`_pyio.BufferedReader.readinto()` can raise `ValueError` after partially filling the destination
Chưa có ai nhận issue này.
- Ngôn ngữ chính
- Python
- Star
- 77.2k
- Fork
- 35.9k
- Chỉ số merge pull request
- Chỉ số pull request đang chờ
Mô tả
Bug report
Bug description:
The pure Python implementation of BufferedReader.readinto() can raise ValueError for a valid writable buffer after partially modifying it.
import io
import _pyio
for module in (io, _pyio):
reader = module.BufferedReader(module.BytesIO(b"abcd"), buffer_size=2)
assert reader.read(1) == b"a"
destination = bytearray(2)
try:
result = reader.readinto(destination)
except ValueError as error:
result = f"{type(error).__name__}: {error}"
print(module.__name__, result, destination, reader.read())
Current output on main:
io 2 bytearray(b'bc') b'd'
_pyio ValueError: memoryview assignment: lvalue and rvalue have different structures bytearray(b'b\x00') b'cd'
_pyio should match io: return 2, fill the destination with b"bc", and leave b"d" unread. readinto() first partially fills the destination with data from its internal buffer, then refills that buffer with more data than fits in the remaining space. It then raises ValueError. Because the destination has already been modified and the stream has advanced when the exception is raised, the caller receives no byte count and cannot safely retry on a non-seekable stream.
_pyio.BufferedRandom.readinto() and _pyio.BufferedRWPair.readinto() are also affected because they use the same reader path.
I am working on a PR with a regression test shared by the C and pure Python implementations.
CPython versions tested on:
CPython main branch
Operating systems tested on:
Linux
Linked PRs
- gh-155075
Hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Hướng nghiên cứu
Bắt đầu tại entry point _pyio.BufferedReader.readinto() và chạy reproducer từ issue, so sánh với io.BufferedReader.readinto(). Được xem là hoàn tất khi đường dẫn Python thuần trả về 2, điền đích bằng b"bc", để b"d" chưa được đọc và bao quát hành vi hồi quy dùng chung được mô tả cho BufferedRandom và BufferedRWPair.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Đánh giá
- Công nghệ
- python
- Lĩnh vực
- backend
- Loại issue
- Lỗi
- Độ khó
- 3/5
- Thời gian dự kiến
- 1-2 ngày
- Mức độ hoạt động
- Đình trệ
- Độ rõ ràng
- Đặc tả rõ ràng
- Mức phù hợp với người mới
- 25/100