diff options
author | Matt Wolenetz <wolenetz@google.com> | 2019-07-25 15:54:49 -0700 |
---|---|---|
committer | Michael Niedermayer <michael@niedermayer.cc> | 2019-11-15 12:25:45 +0100 |
commit | c88d2c4e2f7632f5695d0d24899e5aa9db842eea (patch) | |
tree | 4e50ae2f28e370be0a8c56278260c2f7e8952c8e | |
parent | 5088a3e2d3b1f94fedb4d880413b3e9a2dc9c5fb (diff) | |
download | ffmpeg-c88d2c4e2f7632f5695d0d24899e5aa9db842eea.tar.gz |
lafv/wavdec: Fail bext parsing on incomplete reads
avio_read can successfully return even when less than the requested
amount of input was read. wavdec's bext parsing mistakenly assumed a
successful avio_read always read the full amount that was requested.
The result could be dictionary tags populated with partially
uninitialized values.
This change also fixes a broken assertion in wav_parse_bext_string that
was off-by-one, though no known current usage of that method hits that
broken case.
Chromium bug: 987270
Signed-off-by: Matt Wolenetz <wolenetz@chromium.org>
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
(cherry picked from commit 052d41377a02f480f8e7135c0f7d418e9a405215)
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
-rw-r--r-- | libavformat/wavdec.c | 12 |
1 files changed, 7 insertions, 5 deletions
diff --git a/libavformat/wavdec.c b/libavformat/wavdec.c index b016185a1b..22150f63e9 100644 --- a/libavformat/wavdec.c +++ b/libavformat/wavdec.c @@ -232,9 +232,9 @@ static inline int wav_parse_bext_string(AVFormatContext *s, const char *key, char temp[257]; int ret; - av_assert0(length <= sizeof(temp)); - if ((ret = avio_read(s->pb, temp, length)) < 0) - return ret; + av_assert0(length < sizeof(temp)); + if ((ret = avio_read(s->pb, temp, length)) != length) + return ret < 0 ? ret : AVERROR_INVALIDDATA; temp[length] = 0; @@ -303,8 +303,10 @@ static int wav_parse_bext_tag(AVFormatContext *s, int64_t size) if (!(coding_history = av_malloc(size + 1))) return AVERROR(ENOMEM); - if ((ret = avio_read(s->pb, coding_history, size)) < 0) - return ret; + if ((ret = avio_read(s->pb, coding_history, size)) != size) { + av_free(coding_history); + return ret < 0 ? ret : AVERROR_INVALIDDATA; + } coding_history[size] = 0; if ((ret = av_dict_set(&s->metadata, "coding_history", coding_history, |