summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLin Jen-Shin <godfat@godfat.org>2017-04-18 17:03:02 +0800
committerLin Jen-Shin <godfat@godfat.org>2017-04-18 17:03:02 +0800
commit7c1abc2cabb20e286ca40be2e3071bb95886bf25 (patch)
tree54e3ee598eedf08e8dd4d82854612c38e91f6fe6
parentec9f6180bc4684521444ee0681308bf4c9c71297 (diff)
downloadgitlab-ce-use-buffer-for-ansi2html.tar.gz
Use a buffer for Ansi2html so it's not affecting Streamuse-buffer-for-ansi2html
Fixes https://sentry.gitlap.com/gitlab/gitlabcom/issues/27545/
-rw-r--r--lib/gitlab/ci/trace/stream.rb34
-rw-r--r--spec/lib/gitlab/ci/trace/stream_spec.rb17
2 files changed, 39 insertions, 12 deletions
diff --git a/lib/gitlab/ci/trace/stream.rb b/lib/gitlab/ci/trace/stream.rb
index b929bdd55bc..8fa2b18329e 100644
--- a/lib/gitlab/ci/trace/stream.rb
+++ b/lib/gitlab/ci/trace/stream.rb
@@ -14,14 +14,7 @@ module Gitlab
def initialize
@stream = yield
- if @stream
- @stream.binmode
- # Ci::Ansi2html::Converter would read from @stream directly,
- # using @stream.each_line to be specific. It's safe to set
- # the encoding here because IO#seek(bytes) and IO#read(bytes)
- # are not characters based, so encoding doesn't matter to them.
- @stream.set_encoding(Encoding.default_external)
- end
+ @stream.binmode if @stream
end
def valid?
@@ -63,13 +56,14 @@ module Gitlab
end
def html_with_state(state = nil)
- ::Ci::Ansi2html.convert(stream, state)
+ buffer = create_stream_for_ansi2html(stream) if stream
+ ::Ci::Ansi2html.convert(buffer, state)
end
def html(last_lines: nil)
text = raw(last_lines: last_lines)
- stream = StringIO.new(text)
- ::Ci::Ansi2html.convert(stream).html
+ buffer = create_stream_for_ansi2html(text)
+ ::Ci::Ansi2html.convert(buffer).html
end
def extract_coverage(regex)
@@ -122,6 +116,24 @@ module Gitlab
chunks.join.lines.last(last_lines).join
end
+
+ def create_stream_for_ansi2html(io_or_string)
+ buffer = StringIO.new
+
+ case io_or_string
+ when IO, StringIO
+ IO.copy_stream(io_or_string, buffer)
+ when String
+ buffer.string = io_or_string
+ else
+ raise TypeError,
+ "should be an IO or String, but got: #{io_or_string.class}"
+ end
+
+ buffer.set_encoding(Encoding.default_external)
+ buffer.rewind
+ buffer
+ end
end
end
end
diff --git a/spec/lib/gitlab/ci/trace/stream_spec.rb b/spec/lib/gitlab/ci/trace/stream_spec.rb
index 03f040f4465..2bd2aab829e 100644
--- a/spec/lib/gitlab/ci/trace/stream_spec.rb
+++ b/spec/lib/gitlab/ci/trace/stream_spec.rb
@@ -71,9 +71,13 @@ describe Gitlab::Ci::Trace::Stream do
end
describe '#append' do
+ let(:tempfile) { Tempfile.new }
+
let(:stream) do
described_class.new do
- StringIO.new("12345678")
+ tempfile.write("12345678")
+ tempfile.rewind
+ tempfile
end
end
@@ -84,6 +88,17 @@ describe Gitlab::Ci::Trace::Stream do
expect(stream.size).to eq(6)
expect(stream.raw).to eq("123489")
end
+
+ it 'appends in binary mode' do
+ '😺'.force_encoding('ASCII-8BIT').each_char.with_index do |byte, offset|
+ stream.append(byte, offset)
+ end
+
+ stream.seek(0)
+
+ expect(stream.size).to eq(4)
+ expect(stream.raw).to eq('😺')
+ end
end
describe '#set' do