summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn-Mark Bell <jmb@netsurf-browser.org>2015-11-21 11:20:59 (GMT)
committer John-Mark Bell <jmb@netsurf-browser.org>2015-11-21 11:20:59 (GMT)
commit5446c3c056f30d98c725e1899a92e104ad70c7e0 (patch)
tree5a9ce17455190c28008887c9ca0f4c05e3148b13
parent0c97f24173d461cd07e06da5f419bd1238cbd6e6 (diff)
downloadlibnsgif-5446c3c056f30d98c725e1899a92e104ad70c7e0.tar.gz
libnsgif-5446c3c056f30d98c725e1899a92e104ad70c7e0.tar.bz2
Improve checks for data buffer exhaustion
-rw-r--r--src/libnsgif.c30
1 files changed, 22 insertions, 8 deletions
diff --git a/src/libnsgif.c b/src/libnsgif.c
index dd44a43..0047ee0 100644
--- a/src/libnsgif.c
+++ b/src/libnsgif.c
@@ -513,6 +513,7 @@ static gif_result gif_initialise_frame(gif_animation *gif) {
/* Do some simple boundary checking
*/
+ if (gif_bytes < 10) return GIF_INSUFFICIENT_FRAME_DATA;
offset_x = gif_data[1] | (gif_data[2] << 8);
offset_y = gif_data[3] | (gif_data[4] << 8);
width = gif_data[5] | (gif_data[6] << 8);
@@ -574,20 +575,22 @@ static gif_result gif_initialise_frame(gif_animation *gif) {
/* Ensure we have a correct code size
*/
+ if (gif_bytes < 1)
+ return GIF_INSUFFICIENT_FRAME_DATA;
if (gif_data[0] > GIF_MAX_LZW)
return GIF_DATA_ERROR;
/* Move our pointer to the actual image data
*/
gif_data++;
- if (--gif_bytes < 0)
- return GIF_INSUFFICIENT_FRAME_DATA;
+ --gif_bytes;
/* Repeatedly skip blocks until we get a zero block or run out of data
* These blocks of image data are processed later by gif_decode_frame()
*/
block_size = 0;
while (block_size != 1) {
+ if (gif_bytes < 1) return GIF_INSUFFICIENT_FRAME_DATA;
block_size = gif_data[0] + 1;
/* Check if the frame data runs off the end of the file
*/
@@ -644,9 +647,10 @@ static gif_result gif_initialise_frame_extensions(gif_animation *gif, const int
/* Initialise the extensions
*/
- while (gif_data[0] == GIF_EXTENSION_INTRODUCER) {
+ while (gif_data < gif_end && gif_data[0] == GIF_EXTENSION_INTRODUCER) {
++gif_data;
- gif_bytes = (gif_end - gif_data);
+ if ((gif_bytes = (gif_end - gif_data)) < 1)
+ return GIF_INSUFFICIENT_FRAME_DATA;
/* Switch on extension label
*/
@@ -713,6 +717,7 @@ static gif_result gif_initialise_frame_extensions(gif_animation *gif, const int
* Skip the extension size itself
*/
default:
+ if (gif_bytes < 2) return GIF_INSUFFICIENT_FRAME_DATA;
gif_data += (2 + gif_data[1]);
}
@@ -721,7 +726,7 @@ static gif_result gif_initialise_frame_extensions(gif_animation *gif, const int
*/
gif_bytes = (gif_end - gif_data);
block_size = 0;
- while (gif_data[0] != GIF_BLOCK_TERMINATOR) {
+ while (gif_data < gif_end && gif_data[0] != GIF_BLOCK_TERMINATOR) {
block_size = gif_data[0] + 1;
if ((gif_bytes -= block_size) < 0)
return GIF_INSUFFICIENT_FRAME_DATA;
@@ -1070,8 +1075,10 @@ static gif_result gif_skip_frame_extensions(gif_animation *gif) {
/* Skip the extensions
*/
- while (gif_data[0] == GIF_EXTENSION_INTRODUCER) {
+ while (gif_data < gif_end && gif_data[0] == GIF_EXTENSION_INTRODUCER) {
++gif_data;
+ if (gif_data >= gif_end)
+ return GIF_INSUFFICIENT_FRAME_DATA;
/* Switch on extension label
*/
@@ -1088,6 +1095,8 @@ static gif_result gif_skip_frame_extensions(gif_animation *gif) {
* Skip the extension size itself
*/
default:
+ if (gif_data + 1 >= gif_end)
+ return GIF_INSUFFICIENT_FRAME_DATA;
gif_data += (2 + gif_data[1]);
}
@@ -1096,7 +1105,7 @@ static gif_result gif_skip_frame_extensions(gif_animation *gif) {
*/
gif_bytes = (gif_end - gif_data);
block_size = 0;
- while (gif_data[0] != GIF_BLOCK_TERMINATOR) {
+ while (gif_data < gif_end && gif_data[0] != GIF_BLOCK_TERMINATOR) {
block_size = gif_data[0] + 1;
if ((gif_bytes -= block_size) < 0)
return GIF_INSUFFICIENT_FRAME_DATA;
@@ -1188,7 +1197,8 @@ static bool gif_next_LZW(gif_animation *gif) {
return false;
}
block_size = 0;
- while (block_size != 1) {
+ while (block_size != 1 &&
+ gif->buffer_position < gif->buffer_size) {
block_size = gif->gif_data[gif->buffer_position] + 1;
gif->buffer_position += block_size;
}
@@ -1249,12 +1259,16 @@ static int gif_next_code(gif_animation *gif, int code_size) {
/* get the next block */
direct = gif->gif_data + gif->buffer_position;
+ if (gif->buffer_position >= gif->buffer_size)
+ return GIF_INSUFFICIENT_FRAME_DATA;
zero_data_block = ((count = direct[0]) == 0);
if ((gif->buffer_position + count) >= gif->buffer_size)
return GIF_INSUFFICIENT_FRAME_DATA;
if (count == 0)
get_done = true;
else {
+ if (gif->buffer_position + 3 >= gif->buffer_size)
+ return GIF_INSUFFICIENT_FRAME_DATA;
direct -= 1;
buf[2] = direct[2];
buf[3] = direct[3];