mesa: fix out-of-bounds memory reads in swizzle_copy()
authorBrian Paul <brian.paul@tungstengraphics.com>
Fri, 8 Aug 2008 15:08:44 +0000 (09:08 -0600)
committerBrian Paul <brian.paul@tungstengraphics.com>
Fri, 8 Aug 2008 15:08:44 +0000 (09:08 -0600)
src/mesa/main/texstore.c

index 97fdfd39b2a5a4bef11714086676c361b84cb3b2..9fe989aaebb95ee2e14716c7445378c7a93fa129 100644 (file)
@@ -2,7 +2,7 @@
  * Mesa 3-D graphics library
  * Version:  7.1
  *
- * Copyright (C) 1999-2007  Brian Paul   All Rights Reserved.
+ * Copyright (C) 1999-2008  Brian Paul   All Rights Reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -678,56 +678,116 @@ static void
 swizzle_copy(GLubyte *dst, GLuint dstComponents, const GLubyte *src, 
              GLuint srcComponents, const GLubyte *map, GLuint count)
 {
+#define SWZ_CPY(dst, src, count, dstComps, srcComps) \
+   do {                                              \
+      GLuint i;                                      \
+      for (i = 0; i < count; i++) {                  \
+         GLuint j;                                   \
+         if (srcComps == 4) {                        \
+            COPY_4UBV(tmp, src);                     \
+         }                                           \
+         else {                                      \
+            for (j = 0; j < srcComps; j++) {         \
+               tmp[j] = src[j];                      \
+            }                                        \
+         }                                           \
+         src += srcComps;                            \
+         for (j = 0; j < dstComps; j++) {            \
+            dst[j] = tmp[map[j]];                    \
+         }                                           \
+         dst += dstComps;                            \
+      }                                              \
+   } while (0)
+
    GLubyte tmp[6];
-   GLuint i;
 
    tmp[ZERO] = 0x0;
    tmp[ONE] = 0xff;
 
+   ASSERT(srcComponents <= 4);
+   ASSERT(dstComponents <= 4);
+
    switch (dstComponents) {
    case 4:
-      for (i = 0; i < count; i++) {
-        COPY_4UBV(tmp, src); 
-        src += srcComponents;      
-        dst[0] = tmp[map[0]];
-        dst[1] = tmp[map[1]];
-        dst[2] = tmp[map[2]];
-        dst[3] = tmp[map[3]];
-        dst += 4;
+      switch (srcComponents) {
+      case 4:
+         SWZ_CPY(dst, src, count, 4, 4);
+         break;
+      case 3:
+         SWZ_CPY(dst, src, count, 4, 3);
+         break;
+      case 2:
+         SWZ_CPY(dst, src, count, 4, 2);
+         break;
+      case 1:
+         SWZ_CPY(dst, src, count, 4, 1);
+         break;
+      default:
+         ;
       }
       break;
    case 3:
-      for (i = 0; i < count; i++) {
-        COPY_4UBV(tmp, src); 
-        src += srcComponents;      
-        dst[0] = tmp[map[0]];
-        dst[1] = tmp[map[1]];
-        dst[2] = tmp[map[2]];
-        dst += 3;
+      switch (srcComponents) {
+      case 4:
+         SWZ_CPY(dst, src, count, 3, 4);
+         break;
+      case 3:
+         SWZ_CPY(dst, src, count, 3, 3);
+         break;
+      case 2:
+         SWZ_CPY(dst, src, count, 3, 2);
+         break;
+      case 1:
+         SWZ_CPY(dst, src, count, 3, 1);
+         break;
+      default:
+         ;
       }
       break;
    case 2:
-      for (i = 0; i < count; i++) {
-        COPY_4UBV(tmp, src); 
-        src += srcComponents;      
-        dst[0] = tmp[map[0]];
-        dst[1] = tmp[map[1]];
-        dst += 2;
+      switch (srcComponents) {
+      case 4:
+         SWZ_CPY(dst, src, count, 2, 4);
+         break;
+      case 3:
+         SWZ_CPY(dst, src, count, 2, 3);
+         break;
+      case 2:
+         SWZ_CPY(dst, src, count, 2, 2);
+         break;
+      case 1:
+         SWZ_CPY(dst, src, count, 2, 1);
+         break;
+      default:
+         ;
       }
       break;
    case 1:
-      /* XXX investigate valgrind invalid read when running demos/texenv.c */
-      for (i = 0; i < count; i++) {
-        COPY_4UBV(tmp, src); 
-        src += srcComponents;      
-        dst[0] = tmp[map[0]];
-        dst += 1;
+      switch (srcComponents) {
+      case 4:
+         SWZ_CPY(dst, src, count, 1, 4);
+         break;
+      case 3:
+         SWZ_CPY(dst, src, count, 1, 3);
+         break;
+      case 2:
+         SWZ_CPY(dst, src, count, 1, 2);
+         break;
+      case 1:
+         SWZ_CPY(dst, src, count, 1, 1);
+         break;
+      default:
+         ;
       }
       break;
+   default:
+      ;
    }
+#undef SWZ_CPY
 }
 
 
+
 static const GLubyte map_identity[6] = { 0, 1, 2, 3, ZERO, ONE };
 static const GLubyte map_3210[6] = { 3, 2, 1, 0, ZERO, ONE };