Patchwork [3,of,4,censor,RFC] revlog: verify censored flag when hashing added revision fulltext

login
register
mail settings
Submitter adgar@google.com
Date Jan. 12, 2015, 9:08 p.m.
Message ID <14ac00cc2162fb0d933e.1421096899@adgar.nyc.corp.google.com>
Download mbox | patch
Permalink /patch/7445/
State Accepted
Commit 8a3c132f93d2dfbcfc9cc3f3fa57173f407370f1
Headers show

Comments

adgar@google.com - Jan. 12, 2015, 9:08 p.m.
# HG changeset patch
# User Mike Edgar <adgar@google.com>
# Date 1421091685 18000
#      Mon Jan 12 14:41:25 2015 -0500
# Node ID 14ac00cc2162fb0d933e334b08bccdc49012843c
# Parent  e00466845102181cc01816b2b06df8fe12cc5493
revlog: verify censored flag when hashing added revision fulltext

When receiving a delta via exchange, three possible storage outcomes emerge:

1. The delta is added directly to the revlog. ("fast-path")
2. A freshly-computed delta with a different base is stored.
3. The new revision's fulltext is computed and stored outright.

Both (2) and (3) require materializing the full text of the new revision by
applying the delta to its base. This is typically followed by a hash check.

The new flags argument allows callers to _addrevision to signal that they
expect that hash check to fail. We can use this opportunity to verify that
expectation. If the hash fails, require the flag be set; if the hash passes,
require the flag be unset.

Rather than simply eliding the hash check, this approach provides some
assurance that the censored flag is not applied to valid revisions.

Read more at: http://mercurial.selenic.com/wiki/CensorPlan

Patch

diff -r e00466845102 -r 14ac00cc2162 mercurial/revlog.py
--- a/mercurial/revlog.py	Mon Jan 12 14:30:24 2015 -0500
+++ b/mercurial/revlog.py	Mon Jan 12 14:41:25 2015 -0500
@@ -1235,8 +1235,12 @@ 
             btext[0] = mdiff.patch(basetext, cachedelta[1])
             try:
                 self.checkhash(btext[0], p1, p2, node)
+                if flags & REVIDX_ISCENSORED:
+                    raise RevlogError(_('node %s is not censored') % node)
             except CensoredNodeError:
-                pass # always import a censor tombstone.
+                # must pass the censored index flag to add censored revisions
+                if not flags & REVIDX_ISCENSORED:
+                    raise
             return btext[0]
 
         def builddelta(rev):