Merge QS into master - #1372
Merged
Merged
Conversation
Move the product overview, feature list, screenshots, and LFS note from the removed floss/qs/readme.md into the main README under layout-aware floss quantum analysis.
Hoist rich.traceback.install above the quantum subcommand dispatch so classic and floss quantum share the same setup. Keep install in quantum.main for the standalone quantum console entry, with matching show_locals=True.
Replace conftest sys.path mutation with tool.pytest.ini_options so tests can import scripts.tags without mutating the whole suite.
Clarify that the suite only smoke-tests the five render-* import scripts under scripts/disassemblers/.
Drop __all__ and convenience re-exports; import types and extract helpers from the defining submodules.
Project does not use star imports; keep the package re-exports as-is.
refactor: split QUANTUMSTRAND into first-class layout/tags modules
…cument Extend the major-release schema with plain enrichment fields on string types and an optional serializable layout tree. Add JSON round-trip tests for the new fields.
Add helpers to flatten layout trees into StaticString lists and enrich offset-bearing language strings with tags, section, and structure.
Move orchestration into pipeline.analyze. When PE/ELF/Mach-O layout succeeds, reuse quantum extract (tags, structures, FP-lib filter) and replace static_strings; fall back to classic statics otherwise. CLI gains --no layout/tags; main is a thin entry point.
Skip classic meta when layout exists; render section tree via layout_text. Language and recovered strings follow as classic blocks.
Update LFS attributes, data_root(), PyInstaller datas, OSS workflow, packaging, and docs. Remove residual floss/qs package.
Deprecate floss.quantum and document dual schema; floss quantum remains a thin alias. Update README, bulk_analyze, and QS document tests for the unified ResultDocument.
Correct import order, reformat pipeline helpers, and satisfy mypy on ResultLayout conversion, TagRules typing, and analyze() Optional result.
Layout types live in floss.results; nothing imports document.py anymore.
Layout-aware analysis is the default for floss; the quantum console script and deprecated subcommand shim are no longer needed.
Keep the round-trip and assertion guidance comments removed during the schema migration per review feedback.
Bring back the basic layout pipeline smoke test removed during the schema migration.
Stop re-exporting pipeline/CLI helpers from floss.main. Import select_functions from floss.pipeline, StringType/set_log_config from floss.cli, and load stack/tight string modules lazily in conftest to avoid the identify/features circular import.
hide_strings_by_rules now returns a new layout tree so default render no longer deep-copies results.layout. Fold the redundant has_layout inner condition into one if that also narrows for mypy.
No cycle requires deferred imports; load hide_strings_by_rules and render_strings with the rest of default render dependencies.
When stack/tight/decoded analysis is enabled, print the section heading with the count even if zero strings were found, matching classic FLOSS.
Keep the original guidance comments adapted to field-level JSON round-trip asserts, and assert version divergence changes JSON output.
These fields were not shown in the UI; tags was a copy of layout time rather than a real measurement. static_strings already covers layout work. Restore useful analysis comments lost in the pipeline move.
Tagging/enrichment only applies to static (and language) strings for now. Remove premature tags (and section/structure on DecodedString) until needed.
Keep the floss.cli import change only; restore pre-existing wrapping that already satisfies black/isort at line-length 120.
Previous edit used default black line wrapping (too aggressive for line-length 120), which broke the code_style CI job.
Collaborator
Author
|
cla failing because of commit limits, not a concern here |
Collaborator
that's how we know we did a lot of work here 😉 |
10 tasks
XOR-obfuscated headers append ' (XOR decoded with key: 0x...)' to the layout name, so is_structured_layout()'s exact 'pe'/'elf' match failed and compute_layout() silently fell back to classic static strings, losing section names, code/reloc/XOR tags, and structure annotations. Strip any parenthetical suffix before matching.
The help text says -y defaults to not running deobfuscation, but the prompt branch -y bypasses was the only place stack/tight/decoded got disabled, so a non-interactive Go/Rust run with -y ran full deobfuscation anyway (only .NET was force-disabled). -y now skips the prompt and disables deobfuscation, matching the documented default.
The key was sha256+version only, so interpreting the same bytes under a different --format (sc32 vs sc64) could serve the other variant's stack/tight/decoded results. The CLI already disables caching for non-auto formats, but API callers passing cache_dir were unprotected. Format is now part of the key, so variants never collide.
PELayout/ELFLayout mark_structures overrides only recursed into children, never applying structures_by_address to their own strings, so strings in the ELF header/program-header gap (attached to the root node) and PE header-gap strings rendered with an empty .structure. Both now annotate their own strings before recursing, matching MachOLayout.
--summary auto-disables stack/tight/decoded and --analyze-functions disables static, so the combination silently left every string type disabled and rendered an empty summary. Since the summary only covers static strings, which --analyze-functions cannot show, the two are incompatible and now raise a clear argument error.
The max_len fallback branch tested args.libs twice, so --pes without an
explicit --max-len raised ValueError('unknown extraction type'). The
second condition now checks args.pes.
Only gp.StringHashDatabase checked for a Git LFS pointer; the oss, winapi, and expert loaders failed with a confusing BadGzipFile/msgspec error on a fresh clone without git lfs pull. A shared ensure_not_lfs_pointer() helper now raises the actionable message, and gp's loader is refactored onto it.
The CLI flag was already removed; Options.disable_progress remained as a permanently-False field feeding 5 progress-gating sites. Per review, drop the flag entirely: quiet now drives those gates directly.
--yes implied it enables deobfuscation, but the flag skips the prompt and defaults to not running it, which confused reviewers. --no-prompt states the intent. The dest and Options field become no_prompt (store_true).
compute_key(sha256, version, format='auto') so callers that only need the default variant don't have to pass it explicitly.
The interactive deobfuscation prompt (and the confusing -y/--yes / --no-prompt flag that skipped it) is removed entirely. String deobfuscation is now opt-in: a plain run defaults to static (and language) strings only, and stack/tight/decoded must be requested explicitly via --string-type. --analyze-functions requests function-level deobfuscation, so it is not disabled by the default. This resolves the silent redirect behavior from #1176: there is no implicit 'n' anymore, just an explicit default.
Runs serve cached documents by default, which silently mixes output from different code revisions. Document FLOSS_CACHE_ENABLE=0 for reproducing and diffing.
format='auto' is now the default, so tests no longer pass it explicitly.
Previously only non-static values were rejected, silently allowing --summary --string-type static. --summary is its own static-only view, so any --string-type/--no-string-type is now an argument error.
MAX_LEN_LIBS (64) now applies to --libs and MAX_LEN_PES (100) to --pes; they were swapped.
It only re-asserted the Analysis defaults and added a slow full run; the default all-on behavior is covered implicitly elsewhere.
The layout tree widened \t to 4 spaces while every other view escapes it to the literal two-char sequence via sanitize(). json.dumps() already escapes \t (and \n, \r), so dropping the widening makes the layout view consistent: control chars render as literals and stay on one line.
Fix review issues from #1375 (quantumstrand correctness/regression fixes)
mr-tz
approved these changes
Aug 19, 2026
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.
Closes #943