diff options
author | Georg Brandl <georg@python.org> | 2019-05-06 07:42:02 +0200 |
---|---|---|
committer | Georg Brandl <georg@python.org> | 2019-05-06 07:42:02 +0200 |
commit | deea374f51f82b1ea16b27df3dce1749be93f614 (patch) | |
tree | 2204585abebf3a19310e4e843df1c8f2f8240511 /pygments | |
parent | 249e5feec73189cfff3a4c81d6a6c9fc821286cd (diff) | |
download | pygments-deea374f51f82b1ea16b27df3dce1749be93f614.tar.gz |
Never pop all states from the stack, even if a lexer wants to.
fixes #1506
Diffstat (limited to 'pygments')
-rw-r--r-- | pygments/lexer.py | 22 |
1 files changed, 16 insertions, 6 deletions
diff --git a/pygments/lexer.py b/pygments/lexer.py index 90905ba5..62d66318 100644 --- a/pygments/lexer.py +++ b/pygments/lexer.py @@ -639,14 +639,20 @@ class RegexLexer(Lexer): if isinstance(new_state, tuple): for state in new_state: if state == '#pop': - statestack.pop() + if len(statestack) > 1: + statestack.pop() elif state == '#push': statestack.append(statestack[-1]) else: statestack.append(state) elif isinstance(new_state, int): - # pop - del statestack[new_state:] + # pop, but keep at least one state on the stack + # (random code leading to unexpected pops should + # not allow exceptions) + if abs(new_state) >= len(statestack): + del statestack[1:] + else: + del statestack[new_state:] elif new_state == '#push': statestack.append(statestack[-1]) else: @@ -724,14 +730,18 @@ class ExtendedRegexLexer(RegexLexer): if isinstance(new_state, tuple): for state in new_state: if state == '#pop': - ctx.stack.pop() + if len(ctx.stack) > 1: + ctx.stack.pop() elif state == '#push': ctx.stack.append(ctx.stack[-1]) else: ctx.stack.append(state) elif isinstance(new_state, int): - # pop - del ctx.stack[new_state:] + # see RegexLexer for why this check is made + if abs(new_state) >= len(ctx.stack): + del ctx.state[1:] + else: + del ctx.stack[new_state:] elif new_state == '#push': ctx.stack.append(ctx.stack[-1]) else: |