Commit 5442733480 for ffmpeg
commit 5442733480f004f5d14323c698e7ded11e24c289
Author: Kacper Michajłow <kasper93@gmail.com>
Date: Thu Oct 29 21:56:57 2026 +0100
avformat/nsvdec: do not allocate the declared info strings size
The NSVf header declares the size of its info strings, up to 2 GiB, and
the buffer was allocated and zeroed before reading them, also when the
file is much shorter. Read them with avio_read_to_bprint(), which
allocates as the data arrives.
Fixes: OOM
Fixes: clusterfuzz-testcase-fuzzer_protocol_memory-6327893299625984
Fixes: clusterfuzz-testcase-fuzzer_protocol_edl-5153066277208064
Found-by: https://github.com/google/oss-fuzz/tree/master/projects/mpv
Signed-off-by: Kacper Michajłow <kasper93@gmail.com>
diff --git a/libavformat/nsvdec.c b/libavformat/nsvdec.c
index 9b945a7c12..b18fc46a4e 100644
--- a/libavformat/nsvdec.c
+++ b/libavformat/nsvdec.c
@@ -22,6 +22,7 @@
*/
#include "libavutil/attributes.h"
+#include "libavutil/bprint.h"
#include "libavutil/mathematics.h"
#include "libavutil/mem.h"
#include "avformat.h"
@@ -301,16 +302,20 @@ static int nsv_parse_NSVf_header(AVFormatContext *s)
av_log(s, AV_LOG_TRACE, "NSV got header; filepos %"PRId64"\n", avio_tell(pb));
if (strings_size > 0) {
- char *strings; /* last byte will be '\0' to play safe with str*() */
+ AVBPrint strings;
char *p, *endp;
char *token, *value;
char quote;
+ int ret;
- p = strings = av_mallocz((size_t)strings_size + 1);
- if (!p)
- return AVERROR(ENOMEM);
- endp = strings + strings_size;
- avio_read(pb, strings, strings_size);
+ av_bprint_init(&strings, 0, AV_BPRINT_SIZE_UNLIMITED);
+ ret = avio_read_to_bprint(pb, &strings, strings_size);
+ if (ret < 0) {
+ av_bprint_finalize(&strings, NULL);
+ return ret;
+ }
+ p = strings.str;
+ endp = strings.str + strings.len;
while (p < endp) {
while (*p == ' ')
p++; /* strip out spaces */
@@ -330,7 +335,7 @@ static int nsv_parse_NSVf_header(AVFormatContext *s)
av_log(s, AV_LOG_TRACE, "NSV NSVf INFO: %s='%s'\n", token, value);
av_dict_set(&s->metadata, token, value, 0);
}
- av_free(strings);
+ av_bprint_finalize(&strings, NULL);
}
if (avio_feof(pb))
return -1;