From 1bc035bc03542c0b2215effc0e53c5c9d2e786ac Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Sat, 4 Feb 2012 16:29:37 -0500 Subject: ape: return error if seeking to the current packet fails in ape_read_packet() --- libavformat/ape.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'libavformat/ape.c') diff --git a/libavformat/ape.c b/libavformat/ape.c index 345648eb33..a6e9bf1d79 100644 --- a/libavformat/ape.c +++ b/libavformat/ape.c @@ -361,7 +361,8 @@ static int ape_read_packet(AVFormatContext * s, AVPacket * pkt) if (ape->currentframe > ape->totalframes) return AVERROR(EIO); - avio_seek (s->pb, ape->frames[ape->currentframe].pos, SEEK_SET); + if (avio_seek(s->pb, ape->frames[ape->currentframe].pos, SEEK_SET) < 0) + return AVERROR(EIO); /* Calculate how many blocks there are in this frame */ if (ape->currentframe == (ape->totalframes - 1)) -- cgit v1.2.3 From 66f7be3603b527153daaae0999c743eb1438c7e5 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Sat, 4 Feb 2012 16:31:37 -0500 Subject: ape: return AVERROR_EOF instead of AVERROR(EIO) when demuxing is finished --- libavformat/ape.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'libavformat/ape.c') diff --git a/libavformat/ape.c b/libavformat/ape.c index a6e9bf1d79..853fdcac7e 100644 --- a/libavformat/ape.c +++ b/libavformat/ape.c @@ -357,9 +357,9 @@ static int ape_read_packet(AVFormatContext * s, AVPacket * pkt) uint32_t extra_size = 8; if (s->pb->eof_reached) - return AVERROR(EIO); + return AVERROR_EOF; if (ape->currentframe > ape->totalframes) - return AVERROR(EIO); + return AVERROR_EOF; if (avio_seek(s->pb, ape->frames[ape->currentframe].pos, SEEK_SET) < 0) return AVERROR(EIO); -- cgit v1.2.3 From c2c316158fb670f61abfa108cb940ba31264b0f8 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Sat, 4 Feb 2012 16:34:20 -0500 Subject: ape: stop reading after the last frame has been read This avoids buffer overread when the last packet size estimate is too small. --- libavformat/ape.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'libavformat/ape.c') diff --git a/libavformat/ape.c b/libavformat/ape.c index 853fdcac7e..c650a54ad4 100644 --- a/libavformat/ape.c +++ b/libavformat/ape.c @@ -358,7 +358,7 @@ static int ape_read_packet(AVFormatContext * s, AVPacket * pkt) if (s->pb->eof_reached) return AVERROR_EOF; - if (ape->currentframe > ape->totalframes) + if (ape->currentframe >= ape->totalframes) return AVERROR_EOF; if (avio_seek(s->pb, ape->frames[ape->currentframe].pos, SEEK_SET) < 0) -- cgit v1.2.3 From ac3f8d317c5d1e78340b57ebd2b5c1317e175bc2 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Sat, 4 Feb 2012 17:01:03 -0500 Subject: ape: calculate final packet size instead of guessing Calculates based on total file size and wavetaillength from the header. Falls back to multiplying finalframeblocks by 8 instead of 4 so that it will at least be overestimating for 24-bit. Currently it can underestimate the final packet size, leading to decoding errors. --- libavformat/ape.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) (limited to 'libavformat/ape.c') diff --git a/libavformat/ape.c b/libavformat/ape.c index c650a54ad4..8145db3a76 100644 --- a/libavformat/ape.c +++ b/libavformat/ape.c @@ -159,8 +159,8 @@ static int ape_read_header(AVFormatContext * s) AVStream *st; uint32_t tag; int i; - int total_blocks; - int64_t pts; + int total_blocks, final_size = 0; + int64_t pts, file_size; /* Skip any leading junk such as id3v2 tags */ ape->junklength = avio_tell(pb); @@ -289,8 +289,17 @@ static int ape_read_header(AVFormatContext * s) ape->frames[i - 1].size = ape->frames[i].pos - ape->frames[i - 1].pos; ape->frames[i].skip = (ape->frames[i].pos - ape->frames[0].pos) & 3; } - ape->frames[ape->totalframes - 1].size = ape->finalframeblocks * 4; ape->frames[ape->totalframes - 1].nblocks = ape->finalframeblocks; + /* calculate final packet size from total file size, if available */ + file_size = avio_size(pb); + if (file_size > 0) { + final_size = file_size - ape->frames[ape->totalframes - 1].pos - + ape->wavtaillength; + final_size -= final_size & 3; + } + if (file_size <= 0 || final_size <= 0) + final_size = ape->finalframeblocks * 8; + ape->frames[ape->totalframes - 1].size = final_size; for (i = 0; i < ape->totalframes; i++) { if(ape->frames[i].skip){ -- cgit v1.2.3 From f1c3d4a68a743c1b274dc764e54e2df276a7c774 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Sat, 4 Feb 2012 17:08:34 -0500 Subject: ape: skip packets with invalid size --- libavformat/ape.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'libavformat/ape.c') diff --git a/libavformat/ape.c b/libavformat/ape.c index 8145db3a76..4d13e4836c 100644 --- a/libavformat/ape.c +++ b/libavformat/ape.c @@ -379,6 +379,14 @@ static int ape_read_packet(AVFormatContext * s, AVPacket * pkt) else nblocks = ape->blocksperframe; + if (ape->frames[ape->currentframe].size <= 0 || + ape->frames[ape->currentframe].size > INT_MAX - extra_size) { + av_log(s, AV_LOG_ERROR, "invalid packet size: %d\n", + ape->frames[ape->currentframe].size); + ape->currentframe++; + return AVERROR(EIO); + } + if (av_new_packet(pkt, ape->frames[ape->currentframe].size + extra_size) < 0) return AVERROR(ENOMEM); -- cgit v1.2.3