slackware-current/source/xap/seamonkey/seamonkey.rust14x.diff
Patrick J Volkerding 11403357f2 Mon Mar 2 19:05:10 UTC 2020
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.
2020-03-03 08:59:49 +01:00

4279 lines
131 KiB
Diff
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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 URLs 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": "Cant 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 its 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 its 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://.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://",
@@ -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"