From 5fceaa79f3ba92e7948f1638f86cb4a3f82d0dab Mon Sep 17 00:00:00 2001 From: Hampus Kraft Date: Fri, 20 Feb 2026 19:24:07 +0000 Subject: [PATCH] fix(markdown): parse mentions inside brackets correctly --- .../src/__tests__/LinkParsers.test.tsx | 18 +++++++++++++++++- .../src/parsers/LinkParsers.tsx | 10 +++++++++- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/packages/markdown_parser/src/__tests__/LinkParsers.test.tsx b/packages/markdown_parser/src/__tests__/LinkParsers.test.tsx index 324423f5..37c6b693 100644 --- a/packages/markdown_parser/src/__tests__/LinkParsers.test.tsx +++ b/packages/markdown_parser/src/__tests__/LinkParsers.test.tsx @@ -18,7 +18,7 @@ */ import {Parser} from '@fluxer/markdown_parser/src/parser/Parser'; -import {NodeType, ParserFlags} from '@fluxer/markdown_parser/src/types/Enums'; +import {MentionKind, NodeType, ParserFlags} from '@fluxer/markdown_parser/src/types/Enums'; import type {LinkNode} from '@fluxer/markdown_parser/src/types/Nodes'; import {describe, expect, test} from 'vitest'; @@ -543,6 +543,22 @@ describe('Fluxer Markdown Parser', () => { ]); }); + test('link parser should not escape bracketed mentions', () => { + const input = '[ <@1473362285356646457> ]'; + const flags = ParserFlags.ALLOW_MASKED_LINKS | ParserFlags.ALLOW_USER_MENTIONS; + const parser = new Parser(input, flags); + const {nodes: ast} = parser.parse(); + + expect(ast).toEqual([ + {type: NodeType.Text, content: '[ '}, + { + type: NodeType.Mention, + kind: {kind: MentionKind.User, id: '1473362285356646457'}, + }, + {type: NodeType.Text, content: ' ]'}, + ]); + }); + test('domain-like link text without protocol should parse as a link', () => { const testCases = [ {input: '[google.com](https://evil.com)', url: 'https://evil.com/'}, diff --git a/packages/markdown_parser/src/parsers/LinkParsers.tsx b/packages/markdown_parser/src/parsers/LinkParsers.tsx index 49098f9b..dfef9802 100644 --- a/packages/markdown_parser/src/parsers/LinkParsers.tsx +++ b/packages/markdown_parser/src/parsers/LinkParsers.tsx @@ -17,6 +17,7 @@ * along with Fluxer. If not, see . */ +import {parseMention} from '@fluxer/markdown_parser/src/parsers/MentionParsers'; import {NodeType, ParserFlags} from '@fluxer/markdown_parser/src/types/Enums'; import {MAX_LINK_URL_LENGTH} from '@fluxer/markdown_parser/src/types/MarkdownConstants'; import type {Node, ParserResult} from '@fluxer/markdown_parser/src/types/Nodes'; @@ -53,7 +54,7 @@ function containsLinkSyntax(text: string): boolean { export function parseLink( text: string, - _parserFlags: number, + parserFlags: number, parseInline: (text: string) => Array, ): ParserResult | null { if (text.charCodeAt(0) !== OPEN_BRACKET) return null; @@ -72,6 +73,13 @@ export function parseLink( if (bracketResult) { const {bracketPosition, linkText} = bracketResult; + const trimmedLinkText = linkText.trim(); + + const mentionResult = parseMention(trimmedLinkText, parserFlags); + + if (mentionResult && mentionResult.advance === trimmedLinkText.length) { + return null; + } if (containsLinkSyntax(linkText)) { return {