summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVincent Sanders <vince@kyllikki.org>2017-01-27 13:26:57 +0000
committerVincent Sanders <vince@kyllikki.org>2017-01-27 13:26:57 +0000
commita1617883903bf102af5d6712c9812261efe1ccb9 (patch)
tree3472d376ab5edbe1769319ef765050925af36963
parent83442501788be224b9da56c3c837a9024795ca8c (diff)
downloadlibnsgif-a1617883903bf102af5d6712c9812261efe1ccb9.tar.gz
libnsgif-a1617883903bf102af5d6712c9812261efe1ccb9.tar.bz2
fix buffer overrun due to LZW code clearing
The LZW code clearing function was not dealing with errors when obtaining the next code from the gif. this resulted in input buffer overruns and occasional segmentation faults.
-rw-r--r--src/libnsgif.c16
1 files changed, 14 insertions, 2 deletions
diff --git a/src/libnsgif.c b/src/libnsgif.c
index f241145..8422563 100644
--- a/src/libnsgif.c
+++ b/src/libnsgif.c
@@ -177,6 +177,7 @@ static int gif_next_code(gif_animation *gif, int code_size)
static gif_result gif_clear_codes_LZW(gif_animation *gif)
{
int i;
+ int code;
if (lzw->clear_code >= (1 << GIF_MAX_LZW)) {
lzw->stack_pointer = lzw->stack;
@@ -197,8 +198,13 @@ static gif_result gif_clear_codes_LZW(gif_animation *gif)
/* process repeated clear codes */
do {
- lzw->firstcode = lzw->oldcode = gif_next_code(gif, lzw->code_size);
- } while (lzw->firstcode == lzw->clear_code);
+ code = gif_next_code(gif, lzw->code_size);
+ if (code < 0) {
+ return code;
+ }
+ } while (code == lzw->clear_code);
+ lzw->firstcode = lzw->oldcode = code;
+
*lzw->stack_pointer++ = lzw->firstcode;
return GIF_OK;
@@ -219,6 +225,9 @@ static bool gif_next_LZW(gif_animation *gif)
if (code == lzw->clear_code) {
gif->current_error = gif_clear_codes_LZW(gif);
+ if (gif->current_error != GIF_OK) {
+ return false;
+ }
return true;
}
@@ -1053,6 +1062,9 @@ gif_internal_decode_frame(gif_animation *gif,
lzw->get_done = false;
lzw->direct = lzw->buf;
gif->current_error = gif_clear_codes_LZW(gif);
+ if (gif->current_error != GIF_OK) {
+ return gif->current_error;
+ }
/* Decompress the data */
for (y = 0; y < height; y++) {