[Mono-list] HttpWebRequest.GetResponse() can trigger an uncatchable exception

Christopher David Howie me at chrishowie.com
Fri Jul 8 10:36:11 EDT 2011


Hello Gonzalo/List:

For reference, see this SO post:
<http://stackoverflow.com/questions/5301539/mono-2-8-2-system-buffer-blockcopy-error>.

This bug has existed since at least 2.8 and continues to exist in
2.20.2.  It's a blocker for me, so I've been investing a bit of time
digging into the class libraries to try to come up with a fix.  I'm not
sure exactly what I'm doing though, and would like to probe for other
ideas about the proper way to fix this.

The basic problem is that HttpWebRequest.GetResponse(), whether invoked
asynchronously or not, will make its own async calls.  One of these down
the line results in a callback to WebRequest:ReadDone(IAsyncResult).
This callback has a slim chance to throw an ArgumentOutOfRangeException,
which is not caught, and therefore kills the entire application.  There
is no workaround for this problem, since it happens in framework code on
a separate thread; the developer cannot catch it.

I have been doing my research on the 2.10.2 tag, so my line numbers will
correspond with that commit.  Here's what I know:

* mcs/class/System/System.Net/WebConnection.cs:477 is
"stream.ReadBufferOffset = pos;".
* :479 calls stream.CheckResponseInBuffer() which, down the line, uses
the ReadBufferOffset in a call to Buffer:BlockCopy(), which is not happy
about the negative argument (this triggers the ArgumentOutOfRangeException).
* pos is declared and set to -1 on :438.
* pos can be set to the result of WebConnection:GetResponse(byte[],int)
on :443, but this is dependent on "cnc.readState == ReadState.None".
Additionally, GetResponse() can return -1.

So it seems there are several opportunities for this pos variable to
have the negative value that triggers the exception.  I'm unsure exactly
how to fix this -- set stream.ReadBufferOffset to zero if pos is less
than zero?  I'm not very familiar with what this code is doing, but I'm
pretty certain that if pos winds up being negative and
stream.CheckResponseInBuffer() winds up being called, this will kill the
whole application.

Input and possible fixes would be appreciated.  I want to fix this!  :)

-- 
Chris Howie
http://www.chrishowie.com
http://en.wikipedia.org/wiki/User:Crazycomputers

If you correspond with me on a regular basis, please read this document:
http://www.chrishowie.com/email-preferences/

PGP fingerprint: 2B7A B280 8B12 21CC 260A DF65 6FCE 505A CF83 38F5

------------------------------------------------------------------------
                    IMPORTANT INFORMATION/DISCLAIMER

This document should be read only by those persons to whom it is
addressed.  If you have received this message it was obviously addressed
to you and therefore you can read it.

Additionally, by sending an email to ANY of my addresses or to ANY
mailing lists to which I am subscribed, whether intentionally or
accidentally, you are agreeing that I am "the intended recipient," and
that I may do whatever I wish with the contents of any message received
from you, unless a pre-existing agreement prohibits me from so doing.

This overrides any disclaimer or statement of confidentiality that may
be included on your message.


More information about the Mono-list mailing list