Skip to content

fix: keep parens in markdown link URLs instead of truncating#871

Merged
vivek7405 merged 2 commits into
mainfrom
fix/paren-url-truncation
Jul 9, 2026
Merged

fix: keep parens in markdown link URLs instead of truncating#871
vivek7405 merged 2 commits into
mainfrom
fix/paren-url-truncation

Conversation

@vivek7405

@vivek7405 vivek7405 commented Jul 9, 2026

Copy link
Copy Markdown
Collaborator

Closes #860

What

The shared blog/compare markdown renderer captured link URLs with [^)]+, which stops at the first ). A link whose address legitimately contains a paren (a Wikipedia ..._(programming_language) URL, for example) was truncated, so its href pointed at a broken address and a stray ) leaked as text. This widens the URL group to allow one level of balanced nested parens so the address is captured whole.

Change

  • website/modules/blog/utils/render-post.ts: the link regex URL group becomes ((?:[^()]|\([^()]*\))*), capturing a URL that contains a single level of balanced (...).
  • Test in website/test/ssr/compare-ssr.test.ts for a paren-containing URL, with a counterfactual (fails against the old [^)]+).

Scope note

Handles one level of nesting (the realistic case). Deeper nesting (a_(b_(c))) is still not supported, which matches how many lightweight markdown renderers behave; not worth a full parser here.

Docs / surfaces

  • N/A for framework docs: website-local util, no packages/* public surface changed. The renderer header comment is updated to document balanced-paren URLs.

The blog/compare markdown renderer's link regex captured the URL with
`[^)]+`, which stops at the first `)`, so a link whose address contains
a paren (e.g. a Wikipedia `..._(programming_language)` URL) was cut off
and its `href` pointed at a broken address. Allow one level of balanced
nested parens in the URL group so the address is captured whole. Add a
test with the paren-containing URL.
@vivek7405 vivek7405 self-assigned this Jul 9, 2026
Address review of the paren-URL fix:
- Require at least one char in the URL group (`+` not `*`) so a malformed
  `[x]()` stays literal text instead of emitting an empty-href anchor,
  matching the prior behavior.
- Make the orphan-paren assertion real (the previous one never matched
  because of the injected screen-reader span) and add an empty-URL test.
- Update the renderer header comment to document balanced-paren URLs.

@vivek7405 vivek7405 left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

The regex fix is correct and safe (the unrolled (?:[^()]|\([^()]*\)) form has no ambiguous backtracking, so no ReDoS; no-paren URLs and one-level balanced parens both behave). Three things needed tightening: the group allowed zero reps so a malformed [x]() started emitting an empty-href anchor (now requires at least one char), the test's orphan-paren assertion never actually matched because of the injected sr-only span (now a real check, plus an empty-URL test), and the PR body claimed a header-comment update that had not happened (now the header genuinely documents balanced-paren URLs).

Comment thread website/modules/blog/utils/render-post.ts
Comment thread website/test/ssr/compare-ssr.test.ts
Comment thread website/modules/blog/utils/render-post.ts

@vivek7405 vivek7405 left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Went back over the regex with the + and the tests. Whole-URL capture with one level of parens holds, [x]() and [a](b) behave, no runaway backtracking, and the header comment matches the actual one-level limit. Nothing left.

@vivek7405 vivek7405 marked this pull request as ready for review July 9, 2026 08:20
@vivek7405 vivek7405 merged commit 41e7261 into main Jul 9, 2026
19 of 20 checks passed
@vivek7405 vivek7405 deleted the fix/paren-url-truncation branch July 9, 2026 08:46
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.

Blog/compare markdown renderer truncates URLs containing a closing paren

1 participant