aboutsummaryrefslogtreecommitdiffstats
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
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>
-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
-rw-r--r--libavformat/bfi.c11
-rw-r--r--libavformat/electronicarts.c5
-rw-r--r--libavformat/mov.c4
-rw-r--r--libavformat/riff.c5
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;