PR #22835 opened by itstanishkraj007
URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/22835
Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/22835.patch

Tests av_adts_header_parse and avpriv_adts_header_parse exercising
all previously untested branches in libavcodec/adts_parser.c:

- NULL buf in av_adts_header_parse (AVERROR(EINVAL) path)
- NULL phdr/buf/small-size guards (AVERROR_INVALIDDATA)
- auto-allocation success path (*phdr == NULL, parse succeeds)
- pre-allocated success path (*phdr != NULL)
- auto-allocation + parse failure (memory correctly freed)

Also submitted to [email protected] mailing list.

Signed-off-by: Tanishk Raj <[email protected]>


From a1678f03ebd9c94565d60609d5c32dfca5d256a4 Mon Sep 17 00:00:00 2001
From: Tanishk Raj <[email protected]>
Date: Sun, 12 Apr 2026 14:26:46 +0530
Subject: [PATCH 1/2] avutil/tests: add test for avpriv_open and
 avpriv_fopen_utf8 failure paths

Test the failure branches in libavutil/file_open.c by calling
avpriv_open and avpriv_fopen_utf8 with a non-existent file and
verifying the return value is negative.
---
 libavutil/Makefile          |  1 +
 libavutil/tests/file_open.c | 69 +++++++++++++++++++++++++++++++++++++
 tests/fate/libavutil.mak    |  7 ++++
 3 files changed, 77 insertions(+)
 create mode 100644 libavutil/tests/file_open.c

diff --git a/libavutil/Makefile b/libavutil/Makefile
index 38e08a3d5d..ba8969367a 100644
--- a/libavutil/Makefile
+++ b/libavutil/Makefile
@@ -311,6 +311,7 @@ TESTPROGS = adler32                                         
            \
             tree                                                        \
             twofish                                                     \
             utf8                                                        \
+            file_open                                                   \
             uuid                                                        \
             video_enc_params                                            \
             xtea                                                        \
diff --git a/libavutil/tests/file_open.c b/libavutil/tests/file_open.c
new file mode 100644
index 0000000000..b22fa1bd45
--- /dev/null
+++ b/libavutil/tests/file_open.c
@@ -0,0 +1,69 @@
+/*
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <fcntl.h>
+#include <stdio.h>
+#include "libavutil/file_open.h"
+
+int main(void)
+{
+    FILE *f;
+    int   fd;
+
+    /* avpriv_open: non-existent file must return negative fd */
+    fd = avpriv_open("no_such_file_xyz", O_RDONLY);
+    if (fd >= 0)
+        return 1;
+
+    /* avpriv_fopen_utf8: invalid mode → default branch → must return NULL */
+    f = avpriv_fopen_utf8("no_such_file_xyz", "x");
+    if (f != NULL)
+        return 2;
+
+    /* avpriv_fopen_utf8: mode 'r' on non-existent file → fd==-1 branch */
+    f = avpriv_fopen_utf8("no_such_file_xyz", "r");
+    if (f != NULL)
+        return 3;
+
+    /* avpriv_fopen_utf8: mode 'w' → O_WRONLY|O_CREAT|O_TRUNC branch */
+    f = avpriv_fopen_utf8("fate_file_open_tmp", "w");
+    if (!f)
+        return 4;
+    fclose(f);
+
+    /* avpriv_fopen_utf8: mode 'a' → O_APPEND branch */
+    f = avpriv_fopen_utf8("fate_file_open_tmp", "a");
+    if (!f)
+        return 5;
+    fclose(f);
+
+    /* avpriv_fopen_utf8: mode 'r+' → while(*m) loop + '+' branch */
+    f = avpriv_fopen_utf8("fate_file_open_tmp", "r+");
+    if (!f)
+        return 6;
+    fclose(f);
+
+    /* avpriv_fopen_utf8: mode 'rb' → while(*m) loop + 'b' branch */
+    f = avpriv_fopen_utf8("fate_file_open_tmp", "rb");
+    if (!f)
+        return 7;
+    fclose(f);
+
+    remove("fate_file_open_tmp");
+    return 0;
+}
diff --git a/tests/fate/libavutil.mak b/tests/fate/libavutil.mak
index 12143bc248..3d50c2e04c 100644
--- a/tests/fate/libavutil.mak
+++ b/tests/fate/libavutil.mak
@@ -216,10 +216,17 @@ fate-file: libavutil/tests/file$(EXESUF)
 fate-file: CMD = run libavutil/tests/file$(EXESUF) 
