Merge pull request #7568 from aibaars/ruby-pattern-matching-taint

Ruby: taint steps for pattern matches
This commit is contained in:
Arthur Baars
2022-01-26 10:27:47 +01:00
committed by GitHub
16 changed files with 533 additions and 54 deletions

View File

@@ -800,6 +800,7 @@ control/cases.rb:
# 52| getBranch: [InClause] in ... then ...
# 52| getPattern: [HashPattern] { ..., ** }
# 52| getKey: [SymbolLiteral] :a
# 52| getValue: [LocalVariableAccess] a
# 53| getBranch: [InClause] in ... then ...
# 53| getPattern: [HashPattern] { ..., ** }
# 53| getKey: [SymbolLiteral] :a
@@ -813,17 +814,20 @@ control/cases.rb:
# 55| getKey: [SymbolLiteral] :a
# 55| getValue: [IntegerLiteral] 5
# 55| getKey: [SymbolLiteral] :b
# 55| getValue: [LocalVariableAccess] b
# 56| getBranch: [InClause] in ... then ...
# 56| getPattern: [HashPattern] { ..., ** }
# 56| getKey: [SymbolLiteral] :a
# 56| getValue: [IntegerLiteral] 5
# 56| getKey: [SymbolLiteral] :b
# 56| getValue: [LocalVariableAccess] b
# 56| getRestVariableAccess: [LocalVariableAccess] map
# 57| getBranch: [InClause] in ... then ...
# 57| getPattern: [HashPattern] { ..., ** }
# 57| getKey: [SymbolLiteral] :a
# 57| getValue: [IntegerLiteral] 5
# 57| getKey: [SymbolLiteral] :b
# 57| getValue: [LocalVariableAccess] b
# 58| getBranch: [InClause] in ... then ...
# 58| getPattern: [HashPattern] { ..., ** }
# 59| getBranch: [InClause] in ... then ...
@@ -878,6 +882,7 @@ control/cases.rb:
# 71| getBranch: [InClause] in ... then ...
# 71| getPattern: [HashPattern] { ..., ** }
# 71| getKey: [SymbolLiteral] :a
# 71| getValue: [LocalVariableAccess] a
# 72| getBranch: [InClause] in ... then ...
# 72| getPattern: [HashPattern] { ..., ** }
# 72| getKey: [SymbolLiteral] :a
@@ -891,17 +896,20 @@ control/cases.rb:
# 74| getKey: [SymbolLiteral] :a
# 74| getValue: [IntegerLiteral] 5
# 74| getKey: [SymbolLiteral] :b
# 74| getValue: [LocalVariableAccess] b
# 75| getBranch: [InClause] in ... then ...
# 75| getPattern: [HashPattern] { ..., ** }
# 75| getKey: [SymbolLiteral] :a
# 75| getValue: [IntegerLiteral] 5
# 75| getKey: [SymbolLiteral] :b
# 75| getValue: [LocalVariableAccess] b
# 75| getRestVariableAccess: [LocalVariableAccess] map
# 76| getBranch: [InClause] in ... then ...
# 76| getPattern: [HashPattern] { ..., ** }
# 76| getKey: [SymbolLiteral] :a
# 76| getValue: [IntegerLiteral] 5
# 76| getKey: [SymbolLiteral] :b
# 76| getValue: [LocalVariableAccess] b
# 77| getBranch: [InClause] in ... then ...
# 77| getPattern: [HashPattern] { ..., ** }
# 78| getBranch: [InClause] in ... then ...
@@ -1078,6 +1086,7 @@ control/cases.rb:
# 139| getBranch: [InClause] in ... then ...
# 139| getPattern: [HashPattern] { ..., ** }
# 139| getKey: [SymbolLiteral] :x
# 139| getValue: [LocalVariableAccess] x
# 140| getBranch: [InClause] in ... then ...
# 140| getPattern: [HashPattern] { ..., ** }
# 140| getClass: [ConstantReadAccess] Bar
@@ -1091,11 +1100,13 @@ control/cases.rb:
# 141| getKey: [SymbolLiteral] :x
# 141| getValue: [IntegerLiteral] 1
# 141| getKey: [SymbolLiteral] :a
# 141| getValue: [LocalVariableAccess] a
# 141| getRestVariableAccess: [LocalVariableAccess] rest
# 142| getBranch: [InClause] in ... then ...
# 142| getPattern: [HashPattern] { ..., ** }
# 142| getClass: [ConstantReadAccess] Foo
# 142| getKey: [SymbolLiteral] :y
# 142| getValue: [LocalVariableAccess] y
# 143| getBranch: [InClause] in ... then ...
# 143| getPattern: [HashPattern] { ..., ** }
# 143| getClass: [ConstantReadAccess] Bar

