Skip to content

Fix nested links produced when a bracket opens after an inner link - #640

Open
zayeem06 wants to merge 1 commit into
commonmark:masterfrom
zayeem06:nested-link-active-flag
Open

zayeem06 wants to merge 1 commit into
commonmark:masterfrom
zayeem06:nested-link-active-flag

Conversation

@zayeem06

Copy link
Copy Markdown
Contributor

handle_close_bracket tracked whether any active link opener remained with a single global flag on the subject (no_link_openers) rather than the per-opener active bit the CommonMark algorithm uses. The flag is set after a link is formed, so an outer ] that comes right after an inner link is correctly left literal (spec example 549). But push_bracket clears the flag for every new [, so a bracket opened between the inner link and the outer ] re-activates the still-open outer opener. When that ] is reached the outer opener matches and wraps the inner link:

[foo [bar](/uri)[x]](/uri)

rendered <p><a href="/uri">foo <a href="/uri">bar</a>[x]</a></p>, an <a> inside an <a>, which the spec forbids ("Links may not contain other links, at any level of nesting"). commonmark.js gives <p>[foo <a href="/uri">bar</a>[x]](/uri)</p>.

A single boolean cannot represent per-opener state. This switches to the active field already present on each bracket: the close-bracket check consults opener->active, and forming a link deactivates every remaining non-image opener on the stack, as commonmark.js does. Spec example 549 and nested images inside links are unaffected, and the full spec suite stays green.

Regression tests added for the inline and reference-link forms.

handle_close_bracket tracked whether any active link opener remained
with a single global flag on the subject (no_link_openers) rather than
the per-opener active bit the CommonMark algorithm uses. The flag is set
after a link is formed, so an outer ] that comes right after an inner
link is left literal (spec example 549). But push_bracket clears the
flag for every new [, so a bracket opened between the inner link and the
outer ] re-activates the still-open outer opener. When that ] is reached
the outer opener matches and wraps the inner link:

    [foo [bar](/uri)[x]](/uri)

rendered <a> nested inside <a>, which the spec forbids ("Links may not
contain other links, at any level of nesting"). commonmark.js leaves
the outer brackets literal.

Use the active field already present on each bracket: the close-bracket
check consults opener->active, and forming a link deactivates every
remaining non-image opener on the stack, as commonmark.js does.

Regression tests added for the inline and reference-link forms.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant