lodepng-rust
lodepng-rust copied to clipboard
Using any (impl Copy) type as pixel buffer is unspecified behaviour
The encoder API encourages to use "any type as long as it has 4 bytes per element", and does fn buffer_for_type(){ ... unsafe { pointer cast }}
. It has the following problem
- Casting the pointer to a different type and then deference it is probably undefined behaviour. I haven't verified this yet.
- even if this is defined behaviour, it is still unspecified: rust doesn't guarantee any layout on struct or tuple (unless you decorate it with
#[repr()]
). In other words, when the user supply a buffer with[(R, G, B, A)]
type, the compiler can freely reorder the members and gives unexpected[(G, R, B, A)]
layout.
I've added an extra 'static
bound in 71c80da055c94aa1f2c78d6cb7f9d2f8a03507ac to make it less terrible. Note that this hack is used only for reading memory, so even if you passed in something silly like a pointer or a reference, it wouldn't be UB, because there's no dereferencing, and it wouldn't create an invalid pointer.
I'm not too worried about cases where it's merely wrong (like reordered fields), because that's just a case of garbage-in-garbage-out. I'm checking size_of
, so there shouldn't be some outright terrible UB in there.
Types may have padding bytes, and it would read the padding bytes. But I assume that's merely an unspecified/implementation-defined behavior rather than the evil UB.
It'd be great if Rust had a plain-old-data auto-trait. Do you have a suggestion what should I use instead?