$(SRC_PATH)/libavutil/tests/file.c
 fate-file: CMP = null
 
+
 FATE_LIBAVUTIL += fate-timecode
 fate-timecode: libavutil/tests/timecode$(EXESUF)
 fate-timecode: CMD = run libavutil/tests/timecode$(EXESUF)
 
+FATE_LIBAVUTIL += fate-avutil-file-open
+fate-avutil-file-open: libavutil/tests/file_open$(EXESUF)
+fate-avutil-file-open: CMD = run libavutil/tests/file_open$(EXESUF)
+fate-avutil-file-open: CMP = null
+ (avutil/tests: add test for avpriv_open and avpriv_fopen_utf8 failure paths)
+
 FATE_LIBAVUTIL += $(FATE_LIBAVUTIL-yes)
 FATE-$(CONFIG_AVUTIL) += $(FATE_LIBAVUTIL)
 fate-libavutil: $(FATE_LIBAVUTIL)
-- 
2.52.0


From 935e0d6cf623d1a7cfd212584cc58973d77e960b Mon Sep 17 00:00:00 2001
From: Tanishk Raj <[email protected]>
Date: Thu, 16 Apr 2026 06:42:33 +0530
Subject: [PATCH 2/2] avcodec/tests: add FATE test for adts_parser

Tests av_adts_header_parse and avpriv_adts_header_parse covering
previously untested branches: NULL input guards, auto-allocation
success and failure paths, and pre-allocated struct path.
---
 libavcodec/Makefile            |   1 +
 libavcodec/tests/adts_parser.c | 111 +++++++++++++++++++++++++++++++++
 tests/fate/libavcodec.mak      |   5 ++
 3 files changed, 117 insertions(+)
 create mode 100644 libavcodec/tests/adts_parser.c

diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index 85d35913f3..f1c6dc34bc 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -1372,6 +1372,7 @@ TESTPROGS = avcodec                                       
              \
             jpeg2000dwt                                                 \
             mathops                                                    \
 
+TESTPROGS-$(CONFIG_ADTS_HEADER)           += adts_parser
 TESTPROGS-$(CONFIG_APV_DECODER)           += apv
 TESTPROGS-$(CONFIG_AV1_VAAPI_ENCODER)     += av1_levels
 TESTPROGS-$(CONFIG_CABAC)                 += cabac
