Skip to content

Commit 401a892

Browse files
committed
Do not trim each forward slash when not required.
1 parent 9597bb3 commit 401a892

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
@@ -456,13 +456,15 @@ impl Url {
456456

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

src/parser.rs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -440,7 +440,11 @@ impl<'a> Parser<'a> {
440440
.collect::<String>()
441441
!= "//"
442442
});
443-
self.after_double_slash(remaining, scheme_type, scheme_end)
443+
if let Some(after_prefix) = input.split_prefix("//") {
444+
return self.after_double_slash(after_prefix, scheme_type, scheme_end);
445+
} else {
446+
self.after_double_slash(remaining, scheme_type, scheme_end)
447+
}
444448
}
445449
SchemeType::NotSpecial => self.parse_non_special(input, scheme_type, scheme_end),
446450
}
@@ -753,6 +757,9 @@ impl<'a> Parser<'a> {
753757
debug_assert!(base_url.byte_at(scheme_end) == b':');
754758
self.serialization
755759
.push_str(base_url.slice(..scheme_end + 1));
760+
if let Some(after_prefix) = input.split_prefix("//") {
761+
return self.after_double_slash(after_prefix, scheme_type, scheme_end);
762+
}
756763
return self.after_double_slash(remaining, scheme_type, scheme_end);
757764
}
758765
let path_start = base_url.path_start;
@@ -1150,7 +1157,11 @@ impl<'a> Parser<'a> {
11501157
".." | "%2e%2e" | "%2e%2E" | "%2E%2e" | "%2E%2E" | "%2e." | "%2E." | ".%2e"
11511158
| ".%2E" => {
11521159
debug_assert!(self.serialization.as_bytes()[segment_start - 1] == b'/');
1153-
self.serialization.truncate(segment_start - 1); // Truncate "/../"
1160+
if ends_with_slash {
1161+
self.serialization.truncate(segment_start - 1); // Truncate "/../"
1162+
} else {
1163+
self.serialization.truncate(segment_start); // Truncate ".."
1164+
}
11541165
self.pop_path(scheme_type, path_start);
11551166
// 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.
11561167
if ends_with_slash && !self.serialization.ends_with("/") {

0 commit comments

Comments
 (0)