test(assets): two guards the mutant survey found missing (red)
Written after walking the five mutants the order names against the eval as committed. Two of them SURVIVED it, which makes them holes in the eval and not in the code that does not exist yet. 1. "the format is read from the file extension instead of the bytes" survived, because every image in the fixture is named after what it is: a `.bmp` maps to image/bmp either way and a `.tiff` to image/tiff either way, so the fixture could not tell a sniffed type from a claimed one. A BMP named `graphics/figur.png` can. Red today: `image/bmp` != `image/png`. 2. "the ceiling is checked after decoding instead of before" survived because the guard only asserted that the refusal happens, and `encode_png`'s own `check_size` refuses too -- one frame later, after the memory is spent. The guard already measured the peak; what it could not do was measure it affordably, because a 50 000 x 50 000 frame is 2.5 GB. At 7 000 x 7 000 the declaration is still over the 40 MP bound and the unbounded frame is 49 MB -- measurable, and two orders of magnitude over the 4 MB the guard allows. Nine of thirteen guards are now red on their claim; the four green ones state properties that already hold. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
fea04355b5
commit
9e99bb2cec
1 changed files with 22 additions and 1 deletions
|
|
@ -393,7 +393,13 @@ def test_a_bmp_declaring_a_huge_size_is_refused_before_it_is_decoded() -> None:
|
|||
"""Eval point 4. The bound is on the DECLARATION, paid before the pixels."""
|
||||
import tracemalloc
|
||||
|
||||
bomb = bmp_rle8(50_000, 50_000, PALETTE, bytes([0xFF, 0x01] * 64))
|
||||
# 49 MP, just over the package's 40 MP bound. Deliberately NOT 50 000 x
|
||||
# 50 000: the guard has to stay able to tell "refused before the decode"
|
||||
# from "refused after it", and measuring the second costs a frame of the
|
||||
# declared size. At 7 000 x 7 000 that frame is 49 MB -- affordable to
|
||||
# measure, and two orders of magnitude over the 4 MB this asserts.
|
||||
bomb = bmp_rle8(7_000, 7_000, PALETTE, bytes([0xFF, 0x01] * 64))
|
||||
assert 7_000 * 7_000 > 40_000_000
|
||||
assert len(bomb) < 4096, len(bomb)
|
||||
tracemalloc.start()
|
||||
try:
|
||||
|
|
@ -434,6 +440,21 @@ def test_an_rle_stream_longer_than_its_declared_image_costs_the_declaration() ->
|
|||
assert peak < 16 * 1024 * 1024, peak
|
||||
|
||||
|
||||
def test_a_bmp_whose_name_claims_png_is_still_converted() -> None:
|
||||
"""The type is read off the BYTES. A rule that trusted the extension would
|
||||
carry this file unchanged and call it viewable, and every structural check
|
||||
downstream would agree with it -- the count, the suffix and the pointer.
|
||||
|
||||
The R761 delivery is why this is not hypothetical: its graphics directory
|
||||
holds `.bmp`, `.jpg` and `.png` side by side and the document's own
|
||||
`xlink:href` values are whatever the publisher's tool wrote.
|
||||
"""
|
||||
image = read_image(bmp_rle8(8, 4, PALETTE, RLE8_STREAM), name="graphics/figur.png")
|
||||
assert image.media_type == "image/png"
|
||||
assert image.suffix == ".png"
|
||||
assert decode_rgb(image.data) == ((8, 4), expected_rgb())
|
||||
|
||||
|
||||
# --- 5. the known-positive: what is already viewable does not move ----------
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue