Project

General

Profile

Actions

Defect #33432

open

Rendering of Macros with (empty) text parameter different in preview and non preview mode

Added by Holger Mößinger almost 4 years ago. Updated almost 4 years ago.

Status:
Confirmed
Priority:
Normal
Assignee:
-
Category:
Text formatting
Start date:
Due date:
% Done:

0%

Estimated time:
Resolution:
Affected version:

Description

Macros with empty text parameter are rendered differently in preview mode vs. non preview mode.

The preview mode seems to parse the the closing double curly brackets as text parameter and does not stop until the next macros double curly brackets, while the non preview mode parses an empty text parameter.

The sample code below shows demonstrates this with the collapse macro, but it happens for any macro which allows a text parameter and the two attached images.

This might be an issue with a greedy regular expression.

Test code for the bug in Redmine 4.x

{{collapse(Collapse 1)}}

Above is a empty collapse macro which renders correctly in preview and in wiki view.

{{collapse(Collapse 2)
}}

Above is a empty collapse macro which renders correctly in wiki view but this text (and the following macro up to its closing curly brackets) will not be visible in preview mode.

{{collapse(Collapse 3)
This is a block of text that is collapsed by default.
It can be expanded by clicking a link.
}}

Above is a non empty collapse macro which renders correctly in preview and in wiki view.

Test code for the bug in Redmine 4.x

Collapse 1

Above is a empty collapse macro which renders correctly in preview and in wiki view.

Collapse 2

Above is a empty collapse macro which renders correctly in wiki view but this text (and the following macro up to its closing curly brackets) will not be visible in preview mode.

Collapse 3

Above is a non empty collapse macro witch renders correctly in preview and in wiki view.


Environment:
Redmine version 4.1.1.stable
Ruby version 2.6.6-p146 (2020-03-31) [x86_64-linux]
Rails version 5.2.4.2
Environment production
Database adapter PostgreSQL
Mailer queue ActiveJob::QueueAdapters::AsyncAdapter
Mailer delivery smtp
SCM:
Subversion 1.10.4
Git 2.20.1
Filesystem
Xitolite 2.20.1
Redmine plugins:
additionals 2.0.24-master
redmine_advancedimage 0.0.4
redmine_agile 1.5.3
redmine_checklists 3.1.16
redmine_filelinks 0.0.0
redmine_git_hosting 4.0.2
redmine_latex_mathjax 0.4.0
redmine_lightbox2 0.5.1
redmine_local_avatars 1.0.0
redmine_mentions 1.0.0
redmine_postgresql_search 1.0.6
redmine_recurring_tasks 0.3.4
redmine_reporting 2.0.6
redmine_wiki_lists 0.0.9
redmine_wikiapproval 0.0.0
redmine_wikiforms 0.0.0
redmineup_tags 2.0.8
sidebar_hide 0.0.8-fix


Files

Redmine 4.x preview render.PNG (26.4 KB) Redmine 4.x preview render.PNG Holger Mößinger, 2020-05-11 13:50
Redmine 4.x wiki render.PNG (27.6 KB) Redmine 4.x wiki render.PNG Holger Mößinger, 2020-05-11 13:50
33432.patch (785 Bytes) 33432.patch Yuichi HARADA, 2020-05-21 04:58
33432-v2.patch (700 Bytes) 33432-v2.patch Yuichi HARADA, 2020-05-26 02:36
33432-test.patch (735 Bytes) 33432-test.patch Go MAEDA, 2020-06-06 08:31
Actions #1

Updated by Go MAEDA almost 4 years ago

  • Category changed from Wiki to Text formatting
  • Status changed from New to Confirmed
Actions #2

Updated by Yuichi HARADA almost 4 years ago

It seems that the line break code is different between preview mode and non-preview mode.
So preview mode doesn't seem to match the regular expression ApplicationHelper::MACROS_RE.

preview mode(Linebreak: "\n"). Since the input value is posted via JavaScript, the line break code is replaced from "\r\n" to "\n".

"Test code for the bug in Redmine 4.x\n\n{{collapse(Collapse 1)}}\n\nAbove is a empty collapse macro which renders correctly in preview and in wiki view.\n\n{{collapse(Collapse 2)\n}}\n\nAbove is a empty collapse macro which renders correctly in wiki view but this text (and the following macro up to its closing curly brackets) will not be visible in preview mode.\n\n{{collapse(Collapse 3)\nThis is a block of text that is collapsed by default.\nIt can be expanded by clicking a link.\n}}\n\nAbove is a non empty collapse macro which renders correctly in preview and in wiki view." 

