aboutsummaryrefslogtreecommitdiffstats
path: root/libavcodec
diff options
context:
space:
mode:
authorMichael Niedermayer <michaelni@gmx.at>2013-10-08 01:41:20 +0200
committerMichael Niedermayer <michaelni@gmx.at>2013-10-08 01:41:20 +0200
commit8d14e1d64ee1780f839e05c22fc633b3cf1b8579 (patch)
tree9a2259418c83ee5f4397f0fc921b52e45f817269 /libavcodec
parent5da68aff96ff77b0f82d80f250e23c2f3696938b (diff)
parent7e350b7ddd19af856b55634233d609e29baab646 (diff)
downloadffmpeg-8d14e1d64ee1780f839e05c22fc633b3cf1b8579.tar.gz
Merge commit '7e350b7ddd19af856b55634233d609e29baab646' into release/1.1
* commit '7e350b7ddd19af856b55634233d609e29baab646': pcx: Check the packet size before assuming it fits a palette rpza: Fix a buffer size check xxan: Disallow odd width xan: Only read within the data that actually was initialized xan: Use bytestream2 to limit reading to within the buffer pcx: Consume the whole packet if giving up due to missing palette pngdec: Stop trying to decode once inflate returns Z_STREAM_END mov: Make sure the read sample count is nonnegative bfi: Add some very basic sanity checks for input packet sizes bfi: Avoid divisions by zero electronicarts: Add more sanity checking for the number of channels riffdec: Add sanity checks for the sample rate Conflicts: libavcodec/pcx.c libavcodec/xan.c libavformat/mov.c libavformat/riff.c Merged-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libavcodec')
-rw-r--r--libavcodec/pcx.c10
-rw-r--r--libavcodec/pngdec.c4
-rw-r--r--libavcodec/rpza.c2
-rw-r--r--libavcodec/xan.c44
-rw-r--r--libavcodec/xxan.c4
5 files changed, 39 insertions, 25 deletions
diff --git a/libavcodec/pcx.c b/libavcodec/pcx.c
index 3aed3a3e2b..1900b8c4bc 100644
--- a/libavcodec/pcx.c
+++ b/libavcodec/pcx.c
@@ -184,7 +184,13 @@ static int pcx_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
} else if (nplanes == 1 && bits_per_pixel == 8) {
int palstart = avpkt->size - 769;
- for (y=0; y<h; y++, ptr+=stride) {
+ if (avpkt->size < 769) {
+ av_log(avctx, AV_LOG_ERROR, "File is too short\n");
+ ret = avpkt->size;
+ goto end;
+ }
+
+ for (y = 0; y < h; y++, ptr += stride) {
pcx_rle_decode(&gb, scanline, bytes_per_scanline, compressed);
memcpy(ptr, scanline, w);
}
@@ -195,7 +201,7 @@ static int pcx_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
}
if (bytestream2_get_byte(&gb) != 12) {
av_log(avctx, AV_LOG_ERROR, "expected palette after image data\n");
- ret = AVERROR_INVALIDDATA;
+ ret = avpkt->size;
goto end;
}
diff --git a/libavcodec/pngdec.c b/libavcodec/pngdec.c
index c0a1737054..4740932c41 100644
--- a/libavcodec/pngdec.c
+++ b/libavcodec/pngdec.c
@@ -380,6 +380,10 @@ static int png_decode_idat(PNGDecContext *s, int length)
s->zstream.avail_out = s->crow_size;
s->zstream.next_out = s->crow_buf;
}
+ if (ret == Z_STREAM_END && s->zstream.avail_in > 0) {
+ av_log(NULL, AV_LOG_WARNING, "%d undecompressed bytes left in buffer\n", s->zstream.avail_in);
+ return 0;
+ }
}
return 0;
}
diff --git a/libavcodec/rpza.c b/libavcodec/rpza.c
index 246d575ee4..53757f2b31 100644
--- a/libavcodec/rpza.c
+++ b/libavcodec/rpza.c
@@ -203,7 +203,7 @@ static void rpza_decode_stream(RpzaContext *s)
/* Fill block with 16 colors */
case 0x00:
- if (s->size - stream_ptr < 16)
+ if (s->size - stream_ptr < 30)
return;
ADVANCE_BLOCK();
block_ptr = row_ptr + pixel_ptr;
diff --git a/libavcodec/xan.c b/libavcodec/xan.c
index 899c1f1d22..9ab3270f6e 100644
--- a/libavcodec/xan.c
+++ b/libavcodec/xan.c
@@ -106,6 +106,7 @@ static int xan_huffman_decode(unsigned char *dest, int dest_len,
int ptr_len = src_len - 1 - byte*2;
unsigned char val = ival;
unsigned char *dest_end = dest + dest_len;
+ unsigned char *dest_start = dest;
GetBitContext gb;
if (ptr_len < 0)
@@ -121,13 +122,13 @@ static int xan_huffman_decode(unsigned char *dest, int dest_len,
if (val < 0x16) {
if (dest >= dest_end)
- return 0;
+ return dest_len;
*dest++ = val;
val = ival;
}
}
- return 0;
+ return dest - dest_start;
}
/**
@@ -276,7 +277,7 @@ static int xan_wc3_decode_frame(XanContext *s) {
unsigned char flag = 0;
int size = 0;
int motion_x, motion_y;
- int x, y;
+ int x, y, ret;
unsigned char *opcode_buffer = s->buffer1;
unsigned char *opcode_buffer_end = s->buffer1 + s->buffer1_size;
@@ -285,10 +286,9 @@ static int xan_wc3_decode_frame(XanContext *s) {
/* pointers to segments inside the compressed chunk */
const unsigned char *huffman_segment;
- const unsigned char *size_segment;
- const unsigned char *vector_segment;
+ GetByteContext size_segment;
+ GetByteContext vector_segment;
const unsigned char *imagedata_segment;
- const unsigned char *buf_end = s->buf + s->size;
int huffman_offset, size_offset, vector_offset, imagedata_offset,
imagedata_size;
@@ -307,13 +307,14 @@ static int xan_wc3_decode_frame(XanContext *s) {
return AVERROR_INVALIDDATA;
huffman_segment = s->buf + huffman_offset;
- size_segment = s->buf + size_offset;
- vector_segment = s->buf + vector_offset;
+ bytestream2_init(&size_segment, s->buf + size_offset, s->size - size_offset);
+ bytestream2_init(&vector_segment, s->buf + vector_offset, s->size - vector_offset);
imagedata_segment = s->buf + imagedata_offset;
- if (xan_huffman_decode(opcode_buffer, opcode_buffer_size,
- huffman_segment, s->size - huffman_offset) < 0)
+ if ((ret = xan_huffman_decode(opcode_buffer, opcode_buffer_size,
+ huffman_segment, s->size - huffman_offset)) < 0)
return AVERROR_INVALIDDATA;
+ opcode_buffer_end = opcode_buffer + ret;
if (imagedata_segment[0] == 2) {
xan_unpack(s->buffer2, s->buffer2_size,
@@ -360,31 +361,29 @@ static int xan_wc3_decode_frame(XanContext *s) {
case 9:
case 19:
- if (buf_end - size_segment < 1) {
+ if (bytestream2_get_bytes_left(&size_segment) < 1) {
av_log(s->avctx, AV_LOG_ERROR, "size_segment overread\n");
return AVERROR_INVALIDDATA;
}
- size = *size_segment++;
+ size = bytestream2_get_byte(&size_segment);
break;
case 10:
case 20:
- if (buf_end - size_segment < 2) {
+ if (bytestream2_get_bytes_left(&size_segment) < 2) {
av_log(s->avctx, AV_LOG_ERROR, "size_segment overread\n");
return AVERROR_INVALIDDATA;
}
- size = AV_RB16(&size_segment[0]);
- size_segment += 2;
+ size = bytestream2_get_be16(&size_segment);
break;
case 11:
case 21:
- if (buf_end - size_segment < 3) {
+ if (bytestream2_get_bytes_left(&size_segment) < 3) {
av_log(s->avctx, AV_LOG_ERROR, "size_segment overread\n");
return AVERROR_INVALIDDATA;
}
- size = AV_RB24(size_segment);
- size_segment += 3;
+ size = bytestream2_get_be24(&size_segment);
break;
}
@@ -405,14 +404,15 @@ static int xan_wc3_decode_frame(XanContext *s) {
imagedata_size -= size;
}
} else {
- if (vector_segment >= buf_end) {
+ uint8_t vector;
+ if (bytestream2_get_bytes_left(&vector_segment) <= 0) {
av_log(s->avctx, AV_LOG_ERROR, "vector_segment overread\n");
return AVERROR_INVALIDDATA;
}
/* run-based motion compensation from last frame */
- motion_x = sign_extend(*vector_segment >> 4, 4);
- motion_y = sign_extend(*vector_segment & 0xF, 4);
- vector_segment++;
+ vector = bytestream2_get_byte(&vector_segment);
+ motion_x = sign_extend(vector >> 4, 4);
+ motion_y = sign_extend(vector & 0xF, 4);
/* copy a run of pixels from the previous frame */
xan_wc3_copy_pixel_run(s, x, y, size, motion_x, motion_y);
diff --git a/libavcodec/xxan.c b/libavcodec/xxan.c
index 1deafe8bcc..c8ccb9716c 100644
--- a/libavcodec/xxan.c
+++ b/libavcodec/xxan.c
@@ -49,6 +49,10 @@ static av_cold int xan_decode_init(AVCodecContext *avctx)
av_log(avctx, AV_LOG_ERROR, "Invalid frame height: %d.\n", avctx->height);
return AVERROR(EINVAL);
}
+ if (avctx->width & 1) {
+ av_log(avctx, AV_LOG_ERROR, "Invalid frame width: %d.\n", avctx->width);
+ return AVERROR(EINVAL);
+ }
s->buffer_size = avctx->width * avctx->height;
s->y_buffer = av_malloc(s->buffer_size);