Skip to content

Commit 5517cfa

Browse files
committed
Ruby: add flow summary for Enumerable#pluck
1 parent 207ba86 commit 5517cfa

File tree

3 files changed

+189
-0
lines changed

3 files changed

+189
-0
lines changed

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

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -367,6 +367,60 @@ module ActiveSupport {
367367
preservesValue = true
368368
}
369369
}
370+
371+
private class PluckSingleSummary extends SummarizedCallable {
372+
private MethodCall mc;
373+
private string key;
374+
375+
PluckSingleSummary() {
376+
key = getKeyArgument(mc, 0) and
377+
this = "Enumerable.pluck(" + key + ")" and
378+
mc.getMethodName() = "pluck" and
379+
mc.getNumberOfArguments() = 1
380+
}
381+
382+
override MethodCall getACall() { result = mc }
383+
384+
override predicate propagatesFlowExt(string input, string output, boolean preservesValue) {
385+
input = "Argument[self].Element[any].Element[" + key + "!]" and
386+
output = "ReturnValue.Element[any]" and
387+
preservesValue = true
388+
}
389+
}
390+
391+
private class PluckMultipleSummary extends SummarizedCallable {
392+
private MethodCall mc;
393+
394+
PluckMultipleSummary() {
395+
mc.getMethodName() = "pluck" and
396+
mc.getNumberOfArguments() > 1 and
397+
exists(int maxKey |
398+
maxKey = max(int j | exists(getKeyArgument(mc, j))) and
399+
this =
400+
"Enumerable.pluck(" +
401+
concat(int i, string key |
402+
key = getKeyArgument(mc, i)
403+
or
404+
key = "_" and
405+
not exists(getKeyArgument(mc, i)) and
406+
i in [0 .. maxKey]
407+
|
408+
key, "," order by i
409+
) + ")"
410+
)
411+
}
412+
413+
override MethodCall getACall() { result = mc }
414+
415+
override predicate propagatesFlowExt(string input, string output, boolean preservesValue) {
416+
exists(string s, int i |
417+
s = getKeyArgument(mc, i) and
418+
input = "Argument[self].Element[any].Element[" + s + "!]" and
419+
output = "ReturnValue.Element[?].Element[" + i + "!]"
420+
) and
421+
preservesValue = true
422+
}
423+
}
370424
}
371425
}
372426

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

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -352,6 +352,64 @@ edges
352352
| hash_extensions.rb:104:10:104:15 | values [element 0, element :id] : | hash_extensions.rb:104:10:104:32 | call to pick [element 1] : |
353353
| hash_extensions.rb:104:10:104:32 | call to pick [element 1] : | hash_extensions.rb:104:10:104:35 | ...[...] |
354354
| hash_extensions.rb:104:10:104:32 | call to pick [element 1] : | hash_extensions.rb:104:10:104:35 | ...[...] |
355+
| hash_extensions.rb:110:21:110:31 | call to source : | hash_extensions.rb:112:10:112:15 | values [element 0, element :id] : |
356+
| hash_extensions.rb:110:21:110:31 | call to source : | hash_extensions.rb:112:10:112:15 | values [element 0, element :id] : |
357+
| hash_extensions.rb:110:21:110:31 | call to source : | hash_extensions.rb:115:10:115:15 | values [element 0, element :id] : |
358+
| hash_extensions.rb:110:21:110:31 | call to source : | hash_extensions.rb:115:10:115:15 | values [element 0, element :id] : |
359+
| hash_extensions.rb:110:40:110:54 | call to source : | hash_extensions.rb:111:10:111:15 | values [element 0, element :name] : |
360+
| hash_extensions.rb:110:40:110:54 | call to source : | hash_extensions.rb:111:10:111:15 | values [element 0, element :name] : |
361+
| hash_extensions.rb:110:40:110:54 | call to source : | hash_extensions.rb:113:10:113:15 | values [element 0, element :name] : |
362+
| hash_extensions.rb:110:40:110:54 | call to source : | hash_extensions.rb:113:10:113:15 | values [element 0, element :name] : |
363+
| hash_extensions.rb:110:40:110:54 | call to source : | hash_extensions.rb:114:10:114:15 | values [element 0, element :name] : |
364+
| hash_extensions.rb:110:40:110:54 | call to source : | hash_extensions.rb:114:10:114:15 | values [element 0, element :name] : |
365+
| hash_extensions.rb:110:65:110:75 | call to source : | hash_extensions.rb:112:10:112:15 | values [element 1, element :id] : |
366+
| hash_extensions.rb:110:65:110:75 | call to source : | hash_extensions.rb:112:10:112:15 | values [element 1, element :id] : |
367+
| hash_extensions.rb:110:65:110:75 | call to source : | hash_extensions.rb:115:10:115:15 | values [element 1, element :id] : |
368+
| hash_extensions.rb:110:65:110:75 | call to source : | hash_extensions.rb:115:10:115:15 | values [element 1, element :id] : |
369+
| hash_extensions.rb:110:84:110:99 | call to source : | hash_extensions.rb:111:10:111:15 | values [element 1, element :name] : |
370+
| hash_extensions.rb:110:84:110:99 | call to source : | hash_extensions.rb:111:10:111:15 | values [element 1, element :name] : |
371+
| hash_extensions.rb:110:84:110:99 | call to source : | hash_extensions.rb:113:10:113:15 | values [element 1, element :name] : |
372+
| hash_extensions.rb:110:84:110:99 | call to source : | hash_extensions.rb:113:10:113:15 | values [element 1, element :name] : |
373+
| hash_extensions.rb:110:84:110:99 | call to source : | hash_extensions.rb:114:10:114:15 | values [element 1, element :name] : |
374+
| hash_extensions.rb:110:84:110:99 | call to source : | hash_extensions.rb:114:10:114:15 | values [element 1, element :name] : |
375+
| hash_extensions.rb:111:10:111:15 | values [element 0, element :name] : | hash_extensions.rb:111:10:111:28 | call to pluck [element] : |
376+
| hash_extensions.rb:111:10:111:15 | values [element 0, element :name] : | hash_extensions.rb:111:10:111:28 | call to pluck [element] : |
377+
| hash_extensions.rb:111:10:111:15 | values [element 1, element :name] : | hash_extensions.rb:111:10:111:28 | call to pluck [element] : |
378+
| hash_extensions.rb:111:10:111:15 | values [element 1, element :name] : | hash_extensions.rb:111:10:111:28 | call to pluck [element] : |
379+
| hash_extensions.rb:111:10:111:28 | call to pluck [element] : | hash_extensions.rb:111:10:111:31 | ...[...] |
380+
| hash_extensions.rb:111:10:111:28 | call to pluck [element] : | hash_extensions.rb:111:10:111:31 | ...[...] |
381+
| hash_extensions.rb:112:10:112:15 | values [element 0, element :id] : | hash_extensions.rb:112:10:112:33 | call to pluck [element, element 0] : |
382+
| hash_extensions.rb:112:10:112:15 | values [element 0, element :id] : | hash_extensions.rb:112:10:112:33 | call to pluck [element, element 0] : |
383+
| hash_extensions.rb:112:10:112:15 | values [element 1, element :id] : | hash_extensions.rb:112:10:112:33 | call to pluck [element, element 0] : |
384+
| hash_extensions.rb:112:10:112:15 | values [element 1, element :id] : | hash_extensions.rb:112:10:112:33 | call to pluck [element, element 0] : |
385+
| hash_extensions.rb:112:10:112:33 | call to pluck [element, element 0] : | hash_extensions.rb:112:10:112:36 | ...[...] [element 0] : |
386+
| hash_extensions.rb:112:10:112:33 | call to pluck [element, element 0] : | hash_extensions.rb:112:10:112:36 | ...[...] [element 0] : |
387+
| hash_extensions.rb:112:10:112:36 | ...[...] [element 0] : | hash_extensions.rb:112:10:112:39 | ...[...] |
388+
| hash_extensions.rb:112:10:112:36 | ...[...] [element 0] : | hash_extensions.rb:112:10:112:39 | ...[...] |
389+
| hash_extensions.rb:113:10:113:15 | values [element 0, element :name] : | hash_extensions.rb:113:10:113:33 | call to pluck [element, element 1] : |
390+
| hash_extensions.rb:113:10:113:15 | values [element 0, element :name] : | hash_extensions.rb:113:10:113:33 | call to pluck [element, element 1] : |
391+
| hash_extensions.rb:113:10:113:15 | values [element 1, element :name] : | hash_extensions.rb:113:10:113:33 | call to pluck [element, element 1] : |
392+
| hash_extensions.rb:113:10:113:15 | values [element 1, element :name] : | hash_extensions.rb:113:10:113:33 | call to pluck [element, element 1] : |
393+
| hash_extensions.rb:113:10:113:33 | call to pluck [element, element 1] : | hash_extensions.rb:113:10:113:36 | ...[...] [element 1] : |
394+
| hash_extensions.rb:113:10:113:33 | call to pluck [element, element 1] : | hash_extensions.rb:113:10:113:36 | ...[...] [element 1] : |
395+
| hash_extensions.rb:113:10:113:36 | ...[...] [element 1] : | hash_extensions.rb:113:10:113:39 | ...[...] |
396+
| hash_extensions.rb:113:10:113:36 | ...[...] [element 1] : | hash_extensions.rb:113:10:113:39 | ...[...] |
397+
| hash_extensions.rb:114:10:114:15 | values [element 0, element :name] : | hash_extensions.rb:114:10:114:33 | call to pluck [element, element 0] : |
398+
| hash_extensions.rb:114:10:114:15 | values [element 0, element :name] : | hash_extensions.rb:114:10:114:33 | call to pluck [element, element 0] : |
399+
| hash_extensions.rb:114:10:114:15 | values [element 1, element :name] : | hash_extensions.rb:114:10:114:33 | call to pluck [element, element 0] : |
400+
| hash_extensions.rb:114:10:114:15 | values [element 1, element :name] : | hash_extensions.rb:114:10:114:33 | call to pluck [element, element 0] : |
401+
| hash_extensions.rb:114:10:114:33 | call to pluck [element, element 0] : | hash_extensions.rb:114:10:114:36 | ...[...] [element 0] : |
402+
| hash_extensions.rb:114:10:114:33 | call to pluck [element, element 0] : | hash_extensions.rb:114:10:114:36 | ...[...] [element 0] : |
403+
| hash_extensions.rb:114:10:114:36 | ...[...] [element 0] : | hash_extensions.rb:114:10:114:39 | ...[...] |
404+
| hash_extensions.rb:114:10:114:36 | ...[...] [element 0] : | hash_extensions.rb:114:10:114:39 | ...[...] |
405+
| hash_extensions.rb:115:10:115:15 | values [element 0, element :id] : | hash_extensions.rb:115:10:115:33 | call to pluck [element, element 1] : |
406+
| hash_extensions.rb:115:10:115:15 | values [element 0, element :id] : | hash_extensions.rb:115:10:115:33 | call to pluck [element, element 1] : |
407+
| hash_extensions.rb:115:10:115:15 | values [element 1, element :id] : | hash_extensions.rb:115:10:115:33 | call to pluck [element, element 1] : |
408+
| hash_extensions.rb:115:10:115:15 | values [element 1, element :id] : | hash_extensions.rb:115:10:115:33 | call to pluck [element, element 1] : |
409+
| hash_extensions.rb:115:10:115:33 | call to pluck [element, element 1] : | hash_extensions.rb:115:10:115:36 | ...[...] [element 1] : |
410+
| hash_extensions.rb:115:10:115:33 | call to pluck [element, element 1] : | hash_extensions.rb:115:10:115:36 | ...[...] [element 1] : |
411+
| hash_extensions.rb:115:10:115:36 | ...[...] [element 1] : | hash_extensions.rb:115:10:115:39 | ...[...] |
412+
| hash_extensions.rb:115:10:115:36 | ...[...] [element 1] : | hash_extensions.rb:115:10:115:39 | ...[...] |
355413
nodes
356414
| active_support.rb:10:9:10:18 | call to source : | semmle.label | call to source : |
357415
| active_support.rb:11:10:11:10 | x : | semmle.label | x : |
@@ -790,6 +848,62 @@ nodes
790848
| hash_extensions.rb:104:10:104:32 | call to pick [element 1] : | semmle.label | call to pick [element 1] : |
791849
| hash_extensions.rb:104:10:104:35 | ...[...] | semmle.label | ...[...] |
792850
| hash_extensions.rb:104:10:104:35 | ...[...] | semmle.label | ...[...] |
851+
| hash_extensions.rb:110:21:110:31 | call to source : | semmle.label | call to source : |
852+
| hash_extensions.rb:110:21:110:31 | call to source : | semmle.label | call to source : |
853+
| hash_extensions.rb:110:40:110:54 | call to source : | semmle.label | call to source : |
854+
| hash_extensions.rb:110:40:110:54 | call to source : | semmle.label | call to source : |
855+
| hash_extensions.rb:110:65:110:75 | call to source : | semmle.label | call to source : |
856+
| hash_extensions.rb:110:65:110:75 | call to source : | semmle.label | call to source : |
857+
| hash_extensions.rb:110:84:110:99 | call to source : | semmle.label | call to source : |
858+
| hash_extensions.rb:110:84:110:99 | call to source : | semmle.label | call to source : |
859+
| hash_extensions.rb:111:10:111:15 | values [element 0, element :name] : | semmle.label | values [element 0, element :name] : |
860+
| hash_extensions.rb:111:10:111:15 | values [element 0, element :name] : | semmle.label | values [element 0, element :name] : |
861+
| hash_extensions.rb:111:10:111:15 | values [element 1, element :name] : | semmle.label | values [element 1, element :name] : |
862+
| hash_extensions.rb:111:10:111:15 | values [element 1, element :name] : | semmle.label | values [element 1, element :name] : |
863+
| hash_extensions.rb:111:10:111:28 | call to pluck [element] : | semmle.label | call to pluck [element] : |
864+
| hash_extensions.rb:111:10:111:28 | call to pluck [element] : | semmle.label | call to pluck [element] : |
865+
| hash_extensions.rb:111:10:111:31 | ...[...] | semmle.label | ...[...] |
866+
| hash_extensions.rb:111:10:111:31 | ...[...] | semmle.label | ...[...] |
867+
| hash_extensions.rb:112:10:112:15 | values [element 0, element :id] : | semmle.label | values [element 0, element :id] : |
868+
| hash_extensions.rb:112:10:112:15 | values [element 0, element :id] : | semmle.label | values [element 0, element :id] : |
869+
| hash_extensions.rb:112:10:112:15 | values [element 1, element :id] : | semmle.label | values [element 1, element :id] : |
870+
| hash_extensions.rb:112:10:112:15 | values [element 1, element :id] : | semmle.label | values [element 1, element :id] : |
871+
| hash_extensions.rb:112:10:112:33 | call to pluck [element, element 0] : | semmle.label | call to pluck [element, element 0] : |
872+
| hash_extensions.rb:112:10:112:33 | call to pluck [element, element 0] : | semmle.label | call to pluck [element, element 0] : |
873+
| hash_extensions.rb:112:10:112:36 | ...[...] [element 0] : | semmle.label | ...[...] [element 0] : |
874+
| hash_extensions.rb:112:10:112:36 | ...[...] [element 0] : | semmle.label | ...[...] [element 0] : |
875+
| hash_extensions.rb:112:10:112:39 | ...[...] | semmle.label | ...[...] |
876+
| hash_extensions.rb:112:10:112:39 | ...[...] | semmle.label | ...[...] |
877+
| hash_extensions.rb:113:10:113:15 | values [element 0, element :name] : | semmle.label | values [element 0, element :name] : |
878+
| hash_extensions.rb:113:10:113:15 | values [element 0, element :name] : | semmle.label | values [element 0, element :name] : |
879+
| hash_extensions.rb:113:10:113:15 | values [element 1, element :name] : | semmle.label | values [element 1, element :name] : |
880+
| hash_extensions.rb:113:10:113:15 | values [element 1, element :name] : | semmle.label | values [element 1, element :name] : |
881+
| hash_extensions.rb:113:10:113:33 | call to pluck [element, element 1] : | semmle.label | call to pluck [element, element 1] : |
882+
| hash_extensions.rb:113:10:113:33 | call to pluck [element, element 1] : | semmle.label | call to pluck [element, element 1] : |
883+
| hash_extensions.rb:113:10:113:36 | ...[...] [element 1] : | semmle.label | ...[...] [element 1] : |
884+
| hash_extensions.rb:113:10:113:36 | ...[...] [element 1] : | semmle.label | ...[...] [element 1] : |
885+
| hash_extensions.rb:113:10:113:39 | ...[...] | semmle.label | ...[...] |
886+
| hash_extensions.rb:113:10:113:39 | ...[...] | semmle.label | ...[...] |
887+
| hash_extensions.rb:114:10:114:15 | values [element 0, element :name] : | semmle.label | values [element 0, element :name] : |
888+
| hash_extensions.rb:114:10:114:15 | values [element 0, element :name] : | semmle.label | values [element 0, element :name] : |
889+
| hash_extensions.rb:114:10:114:15 | values [element 1, element :name] : | semmle.label | values [element 1, element :name] : |
890+
| hash_extensions.rb:114:10:114:15 | values [element 1, element :name] : | semmle.label | values [element 1, element :name] : |
891+
| hash_extensions.rb:114:10:114:33 | call to pluck [element, element 0] : | semmle.label | call to pluck [element, element 0] : |
892+
| hash_extensions.rb:114:10:114:33 | call to pluck [element, element 0] : | semmle.label | call to pluck [element, element 0] : |
893+
| hash_extensions.rb:114:10:114:36 | ...[...] [element 0] : | semmle.label | ...[...] [element 0] : |
894+
| hash_extensions.rb:114:10:114:36 | ...[...] [element 0] : | semmle.label | ...[...] [element 0] : |
895+
| hash_extensions.rb:114:10:114:39 | ...[...] | semmle.label | ...[...] |
896+
| hash_extensions.rb:114:10:114:39 | ...[...] | semmle.label | ...[...] |
897+
| hash_extensions.rb:115:10:115:15 | values [element 0, element :id] : | semmle.label | values [element 0, element :id] : |
898+
| hash_extensions.rb:115:10:115:15 | values [element 0, element :id] : | semmle.label | values [element 0, element :id] : |
899+
| hash_extensions.rb:115:10:115:15 | values [element 1, element :id] : | semmle.label | values [element 1, element :id] : |
900+
| hash_extensions.rb:115:10:115:15 | values [element 1, element :id] : | semmle.label | values [element 1, element :id] : |
901+
| hash_extensions.rb:115:10:115:33 | call to pluck [element, element 1] : | semmle.label | call to pluck [element, element 1] : |
902+
| hash_extensions.rb:115:10:115:33 | call to pluck [element, element 1] : | semmle.label | call to pluck [element, element 1] : |
903+
| hash_extensions.rb:115:10:115:36 | ...[...] [element 1] : | semmle.label | ...[...] [element 1] : |
904+
| hash_extensions.rb:115:10:115:36 | ...[...] [element 1] : | semmle.label | ...[...] [element 1] : |
905+
| hash_extensions.rb:115:10:115:39 | ...[...] | semmle.label | ...[...] |
906+
| hash_extensions.rb:115:10:115:39 | ...[...] | semmle.label | ...[...] |
793907
subpaths
794908
#select
795909
| 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 : |
@@ -840,3 +954,13 @@ subpaths
840954
| hash_extensions.rb:102:10:102:35 | ...[...] | hash_extensions.rb:98:40:98:54 | call to source : | hash_extensions.rb:102:10:102:35 | ...[...] | $@ | hash_extensions.rb:98:40:98:54 | call to source : | call to source : |
841955
| hash_extensions.rb:103:10:103:35 | ...[...] | hash_extensions.rb:98:40:98:54 | call to source : | hash_extensions.rb:103:10:103:35 | ...[...] | $@ | hash_extensions.rb:98:40:98:54 | call to source : | call to source : |
842956
| hash_extensions.rb:104:10:104:35 | ...[...] | hash_extensions.rb:98:21:98:31 | call to source : | hash_extensions.rb:104:10:104:35 | ...[...] | $@ | hash_extensions.rb:98:21:98:31 | call to source : | call to source : |
957+
| hash_extensions.rb:111:10:111:31 | ...[...] | hash_extensions.rb:110:40:110:54 | call to source : | hash_extensions.rb:111:10:111:31 | ...[...] | $@ | hash_extensions.rb:110:40:110:54 | call to source : | call to source : |
958+
| hash_extensions.rb:111:10:111:31 | ...[...] | hash_extensions.rb:110:84:110:99 | call to source : | hash_extensions.rb:111:10:111:31 | ...[...] | $@ | hash_extensions.rb:110:84:110:99 | call to source : | call to source : |
959+
| hash_extensions.rb:112:10:112:39 | ...[...] | hash_extensions.rb:110:21:110:31 | call to source : | hash_extensions.rb:112:10:112:39 | ...[...] | $@ | hash_extensions.rb:110:21:110:31 | call to source : | call to source : |
960+
| hash_extensions.rb:112:10:112:39 | ...[...] | hash_extensions.rb:110:65:110:75 | call to source : | hash_extensions.rb:112:10:112:39 | ...[...] | $@ | hash_extensions.rb:110:65:110:75 | call to source : | call to source : |
961+
| hash_extensions.rb:113:10:113:39 | ...[...] | hash_extensions.rb:110:40:110:54 | call to source : | hash_extensions.rb:113:10:113:39 | ...[...] | $@ | hash_extensions.rb:110:40:110:54 | call to source : | call to source : |
962+
| hash_extensions.rb:113:10:113:39 | ...[...] | hash_extensions.rb:110:84:110:99 | call to source : | hash_extensions.rb:113:10:113:39 | ...[...] | $@ | hash_extensions.rb:110:84:110:99 | call to source : | call to source : |
963+
| hash_extensions.rb:114:10:114:39 | ...[...] | hash_extensions.rb:110:40:110:54 | call to source : | hash_extensions.rb:114:10:114:39 | ...[...] | $@ | hash_extensions.rb:110:40:110:54 | call to source : | call to source : |
964+
| hash_extensions.rb:114:10:114:39 | ...[...] | hash_extensions.rb:110:84:110:99 | call to source : | hash_extensions.rb:114:10:114:39 | ...[...] | $@ | hash_extensions.rb:110:84:110:99 | call to source : | call to source : |
965+
| hash_extensions.rb:115:10:115:39 | ...[...] | hash_extensions.rb:110:21:110:31 | call to source : | hash_extensions.rb:115:10:115:39 | ...[...] | $@ | hash_extensions.rb:110:21:110:31 | call to source : | call to source : |
966+
| hash_extensions.rb:115:10:115:39 | ...[...] | hash_extensions.rb:110:65:110:75 | call to source : | hash_extensions.rb:115:10:115:39 | ...[...] | $@ | hash_extensions.rb:110:65:110:75 | call to source : | call to source : |

0 commit comments

Comments
 (0)