JS: whitelist decorator-bound methods in js/unbound-event-handler-receiver

This commit is contained in:
Esben Sparre Andreasen
2018-09-11 21:51:51 +02:00
parent 1220b50737
commit eb10f603ab
3 changed files with 25 additions and 4 deletions

View File

@@ -10,7 +10,7 @@
import javascript
/**
* Holds if the receiver of `method` is bound in a method of its class.
* Holds if the receiver of `method` is bound.
*/
private predicate isBoundInMethod(MethodDeclaration method) {
exists (DataFlow::ThisNode thiz, MethodDeclaration bindingMethod, string name |
@@ -38,6 +38,15 @@ private predicate isBoundInMethod(MethodDeclaration method) {
)
)
)
or
exists (Expr decoration, string name |
decoration = method.getADecorator().getExpression() and
name.regexpMatch("(?i).*(bind|bound).*") |
// @autobind
decoration.(Identifier).getName() = name or
// @action.bound
decoration.(PropAccess).getPropertyName() = name
)
}
/**

View File

@@ -1,3 +1,3 @@
| tst.js:8:18:8:40 | onClick ... bound1} | The receiver of this event handler call is unbound, `$@` will be `undefined` in the call to $@ | tst.js:35:9:35:12 | this | this | tst.js:34:5:36:5 | unbound ... ;\\n } | unbound1 |
| tst.js:9:18:9:40 | onClick ... bound2} | The receiver of this event handler call is unbound, `$@` will be `undefined` in the call to $@ | tst.js:39:15:39:18 | this | this | tst.js:38:5:40:5 | unbound ... ;\\n } | unbound2 |
| tst.js:10:18:10:35 | onClick={unbound3} | The receiver of this event handler call is unbound, `$@` will be `undefined` in the call to $@ | tst.js:43:15:43:18 | this | this | tst.js:42:5:44:5 | unbound ... ;\\n } | unbound3 |
| tst.js:8:18:8:40 | onClick ... bound1} | The receiver of this event handler call is unbound, `$@` will be `undefined` in the call to $@ | tst.js:37:9:37:12 | this | this | tst.js:36:5:38:5 | unbound ... ;\\n } | unbound1 |
| tst.js:9:18:9:40 | onClick ... bound2} | The receiver of this event handler call is unbound, `$@` will be `undefined` in the call to $@ | tst.js:41:15:41:18 | this | this | tst.js:40:5:42:5 | unbound ... ;\\n } | unbound2 |
| tst.js:10:18:10:35 | onClick={unbound3} | The receiver of this event handler call is unbound, `$@` will be `undefined` in the call to $@ | tst.js:45:15:45:18 | this | this | tst.js:44:5:46:5 | unbound ... ;\\n } | unbound3 |

View File

@@ -17,6 +17,8 @@ class Component extends React.Component {
<div onClick={this.bound_throughNonSyntacticBindInConstructor}/> // OK
<div onClick={this.bound_throughBindAllInConstructor1}/> // OK
<div onClick={this.bound_throughBindAllInConstructor2}/> // OK
<div onClick={this.bound_throughDecorator_autobind}/> // OK
<div onClick={this.bound_throughDecorator_actionBound}/> // OK
</div>
}
@@ -87,6 +89,16 @@ class Component extends React.Component {
this.setState({ });
}
@autobind
bound_throughDecorator_autobind() {
this.setState({ });
}
@action.bound
bound_throughDecorator_actionBound() {
this.setState({ });
}
}
// semmle-extractor-options: --experimental