Ruby: Generalize ArrayElementContent to ElementContent

This commit is contained in:
Tom Hvitved
2022-02-09 10:41:25 +01:00
parent 597424809f
commit d1c9d68e14
15 changed files with 5554 additions and 5546 deletions

View File

@@ -105,6 +105,33 @@ class ConstantValue extends TConstantValue {
/** Holds if this is the `nil` value. */
predicate isNil() { this = TNil() }
/** Gets a (unique) serialized version of this value. */
final string serialize() {
result = this.getInt().toString()
or
exists(string res | res = this.getFloat().toString() |
if exists(res.indexOf(".")) then result = res else result = res + ".0"
)
or
exists(int numerator, int denominator |
this.isRational(numerator, denominator) and
result = numerator + "/" + denominator
)
or
exists(float real, float imaginary |
this.isComplex(real, imaginary) and
result = real + "+" + imaginary + "i"
)
or
result = "\"" + this.getString().replaceAll("\"", "\\\"") + "\""
or
result = ":" + this.getSymbol()
or
result = this.getBoolean().toString()
or
this.isNil() and result = "nil"
}
}
/** Provides different sub classes of `ConstantValue`. */

View File

@@ -404,7 +404,7 @@ cached
private module Cached {
cached
newtype TConstantValue =
TInt(int i) { isInt(_, i) or isIntExpr(_, i) } or
TInt(int i) { isInt(_, i) or isIntExpr(_, i) or i in [0 .. 100] } or
TFloat(float f) { isFloat(_, f) or isFloatExpr(_, f) } or
TRational(int numerator, int denominator) {
isRational(_, numerator, denominator) or

View File

@@ -31,33 +31,27 @@ module SummaryComponent {
/** Gets a summary component that represents a block argument. */
SummaryComponent block() { result = argument(any(ParameterPosition pos | pos.isBlock())) }
/** Gets a summary component that represents an element in an array at an unknown index. */
SummaryComponent arrayElementUnknown() {
result = SC::content(TSingletonContent(TUnknownArrayElementContent()))
/** Gets a summary component that represents an element in a collection at an unknown index. */
SummaryComponent elementUnknown() {
result = SC::content(TSingletonContent(TUnknownElementContent()))
}
/** Gets a summary component that represents an element in a collection at a known index. */
SummaryComponent elementKnown(ConstantValue cv) {
result = SC::content(TSingletonContent(DataFlow::Content::getElementContent(cv)))
}
/**
* Gets a summary component that represents an element in an array at a known index.
* Gets a summary component that represents an element in a collection at either an unknown
* index or known index. This has the same semantics as
*
* Has no result for negative indices. Wrap-around interpretation of negative indices should be
* handled by the caller, if modeling a function that has such behavior.
* ```ql
* elementKnown() or elementUnknown(_)
* ```
*
* but is more efficient, because it is represented by a single value.
*/
bindingset[i]
SummaryComponent arrayElementKnown(int i) {
result = SC::content(TSingletonContent(TKnownArrayElementContent(i)))
or
// `i` may be out of range
i >= 0 and
not exists(TKnownArrayElementContent(i)) and
result = arrayElementUnknown()
}
/**
* Gets a summary component that represents an element in an array at either an unknown
* index or known index. This predicate should never be used in the output specification
* of a flow summary; use `arrayElementUnknown()` instead.
*/
SummaryComponent arrayElementAny() { result = SC::content(TAnyArrayElementContent()) }
SummaryComponent elementAny() { result = SC::content(TAnyElementContent()) }
/** Gets a summary component that represents the return value of a call. */
SummaryComponent return() { result = SC::return(any(NormalReturnKind rk)) }

View File

@@ -319,12 +319,15 @@ private module Cached {
cached
newtype TContentSet =
TSingletonContent(Content c) or
TAnyArrayElementContent()
TAnyElementContent()
cached
newtype TContent =
TKnownArrayElementContent(int i) { i in [0 .. 10] } or
TUnknownArrayElementContent()
TKnownElementContent(ConstantValue cv) {
not cv.isInt(_) or
cv.getInt() in [0 .. 10]
} or
TUnknownElementContent()
/**
* Holds if `e` is an `ExprNode` that may be returned by a call to `c`.
@@ -341,7 +344,7 @@ private module Cached {
}
}
class TArrayElementContent = TKnownArrayElementContent or TUnknownArrayElementContent;
class TElementContent = TKnownElementContent or TUnknownElementContent;
import Cached
@@ -862,7 +865,7 @@ int accessPathLimit() { result = 5 }
* Holds if access paths with `c` at their head always should be tracked at high
* precision. This disables adaptive access path precision for such access paths.
*/
predicate forceHighPrecision(Content c) { c instanceof Content::ArrayElementContent }
predicate forceHighPrecision(Content c) { c instanceof Content::ElementContent }
/** The unit type. */
private newtype TUnit = TMkUnit()

View File

@@ -203,24 +203,32 @@ class Content extends TContent {
/** Provides different sub classes of `Content`. */
module Content {
/** An element in an array. */
class ArrayElementContent extends Content, TArrayElementContent { }
/** An element in an collection, for example an element in array or in a hash. */
class ElementContent extends Content, TElementContent { }
/** An element in an array at a known index. */
class KnownArrayElementContent extends ArrayElementContent, TKnownArrayElementContent {
private int i;
/** An element in a collection at a known index. */
class KnownElementContent extends ElementContent, TKnownElementContent {
private ConstantValue cv;
KnownArrayElementContent() { this = TKnownArrayElementContent(i) }
KnownElementContent() { this = TKnownElementContent(cv) }
/** Gets the index in the array. */
int getIndex() { result = i }
/** Gets the index in the collection. */
ConstantValue getIndex() { result = cv }
override string toString() { result = "array element " + i }
override string toString() { result = "element " + cv }
}
/** An element in an array at an unknown index. */
class UnknownArrayElementContent extends ArrayElementContent, TUnknownArrayElementContent {
override string toString() { result = "array element" }
/** An element in a collection at an unknown index. */
class UnknownElementContent extends ElementContent, TUnknownElementContent {
override string toString() { result = "element" }
}
/** Gets the element content corresponding to constant value `cv`. */
ElementContent getElementContent(ConstantValue cv) {
result = TKnownElementContent(cv)
or
not exists(TKnownElementContent(cv)) and
result = TUnknownElementContent()
}
}
@@ -234,8 +242,8 @@ class ContentSet extends TContentSet {
/** Holds if this content set is the singleton `{c}`. */
predicate isSingleton(Content c) { this = TSingletonContent(c) }
/** Holds if this content set represent all `ArrayElementContent`s. */
predicate isAnyArrayElement() { this = TAnyArrayElementContent() }
/** Holds if this content set represents all `ElementContent`s. */
predicate isAnyElement() { this = TAnyElementContent() }
/** Gets a textual representation of this content set. */
string toString() {
@@ -244,7 +252,7 @@ class ContentSet extends TContentSet {
result = c.toString()
)
or
this.isAnyArrayElement() and
this.isAnyElement() and
result = "any array element"
}
@@ -252,16 +260,16 @@ class ContentSet extends TContentSet {
Content getAStoreContent() {
this.isSingleton(result)
or
this.isAnyArrayElement() and
result = TUnknownArrayElementContent()
this.isAnyElement() and
result = TUnknownElementContent()
}
/** Gets a content that may be read from when reading from this set. */
Content getAReadContent() {
this.isSingleton(result)
or
this.isAnyArrayElement() and
result instanceof Content::ArrayElementContent
this.isAnyElement() and
result instanceof Content::ElementContent
}
}

View File

@@ -73,18 +73,20 @@ SummaryComponent interpretComponentSpecific(AccessPathToken c) {
ppos.isPositionalLowerBound(AccessPath::parseLowerBound(arg))
)
or
c.getName() = "ArrayElement" and
c.getName() = "Element" and
(
c.getNumArgument() = 0 and
result = FlowSummary::SummaryComponent::arrayElementAny()
result = FlowSummary::SummaryComponent::elementAny()
or
exists(string arg | arg = c.getAnArgument() |
arg = "?" and
result = FlowSummary::SummaryComponent::arrayElementUnknown()
result = FlowSummary::SummaryComponent::elementUnknown()
or
exists(int i |
i = AccessPath::parseInt(c.getAnArgument()) and
result = FlowSummary::SummaryComponent::arrayElementKnown(i)
exists(ConstantValue cv | result = FlowSummary::SummaryComponent::elementKnown(cv) |
cv.isInt(AccessPath::parseInt(arg))
or
not exists(AccessPath::parseInt(arg)) and
cv.serialize() = c.getAnArgument()
)
)
)

View File

@@ -103,9 +103,9 @@ private module Cached {
// allow flow out of a _tainted_ collection. This is needed in order to support taint-
// tracking configurations where the source is a collection.
exists(DataFlow::ContentSet c | readStep(nodeFrom, c, nodeTo) |
c.isSingleton(any(DataFlow::Content::ArrayElementContent aec))
c.isSingleton(any(DataFlow::Content::ElementContent ec))
or
c.isAnyArrayElement()
c.isAnyElement()
)
}

View File

@@ -62,7 +62,7 @@ private class SplatSummary extends SummarizedCallable {
(
// *1 = [1]
input = "Argument[self]" and
output = "ReturnValue.ArrayElement[0]"
output = "ReturnValue.Element[0]"
or
// *[1] = [1]
input = "Argument[self]" and

File diff suppressed because it is too large Load Diff

View File

@@ -133,7 +133,7 @@ module String {
FormatSummary() { this = "%" }
override predicate propagatesFlowExt(string input, string output, boolean preservesValue) {
input = ["Argument[self]", "Argument[0]", "Argument[0].ArrayElement"] and
input = ["Argument[self]", "Argument[0]", "Argument[0].Element"] and
output = "ReturnValue" and
preservesValue = false
}
@@ -301,7 +301,7 @@ module String {
override predicate propagatesFlowExt(string input, string output, boolean preservesValue) {
preservesValue = false and
input = "Argument[self]" and
output = "ReturnValue.ArrayElement[?]"
output = "ReturnValue.Element[?]"
}
}
@@ -415,7 +415,7 @@ module String {
override predicate propagatesFlowExt(string input, string output, boolean preservesValue) {
input = "Argument[self]" and
output = "ReturnValue.ArrayElement[" + [0, 1, 2] + "]" and
output = "ReturnValue.Element[" + [0, 1, 2] + "]" and
preservesValue = false
}
}
@@ -480,7 +480,7 @@ module String {
override predicate propagatesFlowExt(string input, string output, boolean preservesValue) {
// scan(pattern) -> array
input = "Argument[self]" and
output = "ReturnValue.ArrayElement[?]" and
output = "ReturnValue.Element[?]" and
preservesValue = false
}
}
@@ -547,7 +547,7 @@ module String {
override predicate propagatesFlowExt(string input, string output, boolean preservesValue) {
input = "Argument[self]" and
output = "ReturnValue.ArrayElement[?]" and
output = "ReturnValue.Element[?]" and
preservesValue = false
}
}
@@ -631,7 +631,7 @@ module String {
preservesValue = false
or
input = "Argument[block].ReturnValue" and
output = "ReturnValue.ArrayElement[?]" and
output = "ReturnValue.Element[?]" and
preservesValue = false
}
}
@@ -651,7 +651,7 @@ module String {
preservesValue = false
or
input = "Argument[block].ReturnValue" and
output = "ReturnValue.ArrayElement[?]" and
output = "ReturnValue.Element[?]" and
preservesValue = false
}
}

View File

@@ -113,8 +113,8 @@ API::Node getExtraSuccessorFromNode(API::Node node, AccessPathToken token) {
result =
node.getASuccessor(API::Label::getLabelFromArgumentPosition(FlowSummaryImplSpecific::parseParamBody(token
.getAnArgument())))
// Note: The "ArrayElement" token is not implemented yet, as it ultimately requires type-tracking and
// API graphs to be aware of the steps involving ArrayElement contributed by the standard library model.
// Note: The "Element" token is not implemented yet, as it ultimately requires type-tracking and
// API graphs to be aware of the steps involving Element contributed by the standard library model.
// Type-tracking cannot summarize function calls on its own, so it doesn't benefit from synthesized callables.
}

View File

@@ -90,19 +90,19 @@ edges
| string_flow.rb:133:9:133:9 | a : | string_flow.rb:133:24:133:27 | line : |
| string_flow.rb:133:9:133:40 | call to each_line : | string_flow.rb:134:10:134:10 | b |
| string_flow.rb:133:24:133:27 | line : | string_flow.rb:133:35:133:38 | line |
| string_flow.rb:135:9:135:9 | a : | string_flow.rb:135:9:135:19 | call to each_line [array element] : |
| string_flow.rb:135:9:135:19 | call to each_line [array element] : | string_flow.rb:136:10:136:10 | c [array element] : |
| string_flow.rb:136:10:136:10 | c [array element] : | string_flow.rb:136:10:136:15 | call to to_a [array element] : |
| string_flow.rb:136:10:136:15 | call to to_a [array element] : | string_flow.rb:136:10:136:18 | ...[...] |
| string_flow.rb:135:9:135:9 | a : | string_flow.rb:135:9:135:19 | call to each_line [element] : |
| string_flow.rb:135:9:135:19 | call to each_line [element] : | string_flow.rb:136:10:136:10 | c [element] : |
| string_flow.rb:136:10:136:10 | c [element] : | string_flow.rb:136:10:136:15 | call to to_a [element] : |
| string_flow.rb:136:10:136:15 | call to to_a [element] : | string_flow.rb:136:10:136:18 | ...[...] |
| string_flow.rb:140:9:140:18 | call to source : | string_flow.rb:141:9:141:9 | a : |
| string_flow.rb:140:9:140:18 | call to source : | string_flow.rb:143:9:143:9 | a : |
| string_flow.rb:141:9:141:9 | a : | string_flow.rb:141:9:141:36 | call to lines : |
| string_flow.rb:141:9:141:9 | a : | string_flow.rb:141:20:141:23 | line : |
| string_flow.rb:141:9:141:36 | call to lines : | string_flow.rb:142:10:142:10 | b |
| string_flow.rb:141:20:141:23 | line : | string_flow.rb:141:31:141:34 | line |
| string_flow.rb:143:9:143:9 | a : | string_flow.rb:143:9:143:15 | call to lines [array element] : |
| string_flow.rb:143:9:143:15 | call to lines [array element] : | string_flow.rb:144:10:144:10 | c [array element] : |
| string_flow.rb:144:10:144:10 | c [array element] : | string_flow.rb:144:10:144:13 | ...[...] |
| string_flow.rb:143:9:143:9 | a : | string_flow.rb:143:9:143:15 | call to lines [element] : |
| string_flow.rb:143:9:143:15 | call to lines [element] : | string_flow.rb:144:10:144:10 | c [element] : |
| string_flow.rb:144:10:144:10 | c [element] : | string_flow.rb:144:10:144:13 | ...[...] |
| string_flow.rb:148:9:148:18 | call to source : | string_flow.rb:149:10:149:10 | a : |
| string_flow.rb:148:9:148:18 | call to source : | string_flow.rb:150:10:150:10 | a : |
| string_flow.rb:148:9:148:18 | call to source : | string_flow.rb:151:10:151:10 | a : |
@@ -166,15 +166,15 @@ edges
| string_flow.rb:209:10:209:10 | a : | string_flow.rb:209:10:209:15 | call to succ |
| string_flow.rb:210:10:210:10 | a : | string_flow.rb:210:10:210:16 | call to succ! |
| string_flow.rb:214:9:214:18 | call to source : | string_flow.rb:215:9:215:9 | a : |
| string_flow.rb:215:9:215:9 | a : | string_flow.rb:215:9:215:24 | call to partition [array element 0] : |
| string_flow.rb:215:9:215:9 | a : | string_flow.rb:215:9:215:24 | call to partition [array element 1] : |
| string_flow.rb:215:9:215:9 | a : | string_flow.rb:215:9:215:24 | call to partition [array element 2] : |
| string_flow.rb:215:9:215:24 | call to partition [array element 0] : | string_flow.rb:216:10:216:10 | b [array element 0] : |
| string_flow.rb:215:9:215:24 | call to partition [array element 1] : | string_flow.rb:217:10:217:10 | b [array element 1] : |
| string_flow.rb:215:9:215:24 | call to partition [array element 2] : | string_flow.rb:218:10:218:10 | b [array element 2] : |
| string_flow.rb:216:10:216:10 | b [array element 0] : | string_flow.rb:216:10:216:13 | ...[...] |
| string_flow.rb:217:10:217:10 | b [array element 1] : | string_flow.rb:217:10:217:13 | ...[...] |
| string_flow.rb:218:10:218:10 | b [array element 2] : | string_flow.rb:218:10:218:13 | ...[...] |
| string_flow.rb:215:9:215:9 | a : | string_flow.rb:215:9:215:24 | call to partition [element 0] : |
| string_flow.rb:215:9:215:9 | a : | string_flow.rb:215:9:215:24 | call to partition [element 1] : |
| string_flow.rb:215:9:215:9 | a : | string_flow.rb:215:9:215:24 | call to partition [element 2] : |
| string_flow.rb:215:9:215:24 | call to partition [element 0] : | string_flow.rb:216:10:216:10 | b [element 0] : |
| string_flow.rb:215:9:215:24 | call to partition [element 1] : | string_flow.rb:217:10:217:10 | b [element 1] : |
| string_flow.rb:215:9:215:24 | call to partition [element 2] : | string_flow.rb:218:10:218:10 | b [element 2] : |
| string_flow.rb:216:10:216:10 | b [element 0] : | string_flow.rb:216:10:216:13 | ...[...] |
| string_flow.rb:217:10:217:10 | b [element 1] : | string_flow.rb:217:10:217:13 | ...[...] |
| string_flow.rb:218:10:218:10 | b [element 2] : | string_flow.rb:218:10:218:13 | ...[...] |
| string_flow.rb:223:9:223:18 | call to source : | string_flow.rb:225:10:225:10 | a : |
| string_flow.rb:223:9:223:18 | call to source : | string_flow.rb:225:10:225:10 | a : |
| string_flow.rb:224:9:224:18 | call to source : | string_flow.rb:225:20:225:20 | b : |
@@ -195,11 +195,11 @@ edges
| string_flow.rb:238:9:238:9 | a : | string_flow.rb:238:27:238:27 | y : |
| string_flow.rb:238:9:238:37 | call to scan : | string_flow.rb:239:10:239:10 | b |
| string_flow.rb:238:27:238:27 | y : | string_flow.rb:238:35:238:35 | y |
| string_flow.rb:240:9:240:9 | a : | string_flow.rb:240:9:240:19 | call to scan [array element] : |
| string_flow.rb:240:9:240:19 | call to scan [array element] : | string_flow.rb:241:10:241:10 | b [array element] : |
| string_flow.rb:240:9:240:19 | call to scan [array element] : | string_flow.rb:242:10:242:10 | b [array element] : |
| string_flow.rb:241:10:241:10 | b [array element] : | string_flow.rb:241:10:241:13 | ...[...] |
| string_flow.rb:242:10:242:10 | b [array element] : | string_flow.rb:242:10:242:13 | ...[...] |
| string_flow.rb:240:9:240:9 | a : | string_flow.rb:240:9:240:19 | call to scan [element] : |
| string_flow.rb:240:9:240:19 | call to scan [element] : | string_flow.rb:241:10:241:10 | b [element] : |
| string_flow.rb:240:9:240:19 | call to scan [element] : | string_flow.rb:242:10:242:10 | b [element] : |
| string_flow.rb:241:10:241:10 | b [element] : | string_flow.rb:241:10:241:13 | ...[...] |
| string_flow.rb:242:10:242:10 | b [element] : | string_flow.rb:242:10:242:13 | ...[...] |
| string_flow.rb:246:5:246:18 | ... = ... : | string_flow.rb:250:26:250:26 | a : |
| string_flow.rb:246:9:246:18 | call to source : | string_flow.rb:246:5:246:18 | ... = ... : |
| string_flow.rb:246:9:246:18 | call to source : | string_flow.rb:247:10:247:10 | a : |
@@ -223,9 +223,9 @@ edges
| string_flow.rb:262:9:262:18 | call to source : | string_flow.rb:263:10:263:10 | a : |
| string_flow.rb:263:10:263:10 | a : | string_flow.rb:263:10:263:22 | call to shellescape |
| string_flow.rb:267:9:267:18 | call to source : | string_flow.rb:268:9:268:9 | a : |
| string_flow.rb:268:9:268:9 | a : | string_flow.rb:268:9:268:20 | call to shellsplit [array element] : |
| string_flow.rb:268:9:268:20 | call to shellsplit [array element] : | string_flow.rb:269:10:269:10 | b [array element] : |
| string_flow.rb:269:10:269:10 | b [array element] : | string_flow.rb:269:10:269:13 | ...[...] |
| string_flow.rb:268:9:268:9 | a : | string_flow.rb:268:9:268:20 | call to shellsplit [element] : |
| string_flow.rb:268:9:268:20 | call to shellsplit [element] : | string_flow.rb:269:10:269:10 | b [element] : |
| string_flow.rb:269:10:269:10 | b [element] : | string_flow.rb:269:10:269:13 | ...[...] |
| string_flow.rb:273:9:273:18 | call to source : | string_flow.rb:274:9:274:9 | a : |
| string_flow.rb:273:9:273:18 | call to source : | string_flow.rb:277:9:277:9 | a : |
| string_flow.rb:274:9:274:9 | a : | string_flow.rb:274:9:274:18 | call to slice : |
@@ -233,13 +233,13 @@ edges
| string_flow.rb:275:10:275:10 | b : | string_flow.rb:275:10:275:13 | ...[...] |
| string_flow.rb:277:9:277:9 | [post] a : | string_flow.rb:280:9:280:9 | a : |
| string_flow.rb:277:9:277:9 | [post] a : | string_flow.rb:283:9:283:9 | a : |
| string_flow.rb:277:9:277:9 | [post] a [array element 1] : | string_flow.rb:283:9:283:9 | a [array element 1] : |
| string_flow.rb:277:9:277:9 | [post] a [array element 2] : | string_flow.rb:283:9:283:9 | a [array element 2] : |
| string_flow.rb:277:9:277:9 | [post] a [array element] : | string_flow.rb:283:9:283:9 | a [array element] : |
| string_flow.rb:277:9:277:9 | [post] a [element 1] : | string_flow.rb:283:9:283:9 | a [element 1] : |
| string_flow.rb:277:9:277:9 | [post] a [element 2] : | string_flow.rb:283:9:283:9 | a [element 2] : |
| string_flow.rb:277:9:277:9 | [post] a [element] : | string_flow.rb:283:9:283:9 | a [element] : |
| string_flow.rb:277:9:277:9 | a : | string_flow.rb:277:9:277:9 | [post] a : |
| string_flow.rb:277:9:277:9 | a : | string_flow.rb:277:9:277:9 | [post] a [array element 1] : |
| string_flow.rb:277:9:277:9 | a : | string_flow.rb:277:9:277:9 | [post] a [array element 2] : |
| string_flow.rb:277:9:277:9 | a : | string_flow.rb:277:9:277:9 | [post] a [array element] : |
| string_flow.rb:277:9:277:9 | a : | string_flow.rb:277:9:277:9 | [post] a [element 1] : |
| string_flow.rb:277:9:277:9 | a : | string_flow.rb:277:9:277:9 | [post] a [element 2] : |
| string_flow.rb:277:9:277:9 | a : | string_flow.rb:277:9:277:9 | [post] a [element] : |
| string_flow.rb:277:9:277:9 | a : | string_flow.rb:277:9:277:19 | call to slice! : |
| string_flow.rb:277:9:277:19 | call to slice! : | string_flow.rb:278:10:278:10 | b : |
| string_flow.rb:278:10:278:10 | b : | string_flow.rb:278:10:278:13 | ...[...] |
@@ -247,20 +247,20 @@ edges
| string_flow.rb:280:9:280:20 | call to split : | string_flow.rb:281:10:281:10 | b : |
| string_flow.rb:281:10:281:10 | b : | string_flow.rb:281:10:281:13 | ...[...] |
| string_flow.rb:283:9:283:9 | a : | string_flow.rb:283:9:283:14 | ...[...] : |
| string_flow.rb:283:9:283:9 | a : | string_flow.rb:283:9:283:14 | ...[...] [array element 0] : |
| string_flow.rb:283:9:283:9 | a : | string_flow.rb:283:9:283:14 | ...[...] [array element 1] : |
| string_flow.rb:283:9:283:9 | a : | string_flow.rb:283:9:283:14 | ...[...] [array element] : |
| string_flow.rb:283:9:283:9 | a [array element 1] : | string_flow.rb:283:9:283:14 | ...[...] [array element 0] : |
| string_flow.rb:283:9:283:9 | a [array element 2] : | string_flow.rb:283:9:283:14 | ...[...] [array element 1] : |
| string_flow.rb:283:9:283:9 | a [array element] : | string_flow.rb:283:9:283:14 | ...[...] [array element] : |
| string_flow.rb:283:9:283:9 | a : | string_flow.rb:283:9:283:14 | ...[...] [element 0] : |
| string_flow.rb:283:9:283:9 | a : | string_flow.rb:283:9:283:14 | ...[...] [element 1] : |
| string_flow.rb:283:9:283:9 | a : | string_flow.rb:283:9:283:14 | ...[...] [element] : |
| string_flow.rb:283:9:283:9 | a [element 1] : | string_flow.rb:283:9:283:14 | ...[...] [element 0] : |
| string_flow.rb:283:9:283:9 | a [element 2] : | string_flow.rb:283:9:283:14 | ...[...] [element 1] : |
| string_flow.rb:283:9:283:9 | a [element] : | string_flow.rb:283:9:283:14 | ...[...] [element] : |
| string_flow.rb:283:9:283:14 | ...[...] : | string_flow.rb:284:10:284:10 | b : |
| string_flow.rb:283:9:283:14 | ...[...] [array element 0] : | string_flow.rb:284:10:284:10 | b [array element 0] : |
| string_flow.rb:283:9:283:14 | ...[...] [array element 1] : | string_flow.rb:284:10:284:10 | b [array element 1] : |
| string_flow.rb:283:9:283:14 | ...[...] [array element] : | string_flow.rb:284:10:284:10 | b [array element] : |
| string_flow.rb:283:9:283:14 | ...[...] [element 0] : | string_flow.rb:284:10:284:10 | b [element 0] : |
| string_flow.rb:283:9:283:14 | ...[...] [element 1] : | string_flow.rb:284:10:284:10 | b [element 1] : |
| string_flow.rb:283:9:283:14 | ...[...] [element] : | string_flow.rb:284:10:284:10 | b [element] : |
| string_flow.rb:284:10:284:10 | b : | string_flow.rb:284:10:284:13 | ...[...] |
| string_flow.rb:284:10:284:10 | b [array element 0] : | string_flow.rb:284:10:284:13 | ...[...] |
| string_flow.rb:284:10:284:10 | b [array element 1] : | string_flow.rb:284:10:284:13 | ...[...] |
| string_flow.rb:284:10:284:10 | b [array element] : | string_flow.rb:284:10:284:13 | ...[...] |
| string_flow.rb:284:10:284:10 | b [element 0] : | string_flow.rb:284:10:284:13 | ...[...] |
| string_flow.rb:284:10:284:10 | b [element 1] : | string_flow.rb:284:10:284:13 | ...[...] |
| string_flow.rb:284:10:284:10 | b [element] : | string_flow.rb:284:10:284:13 | ...[...] |
| string_flow.rb:288:9:288:18 | call to source : | string_flow.rb:289:10:289:10 | a : |
| string_flow.rb:288:9:288:18 | call to source : | string_flow.rb:290:10:290:10 | a : |
| string_flow.rb:288:9:288:18 | call to source : | string_flow.rb:291:10:291:10 | a : |
@@ -405,9 +405,9 @@ nodes
| string_flow.rb:133:35:133:38 | line | semmle.label | line |
| string_flow.rb:134:10:134:10 | b | semmle.label | b |
| string_flow.rb:135:9:135:9 | a : | semmle.label | a : |
| string_flow.rb:135:9:135:19 | call to each_line [array element] : | semmle.label | call to each_line [array element] : |
| string_flow.rb:136:10:136:10 | c [array element] : | semmle.label | c [array element] : |
| string_flow.rb:136:10:136:15 | call to to_a [array element] : | semmle.label | call to to_a [array element] : |
| string_flow.rb:135:9:135:19 | call to each_line [element] : | semmle.label | call to each_line [element] : |
| string_flow.rb:136:10:136:10 | c [element] : | semmle.label | c [element] : |
| string_flow.rb:136:10:136:15 | call to to_a [element] : | semmle.label | call to to_a [element] : |
| string_flow.rb:136:10:136:18 | ...[...] | semmle.label | ...[...] |
| string_flow.rb:140:9:140:18 | call to source : | semmle.label | call to source : |
| string_flow.rb:141:9:141:9 | a : | semmle.label | a : |
@@ -416,8 +416,8 @@ nodes
| string_flow.rb:141:31:141:34 | line | semmle.label | line |
| string_flow.rb:142:10:142:10 | b | semmle.label | b |
| string_flow.rb:143:9:143:9 | a : | semmle.label | a : |
| string_flow.rb:143:9:143:15 | call to lines [array element] : | semmle.label | call to lines [array element] : |
| string_flow.rb:144:10:144:10 | c [array element] : | semmle.label | c [array element] : |
| string_flow.rb:143:9:143:15 | call to lines [element] : | semmle.label | call to lines [element] : |
| string_flow.rb:144:10:144:10 | c [element] : | semmle.label | c [element] : |
| string_flow.rb:144:10:144:13 | ...[...] | semmle.label | ...[...] |
| string_flow.rb:148:9:148:18 | call to source : | semmle.label | call to source : |
| string_flow.rb:149:10:149:10 | a : | semmle.label | a : |
@@ -489,14 +489,14 @@ nodes
| string_flow.rb:210:10:210:16 | call to succ! | semmle.label | call to succ! |
| string_flow.rb:214:9:214:18 | call to source : | semmle.label | call to source : |
| string_flow.rb:215:9:215:9 | a : | semmle.label | a : |
| string_flow.rb:215:9:215:24 | call to partition [array element 0] : | semmle.label | call to partition [array element 0] : |
| string_flow.rb:215:9:215:24 | call to partition [array element 1] : | semmle.label | call to partition [array element 1] : |
| string_flow.rb:215:9:215:24 | call to partition [array element 2] : | semmle.label | call to partition [array element 2] : |
| string_flow.rb:216:10:216:10 | b [array element 0] : | semmle.label | b [array element 0] : |
| string_flow.rb:215:9:215:24 | call to partition [element 0] : | semmle.label | call to partition [element 0] : |
| string_flow.rb:215:9:215:24 | call to partition [element 1] : | semmle.label | call to partition [element 1] : |
| string_flow.rb:215:9:215:24 | call to partition [element 2] : | semmle.label | call to partition [element 2] : |
| string_flow.rb:216:10:216:10 | b [element 0] : | semmle.label | b [element 0] : |
| string_flow.rb:216:10:216:13 | ...[...] | semmle.label | ...[...] |
| string_flow.rb:217:10:217:10 | b [array element 1] : | semmle.label | b [array element 1] : |
| string_flow.rb:217:10:217:10 | b [element 1] : | semmle.label | b [element 1] : |
| string_flow.rb:217:10:217:13 | ...[...] | semmle.label | ...[...] |
| string_flow.rb:218:10:218:10 | b [array element 2] : | semmle.label | b [array element 2] : |
| string_flow.rb:218:10:218:10 | b [element 2] : | semmle.label | b [element 2] : |
| string_flow.rb:218:10:218:13 | ...[...] | semmle.label | ...[...] |
| string_flow.rb:223:9:223:18 | call to source : | semmle.label | call to source : |
| string_flow.rb:223:9:223:18 | call to source : | semmle.label | call to source : |
@@ -522,10 +522,10 @@ nodes
| string_flow.rb:238:35:238:35 | y | semmle.label | y |
| string_flow.rb:239:10:239:10 | b | semmle.label | b |
| string_flow.rb:240:9:240:9 | a : | semmle.label | a : |
| string_flow.rb:240:9:240:19 | call to scan [array element] : | semmle.label | call to scan [array element] : |
| string_flow.rb:241:10:241:10 | b [array element] : | semmle.label | b [array element] : |
| string_flow.rb:240:9:240:19 | call to scan [element] : | semmle.label | call to scan [element] : |
| string_flow.rb:241:10:241:10 | b [element] : | semmle.label | b [element] : |
| string_flow.rb:241:10:241:13 | ...[...] | semmle.label | ...[...] |
| string_flow.rb:242:10:242:10 | b [array element] : | semmle.label | b [array element] : |
| string_flow.rb:242:10:242:10 | b [element] : | semmle.label | b [element] : |
| string_flow.rb:242:10:242:13 | ...[...] | semmle.label | ...[...] |
| string_flow.rb:246:5:246:18 | ... = ... : | semmle.label | ... = ... : |
| string_flow.rb:246:9:246:18 | call to source : | semmle.label | call to source : |
@@ -554,8 +554,8 @@ nodes
| string_flow.rb:263:10:263:22 | call to shellescape | semmle.label | call to shellescape |
| string_flow.rb:267:9:267:18 | call to source : | semmle.label | call to source : |
| string_flow.rb:268:9:268:9 | a : | semmle.label | a : |
| string_flow.rb:268:9:268:20 | call to shellsplit [array element] : | semmle.label | call to shellsplit [array element] : |
| string_flow.rb:269:10:269:10 | b [array element] : | semmle.label | b [array element] : |
| string_flow.rb:268:9:268:20 | call to shellsplit [element] : | semmle.label | call to shellsplit [element] : |
| string_flow.rb:269:10:269:10 | b [element] : | semmle.label | b [element] : |
| string_flow.rb:269:10:269:13 | ...[...] | semmle.label | ...[...] |
| string_flow.rb:273:9:273:18 | call to source : | semmle.label | call to source : |
| string_flow.rb:274:9:274:9 | a : | semmle.label | a : |
@@ -563,9 +563,9 @@ nodes
| string_flow.rb:275:10:275:10 | b : | semmle.label | b : |
| string_flow.rb:275:10:275:13 | ...[...] | semmle.label | ...[...] |
| string_flow.rb:277:9:277:9 | [post] a : | semmle.label | [post] a : |
| string_flow.rb:277:9:277:9 | [post] a [array element 1] : | semmle.label | [post] a [array element 1] : |
| string_flow.rb:277:9:277:9 | [post] a [array element 2] : | semmle.label | [post] a [array element 2] : |
| string_flow.rb:277:9:277:9 | [post] a [array element] : | semmle.label | [post] a [array element] : |
| string_flow.rb:277:9:277:9 | [post] a [element 1] : | semmle.label | [post] a [element 1] : |
| string_flow.rb:277:9:277:9 | [post] a [element 2] : | semmle.label | [post] a [element 2] : |
| string_flow.rb:277:9:277:9 | [post] a [element] : | semmle.label | [post] a [element] : |
| string_flow.rb:277:9:277:9 | a : | semmle.label | a : |
| string_flow.rb:277:9:277:19 | call to slice! : | semmle.label | call to slice! : |
| string_flow.rb:278:10:278:10 | b : | semmle.label | b : |
@@ -575,17 +575,17 @@ nodes
| string_flow.rb:281:10:281:10 | b : | semmle.label | b : |
| string_flow.rb:281:10:281:13 | ...[...] | semmle.label | ...[...] |
| string_flow.rb:283:9:283:9 | a : | semmle.label | a : |
| string_flow.rb:283:9:283:9 | a [array element 1] : | semmle.label | a [array element 1] : |
| string_flow.rb:283:9:283:9 | a [array element 2] : | semmle.label | a [array element 2] : |
| string_flow.rb:283:9:283:9 | a [array element] : | semmle.label | a [array element] : |
| string_flow.rb:283:9:283:9 | a [element 1] : | semmle.label | a [element 1] : |
| string_flow.rb:283:9:283:9 | a [element 2] : | semmle.label | a [element 2] : |
| string_flow.rb:283:9:283:9 | a [element] : | semmle.label | a [element] : |
| string_flow.rb:283:9:283:14 | ...[...] : | semmle.label | ...[...] : |
| string_flow.rb:283:9:283:14 | ...[...] [array element 0] : | semmle.label | ...[...] [array element 0] : |
| string_flow.rb:283:9:283:14 | ...[...] [array element 1] : | semmle.label | ...[...] [array element 1] : |
| string_flow.rb:283:9:283:14 | ...[...] [array element] : | semmle.label | ...[...] [array element] : |
| string_flow.rb:283:9:283:14 | ...[...] [element 0] : | semmle.label | ...[...] [element 0] : |
| string_flow.rb:283:9:283:14 | ...[...] [element 1] : | semmle.label | ...[...] [element 1] : |
| string_flow.rb:283:9:283:14 | ...[...] [element] : | semmle.label | ...[...] [element] : |
| string_flow.rb:284:10:284:10 | b : | semmle.label | b : |
| string_flow.rb:284:10:284:10 | b [array element 0] : | semmle.label | b [array element 0] : |
| string_flow.rb:284:10:284:10 | b [array element 1] : | semmle.label | b [array element 1] : |
| string_flow.rb:284:10:284:10 | b [array element] : | semmle.label | b [array element] : |
| string_flow.rb:284:10:284:10 | b [element 0] : | semmle.label | b [element 0] : |
| string_flow.rb:284:10:284:10 | b [element 1] : | semmle.label | b [element 1] : |
| string_flow.rb:284:10:284:10 | b [element] : | semmle.label | b [element] : |
| string_flow.rb:284:10:284:13 | ...[...] | semmle.label | ...[...] |
| string_flow.rb:288:9:288:18 | call to source : | semmle.label | call to source : |
| string_flow.rb:289:10:289:10 | a : | semmle.label | a : |

View File

@@ -133,7 +133,6 @@ nodes
| summaries.rb:71:26:71:56 | call to source : | semmle.label | call to source : |
subpaths
invalidSpecComponent
invalidOutputSpecComponent
#select
| summaries.rb:2:6:2:12 | tainted | summaries.rb:1:20:1:36 | call to source : | summaries.rb:2:6:2:12 | tainted | $@ | summaries.rb:1:20:1:36 | call to source : | call to source : |
| summaries.rb:2:6:2:12 | tainted | summaries.rb:1:20:1:36 | call to source : | summaries.rb:2:6:2:12 | tainted | $@ | summaries.rb:1:20:1:36 | call to source : | call to source : |

View File

@@ -18,12 +18,6 @@ query predicate invalidSpecComponent(SummarizedCallable sc, string s, string c)
query predicate warning = ModelOutput::getAWarning/0;
query predicate invalidOutputSpecComponent(SummarizedCallable sc, AccessPath s, AccessPathToken c) {
sc.propagatesFlowExt(_, s, _) and
c = s.getToken(_) and
c = "ArrayElement" // not allowed in output specs; use `ArrayElement[?] instead
}
private class SummarizedCallableIdentity extends SummarizedCallable {
SummarizedCallableIdentity() { this = "identity" }