From 02bd38f3042f4e90a7771f3eaab8ad62f27e0c9f Mon Sep 17 00:00:00 2001 From: Dennis Duda Date: Thu, 28 Dec 2023 20:19:28 +0100 Subject: [PATCH] Fall back to old env arg behavior if `CompareStringOrdinal` is not available See https://github.com/rust-lang/rust/pull/85270 and https://github.com/rust-lang/rust/pull/87863 --- library/std/src/sys/windows/c.rs | 10 ++++++++++ library/std/src/sys/windows/process.rs | 19 ++++++++++++++++--- 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/library/std/src/sys/windows/c.rs b/library/std/src/sys/windows/c.rs index c7c060324e3a7..4aa76f201f5ef 100644 --- a/library/std/src/sys/windows/c.rs +++ b/library/std/src/sys/windows/c.rs @@ -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! { diff --git a/library/std/src/sys/windows/process.rs b/library/std/src/sys/windows/process.rs index 52b6e9d6accdf..2a24ec33b033e 100644 --- a/library/std/src/sys/windows/process.rs +++ b/library/std/src/sys/windows/process.rs @@ -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(), @@ -124,7 +128,12 @@ impl PartialEq for EnvKey { // Environment variable keys should preserve their original case even though // they are compared using a caseless string mapping. impl From 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 } } } @@ -857,8 +866,12 @@ fn make_envp(maybe_env: Option>) -> 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);