Fixed out-of-bounds memory write problem (CONVERT_TEXEL_DWORD macro).

Renamed 'packing' to 'unpacking' since we're moving data from client -> GL.
Rnamed DST_ROW_WIDTH to DST_ROW_BYTES.
This commit is contained in:
Brian Paul 2002-02-21 15:12:31 +00:00
parent d0271502f8
commit c7a3356746
2 changed files with 167 additions and 114 deletions

View File

@ -1,10 +1,10 @@
/* $Id: texutil.c,v 1.25 2001/06/15 15:22:08 brianp Exp $ */
/* $Id: texutil.c,v 1.26 2002/02/21 15:12:31 brianp Exp $ */
/*
* Mesa 3-D graphics library
* Version: 3.5
* Version: 4.0.2
*
* Copyright (C) 1999-2001 Brian Paul All Rights Reserved.
* Copyright (C) 1999-2002 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"),
@ -52,7 +52,7 @@ struct gl_texture_convert {
/* Needed for subimage replacement */
GLenum format, type; /* Source (user) format and type */
const struct gl_pixelstore_attrib *packing;
const struct gl_pixelstore_attrib *unpacking;
const GLvoid *srcImage;
GLvoid *dstImage;
@ -63,7 +63,7 @@ struct gl_texture_convert {
typedef GLboolean (*convert_func)( struct gl_texture_convert *convert );
#define CONVERT_STRIDE_BIT 0x1
#define CONVERT_PACKING_BIT 0x2
#define CONVERT_UNPACKING_BIT 0x2
@ -681,23 +681,23 @@ static convert_func gl_convert_texsubimage3d_tab[] = {
/* See if we need to care about the pixel store attributes when we're
* converting the texture image. This should be stored as
* packing->_SomeBoolean and updated when the values change, to avoid
* unpacking->_SomeBoolean and updated when the values change, to avoid
* testing every time...
*/
static INLINE GLboolean
convert_needs_packing( const struct gl_pixelstore_attrib *packing,
convert_needs_unpacking( const struct gl_pixelstore_attrib *unpacking,
GLenum format, GLenum type )
{
if ( ( packing->Alignment == 1 ||
( packing->Alignment == 4 && /* Pick up the common Q3A case... */
if ( ( unpacking->Alignment == 1 ||
( unpacking->Alignment == 4 && /* Pick up the common Q3A case... */
format == GL_RGBA && type == GL_UNSIGNED_BYTE ) ) &&
packing->RowLength == 0 &&
packing->SkipPixels == 0 &&
packing->SkipRows == 0 &&
packing->ImageHeight == 0 &&
packing->SkipImages == 0 &&
packing->SwapBytes == GL_FALSE &&
packing->LsbFirst == GL_FALSE ) {
unpacking->RowLength == 0 &&
unpacking->SkipPixels == 0 &&
unpacking->SkipRows == 0 &&
unpacking->ImageHeight == 0 &&
unpacking->SkipImages == 0 &&
unpacking->SwapBytes == GL_FALSE &&
unpacking->LsbFirst == GL_FALSE ) {
return GL_FALSE;
} else {
return GL_TRUE;
@ -710,12 +710,12 @@ _mesa_convert_texsubimage1d( GLint mesaFormat,
GLint xoffset,
GLint width,
GLenum format, GLenum type,
const struct gl_pixelstore_attrib *packing,
const struct gl_pixelstore_attrib *unpacking,
const GLvoid *srcImage, GLvoid *dstImage )
{
struct gl_texture_convert convert;
ASSERT( packing );
ASSERT( unpacking );
ASSERT( srcImage );
ASSERT( dstImage );
@ -730,14 +730,14 @@ _mesa_convert_texsubimage1d( GLint mesaFormat,
convert.height = 1;
convert.format = format;
convert.type = type;
convert.packing = packing;
convert.unpacking = unpacking;
convert.srcImage = srcImage;
convert.dstImage = dstImage;
convert.index = 0;
if ( convert_needs_packing( packing, format, type ) )
convert.index |= CONVERT_PACKING_BIT;
if ( convert_needs_unpacking( unpacking, format, type ) )
convert.index |= CONVERT_UNPACKING_BIT;
return gl_convert_texsubimage2d_tab[mesaFormat]( &convert );
}
@ -764,7 +764,7 @@ _mesa_convert_texsubimage1d( GLint mesaFormat,
* width, height - incoming image size, also size of dest region.
* dstImageWidth - width (row stride) of dest image in pixels
* format, type - incoming image format and type
* packing - describes incoming image packing
* unpacking - describes incoming image unpacking
* srcImage - pointer to source image
* destImage - pointer to dest image
*/
@ -774,12 +774,12 @@ _mesa_convert_texsubimage2d( GLint mesaFormat,
GLint width, GLint height,
GLint destImageWidth,
GLenum format, GLenum type,
const struct gl_pixelstore_attrib *packing,
const struct gl_pixelstore_attrib *unpacking,
const GLvoid *srcImage, GLvoid *dstImage )
{
struct gl_texture_convert convert;
ASSERT( packing );
ASSERT( unpacking );
ASSERT( srcImage );
ASSERT( dstImage );
@ -795,14 +795,14 @@ _mesa_convert_texsubimage2d( GLint mesaFormat,
convert.dstImageWidth = destImageWidth;
convert.format = format;
convert.type = type;
convert.packing = packing;
convert.unpacking = unpacking;
convert.srcImage = srcImage;
convert.dstImage = dstImage;
convert.index = 0;
if ( convert_needs_packing( packing, format, type ) )
convert.index |= CONVERT_PACKING_BIT;
if ( convert_needs_unpacking( unpacking, format, type ) )
convert.index |= CONVERT_UNPACKING_BIT;
if ( width != destImageWidth )
convert.index |= CONVERT_STRIDE_BIT;
@ -816,12 +816,12 @@ _mesa_convert_texsubimage3d( GLint mesaFormat,
GLint width, GLint height, GLint depth,
GLint dstImageWidth, GLint dstImageHeight,
GLenum format, GLenum type,
const struct gl_pixelstore_attrib *packing,
const struct gl_pixelstore_attrib *unpacking,
const GLvoid *srcImage, GLvoid *dstImage )
{
struct gl_texture_convert convert;
ASSERT( packing );
ASSERT( unpacking );
ASSERT( srcImage );
ASSERT( dstImage );
@ -840,14 +840,14 @@ _mesa_convert_texsubimage3d( GLint mesaFormat,
convert.dstImageHeight = dstImageHeight;
convert.format = format;
convert.type = type;
convert.packing = packing;
convert.unpacking = unpacking;
convert.srcImage = srcImage;
convert.dstImage = dstImage;
convert.index = 0;
if ( convert_needs_packing( packing, format, type ) )
convert.index |= CONVERT_PACKING_BIT;
if ( convert_needs_unpacking( unpacking, format, type ) )
convert.index |= CONVERT_UNPACKING_BIT;
if ( width != dstImageWidth || height != dstImageHeight )
convert.index |= CONVERT_STRIDE_BIT;

View File

@ -1,10 +1,10 @@
/* $Id: texutil_tmp.h,v 1.8 2001/04/20 19:21:41 brianp Exp $ */
/* $Id: texutil_tmp.h,v 1.9 2002/02/21 15:12:31 brianp Exp $ */
/*
* Mesa 3-D graphics library
* Version: 3.5
* Version: 4.0.2
*
* Copyright (C) 1999-2001 Brian Paul All Rights Reserved.
* Copyright (C) 1999-2002 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"),
@ -33,7 +33,7 @@
#define DST_TEXEL_BYTES (4 / DST_TEXELS_PER_DWORD)
#define DST_ROW_WIDTH (convert->width * DST_TEXEL_BYTES)
#define DST_ROW_BYTES (convert->width * DST_TEXEL_BYTES)
#define DST_ROW_STRIDE (convert->dstImageWidth * DST_TEXEL_BYTES)
#define DST_IMG_STRIDE (convert->dstImageWidth * \
convert->dstImageHeight * DST_TEXEL_BYTES)
@ -49,22 +49,27 @@ TAG(texsubimage2d)( struct gl_texture_convert *convert )
GLuint *dst = (GLuint *)((GLubyte *)convert->dstImage +
(convert->yoffset * convert->dstImageWidth +
convert->xoffset) * DST_TEXEL_BYTES);
GLint dwords, i;
(void) dwords; (void) i;
#if DEBUG_TEXUTIL
fprintf( stderr, __FUNCTION__ "\n" );
#endif
#ifdef CONVERT_DIRECT
MEMCPY( dst, src, convert->height * DST_ROW_WIDTH );
MEMCPY( dst, src, convert->height * DST_ROW_BYTES );
#else
dwords = (convert->width * convert->height +
DST_TEXELS_PER_DWORD - 1) / DST_TEXELS_PER_DWORD;
for ( i = 0 ; i < dwords ; i++ ) {
CONVERT_TEXEL_DWORD( *dst++, src );
src += SRC_TEXEL_BYTES * DST_TEXELS_PER_DWORD;
{
const GLint texels = convert->width * convert->height;
const GLint dwords = texels / DST_TEXELS_PER_DWORD;
const GLint leftover = texels - dwords * DST_TEXELS_PER_DWORD;
GLint i;
for ( i = 0 ; i < dwords ; i++ ) {
CONVERT_TEXEL_DWORD( *dst++, src );
src += SRC_TEXEL_BYTES * DST_TEXELS_PER_DWORD;
}
for ( i = 0; i < leftover; i++ ) {
CONVERT_TEXEL( *dst++, src );
src += SRC_TEXEL_BYTES;
}
}
#endif
@ -81,22 +86,26 @@ TAG(texsubimage3d)( struct gl_texture_convert *convert )
((convert->zoffset * convert->height +
convert->yoffset) * convert->width +
convert->xoffset) * DST_TEXEL_BYTES);
GLint dwords, i;
(void) dwords; (void) i;
#if DEBUG_TEXUTIL
fprintf( stderr, __FUNCTION__ "\n" );
#endif
#ifdef CONVERT_DIRECT
MEMCPY( dst, src, convert->depth * convert->height * DST_ROW_WIDTH );
MEMCPY( dst, src, convert->depth * convert->height * DST_ROW_BYTES );
#else
dwords = (convert->width * convert->height * convert->depth +
DST_TEXELS_PER_DWORD - 1) / DST_TEXELS_PER_DWORD;
for ( i = 0 ; i < dwords ; i++ ) {
CONVERT_TEXEL_DWORD( *dst++, src );
src += SRC_TEXEL_BYTES * DST_TEXELS_PER_DWORD;
{
const GLint texels = convert->width * convert->height * convert->depth;
const GLint dwords = texels / DST_TEXELS_PER_DWORD;
const GLint leftover = texels - dwords * DST_TEXELS_PER_DWORD;
GLint i;
for ( i = 0 ; i < dwords ; i++ ) {
CONVERT_TEXEL_DWORD( *dst++, src );
src += SRC_TEXEL_BYTES * DST_TEXELS_PER_DWORD;
}
for ( i = 0; i < leftover; i++ ) {
CONVERT_TEXEL( *dst++, src );
src += SRC_TEXEL_BYTES;
}
}
#endif
@ -182,42 +191,56 @@ TAG(texsubimage3d_stride)( struct gl_texture_convert *convert )
* PRE: Require pixelstore attribs, width == dstImageWidth.
*/
static GLboolean
TAG(texsubimage2d_pack)( struct gl_texture_convert *convert )
TAG(texsubimage2d_unpack)( struct gl_texture_convert *convert )
{
const GLubyte *src = (const GLubyte *)
_mesa_image_address( convert->packing, convert->srcImage,
_mesa_image_address( convert->unpacking, convert->srcImage,
convert->width, convert->height,
convert->format, convert->type, 0, 0, 0 );
const GLint srcRowStride =
_mesa_image_row_stride( convert->packing, convert->width,
_mesa_image_row_stride( convert->unpacking, convert->width,
convert->format, convert->type );
GLuint *dst = (GLuint *)((GLubyte *)convert->dstImage +
(convert->yoffset * convert->width +
convert->xoffset) * DST_TEXEL_BYTES);
GLint width;
GLint row, col;
(void) col;
#if DEBUG_TEXUTIL
fprintf( stderr, __FUNCTION__ "\n" );
#endif
width = ((convert->width + DST_TEXELS_PER_DWORD - 1)
& ~(DST_TEXELS_PER_DWORD - 1));
for ( row = 0 ; row < convert->height ; row++ ) {
#ifdef CONVERT_DIRECT
MEMCPY( dst, src, DST_ROW_STRIDE );
src += srcRowStride;
dst = (GLuint *)((GLubyte *)dst + DST_ROW_STRIDE);
#else
const GLubyte *srcRow = src;
for ( col = width / DST_TEXELS_PER_DWORD ; col ; col-- ) {
CONVERT_TEXEL_DWORD( *dst++, src );
src += SRC_TEXEL_BYTES * DST_TEXELS_PER_DWORD;
if (convert->width & (DST_TEXELS_PER_DWORD - 1)) {
/* Can't use dword conversion (i.e. when width = 1 and texels/dword = 2
* or width = 2 and texels/dword = 4).
*/
DST_TYPE *dst = (DST_TYPE *)((GLubyte *)convert->dstImage +
(convert->yoffset * convert->width +
convert->xoffset) * DST_TEXEL_BYTES);
for ( row = 0 ; row < convert->height ; row++ ) {
const GLubyte *srcRow = src;
for ( col = 0; col < convert->width; col++ ) {
CONVERT_TEXEL(*dst, src);
src += SRC_TEXEL_BYTES;
}
src = srcRow + srcRowStride;
}
src = srcRow + srcRowStride;
}
else {
/* the common case */
GLuint *dst = (GLuint *)((GLubyte *)convert->dstImage +
(convert->yoffset * convert->width +
convert->xoffset) * DST_TEXEL_BYTES);
for ( row = 0 ; row < convert->height ; row++ ) {
#ifdef CONVERT_DIRECT
MEMCPY( dst, src, DST_ROW_STRIDE );
src += srcRowStride;
dst = (GLuint *)((GLubyte *)dst + DST_ROW_STRIDE);
#else
const GLubyte *srcRow = src;
for ( col = convert->width / DST_TEXELS_PER_DWORD ; col ; col-- ) {
CONVERT_TEXEL_DWORD( *dst++, src );
src += SRC_TEXEL_BYTES * DST_TEXELS_PER_DWORD;
}
src = srcRow + srcRowStride;
#endif
}
}
return GL_TRUE;
@ -226,44 +249,69 @@ TAG(texsubimage2d_pack)( struct gl_texture_convert *convert )
/* PRE: as above, height == dstImageHeight also.
*/
static GLboolean
TAG(texsubimage3d_pack)( struct gl_texture_convert *convert )
TAG(texsubimage3d_unpack)( struct gl_texture_convert *convert )
{
const GLubyte *src = (const GLubyte *)
_mesa_image_address( convert->packing, convert->srcImage,
_mesa_image_address( convert->unpacking, convert->srcImage,
convert->width, convert->height,
convert->format, convert->type, 0, 0, 0 );
const GLint srcImgStride = (const GLubyte *)
_mesa_image_address( convert->unpacking, convert->srcImage,
convert->width, convert->height,
convert->format, convert->type, 1, 0, 0 ) - src;
const GLint srcRowStride =
_mesa_image_row_stride( convert->packing, convert->width,
_mesa_image_row_stride( convert->unpacking, convert->width,
convert->format, convert->type );
GLuint *dst = (GLuint *)((GLubyte *)convert->dstImage +
((convert->zoffset * convert->height +
convert->yoffset) * convert->width +
convert->xoffset) * DST_TEXEL_BYTES);
GLint width;
GLint row, col, img;
(void) col;
#if DEBUG_TEXUTIL
fprintf( stderr, __FUNCTION__ "\n" );
#endif
width = ((convert->width + DST_TEXELS_PER_DWORD - 1)
& ~(DST_TEXELS_PER_DWORD - 1));
for ( img = 0 ; img < convert->depth ; img++ ) {
for ( row = 0 ; row < convert->height ; row++ ) {
if (convert->width & (DST_TEXELS_PER_DWORD - 1)) {
/* Can't use dword conversion (i.e. when width = 1 and texels/dword = 2
* or width = 2 and texels/dword = 4).
*/
DST_TYPE *dst = (DST_TYPE *)((GLubyte *)convert->dstImage +
((convert->zoffset * convert->height +
convert->yoffset) * convert->width +
convert->xoffset) * DST_TEXEL_BYTES);
for ( img = 0 ; img < convert->depth ; img++ ) {
const GLubyte *srcImage = src;
for ( row = 0 ; row < convert->height ; row++ ) {
const GLubyte *srcRow = src;
for ( col = 0; col < convert->width; col++ ) {
CONVERT_TEXEL(*dst, src);
src += SRC_TEXEL_BYTES;
}
src = srcRow + srcRowStride;
}
src = srcImage + srcImgStride;
}
}
else {
/* the common case */
GLuint *dst = (GLuint *)((GLubyte *)convert->dstImage +
((convert->zoffset * convert->height +
convert->yoffset) * convert->width +
convert->xoffset) * DST_TEXEL_BYTES);
for ( img = 0 ; img < convert->depth ; img++ ) {
const GLubyte *srcImage = src;
for ( row = 0 ; row < convert->height ; row++ ) {
#ifdef CONVERT_DIRECT
MEMCPY( dst, src, DST_ROW_STRIDE );
src += srcRowStride;
dst = (GLuint *)((GLubyte *)dst + DST_ROW_STRIDE);
MEMCPY( dst, src, DST_ROW_STRIDE );
src += srcRowStride;
dst = (GLuint *)((GLubyte *)dst + DST_ROW_STRIDE);
#else
const GLubyte *srcRow = src;
for ( col = width / DST_TEXELS_PER_DWORD ; col ; col-- ) {
CONVERT_TEXEL_DWORD( *dst++, src );
src += SRC_TEXEL_BYTES * DST_TEXELS_PER_DWORD;
}
src = srcRow + srcRowStride;
const GLubyte *srcRow = src;
for ( col = convert->width / DST_TEXELS_PER_DWORD ; col ; col-- ) {
CONVERT_TEXEL_DWORD( *dst++, src );
src += SRC_TEXEL_BYTES * DST_TEXELS_PER_DWORD;
}
src = srcRow + srcRowStride;
#endif
}
src = srcImage + srcImgStride;
}
}
@ -276,14 +324,14 @@ TAG(texsubimage3d_pack)( struct gl_texture_convert *convert )
* PRE: Require pixelstore attribs, width != dstImageWidth.
*/
static GLboolean
TAG(texsubimage2d_stride_pack)( struct gl_texture_convert *convert )
TAG(texsubimage2d_stride_unpack)( struct gl_texture_convert *convert )
{
const GLubyte *src = (const GLubyte *)
_mesa_image_address( convert->packing, convert->srcImage,
_mesa_image_address( convert->unpacking, convert->srcImage,
convert->width, convert->height,
convert->format, convert->type, 0, 0, 0 );
const GLint srcRowStride =
_mesa_image_row_stride( convert->packing, convert->width,
_mesa_image_row_stride( convert->unpacking, convert->width,
convert->format, convert->type );
DST_TYPE *dst = (DST_TYPE *)((GLubyte *)convert->dstImage +
(convert->yoffset * convert->dstImageWidth +
@ -304,7 +352,7 @@ TAG(texsubimage2d_stride_pack)( struct gl_texture_convert *convert )
for ( row = 0 ; row < convert->height ; row++ ) {
#ifdef CONVERT_DIRECT
MEMCPY( dst, src, DST_ROW_WIDTH );
MEMCPY( dst, src, DST_ROW_BYTES );
src += srcRowStride;
dst += convert->dstImageWidth;
#else
@ -324,14 +372,18 @@ TAG(texsubimage2d_stride_pack)( struct gl_texture_convert *convert )
/* PRE: As above, or height != dstImageHeight also.
*/
static GLboolean
TAG(texsubimage3d_stride_pack)( struct gl_texture_convert *convert )
TAG(texsubimage3d_stride_unpack)( struct gl_texture_convert *convert )
{
const GLubyte *src = (const GLubyte *)
_mesa_image_address( convert->packing, convert->srcImage,
_mesa_image_address( convert->unpacking, convert->srcImage,
convert->width, convert->height,
convert->format, convert->type, 0, 0, 0 );
const GLint srcImgStride = (const GLubyte *)
_mesa_image_address( convert->unpacking, convert->srcImage,
convert->width, convert->height,
convert->format, convert->type, 1, 0, 0 ) - src;
const GLint srcRowStride =
_mesa_image_row_stride( convert->packing, convert->width,
_mesa_image_row_stride( convert->unpacking, convert->width,
convert->format, convert->type );
DST_TYPE *dst = (DST_TYPE *)((GLubyte *)convert->dstImage +
((convert->zoffset * convert->dstImageHeight +
@ -352,9 +404,10 @@ TAG(texsubimage3d_stride_pack)( struct gl_texture_convert *convert )
#endif
for ( img = 0 ; img < convert->depth ; img++ ) {
const GLubyte *srcImage = src;
for ( row = 0 ; row < convert->height ; row++ ) {
#ifdef CONVERT_DIRECT
MEMCPY( dst, src, DST_ROW_WIDTH );
MEMCPY( dst, src, DST_ROW_BYTES );
src += srcRowStride;
dst += convert->dstImageWidth;
#else
@ -367,7 +420,7 @@ TAG(texsubimage3d_stride_pack)( struct gl_texture_convert *convert )
dst += adjust;
#endif
}
/* FIXME: ... */
src = srcImage + srcImgStride;
}
return GL_TRUE;
@ -378,15 +431,15 @@ TAG(texsubimage3d_stride_pack)( struct gl_texture_convert *convert )
static convert_func TAG(texsubimage2d_tab)[] = {
TAG(texsubimage2d),
TAG(texsubimage2d_stride),
TAG(texsubimage2d_pack),
TAG(texsubimage2d_stride_pack),
TAG(texsubimage2d_unpack),
TAG(texsubimage2d_stride_unpack),
};
static convert_func TAG(texsubimage3d_tab)[] = {
TAG(texsubimage3d),
TAG(texsubimage3d_stride),
TAG(texsubimage3d_pack),
TAG(texsubimage3d_stride_pack),
TAG(texsubimage3d_unpack),
TAG(texsubimage3d_stride_unpack),
};
@ -397,7 +450,7 @@ static convert_func TAG(texsubimage3d_tab)[] = {
#undef SRC_TEXEL_BYTES
#undef DST_TEXEL_BYTES
#undef DST_ROW_WIDTH
#undef DST_ROW_BYTES
#undef DST_ROW_STRIDE
#undef CONVERT_TEXEL