Skip to content

Commit 8fdc487

Browse files
committed
Ruby: rack - replace RackApplication with just the rack RequestHandler
1 parent 6008c7b commit 8fdc487

File tree

6 files changed

+30
-105
lines changed

6 files changed

+30
-105
lines changed

ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowPublic.qll

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1010,23 +1010,6 @@ class ModuleNode instanceof Module {
10101010
*/
10111011
MethodNode getAnInstanceMethod() { result = this.getInstanceMethod(_) }
10121012

1013-
/**
1014-
* Gets the singleton method named `name` available in this module, including methods inherited from ancestors.
1015-
*
1016-
* Overridden methods are not included.
1017-
*/
1018-
MethodNode getSingletonMethod(string name) {
1019-
result.asCallableAstNode() = super.getAnOwnSingletonMethod() and
1020-
result.getMethodName() = name
1021-
}
1022-
1023-
/**
1024-
* Gets a singleton method available in this module, including methods inherited from ancestors.
1025-
*
1026-
* Overridden methods are not included.
1027-
*/
1028-
MethodNode getASingletonMethod() { result = this.getSingletonMethod(_) }
1029-
10301013
/**
10311014
* Gets the enclosing module, as it appears in the qualified name of this module.
10321015
*

ruby/ql/lib/codeql/ruby/frameworks/actiondispatch/internal/Request.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ module Request {
128128
private import codeql.ruby.frameworks.Rack
129129

130130
private class RackEnv extends Env {
131-
RackEnv() { this = any(Rack::App::RackApplication app).getEnv().getALocalUse() }
131+
RackEnv() { this = any(Rack::App::RequestHandler handler).getEnv().getALocalUse() }
132132
}
133133

134134
/**

ruby/ql/lib/codeql/ruby/frameworks/rack/internal/App.qll

Lines changed: 13 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ private import Response::Private as RP
1212
* A callable node that takes a single argument and, if it has a method name,
1313
* is called "call".
1414
*/
15-
private class PotentialCallNode extends DataFlow::CallableNode {
16-
PotentialCallNode() {
15+
private class PotentialRequestHandler extends DataFlow::CallableNode {
16+
PotentialRequestHandler() {
1717
this.getNumberOfParameters() = 1 and
1818
(
1919
this.(DataFlow::MethodNode).getMethodName() = "call"
@@ -32,26 +32,14 @@ private class PotentialCallNode extends DataFlow::CallableNode {
3232
}
3333
}
3434

35-
/**
36-
* A callable node that looks like it implements the rack specification.
37-
*/
38-
private class CallNode extends PotentialCallNode {
39-
private RP::PotentialResponseNode resp;
40-
41-
CallNode() { resp = trackRackResponse(this) }
42-
43-
/** Gets a response returned from a request to this application. */
44-
RP::PotentialResponseNode getAResponse() { result = resp }
45-
}
46-
47-
private DataFlow::LocalSourceNode trackRackResponse(TypeBackTracker t, PotentialCallNode call) {
35+
private DataFlow::LocalSourceNode trackRackResponse(TypeBackTracker t, PotentialRequestHandler call) {
4836
t.start() and
4937
result = call.getAReturnNode().getALocalSource()
5038
or
5139
exists(TypeBackTracker t2 | result = trackRackResponse(t2, call).backtrack(t2, t))
5240
}
5341

54-
private RP::PotentialResponseNode trackRackResponse(PotentialCallNode call) {
42+
private RP::PotentialResponseNode trackRackResponse(PotentialRequestHandler call) {
5543
result = trackRackResponse(TypeBackTracker::end(), call)
5644
}
5745

@@ -66,7 +54,7 @@ module App {
6654
* (traditionally called `env`) and returns a rack-compatible response.
6755
*/
6856
deprecated class AppCandidate extends DataFlow::ClassNode {
69-
private CallNode call;
57+
private RequestHandler call;
7058
private RP::PotentialResponseNode resp;
7159

7260
AppCandidate() {
@@ -84,64 +72,18 @@ module App {
8472
RP::PotentialResponseNode getResponse() { result = resp }
8573
}
8674

87-
private newtype TApp =
88-
TClassApp(DataFlow::ClassNode cn, CallNode call) or
89-
TAnonymousApp(CallNode call)
90-
9175
/**
92-
* A rack application. This is either some object that responds to `call`
93-
* taking a single argument and returns a rack response, or a lambda or
94-
* proc that takes a single `env` argument and returns a rack response.
76+
* A callable node that looks like it implements the rack specification.
9577
*/
96-
abstract class RackApplication extends TApp {
97-
/** Gets a textual representation of this element. */
98-
string toString() { result = "Rack application" }
99-
100-
/** Gets the `DataFlow::CallableNode` that will handle requests to this app. */
101-
abstract CallNode getCall();
102-
103-
/** Gets a response returned from a request to this app. */
104-
RP::PotentialResponseNode getAResponse() { result = this.getCall().getAResponse() }
105-
106-
/** Gets the `env` parameter passed to this app when it handles a request. */
107-
DataFlow::ParameterNode getEnv() { result = this.getCall().getParameter(0) }
108-
}
109-
110-
/**
111-
* A rack application using a `DataFlow::ClassNode`. The class has either
112-
* an instance method or a singleton method named "call" which takes a
113-
* single `env` argument and returns a rack response.
114-
*/
115-
private class ClassRackApplication extends TApp, RackApplication {
116-
private DataFlow::ClassNode cn;
117-
private CallNode call;
118-
119-
ClassRackApplication() {
120-
this = TClassApp(cn, call) and
121-
call = [cn.getInstanceMethod("call"), cn.getSingletonMethod("call")]
122-
}
123-
124-
override string toString() { result = "Rack application: " + cn.toString() }
125-
126-
override CallNode getCall() { result = call }
127-
}
128-
129-
/**
130-
* A rack application that is either a lambda or a proc, which takes a
131-
* single `env` argument and returns a rack response.
132-
*/
133-
private class AnonymousRackApplication extends TApp, RackApplication {
134-
private CallNode call;
78+
class RequestHandler extends PotentialRequestHandler {
79+
private RP::PotentialResponseNode resp;
13580

136-
AnonymousRackApplication() {
137-
this = TAnonymousApp(call) and
138-
not exists(DataFlow::ClassNode cn |
139-
call = [cn.getInstanceMethod(_), cn.getSingletonMethod(_)]
140-
)
141-
}
81+
RequestHandler() { resp = trackRackResponse(this) }
14282

143-
override string toString() { result = "Rack application: " + call.toString() }
83+
/** Gets the `env` parameter passed to this request handler. */
84+
DataFlow::ParameterNode getEnv() { result = this.getParameter(0) }
14485

145-
override CallNode getCall() { result = call }
86+
/** Gets a response returned from this request handler. */
87+
RP::PotentialResponseNode getAResponse() { result = resp }
14688
}
14789
}

ruby/ql/lib/codeql/ruby/frameworks/rack/internal/Response.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ module Public {
9191
/** A `DataFlow::Node` returned from a rack request. */
9292
class ResponseNode extends Http::Server::HttpResponse::Range instanceof Private::PotentialResponseNode
9393
{
94-
ResponseNode() { this = any(A::App::RackApplication app).getAResponse() }
94+
ResponseNode() { this = any(A::App::RequestHandler handler).getAResponse() }
9595

9696
override DataFlow::Node getBody() { result = this.(Private::PotentialResponseNode).getBody() }
9797

ruby/ql/test/library-tests/frameworks/rack/Rack.expected

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
1-
rackApps
2-
| Rack application: -> { ... } | rack_apps.rb:21:17:21:19 | env | rack_apps.rb:21:24:21:48 | call to [] |
3-
| Rack application: Baz | rack.rb:60:12:60:14 | env | rack.rb:66:7:66:22 | call to [] |
4-
| Rack application: Baz | rack.rb:60:12:60:14 | env | rack.rb:73:5:73:21 | call to [] |
5-
| Rack application: ClassApp | rack_apps.rb:16:17:16:19 | env | rack_apps.rb:17:5:17:28 | call to [] |
6-
| Rack application: HelloWorld | rack.rb:2:12:2:14 | env | rack.rb:8:5:8:38 | call to [] |
7-
| Rack application: InstanceApp | rack_apps.rb:6:12:6:14 | env | rack_apps.rb:10:12:10:34 | call to [] |
8-
| Rack application: Logger | rack.rb:30:12:30:14 | env | rack.rb:35:5:35:26 | call to [] |
9-
| Rack application: Proxy | rack.rb:17:12:17:18 | the_env | rack.rb:20:5:20:27 | call to [] |
10-
| Rack application: Qux | rack.rb:79:17:79:19 | env | rack.rb:93:5:93:78 | call to finish |
11-
| Rack application: Redirector | rack.rb:40:12:40:14 | env | rack.rb:43:5:43:45 | call to [] |
12-
| Rack application: { ... } | rack_apps.rb:23:24:23:26 | env | rack_apps.rb:23:29:23:51 | call to [] |
1+
rackRequestHandlers
2+
| rack.rb:2:3:9:5 | call | rack.rb:2:12:2:14 | env | rack.rb:8:5:8:38 | call to [] |
3+
| rack.rb:17:3:21:5 | call | rack.rb:17:12:17:18 | the_env | rack.rb:20:5:20:27 | call to [] |
4+
| rack.rb:30:3:36:5 | call | rack.rb:30:12:30:14 | env | rack.rb:35:5:35:26 | call to [] |
5+
| rack.rb:40:3:44:5 | call | rack.rb:40:12:40:14 | env | rack.rb:43:5:43:45 | call to [] |
6+
| rack.rb:60:3:62:5 | call | rack.rb:60:12:60:14 | env | rack.rb:66:7:66:22 | call to [] |
7+
| rack.rb:60:3:62:5 | call | rack.rb:60:12:60:14 | env | rack.rb:73:5:73:21 | call to [] |
8+
| rack.rb:79:3:81:5 | call | rack.rb:79:17:79:19 | env | rack.rb:93:5:93:78 | call to finish |
9+
| rack_apps.rb:6:3:12:5 | call | rack_apps.rb:6:12:6:14 | env | rack_apps.rb:10:12:10:34 | call to [] |
10+
| rack_apps.rb:16:3:18:5 | call | rack_apps.rb:16:17:16:19 | env | rack_apps.rb:17:5:17:28 | call to [] |
11+
| rack_apps.rb:21:14:21:50 | -> { ... } | rack_apps.rb:21:17:21:19 | env | rack_apps.rb:21:24:21:48 | call to [] |
12+
| rack_apps.rb:23:21:23:53 | { ... } | rack_apps.rb:23:24:23:26 | env | rack_apps.rb:23:29:23:51 | call to [] |
1313
rackResponseContentTypes
1414
| rack.rb:8:5:8:38 | call to [] | rack.rb:7:34:7:45 | "text/plain" |
1515
| rack.rb:20:5:20:27 | call to [] | rack.rb:19:28:19:38 | "text/html" |

ruby/ql/test/library-tests/frameworks/rack/Rack.ql

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@ private import codeql.ruby.AST
22
private import codeql.ruby.frameworks.Rack
33
private import codeql.ruby.DataFlow
44

5-
query predicate rackApps(
6-
Rack::App::RackApplication app, DataFlow::ParameterNode env, Rack::Response::ResponseNode resp
5+
query predicate rackRequestHandlers(
6+
Rack::App::RequestHandler handler, DataFlow::ParameterNode env, Rack::Response::ResponseNode resp
77
) {
8-
env = app.getEnv() and resp = app.getAResponse()
8+
env = handler.getEnv() and resp = handler.getAResponse()
99
}
1010

1111
query predicate rackResponseContentTypes(

0 commit comments

Comments
 (0)