windows-permissions-rs icon indicating copy to clipboard operation
windows-permissions-rs copied to clipboard

std::mem::replace doesn't work on Sid

Open roblabla opened this issue 3 years ago • 2 comments

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.

roblabla avatar May 24 '21 10:05 roblabla

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.

danieldulaney avatar May 29 '21 21:05 danieldulaney

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.

danieldulaney avatar May 29 '21 21:05 danieldulaney