mirror of
https://github.com/github/codeql.git
synced 2026-03-01 05:13:41 +01:00
Java: Add support for synthetic fields in csv rows.
This commit is contained in:
@@ -652,6 +652,48 @@ Element interpretElement(
|
||||
)
|
||||
}
|
||||
|
||||
private predicate parseField(string c, FieldContent f) {
|
||||
specSplit(_, c, _) and
|
||||
exists(string fieldRegex, string package, string className, string fieldName |
|
||||
fieldRegex = "^Field\\[(.*)\\.([^.]+)\\.([^.]+)\\]$" and
|
||||
package = c.regexpCapture(fieldRegex, 1) and
|
||||
className = c.regexpCapture(fieldRegex, 2) and
|
||||
fieldName = c.regexpCapture(fieldRegex, 3) and
|
||||
f.getField().hasQualifiedName(package, className, fieldName)
|
||||
)
|
||||
}
|
||||
|
||||
/** A string representing a synthetic instance field. */
|
||||
class SyntheticField extends string {
|
||||
SyntheticField() { parseSynthField(_, this) }
|
||||
|
||||
/**
|
||||
* Gets the type of this field. The default type is `Object`, but this can be
|
||||
* overridden.
|
||||
*/
|
||||
Type getType() { result instanceof TypeObject }
|
||||
}
|
||||
|
||||
private predicate parseSynthField(string c, string f) {
|
||||
specSplit(_, c, _) and
|
||||
c.regexpCapture("SyntheticField\\[([.a-zA-Z0-9]+)\\]", 1) = f
|
||||
}
|
||||
|
||||
/** Holds if the specification component parses as a `Content`. */
|
||||
predicate parseContent(string component, Content content) {
|
||||
parseField(component, content)
|
||||
or
|
||||
parseSynthField(component, content.(SyntheticFieldContent).getField())
|
||||
or
|
||||
component = "ArrayElement" and content instanceof ArrayContent
|
||||
or
|
||||
component = "Element" and content instanceof CollectionContent
|
||||
or
|
||||
component = "MapKey" and content instanceof MapKeyContent
|
||||
or
|
||||
component = "MapValue" and content instanceof MapValueContent
|
||||
}
|
||||
|
||||
cached
|
||||
private module Cached {
|
||||
/**
|
||||
|
||||
@@ -162,7 +162,8 @@ private newtype TContent =
|
||||
TArrayContent() or
|
||||
TCollectionContent() or
|
||||
TMapKeyContent() or
|
||||
TMapValueContent()
|
||||
TMapValueContent() or
|
||||
TSyntheticFieldContent(SyntheticField s)
|
||||
|
||||
/**
|
||||
* A description of the way data may be stored inside an object. Examples
|
||||
@@ -170,6 +171,9 @@ private newtype TContent =
|
||||
* of an array.
|
||||
*/
|
||||
class Content extends TContent {
|
||||
/** Gets the type of the contained data for the purpose of type pruning. */
|
||||
abstract DataFlowType getType();
|
||||
|
||||
/** Gets a textual representation of this element. */
|
||||
abstract string toString();
|
||||
|
||||
@@ -193,6 +197,8 @@ class FieldContent extends Content, TFieldContent {
|
||||
|
||||
InstanceField getField() { result = f }
|
||||
|
||||
override DataFlowType getType() { result = getErasedRepr(f.getType()) }
|
||||
|
||||
override string toString() { result = f.toString() }
|
||||
|
||||
override predicate hasLocationInfo(string path, int sl, int sc, int el, int ec) {
|
||||
@@ -202,24 +208,45 @@ class FieldContent extends Content, TFieldContent {
|
||||
|
||||
/** A reference through an array. */
|
||||
class ArrayContent extends Content, TArrayContent {
|
||||
override DataFlowType getType() { result instanceof TypeObject }
|
||||
|
||||
override string toString() { result = "[]" }
|
||||
}
|
||||
|
||||
/** A reference through the contents of some collection-like container. */
|
||||
class CollectionContent extends Content, TCollectionContent {
|
||||
override DataFlowType getType() { result instanceof TypeObject }
|
||||
|
||||
override string toString() { result = "<element>" }
|
||||
}
|
||||
|
||||
/** A reference through a map key. */
|
||||
class MapKeyContent extends Content, TMapKeyContent {
|
||||
override DataFlowType getType() { result instanceof TypeObject }
|
||||
|
||||
override string toString() { result = "<map.key>" }
|
||||
}
|
||||
|
||||
/** A reference through a map value. */
|
||||
class MapValueContent extends Content, TMapValueContent {
|
||||
override DataFlowType getType() { result instanceof TypeObject }
|
||||
|
||||
override string toString() { result = "<map.value>" }
|
||||
}
|
||||
|
||||
/** A reference through a synthetic instance field. */
|
||||
class SyntheticFieldContent extends Content, TSyntheticFieldContent {
|
||||
SyntheticField s;
|
||||
|
||||
SyntheticFieldContent() { this = TSyntheticFieldContent(s) }
|
||||
|
||||
SyntheticField getField() { result = s }
|
||||
|
||||
override DataFlowType getType() { result = getErasedRepr(s.getType()) }
|
||||
|
||||
override string toString() { result = s.toString() }
|
||||
}
|
||||
|
||||
/**
|
||||
* A guard that validates some expression.
|
||||
*
|
||||
|
||||
@@ -23,21 +23,7 @@ Node summaryNode(SummarizedCallable c, SummaryNodeState state) { result = getSum
|
||||
DataFlowCall summaryDataFlowCall(Node receiver) { none() }
|
||||
|
||||
/** Gets the type of content `c`. */
|
||||
DataFlowType getContentType(Content c) {
|
||||
result = getErasedRepr(c.(FieldContent).getField().getType())
|
||||
or
|
||||
c instanceof CollectionContent and
|
||||
result instanceof TypeObject
|
||||
or
|
||||
c instanceof ArrayContent and
|
||||
result instanceof TypeObject
|
||||
or
|
||||
c instanceof MapKeyContent and
|
||||
result instanceof TypeObject
|
||||
or
|
||||
c instanceof MapValueContent and
|
||||
result instanceof TypeObject
|
||||
}
|
||||
DataFlowType getContentType(Content c) { result = c.getType() }
|
||||
|
||||
/** Gets the return type of kind `rk` for callable `c`. */
|
||||
DataFlowType getReturnType(SummarizedCallable c, ReturnKind rk) {
|
||||
@@ -70,29 +56,10 @@ predicate summaryElement(DataFlowCallable c, string input, string output, string
|
||||
)
|
||||
}
|
||||
|
||||
private FieldContent parseField(string c) {
|
||||
External::specSplit(_, c, _) and
|
||||
exists(string fieldRegex, string package, string className, string fieldName |
|
||||
fieldRegex = "^Field\\[(.*)\\.([^.]+)\\.([^.]+)\\]$" and
|
||||
package = c.regexpCapture(fieldRegex, 1) and
|
||||
className = c.regexpCapture(fieldRegex, 2) and
|
||||
fieldName = c.regexpCapture(fieldRegex, 3) and
|
||||
result.getField().hasQualifiedName(package, className, fieldName)
|
||||
)
|
||||
}
|
||||
|
||||
/** Gets the summary component for specification component `c`, if any. */
|
||||
bindingset[c]
|
||||
SummaryComponent interpretComponentSpecific(string c) {
|
||||
result = SummaryComponent::content(parseField(c))
|
||||
or
|
||||
c = "ArrayElement" and result = SummaryComponent::content(any(ArrayContent c0))
|
||||
or
|
||||
c = "Element" and result = SummaryComponent::content(any(CollectionContent c0))
|
||||
or
|
||||
c = "MapKey" and result = SummaryComponent::content(any(MapKeyContent c0))
|
||||
or
|
||||
c = "MapValue" and result = SummaryComponent::content(any(MapValueContent c0))
|
||||
exists(Content content | parseContent(c, content) and result = SummaryComponent::content(content))
|
||||
}
|
||||
|
||||
class SourceOrSinkElement = Top;
|
||||
|
||||
Reference in New Issue
Block a user