From 9ce8f89cbcac7539ee4c7313ab1828d95100dce1 Mon Sep 17 00:00:00 2001 From: ludwig Date: Thu, 14 Feb 2008 11:12:59 +0000 Subject: make tga decoder more robust against corrupt files git-svn-id: svn://svn.icculus.org/quake3/trunk@1256 edf5b092-35ff-0310-97b2-ce42778d08ea --- code/renderer/tr_image.c | 51 ++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 41 insertions(+), 10 deletions(-) (limited to 'code/renderer/tr_image.c') diff --git a/code/renderer/tr_image.c b/code/renderer/tr_image.c index b008dae..a478609 100644 --- a/code/renderer/tr_image.c +++ b/code/renderer/tr_image.c @@ -1177,21 +1177,34 @@ static void LoadTGA ( const char *name, byte **pic, int *width, int *height) byte *pixbuf; int row, column; byte *buf_p; - byte *buffer; + byte *end; + byte *buffer = NULL; TargaHeader targa_header; byte *targa_rgba; + int length; *pic = NULL; + if(width) + *width = 0; + if(height) + *height = 0; + // // load the file // - ri.FS_ReadFile ( ( char * ) name, (void **)&buffer); - if (!buffer) { + length = ri.FS_ReadFile ( ( char * ) name, (void **)&buffer); + if (!buffer || length < 0) { return; } + if(length < 18) + { + ri.Error( ERR_DROP, "LoadTGA: header too short (%s)\n", name ); + } + buf_p = buffer; + end = buffer + length; targa_header.id_length = buf_p[0]; targa_header.colormap_type = buf_p[1]; @@ -1237,24 +1250,29 @@ static void LoadTGA ( const char *name, byte **pic, int *width, int *height) rows = targa_header.height; numPixels = columns * rows * 4; - if (width) - *width = columns; - if (height) - *height = rows; - if(!columns || !rows || numPixels > 0x7FFFFFFF || numPixels / columns / 4 != rows) { ri.Error (ERR_DROP, "LoadTGA: %s has an invalid image size\n", name); } + targa_rgba = ri.Malloc (numPixels); - *pic = targa_rgba; if (targa_header.id_length != 0) + { + if (buf_p + targa_header.id_length > end) + ri.Error( ERR_DROP, "LoadTGA: header too short (%s)\n", name ); + buf_p += targa_header.id_length; // skip TARGA image comment + } if ( targa_header.image_type==2 || targa_header.image_type == 3 ) { + if(buf_p + columns*rows*targa_header.pixel_size/8 > end) + { + ri.Error (ERR_DROP, "LoadTGA: file truncated (%s)\n", name); + } + // Uncompressed RGB or gray scale image for(row=rows-1; row>=0; row--) { @@ -1312,9 +1330,13 @@ static void LoadTGA ( const char *name, byte **pic, int *width, int *height) for(row=rows-1; row>=0; row--) { pixbuf = targa_rgba + row*columns*4; for(column=0; column end) + ri.Error (ERR_DROP, "LoadTGA: file truncated (%s)\n", name); packetHeader= *buf_p++; packetSize = 1 + (packetHeader & 0x7f); if (packetHeader & 0x80) { // run-length packet + if(buf_p + targa_header.pixel_size/8 > end) + ri.Error (ERR_DROP, "LoadTGA: file truncated (%s)\n", name); switch (targa_header.pixel_size) { case 24: blue = *buf_p++; @@ -1350,6 +1372,9 @@ static void LoadTGA ( const char *name, byte **pic, int *width, int *height) } } else { // non run-length packet + + if(buf_p + targa_header.pixel_size/8*packetSize > end) + ri.Error (ERR_DROP, "LoadTGA: file truncated (%s)\n", name); for(j=0;j