X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavformat%2Felectronicarts.c;h=7c1fabee0f3dd64012b2bd76c5985407bd4c55ea;hb=8a70ef94b9c377293b3dfa7d92cdc81a4fe1543a;hp=e764bd96ebbf0c7e9bf3bcbc5823e3cb54431a22;hpb=163a729725c6eb0081b0af41a7279f7d19aee86e;p=ffmpeg diff --git a/libavformat/electronicarts.c b/libavformat/electronicarts.c index e764bd96ebb..7c1fabee0f3 100644 --- a/libavformat/electronicarts.c +++ b/libavformat/electronicarts.c @@ -25,6 +25,8 @@ * by Robin Kay (komadori at gekkou.co.uk) */ +#include + #include "libavutil/intreadwrite.h" #include "avformat.h" #include "internal.h" @@ -151,7 +153,7 @@ static int process_audio_header_elements(AVFormatContext *s) break; case 0x8A: av_log(s, AV_LOG_DEBUG, - "element 0x%02x set to 0x%08x\n", + "element 0x%02x set to 0x%08"PRIx32"\n", subbyte, read_arbitrary(pb)); av_log(s, AV_LOG_DEBUG, "exited audio subheader\n"); in_subheader = 0; @@ -170,7 +172,7 @@ static int process_audio_header_elements(AVFormatContext *s) break; default: av_log(s, AV_LOG_DEBUG, - "element 0x%02x set to 0x%08x\n", + "element 0x%02x set to 0x%08"PRIx32"\n", subbyte, read_arbitrary(pb)); break; } @@ -182,7 +184,7 @@ static int process_audio_header_elements(AVFormatContext *s) break; default: av_log(s, AV_LOG_DEBUG, - "header element 0x%02x set to 0x%08x\n", + "header element 0x%02x set to 0x%08"PRIx32"\n", byte, read_arbitrary(pb)); break; } @@ -392,14 +394,18 @@ static int process_ea_header(AVFormatContext *s) case pQGT_TAG: case TGQs_TAG: ea->video_codec = AV_CODEC_ID_TGQ; + ea->time_base = (AVRational) { 1, 15 }; break; case pIQT_TAG: ea->video_codec = AV_CODEC_ID_TQI; + ea->time_base = (AVRational) { 1, 15 }; break; case MADk_TAG: ea->video_codec = AV_CODEC_ID_MAD; + avio_skip(pb, 6); + ea->time_base = (AVRational) { avio_rl16(pb), 1000 }; break; case MVhd_TAG: @@ -467,7 +473,7 @@ static int ea_read_header(AVFormatContext *s) } if (ea->audio_codec) { - if (ea->num_channels <= 0) { + 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; @@ -520,7 +526,7 @@ static int ea_read_packet(AVFormatContext *s, AVPacket *pkt) while (!packet_read) { chunk_type = avio_rl32(pb); chunk_size = ea->big_endian ? avio_rb32(pb) : avio_rl32(pb); - if (chunk_size <= 8) + if (chunk_size < 8) return AVERROR_INVALIDDATA; chunk_size -= 8; @@ -545,6 +551,9 @@ static int ea_read_packet(AVFormatContext *s, AVPacket *pkt) avio_skip(pb, 8); chunk_size -= 12; } + if (!chunk_size) + continue; + ret = av_get_packet(pb, pkt, chunk_size); if (ret < 0) return ret; @@ -555,10 +564,16 @@ static int ea_read_packet(AVFormatContext *s, AVPacket *pkt) case AV_CODEC_ID_ADPCM_EA_R1: case AV_CODEC_ID_ADPCM_EA_R2: case AV_CODEC_ID_ADPCM_IMA_EA_EACS: - pkt->duration = AV_RL32(pkt->data); - break; case AV_CODEC_ID_ADPCM_EA_R3: - pkt->duration = AV_RB32(pkt->data); + if (pkt->size < 4) { + av_log(s, AV_LOG_ERROR, "Packet is too short\n"); + av_free_packet(pkt); + return AVERROR_INVALIDDATA; + } + if (ea->audio_codec == AV_CODEC_ID_ADPCM_EA_R3) + pkt->duration = AV_RB32(pkt->data); + else + pkt->duration = AV_RL32(pkt->data); break; case AV_CODEC_ID_ADPCM_IMA_EA_SEAD: pkt->duration = ret * 2 / ea->num_channels; @@ -599,6 +614,9 @@ static int ea_read_packet(AVFormatContext *s, AVPacket *pkt) goto get_video_packet; case mTCD_TAG: + if (chunk_size < 8) + return AVERROR_INVALIDDATA; + avio_skip(pb, 8); // skip ea DCT header chunk_size -= 8; goto get_video_packet; @@ -609,6 +627,9 @@ static int ea_read_packet(AVFormatContext *s, AVPacket *pkt) key = AV_PKT_FLAG_KEY; case MV0F_TAG: get_video_packet: + if (!chunk_size) + continue; + ret = av_get_packet(pb, pkt, chunk_size); if (ret < 0) return ret;