Skip to content

Commit cc54fda

Browse files
Rollup merge of #87863 - ChrisDenton:command-env-path-fix, r=dtolnay
Fix Windows Command::env("PATH") Fixes #87859
2 parents 0b950d3 + 419902e commit cc54fda

File tree

2 files changed

+30
-9
lines changed

2 files changed

+30
-9
lines changed

library/std/src/sys/windows/process.rs

+24-5
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
#[cfg(test)]
44
mod tests;
55

6-
use crate::borrow::Borrow;
76
use crate::cmp;
87
use crate::collections::BTreeMap;
98
use crate::convert::{TryFrom, TryInto};
@@ -46,6 +45,12 @@ pub struct EnvKey {
4645
utf16: Vec<u16>,
4746
}
4847

48+
impl EnvKey {
49+
fn new<T: Into<OsString>>(key: T) -> Self {
50+
EnvKey::from(key.into())
51+
}
52+
}
53+
4954
// Comparing Windows environment variable keys[1] are behaviourally the
5055
// composition of two operations[2]:
5156
//
@@ -100,6 +105,20 @@ impl PartialEq for EnvKey {
100105
}
101106
}
102107
}
108+
impl PartialOrd<str> for EnvKey {
109+
fn partial_cmp(&self, other: &str) -> Option<cmp::Ordering> {
110+
Some(self.cmp(&EnvKey::new(other)))
111+
}
112+
}
113+
impl PartialEq<str> for EnvKey {
114+
fn eq(&self, other: &str) -> bool {
115+
if self.os_string.len() != other.len() {
116+
false
117+
} else {
118+
self.cmp(&EnvKey::new(other)) == cmp::Ordering::Equal
119+
}
120+
}
121+
}
103122

104123
// Environment variable keys should preserve their original case even though
105124
// they are compared using a caseless string mapping.
@@ -115,9 +134,9 @@ impl From<EnvKey> for OsString {
115134
}
116135
}
117136

118-
impl Borrow<OsStr> for EnvKey {
119-
fn borrow(&self) -> &OsStr {
120-
&self.os_string
137+
impl From<&OsStr> for EnvKey {
138+
fn from(k: &OsStr) -> Self {
139+
Self::from(k.to_os_string())
121140
}
122141
}
123142

@@ -242,7 +261,7 @@ impl Command {
242261
// to read the *child's* PATH if one is provided. See #15149 for more
243262
// details.
244263
let program = maybe_env.as_ref().and_then(|env| {
245-
if let Some(v) = env.get(OsStr::new("PATH")) {
264+
if let Some(v) = env.get(&EnvKey::new("PATH")) {
246265
// Split the value and test each path to see if the
247266
// program exists.
248267
for path in split_paths(&v) {

library/std/src/sys_common/process.rs

+6-4
Original file line numberDiff line numberDiff line change
@@ -65,16 +65,18 @@ impl CommandEnv {
6565

6666
// The following functions build up changes
6767
pub fn set(&mut self, key: &OsStr, value: &OsStr) {
68+
let key = EnvKey::from(key);
6869
self.maybe_saw_path(&key);
69-
self.vars.insert(key.to_owned().into(), Some(value.to_owned()));
70+
self.vars.insert(key, Some(value.to_owned()));
7071
}
7172

7273
pub fn remove(&mut self, key: &OsStr) {
74+
let key = EnvKey::from(key);
7375
self.maybe_saw_path(&key);
7476
if self.clear {
75-
self.vars.remove(key);
77+
self.vars.remove(&key);
7678
} else {
77-
self.vars.insert(key.to_owned().into(), None);
79+
self.vars.insert(key, None);
7880
}
7981
}
8082

@@ -87,7 +89,7 @@ impl CommandEnv {
8789
self.saw_path || self.clear
8890
}
8991

90-
fn maybe_saw_path(&mut self, key: &OsStr) {
92+
fn maybe_saw_path(&mut self, key: &EnvKey) {
9193
if !self.saw_path && key == "PATH" {
9294
self.saw_path = true;
9395
}

0 commit comments

Comments
 (0)