PR #24338 opened by AYOUB NABIL BOUBAGRAT (ayoubnabil)
URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24338
Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24338.patch

samples_per_block is used as a divisor when seeking. reject zero during header 
parsing to prevent a division by zero on malformed BRSTM, BFSTM, and BCSTM 
files. add a FATE regression test.


>From ac528c0cef785024f1b9f575b2f04e6e26556ef3 Mon Sep 17 00:00:00 2001
From: Ayoub Nabil Boubagrat <[email protected]>
Date: Mon, 31 Aug 2026 19:07:19 +0200
Subject: [PATCH] avformat/brstm: reject zero samples per block

Signed-off-by: Ayoub Nabil Boubagrat 
<[email protected]>
---
 libavformat/brstm.c        |  2 ++
 libavformat/tests/seek.c   | 10 ++++++++++
 tests/fate/libavformat.mak | 11 +++++++++++
 3 files changed, 23 insertions(+)

diff --git a/libavformat/brstm.c b/libavformat/brstm.c
index 3fe19fff72..1a7c3a9100 100644
--- a/libavformat/brstm.c
+++ b/libavformat/brstm.c
@@ -253,6 +253,8 @@ static int read_header(AVFormatContext *s)
         return AVERROR_INVALIDDATA;
 
     b->samples_per_block = read32(s);
+    if (!b->samples_per_block)
+        return AVERROR_INVALIDDATA;
     b->last_block_used_bytes = read32(s);
     b->last_block_samples = read32(s);
     b->last_block_size = read32(s);
diff --git a/libavformat/tests/seek.c b/libavformat/tests/seek.c
index 61219e8086..0f2b18330d 100644
--- a/libavformat/tests/seek.c
+++ b/libavformat/tests/seek.c
@@ -67,6 +67,7 @@ int main(int argc, char **argv)
     int frame_count = 1;
     int duration = 4;
     int seekfirst_stream = -1;
+    int expect_open_invalid = 0;
 
     for(i=2; i<argc; i+=2){
         if       (!strcmp(argv[i], "-seekforw")){
@@ -84,6 +85,8 @@ int main(int argc, char **argv)
             if (atoi(argv[i+1])) {
                 ic->flags |= AVFMT_FLAG_FAST_SEEK;
             }
+        } else if(!strcmp(argv[i], "-expect_open_invalid")) {
+            expect_open_invalid = atoi(argv[i+1]);
         } else if(argv[i][0] == '-' && argv[i+1]) {
             av_dict_set(&format_opts, argv[i] + 1, argv[i+1], 0);
         } else {
@@ -105,9 +108,16 @@ int main(int argc, char **argv)
     ret = avformat_open_input(&ic, filename, NULL, &format_opts);
     av_dict_free(&format_opts);
     if (ret < 0) {
+        if (expect_open_invalid && ret == AVERROR_INVALIDDATA)
+            return 0;
         fprintf(stderr, "cannot open %s\n", filename);
         return 1;
     }
+    if (expect_open_invalid) {
+        av_seek_frame(ic, 0, 1, 0);
+        avformat_close_input(&ic);
+        return 1;
+    }
 
     ret = avformat_find_stream_info(ic, NULL);
     if (ret < 0) {
diff --git a/tests/fate/libavformat.mak b/tests/fate/libavformat.mak
index f306e19245..962ec28b01 100644
--- a/tests/fate/libavformat.mak
+++ b/tests/fate/libavformat.mak
@@ -65,6 +65,17 @@ fate-seek_utils: libavformat/tests/seek_utils$(EXESUF)
 fate-seek_utils: CMD = run libavformat/tests/seek_utils$(EXESUF)
 fate-seek_utils: CMP = null
 
+# 103-byte BRSTM with samples_per_block set to zero
+BRSTM_ZERO_SAMPLES_1 = 
UlNUTf7/AQAAAABnAA5IRUFEAAAAUAAAAAAAAAAYAAAAAAAAAAAAAAAAAAAAAAAAAQAfQAAA
+BRSTM_ZERO_SAMPLES_2 = 
AAAAAAAAAAEAAABmAAAAAQAAAAEAAAAAAAAAAQAAAAEAAAABAAAAAERBVEEAAAAJAA==
+BRSTM_DATA_URI = data:application/octet-stream;base64,
+BRSTM_ZERO_SAMPLES_URI = 
$(BRSTM_DATA_URI)$(BRSTM_ZERO_SAMPLES_1)$(BRSTM_ZERO_SAMPLES_2)
+FATE_LIBAVFORMAT-$(call ALLYES, BRSTM_DEMUXER DATA_PROTOCOL) += 
fate-brstm-zero-samples-per-block
+fate-brstm-zero-samples-per-block: libavformat/tests/seek$(EXESUF)
+fate-brstm-zero-samples-per-block: CMD = run libavformat/tests/seek$(EXESUF) \
+    "$(BRSTM_ZERO_SAMPLES_URI)" -expect_open_invalid 1
+fate-brstm-zero-samples-per-block: CMP = null
+
 FATE_LIBAVFORMAT += $(FATE_LIBAVFORMAT-yes)
 FATE-$(CONFIG_AVFORMAT) += $(FATE_LIBAVFORMAT)
 fate-libavformat: $(FATE_LIBAVFORMAT)
-- 
2.52.0

_______________________________________________
ffmpeg-devel mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to