diff --git a/lib/src/backend.rs b/lib/src/backend.rs index 902a2cd69..c154d60b0 100644 --- a/lib/src/backend.rs +++ b/lib/src/backend.rs @@ -173,6 +173,16 @@ content_hash! { #[derive(Debug, Error, PartialEq, Eq)] pub enum BackendError { + #[error( + "Invalid hash for object of type {object_type}: {hash} (expected {expected} bytes, got \ + {actual} bytes)" + )] + InvalidHashLength { + expected: usize, + actual: usize, + object_type: &'static str, + hash: String, + }, #[error("Object not found")] NotFound, #[error("Error: {0}")] diff --git a/lib/src/git_backend.rs b/lib/src/git_backend.rs index 13909f918..e561cc47c 100644 --- a/lib/src/git_backend.rs +++ b/lib/src/git_backend.rs @@ -180,7 +180,12 @@ impl Backend for GitBackend { fn read_file(&self, _path: &RepoPath, id: &FileId) -> BackendResult> { if id.as_bytes().len() != self.hash_length() { - return Err(BackendError::NotFound); + return Err(BackendError::InvalidHashLength { + expected: self.hash_length(), + actual: id.as_bytes().len(), + object_type: "file", + hash: id.hex(), + }); } let locked_repo = self.repo.lock().unwrap(); let blob = locked_repo @@ -200,7 +205,12 @@ impl Backend for GitBackend { fn read_symlink(&self, _path: &RepoPath, id: &SymlinkId) -> Result { if id.as_bytes().len() != self.hash_length() { - return Err(BackendError::NotFound); + return Err(BackendError::InvalidHashLength { + expected: self.hash_length(), + actual: id.as_bytes().len(), + object_type: "symlink", + hash: id.hex(), + }); } let locked_repo = self.repo.lock().unwrap(); let blob = locked_repo @@ -229,7 +239,12 @@ impl Backend for GitBackend { return Ok(Tree::default()); } if id.as_bytes().len() != self.hash_length() { - return Err(BackendError::NotFound); + return Err(BackendError::InvalidHashLength { + expected: self.hash_length(), + actual: id.as_bytes().len(), + object_type: "tree", + hash: id.hex(), + }); } let locked_repo = self.repo.lock().unwrap(); @@ -348,7 +363,12 @@ impl Backend for GitBackend { fn read_commit(&self, id: &CommitId) -> BackendResult { if id.as_bytes().len() != self.hash_length() { - return Err(BackendError::NotFound); + return Err(BackendError::InvalidHashLength { + expected: self.hash_length(), + actual: id.as_bytes().len(), + object_type: "commit", + hash: id.hex(), + }); } if *id == self.root_commit_id { diff --git a/lib/src/revset.rs b/lib/src/revset.rs index f0d18dbb1..f1c432950 100644 --- a/lib/src/revset.rs +++ b/lib/src/revset.rs @@ -86,6 +86,9 @@ fn resolve_full_commit_id( symbol: &str, ) -> Result>, RevsetError> { if let Ok(binary_commit_id) = hex::decode(symbol) { + if repo.store().hash_length() != binary_commit_id.len() { + return Ok(None); + } let commit_id = CommitId::new(binary_commit_id); match repo.store().get_commit(&commit_id) { Ok(_) => Ok(Some(vec![commit_id])),