From 870d44a5f392c48088dcb32cb302740ba7dd9e23 Mon Sep 17 00:00:00 2001 From: Juan Manuel Mendez Rey Date: Mon, 18 May 2026 22:47:06 +0200 Subject: [PATCH] Fix fromHex endianness on big-endian architectures The fromHex function reverses decoded hex bytes into little-endian order, then calls FromBytes() which uses an unsafe pointer cast to reinterpret []byte as []uint64. This cast uses native byte order, producing incorrect results on big-endian systems (e.g. s390x). Replace the unsafe FromBytes() call with explicit binary.LittleEndian.Uint64() decoding so the hex-to-bitmap conversion is correct on all architectures. Fixes #47 --- codec.go | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/codec.go b/codec.go index 95637ef..2435452 100644 --- a/codec.go +++ b/codec.go @@ -170,22 +170,29 @@ func (dst *Bitmap) UnmarshalJSON(data []byte) (err error) { // fromHex reads a hexadecimal string and converts it to bitmap, character at index 0 is the most significant func fromHex(hexString string) (Bitmap, error) { - bytes, err := hex.DecodeString(hexString) + b, err := hex.DecodeString(hexString) switch { case err != nil: return nil, err - case len(bytes) == 0: + case len(b) == 0: return nil, nil } - // reverse bytes to maintain bytes significance order (least significant = hexString tail = list head) - for l, r := 0, len(bytes)-1; l < r; l, r = l+1, r-1 { - bytes[l], bytes[r] = bytes[r], bytes[l] + // reverse bytes into little-endian order (least significant = hexString tail = list head) + for l, r := 0, len(b)-1; l < r; l, r = l+1, r-1 { + b[l], b[r] = b[r], b[l] } - for len(bytes)%8 != 0 { - bytes = append(bytes, 0) + for len(b)%8 != 0 { + b = append(b, 0) } - return FromBytes(bytes), nil + + // Use explicit little-endian decoding instead of unsafe pointer cast + // to produce correct results on big-endian architectures (e.g. s390x). + out := make(Bitmap, len(b)/8) + for i := range out { + out[i] = binary.LittleEndian.Uint64(b[i*8 : (i+1)*8]) + } + return out, nil }