Skip to content

gh-154566: Fix array.byteswap() corrupting 'Zd' arrays with more than one element - #154567

Merged
vstinner merged 3 commits into
python:mainfrom
PhysicistJohn:gh-154566-byteswap-zd-fix
Aug 13, 2026
Merged

gh-154566: Fix array.byteswap() corrupting 'Zd' arrays with more than one element#154567
vstinner merged 3 commits into
python:mainfrom
PhysicistJohn:gh-154566-byteswap-zd-fix

Conversation

@PhysicistJohn

Copy link
Copy Markdown
Contributor

array.array('Zd', ...).byteswap() scrambled every item after the first
because the 16-byte-item loop advanced the pointer by 8 bytes instead of
16. Fixes gh-154566.

Adds a regression test that checks the actual byte-level result of a
single byteswap() call (the existing test only checked a double-call
round-trip, which passes even under the bug since the corruption happens
to be self-canceling on the second call).

…e than one element

The 16-byte-item loop in array_array_byteswap_impl() advanced the
buffer pointer by only 8 bytes per iteration, even though each
iteration swaps a full 16-byte item (two independent 8-byte halves
for the real/imaginary double components). This caused every item
after the first to overlap the previous iteration's byte window and
come out scrambled.

A single byteswap() call gave wrong bytes for the second item onward.
Calling byteswap() twice happened to round-trip back to the original
value (the corruption is self-canceling under double application),
which is why the existing test suite -- which only checked a
double-call round-trip -- didn't catch it. Added a regression test
that checks the actual byte-level result of a single call.
@python-cla-bot

This comment was marked as resolved.

Comment thread Misc/NEWS.d/next/Library/2026-07-23-20-00-00.gh-issue-154566.byteswap-zd.rst Outdated
Comment thread Lib/test/test_array.py Outdated
Comment thread Lib/test/test_array.py Outdated
@skirpichev skirpichev added the needs backport to 3.15 pre-release feature fixes, bugs and security fixes label Jul 24, 2026
@skirpichev
skirpichev requested a review from vstinner July 24, 2026 08:31
@vstinner

Copy link
Copy Markdown
Member

skirpichev requested a review from vstinner 1 hour ago

I will wait until @PhysicistJohn applies your suggestions before reviewing this change.

…l test

Per skirpichev's review on pythonGH-154567:
- Trim the NEWS entry to his suggested wording.
- Move test_byteswap_single_call_result from ComplexDoubleTest into the
  shared CFPTest base class, using self.example and computing
  itemsize/half dynamically instead of hardcoded values, so it now
  covers both ComplexFloatTest ('Zf') and ComplexDoubleTest ('Zd')
  rather than just one.
@PhysicistJohn

Copy link
Copy Markdown
Contributor Author

Thanks for the review! Applied all three: trimmed the NEWS wording per
your suggestion, and moved the single-call test into CFPTest using
self.example with a generic itemsize/half calculation, so it now
covers both 'Zf' and 'Zd' instead of being hardcoded to one.

@vstinner vstinner left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@vstinner

Copy link
Copy Markdown
Member

A CI job failed for an unknown reason:

Check labels / Unresolved review (pull_request): Cancelled after 15m

I clicked on [Update branch] to attempt to repair the CI.

@vstinner
vstinner merged commit 46c355f into python:main Aug 13, 2026
54 checks passed
@miss-islington-app

Copy link
Copy Markdown

Thanks @PhysicistJohn for the PR, and @vstinner for merging it 🌮🎉.. I'm working now to backport this PR to: 3.15.
🐍🍒⛏🤖 I'm not a witch! I'm not a witch!

@bedevere-app

bedevere-app Bot commented Aug 13, 2026

Copy link
Copy Markdown

GH-155756 is a backport of this pull request to the 3.15 branch.

@bedevere-app bedevere-app Bot removed the needs backport to 3.15 pre-release feature fixes, bugs and security fixes label Aug 13, 2026
@vstinner

Copy link
Copy Markdown
Member

Merged, thanks for the fix.

hugovk pushed a commit that referenced this pull request Aug 14, 2026
…re than one element (GH-154567) (#155756)

gh-154566: Fix array.byteswap() corrupting 'Zd' arrays with more than one element (GH-154567)

Fix array.array.byteswap() corrupting data for 'Zd' (complex
double) arrays with more than one element: the 16-byte item loop advanced
the buffer pointer by only 8 bytes per iteration, causing items after the
first to be scrambled.
(cherry picked from commit 46c355f)

Co-authored-by: PhysicistJohn <54456354+PhysicistJohn@users.noreply.github.com>
Co-authored-by: Victor Stinner <vstinner@python.org>
mbeijen pushed a commit to mbeijen/cpython that referenced this pull request Aug 14, 2026
…e than one element (python#154567)

Fix array.array.byteswap() corrupting data for 'Zd' (complex
double) arrays with more than one element: the 16-byte item loop advanced
the buffer pointer by only 8 bytes per iteration, causing items after the
first to be scrambled.

Co-authored-by: Victor Stinner <vstinner@python.org>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

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

3 participants