JS: Add UselessRangeCheck.ql

This commit is contained in:
Asger F
2018-09-21 12:24:25 +01:00
parent d813635f3e
commit 344bec3865
8 changed files with 117 additions and 0 deletions

View File

@@ -0,0 +1,47 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<overview>
<p>
If a condition always evaluates to true or always evaluates to false, this often indicates
incomplete code or a latent bug and should be examined carefully.
</p>
</overview>
<recommendation>
<p>
Examine the surrounding code to determine why the condition is useless. If it is no
longer needed, remove it.
</p>
<p>
If the check is needed to guard against NaN values, insert a comment explaning the possibility of NaN.
</p>
</recommendation>
<example>
<p>
The following example finds the index of an element in a given slice of the array:
</p>
<sample src="examples/UselessConditional.js" />
<p>
The condition <tt>i &lt; end</tt> at the end is always false, however. The code can be clarified if the
redundant condition is removed:
</p>
<sample src="examples/UselessConditionalGood.js" />
</example>
<references>
<li>Mozilla Developer Network: <a href="https://developer.mozilla.org/en-US/docs/Glossary/Truthy">Truthy</a>,
<a href="https://developer.mozilla.org/en-US/docs/Glossary/Falsy">Falsy</a>.</li>
</references>
</qhelp>

View File

@@ -0,0 +1,28 @@
/**
* @name Useless range check
* @description If a range check always fails or always succeeds it is indicative of a bug.
* @kind problem
* @problem.severity warning
* @id js/useless-range-check
* @tags correctness
* @precision high
*/
import javascript
/**
* Gets the guard node with the opposite outcome of `guard`.
*/
ConditionGuardNode getOppositeGuard(ConditionGuardNode guard) {
result.getTest() = guard.getTest() and
result.getOutcome() = guard.getOutcome().booleanNot()
}
from ConditionGuardNode guard
where RangeAnalysis::isContradictoryGuardNode(guard)
// Do not report conditions that themselves are unreachable because of
// a prior contradiction.
and not RangeAnalysis::isContradictoryGuardNode(getOppositeGuard(guard))
select guard.getTest(), "The condition '" + guard.getTest() + "' is always " + guard.getOutcome().booleanNot()

View File

@@ -0,0 +1,12 @@
function findValue(values, x, start, end) {
let i;
for (i = start; i < end; ++i) {
if (values[i] === x) {
return i;
}
}
if (i < end) {
return i;
}
return -1;
}

View File

@@ -0,0 +1,8 @@
function findValue(values, x, start, end) {
for (let i = start; i < end; ++i) {
if (values[i] === x) {
return i;
}
}
return -1;
}