Skip to content

Commit a951ddb

Browse files
committed
fix: comprehensive MarkdownV2 escaping and sanitization
1 parent 61813e8 commit a951ddb

2 files changed

Lines changed: 12 additions & 6 deletions

File tree

bot

Submodule bot updated 1 file

packages/shared/src/index.ts

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -191,14 +191,20 @@ export async function markdownToHtml(s: string): Promise<string> {
191191
return (parsed as string).replace(/\n{3,}/g, '\n\n').trim();
192192
}
193193

194-
export function sanitizeMarkdownV2(text: string): string {
195-
return text.replace(/([_*[\]()~`>#+\-=|{}.!])/g, '\\$1');
194+
export function sanitizeMarkdownV2(text: string, isInsideLink = false): string {
195+
// Standard MarkdownV2 characters that MUST be escaped outside of code/pre
196+
let escaped = text.replace(/([_*[\]()~`>#+\-=|{}.!\\])/g, '\\$1');
197+
if (isInsideLink) {
198+
// Inside links, additional characters need escaping
199+
escaped = escaped.replace(/([()])/g, '\\$1');
200+
}
201+
return escaped;
196202
}
197203

198204
export async function markdownToMarkdownV2(s: string): Promise<string> {
199205
const renderer = new marked.Renderer();
200206

201-
const escape = (text: string) => sanitizeMarkdownV2(text);
207+
const escape = (text: string, isLink = false) => sanitizeMarkdownV2(text, isLink);
202208

203209
renderer.heading = ({ tokens }) => {
204210
const text = renderer.parser.parseInline(tokens);
@@ -241,8 +247,8 @@ export async function markdownToMarkdownV2(s: string): Promise<string> {
241247
renderer.del = ({ tokens }) => `~${renderer.parser.parseInline(tokens)}~`;
242248

243249
renderer.link = ({ href, tokens }) =>
244-
`[${renderer.parser.parseInline(tokens)}](${escape(href)})`;
245-
renderer.image = ({ href, text }) => `[${escape(text)}](${escape(href)})`;
250+
`[${renderer.parser.parseInline(tokens)}](${escape(href, true)})`;
251+
renderer.image = ({ href, text }) => `[${escape(text)}](${escape(href, true)})`;
246252

247253
renderer.blockquote = ({ tokens }) => {
248254
const text = renderer.parser.parse(tokens).trim();

0 commit comments

Comments
 (0)