diff options
author | Frank Bossen <frank@bossentech.com> | 2014-12-29 19:42:20 +0100 |
---|---|---|
committer | DRC <information@libjpeg-turbo.org> | 2015-08-14 11:42:29 -0500 |
commit | 6709e4a0cfa44d4f54ee8ad05753d4aa9260cb91 (patch) | |
tree | 0f85237364149d3b9339bb32812eb984a7a73fa9 | |
parent | 82923eb93a2eacf4a593e00e3e672bbb86a8a3a0 (diff) | |
download | libjpeg-turbo-6709e4a0cfa44d4f54ee8ad05753d4aa9260cb91.tar.gz |
Check range of integer values in PPM text file
Add checks to ensure values are within the specified range.
Fixes mozilla/mozjpeg#141, closes #8
-rw-r--r-- | cderror.h | 1 | ||||
-rw-r--r-- | rdppm.c | 24 |
2 files changed, 17 insertions, 8 deletions
@@ -74,6 +74,7 @@ JMESSAGE(JWRN_GIF_NOMOREDATA, "Ran out of GIF bits") #ifdef PPM_SUPPORTED JMESSAGE(JERR_PPM_COLORSPACE, "PPM output must be grayscale or RGB") JMESSAGE(JERR_PPM_NONNUMERIC, "Nonnumeric data in PPM file") +JMESSAGE(JERR_PPM_TOOLARGE, "Integer value too large in PPM file") JMESSAGE(JERR_PPM_NOT, "Not a PPM/PGM file") JMESSAGE(JTRC_PGM, "%ux%u PGM image") JMESSAGE(JTRC_PGM_TEXT, "%ux%u text PGM image") @@ -68,6 +68,7 @@ typedef struct { JSAMPROW pixrow; /* compressor input buffer */ size_t buffer_width; /* width of I/O buffer */ JSAMPLE *rescale; /* => maxval-remapping array, or NULL */ + int maxval; } ppm_source_struct; typedef ppm_source_struct * ppm_source_ptr; @@ -91,7 +92,7 @@ pbm_getc (FILE * infile) LOCAL(unsigned int) -read_pbm_integer (j_compress_ptr cinfo, FILE * infile) +read_pbm_integer (j_compress_ptr cinfo, FILE * infile, int maxval) /* Read an unsigned decimal integer from the PPM file */ /* Swallows one trailing character after the integer */ /* Note that on a 16-bit-int machine, only values up to 64k can be read. */ @@ -115,6 +116,10 @@ read_pbm_integer (j_compress_ptr cinfo, FILE * infile) val *= 10; val += ch - '0'; } + + if (val > maxval) + ERREXIT(cinfo, JERR_PPM_TOOLARGE); + return val; } @@ -139,10 +144,11 @@ get_text_gray_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo) register JSAMPROW ptr; register JSAMPLE *rescale = source->rescale; JDIMENSION col; + int maxval = source->maxval; ptr = source->pub.buffer[0]; for (col = cinfo->image_width; col > 0; col--) { - *ptr++ = rescale[read_pbm_integer(cinfo, infile)]; + *ptr++ = rescale[read_pbm_integer(cinfo, infile, maxval)]; } return 1; } @@ -157,12 +163,13 @@ get_text_rgb_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo) register JSAMPROW ptr; register JSAMPLE *rescale = source->rescale; JDIMENSION col; + int maxval = source->maxval; ptr = source->pub.buffer[0]; for (col = cinfo->image_width; col > 0; col--) { - *ptr++ = rescale[read_pbm_integer(cinfo, infile)]; - *ptr++ = rescale[read_pbm_integer(cinfo, infile)]; - *ptr++ = rescale[read_pbm_integer(cinfo, infile)]; + *ptr++ = rescale[read_pbm_integer(cinfo, infile, maxval)]; + *ptr++ = rescale[read_pbm_integer(cinfo, infile, maxval)]; + *ptr++ = rescale[read_pbm_integer(cinfo, infile, maxval)]; } return 1; } @@ -311,9 +318,9 @@ start_input_ppm (j_compress_ptr cinfo, cjpeg_source_ptr sinfo) } /* fetch the remaining header info */ - w = read_pbm_integer(cinfo, source->pub.input_file); - h = read_pbm_integer(cinfo, source->pub.input_file); - maxval = read_pbm_integer(cinfo, source->pub.input_file); + w = read_pbm_integer(cinfo, source->pub.input_file, 65535); + h = read_pbm_integer(cinfo, source->pub.input_file, 65535); + maxval = read_pbm_integer(cinfo, source->pub.input_file, 65535); if (w <= 0 || h <= 0 || maxval <= 0) /* error check */ ERREXIT(cinfo, JERR_PPM_NOT); @@ -321,6 +328,7 @@ start_input_ppm (j_compress_ptr cinfo, cjpeg_source_ptr sinfo) cinfo->data_precision = BITS_IN_JSAMPLE; /* we always rescale data to this */ cinfo->image_width = (JDIMENSION) w; cinfo->image_height = (JDIMENSION) h; + source->maxval = maxval; /* initialize flags to most common settings */ need_iobuffer = TRUE; /* do we need an I/O buffer? */ |