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>
This commit is contained in:
Michael Niedermayer
2013-10-08 01:41:20 +02:00
9 changed files with 59 additions and 30 deletions

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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;

View File

@@ -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);

View File

@@ -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);

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -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;

View File

@@ -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;