Merge branch 'krille/fix-crash-in-htmltotext' into 'main'

fix: HtmlToText crashes with an empty code block

Closes #249

See merge request famedly/company/frontend/famedlysdk!897
This commit is contained in:
td 2021-11-16 07:27:09 +00:00
commit 1804838324
2 changed files with 89 additions and 84 deletions

View File

@ -50,11 +50,13 @@ class HtmlToText {
.firstMatch(text); .firstMatch(text);
if (match == null) { if (match == null) {
text = HtmlUnescape().convert(text); text = HtmlUnescape().convert(text);
if (text[0] != '\n') { if (text.isNotEmpty) {
text = '\n$text'; if (text[0] != '\n') {
} text = '\n$text';
if (text[text.length - 1] != '\n') { }
text += '\n'; if (text[text.length - 1] != '\n') {
text += '\n';
}
} }
return text; return text;
} }
@ -64,11 +66,13 @@ class HtmlToText {
text = text.replaceAll( text = text.replaceAll(
RegExp(r'</code>$', multiLine: false, caseSensitive: false), ''); RegExp(r'</code>$', multiLine: false, caseSensitive: false), '');
text = HtmlUnescape().convert(text); text = HtmlUnescape().convert(text);
if (text[0] != '\n') { if (text.isNotEmpty) {
text = '\n$text'; if (text[0] != '\n') {
} text = '\n$text';
if (text[text.length - 1] != '\n') { }
text += '\n'; if (text[text.length - 1] != '\n') {
text += '\n';
}
} }
final language = final language =
RegExp(r'language-(\w+)', multiLine: false, caseSensitive: false) RegExp(r'language-(\w+)', multiLine: false, caseSensitive: false)

View File

@ -21,80 +21,81 @@ import 'package:test/test.dart';
void main() { void main() {
group('htmlToText', () { group('htmlToText', () {
test('stuff', () async { final testMap = <String, String>{
final testMap = <String, String>{ '': '',
'': '', 'hello world\nthis is a test': 'hello world\nthis is a test',
'hello world\nthis is a test': 'hello world\nthis is a test', '<em>That\'s</em> not a test, <strong>this</strong> is a test':
'<em>That\'s</em> not a test, <strong>this</strong> is a test': '*That\'s* not a test, **this** is a test',
'*That\'s* not a test, **this** is a test', 'Visit <del><a href="http://example.com">our website</a></del> (outdated)':
'Visit <del><a href="http://example.com">our website</a></del> (outdated)': 'Visit ~~🔗our website~~ (outdated)',
'Visit ~~🔗our website~~ (outdated)', '(cw spiders) <span data-mx-spoiler>spiders are pretty cool</span>':
'(cw spiders) <span data-mx-spoiler>spiders are pretty cool</span>': '(cw spiders) ███████████████████████',
'(cw spiders) ███████████████████████', '<span data-mx-spoiler="cw spiders">spiders are pretty cool</span>':
'<span data-mx-spoiler="cw spiders">spiders are pretty cool</span>': '(cw spiders) ███████████████████████',
'(cw spiders) ███████████████████████', '<img src="test.gif" alt="a test case" />': 'a test case',
'<img src="test.gif" alt="a test case" />': 'a test case', 'List of cute animals:\n<ul>\n<li>Kittens</li>\n<li>Puppies</li>\n<li>Snakes<br/>(I think they\'re cute!)</li>\n</ul>\n(This list is incomplete, you can help by adding to it!)':
'List of cute animals:\n<ul>\n<li>Kittens</li>\n<li>Puppies</li>\n<li>Snakes<br/>(I think they\'re cute!)</li>\n</ul>\n(This list is incomplete, you can help by adding to it!)': 'List of cute animals:\n● Kittens\n● Puppies\n● Snakes\n (I think they\'re cute!)\n(This list is incomplete, you can help by adding to it!)',
'List of cute animals:\n● Kittens\n● Puppies\n● Snakes\n (I think they\'re cute!)\n(This list is incomplete, you can help by adding to it!)', '<em>fox</em>': '*fox*',
'<em>fox</em>': '*fox*', '<i>fox</i>': '*fox*',
'<i>fox</i>': '*fox*', '<strong>fox</i>': '**fox**',
'<strong>fox</i>': '**fox**', '<b>fox</b>': '**fox**',
'<b>fox</b>': '**fox**', '<u>fox</u>': '__fox__',
'<u>fox</u>': '__fox__', '<ins>fox</ins>': '__fox__',
'<ins>fox</ins>': '__fox__', '<del>fox</del>': '~~fox~~',
'<del>fox</del>': '~~fox~~', '<strike>fox</strike>': '~~fox~~',
'<strike>fox</strike>': '~~fox~~', '<s>fox</s>': '~~fox~~',
'<s>fox</s>': '~~fox~~', '<code>&gt;fox</code>': '`>fox`',
'<code>&gt;fox</code>': '`>fox`', '<pre>meep</pre>': '```\nmeep\n```',
'<pre>meep</pre>': '```\nmeep\n```', '<pre>meep\n</pre>': '```\nmeep\n```',
'<pre>meep\n</pre>': '```\nmeep\n```', '<pre><code class="language-floof">meep</code></pre>':
'<pre><code class="language-floof">meep</code></pre>': '```floof\nmeep\n```',
'```floof\nmeep\n```', 'before<pre>code</pre>after': 'before\n```\ncode\n```\nafter',
'before<pre>code</pre>after': 'before\n```\ncode\n```\nafter', '<p>before</p><pre>code</pre><p>after</p>':
'<p>before</p><pre>code</pre><p>after</p>': 'before\n```\ncode\n```\nafter',
'before\n```\ncode\n```\nafter', '<p>fox</p>': 'fox',
'<p>fox</p>': 'fox', '<p>fox</p><p>floof</p>': 'fox\n\nfloof',
'<p>fox</p><p>floof</p>': 'fox\n\nfloof', '<a href="https://example.org">website</a>': '🔗website',
'<a href="https://example.org">website</a>': '🔗website', '<a href="https://matrix.to/#/@user:example.org">fox</a>': 'fox',
'<a href="https://matrix.to/#/@user:example.org">fox</a>': 'fox', '<a href="matrix:u/user:example.org">fox</a>': 'fox',
'<a href="matrix:u/user:example.org">fox</a>': 'fox', '<img alt=":wave:" src="mxc://fox">': ':wave:',
'<img alt=":wave:" src="mxc://fox">': ':wave:', 'fox<br>floof': 'fox\nfloof',
'fox<br>floof': 'fox\nfloof', '<blockquote>fox</blockquote>floof': '> fox\nfloof',
'<blockquote>fox</blockquote>floof': '> fox\nfloof', '<blockquote><p>fox</p></blockquote>floof': '> fox\nfloof',
'<blockquote><p>fox</p></blockquote>floof': '> fox\nfloof', '<blockquote><p>fox</p></blockquote><p>floof</p>': '> fox\nfloof',
'<blockquote><p>fox</p></blockquote><p>floof</p>': '> fox\nfloof', 'a<blockquote>fox</blockquote>floof': 'a\n> fox\nfloof',
'a<blockquote>fox</blockquote>floof': 'a\n> fox\nfloof', '<blockquote><blockquote>fox</blockquote>floof</blockquote>fluff':
'<blockquote><blockquote>fox</blockquote>floof</blockquote>fluff': '> > fox\n> floof\nfluff',
'> > fox\n> floof\nfluff', '<ul><li>hey<ul><li>a</li><li>b</li></ul></li><li>foxies</li></ul>':
'<ul><li>hey<ul><li>a</li><li>b</li></ul></li><li>foxies</li></ul>': '● hey\n ○ a\n ○ b\n● foxies',
'● hey\n ○ a\n ○ b\n● foxies', '<ol><li>a</li><li>b</li></ol>': '1. a\n2. b',
'<ol><li>a</li><li>b</li></ol>': '1. a\n2. b', '<ol start="42"><li>a</li><li>b</li></ol>': '42. a\n43. b',
'<ol start="42"><li>a</li><li>b</li></ol>': '42. a\n43. b', '<ol><li>a<ol><li>aa</li><li>bb</li></ol></li><li>b</li></ol>':
'<ol><li>a<ol><li>aa</li><li>bb</li></ol></li><li>b</li></ol>': '1. a\n 1. aa\n 2. bb\n2. b',
'1. a\n 1. aa\n 2. bb\n2. b', '<ol><li>a<ul><li>aa</li><li>bb</li></ul></li><li>b</li></ol>':
'<ol><li>a<ul><li>aa</li><li>bb</li></ul></li><li>b</li></ol>': '1. a\n ○ aa\n ○ bb\n2. b',
'1. a\n ○ aa\n ○ bb\n2. b', '<ul><li>a<ol><li>aa</li><li>bb</li></ol></li><li>b</li></ul>':
'<ul><li>a<ol><li>aa</li><li>bb</li></ol></li><li>b</li></ul>': '● a\n 1. aa\n 2. bb\n● b',
'● a\n 1. aa\n 2. bb\n● b', '<mx-reply>bunny</mx-reply>fox': 'fox',
'<mx-reply>bunny</mx-reply>fox': 'fox', 'fox<hr>floof': 'fox\n----------\nfloof',
'fox<hr>floof': 'fox\n----------\nfloof', '<p>fox</p><hr><p>floof</p>': 'fox\n----------\nfloof',
'<p>fox</p><hr><p>floof</p>': 'fox\n----------\nfloof', '<h1>fox</h1>floof': '# fox\nfloof',
'<h1>fox</h1>floof': '# fox\nfloof', '<h1>fox</h1><p>floof</p>': '# fox\nfloof',
'<h1>fox</h1><p>floof</p>': '# fox\nfloof', 'floof<h1>fox</h1>': 'floof\n# fox',
'floof<h1>fox</h1>': 'floof\n# fox', '<p>floof</p><h1>fox</h1>': 'floof\n# fox',
'<p>floof</p><h1>fox</h1>': 'floof\n# fox', '<h2>fox</h2>': '## fox',
'<h2>fox</h2>': '## fox', '<h3>fox</h3>': '### fox',
'<h3>fox</h3>': '### fox', '<h4>fox</h4>': '#### fox',
'<h4>fox</h4>': '#### fox', '<h5>fox</h5>': '##### fox',
'<h5>fox</h5>': '##### fox', '<h6>fox</h6>': '###### fox',
'<h6>fox</h6>': '###### fox', '<span>fox</span>': 'fox',
'<span>fox</span>': 'fox', '<p>fox</p>\n<p>floof</p>': 'fox\n\nfloof',
'<p>fox</p>\n<p>floof</p>': 'fox\n\nfloof', '<mx-reply>beep</mx-reply><p>fox</p>\n<p>floof</p>': 'fox\n\nfloof',
'<mx-reply>beep</mx-reply><p>fox</p>\n<p>floof</p>': 'fox\n\nfloof', '<pre><code></code></pre>': '``````',
}; };
for (final entry in testMap.entries) { for (final entry in testMap.entries) {
test(entry.key, () async {
expect(HtmlToText.convert(entry.key), entry.value); expect(HtmlToText.convert(entry.key), entry.value);
} });
}); }
}); });
} }