Skip to content

Commit 74d529d

Browse files
authored
Merge pull request #9918 from hmac/hmac/mime-type-match
Ruby: Model Mime::Type
2 parents 157bbcc + 452811d commit 74d529d

File tree

7 files changed

+928
-813
lines changed

7 files changed

+928
-813
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
category: minorAnalysis
3+
---
4+
* Arguments to `Mime::Type#match?` and `Mime::Type#=~` are now recognised as
5+
regular expression sources.

ruby/ql/lib/codeql/ruby/Regexp.qll

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -92,20 +92,32 @@ private class ParsedStringRegExp extends RegExp {
9292
override string getFlags() { none() }
9393
}
9494

95+
/** Provides a class for modeling regular expression interpretations. */
96+
module RegExpInterpretation {
97+
/**
98+
* A node that is not a regular expression literal, but is used in places that
99+
* may interpret it as one. Instances of this class are typically strings that
100+
* flow to method calls like `RegExp.new`.
101+
*/
102+
abstract class Range extends DataFlow::Node { }
103+
}
104+
95105
/**
96-
* Holds if `source` may be interpreted as a regular expression.
106+
* A node interpreted as a regular expression.
97107
*/
98-
private predicate isInterpretedAsRegExp(DataFlow::Node source) {
99-
// The first argument to an invocation of `Regexp.new` or `Regexp.compile`.
100-
source = API::getTopLevelMember("Regexp").getAMethodCall(["compile", "new"]).getArgument(0)
101-
or
102-
// The argument of a call that coerces the argument to a regular expression.
103-
exists(DataFlow::CallNode mce |
104-
mce.getMethodName() = ["match", "match?"] and
105-
source = mce.getArgument(0) and
106-
// exclude https://ruby-doc.org/core-2.4.0/Regexp.html#method-i-match
107-
not mce.getReceiver().asExpr().getExpr() instanceof AST::RegExpLiteral
108-
)
108+
class StdLibRegExpInterpretation extends RegExpInterpretation::Range {
109+
StdLibRegExpInterpretation() {
110+
// The first argument to an invocation of `Regexp.new` or `Regexp.compile`.
111+
this = API::getTopLevelMember("Regexp").getAMethodCall(["compile", "new"]).getArgument(0)
112+
or
113+
// The argument of a call that coerces the argument to a regular expression.
114+
exists(DataFlow::CallNode mce |
115+
mce.getMethodName() = ["match", "match?"] and
116+
this = mce.getArgument(0) and
117+
// exclude https://ruby-doc.org/core-2.4.0/Regexp.html#method-i-match
118+
not mce.getReceiver().asExpr().getExpr() instanceof AST::RegExpLiteral
119+
)
120+
}
109121
}
110122

111123
private class RegExpConfiguration extends Configuration {
@@ -120,7 +132,7 @@ private class RegExpConfiguration extends Configuration {
120132
)
121133
}
122134

123-
override predicate isSink(DataFlow::Node sink) { isInterpretedAsRegExp(sink) }
135+
override predicate isSink(DataFlow::Node sink) { sink instanceof RegExpInterpretation::Range }
124136

125137
override predicate isSanitizer(DataFlow::Node node) {
126138
// stop flow if `node` is receiver of

ruby/ql/lib/codeql/ruby/frameworks/ActionController.qll

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ class ActionControllerActionMethod extends Method, HTTP::Server::RequestHandler:
8383
* Gets a route to this handler, if one exists.
8484
* May return multiple results.
8585
*/
86-
ActionDispatch::Route getARoute() {
86+
ActionDispatch::Routing::Route getARoute() {
8787
exists(string name |
8888
isRoute(result, name, controllerClass) and
8989
isActionControllerMethod(this, name, controllerClass)
@@ -93,10 +93,10 @@ class ActionControllerActionMethod extends Method, HTTP::Server::RequestHandler:
9393

9494
pragma[nomagic]
9595
private predicate isRoute(
96-
ActionDispatch::Route route, string name, ActionControllerControllerClass controllerClass
96+
ActionDispatch::Routing::Route route, string name, ActionControllerControllerClass controllerClass
9797
) {
9898
route.getController() + "_controller" =
99-
ActionDispatch::underscore(namespaceDeclaration(controllerClass)) and
99+
ActionDispatch::Routing::underscore(namespaceDeclaration(controllerClass)) and
100100
name = route.getAction()
101101
}
102102

0 commit comments

Comments
 (0)