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
diff --git a/rdppm.c b/rdppm.c
index f56d5cf..2e9b54d 100644
--- a/rdppm.c
+++ b/rdppm.c
@@ -68,6 +68,7 @@
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 @@
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 @@
val *= 10;
val += ch - '0';
}
+
+ if (val > maxval)
+ ERREXIT(cinfo, JERR_PPM_TOOLARGE);
+
return val;
}
@@ -139,10 +144,11 @@
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 @@
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 @@
}
/* 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 @@
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? */