Skip to content

Commit 3c693cc

Browse files
committed
Fix crash when passing -1 as fd in os.pathconf
1 parent 6c417e4 commit 3c693cc

File tree

2 files changed

+18
-1
lines changed

2 files changed

+18
-1
lines changed

Lib/test/test_os/test_os.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2778,6 +2778,16 @@ def test_fpathconf_bad_fd(self):
27782778
self.check(os.pathconf, "PC_NAME_MAX")
27792779
self.check(os.fpathconf, "PC_NAME_MAX")
27802780

2781+
@unittest.skipUnless(hasattr(os, 'pathconf'), 'test needs os.pathconf()')
2782+
@unittest.skipIf(
2783+
support.linked_to_musl(),
2784+
'musl pathconf ignores the file descriptor and returns a constant',
2785+
)
2786+
def test_pathconf_negative_fd_uses_fd_semantics(self):
2787+
with self.assertRaises(OSError) as ctx:
2788+
os.pathconf(-1, 1)
2789+
self.assertEqual(ctx.exception.errno, errno.EBADF)
2790+
27812791
@unittest.skipUnless(hasattr(os, 'ftruncate'), 'test needs os.ftruncate()')
27822792
def test_ftruncate(self):
27832793
self.check(os.truncate, 0)

Modules/posixmodule.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1609,6 +1609,12 @@ follow_symlinks_specified(const char *function_name, int follow_symlinks)
16091609
return 1;
16101610
}
16111611

1612+
static bool
1613+
path_is_fd(const path_t *path)
1614+
{
1615+
return path->allow_fd && path->object != NULL && PyIndex_Check(path->object);
1616+
}
1617+
16121618
static int
16131619
path_and_dir_fd_invalid(const char *function_name, path_t *path, int dir_fd)
16141620
{
@@ -14328,8 +14334,9 @@ os_pathconf_impl(PyObject *module, path_t *path, int name)
1432814334

1432914335
errno = 0;
1433014336
#ifdef HAVE_FPATHCONF
14331-
if (path->fd != -1)
14337+
if (path_is_fd(path)) {
1433214338
limit = fpathconf(path->fd, name);
14339+
}
1433314340
else
1433414341
#endif
1433514342
limit = pathconf(path->narrow, name);

0 commit comments

Comments
 (0)