Skip to content

Commit 0dca594

Browse files
StefanKarpinskitkelman
authored andcommitted
hashing of general objects was far too simple (fixes #20744) (#20767)
* hashing of general objects was far too simple (fixes #20744) * hash_uint(3h - object_id(x)) is a somewhat better hash If we'd used `3h - object_id(x)` previously, the original issue would never have come up since `hash(a, hash(b, hash(c, h)))` wouldn't have produced `3A - 3B + 3C - h` but would instead have given the value `27h -9A - 3B - C`, which is asymmetrical in `a` and `c`. Passing the result to `hash_uint` fixes that issue since that function is non-linear, but defense in depth, right? We may as well do the same operations in such a way that the passed-through value gets the most operations done on it.
1 parent 70fc72a commit 0dca594

File tree

2 files changed

+4
-2
lines changed

2 files changed

+4
-2
lines changed

base/hashing.jl

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ hash(w::WeakRef, h::UInt) = hash(w.value, h)
77

88
## hashing general objects ##
99

10-
hash(x::ANY, h::UInt) = 3*object_id(x) - h
10+
hash(x::ANY, h::UInt) = hash_uint(3h - object_id(x))
1111

1212
## core data hashing functions ##
1313

@@ -55,7 +55,6 @@ end
5555

5656
## symbol & expression hashing ##
5757

58-
hash(x::Symbol, h::UInt) = 3*object_id(x) - h
5958
if UInt === UInt64
6059
hash(x::Expr, h::UInt) = hash(x.args, hash(x.head, h + 0x83c7900696d26dc6))
6160
else

test/hashing.jl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,3 +117,6 @@ for prec in [3, 11, 15, 16, 31, 32, 33, 63, 64, 65, 254, 255, 256, 257, 258, 102
117117
@test isequal(x, y)
118118
end
119119
end
120+
121+
# issue #20744
122+
@test hash(:c, hash(:b, hash(:a))) != hash(:a, hash(:b, hash(:c)))

0 commit comments

Comments
 (0)