Skip to content

Commit

Permalink
Fall back to old env arg behavior if CompareStringOrdinal is not av…
Browse files Browse the repository at this point in the history
…ailable

See rust-lang#85270 and rust-lang#87863
  • Loading branch information
seritools committed Dec 29, 2023
1 parent 0bb64a8 commit 02bd38f
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 3 deletions.
10 changes: 10 additions & 0 deletions library/std/src/sys/windows/c.rs
Original file line number Diff line number Diff line change
Expand Up @@ -464,6 +464,16 @@ compat_fn_lazy! {
pbcancel: *mut BOOL,
dwcopyflags: u32,
) -> BOOL;

// >= Vista / Server 2008
// https://docs.microsoft.com/en-us/windows/win32/api/stringapiset/nf-stringapiset-comparestringordinal
pub fn CompareStringOrdinal(
lpstring1: PCWSTR,
cchcount1: i32,
lpstring2: PCWSTR,
cchcount2: i32,
bignorecase: BOOL,
) -> COMPARESTRING_RESULT;
}

compat_fn_optional! {
Expand Down
19 changes: 16 additions & 3 deletions library/std/src/sys/windows/process.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,10 @@ impl EnvKey {
// [4] https://docs.microsoft.com/en-us/windows/win32/api/stringapiset/nf-stringapiset-comparestringordinal
impl Ord for EnvKey {
fn cmp(&self, other: &Self) -> cmp::Ordering {
if !c::CompareStringOrdinal::option().is_some() {
return self.os_string.cmp(&other.os_string);
}

unsafe {
let result = c::CompareStringOrdinal(
self.utf16.as_ptr(),
Expand Down Expand Up @@ -124,7 +128,12 @@ impl PartialEq<str> for EnvKey {
// Environment variable keys should preserve their original case even though
// they are compared using a caseless string mapping.
impl From<OsString> for EnvKey {
fn from(k: OsString) -> Self {
fn from(mut k: OsString) -> Self {
if !c::CompareStringOrdinal::option().is_some() {
k.make_ascii_uppercase();
return EnvKey { utf16: Vec::new(), os_string: k };
}

EnvKey { utf16: k.encode_wide().collect(), os_string: k }
}
}
Expand Down Expand Up @@ -857,8 +866,12 @@ fn make_envp(maybe_env: Option<BTreeMap<EnvKey, OsString>>) -> io::Result<(*mut
}

for (k, v) in env {
ensure_no_nuls(k.os_string)?;
blk.extend(k.utf16);
if !c::CompareStringOrdinal::option().is_some() {
blk.extend(ensure_no_nuls(k.os_string)?.encode_wide());
} else {
ensure_no_nuls(k.os_string)?;
blk.extend(k.utf16);
}
blk.push('=' as u16);
blk.extend(ensure_no_nuls(v)?.encode_wide());
blk.push(0);
Expand Down

0 comments on commit 02bd38f

Please sign in to comment.