Skip to content

Commit cc16025

Browse files
authored
Merge pull request #4104 from radarhere/overrun
Catch buffer overruns
2 parents fb84701 + ab52630 commit cc16025

File tree

7 files changed

+30
-3
lines changed

7 files changed

+30
-3
lines changed

Tests/images/fli_overrun.bin

188 Bytes
Binary file not shown.

Tests/images/pcx_overrun.bin

258 Bytes
Binary file not shown.

Tests/images/sgi_overrun.bin

4 KB
Binary file not shown.

Tests/test_image.py

+9
Original file line numberDiff line numberDiff line change
@@ -589,6 +589,15 @@ def act(fp):
589589

590590
self.assertFalse(fp.closed)
591591

592+
def test_overrun(self):
593+
for file in ["fli_overrun.bin", "sgi_overrun.bin", "pcx_overrun.bin"]:
594+
im = Image.open(os.path.join("Tests/images", file))
595+
try:
596+
im.load()
597+
self.assertFail()
598+
except IOError as e:
599+
self.assertEqual(str(e), "buffer overrun when reading image file")
600+
592601

593602
class MockEncoder(object):
594603
pass

src/libImaging/FliDecode.c

+11-3
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ ImagingFliDecode(Imaging im, ImagingCodecState state, UINT8* buf, Py_ssize_t byt
3030
{
3131
UINT8* ptr;
3232
int framesize;
33-
int c, chunks;
33+
int c, chunks, advance;
3434
int l, lines;
3535
int i, j, x = 0, y, ymax;
3636

@@ -59,10 +59,16 @@ ImagingFliDecode(Imaging im, ImagingCodecState state, UINT8* buf, Py_ssize_t byt
5959

6060
chunks = I16(ptr+6);
6161
ptr += 16;
62+
bytes -= 16;
6263

6364
/* Process subchunks */
6465
for (c = 0; c < chunks; c++) {
65-
UINT8 *data = ptr + 6;
66+
UINT8* data;
67+
if (bytes < 10) {
68+
state->errcode = IMAGING_CODEC_OVERRUN;
69+
return -1;
70+
}
71+
data = ptr + 6;
6672
switch (I16(ptr+4)) {
6773
case 4: case 11:
6874
/* FLI COLOR chunk */
@@ -198,7 +204,9 @@ ImagingFliDecode(Imaging im, ImagingCodecState state, UINT8* buf, Py_ssize_t byt
198204
state->errcode = IMAGING_CODEC_UNKNOWN;
199205
return -1;
200206
}
201-
ptr += I32(ptr);
207+
advance = I32(ptr);
208+
ptr += advance;
209+
bytes -= advance;
202210
}
203211

204212
return -1; /* end of frame */

src/libImaging/PcxDecode.c

+5
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,11 @@ ImagingPcxDecode(Imaging im, ImagingCodecState state, UINT8* buf, Py_ssize_t byt
2222
UINT8 n;
2323
UINT8* ptr;
2424

25+
if (strcmp(im->mode, "1") == 0 && state->xsize > state->bytes * 8) {
26+
state->errcode = IMAGING_CODEC_OVERRUN;
27+
return -1;
28+
}
29+
2530
ptr = buf;
2631

2732
for (;;) {

src/libImaging/SgiRleDecode.c

+5
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,11 @@ ImagingSgiRleDecode(Imaging im, ImagingCodecState state,
157157
c->rlelength = c->lengthtab[c->rowno + c->channo * im->ysize];
158158
c->rleoffset -= SGI_HEADER_SIZE;
159159

160+
if (c->rleoffset + c->rlelength > c->bufsize) {
161+
state->errcode = IMAGING_CODEC_OVERRUN;
162+
return -1;
163+
}
164+
160165
/* row decompression */
161166
if (c->bpc ==1) {
162167
if(expandrow(&state->buffer[c->channo], &ptr[c->rleoffset], c->rlelength, im->bands))

0 commit comments

Comments
 (0)