wstr: Revert incorrect optimization in hash calculation

Calling `Hash::write_bytes` isn't guaranteed to be equivalent to a
sequence of `Hash::write_u8`.

Additionally, make sure the hash is truly prefix-free by hashing the
length first.
This commit is contained in:
Moulins 2023-03-25 04:51:39 +01:00 committed by Mike Welsh
parent 65d2fca7bd
commit 5b4096de8b
2 changed files with 6 additions and 4 deletions

View File

@ -9,6 +9,6 @@ b 2 1,2,3 [object Object] undefined null i [object Object] test 5.3
226
16
WARNING: The output.txt file has been hand-edited to match Ruffle's output, since we don't match Flash's serialization order
{"prop2":true,"myGetter":"Getter value","MY_CONST":"Const val","prop1":"Hello"}
{"prop1":"Hello","myGetter":"Getter value","prop2":true,"MY_CONST":"Const val"}
WARNING: The output.txt file has been hand-edited to match Ruffle's output, since we don't match Flash's serialization order
{"prop2":false,"prop1":"Dynamic","dyn1":"Dyn prop"}
{"prop1":"Dynamic","prop2":false,"dyn1":"Dyn prop"}

View File

@ -150,8 +150,11 @@ pub fn str_cmp_ignore_case(left: &WStr, right: &WStr) -> core::cmp::Ordering {
}
pub fn str_hash<H: Hasher>(s: &WStr, state: &mut H) {
state.write_u32(s.len() as u32);
match s.units() {
Units::Bytes(us) => state.write(us),
// Using `state.write_bytes(us)` would be incorrect here, as `Hash`
// doesn't guarantee any equivalence between its various methods.
Units::Bytes(us) => us.iter().for_each(|u| state.write_u8(*u)),
Units::Wide(us) => us.iter().for_each(|u| {
if *u <= 0xFF {
state.write_u8(*u as u8)
@ -160,7 +163,6 @@ pub fn str_hash<H: Hasher>(s: &WStr, state: &mut H) {
}
}),
}
state.write_u8(0xff);
}
pub fn str_offset_in(s: &WStr, other: &WStr) -> Option<usize> {