Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions javascript/ql/src/semmle/javascript/AMD.qll
Original file line number Diff line number Diff line change
Expand Up @@ -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. */
Expand Down
33 changes: 16 additions & 17 deletions javascript/ql/src/semmle/javascript/dataflow/DataFlow.qll
Original file line number Diff line number Diff line change
Expand Up @@ -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() }
Expand Down Expand Up @@ -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(
Expand Down Expand Up @@ -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();

/**
Expand Down Expand Up @@ -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 }
ObjectDefinePropertyAsPropWrite() {
astNode.getReceiver().(GlobalVarAccess).getName() = "Object" and
astNode.getMethodName() = "defineProperty"
}

override Node getBase() { result = odp.getBaseObject() }
override Node getBase() { result = astNode.getArgument(0).flow() }

override Expr getPropertyNameExpr() { result = odp.getArgument(1).asExpr() }
override Expr getPropertyNameExpr() { result = astNode.getArgument(1) }

override string getPropertyName() { result = odp.getPropertyName() }
override string getPropertyName() { result = astNode.getArgument(1).getStringValue() }

override Node getRhs() {
// not using `CallToObjectDefineProperty::getAPropertyAttribute` for performance reasons
exists(ObjectLiteralNode propdesc |
propdesc.flowsTo(odp.getPropertyDescriptor()) and
propdesc.hasPropertyWrite("value", result)
)
result = astNode.getArgument(2).(ObjectExpr).getPropertyByName("value").getInit().flow()
}

override ControlFlowNode getWriteNode() { result = odp.getAstNode() }
override ControlFlowNode getWriteNode() { result = astNode }
}

/**
Expand Down
1 change: 1 addition & 0 deletions javascript/ql/src/semmle/javascript/dataflow/Nodes.qll
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
Expand Down
1 change: 1 addition & 0 deletions javascript/ql/src/semmle/javascript/dataflow/Sources.qll
Original file line number Diff line number Diff line change
Expand Up @@ -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()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
Expand Down