From 270b6c4d7eef3fcc38657ad411553da47a2e958b Mon Sep 17 00:00:00 2001 From: Jean-Philippe Lang Date: Sun, 17 Jun 2018 05:45:17 +0000 Subject: [PATCH] User link syntax (user:login) doesn't work for logins consisting of an email adress (#26443). Patch by Marius BALTEANU. git-svn-id: http://svn.redmine.org/redmine/trunk@17392 e93f8b46-1217-0410-a6f0-8f06a7374b81 --- lib/redmine/wiki_formatting.rb | 23 +++++++++- .../wiki_formatting/markdown/formatter.rb | 16 ++----- .../wiki_formatting/textile/formatter.rb | 3 +- test/helpers/application_helper_test.rb | 43 ++++++++++++++++--- 4 files changed, 66 insertions(+), 19 deletions(-) diff --git a/lib/redmine/wiki_formatting.rb b/lib/redmine/wiki_formatting.rb index bb9089218..9a2de5cff 100644 --- a/lib/redmine/wiki_formatting.rb +++ b/lib/redmine/wiki_formatting.rb @@ -153,7 +153,7 @@ module Redmine # Destructively replaces email addresses into clickable links def auto_mailto!(text) - text.gsub!(/((?]*>(.*)(#{Regexp.escape(mail)})(.*)<\/a>/) mail @@ -162,6 +162,26 @@ module Redmine end end end + + def restore_redmine_links(html) + # restore wiki links eg. [[Foo]] + html.gsub!(%r{\[(.*?)\]}) do + "[[#{$2}]]" + end + # restore Redmine links with double-quotes, eg. version:"1.0" + html.gsub!(/(\w):"(.+?)"/) do + "#{$1}:\"#{$2}\"" + end + # restore user links with @ in login name eg. [@jsmith@somenet.foo] + html.gsub!(%r{[@\A](.*?)}) do + "@#{$2}" + end + # restore user links with @ in login name eg. [user:jsmith@somenet.foo] + html.gsub!(%r{\buser:(.*?)<\/a>}) do + "user:#{$2}" + end + html + end end # Default formatter module @@ -180,6 +200,7 @@ module Redmine t = CGI::escapeHTML(@text) auto_link!(t) auto_mailto!(t) + restore_redmine_links(t) simple_format(t, {}, :sanitize => false) end end diff --git a/lib/redmine/wiki_formatting/markdown/formatter.rb b/lib/redmine/wiki_formatting/markdown/formatter.rb index b5ee2c941..4bfd00c79 100644 --- a/lib/redmine/wiki_formatting/markdown/formatter.rb +++ b/lib/redmine/wiki_formatting/markdown/formatter.rb @@ -52,24 +52,16 @@ module Redmine end class Formatter + include Redmine::WikiFormatting::LinksHelper + alias :inline_restore_redmine_links :restore_redmine_links + def initialize(text) @text = text end def to_html(*args) html = formatter.render(@text) - # restore wiki links eg. [[Foo]] - html.gsub!(%r{\[(.*?)\]}) do - "[[#{$2}]]" - end - # restore Redmine links with double-quotes, eg. version:"1.0" - html.gsub!(/(\w):"(.+?)"/) do - "#{$1}:\"#{$2}\"" - end - # restore user links with @ in login name eg. [@jsmith@somenet.foo] - html.gsub!(%r{[@\A](.*?)}) do - "@#{$2}" - end + html = inline_restore_redmine_links(html) html end diff --git a/lib/redmine/wiki_formatting/textile/formatter.rb b/lib/redmine/wiki_formatting/textile/formatter.rb index 6e7f28e62..b0b65bbbc 100644 --- a/lib/redmine/wiki_formatting/textile/formatter.rb +++ b/lib/redmine/wiki_formatting/textile/formatter.rb @@ -27,9 +27,10 @@ module Redmine alias :inline_auto_link :auto_link! alias :inline_auto_mailto :auto_mailto! + alias :inline_restore_redmine_links :restore_redmine_links # auto_link rule after textile rules so that it doesn't break !image_url! tags - RULES = [:textile, :block_markdown_rule, :inline_auto_link, :inline_auto_mailto] + RULES = [:textile, :block_markdown_rule, :inline_auto_link, :inline_auto_mailto, :inline_restore_redmine_links] def initialize(*args) super diff --git a/test/helpers/application_helper_test.rb b/test/helpers/application_helper_test.rb index bd8debcea..437b80018 100644 --- a/test/helpers/application_helper_test.rb +++ b/test/helpers/application_helper_test.rb @@ -282,6 +282,11 @@ RAW end def test_redmine_links + user_with_email_login = User.generate!(:login => 'abcd@example.com') + user_with_email_login_2 = User.generate!(:login => 'foo.bar@example.com') + u_email_id = user_with_email_login.id + u_email_id_2 = user_with_email_login_2.id + issue_link = link_to('#3', {:controller => 'issues', :action => 'show', :id => 3}, :class => Issue.find(3).css_classes, :title => 'Bug: Error 281 when updating a recipe (New)') note_link = link_to('#3-14', {:controller => 'issues', :action => 'show', :id => 3, :anchor => 'note-14'}, @@ -388,6 +393,10 @@ RAW 'user:jsmith' => link_to_user(User.find_by_id(2)), 'user#2' => link_to_user(User.find_by_id(2)), '@jsmith' => link_to_user(User.find_by_id(2)), + '@abcd@example.com' => link_to_user(User.find_by_id(u_email_id)), + 'user:abcd@example.com' => link_to_user(User.find_by_id(u_email_id)), + '@foo.bar@example.com' => link_to_user(User.find_by_id(u_email_id_2)), + 'user:foo.bar@example.com' => link_to_user(User.find_by_id(u_email_id_2)), # invalid user 'user:foobar' => 'user:foobar', } @@ -395,12 +404,36 @@ RAW to_test.each { |text, result| assert_equal "

#{result}

", textilizable(text), "#{text} failed" } end - def test_user_links_with_email_as_login_name_should_not_be_parsed - u = User.generate!(:login => 'jsmith@somenet.foo') - raw = "@jsmith@somenet.foo should not be parsed in jsmith@somenet.foo" + def test_user_links_with_email_as_login_name_should_not_be_parsed_textile + with_settings :text_formatting => 'textile' do + u = User.generate!(:login => 'jsmith@somenet.foo') - assert_match %r{

#{u.name} should not be parsed in

}, - textilizable(raw, :project => Project.find(1)) + # user link format: @jsmith@somenet.foo + raw = "@jsmith@somenet.foo should not be parsed in jsmith@somenet.foo" + assert_match %r{

#{u.name} should not be parsed in

}, + textilizable(raw, :project => Project.find(1)) + + # user link format: user:jsmith@somenet.foo + raw = "user:jsmith@somenet.foo should not be parsed in jsmith@somenet.foo" + assert_match %r{

#{u.name} should not be parsed in

}, + textilizable(raw, :project => Project.find(1)) + end + end + + def test_user_links_with_email_as_login_name_should_not_be_parsed_markdown + with_settings :text_formatting => 'markdown' do + u = User.generate!(:login => 'jsmith@somenet.foo') + + # user link format: @jsmith@somenet.foo + raw = "@jsmith@somenet.foo should not be parsed in jsmith@somenet.foo" + assert_match %r{

#{u.name} should not be parsed in jsmith@somenet.foo

}, + textilizable(raw, :project => Project.find(1)) + + # user link format: user:jsmith@somenet.foo + raw = "user:jsmith@somenet.foo should not be parsed in jsmith@somenet.foo" + assert_match %r{

#{u.name} should not be parsed in jsmith@somenet.foo

}, + textilizable(raw, :project => Project.find(1)) + end end def test_should_not_parse_redmine_links_inside_link