зеркало из https://github.com/github/codeql.git
Ruby: Add ActiveSupport extensions
This commit is contained in:
Родитель
cb37a0e835
Коммит
71d703f2a5
|
@ -83,6 +83,74 @@ module ActiveSupport {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Extensions to the `Hash` class.
|
||||
*/
|
||||
module Hash {
|
||||
private class WithIndifferentAccessSummary extends SimpleSummarizedCallable {
|
||||
WithIndifferentAccessSummary() { this = "with_indifferent_access" }
|
||||
|
||||
override predicate propagatesFlowExt(string input, string output, boolean preservesValue) {
|
||||
input = "Argument[self].Element[any]" and
|
||||
output = "ReturnValue.Element[any]" and
|
||||
preservesValue = true
|
||||
}
|
||||
}
|
||||
|
||||
private class TransformSummary extends SimpleSummarizedCallable {
|
||||
TransformSummary() {
|
||||
this =
|
||||
[
|
||||
"stringify_keys", "to_options", "symbolize_keys", "deep_stringify_keys",
|
||||
"deep_symbolize_keys", "with_indifferent_access"
|
||||
]
|
||||
}
|
||||
|
||||
override predicate propagatesFlowExt(string input, string output, boolean preservesValue) {
|
||||
input = "Argument[self].Element[any]" and
|
||||
output = "ReturnValue.Element[?]" and
|
||||
preservesValue = true
|
||||
}
|
||||
}
|
||||
|
||||
private string getExtractComponent(MethodCall mc, int i) {
|
||||
mc.getMethodName() = ["extract!"] and
|
||||
result = DataFlow::Content::getKnownElementIndex(mc.getArgument(i)).serialize()
|
||||
}
|
||||
|
||||
private class ExtractSummary extends SummarizedCallable {
|
||||
MethodCall mc;
|
||||
|
||||
ExtractSummary() {
|
||||
mc.getMethodName() = "extract!" and
|
||||
this =
|
||||
"extract!(" +
|
||||
concat(int i, string s | s = getExtractComponent(mc, i) | s, "," order by i) + ")"
|
||||
}
|
||||
|
||||
final override MethodCall getACall() { result = mc }
|
||||
|
||||
override predicate propagatesFlowExt(string input, string output, boolean preservesValue) {
|
||||
(
|
||||
exists(string s | s = getExtractComponent(mc, _) |
|
||||
input = "Argument[self].Element[" + s + "!]" and
|
||||
output = "ReturnValue.Element[" + s + "!]"
|
||||
)
|
||||
or
|
||||
input =
|
||||
"Argument[self]" +
|
||||
concat(int i, string s |
|
||||
s = getExtractComponent(mc, i)
|
||||
|
|
||||
".WithoutElement[" + s + "!]" order by i
|
||||
) + ".WithElement[any]" and
|
||||
output = "Argument[self]"
|
||||
) and
|
||||
preservesValue = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Extensions to the `Enumerable` module.
|
||||
*/
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
import codeql.ruby.AST
|
||||
import TestUtilities.InlineFlowTest
|
||||
import codeql.ruby.Frameworks
|
||||
import PathGraph
|
||||
|
||||
from DataFlow::PathNode source, DataFlow::PathNode sink, DefaultValueFlowConf conf
|
||||
|
|
|
@ -0,0 +1,76 @@
|
|||
def m_deep_merge
|
||||
h1 = { a: source "a" }
|
||||
h2 = { b: source "b" }
|
||||
x = h1.deep_merge(h2)
|
||||
|
||||
sink x[:a] # $ hasValueFlow=a
|
||||
sink x[:b] # $ hasValueFlow=b
|
||||
end
|
||||
|
||||
def m_deep_merge!
|
||||
h1 = { a: source "a" }
|
||||
h2 = { b: source "b" }
|
||||
x = h1.deep_merge!(h2)
|
||||
|
||||
sink x[:a] # $ hasValueFlow=a
|
||||
sink x[:b] # $ hasValueFlow=b
|
||||
|
||||
sink h1[:a] # $ hasValueFlow=a
|
||||
sink h1[:b] # $ hasValueFlow=b
|
||||
|
||||
sink h2[:a]
|
||||
sink h2[:b] # $ hasValueFlow=b
|
||||
end
|
||||
|
||||
def m_stringify_keys
|
||||
h = { a: source "a" }
|
||||
x = h.stringify_keys
|
||||
sink x[:a] # $hasValueFlow=a
|
||||
end
|
||||
|
||||
def m_to_options
|
||||
h = { a: taint "a" }
|
||||
x = h.to_options
|
||||
sink x[:a] # $hasTaintFlow=a
|
||||
end
|
||||
|
||||
def m_symbolize_keys
|
||||
h = { a: taint "a" }
|
||||
x = h.symbolize_keys
|
||||
sink x[:a] # $hasTaintFlow=a
|
||||
end
|
||||
|
||||
def m_deep_stringify_keys
|
||||
h = { a: taint "a" }
|
||||
x = h.deep_stringify_keys
|
||||
sink x[:a] # $hasTaintFlow=a
|
||||
end
|
||||
|
||||
def m_deep_symbolize_keys
|
||||
h = { a: taint "a" }
|
||||
x = h.deep_symbolize_keys
|
||||
sink x[:a] # $hasTaintFlow=a
|
||||
end
|
||||
|
||||
def m_with_indifferent_access
|
||||
h = { a: taint "a" }
|
||||
x = h.with_indifferent_access
|
||||
sink x[:a] # $hasTaintFlow=a
|
||||
end
|
||||
|
||||
def m_extract!(x)
|
||||
h = { a: taint "a", b: taint "b", c: "c", d: taint "d" }
|
||||
x = h.extract!(:a, x, :b)
|
||||
|
||||
sink h[:a]
|
||||
sink h[:b]
|
||||
sink h[:c]
|
||||
sink h[:d] # $ hasValueFlow=d
|
||||
|
||||
sink x[:a] # $ hasValueFlow=a
|
||||
sink x[:b] # $ hasValueFlow=b
|
||||
sink x[:c]
|
||||
sink x[:d]
|
||||
end
|
||||
|
||||
m_extract!(:c)
|
Загрузка…
Ссылка в новой задаче