Repository navigation
[markdown] Fix LinkParser edge cases and BlockParser retreat loop - #2631
Conversation
- Check `isDone` after advancing past a trailing backslash (`\`) in `LinkParser.parseLabel`, `_parseBracketedDestination`, `_parseBareDestination`, and `_parseTitle`, and after advancing past the opening `<` in `_parseBracketedDestination` (`pkgs/markdown/lib/src/link_parser.dart`).
- Use `_position >= length` in `TextParser.isDone` (`pkgs/markdown/lib/src/text_parser.dart`) to match `BlockParser.isDone`.
- Track all non-advancing `BlockSyntax` rules at the current line position in `neverMatch` (`final neverMatch = <BlockSyntax>[]`) in `BlockParser.parseLines` (`pkgs/markdown/lib/src/block_parser.dart`) so a line matching multiple retreating syntaxes (such as `TableSyntax` followed by `LinkReferenceDefinitionSyntax`) falls through to `ParagraphSyntax` instead of throwing `AssertionError('BlockParser.parseLines is not advancing')`.
- Add regression tests in `pkgs/markdown/test/regression_test.dart`.
…e check - Remove redundant null check and duplicate `while (row.children!.length > columnCount)` loop in `TableSyntax.parse` (`pkgs/markdown/lib/src/block_syntaxes/table_syntax.dart`). - Remove unreachable `if (isDone)` check after `while (true)` loop in `LinkParser._parseTitle` (`pkgs/markdown/lib/src/link_parser.dart`).
…nlineParser.isDone - Reject unbalanced closing parentheses (`parenCount < 0`) and unclosed opening parentheses (`parenCount != 0`) in `LinkParser._parseBareDestination`, and continue scanning after a balanced `)` instead of breaking prematurely (`pkgs/markdown/lib/src/link_parser.dart`). - Use `pos >= source.length` in `InlineParser.isDone` (`pkgs/markdown/lib/src/inline_parser.dart`) to match `BlockParser.isDone` and `TextParser.isDone`. - Add regression tests in `pkgs/markdown/test/regression_test.dart` and update `pkgs/markdown/CHANGELOG.md`.
PR HealthCoverage ✔️
This check for test coverage is informational (issues shown here will not fail the PR). This check can be disabled by tagging the PR with License Headers ✔️
All source files should start with a license header. Unrelated files missing license headers
This check can be disabled by tagging the PR with Breaking changes ✔️
This check can be disabled by tagging the PR with Unused Dependencies ✔️
For details on how to fix these, see dependency_validator. This check can be disabled by tagging the PR with API leaks ✔️The following packages contain symbols visible in the public API, but not exported by the library. Export these symbols or remove them from your publicly visible API.
This check can be disabled by tagging the PR with Changelog Entry ✔️
Changes to files need to be accounted for in their respective changelogs. This check can be disabled by tagging the PR with |
There was a problem hiding this comment.
Code Review
This pull request addresses several issues in the markdown parser. It fixes a RangeError in LinkParser when a link reference definition ends with a trailing backslash or an unclosed < destination at EOF, rejects unbalanced parentheses in bare link reference destinations, and resolves an AssertionError when multiple BlockSyntax rules match on the same line without advancing by tracking multiple non-advancing syntaxes in a list. Additionally, it updates the isDone boundary checks in InlineParser and TextParser to use >= instead of ==, simplifies table cell padding logic in TableSyntax, and adds comprehensive regression tests. There are no review comments, and I have no additional feedback to provide.
- Pass `List<Node>` (`<Node>[...]`) instead of `List<Element>` when constructing `Element` instances in `ListSyntax.parse`, `TableSyntax.parse`, `TableSyntax._parseRow`, and `Document._filterFootnotes` so `Element.children` can accept `Text` nodes. - Handle void elements (`last.children == null`, such as `<hr />`) in `Document._appendBackref` so backreferences are not silently dropped. - Add regression tests in `test/regression_test.dart` and update `CHANGELOG.md`.
Roll `tools_rev` to c1471db9c0fead64394eab4834d0fb640403b42a and replace `dartdev`'s duplicate `_isRunningOnBot` implementation with `Analytics.isBot` from `package:unified_analytics`, which ignores falsy `CI` and `BOT` environment values (`false`, `0`, empty). Rolling `package:unified_analytics` also defaults `Analytics.agent` to `AiAgent.detectAgentName(Platform.environment)` for SDK tools such as `analysis_server` and `dtd` when `agent` is omitted, and tightens `AiAgent.cursor` detection. tools (https://github.com/dart-lang/tools/compare/350bde5..c1471db): c1471db9 Fri Oct 16 09:35:21 2026 -0700 Kevin Moore [unified_analytics] Fix Cursor agent check, default agent & add isBot (dart-lang/tools#2687) 2d0d09a1 Fri Oct 16 15:37:59 2026 +0000 Phil Quitslund [unified_analytics] Prepare for 8.1.0 release (dart-lang/tools#2684) 7ea42bf6 Thu Oct 15 11:13:58 2026 -0700 Kallen Tu Add Event.migrateEvent for the dart migrate tool. (dart-lang/tools#2682) 4eaf46ba Wed Oct 14 18:18:45 2026 +0000 Kevin Moore [markdown] Fix LinkParser edge cases and BlockParser retreat loop (dart-lang/tools#2631) 03f7124a Wed Oct 14 11:15:00 2026 -0700 Kevin Moore [markdown] Add tool/update_spec_tests.dart and sync GFM 0.29.0.gfm.13 spec stats (dart-lang/tools#2666) e0c90075 Tue Oct 13 16:16:23 2026 -0700 Morgan :) [code_builder] publish 4.13.0 (dart-lang/tools#2663) Fixes #64594 Fixes #64591 TEST=pkg/dartdev/test/analytics_test.dart Change-Id: I71026772917d60df2ef144cc5527be9002f087f6 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/565421 Commit-Queue: Kevin Moore <[email protected]> Reviewed-by: Keerti Parthasarathy <[email protected]>
Fix crashes and misparses on malformed link reference definitions, retreating block syntaxes, and list-ending footnotes:
\or<inLinkParser, and require balanced parentheses across bare link destinations ([a]: /url(a)b).BlockSyntaxrules per line (List<BlockSyntax>) inBlockParser.parseLinesso two retreating syntaxes on the same line cannot loop.Element.childrenasList<Node>in list/table/footnote builders so appending footnote backreferences (List<Node>) to a footnote ending in a list does not throwTypeError.