mirror of
https://github.com/github/codeql.git
synced 2025-12-24 04:36:35 +01:00
Python: API-graphs: allow class decorators in .getASubclass()
This commit is contained in:
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Change `.getASubclass()` on `API::Node` so it allows to follow subclasses even if the class has a class decorator.
|
||||
@@ -591,8 +591,18 @@ module API {
|
||||
or
|
||||
// Subclassing a node
|
||||
lbl = Label::subclass() and
|
||||
exists(DataFlow::Node superclass | pred.flowsTo(superclass) |
|
||||
ref.asExpr().(PY::ClassExpr).getABase() = superclass.asExpr()
|
||||
exists(PY::ClassExpr clsExpr, DataFlow::Node superclass | pred.flowsTo(superclass) |
|
||||
clsExpr.getABase() = superclass.asExpr() and
|
||||
// Potentially a class decorator could do anything, but we assume they are
|
||||
// "benign" and let subclasses edges flow through anyway.
|
||||
// see example in https://github.com/django/django/blob/c2250cfb80e27cdf8d098428824da2800a18cadf/tests/auth_tests/test_views.py#L40-L46
|
||||
(
|
||||
not exists(clsExpr.getADecorator()) and
|
||||
ref.asExpr() = clsExpr
|
||||
or
|
||||
ref.asExpr() = clsExpr.getADecoratorCall() and
|
||||
not exists(PY::Call otherDecorator | otherDecorator.getArg(0) = ref.asExpr())
|
||||
)
|
||||
)
|
||||
or
|
||||
// awaiting
|
||||
|
||||
@@ -30,5 +30,5 @@ def my_class_decorator(cls):
|
||||
class MyViewWithDecorator(View): #$ use=moduleImport("flask").getMember("views").getMember("View").getASubclass()
|
||||
pass
|
||||
|
||||
class SubclassFromDecorated(MyViewWithDecorator): #$ MISSING: use=moduleImport("flask").getMember("views").getMember("View").getASubclass().getASubclass()
|
||||
class SubclassFromDecorated(MyViewWithDecorator): #$ use=moduleImport("flask").getMember("views").getMember("View").getASubclass().getASubclass()
|
||||
pass
|
||||
|
||||
Reference in New Issue
Block a user