Skip to content

2.0 #517

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

Merged
merged 43 commits into from
Jul 17, 2019
Merged

2.0 #517

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
667c896
Add a Config struct following the builder pattern to idna
nox Feb 11, 2019
946c298
Pass a Config value to validate in uts46
nox Feb 11, 2019
6e18952
Introduce Config::check_hyphens in uts46
nox Feb 11, 2019
8975bb9
Bump idna to 0.1.6
nox Feb 11, 2019
fb3b957
Don't check hyphens in domain_to_ascii and domain_to_unicode (fixes #…
nox Feb 11, 2019
ce34673
url crate: remove rustc-serialize optional dependency
est31 Jul 13, 2019
424f3e4
Remove reundant use
est31 Jul 13, 2019
04e705d
Auto merge of #507 - est31:remove_rustc_serialize_feature, r=SimonSapin
Jul 13, 2019
5ae0998
Remove AsciiExt
est31 Jul 13, 2019
03c43b2
Replace deprecated ATOMIC_USIZE_INIT by AtomicUsize::new
est31 Jul 13, 2019
bc09a23
Increase MSRV to 1.24.0
est31 Jul 13, 2019
85bfa53
Remove the deprecated log_syntax_violation function for 2.0
est31 Jul 13, 2019
d6c3bcd
Update to serde 1.0
est31 Jul 13, 2019
ca5f6c8
Auto merge of #512 - est31:serde_1.0, r=SimonSapin
Jul 14, 2019
a1ed777
Make the tests use serde_json instead of rustc_serialize
est31 Jul 14, 2019
f75aef7
Auto merge of #514 - est31:no_rustc_serialize, r=SimonSapin
Jul 15, 2019
54d8b3f
Merge commit 'refs/pull/510/head' of github.com:servo/rust-url into 2.0
SimonSapin Jul 15, 2019
a9526cd
Simplify .travis.yml
SimonSapin Jul 15, 2019
629ec2a
Fix autotests warning
SimonSapin Jul 15, 2019
77a1033
cargo fix
SimonSapin Jul 15, 2019
90e65b2
Merge commit 'refs/pull/511/head' of github.com:servo/rust-url into 2.0
SimonSapin Jul 15, 2019
48f3bed
Use Option instead of a custom ViolationFn enum
SimonSapin Jul 15, 2019
9b8c149
Tell rustfmt to leave some data tables alone
SimonSapin Jul 14, 2019
c276a82
rustfmt
SimonSapin Jul 14, 2019
394e63a
Remove support for the heapsize crate
SimonSapin Jul 14, 2019
fe74a60
Don’t reexport idna and percent_encoding in the url crate
SimonSapin Jul 15, 2019
568425a
Bump url to 2.0.0
SimonSapin Jul 15, 2019
51d6b33
Remove url_serde
SimonSapin Jul 15, 2019
6e08201
Remove DNS-related functionality
SimonSapin Jul 15, 2019
896662b
Merge remote-tracking branch 'origin/master' into 2.0
SimonSapin Jul 15, 2019
47e2286
Remove _charset_ support
SimonSapin Jul 15, 2019
b567a51
Remove rust-encoding support
SimonSapin Jul 15, 2019
9ab946f
`#[rustfmt::skip]` requires 1.30
SimonSapin Jul 15, 2019
5453f6f
Move docs/ to the gh-pages branch
SimonSapin Jul 16, 2019
da2b1af
Merge commit 'refs/pull/484/head' of github.com:servo/rust-url into 2.0
SimonSapin Jul 17, 2019
449c10a
Kill idna::uts46::Flags
nox Jul 17, 2019
38cfea4
Bump idna to 0.2
nox Jul 17, 2019
b2b70f5
Merge commit 'refs/pull/484/head' of github.com:servo/rust-url into 2.0
SimonSapin Jul 17, 2019
e3441b3
rustfmt
SimonSapin Jul 17, 2019
5aeaf89
Make the uts46 module private
SimonSapin Jul 17, 2019
62cc614
Have an explicit `impl Default for Config` in idna
SimonSapin Jul 17, 2019
7371286
Add idna::domain_to_ascii_strict
SimonSapin Jul 17, 2019
50c3efe
Fix idna tests
SimonSapin Jul 17, 2019
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
20 changes: 2 additions & 18 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,28 +1,12 @@
language: rust
script: cargo test --all-features --all

