Fix `RangeError` hazards in links (dart-lang/markdown#624)
diff --git a/pkgs/markdown/CHANGELOG.md b/pkgs/markdown/CHANGELOG.md index ec5b890..658d8b6 100644 --- a/pkgs/markdown/CHANGELOG.md +++ b/pkgs/markdown/CHANGELOG.md
@@ -2,6 +2,7 @@ * Fix an issue with checkbox list items separated with blank lines (#602). * Require package `web: '>=0.4.2 <2.0.0'`. +* Fix several `RangeError` hazards in links (#623). ## 7.2.2
diff --git a/pkgs/markdown/lib/src/inline_syntaxes/link_syntax.dart b/pkgs/markdown/lib/src/inline_syntaxes/link_syntax.dart index 7b3c304..bca3efb 100644 --- a/pkgs/markdown/lib/src/inline_syntaxes/link_syntax.dart +++ b/pkgs/markdown/lib/src/inline_syntaxes/link_syntax.dart
@@ -216,6 +216,7 @@ final char = parser.charAt(parser.pos); if (char == $backslash) { parser.advanceBy(1); + if (parser.isDone) return null; final next = parser.charAt(parser.pos); if (next != $backslash && next != $rbracket) { buffer.writeCharCode(char); @@ -273,12 +274,14 @@ /// Returns the link if it was successfully created, `null` otherwise. InlineLink? _parseInlineBracketedLink(InlineParser parser) { parser.advanceBy(1); + if (parser.isDone) return null; final buffer = StringBuffer(); while (true) { final char = parser.charAt(parser.pos); if (char == $backslash) { parser.advanceBy(1); + if (parser.isDone) return null; final next = parser.charAt(parser.pos); // TODO: Follow the backslash spec better here. // https://spec.commonmark.org/0.30/#backslash-escapes @@ -302,6 +305,7 @@ final destination = buffer.toString(); parser.advanceBy(1); + if (parser.isDone) return null; final char = parser.charAt(parser.pos); if (char == $space || char == $lf || char == $cr || char == $ff) { final title = _parseTitle(parser); @@ -433,6 +437,7 @@ final closeDelimiter = delimiter == $lparen ? $rparen : delimiter; parser.advanceBy(1); + if (parser.isDone) return null; // Now we look for an un-escaped closing delimiter. final buffer = StringBuffer(); @@ -440,6 +445,7 @@ final char = parser.charAt(parser.pos); if (char == $backslash) { parser.advanceBy(1); + if (parser.isDone) return null; final next = parser.charAt(parser.pos); if (next != $backslash && next != closeDelimiter) { buffer.writeCharCode(char);
diff --git a/pkgs/markdown/test/markdown_test.dart b/pkgs/markdown/test/markdown_test.dart index 1fea683..feb2d77 100644 --- a/pkgs/markdown/test/markdown_test.dart +++ b/pkgs/markdown/test/markdown_test.dart
@@ -80,6 +80,42 @@ <p>5 Ethernet ([Music](</p> '''); + validateCore('Incorrect Links - Issue #623 - 1 - Bracketed link 1', ''' +[](< +''', ''' +<p>[](<</p> +'''); + + validateCore('Incorrect Links - Issue #623 - 2 - Bracketed link 2', ''' +[](<> +''', ''' +<p>[](<></p> +'''); + + validateCore('Incorrect Links - Issue #623 - 3 - Bracketed link 3', r''' +[](<\ +''', r''' +<p>[](<\</p> +'''); + + validateCore('Incorrect Links - Issue #623 - 4 - Link title 1', ''' +[](www.example.com " +''', ''' +<p>[](www.example.com "</p> +'''); + + validateCore('Incorrect Links - Issue #623 - 5 - Link title 2', r''' +[](www.example.com "\ +''', r''' +<p>[](www.example.com "\</p> +'''); + + validateCore('Incorrect Links - Issue #623 - 6 - Reference link label', r''' +[][\ +''', r''' +<p>[][\</p> +'''); + validateCore('Escaping code block language', ''' ```"/><a/href="url">arbitrary_html</a> ```