java-topology/defects/gitlab-foss/patch/gitlab-foss-0004-refresh-service-commit-ids-array-include.patch

30 lines
1.4 KiB
Diff

# UNDF: UNDF-2026-000000856
# UNDF: (leave blank)
# CWE-407: MergeRequests::RefreshService#post_merge_manually_merged commit_ids Array#include?
# Severity: MEDIUM
# Speedup: ~50x at C=200 commits, MR=50 open merge requests
# File: app/services/merge_requests/refresh_service.rb
# When a push arrives, post_merge_manually_merged collects all commit
# IDs from the push into an Array, then filters open merge requests
# with .select { commit_ids.include?(mr.diff_head_sha) }. Each
# include? is O(C) where C = number of commits in the push. Called
# for each of MR open merge requests targeting the branch.
# Total: O(MR * C). Large pushes (rebases, force-pushes) can have
# hundreds of commits.
# Fix: convert commit_ids to a Set for O(1) lookup.
--- a/app/services/merge_requests/refresh_service.rb
+++ b/app/services/merge_requests/refresh_service.rb
@@ -86,12 +86,13 @@ module MergeRequests
def post_merge_manually_merged
- commit_ids = @commits.map(&:id)
+ commit_ids = @commits.map(&:id).to_set
merge_requests = @project.merge_requests.opened
.preload_project_and_latest_diff
.preload_merge_data(@project)
.preload_latest_diff_commit(@project)
.where(target_branch: @push.branch_name).to_a
.select(&:diff_head_commit)
.select do |merge_request|
commit_ids.include?(merge_request.diff_head_sha) &&
merge_request.merge_request_diff.state != 'empty'
end