From f3339b0906669e2619edf7c14a3328d83a2879f6 Mon Sep 17 00:00:00 2001 From: Sei Lisa Date: Sun, 27 Jul 2014 18:42:55 +0200 Subject: [PATCH] Fix an infinite recursion by disallowing forward globals in global var defs. --- lslopt/lsloptimizer.py | 5 ++--- lslopt/lslparse.py | 9 +++++++++ 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/lslopt/lsloptimizer.py b/lslopt/lsloptimizer.py index dcc8380..d66597b 100644 --- a/lslopt/lsloptimizer.py +++ b/lslopt/lsloptimizer.py @@ -165,9 +165,8 @@ class optimizer(object): if self.globalmode: val = self.symtab[code[3]][code[2]][2] if val is not None: - # WARNING: Possible reference loop here - # TODO: Break reference loop by only accepting globals in order - # of definition during parsing. + # Infinite recursion is prevented at the parser level, by + # not allowing forward globals in global var definitions. self.FoldTree(val) if code[1] != 'key' and val is not None: code[:] = [CONSTANT, code[1], val] diff --git a/lslopt/lslparse.py b/lslopt/lslparse.py index f6dd885..e473e86 100644 --- a/lslopt/lslparse.py +++ b/lslopt/lslparse.py @@ -186,6 +186,8 @@ class parser(object): # return (symtab[symbol][1], symtab[symbol][3]) return symtab[symbol][1] scope = symtab[-1] + if self.globalmode and symbol not in self.symtab[0]: + return None # Disallow forwards in global var mode if symbol not in self.globals: return None return self.globals[symbol] @@ -1464,7 +1466,9 @@ class parser(object): if self.tok[0] == '=': self.NextToken() if self.extendedglobalexpr: + self.globalmode = True # Var def. Disallow forward globals. value = tuple(self.Parse_expression()) # Use advanced expression evaluation. + self.globalmode = False # Allow forward globals again. else: value = self.Parse_simple_expr() # Use LSL's dull global expression. self.expect(';') @@ -1713,6 +1717,11 @@ class parser(object): self.dictorder = 0 + # This is a small hack to prevent circular definitions in globals when + # extended expressions are enabled. When false (default), forward + # globals are allowed; if true, only already seen globals are permitted. + self.globalmode = False + # Globals and labels can be referenced before they are defined. That # includes states. #