mirror of
https://github.com/ioquake/ioq3.git
synced 2024-11-10 07:11:46 +00:00
don't read more memory than available in jpg decode
This commit is contained in:
parent
c77f537ae3
commit
7132b492dd
3 changed files with 30 additions and 10 deletions
|
@ -20,13 +20,18 @@
|
||||||
#include "jpeglib.h"
|
#include "jpeglib.h"
|
||||||
#include "jerror.h"
|
#include "jerror.h"
|
||||||
|
|
||||||
|
#ifndef MIN
|
||||||
|
#define MIN(a, b) ((a)<(b)?(a):(b))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* Expanded data source object for stdio input */
|
/* Expanded data source object for stdio input */
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
struct jpeg_source_mgr pub; /* public fields */
|
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 */
|
JOCTET * buffer; /* start of buffer */
|
||||||
boolean start_of_file; /* have we gotten any data yet? */
|
boolean start_of_file; /* have we gotten any data yet? */
|
||||||
} my_source_mgr;
|
} my_source_mgr;
|
||||||
|
@ -91,13 +96,26 @@ METHODDEF boolean
|
||||||
fill_input_buffer (j_decompress_ptr cinfo)
|
fill_input_buffer (j_decompress_ptr cinfo)
|
||||||
{
|
{
|
||||||
my_src_ptr src = (my_src_ptr) cinfo->src;
|
my_src_ptr src = (my_src_ptr) cinfo->src;
|
||||||
|
size_t nbytes = MIN(src->inbufbytes, INPUT_BUF_SIZE);
|
||||||
|
|
||||||
memcpy( src->buffer, src->infile, 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);
|
||||||
|
|
||||||
src->infile += INPUT_BUF_SIZE;
|
src->inbuf += nbytes;
|
||||||
|
src->inbufbytes -= nbytes;
|
||||||
|
}
|
||||||
|
|
||||||
src->pub.next_input_byte = src->buffer;
|
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;
|
src->start_of_file = FALSE;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -171,7 +189,7 @@ term_source (j_decompress_ptr cinfo)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
GLOBAL void
|
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;
|
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.skip_input_data = skip_input_data;
|
||||||
src->pub.resync_to_restart = jpeg_resync_to_restart; /* use default method */
|
src->pub.resync_to_restart = jpeg_resync_to_restart; /* use default method */
|
||||||
src->pub.term_source = term_source;
|
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.bytes_in_buffer = 0; /* forces fill_input_buffer on first read */
|
||||||
src->pub.next_input_byte = NULL; /* until buffer loaded */
|
src->pub.next_input_byte = NULL; /* until buffer loaded */
|
||||||
}
|
}
|
||||||
|
|
|
@ -874,7 +874,7 @@ EXTERN void jpeg_destroy_decompress JPP((j_decompress_ptr cinfo));
|
||||||
/* Standard data source and destination managers: stdio streams. */
|
/* Standard data source and destination managers: stdio streams. */
|
||||||
/* Caller is responsible for opening the file before and closing after. */
|
/* 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_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 */
|
/* Default parameter setup for compression */
|
||||||
EXTERN void jpeg_set_defaults JPP((j_compress_ptr cinfo));
|
EXTERN void jpeg_set_defaults JPP((j_compress_ptr cinfo));
|
||||||
|
|
|
@ -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 row_stride; /* physical row width in output buffer */
|
||||||
unsigned pixelcount, memcount;
|
unsigned pixelcount, memcount;
|
||||||
unsigned char *out;
|
unsigned char *out;
|
||||||
|
int len;
|
||||||
byte *fbuffer;
|
byte *fbuffer;
|
||||||
byte *buf;
|
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.
|
* requires it in order to read binary files.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
ri.FS_ReadFile ( ( char * ) filename, (void **)&fbuffer);
|
len = ri.FS_ReadFile ( ( char * ) filename, (void **)&fbuffer);
|
||||||
if (!fbuffer) {
|
if (!fbuffer || len < 0) {
|
||||||
return;
|
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) */
|
/* 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() */
|
/* Step 3: read file parameters with jpeg_read_header() */
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue