Avoid zeroing a 1kb stack buffer on every call to std::sys::windows::fill_utf16_buf
This commit is contained in:
parent
8064a49508
commit
f50f8782fe
@ -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` bytes are initialized.
|
||||
let slice: &[u16] = MaybeUninit::slice_assume_init_ref(&buf[..k]);
|
||||
return Ok(f2(slice));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user