Project

General

Profile

Actions

Defect #40193

closed

Performance issue with email address auto-linking in the default ("none") formatter

Added by Vincent Robert 3 months ago. Updated 3 months ago.

Status:
Closed
Priority:
Normal
Assignee:
Category:
Text formatting
Target version:
Start date:
Due date:
% Done:

0%

Estimated time:
Resolution:
Fixed
Affected version:

Description

We recently encountered a significant issue where a user created issues with very lengthy descriptions, including email addresses at the end. This scenario exposed a performance concern in the auto_mailto! method, leading to potential server overload and unavailable application.

The issue stems from the fact that the regular expression used in the auto_mailto! method is relatively slow when applied to large text, posing challenges for improvement.

Attached is a test case that replicates the problem, highlighting that text formatting is swift on extensive input without email addresses, but significantly slows down when the auto_mailto! method is involved.

To address this issue in our production environment, we've temporarily implemented a patch. While it may not be the most elegant piece of code, it effectively mitigates the problem we encountered. This solution prevents server timeouts when users attempt to render the affected issues:

diff --git a/lib/redmine/wiki_formatting.rb b/lib/redmine/wiki_formatting.rb
index 6bd4d4c3f..be084f43c 100644
--- a/lib/redmine/wiki_formatting.rb
+++ b/lib/redmine/wiki_formatting.rb
@@ -159,6 +159,7 @@ module Redmine

       # Destructively replaces email addresses into clickable links
       def auto_mailto!(text)
+        return text if text.length > 10000
         text.gsub!(/([\w\.!#\$%\-+.\/]+@[A-Za-z0-9\-]+(\.[A-Za-z0-9\-]+)+)/) do
           mail = $1
           if /<a\b[^>]*>(.*)(#{Regexp.escape(mail)})(.*)<\/a>/.match?(text)

Files

wiki_formatting_test.diff (20.5 KB) wiki_formatting_test.diff Vincent Robert, 2024-02-05 16:11
40193.patch (847 Bytes) 40193.patch Go MAEDA, 2024-02-06 09:35
Actions #1

Updated by Vincent Robert 3 months ago

  • Affected version set to 5.1.1
Actions #2

Updated by Go MAEDA 3 months ago

  • Status changed from New to Confirmed
  • Target version set to Candidate for next minor release

I have confirmed the issue is reproducible with Ruby 3.0 and 3.1 but the test does not fail with Ruby 3.2 or later. Maybe this is because the performance of Regexp was improved in Ruby 3.2 (see https://www.ruby-lang.org/en/news/2022/12/25/ruby-3-2-0-released/).

I found the issue can be fixed by limiting the maximum length of an email address. In the change below, the maximum length of the local part of an e-mail address to 64 characters, the domain part between the "@" and the first dot to 255 characters, and the remaining domain part to 255 characters.

I think the limitations are big enough because RFC3696 Section 3 says that the maximum length of the local part is 64 characters and the maximum length of the domain part is 255 characters.

diff --git a/lib/redmine/wiki_formatting/links_helper.rb b/lib/redmine/wiki_formatting/links_helper.rb
index 4595428a4..08a2c43c5 100644
--- a/lib/redmine/wiki_formatting/links_helper.rb
+++ b/lib/redmine/wiki_formatting/links_helper.rb
@@ -65,7 +65,7 @@ module Redmine

       # Destructively replaces email addresses into clickable links
       def auto_mailto!(text)
-        text.gsub!(/([\w\.!#\$%\-+.\/]+@[A-Za-z0-9\-]+(\.[A-Za-z0-9\-]+)+)/) do
+        text.gsub!(/([\w\.!#\$%\-+.\/]{1,64}@[A-Za-z0-9\-]{1,255}(\.[A-Za-z0-9\-]{1,255})+)/) do
           mail = $1
           if /<a\b[^>]*>(.*)(#{Regexp.escape(mail)})(.*)<\/a>/.match?(text)
             mail
Actions #3

Updated by Go MAEDA 3 months ago

According to RFC1034 Section 3.1, the maximum length of each label in a domain name is 63 characters. I have updated the patch.

diff --git a/lib/redmine/wiki_formatting/links_helper.rb b/lib/redmine/wiki_formatting/links_helper.rb
index 4595428a4..08a2c43c5 100644
--- a/lib/redmine/wiki_formatting/links_helper.rb
+++ b/lib/redmine/wiki_formatting/links_helper.rb
@@ -65,7 +65,7 @@ module Redmine

       # Destructively replaces email addresses into clickable links
       def auto_mailto!(text)
-        text.gsub!(/([\w\.!#\$%\-+.\/]+@[A-Za-z0-9\-]+(\.[A-Za-z0-9\-]+)+)/) do
+        text.gsub!(/([\w\.!#\$%\-+.\/]{1,64}@[A-Za-z0-9\-]{1,63}(\.[A-Za-z0-9\-]{1,63})+)/) do
           mail = $1
           if /<a\b[^>]*>(.*)(#{Regexp.escape(mail)})(.*)<\/a>/.match?(text)
             mail
Actions #4

Updated by Vincent Robert 3 months ago

I have just tested the latest patch. It works great. No more performance issues.

Actions #5

Updated by Go MAEDA 3 months ago

  • File 40193.patch 40193.patch added
  • Subject changed from Performance issue when formatting text containing email addresses to Performance issue with email address auto-linking in the default ("none") formatter
  • Category changed from Performance to Text formatting
  • Target version changed from Candidate for next minor release to 5.0.8

Setting the target version to 5.0.8.

Actions #6

Updated by Go MAEDA 3 months ago

  • Status changed from Confirmed to Resolved
  • Assignee set to Go MAEDA
  • Resolution set to Fixed

Committed the patch in r22684. Thank you for reporting the issue.

Actions #7

Updated by Go MAEDA 3 months ago

  • Status changed from Resolved to Closed
Actions

Also available in: Atom PDF