Skip to content

Commit 2082171

Browse files
authored
Merge pull request #51 from github/aibaars/cfg-scopes
CFG: add more CfgScopeRanges
2 parents e181666 + 8632cbe commit 2082171

File tree

2 files changed

+71
-13
lines changed

2 files changed

+71
-13
lines changed

ql/src/codeql_ruby/controlflow/ControlFlowGraph.qll

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,34 @@ private import internal.ControlFlowGraphImpl
77
private import internal.Splitting
88
private import internal.Completion
99

10-
private class CfgScopeRange = @method or @block or @do_block;
10+
private class CfgScopeRange =
11+
@program or @begin_block or @end_block or @module or @class or @singleton_class or @method or
12+
@singleton_method or @block or @do_block;
1113

1214
/** An AST node with an associated control-flow graph. */
1315
class CfgScope extends AstNode, CfgScopeRange {
1416
/** Gets the name of this scope. */
1517
string getName() {
18+
this instanceof Program and
19+
result = "top-level"
20+
or
21+
this instanceof BeginBlock and
22+
result = "BEGIN block"
23+
or
24+
this instanceof EndBlock and
25+
result = "END block"
26+
or
27+
result = this.(Module).getName().toString()
28+
or
29+
result = this.(Class).getName().toString()
30+
or
31+
this instanceof SingletonClass and
32+
result = "singleton class"
33+
or
1634
result = this.(Method).getName().toString()
1735
or
36+
result = this.(SingletonMethod).getName().toString()
37+
or
1838
this instanceof Block and
1939
result = "block"
2040
or

ql/src/codeql_ruby/controlflow/internal/ControlFlowGraphImpl.qll

Lines changed: 50 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,14 @@ abstract private class StandardNode extends ControlFlowTree {
141141
abstract AstNode getChildNode(int i);
142142

143143
private AstNode getChildNodeRanked(int i) {
144-
result = rank[i + 1](AstNode child, int j | child = this.getChildNode(j) | child order by j)
144+
result =
145+
rank[i + 1](AstNode child, int j |
146+
child = this.getChildNode(j) and
147+
// Never descend into children with a separate scope
148+
not child instanceof CfgScope
149+
|
150+
child order by j
151+
)
145152
}
146153

147154
/** Gets the first child node of this element. */
@@ -150,24 +157,17 @@ abstract private class StandardNode extends ControlFlowTree {
150157
/** Gets the last child node of this node. */
151158
final AstNode getLastChildNode() {
152159
exists(int last |
153-
last = max(int i | exists(this.getChildNodeRanked(i))) and
154-
result = this.getChildNodeRanked(last)
160+
result = this.getChildNodeRanked(last) and
161+
not exists(this.getChildNodeRanked(last + 1))
155162
)
156163
}
157164

158-
/** Gets the `i`th child, which is not the last node. */
159-
pragma[nomagic]
160-
private AstNode getNonLastChildNode(int i) {
161-
result = this.getChildNodeRanked(i) and
162-
not result = this.getLastChildNode()
163-
}
164-
165-
final override predicate propagatesAbnormal(AstNode child) { child = this.getChildNode(_) }
165+
final override predicate propagatesAbnormal(AstNode child) { child = this.getChildNodeRanked(_) }
166166

167167
pragma[nomagic]
168168
override predicate succ(AstNode pred, AstNode succ, Completion c) {
169169
exists(int i |
170-
last(this.getNonLastChildNode(i), pred, c) and
170+
last(this.getChildNodeRanked(i), pred, c) and
171171
c instanceof NormalCompletion and
172172
first(this.getChildNodeRanked(i + 1), succ)
173173
)
@@ -246,6 +246,10 @@ private module Trees {
246246
}
247247
}
248248

249+
private class BeginBlockTree extends StandardPreOrderTree, BeginBlock {
250+
final override AstNode getChildNode(int i) { result = this.getChild(i) }
251+
}
252+
249253
private class BinaryTree extends StandardPostOrderTree, Binary {
250254
BinaryTree() { not this instanceof LogicalAndAstNode and not this instanceof LogicalOrAstNode }
251255

@@ -272,6 +276,12 @@ private module Trees {
272276
}
273277
}
274278

279+
private class ClassTree extends StandardPreOrderTree, Class {
280+
final override AstNode getChildNode(int i) { result = this.getChild(i) }
281+
282+
override predicate isHidden() { any() }
283+
}
284+
275285
private class DoTree extends StandardPreOrderTree, Do {
276286
final override AstNode getChildNode(int i) { result = this.getChild(i) }
277287

@@ -290,6 +300,10 @@ private module Trees {
290300
override predicate isHidden() { any() }
291301
}
292302

303+
private class EndBlockTree extends StandardPreOrderTree, EndBlock {
304+
final override AstNode getChildNode(int i) { result = this.getChild(i) }
305+
}
306+
293307
private class IdentifierTree extends LeafTree, Identifier { }
294308

295309
private class IfElsifTree extends PreOrderTree, IfElsifAstNode {
@@ -392,6 +406,12 @@ private module Trees {
392406
}
393407
}
394408

409+
private class ModuleTree extends StandardPreOrderTree, Module {
410+
final override AstNode getChildNode(int i) { result = this.getChild(i) }
411+
412+
override predicate isHidden() { any() }
413+
}
414+
395415
private class NextTree extends StandardPostOrderTree, Next {
396416
final override AstNode getChildNode(int i) { result = this.getChild() and i = 0 }
397417
}
@@ -408,6 +428,12 @@ private module Trees {
408428
final override AstNode getChildNode(int i) { result = this.getChild(i) }
409429
}
410430

431+
private class ProgramTree extends StandardPreOrderTree, Program {
432+
final override AstNode getChildNode(int i) { result = this.getChild(i) }
433+
434+
override predicate isHidden() { any() }
435+
}
436+
411437
private class RedoTree extends StandardPostOrderTree, Redo {
412438
final override AstNode getChildNode(int i) { result = this.getChild() and i = 0 }
413439
}
@@ -416,6 +442,18 @@ private module Trees {
416442
final override AstNode getChildNode(int i) { result = this.getChild() and i = 0 }
417443
}
418444

445+
private class SingletonClassTree extends StandardPreOrderTree, SingletonClass {
446+
final override AstNode getChildNode(int i) { result = this.getChild(i) }
447+
448+
override predicate isHidden() { any() }
449+
}
450+
451+
private class SingletonMethodTree extends StandardPreOrderTree, SingletonMethod {
452+
final override AstNode getChildNode(int i) { result = this.getChild(i) }
453+
454+
override predicate isHidden() { any() }
455+
}
456+
419457
private class StringTree extends LeafTree, String { }
420458

421459
private class ThenTree extends StandardPreOrderTree, Then {

0 commit comments

Comments
 (0)