Files
Open_Ultra_SAST/tests/test_semantic_cst.py
T

71 lines
2.6 KiB
Python
Raw Normal View History

"""Extra-on CST walker and overlay. Skips when wheels are absent."""
from __future__ import annotations
from pathlib import Path
import pytest
from openultrasast.findings import quick_scan_findings
from openultrasast.preprocess import preprocess_repository
from openultrasast.rank import rank_targets
from openultrasast.semantic import adjudicate, has_semantic_extra
from openultrasast.semantic.ir import parse_file
pytestmark = pytest.mark.semantic
def _require_extra() -> None:
if not has_semantic_extra():
pytest.skip("requires openultrasast[semantic]")
def test_javascript_eval_query_is_tree_sitter_call() -> None:
_require_extra()
ir = parse_file("app.js", "eval(req.query.x)\n", "javascript")
assert ir.parse_ok is True
assert ir.engine == "tree-sitter"
calls = [call for function in ir.functions for call in function.calls]
eval_calls = [call for call in calls if call.name == "eval"]
assert eval_calls
assert any("req.query" in arg for arg in eval_calls[0].arg_texts)
def test_broken_javascript_is_parse_failed() -> None:
_require_extra()
ir = parse_file("app.js", "eval(req.query.x\n", "javascript")
assert ir.parse_ok is False
assert ir.reason == "parse_failed"
def test_javascript_eval_promotes(tmp_path: Path) -> None:
_require_extra()
root = tmp_path / "repo"
root.mkdir()
(root / "app.js").write_text("eval(req.query.x)\n")
_, targets = preprocess_repository(root)
findings = quick_scan_findings(root, targets, rank_targets(targets))
records = adjudicate(root=root, targets=targets, findings=findings)
eval_records = [record for record in records if "js-eval" in record.proposal_id]
assert eval_records
assert eval_records[0].disposition == "promote"
assert eval_records[0].evidence_level == "static_corroboration"
assert eval_records[0].engine == "tree-sitter"
def test_c_constant_system_demotes(tmp_path: Path) -> None:
_require_extra()
root = tmp_path / "repo"
root.mkdir()
(root / "run.c").write_text('void f(void) { system("ls"); }\n')
_, targets = preprocess_repository(root)
findings = quick_scan_findings(root, targets, rank_targets(targets))
records = adjudicate(root=root, targets=targets, findings=findings)
hits = [record for record in records if record.path == "run.c"]
assert hits
assert all(record.disposition != "unadjudicated" or record.reason != "language_unsupported" for record in hits)
demoted = [record for record in hits if record.disposition == "demote"]
assert demoted
assert demoted[0].dominating_fact == "constant"
assert demoted[0].evidence_level == "static_corroboration"