From f3fbdf2b44e37d2522c0c879f46c5dee057c14bd Mon Sep 17 00:00:00 2001 From: none <189900@gmail.com> Date: Sat, 5 Aug 2023 12:45:33 +0300 Subject: [PATCH] wyhash: keep tail bytes on iterative update Update calls with input longer then one block must ensure that last sixteen bytes are available when final is called. Fixes #16695 --- lib/std/hash/wyhash.zig | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/lib/std/hash/wyhash.zig b/lib/std/hash/wyhash.zig index aced3be66e..acce3a7732 100644 --- a/lib/std/hash/wyhash.zig +++ b/lib/std/hash/wyhash.zig @@ -57,6 +57,10 @@ pub const Wyhash = struct { } const remaining_bytes = input[i..]; + if (remaining_bytes.len < 16 and i >= 48) { + const rem = 16 - remaining_bytes.len; + @memcpy(self.buf[self.buf.len - rem ..], input[i - rem .. i]); + } @memcpy(self.buf[0..remaining_bytes.len], remaining_bytes); self.buf_len = remaining_bytes.len; } @@ -271,3 +275,19 @@ test "iterative non-divisible update" { try std.testing.expectEqual(iterative_hash, non_iterative_hash); } } + +test "iterative maintains last sixteen" { + const input = "Z" ** 48 ++ "01234567890abcdefg"; + const seed = 0; + + for (0..17) |i| { + const payload = input[0 .. input.len - i]; + const non_iterative_hash = Wyhash.hash(seed, payload); + + var wh = Wyhash.init(seed); + wh.update(payload); + const iterative_hash = wh.final(); + + try expectEqual(non_iterative_hash, iterative_hash); + } +}