View File

@@ -936,6 +936,9 @@ case.rb:
# 49| 1
#-----| no-match -> in ... then ...
#-----| match -> a
# 49| a
#-----| match -> rest
# 49| rest
@@ -1190,8 +1193,14 @@ case.rb:
#-----| match -> x
# 82| x
#-----| match -> 1
# 82| then ...
#-----| -> case ...
# 82| 1
#-----| -> then ...
# 83| in ... then ...
#-----| -> ... | ...
@@ -1355,8 +1364,8 @@ case.rb:
#-----| match -> case ...
# 91| [ ..., * ]
#-----| match -> case ...
#-----| no-match -> { ..., ** }
#-----| match -> case ...
# 91| { ..., ** }
#-----| match -> case ...

View File

@@ -79,7 +79,7 @@ def case_match_various value
in 5 .. 10
in .. 10
in 5 ..
in 5 => x
in 5 => x then 1
in 5 | ^foo | "string"
in ::Foo::Bar
in -> x { x == 10 }

View File

@@ -70,6 +70,17 @@
| local_dataflow.rb:50:18:50:18 | [post] x | local_dataflow.rb:51:20:51:20 | x |
| local_dataflow.rb:50:18:50:18 | x | local_dataflow.rb:51:20:51:20 | x |
| local_dataflow.rb:51:9:51:15 | "break" | local_dataflow.rb:51:3:51:15 | break |
| local_dataflow.rb:60:1:90:3 | self (test_case) | local_dataflow.rb:78:12:78:20 | self |
| local_dataflow.rb:60:1:90:3 | self in test_case | local_dataflow.rb:78:12:78:20 | self |
| local_dataflow.rb:60:1:90:3 | self in test_case | local_dataflow.rb:79:20:79:26 | self |
| local_dataflow.rb:60:1:90:3 | self in test_case | local_dataflow.rb:80:24:80:30 | self |
| local_dataflow.rb:60:1:90:3 | self in test_case | local_dataflow.rb:82:7:82:13 | self |
| local_dataflow.rb:60:1:90:3 | self in test_case | local_dataflow.rb:83:7:83:13 | self |
| local_dataflow.rb:60:1:90:3 | self in test_case | local_dataflow.rb:84:7:84:13 | self |
| local_dataflow.rb:60:1:90:3 | self in test_case | local_dataflow.rb:85:22:85:28 | self |
| local_dataflow.rb:60:1:90:3 | self in test_case | local_dataflow.rb:86:28:86:34 | self |
| local_dataflow.rb:60:1:90:3 | self in test_case | local_dataflow.rb:87:20:87:26 | self |
| local_dataflow.rb:60:1:90:3 | self in test_case | local_dataflow.rb:89:3:89:9 | self |
| local_dataflow.rb:60:15:60:15 | x | local_dataflow.rb:60:15:60:15 | x |
| local_dataflow.rb:60:15:60:15 | x | local_dataflow.rb:61:12:61:12 | x |
| local_dataflow.rb:61:7:68:5 | case ... | local_dataflow.rb:61:3:68:5 | ... = ... |
@@ -100,3 +111,58 @@
| local_dataflow.rb:73:7:73:7 | x | local_dataflow.rb:72:7:73:7 | then ... |
| local_dataflow.rb:74:3:75:6 | else ... | local_dataflow.rb:69:7:76:5 | case ... |
| local_dataflow.rb:75:6:75:6 | x | local_dataflow.rb:74:3:75:6 | else ... |
| local_dataflow.rb:78:3:88:5 | ... = ... | local_dataflow.rb:89:8:89:8 | z |
| local_dataflow.rb:78:7:88:5 | case ... | local_dataflow.rb:78:3:88:5 | ... = ... |
| local_dataflow.rb:78:7:88:5 | case ... | local_dataflow.rb:78:3:88:5 | ... = ... |
| local_dataflow.rb:78:12:78:20 | [post] self | local_dataflow.rb:79:20:79:26 | self |
| local_dataflow.rb:78:12:78:20 | [post] self | local_dataflow.rb:80:24:80:30 | self |
| local_dataflow.rb:78:12:78:20 | [post] self | local_dataflow.rb:82:7:82:13 | self |
| local_dataflow.rb:78:12:78:20 | [post] self | local_dataflow.rb:85:22:85:28 | self |
| local_dataflow.rb:78:12:78:20 | [post] self | local_dataflow.rb:86:28:86:34 | self |
| local_dataflow.rb:78:12:78:20 | [post] self | local_dataflow.rb:87:20:87:26 | self |
| local_dataflow.rb:78:12:78:20 | self | local_dataflow.rb:79:20:79:26 | self |
| local_dataflow.rb:78:12:78:20 | self | local_dataflow.rb:80:24:80:30 | self |
| local_dataflow.rb:78:12:78:20 | self | local_dataflow.rb:82:7:82:13 | self |
| local_dataflow.rb:78:12:78:20 | self | local_dataflow.rb:85:22:85:28 | self |
| local_dataflow.rb:78:12:78:20 | self | local_dataflow.rb:86:28:86:34 | self |
| local_dataflow.rb:78:12:78:20 | self | local_dataflow.rb:87:20:87:26 | self |
| local_dataflow.rb:79:13:79:13 | b | local_dataflow.rb:79:25:79:25 | b |
| local_dataflow.rb:79:15:79:45 | then ... | local_dataflow.rb:78:7:88:5 | case ... |
| local_dataflow.rb:79:20:79:26 | [post] self | local_dataflow.rb:89:3:89:9 | self |
| local_dataflow.rb:79:20:79:26 | call to sink | local_dataflow.rb:79:15:79:45 | then ... |
| local_dataflow.rb:79:20:79:26 | self | local_dataflow.rb:89:3:89:9 | self |
| local_dataflow.rb:80:8:80:8 | a | local_dataflow.rb:80:13:80:13 | a |
| local_dataflow.rb:80:13:80:13 | [post] a | local_dataflow.rb:80:29:80:29 | a |
| local_dataflow.rb:80:13:80:13 | a | local_dataflow.rb:80:29:80:29 | a |
| local_dataflow.rb:80:19:80:49 | then ... | local_dataflow.rb:78:7:88:5 | case ... |
| local_dataflow.rb:80:24:80:30 | [post] self | local_dataflow.rb:89:3:89:9 | self |
| local_dataflow.rb:80:24:80:30 | call to sink | local_dataflow.rb:80:19:80:49 | then ... |
| local_dataflow.rb:80:24:80:30 | self | local_dataflow.rb:89:3:89:9 | self |
| local_dataflow.rb:81:9:81:9 | c | local_dataflow.rb:82:12:82:12 | c |
| local_dataflow.rb:81:13:81:13 | d | local_dataflow.rb:83:12:83:12 | d |
| local_dataflow.rb:81:16:81:16 | e | local_dataflow.rb:84:12:84:12 | e |
| local_dataflow.rb:81:20:84:33 | then ... | local_dataflow.rb:78:7:88:5 | case ... |
| local_dataflow.rb:81:25:84:14 | call to [] | local_dataflow.rb:81:20:84:33 | then ... |
| local_dataflow.rb:82:7:82:13 | [post] self | local_dataflow.rb:83:7:83:13 | self |
| local_dataflow.rb:82:7:82:13 | self | local_dataflow.rb:83:7:83:13 | self |
| local_dataflow.rb:83:7:83:13 | [post] self | local_dataflow.rb:84:7:84:13 | self |
| local_dataflow.rb:83:7:83:13 | self | local_dataflow.rb:84:7:84:13 | self |
| local_dataflow.rb:84:7:84:13 | [post] self | local_dataflow.rb:89:3:89:9 | self |
| local_dataflow.rb:84:7:84:13 | self | local_dataflow.rb:89:3:89:9 | self |
| local_dataflow.rb:85:13:85:13 | f | local_dataflow.rb:85:27:85:27 | f |
| local_dataflow.rb:85:17:85:47 | then ... | local_dataflow.rb:78:7:88:5 | case ... |
| local_dataflow.rb:85:22:85:28 | [post] self | local_dataflow.rb:89:3:89:9 | self |
| local_dataflow.rb:85:22:85:28 | call to sink | local_dataflow.rb:85:17:85:47 | then ... |
| local_dataflow.rb:85:22:85:28 | self | local_dataflow.rb:89:3:89:9 | self |
| local_dataflow.rb:86:18:86:18 | g | local_dataflow.rb:86:33:86:33 | g |
| local_dataflow.rb:86:23:86:53 | then ... | local_dataflow.rb:78:7:88:5 | case ... |
| local_dataflow.rb:86:28:86:34 | [post] self | local_dataflow.rb:89:3:89:9 | self |
| local_dataflow.rb:86:28:86:34 | call to sink | local_dataflow.rb:86:23:86:53 | then ... |
| local_dataflow.rb:86:28:86:34 | self | local_dataflow.rb:89:3:89:9 | self |
| local_dataflow.rb:87:10:87:10 | x | local_dataflow.rb:87:25:87:25 | x |
| local_dataflow.rb:87:15:87:48 | then ... | local_dataflow.rb:78:7:88:5 | case ... |
| local_dataflow.rb:87:20:87:26 | [post] self | local_dataflow.rb:89:3:89:9 | self |
| local_dataflow.rb:87:20:87:26 | self | local_dataflow.rb:89:3:89:9 | self |
| local_dataflow.rb:87:25:87:25 | [post] x | local_dataflow.rb:87:29:87:29 | x |
| local_dataflow.rb:87:25:87:25 | x | local_dataflow.rb:87:29:87:29 | x |
| local_dataflow.rb:87:29:87:29 | x | local_dataflow.rb:87:15:87:48 | then ... |

