From b229066891bab3ecc52aa3bfe534c5886493bb41 Mon Sep 17 00:00:00 2001 From: Taus Date: Tue, 21 Apr 2026 15:05:48 +0000 Subject: [PATCH] Python: Add `with` Co-authored-by: yoff --- .../controlflow/internal/AstNodeImpl.qll | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/python/ql/lib/semmle/python/controlflow/internal/AstNodeImpl.qll b/python/ql/lib/semmle/python/controlflow/internal/AstNodeImpl.qll index 26f778130cc..18bdeca4e31 100644 --- a/python/ql/lib/semmle/python/controlflow/internal/AstNodeImpl.qll +++ b/python/ql/lib/semmle/python/controlflow/internal/AstNodeImpl.qll @@ -228,6 +228,19 @@ private module Ast { ExprNode getCause() { result.asExpr() = raise.getCause() } } + /** A `with` statement. */ + class WithNode extends StmtNode { + private Py::With withStmt; + + WithNode() { withStmt = this.asStmt() } + + ExprNode getContextExpr() { result.asExpr() = withStmt.getContextExpr() } + + ExprNode getOptionalVars() { result.asExpr() = withStmt.getOptionalVars() } + + StmtListNode getBody() { result.asStmtList() = withStmt.getBody() } + } + /** A `break` statement. */ class BreakNode extends StmtNode { BreakNode() { this.asStmt() instanceof Py::Break } @@ -650,6 +663,15 @@ module AstSigImpl implements AstSig { // Delete: targets left to right result = n.(Ast::DeleteNode).getTarget(index) or + // With: context expr (0), optional vars (1), body (2) + exists(Ast::WithNode w | w = n | + index = 0 and result = w.getContextExpr() + or + index = 1 and result = w.getOptionalVars() + or + index = 2 and result = w.getBody() + ) + or // ThrowStmt (raise): the exception (0), the cause (1) exists(Ast::RaiseNode r | r = n | index = 0 and result = r.getException()