Description
Hi, and thanks for making this project!
Background
Coming from rust-lang/rustup#3896, we (the Rustup team) are currently evaluating the possibility of replacing winreg
with windows-registry
in Rustup. This is mainly because we use the registry APIs to inspect and change the PATH
variable, which is a necessary step in Rustup's installation process.
However, the following function signatures look a bit concerning:
windows-rs/crates/libs/registry/src/key.rs
Line 245 in 2ec4e06
... which is because being valid UTF8 is a core invariant of the str
type. OTOH, it seems to me that there's no guarantee that we should always get/set valid UTF16LE from/to the registry, and we'd like to make sure that Rustup is still working correctly even if there are non-Unicode bytes in the registry value in question (which could be added by a third-party app?).
For example, we now have the following smoke test that inserts into the registry a sequence of u16
that would be considered malformed UTF16LE, and it's expected to work:
// Set up a non unicode PATH
let reg_value = RegValue {
bytes: vec![
0x00, 0xD8, // leading surrogate
0x01, 0x01, // bogus trailing surrogate
0x00, 0x00, // null
],
vtype: RegType::REG_EXPAND_SZ,
};
RegKey::predef(HKEY_CURRENT_USER)
.open_subkey_with_flags("Environment", KEY_READ | KEY_WRITE)
.unwrap()
.set_raw_value("PATH", ®_value)
.unwrap();
Suggestion
For the exact reason explained above, I believe OsStr
/OsString
is a better alternative to str
/String
in APIs like this.
Quoting https://doc.rust-lang.org/std/ffi/struct.OsString.html:
The need for this type arises from the fact that:
- On Windows, strings are often arbitrary sequences of non-zero 16-bit values, interpreted as UTF-16 when it is valid to do so.
Once that change is made, we would be able to use windows::ffi::OsStringExt::from_wide
to construct an OsString
from any &[u16]
.
I'm still not very familiar with Windows development myself, so please feel free to correct me if I'm wrong about anything.
Many thanks in advance!