jobs:
include:
- rust: 1.17.0
install:
# --precise requires Cargo.lock to already exist
- cargo update
# getopts is only used in tests. Its versions 0.2.16+ don’t build on 1.17.0
- cargo update -p getopts --precise 0.2.15

- cargo update -p unicode-normalization --precise 0.1.5

# data-url uses pub(crate) which is unstable in 1.17
script: cargo test --all-features -p url -p idna -p percent-encoding -p url_serde

- rust: 1.30.0
- rust: stable
script: cargo test --all-features --all

- rust: beta
script: cargo test --all-features --all

- rust: nightly
script: cargo test --all-features --all

- rust: nightly
env: TARGET=WASM32 # For job list UI
install: rustup target add wasm32-unknown-unknown
Expand Down
21 changes: 5 additions & 16 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

name = "url"
# When updating version, also modify html_root_url in the lib.rs
version = "1.7.2"
version = "2.0.0"
authors = ["The rust-url developers"]

description = "URL library for Rust, based on the WHATWG URL Standard"
Expand All @@ -18,7 +18,7 @@ travis-ci = { repository = "servo/rust-url" }
appveyor = { repository = "Manishearth/rust-url" }

[workspace]
members = [".", "idna", "percent_encoding", "url_serde", "data-url"]
members = [".", "idna", "percent_encoding", "data-url"]

[[test]]
name = "unit"
Expand All @@ -32,27 +32,16 @@ test = false

[dev-dependencies]
rustc-test = "0.3"
rustc-serialize = "0.3"
serde_json = ">=0.6.1, <0.9"
serde_json = "1.0"

bencher = "0.1"

[features]
query_encoding = ["encoding"]
heap_size = ["heapsize"]

[dependencies]
encoding = {version = "0.2", optional = true}
heapsize = {version = ">=0.4.1, <0.5", optional = true}
idna = { version = "0.1.0", path = "./idna" }
idna = { version = "0.2.0", path = "./idna" }
matches = "0.1"
percent-encoding = { version = "1.0.0", path = "./percent_encoding" }
rustc-serialize = {version = "0.3", optional = true}
serde = {version = ">=0.6.1, <0.9", optional = true}
serde = {version = "1.0", optional = true}

[[bench]]
name = "parse_url"
harness = false

[package.metadata.docs.rs]
features = ["query_encoding"]
35 changes: 16 additions & 19 deletions data-url/src/forgiving_base64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ impl From<DecodeError<Impossible>> for InvalidBase64 {
fn from(e: DecodeError<Impossible>) -> Self {
match e {
DecodeError::InvalidBase64(e) => e,
DecodeError::WriteError(e) => match e {}
DecodeError::WriteError(e) => match e {},
}
}
}
Expand All @@ -46,14 +46,20 @@ pub fn decode_to_vec(input: &[u8]) -> Result<Vec<u8>, InvalidBase64> {
}

