mirror of
https://github.com/github/codeql.git
synced 2026-02-08 19:21:07 +01:00
QL: Merge pull request #125 from github/erik-krogh/fix-my-own-mistake
fixing the callgraph
This commit is contained in:
10
ql/consistency-queries/AstConsistency.ql
Normal file
10
ql/consistency-queries/AstConsistency.ql
Normal file
@@ -0,0 +1,10 @@
|
||||
import ql
|
||||
private import codeql_ql.ast.internal.AstNodes as AstNodes
|
||||
|
||||
query AstNode nonTotalGetParent() {
|
||||
exists(AstNodes::toQL(result).getParent()) and
|
||||
not exists(result.getParent()) and
|
||||
not result.getLocation().getStartColumn() = 1 and // startcolumn = 1 <=> top level in file <=> fine to have no parent
|
||||
not result instanceof YAML::YAMLNode and // parents for YAML doens't work
|
||||
not (result instanceof QLDoc and result.getLocation().getFile().getExtension() = "dbscheme") // qldoc in dbschemes are not hooked up
|
||||
}
|
||||
@@ -56,7 +56,11 @@ class AstNode extends TAstNode {
|
||||
* named `pred`.
|
||||
*/
|
||||
cached
|
||||
AstNode getAChild(string pred) { none() }
|
||||
AstNode getAChild(string pred) {
|
||||
pred = directMember("getAnAnnotation") and result = getAnAnnotation()
|
||||
or
|
||||
pred = directMember("getQLDoc") and result = getQLDoc()
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the primary QL class for the ast node.
|
||||
@@ -70,10 +74,7 @@ class AstNode extends TAstNode {
|
||||
predicate hasAnnotation(string name) { this.getAnAnnotation().getName() = name }
|
||||
|
||||
/** Gets an annotation of this AST node. */
|
||||
cached
|
||||
Annotation getAnAnnotation() {
|
||||
toQL(this).getParent() = pragma[only_bind_out](toQL(result)).getParent()
|
||||
}
|
||||
Annotation getAnAnnotation() { toQL(this).getParent() = toQL(result).getParent() }
|
||||
|
||||
/**
|
||||
* Gets the predicate that contains this AST node.
|
||||
@@ -119,8 +120,6 @@ class TopLevel extends TTopLevel, AstNode {
|
||||
NewType getANewType() { result = this.getAMember() }
|
||||
|
||||
override ModuleMember getAChild(string pred) {
|
||||
pred = directMember("getQLDoc") and result = this.getQLDoc()
|
||||
or
|
||||
pred = directMember("getAnImport") and result = this.getAnImport()
|
||||
or
|
||||
pred = directMember("getAClass") and result = this.getAClass()
|
||||
@@ -214,7 +213,7 @@ class BuiltinPredicate extends PredicateOrBuiltin, TBuiltin {
|
||||
override string getAPrimaryQlClass() { result = "BuiltinPredicate" }
|
||||
}
|
||||
|
||||
private class BuiltinClassless extends BuiltinPredicate, TBuiltinClassless {
|
||||
class BuiltinClassless extends BuiltinPredicate, TBuiltinClassless {
|
||||
string name;
|
||||
string ret;
|
||||
string args;
|
||||
@@ -228,7 +227,7 @@ private class BuiltinClassless extends BuiltinPredicate, TBuiltinClassless {
|
||||
override PrimitiveType getParameterType(int i) { result.getName() = getArgType(args, i) }
|
||||
}
|
||||
|
||||
private class BuiltinMember extends BuiltinPredicate, TBuiltinMember {
|
||||
class BuiltinMember extends BuiltinPredicate, TBuiltinMember {
|
||||
string name;
|
||||
string qual;
|
||||
string ret;
|
||||
@@ -626,7 +625,7 @@ class TypeExpr extends TType, AstNode {
|
||||
*/
|
||||
Type getResolvedType() { resolveTypeExpr(this, result) }
|
||||
|
||||
override ModuleExpr getAChild(string pred) {
|
||||
override AstNode getAChild(string pred) {
|
||||
result = super.getAChild(pred)
|
||||
or
|
||||
pred = directMember("getModule") and result = this.getModule()
|
||||
@@ -691,11 +690,7 @@ class Declaration extends TDeclaration, AstNode {
|
||||
result = any(Class c).getQLDocFor(this)
|
||||
}
|
||||
|
||||
override AstNode getAChild(string pred) {
|
||||
result = super.getAChild(pred)
|
||||
or
|
||||
pred = directMember("getQLDoc") and result = this.getQLDoc()
|
||||
}
|
||||
override AstNode getAChild(string pred) { result = super.getAChild(pred) }
|
||||
}
|
||||
|
||||
/** An entity that can be declared in a module. */
|
||||
@@ -784,6 +779,8 @@ class Class extends TClass, TypeDeclaration, ModuleDeclaration {
|
||||
or
|
||||
pred = directMember("getASuperType") and result = this.getASuperType()
|
||||
or
|
||||
pred = directMember("getAnInstanceofType") and result = this.getAnInstanceofType()
|
||||
or
|
||||
exists(string name |
|
||||
pred = stringIndexedMember("getClassPredicate", name) and
|
||||
result = this.getClassPredicate(name)
|
||||
@@ -860,8 +857,6 @@ class NewTypeBranch extends TNewTypeBranch, PredicateOrBuiltin, TypeDeclaration
|
||||
pred = directMember("getBody") and result = this.getBody()
|
||||
or
|
||||
exists(int i | pred = indexedMember("getField", i) and result = this.getField(i))
|
||||
or
|
||||
pred = directMember("getQLDoc") and result = this.getQLDoc()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2196,6 +2191,12 @@ class Annotation extends TAnnotation, AstNode {
|
||||
|
||||
/** Gets the node corresponding to the field `name`. */
|
||||
string getName() { result = annot.getName().getValue() }
|
||||
|
||||
override AstNode getAChild(string pred) {
|
||||
result = super.getAChild(pred)
|
||||
or
|
||||
exists(int i | pred = indexedMember("getArgs", i) and result = this.getArgs(i))
|
||||
}
|
||||
}
|
||||
|
||||
/** A `pragma[noinline]` annotation. */
|
||||
@@ -2414,8 +2415,8 @@ module YAML {
|
||||
|
||||
/** Gets the database scheme of this qlpack */
|
||||
File getDBScheme() {
|
||||
result.getBaseName() = this.getProperty("dbscheme") and
|
||||
result = file.getParentContainer().getFile(any(string s | s.matches("%.dbscheme")))
|
||||
result.getAbsolutePath() =
|
||||
file.getParentContainer().getAbsolutePath() + "/" + this.getProperty("dbscheme")
|
||||
}
|
||||
|
||||
pragma[noinline]
|
||||
|
||||
@@ -44,7 +44,9 @@ predicate isBuiltinMember(string sig) {
|
||||
"string string.toLowerCase()", "string string.toUpperCase()", "string string.trim()",
|
||||
"int date.daysTo(date)", "int date.getDay()", "int date.getHours()", "int date.getMinutes()",
|
||||
"int date.getMonth()", "int date.getSeconds()", "int date.getYear()",
|
||||
"string date.toString()", "string date.toISO()", "string int.toUnicode()"
|
||||
"string date.toString()", "string date.toISO()", "string int.toUnicode()",
|
||||
"string any.getAQlClass()"
|
||||
/* getAQlClass is special , see Predicate.qll*/
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
@@ -154,18 +154,13 @@ private predicate resolveSelectionName(Import imp, ContainerOrModule m, int i) {
|
||||
|
||||
cached
|
||||
private module Cached {
|
||||
private Module getEnclosingModule0(AstNode n) {
|
||||
not n instanceof Module and
|
||||
(
|
||||
n = result.getAChild(_)
|
||||
or
|
||||
exists(AstNode prev |
|
||||
result = getEnclosingModule0(prev) and
|
||||
n = prev.getAChild(_)
|
||||
)
|
||||
)
|
||||
private AstNode parent(AstNode n) {
|
||||
result = n.getParent() and
|
||||
not n instanceof Module
|
||||
}
|
||||
|
||||
private Module getEnclosingModule0(AstNode n) { result = parent*(n.getParent()) }
|
||||
|
||||
cached
|
||||
ContainerOrModule getEnclosingModule(AstNode n) {
|
||||
result = TModule(getEnclosingModule0(n))
|
||||
|
||||
@@ -81,7 +81,7 @@ private module Cached {
|
||||
// super calls
|
||||
exists(Super sup, ClassType type, Type supertype |
|
||||
mc.getBase() = sup and
|
||||
sup.getEnclosingPredicate().(ClassPredicate).getParent().getType() = type and
|
||||
sup.getEnclosingPredicate().getParent().(Class).getType() = type and
|
||||
supertype in [type.getASuperType(), type.getAnInstanceofType()] and
|
||||
p = supertype.getClassPredicate(mc.getMemberName(), mc.getNumberOfArguments())
|
||||
)
|
||||
@@ -110,14 +110,26 @@ private module Cached {
|
||||
)
|
||||
}
|
||||
|
||||
private predicate resolveBuildinPredicateCall(PredicateCall call, BuiltinClassless pred) {
|
||||
call.getNumberOfArguments() = pred.getArity() and
|
||||
call.getPredicateName() = pred.getName()
|
||||
}
|
||||
|
||||
cached
|
||||
predicate resolveCall(Call c, PredicateOrBuiltin p) {
|
||||
resolvePredicateCall(c, p)
|
||||
or
|
||||
not resolvePredicateCall(c, _) and
|
||||
resolveBuildinPredicateCall(c, p)
|
||||
or
|
||||
resolveMemberCall(c, p)
|
||||
or
|
||||
not resolvePredicateCall(c, _) and
|
||||
resolveDBRelation(c, p)
|
||||
or
|
||||
// getAQlClass() is special
|
||||
c.(MemberCall).getMemberName() = "getAQlClass" and
|
||||
p.(BuiltinMember).getName() = "getAQlClass"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
9
ql/test/callgraph/Bar.qll
Normal file
9
ql/test/callgraph/Bar.qll
Normal file
@@ -0,0 +1,9 @@
|
||||
import ql
|
||||
|
||||
module Firebase {
|
||||
module Database {
|
||||
query predicate ref(int i) { i = snapshot() }
|
||||
}
|
||||
|
||||
int snapshot() { result = 2 }
|
||||
}
|
||||
11
ql/test/callgraph/Baz.qll
Normal file
11
ql/test/callgraph/Baz.qll
Normal file
@@ -0,0 +1,11 @@
|
||||
class Foo extends string {
|
||||
Foo() { this = "Foo" }
|
||||
|
||||
string getImportedPath() { none() }
|
||||
}
|
||||
|
||||
class Bar extends string, Foo {
|
||||
Bar() { exists(Foo.super.getImportedPath()) }
|
||||
|
||||
override string getImportedPath() { none() }
|
||||
}
|
||||
@@ -1,4 +1,6 @@
|
||||
getTarget
|
||||
| Bar.qll:5:38:5:47 | PredicateCall | Bar.qll:8:3:8:31 | ClasslessPredicate snapshot |
|
||||
| Baz.qll:8:18:8:44 | MemberCall | Baz.qll:4:3:4:37 | ClassPredicate getImportedPath |
|
||||
| Foo.qll:5:26:5:30 | PredicateCall | Foo.qll:3:1:3:26 | ClasslessPredicate foo |
|
||||
| Foo.qll:10:21:10:25 | PredicateCall | Foo.qll:8:3:8:28 | ClassPredicate bar |
|
||||
| Foo.qll:14:30:14:40 | MemberCall | Foo.qll:10:3:10:27 | ClassPredicate baz |
|
||||
|
||||
@@ -196,6 +196,7 @@ nodes
|
||||
| file://:0:0:0:0 | exp | semmle.label | [BuiltinPredicate] exp |
|
||||
| file://:0:0:0:0 | floor | semmle.label | [BuiltinPredicate] floor |
|
||||
| file://:0:0:0:0 | gcd | semmle.label | [BuiltinPredicate] gcd |
|
||||
| file://:0:0:0:0 | getAQlClass | semmle.label | [BuiltinPredicate] getAQlClass |
|
||||
| file://:0:0:0:0 | getDay | semmle.label | [BuiltinPredicate] getDay |
|
||||
| file://:0:0:0:0 | getHours | semmle.label | [BuiltinPredicate] getHours |
|
||||
| file://:0:0:0:0 | getMinutes | semmle.label | [BuiltinPredicate] getMinutes |
|
||||
@@ -288,6 +289,10 @@ edges
|
||||
| Foo.qll:6:23:6:36 | ComparisonFormula | Foo.qll:6:30:6:30 | ComparisonOp | semmle.order | 14 |
|
||||
| Foo.qll:6:23:6:36 | ComparisonFormula | Foo.qll:6:32:6:36 | String | semmle.label | getRightOperand() |
|
||||
| Foo.qll:6:23:6:36 | ComparisonFormula | Foo.qll:6:32:6:36 | String | semmle.order | 15 |
|
||||
| Foo.qll:9:1:9:5 | annotation | Foo.qll:9:1:9:5 | annotation | semmle.label | getAnAnnotation() |
|
||||
| Foo.qll:9:1:9:5 | annotation | Foo.qll:9:1:9:5 | annotation | semmle.order | 16 |
|
||||
| Foo.qll:9:7:11:1 | ClasslessPredicate foo | Foo.qll:9:1:9:5 | annotation | semmle.label | getAnAnnotation() |
|
||||
| Foo.qll:9:7:11:1 | ClasslessPredicate foo | Foo.qll:9:1:9:5 | annotation | semmle.order | 16 |
|
||||
| Foo.qll:9:7:11:1 | ClasslessPredicate foo | Foo.qll:9:21:9:25 | f | semmle.label | getParameter(_) |
|
||||
| Foo.qll:9:7:11:1 | ClasslessPredicate foo | Foo.qll:9:21:9:25 | f | semmle.order | 18 |
|
||||
| Foo.qll:9:7:11:1 | ClasslessPredicate foo | Foo.qll:10:3:10:85 | ComparisonFormula | semmle.label | getBody() |
|
||||
|
||||
Reference in New Issue
Block a user