Compare commits

..

19 Commits

Author SHA1 Message Date
Asger F
69a7376981 QL4QL: Regenerate raw AST 2026-06-26 08:44:42 +00:00
Asger F
81945d261f Ruby: Regenerate raw AST 2026-06-26 08:44:14 +00:00
Asger F
6ae75e5920 unified: Add PrintAst query 2026-06-26 08:44:14 +00:00
Asger F
6e10897a47 unified: Regenerate AST 2026-06-26 08:44:13 +00:00
Asger F
f8bccf91b6 Shared: Generate PrintAst helper in tree sitter extractor
Auto-generating a helper for implementing the PrintAST query on top of the generated AST.
2026-06-26 08:44:13 +00:00
copilot-swe-agent[bot]
4297f012f7 Initial plan 2026-06-26 08:40:05 +00:00
Asger F
cacdc467de Merge pull request #22036 from forks-felickz/felickz/js-angular-hostlistener-postmessage
JavaScript: Recognize Angular @HostListener('window:message') as a postMessage handler
2026-06-26 10:09:42 +02:00
Owen Mansel-Chan
7b800b1dd6 Merge pull request #22065 from github/dependabot/go_modules/go/extractor/extractor-dependencies-9f88df4328
Bump golang.org/x/tools from 0.46.0 to 0.47.0 in /go/extractor in the extractor-dependencies group
2026-06-26 06:59:52 +01:00
dependabot[bot]
3d1b6b64ed Bump golang.org/x/tools
Bumps the extractor-dependencies group in /go/extractor with 1 update: [golang.org/x/tools](https://github.com/golang/tools).


Updates `golang.org/x/tools` from 0.46.0 to 0.47.0
- [Release notes](https://github.com/golang/tools/releases)
- [Commits](https://github.com/golang/tools/compare/v0.46.0...v0.47.0)

---
updated-dependencies:
- dependency-name: golang.org/x/tools
  dependency-version: 0.47.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: extractor-dependencies
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-06-26 03:03:16 +00:00
yoff
5fcaac7cb2 Merge pull request #21869 from yoff/python/support-flask-subclasses
Python: Support Flask subclasses
2026-06-25 23:42:21 +02:00
Mario Campos
336df3ccf4 Merge pull request #22060 from github/post-release-prep/codeql-cli-2.26.0
Post-release preparation for codeql-cli-2.26.0
2026-06-25 12:43:54 -05:00
github-actions[bot]
456e33773b Post-release preparation for codeql-cli-2.26.0 2026-06-25 16:24:06 +00:00
Chad Bentz
d1d9df7729 Address review: restrict @HostListener handler to window/document message targets
Drop the plain 'message' event name from the @HostListener matcher. The
postMessage 'message' event is dispatched on window and does not bubble, so an
element-level @HostListener('message') does not receive cross-window messages.
Keeping only 'window:message' and 'document:message' makes the model more
precise and matches the accompanying comment and change note.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-22 21:35:21 -04:00
Chad Bentz
9bffcf81b5 JavaScript: Recognize Angular @HostListener('window:message') as a postMessage handler
Angular registers window message handlers via the
@HostListener('window:message', ['\']) decorator rather than
window.addEventListener('message', ...). The PostMessageEventHandler class
only modeled the addEventListener and window.onmessage forms, so the decorated
handler's event parameter was never treated as a message source. As a result,
js/missing-origin-check produced no alert and the event was not a client-side
remote flow source for downstream queries (e.g. client-side URL redirection).

Extend PostMessageEventHandler to also recognize methods decorated with
@HostListener for 'window:message', 'document:message', or 'message'.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-22 21:21:15 -04:00
yoff
f7c4e61956 Apply suggestions from code review
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-06-02 15:12:41 +02:00
yoff
575ece6ae2 Python: Add change note 2026-06-02 13:50:31 +02:00
yoff
f6ed5c19be Python: fix sub class test 2026-06-02 13:50:31 +02:00
yoff
4298b70f1c Python: add test for sub class 2026-06-02 13:49:25 +02:00
yoff
e88b8c53f3 Python: Add test for instances 2026-06-02 13:49:24 +02:00
70 changed files with 1413 additions and 59 deletions

View File

@@ -1,5 +1,5 @@
name: codeql/actions-all
version: 0.4.38
version: 0.4.39-dev
library: true
warnOnImplicitThis: true
dependencies:

View File

@@ -1,5 +1,5 @@
name: codeql/actions-queries
version: 0.6.30
version: 0.6.31-dev
library: false
warnOnImplicitThis: true
groups: [actions, queries]

View File

@@ -1,5 +1,5 @@
name: codeql/cpp-all
version: 11.0.0
version: 11.0.1-dev
groups: cpp
dbscheme: semmlecode.cpp.dbscheme
extractor: cpp

View File

@@ -1,5 +1,5 @@
name: codeql/cpp-queries
version: 1.6.5
version: 1.6.6-dev
groups:
- cpp
- queries

View File

@@ -1,5 +1,5 @@
name: codeql/csharp-solorigate-all
version: 1.7.69
version: 1.7.70-dev
groups:
- csharp
- solorigate

View File

@@ -1,5 +1,5 @@
name: codeql/csharp-solorigate-queries
version: 1.7.69
version: 1.7.70-dev
groups:
- csharp
- solorigate

View File

@@ -1,5 +1,5 @@
name: codeql/csharp-all
version: 7.0.0
version: 7.0.1-dev
groups: csharp
dbscheme: semmlecode.csharp.dbscheme
extractor: csharp

View File

@@ -1,5 +1,5 @@
name: codeql/csharp-queries
version: 1.7.5
version: 1.7.6-dev
groups:
- csharp
- queries

View File

@@ -10,7 +10,7 @@ toolchain go1.26.4
// bazel mod tidy
require (
golang.org/x/mod v0.37.0
golang.org/x/tools v0.46.0
golang.org/x/tools v0.47.0
)
require github.com/stretchr/testify v1.11.1

View File

@@ -10,8 +10,8 @@ golang.org/x/mod v0.37.0 h1:vF1DjpVEshcIqoEaauuHebaLk1O1forxjxBaVn884JQ=
golang.org/x/mod v0.37.0/go.mod h1:m8S8VeM9r4dzDwjrKO0a1sZP3YjeMamRRlD+fmR2Q/0=
golang.org/x/sync v0.21.0 h1:HLII4xRRTtCRkxYp4HNFF0Js/Og6q2i++KXbg0gHCwM=
golang.org/x/sync v0.21.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0=
golang.org/x/tools v0.46.0 h1:7jTurBkPZu4moS/Uy4OQT1M+QBlsj3wejyZwsT8Z7rk=
golang.org/x/tools v0.46.0/go.mod h1:FrD85F8l+NWL+9XWBSyVSHO6Ne4jutsfIFba7AWQ5Ys=
golang.org/x/tools v0.47.0 h1:7Kn5x/d1svx/PzryTsqeoZN4TZwqeH5pGWjefhLi/1Q=
golang.org/x/tools v0.47.0/go.mod h1:dFHnyTvFWY212G+h7ZY4Vsp/K3U4/7W9TyVaAul8uCA=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=

View File

@@ -1,5 +1,5 @@
name: codeql-go-consistency-queries
version: 1.0.52
version: 1.0.53-dev
groups:
- go
- queries

View File

@@ -1,5 +1,5 @@
name: codeql/go-all
version: 7.2.0
version: 7.2.1-dev
groups: go
dbscheme: go.dbscheme
extractor: go

View File

@@ -1,5 +1,5 @@
name: codeql/go-queries
version: 1.6.5
version: 1.6.6-dev
groups:
- go
- queries

View File

@@ -1,5 +1,5 @@
name: codeql/java-all
version: 9.2.0
version: 9.2.1-dev
groups: java
dbscheme: config/semmlecode.dbscheme
extractor: java

View File

@@ -1,5 +1,5 @@
name: codeql/java-queries
version: 1.11.5
version: 1.11.6-dev
groups:
- java
- queries

View File

@@ -0,0 +1,4 @@
---
category: minorAnalysis
---
* Added support for Angular's `@HostListener('window:message', ...)` and `@HostListener('document:message', ...)` decorators as `postMessage` event handlers. The decorated method's event parameter is now recognized as a client-side remote flow source, and is considered by the `js/missing-origin-check` query.

View File

@@ -1,5 +1,5 @@
name: codeql/javascript-all
version: 2.8.0
version: 2.8.1-dev
groups: javascript
dbscheme: semmlecode.javascript.dbscheme
extractor: javascript

View File

@@ -195,6 +195,18 @@ class PostMessageEventHandler extends Function {
rhs = DataFlow::globalObjectRef().getAPropertyWrite("onmessage").getRhs() and
rhs.getABoundFunctionValue(paramIndex).getFunction() = this
)
or
// Angular's `@HostListener('window:message', ['$event'])` decorator registers
// a method as a `message` event handler on the global `window` or `document`
// target. The decorated method receives the `MessageEvent` as its first
// parameter, so it is equivalent to `window.addEventListener('message', ...)`.
exists(MethodDefinition method, DataFlow::CallNode decorator |
decorator = DataFlow::moduleMember("@angular/core", "HostListener").getACall() and
decorator = method.getADecorator().getExpression().flow() and
decorator.getArgument(0).mayHaveStringValue(["window:message", "document:message"]) and
method.getBody() = this and
paramIndex = 0
)
}
/**

View File

@@ -1,5 +1,5 @@
name: codeql/javascript-queries
version: 2.4.0
version: 2.4.1-dev
groups:
- javascript
- queries

View File

@@ -0,0 +1,29 @@
import { Component, HostListener } from '@angular/core';
@Component({ selector: 'app-root' })
class AngularComponent {
// Angular registers this as a `window` message handler via the decorator,
// equivalent to `window.addEventListener('message', ...)`.
@HostListener('window:message', ['$event'])
onWindowMessage(event: MessageEvent): void { // $ Alert - no origin check
eval(event.data);
}
@HostListener('document:message', ['$event'])
onDocumentMessage(event: MessageEvent): void { // $ Alert - no origin check
eval(event.data);
}
@HostListener('window:message', ['$event'])
onCheckedMessage(event: MessageEvent): void { // OK - has an origin check
if (event.origin === 'https://www.example.com') {
eval(event.data);
}
}
// Not a message event, so it is not a postMessage handler.
@HostListener('window:resize', ['$event'])
onResize(event: MessageEvent): void { // OK - not a message handler
eval(event.data);
}
}

View File

@@ -1,3 +1,5 @@
| Angular.ts:8:19:8:23 | event | Postmessage handler has no origin check. |
| Angular.ts:13:21:13:25 | event | Postmessage handler has no origin check. |
| tst.js:11:20:11:24 | event | Postmessage handler has no origin check. |
| tst.js:24:27:24:27 | e | Postmessage handler has no origin check. |
| tst.js:40:27:40:27 | e | Postmessage handler has no origin check. |

View File

@@ -1,4 +1,4 @@
name: codeql/suite-helpers
version: 1.0.52
version: 1.0.53-dev
groups: shared
warnOnImplicitThis: true

View File

@@ -0,0 +1,4 @@
---
category: minorAnalysis
---
* `Flask::FlaskApp::instance()` will now also return instances of subclasses defined in the source tree. Previously, these were filtered out. `Flask::FlaskApp::classRef()` has been deprecated in favor of `Flask::FlaskApp::subclassRef()` since it already returned some subclasses.

View File

@@ -1,5 +1,5 @@
name: codeql/python-all
version: 7.2.0
version: 7.2.1-dev
groups: python
dbscheme: semmlecode.python.dbscheme
extractor: python

View File

@@ -71,14 +71,21 @@ module Flask {
* See https://flask.palletsprojects.com/en/1.1.x/api/#flask.Flask.
*/
module FlaskApp {
/** Gets a reference to the `flask.Flask` class. */
API::Node classRef() {
result = API::moduleImport("flask").getMember("Flask") or
/**
* Gets a reference to the `flask.Flask` class or any subclass.
*
* Deprecated: Use `subclassRef()` instead, this predicate always returned some subclasses.
*/
deprecated API::Node classRef() { result = subclassRef() }
/** Gets a reference to the `flask.Flask` class or any subclass. */
API::Node subclassRef() {
result = API::moduleImport("flask").getMember("Flask").getASubclass*() or
result = ModelOutput::getATypeNode("flask.Flask~Subclass").getASubclass*()
}
/** Gets a reference to an instance of `flask.Flask` (a flask application). */
API::Node instance() { result = classRef().getReturn() }
API::Node instance() { result = subclassRef().getReturn() }
}
/**
@@ -132,7 +139,7 @@ module Flask {
API::Node classRef() {
result = API::moduleImport("flask").getMember("Response")
or
result = [FlaskApp::classRef(), FlaskApp::instance()].getMember("response_class")
result = [FlaskApp::subclassRef(), FlaskApp::instance()].getMember("response_class")
or
result = ModelOutput::getATypeNode("flask.Response~Subclass").getASubclass*()
}

View File

@@ -351,7 +351,7 @@ class DjangoHttpRequest extends FindSubclassesSpec {
class FlaskClass extends FindSubclassesSpec {
FlaskClass() { this = "flask.Flask~Subclass" }
override API::Node getAlreadyModeledClass() { result = Flask::FlaskApp::classRef() }
override API::Node getAlreadyModeledClass() { result = Flask::FlaskApp::subclassRef() }
}
class FlaskBlueprint extends FindSubclassesSpec {

View File

@@ -1,5 +1,5 @@
name: codeql/python-queries
version: 1.8.5
version: 1.8.6-dev
groups:
- python
- queries

View File

@@ -0,0 +1,29 @@
/**
* Defines an InlineExpectationsTest for class instances, that is,
* for any API::Node that is an instance of a class (e.g. `Flask`).
*/
import python
import semmle.python.ApiGraphs
import utils.test.InlineExpectationsTest
private import semmle.python.dataflow.new.internal.PrintNode
signature API::Node getInstanceSig();
module MakeInlineInstanceTest<getInstanceSig/0 getInstance> {
private module InlineInstanceTest implements TestSig {
string getARelevantTag() { result = "instance" }
predicate hasActualResult(Location location, string element, string tag, string value) {
exists(location.getFile().getRelativePath()) and
exists(API::Node instance | instance = getInstance() |
location = instance.getLocation() and
element = prettyNode(instance.asSource()) and
value = "" and
tag = "instance"
)
}
}
import MakeTest<InlineInstanceTest>
}

View File

@@ -0,0 +1,8 @@
import python
import semmle.python.frameworks.Flask
import semmle.python.ApiGraphs
import experimental.meta.InlineInstanceTest
API::Node getInstance() { result = Flask::FlaskApp::instance() }
import MakeInlineInstanceTest<getInstance/0>

View File

@@ -0,0 +1,14 @@
from flask import Flask
class Sub(Flask):
def __init__(self, *args, **kwargs):
Flask.__init__(self, *args, **kwargs)
app = Sub(__name__) # $ instance
@app.route("/") # $ routeSetup="/"
def hello(): # $ requestHandler
return "world" # $ HttpResponse

View File

@@ -1,7 +1,7 @@
import flask
from flask import Flask, request, make_response
app = Flask(__name__)
app = Flask(__name__) # $ instance
@app.route("/") # $ routeSetup="/"
def hello_world(): # $ requestHandler

View File

@@ -3,7 +3,7 @@ import json
from flask import Flask, make_response, jsonify, Response, request, redirect
from werkzeug.datastructures import Headers
app = Flask(__name__)
app = Flask(__name__) # $ instance
@app.route("/html1") # $ routeSetup="/html1"

View File

@@ -1,7 +1,7 @@
import flask
from flask import Flask, make_response
app = Flask(__name__)
app = Flask(__name__) # $ instance
SOME_ROUTE = "/some/route"

View File

@@ -1,5 +1,5 @@
from flask import Flask, request
app = Flask(__name__)
app = Flask(__name__) # $ instance
@app.route("/save-uploaded-file") # $ routeSetup="/save-uploaded-file"
def test_taint(): # $ requestHandler

View File

@@ -1,5 +1,5 @@
from flask import Flask, request, render_template_string, stream_template_string
app = Flask(__name__)
app = Flask(__name__) # $ instance
@app.route("/test_taint/<name>/<int:number>") # $ routeSetup="/test_taint/<name>/<int:number>"
def test_taint(name = "World!", number="0", foo="foo"): # $ requestHandler routedParameter=name routedParameter=number

View File

@@ -1,5 +1,5 @@
from flask import Flask, Response, stream_with_context, render_template_string, stream_template_string
app = Flask(__name__)
app = Flask(__name__) # $ instance
@app.route("/a") # $ routeSetup="/a"
def a(): # $ requestHandler

View File

@@ -1312,6 +1312,244 @@ module QL {
/** Gets a field or child node of this node. */
final override AstNode getAFieldOrChild() { ql_variable_def(this, result) }
}
/** Provides predicates for mapping AST nodes to their named children. */
module PrintAst {
/** Gets a child of `node` returned by the member predicate with the given `name`. If the predicate takes an index argument, `i` is bound to that index, otherwise `i` is `-1` (which is never a valid index). */
AstNode getChild(AstNode node, string name, int i) {
result = node.(AddExpr).getLeft() and i = -1 and name = "getLeft"
or
result = node.(AddExpr).getRight() and i = -1 and name = "getRight"
or
result = node.(AddExpr).getChild() and i = -1 and name = "getChild"
or
result = node.(Aggregate).getChild(i) and name = "getChild"
or
result = node.(AnnotArg).getChild() and i = -1 and name = "getChild"
or
result = node.(Annotation).getArgs(i) and name = "getArgs"
or
result = node.(Annotation).getName() and i = -1 and name = "getName"
or
result = node.(AritylessPredicateExpr).getName() and i = -1 and name = "getName"
or
result = node.(AritylessPredicateExpr).getQualifier() and i = -1 and name = "getQualifier"
or
result = node.(AsExpr).getChild(i) and name = "getChild"
or
result = node.(AsExprs).getChild(i) and name = "getChild"
or
result = node.(Body).getChild() and i = -1 and name = "getChild"
or
result = node.(Bool).getChild() and i = -1 and name = "getChild"
or
result = node.(CallBody).getChild(i) and name = "getChild"
or
result = node.(CallOrUnqualAggExpr).getChild(i) and name = "getChild"
or
result = node.(Charpred).getBody() and i = -1 and name = "getBody"
or
result = node.(Charpred).getChild() and i = -1 and name = "getChild"
or
result = node.(ClassMember).getChild(i) and name = "getChild"
or
result = node.(ClasslessPredicate).getName() and i = -1 and name = "getName"
or
result = node.(ClasslessPredicate).getReturnType() and i = -1 and name = "getReturnType"
or
result = node.(ClasslessPredicate).getChild(i) and name = "getChild"
or
result = node.(CompTerm).getLeft() and i = -1 and name = "getLeft"
or
result = node.(CompTerm).getRight() and i = -1 and name = "getRight"
or
result = node.(CompTerm).getChild() and i = -1 and name = "getChild"
or
result = node.(Conjunction).getLeft() and i = -1 and name = "getLeft"
or
result = node.(Conjunction).getRight() and i = -1 and name = "getRight"
or
result = node.(Dataclass).getExtends(i) and name = "getExtends"
or
result = node.(Dataclass).getInstanceof(i) and name = "getInstanceof"
or
result = node.(Dataclass).getName() and i = -1 and name = "getName"
or
result = node.(Dataclass).getChild(i) and name = "getChild"
or
result = node.(Datatype).getName() and i = -1 and name = "getName"
or
result = node.(Datatype).getChild() and i = -1 and name = "getChild"
or
result = node.(DatatypeBranch).getName() and i = -1 and name = "getName"
or
result = node.(DatatypeBranch).getChild(i) and name = "getChild"
or
result = node.(DatatypeBranches).getChild(i) and name = "getChild"
or
result = node.(Disjunction).getLeft() and i = -1 and name = "getLeft"
or
result = node.(Disjunction).getRight() and i = -1 and name = "getRight"
or
result = node.(ExprAggregateBody).getAsExprs() and i = -1 and name = "getAsExprs"
or
result = node.(ExprAggregateBody).getOrderBys() and i = -1 and name = "getOrderBys"
or
result = node.(ExprAnnotation).getAnnotArg() and i = -1 and name = "getAnnotArg"
or
result = node.(ExprAnnotation).getName() and i = -1 and name = "getName"
or
result = node.(ExprAnnotation).getChild() and i = -1 and name = "getChild"
or
result = node.(Field).getChild() and i = -1 and name = "getChild"
or
result = node.(FullAggregateBody).getAsExprs() and i = -1 and name = "getAsExprs"
or
result = node.(FullAggregateBody).getGuard() and i = -1 and name = "getGuard"
or
result = node.(FullAggregateBody).getOrderBys() and i = -1 and name = "getOrderBys"
or
result = node.(FullAggregateBody).getChild(i) and name = "getChild"
or
result = node.(HigherOrderTerm).getName() and i = -1 and name = "getName"
or
result = node.(HigherOrderTerm).getChild(i) and name = "getChild"
or
result = node.(IfTerm).getCond() and i = -1 and name = "getCond"
or
result = node.(IfTerm).getFirst() and i = -1 and name = "getFirst"
or
result = node.(IfTerm).getSecond() and i = -1 and name = "getSecond"
or
result = node.(Implication).getLeft() and i = -1 and name = "getLeft"
or
result = node.(Implication).getRight() and i = -1 and name = "getRight"
or
result = node.(ImportDirective).getChild(i) and name = "getChild"
or
result = node.(ImportModuleExpr).getQualName(i) and name = "getQualName"
or
result = node.(ImportModuleExpr).getChild() and i = -1 and name = "getChild"
or
result = node.(InExpr).getLeft() and i = -1 and name = "getLeft"
or
result = node.(InExpr).getRight() and i = -1 and name = "getRight"
or
result = node.(InstanceOf).getChild(i) and name = "getChild"
or
result = node.(Literal).getChild() and i = -1 and name = "getChild"
or
result = node.(MemberPredicate).getName() and i = -1 and name = "getName"
or
result = node.(MemberPredicate).getReturnType() and i = -1 and name = "getReturnType"
or
result = node.(MemberPredicate).getChild(i) and name = "getChild"
or
result = node.(Module).getImplements(i) and name = "getImplements"
or
result = node.(Module).getName() and i = -1 and name = "getName"
or
result = node.(Module).getParameter(i) and name = "getParameter"
or
result = node.(Module).getChild(i) and name = "getChild"
or
result = node.(ModuleAliasBody).getChild() and i = -1 and name = "getChild"
or
result = node.(ModuleExpr).getName() and i = -1 and name = "getName"
or
result = node.(ModuleExpr).getChild() and i = -1 and name = "getChild"
or
result = node.(ModuleInstantiation).getName() and i = -1 and name = "getName"
or
result = node.(ModuleInstantiation).getChild(i) and name = "getChild"
or
result = node.(ModuleMember).getChild(i) and name = "getChild"
or
result = node.(ModuleName).getChild() and i = -1 and name = "getChild"
or
result = node.(ModuleParam).getParameter() and i = -1 and name = "getParameter"
or
result = node.(ModuleParam).getSignature() and i = -1 and name = "getSignature"
or
result = node.(MulExpr).getLeft() and i = -1 and name = "getLeft"
or
result = node.(MulExpr).getRight() and i = -1 and name = "getRight"
or
result = node.(MulExpr).getChild() and i = -1 and name = "getChild"
or
result = node.(Negation).getChild() and i = -1 and name = "getChild"
or
result = node.(OrderBy).getChild(i) and name = "getChild"
or
result = node.(OrderBys).getChild(i) and name = "getChild"
or
result = node.(ParExpr).getChild() and i = -1 and name = "getChild"
or
result = node.(PredicateAliasBody).getChild() and i = -1 and name = "getChild"
or
result = node.(PredicateExpr).getChild(i) and name = "getChild"
or
result = node.(PrefixCast).getChild(i) and name = "getChild"
or
result = node.(Ql).getChild(i) and name = "getChild"
or
result = node.(QualifiedRhs).getName() and i = -1 and name = "getName"
or
result = node.(QualifiedRhs).getChild(i) and name = "getChild"
or
result = node.(QualifiedExpr).getChild(i) and name = "getChild"
or
result = node.(Quantified).getExpr() and i = -1 and name = "getExpr"
or
result = node.(Quantified).getFormula() and i = -1 and name = "getFormula"
or
result = node.(Quantified).getRange() and i = -1 and name = "getRange"
or
result = node.(Quantified).getChild(i) and name = "getChild"
or
result = node.(Range).getLower() and i = -1 and name = "getLower"
or
result = node.(Range).getUpper() and i = -1 and name = "getUpper"
or
result = node.(Select).getChild(i) and name = "getChild"
or
result = node.(SetLiteral).getChild(i) and name = "getChild"
or
result = node.(SignatureExpr).getModExpr() and i = -1 and name = "getModExpr"
or
result = node.(SignatureExpr).getPredicate() and i = -1 and name = "getPredicate"
or
result = node.(SignatureExpr).getTypeExpr() and i = -1 and name = "getTypeExpr"
or
result = node.(SpecialCall).getChild() and i = -1 and name = "getChild"
or
result = node.(SuperRef).getChild(i) and name = "getChild"
or
result = node.(TypeAliasBody).getChild() and i = -1 and name = "getChild"
or
result = node.(TypeExpr).getName() and i = -1 and name = "getName"
or
result = node.(TypeExpr).getQualifier() and i = -1 and name = "getQualifier"
or
result = node.(TypeExpr).getChild() and i = -1 and name = "getChild"
or
result = node.(TypeUnionBody).getChild(i) and name = "getChild"
or
result = node.(UnaryExpr).getChild(i) and name = "getChild"
or
result = node.(UnqualAggBody).getAsExprs(i) and name = "getAsExprs"
or
result = node.(UnqualAggBody).getGuard() and i = -1 and name = "getGuard"
or
result = node.(UnqualAggBody).getChild(i) and name = "getChild"
or
result = node.(VarDecl).getChild(i) and name = "getChild"
or
result = node.(VarName).getChild() and i = -1 and name = "getChild"
or
result = node.(Variable).getChild() and i = -1 and name = "getChild"
}
}
}
overlay[local]
@@ -1669,6 +1907,60 @@ module Dbscheme {
/** Gets the name of the primary QL class for this element. */
final override string getAPrimaryQlClass() { result = "Varchar" }
}
/** Provides predicates for mapping AST nodes to their named children. */
module PrintAst {
/** Gets a child of `node` returned by the member predicate with the given `name`. If the predicate takes an index argument, `i` is bound to that index, otherwise `i` is `-1` (which is never a valid index). */
AstNode getChild(AstNode node, string name, int i) {
result = node.(Annotation).getArgsAnnotation() and i = -1 and name = "getArgsAnnotation"
or
result = node.(Annotation).getSimpleAnnotation() and i = -1 and name = "getSimpleAnnotation"
or
result = node.(ArgsAnnotation).getName() and i = -1 and name = "getName"
or
result = node.(ArgsAnnotation).getChild(i) and name = "getChild"
or
result = node.(Branch).getQldoc() and i = -1 and name = "getQldoc"
or
result = node.(Branch).getChild(i) and name = "getChild"
or
result = node.(CaseDecl).getBase() and i = -1 and name = "getBase"
or
result = node.(CaseDecl).getDiscriminator() and i = -1 and name = "getDiscriminator"
or
result = node.(CaseDecl).getChild(i) and name = "getChild"
or
result = node.(ColType).getChild() and i = -1 and name = "getChild"
or
result = node.(Column).getColName() and i = -1 and name = "getColName"
or
result = node.(Column).getColType() and i = -1 and name = "getColType"
or
result = node.(Column).getIsRef() and i = -1 and name = "getIsRef"
or
result = node.(Column).getIsUnique() and i = -1 and name = "getIsUnique"
or
result = node.(Column).getQldoc() and i = -1 and name = "getQldoc"
or
result = node.(Column).getReprType() and i = -1 and name = "getReprType"
or
result = node.(Dbscheme).getChild(i) and name = "getChild"
or
result = node.(Entry).getChild() and i = -1 and name = "getChild"
or
result = node.(ReprType).getChild(i) and name = "getChild"
or
result = node.(Table).getTableName() and i = -1 and name = "getTableName"
or
result = node.(Table).getChild(i) and name = "getChild"
or
result = node.(TableName).getChild() and i = -1 and name = "getChild"
or
result = node.(UnionDecl).getBase() and i = -1 and name = "getBase"
or
result = node.(UnionDecl).getChild(i) and name = "getChild"
}
}
}
overlay[local]
@@ -1803,6 +2095,24 @@ module Blame {
/** Gets the name of the primary QL class for this element. */
final override string getAPrimaryQlClass() { result = "Number" }
}
/** Provides predicates for mapping AST nodes to their named children. */
module PrintAst {
/** Gets a child of `node` returned by the member predicate with the given `name`. If the predicate takes an index argument, `i` is bound to that index, otherwise `i` is `-1` (which is never a valid index). */
AstNode getChild(AstNode node, string name, int i) {
result = node.(BlameEntry).getDate() and i = -1 and name = "getDate"
or
result = node.(BlameEntry).getLine(i) and name = "getLine"
or
result = node.(BlameInfo).getFileEntry(i) and name = "getFileEntry"
or
result = node.(BlameInfo).getToday() and i = -1 and name = "getToday"
or
result = node.(FileEntry).getBlameEntry(i) and name = "getBlameEntry"
or
result = node.(FileEntry).getFileName() and i = -1 and name = "getFileName"
}
}
}
overlay[local]
@@ -1977,4 +2287,22 @@ module JSON {
/** Gets the name of the primary QL class for this element. */
final override string getAPrimaryQlClass() { result = "True" }
}
/** Provides predicates for mapping AST nodes to their named children. */
module PrintAst {
/** Gets a child of `node` returned by the member predicate with the given `name`. If the predicate takes an index argument, `i` is bound to that index, otherwise `i` is `-1` (which is never a valid index). */
AstNode getChild(AstNode node, string name, int i) {
result = node.(Array).getChild(i) and name = "getChild"
or
result = node.(Document).getChild(i) and name = "getChild"
or
result = node.(Object).getChild(i) and name = "getChild"
or
result = node.(Pair).getKey() and i = -1 and name = "getKey"
or
result = node.(Pair).getValue() and i = -1 and name = "getValue"
or
result = node.(String).getChild(i) and name = "getChild"
}
}
}

View File

@@ -1964,6 +1964,340 @@ module Ruby {
/** Gets a field or child node of this node. */
final override AstNode getAFieldOrChild() { ruby_yield_child(this, result) }
}
/** Provides predicates for mapping AST nodes to their named children. */
module PrintAst {
/** Gets a child of `node` returned by the member predicate with the given `name`. If the predicate takes an index argument, `i` is bound to that index, otherwise `i` is `-1` (which is never a valid index). */
AstNode getChild(AstNode node, string name, int i) {
result = node.(Alias).getAlias() and i = -1 and name = "getAlias"
or
result = node.(Alias).getName() and i = -1 and name = "getName"
or
result = node.(AlternativePattern).getAlternatives(i) and name = "getAlternatives"
or
result = node.(ArgumentList).getChild(i) and name = "getChild"
or
result = node.(Array).getChild(i) and name = "getChild"
or
result = node.(ArrayPattern).getClass() and i = -1 and name = "getClass"
or
result = node.(ArrayPattern).getChild(i) and name = "getChild"
or
result = node.(AsPattern).getName() and i = -1 and name = "getName"
or
result = node.(AsPattern).getValue() and i = -1 and name = "getValue"
or
result = node.(Assignment).getLeft() and i = -1 and name = "getLeft"
or
result = node.(Assignment).getRight() and i = -1 and name = "getRight"
or
result = node.(BareString).getChild(i) and name = "getChild"
or
result = node.(BareSymbol).getChild(i) and name = "getChild"
or
result = node.(Begin).getChild(i) and name = "getChild"
or
result = node.(BeginBlock).getChild(i) and name = "getChild"
or
result = node.(Binary).getLeft() and i = -1 and name = "getLeft"
or
result = node.(Binary).getRight() and i = -1 and name = "getRight"
or
result = node.(Block).getBody() and i = -1 and name = "getBody"
or
result = node.(Block).getParameters() and i = -1 and name = "getParameters"
or
result = node.(BlockArgument).getChild() and i = -1 and name = "getChild"
or
result = node.(BlockBody).getChild(i) and name = "getChild"
or
result = node.(BlockParameter).getName() and i = -1 and name = "getName"
or
result = node.(BlockParameters).getLocals(i) and name = "getLocals"
or
result = node.(BlockParameters).getChild(i) and name = "getChild"
or
result = node.(BodyStatement).getChild(i) and name = "getChild"
or
result = node.(Break).getChild() and i = -1 and name = "getChild"
or
result = node.(Call).getArguments() and i = -1 and name = "getArguments"
or
result = node.(Call).getBlock() and i = -1 and name = "getBlock"
or
result = node.(Call).getMethod() and i = -1 and name = "getMethod"
or
result = node.(Call).getOperator() and i = -1 and name = "getOperator"
or
result = node.(Call).getReceiver() and i = -1 and name = "getReceiver"
or
result = node.(Case).getValue() and i = -1 and name = "getValue"
or
result = node.(Case).getChild(i) and name = "getChild"
or
result = node.(CaseMatch).getClauses(i) and name = "getClauses"
or
result = node.(CaseMatch).getElse() and i = -1 and name = "getElse"
or
result = node.(CaseMatch).getValue() and i = -1 and name = "getValue"
or
result = node.(ChainedString).getChild(i) and name = "getChild"
or
result = node.(Class).getBody() and i = -1 and name = "getBody"
or
result = node.(Class).getName() and i = -1 and name = "getName"
or
result = node.(Class).getSuperclass() and i = -1 and name = "getSuperclass"
or
result = node.(Complex).getChild() and i = -1 and name = "getChild"
or
result = node.(Conditional).getAlternative() and i = -1 and name = "getAlternative"
or
result = node.(Conditional).getCondition() and i = -1 and name = "getCondition"
or
result = node.(Conditional).getConsequence() and i = -1 and name = "getConsequence"
or
result = node.(DelimitedSymbol).getChild(i) and name = "getChild"
or
result = node.(DestructuredLeftAssignment).getChild(i) and name = "getChild"
or
result = node.(DestructuredParameter).getChild(i) and name = "getChild"
or
result = node.(Do).getChild(i) and name = "getChild"
or
result = node.(DoBlock).getBody() and i = -1 and name = "getBody"
or
result = node.(DoBlock).getParameters() and i = -1 and name = "getParameters"
or
result = node.(ElementReference).getBlock() and i = -1 and name = "getBlock"
or
result = node.(ElementReference).getObject() and i = -1 and name = "getObject"
or
result = node.(ElementReference).getChild(i) and name = "getChild"
or
result = node.(Else).getChild(i) and name = "getChild"
or
result = node.(Elsif).getAlternative() and i = -1 and name = "getAlternative"
or
result = node.(Elsif).getCondition() and i = -1 and name = "getCondition"
or
result = node.(Elsif).getConsequence() and i = -1 and name = "getConsequence"
or
result = node.(EndBlock).getChild(i) and name = "getChild"
or
result = node.(Ensure).getChild(i) and name = "getChild"
or
result = node.(ExceptionVariable).getChild() and i = -1 and name = "getChild"
or
result = node.(Exceptions).getChild(i) and name = "getChild"
or
result = node.(ExpressionReferencePattern).getValue() and i = -1 and name = "getValue"
or
result = node.(FindPattern).getClass() and i = -1 and name = "getClass"
or
result = node.(FindPattern).getChild(i) and name = "getChild"
or
result = node.(For).getBody() and i = -1 and name = "getBody"
or
result = node.(For).getPattern() and i = -1 and name = "getPattern"
or
result = node.(For).getValue() and i = -1 and name = "getValue"
or
result = node.(Hash).getChild(i) and name = "getChild"
or
result = node.(HashPattern).getClass() and i = -1 and name = "getClass"
or
result = node.(HashPattern).getChild(i) and name = "getChild"
or
result = node.(HashSplatArgument).getChild() and i = -1 and name = "getChild"
or
result = node.(HashSplatParameter).getName() and i = -1 and name = "getName"
or
result = node.(HeredocBody).getChild(i) and name = "getChild"
or
result = node.(If).getAlternative() and i = -1 and name = "getAlternative"
or
result = node.(If).getCondition() and i = -1 and name = "getCondition"
or
result = node.(If).getConsequence() and i = -1 and name = "getConsequence"
or
result = node.(IfGuard).getCondition() and i = -1 and name = "getCondition"
or
result = node.(IfModifier).getBody() and i = -1 and name = "getBody"
or
result = node.(IfModifier).getCondition() and i = -1 and name = "getCondition"
or
result = node.(In).getChild() and i = -1 and name = "getChild"
or
result = node.(InClause).getBody() and i = -1 and name = "getBody"
or
result = node.(InClause).getGuard() and i = -1 and name = "getGuard"
or
result = node.(InClause).getPattern() and i = -1 and name = "getPattern"
or
result = node.(Interpolation).getChild(i) and name = "getChild"
or
result = node.(KeywordParameter).getName() and i = -1 and name = "getName"
or
result = node.(KeywordParameter).getValue() and i = -1 and name = "getValue"
or
result = node.(KeywordPattern).getKey() and i = -1 and name = "getKey"
or
result = node.(KeywordPattern).getValue() and i = -1 and name = "getValue"
or
result = node.(Lambda).getBody() and i = -1 and name = "getBody"
or
result = node.(Lambda).getParameters() and i = -1 and name = "getParameters"
or
result = node.(LambdaParameters).getChild(i) and name = "getChild"
or
result = node.(LeftAssignmentList).getChild(i) and name = "getChild"
or
result = node.(MatchPattern).getPattern() and i = -1 and name = "getPattern"
or
result = node.(MatchPattern).getValue() and i = -1 and name = "getValue"
or
result = node.(Method).getBody() and i = -1 and name = "getBody"
or
result = node.(Method).getName() and i = -1 and name = "getName"
or
result = node.(Method).getParameters() and i = -1 and name = "getParameters"
or
result = node.(MethodParameters).getChild(i) and name = "getChild"
or
result = node.(Module).getBody() and i = -1 and name = "getBody"
or
result = node.(Module).getName() and i = -1 and name = "getName"
or
result = node.(Next).getChild() and i = -1 and name = "getChild"
or
result = node.(OperatorAssignment).getLeft() and i = -1 and name = "getLeft"
or
result = node.(OperatorAssignment).getRight() and i = -1 and name = "getRight"
or
result = node.(OptionalParameter).getName() and i = -1 and name = "getName"
or
result = node.(OptionalParameter).getValue() and i = -1 and name = "getValue"
or
result = node.(Pair).getKey() and i = -1 and name = "getKey"
or
result = node.(Pair).getValue() and i = -1 and name = "getValue"
or
result = node.(ParenthesizedPattern).getChild() and i = -1 and name = "getChild"
or
result = node.(ParenthesizedStatements).getChild(i) and name = "getChild"
or
result = node.(Pattern).getChild() and i = -1 and name = "getChild"
or
result = node.(Program).getChild(i) and name = "getChild"
or
result = node.(Range).getBegin() and i = -1 and name = "getBegin"
or
result = node.(Range).getEnd() and i = -1 and name = "getEnd"
or
result = node.(Rational).getChild() and i = -1 and name = "getChild"
or
result = node.(Redo).getChild() and i = -1 and name = "getChild"
or
result = node.(Regex).getChild(i) and name = "getChild"
or
result = node.(Rescue).getBody() and i = -1 and name = "getBody"
or
result = node.(Rescue).getExceptions() and i = -1 and name = "getExceptions"
or
result = node.(Rescue).getVariable() and i = -1 and name = "getVariable"
or
result = node.(RescueModifier).getBody() and i = -1 and name = "getBody"
or
result = node.(RescueModifier).getHandler() and i = -1 and name = "getHandler"
or
result = node.(RestAssignment).getChild() and i = -1 and name = "getChild"
or
result = node.(Retry).getChild() and i = -1 and name = "getChild"
or
result = node.(Return).getChild() and i = -1 and name = "getChild"
or
result = node.(RightAssignmentList).getChild(i) and name = "getChild"
or
result = node.(ScopeResolution).getName() and i = -1 and name = "getName"
or
result = node.(ScopeResolution).getScope() and i = -1 and name = "getScope"
or
result = node.(Setter).getName() and i = -1 and name = "getName"
or
result = node.(SingletonClass).getBody() and i = -1 and name = "getBody"
or
result = node.(SingletonClass).getValue() and i = -1 and name = "getValue"
or
result = node.(SingletonMethod).getBody() and i = -1 and name = "getBody"
or
result = node.(SingletonMethod).getName() and i = -1 and name = "getName"
or
result = node.(SingletonMethod).getObject() and i = -1 and name = "getObject"
or
result = node.(SingletonMethod).getParameters() and i = -1 and name = "getParameters"
or
result = node.(SplatArgument).getChild() and i = -1 and name = "getChild"
or
result = node.(SplatParameter).getName() and i = -1 and name = "getName"
or
result = node.(String).getChild(i) and name = "getChild"
or
result = node.(StringArray).getChild(i) and name = "getChild"
or
result = node.(Subshell).getChild(i) and name = "getChild"
or
result = node.(Superclass).getChild() and i = -1 and name = "getChild"
or
result = node.(SymbolArray).getChild(i) and name = "getChild"
or
result = node.(TestPattern).getPattern() and i = -1 and name = "getPattern"
or
result = node.(TestPattern).getValue() and i = -1 and name = "getValue"
or
result = node.(Then).getChild(i) and name = "getChild"
or
result = node.(Unary).getOperand() and i = -1 and name = "getOperand"
or
result = node.(Undef).getChild(i) and name = "getChild"
or
result = node.(Unless).getAlternative() and i = -1 and name = "getAlternative"
or
result = node.(Unless).getCondition() and i = -1 and name = "getCondition"
or
result = node.(Unless).getConsequence() and i = -1 and name = "getConsequence"
or
result = node.(UnlessGuard).getCondition() and i = -1 and name = "getCondition"
or
result = node.(UnlessModifier).getBody() and i = -1 and name = "getBody"
or
result = node.(UnlessModifier).getCondition() and i = -1 and name = "getCondition"
or
result = node.(Until).getBody() and i = -1 and name = "getBody"
or
result = node.(Until).getCondition() and i = -1 and name = "getCondition"
or
result = node.(UntilModifier).getBody() and i = -1 and name = "getBody"
or
result = node.(UntilModifier).getCondition() and i = -1 and name = "getCondition"
or
result = node.(VariableReferencePattern).getName() and i = -1 and name = "getName"
or
result = node.(When).getBody() and i = -1 and name = "getBody"
or
result = node.(When).getPattern(i) and name = "getPattern"
or
result = node.(While).getBody() and i = -1 and name = "getBody"
or
result = node.(While).getCondition() and i = -1 and name = "getCondition"
or
result = node.(WhileModifier).getBody() and i = -1 and name = "getBody"
or
result = node.(WhileModifier).getCondition() and i = -1 and name = "getCondition"
or
result = node.(Yield).getChild() and i = -1 and name = "getChild"
}
}
}
overlay[local]
@@ -2107,4 +2441,20 @@ module Erb {
/** Gets a field or child node of this node. */
final override AstNode getAFieldOrChild() { erb_template_child(this, _, result) }
}
/** Provides predicates for mapping AST nodes to their named children. */
module PrintAst {
/** Gets a child of `node` returned by the member predicate with the given `name`. If the predicate takes an index argument, `i` is bound to that index, otherwise `i` is `-1` (which is never a valid index). */
AstNode getChild(AstNode node, string name, int i) {
result = node.(CommentDirective).getChild() and i = -1 and name = "getChild"
or
result = node.(Directive).getChild() and i = -1 and name = "getChild"
or
result = node.(GraphqlDirective).getChild() and i = -1 and name = "getChild"
or
result = node.(OutputDirective).getChild() and i = -1 and name = "getChild"
or
result = node.(Template).getChild(i) and name = "getChild"
}
}
}

