Skip to content

Commit 2ca45ef

Browse files
committed
Ruby: support BlockArgument in identifying access path
1 parent c935509 commit 2ca45ef

File tree

4 files changed

+15
-3
lines changed

4 files changed

+15
-3
lines changed

ruby/ql/lib/codeql/ruby/frameworks/data/internal/ApiGraphModelsSpecific.qll

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,9 @@ API::Node getExtraSuccessorFromNode(API::Node node, AccessPathToken token) {
106106
or
107107
token.getName() = "Instance" and
108108
result = node.getInstance()
109+
or
110+
token.getName() = "BlockArgument" and
111+
result = node.getBlock()
109112
// Note: The "ArrayElement" token is not implemented yet, as it ultimately requires type-tracking and
110113
// API graphs to be aware of the steps involving ArrayElement contributed by the standard library model.
111114
// Type-tracking cannot summarize function calls on its own, so it doesn't benefit from synthesized callables.
@@ -143,15 +146,15 @@ InvokeNode getAnInvocationOf(API::Node node) { result = node }
143146
*/
144147
bindingset[name]
145148
predicate isExtraValidTokenNameInIdentifyingAccessPath(string name) {
146-
name = ["Member", "Method", "Instance", "WithBlock", "WithoutBlock"]
149+
name = ["Member", "Method", "Instance", "WithBlock", "WithoutBlock", "BlockArgument"]
147150
}
148151

149152
/**
150153
* Holds if `name` is a valid name for an access path token with no arguments, occuring
151154
* in an identifying access path.
152155
*/
153156
predicate isExtraValidNoArgumentTokenInIdentifyingAccessPath(string name) {
154-
name = ["Instance", "WithBlock", "WithoutBlock"]
157+
name = ["Instance", "WithBlock", "WithoutBlock", "BlockArgument"]
155158
}
156159

157160
/**

ruby/ql/test/library-tests/dataflow/summaries/Summaries.expected

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ edges
3131
| summaries.rb:41:24:41:24 | t : | summaries.rb:41:8:41:25 | call to matchedByName |
3232
| summaries.rb:42:24:42:24 | t : | summaries.rb:42:8:42:25 | call to matchedByName |
3333
| summaries.rb:44:8:44:8 | t : | summaries.rb:44:8:44:27 | call to matchedByNameRcv |
34+
| summaries.rb:48:24:48:30 | "taint" : | summaries.rb:48:8:48:31 | call to preserveTaint |
3435
nodes
3536
| summaries.rb:1:11:1:26 | call to identity : | semmle.label | call to identity : |
3637
| summaries.rb:1:20:1:26 | "taint" : | semmle.label | "taint" : |
@@ -66,6 +67,8 @@ nodes
6667
| summaries.rb:42:24:42:24 | t : | semmle.label | t : |
6768
| summaries.rb:44:8:44:8 | t : | semmle.label | t : |
6869
| summaries.rb:44:8:44:27 | call to matchedByNameRcv | semmle.label | call to matchedByNameRcv |
70+
| summaries.rb:48:8:48:31 | call to preserveTaint | semmle.label | call to preserveTaint |
71+
| summaries.rb:48:24:48:30 | "taint" : | semmle.label | "taint" : |
6972
subpaths
7073
invalidSpecComponent
7174
invalidOutputSpecComponent
@@ -86,6 +89,7 @@ invalidOutputSpecComponent
8689
| summaries.rb:41:8:41:25 | call to matchedByName | summaries.rb:40:7:40:13 | "taint" : | summaries.rb:41:8:41:25 | call to matchedByName | $@ | summaries.rb:40:7:40:13 | "taint" : | "taint" : |
8790
| summaries.rb:42:8:42:25 | call to matchedByName | summaries.rb:40:7:40:13 | "taint" : | summaries.rb:42:8:42:25 | call to matchedByName | $@ | summaries.rb:40:7:40:13 | "taint" : | "taint" : |
8891
| summaries.rb:44:8:44:27 | call to matchedByNameRcv | summaries.rb:40:7:40:13 | "taint" : | summaries.rb:44:8:44:27 | call to matchedByNameRcv | $@ | summaries.rb:40:7:40:13 | "taint" : | "taint" : |
92+
| summaries.rb:48:8:48:31 | call to preserveTaint | summaries.rb:48:24:48:30 | "taint" : | summaries.rb:48:8:48:31 | call to preserveTaint | $@ | summaries.rb:48:24:48:30 | "taint" : | "taint" : |
8993
warning
9094
| CSV type row should have 5 columns but has 2: test;TooFewColumns |
9195
| CSV type row should have 5 columns but has 8: test;TooManyColumns;;;Member[Foo].Instance;too;many;columns |

ruby/ql/test/library-tests/dataflow/summaries/Summaries.ql

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,9 @@ private class StepsFromModel extends ModelInput::SummaryModelCsv {
7575
";;Member[Foo].Method[secondArg];Argument[1];ReturnValue;taint",
7676
";;Member[Foo].Method[onlyWithoutBlock].WithoutBlock;Argument[0];ReturnValue;taint",
7777
";;Member[Foo].Method[onlyWithBlock].WithBlock;Argument[0];ReturnValue;taint",
78+
";;Member[Foo].Method[blockArg].BlockArgument.Parameter[0].Method[preserveTaint];Argument[0];ReturnValue;taint",
7879
";any;Method[matchedByName];Argument[0];ReturnValue;taint",
79-
";any;Method[matchedByNameRcv];Receiver;ReturnValue;taint"
80+
";any;Method[matchedByNameRcv];Receiver;ReturnValue;taint",
8081
]
8182
}
8283
}

ruby/ql/test/library-tests/dataflow/summaries/summaries.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,3 +43,7 @@ def userDefinedFunction(x, y)
4343
sink(x.unmatchedName(t))
4444
sink(t.matchedByNameRcv())
4545
end
46+
47+
Foo.blockArg do |x|
48+
sink(x.preserveTaint("taint"))
49+
end

0 commit comments

Comments
 (0)