Skip to content

Fix fromHex endianness on big-endian architectures (s390x)#48

Open
vejeta wants to merge 1 commit into
kelindar:mainfrom
vejeta:fix/fromhex-big-endian
Open

Fix fromHex endianness on big-endian architectures (s390x)#48
vejeta wants to merge 1 commit into
kelindar:mainfrom
vejeta:fix/fromhex-big-endian

Conversation

@vejeta
Copy link
Copy Markdown

@vejeta vejeta commented May 18, 2026

Fixes #47

Hello, first from all, thanks for this project. I was packaging this for debian, and found
the issue in CI that was reported on #47

This is a little patch.

Summary:

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 interprets bytes in native
byte order, so on big-endian systems (e.g. s390x) the uint64 values come
out byte-swapped.

For example, hex string "FFA001" produces:

  • Little-endian (amd64, arm64): 0xFFA001 (correct)
  • Big-endian (s390x): 0x01A0FF0000000000 (wrong)

The fix replaces the FromBytes() call with explicit
binary.LittleEndian.Uint64() decoding, which produces correct results
regardless of the host byte order. All existing tests continue to pass
on little-endian, and the two failing tests (TestJSON, TestFromHex)
are fixed on big-endian.

For the origin where we found this bug in Debian. CI: where autopkgtest
runs on s390x among other architectures:
https://ci.debian.net/packages/g/golang-github-kelindar-bitmap/testing/s390x/71172418/

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 kelindar#47
Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request updates the fromHex function in codec.go to use explicit little-endian decoding, ensuring compatibility with big-endian architectures like s390x. The reviewer pointed out that the FromBytes function still contains platform-dependent code using unsafe.Pointer and recommended either making it platform-independent or auditing its other usages to prevent similar bugs in other parts of the package.

Comment thread codec.go
Comment on lines +191 to +196
// 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])
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

Replacing the FromBytes call with explicit little-endian decoding correctly addresses the endianness issue for the fromHex function. However, as noted in the pull request description, the FromBytes function itself uses an unsafe.Pointer cast that is sensitive to host byte order. If FromBytes is still used elsewhere in the package (for example, in binary deserialization logic), those call sites will remain broken on big-endian architectures like s390x. It is recommended to either update FromBytes to be platform-independent or audit all other usages to ensure they are not intended for portable data formats.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

FAIL: TestJSON TestFromHex: big-endian s390x issue?

1 participant