`ZstdDecompressor` and `LZMADecompressor` raise on repeated `decompress(b'', max_length=0)` calls with output pending
Maintainer thường phản hồi trong vòng 1 ngày
Chưa có ai nhận issue này.
Đánh giá
- Độ khó
- 3/5
- Thời gian dự kiến
- 1-2 ngày
- Mức phù hợp với người mới
- 72/100
- Loại issue
- Lỗi
- Độ rõ ràng
- Đặc tả rõ ràng
- Mức độ hoạt động
- Sôi nổi
- Công nghệ
- python
- Lĩnh vực
- backend, performance
Hướng nghiên cứu
Start with Modules/_zstd/decompressor.c around the ZSTD_decompressStream call described in the issue, then inspect the LZMA decompressor path and the regression test test_max_length_zero_with_pending_output mentioned in PR #159960. Reproduce the repeated empty-input calls with max_length=0 on both backends. Done means both return b'' without an error while output is pending, with existing decompression behavior preserved.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
Bug description
When a compression.zstd.ZstdDecompressor has decompressed output waiting (because an earlier max_length cut it short), calling decompress with max_length=0 works 15 times and fails on the 16th:
>>> from compression import zstd
>>> d = zstd.ZstdDecompressor()
>>> d.decompress(zstd.compress(b"\x00"), max_length=0)
b''
>>> for _ in range(15):
... d.decompress(b"", max_length=0)
...
>>> d.decompress(b"", max_length=0)
Traceback (most recent call last):
File "<python-input-4>", line 1, in <module>
d.decompress(b"", max_length=0)
_zstd.ZstdError: Unable to decompress Zstandard data: Operation made no progress over multiple calls, due to output buffer being full
Every one of those calls is a legitimate "buffer this, give me nothing yet" request, and needs_input is False throughout, so I would expect b'' each time with no error. The decompressor is not actually broken afterwards: a following decompress(b"", -1) still returns b"\x00" with eof set, so this is an error raised on a valid call rather than lost data.
LZMADecompressor fails the same sequence, on the fourth call rather than the sixteenth:
>>> import lzma
>>> d = lzma.LZMADecompressor()
>>> d.decompress(lzma.compress(b"\x00"), max_length=0)
b''
>>> for _ in range(3):
... d.decompress(b"", max_length=0)
...
>>> d.decompress(b"", max_length=0)
Traceback (most recent call last):
File "<python-input-4>", line 1, in <module>
d.decompress(b"", max_length=0)
_lzma.LZMAError: Insufficient buffer space
That is the mechanism described in #160000 (liblzma's LZMA_BUF_ERROR leaking through when the output buffer is empty) showing up with input buffered rather than on a fresh decompressor; I expect the fix for that issue covers it, but it seemed worth recording the second shape since the fresh-decompressor test alone would not catch a regression here. BZ2Decompressor and zlib._ZlibDecompressor return b'' for any number of such calls.
The zstd mechanism: decompress_lock_held calls ZSTD_decompressStream even when max_length is 0, so with a zero-size output buffer: Modules/_zstd/decompressor.c lines 229-233. libzstd counts consecutive ZSTD_decompressStream calls that consume no input and produce no output (ZSTD_NO_FORWARD_PROGRESS_MAX, which is 16) and returns ZSTD_error_noForwardProgress_destFull once the limit is hit, as protection against callers looping forever. The simplest fix is probably to return b'' without calling into libzstd at all when max_length == 0, since there is nothing such a call can do except (with new input) append to the internal input buffer, which happens outside this loop anyway.
Found by running the Hypothesis tests from #159960 under Atheris, with the _zstd module compiled with -fsanitize=fuzzer-no-link. libFuzzer hit it within about twenty seconds, whereas plain Hypothesis had not found it in many runs, because it needs sixteen consecutive max_length=0 values; the zstd reproducer above is the shrunk result. Both backends are now pinned in that PR as test_max_length_zero_with_pending_output under expectedFailure.
CPython versions tested on
CPython main (39bc958bf9b), libzstd 1.5.7, liblzma 5.8.4
Operating systems tested on
Linux
cc @emmatyping
- Ngôn ngữ chính
- Python
- Star
- 77.7k
- Fork
- 38.3k
- Merge trung bình
- 13 giờ 43 phút
- Pull request đã merge (30 ngày)
- 704
Chuẩn bị môi trường
Khởi chạy dev container của dự án ngay trên trình duyệt, bằng tài khoản GitHub của bạn.
- Không có Dockerfile hay tệp Docker Compose
- Có mẫu pull request
- Đọc 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.
Issue khác của python/cpython
-
topic-socket type-bug
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 72/100
python/cpython#160561 · 7 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
tests topic-profiling type-bug
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
python/cpython#160334 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
`iso2022_jp_3` encodes U+9B1D but decodes the result as U+9B1CCó thể đã có người làm @kinqsradio đã nhận hôm nay. Đang mởextension-modules type-bug
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 84/100
Maintainer thường phản hồi trong vòng 1 ngày
-
Remove unused FVS_* macrosĐang mởinterpreter-core type-feature
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 78/100
python/cpython#160109 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
extension-modules type-bug
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 72/100
python/cpython#160001 · 3 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
Tất cả issue của python/cpython
Issue tương tự
-
area/config comp/tools P2 platform/telegram type/bug
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 74/100
NousResearch/hermes-agent#145412 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
[oblt-aw][autodoc] Update docs for security org scaffolding and Docs AI menu permission changesCó thể đã có người làm @github-actions đã nhận hôm nay. Đang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 75/100
Maintainer thường phản hồi trong vòng 1 ngày
-
Community project: hosted MOSS-Image studio with a visual JSON layout builder (no ComfyUI needed)Đang mở
Độ khó 1/5 1-3 giờ Mức phù hợp với người mới 65/100
OpenMOSS/MOSS-Image#27 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 76/100
deepspeedai/DeepSpeed#8925 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 3 ngày
-
external integration integration-submission
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 68/100
langchain-ai/docs#7077 ·
Maintainer thường phản hồi trong vòng 1 ngày