Skip to content

Commit

Permalink
[3.9] gh-91700: Validate the group number in conditional expression i…
Browse files Browse the repository at this point in the history
…n RE (GH-91702) (GH-91831) (GH-91836)

In expression (?(group)...) an appropriate re.error is now
raised if the group number refers to not defined group.

Previously it raised RuntimeError: invalid SRE code.
(cherry picked from commit 48ec61a)
(cherry picked from commit 080781c)

Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
  • Loading branch information
miss-islington and serhiy-storchaka committed Apr 22, 2022
1 parent 97d14e1 commit 76ff686
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 0 deletions.
10 changes: 10 additions & 0 deletions Lib/sre_parse.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ def __init__(self):
self.groupdict = {}
self.groupwidths = [None] # group 0
self.lookbehindgroups = None
self.grouprefpos = {}
@property
def groups(self):
return len(self.groupwidths)
Expand Down Expand Up @@ -786,6 +787,10 @@ def _parse(source, state, verbose, nested, first=False):
if condgroup >= MAXGROUPS:
msg = "invalid group reference %d" % condgroup
raise source.error(msg, len(condname) + 1)
if condgroup not in state.grouprefpos:
state.grouprefpos[condgroup] = (
source.tell() - len(condname) - 1
)
state.checklookbehindgroup(condgroup, source)
item_yes = _parse(source, state, verbose, nested + 1)
if source.match("|"):
Expand Down Expand Up @@ -963,6 +968,11 @@ def parse(str, flags=0, state=None):
assert source.next == ")"
raise source.error("unbalanced parenthesis")

for g in p.state.grouprefpos:
if g >= p.state.groups:
msg = "invalid group reference %d" % g
raise error(msg, str, p.state.grouprefpos[g])

if flags & SRE_FLAG_DEBUG:
p.dump()

Expand Down
2 changes: 2 additions & 0 deletions Lib/test/test_re.py
Original file line number Diff line number Diff line change
Expand Up @@ -574,6 +574,8 @@ def test_re_groupref_exists_errors(self):
self.checkPatternError(r'()(?(1)a|b|c)',
'conditional backref with more than '
'two branches', 10)
self.checkPatternError(r'()(?(2)a)',
"invalid group reference 2", 5)

def test_re_groupref_overflow(self):
from sre_constants import MAXGROUPS
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Compilation of regular expression containing a conditional expression
``(?(group)...)`` now raises an appropriate :exc:`re.error` if the group
number refers to not defined group. Previously an internal RuntimeError was
raised.

0 comments on commit 76ff686

Please sign in to comment.