diff options
author | Brian Paul <brian.paul@tungstengraphics.com> | 2008-08-08 09:04:57 -0600 |
---|---|---|
committer | Brian Paul <brian.paul@tungstengraphics.com> | 2008-08-08 09:05:41 -0600 |
commit | 501338d70e96e0388fd5198625d856c4ec07745f (patch) | |
tree | 8d447958852eb42bd246d8c367635f3311001ee5 /src | |
parent | 919ec22ecf72aa163e1b97d8c7381002131ed32c (diff) |
mesa: fix out-of-bounds memory reads in swizzle_copy()
Diffstat (limited to 'src')
-rw-r--r-- | src/mesa/main/texstore.c | 120 |
1 files changed, 90 insertions, 30 deletions
diff --git a/src/mesa/main/texstore.c b/src/mesa/main/texstore.c index 853205ac95..25381e32dc 100644 --- a/src/mesa/main/texstore.c +++ b/src/mesa/main/texstore.c @@ -1,8 +1,8 @@ /* * Mesa 3-D graphics library - * Version: 6.5.1 + * Version: 7.1 * - * Copyright (C) 1999-2006 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"), @@ -663,56 +663,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 }; |