[PATCH 3 of 5] registrar: define revsetpredicate to decorate revset predicate

Yuya Nishihara yuya at tcha.org
Thu Jan 7 09:01:57 CST 2016


On Tue, 05 Jan 2016 20:48:36 +0900, FUJIWARA Katsunori wrote:
> # HG changeset patch
> # User FUJIWARA Katsunori <foozy at lares.dti.ne.jp>
> # Date 1451994203 -32400
> #      Tue Jan 05 20:43:23 2016 +0900
> # Node ID c6554052f10db3a9312b17c658bf8c579198a5d2
> # Parent  de07b46cc5de1baa86d40492941fd56c849311c3
> registrar: define revsetpredicate to decorate revset predicate
> 
> 'revsetpredicate' is used to replace 'revset.predicate' and
> 'revset.extpredicate' in subsequent patches.
> 
> This patch also adds 'loadpredicate()' to revset, because this
> combination helps to figure out how the name of safe predicate is put
> into 'safesymbols'.
> 
> This patch still uses 'safesymbols' set to examine whether the
> predicate corresponded to the 'name' is safe from DoS attack or not,
> because just setting 'func._safe' property needs changes below for
> such examination.
> 
>   before:
>       name in revset.safesymbols
> 
>   after:
>       getattr(revset.symbols.get(name, None), '_safe', False)
> 
> diff --git a/mercurial/registrar.py b/mercurial/registrar.py
> --- a/mercurial/registrar.py
> +++ b/mercurial/registrar.py
> @@ -208,3 +208,30 @@ class funcregistrarbase(object):
>          """Execute exra setup for registered function, if needed
>          """
>          pass
> +
> +class revsetpredicate(funcregistrarbase):
> +    """Decorator to register revset predicate
> +
> +    Usage::
> +
> +        revsetpredicate = registrar.revsetpredicate()
> +
> +        @revsetpredicate('mypredicate(arg1, arg2[, arg3])')
> +        def mypredicatefunc(repo, subset, x):
> +            '''Explanation of this revset predicate ....
> +            '''
> +            pass
> +
> +    The first string argument is used also in online help.
> +
> +    Optional argument 'safe' indicates whether a predicate is safe for
> +    DoS attack (False by default).
> +
> +    'revsetpredicate' instance in example above can be used to
> +    decorate multiple functions.
> +    """
> +    getname = funcregistrarbase.parsefuncdecl
> +    formatdoc = "``%s``\n    %s"
> +
> +    def extrasetup(self, name, func, safe=False):
> +        func._safe = safe
> diff --git a/mercurial/revset.py b/mercurial/revset.py
> --- a/mercurial/revset.py
> +++ b/mercurial/revset.py
> @@ -3667,5 +3667,16 @@ def prettyformatset(revs):
>          p = q
>      return '\n'.join('  ' * l + s for l, s in lines)
>  
> +def loadpredicate(ui, extname, predicateobj):
> +    """Load revset predicates from specified predicateobj
> +    """
> +    if not isinstance(predicateobj, registrar.revsetpredicate):
> +        # extension may not know about recent 'revsetpredicate' naming rule
> +        return

This looks like a temporary workaround, but the next patch doesn't remove it.

> +    for name, func in predicateobj.table.iteritems():
> +        symbols[name] = func
> +        if func._safe:
> +            safesymbols.add(name)
> +
>  # tell hggettext to extract docstrings from these functions:
>  i18nfunctions = symbols.values()
> _______________________________________________
> Mercurial-devel mailing list
> Mercurial-devel at selenic.com
> https://selenic.com/mailman/listinfo/mercurial-devel


More information about the Mercurial-devel mailing list