diff --git a/src/lib/utils/url-link-converter.js b/src/lib/utils/url-link-converter.js index cff1cc1..8de7459 100644 --- a/src/lib/utils/url-link-converter.js +++ b/src/lib/utils/url-link-converter.js @@ -42,9 +42,12 @@ export function convertUrlsToLinks(text) { // Extract code blocks and replace with placeholders while ((codeMatch = codeBlockRegex.exec(text)) !== null) { - const placeholder = `__CODE_BLOCK_${codeIndex}__`; + const placeholder = createCodeBlockPlaceholder(text, codeIndex); const codeContent = codeMatch[1]; - codeBlocks.push(`
${escapeHtml(codeContent)}`);
+ codeBlocks.push({
+ placeholder,
+ html: `${escapeHtml(codeContent)}`
+ });
textWithPlaceholders = textWithPlaceholders.replace(codeMatch[0], placeholder);
codeIndex++;
}
@@ -86,10 +89,19 @@ export function convertUrlsToLinks(text) {
});
// Restore code blocks from placeholders
- codeBlocks.forEach((codeBlock, index) => {
- const placeholder = `__CODE_BLOCK_${index}__`;
- result = result.replace(placeholder, codeBlock);
+ codeBlocks.forEach((codeBlock) => {
+ result = result.replace(codeBlock.placeholder, codeBlock.html);
});
return result;
}
+
+function createCodeBlockPlaceholder(text, index) {
+ let suffix = 0;
+ let placeholder;
+ do {
+ placeholder = `\u0000QRYPTCHAT_CODE_BLOCK_${index}_${suffix}\u0000`;
+ suffix++;
+ } while (text.includes(placeholder));
+ return placeholder;
+}
diff --git a/tests/url-link-converter-placeholder.test.js b/tests/url-link-converter-placeholder.test.js
new file mode 100644
index 0000000..ec38899
--- /dev/null
+++ b/tests/url-link-converter-placeholder.test.js
@@ -0,0 +1,14 @@
+import assert from 'node:assert/strict';
+import { describe, it } from 'node:test';
+
+import { convertUrlsToLinks } from '../src/lib/utils/url-link-converter.js';
+
+describe('convertUrlsToLinks code block placeholders', () => {
+ it('does not replace user-authored placeholder-like text with code block HTML', () => {
+ const html = convertUrlsToLinks('literal __CODE_BLOCK_0__ here\n```js\nconsole.log(1)\n```');
+
+ assert.match(html, /literal __CODE_BLOCK_0__ here/);
+ assert.match(html, /js\nconsole\.log\(1\)\n<\/code><\/pre>/);
+ assert.doesNotMatch(html, /
__CODE_BLOCK_0__$/);
+ });
+});