Skip to content

Commit fd98554

Browse files
committed
Merge branch 'master' into no_std
2 parents b908f7f + 3a474c3 commit fd98554

File tree

13 files changed

+162
-34
lines changed

13 files changed

+162
-34
lines changed

.github/workflows/main.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ jobs:
5353
if: |
5454
matrix.os == 'windows-latest' &&
5555
matrix.rust == 'nightly'
56-
run: cargo test --test debugger_visualizer --features "url/serde,url/debugger_visualizer" -- --test-threads=1
56+
run: cargo test --test debugger_visualizer --features "url/debugger_visualizer,url_debug_tests/debugger_visualizer" -- --test-threads=1
5757
- name: Test `no_std` support
5858
run: cargo test --no-default-features --features=alloc,no_std_net
5959

Cargo.toml

+8-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,9 @@
11
[workspace]
2-
members = ["url", "form_urlencoded", "idna", "percent_encoding", "data-url"]
2+
members = [
3+
"url",
4+
"form_urlencoded",
5+
"idna",
6+
"percent_encoding",
7+
"data-url",
8+
"url_debug_tests",
9+
]

data-url/src/forgiving_base64.rs

+28
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,26 @@
11
//! <https://infra.spec.whatwg.org/#forgiving-base64-decode>
22
33
use alloc::vec::Vec;
4+
use core::fmt;
45

56
#[derive(Debug)]
67
pub struct InvalidBase64(InvalidBase64Details);
78

