Hirevo / som-rs

An alternative implementation of the Simple Object Machine, written in Rust

Home Page:https://hirevo.github.io/som-rs/som_interpreter_bc/index.html

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

`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. :/