From c529793fdb60a4b58e6914c4aa0e58e34f688f56 Mon Sep 17 00:00:00 2001 From: ludwig Date: Thu, 14 Feb 2008 11:13:42 +0000 Subject: don't read more memory than available in jpg decode git-svn-id: svn://svn.icculus.org/quake3/trunk@1259 edf5b092-35ff-0310-97b2-ce42778d08ea --- code/jpeg-6/jdatasrc.c | 33 ++++++++++++++++++++++++++------- code/jpeg-6/jpeglib.h | 2 +- code/renderer/tr_image_jpg.c | 7 ++++--- 3 files changed, 31 insertions(+), 11 deletions(-) diff --git a/code/jpeg-6/jdatasrc.c b/code/jpeg-6/jdatasrc.c index 0bf7866..b19d885 100644 --- a/code/jpeg-6/jdatasrc.c +++ b/code/jpeg-6/jdatasrc.c @@ -20,13 +20,18 @@ #include "jpeglib.h" #include "jerror.h" +#ifndef MIN +#define MIN(a, b) ((a)<(b)?(a):(b)) +#endif + /* Expanded data source object for stdio input */ typedef struct { struct jpeg_source_mgr pub; /* public fields */ - unsigned char *infile; /* source stream */ + unsigned char *inbuf; /* source stream */ + size_t inbufbytes; JOCTET * buffer; /* start of buffer */ boolean start_of_file; /* have we gotten any data yet? */ } my_source_mgr; @@ -91,13 +96,26 @@ METHODDEF boolean fill_input_buffer (j_decompress_ptr cinfo) { my_src_ptr src = (my_src_ptr) cinfo->src; + size_t nbytes = MIN(src->inbufbytes, INPUT_BUF_SIZE); + + if(!nbytes) + { + WARNMS(cinfo, JWRN_JPEG_EOF); + /* Insert a fake EOI marker */ + src->buffer[0] = (JOCTET) 0xFF; + src->buffer[1] = (JOCTET) JPEG_EOI; + nbytes = 2; + } + else + { + memcpy( src->buffer, src->inbuf, nbytes); - memcpy( src->buffer, src->infile, INPUT_BUF_SIZE ); - - src->infile += INPUT_BUF_SIZE; + src->inbuf += nbytes; + src->inbufbytes -= nbytes; + } src->pub.next_input_byte = src->buffer; - src->pub.bytes_in_buffer = INPUT_BUF_SIZE; + src->pub.bytes_in_buffer = nbytes; src->start_of_file = FALSE; return TRUE; @@ -171,7 +189,7 @@ term_source (j_decompress_ptr cinfo) */ GLOBAL void -jpeg_stdio_src (j_decompress_ptr cinfo, unsigned char *infile) +jpeg_mem_src (j_decompress_ptr cinfo, unsigned char *inbuf, size_t size) { my_src_ptr src; @@ -198,7 +216,8 @@ jpeg_stdio_src (j_decompress_ptr cinfo, unsigned char *infile) src->pub.skip_input_data = skip_input_data; src->pub.resync_to_restart = jpeg_resync_to_restart; /* use default method */ src->pub.term_source = term_source; - src->infile = infile; + src->inbuf = inbuf; + src->inbufbytes = size; src->pub.bytes_in_buffer = 0; /* forces fill_input_buffer on first read */ src->pub.next_input_byte = NULL; /* until buffer loaded */ } diff --git a/code/jpeg-6/jpeglib.h b/code/jpeg-6/jpeglib.h index edfdda1..a0e9e27 100644 --- a/code/jpeg-6/jpeglib.h +++ b/code/jpeg-6/jpeglib.h @@ -874,7 +874,7 @@ EXTERN void jpeg_destroy_decompress JPP((j_decompress_ptr cinfo)); /* Standard data source and destination managers: stdio streams. */ /* Caller is responsible for opening the file before and closing after. */ EXTERN void jpeg_stdio_dest JPP((j_compress_ptr cinfo, FILE * outfile)); -EXTERN void jpeg_stdio_src JPP((j_decompress_ptr cinfo, unsigned char *infile)); +EXTERN void jpeg_mem_src JPP((j_decompress_ptr cinfo, unsigned char *buffer, size_t size)); /* Default parameter setup for compression */ EXTERN void jpeg_set_defaults JPP((j_compress_ptr cinfo)); diff --git a/code/renderer/tr_image_jpg.c b/code/renderer/tr_image_jpg.c index cae7ccb..9add7dd 100644 --- a/code/renderer/tr_image_jpg.c +++ b/code/renderer/tr_image_jpg.c @@ -56,6 +56,7 @@ void LoadJPG( const char *filename, unsigned char **pic, int *width, int *height unsigned row_stride; /* physical row width in output buffer */ unsigned pixelcount, memcount; unsigned char *out; + int len; byte *fbuffer; byte *buf; @@ -65,8 +66,8 @@ void LoadJPG( const char *filename, unsigned char **pic, int *width, int *height * requires it in order to read binary files. */ - ri.FS_ReadFile ( ( char * ) filename, (void **)&fbuffer); - if (!fbuffer) { + len = ri.FS_ReadFile ( ( char * ) filename, (void **)&fbuffer); + if (!fbuffer || len < 0) { return; } @@ -84,7 +85,7 @@ void LoadJPG( const char *filename, unsigned char **pic, int *width, int *height /* Step 2: specify data source (eg, a file) */ - jpeg_stdio_src(&cinfo, fbuffer); + jpeg_mem_src(&cinfo, fbuffer, len); /* Step 3: read file parameters with jpeg_read_header() */ -- cgit v1.2.3