Skip to content

Commit 5cb58ca

Browse files
authored
test: add null-byte escape test cases for '#' handling (#473)
1 parent 39d56d3 commit 5cb58ca

File tree

1 file changed

+48
-0
lines changed

1 file changed

+48
-0
lines changed

test/identifier.test.js

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,43 @@ describe("identifier", () => {
6666
run(tests);
6767
});
6868

69+
// Tests for https://github.com/webpack/webpack/issues/16819
70+
// To embed a literal '#' in a filesystem path, the caller must use the
71+
// '\0#' null-byte escape. Unescaped '#' always starts a fragment.
72+
describe("parse identifier. '#' escape with \\0", () => {
73+
/** @type {TestSuite[]} */
74+
const tests = [
75+
// '\0#' in path is unescaped to '#' (part of directory name), no fragment
76+
{
77+
input: "/home/user/projects/test\0#/webpack/src/file.js",
78+
expected: ["/home/user/projects/test#/webpack/src/file.js", "", ""],
79+
},
80+
// '\0#' dir name, with a real (unescaped) '#' fragment at the end
81+
{
82+
input: "/projects/test\0#app/src/file.js#fragment",
83+
expected: ["/projects/test#app/src/file.js", "", "#fragment"],
84+
},
85+
// Multiple '\0#' escapes in dir names, then a real fragment
86+
{
87+
input: "/a\0#b/c\0#d/file.js#hash",
88+
expected: ["/a#b/c#d/file.js", "", "#hash"],
89+
},
90+
// '\0#' dir name with both query and fragment
91+
{
92+
input: "/projects/test\0#app/file.js?query#fragment",
93+
expected: ["/projects/test#app/file.js", "?query", "#fragment"],
94+
},
95+
// Unescaped '#' mid-segment is still treated as a fragment start
96+
// (callers must escape '#' in paths via '\0#' — see webpack#16819)
97+
{
98+
input: "/home/user/projects/test#/webpack/src/file.js",
99+
expected: ["/home/user/projects/test", "", "#/webpack/src/file.js"],
100+
},
101+
];
102+
103+
run(tests);
104+
});
105+
69106
describe("parse identifier. Windows-like paths", () => {
70107
/** @type {TestSuite[]} */
71108
const tests = [
@@ -93,6 +130,17 @@ describe("identifier", () => {
93130
input: "path\\#/not/a/hash?not-a-query",
94131
expected: ["path\\", "", "#/not/a/hash?not-a-query"],
95132
},
133+
// Regression (webpack#16819): '\0#' null-byte escape correctly
134+
// embeds '#' in a Windows dir name (no fragment produced)
135+
{
136+
input: "C:\\Users\\test\0#proj\\webpack\\src\\file.js",
137+
expected: ["C:\\Users\\test#proj\\webpack\\src\\file.js", "", ""],
138+
},
139+
// Without escaping, '#' still starts a fragment (caller must escape)
140+
{
141+
input: "C:\\Users\\test#proj\\webpack\\src\\file.js",
142+
expected: ["C:\\Users\\test", "", "#proj\\webpack\\src\\file.js"],
143+
},
96144
];
97145

98146
run(tests);

0 commit comments

Comments
 (0)