Show More
@@ -83,7 +83,7 b' impl TruncatedTimestamp {' | |||||
83 | second_ambiguous, |
|
83 | second_ambiguous, | |
84 | }) |
|
84 | }) | |
85 | } else { |
|
85 | } else { | |
86 | Err(DirstateV2ParseError) |
|
86 | Err(DirstateV2ParseError::new("when reading datetime")) | |
87 | } |
|
87 | } | |
88 | } |
|
88 | } | |
89 |
|
89 |
@@ -463,7 +463,7 b" impl<'on_disk> DirstateMap<'on_disk> {" | |||||
463 | if let Some(data) = on_disk.get(..data_size) { |
|
463 | if let Some(data) = on_disk.get(..data_size) { | |
464 | Ok(on_disk::read(data, metadata)?) |
|
464 | Ok(on_disk::read(data, metadata)?) | |
465 | } else { |
|
465 | } else { | |
466 | Err(DirstateV2ParseError.into()) |
|
466 | Err(DirstateV2ParseError::new("not enough bytes on disk").into()) | |
467 | } |
|
467 | } | |
468 | } |
|
468 | } | |
469 |
|
469 |
@@ -175,11 +175,21 b' type OptPathSlice = PathSlice;' | |||||
175 | /// |
|
175 | /// | |
176 | /// This should only happen if Mercurial is buggy or a repository is corrupted. |
|
176 | /// This should only happen if Mercurial is buggy or a repository is corrupted. | |
177 | #[derive(Debug)] |
|
177 | #[derive(Debug)] | |
178 |
pub struct DirstateV2ParseError |
|
178 | pub struct DirstateV2ParseError { | |
|
179 | message: String, | |||
|
180 | } | |||
|
181 | ||||
|
182 | impl DirstateV2ParseError { | |||
|
183 | pub fn new<S: Into<String>>(message: S) -> Self { | |||
|
184 | Self { | |||
|
185 | message: message.into(), | |||
|
186 | } | |||
|
187 | } | |||
|
188 | } | |||
179 |
|
189 | |||
180 | impl From<DirstateV2ParseError> for HgError { |
|
190 | impl From<DirstateV2ParseError> for HgError { | |
181 |
fn from( |
|
191 | fn from(e: DirstateV2ParseError) -> Self { | |
182 | HgError::corrupted("dirstate-v2 parse error") |
|
192 | HgError::corrupted(format!("dirstate-v2 parse error: {}", e.message)) | |
183 | } |
|
193 | } | |
184 | } |
|
194 | } | |
185 |
|
195 | |||
@@ -262,13 +272,16 b" impl<'on_disk> Docket<'on_disk> {" | |||||
262 | pub fn read_docket( |
|
272 | pub fn read_docket( | |
263 | on_disk: &[u8], |
|
273 | on_disk: &[u8], | |
264 | ) -> Result<Docket<'_>, DirstateV2ParseError> { |
|
274 | ) -> Result<Docket<'_>, DirstateV2ParseError> { | |
265 | let (header, uuid) = |
|
275 | let (header, uuid) = DocketHeader::from_bytes(on_disk).map_err(|e| { | |
266 | DocketHeader::from_bytes(on_disk).map_err(|_| DirstateV2ParseError)?; |
|
276 | DirstateV2ParseError::new(format!("when reading docket, {}", e)) | |
|
277 | })?; | |||
267 | let uuid_size = header.uuid_size as usize; |
|
278 | let uuid_size = header.uuid_size as usize; | |
268 | if header.marker == *V2_FORMAT_MARKER && uuid.len() == uuid_size { |
|
279 | if header.marker == *V2_FORMAT_MARKER && uuid.len() == uuid_size { | |
269 | Ok(Docket { header, uuid }) |
|
280 | Ok(Docket { header, uuid }) | |
270 | } else { |
|
281 | } else { | |
271 |
Err(DirstateV2ParseError |
|
282 | Err(DirstateV2ParseError::new( | |
|
283 | "invalid format marker or uuid size", | |||
|
284 | )) | |||
272 | } |
|
285 | } | |
273 | } |
|
286 | } | |
274 |
|
287 | |||
@@ -281,14 +294,17 b" pub(super) fn read<'on_disk>(" | |||||
281 | map.dirstate_version = DirstateVersion::V2; |
|
294 | map.dirstate_version = DirstateVersion::V2; | |
282 | return Ok(map); |
|
295 | return Ok(map); | |
283 | } |
|
296 | } | |
284 | let (meta, _) = TreeMetadata::from_bytes(metadata) |
|
297 | let (meta, _) = TreeMetadata::from_bytes(metadata).map_err(|e| { | |
285 | .map_err(|_| DirstateV2ParseError)?; |
|
298 | DirstateV2ParseError::new(format!("when parsing tree metadata, {}", e)) | |
|
299 | })?; | |||
286 | let dirstate_map = DirstateMap { |
|
300 | let dirstate_map = DirstateMap { | |
287 | on_disk, |
|
301 | on_disk, | |
288 |
root: dirstate_map::ChildNodes::OnDisk( |
|
302 | root: dirstate_map::ChildNodes::OnDisk( | |
289 | on_disk, |
|
303 | read_nodes(on_disk, meta.root_nodes).map_err(|mut e| { | |
290 | meta.root_nodes, |
|
304 | e.message = format!("{}, when reading root notes", e.message); | |
291 | )?), |
|
305 | e | |
|
306 | })?, | |||
|
307 | ), | |||
292 | nodes_with_entry_count: meta.nodes_with_entry_count.get(), |
|
308 | nodes_with_entry_count: meta.nodes_with_entry_count.get(), | |
293 | nodes_with_copy_source_count: meta.nodes_with_copy_source_count.get(), |
|
309 | nodes_with_copy_source_count: meta.nodes_with_copy_source_count.get(), | |
294 | ignore_patterns_hash: meta.ignore_patterns_hash, |
|
310 | ignore_patterns_hash: meta.ignore_patterns_hash, | |
@@ -317,7 +333,7 b' impl Node {' | |||||
317 | .expect("dirstate-v2 base_name_start out of bounds"); |
|
333 | .expect("dirstate-v2 base_name_start out of bounds"); | |
318 | Ok(start) |
|
334 | Ok(start) | |
319 | } else { |
|
335 | } else { | |
320 | Err(DirstateV2ParseError) |
|
336 | Err(DirstateV2ParseError::new("not enough bytes for base name")) | |
321 | } |
|
337 | } | |
322 | } |
|
338 | } | |
323 |
|
339 | |||
@@ -571,11 +587,19 b' where' | |||||
571 | // `&[u8]` cannot occupy the entire addess space. |
|
587 | // `&[u8]` cannot occupy the entire addess space. | |
572 | let start = start.get().try_into().unwrap_or(std::usize::MAX); |
|
588 | let start = start.get().try_into().unwrap_or(std::usize::MAX); | |
573 | let len = len.try_into().unwrap_or(std::usize::MAX); |
|
589 | let len = len.try_into().unwrap_or(std::usize::MAX); | |
574 | on_disk |
|
590 | let bytes = match on_disk.get(start..) { | |
575 | .get(start..) |
|
591 | Some(bytes) => bytes, | |
576 | .and_then(|bytes| T::slice_from_bytes(bytes, len).ok()) |
|
592 | None => { | |
|
593 | return Err(DirstateV2ParseError::new( | |||
|
594 | "not enough bytes from disk", | |||
|
595 | )) | |||
|
596 | } | |||
|
597 | }; | |||
|
598 | T::slice_from_bytes(bytes, len) | |||
|
599 | .map_err(|e| { | |||
|
600 | DirstateV2ParseError::new(format!("when reading a slice, {}", e)) | |||
|
601 | }) | |||
577 | .map(|(slice, _rest)| slice) |
|
602 | .map(|(slice, _rest)| slice) | |
578 | .ok_or_else(|| DirstateV2ParseError) |
|
|||
579 | } |
|
603 | } | |
580 |
|
604 | |||
581 | pub(crate) fn for_each_tracked_path<'on_disk>( |
|
605 | pub(crate) fn for_each_tracked_path<'on_disk>( | |
@@ -583,8 +607,9 b" pub(crate) fn for_each_tracked_path<'on_" | |||||
583 | metadata: &[u8], |
|
607 | metadata: &[u8], | |
584 | mut f: impl FnMut(&'on_disk HgPath), |
|
608 | mut f: impl FnMut(&'on_disk HgPath), | |
585 | ) -> Result<(), DirstateV2ParseError> { |
|
609 | ) -> Result<(), DirstateV2ParseError> { | |
586 | let (meta, _) = TreeMetadata::from_bytes(metadata) |
|
610 | let (meta, _) = TreeMetadata::from_bytes(metadata).map_err(|e| { | |
587 | .map_err(|_| DirstateV2ParseError)?; |
|
611 | DirstateV2ParseError::new(format!("when parsing tree metadata, {}", e)) | |
|
612 | })?; | |||
588 | fn recur<'on_disk>( |
|
613 | fn recur<'on_disk>( | |
589 | on_disk: &'on_disk [u8], |
|
614 | on_disk: &'on_disk [u8], | |
590 | nodes: ChildNodes, |
|
615 | nodes: ChildNodes, |
General Comments 0
You need to be logged in to leave comments.
Login now