Conversation
Signed-off-by: Eloïse Brocas <ebrocas@quarkslab.com>
Signed-off-by: Eloïse Brocas <ebrocas@quarkslab.com>
Signed-off-by: Eloïse Brocas <ebrocas@quarkslab.com>
Signed-off-by: Eloïse Brocas <ebrocas@quarkslab.com>
Signed-off-by: Eloïse Brocas <ebrocas@quarkslab.com>
Signed-off-by: Eloïse Brocas <ebrocas@quarkslab.com>
Signed-off-by: Eloïse Brocas <ebrocas@quarkslab.com>
Signed-off-by: Eloïse Brocas <ebrocas@quarkslab.com>
Signed-off-by: Eloïse Brocas <ebrocas@quarkslab.com>
Signed-off-by: Eloïse Brocas <ebrocas@quarkslab.com>
Signed-off-by: Eloïse Brocas <ebrocas@quarkslab.com>
Signed-off-by: Eloïse Brocas <ebrocas@quarkslab.com>
Signed-off-by: Eloïse Brocas <ebrocas@quarkslab.com>
Signed-off-by: Eloïse Brocas <ebrocas@quarkslab.com>
Signed-off-by: Eloïse Brocas <ebrocas@quarkslab.com>
Signed-off-by: Eloïse Brocas <ebrocas@quarkslab.com>
Signed-off-by: Eloïse Brocas <ebrocas@quarkslab.com>
Signed-off-by: Eloïse Brocas <ebrocas@quarkslab.com>
Signed-off-by: Eloïse Brocas <ebrocas@quarkslab.com>
Signed-off-by: Eloïse Brocas <ebrocas@quarkslab.com>
Signed-off-by: Eloïse Brocas <ebrocas@quarkslab.com>
Signed-off-by: Eloïse Brocas <ebrocas@quarkslab.com>
Signed-off-by: Eloïse Brocas <ebrocas@quarkslab.com>
Signed-off-by: Eloïse Brocas <ebrocas@quarkslab.com>
Signed-off-by: Eloïse Brocas <ebrocas@quarkslab.com>
Signed-off-by: Eloïse Brocas <ebrocas@quarkslab.com>
Signed-off-by: Eloïse Brocas <ebrocas@quarkslab.com>
Signed-off-by: Eloïse Brocas <ebrocas@quarkslab.com>
pytest 9 deprecates class-scoped fixtures defined as instance methods (they will be removed in pytest 10): the instance a fixture runs on is not the one test methods see. Convert the class-scoped fixtures (pyrrha_exec, export_res, export_dump across the fs, fs-cg and decomp test classes, plus the _host_path helper they call) to classmethods using cls instead of self. The abstract export_res stub stays an instance method since it is always overridden and never run as a fixture.
NamedTemporaryFile(delete_on_close=...) only exists on Python >= 3.12, but the project supports 3.11 (the Ghidra CI image runs 3.11), so record_source raised TypeError on the first non-imported function, aborting every Ghidra decompilation run. Use delete=False with explicit cleanup in a finally block; this also fixes the Windows case, where record_file cannot reopen a still-open NamedTemporaryFile.
record_reference_location expects the reference id returned by record_ref_call, but index_call_graph discarded it and passed the callee symbol id instead, so call-site highlights were associated with the wrong token. Capture the ref id and use it, skipping location recording when no reference was created.
numbat derives a source file's node id from the name passed to record_file and returns the existing id when that name was already seen, but then always inserts a new file row with it, raising "UNIQUE constraint failed: file.id" whenever two functions share a name. Ghidra (and IDA) can emit several functions with the same mangled name (tool-generated or versioned symbols), so record the file under "<name>@<addr>", which is unique because the address is the key under which the function is stored.
Add tests/test_decomp_mapper.py covering record_function, record_source, index_decompiled (declaration/call-site location, suffix shadowing, missing declaration) and index_call_graph (reference recording, imported caller/callee skipping, unregistered callees, missing source) plus to_export and normalize_name. The mapper is driven through a fake DB and injected FuncData, so no IDA/Ghidra backend is needed; this raises decomp_mapper coverage from ~31% to ~82% in the backend-free CI job. Add a test_decomp_mapper CI job to collect that coverage. The remaining uncovered lines are __init__, index_function and map(), which require a real backend and are exercised by the IDA/Ghidra jobs.
Signed-off-by: Eloïse Brocas <ebrocas@quarkslab.com>
Signed-off-by: Eloïse Brocas <ebrocas@quarkslab.com>
Signed-off-by: Eloïse Brocas <ebrocas@quarkslab.com>
The _collect_export_artifacts teardown copied each artifact into PYTEST_ARTIFACTS_DIR with shutil.copy2 and no error handling. When a job downloads another job's artifacts into that same directory (test_fs-cg_backend needs test_fs), GitLab restores them read-only, so the copy raised PermissionError and failed the test at teardown. Drop a pre-existing destination before copying and swallow any OSError with a warning: collecting artifacts is a convenience and must never fail a test.
Signed-off-by: Eloïse Brocas <ebrocas@quarkslab.com>
Each test job measured only its own module and emitted a separate coverage percentage, so there was no single number for the whole suite. Run coverage in parallel mode (parallel=true in [tool.coverage.run]) so each job writes a uniquely suffixed data file, save that file as an artifact, and add a coverage job that downloads every test job's data file, combines them and produces one global cobertura report and percentage. A [tool.coverage.paths] alias maps the source tree and the installed wheel to the same logical path so the data files merge instead of being double-counted. coverage combine is added before xml/report in the per-job script, which parallel mode now requires.
Each test job runs `coverage combine`, which consumes the suffixed .coverage.*
files and writes a single plain .coverage; the artifact glob ".coverage.*" then
matched nothing, so the coverage job had no data to combine ("No data to
combine"). Rename the combined file to .coverage.$CI_JOB_NAME_SLUG (unique per
job, including matrix children) and save that as the artifact; the coverage job
then finds every job's file and merges them.
Signed-off-by: Eloïse Brocas <ebrocas@quarkslab.com>
When several filesystem components match an imported name and the INTERACTIVE strategy is used, _select_fs_component scans the resolve cache for an already-chosen entry. On a cache hit it set selected_bin but left selected_index as None, so the prompt loop guard stayed satisfied and the user was asked to choose again, ignoring the cached decision. Record the matching index and break out of the scan on a cache hit so the cached choice is returned without prompting.
Add unit tests that run without a disassembler backend, raising backend-free coverage of the affected modules: - decomp_mapper: drive __init__, index_function and map() via a DecompilMapper subclass with canned backend accessors (82% -> 99%). - __main__: exercise the fs, fs-cg and decomp CLI commands with the mappers, setup_db and setup_logs faked, plus setup_logs and the unsupported-backend guards (0% -> 99%). - imports_mapper: cover the DB-recording helpers, _select_fs_component strategies, _resolve_lib_import, resolve_symbol_import, the non-resolved import recording and the result validators (17% -> 45%). The imports tests use a recording FakeDB double and real FileSystem / Binary / Symbol objects so the resolution heuristics run against genuine data. Includes a regression test for the INTERACTIVE duplicate-resolution cache reuse.
Add unit tests that run without a disassembler backend for the inter-image call-graph modules: - intercg_mapper: cover the overridden _correct_map_result, map_binary bookkeeping, _treat_bin_parsing_result dispatch (incl. the lief fallback), the static _merge_parser_functions_into_cached_binary helper, _record_call_ref / _record_unindexed_call, the export-to-binaries map and the _record_one_call resolution branches (local, ignore-listed, ghidra-synthetic, template/version stripping, single/multiple exporters, unindexed, .ko handling) (15% -> 58%). - intercg_bin_loader: cover FuncData accessors, the _count_leading_underscores helper, the synthetic-name regex, _build_calls_list and _disambiguate_export, the latter two exercised on a parser built without launching a disassembler (20% -> 32%). As elsewhere, a recording FakeDB double and real FileSystem / Binary / Symbol objects are used so resolution logic runs against genuine data.
The backend-free unit tests (test_main.py, test_imports_mapper.py, test_intercg_mapper.py, test_intercg_bin_loader.py) were added as files but no pipeline job executed them, so their coverage never reached the global report: the intercg modules stayed at their import-only floor, imports_mapper reflected only the backend job, and __main__ was absent from the report entirely. Add four backend-free jobs in the 'test' stage, each extending test_data_structures so they reuse the parallel-mode coverage + combine + per-job .coverage.<slug> artifact pattern: - test_cli -> __main__ (tests/test_main.py) - test_imports_mapper -> imports_mapper unit paths - test_intercg_mapper -> intercg_mapper - test_intercg_bin_loader -> intercg_bin_loader Add all four to the global 'coverage' job's needs so their data files are combined with the backend jobs. Modules measured by both a unit job and a backend job (imports_mapper, intercg_*) are reported as the union of lines any test exercised.
Signed-off-by: Eloïse Brocas <ebrocas@quarkslab.com>
Signed-off-by: Eloïse Brocas <ebrocas@quarkslab.com>
Signed-off-by: Eloïse Brocas <ebrocas@quarkslab.com>
Signed-off-by: Eloïse Brocas <ebrocas@quarkslab.com>
Signed-off-by: Eloïse Brocas <ebrocas@quarkslab.com>
Signed-off-by: Eloïse Brocas <ebrocas@quarkslab.com>
Signed-off-by: Eloïse Brocas <ebrocas@quarkslab.com>
Signed-off-by: Eloïse Brocas <ebrocas@quarkslab.com>
Signed-off-by: Eloïse Brocas <ebrocas@quarkslab.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.
No description provided.