mirror of
https://github.com/github/codeql.git
synced 2026-04-30 03:05:15 +02:00
Merge pull request #4401 from asgerf/js/angular-prerequisites
Approved by erik-krogh
This commit is contained in:
@@ -347,7 +347,11 @@ module DOM {
|
||||
}
|
||||
|
||||
/** Gets a data flow node that may refer to a value from the DOM. */
|
||||
DataFlow::SourceNode domValueRef() { result = domValueRef(DataFlow::TypeTracker::end()) }
|
||||
DataFlow::SourceNode domValueRef() {
|
||||
result = domValueRef(DataFlow::TypeTracker::end())
|
||||
or
|
||||
result.hasUnderlyingType("Element")
|
||||
}
|
||||
|
||||
module LocationSource {
|
||||
/**
|
||||
@@ -419,5 +423,9 @@ module DOM {
|
||||
/**
|
||||
* Gets a reference to the 'document' object.
|
||||
*/
|
||||
DataFlow::SourceNode documentRef() { result = documentRef(DataFlow::TypeTracker::end()) }
|
||||
DataFlow::SourceNode documentRef() {
|
||||
result = documentRef(DataFlow::TypeTracker::end())
|
||||
or
|
||||
result.hasUnderlyingType("Document")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,6 +34,13 @@ abstract class ExtendCall extends DataFlow::CallNode {
|
||||
}
|
||||
}
|
||||
|
||||
/** A version of `JQuery::dollarSource()` with fewer dependencies. */
|
||||
private DataFlow::SourceNode localDollar() {
|
||||
result.accessesGlobal(["$", "jQuery"])
|
||||
or
|
||||
result = DataFlow::moduleImport("jquery")
|
||||
}
|
||||
|
||||
/**
|
||||
* An extend call of form `extend(true/false, dst, src1, src2, ...)`, where the true/false
|
||||
* argument is possibly omitted.
|
||||
@@ -47,9 +54,7 @@ private class ExtendCallWithFlag extends ExtendCall {
|
||||
name = "node.extend"
|
||||
)
|
||||
or
|
||||
// Match $.extend using the source of `$` only, as ExtendCall should not
|
||||
// depend on type tracking.
|
||||
this = JQuery::dollarSource().getAMemberCall("extend")
|
||||
this = localDollar().getAMemberCall("extend")
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -420,6 +420,24 @@ private predicate barrierGuardBlocksSsaRefinement(
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if the result of `guard` is used in the branching condition `cond`.
|
||||
*
|
||||
* `outcome` is bound to the outcome of `cond` for join-ordering purposes.
|
||||
*/
|
||||
pragma[noinline]
|
||||
private predicate barrierGuardUsedInCondition(
|
||||
BarrierGuardNode guard, ConditionGuardNode cond, boolean outcome
|
||||
) {
|
||||
barrierGuardIsRelevant(guard) and
|
||||
outcome = cond.getOutcome() and
|
||||
(
|
||||
cond.getTest() = guard.getEnclosingExpr()
|
||||
or
|
||||
cond.getTest().flow().getImmediatePredecessor+() = guard
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if data flow node `nd` acts as a barrier for data flow, possibly due to aliasing
|
||||
* through an access path.
|
||||
@@ -435,14 +453,9 @@ private predicate barrierGuardBlocksNode(BarrierGuardNode guard, DataFlow::Node
|
||||
)
|
||||
or
|
||||
// 2) `nd` is an instance of an access path `p`, and dominated by a barrier for `p`
|
||||
barrierGuardIsRelevant(guard) and
|
||||
exists(AccessPath p, BasicBlock bb, ConditionGuardNode cond, boolean outcome |
|
||||
nd = DataFlow::valueNode(p.getAnInstanceIn(bb)) and
|
||||
(
|
||||
guard.getEnclosingExpr() = cond.getTest() or
|
||||
guard = cond.getTest().flow().getImmediatePredecessor+()
|
||||
) and
|
||||
outcome = cond.getOutcome() and
|
||||
barrierGuardUsedInCondition(guard, cond, outcome) and
|
||||
barrierGuardBlocksAccessPath(guard, outcome, p, label) and
|
||||
cond.dominates(bb)
|
||||
)
|
||||
|
||||
@@ -228,7 +228,7 @@ module DataFlow {
|
||||
*
|
||||
* Doesn't take field types and function return types into account.
|
||||
*/
|
||||
private JSDocTypeExpr getFallbackTypeAnnotation() {
|
||||
private TypeAnnotation getFallbackTypeAnnotation() {
|
||||
exists(BindingPattern pattern |
|
||||
this = valueNode(pattern) and
|
||||
not ast_node_type(pattern, _) and
|
||||
@@ -236,6 +236,11 @@ module DataFlow {
|
||||
)
|
||||
or
|
||||
result = getAPredecessor().getFallbackTypeAnnotation()
|
||||
or
|
||||
exists(DataFlow::ClassNode cls, string fieldName |
|
||||
this = cls.getAReceiverNode().getAPropertyRead(fieldName) and
|
||||
result = cls.getFieldTypeAnnotation(fieldName)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -704,7 +709,9 @@ module DataFlow {
|
||||
result = thisNode(prop.getDeclaringClass().getConstructor().getBody())
|
||||
}
|
||||
|
||||
override Expr getPropertyNameExpr() { result = prop.getNameExpr() }
|
||||
override Expr getPropertyNameExpr() {
|
||||
none() // The parameter value is not the name of the field
|
||||
}
|
||||
|
||||
override string getPropertyName() { result = prop.getName() }
|
||||
|
||||
|
||||
@@ -995,6 +995,13 @@ class ClassNode extends DataFlow::SourceNode {
|
||||
predicate hasQualifiedName(string name) {
|
||||
getAClassReference().flowsTo(AccessPath::getAnAssignmentTo(name))
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the type annotation for the field `fieldName`, if any.
|
||||
*/
|
||||
TypeAnnotation getFieldTypeAnnotation(string fieldName) {
|
||||
result = impl.getFieldTypeAnnotation(fieldName)
|
||||
}
|
||||
}
|
||||
|
||||
module ClassNode {
|
||||
@@ -1047,6 +1054,11 @@ module ClassNode {
|
||||
* of this node.
|
||||
*/
|
||||
abstract DataFlow::Node getASuperClassNode();
|
||||
|
||||
/**
|
||||
* Gets the type annotation for the field `fieldName`, if any.
|
||||
*/
|
||||
TypeAnnotation getFieldTypeAnnotation(string fieldName) { none() }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1106,6 +1118,14 @@ module ClassNode {
|
||||
}
|
||||
|
||||
override DataFlow::Node getASuperClassNode() { result = astNode.getSuperClass().flow() }
|
||||
|
||||
override TypeAnnotation getFieldTypeAnnotation(string fieldName) {
|
||||
exists(FieldDeclaration field |
|
||||
field.getDeclaringClass() = astNode and
|
||||
fieldName = field.getName() and
|
||||
result = field.getTypeAnnotation()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private DataFlow::PropRef getAPrototypeReferenceInFile(string name, File f) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
| fields.ts:2:16:2:32 | (x: string) => {} | Foo.m | method |
|
||||
| fields.ts:12:16:12:32 | (x: string) => {} | Foo.m | method |
|
||||
| namespace.js:5:32:5:44 | function() {} | Baz.method | method |
|
||||
| tst2.js:6:9:9:3 | () {\\n ... .x;\\n } | C.method | method |
|
||||
| tst2.js:11:13:13:3 | () {\\n ... .x;\\n } | C.getter | getter |
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
| fields.ts:2:16:2:32 | (x: string) => {} | Foo.m |
|
||||
| fields.ts:12:16:12:32 | (x: string) => {} | Foo.m |
|
||||
| namespace.js:5:32:5:44 | function() {} | Baz.method |
|
||||
| tst2.js:6:9:9:3 | () {\\n ... .x;\\n } | C.method |
|
||||
| tst2.js:18:14:18:22 | (x) => {} | D.f |
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
| fields.ts:5:1:13:1 | class F ... > {};\\n} | Foo | fields.ts:1:1:3:1 | class B ... mber;\\n} | Base |
|
||||
| tst.js:13:1:13:21 | class A ... ds A {} | A2 | tst.js:3:1:10:1 | class A ... () {}\\n} | A |
|
||||
| tst.js:15:1:15:15 | function B() {} | B | tst.js:3:1:10:1 | class A ... () {}\\n} | A |
|
||||
| tst.js:19:1:19:15 | function C() {} | C | tst.js:15:1:15:15 | function B() {} | B |
|
||||
|
||||
@@ -1,3 +1,13 @@
|
||||
class Foo {
|
||||
class Base {
|
||||
baseField: number;
|
||||
}
|
||||
|
||||
class Foo extends Base {
|
||||
constructor(public x: number, private y: string) {
|
||||
super();
|
||||
}
|
||||
|
||||
z: string[];
|
||||
|
||||
public m = (x: string) => {};
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
| fields.ts:1:1:3:1 | class F ... > {};\\n} | fields.ts:1:11:1:10 | this |
|
||||
| fields.ts:1:1:3:1 | class B ... mber;\\n} | fields.ts:1:12:1:11 | this |
|
||||
| fields.ts:5:1:13:1 | class F ... > {};\\n} | fields.ts:6:5:6:4 | this |
|
||||
| namespace.js:3:15:3:31 | function Baz() {} | namespace.js:3:15:3:14 | this |
|
||||
| namespace.js:3:15:3:31 | function Baz() {} | namespace.js:5:32:5:31 | this |
|
||||
| tst2.js:1:1:14:1 | class C ... ;\\n }\\n} | tst2.js:2:14:2:13 | this |
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
| fields.ts:1:1:3:1 | class B ... mber;\\n} | baseField | fields.ts:2:16:2:21 | number |
|
||||
| fields.ts:5:1:13:1 | class F ... > {};\\n} | x | fields.ts:6:27:6:32 | number |
|
||||
| fields.ts:5:1:13:1 | class F ... > {};\\n} | y | fields.ts:6:46:6:51 | string |
|
||||
| fields.ts:5:1:13:1 | class F ... > {};\\n} | z | fields.ts:10:8:10:15 | string[] |
|
||||
@@ -0,0 +1,4 @@
|
||||
import javascript
|
||||
|
||||
from DataFlow::ClassNode cls, string name
|
||||
select cls, name, cls.getFieldTypeAnnotation(name)
|
||||
Reference in New Issue
Block a user