From 4bda5b502de35b7032f8c49a340325aeeb0d7ebe Mon Sep 17 00:00:00 2001
From: Nick Thomas <nick@gitlab.com>
Date: Fri, 21 Jul 2017 13:04:18 +0100
Subject: [PATCH] Short-circuit build coverage extraction for empty regexes

---
 lib/gitlab/ci/trace/stream.rb            |  2 +-
 lib/gitlab/untrusted_regexp.rb           |  7 ++++++-
 spec/lib/gitlab/ci/trace/stream_spec.rb  | 22 ++++++++++++++++++++++
 spec/lib/gitlab/untrusted_regexp_spec.rb |  6 +++---
 4 files changed, 32 insertions(+), 5 deletions(-)

diff --git a/lib/gitlab/ci/trace/stream.rb b/lib/gitlab/ci/trace/stream.rb
index aaba034474c..8503ecf8700 100644
--- a/lib/gitlab/ci/trace/stream.rb
+++ b/lib/gitlab/ci/trace/stream.rb
@@ -67,7 +67,7 @@ module Gitlab
 
         def extract_coverage(regex)
           return unless valid?
-          return unless regex
+          return unless regex.present?
 
           regex = Gitlab::UntrustedRegexp.new(regex)
 
diff --git a/lib/gitlab/untrusted_regexp.rb b/lib/gitlab/untrusted_regexp.rb
index 925b2158a22..187a9e1145f 100644
--- a/lib/gitlab/untrusted_regexp.rb
+++ b/lib/gitlab/untrusted_regexp.rb
@@ -39,7 +39,12 @@ module Gitlab
             groups[1..-1]
           end
 
-        text.slice!(0, match.end(0) || 1)
+        matchsize = match.end(0)
+
+        # No further matches
+        break unless matchsize.present?
+
+        text.slice!(0, matchsize)
         break unless text.present?
       end
 
diff --git a/spec/lib/gitlab/ci/trace/stream_spec.rb b/spec/lib/gitlab/ci/trace/stream_spec.rb
index 3a132fb9989..8b925fd4e22 100644
--- a/spec/lib/gitlab/ci/trace/stream_spec.rb
+++ b/spec/lib/gitlab/ci/trace/stream_spec.rb
@@ -307,5 +307,27 @@ describe Gitlab::Ci::Trace::Stream do
 
       it { is_expected.to eq('65') }
     end
+
+    context 'empty regex' do
+      let(:data) { 'foo' }
+      let(:regex) { '' }
+
+      it 'skips processing' do
+        expect(stream).not_to receive(:read)
+
+        is_expected.to be_nil
+      end
+    end
+
+    context 'nil regex' do
+      let(:data) { 'foo' }
+      let(:regex) { nil }
+
+      it 'skips processing' do
+        expect(stream).not_to receive(:read)
+
+        is_expected.to be_nil
+      end
+    end
   end
 end
diff --git a/spec/lib/gitlab/untrusted_regexp_spec.rb b/spec/lib/gitlab/untrusted_regexp_spec.rb
index a2ef2a27e4c..21d47b7897a 100644
--- a/spec/lib/gitlab/untrusted_regexp_spec.rb
+++ b/spec/lib/gitlab/untrusted_regexp_spec.rb
@@ -55,7 +55,7 @@ describe Gitlab::UntrustedRegexp do
       let(:text) { 'foo' }
 
       it 'returns an array of empty matches' do
-        is_expected.to eq(['', '', ''])
+        is_expected.to eq([''])
       end
     end
 
@@ -63,8 +63,8 @@ describe Gitlab::UntrustedRegexp do
       let(:regexp) { '()' }
       let(:text) { 'foo' }
 
-      it 'returns arrays of empty matches in an array' do
-        is_expected.to eq([[''], [''], ['']])
+      it 'returns an array of empty matches in an array' do
+        is_expected.to eq([['']])
       end
     end
 
-- 
2.30.9