JS: move isDefensiveInit to DefensiveProgramming.qll

This commit is contained in:
Esben Sparre Andreasen
2018-09-27 15:01:46 +02:00
parent 2f0e693b38
commit c2fb14640e
2 changed files with 29 additions and 24 deletions

View File

@@ -15,29 +15,7 @@
import javascript
import semmle.javascript.RestrictedLocations
import semmle.javascript.dataflow.Refinements
/**
* Holds if `va` is a defensive truthiness check that may be worth keeping, even if it
* is strictly speaking useless.
*
* We currently recognize three patterns:
*
* - the first `x` in `x || (x = e)`
* - the second `x` in `x = (x || e)`
* - the second `x` in `var x = x || e`
*/
predicate isDefensiveInit(VarAccess va) {
exists (LogOrExpr o, VarRef va2 |
va = o.getLeftOperand().getUnderlyingReference() and va2.getVariable() = va.getVariable() |
exists (AssignExpr assgn | va2 = assgn.getTarget() |
assgn = o.getRightOperand().stripParens() or
o = assgn.getRhs().getUnderlyingValue()
) or
exists (VariableDeclarator vd | va2 = vd.getBindingPattern() |
o = vd.getInit().getUnderlyingValue()
)
)
}
import semmle.javascript.DefensiveProgramming
/**
* Holds if variable `v` looks like a symbolic constant, that is, it is assigned
@@ -109,7 +87,7 @@ predicate isConstantBooleanReturnValue(Expr e) {
predicate whitelist(Expr e) {
isConstant(e) or
isConstant(e.(LogNotExpr).getOperand()) or
isDefensiveInit(e) or
e.flow() instanceof DefensiveInit or
isInitialParameterUse(e) or
isConstantBooleanReturnValue(e)
}

View File

@@ -0,0 +1,27 @@
import javascript
/**
* A defensive truthiness check that may be worth keeping, even if it
* is strictly speaking useless.
*
* We currently recognize three patterns:
*
* - the first `x` in `x || (x = e)`
* - the second `x` in `x = (x || e)`
* - the second `x` in `var x = x || e`
*/
class DefensiveInit extends DataFlow::ValueNode {
DefensiveInit() {
exists(VarAccess va, LogOrExpr o, VarRef va2 |
va = astNode and
va = o.getLeftOperand().stripParens() and va2.getVariable() = va.getVariable() |
exists(AssignExpr assgn | va2 = assgn.getTarget() |
assgn = o.getRightOperand().stripParens() or
o = assgn.getRhs().stripParens()
)
or
exists(VariableDeclarator vd | va2 = vd.getBindingPattern() | o = vd.getInit().stripParens())
)
}
}