X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavformat%2Faiffdec.c;h=cade05a9d6ff99676c9c16878bb3a2c093a4cd8a;hb=bc70684e74a185d7b80c8b80bdedda659cb581b8;hp=7c701e0c700769d5e47b990f463393f9aca153e1;hpb=fb4a12cda4033f2f3d3d1039739f6e0e6f9afb82;p=ffmpeg diff --git a/libavformat/aiffdec.c b/libavformat/aiffdec.c index 7c701e0c700..cade05a9d6f 100644 --- a/libavformat/aiffdec.c +++ b/libavformat/aiffdec.c @@ -20,15 +20,14 @@ */ #include "libavutil/intreadwrite.h" -#include "libavutil/mathematics.h" #include "libavutil/dict.h" #include "avformat.h" #include "internal.h" #include "pcm.h" #include "aiff.h" -#include "isom.h" #include "id3v2.h" #include "mov_chan.h" +#include "replaygain.h" #define AIFF 0 #define AIFF_C_VERSION1 0xA2805140 @@ -119,6 +118,8 @@ static int get_aiff_header(AVFormatContext *s, int size, else sample_rate = (val + (1ULL<<(-exp-1))) >> -exp; par->sample_rate = sample_rate; + if (size < 18) + return AVERROR_INVALIDDATA; size -= 18; /* get codec id for AIFF-C */ @@ -189,7 +190,7 @@ static int get_aiff_header(AVFormatContext *s, int size, return num_frames; } -static int aiff_probe(AVProbeData *p) +static int aiff_probe(const AVProbeData *p) { /* check file header */ if (p->buf[0] == 'F' && p->buf[1] == 'O' && @@ -211,7 +212,7 @@ static int aiff_read_header(AVFormatContext *s) AVIOContext *pb = s->pb; AVStream * st; AIFFInputContext *aiff = s->priv_data; - ID3v2ExtraMeta *id3v2_extra_meta = NULL; + ID3v2ExtraMeta *id3v2_extra_meta; /* check FORM header */ filesize = get_tag(pb, &tag); @@ -242,7 +243,10 @@ static int aiff_read_header(AVFormatContext *s) if (size < 0) return size; - filesize -= size + 8; + if (size >= 0x7fffffff - 8) + filesize = 0; + else + filesize -= size + 8; switch (tag) { case MKTAG('C', 'O', 'M', 'M'): /* Common chunk */ @@ -257,8 +261,8 @@ static int aiff_read_header(AVFormatContext *s) position = avio_tell(pb); ff_id3v2_read(s, ID3v2_DEFAULT_MAGIC, &id3v2_extra_meta, size); if (id3v2_extra_meta) - if ((ret = ff_id3v2_parse_apic(s, &id3v2_extra_meta)) < 0 || - (ret = ff_id3v2_parse_chapters(s, &id3v2_extra_meta)) < 0) { + if ((ret = ff_id3v2_parse_apic(s, id3v2_extra_meta)) < 0 || + (ret = ff_id3v2_parse_chapters(s, id3v2_extra_meta)) < 0) { ff_id3v2_free_extra_meta(&id3v2_extra_meta); return ret; } @@ -282,6 +286,8 @@ static int aiff_read_header(AVFormatContext *s) get_meta(s, "comment" , size); break; case MKTAG('S', 'S', 'N', 'D'): /* Sampled sound chunk */ + if (size < 8) + return AVERROR_INVALIDDATA; aiff->data_end = avio_tell(pb) + size; offset = avio_rb32(pb); /* Offset of sound data */ avio_rb32(pb); /* BlockSize... don't care */ @@ -297,8 +303,8 @@ static int aiff_read_header(AVFormatContext *s) case MKTAG('w', 'a', 'v', 'e'): if ((uint64_t)size > (1<<30)) return -1; - if (ff_get_extradata(s, st->codecpar, pb, size) < 0) - return AVERROR(ENOMEM); + if ((ret = ff_get_extradata(s, st->codecpar, pb, size)) < 0) + return ret; if ( (st->codecpar->codec_id == AV_CODEC_ID_QDMC || st->codecpar->codec_id == AV_CODEC_ID_QDM2) && size>=12*4 && !st->codecpar->block_align) { st->codecpar->block_align = AV_RB32(st->codecpar->extradata+11*4); @@ -321,8 +327,8 @@ static int aiff_read_header(AVFormatContext *s) } break; case MKTAG('C','H','A','N'): - if(ff_mov_read_chan(s, pb, st, size) < 0) - return AVERROR_INVALIDDATA; + if ((ret = ff_mov_read_chan(s, pb, st, size)) < 0) + return ret; break; case MKTAG('A','P','C','M'): /* XA ADPCM compressed sound chunk */ st->codecpar->codec_id = AV_CODEC_ID_ADPCM_XA; @@ -348,6 +354,10 @@ static int aiff_read_header(AVFormatContext *s) } } + ret = ff_replaygain_export(st, s->metadata); + if (ret < 0) + return ret; + got_sound: if (!st->codecpar->block_align && st->codecpar->codec_id == AV_CODEC_ID_QCELP) { av_log(s, AV_LOG_WARNING, "qcelp without wave chunk, assuming full rate\n"); @@ -398,6 +408,8 @@ static int aiff_read_packet(AVFormatContext *s, break; default: size = st->codecpar->block_align ? (MAX_SIZE / st->codecpar->block_align) * st->codecpar->block_align : MAX_SIZE; + if (!size) + return AVERROR_INVALIDDATA; } size = FFMIN(max_size, size); res = av_get_packet(s->pb, pkt, size); @@ -412,7 +424,7 @@ static int aiff_read_packet(AVFormatContext *s, return 0; } -AVInputFormat ff_aiff_demuxer = { +const AVInputFormat ff_aiff_demuxer = { .name = "aiff", .long_name = NULL_IF_CONFIG_SMALL("Audio IFF"), .priv_data_size = sizeof(AIFFInputContext), @@ -420,5 +432,5 @@ AVInputFormat ff_aiff_demuxer = { .read_header = aiff_read_header, .read_packet = aiff_read_packet, .read_seek = ff_pcm_read_seek, - .codec_tag = (const AVCodecTag* const []){ ff_codec_aiff_tags, 0 }, + .codec_tag = ff_aiff_codec_tags_list, };