summaryrefslogtreecommitdiffhomepage
path: root/talpid-core/src
diff options
context:
space:
mode:
authorDavid Lönnhager <david.l@mullvad.net>2024-11-02 13:01:21 +0100
committerDavid Lönnhager <david.l@mullvad.net>2024-11-07 17:08:01 +0100
commit8d6b89bfb33f31b2b6efe1429898d79c20cc4e61 (patch)
treeb98f66389cdc4e08b3a744d5073061c5ddf78cd1 /talpid-core/src
parentcc1ee4f262dfdbbf939d04ad60393b6d6781d96f (diff)
downloadmullvadvpn-8d6b89bfb33f31b2b6efe1429898d79c20cc4e61.tar.xz
mullvadvpn-8d6b89bfb33f31b2b6efe1429898d79c20cc4e61.zip
Remove unnecessary unsafety
Diffstat (limited to 'talpid-core/src')
-rw-r--r--talpid-core/src/firewall/windows/mod.rs34
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,