Commit b506d27
committed
Fix misaligned memory access in
After DCT decoding, `LossyDctDecoder_execute()` expands FLOAT-type channels
from their intermediate HALF (16-bit) XDR representation back to FLOAT (32-bit)
XDR in place. The expansion was done by casting `_rows[y]` (a `uint8_t *`)
directly to `float *` and `uint16_t *`, then reading and writing through those
typed pointers.
Because row buffers are assigned by advancing a byte pointer with no alignment
padding (`outBufferEnd += chan->width * chan->bytes_per_element` in
`internal_dwa_compressor.h`), a FLOAT channel that follows a HALF channel of
odd width receives a `_rows[y]` pointer that is 2-byte aligned but not 4-byte
aligned. Dereferencing a `float *` cast from such a pointer is undefined
behavior under the C standard:
- On ARM, RISC-V, and MIPS (strict alignment) this crashes immediately.
- On x86 it is silently tolerated at the hardware level but remains UB:
auto-vectorizing compilers (SSE/AVX) may assume aligned access and generate
incorrect code.
- UBSan reports: `store to misaligned address ... for type 'float', which
requires 4 byte alignment` at `internal_dwa_decoder.h:749`.
Fix: replace the cast-and-dereference pattern with the `unaligned_load16` /
`memcpy` / `unaligned_store32` helpers already used throughout the rest of
OpenEXRCore (`internal_xdr.h`, `unpack.c`, `pack.c`, `internal_pxr24.c`).
These helpers use `memcpy` internally, which the C standard guarantees is safe
for unaligned addresses and which compilers compile to a single load/store
instruction on architectures that support it.
The byte-order handling is preserved correctly:
- `unaligned_load16` reads 2 bytes via `memcpy` and applies `one_to_native16`
(XDR → native), returning a native-endian HALF value.
- `half_to_float` converts native HALF → native float.
- `memcpy(&bits, &f, 4)` reinterprets the float's bit pattern as `uint32_t`
without numeric conversion (the correct type-pun idiom in C).
- `unaligned_store32` applies `one_from_native32` (native → XDR) and writes
4 bytes via `memcpy`, storing the result in XDR float format.
Made-with: Cursor
Signed-off-by: Cary Phillips <cary@ilm.com>LossyDctDecoder_execute HALF→FLOAT expansion1 parent c48f23c commit b506d27
1 file changed
Lines changed: 6 additions & 4 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
741 | 741 | | |
742 | 742 | | |
743 | 743 | | |
744 | | - | |
745 | | - | |
| 744 | + | |
746 | 745 | | |
747 | 746 | | |
748 | 747 | | |
749 | | - | |
750 | | - | |
| 748 | + | |
| 749 | + | |
| 750 | + | |
| 751 | + | |
| 752 | + | |
751 | 753 | | |
752 | 754 | | |
753 | 755 | | |
| |||
0 commit comments