Skip to content

Commit 096ef0b

Browse files
committed
Do not trim each forward slash when not required.
1 parent 6dea973 commit 096ef0b

File tree

2 files changed

+21
-8
lines changed

2 files changed

+21
-8
lines changed

src/lib.rs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -455,13 +455,15 @@ impl Url {
455455

456456
if self.slice(self.scheme_end + 1..).starts_with("//") {
457457
// URL with authority
458-
match self.byte_at(self.username_end) {
459-
b':' => {
460-
assert!(self.host_start >= self.username_end + 2);
461-
assert_eq!(self.byte_at(self.host_start - 1), b'@');
458+
if self.username_end < self.serialization.len() as u32 {
459+
match self.byte_at(self.username_end) {
460+
b':' => {
461+
assert!(self.host_start >= self.username_end + 2);
462+
assert_eq!(self.byte_at(self.host_start - 1), b'@');
463+
}
464+
b'@' => assert!(self.host_start == self.username_end + 1),
465+
_ => assert_eq!(self.username_end, self.scheme_end + 3),
462466
}
463-
b'@' => assert!(self.host_start == self.username_end + 1),
464-
_ => assert_eq!(self.username_end, self.scheme_end + 3),
465467
}
466468
assert!(self.host_start >= self.username_end);
467469
assert!(self.host_end >= self.host_start);

src/parser.rs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -422,7 +422,11 @@ impl<'a> Parser<'a> {
422422
.collect::<String>()
423423
!= "//"
424424
});
425-
self.after_double_slash(remaining, scheme_type, scheme_end)
425+
if let Some(after_prefix) = input.split_prefix("//") {
426+
return self.after_double_slash(after_prefix, scheme_type, scheme_end);
427+
} else {
428+
self.after_double_slash(remaining, scheme_type, scheme_end)
429+
}
426430
}
427431
SchemeType::NotSpecial => self.parse_non_special(input, scheme_type, scheme_end),
428432
}
@@ -735,6 +739,9 @@ impl<'a> Parser<'a> {
735739
debug_assert!(base_url.byte_at(scheme_end) == b':');
736740
self.serialization
737741
.push_str(base_url.slice(..scheme_end + 1));
742+
if let Some(after_prefix) = input.split_prefix("//") {
743+
return self.after_double_slash(after_prefix, scheme_type, scheme_end);
744+
}
738745
return self.after_double_slash(remaining, scheme_type, scheme_end);
739746
}
740747
let path_start = base_url.path_start;
@@ -1132,7 +1139,11 @@ impl<'a> Parser<'a> {
11321139
".." | "%2e%2e" | "%2e%2E" | "%2E%2e" | "%2E%2E" | "%2e." | "%2E." | ".%2e"
11331140
| ".%2E" => {
11341141
debug_assert!(self.serialization.as_bytes()[segment_start - 1] == b'/');
1135-
self.serialization.truncate(segment_start - 1); // Truncate "/../"
1142+
if ends_with_slash {
1143+
self.serialization.truncate(segment_start - 1); // Truncate "/../"
1144+
} else {
1145+
self.serialization.truncate(segment_start); // Truncate ".."
1146+
}
11361147
self.pop_path(scheme_type, path_start);
11371148
// and then if neither c is U+002F (/), nor url is special and c is U+005C (\), append the empty string to url’s path.
11381149
if ends_with_slash && !self.serialization.ends_with("/") {

0 commit comments

Comments
 (0)