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

Skip to content

array.byteswap() corrupts data for 'Zd' (complex double) arrays with more than one element #154566

Description

@PhysicistJohn

Bug description:

array.array('Zd', ...).byteswap() produces incorrect data for arrays
with more than one element. The 16-byte-item loop in array_array_byteswap_impl
(Modules/arraymodule.c) advances the buffer pointer by only 8 bytes per
iteration even though each iteration manually swaps a full 16-byte item
(two independent 8-byte halves, for the real/imaginary double components).
This causes every item after the first to overlap the previous iteration's
byte window and come out scrambled.

Reproducer:

import array
a = array.array('Zd', [1+2j, 3+4j])
raw_before = a.tobytes()
a.byteswap()
raw_after = a.tobytes()

expected = bytearray()
for i in range(0, len(raw_before), 8):
    expected += raw_before[i:i+8][::-1]

print(bytes(expected) == raw_after)  # False -- should be True

A single byteswap() call gives the wrong bytes for the second item
onward. Calling byteswap() twice happens to round-trip back to the
original value (the corruption is self-canceling under double
application), which is why the existing test suite (test_byteswap in
Lib/test/test_array.py, which only checks a double-call round-trip)
doesn't catch it.

The sibling cases in the same switch statement (case 4:, case 8:)
correctly advance the pointer by the item's own size (4, 8 bytes); the
case 16: block is the only one where the increment doesn't match the
16 bytes actually touched in the loop body.

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