From e552aeeb605921273919d6edc2f8db3cb11345b0 Mon Sep 17 00:00:00 2001 From: Basix Date: Sun, 9 Aug 2020 17:53:59 +0900 Subject: [PATCH] Fix errors on creating arguments for _wexecv --- vm/src/stdlib/os.rs | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/vm/src/stdlib/os.rs b/vm/src/stdlib/os.rs index 9a66806d4..3151fade7 100644 --- a/vm/src/stdlib/os.rs +++ b/vm/src/stdlib/os.rs @@ -2122,6 +2122,7 @@ pub(crate) use posix::raw_set_inheritable; #[pymodule] mod nt { use super::*; + use crate::obj::objlist::PyListRef; pub(super) use std::os::windows::fs::OpenOptionsExt; use std::os::windows::io::RawHandle; #[cfg(target_env = "msvc")] @@ -2435,11 +2436,16 @@ mod nt { #[cfg(target_env = "msvc")] #[pyfunction] - fn execv(path: PyStringRef, argv_list: Either, vm: &VirtualMachine) -> PyResult<()> { + fn execv( + path: PyStringRef, + argv_list: Either, + vm: &VirtualMachine, + ) -> PyResult<()> { use std::iter::once; use std::os::windows::prelude::*; + use std::str::FromStr; - let path: Vec = ffi::OsString::from_str(path.as_str()) + let path: Vec = ffi::OsString::from_str(path.borrow_value()) .unwrap() .encode_wide() .chain(once(0u16)) @@ -2454,15 +2460,25 @@ mod nt { return Err(vm.new_value_error("execv() arg 2 must not be empty".to_owned())); } - if argv.first().unwrap().to_bytes().is_empty() { + // unwrap is safe, since argv is not empty there has to be a item unless race condition happens + if argv.first().unwrap().is_empty() { return Err( vm.new_value_error("execv() arg 2 first element cannot be empty".to_owned()) ); } - let argv = argv.map(|s| s.encode_wide().chain(once(0u16)).collect::>()); + let argv: Vec> = argv + .into_iter() + .map(|s| s.encode_wide().chain(once(0u16)).collect()) + .collect(); - if (unsafe { _wexecv(&path, &argv) } == -1) { + let argv_execv: Vec<*const u16> = argv + .iter() + .map(|v| v.as_ptr()) + .chain(once(std::ptr::null())) + .collect(); + + if (unsafe { _wexecv(path.as_ptr(), argv_execv.as_ptr()) } == -1) { Err(errno_err(vm)) } else { Ok(())