From 95e170228440011bc6ac2eb5c689eda2f75ac586 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Sun, 20 Mar 2022 15:37:31 -0700 Subject: [PATCH 1/2] Preserve the Windows `GetLastError` error in `HandleOrInvalid`. In the `TryFrom for OwnedHandle` and `TryFrom for OwnedHandle` implemenations, `forget` the owned handle on the error path, to avoid calling `CloseHandle` on an invalid handle. It's harmless, except that it may overwrite the thread's `GetLastError` error. --- library/std/src/os/windows/io/handle.rs | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/library/std/src/os/windows/io/handle.rs b/library/std/src/os/windows/io/handle.rs index be2ccbd98e9..120af9f99dd 100644 --- a/library/std/src/os/windows/io/handle.rs +++ b/library/std/src/os/windows/io/handle.rs @@ -147,7 +147,15 @@ impl TryFrom for OwnedHandle { #[inline] fn try_from(handle_or_null: HandleOrNull) -> Result { let owned_handle = handle_or_null.0; - if owned_handle.handle.is_null() { Err(()) } else { Ok(owned_handle) } + if owned_handle.handle.is_null() { + // Don't call `CloseHandle`; it'd be harmless, except that it could + // overwrite the `GetLastError` error. + forget(owned_handle); + + Err(()) + } else { + Ok(owned_handle) + } } } @@ -197,7 +205,15 @@ impl TryFrom for OwnedHandle { #[inline] fn try_from(handle_or_invalid: HandleOrInvalid) -> Result { let owned_handle = handle_or_invalid.0; - if owned_handle.handle == c::INVALID_HANDLE_VALUE { Err(()) } else { Ok(owned_handle) } + if owned_handle.handle == c::INVALID_HANDLE_VALUE { + // Don't call `CloseHandle`; it'd be harmless, except that it could + // overwrite the `GetLastError` error. + forget(owned_handle); + + Err(()) + } else { + Ok(owned_handle) + } } } From 6c407d0592288d3890d45590466b80a364f42982 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Sun, 20 Mar 2022 15:54:03 -0700 Subject: [PATCH 2/2] Add a testcase. --- library/std/src/fs/tests.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/library/std/src/fs/tests.rs b/library/std/src/fs/tests.rs index 6d67c396c62..3fa731c9529 100644 --- a/library/std/src/fs/tests.rs +++ b/library/std/src/fs/tests.rs @@ -1359,6 +1359,12 @@ fn read_dir_not_found() { assert_eq!(res.err().unwrap().kind(), ErrorKind::NotFound); } +#[test] +fn file_open_not_found() { + let res = File::open("/path/that/does/not/exist"); + assert_eq!(res.err().unwrap().kind(), ErrorKind::NotFound); +} + #[test] fn create_dir_all_with_junctions() { let tmpdir = tmpdir();