diff options
Diffstat (limited to 'os')
-rw-r--r-- | os/io.c | 27 | ||||
-rw-r--r-- | os/osdep.h | 1 |
2 files changed, 25 insertions, 3 deletions
@@ -251,7 +251,14 @@ ReadRequestFromClient(ClientPtr client) need_header = FALSE; move_header = FALSE; gotnow = oci->bufcnt + oci->buffer - oci->bufptr; - if (gotnow < sizeof(xReq)) + + if (oci->ignoreBytes > 0) { + if (oci->ignoreBytes > oci->size) + needed = oci->size; + else + needed = oci->ignoreBytes; + } + else if (gotnow < sizeof(xReq)) { /* We don't have an entire xReq yet. Can't tell how big * the request will be until we get the whole xReq. @@ -294,8 +301,13 @@ ReadRequestFromClient(ClientPtr client) if (needed > maxBigRequestSize << 2) { /* request is too big for us to handle */ - YieldControlDeath(); - return -1; + /* + * Mark the rest of it as needing to be ignored, and then return + * the full size. Dispatch() will turn it into a BadLength error. + */ + oci->ignoreBytes = needed - gotnow; + oci->lenLastReq = gotnow; + return needed; } if ((gotnow == 0) || ((oci->bufptr - oci->buffer + needed) > oci->size)) @@ -400,6 +412,14 @@ ReadRequestFromClient(ClientPtr client) } oci->lenLastReq = needed; + /* If there are bytes to ignore, ignore them now. */ + + if (oci->ignoreBytes > 0) { + assert(needed == oci->ignoreBytes || needed == oci->size); + oci->ignoreBytes -= gotnow; + needed = gotnow = 0; + } + /* * Check to see if client has at least one whole request in the * buffer beyond the request we're returning to the caller. @@ -1030,6 +1050,7 @@ AllocateInputBuffer(void) oci->bufptr = oci->buffer; oci->bufcnt = 0; oci->lenLastReq = 0; + oci->ignoreBytes = 0; return oci; } diff --git a/os/osdep.h b/os/osdep.h index 1d87592e3..3c0e78f06 100644 --- a/os/osdep.h +++ b/os/osdep.h @@ -125,6 +125,7 @@ typedef struct _connectionInput { int bufcnt; /* count of bytes in buffer */ int lenLastReq; int size; + unsigned int ignoreBytes; /* bytes to ignore before the next request */ } ConnectionInput, *ConnectionInputPtr; typedef struct _connectionOutput { |