From d8e7e2e037687b0ab40fb03236b31e2985081cd6 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Thu, 1 Oct 2026 23:31:02 +0100 Subject: [PATCH 1/2] Update tree-sitter-ql Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- ql/Cargo.lock | 2 +- ql/extractor/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ql/Cargo.lock b/ql/Cargo.lock index 7d52df74d85d..fd46dc52cc76 100644 --- a/ql/Cargo.lock +++ b/ql/Cargo.lock @@ -844,7 +844,7 @@ dependencies = [ [[package]] name = "tree-sitter-ql" version = "0.23.1" -source = "git+https://github.com/tree-sitter/tree-sitter-ql.git?rev=5b8ee9adaa1f2a1ea958064b61f8feb0a5a886c0#5b8ee9adaa1f2a1ea958064b61f8feb0a5a886c0" +source = "git+https://github.com/tree-sitter/tree-sitter-ql.git?rev=d9d6c853caf0f882e6371e4d4da5817c48c8a8d8#d9d6c853caf0f882e6371e4d4da5817c48c8a8d8" dependencies = [ "cc", "tree-sitter-language", diff --git a/ql/extractor/Cargo.toml b/ql/extractor/Cargo.toml index 0a1b17d9c920..aa81f1904171 100644 --- a/ql/extractor/Cargo.toml +++ b/ql/extractor/Cargo.toml @@ -8,7 +8,7 @@ edition = "2021" [dependencies] tree-sitter = ">= 0.26.0" -tree-sitter-ql = { git = "https://github.com/tree-sitter/tree-sitter-ql.git", rev = "5b8ee9adaa1f2a1ea958064b61f8feb0a5a886c0"} +tree-sitter-ql = { git = "https://github.com/tree-sitter/tree-sitter-ql.git", rev = "d9d6c853caf0f882e6371e4d4da5817c48c8a8d8"} tree-sitter-ql-dbscheme = { git = "https://github.com/tree-sitter/tree-sitter-ql-dbscheme.git", rev = "1980b4b6998a1138d326f863e6168f0f2c0c544d"} tree-sitter-blame = {path = "../buramu/tree-sitter-blame"} tree-sitter-json = {git = "https://github.com/tree-sitter/tree-sitter-json.git", rev = "8bfdb43f47ad805bb1ce093203cfcbaa8ed2c571"} From 993ce4be3426f08624a6cf9c13c4c3910426fba6 Mon Sep 17 00:00:00 2001 From: Owen Mansel-Chan Date: Thu, 1 Oct 2026 23:56:41 +0100 Subject: [PATCH 2/2] Model optional overlay annotations Preserve the anonymous question-mark suffix in annotation arguments so overlay[caller?] and overlay[local?] use their dedicated AST classes. Add regression coverage for optional and non-optional overlay annotations. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- ql/ql/src/codeql_ql/ast/Ast.qll | 22 ++++++++++++++----- .../OverlayAnnotations.expected | 3 +++ .../InlineOverlayCaller/OverlayAnnotations.ql | 9 ++++++++ 3 files changed, 29 insertions(+), 5 deletions(-) create mode 100644 ql/ql/test/queries/overlay/InlineOverlayCaller/OverlayAnnotations.expected create mode 100644 ql/ql/test/queries/overlay/InlineOverlayCaller/OverlayAnnotations.ql diff --git a/ql/ql/src/codeql_ql/ast/Ast.qll b/ql/ql/src/codeql_ql/ast/Ast.qll index 1dcbff8c8171..7cdfd6163d2a 100644 --- a/ql/ql/src/codeql_ql/ast/Ast.qll +++ b/ql/ql/src/codeql_ql/ast/Ast.qll @@ -2530,13 +2530,25 @@ private class AnnotationArg extends TAnnotationArg, AstNode { AnnotationArg() { this = TAnnotationArg(arg) } + private predicate isOptional() { + arg.getLocation().getEndLine() != arg.getChild().getLocation().getEndLine() + or + arg.getLocation().getEndColumn() != arg.getChild().getLocation().getEndColumn() + } + /** Gets the name of this argument. */ string getValue() { - result = - [ - arg.getChild().(QL::SimpleId).getValue(), arg.getChild().(QL::Result).getValue(), - arg.getChild().(QL::This).getValue() - ] + exists(string value | + value = + [ + arg.getChild().(QL::SimpleId).getValue(), arg.getChild().(QL::Result).getValue(), + arg.getChild().(QL::This).getValue() + ] + | + result = value and not this.isOptional() + or + result = value + "?" and this.isOptional() + ) } override string toString() { result = this.getValue() } diff --git a/ql/ql/test/queries/overlay/InlineOverlayCaller/OverlayAnnotations.expected b/ql/ql/test/queries/overlay/InlineOverlayCaller/OverlayAnnotations.expected new file mode 100644 index 000000000000..138b0f999121 --- /dev/null +++ b/ql/ql/test/queries/overlay/InlineOverlayCaller/OverlayAnnotations.expected @@ -0,0 +1,3 @@ +| Test.qll:1:1:1:15 | overlay[local?] | overlay[local?] | +| Test.qll:9:1:9:15 | overlay[caller] | overlay[caller] | +| Test.qll:16:1:16:16 | overlay[caller?] | overlay[caller?] | diff --git a/ql/ql/test/queries/overlay/InlineOverlayCaller/OverlayAnnotations.ql b/ql/ql/test/queries/overlay/InlineOverlayCaller/OverlayAnnotations.ql new file mode 100644 index 000000000000..6154afc96ae6 --- /dev/null +++ b/ql/ql/test/queries/overlay/InlineOverlayCaller/OverlayAnnotations.ql @@ -0,0 +1,9 @@ +import ql + +from Annotation a +where + a instanceof OverlayCaller or + a instanceof OverlayCallerQ or + a instanceof OverlayLocal or + a instanceof OverlayLocalQ +select a, a.toString()