Open InspectorBoat opened 10 months ago
Pages are word-aligned. If reads are word-aligned too, there will be no segfaults. Of course, flexible int size access would require more masks and shifts but it is a price worth paying to prevent segfaults.
@slonik-az That may be implemented as an optimization on specific platforms then, like #17161.
Zig Version
0.12.0-dev.1486+234693bcb
Steps to Reproduce and Observed Behavior
PackedIntIo currently works like this:
(from packed_int_array.zig)
The
MinIo
andMaxIo
container types are defined as follows:This code makes the false assumption that reading
*align(1) MinIo
or*align(1) MaxIo
only reads@bitSizeOf(MinIo/MaxIo) / 8
bytes:However, (at least on x86-64) accessing an exotically sized integer actually accesses the backing naturally-sized integer. For example, reading
*u24
will read a full dword. (relevant issue?). For a PackedIntIo(u24), the above code assumes that if reading a*align(1) MaxIo
would cause an out of bounds access, reading*align(1) MinIo
must be safe. However, both code paths will read a full 4 bytes, which can cause a segfault when crossing page boundaries. This can be observed with:Expected Behavior
A possible fix:
However, I don't think this code would be correct. It requires that
MinIo
These conditions are true under the incorrect assumptions that reading a *uX actually only reads X bits, and that
MaxIo
is at most only 1 byte larger thanMinIo
. I suspect they no longer hold whenMaxIo
can be 1, 2, 4, or 8 bytes larger. It would be better to just use the alternate function,getBitsContainerless
regardless of the size ofMinIo
. Sorry if I got anything wrong about the semantics, I'm still quite new to all this.