From 7690a55d0d205ee877696306aaa5ddda8430bb03 Mon Sep 17 00:00:00 2001 From: Mohamed Yassin Date: Wed, 3 Dec 2025 11:53:19 +0200 Subject: [PATCH] fix: use emoji regex to correctly mask pair emojis --- package-lock.json | 21 +++++++++++---------- package.json | 1 + src/Lexer.ts | 5 +++++ 3 files changed, 17 insertions(+), 10 deletions(-) diff --git a/package-lock.json b/package-lock.json index f63d677360..57ddda7609 100644 --- a/package-lock.json +++ b/package-lock.json @@ -24,6 +24,7 @@ "commonmark": "0.31.2", "cross-env": "^10.1.0", "dts-bundle-generator": "^9.5.1", + "emoji-regex": "^10.6.0", "esbuild": "^0.27.0", "esbuild-plugin-umd-wrapper": "^3.0.0", "eslint": "^9.39.1", @@ -3032,9 +3033,9 @@ } }, "node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz", + "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==", "dev": true, "license": "MIT" }, @@ -8613,13 +8614,6 @@ "node": ">=20" } }, - "node_modules/semantic-release/node_modules/emoji-regex": { - "version": "10.6.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz", - "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==", - "dev": true, - "license": "MIT" - }, "node_modules/semantic-release/node_modules/escape-string-regexp": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", @@ -9265,6 +9259,13 @@ "node": ">=8" } }, + "node_modules/string-width/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, "node_modules/strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", diff --git a/package.json b/package.json index b8a05d192b..a30375a4c2 100644 --- a/package.json +++ b/package.json @@ -60,6 +60,7 @@ "commonmark": "0.31.2", "cross-env": "^10.1.0", "dts-bundle-generator": "^9.5.1", + "emoji-regex": "^10.6.0", "esbuild": "^0.27.0", "esbuild-plugin-umd-wrapper": "^3.0.0", "eslint": "^9.39.1", diff --git a/src/Lexer.ts b/src/Lexer.ts index 89d439dc8c..eb3a351073 100644 --- a/src/Lexer.ts +++ b/src/Lexer.ts @@ -1,9 +1,12 @@ +import emojiRegex from 'emoji-regex'; import { _Tokenizer } from './Tokenizer.ts'; import { _defaults } from './defaults.ts'; import { other, block, inline } from './rules.ts'; import type { Token, TokensList, Tokens } from './Tokens.ts'; import type { MarkedOptions } from './MarkedOptions.ts'; +const emojiMatcher = emojiRegex(); + /** * Block Lexer */ @@ -330,6 +333,8 @@ export class _Lexer { // Mask out blocks from extensions maskedSrc = this.options.hooks?.emStrongMask?.call({ lexer: this }, maskedSrc) ?? maskedSrc; + maskedSrc = maskedSrc.replace(emojiMatcher, (m) => 'a'.repeat(m.length)); + let keepPrevChar = false; let prevChar = ''; while (src) {