[FFmpeg-devel] [PATCH v2] libavformat/mov: Fix memleaks when demuxing DV audio

Andreas Rheinhardt andreas.rheinhardt at gmail.com
Tue Jun 30 00:50:55 EEST 2020


The code for demuxing DV audio predates the introduction of refcounted
packets and when the latter was added, changes to the former were
forgotten. This meant that when avpriv_dv_produce_packet initialized the
packet containing the AVBufferRef, the AVBufferRef as well as the
underlying AVBuffer leaked; the actual packet data didn't leak: They
were directly freed, but not via their AVBuffer's free function.

https://samples.ffmpeg.org/ffmpeg-bugs/trac/ticket4671/dir1.tar.bz2
contains samples for this (enable_drefs needs to be enabled for them).

Moreover, errors in avpriv_dv_produce_packet were ignored; this has been
changed, too.

Furthermore, in the hypothetical scenario that the track has a palette,
this would leak, too, so reorder the code so that the palette code
appears after the DV audio code.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt at gmail.com>
---
I already sent this patch last September [1]; the only difference is
that I have updated the commit message in light of the fact that I have
now found a sample to actually test it (it works as intended). I intend
to apply it in two days unless there are objections.

[1]: https://patchwork.ffmpeg.org/project/ffmpeg/patch/20190916155502.17579-3-andreas.rheinhardt@gmail.com/

 libavformat/mov.c | 23 +++++++++++++----------
 1 file changed, 13 insertions(+), 10 deletions(-)

diff --git a/libavformat/mov.c b/libavformat/mov.c
index adc52de947..8be01dd66b 100644
--- a/libavformat/mov.c
+++ b/libavformat/mov.c
@@ -7898,6 +7898,19 @@ static int mov_read_packet(AVFormatContext *s, AVPacket *pkt)
             }
             return ret;
         }
+#if CONFIG_DV_DEMUXER
+        if (mov->dv_demux && sc->dv_audio_container) {
+            AVBufferRef *buf = pkt->buf;
+            ret = avpriv_dv_produce_packet(mov->dv_demux, pkt, pkt->data, pkt->size, pkt->pos);
+            pkt->buf = buf;
+            av_packet_unref(pkt);
+            if (ret < 0)
+                return ret;
+            ret = avpriv_dv_get_packet(mov->dv_demux, pkt);
+            if (ret < 0)
+                return ret;
+        }
+#endif
         if (sc->has_palette) {
             uint8_t *pal;
 
@@ -7909,16 +7922,6 @@ static int mov_read_packet(AVFormatContext *s, AVPacket *pkt)
                 sc->has_palette = 0;
             }
         }
-#if CONFIG_DV_DEMUXER
-        if (mov->dv_demux && sc->dv_audio_container) {
-            avpriv_dv_produce_packet(mov->dv_demux, pkt, pkt->data, pkt->size, pkt->pos);
-            av_freep(&pkt->data);
-            pkt->size = 0;
-            ret = avpriv_dv_get_packet(mov->dv_demux, pkt);
-            if (ret < 0)
-                return ret;
-        }
-#endif
         if (st->codecpar->codec_id == AV_CODEC_ID_MP3 && !st->need_parsing && pkt->size > 4) {
             if (ff_mpa_check_header(AV_RB32(pkt->data)) < 0)
                 st->need_parsing = AVSTREAM_PARSE_FULL;
-- 
2.20.1



More information about the ffmpeg-devel mailing list