I propose the following patch to support BIG-REQUESTS. Please review.

Cheers, Paul

Paul Szabo   p...@maths.usyd.edu.au   http://www.maths.usyd.edu.au/u/psz/
School of Mathematics and Statistics   University of Sydney    Australia
--- ClientChannel.C-prePSz	2007-02-03 01:25:48.000000000 +1100
+++ ClientChannel.C	2014-10-20 06:34:40.000000000 +1100
@@ -87,9 +87,28 @@
         {
             clientCache_.lastRequestSequenceNum++;
             unsigned char opcode = *buffer;
+	    // Support BIG-REQUESTS
+	    // This code "traditionally" used buffer for the whole request,
+	    // starting with the header and then the data at (buffer+4).
+	    // We now pick out the header so later do not need to reference
+	    // the first four bytes, and use datbuf pointing to the data.
+	    // For BIG-REQUESTS we advance datbuf by four bytes, so it still
+	    // points to the data.
+	    // We use datsiz, the size of datbuf in 4-byte units, so normally
+	    // datsiz = (size/4 - 1) but for BIG-REQUESTS it is (size/4 - 2).
+	    unsigned char datbyte = buffer[1];
+	    unsigned int buffer2 = GetUINT(buffer + 2, bigEndian_);
+	    unsigned int datsiz = buffer2 - 1;
+	    const unsigned char* datbuf = buffer+4;
+	    if (buffer2 == 0)
+	    {
+		// BIG-REQUESTS
+		datsiz = GetULONG(datbuf, bigEndian_) - 2;
+		datbuf += 4;
+	    }
 
             if ((opcode == X_PolyFillRectangle) &&
-                (GetUINT(buffer + 2, bigEndian_) == 3))
+                (buffer2 == 3))
             {
                 opcode = X_NoOperation;
             }
