Commit 0ace54e8 authored by Robert Speicher's avatar Robert Speicher

Merge branch 'allow-resolving-conflicts-in-utf-8' into 'master'

Allow resolving conflicts with non-ASCII chars

Closes #26214

See merge request !9937
parents 6619772f 96c77bf7
---
title: Fix conflict resolution when files contain valid UTF-8 characters
merge_request:
author:
...@@ -15,11 +15,9 @@ module Gitlab ...@@ -15,11 +15,9 @@ module Gitlab
raise UnmergeableFile if text.blank? # Typically a binary file raise UnmergeableFile if text.blank? # Typically a binary file
raise UnmergeableFile if text.length > 200.kilobytes raise UnmergeableFile if text.length > 200.kilobytes
begin text.force_encoding('UTF-8')
text.to_json
rescue Encoding::UndefinedConversionError raise UnsupportedEncoding unless text.valid_encoding?
raise UnsupportedEncoding
end
line_obj_index = 0 line_obj_index = 0
line_old = 1 line_old = 1
......
...@@ -120,44 +120,62 @@ CONFLICT ...@@ -120,44 +120,62 @@ CONFLICT
end end
context 'when the file contents include conflict delimiters' do context 'when the file contents include conflict delimiters' do
it 'raises UnexpectedDelimiter when there is a non-start delimiter first' do context 'when there is a non-start delimiter first' do
it 'raises UnexpectedDelimiter when there is a middle delimiter first' do
expect { parse_text('=======') }. expect { parse_text('=======') }.
to raise_error(Gitlab::Conflict::Parser::UnexpectedDelimiter) to raise_error(Gitlab::Conflict::Parser::UnexpectedDelimiter)
end
it 'raises UnexpectedDelimiter when there is an end delimiter first' do
expect { parse_text('>>>>>>> README.md') }. expect { parse_text('>>>>>>> README.md') }.
to raise_error(Gitlab::Conflict::Parser::UnexpectedDelimiter) to raise_error(Gitlab::Conflict::Parser::UnexpectedDelimiter)
end
it 'does not raise when there is an end delimiter for a different path first' do
expect { parse_text('>>>>>>> some-other-path.md') }. expect { parse_text('>>>>>>> some-other-path.md') }.
not_to raise_error not_to raise_error
end end
end
it 'raises UnexpectedDelimiter when a start delimiter is followed by a non-middle delimiter' do context 'when a start delimiter is followed by a non-middle delimiter' do
start_text = "<<<<<<< README.md\n" let(:start_text) { "<<<<<<< README.md\n" }
end_text = "\n=======\n>>>>>>> README.md" let(:end_text) { "\n=======\n>>>>>>> README.md" }
it 'raises UnexpectedDelimiter when it is followed by an end delimiter' do
expect { parse_text(start_text + '>>>>>>> README.md' + end_text) }. expect { parse_text(start_text + '>>>>>>> README.md' + end_text) }.
to raise_error(Gitlab::Conflict::Parser::UnexpectedDelimiter) to raise_error(Gitlab::Conflict::Parser::UnexpectedDelimiter)
end
it 'raises UnexpectedDelimiter when it is followed by another start delimiter' do
expect { parse_text(start_text + start_text + end_text) }. expect { parse_text(start_text + start_text + end_text) }.
to raise_error(Gitlab::Conflict::Parser::UnexpectedDelimiter) to raise_error(Gitlab::Conflict::Parser::UnexpectedDelimiter)
end
it 'does not raise when it is followed by a start delimiter for a different path' do
expect { parse_text(start_text + '>>>>>>> some-other-path.md' + end_text) }. expect { parse_text(start_text + '>>>>>>> some-other-path.md' + end_text) }.
not_to raise_error not_to raise_error
end end
end
it 'raises UnexpectedDelimiter when a middle delimiter is followed by a non-end delimiter' do context 'when a middle delimiter is followed by a non-end delimiter' do
start_text = "<<<<<<< README.md\n=======\n" let(:start_text) { "<<<<<<< README.md\n=======\n" }
end_text = "\n>>>>>>> README.md" let(:end_text) { "\n>>>>>>> README.md" }
it 'raises UnexpectedDelimiter when it is followed by another middle delimiter' do
expect { parse_text(start_text + '=======' + end_text) }. expect { parse_text(start_text + '=======' + end_text) }.
to raise_error(Gitlab::Conflict::Parser::UnexpectedDelimiter) to raise_error(Gitlab::Conflict::Parser::UnexpectedDelimiter)
end
it 'raises UnexpectedDelimiter when it is followed by a start delimiter' do
expect { parse_text(start_text + start_text + end_text) }. expect { parse_text(start_text + start_text + end_text) }.
to raise_error(Gitlab::Conflict::Parser::UnexpectedDelimiter) to raise_error(Gitlab::Conflict::Parser::UnexpectedDelimiter)
end
expect { parse_text(start_text + '>>>>>>> some-other-path.md' + end_text) }. it 'does not raise when it is followed by a start delimiter for another path' do
expect { parse_text(start_text + '<<<<<<< some-other-path.md' + end_text) }.
not_to raise_error not_to raise_error
end end
end
it 'raises MissingEndDelimiter when there is no end delimiter at the end' do it 'raises MissingEndDelimiter when there is no end delimiter at the end' do
start_text = "<<<<<<< README.md\n=======\n" start_text = "<<<<<<< README.md\n=======\n"
...@@ -184,10 +202,21 @@ CONFLICT ...@@ -184,10 +202,21 @@ CONFLICT
to raise_error(Gitlab::Conflict::Parser::UnmergeableFile) to raise_error(Gitlab::Conflict::Parser::UnmergeableFile)
end end
it 'raises UnsupportedEncoding when the file contains non-UTF-8 characters' do # All text from Rugged has an encoding of ASCII_8BIT, so force that in
# these strings.
context 'when the file contains UTF-8 characters' do
it 'does not raise' do
expect { parse_text("Espa\xC3\xB1a".force_encoding(Encoding::ASCII_8BIT)) }.
not_to raise_error
end
end
context 'when the file contains non-UTF-8 characters' do
it 'raises UnsupportedEncoding' do
expect { parse_text("a\xC4\xFC".force_encoding(Encoding::ASCII_8BIT)) }. expect { parse_text("a\xC4\xFC".force_encoding(Encoding::ASCII_8BIT)) }.
to raise_error(Gitlab::Conflict::Parser::UnsupportedEncoding) to raise_error(Gitlab::Conflict::Parser::UnsupportedEncoding)
end end
end end
end end
end
end end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment