summaryrefslogtreecommitdiff
path: root/pygments
diff options
context:
space:
mode:
authorGeorg Brandl <georg@python.org>2019-05-06 07:42:02 +0200
committerGeorg Brandl <georg@python.org>2019-05-06 07:42:02 +0200
commitdeea374f51f82b1ea16b27df3dce1749be93f614 (patch)
tree2204585abebf3a19310e4e843df1c8f2f8240511 /pygments
parent249e5feec73189cfff3a4c81d6a6c9fc821286cd (diff)
downloadpygments-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.py22
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: