Skip to content

Commit 3583394

Browse files
committed
Ruby: Fix bad join
Before ``` Evaluated relational algebra for predicate Filters::Filters::FilterCall.getAnAction/0#dispred#9c0da667@85a4cbtp with tuple counts: 394650 ~2% {2} r1 = `__#Module::ModuleBase.getAMethod/0#dispred#56626ed3Merge_Module::ModuleBase.getModule/0#dispred#4f2c__#shared` AND NOT `_Filters::Filters::FilterCall.getExceptArgument/0#dispred#515c95c0__#Method::Method.getName/0#dispre__#antijoin_rhs`(FIRST 2) {2} | AND NOT `project#Filters::Filters::FilterCall.getOnlyArgument/0#dispred#f337e70f`(FIRST 1) 380366 ~0% {2} | SCAN OUTPUT In.1, In.0 29453 ~0% {2} r2 = JOIN `_#Module::ModuleBase.getAMethod/0#dispred#56626ed3Merge__#AST::AstNode.getEnclosingModule/0#dispred#__#shared` WITH project#ActionController::ActionControllerActionMethod#6db6f5e0 ON FIRST 1 OUTPUT Lhs.0, Lhs.1 366017 ~0% {2} r3 = JOIN `_#Module::ModuleBase.getAMethod/0#dispred#56626ed3Merge_Module::ModuleBase.getModule/0#dispred#4f2ca__#shared` WITH project#ActionController::ActionControllerActionMethod#6db6f5e0 ON FIRST 1 OUTPUT Lhs.0, Lhs.1 395470 ~0% {2} r4 = r2 UNION r3 395470 ~0% {3} | JOIN WITH `Method::Method.getName/0#dispred#2acbf239` ON FIRST 1 OUTPUT Lhs.1, Rhs.1, Lhs.0 2227 ~0% {2} | JOIN WITH `Filters::Filters::FilterCall.getOnlyArgument/0#dispred#f337e70f` ON FIRST 2 OUTPUT Lhs.2, Lhs.0 382593 ~0% {2} r5 = r1 UNION r4 133735 ~4% {2} | JOIN WITH `project#ActionController::ActionControllerActionMethod.getARoute/0#dispred#9eb85e56` ON FIRST 1 OUTPUT Lhs.1, Lhs.0 540556870 ~2% {3} | JOIN WITH Filters::Filters::Filter#a42c5138 CARTESIAN PRODUCT OUTPUT Rhs.0, Lhs.0, Lhs.1 525979755 ~127% {3} | JOIN WITH `Filters::Filters::FilterImpl.getFilterCallable/0#dispred#451bf7d7` ON FIRST 1 OUTPUT Lhs.1, Lhs.2, Rhs.1 {3} | REWRITE WITH TEST InOut.1 != InOut.2 525979755 ~407036% {2} | SCAN OUTPUT In.0, In.1 return r5 ``` After ``` Evaluated relational algebra for predicate Filters::Filters::FilterCall.getAnAction/0#91dba45c@74dfcepp with tuple counts: 1363 ~4% {2} r1 = JOIN `Filters::Filters::FilterCall.getAnActionCand/1#f053150d` WITH `Filters::Filters::FilterCall.getOnlyArgument/0#dispred#f337e70f` ON FIRST 2 OUTPUT Lhs.0, Lhs.2 140978 ~0% {3} r2 = `Filters::Filters::FilterCall.getAnActionCand/1#f053150d` AND NOT `Filters::Filters::FilterCall.getExceptArgument/0#dispred#515c95c0#fb`(FIRST 2) {3} | AND NOT `project#Filters::Filters::FilterCall.getOnlyArgument/0#dispred#f337e70f`(FIRST 1) 132372 ~3% {2} | SCAN OUTPUT In.0, In.2 133735 ~4% {2} r3 = r1 UNION r2 return r3 ```
1 parent 19179d5 commit 3583394

File tree

1 file changed

+16
-9
lines changed
  • ruby/ql/lib/codeql/ruby/frameworks/actioncontroller

1 file changed

+16
-9
lines changed

ruby/ql/lib/codeql/ruby/frameworks/actioncontroller/Filters.qll

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -55,28 +55,35 @@ module Filters {
5555
private class FilterCall extends MethodCallCfgNode {
5656
private FilterKind kind;
5757

58+
pragma[nomagic]
5859
FilterCall() {
5960
this.getExpr().getEnclosingModule() = any(ActionControllerClass c).getADeclaration() and
6061
this.getMethodName() = ["", "prepend_", "append_", "skip_"] + kind + "_action"
6162
}
6263

6364
FilterKind getKind() { result = kind }
6465

66+
pragma[nomagic]
67+
private ActionControllerActionMethod getAnActionCand(string name) {
68+
result = getADescendentAction(this) and
69+
name = result.getName() and
70+
// A filter cannot apply to another filter
71+
not result = any(Filter f).getFilterCallable() and
72+
// Only include routable actions. This can exclude valid actions if we can't parse the `routes.rb` file fully.
73+
exists(result.getARoute())
74+
}
75+
6576
/**
6677
* Gets an action which this filter is applied to.
6778
*/
79+
pragma[nomagic]
6880
ActionControllerActionMethod getAnAction() {
69-
// A filter cannot apply to another filter
70-
result != any(Filter f).getFilterCallable() and
71-
// Only include routable actions. This can exclude valid actions if we can't parse the `routes.rb` file fully.
72-
exists(result.getARoute()) and
73-
(
74-
result.getName() = this.getOnlyArgument()
81+
exists(string name | result = this.getAnActionCand(name) |
82+
name = this.getOnlyArgument()
7583
or
7684
not exists(this.getOnlyArgument()) and
77-
forall(string except | except = this.getExceptArgument() | result.getName() != except)
78-
) and
79-
result = getADescendentAction(this)
85+
forall(string except | except = this.getExceptArgument() | name != except)
86+
)
8087
}
8188

8289
private string getOnlyArgument() {

0 commit comments

Comments
 (0)