View File

@@ -12,7 +12,7 @@ ret
| local_dataflow.rb:50:3:50:13 | next |
| local_dataflow.rb:51:3:51:15 | break |
| local_dataflow.rb:52:3:52:10 | "normal" |
| local_dataflow.rb:69:3:76:5 | ... = ... |
| local_dataflow.rb:89:3:89:9 | call to sink |
arg
| local_dataflow.rb:3:8:3:10 | self | local_dataflow.rb:3:8:3:10 | call to p | self |
| local_dataflow.rb:3:10:3:10 | a | local_dataflow.rb:3:8:3:10 | call to p | position 0 |
@@ -49,3 +49,29 @@ arg
| local_dataflow.rb:55:6:55:6 | 1 | local_dataflow.rb:55:5:55:13 | call to [] | position 0 |
| local_dataflow.rb:55:9:55:9 | 2 | local_dataflow.rb:55:5:55:13 | call to [] | position 1 |
| local_dataflow.rb:55:12:55:12 | 3 | local_dataflow.rb:55:5:55:13 | call to [] | position 2 |
| local_dataflow.rb:78:12:78:20 | self | local_dataflow.rb:78:12:78:20 | call to source | self |
| local_dataflow.rb:78:19:78:19 | 1 | local_dataflow.rb:78:12:78:20 | call to source | position 0 |
| local_dataflow.rb:79:20:79:26 | self | local_dataflow.rb:79:20:79:26 | call to sink | self |
| local_dataflow.rb:79:25:79:25 | b | local_dataflow.rb:79:20:79:26 | call to sink | position 0 |
| local_dataflow.rb:80:13:80:13 | a | local_dataflow.rb:80:13:80:17 | ... > ... | self |
| local_dataflow.rb:80:17:80:17 | 0 | local_dataflow.rb:80:13:80:17 | ... > ... | position 0 |
| local_dataflow.rb:80:24:80:30 | self | local_dataflow.rb:80:24:80:30 | call to sink | self |
| local_dataflow.rb:80:29:80:29 | a | local_dataflow.rb:80:24:80:30 | call to sink | position 0 |
| local_dataflow.rb:81:25:84:14 | Array | local_dataflow.rb:81:25:84:14 | call to [] | self |
| local_dataflow.rb:82:7:82:13 | call to sink | local_dataflow.rb:81:25:84:14 | call to [] | position 0 |
| local_dataflow.rb:82:7:82:13 | self | local_dataflow.rb:82:7:82:13 | call to sink | self |
| local_dataflow.rb:82:12:82:12 | c | local_dataflow.rb:82:7:82:13 | call to sink | position 0 |
| local_dataflow.rb:83:7:83:13 | call to sink | local_dataflow.rb:81:25:84:14 | call to [] | position 1 |
| local_dataflow.rb:83:7:83:13 | self | local_dataflow.rb:83:7:83:13 | call to sink | self |
| local_dataflow.rb:83:12:83:12 | d | local_dataflow.rb:83:7:83:13 | call to sink | position 0 |
| local_dataflow.rb:84:7:84:13 | call to sink | local_dataflow.rb:81:25:84:14 | call to [] | position 2 |
| local_dataflow.rb:84:7:84:13 | self | local_dataflow.rb:84:7:84:13 | call to sink | self |
| local_dataflow.rb:84:12:84:12 | e | local_dataflow.rb:84:7:84:13 | call to sink | position 0 |
| local_dataflow.rb:85:22:85:28 | self | local_dataflow.rb:85:22:85:28 | call to sink | self |
| local_dataflow.rb:85:27:85:27 | f | local_dataflow.rb:85:22:85:28 | call to sink | position 0 |
| local_dataflow.rb:86:28:86:34 | self | local_dataflow.rb:86:28:86:34 | call to sink | self |
| local_dataflow.rb:86:33:86:33 | g | local_dataflow.rb:86:28:86:34 | call to sink | position 0 |
| local_dataflow.rb:87:20:87:26 | self | local_dataflow.rb:87:20:87:26 | call to sink | self |
| local_dataflow.rb:87:25:87:25 | x | local_dataflow.rb:87:20:87:26 | call to sink | position 0 |
| local_dataflow.rb:89:3:89:9 | self | local_dataflow.rb:89:3:89:9 | call to sink | self |
| local_dataflow.rb:89:8:89:8 | z | local_dataflow.rb:89:3:89:9 | call to sink | position 0 |

