add summary for the Array method on Kernel

This commit is contained in:
erik-krogh
2023-03-01 12:53:13 +01:00
parent 36b33765a5
commit 31336b09c4
3 changed files with 53 additions and 4 deletions

View File

@@ -197,4 +197,35 @@ module Kernel {
super.getMethodName() = ["autoload", "autoload?"]
}
}
/**
* A call to `Array()`, that converts it's singular argument to an array.
* This summary is based on https://ruby-doc.org/3.2.1/Kernel.html#method-i-Array
*/
private class KernelArraySummary extends SummarizedCallable {
KernelArraySummary() { this = "Array()" }
override MethodCall getACallSimple() {
result.getMethodName() = "Array" and
// I have to have a simplified "KernelMethodCall" implementation inlined here, because relying on `UnknownMethodCall` results in non-monotonic recursion (even if using `getACall`).
(
result = API::getTopLevelMember("Kernel").getAMethodCall(_).asExpr().getExpr()
or
result.getReceiver() instanceof SelfVariableAccess
)
}
override predicate propagatesFlowExt(string input, string output, boolean preservesValue) {
(
// already an array
input = "Argument[0].WithElement[0..]" and
output = "ReturnValue"
or
// not already an array
input = "Argument[0].WithoutElement[0..]" and
output = "ReturnValue.Element[0]"
) and
preservesValue = true
}
}
}

View File

@@ -11,6 +11,13 @@ edges
| impl/unsafeCode.rb:39:14:39:14 | x : | impl/unsafeCode.rb:39:5:39:7 | [post] arr [element] : |
| impl/unsafeCode.rb:47:15:47:15 | x : | impl/unsafeCode.rb:49:9:49:12 | #{...} |
| impl/unsafeCode.rb:54:21:54:21 | x : | impl/unsafeCode.rb:55:22:55:22 | x |
| impl/unsafeCode.rb:59:21:59:21 | x : | impl/unsafeCode.rb:60:17:60:17 | x : |
| impl/unsafeCode.rb:59:24:59:24 | y : | impl/unsafeCode.rb:63:30:63:30 | y : |
| impl/unsafeCode.rb:60:11:60:18 | call to Array [element 0] : | impl/unsafeCode.rb:61:10:61:12 | arr |
| impl/unsafeCode.rb:60:17:60:17 | x : | impl/unsafeCode.rb:60:11:60:18 | call to Array [element 0] : |
| impl/unsafeCode.rb:63:13:63:32 | call to Array [element 1] : | impl/unsafeCode.rb:63:13:63:42 | call to join : |
| impl/unsafeCode.rb:63:13:63:42 | call to join : | impl/unsafeCode.rb:64:10:64:13 | arr2 |
| impl/unsafeCode.rb:63:30:63:30 | y : | impl/unsafeCode.rb:63:13:63:32 | call to Array [element 1] : |
nodes
| impl/unsafeCode.rb:2:12:2:17 | target : | semmle.label | target : |
| impl/unsafeCode.rb:3:17:3:25 | #{...} | semmle.label | #{...} |
@@ -32,6 +39,15 @@ nodes
| impl/unsafeCode.rb:49:9:49:12 | #{...} | semmle.label | #{...} |
| impl/unsafeCode.rb:54:21:54:21 | x : | semmle.label | x : |
| impl/unsafeCode.rb:55:22:55:22 | x | semmle.label | x |
| impl/unsafeCode.rb:59:21:59:21 | x : | semmle.label | x : |
| impl/unsafeCode.rb:59:24:59:24 | y : | semmle.label | y : |
| impl/unsafeCode.rb:60:11:60:18 | call to Array [element 0] : | semmle.label | call to Array [element 0] : |
| impl/unsafeCode.rb:60:17:60:17 | x : | semmle.label | x : |
| impl/unsafeCode.rb:61:10:61:12 | arr | semmle.label | arr |
| impl/unsafeCode.rb:63:13:63:32 | call to Array [element 1] : | semmle.label | call to Array [element 1] : |
| impl/unsafeCode.rb:63:13:63:42 | call to join : | semmle.label | call to join : |
| impl/unsafeCode.rb:63:30:63:30 | y : | semmle.label | y : |
| impl/unsafeCode.rb:64:10:64:13 | arr2 | semmle.label | arr2 |
subpaths
#select
| impl/unsafeCode.rb:3:17:3:25 | #{...} | impl/unsafeCode.rb:2:12:2:17 | target : | impl/unsafeCode.rb:3:17:3:25 | #{...} | This string interpolation which depends on $@ is later $@. | impl/unsafeCode.rb:2:12:2:17 | target | library input | impl/unsafeCode.rb:3:5:3:27 | call to eval | interpreted as code |
@@ -43,3 +59,5 @@ subpaths
| impl/unsafeCode.rb:44:10:44:12 | arr | impl/unsafeCode.rb:37:15:37:15 | x : | impl/unsafeCode.rb:44:10:44:12 | arr | This array which depends on $@ is later $@. | impl/unsafeCode.rb:37:15:37:15 | x | library input | impl/unsafeCode.rb:44:5:44:24 | call to eval | interpreted as code |
| impl/unsafeCode.rb:49:9:49:12 | #{...} | impl/unsafeCode.rb:47:15:47:15 | x : | impl/unsafeCode.rb:49:9:49:12 | #{...} | This string interpolation which depends on $@ is later $@. | impl/unsafeCode.rb:47:15:47:15 | x | library input | impl/unsafeCode.rb:51:5:51:13 | call to eval | interpreted as code |
| impl/unsafeCode.rb:55:22:55:22 | x | impl/unsafeCode.rb:54:21:54:21 | x : | impl/unsafeCode.rb:55:22:55:22 | x | This string concatenation which depends on $@ is later $@. | impl/unsafeCode.rb:54:21:54:21 | x | library input | impl/unsafeCode.rb:56:5:56:13 | call to eval | interpreted as code |
| impl/unsafeCode.rb:61:10:61:12 | arr | impl/unsafeCode.rb:59:21:59:21 | x : | impl/unsafeCode.rb:61:10:61:12 | arr | This array which depends on $@ is later $@. | impl/unsafeCode.rb:59:21:59:21 | x | library input | impl/unsafeCode.rb:61:5:61:23 | call to eval | interpreted as code |
| impl/unsafeCode.rb:64:10:64:13 | arr2 | impl/unsafeCode.rb:59:24:59:24 | y : | impl/unsafeCode.rb:64:10:64:13 | arr2 | This array which depends on $@ is later $@. | impl/unsafeCode.rb:59:24:59:24 | y | library input | impl/unsafeCode.rb:64:5:64:25 | call to eval | interpreted as code |

View File

@@ -57,10 +57,10 @@ class Foobar
end
def join_indirect(x, y)
arr = Array("foo = ", x)
eval(arr.join(" ")) # NOT OK - but not currently flagged by the query
arr = Array(x)
eval(arr.join(" ")) # NOT OK
arr2 = [Array("foo = ", y).join(" ")]
eval(arr2.join("\n")) # NOT OK - but not currently flagged by the query
arr2 = [Array(["foo = ", y]).join(" ")]
eval(arr2.join("\n")) # NOT OK
end
end