View File

@@ -1,5 +1,5 @@
name: codeql/ruby-all
version: 6.0.0
version: 6.0.1-dev
groups: ruby
extractor: ruby
dbscheme: ruby.dbscheme

View File

@@ -1,5 +1,5 @@
name: codeql/ruby-queries
version: 1.6.5
version: 1.6.6-dev
groups:
- ruby
- queries

View File

@@ -1,5 +1,5 @@
name: codeql/rust-all
version: 0.2.16
version: 0.2.17-dev
groups: rust
extractor: rust
dbscheme: rust.dbscheme

View File

@@ -1,5 +1,5 @@
name: codeql/rust-queries
version: 0.1.37
version: 0.1.38-dev
groups:
- rust
- queries

View File

@@ -1,5 +1,5 @@
name: codeql/concepts
version: 0.0.26
version: 0.0.27-dev
groups: shared
library: true
dependencies:

View File

@@ -1,5 +1,5 @@
name: codeql/controlflow
version: 2.0.36
version: 2.0.37-dev
groups: shared
library: true
dependencies:

View File

@@ -1,5 +1,5 @@
name: codeql/dataflow
version: 2.1.8
version: 2.1.9-dev
groups: shared
library: true
dependencies:

View File

@@ -1,5 +1,5 @@
name: codeql/mad
version: 1.0.52
version: 1.0.53-dev
groups: shared
library: true
dependencies:

