summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Rheinhardt <andreas.rheinhardt@gmail.com>2019-09-16 15:48:31 +0200
committerAndreas Rheinhardt <andreas.rheinhardt@gmail.com>2020-07-01 15:12:49 +0200
commit61f5c6ab06fc61e0f9f8f8dab5595b8bb202df73 (patch)
tree3734540d1680598883a457688ba729c2665a9619
parent42b28565aa852b98d95d8d02f7b0781999f9d533 (diff)
libavformat/mov: Fix memleaks when demuxing DV audio
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@gmail.com>
-rw-r--r--libavformat/mov.c23
1 files 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;