Skip to content

Commit ba89653

Browse files
committed
Ruby: CFG: make RescueClause post-order
1 parent db4b781 commit ba89653

File tree

2 files changed

+52
-64
lines changed

2 files changed

+52
-64
lines changed

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

Lines changed: 32 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,7 @@ module Trees {
246246
)
247247
or
248248
// Last element from any matching `rescue` block continues to the `ensure` block
249-
this.getRescue(_).(RescueTree).lastMatch(result, c) and
249+
last(this.getRescue(_), result, c) and
250250
ensurable = true
251251
or
252252
// If the last `rescue` block does not match, continue to the `ensure` block
@@ -1170,80 +1170,68 @@ module Trees {
11701170
}
11711171
}
11721172

1173-
private class RescueTree extends PreOrderTree, RescueClause {
1174-
final override predicate propagatesAbnormal(AstNode child) { child = this.getAnException() }
1175-
1176-
private Expr getLastException() {
1177-
exists(int i | result = this.getException(i) and not exists(this.getException(i + 1)))
1173+
private class RescueTree extends PostOrderTree, RescueClause {
1174+
final override predicate propagatesAbnormal(AstNode child) {
1175+
child = this.getAnException() or
1176+
child = this.getBody()
11781177
}
11791178

1180-
predicate lastMatch(AstNode last, Completion c) {
1181-
last(this.getBody(), last, c)
1179+
final override predicate first(AstNode first) {
1180+
first(this.getException(0), first)
11821181
or
1183-
not exists(this.getBody()) and
1182+
not exists(this.getException(0)) and
11841183
(
1185-
last(this.getVariableExpr(), last, c)
1184+
first(this.getVariableExpr(), first)
11861185
or
11871186
not exists(this.getVariableExpr()) and
11881187
(
1189-
last(this.getAnException(), last, c) and
1190-
c.(MatchingCompletion).getValue() = true
1188+
first(this.getBody(), first)
11911189
or
1192-
not exists(this.getAnException()) and
1193-
last = this and
1194-
c.isValidFor(this)
1190+
not exists(this.getBody()) and first = this
11951191
)
11961192
)
11971193
}
11981194

1195+
private Expr getLastException() {
1196+
exists(int i | result = this.getException(i) and not exists(this.getException(i + 1)))
1197+
}
1198+
11991199
predicate lastNoMatch(AstNode last, Completion c) {
12001200
last(this.getLastException(), last, c) and
12011201
c.(MatchingCompletion).getValue() = false
12021202
}
12031203

1204-
final override predicate last(AstNode last, Completion c) {
1205-
this.lastNoMatch(last, c)
1206-
or
1207-
this.lastMatch(last, c)
1208-
}
1209-
12101204
final override predicate succ(AstNode pred, AstNode succ, Completion c) {
1211-
exists(AstNode next |
1212-
pred = this and
1213-
first(next, succ) and
1214-
c instanceof SimpleCompletion
1215-
|
1216-
next = this.getException(0)
1205+
last(this.getAnException(), pred, c) and
1206+
c.(MatchingCompletion).getValue() = true and
1207+
(
1208+
first(this.getVariableExpr(), succ)
12171209
or
1218-
not exists(this.getException(0)) and
1210+
not exists(this.getVariableExpr()) and
12191211
(
1220-
next = this.getVariableExpr()
1212+
first(this.getBody(), succ)
12211213
or
1222-
not exists(this.getVariableExpr()) and
1223-
next = this.getBody()
1214+
not exists(this.getBody()) and succ = this
12241215
)
12251216
)
12261217
or
1227-
exists(AstNode next |
1228-
last(this.getAnException(), pred, c) and
1229-
first(next, succ) and
1230-
c.(MatchingCompletion).getValue() = true
1231-
|
1232-
next = this.getVariableExpr()
1233-
or
1234-
not exists(this.getVariableExpr()) and
1235-
next = this.getBody()
1236-
)
1237-
or
12381218
exists(int i |
12391219
last(this.getException(i), pred, c) and
12401220
c.(MatchingCompletion).getValue() = false and
12411221
first(this.getException(i + 1), succ)
12421222
)
12431223
or
12441224
last(this.getVariableExpr(), pred, c) and
1245-
first(this.getBody(), succ) and
1246-
c instanceof NormalCompletion
1225+
c instanceof NormalCompletion and
1226+
(
1227+
first(this.getBody(), succ)
1228+
or
1229+
not exists(this.getBody()) and succ = this
1230+
)
1231+
or
1232+
last(this.getBody(), pred, c) and
1233+
c instanceof NormalCompletion and
1234+
succ = this
12471235
}
12481236
}
12491237

ruby/ql/test/library-tests/controlflow/graph/Cfg.expected

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -4914,7 +4914,7 @@ raise.rb:
49144914
#-----| true -> self
49154915

49164916
# 17| call to raise
4917-
#-----| raise -> rescue ...
4917+
#-----| raise -> ExceptionA
49184918

49194919
# 17| self
49204920
#-----| -> ExceptionA
@@ -4923,14 +4923,14 @@ raise.rb:
49234923
#-----| -> call to raise
49244924

49254925
# 19| rescue ...
4926-
#-----| -> ExceptionA
4926+
#-----| -> self
49274927

49284928
# 19| ExceptionA
49294929
#-----| match -> self
49304930
#-----| raise -> exit m2 (abnormal)
49314931

49324932
# 19| then ...
4933-
#-----| -> self
4933+
#-----| -> rescue ...
49344934

49354935
# 20| call to puts
49364936
#-----| -> then ...
@@ -4972,7 +4972,7 @@ raise.rb:
49724972
#-----| true -> self
49734973

49744974
# 28| call to raise
4975-
#-----| raise -> rescue ...
4975+
#-----| raise -> self
49764976

49774977
# 28| self
49784978
#-----| -> ExceptionA
@@ -4984,7 +4984,7 @@ raise.rb:
49844984
#-----| -> self
49854985

49864986
# 30| then ...
4987-
#-----| -> self
4987+
#-----| -> rescue ...
49884988

49894989
# 31| call to puts
49904990
#-----| -> then ...
@@ -5026,7 +5026,7 @@ raise.rb:
50265026
#-----| true -> self
50275027

50285028
# 39| call to raise
5029-
#-----| raise -> rescue ...
5029+
#-----| raise -> e
50305030

50315031
# 39| self
50325032
#-----| -> ExceptionA
@@ -5035,13 +5035,13 @@ raise.rb:
50355035
#-----| -> call to raise
50365036

50375037
# 41| rescue ...
5038-
#-----| -> e
5038+
#-----| -> self
50395039

50405040
# 41| e
50415041
#-----| -> self
50425042

50435043
# 41| then ...
5044-
#-----| -> self
5044+
#-----| -> rescue ...
50455045

50465046
# 42| call to puts
50475047
#-----| -> then ...
@@ -5083,7 +5083,7 @@ raise.rb:
50835083
#-----| true -> self
50845084

50855085
# 50| call to raise
5086-
#-----| raise -> rescue ...
5086+
#-----| raise -> e
50875087

50885088
# 50| self
50895089
#-----| -> ExceptionA
@@ -5092,10 +5092,10 @@ raise.rb:
50925092
#-----| -> call to raise
50935093

50945094
# 52| rescue ...
5095-
#-----| -> e
5095+
#-----| -> self
50965096

50975097
# 52| e
5098-
#-----| -> self
5098+
#-----| -> rescue ...
50995099

51005100
# 54| call to puts
51015101
#-----| -> exit m5 (normal)
@@ -5131,7 +5131,7 @@ raise.rb:
51315131
#-----| true -> self
51325132

51335133
# 60| call to raise
5134-
#-----| raise -> rescue ...
5134+
#-----| raise -> ExceptionA
51355135

51365136
# 60| self
51375137
#-----| -> ExceptionA
@@ -5140,7 +5140,7 @@ raise.rb:
51405140
#-----| -> call to raise
51415141

51425142
# 62| rescue ...
5143-
#-----| -> ExceptionA
5143+
#-----| -> self
51445144

51455145
# 62| ExceptionA
51465146
#-----| no-match -> ExceptionB
@@ -5154,7 +5154,7 @@ raise.rb:
51545154
#-----| -> self
51555155

51565156
# 62| then ...
5157-
#-----| -> self
5157+
#-----| -> rescue ...
51585158

51595159
# 63| call to puts
51605160
#-----| -> then ...
@@ -5813,7 +5813,7 @@ raise.rb:
58135813
#-----| true -> self
58145814

58155815
# 131| call to raise
5816-
#-----| raise -> rescue ...
5816+
#-----| raise -> ExceptionA
58175817

58185818
# 131| self
58195819
#-----| -> ExceptionA
@@ -5822,21 +5822,21 @@ raise.rb:
58225822
#-----| -> call to raise
58235823

58245824
# 133| rescue ...
5825-
#-----| -> ExceptionA
5825+
#-----| -> self
58265826

58275827
# 133| ExceptionA
5828-
#-----| no-match -> rescue ...
5829-
#-----| match -> self
5828+
#-----| match -> rescue ...
5829+
#-----| no-match -> ExceptionB
58305830

58315831
# 134| rescue ...
5832-
#-----| -> ExceptionB
5832+
#-----| -> self
58335833

58345834
# 134| ExceptionB
58355835
#-----| match -> self
58365836
#-----| raise -> [ensure: raise] self
58375837

58385838
# 134| then ...
5839-
#-----| -> self
5839+
#-----| -> rescue ...
58405840

58415841
# 135| call to puts
58425842
#-----| -> then ...

0 commit comments

Comments
 (0)