Skip to content

Commit 4892025

Browse files
committed
ruby: Filter out loops over constants
1 parent af2a4c3 commit 4892025

File tree

2 files changed

+51
-5
lines changed

2 files changed

+51
-5
lines changed

ruby/ql/src/queries/performance/CouldBeHoisted.ql

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
// If you already did article includes book, there should be no problem.
1717
import ruby
1818
private import codeql.ruby.AST
19+
import codeql.ruby.ast.internal.Constant
1920
import codeql.ruby.Concepts
2021
import codeql.ruby.frameworks.ActiveRecord
2122
private import codeql.ruby.TaintTracking
@@ -84,12 +85,14 @@ DataFlow::Node guardForLoopControl(ConditionalExpr cond, Stmt control) {
8485

8586
from LoopingCall loop, DataFlow::CallNode call
8687
where
87-
// TODO: Filter loops over constants
88+
// Filter loops over constants
89+
not isArrayConstant(loop.getReceiver().asExpr(), _) and
90+
// Filter tests
8891
not call.getLocation().getFile().getAbsolutePath().matches("%test%") and
89-
// not call = any(PluckCall p).chaines() and
92+
not call = any(PluckCall p).chaines() and
9093
not usedInLoopControlGuard(call, _) and
9194
happensInInnermostLoop(loop, call) and
92-
call instanceof ActiveRecordModelFinderCall and
93-
not call.getMethodName() in ["new", "create"] //and
94-
// call.getLocation().getFile().getAbsolutePath().matches("%app/models/stafftools/%")
95+
(call instanceof ActiveRecordModelFinderCall or call instanceof PluckCall) and
96+
not call.getMethodName() in ["new", "create"] and
97+
call.getLocation().getFile().getAbsolutePath().matches(["%app/models/s%", "%app/models/e%"])
9598
select call, "This call happens inside $@, and could be hoisted.", loop, "this loop"
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
In this snippet
2+
```ruby
3+
users = []
4+
app_integration = authentication_token.authenticatable.integration
5+
app_owner = app_integration.owner
6+
if app_owner.user?
7+
users << app_owner.id
8+
else
9+
potential_users = []
10+
Permissions::Enumerator.actor_ids_with_permission(
11+
action: :manage_app,
12+
subject_id: app_integration.id,
13+
context: { owner_id: app_owner.id },
14+
).map do |actor_id|
15+
potential_users << actor_id
16+
end
17+
18+
Permissions::Enumerator.actor_ids_with_permission(
19+
action: :manage_all_apps,
20+
subject_id: app_owner.id
21+
).map do |actor_id|
22+
potential_users << actor_id
23+
end
24+
25+
app_owner.members(actor_ids: potential_users).each do |member|
26+
users << member.id
27+
end
28+
end
29+
30+
users.each do |user_id|
31+
if !is_one_click_revoke
32+
notify_user_of_revoked_access(
33+
target: target,
34+
user: User.find(user_id),
35+
token: token,
36+
app_name: app_integration.name,
37+
revoked_by: revoked_by,
38+
is_expired: authentication_token.expires_at_timestamp.to_i < Time.now.to_i,
39+
)
40+
end
41+
end
42+
```
43+
`users` is identified as an array constant.

0 commit comments

Comments
 (0)