Skip to content

Commit d8eea7b

Browse files
committed
property writes are def nodes
1 parent a908b21 commit d8eea7b

File tree

3 files changed

+28
-33
lines changed

3 files changed

+28
-33
lines changed

python/ql/lib/semmle/python/ApiGraphs.qll

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -507,16 +507,13 @@ module API {
507507
lbl = Label::parameter(i) and
508508
argumentPassing(base, i, rhs)
509509
)
510-
/*
511-
* or // TODO:
512-
* exists(DataFlow::SourceNode src, DataFlow::PropWrite pw |
513-
* use(base, src) and pw = trackUseNode(src).getAPropertyWrite() and rhs = pw.getRhs()
514-
* |
515-
* lbl = Label::memberFromRef(pw)
516-
* )
517-
*/
518-
519-
}
510+
or
511+
exists(DataFlow::LocalSourceNode src, DataFlow::AttrWrite pw |
512+
use(base, src) and pw = trackUseNode(src).getAnAttributeWrite() and rhs = pw.getValue()
513+
|
514+
lbl = Label::memberFromRef(pw)
515+
)
516+
}
520517

521518
/**
522519
* Holds if `ref` is a use of a node that should have an incoming edge from `base` labeled
@@ -536,7 +533,7 @@ module API {
536533
|
537534
// Referring to an attribute on a node that is a use of `base`:
538535
lbl = Label::memberFromRef(ref) and
539-
ref = pred.getAnAttributeReference() // TODO: Change to read.
536+
ref = pred.getAnAttributeRead()
540537
or
541538
// Calling a node that is a use of `base`
542539
lbl = Label::return() and
@@ -778,7 +775,7 @@ module API {
778775
MkLabelParameter(int i) {
779776
exists(any(DataFlow::CallCfgNode c).getArg(i))
780777
or
781-
i = [-1 .. 10] // TODO: Def nodes, figure out how to make this prettier.
778+
exists(any(Function f).getArg(i))
782779
} or
783780
MkLabelReturn() or
784781
MkLabelSubclass() or
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# Subclasses
2+
3+
from flask.views import View #$ use=moduleImport("flask").getMember("views").getMember("View")
4+
5+
class MyView(View): #$ use=moduleImport("flask").getMember("views").getMember("View").getASubclass()
6+
myvar = 45 #$ def=moduleImport("flask").getMember("views").getMember("View").getASubclass().getMember("myvar")
7+
def my_method(self): #$ def=moduleImport("flask").getMember("views").getMember("View").getASubclass().getMember("my_method") use=moduleImport("flask").getMember("views").getMember("View").getASubclass().getMember("my_method").getParameter(0)
8+
pass
9+
10+
instance = MyView() #$ use=moduleImport("flask").getMember("views").getMember("View").getASubclass().getReturn()
11+
12+
def internal():
13+
from pflask.views import View #$ use=moduleImport("pflask").getMember("views").getMember("View")
14+
class IntMyView(View): #$ use=moduleImport("pflask").getMember("views").getMember("View").getASubclass()
15+
my_internal_var = 35 #$ def=moduleImport("pflask").getMember("views").getMember("View").getASubclass().getMember("my_internal_var")
16+
def my_internal_method(self): #$ def=moduleImport("pflask").getMember("views").getMember("View").getASubclass().getMember("my_internal_method") use=moduleImport("pflask").getMember("views").getMember("View").getASubclass().getMember("my_internal_method").getParameter(0)
17+
pass
18+
19+
int_instance = IntMyView() #$ use=moduleImport("pflask").getMember("views").getMember("View").getASubclass().getReturn()

python/ql/test/library-tests/ApiGraphs/test.py

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -75,27 +75,6 @@ def f():
7575
sink(foo) #$ use=moduleImport("danger").getMember("SOURCE")
7676

7777

78-
# Subclasses
79-
80-
from flask.views import View #$ use=moduleImport("flask").getMember("views").getMember("View")
81-
82-
class MyView(View): #$ use=moduleImport("flask").getMember("views").getMember("View").getASubclass()
83-
myvar = 45 #$ use=moduleImport("flask").getMember("views").getMember("View").getASubclass().getMember("myvar")
84-
def my_method(self): #$ use=moduleImport("flask").getMember("views").getMember("View").getASubclass().getMember("my_method")
85-
pass
86-
87-
instance = MyView() #$ use=moduleImport("flask").getMember("views").getMember("View").getASubclass().getReturn()
88-
89-
def internal():
90-
from pflask.views import View #$ use=moduleImport("pflask").getMember("views").getMember("View")
91-
class IntMyView(View): #$ use=moduleImport("pflask").getMember("views").getMember("View").getASubclass()
92-
my_internal_var = 35 #$ use=moduleImport("pflask").getMember("views").getMember("View").getASubclass().getMember("my_internal_var")
93-
def my_internal_method(self): #$ use=moduleImport("pflask").getMember("views").getMember("View").getASubclass().getMember("my_internal_method")
94-
pass
95-
96-
int_instance = IntMyView() #$ use=moduleImport("pflask").getMember("views").getMember("View").getASubclass().getReturn()
97-
98-
9978
# Built-ins
10079

10180
def use_of_builtins():

0 commit comments

Comments
 (0)