From 5df2851f85778fb707fd57b565e57a2d634f9745 Mon Sep 17 00:00:00 2001 From: wiredfool Date: Sat, 19 Nov 2016 17:39:30 -0800 Subject: [PATCH] Fixed literal expansion, allowed run length > line length --- libImaging/SunRleDecode.c | 122 ++++++++++++++++++++++---------------- 1 file changed, 70 insertions(+), 52 deletions(-) diff --git a/libImaging/SunRleDecode.c b/libImaging/SunRleDecode.c index 6c240e400..9c126755f 100644 --- a/libImaging/SunRleDecode.c +++ b/libImaging/SunRleDecode.c @@ -7,7 +7,7 @@ * decoder for SUN RLE data. * * history: - * 97-01-04 fl Created + * 97-01-04 fl Created * * Copyright (c) Fredrik Lundh 1997. * Copyright (c) Secret Labs AB 1997. @@ -24,88 +24,106 @@ ImagingSunRleDecode(Imaging im, ImagingCodecState state, UINT8* buf, int bytes) { int n; UINT8* ptr; + UINT8 extra_data = 0; + UINT8 extra_bytes = 0; + int ct_bytes = 0; ptr = buf; for (;;) { - if (bytes < 1) - return ptr - buf; + if (bytes < 1) + return ptr - buf; - if (ptr[0] == 0x80) { + if (ptr[0] == 0x80) { - if (bytes < 2) - break; + if (bytes < 2) + break; - n = ptr[1]; + n = ptr[1]; - if (n == 0) { - /* Literal 0x80 (2 bytes) */ - n = 1; + if (n == 0) { - state->buffer[state->x] = 0x80; + /* Literal 0x80 (2 bytes) */ + n = 1; + ct_bytes += n; - ptr += 2; - bytes -= 2; + state->buffer[state->x] = 0x80; - } else { + ptr += 2; + bytes -= 2; - /* Run (3 bytes) */ - if (bytes < 3) - break; + } else { - if (state->x + n > state->bytes) { - /* FIXME: is this correct? */ - state->errcode = IMAGING_CODEC_OVERRUN; - return -1; - } + /* Run (3 bytes) */ + if (bytes < 3) + break; - memset(state->buffer + state->x, ptr[2], n); + ct_bytes += n; - ptr += 3; - bytes -= 3; + if (state->x + n > state->bytes) { + extra_bytes = n; /* full value */ + n = state->bytes - state->x; + extra_bytes -= n; + extra_data = ptr[2]; + } - } + memset(state->buffer + state->x, ptr[2], n); - } else { + ptr += 3; + bytes -= 3; - /* Literal (1+n bytes block) */ - n = ptr[0]; + } - if (bytes < 1 + n) - break; + } else { - if (state->x + n > state->bytes) { - /* FIXME: is this correct? */ - state->errcode = IMAGING_CODEC_OVERRUN; - return -1; - } + /* Literal byte */ + n = 1; + ct_bytes += n; - memcpy(state->buffer + state->x, ptr + 1, n); + state->buffer[state->x] = ptr[0]; - ptr += 1 + n; - bytes -= 1 + n; + ptr += 1; + bytes -= 1; - } + } - state->x += n; + for (;;) { + state->x += n; + + if (state->x >= state->bytes) { - if (state->x >= state->bytes) { + /* Got a full line, unpack it */ + state->shuffle((UINT8*) im->image[state->y + state->yoff] + + state->xoff * im->pixelsize, state->buffer, + state->xsize); - /* Got a full line, unpack it */ - state->shuffle((UINT8*) im->image[state->y + state->yoff] + - state->xoff * im->pixelsize, state->buffer, - state->xsize); + state->x = 0; - state->x = 0; + if (++state->y >= state->ysize) { + /* End of file (errcode = 0) */ + printf("%d", ct_bytes); + return -1; + } + } + + if (extra_bytes == 0) { + break; + } - if (++state->y >= state->ysize) { - /* End of file (errcode = 0) */ - return -1; - } - } + if (state->x > 0) { + break; // assert + } + if (extra_bytes >= state->bytes) { + n = state->bytes; + } else { + n = extra_bytes; + } + memset(state->buffer + state->x, extra_data, n); + extra_bytes -= n; + } } return ptr - buf;