mirror of
https://github.com/RustPython/RustPython.git
synced 2026-10-29 03:04:38 +08:00
* zlib: clear unconsumed_tail when a bounded decompress reaches stream end When a max_length-bounded Decompress.decompress() call reached the end of the stream, the bytes after the stream went to unused_data, but unconsumed_tail kept the previous call's tail, including input the call had already consumed. A later flush() then moved those stale bytes into unused_data. Empty unconsumed_tail at end of stream, as CPython's save_unconsumed_input() does since gh-158169. CPython releases before that change report the bytes after the stream in unconsumed_tail, so the snippet accepts either value when it runs under CPython. Fixes #8906 Assisted-by: Claude Code:claude-opus-5-5 * zlib: bind the unconsumed input with an if expression Choose between the empty slice and the rest of the input in one expression instead of reassigning a mutable binding. Assisted-by: Claude Code:claude-opus-5-5 * zlib: accept both valid tails in the snippet on every implementation The snippet no longer branches on sys.implementation. RustPython and CPython after gh-158169 give an empty tail; CPython before it gives the bytes after the stream. The stale tail of gh-8906 fails either way. Assisted-by: Claude Code:claude-opus-5-5
82 lines
3.3 KiB
Python
82 lines
3.3 KiB
Python
import zlib
|
|
|
|
from testutils import assert_raises
|
|
|
|
# checksum functions
|
|
assert zlib.crc32(b"123") == 2286445522
|
|
assert zlib.crc32(b"123", 1) == 2307525093
|
|
assert zlib.crc32(b"123", 2) == 2345449404
|
|
assert zlib.crc32(b"123", 3) == 2316230027
|
|
assert zlib.crc32(b"123", 4) == 2403453710
|
|
assert zlib.crc32(b"123", 5) == 2390991161
|
|
assert zlib.crc32(b"123", 6) == 2361728864
|
|
assert zlib.crc32(b"123", -123) == 3515918521
|
|
assert zlib.crc32(b"123", -122) == 3554023136
|
|
assert zlib.crc32(b"123", -121) == 3524558039
|
|
assert zlib.crc32(b"123", -120) == 3645389802
|
|
assert zlib.crc32(b"123", -119) == 3632943581
|
|
assert zlib.crc32(b"123", -118) == 3670863748
|
|
assert zlib.crc32(b"123") == zlib.crc32(b"123", 0)
|
|
|
|
assert zlib.adler32(b"456") == 20906144
|
|
assert zlib.adler32(b"456", 1) == 20906144
|
|
assert zlib.adler32(b"456", 2) == 21102753
|
|
assert zlib.adler32(b"456", 3) == 21299362
|
|
assert zlib.adler32(b"456", 4) == 21495971
|
|
assert zlib.adler32(b"456", 5) == 21692580
|
|
assert zlib.adler32(b"456", 6) == 21889189
|
|
assert zlib.adler32(b"456", -123) == 393267
|
|
assert zlib.adler32(b"456", -122) == 589876
|
|
assert zlib.adler32(b"456", -121) == 786485
|
|
assert zlib.adler32(b"456", -120) == 983094
|
|
assert zlib.adler32(b"456", -119) == 1179703
|
|
assert zlib.adler32(b"456", -118) == 1376312
|
|
assert zlib.adler32(b"456") == zlib.adler32(b"456", 1)
|
|
|
|
# compression
|
|
lorem = bytes("Lorem ipsum dolor sit amet", "utf-8")
|
|
|
|
compressed_lorem_list = [
|
|
b"x\x01\x01\x1a\x00\xe5\xffLorem ipsum dolor sit amet\x83\xd5\t\xc5",
|
|
b"x\x01\xf3\xc9/J\xcdU\xc8,(.\xcdUH\xc9\xcf\xc9/R(\xce,QH\xccM-\x01\x00\x83\xd5\t\xc5",
|
|
b"x^\xf3\xc9/J\xcdU\xc8,(.\xcdUH\xc9\xcf\xc9/R(\xce,QH\xccM-\x01\x00\x83\xd5\t\xc5",
|
|
b"x^\xf3\xc9/J\xcdU\xc8,(.\xcdUH\xc9\xcf\xc9/R(\xce,QH\xccM-\x01\x00\x83\xd5\t\xc5",
|
|
b"x^\xf3\xc9/J\xcdU\xc8,(.\xcdUH\xc9\xcf\xc9/R(\xce,QH\xccM-\x01\x00\x83\xd5\t\xc5",
|
|
b"x^\xf3\xc9/J\xcdU\xc8,(.\xcdUH\xc9\xcf\xc9/R(\xce,QH\xccM-\x01\x00\x83\xd5\t\xc5",
|
|
b"x\x9c\xf3\xc9/J\xcdU\xc8,(.\xcdUH\xc9\xcf\xc9/R(\xce,QH\xccM-\x01\x00\x83\xd5\t\xc5",
|
|
b"x\xda\xf3\xc9/J\xcdU\xc8,(.\xcdUH\xc9\xcf\xc9/R(\xce,QH\xccM-\x01\x00\x83\xd5\t\xc5",
|
|
b"x\xda\xf3\xc9/J\xcdU\xc8,(.\xcdUH\xc9\xcf\xc9/R(\xce,QH\xccM-\x01\x00\x83\xd5\t\xc5",
|
|
b"x\xda\xf3\xc9/J\xcdU\xc8,(.\xcdUH\xc9\xcf\xc9/R(\xce,QH\xccM-\x01\x00\x83\xd5\t\xc5",
|
|
]
|
|
|
|
for level, expected in enumerate(compressed_lorem_list):
|
|
actual = zlib.compress(lorem, level)
|
|
assert actual == expected
|
|
|
|
# default level
|
|
assert zlib.compress(lorem) == zlib.compress(lorem, -1) == zlib.compress(lorem, 6)
|
|
|
|
# decompression
|
|
for text in compressed_lorem_list:
|
|
assert zlib.decompress(text) == lorem
|
|
|
|
assert_raises(zlib.error, lambda: zlib.compress(b"123", -40))
|
|
assert_raises(zlib.error, lambda: zlib.compress(b"123", 10))
|
|
|
|
# A max_length-bounded call that reaches the end of the stream keeps no
|
|
# stale input in unconsumed_tail (gh-8906). The tail is empty, or, as in
|
|
# CPython before gh-158169, the bytes after the stream.
|
|
source = b"x" * 20000
|
|
d = zlib.decompressobj()
|
|
out = d.decompress(zlib.compress(source) + b"NEXT", 100)
|
|
assert not d.eof
|
|
out += d.decompress(d.unconsumed_tail, 100000)
|
|
assert d.eof
|
|
assert out == source
|
|
assert d.unused_data == b"NEXT"
|
|
tail = d.unconsumed_tail
|
|
assert tail in (b"", b"NEXT")
|
|
assert d.flush() == b""
|
|
assert d.unconsumed_tail == tail
|
|
assert d.unused_data == b"NEXT" + tail
|