Skip to content

Commit 71dccf8

Browse files
committed
Also check for NULs in environment variables
This check is necessary, because the underlying API only reads strings until the first NUL.
1 parent 06fab0e commit 71dccf8

File tree

3 files changed

+20
-18
lines changed

3 files changed

+20
-18
lines changed

src/libstd/sys/windows/fs.rs

+3-10
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@ use sync::Arc;
2222
use sys::handle::Handle;
2323
use sys::{c, cvt};
2424
use sys_common::FromInner;
25-
use vec::Vec;
25+
26+
use super::to_u16s;
2627

2728
pub struct File { handle: Handle }
2829

@@ -377,15 +378,6 @@ impl fmt::Debug for File {
377378
}
378379
}
379380

380-
pub fn to_u16s(s: &Path) -> io::Result<Vec<u16>> {
381-
let mut maybe_result = s.as_os_str().encode_wide().collect();
382-
if maybe_result.iter().any(|&u| u == 0) {
383-
return Err(io::Error::new(io::ErrorKind::InvalidInput, "paths cannot contain NULs"));
384-
}
385-
maybe_result.push(0);
386-
Ok(maybe_result)
387-
}
388-
389381
impl FileAttr {
390382
pub fn size(&self) -> u64 {
391383
((self.data.nFileSizeHigh as u64) << 32) | (self.data.nFileSizeLow as u64)
@@ -622,6 +614,7 @@ fn directory_junctions_are_directories() {
622614
use ffi::OsStr;
623615
use env;
624616
use rand::{self, StdRng, Rng};
617+
use vec::Vec;
625618

626619
macro_rules! t {
627620
($e:expr) => (match $e {

src/libstd/sys/windows/mod.rs

+11-4
Original file line numberDiff line numberDiff line change
@@ -72,10 +72,17 @@ pub fn decode_error_kind(errno: i32) -> ErrorKind {
7272
}
7373
}
7474

75-
fn to_utf16_os(s: &OsStr) -> Vec<u16> {
76-
let mut v: Vec<_> = s.encode_wide().collect();
77-
v.push(0);
78-
v
75+
pub fn to_u16s<S: AsRef<OsStr>>(s: S) -> io::Result<Vec<u16>> {
76+
fn inner(s: &OsStr) -> io::Result<Vec<u16>> {
77+
let mut maybe_result: Vec<u16> = s.encode_wide().collect();
78+
if maybe_result.iter().any(|&u| u == 0) {
79+
return Err(io::Error::new(io::ErrorKind::InvalidInput,
80+
"strings passed to WinAPI cannot contain NULs"));
81+
}
82+
maybe_result.push(0);
83+
Ok(maybe_result)
84+
}
85+
inner(s.as_ref())
7986
}
8087

8188
// Many Windows APIs follow a pattern of where we hand a buffer and then they

src/libstd/sys/windows/os.rs

+6-4
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ use slice;
2828
use sys::{c, cvt};
2929
use sys::handle::Handle;
3030

31+
use super::to_u16s;
32+
3133
pub fn errno() -> i32 {
3234
unsafe { c::GetLastError() as i32 }
3335
}
@@ -228,7 +230,7 @@ pub fn chdir(p: &path::Path) -> io::Result<()> {
228230
}
229231

230232
pub fn getenv(k: &OsStr) -> io::Result<Option<OsString>> {
231-
let k = super::to_utf16_os(k);
233+
let k = try!(to_u16s(k));
232234
let res = super::fill_utf16_buf(|buf, sz| unsafe {
233235
c::GetEnvironmentVariableW(k.as_ptr(), buf, sz)
234236
}, |buf| {
@@ -247,16 +249,16 @@ pub fn getenv(k: &OsStr) -> io::Result<Option<OsString>> {
247249
}
248250

249251
pub fn setenv(k: &OsStr, v: &OsStr) -> io::Result<()> {
250-
let k = super::to_utf16_os(k);
251-
let v = super::to_utf16_os(v);
252+
let k = try!(to_u16s(k));
253+
let v = try!(to_u16s(v));
252254

253255
cvt(unsafe {
254256
c::SetEnvironmentVariableW(k.as_ptr(), v.as_ptr())
255257
}).map(|_| ())
256258
}
257259

258260
pub fn unsetenv(n: &OsStr) -> io::Result<()> {
259-
let v = super::to_utf16_os(n);
261+
let v = try!(to_u16s(n));
260262
cvt(unsafe {
261263
c::SetEnvironmentVariableW(v.as_ptr(), ptr::null())
262264
}).map(|_| ())

0 commit comments

Comments
 (0)