Show More
@@ -49,18 +49,20 b' 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( |
|
52 | NodeMapError::RevisionNotInIndex(rev) => RevlogError::corrupted( | |
|
53 | format!("nodemap point to revision {} not in index", rev), | |||
|
54 | ), | |||
53 | } |
|
55 | } | |
54 | } |
|
56 | } | |
55 | } |
|
57 | } | |
56 |
|
58 | |||
57 | fn corrupted() -> HgError { |
|
59 | fn corrupted<S: AsRef<str>>(context: S) -> HgError { | |
58 | HgError::corrupted("corrupted revlog") |
|
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 | |||
@@ -329,7 +331,8 b' impl Revlog {' | |||||
329 | &self, |
|
331 | &self, | |
330 | rev: Revision, |
|
332 | rev: Revision, | |
331 | ) -> Result<RevlogEntry, HgError> { |
|
333 | ) -> Result<RevlogEntry, HgError> { | |
332 |
|
|
334 | self.get_entry(rev) | |
|
335 | .map_err(|_| corrupted(format!("revision {} out of range", rev))) | |||
333 | } |
|
336 | } | |
334 | } |
|
337 | } | |
335 |
|
338 | |||
@@ -449,7 +452,10 b" impl<'a> RevlogEntry<'a> {" | |||||
449 | ) { |
|
452 | ) { | |
450 | Ok(data) |
|
453 | Ok(data) | |
451 | } else { |
|
454 | } else { | |
452 |
Err(corrupted( |
|
455 | Err(corrupted(format!( | |
|
456 | "hash check failed for revision {}", | |||
|
457 | self.rev | |||
|
458 | ))) | |||
453 | } |
|
459 | } | |
454 | } |
|
460 | } | |
455 |
|
461 | |||
@@ -478,7 +484,10 b" impl<'a> RevlogEntry<'a> {" | |||||
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 |
|
|
487 | format_type => Err(corrupted(format!( | |
|
488 | "unknown compression header '{}'", | |||
|
489 | format_type | |||
|
490 | ))), | |||
482 | } |
|
491 | } | |
483 | } |
|
492 | } | |
484 |
|
493 | |||
@@ -486,12 +495,16 b" impl<'a> RevlogEntry<'a> {" | |||||
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 | } | |
@@ -500,15 +513,15 b" impl<'a> RevlogEntry<'a> {" | |||||
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(| |
|
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(| |
|
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 | } |
@@ -107,7 +107,10 b' py_class!(pub class MixedIndex |py| {' | |||||
107 | String::from_utf8_lossy(node.data(py)).to_string() |
|
107 | String::from_utf8_lossy(node.data(py)).to_string() | |
108 | }; |
|
108 | }; | |
109 |
|
109 | |||
110 |
let prefix = NodePrefix::from_hex(&node_as_string) |
|
110 | let prefix = NodePrefix::from_hex(&node_as_string) | |
|
111 | .map_err(|_| PyErr::new::<ValueError, _>( | |||
|
112 | py, format!("Invalid node or prefix '{}'", node_as_string)) | |||
|
113 | )?; | |||
111 |
|
114 | |||
112 | nt.find_bin(idx, prefix) |
|
115 | nt.find_bin(idx, prefix) | |
113 | // TODO make an inner API returning the node directly |
|
116 | // TODO make an inner API returning the node directly |
@@ -517,10 +517,13 b' fn unsure_is_modified(' | |||||
517 | } |
|
517 | } | |
518 | let filelog = repo.filelog(hg_path)?; |
|
518 | let filelog = repo.filelog(hg_path)?; | |
519 | let fs_len = fs_metadata.len(); |
|
519 | let fs_len = fs_metadata.len(); | |
520 |
let file |
|
520 | let file_node = entry.node_id()?; | |
521 |
|
|
521 | let filelog_entry = filelog.entry_for_node(file_node).map_err(|_| { | |
522 |
|
|
522 | HgError::corrupted(format!( | |
523 | })?; |
|
523 | "filelog missing node {:?} from manifest", | |
|
524 | file_node | |||
|
525 | )) | |||
|
526 | })?; | |||
524 | if filelog_entry.file_data_len_not_equal_to(fs_len) { |
|
527 | if filelog_entry.file_data_len_not_equal_to(fs_len) { | |
525 | // No need to read file contents: |
|
528 | // No need to read file contents: | |
526 | // it cannot be equal if it has a different length. |
|
529 | // it cannot be equal if it has a different length. |
General Comments 0
You need to be logged in to leave comments.
Login now