/** * @name Inconsistent direction of for loop * @description A 'for' loop that increments its loop variable but checks it * against a lower bound, or decrements its loop variable but * checks it against an upper bound, will either stop iterating * immediately or keep iterating indefinitely, and is usually * indicative of a typo. * @kind problem * @problem.severity error * @id js/inconsistent-loop-direction * @tags correctness * external/cwe/cwe-835 * @precision very-high */ import javascript /** * Holds if `test` bounds `v` in `direction`, which is either `"upward"` * or `"downward"`. * * For example, `x < 42` bounds `x` upward, while `y >= 0` bounds `y` * downward. */ predicate bounds(RelationalComparison test, Variable v, string direction) { test.getLesserOperand() = v.getAnAccess() and direction = "upward" or test.getGreaterOperand() = v.getAnAccess() and direction = "downward" } /** * Holds if `upd` updates `v` in `direction`, which is either `"upward"` * or `"downward"`. * * For example, `++x` updates `x` upward, while `y--` updates `y` * downward. */ predicate updates(UpdateExpr upd, Variable v, string direction) { upd.getOperand() = v.getAnAccess() and ( upd instanceof IncExpr and direction = "upward" or upd instanceof DecExpr and direction = "downward" ) } from ForStmt l, Variable v, string d1, string d2 where bounds(l.getTest(), v, d1) and updates(l.getUpdate(), v, d2) and d1 != d2 select l, "This loop counts " + d2 + ", but its variable is bounded " + d1 + "."