Skip to content

Commit

Permalink
Merge pull request #4104 from radarhere/overrun
Browse files Browse the repository at this point in the history
Catch buffer overruns
  • Loading branch information
radarhere authored Sep 30, 2019
2 parents fb84701 + ab52630 commit cc16025
Show file tree
Hide file tree
Showing 7 changed files with 30 additions and 3 deletions.
Binary file added Tests/images/fli_overrun.bin
Binary file not shown.
Binary file added Tests/images/pcx_overrun.bin
Binary file not shown.
Binary file added Tests/images/sgi_overrun.bin
Binary file not shown.
9 changes: 9 additions & 0 deletions Tests/test_image.py
Original file line number Diff line number Diff line change
Expand Up @@ -589,6 +589,15 @@ def act(fp):

self.assertFalse(fp.closed)

def test_overrun(self):
for file in ["fli_overrun.bin", "sgi_overrun.bin", "pcx_overrun.bin"]:
im = Image.open(os.path.join("Tests/images", file))
try:
im.load()
self.assertFail()
except IOError as e:
self.assertEqual(str(e), "buffer overrun when reading image file")


class MockEncoder(object):
pass
Expand Down
14 changes: 11 additions & 3 deletions src/libImaging/FliDecode.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ ImagingFliDecode(Imaging im, ImagingCodecState state, UINT8* buf, Py_ssize_t byt
{
UINT8* ptr;
int framesize;
int c, chunks;
int c, chunks, advance;
int l, lines;
int i, j, x = 0, y, ymax;

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

chunks = I16(ptr+6);
ptr += 16;
bytes -= 16;

/* Process subchunks */
for (c = 0; c < chunks; c++) {
UINT8 *data = ptr + 6;
UINT8* data;
if (bytes < 10) {
state->errcode = IMAGING_CODEC_OVERRUN;
return -1;
}
data = ptr + 6;
switch (I16(ptr+4)) {
case 4: case 11:
/* FLI COLOR chunk */
Expand Down Expand Up @@ -198,7 +204,9 @@ ImagingFliDecode(Imaging im, ImagingCodecState state, UINT8* buf, Py_ssize_t byt
state->errcode = IMAGING_CODEC_UNKNOWN;
return -1;
}
ptr += I32(ptr);
advance = I32(ptr);
ptr += advance;
bytes -= advance;
}

return -1; /* end of frame */
Expand Down
5 changes: 5 additions & 0 deletions src/libImaging/PcxDecode.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ ImagingPcxDecode(Imaging im, ImagingCodecState state, UINT8* buf, Py_ssize_t byt
UINT8 n;
UINT8* ptr;

if (strcmp(im->mode, "1") == 0 && state->xsize > state->bytes * 8) {
state->errcode = IMAGING_CODEC_OVERRUN;
return -1;
}

ptr = buf;

for (;;) {
Expand Down
5 changes: 5 additions & 0 deletions src/libImaging/SgiRleDecode.c
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,11 @@ ImagingSgiRleDecode(Imaging im, ImagingCodecState state,
c->rlelength = c->lengthtab[c->rowno + c->channo * im->ysize];
c->rleoffset -= SGI_HEADER_SIZE;

if (c->rleoffset + c->rlelength > c->bufsize) {
state->errcode = IMAGING_CODEC_OVERRUN;
return -1;
}

/* row decompression */
if (c->bpc ==1) {
if(expandrow(&state->buffer[c->channo], &ptr[c->rleoffset], c->rlelength, im->bands))
Expand Down

0 comments on commit cc16025

Please # to comment.