Skip to content

Commit 78c2599

Browse files
committed
36 tests to go.
1 parent 0790da7 commit 78c2599

File tree

3 files changed

+59
-2
lines changed

3 files changed

+59
-2
lines changed

src/host.rs

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,52 @@ pub(crate) enum HostInternal {
2424
Ipv6(Ipv6Addr),
2525
}
2626

27-
impl<S> From<Host<S>> for HostInternal {
27+
#[cfg(feature = "serde")]
28+
impl ::serde::Serialize for HostInternal {
29+
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
30+
where
31+
S: ::serde::Serializer,
32+
{
33+
// This doesn’t use `derive` because that involves
34+
// large dependencies (that take a long time to build), and
35+
// either Macros 1.1 which are not stable yet or a cumbersome build script.
36+
//
37+
// Implementing `Serializer` correctly for an enum is tricky,
38+
// so let’s use existing enums that already do.
39+
use std::net::IpAddr;
40+
match *self {
41+
HostInternal::None => None,
42+
HostInternal::Domain => Some(None),
43+
HostInternal::Ipv4(addr) => Some(Some(IpAddr::V4(addr))),
44+
HostInternal::Ipv6(addr) => Some(Some(IpAddr::V6(addr))),
45+
}
46+
.serialize(serializer)
47+
}
48+
}
49+
50+
#[cfg(feature = "serde")]
51+
impl<'de> ::serde::Deserialize<'de> for HostInternal {
52+
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
53+
where
54+
D: ::serde::Deserializer<'de>,
55+
{
56+
use std::net::IpAddr;
57+
Ok(match ::serde::Deserialize::deserialize(deserializer)? {
58+
None => HostInternal::None,
59+
Some(None) => HostInternal::Domain,
60+
Some(Some(IpAddr::V4(addr))) => HostInternal::Ipv4(addr),
61+
Some(Some(IpAddr::V6(addr))) => HostInternal::Ipv6(addr),
62+
})
63+
}
64+
}
65+
66+
impl<S> From<Host<S>> for HostInternal
67+
where
68+
S: ToString,
69+
{
2870
fn from(host: Host<S>) -> HostInternal {
2971
match host {
72+
Host::Domain(ref s) if s.to_string().is_empty() => HostInternal::None,
3073
Host::Domain(_) => HostInternal::Domain,
3174
Host::Ipv4(address) => HostInternal::Ipv4(address),
3275
Host::Ipv6(address) => HostInternal::Ipv6(address),

src/parser.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -967,7 +967,7 @@ impl<'a> Parser<'a> {
967967
host_str = &input_str[..bytes]
968968
}
969969
}
970-
if scheme_type.is_special() && host_str.is_empty() {
970+
if scheme_type == SchemeType::SpecialNotFile && host_str.is_empty() {
971971
return Err(ParseError::EmptyHost);
972972
}
973973
if !scheme_type.is_special() {

src/quirks.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,20 @@ pub fn set_host(url: &mut Url, new_host: &str) -> Result<(), ()> {
122122
Err(_) => return Err(()),
123123
}
124124
}
125+
// Make sure we won't set an empty host to a url with a username or a port
126+
if host == Host::Domain("".to_string()) {
127+
if !username(&url).is_empty() {
128+
return Err(());
129+
}
130+
if let Some(p) = opt_port {
131+
if let Some(_) = p {
132+
return Err(());
133+
}
134+
}
135+
if url.port().is_some() {
136+
return Err(());
137+
}
138+
}
125139
url.set_host_internal(host, opt_port);
126140
Ok(())
127141
}

0 commit comments

Comments
 (0)