bpo-23689: re module, fix memory leak when a match is terminated by a… · python/cpython@6e3eee5

GitHub

@@ -67,14 +67,21 @@

6767_ignorecase_fixes= {i: tuple(jforjintifi!=j)

6868fortin_equivalencesforiint}

696970+class_CompileData:

71+__slots__= ('code', 'repeat_count')

72+def__init__(self):

73+self.code= []

74+self.repeat_count=0

75+7076def_combine_flags(flags, add_flags, del_flags,

7177TYPE_FLAGS=_parser.TYPE_FLAGS):

7278ifadd_flags&TYPE_FLAGS:

7379flags&=~TYPE_FLAGS

7480return (flags|add_flags) &~del_flags

758176-def_compile(code, pattern, flags):

82+def_compile(data, pattern, flags):

7783# internal: compile a (sub)pattern

84+code=data.code

7885emit=code.append

7986_len=len

8087LITERAL_CODES=_LITERAL_CODES

@@ -147,15 +154,19 @@ def _compile(code, pattern, flags):

147154skip=_len(code); emit(0)

148155emit(av[0])

149156emit(av[1])

150-_compile(code, av[2], flags)

157+_compile(data, av[2], flags)

151158emit(SUCCESS)

152159code[skip] =_len(code) -skip

153160else:

154161emit(REPEATING_CODES[op][0])

155162skip=_len(code); emit(0)

156163emit(av[0])

157164emit(av[1])

158-_compile(code, av[2], flags)

165+# now op is in (MIN_REPEAT, MAX_REPEAT, POSSESSIVE_REPEAT)

166+ifop!=POSSESSIVE_REPEAT:

167+emit(data.repeat_count)

168+data.repeat_count+=1

169+_compile(data, av[2], flags)

159170code[skip] =_len(code) -skip

160171emit(REPEATING_CODES[op][1])

161172elifopisSUBPATTERN:

@@ -164,7 +175,7 @@ def _compile(code, pattern, flags):

164175emit(MARK)

165176emit((group-1)*2)

166177# _compile_info(code, p, _combine_flags(flags, add_flags, del_flags))

167-_compile(code, p, _combine_flags(flags, add_flags, del_flags))

178+_compile(data, p, _combine_flags(flags, add_flags, del_flags))

168179ifgroup:

169180emit(MARK)

170181emit((group-1)*2+1)

@@ -176,7 +187,7 @@ def _compile(code, pattern, flags):

176187# pop their stack if they reach it

177188emit(ATOMIC_GROUP)

178189skip=_len(code); emit(0)

179-_compile(code, av, flags)

190+_compile(data, av, flags)

180191emit(SUCCESS)

181192code[skip] =_len(code) -skip

182193elifopinSUCCESS_CODES:

@@ -191,13 +202,13 @@ def _compile(code, pattern, flags):

191202iflo!=hi:

192203raiseerror("look-behind requires fixed-width pattern")

193204emit(lo) # look behind

194-_compile(code, av[1], flags)

205+_compile(data, av[1], flags)

195206emit(SUCCESS)

196207code[skip] =_len(code) -skip

197208elifopisCALL:

198209emit(op)

199210skip=_len(code); emit(0)

200-_compile(code, av, flags)

211+_compile(data, av, flags)

201212emit(SUCCESS)

202213code[skip] =_len(code) -skip

203214elifopisAT:

@@ -216,7 +227,7 @@ def _compile(code, pattern, flags):

216227foravinav[1]:

217228skip=_len(code); emit(0)

218229# _compile_info(code, av, flags)

219-_compile(code, av, flags)

230+_compile(data, av, flags)

220231emit(JUMP)

221232tailappend(_len(code)); emit(0)

222233code[skip] =_len(code) -skip

@@ -244,12 +255,12 @@ def _compile(code, pattern, flags):

244255emit(op)

245256emit(av[0]-1)

246257skipyes=_len(code); emit(0)

247-_compile(code, av[1], flags)

258+_compile(data, av[1], flags)

248259ifav[2]:

249260emit(JUMP)

250261skipno=_len(code); emit(0)

251262code[skipyes] =_len(code) -skipyes+1

252-_compile(code, av[2], flags)

263+_compile(data, av[2], flags)

253264code[skipno] =_len(code) -skipno

254265else:

255266code[skipyes] =_len(code) -skipyes+1

@@ -608,17 +619,17 @@ def isstring(obj):

608619def_code(p, flags):

609620610621flags=p.state.flags|flags

611-code=[]

622+data=_CompileData()

612623613624# compile info block

614-_compile_info(code, p, flags)

625+_compile_info(data.code, p, flags)

615626616627# compile the pattern

617-_compile(code, p.data, flags)

628+_compile(data, p.data, flags)

618629619-code.append(SUCCESS)

630+data.code.append(SUCCESS)

620631621-returncode

632+returndata

622633623634def_hex_code(code):

624635return'[%s]'%', '.join('%#0*x'% (_sre.CODESIZE*2+2, x) forxincode)

@@ -719,14 +730,21 @@ def print_2(*args):

719730else:

720731print_(FAILURE)

721732i+=1

722-elifopin (REPEAT, REPEAT_ONE, MIN_REPEAT_ONE,

733+elifopin (REPEAT_ONE, MIN_REPEAT_ONE,

723734POSSESSIVE_REPEAT, POSSESSIVE_REPEAT_ONE):

724735skip, min, max=code[i: i+3]

725736ifmax==MAXREPEAT:

726737max='MAXREPEAT'

727738print_(op, skip, min, max, to=i+skip)

728739dis_(i+3, i+skip)

729740i+=skip

741+elifopisREPEAT:

742+skip, min, max, repeat_index=code[i: i+4]

743+ifmax==MAXREPEAT:

744+max='MAXREPEAT'

745+print_(op, skip, min, max, repeat_index, to=i+skip)

746+dis_(i+4, i+skip)

747+i+=skip

730748elifopisGROUPREF_EXISTS:

731749arg, skip=code[i: i+2]

732750print_(op, arg, skip, to=i+skip)

@@ -781,11 +799,11 @@ def compile(p, flags=0):

781799else:

782800pattern=None

783801784-code=_code(p, flags)

802+data=_code(p, flags)

785803786804ifflags&SRE_FLAG_DEBUG:

787805print()

788-dis(code)

806+dis(data.code)

789807790808# map in either direction

791809groupindex=p.state.groupdict

@@ -794,7 +812,6 @@ def compile(p, flags=0):

794812indexgroup[i] =k

795813796814return_sre.compile(

797-pattern, flags|p.state.flags, code,

798-p.state.groups-1,

799-groupindex, tuple(indexgroup)

800- )

815+pattern, flags|p.state.flags, data.code,

816+p.state.groups-1, groupindex, tuple(indexgroup),

817+data.repeat_count)