Skip to content

Commit dcba374

Browse files
RaisinTentargos
authored andcommitted
src: fix leading backslash bug in URL
The associated condition mentioned in the URL parsing algorithm of the WHATWG URL Standard is: url is special and c is U+005C (\) So, `special_back_slash` must be updated whenever `special` is updated. Fixes: #36559 PR-URL: #36613 Reviewed-By: Rich Trott <rtrott@gmail.com> Reviewed-By: Daijiro Wachi <daijiro.wachi@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
1 parent fe6e5e4 commit dcba374

File tree

2 files changed

+51
-1
lines changed

2 files changed

+51
-1
lines changed

src/node_url.cc

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1426,7 +1426,7 @@ void URL::Parse(const char* input,
14261426
const char ch = p < end ? p[0] : kEOL;
14271427
bool special = (url->flags & URL_FLAGS_SPECIAL);
14281428
bool cannot_be_base;
1429-
const bool special_back_slash = (special && ch == '\\');
1429+
bool special_back_slash = (special && ch == '\\');
14301430

14311431
switch (state) {
14321432
case kSchemeStart:
@@ -1476,6 +1476,7 @@ void URL::Parse(const char* input,
14761476
url->flags &= ~URL_FLAGS_SPECIAL;
14771477
special = false;
14781478
}
1479+
special_back_slash = (special && ch == '\\');
14791480
buffer.clear();
14801481
if (has_state_override)
14811482
return;
@@ -1520,6 +1521,7 @@ void URL::Parse(const char* input,
15201521
url->flags &= ~URL_FLAGS_SPECIAL;
15211522
special = false;
15221523
}
1524+
special_back_slash = (special && ch == '\\');
15231525
if (base->flags & URL_FLAGS_HAS_PATH) {
15241526
url->flags |= URL_FLAGS_HAS_PATH;
15251527
url->path = base->path;
@@ -1543,6 +1545,7 @@ void URL::Parse(const char* input,
15431545
url->flags |= URL_FLAGS_SPECIAL;
15441546
special = true;
15451547
state = kFile;
1548+
special_back_slash = (special && ch == '\\');
15461549
continue;
15471550
}
15481551
break;
@@ -1572,6 +1575,7 @@ void URL::Parse(const char* input,
15721575
url->flags &= ~URL_FLAGS_SPECIAL;
15731576
special = false;
15741577
}
1578+
special_back_slash = (special && ch == '\\');
15751579
switch (ch) {
15761580
case kEOL:
15771581
if (base->flags & URL_FLAGS_HAS_USERNAME) {

test/cctest/test_url.cc

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,52 @@ TEST_F(URLTest, Base3) {
8181
EXPECT_EQ(simple.path(), "/baz");
8282
}
8383

84+
TEST_F(URLTest, Base4) {
85+
const char* input = "\\x";
86+
const char* base = "http://example.org/foo/bar";
87+
88+
URL simple(input, strlen(input), base, strlen(base));
89+
90+
EXPECT_FALSE(simple.flags() & URL_FLAGS_FAILED);
91+
EXPECT_EQ(simple.protocol(), "http:");
92+
EXPECT_EQ(simple.host(), "example.org");
93+
EXPECT_EQ(simple.path(), "/x");
94+
}
95+
96+
TEST_F(URLTest, Base5) {
97+
const char* input = "/x";
98+
const char* base = "http://example.org/foo/bar";
99+
100+
URL simple(input, strlen(input), base, strlen(base));
101+
102+
EXPECT_FALSE(simple.flags() & URL_FLAGS_FAILED);
103+
EXPECT_EQ(simple.protocol(), "http:");
104+
EXPECT_EQ(simple.host(), "example.org");
105+
EXPECT_EQ(simple.path(), "/x");
106+
}
107+
108+
TEST_F(URLTest, Base6) {
109+
const char* input = "\\\\x";
110+
const char* base = "http://example.org/foo/bar";
111+
112+
URL simple(input, strlen(input), base, strlen(base));
113+
114+
EXPECT_FALSE(simple.flags() & URL_FLAGS_FAILED);
115+
EXPECT_EQ(simple.protocol(), "http:");
116+
EXPECT_EQ(simple.host(), "x");
117+
}
118+
119+
TEST_F(URLTest, Base7) {
120+
const char* input = "//x";
121+
const char* base = "http://example.org/foo/bar";
122+
123+
URL simple(input, strlen(input), base, strlen(base));
124+
125+
EXPECT_FALSE(simple.flags() & URL_FLAGS_FAILED);
126+
EXPECT_EQ(simple.protocol(), "http:");
127+
EXPECT_EQ(simple.host(), "x");
128+
}
129+
84130
TEST_F(URLTest, TruncatedAfterProtocol) {
85131
char input[2] = { 'q', ':' };
86132
URL simple(input, sizeof(input));

0 commit comments

Comments
 (0)