X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavformat%2Felectronicarts.c;h=8080ee7e41984e5222386c245e612d44b96dbd05;hb=bc70684e74a185d7b80c8b80bdedda659cb581b8;hp=6dbc3e350a4a19863602f8c737ed8ec63a763c43;hpb=4d8875ec23cf299277a0f028ea2ac99eb6f603c9;p=ffmpeg diff --git a/libavformat/electronicarts.c b/libavformat/electronicarts.c index 6dbc3e350a4..8080ee7e419 100644 --- a/libavformat/electronicarts.c +++ b/libavformat/electronicarts.c @@ -530,20 +530,17 @@ static int ea_read_header(AVFormatContext *s) 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; + goto no_audio; } if (ea->sample_rate <= 0) { av_log(s, AV_LOG_ERROR, "Unsupported sample rate: %d\n", ea->sample_rate); - ea->audio_codec = 0; - return 1; + goto no_audio; } if (ea->bytes <= 0 || ea->bytes > 2) { av_log(s, AV_LOG_ERROR, "Invalid number of bytes per sample: %d\n", ea->bytes); - ea->audio_codec = AV_CODEC_ID_NONE; - return 1; + goto no_audio; } /* initialize the audio decoder stream */ @@ -564,9 +561,14 @@ static int ea_read_header(AVFormatContext *s) st->codecpar->bits_per_coded_sample; ea->audio_stream_index = st->index; st->start_time = 0; + return 0; } +no_audio: + ea->audio_codec = AV_CODEC_ID_NONE; - return 1; + if (!ea->video.codec) + return AVERROR_INVALIDDATA; + return 0; } static int ea_read_packet(AVFormatContext *s, AVPacket *pkt) @@ -574,11 +576,14 @@ static int ea_read_packet(AVFormatContext *s, AVPacket *pkt) EaDemuxContext *ea = s->priv_data; AVIOContext *pb = s->pb; int partial_packet = 0; + int hit_end = 0; unsigned int chunk_type, chunk_size; int ret = 0, packet_read = 0, key = 0; int av_uninit(num_samples); - while (!packet_read || partial_packet) { + while ((!packet_read && !hit_end) || partial_packet) { + if (avio_feof(pb)) + return AVERROR_EOF; chunk_type = avio_rl32(pb); chunk_size = ea->big_endian ? avio_rb32(pb) : avio_rl32(pb); if (chunk_size < 8) @@ -602,10 +607,14 @@ static int ea_read_packet(AVFormatContext *s, AVPacket *pkt) break; } else if (ea->audio_codec == AV_CODEC_ID_PCM_S16LE_PLANAR || ea->audio_codec == AV_CODEC_ID_MP3) { + if (chunk_size < 12) + return AVERROR_INVALIDDATA; num_samples = avio_rl32(pb); avio_skip(pb, 8); chunk_size -= 12; } else if (ea->audio_codec == AV_CODEC_ID_ADPCM_PSX) { + if (chunk_size < 8) + return AVERROR_INVALIDDATA; avio_skip(pb, 8); chunk_size -= 8; } @@ -632,7 +641,6 @@ static int ea_read_packet(AVFormatContext *s, AVPacket *pkt) case AV_CODEC_ID_ADPCM_EA_R3: if (pkt->size < 4) { av_log(s, AV_LOG_ERROR, "Packet is too short\n"); - av_packet_unref(pkt); return AVERROR_INVALIDDATA; } if (ea->audio_codec == AV_CODEC_ID_ADPCM_EA_R3) @@ -676,7 +684,7 @@ static int ea_read_packet(AVFormatContext *s, AVPacket *pkt) } if (avio_feof(pb)) ret = AVERROR_EOF; - packet_read = 1; + hit_end = 1; break; case MVIh_TAG: @@ -689,6 +697,8 @@ static int ea_read_packet(AVFormatContext *s, AVPacket *pkt) case fVGT_TAG: case MADm_TAG: case MADe_TAG: + if (chunk_size > INT_MAX - 8) + return AVERROR_INVALIDDATA; avio_seek(pb, -8, SEEK_CUR); // include chunk preamble chunk_size += 8; goto get_video_packet; @@ -718,6 +728,7 @@ get_video_packet: ret = av_get_packet(pb, pkt, chunk_size); if (ret < 0) { packet_read = 1; + partial_packet = 0; break; } partial_packet = chunk_type == MVIh_TAG; @@ -735,12 +746,13 @@ get_video_packet: } } - if (ret < 0 && partial_packet) - av_packet_unref(pkt); + if (ret >= 0 && hit_end && !packet_read) + return AVERROR(EAGAIN); + return ret; } -AVInputFormat ff_ea_demuxer = { +const AVInputFormat ff_ea_demuxer = { .name = "ea", .long_name = NULL_IF_CONFIG_SMALL("Electronic Arts Multimedia"), .priv_data_size = sizeof(EaDemuxContext),