JS: Fix join orders and use SourceNode API in React model

This commit is contained in:
Asger Feldthaus
2020-05-08 10:13:48 +01:00
parent 255424cdc2
commit d823fd15af

View File

@@ -49,6 +49,12 @@ abstract class ReactComponent extends ASTNode {
*/
abstract DataFlow::SourceNode getAComponentCreatorReference();
/**
* Gets a reference to an instance of this component.
*/
pragma[noinline]
DataFlow::SourceNode getAnInstanceReference() { result = ref() }
/**
* Gets a reference to this component.
*/
@@ -70,20 +76,19 @@ abstract class ReactComponent extends ASTNode {
* Gets an access to the `state` object of this component.
*/
DataFlow::SourceNode getADirectStateAccess() {
result.(DataFlow::PropRef).accesses(ref(), "state")
result = getAnInstanceReference().getAPropertyReference("state")
}
/**
* Gets a data flow node that reads a prop of this component.
*/
DataFlow::PropRead getAPropRead() { getADirectPropsAccess().flowsTo(result.getBase()) }
DataFlow::PropRead getAPropRead() { result = getADirectPropsAccess().getAPropertyRead() }
/**
* Gets a data flow node that reads prop `name` of this component.
*/
DataFlow::PropRead getAPropRead(string name) {
result = getAPropRead() and
result.getPropertyName() = name
result = getADirectPropsAccess().getAPropertyRead(name)
}
/**
@@ -93,7 +98,7 @@ abstract class ReactComponent extends ASTNode {
DataFlow::SourceNode getAStateAccess() {
result = getADirectStateAccess()
or
exists(DataFlow::PropRef prn | result = prn | getAStateAccess().flowsTo(prn.getBase()))
result = getAStateAccess().getAPropertyReference()
}
/**
@@ -116,18 +121,17 @@ abstract class ReactComponent extends ASTNode {
/**
* Gets a call to method `name` on this component.
*/
DataFlow::MethodCallNode getAMethodCall(string name) { result.calls(ref(), name) }
DataFlow::MethodCallNode getAMethodCall(string name) {
result = getAnInstanceReference().getAMethodCall(name)
}
/**
* Gets a value that will become (part of) the state
* object of this component, for example an assignment to `this.state`.
*/
DataFlow::SourceNode getACandidateStateSource() {
exists(DataFlow::PropWrite pwn, DataFlow::Node rhs |
// a direct definition: `this.state = o`
result.flowsTo(rhs) and
pwn.writes(ref(), "state", rhs)
)
// a direct definition: `this.state = o`
result = getAnInstanceReference().getAPropertySource("state")
or
exists(DataFlow::MethodCallNode mce, DataFlow::SourceNode arg0 |
mce = getAMethodCall("setState") or
@@ -314,7 +318,8 @@ abstract private class SharedReactPreactClassComponent extends ReactComponent, C
}
override DataFlow::SourceNode getADirectPropsAccess() {
result.(DataFlow::PropRef).accesses(ref(), "props") or
result = getAnInstanceReference().getAPropertyRead("props")
or
result = DataFlow::parameterNode(getConstructor().getBody().getParameter(0))
}
@@ -437,7 +442,7 @@ class ES5Component extends ReactComponent, ObjectExpr {
override Function getStaticMethod(string name) { none() }
override DataFlow::SourceNode getADirectPropsAccess() {
result.(DataFlow::PropRef).accesses(ref(), "props")
result = getAnInstanceReference().getAPropertyRead("props")
}
override AbstractValue getAbstractComponent() { result = TAbstractObjectLiteral(this) }