diff options
author | Andreas Rheinhardt <andreas.rheinhardt@gmail.com> | 2020-06-14 00:37:40 +0200 |
---|---|---|
committer | Andreas Rheinhardt <andreas.rheinhardt@gmail.com> | 2020-06-15 16:46:15 +0200 |
commit | ac378c535be907ee383dafb430be7216a2920982 (patch) | |
tree | 6b51e98c79d2557d053b3887735aa1618062865c | |
parent | 3d3ba43bc68ca90fe72d0fc390c9e5f5c7de1513 (diff) | |
download | ffmpeg-ac378c535be907ee383dafb430be7216a2920982.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>
-rw-r--r-- | libavformat/mov.c | 33 |
1 files changed, 17 insertions, 16 deletions
diff --git a/libavformat/mov.c b/libavformat/mov.c index 2fc27d2aec..47bbb3697d 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -7580,14 +7580,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)); @@ -7640,7 +7639,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 && @@ -7660,8 +7659,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; } @@ -7676,8 +7675,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; @@ -7701,8 +7700,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: @@ -7710,7 +7708,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; } @@ -7719,7 +7717,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; } @@ -7728,7 +7726,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; } @@ -7737,7 +7735,7 @@ static int mov_read_header(AVFormatContext *s) (uint8_t *)sc->mastering, sizeof(*sc->mastering)); if (err < 0) - return err; + goto fail; sc->mastering = NULL; } @@ -7746,7 +7744,7 @@ static int mov_read_header(AVFormatContext *s) (uint8_t *)sc->coll, sc->coll_size); if (err < 0) - return err; + goto fail; sc->coll = NULL; } @@ -7760,6 +7758,9 @@ static int mov_read_header(AVFormatContext *s) mov->frag_index.item[i].headers_read = 1; return 0; +fail: + mov_read_close(s); + return err; } static AVIndexEntry *mov_find_next_sample(AVFormatContext *s, AVStream **st) |