mirror of https://git.ffmpeg.org/ffmpeg.git
aadec: improve eof detection
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. Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
This commit is contained in:
parent
3a2d21bc5f
commit
c126065947
|
@ -46,6 +46,7 @@ typedef struct AADemuxContext {
|
||||||
struct AVTEA *tea_ctx;
|
struct AVTEA *tea_ctx;
|
||||||
uint8_t file_key[16];
|
uint8_t file_key[16];
|
||||||
int64_t current_chapter_size;
|
int64_t current_chapter_size;
|
||||||
|
int64_t content_end;
|
||||||
} AADemuxContext;
|
} AADemuxContext;
|
||||||
|
|
||||||
static int get_second_size(char *codec_name)
|
static int get_second_size(char *codec_name)
|
||||||
|
@ -197,6 +198,7 @@ static int aa_read_header(AVFormatContext *s)
|
||||||
}
|
}
|
||||||
start = TOC[largest_idx].offset;
|
start = TOC[largest_idx].offset;
|
||||||
avio_seek(pb, start, SEEK_SET);
|
avio_seek(pb, start, SEEK_SET);
|
||||||
|
c->content_end = start + largest_size;
|
||||||
c->current_chapter_size = 0;
|
c->current_chapter_size = 0;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -214,6 +216,11 @@ static int aa_read_packet(AVFormatContext *s, AVPacket *pkt)
|
||||||
int ret;
|
int ret;
|
||||||
AADemuxContext *c = s->priv_data;
|
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?
|
// are we at the start of a chapter?
|
||||||
if (c->current_chapter_size == 0) {
|
if (c->current_chapter_size == 0) {
|
||||||
c->current_chapter_size = avio_rb32(s->pb);
|
c->current_chapter_size = avio_rb32(s->pb);
|
||||||
|
@ -234,7 +241,9 @@ static int aa_read_packet(AVFormatContext *s, AVPacket *pkt)
|
||||||
// decrypt c->current_codec_second_size bytes
|
// decrypt c->current_codec_second_size bytes
|
||||||
blocks = c->current_codec_second_size / TEA_BLOCK_SIZE;
|
blocks = c->current_codec_second_size / TEA_BLOCK_SIZE;
|
||||||
for (i = 0; i < blocks; i++) {
|
for (i = 0; i < blocks; i++) {
|
||||||
avio_read(s->pb, src, TEA_BLOCK_SIZE);
|
ret = avio_read(s->pb, src, TEA_BLOCK_SIZE);
|
||||||
|
if (ret != TEA_BLOCK_SIZE)
|
||||||
|
return (ret < 0) ? ret : AVERROR_EOF;
|
||||||
av_tea_init(c->tea_ctx, c->file_key, 16);
|
av_tea_init(c->tea_ctx, c->file_key, 16);
|
||||||
av_tea_crypt(c->tea_ctx, dst, src, 1, NULL, 1);
|
av_tea_crypt(c->tea_ctx, dst, src, 1, NULL, 1);
|
||||||
memcpy(buf + written, dst, TEA_BLOCK_SIZE);
|
memcpy(buf + written, dst, TEA_BLOCK_SIZE);
|
||||||
|
@ -242,7 +251,9 @@ static int aa_read_packet(AVFormatContext *s, AVPacket *pkt)
|
||||||
}
|
}
|
||||||
trailing_bytes = c->current_codec_second_size % TEA_BLOCK_SIZE;
|
trailing_bytes = c->current_codec_second_size % TEA_BLOCK_SIZE;
|
||||||
if (trailing_bytes != 0) { // trailing bytes are left unencrypted!
|
if (trailing_bytes != 0) { // trailing bytes are left unencrypted!
|
||||||
avio_read(s->pb, src, trailing_bytes);
|
ret = avio_read(s->pb, src, trailing_bytes);
|
||||||
|
if (ret != trailing_bytes)
|
||||||
|
return (ret < 0) ? ret : AVERROR_EOF;
|
||||||
memcpy(buf + written, src, trailing_bytes);
|
memcpy(buf + written, src, trailing_bytes);
|
||||||
written = written + trailing_bytes;
|
written = written + trailing_bytes;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue