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

Skip to content

Commit 2e6c3c9

Browse files
committed
Python points-to: Support classes created dynamically as instances of meta-class.
1 parent 06ab671 commit 2e6c3c9

4 files changed

Lines changed: 57 additions & 2 deletions

File tree

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

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,3 +277,53 @@ class TypeInternal extends ClassObjectInternal, TType {
277277
override predicate attributesUnknown() { any() }
278278

279279
}
280+
281+
class DynamicallyCreatedClass extends ClassObjectInternal, TDynamicClass {
282+
283+
override string toString() {
284+
result = this.getOrigin().getNode().toString()
285+
}
286+
287+
override ObjectInternal getClass() {
288+
this = TDynamicClass(_, result, _)
289+
}
290+
291+
override predicate callResult(PointsToContext callee, ObjectInternal obj, CfgOrigin origin) {
292+
none()
293+
}
294+
295+
override predicate callResult(ObjectInternal obj, CfgOrigin origin) {
296+
none()
297+
}
298+
299+
override predicate lookup(string name, ObjectInternal value, CfgOrigin origin) {
300+
exists(ClassObjectInternal decl |
301+
decl = Types::getMro(this).findDeclaringClass(name) |
302+
Types::declaredAttribute(decl, name, value, origin)
303+
)
304+
}
305+
306+
override Builtin getBuiltin() {
307+
none()
308+
}
309+
310+
override ControlFlowNode getOrigin() {
311+
this = TDynamicClass(result, _, _)
312+
}
313+
314+
override predicate attributesUnknown() { any() }
315+
316+
override predicate introduced(ControlFlowNode node, PointsToContext context) {
317+
this = TDynamicClass(node, _, context)
318+
}
319+
320+
override predicate calleeAndOffset(Function scope, int paramOffset) {
321+
none()
322+
}
323+
324+
override boolean isComparable() { result = true }
325+
326+
override ClassDecl getClassDeclaration() { none() }
327+
328+
}
329+

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,11 @@ newtype TObject =
130130
PointsToInternal::pointsTo(call.getFunction(), ctx, ObjectInternal::property(), _) and
131131
PointsToInternal::pointsTo(call.getArg(0), ctx, getter, _)
132132
}
133+
or
134+
TDynamicClass(ControlFlowNode instantiation, ClassObjectInternal metacls, PointsToContext context) {
135+
PointsToInternal::pointsTo(instantiation.(CallNode).getFunction(), context, metacls, _) and
136+
Types::getMro(metacls).contains(TType())
137+
}
133138

134139
private predicate is_power_2(int n) {
135140
n = 1 or

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1445,7 +1445,7 @@ cached module Types {
14451445
)
14461446
}
14471447

1448-
cached ClassObjectInternal getBase(ClassObjectInternal cls, int n) {
1448+
cached ObjectInternal getBase(ClassObjectInternal cls, int n) {
14491449
result.getBuiltin() = cls.getBuiltin().getBaseClass() and n = 0
14501450
or
14511451
exists(Class pycls |

python/ql/src/semmle/python/types/ClassObject.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ class ClassObject extends Object {
6868

6969
/** Gets a super class of this class (includes transitive super classes) or this class */
7070
ClassObject getAnImproperSuperType() {
71-
result = Types::getMro(theClass()).getAnItem().getSource()
71+
result = this.getABaseType*()
7272
}
7373

7474
/** Whether this class is a new style class.

0 commit comments

Comments
 (0)