diff --git a/changelog_unreleased/markdown/15400.md b/changelog_unreleased/markdown/15400.md new file mode 100644 index 000000000..9fe662a33 --- /dev/null +++ b/changelog_unreleased/markdown/15400.md @@ -0,0 +1,25 @@ +#### Encoding `<` and `>` in markdown urls (#15400 by @vivekjoshi556) + + +```md + +[link](https://www.google.fr/()foo->bar) + + +[link](bar>) + + +[link]() +``` + + +```md + +![link](bar>) + + +![link](bar>) + + +![link]() +``` diff --git a/src/language-markdown/clean.js b/src/language-markdown/clean.js index 5deb19f34..4cafc18b0 100644 --- a/src/language-markdown/clean.js +++ b/src/language-markdown/clean.js @@ -48,6 +48,16 @@ function clean(ast, newObj, parent) { newObj.label = collapseWhiteSpace(ast.label); } + if ( + (ast.type === "link" || ast.type === "image") && + ast.url && + ast.url.includes("(") + ) { + for (const character of "<>") { + newObj.url = ast.url.replaceAll(character, encodeURIComponent(character)); + } + } + if ( (ast.type === "definition" || ast.type === "link" || diff --git a/src/language-markdown/printer-markdown.js b/src/language-markdown/printer-markdown.js index d9d646229..249828d05 100644 --- a/src/language-markdown/printer-markdown.js +++ b/src/language-markdown/printer-markdown.js @@ -778,6 +778,13 @@ function shouldRemainTheSameContent(path) { ); } +const encodeUrl = (url, characters) => { + for (const character of characters) { + url = url.replaceAll(character, encodeURIComponent(character)); + } + return url; +}; + /** * @param {string} url * @param {string[] | string} [dangerousCharOrChars] @@ -790,8 +797,9 @@ function printUrl(url, dangerousCharOrChars = []) { ? dangerousCharOrChars : [dangerousCharOrChars]), ]; + return new RegExp(dangerousChars.map((x) => `\\${x}`).join("|")).test(url) - ? `<${url}>` + ? `<${encodeUrl(url, "<>")}>` : url; } diff --git a/tests/format/markdown/link/__snapshots__/jsfmt.spec.js.snap b/tests/format/markdown/link/__snapshots__/jsfmt.spec.js.snap index 0b6f604e2..d9f00f4cb 100644 --- a/tests/format/markdown/link/__snapshots__/jsfmt.spec.js.snap +++ b/tests/format/markdown/link/__snapshots__/jsfmt.spec.js.snap @@ -47,6 +47,83 @@ proseWrap: "always" ================================================================================ `; +exports[`encodedLink.md - {"proseWrap":"always","singleQuote":true} format 1`] = ` +====================================options===================================== +parsers: ["markdown"] +printWidth: 80 +proseWrap: "always" +singleQuote: true + | printWidth +=====================================input====================================== +[link](https://www.google.fr/()foo->bar) +[link](https://www.google.fr/foo->bar) +[link](https://www.google.fr/foo-%3Ebar) +[link](https://www.google.fr/foo-bar) +![link](https://www.google.fr/foo->bar) +![link](https://www.google.fr/foo-%3Ebar) +![link](https://www.google.fr/foo-bar +[link]: https://www.google.fr/foo->bar +[link]: https://www.google.fr/foo-%3Ebar +[link]: https://www.google.fr/foo-) +[link](https://www.google.fr/foo->bar) [link](https://www.google.fr/foo-%3Ebar) +[link](https://www.google.fr/foo-) +![link](https://www.google.fr/foo->bar) +![link](https://www.google.fr/foo-%3Ebar) +![link](https://www.google.fr/foo-bar [link]: https://www.google.fr/foo->bar [link]: +https://www.google.fr/foo-%3Ebar [link]: https://www.google.fr/foo-bar) +[link](https://www.google.fr/foo->bar) +[link](https://www.google.fr/foo-%3Ebar) +[link](https://www.google.fr/foo-bar) +![link](https://www.google.fr/foo->bar) +![link](https://www.google.fr/foo-%3Ebar) +![link](https://www.google.fr/foo-bar +[link]: https://www.google.fr/foo->bar +[link]: https://www.google.fr/foo-%3Ebar +[link]: https://www.google.fr/foo-) +[link](https://www.google.fr/foo->bar) [link](https://www.google.fr/foo-%3Ebar) +[link](https://www.google.fr/foo-) +![link](https://www.google.fr/foo->bar) +![link](https://www.google.fr/foo-%3Ebar) +![link](https://www.google.fr/foo-bar [link]: https://www.google.fr/foo->bar [link]: +https://www.google.fr/foo-%3Ebar [link]: https://www.google.fr/foo-bar) +[link](https://www.google.fr/foo->bar) +[link](https://www.google.fr/foo-%3Ebar) +[link](https://www.google.fr/foo-bar) +![link](https://www.google.fr/foo->bar) +![link](https://www.google.fr/foo-%3Ebar) +![link](https://www.google.fr/foo-bar +[link]: https://www.google.fr/foo->bar +[link]: https://www.google.fr/foo-%3Ebar +[link]: https://www.google.fr/foo-