Skip to content

[markdown] Fix LinkParser edge cases and BlockParser retreat loop - #2631

Merged
auto-submit[bot] merged 6 commits into
mainfrom
fix-markdown
Oct 14, 2026
Merged

auto-submit[bot] merged 6 commits into
mainfrom
fix-markdown

Conversation

@kevmoo

@kevmoo kevmoo commented Oct 3, 2026 •

Copy link
Copy Markdown
Member

Fix crashes and misparses on malformed link reference definitions, retreating block syntaxes, and list-ending footnotes:

  • Guard against EOF after trailing \ or < in LinkParser, and require balanced parentheses across bare link destinations ([a]: /url(a)b).
  • Track all retreating BlockSyntax rules per line (List<BlockSyntax>) in BlockParser.parseLines so two retreating syntaxes on the same line cannot loop.
  • Type Element.children as List<Node> in list/table/footnote builders so appending footnote backreferences (List<Node>) to a footnote ending in a list does not throw TypeError.

kevmoo added 3 commits October 2, 2026 23:21
- 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`.
@github-actions

github-actions Bot commented Oct 3, 2026 •

Copy link
Copy Markdown

PR Health

Coverage ✔️
File Coverage
pkgs/markdown/lib/src/block_parser.dart 💚 91 % ⬆️ 1 %
pkgs/markdown/lib/src/block_syntaxes/list_syntax.dart 💚 94 %
pkgs/markdown/lib/src/block_syntaxes/table_syntax.dart 💚 91 % ⬆️ 1 %
pkgs/markdown/lib/src/document.dart 💚 93 % ⬆️ 0 %
pkgs/markdown/lib/src/inline_parser.dart 💚 98 %
pkgs/markdown/lib/src/link_parser.dart 💚 98 % ⬆️ 1 %
pkgs/markdown/lib/src/text_parser.dart 💚 95 %

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 skip-coverage-check.

License Headers ✔️
// Copyright (c) 2026, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

Files
no missing headers

All source files should start with a license header.

Unrelated files missing license headers
Files
pkgs/html/test/differential_test.dart
pkgs/html/test/dom_parsing_test.dart
pkgs/html/test/mxss_test.dart
pkgs/html/test/noah_ark_clause_limit_test.dart

This check can be disabled by tagging the PR with skip-license-check.

Breaking changes ✔️
Package Change Current Version New Version Needed Version Looking good?
markdown Non-Breaking 7.3.1 7.4.1-wip 7.4.1-wip ✔️

This check can be disabled by tagging the PR with skip-breaking-check.

Unused Dependencies ✔️
Package Status
markdown ✔️ All dependencies utilized correctly.

For details on how to fix these, see dependency_validator.

This check can be disabled by tagging the PR with skip-unused-dependencies-check.

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.

Package Leaked API symbol Leaking sources

This check can be disabled by tagging the PR with skip-leaking-check.

Changelog Entry ✔️
Package Changed Files

Changes to files need to be accounted for in their respective changelogs.

This check can be disabled by tagging the PR with skip-changelog-check (for example, for non-user-visible changes when the package version is already at -wip).

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

kevmoo added 3 commits October 3, 2026 01:29
- 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`.

@srawlins srawlins left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Woohoo! Nice fixes

@auto-submit
auto-submit Bot merged commit 4eaf46b into main Oct 14, 2026
33 checks passed
@auto-submit
auto-submit Bot deleted the fix-markdown branch October 14, 2026 18:18
copybara-service Bot pushed a commit to dart-lang/sdk that referenced this pull request Oct 17, 2026
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]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants