diff options
author | Vitaliy E Sugrobov | 2012-11-30 12:58:54 +0400 |
---|---|---|
committer | Paul B Mahol | 2012-11-30 14:33:58 +0000 |
commit | de0cb7f070dc941ea2d3f8a99dad497c852b4e35 (patch) | |
tree | 2d86c6950638e6912b1de5a7c59cb67c451a6093 /libavcodec | |
parent | 91499f4ee825502677dfc11b00205538720d0513 (diff) |
Additional checks to prevent overread.
Check for availability of some required amount of bytes in buffer before
reading further.
Signed-off-by: Vitaliy E Sugrobov <vsugrob@hotmail.com>
Diffstat (limited to 'libavcodec')
-rwxr-xr-x | libavcodec/gifdec.c | 24 |
1 files changed, 23 insertions, 1 deletions
diff --git a/libavcodec/gifdec.c b/libavcodec/gifdec.c index 887a253599..2213733e25 100755 --- a/libavcodec/gifdec.c +++ b/libavcodec/gifdec.c @@ -146,6 +146,10 @@ static int gif_read_image(GifState *s) int ret; uint8_t *idx; + /* At least 9 bytes of Image Descriptor. */ + if (s->bytestream_end < s->bytestream + 9) + return AVERROR_INVALIDDATA; + left = bytestream_get_le16(&s->bytestream); top = bytestream_get_le16(&s->bytestream); width = bytestream_get_le16(&s->bytestream); @@ -222,6 +226,10 @@ static int gif_read_image(GifState *s) } } + /* Expect at least 2 bytes: 1 for lzw code size and 1 for block size. */ + if (s->bytestream_end < s->bytestream + 2) + return AVERROR_INVALIDDATA; + /* now get the image data */ code_size = bytestream_get_byte(&s->bytestream); if ((ret = ff_lzw_decode_init(s->lzw, code_size, s->bytestream, @@ -296,7 +304,11 @@ static int gif_read_extension(GifState *s) { int ext_code, ext_len, i, gce_flags, gce_transparent_index; - /* extension */ + /* There must be at least 2 bytes: + * 1 for extension label and 1 for extension length. */ + if (s->bytestream_end < s->bytestream + 2) + return AVERROR_INVALIDDATA; + ext_code = bytestream_get_byte(&s->bytestream); ext_len = bytestream_get_byte(&s->bytestream); @@ -306,6 +318,12 @@ static int gif_read_extension(GifState *s) case GIF_GCE_EXT_LABEL: if (ext_len != 4) goto discard_ext; + + /* We need at least 5 bytes more: 4 is for extension body + * and 1 for next block size. */ + if (s->bytestream_end < s->bytestream + 5) + return AVERROR_INVALIDDATA; + s->transparent_color_index = -1; gce_flags = bytestream_get_byte(&s->bytestream); bytestream_get_le16(&s->bytestream); // delay during which the frame is shown @@ -332,6 +350,10 @@ static int gif_read_extension(GifState *s) /* NOTE: many extension blocks can come after */ discard_ext: while (ext_len != 0) { + /* There must be at least ext_len bytes and 1 for next block size byte. */ + if (s->bytestream_end < s->bytestream + ext_len + 1) + return AVERROR_INVALIDDATA; + for (i = 0; i < ext_len; i++) bytestream_get_byte(&s->bytestream); ext_len = bytestream_get_byte(&s->bytestream); |