Skip to content

Commit 1f7dbe0

Browse files
authored
Merge pull request #848 from lucacasonato/fix_trailing_space_pathname_setter
Fix trailing spaces in scheme / pathname / search setters
2 parents 93b8e2f + 4d3e9e9 commit 1f7dbe0

File tree

5 files changed

+75
-18
lines changed

5 files changed

+75
-18
lines changed

url/src/lib.rs

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1486,7 +1486,7 @@ impl Url {
14861486
if let Some(input) = fragment {
14871487
self.fragment_start = Some(to_u32(self.serialization.len()).unwrap());
14881488
self.serialization.push('#');
1489-
self.mutate(|parser| parser.parse_fragment(parser::Input::no_trim(input)))
1489+
self.mutate(|parser| parser.parse_fragment(parser::Input::new_no_trim(input)))
14901490
} else {
14911491
self.fragment_start = None;
14921492
self.strip_trailing_spaces_from_opaque_path();
@@ -1549,7 +1549,7 @@ impl Url {
15491549
parser.parse_query(
15501550
scheme_type,
15511551
scheme_end,
1552-
parser::Input::trim_tab_and_newlines(input, vfn),
1552+
parser::Input::new_trim_tab_and_newlines(input, vfn),
15531553
)
15541554
});
15551555
} else {
@@ -1670,10 +1670,14 @@ impl Url {
16701670
parser.serialization.push_str("%2F");
16711671
path = &path[1..];
16721672
}
1673-
parser.parse_cannot_be_a_base_path(parser::Input::new(path));
1673+
parser.parse_cannot_be_a_base_path(parser::Input::new_no_trim(path));
16741674
} else {
16751675
let mut has_host = true; // FIXME
1676-
parser.parse_path_start(scheme_type, &mut has_host, parser::Input::new(path));
1676+
parser.parse_path_start(
1677+
scheme_type,
1678+
&mut has_host,
1679+
parser::Input::new_no_trim(path),
1680+
);
16771681
}
16781682
});
16791683
self.restore_after_path(old_after_path_pos, &after_path);
@@ -2343,7 +2347,7 @@ impl Url {
23432347
#[allow(clippy::result_unit_err, clippy::suspicious_operation_groupings)]
23442348
pub fn set_scheme(&mut self, scheme: &str) -> Result<(), ()> {
23452349
let mut parser = Parser::for_setter(String::new());
2346-
let remaining = parser.parse_scheme(parser::Input::new(scheme))?;
2350+
let remaining = parser.parse_scheme(parser::Input::new_no_trim(scheme))?;
23472351
let new_scheme_type = SchemeType::from(&parser.serialization);
23482352
let old_scheme_type = SchemeType::from(self.scheme());
23492353
// If url’s scheme is a special scheme and buffer is not a special scheme, then return.

url/src/parser.rs

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -184,17 +184,13 @@ pub struct Input<'i> {
184184
}
185185

186186
impl<'i> Input<'i> {
187-
pub fn new(input: &'i str) -> Self {
188-
Input::with_log(input, None)
189-
}
190-
191-
pub fn no_trim(input: &'i str) -> Self {
187+
pub fn new_no_trim(input: &'i str) -> Self {
192188
Input {
193189
chars: input.chars(),
194190
}
195191
}
196192

197-
pub fn trim_tab_and_newlines(
193+
pub fn new_trim_tab_and_newlines(
198194
original_input: &'i str,
199195
vfn: Option<&dyn Fn(SyntaxViolation)>,
200196
) -> Self {
@@ -212,7 +208,10 @@ impl<'i> Input<'i> {
212208
}
213209
}
214210

215-
pub fn with_log(original_input: &'i str, vfn: Option<&dyn Fn(SyntaxViolation)>) -> Self {
211+
pub fn new_trim_c0_control_and_space(
212+
original_input: &'i str,
213+
vfn: Option<&dyn Fn(SyntaxViolation)>,
214+
) -> Self {
216215
let input = original_input.trim_matches(c0_control_or_space);
217216
if let Some(vfn) = vfn {
218217
if input.len() < original_input.len() {
@@ -362,7 +361,7 @@ impl<'a> Parser<'a> {
362361

363362
/// https://url.spec.whatwg.org/#concept-basic-url-parser
364363
pub fn parse_url(mut self, input: &str) -> ParseResult<Url> {
365-
let input = Input::with_log(input, self.violation_fn);
364+
let input = Input::new_trim_c0_control_and_space(input, self.violation_fn);
366365
if let Ok(remaining) = self.parse_scheme(input.clone()) {
367366
return self.parse_with_scheme(remaining);
368367
}

url/src/path_segments.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,7 @@ impl<'a> PathSegmentsMut<'a> {
237237
scheme_type,
238238
&mut has_host,
239239
path_start,
240-
parser::Input::new(segment),
240+
parser::Input::new_no_trim(segment),
241241
);
242242
}
243243
});

url/src/quirks.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ pub fn set_host(url: &mut Url, new_host: &str) -> Result<(), ()> {
152152
}
153153
// Host parsing rules are strict,
154154
// We don't want to trim the input
155-
let input = Input::no_trim(new_host);
155+
let input = Input::new_no_trim(new_host);
156156
let host;
157157
let opt_port;
158158
{
@@ -203,7 +203,7 @@ pub fn set_hostname(url: &mut Url, new_hostname: &str) -> Result<(), ()> {
203203
return Err(());
204204
}
205205
// Host parsing rules are strict we don't want to trim the input
206-
let input = Input::no_trim(new_hostname);
206+
let input = Input::new_no_trim(new_hostname);
207207
let scheme_type = SchemeType::from(url.scheme());
208208
if scheme_type == SchemeType::File && new_hostname.is_empty() {
209209
url.set_host_internal(Host::Domain(String::new()), None);
@@ -249,7 +249,7 @@ pub fn set_port(url: &mut Url, new_port: &str) -> Result<(), ()> {
249249
return Err(());
250250
}
251251
result = Parser::parse_port(
252-
Input::new(new_port),
252+
Input::new_no_trim(new_port),
253253
|| default_port(scheme),
254254
Context::Setter,
255255
)

url/tests/setters_tests.json

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"comment": [
3-
"AS OF https://github.com/jsdom/whatwg-url/commit/35f04dfd3048cf6362f4398745bb13375c5020c2",
3+
"AS OF https://github.com/web-platform-tests/wpt/blob/09b34ae130cd946e111cd427d6bcf2d6f257aed8/url/resources/setters_tests.json, but only passing tests",
44
"## Tests for setters of https://url.spec.whatwg.org/#urlutils-members",
55
"",
66
"This file contains a JSON object.",
@@ -1653,6 +1653,24 @@
16531653
"href": "file:///",
16541654
"pathname": "/"
16551655
}
1656+
},
1657+
{
1658+
"comment": "Trailing space should be encoded",
1659+
"href": "http://example.net",
1660+
"new_value": " ",
1661+
"expected": {
1662+
"href": "http://example.net/%20",
1663+
"pathname": "/%20"
1664+
}
1665+
},
1666+
{
1667+
"comment": "Trailing C0 control should be encoded",
1668+
"href": "http://example.net",
1669+
"new_value": "\u0000",
1670+
"expected": {
1671+
"href": "http://example.net/%00",
1672+
"pathname": "/%00"
1673+
}
16561674
}
16571675
],
16581676
"search": [
@@ -1737,6 +1755,24 @@
17371755
"href": "http://example.net/?%c3%89t%C3%A9",
17381756
"search": "?%c3%89t%C3%A9"
17391757
}
1758+
},
1759+
{
1760+
"comment": "Trailing space should be encoded",
1761+
"href": "http://example.net",
1762+
"new_value": " ",
1763+
"expected": {
1764+
"href": "http://example.net/?%20",
1765+
"search": "?%20"
1766+
}
1767+
},
1768+
{
1769+
"comment": "Trailing C0 control should be encoded",
1770+
"href": "http://example.net",
1771+
"new_value": "\u0000",
1772+
"expected": {
1773+
"href": "http://example.net/?%00",
1774+
"search": "?%00"
1775+
}
17401776
}
17411777
],
17421778
"hash": [
@@ -1871,6 +1907,24 @@
18711907
"href": "javascript:alert(1)#castle",
18721908
"hash": "#castle"
18731909
}
1910+
},
1911+
{
1912+
"comment": "Trailing space should be encoded",
1913+
"href": "http://example.net",
1914+
"new_value": " ",
1915+
"expected": {
1916+
"href": "http://example.net/#%20",
1917+
"hash": "#%20"
1918+
}
1919+
},
1920+
{
1921+
"comment": "Trailing C0 control should be encoded",
1922+
"href": "http://example.net",
1923+
"new_value": "\u0000",
1924+
"expected": {
1925+
"href": "http://example.net/#%00",
1926+
"hash": "#%00"
1927+
}
18741928
}
18751929
]
18761930
}

0 commit comments

Comments
 (0)