From fb86ef4aac22173a58f10d42dade5f1d0be890f7 Mon Sep 17 00:00:00 2001 From: Harry Maclean Date: Tue, 13 Dec 2022 12:03:07 +1300 Subject: [PATCH 01/12] Ruby: Model ActionController filters ActionController filters provide a way to register callbacks that run before, after or around an action (i.e. HTTP request handler). They run in the same class context as the action, so can get/set instance variables and generally interact with the action in arbitrary ways. In order to track flow between filters and actions, we have to model the callback chain. This commit does that. A later change will add dataflow steps to actually track flow through the chain. --- .../ruby/frameworks/ActionController.qll | 9 + .../frameworks/actioncontroller/Filters.qll | 362 ++++++++++++++++++ .../frameworks/ActionDispatch.expected | 80 +++- .../frameworks/ActionView.expected | 9 +- .../ActionController.expected | 89 +++-- .../action_controller/Filters.expected | 48 +++ .../frameworks/action_controller/Filters.ql | 5 + .../controllers/application_controller.rb | 13 + .../controllers/comments_controller.rb | 42 ++ .../controllers/photos_controller.rb | 6 + .../controllers/posts_controller.rb | 16 +- .../frameworks/action_controller/routes.rb | 11 + 12 files changed, 636 insertions(+), 54 deletions(-) create mode 100644 ruby/ql/lib/codeql/ruby/frameworks/actioncontroller/Filters.qll create mode 100644 ruby/ql/test/library-tests/frameworks/action_controller/Filters.expected create mode 100644 ruby/ql/test/library-tests/frameworks/action_controller/Filters.ql create mode 100644 ruby/ql/test/library-tests/frameworks/action_controller/controllers/application_controller.rb create mode 100644 ruby/ql/test/library-tests/frameworks/action_controller/routes.rb diff --git a/ruby/ql/lib/codeql/ruby/frameworks/ActionController.qll b/ruby/ql/lib/codeql/ruby/frameworks/ActionController.qll index 6fd1f77d554..ba365af167d 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/ActionController.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/ActionController.qll @@ -14,6 +14,15 @@ private import codeql.ruby.frameworks.Rails private import codeql.ruby.frameworks.internal.Rails private import codeql.ruby.dataflow.internal.DataFlowDispatch +/** + * Provides modeling for ActionController, which is part of the `actionpack` gem. + * Version: 7.0. + */ +module ActionController { + // TODO: move the rest of this file inside this module. + import codeql.ruby.frameworks.actioncontroller.Filters +} + /** * DEPRECATED: Import `codeql.ruby.frameworks.Rails` and use `Rails::ParamsCall` instead. */ diff --git a/ruby/ql/lib/codeql/ruby/frameworks/actioncontroller/Filters.qll b/ruby/ql/lib/codeql/ruby/frameworks/actioncontroller/Filters.qll new file mode 100644 index 00000000000..d5eeb05374a --- /dev/null +++ b/ruby/ql/lib/codeql/ruby/frameworks/actioncontroller/Filters.qll @@ -0,0 +1,362 @@ +/** + * Provides modeling for ActionController filters. + */ + +private import codeql.ruby.AST +private import codeql.ruby.frameworks.ActionController +private import codeql.ruby.controlflow.CfgNodes +private import codeql.ruby.controlflow.CfgNodes::ExprNodes +private import codeql.ruby.DataFlow +private import codeql.ruby.dataflow.internal.DataFlowPrivate as DataFlowPrivate +private import codeql.ruby.ast.internal.Constant + +/** + * Provides modeling for ActionController filters. + */ +module Filters { + private newtype TFilterKind = + TBeforeKind() or + TAfterKind() or + TAroundKind() + + /** + * Represents the kind of filter. + * "before" filters run before the action and "after" filters run after the + * action. "around" filters run around the action, `yield`ing to it at will. + */ + private class FilterKind extends TFilterKind { + string toString() { + this = TBeforeKind() and result = "before" + or + this = TAfterKind() and result = "after" + or + this = TAroundKind() and result = "around" + } + } + + /** + * A call to a class method that adds or removes a filter from the callback chain. + * This class exists to encapsulate common behavior between calls that + * register callbacks (`before_action`, `after_action` etc.) and calls that + * remove callbacks (`skip_before_action`, `skip_after_action` etc.) + */ + private class FilterCall extends MethodCallCfgNode { + private FilterKind kind; + + FilterCall() { + this.getExpr().getEnclosingModule() = any(ActionControllerClass c).getADeclaration() and + this.getMethodName() = ["", "prepend_", "append_", "skip_"] + kind + "_action" + } + + FilterKind getKind() { result = kind } + + /** + * Gets an action which this filter is applied to. + */ + ActionControllerActionMethod getAction() { + // 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() + or + not exists(this.getOnlyArgument()) and + forall(string except | except = this.getExceptArgument() | result.getName() != except) + ) and + ( + result = this.getExpr().getEnclosingModule().getAMethod() + or + exists(ModuleBase m | + m.getModule() = this.getExpr().getEnclosingModule().getModule().getADescendent() and + result = m.getAMethod() + ) + ) + } + + private string getOnlyArgument() { + exists(ExprCfgNode only | only = this.getKeywordArgument("only") | + // only: :index + result = only.getConstantValue().getStringlikeValue() + or + // only: [:index, :show] + // only: SOME_CONST_ARRAY + exists(ArrayLiteralCfgNode n | + isArrayConstant(only, n) and + result = n.getAnArgument().getConstantValue().getStringlikeValue() + ) + ) + } + + private string getExceptArgument() { + exists(ExprCfgNode except | except = this.getKeywordArgument("except") | + // except: :create + result = except.getConstantValue().getStringlikeValue() + or + // except: [:create, :update] + result = + except.(ArrayLiteralCfgNode).getAnArgument().getConstantValue().getStringlikeValue() + ) + } + + StringlikeLiteralCfgNode getFilterArgument() { result = this.getPositionalArgument(_) } + + /** + * Gets the callable that implements the filter with name `name`. + * This currently only finds methods in the local class or superclass. + * It doesn't handle: + * - lambdas + * - blocks + * - classes + * + * In the example below, the callable for the filter `:foo` is the method `foo`. + * ```rb + * class PostsController < ActionController::Base + * before_action :foo + * + * def foo + * end + * end + * ``` + */ + Callable getFilterCallable(string name) { + result.(MethodBase).getName() = name and + // Method in same class + ( + result.getEnclosingModule() = this.getExpr().getEnclosingModule() + or + // Method in superclass + result.getEnclosingModule().getModule() = + this.getExpr().getEnclosingModule().getModule().getSuperClass() + ) + } + } + + /** + * An argument to a call that registers a callback for one or more + * ActionController actions. These are commonly called filters. + * + * In the example below, the `before_action` call registers `set_user` as a + * callback for all actions in the controller. When a request is routed to + * `PostsController#index`, the method `set_user` will be called before + * `index` is executed. + * + * The `after_action` call registers `log_request` as a callback. This behaves + * similarly to `before_action` but the callback will be called _after_ the + * action has finished executing. + * + * The `around_action` call registers `trace_request` as a callback that will + * run _around_ the action. This means that `trace_request` will be called + * before the action, and will run until it `yield`s control. Then the action + * (or another callback) will be run. Once the action has run, control will be + * returned to `trace_request`, which will finish executing. + * + * Due to the complexity of dataflow around `yield` calls, currently only + * `before_action` and `after_action` callbacks are modeled fully here. + * + * ```rb + * class PostsController < ApplicationController + * before_action :set_user + * after_action :log_request + * around_action :trace_request + * + * def index + * @posts = @user.posts.all + * end + * + * private + * + * def set_user + * @user = User.find(session[:user_id]) + * end + * + * def log_request + * Logger.info(request.path) + * end + * + * def trace_request + * start = Time.now + * yield + * Logger.info("Request took #{Time.now = start} seconds") + * end + * end + * ``` + */ + private class Filter extends StringlikeLiteralCfgNode { + private FilterCall call; + private FilterKind kind; + + Filter() { + this = call.getFilterArgument() and + kind = call.getKind() and + call.getMethodName() = ["", "prepend_", "append_"] + kind + "_action" + } + + predicate isPrepended() { call.getMethodName().regexpMatch("^prepend.+$") } + + MethodCallCfgNode getCall() { result = call } + + FilterKind getKind() { result = kind } + + private ModuleBase getEnclosingModule() { result = call.getExpr().getEnclosingModule() } + + /** + * Holds if this callback is registered before `other`. This does not + * guarantee that the callback will be executed before `other`. For example, + * `after_action` callbacks are executed in reverse order. + */ + predicate registeredBefore(Filter other) { + // before_action :this, :other + // + // before_action :this + // before_action :other + this.getBasicBlock() = other.getBasicBlock() and this.getASuccessor+() = other + or + this.getEnclosingModule() = other.getEnclosingModule() and + this.getBasicBlock().strictlyDominates(other.getBasicBlock()) and + this != other + or + // This callback is in a superclass of `other`'s class. + // + // class A + // before_action :this + // + // class B < A + // before_action :other + other.getEnclosingModule().getModule() = this.getEnclosingModule().getModule().getASubClass+() + } + + /** + * Holds if this callback runs before `other`. + */ + private predicate runsBefore(Filter other, ActionControllerActionMethod action) { + other.getKind() = this.getKind() and + not this.skipped(action) and + not other.skipped(action) and + action = this.getAction() and + action = other.getAction() and + ( + not this.isPrepended() and + ( + not other.isPrepended() and + ( + this.getKind() = TBeforeKind() and + this.registeredBefore(other) + or + this.getKind() = TAfterKind() and + other.registeredBefore(this) + ) + or + other.isPrepended() and this.getKind() = TAfterKind() + ) + or + this.isPrepended() and + ( + not other.isPrepended() and + this.getKind() = TBeforeKind() + or + other.isPrepended() and + ( + this.getKind() = TBeforeKind() and this.registeredBefore(other) + or + this.getKind() = TAfterKind() and other.registeredBefore(this) + ) + ) + ) + } + + Filter getNextFilter(ActionControllerActionMethod action) { + result != this and + this.runsBefore(result, action) and + not exists(Filter mid | this.runsBefore(mid, action) | mid.runsBefore(result, action)) + } + + predicate skipped(ActionControllerActionMethod action) { + this = any(SkipFilter f | f.getKind() = this.getKind()).getSkippedFilter(action) + } + + private string getFilterName() { result = this.getConstantValue().getStringlikeValue() } + + Callable getFilterCallable() { result = call.getFilterCallable(this.getFilterName()) } + + ActionControllerActionMethod getAction() { result = call.getAction() } + } + + private class BeforeFilter extends Filter { + BeforeFilter() { this.getKind() = TBeforeKind() } + } + + private class AfterFilter extends Filter { + AfterFilter() { this.getKind() = TAfterKind() } + } + + /** + * A call to `skip_before_action`, `skip_after_action` or `skip_around_action`. + * This skips a previously registered callback. + * Like other filter calls, the `except` and `only` keyword arguments can be + * passed to restrict the actions that the callback is skipped for. + */ + private class SkipFilter extends StringlikeLiteralCfgNode { + private FilterCall call; + private FilterKind kind; + + SkipFilter() { + this = call.getFilterArgument() and + call.getMethodName() = "skip_" + kind + "_action" + } + + FilterKind getKind() { result = kind } + + private string getFilterName() { result = this.getConstantValue().getStringlikeValue() } + + Callable getFilterCallable() { result = call.getFilterCallable(this.getFilterName()) } + + ActionControllerActionMethod getAction() { result = call.getAction() } + + Filter getSkippedFilter(ActionControllerActionMethod action) { + not result instanceof SkipFilter and + action = this.getAction() and + action = result.getAction() and + result.getFilterCallable() = this.getFilterCallable() + } + } + + /** + * Holds if `pred` is called before `succ` in the callback chain for action `action`. + * `pred` and `succ` may be methods bound to callbacks or controller actions. + */ + predicate next(ActionControllerActionMethod action, Method pred, Method succ) { + exists(BeforeFilter f | pred = f.getFilterCallable() | + // Non-terminal before filter + succ = f.getNextFilter(action).getFilterCallable() + or + // Final before filter + not exists(f.getNextFilter(action)) and + not f.skipped(action) and + action = f.getAction() and + succ = action + ) + or + exists(AfterFilter f | + // First after filter + action = f.getAction() and + not f.skipped(action) and + pred = action and + succ = f.getFilterCallable() and + not exists(AfterFilter g | g.getNextFilter(action) = f) + or + // Subsequent after filter + pred = f.getFilterCallable() and + succ = f.getNextFilter(action).getFilterCallable() + ) + } + + /** + * Holds if `pred` is called before `succ` in the callback chain for some action. + * `pred` and `succ` may be methods bound to callbacks or controller actions. + */ + cached + predicate next(Method pred, Method succ) { + exists(ActionControllerActionMethod action | next(action, pred, succ)) + } +} diff --git a/ruby/ql/test/library-tests/frameworks/ActionDispatch.expected b/ruby/ql/test/library-tests/frameworks/ActionDispatch.expected index 849ed702151..9b55a95b8a1 100644 --- a/ruby/ql/test/library-tests/frameworks/ActionDispatch.expected +++ b/ruby/ql/test/library-tests/frameworks/ActionDispatch.expected @@ -1,4 +1,46 @@ actionDispatchRoutes +| action_controller/routes.rb:2:5:2:20 | call to resources | delete | users/:id | users | destroy | +| action_controller/routes.rb:2:5:2:20 | call to resources | get | users | users | index | +| action_controller/routes.rb:2:5:2:20 | call to resources | get | users/:id | users | show | +| action_controller/routes.rb:2:5:2:20 | call to resources | get | users/new | users | new | +| action_controller/routes.rb:2:5:2:20 | call to resources | get | users:id/edit | users | edit | +| action_controller/routes.rb:2:5:2:20 | call to resources | patch | users/:id | users | update | +| action_controller/routes.rb:2:5:2:20 | call to resources | post | users | users | create | +| action_controller/routes.rb:2:5:2:20 | call to resources | put | users/:id | users | update | +| action_controller/routes.rb:3:5:5:7 | call to resources | delete | comments/:id | comments | destroy | +| action_controller/routes.rb:3:5:5:7 | call to resources | get | comments | comments | index | +| action_controller/routes.rb:3:5:5:7 | call to resources | get | comments/:id | comments | show | +| action_controller/routes.rb:3:5:5:7 | call to resources | get | comments/new | comments | new | +| action_controller/routes.rb:3:5:5:7 | call to resources | get | comments:id/edit | comments | edit | +| action_controller/routes.rb:3:5:5:7 | call to resources | patch | comments/:id | comments | update | +| action_controller/routes.rb:3:5:5:7 | call to resources | post | comments | comments | create | +| action_controller/routes.rb:3:5:5:7 | call to resources | put | comments/:id | comments | update | +| action_controller/routes.rb:4:9:4:32 | call to get | get | comments/:comment_id/photo | comments | photo | +| action_controller/routes.rb:6:5:6:21 | call to resources | delete | photos/:id | photos | destroy | +| action_controller/routes.rb:6:5:6:21 | call to resources | get | photos | photos | index | +| action_controller/routes.rb:6:5:6:21 | call to resources | get | photos/:id | photos | show | +| action_controller/routes.rb:6:5:6:21 | call to resources | get | photos/new | photos | new | +| action_controller/routes.rb:6:5:6:21 | call to resources | get | photos:id/edit | photos | edit | +| action_controller/routes.rb:6:5:6:21 | call to resources | patch | photos/:id | photos | update | +| action_controller/routes.rb:6:5:6:21 | call to resources | post | photos | photos | create | +| action_controller/routes.rb:6:5:6:21 | call to resources | put | photos/:id | photos | update | +| action_controller/routes.rb:7:5:9:7 | call to resources | delete | posts/:id | posts | destroy | +| action_controller/routes.rb:7:5:9:7 | call to resources | get | posts | posts | index | +| action_controller/routes.rb:7:5:9:7 | call to resources | get | posts/:id | posts | show | +| action_controller/routes.rb:7:5:9:7 | call to resources | get | posts/new | posts | new | +| action_controller/routes.rb:7:5:9:7 | call to resources | get | posts:id/edit | posts | edit | +| action_controller/routes.rb:7:5:9:7 | call to resources | patch | posts/:id | posts | update | +| action_controller/routes.rb:7:5:9:7 | call to resources | post | posts | posts | create | +| action_controller/routes.rb:7:5:9:7 | call to resources | put | posts/:id | posts | update | +| action_controller/routes.rb:8:9:8:34 | call to post | post | posts/:post_id/upvote | posts | upvote | +| action_controller/routes.rb:10:5:10:19 | call to resources | delete | tags/:id | tags | destroy | +| action_controller/routes.rb:10:5:10:19 | call to resources | get | tags | tags | index | +| action_controller/routes.rb:10:5:10:19 | call to resources | get | tags/:id | tags | show | +| action_controller/routes.rb:10:5:10:19 | call to resources | get | tags/new | tags | new | +| action_controller/routes.rb:10:5:10:19 | call to resources | get | tags:id/edit | tags | edit | +| action_controller/routes.rb:10:5:10:19 | call to resources | patch | tags/:id | tags | update | +| action_controller/routes.rb:10:5:10:19 | call to resources | post | tags | tags | create | +| action_controller/routes.rb:10:5:10:19 | call to resources | put | tags/:id | tags | update | | app/config/routes.rb:2:3:8:5 | call to resources | get | posts | posts | index | | app/config/routes.rb:2:3:8:5 | call to resources | get | posts/:id | posts | show | | app/config/routes.rb:3:5:6:7 | call to resources | delete | posts/:post_id/comments/:id | comments | destroy | @@ -34,24 +76,42 @@ actionDispatchRoutes | app/config/routes.rb:49:5:49:95 | call to delete | delete | users/:user/notifications | users/notifications | destroy | | app/config/routes.rb:50:5:50:94 | call to post | post | users/:user/notifications/:notification_id/mark_as_read | users/notifications | mark_as_read | actionDispatchControllerMethods -| app/config/routes.rb:2:3:8:5 | call to resources | action_controller/controllers/posts_controller.rb:2:3:3:5 | index | -| app/config/routes.rb:2:3:8:5 | call to resources | action_controller/controllers/posts_controller.rb:5:3:6:5 | show | +| action_controller/routes.rb:2:5:2:20 | call to resources | action_controller/input_access.rb:2:3:49:5 | index | +| action_controller/routes.rb:2:5:2:20 | call to resources | action_controller/logging.rb:2:5:8:7 | index | +| action_controller/routes.rb:3:5:5:7 | call to resources | action_controller/controllers/comments_controller.rb:12:3:46:5 | index | +| action_controller/routes.rb:3:5:5:7 | call to resources | action_controller/controllers/comments_controller.rb:48:3:49:5 | create | +| action_controller/routes.rb:3:5:5:7 | call to resources | action_controller/controllers/comments_controller.rb:51:3:57:5 | show | +| action_controller/routes.rb:3:5:5:7 | call to resources | action_controller/controllers/comments_controller.rb:63:3:65:5 | destroy | +| action_controller/routes.rb:3:5:5:7 | call to resources | app/controllers/comments_controller.rb:2:3:36:5 | index | +| action_controller/routes.rb:3:5:5:7 | call to resources | app/controllers/comments_controller.rb:38:3:39:5 | show | +| action_controller/routes.rb:4:9:4:32 | call to get | action_controller/controllers/comments_controller.rb:59:3:61:5 | photo | +| action_controller/routes.rb:6:5:6:21 | call to resources | action_controller/controllers/photos_controller.rb:3:3:6:5 | show | +| action_controller/routes.rb:6:5:6:21 | call to resources | app/controllers/photos_controller.rb:2:3:3:5 | show | +| action_controller/routes.rb:7:5:9:7 | call to resources | action_controller/controllers/posts_controller.rb:6:3:7:5 | index | +| action_controller/routes.rb:7:5:9:7 | call to resources | action_controller/controllers/posts_controller.rb:9:3:10:5 | show | +| action_controller/routes.rb:7:5:9:7 | call to resources | app/controllers/posts_controller.rb:2:3:3:5 | index | +| action_controller/routes.rb:7:5:9:7 | call to resources | app/controllers/posts_controller.rb:5:3:6:5 | show | +| action_controller/routes.rb:8:9:8:34 | call to post | action_controller/controllers/posts_controller.rb:12:3:13:5 | upvote | +| action_controller/routes.rb:8:9:8:34 | call to post | app/controllers/posts_controller.rb:8:3:9:5 | upvote | +| app/config/routes.rb:2:3:8:5 | call to resources | action_controller/controllers/posts_controller.rb:6:3:7:5 | index | +| app/config/routes.rb:2:3:8:5 | call to resources | action_controller/controllers/posts_controller.rb:9:3:10:5 | show | | app/config/routes.rb:2:3:8:5 | call to resources | app/controllers/posts_controller.rb:2:3:3:5 | index | | app/config/routes.rb:2:3:8:5 | call to resources | app/controllers/posts_controller.rb:5:3:6:5 | show | -| app/config/routes.rb:3:5:6:7 | call to resources | action_controller/controllers/comments_controller.rb:2:3:36:5 | index | -| app/config/routes.rb:3:5:6:7 | call to resources | action_controller/controllers/comments_controller.rb:38:3:44:5 | show | -| app/config/routes.rb:3:5:6:7 | call to resources | action_controller/controllers/comments_controller.rb:50:3:52:5 | destroy | +| app/config/routes.rb:3:5:6:7 | call to resources | action_controller/controllers/comments_controller.rb:12:3:46:5 | index | +| app/config/routes.rb:3:5:6:7 | call to resources | action_controller/controllers/comments_controller.rb:48:3:49:5 | create | +| app/config/routes.rb:3:5:6:7 | call to resources | action_controller/controllers/comments_controller.rb:51:3:57:5 | show | +| app/config/routes.rb:3:5:6:7 | call to resources | action_controller/controllers/comments_controller.rb:63:3:65:5 | destroy | | app/config/routes.rb:3:5:6:7 | call to resources | app/controllers/comments_controller.rb:2:3:36:5 | index | | app/config/routes.rb:3:5:6:7 | call to resources | app/controllers/comments_controller.rb:38:3:39:5 | show | -| app/config/routes.rb:7:5:7:37 | call to post | action_controller/controllers/posts_controller.rb:8:3:9:5 | upvote | +| app/config/routes.rb:7:5:7:37 | call to post | action_controller/controllers/posts_controller.rb:12:3:13:5 | upvote | | app/config/routes.rb:7:5:7:37 | call to post | app/controllers/posts_controller.rb:8:3:9:5 | upvote | -| app/config/routes.rb:27:3:27:48 | call to match | action_controller/controllers/photos_controller.rb:2:3:3:5 | show | +| app/config/routes.rb:27:3:27:48 | call to match | action_controller/controllers/photos_controller.rb:3:3:6:5 | show | | app/config/routes.rb:27:3:27:48 | call to match | app/controllers/photos_controller.rb:2:3:3:5 | show | -| app/config/routes.rb:28:3:28:50 | call to match | action_controller/controllers/photos_controller.rb:2:3:3:5 | show | +| app/config/routes.rb:28:3:28:50 | call to match | action_controller/controllers/photos_controller.rb:3:3:6:5 | show | | app/config/routes.rb:28:3:28:50 | call to match | app/controllers/photos_controller.rb:2:3:3:5 | show | -| app/config/routes.rb:29:3:29:69 | call to match | action_controller/controllers/photos_controller.rb:2:3:3:5 | show | +| app/config/routes.rb:29:3:29:69 | call to match | action_controller/controllers/photos_controller.rb:3:3:6:5 | show | | app/config/routes.rb:29:3:29:69 | call to match | app/controllers/photos_controller.rb:2:3:3:5 | show | -| app/config/routes.rb:30:3:30:50 | call to match | action_controller/controllers/photos_controller.rb:2:3:3:5 | show | +| app/config/routes.rb:30:3:30:50 | call to match | action_controller/controllers/photos_controller.rb:3:3:6:5 | show | | app/config/routes.rb:30:3:30:50 | call to match | app/controllers/photos_controller.rb:2:3:3:5 | show | | app/config/routes.rb:50:5:50:94 | call to post | action_controller/controllers/users/notifications_controller.rb:3:5:4:7 | mark_as_read | | app/config/routes.rb:50:5:50:94 | call to post | app/controllers/users/notifications_controller.rb:3:5:4:7 | mark_as_read | diff --git a/ruby/ql/test/library-tests/frameworks/ActionView.expected b/ruby/ql/test/library-tests/frameworks/ActionView.expected index 1ad020a2394..2f49c6e7b99 100644 --- a/ruby/ql/test/library-tests/frameworks/ActionView.expected +++ b/ruby/ql/test/library-tests/frameworks/ActionView.expected @@ -9,7 +9,8 @@ rawCalls | app/views/foo/bars/show.html.erb:5:5:5:21 | call to raw | | app/views/foo/bars/show.html.erb:7:5:7:19 | call to raw | renderCalls -| action_controller/controllers/comments_controller.rb:42:21:42:64 | call to render | +| action_controller/controllers/comments_controller.rb:55:21:55:64 | call to render | +| action_controller/controllers/comments_controller.rb:71:5:71:68 | call to render | | action_controller/controllers/foo/bars_controller.rb:6:5:6:37 | call to render | | action_controller/controllers/foo/bars_controller.rb:23:5:23:76 | call to render | | action_controller/controllers/foo/bars_controller.rb:35:5:35:33 | call to render | @@ -29,9 +30,9 @@ renderToCalls linkToCalls | app/views/foo/bars/show.html.erb:33:5:33:41 | call to link_to | httpResponses -| action_controller/controllers/comments_controller.rb:11:5:11:17 | call to body= | action_controller/controllers/comments_controller.rb:11:21:11:34 | ... = ... | text/http | -| action_controller/controllers/comments_controller.rb:21:5:21:37 | call to send_file | action_controller/controllers/comments_controller.rb:21:24:21:36 | "my-file.ext" | application/octet-stream | -| action_controller/controllers/comments_controller.rb:47:5:47:20 | call to send_data | action_controller/controllers/comments_controller.rb:47:15:47:20 | @photo | application/octet-stream | +| action_controller/controllers/comments_controller.rb:21:5:21:17 | call to body= | action_controller/controllers/comments_controller.rb:21:21:21:34 | ... = ... | text/http | +| action_controller/controllers/comments_controller.rb:31:5:31:37 | call to send_file | action_controller/controllers/comments_controller.rb:31:24:31:36 | "my-file.ext" | application/octet-stream | +| action_controller/controllers/comments_controller.rb:60:5:60:20 | call to send_data | action_controller/controllers/comments_controller.rb:60:15:60:20 | @photo | application/octet-stream | | action_controller/controllers/foo/bars_controller.rb:15:16:15:97 | call to render_to_string | action_controller/controllers/foo/bars_controller.rb:15:33:15:47 | "foo/bars/show" | text/html | | action_controller/controllers/foo/bars_controller.rb:23:5:23:76 | call to render | action_controller/controllers/foo/bars_controller.rb:23:12:23:26 | "foo/bars/show" | text/html | | action_controller/controllers/foo/bars_controller.rb:35:5:35:33 | call to render | action_controller/controllers/foo/bars_controller.rb:35:18:35:33 | call to [] | application/json | diff --git a/ruby/ql/test/library-tests/frameworks/action_controller/ActionController.expected b/ruby/ql/test/library-tests/frameworks/action_controller/ActionController.expected index f4a21655355..e34eddc94d1 100644 --- a/ruby/ql/test/library-tests/frameworks/action_controller/ActionController.expected +++ b/ruby/ql/test/library-tests/frameworks/action_controller/ActionController.expected @@ -1,28 +1,31 @@ actionControllerControllerClasses -| controllers/comments_controller.rb:1:1:53:3 | CommentsController | +| controllers/application_controller.rb:1:1:13:3 | ApplicationController | +| controllers/comments_controller.rb:1:1:95:3 | CommentsController | | controllers/foo/bars_controller.rb:3:1:46:3 | BarsController | -| controllers/photos_controller.rb:1:1:4:3 | PhotosController | -| controllers/posts_controller.rb:1:1:10:3 | PostsController | +| controllers/photos_controller.rb:1:1:10:3 | PhotosController | +| controllers/posts_controller.rb:1:1:24:3 | PostsController | | controllers/tags_controller.rb:1:1:2:3 | TagsController | | controllers/users/notifications_controller.rb:2:3:5:5 | Users::NotificationsController | | input_access.rb:1:1:50:3 | UsersController | | params_flow.rb:1:1:162:3 | MyController | | params_flow.rb:170:1:178:3 | Subclass | actionControllerActionMethods -| controllers/comments_controller.rb:2:3:36:5 | index | -| controllers/comments_controller.rb:38:3:44:5 | show | -| controllers/comments_controller.rb:46:3:48:5 | photo | -| controllers/comments_controller.rb:50:3:52:5 | destroy | +| controllers/comments_controller.rb:12:3:46:5 | index | +| controllers/comments_controller.rb:48:3:49:5 | create | +| controllers/comments_controller.rb:51:3:57:5 | show | +| controllers/comments_controller.rb:59:3:61:5 | photo | +| controllers/comments_controller.rb:63:3:65:5 | destroy | | controllers/foo/bars_controller.rb:5:3:7:5 | index | | controllers/foo/bars_controller.rb:9:3:18:5 | show_debug | | controllers/foo/bars_controller.rb:20:3:24:5 | show | | controllers/foo/bars_controller.rb:26:3:28:5 | go_back | | controllers/foo/bars_controller.rb:30:3:32:5 | go_back_2 | | controllers/foo/bars_controller.rb:34:3:39:5 | show_2 | -| controllers/photos_controller.rb:2:3:3:5 | show | -| controllers/posts_controller.rb:2:3:3:5 | index | -| controllers/posts_controller.rb:5:3:6:5 | show | -| controllers/posts_controller.rb:8:3:9:5 | upvote | +| controllers/photos_controller.rb:3:3:6:5 | show | +| controllers/photos_controller.rb:8:3:9:5 | foo | +| controllers/posts_controller.rb:6:3:7:5 | index | +| controllers/posts_controller.rb:9:3:10:5 | show | +| controllers/posts_controller.rb:12:3:13:5 | upvote | | controllers/users/notifications_controller.rb:3:5:4:7 | mark_as_read | | input_access.rb:2:3:49:5 | index | | logging.rb:2:5:8:7 | index | @@ -63,10 +66,12 @@ actionControllerActionMethods | params_flow.rb:165:3:167:5 | m34 | | params_flow.rb:171:3:173:5 | m35 | paramsCalls +| controllers/comments_controller.rb:75:36:75:41 | call to params | | controllers/foo/bars_controller.rb:13:21:13:26 | call to params | | controllers/foo/bars_controller.rb:14:10:14:15 | call to params | | controllers/foo/bars_controller.rb:21:21:21:26 | call to params | | controllers/foo/bars_controller.rb:22:10:22:15 | call to params | +| controllers/posts_controller.rb:18:23:18:28 | call to params | | params_flow.rb:3:10:3:15 | call to params | | params_flow.rb:7:10:7:15 | call to params | | params_flow.rb:11:10:11:15 | call to params | @@ -116,10 +121,12 @@ paramsCalls | params_flow.rb:172:10:172:15 | call to params | | params_flow.rb:176:10:176:15 | call to params | paramsSources +| controllers/comments_controller.rb:75:36:75:41 | call to params | | controllers/foo/bars_controller.rb:13:21:13:26 | call to params | | controllers/foo/bars_controller.rb:14:10:14:15 | call to params | | controllers/foo/bars_controller.rb:21:21:21:26 | call to params | | controllers/foo/bars_controller.rb:22:10:22:15 | call to params | +| controllers/posts_controller.rb:18:23:18:28 | call to params | | params_flow.rb:3:10:3:15 | call to params | | params_flow.rb:7:10:7:15 | call to params | | params_flow.rb:11:10:11:15 | call to params | @@ -169,19 +176,22 @@ paramsSources | params_flow.rb:172:10:172:15 | call to params | | params_flow.rb:176:10:176:15 | call to params | httpInputAccesses -| controllers/comments_controller.rb:3:5:3:18 | call to params | ActionDispatch::Request#params | -| controllers/comments_controller.rb:4:5:4:22 | call to parameters | ActionDispatch::Request#parameters | -| controllers/comments_controller.rb:5:5:5:15 | call to GET | ActionDispatch::Request#GET | -| controllers/comments_controller.rb:6:5:6:16 | call to POST | ActionDispatch::Request#POST | -| controllers/comments_controller.rb:7:5:7:28 | call to query_parameters | ActionDispatch::Request#query_parameters | -| controllers/comments_controller.rb:8:5:8:30 | call to request_parameters | ActionDispatch::Request#request_parameters | -| controllers/comments_controller.rb:9:5:9:31 | call to filtered_parameters | ActionDispatch::Request#filtered_parameters | -| controllers/comments_controller.rb:51:12:51:30 | call to body_stream | ActionDispatch::Request#body_stream | +| controllers/application_controller.rb:11:53:11:64 | call to path | ActionDispatch::Request#path | +| controllers/comments_controller.rb:13:5:13:18 | call to params | ActionDispatch::Request#params | +| controllers/comments_controller.rb:14:5:14:22 | call to parameters | ActionDispatch::Request#parameters | +| controllers/comments_controller.rb:15:5:15:15 | call to GET | ActionDispatch::Request#GET | +| controllers/comments_controller.rb:16:5:16:16 | call to POST | ActionDispatch::Request#POST | +| controllers/comments_controller.rb:17:5:17:28 | call to query_parameters | ActionDispatch::Request#query_parameters | +| controllers/comments_controller.rb:18:5:18:30 | call to request_parameters | ActionDispatch::Request#request_parameters | +| controllers/comments_controller.rb:19:5:19:31 | call to filtered_parameters | ActionDispatch::Request#filtered_parameters | +| controllers/comments_controller.rb:64:12:64:30 | call to body_stream | ActionDispatch::Request#body_stream | +| controllers/comments_controller.rb:75:36:75:41 | call to params | ActionController::Metal#params | | controllers/foo/bars_controller.rb:10:27:10:33 | call to cookies | ActionController::Metal#cookies | | controllers/foo/bars_controller.rb:13:21:13:26 | call to params | ActionController::Metal#params | | controllers/foo/bars_controller.rb:14:10:14:15 | call to params | ActionController::Metal#params | | controllers/foo/bars_controller.rb:21:21:21:26 | call to params | ActionController::Metal#params | | controllers/foo/bars_controller.rb:22:10:22:15 | call to params | ActionController::Metal#params | +| controllers/posts_controller.rb:18:23:18:28 | call to params | ActionController::Metal#params | | input_access.rb:3:5:3:18 | call to params | ActionDispatch::Request#params | | input_access.rb:4:5:4:22 | call to parameters | ActionDispatch::Request#parameters | | input_access.rb:5:5:5:15 | call to GET | ActionDispatch::Request#GET | @@ -275,21 +285,22 @@ cookiesCalls cookiesSources | controllers/foo/bars_controller.rb:10:27:10:33 | call to cookies | redirectToCalls -| controllers/comments_controller.rb:40:21:40:49 | call to redirect_to | +| controllers/comments_controller.rb:53:21:53:49 | call to redirect_to | | controllers/foo/bars_controller.rb:17:5:17:30 | call to redirect_to | | controllers/foo/bars_controller.rb:27:5:27:39 | call to redirect_back_or_to | | controllers/foo/bars_controller.rb:31:5:31:56 | call to redirect_back | renderCalls -| controllers/comments_controller.rb:42:21:42:64 | call to render | +| controllers/comments_controller.rb:55:21:55:64 | call to render | +| controllers/comments_controller.rb:71:5:71:68 | call to render | | controllers/foo/bars_controller.rb:6:5:6:37 | call to render | | controllers/foo/bars_controller.rb:23:5:23:76 | call to render | | controllers/foo/bars_controller.rb:35:5:35:33 | call to render | | controllers/foo/bars_controller.rb:38:5:38:50 | call to render | | controllers/foo/bars_controller.rb:44:5:44:17 | call to render | httpResponses -| controllers/comments_controller.rb:11:5:11:17 | call to body= | controllers/comments_controller.rb:11:21:11:34 | ... = ... | -| controllers/comments_controller.rb:21:5:21:37 | call to send_file | controllers/comments_controller.rb:21:24:21:36 | "my-file.ext" | -| controllers/comments_controller.rb:47:5:47:20 | call to send_data | controllers/comments_controller.rb:47:15:47:20 | @photo | +| controllers/comments_controller.rb:21:5:21:17 | call to body= | controllers/comments_controller.rb:21:21:21:34 | ... = ... | +| controllers/comments_controller.rb:31:5:31:37 | call to send_file | controllers/comments_controller.rb:31:24:31:36 | "my-file.ext" | +| controllers/comments_controller.rb:60:5:60:20 | call to send_data | controllers/comments_controller.rb:60:15:60:20 | @photo | | controllers/foo/bars_controller.rb:15:16:15:97 | call to render_to_string | controllers/foo/bars_controller.rb:15:33:15:47 | "foo/bars/show" | | controllers/foo/bars_controller.rb:23:5:23:76 | call to render | controllers/foo/bars_controller.rb:23:12:23:26 | "foo/bars/show" | | controllers/foo/bars_controller.rb:35:5:35:33 | call to render | controllers/foo/bars_controller.rb:35:18:35:33 | call to [] | @@ -300,21 +311,21 @@ actionControllerHelperMethods getAssociatedControllerClasses controllerTemplateFiles headerWriteAccesses -| controllers/comments_controller.rb:15:5:15:35 | call to []= | content-type | controllers/comments_controller.rb:15:39:15:49 | ... = ... | -| controllers/comments_controller.rb:16:5:16:46 | call to set_header | content-length | controllers/comments_controller.rb:16:43:16:45 | 100 | -| controllers/comments_controller.rb:17:5:17:39 | call to []= | x-custom-header | controllers/comments_controller.rb:17:43:17:46 | ... = ... | -| controllers/comments_controller.rb:18:5:18:39 | call to []= | x-another-custom-header | controllers/comments_controller.rb:18:43:18:47 | ... = ... | -| controllers/comments_controller.rb:19:5:19:49 | call to add_header | x-yet-another | controllers/comments_controller.rb:19:42:19:49 | "indeed" | -| controllers/comments_controller.rb:25:5:25:21 | call to location= | location | controllers/comments_controller.rb:25:25:25:36 | ... = ... | -| controllers/comments_controller.rb:26:5:26:26 | call to cache_control= | cache-control | controllers/comments_controller.rb:26:30:26:36 | ... = ... | -| controllers/comments_controller.rb:27:5:27:27 | call to _cache_control= | cache-control | controllers/comments_controller.rb:27:31:27:37 | ... = ... | -| controllers/comments_controller.rb:28:5:28:17 | call to etag= | etag | controllers/comments_controller.rb:28:21:28:27 | ... = ... | -| controllers/comments_controller.rb:29:5:29:20 | call to charset= | content-type | controllers/comments_controller.rb:29:24:29:30 | ... = ... | -| controllers/comments_controller.rb:30:5:30:25 | call to content_type= | content-type | controllers/comments_controller.rb:30:29:30:35 | ... = ... | -| controllers/comments_controller.rb:32:5:32:17 | call to date= | date | controllers/comments_controller.rb:32:21:32:30 | ... = ... | -| controllers/comments_controller.rb:33:5:33:26 | call to last_modified= | last-modified | controllers/comments_controller.rb:33:30:33:43 | ... = ... | -| controllers/comments_controller.rb:34:5:34:22 | call to weak_etag= | etag | controllers/comments_controller.rb:34:26:34:32 | ... = ... | -| controllers/comments_controller.rb:35:5:35:24 | call to strong_etag= | etag | controllers/comments_controller.rb:35:28:35:34 | ... = ... | +| controllers/comments_controller.rb:25:5:25:35 | call to []= | content-type | controllers/comments_controller.rb:25:39:25:49 | ... = ... | +| controllers/comments_controller.rb:26:5:26:46 | call to set_header | content-length | controllers/comments_controller.rb:26:43:26:45 | 100 | +| controllers/comments_controller.rb:27:5:27:39 | call to []= | x-custom-header | controllers/comments_controller.rb:27:43:27:46 | ... = ... | +| controllers/comments_controller.rb:28:5:28:39 | call to []= | x-another-custom-header | controllers/comments_controller.rb:28:43:28:47 | ... = ... | +| controllers/comments_controller.rb:29:5:29:49 | call to add_header | x-yet-another | controllers/comments_controller.rb:29:42:29:49 | "indeed" | +| controllers/comments_controller.rb:35:5:35:21 | call to location= | location | controllers/comments_controller.rb:35:25:35:36 | ... = ... | +| controllers/comments_controller.rb:36:5:36:26 | call to cache_control= | cache-control | controllers/comments_controller.rb:36:30:36:36 | ... = ... | +| controllers/comments_controller.rb:37:5:37:27 | call to _cache_control= | cache-control | controllers/comments_controller.rb:37:31:37:37 | ... = ... | +| controllers/comments_controller.rb:38:5:38:17 | call to etag= | etag | controllers/comments_controller.rb:38:21:38:27 | ... = ... | +| controllers/comments_controller.rb:39:5:39:20 | call to charset= | content-type | controllers/comments_controller.rb:39:24:39:30 | ... = ... | +| controllers/comments_controller.rb:40:5:40:25 | call to content_type= | content-type | controllers/comments_controller.rb:40:29:40:35 | ... = ... | +| controllers/comments_controller.rb:42:5:42:17 | call to date= | date | controllers/comments_controller.rb:42:21:42:30 | ... = ... | +| controllers/comments_controller.rb:43:5:43:26 | call to last_modified= | last-modified | controllers/comments_controller.rb:43:30:43:43 | ... = ... | +| controllers/comments_controller.rb:44:5:44:22 | call to weak_etag= | etag | controllers/comments_controller.rb:44:26:44:32 | ... = ... | +| controllers/comments_controller.rb:45:5:45:24 | call to strong_etag= | etag | controllers/comments_controller.rb:45:28:45:34 | ... = ... | loggingCalls | logging.rb:3:9:3:31 | call to info | logging.rb:3:21:3:31 | "some info" | | logging.rb:4:9:4:31 | call to warn | logging.rb:4:21:4:31 | "a warning" | diff --git a/ruby/ql/test/library-tests/frameworks/action_controller/Filters.expected b/ruby/ql/test/library-tests/frameworks/action_controller/Filters.expected new file mode 100644 index 00000000000..cb233ca0c7c --- /dev/null +++ b/ruby/ql/test/library-tests/frameworks/action_controller/Filters.expected @@ -0,0 +1,48 @@ +| controllers/comments_controller.rb:12:3:46:5 | index | controllers/application_controller.rb:6:3:8:5 | set_user | controllers/comments_controller.rb:90:3:91:5 | foo | +| controllers/comments_controller.rb:12:3:46:5 | index | controllers/application_controller.rb:10:3:12:5 | log_request | controllers/application_controller.rb:6:3:8:5 | set_user | +| controllers/comments_controller.rb:12:3:46:5 | index | controllers/comments_controller.rb:12:3:46:5 | index | controllers/comments_controller.rb:86:3:88:5 | this_must_run_last | +| controllers/comments_controller.rb:12:3:46:5 | index | controllers/comments_controller.rb:82:3:84:5 | this_must_run_first | controllers/application_controller.rb:10:3:12:5 | log_request | +| controllers/comments_controller.rb:12:3:46:5 | index | controllers/comments_controller.rb:90:3:91:5 | foo | controllers/comments_controller.rb:93:3:94:5 | bar | +| controllers/comments_controller.rb:12:3:46:5 | index | controllers/comments_controller.rb:93:3:94:5 | bar | controllers/comments_controller.rb:12:3:46:5 | index | +| controllers/comments_controller.rb:48:3:49:5 | create | controllers/application_controller.rb:6:3:8:5 | set_user | controllers/comments_controller.rb:69:3:72:5 | ensure_user_can_edit_comments | +| controllers/comments_controller.rb:48:3:49:5 | create | controllers/application_controller.rb:10:3:12:5 | log_request | controllers/application_controller.rb:6:3:8:5 | set_user | +| controllers/comments_controller.rb:48:3:49:5 | create | controllers/comments_controller.rb:48:3:49:5 | create | controllers/comments_controller.rb:78:3:80:5 | log_comment_change | +| controllers/comments_controller.rb:48:3:49:5 | create | controllers/comments_controller.rb:69:3:72:5 | ensure_user_can_edit_comments | controllers/comments_controller.rb:90:3:91:5 | foo | +| controllers/comments_controller.rb:48:3:49:5 | create | controllers/comments_controller.rb:78:3:80:5 | log_comment_change | controllers/comments_controller.rb:86:3:88:5 | this_must_run_last | +| controllers/comments_controller.rb:48:3:49:5 | create | controllers/comments_controller.rb:82:3:84:5 | this_must_run_first | controllers/application_controller.rb:10:3:12:5 | log_request | +| controllers/comments_controller.rb:48:3:49:5 | create | controllers/comments_controller.rb:90:3:91:5 | foo | controllers/comments_controller.rb:93:3:94:5 | bar | +| controllers/comments_controller.rb:48:3:49:5 | create | controllers/comments_controller.rb:93:3:94:5 | bar | controllers/comments_controller.rb:48:3:49:5 | create | +| controllers/comments_controller.rb:51:3:57:5 | show | controllers/application_controller.rb:6:3:8:5 | set_user | controllers/comments_controller.rb:74:3:76:5 | set_comment | +| controllers/comments_controller.rb:51:3:57:5 | show | controllers/application_controller.rb:10:3:12:5 | log_request | controllers/application_controller.rb:6:3:8:5 | set_user | +| controllers/comments_controller.rb:51:3:57:5 | show | controllers/comments_controller.rb:51:3:57:5 | show | controllers/comments_controller.rb:86:3:88:5 | this_must_run_last | +| controllers/comments_controller.rb:51:3:57:5 | show | controllers/comments_controller.rb:74:3:76:5 | set_comment | controllers/comments_controller.rb:90:3:91:5 | foo | +| controllers/comments_controller.rb:51:3:57:5 | show | controllers/comments_controller.rb:82:3:84:5 | this_must_run_first | controllers/application_controller.rb:10:3:12:5 | log_request | +| controllers/comments_controller.rb:51:3:57:5 | show | controllers/comments_controller.rb:90:3:91:5 | foo | controllers/comments_controller.rb:93:3:94:5 | bar | +| controllers/comments_controller.rb:51:3:57:5 | show | controllers/comments_controller.rb:93:3:94:5 | bar | controllers/comments_controller.rb:51:3:57:5 | show | +| controllers/comments_controller.rb:59:3:61:5 | photo | controllers/application_controller.rb:6:3:8:5 | set_user | controllers/comments_controller.rb:90:3:91:5 | foo | +| controllers/comments_controller.rb:59:3:61:5 | photo | controllers/application_controller.rb:10:3:12:5 | log_request | controllers/application_controller.rb:6:3:8:5 | set_user | +| controllers/comments_controller.rb:59:3:61:5 | photo | controllers/comments_controller.rb:59:3:61:5 | photo | controllers/comments_controller.rb:78:3:80:5 | log_comment_change | +| controllers/comments_controller.rb:59:3:61:5 | photo | controllers/comments_controller.rb:78:3:80:5 | log_comment_change | controllers/comments_controller.rb:86:3:88:5 | this_must_run_last | +| controllers/comments_controller.rb:59:3:61:5 | photo | controllers/comments_controller.rb:82:3:84:5 | this_must_run_first | controllers/application_controller.rb:10:3:12:5 | log_request | +| controllers/comments_controller.rb:59:3:61:5 | photo | controllers/comments_controller.rb:90:3:91:5 | foo | controllers/comments_controller.rb:93:3:94:5 | bar | +| controllers/comments_controller.rb:59:3:61:5 | photo | controllers/comments_controller.rb:93:3:94:5 | bar | controllers/comments_controller.rb:59:3:61:5 | photo | +| controllers/comments_controller.rb:63:3:65:5 | destroy | controllers/application_controller.rb:6:3:8:5 | set_user | controllers/comments_controller.rb:69:3:72:5 | ensure_user_can_edit_comments | +| controllers/comments_controller.rb:63:3:65:5 | destroy | controllers/application_controller.rb:10:3:12:5 | log_request | controllers/application_controller.rb:6:3:8:5 | set_user | +| controllers/comments_controller.rb:63:3:65:5 | destroy | controllers/comments_controller.rb:63:3:65:5 | destroy | controllers/comments_controller.rb:78:3:80:5 | log_comment_change | +| controllers/comments_controller.rb:63:3:65:5 | destroy | controllers/comments_controller.rb:69:3:72:5 | ensure_user_can_edit_comments | controllers/comments_controller.rb:74:3:76:5 | set_comment | +| controllers/comments_controller.rb:63:3:65:5 | destroy | controllers/comments_controller.rb:74:3:76:5 | set_comment | controllers/comments_controller.rb:90:3:91:5 | foo | +| controllers/comments_controller.rb:63:3:65:5 | destroy | controllers/comments_controller.rb:78:3:80:5 | log_comment_change | controllers/comments_controller.rb:86:3:88:5 | this_must_run_last | +| controllers/comments_controller.rb:63:3:65:5 | destroy | controllers/comments_controller.rb:82:3:84:5 | this_must_run_first | controllers/application_controller.rb:10:3:12:5 | log_request | +| controllers/comments_controller.rb:63:3:65:5 | destroy | controllers/comments_controller.rb:90:3:91:5 | foo | controllers/comments_controller.rb:93:3:94:5 | bar | +| controllers/comments_controller.rb:63:3:65:5 | destroy | controllers/comments_controller.rb:93:3:94:5 | bar | controllers/comments_controller.rb:63:3:65:5 | destroy | +| controllers/photos_controller.rb:3:3:6:5 | show | controllers/application_controller.rb:10:3:12:5 | log_request | controllers/photos_controller.rb:3:3:6:5 | show | +| controllers/photos_controller.rb:3:3:6:5 | show | controllers/photos_controller.rb:3:3:6:5 | show | controllers/photos_controller.rb:8:3:9:5 | foo | +| controllers/posts_controller.rb:6:3:7:5 | index | controllers/application_controller.rb:6:3:8:5 | set_user | controllers/posts_controller.rb:6:3:7:5 | index | +| controllers/posts_controller.rb:6:3:7:5 | index | controllers/application_controller.rb:10:3:12:5 | log_request | controllers/application_controller.rb:6:3:8:5 | set_user | +| controllers/posts_controller.rb:9:3:10:5 | show | controllers/application_controller.rb:6:3:8:5 | set_user | controllers/posts_controller.rb:17:3:19:5 | set_post | +| controllers/posts_controller.rb:9:3:10:5 | show | controllers/application_controller.rb:10:3:12:5 | log_request | controllers/application_controller.rb:6:3:8:5 | set_user | +| controllers/posts_controller.rb:9:3:10:5 | show | controllers/posts_controller.rb:17:3:19:5 | set_post | controllers/posts_controller.rb:9:3:10:5 | show | +| controllers/posts_controller.rb:12:3:13:5 | upvote | controllers/application_controller.rb:6:3:8:5 | set_user | controllers/posts_controller.rb:17:3:19:5 | set_post | +| controllers/posts_controller.rb:12:3:13:5 | upvote | controllers/application_controller.rb:10:3:12:5 | log_request | controllers/application_controller.rb:6:3:8:5 | set_user | +| controllers/posts_controller.rb:12:3:13:5 | upvote | controllers/posts_controller.rb:12:3:13:5 | upvote | controllers/posts_controller.rb:21:3:23:5 | log_upvote | +| controllers/posts_controller.rb:12:3:13:5 | upvote | controllers/posts_controller.rb:17:3:19:5 | set_post | controllers/posts_controller.rb:12:3:13:5 | upvote | diff --git a/ruby/ql/test/library-tests/frameworks/action_controller/Filters.ql b/ruby/ql/test/library-tests/frameworks/action_controller/Filters.ql new file mode 100644 index 00000000000..7a3a2c9ec3f --- /dev/null +++ b/ruby/ql/test/library-tests/frameworks/action_controller/Filters.ql @@ -0,0 +1,5 @@ +private import codeql.ruby.AST +private import codeql.ruby.frameworks.ActionController +private import codeql.ruby.DataFlow + +query predicate filterChain = ActionController::Filters::next/3; diff --git a/ruby/ql/test/library-tests/frameworks/action_controller/controllers/application_controller.rb b/ruby/ql/test/library-tests/frameworks/action_controller/controllers/application_controller.rb new file mode 100644 index 00000000000..644a5331050 --- /dev/null +++ b/ruby/ql/test/library-tests/frameworks/action_controller/controllers/application_controller.rb @@ -0,0 +1,13 @@ +class ApplicationController < ActionController::Base + before_action :log_request + + private + + def set_user + @user = User.find(session[:user_id]) + end + + def log_request + Rails.logger.info("Request: #{request.method} #{request.path}") + end +end diff --git a/ruby/ql/test/library-tests/frameworks/action_controller/controllers/comments_controller.rb b/ruby/ql/test/library-tests/frameworks/action_controller/controllers/comments_controller.rb index daa96090b09..ea50837da99 100644 --- a/ruby/ql/test/library-tests/frameworks/action_controller/controllers/comments_controller.rb +++ b/ruby/ql/test/library-tests/frameworks/action_controller/controllers/comments_controller.rb @@ -1,4 +1,14 @@ class CommentsController < ApplicationController + prepend_after_action :this_must_run_last + before_action :set_user + before_action :ensure_user_can_edit_comments, only: WRITE_ACTIONS + before_action :set_comment, only: [:show, :edit, :update, :destroy] + before_action :foo, :bar + after_action :log_comment_change, except: [:index, :show, :new] + prepend_before_action :this_must_run_first + + WRITE_ACTIONS = %i[create update destroy] + def index request.params request.parameters @@ -35,6 +45,9 @@ class CommentsController < ApplicationController response.strong_etag = "value" end + def create + end + def show respond_to do |format| format.html { redirect_to(comment_view_url) } @@ -50,4 +63,33 @@ class CommentsController < ApplicationController def destroy body = request.body_stream end + + private + + def ensure_user_can_edit_comments + return if @user.can_edit_comments? + render status: 403, text: "You are not allowed to edit comments" + end + + def set_comment + @comment = @user.comments.find(params[:id]) + end + + def log_comment_change + AuditLog.create!(:comment_change, user: @user, comment: @comment) + end + + def this_must_run_first + # for whatever reason + end + + def this_must_run_last + # for whatever reason + end + + def foo + end + + def bar + end end diff --git a/ruby/ql/test/library-tests/frameworks/action_controller/controllers/photos_controller.rb b/ruby/ql/test/library-tests/frameworks/action_controller/controllers/photos_controller.rb index 0de193b9029..f5f092a76e5 100644 --- a/ruby/ql/test/library-tests/frameworks/action_controller/controllers/photos_controller.rb +++ b/ruby/ql/test/library-tests/frameworks/action_controller/controllers/photos_controller.rb @@ -1,4 +1,10 @@ class PhotosController < ApplicationController + after_action :foo def show + @a = 1 + @b = 2 + end + + def foo end end \ No newline at end of file diff --git a/ruby/ql/test/library-tests/frameworks/action_controller/controllers/posts_controller.rb b/ruby/ql/test/library-tests/frameworks/action_controller/controllers/posts_controller.rb index 9760219cdf2..7ff97777b01 100644 --- a/ruby/ql/test/library-tests/frameworks/action_controller/controllers/posts_controller.rb +++ b/ruby/ql/test/library-tests/frameworks/action_controller/controllers/posts_controller.rb @@ -1,4 +1,8 @@ class PostsController < ApplicationController + before_action :set_user + append_before_action :set_post, only: [:show, :upvote] + after_action :log_upvote, only: :upvote + def index end @@ -7,4 +11,14 @@ class PostsController < ApplicationController def upvote end -end \ No newline at end of file + + private + + def set_post + @post = Post.find(params[:id]) + end + + def log_upvote + Rails.logger.info("Post upvoted: #{@post.id}") + end +end diff --git a/ruby/ql/test/library-tests/frameworks/action_controller/routes.rb b/ruby/ql/test/library-tests/frameworks/action_controller/routes.rb new file mode 100644 index 00000000000..1ccc9e6238b --- /dev/null +++ b/ruby/ql/test/library-tests/frameworks/action_controller/routes.rb @@ -0,0 +1,11 @@ +Rails.application.routes.draw do + resources :users + resources :comments do + get "photo", on: :member + end + resources :photos + resources :posts do + post "upvote", on: :member + end + resources :tags +end From 28c3bd3e2ff043e96b8bce5880077a1e0268f963 Mon Sep 17 00:00:00 2001 From: Harry Maclean Date: Mon, 23 Jan 2023 14:25:00 +1300 Subject: [PATCH 02/12] Ruby: QL4QL fix --- .../lib/codeql/ruby/frameworks/actioncontroller/Filters.qll | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/ruby/ql/lib/codeql/ruby/frameworks/actioncontroller/Filters.qll b/ruby/ql/lib/codeql/ruby/frameworks/actioncontroller/Filters.qll index d5eeb05374a..6d0cad0c5ea 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/actioncontroller/Filters.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/actioncontroller/Filters.qll @@ -356,7 +356,5 @@ module Filters { * `pred` and `succ` may be methods bound to callbacks or controller actions. */ cached - predicate next(Method pred, Method succ) { - exists(ActionControllerActionMethod action | next(action, pred, succ)) - } + predicate next(Method pred, Method succ) { next(_, pred, succ) } } From a164e76a5d1d2b2abcced1003bac20a10afb56a9 Mon Sep 17 00:00:00 2001 From: Harry Maclean Date: Mon, 30 Jan 2023 18:05:22 +1300 Subject: [PATCH 03/12] Ruby: Model actioncontroller filter overrides If a filter is registered twice with the same name, the last registration wins. --- .../frameworks/actioncontroller/Filters.qll | 28 +++++- .../action_controller/Filters.expected | 97 ++++++++++--------- .../controllers/comments_controller.rb | 8 ++ .../controllers/posts_controller.rb | 4 + 4 files changed, 90 insertions(+), 47 deletions(-) diff --git a/ruby/ql/lib/codeql/ruby/frameworks/actioncontroller/Filters.qll b/ruby/ql/lib/codeql/ruby/frameworks/actioncontroller/Filters.qll index 6d0cad0c5ea..729cee0d243 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/actioncontroller/Filters.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/actioncontroller/Filters.qll @@ -271,8 +271,34 @@ module Filters { not exists(Filter mid | this.runsBefore(mid, action) | mid.runsBefore(result, action)) } + /** + * Holds if this callback does not run for `action`. This is either because + * it has been explicitly skipped by a `SkipFilter` or because a callback + * with the same name is registered later one, overriding this one. + */ predicate skipped(ActionControllerActionMethod action) { - this = any(SkipFilter f | f.getKind() = this.getKind()).getSkippedFilter(action) + this = any(SkipFilter f | f.getKind() = this.getKind()).getSkippedFilter(action) or + this.overridden() + } + + /** + * Holds if this callback is overridden by a callback with the same name. For example: + * ```rb + * class UsersController + * before_action :foo # this filter is override by the subsequent `before_action :foo` call below. + * before_action :bar + * before_action :foo + * end + * ``` + */ + private predicate overridden() { + exists(Filter f | + f != this and + f.getFilterCallable() = this.getFilterCallable() and + f.getFilterName() = this.getFilterName() and + f.getKind() = this.getKind() and + this.registeredBefore(f) + ) } private string getFilterName() { result = this.getConstantValue().getStringlikeValue() } diff --git a/ruby/ql/test/library-tests/frameworks/action_controller/Filters.expected b/ruby/ql/test/library-tests/frameworks/action_controller/Filters.expected index cb233ca0c7c..7334fe8a960 100644 --- a/ruby/ql/test/library-tests/frameworks/action_controller/Filters.expected +++ b/ruby/ql/test/library-tests/frameworks/action_controller/Filters.expected @@ -1,48 +1,53 @@ -| controllers/comments_controller.rb:12:3:46:5 | index | controllers/application_controller.rb:6:3:8:5 | set_user | controllers/comments_controller.rb:90:3:91:5 | foo | -| controllers/comments_controller.rb:12:3:46:5 | index | controllers/application_controller.rb:10:3:12:5 | log_request | controllers/application_controller.rb:6:3:8:5 | set_user | -| controllers/comments_controller.rb:12:3:46:5 | index | controllers/comments_controller.rb:12:3:46:5 | index | controllers/comments_controller.rb:86:3:88:5 | this_must_run_last | -| controllers/comments_controller.rb:12:3:46:5 | index | controllers/comments_controller.rb:82:3:84:5 | this_must_run_first | controllers/application_controller.rb:10:3:12:5 | log_request | -| controllers/comments_controller.rb:12:3:46:5 | index | controllers/comments_controller.rb:90:3:91:5 | foo | controllers/comments_controller.rb:93:3:94:5 | bar | -| controllers/comments_controller.rb:12:3:46:5 | index | controllers/comments_controller.rb:93:3:94:5 | bar | controllers/comments_controller.rb:12:3:46:5 | index | -| controllers/comments_controller.rb:48:3:49:5 | create | controllers/application_controller.rb:6:3:8:5 | set_user | controllers/comments_controller.rb:69:3:72:5 | ensure_user_can_edit_comments | -| controllers/comments_controller.rb:48:3:49:5 | create | controllers/application_controller.rb:10:3:12:5 | log_request | controllers/application_controller.rb:6:3:8:5 | set_user | -| controllers/comments_controller.rb:48:3:49:5 | create | controllers/comments_controller.rb:48:3:49:5 | create | controllers/comments_controller.rb:78:3:80:5 | log_comment_change | -| controllers/comments_controller.rb:48:3:49:5 | create | controllers/comments_controller.rb:69:3:72:5 | ensure_user_can_edit_comments | controllers/comments_controller.rb:90:3:91:5 | foo | -| controllers/comments_controller.rb:48:3:49:5 | create | controllers/comments_controller.rb:78:3:80:5 | log_comment_change | controllers/comments_controller.rb:86:3:88:5 | this_must_run_last | -| controllers/comments_controller.rb:48:3:49:5 | create | controllers/comments_controller.rb:82:3:84:5 | this_must_run_first | controllers/application_controller.rb:10:3:12:5 | log_request | -| controllers/comments_controller.rb:48:3:49:5 | create | controllers/comments_controller.rb:90:3:91:5 | foo | controllers/comments_controller.rb:93:3:94:5 | bar | -| controllers/comments_controller.rb:48:3:49:5 | create | controllers/comments_controller.rb:93:3:94:5 | bar | controllers/comments_controller.rb:48:3:49:5 | create | -| controllers/comments_controller.rb:51:3:57:5 | show | controllers/application_controller.rb:6:3:8:5 | set_user | controllers/comments_controller.rb:74:3:76:5 | set_comment | -| controllers/comments_controller.rb:51:3:57:5 | show | controllers/application_controller.rb:10:3:12:5 | log_request | controllers/application_controller.rb:6:3:8:5 | set_user | -| controllers/comments_controller.rb:51:3:57:5 | show | controllers/comments_controller.rb:51:3:57:5 | show | controllers/comments_controller.rb:86:3:88:5 | this_must_run_last | -| controllers/comments_controller.rb:51:3:57:5 | show | controllers/comments_controller.rb:74:3:76:5 | set_comment | controllers/comments_controller.rb:90:3:91:5 | foo | -| controllers/comments_controller.rb:51:3:57:5 | show | controllers/comments_controller.rb:82:3:84:5 | this_must_run_first | controllers/application_controller.rb:10:3:12:5 | log_request | -| controllers/comments_controller.rb:51:3:57:5 | show | controllers/comments_controller.rb:90:3:91:5 | foo | controllers/comments_controller.rb:93:3:94:5 | bar | -| controllers/comments_controller.rb:51:3:57:5 | show | controllers/comments_controller.rb:93:3:94:5 | bar | controllers/comments_controller.rb:51:3:57:5 | show | -| controllers/comments_controller.rb:59:3:61:5 | photo | controllers/application_controller.rb:6:3:8:5 | set_user | controllers/comments_controller.rb:90:3:91:5 | foo | -| controllers/comments_controller.rb:59:3:61:5 | photo | controllers/application_controller.rb:10:3:12:5 | log_request | controllers/application_controller.rb:6:3:8:5 | set_user | -| controllers/comments_controller.rb:59:3:61:5 | photo | controllers/comments_controller.rb:59:3:61:5 | photo | controllers/comments_controller.rb:78:3:80:5 | log_comment_change | -| controllers/comments_controller.rb:59:3:61:5 | photo | controllers/comments_controller.rb:78:3:80:5 | log_comment_change | controllers/comments_controller.rb:86:3:88:5 | this_must_run_last | -| controllers/comments_controller.rb:59:3:61:5 | photo | controllers/comments_controller.rb:82:3:84:5 | this_must_run_first | controllers/application_controller.rb:10:3:12:5 | log_request | -| controllers/comments_controller.rb:59:3:61:5 | photo | controllers/comments_controller.rb:90:3:91:5 | foo | controllers/comments_controller.rb:93:3:94:5 | bar | -| controllers/comments_controller.rb:59:3:61:5 | photo | controllers/comments_controller.rb:93:3:94:5 | bar | controllers/comments_controller.rb:59:3:61:5 | photo | -| controllers/comments_controller.rb:63:3:65:5 | destroy | controllers/application_controller.rb:6:3:8:5 | set_user | controllers/comments_controller.rb:69:3:72:5 | ensure_user_can_edit_comments | -| controllers/comments_controller.rb:63:3:65:5 | destroy | controllers/application_controller.rb:10:3:12:5 | log_request | controllers/application_controller.rb:6:3:8:5 | set_user | -| controllers/comments_controller.rb:63:3:65:5 | destroy | controllers/comments_controller.rb:63:3:65:5 | destroy | controllers/comments_controller.rb:78:3:80:5 | log_comment_change | -| controllers/comments_controller.rb:63:3:65:5 | destroy | controllers/comments_controller.rb:69:3:72:5 | ensure_user_can_edit_comments | controllers/comments_controller.rb:74:3:76:5 | set_comment | -| controllers/comments_controller.rb:63:3:65:5 | destroy | controllers/comments_controller.rb:74:3:76:5 | set_comment | controllers/comments_controller.rb:90:3:91:5 | foo | -| controllers/comments_controller.rb:63:3:65:5 | destroy | controllers/comments_controller.rb:78:3:80:5 | log_comment_change | controllers/comments_controller.rb:86:3:88:5 | this_must_run_last | -| controllers/comments_controller.rb:63:3:65:5 | destroy | controllers/comments_controller.rb:82:3:84:5 | this_must_run_first | controllers/application_controller.rb:10:3:12:5 | log_request | -| controllers/comments_controller.rb:63:3:65:5 | destroy | controllers/comments_controller.rb:90:3:91:5 | foo | controllers/comments_controller.rb:93:3:94:5 | bar | -| controllers/comments_controller.rb:63:3:65:5 | destroy | controllers/comments_controller.rb:93:3:94:5 | bar | controllers/comments_controller.rb:63:3:65:5 | destroy | +| controllers/comments_controller.rb:16:3:50:5 | index | controllers/application_controller.rb:6:3:8:5 | set_user | controllers/comments_controller.rb:98:3:99:5 | foo | +| controllers/comments_controller.rb:16:3:50:5 | index | controllers/application_controller.rb:10:3:12:5 | log_request | controllers/application_controller.rb:6:3:8:5 | set_user | +| controllers/comments_controller.rb:16:3:50:5 | index | controllers/comments_controller.rb:16:3:50:5 | index | controllers/comments_controller.rb:86:3:88:5 | check_feature_flags | +| controllers/comments_controller.rb:16:3:50:5 | index | controllers/comments_controller.rb:86:3:88:5 | check_feature_flags | controllers/comments_controller.rb:94:3:96:5 | this_must_run_last | +| controllers/comments_controller.rb:16:3:50:5 | index | controllers/comments_controller.rb:90:3:92:5 | this_must_run_first | controllers/application_controller.rb:10:3:12:5 | log_request | +| controllers/comments_controller.rb:16:3:50:5 | index | controllers/comments_controller.rb:98:3:99:5 | foo | controllers/comments_controller.rb:101:3:102:5 | bar | +| controllers/comments_controller.rb:16:3:50:5 | index | controllers/comments_controller.rb:101:3:102:5 | bar | controllers/comments_controller.rb:16:3:50:5 | index | +| controllers/comments_controller.rb:52:3:53:5 | create | controllers/application_controller.rb:6:3:8:5 | set_user | controllers/comments_controller.rb:73:3:76:5 | ensure_user_can_edit_comments | +| controllers/comments_controller.rb:52:3:53:5 | create | controllers/application_controller.rb:10:3:12:5 | log_request | controllers/application_controller.rb:6:3:8:5 | set_user | +| controllers/comments_controller.rb:52:3:53:5 | create | controllers/comments_controller.rb:52:3:53:5 | create | controllers/comments_controller.rb:82:3:84:5 | log_comment_change | +| controllers/comments_controller.rb:52:3:53:5 | create | controllers/comments_controller.rb:73:3:76:5 | ensure_user_can_edit_comments | controllers/comments_controller.rb:98:3:99:5 | foo | +| controllers/comments_controller.rb:52:3:53:5 | create | controllers/comments_controller.rb:82:3:84:5 | log_comment_change | controllers/comments_controller.rb:86:3:88:5 | check_feature_flags | +| controllers/comments_controller.rb:52:3:53:5 | create | controllers/comments_controller.rb:86:3:88:5 | check_feature_flags | controllers/comments_controller.rb:94:3:96:5 | this_must_run_last | +| controllers/comments_controller.rb:52:3:53:5 | create | controllers/comments_controller.rb:90:3:92:5 | this_must_run_first | controllers/application_controller.rb:10:3:12:5 | log_request | +| controllers/comments_controller.rb:52:3:53:5 | create | controllers/comments_controller.rb:98:3:99:5 | foo | controllers/comments_controller.rb:101:3:102:5 | bar | +| controllers/comments_controller.rb:52:3:53:5 | create | controllers/comments_controller.rb:101:3:102:5 | bar | controllers/comments_controller.rb:52:3:53:5 | create | +| controllers/comments_controller.rb:55:3:61:5 | show | controllers/application_controller.rb:6:3:8:5 | set_user | controllers/comments_controller.rb:78:3:80:5 | set_comment | +| controllers/comments_controller.rb:55:3:61:5 | show | controllers/application_controller.rb:10:3:12:5 | log_request | controllers/application_controller.rb:6:3:8:5 | set_user | +| controllers/comments_controller.rb:55:3:61:5 | show | controllers/comments_controller.rb:55:3:61:5 | show | controllers/comments_controller.rb:86:3:88:5 | check_feature_flags | +| controllers/comments_controller.rb:55:3:61:5 | show | controllers/comments_controller.rb:78:3:80:5 | set_comment | controllers/comments_controller.rb:98:3:99:5 | foo | +| controllers/comments_controller.rb:55:3:61:5 | show | controllers/comments_controller.rb:86:3:88:5 | check_feature_flags | controllers/comments_controller.rb:94:3:96:5 | this_must_run_last | +| controllers/comments_controller.rb:55:3:61:5 | show | controllers/comments_controller.rb:90:3:92:5 | this_must_run_first | controllers/application_controller.rb:10:3:12:5 | log_request | +| controllers/comments_controller.rb:55:3:61:5 | show | controllers/comments_controller.rb:98:3:99:5 | foo | controllers/comments_controller.rb:101:3:102:5 | bar | +| controllers/comments_controller.rb:55:3:61:5 | show | controllers/comments_controller.rb:101:3:102:5 | bar | controllers/comments_controller.rb:55:3:61:5 | show | +| controllers/comments_controller.rb:63:3:65:5 | photo | controllers/application_controller.rb:6:3:8:5 | set_user | controllers/comments_controller.rb:98:3:99:5 | foo | +| controllers/comments_controller.rb:63:3:65:5 | photo | controllers/application_controller.rb:10:3:12:5 | log_request | controllers/application_controller.rb:6:3:8:5 | set_user | +| controllers/comments_controller.rb:63:3:65:5 | photo | controllers/comments_controller.rb:63:3:65:5 | photo | controllers/comments_controller.rb:82:3:84:5 | log_comment_change | +| controllers/comments_controller.rb:63:3:65:5 | photo | controllers/comments_controller.rb:82:3:84:5 | log_comment_change | controllers/comments_controller.rb:86:3:88:5 | check_feature_flags | +| controllers/comments_controller.rb:63:3:65:5 | photo | controllers/comments_controller.rb:86:3:88:5 | check_feature_flags | controllers/comments_controller.rb:94:3:96:5 | this_must_run_last | +| controllers/comments_controller.rb:63:3:65:5 | photo | controllers/comments_controller.rb:90:3:92:5 | this_must_run_first | controllers/application_controller.rb:10:3:12:5 | log_request | +| controllers/comments_controller.rb:63:3:65:5 | photo | controllers/comments_controller.rb:98:3:99:5 | foo | controllers/comments_controller.rb:101:3:102:5 | bar | +| controllers/comments_controller.rb:63:3:65:5 | photo | controllers/comments_controller.rb:101:3:102:5 | bar | controllers/comments_controller.rb:63:3:65:5 | photo | +| controllers/comments_controller.rb:67:3:69:5 | destroy | controllers/application_controller.rb:6:3:8:5 | set_user | controllers/comments_controller.rb:73:3:76:5 | ensure_user_can_edit_comments | +| controllers/comments_controller.rb:67:3:69:5 | destroy | controllers/application_controller.rb:10:3:12:5 | log_request | controllers/application_controller.rb:6:3:8:5 | set_user | +| controllers/comments_controller.rb:67:3:69:5 | destroy | controllers/comments_controller.rb:67:3:69:5 | destroy | controllers/comments_controller.rb:82:3:84:5 | log_comment_change | +| controllers/comments_controller.rb:67:3:69:5 | destroy | controllers/comments_controller.rb:73:3:76:5 | ensure_user_can_edit_comments | controllers/comments_controller.rb:78:3:80:5 | set_comment | +| controllers/comments_controller.rb:67:3:69:5 | destroy | controllers/comments_controller.rb:78:3:80:5 | set_comment | controllers/comments_controller.rb:98:3:99:5 | foo | +| controllers/comments_controller.rb:67:3:69:5 | destroy | controllers/comments_controller.rb:82:3:84:5 | log_comment_change | controllers/comments_controller.rb:86:3:88:5 | check_feature_flags | +| controllers/comments_controller.rb:67:3:69:5 | destroy | controllers/comments_controller.rb:86:3:88:5 | check_feature_flags | controllers/comments_controller.rb:94:3:96:5 | this_must_run_last | +| controllers/comments_controller.rb:67:3:69:5 | destroy | controllers/comments_controller.rb:90:3:92:5 | this_must_run_first | controllers/application_controller.rb:10:3:12:5 | log_request | +| controllers/comments_controller.rb:67:3:69:5 | destroy | controllers/comments_controller.rb:98:3:99:5 | foo | controllers/comments_controller.rb:101:3:102:5 | bar | +| controllers/comments_controller.rb:67:3:69:5 | destroy | controllers/comments_controller.rb:101:3:102:5 | bar | controllers/comments_controller.rb:67:3:69:5 | destroy | | controllers/photos_controller.rb:3:3:6:5 | show | controllers/application_controller.rb:10:3:12:5 | log_request | controllers/photos_controller.rb:3:3:6:5 | show | | controllers/photos_controller.rb:3:3:6:5 | show | controllers/photos_controller.rb:3:3:6:5 | show | controllers/photos_controller.rb:8:3:9:5 | foo | -| controllers/posts_controller.rb:6:3:7:5 | index | controllers/application_controller.rb:6:3:8:5 | set_user | controllers/posts_controller.rb:6:3:7:5 | index | -| controllers/posts_controller.rb:6:3:7:5 | index | controllers/application_controller.rb:10:3:12:5 | log_request | controllers/application_controller.rb:6:3:8:5 | set_user | -| controllers/posts_controller.rb:9:3:10:5 | show | controllers/application_controller.rb:6:3:8:5 | set_user | controllers/posts_controller.rb:17:3:19:5 | set_post | -| controllers/posts_controller.rb:9:3:10:5 | show | controllers/application_controller.rb:10:3:12:5 | log_request | controllers/application_controller.rb:6:3:8:5 | set_user | -| controllers/posts_controller.rb:9:3:10:5 | show | controllers/posts_controller.rb:17:3:19:5 | set_post | controllers/posts_controller.rb:9:3:10:5 | show | -| controllers/posts_controller.rb:12:3:13:5 | upvote | controllers/application_controller.rb:6:3:8:5 | set_user | controllers/posts_controller.rb:17:3:19:5 | set_post | -| controllers/posts_controller.rb:12:3:13:5 | upvote | controllers/application_controller.rb:10:3:12:5 | log_request | controllers/application_controller.rb:6:3:8:5 | set_user | -| controllers/posts_controller.rb:12:3:13:5 | upvote | controllers/posts_controller.rb:12:3:13:5 | upvote | controllers/posts_controller.rb:21:3:23:5 | log_upvote | -| controllers/posts_controller.rb:12:3:13:5 | upvote | controllers/posts_controller.rb:17:3:19:5 | set_post | controllers/posts_controller.rb:12:3:13:5 | upvote | +| controllers/posts_controller.rb:10:3:11:5 | index | controllers/application_controller.rb:6:3:8:5 | set_user | controllers/posts_controller.rb:10:3:11:5 | index | +| controllers/posts_controller.rb:10:3:11:5 | index | controllers/application_controller.rb:10:3:12:5 | log_request | controllers/application_controller.rb:6:3:8:5 | set_user | +| controllers/posts_controller.rb:13:3:14:5 | show | controllers/application_controller.rb:6:3:8:5 | set_user | controllers/posts_controller.rb:13:3:14:5 | show | +| controllers/posts_controller.rb:13:3:14:5 | show | controllers/application_controller.rb:10:3:12:5 | log_request | controllers/posts_controller.rb:21:3:23:5 | set_post | +| controllers/posts_controller.rb:13:3:14:5 | show | controllers/posts_controller.rb:21:3:23:5 | set_post | controllers/application_controller.rb:6:3:8:5 | set_user | +| controllers/posts_controller.rb:16:3:17:5 | upvote | controllers/application_controller.rb:6:3:8:5 | set_user | controllers/posts_controller.rb:16:3:17:5 | upvote | +| controllers/posts_controller.rb:16:3:17:5 | upvote | controllers/application_controller.rb:10:3:12:5 | log_request | controllers/posts_controller.rb:21:3:23:5 | set_post | +| controllers/posts_controller.rb:16:3:17:5 | upvote | controllers/posts_controller.rb:16:3:17:5 | upvote | controllers/posts_controller.rb:25:3:27:5 | log_upvote | +| controllers/posts_controller.rb:16:3:17:5 | upvote | controllers/posts_controller.rb:21:3:23:5 | set_post | controllers/application_controller.rb:6:3:8:5 | set_user | diff --git a/ruby/ql/test/library-tests/frameworks/action_controller/controllers/comments_controller.rb b/ruby/ql/test/library-tests/frameworks/action_controller/controllers/comments_controller.rb index ea50837da99..42cce6d466a 100644 --- a/ruby/ql/test/library-tests/frameworks/action_controller/controllers/comments_controller.rb +++ b/ruby/ql/test/library-tests/frameworks/action_controller/controllers/comments_controller.rb @@ -1,9 +1,13 @@ class CommentsController < ApplicationController + after_action :check_feature_flags + after_action :log_comment_change prepend_after_action :this_must_run_last before_action :set_user before_action :ensure_user_can_edit_comments, only: WRITE_ACTIONS before_action :set_comment, only: [:show, :edit, :update, :destroy] before_action :foo, :bar + + # this overrides the earlier callback on L2 after_action :log_comment_change, except: [:index, :show, :new] prepend_before_action :this_must_run_first @@ -78,6 +82,10 @@ class CommentsController < ApplicationController def log_comment_change AuditLog.create!(:comment_change, user: @user, comment: @comment) end + + def check_feature_flags + raise CommentsNotEnabled unless FeatureFlag.enabled?(:comments) + end def this_must_run_first # for whatever reason diff --git a/ruby/ql/test/library-tests/frameworks/action_controller/controllers/posts_controller.rb b/ruby/ql/test/library-tests/frameworks/action_controller/controllers/posts_controller.rb index 7ff97777b01..5919be005ee 100644 --- a/ruby/ql/test/library-tests/frameworks/action_controller/controllers/posts_controller.rb +++ b/ruby/ql/test/library-tests/frameworks/action_controller/controllers/posts_controller.rb @@ -1,7 +1,11 @@ class PostsController < ApplicationController before_action :set_user append_before_action :set_post, only: [:show, :upvote] + after_action :log_upvote + + # these calls override the earlier ones after_action :log_upvote, only: :upvote + before_action :set_user def index end From 246ad46eb14c16514801ca1caec0ddec23edf52b Mon Sep 17 00:00:00 2001 From: Harry Maclean Date: Mon, 30 Jan 2023 18:50:30 +1300 Subject: [PATCH 04/12] Ruby: Account for filter skip ordering A `skip_*_filter :foo` call only has an effect if there was an earlier call that registered `:foo` as a filter. --- .../frameworks/actioncontroller/Filters.qll | 74 +++++++++++++------ .../action_controller/Filters.expected | 18 ++--- .../controllers/posts_controller.rb | 2 + 3 files changed, 61 insertions(+), 33 deletions(-) diff --git a/ruby/ql/lib/codeql/ruby/frameworks/actioncontroller/Filters.qll b/ruby/ql/lib/codeql/ruby/frameworks/actioncontroller/Filters.qll index 729cee0d243..b0f63547d1e 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/actioncontroller/Filters.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/actioncontroller/Filters.qll @@ -198,33 +198,12 @@ module Filters { FilterKind getKind() { result = kind } - private ModuleBase getEnclosingModule() { result = call.getExpr().getEnclosingModule() } - /** * Holds if this callback is registered before `other`. This does not * guarantee that the callback will be executed before `other`. For example, * `after_action` callbacks are executed in reverse order. */ - predicate registeredBefore(Filter other) { - // before_action :this, :other - // - // before_action :this - // before_action :other - this.getBasicBlock() = other.getBasicBlock() and this.getASuccessor+() = other - or - this.getEnclosingModule() = other.getEnclosingModule() and - this.getBasicBlock().strictlyDominates(other.getBasicBlock()) and - this != other - or - // This callback is in a superclass of `other`'s class. - // - // class A - // before_action :this - // - // class B < A - // before_action :other - other.getEnclosingModule().getModule() = this.getEnclosingModule().getModule().getASubClass+() - } + predicate registeredBefore(Filter other) { callbackRegisteredBefore(call, _, this, other) } /** * Holds if this callback runs before `other`. @@ -277,7 +256,9 @@ module Filters { * with the same name is registered later one, overriding this one. */ predicate skipped(ActionControllerActionMethod action) { - this = any(SkipFilter f | f.getKind() = this.getKind()).getSkippedFilter(action) or + this = + any(SkipFilter f | f.getKind() = this.getKind() and this.registeredBefore(f)) + .getSkippedFilter(action) or this.overridden() } @@ -339,6 +320,11 @@ module Filters { ActionControllerActionMethod getAction() { result = call.getAction() } + predicate registeredBefore(StringlikeLiteralCfgNode other) { + (other instanceof SkipFilter or other instanceof Filter) and + callbackRegisteredBefore(call, _, this, other) + } + Filter getSkippedFilter(ActionControllerActionMethod action) { not result instanceof SkipFilter and action = this.getAction() and @@ -347,6 +333,47 @@ module Filters { } } + /** + * Holds if `predCall` (resp. `succCall`) registers or skips the callback referred to by `pred` (`succ`) and `predCall` is evaluated called before `succCall`. + * Typically this means that `pred` is registered before `succ`, or `pred` is skipped before `succ`, depending on the nature of the call. + * `pred` and `succ` are expected to be arguments. In the examples below, `pred` is `:foo` and `succ` is `:bar`. + * ```rb + * before_action :foo, :bar + * skip_before_action :foo, :bar + * ``` + * This does not guarantee that the callback referred to by `pred` will be executed before + * `succ`. For example, `after_action` callbacks are executed in reverse order. + */ + private predicate callbackRegisteredBefore( + FilterCall predCall, FilterCall succCall, StringlikeLiteralCfgNode pred, + StringlikeLiteralCfgNode succ + ) { + pred = predCall.getFilterArgument() and + succ = succCall.getFilterArgument() and + ( + // before_action :this, :other + // + // before_action :this + // before_action :other + pred.getBasicBlock() = succ.getBasicBlock() and + pred.getASuccessor+() = succ + or + predCall.getExpr().getEnclosingModule() = succCall.getExpr().getEnclosingModule() and + pred.getBasicBlock().strictlyDominates(succ.getBasicBlock()) and + pred != succ + or + // This callback is in a superclass of `other`'s class. + // + // class A + // before_action :this + // + // class B < A + // before_action :other + succCall.getExpr().getEnclosingModule().getModule() = + predCall.getExpr().getEnclosingModule().getModule().getASubClass+() + ) + } + /** * Holds if `pred` is called before `succ` in the callback chain for action `action`. * `pred` and `succ` may be methods bound to callbacks or controller actions. @@ -381,6 +408,5 @@ module Filters { * Holds if `pred` is called before `succ` in the callback chain for some action. * `pred` and `succ` may be methods bound to callbacks or controller actions. */ - cached predicate next(Method pred, Method succ) { next(_, pred, succ) } } diff --git a/ruby/ql/test/library-tests/frameworks/action_controller/Filters.expected b/ruby/ql/test/library-tests/frameworks/action_controller/Filters.expected index 7334fe8a960..2ef139d2a4f 100644 --- a/ruby/ql/test/library-tests/frameworks/action_controller/Filters.expected +++ b/ruby/ql/test/library-tests/frameworks/action_controller/Filters.expected @@ -42,12 +42,12 @@ | controllers/comments_controller.rb:67:3:69:5 | destroy | controllers/comments_controller.rb:101:3:102:5 | bar | controllers/comments_controller.rb:67:3:69:5 | destroy | | controllers/photos_controller.rb:3:3:6:5 | show | controllers/application_controller.rb:10:3:12:5 | log_request | controllers/photos_controller.rb:3:3:6:5 | show | | controllers/photos_controller.rb:3:3:6:5 | show | controllers/photos_controller.rb:3:3:6:5 | show | controllers/photos_controller.rb:8:3:9:5 | foo | -| controllers/posts_controller.rb:10:3:11:5 | index | controllers/application_controller.rb:6:3:8:5 | set_user | controllers/posts_controller.rb:10:3:11:5 | index | -| controllers/posts_controller.rb:10:3:11:5 | index | controllers/application_controller.rb:10:3:12:5 | log_request | controllers/application_controller.rb:6:3:8:5 | set_user | -| controllers/posts_controller.rb:13:3:14:5 | show | controllers/application_controller.rb:6:3:8:5 | set_user | controllers/posts_controller.rb:13:3:14:5 | show | -| controllers/posts_controller.rb:13:3:14:5 | show | controllers/application_controller.rb:10:3:12:5 | log_request | controllers/posts_controller.rb:21:3:23:5 | set_post | -| controllers/posts_controller.rb:13:3:14:5 | show | controllers/posts_controller.rb:21:3:23:5 | set_post | controllers/application_controller.rb:6:3:8:5 | set_user | -| controllers/posts_controller.rb:16:3:17:5 | upvote | controllers/application_controller.rb:6:3:8:5 | set_user | controllers/posts_controller.rb:16:3:17:5 | upvote | -| controllers/posts_controller.rb:16:3:17:5 | upvote | controllers/application_controller.rb:10:3:12:5 | log_request | controllers/posts_controller.rb:21:3:23:5 | set_post | -| controllers/posts_controller.rb:16:3:17:5 | upvote | controllers/posts_controller.rb:16:3:17:5 | upvote | controllers/posts_controller.rb:25:3:27:5 | log_upvote | -| controllers/posts_controller.rb:16:3:17:5 | upvote | controllers/posts_controller.rb:21:3:23:5 | set_post | controllers/application_controller.rb:6:3:8:5 | set_user | +| controllers/posts_controller.rb:12:3:13:5 | index | controllers/application_controller.rb:6:3:8:5 | set_user | controllers/posts_controller.rb:12:3:13:5 | index | +| controllers/posts_controller.rb:12:3:13:5 | index | controllers/application_controller.rb:10:3:12:5 | log_request | controllers/application_controller.rb:6:3:8:5 | set_user | +| controllers/posts_controller.rb:15:3:16:5 | show | controllers/application_controller.rb:6:3:8:5 | set_user | controllers/posts_controller.rb:15:3:16:5 | show | +| controllers/posts_controller.rb:15:3:16:5 | show | controllers/application_controller.rb:10:3:12:5 | log_request | controllers/posts_controller.rb:23:3:25:5 | set_post | +| controllers/posts_controller.rb:15:3:16:5 | show | controllers/posts_controller.rb:23:3:25:5 | set_post | controllers/application_controller.rb:6:3:8:5 | set_user | +| controllers/posts_controller.rb:18:3:19:5 | upvote | controllers/application_controller.rb:6:3:8:5 | set_user | controllers/posts_controller.rb:18:3:19:5 | upvote | +| controllers/posts_controller.rb:18:3:19:5 | upvote | controllers/application_controller.rb:10:3:12:5 | log_request | controllers/posts_controller.rb:23:3:25:5 | set_post | +| controllers/posts_controller.rb:18:3:19:5 | upvote | controllers/posts_controller.rb:18:3:19:5 | upvote | controllers/posts_controller.rb:27:3:29:5 | log_upvote | +| controllers/posts_controller.rb:18:3:19:5 | upvote | controllers/posts_controller.rb:23:3:25:5 | set_post | controllers/application_controller.rb:6:3:8:5 | set_user | diff --git a/ruby/ql/test/library-tests/frameworks/action_controller/controllers/posts_controller.rb b/ruby/ql/test/library-tests/frameworks/action_controller/controllers/posts_controller.rb index 5919be005ee..ed1fa22c2fa 100644 --- a/ruby/ql/test/library-tests/frameworks/action_controller/controllers/posts_controller.rb +++ b/ruby/ql/test/library-tests/frameworks/action_controller/controllers/posts_controller.rb @@ -6,6 +6,8 @@ class PostsController < ApplicationController # these calls override the earlier ones after_action :log_upvote, only: :upvote before_action :set_user + skip_before_action :set_user + before_action :set_user def index end From 28716866d896549d68fbcbc0697e9eeddca5f8f0 Mon Sep 17 00:00:00 2001 From: Harry Maclean Date: Mon, 30 Jan 2023 18:52:47 +1300 Subject: [PATCH 05/12] Ruby: getAction -> getAnAction --- .../frameworks/actioncontroller/Filters.qll | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/ruby/ql/lib/codeql/ruby/frameworks/actioncontroller/Filters.qll b/ruby/ql/lib/codeql/ruby/frameworks/actioncontroller/Filters.qll index b0f63547d1e..607d5544018 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/actioncontroller/Filters.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/actioncontroller/Filters.qll @@ -53,7 +53,7 @@ module Filters { /** * Gets an action which this filter is applied to. */ - ActionControllerActionMethod getAction() { + 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. @@ -212,8 +212,8 @@ module Filters { other.getKind() = this.getKind() and not this.skipped(action) and not other.skipped(action) and - action = this.getAction() and - action = other.getAction() and + action = this.getAnAction() and + action = other.getAnAction() and ( not this.isPrepended() and ( @@ -286,7 +286,7 @@ module Filters { Callable getFilterCallable() { result = call.getFilterCallable(this.getFilterName()) } - ActionControllerActionMethod getAction() { result = call.getAction() } + ActionControllerActionMethod getAnAction() { result = call.getAnAction() } } private class BeforeFilter extends Filter { @@ -318,7 +318,7 @@ module Filters { Callable getFilterCallable() { result = call.getFilterCallable(this.getFilterName()) } - ActionControllerActionMethod getAction() { result = call.getAction() } + ActionControllerActionMethod getAnAction() { result = call.getAnAction() } predicate registeredBefore(StringlikeLiteralCfgNode other) { (other instanceof SkipFilter or other instanceof Filter) and @@ -327,8 +327,8 @@ module Filters { Filter getSkippedFilter(ActionControllerActionMethod action) { not result instanceof SkipFilter and - action = this.getAction() and - action = result.getAction() and + action = this.getAnAction() and + action = result.getAnAction() and result.getFilterCallable() = this.getFilterCallable() } } @@ -386,13 +386,13 @@ module Filters { // Final before filter not exists(f.getNextFilter(action)) and not f.skipped(action) and - action = f.getAction() and + action = f.getAnAction() and succ = action ) or exists(AfterFilter f | // First after filter - action = f.getAction() and + action = f.getAnAction() and not f.skipped(action) and pred = action and succ = f.getFilterCallable() and From 708e303c013b3999b3b2c36ef76b1b5bd98f240f Mon Sep 17 00:00:00 2001 From: Harry Maclean Date: Mon, 30 Jan 2023 21:17:31 +1300 Subject: [PATCH 06/12] Ruby: Model except: with a const argument --- .../frameworks/actioncontroller/Filters.qll | 7 +- .../action_controller/Filters.expected | 84 +++++++++---------- .../controllers/comments_controller.rb | 5 +- 3 files changed, 50 insertions(+), 46 deletions(-) diff --git a/ruby/ql/lib/codeql/ruby/frameworks/actioncontroller/Filters.qll b/ruby/ql/lib/codeql/ruby/frameworks/actioncontroller/Filters.qll index 607d5544018..1047d7af8bc 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/actioncontroller/Filters.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/actioncontroller/Filters.qll @@ -94,8 +94,11 @@ module Filters { result = except.getConstantValue().getStringlikeValue() or // except: [:create, :update] - result = - except.(ArrayLiteralCfgNode).getAnArgument().getConstantValue().getStringlikeValue() + // except: SOME_CONST_ARRAY + exists(ArrayLiteralCfgNode n | + isArrayConstant(except, n) and + result = n.getAnArgument().getConstantValue().getStringlikeValue() + ) ) } diff --git a/ruby/ql/test/library-tests/frameworks/action_controller/Filters.expected b/ruby/ql/test/library-tests/frameworks/action_controller/Filters.expected index 2ef139d2a4f..260a818fc41 100644 --- a/ruby/ql/test/library-tests/frameworks/action_controller/Filters.expected +++ b/ruby/ql/test/library-tests/frameworks/action_controller/Filters.expected @@ -1,45 +1,45 @@ -| controllers/comments_controller.rb:16:3:50:5 | index | controllers/application_controller.rb:6:3:8:5 | set_user | controllers/comments_controller.rb:98:3:99:5 | foo | -| controllers/comments_controller.rb:16:3:50:5 | index | controllers/application_controller.rb:10:3:12:5 | log_request | controllers/application_controller.rb:6:3:8:5 | set_user | -| controllers/comments_controller.rb:16:3:50:5 | index | controllers/comments_controller.rb:16:3:50:5 | index | controllers/comments_controller.rb:86:3:88:5 | check_feature_flags | -| controllers/comments_controller.rb:16:3:50:5 | index | controllers/comments_controller.rb:86:3:88:5 | check_feature_flags | controllers/comments_controller.rb:94:3:96:5 | this_must_run_last | -| controllers/comments_controller.rb:16:3:50:5 | index | controllers/comments_controller.rb:90:3:92:5 | this_must_run_first | controllers/application_controller.rb:10:3:12:5 | log_request | -| controllers/comments_controller.rb:16:3:50:5 | index | controllers/comments_controller.rb:98:3:99:5 | foo | controllers/comments_controller.rb:101:3:102:5 | bar | -| controllers/comments_controller.rb:16:3:50:5 | index | controllers/comments_controller.rb:101:3:102:5 | bar | controllers/comments_controller.rb:16:3:50:5 | index | -| controllers/comments_controller.rb:52:3:53:5 | create | controllers/application_controller.rb:6:3:8:5 | set_user | controllers/comments_controller.rb:73:3:76:5 | ensure_user_can_edit_comments | -| controllers/comments_controller.rb:52:3:53:5 | create | controllers/application_controller.rb:10:3:12:5 | log_request | controllers/application_controller.rb:6:3:8:5 | set_user | -| controllers/comments_controller.rb:52:3:53:5 | create | controllers/comments_controller.rb:52:3:53:5 | create | controllers/comments_controller.rb:82:3:84:5 | log_comment_change | -| controllers/comments_controller.rb:52:3:53:5 | create | controllers/comments_controller.rb:73:3:76:5 | ensure_user_can_edit_comments | controllers/comments_controller.rb:98:3:99:5 | foo | -| controllers/comments_controller.rb:52:3:53:5 | create | controllers/comments_controller.rb:82:3:84:5 | log_comment_change | controllers/comments_controller.rb:86:3:88:5 | check_feature_flags | -| controllers/comments_controller.rb:52:3:53:5 | create | controllers/comments_controller.rb:86:3:88:5 | check_feature_flags | controllers/comments_controller.rb:94:3:96:5 | this_must_run_last | -| controllers/comments_controller.rb:52:3:53:5 | create | controllers/comments_controller.rb:90:3:92:5 | this_must_run_first | controllers/application_controller.rb:10:3:12:5 | log_request | -| controllers/comments_controller.rb:52:3:53:5 | create | controllers/comments_controller.rb:98:3:99:5 | foo | controllers/comments_controller.rb:101:3:102:5 | bar | -| controllers/comments_controller.rb:52:3:53:5 | create | controllers/comments_controller.rb:101:3:102:5 | bar | controllers/comments_controller.rb:52:3:53:5 | create | -| controllers/comments_controller.rb:55:3:61:5 | show | controllers/application_controller.rb:6:3:8:5 | set_user | controllers/comments_controller.rb:78:3:80:5 | set_comment | -| controllers/comments_controller.rb:55:3:61:5 | show | controllers/application_controller.rb:10:3:12:5 | log_request | controllers/application_controller.rb:6:3:8:5 | set_user | -| controllers/comments_controller.rb:55:3:61:5 | show | controllers/comments_controller.rb:55:3:61:5 | show | controllers/comments_controller.rb:86:3:88:5 | check_feature_flags | -| controllers/comments_controller.rb:55:3:61:5 | show | controllers/comments_controller.rb:78:3:80:5 | set_comment | controllers/comments_controller.rb:98:3:99:5 | foo | -| controllers/comments_controller.rb:55:3:61:5 | show | controllers/comments_controller.rb:86:3:88:5 | check_feature_flags | controllers/comments_controller.rb:94:3:96:5 | this_must_run_last | -| controllers/comments_controller.rb:55:3:61:5 | show | controllers/comments_controller.rb:90:3:92:5 | this_must_run_first | controllers/application_controller.rb:10:3:12:5 | log_request | -| controllers/comments_controller.rb:55:3:61:5 | show | controllers/comments_controller.rb:98:3:99:5 | foo | controllers/comments_controller.rb:101:3:102:5 | bar | -| controllers/comments_controller.rb:55:3:61:5 | show | controllers/comments_controller.rb:101:3:102:5 | bar | controllers/comments_controller.rb:55:3:61:5 | show | -| controllers/comments_controller.rb:63:3:65:5 | photo | controllers/application_controller.rb:6:3:8:5 | set_user | controllers/comments_controller.rb:98:3:99:5 | foo | -| controllers/comments_controller.rb:63:3:65:5 | photo | controllers/application_controller.rb:10:3:12:5 | log_request | controllers/application_controller.rb:6:3:8:5 | set_user | -| controllers/comments_controller.rb:63:3:65:5 | photo | controllers/comments_controller.rb:63:3:65:5 | photo | controllers/comments_controller.rb:82:3:84:5 | log_comment_change | -| controllers/comments_controller.rb:63:3:65:5 | photo | controllers/comments_controller.rb:82:3:84:5 | log_comment_change | controllers/comments_controller.rb:86:3:88:5 | check_feature_flags | -| controllers/comments_controller.rb:63:3:65:5 | photo | controllers/comments_controller.rb:86:3:88:5 | check_feature_flags | controllers/comments_controller.rb:94:3:96:5 | this_must_run_last | -| controllers/comments_controller.rb:63:3:65:5 | photo | controllers/comments_controller.rb:90:3:92:5 | this_must_run_first | controllers/application_controller.rb:10:3:12:5 | log_request | -| controllers/comments_controller.rb:63:3:65:5 | photo | controllers/comments_controller.rb:98:3:99:5 | foo | controllers/comments_controller.rb:101:3:102:5 | bar | -| controllers/comments_controller.rb:63:3:65:5 | photo | controllers/comments_controller.rb:101:3:102:5 | bar | controllers/comments_controller.rb:63:3:65:5 | photo | -| controllers/comments_controller.rb:67:3:69:5 | destroy | controllers/application_controller.rb:6:3:8:5 | set_user | controllers/comments_controller.rb:73:3:76:5 | ensure_user_can_edit_comments | -| controllers/comments_controller.rb:67:3:69:5 | destroy | controllers/application_controller.rb:10:3:12:5 | log_request | controllers/application_controller.rb:6:3:8:5 | set_user | -| controllers/comments_controller.rb:67:3:69:5 | destroy | controllers/comments_controller.rb:67:3:69:5 | destroy | controllers/comments_controller.rb:82:3:84:5 | log_comment_change | -| controllers/comments_controller.rb:67:3:69:5 | destroy | controllers/comments_controller.rb:73:3:76:5 | ensure_user_can_edit_comments | controllers/comments_controller.rb:78:3:80:5 | set_comment | -| controllers/comments_controller.rb:67:3:69:5 | destroy | controllers/comments_controller.rb:78:3:80:5 | set_comment | controllers/comments_controller.rb:98:3:99:5 | foo | -| controllers/comments_controller.rb:67:3:69:5 | destroy | controllers/comments_controller.rb:82:3:84:5 | log_comment_change | controllers/comments_controller.rb:86:3:88:5 | check_feature_flags | -| controllers/comments_controller.rb:67:3:69:5 | destroy | controllers/comments_controller.rb:86:3:88:5 | check_feature_flags | controllers/comments_controller.rb:94:3:96:5 | this_must_run_last | -| controllers/comments_controller.rb:67:3:69:5 | destroy | controllers/comments_controller.rb:90:3:92:5 | this_must_run_first | controllers/application_controller.rb:10:3:12:5 | log_request | -| controllers/comments_controller.rb:67:3:69:5 | destroy | controllers/comments_controller.rb:98:3:99:5 | foo | controllers/comments_controller.rb:101:3:102:5 | bar | -| controllers/comments_controller.rb:67:3:69:5 | destroy | controllers/comments_controller.rb:101:3:102:5 | bar | controllers/comments_controller.rb:67:3:69:5 | destroy | +| controllers/comments_controller.rb:17:3:51:5 | index | controllers/application_controller.rb:6:3:8:5 | set_user | controllers/comments_controller.rb:99:3:100:5 | foo | +| controllers/comments_controller.rb:17:3:51:5 | index | controllers/application_controller.rb:10:3:12:5 | log_request | controllers/application_controller.rb:6:3:8:5 | set_user | +| controllers/comments_controller.rb:17:3:51:5 | index | controllers/comments_controller.rb:17:3:51:5 | index | controllers/comments_controller.rb:87:3:89:5 | check_feature_flags | +| controllers/comments_controller.rb:17:3:51:5 | index | controllers/comments_controller.rb:87:3:89:5 | check_feature_flags | controllers/comments_controller.rb:95:3:97:5 | this_must_run_last | +| controllers/comments_controller.rb:17:3:51:5 | index | controllers/comments_controller.rb:91:3:93:5 | this_must_run_first | controllers/application_controller.rb:10:3:12:5 | log_request | +| controllers/comments_controller.rb:17:3:51:5 | index | controllers/comments_controller.rb:99:3:100:5 | foo | controllers/comments_controller.rb:102:3:103:5 | bar | +| controllers/comments_controller.rb:17:3:51:5 | index | controllers/comments_controller.rb:102:3:103:5 | bar | controllers/comments_controller.rb:17:3:51:5 | index | +| controllers/comments_controller.rb:53:3:54:5 | create | controllers/application_controller.rb:6:3:8:5 | set_user | controllers/comments_controller.rb:74:3:77:5 | ensure_user_can_edit_comments | +| controllers/comments_controller.rb:53:3:54:5 | create | controllers/application_controller.rb:10:3:12:5 | log_request | controllers/application_controller.rb:6:3:8:5 | set_user | +| controllers/comments_controller.rb:53:3:54:5 | create | controllers/comments_controller.rb:53:3:54:5 | create | controllers/comments_controller.rb:83:3:85:5 | log_comment_change | +| controllers/comments_controller.rb:53:3:54:5 | create | controllers/comments_controller.rb:74:3:77:5 | ensure_user_can_edit_comments | controllers/comments_controller.rb:99:3:100:5 | foo | +| controllers/comments_controller.rb:53:3:54:5 | create | controllers/comments_controller.rb:83:3:85:5 | log_comment_change | controllers/comments_controller.rb:87:3:89:5 | check_feature_flags | +| controllers/comments_controller.rb:53:3:54:5 | create | controllers/comments_controller.rb:87:3:89:5 | check_feature_flags | controllers/comments_controller.rb:95:3:97:5 | this_must_run_last | +| controllers/comments_controller.rb:53:3:54:5 | create | controllers/comments_controller.rb:91:3:93:5 | this_must_run_first | controllers/application_controller.rb:10:3:12:5 | log_request | +| controllers/comments_controller.rb:53:3:54:5 | create | controllers/comments_controller.rb:99:3:100:5 | foo | controllers/comments_controller.rb:102:3:103:5 | bar | +| controllers/comments_controller.rb:53:3:54:5 | create | controllers/comments_controller.rb:102:3:103:5 | bar | controllers/comments_controller.rb:53:3:54:5 | create | +| controllers/comments_controller.rb:56:3:62:5 | show | controllers/application_controller.rb:6:3:8:5 | set_user | controllers/comments_controller.rb:79:3:81:5 | set_comment | +| controllers/comments_controller.rb:56:3:62:5 | show | controllers/application_controller.rb:10:3:12:5 | log_request | controllers/application_controller.rb:6:3:8:5 | set_user | +| controllers/comments_controller.rb:56:3:62:5 | show | controllers/comments_controller.rb:56:3:62:5 | show | controllers/comments_controller.rb:87:3:89:5 | check_feature_flags | +| controllers/comments_controller.rb:56:3:62:5 | show | controllers/comments_controller.rb:79:3:81:5 | set_comment | controllers/comments_controller.rb:99:3:100:5 | foo | +| controllers/comments_controller.rb:56:3:62:5 | show | controllers/comments_controller.rb:87:3:89:5 | check_feature_flags | controllers/comments_controller.rb:95:3:97:5 | this_must_run_last | +| controllers/comments_controller.rb:56:3:62:5 | show | controllers/comments_controller.rb:91:3:93:5 | this_must_run_first | controllers/application_controller.rb:10:3:12:5 | log_request | +| controllers/comments_controller.rb:56:3:62:5 | show | controllers/comments_controller.rb:99:3:100:5 | foo | controllers/comments_controller.rb:102:3:103:5 | bar | +| controllers/comments_controller.rb:56:3:62:5 | show | controllers/comments_controller.rb:102:3:103:5 | bar | controllers/comments_controller.rb:56:3:62:5 | show | +| controllers/comments_controller.rb:64:3:66:5 | photo | controllers/application_controller.rb:6:3:8:5 | set_user | controllers/comments_controller.rb:99:3:100:5 | foo | +| controllers/comments_controller.rb:64:3:66:5 | photo | controllers/application_controller.rb:10:3:12:5 | log_request | controllers/application_controller.rb:6:3:8:5 | set_user | +| controllers/comments_controller.rb:64:3:66:5 | photo | controllers/comments_controller.rb:64:3:66:5 | photo | controllers/comments_controller.rb:83:3:85:5 | log_comment_change | +| controllers/comments_controller.rb:64:3:66:5 | photo | controllers/comments_controller.rb:83:3:85:5 | log_comment_change | controllers/comments_controller.rb:87:3:89:5 | check_feature_flags | +| controllers/comments_controller.rb:64:3:66:5 | photo | controllers/comments_controller.rb:87:3:89:5 | check_feature_flags | controllers/comments_controller.rb:95:3:97:5 | this_must_run_last | +| controllers/comments_controller.rb:64:3:66:5 | photo | controllers/comments_controller.rb:91:3:93:5 | this_must_run_first | controllers/application_controller.rb:10:3:12:5 | log_request | +| controllers/comments_controller.rb:64:3:66:5 | photo | controllers/comments_controller.rb:99:3:100:5 | foo | controllers/comments_controller.rb:102:3:103:5 | bar | +| controllers/comments_controller.rb:64:3:66:5 | photo | controllers/comments_controller.rb:102:3:103:5 | bar | controllers/comments_controller.rb:64:3:66:5 | photo | +| controllers/comments_controller.rb:68:3:70:5 | destroy | controllers/application_controller.rb:6:3:8:5 | set_user | controllers/comments_controller.rb:74:3:77:5 | ensure_user_can_edit_comments | +| controllers/comments_controller.rb:68:3:70:5 | destroy | controllers/application_controller.rb:10:3:12:5 | log_request | controllers/application_controller.rb:6:3:8:5 | set_user | +| controllers/comments_controller.rb:68:3:70:5 | destroy | controllers/comments_controller.rb:68:3:70:5 | destroy | controllers/comments_controller.rb:83:3:85:5 | log_comment_change | +| controllers/comments_controller.rb:68:3:70:5 | destroy | controllers/comments_controller.rb:74:3:77:5 | ensure_user_can_edit_comments | controllers/comments_controller.rb:79:3:81:5 | set_comment | +| controllers/comments_controller.rb:68:3:70:5 | destroy | controllers/comments_controller.rb:79:3:81:5 | set_comment | controllers/comments_controller.rb:99:3:100:5 | foo | +| controllers/comments_controller.rb:68:3:70:5 | destroy | controllers/comments_controller.rb:83:3:85:5 | log_comment_change | controllers/comments_controller.rb:87:3:89:5 | check_feature_flags | +| controllers/comments_controller.rb:68:3:70:5 | destroy | controllers/comments_controller.rb:87:3:89:5 | check_feature_flags | controllers/comments_controller.rb:95:3:97:5 | this_must_run_last | +| controllers/comments_controller.rb:68:3:70:5 | destroy | controllers/comments_controller.rb:91:3:93:5 | this_must_run_first | controllers/application_controller.rb:10:3:12:5 | log_request | +| controllers/comments_controller.rb:68:3:70:5 | destroy | controllers/comments_controller.rb:99:3:100:5 | foo | controllers/comments_controller.rb:102:3:103:5 | bar | +| controllers/comments_controller.rb:68:3:70:5 | destroy | controllers/comments_controller.rb:102:3:103:5 | bar | controllers/comments_controller.rb:68:3:70:5 | destroy | | controllers/photos_controller.rb:3:3:6:5 | show | controllers/application_controller.rb:10:3:12:5 | log_request | controllers/photos_controller.rb:3:3:6:5 | show | | controllers/photos_controller.rb:3:3:6:5 | show | controllers/photos_controller.rb:3:3:6:5 | show | controllers/photos_controller.rb:8:3:9:5 | foo | | controllers/posts_controller.rb:12:3:13:5 | index | controllers/application_controller.rb:6:3:8:5 | set_user | controllers/posts_controller.rb:12:3:13:5 | index | diff --git a/ruby/ql/test/library-tests/frameworks/action_controller/controllers/comments_controller.rb b/ruby/ql/test/library-tests/frameworks/action_controller/controllers/comments_controller.rb index 42cce6d466a..1129dc268ed 100644 --- a/ruby/ql/test/library-tests/frameworks/action_controller/controllers/comments_controller.rb +++ b/ruby/ql/test/library-tests/frameworks/action_controller/controllers/comments_controller.rb @@ -7,11 +7,12 @@ class CommentsController < ApplicationController before_action :set_comment, only: [:show, :edit, :update, :destroy] before_action :foo, :bar - # this overrides the earlier callback on L2 - after_action :log_comment_change, except: [:index, :show, :new] + # this overrides the earlier callback on L3 + after_action :log_comment_change, except: READ_ACTIONS prepend_before_action :this_must_run_first WRITE_ACTIONS = %i[create update destroy] + READ_ACTIONS = %i[index show new] def index request.params From 5e9210fceac0c5a0501bb23cbc92e59d61dd9d39 Mon Sep 17 00:00:00 2001 From: Harry Maclean Date: Mon, 30 Jan 2023 21:21:38 +1300 Subject: [PATCH 07/12] Ruby: use getAnAncestor --- .../ruby/frameworks/actioncontroller/Filters.qll | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/ruby/ql/lib/codeql/ruby/frameworks/actioncontroller/Filters.qll b/ruby/ql/lib/codeql/ruby/frameworks/actioncontroller/Filters.qll index 1047d7af8bc..063d2466e61 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/actioncontroller/Filters.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/actioncontroller/Filters.qll @@ -124,14 +124,8 @@ module Filters { */ Callable getFilterCallable(string name) { result.(MethodBase).getName() = name and - // Method in same class - ( - result.getEnclosingModule() = this.getExpr().getEnclosingModule() - or - // Method in superclass - result.getEnclosingModule().getModule() = - this.getExpr().getEnclosingModule().getModule().getSuperClass() - ) + result.getEnclosingModule().getModule() = + this.getExpr().getEnclosingModule().getModule().getAnAncestor() } } From 7778524e084bcf62b3b7da0dd158b073fcbb02a5 Mon Sep 17 00:00:00 2001 From: Harry Maclean Date: Mon, 30 Jan 2023 21:52:59 +1300 Subject: [PATCH 08/12] Ruby: Refactor --- .../frameworks/actioncontroller/Filters.qll | 168 ++++++++---------- 1 file changed, 73 insertions(+), 95 deletions(-) diff --git a/ruby/ql/lib/codeql/ruby/frameworks/actioncontroller/Filters.qll b/ruby/ql/lib/codeql/ruby/frameworks/actioncontroller/Filters.qll index 063d2466e61..9a9a3ad92d7 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/actioncontroller/Filters.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/actioncontroller/Filters.qll @@ -174,38 +174,28 @@ module Filters { * def trace_request * start = Time.now * yield - * Logger.info("Request took #{Time.now = start} seconds") + * Logger.info("Request took #{Time.now - start} seconds") * end * end * ``` */ - private class Filter extends StringlikeLiteralCfgNode { - private FilterCall call; - private FilterKind kind; - - Filter() { - this = call.getFilterArgument() and - kind = call.getKind() and - call.getMethodName() = ["", "prepend_", "append_"] + kind + "_action" - } - - predicate isPrepended() { call.getMethodName().regexpMatch("^prepend.+$") } - - MethodCallCfgNode getCall() { result = call } - - FilterKind getKind() { result = kind } + private class Filter extends FilterImpl { + Filter() { not this.isSkipFilter() } /** - * Holds if this callback is registered before `other`. This does not - * guarantee that the callback will be executed before `other`. For example, - * `after_action` callbacks are executed in reverse order. + * Holds if this callback does not run for `action`. This is either because + * it has been explicitly skipped by a `SkipFilter` or because a callback + * with the same name is registered later one, overriding this one. */ - predicate registeredBefore(Filter other) { callbackRegisteredBefore(call, _, this, other) } + predicate skipped(ActionControllerActionMethod action) { + this = any(SkipFilter f).getSkippedFilter(action) or + this.overridden() + } /** * Holds if this callback runs before `other`. */ - private predicate runsBefore(Filter other, ActionControllerActionMethod action) { + predicate runsBefore(Filter other, ActionControllerActionMethod action) { other.getKind() = this.getKind() and not this.skipped(action) and not other.skipped(action) and @@ -246,17 +236,64 @@ module Filters { this.runsBefore(result, action) and not exists(Filter mid | this.runsBefore(mid, action) | mid.runsBefore(result, action)) } + } + + /** + * Behaviour that is common to filters and `skip_*` calls. + * This is separated just because when we don't want `Filter` to include `skip_*` calls. + */ + private class FilterImpl extends StringlikeLiteralCfgNode { + private FilterCall call; + private FilterKind kind; + + FilterImpl() { + this = call.getFilterArgument() and + kind = call.getKind() and + call.getMethodName() = ["", "prepend_", "append_", "skip_"] + kind + "_action" + } + + predicate isSkipFilter() { call.getMethodName().regexpMatch("^skip_.+$") } + + predicate isPrepended() { call.getMethodName().regexpMatch("^prepend.+$") } + + MethodCallCfgNode getCall() { result = call } + + FilterKind getKind() { result = kind } /** - * Holds if this callback does not run for `action`. This is either because - * it has been explicitly skipped by a `SkipFilter` or because a callback - * with the same name is registered later one, overriding this one. + * Holds if this callback is registered before `other`. This does not + * guarantee that the callback will be executed before `other`. For example, + * `after_action` callbacks are executed in reverse order. */ - predicate skipped(ActionControllerActionMethod action) { - this = - any(SkipFilter f | f.getKind() = this.getKind() and this.registeredBefore(f)) - .getSkippedFilter(action) or - this.overridden() + predicate registeredBefore(FilterImpl other) { + exists(FilterCall otherCall | + // predCall -> call + // pred -> this + // succ -> other + other = otherCall.getFilterArgument() and + ( + // before_action :this, :other + // + // before_action :this + // before_action :other + this.getBasicBlock() = other.getBasicBlock() and + this.getASuccessor+() = other + or + call.getExpr().getEnclosingModule() = otherCall.getExpr().getEnclosingModule() and + this.getBasicBlock().strictlyDominates(other.getBasicBlock()) and + this != other + or + // This callback is in a superclass of `other`'s class. + // + // class A + // before_action :this + // + // class B < A + // before_action :other + otherCall.getExpr().getEnclosingModule().getModule() = + call.getExpr().getEnclosingModule().getModule().getASubClass+() + ) + ) } /** @@ -269,8 +306,8 @@ module Filters { * end * ``` */ - private predicate overridden() { - exists(Filter f | + predicate overridden() { + exists(FilterImpl f | f != this and f.getFilterCallable() = this.getFilterCallable() and f.getFilterName() = this.getFilterName() and @@ -279,7 +316,7 @@ module Filters { ) } - private string getFilterName() { result = this.getConstantValue().getStringlikeValue() } + string getFilterName() { result = this.getConstantValue().getStringlikeValue() } Callable getFilterCallable() { result = call.getFilterCallable(this.getFilterName()) } @@ -300,77 +337,18 @@ module Filters { * Like other filter calls, the `except` and `only` keyword arguments can be * passed to restrict the actions that the callback is skipped for. */ - private class SkipFilter extends StringlikeLiteralCfgNode { - private FilterCall call; - private FilterKind kind; - - SkipFilter() { - this = call.getFilterArgument() and - call.getMethodName() = "skip_" + kind + "_action" - } - - FilterKind getKind() { result = kind } - - private string getFilterName() { result = this.getConstantValue().getStringlikeValue() } - - Callable getFilterCallable() { result = call.getFilterCallable(this.getFilterName()) } - - ActionControllerActionMethod getAnAction() { result = call.getAnAction() } - - predicate registeredBefore(StringlikeLiteralCfgNode other) { - (other instanceof SkipFilter or other instanceof Filter) and - callbackRegisteredBefore(call, _, this, other) - } + private class SkipFilter extends FilterImpl { + SkipFilter() { this.isSkipFilter() } Filter getSkippedFilter(ActionControllerActionMethod action) { - not result instanceof SkipFilter and action = this.getAnAction() and action = result.getAnAction() and + result.getKind() = this.getKind() and + result.registeredBefore(this) and result.getFilterCallable() = this.getFilterCallable() } } - /** - * Holds if `predCall` (resp. `succCall`) registers or skips the callback referred to by `pred` (`succ`) and `predCall` is evaluated called before `succCall`. - * Typically this means that `pred` is registered before `succ`, or `pred` is skipped before `succ`, depending on the nature of the call. - * `pred` and `succ` are expected to be arguments. In the examples below, `pred` is `:foo` and `succ` is `:bar`. - * ```rb - * before_action :foo, :bar - * skip_before_action :foo, :bar - * ``` - * This does not guarantee that the callback referred to by `pred` will be executed before - * `succ`. For example, `after_action` callbacks are executed in reverse order. - */ - private predicate callbackRegisteredBefore( - FilterCall predCall, FilterCall succCall, StringlikeLiteralCfgNode pred, - StringlikeLiteralCfgNode succ - ) { - pred = predCall.getFilterArgument() and - succ = succCall.getFilterArgument() and - ( - // before_action :this, :other - // - // before_action :this - // before_action :other - pred.getBasicBlock() = succ.getBasicBlock() and - pred.getASuccessor+() = succ - or - predCall.getExpr().getEnclosingModule() = succCall.getExpr().getEnclosingModule() and - pred.getBasicBlock().strictlyDominates(succ.getBasicBlock()) and - pred != succ - or - // This callback is in a superclass of `other`'s class. - // - // class A - // before_action :this - // - // class B < A - // before_action :other - succCall.getExpr().getEnclosingModule().getModule() = - predCall.getExpr().getEnclosingModule().getModule().getASubClass+() - ) - } - /** * Holds if `pred` is called before `succ` in the callback chain for action `action`. * `pred` and `succ` may be methods bound to callbacks or controller actions. From f7cdd430a2b1764e00fb8e107ec3a07cfae60684 Mon Sep 17 00:00:00 2001 From: Harry Maclean Date: Mon, 30 Jan 2023 21:55:19 +1300 Subject: [PATCH 09/12] Ruby: Small fix --- ruby/ql/lib/codeql/ruby/frameworks/actioncontroller/Filters.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ruby/ql/lib/codeql/ruby/frameworks/actioncontroller/Filters.qll b/ruby/ql/lib/codeql/ruby/frameworks/actioncontroller/Filters.qll index 9a9a3ad92d7..70b09f7a477 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/actioncontroller/Filters.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/actioncontroller/Filters.qll @@ -256,7 +256,7 @@ module Filters { predicate isPrepended() { call.getMethodName().regexpMatch("^prepend.+$") } - MethodCallCfgNode getCall() { result = call } + FilterCall getCall() { result = call } FilterKind getKind() { result = kind } From 69ed00cdf1358b3cf4082b739131720dd1001c35 Mon Sep 17 00:00:00 2001 From: Harry Maclean Date: Tue, 31 Jan 2023 11:06:32 +1300 Subject: [PATCH 10/12] Ruby: QL4QL fix --- .../codeql/ruby/frameworks/actioncontroller/Filters.qll | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/ruby/ql/lib/codeql/ruby/frameworks/actioncontroller/Filters.qll b/ruby/ql/lib/codeql/ruby/frameworks/actioncontroller/Filters.qll index 70b09f7a477..55c7e2e7683 100644 --- a/ruby/ql/lib/codeql/ruby/frameworks/actioncontroller/Filters.qll +++ b/ruby/ql/lib/codeql/ruby/frameworks/actioncontroller/Filters.qll @@ -188,8 +188,11 @@ module Filters { * with the same name is registered later one, overriding this one. */ predicate skipped(ActionControllerActionMethod action) { - this = any(SkipFilter f).getSkippedFilter(action) or - this.overridden() + action = this.getAnAction() and + ( + this = any(SkipFilter f).getSkippedFilter(action) or + this.overridden() + ) } /** @@ -239,7 +242,7 @@ module Filters { } /** - * Behaviour that is common to filters and `skip_*` calls. + * Behavior that is common to filters and `skip_*` calls. * This is separated just because when we don't want `Filter` to include `skip_*` calls. */ private class FilterImpl extends StringlikeLiteralCfgNode { From c99a096c9b7c631d209dbebab90f4a4074069ee7 Mon Sep 17 00:00:00 2001 From: Harry Maclean Date: Tue, 31 Jan 2023 11:27:19 +1300 Subject: [PATCH 11/12] Ruby: Update test fixtures --- .../frameworks/ActionDispatch.expected | 30 +++---- .../frameworks/ActionView.expected | 10 +-- .../ActionController.expected | 90 +++++++++---------- 3 files changed, 65 insertions(+), 65 deletions(-) diff --git a/ruby/ql/test/library-tests/frameworks/ActionDispatch.expected b/ruby/ql/test/library-tests/frameworks/ActionDispatch.expected index 9b55a95b8a1..f09706f05fe 100644 --- a/ruby/ql/test/library-tests/frameworks/ActionDispatch.expected +++ b/ruby/ql/test/library-tests/frameworks/ActionDispatch.expected @@ -78,32 +78,32 @@ actionDispatchRoutes actionDispatchControllerMethods | action_controller/routes.rb:2:5:2:20 | call to resources | action_controller/input_access.rb:2:3:49:5 | index | | action_controller/routes.rb:2:5:2:20 | call to resources | action_controller/logging.rb:2:5:8:7 | index | -| action_controller/routes.rb:3:5:5:7 | call to resources | action_controller/controllers/comments_controller.rb:12:3:46:5 | index | -| action_controller/routes.rb:3:5:5:7 | call to resources | action_controller/controllers/comments_controller.rb:48:3:49:5 | create | -| action_controller/routes.rb:3:5:5:7 | call to resources | action_controller/controllers/comments_controller.rb:51:3:57:5 | show | -| action_controller/routes.rb:3:5:5:7 | call to resources | action_controller/controllers/comments_controller.rb:63:3:65:5 | destroy | +| action_controller/routes.rb:3:5:5:7 | call to resources | action_controller/controllers/comments_controller.rb:17:3:51:5 | index | +| action_controller/routes.rb:3:5:5:7 | call to resources | action_controller/controllers/comments_controller.rb:53:3:54:5 | create | +| action_controller/routes.rb:3:5:5:7 | call to resources | action_controller/controllers/comments_controller.rb:56:3:62:5 | show | +| action_controller/routes.rb:3:5:5:7 | call to resources | action_controller/controllers/comments_controller.rb:68:3:70:5 | destroy | | action_controller/routes.rb:3:5:5:7 | call to resources | app/controllers/comments_controller.rb:2:3:36:5 | index | | action_controller/routes.rb:3:5:5:7 | call to resources | app/controllers/comments_controller.rb:38:3:39:5 | show | -| action_controller/routes.rb:4:9:4:32 | call to get | action_controller/controllers/comments_controller.rb:59:3:61:5 | photo | +| action_controller/routes.rb:4:9:4:32 | call to get | action_controller/controllers/comments_controller.rb:64:3:66:5 | photo | | action_controller/routes.rb:6:5:6:21 | call to resources | action_controller/controllers/photos_controller.rb:3:3:6:5 | show | | action_controller/routes.rb:6:5:6:21 | call to resources | app/controllers/photos_controller.rb:2:3:3:5 | show | -| action_controller/routes.rb:7:5:9:7 | call to resources | action_controller/controllers/posts_controller.rb:6:3:7:5 | index | -| action_controller/routes.rb:7:5:9:7 | call to resources | action_controller/controllers/posts_controller.rb:9:3:10:5 | show | +| action_controller/routes.rb:7:5:9:7 | call to resources | action_controller/controllers/posts_controller.rb:12:3:13:5 | index | +| action_controller/routes.rb:7:5:9:7 | call to resources | action_controller/controllers/posts_controller.rb:15:3:16:5 | show | | action_controller/routes.rb:7:5:9:7 | call to resources | app/controllers/posts_controller.rb:2:3:3:5 | index | | action_controller/routes.rb:7:5:9:7 | call to resources | app/controllers/posts_controller.rb:5:3:6:5 | show | -| action_controller/routes.rb:8:9:8:34 | call to post | action_controller/controllers/posts_controller.rb:12:3:13:5 | upvote | +| action_controller/routes.rb:8:9:8:34 | call to post | action_controller/controllers/posts_controller.rb:18:3:19:5 | upvote | | action_controller/routes.rb:8:9:8:34 | call to post | app/controllers/posts_controller.rb:8:3:9:5 | upvote | -| app/config/routes.rb:2:3:8:5 | call to resources | action_controller/controllers/posts_controller.rb:6:3:7:5 | index | -| app/config/routes.rb:2:3:8:5 | call to resources | action_controller/controllers/posts_controller.rb:9:3:10:5 | show | +| app/config/routes.rb:2:3:8:5 | call to resources | action_controller/controllers/posts_controller.rb:12:3:13:5 | index | +| app/config/routes.rb:2:3:8:5 | call to resources | action_controller/controllers/posts_controller.rb:15:3:16:5 | show | | app/config/routes.rb:2:3:8:5 | call to resources | app/controllers/posts_controller.rb:2:3:3:5 | index | | app/config/routes.rb:2:3:8:5 | call to resources | app/controllers/posts_controller.rb:5:3:6:5 | show | -| app/config/routes.rb:3:5:6:7 | call to resources | action_controller/controllers/comments_controller.rb:12:3:46:5 | index | -| app/config/routes.rb:3:5:6:7 | call to resources | action_controller/controllers/comments_controller.rb:48:3:49:5 | create | -| app/config/routes.rb:3:5:6:7 | call to resources | action_controller/controllers/comments_controller.rb:51:3:57:5 | show | -| app/config/routes.rb:3:5:6:7 | call to resources | action_controller/controllers/comments_controller.rb:63:3:65:5 | destroy | +| app/config/routes.rb:3:5:6:7 | call to resources | action_controller/controllers/comments_controller.rb:17:3:51:5 | index | +| app/config/routes.rb:3:5:6:7 | call to resources | action_controller/controllers/comments_controller.rb:53:3:54:5 | create | +| app/config/routes.rb:3:5:6:7 | call to resources | action_controller/controllers/comments_controller.rb:56:3:62:5 | show | +| app/config/routes.rb:3:5:6:7 | call to resources | action_controller/controllers/comments_controller.rb:68:3:70:5 | destroy | | app/config/routes.rb:3:5:6:7 | call to resources | app/controllers/comments_controller.rb:2:3:36:5 | index | | app/config/routes.rb:3:5:6:7 | call to resources | app/controllers/comments_controller.rb:38:3:39:5 | show | -| app/config/routes.rb:7:5:7:37 | call to post | action_controller/controllers/posts_controller.rb:12:3:13:5 | upvote | +| app/config/routes.rb:7:5:7:37 | call to post | action_controller/controllers/posts_controller.rb:18:3:19:5 | upvote | | app/config/routes.rb:7:5:7:37 | call to post | app/controllers/posts_controller.rb:8:3:9:5 | upvote | | app/config/routes.rb:27:3:27:48 | call to match | action_controller/controllers/photos_controller.rb:3:3:6:5 | show | | app/config/routes.rb:27:3:27:48 | call to match | app/controllers/photos_controller.rb:2:3:3:5 | show | diff --git a/ruby/ql/test/library-tests/frameworks/ActionView.expected b/ruby/ql/test/library-tests/frameworks/ActionView.expected index 2f49c6e7b99..07fb6264633 100644 --- a/ruby/ql/test/library-tests/frameworks/ActionView.expected +++ b/ruby/ql/test/library-tests/frameworks/ActionView.expected @@ -9,8 +9,8 @@ rawCalls | app/views/foo/bars/show.html.erb:5:5:5:21 | call to raw | | app/views/foo/bars/show.html.erb:7:5:7:19 | call to raw | renderCalls -| action_controller/controllers/comments_controller.rb:55:21:55:64 | call to render | -| action_controller/controllers/comments_controller.rb:71:5:71:68 | call to render | +| action_controller/controllers/comments_controller.rb:60:21:60:64 | call to render | +| action_controller/controllers/comments_controller.rb:76:5:76:68 | call to render | | action_controller/controllers/foo/bars_controller.rb:6:5:6:37 | call to render | | action_controller/controllers/foo/bars_controller.rb:23:5:23:76 | call to render | | action_controller/controllers/foo/bars_controller.rb:35:5:35:33 | call to render | @@ -30,9 +30,9 @@ renderToCalls linkToCalls | app/views/foo/bars/show.html.erb:33:5:33:41 | call to link_to | httpResponses -| action_controller/controllers/comments_controller.rb:21:5:21:17 | call to body= | action_controller/controllers/comments_controller.rb:21:21:21:34 | ... = ... | text/http | -| action_controller/controllers/comments_controller.rb:31:5:31:37 | call to send_file | action_controller/controllers/comments_controller.rb:31:24:31:36 | "my-file.ext" | application/octet-stream | -| action_controller/controllers/comments_controller.rb:60:5:60:20 | call to send_data | action_controller/controllers/comments_controller.rb:60:15:60:20 | @photo | application/octet-stream | +| action_controller/controllers/comments_controller.rb:26:5:26:17 | call to body= | action_controller/controllers/comments_controller.rb:26:21:26:34 | ... = ... | text/http | +| action_controller/controllers/comments_controller.rb:36:5:36:37 | call to send_file | action_controller/controllers/comments_controller.rb:36:24:36:36 | "my-file.ext" | application/octet-stream | +| action_controller/controllers/comments_controller.rb:65:5:65:20 | call to send_data | action_controller/controllers/comments_controller.rb:65:15:65:20 | @photo | application/octet-stream | | action_controller/controllers/foo/bars_controller.rb:15:16:15:97 | call to render_to_string | action_controller/controllers/foo/bars_controller.rb:15:33:15:47 | "foo/bars/show" | text/html | | action_controller/controllers/foo/bars_controller.rb:23:5:23:76 | call to render | action_controller/controllers/foo/bars_controller.rb:23:12:23:26 | "foo/bars/show" | text/html | | action_controller/controllers/foo/bars_controller.rb:35:5:35:33 | call to render | action_controller/controllers/foo/bars_controller.rb:35:18:35:33 | call to [] | application/json | diff --git a/ruby/ql/test/library-tests/frameworks/action_controller/ActionController.expected b/ruby/ql/test/library-tests/frameworks/action_controller/ActionController.expected index e34eddc94d1..e17f691b149 100644 --- a/ruby/ql/test/library-tests/frameworks/action_controller/ActionController.expected +++ b/ruby/ql/test/library-tests/frameworks/action_controller/ActionController.expected @@ -1,20 +1,20 @@ actionControllerControllerClasses | controllers/application_controller.rb:1:1:13:3 | ApplicationController | -| controllers/comments_controller.rb:1:1:95:3 | CommentsController | +| controllers/comments_controller.rb:1:1:104:3 | CommentsController | | controllers/foo/bars_controller.rb:3:1:46:3 | BarsController | | controllers/photos_controller.rb:1:1:10:3 | PhotosController | -| controllers/posts_controller.rb:1:1:24:3 | PostsController | +| controllers/posts_controller.rb:1:1:30:3 | PostsController | | controllers/tags_controller.rb:1:1:2:3 | TagsController | | controllers/users/notifications_controller.rb:2:3:5:5 | Users::NotificationsController | | input_access.rb:1:1:50:3 | UsersController | | params_flow.rb:1:1:162:3 | MyController | | params_flow.rb:170:1:178:3 | Subclass | actionControllerActionMethods -| controllers/comments_controller.rb:12:3:46:5 | index | -| controllers/comments_controller.rb:48:3:49:5 | create | -| controllers/comments_controller.rb:51:3:57:5 | show | -| controllers/comments_controller.rb:59:3:61:5 | photo | -| controllers/comments_controller.rb:63:3:65:5 | destroy | +| controllers/comments_controller.rb:17:3:51:5 | index | +| controllers/comments_controller.rb:53:3:54:5 | create | +| controllers/comments_controller.rb:56:3:62:5 | show | +| controllers/comments_controller.rb:64:3:66:5 | photo | +| controllers/comments_controller.rb:68:3:70:5 | destroy | | controllers/foo/bars_controller.rb:5:3:7:5 | index | | controllers/foo/bars_controller.rb:9:3:18:5 | show_debug | | controllers/foo/bars_controller.rb:20:3:24:5 | show | @@ -23,9 +23,9 @@ actionControllerActionMethods | controllers/foo/bars_controller.rb:34:3:39:5 | show_2 | | controllers/photos_controller.rb:3:3:6:5 | show | | controllers/photos_controller.rb:8:3:9:5 | foo | -| controllers/posts_controller.rb:6:3:7:5 | index | -| controllers/posts_controller.rb:9:3:10:5 | show | -| controllers/posts_controller.rb:12:3:13:5 | upvote | +| controllers/posts_controller.rb:12:3:13:5 | index | +| controllers/posts_controller.rb:15:3:16:5 | show | +| controllers/posts_controller.rb:18:3:19:5 | upvote | | controllers/users/notifications_controller.rb:3:5:4:7 | mark_as_read | | input_access.rb:2:3:49:5 | index | | logging.rb:2:5:8:7 | index | @@ -66,12 +66,12 @@ actionControllerActionMethods | params_flow.rb:165:3:167:5 | m34 | | params_flow.rb:171:3:173:5 | m35 | paramsCalls -| controllers/comments_controller.rb:75:36:75:41 | call to params | +| controllers/comments_controller.rb:80:36:80:41 | call to params | | controllers/foo/bars_controller.rb:13:21:13:26 | call to params | | controllers/foo/bars_controller.rb:14:10:14:15 | call to params | | controllers/foo/bars_controller.rb:21:21:21:26 | call to params | | controllers/foo/bars_controller.rb:22:10:22:15 | call to params | -| controllers/posts_controller.rb:18:23:18:28 | call to params | +| controllers/posts_controller.rb:24:23:24:28 | call to params | | params_flow.rb:3:10:3:15 | call to params | | params_flow.rb:7:10:7:15 | call to params | | params_flow.rb:11:10:11:15 | call to params | @@ -121,12 +121,12 @@ paramsCalls | params_flow.rb:172:10:172:15 | call to params | | params_flow.rb:176:10:176:15 | call to params | paramsSources -| controllers/comments_controller.rb:75:36:75:41 | call to params | +| controllers/comments_controller.rb:80:36:80:41 | call to params | | controllers/foo/bars_controller.rb:13:21:13:26 | call to params | | controllers/foo/bars_controller.rb:14:10:14:15 | call to params | | controllers/foo/bars_controller.rb:21:21:21:26 | call to params | | controllers/foo/bars_controller.rb:22:10:22:15 | call to params | -| controllers/posts_controller.rb:18:23:18:28 | call to params | +| controllers/posts_controller.rb:24:23:24:28 | call to params | | params_flow.rb:3:10:3:15 | call to params | | params_flow.rb:7:10:7:15 | call to params | | params_flow.rb:11:10:11:15 | call to params | @@ -177,21 +177,21 @@ paramsSources | params_flow.rb:176:10:176:15 | call to params | httpInputAccesses | controllers/application_controller.rb:11:53:11:64 | call to path | ActionDispatch::Request#path | -| controllers/comments_controller.rb:13:5:13:18 | call to params | ActionDispatch::Request#params | -| controllers/comments_controller.rb:14:5:14:22 | call to parameters | ActionDispatch::Request#parameters | -| controllers/comments_controller.rb:15:5:15:15 | call to GET | ActionDispatch::Request#GET | -| controllers/comments_controller.rb:16:5:16:16 | call to POST | ActionDispatch::Request#POST | -| controllers/comments_controller.rb:17:5:17:28 | call to query_parameters | ActionDispatch::Request#query_parameters | -| controllers/comments_controller.rb:18:5:18:30 | call to request_parameters | ActionDispatch::Request#request_parameters | -| controllers/comments_controller.rb:19:5:19:31 | call to filtered_parameters | ActionDispatch::Request#filtered_parameters | -| controllers/comments_controller.rb:64:12:64:30 | call to body_stream | ActionDispatch::Request#body_stream | -| controllers/comments_controller.rb:75:36:75:41 | call to params | ActionController::Metal#params | +| controllers/comments_controller.rb:18:5:18:18 | call to params | ActionDispatch::Request#params | +| controllers/comments_controller.rb:19:5:19:22 | call to parameters | ActionDispatch::Request#parameters | +| controllers/comments_controller.rb:20:5:20:15 | call to GET | ActionDispatch::Request#GET | +| controllers/comments_controller.rb:21:5:21:16 | call to POST | ActionDispatch::Request#POST | +| controllers/comments_controller.rb:22:5:22:28 | call to query_parameters | ActionDispatch::Request#query_parameters | +| controllers/comments_controller.rb:23:5:23:30 | call to request_parameters | ActionDispatch::Request#request_parameters | +| controllers/comments_controller.rb:24:5:24:31 | call to filtered_parameters | ActionDispatch::Request#filtered_parameters | +| controllers/comments_controller.rb:69:12:69:30 | call to body_stream | ActionDispatch::Request#body_stream | +| controllers/comments_controller.rb:80:36:80:41 | call to params | ActionController::Metal#params | | controllers/foo/bars_controller.rb:10:27:10:33 | call to cookies | ActionController::Metal#cookies | | controllers/foo/bars_controller.rb:13:21:13:26 | call to params | ActionController::Metal#params | | controllers/foo/bars_controller.rb:14:10:14:15 | call to params | ActionController::Metal#params | | controllers/foo/bars_controller.rb:21:21:21:26 | call to params | ActionController::Metal#params | | controllers/foo/bars_controller.rb:22:10:22:15 | call to params | ActionController::Metal#params | -| controllers/posts_controller.rb:18:23:18:28 | call to params | ActionController::Metal#params | +| controllers/posts_controller.rb:24:23:24:28 | call to params | ActionController::Metal#params | | input_access.rb:3:5:3:18 | call to params | ActionDispatch::Request#params | | input_access.rb:4:5:4:22 | call to parameters | ActionDispatch::Request#parameters | | input_access.rb:5:5:5:15 | call to GET | ActionDispatch::Request#GET | @@ -285,22 +285,22 @@ cookiesCalls cookiesSources | controllers/foo/bars_controller.rb:10:27:10:33 | call to cookies | redirectToCalls -| controllers/comments_controller.rb:53:21:53:49 | call to redirect_to | +| controllers/comments_controller.rb:58:21:58:49 | call to redirect_to | | controllers/foo/bars_controller.rb:17:5:17:30 | call to redirect_to | | controllers/foo/bars_controller.rb:27:5:27:39 | call to redirect_back_or_to | | controllers/foo/bars_controller.rb:31:5:31:56 | call to redirect_back | renderCalls -| controllers/comments_controller.rb:55:21:55:64 | call to render | -| controllers/comments_controller.rb:71:5:71:68 | call to render | +| controllers/comments_controller.rb:60:21:60:64 | call to render | +| controllers/comments_controller.rb:76:5:76:68 | call to render | | controllers/foo/bars_controller.rb:6:5:6:37 | call to render | | controllers/foo/bars_controller.rb:23:5:23:76 | call to render | | controllers/foo/bars_controller.rb:35:5:35:33 | call to render | | controllers/foo/bars_controller.rb:38:5:38:50 | call to render | | controllers/foo/bars_controller.rb:44:5:44:17 | call to render | httpResponses -| controllers/comments_controller.rb:21:5:21:17 | call to body= | controllers/comments_controller.rb:21:21:21:34 | ... = ... | -| controllers/comments_controller.rb:31:5:31:37 | call to send_file | controllers/comments_controller.rb:31:24:31:36 | "my-file.ext" | -| controllers/comments_controller.rb:60:5:60:20 | call to send_data | controllers/comments_controller.rb:60:15:60:20 | @photo | +| controllers/comments_controller.rb:26:5:26:17 | call to body= | controllers/comments_controller.rb:26:21:26:34 | ... = ... | +| controllers/comments_controller.rb:36:5:36:37 | call to send_file | controllers/comments_controller.rb:36:24:36:36 | "my-file.ext" | +| controllers/comments_controller.rb:65:5:65:20 | call to send_data | controllers/comments_controller.rb:65:15:65:20 | @photo | | controllers/foo/bars_controller.rb:15:16:15:97 | call to render_to_string | controllers/foo/bars_controller.rb:15:33:15:47 | "foo/bars/show" | | controllers/foo/bars_controller.rb:23:5:23:76 | call to render | controllers/foo/bars_controller.rb:23:12:23:26 | "foo/bars/show" | | controllers/foo/bars_controller.rb:35:5:35:33 | call to render | controllers/foo/bars_controller.rb:35:18:35:33 | call to [] | @@ -311,21 +311,21 @@ actionControllerHelperMethods getAssociatedControllerClasses controllerTemplateFiles headerWriteAccesses -| controllers/comments_controller.rb:25:5:25:35 | call to []= | content-type | controllers/comments_controller.rb:25:39:25:49 | ... = ... | -| controllers/comments_controller.rb:26:5:26:46 | call to set_header | content-length | controllers/comments_controller.rb:26:43:26:45 | 100 | -| controllers/comments_controller.rb:27:5:27:39 | call to []= | x-custom-header | controllers/comments_controller.rb:27:43:27:46 | ... = ... | -| controllers/comments_controller.rb:28:5:28:39 | call to []= | x-another-custom-header | controllers/comments_controller.rb:28:43:28:47 | ... = ... | -| controllers/comments_controller.rb:29:5:29:49 | call to add_header | x-yet-another | controllers/comments_controller.rb:29:42:29:49 | "indeed" | -| controllers/comments_controller.rb:35:5:35:21 | call to location= | location | controllers/comments_controller.rb:35:25:35:36 | ... = ... | -| controllers/comments_controller.rb:36:5:36:26 | call to cache_control= | cache-control | controllers/comments_controller.rb:36:30:36:36 | ... = ... | -| controllers/comments_controller.rb:37:5:37:27 | call to _cache_control= | cache-control | controllers/comments_controller.rb:37:31:37:37 | ... = ... | -| controllers/comments_controller.rb:38:5:38:17 | call to etag= | etag | controllers/comments_controller.rb:38:21:38:27 | ... = ... | -| controllers/comments_controller.rb:39:5:39:20 | call to charset= | content-type | controllers/comments_controller.rb:39:24:39:30 | ... = ... | -| controllers/comments_controller.rb:40:5:40:25 | call to content_type= | content-type | controllers/comments_controller.rb:40:29:40:35 | ... = ... | -| controllers/comments_controller.rb:42:5:42:17 | call to date= | date | controllers/comments_controller.rb:42:21:42:30 | ... = ... | -| controllers/comments_controller.rb:43:5:43:26 | call to last_modified= | last-modified | controllers/comments_controller.rb:43:30:43:43 | ... = ... | -| controllers/comments_controller.rb:44:5:44:22 | call to weak_etag= | etag | controllers/comments_controller.rb:44:26:44:32 | ... = ... | -| controllers/comments_controller.rb:45:5:45:24 | call to strong_etag= | etag | controllers/comments_controller.rb:45:28:45:34 | ... = ... | +| controllers/comments_controller.rb:30:5:30:35 | call to []= | content-type | controllers/comments_controller.rb:30:39:30:49 | ... = ... | +| controllers/comments_controller.rb:31:5:31:46 | call to set_header | content-length | controllers/comments_controller.rb:31:43:31:45 | 100 | +| controllers/comments_controller.rb:32:5:32:39 | call to []= | x-custom-header | controllers/comments_controller.rb:32:43:32:46 | ... = ... | +| controllers/comments_controller.rb:33:5:33:39 | call to []= | x-another-custom-header | controllers/comments_controller.rb:33:43:33:47 | ... = ... | +| controllers/comments_controller.rb:34:5:34:49 | call to add_header | x-yet-another | controllers/comments_controller.rb:34:42:34:49 | "indeed" | +| controllers/comments_controller.rb:40:5:40:21 | call to location= | location | controllers/comments_controller.rb:40:25:40:36 | ... = ... | +| controllers/comments_controller.rb:41:5:41:26 | call to cache_control= | cache-control | controllers/comments_controller.rb:41:30:41:36 | ... = ... | +| controllers/comments_controller.rb:42:5:42:27 | call to _cache_control= | cache-control | controllers/comments_controller.rb:42:31:42:37 | ... = ... | +| controllers/comments_controller.rb:43:5:43:17 | call to etag= | etag | controllers/comments_controller.rb:43:21:43:27 | ... = ... | +| controllers/comments_controller.rb:44:5:44:20 | call to charset= | content-type | controllers/comments_controller.rb:44:24:44:30 | ... = ... | +| controllers/comments_controller.rb:45:5:45:25 | call to content_type= | content-type | controllers/comments_controller.rb:45:29:45:35 | ... = ... | +| controllers/comments_controller.rb:47:5:47:17 | call to date= | date | controllers/comments_controller.rb:47:21:47:30 | ... = ... | +| controllers/comments_controller.rb:48:5:48:26 | call to last_modified= | last-modified | controllers/comments_controller.rb:48:30:48:43 | ... = ... | +| controllers/comments_controller.rb:49:5:49:22 | call to weak_etag= | etag | controllers/comments_controller.rb:49:26:49:32 | ... = ... | +| controllers/comments_controller.rb:50:5:50:24 | call to strong_etag= | etag | controllers/comments_controller.rb:50:28:50:34 | ... = ... | loggingCalls | logging.rb:3:9:3:31 | call to info | logging.rb:3:21:3:31 | "some info" | | logging.rb:4:9:4:31 | call to warn | logging.rb:4:21:4:31 | "a warning" | From 373148decdc6c75c3bfcce32b0190557d82949ec Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 1 Feb 2023 03:11:28 +0000 Subject: [PATCH 12/12] Bump tracing from 0.1.35 to 0.1.37 in /ql Bumps [tracing](https://github.com/tokio-rs/tracing) from 0.1.35 to 0.1.37. - [Release notes](https://github.com/tokio-rs/tracing/releases) - [Commits](https://github.com/tokio-rs/tracing/compare/tracing-0.1.35...tracing-0.1.37) --- updated-dependencies: - dependency-name: tracing dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- ql/Cargo.lock | Bin 15321 -> 15321 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/ql/Cargo.lock b/ql/Cargo.lock index 6ee11a3ab467db0e9c7543dc6c959286b1dc7520..d9961c9d94feceb23c49a38b26b710e718615cce 100644 GIT binary patch delta 169 zcmWm7u?+$-3_wvKBnqHr1S&vr?AX2v=#iKqXD1_YgJc3WIEiVlMr^*{`1D{6>YowRpK&XF>g6p<)Zk5CNIkrSFHsH~9t%0i$uQR&-rxohKk)7tT| yz`uB*08+J50_;?RWhpF?m0=DbCSWojLUigP70)c7926~JnE96Xx7X+N-TnaJh%sdV delta 167 zcmWN~u?+$-3;;mUPyjU>K=mLyiTzFm^hmHmoH!%!bD%8p5|dDVjo5$z_~zQ1hG`f- z-GbU>c{`;5U>;Lq&{#r9