Skip to content

Commit 1e47e8a

Browse files
authored
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`
2 parents 84f81e7 + d4cba61 commit 1e47e8a

File tree

1 file changed

+13
-5
lines changed
  • library/std/src/sys/windows

1 file changed

+13
-5
lines changed

library/std/src/sys/windows/mod.rs

+13-5
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
use crate::ffi::{CStr, OsStr, OsString};
44
use crate::io::ErrorKind;
5+
use crate::mem::MaybeUninit;
56
use crate::os::windows::ffi::{OsStrExt, OsStringExt};
67
use crate::path::PathBuf;
78
use crate::time::Duration;
@@ -204,8 +205,8 @@ where
204205
// This initial size also works around `GetFullPathNameW` returning
205206
// incorrect size hints for some short paths:
206207
// https://github.com/dylni/normpath/issues/5
207-
let mut stack_buf = [0u16; 512];
208-
let mut heap_buf = Vec::new();
208+
let mut stack_buf: [MaybeUninit<u16>; 512] = MaybeUninit::uninit_array();
209+
let mut heap_buf: Vec<MaybeUninit<u16>> = Vec::new();
209210
unsafe {
210211
let mut n = stack_buf.len();
211212
loop {
@@ -214,6 +215,11 @@ where
214215
} else {
215216
let extra = n - heap_buf.len();
216217
heap_buf.reserve(extra);
218+
// We used `reserve` and not `reserve_exact`, so in theory we
219+
// may have gotten more than requested. If so, we'd like to use
220+
// it... so long as we won't cause overflow.
221+
n = heap_buf.capacity().min(c::DWORD::MAX as usize);
222+
// Safety: MaybeUninit<u16> does not need initialization
217223
heap_buf.set_len(n);
218224
&mut heap_buf[..]
219225
};
@@ -228,13 +234,13 @@ where
228234
// error" is still 0 then we interpret it as a 0 length buffer and
229235
// not an actual error.
230236
c::SetLastError(0);
231-
let k = match f1(buf.as_mut_ptr(), n as c::DWORD) {
237+
let k = match f1(buf.as_mut_ptr().cast::<u16>(), n as c::DWORD) {
232238
0 if c::GetLastError() == 0 => 0,
233239
0 => return Err(crate::io::Error::last_os_error()),
234240
n => n,
235241
} as usize;
236242
if k == n && c::GetLastError() == c::ERROR_INSUFFICIENT_BUFFER {
237-
n *= 2;
243+
n = n.saturating_mul(2).min(c::DWORD::MAX as usize);
238244
} else if k > n {
239245
n = k;
240246
} else if k == n {
@@ -244,7 +250,9 @@ where
244250
// Therefore k never equals n.
245251
unreachable!();
246252
} else {
247-
return Ok(f2(&buf[..k]));
253+
// Safety: First `k` values are initialized.
254+
let slice: &[u16] = MaybeUninit::slice_assume_init_ref(&buf[..k]);
255+
return Ok(f2(slice));
248256
}
249257
}
250258
}

0 commit comments

Comments
 (0)