diff --git a/src/cargo/ops/cargo_package.rs b/src/cargo/ops/cargo_package.rs index 9678dd4d368..1d7af7bf813 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..57a3af87e48 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) -> 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)?; + if n == 0 { + break; + } + hasher.write(&buf[..n]); + } + Ok(hasher.finish()) +} + pub fn short_hash(hashable: &H) -> String { to_hex(hash_u64(hashable)) }