non-preview mode(Linebreak: "\r\n")

"Test code for the bug in Redmine 4.x\r\n\r\n{{collapse(Collapse 1)}}\r\n\r\nAbove is a empty collapse macro which renders correctly in preview and in wiki view.\r\n\r\n{{collapse(Collapse 2)\r\n}}\r\n\r\nAbove is a empty collapse macro which renders correctly in wiki view but this text (and the following macro up to its closing curly brackets) will not be visible in preview mode.\r\n\r\n{{collapse(Collapse 3)\r\nThis is a block of text that is collapsed by default.\r\nIt can be expanded by clicking a link.\r\n}}\r\n\r\nAbove is a non empty collapse macro which renders correctly in preview and in wiki view." 

Fixed the regular expression. I think this will solve the problem.

diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb
index bf55e05a5..5bcdca29f 100644
--- a/app/helpers/application_helper.rb
+++ b/app/helpers/application_helper.rb
@@ -1277,8 +1277,8 @@ module ApplicationHelper
                 (
                 \{\{                        # opening tag
                 ([\w]+)                     # macro name
-                (\(([^\n\r]*?)\))?          # optional arguments
-                ([\n\r].*?[\n\r])?          # optional block of text
+                (\(([^\R]*?)\))?            # optional arguments
+                (\R.*?\R?)?                 # optional block of text
                 \}\}                        # closing tag
                 )
                )/mx unless const_defined?(:MACROS_RE)
Actions #3

Updated by Go MAEDA almost 4 years ago

Yuichi HARADA wrote:

It seems that the line break code is different between preview mode and non-preview mode.
So preview mode doesn't seem to match the regular expression ApplicationHelper::MACROS_RE.

Thank you for posting the patch. But I think the patch needs some fix.

I think the following line does not work as expected because the metacharacter \R cannot be put into []. [^\R] is actually equivalent to [^R].

                (\(([^\R]*?)\))?            # optional arguments

See the test result below.

irb(main):001:0> /[^\n\r]/ =~ "\n" 
=> nil
irb(main):002:0> /[^\R]/ =~ "\n" 
=> 0
irb(main):003:0> /[^\R]/ =~ "R" 
=> nil
Actions #4

Updated by Yuichi HARADA almost 4 years ago

Go MAEDA wrote:

I think the following line does not work as expected because the metacharacter \R cannot be put into []. [^\R] is actually equivalent to [^R].

[...]

See the test result below.

[...]

Thank you for your report.
I confirmed that the negative match /[^\R]/ doesn't work with the line break code.
Fixed the patch.

Actions #5

Updated by Go MAEDA almost 4 years ago

  • Target version set to Candidate for next minor release
Actions #6

Updated by Go MAEDA almost 4 years ago

Attaching test code for the patch.

Actions #7

Updated by Go MAEDA almost 4 years ago

  • Target version changed from Candidate for next minor release to 4.0.8
  • Affected version changed from 4.1.1 to 4.0.0

Setting the target version to 4.0.8.

Actions #8

Updated by Go MAEDA almost 4 years ago

  • Target version changed from 4.0.8 to Candidate for next minor release

The actual cause of the problem is that the regular expression expects that there are two line terminators between "macroname{{" and "}}". The reason why there appears to be no problem when a line terminator is "\r\n" is that "\r" is parsed as the first line terminator and "\n" is parsed as the second line terminator.

So, even after applying the patch 33432-v2.patch, the macro in the following text is not detected in the Preview tab.

collapse{{
}}

The code below can test it.

Index: test/helpers/application_helper_test.rb
===================================================================
--- test/helpers/application_helper_test.rb    (リビジョン 19814)
+++ test/helpers/application_helper_test.rb    (作業コピー)
@@ -1937,6 +1937,13 @@
     end
   end

+  def test_catch_macros_should_allow_empty_text_block
+    macros = catch_macros(+"{{collapse\r\n}}")
+    assert_equal "{{collapse\r\n}}", macros[0]
+    macros = catch_macros(+"{{collapse\n}}")
+    assert_equal "{{collapse\n}}", macros[0]
+  end
+
   private

   def wiki_links_with_special_characters
Actions

Also available in: Atom PDF