Skip to content

Commit e2ebbf0

Browse files
committed
Merge branch 'master' into addl-percent-encode-sets
2 parents 81d0620 + edabc79 commit e2ebbf0

File tree

20 files changed

+2302
-820
lines changed

20 files changed

+2302
-820
lines changed

.github/workflows/main.yml

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ on:
44
push:
55
branches: ["master"]
66
pull_request:
7+
merge_group:
8+
types: [checks_requested]
79

810
env:
911
CARGO_NET_GIT_FETCH_WITH_CLI: true
@@ -40,12 +42,12 @@ jobs:
4042
# Run tests enabling the serde feature
4143
- name: Run tests with the serde feature
4244
run: cargo test --features "url/serde,url/expose_internals"
43-
# The #[debugger_visualizer] attribute is currently gated behind an unstable feature flag.
44-
# In order to test the visualizers for the url crate, they have to be tested on a nightly build.
45+
# The #[debugger_visualizer] attribute is currently gated behind a feature flag until #[debugger_visualizer]
46+
# is available in all rustc versions past our MSRV. As such, we only run the tests on newer rustc versions.
4547
- name: Run debugger_visualizer tests
4648
if: |
4749
matrix.os == 'windows-latest' &&
48-
matrix.rust == 'nightly'
50+
matrix.rust != '1.56.0'
4951
run: cargo test --test debugger_visualizer --features "url/debugger_visualizer,url_debug_tests/debugger_visualizer" -- --test-threads=1
5052
- name: Test `no_std` support
5153
run: cargo test --no-default-features --features=alloc
@@ -75,3 +77,19 @@ jobs:
7577
steps:
7678
- uses: actions/checkout@v3
7779
- uses: EmbarkStudios/cargo-deny-action@v1
80+
81+
Result:
82+
name: Result
83+
runs-on: ubuntu-latest
84+
needs:
85+
- "Test"
86+
- "WASM"
87+
- "Lint"
88+
- "Audit"
89+
steps:
90+
- name: Mark the job as successful
91+
run: exit 0
92+
if: success()
93+
- name: Mark the job as unsuccessful
94+
run: exit 1
95+
if: "!success()"

data-url/Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,3 +26,6 @@ test = false
2626
[[test]]
2727
name = "wpt"
2828
harness = false
29+
30+
[package.metadata.docs.rs]
31+
rustdoc-args = ["--generate-link-to-definition"]

