Skip to content

Commit aa24c29

Browse files
authored
Merge pull request github#16122 from hvitved/ruby/cfg-may-raise-issue
Ruby: Fix CFG for nodes that may raise
2 parents b8e6632 + ce3b359 commit aa24c29

File tree

5 files changed

+107
-22
lines changed

5 files changed

+107
-22
lines changed

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

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -90,9 +90,7 @@ private predicate mayRaise(Call c) { c = getARescuableBodyChild() }
9090

9191
/** A completion of a statement or an expression. */
9292
abstract class Completion extends TCompletion {
93-
private predicate isValidForSpecific(AstNode n) {
94-
exists(AstNode other | n = other.getDesugared() and this.isValidForSpecific(other))
95-
or
93+
private predicate isValidForSpecific0(AstNode n) {
9694
this = n.(NonReturningCall).getACompletion()
9795
or
9896
completionIsValidForStmt(n, this)
@@ -110,12 +108,19 @@ abstract class Completion extends TCompletion {
110108
or
111109
n = any(RescueModifierExpr parent).getBody() and
112110
this = [TSimpleCompletion().(TCompletion), TRaiseCompletion()]
111+
}
112+
113+
private predicate isValidForSpecific(AstNode n) {
114+
this.isValidForSpecific0(n)
115+
or
116+
exists(AstNode other | n = other.getDesugared() and this.isValidForSpecific(other))
113117
or
114118
mayRaise(n) and
115119
(
116120
this = TRaiseCompletion()
117121
or
118-
this = TSimpleCompletion() and not n instanceof NonReturningCall
122+
not any(Completion c).isValidForSpecific0(n) and
123+
this = TSimpleCompletion()
119124
)
120125
}
121126

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

Lines changed: 82 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2397,18 +2397,9 @@ cfg.rb:
23972397
# 90| ...
23982398
#-----| -> $global
23992399

2400-
# 90| ... = ...
2401-
#-----| -> if ...
2402-
24032400
# 90| ... = ...
24042401
#-----| -> x
24052402

2406-
# 90| [false] ! ...
2407-
#-----| false -> if ...
2408-
2409-
# 90| [true] ! ...
2410-
#-----| true -> x
2411-
24122403
# 90| __synth__0__1
24132404
#-----| -> x
24142405

@@ -2418,10 +2409,6 @@ cfg.rb:
24182409
# 90| call to each
24192410
#-----| -> ...
24202411

2421-
# 90| defined? ...
2422-
#-----| false -> [true] ! ...
2423-
#-----| true -> [false] ! ...
2424-
24252412
# 90| enter { ... }
24262413
#-----| -> __synth__0__1
24272414

@@ -2430,6 +2417,22 @@ cfg.rb:
24302417
# 90| exit { ... } (normal)
24312418
#-----| -> exit { ... }
24322419

2420+
# 90| { ... }
2421+
#-----| -> call to each
2422+
2423+
# 90| ... = ...
2424+
#-----| -> if ...
2425+
2426+
# 90| [false] ! ...
2427+
#-----| false -> if ...
2428+
2429+
# 90| [true] ! ...
2430+
#-----| true -> x
2431+
2432+
# 90| defined? ...
2433+
#-----| false -> [true] ! ...
2434+
#-----| true -> [false] ! ...
2435+
24332436
# 90| if ...
24342437
#-----| -> Array
24352438

@@ -2442,9 +2445,6 @@ cfg.rb:
24422445
# 90| x
24432446
#-----| -> defined? ...
24442447

2445-
# 90| { ... }
2446-
#-----| -> call to each
2447-
24482448
# 90| x
24492449
#-----| -> __synth__0__1
24502450

@@ -6915,7 +6915,7 @@ raise.rb:
69156915
#-----| -> exit m
69166916

69176917
# 167| m
6918-
#-----| -> exit raise.rb (normal)
6918+
#-----| -> m16
69196919

69206920
# 167| self
69216921
#-----| -> m
@@ -6928,3 +6928,68 @@ raise.rb:
69286928

69296929
# 168| ""
69306930
#-----| -> call to raise
6931+
6932+
# 172| enter m16
6933+
#-----| -> b1
6934+
6935+
# 172| exit m16
6936+
6937+
# 172| exit m16 (abnormal)
6938+
#-----| -> exit m16
6939+
6940+
# 172| exit m16 (normal)
6941+
#-----| -> exit m16
6942+
6943+
# 172| m16
6944+
#-----| -> exit raise.rb (normal)
6945+
6946+
# 172| b1
6947+
#-----| -> b2
6948+
6949+
# 172| b2
6950+
#-----| -> b1
6951+
6952+
# 174| b1
6953+
#-----| true -> [true] ... || ...
6954+
#-----| false -> b2
6955+
6956+
# 174| [false] ... || ...
6957+
#-----| false -> 2
6958+
#-----| raise -> ExceptionA
6959+
6960+
# 174| [true] ... || ...
6961+
#-----| true -> 1
6962+
#-----| raise -> ExceptionA
6963+
6964+
# 174| b2
6965+
#-----| -> true
6966+
6967+
# 174| ... == ...
6968+
#-----| false -> [false] ... || ...
6969+
#-----| true -> [true] ... || ...
6970+
#-----| raise -> ExceptionA
6971+
6972+
# 174| true
6973+
#-----| -> ... == ...
6974+
6975+
# 175| return
6976+
#-----| return -> exit m16 (normal)
6977+
6978+
# 175| 1
6979+
#-----| -> return
6980+
6981+
# 177| return
6982+
#-----| return -> exit m16 (normal)
6983+
6984+
# 177| 2
6985+
#-----| -> return
6986+
6987+
# 179| ExceptionA
6988+
#-----| raise -> exit m16 (abnormal)
6989+
#-----| match -> 3
6990+
6991+
# 180| return
6992+
#-----| return -> exit m16 (normal)
6993+
6994+
# 180| 3
6995+
#-----| -> return

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -367,6 +367,9 @@ positionalArguments
367367
| raise.rb:160:5:162:7 | call to bar | raise.rb:160:9:162:7 | -> { ... } |
368368
| raise.rb:161:7:161:14 | call to raise | raise.rb:161:13:161:14 | "" |
369369
| raise.rb:168:5:168:12 | call to raise | raise.rb:168:11:168:12 | "" |
370+
| raise.rb:174:8:174:23 | [false] ... \|\| ... | raise.rb:174:14:174:23 | ... == ... |
371+
| raise.rb:174:8:174:23 | [true] ... \|\| ... | raise.rb:174:14:174:23 | ... == ... |
372+
| raise.rb:174:14:174:23 | ... == ... | raise.rb:174:20:174:23 | true |
370373
keywordArguments
371374
| cfg.html.erb:6:9:6:58 | call to stylesheet_link_tag | media | cfg.html.erb:6:54:6:58 | "all" |
372375
| cfg.html.erb:12:11:12:33 | call to link_to | id | cfg.html.erb:12:31:12:33 | "a" |

ruby/ql/test/library-tests/controlflow/graph/ifs.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,4 +55,4 @@ def disjunct (b1, b2)
5555
if (b1 || b2) then
5656
puts "b1 or b2"
5757
end
58-
end
58+
end

ruby/ql/test/library-tests/controlflow/graph/raise.rb

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,3 +168,15 @@ def self.m()
168168
raise ""
169169
end
170170
end
171+
172+
def m16(b1, b2)
173+
begin
174+
if b1 || b2 == true
175+
return 1
176+
else
177+
return 2
178+
end
179+
rescue ExceptionA
180+
return 3
181+
end
182+
end

0 commit comments

Comments
 (0)