shithub: front

Download patch

ref: b5344401da6ab27d87a5b6e6defc65d73dfdf31e
parent: 438bda55bb6f41735651bcaca77907792fb5d9dd
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Tue Aug 12 04:27:48 EDT 2025

git/*: make murmurhash portable

We can't just cast void* to u32int* and dereference it,
as this causes alignment faults on arm32 (and mips).

so do byte-loads and shift/or instead.

--- a/sys/src/cmd/git/util.c
+++ b/sys/src/cmd/git/util.c
@@ -452,24 +452,13 @@
 	u32int m = 0x5bd1e995;
 	u32int r = 24;
 	u32int h, k;
-	u32int *w, *e;
-	uchar *p;
+	uchar *w, *e;
 	
 	h = Seed ^ n;
 	e = pp;
-	e += (n / 4);
-	for (w = pp; w != e; w++) {
-		/*
-		 * NB: this is endian dependent.
-		 * This is fine for use in git, since the
-		 * hashes computed here are only ever used
-		 * for in memory data structures.
-		 *
-		 * Pack files will differ when packed on
-		 * machines with different endianness,
-		 * but the results will still be correct.
-		 */
-		k = *w;
+	e += n & -4;
+	for (w = pp; w != e; w += 4) {
+		k = (u32int)w[0] | (u32int)w[1] << 8 | (u32int)w[2] << 16 | (u32int)w[3] << 24;
 		k *= m;
 		k ^= k >> r;
 		k *= m;
@@ -478,11 +467,10 @@
 		h ^= k;
 	}
 
-	p = (uchar*)w;
 	switch (n & 0x3) {
-	case 3:	h ^= p[2] << 16;
-	case 2:	h ^= p[1] << 8;
-	case 1:	h ^= p[0] << 0;
+	case 3:	h ^= w[2] << 16;
+	case 2:	h ^= w[1] << 8;
+	case 1:	h ^= w[0] << 0;
 		h *= m;
 	}
 
--