x11drv fix for bug#4506: page fault on read access

Rein Klazes wijn at wanadoo.nl
Sat Feb 18 06:57:51 CST 2006


Hi,

Fixing bug #4506: unaligned 32bit access, can access one byte beyond the
pixel buffer.

Changelog:
dlls/x11drv	: dib_convert.c
Avoid unaligned 32 bit reads, and reads beyond the input pixel buffer in
the convert_888_to_0888_* functions.

Rein.
-------------- next part --------------
--- wine/dlls/x11drv/dib_convert.c	2006-02-10 08:41:04.000000000 +0100
+++ mywine/dlls/x11drv/dib_convert.c	2006-02-16 08:41:52.000000000 +0100
@@ -818,37 +818,39 @@ static void convert_888_to_0888_asis(int
                                      const void* srcbits, int srclinebytes,
                                      void* dstbits, int dstlinebytes)
 {
-    const DWORD* srcpixel;
+    const BYTE* srcpixel;
     DWORD* dstpixel;
+    DWORD prev, curr;
     int x,y;
-    int oddwidth;
 
-    oddwidth=width & 3;
-    width=width/4;
     for (y=0; y<height; y++) {
         srcpixel=srcbits;
         dstpixel=dstbits;
-        for (x=0; x<width; x++) {
-            /* Do 4 pixels at a time: 3 dwords in and 4 dwords out */
-            DWORD srcval1,srcval2;
-            srcval1=srcpixel[0];
-            dstpixel[0]=( srcval1        & 0x00ffffff);  /* h1, g1, l1 */
-            srcval2=srcpixel[1];
-            dstpixel[1]=( srcval1 >> 24) |              /* l2 */
-                        ((srcval2 <<  8) & 0x00ffff00); /* h2, g2 */
-            srcval1=srcpixel[2];
-            dstpixel[2]=( srcval2 >> 16) |              /* g3, l3 */
-                        ((srcval1 << 16) & 0x00ff0000); /* h3 */
-            dstpixel[3]=( srcval1 >>  8);               /* h4, g4, l4 */
-            srcpixel+=3;
-            dstpixel+=4;
-        }
-        /* And now up to 3 odd pixels */
-        for (x=0; x<oddwidth; x++) {
-            DWORD srcval;
-            srcval=*srcpixel;
-            srcpixel=(const DWORD*)(((const char*)srcpixel)+3);
-            *dstpixel++=( srcval         & 0x00ffffff); /* h, g, l */
+        curr = *(const DWORD*)( (int)srcpixel & 0xfffffffc);
+        for( x = 0; x < width; x++) {
+            switch( (int)srcpixel & 0x3) {
+                case 0:
+                    curr = *(const DWORD*)( srcpixel);
+                    *dstpixel = ( curr        & 0x00ffffff);  /* h1, g1, l1 */
+                    break;
+                case 3:
+                    prev = curr;
+                    curr = *(const DWORD*)( srcpixel + 1);
+                    *dstpixel = ( prev >> 24) |              /* l2 */
+                                ((curr <<  8) & 0x00ffff00); /* h2, g2 */
+                    break;
+                case 2:
+                    prev = curr;
+                    curr = *(const DWORD*)( srcpixel + 2);
+                    *dstpixel = ( prev >> 16) |              /* g3, l3 */
+                                ((curr << 16) & 0x00ff0000); /* h3 */
+                    break;
+                case 1:
+                    *dstpixel = ( curr >>  8);               /* h4, g4, l4 */
+                    break;
+            }
+            dstpixel++;
+            srcpixel += 3;
         }
         srcbits = (const char*)srcbits + srclinebytes;
         dstbits = (char*)dstbits + dstlinebytes;
@@ -859,46 +861,45 @@ static void convert_888_to_0888_reverse(
                                         const void* srcbits, int srclinebytes,
                                         void* dstbits, int dstlinebytes)
 {
-    const DWORD* srcpixel;
+    const BYTE* srcpixel;
     DWORD* dstpixel;
+    DWORD prev, curr;
     int x,y;
-    int oddwidth;
 
-    oddwidth=width & 3;
-    width=width/4;
     for (y=0; y<height; y++) {
         srcpixel=srcbits;
         dstpixel=dstbits;
-        for (x=0; x<width; x++) {
-            /* Do 4 pixels at a time: 3 dwords in and 4 dwords out */
-            DWORD srcval1,srcval2;
-
-            srcval1=srcpixel[0];
-            dstpixel[0]=((srcval1 >> 16) & 0x0000ff) | /* h1 */
-                        ( srcval1        & 0x00ff00) | /* g1 */
-                        ((srcval1 << 16) & 0xff0000);  /* l1 */
-            srcval2=srcpixel[1];
-            dstpixel[1]=((srcval1 >>  8) & 0xff0000) | /* l2 */
-                        ((srcval2 <<  8) & 0x00ff00) | /* g2 */
-                        ((srcval2 >>  8) & 0x0000ff);  /* h2 */
-            srcval1=srcpixel[2];
-            dstpixel[2]=( srcval2        & 0xff0000) | /* l3 */
-                        ((srcval2 >> 16) & 0x00ff00) | /* g3 */
-                        ( srcval1        & 0x0000ff);  /* h3 */
-            dstpixel[3]=((srcval1 >> 24) & 0x0000ff) | /* h4 */
-                        ((srcval1 >>  8) & 0x00ff00) | /* g4 */
-                        ((srcval1 <<  8) & 0xff0000);  /* l4 */
-            srcpixel+=3;
-            dstpixel+=4;
-        }
-        /* And now up to 3 odd pixels */
-        for (x=0; x<oddwidth; x++) {
-            DWORD srcval;
-            srcval=*srcpixel;
-            srcpixel=(const DWORD*)(((const char*)srcpixel)+3);
-            *dstpixel++=((srcval  >> 16) & 0x0000ff) | /* h */
-                        ( srcval         & 0x00ff00) | /* g */
-                        ((srcval  << 16) & 0xff0000);  /* l */
+        curr = *(const DWORD*)( (int)srcpixel & 0xfffffffc);
+        for( x = 0; x < width; x++) {
+            switch( (int)srcpixel & 0x3) {
+                case 0:
+                    curr = *(const DWORD*)( srcpixel);
+                    *dstpixel = ((curr >> 16) & 0x0000ff) | /* h1 */
+                                ( curr        & 0x00ff00) | /* g1 */
+                                ((curr << 16) & 0xff0000);  /* l1 */
+                    break;
+                case 3:
+                    prev = curr;
+                    curr = *(const DWORD*)( srcpixel + 1);
+                    *dstpixel = ((prev >>  8) & 0xff0000) | /* l2 */
+                                ((curr <<  8) & 0x00ff00) | /* g2 */
+                                ((curr >>  8) & 0x0000ff);  /* h2 */
+                    break;
+                case 2:
+                    prev = curr;
+                    curr = *(const DWORD*)( srcpixel + 2);
+                    *dstpixel = ( prev        & 0xff0000) | /* l3 */
+                                ((prev >> 16) & 0x00ff00) | /* g3 */
+                                ( curr        & 0x0000ff);  /* h3 */
+                    break;
+                case 1:
+                    *dstpixel = ((curr >> 24) & 0x0000ff) | /* h4 */
+                                ((curr >>  8) & 0x00ff00) | /* g4 */
+                                ((curr <<  8) & 0xff0000);  /* l4 */
+                    break;
+            }
+            dstpixel++;
+            srcpixel += 3;
         }
         srcbits = (const char*)srcbits + srclinebytes;
         dstbits = (char*)dstbits + dstlinebytes;


More information about the wine-patches mailing list