2.26.3 manual sync - #391
Merged
Merged
Conversation
Preparatory refactor for the shared-CFG dataflow migration. Adds the adapter that mediates between the Python AST and the shared codeql.controlflow.ControlFlowGraph signature, plus the test suites that validate the new CFG directly against this adapter. The public facade is added in the following commit. Library additions: - semmle.python.controlflow.internal.AstNodeImpl — wraps Python's Stmt/Expr/Scope/Pattern and adds two synthetic kinds of node (BlockStmt for body slots, intermediate nodes for multi-operand boolean expressions) to satisfy the shared CFG signature. - lib/ide-contextual-queries/printCfg.ql — the IDE "Print CFG" query, retargeted to the new CFG. - consistency-queries/CfgConsistency.ql — consistency query running the shared CFG's standard checks against Python. Test additions (all driven directly off AstNodeImpl): - ControlFlow/bindings/* — annotation-driven SSA-binding tests (annassign, compound, comprehension, decorated, except_handler, imports, match_pattern, parameters, simple, type_params, walrus_starred, with_stmt, dead_under_no_raise). - ControlFlow/evaluation-order/NewCfg*.ql — mirrors of the existing OldCfg evaluation-order self-validation suite, run against the new CFG via NewCfgImpl.qll. - Minor extensions to existing test_if.py / test_boolean.py + cosmetic .expected churn on a handful of OldCfg tests. No dataflow, SSA, or production query is migrated yet. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Adds the public facade on top of the AstNodeImpl adapter from the previous commit. Re-exposes the same API surface as semmle/python/Flow.qll (ControlFlowNode, CallNode, BasicBlock, NameNode, DefinitionNode, CompareNode, ...), backed by the shared codeql.controlflow.ControlFlowGraph library. - semmle.python.controlflow.internal.Cfg — public facade. - ControlFlow/store-load/* — basic store/load coverage via the facade. The new CFG library is added additively: it has zero callers in lib/ and src/, and the legacy CFG in semmle/python/Flow.qll remains the default. Dataflow, SSA, and production query migration land in follow-up PRs. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…with The new CFG previously only emitted exception edges for explicit `raise` and `assert` statements. As a result, code that became reachable only via the exception path of an arbitrary expression (e.g., the body of an `except` handler following a try-body whose `call()` could raise) was classified as dead, breaking analyses like StackTraceExposure, FileNotAlwaysClosed, ExceptionInfo, UseOfExit, and CatchingBaseException. This commit adds a `mayThrow` predicate over expressions that are known sources of implicit exceptions in Python (calls, attribute access, subscripts, arithmetic/comparison operators, imports, await/yield/yield from) plus `from m import *` at the statement level, and routes them through the shared CFG's `beginAbruptCompletion(_, _, ExceptionSuccessor, always=false)` hook. The set of exception sources is restricted to nodes that are syntactically inside a `try`/`with` statement in the same scope. This mirrors Java's `ControlFlowGraph::mayThrow`, which only emits exception edges where local handling can observe them — outside such contexts, the edges add CFG complexity (weakening BarrierGuard precision and breaking SSA continuity around augmented assignments and subscript stores) without analysis benefit, since exceptions just propagate to the function exit anyway. Net effect on the test suite: ~100 alerts restored across the exception- related query tests (StackTraceExposure +29, ExceptionInfo +17, FileNotAlwaysClosed +52, UseOfExit +1, CatchingBaseException restored) with no precision regressions. Affected `.expected` files and the regression-guard `dead_under_no_raise.py` are updated accordingly. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The new (shared-CFG-based) Python control flow graph in `semmle.python.controlflow.internal.Cfg` previously did not emit CFG nodes for parameter type annotations (`def f(x: T): ...`) or for the return type annotation (`-> T`). The legacy CFG emitted both, and a small number of framework models rely on this: `LocalSources.qll`'s `annotatedInstance` walks the parameter annotation expression by way of its CFG node to track that a parameter receives an instance of the annotated class. After the dataflow flip to the new CFG/SSA this regression manifested as lost flows in any test exercising annotation-based parameter tracking: FastAPI `Depends()` receivers, Pydantic request bodies, Starlette `WebSocket`, the call-graph type-annotation test, and so on. Extend `FunctionDefExpr` to visit each annotation as a child of the function-def expression, in CPython evaluation order: positional parameter annotations, `*args` annotation, keyword-only parameter annotations, `**kwargs` annotation, then the return annotation. (Lambda expressions have no annotations in Python syntax, so `LambdaExpr` is unchanged.) PEP 695 type parameters remain out of scope; they belong to the inner annotation scope, not the enclosing CFG. Restored test results across `framework/aiohttp`, `framework/fastapi`, `framework/lxml`, the `CallGraph-type-annotations` test, and `CWE-022-PathInjection`. Two FastAPI list-comprehension MISSING markers become positive (`taint_test.py:41,55`). CPython CFG consistency remains clean. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…seroute-query Model Vue Router useRoute query as a remote flow source
…ntenance Move Vue Composition API flow models into Vue.qll
Make `toRef` value-preserving and model the `computed` object overload so `.value` flow is exercised for both `computed` API shapes. `computed` is moved into the `vue.model.yml` data extension because the object overload requires callback flow synthesis that a hand-written `SummarizedCallable` cannot provide. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 5c95b651-1e79-499e-9e11-e09065b14aa9
…-tests Add Vue toRef value-flow and computed object-overload tests
- AST navigation such as `getObject` and `getChild` now only moves through nodes identified via `injects` - identification such as `isSubscript` only holds for injected nodes - subclasses such as `AttrNode` are injected nodes (no, say after-nodes)
We have CfgImpl::Cfg already.
Bumps [rules_nodejs](https://github.com/bazel-contrib/rules_nodejs) from 6.7.3 to 6.7.5. - [Release notes](https://github.com/bazel-contrib/rules_nodejs/releases) - [Changelog](https://github.com/bazel-contrib/rules_nodejs/blob/main/CHANGELOG.md) - [Commits](bazel-contrib/rules_nodejs@v6.7.3...v6.7.5) --- updated-dependencies: - dependency-name: rules_nodejs dependency-version: 6.7.5 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com>
The AST dump previously emitted named fields in field-id order, which made it dependant on registration order and so it could differ between front-ends. We now emit them in the order declared in the node-types YAML instead, so that the order is kept stable.
In our swift-syntax wrapper, we now attempt to fold all operator sequences (i.e. `sequenceExpr` nodes) into appropriate `infixOperatorExpr` nodes, assuming the requisite operator definitions are present. Currently, we only consider operators that are defined in the standard library, and operators that are defined in the current file, leaving operators defined in separate modules as future work. The folding is done maximally -- if an argument of an unknown operator can be folded in isolation, then this is done. Each top-level sequence is folded independently, so a single unknown operator leaves only its own sequence flat rather than aborting folding elsewhere.
Prepare yeast for front-ends that do not parse with tree-sitter (e.g. the swift-syntax front-end, whose parser hands us a ready-built `yeast::Ast`): - `Runner`/`ConcreteDesugarer` now hold `Option<tree_sitter::Language>`. New constructors `Runner::with_schema_no_language`, `ConcreteDesugarer::without_language`, and `DesugaringConfig::build_schema_no_language` build the schema from the output node-types YAML alone. The parsing entry points (`run`/`run_from_tree`) error when no language is present; `run_from_ast` needs none. - `BuildCtx::source_text` is a small convenience for Rust-block rules that read a captured token's source text. - AST-dump type validation now resolves field constraints and required fields by field NAME rather than by field id. A field id is local to the schema that assigned it, so an AST built by one schema (e.g. an external parser's adapter) could not be validated against another (the output node-types schema) without re-keying. Looking up by name keeps the two schemas full independent: they share field names, not ids. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Previously the `simple` multi-language extractor carried an optional
desugarer, so every language (including plain tree-sitter ones such as
ql, dbscheme, json and blame) went through the same desugaring-aware
extraction path.
This commit splits it into two front-ends that share a private driver:
- `simple`: pure tree-sitter extraction with no desugaring. Comments
and other `extra` nodes are emitted inline as tokens. (The extractor
then extracts these as usual.)
- `desugaring`: parses source into a `ParsedTree` (a yeast AST plus
side-channel `extra` tokens) and rewrites the AST through a
`yeast::Desugarer` before extraction. The parser is a closure, so
both tree-sitter grammars (via `tree_sitter_parser`) and custom
parsers plug in the same way.
The shared multi-file plumbing (threading, glob matching, source-archive
copying, TRAP writing) lives in a new private `driver` module behind a
`LanguageExtractor` trait, so neither front-end duplicates it.
`extract` no longer takes an optional desugarer (it always walks the
parse tree directly); `extract_parsed` takes a required desugarer. ql
and ruby use the direct path; the unified Swift extractor uses the
desugaring path.
Also rename the new side-channel identifiers from "trivia" to "extra"
(ExtraToken, ParsedTree.extras, emit_extra, ...) to match tree-sitter's
own `is_extra()` terminology. The pre-existing `*_trivia_tokeninfo`
relation is left unchanged for a separate change.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Documents existing behavior for implicit returns (no return keyword) from: - method body with ensure present - rescue clause (with and without ensure) - else clause (with and without ensure) The test shows that only simple body returns currently work; all other cases are marked MISSING to document the known gaps.
Runner labels cannot reliably distinguish self-hosted runners from managed runners. Deprecate the supporting SelfHostedQuery library module.
Co-authored-by: Anders Schack-Mulligen <aschackmull@users.noreply.github.com>
…d-runner-query Actions: Remove experimental self-hosted runner query
…ons-cache-poisoning-cache-write-access
…nting-existing-behavior Ruby: add qltest documenting implicit return dataflow gaps
JS: Add support for file-scoped MaD models
CODEOWNERS: make language coverage team responsible for more Rust and C++ code
Even though we're not using the new Go-based TypeScript compiler under the hood, we can still handle TypeScript 7.0 codebases, so bumping to that version.
…d-runner-remnants Actions: Remove SelfHostedQuery completely
…ng-cache-write-access Actions: Fix actions cache poisoning queries to account for the latest changes in cache write access
…t-version JS: Update supported TypeScript language version
Python: Update doc to refect that we support Python 3.14
…clude Ruby: Exclude vendored library parameters from taint sources.
…-promise-chain JS: Track response data through promises
Release preparation for version 2.26.3
dilanbhalla
enabled auto-merge
August 13, 2026 19:18
Mathias Vorreiter Pedersen (MathiasVP)
approved these changes
Aug 13, 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.
No description provided.