Skip to content

Commit 3e26236

Browse files
committed
JS: Add recursion guard test
1 parent c103939 commit 3e26236

File tree

3 files changed

+28
-1
lines changed

3 files changed

+28
-1
lines changed

javascript/ql/src/semmle/javascript/dataflow/Sources.qll

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,11 @@ private import semmle.javascript.internal.CachedStages
3434
* ```
3535
*/
3636
class SourceNode extends DataFlow::Node {
37-
SourceNode() { this instanceof SourceNode::Range }
37+
SourceNode() {
38+
this instanceof SourceNode::Range
39+
or
40+
none() and this instanceof SourceNode::Internal::RecursionGuard
41+
}
3842

3943
/**
4044
* Holds if this node flows into `sink` in zero or more local (that is,
@@ -329,6 +333,12 @@ module SourceNode {
329333
DataFlow::functionReturnNode(this, _)
330334
}
331335
}
336+
337+
/** INTERNAL. DO NOT USE. */
338+
module Internal {
339+
/** An empty class that some tests are using to enforce that SourceNode is non-recursive. */
340+
abstract class RecursionGuard extends DataFlow::Node {}
341+
}
332342
}
333343

334344
deprecated class DefaultSourceNode extends SourceNode {
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
| Success |
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
/**
2+
* Test that fails to compile if the domain of `SourceNode::Range` depends on `SourceNode` (recursively).
3+
*
4+
* This tests adds a negative dependency `SourceNode --!--> SourceNode::Range`
5+
* so that the undesired edge `SourceNode::Range --> SourceNode` completes a negative cycle.
6+
*/
7+
8+
import javascript
9+
10+
class BadSourceNodeRange extends DataFlow::SourceNode::Internal::RecursionGuard {
11+
BadSourceNodeRange() {
12+
not this instanceof DataFlow::SourceNode::Range
13+
}
14+
}
15+
16+
select "Success"

0 commit comments

Comments
 (0)