about summary refs log tree commit diff
diff options
context:
space:
mode:
authorChris Denton <christophersdenton@gmail.com>2022-10-21 17:57:22 +0100
committerChris Denton <christophersdenton@gmail.com>2022-10-21 18:06:12 +0100
commitd7b0bcb20f2f7d5f3ea3489d56ece630147e98f5 (patch)
tree14979b75840969a5dd5bdbf73551f37e5a9cdc6f
parent657f246812ab2684e3c3954b1c77f98fd59e0b21 (diff)
downloadrust-d7b0bcb20f2f7d5f3ea3489d56ece630147e98f5.tar.gz
rust-d7b0bcb20f2f7d5f3ea3489d56ece630147e98f5.zip
Reduce false positives in msys2 detection
This checks that:

* the handle is a pipe
* the pipe's file name starts with "msys-" or "cygwin-" rather than looking in the full path.
-rw-r--r--library/std/src/sys/windows/c.rs3
-rw-r--r--library/std/src/sys/windows/io.rs11
2 files changed, 12 insertions, 2 deletions
diff --git a/library/std/src/sys/windows/c.rs b/library/std/src/sys/windows/c.rs
index 917fc8e4995..be6fc2ebb7a 100644
--- a/library/std/src/sys/windows/c.rs
+++ b/library/std/src/sys/windows/c.rs
@@ -129,6 +129,8 @@ pub const FIONBIO: c_ulong = 0x8004667e;
 
 pub const MAX_PATH: usize = 260;
 
+pub const FILE_TYPE_PIPE: u32 = 3;
+
 #[repr(C)]
 #[derive(Copy)]
 pub struct WIN32_FIND_DATAW {
@@ -1114,6 +1116,7 @@ extern "system" {
         lpFileInformation: LPVOID,
         dwBufferSize: DWORD,
     ) -> BOOL;
+    pub fn GetFileType(hfile: HANDLE) -> DWORD;
     pub fn SleepConditionVariableSRW(
         ConditionVariable: PCONDITION_VARIABLE,
         SRWLock: PSRWLOCK,
diff --git a/library/std/src/sys/windows/io.rs b/library/std/src/sys/windows/io.rs
index 0879ef19933..2cc34c986b9 100644
--- a/library/std/src/sys/windows/io.rs
+++ b/library/std/src/sys/windows/io.rs
@@ -120,6 +120,11 @@ unsafe fn handle_is_console(handle: BorrowedHandle<'_>) -> bool {
 }
 
 unsafe fn msys_tty_on(handle: c::HANDLE) -> bool {
+    // Early return if the handle is not a pipe.
+    if c::GetFileType(handle) != c::FILE_TYPE_PIPE {
+        return false;
+    }
+
     const SIZE: usize = size_of::<c::FILE_NAME_INFO>() + c::MAX_PATH * size_of::<c::WCHAR>();
     let mut name_info_bytes = Align8([0u8; SIZE]);
     let res = c::GetFileInformationByHandleEx(
@@ -137,11 +142,13 @@ unsafe fn msys_tty_on(handle: c::HANDLE) -> bool {
     let name_ptr = name_info_bytes.0.as_ptr().offset(size_of::<c::DWORD>() as isize).cast::<u16>();
     let s = core::slice::from_raw_parts(name_ptr, name_len);
     let name = String::from_utf16_lossy(s);
+    // Get the file name only.
+    let name = name.rsplit('\\').next().unwrap_or(&name);
     // This checks whether 'pty' exists in the file name, which indicates that
     // a pseudo-terminal is attached. To mitigate against false positives
     // (e.g., an actual file name that contains 'pty'), we also require that
-    // either the strings 'msys-' or 'cygwin-' are in the file name as well.)
-    let is_msys = name.contains("msys-") || name.contains("cygwin-");
+    // the file name begins with either the strings 'msys-' or 'cygwin-'.)
+    let is_msys = name.starts_with("msys-") || name.starts_with("cygwin-");
     let is_pty = name.contains("-pty");
     is_msys && is_pty
 }