summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrian Paul <[email protected]>2008-08-08 09:08:44 -0600
committerBrian Paul <[email protected]>2008-08-08 09:08:44 -0600
commit48cf46a29d8bccb0d83ae7e53e4ded44492cdb5f (patch)
tree78c554590dacb31f0cd10acbd29cbd0b93528a57
parent74d649d9a9e85be6dfec170b018b31626d40914b (diff)
mesa: fix out-of-bounds memory reads in swizzle_copy()
-rw-r--r--src/mesa/main/texstore.c118
1 files changed, 89 insertions, 29 deletions
diff --git a/src/mesa/main/texstore.c b/src/mesa/main/texstore.c
index 97fdfd39b2a..9fe989aaebb 100644
--- a/src/mesa/main/texstore.c
+++ b/src/mesa/main/texstore.c
@@ -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 };