diff --git a/libavcodec/eacmv.c b/libavcodec/eacmv.c index 8a8d6a9cef..82ec9fc9fc 100644 --- a/libavcodec/eacmv.c +++ b/libavcodec/eacmv.c @@ -162,8 +162,11 @@ static int cmv_decode_frame(AVCodecContext *avctx, return AVERROR_INVALIDDATA; if (AV_RL32(buf)==MVIh_TAG||AV_RB32(buf)==MVIh_TAG) { + unsigned size = AV_RL32(buf + 4); cmv_process_header(s, buf+EA_PREAMBLE_SIZE, buf_end); - return buf_size; + if (size > buf_end - buf - EA_PREAMBLE_SIZE) + return -1; + buf += size; } if (av_image_check_size(s->width, s->height, 0, s->avctx)) diff --git a/libavformat/electronicarts.c b/libavformat/electronicarts.c index c901931dec..55cab7c70f 100644 --- a/libavformat/electronicarts.c +++ b/libavformat/electronicarts.c @@ -469,11 +469,12 @@ static int ea_read_packet(AVFormatContext *s, AVIOContext *pb = s->pb; int ret = 0; int packet_read = 0; + int partial_packet = 0; unsigned int chunk_type, chunk_size; int key = 0; int av_uninit(num_samples); - while (!packet_read) { + while (!packet_read || partial_packet) { chunk_type = avio_rl32(pb); chunk_size = (ea->big_endian ? avio_rb32(pb) : avio_rl32(pb)) - 8; @@ -496,6 +497,11 @@ static int ea_read_packet(AVFormatContext *s, avio_skip(pb, 8); chunk_size -= 12; } + if (partial_packet) { + av_log_ask_for_sample(s, "video header followed by audio packet not supported.\n"); + av_free_packet(pkt); + partial_packet = 0; + } ret = av_get_packet(pb, pkt, chunk_size); if (ret < 0) return ret; @@ -558,9 +564,15 @@ static int ea_read_packet(AVFormatContext *s, key = AV_PKT_FLAG_KEY; case MV0F_TAG: get_video_packet: - ret = av_get_packet(pb, pkt, chunk_size); - if (ret < 0) - return ret; + if (partial_packet) { + ret = av_append_packet(pb, pkt, chunk_size); + } else + ret = av_get_packet(pb, pkt, chunk_size); + if (ret < 0) { + packet_read = 1; + break; + } + partial_packet = chunk_type == MVIh_TAG; pkt->stream_index = ea->video_stream_index; pkt->flags |= key; packet_read = 1; @@ -572,6 +584,8 @@ get_video_packet: } } + if (ret < 0 && partial_packet) + av_free_packet(pkt); return ret; }