Skip to content

Commit b35c4b2

Browse files
author
Esben Sparre Andreasen
committed
JS: support FP pattern for js/unbound-event-handler-receiver
1 parent 9c41b21 commit b35c4b2

File tree

2 files changed

+30
-1
lines changed

2 files changed

+30
-1
lines changed

javascript/ql/src/Expressions/UnboundEventHandlerReceiver.ql

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,15 @@ private predicate isBoundInMethod(MethodDeclaration method) {
1818
bindingMethod.getDeclaringClass() = method.getDeclaringClass() and
1919
not bindingMethod.isStatic() and
2020
thiz.getBinder().getAstNode() = bindingMethod.getBody()
21-
|
21+
|
22+
exists (DataFlow::MethodCallNode bind, DataFlow::PropWrite w |
23+
// this[x] = <expr>.bind(...)
24+
w = thiz.getAPropertyWrite() and
25+
not exists(w.getPropertyName()) and
26+
bind.getMethodName() = "bind" and
27+
bind.flowsTo(w.getRhs())
28+
)
29+
or
2230
// require("auto-bind")(this)
2331
thiz.flowsTo(DataFlow::moduleImport("auto-bind").getACall().getArgument(0))
2432
or

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

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,4 +134,25 @@ class Component2 extends React.Component {
134134
}
135135

136136
}
137+
138+
class Component3 extends React.Component {
139+
140+
render() {
141+
return <div>
142+
<div onClick={this.bound_throughIterator}/> // OK
143+
</div>
144+
}
145+
146+
constructor(props) {
147+
super(props);
148+
Object.getOwnPropertyNames( Component3.prototype )
149+
.filter( prop => typeof this[ prop ] === 'function' )
150+
.forEach( prop => ( this[ prop ] = this[ prop ].bind( this ) ) );
151+
}
152+
153+
bound_throughIterator() {
154+
this.setState({ });
155+
}
156+
}
157+
137158
// semmle-extractor-options: --experimental

0 commit comments

Comments
 (0)