about summary refs log tree commit diff
path: root/src/libstd/sys
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2015-11-19 22:15:13 +0000
committerbors <bors@rust-lang.org>2015-11-19 22:15:13 +0000
commit6861c51453963317849b4488ddc6a110e4f3470a (patch)
tree00156f3ae5e43cc0d20f149e48dcb18f2f2b7ef9 /src/libstd/sys
parent19020210321b08f136349968a8d868f789445090 (diff)
parent9b4f16b370c2c4b44de99960a2bf7300c93e3f9e (diff)
downloadrust-6861c51453963317849b4488ddc6a110e4f3470a.tar.gz
rust-6861c51453963317849b4488ddc6a110e4f3470a.zip
Auto merge of #29901 - tbu-:pr_env_ignore_malformed_windows, r=alexcrichton
See also #29297.
Diffstat (limited to 'src/libstd/sys')
-rw-r--r--src/libstd/sys/windows/os.rs39
1 files changed, 24 insertions, 15 deletions
diff --git a/src/libstd/sys/windows/os.rs b/src/libstd/sys/windows/os.rs
index 52740b2cad4..a01a80c4c38 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;
+        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)))
         }
     }
 }