Skip to content

Commit 6509c19

Browse files
authored
Merge pull request #10692 from aibaars/fix-splats
Ruby: fix CFG and toString for anonymous '*' and '**'
2 parents 5984b8d + a080f49 commit 6509c19

File tree

5 files changed

+71
-3
lines changed

5 files changed

+71
-3
lines changed

ruby/ql/lib/codeql/ruby/ast/Parameter.qll

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,11 @@ class HashSplatParameter extends NamedParameter, THashSplatParameter {
183183

184184
final override LocalVariable getVariable() { result = TLocalVariableReal(_, _, g.getName()) }
185185

186-
final override string toString() { result = "**" + this.getName() }
186+
final override string toString() {
187+
result = "**" + this.getName()
188+
or
189+
not exists(g.getName()) and result = "**"
190+
}
187191

188192
final override string getName() { result = g.getName().getValue() }
189193
}
@@ -305,7 +309,11 @@ class SplatParameter extends NamedParameter, TSplatParameter {
305309

306310
final override LocalVariable getVariable() { result = TLocalVariableReal(_, _, g.getName()) }
307311

308-
final override string toString() { result = "*" + this.getName() }
312+
final override string toString() {
313+
result = "*" + this.getName()
314+
or
315+
not exists(g.getName()) and result = "*"
316+
}
309317

310318
final override string getName() { result = g.getName().getValue() }
311319
}

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,10 +139,16 @@ module Trees {
139139
abstract private class NonDefaultValueParameterTree extends ControlFlowTree, NamedParameter {
140140
final override predicate first(AstNode first) {
141141
this.getDefiningAccess().(ControlFlowTree).first(first)
142+
or
143+
not exists(this.getDefiningAccess()) and first = this
142144
}
143145

144146
final override predicate last(AstNode last, Completion c) {
145147
this.getDefiningAccess().(ControlFlowTree).last(last, c)
148+
or
149+
not exists(this.getDefiningAccess()) and
150+
last = this and
151+
c.isValidFor(this)
146152
}
147153

148154
override predicate propagatesAbnormal(AstNode child) {

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

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3649,7 +3649,7 @@ cfg.rb:
36493649
#-----| -> call to foo
36503650

36513651
# 205| ...
3652-
#-----| -> exit cfg.rb (normal)
3652+
#-----| -> filter_nil
36533653

36543654
# 205| call to bar
36553655
#-----| -> if ...
@@ -3687,6 +3687,52 @@ cfg.rb:
36873687
# 205| x
36883688
#-----| -> exit { ... } (normal)
36893689

3690+
# 207| enter filter_nil
3691+
#-----| -> list
3692+
3693+
# 207| exit filter_nil
3694+
3695+
# 207| exit filter_nil (normal)
3696+
#-----| -> exit filter_nil
3697+
3698+
# 207| filter_nil
3699+
#-----| -> exit cfg.rb (normal)
3700+
3701+
# 207| list
3702+
#-----| -> list
3703+
3704+
# 208| list
3705+
#-----| -> do ... end
3706+
3707+
# 208| call to reject
3708+
#-----| -> exit filter_nil (normal)
3709+
3710+
# 208| do ... end
3711+
#-----| -> call to reject
3712+
3713+
# 208| enter do ... end
3714+
#-----| -> elem
3715+
3716+
# 208| exit do ... end
3717+
3718+
# 208| exit do ... end (normal)
3719+
#-----| -> exit do ... end
3720+
3721+
# 208| elem
3722+
#-----| -> *
3723+
3724+
# 208| *
3725+
#-----| -> **
3726+
3727+
# 208| **
3728+
#-----| -> elem
3729+
3730+
# 209| elem
3731+
#-----| -> call to nil?
3732+
3733+
# 209| call to nil?
3734+
#-----| -> exit do ... end (normal)
3735+
36903736
desugar.rb:
36913737
# 1| enter m1
36923738
#-----| -> x

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ callsWithNoArguments
4242
| cfg.rb:200:1:200:32 | call to times |
4343
| cfg.rb:202:1:202:35 | call to times |
4444
| cfg.rb:205:1:205:3 | call to foo |
45+
| cfg.rb:208:3:210:5 | call to reject |
46+
| cfg.rb:209:5:209:13 | call to nil? |
4547
| desugar.rb:6:3:6:7 | call to foo |
4648
| desugar.rb:10:3:10:7 | call to foo |
4749
| desugar.rb:14:3:14:7 | call to foo |

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,12 @@ def forward_param(a, b, ...)
204204
# A call with a safe navigation operator
205205
foo&.bar(1,2) { |x| x }
206206

207+
def filter_nil list
208+
list.reject do |elem, *, **|
209+
elem.nil?
210+
end
211+
end
212+
207213
__END__
208214

209215
Some ignored nonsense

0 commit comments

Comments
 (0)