Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update port on scheme change + host parsing rules to the host setter + hash parsing rules #523

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 24 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1569,10 +1569,25 @@ impl Url {
if host == "" && SchemeType::from(self.scheme()).is_special() {
return Err(ParseError::EmptyHost);
}
let mut host_substr = host;
// Otherwise, if c is U+003A (:) and the [] flag is unset, then
if !host.starts_with('[') || !host.ends_with(']') {
match host.find(':') {
Some(0) => {
// If buffer is the empty string, validation error, return failure.
return Err(ParseError::InvalidDomainCharacter);
}
// Let host be the result of host parsing buffer
Some(colon_index) => {
host_substr = &host[..colon_index];
}
None => {}
}
}
if SchemeType::from(self.scheme()).is_special() {
self.set_host_internal(Host::parse(host)?, None)
self.set_host_internal(Host::parse(host_substr)?, None);
} else {
self.set_host_internal(Host::parse_opaque(host)?, None)
self.set_host_internal(Host::parse_opaque(host_substr)?, None);
}
} else if self.has_host() {
if SchemeType::from(self.scheme()).is_special() {
Expand Down Expand Up @@ -1954,6 +1969,13 @@ impl Url {

parser.serialization.push_str(self.slice(old_scheme_end..));
self.serialization = parser.serialization;

// Update the port so it can be removed
// If it is the scheme's default
// We don't mind it silently failing
// If there was no port in the first place
let _ = self.set_port(self.port());

Ok(())
}

Expand Down
25 changes: 15 additions & 10 deletions src/quirks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,9 +111,13 @@ pub fn set_host(url: &mut Url, new_host: &str) -> Result<(), ()> {
Ok((h, remaining)) => {
host = h;
opt_port = if let Some(remaining) = remaining.split_prefix(':') {
Parser::parse_port(remaining, || default_port(scheme), Context::Setter)
.ok()
.map(|(port, _remaining)| port)
if remaining.is_empty() {
None
} else {
Parser::parse_port(remaining, || default_port(scheme), Context::Setter)
.ok()
.map(|(port, _remaining)| port)
}
} else {
None
};
Expand Down Expand Up @@ -208,13 +212,14 @@ pub fn hash(url: &Url) -> &str {

/// Setter for https://url.spec.whatwg.org/#dom-url-hash
pub fn set_hash(url: &mut Url, new_hash: &str) {
if url.scheme() != "javascript" {
url.set_fragment(match new_hash {
"" => None,
_ if new_hash.starts_with('#') => Some(&new_hash[1..]),
_ => Some(new_hash),
})
}
url.set_fragment(match new_hash {
// If the given value is the empty string,
// then set context object’s url’s fragment to null and return.
"" => None,
// Let input be the given value with a single leading U+0023 (#) removed, if any.
_ if new_hash.starts_with('#') => Some(&new_hash[1..]),
_ => Some(new_hash),
})
}

fn trim(s: &str) -> &str {
Expand Down