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

Skip to content

Commit 1f00c3b

Browse files
committed
Python points-to: Fix up metaclass determination for Python 2.
1 parent 26044f2 commit 1f00c3b

4 files changed

Lines changed: 21 additions & 14 deletions

File tree

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -426,6 +426,11 @@ module ObjectInternal {
426426
result = TBuiltinClassObject(Builtin::special("super"))
427427
}
428428

429+
/** The old-style class type (Python 2 only) */
430+
ObjectInternal classType() {
431+
result = TBuiltinClassObject(Builtin::special("ClassType"))
432+
}
433+
429434
}
430435

431436
/** Helper for boolean predicates returning both `true` and `false` */

python/ql/src/semmle/python/pointsto/PointsTo.qll

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1692,9 +1692,9 @@ cached module Types {
16921692
}
16931693

16941694
cached ClassObjectInternal getMetaClass(PythonClassObjectInternal cls) {
1695-
result = declaredMetaClass(cls)
1696-
or
1697-
hasDeclaredMetaclass(cls) = false and result = getInheritedMetaclass(cls)
1695+
result = declaredMetaClass(cls)
1696+
or
1697+
hasDeclaredMetaclass(cls) = false and result = getInheritedMetaclass(cls)
16981698
}
16991699

17001700
private ClassObjectInternal declaredMetaClass(PythonClassObjectInternal cls) {
@@ -1799,7 +1799,9 @@ cached module Types {
17991799
c = cls.(PythonClassObjectInternal).getScope() and
18001800
n = count(c.getABase())
18011801
|
1802-
result = ObjectInternal::builtin("type")
1802+
result = ObjectInternal::type() and major_version() = 3
1803+
or
1804+
result = ObjectInternal::classType() and major_version() = 2
18031805
)
18041806
or
18051807
exists(ClassObjectInternal meta1, ClassObjectInternal meta2 |
@@ -1811,6 +1813,8 @@ cached module Types {
18111813
or
18121814
improperSuperType(meta2) = meta1 and result = meta2
18131815
or
1816+
meta2 = ObjectInternal::classType() and result = meta1
1817+
or
18141818
/* Make sure we have a metaclass, even if base is unknown */
18151819
meta1 = ObjectInternal::unknownClass() and result = ObjectInternal::builtin("type")
18161820
or

python/ql/test/2/library-tests/classes/mro/C3.ql

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,17 @@
11

22
import python
33
import semmle.python.pointsto.MRO
4+
import semmle.python.pointsto.PointsTo
5+
import semmle.python.objects.ObjectInternal
46

5-
ClassList mro(ClassObject cls) {
6-
if cls.isNewStyle() then
7-
result = new_style_mro(cls)
7+
ClassList mro(ClassObjectInternal cls) {
8+
if Types::isNewStyle(cls) then
9+
result = Mro::newStyleMro(cls)
810
else
9-
result = old_style_mro(cls)
11+
result = Mro::oldStyleMro(cls)
1012
}
1113

12-
from ClassObject cls
14+
from ClassObjectInternal cls
1315
where not cls.isBuiltin()
1416

1517
select cls.toString(), mro(cls)

python/ql/test/2/library-tests/classes/mro/mro.ql

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,4 @@
1-
/**
2-
* @name class_attr
3-
* @kind test
4-
* @problem.severity warning
5-
*/
1+
62

73
import python
84

0 commit comments

Comments
 (0)