mirror of
https://github.com/github/codeql.git
synced 2025-12-20 02:44:30 +01:00
Python: Implement field-stores, -reads, and -content
This commit is contained in:
@@ -361,7 +361,7 @@ class DataFlowType extends TDataFlowType {
|
||||
}
|
||||
|
||||
/** A node that performs a type cast. */
|
||||
class CastNode extends Node {
|
||||
class CastNode extends CfgNode {
|
||||
CastNode() { none() }
|
||||
}
|
||||
|
||||
@@ -423,6 +423,8 @@ predicate storeStep(Node nodeFrom, Content c, Node nodeTo) {
|
||||
dictStoreStep(nodeFrom, c, nodeTo)
|
||||
or
|
||||
comprehensionStoreStep(nodeFrom, c, nodeTo)
|
||||
or
|
||||
attributeStoreStep(nodeFrom, c, nodeTo)
|
||||
}
|
||||
|
||||
/** Data flows from an element of a list to the list. */
|
||||
@@ -497,6 +499,30 @@ predicate comprehensionStoreStep(CfgNode nodeFrom, Content c, CfgNode nodeTo) {
|
||||
c instanceof ListElementContent
|
||||
}
|
||||
|
||||
/**
|
||||
* In
|
||||
* ```python
|
||||
* obj.foo = x
|
||||
* ```
|
||||
* data flows from `x` to (the post-update node for) `obj` via assignment to `foo`.
|
||||
*/
|
||||
predicate attributeStoreStep(CfgNode nodeFrom, Content c, PostUpdateNode nodeTo) {
|
||||
exists(AssignStmt a, Attribute attr |
|
||||
a.getValue().getAFlowNode() = nodeFrom.getNode() and
|
||||
a.getATarget().(Attribute) = attr and
|
||||
attr.getName() = c.(AttributeContent).getAttribute() and
|
||||
attr.getObject().getAFlowNode() = nodeTo.getPreUpdateNode().(CfgNode).getNode() and
|
||||
attr.getCtx() instanceof Store
|
||||
)
|
||||
or
|
||||
exists(AssignExpr ae |
|
||||
ae.getValue().getAFlowNode() = nodeFrom.getNode() and
|
||||
ae.getTarget().(Attribute).getName() = c.(AttributeContent).getAttribute() and
|
||||
ae.getTarget().(Attribute).getObject().getAFlowNode() =
|
||||
nodeTo.getPreUpdateNode().(CfgNode).getNode()
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if data can flow from `nodeFrom` to `nodeTo` via a read of content `c`.
|
||||
*/
|
||||
@@ -506,6 +532,8 @@ predicate readStep(Node nodeFrom, Content c, Node nodeTo) {
|
||||
popReadStep(nodeFrom, c, nodeTo)
|
||||
or
|
||||
comprehensionReadStep(nodeFrom, c, nodeTo)
|
||||
or
|
||||
attributeReadStep(nodeFrom, c, nodeTo)
|
||||
}
|
||||
|
||||
/** Data flows from a sequence to a subscript of the sequence. */
|
||||
@@ -592,6 +620,22 @@ predicate comprehensionReadStep(CfgNode nodeFrom, Content c, EssaNode nodeTo) {
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* In
|
||||
* ```python
|
||||
* obj.foo
|
||||
* ```
|
||||
* data flows from `obj` to `obj.foo` via a read from `foo`.
|
||||
*/
|
||||
predicate attributeReadStep(CfgNode nodeFrom, Content c, CfgNode nodeTo) {
|
||||
exists(Attribute attr |
|
||||
nodeTo.asCfgNode().(AttrNode).getNode() = attr and
|
||||
nodeFrom.asCfgNode() = attr.getObject().getAFlowNode() and
|
||||
attr.getName() = c.(AttributeContent).getAttribute() and
|
||||
attr.getCtx() instanceof Load
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if values stored inside content `c` are cleared at node `n`. For example,
|
||||
* any value stored inside `f` is cleared at the pre-update node associated with `x`
|
||||
|
||||
@@ -202,7 +202,9 @@ newtype TContent =
|
||||
key = any(Keyword kw).getArg()
|
||||
} or
|
||||
/** An element of a dictionary at any key. */
|
||||
TDictionaryElementAnyContent()
|
||||
TDictionaryElementAnyContent() or
|
||||
/** An object attribute. */
|
||||
TAttributeContent(string attr) { attr = any(Attribute a).getName() }
|
||||
|
||||
class Content extends TContent {
|
||||
/** Gets a textual representation of this element. */
|
||||
@@ -210,12 +212,10 @@ class Content extends TContent {
|
||||
}
|
||||
|
||||
class ListElementContent extends TListElementContent, Content {
|
||||
/** Gets a textual representation of this element. */
|
||||
override string toString() { result = "List element" }
|
||||
}
|
||||
|
||||
class SetElementContent extends TSetElementContent, Content {
|
||||
/** Gets a textual representation of this element. */
|
||||
override string toString() { result = "Set element" }
|
||||
}
|
||||
|
||||
@@ -224,10 +224,9 @@ class TupleElementContent extends TTupleElementContent, Content {
|
||||
|
||||
TupleElementContent() { this = TTupleElementContent(index) }
|
||||
|
||||
/** Gets the index for this tuple element */
|
||||
/** Gets the index for this tuple element. */
|
||||
int getIndex() { result = index }
|
||||
|
||||
/** Gets a textual representation of this element. */
|
||||
override string toString() { result = "Tuple element at index " + index.toString() }
|
||||
}
|
||||
|
||||
@@ -236,14 +235,23 @@ class DictionaryElementContent extends TDictionaryElementContent, Content {
|
||||
|
||||
DictionaryElementContent() { this = TDictionaryElementContent(key) }
|
||||
|
||||
/** Gets the index for this tuple element */
|
||||
/** Gets the key for this dictionary element. */
|
||||
string getKey() { result = key }
|
||||
|
||||
/** Gets a textual representation of this element. */
|
||||
override string toString() { result = "Dictionary element at key " + key }
|
||||
}
|
||||
|
||||
class DictionaryElementAnyContent extends TDictionaryElementAnyContent, Content {
|
||||
/** Gets a textual representation of this element. */
|
||||
override string toString() { result = "Any dictionary element" }
|
||||
}
|
||||
|
||||
class AttributeContent extends TAttributeContent, Content {
|
||||
private string attr;
|
||||
|
||||
AttributeContent() { this = TAttributeContent(attr) }
|
||||
|
||||
/** Gets the name of the attribute under which this content is stored. */
|
||||
string getAttribute() { result = attr }
|
||||
|
||||
override string toString() { result = "Attribute " + attr }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user