summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2020-02-15 14:07:46 +0100
committerwm4 <wm4@nowhere>2020-02-15 14:07:46 +0100
commit121bc6ad62a75eb4a3c9cbd2d4f96fcd18593ac9 (patch)
tree1c5dabbb2aa255dc1969b99cd47ce4a2ac1dde9b
parent64a03b03eacaca7a5b9c2e7323d96811ecad83e0 (diff)
downloadmpv-121bc6ad62a75eb4a3c9cbd2d4f96fcd18593ac9.tar.bz2
mpv-121bc6ad62a75eb4a3c9cbd2d4f96fcd18593ac9.tar.xz
demux_timeline: fix another cursed memory management issue
The timeline stuff has messed up memory management because there are no clear ownership rules between a some demuxer instances (master or demux_timeline) and the timeline object itself. This is another subtle problem that happened: apparently, demux_timeline.open is supposed to take over ownership of timeline, but only on success. If it fails, it's not supposed to free it. It didn't follow this, which lead to a double-free if demux_timeline.open failed. The failure path in demux.c calls both timeline_destroy() and demux_timeline.close on failure.
-rw-r--r--demux/demux_timeline.c10
1 files changed, 7 insertions, 3 deletions
diff --git a/demux/demux_timeline.c b/demux/demux_timeline.c
index a657efdab2..cdad24f02d 100644
--- a/demux/demux_timeline.c
+++ b/demux/demux_timeline.c
@@ -78,6 +78,7 @@ struct virtual_source {
struct priv {
struct timeline *tl;
+ bool owns_tl;
double duration;
@@ -614,6 +615,7 @@ static int d_open(struct demuxer *demuxer, enum demux_check check)
reselect_streams(demuxer);
+ p->owns_tl = true;
return 0;
}
@@ -629,9 +631,11 @@ static void d_close(struct demuxer *demuxer)
close_lazy_segments(demuxer, src);
}
- struct demuxer *master = p->tl->demuxer;
- timeline_destroy(p->tl);
- demux_free(master);
+ if (p->owns_tl) {
+ struct demuxer *master = p->tl->demuxer;
+ timeline_destroy(p->tl);
+ demux_free(master);
+ }
}
static void d_switched_tracks(struct demuxer *demuxer)