mirror of
https://github.com/facebook/sapling.git
synced 2024-10-06 23:07:18 +03:00
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')]
This commit is contained in:
parent
554208ae8f
commit
1f60c51fa5
@ -231,6 +231,9 @@ def _recursivesymbolblocker(key):
|
||||
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 @@ class engine(object):
|
||||
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):
|
||||
|
@ -1053,6 +1053,12 @@ Check that recursive reference does not fall into RuntimeError (issue4758):
|
||||
abort: recursive reference 'foo' in template
|
||||
[255]
|
||||
|
||||
buildmap() -> gettemplate(), where no thunk was made:
|
||||
|
||||
$ hg log -T '{files % changeset}\n'
|
||||
abort: recursive reference 'changeset' in template
|
||||
[255]
|
||||
|
||||
not a recursion if a keyword of the same name exists:
|
||||
|
||||
$ cat << EOF > issue4758
|
||||
|
Loading…
Reference in New Issue
Block a user