summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2021-10-27 11:17:07 -0400
committerDavid Robillard <d@drobilla.net>2021-10-27 11:17:07 -0400
commit7a26258b1208ca174cbeaf0bc455f459578c623c (patch)
tree431f0d90513c9337ca6484d8cbeab77b982f61c0 /src
parent6efd3ee1cb1c85e39fcdc6f0eef0c0e86db827a6 (diff)
downloadzix-7a26258b1208ca174cbeaf0bc455f459578c623c.tar.gz
zix-7a26258b1208ca174cbeaf0bc455f459578c623c.tar.bz2
zix-7a26258b1208ca174cbeaf0bc455f459578c623c.zip
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.
Diffstat (limited to 'src')
-rw-r--r--src/digest.c10
1 files 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;