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

Skip to content

Commit dedae5b

Browse files
committed
refactor isExplicitConditional into a library file, and use it from js/use-of-returnless-function
1 parent bda37b6 commit dedae5b

4 files changed

Lines changed: 29 additions & 17 deletions

File tree

javascript/ql/src/Statements/UseOfReturnlessFunction.ql

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import javascript
1313
import Declarations.UnusedVariable
1414
import Expressions.ExprHasNoEffect
15+
import Statements.UselessConditional
1516

1617
predicate returnsVoid(Function f) {
1718
exists(f.getBody().(Stmt)) and
@@ -57,9 +58,8 @@ predicate benignContext(Expr e) {
5758
// It is ok (or to be flagged by another query?) to await a non-async function.
5859
exists(AwaitExpr await | await.getOperand() = e and benignContext(await))
5960
or
60-
6161
// Avoid double reporting with js/trivial-conditional
62-
exists(IfStmt ifStmt | ifStmt.getCondition() = e)
62+
exists(ASTNode cond | isExplicitConditional(cond, e))
6363
or
6464
// Avoid double reporting with js/comparison-between-incompatible-types
6565
exists(Comparison binOp | binOp.getAnOperand() = e)

javascript/ql/src/Statements/UselessConditional.ql

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import javascript
1616
import semmle.javascript.RestrictedLocations
1717
import semmle.javascript.dataflow.Refinements
1818
import semmle.javascript.DefensiveProgramming
19+
import UselessConditional
1920

2021
/**
2122
* Gets the unique definition of `v`.
@@ -123,21 +124,7 @@ predicate whitelist(Expr e) {
123124
isConstantBooleanReturnValue(e)
124125
}
125126

126-
/**
127-
* Holds if `e` is part of a conditional node `cond` that evaluates
128-
* `e` and checks its value for truthiness, and the return value of `e`
129-
* is not used for anything other than this truthiness check.
130-
*/
131-
predicate isExplicitConditional(ASTNode cond, Expr e) {
132-
e = cond.(IfStmt).getCondition()
133-
or
134-
e = cond.(LoopStmt).getTest()
135-
or
136-
e = cond.(ConditionalExpr).getCondition()
137-
or
138-
isExplicitConditional(_, cond) and
139-
e = cond.(Expr).getUnderlyingValue().(LogicalBinaryExpr).getAnOperand()
140-
}
127+
141128

142129
/**
143130
* Holds if `e` is part of a conditional node `cond` that evaluates
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import javascript
2+
3+
/**
4+
* Holds if `e` is part of a conditional node `cond` that evaluates
5+
* `e` and checks its value for truthiness, and the return value of `e`
6+
* is not used for anything other than this truthiness check.
7+
*/
8+
predicate isExplicitConditional(ASTNode cond, Expr e) {
9+
e = cond.(IfStmt).getCondition()
10+
or
11+
e = cond.(LoopStmt).getTest()
12+
or
13+
e = cond.(ConditionalExpr).getCondition()
14+
or
15+
isExplicitConditional(_, cond) and
16+
e = cond.(Expr).getUnderlyingValue().(LogicalBinaryExpr).getAnOperand()
17+
}

javascript/ql/test/query-tests/Statements/UseOfReturnlessFunction/tst.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,4 +29,12 @@
2929

3030
var d = 42 + (42, onlySideEffects()); // NOT OK!
3131
console.log(d);
32+
33+
if (onlySideEffects()) {
34+
// nothing.
35+
}
36+
37+
for (i = 0; onlySideEffects(); i++) {
38+
// nothing.
39+
}
3240
})();

0 commit comments

Comments
 (0)