Skip to content

Commit a57c9c1

Browse files
committed
fix posix & winapi to use proper PyMapping
Signed-off-by: snowapril <sinjihng@gmail.com>
1 parent af7b112 commit a57c9c1

File tree

2 files changed

+42
-13
lines changed

2 files changed

+42
-13
lines changed

vm/src/stdlib/posix.rs

+18-4
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ pub mod module {
3333
builtins::{PyDictRef, PyInt, PyListRef, PyStrRef, PyTupleRef, PyTypeRef},
3434
exceptions::IntoPyException,
3535
function::OptionalArg,
36+
protocol::PyMapping,
3637
slots::SlotConstructor,
3738
stdlib::os::{
3839
errno_err, DirFd, FollowSymlinks, PathOrFd, PyPathLike, SupportFunc, TargetIsDirectory,
@@ -1049,8 +1050,21 @@ pub mod module {
10491050
}
10501051

10511052
#[cfg(any(target_os = "linux", target_os = "freebsd", target_os = "macos"))]
1052-
fn envp_from_dict(dict: PyDictRef, vm: &VirtualMachine) -> PyResult<Vec<CString>> {
1053-
dict.into_iter()
1053+
fn envp_from_dict(env: PyMapping, vm: &VirtualMachine) -> PyResult<Vec<CString>> {
1054+
let keys = env.keys(vm)?;
1055+
let values = env.values(vm)?;
1056+
1057+
let keys = PyListRef::try_from_object(vm, keys)
1058+
.map_err(|_| vm.new_type_error("env.keys() is not a list".to_owned()))?
1059+
.borrow_vec()
1060+
.to_vec();
1061+
let values = PyListRef::try_from_object(vm, values)
1062+
.map_err(|_| vm.new_type_error("env.values() is not a list".to_owned()))?
1063+
.borrow_vec()
1064+
.to_vec();
1065+
1066+
keys.into_iter()
1067+
.zip(values.into_iter())
10541068
.map(|(k, v)| {
10551069
let k = PyPathLike::try_from_object(vm, k)?.into_bytes();
10561070
let v = PyPathLike::try_from_object(vm, v)?.into_bytes();
@@ -1085,7 +1099,7 @@ pub mod module {
10851099
#[pyarg(positional)]
10861100
args: crate::function::ArgIterable<PyPathLike>,
10871101
#[pyarg(positional)]
1088-
env: crate::builtins::dict::PyMapping,
1102+
env: PyMapping,
10891103
#[pyarg(named, default)]
10901104
file_actions: Option<crate::function::ArgIterable<PyTupleRef>>,
10911105
#[pyarg(named, default)]
@@ -1198,7 +1212,7 @@ pub mod module {
11981212
.map(|s| s.as_ptr() as _)
11991213
.chain(std::iter::once(std::ptr::null_mut()))
12001214
.collect();
1201-
let mut env = envp_from_dict(self.env.into_dict(), vm)?;
1215+
let mut env = envp_from_dict(self.env, vm)?;
12021216
let envp: Vec<*mut libc::c_char> = env
12031217
.iter_mut()
12041218
.map(|s| s.as_ptr() as _)

vm/src/stdlib/winapi.rs

+24-9
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,11 @@
22

33
use super::os::errno_err;
44
use crate::{
5-
builtins::{dict::PyMapping, PyDictRef, PyStrRef},
5+
builtins::{PyListRef, PyStrRef},
66
exceptions::IntoPyException,
77
function::OptionalArg,
8-
PyObjectRef, PyResult, PySequence, TryFromObject, VirtualMachine,
8+
protocol::PyMapping,
9+
ItemProtocol, PyObjectRef, PyResult, PySequence, TryFromObject, VirtualMachine,
910
};
1011
use std::ptr::{null, null_mut};
1112
use winapi::shared::winerror;
@@ -155,7 +156,7 @@ fn _winapi_CreateProcess(
155156

156157
let mut env = args
157158
.env_mapping
158-
.map(|m| getenvironment(m.into_dict(), vm))
159+
.map(|m| getenvironment(m, vm))
159160
.transpose()?;
160161
let env = env.as_mut().map_or_else(null_mut, |v| v.as_mut_ptr());
161162

@@ -216,9 +217,21 @@ fn _winapi_CreateProcess(
216217
))
217218
}
218219

219-
fn getenvironment(env: PyDictRef, vm: &VirtualMachine) -> PyResult<Vec<u16>> {
220+
fn getenvironment(env: PyMapping, vm: &VirtualMachine) -> PyResult<Vec<u16>> {
221+
let keys = env.keys(vm)?;
222+
let values = env.values(vm)?;
223+
224+
let keys = PyListRef::try_from_object(vm, keys)?.borrow_vec().to_vec();
225+
let values = PyListRef::try_from_object(vm, values)?
226+
.borrow_vec()
227+
.to_vec();
228+
229+
if keys.len() != values.len() {
230+
return Err(vm.new_runtime_error("environment changed size during iteration".to_owned()));
231+
}
232+
220233
let mut out = widestring::WideString::new();
221-
for (k, v) in env {
234+
for (k, v) in keys.into_iter().zip(values.into_iter()) {
222235
let k = PyStrRef::try_from_object(vm, k)?;
223236
let k = k.as_str();
224237
let v = PyStrRef::try_from_object(vm, v)?;
@@ -252,10 +265,11 @@ impl Drop for AttrList {
252265

253266
fn getattributelist(obj: PyObjectRef, vm: &VirtualMachine) -> PyResult<Option<AttrList>> {
254267
<Option<PyMapping>>::try_from_object(vm, obj)?
255-
.map(|d| {
256-
let d = d.into_dict();
257-
let handlelist = d
258-
.get_item_option("handle_list", vm)?
268+
.map(|mapping| {
269+
let handlelist = mapping
270+
.into_object()
271+
.get_item("handle_list", vm)
272+
.ok()
259273
.and_then(|obj| {
260274
<Option<PySequence<usize>>>::try_from_object(vm, obj)
261275
.map(|s| match s {
@@ -265,6 +279,7 @@ fn getattributelist(obj: PyObjectRef, vm: &VirtualMachine) -> PyResult<Option<At
265279
.transpose()
266280
})
267281
.transpose()?;
282+
268283
let attr_count = handlelist.is_some() as u32;
269284
let mut size = 0;
270285
let ret = unsafe {

0 commit comments

Comments
 (0)