Skip to content

Commit a53997e

Browse files
RaisinTendanielleadams
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 <[email protected]> Reviewed-By: Daijiro Wachi <[email protected]> Reviewed-By: James M Snell <[email protected]>
1 parent edf8c6d commit a53997e

File tree

2 files changed

+51
-1
lines changed

2 files changed

+51
-1
lines changed

src/node_url.cc

+5-1
Original file line numberDiff line numberDiff line change
@@ -1429,7 +1429,7 @@ void URL::Parse(const char* input,
14291429
const char ch = p < end ? p[0] : kEOL;
14301430
bool special = (url->flags & URL_FLAGS_SPECIAL);
14311431
bool cannot_be_base;
1432-
const bool special_back_slash = (special && ch == '\\');
1432+
bool special_back_slash = (special && ch == '\\');
14331433

14341434
switch (state) {
14351435
case kSchemeStart:
@@ -1477,6 +1477,7 @@ void URL::Parse(const char* input,
14771477
url->flags &= ~URL_FLAGS_SPECIAL;
14781478
special = false;
14791479
}
1480+
special_back_slash = (special && ch == '\\');
14801481
buffer.clear();
14811482
if (has_state_override)
14821483
return;
@@ -1521,6 +1522,7 @@ void URL::Parse(const char* input,
15211522
url->flags &= ~URL_FLAGS_SPECIAL;
15221523
special = false;
15231524
}
1525+
special_back_slash = (special && ch == '\\');
15241526
if (base->flags & URL_FLAGS_HAS_PATH) {
15251527
url->flags |= URL_FLAGS_HAS_PATH;
15261528
url->path = base->path;
@@ -1544,6 +1546,7 @@ void URL::Parse(const char* input,
15441546
url->flags |= URL_FLAGS_SPECIAL;
15451547
special = true;
15461548
state = kFile;
1549+
special_back_slash = (special && ch == '\\');
15471550
continue;
15481551
}
15491552
break;
@@ -1573,6 +1576,7 @@ void URL::Parse(const char* input,
15731576
url->flags &= ~URL_FLAGS_SPECIAL;
15741577
special = false;
15751578
}
1579+
special_back_slash = (special && ch == '\\');
15761580
switch (ch) {
15771581
case kEOL:
15781582
if (base->flags & URL_FLAGS_HAS_USERNAME) {

test/cctest/test_url.cc

+46
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)