From patchwork Mon Sep 28 13:48:31 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: D9100: hg-core: return `Err` on decompression error (D8958#inline-15004 followup) From: phabricator X-Patchwork-Id: 47315 Message-Id: To: Phabricator Cc: mercurial-devel@mercurial-scm.org Date: Mon, 28 Sep 2020 13:48:31 +0000 acezar created this revision. Herald added a reviewer: hg-reviewers. Herald added a subscriber: mercurial-patches. REPOSITORY rHG Mercurial BRANCH default REVISION DETAIL https://phab.mercurial-scm.org/D9100 AFFECTED FILES rust/hg-core/src/revlog/revlog.rs CHANGE DETAILS To: acezar, #hg-reviewers Cc: mercurial-patches, mercurial-devel diff --git a/rust/hg-core/src/revlog/revlog.rs b/rust/hg-core/src/revlog/revlog.rs --- a/rust/hg-core/src/revlog/revlog.rs +++ b/rust/hg-core/src/revlog/revlog.rs @@ -247,38 +247,45 @@ // Raw revision data follows. b'u' => Ok(Cow::Borrowed(&self.bytes[1..])), // zlib (RFC 1950) data. - b'x' => Ok(Cow::Owned(self.uncompressed_zlib_data())), + b'x' => Ok(Cow::Owned(self.uncompressed_zlib_data()?)), // zstd data. - b'\x28' => Ok(Cow::Owned(self.uncompressed_zstd_data())), + b'\x28' => Ok(Cow::Owned(self.uncompressed_zstd_data()?)), format_type => Err(RevlogError::UnknowDataFormat(format_type)), } } - fn uncompressed_zlib_data(&self) -> Vec { + fn uncompressed_zlib_data(&self) -> Result, RevlogError> { let mut decoder = ZlibDecoder::new(self.bytes); if self.is_delta() { let mut buf = Vec::with_capacity(self.compressed_len); - decoder.read_to_end(&mut buf).expect("corrupted zlib data"); - buf + decoder + .read_to_end(&mut buf) + .map_err(|_| RevlogError::Corrupted)?; + Ok(buf) } else { let mut buf = vec![0; self.uncompressed_len]; - decoder.read_exact(&mut buf).expect("corrupted zlib data"); - buf + decoder + .read_exact(&mut buf) + .map_err(|_| RevlogError::Corrupted)?; + Ok(buf) } } - fn uncompressed_zstd_data(&self) -> Vec { + fn uncompressed_zstd_data(&self) -> Result, RevlogError> { if self.is_delta() { let mut buf = Vec::with_capacity(self.compressed_len); zstd::stream::copy_decode(self.bytes, &mut buf) - .expect("corrupted zstd data"); - buf + .map_err(|_| RevlogError::Corrupted)?; + Ok(buf) } else { let mut buf = vec![0; self.uncompressed_len]; let len = zstd::block::decompress_to_buffer(self.bytes, &mut buf) - .expect("corrupted zstd data"); - assert_eq!(len, self.uncompressed_len, "corrupted zstd data"); - buf + .map_err(|_| RevlogError::Corrupted)?; + if len != self.uncompressed_len { + Err(RevlogError::Corrupted) + } else { + Ok(buf) + } } }