Message ID | 20180127230114.82506-2-ottoka@posteo.de |
---|---|
State | Superseded |
Headers | show |
On Sun, Jan 28, 2018 at 12:01:13AM +0100, Karsten Otto wrote: > Remember the end position of audio content in the file and check it during > read_packet. There always seems to be other data beyond it, which could be > misinterpreted as more audio. Also add some extra avio_read error checks, > to bail early in case of a broken/truncated file. > --- > libavformat/aadec.c | 11 +++++++++-- > 1 file changed, 9 insertions(+), 2 deletions(-) > > diff --git a/libavformat/aadec.c b/libavformat/aadec.c > index 8d39b1d9ba..d6b6c125da 100644 > --- a/libavformat/aadec.c > +++ b/libavformat/aadec.c > @@ -46,6 +46,7 @@ typedef struct AADemuxContext { > struct AVTEA *tea_ctx; > uint8_t file_key[16]; > int64_t current_chapter_size; > + int64_t content_end; > } AADemuxContext; > > static int get_second_size(char *codec_name) > @@ -197,6 +198,7 @@ static int aa_read_header(AVFormatContext *s) > } > start = TOC[largest_idx].offset; > avio_seek(pb, start, SEEK_SET); > + c->content_end = start + largest_size; > c->current_chapter_size = 0; > > return 0; > @@ -214,6 +216,11 @@ static int aa_read_packet(AVFormatContext *s, AVPacket *pkt) > int ret; > AADemuxContext *c = s->priv_data; > > + // are we at the end of the audio content? > + if (avio_tell(s->pb) >= c->content_end) { > + return AVERROR_EOF; > + } > + > // are we at the start of a chapter? > if (c->current_chapter_size == 0) { > c->current_chapter_size = avio_rb32(s->pb); > @@ -234,7 +241,7 @@ static int aa_read_packet(AVFormatContext *s, AVPacket *pkt) > // decrypt c->current_codec_second_size bytes > blocks = c->current_codec_second_size / TEA_BLOCK_SIZE; > for (i = 0; i < blocks; i++) { > - avio_read(s->pb, src, TEA_BLOCK_SIZE); > + if (avio_read(s->pb, src, TEA_BLOCK_SIZE) < 0) return AVERROR_EOF; I suspect this should forward the error code or the test should be for != TEA_BLOCK_SIZE [...]
diff --git a/libavformat/aadec.c b/libavformat/aadec.c index 8d39b1d9ba..d6b6c125da 100644 --- a/libavformat/aadec.c +++ b/libavformat/aadec.c @@ -46,6 +46,7 @@ typedef struct AADemuxContext { struct AVTEA *tea_ctx; uint8_t file_key[16]; int64_t current_chapter_size; + int64_t content_end; } AADemuxContext; static int get_second_size(char *codec_name) @@ -197,6 +198,7 @@ static int aa_read_header(AVFormatContext *s) } start = TOC[largest_idx].offset; avio_seek(pb, start, SEEK_SET); + c->content_end = start + largest_size; c->current_chapter_size = 0; return 0; @@ -214,6 +216,11 @@ static int aa_read_packet(AVFormatContext *s, AVPacket *pkt) int ret; AADemuxContext *c = s->priv_data; + // are we at the end of the audio content? + if (avio_tell(s->pb) >= c->content_end) { + return AVERROR_EOF; + } + // are we at the start of a chapter? if (c->current_chapter_size == 0) { c->current_chapter_size = avio_rb32(s->pb); @@ -234,7 +241,7 @@ static int aa_read_packet(AVFormatContext *s, AVPacket *pkt) // decrypt c->current_codec_second_size bytes blocks = c->current_codec_second_size / TEA_BLOCK_SIZE; for (i = 0; i < blocks; i++) { - avio_read(s->pb, src, TEA_BLOCK_SIZE); + if (avio_read(s->pb, src, TEA_BLOCK_SIZE) < 0) return AVERROR_EOF; av_tea_init(c->tea_ctx, c->file_key, 16); av_tea_crypt(c->tea_ctx, dst, src, 1, NULL, 1); memcpy(buf + written, dst, TEA_BLOCK_SIZE); @@ -242,7 +249,7 @@ static int aa_read_packet(AVFormatContext *s, AVPacket *pkt) } trailing_bytes = c->current_codec_second_size % TEA_BLOCK_SIZE; if (trailing_bytes != 0) { // trailing bytes are left unencrypted! - avio_read(s->pb, src, trailing_bytes); + if (avio_read(s->pb, src, trailing_bytes) < 0) return AVERROR_EOF; memcpy(buf + written, src, trailing_bytes); written = written + trailing_bytes; }