Skip to content

Commit a164e76

Browse files
committed
Ruby: Model actioncontroller filter overrides
If a filter is registered twice with the same name, the last registration wins.
1 parent 28c3bd3 commit a164e76

File tree

4 files changed

+90
-47
lines changed

4 files changed

+90
-47
lines changed

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

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -271,8 +271,34 @@ module Filters {
271271
not exists(Filter mid | this.runsBefore(mid, action) | mid.runsBefore(result, action))
272272
}
273273

274+
/**
275+
* Holds if this callback does not run for `action`. This is either because
276+
* it has been explicitly skipped by a `SkipFilter` or because a callback
277+
* with the same name is registered later one, overriding this one.
278+
*/
274279
predicate skipped(ActionControllerActionMethod action) {
275-
this = any(SkipFilter f | f.getKind() = this.getKind()).getSkippedFilter(action)
280+
this = any(SkipFilter f | f.getKind() = this.getKind()).getSkippedFilter(action) or
281+
this.overridden()
282+
}
283+
284+
/**
285+
* Holds if this callback is overridden by a callback with the same name. For example:
286+
* ```rb
287+
* class UsersController
288+
* before_action :foo # this filter is override by the subsequent `before_action :foo` call below.
289+
* before_action :bar
290+
* before_action :foo
291+
* end
292+
* ```
293+
*/
294+
private predicate overridden() {
295+
exists(Filter f |
296+
f != this and
297+
f.getFilterCallable() = this.getFilterCallable() and
298+
f.getFilterName() = this.getFilterName() and
299+
f.getKind() = this.getKind() and
300+
this.registeredBefore(f)
301+
)
276302
}
277303

278304
private string getFilterName() { result = this.getConstantValue().getStringlikeValue() }
Lines changed: 51 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,53 @@
1-
| 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 |
2-
| 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 |
3-
| 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 |
4-
| 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 |
5-
| 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 |
6-
| 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 |
7-
| 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 |
8-
| 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 |
9-
| 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 |
10-
| 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 |
11-
| 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 |
12-
| 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 |
13-
| 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 |
14-
| 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 |
15-
| 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 |
16-
| 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 |
17-
| 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 |
18-
| 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 |
19-
| 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 |
20-
| 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 |
21-
| 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 |
22-
| 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 |
23-
| 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 |
24-
| 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 |
25-
| 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 |
26-
| 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 |
27-
| 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 |
28-
| 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 |
29-
| 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 |
30-
| 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 |
31-
| 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 |
32-
| 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 |
33-
| 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 |
34-
| 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 |
35-
| 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 |
36-
| 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 |
37-
| 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 |
1+
| 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 |
2+
| 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 |
3+
| 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 |
4+
| 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 |
5+
| 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 |
6+
| 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 |
7+
| 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 |
8+
| 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 |
9+
| 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 |
10+
| 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 |
11+
| 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 |
12+
| 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 |
13+
| 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 |
14+
| 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 |
15+
| 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 |
16+
| 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 |
17+
| 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 |
18+
| 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 |
19+
| 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 |
20+
| 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 |
21+
| 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 |
22+
| 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 |
23+
| 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 |
24+
| 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 |
25+
| 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 |
26+
| 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 |
27+
| 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 |
28+
| 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 |
29+
| 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 |
30+
| 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 |
31+
| 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 |
32+
| 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 |
33+
| 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 |
34+
| 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 |
35+
| 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 |
36+
| 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 |
37+
| 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 |
38+
| 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 |
39+
| 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 |
40+
| 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 |
41+
| 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 |
42+
| 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 |
3843
| 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 |
3944
| 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 |
40-
| 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 |
41-
| 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 |
42-
| 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 |
43-
| 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 |
44-
| 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 |
45-
| 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 |
46-
| 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 |
47-
| 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 |
48-
| 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 |
45+
| 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 |
46+
| 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 |
47+
| 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 |
48+
| 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 |
49+
| 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 |
50+
| 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 |
51+
| 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 |
52+
| 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 |
53+
| 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 |

ruby/ql/test/library-tests/frameworks/action_controller/controllers/comments_controller.rb

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
11
class CommentsController < ApplicationController
2+
after_action :check_feature_flags
3+
after_action :log_comment_change
24
prepend_after_action :this_must_run_last
35
before_action :set_user
46
before_action :ensure_user_can_edit_comments, only: WRITE_ACTIONS
57
before_action :set_comment, only: [:show, :edit, :update, :destroy]
68
before_action :foo, :bar
9+
10+
# this overrides the earlier callback on L2
711
after_action :log_comment_change, except: [:index, :show, :new]
812
prepend_before_action :this_must_run_first
913

@@ -78,6 +82,10 @@ def set_comment
7882
def log_comment_change
7983
AuditLog.create!(:comment_change, user: @user, comment: @comment)
8084
end
85+
86+
def check_feature_flags
87+
raise CommentsNotEnabled unless FeatureFlag.enabled?(:comments)
88+
end
8189

8290
def this_must_run_first
8391
# for whatever reason

ruby/ql/test/library-tests/frameworks/action_controller/controllers/posts_controller.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
class PostsController < ApplicationController
22
before_action :set_user
33
append_before_action :set_post, only: [:show, :upvote]
4+
after_action :log_upvote
5+
6+
# these calls override the earlier ones
47
after_action :log_upvote, only: :upvote
8+
before_action :set_user
59

610
def index
711
end

0 commit comments

Comments
 (0)