Skip to content

fix: #4356 crash when using the link popover on a link with an unsupported protocol - #4473

Merged
Jocs merged 1 commit into
marktext:developfrom
FurkaanBoraa:fix/4356-link-jump-null-href
Jun 21, 2026
Merged

Jocs merged 1 commit into
marktext:developfrom
FurkaanBoraa:fix/4356-link-jump-null-href

Conversation

@FurkaanBoraa

Copy link
Copy Markdown
Contributor

Closes #4356

Summary

Clicking the "jump" button in the link popover on a link whose URL uses an unsupported protocol (e.g. sambesi://localhost/node/11164) crashed the renderer with TypeError: Cannot read properties of null (reading 'length').

Root cause: muya's sanitizeHyperlink (DOMPurify's protocol allowlist) strips such hrefs at render time, so getLinkInfo captures href: null, and the popover's jump handler forwarded that to FORMAT_LINK_CLICK, which read data.href.length without a guard.

The fix is two-layered:

  • @muyajs/core: the linkTools popover no longer offers "jump" when linkInfo.href is empty — there is nothing to jump to. This mirrors the existing nothing-to-act-on rule that keeps unresolved reference links out of the popover entirely.
  • desktop: FORMAT_LINK_CLICK null-guards data.href (defense in depth), and the jumpClick / store payload types now match muya's actual contract (href: string | null).

Reproduced on macOS against develop (64e590c) before the fix with the exact stack trace from the issue; the same scenario is clean after the fix.

Note on scope: even without the crash, custom-protocol links do not open — the main-process mt::format-link-click handler only opens http(s) URLs and deliberately swallows other schemes (// Prevent other URLs.). That behavior predates the engine rewrite and is left unchanged here, since opening arbitrary schemes via shell.openExternal is a security decision. Happy to follow up if supporting custom protocols (e.g. behind a confirmation prompt) is wanted — discussed in #4356.

Type of change

  • Bug fix (non-breaking, fixes an issue)
  • New feature (non-breaking, adds functionality)
  • Breaking change (causes existing functionality to change)
  • Documentation update

Test plan

  • New tests added (or explain why not needed)
  • Manually tested on: macOS

New tests:

  • packages/muya/src/ui/linkTools/__tests__/linkTools.spec.ts — the popover omits the jump item when linkInfo.href is null and renders it when an href is present.
  • packages/desktop/test/e2e/issue-4356.spec.ts — Playwright regression spec: the popover on a custom-protocol link offers only "unlink" without renderer errors, and anchor links still offer a working "jump".

Verified locally: muya unit tests (726 passed), desktop unit tests (465 passed), pnpm run lint, pnpm run typecheck, pnpm -C packages/muya lint, pnpm -C packages/muya lint:types, and the desktop e2e suite (97 passed; the one failure, parity-source-undo-saved.spec.ts, fails identically on unmodified develop and is unrelated).

Notes for reviewers [optional]

The e2e spec follows the existing issue-NNNN.spec.ts crash-guard convention and uses the suppressErrorDialog + expectNoRendererErrors helpers from test/e2e/helpers.ts.


By submitting this pull request, I confirm that my contribution is made under the terms of the MIT license.

@FurkaanBoraa

Copy link
Copy Markdown
Contributor Author

Rebased onto the latest develop (the muya engine refactor renamed some private members, so the linkTools change was updated to match), and re-verified on macOS: the crash still reproduces on current develop, and after this change it's gone. muya unit tests, the desktop e2e regression spec (issue-4356.spec.ts), lint and typecheck all pass on both packages.

Just to clarify scope so this is easy to evaluate: this PR only fixes the crash — it stops the popover from offering "jump" when the href was sanitized away, and null-guards FORMAT_LINK_CLICK. It deliberately does not change the existing http(s)-only open policy. The separate work of actually opening custom protocols is #4416, whose author kindly suggested landing this narrower crash fix first (#4416 (comment) thread).

Whenever you have a moment, could you take a look / approve the CI run? Happy to adjust anything.

@Jocs

Jocs commented Jun 18, 2026

Copy link
Copy Markdown
Member

@FurkaanBoraa Pls fix the failed CI.

A markdown link with an unsupported protocol (e.g. sambesi://) gets its
href stripped by muya's sanitizeHyperlink, so the linkTools popover
captures href: null and clicking "jump" crashed FORMAT_LINK_CLICK with
"TypeError: Cannot read properties of null (reading 'length')".

- muya: hide the jump action when linkInfo.href is empty — there is
  nothing to jump to
- desktop: null-guard FORMAT_LINK_CLICK and align the payload types
  with muya's actual contract (href: string | null)
- tests: muya unit specs for the popover filtering; desktop e2e
  regression spec issue-4356.spec.ts
@FurkaanBoraa
FurkaanBoraa force-pushed the fix/4356-link-jump-null-href branch from 4ec36fb to aa86971 Compare June 21, 2026 13:42
@FurkaanBoraa

Copy link
Copy Markdown
Contributor Author

Thanks @Jocs — fixed and pushed. The CI failure was in the muya unit spec: after the engine refactor renamed the link-tools private members to the _-prefixed form, my added test cases still referenced the old linkInfo name (and the white-box ILinkToolsView interface needed render/container added). I'd updated this locally during the rebase but missed committing it before the force-push — that's on me. Corrected now and verified locally: lint:types, lint, and the full muya suite (985 tests) all pass, plus desktop typecheck/lint/e2e.

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.

Link with custom protocoll does not work

2 participants