summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Rheinhardt <andreas.rheinhardt@gmail.com>2020-06-14 00:37:40 +0200
committerAndreas Rheinhardt <andreas.rheinhardt@gmail.com>2020-07-03 14:13:43 +0200
commit19b1f676f66ec26afb2c9c9501d5451847a7c9b5 (patch)
tree4c1f4305b6afde22f0f9078b08d97b283fe8614a
parentda59fe3eea93e6a3ba48ebb60e151ba7f303c1e6 (diff)
downloadffmpeg-19b1f676f66ec26afb2c9c9501d5451847a7c9b5.tar.gz
avformat/mov: Fix memleaks upon read_header failure
By default, a demuxer's read_close function is not called automatically if an error happens when reading the header; instead it is up to the demuxer to clean up after itself in this case. The mov demuxer did this by calling its read_close function when it encountered some errors when reading the header. Yet for other errors (mostly adding side-data to streams) this has been forgotten, so that all the internal structures of the demuxer leak. This commit fixes this by making sure mov_read_close is called when necessary. Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com> (cherry picked from commit ac378c535be907ee383dafb430be7216a2920982) Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
-rw-r--r--libavformat/mov.c29
1 files changed, 15 insertions, 14 deletions
diff --git a/libavformat/mov.c b/libavformat/mov.c
index 105084813e..0c354ab387 100644
--- a/libavformat/mov.c
+++ b/libavformat/mov.c
@@ -6024,14 +6024,13 @@ static int mov_read_header(AVFormatContext *s)
avio_seek(pb, 0, SEEK_SET);
if ((err = mov_read_default(mov, pb, atom)) < 0) {
av_log(s, AV_LOG_ERROR, "error reading header\n");
- mov_read_close(s);
- return err;
+ goto fail;
}
} while ((pb->seekable & AVIO_SEEKABLE_NORMAL) && !mov->found_moov && !mov->moov_retry++);
if (!mov->found_moov) {
av_log(s, AV_LOG_ERROR, "moov atom not found\n");
- mov_read_close(s);
- return AVERROR_INVALIDDATA;
+ err = AVERROR_INVALIDDATA;
+ goto fail;
}
av_log(mov->fc, AV_LOG_TRACE, "on_parse_exit_offset=%"PRId64"\n", avio_tell(pb));
@@ -6084,7 +6083,7 @@ static int mov_read_header(AVFormatContext *s)
}
if (st->codecpar->codec_id == AV_CODEC_ID_DVD_SUBTITLE) {
if ((err = mov_rewrite_dvd_sub_extradata(st)) < 0)
- return err;
+ goto fail;
}
}
if (mov->handbrake_version &&
@@ -6104,8 +6103,8 @@ static int mov_read_header(AVFormatContext *s)
if (sc->data_size > INT64_MAX / sc->time_scale / 8) {
av_log(s, AV_LOG_ERROR, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
sc->data_size, sc->time_scale);
- mov_read_close(s);
- return AVERROR_INVALIDDATA;
+ err = AVERROR_INVALIDDATA;
+ goto fail;
}
st->codecpar->bit_rate = sc->data_size * 8 * sc->time_scale / st->duration;
}
@@ -6120,8 +6119,8 @@ static int mov_read_header(AVFormatContext *s)
if (sc->data_size > INT64_MAX / sc->time_scale / 8) {
av_log(s, AV_LOG_ERROR, "Overflow during bit rate calculation %"PRId64" * 8 * %d\n",
sc->data_size, sc->time_scale);
- mov_read_close(s);
- return AVERROR_INVALIDDATA;
+ err = AVERROR_INVALIDDATA;
+ goto fail;
}
st->codecpar->bit_rate = sc->data_size * 8 * sc->time_scale /
sc->duration_for_fps;
@@ -6145,8 +6144,7 @@ static int mov_read_header(AVFormatContext *s)
case AVMEDIA_TYPE_AUDIO:
err = ff_replaygain_export(st, s->metadata);
if (err < 0) {
- mov_read_close(s);
- return err;
+ goto fail;
}
break;
case AVMEDIA_TYPE_VIDEO:
@@ -6154,7 +6152,7 @@ static int mov_read_header(AVFormatContext *s)
err = av_stream_add_side_data(st, AV_PKT_DATA_DISPLAYMATRIX, (uint8_t*)sc->display_matrix,
sizeof(int32_t) * 9);
if (err < 0)
- return err;
+ goto fail;
sc->display_matrix = NULL;
}
@@ -6163,7 +6161,7 @@ static int mov_read_header(AVFormatContext *s)
(uint8_t *)sc->stereo3d,
sizeof(*sc->stereo3d));
if (err < 0)
- return err;
+ goto fail;
sc->stereo3d = NULL;
}
@@ -6172,7 +6170,7 @@ static int mov_read_header(AVFormatContext *s)
(uint8_t *)sc->spherical,
sc->spherical_size);
if (err < 0)
- return err;
+ goto fail;
sc->spherical = NULL;
}
@@ -6182,6 +6180,9 @@ static int mov_read_header(AVFormatContext *s)
ff_configure_buffers_for_index(s, AV_TIME_BASE);
return 0;
+fail:
+ mov_read_close(s);
+ return err;
}
static AVIndexEntry *mov_find_next_sample(AVFormatContext *s, AVStream **st)