Bug 1441204 - Upgrade zip crate from 0.3.1 to 0.3.3. r?maja_zf draft
authorAndreas Tolfsen <ato@sny.no>
Thu, 14 Jun 2018 12:57:36 -0700
changeset 807818 a42e6de60ed41d6049fb237a5a3fbfec0dd4b2cd
parent 807817 489658131076c0506f646bd7c1d04dff84ea5fd6
child 807819 137f120e74683e82cfcb1c400956b436118e4170
push id113223
push userbmo:ato@sny.no
push dateFri, 15 Jun 2018 20:32:16 +0000
reviewersmaja_zf
bugs1441204
milestone62.0a1
Bug 1441204 - Upgrade zip crate from 0.3.1 to 0.3.3. r?maja_zf MozReview-Commit-ID: LjzVBrGK4LM
Cargo.lock
third_party/rust/zip/.cargo-checksum.json
third_party/rust/zip/Cargo.toml
third_party/rust/zip/README.md
third_party/rust/zip/examples/extract.rs
third_party/rust/zip/src/read.rs
third_party/rust/zip/src/types.rs
third_party/rust/zip/src/write.rs
third_party/rust/zip/tests/data/mimetype.zip
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -789,17 +789,17 @@ dependencies = [
  "log 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "mozprofile 0.3.0",
  "mozrunner 0.6.1",
  "mozversion 0.1.3",
  "regex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)",
  "uuid 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)",
  "webdriver 0.35.1",
- "zip 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "zip 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "geckoservo"
 version = "0.0.1"
 dependencies = [
  "atomic_refcell 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "cssparser 0.23.9 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2498,17 +2498,17 @@ name = "yaml-rust"
 version = "0.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "linked-hash-map 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "zip"
-version = "0.3.1"
+version = "0.3.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "bzip2 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "flate2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "msdos_time 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "podio 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
@@ -2747,9 +2747,9 @@ dependencies = [
 "checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc"
 "checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
 "checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
 "checksum wincolor 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "eeb06499a3a4d44302791052df005d5232b927ed1a9658146d842165c4de7767"
 "checksum winreg 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9338067aba07889a38beaad4dbb77fa2e62e87c423b770824b3bdf412874bd2c"
 "checksum ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e"
 "checksum xml-rs 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3c1cb601d29fe2c2ac60a2b2e5e293994d87a1f6fa9687a31a15270f909be9c2"
 "checksum yaml-rust 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "57ab38ee1a4a266ed033496cf9af1828d8d6e6c1cfa5f643a2809effcae4d628"
-"checksum zip 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "10931e278527cea65682696481e6d840371d581079df529ebfee186e0eaad719"
+"checksum zip 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "77ce0ceee93c995954a31f77903925a6a8bb094709445238e344f2107910e29e"
--- a/third_party/rust/zip/.cargo-checksum.json
+++ b/third_party/rust/zip/.cargo-checksum.json
@@ -1,1 +1,1 @@
-{"files":{".travis.yml":"93ce7e20127d942fcf3a571d004e02a3b9ec38e98c71f32a561ce41b5c27f500","Cargo.toml":"d24868ffe67921dcb17f91d4e852b40a7948102c1c623364b95e9d03bf563d6b","LICENSE":"6ac8711fb340c62ce0a4ecd463342d3fa0e8e70de697c863a2e1c0c53006003c","README.md":"ddce51a28cf4477026c4e974c7e41191f84669000a0c9dd20a8ae887590849f4","appveyor.yml":"53ebe35598907954204812614a160355f36750ede4546bc69027cbaf7643d34c","examples/extract.rs":"9f6de63fb9077ed730a004bf18ef762e0d4e60b3332bfdba38b0f6eed490b33b","examples/extract_lorem.rs":"4e4e70927d2928a411ce4abe37ef4924c7156c4fd2697527c01fbd1797a76969","examples/write_dir.rs":"1a39da7b5d31997bf353a56d009ecdcf31da765f9ab191b20792e1904a594183","examples/write_sample.rs":"72a7c2db8074d20651ba04d0a49a7d6fb213ca674c63ab48db506deb69cba64c","script/doc-upload.cfg":"10684c8f5ef7e7388cfc4742ab9a060fe8f7fc1c51a63ede3c2443260ecc2d5e","src/compression.rs":"535e422f801caf53829014a0982698483c504da4082ebb571e468d4721d8434b","src/cp437.rs":"7954c5b7df6f72fe3fe2c377c5de09973c2fa704c7ae0274a5490594e4b69517","src/crc32.rs":"8b585059958a7150a4e40f0bd95198cc906385eb42468652f96e9d3294145b01","src/lib.rs":"15206ffb3612b4bbde73604ed2e194c4ced23487ffdefe01f42653bf1bdffff8","src/read.rs":"ecda9e85217ad3aa4dc8fe04a23ee043cba3fe8a1324e47788fd32642d220790","src/result.rs":"1006e46206a5b1491ed1d4fde0955a391df78cd42aa9582784b19170332a3783","src/spec.rs":"39b5e115745d962978e55ffb63ae2d62d0176c4c5ab457eea907a7aa33bf4e18","src/types.rs":"621a7a4eea9f740175bb804339cbe7fdd93a2e32b260c591d87ec0a702aa0d7f","src/write.rs":"7b6f312c8a5bcdd78f63bdf0787d0ca8b21a71d354cb9f2e34e1f2ce89f8662d","tests/data/invalid_offset.zip":"c5534a1803145f6344b04c437d436bd583852c78dd3937f4a73a2a39aa2d76b2","tests/data/mimetype.zip":"3e2cfc7af7a0e0f0b328885c57c0864c11a91da9c25b51be12d078af8b9ef6cf","tests/data/zip64_demo.zip":"223072a480f60d6a700e427b294e575ae2d6265f3e9881b647927f31d96c7e01","tests/invalid_date.rs":"e78b63b469d1f768bb452fefb84b013d3f9a4bf71dba2f9e12ff9e9c6ff8fd25"},"package":"10931e278527cea65682696481e6d840371d581079df529ebfee186e0eaad719"}
\ No newline at end of file
+{"files":{".travis.yml":"93ce7e20127d942fcf3a571d004e02a3b9ec38e98c71f32a561ce41b5c27f500","Cargo.toml":"b6f076a871f5bb585272bf3d458e789d89d5ad6723e152d49c07f99320c8a0ce","LICENSE":"6ac8711fb340c62ce0a4ecd463342d3fa0e8e70de697c863a2e1c0c53006003c","README.md":"8f548f0d5a9b2661839258c14a70284638fc4ce3017fc7ed2b9540ae3617ad2d","appveyor.yml":"53ebe35598907954204812614a160355f36750ede4546bc69027cbaf7643d34c","examples/extract.rs":"53b555617192330bd2f95235b82749905ad52617a5a3ba2648dbafbfff8a49a0","examples/extract_lorem.rs":"4e4e70927d2928a411ce4abe37ef4924c7156c4fd2697527c01fbd1797a76969","examples/write_dir.rs":"1a39da7b5d31997bf353a56d009ecdcf31da765f9ab191b20792e1904a594183","examples/write_sample.rs":"72a7c2db8074d20651ba04d0a49a7d6fb213ca674c63ab48db506deb69cba64c","script/doc-upload.cfg":"10684c8f5ef7e7388cfc4742ab9a060fe8f7fc1c51a63ede3c2443260ecc2d5e","src/compression.rs":"535e422f801caf53829014a0982698483c504da4082ebb571e468d4721d8434b","src/cp437.rs":"7954c5b7df6f72fe3fe2c377c5de09973c2fa704c7ae0274a5490594e4b69517","src/crc32.rs":"8b585059958a7150a4e40f0bd95198cc906385eb42468652f96e9d3294145b01","src/lib.rs":"15206ffb3612b4bbde73604ed2e194c4ced23487ffdefe01f42653bf1bdffff8","src/read.rs":"30ee981fcf690675d3f9c892b49e1a2539b4e9511d078d13e89686e3887f250f","src/result.rs":"1006e46206a5b1491ed1d4fde0955a391df78cd42aa9582784b19170332a3783","src/spec.rs":"39b5e115745d962978e55ffb63ae2d62d0176c4c5ab457eea907a7aa33bf4e18","src/types.rs":"4aca0943f436cf52d446e1ae65c078f349821936e25ecced332f660b95382d75","src/write.rs":"eb9f2ce88180a9ee80b28a92e40ffa70f50377d2b5cdcb0e6ce763edbf0fa703","tests/data/invalid_offset.zip":"c5534a1803145f6344b04c437d436bd583852c78dd3937f4a73a2a39aa2d76b2","tests/data/mimetype.zip":"4bc6fd161d3e844b3e2b7f10fd0f9077ff565bb39fd2bfa34e7f8e9cd62db06d","tests/data/zip64_demo.zip":"223072a480f60d6a700e427b294e575ae2d6265f3e9881b647927f31d96c7e01","tests/invalid_date.rs":"e78b63b469d1f768bb452fefb84b013d3f9a4bf71dba2f9e12ff9e9c6ff8fd25"},"package":"77ce0ceee93c995954a31f77903925a6a8bb094709445238e344f2107910e29e"}
\ No newline at end of file
--- a/third_party/rust/zip/Cargo.toml
+++ b/third_party/rust/zip/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 = "zip"
-version = "0.3.1"
+version = "0.3.3"
 authors = ["Mathijs van de Nes <git@mathijs.vd-nes.nl>"]
 description = "Library to support the reading and writing of zip files.\n"
 documentation = "http://mvdnes.github.io/rust-docs/zip-rs/zip/index.html"
 keywords = ["zip", "archive"]
 license = "MIT"
 repository = "https://github.com/mvdnes/zip-rs.git"
 [dependencies.bzip2]
 version = "0.3"
--- a/third_party/rust/zip/README.md
+++ b/third_party/rust/zip/README.md
@@ -43,11 +43,11 @@ Without the default features:
 zip = { version = "0.3", default-features = false }
 ```
 
 Examples
 --------
 
 See the [examples directory](examples) for:
    * How to write a file to a zip.
-   * how to write a directory of files to a zip (using [walkdir](/BurntSushi/walkdir)).
+   * how to write a directory of files to a zip (using [walkdir](https://github.com/BurntSushi/walkdir)).
    * How to extract a zip file.
    * How to extract a single file from a zip.
--- a/third_party/rust/zip/examples/extract.rs
+++ b/third_party/rust/zip/examples/extract.rs
@@ -15,17 +15,17 @@ fn real_main() -> i32 {
     }
     let fname = std::path::Path::new(&*args[1]);
     let file = fs::File::open(&fname).unwrap();
 
     let mut archive = zip::ZipArchive::new(file).unwrap();
 
     for i in 0..archive.len() {
         let mut file = archive.by_index(i).unwrap();
-        let outpath = sanitize_filename(file.name());
+        let outpath = file.sanitized_name();
 
         {
             let comment = file.comment();
             if !comment.is_empty() {
                 println!("File {} comment: {}", i, comment);
             }
         }
 
@@ -50,26 +50,8 @@ fn real_main() -> i32 {
 
             if let Some(mode) = file.unix_mode() {
                 fs::set_permissions(&outpath, fs::Permissions::from_mode(mode)).unwrap();
             }
         }
     }
     return 0;
 }
-
-fn sanitize_filename(filename: &str) -> std::path::PathBuf {
-    let no_null_filename = match filename.find('\0') {
-        Some(index) => &filename[0..index],
-        None => filename,
-    };
-
-    std::path::Path::new(no_null_filename)
-        .components()
-        .filter(|component| match *component {
-            std::path::Component::Normal(..) => true,
-            _ => false,
-        })
-        .fold(std::path::PathBuf::new(), |mut path, ref cur| {
-            path.push(cur.as_os_str());
-            path
-        })
-}
--- a/third_party/rust/zip/src/read.rs
+++ b/third_party/rust/zip/src/read.rs
@@ -410,16 +410,21 @@ impl<'a> ZipFile<'a> {
     /// Get the name of the file
     pub fn name(&self) -> &str {
         &*self.data.file_name
     }
     /// Get the name of the file, in the raw (internal) byte representation.
     pub fn name_raw(&self) -> &[u8] {
         &*self.data.file_name_raw
     }
+    /// Get the name of the file in a sanitized form. It truncates the name to the first NULL byte,
+    /// removes a leading '/' and removes '..' parts.
+    pub fn sanitized_name(&self) -> ::std::path::PathBuf {
+        self.data.file_name_sanitized()
+    }
     /// Get the comment of the file
     pub fn comment(&self) -> &str {
         &*self.data.file_comment
     }
     /// Get the compression method used to store the file
     pub fn compression(&self) -> CompressionMethod {
         self.data.compression_method
     }
--- a/third_party/rust/zip/src/types.rs
+++ b/third_party/rust/zip/src/types.rs
@@ -20,17 +20,17 @@ impl System {
         match system {
             0 => Dos,
             3 => Unix,
             _ => Unknown,
         }
     }
 }
 
-pub const DEFAULT_VERSION: u8 = 20;
+pub const DEFAULT_VERSION: u8 = 46;
 
 /// Structure representing a ZIP file.
 #[derive(Debug)]
 pub struct ZipFileData
 {
     /// Compatibility of the file attribute information
     pub system: System,
     /// Specification version
@@ -56,19 +56,70 @@ pub struct ZipFileData
     /// Specifies where the local header of the file starts
     pub header_start: u64,
     /// Specifies where the compressed data of the file starts
     pub data_start: u64,
     /// External file attributes
     pub external_attributes: u32,
 }
 
+impl ZipFileData {
+    pub fn file_name_sanitized(&self) -> ::std::path::PathBuf {
+        let no_null_filename = match self.file_name.find('\0') {
+            Some(index) => &self.file_name[0..index],
+            None => &self.file_name,
+        };
+
+        ::std::path::Path::new(no_null_filename)
+            .components()
+            .filter(|component| match *component {
+                ::std::path::Component::Normal(..) => true,
+                _ => false,
+            })
+            .fold(::std::path::PathBuf::new(), |mut path, ref cur| {
+                path.push(cur.as_os_str());
+                path
+            })
+    }
+
+    pub fn version_needed(&self) -> u16 {
+        match self.compression_method {
+            #[cfg(feature = "bzip2")]
+            ::compression::CompressionMethod::Bzip2 => 46,
+            _ => 20,
+        }
+    }
+}
+
 #[cfg(test)]
 mod test {
     #[test]
     fn system() {
         use super::System;
         assert_eq!(System::Dos as u16, 0u16);
         assert_eq!(System::Unix as u16, 3u16);
         assert_eq!(System::from_u8(0), System::Dos);
         assert_eq!(System::from_u8(3), System::Unix);
     }
+
+    #[test]
+    fn sanitize() {
+        use super::*;
+        let file_name = "/path/../../../../etc/./passwd\0/etc/shadow".to_string();
+        let data = ZipFileData {
+            system: System::Dos,
+            version_made_by: 0,
+            encrypted: false,
+            compression_method: ::compression::CompressionMethod::Stored,
+            last_modified_time: time::empty_tm(),
+            crc32: 0,
+            compressed_size: 0,
+            uncompressed_size: 0,
+            file_name: file_name.clone(),
+            file_name_raw: file_name.into_bytes(),
+            file_comment: String::new(),
+            header_start: 0,
+            data_start: 0,
+            external_attributes: 0,
+        };
+        assert_eq!(data.file_name_sanitized(), ::std::path::PathBuf::from("path/etc/passwd"));
+    }
 }
--- a/third_party/rust/zip/src/write.rs
+++ b/third_party/rust/zip/src/write.rs
@@ -419,18 +419,17 @@ impl<W: Write+io::Seek> GenericZipWriter
     }
 }
 
 fn write_local_file_header<T: Write>(writer: &mut T, file: &ZipFileData) -> ZipResult<()>
 {
     // local file header signature
     try!(writer.write_u32::<LittleEndian>(spec::LOCAL_FILE_HEADER_SIGNATURE));
     // version needed to extract
-    let version_made_by = (file.system as u16) << 8 | (file.version_made_by as u16);
-    try!(writer.write_u16::<LittleEndian>(version_made_by));
+    try!(writer.write_u16::<LittleEndian>(file.version_needed()));
     // general purpose bit flag
     let flag = if !file.file_name.is_ascii() { 1u16 << 11 } else { 0 };
     try!(writer.write_u16::<LittleEndian>(flag));
     // Compression method
     try!(writer.write_u16::<LittleEndian>(file.compression_method.to_u16()));
     // last mod file time and last mod file date
     let msdos_datetime = try!(file.last_modified_time.to_msdos());
     try!(writer.write_u16::<LittleEndian>(msdos_datetime.timepart));
@@ -467,17 +466,17 @@ fn update_local_file_header<T: Write+io:
 fn write_central_directory_header<T: Write>(writer: &mut T, file: &ZipFileData) -> ZipResult<()>
 {
     // central file header signature
     try!(writer.write_u32::<LittleEndian>(spec::CENTRAL_DIRECTORY_HEADER_SIGNATURE));
     // version made by
     let version_made_by = (file.system as u16) << 8 | (file.version_made_by as u16);
     try!(writer.write_u16::<LittleEndian>(version_made_by));
     // version needed to extract
-    try!(writer.write_u16::<LittleEndian>(20));
+    try!(writer.write_u16::<LittleEndian>(file.version_needed()));
     // general puprose bit flag
     let flag = if !file.file_name.is_ascii() { 1u16 << 11 } else { 0 };
     try!(writer.write_u16::<LittleEndian>(flag));
     // compression method
     try!(writer.write_u16::<LittleEndian>(file.compression_method.to_u16()));
     // last mod file time + date
     let msdos_datetime = try!(file.last_modified_time.to_msdos());
     try!(writer.write_u16::<LittleEndian>(msdos_datetime.timepart));
index d303463d84290caea2eebbb36d709a9739640e99..78f98224e8a226a235a08304f717015dfa97aef5
GIT binary patch
literal 159
zc$^FHW@Zs#fB;2?xMM~<>Od9<a{zH}W^QUpWkG6UK|xMta$-qlex80=UW#6RVsU1%
zUVcGpUP^v)X>Mv>iC#%+MM;1+Ba<F8ZsTBJNh1T2;Q`*PY#=@(5SjsLUm#{<sLCwR
HEh+{8)GQ!n