Patchwork D12607: censor: make rhg fall back to python when encountering a censored node

login
register
mail settings
Submitter phabricator
Date May 5, 2022, 2:40 p.m.
Message ID <differential-rev-PHID-DREV-6mh3bb47xkwgab7kdhky-req@mercurial-scm.org>
Download mbox | patch
Permalink /patch/50958/
State New
Headers show

Comments

phabricator - May 5, 2022, 2:40 p.m.
aalekseyev created this revision.
Herald added a reviewer: hg-reviewers.
Herald added a subscriber: mercurial-patches.

REVISION SUMMARY
  This is to make it support censor.policy=ignore without having
  to duplicate that logic.
  
  Also, change the censor test in such a way that it uses rhg now,
  because extensions are disabled except when we call [hg censor].

REPOSITORY
  rHG Mercurial

BRANCH
  default

REVISION DETAIL
  https://phab.mercurial-scm.org/D12607

AFFECTED FILES
  rust/hg-core/src/errors.rs
  rust/hg-core/src/revlog/revlog.rs
  rust/rhg/src/error.rs
  tests/test-censor.t

CHANGE DETAILS




To: aalekseyev, #hg-reviewers
Cc: mercurial-patches, mercurial-devel

Patch

diff --git a/tests/test-censor.t b/tests/test-censor.t
--- a/tests/test-censor.t
+++ b/tests/test-censor.t
@@ -10,10 +10,6 @@ 
 
 #endif
 
-  $ cat >> $HGRCPATH <<EOF
-  > [extensions]
-  > censor=
-  > EOF
   $ cp $HGRCPATH $HGRCPATH.orig
 
 Create repo with unimpeachable content
@@ -81,7 +77,7 @@ 
 (this also tests file pattern matching: path relative to cwd case)
 
   $ mkdir -p foo/bar/baz
-  $ hg --cwd foo/bar/baz censor -r $C2 -t "remove password" ../../../target
+  $ hg --config extensions.censor= --cwd foo/bar/baz censor -r $C2 -t "remove password" ../../../target
   $ hg cat -r $H1 target | head -n 10
   Tainted file is now sanitized
   $ hg cat -r $H2 target | head -n 10
@@ -99,7 +95,7 @@ 
 
 (this also tests file pattern matching: with 'path:' scheme)
 
-  $ hg --cwd foo/bar/baz censor -r $C1 path:target
+  $ hg --config extensions.censor= --cwd foo/bar/baz censor -r $C1 path:target
   $ hg cat -r $H1 target | head -n 10
   Tainted file is now sanitized
   $ hg cat -r $H2 target | head -n 10
@@ -242,7 +238,7 @@ 
   $ echo 'advanced head H1' > target
   $ hg ci -m 'advance head H1' target
   $ H1=`hg id --debug -i`
-  $ hg censor -r $C3 target
+  $ hg --config extensions.censor= censor -r $C3 target
   $ hg update -r $H2
   1 files updated, 0 files merged, 0 files removed, 0 files unresolved
   $ hg merge -r $C3
@@ -254,14 +250,14 @@ 
 
   $ hg update -C -r $H2
   1 files updated, 0 files merged, 0 files removed, 0 files unresolved
-  $ hg censor -r $H2 target
+  $ hg --config extensions.censor= censor -r $H2 target
   abort: cannot censor file in heads (78a8fc215e79)
   (clean/delete and commit first)
   [255]
   $ echo 'twiddling thumbs' > bystander
   $ hg ci -m 'bystander commit'
   $ H2=`hg id --debug -i`
-  $ hg censor -r "$H2^" target
+  $ hg --config extensions.censor= censor -r "$H2^" target
   abort: cannot censor file in heads (efbe78065929)
   (clean/delete and commit first)
   [255]
@@ -273,7 +269,7 @@ 
   $ H2=`hg id --debug -i`
   $ hg update -r "$H2^"
   1 files updated, 0 files merged, 0 files removed, 0 files unresolved
-  $ hg censor -r . target
+  $ hg --config extensions.censor= censor -r . target
   abort: cannot censor working directory
   (clean/delete/update first)
   [255]
@@ -286,7 +282,7 @@ 
   $ hg rm target
   $ hg ci -m 'delete target so it may be censored'
   $ H2=`hg id --debug -i`
-  $ hg censor -r $C4 target
+  $ hg --config extensions.censor= censor -r $C4 target
   $ hg cat -r $C4 target | head -n 10
   $ hg cat -r "$H2^^" target | head -n 10
   Tainted file now super sanitized
