https://github.com/python/cpython/commit/5c3a47b94a39f87c36b1f36704d80775802ad034
commit: 5c3a47b94a39f87c36b1f36704d80775802ad034
branch: main
author: AN Long <[email protected]>
committer: vstinner <[email protected]>
date: 2026-03-02T19:07:49+01:00
summary:
gh-145335: Fix crash when passing -1 as fd in os.pathconf (#145390)
Co-authored-by: blurb-it[bot] <43283697+blurb-it[bot]@users.noreply.github.com>
files:
A
Misc/NEWS.d/next/Core_and_Builtins/2026-03-01-13-37-31.gh-issue-145335.e36kPJ.rst
M Lib/test/test_os/test_os.py
M Modules/posixmodule.c
diff --git a/Lib/test/test_os/test_os.py b/Lib/test/test_os/test_os.py
index 82c55c8ba33065..1f241609da80cd 100644
--- a/Lib/test/test_os/test_os.py
+++ b/Lib/test/test_os/test_os.py
@@ -2778,6 +2778,16 @@ def test_fpathconf_bad_fd(self):
self.check(os.pathconf, "PC_NAME_MAX")
self.check(os.fpathconf, "PC_NAME_MAX")
+ @unittest.skipUnless(hasattr(os, 'pathconf'), 'test needs os.pathconf()')
+ @unittest.skipIf(
+ support.linked_to_musl(),
+ 'musl fpathconf ignores the file descriptor and returns a constant',
+ )
+ def test_pathconf_negative_fd_uses_fd_semantics(self):
+ with self.assertRaises(OSError) as ctx:
+ os.pathconf(-1, 1)
+ self.assertEqual(ctx.exception.errno, errno.EBADF)
+
@unittest.skipUnless(hasattr(os, 'ftruncate'), 'test needs os.ftruncate()')
def test_ftruncate(self):
self.check(os.truncate, 0)
diff --git
a/Misc/NEWS.d/next/Core_and_Builtins/2026-03-01-13-37-31.gh-issue-145335.e36kPJ.rst
b/Misc/NEWS.d/next/Core_and_Builtins/2026-03-01-13-37-31.gh-issue-145335.e36kPJ.rst
new file mode 100644
index 00000000000000..42ed85c7da31ac
--- /dev/null
+++
b/Misc/NEWS.d/next/Core_and_Builtins/2026-03-01-13-37-31.gh-issue-145335.e36kPJ.rst
@@ -0,0 +1,2 @@
+Fix a crash in :func:`os.pathconf` when called with ``-1`` as the path
+argument.
diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c
index 8d38e034aa6b5e..b82f08e7dc4291 100644
--- a/Modules/posixmodule.c
+++ b/Modules/posixmodule.c
@@ -1280,6 +1280,8 @@ get_posix_state(PyObject *module)
* Contains a file descriptor if path.accept_fd was true
* and the caller provided a signed integer instead of any
* sort of string.
+ * path.is_fd
+ * True if path was provided as a file descriptor.
*
* WARNING: if your "path" parameter is optional, and is
* unspecified, path_converter will never get called.
@@ -1332,6 +1334,7 @@ typedef struct {
const wchar_t *wide;
const char *narrow;
int fd;
+ bool is_fd;
int value_error;
Py_ssize_t length;
PyObject *object;
@@ -1341,7 +1344,7 @@ typedef struct {
#define PATH_T_INITIALIZE(function_name, argument_name, nullable, nonstrict, \
make_wide, suppress_value_error, allow_fd) \
{function_name, argument_name, nullable, nonstrict, make_wide, \
- suppress_value_error, allow_fd, NULL, NULL, -1, 0, 0, NULL, NULL}
+ suppress_value_error, allow_fd, NULL, NULL, -1, false, 0, 0, NULL, NULL}
#ifdef MS_WINDOWS
#define PATH_T_INITIALIZE_P(function_name, argument_name, nullable, \
nonstrict, suppress_value_error, allow_fd) \
@@ -1475,6 +1478,7 @@ path_converter(PyObject *o, void *p)
}
path->wide = NULL;
path->narrow = NULL;
+ path->is_fd = true;
goto success_exit;
}
else {
@@ -14328,8 +14332,9 @@ os_pathconf_impl(PyObject *module, path_t *path, int
name)
errno = 0;
#ifdef HAVE_FPATHCONF
- if (path->fd != -1)
+ if (path->is_fd) {
limit = fpathconf(path->fd, name);
+ }
else
#endif
limit = pathconf(path->narrow, name);
_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]