rust-revlog: fix RevlogEntry.data() for NULL_REVISION stable
authorGeorges Racinet <georges.racinet@octobus.net>
Thu, 06 Jul 2023 11:53:40 +0200
branchstable
changeset 50746 124c44b5cfad
parent 50745 3338c6ffdaa3
child 50747 9865af7191d2
rust-revlog: fix RevlogEntry.data() for NULL_REVISION Before this change, the pseudo-entry returned by `Revlog.get_entry` for `NULL_REVISION` would trigger errors in application code using it. For example, this fixes a crash spotted with changelog data while implementing RHGitaly: `Changelog.data_for_rev(-1)` was already returning the pseudo content as expected, e.g., for `hg log`, but `Changelog.entry_for_rev(-1).data()` would still crash with "corrupted revlog, hash check failed for revision -1". There is an added test for this scenario.
rust/hg-core/src/revlog/changelog.rs
rust/hg-core/src/revlog/mod.rs
--- a/rust/hg-core/src/revlog/changelog.rs	Thu Jul 06 11:43:26 2023 +0200
+++ b/rust/hg-core/src/revlog/changelog.rs	Thu Jul 06 11:53:40 2023 +0200
@@ -336,6 +336,11 @@
             changelog.data_for_rev(NULL_REVISION)?,
             ChangelogRevisionData::null()
         );
+        // same with the intermediate entry object
+        assert_eq!(
+            changelog.entry_for_rev(NULL_REVISION)?.data()?,
+            ChangelogRevisionData::null()
+        );
         Ok(())
     }
 }
--- a/rust/hg-core/src/revlog/mod.rs	Thu Jul 06 11:43:26 2023 +0200
+++ b/rust/hg-core/src/revlog/mod.rs	Thu Jul 06 11:53:40 2023 +0200
@@ -562,6 +562,9 @@
 
     pub fn data(&self) -> Result<Cow<'revlog, [u8]>, HgError> {
         let data = self.rawdata()?;
+        if self.rev == NULL_REVISION {
+            return Ok(data);
+        }
         if self.is_censored() {
             return Err(HgError::CensoredNodeError);
         }
@@ -688,6 +691,9 @@
             revlog.rev_from_node(NULL_NODE.into()).unwrap(),
             NULL_REVISION
         );
+        let null_entry = revlog.get_entry(NULL_REVISION).ok().unwrap();
+        assert_eq!(null_entry.revision(), NULL_REVISION);
+        assert!(null_entry.data().unwrap().is_empty());
     }
 
     #[test]