refactor isExplicitConditional into a library file, and use it from js/use-of-returnless-function

This commit is contained in:
Erik Krogh Kristensen
2019-10-02 11:27:31 +02:00
parent bda37b6d6f
commit dedae5ba1d
4 changed files with 29 additions and 17 deletions

View File

@@ -12,6 +12,7 @@
import javascript
import Declarations.UnusedVariable
import Expressions.ExprHasNoEffect
import Statements.UselessConditional
predicate returnsVoid(Function f) {
exists(f.getBody().(Stmt)) and
@@ -57,9 +58,8 @@ predicate benignContext(Expr e) {
// It is ok (or to be flagged by another query?) to await a non-async function.
exists(AwaitExpr await | await.getOperand() = e and benignContext(await))
or
// Avoid double reporting with js/trivial-conditional
exists(IfStmt ifStmt | ifStmt.getCondition() = e)
exists(ASTNode cond | isExplicitConditional(cond, e))
or
// Avoid double reporting with js/comparison-between-incompatible-types
exists(Comparison binOp | binOp.getAnOperand() = e)

View File

@@ -16,6 +16,7 @@ import javascript
import semmle.javascript.RestrictedLocations
import semmle.javascript.dataflow.Refinements
import semmle.javascript.DefensiveProgramming
import UselessConditional
/**
* Gets the unique definition of `v`.
@@ -123,21 +124,7 @@ predicate whitelist(Expr e) {
isConstantBooleanReturnValue(e)
}
/**
* Holds if `e` is part of a conditional node `cond` that evaluates
* `e` and checks its value for truthiness, and the return value of `e`
* is not used for anything other than this truthiness check.
*/
predicate isExplicitConditional(ASTNode cond, Expr e) {
e = cond.(IfStmt).getCondition()
or
e = cond.(LoopStmt).getTest()
or
e = cond.(ConditionalExpr).getCondition()
or
isExplicitConditional(_, cond) and
e = cond.(Expr).getUnderlyingValue().(LogicalBinaryExpr).getAnOperand()
}
/**
* Holds if `e` is part of a conditional node `cond` that evaluates

View File

@@ -0,0 +1,17 @@
import javascript
/**
* Holds if `e` is part of a conditional node `cond` that evaluates
* `e` and checks its value for truthiness, and the return value of `e`
* is not used for anything other than this truthiness check.
*/
predicate isExplicitConditional(ASTNode cond, Expr e) {
e = cond.(IfStmt).getCondition()
or
e = cond.(LoopStmt).getTest()
or
e = cond.(ConditionalExpr).getCondition()
or
isExplicitConditional(_, cond) and
e = cond.(Expr).getUnderlyingValue().(LogicalBinaryExpr).getAnOperand()
}