mirror of
https://github.com/github/codeql.git
synced 2025-12-16 16:53:25 +01:00
For now, these have just been made into `private` imports. After doing
this, I went through all of the (now not compiling) files and added in
private imports to the modules that they actually depended on.
I also added an explicit import of `LegacyPointsTo` (even though it may
be unnecessary) in cases where the points-to dependency was somewhat
surprising (and one we want to get rid of). This was primarily inside
the various SSA layers.
For modules inside `semmle.python.{types, objects, pointsto}` I did not
bother, as these are fairly clearly related to points-to.
92 lines
2.8 KiB
Plaintext
92 lines
2.8 KiB
Plaintext
/**
|
|
* Utilities to support queries about instance attribute accesses of
|
|
* the form `self.attr`.
|
|
*/
|
|
|
|
import python
|
|
private import semmle.python.pointsto.Filters
|
|
private import LegacyPointsTo
|
|
|
|
/**
|
|
* An attribute access where the left hand side of the attribute expression
|
|
* is `self`.
|
|
*/
|
|
class SelfAttribute extends Attribute {
|
|
SelfAttribute() { self_attribute(this, _) }
|
|
|
|
Class getClass() { self_attribute(this, result) }
|
|
}
|
|
|
|
/** Whether variable 'self' is the self variable in method 'method' */
|
|
private predicate self_variable(Function method, Variable self) {
|
|
self.isParameter() and
|
|
method.isMethod() and
|
|
method.getArg(0).asName() = self.getAnAccess()
|
|
}
|
|
|
|
/** Whether attribute is an access of the form `self.attr` in the body of the class 'cls' */
|
|
private predicate self_attribute(Attribute attr, Class cls) {
|
|
exists(Function f, Variable self | self_variable(f, self) |
|
|
self.getAnAccess() = attr.getObject() and
|
|
cls = f.getScope+()
|
|
)
|
|
}
|
|
|
|
/** A helper class for UndefinedClassAttribute.ql & MaybeUndefinedClassAttribute.ql */
|
|
class SelfAttributeRead extends SelfAttribute {
|
|
SelfAttributeRead() {
|
|
this.getCtx() instanceof Load and
|
|
// Be stricter for loads.
|
|
// We want to generous as to what is defined (i.e. stores),
|
|
// but strict as to what needs to be defined (i.e. loads).
|
|
exists(ClassObject cls, FunctionObject func | cls.declaredAttribute(_) = func |
|
|
func.getFunction() = this.getScope() and
|
|
cls.getPyClass() = this.getClass()
|
|
)
|
|
}
|
|
|
|
predicate guardedByHasattr() {
|
|
exists(Variable var, ControlFlowNode n |
|
|
var.getAUse() = this.getObject().getAFlowNode() and
|
|
hasattr(n, var.getAUse(), this.getName()) and
|
|
n.strictlyDominates(this.getAFlowNode())
|
|
)
|
|
}
|
|
|
|
pragma[noinline]
|
|
predicate locallyDefined() {
|
|
exists(SelfAttributeStore store |
|
|
this.getName() = store.getName() and
|
|
this.getScope() = store.getScope()
|
|
|
|
|
store.getAFlowNode().strictlyDominates(this.getAFlowNode())
|
|
)
|
|
}
|
|
}
|
|
|
|
class SelfAttributeStore extends SelfAttribute {
|
|
SelfAttributeStore() { this.getCtx() instanceof Store }
|
|
|
|
Expr getAssignedValue() { exists(Assign a | a.getATarget() = this | result = a.getValue()) }
|
|
}
|
|
|
|
private predicate attr_assigned_in_method_arg_n(FunctionObject method, string name, int n) {
|
|
exists(SsaVariable param |
|
|
method.getFunction().getArg(n).asName() = param.getDefinition().getNode()
|
|
|
|
|
exists(AttrNode attr |
|
|
attr.getObject(name) = param.getAUse() and
|
|
attr.isStore()
|
|
)
|
|
or
|
|
exists(FunctionObject callee, int m |
|
|
callee.getArgumentForCall(_, m) = param.getAUse() and
|
|
attr_assigned_in_method_arg_n(callee, name, m)
|
|
)
|
|
)
|
|
}
|
|
|
|
predicate attribute_assigned_in_method(FunctionObject method, string name) {
|
|
attr_assigned_in_method_arg_n(method, name, 0)
|
|
}
|