xserver: Branch 'master'

Keith Packard keithp at kemper.freedesktop.org
Wed Nov 10 15:46:24 PST 2010


 os/io.c |   19 ++++++++++++++++---
 1 file changed, 16 insertions(+), 3 deletions(-)

New commits:
commit c80c41767eb101e9dbd8393d8cca7764b4e248a4
Author: Aaron Plattner <aplattner at nvidia.com>
Date:   Mon Oct 25 22:01:32 2010 -0700

    os: Fix BigReq ignoring when another request is pending
    
    Commit cf88363db0ebb42df7cc286b85d30d7898aea840 fixed the handling of
    BigReq requests that are way too large and handles the case where the
    read() syscall returns a short read.  However, it neglected to handle
    the case where it returns a long read, which happens when the client
    has another request in the queue after the bogus large one.
    
    Handle the long read case by subtracting the smaller of 'needed' and
    'gotnow' from oci->ignoreBytes.  If needed < gotnow, simply subtract
    the two, leaving gotnow equal to the number of extra bytes read.
    Since the code immediately following the (oci->ignoreBytes > 0) block
    tries to handle the next request, advance oci->bufptr immediately
    instead of setting oci->lenLastReq and letting the next call to
    ReadRequestFromClient do it.
    
    Fixes the XTS pChangeKeyboardMapping-3 test.
    
             CASES TESTS  PASS UNSUP UNTST NOTIU  WARN   FIP  FAIL UNRES  UNIN ABORT
    -Xproto    122   389   367     2    19     0     0     0     1     0     0     0
    +Xproto    122   389   368     2    19     0     0     0     0     0     0     0
    
    Signed-off-by: Aaron Plattner <aplattner at nvidia.com>
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Keith Packard <keithp at keithp.com>

diff --git a/os/io.c b/os/io.c
index fb9f762..4210238 100644
--- a/os/io.c
+++ b/os/io.c
@@ -410,16 +410,29 @@ ReadRequestFromClient(ClientPtr client)
 	else
 	    needed = sizeof(xReq);
     }
-    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;
+	/*
+	 * The _XSERVTransRead call above may return more or fewer bytes than we
+	 * want to ignore.  Ignore the smaller of the two sizes.
+	 */
+	if (gotnow < needed) {
+	    oci->ignoreBytes -= gotnow;
+	    oci->bufptr += gotnow;
+	    gotnow = 0;
+	} else {
+	    oci->ignoreBytes -= needed;
+	    oci->bufptr += needed;
+	    gotnow -= needed;
+	}
+	needed = 0;
     }
 
+    oci->lenLastReq = needed;
+
     /*
      *  Check to see if client has at least one whole request in the
      *  buffer beyond the request we're returning to the caller.


More information about the xorg-commit mailing list