From 7a26258b1208ca174cbeaf0bc455f459578c623c Mon Sep 17 00:00:00 2001 From: David Robillard Date: Wed, 27 Oct 2021 11:17:07 -0400 Subject: Fix zix_digest64() to consume all input This was a copy-paste bug since the loop in zix_digest32() worked differently. As a result only the first block was considered, making the digest nearly useless for larger values. The tests didn't (and unfortunately still don't) catch this because the 64-bit digest algorithm incorporates the size itself. Fix this by changing the loop to work the same way as zix_digest32(), so hopefully something like this doesn't happen again. --- src/digest.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/digest.c b/src/digest.c index 6483eb0..8a58784 100644 --- a/src/digest.c +++ b/src/digest.c @@ -34,12 +34,12 @@ zix_digest64(const uint64_t seed, const void* const key, const size_t len) { static const uint64_t m = 0x880355F21E6D1965ull; + // Process as many 64-bit blocks as possible const size_t n_blocks = len / sizeof(uint64_t); - const uint8_t* const data = (const uint8_t*)key; + const uint8_t* data = (const uint8_t*)key; const uint8_t* const blocks_end = data + (n_blocks * sizeof(uint64_t)); - - uint64_t h = seed ^ (len * m); - for (size_t i = 0u; i < n_blocks; ++i) { + uint64_t h = seed ^ (len * m); + for (; data != blocks_end; data += sizeof(uint64_t)) { uint64_t k = 0u; memcpy(&k, data, sizeof(uint64_t)); @@ -47,9 +47,9 @@ zix_digest64(const uint64_t seed, const void* const key, const size_t len) h *= m; } + // Process any trailing bytes const uint8_t* const tail = blocks_end; uint64_t v = 0u; - switch (len & 7u) { case 7: v |= (uint64_t)tail[6] << 48u; -- cgit v1.2.1