Skip to content

Commit 8803fb2

Browse files
committed
Python: Refactor RouteSetup with default impl for getUrlPattern
Having multiple copies of the StrConst data-flow tracking code means that if we need to update this to be more sophisticated, we could easily forget to do it somewhere :| Until we have a proper `.getAPossibleStringValue` helper, this refactoring should be nice :)
1 parent 44683f2 commit 8803fb2

File tree

3 files changed

+13
-27
lines changed

3 files changed

+13
-27
lines changed

python/ql/src/experimental/semmle/python/Concepts.qll

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,8 +163,16 @@ module HTTP {
163163
* extend `RouteSetup` instead.
164164
*/
165165
abstract class Range extends DataFlow::Node {
166+
/** Gets the argument used to set the URL pattern. */
167+
abstract DataFlow::Node getUrlPatternArg();
168+
166169
/** Gets the URL pattern for this route, if it can be statically determined. */
167-
abstract string getUrlPattern();
170+
string getUrlPattern() {
171+
exists(StrConst str |
172+
DataFlow::localFlow(DataFlow::exprNode(str), this.getUrlPatternArg()) and
173+
result = str.getText()
174+
)
175+
}
168176

169177
/** Gets a function that will handle incoming requests for this route, if any. */
170178
abstract Function getARouteHandler();

python/ql/src/experimental/semmle/python/frameworks/Django.qll

Lines changed: 4 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -170,14 +170,8 @@ private module Django {
170170

171171
DjangoUrlsPathCall() { node.getFunction() = django::urls::path().asCfgNode() }
172172

173-
override string getUrlPattern() {
174-
exists(StrConst str, ControlFlowNode urlPatternArg |
175-
urlPatternArg = [node.getArg(0), node.getArgByName("route")]
176-
|
177-
DataFlow::localFlow(DataFlow::exprNode(str),
178-
any(DataFlow::Node n | n.asCfgNode() = urlPatternArg)) and
179-
result = str.getText()
180-
)
173+
override DataFlow::Node getUrlPatternArg() {
174+
result.asCfgNode() = [node.getArg(0), node.getArgByName("route")]
181175
}
182176

183177
override Function getARouteHandler() {
@@ -200,14 +194,8 @@ private module Django {
200194

201195
DjangoUrlsRePathCall() { node.getFunction() = django::urls::re_path().asCfgNode() }
202196

203-
override string getUrlPattern() {
204-
exists(StrConst str, ControlFlowNode urlPatternArg |
205-
urlPatternArg = [node.getArg(0), node.getArgByName("route")]
206-
|
207-
DataFlow::localFlow(DataFlow::exprNode(str),
208-
any(DataFlow::Node n | n.asCfgNode() = urlPatternArg)) and
209-
result = str.getText()
210-
)
197+
override DataFlow::Node getUrlPatternArg() {
198+
result.asCfgNode() = [node.getArg(0), node.getArgByName("route")]
211199
}
212200

213201
override Function getARouteHandler() {

python/ql/src/experimental/semmle/python/frameworks/Flask.qll

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -131,16 +131,6 @@ private module Flask {
131131
)
132132
)
133133
}
134-
135-
/** Gets the argument used to pass in the URL pattern. */
136-
abstract DataFlow::Node getUrlPatternArg();
137-
138-
override string getUrlPattern() {
139-
exists(StrConst str |
140-
DataFlow::localFlow(DataFlow::exprNode(str), this.getUrlPatternArg()) and
141-
result = str.getText()
142-
)
143-
}
144134
}
145135

146136
/**

0 commit comments

Comments
 (0)