mirror of
https://github.com/github/codeql.git
synced 2026-02-12 05:01:06 +01:00
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
```
This commit is contained in:
@@ -55,6 +55,7 @@ module Filters {
|
||||
private class FilterCall extends MethodCallCfgNode {
|
||||
private FilterKind kind;
|
||||
|
||||
pragma[nomagic]
|
||||
FilterCall() {
|
||||
this.getExpr().getEnclosingModule() = any(ActionControllerClass c).getADeclaration() and
|
||||
this.getMethodName() = ["", "prepend_", "append_", "skip_"] + kind + "_action"
|
||||
@@ -62,21 +63,27 @@ module Filters {
|
||||
|
||||
FilterKind getKind() { result = kind }
|
||||
|
||||
pragma[nomagic]
|
||||
private ActionControllerActionMethod getAnActionCand(string name) {
|
||||
result = getADescendentAction(this) and
|
||||
name = result.getName() and
|
||||
// A filter cannot apply to another filter
|
||||
not result = any(Filter f).getFilterCallable() and
|
||||
// Only include routable actions. This can exclude valid actions if we can't parse the `routes.rb` file fully.
|
||||
exists(result.getARoute())
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an action which this filter is applied to.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
ActionControllerActionMethod getAnAction() {
|
||||
// A filter cannot apply to another filter
|
||||
result != any(Filter f).getFilterCallable() and
|
||||
// Only include routable actions. This can exclude valid actions if we can't parse the `routes.rb` file fully.
|
||||
exists(result.getARoute()) and
|
||||
(
|
||||
result.getName() = this.getOnlyArgument()
|
||||
exists(string name | result = this.getAnActionCand(name) |
|
||||
name = this.getOnlyArgument()
|
||||
or
|
||||
not exists(this.getOnlyArgument()) and
|
||||
forall(string except | except = this.getExceptArgument() | result.getName() != except)
|
||||
) and
|
||||
result = getADescendentAction(this)
|
||||
forall(string except | except = this.getExceptArgument() | name != except)
|
||||
)
|
||||
}
|
||||
|
||||
private string getOnlyArgument() {
|
||||
|
||||
Reference in New Issue
Block a user