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

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

`

67

67

`_ignorecase_fixes = {i: tuple(j for j in t if i != j)

`

68

68

`for t in _equivalences for i in t}

`

69

69

``

``

70

`+

class _CompileData:

`

``

71

`+

slots = ('code', 'repeat_count')

`

``

72

`+

def init(self):

`

``

73

`+

self.code = []

`

``

74

`+

self.repeat_count = 0

`

``

75

+

70

76

`def _combine_flags(flags, add_flags, del_flags,

`

71

77

`TYPE_FLAGS=_parser.TYPE_FLAGS):

`

72

78

`if add_flags & TYPE_FLAGS:

`

73

79

`flags &= ~TYPE_FLAGS

`

74

80

`return (flags | add_flags) & ~del_flags

`

75

81

``

76

``

`-

def _compile(code, pattern, flags):

`

``

82

`+

def _compile(data, pattern, flags):

`

77

83

`# internal: compile a (sub)pattern

`

``

84

`+

code = data.code

`

78

85

`emit = code.append

`

79

86

`_len = len

`

80

87

`LITERAL_CODES = _LITERAL_CODES

`

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

`

147

154

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

`

148

155

`emit(av[0])

`

149

156

`emit(av[1])

`

150

``

`-

_compile(code, av[2], flags)

`

``

157

`+

_compile(data, av[2], flags)

`

151

158

`emit(SUCCESS)

`

152

159

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

`

153

160

`else:

`

154

161

`emit(REPEATING_CODES[op][0])

`

155

162

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

`

156

163

`emit(av[0])

`

157

164

`emit(av[1])

`

158

``

`-

_compile(code, av[2], flags)

`

``

165

`+

now op is in (MIN_REPEAT, MAX_REPEAT, POSSESSIVE_REPEAT)

`

``

166

`+

if op != POSSESSIVE_REPEAT:

`

``

167

`+

emit(data.repeat_count)

`

``

168

`+

data.repeat_count += 1

`

``

169

`+

_compile(data, av[2], flags)

`

159

170

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

`

160

171

`emit(REPEATING_CODES[op][1])

`

161

172

`elif op is SUBPATTERN:

`

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

`

164

175

`emit(MARK)

`

165

176

`emit((group-1)*2)

`

166

177

`# _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))

`

168

179

`if group:

`

169

180

`emit(MARK)

`

170

181

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

`

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

`

176

187

`# pop their stack if they reach it

`

177

188

`emit(ATOMIC_GROUP)

`

178

189

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

`

179

``

`-

_compile(code, av, flags)

`

``

190

`+

_compile(data, av, flags)

`

180

191

`emit(SUCCESS)

`

181

192

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

`

182

193

`elif op in SUCCESS_CODES:

`

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

`

191

202

`if lo != hi:

`

192

203

`raise error("look-behind requires fixed-width pattern")

`

193

204

`emit(lo) # look behind

`

194

``

`-

_compile(code, av[1], flags)

`

``

205

`+

_compile(data, av[1], flags)

`

195

206

`emit(SUCCESS)

`

196

207

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

`

197

208

`elif op is CALL:

`

198

209

`emit(op)

`

199

210

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

`

200

``

`-

_compile(code, av, flags)

`

``

211

`+

_compile(data, av, flags)

`

201

212

`emit(SUCCESS)

`

202

213

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

`

203

214

`elif op is AT:

`

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

`

216

227

`for av in av[1]:

`

217

228

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

`

218

229

`# _compile_info(code, av, flags)

`

219

``

`-

_compile(code, av, flags)

`

``

230

`+

_compile(data, av, flags)

`

220

231

`emit(JUMP)

`

221

232

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

`

222

233

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

`

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

`

244

255

`emit(op)

`

245

256

`emit(av[0]-1)

`

246

257

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

`

247

``

`-

_compile(code, av[1], flags)

`

``

258

`+

_compile(data, av[1], flags)

`

248

259

`if av[2]:

`

249

260

`emit(JUMP)

`

250

261

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

`

251

262

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

`

252

``

`-

_compile(code, av[2], flags)

`

``

263

`+

_compile(data, av[2], flags)

`

253

264

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

`

254

265

`else:

`

255

266

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

`

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

`

608

619

`def _code(p, flags):

`

609

620

``

610

621

`flags = p.state.flags | flags

`

611

``

`-

code = []

`

``

622

`+

data = _CompileData()

`

612

623

``

613

624

`# compile info block

`

614

``

`-

_compile_info(code, p, flags)

`

``

625

`+

_compile_info(data.code, p, flags)

`

615

626

``

616

627

`# compile the pattern

`

617

``

`-

_compile(code, p.data, flags)

`

``

628

`+

_compile(data, p.data, flags)

`

618

629

``

619

``

`-

code.append(SUCCESS)

`

``

630

`+

data.code.append(SUCCESS)

`

620

631

``

621

``

`-

return code

`

``

632

`+

return data

`

622

633

``

623

634

`def _hex_code(code):

`

624

635

`return '[%s]' % ', '.join('%#0x' % (_sre.CODESIZE2+2, x) for x in code)

`

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

`

719

730

`else:

`

720

731

`print_(FAILURE)

`

721

732

`i += 1

`

722

``

`-

elif op in (REPEAT, REPEAT_ONE, MIN_REPEAT_ONE,

`

``

733

`+

elif op in (REPEAT_ONE, MIN_REPEAT_ONE,

`

723

734

`POSSESSIVE_REPEAT, POSSESSIVE_REPEAT_ONE):

`

724

735

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

`

725

736

`if max == MAXREPEAT:

`

726

737

`max = 'MAXREPEAT'

`

727

738

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

`

728

739

`dis_(i+3, i+skip)

`

729

740

`i += skip

`

``

741

`+

elif op is REPEAT:

`

``

742

`+

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

`

``

743

`+

if max == MAXREPEAT:

`

``

744

`+

max = 'MAXREPEAT'

`

``

745

`+

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

`

``

746

`+

dis_(i+4, i+skip)

`

``

747

`+

i += skip

`

730

748

`elif op is GROUPREF_EXISTS:

`

731

749

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

`

732

750

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

`

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

`

781

799

`else:

`

782

800

`pattern = None

`

783

801

``

784

``

`-

code = _code(p, flags)

`

``

802

`+

data = _code(p, flags)

`

785

803

``

786

804

`if flags & SRE_FLAG_DEBUG:

`

787

805

`print()

`

788

``

`-

dis(code)

`

``

806

`+

dis(data.code)

`

789

807

``

790

808

`# map in either direction

`

791

809

`groupindex = p.state.groupdict

`

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

`

794

812

`indexgroup[i] = k

`

795

813

``

796

814

`return _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)

`