Mercurial > public > mercurial-scm > hg-stable
diff mercurial/templater.py @ 27940:cfe7da66f555 stable
templater: abort if infinite recursion detected while compiling
In this case, a template is parsed recursively with no thunk for lazy
evaluation. This patch prevents recursion by putting a dummy of the same name
into a cache that will be referenced while parsing if there's a recursion.
changeset = {files % changeset}\n
~~~~~~~~~
= [(_runrecursivesymbol, 'changeset')]
author | Yuya Nishihara <yuya@tcha.org> |
---|---|
date | Thu, 23 Jul 2015 23:41:29 +0900 |
parents | 7ed3a3c0cef1 |
children | 96f2d50fb9f6 |
line wrap: on
line diff
--- a/mercurial/templater.py Wed Jul 22 23:29:41 2015 +0900 +++ b/mercurial/templater.py Thu Jul 23 23:41:29 2015 +0900 @@ -231,6 +231,9 @@ raise error.Abort(_("recursive reference '%s' in template") % key) return showrecursion +def _runrecursivesymbol(context, mapping, key): + raise error.Abort(_("recursive reference '%s' in template") % key) + def runsymbol(context, mapping, key): v = mapping.get(key) if v is None: @@ -826,7 +829,13 @@ def _load(self, t): '''load, parse, and cache a template''' if t not in self._cache: - self._cache[t] = compiletemplate(self._loader(t), self) + # put poison to cut recursion while compiling 't' + self._cache[t] = [(_runrecursivesymbol, t)] + try: + self._cache[t] = compiletemplate(self._loader(t), self) + except: # re-raises + del self._cache[t] + raise return self._cache[t] def process(self, t, mapping):