Mercurial > public > mercurial-scm > hg-stable
comparison rust/hg-core/src/revlog/revlog.rs @ 48572:0a4ac916673e
rhg: RevlogEntry::uncompressed_len is signed
The corresponding Python code appears to explicitly check for non-negative values.
Differential Revision: https://phab.mercurial-scm.org/D11962
author | Simon Sapin <simon.sapin@octobus.net> |
---|---|
date | Tue, 21 Dec 2021 21:23:46 +0100 |
parents | 35c47015b9b7 |
children | faa243f345cc |
comparison
equal
deleted
inserted
replaced
48571:35c47015b9b7 | 48572:0a4ac916673e |
---|---|
1 use std::borrow::Cow; | 1 use std::borrow::Cow; |
2 use std::convert::TryFrom; | |
2 use std::io::Read; | 3 use std::io::Read; |
3 use std::ops::Deref; | 4 use std::ops::Deref; |
4 use std::path::Path; | 5 use std::path::Path; |
5 | 6 |
6 use flate2::read::ZlibDecoder; | 7 use flate2::read::ZlibDecoder; |
257 let index_entry = self | 258 let index_entry = self |
258 .index | 259 .index |
259 .get_entry(rev) | 260 .get_entry(rev) |
260 .ok_or(RevlogError::InvalidRevision)?; | 261 .ok_or(RevlogError::InvalidRevision)?; |
261 let start = index_entry.offset(); | 262 let start = index_entry.offset(); |
262 let end = start + index_entry.compressed_len(); | 263 let end = start + index_entry.compressed_len() as usize; |
263 let data = if self.index.is_inline() { | 264 let data = if self.index.is_inline() { |
264 self.index.data(start, end) | 265 self.index.data(start, end) |
265 } else { | 266 } else { |
266 &self.data()[start..end] | 267 &self.data()[start..end] |
267 }; | 268 }; |
298 #[derive(Clone)] | 299 #[derive(Clone)] |
299 pub struct RevlogEntry<'a> { | 300 pub struct RevlogEntry<'a> { |
300 revlog: &'a Revlog, | 301 revlog: &'a Revlog, |
301 rev: Revision, | 302 rev: Revision, |
302 bytes: &'a [u8], | 303 bytes: &'a [u8], |
303 compressed_len: usize, | 304 compressed_len: u32, |
304 uncompressed_len: usize, | 305 uncompressed_len: i32, |
305 base_rev_or_base_of_delta_chain: Option<Revision>, | 306 base_rev_or_base_of_delta_chain: Option<Revision>, |
306 } | 307 } |
307 | 308 |
308 impl<'a> RevlogEntry<'a> { | 309 impl<'a> RevlogEntry<'a> { |
309 pub fn revision(&self) -> Revision { | 310 pub fn revision(&self) -> Revision { |
310 self.rev | 311 self.rev |
312 } | |
313 | |
314 pub fn uncompressed_len(&self) -> Option<u32> { | |
315 u32::try_from(self.uncompressed_len).ok() | |
311 } | 316 } |
312 | 317 |
313 /// The data for this entry, after resolving deltas if any. | 318 /// The data for this entry, after resolving deltas if any. |
314 pub fn data(&self) -> Result<Cow<'a, [u8]>, HgError> { | 319 pub fn data(&self) -> Result<Cow<'a, [u8]>, HgError> { |
315 let mut entry = self.clone(); | 320 let mut entry = self.clone(); |
377 } | 382 } |
378 | 383 |
379 fn uncompressed_zlib_data(&self) -> Result<Vec<u8>, HgError> { | 384 fn uncompressed_zlib_data(&self) -> Result<Vec<u8>, HgError> { |
380 let mut decoder = ZlibDecoder::new(self.bytes); | 385 let mut decoder = ZlibDecoder::new(self.bytes); |
381 if self.is_delta() { | 386 if self.is_delta() { |
382 let mut buf = Vec::with_capacity(self.compressed_len); | 387 let mut buf = Vec::with_capacity(self.compressed_len as usize); |
383 decoder.read_to_end(&mut buf).map_err(|_| corrupted())?; | 388 decoder.read_to_end(&mut buf).map_err(|_| corrupted())?; |
384 Ok(buf) | 389 Ok(buf) |
385 } else { | 390 } else { |
386 let mut buf = vec![0; self.uncompressed_len]; | 391 let cap = self.uncompressed_len.max(0) as usize; |
392 let mut buf = vec![0; cap]; | |
387 decoder.read_exact(&mut buf).map_err(|_| corrupted())?; | 393 decoder.read_exact(&mut buf).map_err(|_| corrupted())?; |
388 Ok(buf) | 394 Ok(buf) |
389 } | 395 } |
390 } | 396 } |
391 | 397 |
392 fn uncompressed_zstd_data(&self) -> Result<Vec<u8>, HgError> { | 398 fn uncompressed_zstd_data(&self) -> Result<Vec<u8>, HgError> { |
393 if self.is_delta() { | 399 if self.is_delta() { |
394 let mut buf = Vec::with_capacity(self.compressed_len); | 400 let mut buf = Vec::with_capacity(self.compressed_len as usize); |
395 zstd::stream::copy_decode(self.bytes, &mut buf) | 401 zstd::stream::copy_decode(self.bytes, &mut buf) |
396 .map_err(|_| corrupted())?; | 402 .map_err(|_| corrupted())?; |
397 Ok(buf) | 403 Ok(buf) |
398 } else { | 404 } else { |
399 let mut buf = vec![0; self.uncompressed_len]; | 405 let cap = self.uncompressed_len.max(0) as usize; |
406 let mut buf = vec![0; cap]; | |
400 let len = zstd::block::decompress_to_buffer(self.bytes, &mut buf) | 407 let len = zstd::block::decompress_to_buffer(self.bytes, &mut buf) |
401 .map_err(|_| corrupted())?; | 408 .map_err(|_| corrupted())?; |
402 if len != self.uncompressed_len { | 409 if len != self.uncompressed_len as usize { |
403 Err(corrupted()) | 410 Err(corrupted()) |
404 } else { | 411 } else { |
405 Ok(buf) | 412 Ok(buf) |
406 } | 413 } |
407 } | 414 } |