diff options
| author | David Lönnhager <david.l@mullvad.net> | 2024-11-02 13:01:21 +0100 |
|---|---|---|
| committer | David Lönnhager <david.l@mullvad.net> | 2024-11-07 17:08:01 +0100 |
| commit | 8d6b89bfb33f31b2b6efe1429898d79c20cc4e61 (patch) | |
| tree | b98f66389cdc4e08b3a744d5073061c5ddf78cd1 /talpid-core/src | |
| parent | cc1ee4f262dfdbbf939d04ad60393b6d6781d96f (diff) | |
| download | mullvadvpn-8d6b89bfb33f31b2b6efe1429898d79c20cc4e61.tar.xz mullvadvpn-8d6b89bfb33f31b2b6efe1429898d79c20cc4e61.zip | |
Remove unnecessary unsafety
Diffstat (limited to 'talpid-core/src')
| -rw-r--r-- | talpid-core/src/firewall/windows/mod.rs | 34 |
1 files changed, 31 insertions, 3 deletions
diff --git a/talpid-core/src/firewall/windows/mod.rs b/talpid-core/src/firewall/windows/mod.rs index d4b0b883d4..fa59611132 100644 --- a/talpid-core/src/firewall/windows/mod.rs +++ b/talpid-core/src/firewall/windows/mod.rs @@ -455,11 +455,13 @@ pub extern "system" fn log_sink( } } +/// Convert `mb_string`, with the given character encoding `codepage`, to a UTF-16 string. fn multibyte_to_wide(mb_string: &CStr, codepage: u32) -> Result<Vec<u16>, io::Error> { - if unsafe { *mb_string.as_ptr() } == 0 { + if mb_string.is_empty() { return Ok(vec![]); } + // SAFETY: `mb_string` is null-terminated and valid. let wc_size = unsafe { MultiByteToWideChar( codepage, @@ -475,8 +477,10 @@ fn multibyte_to_wide(mb_string: &CStr, codepage: u32) -> Result<Vec<u16>, io::Er return Err(io::Error::last_os_error()); } - let mut wc_buffer = Vec::with_capacity(wc_size as usize); + let mut wc_buffer = vec![0u16; usize::try_from(wc_size).unwrap()]; + // SAFETY: `wc_buffer` can contain up to `wc_size` characters, including a null + // terminator. let chars_written = unsafe { MultiByteToWideChar( codepage, @@ -492,11 +496,35 @@ fn multibyte_to_wide(mb_string: &CStr, codepage: u32) -> Result<Vec<u16>, io::Er return Err(io::Error::last_os_error()); } - unsafe { wc_buffer.set_len((chars_written - 1) as usize) }; + wc_buffer.truncate(usize::try_from(chars_written - 1).unwrap()); Ok(wc_buffer) } +#[cfg(test)] +mod test { + use super::multibyte_to_wide; + use windows_sys::Win32::Globalization::CP_UTF8; + + #[test] + fn test_multibyte_to_wide() { + // € = 0x20AC in UTF-16 + let converted = multibyte_to_wide(c"€€", CP_UTF8); + const EXPECTED: &[u16] = &[0x20AC, 0x20AC]; + assert!( + matches!(converted.as_deref(), Ok(EXPECTED)), + "expected Ok({EXPECTED:?}), got {converted:?}", + ); + + // boundary case + let converted = multibyte_to_wide(c"", CP_UTF8); + assert!( + matches!(converted.as_deref(), Ok([])), + "unexpected result {converted:?}" + ); + } +} + // Convert `result` into an option and log the error, if any. fn consume_and_log_hyperv_err<T>( action: &'static str, |
