Merge pull request #3380 from asger-semmle/js/cache-amd

Approved by erik-krogh
This commit is contained in:
semmle-qlci
2020-05-02 20:18:22 +01:00
committed by GitHub
5 changed files with 25 additions and 22 deletions

View File

@@ -290,6 +290,7 @@ private class AmdDependencyImport extends Import {
* ```
*/
class AmdModule extends Module {
cached
AmdModule() { strictcount(AmdModuleDefinition def | amdModuleTopLevel(def, this)) = 1 }
/** Gets the definition of this module. */

View File

@@ -118,7 +118,11 @@ module DataFlow {
predicate accessesGlobal(string g) { globalVarRef(g).flowsTo(this) }
/** Holds if this node may evaluate to the string `s`, possibly through local data flow. */
predicate mayHaveStringValue(string s) { getAPredecessor().mayHaveStringValue(s) }
predicate mayHaveStringValue(string s) {
getAPredecessor().mayHaveStringValue(s)
or
s = getStringValue()
}
/** Gets the string value of this node, if it is a string literal or constant string concatenation. */
string getStringValue() { result = asExpr().getStringValue() }
@@ -297,11 +301,6 @@ module DataFlow {
/** Gets the expression or declaration this node corresponds to. */
override AST::ValueNode getAstNode() { result = astNode }
override predicate mayHaveStringValue(string s) {
Node.super.mayHaveStringValue(s) or
astNode.(ConstantString).getStringValue() = s
}
override BasicBlock getBasicBlock() { astNode = result.getANode() }
override predicate hasLocationInfo(
@@ -587,6 +586,7 @@ module DataFlow {
* This predicate is undefined for spread properties, accessor
* properties, and most uses of `Object.defineProperty`.
*/
pragma[nomagic]
abstract Node getRhs();
/**
@@ -648,25 +648,24 @@ module DataFlow {
* writes to the corresponding property.
*/
private class ObjectDefinePropertyAsPropWrite extends PropWrite, ValueNode {
CallToObjectDefineProperty odp;
override MethodCallExpr astNode;
ObjectDefinePropertyAsPropWrite() { odp = this }
override Node getBase() { result = odp.getBaseObject() }
override Expr getPropertyNameExpr() { result = odp.getArgument(1).asExpr() }
override string getPropertyName() { result = odp.getPropertyName() }
override Node getRhs() {
// not using `CallToObjectDefineProperty::getAPropertyAttribute` for performance reasons
exists(ObjectLiteralNode propdesc |
propdesc.flowsTo(odp.getPropertyDescriptor()) and
propdesc.hasPropertyWrite("value", result)
)
ObjectDefinePropertyAsPropWrite() {
astNode.getReceiver().(GlobalVarAccess).getName() = "Object" and
astNode.getMethodName() = "defineProperty"
}
override ControlFlowNode getWriteNode() { result = odp.getAstNode() }
override Node getBase() { result = astNode.getArgument(0).flow() }
override Expr getPropertyNameExpr() { result = astNode.getArgument(1) }
override string getPropertyName() { result = astNode.getArgument(1).getStringValue() }
override Node getRhs() {
result = astNode.getArgument(2).(ObjectExpr).getPropertyByName("value").getInit().flow()
}
override ControlFlowNode getWriteNode() { result = astNode }
}
/**

View File

@@ -156,6 +156,7 @@ class InvokeNode extends DataFlow::SourceNode {
* Holds if the `i`th argument of this invocation is an object literal whose property
* `name` is set to `result`.
*/
pragma[nomagic]
DataFlow::ValueNode getOptionArgument(int i, string name) {
getOptionsArgument(i).hasPropertyWrite(name, result)
}

View File

@@ -70,6 +70,7 @@ class SourceNode extends DataFlow::Node {
* Holds if there is an assignment to property `propName` on this node,
* and the right hand side of the assignment is `rhs`.
*/
pragma[nomagic]
predicate hasPropertyWrite(string propName, DataFlow::Node rhs) {
rhs = getAPropertyWrite(propName).getRhs()
}

View File

@@ -461,6 +461,7 @@ class ComponentDirective extends CustomDirective, MkCustomComponent {
override DataFlow::Node getDefinition() { result = comp }
pragma[nomagic]
override DataFlow::ValueNode getMemberInit(string name) {
comp.getConfig().hasPropertyWrite(name, result)
}