This is an automated email from the git hooks/post-receive script.

Git pushed a commit to branch master
in repository ffmpeg.

commit a6ed750664d6d8760bcee88f8aacec2e7d1b3ab7
Author:     Jun Zhao <[email protected]>
AuthorDate: Sat Jul 11 11:26:20 2026 +0800
Commit:     Jun Zhao <[email protected]>
CommitDate: Sun Jul 12 00:02:40 2026 +0000

    avformat/utils: fix ff_mkdir_p() swallowing intermediate mkdir errors
    
    When creating nested directories (e.g. /a/b/c), a genuine mkdir()
    failure for an intermediate component was overwritten by later
    attempts, making the original failure harder to diagnose.
    
    Stop immediately on intermediate errors other than EEXIST, preserving
    errno for the caller. Existing path components remain non-fatal, as
    required by mkdir -p semantics. Add a regression test for creating a
    child below an existing parent directory.
    
    Signed-off-by: Jun Zhao <[email protected]>
---
 libavformat/Makefile                        |  1 +
 libavformat/tests/.gitignore                |  1 +
 tests/base64.c => libavformat/tests/mkdir.c | 66 +++++++++++++++++------------
 libavformat/utils.c                         |  6 +++
 tests/fate/libavformat.mak                  |  5 +++
 5 files changed, 52 insertions(+), 27 deletions(-)

diff --git a/libavformat/Makefile b/libavformat/Makefile
index 9c761ba341..3595567464 100644
--- a/libavformat/Makefile
+++ b/libavformat/Makefile
@@ -780,6 +780,7 @@ SKIPHEADERS-$(CONFIG_FFRTMPCRYPT_PROTOCOL) += rtmpdh.h
 SKIPHEADERS-$(CONFIG_NETWORK)            += network.h rtsp.h
 
 TESTPROGS = id3v2                                                       \
+            mkdir                                                       \
             seek                                                        \
             url                                                         \
             seek_utils
diff --git a/libavformat/tests/.gitignore b/libavformat/tests/.gitignore
index f9aac1f9e0..951ccf0f37 100644
--- a/libavformat/tests/.gitignore
+++ b/libavformat/tests/.gitignore
@@ -1,6 +1,7 @@
 /id3v2
 /fifo_muxer
 /imf
+/mkdir
 /movenc
 /noproxy
 /rtmpdh
diff --git a/tests/base64.c b/libavformat/tests/mkdir.c
similarity index 50%
copy from tests/base64.c
copy to libavformat/tests/mkdir.c
index 5035ad96a7..42e5c0562d 100644
--- a/tests/base64.c
+++ b/libavformat/tests/mkdir.c
@@ -1,4 +1,6 @@
 /*
+ * Copyright (c) 2026 Jun Zhao
+ *
  * This file is part of FFmpeg.
  *
  * FFmpeg is free software; you can redistribute it and/or
@@ -16,39 +18,49 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-/*
- * Based on libavutil/base64.c
- */
+#include "config.h"
 
+#include <errno.h>
 #include <stdio.h>
 
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include "libavutil/random_seed.h"
+
+#include "libavformat/internal.h"
+#include "libavformat/os_support.h"
+
 int main(void)
 {
-    static const char b64[] =
-        "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
-    unsigned i_bits = 0;
-    int i_shift     = 0;
-    int out_len     = 0;
-    int in;
-
-#define putb64()                                        \
-    do {                                                \
-        putchar(b64[(i_bits << 6 >> i_shift) & 0x3f]);  \
-        out_len++;                                      \
-        i_shift -= 6;                                   \
-    } while (0)
-
-    while ((in = getchar()) != EOF) {
-        i_bits   = (i_bits << 8) + in;
-        i_shift += 8;
-        while (i_shift > 6)
-            putb64();
+    char parent[64];
+    char child[80];
+
+    snprintf(parent, sizeof(parent), "ff-mkdir-test-%08x", 
av_get_random_seed());
+    snprintf(child, sizeof(child), "%s/child", parent);
+
+    if (mkdir(parent, 0755) < 0) {
+        perror("mkdir parent");
+        return 1;
+    }
+
+    if (ff_mkdir_p(child) < 0) {
+        perror("ff_mkdir_p");
+        rmdir(parent);
+        return 1;
+    }
+
+    if (rmdir(child) < 0) {
+        perror("rmdir child");
+        rmdir(parent);
+        return 1;
+    }
+
+    if (rmdir(parent) < 0) {
+        perror("rmdir parent");
+        return 1;
     }
-    while (i_shift > 0)
-        putb64();
-    while (out_len++ & 3)
-        putchar('=');
-    putchar('\n');
 
     return 0;
 }
diff --git a/libavformat/utils.c b/libavformat/utils.c
index c64ff27418..cb0ae7444e 100644
--- a/libavformat/utils.c
+++ b/libavformat/utils.c
@@ -443,6 +443,12 @@ int ff_mkdir_p(const char *path)
             tmp_ch = *pos;
             *pos = '\0';
             ret = mkdir(temp, 0755);
+            if (ret < 0 && errno != EEXIST) {
+                int err = errno;
+                av_free(temp);
+                errno = err;
+                return ret;
+            }
             *pos = tmp_ch;
         }
     }
diff --git a/tests/fate/libavformat.mak b/tests/fate/libavformat.mak
index 3b3a8a1177..989515a646 100644
--- a/tests/fate/libavformat.mak
+++ b/tests/fate/libavformat.mak
@@ -2,6 +2,11 @@
 #fate-async: libavformat/tests/async$(EXESUF)
 #fate-async: CMD = run libavformat/tests/async
 
+FATE_LIBAVFORMAT += fate-mkdir
+fate-mkdir: libavformat/tests/mkdir$(EXESUF)
+fate-mkdir: CMD = run libavformat/tests/mkdir$(EXESUF)
+fate-mkdir: CMP = null
+
 FATE_LIBAVFORMAT-$(CONFIG_NETWORK) += fate-noproxy
 fate-noproxy: libavformat/tests/noproxy$(EXESUF)
 fate-noproxy: CMD = run libavformat/tests/noproxy$(EXESUF)

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

Reply via email to