Quality cleanup: no shared-gadget mutation, faster chain build, style#18
Merged
Conversation
- operation: filter_gadgets annotates a copy (dataclasses.replace) instead of mutating the shared input Gadget objects, removing the cross-operation aliasing hazard; replace() also gives each match fresh side-effect sets - ropchain: _build_per_comb_gadgets sorts each operation's gadget list once and memoises the filter/prune result per (step, dst, src), avoiding the previous O(combinations x gadgets) re-filter+re-sort - arch: add ArchitectureSingleton.reset() to encapsulate the global state (used by the test fixtures instead of poking the private attribute) - style: isinstance() instead of type() == ... (operation, yaml parser); move imports above module constants in gadfinder; pin lower bounds for pyelftools/pyyaml/macholib in requirements.txt Tests: add filter_gadgets no-mutation regression and a ropchain search suite (concrete, two-step, generic-register and not-found cases) to guard the chain-build refactor. 59 tests pass. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Resolves the maintainability items raised in the post-merge code review (no behaviour change for users; output is identical).
No shared-
GadgetmutationOperation.filter_gadgetspreviously wrote.op/.dst/.srcand side effects onto the inputGadgetobjects. Because the same gadget list is filtered for several operations of a chain, the last match could overwrite annotations on a shared object. It now annotates a copy viadataclasses.replace, which also gives each match fresh side-effect sets.Faster ROP-chain construction
_build_per_comb_gadgetsused to re-filter, re-sort and re-prune the full per-operation gadget lists for every register combination — O(combinations × gadgets). It now:(step, req_dst, req_src), since different combinations frequently request the same concrete registers for a step.Output is unchanged (same filtering, sort order and pruning).
Encapsulation & style
ArchitectureSingleton.reset()added to clear the global state cleanly (used by the test fixtures instead of poking the private attribute).isinstance(...)instead oftype(...) == ...(operation.py,yaml_parser.py).gadfinder.py.pyelftools/pyyaml/macholibinrequirements.txt.Tests
filter_gadgetsno-mutation regression test.test_ropchain.py(concrete, two-step, generic-register and not-found cases) to guard the chain-build refactor./bin/lsand a 32-bit busybox.🤖 Generated with Claude Code