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

Skip to content

Commit a5eeba3

Browse files
author
Esben Sparre Andreasen
committed
JS: prepare DefensiveProgramming.qll for additions
1 parent c2fb146 commit a5eeba3

2 files changed

Lines changed: 42 additions & 20 deletions

File tree

javascript/ql/src/Statements/UselessConditional.ql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ predicate isConstantBooleanReturnValue(Expr e) {
8787
predicate whitelist(Expr e) {
8888
isConstant(e) or
8989
isConstant(e.(LogNotExpr).getOperand()) or
90-
e.flow() instanceof DefensiveInit or
90+
e.flow() instanceof Internal::DefensiveInit or
9191
isInitialParameterUse(e) or
9292
isConstantBooleanReturnValue(e)
9393
}
Lines changed: 41 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,49 @@
1+
/**
2+
* Provides classes for working with defensive programming patterns.
3+
*/
4+
15
import javascript
6+
private import semmle.javascript.dataflow.InferredTypes
27

38
/**
4-
* A defensive truthiness check that may be worth keeping, even if it
5-
* is strictly speaking useless.
6-
*
7-
* We currently recognize three patterns:
8-
*
9-
* - the first `x` in `x || (x = e)`
10-
* - the second `x` in `x = (x || e)`
11-
* - the second `x` in `var x = x || e`
9+
* The test in a defensive programming pattern.
1210
*/
13-
class DefensiveInit extends DataFlow::ValueNode {
14-
DefensiveInit() {
15-
exists(VarAccess va, LogOrExpr o, VarRef va2 |
16-
va = astNode and
17-
va = o.getLeftOperand().stripParens() and va2.getVariable() = va.getVariable() |
18-
exists(AssignExpr assgn | va2 = assgn.getTarget() |
19-
assgn = o.getRightOperand().stripParens() or
20-
o = assgn.getRhs().stripParens()
11+
abstract class DefensiveExpression extends DataFlow::ValueNode {
12+
/** Gets the unique Boolean value that this test evaluates to, if any. */
13+
abstract boolean getTheTestResult();
14+
}
15+
16+
/**
17+
* INTERNAL: Do not use directly; use `DefensiveExpression` instead.
18+
*/
19+
module Internal {
20+
/**
21+
* A defensive truthiness check that may be worth keeping, even if it
22+
* is strictly speaking useless.
23+
*
24+
* We currently recognize three patterns:
25+
*
26+
* - the first `x` in `x || (x = e)`
27+
* - the second `x` in `x = (x || e)`
28+
* - the second `x` in `var x = x || e`
29+
*/
30+
class DefensiveInit extends DefensiveExpression {
31+
DefensiveInit() {
32+
exists(VarAccess va, LogOrExpr o, VarRef va2 |
33+
va = astNode and
34+
va = o.getLeftOperand().stripParens() and va2.getVariable() = va.getVariable() |
35+
exists(AssignExpr assgn | va2 = assgn.getTarget() |
36+
assgn = o.getRightOperand().stripParens() or
37+
o = assgn.getRhs().stripParens()
38+
)
39+
or
40+
exists(VariableDeclarator vd | va2 = vd.getBindingPattern() | o = vd.getInit().stripParens())
2141
)
22-
or
23-
exists(VariableDeclarator vd | va2 = vd.getBindingPattern() | o = vd.getInit().stripParens())
24-
)
42+
}
43+
44+
override boolean getTheTestResult() {
45+
result = analyze().getTheBooleanValue()
46+
}
2547
}
2648

2749
}

0 commit comments

Comments
 (0)