47 |
47 |
48 impl From<NodeMapError> for RevlogError { |
48 impl From<NodeMapError> for RevlogError { |
49 fn from(error: NodeMapError) -> Self { |
49 fn from(error: NodeMapError) -> Self { |
50 match error { |
50 match error { |
51 NodeMapError::MultipleResults => RevlogError::AmbiguousPrefix, |
51 NodeMapError::MultipleResults => RevlogError::AmbiguousPrefix, |
52 NodeMapError::RevisionNotInIndex(_) => RevlogError::corrupted(), |
52 NodeMapError::RevisionNotInIndex(rev) => RevlogError::corrupted( |
53 } |
53 format!("nodemap point to revision {} not in index", rev), |
54 } |
54 ), |
55 } |
55 } |
56 |
56 } |
57 fn corrupted() -> HgError { |
57 } |
58 HgError::corrupted("corrupted revlog") |
58 |
|
59 fn corrupted<S: AsRef<str>>(context: S) -> HgError { |
|
60 HgError::corrupted(format!("corrupted revlog, {}", context.as_ref())) |
59 } |
61 } |
60 |
62 |
61 impl RevlogError { |
63 impl RevlogError { |
62 fn corrupted() -> Self { |
64 fn corrupted<S: AsRef<str>>(context: S) -> Self { |
63 RevlogError::Other(corrupted()) |
65 RevlogError::Other(corrupted(context)) |
64 } |
66 } |
65 } |
67 } |
66 |
68 |
67 /// Read only implementation of revlog. |
69 /// Read only implementation of revlog. |
68 pub struct Revlog { |
70 pub struct Revlog { |
327 /// should be reported as corruption, instead of e.g. "invalid revision" |
329 /// should be reported as corruption, instead of e.g. "invalid revision" |
328 fn get_entry_internal( |
330 fn get_entry_internal( |
329 &self, |
331 &self, |
330 rev: Revision, |
332 rev: Revision, |
331 ) -> Result<RevlogEntry, HgError> { |
333 ) -> Result<RevlogEntry, HgError> { |
332 return self.get_entry(rev).map_err(|_| corrupted()); |
334 self.get_entry(rev) |
|
335 .map_err(|_| corrupted(format!("revision {} out of range", rev))) |
333 } |
336 } |
334 } |
337 } |
335 |
338 |
336 /// The revlog entry's bytes and the necessary informations to extract |
339 /// The revlog entry's bytes and the necessary informations to extract |
337 /// the entry's data. |
340 /// the entry's data. |
476 // zlib (RFC 1950) data. |
482 // zlib (RFC 1950) data. |
477 b'x' => Ok(Cow::Owned(self.uncompressed_zlib_data()?)), |
483 b'x' => Ok(Cow::Owned(self.uncompressed_zlib_data()?)), |
478 // zstd data. |
484 // zstd data. |
479 b'\x28' => Ok(Cow::Owned(self.uncompressed_zstd_data()?)), |
485 b'\x28' => Ok(Cow::Owned(self.uncompressed_zstd_data()?)), |
480 // A proper new format should have had a repo/store requirement. |
486 // A proper new format should have had a repo/store requirement. |
481 _format_type => Err(corrupted()), |
487 format_type => Err(corrupted(format!( |
|
488 "unknown compression header '{}'", |
|
489 format_type |
|
490 ))), |
482 } |
491 } |
483 } |
492 } |
484 |
493 |
485 fn uncompressed_zlib_data(&self) -> Result<Vec<u8>, HgError> { |
494 fn uncompressed_zlib_data(&self) -> Result<Vec<u8>, HgError> { |
486 let mut decoder = ZlibDecoder::new(self.bytes); |
495 let mut decoder = ZlibDecoder::new(self.bytes); |
487 if self.is_delta() { |
496 if self.is_delta() { |
488 let mut buf = Vec::with_capacity(self.compressed_len as usize); |
497 let mut buf = Vec::with_capacity(self.compressed_len as usize); |
489 decoder.read_to_end(&mut buf).map_err(|_| corrupted())?; |
498 decoder |
|
499 .read_to_end(&mut buf) |
|
500 .map_err(|e| corrupted(e.to_string()))?; |
490 Ok(buf) |
501 Ok(buf) |
491 } else { |
502 } else { |
492 let cap = self.uncompressed_len.max(0) as usize; |
503 let cap = self.uncompressed_len.max(0) as usize; |
493 let mut buf = vec![0; cap]; |
504 let mut buf = vec![0; cap]; |
494 decoder.read_exact(&mut buf).map_err(|_| corrupted())?; |
505 decoder |
|
506 .read_exact(&mut buf) |
|
507 .map_err(|e| corrupted(e.to_string()))?; |
495 Ok(buf) |
508 Ok(buf) |
496 } |
509 } |
497 } |
510 } |
498 |
511 |
499 fn uncompressed_zstd_data(&self) -> Result<Vec<u8>, HgError> { |
512 fn uncompressed_zstd_data(&self) -> Result<Vec<u8>, HgError> { |
500 if self.is_delta() { |
513 if self.is_delta() { |
501 let mut buf = Vec::with_capacity(self.compressed_len as usize); |
514 let mut buf = Vec::with_capacity(self.compressed_len as usize); |
502 zstd::stream::copy_decode(self.bytes, &mut buf) |
515 zstd::stream::copy_decode(self.bytes, &mut buf) |
503 .map_err(|_| corrupted())?; |
516 .map_err(|e| corrupted(e.to_string()))?; |
504 Ok(buf) |
517 Ok(buf) |
505 } else { |
518 } else { |
506 let cap = self.uncompressed_len.max(0) as usize; |
519 let cap = self.uncompressed_len.max(0) as usize; |
507 let mut buf = vec![0; cap]; |
520 let mut buf = vec![0; cap]; |
508 let len = zstd::block::decompress_to_buffer(self.bytes, &mut buf) |
521 let len = zstd::block::decompress_to_buffer(self.bytes, &mut buf) |
509 .map_err(|_| corrupted())?; |
522 .map_err(|e| corrupted(e.to_string()))?; |
510 if len != self.uncompressed_len as usize { |
523 if len != self.uncompressed_len as usize { |
511 Err(corrupted()) |
524 Err(corrupted("uncompressed length does not match")) |
512 } else { |
525 } else { |
513 Ok(buf) |
526 Ok(buf) |
514 } |
527 } |
515 } |
528 } |
516 } |
529 } |