Thanks to visit codestin.com
Credit goes to github.com

Skip to content

array._array_reconstructor() ignores requested byte order for float16 (IEEE_754_FLOAT16_LE/BE) #154568

Description

@PhysicistJohn

Bug description:

array._array_reconstructor() (the internal function used to unpickle
array.array objects) ignores the requested byte order when decoding
half-precision floats. The slow-path decoder for
IEEE_754_FLOAT16_LE/IEEE_754_FLOAT16_BE (Modules/arraymodule.c)
computes the byte-order flag by comparing mformat_code against
IEEE_754_FLOAT_LE (the 32-bit float constant, value 14) instead of
IEEE_754_FLOAT16_LE (value 26). Since the float16 mformat codes are
26/27, this comparison is always false, so the decoder always treats
the input as big-endian, regardless of which byte order was actually
requested.

Reproducer (using typecode 'd' to deterministically force the slow
/converting decode path regardless of the test machine's native
endianness):

import array, struct
le_bytes = struct.pack('<e', 1.0)
result = array._array_reconstructor(array.array, 'd', 26, le_bytes)  # 26 = IEEE_754_FLOAT16_LE
print(result.tolist())  # [3.5762786865234375e-06] -- should be [1.0]

The sibling cases in the same switch statement (IEEE_754_FLOAT_LE/BE,
IEEE_754_DOUBLE_LE/BE, the complex variants) all correctly compare
mformat_code against their own constant; the float16 case is the only
one comparing against the wrong constant.

Real-world impact: pickling an array('e', ...) (half-precision float
array) on one machine and unpickling it on a machine with different
native endianness silently produces wrong values instead of either the
correct values or an error.

CPython versions tested on:

CPython main branch (3.16.0a0)

Operating systems tested on:

macOS (arm64)

Linked PRs

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    extension-modulesC modules in the Modules dirtype-bugAn unexpected behavior, bug, or error

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions