gh-141311: Avoid assertion in BytesIO readinto#141333
gh-141311: Avoid assertion in BytesIO readinto#141333serhiy-storchaka merged 9 commits intopython:mainfrom
Conversation
Account for when self->pos is equal to PY_SSIZE_T_MAX. The length of read was correctly set to zero but the asserts assumed self->pos couldn't reach PY_SSIZE_T_MAX. Return early to avoid edge cases.
Misc/NEWS.d/next/Library/2025-11-09-18-55-13.gh-issue-141311.qZ3swc.rst
Outdated
Show resolved
Hide resolved
For `read_bytes_lock_held` the `size` parameter is always set to 0 by calling code currently if self->pos > self->string_size. I added a range check for self->pos as an extra safety as codepaths chagne but can remove if it's too much. `write_bytes_lock_held`: `endpos` is a `size_t` so can hold `2 * PY_SSIZE_T_MAX`. Value is bounds checked in `resize_buffer_lock_held`. A number of cases use `scan_eol_lock_held` to move forward. That has code which checks `self->pos >= self->string_size` and returns `0`. Callsites all seem to handle that correctly.
|
I audited the codepaths which did For
A number of cases use |
|
Thanks @cmaloney for the PR, and @serhiy-storchaka for merging it 🌮🎉.. I'm working now to backport this PR to: 3.13. |
|
Thanks @cmaloney for the PR, and @serhiy-storchaka for merging it 🌮🎉.. I'm working now to backport this PR to: 3.14. |
|
Sorry, @cmaloney and @serhiy-storchaka, I could not cleanly backport this to |
Fix error in assertion which causes failure if pos is equal to PY_SSIZE_T_MAX. Fix undefined behavior in read() and readinto() if pos is larger that the size of the underlying buffer. (cherry picked from commit 7d54374) Co-authored-by: Cody Maloney <cmaloney@users.noreply.github.com>
|
GH-141457 is a backport of this pull request to the 3.14 branch. |
|
@cmaloney, could you please create a backport to 3.13 manually? |
|
GH-141478 is a backport of this pull request to the 3.13 branch. |
Fix error in assertion which causes failure if pos is equal to PY_SSIZE_T_MAX. Fix undefined behavior in read() and readinto() if pos is larger that the size of the underlying buffer.
Account for when self->pos is equal to PY_SSIZE_T_MAX. The length of read was correctly set to zero but the asserts assumed self->pos couldn't reach PY_SSIZE_T_MAX. Return early to avoid edge cases.
_io_BytesIO_readinto_impl: Assertion 'self->pos + len < PY_SSIZE_T_MAX' failed.#141311