mirror of
https://github.com/github/codeql.git
synced 2025-12-25 21:26:37 +01:00
53 lines
1.6 KiB
Plaintext
53 lines
1.6 KiB
Plaintext
/**
|
|
* @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 + "."
|