Parcourir la source

Fix a lifetime bug uncovered by NLL, thanks @lqd

Simon Sapin il y a 8 ans
Parent
commit
5852553035
3 fichiers modifiés avec 16 ajouts et 6 suppressions
  1. 1 1
      Cargo.toml
  2. 10 2
      src/form_urlencoded.rs
  3. 5 3
      src/lib.rs

+ 1 - 1
Cargo.toml

@@ -2,7 +2,7 @@
 
 name = "url"
 # When updating version, also modify html_root_url in the lib.rs
-version = "1.6.0"
+version = "1.6.1"
 authors = ["The rust-url developers"]
 
 description = "URL library for Rust, based on the WHATWG URL Standard"

+ 10 - 2
src/form_urlencoded.rs

@@ -257,8 +257,16 @@ impl<'a> Target for &'a mut String {
 // * `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;
 }
 

+ 5 - 3
src/lib.rs

@@ -1304,7 +1304,7 @@ impl Url {
             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())
     }
 
@@ -2373,13 +2373,15 @@ fn io_error<T>(reason: &str) -> io::Result<T> {
 /// 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())
+        }
     }
 }