authorgravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2020-12-17 12:00:48+01:00
committergravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2020-12-17 12:00:48+01:00
log135f4791e5cbffc75f51d404ef1abb6aca5de0e3
tree2a604d1357e66578b625ef3843256e78884c76d3
parent9e5869262a5f07300b7f4ff65dfe60810f22afee

std: Don't hash undefined bits

auto_hash must be extra careful when hashing integers whose bit size is not a multiple of 8 as, when reinterpreted with mem.asBytes, may contain undefined non-zero bits too.

1 files changed, 10 insertions(+), 1 deletions(-)

lib/std/hash/auto_hash.zig+10-1
...@@ -99,7 +99,16 @@ pub fn hash(hasher: anytype, key: anytype, comptime strat: HashStrategy) void {...@@ -99,7 +99,16 @@ pub fn hash(hasher: anytype, key: anytype, comptime strat: HashStrategy) void {
9999
100 // Help the optimizer see that hashing an int is easy by inlining!100 // Help the optimizer see that hashing an int is easy by inlining!
101 // TODO Check if the situation is better after #561 is resolved.101 // TODO Check if the situation is better after #561 is resolved.
102 .Int => @call(.{ .modifier = .always_inline }, hasher.update, .{std.mem.asBytes(&key)}),102 .Int => {
103 if (comptime meta.trait.hasUniqueRepresentation(Key)) {
104 @call(.{ .modifier = .always_inline }, hasher.update, .{std.mem.asBytes(&key)});
105 } else {
106 // Take only the part containing the key value, the remaining
107 // bytes are undefined and must not be hashed!
108 const byte_size = comptime std.math.divCeil(comptime_int, @bitSizeOf(Key), 8) catch unreachable;
109 @call(.{ .modifier = .always_inline }, hasher.update, .{std.mem.asBytes(&key)[0..byte_size]});
110 }
111 },
103112
104 .Bool => hash(hasher, @boolToInt(key), strat),113 .Bool => hash(hasher, @boolToInt(key), strat),
105 .Enum => hash(hasher, @enumToInt(key), strat),114 .Enum => hash(hasher, @enumToInt(key), strat),