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