@@ -79,6 +79,31 @@ module PEP249 {
79
79
* See https://www.python.org/dev/peps/pep-0249/#cursor.
80
80
*/
81
81
module cursor {
82
+ /**
83
+ * A source of database cursors (following PEP 249), extend this class to model new instances.
84
+ *
85
+ * This can include instantiations of the class, return values from function
86
+ * calls, or a special parameter that will be set when functions are called by external
87
+ * libraries.
88
+ *
89
+ * Use the predicate `Connection::instance()` to get references database cursors (following PEP 249).
90
+ *
91
+ * Extend this class if the module implementing PEP 249 offers more direct ways to obtain
92
+ * a connection than going through `connect`.
93
+ */
94
+ abstract class InstanceSource extends DataFlow:: LocalSourceNode { }
95
+
96
+ /** Gets a reference to a database cursor. */
97
+ private DataFlow:: LocalSourceNode instance ( DataFlow:: TypeTracker t ) {
98
+ t .start ( ) and
99
+ result instanceof InstanceSource
100
+ or
101
+ exists ( DataFlow:: TypeTracker t2 | result = instance ( t2 ) .track ( t2 , t ) )
102
+ }
103
+
104
+ /** Gets a reference to a database cursor. */
105
+ DataFlow:: Node instance ( ) { instance ( DataFlow:: TypeTracker:: end ( ) ) .flowsTo ( result ) }
106
+
82
107
/** Gets a reference to the `cursor` method on a database connection. */
83
108
private DataFlow:: LocalSourceNode methodRef ( DataFlow:: TypeTracker t ) {
84
109
t .startInAttr ( "cursor" ) and
@@ -90,6 +115,11 @@ module PEP249 {
90
115
/** Gets a reference to the `cursor` method on a database connection. */
91
116
DataFlow:: Node methodRef ( ) { methodRef ( DataFlow:: TypeTracker:: end ( ) ) .flowsTo ( result ) }
92
117
118
+ /** A call to the `cursor` method on a database connection */
119
+ private class CursorCall extends InstanceSource , DataFlow:: CallCfgNode {
120
+ CursorCall ( ) { this .getFunction ( ) = methodRef ( ) }
121
+ }
122
+
93
123
/** Gets a reference to a result of calling the `cursor` method on a database connection. */
94
124
private DataFlow:: LocalSourceNode methodResult ( DataFlow:: TypeTracker t ) {
95
125
t .start ( ) and
@@ -98,8 +128,14 @@ module PEP249 {
98
128
exists ( DataFlow:: TypeTracker t2 | result = methodResult ( t2 ) .track ( t2 , t ) )
99
129
}
100
130
101
- /** Gets a reference to a result of calling the `cursor` method on a database connection. */
102
- DataFlow:: Node methodResult ( ) { methodResult ( DataFlow:: TypeTracker:: end ( ) ) .flowsTo ( result ) }
131
+ /**
132
+ * DEPRECATED: Use `Cursor::instance()` to get references to database cursors instead.
133
+ *
134
+ * Gets a reference to a result of calling the `cursor` method on a database connection.
135
+ */
136
+ deprecated DataFlow:: Node methodResult ( ) {
137
+ methodResult ( DataFlow:: TypeTracker:: end ( ) ) .flowsTo ( result )
138
+ }
103
139
}
104
140
105
141
/**
@@ -112,7 +148,7 @@ module PEP249 {
112
148
*/
113
149
private DataFlow:: LocalSourceNode execute ( DataFlow:: TypeTracker t ) {
114
150
t .startInAttr ( "execute" ) and
115
- result in [ cursor:: methodResult ( ) , Connection:: instance ( ) ]
151
+ result in [ cursor:: instance ( ) , Connection:: instance ( ) ]
116
152
or
117
153
exists ( DataFlow:: TypeTracker t2 | result = execute ( t2 ) .track ( t2 , t ) )
118
154
}
0 commit comments