Skip to content

Commit 7dcd2d6

Browse files
committed
Ruby: Adjust CFG to updated AST.
1 parent b6c2915 commit 7dcd2d6

3 files changed

Lines changed: 62 additions & 76 deletions

File tree

ruby/ql/consistency-queries/CfgConsistency.ql

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,7 @@ import codeql.ruby.controlflow.internal.ControlFlowGraphImpl as CfgImpl
1111
query predicate nonPostOrderExpr(Expr e, string cls) {
1212
cls = e.getPrimaryQlClasses() and
1313
not exists(e.getDesugared()) and
14-
not e instanceof BeginExpr and
15-
not e instanceof Namespace and
16-
not e instanceof Toplevel and
14+
not e instanceof BodyStmt and
1715
exists(AstNode last, Completion c |
1816
CfgImpl::last(e, last, c) and
1917
last != e and

ruby/ql/lib/codeql/ruby/controlflow/internal/ControlFlowGraphImpl.qll

Lines changed: 60 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -100,24 +100,26 @@ private class EndBlockScope extends CfgScopeImpl, EndBlock {
100100
}
101101
}
102102

103-
private class BodyStmtCallableScope extends CfgScopeImpl, AstInternal::TBodyStmt, Callable {
104-
final override predicate entry(AstNode first) { this.(Trees::BodyStmtTree).firstInner(first) }
105-
106-
final override predicate exit(AstNode last, Completion c) {
107-
this.(Trees::BodyStmtTree).lastInner(last, c)
108-
}
109-
}
110-
111-
private class BraceBlockScope extends CfgScopeImpl, BraceBlock {
103+
private class CallableScope extends CfgScopeImpl, Callable {
112104
final override predicate entry(AstNode first) {
113-
first(this.(Trees::BraceBlockTree).getBodyChild(0, _), first)
105+
first(this.(Trees::CallableTree).getBodyChild(0), first)
114106
}
115107

116108
final override predicate exit(AstNode last, Completion c) {
117-
last(this.(Trees::BraceBlockTree).getLastBodyChild(), last, c)
109+
this.getBody().(Trees::BodyStmtTree).last(last, c)
118110
or
119-
last(this.(Trees::BraceBlockTree).getBodyChild(_, _), last, c) and
120-
not c instanceof NormalCompletion
111+
exists(int i |
112+
not exists(this.getBody()) and
113+
last(this.(Trees::CallableTree).getBodyChild(i), last, c) and
114+
not exists(this.(Trees::CallableTree).getBodyChild(i + 1))
115+
)
116+
or
117+
exists(AstNode child |
118+
child = this.(Trees::CallableTree).getBodyChild(_) and
119+
not child = this.getBody() and
120+
last(child, last, c) and
121+
not c instanceof NormalCompletion
122+
)
121123
}
122124
}
123125

@@ -159,10 +161,6 @@ module Trees {
159161
}
160162

161163
private class BeginTree extends BodyStmtTree instanceof BeginExpr {
162-
final override predicate first(AstNode first) { this.firstInner(first) }
163-
164-
final override predicate last(AstNode last, Completion c) { this.lastInner(last, c) }
165-
166164
final override predicate propagatesAbnormal(AstNode child) { none() }
167165
}
168166

@@ -196,16 +194,14 @@ module Trees {
196194
private class BlockParameterTree extends NonDefaultValueParameterTree instanceof BlockParameter {
197195
}
198196

199-
abstract class BodyStmtTree extends StmtSequenceTree instanceof BodyStmt {
197+
class BodyStmtTree extends StmtSequenceTree instanceof BodyStmt {
200198
/** Gets a rescue clause in this block. */
201199
final RescueClause getARescue() { result = super.getRescue(_) }
202200

203201
/** Gets the `ensure` clause in this block, if any. */
204202
final StmtSequence getEnsure() { result = super.getEnsure() }
205203

206-
override predicate first(AstNode first) { first = this }
207-
208-
predicate firstInner(AstNode first) {
204+
override predicate first(AstNode first) {
209205
first(this.getBodyChild(0, _), first)
210206
or
211207
not exists(this.getBodyChild(_, _)) and
@@ -217,7 +213,7 @@ module Trees {
217213
)
218214
}
219215

220-
predicate lastInner(AstNode last, Completion c) {
216+
override predicate last(AstNode last, Completion c) {
221217
exists(boolean ensurable | last = this.getAnEnsurePredecessor(c, ensurable) |
222218
not super.hasEnsure()
223219
or
@@ -387,27 +383,28 @@ module Trees {
387383

388384
private class BooleanLiteralTree extends LeafTree instanceof BooleanLiteral { }
389385

390-
class BraceBlockTree extends StmtSequenceTree instanceof BraceBlock {
391-
final override predicate propagatesAbnormal(AstNode child) { none() }
392-
393-
final override AstNode getBodyChild(int i, boolean rescuable) {
394-
result = super.getParameter(i) and rescuable = false
386+
class BraceBlockTree extends CallableTree instanceof BraceBlock {
387+
final override AstNode getBodyChild(int i) {
388+
result = super.getParameter(i)
395389
or
396-
result = super.getLocalVariable(i - super.getNumberOfParameters()) and rescuable = false
390+
result = super.getLocalVariable(i - super.getNumberOfParameters())
397391
or
398-
result =
399-
StmtSequenceTree.super
400-
.getBodyChild(i - super.getNumberOfParameters() - count(super.getALocalVariable()),
401-
rescuable)
392+
result = super.getBody() and
393+
i = super.getNumberOfParameters() + count(super.getALocalVariable())
402394
}
395+
}
396+
397+
class CallableTree extends PostOrderTree instanceof Callable {
398+
final override predicate propagatesAbnormal(AstNode child) { none() }
403399

404400
override predicate first(AstNode first) { first = this }
405401

402+
abstract AstNode getBodyChild(int i);
403+
406404
override predicate succ(AstNode pred, AstNode succ, Completion c) {
407-
// Normal left-to-right evaluation in the body
408405
exists(int i |
409-
last(this.getBodyChild(i, _), pred, c) and
410-
first(this.getBodyChild(i + 1, _), succ) and
406+
last(this.getBodyChild(i), pred, c) and
407+
first(this.getBodyChild(i + 1), succ) and
411408
c instanceof NormalCompletion
412409
)
413410
}
@@ -1016,20 +1013,16 @@ module Trees {
10161013
final override predicate succ(AstNode pred, AstNode succ, Completion c) { none() }
10171014
}
10181015

1019-
private class DoBlockTree extends BodyStmtTree instanceof DoBlock {
1016+
private class DoBlockTree extends CallableTree instanceof DoBlock {
10201017
/** Gets the `i`th child in the body of this block. */
1021-
final override AstNode getBodyChild(int i, boolean rescuable) {
1022-
result = super.getParameter(i) and rescuable = false
1018+
final override AstNode getBodyChild(int i) {
1019+
result = super.getParameter(i)
10231020
or
1024-
result = super.getLocalVariable(i - super.getNumberOfParameters()) and rescuable = false
1021+
result = super.getLocalVariable(i - super.getNumberOfParameters())
10251022
or
1026-
result =
1027-
BodyStmtTree.super
1028-
.getBodyChild(i - super.getNumberOfParameters() - count(super.getALocalVariable()),
1029-
rescuable)
1023+
result = super.getBody() and
1024+
i = super.getNumberOfParameters() + count(super.getALocalVariable())
10301025
}
1031-
1032-
override predicate propagatesAbnormal(AstNode child) { none() }
10331026
}
10341027

10351028
private class EmptyStatementTree extends LeafTree instanceof EmptyStmt { }
@@ -1073,14 +1066,12 @@ module Trees {
10731066
final override AstNode getAccessNode() { result = super.getDefiningAccess() }
10741067
}
10751068

1076-
private class LambdaTree extends BodyStmtTree instanceof Lambda {
1077-
final override predicate propagatesAbnormal(AstNode child) { none() }
1078-
1069+
private class LambdaTree extends CallableTree instanceof Lambda {
10791070
/** Gets the `i`th child in the body of this block. */
1080-
final override AstNode getBodyChild(int i, boolean rescuable) {
1081-
result = super.getParameter(i) and rescuable = false
1071+
final override AstNode getBodyChild(int i) {
1072+
result = super.getParameter(i)
10821073
or
1083-
result = BodyStmtTree.super.getBodyChild(i - super.getNumberOfParameters(), rescuable)
1074+
result = super.getBody() and i = super.getNumberOfParameters()
10841075
}
10851076
}
10861077

@@ -1151,14 +1142,12 @@ module Trees {
11511142
private class MethodNameTree extends LeafTree instanceof MethodName, AstInternal::TTokenMethodName
11521143
{ }
11531144

1154-
private class MethodTree extends BodyStmtTree instanceof Method {
1155-
final override predicate propagatesAbnormal(AstNode child) { none() }
1156-
1145+
private class MethodTree extends CallableTree instanceof Method {
11571146
/** Gets the `i`th child in the body of this block. */
1158-
final override AstNode getBodyChild(int i, boolean rescuable) {
1159-
result = super.getParameter(i) and rescuable = false
1147+
final override AstNode getBodyChild(int i) {
1148+
result = super.getParameter(i)
11601149
or
1161-
result = BodyStmtTree.super.getBodyChild(i - super.getNumberOfParameters(), rescuable)
1150+
result = super.getBody() and i = super.getNumberOfParameters()
11621151
}
11631152
}
11641153

@@ -1183,12 +1172,12 @@ module Trees {
11831172
BodyStmtTree.super.succ(pred, succ, c)
11841173
or
11851174
pred = this and
1186-
this.firstInner(succ) and
1175+
super.first(succ) and
11871176
c instanceof SimpleCompletion
11881177
}
11891178

11901179
final override predicate last(AstNode last, Completion c) {
1191-
this.lastInner(last, c)
1180+
super.last(last, c)
11921181
or
11931182
not exists(this.getAChild(_)) and
11941183
last = this and
@@ -1328,7 +1317,7 @@ module Trees {
13281317

13291318
private class SingletonClassTree extends BodyStmtTree instanceof SingletonClass {
13301319
final override predicate first(AstNode first) {
1331-
this.firstInner(first)
1320+
super.first(first)
13321321
or
13331322
not exists(this.getAChild(_)) and
13341323
first = this
@@ -1338,7 +1327,12 @@ module Trees {
13381327
BodyStmtTree.super.succ(pred, succ, c)
13391328
or
13401329
succ = this and
1341-
this.lastInner(pred, c)
1330+
super.last(pred, c)
1331+
}
1332+
1333+
final override predicate last(AstNode last, Completion c) {
1334+
last = this and
1335+
c.isValidFor(this)
13421336
}
13431337

13441338
/** Gets the `i`th child in the body of this block. */
@@ -1351,20 +1345,18 @@ module Trees {
13511345
}
13521346
}
13531347

1354-
private class SingletonMethodTree extends BodyStmtTree instanceof SingletonMethod {
1355-
final override predicate propagatesAbnormal(AstNode child) { none() }
1356-
1348+
private class SingletonMethodTree extends CallableTree instanceof SingletonMethod {
13571349
/** Gets the `i`th child in the body of this block. */
1358-
final override AstNode getBodyChild(int i, boolean rescuable) {
1359-
result = super.getParameter(i) and rescuable = false
1350+
final override AstNode getBodyChild(int i) {
1351+
result = super.getParameter(i)
13601352
or
1361-
result = BodyStmtTree.super.getBodyChild(i - super.getNumberOfParameters(), rescuable)
1353+
result = super.getBody() and i = super.getNumberOfParameters()
13621354
}
13631355

13641356
override predicate first(AstNode first) { first(super.getObject(), first) }
13651357

13661358
override predicate succ(AstNode pred, AstNode succ, Completion c) {
1367-
BodyStmtTree.super.succ(pred, succ, c)
1359+
CallableTree.super.succ(pred, succ, c)
13681360
or
13691361
last(super.getObject(), pred, c) and
13701362
succ = this and
@@ -1443,10 +1435,6 @@ module Trees {
14431435
or
14441436
result = BodyStmtTree.super.getBodyChild(i - count(super.getABeginBlock()), rescuable)
14451437
}
1446-
1447-
final override predicate first(AstNode first) { super.firstInner(first) }
1448-
1449-
final override predicate last(AstNode last, Completion c) { super.lastInner(last, c) }
14501438
}
14511439

14521440
private class UndefStmtTree extends StandardPreOrderTree instanceof UndefStmt {

ruby/ql/lib/codeql/ruby/controlflow/internal/Splitting.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,7 @@ module EnsureSplitting {
246246
private predicate exit0(AstNode pred, Trees::BodyStmtTree block, int nestLevel, Completion c) {
247247
this.appliesToPredecessor(pred) and
248248
nestLevel = block.getNestLevel() and
249-
block.lastInner(pred, c)
249+
block.last(pred, c)
250250
}
251251

252252
/**

0 commit comments

Comments
 (0)