merge: taint-query null-guard fix and trace-enabled engine runner

The query fix stops a class-level call from aborting the whole taint batch on
real PHP code; gate, map_gate and pair_gate outputs are unchanged. Trace parsing
lives with the runner (benchmarks/learn/engine_trace_parse.py).

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
Marius Ciepluch
2026-10-04 10:53:23 +02:00
co-authored by Claude Opus 5.5
10 changed files with 2557 additions and 22 deletions
+13
View File
@@ -20,6 +20,7 @@ host's pytest mounted in, which needs no network and installs nothing:
from __future__ import annotations
import json
import re
import subprocess
from pathlib import Path
@@ -28,6 +29,18 @@ import pytest
QUERIES = Path("src/openultrasast/cpg/queries")
@pytest.mark.parametrize("name", ["taint", "dominance", "config", "census", "overlay", "vocabulary"])
def test_query_scope_checks_guard_nullable_methods(name: str) -> None:
"""PHP class constants can have no method; one unsafe scope check aborts the batch."""
script = QUERIES / f"{name}.sc"
source = script.read_text()
assert source, f"{script} is empty"
# Require Option(node.method).exists(predicate), keeping the null guard at the call site.
unsafe = re.compile(r"\b(?:inScope|nestedInLabeled)\s*\(\s*[\w.]+\s*\.\s*method\s*\)")
sites = [source.count("\n", 0, match.start()) + 1 for match in unsafe.finditer(source)]
assert not sites, f"{script}: unguarded method scope checks at lines {sites}"
def _joern() -> str | None:
import shutil
File diff suppressed because it is too large Load Diff