Skip to content

Commit ed9aa7d

Browse files
committed
Python: Write DjangoPathRoute in modern way
That is, assigning to fields instead of repeatedly using helper predicate
1 parent 5a0babe commit ed9aa7d

File tree

1 file changed

+38
-40
lines changed

1 file changed

+38
-40
lines changed

python/ql/src/semmle/python/web/django/General.qll

Lines changed: 38 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -34,25 +34,6 @@ private predicate django_regex_route(CallNode call, ControlFlowNode regex, Funct
3434
)
3535
}
3636

37-
private predicate django_path_route(CallNode call, ControlFlowNode route, FunctionValue view) {
38-
exists(Value route_maker |
39-
// Django 2.x and 3.x: https://docs.djangoproject.com/en/3.0/ref/urls/#path
40-
Value::named("django.urls.path") = route_maker and
41-
route_maker.getACall() = call and
42-
(
43-
call.getArg(0) = route
44-
or
45-
call.getArgByName("route") = route
46-
47-
) and
48-
(
49-
call.getArg(1).pointsTo(view)
50-
or
51-
call.getArgByName("view").pointsTo(view)
52-
)
53-
)
54-
}
55-
5637
class DjangoRouteRegex extends RegexString {
5738
DjangoRouteRegex() { django_regex_route(_, this.getAFlowNode(), _) }
5839
}
@@ -70,27 +51,6 @@ abstract class DjangoRoute extends CallNode {
7051
abstract int getNumPositionalArguments();
7152
}
7253

73-
class DjangoPathRoute extends DjangoRoute {
74-
75-
DjangoPathRoute() { django_path_route(this, _, _) }
76-
77-
override FunctionValue getViewFunction() { django_path_route(this, _, result) }
78-
79-
override string getANamedArgument() {
80-
// regexp taken from django:
81-
// https://github.com/django/django/blob/7d1bf29977bb368d7c28e7c6eb146db3b3009ae7/django/urls/resolvers.py#L199
82-
exists(StrConst route, string match |
83-
django_path_route(this, route.getAFlowNode(), _) and
84-
match = route.getText().regexpFind("<(?:(?<converter>[^>:]+):)?(?<parameter>\\w+)>", _, _) and
85-
result = match.regexpCapture("<(?:(?<converter>[^>:]+):)?(?<parameter>\\w+)>", 2)
86-
)
87-
}
88-
89-
override int getNumPositionalArguments() {
90-
none()
91-
}
92-
}
93-
9454
class DjangoRegexRoute extends DjangoRoute {
9555
DjangoRegexRoute() { django_regex_route(this, _, _) }
9656

@@ -111,3 +71,41 @@ class DjangoRegexRoute extends DjangoRoute {
11171
)
11272
}
11373
}
74+
75+
class DjangoPathRoute extends DjangoRoute {
76+
77+
ControlFlowNode route;
78+
FunctionValue view;
79+
80+
DjangoPathRoute() {
81+
// Django 2.x and 3.x: https://docs.djangoproject.com/en/3.0/ref/urls/#path
82+
this = Value::named("django.urls.path").getACall() and
83+
(
84+
route = this.getArg(0)
85+
or
86+
route = this.getArgByName("route")
87+
88+
) and
89+
(
90+
this.getArg(1).pointsTo(view)
91+
or
92+
this.getArgByName("view").pointsTo(view)
93+
)
94+
}
95+
96+
override FunctionValue getViewFunction() { result = view }
97+
98+
override string getANamedArgument() {
99+
// regexp taken from django:
100+
// https://github.com/django/django/blob/7d1bf29977bb368d7c28e7c6eb146db3b3009ae7/django/urls/resolvers.py#L199
101+
exists(StrConst route_str, string match |
102+
route_str = route.getNode() and
103+
match = route_str.getText().regexpFind("<(?:(?<converter>[^>:]+):)?(?<parameter>\\w+)>", _, _) and
104+
result = match.regexpCapture("<(?:(?<converter>[^>:]+):)?(?<parameter>\\w+)>", 2)
105+
)
106+
}
107+
108+
override int getNumPositionalArguments() {
109+
none()
110+
}
111+
}

0 commit comments

Comments
 (0)