X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavformat%2Fapngdec.c;h=bf8343faf3a105a831c11d4b0331c63918177206;hb=e5af9203098a889f36b759652615046254d45102;hp=53cdd4538e010b9c2ef6560adcb6bbc15e60b889;hpb=ebdc5c419aef0d9eed8c1ec57b30238194c1db0a;p=ffmpeg diff --git a/libavformat/apngdec.c b/libavformat/apngdec.c index 53cdd4538e0..bf8343faf3a 100644 --- a/libavformat/apngdec.c +++ b/libavformat/apngdec.c @@ -66,7 +66,7 @@ typedef struct APNGDemuxContext { * ... * IDAT */ -static int apng_probe(AVProbeData *p) +static int apng_probe(const AVProbeData *p) { GetByteContext gb; int state = 0; @@ -127,17 +127,18 @@ static int append_extradata(AVCodecParameters *par, AVIOContext *pb, int len) int new_size, ret; uint8_t *new_extradata; - if (previous_size > INT_MAX - len) + if (len > INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE - previous_size) return AVERROR_INVALIDDATA; new_size = previous_size + len; new_extradata = av_realloc(par->extradata, new_size + AV_INPUT_BUFFER_PADDING_SIZE); if (!new_extradata) return AVERROR(ENOMEM); + memset(new_extradata + new_size, 0, AV_INPUT_BUFFER_PADDING_SIZE); par->extradata = new_extradata; par->extradata_size = new_size; - if ((ret = avio_read(pb, par->extradata + previous_size, len)) < 0) + if ((ret = ffio_read_size(pb, par->extradata + previous_size, len)) < 0) return ret; return previous_size; @@ -150,17 +151,17 @@ static int apng_read_header(AVFormatContext *s) uint32_t len, tag; AVStream *st; int acTL_found = 0; - int64_t ret = AVERROR_INVALIDDATA; + int64_t ret; /* verify PNGSIG */ if (avio_rb64(pb) != PNGSIG) - return ret; + return AVERROR_INVALIDDATA; /* parse IHDR (must be first chunk) */ len = avio_rb32(pb); tag = avio_rl32(pb); if (len != 13 || tag != MKTAG('I', 'H', 'D', 'R')) - return ret; + return AVERROR_INVALIDDATA; st = avformat_new_stream(s, NULL); if (!st) @@ -177,27 +178,24 @@ static int apng_read_header(AVFormatContext *s) return ret; /* extradata will contain every chunk up to the first fcTL (excluded) */ - st->codecpar->extradata = av_malloc(len + 12 + AV_INPUT_BUFFER_PADDING_SIZE); - if (!st->codecpar->extradata) - return AVERROR(ENOMEM); - st->codecpar->extradata_size = len + 12; + ret = ff_alloc_extradata(st->codecpar, len + 12); + if (ret < 0) + return ret; AV_WB32(st->codecpar->extradata, len); AV_WL32(st->codecpar->extradata+4, tag); AV_WB32(st->codecpar->extradata+8, st->codecpar->width); AV_WB32(st->codecpar->extradata+12, st->codecpar->height); - if ((ret = avio_read(pb, st->codecpar->extradata+16, 9)) < 0) - goto fail; + if ((ret = ffio_read_size(pb, st->codecpar->extradata + 16, 9)) < 0) + return ret; - while (!avio_feof(pb)) { + while (1) { if (acTL_found && ctx->num_play != 1) { int64_t size = avio_size(pb); int64_t offset = avio_tell(pb); if (size < 0) { - ret = size; - goto fail; + return size; } else if (offset < 0) { - ret = offset; - goto fail; + return offset; } else if ((ret = ffio_ensure_seekback(pb, size - offset)) < 0) { av_log(s, AV_LOG_WARNING, "Could not ensure seekback, will not loop\n"); ctx->num_play = 1; @@ -205,20 +203,18 @@ static int apng_read_header(AVFormatContext *s) } if ((ctx->num_play == 1 || !acTL_found) && ((ret = ffio_ensure_seekback(pb, 4 /* len */ + 4 /* tag */)) < 0)) - goto fail; + return ret; len = avio_rb32(pb); - if (len > 0x7fffffff) { - ret = AVERROR_INVALIDDATA; - goto fail; - } + if (len > INT_MAX - 12) + return AVERROR_INVALIDDATA; tag = avio_rl32(pb); switch (tag) { case MKTAG('a', 'c', 'T', 'L'): if ((ret = avio_seek(pb, -8, SEEK_CUR)) < 0 || (ret = append_extradata(st->codecpar, pb, len + 12)) < 0) - goto fail; + return ret; acTL_found = 1; ctx->num_frames = AV_RB32(st->codecpar->extradata + ret + 8); ctx->num_play = AV_RB32(st->codecpar->extradata + ret + 12); @@ -226,26 +222,18 @@ static int apng_read_header(AVFormatContext *s) ctx->num_frames, ctx->num_play); break; case MKTAG('f', 'c', 'T', 'L'): - if (!acTL_found) { - ret = AVERROR_INVALIDDATA; - goto fail; + if (!acTL_found || len != 26) { + return AVERROR_INVALIDDATA; } if ((ret = avio_seek(pb, -8, SEEK_CUR)) < 0) - goto fail; + return ret; return 0; default: if ((ret = avio_seek(pb, -8, SEEK_CUR)) < 0 || (ret = append_extradata(st->codecpar, pb, len + 12)) < 0) - goto fail; + return ret; } } - -fail: - if (st->codecpar->extradata_size) { - av_freep(&st->codecpar->extradata); - st->codecpar->extradata_size = 0; - } - return ret; } static int decode_fctl_chunk(AVFormatContext *s, APNGDemuxContext *ctx, AVPacket *pkt)