diff --git a/ql/src/codeql_ruby/controlflow/internal/ControlFlowGraphImpl.qll b/ql/src/codeql_ruby/controlflow/internal/ControlFlowGraphImpl.qll index 5207043e3c7..4cfeba99799 100644 --- a/ql/src/codeql_ruby/controlflow/internal/ControlFlowGraphImpl.qll +++ b/ql/src/codeql_ruby/controlflow/internal/ControlFlowGraphImpl.qll @@ -1223,26 +1223,12 @@ module Trees { } } - private class ConditionalLoopTree extends PreOrderTree, ConditionalLoopAstNode { + private class ConditionalLoopTree extends PostOrderTree, ConditionalLoopAstNode { final override predicate propagatesAbnormal(AstNode child) { child = this.getConditionNode() } - final override predicate last(AstNode last, Completion c) { - last(this.getConditionNode(), last, c) and - this.endLoop(c) - or - last(this.getBodyNode(), last, c) and - not c.continuesLoop() and - not c instanceof BreakCompletion and - not c instanceof RedoCompletion - or - last(this.getBodyNode(), last, c.(NestedBreakCompletion).getAnInnerCompatibleCompletion()) - } + final override predicate first(AstNode first) { first(this.getConditionNode(), first) } final override predicate succ(AstNode pred, AstNode succ, Completion c) { - pred = this and - first(this.getConditionNode(), succ) and - c instanceof SimpleCompletion - or last(this.getConditionNode(), pred, c) and this.continueLoop(c) and first(this.getBodyNode(), succ) @@ -1254,6 +1240,19 @@ module Trees { last(this.getBodyNode(), pred, c) and first(this.getBodyNode(), succ) and c instanceof RedoCompletion + or + succ = this and + ( + last(this.getConditionNode(), pred, c) and + this.endLoop(c) + or + last(this.getBodyNode(), pred, c) and + not c.continuesLoop() and + not c instanceof BreakCompletion and + not c instanceof RedoCompletion + or + last(this.getBodyNode(), pred, c.(NestedBreakCompletion).getAnInnerCompatibleCompletion()) + ) } } } diff --git a/ql/test/library-tests/controlflow/graph/Cfg.expected b/ql/test/library-tests/controlflow/graph/Cfg.expected index 319ae01c0bf..a7e9778436e 100644 --- a/ql/test/library-tests/controlflow/graph/Cfg.expected +++ b/ql/test/library-tests/controlflow/graph/Cfg.expected @@ -683,7 +683,7 @@ cfg.rb: #-----| -> &... # 29| call to new -#-----| -> while ... +#-----| -> true # 29| Proc #-----| -> new @@ -707,13 +707,13 @@ cfg.rb: #-----| -> call to call # 31| while ... -#-----| -> true +#-----| -> false # 31| true #-----| true -> 1 # 32| Break -#-----| break -> false +#-----| break -> while ... # 32| 1 #-----| -> Break @@ -1824,7 +1824,7 @@ cfg.rb: #-----| -> call to puts # 171| ... unless ... -#-----| -> until ... +#-----| -> x # 171| call to puts #-----| -> ... unless ... @@ -1846,11 +1846,11 @@ cfg.rb: #-----| -> ... == ... # 173| until ... -#-----| -> x +#-----| -> 0 # 173| ... > ... +#-----| true -> until ... #-----| false -> x -#-----| true -> 0 # 173| x #-----| -> 10 @@ -1877,7 +1877,7 @@ cfg.rb: #-----| -> call to puts # 175| ... = ... -#-----| -> ... until ... +#-----| -> i # 175| i #-----| -> ... = ... @@ -1886,7 +1886,7 @@ cfg.rb: #-----| -> i # 176| ... until ... -#-----| -> i +#-----| -> 0 # 176| (...; ...) #-----| -> i @@ -1910,8 +1910,8 @@ cfg.rb: #-----| -> ... += ... # 176| ... == ... +#-----| true -> ... until ... #-----| false -> puts -#-----| true -> 0 # 176| i #-----| -> 10 @@ -1920,7 +1920,7 @@ cfg.rb: #-----| -> ... == ... # 178| ... = ... -#-----| -> while ... +#-----| -> x # 178| x #-----| -> ... = ... @@ -1929,11 +1929,11 @@ cfg.rb: #-----| -> x # 179| while ... -#-----| -> x +#-----| -> i # 179| ... < ... +#-----| false -> while ... #-----| true -> x -#-----| false -> ... while ... # 179| x #-----| -> 10 @@ -1976,7 +1976,7 @@ cfg.rb: #-----| -> call to puts # 185| ... while ... -#-----| -> i +#-----| -> run_block # 185| (...; ...) #-----| -> i @@ -2000,8 +2000,8 @@ cfg.rb: #-----| -> ... -= ... # 185| ... != ... +#-----| false -> ... while ... #-----| true -> puts -#-----| false -> run_block # 185| i #-----| -> 0 @@ -2523,14 +2523,14 @@ loops.rb: #-----| -> m1 # 1| x -#-----| -> while ... - -# 2| while ... #-----| -> x +# 2| while ... +#-----| -> exit m1 (normal) + # 2| ... >= ... +#-----| false -> while ... #-----| true -> puts -#-----| false -> exit m1 (normal) # 2| x #-----| -> 0 @@ -2563,14 +2563,14 @@ loops.rb: #-----| -> m2 # 8| x -#-----| -> while ... - -# 9| while ... #-----| -> x +# 9| while ... +#-----| -> puts + # 9| ... >= ... +#-----| false -> while ... #-----| true -> puts -#-----| false -> puts # 9| x #-----| -> 0 @@ -2610,7 +2610,7 @@ loops.rb: #-----| -> ... > ... # 13| Break -#-----| break -> puts +#-----| break -> while ... # 14| elsif ... #-----| -> if ...