Bug Description
The markdown() function in lib/src/utils/markdown.dart pre-escapes all <> patterns before passing text to markdownToHtml():
text.replaceAllMapped(
RegExp(r'<([^>]*)>'),
(match) => '<${match.group(1)}>',
)
However, markdownToHtml() (from the markdown package) also escapes special characters inside code blocks. This causes double encoding.
Steps to Reproduce
Send a message containing a code block with angle brackets:
```dart
List<String> items = [];
```
Expected
The formatted_body HTML should contain single-encoded entities inside <code>:
List & l t ; String & g t ;
(i.e. & + lt; and & + gt; — standard HTML encoding of < and >)
Actual
The formatted_body HTML contains double-encoded entities:
List & a m p ; l t ; String & a m p ; g t ;
(i.e. & + amp;lt; — the & itself got encoded to &, producing &lt;)
Which renders as literal text List<String> instead of List<String>.
Pipeline
- Pre-processing regex:
<String> → <String> (the <> are replaced with entities)
markdownToHtml() code block escaping: <String> → &lt;String&gt; (the & gets escaped again)
- DOM parser decodes one level:
&lt; → < (only the outer & is decoded)
- User sees:
<String> instead of <String>
Additional Issues
The regex <([^>]*)> also has a greedy matching problem with nested generics. For Map<String, List<int>>, the regex matches <String, List<int> as one group (because [^>]* stops at the first >), leaving inconsistent escaping.
Affected Versions
Introduced in PR #2178 ("refactor: Escape HTML tags before markdown rendering", merged 2025-11-06). Still present on main (v7.2.2).
Suggested Fix
The markdown package's markdownToHtml() already handles HTML escaping inside code blocks via its encodeHtml parameter (default true). The pre-escape regex should either:
- Skip content inside code fences (
` and ```)
- Or be removed entirely if the markdown package's built-in escaping is sufficient for the non-code use case
Bug Description
The
markdown()function inlib/src/utils/markdown.dartpre-escapes all<>patterns before passing text tomarkdownToHtml():However,
markdownToHtml()(from themarkdownpackage) also escapes special characters inside code blocks. This causes double encoding.Steps to Reproduce
Send a message containing a code block with angle brackets:
Expected
The
formatted_bodyHTML should contain single-encoded entities inside<code>:(i.e.
&+lt;and&+gt;— standard HTML encoding of<and>)Actual
The
formatted_bodyHTML contains double-encoded entities:(i.e.
&+amp;lt;— the&itself got encoded to&, producing&lt;)Which renders as literal text
List<String>instead ofList<String>.Pipeline
<String>→<String>(the<>are replaced with entities)markdownToHtml()code block escaping:<String>→&lt;String&gt;(the&gets escaped again)&lt;→<(only the outer&is decoded)<String>instead of<String>Additional Issues
The regex
<([^>]*)>also has a greedy matching problem with nested generics. ForMap<String, List<int>>, the regex matches<String, List<int>as one group (because[^>]*stops at the first>), leaving inconsistent escaping.Affected Versions
Introduced in PR #2178 ("refactor: Escape HTML tags before markdown rendering", merged 2025-11-06). Still present on
main(v7.2.2).Suggested Fix
The
markdownpackage'smarkdownToHtml()already handles HTML escaping inside code blocks via itsencodeHtmlparameter (defaulttrue). The pre-escape regex should either:`and```)