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

## Problem

`ff_mkdir_p` calls `mkdir()` on each path prefix component, including the bare 
drive letter (e.g. `C:`). On Windows, `C:` is a drive-relative path — it 
resolves to the process's saved current directory on drive C:. When the process 
CWD is on a different drive (e.g. E:), `C:` resolves to the drive root (`C:\`), 
and `mkdir("C:\\")` returns `EACCES`, causing spurious "Permission denied" 
errors.

## Reproduction (Windows)

```powershell
cd E:\
ffmpeg -y -f lavfi -i color=c=black:s=128x72:d=2 -pix_fmt yuv420p -c:v libx264 
-f hls -var_stream_map "v:0,name:720p" -hls_segment_filename 
"C:\Users\%USERNAME%\AppData\Local\Temp\test\var-%v\seg%d.ts" 
"C:\Users\%USERNAME%\AppData\Local\Temp\test\var-%v\playlist.m3u8"
# → Permission denied

cd C:\Users\%USERNAME%\AppData\Local\Temp
# same command → works
```

## Fix

Skip the Windows drive letter (`X:`) and the following separator(s) before the 
component walk, guarded with `#if HAVE_DOS_PATHS`.

Fixes #24263


From 01368b88170e9478f9806f9f3845e3e90752c14d Mon Sep 17 00:00:00 2001
From: Khalil Elemam <[email protected]>
Date: Wed, 26 Aug 2026 07:38:01 +0000
Subject: [PATCH] ff_mkdir_p: skip Windows drive letter to avoid spurious
 EACCES

ff_mkdir_p walks the path and calls mkdir() on each prefix component,
including the bare drive letter (e.g. "C:"). On Windows, "C:" is a
drive-relative path that resolves to the process's saved current directory
on that drive. When the process CWD is on a different drive, "C:" resolves
to the drive root (C:\), and mkdir on the root returns EACCES.

This causes spurious "Permission denied" errors when creating output
directories (e.g. HLS segments) on a drive different from the process
working directory.

Fix: skip the drive letter (X:) and the following separator(s) before
the component walk, so the first mkdir targets an absolute path.

Fixes #24263
---
 libavformat/utils.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/libavformat/utils.c b/libavformat/utils.c
index cb0ae7444e..f0ff3b42e8 100644
--- a/libavformat/utils.c
+++ b/libavformat/utils.c
@@ -437,6 +437,19 @@ int ff_mkdir_p(const char *path)
     } else if (!av_strncasecmp(temp, "./", 2) || !av_strncasecmp(temp, ".\\", 
2)) {
         pos += 2;
     }
+    
+#if HAVE_DOS_PATHS
+    /* Skip Windows drive letter (e.g. "C:") and the separator(s) after it.
+     * Without this, the loop below calls mkdir("C:"), which on Windows
+     * is a drive-relative path. When the process CWD is on a different
+     * drive, "C:" resolves to the drive root (C:\), and mkdir on the
+     * root returns EACCES, causing spurious "Permission denied" errors. */
+    if (pos[0] && pos[1] == ':') {
+        pos += 2;
+        while (*pos == '/' || *pos == '\\')
+            pos++;
+    }
+#endif
 
     for ( ; *pos != '\0'; ++pos) {
         if (*pos == '/' || *pos == '\\') {
-- 
2.52.0

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

Reply via email to