Skip to content

Commit bf4f6b9

Browse files
committed
Update netrc.py from 3.13.6 and make pwd accesible on android
1 parent e922722 commit bf4f6b9

File tree

4 files changed

+41
-24
lines changed

4 files changed

+41
-24
lines changed

Lib/netrc.py

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,24 @@
22

33
# Module and documentation by Eric S. Raymond, 21 Dec 1998
44

5-
import os, shlex, stat
5+
import os, stat
66

77
__all__ = ["netrc", "NetrcParseError"]
88

99

10+
def _can_security_check():
11+
# On WASI, getuid() is indicated as a stub but it may also be missing.
12+
return os.name == 'posix' and hasattr(os, 'getuid')
13+
14+
15+
def _getpwuid(uid):
16+
try:
17+
import pwd
18+
return pwd.getpwuid(uid)[0]
19+
except (ImportError, LookupError):
20+
return f'uid {uid}'
21+
22+
1023
class NetrcParseError(Exception):
1124
"""Exception raised on syntax errors in the .netrc file."""
1225
def __init__(self, msg, filename=None, lineno=None):
@@ -142,18 +155,12 @@ def _parse(self, file, fp, default_netrc):
142155
self._security_check(fp, default_netrc, self.hosts[entryname][0])
143156

144157
def _security_check(self, fp, default_netrc, login):
145-
if os.name == 'posix' and default_netrc and login != "anonymous":
158+
if _can_security_check() and default_netrc and login != "anonymous":
146159
prop = os.fstat(fp.fileno())
147-
if prop.st_uid != os.getuid():
148-
import pwd
149-
try:
150-
fowner = pwd.getpwuid(prop.st_uid)[0]
151-
except KeyError:
152-
fowner = 'uid %s' % prop.st_uid
153-
try:
154-
user = pwd.getpwuid(os.getuid())[0]
155-
except KeyError:
156-
user = 'uid %s' % os.getuid()
160+
current_user_id = os.getuid()
161+
if prop.st_uid != current_user_id:
162+
fowner = _getpwuid(prop.st_uid)
163+
user = _getpwuid(current_user_id)
157164
raise NetrcParseError(
158165
(f"~/.netrc file owner ({fowner}, {user}) does not match"
159166
" current user"))

Lib/test/test_netrc.py

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,6 @@
11
import netrc, os, unittest, sys, textwrap
2-
from test.support import os_helper, run_unittest
3-
4-
try:
5-
import pwd
6-
except ImportError:
7-
pwd = None
2+
from test import support
3+
from test.support import os_helper
84

95
temp_filename = os_helper.TESTFN
106

@@ -269,9 +265,14 @@ def test_comment_at_end_of_machine_line_pass_has_hash(self):
269265
machine bar.domain.com login foo password pass
270266
""", '#pass')
271267

268+
@unittest.skipUnless(support.is_wasi, 'WASI only test')
269+
def test_security_on_WASI(self):
270+
self.assertFalse(netrc._can_security_check())
271+
self.assertEqual(netrc._getpwuid(0), 'uid 0')
272+
self.assertEqual(netrc._getpwuid(123456), 'uid 123456')
272273

273274
@unittest.skipUnless(os.name == 'posix', 'POSIX only test')
274-
@unittest.skipIf(pwd is None, 'security check requires pwd module')
275+
@unittest.skipUnless(hasattr(os, 'getuid'), "os.getuid is required")
275276
@os_helper.skip_unless_working_chmod
276277
def test_security(self):
277278
# This test is incomplete since we are normally not run as root and
@@ -308,8 +309,6 @@ def test_security(self):
308309
self.assertEqual(nrc.hosts['foo.domain.com'],
309310
('anonymous', '', 'pass'))
310311

311-
def test_main():
312-
run_unittest(NetrcTestCase)
313312

314313
if __name__ == "__main__":
315-
test_main()
314+
unittest.main()

vm/src/stdlib/mod.rs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,13 @@ pub mod posix;
4646
mod ctypes;
4747
#[cfg(windows)]
4848
pub(crate) mod msvcrt;
49-
#[cfg(all(unix, not(any(target_os = "android", target_os = "redox"))))]
49+
50+
#[cfg(all(
51+
unix,
52+
not(any(target_os = "ios", target_os = "wasi", target_os = "redox"))
53+
))]
5054
mod pwd;
55+
5156
pub(crate) mod signal;
5257
pub mod sys;
5358
#[cfg(windows)]
@@ -120,7 +125,10 @@ pub fn get_module_inits() -> StdlibMap {
120125
"_thread" => thread::make_module,
121126
}
122127
// Unix-only
123-
#[cfg(all(unix, not(any(target_os = "android", target_os = "redox"))))]
128+
#[cfg(all(
129+
unix,
130+
not(any(target_os = "ios", target_os = "wasi", target_os = "redox"))
131+
))]
124132
{
125133
"pwd" => pwd::make_module,
126134
}

vm/src/stdlib/pwd.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
pub(crate) use pwd::make_module;
44

5+
#[allow(unused)]
56
#[pymodule]
67
mod pwd {
78
use crate::{
@@ -26,6 +27,7 @@ mod pwd {
2627
pw_dir: String,
2728
pw_shell: String,
2829
}
30+
2931
#[pyclass(with(PyStructSequence))]
3032
impl Passwd {}
3133

@@ -91,6 +93,7 @@ mod pwd {
9193
}
9294

9395
// TODO: maybe merge this functionality into nix?
96+
#[cfg(not(target_os = "android"))]
9497
#[pyfunction]
9598
fn getpwall(vm: &VirtualMachine) -> PyResult<Vec<PyObjectRef>> {
9699
// setpwent, getpwent, etc are not thread safe. Could use fgetpwent_r, but this is easier

0 commit comments

Comments
 (0)