blob: 2657d8d82c6f1cbc16990a67ebb36f1e37b67c4c [file] [log] [blame]
Serhiy Storchaka8444ebb2013-10-26 11:18:42 +03001/*
2 * Secret Labs' Regular Expression Engine
3 *
4 * regular expression matching engine
5 *
6 * Copyright (c) 1997-2001 by Secret Labs AB. All rights reserved.
7 *
8 * See the _sre.c file for information on usage and redistribution.
9 */
10
11/* String matching engine */
12
13/* This file is included three times, with different character settings */
14
15LOCAL(int)
Serhiy Storchakacd8295f2020-04-11 10:48:40 +030016SRE(at)(SRE_STATE* state, const SRE_CHAR* ptr, SRE_CODE at)
Serhiy Storchaka8444ebb2013-10-26 11:18:42 +030017{
18 /* check if pointer is at given position */
19
20 Py_ssize_t thisp, thatp;
21
22 switch (at) {
23
24 case SRE_AT_BEGINNING:
25 case SRE_AT_BEGINNING_STRING:
26 return ((void*) ptr == state->beginning);
27
28 case SRE_AT_BEGINNING_LINE:
29 return ((void*) ptr == state->beginning ||
30 SRE_IS_LINEBREAK((int) ptr[-1]));
31
32 case SRE_AT_END:
Serhiy Storchaka03d6ee32015-07-06 13:58:33 +030033 return (((SRE_CHAR *)state->end - ptr == 1 &&
Serhiy Storchaka8444ebb2013-10-26 11:18:42 +030034 SRE_IS_LINEBREAK((int) ptr[0])) ||
35 ((void*) ptr == state->end));
36
37 case SRE_AT_END_LINE:
38 return ((void*) ptr == state->end ||
39 SRE_IS_LINEBREAK((int) ptr[0]));
40
41 case SRE_AT_END_STRING:
42 return ((void*) ptr == state->end);
43
44 case SRE_AT_BOUNDARY:
45 if (state->beginning == state->end)
46 return 0;
47 thatp = ((void*) ptr > state->beginning) ?
48 SRE_IS_WORD((int) ptr[-1]) : 0;
49 thisp = ((void*) ptr < state->end) ?
50 SRE_IS_WORD((int) ptr[0]) : 0;
51 return thisp != thatp;
52
53 case SRE_AT_NON_BOUNDARY:
54 if (state->beginning == state->end)
55 return 0;
56 thatp = ((void*) ptr > state->beginning) ?
57 SRE_IS_WORD((int) ptr[-1]) : 0;
58 thisp = ((void*) ptr < state->end) ?
59 SRE_IS_WORD((int) ptr[0]) : 0;
60 return thisp == thatp;
61
62 case SRE_AT_LOC_BOUNDARY:
63 if (state->beginning == state->end)
64 return 0;
65 thatp = ((void*) ptr > state->beginning) ?
66 SRE_LOC_IS_WORD((int) ptr[-1]) : 0;
67 thisp = ((void*) ptr < state->end) ?
68 SRE_LOC_IS_WORD((int) ptr[0]) : 0;
69 return thisp != thatp;
70
71 case SRE_AT_LOC_NON_BOUNDARY:
72 if (state->beginning == state->end)
73 return 0;
74 thatp = ((void*) ptr > state->beginning) ?
75 SRE_LOC_IS_WORD((int) ptr[-1]) : 0;
76 thisp = ((void*) ptr < state->end) ?
77 SRE_LOC_IS_WORD((int) ptr[0]) : 0;
78 return thisp == thatp;
79
80 case SRE_AT_UNI_BOUNDARY:
81 if (state->beginning == state->end)
82 return 0;
83 thatp = ((void*) ptr > state->beginning) ?
84 SRE_UNI_IS_WORD((int) ptr[-1]) : 0;
85 thisp = ((void*) ptr < state->end) ?
86 SRE_UNI_IS_WORD((int) ptr[0]) : 0;
87 return thisp != thatp;
88
89 case SRE_AT_UNI_NON_BOUNDARY:
90 if (state->beginning == state->end)
91 return 0;
92 thatp = ((void*) ptr > state->beginning) ?
93 SRE_UNI_IS_WORD((int) ptr[-1]) : 0;
94 thisp = ((void*) ptr < state->end) ?
95 SRE_UNI_IS_WORD((int) ptr[0]) : 0;
96 return thisp == thatp;
97
98 }
99
100 return 0;
101}
102
103LOCAL(int)
Serhiy Storchakacd8295f2020-04-11 10:48:40 +0300104SRE(charset)(SRE_STATE* state, const SRE_CODE* set, SRE_CODE ch)
Serhiy Storchaka8444ebb2013-10-26 11:18:42 +0300105{
106 /* check if character is a member of the given set */
107
108 int ok = 1;
109
110 for (;;) {
111 switch (*set++) {
112
113 case SRE_OP_FAILURE:
114 return !ok;
115
116 case SRE_OP_LITERAL:
117 /* <LITERAL> <code> */
118 if (ch == set[0])
119 return ok;
120 set++;
121 break;
122
123 case SRE_OP_CATEGORY:
124 /* <CATEGORY> <code> */
125 if (sre_category(set[0], (int) ch))
126 return ok;
127 set++;
128 break;
129
130 case SRE_OP_CHARSET:
131 /* <CHARSET> <bitmap> */
132 if (ch < 256 &&
133 (set[ch/SRE_CODE_BITS] & (1u << (ch & (SRE_CODE_BITS-1)))))
134 return ok;
135 set += 256/SRE_CODE_BITS;
136 break;
137
138 case SRE_OP_RANGE:
139 /* <RANGE> <lower> <upper> */
140 if (set[0] <= ch && ch <= set[1])
141 return ok;
142 set += 2;
143 break;
144
Serhiy Storchaka3557b052017-10-24 23:31:42 +0300145 case SRE_OP_RANGE_UNI_IGNORE:
146 /* <RANGE_UNI_IGNORE> <lower> <upper> */
Serhiy Storchaka4b8f8942014-10-31 12:36:56 +0200147 {
148 SRE_CODE uch;
149 /* ch is already lower cased */
150 if (set[0] <= ch && ch <= set[1])
151 return ok;
Serhiy Storchaka3557b052017-10-24 23:31:42 +0300152 uch = sre_upper_unicode(ch);
Serhiy Storchaka4b8f8942014-10-31 12:36:56 +0200153 if (set[0] <= uch && uch <= set[1])
154 return ok;
155 set += 2;
156 break;
157 }
158
Serhiy Storchaka8444ebb2013-10-26 11:18:42 +0300159 case SRE_OP_NEGATE:
160 ok = !ok;
161 break;
162
163 case SRE_OP_BIGCHARSET:
164 /* <BIGCHARSET> <blockcount> <256 blockindices> <blocks> */
165 {
166 Py_ssize_t count, block;
167 count = *(set++);
168
169 if (ch < 0x10000u)
170 block = ((unsigned char*)set)[ch >> 8];
171 else
172 block = -1;
173 set += 256/sizeof(SRE_CODE);
174 if (block >=0 &&
175 (set[(block * 256 + (ch & 255))/SRE_CODE_BITS] &
176 (1u << (ch & (SRE_CODE_BITS-1)))))
177 return ok;
178 set += count * (256/SRE_CODE_BITS);
179 break;
180 }
181
182 default:
183 /* internal error -- there's not much we can do about it
184 here, so let's just pretend it didn't match... */
185 return 0;
186 }
187 }
188}
189
Serhiy Storchaka898ff032017-05-05 08:53:40 +0300190LOCAL(int)
Serhiy Storchakacd8295f2020-04-11 10:48:40 +0300191SRE(charset_loc_ignore)(SRE_STATE* state, const SRE_CODE* set, SRE_CODE ch)
Serhiy Storchaka898ff032017-05-05 08:53:40 +0300192{
193 SRE_CODE lo, up;
Serhiy Storchaka3557b052017-10-24 23:31:42 +0300194 lo = sre_lower_locale(ch);
Serhiy Storchaka898ff032017-05-05 08:53:40 +0300195 if (SRE(charset)(state, set, lo))
196 return 1;
197
Serhiy Storchaka3557b052017-10-24 23:31:42 +0300198 up = sre_upper_locale(ch);
Serhiy Storchaka898ff032017-05-05 08:53:40 +0300199 return up != lo && SRE(charset)(state, set, up);
200}
201
Serhiy Storchakacd8295f2020-04-11 10:48:40 +0300202LOCAL(Py_ssize_t) SRE(match)(SRE_STATE* state, const SRE_CODE* pattern, int toplevel);
Serhiy Storchaka8444ebb2013-10-26 11:18:42 +0300203
204LOCAL(Py_ssize_t)
Serhiy Storchakacd8295f2020-04-11 10:48:40 +0300205SRE(count)(SRE_STATE* state, const SRE_CODE* pattern, Py_ssize_t maxcount)
Serhiy Storchaka8444ebb2013-10-26 11:18:42 +0300206{
207 SRE_CODE chr;
208 SRE_CHAR c;
Serhiy Storchakacd8295f2020-04-11 10:48:40 +0300209 const SRE_CHAR* ptr = (const SRE_CHAR *)state->ptr;
210 const SRE_CHAR* end = (const SRE_CHAR *)state->end;
Serhiy Storchaka8444ebb2013-10-26 11:18:42 +0300211 Py_ssize_t i;
212
213 /* adjust end */
214 if (maxcount < end - ptr && maxcount != SRE_MAXREPEAT)
215 end = ptr + maxcount;
216
217 switch (pattern[0]) {
218
219 case SRE_OP_IN:
220 /* repeated set */
221 TRACE(("|%p|%p|COUNT IN\n", pattern, ptr));
Serhiy Storchaka4b8f8942014-10-31 12:36:56 +0200222 while (ptr < end && SRE(charset)(state, pattern + 2, *ptr))
Serhiy Storchaka8444ebb2013-10-26 11:18:42 +0300223 ptr++;
224 break;
225
226 case SRE_OP_ANY:
227 /* repeated dot wildcard. */
228 TRACE(("|%p|%p|COUNT ANY\n", pattern, ptr));
229 while (ptr < end && !SRE_IS_LINEBREAK(*ptr))
230 ptr++;
231 break;
232
233 case SRE_OP_ANY_ALL:
234 /* repeated dot wildcard. skip to the end of the target
235 string, and backtrack from there */
236 TRACE(("|%p|%p|COUNT ANY_ALL\n", pattern, ptr));
237 ptr = end;
238 break;
239
240 case SRE_OP_LITERAL:
241 /* repeated literal */
242 chr = pattern[1];
243 TRACE(("|%p|%p|COUNT LITERAL %d\n", pattern, ptr, chr));
244 c = (SRE_CHAR) chr;
245#if SIZEOF_SRE_CHAR < 4
246 if ((SRE_CODE) c != chr)
247 ; /* literal can't match: doesn't fit in char width */
248 else
249#endif
250 while (ptr < end && *ptr == c)
251 ptr++;
252 break;
253
254 case SRE_OP_LITERAL_IGNORE:
255 /* repeated literal */
256 chr = pattern[1];
257 TRACE(("|%p|%p|COUNT LITERAL_IGNORE %d\n", pattern, ptr, chr));
Serhiy Storchaka3557b052017-10-24 23:31:42 +0300258 while (ptr < end && (SRE_CODE) sre_lower_ascii(*ptr) == chr)
259 ptr++;
260 break;
261
262 case SRE_OP_LITERAL_UNI_IGNORE:
263 /* repeated literal */
264 chr = pattern[1];
265 TRACE(("|%p|%p|COUNT LITERAL_UNI_IGNORE %d\n", pattern, ptr, chr));
266 while (ptr < end && (SRE_CODE) sre_lower_unicode(*ptr) == chr)
Serhiy Storchaka8444ebb2013-10-26 11:18:42 +0300267 ptr++;
268 break;
269
Serhiy Storchaka898ff032017-05-05 08:53:40 +0300270 case SRE_OP_LITERAL_LOC_IGNORE:
271 /* repeated literal */
272 chr = pattern[1];
273 TRACE(("|%p|%p|COUNT LITERAL_LOC_IGNORE %d\n", pattern, ptr, chr));
Serhiy Storchaka3557b052017-10-24 23:31:42 +0300274 while (ptr < end && char_loc_ignore(chr, *ptr))
Serhiy Storchaka898ff032017-05-05 08:53:40 +0300275 ptr++;
276 break;
277
Serhiy Storchaka8444ebb2013-10-26 11:18:42 +0300278 case SRE_OP_NOT_LITERAL:
279 /* repeated non-literal */
280 chr = pattern[1];
281 TRACE(("|%p|%p|COUNT NOT_LITERAL %d\n", pattern, ptr, chr));
282 c = (SRE_CHAR) chr;
283#if SIZEOF_SRE_CHAR < 4
284 if ((SRE_CODE) c != chr)
285 ptr = end; /* literal can't match: doesn't fit in char width */
286 else
287#endif
288 while (ptr < end && *ptr != c)
289 ptr++;
290 break;
291
292 case SRE_OP_NOT_LITERAL_IGNORE:
293 /* repeated non-literal */
294 chr = pattern[1];
295 TRACE(("|%p|%p|COUNT NOT_LITERAL_IGNORE %d\n", pattern, ptr, chr));
Serhiy Storchaka3557b052017-10-24 23:31:42 +0300296 while (ptr < end && (SRE_CODE) sre_lower_ascii(*ptr) != chr)
297 ptr++;
298 break;
299
300 case SRE_OP_NOT_LITERAL_UNI_IGNORE:
301 /* repeated non-literal */
302 chr = pattern[1];
303 TRACE(("|%p|%p|COUNT NOT_LITERAL_UNI_IGNORE %d\n", pattern, ptr, chr));
304 while (ptr < end && (SRE_CODE) sre_lower_unicode(*ptr) != chr)
Serhiy Storchaka8444ebb2013-10-26 11:18:42 +0300305 ptr++;
306 break;
307
Serhiy Storchaka898ff032017-05-05 08:53:40 +0300308 case SRE_OP_NOT_LITERAL_LOC_IGNORE:
309 /* repeated non-literal */
310 chr = pattern[1];
311 TRACE(("|%p|%p|COUNT NOT_LITERAL_LOC_IGNORE %d\n", pattern, ptr, chr));
Serhiy Storchaka3557b052017-10-24 23:31:42 +0300312 while (ptr < end && !char_loc_ignore(chr, *ptr))
Serhiy Storchaka898ff032017-05-05 08:53:40 +0300313 ptr++;
314 break;
315
Serhiy Storchaka8444ebb2013-10-26 11:18:42 +0300316 default:
317 /* repeated single character pattern */
318 TRACE(("|%p|%p|COUNT SUBPATTERN\n", pattern, ptr));
319 while ((SRE_CHAR*) state->ptr < end) {
Serhiy Storchaka429b59e2014-05-14 21:48:17 +0300320 i = SRE(match)(state, pattern, 0);
Serhiy Storchaka8444ebb2013-10-26 11:18:42 +0300321 if (i < 0)
322 return i;
323 if (!i)
324 break;
325 }
326 TRACE(("|%p|%p|COUNT %" PY_FORMAT_SIZE_T "d\n", pattern, ptr,
327 (SRE_CHAR*) state->ptr - ptr));
328 return (SRE_CHAR*) state->ptr - ptr;
329 }
330
331 TRACE(("|%p|%p|COUNT %" PY_FORMAT_SIZE_T "d\n", pattern, ptr,
332 ptr - (SRE_CHAR*) state->ptr));
333 return ptr - (SRE_CHAR*) state->ptr;
334}
335
336#if 0 /* not used in this release */
337LOCAL(int)
Serhiy Storchakacd8295f2020-04-11 10:48:40 +0300338SRE(info)(SRE_STATE* state, const SRE_CODE* pattern)
Serhiy Storchaka8444ebb2013-10-26 11:18:42 +0300339{
340 /* check if an SRE_OP_INFO block matches at the current position.
341 returns the number of SRE_CODE objects to skip if successful, 0
342 if no match */
343
Serhiy Storchakacd8295f2020-04-11 10:48:40 +0300344 const SRE_CHAR* end = (const SRE_CHAR*) state->end;
345 const SRE_CHAR* ptr = (const SRE_CHAR*) state->ptr;
Serhiy Storchaka8444ebb2013-10-26 11:18:42 +0300346 Py_ssize_t i;
347
348 /* check minimal length */
349 if (pattern[3] && end - ptr < pattern[3])
350 return 0;
351
352 /* check known prefix */
353 if (pattern[2] & SRE_INFO_PREFIX && pattern[5] > 1) {
354 /* <length> <skip> <prefix data> <overlap data> */
355 for (i = 0; i < pattern[5]; i++)
356 if ((SRE_CODE) ptr[i] != pattern[7 + i])
357 return 0;
358 return pattern[0] + 2 * pattern[6];
359 }
360 return pattern[0];
361}
362#endif
363
364/* The macros below should be used to protect recursive SRE(match)()
365 * calls that *failed* and do *not* return immediately (IOW, those
366 * that will backtrack). Explaining:
367 *
368 * - Recursive SRE(match)() returned true: that's usually a success
369 * (besides atypical cases like ASSERT_NOT), therefore there's no
370 * reason to restore lastmark;
371 *
372 * - Recursive SRE(match)() returned false but the current SRE(match)()
373 * is returning to the caller: If the current SRE(match)() is the
374 * top function of the recursion, returning false will be a matching
375 * failure, and it doesn't matter where lastmark is pointing to.
376 * If it's *not* the top function, it will be a recursive SRE(match)()
377 * failure by itself, and the calling SRE(match)() will have to deal
378 * with the failure by the same rules explained here (it will restore
379 * lastmark by itself if necessary);
380 *
381 * - Recursive SRE(match)() returned false, and will continue the
382 * outside 'for' loop: must be protected when breaking, since the next
383 * OP could potentially depend on lastmark;
384 *
385 * - Recursive SRE(match)() returned false, and will be called again
386 * inside a local for/while loop: must be protected between each
387 * loop iteration, since the recursive SRE(match)() could do anything,
388 * and could potentially depend on lastmark.
389 *
390 * For more information, check the discussion at SF patch #712900.
391 */
392#define LASTMARK_SAVE() \
393 do { \
394 ctx->lastmark = state->lastmark; \
395 ctx->lastindex = state->lastindex; \
396 } while (0)
397#define LASTMARK_RESTORE() \
398 do { \
399 state->lastmark = ctx->lastmark; \
400 state->lastindex = ctx->lastindex; \
401 } while (0)
402
403#define RETURN_ERROR(i) do { return i; } while(0)
404#define RETURN_FAILURE do { ret = 0; goto exit; } while(0)
405#define RETURN_SUCCESS do { ret = 1; goto exit; } while(0)
406
407#define RETURN_ON_ERROR(i) \
408 do { if (i < 0) RETURN_ERROR(i); } while (0)
409#define RETURN_ON_SUCCESS(i) \
410 do { RETURN_ON_ERROR(i); if (i > 0) RETURN_SUCCESS; } while (0)
411#define RETURN_ON_FAILURE(i) \
412 do { RETURN_ON_ERROR(i); if (i == 0) RETURN_FAILURE; } while (0)
413
Serhiy Storchaka8444ebb2013-10-26 11:18:42 +0300414#define DATA_STACK_ALLOC(state, type, ptr) \
415do { \
416 alloc_pos = state->data_stack_base; \
417 TRACE(("allocating %s in %" PY_FORMAT_SIZE_T "d " \
418 "(%" PY_FORMAT_SIZE_T "d)\n", \
Serhiy Storchaka12b25382015-11-05 17:43:42 +0200419 Py_STRINGIFY(type), alloc_pos, sizeof(type))); \
Serhiy Storchaka8444ebb2013-10-26 11:18:42 +0300420 if (sizeof(type) > state->data_stack_size - alloc_pos) { \
421 int j = data_stack_grow(state, sizeof(type)); \
422 if (j < 0) return j; \
423 if (ctx_pos != -1) \
424 DATA_STACK_LOOKUP_AT(state, SRE(match_context), ctx, ctx_pos); \
425 } \
426 ptr = (type*)(state->data_stack+alloc_pos); \
427 state->data_stack_base += sizeof(type); \
428} while (0)
429
430#define DATA_STACK_LOOKUP_AT(state, type, ptr, pos) \
431do { \
Serhiy Storchaka12b25382015-11-05 17:43:42 +0200432 TRACE(("looking up %s at %" PY_FORMAT_SIZE_T "d\n", Py_STRINGIFY(type), pos)); \
Serhiy Storchaka8444ebb2013-10-26 11:18:42 +0300433 ptr = (type*)(state->data_stack+pos); \
434} while (0)
435
436#define DATA_STACK_PUSH(state, data, size) \
437do { \
438 TRACE(("copy data in %p to %" PY_FORMAT_SIZE_T "d " \
439 "(%" PY_FORMAT_SIZE_T "d)\n", \
440 data, state->data_stack_base, size)); \
441 if (size > state->data_stack_size - state->data_stack_base) { \
442 int j = data_stack_grow(state, size); \
443 if (j < 0) return j; \
444 if (ctx_pos != -1) \
445 DATA_STACK_LOOKUP_AT(state, SRE(match_context), ctx, ctx_pos); \
446 } \
447 memcpy(state->data_stack+state->data_stack_base, data, size); \
448 state->data_stack_base += size; \
449} while (0)
450
Ammar Askar06e3a272020-06-01 17:21:43 +0000451/* We add an explicit cast to memcpy here because MSVC has a bug when
452 compiling C code where it believes that `const void**` cannot be
453 safely casted to `void*`, see bpo-39943 for details. */
Serhiy Storchaka8444ebb2013-10-26 11:18:42 +0300454#define DATA_STACK_POP(state, data, size, discard) \
455do { \
456 TRACE(("copy data to %p from %" PY_FORMAT_SIZE_T "d " \
457 "(%" PY_FORMAT_SIZE_T "d)\n", \
458 data, state->data_stack_base-size, size)); \
Ammar Askar06e3a272020-06-01 17:21:43 +0000459 memcpy((void*) data, state->data_stack+state->data_stack_base-size, size); \
Serhiy Storchaka8444ebb2013-10-26 11:18:42 +0300460 if (discard) \
461 state->data_stack_base -= size; \
462} while (0)
463
464#define DATA_STACK_POP_DISCARD(state, size) \
465do { \
466 TRACE(("discard data from %" PY_FORMAT_SIZE_T "d " \
467 "(%" PY_FORMAT_SIZE_T "d)\n", \
468 state->data_stack_base-size, size)); \
469 state->data_stack_base -= size; \
470} while(0)
471
472#define DATA_PUSH(x) \
473 DATA_STACK_PUSH(state, (x), sizeof(*(x)))
474#define DATA_POP(x) \
475 DATA_STACK_POP(state, (x), sizeof(*(x)), 1)
476#define DATA_POP_DISCARD(x) \
477 DATA_STACK_POP_DISCARD(state, sizeof(*(x)))
478#define DATA_ALLOC(t,p) \
479 DATA_STACK_ALLOC(state, t, p)
480#define DATA_LOOKUP_AT(t,p,pos) \
481 DATA_STACK_LOOKUP_AT(state,t,p,pos)
482
483#define MARK_PUSH(lastmark) \
484 do if (lastmark > 0) { \
485 i = lastmark; /* ctx->lastmark may change if reallocated */ \
486 DATA_STACK_PUSH(state, state->mark, (i+1)*sizeof(void*)); \
487 } while (0)
488#define MARK_POP(lastmark) \
489 do if (lastmark > 0) { \
490 DATA_STACK_POP(state, state->mark, (lastmark+1)*sizeof(void*), 1); \
491 } while (0)
492#define MARK_POP_KEEP(lastmark) \
493 do if (lastmark > 0) { \
494 DATA_STACK_POP(state, state->mark, (lastmark+1)*sizeof(void*), 0); \
495 } while (0)
496#define MARK_POP_DISCARD(lastmark) \
497 do if (lastmark > 0) { \
498 DATA_STACK_POP_DISCARD(state, (lastmark+1)*sizeof(void*)); \
499 } while (0)
500
501#define JUMP_NONE 0
502#define JUMP_MAX_UNTIL_1 1
503#define JUMP_MAX_UNTIL_2 2
504#define JUMP_MAX_UNTIL_3 3
505#define JUMP_MIN_UNTIL_1 4
506#define JUMP_MIN_UNTIL_2 5
507#define JUMP_MIN_UNTIL_3 6
508#define JUMP_REPEAT 7
509#define JUMP_REPEAT_ONE_1 8
510#define JUMP_REPEAT_ONE_2 9
511#define JUMP_MIN_REPEAT_ONE 10
512#define JUMP_BRANCH 11
513#define JUMP_ASSERT 12
514#define JUMP_ASSERT_NOT 13
515
Serhiy Storchaka70d56fb2017-12-04 14:29:05 +0200516#define DO_JUMPX(jumpvalue, jumplabel, nextpattern, toplevel_) \
Serhiy Storchaka8444ebb2013-10-26 11:18:42 +0300517 DATA_ALLOC(SRE(match_context), nextctx); \
518 nextctx->last_ctx_pos = ctx_pos; \
519 nextctx->jump = jumpvalue; \
520 nextctx->pattern = nextpattern; \
Serhiy Storchaka70d56fb2017-12-04 14:29:05 +0200521 nextctx->toplevel = toplevel_; \
Serhiy Storchaka8444ebb2013-10-26 11:18:42 +0300522 ctx_pos = alloc_pos; \
523 ctx = nextctx; \
524 goto entrance; \
525 jumplabel: \
526 while (0) /* gcc doesn't like labels at end of scopes */ \
527
Serhiy Storchaka32eddc12013-11-23 23:20:30 +0200528#define DO_JUMP(jumpvalue, jumplabel, nextpattern) \
Serhiy Storchaka70d56fb2017-12-04 14:29:05 +0200529 DO_JUMPX(jumpvalue, jumplabel, nextpattern, ctx->toplevel)
Serhiy Storchaka32eddc12013-11-23 23:20:30 +0200530
531#define DO_JUMP0(jumpvalue, jumplabel, nextpattern) \
532 DO_JUMPX(jumpvalue, jumplabel, nextpattern, 0)
533
Serhiy Storchaka8444ebb2013-10-26 11:18:42 +0300534typedef struct {
535 Py_ssize_t last_ctx_pos;
536 Py_ssize_t jump;
Serhiy Storchakacd8295f2020-04-11 10:48:40 +0300537 const SRE_CHAR* ptr;
538 const SRE_CODE* pattern;
Serhiy Storchaka8444ebb2013-10-26 11:18:42 +0300539 Py_ssize_t count;
540 Py_ssize_t lastmark;
541 Py_ssize_t lastindex;
542 union {
543 SRE_CODE chr;
544 SRE_REPEAT* rep;
545 } u;
Serhiy Storchaka70d56fb2017-12-04 14:29:05 +0200546 int toplevel;
Serhiy Storchaka8444ebb2013-10-26 11:18:42 +0300547} SRE(match_context);
548
549/* check if string matches the given pattern. returns <0 for
550 error, 0 for failure, and 1 for success */
551LOCAL(Py_ssize_t)
Serhiy Storchakacd8295f2020-04-11 10:48:40 +0300552SRE(match)(SRE_STATE* state, const SRE_CODE* pattern, int toplevel)
Serhiy Storchaka8444ebb2013-10-26 11:18:42 +0300553{
Serhiy Storchakacd8295f2020-04-11 10:48:40 +0300554 const SRE_CHAR* end = (const SRE_CHAR *)state->end;
Serhiy Storchaka8444ebb2013-10-26 11:18:42 +0300555 Py_ssize_t alloc_pos, ctx_pos = -1;
556 Py_ssize_t i, ret = 0;
557 Py_ssize_t jump;
558 unsigned int sigcount=0;
559
560 SRE(match_context)* ctx;
561 SRE(match_context)* nextctx;
562
563 TRACE(("|%p|%p|ENTER\n", pattern, state->ptr));
564
565 DATA_ALLOC(SRE(match_context), ctx);
566 ctx->last_ctx_pos = -1;
567 ctx->jump = JUMP_NONE;
568 ctx->pattern = pattern;
Serhiy Storchaka70d56fb2017-12-04 14:29:05 +0200569 ctx->toplevel = toplevel;
Serhiy Storchaka8444ebb2013-10-26 11:18:42 +0300570 ctx_pos = alloc_pos;
571
572entrance:
573
574 ctx->ptr = (SRE_CHAR *)state->ptr;
575
576 if (ctx->pattern[0] == SRE_OP_INFO) {
577 /* optimization info block */
578 /* <INFO> <1=skip> <2=flags> <3=min> ... */
Benjamin Petersonca470632016-09-06 13:47:26 -0700579 if (ctx->pattern[3] && (uintptr_t)(end - ctx->ptr) < ctx->pattern[3]) {
Serhiy Storchaka8444ebb2013-10-26 11:18:42 +0300580 TRACE(("reject (got %" PY_FORMAT_SIZE_T "d chars, "
581 "need %" PY_FORMAT_SIZE_T "d)\n",
582 end - ctx->ptr, (Py_ssize_t) ctx->pattern[3]));
583 RETURN_FAILURE;
584 }
585 ctx->pattern += ctx->pattern[1] + 1;
586 }
587
588 for (;;) {
589 ++sigcount;
590 if ((0 == (sigcount & 0xfff)) && PyErr_CheckSignals())
591 RETURN_ERROR(SRE_ERROR_INTERRUPTED);
592
593 switch (*ctx->pattern++) {
594
595 case SRE_OP_MARK:
596 /* set mark */
597 /* <MARK> <gid> */
598 TRACE(("|%p|%p|MARK %d\n", ctx->pattern,
599 ctx->ptr, ctx->pattern[0]));
600 i = ctx->pattern[0];
601 if (i & 1)
602 state->lastindex = i/2 + 1;
603 if (i > state->lastmark) {
604 /* state->lastmark is the highest valid index in the
605 state->mark array. If it is increased by more than 1,
606 the intervening marks must be set to NULL to signal
607 that these marks have not been encountered. */
608 Py_ssize_t j = state->lastmark + 1;
609 while (j < i)
610 state->mark[j++] = NULL;
611 state->lastmark = i;
612 }
613 state->mark[i] = ctx->ptr;
614 ctx->pattern++;
615 break;
616
617 case SRE_OP_LITERAL:
618 /* match literal string */
619 /* <LITERAL> <code> */
620 TRACE(("|%p|%p|LITERAL %d\n", ctx->pattern,
621 ctx->ptr, *ctx->pattern));
622 if (ctx->ptr >= end || (SRE_CODE) ctx->ptr[0] != ctx->pattern[0])
623 RETURN_FAILURE;
624 ctx->pattern++;
625 ctx->ptr++;
626 break;
627
628 case SRE_OP_NOT_LITERAL:
629 /* match anything that is not literal character */
630 /* <NOT_LITERAL> <code> */
631 TRACE(("|%p|%p|NOT_LITERAL %d\n", ctx->pattern,
632 ctx->ptr, *ctx->pattern));
633 if (ctx->ptr >= end || (SRE_CODE) ctx->ptr[0] == ctx->pattern[0])
634 RETURN_FAILURE;
635 ctx->pattern++;
636 ctx->ptr++;
637 break;
638
639 case SRE_OP_SUCCESS:
640 /* end of pattern */
641 TRACE(("|%p|%p|SUCCESS\n", ctx->pattern, ctx->ptr));
Serhiy Storchaka70d56fb2017-12-04 14:29:05 +0200642 if (ctx->toplevel &&
643 ((state->match_all && ctx->ptr != state->end) ||
644 (state->must_advance && ctx->ptr == state->start)))
645 {
646 RETURN_FAILURE;
Serhiy Storchaka32eddc12013-11-23 23:20:30 +0200647 }
Serhiy Storchaka70d56fb2017-12-04 14:29:05 +0200648 state->ptr = ctx->ptr;
649 RETURN_SUCCESS;
Serhiy Storchaka8444ebb2013-10-26 11:18:42 +0300650
651 case SRE_OP_AT:
652 /* match at given position */
653 /* <AT> <code> */
654 TRACE(("|%p|%p|AT %d\n", ctx->pattern, ctx->ptr, *ctx->pattern));
655 if (!SRE(at)(state, ctx->ptr, *ctx->pattern))
656 RETURN_FAILURE;
657 ctx->pattern++;
658 break;
659
660 case SRE_OP_CATEGORY:
661 /* match at given category */
662 /* <CATEGORY> <code> */
663 TRACE(("|%p|%p|CATEGORY %d\n", ctx->pattern,
664 ctx->ptr, *ctx->pattern));
665 if (ctx->ptr >= end || !sre_category(ctx->pattern[0], ctx->ptr[0]))
666 RETURN_FAILURE;
667 ctx->pattern++;
668 ctx->ptr++;
669 break;
670
671 case SRE_OP_ANY:
672 /* match anything (except a newline) */
673 /* <ANY> */
674 TRACE(("|%p|%p|ANY\n", ctx->pattern, ctx->ptr));
675 if (ctx->ptr >= end || SRE_IS_LINEBREAK(ctx->ptr[0]))
676 RETURN_FAILURE;
677 ctx->ptr++;
678 break;
679
680 case SRE_OP_ANY_ALL:
681 /* match anything */
682 /* <ANY_ALL> */
683 TRACE(("|%p|%p|ANY_ALL\n", ctx->pattern, ctx->ptr));
684 if (ctx->ptr >= end)
685 RETURN_FAILURE;
686 ctx->ptr++;
687 break;
688
689 case SRE_OP_IN:
690 /* match set member (or non_member) */
691 /* <IN> <skip> <set> */
692 TRACE(("|%p|%p|IN\n", ctx->pattern, ctx->ptr));
Serhiy Storchaka4b8f8942014-10-31 12:36:56 +0200693 if (ctx->ptr >= end ||
694 !SRE(charset)(state, ctx->pattern + 1, *ctx->ptr))
Serhiy Storchaka8444ebb2013-10-26 11:18:42 +0300695 RETURN_FAILURE;
696 ctx->pattern += ctx->pattern[0];
697 ctx->ptr++;
698 break;
699
700 case SRE_OP_LITERAL_IGNORE:
701 TRACE(("|%p|%p|LITERAL_IGNORE %d\n",
702 ctx->pattern, ctx->ptr, ctx->pattern[0]));
703 if (ctx->ptr >= end ||
Serhiy Storchaka3557b052017-10-24 23:31:42 +0300704 sre_lower_ascii(*ctx->ptr) != *ctx->pattern)
705 RETURN_FAILURE;
706 ctx->pattern++;
707 ctx->ptr++;
708 break;
709
710 case SRE_OP_LITERAL_UNI_IGNORE:
711 TRACE(("|%p|%p|LITERAL_UNI_IGNORE %d\n",
712 ctx->pattern, ctx->ptr, ctx->pattern[0]));
713 if (ctx->ptr >= end ||
714 sre_lower_unicode(*ctx->ptr) != *ctx->pattern)
Serhiy Storchaka898ff032017-05-05 08:53:40 +0300715 RETURN_FAILURE;
716 ctx->pattern++;
717 ctx->ptr++;
718 break;
719
720 case SRE_OP_LITERAL_LOC_IGNORE:
721 TRACE(("|%p|%p|LITERAL_LOC_IGNORE %d\n",
722 ctx->pattern, ctx->ptr, ctx->pattern[0]));
723 if (ctx->ptr >= end
Serhiy Storchaka3557b052017-10-24 23:31:42 +0300724 || !char_loc_ignore(*ctx->pattern, *ctx->ptr))
Serhiy Storchaka8444ebb2013-10-26 11:18:42 +0300725 RETURN_FAILURE;
726 ctx->pattern++;
727 ctx->ptr++;
728 break;
729
730 case SRE_OP_NOT_LITERAL_IGNORE:
731 TRACE(("|%p|%p|NOT_LITERAL_IGNORE %d\n",
732 ctx->pattern, ctx->ptr, *ctx->pattern));
733 if (ctx->ptr >= end ||
Serhiy Storchaka3557b052017-10-24 23:31:42 +0300734 sre_lower_ascii(*ctx->ptr) == *ctx->pattern)
735 RETURN_FAILURE;
736 ctx->pattern++;
737 ctx->ptr++;
738 break;
739
740 case SRE_OP_NOT_LITERAL_UNI_IGNORE:
741 TRACE(("|%p|%p|NOT_LITERAL_UNI_IGNORE %d\n",
742 ctx->pattern, ctx->ptr, *ctx->pattern));
743 if (ctx->ptr >= end ||
744 sre_lower_unicode(*ctx->ptr) == *ctx->pattern)
Serhiy Storchaka898ff032017-05-05 08:53:40 +0300745 RETURN_FAILURE;
746 ctx->pattern++;
747 ctx->ptr++;
748 break;
749
750 case SRE_OP_NOT_LITERAL_LOC_IGNORE:
751 TRACE(("|%p|%p|NOT_LITERAL_LOC_IGNORE %d\n",
752 ctx->pattern, ctx->ptr, *ctx->pattern));
753 if (ctx->ptr >= end
Serhiy Storchaka3557b052017-10-24 23:31:42 +0300754 || char_loc_ignore(*ctx->pattern, *ctx->ptr))
Serhiy Storchaka8444ebb2013-10-26 11:18:42 +0300755 RETURN_FAILURE;
756 ctx->pattern++;
757 ctx->ptr++;
758 break;
759
760 case SRE_OP_IN_IGNORE:
761 TRACE(("|%p|%p|IN_IGNORE\n", ctx->pattern, ctx->ptr));
762 if (ctx->ptr >= end
Serhiy Storchaka4b8f8942014-10-31 12:36:56 +0200763 || !SRE(charset)(state, ctx->pattern+1,
Serhiy Storchaka3557b052017-10-24 23:31:42 +0300764 (SRE_CODE)sre_lower_ascii(*ctx->ptr)))
765 RETURN_FAILURE;
766 ctx->pattern += ctx->pattern[0];
767 ctx->ptr++;
768 break;
769
770 case SRE_OP_IN_UNI_IGNORE:
771 TRACE(("|%p|%p|IN_UNI_IGNORE\n", ctx->pattern, ctx->ptr));
772 if (ctx->ptr >= end
773 || !SRE(charset)(state, ctx->pattern+1,
774 (SRE_CODE)sre_lower_unicode(*ctx->ptr)))
Serhiy Storchaka8444ebb2013-10-26 11:18:42 +0300775 RETURN_FAILURE;
776 ctx->pattern += ctx->pattern[0];
777 ctx->ptr++;
778 break;
779
Serhiy Storchaka898ff032017-05-05 08:53:40 +0300780 case SRE_OP_IN_LOC_IGNORE:
781 TRACE(("|%p|%p|IN_LOC_IGNORE\n", ctx->pattern, ctx->ptr));
782 if (ctx->ptr >= end
783 || !SRE(charset_loc_ignore)(state, ctx->pattern+1, *ctx->ptr))
784 RETURN_FAILURE;
785 ctx->pattern += ctx->pattern[0];
786 ctx->ptr++;
787 break;
788
Serhiy Storchaka8444ebb2013-10-26 11:18:42 +0300789 case SRE_OP_JUMP:
790 case SRE_OP_INFO:
791 /* jump forward */
792 /* <JUMP> <offset> */
793 TRACE(("|%p|%p|JUMP %d\n", ctx->pattern,
794 ctx->ptr, ctx->pattern[0]));
795 ctx->pattern += ctx->pattern[0];
796 break;
797
798 case SRE_OP_BRANCH:
799 /* alternation */
800 /* <BRANCH> <0=skip> code <JUMP> ... <NULL> */
801 TRACE(("|%p|%p|BRANCH\n", ctx->pattern, ctx->ptr));
802 LASTMARK_SAVE();
803 ctx->u.rep = state->repeat;
804 if (ctx->u.rep)
805 MARK_PUSH(ctx->lastmark);
806 for (; ctx->pattern[0]; ctx->pattern += ctx->pattern[0]) {
807 if (ctx->pattern[1] == SRE_OP_LITERAL &&
808 (ctx->ptr >= end ||
809 (SRE_CODE) *ctx->ptr != ctx->pattern[2]))
810 continue;
811 if (ctx->pattern[1] == SRE_OP_IN &&
812 (ctx->ptr >= end ||
Serhiy Storchaka4b8f8942014-10-31 12:36:56 +0200813 !SRE(charset)(state, ctx->pattern + 3,
814 (SRE_CODE) *ctx->ptr)))
Serhiy Storchaka8444ebb2013-10-26 11:18:42 +0300815 continue;
816 state->ptr = ctx->ptr;
817 DO_JUMP(JUMP_BRANCH, jump_branch, ctx->pattern+1);
818 if (ret) {
819 if (ctx->u.rep)
820 MARK_POP_DISCARD(ctx->lastmark);
821 RETURN_ON_ERROR(ret);
822 RETURN_SUCCESS;
823 }
824 if (ctx->u.rep)
825 MARK_POP_KEEP(ctx->lastmark);
826 LASTMARK_RESTORE();
827 }
828 if (ctx->u.rep)
829 MARK_POP_DISCARD(ctx->lastmark);
830 RETURN_FAILURE;
831
832 case SRE_OP_REPEAT_ONE:
833 /* match repeated sequence (maximizing regexp) */
834
835 /* this operator only works if the repeated item is
836 exactly one character wide, and we're not already
837 collecting backtracking points. for other cases,
838 use the MAX_REPEAT operator */
839
840 /* <REPEAT_ONE> <skip> <1=min> <2=max> item <SUCCESS> tail */
841
842 TRACE(("|%p|%p|REPEAT_ONE %d %d\n", ctx->pattern, ctx->ptr,
843 ctx->pattern[1], ctx->pattern[2]));
844
845 if ((Py_ssize_t) ctx->pattern[1] > end - ctx->ptr)
846 RETURN_FAILURE; /* cannot match */
847
848 state->ptr = ctx->ptr;
849
850 ret = SRE(count)(state, ctx->pattern+3, ctx->pattern[2]);
851 RETURN_ON_ERROR(ret);
852 DATA_LOOKUP_AT(SRE(match_context), ctx, ctx_pos);
853 ctx->count = ret;
854 ctx->ptr += ctx->count;
855
856 /* when we arrive here, count contains the number of
857 matches, and ctx->ptr points to the tail of the target
858 string. check if the rest of the pattern matches,
859 and backtrack if not. */
860
861 if (ctx->count < (Py_ssize_t) ctx->pattern[1])
862 RETURN_FAILURE;
863
Serhiy Storchaka32eddc12013-11-23 23:20:30 +0200864 if (ctx->pattern[ctx->pattern[0]] == SRE_OP_SUCCESS &&
Serhiy Storchaka70d56fb2017-12-04 14:29:05 +0200865 ctx->ptr == state->end &&
866 !(ctx->toplevel && state->must_advance && ctx->ptr == state->start))
867 {
Serhiy Storchaka8444ebb2013-10-26 11:18:42 +0300868 /* tail is empty. we're finished */
869 state->ptr = ctx->ptr;
870 RETURN_SUCCESS;
871 }
872
873 LASTMARK_SAVE();
874
875 if (ctx->pattern[ctx->pattern[0]] == SRE_OP_LITERAL) {
876 /* tail starts with a literal. skip positions where
877 the rest of the pattern cannot possibly match */
878 ctx->u.chr = ctx->pattern[ctx->pattern[0]+1];
879 for (;;) {
880 while (ctx->count >= (Py_ssize_t) ctx->pattern[1] &&
881 (ctx->ptr >= end || *ctx->ptr != ctx->u.chr)) {
882 ctx->ptr--;
883 ctx->count--;
884 }
885 if (ctx->count < (Py_ssize_t) ctx->pattern[1])
886 break;
887 state->ptr = ctx->ptr;
888 DO_JUMP(JUMP_REPEAT_ONE_1, jump_repeat_one_1,
889 ctx->pattern+ctx->pattern[0]);
890 if (ret) {
891 RETURN_ON_ERROR(ret);
892 RETURN_SUCCESS;
893 }
894
895 LASTMARK_RESTORE();
896
897 ctx->ptr--;
898 ctx->count--;
899 }
900
901 } else {
902 /* general case */
903 while (ctx->count >= (Py_ssize_t) ctx->pattern[1]) {
904 state->ptr = ctx->ptr;
905 DO_JUMP(JUMP_REPEAT_ONE_2, jump_repeat_one_2,
906 ctx->pattern+ctx->pattern[0]);
907 if (ret) {
908 RETURN_ON_ERROR(ret);
909 RETURN_SUCCESS;
910 }
911 ctx->ptr--;
912 ctx->count--;
913 LASTMARK_RESTORE();
914 }
915 }
916 RETURN_FAILURE;
917
918 case SRE_OP_MIN_REPEAT_ONE:
919 /* match repeated sequence (minimizing regexp) */
920
921 /* this operator only works if the repeated item is
922 exactly one character wide, and we're not already
923 collecting backtracking points. for other cases,
924 use the MIN_REPEAT operator */
925
926 /* <MIN_REPEAT_ONE> <skip> <1=min> <2=max> item <SUCCESS> tail */
927
928 TRACE(("|%p|%p|MIN_REPEAT_ONE %d %d\n", ctx->pattern, ctx->ptr,
929 ctx->pattern[1], ctx->pattern[2]));
930
931 if ((Py_ssize_t) ctx->pattern[1] > end - ctx->ptr)
932 RETURN_FAILURE; /* cannot match */
933
934 state->ptr = ctx->ptr;
935
936 if (ctx->pattern[1] == 0)
937 ctx->count = 0;
938 else {
939 /* count using pattern min as the maximum */
940 ret = SRE(count)(state, ctx->pattern+3, ctx->pattern[1]);
941 RETURN_ON_ERROR(ret);
942 DATA_LOOKUP_AT(SRE(match_context), ctx, ctx_pos);
943 if (ret < (Py_ssize_t) ctx->pattern[1])
944 /* didn't match minimum number of times */
945 RETURN_FAILURE;
946 /* advance past minimum matches of repeat */
947 ctx->count = ret;
948 ctx->ptr += ctx->count;
949 }
950
Serhiy Storchaka32eddc12013-11-23 23:20:30 +0200951 if (ctx->pattern[ctx->pattern[0]] == SRE_OP_SUCCESS &&
Serhiy Storchaka70d56fb2017-12-04 14:29:05 +0200952 !(ctx->toplevel &&
953 ((state->match_all && ctx->ptr != state->end) ||
954 (state->must_advance && ctx->ptr == state->start))))
955 {
Serhiy Storchaka8444ebb2013-10-26 11:18:42 +0300956 /* tail is empty. we're finished */
957 state->ptr = ctx->ptr;
958 RETURN_SUCCESS;
959
960 } else {
961 /* general case */
962 LASTMARK_SAVE();
963 while ((Py_ssize_t)ctx->pattern[2] == SRE_MAXREPEAT
964 || ctx->count <= (Py_ssize_t)ctx->pattern[2]) {
965 state->ptr = ctx->ptr;
966 DO_JUMP(JUMP_MIN_REPEAT_ONE,jump_min_repeat_one,
967 ctx->pattern+ctx->pattern[0]);
968 if (ret) {
969 RETURN_ON_ERROR(ret);
970 RETURN_SUCCESS;
971 }
972 state->ptr = ctx->ptr;
973 ret = SRE(count)(state, ctx->pattern+3, 1);
974 RETURN_ON_ERROR(ret);
975 DATA_LOOKUP_AT(SRE(match_context), ctx, ctx_pos);
976 if (ret == 0)
977 break;
978 assert(ret == 1);
979 ctx->ptr++;
980 ctx->count++;
981 LASTMARK_RESTORE();
982 }
983 }
984 RETURN_FAILURE;
985
986 case SRE_OP_REPEAT:
987 /* create repeat context. all the hard work is done
988 by the UNTIL operator (MAX_UNTIL, MIN_UNTIL) */
989 /* <REPEAT> <skip> <1=min> <2=max> item <UNTIL> tail */
990 TRACE(("|%p|%p|REPEAT %d %d\n", ctx->pattern, ctx->ptr,
991 ctx->pattern[1], ctx->pattern[2]));
992
993 /* install new repeat context */
994 ctx->u.rep = (SRE_REPEAT*) PyObject_MALLOC(sizeof(*ctx->u.rep));
995 if (!ctx->u.rep) {
996 PyErr_NoMemory();
997 RETURN_FAILURE;
998 }
999 ctx->u.rep->count = -1;
1000 ctx->u.rep->pattern = ctx->pattern;
1001 ctx->u.rep->prev = state->repeat;
1002 ctx->u.rep->last_ptr = NULL;
1003 state->repeat = ctx->u.rep;
1004
1005 state->ptr = ctx->ptr;
1006 DO_JUMP(JUMP_REPEAT, jump_repeat, ctx->pattern+ctx->pattern[0]);
1007 state->repeat = ctx->u.rep->prev;
1008 PyObject_FREE(ctx->u.rep);
1009
1010 if (ret) {
1011 RETURN_ON_ERROR(ret);
1012 RETURN_SUCCESS;
1013 }
1014 RETURN_FAILURE;
1015
1016 case SRE_OP_MAX_UNTIL:
1017 /* maximizing repeat */
1018 /* <REPEAT> <skip> <1=min> <2=max> item <MAX_UNTIL> tail */
1019
1020 /* FIXME: we probably need to deal with zero-width
1021 matches in here... */
1022
1023 ctx->u.rep = state->repeat;
1024 if (!ctx->u.rep)
1025 RETURN_ERROR(SRE_ERROR_STATE);
1026
1027 state->ptr = ctx->ptr;
1028
1029 ctx->count = ctx->u.rep->count+1;
1030
1031 TRACE(("|%p|%p|MAX_UNTIL %" PY_FORMAT_SIZE_T "d\n", ctx->pattern,
1032 ctx->ptr, ctx->count));
1033
1034 if (ctx->count < (Py_ssize_t) ctx->u.rep->pattern[1]) {
1035 /* not enough matches */
1036 ctx->u.rep->count = ctx->count;
1037 DO_JUMP(JUMP_MAX_UNTIL_1, jump_max_until_1,
1038 ctx->u.rep->pattern+3);
1039 if (ret) {
1040 RETURN_ON_ERROR(ret);
1041 RETURN_SUCCESS;
1042 }
1043 ctx->u.rep->count = ctx->count-1;
1044 state->ptr = ctx->ptr;
1045 RETURN_FAILURE;
1046 }
1047
1048 if ((ctx->count < (Py_ssize_t) ctx->u.rep->pattern[2] ||
1049 ctx->u.rep->pattern[2] == SRE_MAXREPEAT) &&
1050 state->ptr != ctx->u.rep->last_ptr) {
1051 /* we may have enough matches, but if we can
1052 match another item, do so */
1053 ctx->u.rep->count = ctx->count;
1054 LASTMARK_SAVE();
1055 MARK_PUSH(ctx->lastmark);
1056 /* zero-width match protection */
1057 DATA_PUSH(&ctx->u.rep->last_ptr);
1058 ctx->u.rep->last_ptr = state->ptr;
1059 DO_JUMP(JUMP_MAX_UNTIL_2, jump_max_until_2,
1060 ctx->u.rep->pattern+3);
1061 DATA_POP(&ctx->u.rep->last_ptr);
1062 if (ret) {
1063 MARK_POP_DISCARD(ctx->lastmark);
1064 RETURN_ON_ERROR(ret);
1065 RETURN_SUCCESS;
1066 }
1067 MARK_POP(ctx->lastmark);
1068 LASTMARK_RESTORE();
1069 ctx->u.rep->count = ctx->count-1;
1070 state->ptr = ctx->ptr;
1071 }
1072
1073 /* cannot match more repeated items here. make sure the
1074 tail matches */
1075 state->repeat = ctx->u.rep->prev;
1076 DO_JUMP(JUMP_MAX_UNTIL_3, jump_max_until_3, ctx->pattern);
1077 RETURN_ON_SUCCESS(ret);
1078 state->repeat = ctx->u.rep;
1079 state->ptr = ctx->ptr;
1080 RETURN_FAILURE;
1081
1082 case SRE_OP_MIN_UNTIL:
1083 /* minimizing repeat */
1084 /* <REPEAT> <skip> <1=min> <2=max> item <MIN_UNTIL> tail */
1085
1086 ctx->u.rep = state->repeat;
1087 if (!ctx->u.rep)
1088 RETURN_ERROR(SRE_ERROR_STATE);
1089
1090 state->ptr = ctx->ptr;
1091
1092 ctx->count = ctx->u.rep->count+1;
1093
1094 TRACE(("|%p|%p|MIN_UNTIL %" PY_FORMAT_SIZE_T "d %p\n", ctx->pattern,
1095 ctx->ptr, ctx->count, ctx->u.rep->pattern));
1096
1097 if (ctx->count < (Py_ssize_t) ctx->u.rep->pattern[1]) {
1098 /* not enough matches */
1099 ctx->u.rep->count = ctx->count;
1100 DO_JUMP(JUMP_MIN_UNTIL_1, jump_min_until_1,
1101 ctx->u.rep->pattern+3);
1102 if (ret) {
1103 RETURN_ON_ERROR(ret);
1104 RETURN_SUCCESS;
1105 }
1106 ctx->u.rep->count = ctx->count-1;
1107 state->ptr = ctx->ptr;
1108 RETURN_FAILURE;
1109 }
1110
1111 LASTMARK_SAVE();
1112
1113 /* see if the tail matches */
1114 state->repeat = ctx->u.rep->prev;
1115 DO_JUMP(JUMP_MIN_UNTIL_2, jump_min_until_2, ctx->pattern);
1116 if (ret) {
1117 RETURN_ON_ERROR(ret);
1118 RETURN_SUCCESS;
1119 }
1120
1121 state->repeat = ctx->u.rep;
1122 state->ptr = ctx->ptr;
1123
1124 LASTMARK_RESTORE();
1125
1126 if ((ctx->count >= (Py_ssize_t) ctx->u.rep->pattern[2]
1127 && ctx->u.rep->pattern[2] != SRE_MAXREPEAT) ||
1128 state->ptr == ctx->u.rep->last_ptr)
1129 RETURN_FAILURE;
1130
1131 ctx->u.rep->count = ctx->count;
1132 /* zero-width match protection */
1133 DATA_PUSH(&ctx->u.rep->last_ptr);
1134 ctx->u.rep->last_ptr = state->ptr;
1135 DO_JUMP(JUMP_MIN_UNTIL_3,jump_min_until_3,
1136 ctx->u.rep->pattern+3);
1137 DATA_POP(&ctx->u.rep->last_ptr);
1138 if (ret) {
1139 RETURN_ON_ERROR(ret);
1140 RETURN_SUCCESS;
1141 }
1142 ctx->u.rep->count = ctx->count-1;
1143 state->ptr = ctx->ptr;
1144 RETURN_FAILURE;
1145
1146 case SRE_OP_GROUPREF:
1147 /* match backreference */
1148 TRACE(("|%p|%p|GROUPREF %d\n", ctx->pattern,
1149 ctx->ptr, ctx->pattern[0]));
1150 i = ctx->pattern[0];
1151 {
1152 Py_ssize_t groupref = i+i;
1153 if (groupref >= state->lastmark) {
1154 RETURN_FAILURE;
1155 } else {
1156 SRE_CHAR* p = (SRE_CHAR*) state->mark[groupref];
1157 SRE_CHAR* e = (SRE_CHAR*) state->mark[groupref+1];
1158 if (!p || !e || e < p)
1159 RETURN_FAILURE;
1160 while (p < e) {
1161 if (ctx->ptr >= end || *ctx->ptr != *p)
1162 RETURN_FAILURE;
1163 p++;
1164 ctx->ptr++;
1165 }
1166 }
1167 }
1168 ctx->pattern++;
1169 break;
1170
1171 case SRE_OP_GROUPREF_IGNORE:
1172 /* match backreference */
1173 TRACE(("|%p|%p|GROUPREF_IGNORE %d\n", ctx->pattern,
1174 ctx->ptr, ctx->pattern[0]));
1175 i = ctx->pattern[0];
1176 {
1177 Py_ssize_t groupref = i+i;
1178 if (groupref >= state->lastmark) {
1179 RETURN_FAILURE;
1180 } else {
1181 SRE_CHAR* p = (SRE_CHAR*) state->mark[groupref];
1182 SRE_CHAR* e = (SRE_CHAR*) state->mark[groupref+1];
1183 if (!p || !e || e < p)
1184 RETURN_FAILURE;
1185 while (p < e) {
1186 if (ctx->ptr >= end ||
Serhiy Storchaka3557b052017-10-24 23:31:42 +03001187 sre_lower_ascii(*ctx->ptr) != sre_lower_ascii(*p))
1188 RETURN_FAILURE;
1189 p++;
1190 ctx->ptr++;
1191 }
1192 }
1193 }
1194 ctx->pattern++;
1195 break;
1196
1197 case SRE_OP_GROUPREF_UNI_IGNORE:
1198 /* match backreference */
1199 TRACE(("|%p|%p|GROUPREF_UNI_IGNORE %d\n", ctx->pattern,
1200 ctx->ptr, ctx->pattern[0]));
1201 i = ctx->pattern[0];
1202 {
1203 Py_ssize_t groupref = i+i;
1204 if (groupref >= state->lastmark) {
1205 RETURN_FAILURE;
1206 } else {
1207 SRE_CHAR* p = (SRE_CHAR*) state->mark[groupref];
1208 SRE_CHAR* e = (SRE_CHAR*) state->mark[groupref+1];
1209 if (!p || !e || e < p)
1210 RETURN_FAILURE;
1211 while (p < e) {
1212 if (ctx->ptr >= end ||
1213 sre_lower_unicode(*ctx->ptr) != sre_lower_unicode(*p))
1214 RETURN_FAILURE;
1215 p++;
1216 ctx->ptr++;
1217 }
1218 }
1219 }
1220 ctx->pattern++;
1221 break;
1222
1223 case SRE_OP_GROUPREF_LOC_IGNORE:
1224 /* match backreference */
1225 TRACE(("|%p|%p|GROUPREF_LOC_IGNORE %d\n", ctx->pattern,
1226 ctx->ptr, ctx->pattern[0]));
1227 i = ctx->pattern[0];
1228 {
1229 Py_ssize_t groupref = i+i;
1230 if (groupref >= state->lastmark) {
1231 RETURN_FAILURE;
1232 } else {
1233 SRE_CHAR* p = (SRE_CHAR*) state->mark[groupref];
1234 SRE_CHAR* e = (SRE_CHAR*) state->mark[groupref+1];
1235 if (!p || !e || e < p)
1236 RETURN_FAILURE;
1237 while (p < e) {
1238 if (ctx->ptr >= end ||
1239 sre_lower_locale(*ctx->ptr) != sre_lower_locale(*p))
Serhiy Storchaka8444ebb2013-10-26 11:18:42 +03001240 RETURN_FAILURE;
1241 p++;
1242 ctx->ptr++;
1243 }
1244 }
1245 }
1246 ctx->pattern++;
1247 break;
1248
1249 case SRE_OP_GROUPREF_EXISTS:
1250 TRACE(("|%p|%p|GROUPREF_EXISTS %d\n", ctx->pattern,
1251 ctx->ptr, ctx->pattern[0]));
1252 /* <GROUPREF_EXISTS> <group> <skip> codeyes <JUMP> codeno ... */
1253 i = ctx->pattern[0];
1254 {
1255 Py_ssize_t groupref = i+i;
1256 if (groupref >= state->lastmark) {
1257 ctx->pattern += ctx->pattern[1];
1258 break;
1259 } else {
1260 SRE_CHAR* p = (SRE_CHAR*) state->mark[groupref];
1261 SRE_CHAR* e = (SRE_CHAR*) state->mark[groupref+1];
1262 if (!p || !e || e < p) {
1263 ctx->pattern += ctx->pattern[1];
1264 break;
1265 }
1266 }
1267 }
1268 ctx->pattern += 2;
1269 break;
1270
1271 case SRE_OP_ASSERT:
1272 /* assert subpattern */
1273 /* <ASSERT> <skip> <back> <pattern> */
1274 TRACE(("|%p|%p|ASSERT %d\n", ctx->pattern,
1275 ctx->ptr, ctx->pattern[1]));
Serhiy Storchaka03d6ee32015-07-06 13:58:33 +03001276 if (ctx->ptr - (SRE_CHAR *)state->beginning < (Py_ssize_t)ctx->pattern[1])
Serhiy Storchaka8444ebb2013-10-26 11:18:42 +03001277 RETURN_FAILURE;
Serhiy Storchaka03d6ee32015-07-06 13:58:33 +03001278 state->ptr = ctx->ptr - ctx->pattern[1];
Serhiy Storchaka32eddc12013-11-23 23:20:30 +02001279 DO_JUMP0(JUMP_ASSERT, jump_assert, ctx->pattern+2);
Serhiy Storchaka8444ebb2013-10-26 11:18:42 +03001280 RETURN_ON_FAILURE(ret);
1281 ctx->pattern += ctx->pattern[0];
1282 break;
1283
1284 case SRE_OP_ASSERT_NOT:
1285 /* assert not subpattern */
1286 /* <ASSERT_NOT> <skip> <back> <pattern> */
1287 TRACE(("|%p|%p|ASSERT_NOT %d\n", ctx->pattern,
1288 ctx->ptr, ctx->pattern[1]));
Serhiy Storchaka03d6ee32015-07-06 13:58:33 +03001289 if (ctx->ptr - (SRE_CHAR *)state->beginning >= (Py_ssize_t)ctx->pattern[1]) {
1290 state->ptr = ctx->ptr - ctx->pattern[1];
Serhiy Storchaka32eddc12013-11-23 23:20:30 +02001291 DO_JUMP0(JUMP_ASSERT_NOT, jump_assert_not, ctx->pattern+2);
Serhiy Storchaka8444ebb2013-10-26 11:18:42 +03001292 if (ret) {
1293 RETURN_ON_ERROR(ret);
1294 RETURN_FAILURE;
1295 }
1296 }
1297 ctx->pattern += ctx->pattern[0];
1298 break;
1299
1300 case SRE_OP_FAILURE:
1301 /* immediate failure */
1302 TRACE(("|%p|%p|FAILURE\n", ctx->pattern, ctx->ptr));
1303 RETURN_FAILURE;
1304
1305 default:
1306 TRACE(("|%p|%p|UNKNOWN %d\n", ctx->pattern, ctx->ptr,
1307 ctx->pattern[-1]));
1308 RETURN_ERROR(SRE_ERROR_ILLEGAL);
1309 }
1310 }
1311
1312exit:
1313 ctx_pos = ctx->last_ctx_pos;
1314 jump = ctx->jump;
1315 DATA_POP_DISCARD(ctx);
1316 if (ctx_pos == -1)
1317 return ret;
1318 DATA_LOOKUP_AT(SRE(match_context), ctx, ctx_pos);
1319
1320 switch (jump) {
1321 case JUMP_MAX_UNTIL_2:
1322 TRACE(("|%p|%p|JUMP_MAX_UNTIL_2\n", ctx->pattern, ctx->ptr));
1323 goto jump_max_until_2;
1324 case JUMP_MAX_UNTIL_3:
1325 TRACE(("|%p|%p|JUMP_MAX_UNTIL_3\n", ctx->pattern, ctx->ptr));
1326 goto jump_max_until_3;
1327 case JUMP_MIN_UNTIL_2:
1328 TRACE(("|%p|%p|JUMP_MIN_UNTIL_2\n", ctx->pattern, ctx->ptr));
1329 goto jump_min_until_2;
1330 case JUMP_MIN_UNTIL_3:
1331 TRACE(("|%p|%p|JUMP_MIN_UNTIL_3\n", ctx->pattern, ctx->ptr));
1332 goto jump_min_until_3;
1333 case JUMP_BRANCH:
1334 TRACE(("|%p|%p|JUMP_BRANCH\n", ctx->pattern, ctx->ptr));
1335 goto jump_branch;
1336 case JUMP_MAX_UNTIL_1:
1337 TRACE(("|%p|%p|JUMP_MAX_UNTIL_1\n", ctx->pattern, ctx->ptr));
1338 goto jump_max_until_1;
1339 case JUMP_MIN_UNTIL_1:
1340 TRACE(("|%p|%p|JUMP_MIN_UNTIL_1\n", ctx->pattern, ctx->ptr));
1341 goto jump_min_until_1;
1342 case JUMP_REPEAT:
1343 TRACE(("|%p|%p|JUMP_REPEAT\n", ctx->pattern, ctx->ptr));
1344 goto jump_repeat;
1345 case JUMP_REPEAT_ONE_1:
1346 TRACE(("|%p|%p|JUMP_REPEAT_ONE_1\n", ctx->pattern, ctx->ptr));
1347 goto jump_repeat_one_1;
1348 case JUMP_REPEAT_ONE_2:
1349 TRACE(("|%p|%p|JUMP_REPEAT_ONE_2\n", ctx->pattern, ctx->ptr));
1350 goto jump_repeat_one_2;
1351 case JUMP_MIN_REPEAT_ONE:
1352 TRACE(("|%p|%p|JUMP_MIN_REPEAT_ONE\n", ctx->pattern, ctx->ptr));
1353 goto jump_min_repeat_one;
1354 case JUMP_ASSERT:
1355 TRACE(("|%p|%p|JUMP_ASSERT\n", ctx->pattern, ctx->ptr));
1356 goto jump_assert;
1357 case JUMP_ASSERT_NOT:
1358 TRACE(("|%p|%p|JUMP_ASSERT_NOT\n", ctx->pattern, ctx->ptr));
1359 goto jump_assert_not;
1360 case JUMP_NONE:
1361 TRACE(("|%p|%p|RETURN %" PY_FORMAT_SIZE_T "d\n", ctx->pattern,
1362 ctx->ptr, ret));
1363 break;
1364 }
1365
1366 return ret; /* should never get here */
1367}
1368
animalize4a7f44a2019-02-18 21:26:37 +08001369/* need to reset capturing groups between two SRE(match) callings in loops */
1370#define RESET_CAPTURE_GROUP() \
1371 do { state->lastmark = state->lastindex = -1; } while (0)
1372
Serhiy Storchaka8444ebb2013-10-26 11:18:42 +03001373LOCAL(Py_ssize_t)
1374SRE(search)(SRE_STATE* state, SRE_CODE* pattern)
1375{
1376 SRE_CHAR* ptr = (SRE_CHAR *)state->start;
1377 SRE_CHAR* end = (SRE_CHAR *)state->end;
1378 Py_ssize_t status = 0;
1379 Py_ssize_t prefix_len = 0;
1380 Py_ssize_t prefix_skip = 0;
1381 SRE_CODE* prefix = NULL;
1382 SRE_CODE* charset = NULL;
1383 SRE_CODE* overlap = NULL;
1384 int flags = 0;
1385
Serhiy Storchaka03d6ee32015-07-06 13:58:33 +03001386 if (ptr > end)
1387 return 0;
1388
Serhiy Storchaka8444ebb2013-10-26 11:18:42 +03001389 if (pattern[0] == SRE_OP_INFO) {
1390 /* optimization info block */
1391 /* <INFO> <1=skip> <2=flags> <3=min> <4=max> <5=prefix info> */
1392
1393 flags = pattern[2];
1394
Serhiy Storchaka03d6ee32015-07-06 13:58:33 +03001395 if (pattern[3] && end - ptr < (Py_ssize_t)pattern[3]) {
1396 TRACE(("reject (got %u chars, need %u)\n",
1397 (unsigned int)(end - ptr), pattern[3]));
1398 return 0;
1399 }
Serhiy Storchaka8444ebb2013-10-26 11:18:42 +03001400 if (pattern[3] > 1) {
1401 /* adjust end point (but make sure we leave at least one
1402 character in there, so literal search will work) */
1403 end -= pattern[3] - 1;
1404 if (end <= ptr)
1405 end = ptr;
1406 }
1407
1408 if (flags & SRE_INFO_PREFIX) {
1409 /* pattern starts with a known prefix */
1410 /* <length> <skip> <prefix data> <overlap data> */
1411 prefix_len = pattern[5];
1412 prefix_skip = pattern[6];
1413 prefix = pattern + 7;
1414 overlap = prefix + prefix_len - 1;
1415 } else if (flags & SRE_INFO_CHARSET)
1416 /* pattern starts with a character from a known set */
1417 /* <charset> */
1418 charset = pattern + 5;
1419
1420 pattern += 1 + pattern[1];
1421 }
1422
1423 TRACE(("prefix = %p %" PY_FORMAT_SIZE_T "d %" PY_FORMAT_SIZE_T "d\n",
1424 prefix, prefix_len, prefix_skip));
1425 TRACE(("charset = %p\n", charset));
1426
Serhiy Storchaka66dc4642015-06-21 14:06:55 +03001427 if (prefix_len == 1) {
1428 /* pattern starts with a literal character */
1429 SRE_CHAR c = (SRE_CHAR) prefix[0];
1430#if SIZEOF_SRE_CHAR < 4
1431 if ((SRE_CODE) c != prefix[0])
1432 return 0; /* literal can't match: doesn't fit in char width */
1433#endif
1434 end = (SRE_CHAR *)state->end;
Serhiy Storchaka70d56fb2017-12-04 14:29:05 +02001435 state->must_advance = 0;
Serhiy Storchaka66dc4642015-06-21 14:06:55 +03001436 while (ptr < end) {
1437 while (*ptr != c) {
1438 if (++ptr >= end)
1439 return 0;
1440 }
1441 TRACE(("|%p|%p|SEARCH LITERAL\n", pattern, ptr));
1442 state->start = ptr;
1443 state->ptr = ptr + prefix_skip;
1444 if (flags & SRE_INFO_LITERAL)
1445 return 1; /* we got all of it */
1446 status = SRE(match)(state, pattern + 2*prefix_skip, 0);
1447 if (status != 0)
1448 return status;
1449 ++ptr;
animalize4a7f44a2019-02-18 21:26:37 +08001450 RESET_CAPTURE_GROUP();
Serhiy Storchaka66dc4642015-06-21 14:06:55 +03001451 }
1452 return 0;
1453 }
1454
Serhiy Storchaka8444ebb2013-10-26 11:18:42 +03001455 if (prefix_len > 1) {
1456 /* pattern starts with a known prefix. use the overlap
1457 table to skip forward as fast as we possibly can */
1458 Py_ssize_t i = 0;
1459
1460 end = (SRE_CHAR *)state->end;
1461 if (prefix_len > end - ptr)
1462 return 0;
1463#if SIZEOF_SRE_CHAR < 4
1464 for (i = 0; i < prefix_len; i++)
1465 if ((SRE_CODE)(SRE_CHAR) prefix[i] != prefix[i])
1466 return 0; /* literal can't match: doesn't fit in char width */
1467#endif
1468 while (ptr < end) {
1469 SRE_CHAR c = (SRE_CHAR) prefix[0];
1470 while (*ptr++ != c) {
1471 if (ptr >= end)
1472 return 0;
1473 }
1474 if (ptr >= end)
1475 return 0;
1476
1477 i = 1;
Serhiy Storchaka70d56fb2017-12-04 14:29:05 +02001478 state->must_advance = 0;
Serhiy Storchaka8444ebb2013-10-26 11:18:42 +03001479 do {
1480 if (*ptr == (SRE_CHAR) prefix[i]) {
1481 if (++i != prefix_len) {
1482 if (++ptr >= end)
1483 return 0;
1484 continue;
1485 }
1486 /* found a potential match */
1487 TRACE(("|%p|%p|SEARCH SCAN\n", pattern, ptr));
1488 state->start = ptr - (prefix_len - 1);
1489 state->ptr = ptr - (prefix_len - prefix_skip - 1);
1490 if (flags & SRE_INFO_LITERAL)
1491 return 1; /* we got all of it */
Serhiy Storchaka429b59e2014-05-14 21:48:17 +03001492 status = SRE(match)(state, pattern + 2*prefix_skip, 0);
Serhiy Storchaka8444ebb2013-10-26 11:18:42 +03001493 if (status != 0)
1494 return status;
1495 /* close but no cigar -- try again */
1496 if (++ptr >= end)
1497 return 0;
animalize4a7f44a2019-02-18 21:26:37 +08001498 RESET_CAPTURE_GROUP();
Serhiy Storchaka8444ebb2013-10-26 11:18:42 +03001499 }
1500 i = overlap[i];
1501 } while (i != 0);
1502 }
1503 return 0;
1504 }
Serhiy Storchaka8444ebb2013-10-26 11:18:42 +03001505
Serhiy Storchaka66dc4642015-06-21 14:06:55 +03001506 if (charset) {
Serhiy Storchaka8444ebb2013-10-26 11:18:42 +03001507 /* pattern starts with a character from a known set */
1508 end = (SRE_CHAR *)state->end;
Serhiy Storchaka70d56fb2017-12-04 14:29:05 +02001509 state->must_advance = 0;
Serhiy Storchaka8444ebb2013-10-26 11:18:42 +03001510 for (;;) {
Serhiy Storchaka4b8f8942014-10-31 12:36:56 +02001511 while (ptr < end && !SRE(charset)(state, charset, *ptr))
Serhiy Storchaka8444ebb2013-10-26 11:18:42 +03001512 ptr++;
1513 if (ptr >= end)
1514 return 0;
1515 TRACE(("|%p|%p|SEARCH CHARSET\n", pattern, ptr));
1516 state->start = ptr;
1517 state->ptr = ptr;
Serhiy Storchaka429b59e2014-05-14 21:48:17 +03001518 status = SRE(match)(state, pattern, 0);
Serhiy Storchaka8444ebb2013-10-26 11:18:42 +03001519 if (status != 0)
1520 break;
1521 ptr++;
animalize4a7f44a2019-02-18 21:26:37 +08001522 RESET_CAPTURE_GROUP();
Serhiy Storchaka8444ebb2013-10-26 11:18:42 +03001523 }
Serhiy Storchaka03d6ee32015-07-06 13:58:33 +03001524 } else {
Serhiy Storchaka8444ebb2013-10-26 11:18:42 +03001525 /* general case */
Serhiy Storchaka03d6ee32015-07-06 13:58:33 +03001526 assert(ptr <= end);
Serhiy Storchaka70d56fb2017-12-04 14:29:05 +02001527 TRACE(("|%p|%p|SEARCH\n", pattern, ptr));
1528 state->start = state->ptr = ptr;
1529 status = SRE(match)(state, pattern, 1);
1530 state->must_advance = 0;
1531 while (status == 0 && ptr < end) {
1532 ptr++;
animalize4a7f44a2019-02-18 21:26:37 +08001533 RESET_CAPTURE_GROUP();
Serhiy Storchaka8444ebb2013-10-26 11:18:42 +03001534 TRACE(("|%p|%p|SEARCH\n", pattern, ptr));
Serhiy Storchaka03d6ee32015-07-06 13:58:33 +03001535 state->start = state->ptr = ptr;
Serhiy Storchaka429b59e2014-05-14 21:48:17 +03001536 status = SRE(match)(state, pattern, 0);
Serhiy Storchaka8444ebb2013-10-26 11:18:42 +03001537 }
Serhiy Storchaka03d6ee32015-07-06 13:58:33 +03001538 }
Serhiy Storchaka8444ebb2013-10-26 11:18:42 +03001539
1540 return status;
1541}
1542
1543#undef SRE_CHAR
1544#undef SIZEOF_SRE_CHAR
1545#undef SRE
1546
1547/* vim:ts=4:sw=4:et
1548*/