diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2013-10-08 01:41:20 +0200 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2013-10-08 01:41:20 +0200 |
commit | 8d14e1d64ee1780f839e05c22fc633b3cf1b8579 (patch) | |
tree | 9a2259418c83ee5f4397f0fc921b52e45f817269 | |
parent | 5da68aff96ff77b0f82d80f250e23c2f3696938b (diff) | |
parent | 7e350b7ddd19af856b55634233d609e29baab646 (diff) | |
download | ffmpeg-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>
-rw-r--r-- | libavcodec/pcx.c | 10 | ||||
-rw-r--r-- | libavcodec/pngdec.c | 4 | ||||
-rw-r--r-- | libavcodec/rpza.c | 2 | ||||
-rw-r--r-- | libavcodec/xan.c | 44 | ||||
-rw-r--r-- | libavcodec/xxan.c | 4 | ||||
-rw-r--r-- | libavformat/bfi.c | 11 | ||||
-rw-r--r-- | libavformat/electronicarts.c | 5 | ||||
-rw-r--r-- | libavformat/mov.c | 4 | ||||
-rw-r--r-- | libavformat/riff.c | 5 |
9 files changed, 59 insertions, 30 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); diff --git a/libavformat/bfi.c b/libavformat/bfi.c index a28e09a4f1..212a6119da 100644 --- a/libavformat/bfi.c +++ b/libavformat/bfi.c @@ -134,6 +134,10 @@ static int bfi_read_packet(AVFormatContext * s, AVPacket * pkt) video_offset = avio_rl32(pb); audio_size = video_offset - audio_offset; bfi->video_size = chunk_size - video_offset; + if (audio_size < 0 || bfi->video_size < 0) { + av_log(s, AV_LOG_ERROR, "Invalid audio/video offsets or chunk size\n"); + return AVERROR_INVALIDDATA; + } //Tossing an audio packet at the audio decoder. ret = av_get_packet(pb, pkt, audio_size); @@ -142,9 +146,7 @@ static int bfi_read_packet(AVFormatContext * s, AVPacket * pkt) pkt->pts = bfi->audio_frame; bfi->audio_frame += ret; - } - - else { + } else if (bfi->video_size > 0) { //Tossing a video packet at the video decoder. ret = av_get_packet(pb, pkt, bfi->video_size); @@ -156,6 +158,9 @@ static int bfi_read_packet(AVFormatContext * s, AVPacket * pkt) /* One less frame to read. A cursory decrement. */ bfi->nframes--; + } else { + /* Empty video packet */ + ret = AVERROR(EAGAIN); } bfi->avflag = !bfi->avflag; diff --git a/libavformat/electronicarts.c b/libavformat/electronicarts.c index bc7ea140d5..4484355e94 100644 --- a/libavformat/electronicarts.c +++ b/libavformat/electronicarts.c @@ -453,8 +453,9 @@ static int ea_read_header(AVFormatContext *s) } if (ea->audio_codec) { - if (ea->num_channels <= 0) { - av_log(s, AV_LOG_WARNING, "Unsupported number of channels: %d\n", ea->num_channels); + if (ea->num_channels <= 0 || ea->num_channels > 2) { + av_log(s, AV_LOG_WARNING, + "Unsupported number of channels: %d\n", ea->num_channels); ea->audio_codec = 0; return 1; } diff --git a/libavformat/mov.c b/libavformat/mov.c index 32add6db03..db4ff274ce 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -1821,6 +1821,10 @@ static int mov_read_stts(MOVContext *c, AVIOContext *pb, MOVAtom atom) av_log(c->fc, AV_LOG_ERROR, "Invalid SampleDelta in STTS %d\n", sample_duration); sample_duration = 1; } + if (sample_count < 0) { + av_log(c->fc, AV_LOG_ERROR, "Invalid sample_count=%d\n", sample_count); + return AVERROR_INVALIDDATA; + } sc->stts_data[i].count= sample_count; sc->stts_data[i].duration= sample_duration; diff --git a/libavformat/riff.c b/libavformat/riff.c index b417e2e594..02bf1e5962 100644 --- a/libavformat/riff.c +++ b/libavformat/riff.c @@ -736,6 +736,11 @@ int ff_get_wav_header(AVIOContext *pb, AVCodecContext *codec, int size) if (size > 0) avio_skip(pb, size); } + if (codec->sample_rate <= 0) { + av_log(NULL, AV_LOG_ERROR, + "Invalid sample rate: %d\n", codec->sample_rate); + return AVERROR_INVALIDDATA; + } if (codec->codec_id == AV_CODEC_ID_AAC_LATM) { /* channels and sample_rate values are those prior to applying SBR and/or PS */ codec->channels = 0; |