Skip to content

samples: expand SuperBomb protocol coverage + recursion-shape probes - #227

Merged
devdanzin merged 1 commit into
mainfrom
rustpython-hostile-samples
Jul 19, 2026
Merged

samples: expand SuperBomb protocol coverage + recursion-shape probes#227
devdanzin merged 1 commit into
mainfrom
rustpython-hostile-samples

Conversation

@devdanzin

Copy link
Copy Markdown
Owner

Two low-effort additions to the hostile-object corpus that widen the surface alternative interpreters (RustPython, PyPy) crash on — the dominant RustPython bug class is a native .unwrap()/panic! on a Python-level callback. Independent of #226 (touches only samples/ + the golden).

SuperBomb (_SUPERBOMB_DUNDERS, 65 → 87 slots)

  • reflected binary ops: __rmod__/__rdivmod__/__rpow__/__rtruediv__/__rfloordiv__/__rmatmul__/__rand__/__ror__/__rxor__/__rlshift__/__rrshift__
  • in-place ops: __imul__/__isub__/__imod__/__ipow__/__itruediv__/__ifloordiv__/__imatmul__/__iand__/__ior__/__ixor__/__ilshift__/__irshift__
  • buffer protocol (PEP 688): __buffer__/__release_buffer__ — a raising __buffer__ detonates native buffer acquisition (memoryview(...), struct/array), an error path C/Rust code often skips.

Each still raises the fusil superbomb via <name> message already covered by the stdout ignore-regex, so no new suppression is needed.

Recursion-shape probes (tricky_objects)

For the unguarded-native-recursion crash class (RustPython #2796):

  • a pair of _TrickyRecur objects whose hash/eq/getitem/iter/repr/call each re-enter the same protocol on a partner object (mutual cross-object recursion, harder to short-circuit than self-recursion);
  • a deep list[list[...T...]] generic-alias bottomed on a TypeVar so the parameter walk actually recurses (RustPython segfaulted in genericalias::make_parameters_from_slice).

CPython raises RecursionError; construction is cheap (recursion fires only when a protocol is exercised). These are corpus building blocks — simple recursion is guarded by RustPython standalone; the segfaults need fusil's combined object graphs.

Flaky-test fix

test_failing_iterator_raises_during_iteration was ~8% flaky on any tree: FailingIterator draws from the bomb pool (which includes StopIteration), and raise StopIteration in a plain iterator's __next__ ends list() cleanly — no exception escapes, so assertRaises fails. The seeded RNG made the new dunder draws surface it reliably. Fixed by pinning exc=ValueError so the test verifies its intent deterministically.

Testing

Golden regenerated (samples are spliced verbatim into every script). ruff check + ruff format --check clean; full suite (1145 tests) green and stable across repeated runs.

🤖 Generated with Claude Code

Two low-effort additions to the hostile-object corpus that widen the surface
alternative interpreters (RustPython, PyPy) crash on -- the dominant RustPython
bug class is a native .unwrap()/panic! on a Python-level callback.

SuperBomb (_SUPERBOMB_DUNDERS, 65 -> 87 slots): add the reflected binary ops
(__rmod__/__rdivmod__/__rpow__/__rtruediv__/__rfloordiv__/__rmatmul__/__rand__/
__ror__/__rxor__/__rlshift__/__rrshift__), the in-place ops (__imul__/__isub__/
__imod__/__ipow__/__itruediv__/__ifloordiv__/__imatmul__/__iand__/__ior__/__ixor__/
__ilshift__/__irshift__), and the PEP 688 buffer protocol (__buffer__/
__release_buffer__ -- a raising __buffer__ detonates native buffer acquisition,
an error path C/Rust code often skips). Each still raises the "fusil superbomb via
<name>" message already covered by the ignore-regex.

tricky_objects: add recursion-shape probes for the unguarded-native-recursion crash
class (RustPython #2796): a pair of _TrickyRecur objects whose hash/eq/getitem/iter/
repr/call each re-enter the SAME protocol on a PARTNER object (mutual cross-object
recursion, harder to short-circuit than self-recursion), and a deep list[list[...T...]]
generic-alias bottomed on a TypeVar so the parameter walk actually recurses
(RustPython segfaulted in genericalias::make_parameters_from_slice). CPython raises
RecursionError; construction is cheap (recursion fires only when a protocol is
exercised). These are corpus building blocks -- simple recursion is guarded by
RustPython standalone; the segfaults need fusil's combined object graphs.

Also fixes a pre-existing ~8% flake in test_failing_iterator_raises_during_iteration:
FailingIterator draws from the bomb pool, which includes StopIteration, and `raise
StopIteration` in a plain iterator's __next__ ends list() cleanly (no exception
escapes) -- pin exc=ValueError so the test verifies its intent deterministically.
(The seeded RNG made the new dunder draws surface this reliably.)

Golden regenerated (samples are spliced verbatim). ruff + full suite green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@devdanzin
devdanzin merged commit cc2e6a1 into main Jul 19, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant