Skip to content

Commit d55925d

Browse files
committed
Ruby: support splat type-tracking step
1 parent 9bbbece commit d55925d

File tree

3 files changed

+15
-6
lines changed

3 files changed

+15
-6
lines changed

ruby/ql/lib/codeql/ruby/frameworks/Core.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ class SubshellHeredocExecution extends SystemCommandExecution::Range {
5858
private class SplatSummary extends SummarizedCallable {
5959
SplatSummary() { this = "*(splat)" }
6060

61-
override SplatExpr getACall() { any() }
61+
override SplatExpr getACallSimple() { any() }
6262

6363
override predicate propagatesFlowExt(string input, string output, boolean preservesValue) {
6464
(

ruby/ql/lib/codeql/ruby/typetracking/TypeTrackerSpecific.qll

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -325,9 +325,18 @@ private predicate hasStoreSummary(
325325
SummarizedCallable callable, DataFlow::ContentSet contents, SummaryComponentStack input,
326326
SummaryComponentStack output
327327
) {
328-
callable.propagatesFlow(input, push(SummaryComponent::content(contents), output), true) and
329328
not isNonLocal(input.head()) and
330-
not isNonLocal(output.head())
329+
not isNonLocal(output.head()) and
330+
(
331+
callable.propagatesFlow(input, push(SummaryComponent::content(contents), output), true)
332+
or
333+
// Allow the input to start with an arbitrary WithoutContent[X].
334+
// Since type-tracking only tracks one content deep, and we're about to store into another content,
335+
// we're already preventing the input from being in a content.
336+
callable
337+
.propagatesFlow(push(SummaryComponent::withoutContent(_), input),
338+
push(SummaryComponent::content(contents), output), true)
339+
)
331340
}
332341

333342
pragma[nomagic]
@@ -460,6 +469,9 @@ private predicate dependsOnSummaryComponentStack(
460469
callable.propagatesFlow(stack, _, true)
461470
or
462471
callable.propagatesFlow(_, stack, true)
472+
or
473+
// include store summaries as they may skip an initial step at the input
474+
hasStoreSummary(callable, _, stack, _)
463475
)
464476
or
465477
dependsOnSummaryComponentStackCons(callable, _, stack)

ruby/ql/test/library-tests/dataflow/array-flow/type-tracking-array-flow.expected

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
| array_flow.rb:3:16:3:35 | # $ hasValueFlow=0.1 | Missing result:hasValueFlow=0.1 |
2-
| array_flow.rb:5:16:5:35 | # $ hasValueFlow=0.1 | Missing result:hasValueFlow=0.1 |
3-
| array_flow.rb:83:13:83:30 | # $ hasValueFlow=9 | Missing result:hasValueFlow=9 |
41
| array_flow.rb:107:10:107:13 | ...[...] | Unexpected result: hasValueFlow=11.2 |
52
| array_flow.rb:179:28:179:46 | # $ hasValueFlow=19 | Missing result:hasValueFlow=19 |
63
| array_flow.rb:180:28:180:46 | # $ hasValueFlow=19 | Missing result:hasValueFlow=19 |

0 commit comments

Comments
 (0)