diff mbox

[FFmpeg-devel,1/2] aadec: improve eof detection

Message ID 20180127230114.82506-2-ottoka@posteo.de
State Superseded
Headers show

Commit Message

Karsten Otto Jan. 27, 2018, 11:01 p.m. UTC
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(-)

Comments

Michael Niedermayer Jan. 28, 2018, 4:10 a.m. UTC | #1
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 mbox

Patch

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;
     }