windows-permissions-rs
windows-permissions-rs copied to clipboard
std::mem::replace doesn't work on Sid
Because Sid is an opaque type, it is impossible to std::mem::replace
it. Example test:
/// Ensures that std::mem::replace works properly with Sid
#[test]
fn mem_replace() {
let mut sid1 = crate::Sid::well_known_sid(winapi::um::winnt::WinWorldSid).unwrap();
let mut sid2 = crate::Sid::well_known_sid(winapi::um::winnt::WinNtAuthoritySid).unwrap();
assert_eq!(sid1.id_authority(), &[0, 0, 0, 0, 0, 1]);
assert_eq!(sid2.id_authority(), &[0, 0, 0, 0, 0, 5]);
std::mem::swap(&mut *sid1, &mut *sid2);
assert_eq!(sid1.id_authority(), &[0, 0, 0, 0, 0, 5]);
assert_eq!(sid2.id_authority(), &[0, 0, 0, 0, 0, 1]);
}
Fixing this is, erm, complicated. I suppose the ideal solution would be to make Sid an unsized type ([u8]
) instead of an opaque type. This would cause mem::replace
to become a compile time error, I believe, but would turn pointers to Sid into fat pointers.
EDIT: I think what we'd need is https://github.com/rust-lang/rust/issues/43467. If Sid was an Opaque Type, it'd be !Sized, and thus mem::replace
wouldn't work, but a reference to it would still be only a single pointer.
I think that's correct. I don't know of any way to explicitly mark a type as !Sized, but the goal is that it should only be accessible through a pointer.
For what it's worth, swapping does work with std::mem::swap(&mut sid1, &mut sid2)
. This is definitely a bug until there is a way to mark a struct !Sized.
Also, the example uses mem_swap and I think that's the main issue. mem_replace should be fine because you need a raw Sid (not behind a pointer) to call it, and there should never be a way to get hold of one of those.