Skip to content

Commit

Permalink
Check range of integer values in PPM text file
Browse files Browse the repository at this point in the history
Add checks to ensure values are within the specified range.

Fixes mozilla/mozjpeg#141, closes libjpeg-turbo#8
  • Loading branch information
fbossen authored and dcommander committed Aug 14, 2015
1 parent d0bba12 commit f7e21f0
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 8 deletions.
1 change: 1 addition & 0 deletions cderror.h
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand Down
24 changes: 16 additions & 8 deletions rdppm.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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. */
Expand All @@ -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;
}

Expand All @@ -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;
}
Expand All @@ -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;
}
Expand Down Expand Up @@ -311,16 +318,17 @@ 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);

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? */
Expand Down

0 comments on commit f7e21f0

Please sign in to comment.