View File

@@ -0,0 +1,33 @@
failures
edges
| local_dataflow.rb:78:12:78:20 | call to source : | local_dataflow.rb:79:25:79:25 | b |
| local_dataflow.rb:78:12:78:20 | call to source : | local_dataflow.rb:80:29:80:29 | a |
| local_dataflow.rb:78:12:78:20 | call to source : | local_dataflow.rb:82:12:82:12 | c |
| local_dataflow.rb:78:12:78:20 | call to source : | local_dataflow.rb:83:12:83:12 | d |
| local_dataflow.rb:78:12:78:20 | call to source : | local_dataflow.rb:84:12:84:12 | e |
| local_dataflow.rb:78:12:78:20 | call to source : | local_dataflow.rb:85:27:85:27 | f |
| local_dataflow.rb:78:12:78:20 | call to source : | local_dataflow.rb:86:33:86:33 | g |
| local_dataflow.rb:78:12:78:20 | call to source : | local_dataflow.rb:87:25:87:25 | x |
| local_dataflow.rb:78:12:78:20 | call to source : | local_dataflow.rb:89:8:89:8 | z |
nodes
| local_dataflow.rb:78:12:78:20 | call to source : | semmle.label | call to source : |
| local_dataflow.rb:79:25:79:25 | b | semmle.label | b |
| local_dataflow.rb:80:29:80:29 | a | semmle.label | a |
| local_dataflow.rb:82:12:82:12 | c | semmle.label | c |
| local_dataflow.rb:83:12:83:12 | d | semmle.label | d |
| local_dataflow.rb:84:12:84:12 | e | semmle.label | e |
| local_dataflow.rb:85:27:85:27 | f | semmle.label | f |
| local_dataflow.rb:86:33:86:33 | g | semmle.label | g |
| local_dataflow.rb:87:25:87:25 | x | semmle.label | x |
| local_dataflow.rb:89:8:89:8 | z | semmle.label | z |
subpaths
#select
| local_dataflow.rb:79:25:79:25 | b | local_dataflow.rb:78:12:78:20 | call to source : | local_dataflow.rb:79:25:79:25 | b | $@ | local_dataflow.rb:78:12:78:20 | call to source : | call to source : |
| local_dataflow.rb:80:29:80:29 | a | local_dataflow.rb:78:12:78:20 | call to source : | local_dataflow.rb:80:29:80:29 | a | $@ | local_dataflow.rb:78:12:78:20 | call to source : | call to source : |
| local_dataflow.rb:82:12:82:12 | c | local_dataflow.rb:78:12:78:20 | call to source : | local_dataflow.rb:82:12:82:12 | c | $@ | local_dataflow.rb:78:12:78:20 | call to source : | call to source : |
| local_dataflow.rb:83:12:83:12 | d | local_dataflow.rb:78:12:78:20 | call to source : | local_dataflow.rb:83:12:83:12 | d | $@ | local_dataflow.rb:78:12:78:20 | call to source : | call to source : |
| local_dataflow.rb:84:12:84:12 | e | local_dataflow.rb:78:12:78:20 | call to source : | local_dataflow.rb:84:12:84:12 | e | $@ | local_dataflow.rb:78:12:78:20 | call to source : | call to source : |
| local_dataflow.rb:85:27:85:27 | f | local_dataflow.rb:78:12:78:20 | call to source : | local_dataflow.rb:85:27:85:27 | f | $@ | local_dataflow.rb:78:12:78:20 | call to source : | call to source : |
| local_dataflow.rb:86:33:86:33 | g | local_dataflow.rb:78:12:78:20 | call to source : | local_dataflow.rb:86:33:86:33 | g | $@ | local_dataflow.rb:78:12:78:20 | call to source : | call to source : |
| local_dataflow.rb:87:25:87:25 | x | local_dataflow.rb:78:12:78:20 | call to source : | local_dataflow.rb:87:25:87:25 | x | $@ | local_dataflow.rb:78:12:78:20 | call to source : | call to source : |
| local_dataflow.rb:89:8:89:8 | z | local_dataflow.rb:78:12:78:20 | call to source : | local_dataflow.rb:89:8:89:8 | z | $@ | local_dataflow.rb:78:12:78:20 | call to source : | call to source : |

View File

@@ -0,0 +1,11 @@
/**
* @kind path-problem
*/
import ruby
import TestUtilities.InlineFlowTest
import PathGraph
from DataFlow::PathNode source, DataFlow::PathNode sink, DefaultTaintFlowConf conf
where conf.hasFlowPath(source, sink)
select sink, source, sink, "$@", source, source.toString()

View File

@@ -74,5 +74,18 @@ def test_case x
else
x
end
z = case source(1)
in 5 => b then sink(b) # $ hasTaintFlow=1
in a if a > 0 then sink(a) # $ hasTaintFlow=1
in [c, *d, e ] then [
sink(c), # $ hasTaintFlow=1
sink(d), # $ hasTaintFlow=1
sink(e)] # $ hasTaintFlow=1
in { a: f } then sink(f) # $ hasTaintFlow=1
in { foo: 1, g: } then sink(g) # $ hasTaintFlow=1
in { x: } then sink(x); x # $ hasTaintFlow=1
end
sink(z) # $ hasTaintFlow=1
end