Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RegValue should contain Cow<[u8]>, not Vec<u8> #64

Open
Enyium opened this issue Dec 5, 2023 · 0 comments
Open

RegValue should contain Cow<[u8]>, not Vec<u8> #64

Enyium opened this issue Dec 5, 2023 · 0 comments

Comments

@Enyium
Copy link

Enyium commented Dec 5, 2023

In my abstracting write-function, I prevent having to unnecessarily clone the byte array this way:

pub fn write_reg_bin_value(
    reg_value_path: &RegValuePath,
    bytes: &Vec<u8>,
) -> Result<(), io::Error> {
    let key = RegKey::predef(reg_value_path.hkey)
        .open_subkey_with_flags(reg_value_path.subkey_path, KEY_SET_VALUE)?;

    let unsafe_reg_value = ManuallyDrop::new(RegValue {
        vtype: RegType::REG_BINARY,
        // Unsafely double-owned `Vec`.
        bytes: unsafe { Vec::from_raw_parts(bytes.as_ptr() as _, bytes.len(), bytes.capacity()) },
    });

    // A panic would leak the reg value, but at least not cause a double-drop.
    let result = key.set_raw_value(reg_value_path.value_name, &unsafe_reg_value);

    // Drop only parts in fact owned. Use `ManuallyDrop` like `Vec::into_raw_parts()`, which is available in nightly Rust (as of Nov. 2023).
    let RegValue { bytes, .. } = ManuallyDrop::into_inner(unsafe_reg_value);
    let _ = ManuallyDrop::new(bytes);

    result?;
    Ok(())
}

This is quite hacky, of course.

When winreg generates a RegValue by reading it from the registry, it would use Cow::Owned. But when writing one with RegKey::set_raw_value(), which borrows it immutably anyways, Cow::Borrowed would suffice, so you don't have to unnecessarily clone the value, just for an immutalbe borrow!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant