rust unsafe code quiz: can you spot the issue.
let src = [1_u8, 2, 3, 4];
let mut dest = std::mem::MaybeUninit::<[u8; 4]>::uninit();
std::ptr::copy_nonoverlapping(
&src,
dest.as_mut_ptr(),
std::mem::size_of::<[u8; 4]>());
} }
this code is blatantly wrong, once you know what it is. (also, before you ask, no it's not an argument order issue, that wouldn't compile in this case.)
rustc doesn't lint on this at all. (clippy does have a lint for this)
=> More informations about this toot | More toots from 5225225@furry.engineer
@5225225 lol
=> More informations about this toot | More toots from leo@60228.dev
@5225225 oh wow ow
=> More informations about this toot | More toots from luna@pony.social
@luna yeah. lmao.
hey, clippy does catch this (with a deny by default lint). so moral of the story: run clippy ig.
(honestly, imo this lint would be a candidate for uplifting into rustc itself because it's so obviously wrong to do this, and wrong in a very subtle way.)
=> More informations about this toot | More toots from 5225225@furry.engineer
@5225225 this took me a bit to figure out
wow, this is honestly such an easy mistake to make
=> More informations about this toot | More toots from noah@mastodon.despise.computer
@5225225 OH it's a count not a size for third argument of copy_nonoverlapping 💀💀💀
At least it's reassuring to think that unless you have an IDE that suggests these functions to you and you guess it, you should see a "count" variable name and think for a second. Still, that's an easy footgun
EDIT: and of course here it silently works as intended because of u8
=> More informations about this toot | More toots from SharpLimefox@eldritch.cafe
@5225225
One of the arguments depends on size_of::()
=> More informations about this toot | More toots from SharpLimefox@eldritch.cafe
@SharpLimefox (untyped in that it doesnt need to be a valid T)
see https://github.com/rust-lang/unsafe-code-guidelines/issues/330 for more context
=> More informations about this toot | More toots from 5225225@furry.engineer
@5225225 ah, gotcha
=> More informations about this toot | More toots from SharpLimefox@eldritch.cafe
@5225225 attempting to answer before looking at the actual answer: is taking a mutable pointer of an uninitialized MaybeUninit through as_mut_ptr() UB? maybe
=> More informations about this toot | More toots from fen@yiff.life
@5225225 ah nah ok it's the size argument being in T and not in bytes. yeahhh i'm glad that at least clippy catches that shit
=> More informations about this toot | More toots from fen@yiff.life
@5225225 accesses 12 bytes past the end of either array?
=> More informations about this toot | More toots from charlotte@akko.chir.rs
@5225225 I've been puzzled by this for a while.
Is the bug that copy_nonoverlapping will copy size of [u8;4] x size of [u8;4], so 16 bytes, instead of 4 bytes as intended ?
Because copy_nonoverlapping will copy count (arg3) x size of T, and T here is [u8;4] instead of u8 ?
=> More informations about this toot | More toots from Sobex@sciences.re
@Sobex yep :3
it's subtle but yeah, copy_nonoverlapping takes a count, you don't need to calculate size yourself. the correct thing would be to just pass a constant 1
=> More informations about this toot | More toots from 5225225@furry.engineer This content has been proxied by September (3851b).Proxy Information
text/gemini