mirror of
https://github.com/github/codeql.git
synced 2026-04-30 19:26:02 +02:00
Python points-to: Handle subclassing of ABCs.
This commit is contained in:
@@ -62,6 +62,19 @@ abstract class ClassObjectInternal extends ObjectInternal {
|
||||
|
||||
override int length() { none() }
|
||||
|
||||
boolean isIterableSubclass() {
|
||||
this = ObjectInternal::builtin("list") and result = true
|
||||
or
|
||||
this = ObjectInternal::builtin("set") and result = true
|
||||
or
|
||||
this = ObjectInternal::builtin("dict") and result = true
|
||||
or
|
||||
this != ObjectInternal::builtin("list") and
|
||||
this != ObjectInternal::builtin("set") and
|
||||
this != ObjectInternal::builtin("dict") and
|
||||
result = false
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class PythonClassObjectInternal extends ClassObjectInternal, TPythonClassObject {
|
||||
|
||||
@@ -31,7 +31,7 @@ class SpecificInstanceInternal extends TSpecificInstance, ObjectInternal {
|
||||
|
||||
override boolean isClass() { result = false }
|
||||
|
||||
override boolean isComparable() { result = false }
|
||||
override boolean isComparable() { result = true }
|
||||
|
||||
override ObjectInternal getClass() {
|
||||
this = TSpecificInstance(_, result, _)
|
||||
|
||||
@@ -159,6 +159,8 @@ predicate literal_instantiation(ControlFlowNode n, ClassObjectInternal cls, Poin
|
||||
or
|
||||
n instanceof DictNode and cls = ObjectInternal::builtin("dict")
|
||||
or
|
||||
n instanceof SetNode and cls = ObjectInternal::builtin("set")
|
||||
or
|
||||
n.getNode() instanceof ImaginaryLiteral and cls = ObjectInternal::builtin("complex")
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1746,10 +1746,23 @@ cached module Types {
|
||||
or
|
||||
mro.getItem(n) = sup and result = true
|
||||
or
|
||||
mro.getItem(n) != sup and result = mroContains(mro, sup, n+1)
|
||||
mro.getItem(n) = abc_to_concrete(sup) and result = true
|
||||
or
|
||||
mro.getItem(n) != sup and sup != AbstractBaseClass::named("Iterable") and
|
||||
mro.getItem(n) != abc_to_concrete(sup) and result = mroContains(mro, sup, n+1)
|
||||
or
|
||||
sup = AbstractBaseClass::named("Iterable") and result = mro.getItem(n).isIterableSubclass()
|
||||
)
|
||||
}
|
||||
|
||||
private ClassObjectInternal abc_to_concrete(ClassObjectInternal c) {
|
||||
c = AbstractBaseClass::named("Sequence") and result = ObjectInternal::builtin("list")
|
||||
or
|
||||
c = AbstractBaseClass::named("Set") and result = ObjectInternal::builtin("set")
|
||||
or
|
||||
c = AbstractBaseClass::named("Mapping") and result = ObjectInternal::builtin("dict")
|
||||
}
|
||||
|
||||
cached boolean hasAttr(ObjectInternal cls, string name) {
|
||||
result = mroHasAttr(Types::getMro(cls), name, 0)
|
||||
}
|
||||
@@ -1776,6 +1789,19 @@ cached module Types {
|
||||
}
|
||||
|
||||
|
||||
module AbstractBaseClass {
|
||||
|
||||
ClassObjectInternal named(string name) {
|
||||
exists(ModuleObjectInternal m |
|
||||
m.getName() = "_abcoll"
|
||||
or
|
||||
m.getName() = "_collections_abc"
|
||||
|
|
||||
m.attribute(name, result, _)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
module AttributePointsTo {
|
||||
|
||||
predicate pointsTo(AttrNode f, Context context, ObjectInternal value, ControlFlowNode origin) {
|
||||
|
||||
Reference in New Issue
Block a user