Skip to content

Commit 8d854e0

Browse files
authored
Merge pull request github#11252 from github/nickrolfe/active_support_enumerable
Ruby: add flow summary for Enumerable#index_by
2 parents d285700 + c80fbff commit 8d854e0

File tree

4 files changed

+91
-1
lines changed

4 files changed

+91
-1
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
category: minorAnalysis
3+
---
4+
* Data flow through the `ActiveSupport` extension `Enumerable#index_by` is now modeled.

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

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -284,7 +284,17 @@ module ActiveSupport {
284284
preservesValue = true
285285
}
286286
}
287-
// TODO: index_by, index_with, pick, pluck (they require Hash dataflow)
287+
288+
private class IndexBySummary extends SimpleSummarizedCallable {
289+
IndexBySummary() { this = "index_by" }
290+
291+
override predicate propagatesFlowExt(string input, string output, boolean preservesValue) {
292+
input = "Argument[self].Element[any]" and
293+
output = ["Argument[block].Parameter[0]", "ReturnValue.Element[?]"] and
294+
preservesValue = true
295+
}
296+
}
297+
// TODO: index_with, pick, pluck (they require Hash dataflow)
288298
}
289299
}
290300

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

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,34 @@ edges
258258
| hash_extensions.rb:58:10:58:10 | x [element :a] : | hash_extensions.rb:58:10:58:14 | ...[...] |
259259
| hash_extensions.rb:59:10:59:10 | x [element :b] : | hash_extensions.rb:59:10:59:14 | ...[...] |
260260
| hash_extensions.rb:59:10:59:10 | x [element :b] : | hash_extensions.rb:59:10:59:14 | ...[...] |
261+
| hash_extensions.rb:67:15:67:25 | call to source : | hash_extensions.rb:68:9:68:14 | values [element 0] : |
262+
| hash_extensions.rb:67:15:67:25 | call to source : | hash_extensions.rb:68:9:68:14 | values [element 0] : |
263+
| hash_extensions.rb:67:28:67:38 | call to source : | hash_extensions.rb:68:9:68:14 | values [element 1] : |
264+
| hash_extensions.rb:67:28:67:38 | call to source : | hash_extensions.rb:68:9:68:14 | values [element 1] : |
265+
| hash_extensions.rb:67:41:67:51 | call to source : | hash_extensions.rb:68:9:68:14 | values [element 2] : |
266+
| hash_extensions.rb:67:41:67:51 | call to source : | hash_extensions.rb:68:9:68:14 | values [element 2] : |
267+
| hash_extensions.rb:68:9:68:14 | values [element 0] : | hash_extensions.rb:68:9:71:7 | call to index_by [element] : |
268+
| hash_extensions.rb:68:9:68:14 | values [element 0] : | hash_extensions.rb:68:9:71:7 | call to index_by [element] : |
269+
| hash_extensions.rb:68:9:68:14 | values [element 0] : | hash_extensions.rb:68:29:68:33 | value : |
270+
| hash_extensions.rb:68:9:68:14 | values [element 0] : | hash_extensions.rb:68:29:68:33 | value : |
271+
| hash_extensions.rb:68:9:68:14 | values [element 1] : | hash_extensions.rb:68:9:71:7 | call to index_by [element] : |
272+
| hash_extensions.rb:68:9:68:14 | values [element 1] : | hash_extensions.rb:68:9:71:7 | call to index_by [element] : |
273+
| hash_extensions.rb:68:9:68:14 | values [element 1] : | hash_extensions.rb:68:29:68:33 | value : |
274+
| hash_extensions.rb:68:9:68:14 | values [element 1] : | hash_extensions.rb:68:29:68:33 | value : |
275+
| hash_extensions.rb:68:9:68:14 | values [element 2] : | hash_extensions.rb:68:9:71:7 | call to index_by [element] : |
276+
| hash_extensions.rb:68:9:68:14 | values [element 2] : | hash_extensions.rb:68:9:71:7 | call to index_by [element] : |
277+
| hash_extensions.rb:68:9:68:14 | values [element 2] : | hash_extensions.rb:68:29:68:33 | value : |
278+
| hash_extensions.rb:68:9:68:14 | values [element 2] : | hash_extensions.rb:68:29:68:33 | value : |
279+
| hash_extensions.rb:68:9:71:7 | call to index_by [element] : | hash_extensions.rb:73:10:73:10 | h [element] : |
280+
| hash_extensions.rb:68:9:71:7 | call to index_by [element] : | hash_extensions.rb:73:10:73:10 | h [element] : |
281+
| hash_extensions.rb:68:9:71:7 | call to index_by [element] : | hash_extensions.rb:74:10:74:10 | h [element] : |
282+
| hash_extensions.rb:68:9:71:7 | call to index_by [element] : | hash_extensions.rb:74:10:74:10 | h [element] : |
283+
| hash_extensions.rb:68:29:68:33 | value : | hash_extensions.rb:69:14:69:18 | value |
284+
| hash_extensions.rb:68:29:68:33 | value : | hash_extensions.rb:69:14:69:18 | value |
285+
| hash_extensions.rb:73:10:73:10 | h [element] : | hash_extensions.rb:73:10:73:16 | ...[...] |
286+
| hash_extensions.rb:73:10:73:10 | h [element] : | hash_extensions.rb:73:10:73:16 | ...[...] |
287+
| hash_extensions.rb:74:10:74:10 | h [element] : | hash_extensions.rb:74:10:74:16 | ...[...] |
288+
| hash_extensions.rb:74:10:74:10 | h [element] : | hash_extensions.rb:74:10:74:16 | ...[...] |
261289
nodes
262290
| active_support.rb:10:9:10:18 | call to source : | semmle.label | call to source : |
263291
| active_support.rb:11:10:11:10 | x : | semmle.label | x : |
@@ -594,6 +622,32 @@ nodes
594622
| hash_extensions.rb:59:10:59:10 | x [element :b] : | semmle.label | x [element :b] : |
595623
| hash_extensions.rb:59:10:59:14 | ...[...] | semmle.label | ...[...] |
596624
| hash_extensions.rb:59:10:59:14 | ...[...] | semmle.label | ...[...] |
625+
| hash_extensions.rb:67:15:67:25 | call to source : | semmle.label | call to source : |
626+
| hash_extensions.rb:67:15:67:25 | call to source : | semmle.label | call to source : |
627+
| hash_extensions.rb:67:28:67:38 | call to source : | semmle.label | call to source : |
628+
| hash_extensions.rb:67:28:67:38 | call to source : | semmle.label | call to source : |
629+
| hash_extensions.rb:67:41:67:51 | call to source : | semmle.label | call to source : |
630+
| hash_extensions.rb:67:41:67:51 | call to source : | semmle.label | call to source : |
631+
| hash_extensions.rb:68:9:68:14 | values [element 0] : | semmle.label | values [element 0] : |
632+
| hash_extensions.rb:68:9:68:14 | values [element 0] : | semmle.label | values [element 0] : |
633+
| hash_extensions.rb:68:9:68:14 | values [element 1] : | semmle.label | values [element 1] : |
634+
| hash_extensions.rb:68:9:68:14 | values [element 1] : | semmle.label | values [element 1] : |
635+
| hash_extensions.rb:68:9:68:14 | values [element 2] : | semmle.label | values [element 2] : |
636+
| hash_extensions.rb:68:9:68:14 | values [element 2] : | semmle.label | values [element 2] : |
637+
| hash_extensions.rb:68:9:71:7 | call to index_by [element] : | semmle.label | call to index_by [element] : |
638+
| hash_extensions.rb:68:9:71:7 | call to index_by [element] : | semmle.label | call to index_by [element] : |
639+
| hash_extensions.rb:68:29:68:33 | value : | semmle.label | value : |
640+
| hash_extensions.rb:68:29:68:33 | value : | semmle.label | value : |
641+
| hash_extensions.rb:69:14:69:18 | value | semmle.label | value |
642+
| hash_extensions.rb:69:14:69:18 | value | semmle.label | value |
643+
| hash_extensions.rb:73:10:73:10 | h [element] : | semmle.label | h [element] : |
644+
| hash_extensions.rb:73:10:73:10 | h [element] : | semmle.label | h [element] : |
645+
| hash_extensions.rb:73:10:73:16 | ...[...] | semmle.label | ...[...] |
646+
| hash_extensions.rb:73:10:73:16 | ...[...] | semmle.label | ...[...] |
647+
| hash_extensions.rb:74:10:74:10 | h [element] : | semmle.label | h [element] : |
648+
| hash_extensions.rb:74:10:74:10 | h [element] : | semmle.label | h [element] : |
649+
| hash_extensions.rb:74:10:74:16 | ...[...] | semmle.label | ...[...] |
650+
| hash_extensions.rb:74:10:74:16 | ...[...] | semmle.label | ...[...] |
597651
subpaths
598652
#select
599653
| 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 : |
@@ -622,3 +676,12 @@ subpaths
622676
| hash_extensions.rb:56:10:56:14 | ...[...] | hash_extensions.rb:50:52:50:61 | call to taint : | hash_extensions.rb:56:10:56:14 | ...[...] | $@ | hash_extensions.rb:50:52:50:61 | call to taint : | call to taint : |
623677
| hash_extensions.rb:58:10:58:14 | ...[...] | hash_extensions.rb:50:14:50:23 | call to taint : | hash_extensions.rb:58:10:58:14 | ...[...] | $@ | hash_extensions.rb:50:14:50:23 | call to taint : | call to taint : |
624678
| hash_extensions.rb:59:10:59:14 | ...[...] | hash_extensions.rb:50:29:50:38 | call to taint : | hash_extensions.rb:59:10:59:14 | ...[...] | $@ | hash_extensions.rb:50:29:50:38 | call to taint : | call to taint : |
679+
| hash_extensions.rb:69:14:69:18 | value | hash_extensions.rb:67:15:67:25 | call to source : | hash_extensions.rb:69:14:69:18 | value | $@ | hash_extensions.rb:67:15:67:25 | call to source : | call to source : |
680+
| hash_extensions.rb:69:14:69:18 | value | hash_extensions.rb:67:28:67:38 | call to source : | hash_extensions.rb:69:14:69:18 | value | $@ | hash_extensions.rb:67:28:67:38 | call to source : | call to source : |
681+
| hash_extensions.rb:69:14:69:18 | value | hash_extensions.rb:67:41:67:51 | call to source : | hash_extensions.rb:69:14:69:18 | value | $@ | hash_extensions.rb:67:41:67:51 | call to source : | call to source : |
682+
| hash_extensions.rb:73:10:73:16 | ...[...] | hash_extensions.rb:67:15:67:25 | call to source : | hash_extensions.rb:73:10:73:16 | ...[...] | $@ | hash_extensions.rb:67:15:67:25 | call to source : | call to source : |
683+
| hash_extensions.rb:73:10:73:16 | ...[...] | hash_extensions.rb:67:28:67:38 | call to source : | hash_extensions.rb:73:10:73:16 | ...[...] | $@ | hash_extensions.rb:67:28:67:38 | call to source : | call to source : |
684+
| hash_extensions.rb:73:10:73:16 | ...[...] | hash_extensions.rb:67:41:67:51 | call to source : | hash_extensions.rb:73:10:73:16 | ...[...] | $@ | hash_extensions.rb:67:41:67:51 | call to source : | call to source : |
685+
| 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 : |
686+
| 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 : |
687+
| 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 : |

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

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,3 +62,16 @@ def m_extract!(x)
6262
end
6363

6464
m_extract!(:c)
65+
66+
def m_index_by
67+
values = [source("a"), source("b"), source("c")]
68+
h = values.index_by do |value|
69+
sink value # $ hasValueFlow=a $ hasValueFlow=b $ hasValueFlow=c
70+
make_key(value)
71+
end
72+
73+
sink h[:foo] # $ hasValueFlow=a $ hasValueFlow=b $ hasValueFlow=c
74+
sink h[:bar] # $ hasValueFlow=a $ hasValueFlow=b $ hasValueFlow=c
75+
end
76+
77+
m_index_by()

0 commit comments

Comments
 (0)