Commit b905702d authored by Robert Speicher's avatar Robert Speicher

Escape title attributes in references

parent a3c71d98
......@@ -109,5 +109,6 @@ module IssuesHelper
end
end
# Required for Gitlab::Markdown::IssueReferenceFilter
module_function :url_for_issue, :title_for_issue
end
module LabelsHelper
include ActionView::Helpers::TagHelper
def project_label_names
@project.labels.pluck(:title)
end
......@@ -11,7 +13,7 @@ module LabelsHelper
# by LabelReferenceFilter
span = %(<span class="label color-label") +
%( style="background-color: #{label_color}; color: #{text_color}">) +
label.name + '</span>'
escape_once(label.name) + '</span>'
span.html_safe
end
......@@ -56,5 +58,6 @@ module LabelsHelper
options_from_collection_for_select(project.labels, 'name', 'name', params[:label_name])
end
module_function :render_colored_label, :text_color_for_bg
# Required for Gitlab::Markdown::LabelReferenceFilter
module_function :render_colored_label, :text_color_for_bg, :escape_once
end
......@@ -50,7 +50,7 @@ module Gitlab
if project.valid_repo? && commit = project.repository.commit(commit_ref)
url = url_for_commit(project, commit)
title = commit.link_title
title = escape_once(commit.link_title)
klass = reference_class(:commit)
project_ref += '@' if project_ref
......
......@@ -46,7 +46,7 @@ module Gitlab
self.class.references_in(text) do |match, issue|
url = url_for_issue(issue, project, only_path: context[:only_path])
title = "Issue in #{project.external_issue_tracker.title}"
title = escape_once("Issue in #{project.external_issue_tracker.title}")
klass = reference_class(:issue)
%(<a href="#{url}"
......
......@@ -50,7 +50,7 @@ module Gitlab
if project.issue_exists?(issue)
url = url_for_issue(issue, project, only_path: context[:only_path])
title = "Issue: #{title_for_issue(issue, project)}"
title = escape_once("Issue: #{title_for_issue(issue, project)}")
klass = reference_class(:issue)
%(<a href="#{url}"
......
......@@ -52,7 +52,7 @@ module Gitlab
project = self.project_from_ref(project_ref)
if merge_request = project.merge_requests.find_by(iid: id)
title = "Merge Request: #{merge_request.title}"
title = escape_once("Merge Request: #{merge_request.title}")
klass = reference_class(:merge_request)
url = url_for_merge_request(merge_request, project)
......
require 'active_support/core_ext/string/output_safety'
require 'html/pipeline'
module Gitlab
......@@ -12,6 +13,10 @@ module Gitlab
# :only_path - Generate path-only links.
#
class ReferenceFilter < HTML::Pipeline::Filter
def escape_once(html)
ERB::Util.html_escape_once(html)
end
# Don't look for references in text nodes that are children of these
# elements.
IGNORE_PARENTS = %w(pre code a style).to_set
......
......@@ -48,7 +48,7 @@ module Gitlab
project = self.project_from_ref(project_ref)
if snippet = project.snippets.find_by(id: id)
title = "Snippet: #{snippet.title}"
title = escape_once("Snippet: #{snippet.title}")
klass = reference_class(:snippet)
url = url_for_snippet(snippet, project)
......
......@@ -51,6 +51,13 @@ module Gitlab::Markdown
expect(doc.css('a').first.attr('title')).to eq commit.link_title
end
it 'escapes the title attribute' do
allow_any_instance_of(Commit).to receive(:title).and_return(%{"></a>whatever<a title="})
doc = filter("See #{reference}")
expect(doc.text).to eq "See #{commit.id}"
end
it 'includes default classes' do
doc = filter("See #{reference}")
expect(doc.css('a').first.attr('class')).to eq 'gfm gfm-commit'
......
......@@ -80,6 +80,14 @@ module Gitlab::Markdown
expect(doc.css('a').first.attr('title')).to eq "Issue in JIRA tracker"
end
it 'escapes the title attribute' do
allow(project.external_issue_tracker).to receive(:title).
and_return(%{"></a>whatever<a title="})
doc = filter("Issue #{reference}")
expect(doc.text).to eq "Issue #{reference}"
end
it 'includes default classes' do
doc = filter("Issue #{reference}")
expect(doc.css('a').first.attr('class')).to eq 'gfm gfm-issue'
......
......@@ -57,6 +57,13 @@ module Gitlab::Markdown
expect(doc.css('a').first.attr('title')).to eq "Issue: #{issue.title}"
end
it 'escapes the title attribute' do
issue.update_attribute(:title, %{"></a>whatever<a title="})
doc = filter("Issue #{reference}")
expect(doc.text).to eq "Issue #{reference}"
end
it 'includes default classes' do
doc = filter("Issue #{reference}")
expect(doc.css('a').first.attr('class')).to eq 'gfm gfm-issue'
......
......@@ -45,6 +45,13 @@ module Gitlab::Markdown
expect(doc.css('a').first.attr('title')).to eq "Merge Request: #{merge.title}"
end
it 'escapes the title attribute' do
merge.update_attribute(:title, %{"></a>whatever<a title="})
doc = filter("Merge #{reference}")
expect(doc.text).to eq "Merge #{reference}"
end
it 'includes default classes' do
doc = filter("Merge #{reference}")
expect(doc.css('a').first.attr('class')).to eq 'gfm gfm-merge_request'
......
......@@ -44,6 +44,13 @@ module Gitlab::Markdown
expect(doc.css('a').first.attr('title')).to eq "Snippet: #{snippet.title}"
end
it 'escapes the title attribute' do
snippet.update_attribute(:title, %{"></a>whatever<a title="})
doc = filter("Snippet #{reference}")
expect(doc.text).to eq "Snippet #{reference}"
end
it 'includes default classes' do
doc = filter("Snippet #{reference}")
expect(doc.css('a').first.attr('class')).to eq 'gfm gfm-snippet'
......
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