diff options
-rw-r--r-- | Gemfile | 2 | ||||
-rw-r--r-- | Gemfile.lock | 4 | ||||
-rw-r--r-- | lib/gitlab/untrusted_regexp.rb | 30 | ||||
-rw-r--r-- | spec/lib/gitlab/ci/trace/stream_spec.rb | 14 | ||||
-rw-r--r-- | spec/lib/gitlab/untrusted_regexp_spec.rb | 8 |
5 files changed, 24 insertions, 34 deletions
@@ -164,7 +164,7 @@ gem 'rainbow', '~> 2.2' gem 'settingslogic', '~> 2.0.9' # Linear-time regex library for untrusted regular expressions -gem 're2', '~> 1.0.0' +gem 're2', '~> 1.1.0' # Misc diff --git a/Gemfile.lock b/Gemfile.lock index b0b437ae342..f8aaba57998 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -656,7 +656,7 @@ GEM debugger-ruby_core_source (~> 1.3) rdoc (4.2.2) json (~> 1.4) - re2 (1.0.0) + re2 (1.1.0) recaptcha (3.0.0) json recursive-open-struct (1.0.0) @@ -1055,7 +1055,7 @@ DEPENDENCIES raindrops (~> 0.18) rblineprof (~> 0.3.6) rdoc (~> 4.2) - re2 (~> 1.0.0) + re2 (~> 1.1.0) recaptcha (~> 3.0) redcarpet (~> 3.4) redis (~> 3.2) diff --git a/lib/gitlab/untrusted_regexp.rb b/lib/gitlab/untrusted_regexp.rb index 187a9e1145f..7ce2e9d636e 100644 --- a/lib/gitlab/untrusted_regexp.rb +++ b/lib/gitlab/untrusted_regexp.rb @@ -22,33 +22,9 @@ module Gitlab end def scan(text) - 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 - - matchsize = match.end(0) - - # No further matches - break unless matchsize.present? - - text.slice!(0, matchsize) - break unless text.present? - end - - results + matches = scan_regexp.scan(text).to_a + matches.map!(&:first) if regexp.number_of_capturing_groups.zero? + matches end def replace(text, rewrite) diff --git a/spec/lib/gitlab/ci/trace/stream_spec.rb b/spec/lib/gitlab/ci/trace/stream_spec.rb index 8b925fd4e22..ebe5af56160 100644 --- a/spec/lib/gitlab/ci/trace/stream_spec.rb +++ b/spec/lib/gitlab/ci/trace/stream_spec.rb @@ -308,6 +308,20 @@ describe Gitlab::Ci::Trace::Stream do it { is_expected.to eq('65') } end + context 'long line' do + let(:data) { 'a' * 80000 + '100%' + 'a' * 80000 } + let(:regex) { '\d+\%' } + + it { is_expected.to eq('100') } + end + + context 'many lines' do + let(:data) { "foo\n" * 80000 + "100%\n" + "foo\n" * 80000 } + let(:regex) { '\d+\%' } + + it { is_expected.to eq('100') } + end + context 'empty regex' do let(:data) { 'foo' } let(:regex) { '' } diff --git a/spec/lib/gitlab/untrusted_regexp_spec.rb b/spec/lib/gitlab/untrusted_regexp_spec.rb index 21d47b7897a..bed58d407ef 100644 --- a/spec/lib/gitlab/untrusted_regexp_spec.rb +++ b/spec/lib/gitlab/untrusted_regexp_spec.rb @@ -54,8 +54,8 @@ describe Gitlab::UntrustedRegexp do let(:regexp) { '' } let(:text) { 'foo' } - it 'returns an array of empty matches' do - is_expected.to eq(['']) + it 'returns an array of nil matches' do + is_expected.to eq([nil, nil, nil, nil]) end end @@ -63,8 +63,8 @@ describe Gitlab::UntrustedRegexp do let(:regexp) { '()' } let(:text) { 'foo' } - it 'returns an array of empty matches in an array' do - is_expected.to eq([['']]) + it 'returns an array of nil matches in an array' do + is_expected.to eq([[nil], [nil], [nil], [nil]]) end end |