9+
impl fmt::Display for InvalidBase64 {
10+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
11+
match self.0 {
12+
InvalidBase64Details::UnexpectedSymbol(code_point) => {
13+
write!(f, "symbol with codepoint {} not expected", code_point)
14+
}
15+
InvalidBase64Details::AlphabetSymbolAfterPadding => {
16+
write!(f, "alphabet symbol present after padding")
17+
}
18+
InvalidBase64Details::LoneAlphabetSymbol => write!(f, "lone alphabet symbol present"),
19+
InvalidBase64Details::Padding => write!(f, "incorrect padding"),
20+
}
21+
}
22+
}
23+
824
#[derive(Debug)]
925
enum InvalidBase64Details {
1026
UnexpectedSymbol(u8),
@@ -19,6 +35,18 @@ pub enum DecodeError<E> {
1935
WriteError(E),
2036
}
2137

38+
impl<E: fmt::Display> fmt::Display for DecodeError<E> {
39+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
40+
match self {
41+
Self::InvalidBase64(inner) => write!(f, "base64 not valid: {}", inner),
42+
Self::WriteError(err) => write!(f, "write error: {}", err),
43+
}
44+
}
45+
}
46+
47+
#[cfg(feature = "std")]
48+
impl<E: std::error::Error> std::error::Error for DecodeError<E> {}
49+
2250
impl<E> From<InvalidBase64Details> for DecodeError<E> {
2351
fn from(e: InvalidBase64Details) -> Self {
2452
DecodeError::InvalidBase64(InvalidBase64(e))

data-url/src/lib.rs

+17-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818

1919
// For forwards compatibility
2020
#[cfg(feature = "std")]
21-
extern crate std as _;
21+
extern crate std;
2222

2323
#[macro_use]
2424
extern crate alloc;
@@ -27,6 +27,7 @@ extern crate alloc;
2727
compile_error!("the `alloc` feature must be enabled");
2828

2929
use alloc::{string::String, vec::Vec};
30+
use core::fmt;
3031

3132
macro_rules! require {
3233
($condition: expr) => {
@@ -51,6 +52,21 @@ pub enum DataUrlError {
5152
NoComma,
5253
}
5354

55+
impl fmt::Display for DataUrlError {
56+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
57+
match self {
58+
Self::NotADataUrl => write!(f, "not a valid data url"),
59+
Self::NoComma => write!(
60+
f,
61+
"data url is missing comma delimiting attributes and body"
62+
),
63+
}
64+
}
65+
}
66+
67+
#[cfg(feature = "std")]
68+
impl std::error::Error for DataUrlError {}
69+
5470
impl<'a> DataUrl<'a> {
5571
/// <https://fetch.spec.whatwg.org/#data-url-processor>
5672
/// but starting from a string rather than a parsed `Url`, to avoid extra string copies.

data-url/src/mime.rs

+9
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,15 @@ impl Mime {
2626
#[derive(Debug)]
2727
pub struct MimeParsingError(());
2828

29+
impl fmt::Display for MimeParsingError {
30+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
31+
write!(f, "invalid mime type")
32+
}
33+
}
34+
35+
#[cfg(feature = "std")]
36+
impl std::error::Error for MimeParsingError {}
37+
2938
/// <https://mimesniff.spec.whatwg.org/#parsing-a-mime-type>
3039
impl FromStr for Mime {
3140
type Err = MimeParsingError;

url/Cargo.toml

-13
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,9 @@ include = ["src/**/*", "LICENSE-*", "README.md", "tests/**"]
1616
edition = "2018"
1717
rust-version = "1.56"
1818

19-
[badges]
20-
travis-ci = { repository = "servo/rust-url" }
21-
appveyor = { repository = "Manishearth/rust-url" }
22-
2319
[dev-dependencies]
2420
serde_json = "1.0"
2521
bencher = "0.1"
26-
# To test debugger visualizers defined for the url crate such as url.natvis
27-
debugger_test = "0.1"
28-
debugger_test_parser = "0.1"
2922

3023
[dependencies]
3124
form_urlencoded = { version = "1.2.0", path = "../form_urlencoded", default-features = false, features = ["alloc"] }
@@ -53,12 +46,6 @@ name = "parse_url"
5346
path = "benches/parse_url.rs"
5447
harness = false
5548

56-
[[test]]
57-
name = "debugger_visualizer"
58-
path = "tests/debugger_visualizer.rs"
59-
required-features = ["debugger_visualizer"]
60-
test = false
61-
6249
[package.metadata.docs.rs]
6350
features = ["serde"]
6451

url/src/lib.rs

+9-5
Original file line numberDiff line numberDiff line change
@@ -1552,7 +1552,7 @@ impl Url {
15521552
if let Some(input) = fragment {
15531553
self.fragment_start = Some(to_u32(self.serialization.len()).unwrap());
15541554
self.serialization.push('#');
1555-
self.mutate(|parser| parser.parse_fragment(parser::Input::no_trim(input)))
1555+
self.mutate(|parser| parser.parse_fragment(parser::Input::new_no_trim(input)))
15561556
} else {
15571557
self.fragment_start = None;
15581558
self.strip_trailing_spaces_from_opaque_path();
@@ -1615,7 +1615,7 @@ impl Url {
16151615
parser.parse_query(
16161616
scheme_type,
16171617
scheme_end,
1618-
parser::Input::trim_tab_and_newlines(input, vfn),
1618+
parser::Input::new_trim_tab_and_newlines(input, vfn),
16191619
)
16201620
});
16211621
} else {
@@ -1736,10 +1736,14 @@ impl Url {
17361736
parser.serialization.push_str("%2F");
17371737
path = &path[1..];
17381738
}
1739-
parser.parse_cannot_be_a_base_path(parser::Input::new(path));
1739+
parser.parse_cannot_be_a_base_path(parser::Input::new_no_trim(path));
17401740
} else {
17411741
let mut has_host = true; // FIXME
1742-
parser.parse_path_start(scheme_type, &mut has_host, parser::Input::new(path));
1742+
parser.parse_path_start(
1743+
scheme_type,
1744+
&mut has_host,
1745+
parser::Input::new_no_trim(path),
1746+
);
17431747
}
17441748
});
17451749
self.restore_after_path(old_after_path_pos, &after_path);
@@ -2435,7 +2439,7 @@ impl Url {
24352439
#[allow(clippy::result_unit_err, clippy::suspicious_operation_groupings)]
24362440
pub fn set_scheme(&mut self, scheme: &str) -> Result<(), ()> {
24372441
let mut parser = Parser::for_setter(String::new());
2438-
let remaining = parser.parse_scheme(parser::Input::new(scheme))?;
2442+
let remaining = parser.parse_scheme(parser::Input::new_no_trim(scheme))?;
24392443
let new_scheme_type = SchemeType::from(&parser.serialization);
24402444
let old_scheme_type = SchemeType::from(self.scheme());
24412445
// If url’s scheme is a special scheme and buffer is not a special scheme, then return.

url/src/parser.rs

+7-8
Original file line numberDiff line numberDiff line change
@@ -188,17 +188,13 @@ pub struct Input<'i> {
188188
}
189189

190190
impl<'i> Input<'i> {
191-
pub fn new(input: &'i str) -> Self {
192-
Input::with_log(input, None)
193-
}
194-
195-
pub fn no_trim(input: &'i str) -> Self {
191+
pub fn new_no_trim(input: &'i str) -> Self {
196192
Input {
197193
chars: input.chars(),
198194
}
199195
}
200196

201-
pub fn trim_tab_and_newlines(
197+
pub fn new_trim_tab_and_newlines(
202198
original_input: &'i str,
203199
vfn: Option<&dyn Fn(SyntaxViolation)>,
204200
) -> Self {
@@ -216,7 +212,10 @@ impl<'i> Input<'i> {
216212
}
217213
}
218214

219-
pub fn with_log(original_input: &'i str, vfn: Option<&dyn Fn(SyntaxViolation)>) -> Self {
215+
pub fn new_trim_c0_control_and_space(
216+
original_input: &'i str,
217+
vfn: Option<&dyn Fn(SyntaxViolation)>,
218+
) -> Self {
220219
let input = original_input.trim_matches(c0_control_or_space);
221220
if let Some(vfn) = vfn {
222221
if input.len() < original_input.len() {
@@ -366,7 +365,7 @@ impl<'a> Parser<'a> {
366365

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

url/src/path_segments.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -303,7 +303,7 @@ impl<'a> PathSegmentsMut<'a> {
303303
scheme_type,
304304
&mut has_host,
305305
path_start,
306-
parser::Input::new(segment),
306+
parser::Input::new_no_trim(segment),
307307
);
308308
}
309309
});

url/src/quirks.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ pub fn set_host(url: &mut Url, new_host: &str) -> Result<(), ()> {
154154
}
155155
// Host parsing rules are strict,
156156
// We don't want to trim the input
157-
let input = Input::no_trim(new_host);
157+
let input = Input::new_no_trim(new_host);
158158
let host;
159159
let opt_port;
160160
{
@@ -205,7 +205,7 @@ pub fn set_hostname(url: &mut Url, new_hostname: &str) -> Result<(), ()> {
205205
return Err(());
206206
}
207207
// Host parsing rules are strict we don't want to trim the input
208-
let input = Input::no_trim(new_hostname);
208+
let input = Input::new_no_trim(new_hostname);
209209
let scheme_type = SchemeType::from(url.scheme());
210210
if scheme_type == SchemeType::File && new_hostname.is_empty() {
211211
url.set_host_internal(Host::Domain(String::new()), None);
@@ -251,7 +251,7 @@ pub fn set_port(url: &mut Url, new_port: &str) -> Result<(), ()> {
251251
return Err(());
252252
}
253253
result = Parser::parse_port(
254-
Input::new(new_port),
254+
Input::new_no_trim(new_port),
255255
|| default_port(scheme),
256256
Context::Setter,
257257
)

url/tests/setters_tests.json

+55-1
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
}

url_debug_tests/Cargo.toml

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
[package]
2+
3+
name = "url_debug_tests"
4+
version = "0.0.0"
5+
description = "Tests for debugger visualizers defined for the url crate such as url.natvis"
6+
publish = false
7+
rust-version = "1.60"
8+
9+
[dev-dependencies]
10+
url = { path = "../url" }
11+
debugger_test = "0.1"
12+
debugger_test_parser = "0.1"
13+
14+
[features]
15+
debugger_visualizer = []
16+
17+
[[test]]
18+
name = "debugger_visualizer"
19+
path = "tests/debugger_visualizer.rs"
20+
required-features = ["debugger_visualizer"]
21+
test = false

url/tests/debugger_visualizer.rs renamed to url_debug_tests/tests/debugger_visualizer.rs

+3
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
extern crate debugger_test;
2+
extern crate url;
3+
14
use debugger_test::debugger_test;
25
use url::Url;
36

0 commit comments

Comments
 (0)