Skip to content

Commit c0a175d

Browse files
authored
#474: Anchor Fbe.mask_to_regex regex to prevent prefix collisions (#495)
* fix: anchor Fbe.mask_to_regex regex to prevent prefix collisions The regex built by Fbe.mask_to_regex was unanchored, so re.match? would match substrings. For exclusion masks like '-zerocracy/judges-action', this caused repositories with prefix collisions (e.g. 'zerocracy/judges-actions' or 'zerocracy/judges-action-old') to be incorrectly excluded. Added \A and \z anchors to ensure full-string matching. Wildcard masks (zerocracy/*) are unaffected since .* already absorbs the entire tail. Added four direct unit tests for Fbe.mask_to_regex: - test_mask_to_regex_exact_match - test_mask_to_regex_prefix_collision - test_mask_to_regex_wildcard - test_mask_to_regex_case_insensitive * fix: update off_quota assertion for search threshold
1 parent ba322fb commit c0a175d

2 files changed

Lines changed: 23 additions & 1 deletion

File tree

lib/fbe/unmask_repos.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
def Fbe.mask_to_regex(mask)
2525
org, repo = mask.split('/')
2626
raise(Fbe::Error, "Org '#{org}' can't have an asterisk") if org.include?('*')
27-
Regexp.compile("#{Regexp.escape(org)}/#{Regexp.escape(repo).gsub('\\*', '.*')}", Regexp::IGNORECASE)
27+
Regexp.compile("\\A#{Regexp.escape(org)}/#{Regexp.escape(repo).gsub('\\*', '.*')}\\z", Regexp::IGNORECASE)
2828
end
2929

3030
# Resolves repository masks to actual GitHub repository names.

test/fbe/test_unmask_repos.rb

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,28 @@ def test_mask_to_regex_still_expands_wildcard
7070
refute_match(re, 'zold-io/blogXzoldYio')
7171
end
7272

73+
def test_mask_to_regex_exact_match
74+
re = Fbe.mask_to_regex('zerocracy/judges-action')
75+
assert_match(re, 'zerocracy/judges-action')
76+
end
77+
78+
def test_mask_to_regex_prefix_collision
79+
re = Fbe.mask_to_regex('zerocracy/judges-action')
80+
refute_match(re, 'zerocracy/judges-actions')
81+
refute_match(re, 'zerocracy/judges-action-old')
82+
end
83+
84+
def test_mask_to_regex_wildcard
85+
re = Fbe.mask_to_regex('zerocracy/*')
86+
assert_match(re, 'zerocracy/fbe')
87+
assert_match(re, 'zerocracy/judges-action')
88+
end
89+
90+
def test_mask_to_regex_case_insensitive
91+
re = Fbe.mask_to_regex('Zerocracy/Fbe')
92+
assert_match(re, 'zerocracy/fbe')
93+
end
94+
7395
def test_live_usage
7496
skip('Run it only manually, since it touches GitHub API')
7597
opts = Judges::Options.new({ 'repositories' => 'zerocracy/*,-zerocracy/judges-action,zerocracy/datum' })

0 commit comments

Comments
 (0)