From bdec8c23923dc25b11b2dcad08a7f52f752a0008 Mon Sep 17 00:00:00 2001 From: Hanif Bin Ariffin Date: Thu, 27 Feb 2020 16:44:50 -0500 Subject: [PATCH 1/3] Fixes issue #7543 Added a helper function for util::hex::hash_64 that uses streams the content instead of reading through the entire content in one go. --- src/cargo/ops/cargo_package.rs | 4 ++-- src/cargo/util/hex.rs | 15 +++++++++++++++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/cargo/ops/cargo_package.rs b/src/cargo/ops/cargo_package.rs index 9678dd4d368..d57016ff9c5 100644 --- a/src/cargo/ops/cargo_package.rs +++ b/src/cargo/ops/cargo_package.rs @@ -746,8 +746,8 @@ fn hash_all(path: &Path) -> CargoResult> { let entry = entry?; let file_type = entry.file_type(); if file_type.is_file() { - let contents = fs::read(entry.path())?; - let hash = util::hex::hash_u64(&contents); + let file = File::open(entry.path())?; + let hash = util::hex::hash_u64_file(&file); result.insert(entry.path().to_path_buf(), hash); } else if file_type.is_symlink() { let hash = util::hex::hash_u64(&fs::read_link(entry.path())?); diff --git a/src/cargo/util/hex.rs b/src/cargo/util/hex.rs index f3e905c9aba..daa707ddbb7 100644 --- a/src/cargo/util/hex.rs +++ b/src/cargo/util/hex.rs @@ -1,6 +1,8 @@ #![allow(deprecated)] +use std::fs::File; use std::hash::{Hash, Hasher, SipHasher}; +use std::io::Read; pub fn to_hex(num: u64) -> String { hex::encode(&[ @@ -21,6 +23,19 @@ pub fn hash_u64(hashable: H) -> u64 { hasher.finish() } +pub fn hash_u64_file(mut file: &File) -> u64 { + let mut hasher = SipHasher::new_with_keys(0, 0); + let mut buf = [0; 64 * 1024]; + loop { + let n = file.read(&mut buf).unwrap(); + if n == 0 { + break; + } + hasher.write(&buf); + } + hasher.finish() +} + pub fn short_hash(hashable: &H) -> String { to_hex(hash_u64(hashable)) } From c3997d62d4979e9166fe71c5a5cbeedeb58d8cd0 Mon Sep 17 00:00:00 2001 From: Hanif Bin Ariffin Date: Thu, 27 Feb 2020 17:14:24 -0500 Subject: [PATCH 2/3] Fix erronous error with call to write --- src/cargo/util/hex.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cargo/util/hex.rs b/src/cargo/util/hex.rs index daa707ddbb7..15258e2d185 100644 --- a/src/cargo/util/hex.rs +++ b/src/cargo/util/hex.rs @@ -31,7 +31,7 @@ pub fn hash_u64_file(mut file: &File) -> u64 { if n == 0 { break; } - hasher.write(&buf); + hasher.write(&buf[..n]); } hasher.finish() } From 0ac7aeea98567e9cd0b19ed9c832c73c9778b417 Mon Sep 17 00:00:00 2001 From: Hanif Bin Ariffin Date: Thu, 27 Feb 2020 17:30:19 -0500 Subject: [PATCH 3/3] hash_u64_file now returns an Error instead of panicking. --- src/cargo/ops/cargo_package.rs | 2 +- src/cargo/util/hex.rs | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/cargo/ops/cargo_package.rs b/src/cargo/ops/cargo_package.rs index d57016ff9c5..1d7af7bf813 100644 --- a/src/cargo/ops/cargo_package.rs +++ b/src/cargo/ops/cargo_package.rs @@ -747,7 +747,7 @@ fn hash_all(path: &Path) -> CargoResult> { let file_type = entry.file_type(); if file_type.is_file() { let file = File::open(entry.path())?; - let hash = util::hex::hash_u64_file(&file); + let hash = util::hex::hash_u64_file(&file)?; result.insert(entry.path().to_path_buf(), hash); } else if file_type.is_symlink() { let hash = util::hex::hash_u64(&fs::read_link(entry.path())?); diff --git a/src/cargo/util/hex.rs b/src/cargo/util/hex.rs index 15258e2d185..57a3af87e48 100644 --- a/src/cargo/util/hex.rs +++ b/src/cargo/util/hex.rs @@ -23,17 +23,17 @@ pub fn hash_u64(hashable: H) -> u64 { hasher.finish() } -pub fn hash_u64_file(mut file: &File) -> u64 { +pub fn hash_u64_file(mut file: &File) -> std::io::Result { let mut hasher = SipHasher::new_with_keys(0, 0); let mut buf = [0; 64 * 1024]; loop { - let n = file.read(&mut buf).unwrap(); + let n = file.read(&mut buf)?; if n == 0 { break; } hasher.write(&buf[..n]); } - hasher.finish() + Ok(hasher.finish()) } pub fn short_hash(hashable: &H) -> String {