mirror of
https://github.com/github/codeql.git
synced 2026-04-28 18:25:24 +02:00
Ruby: Introduce ContentSet::isElementOfType[OrUnknown]/1
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
private import codeql.util.Boolean
|
||||
private import codeql.ruby.AST
|
||||
private import codeql.ruby.ast.internal.Synthesis
|
||||
private import codeql.ruby.CFG
|
||||
@@ -456,12 +457,15 @@ private module Cached {
|
||||
FlowSummaryImplSpecific::ParsePositions::isParsedElementLowerBoundPosition(_, includeUnknown,
|
||||
lower)
|
||||
} or
|
||||
TElementContentOfTypeContent(string type, Boolean includeUnknown) {
|
||||
type = any(Content::KnownElementContent content).getIndex().getValueType()
|
||||
} or
|
||||
TNoContentSet() // Only used by type-tracking
|
||||
|
||||
cached
|
||||
class TContentSet =
|
||||
TSingletonContent or TAnyElementContent or TKnownOrUnknownElementContent or
|
||||
TElementLowerBoundContent;
|
||||
TElementLowerBoundContent or TElementContentOfTypeContent;
|
||||
|
||||
private predicate trackKnownValue(ConstantValue cv) {
|
||||
not cv.isFloat(_) and
|
||||
|
||||
@@ -534,6 +534,21 @@ class ContentSet extends TContentSet {
|
||||
this = TElementLowerBoundContent(lower, true)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if this content set represents all `KnownElementContent`s where
|
||||
* the index is of type `type`, as per `ConstantValue::getValueType/0`.
|
||||
*/
|
||||
predicate isElementOfType(string type) { this = TElementContentOfTypeContent(type, false) }
|
||||
|
||||
/**
|
||||
* Holds if this content set represents `UnknownElementContent` unioned with
|
||||
* all `KnownElementContent`s where the index is of type `type`, as per
|
||||
* `ConstantValue::getValueType/0`.
|
||||
*/
|
||||
predicate isElementOfTypeOrUnknown(string type) {
|
||||
this = TElementContentOfTypeContent(type, true)
|
||||
}
|
||||
|
||||
/** Gets a textual representation of this content set. */
|
||||
string toString() {
|
||||
exists(Content c |
|
||||
@@ -558,6 +573,16 @@ class ContentSet extends TContentSet {
|
||||
includeUnknown = true and
|
||||
result = lower + ".."
|
||||
)
|
||||
or
|
||||
exists(string type, boolean includeUnknown |
|
||||
this = TElementContentOfTypeContent(type, includeUnknown)
|
||||
|
|
||||
includeUnknown = false and
|
||||
result = "any(" + type + ")!"
|
||||
or
|
||||
includeUnknown = true and
|
||||
result = "any(" + type + ")"
|
||||
)
|
||||
}
|
||||
|
||||
/** Gets a content that may be stored into when storing into this set. */
|
||||
@@ -576,7 +601,14 @@ class ContentSet extends TContentSet {
|
||||
// step that store only into `1`
|
||||
this.isKnownOrUnknownElement(result)
|
||||
or
|
||||
this.isElementLowerBound(_) and
|
||||
// These reverse stores are not as accurate as they could be, but making
|
||||
// them more accurate would result in a large fan-out
|
||||
(
|
||||
this.isElementLowerBound(_) or
|
||||
this.isElementLowerBoundOrUnknown(_) or
|
||||
this.isElementOfType(_) or
|
||||
this.isElementOfTypeOrUnknown(_)
|
||||
) and
|
||||
result = TUnknownElementContent()
|
||||
}
|
||||
|
||||
@@ -603,6 +635,15 @@ class ContentSet extends TContentSet {
|
||||
includeUnknown = true and
|
||||
result = TUnknownElementContent()
|
||||
)
|
||||
or
|
||||
exists(string type, boolean includeUnknown |
|
||||
this = TElementContentOfTypeContent(type, includeUnknown)
|
||||
|
|
||||
type = result.(Content::KnownElementContent).getIndex().getValueType()
|
||||
or
|
||||
includeUnknown = true and
|
||||
result = TUnknownElementContent()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -34,8 +34,6 @@ class Configuration extends TaintTracking::Configuration {
|
||||
override predicate allowImplicitRead(DataFlow::Node node, DataFlow::ContentSet set) {
|
||||
// allow implicit reads of array elements
|
||||
this.isSink(node) and
|
||||
set.isKnownOrUnknownElement(any(DataFlow::Content::KnownElementContent content |
|
||||
content.getIndex().getValueType() = "int"
|
||||
))
|
||||
set.isElementOfTypeOrUnknown("int")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,8 +36,6 @@ class Configuration extends TaintTracking::Configuration {
|
||||
override predicate allowImplicitRead(DataFlow::Node node, DataFlow::ContentSet set) {
|
||||
// allow implicit reads of array elements
|
||||
this.isSink(node) and
|
||||
set.isKnownOrUnknownElement(any(DataFlow::Content::KnownElementContent content |
|
||||
content.getIndex().getValueType() = "int"
|
||||
))
|
||||
set.isElementOfTypeOrUnknown("int")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -449,6 +449,8 @@ private ContentFilter getFilterFromWithoutContentStep(DataFlow::ContentSet conte
|
||||
or
|
||||
content.isElementLowerBoundOrUnknown(_)
|
||||
or
|
||||
content.isElementOfTypeOrUnknown(_)
|
||||
or
|
||||
content.isSingleton(any(DataFlow::Content::UnknownElementContent c))
|
||||
) and
|
||||
result = MkElementFilter()
|
||||
@@ -484,6 +486,10 @@ private ContentFilter getFilterFromWithContentStep(DataFlow::ContentSet content)
|
||||
or
|
||||
content.isElementLowerBoundOrUnknown(_)
|
||||
or
|
||||
content.isElementOfType(_)
|
||||
or
|
||||
content.isElementOfTypeOrUnknown(_)
|
||||
or
|
||||
content.isSingleton(any(DataFlow::Content::ElementContent c))
|
||||
) and
|
||||
result = MkElementFilter()
|
||||
|
||||
@@ -248,6 +248,26 @@ edges
|
||||
| semantics.rb:221:14:221:14 | h [element 2] : | semantics.rb:221:10:221:15 | call to s27 |
|
||||
| semantics.rb:221:14:221:14 | h [element] : | semantics.rb:221:10:221:15 | call to s27 |
|
||||
| semantics.rb:221:14:221:14 | h [element] : | semantics.rb:221:10:221:15 | call to s27 |
|
||||
| semantics.rb:225:9:225:18 | call to source : | semantics.rb:226:13:226:13 | a : |
|
||||
| semantics.rb:225:9:225:18 | call to source : | semantics.rb:226:13:226:13 | a : |
|
||||
| semantics.rb:226:9:226:14 | call to s28 [element] : | semantics.rb:227:10:227:10 | x [element] : |
|
||||
| semantics.rb:226:9:226:14 | call to s28 [element] : | semantics.rb:227:10:227:10 | x [element] : |
|
||||
| semantics.rb:226:9:226:14 | call to s28 [element] : | semantics.rb:228:10:228:10 | x [element] : |
|
||||
| semantics.rb:226:9:226:14 | call to s28 [element] : | semantics.rb:228:10:228:10 | x [element] : |
|
||||
| semantics.rb:226:9:226:14 | call to s28 [element] : | semantics.rb:229:10:229:10 | x [element] : |
|
||||
| semantics.rb:226:9:226:14 | call to s28 [element] : | semantics.rb:229:10:229:10 | x [element] : |
|
||||
| semantics.rb:226:9:226:14 | call to s28 [element] : | semantics.rb:230:10:230:10 | x [element] : |
|
||||
| semantics.rb:226:9:226:14 | call to s28 [element] : | semantics.rb:230:10:230:10 | x [element] : |
|
||||
| semantics.rb:226:13:226:13 | a : | semantics.rb:226:9:226:14 | call to s28 [element] : |
|
||||
| semantics.rb:226:13:226:13 | a : | semantics.rb:226:9:226:14 | call to s28 [element] : |
|
||||
| semantics.rb:227:10:227:10 | x [element] : | semantics.rb:227:10:227:13 | ...[...] |
|
||||
| semantics.rb:227:10:227:10 | x [element] : | semantics.rb:227:10:227:13 | ...[...] |
|
||||
| semantics.rb:228:10:228:10 | x [element] : | semantics.rb:228:10:228:13 | ...[...] |
|
||||
| semantics.rb:228:10:228:10 | x [element] : | semantics.rb:228:10:228:13 | ...[...] |
|
||||
| semantics.rb:229:10:229:10 | x [element] : | semantics.rb:229:10:229:13 | ...[...] |
|
||||
| semantics.rb:229:10:229:10 | x [element] : | semantics.rb:229:10:229:13 | ...[...] |
|
||||
| semantics.rb:230:10:230:10 | x [element] : | semantics.rb:230:10:230:13 | ...[...] |
|
||||
| semantics.rb:230:10:230:10 | x [element] : | semantics.rb:230:10:230:13 | ...[...] |
|
||||
| semantics.rb:235:9:235:18 | call to source : | semantics.rb:240:5:240:5 | [post] h [element 1] : |
|
||||
| semantics.rb:235:9:235:18 | call to source : | semantics.rb:240:5:240:5 | [post] h [element 1] : |
|
||||
| semantics.rb:236:9:236:18 | call to source : | semantics.rb:241:5:241:5 | [post] h [element 2] : |
|
||||
@@ -1206,6 +1226,28 @@ nodes
|
||||
| semantics.rb:221:14:221:14 | h [element 2] : | semmle.label | h [element 2] : |
|
||||
| semantics.rb:221:14:221:14 | h [element] : | semmle.label | h [element] : |
|
||||
| semantics.rb:221:14:221:14 | h [element] : | semmle.label | h [element] : |
|
||||
| semantics.rb:225:9:225:18 | call to source : | semmle.label | call to source : |
|
||||
| semantics.rb:225:9:225:18 | call to source : | semmle.label | call to source : |
|
||||
| semantics.rb:226:9:226:14 | call to s28 [element] : | semmle.label | call to s28 [element] : |
|
||||
| semantics.rb:226:9:226:14 | call to s28 [element] : | semmle.label | call to s28 [element] : |
|
||||
| semantics.rb:226:13:226:13 | a : | semmle.label | a : |
|
||||
| semantics.rb:226:13:226:13 | a : | semmle.label | a : |
|
||||
| semantics.rb:227:10:227:10 | x [element] : | semmle.label | x [element] : |
|
||||
| semantics.rb:227:10:227:10 | x [element] : | semmle.label | x [element] : |
|
||||
| semantics.rb:227:10:227:13 | ...[...] | semmle.label | ...[...] |
|
||||
| semantics.rb:227:10:227:13 | ...[...] | semmle.label | ...[...] |
|
||||
| semantics.rb:228:10:228:10 | x [element] : | semmle.label | x [element] : |
|
||||
| semantics.rb:228:10:228:10 | x [element] : | semmle.label | x [element] : |
|
||||
| semantics.rb:228:10:228:13 | ...[...] | semmle.label | ...[...] |
|
||||
| semantics.rb:228:10:228:13 | ...[...] | semmle.label | ...[...] |
|
||||
| semantics.rb:229:10:229:10 | x [element] : | semmle.label | x [element] : |
|
||||
| semantics.rb:229:10:229:10 | x [element] : | semmle.label | x [element] : |
|
||||
| semantics.rb:229:10:229:13 | ...[...] | semmle.label | ...[...] |
|
||||
| semantics.rb:229:10:229:13 | ...[...] | semmle.label | ...[...] |
|
||||
| semantics.rb:230:10:230:10 | x [element] : | semmle.label | x [element] : |
|
||||
| semantics.rb:230:10:230:10 | x [element] : | semmle.label | x [element] : |
|
||||
| semantics.rb:230:10:230:13 | ...[...] | semmle.label | ...[...] |
|
||||
| semantics.rb:230:10:230:13 | ...[...] | semmle.label | ...[...] |
|
||||
| semantics.rb:235:9:235:18 | call to source : | semmle.label | call to source : |
|
||||
| semantics.rb:235:9:235:18 | call to source : | semmle.label | call to source : |
|
||||
| semantics.rb:236:9:236:18 | call to source : | semmle.label | call to source : |
|
||||
|
||||
@@ -224,10 +224,10 @@ end
|
||||
def m28(i)
|
||||
a = source "a"
|
||||
x = s28(a)
|
||||
sink x[0]
|
||||
sink x[1] # $ MISSING: hasValueFlow=a
|
||||
sink x[2] # $ MISSING: hasValueFlow=a
|
||||
sink x[i] # $ MISSING: hasValueFlow=a
|
||||
sink x[0] # $ SPURIOUS: hasValueFlow=a
|
||||
sink x[1] # $ hasValueFlow=a
|
||||
sink x[2] # $ hasValueFlow=a
|
||||
sink x[i] # $ hasValueFlow=a
|
||||
end
|
||||
|
||||
def m29(i)
|
||||
|
||||
Reference in New Issue
Block a user