* ...
* IDAT
*/
-static int apng_probe(AVProbeData *p)
+static int apng_probe(const AVProbeData *p)
{
GetByteContext gb;
int state = 0;
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;
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)
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;
}
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);
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)
len = avio_rb32(pb);
tag = avio_rl32(pb);
+
+ if (avio_feof(pb))
+ return AVERROR_EOF;
+
switch (tag) {
case MKTAG('f', 'c', 'T', 'L'):
if (len != 26)