Files
codeql/python/ql/lib/semmle/python/SelfAttribute.qll
Taus 78c33ab55a Python: Remove points-to references from python.qll
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.
2025-11-26 12:30:30 +00:00

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)
}