@@ -314,7 +310,7 @@ 
   $ hg revert -r "$H2^" target
   $ hg ci -m 'cleaned 100k passwords'
   $ H2=`hg id --debug -i`
-  $ hg censor -r $C5 target
+  $ hg --config extensions.censor= censor -r $C5 target
   $ hg cat -r $C5 target | head -n 10
   $ hg cat -r $H2 target | head -n 10
   fresh start
@@ -393,7 +389,7 @@ 
   $ CLEANREV=$H2
   $ hg cat -r $REV target | head -n 10
   Passwords: hunter2hunter2
-  $ hg censor -r $REV target
+  $ hg --config extensions.censor= censor -r $REV target
   $ hg cat -r $REV target | head -n 10
   $ hg cat -r $CLEANREV target | head -n 10
   Re-sanitized; nothing to see here
@@ -503,7 +499,7 @@ 
 Can import bundle where first revision of a file is censored
 
   $ hg init ../rinit
-  $ hg censor -r 0 target
+  $ hg --config extensions.censor= censor -r 0 target
   $ hg bundle -r 0 --base null ../rinit/initbundle
   1 changesets found
   $ cd ../rinit
@@ -553,7 +549,7 @@ 
 
   $ hg cat -r $B1 target | wc -l
    *50002 (re)
-  $ hg censor -r $B1 target
+  $ hg --config extensions.censor= censor -r $B1 target
   $ hg cat -r $B1 target | wc -l
    *0 (re)
 
diff --git a/rust/rhg/src/error.rs b/rust/rhg/src/error.rs
--- a/rust/rhg/src/error.rs
+++ b/rust/rhg/src/error.rs
@@ -73,6 +73,9 @@ 
             HgError::UnsupportedFeature(message) => {
                 CommandError::unsupported(message)
             }
+            HgError::CensoredNodeError => {
+                CommandError::unsupported("Encountered a censored node")
+            }
             HgError::Abort {
                 message,
                 detailed_exit_code,
diff --git a/rust/hg-core/src/revlog/revlog.rs b/rust/hg-core/src/revlog/revlog.rs
--- a/rust/hg-core/src/revlog/revlog.rs
+++ b/rust/hg-core/src/revlog/revlog.rs
@@ -378,7 +378,7 @@ 
         }
     }
 
-    pub fn is_cencored(&self) -> bool {
+    pub fn is_censored(&self) -> bool {
         (self.flags & REVISION_FLAG_CENSORED) != 0
     }
 
@@ -389,7 +389,7 @@ 
     }
 
     /// The data for this entry, after resolving deltas if any.
-    pub fn data(&self) -> Result<Cow<'a, [u8]>, HgError> {
+    pub fn rawdata(&self) -> Result<Cow<'a, [u8]>, HgError> {
         let mut entry = self.clone();
         let mut delta_chain = vec![];
 
@@ -414,6 +414,13 @@ 
             Revlog::build_data_from_deltas(entry, &delta_chain)?.into()
         };
 
+        Ok(data)
+    }
+
+    fn check_data(
+        &self,
+        data: Cow<'a, [u8]>,
+    ) -> Result<Cow<'a, [u8]>, HgError> {
         if self.revlog.check_hash(
             self.p1,
             self.p2,
@@ -426,6 +433,14 @@ 
         }
     }
 
+    pub fn data(&self) -> Result<Cow<'a, [u8]>, HgError> {
+        let data = self.rawdata()?;
+        if self.is_censored() {
+          return Err(HgError::CensoredNodeError)
+        }
+        self.check_data(data)
+    }
+
     /// Extract the data contained in the entry.
     /// This may be a delta. (See `is_delta`.)
     fn data_chunk(&self) -> Result<Cow<'a, [u8]>, HgError> {
diff --git a/rust/hg-core/src/errors.rs b/rust/hg-core/src/errors.rs
--- a/rust/hg-core/src/errors.rs
+++ b/rust/hg-core/src/errors.rs
@@ -42,6 +42,9 @@ 
     /// and syntax of each value.
     #[from]
     ConfigValueParseError(ConfigValueParseError),
+
+    /// Censored revision data.
+    CensoredNodeError,
 }
 
 /// Details about where an I/O error happened
@@ -101,6 +104,9 @@ 
             HgError::UnsupportedFeature(explanation) => {
                 write!(f, "unsupported feature: {}", explanation)
             }
+            HgError::CensoredNodeError => {
+                write!(f, "encountered a censored node")
+            }
             HgError::ConfigValueParseError(error) => error.fmt(f),
         }
     }