Skip to content

Commit 5397da7

Browse files
committed
JS: Handle implicit return in getImmediatePredecessor
1 parent 8e1893d commit 5397da7

File tree

2 files changed

+9
-7
lines changed

2 files changed

+9
-7
lines changed

javascript/ql/src/semmle/javascript/dataflow/DataFlow.qll

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -166,11 +166,7 @@ module DataFlow {
166166
* Gets the immediate predecessor of this node, if any.
167167
*
168168
* A node with an immediate predecessor can usually only have the value that flows
169-
* into its from its immediate predecessor, currently with one exception:
170-
*
171-
* - An immediately-invoked function expression with a single return expression `e`
172-
* has `e` as its immediate predecessor, even if the function can fall over the
173-
* end and return `undefined`.
169+
* into its from its immediate predecessor.
174170
*/
175171
cached
176172
DataFlow::Node getImmediatePredecessor() {
@@ -190,11 +186,11 @@ module DataFlow {
190186
)
191187
or
192188
// IIFE call -> return value of IIFE
193-
// Note: not sound in case function falls over end and returns 'undefined'
194189
exists(Function fun |
195190
localCall(this.asExpr(), fun) and
196191
result = fun.getAReturnedExpr().flow() and
197-
strictcount(fun.getAReturnedExpr()) = 1
192+
strictcount(fun.getAReturnedExpr()) = 1 and
193+
not fun.getExit().isJoin() // can only reach exit by the return statement
198194
)
199195
}
200196
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
function test() {
2+
let x = (function() {
3+
if (g) return 5;
4+
})();
5+
if (x + 1 < 5) {} // OK
6+
}

0 commit comments

Comments
 (0)