View File

@@ -1,5 +1,5 @@
name: codeql/namebinding
version: 0.0.1
version: 0.0.2-dev
groups: shared
library: true
dependencies:

View File

@@ -1,5 +1,5 @@
name: codeql/quantum
version: 0.0.30
version: 0.0.31-dev
groups: shared
library: true
dependencies:

View File

@@ -1,5 +1,5 @@
name: codeql/rangeanalysis
version: 1.0.52
version: 1.0.53-dev
groups: shared
library: true
dependencies:

View File

@@ -1,5 +1,5 @@
name: codeql/regex
version: 1.0.52
version: 1.0.53-dev
groups: shared
library: true
dependencies:

View File

@@ -1,5 +1,5 @@
name: codeql/ssa
version: 2.0.28
version: 2.0.29-dev
groups: shared
library: true
dependencies:

View File

@@ -1,5 +1,5 @@
name: codeql/threat-models
version: 1.0.52
version: 1.0.53-dev
library: true
groups: shared
dataExtensions:

View File

@@ -159,6 +159,7 @@ pub fn generate(
));
body.append(&mut ql_gen::convert_nodes(&nodes));
body.push(ql_gen::create_print_ast_module(&nodes));
ql::write(
&mut ql_writer,
&[ql::TopLevel::Module(ql::Module {

View File

@@ -150,12 +150,14 @@ impl fmt::Display for Type<'_> {
pub enum Expression<'a> {
Var(&'a str),
String(&'a str),
Integer(usize),
Integer(i64),
Pred(&'a str, Vec<Expression<'a>>),
And(Vec<Expression<'a>>),
Or(Vec<Expression<'a>>),
Equals(Box<Expression<'a>>, Box<Expression<'a>>),
Dot(Box<Expression<'a>>, &'a str, Vec<Expression<'a>>),
/// A type cast, rendered as `x.(Type)`.
Cast(Box<Expression<'a>>, &'a str),
Aggregate {
name: &'a str,
vars: Vec<FormalParameter<'a>>,
@@ -219,6 +221,7 @@ impl fmt::Display for Expression<'_> {
}
write!(f, ")")
}
Expression::Cast(x, type_name) => write!(f, "{x}.({type_name})"),
Expression::Aggregate {
name,
vars,

View File

@@ -705,7 +705,7 @@ fn create_field_getters<'a>(
),
ql::Expression::Equals(
Box::new(ql::Expression::Var("value")),
Box::new(ql::Expression::Integer(*value)),
Box::new(ql::Expression::Integer(*value as i64)),
),
])
})
@@ -874,3 +874,99 @@ pub fn convert_nodes(nodes: &node_types::NodeTypeMap) -> Vec<ql::TopLevel<'_>> {
classes
}
/// Creates a `PrintAst` module containing a `getChild` predicate that maps each
/// AST node to its children together with the name of the member predicate that
/// produced them (and, for indexed fields, the index). This mirrors the
/// information exposed by `getAFieldOrChild`, but keeps the member predicate
/// name and index so that an AST printer can render labelled edges.
pub fn create_print_ast_module(nodes: &node_types::NodeTypeMap) -> ql::TopLevel<'_> {
let mut disjuncts: Vec<ql::Expression> = Vec::new();
for node in nodes.values() {
if let node_types::EntryKind::Table { name: _, fields } = &node.kind {
for field in fields {
// `ReservedWordInt` fields have string-valued getters, so they
// are not children and are excluded (just as they are from
// `getAFieldOrChild`).
if matches!(
field.type_info,
node_types::FieldTypeInfo::ReservedWordInt(_)
) {
continue;
}
let has_index = matches!(
field.storage,
node_types::Storage::Table {
has_index: true,
..
}
);
let getter_call = ql::Expression::Dot(
Box::new(ql::Expression::Cast(
Box::new(ql::Expression::Var("node")),
&node.ql_class_name,
)),
&field.getter_name,
if has_index {
vec![ql::Expression::Var("i")]
} else {
vec![]
},
);
let mut conjuncts = vec![ql::Expression::Equals(
Box::new(ql::Expression::Var("result")),
Box::new(getter_call),
)];
if !has_index {
conjuncts.push(ql::Expression::Equals(
Box::new(ql::Expression::Var("i")),
Box::new(ql::Expression::Integer(-1)),
));
}
conjuncts.push(ql::Expression::Equals(
Box::new(ql::Expression::Var("name")),
Box::new(ql::Expression::String(&field.getter_name)),
));
disjuncts.push(ql::Expression::And(conjuncts));
}
}
}
let get_child = ql::Predicate {
qldoc: Some(String::from(
"Gets a child of `node` returned by the member predicate with the given `name`. \
If the predicate takes an index argument, `i` is bound to that index, otherwise \
`i` is `-1` (which is never a valid index).",
)),
name: "getChild",
overridden: false,
is_private: false,
is_final: false,
return_type: Some(ql::Type::Normal("AstNode")),
formal_parameters: vec![
ql::FormalParameter {
name: "node",
param_type: ql::Type::Normal("AstNode"),
},
ql::FormalParameter {
name: "name",
param_type: ql::Type::String,
},
ql::FormalParameter {
name: "i",
param_type: ql::Type::Int,
},
],
body: ql::Expression::Or(disjuncts),
overlay: None,
};
ql::TopLevel::Module(ql::Module {
qldoc: Some(String::from(
"Provides predicates for mapping AST nodes to their named children.",
)),
name: "PrintAst",
body: vec![ql::TopLevel::Predicate(get_child)],
overlay: None,
})
}

View File

@@ -1,7 +1,7 @@
name: codeql/tutorial
description: Library for the CodeQL detective tutorials, helping new users learn to
write CodeQL queries.
version: 1.0.52
version: 1.0.53-dev
groups: shared
library: true
warnOnImplicitThis: true

View File

@@ -1,5 +1,5 @@
name: codeql/typeflow
version: 1.0.52
version: 1.0.53-dev
groups: shared
library: true
dependencies:

View File

@@ -1,5 +1,5 @@
name: codeql/typeinference
version: 0.0.33
version: 0.0.34-dev
groups: shared
library: true
dependencies:

View File

@@ -1,5 +1,5 @@
name: codeql/typetracking
version: 2.0.36
version: 2.0.37-dev
groups: shared
library: true
dependencies:

View File

@@ -1,5 +1,5 @@
name: codeql/typos
version: 1.0.52
version: 1.0.53-dev
groups: shared
library: true
warnOnImplicitThis: true

View File

@@ -1,5 +1,5 @@
name: codeql/util
version: 2.0.39
version: 2.0.40-dev
groups: shared
library: true
dependencies: null

View File

@@ -1,5 +1,5 @@
name: codeql/xml
version: 1.0.52
version: 1.0.53-dev
groups: shared
library: true
dependencies:

View File

@@ -1,5 +1,5 @@
name: codeql/yaml
version: 1.0.52
version: 1.0.53-dev
groups: shared
library: true
warnOnImplicitThis: true

View File

@@ -1,5 +1,5 @@
name: codeql/swift-all
version: 6.7.1
version: 6.7.2-dev
groups: swift
extractor: swift
dbscheme: swift.dbscheme

View File

@@ -1,5 +1,5 @@
name: codeql/swift-queries
version: 1.3.5
version: 1.3.6-dev
groups:
- swift
- queries

View File

@@ -0,0 +1,16 @@
/**
* Provides shared predicates related to contextual queries in the code viewer.
*/
private import codeql.files.FileSystem
private import codeql.util.FileSystem
/**
* Returns an appropriately encoded version of a filename `name`
* passed by the VS Code extension in order to coincide with the
* output of `.getFile()` on locatable entities.
*/
cached
File getFileBySourceArchiveName(string name) {
result = IdeContextual<File>::getFileBySourceArchiveName(name)
}

View File

@@ -1439,4 +1439,332 @@ module Unified {
unified_while_stmt_modifier(this, _, result)
}
}
/** Provides predicates for mapping AST nodes to their named children. */
module PrintAst {
/** Gets a child of `node` returned by the member predicate with the given `name`. If the predicate takes an index argument, `i` is bound to that index, otherwise `i` is `-1` (which is never a valid index). */
AstNode getChild(AstNode node, string name, int i) {
result = node.(AccessorDeclaration).getAccessorKind() and i = -1 and name = "getAccessorKind"
or
result = node.(AccessorDeclaration).getBody() and i = -1 and name = "getBody"
or
result = node.(AccessorDeclaration).getModifier(i) and name = "getModifier"
or
result = node.(AccessorDeclaration).getName() and i = -1 and name = "getName"
or
result = node.(AccessorDeclaration).getParameter(i) and name = "getParameter"
or
result = node.(AccessorDeclaration).getType() and i = -1 and name = "getType"
or
result = node.(Argument).getModifier(i) and name = "getModifier"
or
result = node.(Argument).getName() and i = -1 and name = "getName"
or
result = node.(Argument).getValue() and i = -1 and name = "getValue"
or
result = node.(ArrayLiteral).getElement(i) and name = "getElement"
or
result = node.(AssignExpr).getTarget() and i = -1 and name = "getTarget"
or
result = node.(AssignExpr).getValue() and i = -1 and name = "getValue"
or
result = node.(AssociatedTypeDeclaration).getBound() and i = -1 and name = "getBound"
or
result = node.(AssociatedTypeDeclaration).getModifier(i) and name = "getModifier"
or
result = node.(AssociatedTypeDeclaration).getName() and i = -1 and name = "getName"
or
result = node.(BaseType).getModifier(i) and name = "getModifier"
or
result = node.(BaseType).getType() and i = -1 and name = "getType"
or
result = node.(BinaryExpr).getLeft() and i = -1 and name = "getLeft"
or
result = node.(BinaryExpr).getOperator() and i = -1 and name = "getOperator"
or
result = node.(BinaryExpr).getRight() and i = -1 and name = "getRight"
or
result = node.(Block).getStmt(i) and name = "getStmt"
or
result = node.(BoundTypeConstraint).getBound() and i = -1 and name = "getBound"
or
result = node.(BoundTypeConstraint).getType() and i = -1 and name = "getType"
or
result = node.(BreakExpr).getLabel() and i = -1 and name = "getLabel"
or
result = node.(BulkImportingPattern).getModifier(i) and name = "getModifier"
or
result = node.(CallExpr).getArgument(i) and name = "getArgument"
or
result = node.(CallExpr).getCallee() and i = -1 and name = "getCallee"
or
result = node.(CallExpr).getModifier(i) and name = "getModifier"
or
result = node.(CatchClause).getBody() and i = -1 and name = "getBody"
or
result = node.(CatchClause).getGuard() and i = -1 and name = "getGuard"
or
result = node.(CatchClause).getModifier(i) and name = "getModifier"
or
result = node.(CatchClause).getPattern() and i = -1 and name = "getPattern"
or
result = node.(ClassLikeDeclaration).getBaseType(i) and name = "getBaseType"
or
result = node.(ClassLikeDeclaration).getMember(i) and name = "getMember"
or
result = node.(ClassLikeDeclaration).getModifier(i) and name = "getModifier"
or
result = node.(ClassLikeDeclaration).getName() and i = -1 and name = "getName"
or
result = node.(ClassLikeDeclaration).getTypeConstraint(i) and name = "getTypeConstraint"
or
result = node.(ClassLikeDeclaration).getTypeParameter(i) and name = "getTypeParameter"
or
result = node.(CompoundAssignExpr).getOperator() and i = -1 and name = "getOperator"
or
result = node.(CompoundAssignExpr).getTarget() and i = -1 and name = "getTarget"
or
result = node.(CompoundAssignExpr).getValue() and i = -1 and name = "getValue"
or
result = node.(ConstructorDeclaration).getBody() and i = -1 and name = "getBody"
or
result = node.(ConstructorDeclaration).getModifier(i) and name = "getModifier"
or
result = node.(ConstructorDeclaration).getName() and i = -1 and name = "getName"
or
result = node.(ConstructorDeclaration).getParameter(i) and name = "getParameter"
or
result = node.(ConstructorPattern).getConstructor() and i = -1 and name = "getConstructor"
or
result = node.(ConstructorPattern).getElement(i) and name = "getElement"
or
result = node.(ConstructorPattern).getModifier(i) and name = "getModifier"
or
result = node.(ContinueExpr).getLabel() and i = -1 and name = "getLabel"
or
result = node.(DestructorDeclaration).getBody() and i = -1 and name = "getBody"
or
result = node.(DestructorDeclaration).getModifier(i) and name = "getModifier"
or
result = node.(DoWhileStmt).getBody() and i = -1 and name = "getBody"
or
result = node.(DoWhileStmt).getCondition() and i = -1 and name = "getCondition"
or
result = node.(DoWhileStmt).getModifier(i) and name = "getModifier"
or
result = node.(EqualityTypeConstraint).getLeft() and i = -1 and name = "getLeft"
or
result = node.(EqualityTypeConstraint).getRight() and i = -1 and name = "getRight"
or
result = node.(ExprEqualityPattern).getExpr() and i = -1 and name = "getExpr"
or
result = node.(ForEachStmt).getBody() and i = -1 and name = "getBody"
or
result = node.(ForEachStmt).getGuard() and i = -1 and name = "getGuard"
or
result = node.(ForEachStmt).getIterable() and i = -1 and name = "getIterable"
or
result = node.(ForEachStmt).getModifier(i) and name = "getModifier"
or
result = node.(ForEachStmt).getPattern() and i = -1 and name = "getPattern"
or
result = node.(FunctionDeclaration).getBody() and i = -1 and name = "getBody"
or
result = node.(FunctionDeclaration).getModifier(i) and name = "getModifier"
or
result = node.(FunctionDeclaration).getName() and i = -1 and name = "getName"
or
result = node.(FunctionDeclaration).getParameter(i) and name = "getParameter"
or
result = node.(FunctionDeclaration).getReturnType() and i = -1 and name = "getReturnType"
or
result = node.(FunctionDeclaration).getTypeConstraint(i) and name = "getTypeConstraint"
or
result = node.(FunctionDeclaration).getTypeParameter(i) and name = "getTypeParameter"
or
result = node.(FunctionExpr).getBody() and i = -1 and name = "getBody"
or
result = node.(FunctionExpr).getCaptureDeclaration(i) and name = "getCaptureDeclaration"
or
result = node.(FunctionExpr).getModifier(i) and name = "getModifier"
or
result = node.(FunctionExpr).getParameter(i) and name = "getParameter"
or
result = node.(FunctionExpr).getReturnType() and i = -1 and name = "getReturnType"
or
result = node.(FunctionTypeExpr).getParameter(i) and name = "getParameter"
or
result = node.(FunctionTypeExpr).getReturnType() and i = -1 and name = "getReturnType"
or
result = node.(GenericTypeExpr).getBase() and i = -1 and name = "getBase"
or
result = node.(GenericTypeExpr).getTypeArgument(i) and name = "getTypeArgument"
or
result = node.(GuardIfStmt).getCondition() and i = -1 and name = "getCondition"
or
result = node.(GuardIfStmt).getElse() and i = -1 and name = "getElse"
or
result = node.(IfExpr).getCondition() and i = -1 and name = "getCondition"
or
result = node.(IfExpr).getElse() and i = -1 and name = "getElse"
or
result = node.(IfExpr).getThen() and i = -1 and name = "getThen"
or
result = node.(ImportDeclaration).getImportedExpr() and i = -1 and name = "getImportedExpr"
or
result = node.(ImportDeclaration).getModifier(i) and name = "getModifier"
or
result = node.(ImportDeclaration).getPattern() and i = -1 and name = "getPattern"
or
result = node.(InitializerDeclaration).getBody() and i = -1 and name = "getBody"
or
result = node.(InitializerDeclaration).getModifier(i) and name = "getModifier"
or
result = node.(KeyValuePair).getKey() and i = -1 and name = "getKey"
or
result = node.(KeyValuePair).getValue() and i = -1 and name = "getValue"
or
result = node.(LabeledStmt).getLabel() and i = -1 and name = "getLabel"
or
result = node.(LabeledStmt).getStmt() and i = -1 and name = "getStmt"
or
result = node.(MapLiteral).getElement(i) and name = "getElement"
or
result = node.(MemberAccessExpr).getBase() and i = -1 and name = "getBase"
or
result = node.(MemberAccessExpr).getMember() and i = -1 and name = "getMember"
or
result = node.(NameExpr).getIdentifier() and i = -1 and name = "getIdentifier"
or
result = node.(NamePattern).getIdentifier() and i = -1 and name = "getIdentifier"
or
result = node.(NamePattern).getModifier(i) and name = "getModifier"
or
result = node.(NamedTypeExpr).getName() and i = -1 and name = "getName"
or
result = node.(NamedTypeExpr).getQualifier() and i = -1 and name = "getQualifier"
or
result = node.(OperatorSyntaxDeclaration).getFixity() and i = -1 and name = "getFixity"
or
result = node.(OperatorSyntaxDeclaration).getModifier(i) and name = "getModifier"
or
result = node.(OperatorSyntaxDeclaration).getName() and i = -1 and name = "getName"
or
result = node.(OperatorSyntaxDeclaration).getPrecedence() and
i = -1 and
name = "getPrecedence"
or
result = node.(OrPattern).getModifier(i) and name = "getModifier"
or
result = node.(OrPattern).getPattern(i) and name = "getPattern"
or
result = node.(Parameter).getDefault() and i = -1 and name = "getDefault"
or
result = node.(Parameter).getExternalName() and i = -1 and name = "getExternalName"
or
result = node.(Parameter).getModifier(i) and name = "getModifier"
or
result = node.(Parameter).getPattern() and i = -1 and name = "getPattern"
or
result = node.(Parameter).getType() and i = -1 and name = "getType"
or
result = node.(PatternElement).getKey() and i = -1 and name = "getKey"
or
result = node.(PatternElement).getModifier(i) and name = "getModifier"
or
result = node.(PatternElement).getPattern() and i = -1 and name = "getPattern"
or
result = node.(PatternGuardExpr).getPattern() and i = -1 and name = "getPattern"
or
result = node.(PatternGuardExpr).getValue() and i = -1 and name = "getValue"
or
result = node.(ReturnExpr).getValue() and i = -1 and name = "getValue"
or
result = node.(SwitchCase).getBody() and i = -1 and name = "getBody"
or
result = node.(SwitchCase).getGuard() and i = -1 and name = "getGuard"
or
result = node.(SwitchCase).getModifier(i) and name = "getModifier"
or
result = node.(SwitchCase).getPattern() and i = -1 and name = "getPattern"
or
result = node.(SwitchExpr).getCase(i) and name = "getCase"
or
result = node.(SwitchExpr).getModifier(i) and name = "getModifier"
or
result = node.(SwitchExpr).getValue() and i = -1 and name = "getValue"
or
result = node.(ThrowExpr).getValue() and i = -1 and name = "getValue"
or
result = node.(TopLevel).getBody() and i = -1 and name = "getBody"
or
result = node.(TryExpr).getBody() and i = -1 and name = "getBody"
or
result = node.(TryExpr).getCatchClause(i) and name = "getCatchClause"
or
result = node.(TryExpr).getModifier(i) and name = "getModifier"
or
result = node.(TupleExpr).getElement(i) and name = "getElement"
or
result = node.(TuplePattern).getElement(i) and name = "getElement"
or
result = node.(TuplePattern).getModifier(i) and name = "getModifier"
or
result = node.(TupleTypeElement).getName() and i = -1 and name = "getName"
or
result = node.(TupleTypeElement).getType() and i = -1 and name = "getType"
or
result = node.(TupleTypeExpr).getElement(i) and name = "getElement"
or
result = node.(TypeAliasDeclaration).getModifier(i) and name = "getModifier"
or
result = node.(TypeAliasDeclaration).getName() and i = -1 and name = "getName"
or
result = node.(TypeAliasDeclaration).getType() and i = -1 and name = "getType"
or
result = node.(TypeAliasDeclaration).getTypeConstraint(i) and name = "getTypeConstraint"
or
result = node.(TypeAliasDeclaration).getTypeParameter(i) and name = "getTypeParameter"
or
result = node.(TypeCastExpr).getExpr() and i = -1 and name = "getExpr"
or
result = node.(TypeCastExpr).getOperator() and i = -1 and name = "getOperator"
or
result = node.(TypeCastExpr).getType() and i = -1 and name = "getType"
or
result = node.(TypeParameter).getBound() and i = -1 and name = "getBound"
or
result = node.(TypeParameter).getModifier(i) and name = "getModifier"
or
result = node.(TypeParameter).getName() and i = -1 and name = "getName"
or
result = node.(TypeTestExpr).getExpr() and i = -1 and name = "getExpr"
or
result = node.(TypeTestExpr).getOperator() and i = -1 and name = "getOperator"
or
result = node.(TypeTestExpr).getType() and i = -1 and name = "getType"
or
result = node.(TypeTestPattern).getPattern() and i = -1 and name = "getPattern"
or
result = node.(TypeTestPattern).getType() and i = -1 and name = "getType"
or
result = node.(UnaryExpr).getOperand() and i = -1 and name = "getOperand"
or
result = node.(UnaryExpr).getOperator() and i = -1 and name = "getOperator"
or
result = node.(VariableDeclaration).getModifier(i) and name = "getModifier"
or
result = node.(VariableDeclaration).getPattern() and i = -1 and name = "getPattern"
or
result = node.(VariableDeclaration).getType() and i = -1 and name = "getType"
or
result = node.(VariableDeclaration).getValue() and i = -1 and name = "getValue"
or
result = node.(WhileStmt).getBody() and i = -1 and name = "getBody"
or
result = node.(WhileStmt).getCondition() and i = -1 and name = "getCondition"
or
result = node.(WhileStmt).getModifier(i) and name = "getModifier"
}
}
}

