[PATCH 4 of 4 censor RFC] revlog: in addgroup, reject ill-formed deltas based on censored nodes

Augie Fackler raf at durin42.com
Tue Feb 10 13:29:03 CST 2015


On Thu, Feb 05, 2015 at 10:57:50PM -0500, Mike Edgar wrote:
> # HG changeset patch
> # User Mike Edgar <adgar at google.com>
> # Date 1423184129 0
> #      Fri Feb 06 00:55:29 2015 +0000
> # Node ID 3da291d69e2c1eefddbf1366538d7404ebaa022d
> # Parent  95ed0ff48518b8390eb084e8efb9e647516a0b8d
> revlog: in addgroup, reject ill-formed deltas based on censored nodes

These are queued, since they appear to be fairly straighforward. Thanks!

>
> To ensure interoperability when clones disagree about which file nodes are
> censored, a restriction is made on deltas based on censored nodes. Any such
> delta must replace the full text of the base in a single patch.
>
> If the recipient of a delta considers the base to be censored and the delta
> is not in the expected form, the recipient must reject it, as it can't know
> if the source has also censored the base.
>
> For background and broader design of the censorship feature, see:
> http://mercurial.selenic.com/wiki/CensorPlan
>
> diff -r 95ed0ff48518 -r 3da291d69e2c mercurial/changegroup.py
> --- a/mercurial/changegroup.py	Wed Jan 21 16:35:09 2015 -0500
> +++ b/mercurial/changegroup.py	Fri Feb 06 00:55:29 2015 +0000
> @@ -659,8 +659,11 @@
>          pr()
>          fl = repo.file(f)
>          o = len(fl)
> -        if not fl.addgroup(source, revmap, trp):
> -            raise util.Abort(_("received file revlog group is empty"))
> +        try:
> +            if not fl.addgroup(source, revmap, trp):
> +                raise util.Abort(_("received file revlog group is empty"))
> +        except error.CensoredBaseError, e:
> +            raise util.Abort(_("received delta base is censored: %s") % e)
>          revisions += len(fl) - o
>          files += 1
>          if f in needfiles:
> diff -r 95ed0ff48518 -r 3da291d69e2c mercurial/error.py
> --- a/mercurial/error.py	Wed Jan 21 16:35:09 2015 -0500
> +++ b/mercurial/error.py	Fri Feb 06 00:55:29 2015 +0000
> @@ -139,3 +139,11 @@
>      def __init__(self, filename, node):
>          from node import short
>          RevlogError.__init__(self, '%s:%s' % (filename, short(node)))
> +
> +class CensoredBaseError(RevlogError):
> +    """error raised when a delta is rejected because its base is censored
> +
> +    A delta based on a censored revision must be formed as single patch
> +    operation which replaces the entire base with new content. This ensures
> +    the delta may be applied by clones which have not censored the base.
> +    """
> diff -r 95ed0ff48518 -r 3da291d69e2c mercurial/revlog.py
> --- a/mercurial/revlog.py	Wed Jan 21 16:35:09 2015 -0500
> +++ b/mercurial/revlog.py	Fri Feb 06 00:55:29 2015 +0000
> @@ -1401,6 +1401,17 @@
>                                        _('unknown delta base'))
>
>                  baserev = self.rev(deltabase)
> +
> +                if baserev != nullrev and self.iscensored(baserev):
> +                    # if base is censored, delta must be full replacement in a
> +                    # single patch operation
> +                    hlen = struct.calcsize(">lll")
> +                    oldlen = self.rawsize(baserev)
> +                    newlen = len(delta) - hlen
> +                    if delta[:hlen] != mdiff.replacediffheader(oldlen, newlen):
> +                        raise error.CensoredBaseError(self.indexfile,
> +                                                      self.node(baserev))
> +
>                  chain = self._addrevision(node, None, transaction, link,
>                                            p1, p2, REVIDX_DEFAULT_FLAGS,
>                                            (baserev, delta), ifh, dfh)
> _______________________________________________
> Mercurial-devel mailing list
> Mercurial-devel at selenic.com
> http://selenic.com/mailman/listinfo/mercurial-devel


More information about the Mercurial-devel mailing list