gh-154566: Fix array.byteswap() corrupting 'Zd' arrays with more than one element - #154567
Conversation
…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.
This comment was marked as resolved.
This comment was marked as resolved.
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.
|
Thanks for the review! Applied all three: trimmed the NEWS wording per |
|
A CI job failed for an unknown reason:
I clicked on [Update branch] to attempt to repair the CI. |
|
Thanks @PhysicistJohn for the PR, and @vstinner for merging it 🌮🎉.. I'm working now to backport this PR to: 3.15. |
|
GH-155756 is a backport of this pull request to the 3.15 branch. |
|
Merged, thanks for the fix. |
…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>
…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>
array.array('Zd', ...).byteswap()scrambled every item after the firstbecause 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-callround-trip, which passes even under the bug since the corruption happens
to be self-canceling on the second call).