]> git.lizzy.rs Git - rust.git/commitdiff
Ignore malformed environment variables on Windows too
authorTobias Bucher <tobiasbucher5991@gmail.com>
Tue, 17 Nov 2015 23:33:34 +0000 (23:33 +0000)
committerTobias Bucher <tobiasbucher5991@gmail.com>
Thu, 19 Nov 2015 20:00:36 +0000 (20:00 +0000)
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

index 52740b2cad4f0cb10a5cef65b8a45d216704c739..545dec270fbcbb735fd194bc551384d7ecb6bf7a 100644 (file)
@@ -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;
+        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);
+
+                // 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..]),
+                ))
             }
-            let p = p as *const u16;
-            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)))
         }
     }
 }