@@ -55,35 +55,38 @@ private module Django {
5555 /** Gets a reference to the `django.db.connection` object. */
5656 DataFlow:: Node connection ( ) { result = connection ( DataFlow:: TypeTracker:: end ( ) ) }
5757
58- /** Gets a reference to the `django.db.connection.cursor` class. */
59- private DataFlow:: Node classCursor ( DataFlow:: TypeTracker t ) {
60- t .start ( ) and
61- result = DataFlow:: importNode ( "django.db.connection.cursor" )
62- or
63- t .startInAttr ( "cursor" ) and
64- result = connection ( )
65- or
66- exists ( DataFlow:: TypeTracker t2 | result = classCursor ( t2 ) .track ( t2 , t ) )
67- }
58+ /** Provides models for the `django.db.connection.cursor` method. */
59+ module cursor {
60+ /** Gets a reference to the `django.db.connection.cursor` metod. */
61+ private DataFlow:: Node methodRef ( DataFlow:: TypeTracker t ) {
62+ t .start ( ) and
63+ result = DataFlow:: importNode ( "django.db.connection.cursor" )
64+ or
65+ t .startInAttr ( "cursor" ) and
66+ result = connection ( )
67+ or
68+ exists ( DataFlow:: TypeTracker t2 | result = methodRef ( t2 ) .track ( t2 , t ) )
69+ }
6870
69- /** Gets a reference to the `django.db.connection.cursor` class . */
70- DataFlow:: Node classCursor ( ) { result = classCursor ( DataFlow:: TypeTracker:: end ( ) ) }
71+ /** Gets a reference to the `django.db.connection.cursor` metod . */
72+ DataFlow:: Node methodRef ( ) { result = methodRef ( DataFlow:: TypeTracker:: end ( ) ) }
7173
72- /** Gets a reference to an instance of `django.db.connection.cursor`. */
73- private DataFlow:: Node cursor ( DataFlow:: TypeTracker t ) {
74- t .start ( ) and
75- result .asCfgNode ( ) .( CallNode ) .getFunction ( ) = classCursor ( ) .asCfgNode ( )
76- or
77- exists ( DataFlow:: TypeTracker t2 | result = cursor ( t2 ) .track ( t2 , t ) )
78- }
74+ /** Gets a reference to a result of calling `django.db.connection.cursor`. */
75+ private DataFlow:: Node methodResult ( DataFlow:: TypeTracker t ) {
76+ t .start ( ) and
77+ result .asCfgNode ( ) .( CallNode ) .getFunction ( ) = methodRef ( ) .asCfgNode ( )
78+ or
79+ exists ( DataFlow:: TypeTracker t2 | result = methodResult ( t2 ) .track ( t2 , t ) )
80+ }
7981
80- /** Gets a reference to an instance of `django.db.connection.cursor`. */
81- DataFlow:: Node cursor ( ) { result = cursor ( DataFlow:: TypeTracker:: end ( ) ) }
82+ /** Gets a reference to a result of calling `django.db.connection.cursor`. */
83+ DataFlow:: Node methodResult ( ) { result = methodResult ( DataFlow:: TypeTracker:: end ( ) ) }
84+ }
8285
8386 /** Gets a reference to the `django.db.connection.cursor.execute` function. */
8487 private DataFlow:: Node execute ( DataFlow:: TypeTracker t ) {
8588 t .startInAttr ( "execute" ) and
86- result = cursor ( )
89+ result = cursor:: methodResult ( )
8790 or
8891 exists ( DataFlow:: TypeTracker t2 | result = execute ( t2 ) .track ( t2 , t ) )
8992 }
@@ -107,49 +110,59 @@ private module Django {
107110
108111 /** Provides models for the `django.db.models` module. */
109112 module models {
110- /** Gets a reference to the `django.db.models.Model` class. */
111- private DataFlow:: Node classModel ( DataFlow:: TypeTracker t ) {
112- t .start ( ) and
113- result = DataFlow:: importNode ( "django.db.models.Model" )
114- or
115- t .startInAttr ( "Model" ) and
116- result = models ( )
117- or
118- exists ( DataFlow:: TypeTracker t2 | result = classModel ( t2 ) .track ( t2 , t ) )
119- }
113+ /** Provides models for the `django.db.models.Model` class. */
114+ module Model {
115+ /** Gets a reference to the `django.db.models.Model` class. */
116+ private DataFlow:: Node classRef ( DataFlow:: TypeTracker t ) {
117+ t .start ( ) and
118+ result = DataFlow:: importNode ( "django.db.models.Model" )
119+ or
120+ t .startInAttr ( "Model" ) and
121+ result = models ( )
122+ or
123+ exists ( DataFlow:: TypeTracker t2 | result = classRef ( t2 ) .track ( t2 , t ) )
124+ }
120125
121- /** Gets a reference to the `django.db.models.Model` class. */
122- DataFlow:: Node classModel ( ) { result = classModel ( DataFlow:: TypeTracker:: end ( ) ) }
126+ /** Gets a reference to the `django.db.models.Model` class. */
127+ DataFlow:: Node classRef ( ) { result = classRef ( DataFlow:: TypeTracker:: end ( ) ) }
123128
124- /** Gets a definition of a subclass the `django.db.models.Model` class. */
125- class ClassModelSubclassDef extends ControlFlowNode {
126- string name ;
129+ /** Gets a definition of a subclass the `django.db.models.Model` class. */
130+ class SubclassDef extends ControlFlowNode {
131+ string name ;
127132
128- ClassModelSubclassDef ( ) {
129- exists ( ClassExpr ce |
130- this .getNode ( ) = ce and
131- ce .getABase ( ) = classModel ( ) .asExpr ( ) and
132- ce .getName ( ) = name
133- )
134- }
133+ SubclassDef ( ) {
134+ exists ( ClassExpr ce |
135+ this .getNode ( ) = ce and
136+ ce .getABase ( ) = classRef ( ) .asExpr ( ) and
137+ ce .getName ( ) = name
138+ )
139+ }
135140
136- string getName ( ) { result = name }
137- }
141+ string getName ( ) { result = name }
142+ }
138143
139- /**
140- * A reference to a class that is a subclass of the `django.db.models.Model` class.
141- * This is quite an approximation, since it simply matches identifiers.
142- */
143- class ClassModelSubclass extends DataFlow:: CfgNode {
144- override NameNode node ;
144+ /**
145+ * A reference to a class that is a subclass of the `django.db.models.Model` class.
146+ * This is an approximation, since it simply matches identifiers.
147+ */
148+ private DataFlow:: Node subclassRef ( DataFlow:: TypeTracker t ) {
149+ t .start ( ) and
150+ result .asCfgNode ( ) .( NameNode ) .getId ( ) = any ( SubclassDef cd ) .getName ( )
151+ or
152+ exists ( DataFlow:: TypeTracker t2 | result = subclassRef ( t2 ) .track ( t2 , t ) )
153+ }
145154
146- ClassModelSubclass ( ) { node .getId ( ) = any ( ClassModelSubclassDef cd ) .getName ( ) }
155+ /**
156+ * A reference to a class that is a subclass of the `django.db.models.Model` class.
157+ * This is an approximation, since it simply matches identifiers.
158+ */
159+ DataFlow:: Node subclassRef ( ) { result = subclassRef ( DataFlow:: TypeTracker:: end ( ) ) }
147160 }
148161
149162 /** Gets a reference to the `objects` object of a django model. */
150163 private DataFlow:: Node objects ( DataFlow:: TypeTracker t ) {
151164 t .startInAttr ( "objects" ) and
152- result instanceof ClassModelSubclass
165+ result = Model :: subclassRef ( )
153166 or
154167 exists ( DataFlow:: TypeTracker t2 | result = objects ( t2 ) .track ( t2 , t ) )
155168 }
@@ -239,7 +252,7 @@ private module Django {
239252
240253 ObjectsAnnotate ( ) {
241254 node .getFunction ( ) = django:: db:: models:: objects_attr ( "annotate" ) .asCfgNode ( ) and
242- raw = node .getArg ( 0 ) and
255+ raw in [ node .getArg ( 0 ) , node . getArgByName ( _ ) ] and
243256 raw .getFunction ( ) = django:: db:: models:: classRawSQL ( ) .asCfgNode ( )
244257 }
245258
@@ -261,6 +274,10 @@ private module Django {
261274
262275 ObjectsExtra ( ) { node .getFunction ( ) = django:: db:: models:: objects_attr ( "extra" ) .asCfgNode ( ) }
263276
264- override DataFlow:: Node getSql ( ) { result .asCfgNode ( ) = node .getArg ( 0 ) }
277+ override DataFlow:: Node getSql ( ) {
278+ result .asCfgNode ( ) =
279+ [ node .getArg ( [ 0 .. 5 ] ) ,
280+ node .getArgByName ( [ "select" , "where" , "params" , "tables" , "order_by" , "select_params" ] ) ]
281+ }
265282 }
266283}
0 commit comments