Skip to content

Commit 762712d

Browse files
authored
fix: handle consecutive backslashes in no-reference-like-urls (#523)
* wip * wip
1 parent f80a9e1 commit 762712d

File tree

2 files changed

+148
-2
lines changed

2 files changed

+148
-2
lines changed

src/rules/no-reference-like-urls.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import { findOffsets } from "../util.js";
1616

1717
/**
1818
* @import { SourceRange } from "@eslint/core"
19-
* @import { Heading, Node, Paragraph, TableCell } from "mdast";
19+
* @import { Heading, Paragraph, TableCell } from "mdast";
2020
* @import { MarkdownRuleDefinition } from "../types.js";
2121
* @typedef {"referenceLikeUrl"} NoReferenceLikeUrlMessageIds
2222
* @typedef {[]} NoReferenceLikeUrlOptions
@@ -29,7 +29,7 @@ import { findOffsets } from "../util.js";
2929

3030
/** Pattern to match both inline links: `[text](url)` and images: `![alt](url)`, with optional title */
3131
const linkOrImagePattern =
32-
/(?<!(?<!\\)\\)(?<imageBang>!)?\[(?<label>(?:\\.|[^()\\]|\([\s\S]*\))*?)\]\((?<destination>[ \t]*(?:\r\n?|\n)?(?<![ \t])[ \t]*(?:<[^>]*>|[^ \t()]+))(?:[ \t]*(?:\r\n?|\n)?(?<![ \t])[ \t]*(?<title>"[^"]*"|'[^']*'|\([^)]*\)))?[ \t]*(?:\r\n?|\n)?(?<![ \t])[ \t]*\)(?!\()/gu;
32+
/(?<=(?<!\\)(?:\\{2})*)(?<imageBang>!)?\[(?<label>(?:\\.|[^()\\]|\([\s\S]*\))*?)\]\((?<destination>[ \t]*(?:\r\n?|\n)?(?<![ \t])[ \t]*(?:<[^>]*>|[^ \t()]+))(?:[ \t]*(?:\r\n?|\n)?(?<![ \t])[ \t]*(?<title>"[^"]*"|'[^']*'|\([^)]*\)))?[ \t]*(?:\r\n?|\n)?(?<![ \t])[ \t]*\)(?!\()/gu;
3333

3434
/**
3535
* Checks if a given index is within any skip range.

tests/rules/no-reference-like-urls.test.js

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,11 @@ ruleTester.run("no-reference-like-urls", rule, {
155155
`,
156156
language: "markdown/gfm",
157157
},
158+
// Backslash escaping
159+
`${"\\".repeat(1)}[Mercury](mercury)\n\n[mercury]: https://example.com/mercury`,
160+
`${"\\".repeat(3)}[Mercury](mercury)\n\n[mercury]: https://example.com/mercury`,
161+
`${"\\".repeat(5)}[Mercury](mercury)\n\n[mercury]: https://example.com/mercury`,
162+
`${"\\".repeat(7)}[Mercury](mercury)\n\n[mercury]: https://example.com/mercury`,
158163
],
159164
invalid: [
160165
{
@@ -1168,6 +1173,147 @@ ruleTester.run("no-reference-like-urls", rule, {
11681173
},
11691174
],
11701175
},
1176+
// Backslash escaping
1177+
{
1178+
code: `${"\\".repeat(1)}![Mercury](mercury)\n\n[mercury]: https://example.com/mercury`,
1179+
output: `${"\\".repeat(1)}![Mercury][mercury]\n\n[mercury]: https://example.com/mercury`,
1180+
errors: [
1181+
{
1182+
messageId: "referenceLikeUrl",
1183+
data: { type: "link", prefix: "" },
1184+
line: 1,
1185+
column: 3,
1186+
endLine: 1,
1187+
endColumn: 21,
1188+
},
1189+
],
1190+
},
1191+
{
1192+
code: `${"\\".repeat(3)}![Mercury](mercury)\n\n[mercury]: https://example.com/mercury`,
1193+
output: `${"\\".repeat(3)}![Mercury][mercury]\n\n[mercury]: https://example.com/mercury`,
1194+
errors: [
1195+
{
1196+
messageId: "referenceLikeUrl",
1197+
data: { type: "link", prefix: "" },
1198+
line: 1,
1199+
column: 5,
1200+
endLine: 1,
1201+
endColumn: 23,
1202+
},
1203+
],
1204+
},
1205+
{
1206+
code: `${"\\".repeat(5)}![Mercury](mercury)\n\n[mercury]: https://example.com/mercury`,
1207+
output: `${"\\".repeat(5)}![Mercury][mercury]\n\n[mercury]: https://example.com/mercury`,
1208+
errors: [
1209+
{
1210+
messageId: "referenceLikeUrl",
1211+
data: { type: "link", prefix: "" },
1212+
line: 1,
1213+
column: 7,
1214+
endLine: 1,
1215+
endColumn: 25,
1216+
},
1217+
],
1218+
},
1219+
{
1220+
code: `${"\\".repeat(7)}![Mercury](mercury)\n\n[mercury]: https://example.com/mercury`,
1221+
output: `${"\\".repeat(7)}![Mercury][mercury]\n\n[mercury]: https://example.com/mercury`,
1222+
errors: [
1223+
{
1224+
messageId: "referenceLikeUrl",
1225+
data: { type: "link", prefix: "" },
1226+
line: 1,
1227+
column: 9,
1228+
endLine: 1,
1229+
endColumn: 27,
1230+
},
1231+
],
1232+
},
1233+
{
1234+
code: `${"\\".repeat(2)}[Mercury](mercury)\n\n[mercury]: https://example.com/mercury`,
1235+
output: `${"\\".repeat(2)}[Mercury][mercury]\n\n[mercury]: https://example.com/mercury`,
1236+
errors: [
1237+
{
1238+
messageId: "referenceLikeUrl",
1239+
data: { type: "link", prefix: "" },
1240+
line: 1,
1241+
column: 3,
1242+
endLine: 1,
1243+
endColumn: 21,
1244+
},
1245+
],
1246+
},
1247+
{
1248+
code: `${"\\".repeat(4)}[Mercury](mercury)\n\n[mercury]: https://example.com/mercury`,
1249+
output: `${"\\".repeat(4)}[Mercury][mercury]\n\n[mercury]: https://example.com/mercury`,
1250+
errors: [
1251+
{
1252+
messageId: "referenceLikeUrl",
1253+
data: { type: "link", prefix: "" },
1254+
line: 1,
1255+
column: 5,
1256+
endLine: 1,
1257+
endColumn: 23,
1258+
},
1259+
],
1260+
},
1261+
{
1262+
code: `${"\\".repeat(6)}[Mercury](mercury)\n\n[mercury]: https://example.com/mercury`,
1263+
output: `${"\\".repeat(6)}[Mercury][mercury]\n\n[mercury]: https://example.com/mercury`,
1264+
errors: [
1265+
{
1266+
messageId: "referenceLikeUrl",
1267+
data: { type: "link", prefix: "" },
1268+
line: 1,
1269+
column: 7,
1270+
endLine: 1,
1271+
endColumn: 25,
1272+
},
1273+
],
1274+
},
1275+
{
1276+
code: `${"\\".repeat(2)}![Mercury](mercury)\n\n[mercury]: https://example.com/mercury`,
1277+
output: `${"\\".repeat(2)}![Mercury][mercury]\n\n[mercury]: https://example.com/mercury`,
1278+
errors: [
1279+
{
1280+
messageId: "referenceLikeUrl",
1281+
data: { type: "image", prefix: "!" },
1282+
line: 1,
1283+
column: 3,
1284+
endLine: 1,
1285+
endColumn: 22,
1286+
},
1287+
],
1288+
},
1289+
{
1290+
code: `${"\\".repeat(4)}![Mercury](mercury)\n\n[mercury]: https://example.com/mercury`,
1291+
output: `${"\\".repeat(4)}![Mercury][mercury]\n\n[mercury]: https://example.com/mercury`,
1292+
errors: [
1293+
{
1294+
messageId: "referenceLikeUrl",
1295+
data: { type: "image", prefix: "!" },
1296+
line: 1,
1297+
column: 5,
1298+
endLine: 1,
1299+
endColumn: 24,
1300+
},
1301+
],
1302+
},
1303+
{
1304+
code: `${"\\".repeat(6)}![Mercury](mercury)\n\n[mercury]: https://example.com/mercury`,
1305+
output: `${"\\".repeat(6)}![Mercury][mercury]\n\n[mercury]: https://example.com/mercury`,
1306+
errors: [
1307+
{
1308+
messageId: "referenceLikeUrl",
1309+
data: { type: "image", prefix: "!" },
1310+
line: 1,
1311+
column: 7,
1312+
endLine: 1,
1313+
endColumn: 26,
1314+
},
1315+
],
1316+
},
11711317
// This test case is skipped for non-Node environments like Bun
11721318
...(typeof process !== "undefined" &&
11731319
process.release?.name === "node" &&

0 commit comments

Comments
 (0)