summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorSean McGivern <sean@gitlab.com>2017-07-20 13:16:00 +0000
committerJames Edwards-Jones <jedwardsjones@gitlab.com>2017-07-21 13:13:07 +0100
commit83481414341b7ebb82b5a3d948b39e95fdca5289 (patch)
tree3934231c988f4171f61815d357da94ae0956f2af /lib
parent2e46a584b671f5eb06b7e9c37523d7300882d44b (diff)
downloadgitlab-ce-83481414341b7ebb82b5a3d948b39e95fdca5289.tar.gz
Merge branch 'fix-re2-infinite-loop-nick' into 'security-9-3'
Fix an infinite loop in Gitlab:UntrustedRegexp See merge request !2146
Diffstat (limited to 'lib')
-rw-r--r--lib/gitlab/untrusted_regexp.rb29
1 files changed, 22 insertions, 7 deletions
diff --git a/lib/gitlab/untrusted_regexp.rb b/lib/gitlab/untrusted_regexp.rb
index 8b43f0053d6..925b2158a22 100644
--- a/lib/gitlab/untrusted_regexp.rb
+++ b/lib/gitlab/untrusted_regexp.rb
@@ -22,13 +22,28 @@ module Gitlab
end
def scan(text)
- scan_regexp.scan(text).map do |match|
- if regexp.number_of_capturing_groups == 0
- match.first
- else
- match
- end
+ text = text.dup # modified in-place
+ results = []
+
+ loop do
+ match = scan_regexp.match(text)
+ break unless match
+
+ # Ruby scan returns empty strings, not nil
+ groups = match.to_a.map(&:to_s)
+
+ results <<
+ if regexp.number_of_capturing_groups.zero?
+ groups[0]
+ else
+ groups[1..-1]
+ end
+
+ text.slice!(0, match.end(0) || 1)
+ break unless text.present?
end
+
+ results
end
def replace(text, rewrite)
@@ -43,7 +58,7 @@ module Gitlab
# groups, so work around it
def scan_regexp
@scan_regexp ||=
- if regexp.number_of_capturing_groups == 0
+ if regexp.number_of_capturing_groups.zero?
RE2::Regexp.new('(' + regexp.source + ')')
else
regexp