Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 43df953

Browse files
committed
JS: be conservative in presence of NaN comments
1 parent feb8a8c commit 43df953

2 files changed

Lines changed: 32 additions & 1 deletion

File tree

javascript/ql/src/semmle/javascript/RangeAnalysis.qll

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ import javascript
6969
*
7070
* CAVEATS:
7171
*
72-
* - We assume !(x <= y) means x > y, ignoring NaN.
72+
* - We assume !(x <= y) means x > y, ignoring NaN, unless a nearby comment or identifier mentions NaN.
7373
*
7474
* - We assume integer arithmetic is exact, ignoring values above 2^53.
7575
*
@@ -257,6 +257,24 @@ module RangeAnalysis {
257257
)
258258
}
259259

260+
/**
261+
* Holds if the given container has a comment or identifier mentioning `NaN`.
262+
*/
263+
predicate hasNaNIndicator(StmtContainer container) {
264+
exists (Comment comment |
265+
comment.getText().regexpMatch("(?s).*N[aA]N.*") and
266+
comment.getFile() = container.getFile() and
267+
(
268+
comment.getLocation().getStartLine() >= container.getLocation().getStartLine() and
269+
comment.getLocation().getEndLine() <= container.getLocation().getEndLine()
270+
or
271+
comment.getNextToken() = container.getFirstToken()
272+
))
273+
or
274+
exists (Identifier id | id.getName() = "NaN" or id.getName() = "isNaN" |
275+
id.getContainer() = container)
276+
}
277+
260278
/**
261279
* Holds if `guard` asserts that the outcome of `A <op> B + bias` is true, where `<op>` is a comparison operator.
262280
*/
@@ -266,6 +284,7 @@ module RangeAnalysis {
266284
(
267285
guard.getOutcome() = true and operator = compare.getOperator()
268286
or
287+
not hasNaNIndicator(guard.getContainer()) and
269288
guard.getOutcome() = false and operator = negateOperator(compare.getOperator())
270289
)
271290
)

javascript/ql/test/library-tests/RangeAnalysis/tst.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,3 +50,15 @@ function h(x, y) {
5050
if (x > y) {} // NOT OK - always true
5151
}
5252
}
53+
54+
function nan(x) {
55+
// This is a NaN comment.
56+
if (x - 1 < x) {} // OK
57+
}
58+
59+
/**
60+
* This is a NAN comment.
61+
*/
62+
function nan2(x) {
63+
if (x - 1 < x) {} // OK
64+
}

0 commit comments

Comments
 (0)