Skip to content

[3.15] gh-160303: Fix bytearray state after a failed del b[:n] (GH-160304) - #161836

Merged
gpshead merged 1 commit into
python:3.15from
miss-islington:backport-35e2c5a-3.15
Nov 11, 2026
Merged

gpshead merged 1 commit into
python:3.15from
miss-islington:backport-35e2c5a-3.15

Conversation

@miss-islington

@miss-islington miss-islington commented Nov 11, 2026 •

Copy link
Copy Markdown
Contributor

After a failed del b[:n], bytearray_setslice_linear() moved ob_start back, but bytearray_resize_storage() had already realigned the data and reset ob_start, so the bytearray then started n bytes before its buffer. The front-delete path now moves ob_start and the size before the shrinking resize and no longer restores anything, so a failed shrink leaves the bytes removed and the larger block in place, raising MemoryError as the non-front path already does. The checks in bytearray_resize_lock_held() are split from a new bytearray_resize_unchecked() so the slice code can call it directly without changing other callers, and the non-front failure path now writes the trailing null byte it was missing.

Fixes #160303

ANT-2026-QRZ6IDTC

(cherry picked from commit 35e2c5a)

Co-authored-by: Gregory P. Smith 68491+gpshead@users.noreply.github.com

…GH-160304)

* pythongh-160303: Fix bytearray state after a failed del b[:n]

When shrinking the storage of a bytearray which has a logical offset,
allocate the new buffer before modifying the object, so that
bytearray_setslice_linear() can restore ob_start if the allocation fails.

* pythongh-160303: Keep ob_start instead of allocating in del b[:n]

Move ob_start and the size before the shrinking resize, so a failed
shrink leaves the bytes removed and the larger block in place, as the
non-front path already does.  Split the checks out of
bytearray_resize_lock_held() so the slice code can resize directly.
Move the tests into test_resize_error.

* pythongh-160303: Test failed shrinks not at the front; narrow the unchecked resize

Only the front path of bytearray_setslice_linear() calls
bytearray_resize_unchecked(): it has already advanced ob_start and reduced
the size, so bytearray_resize_lock_held() would return early without
releasing memory. Other slices go through bytearray_resize_lock_held()
again and keep the failure fixup to themselves.

test_resize_error now also covers slices in the middle and at the end,
and checks the null byte after the data with float().
(cherry picked from commit 35e2c5abc940e616d84542d32bef80c4ae1faf2c)

Co-authored-by: Gregory P. Smith <68491+gpshead@users.noreply.github.com>
@bedevere-app bedevere-app Bot added the sprint label Nov 11, 2026
@github-project-automation github-project-automation Bot moved this to Todo in Sprint Nov 11, 2026
@gpshead
gpshead enabled auto-merge (squash) November 11, 2026 22:55
@gpshead gpshead self-assigned this Nov 11, 2026
@gpshead
gpshead merged commit 9a52edb into python:3.15 Nov 11, 2026
57 checks passed
@github-project-automation github-project-automation Bot moved this from Todo to Done in Sprint Nov 11, 2026
@miss-islington
miss-islington deleted the backport-35e2c5a-3.15 branch November 11, 2026 23:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

2 participants