/// <https://infra.spec.whatwg.org/#forgiving-base64-decode>
pub struct Decoder<F, E> where F: FnMut(&[u8]) -> Result<(), E> {
pub struct Decoder<F, E>
where
F: FnMut(&[u8]) -> Result<(), E>,
{
write_bytes: F,
bit_buffer: u32,
buffer_bit_length: u8,
padding_symbols: u8,
}

impl<F, E> Decoder<F, E> where F: FnMut(&[u8]) -> Result<(), E> {
impl<F, E> Decoder<F, E>
where
F: FnMut(&[u8]) -> Result<(), E>,
{
pub fn new(write_bytes: F) -> Self {
Self {
write_bytes,
Expand All @@ -72,12 +78,12 @@ impl<F, E> Decoder<F, E> where F: FnMut(&[u8]) -> Result<(), E> {

// Remove ASCII whitespace
if matches!(byte, b' ' | b'\t' | b'\n' | b'\r' | b'\x0C') {
continue
continue;
}

if byte == b'=' {
self.padding_symbols = self.padding_symbols.saturating_add(1);
continue
continue;
}

Err(InvalidBase64Details::UnexpectedSymbol(byte))?
Expand Down Expand Up @@ -115,39 +121,30 @@ impl<F, E> Decoder<F, E> where F: FnMut(&[u8]) -> Result<(), E> {
(12, 2) | (12, 0) => {
// A multiple of four of alphabet symbols, followed by two more symbols,
// optionally followed by two padding characters (which make a total multiple of four).
let byte_buffer = [
(self.bit_buffer >> 4) as u8,
];
let byte_buffer = [(self.bit_buffer >> 4) as u8];
(self.write_bytes)(&byte_buffer).map_err(DecodeError::WriteError)?;
}
(18, 1) | (18, 0) => {
// A multiple of four of alphabet symbols, followed by three more symbols,
// optionally followed by one padding character (which make a total multiple of four).
let byte_buffer = [
(self.bit_buffer >> 10) as u8,
(self.bit_buffer >> 2) as u8,
];
let byte_buffer = [(self.bit_buffer >> 10) as u8, (self.bit_buffer >> 2) as u8];
(self.write_bytes)(&byte_buffer).map_err(DecodeError::WriteError)?;
}
(6, _) => {
Err(InvalidBase64Details::LoneAlphabetSymbol)?
}
_ => {
Err(InvalidBase64Details::Padding)?
}
(6, _) => Err(InvalidBase64Details::LoneAlphabetSymbol)?,
_ => Err(InvalidBase64Details::Padding)?,
}
Ok(())
}
}


/// Generated by `make_base64_decode_table.py` based on "Table 1: The Base 64 Alphabet"
/// at <https://tools.ietf.org/html/rfc4648#section-4>
///
/// Array indices are the byte value of symbols.
/// Array values are their positions in the base64 alphabet,
/// or -1 for symbols not in the alphabet.
/// The position contributes 6 bits to the decoded bytes.
#[rustfmt::skip]
const BASE64_DECODE_TABLE: [i8; 256] = [
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
Expand Down
76 changes: 46 additions & 30 deletions data-url/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,15 @@
//! assert!(fragment.is_none());
//! ```

#[macro_use] extern crate matches;
#[macro_use]
extern crate matches;

macro_rules! require {
($condition: expr) => {
if !$condition {
return None
return None;
}
}
};
}

pub mod forgiving_base64;
Expand Down Expand Up @@ -53,7 +54,11 @@ impl<'a> DataUrl<'a> {

let (mime_type, base64) = parse_header(from_colon_to_comma);

Ok(DataUrl { mime_type, base64, encoded_body_plus_fragment })
Ok(DataUrl {
mime_type,
base64,
encoded_body_plus_fragment,
})
}

pub fn mime_type(&self) -> &mime::Mime {
Expand All @@ -62,9 +67,12 @@ impl<'a> DataUrl<'a> {

/// Streaming-decode the data URL’s body to `write_body_bytes`,
/// and return the URL’s fragment identifier if it has one.
pub fn decode<F, E>(&self, write_body_bytes: F)
-> Result<Option<FragmentIdentifier<'a>>, forgiving_base64::DecodeError<E>>
where F: FnMut(&[u8]) -> Result<(), E>
pub fn decode<F, E>(
&self,
write_body_bytes: F,
) -> Result<Option<FragmentIdentifier<'a>>, forgiving_base64::DecodeError<E>>
where
F: FnMut(&[u8]) -> Result<(), E>,
{
if self.base64 {
decode_with_base64(self.encoded_body_plus_fragment, write_body_bytes)
Expand All @@ -75,9 +83,9 @@ impl<'a> DataUrl<'a> {
}

/// Return the decoded body, and the URL’s fragment identifier if it has one.
pub fn decode_to_vec(&self)
-> Result<(Vec<u8>, Option<FragmentIdentifier<'a>>), forgiving_base64::InvalidBase64>
{
pub fn decode_to_vec(
&self,
) -> Result<(Vec<u8>, Option<FragmentIdentifier<'a>>), forgiving_base64::InvalidBase64> {
let mut body = Vec::new();
let fragment = self.decode(|bytes| Ok(body.extend_from_slice(bytes)))?;
Ok((body, fragment))
Expand All @@ -100,7 +108,7 @@ impl<'a> FragmentIdentifier<'a> {
percent_encode(byte, &mut string)
}
// Printable ASCII
_ => string.push(byte as char)
_ => string.push(byte as char),
}
}
string
Expand All @@ -125,7 +133,9 @@ fn pretend_parse_data_url(input: &str) -> Option<&str> {
let mut bytes = left_trimmed.bytes();
{
// Ignore ASCII tabs or newlines like the URL parser would
let mut iter = bytes.by_ref().filter(|&byte| !matches!(byte, b'\t' | b'\n' | b'\r'));
let mut iter = bytes
.by_ref()
.filter(|&byte| !matches!(byte, b'\t' | b'\n' | b'\r'));
require!(iter.next()?.to_ascii_lowercase() == b'd');
require!(iter.next()?.to_ascii_lowercase() == b'a');
require!(iter.next()?.to_ascii_lowercase() == b't');
Expand All @@ -142,10 +152,10 @@ fn pretend_parse_data_url(input: &str) -> Option<&str> {
fn find_comma_before_fragment(after_colon: &str) -> Option<(&str, &str)> {
for (i, byte) in after_colon.bytes().enumerate() {
if byte == b',' {
return Some((&after_colon[..i], &after_colon[i + 1..]))
return Some((&after_colon[..i], &after_colon[i + 1..]));
}
if byte == b'#' {
break
break;
}
}
None
Expand Down Expand Up @@ -187,18 +197,16 @@ fn parse_header(from_colon_to_comma: &str) -> (mime::Mime, bool) {
}

// Printable ASCII
_ => string.push(byte as char)
_ => string.push(byte as char),
}
}

// FIXME: does Mime::from_str match the MIME Sniffing Standard’s parsing algorithm?
// <https://mimesniff.spec.whatwg.org/#parse-a-mime-type>
let mime_type = string.parse().unwrap_or_else(|_| {
mime::Mime {
type_: String::from("text"),
subtype: String::from("plain"),
parameters: vec![(String::from("charset"), String::from("US-ASCII"))],
}
let mime_type = string.parse().unwrap_or_else(|_| mime::Mime {
type_: String::from("text"),
subtype: String::from("plain"),
parameters: vec![(String::from("charset"), String::from("US-ASCII"))],
});

(mime_type, base64)
Expand All @@ -209,7 +217,9 @@ fn remove_base64_suffix(s: &str) -> Option<&str> {
let mut bytes = s.bytes();
{
// Ignore ASCII tabs or newlines like the URL parser would
let iter = bytes.by_ref().filter(|&byte| !matches!(byte, b'\t' | b'\n' | b'\r'));
let iter = bytes
.by_ref()
.filter(|&byte| !matches!(byte, b'\t' | b'\n' | b'\r'));

// Search from the end
let mut iter = iter.rev();
Expand Down Expand Up @@ -240,9 +250,12 @@ fn percent_encode(byte: u8, string: &mut String) {
/// Anything that would have been UTF-8 percent-encoded by the URL parser
/// would be percent-decoded here.
/// We skip that round-trip and pass it through unchanged.
fn decode_without_base64<F, E>(encoded_body_plus_fragment: &str, mut write_bytes: F)
-> Result<Option<FragmentIdentifier>, E>
where F: FnMut(&[u8]) -> Result<(), E>
fn decode_without_base64<F, E>(
encoded_body_plus_fragment: &str,
mut write_bytes: F,
) -> Result<Option<FragmentIdentifier>, E>
where
F: FnMut(&[u8]) -> Result<(), E>,
{
let bytes = encoded_body_plus_fragment.as_bytes();
let mut slice_start = 0;
Expand Down Expand Up @@ -275,11 +288,11 @@ fn decode_without_base64<F, E>(encoded_body_plus_fragment: &str, mut write_bytes
b'#' => {
let fragment_start = i + 1;
let fragment = &encoded_body_plus_fragment[fragment_start..];
return Ok(Some(FragmentIdentifier(fragment)))
return Ok(Some(FragmentIdentifier(fragment)));
}

// Ignore over '\t' | '\n' | '\r'
_ => slice_start = i + 1
_ => slice_start = i + 1,
}
}
}
Expand All @@ -290,9 +303,12 @@ fn decode_without_base64<F, E>(encoded_body_plus_fragment: &str, mut write_bytes
/// `decode_without_base64()` composed with
/// <https://infra.spec.whatwg.org/#isomorphic-decode> composed with
/// <https://infra.spec.whatwg.org/#forgiving-base64-decode>.
fn decode_with_base64<F, E>(encoded_body_plus_fragment: &str, write_bytes: F)
-> Result<Option<FragmentIdentifier>, forgiving_base64::DecodeError<E>>
where F: FnMut(&[u8]) -> Result<(), E>
fn decode_with_base64<F, E>(
encoded_body_plus_fragment: &str,
write_bytes: F,
) -> Result<Option<FragmentIdentifier>, forgiving_base64::DecodeError<E>>
where
F: FnMut(&[u8]) -> Result<(), E>,
{
let mut decoder = forgiving_base64::Decoder::new(write_bytes);
let fragment = decode_without_base64(encoded_body_plus_fragment, |bytes| decoder.feed(bytes))?;
Expand Down
Loading