View File

@@ -0,0 +1,96 @@
/** Provides a configurable query for printing AST nodes */
private import unified
/**
* The query can extend this class to control which nodes are printed.
*/
class PrintAstConfiguration extends string {
PrintAstConfiguration() { this = "PrintAstConfiguration" }
/**
* Holds if the given node should be printed.
*/
predicate shouldPrintNode(AstNode n) { not n instanceof TriviaToken }
/**
* Holds if the given edge should be printed.
*/
predicate shouldPrintAstEdge(AstNode parent, string edgeName, AstNode child) {
exists(string name, int i |
child = PrintAst::getChild(parent, name, i) and
(if i = -1 then edgeName = name else edgeName = name + "(" + i + ")")
)
}
}
private predicate shouldPrintNode(AstNode n) {
any(PrintAstConfiguration config).shouldPrintNode(n)
}
private predicate shouldPrintAstEdge(AstNode parent, string edgeName, AstNode child) {
any(PrintAstConfiguration config).shouldPrintAstEdge(parent, edgeName, child) and
shouldPrintNode(parent) and
shouldPrintNode(child)
}
/**
* Get an alias for the predicate `name` to use for ordering purposes, to control where
* in the list of children it should appear.
*/
private string reorderName1(string name) { name = "getModifier" and result = "00_getModifier" }
bindingset[name]
private string reorderName(string name) {
result = reorderName1(name)
or
not exists(reorderName1(name)) and
result = name
}
class PrintAstNode extends AstNode {
final int getOrder() {
this =
rank[result](AstNode parent, AstNode child, string name, int i |
child = PrintAst::getChild(parent, name, i)
|
child order by reorderName(name), i
)
}
final string getProperty(string key) {
key = "semmle.label" and
result = this.toString()
or
key = "semmle.order" and result = this.getOrder().toString()
}
}
/**
* Holds if `node` belongs to the output tree, and its property `key` has the
* given `value`.
*/
query predicate nodes(PrintAstNode node, string key, string value) {
shouldPrintNode(node) and
value = node.getProperty(key)
}
/**
* Holds if `target` is a child of `source` in the AST, and property `key` of
* the edge has the given `value`.
*/
query predicate edges(PrintAstNode source, PrintAstNode target, string key, string value) {
key = "semmle.label" and
shouldPrintAstEdge(source, value, target)
or
key = "semmle.order" and
shouldPrintAstEdge(source, _, target) and
value = target.getProperty("semmle.order")
}
/**
* Holds if property `key` of the graph has the given `value`.
*/
query predicate graphProperties(string key, string value) {
key = "semmle.graphKind" and value = "tree"
}

View File

@@ -0,0 +1,27 @@
/**
* @name Print AST
* @description Produces a representation of a file's Abstract Syntax Tree.
* This query is used by the VS Code extension.
* @id unified/print-ast
* @kind graph
* @tags ide-contextual-queries/print-ast
*/
private import codeql.IDEContextual
private import unified
private import codeql.unified.printAst
/**
* The source file to generate an AST from.
*/
external string selectedSourceFile();
/**
* A configuration that only prints nodes in the selected source file.
*/
class Cfg extends PrintAstConfiguration {
override predicate shouldPrintNode(AstNode n) {
super.shouldPrintNode(n) and
n.getLocation().getFile() = getFileBySourceArchiveName(selectedSourceFile())
}
}