Skip to content

Commit c66ec3c

Browse files
authored
Merge pull request github#3380 from asger-semmle/js/cache-amd
Approved by erik-krogh
2 parents 4ce896b + 9b014c3 commit c66ec3c

File tree

5 files changed

+20
-17
lines changed

5 files changed

+20
-17
lines changed

javascript/ql/src/semmle/javascript/AMD.qll

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,7 @@ private class AmdDependencyImport extends Import {
290290
* ```
291291
*/
292292
class AmdModule extends Module {
293+
cached
293294
AmdModule() { strictcount(AmdModuleDefinition def | amdModuleTopLevel(def, this)) = 1 }
294295

295296
/** Gets the definition of this module. */

javascript/ql/src/semmle/javascript/dataflow/DataFlow.qll

Lines changed: 16 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,11 @@ module DataFlow {
118118
predicate accessesGlobal(string g) { globalVarRef(g).flowsTo(this) }
119119

120120
/** Holds if this node may evaluate to the string `s`, possibly through local data flow. */
121-
predicate mayHaveStringValue(string s) { getAPredecessor().mayHaveStringValue(s) }
121+
predicate mayHaveStringValue(string s) {
122+
getAPredecessor().mayHaveStringValue(s)
123+
or
124+
s = getStringValue()
125+
}
122126

123127
/** Gets the string value of this node, if it is a string literal or constant string concatenation. */
124128
string getStringValue() { result = asExpr().getStringValue() }
@@ -297,11 +301,6 @@ module DataFlow {
297301
/** Gets the expression or declaration this node corresponds to. */
298302
override AST::ValueNode getAstNode() { result = astNode }
299303

300-
override predicate mayHaveStringValue(string s) {
301-
Node.super.mayHaveStringValue(s) or
302-
astNode.(ConstantString).getStringValue() = s
303-
}
304-
305304
override BasicBlock getBasicBlock() { astNode = result.getANode() }
306305

307306
override predicate hasLocationInfo(
@@ -587,6 +586,7 @@ module DataFlow {
587586
* This predicate is undefined for spread properties, accessor
588587
* properties, and most uses of `Object.defineProperty`.
589588
*/
589+
pragma[nomagic]
590590
abstract Node getRhs();
591591

592592
/**
@@ -648,25 +648,24 @@ module DataFlow {
648648
* writes to the corresponding property.
649649
*/
650650
private class ObjectDefinePropertyAsPropWrite extends PropWrite, ValueNode {
651-
CallToObjectDefineProperty odp;
651+
override MethodCallExpr astNode;
652652

653-
ObjectDefinePropertyAsPropWrite() { odp = this }
653+
ObjectDefinePropertyAsPropWrite() {
654+
astNode.getReceiver().(GlobalVarAccess).getName() = "Object" and
655+
astNode.getMethodName() = "defineProperty"
656+
}
654657

655-
override Node getBase() { result = odp.getBaseObject() }
658+
override Node getBase() { result = astNode.getArgument(0).flow() }
656659

657-
override Expr getPropertyNameExpr() { result = odp.getArgument(1).asExpr() }
660+
override Expr getPropertyNameExpr() { result = astNode.getArgument(1) }
658661

659-
override string getPropertyName() { result = odp.getPropertyName() }
662+
override string getPropertyName() { result = astNode.getArgument(1).getStringValue() }
660663

661664
override Node getRhs() {
662-
// not using `CallToObjectDefineProperty::getAPropertyAttribute` for performance reasons
663-
exists(ObjectLiteralNode propdesc |
664-
propdesc.flowsTo(odp.getPropertyDescriptor()) and
665-
propdesc.hasPropertyWrite("value", result)
666-
)
665+
result = astNode.getArgument(2).(ObjectExpr).getPropertyByName("value").getInit().flow()
667666
}
668667

669-
override ControlFlowNode getWriteNode() { result = odp.getAstNode() }
668+
override ControlFlowNode getWriteNode() { result = astNode }
670669
}
671670

672671
/**

javascript/ql/src/semmle/javascript/dataflow/Nodes.qll

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,7 @@ class InvokeNode extends DataFlow::SourceNode {
156156
* Holds if the `i`th argument of this invocation is an object literal whose property
157157
* `name` is set to `result`.
158158
*/
159+
pragma[nomagic]
159160
DataFlow::ValueNode getOptionArgument(int i, string name) {
160161
getOptionsArgument(i).hasPropertyWrite(name, result)
161162
}

javascript/ql/src/semmle/javascript/dataflow/Sources.qll

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ class SourceNode extends DataFlow::Node {
7070
* Holds if there is an assignment to property `propName` on this node,
7171
* and the right hand side of the assignment is `rhs`.
7272
*/
73+
pragma[nomagic]
7374
predicate hasPropertyWrite(string propName, DataFlow::Node rhs) {
7475
rhs = getAPropertyWrite(propName).getRhs()
7576
}

javascript/ql/src/semmle/javascript/frameworks/AngularJS/AngularJSCore.qll

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -461,6 +461,7 @@ class ComponentDirective extends CustomDirective, MkCustomComponent {
461461

462462
override DataFlow::Node getDefinition() { result = comp }
463463

464+
pragma[nomagic]
464465
override DataFlow::ValueNode getMemberInit(string name) {
465466
comp.getConfig().hasPropertyWrite(name, result)
466467
}

0 commit comments

Comments
 (0)