aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVitaliy E Sugrobov <vsugrob@hotmail.com>2012-11-30 12:58:54 +0400
committerPaul B Mahol <onemda@gmail.com>2012-11-30 14:33:58 +0000
commitde0cb7f070dc941ea2d3f8a99dad497c852b4e35 (patch)
tree2d86c6950638e6912b1de5a7c59cb67c451a6093
parent91499f4ee825502677dfc11b00205538720d0513 (diff)
downloadffmpeg-de0cb7f070dc941ea2d3f8a99dad497c852b4e35.tar.gz
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>
-rwxr-xr-xlibavcodec/gifdec.c24
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);