Skip to content

Fix the string scans on big-endian targets with Zig 0.16 - #6

Merged
lalinsky merged 1 commit into
mainfrom
fix-big-endian-vector-mask
Oct 16, 2026
Merged

lalinsky merged 1 commit into
mainfrom
fix-big-endian-vector-mask

Conversation

@lalinsky

Copy link
Copy Markdown
Owner

Zig 0.16 bit-casts element 0 of a bool vector to the most significant bit on big-endian targets, while 0.17 always puts it in the least significant one. Both string scans (scanStringEnd in the decoder, writeString in the encoder) bit-cast the match vector to a u16 and take @ctz, so on a big-endian target with 0.16 they pointed at the wrong byte.

On main, zig build test -Dtarget=s390x-linux -fqemu with 0.16 fails 4 tests: decoding escapes, encoding escapes, the struct round trip and skipping unknown fields. With 0.17 it passes. zt hit the same thing (lalinsky/zt#42).

compat.vectorMask detects the bit order at compile time and reverses the mask when needed, so both versions see element i in bit i. On little-endian targets it compiles to the plain bit-cast.

CI now also runs the tests on s390x under qemu.

Tested on 0.16 and 0.17, natively and on s390x.

Zig 0.16 bit-casts element 0 of a bool vector to the most significant
bit on big-endian targets, while 0.17 always puts it in the least
significant one. With the mask reversed, @ctz pointed at the wrong byte
in both string scans, so decoding failed and encoding could leave
characters unescaped. Detect the bit order at compile time and reverse
the mask when needed.

Also run the tests on s390x under qemu in CI.
@lalinsky
lalinsky merged commit c9dafac into main Oct 16, 2026
4 checks passed
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.

1 participant