mirror of
https://github.com/github/codeql.git
synced 2026-05-05 13:45:19 +02:00
Merge branch 'main' into feature/SSRF
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
{ "provide": [ "ql/src/qlpack.yml",
|
||||
"ql/lib/qlpack.yml",
|
||||
"ql/examples/qlpack.yml",
|
||||
"ql/test/qlpack.yml",
|
||||
"upgrades/qlpack.yml",
|
||||
|
||||
2
.github/workflows/codeqltest.yml
vendored
2
.github/workflows/codeqltest.yml
vendored
@@ -98,6 +98,8 @@ jobs:
|
||||
test-win:
|
||||
name: Test Windows
|
||||
runs-on: windows-latest
|
||||
env:
|
||||
CODEQL_LOCK_MODE: verify
|
||||
steps:
|
||||
- name: Set up Go 1.17
|
||||
uses: actions/setup-go@v1
|
||||
|
||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -23,3 +23,6 @@ tools/osx64
|
||||
tools/win64
|
||||
tools/tokenizer.jar
|
||||
main
|
||||
|
||||
# QL pack output directories
|
||||
.codeql
|
||||
19
Makefile
19
Makefile
@@ -1,4 +1,4 @@
|
||||
all: extractor ql/src/go.dbscheme
|
||||
all: extractor ql/lib/go.dbscheme install-deps
|
||||
|
||||
ifeq ($(OS),Windows_NT)
|
||||
EXE = .exe
|
||||
@@ -37,6 +37,9 @@ check-formatting:
|
||||
find ql -iregex '.*\.qll?' -print0 | xargs -0 codeql query format --check-only
|
||||
test -z "$$(find . -path '**/vendor' -prune -or -type f -iname '*.go' ! -empty -print0 | xargs -0 grep -L "//\s*autoformat-ignore" | xargs gofmt -l)"
|
||||
|
||||
install-deps:
|
||||
bash scripts/install-deps.sh $(CODEQL_LOCK_MODE)
|
||||
|
||||
ifeq ($(QHELP_OUT_DIR),)
|
||||
# If not otherwise specified, compile qhelp to markdown in place
|
||||
QHELP_OUT_DIR := ql/src
|
||||
@@ -73,12 +76,12 @@ tools-win64: $(addsuffix .exe,$(addprefix tools/win64/,$(BINARIES)))
|
||||
$(addsuffix .exe,$(addprefix tools/win64/,$(BINARIES))):
|
||||
env GOOS=windows GOARCH=amd64 go build -mod=vendor -o $@ ./extractor/cli/$(basename $(@F))
|
||||
|
||||
.PHONY: extractor-common extractor extractor-full
|
||||
extractor-common: codeql-extractor.yml LICENSE ql/src/go.dbscheme \
|
||||
.PHONY: extractor-common extractor extractor-full install-deps
|
||||
extractor-common: codeql-extractor.yml LICENSE ql/lib/go.dbscheme \
|
||||
tools/tokenizer.jar $(CODEQL_TOOLS)
|
||||
rm -rf $(EXTRACTOR_PACK_OUT)
|
||||
mkdir -p $(EXTRACTOR_PACK_OUT)
|
||||
cp codeql-extractor.yml LICENSE ql/src/go.dbscheme ql/src/go.dbscheme.stats $(EXTRACTOR_PACK_OUT)
|
||||
cp codeql-extractor.yml LICENSE ql/lib/go.dbscheme ql/lib/go.dbscheme.stats $(EXTRACTOR_PACK_OUT)
|
||||
mkdir $(EXTRACTOR_PACK_OUT)/tools
|
||||
cp -r tools/tokenizer.jar $(CODEQL_TOOLS) $(EXTRACTOR_PACK_OUT)/tools
|
||||
|
||||
@@ -99,7 +102,7 @@ tools/net/sourceforge/pmd/cpd/GoLanguage.class: extractor/net/sourceforge/pmd/cp
|
||||
rm tools/net/sourceforge/pmd/cpd/TokenEntry.class
|
||||
rm tools/net/sourceforge/pmd/cpd/Tokenizer.class
|
||||
|
||||
ql/src/go.dbscheme: tools/$(CODEQL_PLATFORM)/go-gen-dbscheme$(EXE)
|
||||
ql/lib/go.dbscheme: tools/$(CODEQL_PLATFORM)/go-gen-dbscheme$(EXE)
|
||||
$< $@
|
||||
|
||||
build/stats/src.stamp:
|
||||
@@ -108,7 +111,7 @@ build/stats/src.stamp:
|
||||
git -C $(@D)/src checkout 9b52d559c609 -q
|
||||
touch $@
|
||||
|
||||
ql/src/go.dbscheme.stats: ql/src/go.dbscheme build/stats/src.stamp extractor
|
||||
ql/lib/go.dbscheme.stats: ql/lib/go.dbscheme build/stats/src.stamp extractor
|
||||
rm -rf build/stats/database
|
||||
codeql database create -l go -s build/stats/src -j4 --search-path . build/stats/database
|
||||
codeql dataset measure -o $@ build/stats/database/db-go
|
||||
@@ -121,9 +124,9 @@ test: all build/testdb/check-upgrade-path
|
||||
bash extractor-smoke-test/test.sh || (echo "Extractor smoke test FAILED"; exit 1)
|
||||
|
||||
.PHONY: build/testdb/check-upgrade-path
|
||||
build/testdb/check-upgrade-path : build/testdb/go.dbscheme ql/src/go.dbscheme
|
||||
build/testdb/check-upgrade-path : build/testdb/go.dbscheme ql/lib/go.dbscheme
|
||||
codeql dataset upgrade build/testdb --search-path upgrades
|
||||
diff -q build/testdb/go.dbscheme ql/src/go.dbscheme
|
||||
diff -q build/testdb/go.dbscheme ql/lib/go.dbscheme
|
||||
|
||||
.PHONY: build/testdb/go.dbscheme
|
||||
build/testdb/go.dbscheme: upgrades/initial/go.dbscheme
|
||||
|
||||
@@ -17,7 +17,11 @@ repository](https://github.com/github/codeql).
|
||||
|
||||
## Installation
|
||||
|
||||
Simply clone this repository. There are no external dependencies.
|
||||
Clone this repository.
|
||||
|
||||
Run `scripts/install-deps.sh`. This will ensure that the necessary external CodeQL packs are
|
||||
downloaded to your machine. You will need to re-run this script whenever you pull new commits from
|
||||
the repo.
|
||||
|
||||
If you want to use the CodeQL extension for Visual Studio Code, import this repository into your VS
|
||||
Code workspace.
|
||||
|
||||
@@ -1159,6 +1159,7 @@ var ErrorsTable = NewTable("errors",
|
||||
IntColumn("idx"),
|
||||
).KeySet("package", "idx")
|
||||
|
||||
// HasEllipsisTable is the table containing all call expressions that have ellipses
|
||||
var HasEllipsisTable = NewTable("has_ellipsis",
|
||||
EntityColumn(CallOrConversionExpr, "id"),
|
||||
)
|
||||
|
||||
4
ql/examples/qlpack.lock.yml
Normal file
4
ql/examples/qlpack.lock.yml
Normal file
@@ -0,0 +1,4 @@
|
||||
---
|
||||
dependencies: {}
|
||||
compiled: false
|
||||
lockVersion: 1.0.0
|
||||
@@ -1,3 +1,4 @@
|
||||
name: codeql-go-examples
|
||||
version: 0.0.0
|
||||
libraryPathDependencies: codeql-go
|
||||
name: codeql/go-examples
|
||||
version: 0.0.2
|
||||
dependencies:
|
||||
codeql/go-all: ^0.0.2
|
||||
|
||||
4
ql/lib/qlpack.lock.yml
Normal file
4
ql/lib/qlpack.lock.yml
Normal file
@@ -0,0 +1,4 @@
|
||||
---
|
||||
dependencies: {}
|
||||
compiled: false
|
||||
lockVersion: 1.0.0
|
||||
7
ql/lib/qlpack.yml
Normal file
7
ql/lib/qlpack.yml
Normal file
@@ -0,0 +1,7 @@
|
||||
name: codeql/go-all
|
||||
version: 0.0.2
|
||||
dbscheme: go.dbscheme
|
||||
extractor: go
|
||||
library: true
|
||||
dependencies:
|
||||
codeql/go-upgrades: ^0.0.2
|
||||
@@ -60,10 +60,10 @@ class CommentGroup extends @comment_group, AstNode {
|
||||
Comment getComment(int i) { comments(result, _, this, i, _) }
|
||||
|
||||
/** Gets a comment in this group. */
|
||||
Comment getAComment() { result = getComment(_) }
|
||||
Comment getAComment() { result = this.getComment(_) }
|
||||
|
||||
/** Gets the number of comments in this group. */
|
||||
int getNumComment() { result = count(getAComment()) }
|
||||
int getNumComment() { result = count(this.getAComment()) }
|
||||
|
||||
override string toString() { result = "comment group" }
|
||||
|
||||
@@ -219,8 +219,8 @@ class BuildConstraintComment extends LineComment {
|
||||
override string getAPrimaryQlClass() { result = "BuildConstraintComment" }
|
||||
|
||||
/** Gets the body of this build constraint. */
|
||||
string getConstraintBody() { result = getText().splitAt("build ", 1) }
|
||||
string getConstraintBody() { result = this.getText().splitAt("build ", 1) }
|
||||
|
||||
/** Gets a disjunct of this build constraint. */
|
||||
string getADisjunct() { result = getConstraintBody().splitAt(" ") }
|
||||
string getADisjunct() { result = this.getConstraintBody().splitAt(" ") }
|
||||
}
|
||||
@@ -42,12 +42,12 @@ class GenDecl extends @gendecl, Decl, Documentable {
|
||||
Spec getSpec(int i) { specs(result, _, this, i) }
|
||||
|
||||
/** Gets a declaration specifier in this declaration. */
|
||||
Spec getASpec() { result = getSpec(_) }
|
||||
Spec getASpec() { result = this.getSpec(_) }
|
||||
|
||||
/** Gets the number of declaration specifiers in this declaration. */
|
||||
int getNumSpec() { result = count(getASpec()) }
|
||||
int getNumSpec() { result = count(this.getASpec()) }
|
||||
|
||||
override predicate mayHaveSideEffects() { getASpec().mayHaveSideEffects() }
|
||||
override predicate mayHaveSideEffects() { this.getASpec().mayHaveSideEffects() }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "GenDecl" }
|
||||
}
|
||||
@@ -130,7 +130,7 @@ class FuncDef extends @funcdef, StmtParent, ExprParent {
|
||||
/**
|
||||
* Gets the number of parameters of this function.
|
||||
*/
|
||||
int getNumParameter() { result = count(getAParameter()) }
|
||||
int getNumParameter() { result = count(this.getAParameter()) }
|
||||
|
||||
/**
|
||||
* Gets a call to this function.
|
||||
@@ -145,16 +145,16 @@ class FuncDef extends @funcdef, StmtParent, ExprParent {
|
||||
*/
|
||||
class FuncDecl extends @funcdecl, Decl, Documentable, FuncDef {
|
||||
/** Gets the identifier denoting the name of this function. */
|
||||
Ident getNameExpr() { result = getChildExpr(0) }
|
||||
Ident getNameExpr() { result = this.getChildExpr(0) }
|
||||
|
||||
override string getName() { result = getNameExpr().getName() }
|
||||
override string getName() { result = this.getNameExpr().getName() }
|
||||
|
||||
override FuncTypeExpr getTypeExpr() { result = getChildExpr(1) }
|
||||
override FuncTypeExpr getTypeExpr() { result = this.getChildExpr(1) }
|
||||
|
||||
override SignatureType getType() { result = getNameExpr().getType() }
|
||||
override SignatureType getType() { result = this.getNameExpr().getType() }
|
||||
|
||||
/** Gets the body of this function, if any. */
|
||||
override BlockStmt getBody() { result = getChildStmt(2) }
|
||||
override BlockStmt getBody() { result = this.getChildStmt(2) }
|
||||
|
||||
/** Gets the function declared by this function declaration. */
|
||||
DeclaredFunction getFunction() { this = result.getFuncDecl() }
|
||||
@@ -196,7 +196,7 @@ class MethodDecl extends FuncDecl {
|
||||
*
|
||||
* is `*Rectangle`.
|
||||
*/
|
||||
Type getReceiverType() { result = getReceiverDecl().getType() }
|
||||
Type getReceiverType() { result = this.getReceiverDecl().getType() }
|
||||
|
||||
/**
|
||||
* Gets the receiver base type of this method.
|
||||
@@ -210,8 +210,8 @@ class MethodDecl extends FuncDecl {
|
||||
* is `Rectangle`.
|
||||
*/
|
||||
NamedType getReceiverBaseType() {
|
||||
result = getReceiverType() or
|
||||
result = getReceiverType().(PointerType).getBaseType()
|
||||
result = this.getReceiverType() or
|
||||
result = this.getReceiverType().(PointerType).getBaseType()
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -261,16 +261,16 @@ class Spec extends @spec, ExprParent, Documentable {
|
||||
*/
|
||||
class ImportSpec extends @importspec, Spec {
|
||||
/** Gets the identifier denoting the imported name. */
|
||||
Ident getNameExpr() { result = getChildExpr(0) }
|
||||
Ident getNameExpr() { result = this.getChildExpr(0) }
|
||||
|
||||
/** Gets the imported name. */
|
||||
string getName() { result = getNameExpr().getName() }
|
||||
string getName() { result = this.getNameExpr().getName() }
|
||||
|
||||
/** Gets the string literal denoting the imported path. */
|
||||
StringLit getPathExpr() { result = getChildExpr(1) }
|
||||
StringLit getPathExpr() { result = this.getChildExpr(1) }
|
||||
|
||||
/** Gets the imported path. */
|
||||
string getPath() { result = getPathExpr().getValue() }
|
||||
string getPath() { result = this.getPathExpr().getValue() }
|
||||
|
||||
override string toString() { result = "import specifier" }
|
||||
|
||||
@@ -284,41 +284,41 @@ class ValueSpec extends @valuespec, Spec {
|
||||
/** Gets the identifier denoting the `i`th name declared by this specifier (0-based). */
|
||||
Ident getNameExpr(int i) {
|
||||
i >= 0 and
|
||||
result = getChildExpr(-(i + 1))
|
||||
result = this.getChildExpr(-(i + 1))
|
||||
}
|
||||
|
||||
/** Holds if this specifier is a part of a constant declaration. */
|
||||
predicate isConstSpec() { this.getParentDecl() instanceof ConstDecl }
|
||||
|
||||
/** Gets an identifier denoting a name declared by this specifier. */
|
||||
Ident getANameExpr() { result = getNameExpr(_) }
|
||||
Ident getANameExpr() { result = this.getNameExpr(_) }
|
||||
|
||||
/** Gets the `i`th name declared by this specifier (0-based). */
|
||||
string getName(int i) { result = getNameExpr(i).getName() }
|
||||
string getName(int i) { result = this.getNameExpr(i).getName() }
|
||||
|
||||
/** Gets a name declared by this specifier. */
|
||||
string getAName() { result = getName(_) }
|
||||
string getAName() { result = this.getName(_) }
|
||||
|
||||
/** Gets the number of names declared by this specifier. */
|
||||
int getNumName() { result = count(getANameExpr()) }
|
||||
int getNumName() { result = count(this.getANameExpr()) }
|
||||
|
||||
/** Gets the expression denoting the type of the symbols declared by this specifier. */
|
||||
Expr getTypeExpr() { result = getChildExpr(0) }
|
||||
Expr getTypeExpr() { result = this.getChildExpr(0) }
|
||||
|
||||
/** Gets the `i`th initializer of this specifier (0-based). */
|
||||
Expr getInit(int i) {
|
||||
i >= 0 and
|
||||
result = getChildExpr(i + 1)
|
||||
result = this.getChildExpr(i + 1)
|
||||
}
|
||||
|
||||
/** Gets an initializer of this specifier. */
|
||||
Expr getAnInit() { result = getInit(_) }
|
||||
Expr getAnInit() { result = this.getInit(_) }
|
||||
|
||||
/** Gets the number of initializers of this specifier. */
|
||||
int getNumInit() { result = count(getAnInit()) }
|
||||
int getNumInit() { result = count(this.getAnInit()) }
|
||||
|
||||
/** Gets the unique initializer of this specifier, if there is only one. */
|
||||
Expr getInit() { getNumInit() = 1 and result = getInit(0) }
|
||||
Expr getInit() { this.getNumInit() = 1 and result = this.getInit(0) }
|
||||
|
||||
/**
|
||||
* Gets the specifier that contains the initializers for this specifier.
|
||||
@@ -349,12 +349,12 @@ class ValueSpec extends @valuespec, Spec {
|
||||
/** Holds if this specifier initializes `name` to the value of `init`. */
|
||||
predicate initializes(string name, Expr init) {
|
||||
exists(int i |
|
||||
name = getName(i) and
|
||||
init = getEffectiveInit(i)
|
||||
name = this.getName(i) and
|
||||
init = this.getEffectiveInit(i)
|
||||
)
|
||||
}
|
||||
|
||||
override predicate mayHaveSideEffects() { getAnInit().mayHaveSideEffects() }
|
||||
override predicate mayHaveSideEffects() { this.getAnInit().mayHaveSideEffects() }
|
||||
|
||||
override string toString() { result = "value declaration specifier" }
|
||||
|
||||
@@ -375,15 +375,15 @@ class ValueSpec extends @valuespec, Spec {
|
||||
*/
|
||||
class TypeSpec extends @typespec, Spec {
|
||||
/** Gets the identifier denoting the name of the declared type. */
|
||||
Ident getNameExpr() { result = getChildExpr(0) }
|
||||
Ident getNameExpr() { result = this.getChildExpr(0) }
|
||||
|
||||
/** Gets the name of the declared type. */
|
||||
string getName() { result = getNameExpr().getName() }
|
||||
string getName() { result = this.getNameExpr().getName() }
|
||||
|
||||
/**
|
||||
* Gets the expression denoting the underlying type to which the newly declared type is bound.
|
||||
*/
|
||||
Expr getTypeExpr() { result = getChildExpr(1) }
|
||||
Expr getTypeExpr() { result = this.getChildExpr(1) }
|
||||
|
||||
override string toString() { result = "type declaration specifier" }
|
||||
|
||||
@@ -420,12 +420,12 @@ class FieldBase extends @field, ExprParent {
|
||||
/**
|
||||
* Gets the expression representing the type of the fields declared in this declaration.
|
||||
*/
|
||||
Expr getTypeExpr() { result = getChildExpr(0) }
|
||||
Expr getTypeExpr() { result = this.getChildExpr(0) }
|
||||
|
||||
/**
|
||||
* Gets the type of the fields declared in this declaration.
|
||||
*/
|
||||
Type getType() { result = getTypeExpr().getType() }
|
||||
Type getType() { result = this.getTypeExpr().getType() }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -442,17 +442,17 @@ class FieldDecl extends FieldBase, Documentable, ExprParent {
|
||||
*/
|
||||
Expr getNameExpr(int i) {
|
||||
i >= 0 and
|
||||
result = getChildExpr(i + 1)
|
||||
result = this.getChildExpr(i + 1)
|
||||
}
|
||||
|
||||
/** Gets the tag expression of this field declaration, if any. */
|
||||
Expr getTag() { result = getChildExpr(-1) }
|
||||
Expr getTag() { result = this.getChildExpr(-1) }
|
||||
|
||||
/** Gets the struct type expression to which this field declaration belongs. */
|
||||
StructTypeExpr getDeclaringStructTypeExpr() { result = st }
|
||||
|
||||
/** Gets the struct type to which this field declaration belongs. */
|
||||
StructType getDeclaringType() { result = getDeclaringStructTypeExpr().getType() }
|
||||
StructType getDeclaringType() { result = this.getDeclaringStructTypeExpr().getType() }
|
||||
|
||||
override string toString() { result = "field declaration" }
|
||||
|
||||
@@ -485,7 +485,7 @@ class ParameterOrResultDecl extends FieldBase, Documentable, ExprParent {
|
||||
/**
|
||||
* Gets the function to which this declaration belongs.
|
||||
*/
|
||||
FuncDef getFunction() { result.getTypeExpr() = getFunctionTypeExpr() }
|
||||
FuncDef getFunction() { result.getTypeExpr() = this.getFunctionTypeExpr() }
|
||||
|
||||
/**
|
||||
* Gets the expression representing the name of the `i`th variable declared in this declaration
|
||||
@@ -493,13 +493,13 @@ class ParameterOrResultDecl extends FieldBase, Documentable, ExprParent {
|
||||
*/
|
||||
Expr getNameExpr(int i) {
|
||||
i >= 0 and
|
||||
result = getChildExpr(i + 1)
|
||||
result = this.getChildExpr(i + 1)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an expression representing the name of a variable declared in this declaration.
|
||||
*/
|
||||
Expr getANameExpr() { result = getNameExpr(_) }
|
||||
Expr getANameExpr() { result = this.getNameExpr(_) }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -535,7 +535,7 @@ class ReceiverDecl extends FieldBase, Documentable, ExprParent {
|
||||
/**
|
||||
* Gets the expression representing the name of the receiver declared in this declaration.
|
||||
*/
|
||||
Expr getNameExpr() { result = getChildExpr(1) }
|
||||
Expr getNameExpr() { result = this.getChildExpr(1) }
|
||||
|
||||
override string toString() { result = "receiver declaration" }
|
||||
|
||||
@@ -586,7 +586,7 @@ class InterfaceMemberSpec extends FieldBase, Documentable, ExprParent {
|
||||
class MethodSpec extends InterfaceMemberSpec {
|
||||
Expr name;
|
||||
|
||||
MethodSpec() { name = getChildExpr(1) }
|
||||
MethodSpec() { name = this.getChildExpr(1) }
|
||||
|
||||
/**
|
||||
* Gets the expression representing the name of the method declared in this specification.
|
||||
@@ -602,7 +602,7 @@ class MethodSpec extends InterfaceMemberSpec {
|
||||
* An embedding specification in an interface.
|
||||
*/
|
||||
class EmbeddingSpec extends InterfaceMemberSpec {
|
||||
EmbeddingSpec() { not exists(getChildExpr(1)) }
|
||||
EmbeddingSpec() { not exists(this.getChildExpr(1)) }
|
||||
|
||||
override string toString() { result = "interface embedding" }
|
||||
|
||||
@@ -138,7 +138,9 @@ class Expr extends @expr, ExprParent {
|
||||
*
|
||||
* Memory allocation is not considered an observable side effect.
|
||||
*/
|
||||
predicate mayHaveSideEffects() { mayHaveOwnSideEffects() or getAChildExpr().mayHaveSideEffects() }
|
||||
predicate mayHaveSideEffects() {
|
||||
this.mayHaveOwnSideEffects() or this.getAChildExpr().mayHaveSideEffects()
|
||||
}
|
||||
|
||||
override string toString() { result = "expression" }
|
||||
}
|
||||
@@ -179,9 +181,9 @@ class Ident extends @ident, Expr {
|
||||
predicate declares(Entity e) { defs(this, e) }
|
||||
|
||||
/** Holds if this identifier refers to (that is, uses, defines or declares) `e`. */
|
||||
predicate refersTo(Entity e) { uses(e) or declares(e) }
|
||||
predicate refersTo(Entity e) { this.uses(e) or this.declares(e) }
|
||||
|
||||
override string toString() { result = getName() }
|
||||
override string toString() { result = this.getName() }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "Ident" }
|
||||
}
|
||||
@@ -196,7 +198,7 @@ class Ident extends @ident, Expr {
|
||||
* ```
|
||||
*/
|
||||
class BlankIdent extends Ident {
|
||||
BlankIdent() { getName() = "_" }
|
||||
BlankIdent() { this.getName() = "_" }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "BlankIdent" }
|
||||
}
|
||||
@@ -213,7 +215,7 @@ class BlankIdent extends Ident {
|
||||
*/
|
||||
class Ellipsis extends @ellipsis, Expr {
|
||||
/** Gets the operand of this ellipsis expression. */
|
||||
Expr getOperand() { result = getChildExpr(0) }
|
||||
Expr getOperand() { result = this.getChildExpr(0) }
|
||||
|
||||
override string toString() { result = "..." }
|
||||
|
||||
@@ -263,7 +265,7 @@ class BasicLit extends @basiclit, Literal {
|
||||
|
||||
override predicate isPlatformIndependentConstant() { any() }
|
||||
|
||||
override string toString() { result = getText() }
|
||||
override string toString() { result = this.getText() }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -358,12 +360,12 @@ class StringLit extends @stringlit, BasicLit {
|
||||
* ```
|
||||
*/
|
||||
class FuncLit extends @funclit, Literal, StmtParent, FuncDef {
|
||||
override FuncTypeExpr getTypeExpr() { result = getChildExpr(0) }
|
||||
override FuncTypeExpr getTypeExpr() { result = this.getChildExpr(0) }
|
||||
|
||||
override SignatureType getType() { result = Literal.super.getType() }
|
||||
|
||||
/** Gets the body of this function literal. */
|
||||
override BlockStmt getBody() { result = getChildStmt(1) }
|
||||
override BlockStmt getBody() { result = this.getChildStmt(1) }
|
||||
|
||||
override predicate isPlatformIndependentConstant() { any() }
|
||||
|
||||
@@ -384,32 +386,32 @@ class FuncLit extends @funclit, Literal, StmtParent, FuncDef {
|
||||
*/
|
||||
class CompositeLit extends @compositelit, Literal {
|
||||
/** Gets the expression representing the type of this composite literal. */
|
||||
Expr getTypeExpr() { result = getChildExpr(0) }
|
||||
Expr getTypeExpr() { result = this.getChildExpr(0) }
|
||||
|
||||
/** Gets the `i`th element of this composite literal (0-based). */
|
||||
Expr getElement(int i) {
|
||||
i >= 0 and
|
||||
result = getChildExpr(i + 1)
|
||||
result = this.getChildExpr(i + 1)
|
||||
}
|
||||
|
||||
/** Gets an element of this composite literal. */
|
||||
Expr getAnElement() { result = getElement(_) }
|
||||
Expr getAnElement() { result = this.getElement(_) }
|
||||
|
||||
/** Gets the number of elements in this composite literal. */
|
||||
int getNumElement() { result = count(getAnElement()) }
|
||||
int getNumElement() { result = count(this.getAnElement()) }
|
||||
|
||||
/**
|
||||
* Gets the `i`th key expression in this literal.
|
||||
*
|
||||
* If the `i`th element of this literal has no key, this predicate is undefined for `i`.
|
||||
*/
|
||||
Expr getKey(int i) { result = getElement(i).(KeyValueExpr).getKey() }
|
||||
Expr getKey(int i) { result = this.getElement(i).(KeyValueExpr).getKey() }
|
||||
|
||||
/**
|
||||
* Gets the `i`th value expression in this literal.
|
||||
*/
|
||||
Expr getValue(int i) {
|
||||
exists(Expr elt | elt = getElement(i) |
|
||||
exists(Expr elt | elt = this.getElement(i) |
|
||||
result = elt.(KeyValueExpr).getValue()
|
||||
or
|
||||
not elt instanceof KeyValueExpr and result = elt
|
||||
@@ -433,7 +435,7 @@ class CompositeLit extends @compositelit, Literal {
|
||||
class MapLit extends CompositeLit {
|
||||
MapType mt;
|
||||
|
||||
MapLit() { mt = getType().getUnderlyingType() }
|
||||
MapLit() { mt = this.getType().getUnderlyingType() }
|
||||
|
||||
/** Gets the key type of this literal. */
|
||||
Type getKeyType() { result = mt.getKeyType() }
|
||||
@@ -460,7 +462,7 @@ class MapLit extends CompositeLit {
|
||||
class StructLit extends CompositeLit {
|
||||
StructType st;
|
||||
|
||||
StructLit() { st = getType().getUnderlyingType() }
|
||||
StructLit() { st = this.getType().getUnderlyingType() }
|
||||
|
||||
/** Gets the struct type underlying this literal. */
|
||||
StructType getStructType() { result = st }
|
||||
@@ -487,7 +489,7 @@ class ArrayOrSliceLit extends CompositeLit {
|
||||
CompositeType type;
|
||||
|
||||
ArrayOrSliceLit() {
|
||||
type = getType().getUnderlyingType() and
|
||||
type = this.getType().getUnderlyingType() and
|
||||
(
|
||||
type instanceof ArrayType
|
||||
or
|
||||
@@ -550,11 +552,13 @@ class SliceLit extends ArrayOrSliceLit {
|
||||
*/
|
||||
class ParenExpr extends @parenexpr, Expr {
|
||||
/** Gets the expression between parentheses. */
|
||||
Expr getExpr() { result = getChildExpr(0) }
|
||||
Expr getExpr() { result = this.getChildExpr(0) }
|
||||
|
||||
override Expr stripParens() { result = getExpr().stripParens() }
|
||||
override Expr stripParens() { result = this.getExpr().stripParens() }
|
||||
|
||||
override predicate isPlatformIndependentConstant() { getExpr().isPlatformIndependentConstant() }
|
||||
override predicate isPlatformIndependentConstant() {
|
||||
this.getExpr().isPlatformIndependentConstant()
|
||||
}
|
||||
|
||||
override string toString() { result = "(...)" }
|
||||
|
||||
@@ -572,23 +576,23 @@ class ParenExpr extends @parenexpr, Expr {
|
||||
*/
|
||||
class SelectorExpr extends @selectorexpr, Expr {
|
||||
/** Gets the base of this selector expression. */
|
||||
Expr getBase() { result = getChildExpr(0) }
|
||||
Expr getBase() { result = this.getChildExpr(0) }
|
||||
|
||||
/** Gets the selector of this selector expression. */
|
||||
Ident getSelector() { result = getChildExpr(1) }
|
||||
Ident getSelector() { result = this.getChildExpr(1) }
|
||||
|
||||
/** Holds if this selector is a use of `e`. */
|
||||
predicate uses(Entity e) { getSelector().uses(e) }
|
||||
predicate uses(Entity e) { this.getSelector().uses(e) }
|
||||
|
||||
/** Holds if this selector is a definition of `e` */
|
||||
predicate declares(Entity e) { getSelector().declares(e) }
|
||||
predicate declares(Entity e) { this.getSelector().declares(e) }
|
||||
|
||||
/** Holds if this selector refers to (that is, uses, defines or declares) `e`. */
|
||||
predicate refersTo(Entity e) { getSelector().refersTo(e) }
|
||||
predicate refersTo(Entity e) { this.getSelector().refersTo(e) }
|
||||
|
||||
override predicate mayHaveOwnSideEffects() { any() }
|
||||
|
||||
override string toString() { result = "selection of " + getSelector() }
|
||||
override string toString() { result = "selection of " + this.getSelector() }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "SelectorExpr" }
|
||||
}
|
||||
@@ -631,10 +635,10 @@ class PromotedSelector extends SelectorExpr {
|
||||
*/
|
||||
class IndexExpr extends @indexexpr, Expr {
|
||||
/** Gets the base of this index expression. */
|
||||
Expr getBase() { result = getChildExpr(0) }
|
||||
Expr getBase() { result = this.getChildExpr(0) }
|
||||
|
||||
/** Gets the index of this index expression. */
|
||||
Expr getIndex() { result = getChildExpr(1) }
|
||||
Expr getIndex() { result = this.getChildExpr(1) }
|
||||
|
||||
override predicate mayHaveOwnSideEffects() { any() }
|
||||
|
||||
@@ -655,16 +659,16 @@ class IndexExpr extends @indexexpr, Expr {
|
||||
*/
|
||||
class SliceExpr extends @sliceexpr, Expr {
|
||||
/** Gets the base of this slice expression. */
|
||||
Expr getBase() { result = getChildExpr(0) }
|
||||
Expr getBase() { result = this.getChildExpr(0) }
|
||||
|
||||
/** Gets the lower bound of this slice expression. */
|
||||
Expr getLow() { result = getChildExpr(1) }
|
||||
Expr getLow() { result = this.getChildExpr(1) }
|
||||
|
||||
/** Gets the upper bound of this slice expression. */
|
||||
Expr getHigh() { result = getChildExpr(2) }
|
||||
Expr getHigh() { result = this.getChildExpr(2) }
|
||||
|
||||
/** Gets the maximum of this slice expression, if any. */
|
||||
Expr getMax() { result = getChildExpr(3) }
|
||||
Expr getMax() { result = this.getChildExpr(3) }
|
||||
|
||||
override string toString() { result = "slice expression" }
|
||||
|
||||
@@ -682,14 +686,16 @@ class SliceExpr extends @sliceexpr, Expr {
|
||||
*/
|
||||
class TypeAssertExpr extends @typeassertexpr, Expr {
|
||||
/** Gets the base expression whose type is being asserted. */
|
||||
Expr getExpr() { result = getChildExpr(0) }
|
||||
Expr getExpr() { result = this.getChildExpr(0) }
|
||||
|
||||
/** Gets the expression representing the asserted type. */
|
||||
Expr getTypeExpr() { result = getChildExpr(1) }
|
||||
Expr getTypeExpr() { result = this.getChildExpr(1) }
|
||||
|
||||
override predicate mayHaveOwnSideEffects() { any() }
|
||||
|
||||
override predicate isPlatformIndependentConstant() { getExpr().isPlatformIndependentConstant() }
|
||||
override predicate isPlatformIndependentConstant() {
|
||||
this.getExpr().isPlatformIndependentConstant()
|
||||
}
|
||||
|
||||
override string toString() { result = "type assertion" }
|
||||
|
||||
@@ -725,16 +731,16 @@ class CallOrConversionExpr extends @callorconversionexpr, Expr {
|
||||
* ```
|
||||
*/
|
||||
class ConversionExpr extends CallOrConversionExpr {
|
||||
ConversionExpr() { isTypeExprBottomUp(getChildExpr(0)) }
|
||||
ConversionExpr() { isTypeExprBottomUp(this.getChildExpr(0)) }
|
||||
|
||||
/** Gets the type expression representing the target type of the conversion. */
|
||||
Expr getTypeExpr() { result = getChildExpr(0) }
|
||||
Expr getTypeExpr() { result = this.getChildExpr(0) }
|
||||
|
||||
/** Gets the operand of the type conversion. */
|
||||
Expr getOperand() { result = getChildExpr(1) }
|
||||
Expr getOperand() { result = this.getChildExpr(1) }
|
||||
|
||||
override predicate isPlatformIndependentConstant() {
|
||||
getOperand().isPlatformIndependentConstant()
|
||||
this.getOperand().isPlatformIndependentConstant()
|
||||
}
|
||||
|
||||
override string toString() { result = "type conversion" }
|
||||
@@ -757,30 +763,30 @@ class ConversionExpr extends CallOrConversionExpr {
|
||||
*/
|
||||
class CallExpr extends CallOrConversionExpr {
|
||||
CallExpr() {
|
||||
exists(Expr callee | callee = getChildExpr(0) | not isTypeExprBottomUp(callee))
|
||||
exists(Expr callee | callee = this.getChildExpr(0) | not isTypeExprBottomUp(callee))
|
||||
or
|
||||
// only calls can have an ellipsis after their last argument
|
||||
has_ellipsis(this)
|
||||
}
|
||||
|
||||
/** Gets the expression representing the function being called. */
|
||||
Expr getCalleeExpr() { result = getChildExpr(0) }
|
||||
Expr getCalleeExpr() { result = this.getChildExpr(0) }
|
||||
|
||||
/** Gets the `i`th argument expression of this call (0-based). */
|
||||
Expr getArgument(int i) {
|
||||
i >= 0 and
|
||||
result = getChildExpr(i + 1)
|
||||
result = this.getChildExpr(i + 1)
|
||||
}
|
||||
|
||||
/** Gets an argument expression of this call. */
|
||||
Expr getAnArgument() { result = getArgument(_) }
|
||||
Expr getAnArgument() { result = this.getArgument(_) }
|
||||
|
||||
/** Gets the number of argument expressions of this call. */
|
||||
int getNumArgument() { result = count(getAnArgument()) }
|
||||
int getNumArgument() { result = count(this.getAnArgument()) }
|
||||
|
||||
/** Gets the name of the invoked function or method if it can be determined syntactically. */
|
||||
string getCalleeName() {
|
||||
exists(Expr callee | callee = getCalleeExpr().stripParens() |
|
||||
exists(Expr callee | callee = this.getCalleeExpr().stripParens() |
|
||||
result = callee.(Ident).getName()
|
||||
or
|
||||
result = callee.(SelectorExpr).getSelector().getName()
|
||||
@@ -788,20 +794,20 @@ class CallExpr extends CallOrConversionExpr {
|
||||
}
|
||||
|
||||
/** Gets the declared target of this call. */
|
||||
Function getTarget() { getCalleeExpr() = result.getAReference() }
|
||||
Function getTarget() { this.getCalleeExpr() = result.getAReference() }
|
||||
|
||||
/** Holds if this call has an ellipsis after its last argument. */
|
||||
predicate hasEllipsis() { has_ellipsis(this) }
|
||||
|
||||
override predicate mayHaveOwnSideEffects() {
|
||||
getTarget().mayHaveSideEffects() or
|
||||
not exists(getTarget())
|
||||
this.getTarget().mayHaveSideEffects() or
|
||||
not exists(this.getTarget())
|
||||
}
|
||||
|
||||
override string toString() {
|
||||
result = "call to " + getCalleeName()
|
||||
result = "call to " + this.getCalleeName()
|
||||
or
|
||||
not exists(getCalleeName()) and
|
||||
not exists(this.getCalleeName()) and
|
||||
result = "function call"
|
||||
}
|
||||
|
||||
@@ -819,7 +825,7 @@ class CallExpr extends CallOrConversionExpr {
|
||||
*/
|
||||
class StarExpr extends @starexpr, Expr {
|
||||
/** Gets the base expression of this star expression. */
|
||||
Expr getBase() { result = getChildExpr(0) }
|
||||
Expr getBase() { result = this.getChildExpr(0) }
|
||||
|
||||
override predicate mayHaveOwnSideEffects() { any() }
|
||||
|
||||
@@ -839,10 +845,10 @@ class StarExpr extends @starexpr, Expr {
|
||||
*/
|
||||
class KeyValueExpr extends @keyvalueexpr, Expr {
|
||||
/** Gets the key expression of this key-value pair. */
|
||||
Expr getKey() { result = getChildExpr(0) }
|
||||
Expr getKey() { result = this.getChildExpr(0) }
|
||||
|
||||
/** Gets the value expression of this key-value pair. */
|
||||
Expr getValue() { result = getChildExpr(1) }
|
||||
Expr getValue() { result = this.getChildExpr(1) }
|
||||
|
||||
/** Gets the composite literal to which this key-value pair belongs. */
|
||||
CompositeLit getLiteral() { this = result.getElement(_) }
|
||||
@@ -863,10 +869,10 @@ class KeyValueExpr extends @keyvalueexpr, Expr {
|
||||
*/
|
||||
class ArrayTypeExpr extends @arraytypeexpr, TypeExpr {
|
||||
/** Gets the length expression of this array type. */
|
||||
Expr getLength() { result = getChildExpr(0) }
|
||||
Expr getLength() { result = this.getChildExpr(0) }
|
||||
|
||||
/** Gets the expression representing the element type of this array type. */
|
||||
Expr getElement() { result = getChildExpr(1) }
|
||||
Expr getElement() { result = this.getChildExpr(1) }
|
||||
|
||||
override string toString() { result = "array type" }
|
||||
|
||||
@@ -899,25 +905,25 @@ class StructTypeExpr extends @structtypeexpr, TypeExpr, FieldParent {
|
||||
*/
|
||||
class FuncTypeExpr extends @functypeexpr, TypeExpr, ScopeNode, FieldParent {
|
||||
/** Gets the `i`th parameter of this function type (0-based). */
|
||||
ParameterDecl getParameterDecl(int i) { result = getField(i) and i >= 0 }
|
||||
ParameterDecl getParameterDecl(int i) { result = this.getField(i) and i >= 0 }
|
||||
|
||||
/** Gets a parameter of this function type. */
|
||||
ParameterDecl getAParameterDecl() { result = getParameterDecl(_) }
|
||||
ParameterDecl getAParameterDecl() { result = this.getParameterDecl(_) }
|
||||
|
||||
/** Gets the number of parameters of this function type. */
|
||||
int getNumParameter() { result = count(getAParameterDecl()) }
|
||||
int getNumParameter() { result = count(this.getAParameterDecl()) }
|
||||
|
||||
/** Gets the `i`th result of this function type (0-based). */
|
||||
ResultVariableDecl getResultDecl(int i) { result = getField(-(i + 1)) }
|
||||
ResultVariableDecl getResultDecl(int i) { result = this.getField(-(i + 1)) }
|
||||
|
||||
/** Gets a result of this function type. */
|
||||
ResultVariableDecl getAResultDecl() { result = getResultDecl(_) }
|
||||
ResultVariableDecl getAResultDecl() { result = this.getResultDecl(_) }
|
||||
|
||||
/** Gets the number of results of this function type. */
|
||||
int getNumResult() { result = count(getAResultDecl()) }
|
||||
int getNumResult() { result = count(this.getAResultDecl()) }
|
||||
|
||||
/** Gets the result of this function type, if there is only one. */
|
||||
ResultVariableDecl getResultDecl() { getNumResult() = 1 and result = getAResultDecl() }
|
||||
ResultVariableDecl getResultDecl() { this.getNumResult() = 1 and result = this.getAResultDecl() }
|
||||
|
||||
override string toString() { result = "function type" }
|
||||
|
||||
@@ -925,9 +931,9 @@ class FuncTypeExpr extends @functypeexpr, TypeExpr, ScopeNode, FieldParent {
|
||||
|
||||
/** Gets the `i`th child of this node, parameters first followed by results. */
|
||||
override AstNode getUniquelyNumberedChild(int i) {
|
||||
if i < getNumParameter()
|
||||
then result = getParameterDecl(i)
|
||||
else result = getResultDecl(i - getNumParameter())
|
||||
if i < this.getNumParameter()
|
||||
then result = this.getParameterDecl(i)
|
||||
else result = this.getResultDecl(i - this.getNumParameter())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -942,13 +948,13 @@ class FuncTypeExpr extends @functypeexpr, TypeExpr, ScopeNode, FieldParent {
|
||||
*/
|
||||
class InterfaceTypeExpr extends @interfacetypeexpr, TypeExpr, FieldParent {
|
||||
/** Gets the `i`th method specification of this interface type. */
|
||||
MethodSpec getMethod(int i) { result = getField(i) }
|
||||
MethodSpec getMethod(int i) { result = this.getField(i) }
|
||||
|
||||
/** Gets a method of this interface type. */
|
||||
MethodSpec getAMethod() { result = getMethod(_) }
|
||||
MethodSpec getAMethod() { result = this.getMethod(_) }
|
||||
|
||||
/** Gets the number of methods of this interface type. */
|
||||
int getNumMethod() { result = count(getAMethod()) }
|
||||
int getNumMethod() { result = count(this.getAMethod()) }
|
||||
|
||||
override string toString() { result = "interface type" }
|
||||
|
||||
@@ -966,16 +972,16 @@ class InterfaceTypeExpr extends @interfacetypeexpr, TypeExpr, FieldParent {
|
||||
*/
|
||||
class MapTypeExpr extends @maptypeexpr, TypeExpr {
|
||||
/** Gets the expression representing the key type of this map type. */
|
||||
Expr getKeyTypeExpr() { result = getChildExpr(0) }
|
||||
Expr getKeyTypeExpr() { result = this.getChildExpr(0) }
|
||||
|
||||
/** Gets the key type of this map type. */
|
||||
Type getKeyType() { result = getKeyTypeExpr().getType() }
|
||||
Type getKeyType() { result = this.getKeyTypeExpr().getType() }
|
||||
|
||||
/** Gets the expression representing the value type of this map type. */
|
||||
Expr getValueTypeExpr() { result = getChildExpr(1) }
|
||||
Expr getValueTypeExpr() { result = this.getChildExpr(1) }
|
||||
|
||||
/** Gets the value type of this map type. */
|
||||
Type getValueType() { result = getValueTypeExpr().getType() }
|
||||
Type getValueType() { result = this.getValueTypeExpr().getType() }
|
||||
|
||||
override string toString() { result = "map type" }
|
||||
|
||||
@@ -1049,15 +1055,15 @@ class BitwiseExpr extends @bitwiseexpr, OperatorExpr { }
|
||||
*/
|
||||
class UnaryExpr extends @unaryexpr, OperatorExpr {
|
||||
/** Gets the operand of this unary expression. */
|
||||
Expr getOperand() { result = getChildExpr(0) }
|
||||
Expr getOperand() { result = this.getChildExpr(0) }
|
||||
|
||||
override Expr getAnOperand() { result = this.getOperand() }
|
||||
|
||||
override predicate isPlatformIndependentConstant() {
|
||||
getOperand().isPlatformIndependentConstant()
|
||||
this.getOperand().isPlatformIndependentConstant()
|
||||
}
|
||||
|
||||
override string toString() { result = getOperator() + "..." }
|
||||
override string toString() { result = this.getOperator() + "..." }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1214,26 +1220,26 @@ class RecvExpr extends @arrowexpr, UnaryExpr {
|
||||
*/
|
||||
class BinaryExpr extends @binaryexpr, OperatorExpr {
|
||||
/** Gets the left operand of this binary expression. */
|
||||
Expr getLeftOperand() { result = getChildExpr(0) }
|
||||
Expr getLeftOperand() { result = this.getChildExpr(0) }
|
||||
|
||||
/** Gets the right operand of this binary expression. */
|
||||
Expr getRightOperand() { result = getChildExpr(1) }
|
||||
Expr getRightOperand() { result = this.getChildExpr(1) }
|
||||
|
||||
override Expr getAnOperand() { result = getChildExpr([0 .. 1]) }
|
||||
override Expr getAnOperand() { result = this.getChildExpr([0 .. 1]) }
|
||||
|
||||
/** Holds if `e` and `f` (in either order) are the two operands of this binary expression. */
|
||||
predicate hasOperands(Expr e, Expr f) {
|
||||
e = getAnOperand() and
|
||||
f = getAnOperand() and
|
||||
e = this.getAnOperand() and
|
||||
f = this.getAnOperand() and
|
||||
e != f
|
||||
}
|
||||
|
||||
override predicate isPlatformIndependentConstant() {
|
||||
getLeftOperand().isPlatformIndependentConstant() and
|
||||
getRightOperand().isPlatformIndependentConstant()
|
||||
this.getLeftOperand().isPlatformIndependentConstant() and
|
||||
this.getRightOperand().isPlatformIndependentConstant()
|
||||
}
|
||||
|
||||
override string toString() { result = "..." + getOperator() + "..." }
|
||||
override string toString() { result = "..." + this.getOperator() + "..." }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1417,9 +1423,9 @@ class LssExpr extends @lssexpr, RelationalComparisonExpr {
|
||||
|
||||
override predicate isStrict() { any() }
|
||||
|
||||
override Expr getLesserOperand() { result = getLeftOperand() }
|
||||
override Expr getLesserOperand() { result = this.getLeftOperand() }
|
||||
|
||||
override Expr getGreaterOperand() { result = getRightOperand() }
|
||||
override Expr getGreaterOperand() { result = this.getRightOperand() }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "LssExpr" }
|
||||
}
|
||||
@@ -1438,9 +1444,9 @@ class LTExpr = LssExpr;
|
||||
class LeqExpr extends @leqexpr, RelationalComparisonExpr {
|
||||
override string getOperator() { result = "<=" }
|
||||
|
||||
override Expr getLesserOperand() { result = getLeftOperand() }
|
||||
override Expr getLesserOperand() { result = this.getLeftOperand() }
|
||||
|
||||
override Expr getGreaterOperand() { result = getRightOperand() }
|
||||
override Expr getGreaterOperand() { result = this.getRightOperand() }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "LeqExpr" }
|
||||
}
|
||||
@@ -1461,9 +1467,9 @@ class GtrExpr extends @gtrexpr, RelationalComparisonExpr {
|
||||
|
||||
override predicate isStrict() { any() }
|
||||
|
||||
override Expr getLesserOperand() { result = getRightOperand() }
|
||||
override Expr getLesserOperand() { result = this.getRightOperand() }
|
||||
|
||||
override Expr getGreaterOperand() { result = getLeftOperand() }
|
||||
override Expr getGreaterOperand() { result = this.getLeftOperand() }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "GtrExpr" }
|
||||
}
|
||||
@@ -1482,9 +1488,9 @@ class GTExpr = GtrExpr;
|
||||
class GeqExpr extends @geqexpr, RelationalComparisonExpr {
|
||||
override string getOperator() { result = ">=" }
|
||||
|
||||
override Expr getLesserOperand() { result = getRightOperand() }
|
||||
override Expr getLesserOperand() { result = this.getRightOperand() }
|
||||
|
||||
override Expr getGreaterOperand() { result = getLeftOperand() }
|
||||
override Expr getGreaterOperand() { result = this.getLeftOperand() }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "GeqExpr" }
|
||||
}
|
||||
@@ -1685,7 +1691,7 @@ class ChanTypeExpr extends @chantypeexpr, TypeExpr {
|
||||
/**
|
||||
* Gets the expression representing the type of values flowing through the channel.
|
||||
*/
|
||||
Expr getValueTypeExpr() { result = getChildExpr(0) }
|
||||
Expr getValueTypeExpr() { result = this.getChildExpr(0) }
|
||||
|
||||
/** Holds if this channel can send data. */
|
||||
predicate canSend() { none() }
|
||||
@@ -47,7 +47,7 @@ abstract class Container extends @container {
|
||||
*/
|
||||
string getRelativePath() {
|
||||
exists(string absPath, string pref |
|
||||
absPath = getAbsolutePath() and sourceLocationPrefix(pref)
|
||||
absPath = this.getAbsolutePath() and sourceLocationPrefix(pref)
|
||||
|
|
||||
absPath = pref and result = ""
|
||||
or
|
||||
@@ -74,7 +74,7 @@ abstract class Container extends @container {
|
||||
* </table>
|
||||
*/
|
||||
string getBaseName() {
|
||||
result = getAbsolutePath().regexpCapture(".*/(([^/]*?)(?:\\.([^.]*))?)", 1)
|
||||
result = this.getAbsolutePath().regexpCapture(".*/(([^/]*?)(?:\\.([^.]*))?)", 1)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -100,7 +100,9 @@ abstract class Container extends @container {
|
||||
* <tr><td>"/tmp/x.tar.gz"</td><td>"gz"</td></tr>
|
||||
* </table>
|
||||
*/
|
||||
string getExtension() { result = getAbsolutePath().regexpCapture(".*/([^/]*?)(\\.([^.]*))?", 3) }
|
||||
string getExtension() {
|
||||
result = this.getAbsolutePath().regexpCapture(".*/([^/]*?)(\\.([^.]*))?", 3)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the stem of this container, that is, the prefix of its base name up to
|
||||
@@ -119,7 +121,9 @@ abstract class Container extends @container {
|
||||
* <tr><td>"/tmp/x.tar.gz"</td><td>"x.tar"</td></tr>
|
||||
* </table>
|
||||
*/
|
||||
string getStem() { result = getAbsolutePath().regexpCapture(".*/([^/]*?)(?:\\.([^.]*))?", 1) }
|
||||
string getStem() {
|
||||
result = this.getAbsolutePath().regexpCapture(".*/([^/]*?)(?:\\.([^.]*))?", 1)
|
||||
}
|
||||
|
||||
/** Gets the parent container of this file or folder, if any. */
|
||||
Container getParentContainer() { containerparent(result, this) }
|
||||
@@ -128,20 +132,20 @@ abstract class Container extends @container {
|
||||
Container getAChildContainer() { this = result.getParentContainer() }
|
||||
|
||||
/** Gets a file in this container. */
|
||||
File getAFile() { result = getAChildContainer() }
|
||||
File getAFile() { result = this.getAChildContainer() }
|
||||
|
||||
/** Gets the file in this container that has the given `baseName`, if any. */
|
||||
File getFile(string baseName) {
|
||||
result = getAFile() and
|
||||
result = this.getAFile() and
|
||||
result.getBaseName() = baseName
|
||||
}
|
||||
|
||||
/** Gets a sub-folder in this container. */
|
||||
Folder getAFolder() { result = getAChildContainer() }
|
||||
Folder getAFolder() { result = this.getAChildContainer() }
|
||||
|
||||
/** Gets the sub-folder in this container that has the given `baseName`, if any. */
|
||||
Folder getFolder(string baseName) {
|
||||
result = getAFolder() and
|
||||
result = this.getAFolder() and
|
||||
result.getBaseName() = baseName
|
||||
}
|
||||
|
||||
@@ -150,7 +154,7 @@ abstract class Container extends @container {
|
||||
*
|
||||
* This is the absolute path of the container.
|
||||
*/
|
||||
string toString() { result = getAbsolutePath() }
|
||||
string toString() { result = this.getAbsolutePath() }
|
||||
}
|
||||
|
||||
/** A folder. */
|
||||
@@ -159,22 +163,22 @@ class Folder extends Container, @folder {
|
||||
|
||||
/** Gets the file or subfolder in this folder that has the given `name`, if any. */
|
||||
Container getChildContainer(string name) {
|
||||
result = getAChildContainer() and
|
||||
result = this.getAChildContainer() and
|
||||
result.getBaseName() = name
|
||||
}
|
||||
|
||||
/** Gets the file in this folder that has the given `stem` and `extension`, if any. */
|
||||
File getFile(string stem, string extension) {
|
||||
result = getAChildContainer() and
|
||||
result = this.getAChildContainer() and
|
||||
result.getStem() = stem and
|
||||
result.getExtension() = extension
|
||||
}
|
||||
|
||||
/** Gets a subfolder contained in this folder. */
|
||||
Folder getASubFolder() { result = getAChildContainer() }
|
||||
Folder getASubFolder() { result = this.getAChildContainer() }
|
||||
|
||||
/** Gets the URL of this folder. */
|
||||
override string getURL() { result = "folder://" + getAbsolutePath() }
|
||||
override string getURL() { result = "folder://" + this.getAbsolutePath() }
|
||||
}
|
||||
|
||||
/** Any file, including files that have not been extracted but are referred to as locations for errors. */
|
||||
@@ -194,10 +198,10 @@ class ExtractedOrExternalFile extends Container, @file, Documentable, ExprParent
|
||||
int getNumberOfLinesOfComments() { numlines(this, _, _, result) }
|
||||
|
||||
/** Gets the package name as specified in the package clause of this file. */
|
||||
Ident getPackageNameExpr() { result = getChildExpr(0) }
|
||||
Ident getPackageNameExpr() { result = this.getChildExpr(0) }
|
||||
|
||||
/** Gets the name of the package to which this file belongs. */
|
||||
string getPackageName() { result = getPackageNameExpr().getName() }
|
||||
string getPackageName() { result = this.getPackageNameExpr().getName() }
|
||||
|
||||
/** Holds if this file contains at least one build constraint. */
|
||||
pragma[noinline]
|
||||
@@ -209,8 +213,8 @@ class ExtractedOrExternalFile extends Container, @file, Documentable, ExprParent
|
||||
* 32 or 64.
|
||||
*/
|
||||
predicate constrainsIntBitSize(int bitSize) {
|
||||
explicitlyConstrainsIntBitSize(bitSize) or
|
||||
implicitlyConstrainsIntBitSize(bitSize)
|
||||
this.explicitlyConstrainsIntBitSize(bitSize) or
|
||||
this.implicitlyConstrainsIntBitSize(bitSize)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -248,12 +252,12 @@ class ExtractedOrExternalFile extends Container, @file, Documentable, ExprParent
|
||||
CommentGroup getCommentGroup(int i) { comment_groups(result, this, i) }
|
||||
|
||||
/** Gets a child comment group. */
|
||||
CommentGroup getACommentGroup() { result = getCommentGroup(_) }
|
||||
CommentGroup getACommentGroup() { result = this.getCommentGroup(_) }
|
||||
|
||||
/** Gets the number of child comment groups of this file. */
|
||||
int getNumCommentGroups() { result = count(getACommentGroup()) }
|
||||
int getNumCommentGroups() { result = count(this.getACommentGroup()) }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "File" }
|
||||
override string getAPrimaryQlClass() { result = "ExtractedOrExternalFile" }
|
||||
}
|
||||
|
||||
/** A file that has been extracted. */
|
||||
@@ -265,14 +269,20 @@ class File extends ExtractedOrExternalFile {
|
||||
or
|
||||
exists(this.getAChild())
|
||||
}
|
||||
|
||||
override string getAPrimaryQlClass() { result = "File" }
|
||||
}
|
||||
|
||||
/** A Go file. */
|
||||
class GoFile extends File {
|
||||
GoFile() { this.getExtension() = "go" }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "GoFile" }
|
||||
}
|
||||
|
||||
/** An HTML file. */
|
||||
class HtmlFile extends File {
|
||||
HtmlFile() { this.getExtension().regexpMatch("x?html?") }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "HtmlFile" }
|
||||
}
|
||||
@@ -56,7 +56,7 @@ class LocalScope extends @localscope, Scope, Locatable {
|
||||
* For function scopes, this is the scope itself.
|
||||
*/
|
||||
FunctionScope getEnclosingFunctionScope() {
|
||||
result = getOuterScope().(LocalScope).getEnclosingFunctionScope()
|
||||
result = this.getOuterScope().(LocalScope).getEnclosingFunctionScope()
|
||||
}
|
||||
|
||||
override string toString() { result = "local scope" }
|
||||
@@ -64,14 +64,14 @@ class LocalScope extends @localscope, Scope, Locatable {
|
||||
|
||||
/** A local scope induced by a file. */
|
||||
class FileScope extends LocalScope {
|
||||
FileScope() { getNode() instanceof File }
|
||||
FileScope() { this.getNode() instanceof File }
|
||||
}
|
||||
|
||||
/** A local scope induced by a function definition. */
|
||||
class FunctionScope extends LocalScope {
|
||||
FuncDef f;
|
||||
|
||||
FunctionScope() { getNode() = f.getTypeExpr() }
|
||||
FunctionScope() { this.getNode() = f.getTypeExpr() }
|
||||
|
||||
/** Gets the function inducing this scope. */
|
||||
FuncDef getFunction() { result = f }
|
||||
@@ -97,13 +97,13 @@ class Entity extends @object {
|
||||
|
||||
/** Holds if this entity is declared in a package with path `pkg` and has the given `name`. */
|
||||
predicate hasQualifiedName(string pkg, string name) {
|
||||
pkg = getPackage().getPath() and
|
||||
name = getName()
|
||||
pkg = this.getPackage().getPath() and
|
||||
name = this.getName()
|
||||
}
|
||||
|
||||
/** Gets the qualified name of this entity, if any. */
|
||||
string getQualifiedName() {
|
||||
exists(string pkg, string name | hasQualifiedName(pkg, name) | result = pkg + "." + name)
|
||||
exists(string pkg, string name | this.hasQualifiedName(pkg, name) | result = pkg + "." + name)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -123,7 +123,7 @@ class Entity extends @object {
|
||||
Type getType() { objecttypes(this, result) }
|
||||
|
||||
/** Gets a textual representation of this entity. */
|
||||
string toString() { result = getName() }
|
||||
string toString() { result = this.getName() }
|
||||
|
||||
/**
|
||||
* Holds if this element is at the specified location.
|
||||
@@ -136,10 +136,10 @@ class Entity extends @object {
|
||||
string filepath, int startline, int startcolumn, int endline, int endcolumn
|
||||
) {
|
||||
// take the location of the declaration if there is one
|
||||
getDeclaration().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
|
||||
this.getDeclaration().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
|
||||
or
|
||||
// otherwise fall back on dummy location
|
||||
not exists(getDeclaration()) and
|
||||
not exists(this.getDeclaration()) and
|
||||
filepath = "" and
|
||||
startline = 0 and
|
||||
startcolumn = 0 and
|
||||
@@ -153,7 +153,7 @@ class DeclaredEntity extends Entity, @declobject {
|
||||
/** Gets the expression to which this entity is initialized, if any. */
|
||||
Expr getInit() {
|
||||
exists(ValueSpec spec, int i |
|
||||
spec.getNameExpr(i) = getDeclaration() and
|
||||
spec.getNameExpr(i) = this.getDeclaration() and
|
||||
spec.getInit(i) = result
|
||||
)
|
||||
}
|
||||
@@ -214,15 +214,17 @@ class DeclaredVariable extends Variable, DeclaredEntity, @declvarobject {
|
||||
|
||||
/** A variable declared in a local scope (as opposed to a package scope or the universal scope). */
|
||||
class LocalVariable extends DeclaredVariable {
|
||||
LocalVariable() { getScope() instanceof LocalScope }
|
||||
LocalVariable() { this.getScope() instanceof LocalScope }
|
||||
|
||||
/** Gets the innermost function containing the scope of this variable, if any. */
|
||||
FuncDef getDeclaringFunction() {
|
||||
result = getScope().(LocalScope).getEnclosingFunctionScope().getFunction()
|
||||
result = this.getScope().(LocalScope).getEnclosingFunctionScope().getFunction()
|
||||
}
|
||||
|
||||
/** Holds if this variable is referenced inside a nested function. */
|
||||
predicate isCaptured() { getDeclaringFunction() != getAReference().getEnclosingFunction() }
|
||||
predicate isCaptured() {
|
||||
this.getDeclaringFunction() != this.getAReference().getEnclosingFunction()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -388,8 +390,8 @@ class Function extends ValueEntity, @functionobject {
|
||||
* by extending `Function` rather than having to remember to extend `DeclaredFunction`.
|
||||
*/
|
||||
predicate mayReturnNormally() {
|
||||
not mustPanic() and
|
||||
(ControlFlow::mayReturnNormally(getFuncDecl()) or not exists(getBody()))
|
||||
not this.mustPanic() and
|
||||
(ControlFlow::mayReturnNormally(this.getFuncDecl()) or not exists(this.getBody()))
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -409,31 +411,31 @@ class Function extends ValueEntity, @functionobject {
|
||||
predicate mustPanic() { none() }
|
||||
|
||||
/** Gets the number of parameters of this function. */
|
||||
int getNumParameter() { result = getType().(SignatureType).getNumParameter() }
|
||||
int getNumParameter() { result = this.getType().(SignatureType).getNumParameter() }
|
||||
|
||||
/** Gets the type of the `i`th parameter of this function. */
|
||||
Type getParameterType(int i) { result = getType().(SignatureType).getParameterType(i) }
|
||||
Type getParameterType(int i) { result = this.getType().(SignatureType).getParameterType(i) }
|
||||
|
||||
/** Gets the number of results of this function. */
|
||||
int getNumResult() { result = getType().(SignatureType).getNumResult() }
|
||||
int getNumResult() { result = this.getType().(SignatureType).getNumResult() }
|
||||
|
||||
/** Gets the type of the `i`th result of this function. */
|
||||
Type getResultType(int i) { result = getType().(SignatureType).getResultType(i) }
|
||||
Type getResultType(int i) { result = this.getType().(SignatureType).getResultType(i) }
|
||||
|
||||
/** Gets the body of this function, if any. */
|
||||
BlockStmt getBody() { result = getFuncDecl().getBody() }
|
||||
BlockStmt getBody() { result = this.getFuncDecl().getBody() }
|
||||
|
||||
/** Gets the `i`th parameter of this function. */
|
||||
Parameter getParameter(int i) { result.isParameterOf(getFuncDecl(), i) }
|
||||
Parameter getParameter(int i) { result.isParameterOf(this.getFuncDecl(), i) }
|
||||
|
||||
/** Gets a parameter of this function. */
|
||||
Parameter getAParameter() { result = getParameter(_) }
|
||||
Parameter getAParameter() { result = this.getParameter(_) }
|
||||
|
||||
/** Gets the `i`th reslt variable of this function. */
|
||||
ResultVariable getResult(int i) { result.isResultOf(getFuncDecl(), i) }
|
||||
ResultVariable getResult(int i) { result.isResultOf(this.getFuncDecl(), i) }
|
||||
|
||||
/** Gets a result variable of this function. */
|
||||
ResultVariable getAResult() { result = getResult(_) }
|
||||
ResultVariable getAResult() { result = this.getResult(_) }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -455,7 +457,9 @@ class Method extends Function {
|
||||
}
|
||||
|
||||
/** Holds if this method is declared in an interface. */
|
||||
predicate isInterfaceMethod() { getReceiverType().getUnderlyingType() instanceof InterfaceType }
|
||||
predicate isInterfaceMethod() {
|
||||
this.getReceiverType().getUnderlyingType() instanceof InterfaceType
|
||||
}
|
||||
|
||||
/** Gets the receiver variable of this method. */
|
||||
Variable getReceiver() { result = receiver }
|
||||
@@ -468,7 +472,7 @@ class Method extends Function {
|
||||
* if it is a pointer type, or the receiver type itself if it is not a pointer type.
|
||||
*/
|
||||
Type getReceiverBaseType() {
|
||||
exists(Type recv | recv = getReceiverType() |
|
||||
exists(Type recv | recv = this.getReceiverType() |
|
||||
if recv instanceof PointerType
|
||||
then result = recv.(PointerType).getBaseType()
|
||||
else result = recv
|
||||
@@ -522,7 +526,7 @@ class Method extends Function {
|
||||
predicate implements(Method m) {
|
||||
this = m
|
||||
or
|
||||
not isInterfaceMethod() and
|
||||
not this.isInterfaceMethod() and
|
||||
exists(Type t |
|
||||
this = t.getMethod(m.getName()) and
|
||||
t.implements(m.getReceiverType().getUnderlyingType())
|
||||
@@ -553,9 +557,9 @@ class DeclaredFunction extends Function, DeclaredEntity, @declfunctionobject {
|
||||
override FuncDecl getFuncDecl() { result.getNameExpr() = this.getDeclaration() }
|
||||
|
||||
override predicate mayHaveSideEffects() {
|
||||
not exists(getBody())
|
||||
not exists(this.getBody())
|
||||
or
|
||||
exists(BlockStmt body | body = getBody() |
|
||||
exists(BlockStmt body | body = this.getBody() |
|
||||
body.mayHaveSideEffects()
|
||||
or
|
||||
// functions declared in files with build constraints may be defined differently
|
||||
@@ -567,17 +571,17 @@ class DeclaredFunction extends Function, DeclaredEntity, @declfunctionobject {
|
||||
|
||||
/** A built-in function. */
|
||||
class BuiltinFunction extends Function, BuiltinEntity, @builtinfunctionobject {
|
||||
override predicate mayHaveSideEffects() { builtinFunction(getName(), false, _, _) }
|
||||
override predicate mayHaveSideEffects() { builtinFunction(this.getName(), false, _, _) }
|
||||
|
||||
override predicate mayPanic() { builtinFunction(getName(), _, true, _) }
|
||||
override predicate mayPanic() { builtinFunction(this.getName(), _, true, _) }
|
||||
|
||||
override predicate mustPanic() { builtinFunction(getName(), _, _, true) }
|
||||
override predicate mustPanic() { builtinFunction(this.getName(), _, _, true) }
|
||||
|
||||
/**
|
||||
* Holds if this function is pure, that is, it has no observable side effects and
|
||||
* no non-determinism.
|
||||
*/
|
||||
predicate isPure() { not mayHaveSideEffects() }
|
||||
predicate isPure() { not this.mayHaveSideEffects() }
|
||||
}
|
||||
|
||||
/** A statement label. */
|
||||
@@ -70,11 +70,11 @@ module StringOps {
|
||||
* An expression of the form `strings.HasPrefix(A, B)`.
|
||||
*/
|
||||
private class StringsHasPrefix extends Range, DataFlow::CallNode {
|
||||
StringsHasPrefix() { getTarget().hasQualifiedName("strings", "HasPrefix") }
|
||||
StringsHasPrefix() { this.getTarget().hasQualifiedName("strings", "HasPrefix") }
|
||||
|
||||
override DataFlow::Node getBaseString() { result = getArgument(0) }
|
||||
override DataFlow::Node getBaseString() { result = this.getArgument(0) }
|
||||
|
||||
override DataFlow::Node getSubstring() { result = getArgument(1) }
|
||||
override DataFlow::Node getSubstring() { result = this.getArgument(1) }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -145,7 +145,7 @@ module StringOps {
|
||||
DataFlow::Node substring;
|
||||
|
||||
HasPrefix_Substring() {
|
||||
eq(_, slice, substring) and
|
||||
this.eq(_, slice, substring) and
|
||||
slice.getLow().getIntValue() = 0 and
|
||||
(
|
||||
exists(DataFlow::CallNode len |
|
||||
@@ -211,25 +211,25 @@ module StringOps {
|
||||
* Gets the string value of the `n`th operand of this string concatenation, if it is
|
||||
* a constant.
|
||||
*/
|
||||
string getOperandStringValue(int n) { result = getOperand(n).getStringValue() }
|
||||
string getOperandStringValue(int n) { result = this.getOperand(n).getStringValue() }
|
||||
|
||||
/**
|
||||
* Gets the number of operands of this string concatenation.
|
||||
*/
|
||||
int getNumOperand() { result = count(getOperand(_)) }
|
||||
int getNumOperand() { result = count(this.getOperand(_)) }
|
||||
}
|
||||
|
||||
/** A string concatenation using the `+` or `+=` operator. */
|
||||
private class PlusConcat extends Range, DataFlow::BinaryOperationNode {
|
||||
PlusConcat() {
|
||||
getType() instanceof StringType and
|
||||
getOperator() = "+"
|
||||
this.getType() instanceof StringType and
|
||||
this.getOperator() = "+"
|
||||
}
|
||||
|
||||
override DataFlow::Node getOperand(int n) {
|
||||
n = 0 and result = getLeftOperand()
|
||||
n = 0 and result = this.getLeftOperand()
|
||||
or
|
||||
n = 1 and result = getRightOperand()
|
||||
n = 1 and result = this.getRightOperand()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -278,7 +278,7 @@ module StringOps {
|
||||
SprintfConcat() {
|
||||
exists(Function sprintf | sprintf.hasQualifiedName("fmt", "Sprintf") |
|
||||
this = sprintf.getACall() and
|
||||
fmt = getArgument(0).getStringValue() and
|
||||
fmt = this.getArgument(0).getStringValue() and
|
||||
fmt.regexpMatch(getFormatComponentRegex() + "*")
|
||||
)
|
||||
}
|
||||
@@ -292,22 +292,22 @@ module StringOps {
|
||||
|
||||
override DataFlow::Node getOperand(int n) {
|
||||
exists(int i, string part | part = "%s" or part = "%v" |
|
||||
part = getComponent(n) and
|
||||
part = this.getComponent(n) and
|
||||
i = n / 2 and
|
||||
result = getArgument(i + 1)
|
||||
result = this.getArgument(i + 1)
|
||||
)
|
||||
}
|
||||
|
||||
override string getOperandStringValue(int n) {
|
||||
result = Range.super.getOperandStringValue(n)
|
||||
or
|
||||
exists(string cmp | cmp = getComponent(n) |
|
||||
exists(string cmp | cmp = this.getComponent(n) |
|
||||
(cmp.charAt(0) != "%" or cmp.charAt(1) = "%") and
|
||||
result = cmp.replaceAll("%%", "%")
|
||||
)
|
||||
}
|
||||
|
||||
override int getNumOperand() { result = max(int i | exists(getComponent(i))) + 1 }
|
||||
override int getNumOperand() { result = max(int i | exists(this.getComponent(i))) + 1 }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -357,7 +357,7 @@ module StringOps {
|
||||
* Gets the string value of this concatenation element if it is a constant.
|
||||
*/
|
||||
string getStringValue() {
|
||||
result = asNode().getStringValue()
|
||||
result = this.asNode().getStringValue()
|
||||
or
|
||||
exists(Concatenation parent, int i | this = MkConcatenationOperand(parent, i) |
|
||||
result = parent.getOperandStringValue(i)
|
||||
@@ -367,7 +367,7 @@ module StringOps {
|
||||
/**
|
||||
* Gets the `n`th operand of this string concatenation.
|
||||
*/
|
||||
ConcatenationOperand getOperand(int n) { result = MkConcatenationOperand(asNode(), n) }
|
||||
ConcatenationOperand getOperand(int n) { result = MkConcatenationOperand(this.asNode(), n) }
|
||||
|
||||
/**
|
||||
* Gets an operand of this string concatenation.
|
||||
@@ -384,14 +384,14 @@ module StringOps {
|
||||
*
|
||||
* For example, the first operand of `(x + y) + z` is `(x + y)`.
|
||||
*/
|
||||
ConcatenationOperand getFirstOperand() { result = getOperand(0) }
|
||||
ConcatenationOperand getFirstOperand() { result = this.getOperand(0) }
|
||||
|
||||
/**
|
||||
* Gets the last operand of this string concatenation.
|
||||
*
|
||||
* For example, the last operand of `x + (y + z)` is `(y + z)`.
|
||||
*/
|
||||
ConcatenationOperand getLastOperand() { result = getOperand(getNumOperand() - 1) }
|
||||
ConcatenationOperand getLastOperand() { result = this.getOperand(this.getNumOperand() - 1) }
|
||||
|
||||
/**
|
||||
* Gets the root of the concatenation tree to which this element belongs.
|
||||
@@ -408,22 +408,22 @@ module StringOps {
|
||||
*
|
||||
* For example, the first leaf of `(x + y) + z` is `x`.
|
||||
*/
|
||||
ConcatenationLeaf getFirstLeaf() { result = getFirstOperand*() }
|
||||
ConcatenationLeaf getFirstLeaf() { result = this.getFirstOperand*() }
|
||||
|
||||
/**
|
||||
* Gets the last leaf in this concatenation tree.
|
||||
*
|
||||
* For example, the last leaf of `x + (y + z)` is `z`.
|
||||
*/
|
||||
ConcatenationLeaf getLastLeaf() { result = getLastOperand*() }
|
||||
ConcatenationLeaf getLastLeaf() { result = this.getLastOperand*() }
|
||||
|
||||
/** Gets a textual representation of this concatenation element. */
|
||||
string toString() {
|
||||
if exists(asNode())
|
||||
then result = asNode().toString()
|
||||
if exists(this.asNode())
|
||||
then result = this.asNode().toString()
|
||||
else
|
||||
if exists(getStringValue())
|
||||
then result = getStringValue()
|
||||
if exists(this.getStringValue())
|
||||
then result = this.getStringValue()
|
||||
else result = "concatenation element"
|
||||
}
|
||||
|
||||
@@ -432,15 +432,15 @@ module StringOps {
|
||||
* The location spans column `startcolumn` of line `startline` to
|
||||
* column `endcolumn` of line `endline` in file `filepath`.
|
||||
* For more information, see
|
||||
* [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html).
|
||||
* [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
|
||||
*/
|
||||
predicate hasLocationInfo(
|
||||
string filepath, int startline, int startcolumn, int endline, int endcolumn
|
||||
) {
|
||||
asNode().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
|
||||
this.asNode().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
|
||||
or
|
||||
// use dummy location for elements that don't have a corresponding node
|
||||
not exists(asNode()) and
|
||||
not exists(this.asNode()) and
|
||||
filepath = "" and
|
||||
startline = 0 and
|
||||
startcolumn = 0 and
|
||||
@@ -470,7 +470,7 @@ module StringOps {
|
||||
* See `ConcatenationElement` for more information.
|
||||
*/
|
||||
class ConcatenationLeaf extends ConcatenationOperand {
|
||||
ConcatenationLeaf() { not exists(getAnOperand()) }
|
||||
ConcatenationLeaf() { not exists(this.getAnOperand()) }
|
||||
|
||||
/**
|
||||
* Gets the operand immediately preceding this one in its parent concatenation.
|
||||
@@ -29,7 +29,7 @@ class Type extends @type {
|
||||
* Only (defined) named types like `io.Writer` have a qualified name. Basic types like `int`,
|
||||
* pointer types like `*io.Writer`, and other composite types do not have a qualified name.
|
||||
*/
|
||||
string getQualifiedName() { result = getEntity().getQualifiedName() }
|
||||
string getQualifiedName() { result = this.getEntity().getQualifiedName() }
|
||||
|
||||
/**
|
||||
* Holds if this type is declared in a package with path `pkg` and has name `name`.
|
||||
@@ -37,12 +37,14 @@ class Type extends @type {
|
||||
* Only (defined) named types like `io.Writer` have a qualified name. Basic types like `int`,
|
||||
* pointer types like `*io.Writer`, and other composite types do not have a qualified name.
|
||||
*/
|
||||
predicate hasQualifiedName(string pkg, string name) { getEntity().hasQualifiedName(pkg, name) }
|
||||
predicate hasQualifiedName(string pkg, string name) {
|
||||
this.getEntity().hasQualifiedName(pkg, name)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if the method set of this type contains a method named `m` of type `t`.
|
||||
*/
|
||||
predicate hasMethod(string m, SignatureType t) { t = getMethod(m).getType() }
|
||||
predicate hasMethod(string m, SignatureType t) { t = this.getMethod(m).getType() }
|
||||
|
||||
/**
|
||||
* Gets the method `m` belonging to the method set of this type, if any.
|
||||
@@ -60,7 +62,7 @@ class Type extends @type {
|
||||
*
|
||||
* This includes fields promoted from an embedded field.
|
||||
*/
|
||||
Field getField(string f) { result = getUnderlyingType().getField(f) }
|
||||
Field getField(string f) { result = this.getUnderlyingType().getField(f) }
|
||||
|
||||
/**
|
||||
* Holds if this type implements interface `i`, that is, the method set of `i`
|
||||
@@ -89,12 +91,12 @@ class Type extends @type {
|
||||
/**
|
||||
* Gets a pretty-printed representation of this type, including its structure where applicable.
|
||||
*/
|
||||
string pp() { result = toString() }
|
||||
string pp() { result = this.toString() }
|
||||
|
||||
/**
|
||||
* Gets a basic textual representation of this type.
|
||||
*/
|
||||
string toString() { result = getName() }
|
||||
string toString() { result = this.getName() }
|
||||
}
|
||||
|
||||
/** An invalid type. */
|
||||
@@ -129,7 +131,7 @@ class NumericType extends @numerictype, BasicType {
|
||||
* This predicate is not defined for `uintptr` since the language specification says nothing
|
||||
* about its size.
|
||||
*/
|
||||
int getASize() { result = getSize() }
|
||||
int getASize() { result = this.getSize() }
|
||||
}
|
||||
|
||||
/** An integer type such as `int` or `uint64`. */
|
||||
@@ -313,11 +315,11 @@ class ArrayType extends @arraytype, CompositeType {
|
||||
string getLengthString() { array_length(this, result) }
|
||||
|
||||
/** Gets the length of this array type if it can be represented as a QL integer. */
|
||||
int getLength() { result = getLengthString().toInt() }
|
||||
int getLength() { result = this.getLengthString().toInt() }
|
||||
|
||||
override Package getPackage() { result = this.getElementType().getPackage() }
|
||||
|
||||
override string pp() { result = "[" + getLength() + "]" + getElementType().pp() }
|
||||
override string pp() { result = "[" + this.getLength() + "]" + this.getElementType().pp() }
|
||||
|
||||
override string toString() { result = "array type" }
|
||||
}
|
||||
@@ -329,7 +331,7 @@ class SliceType extends @slicetype, CompositeType {
|
||||
|
||||
override Package getPackage() { result = this.getElementType().getPackage() }
|
||||
|
||||
override string pp() { result = "[]" + getElementType().pp() }
|
||||
override string pp() { result = "[]" + this.getElementType().pp() }
|
||||
|
||||
override string toString() { result = "slice type" }
|
||||
}
|
||||
@@ -445,12 +447,12 @@ class StructType extends @structtype, CompositeType {
|
||||
private Field getFieldCand(string name, int depth, boolean isEmbedded) {
|
||||
result = this.getOwnField(name, isEmbedded) and depth = 0
|
||||
or
|
||||
exists(Type embedded | hasEmbeddedField(embedded, depth - 1) |
|
||||
exists(Type embedded | this.hasEmbeddedField(embedded, depth - 1) |
|
||||
result = embedded.getUnderlyingType().(StructType).getOwnField(name, isEmbedded)
|
||||
)
|
||||
}
|
||||
|
||||
override Field getField(string name) { result = getFieldAtDepth(name, _) }
|
||||
override Field getField(string name) { result = this.getFieldAtDepth(name, _) }
|
||||
|
||||
/**
|
||||
* Gets the field `f` with depth `depth` of this type.
|
||||
@@ -461,14 +463,14 @@ class StructType extends @structtype, CompositeType {
|
||||
* The depth of a field `f` declared in this type is zero.
|
||||
*/
|
||||
Field getFieldAtDepth(string name, int depth) {
|
||||
depth = min(int depthCand | exists(getFieldCand(name, depthCand, _))) and
|
||||
result = getFieldCand(name, depth, _) and
|
||||
strictcount(getFieldCand(name, depth, _)) = 1
|
||||
depth = min(int depthCand | exists(this.getFieldCand(name, depthCand, _))) and
|
||||
result = this.getFieldCand(name, depth, _) and
|
||||
strictcount(this.getFieldCand(name, depth, _)) = 1
|
||||
}
|
||||
|
||||
Method getMethodAtDepth(string name, int depth) {
|
||||
depth = min(int depthCand | hasMethodCand(name, _, depthCand)) and
|
||||
result = unique(Method m | hasMethodCand(name, m, depth))
|
||||
depth = min(int depthCand | this.hasMethodCand(name, _, depthCand)) and
|
||||
result = unique(Method m | this.hasMethodCand(name, m, depth))
|
||||
}
|
||||
|
||||
override predicate hasMethod(string name, SignatureType tp) {
|
||||
@@ -504,15 +506,15 @@ class PointerType extends @pointertype, CompositeType {
|
||||
or
|
||||
// https://golang.org/ref/spec#Method_sets: "the method set of a pointer type *T is
|
||||
// the set of all methods declared with receiver *T or T"
|
||||
result = getBaseType().getMethod(m)
|
||||
result = this.getBaseType().getMethod(m)
|
||||
or
|
||||
// promoted methods from embedded types
|
||||
exists(StructType s, Type embedded |
|
||||
s = getBaseType().(NamedType).getUnderlyingType() and
|
||||
s = this.getBaseType().(NamedType).getUnderlyingType() and
|
||||
s.hasOwnField(_, _, embedded, true) and
|
||||
// ensure that `m` can be promoted
|
||||
not s.hasOwnField(_, m, _, _) and
|
||||
not exists(Method m2 | m2.getReceiverBaseType() = getBaseType() and m2.getName() = m)
|
||||
not exists(Method m2 | m2.getReceiverBaseType() = this.getBaseType() and m2.getName() = m)
|
||||
|
|
||||
result = embedded.getMethod(m)
|
||||
or
|
||||
@@ -525,7 +527,7 @@ class PointerType extends @pointertype, CompositeType {
|
||||
)
|
||||
}
|
||||
|
||||
override string pp() { result = "* " + getBaseType().pp() }
|
||||
override string pp() { result = "* " + this.getBaseType().pp() }
|
||||
|
||||
override string toString() { result = "pointer type" }
|
||||
}
|
||||
@@ -535,14 +537,14 @@ class InterfaceType extends @interfacetype, CompositeType {
|
||||
/** Gets the type of method `name` of this interface type. */
|
||||
Type getMethodType(string name) { component_types(this, _, name, result) }
|
||||
|
||||
override predicate hasMethod(string m, SignatureType t) { t = getMethodType(m) }
|
||||
override predicate hasMethod(string m, SignatureType t) { t = this.getMethodType(m) }
|
||||
|
||||
language[monotonicAggregates]
|
||||
override string pp() {
|
||||
result =
|
||||
"interface { " +
|
||||
concat(string name, Type tp |
|
||||
tp = getMethodType(name)
|
||||
tp = this.getMethodType(name)
|
||||
|
|
||||
name + " " + tp.pp(), "; " order by name
|
||||
) + " }"
|
||||
@@ -559,7 +561,7 @@ class TupleType extends @tupletype, CompositeType {
|
||||
language[monotonicAggregates]
|
||||
override string pp() {
|
||||
result =
|
||||
"(" + concat(int i, Type tp | tp = getComponentType(i) | tp.pp(), ", " order by i) + ")"
|
||||
"(" + concat(int i, Type tp | tp = this.getComponentType(i) | tp.pp(), ", " order by i) + ")"
|
||||
}
|
||||
|
||||
override string toString() { result = "tuple type" }
|
||||
@@ -574,16 +576,16 @@ class SignatureType extends @signaturetype, CompositeType {
|
||||
Type getResultType(int i) { i >= 0 and component_types(this, -(i + 1), _, result) }
|
||||
|
||||
/** Gets the number of parameters specified by this signature. */
|
||||
int getNumParameter() { result = count(int i | exists(getParameterType(i))) }
|
||||
int getNumParameter() { result = count(int i | exists(this.getParameterType(i))) }
|
||||
|
||||
/** Gets the number of results specified by this signature. */
|
||||
int getNumResult() { result = count(int i | exists(getResultType(i))) }
|
||||
int getNumResult() { result = count(int i | exists(this.getResultType(i))) }
|
||||
|
||||
language[monotonicAggregates]
|
||||
override string pp() {
|
||||
result =
|
||||
"func(" + concat(int i, Type tp | tp = getParameterType(i) | tp.pp(), ", " order by i) + ") " +
|
||||
concat(int i, Type tp | tp = getResultType(i) | tp.pp(), ", " order by i)
|
||||
"func(" + concat(int i, Type tp | tp = this.getParameterType(i) | tp.pp(), ", " order by i) +
|
||||
") " + concat(int i, Type tp | tp = this.getResultType(i) | tp.pp(), ", " order by i)
|
||||
}
|
||||
|
||||
override string toString() { result = "signature type" }
|
||||
@@ -597,7 +599,7 @@ class MapType extends @maptype, CompositeType {
|
||||
/** Gets the value type of this map type. */
|
||||
Type getValueType() { element_type(this, result) }
|
||||
|
||||
override string pp() { result = "[" + getKeyType().pp() + "]" + getValueType().pp() }
|
||||
override string pp() { result = "[" + this.getKeyType().pp() + "]" + this.getValueType().pp() }
|
||||
|
||||
override string toString() { result = "map type" }
|
||||
}
|
||||
@@ -618,7 +620,7 @@ class ChanType extends @chantype, CompositeType {
|
||||
class SendChanType extends @sendchantype, ChanType {
|
||||
override predicate canSend() { any() }
|
||||
|
||||
override string pp() { result = "chan<- " + getElementType().pp() }
|
||||
override string pp() { result = "chan<- " + this.getElementType().pp() }
|
||||
|
||||
override string toString() { result = "send-channel type" }
|
||||
}
|
||||
@@ -627,7 +629,7 @@ class SendChanType extends @sendchantype, ChanType {
|
||||
class RecvChanType extends @recvchantype, ChanType {
|
||||
override predicate canReceive() { any() }
|
||||
|
||||
override string pp() { result = "<-chan " + getElementType().pp() }
|
||||
override string pp() { result = "<-chan " + this.getElementType().pp() }
|
||||
|
||||
override string toString() { result = "receive-channel type" }
|
||||
}
|
||||
@@ -638,7 +640,7 @@ class SendRecvChanType extends @sendrcvchantype, ChanType {
|
||||
|
||||
override predicate canReceive() { any() }
|
||||
|
||||
override string pp() { result = "chan " + getElementType().pp() }
|
||||
override string pp() { result = "chan " + this.getElementType().pp() }
|
||||
|
||||
override string toString() { result = "send-receive-channel type" }
|
||||
}
|
||||
@@ -656,7 +658,7 @@ class NamedType extends @namedtype, CompositeType {
|
||||
or
|
||||
// handle promoted methods
|
||||
exists(StructType s, Type embedded |
|
||||
s = getBaseType() and
|
||||
s = this.getBaseType() and
|
||||
s.hasOwnField(_, _, embedded, true) and
|
||||
// ensure `m` can be promoted
|
||||
not s.hasOwnField(_, m, _, _) and
|
||||
@@ -670,7 +672,7 @@ class NamedType extends @namedtype, CompositeType {
|
||||
)
|
||||
}
|
||||
|
||||
override Type getUnderlyingType() { result = getBaseType().getUnderlyingType() }
|
||||
override Type getUnderlyingType() { result = this.getBaseType().getUnderlyingType() }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -188,7 +188,7 @@ class VariableWithFields extends TVariableWithFields {
|
||||
* The location spans column `startcolumn` of line `startline` to
|
||||
* column `endcolumn` of line `endline` in file `filepath`.
|
||||
* For more information, see
|
||||
* [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html).
|
||||
* [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
|
||||
*/
|
||||
predicate hasLocationInfo(
|
||||
string filepath, int startline, int startcolumn, int endline, int endcolumn
|
||||
@@ -191,17 +191,17 @@ module HTTP {
|
||||
|
||||
/** Gets a content-type associated with this body. */
|
||||
string getAContentType() {
|
||||
exists(HTTP::HeaderWrite hw | hw = getResponseWriter().getAHeaderWrite() |
|
||||
exists(HTTP::HeaderWrite hw | hw = this.getResponseWriter().getAHeaderWrite() |
|
||||
hw.getHeaderName() = "content-type" and
|
||||
result = hw.getHeaderValue()
|
||||
)
|
||||
or
|
||||
result = getAContentTypeNode().getStringValue()
|
||||
result = this.getAContentTypeNode().getStringValue()
|
||||
}
|
||||
|
||||
/** Gets a dataflow node for a content-type associated with this body. */
|
||||
DataFlow::Node getAContentTypeNode() {
|
||||
exists(HTTP::HeaderWrite hw | hw = getResponseWriter().getAHeaderWrite() |
|
||||
exists(HTTP::HeaderWrite hw | hw = this.getResponseWriter().getAHeaderWrite() |
|
||||
hw.getHeaderName() = "content-type" and
|
||||
result = hw.getValue()
|
||||
)
|
||||
@@ -119,7 +119,7 @@ class BasicBlock extends TControlFlowNode {
|
||||
* The location spans column `startcolumn` of line `startline` to
|
||||
* column `endcolumn` of line `endline` in file `filepath`.
|
||||
* For more information, see
|
||||
* [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html).
|
||||
* [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
|
||||
*/
|
||||
predicate hasLocationInfo(
|
||||
string filepath, int startline, int startcolumn, int endline, int endcolumn
|
||||
@@ -89,7 +89,7 @@ module ControlFlow {
|
||||
* The location spans column `startcolumn` of line `startline` to
|
||||
* column `endcolumn` of line `endline` in file `filepath`.
|
||||
* For more information, see
|
||||
* [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html).
|
||||
* [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
|
||||
*/
|
||||
predicate hasLocationInfo(
|
||||
string filepath, int startline, int startcolumn, int endline, int endcolumn
|
||||
File diff suppressed because it is too large
Load Diff
@@ -387,7 +387,7 @@ module IR {
|
||||
Method getMethod() { result = method }
|
||||
|
||||
override predicate readsMethod(Instruction receiver, Method m) {
|
||||
receiver = getReceiver() and m = getMethod()
|
||||
receiver = this.getReceiver() and m = this.getMethod()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -401,7 +401,7 @@ module IR {
|
||||
Instruction getIndex() { result = evalExprInstruction(e.getIndex()) }
|
||||
|
||||
override predicate readsElement(Instruction base, Instruction index) {
|
||||
base = getBase() and index = getIndex()
|
||||
base = this.getBase() and index = this.getIndex()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -454,8 +454,8 @@ module IR {
|
||||
Instruction getRhs() { none() }
|
||||
|
||||
override predicate writes(ValueEntity v, Instruction rhs) {
|
||||
getLhs().refersTo(v) and
|
||||
rhs = getRhs()
|
||||
this.getLhs().refersTo(v) and
|
||||
rhs = this.getRhs()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -506,7 +506,7 @@ module IR {
|
||||
/** Gets the initialized field. */
|
||||
Field getField() {
|
||||
result.getDeclaringType() = lit.getStructType() and
|
||||
result.getName() = getFieldName()
|
||||
result.getName() = this.getFieldName()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -567,9 +567,9 @@ module IR {
|
||||
Field getField() { result = lhs.getField() }
|
||||
|
||||
override predicate writesField(Instruction base, Field f, Instruction rhs) {
|
||||
getBase() = base and
|
||||
getField() = f and
|
||||
getRhs() = rhs
|
||||
this.getBase() = base and
|
||||
this.getField() = f and
|
||||
this.getRhs() = rhs
|
||||
}
|
||||
}
|
||||
|
||||
@@ -586,8 +586,8 @@ module IR {
|
||||
Instruction getIndex() { result = lhs.getIndex() }
|
||||
|
||||
override predicate writesElement(Instruction base, Instruction index) {
|
||||
getBase() = base and
|
||||
getIndex() = index
|
||||
this.getBase() = base and
|
||||
this.getIndex() = index
|
||||
}
|
||||
}
|
||||
|
||||
@@ -635,7 +635,7 @@ module IR {
|
||||
|
||||
override string getStringValue() { none() }
|
||||
|
||||
override string getExactValue() { result = getIntValue().toString() }
|
||||
override string getExactValue() { result = this.getIntValue().toString() }
|
||||
|
||||
override predicate isPlatformIndependentConstant() { any() }
|
||||
|
||||
@@ -681,12 +681,12 @@ module IR {
|
||||
|
||||
override ControlFlow::Root getRoot() { result.isRootOf(assgn) }
|
||||
|
||||
override string toString() { result = "assignment to " + getLhs() }
|
||||
override string toString() { result = "assignment to " + this.getLhs() }
|
||||
|
||||
override predicate hasLocationInfo(
|
||||
string filepath, int startline, int startcolumn, int endline, int endcolumn
|
||||
) {
|
||||
getLhs().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
|
||||
this.getLhs().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -829,10 +829,10 @@ module IR {
|
||||
}
|
||||
|
||||
override string getExactValue() {
|
||||
result = getIntValue().toString() or
|
||||
result = getFloatValue().toString() or
|
||||
result = getStringValue().toString() or
|
||||
result = getBoolValue().toString()
|
||||
result = this.getIntValue().toString() or
|
||||
result = this.getFloatValue().toString() or
|
||||
result = this.getStringValue().toString() or
|
||||
result = this.getBoolValue().toString()
|
||||
}
|
||||
|
||||
override predicate isConst() { any() }
|
||||
@@ -999,7 +999,7 @@ module IR {
|
||||
|
||||
/** Gets the instruction whose result is the (unique) result returned by this statement. */
|
||||
Instruction getResult() {
|
||||
not returnsMultipleResults() and
|
||||
not this.returnsMultipleResults() and
|
||||
result = evalExprInstruction(ret.getExpr())
|
||||
}
|
||||
|
||||
@@ -1386,7 +1386,7 @@ module IR {
|
||||
|
||||
/** Gets the SSA variable being written to, if any. */
|
||||
SsaVariable asSsaVariable() {
|
||||
getWrite() = result.getDefinition().(SsaExplicitDefinition).getInstruction()
|
||||
this.getWrite() = result.getDefinition().(SsaExplicitDefinition).getInstruction()
|
||||
}
|
||||
|
||||
/** Holds if `e` is the variable or field being written to. */
|
||||
@@ -1400,7 +1400,7 @@ module IR {
|
||||
* The location spans column `startcolumn` of line `startline` to
|
||||
* column `endcolumn` of line `endline` in file `filepath`.
|
||||
* For more information, see
|
||||
* [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html).
|
||||
* [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
|
||||
*/
|
||||
predicate hasLocationInfo(
|
||||
string filepath, int startline, int startcolumn, int endline, int endcolumn
|
||||
@@ -1451,12 +1451,12 @@ module IR {
|
||||
}
|
||||
|
||||
/** Gets the variable this refers to, if any. */
|
||||
Variable getVariable() { refersTo(result) }
|
||||
Variable getVariable() { this.refersTo(result) }
|
||||
|
||||
/** Gets the constant this refers to, if any. */
|
||||
Constant getConstant() { refersTo(result) }
|
||||
Constant getConstant() { this.refersTo(result) }
|
||||
|
||||
override string toString() { result = getName() }
|
||||
override string toString() { result = this.getName() }
|
||||
|
||||
override predicate hasLocationInfo(
|
||||
string filepath, int startline, int startcolumn, int endline, int endcolumn
|
||||
@@ -1492,7 +1492,7 @@ module IR {
|
||||
override string getName() { exists(Field f | this.refersTo(f) | result = f.getName()) }
|
||||
|
||||
/** Gets the field this refers to, if it can be determined. */
|
||||
Field getField() { refersTo(result) }
|
||||
Field getField() { this.refersTo(result) }
|
||||
|
||||
override string toString() {
|
||||
exists(SelectorExpr sel | this = MkLhs(_, sel) |
|
||||
@@ -314,7 +314,7 @@ class GVN extends GVNBase {
|
||||
* The location spans column `startcolumn` of line `startline` to
|
||||
* column `endcolumn` of line `endline` in file `filepath`.
|
||||
* For more information, see
|
||||
* [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html).
|
||||
* [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
|
||||
*/
|
||||
predicate hasLocationInfo(
|
||||
string filepath, int startline, int startcolumn, int endline, int endcolumn
|
||||
@@ -55,7 +55,7 @@ class Property extends TProperty {
|
||||
* subexpression of `test`.
|
||||
*/
|
||||
predicate checkOn(DataFlow::Node test, Boolean outcome, DataFlow::Node nd) {
|
||||
checkOnExpr(test.asExpr(), outcome, nd)
|
||||
this.checkOnExpr(test.asExpr(), outcome, nd)
|
||||
}
|
||||
|
||||
/** Holds if this is the property of having the Boolean value `b`. */
|
||||
@@ -10,7 +10,7 @@ private import SsaImpl
|
||||
* declared in file scope.
|
||||
*/
|
||||
class SsaSourceVariable extends LocalVariable {
|
||||
SsaSourceVariable() { not getScope() instanceof FileScope }
|
||||
SsaSourceVariable() { not this.getScope() instanceof FileScope }
|
||||
|
||||
/**
|
||||
* Holds if there may be indirect references of this variable that are not covered by `getAReference()`.
|
||||
@@ -20,10 +20,10 @@ class SsaSourceVariable extends LocalVariable {
|
||||
*/
|
||||
predicate mayHaveIndirectReferences() {
|
||||
// variables that have their address taken
|
||||
exists(AddressExpr addr | addr.getOperand().stripParens() = getAReference())
|
||||
exists(AddressExpr addr | addr.getOperand().stripParens() = this.getAReference())
|
||||
or
|
||||
exists(DataFlow::MethodReadNode mrn |
|
||||
mrn.getReceiver() = getARead() and
|
||||
mrn.getReceiver() = this.getARead() and
|
||||
mrn.getMethod().getReceiverType() instanceof PointerType
|
||||
)
|
||||
or
|
||||
@@ -31,7 +31,7 @@ class SsaSourceVariable extends LocalVariable {
|
||||
// scope or a nested scope, suggesting that name resolution information may be incomplete
|
||||
exists(FunctionScope scope, FuncDef inner |
|
||||
scope = this.getScope().(LocalScope).getEnclosingFunctionScope() and
|
||||
unresolvedReference(getName(), inner) and
|
||||
unresolvedReference(this.getName(), inner) and
|
||||
inner.getScope().getOuterScope*() = scope
|
||||
)
|
||||
}
|
||||
@@ -69,33 +69,33 @@ class SsaVariable extends TSsaDefinition {
|
||||
SsaDefinition getDefinition() { result = this }
|
||||
|
||||
/** Gets the type of this SSA variable. */
|
||||
Type getType() { result = getSourceVariable().getType() }
|
||||
Type getType() { result = this.getSourceVariable().getType() }
|
||||
|
||||
/** Gets a use in basic block `bb` that refers to this SSA variable. */
|
||||
IR::Instruction getAUseIn(ReachableBasicBlock bb) {
|
||||
exists(int i, SsaSourceVariable v | v = getSourceVariable() |
|
||||
exists(int i, SsaSourceVariable v | v = this.getSourceVariable() |
|
||||
result = bb.getNode(i) and
|
||||
this = getDefinition(bb, i, v)
|
||||
)
|
||||
}
|
||||
|
||||
/** Gets a use that refers to this SSA variable. */
|
||||
IR::Instruction getAUse() { result = getAUseIn(_) }
|
||||
IR::Instruction getAUse() { result = this.getAUseIn(_) }
|
||||
|
||||
/** Gets a textual representation of this element. */
|
||||
string toString() { result = getDefinition().prettyPrintRef() }
|
||||
string toString() { result = this.getDefinition().prettyPrintRef() }
|
||||
|
||||
/**
|
||||
* Holds if this element is at the specified location.
|
||||
* The location spans column `startcolumn` of line `startline` to
|
||||
* column `endcolumn` of line `endline` in file `filepath`.
|
||||
* For more information, see
|
||||
* [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html).
|
||||
* [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
|
||||
*/
|
||||
predicate hasLocationInfo(
|
||||
string filepath, int startline, int startcolumn, int endline, int endcolumn
|
||||
) {
|
||||
getDefinition().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
|
||||
this.getDefinition().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -139,17 +139,17 @@ class SsaDefinition extends TSsaDefinition {
|
||||
abstract string prettyPrintRef();
|
||||
|
||||
/** Gets the innermost function or file to which this SSA definition belongs. */
|
||||
ControlFlow::Root getRoot() { result = getBasicBlock().getRoot() }
|
||||
ControlFlow::Root getRoot() { result = this.getBasicBlock().getRoot() }
|
||||
|
||||
/** Gets a textual representation of this element. */
|
||||
string toString() { result = prettyPrintDef() }
|
||||
string toString() { result = this.prettyPrintDef() }
|
||||
|
||||
/**
|
||||
* Holds if this element is at the specified location.
|
||||
* The location spans column `startcolumn` of line `startline` to
|
||||
* column `endcolumn` of line `endline` in file `filepath`.
|
||||
* For more information, see
|
||||
* [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html).
|
||||
* [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
|
||||
*/
|
||||
abstract predicate hasLocationInfo(
|
||||
string filepath, int startline, int startcolumn, int endline, int endcolumn
|
||||
@@ -166,26 +166,26 @@ class SsaExplicitDefinition extends SsaDefinition, TExplicitDef {
|
||||
}
|
||||
|
||||
/** Gets the right-hand side of the definition. */
|
||||
IR::Instruction getRhs() { getInstruction().writes(_, result) }
|
||||
IR::Instruction getRhs() { this.getInstruction().writes(_, result) }
|
||||
|
||||
override predicate definesAt(ReachableBasicBlock bb, int i, SsaSourceVariable v) {
|
||||
this = TExplicitDef(bb, i, v)
|
||||
}
|
||||
|
||||
override ReachableBasicBlock getBasicBlock() { definesAt(result, _, _) }
|
||||
override ReachableBasicBlock getBasicBlock() { this.definesAt(result, _, _) }
|
||||
|
||||
override SsaSourceVariable getSourceVariable() { this = TExplicitDef(_, _, result) }
|
||||
|
||||
override string prettyPrintRef() {
|
||||
exists(int l, int c | hasLocationInfo(_, l, c, _, _) | result = "def@" + l + ":" + c)
|
||||
exists(int l, int c | this.hasLocationInfo(_, l, c, _, _) | result = "def@" + l + ":" + c)
|
||||
}
|
||||
|
||||
override string prettyPrintDef() { result = "definition of " + getSourceVariable() }
|
||||
override string prettyPrintDef() { result = "definition of " + this.getSourceVariable() }
|
||||
|
||||
override predicate hasLocationInfo(
|
||||
string filepath, int startline, int startcolumn, int endline, int endcolumn
|
||||
) {
|
||||
getInstruction().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
|
||||
this.getInstruction().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -209,7 +209,9 @@ abstract class SsaImplicitDefinition extends SsaDefinition {
|
||||
abstract string getKind();
|
||||
|
||||
override string prettyPrintRef() {
|
||||
exists(int l, int c | hasLocationInfo(_, l, c, _, _) | result = getKind() + "@" + l + ":" + c)
|
||||
exists(int l, int c | this.hasLocationInfo(_, l, c, _, _) |
|
||||
result = this.getKind() + "@" + l + ":" + c
|
||||
)
|
||||
}
|
||||
|
||||
override predicate hasLocationInfo(
|
||||
@@ -217,7 +219,7 @@ abstract class SsaImplicitDefinition extends SsaDefinition {
|
||||
) {
|
||||
endline = startline and
|
||||
endcolumn = startcolumn and
|
||||
getBasicBlock().hasLocationInfo(filepath, startline, startcolumn, _, _)
|
||||
this.getBasicBlock().hasLocationInfo(filepath, startline, startcolumn, _, _)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -233,18 +235,18 @@ class SsaVariableCapture extends SsaImplicitDefinition, TCapture {
|
||||
this = TCapture(bb, i, v)
|
||||
}
|
||||
|
||||
override ReachableBasicBlock getBasicBlock() { definesAt(result, _, _) }
|
||||
override ReachableBasicBlock getBasicBlock() { this.definesAt(result, _, _) }
|
||||
|
||||
override SsaSourceVariable getSourceVariable() { definesAt(_, _, result) }
|
||||
override SsaSourceVariable getSourceVariable() { this.definesAt(_, _, result) }
|
||||
|
||||
override string getKind() { result = "capture" }
|
||||
|
||||
override string prettyPrintDef() { result = "capture variable " + getSourceVariable() }
|
||||
override string prettyPrintDef() { result = "capture variable " + this.getSourceVariable() }
|
||||
|
||||
override predicate hasLocationInfo(
|
||||
string filepath, int startline, int startcolumn, int endline, int endcolumn
|
||||
) {
|
||||
exists(ReachableBasicBlock bb, int i | definesAt(bb, i, _) |
|
||||
exists(ReachableBasicBlock bb, int i | this.definesAt(bb, i, _) |
|
||||
bb.getNode(i).hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
|
||||
)
|
||||
}
|
||||
@@ -264,7 +266,7 @@ abstract class SsaPseudoDefinition extends SsaImplicitDefinition {
|
||||
* Gets a textual representation of the inputs of this pseudo-definition
|
||||
* in lexicographical order.
|
||||
*/
|
||||
string ppInputs() { result = concat(getAnInput().getDefinition().prettyPrintRef(), ", ") }
|
||||
string ppInputs() { result = concat(this.getAnInput().getDefinition().prettyPrintRef(), ", ") }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -274,11 +276,11 @@ abstract class SsaPseudoDefinition extends SsaImplicitDefinition {
|
||||
*/
|
||||
class SsaPhiNode extends SsaPseudoDefinition, TPhi {
|
||||
override SsaVariable getAnInput() {
|
||||
result = getDefReachingEndOf(getBasicBlock().getAPredecessor(), getSourceVariable())
|
||||
result = getDefReachingEndOf(this.getBasicBlock().getAPredecessor(), this.getSourceVariable())
|
||||
}
|
||||
|
||||
override predicate definesAt(ReachableBasicBlock bb, int i, SsaSourceVariable v) {
|
||||
bb = getBasicBlock() and v = getSourceVariable() and i = -1
|
||||
bb = this.getBasicBlock() and v = this.getSourceVariable() and i = -1
|
||||
}
|
||||
|
||||
override ReachableBasicBlock getBasicBlock() { this = TPhi(result, _) }
|
||||
@@ -287,14 +289,16 @@ class SsaPhiNode extends SsaPseudoDefinition, TPhi {
|
||||
|
||||
override string getKind() { result = "phi" }
|
||||
|
||||
override string prettyPrintDef() { result = getSourceVariable() + " = phi(" + ppInputs() + ")" }
|
||||
override string prettyPrintDef() {
|
||||
result = this.getSourceVariable() + " = phi(" + this.ppInputs() + ")"
|
||||
}
|
||||
|
||||
override predicate hasLocationInfo(
|
||||
string filepath, int startline, int startcolumn, int endline, int endcolumn
|
||||
) {
|
||||
endline = startline and
|
||||
endcolumn = startcolumn and
|
||||
getBasicBlock().hasLocationInfo(filepath, startline, startcolumn, _, _)
|
||||
this.getBasicBlock().hasLocationInfo(filepath, startline, startcolumn, _, _)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -388,7 +392,7 @@ class SsaWithFields extends TSsaWithFields {
|
||||
* The location spans column `startcolumn` of line `startline` to
|
||||
* column `endcolumn` of line `endline` in file `filepath`.
|
||||
* For more information, see
|
||||
* [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html).
|
||||
* [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
|
||||
*/
|
||||
predicate hasLocationInfo(
|
||||
string filepath, int startline, int startcolumn, int endline, int endcolumn
|
||||
@@ -15,7 +15,7 @@ class RedirectCheckBarrierGuard extends DataFlow::BarrierGuard, DataFlow::CallNo
|
||||
|
||||
override predicate checks(Expr e, boolean outcome) {
|
||||
// `isLocalUrl(e)` is a barrier for `e` if it evaluates to `true`
|
||||
getAnArgument().asExpr() = e and
|
||||
this.getAnArgument().asExpr() = e and
|
||||
outcome = true
|
||||
}
|
||||
}
|
||||
@@ -104,12 +104,12 @@ abstract class Configuration extends string {
|
||||
/**
|
||||
* Holds if data may flow from some source to `sink` for this configuration.
|
||||
*/
|
||||
predicate hasFlowTo(Node sink) { hasFlow(_, sink) }
|
||||
predicate hasFlowTo(Node sink) { this.hasFlow(_, sink) }
|
||||
|
||||
/**
|
||||
* Holds if data may flow from some source to `sink` for this configuration.
|
||||
*/
|
||||
predicate hasFlowToExpr(DataFlowExpr sink) { hasFlowTo(exprNode(sink)) }
|
||||
predicate hasFlowToExpr(DataFlowExpr sink) { this.hasFlowTo(exprNode(sink)) }
|
||||
|
||||
/**
|
||||
* Gets the exploration limit for `hasPartialFlow` and `hasPartialFlowRev`
|
||||
@@ -2873,7 +2873,7 @@ private class AccessPathCons extends AccessPath, TAccessPathCons {
|
||||
}
|
||||
|
||||
override string toString() {
|
||||
result = "[" + this.toStringImpl(true) + length().toString() + ")]"
|
||||
result = "[" + this.toStringImpl(true) + this.length().toString() + ")]"
|
||||
or
|
||||
result = "[" + this.toStringImpl(false)
|
||||
}
|
||||
@@ -2955,7 +2955,7 @@ class PathNode extends TPathNode {
|
||||
* The location spans column `startcolumn` of line `startline` to
|
||||
* column `endcolumn` of line `endline` in file `filepath`.
|
||||
* For more information, see
|
||||
* [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html).
|
||||
* [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
|
||||
*/
|
||||
predicate hasLocationInfo(
|
||||
string filepath, int startline, int startcolumn, int endline, int endcolumn
|
||||
@@ -3008,9 +3008,11 @@ abstract private class PathNodeImpl extends PathNode {
|
||||
result = " <" + this.(PathNodeMid).getCallContext().toString() + ">"
|
||||
}
|
||||
|
||||
override string toString() { result = this.getNode().toString() + ppAp() }
|
||||
override string toString() { result = this.getNode().toString() + this.ppAp() }
|
||||
|
||||
override string toStringWithContext() { result = this.getNode().toString() + ppAp() + ppCtx() }
|
||||
override string toStringWithContext() {
|
||||
result = this.getNode().toString() + this.ppAp() + this.ppCtx()
|
||||
}
|
||||
|
||||
override predicate hasLocationInfo(
|
||||
string filepath, int startline, int startcolumn, int endline, int endcolumn
|
||||
@@ -3070,11 +3072,11 @@ private class PathNodeMid extends PathNodeImpl, TPathNodeMid {
|
||||
|
||||
override PathNodeImpl getASuccessorImpl() {
|
||||
// an intermediate step to another intermediate node
|
||||
result = getSuccMid()
|
||||
result = this.getSuccMid()
|
||||
or
|
||||
// a final step to a sink via zero steps means we merge the last two steps to prevent trivial-looking edges
|
||||
exists(PathNodeMid mid, PathNodeSink sink |
|
||||
mid = getSuccMid() and
|
||||
mid = this.getSuccMid() and
|
||||
mid.getNode() = sink.getNode() and
|
||||
mid.getAp() instanceof AccessPathNil and
|
||||
sink.getConfiguration() = unbindConf(mid.getConfiguration()) and
|
||||
@@ -3641,7 +3643,7 @@ private module FlowExploration {
|
||||
* The location spans column `startcolumn` of line `startline` to
|
||||
* column `endcolumn` of line `endline` in file `filepath`.
|
||||
* For more information, see
|
||||
* [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html).
|
||||
* [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
|
||||
*/
|
||||
predicate hasLocationInfo(
|
||||
string filepath, int startline, int startcolumn, int endline, int endcolumn
|
||||
@@ -104,12 +104,12 @@ abstract class Configuration extends string {
|
||||
/**
|
||||
* Holds if data may flow from some source to `sink` for this configuration.
|
||||
*/
|
||||
predicate hasFlowTo(Node sink) { hasFlow(_, sink) }
|
||||
predicate hasFlowTo(Node sink) { this.hasFlow(_, sink) }
|
||||
|
||||
/**
|
||||
* Holds if data may flow from some source to `sink` for this configuration.
|
||||
*/
|
||||
predicate hasFlowToExpr(DataFlowExpr sink) { hasFlowTo(exprNode(sink)) }
|
||||
predicate hasFlowToExpr(DataFlowExpr sink) { this.hasFlowTo(exprNode(sink)) }
|
||||
|
||||
/**
|
||||
* Gets the exploration limit for `hasPartialFlow` and `hasPartialFlowRev`
|
||||
@@ -2873,7 +2873,7 @@ private class AccessPathCons extends AccessPath, TAccessPathCons {
|
||||
}
|
||||
|
||||
override string toString() {
|
||||
result = "[" + this.toStringImpl(true) + length().toString() + ")]"
|
||||
result = "[" + this.toStringImpl(true) + this.length().toString() + ")]"
|
||||
or
|
||||
result = "[" + this.toStringImpl(false)
|
||||
}
|
||||
@@ -2955,7 +2955,7 @@ class PathNode extends TPathNode {
|
||||
* The location spans column `startcolumn` of line `startline` to
|
||||
* column `endcolumn` of line `endline` in file `filepath`.
|
||||
* For more information, see
|
||||
* [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html).
|
||||
* [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
|
||||
*/
|
||||
predicate hasLocationInfo(
|
||||
string filepath, int startline, int startcolumn, int endline, int endcolumn
|
||||
@@ -3008,9 +3008,11 @@ abstract private class PathNodeImpl extends PathNode {
|
||||
result = " <" + this.(PathNodeMid).getCallContext().toString() + ">"
|
||||
}
|
||||
|
||||
override string toString() { result = this.getNode().toString() + ppAp() }
|
||||
override string toString() { result = this.getNode().toString() + this.ppAp() }
|
||||
|
||||
override string toStringWithContext() { result = this.getNode().toString() + ppAp() + ppCtx() }
|
||||
override string toStringWithContext() {
|
||||
result = this.getNode().toString() + this.ppAp() + this.ppCtx()
|
||||
}
|
||||
|
||||
override predicate hasLocationInfo(
|
||||
string filepath, int startline, int startcolumn, int endline, int endcolumn
|
||||
@@ -3070,11 +3072,11 @@ private class PathNodeMid extends PathNodeImpl, TPathNodeMid {
|
||||
|
||||
override PathNodeImpl getASuccessorImpl() {
|
||||
// an intermediate step to another intermediate node
|
||||
result = getSuccMid()
|
||||
result = this.getSuccMid()
|
||||
or
|
||||
// a final step to a sink via zero steps means we merge the last two steps to prevent trivial-looking edges
|
||||
exists(PathNodeMid mid, PathNodeSink sink |
|
||||
mid = getSuccMid() and
|
||||
mid = this.getSuccMid() and
|
||||
mid.getNode() = sink.getNode() and
|
||||
mid.getAp() instanceof AccessPathNil and
|
||||
sink.getConfiguration() = unbindConf(mid.getConfiguration()) and
|
||||
@@ -3641,7 +3643,7 @@ private module FlowExploration {
|
||||
* The location spans column `startcolumn` of line `startline` to
|
||||
* column `endcolumn` of line `endline` in file `filepath`.
|
||||
* For more information, see
|
||||
* [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html).
|
||||
* [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
|
||||
*/
|
||||
predicate hasLocationInfo(
|
||||
string filepath, int startline, int startcolumn, int endline, int endcolumn
|
||||
@@ -924,7 +924,7 @@ class CallContextSpecificCall extends CallContextCall, TSpecificCall {
|
||||
}
|
||||
|
||||
override predicate relevantFor(DataFlowCallable callable) {
|
||||
recordDataFlowCallSite(getCall(), callable)
|
||||
recordDataFlowCallSite(this.getCall(), callable)
|
||||
}
|
||||
|
||||
override predicate matchesCall(DataFlowCall call) { call = this.getCall() }
|
||||
@@ -1195,7 +1195,7 @@ abstract class AccessPathFront extends TAccessPathFront {
|
||||
|
||||
TypedContent getHead() { this = TFrontHead(result) }
|
||||
|
||||
predicate isClearedAt(Node n) { clearsContentCached(n, getHead().getContent()) }
|
||||
predicate isClearedAt(Node n) { clearsContentCached(n, this.getHead().getContent()) }
|
||||
}
|
||||
|
||||
class AccessPathFrontNil extends AccessPathFront, TFrontNil {
|
||||
@@ -24,7 +24,7 @@ class Node extends TNode {
|
||||
ControlFlow::Root getRoot() { none() } // overridden in subclasses
|
||||
|
||||
/** INTERNAL: Use `getRoot()` instead. */
|
||||
FuncDef getEnclosingCallable() { result = getRoot() }
|
||||
FuncDef getEnclosingCallable() { result = this.getRoot() }
|
||||
|
||||
/** Gets the type of this node. */
|
||||
Type getType() { none() } // overridden in subclasses
|
||||
@@ -42,7 +42,7 @@ class Node extends TNode {
|
||||
string getNodeKind() { none() } // overridden in subclasses
|
||||
|
||||
/** Gets the basic block to which this data-flow node belongs, if any. */
|
||||
BasicBlock getBasicBlock() { result = asInstruction().getBasicBlock() }
|
||||
BasicBlock getBasicBlock() { result = this.asInstruction().getBasicBlock() }
|
||||
|
||||
/** Gets a textual representation of this element. */
|
||||
string toString() { result = "data-flow node" } // overridden in subclasses
|
||||
@@ -52,7 +52,7 @@ class Node extends TNode {
|
||||
* The location spans column `startcolumn` of line `startline` to
|
||||
* column `endcolumn` of line `endline` in file `filepath`.
|
||||
* For more information, see
|
||||
* [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html).
|
||||
* [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
|
||||
*/
|
||||
predicate hasLocationInfo(
|
||||
string filepath, int startline, int startcolumn, int endline, int endcolumn
|
||||
@@ -65,24 +65,24 @@ class Node extends TNode {
|
||||
}
|
||||
|
||||
/** Gets the file in which this node appears. */
|
||||
File getFile() { hasLocationInfo(result.getAbsolutePath(), _, _, _, _) }
|
||||
File getFile() { this.hasLocationInfo(result.getAbsolutePath(), _, _, _, _) }
|
||||
|
||||
/** Gets the start line of the location of this node. */
|
||||
int getStartLine() { hasLocationInfo(_, result, _, _, _) }
|
||||
int getStartLine() { this.hasLocationInfo(_, result, _, _, _) }
|
||||
|
||||
/** Gets the start column of the location of this node. */
|
||||
int getStartColumn() { hasLocationInfo(_, _, result, _, _) }
|
||||
int getStartColumn() { this.hasLocationInfo(_, _, result, _, _) }
|
||||
|
||||
/** Gets the end line of the location of this node. */
|
||||
int getEndLine() { hasLocationInfo(_, _, _, result, _) }
|
||||
int getEndLine() { this.hasLocationInfo(_, _, _, result, _) }
|
||||
|
||||
/** Gets the end column of the location of this node. */
|
||||
int getEndColumn() { hasLocationInfo(_, _, _, _, result) }
|
||||
int getEndColumn() { this.hasLocationInfo(_, _, _, _, result) }
|
||||
|
||||
/**
|
||||
* Gets an upper bound on the type of this node.
|
||||
*/
|
||||
Type getTypeBound() { result = getType() }
|
||||
Type getTypeBound() { result = this.getType() }
|
||||
|
||||
/** Gets the floating-point value this data-flow node contains, if any. */
|
||||
float getFloatValue() { result = this.asExpr().getFloatValue() }
|
||||
@@ -277,7 +277,7 @@ class FunctionNode extends Node {
|
||||
/**
|
||||
* Gets the data-flow node corresponding to the `i`th result of this function.
|
||||
*/
|
||||
ResultNode getResult(int i) { result = getAResult() and result.getIndex() = i }
|
||||
ResultNode getResult(int i) { result = this.getAResult() and result.getIndex() = i }
|
||||
|
||||
/**
|
||||
* Gets the function entity this node corresponds to.
|
||||
@@ -312,7 +312,7 @@ class GlobalFunctionNode extends FunctionNode::Range, MkGlobalFunctionNode {
|
||||
}
|
||||
|
||||
override ResultNode getAResult() {
|
||||
result.getRoot() = getFunction().(DeclaredFunction).getFuncDecl()
|
||||
result.getRoot() = this.getFunction().(DeclaredFunction).getFuncDecl()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -328,7 +328,7 @@ class FuncLitNode extends FunctionNode::Range, ExprNode {
|
||||
|
||||
override string toString() { result = "function literal" }
|
||||
|
||||
override ResultNode getAResult() { result.getRoot() = getExpr() }
|
||||
override ResultNode getAResult() { result.getRoot() = this.getExpr() }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -364,9 +364,9 @@ class CallNode extends ExprNode {
|
||||
* interface type.
|
||||
*/
|
||||
FuncDef getACallee() {
|
||||
result = getTarget().(DeclaredFunction).getFuncDecl()
|
||||
result = this.getTarget().(DeclaredFunction).getFuncDecl()
|
||||
or
|
||||
exists(DataFlow::Node calleeSource | calleeSource = getACalleeSource() |
|
||||
exists(DataFlow::Node calleeSource | calleeSource = this.getACalleeSource() |
|
||||
result = calleeSource.asExpr()
|
||||
or
|
||||
exists(Method declared, Method actual |
|
||||
@@ -418,7 +418,7 @@ class CallNode extends ExprNode {
|
||||
* If there is a single result then it is considered to be the 0th result.
|
||||
*/
|
||||
Node getResult(int i) {
|
||||
i = 0 and result = getResult()
|
||||
i = 0 and result = this.getResult()
|
||||
or
|
||||
result = extractTupleElement(this, i)
|
||||
}
|
||||
@@ -429,13 +429,13 @@ class CallNode extends ExprNode {
|
||||
* Note that this predicate is not defined for calls with multiple results; use the one-argument
|
||||
* variant `getResult(i)` for such calls.
|
||||
*/
|
||||
Node getResult() { not getType() instanceof TupleType and result = this }
|
||||
Node getResult() { not this.getType() instanceof TupleType and result = this }
|
||||
|
||||
/** Gets a result of this call. */
|
||||
Node getAResult() { result = this.getResult(_) }
|
||||
|
||||
/** Gets the data flow node corresponding to the receiver of this call, if any. */
|
||||
Node getReceiver() { result = getACalleeSource().(MethodReadNode).getReceiver() }
|
||||
Node getReceiver() { result = this.getACalleeSource().(MethodReadNode).getReceiver() }
|
||||
|
||||
/** Holds if this call has an ellipsis after its last argument. */
|
||||
predicate hasEllipsis() { expr.hasEllipsis() }
|
||||
@@ -702,7 +702,7 @@ class ElementReadNode extends ComponentReadNode {
|
||||
Node getIndex() { result = instructionNode(insn.getIndex()) }
|
||||
|
||||
/** Holds if this data-flow node reads element `index` of `base`. */
|
||||
predicate reads(Node base, Node index) { readsElement(base, index) }
|
||||
predicate reads(Node base, Node index) { this.readsElement(base, index) }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -734,14 +734,14 @@ class BinaryOperationNode extends Node {
|
||||
string op;
|
||||
|
||||
BinaryOperationNode() {
|
||||
exists(BinaryExpr bin | bin = asExpr() |
|
||||
exists(BinaryExpr bin | bin = this.asExpr() |
|
||||
left = exprNode(bin.getLeftOperand()) and
|
||||
right = exprNode(bin.getRightOperand()) and
|
||||
op = bin.getOperator()
|
||||
)
|
||||
or
|
||||
exists(IR::EvalCompoundAssignRhsInstruction rhs, CompoundAssignStmt assgn, string o |
|
||||
rhs = asInstruction() and assgn = rhs.getAssignment() and o = assgn.getOperator()
|
||||
rhs = this.asInstruction() and assgn = rhs.getAssignment() and o = assgn.getOperator()
|
||||
|
|
||||
left = exprNode(assgn.getLhs()) and
|
||||
right = exprNode(assgn.getRhs()) and
|
||||
@@ -749,7 +749,7 @@ class BinaryOperationNode extends Node {
|
||||
)
|
||||
or
|
||||
exists(IR::EvalIncDecRhsInstruction rhs, IncDecStmt ids |
|
||||
rhs = asInstruction() and ids = rhs.getStmt()
|
||||
rhs = this.asInstruction() and ids = rhs.getStmt()
|
||||
|
|
||||
left = exprNode(ids.getOperand()) and
|
||||
right = instructionNode(any(IR::EvalImplicitOneInstruction one | one.getStmt() = ids)) and
|
||||
@@ -758,7 +758,7 @@ class BinaryOperationNode extends Node {
|
||||
}
|
||||
|
||||
/** Holds if this operation may have observable side effects. */
|
||||
predicate mayHaveSideEffects() { asExpr().mayHaveOwnSideEffects() }
|
||||
predicate mayHaveSideEffects() { this.asExpr().mayHaveOwnSideEffects() }
|
||||
|
||||
/** Gets the left operand of this operation. */
|
||||
Node getLeftOperand() { result = left }
|
||||
@@ -774,8 +774,8 @@ class BinaryOperationNode extends Node {
|
||||
|
||||
/** Holds if `x` and `y` are the operands of this operation, in either order. */
|
||||
predicate hasOperands(Node x, Node y) {
|
||||
x = getAnOperand() and
|
||||
y = getAnOperand() and
|
||||
x = this.getAnOperand() and
|
||||
y = this.getAnOperand() and
|
||||
x != y
|
||||
}
|
||||
}
|
||||
@@ -785,34 +785,34 @@ class BinaryOperationNode extends Node {
|
||||
*/
|
||||
class UnaryOperationNode extends InstructionNode {
|
||||
UnaryOperationNode() {
|
||||
asExpr() instanceof UnaryExpr
|
||||
this.asExpr() instanceof UnaryExpr
|
||||
or
|
||||
asExpr() instanceof StarExpr
|
||||
this.asExpr() instanceof StarExpr
|
||||
or
|
||||
insn instanceof IR::EvalImplicitDerefInstruction
|
||||
}
|
||||
|
||||
/** Holds if this operation may have observable side effects. */
|
||||
predicate mayHaveSideEffects() {
|
||||
asExpr().mayHaveOwnSideEffects()
|
||||
this.asExpr().mayHaveOwnSideEffects()
|
||||
or
|
||||
insn instanceof IR::EvalImplicitDerefInstruction
|
||||
}
|
||||
|
||||
/** Gets the operand of this operation. */
|
||||
Node getOperand() {
|
||||
result = exprNode(asExpr().(UnaryExpr).getOperand())
|
||||
result = exprNode(this.asExpr().(UnaryExpr).getOperand())
|
||||
or
|
||||
result = exprNode(asExpr().(StarExpr).getBase())
|
||||
result = exprNode(this.asExpr().(StarExpr).getBase())
|
||||
or
|
||||
result = exprNode(insn.(IR::EvalImplicitDerefInstruction).getOperand())
|
||||
}
|
||||
|
||||
/** Gets the operator of this operation. */
|
||||
string getOperator() {
|
||||
result = asExpr().(UnaryExpr).getOperator()
|
||||
result = this.asExpr().(UnaryExpr).getOperator()
|
||||
or
|
||||
asExpr() instanceof StarExpr and
|
||||
this.asExpr() instanceof StarExpr and
|
||||
result = "*"
|
||||
or
|
||||
insn instanceof IR::EvalImplicitDerefInstruction and
|
||||
@@ -825,9 +825,9 @@ class UnaryOperationNode extends InstructionNode {
|
||||
*/
|
||||
class PointerDereferenceNode extends UnaryOperationNode {
|
||||
PointerDereferenceNode() {
|
||||
asExpr() instanceof StarExpr
|
||||
this.asExpr() instanceof StarExpr
|
||||
or
|
||||
asExpr() instanceof DerefExpr
|
||||
this.asExpr() instanceof DerefExpr
|
||||
or
|
||||
insn instanceof IR::EvalImplicitDerefInstruction
|
||||
}
|
||||
@@ -1173,7 +1173,7 @@ abstract class BarrierGuard extends Node {
|
||||
Function f, FunctionInput inp, FunctionOutput outp, DataFlow::Property p, CallNode c,
|
||||
Node resNode, Node check, boolean outcome
|
||||
|
|
||||
guardingFunction(f, inp, outp, p) and
|
||||
this.guardingFunction(f, inp, outp, p) and
|
||||
c = f.getACall() and
|
||||
nd = inp.getNode(c) and
|
||||
localFlow(pragma[only_bind_into](outp.getNode(c)), resNode) and
|
||||
@@ -23,6 +23,6 @@ private class JsonIteratorUnmarshalFunction extends TaintTracking::FunctionModel
|
||||
override string getFormat() { result = "JSON" }
|
||||
|
||||
override predicate hasTaintFlow(DataFlow::FunctionInput inp, DataFlow::FunctionOutput outp) {
|
||||
inp = getAnInput() and outp = getOutput()
|
||||
inp = this.getAnInput() and outp = this.getOutput()
|
||||
}
|
||||
}
|
||||
@@ -38,7 +38,7 @@ module K8sIoApiCoreV1 {
|
||||
override string getFormat() { result = "protobuf" }
|
||||
|
||||
override predicate hasTaintFlow(DataFlow::FunctionInput inp, DataFlow::FunctionOutput outp) {
|
||||
inp = getAnInput() and outp = getOutput()
|
||||
inp = this.getAnInput() and outp = this.getOutput()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,7 +55,7 @@ module K8sIoApiCoreV1 {
|
||||
override string getFormat() { result = "protobuf" }
|
||||
|
||||
override predicate hasTaintFlow(DataFlow::FunctionInput inp, DataFlow::FunctionOutput outp) {
|
||||
inp = getAnInput() and outp = getOutput()
|
||||
inp = this.getAnInput() and outp = this.getOutput()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -39,7 +39,7 @@ module K8sIoApimachineryPkgRuntime {
|
||||
}
|
||||
|
||||
override predicate hasTaintFlow(DataFlow::FunctionInput inp, DataFlow::FunctionOutput outp) {
|
||||
inp = getAnInput() and outp = getOutput()
|
||||
inp = this.getAnInput() and outp = this.getOutput()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,7 +64,7 @@ module K8sIoApimachineryPkgRuntime {
|
||||
}
|
||||
|
||||
override predicate hasTaintFlow(DataFlow::FunctionInput inp, DataFlow::FunctionOutput outp) {
|
||||
inp = getAnInput() and outp = getOutput()
|
||||
inp = this.getAnInput() and outp = this.getOutput()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -100,7 +100,7 @@ module K8sIoApimachineryPkgRuntime {
|
||||
}
|
||||
|
||||
override predicate hasTaintFlow(DataFlow::FunctionInput inp, DataFlow::FunctionOutput outp) {
|
||||
inp = getAnInput() and outp = getOutput()
|
||||
inp = this.getAnInput() and outp = this.getOutput()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -129,7 +129,7 @@ module K8sIoApimachineryPkgRuntime {
|
||||
}
|
||||
|
||||
override predicate hasTaintFlow(DataFlow::FunctionInput inp, DataFlow::FunctionOutput outp) {
|
||||
inp = getAnInput() and outp = getOutput()
|
||||
inp = this.getAnInput() and outp = this.getOutput()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -150,7 +150,7 @@ module K8sIoApimachineryPkgRuntime {
|
||||
}
|
||||
|
||||
override predicate hasTaintFlow(DataFlow::FunctionInput inp, DataFlow::FunctionOutput outp) {
|
||||
inp = getAnInput() and outp = getOutput()
|
||||
inp = this.getAnInput() and outp = this.getOutput()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -191,7 +191,7 @@ module K8sIoApimachineryPkgRuntime {
|
||||
}
|
||||
|
||||
override predicate hasTaintFlow(DataFlow::FunctionInput inp, DataFlow::FunctionOutput outp) {
|
||||
inp = getAnInput() and outp = getOutput()
|
||||
inp = this.getAnInput() and outp = this.getOutput()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -255,7 +255,7 @@ module K8sIoApimachineryPkgRuntime {
|
||||
}
|
||||
|
||||
override predicate hasTaintFlow(DataFlow::FunctionInput inp, DataFlow::FunctionOutput outp) {
|
||||
inp = getAnInput() and outp = getOutput()
|
||||
inp = this.getAnInput() and outp = this.getOutput()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -275,7 +275,7 @@ module K8sIoApimachineryPkgRuntime {
|
||||
}
|
||||
|
||||
override predicate hasTaintFlow(DataFlow::FunctionInput inp, DataFlow::FunctionOutput outp) {
|
||||
inp = getAnInput() and outp = getOutput()
|
||||
inp = this.getAnInput() and outp = this.getOutput()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -293,7 +293,7 @@ module K8sIoApimachineryPkgRuntime {
|
||||
override string getFormat() { result = "protobuf" }
|
||||
|
||||
override predicate hasTaintFlow(DataFlow::FunctionInput inp, DataFlow::FunctionOutput outp) {
|
||||
inp = getAnInput() and outp = getOutput()
|
||||
inp = this.getAnInput() and outp = this.getOutput()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -326,7 +326,7 @@ module K8sIoApimachineryPkgRuntime {
|
||||
override string getFormat() { result = "protobuf" }
|
||||
|
||||
override predicate hasTaintFlow(DataFlow::FunctionInput inp, DataFlow::FunctionOutput outp) {
|
||||
inp = getAnInput() and outp = getOutput()
|
||||
inp = this.getAnInput() and outp = this.getOutput()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -341,7 +341,7 @@ module K8sIoApimachineryPkgRuntime {
|
||||
override string getFormat() { result = "protobuf" }
|
||||
|
||||
override predicate hasTaintFlow(DataFlow::FunctionInput inp, DataFlow::FunctionOutput outp) {
|
||||
inp = getAnInput() and outp = getOutput()
|
||||
inp = this.getAnInput() and outp = this.getOutput()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -383,7 +383,7 @@ module K8sIoApimachineryPkgRuntime {
|
||||
override string getFormat() { result = "protobuf" }
|
||||
|
||||
override predicate hasTaintFlow(DataFlow::FunctionInput inp, DataFlow::FunctionOutput outp) {
|
||||
inp = getAnInput() and outp = getOutput()
|
||||
inp = this.getAnInput() and outp = this.getOutput()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -398,7 +398,7 @@ module K8sIoApimachineryPkgRuntime {
|
||||
override string getFormat() { result = "protobuf" }
|
||||
|
||||
override predicate hasTaintFlow(DataFlow::FunctionInput inp, DataFlow::FunctionOutput outp) {
|
||||
inp = getAnInput() and outp = getOutput()
|
||||
inp = this.getAnInput() and outp = this.getOutput()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ module Protobuf {
|
||||
}
|
||||
|
||||
override predicate hasTaintFlow(DataFlow::FunctionInput inp, DataFlow::FunctionOutput outp) {
|
||||
inp = getAnInput() and outp = getOutput()
|
||||
inp = this.getAnInput() and outp = this.getOutput()
|
||||
}
|
||||
|
||||
override DataFlow::FunctionInput getAnInput() {
|
||||
@@ -89,7 +89,7 @@ module Protobuf {
|
||||
}
|
||||
|
||||
override predicate hasTaintFlow(DataFlow::FunctionInput inp, DataFlow::FunctionOutput outp) {
|
||||
inp = getAnInput() and outp = getOutput()
|
||||
inp = this.getAnInput() and outp = this.getOutput()
|
||||
}
|
||||
|
||||
override DataFlow::FunctionInput getAnInput() { result.isParameter(0) }
|
||||
@@ -165,7 +165,7 @@ module Revel {
|
||||
any(Method m | m.hasQualifiedName(packagePath(), "Controller", "RenderFileName")).getACall()
|
||||
}
|
||||
|
||||
override DataFlow::Node getAPathArgument() { result = getArgument(0) }
|
||||
override DataFlow::Node getAPathArgument() { result = this.getArgument(0) }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -31,7 +31,7 @@ module Spew {
|
||||
|
||||
/** The `Sprint` function or one of its variants. */
|
||||
class Sprinter extends TaintTracking::FunctionModel {
|
||||
Sprinter() { hasQualifiedName(packagePath(), ["Sdump", "Sprint", "Sprintln", "Sprintf"]) }
|
||||
Sprinter() { this.hasQualifiedName(packagePath(), ["Sdump", "Sprint", "Sprintln", "Sprintf"]) }
|
||||
|
||||
override predicate hasTaintFlow(FunctionInput inp, FunctionOutput outp) {
|
||||
inp.isParameter(_) and outp.isResult()
|
||||
@@ -18,7 +18,7 @@ private class ShellOrSudoExecution extends SystemCommandExecution::Range, DataFl
|
||||
not hasSafeSubcommand(shellCommand.getStringValue(), this.getAnArgument().getStringValue())
|
||||
}
|
||||
|
||||
override DataFlow::Node getCommandName() { result = getAnArgument() }
|
||||
override DataFlow::Node getCommandName() { result = this.getAnArgument() }
|
||||
|
||||
override predicate doubleDashIsSanitizing() { shellCommand.getStringValue().matches("%git") }
|
||||
}
|
||||
@@ -70,7 +70,7 @@ private class GoShCommandExecution extends SystemCommandExecution::Range, DataFl
|
||||
)
|
||||
or
|
||||
// Catch calls to the `Command` function:
|
||||
getTarget().hasQualifiedName(packagePath, "Command")
|
||||
this.getTarget().hasQualifiedName(packagePath, "Command")
|
||||
)
|
||||
}
|
||||
|
||||
@@ -23,10 +23,10 @@ module XNetHtml {
|
||||
}
|
||||
|
||||
private class FunctionModels extends TaintTracking::FunctionModel {
|
||||
FunctionModels() { hasQualifiedName(packagePath(), _) }
|
||||
FunctionModels() { this.hasQualifiedName(packagePath(), _) }
|
||||
|
||||
override predicate hasTaintFlow(DataFlow::FunctionInput input, DataFlow::FunctionOutput output) {
|
||||
getName() =
|
||||
this.getName() =
|
||||
[
|
||||
"UnescapeString", "Parse", "ParseFragment", "ParseFragmentWithOptions",
|
||||
"ParseWithOptions", "NewTokenizer", "NewTokenizerFragment"
|
||||
@@ -34,11 +34,11 @@ module XNetHtml {
|
||||
input.isParameter(0) and
|
||||
output.isResult(0)
|
||||
or
|
||||
getName() = ["AppendChild", "InsertBefore"] and
|
||||
this.getName() = ["AppendChild", "InsertBefore"] and
|
||||
input.isParameter(0) and
|
||||
output.isReceiver()
|
||||
or
|
||||
getName() = "Render" and
|
||||
this.getName() = "Render" and
|
||||
input.isParameter(1) and
|
||||
output.isParameter(0)
|
||||
}
|
||||
@@ -50,9 +50,11 @@ module XNetHtml {
|
||||
// Note that `TagName` and the key part of `TagAttr` are not sources by default under the assumption
|
||||
// that their character-set restrictions usually rule them out as useful attack routes.
|
||||
override predicate hasTaintFlow(DataFlow::FunctionInput input, DataFlow::FunctionOutput output) {
|
||||
getName() = ["Buffered", "Raw", "Text", "Token"] and input.isReceiver() and output.isResult(0)
|
||||
this.getName() = ["Buffered", "Raw", "Text", "Token"] and
|
||||
input.isReceiver() and
|
||||
output.isResult(0)
|
||||
or
|
||||
getName() = "TagAttr" and input.isReceiver() and output.isResult(1)
|
||||
this.getName() = "TagAttr" and input.isReceiver() and output.isResult(1)
|
||||
}
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user