Fix escaped character in links (#19849)

Co-authored-by: fisker <lionkay@gmail.com>
This commit is contained in:
Miodrag Obradovicandfisker authored and GitHub committed 2026-08-19 06:42:23 +08:00
1 parent 682af374c3
commit 518eb6a18f
4 files changed
+108

No files matched your search

+16
View File
@@ -0,0 +1,16 @@
#### Fix escaped character in links (#19849 by @Kjubikstronk)
<!-- prettier-ignore -->
```markdown
<!-- Input -->
[test](/hello?foo&quot\;bar)
<!-- Prettier stable (First format) -->
[test](/hello?foo&quot;bar)
<!-- Prettier stable (Second format) -->
[test](/hello?foo"bar)
<!-- Prettier main -->
[test](/hello?foo\&quot;bar)
```
+8
View File
@@ -478,6 +478,11 @@ function shouldRemainTheSameContent(path) {
);
}
// https://spec.commonmark.org/0.31.2/#entity-and-numeric-character-references
const characterReferenceRegex = /&(?=(?:#x[\da-f]+|#\d+|[\da-z]+);)/gi;
const escapeCharacterReferences = (value) =>
value.replaceAll(characterReferenceRegex, String.raw`\&`);
/**
* @param {string} url
* @param {boolean} unwrapBalancedParens
@@ -487,6 +492,7 @@ function printUrl(url, unwrapBalancedParens) {
// Backslash followed by ASCII punctuation would be misinterpreted as an
// escape sequence, so must itself be escaped.
url = url.replaceAll(/\\(?![^!"#$%&'()*+,\-./:;<=>?@[\\\]^_`{|}~])/g, "\\\\");
url = escapeCharacterReferences(url);
// CommonMark forbids ASCII controls, space, unbalanced parentheses, and
// initial <, unless wrapped in <> with any inner < or > escaped. CommonMark
@@ -526,11 +532,13 @@ function printTitle(title, options, printSpace = true) {
!title.includes(")")
) {
title = title.replaceAll("\\", "\\\\");
title = escapeCharacterReferences(title);
return `(${title})`; // avoid escaped quotes
}
const quote = getPreferredQuote(title, options.singleQuote);
title = title.replaceAll("\\", "\\\\");
title = title.replaceAll(quote, `\\${quote}`);
title = escapeCharacterReferences(title);
return `${quote}${title}${quote}`;
}
@@ -141,9 +141,65 @@ proseWrap: "always"
=====================================input======================================
[Test](http://localhost:8080/test?language=DE&currency=EUR)
[Test](/a?x&quot\\;b)
[Test](/a?x&#34\\;b)
[Test](/a?x&#x22\\;b)
![Test](/a?x&quot\\;b)
[Test](/a "x&quot\\;b")
[Test](</a b?x&quot\\;c>)
[Test]: /a?x&quot\\;b
[Test](/a?x\\&amp;b)
[Test](/a?x\\&amp;quot;b)
[Test](/a "x\\&amp;b")
[Test](/a "x\\&amp;quot;b")
[Test](/a?x&amp;b)
[Test](/a?x&amp;quot;b)
[Test](/a "/a?x&amp;quot;b")
=====================================output=====================================
[Test](http://localhost:8080/test?language=DE&currency=EUR)
[Test](/a?x\\&quot;b)
[Test](/a?x\\&#34;b)
[Test](/a?x\\&#x22;b)
![Test](/a?x\\&quot;b)
[Test](/a "x\\&quot;b")
[Test](</a b?x\\&quot;c>)
[Test]: /a?x\\&quot;b
[Test](/a?x\\&amp;b)
[Test](/a?x\\&amp;quot;b)
[Test](/a "x\\&amp;b")
[Test](/a "x\\&amp;quot;b")
[Test](/a?x&b)
[Test](/a?x\\&quot;b)
[Test](/a "/a?x\\&quot;b")
================================================================================
`;
+28
View File
@@ -1 +1,29 @@
[Test](http://localhost:8080/test?language=DE&currency=EUR)
[Test](/a?x&quot\;b)
[Test](/a?x&#34\;b)
[Test](/a?x&#x22\;b)
![Test](/a?x&quot\;b)
[Test](/a "x&quot\;b")
[Test](</a b?x&quot\;c>)
[Test]: /a?x&quot\;b
[Test](/a?x\&amp;b)
[Test](/a?x\&amp;quot;b)
[Test](/a "x\&amp;b")
[Test](/a "x\&amp;quot;b")
[Test](/a?x&amp;b)
[Test](/a?x&amp;quot;b)
[Test](/a "/a?x&amp;quot;b")