summaryrefslogtreecommitdiffstats
path: root/vendor/url
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-30 18:31:44 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-30 18:31:44 +0000
commitc23a457e72abe608715ac76f076f47dc42af07a5 (patch)
tree2772049aaf84b5c9d0ed12ec8d86812f7a7904b6 /vendor/url
parentReleasing progress-linux version 1.73.0+dfsg1-1~progress7.99u1. (diff)
downloadrustc-c23a457e72abe608715ac76f076f47dc42af07a5.tar.xz
rustc-c23a457e72abe608715ac76f076f47dc42af07a5.zip
Merging upstream version 1.74.1+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/url')
-rw-r--r--vendor/url/.cargo-checksum.json2
-rw-r--r--vendor/url/Cargo.toml47
-rw-r--r--vendor/url/README.md14
-rw-r--r--vendor/url/src/lib.rs30
-rw-r--r--vendor/url/src/parser.rs16
-rw-r--r--vendor/url/src/path_segments.rs2
-rw-r--r--vendor/url/src/quirks.rs6
-rw-r--r--vendor/url/tests/data.rs260
-rw-r--r--vendor/url/tests/debugger_visualizer.rs102
-rw-r--r--vendor/url/tests/expected_failures.txt53
-rw-r--r--vendor/url/tests/setters_tests.json545
-rw-r--r--vendor/url/tests/unit.rs10
-rw-r--r--vendor/url/tests/urltestdata.json1600
-rw-r--r--vendor/url/tests/wpt.rs477
14 files changed, 2212 insertions, 952 deletions
diff --git a/vendor/url/.cargo-checksum.json b/vendor/url/.cargo-checksum.json
index df3624ea0..601a2ddc8 100644
--- a/vendor/url/.cargo-checksum.json
+++ b/vendor/url/.cargo-checksum.json
@@ -1 +1 @@
-{"files":{"Cargo.toml":"81ec036a51f251210a8469d004611867b1b18cc5e6a5e27abefa86c80b057d75","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"76e972ac0f4ddb116e86e10100132a783931a596e7b9872eaa31be15cd4d751d","README.md":"71b01ec6f2f4ce47235ee430ba0c41afac563403a9dbcda23a584c3e915395ac","src/host.rs":"5e25476aaec0153b64d35b53940a72a1ec58e29a0e1fde36944f52eeb945c5f6","src/lib.rs":"fe1a969023cf7fca36cbd58f72b6cdb988d0ac58c0555d8ecc376dfd78d19a69","src/origin.rs":"19a4b451e8615bfef7239d2fc719c489398fe5044edb0df7c84b54eef4ceba1b","src/parser.rs":"8a928f10387b39fefbba9b22048452b1b1ae9cb46b3c349dea2a59d169e7aed8","src/path_segments.rs":"dd6b637245b2ad77ce96221df3f80c8b4ad858cd52aecc86b97166dec386882a","src/quirks.rs":"82903ff9c95604409cded330e36ebba0ede91c469d1aa40fb646186e2bef0769","src/slicing.rs":"39f4e624adbdbf952b7da8bfe6abdfa6e344193d6e1bbca1b0ccbfc821573f10","tests/data.rs":"35c8f1ab545c3e20a3895712ef235aed07dd8226bf9be6e7b21674fc0125c2be","tests/debugger_visualizer.rs":"d3a9466c636ee80ec9181817a8d30ea3e0cee699776ee4b805175981e4775448","tests/setters_tests.json":"486f6d129960d0d0d99b533caf9bef21113b31adcdb83296dfc4a59cd8431715","tests/unit.rs":"ff61fd7640cc84f45f6dd73d8785576d070506a62c48475bcbf927e9ae97edfd","tests/urltestdata.json":"4df7b990a7624da4fd94bee862fe1c3c1ded59fc27fb1cdf08d4a20b655aa3b7"},"package":"50bff7831e19200a85b17131d085c25d7811bc4e186efdaf54bbd132994a88cb"} \ No newline at end of file
+{"files":{"Cargo.toml":"e8485127c0165af45af4d307166b2db764ee5e1299b9a2cb81c144376361614e","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"76e972ac0f4ddb116e86e10100132a783931a596e7b9872eaa31be15cd4d751d","src/host.rs":"5e25476aaec0153b64d35b53940a72a1ec58e29a0e1fde36944f52eeb945c5f6","src/lib.rs":"1491370cc37bcf7e86dcaa060e24fa83db5ee49c2b91637a188d1407caa1611e","src/origin.rs":"19a4b451e8615bfef7239d2fc719c489398fe5044edb0df7c84b54eef4ceba1b","src/parser.rs":"5427cd15caedc8e3c1418cc576a7263e96df26a51ad3ce88f8c32d3eb7d6dd2c","src/path_segments.rs":"29db87b6902da4ab1ae925b3874afdeff42b8ddfb46356af6a83b86f34e03b14","src/quirks.rs":"c9311e3dd6f701fb4b8e438b3e3960ff6f8c78a67ae763f3640b178f15c60e45","src/slicing.rs":"39f4e624adbdbf952b7da8bfe6abdfa6e344193d6e1bbca1b0ccbfc821573f10","tests/expected_failures.txt":"1afb47b036a9fd2a9db671f233ebfa2802b5cd27c4e65839b518ab0a24380ff2","tests/setters_tests.json":"a3a4cbd7b798bc2c4d9656dc50be7397a5a5ed1f0b52daa1da1ad654d38c1dcd","tests/unit.rs":"1abe0a410c5078e1ad9de8c93f2f2ae660ddb47b7efaac9047e952457b068ded","tests/urltestdata.json":"58d67bea710d5f46324fe6841df5fd82090fe4ec2d882bc0fc7c1784d4771884","tests/wpt.rs":"6302c008cde6e7c0df8626701cc825731363722d02e35804bb370c385b455145"},"package":"143b538f18257fac9cad154828a57c6bf5157e1aa604d4816b5995bf6de87ae5"} \ No newline at end of file
diff --git a/vendor/url/Cargo.toml b/vendor/url/Cargo.toml
index 311354ca2..f70606edb 100644
--- a/vendor/url/Cargo.toml
+++ b/vendor/url/Cargo.toml
@@ -13,46 +13,32 @@
edition = "2018"
rust-version = "1.56"
name = "url"
-version = "2.4.0"
+version = "2.4.1"
authors = ["The rust-url developers"]
-include = [
- "src/**/*",
- "LICENSE-*",
- "README.md",
- "tests/**",
-]
+include = ["src/**/*", "LICENSE-*", "README.md", "tests/**"]
description = "URL library for Rust, based on the WHATWG URL Standard"
documentation = "https://docs.rs/url"
-readme = "README.md"
-keywords = [
- "url",
- "parser",
-]
-categories = [
- "parser-implementations",
- "web-programming",
- "encoding",
-]
+readme = "../README.md"
+keywords = ["url", "parser"]
+categories = ["parser-implementations", "web-programming", "encoding"]
license = "MIT OR Apache-2.0"
repository = "https://github.com/servo/rust-url"
-
[package.metadata.docs.rs]
features = ["serde"]
+rustdoc-args = ["--generate-link-to-definition"]
[package.metadata.playground]
features = ["serde"]
[[test]]
-name = "debugger_visualizer"
-path = "tests/debugger_visualizer.rs"
-test = false
-required-features = ["debugger_visualizer"]
+name = "url_wpt"
+path = "tests/wpt.rs"
+harness = false
[[bench]]
name = "parse_url"
path = "benches/parse_url.rs"
harness = false
-
[dependencies.form_urlencoded]
version = "1.2.0"
@@ -66,15 +52,12 @@ version = "2.3.0"
version = "1.0"
features = ["derive"]
optional = true
-
[dev-dependencies.bencher]
version = "0.1"
-[dev-dependencies.debugger_test]
-version = "0.1"
-
-[dev-dependencies.debugger_test_parser]
-version = "0.1"
+[dev-dependencies.serde]
+version = "1.0"
+features = ["derive"]
[dev-dependencies.serde_json]
version = "1.0"
@@ -83,9 +66,3 @@ version = "1.0"
debugger_visualizer = []
default = []
expose_internals = []
-
-[badges.appveyor]
-repository = "Manishearth/rust-url"
-
-[badges.travis-ci]
-repository = "servo/rust-url"
diff --git a/vendor/url/README.md b/vendor/url/README.md
deleted file mode 100644
index ab31bffc6..000000000
--- a/vendor/url/README.md
+++ /dev/null
@@ -1,14 +0,0 @@
-rust-url
-========
-
-[![Build status](https://github.com/servo/rust-url/workflows/CI/badge.svg)](https://github.com/servo/rust-url/actions?query=workflow%3ACI)
-[![Coverage](https://codecov.io/gh/servo/rust-url/branch/master/graph/badge.svg)](https://codecov.io/gh/servo/rust-url)
-[![Chat](https://img.shields.io/badge/chat-%23rust--url:mozilla.org-%2346BC99?logo=Matrix)](https://matrix.to/#/#rust-url:mozilla.org)
-[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE-MIT)
-[![License: Apache 2.0](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](LICENSE-APACHE)
-
-URL library for Rust, based on the [URL Standard](https://url.spec.whatwg.org/).
-
-[Documentation](https://docs.rs/url/)
-
-Please see [UPGRADING.md](https://github.com/servo/rust-url/blob/master/UPGRADING.md) if you are upgrading from a previous version.
diff --git a/vendor/url/src/lib.rs b/vendor/url/src/lib.rs
index ad3c89001..58c7c07cd 100644
--- a/vendor/url/src/lib.rs
+++ b/vendor/url/src/lib.rs
@@ -119,12 +119,24 @@ See [serde documentation](https://serde.rs) for more information.
url = { version = "2", features = ["serde"] }
```
+# Feature: `debugger_visualizer`
+
+If you enable the `debugger_visualizer` feature, the `url` crate will include
+a [natvis file](https://docs.microsoft.com/en-us/visualstudio/debugger/create-custom-views-of-native-objects)
+for [Visual Studio](https://www.visualstudio.com/) that allows you to view
+[`Url`](struct.Url.html) objects in the debugger.
+
+This feature requires Rust 1.71 or later.
+
+```toml
+url = { version = "2", features = ["debugger_visualizer"] }
+```
+
*/
-#![doc(html_root_url = "https://docs.rs/url/2.4.0")]
+#![doc(html_root_url = "https://docs.rs/url/2.4.1")]
#![cfg_attr(
feature = "debugger_visualizer",
- feature(debugger_visualizer),
debugger_visualizer(natvis_file = "../../debug_metadata/url.natvis")
)]
@@ -1486,7 +1498,7 @@ impl Url {
if let Some(input) = fragment {
self.fragment_start = Some(to_u32(self.serialization.len()).unwrap());
self.serialization.push('#');
- self.mutate(|parser| parser.parse_fragment(parser::Input::no_trim(input)))
+ self.mutate(|parser| parser.parse_fragment(parser::Input::new_no_trim(input)))
} else {
self.fragment_start = None;
self.strip_trailing_spaces_from_opaque_path();
@@ -1549,7 +1561,7 @@ impl Url {
parser.parse_query(
scheme_type,
scheme_end,
- parser::Input::trim_tab_and_newlines(input, vfn),
+ parser::Input::new_trim_tab_and_newlines(input, vfn),
)
});
} else {
@@ -1670,10 +1682,14 @@ impl Url {
parser.serialization.push_str("%2F");
path = &path[1..];
}
- parser.parse_cannot_be_a_base_path(parser::Input::new(path));
+ parser.parse_cannot_be_a_base_path(parser::Input::new_no_trim(path));
} else {
let mut has_host = true; // FIXME
- parser.parse_path_start(scheme_type, &mut has_host, parser::Input::new(path));
+ parser.parse_path_start(
+ scheme_type,
+ &mut has_host,
+ parser::Input::new_no_trim(path),
+ );
}
});
self.restore_after_path(old_after_path_pos, &after_path);
@@ -2343,7 +2359,7 @@ impl Url {
#[allow(clippy::result_unit_err, clippy::suspicious_operation_groupings)]
pub fn set_scheme(&mut self, scheme: &str) -> Result<(), ()> {
let mut parser = Parser::for_setter(String::new());
- let remaining = parser.parse_scheme(parser::Input::new(scheme))?;
+ let remaining = parser.parse_scheme(parser::Input::new_no_trim(scheme))?;
let new_scheme_type = SchemeType::from(&parser.serialization);
let old_scheme_type = SchemeType::from(self.scheme());
// If url’s scheme is a special scheme and buffer is not a special scheme, then return.
diff --git a/vendor/url/src/parser.rs b/vendor/url/src/parser.rs
index 765cc027c..7d94d1d71 100644
--- a/vendor/url/src/parser.rs
+++ b/vendor/url/src/parser.rs
@@ -184,17 +184,13 @@ pub struct Input<'i> {
}
impl<'i> Input<'i> {
- pub fn new(input: &'i str) -> Self {
- Input::with_log(input, None)
- }
-
- pub fn no_trim(input: &'i str) -> Self {
+ pub fn new_no_trim(input: &'i str) -> Self {
Input {
chars: input.chars(),
}
}
- pub fn trim_tab_and_newlines(
+ pub fn new_trim_tab_and_newlines(
original_input: &'i str,
vfn: Option<&dyn Fn(SyntaxViolation)>,
) -> Self {
@@ -212,7 +208,10 @@ impl<'i> Input<'i> {
}
}
- pub fn with_log(original_input: &'i str, vfn: Option<&dyn Fn(SyntaxViolation)>) -> Self {
+ pub fn new_trim_c0_control_and_space(
+ original_input: &'i str,
+ vfn: Option<&dyn Fn(SyntaxViolation)>,
+ ) -> Self {
let input = original_input.trim_matches(c0_control_or_space);
if let Some(vfn) = vfn {
if input.len() < original_input.len() {
@@ -362,7 +361,7 @@ impl<'a> Parser<'a> {
/// https://url.spec.whatwg.org/#concept-basic-url-parser
pub fn parse_url(mut self, input: &str) -> ParseResult<Url> {
- let input = Input::with_log(input, self.violation_fn);
+ let input = Input::new_trim_c0_control_and_space(input, self.violation_fn);
if let Ok(remaining) = self.parse_scheme(input.clone()) {
return self.parse_with_scheme(remaining);
}
@@ -1203,6 +1202,7 @@ impl<'a> Parser<'a> {
_ => {
self.check_url_code_point(c, &input);
if scheme_type.is_file()
+ && self.serialization.len() > path_start
&& is_normalized_windows_drive_letter(
&self.serialization[path_start + 1..],
)
diff --git a/vendor/url/src/path_segments.rs b/vendor/url/src/path_segments.rs
index 29afc1e7e..d8a78d785 100644
--- a/vendor/url/src/path_segments.rs
+++ b/vendor/url/src/path_segments.rs
@@ -237,7 +237,7 @@ impl<'a> PathSegmentsMut<'a> {
scheme_type,
&mut has_host,
path_start,
- parser::Input::new(segment),
+ parser::Input::new_no_trim(segment),
);
}
});
diff --git a/vendor/url/src/quirks.rs b/vendor/url/src/quirks.rs
index 0674ebb62..3a99e22cf 100644
--- a/vendor/url/src/quirks.rs
+++ b/vendor/url/src/quirks.rs
@@ -152,7 +152,7 @@ pub fn set_host(url: &mut Url, new_host: &str) -> Result<(), ()> {
}
// Host parsing rules are strict,
// We don't want to trim the input
- let input = Input::no_trim(new_host);
+ let input = Input::new_no_trim(new_host);
let host;
let opt_port;
{
@@ -203,7 +203,7 @@ pub fn set_hostname(url: &mut Url, new_hostname: &str) -> Result<(), ()> {
return Err(());
}
// Host parsing rules are strict we don't want to trim the input
- let input = Input::no_trim(new_hostname);
+ let input = Input::new_no_trim(new_hostname);
let scheme_type = SchemeType::from(url.scheme());
if scheme_type == SchemeType::File && new_hostname.is_empty() {
url.set_host_internal(Host::Domain(String::new()), None);
@@ -249,7 +249,7 @@ pub fn set_port(url: &mut Url, new_port: &str) -> Result<(), ()> {
return Err(());
}
result = Parser::parse_port(
- Input::new(new_port),
+ Input::new_no_trim(new_port),
|| default_port(scheme),
Context::Setter,
)
diff --git a/vendor/url/tests/data.rs b/vendor/url/tests/data.rs
deleted file mode 100644
index dc4660b9b..000000000
--- a/vendor/url/tests/data.rs
+++ /dev/null
@@ -1,260 +0,0 @@
-// Copyright 2013-2014 The rust-url developers.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! Data-driven tests
-
-use std::str::FromStr;
-
-use serde_json::Value;
-use url::{quirks, Url};
-
-#[test]
-fn urltestdata() {
- // Copied from https://github.com/web-platform-tests/wpt/blob/master/url/
- let mut json = Value::from_str(include_str!("urltestdata.json"))
- .expect("JSON parse error in urltestdata.json");
-
- let mut passed = true;
- let mut skip_next = false;
- for entry in json.as_array_mut().unwrap() {
- if entry.is_string() {
- if entry.as_str().unwrap() == "skip next" {
- skip_next = true;
- }
- continue; // ignore comments
- }
-
- if skip_next {
- skip_next = false;
- continue;
- }
-
- let maybe_base = entry
- .take_key("base")
- .expect("missing base key")
- .maybe_string();
- let input = entry.take_string("input");
- let failure = entry.take_key("failure").is_some();
-
- let res = if let Some(base) = maybe_base {
- let base = match Url::parse(&base) {
- Ok(base) => base,
- Err(_) if failure => continue,
- Err(message) => {
- eprint_failure(
- format!(" failed: error parsing base {:?}: {}", base, message),
- &format!("parse base for {:?}", input),
- None,
- );
- passed = false;
- continue;
- }
- };
- base.join(&input)
- } else {
- Url::parse(&input)
- };
-
- let url = match (res, failure) {
- (Ok(url), false) => url,
- (Err(_), true) => continue,
- (Err(message), false) => {
- eprint_failure(
- format!(" failed: {}", message),
- &format!("parse URL for {:?}", input),
- None,
- );
- passed = false;
- continue;
- }
- (Ok(_), true) => {
- eprint_failure(
- format!(" failed: expected parse error for URL {:?}", input),
- &format!("parse URL for {:?}", input),
- None,
- );
- passed = false;
- continue;
- }
- };
-
- passed &= check_invariants(&url, &format!("invariants for {:?}", input), None);
-
- for &attr in ATTRIBS {
- passed &= test_eq_eprint(
- entry.take_string(attr),
- get(&url, attr),
- &format!("{:?} - {}", input, attr),
- None,
- );
- }
-
- if let Some(expected_origin) = entry.take_key("origin").map(|s| s.string()) {
- passed &= test_eq_eprint(
- expected_origin,
- &quirks::origin(&url),
- &format!("origin for {:?}", input),
- None,
- );
- }
- }
-
- assert!(passed)
-}
-
-#[test]
-fn setters_tests() {
- let mut json = Value::from_str(include_str!("setters_tests.json"))
- .expect("JSON parse error in setters_tests.json");
-
- let mut passed = true;
- for &attr in ATTRIBS {
- if attr == "href" {
- continue;
- }
-
- let mut tests = json.take_key(attr).unwrap();
- for mut test in tests.as_array_mut().unwrap().drain(..) {
- let comment = test.take_key("comment").map(|s| s.string());
- {
- if let Some(comment) = comment.as_ref() {
- if comment.starts_with("IDNA Nontransitional_Processing") {
- continue;
- }
- }
- }
- let href = test.take_string("href");
- let new_value = test.take_string("new_value");
- let name = format!("{:?}.{} = {:?}", href, attr, new_value);
- let mut expected = test.take_key("expected").unwrap();
-
- let mut url = Url::parse(&href).unwrap();
- let comment_ref = comment.as_deref();
- passed &= check_invariants(&url, &name, comment_ref);
- set(&mut url, attr, &new_value);
-
- for attr in ATTRIBS {
- if let Some(value) = expected.take_key(attr) {
- passed &= test_eq_eprint(value.string(), get(&url, attr), &name, comment_ref);
- };
- }
-
- passed &= check_invariants(&url, &name, comment_ref);
- }
- }
-
- assert!(passed);
-}
-
-fn check_invariants(url: &Url, name: &str, comment: Option<&str>) -> bool {
- let mut passed = true;
- if let Err(e) = url.check_invariants() {
- passed = false;
- eprint_failure(
- format!(" failed: invariants checked -> {:?}", e),
- name,
- comment,
- );
- }
-
- #[cfg(feature = "serde")]
- {
- let bytes = serde_json::to_vec(url).unwrap();
- let new_url: Url = serde_json::from_slice(&bytes).unwrap();
- passed &= test_eq_eprint(url.to_string(), &new_url.to_string(), name, comment);
- }
-
- passed
-}
-
-trait JsonExt {
- fn take_key(&mut self, key: &str) -> Option<Value>;
- fn string(self) -> String;
- fn maybe_string(self) -> Option<String>;
- fn take_string(&mut self, key: &str) -> String;
-}
-
-impl JsonExt for Value {
- fn take_key(&mut self, key: &str) -> Option<Value> {
- self.as_object_mut().unwrap().remove(key)
- }
-
- fn string(self) -> String {
- self.maybe_string().expect("")
- }
-
- fn maybe_string(self) -> Option<String> {
- match self {
- Value::String(s) => Some(s),
- Value::Null => None,
- _ => panic!("Not a Value::String or Value::Null"),
- }
- }
-
- fn take_string(&mut self, key: &str) -> String {
- self.take_key(key).unwrap().string()
- }
-}
-
-fn get<'a>(url: &'a Url, attr: &str) -> &'a str {
- match attr {
- "href" => quirks::href(url),
- "protocol" => quirks::protocol(url),
- "username" => quirks::username(url),
- "password" => quirks::password(url),
- "hostname" => quirks::hostname(url),
- "host" => quirks::host(url),
- "port" => quirks::port(url),
- "pathname" => quirks::pathname(url),
- "search" => quirks::search(url),
- "hash" => quirks::hash(url),
- _ => unreachable!(),
- }
-}
-
-#[allow(clippy::unit_arg)]
-fn set(url: &mut Url, attr: &str, new: &str) {
- let _ = match attr {
- "protocol" => quirks::set_protocol(url, new),
- "username" => quirks::set_username(url, new),
- "password" => quirks::set_password(url, new),
- "hostname" => quirks::set_hostname(url, new),
- "host" => quirks::set_host(url, new),
- "port" => quirks::set_port(url, new),
- "pathname" => Ok(quirks::set_pathname(url, new)),
- "search" => Ok(quirks::set_search(url, new)),
- "hash" => Ok(quirks::set_hash(url, new)),
- _ => unreachable!(),
- };
-}
-
-fn test_eq_eprint(expected: String, actual: &str, name: &str, comment: Option<&str>) -> bool {
- if expected == actual {
- return true;
- }
- eprint_failure(
- format!("expected: {}\n actual: {}", expected, actual),
- name,
- comment,
- );
- false
-}
-
-fn eprint_failure(err: String, name: &str, comment: Option<&str>) {
- eprintln!(" test: {}\n{}", name, err);
- if let Some(comment) = comment {
- eprintln!("{}\n", comment);
- } else {
- eprintln!();
- }
-}
-
-const ATTRIBS: &[&str] = &[
- "href", "protocol", "username", "password", "host", "hostname", "port", "pathname", "search",
- "hash",
-];
diff --git a/vendor/url/tests/debugger_visualizer.rs b/vendor/url/tests/debugger_visualizer.rs
deleted file mode 100644
index 4558e0701..000000000
--- a/vendor/url/tests/debugger_visualizer.rs
+++ /dev/null
@@ -1,102 +0,0 @@
-use debugger_test::debugger_test;
-use url::Url;
-
-#[inline(never)]
-fn __break() {}
-
-#[debugger_test(
- debugger = "cdb",
- commands = "
- .nvlist
-
- dx base_url
-
- dx url_with_non_special_scheme
-
- dx url_with_user_pass_port_query_fragments
-
- dx url_blob
-
- dx url_with_base
-
- dx url_with_base_replaced
-
- dx url_with_comma",
- expected_statements = r#"
- pattern:debugger_visualizer-.*\.exe \(embedded NatVis ".*-[0-9]+\.natvis"\)
-
- base_url : "http://example.org/foo/bar" [Type: url::Url]
- [<Raw View>] [Type: url::Url]
- [scheme] : "http"
- [host] : "example.org"
- [path] : "/foo/bar"
-
- url_with_non_special_scheme : "non-special://test/x" [Type: url::Url]
- [<Raw View>] [Type: url::Url]
- [scheme] : "non-special"
- [host] : "test"
- [path] : "/x"
-
- url_with_user_pass_port_query_fragments : "http://user:pass@foo:21/bar;par?b#c" [Type: url::Url]
- [<Raw View>] [Type: url::Url]
- [scheme] : "http"
- [username] : "user"
- [host] : "foo"
- [port] : 21
- [path] : "/bar;par"
- [query] : "b"
- [fragment] : "c"
-
- url_blob : "blob:https://example.com:443/" [Type: url::Url]
- [<Raw View>] [Type: url::Url]
- [scheme] : "blob"
- [path] : "https://example.com:443/"
-
- url_with_base : "http://example.org/a%2fc" [Type: url::Url]
- [<Raw View>] [Type: url::Url]
- [scheme] : "http"
- [host] : "example.org"
- [path] : "/a%2fc"
-
- url_with_base_replaced : "http://[::7f00:1]/" [Type: url::Url]
- [<Raw View>] [Type: url::Url]
- [scheme] : "http"
- [host] : "[::7f00:1]"
- [path] : "/"
-
- url_with_comma : "data:text/html,test#test" [Type: url::Url]
- [<Raw View>] [Type: url::Url]
- [scheme] : "data"
- [path] : "text/html,test"
- [fragment] : "test"
- "#
-)]
-fn test_url_visualizer() {
- // Copied from https://github.com/web-platform-tests/wpt/blob/master/url/
- let base_url = Url::parse("http://example.org/foo/bar").unwrap();
- assert_eq!(base_url.as_str(), "http://example.org/foo/bar");
-
- let url_with_non_special_scheme = Url::parse("non-special://:@test/x").unwrap();
- assert_eq!(url_with_non_special_scheme.as_str(), "non-special://test/x");
-
- let url_with_user_pass_port_query_fragments =
- Url::parse("http://user:pass@foo:21/bar;par?b#c").unwrap();
- assert_eq!(
- url_with_user_pass_port_query_fragments.as_str(),
- "http://user:pass@foo:21/bar;par?b#c"
- );
-
- let url_blob = Url::parse("blob:https://example.com:443/").unwrap();
- assert_eq!(url_blob.as_str(), "blob:https://example.com:443/");
-
- let url_with_base = base_url.join("/a%2fc").unwrap();
- assert_eq!(url_with_base.as_str(), "http://example.org/a%2fc");
-
- let url_with_base_replaced = base_url.join("http://[::127.0.0.1]").unwrap();
- assert_eq!(url_with_base_replaced.as_str(), "http://[::7f00:1]/");
-
- let url_with_comma = base_url.join("data:text/html,test#test").unwrap();
- assert_eq!(url_with_comma.as_str(), "data:text/html,test#test");
-
- __break();
-}
diff --git a/vendor/url/tests/expected_failures.txt b/vendor/url/tests/expected_failures.txt
new file mode 100644
index 000000000..1c404a8b7
--- /dev/null
+++ b/vendor/url/tests/expected_failures.txt
@@ -0,0 +1,53 @@
+</> against <file://h/C:/a/b>
+<file:\\\\//>
+<file:\\\\\\\\>
+<file:\\\\\\\\?fox>
+<file:\\\\\\\\#guppy>
+<file://spider///>
+<file:\\\\localhost//>
+<file://\\/localhost//cat>
+<file://localhost//a//../..//>
+</////mouse> against <file:///elephant>
+<\\/localhost//pig> against <file://lion/>
+<//localhost//pig> against <file://lion/>
+</..//localhost//pig> against <file://lion/>
+<C|> against <file://host/dir/file>
+<C|> against <file://host/D:/dir1/dir2/file>
+<C|#> against <file://host/dir/file>
+<C|?> against <file://host/dir/file>
+<C|/> against <file://host/dir/file>
+<C|\n/> against <file://host/dir/file>
+<C|\\> against <file://host/dir/file>
+</c:/foo/bar> against <file://host/path>
+<file://example.net/C:/>
+<file://1.2.3.4/C:/>
+<file://[1::8]/C:/>
+<C|/> against <file://host/>
+</C:/> against <file://host/>
+<file:C:/> against <file://host/>
+<file:/C:/> against <file://host/>
+<file://localhost//a//../..//foo>
+<file://localhost////foo>
+<file:////foo>
+<file:////one/two> against <file:///>
+<////one/two> against <file:///>
+<file:///.//> against <file:////>
+<file:.//p>
+<file:/.//p>
+<http://example.net/path> set hostname to <example.com:8080>
+<http://example.net:8080/path> set hostname to <example.com:>
+<non-spec:/.//p> set hostname to <h>
+<non-spec:/.//p> set hostname to <>
+<foo://somehost/some/path> set pathname to <>
+<foo:///some/path> set pathname to <>
+<http://example.net:8080/path> set port to <randomstring>
+<file:///var/log/system.log> set href to <http://0300.168.0xF0>
+<data:space ?query#fragment> set search to <>
+<sc:space ?query#fragment> set search to <>
+<file://monkey/> set pathname to <\\\\>
+<file:///unicorn> set pathname to <//\\/>
+<file:///unicorn> set pathname to <//monkey/..//>
+<non-spec:/> set pathname to </.//p>
+<non-spec:/> set pathname to </..//p>
+<non-spec:/> set pathname to <//p>
+<non-spec:/.//> set pathname to <p> \ No newline at end of file
diff --git a/vendor/url/tests/setters_tests.json b/vendor/url/tests/setters_tests.json
index 4280032a2..2c6ebee64 100644
--- a/vendor/url/tests/setters_tests.json
+++ b/vendor/url/tests/setters_tests.json
@@ -1,6 +1,6 @@
{
"comment": [
- "AS OF https://github.com/jsdom/whatwg-url/commit/35f04dfd3048cf6362f4398745bb13375c5020c2",
+ "# Pulled from https://github.com/web-platform-tests/wpt/blob/befe66343e5f21dc464c8c772c6d20695936714f/url/resources/setters_tests.json",
"## Tests for setters of https://url.spec.whatwg.org/#urlutils-members",
"",
"This file contains a JSON object.",
@@ -120,11 +120,11 @@
}
},
{
- "href": "gopher://example.net:1234",
+ "href": "https://example.net:1234",
"new_value": "file",
"expected": {
- "href": "gopher://example.net:1234",
- "protocol": "gopher:"
+ "href": "https://example.net:1234/",
+ "protocol": "https:"
}
},
{
@@ -146,7 +146,7 @@
},
{
"href": "file:///test",
- "new_value": "gopher",
+ "new_value": "https",
"expected": {
"href": "file:///test",
"protocol": "file:"
@@ -270,6 +270,57 @@
"protocol": "https:",
"port": ""
}
+ },
+ {
+ "comment": "Tab and newline are stripped",
+ "href": "http://test/",
+ "new_value": "h\u000D\u000Att\u0009ps",
+ "expected": {
+ "href": "https://test/",
+ "protocol": "https:",
+ "port": ""
+ }
+ },
+ {
+ "href": "http://test/",
+ "new_value": "https\u000D",
+ "expected": {
+ "href": "https://test/",
+ "protocol": "https:"
+ }
+ },
+ {
+ "comment": "Non-tab/newline C0 controls result in no-op",
+ "href": "http://test/",
+ "new_value": "https\u0000",
+ "expected": {
+ "href": "http://test/",
+ "protocol": "http:"
+ }
+ },
+ {
+ "href": "http://test/",
+ "new_value": "https\u000C",
+ "expected": {
+ "href": "http://test/",
+ "protocol": "http:"
+ }
+ },
+ {
+ "href": "http://test/",
+ "new_value": "https\u000E",
+ "expected": {
+ "href": "http://test/",
+ "protocol": "http:"
+ }
+ },
+ {
+ "href": "http://test/",
+ "new_value": "https\u0020",
+ "expected": {
+ "href": "http://test/",
+ "protocol": "http:"
+ }
}
],
"username": [
@@ -963,6 +1014,16 @@
}
},
{
+ "href": "file://hi/x",
+ "new_value": "",
+ "expected": {
+ "href": "file:///x",
+ "host": "",
+ "hostname": "",
+ "port": ""
+ }
+ },
+ {
"href": "sc://test@test/",
"new_value": "",
"expected": {
@@ -981,6 +1042,62 @@
"hostname": "test",
"port": "12"
}
+ },
+ {
+ "comment": "Leading / is not stripped",
+ "href": "http://example.com/",
+ "new_value": "///bad.com",
+ "expected": {
+ "href": "http://example.com/",
+ "host": "example.com",
+ "hostname": "example.com"
+ }
+ },
+ {
+ "comment": "Leading / is not stripped",
+ "href": "sc://example.com/",
+ "new_value": "///bad.com",
+ "expected": {
+ "href": "sc:///",
+ "host": "",
+ "hostname": ""
+ }
+ },
+ {
+ "href": "https://example.com/",
+ "new_value": "a%C2%ADb",
+ "expected": {
+ "href": "https://ab/",
+ "host": "ab",
+ "hostname": "ab"
+ }
+ },
+ {
+ "href": "https://example.com/",
+ "new_value": "\u00AD",
+ "expected": {
+ "href": "https://example.com/",
+ "host": "example.com",
+ "hostname": "example.com"
+ }
+ },
+ {
+ "href": "https://example.com/",
+ "new_value": "%C2%AD",
+ "expected": {
+ "href": "https://example.com/",
+ "host": "example.com",
+ "hostname": "example.com"
+ }
+ },
+ {
+ "href": "https://example.com/",
+ "new_value": "xn--",
+ "expected": {
+ "href": "https://example.com/",
+ "host": "example.com",
+ "hostname": "example.com"
+ }
}
],
"hostname": [
@@ -1144,24 +1261,24 @@
}
},
{
- "comment": "Stuff after a : delimiter is ignored",
+ "comment": ": delimiter invalidates entire value",
"href": "http://example.net/path",
"new_value": "example.com:8080",
"expected": {
- "href": "http://example.com/path",
- "host": "example.com",
- "hostname": "example.com",
+ "href": "http://example.net/path",
+ "host": "example.net",
+ "hostname": "example.net",
"port": ""
}
},
{
- "comment": "Stuff after a : delimiter is ignored",
+ "comment": ": delimiter invalidates entire value",
"href": "http://example.net:8080/path",
"new_value": "example.com:",
"expected": {
- "href": "http://example.com:8080/path",
- "host": "example.com:8080",
- "hostname": "example.com",
+ "href": "http://example.net:8080/path",
+ "host": "example.net:8080",
+ "hostname": "example.net",
"port": "8080"
}
},
@@ -1287,6 +1404,16 @@
}
},
{
+ "href": "file://hi/x",
+ "new_value": "",
+ "expected": {
+ "href": "file:///x",
+ "host": "",
+ "hostname": "",
+ "port": ""
+ }
+ },
+ {
"href": "sc://test@test/",
"new_value": "",
"expected": {
@@ -1305,6 +1432,83 @@
"hostname": "test",
"port": "12"
}
+ },
+ {
+ "comment": "Drop /. from path",
+ "href": "non-spec:/.//p",
+ "new_value": "h",
+ "expected": {
+ "href": "non-spec://h//p",
+ "host": "h",
+ "hostname": "h",
+ "pathname": "//p"
+ }
+ },
+ {
+ "href": "non-spec:/.//p",
+ "new_value": "",
+ "expected": {
+ "href": "non-spec:////p",
+ "host": "",
+ "hostname": "",
+ "pathname": "//p"
+ }
+ },
+ {
+ "comment": "Leading / is not stripped",
+ "href": "http://example.com/",
+ "new_value": "///bad.com",
+ "expected": {
+ "href": "http://example.com/",
+ "host": "example.com",
+ "hostname": "example.com"
+ }
+ },
+ {
+ "comment": "Leading / is not stripped",
+ "href": "sc://example.com/",
+ "new_value": "///bad.com",
+ "expected": {
+ "href": "sc:///",
+ "host": "",
+ "hostname": ""
+ }
+ },
+ {
+ "href": "https://example.com/",
+ "new_value": "a%C2%ADb",
+ "expected": {
+ "href": "https://ab/",
+ "host": "ab",
+ "hostname": "ab"
+ }
+ },
+ {
+ "href": "https://example.com/",
+ "new_value": "\u00AD",
+ "expected": {
+ "href": "https://example.com/",
+ "host": "example.com",
+ "hostname": "example.com"
+ }
+ },
+ {
+ "href": "https://example.com/",
+ "new_value": "%C2%AD",
+ "expected": {
+ "href": "https://example.com/",
+ "host": "example.com",
+ "hostname": "example.com"
+ }
+ },
+ {
+ "href": "https://example.com/",
+ "new_value": "xn--",
+ "expected": {
+ "href": "https://example.com/",
+ "host": "example.com",
+ "hostname": "example.com"
+ }
}
],
"port": [
@@ -1462,6 +1666,17 @@
}
},
{
+ "comment": "Setting port to a string that doesn't parse as a number",
+ "href": "http://example.net:8080/path",
+ "new_value": "randomstring",
+ "expected": {
+ "href": "http://example.net:8080/path",
+ "host": "example.net:8080",
+ "hostname": "example.net",
+ "port": "8080"
+ }
+ },
+ {
"comment": "Port numbers are 16 bit integers, overflowing is an error",
"href": "non-special://example.net:8080/path",
"new_value": "65536",
@@ -1519,11 +1734,35 @@
"href": "javascript://x:12/",
"port": "12"
}
+ },
+ {
+ "comment": "Leading u0009 on special scheme",
+ "href": "https://domain.com:443",
+ "new_value": "\u00098080",
+ "expected": {
+ "port": "8080"
+ }
+ },
+ {
+ "comment": "Leading u0009 on non-special scheme",
+ "href": "wpt++://domain.com:443",
+ "new_value": "\u00098080",
+ "expected": {
+ "port": "8080"
+ }
+ },
+ {
+ "comment": "Should use all ascii prefixed characters as port",
+ "href": "https://www.google.com:4343",
+ "new_value": "4wpt",
+ "expected": {
+ "port": "4"
+ }
}
],
"pathname": [
{
- "comment": "Cannot-be-a-base don’t have a path",
+ "comment": "Opaque paths cannot be set",
"href": "mailto:me@example.net",
"new_value": "/foo",
"expected": {
@@ -1532,6 +1771,67 @@
}
},
{
+ "href": "data:original",
+ "new_value": "new value",
+ "expected": {
+ "href": "data:original",
+ "pathname": "original"
+ }
+ },
+ {
+ "href": "sc:original",
+ "new_value": "new value",
+ "expected": {
+ "href": "sc:original",
+ "pathname": "original"
+ }
+ },
+ {
+ "comment": "Special URLs cannot have their paths erased",
+ "href": "file:///some/path",
+ "new_value": "",
+ "expected": {
+ "href": "file:///",
+ "pathname": "/"
+ }
+ },
+ {
+ "comment": "Non-special URLs can have their paths erased",
+ "href": "foo://somehost/some/path",
+ "new_value": "",
+ "expected": {
+ "href": "foo://somehost",
+ "pathname": ""
+ }
+ },
+ {
+ "comment": "Non-special URLs with an empty host can have their paths erased",
+ "href": "foo:///some/path",
+ "new_value": "",
+ "expected": {
+ "href": "foo://",
+ "pathname": ""
+ }
+ },
+ {
+ "comment": "Path-only URLs cannot have their paths erased",
+ "href": "foo:/some/path",
+ "new_value": "",
+ "expected": {
+ "href": "foo:/",
+ "pathname": "/"
+ }
+ },
+ {
+ "comment": "Path-only URLs always have an initial slash",
+ "href": "foo:/some/path",
+ "new_value": "test",
+ "expected": {
+ "href": "foo:/test",
+ "pathname": "/test"
+ }
+ },
+ {
"href": "unix:/run/foo.socket?timeout=10",
"new_value": "/var/log/../run/bar.socket",
"expected": {
@@ -1628,12 +1928,30 @@
}
},
{
+ "comment": "? doesn't mess up encoding",
+ "href": "http://example.net",
+ "new_value": "/?é",
+ "expected": {
+ "href": "http://example.net/%3F%C3%A9",
+ "pathname": "/%3F%C3%A9"
+ }
+ },
+ {
+ "comment": "# doesn't mess up encoding",
+ "href": "http://example.net",
+ "new_value": "/#é",
+ "expected": {
+ "href": "http://example.net/%23%C3%A9",
+ "pathname": "/%23%C3%A9"
+ }
+ },
+ {
"comment": "File URLs and (back)slashes",
"href": "file://monkey/",
"new_value": "\\\\",
"expected": {
- "href": "file://monkey/",
- "pathname": "/"
+ "href": "file://monkey//",
+ "pathname": "//"
}
},
{
@@ -1641,8 +1959,8 @@
"href": "file:///unicorn",
"new_value": "//\\/",
"expected": {
- "href": "file:///",
- "pathname": "/"
+ "href": "file://////",
+ "pathname": "////"
}
},
{
@@ -1650,8 +1968,77 @@
"href": "file:///unicorn",
"new_value": "//monkey/..//",
"expected": {
- "href": "file:///",
- "pathname": "/"
+ "href": "file://///",
+ "pathname": "///"
+ }
+ },
+ {
+ "comment": "Serialize /. in path",
+ "href": "non-spec:/",
+ "new_value": "/.//p",
+ "expected": {
+ "href": "non-spec:/.//p",
+ "pathname": "//p"
+ }
+ },
+ {
+ "href": "non-spec:/",
+ "new_value": "/..//p",
+ "expected": {
+ "href": "non-spec:/.//p",
+ "pathname": "//p"
+ }
+ },
+ {
+ "href": "non-spec:/",
+ "new_value": "//p",
+ "expected": {
+ "href": "non-spec:/.//p",
+ "pathname": "//p"
+ }
+ },
+ {
+ "comment": "Drop /. from path",
+ "href": "non-spec:/.//",
+ "new_value": "p",
+ "expected": {
+ "href": "non-spec:/p",
+ "pathname": "/p"
+ }
+ },
+ {
+ "comment": "Non-special URLs with non-opaque paths percent-encode U+0020",
+ "href": "data:/nospace",
+ "new_value": "space ",
+ "expected": {
+ "href": "data:/space%20",
+ "pathname": "/space%20"
+ }
+ },
+ {
+ "href": "sc:/nospace",
+ "new_value": "space ",
+ "expected": {
+ "href": "sc:/space%20",
+ "pathname": "/space%20"
+ }
+ },
+ {
+ "comment": "Trailing space should be encoded",
+ "href": "http://example.net",
+ "new_value": " ",
+ "expected": {
+ "href": "http://example.net/%20",
+ "pathname": "/%20"
+ }
+ },
+ {
+ "comment": "Trailing C0 control should be encoded",
+ "href": "http://example.net",
+ "new_value": "\u0000",
+ "expected": {
+ "href": "http://example.net/%00",
+ "pathname": "/%00"
}
}
],
@@ -1737,6 +2124,60 @@
"href": "http://example.net/?%c3%89t%C3%A9",
"search": "?%c3%89t%C3%A9"
}
+ },
+ {
+ "comment": "Drop trailing spaces from trailing opaque paths",
+ "href": "data:space ?query",
+ "new_value": "",
+ "expected": {
+ "href": "data:space",
+ "pathname": "space",
+ "search": ""
+ }
+ },
+ {
+ "href": "sc:space ?query",
+ "new_value": "",
+ "expected": {
+ "href": "sc:space",
+ "pathname": "space",
+ "search": ""
+ }
+ },
+ {
+ "comment": "Do not drop trailing spaces from non-trailing opaque paths",
+ "href": "data:space ?query#fragment",
+ "new_value": "",
+ "expected": {
+ "href": "data:space #fragment",
+ "search": ""
+ }
+ },
+ {
+ "href": "sc:space ?query#fragment",
+ "new_value": "",
+ "expected": {
+ "href": "sc:space #fragment",
+ "search": ""
+ }
+ },
+ {
+ "comment": "Trailing space should be encoded",
+ "href": "http://example.net",
+ "new_value": " ",
+ "expected": {
+ "href": "http://example.net/?%20",
+ "search": "?%20"
+ }
+ },
+ {
+ "comment": "Trailing C0 control should be encoded",
+ "href": "http://example.net",
+ "new_value": "\u0000",
+ "expected": {
+ "href": "http://example.net/?%00",
+ "search": "?%00"
+ }
}
],
"hash": [
@@ -1871,6 +2312,70 @@
"href": "javascript:alert(1)#castle",
"hash": "#castle"
}
+ },
+ {
+ "comment": "Drop trailing spaces from trailing opaque paths",
+ "href": "data:space #fragment",
+ "new_value": "",
+ "expected": {
+ "href": "data:space",
+ "pathname": "space",
+ "hash": ""
+ }
+ },
+ {
+ "href": "sc:space #fragment",
+ "new_value": "",
+ "expected": {
+ "href": "sc:space",
+ "pathname": "space",
+ "hash": ""
+ }
+ },
+ {
+ "comment": "Do not drop trailing spaces from non-trailing opaque paths",
+ "href": "data:space ?query#fragment",
+ "new_value": "",
+ "expected": {
+ "href": "data:space ?query",
+ "hash": ""
+ }
+ },
+ {
+ "href": "sc:space ?query#fragment",
+ "new_value": "",
+ "expected": {
+ "href": "sc:space ?query",
+ "hash": ""
+ }
+ },
+ {
+ "comment": "Trailing space should be encoded",
+ "href": "http://example.net",
+ "new_value": " ",
+ "expected": {
+ "href": "http://example.net/#%20",
+ "hash": "#%20"
+ }
+ },
+ {
+ "comment": "Trailing C0 control should be encoded",
+ "href": "http://example.net",
+ "new_value": "\u0000",
+ "expected": {
+ "href": "http://example.net/#%00",
+ "hash": "#%00"
+ }
+ }
+ ],
+ "href": [
+ {
+ "href": "file:///var/log/system.log",
+ "new_value": "http://0300.168.0xF0",
+ "expected": {
+ "href": "http://192.168.0.240/",
+ "protocol": "http:"
+ }
}
]
}
diff --git a/vendor/url/tests/unit.rs b/vendor/url/tests/unit.rs
index 6cb0f37fe..c27f237ba 100644
--- a/vendor/url/tests/unit.rs
+++ b/vendor/url/tests/unit.rs
@@ -472,7 +472,7 @@ fn append_trailing_slash() {
fn extend_query_pairs_then_mutate() {
let mut url: Url = "http://localhost:6767/foo/bar".parse().unwrap();
url.query_pairs_mut()
- .extend_pairs(vec![("auth", "my-token")].into_iter());
+ .extend_pairs(vec![("auth", "my-token")]);
url.check_invariants().unwrap();
assert_eq!(
url.to_string(),
@@ -1298,3 +1298,11 @@ fn test_file_with_drive_and_path() {
let url2 = url::Url::join(&url, s2).unwrap();
assert_eq!(url2.to_string(), "file:///p:/a");
}
+
+#[test]
+fn issue_864() {
+ let mut url = url::Url::parse("file://").unwrap();
+ dbg!(&url);
+ url.set_path("x");
+ dbg!(&url);
+}
diff --git a/vendor/url/tests/urltestdata.json b/vendor/url/tests/urltestdata.json
index 53d036886..1e61729d1 100644
--- a/vendor/url/tests/urltestdata.json
+++ b/vendor/url/tests/urltestdata.json
@@ -1,5 +1,5 @@
[
- "# Based on http://trac.webkit.org/browser/trunk/LayoutTests/fast/url/script-tests/segments.js",
+ "# Pulled from https://github.com/web-platform-tests/wpt/blob/befe66343e5f21dc464c8c772c6d20695936714f/url/resources/urltestdata.json",
{
"input": "http://example\t.\norg",
"base": "http://example.org/foo/bar",
@@ -32,7 +32,7 @@
},
{
"input": "https://test:@test",
- "base": "about:blank",
+ "base": null,
"href": "https://test@test/",
"origin": "https://test",
"protocol": "https:",
@@ -47,7 +47,7 @@
},
{
"input": "https://:@test",
- "base": "about:blank",
+ "base": null,
"href": "https://test/",
"origin": "https://test",
"protocol": "https:",
@@ -62,7 +62,7 @@
},
{
"input": "non-special://test:@test/x",
- "base": "about:blank",
+ "base": null,
"href": "non-special://test@test/x",
"origin": "null",
"protocol": "non-special:",
@@ -77,7 +77,7 @@
},
{
"input": "non-special://:@test/x",
- "base": "about:blank",
+ "base": null,
"href": "non-special://test/x",
"origin": "null",
"protocol": "non-special:",
@@ -167,7 +167,7 @@
},
{
"input": "lolscheme:x x#x x",
- "base": "about:blank",
+ "base": null,
"href": "lolscheme:x x#x%20x",
"protocol": "lolscheme:",
"username": "",
@@ -1075,22 +1075,22 @@
},
{
"input": "file://example:1/",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "file://example:test/",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "file://example%/",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "file://[example]/",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
@@ -1754,7 +1754,7 @@
"# Based on http://trac.webkit.org/browser/trunk/LayoutTests/fast/url/script-tests/path.js",
{
"input": "http://example.com/././foo",
- "base": "about:blank",
+ "base": null,
"href": "http://example.com/foo",
"origin": "http://example.com",
"protocol": "http:",
@@ -1769,7 +1769,7 @@
},
{
"input": "http://example.com/./.foo",
- "base": "about:blank",
+ "base": null,
"href": "http://example.com/.foo",
"origin": "http://example.com",
"protocol": "http:",
@@ -1784,7 +1784,7 @@
},
{
"input": "http://example.com/foo/.",
- "base": "about:blank",
+ "base": null,
"href": "http://example.com/foo/",
"origin": "http://example.com",
"protocol": "http:",
@@ -1799,7 +1799,7 @@
},
{
"input": "http://example.com/foo/./",
- "base": "about:blank",
+ "base": null,
"href": "http://example.com/foo/",
"origin": "http://example.com",
"protocol": "http:",
@@ -1814,7 +1814,7 @@
},
{
"input": "http://example.com/foo/bar/..",
- "base": "about:blank",
+ "base": null,
"href": "http://example.com/foo/",
"origin": "http://example.com",
"protocol": "http:",
@@ -1829,7 +1829,7 @@
},
{
"input": "http://example.com/foo/bar/../",
- "base": "about:blank",
+ "base": null,
"href": "http://example.com/foo/",
"origin": "http://example.com",
"protocol": "http:",
@@ -1844,7 +1844,7 @@
},
{
"input": "http://example.com/foo/..bar",
- "base": "about:blank",
+ "base": null,
"href": "http://example.com/foo/..bar",
"origin": "http://example.com",
"protocol": "http:",
@@ -1859,7 +1859,7 @@
},
{
"input": "http://example.com/foo/bar/../ton",
- "base": "about:blank",
+ "base": null,
"href": "http://example.com/foo/ton",
"origin": "http://example.com",
"protocol": "http:",
@@ -1874,7 +1874,7 @@
},
{
"input": "http://example.com/foo/bar/../ton/../../a",
- "base": "about:blank",
+ "base": null,
"href": "http://example.com/a",
"origin": "http://example.com",
"protocol": "http:",
@@ -1889,7 +1889,7 @@
},
{
"input": "http://example.com/foo/../../..",
- "base": "about:blank",
+ "base": null,
"href": "http://example.com/",
"origin": "http://example.com",
"protocol": "http:",
@@ -1904,7 +1904,7 @@
},
{
"input": "http://example.com/foo/../../../ton",
- "base": "about:blank",
+ "base": null,
"href": "http://example.com/ton",
"origin": "http://example.com",
"protocol": "http:",
@@ -1919,7 +1919,7 @@
},
{
"input": "http://example.com/foo/%2e",
- "base": "about:blank",
+ "base": null,
"href": "http://example.com/foo/",
"origin": "http://example.com",
"protocol": "http:",
@@ -1934,7 +1934,7 @@
},
{
"input": "http://example.com/foo/%2e%2",
- "base": "about:blank",
+ "base": null,
"href": "http://example.com/foo/%2e%2",
"origin": "http://example.com",
"protocol": "http:",
@@ -1949,7 +1949,7 @@
},
{
"input": "http://example.com/foo/%2e./%2e%2e/.%2e/%2e.bar",
- "base": "about:blank",
+ "base": null,
"href": "http://example.com/%2e.bar",
"origin": "http://example.com",
"protocol": "http:",
@@ -1964,7 +1964,7 @@
},
{
"input": "http://example.com////../..",
- "base": "about:blank",
+ "base": null,
"href": "http://example.com//",
"origin": "http://example.com",
"protocol": "http:",
@@ -1979,7 +1979,7 @@
},
{
"input": "http://example.com/foo/bar//../..",
- "base": "about:blank",
+ "base": null,
"href": "http://example.com/foo/",
"origin": "http://example.com",
"protocol": "http:",
@@ -1994,7 +1994,7 @@
},
{
"input": "http://example.com/foo/bar//..",
- "base": "about:blank",
+ "base": null,
"href": "http://example.com/foo/bar/",
"origin": "http://example.com",
"protocol": "http:",
@@ -2009,7 +2009,7 @@
},
{
"input": "http://example.com/foo",
- "base": "about:blank",
+ "base": null,
"href": "http://example.com/foo",
"origin": "http://example.com",
"protocol": "http:",
@@ -2024,7 +2024,7 @@
},
{
"input": "http://example.com/%20foo",
- "base": "about:blank",
+ "base": null,
"href": "http://example.com/%20foo",
"origin": "http://example.com",
"protocol": "http:",
@@ -2039,7 +2039,7 @@
},
{
"input": "http://example.com/foo%",
- "base": "about:blank",
+ "base": null,
"href": "http://example.com/foo%",
"origin": "http://example.com",
"protocol": "http:",
@@ -2054,7 +2054,7 @@
},
{
"input": "http://example.com/foo%2",
- "base": "about:blank",
+ "base": null,
"href": "http://example.com/foo%2",
"origin": "http://example.com",
"protocol": "http:",
@@ -2069,7 +2069,7 @@
},
{
"input": "http://example.com/foo%2zbar",
- "base": "about:blank",
+ "base": null,
"href": "http://example.com/foo%2zbar",
"origin": "http://example.com",
"protocol": "http:",
@@ -2084,7 +2084,7 @@
},
{
"input": "http://example.com/foo%2©zbar",
- "base": "about:blank",
+ "base": null,
"href": "http://example.com/foo%2%C3%82%C2%A9zbar",
"origin": "http://example.com",
"protocol": "http:",
@@ -2099,7 +2099,7 @@
},
{
"input": "http://example.com/foo%41%7a",
- "base": "about:blank",
+ "base": null,
"href": "http://example.com/foo%41%7a",
"origin": "http://example.com",
"protocol": "http:",
@@ -2114,7 +2114,7 @@
},
{
"input": "http://example.com/foo\t\u0091%91",
- "base": "about:blank",
+ "base": null,
"href": "http://example.com/foo%C2%91%91",
"origin": "http://example.com",
"protocol": "http:",
@@ -2129,7 +2129,7 @@
},
{
"input": "http://example.com/foo%00%51",
- "base": "about:blank",
+ "base": null,
"href": "http://example.com/foo%00%51",
"origin": "http://example.com",
"protocol": "http:",
@@ -2144,7 +2144,7 @@
},
{
"input": "http://example.com/(%28:%3A%29)",
- "base": "about:blank",
+ "base": null,
"href": "http://example.com/(%28:%3A%29)",
"origin": "http://example.com",
"protocol": "http:",
@@ -2159,7 +2159,7 @@
},
{
"input": "http://example.com/%3A%3a%3C%3c",
- "base": "about:blank",
+ "base": null,
"href": "http://example.com/%3A%3a%3C%3c",
"origin": "http://example.com",
"protocol": "http:",
@@ -2174,7 +2174,7 @@
},
{
"input": "http://example.com/foo\tbar",
- "base": "about:blank",
+ "base": null,
"href": "http://example.com/foobar",
"origin": "http://example.com",
"protocol": "http:",
@@ -2189,7 +2189,7 @@
},
{
"input": "http://example.com\\\\foo\\\\bar",
- "base": "about:blank",
+ "base": null,
"href": "http://example.com//foo//bar",
"origin": "http://example.com",
"protocol": "http:",
@@ -2204,7 +2204,7 @@
},
{
"input": "http://example.com/%7Ffp3%3Eju%3Dduvgw%3Dd",
- "base": "about:blank",
+ "base": null,
"href": "http://example.com/%7Ffp3%3Eju%3Dduvgw%3Dd",
"origin": "http://example.com",
"protocol": "http:",
@@ -2219,7 +2219,7 @@
},
{
"input": "http://example.com/@asdf%40",
- "base": "about:blank",
+ "base": null,
"href": "http://example.com/@asdf%40",
"origin": "http://example.com",
"protocol": "http:",
@@ -2234,7 +2234,7 @@
},
{
"input": "http://example.com/你好你好",
- "base": "about:blank",
+ "base": null,
"href": "http://example.com/%E4%BD%A0%E5%A5%BD%E4%BD%A0%E5%A5%BD",
"origin": "http://example.com",
"protocol": "http:",
@@ -2249,7 +2249,7 @@
},
{
"input": "http://example.com/‥/foo",
- "base": "about:blank",
+ "base": null,
"href": "http://example.com/%E2%80%A5/foo",
"origin": "http://example.com",
"protocol": "http:",
@@ -2264,7 +2264,7 @@
},
{
"input": "http://example.com//foo",
- "base": "about:blank",
+ "base": null,
"href": "http://example.com/%EF%BB%BF/foo",
"origin": "http://example.com",
"protocol": "http:",
@@ -2279,7 +2279,7 @@
},
{
"input": "http://example.com/‮/foo/‭/bar",
- "base": "about:blank",
+ "base": null,
"href": "http://example.com/%E2%80%AE/foo/%E2%80%AD/bar",
"origin": "http://example.com",
"protocol": "http:",
@@ -2295,7 +2295,7 @@
"# Based on http://trac.webkit.org/browser/trunk/LayoutTests/fast/url/script-tests/relative.js",
{
"input": "http://www.google.com/foo?bar=baz#",
- "base": "about:blank",
+ "base": null,
"href": "http://www.google.com/foo?bar=baz#",
"origin": "http://www.google.com",
"protocol": "http:",
@@ -2310,7 +2310,7 @@
},
{
"input": "http://www.google.com/foo?bar=baz# »",
- "base": "about:blank",
+ "base": null,
"href": "http://www.google.com/foo?bar=baz#%20%C2%BB",
"origin": "http://www.google.com",
"protocol": "http:",
@@ -2325,7 +2325,7 @@
},
{
"input": "data:test# »",
- "base": "about:blank",
+ "base": null,
"href": "data:test#%20%C2%BB",
"origin": "null",
"protocol": "data:",
@@ -2340,7 +2340,7 @@
},
{
"input": "http://www.google.com",
- "base": "about:blank",
+ "base": null,
"href": "http://www.google.com/",
"origin": "http://www.google.com",
"protocol": "http:",
@@ -2355,7 +2355,7 @@
},
{
"input": "http://192.0x00A80001",
- "base": "about:blank",
+ "base": null,
"href": "http://192.168.0.1/",
"origin": "http://192.168.0.1",
"protocol": "http:",
@@ -2370,7 +2370,7 @@
},
{
"input": "http://www/foo%2Ehtml",
- "base": "about:blank",
+ "base": null,
"href": "http://www/foo%2Ehtml",
"origin": "http://www",
"protocol": "http:",
@@ -2385,7 +2385,7 @@
},
{
"input": "http://www/foo/%2E/html",
- "base": "about:blank",
+ "base": null,
"href": "http://www/foo/html",
"origin": "http://www",
"protocol": "http:",
@@ -2400,12 +2400,12 @@
},
{
"input": "http://user:pass@/",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "http://%25DOMAIN:foobar@foodomain.com/",
- "base": "about:blank",
+ "base": null,
"href": "http://%25DOMAIN:foobar@foodomain.com/",
"origin": "http://foodomain.com",
"protocol": "http:",
@@ -2420,7 +2420,7 @@
},
{
"input": "http:\\\\www.google.com\\foo",
- "base": "about:blank",
+ "base": null,
"href": "http://www.google.com/foo",
"origin": "http://www.google.com",
"protocol": "http:",
@@ -2435,7 +2435,7 @@
},
{
"input": "http://foo:80/",
- "base": "about:blank",
+ "base": null,
"href": "http://foo/",
"origin": "http://foo",
"protocol": "http:",
@@ -2450,7 +2450,7 @@
},
{
"input": "http://foo:81/",
- "base": "about:blank",
+ "base": null,
"href": "http://foo:81/",
"origin": "http://foo:81",
"protocol": "http:",
@@ -2465,7 +2465,7 @@
},
{
"input": "httpa://foo:80/",
- "base": "about:blank",
+ "base": null,
"href": "httpa://foo:80/",
"origin": "null",
"protocol": "httpa:",
@@ -2480,12 +2480,12 @@
},
{
"input": "http://foo:-80/",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "https://foo:443/",
- "base": "about:blank",
+ "base": null,
"href": "https://foo/",
"origin": "https://foo",
"protocol": "https:",
@@ -2500,7 +2500,7 @@
},
{
"input": "https://foo:80/",
- "base": "about:blank",
+ "base": null,
"href": "https://foo:80/",
"origin": "https://foo:80",
"protocol": "https:",
@@ -2515,7 +2515,7 @@
},
{
"input": "ftp://foo:21/",
- "base": "about:blank",
+ "base": null,
"href": "ftp://foo/",
"origin": "ftp://foo",
"protocol": "ftp:",
@@ -2530,7 +2530,7 @@
},
{
"input": "ftp://foo:80/",
- "base": "about:blank",
+ "base": null,
"href": "ftp://foo:80/",
"origin": "ftp://foo:80",
"protocol": "ftp:",
@@ -2545,7 +2545,7 @@
},
{
"input": "gopher://foo:70/",
- "base": "about:blank",
+ "base": null,
"href": "gopher://foo:70/",
"origin": "null",
"protocol": "gopher:",
@@ -2560,7 +2560,7 @@
},
{
"input": "gopher://foo:443/",
- "base": "about:blank",
+ "base": null,
"href": "gopher://foo:443/",
"origin": "null",
"protocol": "gopher:",
@@ -2575,7 +2575,7 @@
},
{
"input": "ws://foo:80/",
- "base": "about:blank",
+ "base": null,
"href": "ws://foo/",
"origin": "ws://foo",
"protocol": "ws:",
@@ -2590,7 +2590,7 @@
},
{
"input": "ws://foo:81/",
- "base": "about:blank",
+ "base": null,
"href": "ws://foo:81/",
"origin": "ws://foo:81",
"protocol": "ws:",
@@ -2605,7 +2605,7 @@
},
{
"input": "ws://foo:443/",
- "base": "about:blank",
+ "base": null,
"href": "ws://foo:443/",
"origin": "ws://foo:443",
"protocol": "ws:",
@@ -2620,7 +2620,7 @@
},
{
"input": "ws://foo:815/",
- "base": "about:blank",
+ "base": null,
"href": "ws://foo:815/",
"origin": "ws://foo:815",
"protocol": "ws:",
@@ -2635,7 +2635,7 @@
},
{
"input": "wss://foo:80/",
- "base": "about:blank",
+ "base": null,
"href": "wss://foo:80/",
"origin": "wss://foo:80",
"protocol": "wss:",
@@ -2650,7 +2650,7 @@
},
{
"input": "wss://foo:81/",
- "base": "about:blank",
+ "base": null,
"href": "wss://foo:81/",
"origin": "wss://foo:81",
"protocol": "wss:",
@@ -2665,7 +2665,7 @@
},
{
"input": "wss://foo:443/",
- "base": "about:blank",
+ "base": null,
"href": "wss://foo/",
"origin": "wss://foo",
"protocol": "wss:",
@@ -2680,7 +2680,7 @@
},
{
"input": "wss://foo:815/",
- "base": "about:blank",
+ "base": null,
"href": "wss://foo:815/",
"origin": "wss://foo:815",
"protocol": "wss:",
@@ -2695,7 +2695,7 @@
},
{
"input": "http:/example.com/",
- "base": "about:blank",
+ "base": null,
"href": "http://example.com/",
"origin": "http://example.com",
"protocol": "http:",
@@ -2710,7 +2710,7 @@
},
{
"input": "ftp:/example.com/",
- "base": "about:blank",
+ "base": null,
"href": "ftp://example.com/",
"origin": "ftp://example.com",
"protocol": "ftp:",
@@ -2725,7 +2725,7 @@
},
{
"input": "https:/example.com/",
- "base": "about:blank",
+ "base": null,
"href": "https://example.com/",
"origin": "https://example.com",
"protocol": "https:",
@@ -2740,7 +2740,7 @@
},
{
"input": "madeupscheme:/example.com/",
- "base": "about:blank",
+ "base": null,
"href": "madeupscheme:/example.com/",
"origin": "null",
"protocol": "madeupscheme:",
@@ -2755,7 +2755,7 @@
},
{
"input": "file:/example.com/",
- "base": "about:blank",
+ "base": null,
"href": "file:///example.com/",
"protocol": "file:",
"username": "",
@@ -2769,7 +2769,7 @@
},
{
"input": "ftps:/example.com/",
- "base": "about:blank",
+ "base": null,
"href": "ftps:/example.com/",
"origin": "null",
"protocol": "ftps:",
@@ -2784,7 +2784,7 @@
},
{
"input": "gopher:/example.com/",
- "base": "about:blank",
+ "base": null,
"href": "gopher:/example.com/",
"origin": "null",
"protocol": "gopher:",
@@ -2799,7 +2799,7 @@
},
{
"input": "ws:/example.com/",
- "base": "about:blank",
+ "base": null,
"href": "ws://example.com/",
"origin": "ws://example.com",
"protocol": "ws:",
@@ -2814,7 +2814,7 @@
},
{
"input": "wss:/example.com/",
- "base": "about:blank",
+ "base": null,
"href": "wss://example.com/",
"origin": "wss://example.com",
"protocol": "wss:",
@@ -2829,7 +2829,7 @@
},
{
"input": "data:/example.com/",
- "base": "about:blank",
+ "base": null,
"href": "data:/example.com/",
"origin": "null",
"protocol": "data:",
@@ -2844,7 +2844,7 @@
},
{
"input": "javascript:/example.com/",
- "base": "about:blank",
+ "base": null,
"href": "javascript:/example.com/",
"origin": "null",
"protocol": "javascript:",
@@ -2859,7 +2859,7 @@
},
{
"input": "mailto:/example.com/",
- "base": "about:blank",
+ "base": null,
"href": "mailto:/example.com/",
"origin": "null",
"protocol": "mailto:",
@@ -2874,7 +2874,7 @@
},
{
"input": "http:example.com/",
- "base": "about:blank",
+ "base": null,
"href": "http://example.com/",
"origin": "http://example.com",
"protocol": "http:",
@@ -2889,7 +2889,7 @@
},
{
"input": "ftp:example.com/",
- "base": "about:blank",
+ "base": null,
"href": "ftp://example.com/",
"origin": "ftp://example.com",
"protocol": "ftp:",
@@ -2904,7 +2904,7 @@
},
{
"input": "https:example.com/",
- "base": "about:blank",
+ "base": null,
"href": "https://example.com/",
"origin": "https://example.com",
"protocol": "https:",
@@ -2919,7 +2919,7 @@
},
{
"input": "madeupscheme:example.com/",
- "base": "about:blank",
+ "base": null,
"href": "madeupscheme:example.com/",
"origin": "null",
"protocol": "madeupscheme:",
@@ -2934,7 +2934,7 @@
},
{
"input": "ftps:example.com/",
- "base": "about:blank",
+ "base": null,
"href": "ftps:example.com/",
"origin": "null",
"protocol": "ftps:",
@@ -2949,7 +2949,7 @@
},
{
"input": "gopher:example.com/",
- "base": "about:blank",
+ "base": null,
"href": "gopher:example.com/",
"origin": "null",
"protocol": "gopher:",
@@ -2964,7 +2964,7 @@
},
{
"input": "ws:example.com/",
- "base": "about:blank",
+ "base": null,
"href": "ws://example.com/",
"origin": "ws://example.com",
"protocol": "ws:",
@@ -2979,7 +2979,7 @@
},
{
"input": "wss:example.com/",
- "base": "about:blank",
+ "base": null,
"href": "wss://example.com/",
"origin": "wss://example.com",
"protocol": "wss:",
@@ -2994,7 +2994,7 @@
},
{
"input": "data:example.com/",
- "base": "about:blank",
+ "base": null,
"href": "data:example.com/",
"origin": "null",
"protocol": "data:",
@@ -3009,7 +3009,7 @@
},
{
"input": "javascript:example.com/",
- "base": "about:blank",
+ "base": null,
"href": "javascript:example.com/",
"origin": "null",
"protocol": "javascript:",
@@ -3024,7 +3024,7 @@
},
{
"input": "mailto:example.com/",
- "base": "about:blank",
+ "base": null,
"href": "mailto:example.com/",
"origin": "null",
"protocol": "mailto:",
@@ -3040,7 +3040,7 @@
"# Based on http://trac.webkit.org/browser/trunk/LayoutTests/fast/url/segments-userinfo-vs-host.html",
{
"input": "http:@www.example.com",
- "base": "about:blank",
+ "base": null,
"href": "http://www.example.com/",
"origin": "http://www.example.com",
"protocol": "http:",
@@ -3055,7 +3055,7 @@
},
{
"input": "http:/@www.example.com",
- "base": "about:blank",
+ "base": null,
"href": "http://www.example.com/",
"origin": "http://www.example.com",
"protocol": "http:",
@@ -3070,7 +3070,7 @@
},
{
"input": "http://@www.example.com",
- "base": "about:blank",
+ "base": null,
"href": "http://www.example.com/",
"origin": "http://www.example.com",
"protocol": "http:",
@@ -3085,7 +3085,7 @@
},
{
"input": "http:a:b@www.example.com",
- "base": "about:blank",
+ "base": null,
"href": "http://a:b@www.example.com/",
"origin": "http://www.example.com",
"protocol": "http:",
@@ -3100,7 +3100,7 @@
},
{
"input": "http:/a:b@www.example.com",
- "base": "about:blank",
+ "base": null,
"href": "http://a:b@www.example.com/",
"origin": "http://www.example.com",
"protocol": "http:",
@@ -3115,7 +3115,7 @@
},
{
"input": "http://a:b@www.example.com",
- "base": "about:blank",
+ "base": null,
"href": "http://a:b@www.example.com/",
"origin": "http://www.example.com",
"protocol": "http:",
@@ -3130,7 +3130,7 @@
},
{
"input": "http://@pple.com",
- "base": "about:blank",
+ "base": null,
"href": "http://pple.com/",
"origin": "http://pple.com",
"protocol": "http:",
@@ -3145,7 +3145,7 @@
},
{
"input": "http::b@www.example.com",
- "base": "about:blank",
+ "base": null,
"href": "http://:b@www.example.com/",
"origin": "http://www.example.com",
"protocol": "http:",
@@ -3160,7 +3160,7 @@
},
{
"input": "http:/:b@www.example.com",
- "base": "about:blank",
+ "base": null,
"href": "http://:b@www.example.com/",
"origin": "http://www.example.com",
"protocol": "http:",
@@ -3175,7 +3175,7 @@
},
{
"input": "http://:b@www.example.com",
- "base": "about:blank",
+ "base": null,
"href": "http://:b@www.example.com/",
"origin": "http://www.example.com",
"protocol": "http:",
@@ -3190,64 +3190,64 @@
},
{
"input": "http:/:@/www.example.com",
- "base": "about:blank",
+ "base": null,
"failure": true,
- "inputCanBeRelative": true
+ "relativeTo": "non-opaque-path-base"
},
{
"input": "http://user@/www.example.com",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "http:@/www.example.com",
- "base": "about:blank",
+ "base": null,
"failure": true,
- "inputCanBeRelative": true
+ "relativeTo": "non-opaque-path-base"
},
{
"input": "http:/@/www.example.com",
- "base": "about:blank",
+ "base": null,
"failure": true,
- "inputCanBeRelative": true
+ "relativeTo": "non-opaque-path-base"
},
{
"input": "http://@/www.example.com",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "https:@/www.example.com",
- "base": "about:blank",
+ "base": null,
"failure": true,
- "inputCanBeRelative": true
+ "relativeTo": "non-opaque-path-base"
},
{
"input": "http:a:b@/www.example.com",
- "base": "about:blank",
+ "base": null,
"failure": true,
- "inputCanBeRelative": true
+ "relativeTo": "non-opaque-path-base"
},
{
"input": "http:/a:b@/www.example.com",
- "base": "about:blank",
+ "base": null,
"failure": true,
- "inputCanBeRelative": true
+ "relativeTo": "non-opaque-path-base"
},
{
"input": "http://a:b@/www.example.com",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "http::@/www.example.com",
- "base": "about:blank",
+ "base": null,
"failure": true,
- "inputCanBeRelative": true
+ "relativeTo": "non-opaque-path-base"
},
{
"input": "http:a:@www.example.com",
- "base": "about:blank",
+ "base": null,
"href": "http://a@www.example.com/",
"origin": "http://www.example.com",
"protocol": "http:",
@@ -3262,7 +3262,7 @@
},
{
"input": "http:/a:@www.example.com",
- "base": "about:blank",
+ "base": null,
"href": "http://a@www.example.com/",
"origin": "http://www.example.com",
"protocol": "http:",
@@ -3277,7 +3277,7 @@
},
{
"input": "http://a:@www.example.com",
- "base": "about:blank",
+ "base": null,
"href": "http://a@www.example.com/",
"origin": "http://www.example.com",
"protocol": "http:",
@@ -3292,7 +3292,7 @@
},
{
"input": "http://www.@pple.com",
- "base": "about:blank",
+ "base": null,
"href": "http://www.@pple.com/",
"origin": "http://pple.com",
"protocol": "http:",
@@ -3307,24 +3307,24 @@
},
{
"input": "http:@:www.example.com",
- "base": "about:blank",
+ "base": null,
"failure": true,
- "inputCanBeRelative": true
+ "relativeTo": "non-opaque-path-base"
},
{
"input": "http:/@:www.example.com",
- "base": "about:blank",
+ "base": null,
"failure": true,
- "inputCanBeRelative": true
+ "relativeTo": "non-opaque-path-base"
},
{
"input": "http://@:www.example.com",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "http://:@www.example.com",
- "base": "about:blank",
+ "base": null,
"href": "http://www.example.com/",
"origin": "http://www.example.com",
"protocol": "http:",
@@ -3622,7 +3622,7 @@
"Leading and trailing C0 control or space",
{
"input": "\u0000\u001b\u0004\u0012 http://example.com/\u001f \u000d ",
- "base": "about:blank",
+ "base": null,
"href": "http://example.com/",
"origin": "http://example.com",
"protocol": "http:",
@@ -3666,17 +3666,17 @@
"U+FFFD",
{
"input": "https://\ufffd",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "https://%EF%BF%BD",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "https://x/\ufffd?\ufffd#\ufffd",
- "base": "about:blank",
+ "base": null,
"href": "https://x/%EF%BF%BD?%EF%BF%BD#%EF%BF%BD",
"origin": "https://x",
"protocol": "https:",
@@ -3692,33 +3692,33 @@
"Domain is ASCII, but a label is invalid IDNA",
{
"input": "http://a.b.c.xn--pokxncvks",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "http://10.0.0.xn--pokxncvks",
- "base": "about:blank",
+ "base": null,
"failure": true
},
"IDNA labels should be matched case-insensitively",
{
"input": "http://a.b.c.XN--pokxncvks",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "http://a.b.c.Xn--pokxncvks",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "http://10.0.0.XN--pokxncvks",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "http://10.0.0.xN--pokxncvks",
- "base": "about:blank",
+ "base": null,
"failure": true
},
"Test name prepping, fullwidth input should be converted to ASCII and NOT IDN-ized. This is 'Go' in fullwidth UTF-8/UTF-16.",
@@ -3777,7 +3777,7 @@
},
{
"input": "https://faß.ExAmPlE/",
- "base": "about:blank",
+ "base": null,
"href": "https://xn--fa-hia.example/",
"origin": "https://xn--fa-hia.example",
"protocol": "https:",
@@ -3792,7 +3792,7 @@
},
{
"input": "sc://faß.ExAmPlE/",
- "base": "about:blank",
+ "base": null,
"href": "sc://fa%C3%9F.ExAmPlE/",
"origin": "null",
"protocol": "sc:",
@@ -3872,7 +3872,7 @@
},
{
"input": "https://x x:12",
- "base": "about:blank",
+ "base": null,
"failure": true
},
"Fullwidth and escaped UTF-8 fullwidth should still be treated as IP",
@@ -3894,7 +3894,7 @@
"Domains with empty labels",
{
"input": "http://./",
- "base": "about:blank",
+ "base": null,
"href": "http://./",
"origin": "http://.",
"protocol": "http:",
@@ -3909,7 +3909,7 @@
},
{
"input": "http://../",
- "base": "about:blank",
+ "base": null,
"href": "http://../",
"origin": "http://..",
"protocol": "http:",
@@ -3925,7 +3925,7 @@
"Non-special domains with empty labels",
{
"input": "h://.",
- "base": "about:blank",
+ "base": null,
"href": "h://.",
"origin": "null",
"protocol": "h:",
@@ -3941,7 +3941,7 @@
"Broken IPv6",
{
"input": "http://[www.google.com]/",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
@@ -4067,6 +4067,21 @@
"hash": "#x"
},
{
+ "input": "#x:y",
+ "base": "about:blank",
+ "href": "about:blank#x:y",
+ "origin": "null",
+ "protocol": "about:",
+ "username": "",
+ "password": "",
+ "host": "",
+ "hostname": "",
+ "port": "",
+ "pathname": "blank",
+ "search": "",
+ "hash": "#x:y"
+ },
+ {
"input": "#",
"base": "test:test?test",
"href": "test:test?test#",
@@ -4131,7 +4146,7 @@
"byte is ' and url is special",
{
"input": "http://host/?'",
- "base": "about:blank",
+ "base": null,
"href": "http://host/?%27",
"origin": "http://host",
"protocol": "http:",
@@ -4146,7 +4161,7 @@
},
{
"input": "notspecial://host/?'",
- "base": "about:blank",
+ "base": null,
"href": "notspecial://host/?'",
"origin": "null",
"protocol": "notspecial:",
@@ -4504,7 +4519,7 @@
"# make sure that relative URL logic works on known typically non-relative schemes too",
{
"input": "about:/../",
- "base": "about:blank",
+ "base": null,
"href": "about:/",
"origin": "null",
"protocol": "about:",
@@ -4519,7 +4534,7 @@
},
{
"input": "data:/../",
- "base": "about:blank",
+ "base": null,
"href": "data:/",
"origin": "null",
"protocol": "data:",
@@ -4534,7 +4549,7 @@
},
{
"input": "javascript:/../",
- "base": "about:blank",
+ "base": null,
"href": "javascript:/",
"origin": "null",
"protocol": "javascript:",
@@ -4549,7 +4564,7 @@
},
{
"input": "mailto:/../",
- "base": "about:blank",
+ "base": null,
"href": "mailto:/",
"origin": "null",
"protocol": "mailto:",
@@ -4565,7 +4580,7 @@
"# unknown schemes and their hosts",
{
"input": "sc://ñ.test/",
- "base": "about:blank",
+ "base": null,
"href": "sc://%C3%B1.test/",
"origin": "null",
"protocol": "sc:",
@@ -4580,7 +4595,7 @@
},
{
"input": "sc://%/",
- "base": "about:blank",
+ "base": null,
"href": "sc://%/",
"protocol": "sc:",
"username": "",
@@ -4594,22 +4609,22 @@
},
{
"input": "sc://@/",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "sc://te@s:t@/",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "sc://:/",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "sc://:12/",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
@@ -4630,7 +4645,7 @@
"# unknown schemes and backslashes",
{
"input": "sc:\\../",
- "base": "about:blank",
+ "base": null,
"href": "sc:\\../",
"origin": "null",
"protocol": "sc:",
@@ -4646,7 +4661,7 @@
"# unknown scheme with path looking like a password",
{
"input": "sc::a@example.net",
- "base": "about:blank",
+ "base": null,
"href": "sc::a@example.net",
"origin": "null",
"protocol": "sc:",
@@ -4662,7 +4677,7 @@
"# unknown scheme with bogus percent-encoding",
{
"input": "wow:%NBD",
- "base": "about:blank",
+ "base": null,
"href": "wow:%NBD",
"origin": "null",
"protocol": "wow:",
@@ -4677,7 +4692,7 @@
},
{
"input": "wow:%1G",
- "base": "about:blank",
+ "base": null,
"href": "wow:%1G",
"origin": "null",
"protocol": "wow:",
@@ -4693,7 +4708,7 @@
"# unknown scheme with non-URL characters",
{
"input": "wow:\uFFFF",
- "base": "about:blank",
+ "base": null,
"href": "wow:%EF%BF%BF",
"origin": "null",
"protocol": "wow:",
@@ -4709,53 +4724,53 @@
"Forbidden host code points",
{
"input": "sc://a\u0000b/",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "sc://a b/",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "sc://a<b",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "sc://a>b",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "sc://a[b/",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "sc://a\\b/",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "sc://a]b/",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "sc://a^b",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "sc://a|b/",
- "base": "about:blank",
+ "base": null,
"failure": true
},
"Forbidden host codepoints: tabs and newlines are removed during preprocessing",
{
"input": "foo://ho\u0009st/",
- "base": "about:blank",
+ "base": null,
"hash": "",
"host": "host",
"hostname": "host",
@@ -4769,7 +4784,7 @@
},
{
"input": "foo://ho\u000Ast/",
- "base": "about:blank",
+ "base": null,
"hash": "",
"host": "host",
"hostname": "host",
@@ -4783,7 +4798,7 @@
},
{
"input": "foo://ho\u000Dst/",
- "base": "about:blank",
+ "base": null,
"hash": "",
"host": "host",
"hostname": "host",
@@ -4798,198 +4813,198 @@
"Forbidden domain code-points",
{
"input": "http://a\u0000b/",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "http://a\u0001b/",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "http://a\u0002b/",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "http://a\u0003b/",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "http://a\u0004b/",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "http://a\u0005b/",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "http://a\u0006b/",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "http://a\u0007b/",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "http://a\u0008b/",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "http://a\u000Bb/",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "http://a\u000Cb/",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "http://a\u000Eb/",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "http://a\u000Fb/",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "http://a\u0010b/",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "http://a\u0011b/",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "http://a\u0012b/",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "http://a\u0013b/",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "http://a\u0014b/",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "http://a\u0015b/",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "http://a\u0016b/",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "http://a\u0017b/",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "http://a\u0018b/",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "http://a\u0019b/",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "http://a\u001Ab/",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "http://a\u001Bb/",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "http://a\u001Cb/",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "http://a\u001Db/",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "http://a\u001Eb/",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "http://a\u001Fb/",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "http://a b/",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "http://a%b/",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "http://a<b",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "http://a>b",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "http://a[b/",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "http://a]b/",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "http://a^b",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "http://a|b/",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "http://a\u007Fb/",
- "base": "about:blank",
+ "base": null,
"failure": true
},
"Forbidden domain codepoints: tabs and newlines are removed during preprocessing",
{
"input": "http://ho\u0009st/",
- "base": "about:blank",
+ "base": null,
"hash": "",
"host": "host",
"hostname": "host",
@@ -5003,7 +5018,7 @@
},
{
"input": "http://ho\u000Ast/",
- "base": "about:blank",
+ "base": null,
"hash": "",
"host": "host",
"hostname": "host",
@@ -5017,7 +5032,7 @@
},
{
"input": "http://ho\u000Dst/",
- "base": "about:blank",
+ "base": null,
"hash": "",
"host": "host",
"hostname": "host",
@@ -5032,238 +5047,238 @@
"Encoded forbidden domain codepoints in special URLs",
{
"input": "http://ho%00st/",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "http://ho%01st/",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "http://ho%02st/",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "http://ho%03st/",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "http://ho%04st/",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "http://ho%05st/",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "http://ho%06st/",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "http://ho%07st/",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "http://ho%08st/",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "http://ho%09st/",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "http://ho%0Ast/",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "http://ho%0Bst/",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "http://ho%0Cst/",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "http://ho%0Dst/",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "http://ho%0Est/",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "http://ho%0Fst/",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "http://ho%10st/",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "http://ho%11st/",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "http://ho%12st/",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "http://ho%13st/",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "http://ho%14st/",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "http://ho%15st/",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "http://ho%16st/",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "http://ho%17st/",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "http://ho%18st/",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "http://ho%19st/",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "http://ho%1Ast/",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "http://ho%1Bst/",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "http://ho%1Cst/",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "http://ho%1Dst/",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "http://ho%1Est/",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "http://ho%1Fst/",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "http://ho%20st/",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "http://ho%23st/",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "http://ho%25st/",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "http://ho%2Fst/",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "http://ho%3Ast/",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "http://ho%3Cst/",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "http://ho%3Est/",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "http://ho%3Fst/",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "http://ho%40st/",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "http://ho%5Bst/",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "http://ho%5Cst/",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "http://ho%5Dst/",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "http://ho%7Cst/",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "http://ho%7Fst/",
- "base": "about:blank",
+ "base": null,
"failure": true
},
"Allowed host/domain code points",
{
"input": "http://!\"$&'()*+,-.;=_`{}~/",
- "base": "about:blank",
+ "base": null,
"href": "http://!\"$&'()*+,-.;=_`{}~/",
"origin": "http://!\"$&'()*+,-.;=_`{}~",
"protocol": "http:",
@@ -5278,7 +5293,7 @@
},
{
"input": "sc://\u0001\u0002\u0003\u0004\u0005\u0006\u0007\u0008\u000B\u000C\u000E\u000F\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001A\u001B\u001C\u001D\u001E\u001F\u007F!\"$%&'()*+,-.;=_`{}~/",
- "base": "about:blank",
+ "base": null,
"href": "sc://%01%02%03%04%05%06%07%08%0B%0C%0E%0F%10%11%12%13%14%15%16%17%18%19%1A%1B%1C%1D%1E%1F%7F!\"$%&'()*+,-.;=_`{}~/",
"origin": "null",
"protocol": "sc:",
@@ -5294,27 +5309,27 @@
"# Hosts and percent-encoding",
{
"input": "ftp://example.com%80/",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "ftp://example.com%A0/",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "https://example.com%80/",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "https://example.com%A0/",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "ftp://%e2%98%83",
- "base": "about:blank",
+ "base": null,
"href": "ftp://xn--n3h/",
"origin": "ftp://xn--n3h",
"protocol": "ftp:",
@@ -5329,7 +5344,7 @@
},
{
"input": "https://%e2%98%83",
- "base": "about:blank",
+ "base": null,
"href": "https://xn--n3h/",
"origin": "https://xn--n3h",
"protocol": "https:",
@@ -5345,7 +5360,7 @@
"# tests from jsdom/whatwg-url designed for code coverage",
{
"input": "http://127.0.0.1:10100/relative_import.html",
- "base": "about:blank",
+ "base": null,
"href": "http://127.0.0.1:10100/relative_import.html",
"origin": "http://127.0.0.1:10100",
"protocol": "http:",
@@ -5360,7 +5375,7 @@
},
{
"input": "http://facebook.com/?foo=%7B%22abc%22",
- "base": "about:blank",
+ "base": null,
"href": "http://facebook.com/?foo=%7B%22abc%22",
"origin": "http://facebook.com",
"protocol": "http:",
@@ -5375,7 +5390,7 @@
},
{
"input": "https://localhost:3000/jqueryui@1.2.3",
- "base": "about:blank",
+ "base": null,
"href": "https://localhost:3000/jqueryui@1.2.3",
"origin": "https://localhost:3000",
"protocol": "https:",
@@ -5391,7 +5406,7 @@
"# tab/LF/CR",
{
"input": "h\tt\nt\rp://h\to\ns\rt:9\t0\n0\r0/p\ta\nt\rh?q\tu\ne\rry#f\tr\na\rg",
- "base": "about:blank",
+ "base": null,
"href": "http://host:9000/path?query#frag",
"origin": "http://host:9000",
"protocol": "http:",
@@ -5478,7 +5493,7 @@
"# Percent encoding of fragments",
{
"input": "http://foo.bar/baz?qux#foo\bbar",
- "base": "about:blank",
+ "base": null,
"href": "http://foo.bar/baz?qux#foo%08bar",
"origin": "http://foo.bar",
"protocol": "http:",
@@ -5494,7 +5509,7 @@
},
{
"input": "http://foo.bar/baz?qux#foo\"bar",
- "base": "about:blank",
+ "base": null,
"href": "http://foo.bar/baz?qux#foo%22bar",
"origin": "http://foo.bar",
"protocol": "http:",
@@ -5510,7 +5525,7 @@
},
{
"input": "http://foo.bar/baz?qux#foo<bar",
- "base": "about:blank",
+ "base": null,
"href": "http://foo.bar/baz?qux#foo%3Cbar",
"origin": "http://foo.bar",
"protocol": "http:",
@@ -5526,7 +5541,7 @@
},
{
"input": "http://foo.bar/baz?qux#foo>bar",
- "base": "about:blank",
+ "base": null,
"href": "http://foo.bar/baz?qux#foo%3Ebar",
"origin": "http://foo.bar",
"protocol": "http:",
@@ -5542,7 +5557,7 @@
},
{
"input": "http://foo.bar/baz?qux#foo`bar",
- "base": "about:blank",
+ "base": null,
"href": "http://foo.bar/baz?qux#foo%60bar",
"origin": "http://foo.bar",
"protocol": "http:",
@@ -5774,7 +5789,7 @@
},
{
"input": "https://0x.0x.0",
- "base": "about:blank",
+ "base": null,
"href": "https://0.0.0.0/",
"origin": "https://0.0.0.0",
"protocol": "https:",
@@ -5790,18 +5805,18 @@
"More IPv4 parsing (via https://github.com/jsdom/whatwg-url/issues/92)",
{
"input": "https://0x100000000/test",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "https://256.0.0.1/test",
- "base": "about:blank",
+ "base": null,
"failure": true
},
"# file URLs containing percent-encoded Windows drive letters (shouldn't work)",
{
"input": "file:///C%3A/",
- "base": "about:blank",
+ "base": null,
"href": "file:///C%3A/",
"protocol": "file:",
"username": "",
@@ -5815,7 +5830,7 @@
},
{
"input": "file:///C%7C/",
- "base": "about:blank",
+ "base": null,
"href": "file:///C%7C/",
"protocol": "file:",
"username": "",
@@ -5829,42 +5844,42 @@
},
{
"input": "file://%43%3A",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "file://%43%7C",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "file://%43|",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "file://C%7C",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "file://%43%7C/",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "https://%43%7C/",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "asdf://%43|/",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "asdf://%43%7C/",
- "base": "about:blank",
+ "base": null,
"href": "asdf://%43%7C/",
"origin": "null",
"protocol": "asdf:",
@@ -5935,7 +5950,6 @@
"search": "",
"hash": ""
},
- "skip next",
{
"input": "/",
"base": "file://h/C:/a/b",
@@ -6105,10 +6119,9 @@
"hash": "#x"
},
"# File URLs and many (back)slashes",
- "skip next",
{
"input": "file:\\\\//",
- "base": "about:blank",
+ "base": null,
"href": "file:////",
"protocol": "file:",
"username": "",
@@ -6120,10 +6133,9 @@
"search": "",
"hash": ""
},
- "skip next",
{
"input": "file:\\\\\\\\",
- "base": "about:blank",
+ "base": null,
"href": "file:////",
"protocol": "file:",
"username": "",
@@ -6135,10 +6147,9 @@
"search": "",
"hash": ""
},
- "skip next",
{
"input": "file:\\\\\\\\?fox",
- "base": "about:blank",
+ "base": null,
"href": "file:////?fox",
"protocol": "file:",
"username": "",
@@ -6150,10 +6161,9 @@
"search": "?fox",
"hash": ""
},
- "skip next",
{
"input": "file:\\\\\\\\#guppy",
- "base": "about:blank",
+ "base": null,
"href": "file:////#guppy",
"protocol": "file:",
"username": "",
@@ -6165,10 +6175,9 @@
"search": "",
"hash": "#guppy"
},
- "skip next",
{
"input": "file://spider///",
- "base": "about:blank",
+ "base": null,
"href": "file://spider///",
"protocol": "file:",
"username": "",
@@ -6180,10 +6189,9 @@
"search": "",
"hash": ""
},
- "skip next",
{
"input": "file:\\\\localhost//",
- "base": "about:blank",
+ "base": null,
"href": "file:////",
"protocol": "file:",
"username": "",
@@ -6197,7 +6205,7 @@
},
{
"input": "file:///localhost//cat",
- "base": "about:blank",
+ "base": null,
"href": "file:///localhost//cat",
"protocol": "file:",
"username": "",
@@ -6209,10 +6217,9 @@
"search": "",
"hash": ""
},
- "skip next",
{
"input": "file://\\/localhost//cat",
- "base": "about:blank",
+ "base": null,
"href": "file:////localhost//cat",
"protocol": "file:",
"username": "",
@@ -6224,10 +6231,9 @@
"search": "",
"hash": ""
},
- "skip next",
{
"input": "file://localhost//a//../..//",
- "base": "about:blank",
+ "base": null,
"href": "file://///",
"protocol": "file:",
"username": "",
@@ -6239,7 +6245,6 @@
"search": "",
"hash": ""
},
- "skip next",
{
"input": "/////mouse",
"base": "file:///elephant",
@@ -6268,7 +6273,6 @@
"search": "",
"hash": ""
},
- "skip next",
{
"input": "\\/localhost//pig",
"base": "file://lion/",
@@ -6283,7 +6287,6 @@
"search": "",
"hash": ""
},
- "skip next",
{
"input": "//localhost//pig",
"base": "file://lion/",
@@ -6298,7 +6301,6 @@
"search": "",
"hash": ""
},
- "skip next",
{
"input": "/..//localhost//pig",
"base": "file://lion/",
@@ -6357,7 +6359,6 @@
"hash": ""
},
"# Windows drive letter handling with the 'file:' base URL",
- "skip next",
{
"input": "C|",
"base": "file://host/dir/file",
@@ -6372,7 +6373,6 @@
"search": "",
"hash": ""
},
- "skip next",
{
"input": "C|",
"base": "file://host/D:/dir1/dir2/file",
@@ -6387,7 +6387,6 @@
"search": "",
"hash": ""
},
- "skip next",
{
"input": "C|#",
"base": "file://host/dir/file",
@@ -6402,7 +6401,6 @@
"search": "",
"hash": ""
},
- "skip next",
{
"input": "C|?",
"base": "file://host/dir/file",
@@ -6417,7 +6415,6 @@
"search": "",
"hash": ""
},
- "skip next",
{
"input": "C|/",
"base": "file://host/dir/file",
@@ -6432,7 +6429,6 @@
"search": "",
"hash": ""
},
- "skip next",
{
"input": "C|\n/",
"base": "file://host/dir/file",
@@ -6447,7 +6443,6 @@
"search": "",
"hash": ""
},
- "skip next",
{
"input": "C|\\",
"base": "file://host/dir/file",
@@ -6533,7 +6528,6 @@
"search": "",
"hash": ""
},
- "skip next",
{
"input": "/c:/foo/bar",
"base": "file://host/path",
@@ -6549,10 +6543,9 @@
"hash": ""
},
"# Do not drop the host in the presence of a drive letter",
- "skip next",
{
"input": "file://example.net/C:/",
- "base": "about:blank",
+ "base": null,
"href": "file://example.net/C:/",
"protocol": "file:",
"username": "",
@@ -6564,10 +6557,9 @@
"search": "",
"hash": ""
},
- "skip next",
{
"input": "file://1.2.3.4/C:/",
- "base": "about:blank",
+ "base": null,
"href": "file://1.2.3.4/C:/",
"protocol": "file:",
"username": "",
@@ -6579,10 +6571,9 @@
"search": "",
"hash": ""
},
- "skip next",
{
"input": "file://[1::8]/C:/",
- "base": "about:blank",
+ "base": null,
"href": "file://[1::8]/C:/",
"protocol": "file:",
"username": "",
@@ -6595,7 +6586,6 @@
"hash": ""
},
"# Copy the host from the base URL in the following cases",
- "skip next",
{
"input": "C|/",
"base": "file://host/",
@@ -6610,7 +6600,6 @@
"search": "",
"hash": ""
},
- "skip next",
{
"input": "/C:/",
"base": "file://host/",
@@ -6625,7 +6614,6 @@
"search": "",
"hash": ""
},
- "skip next",
{
"input": "file:C:/",
"base": "file://host/",
@@ -6640,7 +6628,6 @@
"search": "",
"hash": ""
},
- "skip next",
{
"input": "file:/C:/",
"base": "file://host/",
@@ -6656,7 +6643,6 @@
"hash": ""
},
"# Copy the empty host from the input in the following cases",
- "skip next",
{
"input": "//C:/",
"base": "file://host/",
@@ -6716,7 +6702,7 @@
"# Windows drive letter quirk (no host)",
{
"input": "file:/C|/",
- "base": "about:blank",
+ "base": null,
"href": "file:///C:/",
"protocol": "file:",
"username": "",
@@ -6730,7 +6716,7 @@
},
{
"input": "file://C|/",
- "base": "about:blank",
+ "base": null,
"href": "file:///C:/",
"protocol": "file:",
"username": "",
@@ -6745,7 +6731,7 @@
"# file URLs without base URL by Rimas Misevičius",
{
"input": "file:",
- "base": "about:blank",
+ "base": null,
"href": "file:///",
"protocol": "file:",
"username": "",
@@ -6759,7 +6745,7 @@
},
{
"input": "file:?q=v",
- "base": "about:blank",
+ "base": null,
"href": "file:///?q=v",
"protocol": "file:",
"username": "",
@@ -6773,7 +6759,7 @@
},
{
"input": "file:#frag",
- "base": "about:blank",
+ "base": null,
"href": "file:///#frag",
"protocol": "file:",
"username": "",
@@ -6788,7 +6774,7 @@
"# file: drive letter cases from https://crbug.com/1078698",
{
"input": "file:///Y:",
- "base": "about:blank",
+ "base": null,
"href": "file:///Y:",
"protocol": "file:",
"username": "",
@@ -6802,7 +6788,7 @@
},
{
"input": "file:///Y:/",
- "base": "about:blank",
+ "base": null,
"href": "file:///Y:/",
"protocol": "file:",
"username": "",
@@ -6816,7 +6802,7 @@
},
{
"input": "file:///./Y",
- "base": "about:blank",
+ "base": null,
"href": "file:///Y",
"protocol": "file:",
"username": "",
@@ -6830,7 +6816,7 @@
},
{
"input": "file:///./Y:",
- "base": "about:blank",
+ "base": null,
"href": "file:///Y:",
"protocol": "file:",
"username": "",
@@ -6844,14 +6830,14 @@
},
{
"input": "\\\\\\.\\Y:",
- "base": "about:blank",
+ "base": null,
"failure": true,
- "inputCanBeRelative": true
+ "relativeTo": "non-opaque-path-base"
},
"# file: drive letter cases from https://crbug.com/1078698 but lowercased",
{
"input": "file:///y:",
- "base": "about:blank",
+ "base": null,
"href": "file:///y:",
"protocol": "file:",
"username": "",
@@ -6865,7 +6851,7 @@
},
{
"input": "file:///y:/",
- "base": "about:blank",
+ "base": null,
"href": "file:///y:/",
"protocol": "file:",
"username": "",
@@ -6879,7 +6865,7 @@
},
{
"input": "file:///./y",
- "base": "about:blank",
+ "base": null,
"href": "file:///y",
"protocol": "file:",
"username": "",
@@ -6893,7 +6879,7 @@
},
{
"input": "file:///./y:",
- "base": "about:blank",
+ "base": null,
"href": "file:///y:",
"protocol": "file:",
"username": "",
@@ -6907,15 +6893,14 @@
},
{
"input": "\\\\\\.\\y:",
- "base": "about:blank",
+ "base": null,
"failure": true,
- "inputCanBeRelative": true
+ "relativeTo": "non-opaque-path-base"
},
"# Additional file URL tests for (https://github.com/whatwg/url/issues/405)",
- "skip next",
{
"input": "file://localhost//a//../..//foo",
- "base": "about:blank",
+ "base": null,
"href": "file://///foo",
"protocol": "file:",
"username": "",
@@ -6927,10 +6912,9 @@
"search": "",
"hash": ""
},
- "skip next",
{
"input": "file://localhost////foo",
- "base": "about:blank",
+ "base": null,
"href": "file://////foo",
"protocol": "file:",
"username": "",
@@ -6942,10 +6926,9 @@
"search": "",
"hash": ""
},
- "skip next",
{
"input": "file:////foo",
- "base": "about:blank",
+ "base": null,
"href": "file:////foo",
"protocol": "file:",
"username": "",
@@ -6971,7 +6954,6 @@
"search": "",
"hash": ""
},
- "skip next",
{
"input": "file:////one/two",
"base": "file:///",
@@ -7014,7 +6996,6 @@
"search": "",
"hash": ""
},
- "skip next",
{
"input": "////one/two",
"base": "file:///",
@@ -7029,7 +7010,6 @@
"search": "",
"hash": ""
},
- "skip next",
{
"input": "file:///.//",
"base": "file:////",
@@ -7045,10 +7025,9 @@
"hash": ""
},
"File URL tests for https://github.com/whatwg/url/issues/549",
- "skip next",
{
"input": "file:.//p",
- "base": "about:blank",
+ "base": null,
"href": "file:////p",
"protocol": "file:",
"username": "",
@@ -7060,10 +7039,9 @@
"search": "",
"hash": ""
},
- "skip next",
{
"input": "file:/.//p",
- "base": "about:blank",
+ "base": null,
"href": "file:////p",
"protocol": "file:",
"username": "",
@@ -7098,48 +7076,48 @@
},
{
"input": "https://[0::0::0]",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "https://[0:.0]",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "https://[0:0:]",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "https://[0:1:2:3:4:5:6:7.0.0.0.1]",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "https://[0:1.00.0.0.0]",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "https://[0:1.290.0.0.0]",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "https://[0:1.23.23]",
- "base": "about:blank",
+ "base": null,
"failure": true
},
"# Empty host",
{
"input": "http://?",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "http://#",
- "base": "about:blank",
+ "base": null,
"failure": true
},
"Port overflow (2^32 + 81)",
@@ -7163,7 +7141,7 @@
"# Non-special-URL path tests",
{
"input": "sc://ñ",
- "base": "about:blank",
+ "base": null,
"href": "sc://%C3%B1",
"origin": "null",
"protocol": "sc:",
@@ -7178,7 +7156,7 @@
},
{
"input": "sc://ñ?x",
- "base": "about:blank",
+ "base": null,
"href": "sc://%C3%B1?x",
"origin": "null",
"protocol": "sc:",
@@ -7193,7 +7171,7 @@
},
{
"input": "sc://ñ#x",
- "base": "about:blank",
+ "base": null,
"href": "sc://%C3%B1#x",
"origin": "null",
"protocol": "sc:",
@@ -7238,7 +7216,7 @@
},
{
"input": "sc://?",
- "base": "about:blank",
+ "base": null,
"href": "sc://?",
"protocol": "sc:",
"username": "",
@@ -7252,7 +7230,7 @@
},
{
"input": "sc://#",
- "base": "about:blank",
+ "base": null,
"href": "sc://#",
"protocol": "sc:",
"username": "",
@@ -7308,7 +7286,7 @@
},
{
"input": "tftp://foobar.com/someconfig;mode=netascii",
- "base": "about:blank",
+ "base": null,
"href": "tftp://foobar.com/someconfig;mode=netascii",
"origin": "null",
"protocol": "tftp:",
@@ -7323,7 +7301,7 @@
},
{
"input": "telnet://user:pass@foobar.com:23/",
- "base": "about:blank",
+ "base": null,
"href": "telnet://user:pass@foobar.com:23/",
"origin": "null",
"protocol": "telnet:",
@@ -7338,7 +7316,7 @@
},
{
"input": "ut2004://10.10.10.10:7777/Index.ut2",
- "base": "about:blank",
+ "base": null,
"href": "ut2004://10.10.10.10:7777/Index.ut2",
"origin": "null",
"protocol": "ut2004:",
@@ -7353,7 +7331,7 @@
},
{
"input": "redis://foo:bar@somehost:6379/0?baz=bam&qux=baz",
- "base": "about:blank",
+ "base": null,
"href": "redis://foo:bar@somehost:6379/0?baz=bam&qux=baz",
"origin": "null",
"protocol": "redis:",
@@ -7368,7 +7346,7 @@
},
{
"input": "rsync://foo@host:911/sup",
- "base": "about:blank",
+ "base": null,
"href": "rsync://foo@host:911/sup",
"origin": "null",
"protocol": "rsync:",
@@ -7383,7 +7361,7 @@
},
{
"input": "git://github.com/foo/bar.git",
- "base": "about:blank",
+ "base": null,
"href": "git://github.com/foo/bar.git",
"origin": "null",
"protocol": "git:",
@@ -7398,7 +7376,7 @@
},
{
"input": "irc://myserver.com:6999/channel?passwd",
- "base": "about:blank",
+ "base": null,
"href": "irc://myserver.com:6999/channel?passwd",
"origin": "null",
"protocol": "irc:",
@@ -7413,7 +7391,7 @@
},
{
"input": "dns://fw.example.org:9999/foo.bar.org?type=TXT",
- "base": "about:blank",
+ "base": null,
"href": "dns://fw.example.org:9999/foo.bar.org?type=TXT",
"origin": "null",
"protocol": "dns:",
@@ -7428,7 +7406,7 @@
},
{
"input": "ldap://localhost:389/ou=People,o=JNDITutorial",
- "base": "about:blank",
+ "base": null,
"href": "ldap://localhost:389/ou=People,o=JNDITutorial",
"origin": "null",
"protocol": "ldap:",
@@ -7443,7 +7421,7 @@
},
{
"input": "git+https://github.com/foo/bar",
- "base": "about:blank",
+ "base": null,
"href": "git+https://github.com/foo/bar",
"origin": "null",
"protocol": "git+https:",
@@ -7458,7 +7436,7 @@
},
{
"input": "urn:ietf:rfc:2648",
- "base": "about:blank",
+ "base": null,
"href": "urn:ietf:rfc:2648",
"origin": "null",
"protocol": "urn:",
@@ -7473,7 +7451,7 @@
},
{
"input": "tag:joe@example.org,2001:foo/bar",
- "base": "about:blank",
+ "base": null,
"href": "tag:joe@example.org,2001:foo/bar",
"origin": "null",
"protocol": "tag:",
@@ -7489,7 +7467,7 @@
"Serialize /. in path",
{
"input": "non-spec:/.//",
- "base": "about:blank",
+ "base": null,
"href": "non-spec:/.//",
"protocol": "non-spec:",
"username": "",
@@ -7503,7 +7481,7 @@
},
{
"input": "non-spec:/..//",
- "base": "about:blank",
+ "base": null,
"href": "non-spec:/.//",
"protocol": "non-spec:",
"username": "",
@@ -7517,7 +7495,7 @@
},
{
"input": "non-spec:/a/..//",
- "base": "about:blank",
+ "base": null,
"href": "non-spec:/.//",
"protocol": "non-spec:",
"username": "",
@@ -7531,7 +7509,7 @@
},
{
"input": "non-spec:/.//path",
- "base": "about:blank",
+ "base": null,
"href": "non-spec:/.//path",
"protocol": "non-spec:",
"username": "",
@@ -7545,7 +7523,7 @@
},
{
"input": "non-spec:/..//path",
- "base": "about:blank",
+ "base": null,
"href": "non-spec:/.//path",
"protocol": "non-spec:",
"username": "",
@@ -7559,7 +7537,7 @@
},
{
"input": "non-spec:/a/..//path",
- "base": "about:blank",
+ "base": null,
"href": "non-spec:/.//path",
"protocol": "non-spec:",
"username": "",
@@ -7571,7 +7549,6 @@
"search": "",
"hash": ""
},
- "skip next",
{
"input": "/.//path",
"base": "non-spec:/p",
@@ -7674,7 +7651,7 @@
"# percent encoded hosts in non-special-URLs",
{
"input": "non-special://%E2%80%A0/",
- "base": "about:blank",
+ "base": null,
"href": "non-special://%E2%80%A0/",
"protocol": "non-special:",
"username": "",
@@ -7688,7 +7665,7 @@
},
{
"input": "non-special://H%4fSt/path",
- "base": "about:blank",
+ "base": null,
"href": "non-special://H%4fSt/path",
"protocol": "non-special:",
"username": "",
@@ -7703,7 +7680,7 @@
"# IPv6 in non-special-URLs",
{
"input": "non-special://[1:2:0:0:5:0:0:0]/",
- "base": "about:blank",
+ "base": null,
"href": "non-special://[1:2:0:0:5::]/",
"protocol": "non-special:",
"username": "",
@@ -7717,7 +7694,7 @@
},
{
"input": "non-special://[1:2:0:0:0:0:0:3]/",
- "base": "about:blank",
+ "base": null,
"href": "non-special://[1:2::3]/",
"protocol": "non-special:",
"username": "",
@@ -7731,7 +7708,7 @@
},
{
"input": "non-special://[1:2::3]:80/",
- "base": "about:blank",
+ "base": null,
"href": "non-special://[1:2::3]:80/",
"protocol": "non-special:",
"username": "",
@@ -7745,12 +7722,12 @@
},
{
"input": "non-special://[:80/",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "blob:https://example.com:443/",
- "base": "about:blank",
+ "base": null,
"href": "blob:https://example.com:443/",
"origin": "https://example.com",
"protocol": "blob:",
@@ -7764,8 +7741,23 @@
"hash": ""
},
{
+ "input": "blob:http://example.org:88/",
+ "base": null,
+ "href": "blob:http://example.org:88/",
+ "origin": "http://example.org:88",
+ "protocol": "blob:",
+ "username": "",
+ "password": "",
+ "host": "",
+ "hostname": "",
+ "port": "",
+ "pathname": "http://example.org:88/",
+ "search": "",
+ "hash": ""
+ },
+ {
"input": "blob:d3958f5c-0777-0845-9dcf-2cb28783acaf",
- "base": "about:blank",
+ "base": null,
"href": "blob:d3958f5c-0777-0845-9dcf-2cb28783acaf",
"origin": "null",
"protocol": "blob:",
@@ -7780,7 +7772,7 @@
},
{
"input": "blob:",
- "base": "about:blank",
+ "base": null,
"href": "blob:",
"origin": "null",
"protocol": "blob:",
@@ -7793,10 +7785,133 @@
"search": "",
"hash": ""
},
+ "blob: in blob:",
+ {
+ "input": "blob:blob:",
+ "base": null,
+ "href": "blob:blob:",
+ "origin": "null",
+ "protocol": "blob:",
+ "username": "",
+ "password": "",
+ "host": "",
+ "hostname": "",
+ "port": "",
+ "pathname": "blob:",
+ "search": "",
+ "hash": ""
+ },
+ {
+ "input": "blob:blob:https://example.org/",
+ "base": null,
+ "href": "blob:blob:https://example.org/",
+ "origin": "null",
+ "protocol": "blob:",
+ "username": "",
+ "password": "",
+ "host": "",
+ "hostname": "",
+ "port": "",
+ "pathname": "blob:https://example.org/",
+ "search": "",
+ "hash": ""
+ },
+ "Non-http(s): in blob:",
+ {
+ "input": "blob:about:blank",
+ "base": null,
+ "href": "blob:about:blank",
+ "origin": "null",
+ "protocol": "blob:",
+ "username": "",
+ "password": "",
+ "host": "",
+ "hostname": "",
+ "port": "",
+ "pathname": "about:blank",
+ "search": "",
+ "hash": ""
+ },
+ {
+ "input": "blob:file://host/path",
+ "base": null,
+ "href": "blob:file://host/path",
+ "origin": "null",
+ "protocol": "blob:",
+ "username": "",
+ "password": "",
+ "host": "",
+ "hostname": "",
+ "port": "",
+ "pathname": "file://host/path",
+ "search": "",
+ "hash": ""
+ },
+ {
+ "input": "blob:ftp://host/path",
+ "base": null,
+ "href": "blob:ftp://host/path",
+ "origin": "null",
+ "protocol": "blob:",
+ "username": "",
+ "password": "",
+ "host": "",
+ "hostname": "",
+ "port": "",
+ "pathname": "ftp://host/path",
+ "search": "",
+ "hash": ""
+ },
+ {
+ "input": "blob:ws://example.org/",
+ "base": null,
+ "href": "blob:ws://example.org/",
+ "origin": "null",
+ "protocol": "blob:",
+ "username": "",
+ "password": "",
+ "host": "",
+ "hostname": "",
+ "port": "",
+ "pathname": "ws://example.org/",
+ "search": "",
+ "hash": ""
+ },
+ {
+ "input": "blob:wss://example.org/",
+ "base": null,
+ "href": "blob:wss://example.org/",
+ "origin": "null",
+ "protocol": "blob:",
+ "username": "",
+ "password": "",
+ "host": "",
+ "hostname": "",
+ "port": "",
+ "pathname": "wss://example.org/",
+ "search": "",
+ "hash": ""
+ },
+ "Percent-encoded http: in blob:",
+ {
+ "input": "blob:http%3a//example.org/",
+ "base": null,
+ "href": "blob:http%3a//example.org/",
+ "origin": "null",
+ "protocol": "blob:",
+ "username": "",
+ "password": "",
+ "host": "",
+ "hostname": "",
+ "port": "",
+ "pathname": "http%3a//example.org/",
+ "search": "",
+ "hash": ""
+ },
"Invalid IPv4 radix digits",
{
"input": "http://0x7f.0.0.0x7g",
- "base": "about:blank",
+ "base": null,
"href": "http://0x7f.0.0.0x7g/",
"protocol": "http:",
"username": "",
@@ -7810,7 +7925,7 @@
},
{
"input": "http://0X7F.0.0.0X7G",
- "base": "about:blank",
+ "base": null,
"href": "http://0x7f.0.0.0x7g/",
"protocol": "http:",
"username": "",
@@ -7825,13 +7940,13 @@
"Invalid IPv4 portion of IPv6 address",
{
"input": "http://[::127.0.0.0.1]",
- "base": "about:blank",
+ "base": null,
"failure": true
},
"Uncompressed IPv6 addresses with 0",
{
"input": "http://[0:1:0:1:0:1:0:1]",
- "base": "about:blank",
+ "base": null,
"href": "http://[0:1:0:1:0:1:0:1]/",
"protocol": "http:",
"username": "",
@@ -7845,7 +7960,7 @@
},
{
"input": "http://[1:0:1:0:1:0:1:0]",
- "base": "about:blank",
+ "base": null,
"href": "http://[1:0:1:0:1:0:1:0]/",
"protocol": "http:",
"username": "",
@@ -7860,7 +7975,7 @@
"Percent-encoded query and fragment",
{
"input": "http://example.org/test?\u0022",
- "base": "about:blank",
+ "base": null,
"href": "http://example.org/test?%22",
"protocol": "http:",
"username": "",
@@ -7874,7 +7989,7 @@
},
{
"input": "http://example.org/test?\u0023",
- "base": "about:blank",
+ "base": null,
"href": "http://example.org/test?#",
"protocol": "http:",
"username": "",
@@ -7888,7 +8003,7 @@
},
{
"input": "http://example.org/test?\u003C",
- "base": "about:blank",
+ "base": null,
"href": "http://example.org/test?%3C",
"protocol": "http:",
"username": "",
@@ -7902,7 +8017,7 @@
},
{
"input": "http://example.org/test?\u003E",
- "base": "about:blank",
+ "base": null,
"href": "http://example.org/test?%3E",
"protocol": "http:",
"username": "",
@@ -7916,7 +8031,7 @@
},
{
"input": "http://example.org/test?\u2323",
- "base": "about:blank",
+ "base": null,
"href": "http://example.org/test?%E2%8C%A3",
"protocol": "http:",
"username": "",
@@ -7930,7 +8045,7 @@
},
{
"input": "http://example.org/test?%23%23",
- "base": "about:blank",
+ "base": null,
"href": "http://example.org/test?%23%23",
"protocol": "http:",
"username": "",
@@ -7944,7 +8059,7 @@
},
{
"input": "http://example.org/test?%GH",
- "base": "about:blank",
+ "base": null,
"href": "http://example.org/test?%GH",
"protocol": "http:",
"username": "",
@@ -7958,7 +8073,7 @@
},
{
"input": "http://example.org/test?a#%EF",
- "base": "about:blank",
+ "base": null,
"href": "http://example.org/test?a#%EF",
"protocol": "http:",
"username": "",
@@ -7972,7 +8087,7 @@
},
{
"input": "http://example.org/test?a#%GH",
- "base": "about:blank",
+ "base": null,
"href": "http://example.org/test?a#%GH",
"protocol": "http:",
"username": "",
@@ -7987,21 +8102,21 @@
"URLs that require a non-about:blank base. (Also serve as invalid base tests.)",
{
"input": "a",
- "base": "about:blank",
+ "base": null,
"failure": true,
- "inputCanBeRelative": true
+ "relativeTo": "non-opaque-path-base"
},
{
"input": "a/",
- "base": "about:blank",
+ "base": null,
"failure": true,
- "inputCanBeRelative": true
+ "relativeTo": "non-opaque-path-base"
},
{
"input": "a//",
- "base": "about:blank",
+ "base": null,
"failure": true,
- "inputCanBeRelative": true
+ "relativeTo": "non-opaque-path-base"
},
"Bases that don't fail to parse but fail to be bases",
{
@@ -8074,7 +8189,7 @@
"Null code point in fragment",
{
"input": "http://example.org/test?a#b\u0000c",
- "base": "about:blank",
+ "base": null,
"href": "http://example.org/test?a#b%00c",
"protocol": "http:",
"username": "",
@@ -8088,7 +8203,7 @@
},
{
"input": "non-spec://example.org/test?a#b\u0000c",
- "base": "about:blank",
+ "base": null,
"href": "non-spec://example.org/test?a#b%00c",
"protocol": "non-spec:",
"username": "",
@@ -8102,7 +8217,7 @@
},
{
"input": "non-spec:/test?a#b\u0000c",
- "base": "about:blank",
+ "base": null,
"href": "non-spec:/test?a#b%00c",
"protocol": "non-spec:",
"username": "",
@@ -8162,7 +8277,7 @@
"IDNA ignored code points in file URLs hosts",
{
"input": "file://a\u00ADb/p",
- "base": "about:blank",
+ "base": null,
"href": "file://ab/p",
"protocol": "file:",
"username": "",
@@ -8176,7 +8291,7 @@
},
{
"input": "file://a%C2%ADb/p",
- "base": "about:blank",
+ "base": null,
"href": "file://ab/p",
"protocol": "file:",
"username": "",
@@ -8191,7 +8306,7 @@
"IDNA hostnames which get mapped to 'localhost'",
{
"input": "file://loC𝐀𝐋𝐇𝐨𝐬𝐭/usr/bin",
- "base": "about:blank",
+ "base": null,
"href": "file:///usr/bin",
"protocol": "file:",
"username": "",
@@ -8206,17 +8321,17 @@
"Empty host after the domain to ASCII",
{
"input": "file://\u00ad/p",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "file://%C2%AD/p",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "file://xn--/p",
- "base": "about:blank",
+ "base": null,
"failure": true
},
"https://bugzilla.mozilla.org/show_bug.cgi?id=1647058",
@@ -8237,7 +8352,7 @@
"UTF-8 percent-encode of C0 control percent-encode set and supersets",
{
"input": "non-special:cannot-be-a-base-url-\u0000\u0001\u001F\u001E\u007E\u007F\u0080",
- "base": "about:blank",
+ "base": null,
"hash": "",
"host": "",
"hostname": "",
@@ -8252,7 +8367,7 @@
},
{
"input": "https://www.example.com/path{\u007Fpath.html?query'\u007F=query#fragment<\u007Ffragment",
- "base": "about:blank",
+ "base": null,
"hash": "#fragment%3C%7Ffragment",
"host": "www.example.com",
"hostname": "www.example.com",
@@ -8283,7 +8398,7 @@
"Tests for the distinct percent-encode sets",
{
"input": "foo:// !\"$%&'()*+,-.;<=>@[\\]^_`{|}~@host/",
- "base": "about:blank",
+ "base": null,
"hash": "",
"host": "host",
"hostname": "host",
@@ -8298,7 +8413,7 @@
},
{
"input": "wss:// !\"$%&'()*+,-.;<=>@[]^_`{|}~@host/",
- "base": "about:blank",
+ "base": null,
"hash": "",
"host": "host",
"hostname": "host",
@@ -8313,7 +8428,7 @@
},
{
"input": "foo://joe: !\"$%&'()*+,-.:;<=>@[\\]^_`{|}~@host/",
- "base": "about:blank",
+ "base": null,
"hash": "",
"host": "host",
"hostname": "host",
@@ -8328,7 +8443,7 @@
},
{
"input": "wss://joe: !\"$%&'()*+,-.:;<=>@[]^_`{|}~@host/",
- "base": "about:blank",
+ "base": null,
"hash": "",
"host": "host",
"hostname": "host",
@@ -8343,7 +8458,7 @@
},
{
"input": "foo://!\"$%&'()*+,-.;=_`{}~/",
- "base": "about:blank",
+ "base": null,
"hash": "",
"host": "!\"$%&'()*+,-.;=_`{}~",
"hostname": "!\"$%&'()*+,-.;=_`{}~",
@@ -8358,7 +8473,7 @@
},
{
"input": "wss://!\"$&'()*+,-.;=_`{}~/",
- "base": "about:blank",
+ "base": null,
"hash": "",
"host": "!\"$&'()*+,-.;=_`{}~",
"hostname": "!\"$&'()*+,-.;=_`{}~",
@@ -8373,7 +8488,7 @@
},
{
"input": "foo://host/ !\"$%&'()*+,-./:;<=>@[\\]^_`{|}~",
- "base": "about:blank",
+ "base": null,
"hash": "",
"host": "host",
"hostname": "host",
@@ -8388,7 +8503,7 @@
},
{
"input": "wss://host/ !\"$%&'()*+,-./:;<=>@[\\]^_`{|}~",
- "base": "about:blank",
+ "base": null,
"hash": "",
"host": "host",
"hostname": "host",
@@ -8403,7 +8518,7 @@
},
{
"input": "foo://host/dir/? !\"$%&'()*+,-./:;<=>?@[\\]^_`{|}~",
- "base": "about:blank",
+ "base": null,
"hash": "",
"host": "host",
"hostname": "host",
@@ -8418,7 +8533,7 @@
},
{
"input": "wss://host/dir/? !\"$%&'()*+,-./:;<=>?@[\\]^_`{|}~",
- "base": "about:blank",
+ "base": null,
"hash": "",
"host": "host",
"hostname": "host",
@@ -8433,7 +8548,7 @@
},
{
"input": "foo://host/dir/# !\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~",
- "base": "about:blank",
+ "base": null,
"hash": "#%20!%22#$%&'()*+,-./:;%3C=%3E?@[\\]^_%60{|}~",
"host": "host",
"hostname": "host",
@@ -8448,7 +8563,7 @@
},
{
"input": "wss://host/dir/# !\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~",
- "base": "about:blank",
+ "base": null,
"hash": "#%20!%22#$%&'()*+,-./:;%3C=%3E?@[\\]^_%60{|}~",
"host": "host",
"hostname": "host",
@@ -8522,12 +8637,14 @@
{
"input": "#",
"base": null,
- "failure": true
+ "failure": true,
+ "relativeTo": "any-base"
},
{
"input": "?",
"base": null,
- "failure": true
+ "failure": true,
+ "relativeTo": "non-opaque-path-base"
},
"Last component looks like a number, but not valid IPv4",
{
@@ -8542,12 +8659,12 @@
},
{
"input": "http://0..0x300/",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "http://0..0x300./",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
@@ -8562,102 +8679,102 @@
},
{
"input": "http://1.2.3.08",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "http://1.2.3.08.",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "http://1.2.3.09",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "http://09.2.3.4",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "http://09.2.3.4.",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "http://01.2.3.4.5",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "http://01.2.3.4.5.",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "http://0x100.2.3.4",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "http://0x100.2.3.4.",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "http://0x1.2.3.4.5",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "http://0x1.2.3.4.5.",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "http://foo.1.2.3.4",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "http://foo.1.2.3.4.",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "http://foo.2.3.4",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "http://foo.2.3.4.",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "http://foo.09",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "http://foo.09.",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "http://foo.0x4",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "http://foo.0x4.",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "http://foo.09..",
- "base": "about:blank",
+ "base": null,
"hash": "",
"host": "foo.09..",
"hostname": "foo.09..",
@@ -8671,33 +8788,33 @@
},
{
"input": "http://0999999999999999999/",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "http://foo.0x",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "http://foo.0XFfFfFfFfFfFfFfFfFfAcE123",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "http://💩.123/",
- "base": "about:blank",
+ "base": null,
"failure": true
},
"U+0000 and U+FFFF in various places",
{
"input": "https://\u0000y",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "https://x/\u0000y",
- "base": "about:blank",
+ "base": null,
"hash": "",
"host": "x",
"hostname": "x",
@@ -8711,7 +8828,7 @@
},
{
"input": "https://x/?\u0000y",
- "base": "about:blank",
+ "base": null,
"hash": "",
"host": "x",
"hostname": "x",
@@ -8725,7 +8842,7 @@
},
{
"input": "https://x/?#\u0000y",
- "base": "about:blank",
+ "base": null,
"hash": "#%00y",
"host": "x",
"hostname": "x",
@@ -8739,12 +8856,12 @@
},
{
"input": "https://\uFFFFy",
- "base": "about:blank",
+ "base": null,
"failure": true
},
{
"input": "https://x/\uFFFFy",
- "base": "about:blank",
+ "base": null,
"hash": "",
"host": "x",
"hostname": "x",
@@ -8758,7 +8875,7 @@
},
{
"input": "https://x/?\uFFFFy",
- "base": "about:blank",
+ "base": null,
"hash": "",
"host": "x",
"hostname": "x",
@@ -8772,7 +8889,7 @@
},
{
"input": "https://x/?#\uFFFFy",
- "base": "about:blank",
+ "base": null,
"hash": "#%EF%BF%BFy",
"host": "x",
"hostname": "x",
@@ -8786,7 +8903,7 @@
},
{
"input": "non-special:\u0000y",
- "base": "about:blank",
+ "base": null,
"hash": "",
"host": "",
"hostname": "",
@@ -8800,7 +8917,7 @@
},
{
"input": "non-special:x/\u0000y",
- "base": "about:blank",
+ "base": null,
"hash": "",
"host": "",
"hostname": "",
@@ -8814,7 +8931,7 @@
},
{
"input": "non-special:x/?\u0000y",
- "base": "about:blank",
+ "base": null,
"hash": "",
"host": "",
"hostname": "",
@@ -8828,7 +8945,7 @@
},
{
"input": "non-special:x/?#\u0000y",
- "base": "about:blank",
+ "base": null,
"hash": "#%00y",
"host": "",
"hostname": "",
@@ -8842,7 +8959,7 @@
},
{
"input": "non-special:\uFFFFy",
- "base": "about:blank",
+ "base": null,
"hash": "",
"host": "",
"hostname": "",
@@ -8856,7 +8973,7 @@
},
{
"input": "non-special:x/\uFFFFy",
- "base": "about:blank",
+ "base": null,
"hash": "",
"host": "",
"hostname": "",
@@ -8870,7 +8987,7 @@
},
{
"input": "non-special:x/?\uFFFFy",
- "base": "about:blank",
+ "base": null,
"hash": "",
"host": "",
"hostname": "",
@@ -8884,7 +9001,7 @@
},
{
"input": "non-special:x/?#\uFFFFy",
- "base": "about:blank",
+ "base": null,
"hash": "#%EF%BF%BFy",
"host": "",
"hostname": "",
@@ -8898,12 +9015,13 @@
},
{
"input": "",
- "base": "about:blank",
- "failure": true
+ "base": null,
+ "failure": true,
+ "relativeTo": "non-opaque-path-base"
},
{
"input": "https://example.com/\"quoted\"",
- "base": "about:blank",
+ "base": null,
"hash": "",
"host": "example.com",
"hostname": "example.com",
@@ -8915,5 +9033,487 @@
"protocol": "https:",
"search": "",
"username": ""
+ },
+ {
+ "input": "https://a%C2%ADb/",
+ "base": null,
+ "hash": "",
+ "host": "ab",
+ "hostname": "ab",
+ "href": "https://ab/",
+ "origin": "https://ab",
+ "password": "",
+ "pathname": "/",
+ "port": "",
+ "protocol": "https:",
+ "search": "",
+ "username": ""
+ },
+ {
+ "comment": "Empty host after domain to ASCII",
+ "input": "https://\u00AD/",
+ "base": null,
+ "failure": true
+ },
+ {
+ "input": "https://%C2%AD/",
+ "base": null,
+ "failure": true
+ },
+ {
+ "input": "https://xn--/",
+ "base": null,
+ "failure": true
+ },
+ "Non-special schemes that some implementations might incorrectly treat as special",
+ {
+ "input": "data://example.com:8080/pathname?search#hash",
+ "base": null,
+ "href": "data://example.com:8080/pathname?search#hash",
+ "origin": "null",
+ "protocol": "data:",
+ "username": "",
+ "password": "",
+ "host": "example.com:8080",
+ "hostname": "example.com",
+ "port": "8080",
+ "pathname": "/pathname",
+ "search": "?search",
+ "hash": "#hash"
+ },
+ {
+ "input": "data:///test",
+ "base": null,
+ "href": "data:///test",
+ "origin": "null",
+ "protocol": "data:",
+ "username": "",
+ "password": "",
+ "host": "",
+ "hostname": "",
+ "port": "",
+ "pathname": "/test",
+ "search": "",
+ "hash": ""
+ },
+ {
+ "input": "data://test/a/../b",
+ "base": null,
+ "href": "data://test/b",
+ "origin": "null",
+ "protocol": "data:",
+ "username": "",
+ "password": "",
+ "host": "test",
+ "hostname": "test",
+ "port": "",
+ "pathname": "/b",
+ "search": "",
+ "hash": ""
+ },
+ {
+ "input": "data://:443",
+ "base": null,
+ "failure": true
+ },
+ {
+ "input": "data://test:test",
+ "base": null,
+ "failure": true
+ },
+ {
+ "input": "data://[:1]",
+ "base": null,
+ "failure": true
+ },
+ {
+ "input": "javascript://example.com:8080/pathname?search#hash",
+ "base": null,
+ "href": "javascript://example.com:8080/pathname?search#hash",
+ "origin": "null",
+ "protocol": "javascript:",
+ "username": "",
+ "password": "",
+ "host": "example.com:8080",
+ "hostname": "example.com",
+ "port": "8080",
+ "pathname": "/pathname",
+ "search": "?search",
+ "hash": "#hash"
+ },
+ {
+ "input": "javascript:///test",
+ "base": null,
+ "href": "javascript:///test",
+ "origin": "null",
+ "protocol": "javascript:",
+ "username": "",
+ "password": "",
+ "host": "",
+ "hostname": "",
+ "port": "",
+ "pathname": "/test",
+ "search": "",
+ "hash": ""
+ },
+ {
+ "input": "javascript://test/a/../b",
+ "base": null,
+ "href": "javascript://test/b",
+ "origin": "null",
+ "protocol": "javascript:",
+ "username": "",
+ "password": "",
+ "host": "test",
+ "hostname": "test",
+ "port": "",
+ "pathname": "/b",
+ "search": "",
+ "hash": ""
+ },
+ {
+ "input": "javascript://:443",
+ "base": null,
+ "failure": true
+ },
+ {
+ "input": "javascript://test:test",
+ "base": null,
+ "failure": true
+ },
+ {
+ "input": "javascript://[:1]",
+ "base": null,
+ "failure": true
+ },
+ {
+ "input": "mailto://example.com:8080/pathname?search#hash",
+ "base": null,
+ "href": "mailto://example.com:8080/pathname?search#hash",
+ "origin": "null",
+ "protocol": "mailto:",
+ "username": "",
+ "password": "",
+ "host": "example.com:8080",
+ "hostname": "example.com",
+ "port": "8080",
+ "pathname": "/pathname",
+ "search": "?search",
+ "hash": "#hash"
+ },
+ {
+ "input": "mailto:///test",
+ "base": null,
+ "href": "mailto:///test",
+ "origin": "null",
+ "protocol": "mailto:",
+ "username": "",
+ "password": "",
+ "host": "",
+ "hostname": "",
+ "port": "",
+ "pathname": "/test",
+ "search": "",
+ "hash": ""
+ },
+ {
+ "input": "mailto://test/a/../b",
+ "base": null,
+ "href": "mailto://test/b",
+ "origin": "null",
+ "protocol": "mailto:",
+ "username": "",
+ "password": "",
+ "host": "test",
+ "hostname": "test",
+ "port": "",
+ "pathname": "/b",
+ "search": "",
+ "hash": ""
+ },
+ {
+ "input": "mailto://:443",
+ "base": null,
+ "failure": true
+ },
+ {
+ "input": "mailto://test:test",
+ "base": null,
+ "failure": true
+ },
+ {
+ "input": "mailto://[:1]",
+ "base": null,
+ "failure": true
+ },
+ {
+ "input": "intent://example.com:8080/pathname?search#hash",
+ "base": null,
+ "href": "intent://example.com:8080/pathname?search#hash",
+ "origin": "null",
+ "protocol": "intent:",
+ "username": "",
+ "password": "",
+ "host": "example.com:8080",
+ "hostname": "example.com",
+ "port": "8080",
+ "pathname": "/pathname",
+ "search": "?search",
+ "hash": "#hash"
+ },
+ {
+ "input": "intent:///test",
+ "base": null,
+ "href": "intent:///test",
+ "origin": "null",
+ "protocol": "intent:",
+ "username": "",
+ "password": "",
+ "host": "",
+ "hostname": "",
+ "port": "",
+ "pathname": "/test",
+ "search": "",
+ "hash": ""
+ },
+ {
+ "input": "intent://test/a/../b",
+ "base": null,
+ "href": "intent://test/b",
+ "origin": "null",
+ "protocol": "intent:",
+ "username": "",
+ "password": "",
+ "host": "test",
+ "hostname": "test",
+ "port": "",
+ "pathname": "/b",
+ "search": "",
+ "hash": ""
+ },
+ {
+ "input": "intent://:443",
+ "base": null,
+ "failure": true
+ },
+ {
+ "input": "intent://test:test",
+ "base": null,
+ "failure": true
+ },
+ {
+ "input": "intent://[:1]",
+ "base": null,
+ "failure": true
+ },
+ {
+ "input": "urn://example.com:8080/pathname?search#hash",
+ "base": null,
+ "href": "urn://example.com:8080/pathname?search#hash",
+ "origin": "null",
+ "protocol": "urn:",
+ "username": "",
+ "password": "",
+ "host": "example.com:8080",
+ "hostname": "example.com",
+ "port": "8080",
+ "pathname": "/pathname",
+ "search": "?search",
+ "hash": "#hash"
+ },
+ {
+ "input": "urn:///test",
+ "base": null,
+ "href": "urn:///test",
+ "origin": "null",
+ "protocol": "urn:",
+ "username": "",
+ "password": "",
+ "host": "",
+ "hostname": "",
+ "port": "",
+ "pathname": "/test",
+ "search": "",
+ "hash": ""
+ },
+ {
+ "input": "urn://test/a/../b",
+ "base": null,
+ "href": "urn://test/b",
+ "origin": "null",
+ "protocol": "urn:",
+ "username": "",
+ "password": "",
+ "host": "test",
+ "hostname": "test",
+ "port": "",
+ "pathname": "/b",
+ "search": "",
+ "hash": ""
+ },
+ {
+ "input": "urn://:443",
+ "base": null,
+ "failure": true
+ },
+ {
+ "input": "urn://test:test",
+ "base": null,
+ "failure": true
+ },
+ {
+ "input": "urn://[:1]",
+ "base": null,
+ "failure": true
+ },
+ {
+ "input": "turn://example.com:8080/pathname?search#hash",
+ "base": null,
+ "href": "turn://example.com:8080/pathname?search#hash",
+ "origin": "null",
+ "protocol": "turn:",
+ "username": "",
+ "password": "",
+ "host": "example.com:8080",
+ "hostname": "example.com",
+ "port": "8080",
+ "pathname": "/pathname",
+ "search": "?search",
+ "hash": "#hash"
+ },
+ {
+ "input": "turn:///test",
+ "base": null,
+ "href": "turn:///test",
+ "origin": "null",
+ "protocol": "turn:",
+ "username": "",
+ "password": "",
+ "host": "",
+ "hostname": "",
+ "port": "",
+ "pathname": "/test",
+ "search": "",
+ "hash": ""
+ },
+ {
+ "input": "turn://test/a/../b",
+ "base": null,
+ "href": "turn://test/b",
+ "origin": "null",
+ "protocol": "turn:",
+ "username": "",
+ "password": "",
+ "host": "test",
+ "hostname": "test",
+ "port": "",
+ "pathname": "/b",
+ "search": "",
+ "hash": ""
+ },
+ {
+ "input": "turn://:443",
+ "base": null,
+ "failure": true
+ },
+ {
+ "input": "turn://test:test",
+ "base": null,
+ "failure": true
+ },
+ {
+ "input": "turn://[:1]",
+ "base": null,
+ "failure": true
+ },
+ {
+ "input": "stun://example.com:8080/pathname?search#hash",
+ "base": null,
+ "href": "stun://example.com:8080/pathname?search#hash",
+ "origin": "null",
+ "protocol": "stun:",
+ "username": "",
+ "password": "",
+ "host": "example.com:8080",
+ "hostname": "example.com",
+ "port": "8080",
+ "pathname": "/pathname",
+ "search": "?search",
+ "hash": "#hash"
+ },
+ {
+ "input": "stun:///test",
+ "base": null,
+ "href": "stun:///test",
+ "origin": "null",
+ "protocol": "stun:",
+ "username": "",
+ "password": "",
+ "host": "",
+ "hostname": "",
+ "port": "",
+ "pathname": "/test",
+ "search": "",
+ "hash": ""
+ },
+ {
+ "input": "stun://test/a/../b",
+ "base": null,
+ "href": "stun://test/b",
+ "origin": "null",
+ "protocol": "stun:",
+ "username": "",
+ "password": "",
+ "host": "test",
+ "hostname": "test",
+ "port": "",
+ "pathname": "/b",
+ "search": "",
+ "hash": ""
+ },
+ {
+ "input": "stun://:443",
+ "base": null,
+ "failure": true
+ },
+ {
+ "input": "stun://test:test",
+ "base": null,
+ "failure": true
+ },
+ {
+ "input": "stun://[:1]",
+ "base": null,
+ "failure": true
+ },
+ {
+ "input": "w://x:0",
+ "base": null,
+ "href": "w://x:0",
+ "origin": "null",
+ "protocol": "w:",
+ "username": "",
+ "password": "",
+ "host": "x:0",
+ "hostname": "x",
+ "port": "0",
+ "pathname": "",
+ "search": "",
+ "hash": ""
+ },
+ {
+ "input": "west://x:0",
+ "base": null,
+ "href": "west://x:0",
+ "origin": "null",
+ "protocol": "west:",
+ "username": "",
+ "password": "",
+ "host": "x:0",
+ "hostname": "x",
+ "port": "0",
+ "pathname": "",
+ "search": "",
+ "hash": ""
}
]
diff --git a/vendor/url/tests/wpt.rs b/vendor/url/tests/wpt.rs
new file mode 100644
index 000000000..701044d67
--- /dev/null
+++ b/vendor/url/tests/wpt.rs
@@ -0,0 +1,477 @@
+// Copyright 2013-2014 The rust-url developers.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! Data-driven tests imported from web-platform-tests
+
+use std::collections::HashMap;
+use std::fmt::Write;
+use std::panic;
+
+use serde_json::Value;
+use url::Url;
+
+#[derive(Debug, serde::Deserialize)]
+struct UrlTest {
+ input: String,
+ base: Option<String>,
+ #[serde(flatten)]
+ result: UrlTestResult,
+}
+
+#[derive(Debug, serde::Deserialize)]
+#[serde(untagged)]
+#[allow(clippy::large_enum_variant)]
+enum UrlTestResult {
+ Ok(UrlTestOk),
+ Fail(UrlTestFail),
+}
+
+#[derive(Debug, serde::Deserialize)]
+struct UrlTestOk {
+ href: String,
+ protocol: String,
+ username: String,
+ password: String,
+ host: String,
+ hostname: String,
+ port: String,
+ pathname: String,
+ search: String,
+ hash: String,
+}
+
+#[derive(Debug, serde::Deserialize)]
+struct UrlTestFail {
+ failure: bool,
+}
+
+#[derive(Debug, serde::Deserialize)]
+struct SetterTest {
+ href: String,
+ new_value: String,
+ expected: SetterTestExpected,
+}
+
+#[derive(Debug, serde::Deserialize)]
+struct SetterTestExpected {
+ href: Option<String>,
+ protocol: Option<String>,
+ username: Option<String>,
+ password: Option<String>,
+ host: Option<String>,
+ hostname: Option<String>,
+ port: Option<String>,
+ pathname: Option<String>,
+ search: Option<String>,
+ hash: Option<String>,
+}
+
+fn main() {
+ let mut filter = None;
+ let mut args = std::env::args().skip(1);
+ while filter.is_none() {
+ if let Some(arg) = args.next() {
+ if arg == "--test-threads" {
+ args.next();
+ continue;
+ }
+ filter = Some(arg);
+ } else {
+ break;
+ }
+ }
+
+ let mut expected_failures = include_str!("expected_failures.txt")
+ .lines()
+ .collect::<Vec<_>>();
+
+ let mut errors = vec![];
+
+ // Copied from https://github.com/web-platform-tests/wpt/blob/master/url/
+ let url_json: Vec<Value> = serde_json::from_str(include_str!("urltestdata.json"))
+ .expect("JSON parse error in urltestdata.json");
+ let url_tests = url_json
+ .into_iter()
+ .filter(|val| val.is_object())
+ .map(|val| serde_json::from_value::<UrlTest>(val).expect("parsing failed"))
+ .collect::<Vec<_>>();
+
+ let setter_json: HashMap<String, Value> =
+ serde_json::from_str(include_str!("setters_tests.json"))
+ .expect("JSON parse error in setters_tests.json");
+ let setter_tests = setter_json
+ .into_iter()
+ .filter(|(k, _)| k != "comment")
+ .map(|(k, v)| {
+ let test = serde_json::from_value::<Vec<SetterTest>>(v).expect("parsing failed");
+ (k, test)
+ })
+ .collect::<HashMap<_, _>>();
+
+ for url_test in url_tests {
+ let mut name = format!("<{}>", url_test.input.escape_default());
+ if let Some(base) = &url_test.base {
+ write!(&mut name, " against <{}>", base.escape_default()).unwrap();
+ }
+ if should_skip(&name, filter.as_deref()) {
+ continue;
+ }
+ print!("{} ... ", name);
+
+ let res = run_url_test(url_test);
+ report(name, res, &mut errors, &mut expected_failures);
+ }
+
+ for (kind, tests) in setter_tests {
+ for test in tests {
+ let name = format!(
+ "<{}> set {} to <{}>",
+ test.href.escape_default(),
+ kind,
+ test.new_value.escape_default()
+ );
+ if should_skip(&name, filter.as_deref()) {
+ continue;
+ }
+
+ print!("{} ... ", name);
+
+ let res = run_setter_test(&kind, test);
+ report(name, res, &mut errors, &mut expected_failures);
+ }
+ }
+
+ println!();
+ println!("====================");
+ println!();
+
+ if !errors.is_empty() {
+ println!("errors:");
+ println!();
+
+ for (name, err) in errors {
+ println!(" name: {}", name);
+ println!(" err: {}", err);
+ println!();
+ }
+
+ std::process::exit(1);
+ } else {
+ println!("all tests passed");
+ }
+
+ if !expected_failures.is_empty() && filter.is_none() {
+ println!();
+ println!("====================");
+ println!();
+ println!("tests were expected to fail but did not run:");
+ println!();
+
+ for name in expected_failures {
+ println!(" {}", name);
+ }
+
+ println!();
+ println!("if these tests were removed, update expected_failures.txt");
+ println!();
+
+ std::process::exit(1);
+ }
+}
+
+fn should_skip(name: &str, filter: Option<&str>) -> bool {
+ match filter {
+ Some(filter) => !name.contains(filter),
+ None => false,
+ }
+}
+
+fn report(
+ name: String,
+ res: Result<(), String>,
+ errors: &mut Vec<(String, String)>,
+ expected_failures: &mut Vec<&str>,
+) {
+ let expected_failure = expected_failures.contains(&&*name);
+ expected_failures.retain(|&s| s != &*name);
+ match res {
+ Ok(()) => {
+ if expected_failure {
+ println!("🟠 (unexpected success)");
+ errors.push((name, "unexpected success".to_string()));
+ } else {
+ println!("✅");
+ }
+ }
+ Err(err) => {
+ if expected_failure {
+ println!("✅ (expected fail)");
+ } else {
+ println!("❌");
+ errors.push((name, err));
+ }
+ }
+ }
+}
+
+fn run_url_test(
+ UrlTest {
+ base,
+ input,
+ result,
+ }: UrlTest,
+) -> Result<(), String> {
+ let base = match base {
+ Some(base) => {
+ let base = panic::catch_unwind(|| Url::parse(&base))
+ .map_err(|_| "panicked while parsing base".to_string())?
+ .map_err(|e| format!("errored while parsing base: {}", e))?;
+ Some(base)
+ }
+ None => None,
+ };
+
+ let res = panic::catch_unwind(move || Url::options().base_url(base.as_ref()).parse(&input))
+ .map_err(|_| "panicked while parsing input".to_string())?
+ .map_err(|e| format!("errored while parsing input: {}", e));
+
+ match result {
+ UrlTestResult::Ok(ok) => check_url_ok(res, ok),
+ UrlTestResult::Fail(fail) => {
+ assert!(fail.failure);
+ if res.is_ok() {
+ return Err("expected failure, but parsed successfully".to_string());
+ }
+
+ Ok(())
+ }
+ }
+}
+
+fn check_url_ok(res: Result<Url, String>, ok: UrlTestOk) -> Result<(), String> {
+ let url = match res {
+ Ok(url) => url,
+ Err(err) => {
+ return Err(format!("expected success, but errored: {:?}", err));
+ }
+ };
+
+ let href = url::quirks::href(&url);
+ if href != ok.href {
+ return Err(format!("expected href {:?}, but got {:?}", ok.href, href));
+ }
+
+ let protocol = url::quirks::protocol(&url);
+ if protocol != ok.protocol {
+ return Err(format!(
+ "expected protocol {:?}, but got {:?}",
+ ok.protocol, protocol
+ ));
+ }
+
+ let username = url::quirks::username(&url);
+ if username != ok.username {
+ return Err(format!(
+ "expected username {:?}, but got {:?}",
+ ok.username, username
+ ));
+ }
+
+ let password = url::quirks::password(&url);
+ if password != ok.password {
+ return Err(format!(
+ "expected password {:?}, but got {:?}",
+ ok.password, password
+ ));
+ }
+
+ let host = url::quirks::host(&url);
+ if host != ok.host {
+ return Err(format!("expected host {:?}, but got {:?}", ok.host, host));
+ }
+
+ let hostname = url::quirks::hostname(&url);
+ if hostname != ok.hostname {
+ return Err(format!(
+ "expected hostname {:?}, but got {:?}",
+ ok.hostname, hostname
+ ));
+ }
+
+ let port = url::quirks::port(&url);
+ if port != ok.port {
+ return Err(format!("expected port {:?}, but got {:?}", ok.port, port));
+ }
+
+ let pathname = url::quirks::pathname(&url);
+ if pathname != ok.pathname {
+ return Err(format!(
+ "expected pathname {:?}, but got {:?}",
+ ok.pathname, pathname
+ ));
+ }
+
+ let search = url::quirks::search(&url);
+ if search != ok.search {
+ return Err(format!(
+ "expected search {:?}, but got {:?}",
+ ok.search, search
+ ));
+ }
+
+ let hash = url::quirks::hash(&url);
+ if hash != ok.hash {
+ return Err(format!("expected hash {:?}, but got {:?}", ok.hash, hash));
+ }
+
+ Ok(())
+}
+
+fn run_setter_test(
+ kind: &str,
+ SetterTest {
+ href,
+ new_value,
+ expected,
+ }: SetterTest,
+) -> Result<(), String> {
+ let mut url = panic::catch_unwind(|| Url::parse(&href))
+ .map_err(|_| "panicked while parsing href".to_string())?
+ .map_err(|e| format!("errored while parsing href: {}", e))?;
+
+ let url = panic::catch_unwind(move || {
+ match kind {
+ "protocol" => {
+ url::quirks::set_protocol(&mut url, &new_value).ok();
+ }
+ "username" => {
+ url::quirks::set_username(&mut url, &new_value).ok();
+ }
+ "password" => {
+ url::quirks::set_password(&mut url, &new_value).ok();
+ }
+ "host" => {
+ url::quirks::set_host(&mut url, &new_value).ok();
+ }
+ "hostname" => {
+ url::quirks::set_hostname(&mut url, &new_value).ok();
+ }
+ "port" => {
+ url::quirks::set_port(&mut url, &new_value).ok();
+ }
+ "pathname" => url::quirks::set_pathname(&mut url, &new_value),
+ "search" => url::quirks::set_search(&mut url, &new_value),
+ "hash" => url::quirks::set_hash(&mut url, &new_value),
+ _ => panic!("unknown setter kind: {:?}", kind),
+ };
+ url
+ })
+ .map_err(|_| "panicked while setting value".to_string())?;
+
+ if let Some(expected_href) = expected.href {
+ let href = url::quirks::href(&url);
+ if href != expected_href {
+ return Err(format!(
+ "expected href {:?}, but got {:?}",
+ expected_href, href
+ ));
+ }
+ }
+
+ if let Some(expected_protocol) = expected.protocol {
+ let protocol = url::quirks::protocol(&url);
+ if protocol != expected_protocol {
+ return Err(format!(
+ "expected protocol {:?}, but got {:?}",
+ expected_protocol, protocol
+ ));
+ }
+ }
+
+ if let Some(expected_username) = expected.username {
+ let username = url::quirks::username(&url);
+ if username != expected_username {
+ return Err(format!(
+ "expected username {:?}, but got {:?}",
+ expected_username, username
+ ));
+ }
+ }
+
+ if let Some(expected_password) = expected.password {
+ let password = url::quirks::password(&url);
+ if password != expected_password {
+ return Err(format!(
+ "expected password {:?}, but got {:?}",
+ expected_password, password
+ ));
+ }
+ }
+
+ if let Some(expected_host) = expected.host {
+ let host = url::quirks::host(&url);
+ if host != expected_host {
+ return Err(format!(
+ "expected host {:?}, but got {:?}",
+ expected_host, host
+ ));
+ }
+ }
+
+ if let Some(expected_hostname) = expected.hostname {
+ let hostname = url::quirks::hostname(&url);
+ if hostname != expected_hostname {
+ return Err(format!(
+ "expected hostname {:?}, but got {:?}",
+ expected_hostname, hostname
+ ));
+ }
+ }
+
+ if let Some(expected_port) = expected.port {
+ let port = url::quirks::port(&url);
+ if port != expected_port {
+ return Err(format!(
+ "expected port {:?}, but got {:?}",
+ expected_port, port
+ ));
+ }
+ }
+
+ if let Some(expected_pathname) = expected.pathname {
+ let pathname = url::quirks::pathname(&url);
+ if pathname != expected_pathname {
+ return Err(format!(
+ "expected pathname {:?}, but got {:?}",
+ expected_pathname, pathname
+ ));
+ }
+ }
+
+ if let Some(expected_search) = expected.search {
+ let search = url::quirks::search(&url);
+ if search != expected_search {
+ return Err(format!(
+ "expected search {:?}, but got {:?}",
+ expected_search, search
+ ));
+ }
+ }
+
+ if let Some(expected_hash) = expected.hash {
+ let hash = url::quirks::hash(&url);
+ if hash != expected_hash {
+ return Err(format!(
+ "expected hash {:?}, but got {:?}",
+ expected_hash, hash
+ ));
+ }
+ }
+
+ Ok(())
+}