Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit fcc33ce

Browse files
author
Esben Sparre Andreasen
committed
JS: whitelist auto-bind methods in js/unbound-event-handler-receiver
1 parent eb10f60 commit fcc33ce

3 files changed

Lines changed: 45 additions & 21 deletions

File tree

javascript/ql/src/Expressions/UnboundEventHandlerReceiver.ql

Lines changed: 22 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -13,28 +13,33 @@ import javascript
1313
* Holds if the receiver of `method` is bound.
1414
*/
1515
private predicate isBoundInMethod(MethodDeclaration method) {
16-
exists (DataFlow::ThisNode thiz, MethodDeclaration bindingMethod, string name |
17-
name = method.getName() and
16+
exists (DataFlow::ThisNode thiz, MethodDeclaration bindingMethod |
1817
bindingMethod.getDeclaringClass() = method.getDeclaringClass() and
1918
not bindingMethod.isStatic() and
2019
thiz.getBinder().getAstNode() = bindingMethod.getBody() |
21-
exists (DataFlow::Node rhs, DataFlow::MethodCallNode bind |
22-
// this.<methodName> = <expr>.bind(...)
23-
thiz.hasPropertyWrite(name, rhs) and
24-
bind.flowsTo(rhs) and
25-
bind.getMethodName() = "bind"
26-
)
20+
// require("auto-bind")(this)
21+
thiz.flowsTo(DataFlow::moduleImport("auto-bind").getACall().getArgument(0))
2722
or
28-
exists (DataFlow::MethodCallNode bindAll |
29-
bindAll.getMethodName() = "bindAll" and
30-
thiz.flowsTo(bindAll.getArgument(0)) |
31-
// _.bindAll(this, <name1>)
32-
bindAll.getArgument(1).mayHaveStringValue(name)
23+
exists (string name |
24+
name = method.getName() |
25+
exists (DataFlow::Node rhs, DataFlow::MethodCallNode bind |
26+
// this.<methodName> = <expr>.bind(...)
27+
thiz.hasPropertyWrite(name, rhs) and
28+
bind.flowsTo(rhs) and
29+
bind.getMethodName() = "bind"
30+
)
3331
or
34-
// _.bindAll(this, [<name1>, <name2>])
35-
exists (DataFlow::ArrayLiteralNode names |
36-
names.flowsTo(bindAll.getArgument(1)) and
37-
names.getAnElement().mayHaveStringValue(name)
32+
exists (DataFlow::MethodCallNode bindAll |
33+
bindAll.getMethodName() = "bindAll" and
34+
thiz.flowsTo(bindAll.getArgument(0)) |
35+
// _.bindAll(this, <name1>)
36+
bindAll.getArgument(1).mayHaveStringValue(name)
37+
or
38+
// _.bindAll(this, [<name1>, <name2>])
39+
exists (DataFlow::ArrayLiteralNode names |
40+
names.flowsTo(bindAll.getArgument(1)) and
41+
names.getAnElement().mayHaveStringValue(name)
42+
)
3843
)
3944
)
4045
)
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
| 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 |
2-
| 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 |
3-
| 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 |
1+
| tst.js:27:18:27:40 | onClick ... bound1} | The receiver of this event handler call is unbound, `$@` will be `undefined` in the call to $@ | tst.js:56:9:56:12 | this | this | tst.js:55:5:57:5 | unbound ... ;\\n } | unbound1 |
2+
| tst.js:28:18:28:40 | onClick ... bound2} | The receiver of this event handler call is unbound, `$@` will be `undefined` in the call to $@ | tst.js:60:15:60:18 | this | this | tst.js:59:5:61:5 | unbound ... ;\\n } | unbound2 |
3+
| tst.js:29:18:29:35 | onClick={unbound3} | The receiver of this event handler call is unbound, `$@` will be `undefined` in the call to $@ | tst.js:64:15:64:18 | this | this | tst.js:63:5:65:5 | unbound ... ;\\n } | unbound3 |

javascript/ql/test/query-tests/Expressions/UnboundEventHandlerReceiver/tst.js

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,25 @@
11
import React from 'react';
2+
import autoBind from 'auto-bind';
23

3-
class Component extends React.Component {
4+
class Component0 extends React.Component {
5+
6+
render() {
7+
return <div>
8+
<div onClick={this.bound_throughAutoBind}/> // OK
9+
</div>
10+
}
11+
12+
constructor(props) {
13+
super(props);
14+
autoBind(this);
15+
}
16+
17+
bound_throughAutoBind() {
18+
this.setState({ });
19+
}
20+
}
21+
22+
class Component1 extends React.Component {
423

524
render() {
625
var unbound3 = this.unbound3;

0 commit comments

Comments
 (0)