Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit b8fb3e3

Browse files
committed
Python points-to: Distinguish between class attribute access and lookup. Fixes handling of classmethods.
1 parent 55eac7d commit b8fb3e3

2 files changed

Lines changed: 21 additions & 7 deletions

File tree

python/ql/src/semmle/python/objects/Classes.qll

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,24 @@ abstract class ClassObjectInternal extends ObjectInternal {
4040
override predicate binds(ObjectInternal instance, string name, ObjectInternal descriptor) {
4141
instance = this and
4242
PointsToInternal::attributeRequired(this, name) and
43-
this.attribute(name, descriptor, _) and
43+
this.lookup(name, descriptor, _) and
4444
descriptor.isDescriptor() = true
4545
}
4646

47+
abstract predicate lookup(string name, ObjectInternal value, CfgOrigin origin);
48+
49+
/** Approximation to descriptor protocol, skipping meta-descriptor protocol */
50+
override predicate attribute(string name, ObjectInternal value, CfgOrigin origin) {
51+
exists(ObjectInternal descriptor, CfgOrigin desc_origin |
52+
this.lookup(name, descriptor, desc_origin) |
53+
descriptor.isDescriptor() = false and
54+
value = descriptor and origin = desc_origin
55+
or
56+
descriptor.isDescriptor() = true and
57+
descriptor.descriptorGet(this, value, origin)
58+
)
59+
}
60+
4761
}
4862

4963
class PythonClassObjectInternal extends ClassObjectInternal, TPythonClassObject {
@@ -87,7 +101,7 @@ class PythonClassObjectInternal extends ClassObjectInternal, TPythonClassObject
87101
)
88102
}
89103

90-
override predicate attribute(string name, ObjectInternal value, CfgOrigin origin) {
104+
override predicate lookup(string name, ObjectInternal value, CfgOrigin origin) {
91105
exists(ClassObjectInternal decl |
92106
decl = Types::getMro(this).findDeclaringClass(name) |
93107
Types::declaredAttribute(decl, name, value, origin)
@@ -142,7 +156,7 @@ class BuiltinClassObjectInternal extends ClassObjectInternal, TBuiltinClassObjec
142156
none()
143157
}
144158

145-
override predicate attribute(string name, ObjectInternal value, CfgOrigin origin) {
159+
override predicate lookup(string name, ObjectInternal value, CfgOrigin origin) {
146160
value = ObjectInternal::fromBuiltin(this.getBuiltin().getMember(name)) and
147161
origin = CfgOrigin::unknown()
148162
}
@@ -203,7 +217,7 @@ class UnknownClassInternal extends ClassObjectInternal, TUnknownClass {
203217
none()
204218
}
205219

206-
override predicate attribute(string name, ObjectInternal value, CfgOrigin origin) {
220+
override predicate lookup(string name, ObjectInternal value, CfgOrigin origin) {
207221
none()
208222
}
209223

@@ -251,7 +265,7 @@ class TypeInternal extends ClassObjectInternal, TType {
251265
none()
252266
}
253267

254-
override predicate attribute(string name, ObjectInternal value, CfgOrigin origin) {
268+
override predicate lookup(string name, ObjectInternal value, CfgOrigin origin) {
255269
none()
256270
}
257271

python/ql/src/semmle/python/objects/Instances.qll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ class SpecificInstanceInternal extends TSpecificInstance, ObjectInternal {
9191
this = instance and descriptor.isDescriptor() = true and
9292
exists(AttrNode attr |
9393
PointsToInternal::pointsTo(attr.getObject(name), _, instance, _) and
94-
this.getClass().attribute(name, descriptor, _)
94+
this.getClass().(ClassObjectInternal).lookup(name, descriptor, _)
9595
)
9696
}
9797

@@ -302,7 +302,7 @@ private predicate receiver_type(AttrNode attr, string name, ObjectInternal value
302302
}
303303

304304
private predicate cls_descriptor(ClassObjectInternal cls, string name, ObjectInternal descriptor) {
305-
cls.attribute(name, descriptor, _) and
305+
cls.lookup(name, descriptor, _) and
306306
descriptor.isDescriptor() = true
307307
}
308308

0 commit comments

Comments
 (0)