@@ -105,9 +124,9 @@
             case X_AllocColor:
                 {
                     encodeBuffer.
-                        encodeCachedValue(GetULONG(buffer + 4, bigEndian_),
+                        encodeCachedValue(GetULONG(datbuf, bigEndian_),
                                           29, clientCache_.colormapCache, 9);
-                    const unsigned char *nextSrc = buffer + 8;
+                    const unsigned char *nextSrc = datbuf + 4;
                     unsigned int colorData[3];
 
                     for (unsigned int i = 0; i < 3; i++)
@@ -129,30 +148,30 @@
                 break;
             case X_ChangeProperty:
                 {
-                    unsigned char format = buffer[16];
+                    unsigned char format = datbuf[12];
 
                     encodeBuffer.encodeCachedValue(format, 8,
                                                    clientCache_.
                                                    changePropertyFormatCache);
                     unsigned int dataLength =
-                        GetULONG(buffer + 20, bigEndian_);
+                        GetULONG(datbuf + 16, bigEndian_);
                     encodeBuffer.encodeValue(dataLength, 32, 6);
-                    encodeBuffer.encodeValue(buffer[1], 2);
-                    encodeBuffer.encodeCachedValue(GetULONG(buffer + 4,
+                    encodeBuffer.encodeValue(datbyte, 2);
+                    encodeBuffer.encodeCachedValue(GetULONG(datbuf,
                                                             bigEndian_), 29,
                                                    clientCache_.windowCache,
                                                    9);
                     encodeBuffer.
-                        encodeCachedValue(GetULONG(buffer + 8, bigEndian_),
+                        encodeCachedValue(GetULONG(datbuf + 4, bigEndian_),
                                           29,
                                           clientCache_.
                                           changePropertyPropertyCache, 9);
                     encodeBuffer.
-                        encodeCachedValue(GetULONG(buffer + 12, bigEndian_),
+                        encodeCachedValue(GetULONG(datbuf + 8, bigEndian_),
                                           29,
                                           clientCache_.
                                           changePropertyTypeCache, 9);
-                    const unsigned char *nextSrc = buffer + 24;
+                    const unsigned char *nextSrc = datbuf + 20;
 
                     if (format == 8)
                     {
@@ -163,6 +182,7 @@
                     }
                     else if (format == 32)
                     {
+			// Wonder if ChangeProperty format=32 is compressed also?
                         for (unsigned int i = 0; i < dataLength; i++)
                         {
                             encodeBuffer.encodeCachedValue(GetULONG(nextSrc,
@@ -186,17 +206,17 @@
                 break;
             case X_ChangeWindowAttributes:
                 {
-                    encodeBuffer.encodeValue((size - 12) >> 2, 4);
-                    encodeBuffer.encodeCachedValue(GetULONG(buffer + 4,
+                    encodeBuffer.encodeValue(datsiz-2, 4);
+                    encodeBuffer.encodeCachedValue(GetULONG(datbuf,
                                                             bigEndian_), 29,
                                                    clientCache_.windowCache,
                                                    9);
-                    unsigned int bitmask = GetULONG(buffer + 8, bigEndian_);
+                    unsigned int bitmask = GetULONG(datbuf + 4, bigEndian_);
 
                     encodeBuffer.encodeCachedValue(bitmask, 15,
                                                    clientCache_.
                                                    createWindowBitmaskCache);
-                    const unsigned char *nextSrc = buffer + 12;
+                    const unsigned char *nextSrc = datbuf + 8;
                     unsigned int mask = 0x1;
 
                     for (unsigned int j = 0; j < 15; j++)
@@ -217,12 +237,12 @@
                 break;
             case X_ClearArea:
                 {
-                    encodeBuffer.encodeValue((unsigned int) buffer[1], 1);
-                    encodeBuffer.encodeCachedValue(GetULONG(buffer + 4,
+                    encodeBuffer.encodeValue((unsigned int) datbyte, 1);
+                    encodeBuffer.encodeCachedValue(GetULONG(datbuf,
                                                             bigEndian_), 29,
                                                    clientCache_.windowCache,
                                                    9);
-                    const unsigned char *nextSrc = buffer + 8;
+                    const unsigned char *nextSrc = datbuf + 4;
 
                     for (unsigned int i = 0; i < 4; i++)
                     {
@@ -238,7 +258,7 @@
                 break;
             case X_CloseFont:
                 {
-                    unsigned int font = GetULONG(buffer + 4, bigEndian_);
+                    unsigned int font = GetULONG(datbuf, bigEndian_);
 
                     encodeBuffer.encodeValue(font - clientCache_.lastFont,
                                              29, 5);
@@ -247,17 +267,17 @@
                 break;
             case X_ConfigureWindow:
                 {
-                    encodeBuffer.encodeCachedValue(GetULONG(buffer + 4,
+                    encodeBuffer.encodeCachedValue(GetULONG(datbuf,
                                                             bigEndian_), 29,
                                                    clientCache_.windowCache,
                                                    9);
-                    unsigned int bitmask = GetUINT(buffer + 8, bigEndian_);
+                    unsigned int bitmask = GetUINT(datbuf + 4, bigEndian_);
 
                     encodeBuffer.encodeCachedValue(bitmask, 7,
                                                    clientCache_.
                                                    configureWindowBitmaskCache);
                     unsigned int mask = 0x1;
-                    const unsigned char *nextSrc = buffer + 12;
+                    const unsigned char *nextSrc = datbuf + 8;
 
                     for (unsigned int i = 0; i < 7; i++)
                     {
@@ -279,11 +299,11 @@
             case X_ConvertSelection:
                 {
                     encodeBuffer.
-                        encodeCachedValue(GetULONG(buffer + 4, bigEndian_),
+                        encodeCachedValue(GetULONG(datbuf, bigEndian_),
                                           29,
                                           clientCache_.
                                           convertSelectionRequestorCache, 9);
-                    const unsigned char *nextSrc = buffer + 8;
+                    const unsigned char *nextSrc = datbuf + 4;
 
                     for (unsigned int i = 0; i < 3; i++)
                     {
@@ -306,17 +326,17 @@
                 break;
             case X_CopyArea:
                 {
-                    encodeBuffer.encodeCachedValue(GetULONG(buffer + 4,
+                    encodeBuffer.encodeCachedValue(GetULONG(datbuf,
                                                             bigEndian_), 29,
                                                    clientCache_.drawableCache,
                                                    9);
                     encodeBuffer.
-                        encodeCachedValue(GetULONG(buffer + 8, bigEndian_),
+                        encodeCachedValue(GetULONG(datbuf + 4, bigEndian_),
                                           29, clientCache_.drawableCache, 9);
                     encodeBuffer.
-                        encodeCachedValue(GetULONG(buffer + 12, bigEndian_),
+                        encodeCachedValue(GetULONG(datbuf + 8, bigEndian_),
                                           29, clientCache_.gcCache, 9);
-                    const unsigned char *nextSrc = buffer + 16;
+                    const unsigned char *nextSrc = datbuf + 12;
 
                     for (unsigned int i = 0; i < 6; i++)
                     {
@@ -332,31 +352,31 @@
                 break;
             case X_CopyGC:
                 {
-                    encodeBuffer.encodeCachedValue(GetULONG(buffer + 4,
+                    encodeBuffer.encodeCachedValue(GetULONG(datbuf,
                                                             bigEndian_), 29,
                                                    clientCache_.gcCache, 9);
                     encodeBuffer.
-                        encodeCachedValue(GetULONG(buffer + 8, bigEndian_),
+                        encodeCachedValue(GetULONG(datbuf + 4, bigEndian_),
                                           29, clientCache_.gcCache, 9);
                     encodeBuffer.
-                        encodeCachedValue(GetULONG(buffer + 12, bigEndian_),
+                        encodeCachedValue(GetULONG(datbuf + 8, bigEndian_),
                                           23,
                                           clientCache_.createGCBitmaskCache);
                 }
                 break;
             case X_CopyPlane:
                 {
-                    encodeBuffer.encodeCachedValue(GetULONG(buffer + 4,
+                    encodeBuffer.encodeCachedValue(GetULONG(datbuf,
                                                             bigEndian_), 29,
                                                    clientCache_.drawableCache,
                                                    9);
                     encodeBuffer.
-                        encodeCachedValue(GetULONG(buffer + 8, bigEndian_),
+                        encodeCachedValue(GetULONG(datbuf + 4, bigEndian_),
                                           29, clientCache_.drawableCache, 9);
                     encodeBuffer.
-                        encodeCachedValue(GetULONG(buffer + 12, bigEndian_),
+                        encodeCachedValue(GetULONG(datbuf + 8, bigEndian_),
                                           29, clientCache_.gcCache, 9);
-                    const unsigned char *nextSrc = buffer + 16;
+                    const unsigned char *nextSrc = datbuf + 12;
 
                     for (unsigned int i = 0; i < 6; i++)
                     {
@@ -368,7 +388,7 @@
                                                        8);
                         nextSrc += 2;
                     }
-                    encodeBuffer.encodeCachedValue(GetULONG(buffer + 28,
+                    encodeBuffer.encodeCachedValue(GetULONG(datbuf + 24,
                                                             bigEndian_), 32,
                                                    clientCache_.
                                                    copyPlaneBitPlaneCache,
@@ -378,14 +398,14 @@
             case X_CreateGC:
             case X_ChangeGC:
                 {
-                    encodeBuffer.encodeCachedValue(GetULONG(buffer + 4,
+                    encodeBuffer.encodeCachedValue(GetULONG(datbuf,
                                                             bigEndian_), 29,
                                                    clientCache_.gcCache, 9);
-                    const unsigned char *nextSrc = buffer + 8;
+                    const unsigned char *nextSrc = datbuf + 4;
 
                     if (opcode == X_CreateGC)
                     {
-                        encodeBuffer.encodeCachedValue(GetULONG(buffer + 8,
+                        encodeBuffer.encodeCachedValue(GetULONG(datbuf + 4,
                                                                 bigEndian_),
                                                        29,
                                                        clientCache_.
@@ -428,9 +448,9 @@
                 break;
             case X_CreatePixmap:
                 {
-                    encodeBuffer.encodeCachedValue(buffer[1], 8,
+                    encodeBuffer.encodeCachedValue(datbyte, 8,
                                                    clientCache_.depthCache);
-                    unsigned int pixmap = GetULONG(buffer + 4, bigEndian_);
+                    unsigned int pixmap = GetULONG(datbuf, bigEndian_);
                     unsigned int diff = pixmap -
                         clientCache_.createPixmapLastPixmap;
                     if (diff == 0)
@@ -441,32 +461,32 @@
                         encodeBuffer.encodeValue(diff, 29, 4);
                         clientCache_.createPixmapLastPixmap = pixmap;
                     }
-                    encodeBuffer.encodeCachedValue(GetULONG(buffer + 8,
+                    encodeBuffer.encodeCachedValue(GetULONG(datbuf + 4,
                                                             bigEndian_), 29,
                                                    clientCache_.drawableCache,
                                                    9);
                     encodeBuffer.
-                        encodeCachedValue(GetUINT(buffer + 12, bigEndian_),
+                        encodeCachedValue(GetUINT(datbuf + 8, bigEndian_),
                                           16, clientCache_.createPixmapXCache,
                                           8);
                     encodeBuffer.
-                        encodeCachedValue(GetUINT(buffer + 14, bigEndian_),
+                        encodeCachedValue(GetUINT(datbuf + 10, bigEndian_),
                                           16, clientCache_.createPixmapYCache,
                                           8);
                 }
                 break;
             case X_CreateWindow:
                 {
-                    encodeBuffer.encodeCachedValue((unsigned int) buffer[1],
+                    encodeBuffer.encodeCachedValue((unsigned int) datbyte,
                                                    8,
                                                    clientCache_.depthCache);
                     encodeBuffer.
-                        encodeCachedValue(GetULONG(buffer + 8, bigEndian_),
+                        encodeCachedValue(GetULONG(datbuf + 4, bigEndian_),
                                           29, clientCache_.windowCache, 9);
                     encodeBuffer.
-                        encodeCachedValue(GetULONG(buffer + 4, bigEndian_),
+                        encodeCachedValue(GetULONG(datbuf, bigEndian_),
                                           29, clientCache_.windowCache, 9);
-                    const unsigned char *nextSrc = buffer + 12;
+                    const unsigned char *nextSrc = datbuf + 8;
 
                     for (unsigned int i = 0; i < 6; i++)
                     {
@@ -478,15 +498,15 @@
                                                        [i], 8);
                         nextSrc += 2;
                     }
-                    encodeBuffer.encodeCachedValue(GetULONG(buffer + 24,
+                    encodeBuffer.encodeCachedValue(GetULONG(datbuf + 20,
                                                             bigEndian_), 29,
                                                    clientCache_.visualCache);
-                    unsigned int bitmask = GetULONG(buffer + 28, bigEndian_);
+                    unsigned int bitmask = GetULONG(datbuf + 24, bigEndian_);
 
                     encodeBuffer.encodeCachedValue(bitmask, 15,
                                                    clientCache_.
                                                    createWindowBitmaskCache);
-                    nextSrc = buffer + 32;
+                    nextSrc = datbuf + 28;
                     unsigned int mask = 0x1;
 
                     for (unsigned int j = 0; j < 15; j++)
@@ -508,29 +528,29 @@
             case X_DeleteProperty:
                 {
                     encodeBuffer.
-                        encodeCachedValue(GetULONG(buffer + 4, bigEndian_),
+                        encodeCachedValue(GetULONG(datbuf, bigEndian_),
                                           29, clientCache_.windowCache, 9);
-                    encodeBuffer.encodeValue(GetULONG(buffer + 8, bigEndian_),
+                    encodeBuffer.encodeValue(GetULONG(datbuf + 4, bigEndian_),
                                              29, 9);
                 }
                 break;
             case X_FillPoly:
                 {
-                    unsigned int numPoints = ((size - 16) >> 2);
+                    unsigned int numPoints = datsiz - 3;
 
                     encodeBuffer.encodeCachedValue(numPoints, 14,
                                                    clientCache_.
                                                    fillPolyNumPointsCache, 4);
                     encodeBuffer.
-                        encodeCachedValue(GetULONG(buffer + 4, bigEndian_),
+                        encodeCachedValue(GetULONG(datbuf, bigEndian_),
                                           29, clientCache_.drawableCache, 9);
                     encodeBuffer.
-                        encodeCachedValue(GetULONG(buffer + 8, bigEndian_),
+                        encodeCachedValue(GetULONG(datbuf + 4, bigEndian_),
                                           29, clientCache_.gcCache, 9);
-                    encodeBuffer.encodeValue((unsigned int) buffer[12], 2);
-                    encodeBuffer.encodeValue((unsigned int) buffer[13], 1);
-                    int relativeCoordMode = (buffer[13] != 0);
-                    const unsigned char *nextSrc = buffer + 16;
+                    encodeBuffer.encodeValue((unsigned int) datbuf[8], 2);
+                    encodeBuffer.encodeValue((unsigned int) datbuf[9], 1);
+                    int relativeCoordMode = (datbuf[9] != 0);
+                    const unsigned char *nextSrc = datbuf + 12;
                     unsigned int pointIndex = 0;
 
                     for (unsigned int i = 0; i < numPoints; i++)
@@ -602,15 +622,14 @@
                 break;
             case X_FreeColors:
                 {
-                    unsigned int numPixels =
-                        GetUINT(buffer + 2, bigEndian_) - 3;
-                    encodeBuffer.encodeValue(numPixels, 16, 4);
+                    unsigned int numPixels = datsiz - 2;
+                    encodeBuffer.encodeValue(numPixels, 32, 4);
                     encodeBuffer.
-                        encodeCachedValue(GetULONG(buffer + 4, bigEndian_),
+                        encodeCachedValue(GetULONG(datbuf, bigEndian_),
                                           29, clientCache_.colormapCache, 9);
-                    encodeBuffer.encodeValue(GetULONG(buffer + 8, bigEndian_),
+                    encodeBuffer.encodeValue(GetULONG(datbuf + 4, bigEndian_),
                                              32, 4);
-                    const unsigned char *nextSrc = buffer + 12;
+                    const unsigned char *nextSrc = datbuf + 8;
 
                     while (numPixels)
                     {
@@ -624,20 +643,20 @@
             case X_FreeCursor:
                 {
                     encodeBuffer.
-                        encodeCachedValue(GetULONG(buffer + 4, bigEndian_),
+                        encodeCachedValue(GetULONG(datbuf, bigEndian_),
                                           29, clientCache_.cursorCache, 9);
                 }
                 break;
             case X_FreeGC:
                 {
-                    encodeBuffer.encodeCachedValue(GetULONG(buffer + 4,
+                    encodeBuffer.encodeCachedValue(GetULONG(datbuf,
                                                             bigEndian_), 29,
                                                    clientCache_.gcCache, 9);
                 }
                 break;
             case X_FreePixmap:
                 {
-                    unsigned int pixmap = GetULONG(buffer + 4, bigEndian_);
+                    unsigned int pixmap = GetULONG(datbuf, bigEndian_);
                     unsigned int diff = pixmap -
                         clientCache_.createPixmapLastPixmap;
                     if (diff == 0)
@@ -652,7 +671,7 @@
                 break;
             case X_GetAtomName:
                 {
-                    encodeBuffer.encodeValue(GetULONG(buffer + 4, bigEndian_),
+                    encodeBuffer.encodeValue(GetULONG(datbuf, bigEndian_),
                                              29, 9);
                     sequenceNumQueue_.push(clientCache_.
                                            lastRequestSequenceNum, opcode);
@@ -660,7 +679,7 @@
                 break;
             case X_GetGeometry:
                 {
-                    encodeBuffer.encodeCachedValue(GetULONG(buffer + 4,
+                    encodeBuffer.encodeCachedValue(GetULONG(datbuf,
                                                             bigEndian_), 29,
                                                    clientCache_.drawableCache,
                                                    9);
@@ -677,28 +696,28 @@
                 break;
             case X_GetKeyboardMapping:
                 {
-                    encodeBuffer.encodeValue((unsigned int) buffer[4], 8);
-                    encodeBuffer.encodeValue((unsigned int) buffer[5], 8);
+                    encodeBuffer.encodeValue((unsigned int) datbuf[0], 8);
+                    encodeBuffer.encodeValue((unsigned int) datbuf[1], 8);
                     sequenceNumQueue_.push(clientCache_.
                                            lastRequestSequenceNum, opcode);
                 }
                 break;
             case X_GetProperty:
                 {
-                    encodeBuffer.encodeValue((unsigned int) buffer[1], 1);
-                    encodeBuffer.encodeCachedValue(GetULONG(buffer + 4,
+                    encodeBuffer.encodeValue((unsigned int) datbyte, 1);
+                    encodeBuffer.encodeCachedValue(GetULONG(datbuf,
                                                             bigEndian_), 29,
                                                    clientCache_.windowCache,
                                                    9);
-                    unsigned int property = GetULONG(buffer + 8, bigEndian_);
+                    unsigned int property = GetULONG(datbuf + 4, bigEndian_);
 
                     encodeBuffer.encodeValue(property, 29, 9);
                     encodeBuffer.
-                        encodeValue(GetULONG(buffer + 12, bigEndian_), 29, 9);
+                        encodeValue(GetULONG(datbuf + 8, bigEndian_), 29, 9);
                     encodeBuffer.
-                        encodeValue(GetULONG(buffer + 16, bigEndian_), 32, 2);
+                        encodeValue(GetULONG(datbuf + 12, bigEndian_), 32, 2);
                     encodeBuffer.
-                        encodeValue(GetULONG(buffer + 20, bigEndian_), 32, 8);
+                        encodeValue(GetULONG(datbuf + 16, bigEndian_), 32, 8);
                     sequenceNumQueue_.push(clientCache_.
                                            lastRequestSequenceNum, opcode,
                                            property);
@@ -706,7 +725,7 @@
                 break;
             case X_GetSelectionOwner:
                 {
-                    encodeBuffer.encodeCachedValue(GetULONG(buffer + 4,
+                    encodeBuffer.encodeCachedValue(GetULONG(datbuf,
                                                             bigEndian_), 29,
                                                    clientCache_.
                                                    getSelectionOwnerSelectionCache,
@@ -718,38 +737,38 @@
             case X_GrabButton:
             case X_GrabPointer:
                 {
-                    encodeBuffer.encodeValue((unsigned int) buffer[1], 1);
-                    encodeBuffer.encodeCachedValue(GetULONG(buffer + 4,
+                    encodeBuffer.encodeValue((unsigned int) datbyte, 1);
+                    encodeBuffer.encodeCachedValue(GetULONG(datbuf,
                                                             bigEndian_), 29,
                                                    clientCache_.windowCache,
                                                    9);
                     encodeBuffer.
-                        encodeCachedValue(GetUINT(buffer + 8, bigEndian_), 16,
+                        encodeCachedValue(GetUINT(datbuf + 4, bigEndian_), 16,
                                           clientCache_.
                                           grabButtonEventMaskCache);
-                    encodeBuffer.encodeValue((unsigned int) buffer[10], 1);
-                    encodeBuffer.encodeValue((unsigned int) buffer[11], 1);
-                    encodeBuffer.encodeCachedValue(GetULONG(buffer + 12,
+                    encodeBuffer.encodeValue((unsigned int) datbuf[6], 1);
+                    encodeBuffer.encodeValue((unsigned int) datbuf[7], 1);
+                    encodeBuffer.encodeCachedValue(GetULONG(datbuf + 8,
                                                             bigEndian_), 29,
                                                    clientCache_.
                                                    grabButtonConfineCache, 9);
                     encodeBuffer.
-                        encodeCachedValue(GetULONG(buffer + 16, bigEndian_),
+                        encodeCachedValue(GetULONG(datbuf + 12, bigEndian_),
                                           29, clientCache_.cursorCache, 9);
                     if (opcode == X_GrabButton)
                     {
-                        encodeBuffer.encodeCachedValue(buffer[20], 8,
+                        encodeBuffer.encodeCachedValue(datbuf[16], 8,
                                                        clientCache_.
                                                        grabButtonButtonCache);
                         encodeBuffer.
                             encodeCachedValue(GetUINT
-                                              (buffer + 22, bigEndian_), 16,
+                                              (datbuf + 18, bigEndian_), 16,
                                               clientCache_.
                                               grabButtonModifierCache);
                     }
                     else
                     {
-                        unsigned int timestamp = GetULONG(buffer + 20,
+                        unsigned int timestamp = GetULONG(datbuf + 16,
                                                           bigEndian_);
 
                         encodeBuffer.encodeValue(timestamp -
@@ -765,20 +784,20 @@
                 break;
             case X_GrabKeyboard:
                 {
-                    encodeBuffer.encodeValue((unsigned int) buffer[1], 1);
-                    encodeBuffer.encodeCachedValue(GetULONG(buffer + 4,
+                    encodeBuffer.encodeValue((unsigned int) datbyte, 1);
+                    encodeBuffer.encodeCachedValue(GetULONG(datbuf,
                                                             bigEndian_), 29,
                                                    clientCache_.windowCache,
                                                    9);
-                    unsigned int timestamp = GetULONG(buffer + 8, bigEndian_);
+                    unsigned int timestamp = GetULONG(datbuf + 4, bigEndian_);
 
                     encodeBuffer.encodeValue(timestamp -
                                              clientCache_.
                                              grabKeyboardLastTimestamp, 32,
                                              4);
                     clientCache_.grabKeyboardLastTimestamp = timestamp;
-                    encodeBuffer.encodeValue((unsigned int) buffer[12], 1);
-                    encodeBuffer.encodeValue((unsigned int) buffer[13], 1);
+                    encodeBuffer.encodeValue((unsigned int) datbuf[8], 1);
+                    encodeBuffer.encodeValue((unsigned int) datbuf[9], 1);
                     sequenceNumQueue_.push(clientCache_.
                                            lastRequestSequenceNum, opcode);
                 }
@@ -791,31 +810,31 @@
                 break;
             case X_ImageText8:
                 {
-                    unsigned int textLength = (unsigned int) buffer[1];
+                    unsigned int textLength = (unsigned int) datbyte;
 
                     encodeBuffer.encodeValue(textLength, 8);
-                    encodeBuffer.encodeCachedValue(GetULONG(buffer + 4,
+                    encodeBuffer.encodeCachedValue(GetULONG(datbuf,
                                                             bigEndian_), 29,
                                                    clientCache_.drawableCache,
                                                    9);
                     encodeBuffer.
-                        encodeCachedValue(GetULONG(buffer + 8, bigEndian_),
+                        encodeCachedValue(GetULONG(datbuf + 4, bigEndian_),
                                           29, clientCache_.gcCache, 9);
-                    unsigned int x = GetUINT(buffer + 12, bigEndian_);
+                    unsigned int x = GetUINT(datbuf + 8, bigEndian_);
                     int xDiff = x - clientCache_.imageText8LastX;
 
                     clientCache_.imageText8LastX = x;
                     encodeBuffer.encodeCachedValue(xDiff, 16,
                                                    clientCache_.
                                                    imageText8CacheX, 8);
-                    unsigned int y = GetUINT(buffer + 14, bigEndian_);
+                    unsigned int y = GetUINT(datbuf + 10, bigEndian_);
                     int yDiff = y - clientCache_.imageText8LastY;
 
                     clientCache_.imageText8LastY = y;
                     encodeBuffer.encodeCachedValue(yDiff, 16,
                                                    clientCache_.
                                                    imageText8CacheY, 8);
-                    const unsigned char *nextSrc = buffer + 16;
+                    const unsigned char *nextSrc = datbuf + 12;
 
                     clientCache_.imageText8TextCompressor.reset();
                     for (unsigned int j = 0; j < textLength; j++)
@@ -825,11 +844,11 @@
                 break;
             case X_InternAtom:
                 {
-                    unsigned int nameLength = GetUINT(buffer + 4, bigEndian_);
+                    unsigned int nameLength = GetUINT(datbuf, bigEndian_);
 
                     encodeBuffer.encodeValue(nameLength, 16, 6);
-                    encodeBuffer.encodeValue((unsigned int) buffer[1], 1);
-                    const unsigned char *nextSrc = buffer + 8;
+                    encodeBuffer.encodeValue((unsigned int) datbyte, 1);
+                    const unsigned char *nextSrc = datbuf + 4;
 
                     clientCache_.internAtomTextCompressor.reset();
                     for (unsigned int i = 0; i < nameLength; i++)
@@ -847,12 +866,12 @@
                 break;
             case X_ListFonts:
                 {
-                    unsigned int textLength = GetUINT(buffer + 6, bigEndian_);
+                    unsigned int textLength = GetUINT(datbuf + 2, bigEndian_);
 
                     encodeBuffer.encodeValue(textLength, 16, 6);
-                    encodeBuffer.encodeValue(GetUINT(buffer + 4, bigEndian_),
+                    encodeBuffer.encodeValue(GetUINT(datbuf, bigEndian_),
                                              16, 6);
-                    const unsigned char *nextSrc = buffer + 8;
+                    const unsigned char *nextSrc = datbuf + 4;
 
                     clientCache_.polyText8TextCompressor.reset();
                     for (unsigned int i = 0; i < textLength; i++)
@@ -867,13 +886,13 @@
                 {
                     sequenceNumQueue_.push(clientCache_.
                                            lastRequestSequenceNum, opcode);
-                    unsigned int textLength = GetUINT(buffer + 8, bigEndian_);
+                    unsigned int textLength = GetUINT(datbuf + 4, bigEndian_);
 
                     encodeBuffer.encodeValue(textLength, 16, 6);
                     encodeBuffer.
-                        encodeCachedValue(GetULONG(buffer + 4, bigEndian_),
+                        encodeCachedValue(GetULONG(datbuf, bigEndian_),
                                           29, clientCache_.colormapCache, 9);
-                    const unsigned char *nextSrc = buffer + 12;
+                    const unsigned char *nextSrc = datbuf + 8;
 
                     clientCache_.polyText8TextCompressor.reset();
                     for (unsigned int i = 0; i < textLength; i++)
@@ -890,7 +909,7 @@
             case X_QueryPointer:
             case X_QueryTree:
                 {
-                    encodeBuffer.encodeCachedValue(GetULONG(buffer + 4,
+                    encodeBuffer.encodeCachedValue(GetULONG(datbuf,
                                                             bigEndian_), 29,
                                                    clientCache_.windowCache,
                                                    9);
@@ -906,15 +925,15 @@
                 break;
             case X_OpenFont:
                 {
-                    unsigned int nameLength = GetUINT(buffer + 8, bigEndian_);
+                    unsigned int nameLength = GetUINT(datbuf + 4, bigEndian_);
 
                     encodeBuffer.encodeValue(nameLength, 16, 7);
-                    unsigned int font = GetULONG(buffer + 4, bigEndian_);
+                    unsigned int font = GetULONG(datbuf, bigEndian_);
 
                     encodeBuffer.encodeValue(font - clientCache_.lastFont,
                                              29, 5);
                     clientCache_.lastFont = font;
-                    const unsigned char *nextSrc = buffer + 12;
+                    const unsigned char *nextSrc = datbuf + 8;
 
                     clientCache_.openFontTextCompressor.reset();
                     for (; nameLength; nameLength--)
@@ -924,20 +943,20 @@
                 break;
             case X_PolyFillRectangle:
                 {
-                    encodeBuffer.encodeCachedValue(GetULONG(buffer + 4,
+                    encodeBuffer.encodeCachedValue(GetULONG(datbuf,
                                                             bigEndian_), 29,
                                                    clientCache_.drawableCache,
                                                    9);
                     encodeBuffer.
-                        encodeCachedValue(GetULONG(buffer + 8, bigEndian_),
+                        encodeCachedValue(GetULONG(datbuf + 4, bigEndian_),
                                           29, clientCache_.gcCache, 9);
                     unsigned int index = 0;
                     unsigned int lastX = 0, lastY = 0;
                     unsigned int lastWidth = 0, lastHeight = 0;
 
-                    for (unsigned int i = 12; i < size;)
+                    for (unsigned int i = 8; i < (datsiz<<2);)
                     {
-                        unsigned int x = GetUINT(buffer + i, bigEndian_);
+                        unsigned int x = GetUINT(datbuf + i, bigEndian_);
                         unsigned int newX = x;
 
                         x -= lastX;
@@ -947,7 +966,7 @@
                                                        polyFillRectangleCacheX
                                                        [index], 8);
                         i += 2;
-                        unsigned int y = GetUINT(buffer + i, bigEndian_);
+                        unsigned int y = GetUINT(datbuf + i, bigEndian_);
                         unsigned int newY = y;
 
                         y -= lastY;
@@ -957,7 +976,7 @@
                                                        polyFillRectangleCacheY
                                                        [index], 8);
                         i += 2;
-                        unsigned int width = GetUINT(buffer + i, bigEndian_);
+                        unsigned int width = GetUINT(datbuf + i, bigEndian_);
                         unsigned int newWidth = width;
 
                         width -= lastWidth;
@@ -967,7 +986,7 @@
                                                        polyFillRectangleCacheWidth
                                                        [index], 8);
                         i += 2;
-                        unsigned int height = GetUINT(buffer + i, bigEndian_);
+                        unsigned int height = GetUINT(datbuf + i, bigEndian_);
                         unsigned int newHeight = height;
 
                         height -= lastHeight;
@@ -979,27 +998,26 @@
                         i += 2;
                         index = 1;
 
-                        encodeBuffer.encodeValue(((i < size) ? 1 : 0), 1);
+                        encodeBuffer.encodeValue(((i < (datsiz<<2)) ? 1 : 0), 1);
                     }
                 }
                 break;
             case X_PolyPoint:
                 {
-                    encodeBuffer.encodeValue(GetUINT(buffer + 2, bigEndian_) -
-                                             3, 16, 4);
-                    encodeBuffer.encodeValue((unsigned int) buffer[1], 1);
-                    encodeBuffer.encodeCachedValue(GetULONG(buffer + 4,
+                    encodeBuffer.encodeValue(datsiz - 2, 32, 4);
+                    encodeBuffer.encodeValue((unsigned int) datbyte, 1);
+                    encodeBuffer.encodeCachedValue(GetULONG(datbuf,
                                                             bigEndian_), 29,
                                                    clientCache_.drawableCache,
                                                    9);
                     encodeBuffer.
-                        encodeCachedValue(GetULONG(buffer + 8, bigEndian_),
+                        encodeCachedValue(GetULONG(datbuf + 4, bigEndian_),
                                           29, clientCache_.gcCache, 9);
-                    const unsigned char *nextSrc = buffer + 12;
+                    const unsigned char *nextSrc = datbuf + 8;
                     unsigned int index = 0;
                     unsigned int lastX = 0, lastY = 0;
 
-                    for (unsigned int i = 12; i < size; i += 4)
+                    for (unsigned int i = 8; i < (datsiz<<2); i += 4)
                     {
                         unsigned int x = GetUINT(nextSrc, bigEndian_);
 
@@ -1028,21 +1046,20 @@
                 break;
             case X_PolyLine:
                 {
-                    encodeBuffer.encodeValue(GetUINT(buffer + 2, bigEndian_) -
-                                             3, 16, 4);
-                    encodeBuffer.encodeValue((unsigned int) buffer[1], 1);
-                    encodeBuffer.encodeCachedValue(GetULONG(buffer + 4,
+                    encodeBuffer.encodeValue(datsiz - 2, 32, 4);
+                    encodeBuffer.encodeValue((unsigned int) datbyte, 1);
+                    encodeBuffer.encodeCachedValue(GetULONG(datbuf,
                                                             bigEndian_), 29,
                                                    clientCache_.drawableCache,
                                                    9);
                     encodeBuffer.
-                        encodeCachedValue(GetULONG(buffer + 8, bigEndian_),
+                        encodeCachedValue(GetULONG(datbuf + 4, bigEndian_),
                                           29, clientCache_.gcCache, 9);
-                    const unsigned char *nextSrc = buffer + 12;
+                    const unsigned char *nextSrc = datbuf + 8;
                     unsigned int index = 0;
                     unsigned int lastX = 0, lastY = 0;
 
-                    for (unsigned int i = 12; i < size; i += 4)
+                    for (unsigned int i = 8; i < (datsiz<<2); i += 4)
                     {
                         unsigned int x = GetUINT(nextSrc, bigEndian_);
 
@@ -1071,17 +1088,15 @@
                 break;
             case X_PolyRectangle:
                 {
-                    encodeBuffer.encodeValue((GetUINT(buffer + 2,
-                                                      bigEndian_) - 3) >> 1,
-                                             16, 3);
+                    encodeBuffer.encodeValue((datsiz - 2) >> 1, 32, 3);
                     encodeBuffer.
-                        encodeCachedValue(GetULONG(buffer + 4, bigEndian_),
+                        encodeCachedValue(GetULONG(datbuf, bigEndian_),
                                           29, clientCache_.drawableCache, 9);
                     encodeBuffer.
-                        encodeCachedValue(GetULONG(buffer + 8, bigEndian_),
+                        encodeCachedValue(GetULONG(datbuf + 4, bigEndian_),
                                           29, clientCache_.gcCache, 9);
-                    const unsigned char *end = buffer + size;
-                    const unsigned char *nextSrc = buffer + 12;
+                    const unsigned char *end = datbuf + (datsiz<<2);
+                    const unsigned char *nextSrc = datbuf + 8;
 
                     while (nextSrc < end)
                         for (unsigned int i = 0; i < 4; i++)
@@ -1098,17 +1113,15 @@
                 break;
             case X_PolySegment:
                 {
-                    encodeBuffer.encodeValue((GetUINT(buffer + 2,
-                                                      bigEndian_) - 3) >> 1,
-                                             16, 4);
+                    encodeBuffer.encodeValue((datsiz - 2) >> 1, 32, 4);
                     encodeBuffer.
-                        encodeCachedValue(GetULONG(buffer + 4, bigEndian_),
+                        encodeCachedValue(GetULONG(datbuf, bigEndian_),
                                           29, clientCache_.drawableCache, 9);
                     encodeBuffer.
-                        encodeCachedValue(GetULONG(buffer + 8, bigEndian_),
+                        encodeCachedValue(GetULONG(datbuf + 4, bigEndian_),
                                           29, clientCache_.gcCache, 9);
-                    const unsigned char *end = buffer + size;
-                    const unsigned char *nextSrc = buffer + 12;
+                    const unsigned char *end = datbuf + (datsiz<<2);
+                    const unsigned char *nextSrc = datbuf + 8;
 
                     // unsigned int index = 0;
                     // unsigned int lastX1, lastY1, lastX2, lastY2;
@@ -1188,29 +1201,29 @@
                 break;
             case X_PolyText8:
                 {
-                    encodeBuffer.encodeCachedValue(GetULONG(buffer + 4,
+                    encodeBuffer.encodeCachedValue(GetULONG(datbuf,
                                                             bigEndian_), 29,
                                                    clientCache_.drawableCache,
                                                    9);
                     encodeBuffer.
-                        encodeCachedValue(GetULONG(buffer + 8, bigEndian_),
+                        encodeCachedValue(GetULONG(datbuf + 4, bigEndian_),
                                           29, clientCache_.gcCache, 9);
-                    unsigned int x = GetUINT(buffer + 12, bigEndian_);
+                    unsigned int x = GetUINT(datbuf + 8, bigEndian_);
                     int xDiff = x - clientCache_.polyText8LastX;
 
                     clientCache_.polyText8LastX = x;
                     encodeBuffer.encodeCachedValue(xDiff, 16,
                                                    clientCache_.
                                                    polyText8CacheX, 8);
-                    unsigned int y = GetUINT(buffer + 14, bigEndian_);
+                    unsigned int y = GetUINT(datbuf + 10, bigEndian_);
                     int yDiff = y - clientCache_.polyText8LastY;
 
                     clientCache_.polyText8LastY = y;
                     encodeBuffer.encodeCachedValue(yDiff, 16,
                                                    clientCache_.
                                                    polyText8CacheY, 8);
-                    const unsigned char *end = buffer + size - 1;
-                    const unsigned char *nextSrc = buffer + 16;
+                    const unsigned char *end = datbuf + (datsiz<<2) - 1;
+                    const unsigned char *nextSrc = datbuf + 12;
 
                     while (nextSrc < end)
                     {
@@ -1243,57 +1256,56 @@
                 break;
             case X_PutImage:
                 {
-                    encodeBuffer.encodeValue(GetUINT(buffer + 2, bigEndian_),
-                                             16, 8);
-                    encodeBuffer.encodeValue((unsigned int) buffer[1], 2);
-                    encodeBuffer.encodeCachedValue(GetULONG(buffer + 4,
+                    encodeBuffer.encodeValue(datsiz + 1, 32, 8);
+                    encodeBuffer.encodeValue((unsigned int) datbyte, 2);
+                    encodeBuffer.encodeCachedValue(GetULONG(datbuf,
                                                             bigEndian_), 29,
                                                    clientCache_.drawableCache,
                                                    9);
                     encodeBuffer.
-                        encodeCachedValue(GetULONG(buffer + 8, bigEndian_),
+                        encodeCachedValue(GetULONG(datbuf + 4, bigEndian_),
                                           29, clientCache_.gcCache, 9);
-                    unsigned int width = GetUINT(buffer + 12, bigEndian_);
+                    unsigned int width = GetUINT(datbuf + 8, bigEndian_);
 
                     encodeBuffer.encodeCachedValue(width, 16,
                                                    clientCache_.
                                                    putImageWidthCache, 8);
-                    unsigned int height = GetUINT(buffer + 14, bigEndian_);
+                    unsigned int height = GetUINT(datbuf + 10, bigEndian_);
 
                     encodeBuffer.encodeCachedValue(height, 16,
                                                    clientCache_.
                                                    putImageHeightCache, 8);
-                    unsigned int x = GetUINT(buffer + 16, bigEndian_);
+                    unsigned int x = GetUINT(datbuf + 12, bigEndian_);
                     int xDiff = x - clientCache_.putImageLastX;
 
                     clientCache_.putImageLastX = x;
                     encodeBuffer.encodeCachedValue(xDiff, 16,
                                                    clientCache_.
                                                    putImageXCache, 8);
-                    unsigned int y = GetUINT(buffer + 18, bigEndian_);
+                    unsigned int y = GetUINT(datbuf + 14, bigEndian_);
                     int yDiff = y - clientCache_.putImageLastY;
 
                     clientCache_.putImageLastY = y;
                     encodeBuffer.encodeCachedValue(yDiff, 16,
                                                    clientCache_.
                                                    putImageYCache, 8);
-                    encodeBuffer.encodeCachedValue(buffer[20], 8,
+                    encodeBuffer.encodeCachedValue(datbuf[16], 8,
                                                    clientCache_.
                                                    putImageOffsetCache);
-                    encodeBuffer.encodeCachedValue(buffer[21], 8,
+                    encodeBuffer.encodeCachedValue(datbuf[17], 8,
                                                    clientCache_.depthCache);
-                    const unsigned char *nextSrc = buffer + 24;
+                    const unsigned char *nextSrc = datbuf + 20;
 
                     if (!compresser ||
                         (compresser->
-                         compressBuffer(nextSrc, size - 24,
+                         compressBuffer(nextSrc, (datsiz<<2) - 20,
                                         encodeBuffer) ==
                          NO_STREAM_COMPRESSION))
                     {
                         encodeBuffer.encodeValue(NO_STREAM_COMPRESSION,
                                                  COMPRESSION_TYPE_BITS);
 
-                        if ((buffer[1] == 0) && (height <= 32) &&
+                        if ((datbyte == 0) && (height <= 32) &&
                             (width > height * PUT_IMAGE_MIN_ASPECT_RATIO))
                         {
                             // bitmap that probably contains text;
@@ -1303,8 +1315,8 @@
                                 && (bitmapBitOrder_ == 0))
                             {
                                 unsigned char *next =
-                                    (unsigned char *) buffer + 24;
-                                for (unsigned int i = 24; i < size; i++)
+                                    (unsigned char *) datbuf + 20;
+                                for (unsigned int i = 20; i < ((datsiz)<<2); i++)
                                 {
                                     *next = REVERSED_BYTE[*next];
                                     next++;
@@ -1315,7 +1327,7 @@
                             if (widthInBits < width)
                                 widthInBits += scanlinePad_;
                             unsigned int widthInBytes = (widthInBits >> 3);
-                            const unsigned char *nextSrc = buffer + 24;
+                            const unsigned char *nextSrc = datbuf + 20;
                             unsigned char srcMask = 0x80;
 
                             clientCache_.putImageLastPixels.reset();
@@ -1355,7 +1367,7 @@
                                 }
                             }
                         }
-                        else if (buffer[1] == 0)
+                        else if (datbyte == 0)
                         {
                             // bitmap--use "Modified-Modified-Read" FAX coding
                             if (width + 2 > clientCache_.putImageLineSize)
@@ -1378,7 +1390,7 @@
                             {
                                 unsigned int codingLineLength = 0;
                                 const unsigned char *nextSrc =
-                                    buffer + 24 + h * widthInBytes;
+                                    datbuf + 20 + h * widthInBytes;
                                 unsigned char nextSrcChar = *nextSrc;
 
                                 if (h)
@@ -1640,9 +1652,9 @@
                         else
                         {
                             // pixmap, not bitmap
-                            if (buffer[21] == 8)
+                            if (datbuf[17] == 8)
                             {
-                                for (unsigned int i = 24; i < size; i++)
+                                for (unsigned int i = 20; i < ((datsiz)<<2); i++)
                                     encodeBuffer.encodeCachedValue(*nextSrc++,
                                                                    8,
                                                                    clientCache_.
@@ -1651,7 +1663,7 @@
                             }
                             else
                             {
-                                for (unsigned int i = 24; i < size; i++)
+                                for (unsigned int i = 20; i < ((datsiz)<<2); i++)
                                     encodeBuffer.
                                         encodeValue((unsigned int) *nextSrc++,
                                                     8);
@@ -1662,14 +1674,14 @@
                 break;
             case X_QueryBestSize:
                 {
-                    encodeBuffer.encodeValue((unsigned int) buffer[1], 2);
-                    encodeBuffer.encodeCachedValue(GetULONG(buffer + 4,
+                    encodeBuffer.encodeValue((unsigned int) datbyte, 2);
+                    encodeBuffer.encodeCachedValue(GetULONG(datbuf,
                                                             bigEndian_), 29,
                                                    clientCache_.drawableCache,
                                                    9);
-                    encodeBuffer.encodeValue(GetUINT(buffer + 8, bigEndian_),
+                    encodeBuffer.encodeValue(GetUINT(datbuf + 4, bigEndian_),
                                              16, 8);
-                    encodeBuffer.encodeValue(GetUINT(buffer + 10, bigEndian_),
+                    encodeBuffer.encodeValue(GetUINT(datbuf + 6, bigEndian_),
                                              16, 8);
                     sequenceNumQueue_.push(clientCache_.
                                            lastRequestSequenceNum, opcode);
@@ -1677,13 +1689,13 @@
                 break;
             case X_QueryColors:
                 {
-                    unsigned int numColors = ((size - 8) >> 2);
+                    unsigned int numColors = datsiz - 1;
 
-                    encodeBuffer.encodeValue(numColors, 16, 5);
+                    encodeBuffer.encodeValue(numColors, 32, 5);
                     encodeBuffer.
-                        encodeCachedValue(GetULONG(buffer + 4, bigEndian_),
+                        encodeCachedValue(GetULONG(datbuf, bigEndian_),
                                           29, clientCache_.colormapCache, 9);
-                    const unsigned char *nextSrc = buffer + 8;
+                    const unsigned char *nextSrc = datbuf + 4;
                     unsigned int predictedPixel =
                         clientCache_.queryColorsLastPixel;
                     for (unsigned int i = 0; i < numColors; i++)
@@ -1708,10 +1720,10 @@
                 break;
             case X_QueryExtension:
                 {
-                    unsigned int nameLength = GetUINT(buffer + 4, bigEndian_);
+                    unsigned int nameLength = GetUINT(datbuf, bigEndian_);
 
                     encodeBuffer.encodeValue(nameLength, 16, 6);
-                    const unsigned char *nextSrc = buffer + 8;
+                    const unsigned char *nextSrc = datbuf + 4;
 
                     for (; nameLength; nameLength--)
                         encodeBuffer.encodeValue((unsigned int) *nextSrc++,
@@ -1722,7 +1734,7 @@
                 break;
             case X_QueryFont:
                 {
-                    unsigned int font = GetULONG(buffer + 4, bigEndian_);
+                    unsigned int font = GetULONG(datbuf, bigEndian_);
 
                     encodeBuffer.encodeValue(font - clientCache_.lastFont, 29,
                                              5);
@@ -1733,23 +1745,23 @@
                 break;
             case X_SetClipRectangles:
                 {
-                    unsigned int numRectangles = ((size - 12) >> 3);
+                    unsigned int numRectangles = ((datsiz-2) >> 1);
 
                     encodeBuffer.encodeValue(numRectangles, 13, 4);
-                    encodeBuffer.encodeValue((unsigned int) buffer[1], 2);
+                    encodeBuffer.encodeValue((unsigned int) datbyte, 2);
                     encodeBuffer.
-                        encodeCachedValue(GetULONG(buffer + 4, bigEndian_),
+                        encodeCachedValue(GetULONG(datbuf, bigEndian_),
                                           29, clientCache_.gcCache, 9);
                     encodeBuffer.
-                        encodeCachedValue(GetUINT(buffer + 8, bigEndian_), 16,
+                        encodeCachedValue(GetUINT(datbuf + 4, bigEndian_), 16,
                                           clientCache_.
                                           setClipRectanglesXCache, 8);
                     encodeBuffer.
-                        encodeCachedValue(GetUINT(buffer + 10, bigEndian_),
+                        encodeCachedValue(GetUINT(datbuf + 6, bigEndian_),
                                           16,
                                           clientCache_.
                                           setClipRectanglesYCache, 8);
-                    const unsigned char *nextSrc = buffer + 12;
+                    const unsigned char *nextSrc = datbuf + 8;
 
                     for (unsigned int i = 0; i < numRectangles; i++)
                     {
@@ -1768,19 +1780,19 @@
                 break;
             case X_SetDashes:
                 {
-                    unsigned int numDashes = GetUINT(buffer + 10, bigEndian_);
+                    unsigned int numDashes = GetUINT(datbuf + 6, bigEndian_);
 
                     encodeBuffer.encodeCachedValue(numDashes, 16,
                                                    clientCache_.
                                                    setDashesLengthCache, 5);
                     encodeBuffer.
-                        encodeCachedValue(GetULONG(buffer + 4, bigEndian_),
+                        encodeCachedValue(GetULONG(datbuf, bigEndian_),
                                           29, clientCache_.gcCache, 9);
                     encodeBuffer.
-                        encodeCachedValue(GetUINT(buffer + 8, bigEndian_), 16,
+                        encodeCachedValue(GetUINT(datbuf + 4, bigEndian_), 16,
                                           clientCache_.setDashesOffsetCache,
                                           5);
-                    const unsigned char *nextSrc = buffer + 12;
+                    const unsigned char *nextSrc = datbuf + 8;
 
                     for (unsigned int i = 0; i < numDashes; i++)
                         encodeBuffer.encodeCachedValue(*nextSrc++, 8,
@@ -1793,17 +1805,17 @@
             case X_SetSelectionOwner:
                 {
                     encodeBuffer.
-                        encodeCachedValue(GetULONG(buffer + 4, bigEndian_),
+                        encodeCachedValue(GetULONG(datbuf, bigEndian_),
                                           29,
                                           clientCache_.setSelectionOwnerCache,
                                           9);
                     encodeBuffer.
-                        encodeCachedValue(GetULONG(buffer + 8, bigEndian_),
+                        encodeCachedValue(GetULONG(datbuf + 4, bigEndian_),
                                           29,
                                           clientCache_.
                                           getSelectionOwnerSelectionCache, 9);
                     encodeBuffer.
-                        encodeCachedValue(GetULONG(buffer + 12, bigEndian_),
+                        encodeCachedValue(GetULONG(datbuf + 8, bigEndian_),
                                           32,
                                           clientCache_.
                                           setSelectionOwnerTimestampCache, 9);
@@ -1812,22 +1824,22 @@
             case X_TranslateCoords:
                 {
                     encodeBuffer.
-                        encodeCachedValue(GetULONG(buffer + 4, bigEndian_),
+                        encodeCachedValue(GetULONG(datbuf, bigEndian_),
                                           29,
                                           clientCache_.
                                           translateCoordsSrcCache, 9);
                     encodeBuffer.
-                        encodeCachedValue(GetULONG(buffer + 8, bigEndian_),
+                        encodeCachedValue(GetULONG(datbuf + 4, bigEndian_),
                                           29,
                                           clientCache_.
                                           translateCoordsDestCache, 9);
                     encodeBuffer.
-                        encodeCachedValue(GetUINT(buffer + 12, bigEndian_),
+                        encodeCachedValue(GetUINT(datbuf + 8, bigEndian_),
                                           16,
                                           clientCache_.translateCoordsXCache,
                                           8);
                     encodeBuffer.
-                        encodeCachedValue(GetUINT(buffer + 14, bigEndian_),
+                        encodeCachedValue(GetUINT(datbuf + 10, bigEndian_),
                                           16,
                                           clientCache_.translateCoordsYCache,
                                           8);
@@ -1837,10 +1849,9 @@
                 break;
             default:
                 {
-                    encodeBuffer.encodeValue((unsigned int) buffer[1], 8);
-                    encodeBuffer.encodeValue(GetUINT(buffer + 2, bigEndian_),
-                                             16, 8);
-                    const unsigned char *nextSrc = buffer + 4;
+                    encodeBuffer.encodeValue((unsigned int) datbyte, 8);
+                    encodeBuffer.encodeValue(buffer2, 16, 8);
+                    const unsigned char *nextSrc = datbuf;
 
                     for (unsigned int i = 4; i < size; i++)
                         encodeBuffer.encodeValue((unsigned int) *nextSrc++,
--- ClientReadBuffer.C-prePSz	2007-02-03 01:25:48.000000000 +1100
+++ ClientReadBuffer.C	2014-10-20 06:23:51.000000000 +1100
@@ -29,6 +29,21 @@
     else
     {
         dataLength = (GetUINT(start + 2, bigEndian_) << 2);
+        if (dataLength == 0)
+        {
+            // BIG-REQUESTS extension
+            if (size < 8)
+                return 0;
+            dataLength = (GetULONG(start + 4, bigEndian_) << 2);
+            if (dataLength < 8 || dataLength > 1024*1024*1024)
+            {
+                CERR << "BIG-REQUEST with unacceptable dataLength=" << dataLength << ENDL;
+            }
+            else if (dataLength < 4*64*1024)
+            {
+                CERR << "BIG-REQUEST with silly dataLength=" << dataLength << ENDL;
+            }
+        }
     }
 
     if (size < dataLength)
--- ServerChannel.C-prePSz	2007-02-03 01:25:48.000000000 +1100
+++ ServerChannel.C	2014-10-20 06:25:42.000000000 +1100
@@ -1302,6 +1302,9 @@
             clientCache_.lastRequestSequenceNum++;
             unsigned char *outputMessage;
             unsigned int outputLength;
+            // outputMessage and outputLength include the 4-byte header,
+            // just "right"(?) for the "plain" (not BIG-REQUESTS) case;
+            // but somewhat unlike the code in ClientChannel.
             unsigned int value; // general-purpose temp variable for decoding ints
 
             unsigned char cValue;       // general-purpose temp variable for decoding chars
@@ -1863,7 +1866,7 @@
                 {
                     unsigned int numPixels;
 
-                    decodeBuffer.decodeValue(numPixels, 16, 4);
+                    decodeBuffer.decodeValue(numPixels, 32, 4);
                     outputLength = 12 + (numPixels << 2);
                     outputMessage = writeBuffer_.addMessage(outputLength);
                     decodeBuffer.decodeCachedValue(value, 29,
@@ -2308,7 +2311,7 @@
                 {
                     unsigned int numPoints;
 
-                    decodeBuffer.decodeValue(numPoints, 16, 4);
+                    decodeBuffer.decodeValue(numPoints, 32, 4);
                     outputLength = (numPoints << 2) + 12;
                     outputMessage = writeBuffer_.addMessage(outputLength);
                     unsigned int relativeCoordMode;
@@ -2350,7 +2353,7 @@
                 {
                     unsigned int numPoints;
 
-                    decodeBuffer.decodeValue(numPoints, 16, 4);
+                    decodeBuffer.decodeValue(numPoints, 32, 4);
                     outputLength = (numPoints << 2) + 12;
                     outputMessage = writeBuffer_.addMessage(outputLength);
                     unsigned int relativeCoordMode;
@@ -2392,7 +2395,7 @@
                 {
                     unsigned int numRectangles;
 
-                    decodeBuffer.decodeValue(numRectangles, 16, 3);
+                    decodeBuffer.decodeValue(numRectangles, 32, 3);
                     outputLength = (numRectangles << 3) + 12;
                     outputMessage = writeBuffer_.addMessage(outputLength);
                     decodeBuffer.decodeCachedValue(value, 29,
@@ -2420,7 +2423,7 @@
                 {
                     unsigned int numSegments;
 
-                    decodeBuffer.decodeValue(numSegments, 16, 4);
+                    decodeBuffer.decodeValue(numSegments, 32, 4);
                     outputLength = (numSegments << 3) + 12;
                     outputMessage = writeBuffer_.addMessage(outputLength);
                     decodeBuffer.decodeCachedValue(value, 29,
@@ -2555,7 +2558,7 @@
                 break;
             case X_PutImage:
                 {
-                    decodeBuffer.decodeValue(value, 16, 8);
+                    decodeBuffer.decodeValue(value, 32, 8);
                     outputLength = (value << 2);
                     outputMessage = writeBuffer_.addMessage(outputLength);
                     decodeBuffer.decodeValue(value, 2);
@@ -2979,7 +2982,7 @@
                 {
                     unsigned int numColors;
 
-                    decodeBuffer.decodeValue(numColors, 16, 5);
+                    decodeBuffer.decodeValue(numColors, 32, 5);
                     outputLength = (numColors << 2) + 8;
                     outputMessage = writeBuffer_.addMessage(outputLength);
                     decodeBuffer.decodeCachedValue(value, 29,
@@ -3183,7 +3186,18 @@
                 }
             }
             *outputMessage = (unsigned char) opcode;
-            PutUINT(outputLength >> 2, outputMessage + 2, bigEndian_);
+            if (outputLength < 4*64*1024)
+                PutUINT(outputLength >> 2, outputMessage + 2, bigEndian_);
+            else
+            {
+                // Handle BIG-REQUEST
+                PutUINT(0, outputMessage + 2, bigEndian_);
+                // Write first four bytes
+                if (WriteAll(fd_, writeBuffer_.getData(), 4) < 0)
+                    return 0;
+                // Replace with new 4-byte length
+                PutULONG(1 + (outputLength >> 2), outputMessage, bigEndian_);
+            }
         }
     }
 

Reply via email to