diff --git a/libavcodec/tests/adts_parser.c b/libavcodec/tests/adts_parser.c
new file mode 100644
index 0000000000..3e276c5575
--- /dev/null
+++ b/libavcodec/tests/adts_parser.c
@@ -0,0 +1,111 @@
+/*
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <stdint.h>
+#include <stdio.h>
+
+#include "libavcodec/adts_header.h"
+#include "libavcodec/adts_parser.h"
+#include "libavutil/error.h"
+#include "libavutil/mem.h"
+
+/* minimal valid ADTS header: sync=0xFFF, MPEG-4, AAC-LC, 44100Hz, stereo,
+ * frame_length=7, protection_absent=1 (no CRC) */
+static const uint8_t valid_hdr[AV_AAC_ADTS_HEADER_SIZE] = {
+    0xFF, 0xF1, 0x50, 0x80, 0x00, 0xFF, 0xFC
+};
+
+/* invalid header: missing sync word, triggers parse error */
+static const uint8_t invalid_hdr[AV_AAC_ADTS_HEADER_SIZE] = { 0 };
+
+int main(void)
+{
+    AACADTSHeaderInfo *hdr = NULL;
+    uint32_t samples;
+    uint8_t frames;
+    int ret;
+
+    /* av_adts_header_parse: NULL buf should return EINVAL */
+    ret = av_adts_header_parse(NULL, &samples, &frames);
+    if (ret != AVERROR(EINVAL)) {
+        fprintf(stderr, "expected EINVAL for NULL buf, got %d\n", ret);
+        return 1;
+    }
+
+    /* av_adts_header_parse: valid header should succeed */
+    ret = av_adts_header_parse(valid_hdr, &samples, &frames);
+    if (ret != 0) {
+        fprintf(stderr, "expected 0 for valid header, got %d\n", ret);
+        return 1;
+    }
+
+    /* avpriv_adts_header_parse: NULL phdr */
+    ret = avpriv_adts_header_parse(NULL, valid_hdr, AV_AAC_ADTS_HEADER_SIZE);
+    if (ret != AVERROR_INVALIDDATA) {
+        fprintf(stderr, "expected AVERROR_INVALIDDATA for NULL phdr, got 
%d\n", ret);
+        return 1;
+    }
+
+    /* avpriv_adts_header_parse: NULL buf */
+    ret = avpriv_adts_header_parse(&hdr, NULL, AV_AAC_ADTS_HEADER_SIZE);
+    if (ret != AVERROR_INVALIDDATA) {
+        fprintf(stderr, "expected AVERROR_INVALIDDATA for NULL buf, got %d\n", 
ret);
+        return 1;
+    }
+
+    /* avpriv_adts_header_parse: size too small */
+    ret = avpriv_adts_header_parse(&hdr, valid_hdr, AV_AAC_ADTS_HEADER_SIZE - 
1);
+    if (ret != AVERROR_INVALIDDATA) {
+        fprintf(stderr, "expected AVERROR_INVALIDDATA for small size, got 
%d\n", ret);
+        return 1;
+    }
+
+    /* avpriv_adts_header_parse: *phdr == NULL, let function allocate */
+    hdr = NULL;
+    ret = avpriv_adts_header_parse(&hdr, valid_hdr, AV_AAC_ADTS_HEADER_SIZE);
+    if (ret != 0 || !hdr) {
+        fprintf(stderr, "auto-alloc success path failed: ret=%d hdr=%p\n", 
ret, (void *)hdr);
+        av_freep(&hdr);
+        return 1;
+    }
+    av_freep(&hdr);
+
+    /* avpriv_adts_header_parse: *phdr != NULL, use pre-allocated struct */
+    hdr = av_mallocz(sizeof(*hdr));
+    if (!hdr)
+        return 1;
+    ret = avpriv_adts_header_parse(&hdr, valid_hdr, AV_AAC_ADTS_HEADER_SIZE);
+    if (ret != 0) {
+        fprintf(stderr, "pre-alloc success path failed: ret=%d\n", ret);
+        av_freep(&hdr);
+        return 1;
+    }
+    av_freep(&hdr);
+
+    /* avpriv_adts_header_parse: *phdr == NULL + bad header -> alloc then free
+     * hdr must be NULL after this call (av_freep zeroes the pointer) */
+    hdr = NULL;
+    ret = avpriv_adts_header_parse(&hdr, invalid_hdr, AV_AAC_ADTS_HEADER_SIZE);
+    if (ret >= 0 || hdr != NULL) {
+        fprintf(stderr, "alloc+parse-fail path: ret=%d hdr=%p\n", ret, (void 
*)hdr);
+        av_freep(&hdr);
+        return 1;
+    }
+
+    return 0;
+}
diff --git a/tests/fate/libavcodec.mak b/tests/fate/libavcodec.mak
index e2d616e307..b6cb7940ed 100644
--- a/tests/fate/libavcodec.mak
+++ b/tests/fate/libavcodec.mak
@@ -8,6 +8,11 @@ fate-apv-entropy: libavcodec/tests/apv$(EXESUF)
 fate-apv-entropy: CMD = run libavcodec/tests/apv$(EXESUF)
 fate-apv-entropy: REF = /dev/null
 
+FATE_LIBAVCODEC-$(CONFIG_ADTS_HEADER) += fate-avcodec-adts-parser
+fate-avcodec-adts-parser: libavcodec/tests/adts_parser$(EXESUF)
+fate-avcodec-adts-parser: CMD = run libavcodec/tests/adts_parser
+fate-avcodec-adts-parser: CMP = null
+
 FATE_LIBAVCODEC-yes += fate-avpacket
 fate-avpacket: libavcodec/tests/avpacket$(EXESUF)
 fate-avpacket: CMD = run libavcodec/tests/avpacket$(EXESUF)
-- 
2.52.0

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

Reply via email to