From 71dccf8706ab25f75667c1cbb85ce94f2decbb57 Mon Sep 17 00:00:00 2001 From: Tobias Bucher Date: Thu, 19 Nov 2015 18:01:11 +0000 Subject: [PATCH] Also check for NULs in environment variables This check is necessary, because the underlying API only reads strings until the first NUL. --- src/libstd/sys/windows/fs.rs | 13 +++---------- src/libstd/sys/windows/mod.rs | 15 +++++++++++---- src/libstd/sys/windows/os.rs | 10 ++++++---- 3 files changed, 20 insertions(+), 18 deletions(-) diff --git a/src/libstd/sys/windows/fs.rs b/src/libstd/sys/windows/fs.rs index 31e0949edec..9db7ab53459 100644 --- a/src/libstd/sys/windows/fs.rs +++ b/src/libstd/sys/windows/fs.rs @@ -22,7 +22,8 @@ use sys::handle::Handle; use sys::{c, cvt}; use sys_common::FromInner; -use vec::Vec; + +use super::to_u16s; pub struct File { handle: Handle } @@ -377,15 +378,6 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { } } -pub fn to_u16s(s: &Path) -> io::Result> { - let mut maybe_result = s.as_os_str().encode_wide().collect(); - if maybe_result.iter().any(|&u| u == 0) { - return Err(io::Error::new(io::ErrorKind::InvalidInput, "paths cannot contain NULs")); - } - maybe_result.push(0); - Ok(maybe_result) -} - impl FileAttr { pub fn size(&self) -> u64 { ((self.data.nFileSizeHigh as u64) << 32) | (self.data.nFileSizeLow as u64) @@ -622,6 +614,7 @@ fn directory_junctions_are_directories() { use ffi::OsStr; use env; use rand::{self, StdRng, Rng}; + use vec::Vec; macro_rules! t { ($e:expr) => (match $e { diff --git a/src/libstd/sys/windows/mod.rs b/src/libstd/sys/windows/mod.rs index 3f76218eafe..7e5342a3fd4 100644 --- a/src/libstd/sys/windows/mod.rs +++ b/src/libstd/sys/windows/mod.rs @@ -72,10 +72,17 @@ pub fn decode_error_kind(errno: i32) -> ErrorKind { } } -fn to_utf16_os(s: &OsStr) -> Vec { - let mut v: Vec<_> = s.encode_wide().collect(); - v.push(0); - v +pub fn to_u16s>(s: S) -> io::Result> { + fn inner(s: &OsStr) -> io::Result> { + let mut maybe_result: Vec = s.encode_wide().collect(); + if maybe_result.iter().any(|&u| u == 0) { + return Err(io::Error::new(io::ErrorKind::InvalidInput, + "strings passed to WinAPI cannot contain NULs")); + } + maybe_result.push(0); + Ok(maybe_result) + } + inner(s.as_ref()) } // Many Windows APIs follow a pattern of where we hand a buffer and then they diff --git a/src/libstd/sys/windows/os.rs b/src/libstd/sys/windows/os.rs index 52740b2cad4..e2d2dc1a4de 100644 --- a/src/libstd/sys/windows/os.rs +++ b/src/libstd/sys/windows/os.rs @@ -28,6 +28,8 @@ use sys::{c, cvt}; use sys::handle::Handle; +use super::to_u16s; + pub fn errno() -> i32 { unsafe { c::GetLastError() as i32 } } @@ -228,7 +230,7 @@ pub fn chdir(p: &path::Path) -> io::Result<()> { } pub fn getenv(k: &OsStr) -> io::Result> { - let k = super::to_utf16_os(k); + let k = try!(to_u16s(k)); let res = super::fill_utf16_buf(|buf, sz| unsafe { c::GetEnvironmentVariableW(k.as_ptr(), buf, sz) }, |buf| { @@ -247,8 +249,8 @@ pub fn getenv(k: &OsStr) -> io::Result> { } pub fn setenv(k: &OsStr, v: &OsStr) -> io::Result<()> { - let k = super::to_utf16_os(k); - let v = super::to_utf16_os(v); + let k = try!(to_u16s(k)); + let v = try!(to_u16s(v)); cvt(unsafe { c::SetEnvironmentVariableW(k.as_ptr(), v.as_ptr()) @@ -256,7 +258,7 @@ pub fn setenv(k: &OsStr, v: &OsStr) -> io::Result<()> { } pub fn unsetenv(n: &OsStr) -> io::Result<()> { - let v = super::to_utf16_os(n); + let v = try!(to_u16s(n)); cvt(unsafe { c::SetEnvironmentVariableW(v.as_ptr(), ptr::null()) }).map(|_| ()) -- 2.44.0