This is an automated email from the ASF dual-hosted git repository.

asf-gitbox-commits pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/allura.git


The following commit(s) were added to refs/heads/master by this push:
     new 1fc06751a enforce text limits for all markdown rendering paths
1fc06751a is described below

commit 1fc06751a151a3482c5cdbb607077f2db12911d9
Author: Dave Brondsema <[email protected]>
AuthorDate: Thu Jun 11 11:39:08 2026 -0400

    enforce text limits for all markdown rendering paths
---
 Allura/allura/lib/app_globals.py    | 31 ++++++++++++++++++++++++-------
 Allura/allura/lib/search.py         |  4 ++++
 Allura/allura/tests/test_globals.py | 18 ++++++++++++++++++
 Allura/development.ini              |  2 ++
 4 files changed, 48 insertions(+), 7 deletions(-)

diff --git a/Allura/allura/lib/app_globals.py b/Allura/allura/lib/app_globals.py
index 90f1714e3..a7811f3f2 100644
--- a/Allura/allura/lib/app_globals.py
+++ b/Allura/allura/lib/app_globals.py
@@ -100,8 +100,14 @@ def toc_slugify_with_prefix(value, separator):
                         'mdx_breakless_lists',],
             output_format='html')
 
-    def convert(self, source, render_limit=True) -> Markup:
-        if render_limit and len(source) > 
asint(config.get('markdown_render_max_length', 80000)):
+    @staticmethod
+    def base_render_limit() -> int:
+        return asint(config.get('markdown_render_max_length', 80000))
+
+    def convert(self, source, max_length=None) -> Markup:
+        if max_length is None:
+            max_length = self.base_render_limit()
+        if len(source) > max_length:
             # if text is too big, markdown can take a long time to process it,
             # so we return it as a plain text
             log.info('Text is too big. Skipping markdown processing')
@@ -145,7 +151,8 @@ def cached_convert(self, artifact: MappedClass, field_name: 
str) -> Markup:
 
         # Convert the markdown and time the result.
         start = time.time()
-        html = self.convert(source_text, render_limit=False)
+        cached_max_length = 
asint(config.get('markdown_render_max_length.cached', self.base_render_limit() 
* 2))
+        html = self.convert(source_text, max_length=cached_max_length)
         render_time = time.time() - start
 
         threshold = config.get('markdown_cache_threshold')
@@ -189,6 +196,19 @@ def cached_convert(self, artifact: MappedClass, 
field_name: str) -> Markup:
         return html
 
 
+class ForgeMarkdownCommit(ForgeMarkdown):
+
+    def __init__(self, app):
+        super().__init__()
+        self.app = app
+
+    def make_markdown_instance(self, **forge_ext_kwargs):
+        return markdown.Markdown(
+            extensions=[CommitMessageExtension(self.app), EmojiExtension(), 
'markdown.extensions.nl2br'],
+            output_format='html',
+        )
+
+
 class Globals:
 
     """Container for objects available throughout the life of the application.
@@ -520,10 +540,7 @@ def markdown_commit(self):
 
         """
         app = getattr(c, 'app', None)
-        return markdown.Markdown(
-            extensions=[CommitMessageExtension(app), EmojiExtension(), 
'markdown.extensions.nl2br'],
-            output_format='html',
-        )
+        return ForgeMarkdownCommit(app)
 
     @property
     def production_mode(self):
diff --git a/Allura/allura/lib/search.py b/Allura/allura/lib/search.py
index 4e832261b..b234a863b 100644
--- a/Allura/allura/lib/search.py
+++ b/Allura/allura/lib/search.py
@@ -415,7 +415,11 @@ def filter_unauthorized(doc):
 
 def find_shortlinks(text):
     from .markdown_extensions import ForgeExtension
+    from .app_globals import ForgeMarkdown
 
+    if len(text) > ForgeMarkdown.base_render_limit():
+        log.info('Text is too big. Skipping shortlink search')
+        return []
     md = markdown.Markdown(
         extensions=['markdown.extensions.codehilite', ForgeExtension(), 
'markdown.extensions.tables'],
         output_format='html')
diff --git a/Allura/allura/tests/test_globals.py 
b/Allura/allura/tests/test_globals.py
index 0c7331d02..ab1a09c17 100644
--- a/Allura/allura/tests/test_globals.py
+++ b/Allura/allura/tests/test_globals.py
@@ -42,6 +42,7 @@
 from allura import model as M
 from allura.lib import helpers as h
 from allura.lib.app_globals import ForgeMarkdown
+from allura.lib.search import find_shortlinks
 from allura.tests import decorators as td
 
 from forgewiki import model as WM
@@ -445,6 +446,11 @@ def test_markdown_big_text(self):
         assert g.markdown.convert(text) == '<pre>%s</pre>' % text
         assert g.markdown_wiki.convert(text) == '<pre>%s</pre>' % text
         assert g.markdown.convert('<b>' + text) == '<pre>&lt;b&gt;%s</pre>' % 
text
+        assert g.markdown_commit.convert(text) == '<pre>%s</pre>' % text
+
+    def test_find_shortlinks_big_text(self):
+        text = '[a123]  ' + 'a' * 40001
+        assert find_shortlinks(text) == []
 
     def test_markdown_basics(self):
         with h.push_context('test', 'wiki', neighborhood='Projects'):
@@ -922,6 +928,18 @@ def test_render_time_below_threshold(self):
         assert self.post.text_cache.html is None
         assert self.post.text_cache.render_time is None
 
+    @patch.dict('allura.lib.app_globals.config', 
markdown_cache_threshold='99999')
+    def test_big_text(self):
+        # between the base limit and the higher .cached limit (2x by default), 
still renders
+        self.post.text = 'a' * 50000
+        html = self.md.cached_convert(self.post, 'text')
+        assert not html.startswith('<pre>')
+        # beyond the .cached limit, falls back to plain text
+        self.post.text = 'a' * 80001
+        del self.post.text_cache
+        html = self.md.cached_convert(self.post, 'text')
+        assert html == '<pre>%s</pre>' % self.post.text
+
     @patch.dict('allura.lib.app_globals.config', {})
     def test_all_expected_keys_exist_in_cache(self):
         self.md.cached_convert(self.post, 'text')
diff --git a/Allura/development.ini b/Allura/development.ini
index 3193b5331..62d03b9f1 100644
--- a/Allura/development.ini
+++ b/Allura/development.ini
@@ -664,6 +664,8 @@ site_notification.impressions = 0
 markdown_cache_threshold = .1
 ; markdown text longer than max length will not be converted to html
 markdown_render_max_length = 200000
+; higher limit for renders that can be cached (defaults to 2x 
markdown_render_max_length)
+;markdown_render_max_length.cached =
 ; Don't add rel=nofollow to these domains when generating links from Markdown 
content
 ;nofollow_exempt_domains =
 

Reply via email to