You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Surfaced by the new native host test harness (#78) — the first thing it caught.
Symptom
FormatUtilsTest.TestDetectFormatVersion fails on the host build (Linux, g++ 13, -O2):
format_utils_test.cpp:60: Expected equality of these values:
FormatUtils::VERSION_2 (2)
FormatUtils::detectFormatVersion(...) (-1 == UNKNOWN_VERSION)
The test builds a 12-byte big-endian header [9B C1 3A FE | 00 02 | 00 00 | 00 00 00 00] and expects detectFormatVersion to report VERSION_2; on host it reports UNKNOWN.
readUint32 signed-shift UB: suspected (uint8_t promotes to int, 0x9B << 24 overflows signed int = UB), but an isolated g++ -O2 repro shows both the int-promoted and uint32_t-cast forms produce 0x9BC13AFE. So the magic read works in isolation.
Static analysis of the full path (readUint32 → switch → getFormatVersion(readUint16(...,4))) looks correct.
Root cause not yet isolated — likely a host/optimization or ReadOnlyByteArrayView/AK_FORCE_INLINE interaction specific to the host toolchain. The engine works correctly on-device (the app ships and reads dictionaries fine); this is a host-build-only discrepancy in a test that had never been run in CI.
This issue tracks isolating the real cause (and, if it is the readUint32 signed-shift UB after all, hardening it with explicit uint32_t casts — provably identical on-device, removes UB).
Low priority (no on-device impact), but a good demonstration that the harness reaches code the JVM tests cannot.
Surfaced by the new native host test harness (#78) — the first thing it caught.
Symptom
FormatUtilsTest.TestDetectFormatVersionfails on the host build (Linux, g++ 13,-O2):The test builds a 12-byte big-endian header
[9B C1 3A FE | 00 02 | 00 00 | 00 00 00 00]and expectsdetectFormatVersionto reportVERSION_2; on host it reportsUNKNOWN.What was ruled out
DICTIONARY_MINIMUM_SIZE= 12, buffer is exactly 12 → guard passes.readUint32signed-shift UB: suspected (uint8_tpromotes toint,0x9B << 24overflows signed int = UB), but an isolated g++ -O2 repro shows both the int-promoted anduint32_t-cast forms produce0x9BC13AFE. So the magic read works in isolation.readUint32→switch→getFormatVersion(readUint16(...,4))) looks correct.Root cause not yet isolated — likely a host/optimization or
ReadOnlyByteArrayView/AK_FORCE_INLINEinteraction specific to the host toolchain. The engine works correctly on-device (the app ships and reads dictionaries fine); this is a host-build-only discrepancy in a test that had never been run in CI.Action
ctest -E 'FormatUtilsTest.TestDetectFormatVersion') so the other 65 native tests gate as a blocking net.readUint32signed-shift UB after all, hardening it with explicituint32_tcasts — provably identical on-device, removes UB).Low priority (no on-device impact), but a good demonstration that the harness reaches code the JVM tests cannot.