Skip to content
Snippets Groups Projects
Commit a010db5d authored by Douwe Maan's avatar Douwe Maan
Browse files

Properly handle HTML entities with inline diffs

parent 88bd1385
No related branches found
No related tags found
No related merge requests found
Loading
Loading
@@ -16,15 +16,12 @@ module Gitlab
old_line = @lines[old_index]
new_line = @lines[new_index]
 
suffixless_old_line = old_line[1..-1]
suffixless_new_line = new_line[1..-1]
# Skip inline diff if empty line was replaced with content
next if suffixless_old_line == ""
next if old_line[1..-1] == ""
 
# Add one, because this is based on the suffixless version
lcp = longest_common_prefix(suffixless_old_line, suffixless_new_line) + 1
lcs = longest_common_suffix(suffixless_old_line, suffixless_new_line)
# Add one, because this is based on the prefixless version
lcp = longest_common_prefix(old_line[1..-1], new_line[1..-1]) + 1
lcs = longest_common_suffix(old_line[lcp..-1], new_line[lcp..-1])
 
old_diff_range = lcp..(old_line.length - lcs - 1)
new_diff_range = lcp..(new_line.length - lcs - 1)
Loading
Loading
Loading
Loading
@@ -12,7 +12,7 @@ module Gitlab
offset = 0
line_inline_diffs.each do |inline_diff_range|
# Map the inline-diff range based on the raw line to character positions in the rich line
inline_diff_positions = position_mapping[inline_diff_range]
inline_diff_positions = position_mapping[inline_diff_range].flatten
# Turn the array of character positions into ranges
marker_ranges = collapse_ranges(inline_diff_positions)
 
Loading
Loading
@@ -47,7 +47,19 @@ module Gitlab
rich_char = rich_line[rich_pos]
end
 
mapping[raw_pos] = rich_pos
# multi-char HTML entities in the rich line correspond to a single character in the raw line
if rich_char == '&'
multichar_mapping = [rich_pos]
until rich_char == ';'
rich_pos += 1
multichar_mapping << rich_pos
rich_char = rich_line[rich_pos]
end
mapping[raw_pos] = multichar_mapping
else
mapping[raw_pos] = rich_pos
end
 
rich_pos += 1
end
Loading
Loading
Loading
Loading
@@ -14,7 +14,7 @@ module Gitlab
@lines.each do |line|
next if filename?(line)
 
full_line = html_escape(line.gsub(/\n/, ''))
full_line = line.gsub(/\n/, '')
 
if line.match(/^@@ -/)
type = "match"
Loading
Loading
@@ -67,11 +67,6 @@ module Gitlab
nil
end
end
def html_escape(str)
replacements = { '&' => '&amp;', '>' => '&gt;', '<' => '&lt;', '"' => '&quot;', "'" => '&#39;' }
str.gsub(/[&"'><]/, replacements)
end
end
end
end
Loading
Loading
@@ -2,14 +2,14 @@ require 'spec_helper'
 
describe Gitlab::Diff::InlineDiffMarker, lib: true do
describe '#inline_diffs' do
let(:raw) { "abc def" }
let(:rich) { %{<span class="abc">abc</span><span class="space"> </span><span class="def">def</span>} }
let(:inline_diffs) { [2..4] }
let(:raw) { "abc 'def'" }
let(:rich) { %{<span class="abc">abc</span><span class="space"> </span><span class="def">&#39;def&#39;</span>} }
let(:inline_diffs) { [2..5] }
 
let(:subject) { Gitlab::Diff::InlineDiffMarker.new(raw, rich).mark(inline_diffs) }
 
it 'marks the inline diffs' do
expect(subject).to eq(%{<span class="abc">ab<span class='idiff'>c</span></span><span class="space"><span class='idiff'> </span></span><span class="def"><span class='idiff'>d</span>ef</span>})
expect(subject).to eq(%{<span class="abc">ab<span class='idiff'>c</span></span><span class="space"><span class='idiff'> </span></span><span class="def"><span class='idiff'>&#39;d</span>ef&#39;</span>})
end
end
end
Loading
Loading
@@ -86,7 +86,7 @@ eos
it { expect(line.type).to eq(nil) }
it { expect(line.old_pos).to eq(24) }
it { expect(line.new_pos).to eq(31) }
it { expect(line.text).to eq(' @cmd_output &lt;&lt; stderr.read') }
it { expect(line.text).to eq(' @cmd_output << stderr.read') }
end
end
end
Loading
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment