mirror of
https://github.com/RustPython/RustPython.git
synced 2026-10-28 18:59:04 +08:00
Fix pwd.getpwuid raising OSError for unknown uids (#9106)
When a uid does not exist, some NSS backends (systemd-userdb, sssd, LDAP) make getpwuid_r() return a non-zero errno such as ENOENT. POSIX expects success with a NULL result instead. That errno was surfacing as FileNotFoundError and broke test_pwd.test_errors. Match CPython's pwdmodule.c: raise MemoryError only for ENOMEM, and treat any other failure as "not found" (KeyError). Assisted-by: Antigravity:Claude Opus 5.5
This commit is contained in:
1 parent
28393e932d
commit
bc8080a52f
1 file changed
+11
-7
@@ -5,8 +5,8 @@ pub(crate) use pwd::module_def;
|
||||
#[pymodule]
|
||||
mod pwd {
|
||||
use crate::{
|
||||
PyResult, VirtualMachine, builtins::PyUtf8StrRef, convert::IntoPyException, exceptions,
|
||||
function::ArgIndex, types::PyStructSequence,
|
||||
PyResult, VirtualMachine, builtins::PyUtf8StrRef, exceptions, function::ArgIndex,
|
||||
types::PyStructSequence,
|
||||
};
|
||||
use core::hint::cold_path;
|
||||
use rustpython_host_env::pwd as host_pwd;
|
||||
@@ -67,12 +67,16 @@ mod pwd {
|
||||
#[pyfunction]
|
||||
fn getpwuid(uidobj: ArgIndex, vm: &VirtualMachine) -> PyResult<PasswdData> {
|
||||
let uidobj = uidobj.into_int_ref();
|
||||
let uid_t = libc::uid_t::try_from(uidobj.as_bigint()).ok();
|
||||
let user = uid_t
|
||||
let user = match libc::uid_t::try_from(uidobj.as_bigint())
|
||||
.ok()
|
||||
.map(host_pwd::getpwuid)
|
||||
.transpose()
|
||||
.map_err(|err| err.into_pyexception(vm))?
|
||||
.flatten();
|
||||
{
|
||||
Some(Ok(user)) => user,
|
||||
Some(Err(err)) if err.raw_os_error() == Some(libc::ENOMEM) => {
|
||||
return Err(vm.no_memory_error());
|
||||
}
|
||||
_ => None,
|
||||
};
|
||||
let user = user.ok_or_else(|| {
|
||||
vm.new_key_error(
|
||||
vm.ctx
|
||||
|
||||
Reference in new issue
Block a user