Return EBADF for negative stat file descriptors (#9008)

* Reject negative file descriptors before fstat

Return EBADF for negative ordinary descriptors before calling rustix, avoiding debug-build assertions on canonical invalid-fd tests. Keep directory-fd sentinel and absolute-path handling unchanged.

Assisted-by: Codex:model-version-unavailable

* Cover negative stat descriptors through the interpreter

Exercise ordinary negative descriptors including values accepted by rustix as directory sentinels, without changing canonical tests or directory-fd parsing.

Assisted-by: Codex:model-version-unavailable

* Move negative stat regression into the os snippet

Preserve the original Unix RustPython-only coverage and every regression assertion while removing the redundant Rust interpreter wrapper. CPython uses -1 as a path sentinel, so keep this regression scoped to its original runtime.

Assisted-by: Codex:model-version-unavailable
This commit is contained in:
youknowdot authored and GitHub committed 2026-10-09 18:27:10 +09:00
1 parent 0943b4813b
commit 98b280109f
2 files changed
+24

No files matched your search

+4
View File
@@ -11,6 +11,10 @@ pub use windows::{StatStruct, fstat};
#[cfg(not(windows))]
pub fn fstat(fd: crate::crt_fd::Borrowed<'_>) -> std::io::Result<StatStruct> {
// Unlike a directory fd, fstat accepts no negative descriptor sentinels.
if fd.as_raw() < 0 {
return Err(std::io::Error::from_raw_os_error(libc::EBADF));
}
rustix::fs::fstat(fd).map_err(Into::into)
}
+20
View File
@@ -8,6 +8,26 @@ from testutils import assert_raises
assert os.name == "posix" or os.name == "nt"
def stat_rejects_negative_file_descriptors():
import errno
import os
for stat in (os.stat, os.fstat):
for fd in (-1, -5, -9, -100, -(2**31)):
try:
stat(fd)
except OSError as exc:
assert exc.errno == errno.EBADF, (stat, fd, exc)
else:
raise AssertionError((stat, fd, "accepted a negative file descriptor"))
# Keep the original RustPython-only coverage: CPython treats -1 as a path sentinel.
if os.name == "posix" and sys.implementation.name == "rustpython":
stat_rejects_negative_file_descriptors()
fd = os.open("README.md", os.O_RDONLY)
assert fd > 0