mirror of
git://slackware.nl/current.git
synced 2024-12-28 09:59:53 +01:00
11403357f2
a/dialog-1.3_20200228-x86_64-1.txz: Upgraded. l/Mako-1.1.2-x86_64-1.txz: Upgraded. l/imagemagick-7.0.9_27-x86_64-1.txz: Upgraded. l/libcap-2.33-x86_64-1.txz: Upgraded. n/bind-9.16.0-x86_64-2.txz: Rebuilt. rc.bind: ensure /var/run/named exists before starting named. Thanks to MarcT. rc.bind: when stopping named, only kill processes in the current namespace. x/libevdev-1.9.0-x86_64-1.txz: Upgraded. x/wayland-protocols-1.20-noarch-1.txz: Upgraded. xap/seamonkey-2.53.1-x86_64-1.txz: Upgraded. This update contains security fixes and improvements. For more information, see: https://www.seamonkey-project.org/releases/seamonkey2.53.1 (* Security fix *) testing/packages/PAM/libcap-2.33-x86_64-1_pam.txz: Upgraded.
4279 lines
131 KiB
Diff
4279 lines
131 KiB
Diff
diff -u -r --new-file seamonkey-2.53.1.orig/mozilla/netwerk/base/rust-url-capi/Cargo.toml seamonkey-2.53.1/mozilla/netwerk/base/rust-url-capi/Cargo.toml
|
||
--- seamonkey-2.53.1.orig/mozilla/netwerk/base/rust-url-capi/Cargo.toml 2020-02-17 17:37:59.000000000 -0600
|
||
+++ seamonkey-2.53.1/mozilla/netwerk/base/rust-url-capi/Cargo.toml 2020-02-29 21:16:23.109772243 -0600
|
||
@@ -8,6 +8,6 @@
|
||
|
||
[dependencies]
|
||
libc = "0.2.0"
|
||
-url = "1.5.1"
|
||
+url = "1.7.2"
|
||
nsstring = { path = "../../../xpcom/rust/nsstring" }
|
||
nserror = { path = "../../../xpcom/rust/nserror" }
|
||
diff -u -r --new-file seamonkey-2.53.1.orig/mozilla/third_party/rust/url/.cargo-checksum.json seamonkey-2.53.1/mozilla/third_party/rust/url/.cargo-checksum.json
|
||
--- seamonkey-2.53.1.orig/mozilla/third_party/rust/url/.cargo-checksum.json 2020-02-17 17:39:21.000000000 -0600
|
||
+++ seamonkey-2.53.1/mozilla/third_party/rust/url/.cargo-checksum.json 2020-02-29 21:15:43.797770564 -0600
|
||
@@ -1 +1 @@
|
||
-{"files":{".cargo-ok":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",".travis.yml":"890af214187ffcba4732acb2d1af30d7adb9aade0679e9fdb06baae363240b8e","Cargo.toml":"ec586106c4d0625919a3591fe3ae915043e82c8bfdd1c9e747171ba5e21047e1","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"20c7855c364d57ea4c97889a5e8d98470a9952dade37bd9248b9a54431670e5e","Makefile":"bffd75d34654b2955d4f005f1a5e85c821c90becf1a8a52cbe10121972f43148","README.md":"eb3f4694003f408cbe3c7f3e9fbbc71241defb940cc55a816981f0f0f144c8eb","UPGRADING.md":"fbcc2d39bdf17db0745793db6626fcd5c909dddd4ce13b27566cfabece22c368","appveyor.yml":"c78486dbfbe6ebbf3d808afb9a19f7ec18c4704ce451c6305f0716999b70a1a6","docs/.nojekyll":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","docs/404.html":"f61e6271c1ea1aa113b64b356e994595fa548f0433f89948d747503ad22195cd","docs/index.html":"f61e6271c1ea1aa113b64b356e994595fa548f0433f89948d747503ad22195cd","github.png":"b432fd855efe7c430fe6a57ccf83935c1996f03a7cdc8d6e1b34154b8c43f6ec","rust-url-todo":"1192cee7b6cedf2133d97dc6074b593a1d19b0ee13fff6f28d6329855044e575","src/encoding.rs":"f3e109ca8ec5a9130da50cdfb3003530aedb6dd5a440f0790d76b71f6981119c","src/form_urlencoded.rs":"7ccaef7148e4bc2577154c50f8705db3a055b641269e24c22770f06222321e1e","src/host.rs":"281165d732ea87b6f01a98f7c68ffcb284c41f84b3ab6ed674fb8e57022d1019","src/lib.rs":"bd156e8bcfbd44f0cd52c8b394e03ec63fea012c0bf5ca554521352714838605","src/origin.rs":"7071dcc1070ccfae84cdcd43586b84a9706e35a9a099ff4dde128da0909bd0bc","src/parser.rs":"9d30868f0900586fec6f122a0322598a08116ab0b4c4d8caf5c35a720381a73a","src/path_segments.rs":"7bd3142eaa568863ef44e2255c181239141f9eeee337f889b9ffaaeab4ca669d","src/quirks.rs":"1231f965e22bb3632c22993e2a8d4c7470bcb4a8de25d049f31784303f0def03","src/slicing.rs":"4e539886b23945a92094625f3e531a4bff40daa44240b5d19ee8577478c4f7fe","tests/data.rs":"c333766897f6492fb6583ab5c8a511973b7a55f58ca550799432343da64d5ca7","tests/setters_tests.json":"ebcbdb52e9a4b5a565f8806d52ebc610d46a34df883e10b0be080d026468ff73","tests/unit.rs":"c2f206f433be619414d761d358a2a4a5a46cfe8a4fea5339adec5e9937d78de2","tests/urltestdata.json":"430c74aa3a31afaa57a92805544e00825f4dffe2def98c1e3c212c3db80268af"},"package":"eeb819346883532a271eb626deb43c4a1bb4c4dd47c519bd78137c3e72a4fe27"}
|
||
\ No newline at end of file
|
||
+{"files":{"Cargo.toml":"80d575ae6adad93cb0910b385b871e2d92d558078f58a3c8eafe95940d459f6b","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"20c7855c364d57ea4c97889a5e8d98470a9952dade37bd9248b9a54431670e5e","README.md":"eb3f4694003f408cbe3c7f3e9fbbc71241defb940cc55a816981f0f0f144c8eb","UPGRADING.md":"fbcc2d39bdf17db0745793db6626fcd5c909dddd4ce13b27566cfabece22c368","appveyor.yml":"c78486dbfbe6ebbf3d808afb9a19f7ec18c4704ce451c6305f0716999b70a1a6","benches/parse_url.rs":"821ecb051c3c6c40eb3b268ba7337b2988333627d0af0c8e1afc84734ffbbf2b","docs/404.html":"f61e6271c1ea1aa113b64b356e994595fa548f0433f89948d747503ad22195cd","docs/index.html":"f61e6271c1ea1aa113b64b356e994595fa548f0433f89948d747503ad22195cd","src/encoding.rs":"f3e109ca8ec5a9130da50cdfb3003530aedb6dd5a440f0790d76b71f6981119c","src/form_urlencoded.rs":"d8c35e92375cafcd7e12c4f0d5374bab62aa1f333629d55b007a9c3d5c3cb615","src/host.rs":"66a2c0c77a8add2da16bc690fbc82b130cf1367ac655fc36990a214e193a4d6c","src/lib.rs":"e09dcba401018169ee26764e1c2bccf0855a5d935707c2100fd8d8e77a1bbc91","src/origin.rs":"6e4821eb9600a32ef54d05c8e1a7937f6d9b4dd1e3bda7f36c7988f6a2bef78b","src/parser.rs":"76368cbe93308123c014a3502024cf97d97ca61dcfc7b6ecd710073867d6deca","src/path_segments.rs":"7bd3142eaa568863ef44e2255c181239141f9eeee337f889b9ffaaeab4ca669d","src/quirks.rs":"6cf1697bad363532cbcc60917a9b126560ac3ab3e1a77da0abcf4f2a40c8233a","src/slicing.rs":"4e539886b23945a92094625f3e531a4bff40daa44240b5d19ee8577478c4f7fe","tests/data.rs":"f2c1c6d1823e8d21aeeae31c786d7f4ef0d97352a896f8c5aeb03a41fedb9a48","tests/setters_tests.json":"08ddaa632ad19c81e83b904bfaa94bc971f26e2bdfcef27d2f93fd033ad57340","tests/unit.rs":"ead7185710ce06c8d68ea18700618477867ee355656eabcad26cfcfaaad361a0","tests/urltestdata.json":"1b0c7c727d8d7e79dfb0d0aa347ff05675ddb68bc4ead38f83fd8e89bc59cc32"},"package":"dd4e7c0d531266369519a4aa4f399d748bd37043b00bde1e4ff1f60a120b355a"}
|
||
\ No newline at end of file
|
||
diff -u -r --new-file seamonkey-2.53.1.orig/mozilla/third_party/rust/url/.travis.yml seamonkey-2.53.1/mozilla/third_party/rust/url/.travis.yml
|
||
--- seamonkey-2.53.1.orig/mozilla/third_party/rust/url/.travis.yml 2020-02-17 17:39:21.000000000 -0600
|
||
+++ seamonkey-2.53.1/mozilla/third_party/rust/url/.travis.yml 1969-12-31 18:00:00.000000000 -0600
|
||
@@ -1,9 +0,0 @@
|
||
-language: rust
|
||
-rust:
|
||
- - nightly
|
||
- - beta
|
||
- - stable
|
||
- - 1.17.0
|
||
-script: make test
|
||
-notifications:
|
||
- webhooks: http://build.servo.org:54856/travis
|
||
diff -u -r --new-file seamonkey-2.53.1.orig/mozilla/third_party/rust/url/Cargo.toml seamonkey-2.53.1/mozilla/third_party/rust/url/Cargo.toml
|
||
--- seamonkey-2.53.1.orig/mozilla/third_party/rust/url/Cargo.toml 2020-02-17 17:39:21.000000000 -0600
|
||
+++ seamonkey-2.53.1/mozilla/third_party/rust/url/Cargo.toml 2020-02-29 21:15:43.799770565 -0600
|
||
@@ -1,24 +1,31 @@
|
||
-[package]
|
||
+# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
|
||
+#
|
||
+# When uploading crates to the registry Cargo will automatically
|
||
+# "normalize" Cargo.toml files for maximal compatibility
|
||
+# with all versions of Cargo and also rewrite `path` dependencies
|
||
+# to registry (e.g. crates.io) dependencies
|
||
+#
|
||
+# If you believe there's an error in this file please file an
|
||
+# issue against the rust-lang/cargo repository. If you're
|
||
+# editing this file be aware that the upstream Cargo.toml
|
||
+# will likely look very different (and much more reasonable)
|
||
|
||
+[package]
|
||
name = "url"
|
||
-# When updating version, also modify html_root_url in the lib.rs
|
||
-version = "1.5.1"
|
||
+version = "1.7.2"
|
||
authors = ["The rust-url developers"]
|
||
-
|
||
description = "URL library for Rust, based on the WHATWG URL Standard"
|
||
documentation = "https://docs.rs/url"
|
||
-repository = "https://github.com/servo/rust-url"
|
||
readme = "README.md"
|
||
keywords = ["url", "parser"]
|
||
categories = ["parser-implementations", "web-programming", "encoding"]
|
||
license = "MIT/Apache-2.0"
|
||
+repository = "https://github.com/servo/rust-url"
|
||
+[package.metadata.docs.rs]
|
||
+features = ["query_encoding"]
|
||
|
||
-[badges]
|
||
-travis-ci = { repository = "servo/rust-url" }
|
||
-appveyor = { repository = "servo/rust-url" }
|
||
-
|
||
-[workspace]
|
||
-members = [".", "idna", "percent_encoding", "url_serde"]
|
||
+[lib]
|
||
+test = false
|
||
|
||
[[test]]
|
||
name = "unit"
|
||
@@ -27,23 +34,50 @@
|
||
name = "data"
|
||
harness = false
|
||
|
||
-[lib]
|
||
-test = false
|
||
+[[bench]]
|
||
+name = "parse_url"
|
||
+harness = false
|
||
+[dependencies.encoding]
|
||
+version = "0.2"
|
||
+optional = true
|
||
|
||
-[dev-dependencies]
|
||
-rustc-test = "0.1"
|
||
-rustc-serialize = "0.3"
|
||
-serde_json = ">=0.6.1, <0.9"
|
||
+[dependencies.heapsize]
|
||
+version = ">=0.4.1, <0.5"
|
||
+optional = true
|
||
+
|
||
+[dependencies.idna]
|
||
+version = "0.1.0"
|
||
+
|
||
+[dependencies.matches]
|
||
+version = "0.1"
|
||
+
|
||
+[dependencies.percent-encoding]
|
||
+version = "1.0.0"
|
||
+
|
||
+[dependencies.rustc-serialize]
|
||
+version = "0.3"
|
||
+optional = true
|
||
+
|
||
+[dependencies.serde]
|
||
+version = ">=0.6.1, <0.9"
|
||
+optional = true
|
||
+[dev-dependencies.bencher]
|
||
+version = "0.1"
|
||
+
|
||
+[dev-dependencies.rustc-serialize]
|
||
+version = "0.3"
|
||
+
|
||
+[dev-dependencies.rustc-test]
|
||
+version = "0.3"
|
||
+
|
||
+[dev-dependencies.serde_json]
|
||
+version = ">=0.6.1, <0.9"
|
||
|
||
[features]
|
||
-query_encoding = ["encoding"]
|
||
heap_size = ["heapsize"]
|
||
+query_encoding = ["encoding"]
|
||
+[badges.appveyor]
|
||
+repository = "Manishearth/rust-url"
|
||
|
||
-[dependencies]
|
||
-encoding = {version = "0.2", optional = true}
|
||
-heapsize = {version = ">=0.1.1, <0.5", optional = true}
|
||
-idna = { version = "0.1.0", path = "./idna" }
|
||
-matches = "0.1"
|
||
-percent-encoding = { version = "1.0.0", path = "./percent_encoding" }
|
||
-rustc-serialize = {version = "0.3", optional = true}
|
||
-serde = {version = ">=0.6.1, <0.9", optional = true}
|
||
+[badges.travis-ci]
|
||
+repository = "servo/rust-url"
|
||
diff -u -r --new-file seamonkey-2.53.1.orig/mozilla/third_party/rust/url/Makefile seamonkey-2.53.1/mozilla/third_party/rust/url/Makefile
|
||
--- seamonkey-2.53.1.orig/mozilla/third_party/rust/url/Makefile 2020-02-17 17:39:21.000000000 -0600
|
||
+++ seamonkey-2.53.1/mozilla/third_party/rust/url/Makefile 1969-12-31 18:00:00.000000000 -0600
|
||
@@ -1,6 +0,0 @@
|
||
-test:
|
||
- cargo test --features "query_encoding serde rustc-serialize heapsize"
|
||
- (cd idna && cargo test)
|
||
- (cd url_serde && cargo test)
|
||
-
|
||
-.PHONY: test
|
||
diff -u -r --new-file seamonkey-2.53.1.orig/mozilla/third_party/rust/url/benches/parse_url.rs seamonkey-2.53.1/mozilla/third_party/rust/url/benches/parse_url.rs
|
||
--- seamonkey-2.53.1.orig/mozilla/third_party/rust/url/benches/parse_url.rs 1969-12-31 18:00:00.000000000 -0600
|
||
+++ seamonkey-2.53.1/mozilla/third_party/rust/url/benches/parse_url.rs 2020-02-29 21:15:43.801770565 -0600
|
||
@@ -0,0 +1,18 @@
|
||
+#[macro_use]
|
||
+extern crate bencher;
|
||
+
|
||
+extern crate url;
|
||
+
|
||
+use bencher::{black_box, Bencher};
|
||
+
|
||
+use url::Url;
|
||
+
|
||
+fn short(bench: &mut Bencher) {
|
||
+ let url = "https://example.com/bench";
|
||
+
|
||
+ bench.bytes = url.len() as u64;
|
||
+ bench.iter(|| black_box(url).parse::<Url>().unwrap());
|
||
+}
|
||
+
|
||
+benchmark_group!(benches, short);
|
||
+benchmark_main!(benches);
|
||
diff -u -r --new-file seamonkey-2.53.1.orig/mozilla/third_party/rust/url/rust-url-todo seamonkey-2.53.1/mozilla/third_party/rust/url/rust-url-todo
|
||
--- seamonkey-2.53.1.orig/mozilla/third_party/rust/url/rust-url-todo 2020-02-17 17:39:21.000000000 -0600
|
||
+++ seamonkey-2.53.1/mozilla/third_party/rust/url/rust-url-todo 1969-12-31 18:00:00.000000000 -0600
|
||
@@ -1,14 +0,0 @@
|
||
-* standalone path parsing?
|
||
-* Test setters
|
||
- * Test trim C0/space
|
||
- * Test remove tab & newline
|
||
-
|
||
-
|
||
-
|
||
-#[test]
|
||
-fn test_path_segments() {
|
||
- let mut url = Url::parse("http://example.net").unwrap();
|
||
- url.push_path_segment("foo").unwrap();
|
||
- url.extend_path_segments(&["bar", "b/az"]).unwrap();
|
||
- assert_eq!(url.as_str(), "http://example.net/foo");
|
||
-}
|
||
diff -u -r --new-file seamonkey-2.53.1.orig/mozilla/third_party/rust/url/src/form_urlencoded.rs seamonkey-2.53.1/mozilla/third_party/rust/url/src/form_urlencoded.rs
|
||
--- seamonkey-2.53.1.orig/mozilla/third_party/rust/url/src/form_urlencoded.rs 2020-02-17 17:39:21.000000000 -0600
|
||
+++ seamonkey-2.53.1/mozilla/third_party/rust/url/src/form_urlencoded.rs 2020-02-29 21:15:43.802770565 -0600
|
||
@@ -16,6 +16,7 @@
|
||
use encoding::EncodingOverride;
|
||
use percent_encoding::{percent_encode_byte, percent_decode};
|
||
use std::borrow::{Borrow, Cow};
|
||
+use std::fmt;
|
||
use std::str;
|
||
|
||
|
||
@@ -216,6 +217,15 @@
|
||
target: Option<T>,
|
||
start_position: usize,
|
||
encoding: EncodingOverride,
|
||
+ custom_encoding: Option<SilentDebug<Box<FnMut(&str) -> Cow<[u8]>>>>,
|
||
+}
|
||
+
|
||
+struct SilentDebug<T>(T);
|
||
+
|
||
+impl<T> fmt::Debug for SilentDebug<T> {
|
||
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||
+ f.write_str("…")
|
||
+ }
|
||
}
|
||
|
||
pub trait Target {
|
||
@@ -247,8 +257,16 @@
|
||
// * `Serializer` keeps its target in a private field
|
||
// * Unlike in other `Target` impls, `UrlQuery::finished` does not return `Self`.
|
||
impl<'a> Target for ::UrlQuery<'a> {
|
||
- fn as_mut_string(&mut self) -> &mut String { &mut self.url.serialization }
|
||
- fn finish(self) -> &'a mut ::Url { self.url }
|
||
+ fn as_mut_string(&mut self) -> &mut String {
|
||
+ &mut self.url.as_mut().unwrap().serialization
|
||
+ }
|
||
+
|
||
+ fn finish(mut self) -> &'a mut ::Url {
|
||
+ let url = self.url.take().unwrap();
|
||
+ url.restore_already_parsed_fragment(self.fragment.take());
|
||
+ url
|
||
+ }
|
||
+
|
||
type Finished = &'a mut ::Url;
|
||
}
|
||
|
||
@@ -272,6 +290,7 @@
|
||
target: Some(target),
|
||
start_position: start_position,
|
||
encoding: EncodingOverride::utf8(),
|
||
+ custom_encoding: None,
|
||
}
|
||
}
|
||
|
||
@@ -290,11 +309,20 @@
|
||
self
|
||
}
|
||
|
||
+ /// Set the character encoding to be used for names and values before percent-encoding.
|
||
+ pub fn custom_encoding_override<F>(&mut self, encode: F) -> &mut Self
|
||
+ where F: FnMut(&str) -> Cow<[u8]> + 'static
|
||
+ {
|
||
+ self.custom_encoding = Some(SilentDebug(Box::new(encode)));
|
||
+ self
|
||
+ }
|
||
+
|
||
/// Serialize and append a name/value pair.
|
||
///
|
||
/// Panics if called after `.finish()`.
|
||
pub fn append_pair(&mut self, name: &str, value: &str) -> &mut Self {
|
||
- append_pair(string(&mut self.target), self.start_position, self.encoding, name, value);
|
||
+ append_pair(string(&mut self.target), self.start_position, self.encoding,
|
||
+ &mut self.custom_encoding, name, value);
|
||
self
|
||
}
|
||
|
||
@@ -311,7 +339,8 @@
|
||
let string = string(&mut self.target);
|
||
for pair in iter {
|
||
let &(ref k, ref v) = pair.borrow();
|
||
- append_pair(string, self.start_position, self.encoding, k.as_ref(), v.as_ref());
|
||
+ append_pair(string, self.start_position, self.encoding,
|
||
+ &mut self.custom_encoding, k.as_ref(), v.as_ref());
|
||
}
|
||
}
|
||
self
|
||
@@ -324,6 +353,8 @@
|
||
/// Panics if called after `.finish()`.
|
||
#[cfg(feature = "query_encoding")]
|
||
pub fn append_charset(&mut self) -> &mut Self {
|
||
+ assert!(self.custom_encoding.is_none(),
|
||
+ "Cannot use both custom_encoding_override() and append_charset()");
|
||
{
|
||
let string = string(&mut self.target);
|
||
append_separator_if_needed(string, self.start_position);
|
||
@@ -361,9 +392,20 @@
|
||
}
|
||
|
||
fn append_pair(string: &mut String, start_position: usize, encoding: EncodingOverride,
|
||
+ custom_encoding: &mut Option<SilentDebug<Box<FnMut(&str) -> Cow<[u8]>>>>,
|
||
name: &str, value: &str) {
|
||
append_separator_if_needed(string, start_position);
|
||
- string.extend(byte_serialize(&encoding.encode(name.into())));
|
||
+ append_encoded(name, string, encoding, custom_encoding);
|
||
string.push('=');
|
||
- string.extend(byte_serialize(&encoding.encode(value.into())));
|
||
+ append_encoded(value, string, encoding, custom_encoding);
|
||
+}
|
||
+
|
||
+fn append_encoded(s: &str, string: &mut String, encoding: EncodingOverride,
|
||
+ custom_encoding: &mut Option<SilentDebug<Box<FnMut(&str) -> Cow<[u8]>>>>) {
|
||
+ let bytes = if let Some(SilentDebug(ref mut custom)) = *custom_encoding {
|
||
+ custom(s)
|
||
+ } else {
|
||
+ encoding.encode(s.into())
|
||
+ };
|
||
+ string.extend(byte_serialize(&bytes));
|
||
}
|
||
diff -u -r --new-file seamonkey-2.53.1.orig/mozilla/third_party/rust/url/src/host.rs seamonkey-2.53.1/mozilla/third_party/rust/url/src/host.rs
|
||
--- seamonkey-2.53.1.orig/mozilla/third_party/rust/url/src/host.rs 2020-02-17 17:39:21.000000000 -0600
|
||
+++ seamonkey-2.53.1/mozilla/third_party/rust/url/src/host.rs 2020-02-29 21:15:07.663769022 -0600
|
||
@@ -13,7 +13,7 @@
|
||
use std::net::{Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6, ToSocketAddrs};
|
||
use std::vec;
|
||
use parser::{ParseResult, ParseError};
|
||
-use percent_encoding::percent_decode;
|
||
+use percent_encoding::{percent_decode, utf8_percent_encode, SIMPLE_ENCODE_SET};
|
||
use idna;
|
||
|
||
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
||
@@ -73,7 +73,9 @@
|
||
#[derive(Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
|
||
pub enum Host<S=String> {
|
||
/// A DNS domain name, as '.' dot-separated labels.
|
||
- /// Non-ASCII labels are encoded in punycode per IDNA.
|
||
+ /// Non-ASCII labels are encoded in punycode per IDNA if this is the host of
|
||
+ /// a special URL, or percent encoded for non-special URLs. Hosts for
|
||
+ /// non-special URLs are also called opaque hosts.
|
||
Domain(S),
|
||
|
||
/// An IPv4 address.
|
||
@@ -137,7 +139,7 @@
|
||
impl Host<String> {
|
||
/// Parse a host: either an IPv6 address in [] square brackets, or a domain.
|
||
///
|
||
- /// https://url.spec.whatwg.org/#host-parsing
|
||
+ /// <https://url.spec.whatwg.org/#host-parsing>
|
||
pub fn parse(input: &str) -> Result<Self, ParseError> {
|
||
if input.starts_with('[') {
|
||
if !input.ends_with(']') {
|
||
@@ -158,6 +160,23 @@
|
||
Ok(Host::Domain(domain.into()))
|
||
}
|
||
}
|
||
+
|
||
+ // <https://url.spec.whatwg.org/#concept-opaque-host-parser>
|
||
+ pub fn parse_opaque(input: &str) -> Result<Self, ParseError> {
|
||
+ if input.starts_with('[') {
|
||
+ if !input.ends_with(']') {
|
||
+ return Err(ParseError::InvalidIpv6Address)
|
||
+ }
|
||
+ return parse_ipv6addr(&input[1..input.len() - 1]).map(Host::Ipv6)
|
||
+ }
|
||
+ if input.find(|c| matches!(c,
|
||
+ '\0' | '\t' | '\n' | '\r' | ' ' | '#' | '/' | ':' | '?' | '@' | '[' | '\\' | ']'
|
||
+ )).is_some() {
|
||
+ return Err(ParseError::InvalidDomainCharacter)
|
||
+ }
|
||
+ let s = utf8_percent_encode(input, SIMPLE_ENCODE_SET).to_string();
|
||
+ Ok(Host::Domain(s))
|
||
+ }
|
||
}
|
||
|
||
impl<S: AsRef<str>> fmt::Display for Host<S> {
|
||
@@ -309,8 +328,8 @@
|
||
}
|
||
}
|
||
|
||
-/// https://url.spec.whatwg.org/#ipv4-number-parser
|
||
-fn parse_ipv4number(mut input: &str) -> Result<u32, ()> {
|
||
+/// <https://url.spec.whatwg.org/#ipv4-number-parser>
|
||
+fn parse_ipv4number(mut input: &str) -> Result<Option<u32>, ()> {
|
||
let mut r = 10;
|
||
if input.starts_with("0x") || input.starts_with("0X") {
|
||
input = &input[2..];
|
||
@@ -319,19 +338,35 @@
|
||
input = &input[1..];
|
||
r = 8;
|
||
}
|
||
+
|
||
+ // At the moment we can't know the reason why from_str_radix fails
|
||
+ // https://github.com/rust-lang/rust/issues/22639
|
||
+ // So instead we check if the input looks like a real number and only return
|
||
+ // an error when it's an overflow.
|
||
+ let valid_number = match r {
|
||
+ 8 => input.chars().all(|c| c >= '0' && c <='7'),
|
||
+ 10 => input.chars().all(|c| c >= '0' && c <='9'),
|
||
+ 16 => input.chars().all(|c| (c >= '0' && c <='9') || (c >='a' && c <= 'f') || (c >= 'A' && c <= 'F')),
|
||
+ _ => false
|
||
+ };
|
||
+
|
||
+ if !valid_number {
|
||
+ return Ok(None);
|
||
+ }
|
||
+
|
||
if input.is_empty() {
|
||
- return Ok(0);
|
||
+ return Ok(Some(0));
|
||
}
|
||
if input.starts_with('+') {
|
||
- return Err(())
|
||
+ return Ok(None);
|
||
}
|
||
match u32::from_str_radix(input, r) {
|
||
- Ok(number) => Ok(number),
|
||
+ Ok(number) => Ok(Some(number)),
|
||
Err(_) => Err(()),
|
||
}
|
||
}
|
||
|
||
-/// https://url.spec.whatwg.org/#concept-ipv4-parser
|
||
+/// <https://url.spec.whatwg.org/#concept-ipv4-parser>
|
||
fn parse_ipv4addr(input: &str) -> ParseResult<Option<Ipv4Addr>> {
|
||
if input.is_empty() {
|
||
return Ok(None)
|
||
@@ -344,15 +379,19 @@
|
||
return Ok(None);
|
||
}
|
||
let mut numbers: Vec<u32> = Vec::new();
|
||
+ let mut overflow = false;
|
||
for part in parts {
|
||
if part == "" {
|
||
return Ok(None);
|
||
}
|
||
- if let Ok(n) = parse_ipv4number(part) {
|
||
- numbers.push(n);
|
||
- } else {
|
||
- return Ok(None);
|
||
- }
|
||
+ match parse_ipv4number(part) {
|
||
+ Ok(Some(n)) => numbers.push(n),
|
||
+ Ok(None) => return Ok(None),
|
||
+ Err(()) => overflow = true
|
||
+ };
|
||
+ }
|
||
+ if overflow {
|
||
+ return Err(ParseError::InvalidIpv4Address);
|
||
}
|
||
let mut ipv4 = numbers.pop().expect("a non-empty list of numbers");
|
||
// Equivalent to: ipv4 >= 256 ** (4 − numbers.len())
|
||
@@ -368,7 +407,7 @@
|
||
Ok(Some(Ipv4Addr::from(ipv4)))
|
||
}
|
||
|
||
-/// https://url.spec.whatwg.org/#concept-ipv6-parser
|
||
+/// <https://url.spec.whatwg.org/#concept-ipv6-parser>
|
||
fn parse_ipv6addr(input: &str) -> ParseResult<Ipv6Addr> {
|
||
let input = input.as_bytes();
|
||
let len = input.len();
|
||
@@ -423,6 +462,9 @@
|
||
return Err(ParseError::InvalidIpv6Address)
|
||
}
|
||
i = start;
|
||
+ if piece_pointer > 6 {
|
||
+ return Err(ParseError::InvalidIpv6Address)
|
||
+ }
|
||
is_ip_v4 = true;
|
||
},
|
||
b':' => {
|
||
@@ -445,16 +487,24 @@
|
||
if piece_pointer > 6 {
|
||
return Err(ParseError::InvalidIpv6Address)
|
||
}
|
||
- let mut dots_seen = 0;
|
||
+ let mut numbers_seen = 0;
|
||
while i < len {
|
||
- let mut value = None;
|
||
+ if numbers_seen > 0 {
|
||
+ if numbers_seen < 4 && (i < len && input[i] == b'.') {
|
||
+ i += 1
|
||
+ } else {
|
||
+ return Err(ParseError::InvalidIpv6Address)
|
||
+ }
|
||
+ }
|
||
+
|
||
+ let mut ipv4_piece = None;
|
||
while i < len {
|
||
let digit = match input[i] {
|
||
c @ b'0' ... b'9' => c - b'0',
|
||
_ => break
|
||
};
|
||
- match value {
|
||
- None => value = Some(digit as u16),
|
||
+ match ipv4_piece {
|
||
+ None => ipv4_piece = Some(digit as u16),
|
||
Some(0) => return Err(ParseError::InvalidIpv6Address), // No leading zero
|
||
Some(ref mut v) => {
|
||
*v = *v * 10 + digit as u16;
|
||
@@ -465,24 +515,28 @@
|
||
}
|
||
i += 1;
|
||
}
|
||
- if dots_seen < 3 && !(i < len && input[i] == b'.') {
|
||
- return Err(ParseError::InvalidIpv6Address)
|
||
- }
|
||
- pieces[piece_pointer] = if let Some(v) = value {
|
||
+
|
||
+ pieces[piece_pointer] = if let Some(v) = ipv4_piece {
|
||
pieces[piece_pointer] * 0x100 + v
|
||
} else {
|
||
return Err(ParseError::InvalidIpv6Address)
|
||
};
|
||
- if dots_seen == 1 || dots_seen == 3 {
|
||
+ numbers_seen += 1;
|
||
+
|
||
+ if numbers_seen == 2 || numbers_seen == 4 {
|
||
piece_pointer += 1;
|
||
}
|
||
- i += 1;
|
||
- if dots_seen == 3 && i < len {
|
||
- return Err(ParseError::InvalidIpv6Address)
|
||
- }
|
||
- dots_seen += 1;
|
||
+ }
|
||
+
|
||
+ if numbers_seen != 4 {
|
||
+ return Err(ParseError::InvalidIpv6Address)
|
||
}
|
||
}
|
||
+
|
||
+ if i < len {
|
||
+ return Err(ParseError::InvalidIpv6Address)
|
||
+ }
|
||
+
|
||
match compress_pointer {
|
||
Some(compress_pointer) => {
|
||
let mut swaps = piece_pointer - compress_pointer;
|
||
diff -u -r --new-file seamonkey-2.53.1.orig/mozilla/third_party/rust/url/src/lib.rs seamonkey-2.53.1/mozilla/third_party/rust/url/src/lib.rs
|
||
--- seamonkey-2.53.1.orig/mozilla/third_party/rust/url/src/lib.rs 2020-02-17 17:39:21.000000000 -0600
|
||
+++ seamonkey-2.53.1/mozilla/third_party/rust/url/src/lib.rs 2020-02-29 21:15:43.804770565 -0600
|
||
@@ -104,7 +104,7 @@
|
||
# run().unwrap();
|
||
*/
|
||
|
||
-#![doc(html_root_url = "https://docs.rs/url/1.5.1")]
|
||
+#![doc(html_root_url = "https://docs.rs/url/1.7.0")]
|
||
|
||
#[cfg(feature="rustc-serialize")] extern crate rustc_serialize;
|
||
#[macro_use] extern crate matches;
|
||
@@ -112,12 +112,13 @@
|
||
#[cfg(feature="heapsize")] #[macro_use] extern crate heapsize;
|
||
|
||
pub extern crate idna;
|
||
+#[macro_use]
|
||
pub extern crate percent_encoding;
|
||
|
||
use encoding::EncodingOverride;
|
||
#[cfg(feature = "heapsize")] use heapsize::HeapSizeOf;
|
||
use host::HostInternal;
|
||
-use parser::{Parser, Context, SchemeType, to_u32};
|
||
+use parser::{Parser, Context, SchemeType, to_u32, ViolationFn};
|
||
use percent_encoding::{PATH_SEGMENT_ENCODE_SET, USERINFO_ENCODE_SET,
|
||
percent_encode, percent_decode, utf8_percent_encode};
|
||
use std::borrow::Borrow;
|
||
@@ -135,7 +136,7 @@
|
||
pub use origin::{Origin, OpaqueOrigin};
|
||
pub use host::{Host, HostAndPort, SocketAddrs};
|
||
pub use path_segments::PathSegmentsMut;
|
||
-pub use parser::ParseError;
|
||
+pub use parser::{ParseError, SyntaxViolation};
|
||
pub use slicing::Position;
|
||
|
||
mod encoding;
|
||
@@ -186,7 +187,7 @@
|
||
pub struct ParseOptions<'a> {
|
||
base_url: Option<&'a Url>,
|
||
encoding_override: encoding::EncodingOverride,
|
||
- log_syntax_violation: Option<&'a Fn(&'static str)>,
|
||
+ violation_fn: ViolationFn<'a>,
|
||
}
|
||
|
||
impl<'a> ParseOptions<'a> {
|
||
@@ -209,9 +210,47 @@
|
||
self
|
||
}
|
||
|
||
- /// Call the provided function or closure on non-fatal parse errors.
|
||
+ /// Call the provided function or closure on non-fatal parse errors, passing
|
||
+ /// a static string description. This method is deprecated in favor of
|
||
+ /// `syntax_violation_callback` and is implemented as an adaptor for the
|
||
+ /// latter, passing the `SyntaxViolation` description. Only the last value
|
||
+ /// passed to either method will be used by a parser.
|
||
+ #[deprecated]
|
||
pub fn log_syntax_violation(mut self, new: Option<&'a Fn(&'static str)>) -> Self {
|
||
- self.log_syntax_violation = new;
|
||
+ self.violation_fn = match new {
|
||
+ Some(f) => ViolationFn::OldFn(f),
|
||
+ None => ViolationFn::NoOp
|
||
+ };
|
||
+ self
|
||
+ }
|
||
+
|
||
+ /// Call the provided function or closure for a non-fatal `SyntaxViolation`
|
||
+ /// when it occurs during parsing. Note that since the provided function is
|
||
+ /// `Fn`, the caller might need to utilize _interior mutability_, such as with
|
||
+ /// a `RefCell`, to collect the violations.
|
||
+ ///
|
||
+ /// ## Example
|
||
+ /// ```
|
||
+ /// use std::cell::RefCell;
|
||
+ /// use url::{Url, SyntaxViolation};
|
||
+ /// # use url::ParseError;
|
||
+ /// # fn run() -> Result<(), url::ParseError> {
|
||
+ /// let violations = RefCell::new(Vec::new());
|
||
+ /// let url = Url::options()
|
||
+ /// .syntax_violation_callback(Some(&|v| violations.borrow_mut().push(v)))
|
||
+ /// .parse("https:////example.com")?;
|
||
+ /// assert_eq!(url.as_str(), "https://example.com/");
|
||
+ /// assert_eq!(violations.into_inner(),
|
||
+ /// vec!(SyntaxViolation::ExpectedDoubleSlash));
|
||
+ /// # Ok(())
|
||
+ /// # }
|
||
+ /// # run().unwrap();
|
||
+ /// ```
|
||
+ pub fn syntax_violation_callback(mut self, new: Option<&'a Fn(SyntaxViolation)>) -> Self {
|
||
+ self.violation_fn = match new {
|
||
+ Some(f) => ViolationFn::NewFn(f),
|
||
+ None => ViolationFn::NoOp
|
||
+ };
|
||
self
|
||
}
|
||
|
||
@@ -221,7 +260,7 @@
|
||
serialization: String::with_capacity(input.len()),
|
||
base_url: self.base_url,
|
||
query_encoding_override: self.encoding_override,
|
||
- log_syntax_violation: self.log_syntax_violation,
|
||
+ violation_fn: self.violation_fn,
|
||
context: Context::UrlParser,
|
||
}.parse_url(input)
|
||
}
|
||
@@ -229,11 +268,12 @@
|
||
|
||
impl<'a> Debug for ParseOptions<'a> {
|
||
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
||
- write!(f, "ParseOptions {{ base_url: {:?}, encoding_override: {:?}, log_syntax_violation: ", self.base_url, self.encoding_override)?;
|
||
- match self.log_syntax_violation {
|
||
- Some(_) => write!(f, "Some(Fn(&'static str)) }}"),
|
||
- None => write!(f, "None }}")
|
||
- }
|
||
+ write!(f,
|
||
+ "ParseOptions {{ base_url: {:?}, encoding_override: {:?}, \
|
||
+ violation_fn: {:?} }}",
|
||
+ self.base_url,
|
||
+ self.encoding_override,
|
||
+ self.violation_fn)
|
||
}
|
||
}
|
||
|
||
@@ -252,6 +292,13 @@
|
||
/// # }
|
||
/// # run().unwrap();
|
||
/// ```
|
||
+ ///
|
||
+ /// # Errors
|
||
+ ///
|
||
+ /// If the function can not parse an absolute URL from the given string,
|
||
+ /// a [`ParseError`] variant will be returned.
|
||
+ ///
|
||
+ /// [`ParseError`]: enum.ParseError.html
|
||
#[inline]
|
||
pub fn parse(input: &str) -> Result<Url, ::ParseError> {
|
||
Url::options().parse(input)
|
||
@@ -274,6 +321,13 @@
|
||
/// # }
|
||
/// # run().unwrap();
|
||
/// ```
|
||
+ ///
|
||
+ /// # Errors
|
||
+ ///
|
||
+ /// If the function can not parse an absolute URL from the given string,
|
||
+ /// a [`ParseError`] variant will be returned.
|
||
+ ///
|
||
+ /// [`ParseError`]: enum.ParseError.html
|
||
#[inline]
|
||
pub fn parse_with_params<I, K, V>(input: &str, iter: I) -> Result<Url, ::ParseError>
|
||
where I: IntoIterator,
|
||
@@ -301,7 +355,7 @@
|
||
/// ```rust
|
||
/// use url::Url;
|
||
/// # use url::ParseError;
|
||
- ///
|
||
+ ///
|
||
/// # fn run() -> Result<(), ParseError> {
|
||
/// let base = Url::parse("https://example.net/a/b.html")?;
|
||
/// let url = base.join("c.png")?;
|
||
@@ -314,6 +368,13 @@
|
||
/// # }
|
||
/// # run().unwrap();
|
||
/// ```
|
||
+ ///
|
||
+ /// # Errors
|
||
+ ///
|
||
+ /// If the function can not parse an URL from the given string
|
||
+ /// with this URL as the base URL, a [`ParseError`] variant will be returned.
|
||
+ ///
|
||
+ /// [`ParseError`]: enum.ParseError.html
|
||
#[inline]
|
||
pub fn join(&self, input: &str) -> Result<Url, ::ParseError> {
|
||
Url::options().base_url(Some(self)).parse(input)
|
||
@@ -342,7 +403,7 @@
|
||
ParseOptions {
|
||
base_url: None,
|
||
encoding_override: EncodingOverride::utf8(),
|
||
- log_syntax_violation: None,
|
||
+ violation_fn: ViolationFn::NoOp,
|
||
}
|
||
}
|
||
|
||
@@ -500,7 +561,7 @@
|
||
Ok(())
|
||
}
|
||
|
||
- /// Return the origin of this URL (https://url.spec.whatwg.org/#origin)
|
||
+ /// Return the origin of this URL (<https://url.spec.whatwg.org/#origin>)
|
||
///
|
||
/// Note: this returns an opaque origin for `file:` URLs, which causes
|
||
/// `url.origin() != url.origin()`.
|
||
@@ -1156,11 +1217,11 @@
|
||
/// assert_eq!(url.as_str(), "https://example.com/data.csv");
|
||
|
||
/// url.set_fragment(Some("cell=4,1-6,2"));
|
||
- /// assert_eq!(url.as_str(), "https://example.com/data.csv#cell=4,1-6,2");
|
||
+ /// assert_eq!(url.as_str(), "https://example.com/data.csv#cell=4,1-6,2");
|
||
/// assert_eq!(url.fragment(), Some("cell=4,1-6,2"));
|
||
///
|
||
/// url.set_fragment(None);
|
||
- /// assert_eq!(url.as_str(), "https://example.com/data.csv");
|
||
+ /// assert_eq!(url.as_str(), "https://example.com/data.csv");
|
||
/// assert!(url.fragment().is_none());
|
||
/// # Ok(())
|
||
/// # }
|
||
@@ -1213,7 +1274,7 @@
|
||
/// assert_eq!(url.as_str(), "https://example.com/products");
|
||
///
|
||
/// url.set_query(Some("page=2"));
|
||
- /// assert_eq!(url.as_str(), "https://example.com/products?page=2");
|
||
+ /// assert_eq!(url.as_str(), "https://example.com/products?page=2");
|
||
/// assert_eq!(url.query(), Some("page=2"));
|
||
/// # Ok(())
|
||
/// # }
|
||
@@ -1283,7 +1344,7 @@
|
||
self.serialization.push('?');
|
||
}
|
||
|
||
- let query = UrlQuery { url: self, fragment: fragment };
|
||
+ let query = UrlQuery { url: Some(self), fragment: fragment };
|
||
form_urlencoded::Serializer::for_suffix(query, query_start + "?".len())
|
||
}
|
||
|
||
@@ -1309,12 +1370,12 @@
|
||
/// # fn run() -> Result<(), ParseError> {
|
||
/// let mut url = Url::parse("https://example.com")?;
|
||
/// url.set_path("api/comments");
|
||
- /// assert_eq!(url.as_str(), "https://example.com/api/comments");
|
||
+ /// assert_eq!(url.as_str(), "https://example.com/api/comments");
|
||
/// assert_eq!(url.path(), "/api/comments");
|
||
///
|
||
/// let mut url = Url::parse("https://example.com/api")?;
|
||
/// url.set_path("data/report.csv");
|
||
- /// assert_eq!(url.as_str(), "https://example.com/data/report.csv");
|
||
+ /// assert_eq!(url.as_str(), "https://example.com/data/report.csv");
|
||
/// assert_eq!(url.path(), "/data/report.csv");
|
||
/// # Ok(())
|
||
/// # }
|
||
@@ -1406,7 +1467,8 @@
|
||
/// # run().unwrap();
|
||
/// ```
|
||
pub fn set_port(&mut self, mut port: Option<u16>) -> Result<(), ()> {
|
||
- if !self.has_host() || self.scheme() == "file" {
|
||
+ // has_host implies !cannot_be_a_base
|
||
+ if !self.has_host() || self.host() == Some(Host::Domain("")) || self.scheme() == "file" {
|
||
return Err(())
|
||
}
|
||
if port.is_some() && port == parser::default_port(self.scheme()) {
|
||
@@ -1448,9 +1510,6 @@
|
||
|
||
/// Change this URL’s host.
|
||
///
|
||
- /// If this URL is cannot-be-a-base or there is an error parsing the given `host`,
|
||
- /// do nothing and return `Err`.
|
||
- ///
|
||
/// Removing the host (calling this with `None`)
|
||
/// will also remove any username, password, and port number.
|
||
///
|
||
@@ -1477,7 +1536,7 @@
|
||
/// ```
|
||
/// use url::Url;
|
||
/// # use url::ParseError;
|
||
- ///
|
||
+ ///
|
||
/// # fn run() -> Result<(), ParseError> {
|
||
/// let mut url = Url::parse("foo://example.net")?;
|
||
/// let result = url.set_host(None);
|
||
@@ -1493,7 +1552,7 @@
|
||
/// ```
|
||
/// use url::Url;
|
||
/// # use url::ParseError;
|
||
- ///
|
||
+ ///
|
||
/// # fn run() -> Result<(), ParseError> {
|
||
/// let mut url = Url::parse("https://example.net")?;
|
||
/// let result = url.set_host(None);
|
||
@@ -1509,7 +1568,7 @@
|
||
/// ```
|
||
/// use url::Url;
|
||
/// # use url::ParseError;
|
||
- ///
|
||
+ ///
|
||
/// # fn run() -> Result<(), ParseError> {
|
||
/// let mut url = Url::parse("mailto:rms@example.net")?;
|
||
///
|
||
@@ -1524,6 +1583,13 @@
|
||
/// # }
|
||
/// # run().unwrap();
|
||
/// ```
|
||
+ ///
|
||
+ /// # Errors
|
||
+ ///
|
||
+ /// If this URL is cannot-be-a-base or there is an error parsing the given `host`,
|
||
+ /// a [`ParseError`] variant will be returned.
|
||
+ ///
|
||
+ /// [`ParseError`]: enum.ParseError.html
|
||
pub fn set_host(&mut self, host: Option<&str>) -> Result<(), ParseError> {
|
||
if self.cannot_be_a_base() {
|
||
return Err(ParseError::SetHostOnCannotBeABaseUrl)
|
||
@@ -1533,7 +1599,11 @@
|
||
if host == "" && SchemeType::from(self.scheme()).is_special() {
|
||
return Err(ParseError::EmptyHost);
|
||
}
|
||
- self.set_host_internal(Host::parse(host)?, None)
|
||
+ if SchemeType::from(self.scheme()).is_special() {
|
||
+ self.set_host_internal(Host::parse(host)?, None)
|
||
+ } else {
|
||
+ self.set_host_internal(Host::parse_opaque(host)?, None)
|
||
+ }
|
||
} else if self.has_host() {
|
||
if SchemeType::from(self.scheme()).is_special() {
|
||
return Err(ParseError::EmptyHost)
|
||
@@ -1666,7 +1736,8 @@
|
||
/// # run().unwrap();
|
||
/// ```
|
||
pub fn set_password(&mut self, password: Option<&str>) -> Result<(), ()> {
|
||
- if !self.has_host() {
|
||
+ // has_host implies !cannot_be_a_base
|
||
+ if !self.has_host() || self.host() == Some(Host::Domain("")) || self.scheme() == "file" {
|
||
return Err(())
|
||
}
|
||
if let Some(password) = password {
|
||
@@ -1732,21 +1803,23 @@
|
||
/// ```
|
||
///
|
||
/// Setup username to user1
|
||
+ ///
|
||
/// ```rust
|
||
/// use url::{Url, ParseError};
|
||
///
|
||
/// # fn run() -> Result<(), ParseError> {
|
||
- /// let mut url = Url::parse("ftp://:secre1@example.com")?;
|
||
+ /// let mut url = Url::parse("ftp://:secre1@example.com/")?;
|
||
/// let result = url.set_username("user1");
|
||
/// assert!(result.is_ok());
|
||
/// assert_eq!(url.username(), "user1");
|
||
- /// assert_eq!(url.as_str(), "ftp://user1:secre1@example.com");
|
||
+ /// assert_eq!(url.as_str(), "ftp://user1:secre1@example.com/");
|
||
/// # Ok(())
|
||
/// # }
|
||
/// # run().unwrap();
|
||
/// ```
|
||
pub fn set_username(&mut self, username: &str) -> Result<(), ()> {
|
||
- if !self.has_host() {
|
||
+ // has_host implies !cannot_be_a_base
|
||
+ if !self.has_host() || self.host() == Some(Host::Domain("")) || self.scheme() == "file" {
|
||
return Err(())
|
||
}
|
||
let username_start = self.scheme_end + 3;
|
||
@@ -1805,7 +1878,7 @@
|
||
/// ```
|
||
/// use url::Url;
|
||
/// # use url::ParseError;
|
||
- ///
|
||
+ ///
|
||
/// # fn run() -> Result<(), ParseError> {
|
||
/// let mut url = Url::parse("https://example.net")?;
|
||
/// let result = url.set_scheme("foo");
|
||
@@ -1822,7 +1895,7 @@
|
||
/// ```
|
||
/// use url::Url;
|
||
/// # use url::ParseError;
|
||
- ///
|
||
+ ///
|
||
/// # fn run() -> Result<(), ParseError> {
|
||
/// let mut url = Url::parse("https://example.net")?;
|
||
/// let result = url.set_scheme("foõ");
|
||
@@ -1838,7 +1911,7 @@
|
||
/// ```
|
||
/// use url::Url;
|
||
/// # use url::ParseError;
|
||
- ///
|
||
+ ///
|
||
/// # fn run() -> Result<(), ParseError> {
|
||
/// let mut url = Url::parse("mailto:rms@example.net")?;
|
||
/// let result = url.set_scheme("https");
|
||
@@ -1887,7 +1960,7 @@
|
||
/// ```
|
||
/// # if cfg!(unix) {
|
||
/// use url::Url;
|
||
- ///
|
||
+ ///
|
||
/// # fn run() -> Result<(), ()> {
|
||
/// let url = Url::from_file_path("/tmp/foo.txt")?;
|
||
/// assert_eq!(url.as_str(), "file:///tmp/foo.txt");
|
||
@@ -1902,6 +1975,7 @@
|
||
/// # run().unwrap();
|
||
/// # }
|
||
/// ```
|
||
+ #[cfg(any(unix, windows, target_os="redox"))]
|
||
pub fn from_file_path<P: AsRef<Path>>(path: P) -> Result<Url, ()> {
|
||
let mut serialization = "file://".to_owned();
|
||
let host_start = serialization.len() as u32;
|
||
@@ -1937,6 +2011,7 @@
|
||
///
|
||
/// Note that `std::path` does not consider trailing slashes significant
|
||
/// and usually does not include them (e.g. in `Path::parent()`).
|
||
+ #[cfg(any(unix, windows, target_os="redox"))]
|
||
pub fn from_directory_path<P: AsRef<Path>>(path: P) -> Result<Url, ()> {
|
||
let mut url = Url::from_file_path(path)?;
|
||
if !url.serialization.ends_with('/') {
|
||
@@ -2018,6 +2093,7 @@
|
||
/// (That is, if the percent-decoded path contains a NUL byte or,
|
||
/// for a Windows path, is not UTF-8.)
|
||
#[inline]
|
||
+ #[cfg(any(unix, windows, target_os="redox"))]
|
||
pub fn to_file_path(&self) -> Result<PathBuf, ()> {
|
||
if let Some(segments) = self.path_segments() {
|
||
let host = match self.host() {
|
||
@@ -2264,6 +2340,7 @@
|
||
Ok((host_end, host_internal))
|
||
}
|
||
|
||
+
|
||
#[cfg(any(unix, target_os = "redox"))]
|
||
fn file_url_segments_to_pathbuf(host: Option<&str>, segments: str::Split<char>) -> Result<PathBuf, ()> {
|
||
use std::ffi::OsStr;
|
||
@@ -2347,13 +2424,15 @@
|
||
/// Implementation detail of `Url::query_pairs_mut`. Typically not used directly.
|
||
#[derive(Debug)]
|
||
pub struct UrlQuery<'a> {
|
||
- url: &'a mut Url,
|
||
+ url: Option<&'a mut Url>,
|
||
fragment: Option<String>,
|
||
}
|
||
|
||
impl<'a> Drop for UrlQuery<'a> {
|
||
fn drop(&mut self) {
|
||
- self.url.restore_already_parsed_fragment(self.fragment.take())
|
||
+ if let Some(url) = self.url.take() {
|
||
+ url.restore_already_parsed_fragment(self.fragment.take())
|
||
+ }
|
||
}
|
||
}
|
||
|
||
diff -u -r --new-file seamonkey-2.53.1.orig/mozilla/third_party/rust/url/src/origin.rs seamonkey-2.53.1/mozilla/third_party/rust/url/src/origin.rs
|
||
--- seamonkey-2.53.1.orig/mozilla/third_party/rust/url/src/origin.rs 2020-02-17 17:39:21.000000000 -0600
|
||
+++ seamonkey-2.53.1/mozilla/third_party/rust/url/src/origin.rs 2020-02-29 21:14:51.284768322 -0600
|
||
@@ -49,7 +49,7 @@
|
||
/// - If the scheme is anything else, the origin is opaque, meaning
|
||
/// the URL does not have the same origin as any other URL.
|
||
///
|
||
-/// For more information see https://url.spec.whatwg.org/#origin
|
||
+/// For more information see <https://url.spec.whatwg.org/#origin>
|
||
#[derive(PartialEq, Eq, Hash, Clone, Debug)]
|
||
pub enum Origin {
|
||
/// A globally unique identifier
|
||
@@ -86,7 +86,7 @@
|
||
matches!(*self, Origin::Tuple(..))
|
||
}
|
||
|
||
- /// https://html.spec.whatwg.org/multipage/#ascii-serialisation-of-an-origin
|
||
+ /// <https://html.spec.whatwg.org/multipage/#ascii-serialisation-of-an-origin>
|
||
pub fn ascii_serialization(&self) -> String {
|
||
match *self {
|
||
Origin::Opaque(_) => "null".to_owned(),
|
||
@@ -100,7 +100,7 @@
|
||
}
|
||
}
|
||
|
||
- /// https://html.spec.whatwg.org/multipage/#unicode-serialisation-of-an-origin
|
||
+ /// <https://html.spec.whatwg.org/multipage/#unicode-serialisation-of-an-origin>
|
||
pub fn unicode_serialization(&self) -> String {
|
||
match *self {
|
||
Origin::Opaque(_) => "null".to_owned(),
|
||
diff -u -r --new-file seamonkey-2.53.1.orig/mozilla/third_party/rust/url/src/parser.rs seamonkey-2.53.1/mozilla/third_party/rust/url/src/parser.rs
|
||
--- seamonkey-2.53.1.orig/mozilla/third_party/rust/url/src/parser.rs 2020-02-17 17:39:21.000000000 -0600
|
||
+++ seamonkey-2.53.1/mozilla/third_party/rust/url/src/parser.rs 2020-02-29 21:15:43.806770565 -0600
|
||
@@ -6,7 +6,9 @@
|
||
// option. This file may not be copied, modified, or distributed
|
||
// except according to those terms.
|
||
|
||
+#[allow(unused_imports, deprecated)]
|
||
use std::ascii::AsciiExt;
|
||
+
|
||
use std::error::Error;
|
||
use std::fmt::{self, Formatter, Write};
|
||
use std::str;
|
||
@@ -20,6 +22,12 @@
|
||
PATH_SEGMENT_ENCODE_SET
|
||
};
|
||
|
||
+define_encode_set! {
|
||
+ // The backslash (\) character is treated as a path separator in special URLs
|
||
+ // so it needs to be additionally escaped in that case.
|
||
+ pub SPECIAL_PATH_SEGMENT_ENCODE_SET = [PATH_SEGMENT_ENCODE_SET] | {'\\'}
|
||
+}
|
||
+
|
||
pub type ParseResult<T> = Result<T, ParseError>;
|
||
|
||
macro_rules! simple_enum_error {
|
||
@@ -70,6 +78,54 @@
|
||
fn from(_: ::idna::uts46::Errors) -> ParseError { ParseError::IdnaError }
|
||
}
|
||
|
||
+macro_rules! syntax_violation_enum {
|
||
+ ($($name: ident => $description: expr,)+) => {
|
||
+ /// Non-fatal syntax violations that can occur during parsing.
|
||
+ #[derive(PartialEq, Eq, Clone, Copy, Debug)]
|
||
+ pub enum SyntaxViolation {
|
||
+ $(
|
||
+ $name,
|
||
+ )+
|
||
+ }
|
||
+
|
||
+ impl SyntaxViolation {
|
||
+ pub fn description(&self) -> &'static str {
|
||
+ match *self {
|
||
+ $(
|
||
+ SyntaxViolation::$name => $description,
|
||
+ )+
|
||
+ }
|
||
+ }
|
||
+ }
|
||
+ }
|
||
+}
|
||
+
|
||
+syntax_violation_enum! {
|
||
+ Backslash => "backslash",
|
||
+ C0SpaceIgnored =>
|
||
+ "leading or trailing control or space character are ignored in URLs",
|
||
+ EmbeddedCredentials =>
|
||
+ "embedding authentication information (username or password) \
|
||
+ in an URL is not recommended",
|
||
+ ExpectedDoubleSlash => "expected //",
|
||
+ ExpectedFileDoubleSlash => "expected // after file:",
|
||
+ FileWithHostAndWindowsDrive => "file: with host and Windows drive letter",
|
||
+ NonUrlCodePoint => "non-URL code point",
|
||
+ NullInFragment => "NULL characters are ignored in URL fragment identifiers",
|
||
+ PercentDecode => "expected 2 hex digits after %",
|
||
+ TabOrNewlineIgnored => "tabs or newlines are ignored in URLs",
|
||
+ UnencodedAtSign => "unencoded @ sign in username or password",
|
||
+}
|
||
+
|
||
+#[cfg(feature = "heapsize")]
|
||
+known_heap_size!(0, SyntaxViolation);
|
||
+
|
||
+impl fmt::Display for SyntaxViolation {
|
||
+ fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
|
||
+ self.description().fmt(fmt)
|
||
+ }
|
||
+}
|
||
+
|
||
#[derive(Copy, Clone)]
|
||
pub enum SchemeType {
|
||
File,
|
||
@@ -112,18 +168,17 @@
|
||
|
||
impl<'i> Input<'i> {
|
||
pub fn new(input: &'i str) -> Self {
|
||
- Input::with_log(input, None)
|
||
+ Input::with_log(input, ViolationFn::NoOp)
|
||
}
|
||
|
||
- pub fn with_log(original_input: &'i str, log_syntax_violation: Option<&Fn(&'static str)>)
|
||
- -> Self {
|
||
+ pub fn with_log(original_input: &'i str, vfn: ViolationFn) -> Self {
|
||
let input = original_input.trim_matches(c0_control_or_space);
|
||
- if let Some(log) = log_syntax_violation {
|
||
+ if vfn.is_set() {
|
||
if input.len() < original_input.len() {
|
||
- log("leading or trailing control or space character are ignored in URLs")
|
||
+ vfn.call(SyntaxViolation::C0SpaceIgnored)
|
||
}
|
||
if input.chars().any(|c| matches!(c, '\t' | '\n' | '\r')) {
|
||
- log("tabs or newlines are ignored in URLs")
|
||
+ vfn.call(SyntaxViolation::TabOrNewlineIgnored)
|
||
}
|
||
}
|
||
Input { chars: input.chars() }
|
||
@@ -216,11 +271,60 @@
|
||
}
|
||
}
|
||
|
||
+/// Wrapper for syntax violation callback functions.
|
||
+#[derive(Copy, Clone)]
|
||
+pub enum ViolationFn<'a> {
|
||
+ NewFn(&'a (Fn(SyntaxViolation) + 'a)),
|
||
+ OldFn(&'a (Fn(&'static str) + 'a)),
|
||
+ NoOp
|
||
+}
|
||
+
|
||
+impl<'a> ViolationFn<'a> {
|
||
+ /// Call with a violation.
|
||
+ pub fn call(self, v: SyntaxViolation) {
|
||
+ match self {
|
||
+ ViolationFn::NewFn(f) => f(v),
|
||
+ ViolationFn::OldFn(f) => f(v.description()),
|
||
+ ViolationFn::NoOp => {}
|
||
+ }
|
||
+ }
|
||
+
|
||
+ /// Call with a violation, if provided test returns true. Avoids
|
||
+ /// the test entirely if `NoOp`.
|
||
+ pub fn call_if<F>(self, v: SyntaxViolation, test: F)
|
||
+ where F: Fn() -> bool
|
||
+ {
|
||
+ match self {
|
||
+ ViolationFn::NewFn(f) => if test() { f(v) },
|
||
+ ViolationFn::OldFn(f) => if test() { f(v.description()) },
|
||
+ ViolationFn::NoOp => {} // avoid test
|
||
+ }
|
||
+ }
|
||
+
|
||
+ /// True if not `NoOp`
|
||
+ pub fn is_set(self) -> bool {
|
||
+ match self {
|
||
+ ViolationFn::NoOp => false,
|
||
+ _ => true
|
||
+ }
|
||
+ }
|
||
+}
|
||
+
|
||
+impl<'a> fmt::Debug for ViolationFn<'a> {
|
||
+ fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
||
+ match *self {
|
||
+ ViolationFn::NewFn(_) => write!(f, "NewFn(Fn(SyntaxViolation))"),
|
||
+ ViolationFn::OldFn(_) => write!(f, "OldFn(Fn(&'static str))"),
|
||
+ ViolationFn::NoOp => write!(f, "NoOp")
|
||
+ }
|
||
+ }
|
||
+}
|
||
+
|
||
pub struct Parser<'a> {
|
||
pub serialization: String,
|
||
pub base_url: Option<&'a Url>,
|
||
pub query_encoding_override: EncodingOverride,
|
||
- pub log_syntax_violation: Option<&'a Fn(&'static str)>,
|
||
+ pub violation_fn: ViolationFn<'a>,
|
||
pub context: Context,
|
||
}
|
||
|
||
@@ -237,29 +341,14 @@
|
||
serialization: serialization,
|
||
base_url: None,
|
||
query_encoding_override: EncodingOverride::utf8(),
|
||
- log_syntax_violation: None,
|
||
+ violation_fn: ViolationFn::NoOp,
|
||
context: Context::Setter,
|
||
}
|
||
}
|
||
|
||
- fn syntax_violation(&self, reason: &'static str) {
|
||
- if let Some(log) = self.log_syntax_violation {
|
||
- log(reason)
|
||
- }
|
||
- }
|
||
-
|
||
- fn syntax_violation_if<F: Fn() -> bool>(&self, reason: &'static str, test: F) {
|
||
- // Skip test if not logging.
|
||
- if let Some(log) = self.log_syntax_violation {
|
||
- if test() {
|
||
- log(reason)
|
||
- }
|
||
- }
|
||
- }
|
||
-
|
||
/// 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.log_syntax_violation);
|
||
+ let input = Input::with_log(input, self.violation_fn);
|
||
if let Ok(remaining) = self.parse_scheme(input.clone()) {
|
||
return self.parse_with_scheme(remaining)
|
||
}
|
||
@@ -310,12 +399,13 @@
|
||
}
|
||
|
||
fn parse_with_scheme(mut self, input: Input) -> ParseResult<Url> {
|
||
+ use SyntaxViolation::{ExpectedFileDoubleSlash, ExpectedDoubleSlash};
|
||
let scheme_end = to_u32(self.serialization.len())?;
|
||
let scheme_type = SchemeType::from(&self.serialization);
|
||
self.serialization.push(':');
|
||
match scheme_type {
|
||
SchemeType::File => {
|
||
- self.syntax_violation_if("expected // after file:", || !input.starts_with("//"));
|
||
+ self.violation_fn.call_if(ExpectedFileDoubleSlash, || !input.starts_with("//"));
|
||
let base_file_url = self.base_url.and_then(|base| {
|
||
if base.scheme() == "file" { Some(base) } else { None }
|
||
});
|
||
@@ -335,7 +425,7 @@
|
||
}
|
||
}
|
||
// special authority slashes state
|
||
- self.syntax_violation_if("expected //", || {
|
||
+ self.violation_fn.call_if(ExpectedDoubleSlash, || {
|
||
input.clone().take_while(|&c| matches!(c, '/' | '\\'))
|
||
.collect::<String>() != "//"
|
||
});
|
||
@@ -371,6 +461,7 @@
|
||
}
|
||
|
||
fn parse_file(mut self, input: Input, mut base_file_url: Option<&Url>) -> ParseResult<Url> {
|
||
+ use SyntaxViolation::Backslash;
|
||
// file state
|
||
debug_assert!(self.serialization.is_empty());
|
||
let (first_char, input_after_first_char) = input.split_first();
|
||
@@ -451,6 +542,7 @@
|
||
let scheme_end = "file".len() as u32;
|
||
let path_start = "file://".len() as u32;
|
||
let fragment_start = "file:///".len() as u32;
|
||
+ self.serialization.push('#');
|
||
self.parse_fragment(input_after_first_char);
|
||
Ok(Url {
|
||
serialization: self.serialization,
|
||
@@ -467,18 +559,18 @@
|
||
}
|
||
}
|
||
Some('/') | Some('\\') => {
|
||
- self.syntax_violation_if("backslash", || first_char == Some('\\'));
|
||
+ self.violation_fn.call_if(Backslash, || first_char == Some('\\'));
|
||
// file slash state
|
||
let (next_char, input_after_next_char) = input_after_first_char.split_first();
|
||
- self.syntax_violation_if("backslash", || next_char == Some('\\'));
|
||
+ self.violation_fn.call_if(Backslash, || next_char == Some('\\'));
|
||
if matches!(next_char, Some('/') | Some('\\')) {
|
||
// file host state
|
||
self.serialization.push_str("file://");
|
||
let scheme_end = "file".len() as u32;
|
||
let host_start = "file://".len() as u32;
|
||
- let (path_start, host, remaining) =
|
||
+ let (path_start, mut host, remaining) =
|
||
self.parse_file_host(input_after_next_char)?;
|
||
- let host_end = to_u32(self.serialization.len())?;
|
||
+ let mut host_end = to_u32(self.serialization.len())?;
|
||
let mut has_host = !matches!(host, HostInternal::None);
|
||
let remaining = if path_start {
|
||
self.parse_path_start(SchemeType::File, &mut has_host, remaining)
|
||
@@ -487,7 +579,13 @@
|
||
self.serialization.push('/');
|
||
self.parse_path(SchemeType::File, &mut has_host, path_start, remaining)
|
||
};
|
||
- // FIXME: deal with has_host
|
||
+ // For file URLs that have a host and whose path starts
|
||
+ // with the windows drive letter we just remove the host.
|
||
+ if !has_host {
|
||
+ self.serialization.drain(host_start as usize..host_end as usize);
|
||
+ host_end = host_start;
|
||
+ host = HostInternal::None;
|
||
+ }
|
||
let (query_start, fragment_start) =
|
||
self.parse_query_and_fragment(scheme_end, remaining)?;
|
||
Ok(Url {
|
||
@@ -616,7 +714,7 @@
|
||
Some('/') | Some('\\') => {
|
||
let (slashes_count, remaining) = input.count_matching(|c| matches!(c, '/' | '\\'));
|
||
if slashes_count >= 2 {
|
||
- self.syntax_violation_if("expected //", || {
|
||
+ self.violation_fn.call_if(SyntaxViolation::ExpectedDoubleSlash, || {
|
||
input.clone().take_while(|&c| matches!(c, '/' | '\\'))
|
||
.collect::<String>() != "//"
|
||
});
|
||
@@ -680,11 +778,9 @@
|
||
match c {
|
||
'@' => {
|
||
if last_at.is_some() {
|
||
- self.syntax_violation("unencoded @ sign in username or password")
|
||
+ self.violation_fn.call(SyntaxViolation::UnencodedAtSign)
|
||
} else {
|
||
- self.syntax_violation(
|
||
- "embedding authentification information (username or password) \
|
||
- in an URL is not recommended")
|
||
+ self.violation_fn.call(SyntaxViolation::EmbeddedCredentials)
|
||
}
|
||
last_at = Some((char_count, remaining.clone()))
|
||
},
|
||
@@ -701,14 +797,23 @@
|
||
};
|
||
|
||
let mut username_end = None;
|
||
+ let mut has_password = false;
|
||
+ let mut has_username = false;
|
||
while userinfo_char_count > 0 {
|
||
let (c, utf8_c) = input.next_utf8().unwrap();
|
||
userinfo_char_count -= 1;
|
||
if c == ':' && username_end.is_none() {
|
||
// Start parsing password
|
||
username_end = Some(to_u32(self.serialization.len())?);
|
||
- self.serialization.push(':');
|
||
+ // We don't add a colon if the password is empty
|
||
+ if userinfo_char_count > 0 {
|
||
+ self.serialization.push(':');
|
||
+ has_password = true;
|
||
+ }
|
||
} else {
|
||
+ if !has_password {
|
||
+ has_username = true;
|
||
+ }
|
||
self.check_url_code_point(c, &input);
|
||
self.serialization.extend(utf8_percent_encode(utf8_c, USERINFO_ENCODE_SET));
|
||
}
|
||
@@ -717,7 +822,9 @@
|
||
Some(i) => i,
|
||
None => to_u32(self.serialization.len())?,
|
||
};
|
||
- self.serialization.push('@');
|
||
+ if has_username || has_password {
|
||
+ self.serialization.push('@');
|
||
+ }
|
||
Ok((username_end, remaining))
|
||
}
|
||
|
||
@@ -783,6 +890,10 @@
|
||
if scheme_type.is_special() && host_str.is_empty() {
|
||
return Err(ParseError::EmptyHost)
|
||
}
|
||
+ if !scheme_type.is_special() {
|
||
+ let host = Host::parse_opaque(host_str)?;
|
||
+ return Ok((host, input));
|
||
+ }
|
||
let host = Host::parse(host_str)?;
|
||
Ok((host, input))
|
||
}
|
||
@@ -867,7 +978,7 @@
|
||
match input.split_first() {
|
||
(Some('/'), remaining) => input = remaining,
|
||
(Some('\\'), remaining) => if scheme_type.is_special() {
|
||
- self.syntax_violation("backslash");
|
||
+ self.violation_fn.call(SyntaxViolation::Backslash);
|
||
input = remaining
|
||
},
|
||
_ => {}
|
||
@@ -895,7 +1006,7 @@
|
||
},
|
||
'\\' if self.context != Context::PathSegmentSetter &&
|
||
scheme_type.is_special() => {
|
||
- self.syntax_violation("backslash");
|
||
+ self.violation_fn.call(SyntaxViolation::Backslash);
|
||
ends_with_slash = true;
|
||
break
|
||
},
|
||
@@ -905,18 +1016,14 @@
|
||
},
|
||
_ => {
|
||
self.check_url_code_point(c, &input);
|
||
- if c == '%' {
|
||
- let after_percent_sign = input.clone();
|
||
- if matches!(input.next(), Some('2')) &&
|
||
- matches!(input.next(), Some('E') | Some('e')) {
|
||
- self.serialization.push('.');
|
||
- continue
|
||
- }
|
||
- input = after_percent_sign
|
||
- }
|
||
if self.context == Context::PathSegmentSetter {
|
||
- self.serialization.extend(utf8_percent_encode(
|
||
- utf8_c, PATH_SEGMENT_ENCODE_SET));
|
||
+ if scheme_type.is_special() {
|
||
+ self.serialization.extend(utf8_percent_encode(
|
||
+ utf8_c, SPECIAL_PATH_SEGMENT_ENCODE_SET));
|
||
+ } else {
|
||
+ self.serialization.extend(utf8_percent_encode(
|
||
+ utf8_c, PATH_SEGMENT_ENCODE_SET));
|
||
+ }
|
||
} else {
|
||
self.serialization.extend(utf8_percent_encode(
|
||
utf8_c, DEFAULT_ENCODE_SET));
|
||
@@ -925,7 +1032,7 @@
|
||
}
|
||
}
|
||
match &self.serialization[segment_start..] {
|
||
- ".." => {
|
||
+ ".." | "%2e%2e" | "%2e%2E" | "%2E%2e" | "%2E%2E" | "%2e." | "%2E." | ".%2e" | ".%2E" => {
|
||
debug_assert!(self.serialization.as_bytes()[segment_start - 1] == b'/');
|
||
self.serialization.truncate(segment_start - 1); // Truncate "/.."
|
||
self.pop_path(scheme_type, path_start);
|
||
@@ -933,7 +1040,7 @@
|
||
self.serialization.push('/')
|
||
}
|
||
},
|
||
- "." => {
|
||
+ "." | "%2e" | "%2E" => {
|
||
self.serialization.truncate(segment_start);
|
||
},
|
||
_ => {
|
||
@@ -945,7 +1052,7 @@
|
||
self.serialization.push(':');
|
||
}
|
||
if *has_host {
|
||
- self.syntax_violation("file: with host and Windows drive letter");
|
||
+ self.violation_fn.call(SyntaxViolation::FileWithHostAndWindowsDrive);
|
||
*has_host = false; // FIXME account for this in callers
|
||
}
|
||
}
|
||
@@ -1087,7 +1194,7 @@
|
||
pub fn parse_fragment(&mut self, mut input: Input) {
|
||
while let Some((c, utf8_c)) = input.next_utf8() {
|
||
if c == '\0' {
|
||
- self.syntax_violation("NULL characters are ignored in URL fragment identifiers")
|
||
+ self.violation_fn.call(SyntaxViolation::NullInFragment)
|
||
} else {
|
||
self.check_url_code_point(c, &input);
|
||
self.serialization.extend(utf8_percent_encode(utf8_c,
|
||
@@ -1097,15 +1204,16 @@
|
||
}
|
||
|
||
fn check_url_code_point(&self, c: char, input: &Input) {
|
||
- if let Some(log) = self.log_syntax_violation {
|
||
+ let vfn = self.violation_fn;
|
||
+ if vfn.is_set() {
|
||
if c == '%' {
|
||
let mut input = input.clone();
|
||
if !matches!((input.next(), input.next()), (Some(a), Some(b))
|
||
if is_ascii_hex_digit(a) && is_ascii_hex_digit(b)) {
|
||
- log("expected 2 hex digits after %")
|
||
+ vfn.call(SyntaxViolation::PercentDecode)
|
||
}
|
||
} else if !is_url_code_point(c) {
|
||
- log("non-URL code point")
|
||
+ vfn.call(SyntaxViolation::NonUrlCodePoint)
|
||
}
|
||
}
|
||
}
|
||
diff -u -r --new-file seamonkey-2.53.1.orig/mozilla/third_party/rust/url/src/quirks.rs seamonkey-2.53.1/mozilla/third_party/rust/url/src/quirks.rs
|
||
--- seamonkey-2.53.1.orig/mozilla/third_party/rust/url/src/quirks.rs 2020-02-17 17:39:21.000000000 -0600
|
||
+++ seamonkey-2.53.1/mozilla/third_party/rust/url/src/quirks.rs 2020-02-29 21:15:07.670769022 -0600
|
||
@@ -46,7 +46,7 @@
|
||
|
||
/// Getter for https://url.spec.whatwg.org/#dom-url-origin
|
||
pub fn origin(url: &Url) -> String {
|
||
- url.origin().unicode_serialization()
|
||
+ url.origin().ascii_serialization()
|
||
}
|
||
|
||
/// Getter for https://url.spec.whatwg.org/#dom-url-protocol
|
||
@@ -152,7 +152,7 @@
|
||
{
|
||
// has_host implies !cannot_be_a_base
|
||
let scheme = url.scheme();
|
||
- if !url.has_host() || scheme == "file" {
|
||
+ if !url.has_host() || url.host() == Some(Host::Domain("")) || scheme == "file" {
|
||
return Err(())
|
||
}
|
||
result = Parser::parse_port(Input::new(new_port), || default_port(scheme), Context::Setter)
|
||
diff -u -r --new-file seamonkey-2.53.1.orig/mozilla/third_party/rust/url/tests/data.rs seamonkey-2.53.1/mozilla/third_party/rust/url/tests/data.rs
|
||
--- seamonkey-2.53.1.orig/mozilla/third_party/rust/url/tests/data.rs 2020-02-17 17:39:21.000000000 -0600
|
||
+++ seamonkey-2.53.1/mozilla/third_party/rust/url/tests/data.rs 2020-02-29 21:15:43.807770565 -0600
|
||
@@ -9,7 +9,7 @@
|
||
//! Data-driven tests
|
||
|
||
extern crate rustc_serialize;
|
||
-extern crate test;
|
||
+extern crate rustc_test as test;
|
||
extern crate url;
|
||
|
||
use rustc_serialize::json::{self, Json};
|
||
@@ -29,6 +29,7 @@
|
||
fn run_parsing(input: &str, base: &str, expected: Result<ExpectedAttributes, ()>) {
|
||
let base = match Url::parse(&base) {
|
||
Ok(base) => base,
|
||
+ Err(_) if expected.is_err() => return,
|
||
Err(message) => panic!("Error parsing base {:?}: {}", base, message)
|
||
};
|
||
let (url, expected) = match (base.join(&input), expected) {
|
||
@@ -188,11 +189,7 @@
|
||
{
|
||
let mut add_one = |name: String, run: test::TestFn| {
|
||
tests.push(test::TestDescAndFn {
|
||
- desc: test::TestDesc {
|
||
- name: test::DynTestName(name),
|
||
- ignore: false,
|
||
- should_panic: test::ShouldPanic::No,
|
||
- },
|
||
+ desc: test::TestDesc::new(test::DynTestName(name)),
|
||
testfn: run,
|
||
})
|
||
};
|
||
diff -u -r --new-file seamonkey-2.53.1.orig/mozilla/third_party/rust/url/tests/setters_tests.json seamonkey-2.53.1/mozilla/third_party/rust/url/tests/setters_tests.json
|
||
--- seamonkey-2.53.1.orig/mozilla/third_party/rust/url/tests/setters_tests.json 2020-02-17 17:39:21.000000000 -0600
|
||
+++ seamonkey-2.53.1/mozilla/third_party/rust/url/tests/setters_tests.json 2020-02-29 21:15:07.674769022 -0600
|
||
@@ -102,6 +102,31 @@
|
||
}
|
||
},
|
||
{
|
||
+ "comment": "Can’t switch from file URL with no host",
|
||
+ "href": "file://localhost/",
|
||
+ "new_value": "http",
|
||
+ "expected": {
|
||
+ "href": "file:///",
|
||
+ "protocol": "file:"
|
||
+ }
|
||
+ },
|
||
+ {
|
||
+ "href": "file:///test",
|
||
+ "new_value": "gopher",
|
||
+ "expected": {
|
||
+ "href": "file:///test",
|
||
+ "protocol": "file:"
|
||
+ }
|
||
+ },
|
||
+ {
|
||
+ "href": "file:",
|
||
+ "new_value": "wss",
|
||
+ "expected": {
|
||
+ "href": "file:///",
|
||
+ "protocol": "file:"
|
||
+ }
|
||
+ },
|
||
+ {
|
||
"comment": "Spec deviation: from special scheme to not is not problematic. https://github.com/whatwg/url/issues/104",
|
||
"href": "http://example.net",
|
||
"new_value": "b",
|
||
@@ -176,6 +201,14 @@
|
||
}
|
||
},
|
||
{
|
||
+ "href": "javascript:alert(1)",
|
||
+ "new_value": "wario",
|
||
+ "expected": {
|
||
+ "href": "javascript:alert(1)",
|
||
+ "username": ""
|
||
+ }
|
||
+ },
|
||
+ {
|
||
"href": "http://example.net",
|
||
"new_value": "me",
|
||
"expected": {
|
||
@@ -224,6 +257,30 @@
|
||
"href": "http://%c3%89t%C3%A9@example.net/",
|
||
"username": "%c3%89t%C3%A9"
|
||
}
|
||
+ },
|
||
+ {
|
||
+ "href": "sc:///",
|
||
+ "new_value": "x",
|
||
+ "expected": {
|
||
+ "href": "sc:///",
|
||
+ "username": ""
|
||
+ }
|
||
+ },
|
||
+ {
|
||
+ "href": "file://test/",
|
||
+ "new_value": "test",
|
||
+ "expected": {
|
||
+ "href": "file://test/",
|
||
+ "username": ""
|
||
+ }
|
||
+ },
|
||
+ {
|
||
+ "href": "javascript://x/",
|
||
+ "new_value": "wario",
|
||
+ "expected": {
|
||
+ "href": "javascript://wario@x/",
|
||
+ "username": "wario"
|
||
+ }
|
||
}
|
||
],
|
||
"password": [
|
||
@@ -303,10 +360,106 @@
|
||
"href": "http://:%c3%89t%C3%A9@example.net/",
|
||
"password": "%c3%89t%C3%A9"
|
||
}
|
||
+ },
|
||
+ {
|
||
+ "href": "sc:///",
|
||
+ "new_value": "x",
|
||
+ "expected": {
|
||
+ "href": "sc:///",
|
||
+ "password": ""
|
||
+ }
|
||
+ },
|
||
+ {
|
||
+ "href": "file://test/",
|
||
+ "new_value": "test",
|
||
+ "expected": {
|
||
+ "href": "file://test/",
|
||
+ "password": ""
|
||
+ }
|
||
+ },
|
||
+ {
|
||
+ "href": "javascript://x/",
|
||
+ "new_value": "bowser",
|
||
+ "expected": {
|
||
+ "href": "javascript://:bowser@x/",
|
||
+ "password": "bowser"
|
||
+ }
|
||
}
|
||
],
|
||
"host": [
|
||
{
|
||
+ "href": "sc://x/",
|
||
+ "new_value": "\u0009",
|
||
+ "expected": {
|
||
+ "href": "sc:///",
|
||
+ "host": "",
|
||
+ "hostname": ""
|
||
+ }
|
||
+ },
|
||
+ {
|
||
+ "href": "sc://x/",
|
||
+ "new_value": "\u000A",
|
||
+ "expected": {
|
||
+ "href": "sc:///",
|
||
+ "host": "",
|
||
+ "hostname": ""
|
||
+ }
|
||
+ },
|
||
+ {
|
||
+ "href": "sc://x/",
|
||
+ "new_value": "\u000D",
|
||
+ "expected": {
|
||
+ "href": "sc:///",
|
||
+ "host": "",
|
||
+ "hostname": ""
|
||
+ }
|
||
+ },
|
||
+ {
|
||
+ "href": "sc://x/",
|
||
+ "new_value": "#",
|
||
+ "expected": {
|
||
+ "href": "sc:///",
|
||
+ "host": "",
|
||
+ "hostname": ""
|
||
+ }
|
||
+ },
|
||
+ {
|
||
+ "href": "sc://x/",
|
||
+ "new_value": "/",
|
||
+ "expected": {
|
||
+ "href": "sc:///",
|
||
+ "host": "",
|
||
+ "hostname": ""
|
||
+ }
|
||
+ },
|
||
+ {
|
||
+ "href": "sc://x/",
|
||
+ "new_value": "?",
|
||
+ "expected": {
|
||
+ "href": "sc:///",
|
||
+ "host": "",
|
||
+ "hostname": ""
|
||
+ }
|
||
+ },
|
||
+ {
|
||
+ "href": "sc://x/",
|
||
+ "new_value": "@",
|
||
+ "expected": {
|
||
+ "href": "sc://x/",
|
||
+ "host": "x",
|
||
+ "hostname": "x"
|
||
+ }
|
||
+ },
|
||
+ {
|
||
+ "href": "sc://x/",
|
||
+ "new_value": "ß",
|
||
+ "expected": {
|
||
+ "href": "sc://%C3%9F/",
|
||
+ "host": "%C3%9F",
|
||
+ "hostname": "%C3%9F"
|
||
+ }
|
||
+ },
|
||
+ {
|
||
"comment": "Cannot-be-a-base means no host",
|
||
"href": "mailto:me@example.net",
|
||
"new_value": "example.com",
|
||
@@ -384,15 +537,6 @@
|
||
}
|
||
},
|
||
{
|
||
- "comment": "Path-only URLs can gain a host",
|
||
- "href": "a:/foo",
|
||
- "new_value": "example.net",
|
||
- "expected": {
|
||
- "href": "a://example.net/foo",
|
||
- "host": "example.net"
|
||
- }
|
||
- },
|
||
- {
|
||
"comment": "IPv4 address syntax is normalized",
|
||
"href": "http://example.net",
|
||
"new_value": "0x7F000001:8080",
|
||
@@ -536,7 +680,7 @@
|
||
}
|
||
},
|
||
{
|
||
- "comment": "\\ is not a delimiter for non-special schemes, and it’s invalid in a domain",
|
||
+ "comment": "\\ is not a delimiter for non-special schemes, but still forbidden in hosts",
|
||
"href": "view-source+http://example.net/path",
|
||
"new_value": "example.com\\stuff",
|
||
"expected": {
|
||
@@ -600,10 +744,119 @@
|
||
"hostname": "example.com",
|
||
"port": ""
|
||
}
|
||
+ },
|
||
+ {
|
||
+ "comment": "Broken IPv6",
|
||
+ "href": "http://example.net/",
|
||
+ "new_value": "[google.com]",
|
||
+ "expected": {
|
||
+ "href": "http://example.net/",
|
||
+ "host": "example.net",
|
||
+ "hostname": "example.net"
|
||
+ }
|
||
+ },
|
||
+ {
|
||
+ "href": "http://example.net/",
|
||
+ "new_value": "[::1.2.3.4x]",
|
||
+ "expected": {
|
||
+ "href": "http://example.net/",
|
||
+ "host": "example.net",
|
||
+ "hostname": "example.net"
|
||
+ }
|
||
+ },
|
||
+ {
|
||
+ "href": "http://example.net/",
|
||
+ "new_value": "[::1.2.3.]",
|
||
+ "expected": {
|
||
+ "href": "http://example.net/",
|
||
+ "host": "example.net",
|
||
+ "hostname": "example.net"
|
||
+ }
|
||
+ },
|
||
+ {
|
||
+ "href": "http://example.net/",
|
||
+ "new_value": "[::1.2.]",
|
||
+ "expected": {
|
||
+ "href": "http://example.net/",
|
||
+ "host": "example.net",
|
||
+ "hostname": "example.net"
|
||
+ }
|
||
+ },
|
||
+ {
|
||
+ "href": "http://example.net/",
|
||
+ "new_value": "[::1.]",
|
||
+ "expected": {
|
||
+ "href": "http://example.net/",
|
||
+ "host": "example.net",
|
||
+ "hostname": "example.net"
|
||
+ }
|
||
}
|
||
],
|
||
"hostname": [
|
||
{
|
||
+ "href": "sc://x/",
|
||
+ "new_value": "\u0009",
|
||
+ "expected": {
|
||
+ "href": "sc:///",
|
||
+ "host": "",
|
||
+ "hostname": ""
|
||
+ }
|
||
+ },
|
||
+ {
|
||
+ "href": "sc://x/",
|
||
+ "new_value": "\u000A",
|
||
+ "expected": {
|
||
+ "href": "sc:///",
|
||
+ "host": "",
|
||
+ "hostname": ""
|
||
+ }
|
||
+ },
|
||
+ {
|
||
+ "href": "sc://x/",
|
||
+ "new_value": "\u000D",
|
||
+ "expected": {
|
||
+ "href": "sc:///",
|
||
+ "host": "",
|
||
+ "hostname": ""
|
||
+ }
|
||
+ },
|
||
+ {
|
||
+ "href": "sc://x/",
|
||
+ "new_value": "#",
|
||
+ "expected": {
|
||
+ "href": "sc:///",
|
||
+ "host": "",
|
||
+ "hostname": ""
|
||
+ }
|
||
+ },
|
||
+ {
|
||
+ "href": "sc://x/",
|
||
+ "new_value": "/",
|
||
+ "expected": {
|
||
+ "href": "sc:///",
|
||
+ "host": "",
|
||
+ "hostname": ""
|
||
+ }
|
||
+ },
|
||
+ {
|
||
+ "href": "sc://x/",
|
||
+ "new_value": "?",
|
||
+ "expected": {
|
||
+ "href": "sc:///",
|
||
+ "host": "",
|
||
+ "hostname": ""
|
||
+ }
|
||
+ },
|
||
+ {
|
||
+ "href": "sc://x/",
|
||
+ "new_value": "@",
|
||
+ "expected": {
|
||
+ "href": "sc://x/",
|
||
+ "host": "x",
|
||
+ "hostname": "x"
|
||
+ }
|
||
+ },
|
||
+ {
|
||
"comment": "Cannot-be-a-base means no host",
|
||
"href": "mailto:me@example.net",
|
||
"new_value": "example.com",
|
||
@@ -659,15 +912,6 @@
|
||
}
|
||
},
|
||
{
|
||
- "comment": "Path-only URLs can gain a host",
|
||
- "href": "a:/foo",
|
||
- "new_value": "example.net",
|
||
- "expected": {
|
||
- "href": "a://example.net/foo",
|
||
- "host": "example.net"
|
||
- }
|
||
- },
|
||
- {
|
||
"comment": "IPv4 address syntax is normalized",
|
||
"href": "http://example.net:8080",
|
||
"new_value": "0x7F000001",
|
||
@@ -756,7 +1000,7 @@
|
||
}
|
||
},
|
||
{
|
||
- "comment": "\\ is not a delimiter for non-special schemes, and it’s invalid in a domain",
|
||
+ "comment": "\\ is not a delimiter for non-special schemes, but still forbidden in hosts",
|
||
"href": "view-source+http://example.net/path",
|
||
"new_value": "example.com\\stuff",
|
||
"expected": {
|
||
@@ -765,6 +1009,52 @@
|
||
"hostname": "example.net",
|
||
"port": ""
|
||
}
|
||
+ },
|
||
+ {
|
||
+ "comment": "Broken IPv6",
|
||
+ "href": "http://example.net/",
|
||
+ "new_value": "[google.com]",
|
||
+ "expected": {
|
||
+ "href": "http://example.net/",
|
||
+ "host": "example.net",
|
||
+ "hostname": "example.net"
|
||
+ }
|
||
+ },
|
||
+ {
|
||
+ "href": "http://example.net/",
|
||
+ "new_value": "[::1.2.3.4x]",
|
||
+ "expected": {
|
||
+ "href": "http://example.net/",
|
||
+ "host": "example.net",
|
||
+ "hostname": "example.net"
|
||
+ }
|
||
+ },
|
||
+ {
|
||
+ "href": "http://example.net/",
|
||
+ "new_value": "[::1.2.3.]",
|
||
+ "expected": {
|
||
+ "href": "http://example.net/",
|
||
+ "host": "example.net",
|
||
+ "hostname": "example.net"
|
||
+ }
|
||
+ },
|
||
+ {
|
||
+ "href": "http://example.net/",
|
||
+ "new_value": "[::1.2.]",
|
||
+ "expected": {
|
||
+ "href": "http://example.net/",
|
||
+ "host": "example.net",
|
||
+ "hostname": "example.net"
|
||
+ }
|
||
+ },
|
||
+ {
|
||
+ "href": "http://example.net/",
|
||
+ "new_value": "[::1.]",
|
||
+ "expected": {
|
||
+ "href": "http://example.net/",
|
||
+ "host": "example.net",
|
||
+ "hostname": "example.net"
|
||
+ }
|
||
}
|
||
],
|
||
"port": [
|
||
@@ -779,7 +1069,7 @@
|
||
}
|
||
},
|
||
{
|
||
- "comment": "Port number is removed if empty in the new value: https://github.com/whatwg/url/pull/113",
|
||
+ "comment": "Port number is removed if empty is the new value",
|
||
"href": "http://example.net:8080",
|
||
"new_value": "",
|
||
"expected": {
|
||
@@ -920,6 +1210,65 @@
|
||
"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",
|
||
+ "expected": {
|
||
+ "href": "non-special://example.net:8080/path",
|
||
+ "host": "example.net:8080",
|
||
+ "hostname": "example.net",
|
||
+ "port": "8080"
|
||
+ }
|
||
+ },
|
||
+ {
|
||
+ "href": "file://test/",
|
||
+ "new_value": "12",
|
||
+ "expected": {
|
||
+ "href": "file://test/",
|
||
+ "port": ""
|
||
+ }
|
||
+ },
|
||
+ {
|
||
+ "href": "file://localhost/",
|
||
+ "new_value": "12",
|
||
+ "expected": {
|
||
+ "href": "file:///",
|
||
+ "port": ""
|
||
+ }
|
||
+ },
|
||
+ {
|
||
+ "href": "non-base:value",
|
||
+ "new_value": "12",
|
||
+ "expected": {
|
||
+ "href": "non-base:value",
|
||
+ "port": ""
|
||
+ }
|
||
+ },
|
||
+ {
|
||
+ "href": "sc:///",
|
||
+ "new_value": "12",
|
||
+ "expected": {
|
||
+ "href": "sc:///",
|
||
+ "port": ""
|
||
+ }
|
||
+ },
|
||
+ {
|
||
+ "href": "sc://x/",
|
||
+ "new_value": "12",
|
||
+ "expected": {
|
||
+ "href": "sc://x:12/",
|
||
+ "port": "12"
|
||
+ }
|
||
+ },
|
||
+ {
|
||
+ "href": "javascript://x/",
|
||
+ "new_value": "12",
|
||
+ "expected": {
|
||
+ "href": "javascript://x:12/",
|
||
+ "port": "12"
|
||
+ }
|
||
}
|
||
],
|
||
"pathname": [
|
||
@@ -970,8 +1319,8 @@
|
||
"href": "view-source+http://example.net/home?lang=fr#nav",
|
||
"new_value": "\\a\\%2E\\b\\%2e.\\c",
|
||
"expected": {
|
||
- "href": "view-source+http://example.net/\\a\\.\\b\\..\\c?lang=fr#nav",
|
||
- "pathname": "/\\a\\.\\b\\..\\c"
|
||
+ "href": "view-source+http://example.net/\\a\\%2E\\b\\%2e.\\c?lang=fr#nav",
|
||
+ "pathname": "/\\a\\%2E\\b\\%2e.\\c"
|
||
}
|
||
},
|
||
{
|
||
@@ -984,12 +1333,48 @@
|
||
}
|
||
},
|
||
{
|
||
- "comment": "Bytes already percent-encoded are left as-is, except %2E.",
|
||
+ "comment": "Bytes already percent-encoded are left as-is, including %2E outside dotted segments.",
|
||
"href": "http://example.net",
|
||
"new_value": "%2e%2E%c3%89té",
|
||
"expected": {
|
||
- "href": "http://example.net/..%c3%89t%C3%A9",
|
||
- "pathname": "/..%c3%89t%C3%A9"
|
||
+ "href": "http://example.net/%2e%2E%c3%89t%C3%A9",
|
||
+ "pathname": "/%2e%2E%c3%89t%C3%A9"
|
||
+ }
|
||
+ },
|
||
+ {
|
||
+ "comment": "? needs to be encoded",
|
||
+ "href": "http://example.net",
|
||
+ "new_value": "?",
|
||
+ "expected": {
|
||
+ "href": "http://example.net/%3F",
|
||
+ "pathname": "/%3F"
|
||
+ }
|
||
+ },
|
||
+ {
|
||
+ "comment": "# needs to be encoded",
|
||
+ "href": "http://example.net",
|
||
+ "new_value": "#",
|
||
+ "expected": {
|
||
+ "href": "http://example.net/%23",
|
||
+ "pathname": "/%23"
|
||
+ }
|
||
+ },
|
||
+ {
|
||
+ "comment": "? needs to be encoded, non-special scheme",
|
||
+ "href": "sc://example.net",
|
||
+ "new_value": "?",
|
||
+ "expected": {
|
||
+ "href": "sc://example.net/%3F",
|
||
+ "pathname": "/%3F"
|
||
+ }
|
||
+ },
|
||
+ {
|
||
+ "comment": "# needs to be encoded, non-special scheme",
|
||
+ "href": "sc://example.net",
|
||
+ "new_value": "#",
|
||
+ "expected": {
|
||
+ "href": "sc://example.net/%23",
|
||
+ "pathname": "/%23"
|
||
}
|
||
}
|
||
],
|
||
diff -u -r --new-file seamonkey-2.53.1.orig/mozilla/third_party/rust/url/tests/unit.rs seamonkey-2.53.1/mozilla/third_party/rust/url/tests/unit.rs
|
||
--- seamonkey-2.53.1.orig/mozilla/third_party/rust/url/tests/unit.rs 2020-02-17 17:39:21.000000000 -0600
|
||
+++ seamonkey-2.53.1/mozilla/third_party/rust/url/tests/unit.rs 2020-02-29 21:15:43.808770565 -0600
|
||
@@ -11,7 +11,9 @@
|
||
#[macro_use]
|
||
extern crate url;
|
||
|
||
+use std::ascii::AsciiExt;
|
||
use std::borrow::Cow;
|
||
+use std::cell::{Cell, RefCell};
|
||
use std::net::{Ipv4Addr, Ipv6Addr};
|
||
use std::path::{Path, PathBuf};
|
||
use url::{Host, HostAndPort, Url, form_urlencoded};
|
||
@@ -108,6 +110,17 @@
|
||
}
|
||
|
||
#[test]
|
||
+fn path_backslash_fun() {
|
||
+ let mut special_url = "http://foobar.com".parse::<Url>().unwrap();
|
||
+ special_url.path_segments_mut().unwrap().push("foo\\bar");
|
||
+ assert_eq!(special_url.as_str(), "http://foobar.com/foo%5Cbar");
|
||
+
|
||
+ let mut nonspecial_url = "thing://foobar.com".parse::<Url>().unwrap();
|
||
+ nonspecial_url.path_segments_mut().unwrap().push("foo\\bar");
|
||
+ assert_eq!(nonspecial_url.as_str(), "thing://foobar.com/foo\\bar");
|
||
+}
|
||
+
|
||
+#[test]
|
||
fn from_str() {
|
||
assert!("http://testing.com/this".parse::<Url>().is_ok());
|
||
}
|
||
@@ -221,7 +234,7 @@
|
||
("http://example.com/", "http://example.com/"),
|
||
("http://addslash.com", "http://addslash.com/"),
|
||
("http://@emptyuser.com/", "http://emptyuser.com/"),
|
||
- ("http://:@emptypass.com/", "http://:@emptypass.com/"),
|
||
+ ("http://:@emptypass.com/", "http://emptypass.com/"),
|
||
("http://user@user.com/", "http://user@user.com/"),
|
||
("http://user:pass@userpass.com/", "http://user:pass@userpass.com/"),
|
||
("http://slashquery.com/path/?q=something", "http://slashquery.com/path/?q=something"),
|
||
@@ -256,6 +269,15 @@
|
||
}
|
||
|
||
#[test]
|
||
+fn form_urlencoded_custom_encoding_override() {
|
||
+ let encoded = form_urlencoded::Serializer::new(String::new())
|
||
+ .custom_encoding_override(|s| s.as_bytes().to_ascii_uppercase().into())
|
||
+ .append_pair("foo", "bar")
|
||
+ .finish();
|
||
+ assert_eq!(encoded, "FOO=BAR");
|
||
+}
|
||
+
|
||
+#[test]
|
||
fn host_and_port_display() {
|
||
assert_eq!(
|
||
format!(
|
||
@@ -286,22 +308,6 @@
|
||
}
|
||
|
||
#[test]
|
||
-/// https://github.com/servo/rust-url/issues/25
|
||
-fn issue_25() {
|
||
- let filename = if cfg!(windows) { r"C:\run\pg.sock" } else { "/run/pg.sock" };
|
||
- let mut url = Url::from_file_path(filename).unwrap();
|
||
- url.check_invariants().unwrap();
|
||
- url.set_scheme("postgres").unwrap();
|
||
- url.check_invariants().unwrap();
|
||
- url.set_host(Some("")).unwrap();
|
||
- url.check_invariants().unwrap();
|
||
- url.set_username("me").unwrap();
|
||
- url.check_invariants().unwrap();
|
||
- let expected = format!("postgres://me@/{}run/pg.sock", if cfg!(windows) { "C:/" } else { "" });
|
||
- assert_eq!(url.as_str(), expected);
|
||
-}
|
||
-
|
||
-#[test]
|
||
/// https://github.com/servo/rust-url/issues/61
|
||
fn issue_61() {
|
||
let mut url = Url::parse("http://mozilla.org").unwrap();
|
||
@@ -372,6 +378,11 @@
|
||
let mut url = Url::parse("foobar://example.net/hello").unwrap();
|
||
url.set_host(None).unwrap();
|
||
assert_eq!(url.as_str(), "foobar:/hello");
|
||
+
|
||
+ let mut url = Url::parse("foo://ș").unwrap();
|
||
+ assert_eq!(url.as_str(), "foo://%C8%99/");
|
||
+ url.set_host(Some("goșu.ro")).unwrap();
|
||
+ assert_eq!(url.as_str(), "foo://go%C8%99u.ro/");
|
||
}
|
||
|
||
#[test]
|
||
@@ -478,3 +489,68 @@
|
||
let url = Url::from_file_path(Path::new(r"\\.\some\path\file.txt"));
|
||
assert!(url.is_err());
|
||
}
|
||
+
|
||
+// Test the now deprecated log_syntax_violation method for backward
|
||
+// compatibility
|
||
+#[test]
|
||
+#[allow(deprecated)]
|
||
+fn test_old_log_violation_option() {
|
||
+ let violation = Cell::new(None);
|
||
+ let url = Url::options()
|
||
+ .log_syntax_violation(Some(&|s| violation.set(Some(s.to_owned()))))
|
||
+ .parse("http:////mozilla.org:42").unwrap();
|
||
+ assert_eq!(url.port(), Some(42));
|
||
+
|
||
+ let violation = violation.take();
|
||
+ assert_eq!(violation, Some("expected //".to_string()));
|
||
+}
|
||
+
|
||
+#[test]
|
||
+fn test_syntax_violation_callback() {
|
||
+ use url::SyntaxViolation::*;
|
||
+ let violation = Cell::new(None);
|
||
+ let url = Url::options()
|
||
+ .syntax_violation_callback(Some(&|v| violation.set(Some(v))))
|
||
+ .parse("http:////mozilla.org:42").unwrap();
|
||
+ assert_eq!(url.port(), Some(42));
|
||
+
|
||
+ let v = violation.take().unwrap();
|
||
+ assert_eq!(v, ExpectedDoubleSlash);
|
||
+ assert_eq!(v.description(), "expected //");
|
||
+}
|
||
+
|
||
+#[test]
|
||
+fn test_syntax_violation_callback_lifetimes() {
|
||
+ use url::SyntaxViolation::*;
|
||
+ let violation = Cell::new(None);
|
||
+ let vfn = |s| violation.set(Some(s));
|
||
+
|
||
+ let url = Url::options()
|
||
+ .syntax_violation_callback(Some(&vfn))
|
||
+ .parse("http:////mozilla.org:42").unwrap();
|
||
+ assert_eq!(url.port(), Some(42));
|
||
+ assert_eq!(violation.take(), Some(ExpectedDoubleSlash));
|
||
+
|
||
+ let url = Url::options()
|
||
+ .syntax_violation_callback(Some(&vfn))
|
||
+ .parse("http://mozilla.org\\path").unwrap();
|
||
+ assert_eq!(url.path(), "/path");
|
||
+ assert_eq!(violation.take(), Some(Backslash));
|
||
+}
|
||
+
|
||
+#[test]
|
||
+fn test_options_reuse() {
|
||
+ use url::SyntaxViolation::*;
|
||
+ let violations = RefCell::new(Vec::new());
|
||
+ let vfn = |v| violations.borrow_mut().push(v);
|
||
+
|
||
+ let options = Url::options()
|
||
+ .syntax_violation_callback(Some(&vfn));
|
||
+ let url = options.parse("http:////mozilla.org").unwrap();
|
||
+
|
||
+ let options = options.base_url(Some(&url));
|
||
+ let url = options.parse("/sub\\path").unwrap();
|
||
+ assert_eq!(url.as_str(), "http://mozilla.org/sub/path");
|
||
+ assert_eq!(*violations.borrow(),
|
||
+ vec!(ExpectedDoubleSlash, Backslash));
|
||
+}
|
||
diff -u -r --new-file seamonkey-2.53.1.orig/mozilla/third_party/rust/url/tests/urltestdata.json seamonkey-2.53.1/mozilla/third_party/rust/url/tests/urltestdata.json
|
||
--- seamonkey-2.53.1.orig/mozilla/third_party/rust/url/tests/urltestdata.json 2020-02-17 17:39:21.000000000 -0600
|
||
+++ seamonkey-2.53.1/mozilla/third_party/rust/url/tests/urltestdata.json 2020-02-29 21:15:07.679769022 -0600
|
||
@@ -31,6 +31,66 @@
|
||
"hash": "#c"
|
||
},
|
||
{
|
||
+ "input": "https://test:@test",
|
||
+ "base": "about:blank",
|
||
+ "href": "https://test@test/",
|
||
+ "origin": "https://test",
|
||
+ "protocol": "https:",
|
||
+ "username": "test",
|
||
+ "password": "",
|
||
+ "host": "test",
|
||
+ "hostname": "test",
|
||
+ "port": "",
|
||
+ "pathname": "/",
|
||
+ "search": "",
|
||
+ "hash": ""
|
||
+ },
|
||
+ {
|
||
+ "input": "https://:@test",
|
||
+ "base": "about:blank",
|
||
+ "href": "https://test/",
|
||
+ "origin": "https://test",
|
||
+ "protocol": "https:",
|
||
+ "username": "",
|
||
+ "password": "",
|
||
+ "host": "test",
|
||
+ "hostname": "test",
|
||
+ "port": "",
|
||
+ "pathname": "/",
|
||
+ "search": "",
|
||
+ "hash": ""
|
||
+ },
|
||
+ {
|
||
+ "input": "non-special://test:@test/x",
|
||
+ "base": "about:blank",
|
||
+ "href": "non-special://test@test/x",
|
||
+ "origin": "null",
|
||
+ "protocol": "non-special:",
|
||
+ "username": "test",
|
||
+ "password": "",
|
||
+ "host": "test",
|
||
+ "hostname": "test",
|
||
+ "port": "",
|
||
+ "pathname": "/x",
|
||
+ "search": "",
|
||
+ "hash": ""
|
||
+ },
|
||
+ {
|
||
+ "input": "non-special://:@test/x",
|
||
+ "base": "about:blank",
|
||
+ "href": "non-special://test/x",
|
||
+ "origin": "null",
|
||
+ "protocol": "non-special:",
|
||
+ "username": "",
|
||
+ "password": "",
|
||
+ "host": "test",
|
||
+ "hostname": "test",
|
||
+ "port": "",
|
||
+ "pathname": "/x",
|
||
+ "search": "",
|
||
+ "hash": ""
|
||
+ },
|
||
+ {
|
||
"input": "http:foo.com",
|
||
"base": "http://example.org/foo/bar",
|
||
"href": "http://example.org/foo/foo.com",
|
||
@@ -106,6 +166,20 @@
|
||
"hash": "# e"
|
||
},
|
||
{
|
||
+ "input": "lolscheme:x x#x x",
|
||
+ "base": "about:blank",
|
||
+ "href": "lolscheme:x x#x x",
|
||
+ "protocol": "lolscheme:",
|
||
+ "username": "",
|
||
+ "password": "",
|
||
+ "host": "",
|
||
+ "hostname": "",
|
||
+ "port": "",
|
||
+ "pathname": "x x",
|
||
+ "search": "",
|
||
+ "hash": "#x x"
|
||
+ },
|
||
+ {
|
||
"input": "http://f:/c",
|
||
"base": "http://example.org/foo/bar",
|
||
"href": "http://f/c",
|
||
@@ -201,6 +275,11 @@
|
||
"failure": true
|
||
},
|
||
{
|
||
+ "input": "non-special://f:999999/c",
|
||
+ "base": "http://example.org/foo/bar",
|
||
+ "failure": true
|
||
+ },
|
||
+ {
|
||
"input": "http://f: 21 / b ? d # e ",
|
||
"base": "http://example.org/foo/bar",
|
||
"failure": true
|
||
@@ -960,6 +1039,26 @@
|
||
"hash": ""
|
||
},
|
||
{
|
||
+ "input": "file://example:1/",
|
||
+ "base": "about:blank",
|
||
+ "failure": true
|
||
+ },
|
||
+ {
|
||
+ "input": "file://example:test/",
|
||
+ "base": "about:blank",
|
||
+ "failure": true
|
||
+ },
|
||
+ {
|
||
+ "input": "file://example%/",
|
||
+ "base": "about:blank",
|
||
+ "failure": true
|
||
+ },
|
||
+ {
|
||
+ "input": "file://[example]/",
|
||
+ "base": "about:blank",
|
||
+ "failure": true
|
||
+ },
|
||
+ {
|
||
"input": "ftps:/example.com/",
|
||
"base": "http://example.org/foo/bar",
|
||
"href": "ftps:/example.com/",
|
||
@@ -1785,7 +1884,7 @@
|
||
{
|
||
"input": "http://example.com/foo/%2e%2",
|
||
"base": "about:blank",
|
||
- "href": "http://example.com/foo/.%2",
|
||
+ "href": "http://example.com/foo/%2e%2",
|
||
"origin": "http://example.com",
|
||
"protocol": "http:",
|
||
"username": "",
|
||
@@ -1793,14 +1892,14 @@
|
||
"host": "example.com",
|
||
"hostname": "example.com",
|
||
"port": "",
|
||
- "pathname": "/foo/.%2",
|
||
+ "pathname": "/foo/%2e%2",
|
||
"search": "",
|
||
"hash": ""
|
||
},
|
||
{
|
||
"input": "http://example.com/foo/%2e./%2e%2e/.%2e/%2e.bar",
|
||
"base": "about:blank",
|
||
- "href": "http://example.com/..bar",
|
||
+ "href": "http://example.com/%2e.bar",
|
||
"origin": "http://example.com",
|
||
"protocol": "http:",
|
||
"username": "",
|
||
@@ -1808,7 +1907,7 @@
|
||
"host": "example.com",
|
||
"hostname": "example.com",
|
||
"port": "",
|
||
- "pathname": "/..bar",
|
||
+ "pathname": "/%2e.bar",
|
||
"search": "",
|
||
"hash": ""
|
||
},
|
||
@@ -2189,11 +2288,6 @@
|
||
"hash": "# %C2%BB"
|
||
},
|
||
{
|
||
- "input": "http://[www.google.com]/",
|
||
- "base": "about:blank",
|
||
- "failure": true
|
||
- },
|
||
- {
|
||
"input": "http://www.google.com",
|
||
"base": "about:blank",
|
||
"href": "http://www.google.com/",
|
||
@@ -2226,7 +2320,7 @@
|
||
{
|
||
"input": "http://www/foo%2Ehtml",
|
||
"base": "about:blank",
|
||
- "href": "http://www/foo.html",
|
||
+ "href": "http://www/foo%2Ehtml",
|
||
"origin": "http://www",
|
||
"protocol": "http:",
|
||
"username": "",
|
||
@@ -2234,7 +2328,7 @@
|
||
"host": "www",
|
||
"hostname": "www",
|
||
"port": "",
|
||
- "pathname": "/foo.html",
|
||
+ "pathname": "/foo%2Ehtml",
|
||
"search": "",
|
||
"hash": ""
|
||
},
|
||
@@ -3096,7 +3190,7 @@
|
||
{
|
||
"input": "http:a:@www.example.com",
|
||
"base": "about:blank",
|
||
- "href": "http://a:@www.example.com/",
|
||
+ "href": "http://a@www.example.com/",
|
||
"origin": "http://www.example.com",
|
||
"protocol": "http:",
|
||
"username": "a",
|
||
@@ -3111,7 +3205,7 @@
|
||
{
|
||
"input": "http:/a:@www.example.com",
|
||
"base": "about:blank",
|
||
- "href": "http://a:@www.example.com/",
|
||
+ "href": "http://a@www.example.com/",
|
||
"origin": "http://www.example.com",
|
||
"protocol": "http:",
|
||
"username": "a",
|
||
@@ -3126,7 +3220,7 @@
|
||
{
|
||
"input": "http://a:@www.example.com",
|
||
"base": "about:blank",
|
||
- "href": "http://a:@www.example.com/",
|
||
+ "href": "http://a@www.example.com/",
|
||
"origin": "http://www.example.com",
|
||
"protocol": "http:",
|
||
"username": "a",
|
||
@@ -3171,7 +3265,7 @@
|
||
{
|
||
"input": "http://:@www.example.com",
|
||
"base": "about:blank",
|
||
- "href": "http://:@www.example.com/",
|
||
+ "href": "http://www.example.com/",
|
||
"origin": "http://www.example.com",
|
||
"protocol": "http:",
|
||
"username": "",
|
||
@@ -3465,6 +3559,22 @@
|
||
"search": "",
|
||
"hash": ""
|
||
},
|
||
+ "Leading and trailing C0 control or space",
|
||
+ {
|
||
+ "input": "\u0000\u001b\u0004\u0012 http://example.com/\u001f \u000d ",
|
||
+ "base": "about:blank",
|
||
+ "href": "http://example.com/",
|
||
+ "origin": "http://example.com",
|
||
+ "protocol": "http:",
|
||
+ "username": "",
|
||
+ "password": "",
|
||
+ "host": "example.com",
|
||
+ "hostname": "example.com",
|
||
+ "port": "",
|
||
+ "pathname": "/",
|
||
+ "search": "",
|
||
+ "hash": ""
|
||
+ },
|
||
"Ideographic full stop (full-width period for Chinese, etc.) should be treated as a dot. U+3002 is mapped to U+002E (dot)",
|
||
{
|
||
"input": "http://www.foo。bar.com",
|
||
@@ -3493,6 +3603,32 @@
|
||
"base": "http://other.com/",
|
||
"failure": true
|
||
},
|
||
+ "U+FFFD",
|
||
+ {
|
||
+ "input": "https://\ufffd",
|
||
+ "base": "about:blank",
|
||
+ "failure": true
|
||
+ },
|
||
+ {
|
||
+ "input": "https://%EF%BF%BD",
|
||
+ "base": "about:blank",
|
||
+ "failure": true
|
||
+ },
|
||
+ {
|
||
+ "input": "https://x/\ufffd?\ufffd#\ufffd",
|
||
+ "base": "about:blank",
|
||
+ "href": "https://x/%EF%BF%BD?%EF%BF%BD#%EF%BF%BD",
|
||
+ "origin": "https://x",
|
||
+ "protocol": "https:",
|
||
+ "username": "",
|
||
+ "password": "",
|
||
+ "host": "x",
|
||
+ "hostname": "x",
|
||
+ "port": "",
|
||
+ "pathname": "/%EF%BF%BD",
|
||
+ "search": "?%EF%BF%BD",
|
||
+ "hash": "#%EF%BF%BD"
|
||
+ },
|
||
"Test name prepping, fullwidth input should be converted to ASCII and NOT IDN-ized. This is 'Go' in fullwidth UTF-8/UTF-16.",
|
||
{
|
||
"input": "http://Go.com",
|
||
@@ -3536,7 +3672,7 @@
|
||
"input": "http://你好你好",
|
||
"base": "http://other.com/",
|
||
"href": "http://xn--6qqa088eba/",
|
||
- "origin": "http://你好你好",
|
||
+ "origin": "http://xn--6qqa088eba",
|
||
"protocol": "http:",
|
||
"username": "",
|
||
"password": "",
|
||
@@ -3547,6 +3683,36 @@
|
||
"search": "",
|
||
"hash": ""
|
||
},
|
||
+ {
|
||
+ "input": "https://faß.ExAmPlE/",
|
||
+ "base": "about:blank",
|
||
+ "href": "https://xn--fa-hia.example/",
|
||
+ "origin": "https://xn--fa-hia.example",
|
||
+ "protocol": "https:",
|
||
+ "username": "",
|
||
+ "password": "",
|
||
+ "host": "xn--fa-hia.example",
|
||
+ "hostname": "xn--fa-hia.example",
|
||
+ "port": "",
|
||
+ "pathname": "/",
|
||
+ "search": "",
|
||
+ "hash": ""
|
||
+ },
|
||
+ {
|
||
+ "input": "sc://faß.ExAmPlE/",
|
||
+ "base": "about:blank",
|
||
+ "href": "sc://fa%C3%9F.ExAmPlE/",
|
||
+ "origin": "null",
|
||
+ "protocol": "sc:",
|
||
+ "username": "",
|
||
+ "password": "",
|
||
+ "host": "fa%C3%9F.ExAmPlE",
|
||
+ "hostname": "fa%C3%9F.ExAmPlE",
|
||
+ "port": "",
|
||
+ "pathname": "/",
|
||
+ "search": "",
|
||
+ "hash": ""
|
||
+ },
|
||
"Invalid escaped characters should fail and the percents should be escaped. https://www.w3.org/Bugs/Public/show_bug.cgi?id=24191",
|
||
{
|
||
"input": "http://%zz%66%a.com",
|
||
@@ -3600,18 +3766,23 @@
|
||
"base": "http://other.com/",
|
||
"failure": true
|
||
},
|
||
- "Invalid escaping should trigger the regular host error handling",
|
||
+ "Invalid escaping in hosts causes failure",
|
||
{
|
||
"input": "http://%3g%78%63%30%2e%30%32%35%30%2E.01",
|
||
"base": "http://other.com/",
|
||
"failure": true
|
||
},
|
||
- "Something that isn't exactly an IP should get treated as a host and spaces escaped",
|
||
+ "A space in a host causes failure",
|
||
{
|
||
"input": "http://192.168.0.1 hello",
|
||
"base": "http://other.com/",
|
||
"failure": true
|
||
},
|
||
+ {
|
||
+ "input": "https://x x:12",
|
||
+ "base": "about:blank",
|
||
+ "failure": true
|
||
+ },
|
||
"Fullwidth and escaped UTF-8 fullwidth should still be treated as IP",
|
||
{
|
||
"input": "http://0Xc0.0250.01",
|
||
@@ -3628,12 +3799,83 @@
|
||
"search": "",
|
||
"hash": ""
|
||
},
|
||
+ "Domains with empty labels",
|
||
+ {
|
||
+ "input": "http://./",
|
||
+ "base": "about:blank",
|
||
+ "href": "http://./",
|
||
+ "origin": "http://.",
|
||
+ "protocol": "http:",
|
||
+ "username": "",
|
||
+ "password": "",
|
||
+ "host": ".",
|
||
+ "hostname": ".",
|
||
+ "port": "",
|
||
+ "pathname": "/",
|
||
+ "search": "",
|
||
+ "hash": ""
|
||
+ },
|
||
+ {
|
||
+ "input": "http://../",
|
||
+ "base": "about:blank",
|
||
+ "href": "http://../",
|
||
+ "origin": "http://..",
|
||
+ "protocol": "http:",
|
||
+ "username": "",
|
||
+ "password": "",
|
||
+ "host": "..",
|
||
+ "hostname": "..",
|
||
+ "port": "",
|
||
+ "pathname": "/",
|
||
+ "search": "",
|
||
+ "hash": ""
|
||
+ },
|
||
+ {
|
||
+ "input": "http://0..0x300/",
|
||
+ "base": "about:blank",
|
||
+ "href": "http://0..0x300/",
|
||
+ "origin": "http://0..0x300",
|
||
+ "protocol": "http:",
|
||
+ "username": "",
|
||
+ "password": "",
|
||
+ "host": "0..0x300",
|
||
+ "hostname": "0..0x300",
|
||
+ "port": "",
|
||
+ "pathname": "/",
|
||
+ "search": "",
|
||
+ "hash": ""
|
||
+ },
|
||
"Broken IPv6",
|
||
{
|
||
+ "input": "http://[www.google.com]/",
|
||
+ "base": "about:blank",
|
||
+ "failure": true
|
||
+ },
|
||
+ {
|
||
"input": "http://[google.com]",
|
||
"base": "http://other.com/",
|
||
"failure": true
|
||
},
|
||
+ {
|
||
+ "input": "http://[::1.2.3.4x]",
|
||
+ "base": "http://other.com/",
|
||
+ "failure": true
|
||
+ },
|
||
+ {
|
||
+ "input": "http://[::1.2.3.]",
|
||
+ "base": "http://other.com/",
|
||
+ "failure": true
|
||
+ },
|
||
+ {
|
||
+ "input": "http://[::1.2.]",
|
||
+ "base": "http://other.com/",
|
||
+ "failure": true
|
||
+ },
|
||
+ {
|
||
+ "input": "http://[::1.]",
|
||
+ "base": "http://other.com/",
|
||
+ "failure": true
|
||
+ },
|
||
"Misc Unicode",
|
||
{
|
||
"input": "http://foo:💩@example.com/bar",
|
||
@@ -4176,22 +4418,91 @@
|
||
"search": "",
|
||
"hash": ""
|
||
},
|
||
- "# unknown schemes and non-ASCII domains",
|
||
+ "# unknown schemes and their hosts",
|
||
{
|
||
"input": "sc://ñ.test/",
|
||
"base": "about:blank",
|
||
- "href": "sc://xn--ida.test/",
|
||
+ "href": "sc://%C3%B1.test/",
|
||
"origin": "null",
|
||
"protocol": "sc:",
|
||
"username": "",
|
||
"password": "",
|
||
- "host": "xn--ida.test",
|
||
- "hostname": "xn--ida.test",
|
||
+ "host": "%C3%B1.test",
|
||
+ "hostname": "%C3%B1.test",
|
||
"port": "",
|
||
"pathname": "/",
|
||
"search": "",
|
||
"hash": ""
|
||
},
|
||
+ {
|
||
+ "input": "sc://\u001F!\"$&'()*+,-.;<=>^_`{|}~/",
|
||
+ "base": "about:blank",
|
||
+ "href": "sc://%1F!\"$&'()*+,-.;<=>^_`{|}~/",
|
||
+ "origin": "null",
|
||
+ "protocol": "sc:",
|
||
+ "username": "",
|
||
+ "password": "",
|
||
+ "host": "%1F!\"$&'()*+,-.;<=>^_`{|}~",
|
||
+ "hostname": "%1F!\"$&'()*+,-.;<=>^_`{|}~",
|
||
+ "port": "",
|
||
+ "pathname": "/",
|
||
+ "search": "",
|
||
+ "hash": ""
|
||
+ },
|
||
+ {
|
||
+ "input": "sc://\u0000/",
|
||
+ "base": "about:blank",
|
||
+ "failure": true
|
||
+ },
|
||
+ {
|
||
+ "input": "sc:// /",
|
||
+ "base": "about:blank",
|
||
+ "failure": true
|
||
+ },
|
||
+ {
|
||
+ "input": "sc://%/",
|
||
+ "base": "about:blank",
|
||
+ "href": "sc://%/",
|
||
+ "protocol": "sc:",
|
||
+ "username": "",
|
||
+ "password": "",
|
||
+ "host": "%",
|
||
+ "hostname": "%",
|
||
+ "port": "",
|
||
+ "pathname": "/",
|
||
+ "search": "",
|
||
+ "hash": ""
|
||
+ },
|
||
+ {
|
||
+ "input": "sc://[/",
|
||
+ "base": "about:blank",
|
||
+ "failure": true
|
||
+ },
|
||
+ {
|
||
+ "input": "sc://\\/",
|
||
+ "base": "about:blank",
|
||
+ "failure": true
|
||
+ },
|
||
+ {
|
||
+ "input": "sc://]/",
|
||
+ "base": "about:blank",
|
||
+ "failure": true
|
||
+ },
|
||
+ {
|
||
+ "input": "x",
|
||
+ "base": "sc://ñ",
|
||
+ "href": "sc://%C3%B1/x",
|
||
+ "origin": "null",
|
||
+ "protocol": "sc:",
|
||
+ "username": "",
|
||
+ "password": "",
|
||
+ "host": "%C3%B1",
|
||
+ "hostname": "%C3%B1",
|
||
+ "port": "",
|
||
+ "pathname": "/x",
|
||
+ "search": "",
|
||
+ "hash": ""
|
||
+ },
|
||
"# unknown schemes and backslashes",
|
||
{
|
||
"input": "sc:\\../",
|
||
@@ -4224,6 +4535,88 @@
|
||
"search": "",
|
||
"hash": ""
|
||
},
|
||
+ "# unknown scheme with bogus percent-encoding",
|
||
+ {
|
||
+ "input": "wow:%NBD",
|
||
+ "base": "about:blank",
|
||
+ "href": "wow:%NBD",
|
||
+ "origin": "null",
|
||
+ "protocol": "wow:",
|
||
+ "username": "",
|
||
+ "password": "",
|
||
+ "host": "",
|
||
+ "hostname": "",
|
||
+ "port": "",
|
||
+ "pathname": "%NBD",
|
||
+ "search": "",
|
||
+ "hash": ""
|
||
+ },
|
||
+ {
|
||
+ "input": "wow:%1G",
|
||
+ "base": "about:blank",
|
||
+ "href": "wow:%1G",
|
||
+ "origin": "null",
|
||
+ "protocol": "wow:",
|
||
+ "username": "",
|
||
+ "password": "",
|
||
+ "host": "",
|
||
+ "hostname": "",
|
||
+ "port": "",
|
||
+ "pathname": "%1G",
|
||
+ "search": "",
|
||
+ "hash": ""
|
||
+ },
|
||
+ "# Hosts and percent-encoding",
|
||
+ {
|
||
+ "input": "ftp://example.com%80/",
|
||
+ "base": "about:blank",
|
||
+ "failure": true
|
||
+ },
|
||
+ {
|
||
+ "input": "ftp://example.com%A0/",
|
||
+ "base": "about:blank",
|
||
+ "failure": true
|
||
+ },
|
||
+ {
|
||
+ "input": "https://example.com%80/",
|
||
+ "base": "about:blank",
|
||
+ "failure": true
|
||
+ },
|
||
+ {
|
||
+ "input": "https://example.com%A0/",
|
||
+ "base": "about:blank",
|
||
+ "failure": true
|
||
+ },
|
||
+ {
|
||
+ "input": "ftp://%e2%98%83",
|
||
+ "base": "about:blank",
|
||
+ "href": "ftp://xn--n3h/",
|
||
+ "origin": "ftp://xn--n3h",
|
||
+ "protocol": "ftp:",
|
||
+ "username": "",
|
||
+ "password": "",
|
||
+ "host": "xn--n3h",
|
||
+ "hostname": "xn--n3h",
|
||
+ "port": "",
|
||
+ "pathname": "/",
|
||
+ "search": "",
|
||
+ "hash": ""
|
||
+ },
|
||
+ {
|
||
+ "input": "https://%e2%98%83",
|
||
+ "base": "about:blank",
|
||
+ "href": "https://xn--n3h/",
|
||
+ "origin": "https://xn--n3h",
|
||
+ "protocol": "https:",
|
||
+ "username": "",
|
||
+ "password": "",
|
||
+ "host": "xn--n3h",
|
||
+ "hostname": "xn--n3h",
|
||
+ "port": "",
|
||
+ "pathname": "/",
|
||
+ "search": "",
|
||
+ "hash": ""
|
||
+ },
|
||
"# tests from jsdom/whatwg-url designed for code coverage",
|
||
{
|
||
"input": "http://127.0.0.1:10100/relative_import.html",
|
||
@@ -4371,75 +4764,1385 @@
|
||
"port": "",
|
||
"pathname": "/baz",
|
||
"search": "?qux",
|
||
- "searchParams": "",
|
||
+ "searchParams": "qux=",
|
||
"hash": "#foo%08bar"
|
||
},
|
||
- "# IPv6 compression and serialization",
|
||
+ "# IPv4 parsing (via https://github.com/nodejs/node/pull/10317)",
|
||
+ {
|
||
+ "input": "http://192.168.257",
|
||
+ "base": "http://other.com/",
|
||
+ "href": "http://192.168.1.1/",
|
||
+ "origin": "http://192.168.1.1",
|
||
+ "protocol": "http:",
|
||
+ "username": "",
|
||
+ "password": "",
|
||
+ "host": "192.168.1.1",
|
||
+ "hostname": "192.168.1.1",
|
||
+ "port": "",
|
||
+ "pathname": "/",
|
||
+ "search": "",
|
||
+ "hash": ""
|
||
+ },
|
||
+ {
|
||
+ "input": "http://192.168.257.com",
|
||
+ "base": "http://other.com/",
|
||
+ "href": "http://192.168.257.com/",
|
||
+ "origin": "http://192.168.257.com",
|
||
+ "protocol": "http:",
|
||
+ "username": "",
|
||
+ "password": "",
|
||
+ "host": "192.168.257.com",
|
||
+ "hostname": "192.168.257.com",
|
||
+ "port": "",
|
||
+ "pathname": "/",
|
||
+ "search": "",
|
||
+ "hash": ""
|
||
+ },
|
||
+ {
|
||
+ "input": "http://256",
|
||
+ "base": "http://other.com/",
|
||
+ "href": "http://0.0.1.0/",
|
||
+ "origin": "http://0.0.1.0",
|
||
+ "protocol": "http:",
|
||
+ "username": "",
|
||
+ "password": "",
|
||
+ "host": "0.0.1.0",
|
||
+ "hostname": "0.0.1.0",
|
||
+ "port": "",
|
||
+ "pathname": "/",
|
||
+ "search": "",
|
||
+ "hash": ""
|
||
+ },
|
||
+ {
|
||
+ "input": "http://256.com",
|
||
+ "base": "http://other.com/",
|
||
+ "href": "http://256.com/",
|
||
+ "origin": "http://256.com",
|
||
+ "protocol": "http:",
|
||
+ "username": "",
|
||
+ "password": "",
|
||
+ "host": "256.com",
|
||
+ "hostname": "256.com",
|
||
+ "port": "",
|
||
+ "pathname": "/",
|
||
+ "search": "",
|
||
+ "hash": ""
|
||
+ },
|
||
+ {
|
||
+ "input": "http://999999999",
|
||
+ "base": "http://other.com/",
|
||
+ "href": "http://59.154.201.255/",
|
||
+ "origin": "http://59.154.201.255",
|
||
+ "protocol": "http:",
|
||
+ "username": "",
|
||
+ "password": "",
|
||
+ "host": "59.154.201.255",
|
||
+ "hostname": "59.154.201.255",
|
||
+ "port": "",
|
||
+ "pathname": "/",
|
||
+ "search": "",
|
||
+ "hash": ""
|
||
+ },
|
||
+ {
|
||
+ "input": "http://999999999.com",
|
||
+ "base": "http://other.com/",
|
||
+ "href": "http://999999999.com/",
|
||
+ "origin": "http://999999999.com",
|
||
+ "protocol": "http:",
|
||
+ "username": "",
|
||
+ "password": "",
|
||
+ "host": "999999999.com",
|
||
+ "hostname": "999999999.com",
|
||
+ "port": "",
|
||
+ "pathname": "/",
|
||
+ "search": "",
|
||
+ "hash": ""
|
||
+ },
|
||
+ {
|
||
+ "input": "http://10000000000",
|
||
+ "base": "http://other.com/",
|
||
+ "failure": true
|
||
+ },
|
||
+ {
|
||
+ "input": "http://10000000000.com",
|
||
+ "base": "http://other.com/",
|
||
+ "href": "http://10000000000.com/",
|
||
+ "origin": "http://10000000000.com",
|
||
+ "protocol": "http:",
|
||
+ "username": "",
|
||
+ "password": "",
|
||
+ "host": "10000000000.com",
|
||
+ "hostname": "10000000000.com",
|
||
+ "port": "",
|
||
+ "pathname": "/",
|
||
+ "search": "",
|
||
+ "hash": ""
|
||
+ },
|
||
+ {
|
||
+ "input": "http://4294967295",
|
||
+ "base": "http://other.com/",
|
||
+ "href": "http://255.255.255.255/",
|
||
+ "origin": "http://255.255.255.255",
|
||
+ "protocol": "http:",
|
||
+ "username": "",
|
||
+ "password": "",
|
||
+ "host": "255.255.255.255",
|
||
+ "hostname": "255.255.255.255",
|
||
+ "port": "",
|
||
+ "pathname": "/",
|
||
+ "search": "",
|
||
+ "hash": ""
|
||
+ },
|
||
+ {
|
||
+ "input": "http://4294967296",
|
||
+ "base": "http://other.com/",
|
||
+ "failure": true
|
||
+ },
|
||
+ {
|
||
+ "input": "http://0xffffffff",
|
||
+ "base": "http://other.com/",
|
||
+ "href": "http://255.255.255.255/",
|
||
+ "origin": "http://255.255.255.255",
|
||
+ "protocol": "http:",
|
||
+ "username": "",
|
||
+ "password": "",
|
||
+ "host": "255.255.255.255",
|
||
+ "hostname": "255.255.255.255",
|
||
+ "port": "",
|
||
+ "pathname": "/",
|
||
+ "search": "",
|
||
+ "hash": ""
|
||
+ },
|
||
+ {
|
||
+ "input": "http://0xffffffff1",
|
||
+ "base": "http://other.com/",
|
||
+ "failure": true
|
||
+ },
|
||
+ {
|
||
+ "input": "http://256.256.256.256",
|
||
+ "base": "http://other.com/",
|
||
+ "failure": true
|
||
+ },
|
||
+ {
|
||
+ "input": "http://256.256.256.256.256",
|
||
+ "base": "http://other.com/",
|
||
+ "href": "http://256.256.256.256.256/",
|
||
+ "origin": "http://256.256.256.256.256",
|
||
+ "protocol": "http:",
|
||
+ "username": "",
|
||
+ "password": "",
|
||
+ "host": "256.256.256.256.256",
|
||
+ "hostname": "256.256.256.256.256",
|
||
+ "port": "",
|
||
+ "pathname": "/",
|
||
+ "search": "",
|
||
+ "hash": ""
|
||
+ },
|
||
+ {
|
||
+ "input": "https://0x.0x.0",
|
||
+ "base": "about:blank",
|
||
+ "href": "https://0.0.0.0/",
|
||
+ "origin": "https://0.0.0.0",
|
||
+ "protocol": "https:",
|
||
+ "username": "",
|
||
+ "password": "",
|
||
+ "host": "0.0.0.0",
|
||
+ "hostname": "0.0.0.0",
|
||
+ "port": "",
|
||
+ "pathname": "/",
|
||
+ "search": "",
|
||
+ "hash": ""
|
||
+ },
|
||
+ "More IPv4 parsing (via https://github.com/jsdom/whatwg-url/issues/92)",
|
||
+ {
|
||
+ "input": "https://256.0.0.1/test",
|
||
+ "base": "about:blank",
|
||
+ "failure": true
|
||
+ },
|
||
+ "# file URLs containing percent-encoded Windows drive letters (shouldn't work)",
|
||
+ {
|
||
+ "input": "file:///C%3A/",
|
||
+ "base": "about:blank",
|
||
+ "href": "file:///C%3A/",
|
||
+ "protocol": "file:",
|
||
+ "username": "",
|
||
+ "password": "",
|
||
+ "host": "",
|
||
+ "hostname": "",
|
||
+ "port": "",
|
||
+ "pathname": "/C%3A/",
|
||
+ "search": "",
|
||
+ "hash": ""
|
||
+ },
|
||
+ {
|
||
+ "input": "file:///C%7C/",
|
||
+ "base": "about:blank",
|
||
+ "href": "file:///C%7C/",
|
||
+ "protocol": "file:",
|
||
+ "username": "",
|
||
+ "password": "",
|
||
+ "host": "",
|
||
+ "hostname": "",
|
||
+ "port": "",
|
||
+ "pathname": "/C%7C/",
|
||
+ "search": "",
|
||
+ "hash": ""
|
||
+ },
|
||
+ "# file URLs relative to other file URLs (via https://github.com/jsdom/whatwg-url/pull/60)",
|
||
+ {
|
||
+ "input": "pix/submit.gif",
|
||
+ "base": "file:///C:/Users/Domenic/Dropbox/GitHub/tmpvar/jsdom/test/level2/html/files/anchor.html",
|
||
+ "href": "file:///C:/Users/Domenic/Dropbox/GitHub/tmpvar/jsdom/test/level2/html/files/pix/submit.gif",
|
||
+ "protocol": "file:",
|
||
+ "username": "",
|
||
+ "password": "",
|
||
+ "host": "",
|
||
+ "hostname": "",
|
||
+ "port": "",
|
||
+ "pathname": "/C:/Users/Domenic/Dropbox/GitHub/tmpvar/jsdom/test/level2/html/files/pix/submit.gif",
|
||
+ "search": "",
|
||
+ "hash": ""
|
||
+ },
|
||
+ {
|
||
+ "input": "..",
|
||
+ "base": "file:///C:/",
|
||
+ "href": "file:///C:/",
|
||
+ "protocol": "file:",
|
||
+ "username": "",
|
||
+ "password": "",
|
||
+ "host": "",
|
||
+ "hostname": "",
|
||
+ "port": "",
|
||
+ "pathname": "/C:/",
|
||
+ "search": "",
|
||
+ "hash": ""
|
||
+ },
|
||
+ {
|
||
+ "input": "..",
|
||
+ "base": "file:///",
|
||
+ "href": "file:///",
|
||
+ "protocol": "file:",
|
||
+ "username": "",
|
||
+ "password": "",
|
||
+ "host": "",
|
||
+ "hostname": "",
|
||
+ "port": "",
|
||
+ "pathname": "/",
|
||
+ "search": "",
|
||
+ "hash": ""
|
||
+ },
|
||
+ "# More file URL tests by zcorpan and annevk",
|
||
+ {
|
||
+ "input": "/",
|
||
+ "base": "file:///C:/a/b",
|
||
+ "href": "file:///C:/",
|
||
+ "protocol": "file:",
|
||
+ "username": "",
|
||
+ "password": "",
|
||
+ "host": "",
|
||
+ "hostname": "",
|
||
+ "port": "",
|
||
+ "pathname": "/C:/",
|
||
+ "search": "",
|
||
+ "hash": ""
|
||
+ },
|
||
+ {
|
||
+ "input": "//d:",
|
||
+ "base": "file:///C:/a/b",
|
||
+ "href": "file:///d:",
|
||
+ "protocol": "file:",
|
||
+ "username": "",
|
||
+ "password": "",
|
||
+ "host": "",
|
||
+ "hostname": "",
|
||
+ "port": "",
|
||
+ "pathname": "/d:",
|
||
+ "search": "",
|
||
+ "hash": ""
|
||
+ },
|
||
+ {
|
||
+ "input": "//d:/..",
|
||
+ "base": "file:///C:/a/b",
|
||
+ "href": "file:///d:/",
|
||
+ "protocol": "file:",
|
||
+ "username": "",
|
||
+ "password": "",
|
||
+ "host": "",
|
||
+ "hostname": "",
|
||
+ "port": "",
|
||
+ "pathname": "/d:/",
|
||
+ "search": "",
|
||
+ "hash": ""
|
||
+ },
|
||
+ {
|
||
+ "input": "..",
|
||
+ "base": "file:///ab:/",
|
||
+ "href": "file:///",
|
||
+ "protocol": "file:",
|
||
+ "username": "",
|
||
+ "password": "",
|
||
+ "host": "",
|
||
+ "hostname": "",
|
||
+ "port": "",
|
||
+ "pathname": "/",
|
||
+ "search": "",
|
||
+ "hash": ""
|
||
+ },
|
||
+ {
|
||
+ "input": "..",
|
||
+ "base": "file:///1:/",
|
||
+ "href": "file:///",
|
||
+ "protocol": "file:",
|
||
+ "username": "",
|
||
+ "password": "",
|
||
+ "host": "",
|
||
+ "hostname": "",
|
||
+ "port": "",
|
||
+ "pathname": "/",
|
||
+ "search": "",
|
||
+ "hash": ""
|
||
+ },
|
||
+ {
|
||
+ "input": "",
|
||
+ "base": "file:///test?test#test",
|
||
+ "href": "file:///test?test",
|
||
+ "protocol": "file:",
|
||
+ "username": "",
|
||
+ "password": "",
|
||
+ "host": "",
|
||
+ "hostname": "",
|
||
+ "port": "",
|
||
+ "pathname": "/test",
|
||
+ "search": "?test",
|
||
+ "hash": ""
|
||
+ },
|
||
+ {
|
||
+ "input": "file:",
|
||
+ "base": "file:///test?test#test",
|
||
+ "href": "file:///test?test",
|
||
+ "protocol": "file:",
|
||
+ "username": "",
|
||
+ "password": "",
|
||
+ "host": "",
|
||
+ "hostname": "",
|
||
+ "port": "",
|
||
+ "pathname": "/test",
|
||
+ "search": "?test",
|
||
+ "hash": ""
|
||
+ },
|
||
+ {
|
||
+ "input": "?x",
|
||
+ "base": "file:///test?test#test",
|
||
+ "href": "file:///test?x",
|
||
+ "protocol": "file:",
|
||
+ "username": "",
|
||
+ "password": "",
|
||
+ "host": "",
|
||
+ "hostname": "",
|
||
+ "port": "",
|
||
+ "pathname": "/test",
|
||
+ "search": "?x",
|
||
+ "hash": ""
|
||
+ },
|
||
+ {
|
||
+ "input": "file:?x",
|
||
+ "base": "file:///test?test#test",
|
||
+ "href": "file:///test?x",
|
||
+ "protocol": "file:",
|
||
+ "username": "",
|
||
+ "password": "",
|
||
+ "host": "",
|
||
+ "hostname": "",
|
||
+ "port": "",
|
||
+ "pathname": "/test",
|
||
+ "search": "?x",
|
||
+ "hash": ""
|
||
+ },
|
||
+ {
|
||
+ "input": "#x",
|
||
+ "base": "file:///test?test#test",
|
||
+ "href": "file:///test?test#x",
|
||
+ "protocol": "file:",
|
||
+ "username": "",
|
||
+ "password": "",
|
||
+ "host": "",
|
||
+ "hostname": "",
|
||
+ "port": "",
|
||
+ "pathname": "/test",
|
||
+ "search": "?test",
|
||
+ "hash": "#x"
|
||
+ },
|
||
+ {
|
||
+ "input": "file:#x",
|
||
+ "base": "file:///test?test#test",
|
||
+ "href": "file:///test?test#x",
|
||
+ "protocol": "file:",
|
||
+ "username": "",
|
||
+ "password": "",
|
||
+ "host": "",
|
||
+ "hostname": "",
|
||
+ "port": "",
|
||
+ "pathname": "/test",
|
||
+ "search": "?test",
|
||
+ "hash": "#x"
|
||
+ },
|
||
+ "# File URLs and many (back)slashes",
|
||
+ {
|
||
+ "input": "file:///localhost//cat",
|
||
+ "base": "about:blank",
|
||
+ "href": "file:///localhost//cat",
|
||
+ "protocol": "file:",
|
||
+ "username": "",
|
||
+ "password": "",
|
||
+ "host": "",
|
||
+ "hostname": "",
|
||
+ "port": "",
|
||
+ "pathname": "/localhost//cat",
|
||
+ "search": "",
|
||
+ "hash": ""
|
||
+ },
|
||
{
|
||
- "input": "http://[fe80:cd00::1257:0:211e:729c]/",
|
||
+ "input": "\\//pig",
|
||
+ "base": "file://lion/",
|
||
+ "href": "file:///pig",
|
||
+ "protocol": "file:",
|
||
+ "username": "",
|
||
+ "password": "",
|
||
+ "host": "",
|
||
+ "hostname": "",
|
||
+ "port": "",
|
||
+ "pathname": "/pig",
|
||
+ "search": "",
|
||
+ "hash": ""
|
||
+ },
|
||
+ {
|
||
+ "input": "file://",
|
||
+ "base": "file://ape/",
|
||
+ "href": "file:///",
|
||
+ "protocol": "file:",
|
||
+ "username": "",
|
||
+ "password": "",
|
||
+ "host": "",
|
||
+ "hostname": "",
|
||
+ "port": "",
|
||
+ "pathname": "/",
|
||
+ "search": "",
|
||
+ "hash": ""
|
||
+ },
|
||
+ "# Windows drive letter handling with the 'file:' base URL",
|
||
+ {
|
||
+ "input": "C|#",
|
||
+ "base": "file://host/dir/file",
|
||
+ "href": "file:///C:#",
|
||
+ "protocol": "file:",
|
||
+ "username": "",
|
||
+ "password": "",
|
||
+ "host": "",
|
||
+ "hostname": "",
|
||
+ "port": "",
|
||
+ "pathname": "/C:",
|
||
+ "search": "",
|
||
+ "hash": ""
|
||
+ },
|
||
+ {
|
||
+ "input": "C|?",
|
||
+ "base": "file://host/dir/file",
|
||
+ "href": "file:///C:?",
|
||
+ "protocol": "file:",
|
||
+ "username": "",
|
||
+ "password": "",
|
||
+ "host": "",
|
||
+ "hostname": "",
|
||
+ "port": "",
|
||
+ "pathname": "/C:",
|
||
+ "search": "",
|
||
+ "hash": ""
|
||
+ },
|
||
+ {
|
||
+ "input": "C|/",
|
||
+ "base": "file://host/dir/file",
|
||
+ "href": "file:///C:/",
|
||
+ "protocol": "file:",
|
||
+ "username": "",
|
||
+ "password": "",
|
||
+ "host": "",
|
||
+ "hostname": "",
|
||
+ "port": "",
|
||
+ "pathname": "/C:/",
|
||
+ "search": "",
|
||
+ "hash": ""
|
||
+ },
|
||
+ {
|
||
+ "input": "C|\n/",
|
||
+ "base": "file://host/dir/file",
|
||
+ "href": "file:///C:/",
|
||
+ "protocol": "file:",
|
||
+ "username": "",
|
||
+ "password": "",
|
||
+ "host": "",
|
||
+ "hostname": "",
|
||
+ "port": "",
|
||
+ "pathname": "/C:/",
|
||
+ "search": "",
|
||
+ "hash": ""
|
||
+ },
|
||
+ {
|
||
+ "input": "C|\\",
|
||
+ "base": "file://host/dir/file",
|
||
+ "href": "file:///C:/",
|
||
+ "protocol": "file:",
|
||
+ "username": "",
|
||
+ "password": "",
|
||
+ "host": "",
|
||
+ "hostname": "",
|
||
+ "port": "",
|
||
+ "pathname": "/C:/",
|
||
+ "search": "",
|
||
+ "hash": ""
|
||
+ },
|
||
+ {
|
||
+ "input": "C",
|
||
+ "base": "file://host/dir/file",
|
||
+ "href": "file://host/dir/C",
|
||
+ "protocol": "file:",
|
||
+ "username": "",
|
||
+ "password": "",
|
||
+ "host": "host",
|
||
+ "hostname": "host",
|
||
+ "port": "",
|
||
+ "pathname": "/dir/C",
|
||
+ "search": "",
|
||
+ "hash": ""
|
||
+ },
|
||
+ {
|
||
+ "input": "C|a",
|
||
+ "base": "file://host/dir/file",
|
||
+ "href": "file://host/dir/C|a",
|
||
+ "protocol": "file:",
|
||
+ "username": "",
|
||
+ "password": "",
|
||
+ "host": "host",
|
||
+ "hostname": "host",
|
||
+ "port": "",
|
||
+ "pathname": "/dir/C|a",
|
||
+ "search": "",
|
||
+ "hash": ""
|
||
+ },
|
||
+ "# Windows drive letter quirk in the file slash state",
|
||
+ {
|
||
+ "input": "/c:/foo/bar",
|
||
+ "base": "file://host/path",
|
||
+ "href": "file:///c:/foo/bar",
|
||
+ "protocol": "file:",
|
||
+ "username": "",
|
||
+ "password": "",
|
||
+ "host": "",
|
||
+ "hostname": "",
|
||
+ "port": "",
|
||
+ "pathname": "/c:/foo/bar",
|
||
+ "search": "",
|
||
+ "hash": ""
|
||
+ },
|
||
+ "# Windows drive letter quirk (no host)",
|
||
+ {
|
||
+ "input": "file:/C|/",
|
||
"base": "about:blank",
|
||
- "href": "http://[fe80:cd00::1257:0:211e:729c]/",
|
||
- "origin": "http://[fe80:cd00::1257:0:211e:729c]",
|
||
+ "href": "file:///C:/",
|
||
+ "protocol": "file:",
|
||
+ "username": "",
|
||
+ "password": "",
|
||
+ "host": "",
|
||
+ "hostname": "",
|
||
+ "port": "",
|
||
+ "pathname": "/C:/",
|
||
+ "search": "",
|
||
+ "hash": ""
|
||
+ },
|
||
+ {
|
||
+ "input": "file://C|/",
|
||
+ "base": "about:blank",
|
||
+ "href": "file:///C:/",
|
||
+ "protocol": "file:",
|
||
+ "username": "",
|
||
+ "password": "",
|
||
+ "host": "",
|
||
+ "hostname": "",
|
||
+ "port": "",
|
||
+ "pathname": "/C:/",
|
||
+ "search": "",
|
||
+ "hash": ""
|
||
+ },
|
||
+ "# Windows drive letter quirk with not empty host",
|
||
+ {
|
||
+ "input": "file://example.net/C:/",
|
||
+ "base": "about:blank",
|
||
+ "href": "file:///C:/",
|
||
+ "protocol": "file:",
|
||
+ "username": "",
|
||
+ "password": "",
|
||
+ "host": "",
|
||
+ "hostname": "",
|
||
+ "port": "",
|
||
+ "pathname": "/C:/",
|
||
+ "search": "",
|
||
+ "hash": ""
|
||
+ },
|
||
+ {
|
||
+ "input": "file://1.2.3.4/C:/",
|
||
+ "base": "about:blank",
|
||
+ "href": "file:///C:/",
|
||
+ "protocol": "file:",
|
||
+ "username": "",
|
||
+ "password": "",
|
||
+ "host": "",
|
||
+ "hostname": "",
|
||
+ "port": "",
|
||
+ "pathname": "/C:/",
|
||
+ "search": "",
|
||
+ "hash": ""
|
||
+ },
|
||
+ {
|
||
+ "input": "file://[1::8]/C:/",
|
||
+ "base": "about:blank",
|
||
+ "href": "file:///C:/",
|
||
+ "protocol": "file:",
|
||
+ "username": "",
|
||
+ "password": "",
|
||
+ "host": "",
|
||
+ "hostname": "",
|
||
+ "port": "",
|
||
+ "pathname": "/C:/",
|
||
+ "search": "",
|
||
+ "hash": ""
|
||
+ },
|
||
+ "# file URLs without base URL by Rimas Misevičius",
|
||
+ {
|
||
+ "input": "file:",
|
||
+ "base": "about:blank",
|
||
+ "href": "file:///",
|
||
+ "protocol": "file:",
|
||
+ "username": "",
|
||
+ "password": "",
|
||
+ "host": "",
|
||
+ "hostname": "",
|
||
+ "port": "",
|
||
+ "pathname": "/",
|
||
+ "search": "",
|
||
+ "hash": ""
|
||
+ },
|
||
+ {
|
||
+ "input": "file:?q=v",
|
||
+ "base": "about:blank",
|
||
+ "href": "file:///?q=v",
|
||
+ "protocol": "file:",
|
||
+ "username": "",
|
||
+ "password": "",
|
||
+ "host": "",
|
||
+ "hostname": "",
|
||
+ "port": "",
|
||
+ "pathname": "/",
|
||
+ "search": "?q=v",
|
||
+ "hash": ""
|
||
+ },
|
||
+ {
|
||
+ "input": "file:#frag",
|
||
+ "base": "about:blank",
|
||
+ "href": "file:///#frag",
|
||
+ "protocol": "file:",
|
||
+ "username": "",
|
||
+ "password": "",
|
||
+ "host": "",
|
||
+ "hostname": "",
|
||
+ "port": "",
|
||
+ "pathname": "/",
|
||
+ "search": "",
|
||
+ "hash": "#frag"
|
||
+ },
|
||
+ "# IPv6 tests",
|
||
+ {
|
||
+ "input": "http://[1:0::]",
|
||
+ "base": "http://example.net/",
|
||
+ "href": "http://[1::]/",
|
||
+ "origin": "http://[1::]",
|
||
"protocol": "http:",
|
||
"username": "",
|
||
"password": "",
|
||
- "host": "[fe80:cd00::1257:0:211e:729c]",
|
||
- "hostname": "[fe80:cd00::1257:0:211e:729c]",
|
||
+ "host": "[1::]",
|
||
+ "hostname": "[1::]",
|
||
"port": "",
|
||
"pathname": "/",
|
||
"search": "",
|
||
- "searchParams": "",
|
||
"hash": ""
|
||
},
|
||
- "# IPv6 compression and serialization: Compress sequences of two or more zeroes",
|
||
{
|
||
- "input": "http://[fe80:cd00:0:0:1257:0:211e:729c]/",
|
||
+ "input": "http://[0:1:2:3:4:5:6:7:8]",
|
||
+ "base": "http://example.net/",
|
||
+ "failure": true
|
||
+ },
|
||
+ {
|
||
+ "input": "https://[0::0::0]",
|
||
+ "base": "about:blank",
|
||
+ "failure": true
|
||
+ },
|
||
+ {
|
||
+ "input": "https://[0:.0]",
|
||
+ "base": "about:blank",
|
||
+ "failure": true
|
||
+ },
|
||
+ {
|
||
+ "input": "https://[0:0:]",
|
||
+ "base": "about:blank",
|
||
+ "failure": true
|
||
+ },
|
||
+ {
|
||
+ "input": "https://[0:1:2:3:4:5:6:7.0.0.0.1]",
|
||
+ "base": "about:blank",
|
||
+ "failure": true
|
||
+ },
|
||
+ {
|
||
+ "input": "https://[0:1.00.0.0.0]",
|
||
+ "base": "about:blank",
|
||
+ "failure": true
|
||
+ },
|
||
+ {
|
||
+ "input": "https://[0:1.290.0.0.0]",
|
||
+ "base": "about:blank",
|
||
+ "failure": true
|
||
+ },
|
||
+ {
|
||
+ "input": "https://[0:1.23.23]",
|
||
+ "base": "about:blank",
|
||
+ "failure": true
|
||
+ },
|
||
+ "# Empty host",
|
||
+ {
|
||
+ "input": "http://?",
|
||
"base": "about:blank",
|
||
- "href": "http://[fe80:cd00::1257:0:211e:729c]/",
|
||
- "origin": "http://[fe80:cd00::1257:0:211e:729c]",
|
||
+ "failure": true
|
||
+ },
|
||
+ {
|
||
+ "input": "http://#",
|
||
+ "base": "about:blank",
|
||
+ "failure": true
|
||
+ },
|
||
+ "Port overflow (2^32 + 81)",
|
||
+ {
|
||
+ "input": "http://f:4294967377/c",
|
||
+ "base": "http://example.org/",
|
||
+ "failure": true
|
||
+ },
|
||
+ "Port overflow (2^64 + 81)",
|
||
+ {
|
||
+ "input": "http://f:18446744073709551697/c",
|
||
+ "base": "http://example.org/",
|
||
+ "failure": true
|
||
+ },
|
||
+ "Port overflow (2^128 + 81)",
|
||
+ {
|
||
+ "input": "http://f:340282366920938463463374607431768211537/c",
|
||
+ "base": "http://example.org/",
|
||
+ "failure": true
|
||
+ },
|
||
+ "# Non-special-URL path tests",
|
||
+ {
|
||
+ "input": "///",
|
||
+ "base": "sc://x/",
|
||
+ "href": "sc:///",
|
||
+ "protocol": "sc:",
|
||
+ "username": "",
|
||
+ "password": "",
|
||
+ "host": "",
|
||
+ "hostname": "",
|
||
+ "port": "",
|
||
+ "pathname": "/",
|
||
+ "search": "",
|
||
+ "hash": ""
|
||
+ },
|
||
+ {
|
||
+ "input": "tftp://foobar.com/someconfig;mode=netascii",
|
||
+ "base": "about:blank",
|
||
+ "href": "tftp://foobar.com/someconfig;mode=netascii",
|
||
+ "origin": "null",
|
||
+ "protocol": "tftp:",
|
||
+ "username": "",
|
||
+ "password": "",
|
||
+ "host": "foobar.com",
|
||
+ "hostname": "foobar.com",
|
||
+ "port": "",
|
||
+ "pathname": "/someconfig;mode=netascii",
|
||
+ "search": "",
|
||
+ "hash": ""
|
||
+ },
|
||
+ {
|
||
+ "input": "telnet://user:pass@foobar.com:23/",
|
||
+ "base": "about:blank",
|
||
+ "href": "telnet://user:pass@foobar.com:23/",
|
||
+ "origin": "null",
|
||
+ "protocol": "telnet:",
|
||
+ "username": "user",
|
||
+ "password": "pass",
|
||
+ "host": "foobar.com:23",
|
||
+ "hostname": "foobar.com",
|
||
+ "port": "23",
|
||
+ "pathname": "/",
|
||
+ "search": "",
|
||
+ "hash": ""
|
||
+ },
|
||
+ {
|
||
+ "input": "ut2004://10.10.10.10:7777/Index.ut2",
|
||
+ "base": "about:blank",
|
||
+ "href": "ut2004://10.10.10.10:7777/Index.ut2",
|
||
+ "origin": "null",
|
||
+ "protocol": "ut2004:",
|
||
+ "username": "",
|
||
+ "password": "",
|
||
+ "host": "10.10.10.10:7777",
|
||
+ "hostname": "10.10.10.10",
|
||
+ "port": "7777",
|
||
+ "pathname": "/Index.ut2",
|
||
+ "search": "",
|
||
+ "hash": ""
|
||
+ },
|
||
+ {
|
||
+ "input": "redis://foo:bar@somehost:6379/0?baz=bam&qux=baz",
|
||
+ "base": "about:blank",
|
||
+ "href": "redis://foo:bar@somehost:6379/0?baz=bam&qux=baz",
|
||
+ "origin": "null",
|
||
+ "protocol": "redis:",
|
||
+ "username": "foo",
|
||
+ "password": "bar",
|
||
+ "host": "somehost:6379",
|
||
+ "hostname": "somehost",
|
||
+ "port": "6379",
|
||
+ "pathname": "/0",
|
||
+ "search": "?baz=bam&qux=baz",
|
||
+ "hash": ""
|
||
+ },
|
||
+ {
|
||
+ "input": "rsync://foo@host:911/sup",
|
||
+ "base": "about:blank",
|
||
+ "href": "rsync://foo@host:911/sup",
|
||
+ "origin": "null",
|
||
+ "protocol": "rsync:",
|
||
+ "username": "foo",
|
||
+ "password": "",
|
||
+ "host": "host:911",
|
||
+ "hostname": "host",
|
||
+ "port": "911",
|
||
+ "pathname": "/sup",
|
||
+ "search": "",
|
||
+ "hash": ""
|
||
+ },
|
||
+ {
|
||
+ "input": "git://github.com/foo/bar.git",
|
||
+ "base": "about:blank",
|
||
+ "href": "git://github.com/foo/bar.git",
|
||
+ "origin": "null",
|
||
+ "protocol": "git:",
|
||
+ "username": "",
|
||
+ "password": "",
|
||
+ "host": "github.com",
|
||
+ "hostname": "github.com",
|
||
+ "port": "",
|
||
+ "pathname": "/foo/bar.git",
|
||
+ "search": "",
|
||
+ "hash": ""
|
||
+ },
|
||
+ {
|
||
+ "input": "irc://myserver.com:6999/channel?passwd",
|
||
+ "base": "about:blank",
|
||
+ "href": "irc://myserver.com:6999/channel?passwd",
|
||
+ "origin": "null",
|
||
+ "protocol": "irc:",
|
||
+ "username": "",
|
||
+ "password": "",
|
||
+ "host": "myserver.com:6999",
|
||
+ "hostname": "myserver.com",
|
||
+ "port": "6999",
|
||
+ "pathname": "/channel",
|
||
+ "search": "?passwd",
|
||
+ "hash": ""
|
||
+ },
|
||
+ {
|
||
+ "input": "dns://fw.example.org:9999/foo.bar.org?type=TXT",
|
||
+ "base": "about:blank",
|
||
+ "href": "dns://fw.example.org:9999/foo.bar.org?type=TXT",
|
||
+ "origin": "null",
|
||
+ "protocol": "dns:",
|
||
+ "username": "",
|
||
+ "password": "",
|
||
+ "host": "fw.example.org:9999",
|
||
+ "hostname": "fw.example.org",
|
||
+ "port": "9999",
|
||
+ "pathname": "/foo.bar.org",
|
||
+ "search": "?type=TXT",
|
||
+ "hash": ""
|
||
+ },
|
||
+ {
|
||
+ "input": "ldap://localhost:389/ou=People,o=JNDITutorial",
|
||
+ "base": "about:blank",
|
||
+ "href": "ldap://localhost:389/ou=People,o=JNDITutorial",
|
||
+ "origin": "null",
|
||
+ "protocol": "ldap:",
|
||
+ "username": "",
|
||
+ "password": "",
|
||
+ "host": "localhost:389",
|
||
+ "hostname": "localhost",
|
||
+ "port": "389",
|
||
+ "pathname": "/ou=People,o=JNDITutorial",
|
||
+ "search": "",
|
||
+ "hash": ""
|
||
+ },
|
||
+ {
|
||
+ "input": "git+https://github.com/foo/bar",
|
||
+ "base": "about:blank",
|
||
+ "href": "git+https://github.com/foo/bar",
|
||
+ "origin": "null",
|
||
+ "protocol": "git+https:",
|
||
+ "username": "",
|
||
+ "password": "",
|
||
+ "host": "github.com",
|
||
+ "hostname": "github.com",
|
||
+ "port": "",
|
||
+ "pathname": "/foo/bar",
|
||
+ "search": "",
|
||
+ "hash": ""
|
||
+ },
|
||
+ {
|
||
+ "input": "urn:ietf:rfc:2648",
|
||
+ "base": "about:blank",
|
||
+ "href": "urn:ietf:rfc:2648",
|
||
+ "origin": "null",
|
||
+ "protocol": "urn:",
|
||
+ "username": "",
|
||
+ "password": "",
|
||
+ "host": "",
|
||
+ "hostname": "",
|
||
+ "port": "",
|
||
+ "pathname": "ietf:rfc:2648",
|
||
+ "search": "",
|
||
+ "hash": ""
|
||
+ },
|
||
+ {
|
||
+ "input": "tag:joe@example.org,2001:foo/bar",
|
||
+ "base": "about:blank",
|
||
+ "href": "tag:joe@example.org,2001:foo/bar",
|
||
+ "origin": "null",
|
||
+ "protocol": "tag:",
|
||
+ "username": "",
|
||
+ "password": "",
|
||
+ "host": "",
|
||
+ "hostname": "",
|
||
+ "port": "",
|
||
+ "pathname": "joe@example.org,2001:foo/bar",
|
||
+ "search": "",
|
||
+ "hash": ""
|
||
+ },
|
||
+ "# percent encoded hosts in non-special-URLs",
|
||
+ {
|
||
+ "input": "non-special://%E2%80%A0/",
|
||
+ "base": "about:blank",
|
||
+ "href": "non-special://%E2%80%A0/",
|
||
+ "protocol": "non-special:",
|
||
+ "username": "",
|
||
+ "password": "",
|
||
+ "host": "%E2%80%A0",
|
||
+ "hostname": "%E2%80%A0",
|
||
+ "port": "",
|
||
+ "pathname": "/",
|
||
+ "search": "",
|
||
+ "hash": ""
|
||
+ },
|
||
+ {
|
||
+ "input": "non-special://H%4fSt/path",
|
||
+ "base": "about:blank",
|
||
+ "href": "non-special://H%4fSt/path",
|
||
+ "protocol": "non-special:",
|
||
+ "username": "",
|
||
+ "password": "",
|
||
+ "host": "H%4fSt",
|
||
+ "hostname": "H%4fSt",
|
||
+ "port": "",
|
||
+ "pathname": "/path",
|
||
+ "search": "",
|
||
+ "hash": ""
|
||
+ },
|
||
+ "# IPv6 in non-special-URLs",
|
||
+ {
|
||
+ "input": "non-special://[1:2:0:0:5:0:0:0]/",
|
||
+ "base": "about:blank",
|
||
+ "href": "non-special://[1:2:0:0:5::]/",
|
||
+ "protocol": "non-special:",
|
||
+ "username": "",
|
||
+ "password": "",
|
||
+ "host": "[1:2:0:0:5::]",
|
||
+ "hostname": "[1:2:0:0:5::]",
|
||
+ "port": "",
|
||
+ "pathname": "/",
|
||
+ "search": "",
|
||
+ "hash": ""
|
||
+ },
|
||
+ {
|
||
+ "input": "non-special://[1:2:0:0:0:0:0:3]/",
|
||
+ "base": "about:blank",
|
||
+ "href": "non-special://[1:2::3]/",
|
||
+ "protocol": "non-special:",
|
||
+ "username": "",
|
||
+ "password": "",
|
||
+ "host": "[1:2::3]",
|
||
+ "hostname": "[1:2::3]",
|
||
+ "port": "",
|
||
+ "pathname": "/",
|
||
+ "search": "",
|
||
+ "hash": ""
|
||
+ },
|
||
+ {
|
||
+ "input": "non-special://[1:2::3]:80/",
|
||
+ "base": "about:blank",
|
||
+ "href": "non-special://[1:2::3]:80/",
|
||
+ "protocol": "non-special:",
|
||
+ "username": "",
|
||
+ "password": "",
|
||
+ "host": "[1:2::3]:80",
|
||
+ "hostname": "[1:2::3]",
|
||
+ "port": "80",
|
||
+ "pathname": "/",
|
||
+ "search": "",
|
||
+ "hash": ""
|
||
+ },
|
||
+ {
|
||
+ "input": "non-special://[:80/",
|
||
+ "base": "about:blank",
|
||
+ "failure": true
|
||
+ },
|
||
+ {
|
||
+ "input": "blob:https://example.com:443/",
|
||
+ "base": "about:blank",
|
||
+ "href": "blob:https://example.com:443/",
|
||
+ "protocol": "blob:",
|
||
+ "username": "",
|
||
+ "password": "",
|
||
+ "host": "",
|
||
+ "hostname": "",
|
||
+ "port": "",
|
||
+ "pathname": "https://example.com:443/",
|
||
+ "search": "",
|
||
+ "hash": ""
|
||
+ },
|
||
+ {
|
||
+ "input": "blob:d3958f5c-0777-0845-9dcf-2cb28783acaf",
|
||
+ "base": "about:blank",
|
||
+ "href": "blob:d3958f5c-0777-0845-9dcf-2cb28783acaf",
|
||
+ "protocol": "blob:",
|
||
+ "username": "",
|
||
+ "password": "",
|
||
+ "host": "",
|
||
+ "hostname": "",
|
||
+ "port": "",
|
||
+ "pathname": "d3958f5c-0777-0845-9dcf-2cb28783acaf",
|
||
+ "search": "",
|
||
+ "hash": ""
|
||
+ },
|
||
+ "Invalid IPv4 radix digits",
|
||
+ {
|
||
+ "input": "http://0177.0.0.0189",
|
||
+ "base": "about:blank",
|
||
+ "href": "http://0177.0.0.0189/",
|
||
"protocol": "http:",
|
||
"username": "",
|
||
"password": "",
|
||
- "host": "[fe80:cd00::1257:0:211e:729c]",
|
||
- "hostname": "[fe80:cd00::1257:0:211e:729c]",
|
||
+ "host": "0177.0.0.0189",
|
||
+ "hostname": "0177.0.0.0189",
|
||
"port": "",
|
||
"pathname": "/",
|
||
"search": "",
|
||
- "searchParams": "",
|
||
"hash": ""
|
||
},
|
||
- "# IPv6 compression and serialization: Compress longest sequence of zeroes",
|
||
{
|
||
- "input": "http://[fe80:0:0:1257:0:0:0:cd00]/",
|
||
+ "input": "http://0x7f.0.0.0x7g",
|
||
"base": "about:blank",
|
||
- "href": "http://[fe80:0:0:1257::cd00]/",
|
||
- "origin": "http://[fe80:0:0:1257::cd00]",
|
||
+ "href": "http://0x7f.0.0.0x7g/",
|
||
"protocol": "http:",
|
||
"username": "",
|
||
"password": "",
|
||
- "host": "[fe80:0:0:1257::cd00]",
|
||
- "hostname": "[fe80:0:0:1257::cd00]",
|
||
+ "host": "0x7f.0.0.0x7g",
|
||
+ "hostname": "0x7f.0.0.0x7g",
|
||
"port": "",
|
||
"pathname": "/",
|
||
"search": "",
|
||
- "searchParams": "",
|
||
"hash": ""
|
||
},
|
||
- "# IPv6 compression and serialization: Do not compress lone zeroes",
|
||
{
|
||
- "input": "http://[fe80:cd00:0:cde:1257:0:211e:729c]/",
|
||
+ "input": "http://0X7F.0.0.0X7G",
|
||
"base": "about:blank",
|
||
- "href": "http://[fe80:cd00:0:cde:1257:0:211e:729c]/",
|
||
- "origin": "http://[fe80:cd00:0:cde:1257:0:211e:729c]",
|
||
+ "href": "http://0x7f.0.0.0x7g/",
|
||
"protocol": "http:",
|
||
"username": "",
|
||
"password": "",
|
||
- "host": "[fe80:cd00:0:cde:1257:0:211e:729c]",
|
||
- "hostname": "[fe80:cd00:0:cde:1257:0:211e:729c]",
|
||
+ "host": "0x7f.0.0.0x7g",
|
||
+ "hostname": "0x7f.0.0.0x7g",
|
||
"port": "",
|
||
"pathname": "/",
|
||
"search": "",
|
||
- "searchParams": "",
|
||
"hash": ""
|
||
+ },
|
||
+ "Invalid IPv4 portion of IPv6 address",
|
||
+ {
|
||
+ "input": "http://[::127.0.0.0.1]",
|
||
+ "base": "about:blank",
|
||
+ "failure": true
|
||
+ },
|
||
+ "Uncompressed IPv6 addresses with 0",
|
||
+ {
|
||
+ "input": "http://[0:1:0:1:0:1:0:1]",
|
||
+ "base": "about:blank",
|
||
+ "href": "http://[0:1:0:1:0:1:0:1]/",
|
||
+ "protocol": "http:",
|
||
+ "username": "",
|
||
+ "password": "",
|
||
+ "host": "[0:1:0:1:0:1:0:1]",
|
||
+ "hostname": "[0:1:0:1:0:1:0:1]",
|
||
+ "port": "",
|
||
+ "pathname": "/",
|
||
+ "search": "",
|
||
+ "hash": ""
|
||
+ },
|
||
+ {
|
||
+ "input": "http://[1:0:1:0:1:0:1:0]",
|
||
+ "base": "about:blank",
|
||
+ "href": "http://[1:0:1:0:1:0:1:0]/",
|
||
+ "protocol": "http:",
|
||
+ "username": "",
|
||
+ "password": "",
|
||
+ "host": "[1:0:1:0:1:0:1:0]",
|
||
+ "hostname": "[1:0:1:0:1:0:1:0]",
|
||
+ "port": "",
|
||
+ "pathname": "/",
|
||
+ "search": "",
|
||
+ "hash": ""
|
||
+ },
|
||
+ "Percent-encoded query and fragment",
|
||
+ {
|
||
+ "input": "http://example.org/test?\u0022",
|
||
+ "base": "about:blank",
|
||
+ "href": "http://example.org/test?%22",
|
||
+ "protocol": "http:",
|
||
+ "username": "",
|
||
+ "password": "",
|
||
+ "host": "example.org",
|
||
+ "hostname": "example.org",
|
||
+ "port": "",
|
||
+ "pathname": "/test",
|
||
+ "search": "?%22",
|
||
+ "hash": ""
|
||
+ },
|
||
+ {
|
||
+ "input": "http://example.org/test?\u0023",
|
||
+ "base": "about:blank",
|
||
+ "href": "http://example.org/test?#",
|
||
+ "protocol": "http:",
|
||
+ "username": "",
|
||
+ "password": "",
|
||
+ "host": "example.org",
|
||
+ "hostname": "example.org",
|
||
+ "port": "",
|
||
+ "pathname": "/test",
|
||
+ "search": "",
|
||
+ "hash": ""
|
||
+ },
|
||
+ {
|
||
+ "input": "http://example.org/test?\u003C",
|
||
+ "base": "about:blank",
|
||
+ "href": "http://example.org/test?%3C",
|
||
+ "protocol": "http:",
|
||
+ "username": "",
|
||
+ "password": "",
|
||
+ "host": "example.org",
|
||
+ "hostname": "example.org",
|
||
+ "port": "",
|
||
+ "pathname": "/test",
|
||
+ "search": "?%3C",
|
||
+ "hash": ""
|
||
+ },
|
||
+ {
|
||
+ "input": "http://example.org/test?\u003E",
|
||
+ "base": "about:blank",
|
||
+ "href": "http://example.org/test?%3E",
|
||
+ "protocol": "http:",
|
||
+ "username": "",
|
||
+ "password": "",
|
||
+ "host": "example.org",
|
||
+ "hostname": "example.org",
|
||
+ "port": "",
|
||
+ "pathname": "/test",
|
||
+ "search": "?%3E",
|
||
+ "hash": ""
|
||
+ },
|
||
+ {
|
||
+ "input": "http://example.org/test?\u2323",
|
||
+ "base": "about:blank",
|
||
+ "href": "http://example.org/test?%E2%8C%A3",
|
||
+ "protocol": "http:",
|
||
+ "username": "",
|
||
+ "password": "",
|
||
+ "host": "example.org",
|
||
+ "hostname": "example.org",
|
||
+ "port": "",
|
||
+ "pathname": "/test",
|
||
+ "search": "?%E2%8C%A3",
|
||
+ "hash": ""
|
||
+ },
|
||
+ {
|
||
+ "input": "http://example.org/test?%23%23",
|
||
+ "base": "about:blank",
|
||
+ "href": "http://example.org/test?%23%23",
|
||
+ "protocol": "http:",
|
||
+ "username": "",
|
||
+ "password": "",
|
||
+ "host": "example.org",
|
||
+ "hostname": "example.org",
|
||
+ "port": "",
|
||
+ "pathname": "/test",
|
||
+ "search": "?%23%23",
|
||
+ "hash": ""
|
||
+ },
|
||
+ {
|
||
+ "input": "http://example.org/test?%GH",
|
||
+ "base": "about:blank",
|
||
+ "href": "http://example.org/test?%GH",
|
||
+ "protocol": "http:",
|
||
+ "username": "",
|
||
+ "password": "",
|
||
+ "host": "example.org",
|
||
+ "hostname": "example.org",
|
||
+ "port": "",
|
||
+ "pathname": "/test",
|
||
+ "search": "?%GH",
|
||
+ "hash": ""
|
||
+ },
|
||
+ {
|
||
+ "input": "http://example.org/test?a#%EF",
|
||
+ "base": "about:blank",
|
||
+ "href": "http://example.org/test?a#%EF",
|
||
+ "protocol": "http:",
|
||
+ "username": "",
|
||
+ "password": "",
|
||
+ "host": "example.org",
|
||
+ "hostname": "example.org",
|
||
+ "port": "",
|
||
+ "pathname": "/test",
|
||
+ "search": "?a",
|
||
+ "hash": "#%EF"
|
||
+ },
|
||
+ {
|
||
+ "input": "http://example.org/test?a#%GH",
|
||
+ "base": "about:blank",
|
||
+ "href": "http://example.org/test?a#%GH",
|
||
+ "protocol": "http:",
|
||
+ "username": "",
|
||
+ "password": "",
|
||
+ "host": "example.org",
|
||
+ "hostname": "example.org",
|
||
+ "port": "",
|
||
+ "pathname": "/test",
|
||
+ "search": "?a",
|
||
+ "hash": "#%GH"
|
||
+ },
|
||
+ "Bad bases",
|
||
+ {
|
||
+ "input": "test-a.html",
|
||
+ "base": "a",
|
||
+ "failure": true
|
||
+ },
|
||
+ {
|
||
+ "input": "test-a-slash.html",
|
||
+ "base": "a/",
|
||
+ "failure": true
|
||
+ },
|
||
+ {
|
||
+ "input": "test-a-slash-slash.html",
|
||
+ "base": "a//",
|
||
+ "failure": true
|
||
+ },
|
||
+ {
|
||
+ "input": "test-a-colon.html",
|
||
+ "base": "a:",
|
||
+ "failure": true
|
||
+ },
|
||
+ {
|
||
+ "input": "test-a-colon-slash.html",
|
||
+ "base": "a:/",
|
||
+ "href": "a:/test-a-colon-slash.html",
|
||
+ "protocol": "a:",
|
||
+ "username": "",
|
||
+ "password": "",
|
||
+ "host": "",
|
||
+ "hostname": "",
|
||
+ "port": "",
|
||
+ "pathname": "/test-a-colon-slash.html",
|
||
+ "search": "",
|
||
+ "hash": ""
|
||
+ },
|
||
+ {
|
||
+ "input": "test-a-colon-slash-slash.html",
|
||
+ "base": "a://",
|
||
+ "href": "a:///test-a-colon-slash-slash.html",
|
||
+ "protocol": "a:",
|
||
+ "username": "",
|
||
+ "password": "",
|
||
+ "host": "",
|
||
+ "hostname": "",
|
||
+ "port": "",
|
||
+ "pathname": "/test-a-colon-slash-slash.html",
|
||
+ "search": "",
|
||
+ "hash": ""
|
||
+ },
|
||
+ {
|
||
+ "input": "test-a-colon-b.html",
|
||
+ "base": "a:b",
|
||
+ "failure": true
|
||
+ },
|
||
+ {
|
||
+ "input": "test-a-colon-slash-b.html",
|
||
+ "base": "a:/b",
|
||
+ "href": "a:/test-a-colon-slash-b.html",
|
||
+ "protocol": "a:",
|
||
+ "username": "",
|
||
+ "password": "",
|
||
+ "host": "",
|
||
+ "hostname": "",
|
||
+ "port": "",
|
||
+ "pathname": "/test-a-colon-slash-b.html",
|
||
+ "search": "",
|
||
+ "hash": ""
|
||
+ },
|
||
+ {
|
||
+ "input": "test-a-colon-slash-slash-b.html",
|
||
+ "base": "a://b",
|
||
+ "href": "a://b/test-a-colon-slash-slash-b.html",
|
||
+ "protocol": "a:",
|
||
+ "username": "",
|
||
+ "password": "",
|
||
+ "host": "b",
|
||
+ "hostname": "b",
|
||
+ "port": "",
|
||
+ "pathname": "/test-a-colon-slash-slash-b.html",
|
||
+ "search": "",
|
||
+ "hash": ""
|
||
+ },
|
||
+ "Null code point in fragment",
|
||
+ {
|
||
+ "input": "http://example.org/test?a#b\u0000c",
|
||
+ "base": "about:blank",
|
||
+ "href": "http://example.org/test?a#bc",
|
||
+ "protocol": "http:",
|
||
+ "username": "",
|
||
+ "password": "",
|
||
+ "host": "example.org",
|
||
+ "hostname": "example.org",
|
||
+ "port": "",
|
||
+ "pathname": "/test",
|
||
+ "search": "?a",
|
||
+ "hash": "#bc"
|
||
}
|
||
]
|
||
diff -u -r --new-file seamonkey-2.53.1.orig/mozilla/toolkit/library/rust/Cargo.lock seamonkey-2.53.1/mozilla/toolkit/library/rust/Cargo.lock
|
||
--- seamonkey-2.53.1.orig/mozilla/toolkit/library/rust/Cargo.lock 2020-02-17 17:39:43.000000000 -0600
|
||
+++ seamonkey-2.53.1/mozilla/toolkit/library/rust/Cargo.lock 2020-02-29 21:16:23.120772244 -0600
|
||
@@ -808,7 +808,7 @@
|
||
"libc 0.2.24 (registry+https://github.com/rust-lang/crates.io-index)",
|
||
"nserror 0.1.0",
|
||
"nsstring 0.1.0",
|
||
- "url 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||
+ "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||
]
|
||
|
||
[[package]]
|
||
@@ -1154,7 +1154,7 @@
|
||
|
||
[[package]]
|
||
name = "url"
|
||
-version = "1.5.1"
|
||
+version = "1.7.2"
|
||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||
dependencies = [
|
||
"idna 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||
@@ -1383,7 +1383,7 @@
|
||
"checksum unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "bf3a113775714a22dcb774d8ea3655c53a32debae63a063acc00a91cc586245f"
|
||
"checksum unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc"
|
||
"checksum unreachable 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1f2ae5ddb18e1c92664717616dd9549dde73f539f01bd7b77c2edb2446bdff91"
|
||
-"checksum url 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "eeb819346883532a271eb626deb43c4a1bb4c4dd47c519bd78137c3e72a4fe27"
|
||
+"checksum url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dd4e7c0d531266369519a4aa4f399d748bd37043b00bde1e4ff1f60a120b355a"
|
||
"checksum utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "662fab6525a98beff2921d7f61a39e7d59e0b425ebc7d0d9e66d316e55124122"
|
||
"checksum vec_map 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "887b5b631c2ad01628bbbaa7dd4c869f80d3186688f8d0b6f58774fbe324988c"
|
||
"checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
|