Bug 1511591 - Update rust-url to version 1.7.2 r=froydnj
authorValentin Gosu <valentin.gosu@gmail.com>
Sat, 01 Dec 2018 14:58:03 +0000
changeset 508335 93bdaf4be8e4042cadf8fddcc20d43155622474c
parent 508334 6060cddc780cb1e461841c1ad5ee363c6cd1470f
child 508378 8e021c409c6a16d9bab9713d20e30fa05c5b8365
push id1905
push userffxbld-merge
push dateMon, 21 Jan 2019 12:33:13 +0000
treeherdermozilla-release@c2fca1944d8c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersfroydnj
bugs1511591
milestone65.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1511591 - Update rust-url to version 1.7.2 r=froydnj Differential Revision: https://phabricator.services.mozilla.com/D13613
Cargo.lock
netwerk/base/mozurl/Cargo.toml
third_party/rust/url/.cargo-checksum.json
third_party/rust/url/Cargo.toml
third_party/rust/url/benches/parse_url.rs
third_party/rust/url/src/form_urlencoded.rs
third_party/rust/url/src/lib.rs
third_party/rust/url/src/parser.rs
third_party/rust/url/tests/data.rs
third_party/rust/url/tests/unit.rs
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1588,17 +1588,17 @@ dependencies = [
 ]
 
 [[package]]
 name = "mozurl"
 version = "0.0.1"
 dependencies = [
  "nserror 0.1.0",
  "nsstring 0.1.0",
- "url 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "xpcom 0.1.0",
 ]
 
 [[package]]
 name = "mozversion"
 version = "0.1.3"
 dependencies = [
  "regex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2073,17 +2073,17 @@ source = "registry+https://github.com/ru
 dependencies = [
  "arrayref 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "bincode 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "failure 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "lmdb-rkv 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "ordered-float 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
- "url 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "uuid 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "ron"
 version = "0.1.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
@@ -2837,17 +2837,17 @@ name = "unreachable"
 version = "1.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "url"
-version = "1.7.0"
+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)",
  "matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "percent-encoding 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -2916,17 +2916,17 @@ dependencies = [
  "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "regex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde 1.0.80 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_derive 1.0.80 (git+https://github.com/servo/serde?branch=deserialize_from_enums9)",
  "serde_json 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)",
  "time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
  "tokio 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "unicode-segmentation 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "url 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "webidl"
 version = "0.8.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "lalrpop 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -3381,17 +3381,17 @@ dependencies = [
 "checksum ucd-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fd2be2d6639d0f8fe6cdda291ad456e23629558d466e2789d2c3e9892bda285d"
 "checksum uluru 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d2606e9192f308ddc4f0b3c5d1bf3400e28a70fff956e9d9f46d23b094746d9f"
 "checksum unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5"
 "checksum unicode-normalization 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "51ccda9ef9efa3f7ef5d91e8f9b83bbe6955f9bf86aec89d5cce2c874625920f"
 "checksum unicode-segmentation 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "aa6024fc12ddfd1c6dbc14a80fa2324d4568849869b779f6bd37e5e4c03344d1"
 "checksum unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "bf3a113775714a22dcb774d8ea3655c53a32debae63a063acc00a91cc586245f"
 "checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
 "checksum unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56"
-"checksum url 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f808aadd8cfec6ef90e4a14eb46f24511824d1ac596b9682703c87056c8678b7"
+"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 uuid 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e1436e58182935dcd9ce0add9ea0b558e8a87befe01c1a301e6020aeb0876363"
 "checksum vcpkg 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9e0a7d8bed3178a8fb112199d466eeca9ed09a14ba8ad67718179b4fd5487d0b"
 "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"
 "checksum walkdir 2.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "63636bd0eb3d00ccb8b9036381b526efac53caf112b7783b730ab3f8e44da369"
 "checksum want 0.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "797464475f30ddb8830cc529aaaae648d581f99e2036a928877dfde027ddf6b3"
 "checksum wasmparser 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1b4e0f66e314a8e63ff5c3cc5103f7d0a3de9ee98bb61a960adcf7f1d9debd2f"
--- a/netwerk/base/mozurl/Cargo.toml
+++ b/netwerk/base/mozurl/Cargo.toml
@@ -1,10 +1,10 @@
 [package]
 name = "mozurl"
 version = "0.0.1"
 authors = ["Nika Layzell <nika@thelayzells.com>"]
 
 [dependencies]
-url = "1.5.1"
+url = "1.7.2"
 nsstring = { path = "../../../servo/support/gecko/nsstring" }
 nserror = { path = "../../../xpcom/rust/nserror" }
 xpcom = { path = "../../../xpcom/rust/xpcom" }
--- a/third_party/rust/url/.cargo-checksum.json
+++ b/third_party/rust/url/.cargo-checksum.json
@@ -1,1 +1,1 @@
-{"files":{"Cargo.toml":"0c9e7c23f4216471a535938d0babb4c30595c0ed747ef208da3f042027a3b55b","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"20c7855c364d57ea4c97889a5e8d98470a9952dade37bd9248b9a54431670e5e","README.md":"eb3f4694003f408cbe3c7f3e9fbbc71241defb940cc55a816981f0f0f144c8eb","UPGRADING.md":"fbcc2d39bdf17db0745793db6626fcd5c909dddd4ce13b27566cfabece22c368","appveyor.yml":"c78486dbfbe6ebbf3d808afb9a19f7ec18c4704ce451c6305f0716999b70a1a6","docs/404.html":"f61e6271c1ea1aa113b64b356e994595fa548f0433f89948d747503ad22195cd","docs/index.html":"f61e6271c1ea1aa113b64b356e994595fa548f0433f89948d747503ad22195cd","src/encoding.rs":"f3e109ca8ec5a9130da50cdfb3003530aedb6dd5a440f0790d76b71f6981119c","src/form_urlencoded.rs":"320418526c4564a4469581d426e7467bcefe504eecd098e1eb90a2663a75fd80","src/host.rs":"66a2c0c77a8add2da16bc690fbc82b130cf1367ac655fc36990a214e193a4d6c","src/lib.rs":"899d5741dc0da32cea327f11e10bd2f83722c854f946b7201aae4f6c12edc477","src/origin.rs":"6e4821eb9600a32ef54d05c8e1a7937f6d9b4dd1e3bda7f36c7988f6a2bef78b","src/parser.rs":"91882bcf1dc87c98b2849fe2cecfcbcfa9e478dd39e07b7c029269c98e613163","src/path_segments.rs":"7bd3142eaa568863ef44e2255c181239141f9eeee337f889b9ffaaeab4ca669d","src/quirks.rs":"6cf1697bad363532cbcc60917a9b126560ac3ab3e1a77da0abcf4f2a40c8233a","src/slicing.rs":"4e539886b23945a92094625f3e531a4bff40daa44240b5d19ee8577478c4f7fe","tests/data.rs":"e95a78cadbe156597938057b7048d0d0ac4d3568ca548c0658fbea88d71f2de1","tests/setters_tests.json":"08ddaa632ad19c81e83b904bfaa94bc971f26e2bdfcef27d2f93fd033ad57340","tests/unit.rs":"fb17881a57aab4d369cdbcbb4d062083fc2b80319187fe0040891d2830de22fe","tests/urltestdata.json":"1b0c7c727d8d7e79dfb0d0aa347ff05675ddb68bc4ead38f83fd8e89bc59cc32"},"package":"f808aadd8cfec6ef90e4a14eb46f24511824d1ac596b9682703c87056c8678b7"}
\ 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
--- a/third_party/rust/url/Cargo.toml
+++ b/third_party/rust/url/Cargo.toml
@@ -7,17 +7,17 @@
 #
 # 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"
-version = "1.7.0"
+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"
 readme = "README.md"
 keywords = ["url", "parser"]
 categories = ["parser-implementations", "web-programming", "encoding"]
 license = "MIT/Apache-2.0"
 repository = "https://github.com/servo/rust-url"
@@ -28,16 +28,20 @@ features = ["query_encoding"]
 test = false
 
 [[test]]
 name = "unit"
 
 [[test]]
 name = "data"
 harness = false
+
+[[bench]]
+name = "parse_url"
+harness = false
 [dependencies.encoding]
 version = "0.2"
 optional = true
 
 [dependencies.heapsize]
 version = ">=0.4.1, <0.5"
 optional = true
 
@@ -52,21 +56,24 @@ 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.2"
+version = "0.3"
 
 [dev-dependencies.serde_json]
 version = ">=0.6.1, <0.9"
 
 [features]
 heap_size = ["heapsize"]
 query_encoding = ["encoding"]
 [badges.appveyor]
new file mode 100644
--- /dev/null
+++ b/third_party/rust/url/benches/parse_url.rs
@@ -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);
--- a/third_party/rust/url/src/form_urlencoded.rs
+++ b/third_party/rust/url/src/form_urlencoded.rs
@@ -252,18 +252,26 @@ impl<'a> Target for &'a mut String {
 // * Its fields are private
 //   (and so can not be constructed with struct literal syntax outside of this crate),
 // * It has no constructor
 // * It is only visible (on the type level) to users in the return type of
 //   `Url::query_pairs_mut` which is `Serializer<UrlQuery>`
 // * `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;
 }
 
 impl<T: Target> Serializer<T> {
     /// Create a new `application/x-www-form-urlencoded` serializer for the given target.
     ///
     /// If the target is non-empty,
     /// its content is assumed to already be in `application/x-www-form-urlencoded` syntax.
--- a/third_party/rust/url/src/lib.rs
+++ b/third_party/rust/url/src/lib.rs
@@ -107,16 +107,17 @@ assert_eq!(css_url.as_str(), "http://ser
 #![doc(html_root_url = "https://docs.rs/url/1.7.0")]
 
 #[cfg(feature="rustc-serialize")] extern crate rustc_serialize;
 #[macro_use] extern crate matches;
 #[cfg(feature="serde")] extern crate serde;
 #[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, ViolationFn};
 use percent_encoding::{PATH_SEGMENT_ENCODE_SET, USERINFO_ENCODE_SET,
                        percent_encode, percent_decode, utf8_percent_encode};
@@ -1338,17 +1339,17 @@ impl Url {
             debug_assert!(self.byte_at(start) == b'?');
             query_start = start as usize;
         } else {
             query_start = self.serialization.len();
             self.query_start = Some(to_u32(query_start).unwrap());
             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())
     }
 
     fn take_after_path(&mut self) -> String {
         match (self.query_start, self.fragment_start) {
             (Some(i), _) | (None, Some(i)) => {
                 let after_path = self.slice(i..).to_owned();
                 self.serialization.truncate(i as usize);
@@ -2418,23 +2419,25 @@ fn file_url_segments_to_pathbuf_windows(
 
 fn io_error<T>(reason: &str) -> io::Result<T> {
     Err(io::Error::new(io::ErrorKind::InvalidData, reason))
 }
 
 /// 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())
+        }
     }
 }
 
 
 /// Define a new struct
 /// that implements the [`EncodeSet`](percent_encoding/trait.EncodeSet.html) trait,
 /// for use in [`percent_decode()`](percent_encoding/fn.percent_encode.html)
 /// and related functions.
--- a/third_party/rust/url/src/parser.rs
+++ b/third_party/rust/url/src/parser.rs
@@ -1,30 +1,38 @@
 // Copyright 2013-2016 The rust-url developers.
 //
 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#[allow(unused_imports, deprecated)]
 use std::ascii::AsciiExt;
+
 use std::error::Error;
 use std::fmt::{self, Formatter, Write};
 use std::str;
 
 use Url;
 use encoding::EncodingOverride;
 use host::{Host, HostInternal};
 use percent_encoding::{
     utf8_percent_encode, percent_encode,
     SIMPLE_ENCODE_SET, DEFAULT_ENCODE_SET, USERINFO_ENCODE_SET, QUERY_ENCODE_SET,
     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 {
     ($($name: ident => $description: expr,)+) => {
         /// Errors that can occur during parsing.
         #[derive(PartialEq, Eq, Clone, Copy, Debug)]
         pub enum ParseError {
             $(
@@ -1004,18 +1012,23 @@ impl<'a> Parser<'a> {
                     },
                     '?' | '#' if self.context == Context::UrlParser => {
                         input = input_before_c;
                         break
                     },
                     _ => {
                         self.check_url_code_point(c, &input);
                         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));
                         }
                     }
                 }
             }
             match &self.serialization[segment_start..] {
--- a/third_party/rust/url/tests/data.rs
+++ b/third_party/rust/url/tests/data.rs
@@ -4,17 +4,17 @@
 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
 //! Data-driven tests
 
 extern crate rustc_serialize;
-extern crate test;
+extern crate rustc_test as test;
 extern crate url;
 
 use rustc_serialize::json::{self, Json};
 use url::{Url, quirks};
 
 fn check_invariants(url: &Url) {
     url.check_invariants().unwrap();
     #[cfg(feature="serde")] {
--- a/third_party/rust/url/tests/unit.rs
+++ b/third_party/rust/url/tests/unit.rs
@@ -105,16 +105,27 @@ fn new_directory_paths() {
 
         let url = Url::from_directory_path(Path::new(r"C:\foo\bar")).unwrap();
         assert_eq!(url.host(), None);
         assert_eq!(url.path(), "/C:/foo/bar/");
     }
 }
 
 #[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());
 }
 
 #[test]
 fn parse_with_params() {
     let url = Url::parse_with_params("http://testing.com/this?dont=clobberme",
                                      &[("lang", "rust")]).unwrap();