diff options
| author | Matthias Krüger <matthias.krueger@famsik.de> | 2022-08-20 07:09:04 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-08-20 07:09:04 +0200 |
| commit | 1e47e8a9ee83f2b6e110f225f3738392088aa2a9 (patch) | |
| tree | 4496bc5e3b2d4bc204af4f53e8c91a3a7175215e /library/std/src | |
| parent | 84f81e7974da97b293a99087769fe6e9f28fa2c4 (diff) | |
| parent | d4cba61099b3d0457f4ab63a2cb9ae4ae6cf324e (diff) | |
| download | rust-1e47e8a9ee83f2b6e110f225f3738392088aa2a9.tar.gz rust-1e47e8a9ee83f2b6e110f225f3738392088aa2a9.zip | |
Rollup merge of #100729 - thomcc:less-initialized, r=ChrisDenton
Avoid zeroing a 1kb stack buffer on every call to `std::sys::windows::fill_utf16_buf` I've also tried to be slightly more careful about integer overflows, although in practice this is likely still not handled ideally. r? `@ChrisDenton`
Diffstat (limited to 'library/std/src')
| -rw-r--r-- | library/std/src/sys/windows/mod.rs | 18 |
1 files changed, 13 insertions, 5 deletions
diff --git a/library/std/src/sys/windows/mod.rs b/library/std/src/sys/windows/mod.rs index b3f6d2d0aae..a9846a48488 100644 --- a/library/std/src/sys/windows/mod.rs +++ b/library/std/src/sys/windows/mod.rs @@ -2,6 +2,7 @@ use crate::ffi::{CStr, OsStr, OsString}; use crate::io::ErrorKind; +use crate::mem::MaybeUninit; use crate::os::windows::ffi::{OsStrExt, OsStringExt}; use crate::path::PathBuf; use crate::time::Duration; @@ -204,8 +205,8 @@ where // This initial size also works around `GetFullPathNameW` returning // incorrect size hints for some short paths: // https://github.com/dylni/normpath/issues/5 - let mut stack_buf = [0u16; 512]; - let mut heap_buf = Vec::new(); + let mut stack_buf: [MaybeUninit<u16>; 512] = MaybeUninit::uninit_array(); + let mut heap_buf: Vec<MaybeUninit<u16>> = Vec::new(); unsafe { let mut n = stack_buf.len(); loop { @@ -214,6 +215,11 @@ where } else { let extra = n - heap_buf.len(); heap_buf.reserve(extra); + // We used `reserve` and not `reserve_exact`, so in theory we + // may have gotten more than requested. If so, we'd like to use + // it... so long as we won't cause overflow. + n = heap_buf.capacity().min(c::DWORD::MAX as usize); + // Safety: MaybeUninit<u16> does not need initialization heap_buf.set_len(n); &mut heap_buf[..] }; @@ -228,13 +234,13 @@ where // error" is still 0 then we interpret it as a 0 length buffer and // not an actual error. c::SetLastError(0); - let k = match f1(buf.as_mut_ptr(), n as c::DWORD) { + let k = match f1(buf.as_mut_ptr().cast::<u16>(), n as c::DWORD) { 0 if c::GetLastError() == 0 => 0, 0 => return Err(crate::io::Error::last_os_error()), n => n, } as usize; if k == n && c::GetLastError() == c::ERROR_INSUFFICIENT_BUFFER { - n *= 2; + n = n.saturating_mul(2).min(c::DWORD::MAX as usize); } else if k > n { n = k; } else if k == n { @@ -244,7 +250,9 @@ where // Therefore k never equals n. unreachable!(); } else { - return Ok(f2(&buf[..k])); + // Safety: First `k` values are initialized. + let slice: &[u16] = MaybeUninit::slice_assume_init_ref(&buf[..k]); + return Ok(f2(slice)); } } } |
