Skip to content

Commit 4e88b84

Browse files
committed
Ruby: add flow summary for Enumerable#index_with
1 parent dc440aa commit 4e88b84

File tree

3 files changed

+114
-1
lines changed

3 files changed

+114
-1
lines changed

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

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -294,7 +294,21 @@ module ActiveSupport {
294294
preservesValue = true
295295
}
296296
}
297-
// TODO: index_with, pick, pluck (they require Hash dataflow)
297+
298+
private class IndexWithSummary extends SimpleSummarizedCallable {
299+
IndexWithSummary() { this = "index_with" }
300+
301+
override predicate propagatesFlowExt(string input, string output, boolean preservesValue) {
302+
input = "Argument[self].Element[any]" and
303+
output = "Argument[block].Parameter[0]" and
304+
preservesValue = true
305+
or
306+
input = ["Argument[0]", "Argument[block].ReturnValue"] and
307+
output = "ReturnValue.Element[?]" and
308+
preservesValue = true
309+
}
310+
}
311+
// TODO: pick, pluck (they require Hash dataflow)
298312
}
299313
}
300314

ruby/ql/test/library-tests/frameworks/active_support/ActiveSupportDataFlow.expected

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,40 @@ edges
286286
| hash_extensions.rb:73:10:73:10 | h [element] : | hash_extensions.rb:73:10:73:16 | ...[...] |
287287
| hash_extensions.rb:74:10:74:10 | h [element] : | hash_extensions.rb:74:10:74:16 | ...[...] |
288288
| hash_extensions.rb:74:10:74:10 | h [element] : | hash_extensions.rb:74:10:74:16 | ...[...] |
289+
| hash_extensions.rb:80:15:80:25 | call to source : | hash_extensions.rb:81:9:81:14 | values [element 0] : |
290+
| hash_extensions.rb:80:15:80:25 | call to source : | hash_extensions.rb:81:9:81:14 | values [element 0] : |
291+
| hash_extensions.rb:80:28:80:38 | call to source : | hash_extensions.rb:81:9:81:14 | values [element 1] : |
292+
| hash_extensions.rb:80:28:80:38 | call to source : | hash_extensions.rb:81:9:81:14 | values [element 1] : |
293+
| hash_extensions.rb:80:41:80:51 | call to source : | hash_extensions.rb:81:9:81:14 | values [element 2] : |
294+
| hash_extensions.rb:80:41:80:51 | call to source : | hash_extensions.rb:81:9:81:14 | values [element 2] : |
295+
| hash_extensions.rb:81:9:81:14 | values [element 0] : | hash_extensions.rb:81:31:81:33 | key : |
296+
| hash_extensions.rb:81:9:81:14 | values [element 0] : | hash_extensions.rb:81:31:81:33 | key : |
297+
| hash_extensions.rb:81:9:81:14 | values [element 1] : | hash_extensions.rb:81:31:81:33 | key : |
298+
| hash_extensions.rb:81:9:81:14 | values [element 1] : | hash_extensions.rb:81:31:81:33 | key : |
299+
| hash_extensions.rb:81:9:81:14 | values [element 2] : | hash_extensions.rb:81:31:81:33 | key : |
300+
| hash_extensions.rb:81:9:81:14 | values [element 2] : | hash_extensions.rb:81:31:81:33 | key : |
301+
| hash_extensions.rb:81:9:84:7 | call to index_with [element] : | hash_extensions.rb:86:10:86:10 | h [element] : |
302+
| hash_extensions.rb:81:9:84:7 | call to index_with [element] : | hash_extensions.rb:86:10:86:10 | h [element] : |
303+
| hash_extensions.rb:81:9:84:7 | call to index_with [element] : | hash_extensions.rb:87:10:87:10 | h [element] : |
304+
| hash_extensions.rb:81:9:84:7 | call to index_with [element] : | hash_extensions.rb:87:10:87:10 | h [element] : |
305+
| hash_extensions.rb:81:31:81:33 | key : | hash_extensions.rb:82:14:82:16 | key |
306+
| hash_extensions.rb:81:31:81:33 | key : | hash_extensions.rb:82:14:82:16 | key |
307+
| hash_extensions.rb:83:9:83:19 | call to source : | hash_extensions.rb:81:9:84:7 | call to index_with [element] : |
308+
| hash_extensions.rb:83:9:83:19 | call to source : | hash_extensions.rb:81:9:84:7 | call to index_with [element] : |
309+
| hash_extensions.rb:86:10:86:10 | h [element] : | hash_extensions.rb:86:10:86:16 | ...[...] |
310+
| hash_extensions.rb:86:10:86:10 | h [element] : | hash_extensions.rb:86:10:86:16 | ...[...] |
311+
| hash_extensions.rb:87:10:87:10 | h [element] : | hash_extensions.rb:87:10:87:16 | ...[...] |
312+
| hash_extensions.rb:87:10:87:10 | h [element] : | hash_extensions.rb:87:10:87:16 | ...[...] |
313+
| hash_extensions.rb:89:9:89:38 | call to index_with [element] : | hash_extensions.rb:91:10:91:10 | j [element] : |
314+
| hash_extensions.rb:89:9:89:38 | call to index_with [element] : | hash_extensions.rb:91:10:91:10 | j [element] : |
315+
| hash_extensions.rb:89:9:89:38 | call to index_with [element] : | hash_extensions.rb:92:10:92:10 | j [element] : |
316+
| hash_extensions.rb:89:9:89:38 | call to index_with [element] : | hash_extensions.rb:92:10:92:10 | j [element] : |
317+
| hash_extensions.rb:89:27:89:37 | call to source : | hash_extensions.rb:89:9:89:38 | call to index_with [element] : |
318+
| hash_extensions.rb:89:27:89:37 | call to source : | hash_extensions.rb:89:9:89:38 | call to index_with [element] : |
319+
| hash_extensions.rb:91:10:91:10 | j [element] : | hash_extensions.rb:91:10:91:16 | ...[...] |
320+
| hash_extensions.rb:91:10:91:10 | j [element] : | hash_extensions.rb:91:10:91:16 | ...[...] |
321+
| hash_extensions.rb:92:10:92:10 | j [element] : | hash_extensions.rb:92:10:92:16 | ...[...] |
322+
| hash_extensions.rb:92:10:92:10 | j [element] : | hash_extensions.rb:92:10:92:16 | ...[...] |
289323
nodes
290324
| active_support.rb:10:9:10:18 | call to source : | semmle.label | call to source : |
291325
| active_support.rb:11:10:11:10 | x : | semmle.label | x : |
@@ -648,6 +682,46 @@ nodes
648682
| hash_extensions.rb:74:10:74:10 | h [element] : | semmle.label | h [element] : |
649683
| hash_extensions.rb:74:10:74:16 | ...[...] | semmle.label | ...[...] |
650684
| hash_extensions.rb:74:10:74:16 | ...[...] | semmle.label | ...[...] |
685+
| hash_extensions.rb:80:15:80:25 | call to source : | semmle.label | call to source : |
686+
| hash_extensions.rb:80:15:80:25 | call to source : | semmle.label | call to source : |
687+
| hash_extensions.rb:80:28:80:38 | call to source : | semmle.label | call to source : |
688+
| hash_extensions.rb:80:28:80:38 | call to source : | semmle.label | call to source : |
689+
| hash_extensions.rb:80:41:80:51 | call to source : | semmle.label | call to source : |
690+
| hash_extensions.rb:80:41:80:51 | call to source : | semmle.label | call to source : |
691+
| hash_extensions.rb:81:9:81:14 | values [element 0] : | semmle.label | values [element 0] : |
692+
| hash_extensions.rb:81:9:81:14 | values [element 0] : | semmle.label | values [element 0] : |
693+
| hash_extensions.rb:81:9:81:14 | values [element 1] : | semmle.label | values [element 1] : |
694+
| hash_extensions.rb:81:9:81:14 | values [element 1] : | semmle.label | values [element 1] : |
695+
| hash_extensions.rb:81:9:81:14 | values [element 2] : | semmle.label | values [element 2] : |
696+
| hash_extensions.rb:81:9:81:14 | values [element 2] : | semmle.label | values [element 2] : |
697+
| hash_extensions.rb:81:9:84:7 | call to index_with [element] : | semmle.label | call to index_with [element] : |
698+
| hash_extensions.rb:81:9:84:7 | call to index_with [element] : | semmle.label | call to index_with [element] : |
699+
| hash_extensions.rb:81:31:81:33 | key : | semmle.label | key : |
700+
| hash_extensions.rb:81:31:81:33 | key : | semmle.label | key : |
701+
| hash_extensions.rb:82:14:82:16 | key | semmle.label | key |
702+
| hash_extensions.rb:82:14:82:16 | key | semmle.label | key |
703+
| hash_extensions.rb:83:9:83:19 | call to source : | semmle.label | call to source : |
704+
| hash_extensions.rb:83:9:83:19 | call to source : | semmle.label | call to source : |
705+
| hash_extensions.rb:86:10:86:10 | h [element] : | semmle.label | h [element] : |
706+
| hash_extensions.rb:86:10:86:10 | h [element] : | semmle.label | h [element] : |
707+
| hash_extensions.rb:86:10:86:16 | ...[...] | semmle.label | ...[...] |
708+
| hash_extensions.rb:86:10:86:16 | ...[...] | semmle.label | ...[...] |
709+
| hash_extensions.rb:87:10:87:10 | h [element] : | semmle.label | h [element] : |
710+
| hash_extensions.rb:87:10:87:10 | h [element] : | semmle.label | h [element] : |
711+
| hash_extensions.rb:87:10:87:16 | ...[...] | semmle.label | ...[...] |
712+
| hash_extensions.rb:87:10:87:16 | ...[...] | semmle.label | ...[...] |
713+
| hash_extensions.rb:89:9:89:38 | call to index_with [element] : | semmle.label | call to index_with [element] : |
714+
| hash_extensions.rb:89:9:89:38 | call to index_with [element] : | semmle.label | call to index_with [element] : |
715+
| hash_extensions.rb:89:27:89:37 | call to source : | semmle.label | call to source : |
716+
| hash_extensions.rb:89:27:89:37 | call to source : | semmle.label | call to source : |
717+
| hash_extensions.rb:91:10:91:10 | j [element] : | semmle.label | j [element] : |
718+
| hash_extensions.rb:91:10:91:10 | j [element] : | semmle.label | j [element] : |
719+
| hash_extensions.rb:91:10:91:16 | ...[...] | semmle.label | ...[...] |
720+
| hash_extensions.rb:91:10:91:16 | ...[...] | semmle.label | ...[...] |
721+
| hash_extensions.rb:92:10:92:10 | j [element] : | semmle.label | j [element] : |
722+
| hash_extensions.rb:92:10:92:10 | j [element] : | semmle.label | j [element] : |
723+
| hash_extensions.rb:92:10:92:16 | ...[...] | semmle.label | ...[...] |
724+
| hash_extensions.rb:92:10:92:16 | ...[...] | semmle.label | ...[...] |
651725
subpaths
652726
#select
653727
| active_support.rb:182:10:182:13 | ...[...] | active_support.rb:180:10:180:17 | call to source : | active_support.rb:182:10:182:13 | ...[...] | $@ | active_support.rb:180:10:180:17 | call to source : | call to source : |
@@ -685,3 +759,10 @@ subpaths
685759
| hash_extensions.rb:74:10:74:16 | ...[...] | hash_extensions.rb:67:15:67:25 | call to source : | hash_extensions.rb:74:10:74:16 | ...[...] | $@ | hash_extensions.rb:67:15:67:25 | call to source : | call to source : |
686760
| hash_extensions.rb:74:10:74:16 | ...[...] | hash_extensions.rb:67:28:67:38 | call to source : | hash_extensions.rb:74:10:74:16 | ...[...] | $@ | hash_extensions.rb:67:28:67:38 | call to source : | call to source : |
687761
| hash_extensions.rb:74:10:74:16 | ...[...] | hash_extensions.rb:67:41:67:51 | call to source : | hash_extensions.rb:74:10:74:16 | ...[...] | $@ | hash_extensions.rb:67:41:67:51 | call to source : | call to source : |
762+
| hash_extensions.rb:82:14:82:16 | key | hash_extensions.rb:80:15:80:25 | call to source : | hash_extensions.rb:82:14:82:16 | key | $@ | hash_extensions.rb:80:15:80:25 | call to source : | call to source : |
763+
| hash_extensions.rb:82:14:82:16 | key | hash_extensions.rb:80:28:80:38 | call to source : | hash_extensions.rb:82:14:82:16 | key | $@ | hash_extensions.rb:80:28:80:38 | call to source : | call to source : |
764+
| hash_extensions.rb:82:14:82:16 | key | hash_extensions.rb:80:41:80:51 | call to source : | hash_extensions.rb:82:14:82:16 | key | $@ | hash_extensions.rb:80:41:80:51 | call to source : | call to source : |
765+
| hash_extensions.rb:86:10:86:16 | ...[...] | hash_extensions.rb:83:9:83:19 | call to source : | hash_extensions.rb:86:10:86:16 | ...[...] | $@ | hash_extensions.rb:83:9:83:19 | call to source : | call to source : |
766+
| hash_extensions.rb:87:10:87:16 | ...[...] | hash_extensions.rb:83:9:83:19 | call to source : | hash_extensions.rb:87:10:87:16 | ...[...] | $@ | hash_extensions.rb:83:9:83:19 | call to source : | call to source : |
767+
| hash_extensions.rb:91:10:91:16 | ...[...] | hash_extensions.rb:89:27:89:37 | call to source : | hash_extensions.rb:91:10:91:16 | ...[...] | $@ | hash_extensions.rb:89:27:89:37 | call to source : | call to source : |
768+
| hash_extensions.rb:92:10:92:16 | ...[...] | hash_extensions.rb:89:27:89:37 | call to source : | hash_extensions.rb:92:10:92:16 | ...[...] | $@ | hash_extensions.rb:89:27:89:37 | call to source : | call to source : |

ruby/ql/test/library-tests/frameworks/active_support/hash_extensions.rb

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,3 +75,21 @@ def m_index_by
7575
end
7676

7777
m_index_by()
78+
79+
def m_index_with
80+
values = [source("a"), source("b"), source("c")]
81+
h = values.index_with do |key|
82+
sink key # $ hasValueFlow=a $ hasValueFlow=b $ hasValueFlow=c
83+
source("x")
84+
end
85+
86+
sink h[:foo] # $ hasValueFlow=x
87+
sink h[:bar] # $ hasValueFlow=x
88+
89+
j = values.index_with(source("y"))
90+
91+
sink j[:foo] # $ hasValueFlow=y
92+
sink j[:bar] # $ hasValueFlow=y
93+
end
94+
95+
m_index_with()

0 commit comments

Comments
 (0)