From 14983477cacd5576fadd7ead609c24451b748e56 Mon Sep 17 00:00:00 2001 From: Tobias Bucher Date: Tue, 17 Nov 2015 23:33:34 +0000 Subject: [PATCH 1/2] Ignore malformed environment variables on Windows too Leading equals symbols are treated as part of the variable name, if there is no other equality symbol or none at all, the environment string is ignored. --- src/libstd/sys/windows/os.rs | 39 ++++++++++++++++++++++-------------- 1 file changed, 24 insertions(+), 15 deletions(-) diff --git a/src/libstd/sys/windows/os.rs b/src/libstd/sys/windows/os.rs index 52740b2cad4..545dec270fb 100644 --- a/src/libstd/sys/windows/os.rs +++ b/src/libstd/sys/windows/os.rs @@ -78,22 +78,31 @@ impl Iterator for Env { type Item = (OsString, OsString); fn next(&mut self) -> Option<(OsString, OsString)> { - unsafe { - if *self.cur == 0 { return None } - let p = &*self.cur; - let mut len = 0; - while *(p as *const u16).offset(len) != 0 { - len += 1; - } - let p = p as *const u16; - let s = slice::from_raw_parts(p, len as usize); - self.cur = self.cur.offset(len + 1); + loop { + unsafe { + if *self.cur == 0 { return None } + let p = &*self.cur as *const u16; + let mut len = 0; + while *p.offset(len) != 0 { + len += 1; + } + let s = slice::from_raw_parts(p, len as usize); + self.cur = self.cur.offset(len + 1); - let (k, v) = match s.iter().position(|&b| b == '=' as u16) { - Some(n) => (&s[..n], &s[n+1..]), - None => (s, &[][..]), - }; - Some((OsStringExt::from_wide(k), OsStringExt::from_wide(v))) + // Windows allows environment variables to start with an equals + // symbol (in any other position, this is the separator between + // variable name and value). Since`s` has at least length 1 at + // this point (because the empty string terminates the array of + // environment variables), we can safely slice. + let pos = match s[1..].iter().position(|&u| u == b'=' as u16).map(|p| p + 1) { + Some(p) => p, + None => continue, + } + return Some(( + OsStringExt::from_wide(&s[..pos]), + OsStringExt::from_wide(&s[pos+1..]), + )) + } } } } From 9b4f16b370c2c4b44de99960a2bf7300c93e3f9e Mon Sep 17 00:00:00 2001 From: Tobias Bucher Date: Thu, 19 Nov 2015 19:07:27 +0000 Subject: [PATCH 2/2] Re-unignore environment test on MinGW --- src/libstd/sys/windows/os.rs | 2 +- src/test/run-pass/env-vars.rs | 5 +---- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/src/libstd/sys/windows/os.rs b/src/libstd/sys/windows/os.rs index 545dec270fb..a01a80c4c38 100644 --- a/src/libstd/sys/windows/os.rs +++ b/src/libstd/sys/windows/os.rs @@ -97,7 +97,7 @@ impl Iterator for Env { let pos = match s[1..].iter().position(|&u| u == b'=' as u16).map(|p| p + 1) { Some(p) => p, None => continue, - } + }; return Some(( OsStringExt::from_wide(&s[..pos]), OsStringExt::from_wide(&s[pos+1..]), diff --git a/src/test/run-pass/env-vars.rs b/src/test/run-pass/env-vars.rs index d86f63c9cb9..933d9a728db 100644 --- a/src/test/run-pass/env-vars.rs +++ b/src/test/run-pass/env-vars.rs @@ -14,10 +14,7 @@ use std::env::*; fn main() { for (k, v) in vars_os() { let v2 = var_os(&k); - // MingW seems to set some funky environment variables like - // "=C:=C:\MinGW\msys\1.0\bin" and "!::=::\" that are returned - // from vars() but not visible from var(). - assert!(v2.is_none() || v2.as_ref().map(|s| &**s) == Some(&*v), + assert!(v2.as_ref().map(|s| &**s) == Some(&*v), "bad vars->var transition: {:?} {:?} {:?}", k, v, v2); } }