Commit 2bc78739a7aa9d7e5109281fc45dbd41a1a576d4
1 parent
16b54178
Exists in
master
and in
4 other branches
Fix parsing of ref-like Urls in links and images in GFM
Fixes #2166
Showing
3 changed files
with
36 additions
and
7 deletions
Show diff stats
lib/gitlab/markdown.rb
| @@ -45,12 +45,11 @@ module Gitlab | @@ -45,12 +45,11 @@ module Gitlab | ||
| 45 | 45 | ||
| 46 | # Extract pre blocks so they are not altered | 46 | # Extract pre blocks so they are not altered |
| 47 | # from http://github.github.com/github-flavored-markdown/ | 47 | # from http://github.github.com/github-flavored-markdown/ |
| 48 | - extractions = {} | ||
| 49 | - text.gsub!(%r{<pre>.*?</pre>|<code>.*?</code>}m) do |match| | ||
| 50 | - md5 = Digest::MD5.hexdigest(match) | ||
| 51 | - extractions[md5] = match | ||
| 52 | - "{gfm-extraction-#{md5}}" | ||
| 53 | - end | 48 | + text.gsub!(%r{<pre>.*?</pre>|<code>.*?</code>}m) { |match| extract_piece(match) } |
| 49 | + # Extract links with probably parsable hrefs | ||
| 50 | + text.gsub!(%r{<a.*?>.*?</a>}m) { |match| extract_piece(match) } | ||
| 51 | + # Extract images with probably parsable src | ||
| 52 | + text.gsub!(%r{<img.*?>}m) { |match| extract_piece(match) } | ||
| 54 | 53 | ||
| 55 | # TODO: add popups with additional information | 54 | # TODO: add popups with additional information |
| 56 | 55 | ||
| @@ -58,7 +57,7 @@ module Gitlab | @@ -58,7 +57,7 @@ module Gitlab | ||
| 58 | 57 | ||
| 59 | # Insert pre block extractions | 58 | # Insert pre block extractions |
| 60 | text.gsub!(/\{gfm-extraction-(\h{32})\}/) do | 59 | text.gsub!(/\{gfm-extraction-(\h{32})\}/) do |
| 61 | - extractions[$1] | 60 | + insert_piece($1) |
| 62 | end | 61 | end |
| 63 | 62 | ||
| 64 | sanitize text.html_safe, attributes: ActionView::Base.sanitized_allowed_attributes + %w(id class) | 63 | sanitize text.html_safe, attributes: ActionView::Base.sanitized_allowed_attributes + %w(id class) |
| @@ -66,6 +65,18 @@ module Gitlab | @@ -66,6 +65,18 @@ module Gitlab | ||
| 66 | 65 | ||
| 67 | private | 66 | private |
| 68 | 67 | ||
| 68 | + def extract_piece(text) | ||
| 69 | + @extractions ||= {} | ||
| 70 | + | ||
| 71 | + md5 = Digest::MD5.hexdigest(text) | ||
| 72 | + @extractions[md5] = text | ||
| 73 | + "{gfm-extraction-#{md5}}" | ||
| 74 | + end | ||
| 75 | + | ||
| 76 | + def insert_piece(id) | ||
| 77 | + @extractions[id] | ||
| 78 | + end | ||
| 79 | + | ||
| 69 | # Private: Parses text for references and emoji | 80 | # Private: Parses text for references and emoji |
| 70 | # | 81 | # |
| 71 | # text - Text to parse | 82 | # text - Text to parse |
lib/redcarpet/render/gitlab_html.rb
| @@ -27,6 +27,10 @@ class Redcarpet::Render::GitlabHTML < Redcarpet::Render::HTML | @@ -27,6 +27,10 @@ class Redcarpet::Render::GitlabHTML < Redcarpet::Render::HTML | ||
| 27 | HTML | 27 | HTML |
| 28 | end | 28 | end |
| 29 | 29 | ||
| 30 | + def link(link, title, content) | ||
| 31 | + h.link_to_gfm(content, link, title: title) | ||
| 32 | + end | ||
| 33 | + | ||
| 30 | def postprocess(full_document) | 34 | def postprocess(full_document) |
| 31 | h.gfm(full_document) | 35 | h.gfm(full_document) |
| 32 | end | 36 | end |
spec/helpers/gitlab_markdown_helper_spec.rb
| 1 | require "spec_helper" | 1 | require "spec_helper" |
| 2 | 2 | ||
| 3 | describe GitlabMarkdownHelper do | 3 | describe GitlabMarkdownHelper do |
| 4 | + include ApplicationHelper | ||
| 5 | + | ||
| 4 | let!(:project) { create(:project) } | 6 | let!(:project) { create(:project) } |
| 5 | 7 | ||
| 6 | let(:user) { create(:user, username: 'gfm') } | 8 | let(:user) { create(:user, username: 'gfm') } |
| @@ -340,6 +342,18 @@ describe GitlabMarkdownHelper do | @@ -340,6 +342,18 @@ describe GitlabMarkdownHelper do | ||
| 340 | markdown("\nDon't use `$#{snippet.id}` here.\n").should == "<p>Don't use <code>$#{snippet.id}</code> here.</p>\n" | 342 | markdown("\nDon't use `$#{snippet.id}` here.\n").should == "<p>Don't use <code>$#{snippet.id}</code> here.</p>\n" |
| 341 | end | 343 | end |
| 342 | 344 | ||
| 345 | + it "should leave ref-like autolinks untouched" do | ||
| 346 | + markdown("look at http://example.tld/#!#{merge_request.id}").should == "<p>look at <a href=\"http://example.tld/#!#{merge_request.id}\">http://example.tld/#!#{merge_request.id}</a></p>\n" | ||
| 347 | + end | ||
| 348 | + | ||
| 349 | + it "should leave ref-like href of 'manual' links untouched" do | ||
| 350 | + markdown("why not [inspect !#{merge_request.id}](http://example.tld/#!#{merge_request.id})").should == "<p>why not <a href=\"http://example.tld/#!#{merge_request.id}\">inspect </a><a href=\"http://test.host/project60/merge_requests/#{merge_request.id}\" class=\"gfm gfm-merge_request \" title=\"Merge Request: #{merge_request.title}\">!#{merge_request.id}</a><a href=\"http://example.tld/#!#{merge_request.id}\"></a></p>\n" | ||
| 351 | + end | ||
| 352 | + | ||
| 353 | + it "should leave ref-like src of images untouched" do | ||
| 354 | + markdown("screen shot: ").should == "<p>screen shot: <img src=\"http://example.tld/#!#{merge_request.id}\" alt=\"some image\"></p>\n" | ||
| 355 | + end | ||
| 356 | + | ||
| 343 | it "should generate absolute urls for refs" do | 357 | it "should generate absolute urls for refs" do |
| 344 | markdown("##{issue.id}").should include(project_issue_url(project, issue)) | 358 | markdown("##{issue.id}").should include(project_issue_url(project, issue)) |
| 345 | end | 359 | end |