`Object>>#hashcode` primitive is broken
Hirevo opened this issue · comments
The Object>>#hashcode
primitive is broken.
Its current implementation makes that the hash of the same value can change when recomputed.
This is because of the following code (the current implementation):
let mut hasher = DefaultHasher::new();
// Should be fine, since we do not mutate anything ??
let raw_bytes: &[u8] = unsafe {
std::slice::from_raw_parts(
(&value as *const Value) as *const u8,
std::mem::size_of_val(&value),
)
};
hasher.write(raw_bytes);
let hash = (hasher.finish() as i64).abs();
Return::Local(Value::Integer(hash))
The unsafe bit is the broken bit (predictably):
It takes a instance of Value
, which is an enum, and hashes all of its bytes.
The reason it is broken has to do with the fact that Rust implements enums using tagged unions.
And, within unions, not all bytes are always used by every variants, meaning that there can be some uninitialized bytes within an enum
(which is normally not a problem because Rust doesn't expose these bytes to safe code in any way).
These uninitialized bytes are why a hash can change, even when the value is actually the same.
This has been fixed by #6.
I forgot to make it autoclose this issue when merged. :/