data-url/src/forgiving_base64.rs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,29 @@
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+
24+
#[cfg(feature = "std")]
25+
impl std::error::Error for InvalidBase64 {}
26+
827
#[derive(Debug)]
928
enum InvalidBase64Details {
1029
UnexpectedSymbol(u8),
@@ -19,6 +38,18 @@ pub enum DecodeError<E> {
1938
WriteError(E),
2039
}
2140

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

data-url/src/lib.rs

Lines changed: 17 additions & 1 deletion
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

Lines changed: 9 additions & 0 deletions
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;

debug_metadata/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@ types, descibe how to display those types. (For writing a pretty printer, see: h
2222

2323
### Embedding Visualizers
2424

25-
Through the use of the currently unstable `#[debugger_visualizer]` attribute, the `url`
26-
crate can embed debugger visualizers into the crate metadata.
25+
Through the use of the `#[debugger_visualizer]` attribute, the `url` crate can embed
26+
debugger visualizers into the crate metadata.
2727

2828
Currently the two types of visualizers supported are Natvis and Pretty printers.
2929

form_urlencoded/Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,6 @@ alloc = ["percent-encoding/alloc"]
1919

2020
[dependencies]
2121
percent-encoding = { version = "2.3.0", default-features = false, path = "../percent_encoding" }
22+
23+
[package.metadata.docs.rs]
24+
rustdoc-args = ["--generate-link-to-definition"]

idna/Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,3 +38,6 @@ unicode-normalization = { version = "0.1.22", default-features = false }
3838
[[bench]]
3939
name = "all"
4040
harness = false
41+
42+
[package.metadata.docs.rs]
43+
rustdoc-args = ["--generate-link-to-definition"]

idna/src/uts46.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -453,7 +453,7 @@ impl Idna {
453453
return Errors::default();
454454
}
455455
let mut errors = processing(domain, self.config, &mut self.normalized, out);
456-
self.output = std::mem::replace(out, String::with_capacity(out.len()));
456+
self.output = core::mem::replace(out, String::with_capacity(out.len()));
457457
let mut first = true;
458458
for label in self.output.split('.') {
459459
if !first {

percent_encoding/Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,6 @@ rust-version = "1.51"
1313
default = ["std"]
1414
std = ["alloc"]
1515
alloc = []
16+
17+
[package.metadata.docs.rs]
18+
rustdoc-args = ["--generate-link-to-definition"]

url/Cargo.toml

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ edition = "2018"
1717
rust-version = "1.56"
1818

1919
[dev-dependencies]
20+
serde = { version = "1.0", features = ["derive"] }
2021
serde_json = "1.0"
2122
bencher = "0.1"
2223

@@ -28,19 +29,24 @@ serde = { version = "1.0", optional = true, features = ["derive"] }
2829

2930
[features]
3031
default = []
31-
# UNSTABLE FEATURES (requires Rust nightly)
32-
# Enable to use the #[debugger_visualizer] attribute.
32+
# Enable to use the #[debugger_visualizer] attribute. This feature requires Rust >= 1.71.
3333
debugger_visualizer = []
3434
# Expose internal offsets of the URL.
3535
expose_internals = []
3636

37+
[[test]]
38+
name = "url_wpt"
39+
path = "tests/wpt.rs"
40+
harness = false
41+
3742
[[bench]]
3843
name = "parse_url"
3944
path = "benches/parse_url.rs"
4045
harness = false
4146

4247
[package.metadata.docs.rs]
4348
features = ["serde"]
49+
rustdoc-args = ["--generate-link-to-definition"]
4450

4551
[package.metadata.playground]
4652
features = ["serde"]

url/src/lib.rs

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -119,12 +119,24 @@ See [serde documentation](https://serde.rs) for more information.
119119
url = { version = "2", features = ["serde"] }
120120
```
121121
122+
# Feature: `debugger_visualizer`
123+
124+
If you enable the `debugger_visualizer` feature, the `url` crate will include
125+
a [natvis file](https://docs.microsoft.com/en-us/visualstudio/debugger/create-custom-views-of-native-objects)
126+
for [Visual Studio](https://www.visualstudio.com/) that allows you to view
127+
[`Url`](struct.Url.html) objects in the debugger.
128+
129+
This feature requires Rust 1.71 or later.
130+
131+
```toml
132+
url = { version = "2", features = ["debugger_visualizer"] }
133+
```
134+
122135
*/
123136

124137
#![doc(html_root_url = "https://docs.rs/url/2.4.0")]
125138
#![cfg_attr(
126139
feature = "debugger_visualizer",
127-
feature(debugger_visualizer),
128140
debugger_visualizer(natvis_file = "../../debug_metadata/url.natvis")
129141
)]
130142

@@ -1486,7 +1498,7 @@ impl Url {
14861498
if let Some(input) = fragment {
14871499
self.fragment_start = Some(to_u32(self.serialization.len()).unwrap());
14881500
self.serialization.push('#');
1489-
self.mutate(|parser| parser.parse_fragment(parser::Input::no_trim(input)))
1501+
self.mutate(|parser| parser.parse_fragment(parser::Input::new_no_trim(input)))
14901502
} else {
14911503
self.fragment_start = None;
14921504
self.strip_trailing_spaces_from_opaque_path();
@@ -1549,7 +1561,7 @@ impl Url {
15491561
parser.parse_query(
15501562
scheme_type,
15511563
scheme_end,
1552-
parser::Input::trim_tab_and_newlines(input, vfn),
1564+
parser::Input::new_trim_tab_and_newlines(input, vfn),
15531565
)
15541566
});
15551567
} else {
@@ -1670,10 +1682,14 @@ impl Url {
16701682
parser.serialization.push_str("%2F");
16711683
path = &path[1..];
16721684
}
1673-
parser.parse_cannot_be_a_base_path(parser::Input::new(path));
1685+
parser.parse_cannot_be_a_base_path(parser::Input::new_no_trim(path));
16741686
} else {
16751687
let mut has_host = true; // FIXME
1676-
parser.parse_path_start(scheme_type, &mut has_host, parser::Input::new(path));
1688+
parser.parse_path_start(
1689+
scheme_type,
1690+
&mut has_host,
1691+
parser::Input::new_no_trim(path),
1692+
);
16771693
}
16781694
});
16791695
self.restore_after_path(old_after_path_pos, &after_path);
@@ -2343,7 +2359,7 @@ impl Url {
23432359
#[allow(clippy::result_unit_err, clippy::suspicious_operation_groupings)]
23442360
pub fn set_scheme(&mut self, scheme: &str) -> Result<(), ()> {
23452361
let mut parser = Parser::for_setter(String::new());
2346-
let remaining = parser.parse_scheme(parser::Input::new(scheme))?;
2362+
let remaining = parser.parse_scheme(parser::Input::new_no_trim(scheme))?;
23472363
let new_scheme_type = SchemeType::from(&parser.serialization);
23482364
let old_scheme_type = SchemeType::from(self.scheme());
23492365
// If url’s scheme is a special scheme and buffer is not a special scheme, then return.

url/src/parser.rs

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -167,17 +167,13 @@ pub struct Input<'i> {
167167
}
168168

169169
impl<'i> Input<'i> {
170-
pub fn new(input: &'i str) -> Self {
171-
Input::with_log(input, None)
172-
}
173-
174-
pub fn no_trim(input: &'i str) -> Self {
170+
pub fn new_no_trim(input: &'i str) -> Self {
175171
Input {
176172
chars: input.chars(),
177173
}
178174
}
179175

180-
pub fn trim_tab_and_newlines(
176+
pub fn new_trim_tab_and_newlines(
181177
original_input: &'i str,
182178
vfn: Option<&dyn Fn(SyntaxViolation)>,
183179
) -> Self {
@@ -195,7 +191,10 @@ impl<'i> Input<'i> {
195191
}
196192
}
197193

198-
pub fn with_log(original_input: &'i str, vfn: Option<&dyn Fn(SyntaxViolation)>) -> Self {
194+
pub fn new_trim_c0_control_and_space(
195+
original_input: &'i str,
196+
vfn: Option<&dyn Fn(SyntaxViolation)>,
197+
) -> Self {
199198
let input = original_input.trim_matches(c0_control_or_space);
200199
if let Some(vfn) = vfn {
201200
if input.len() < original_input.len() {
@@ -345,7 +344,7 @@ impl<'a> Parser<'a> {
345344

346345
/// https://url.spec.whatwg.org/#concept-basic-url-parser
347346
pub fn parse_url(mut self, input: &str) -> ParseResult<Url> {
348-
let input = Input::with_log(input, self.violation_fn);
347+
let input = Input::new_trim_c0_control_and_space(input, self.violation_fn);
349348
if let Ok(remaining) = self.parse_scheme(input.clone()) {
350349
return self.parse_with_scheme(remaining);
351350
}

url/src/path_segments.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,7 @@ impl<'a> PathSegmentsMut<'a> {
237237
scheme_type,
238238
&mut has_host,
239239
path_start,
240-
parser::Input::new(segment),
240+
parser::Input::new_no_trim(segment),
241241
);
242242
}
243243
});

url/src/quirks.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ pub fn set_host(url: &mut Url, new_host: &str) -> Result<(), ()> {
152152
}
153153
// Host parsing rules are strict,
154154
// We don't want to trim the input
155-
let input = Input::no_trim(new_host);
155+
let input = Input::new_no_trim(new_host);
156156
let host;
157157
let opt_port;
158158
{
@@ -203,7 +203,7 @@ pub fn set_hostname(url: &mut Url, new_hostname: &str) -> Result<(), ()> {
203203
return Err(());
204204
}
205205
// Host parsing rules are strict we don't want to trim the input
206-
let input = Input::no_trim(new_hostname);
206+
let input = Input::new_no_trim(new_hostname);
207207
let scheme_type = SchemeType::from(url.scheme());
208208
if scheme_type == SchemeType::File && new_hostname.is_empty() {
209209
url.set_host_internal(Host::Domain(String::new()), None);
@@ -249,7 +249,7 @@ pub fn set_port(url: &mut Url, new_port: &str) -> Result<(), ()> {
249249
return Err(());
250250
}
251251
result = Parser::parse_port(
252-
Input::new(new_port),
252+
Input::new_no_trim(new_port),
253253
|| default_port(scheme),
254254
Context::Setter,
255255
)

0 commit comments

Comments
 (0)