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:
@@ -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;
|
||||
}
|
||||
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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;
|
||||
|
@@ -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);
|
||||
|
@@ -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);
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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;
|
||||
|
||||
|
@@ -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;
|
||||
|
Reference in New Issue
Block a user