Skip to content

Commit 6709e4a

Browse files
fbossendcommander
authored andcommitted
Check range of integer values in PPM text file
Add checks to ensure values are within the specified range. Fixes mozilla/mozjpeg#141, closes flutter#8
1 parent 82923eb commit 6709e4a

File tree

2 files changed

+17
-8
lines changed

2 files changed

+17
-8
lines changed

cderror.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ JMESSAGE(JWRN_GIF_NOMOREDATA, "Ran out of GIF bits")
7474
#ifdef PPM_SUPPORTED
7575
JMESSAGE(JERR_PPM_COLORSPACE, "PPM output must be grayscale or RGB")
7676
JMESSAGE(JERR_PPM_NONNUMERIC, "Nonnumeric data in PPM file")
77+
JMESSAGE(JERR_PPM_TOOLARGE, "Integer value too large in PPM file")
7778
JMESSAGE(JERR_PPM_NOT, "Not a PPM/PGM file")
7879
JMESSAGE(JTRC_PGM, "%ux%u PGM image")
7980
JMESSAGE(JTRC_PGM_TEXT, "%ux%u text PGM image")

rdppm.c

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ typedef struct {
6868
JSAMPROW pixrow; /* compressor input buffer */
6969
size_t buffer_width; /* width of I/O buffer */
7070
JSAMPLE *rescale; /* => maxval-remapping array, or NULL */
71+
int maxval;
7172
} ppm_source_struct;
7273

7374
typedef ppm_source_struct * ppm_source_ptr;
@@ -91,7 +92,7 @@ pbm_getc (FILE * infile)
9192

9293

9394
LOCAL(unsigned int)
94-
read_pbm_integer (j_compress_ptr cinfo, FILE * infile)
95+
read_pbm_integer (j_compress_ptr cinfo, FILE * infile, int maxval)
9596
/* Read an unsigned decimal integer from the PPM file */
9697
/* Swallows one trailing character after the integer */
9798
/* 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)
115116
val *= 10;
116117
val += ch - '0';
117118
}
119+
120+
if (val > maxval)
121+
ERREXIT(cinfo, JERR_PPM_TOOLARGE);
122+
118123
return val;
119124
}
120125

@@ -139,10 +144,11 @@ get_text_gray_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
139144
register JSAMPROW ptr;
140145
register JSAMPLE *rescale = source->rescale;
141146
JDIMENSION col;
147+
int maxval = source->maxval;
142148

143149
ptr = source->pub.buffer[0];
144150
for (col = cinfo->image_width; col > 0; col--) {
145-
*ptr++ = rescale[read_pbm_integer(cinfo, infile)];
151+
*ptr++ = rescale[read_pbm_integer(cinfo, infile, maxval)];
146152
}
147153
return 1;
148154
}
@@ -157,12 +163,13 @@ get_text_rgb_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
157163
register JSAMPROW ptr;
158164
register JSAMPLE *rescale = source->rescale;
159165
JDIMENSION col;
166+
int maxval = source->maxval;
160167

161168
ptr = source->pub.buffer[0];
162169
for (col = cinfo->image_width; col > 0; col--) {
163-
*ptr++ = rescale[read_pbm_integer(cinfo, infile)];
164-
*ptr++ = rescale[read_pbm_integer(cinfo, infile)];
165-
*ptr++ = rescale[read_pbm_integer(cinfo, infile)];
170+
*ptr++ = rescale[read_pbm_integer(cinfo, infile, maxval)];
171+
*ptr++ = rescale[read_pbm_integer(cinfo, infile, maxval)];
172+
*ptr++ = rescale[read_pbm_integer(cinfo, infile, maxval)];
166173
}
167174
return 1;
168175
}
@@ -311,16 +318,17 @@ start_input_ppm (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
311318
}
312319

313320
/* fetch the remaining header info */
314-
w = read_pbm_integer(cinfo, source->pub.input_file);
315-
h = read_pbm_integer(cinfo, source->pub.input_file);
316-
maxval = read_pbm_integer(cinfo, source->pub.input_file);
321+
w = read_pbm_integer(cinfo, source->pub.input_file, 65535);
322+
h = read_pbm_integer(cinfo, source->pub.input_file, 65535);
323+
maxval = read_pbm_integer(cinfo, source->pub.input_file, 65535);
317324

318325
if (w <= 0 || h <= 0 || maxval <= 0) /* error check */
319326
ERREXIT(cinfo, JERR_PPM_NOT);
320327

321328
cinfo->data_precision = BITS_IN_JSAMPLE; /* we always rescale data to this */
322329
cinfo->image_width = (JDIMENSION) w;
323330
cinfo->image_height = (JDIMENSION) h;
331+
source->maxval = maxval;
324332

325333
/* initialize flags to most common settings */
326334
need_iobuffer = TRUE; /* do we need an I/O buffer? */

0 commit comments

Comments
 (0)