Coverage Report

Created: 2026-09-27 06:15

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/cpython3/Modules/_sre/sre_lib.h
Line
Count
Source
1
/*
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
15
LOCAL(int)
16
SRE(at)(SRE_STATE* state, const SRE_CHAR* ptr, SRE_CODE at)
17
329
{
18
    /* check if pointer is at given position */
19
20
329
    Py_ssize_t thisp, thatp;
21
22
329
    switch (at) {
23
24
255
    case SRE_AT_BEGINNING:
25
255
    case SRE_AT_BEGINNING_STRING:
26
255
        return ((void*) ptr == state->beginning);
27
28
0
    case SRE_AT_BEGINNING_LINE:
29
0
        return ((void*) ptr == state->beginning ||
30
0
                SRE_IS_LINEBREAK((int) ptr[-1]));
31
32
56
    case SRE_AT_END:
33
56
        return (((SRE_CHAR *)state->end - ptr == 1 &&
34
10
                 SRE_IS_LINEBREAK((int) ptr[0])) ||
35
55
                ((void*) ptr == state->end));
36
37
0
    case SRE_AT_END_LINE:
38
0
        return ((void*) ptr == state->end ||
39
0
                SRE_IS_LINEBREAK((int) ptr[0]));
40
41
12
    case SRE_AT_END_STRING:
42
12
        return ((void*) ptr == state->end);
43
44
6
    case SRE_AT_BOUNDARY:
45
6
        thatp = ((void*) ptr > state->beginning) ?
46
6
            SRE_IS_WORD((int) ptr[-1]) : 0;
47
6
        thisp = ((void*) ptr < state->end) ?
48
5
            SRE_IS_WORD((int) ptr[0]) : 0;
49
6
        return thisp != thatp;
50
51
0
    case SRE_AT_NON_BOUNDARY:
52
0
        thatp = ((void*) ptr > state->beginning) ?
53
0
            SRE_IS_WORD((int) ptr[-1]) : 0;
54
0
        thisp = ((void*) ptr < state->end) ?
55
0
            SRE_IS_WORD((int) ptr[0]) : 0;
56
0
        return thisp == thatp;
57
58
0
    case SRE_AT_LOC_BOUNDARY:
59
0
        thatp = ((void*) ptr > state->beginning) ?
60
0
            SRE_LOC_IS_WORD((int) ptr[-1]) : 0;
61
0
        thisp = ((void*) ptr < state->end) ?
62
0
            SRE_LOC_IS_WORD((int) ptr[0]) : 0;
63
0
        return thisp != thatp;
64
65
0
    case SRE_AT_LOC_NON_BOUNDARY:
66
0
        thatp = ((void*) ptr > state->beginning) ?
67
0
            SRE_LOC_IS_WORD((int) ptr[-1]) : 0;
68
0
        thisp = ((void*) ptr < state->end) ?
69
0
            SRE_LOC_IS_WORD((int) ptr[0]) : 0;
70
0
        return thisp == thatp;
71
72
0
    case SRE_AT_UNI_BOUNDARY:
73
0
        thatp = ((void*) ptr > state->beginning) ?
74
0
            SRE_UNI_IS_WORD((int) ptr[-1]) : 0;
75
0
        thisp = ((void*) ptr < state->end) ?
76
0
            SRE_UNI_IS_WORD((int) ptr[0]) : 0;
77
0
        return thisp != thatp;
78
79
0
    case SRE_AT_UNI_NON_BOUNDARY:
80
0
        thatp = ((void*) ptr > state->beginning) ?
81
0
            SRE_UNI_IS_WORD((int) ptr[-1]) : 0;
82
0
        thisp = ((void*) ptr < state->end) ?
83
0
            SRE_UNI_IS_WORD((int) ptr[0]) : 0;
84
0
        return thisp == thatp;
85
86
329
    }
87
88
0
    return 0;
89
329
}
sre.c:sre_ucs1_at
Line
Count
Source
17
329
{
18
    /* check if pointer is at given position */
19
20
329
    Py_ssize_t thisp, thatp;
21
22
329
    switch (at) {
23
24
255
    case SRE_AT_BEGINNING:
25
255
    case SRE_AT_BEGINNING_STRING:
26
255
        return ((void*) ptr == state->beginning);
27
28
0
    case SRE_AT_BEGINNING_LINE:
29
0
        return ((void*) ptr == state->beginning ||
30
0
                SRE_IS_LINEBREAK((int) ptr[-1]));
31
32
56
    case SRE_AT_END:
33
56
        return (((SRE_CHAR *)state->end - ptr == 1 &&
34
10
                 SRE_IS_LINEBREAK((int) ptr[0])) ||
35
55
                ((void*) ptr == state->end));
36
37
0
    case SRE_AT_END_LINE:
38
0
        return ((void*) ptr == state->end ||
39
0
                SRE_IS_LINEBREAK((int) ptr[0]));
40
41
12
    case SRE_AT_END_STRING:
42
12
        return ((void*) ptr == state->end);
43
44
6
    case SRE_AT_BOUNDARY:
45
6
        thatp = ((void*) ptr > state->beginning) ?
46
6
            SRE_IS_WORD((int) ptr[-1]) : 0;
47
6
        thisp = ((void*) ptr < state->end) ?
48
5
            SRE_IS_WORD((int) ptr[0]) : 0;
49
6
        return thisp != thatp;
50
51
0
    case SRE_AT_NON_BOUNDARY:
52
0
        thatp = ((void*) ptr > state->beginning) ?
53
0
            SRE_IS_WORD((int) ptr[-1]) : 0;
54
0
        thisp = ((void*) ptr < state->end) ?
55
0
            SRE_IS_WORD((int) ptr[0]) : 0;
56
0
        return thisp == thatp;
57
58
0
    case SRE_AT_LOC_BOUNDARY:
59
0
        thatp = ((void*) ptr > state->beginning) ?
60
0
            SRE_LOC_IS_WORD((int) ptr[-1]) : 0;
61
0
        thisp = ((void*) ptr < state->end) ?
62
0
            SRE_LOC_IS_WORD((int) ptr[0]) : 0;
63
0
        return thisp != thatp;
64
65
0
    case SRE_AT_LOC_NON_BOUNDARY:
66
0
        thatp = ((void*) ptr > state->beginning) ?
67
0
            SRE_LOC_IS_WORD((int) ptr[-1]) : 0;
68
0
        thisp = ((void*) ptr < state->end) ?
69
0
            SRE_LOC_IS_WORD((int) ptr[0]) : 0;
70
0
        return thisp == thatp;
71
72
0
    case SRE_AT_UNI_BOUNDARY:
73
0
        thatp = ((void*) ptr > state->beginning) ?
74
0
            SRE_UNI_IS_WORD((int) ptr[-1]) : 0;
75
0
        thisp = ((void*) ptr < state->end) ?
76
0
            SRE_UNI_IS_WORD((int) ptr[0]) : 0;
77
0
        return thisp != thatp;
78
79
0
    case SRE_AT_UNI_NON_BOUNDARY:
80
0
        thatp = ((void*) ptr > state->beginning) ?
81
0
            SRE_UNI_IS_WORD((int) ptr[-1]) : 0;
82
0
        thisp = ((void*) ptr < state->end) ?
83
0
            SRE_UNI_IS_WORD((int) ptr[0]) : 0;
84
0
        return thisp == thatp;
85
86
329
    }
87
88
0
    return 0;
89
329
}
Unexecuted instantiation: sre.c:sre_ucs2_at
Unexecuted instantiation: sre.c:sre_ucs4_at
90
91
LOCAL(int)
92
SRE(charset)(SRE_STATE* state, const SRE_CODE* set, SRE_CODE ch)
93
12.3M
{
94
    /* check if character is a member of the given set */
95
96
12.3M
    int ok = 1;
97
98
12.6M
    for (;;) {
99
12.6M
        switch (*set++) {
100
101
91.7k
        case SRE_OP_FAILURE:
102
91.7k
            return !ok;
103
104
1.51M
        case SRE_OP_LITERAL:
105
            /* <LITERAL> <code> */
106
1.51M
            if (ch == set[0])
107
1.26M
                return ok;
108
256k
            set++;
109
256k
            break;
110
111
0
        case SRE_OP_CATEGORY:
112
            /* <CATEGORY> <code> */
113
0
            if (sre_category(set[0], (int) ch))
114
0
                return ok;
115
0
            set++;
116
0
            break;
117
118
11.0M
        case SRE_OP_CHARSET:
119
            /* <CHARSET> <bitmap> */
120
11.0M
            if (ch < 256 &&
121
11.0M
                (set[ch/SRE_CODE_BITS] & (1u << (ch & (SRE_CODE_BITS-1)))))
122
11.0M
                return ok;
123
8.45k
            set += 256/SRE_CODE_BITS;
124
8.45k
            break;
125
126
16
        case SRE_OP_RANGE:
127
            /* <RANGE> <lower> <upper> */
128
16
            if (set[0] <= ch && ch <= set[1])
129
1
                return ok;
130
15
            set += 2;
131
15
            break;
132
133
0
        case SRE_OP_RANGE_UNI_IGNORE:
134
            /* <RANGE_UNI_IGNORE> <lower> <upper> */
135
0
        {
136
0
            SRE_CODE uch;
137
            /* ch is already lower cased */
138
0
            if (set[0] <= ch && ch <= set[1])
139
0
                return ok;
140
0
            uch = sre_upper_unicode(ch);
141
0
            if (set[0] <= uch && uch <= set[1])
142
0
                return ok;
143
0
            set += 2;
144
0
            break;
145
0
        }
146
147
16
        case SRE_OP_NEGATE:
148
16
            ok = !ok;
149
16
            break;
150
151
0
        case SRE_OP_BIGCHARSET:
152
            /* <BIGCHARSET> <blockcount> <256 blockindices> <blocks> */
153
0
        {
154
0
            Py_ssize_t count, block;
155
0
            count = *(set++);
156
157
0
            if (ch < 0x10000u)
158
0
                block = ((unsigned char*)set)[ch >> 8];
159
0
            else
160
0
                block = -1;
161
0
            set += 256/sizeof(SRE_CODE);
162
0
            if (block >=0 &&
163
0
                (set[(block * 256 + (ch & 255))/SRE_CODE_BITS] &
164
0
                    (1u << (ch & (SRE_CODE_BITS-1)))))
165
0
                return ok;
166
0
            set += count * (256/SRE_CODE_BITS);
167
0
            break;
168
0
        }
169
170
0
        default:
171
            /* internal error -- there's not much we can do about it
172
               here, so let's just pretend it didn't match... */
173
0
            return 0;
174
12.6M
        }
175
12.6M
    }
176
12.3M
}
sre.c:sre_ucs1_charset
Line
Count
Source
93
7.44M
{
94
    /* check if character is a member of the given set */
95
96
7.44M
    int ok = 1;
97
98
7.70M
    for (;;) {
99
7.70M
        switch (*set++) {
100
101
87.9k
        case SRE_OP_FAILURE:
102
87.9k
            return !ok;
103
104
1.51M
        case SRE_OP_LITERAL:
105
            /* <LITERAL> <code> */
106
1.51M
            if (ch == set[0])
107
1.26M
                return ok;
108
256k
            set++;
109
256k
            break;
110
111
0
        case SRE_OP_CATEGORY:
112
            /* <CATEGORY> <code> */
113
0
            if (sre_category(set[0], (int) ch))
114
0
                return ok;
115
0
            set++;
116
0
            break;
117
118
6.10M
        case SRE_OP_CHARSET:
119
            /* <CHARSET> <bitmap> */
120
6.10M
            if (ch < 256 &&
121
6.10M
                (set[ch/SRE_CODE_BITS] & (1u << (ch & (SRE_CODE_BITS-1)))))
122
6.09M
                return ok;
123
4.72k
            set += 256/SRE_CODE_BITS;
124
4.72k
            break;
125
126
16
        case SRE_OP_RANGE:
127
            /* <RANGE> <lower> <upper> */
128
16
            if (set[0] <= ch && ch <= set[1])
129
1
                return ok;
130
15
            set += 2;
131
15
            break;
132
133
0
        case SRE_OP_RANGE_UNI_IGNORE:
134
            /* <RANGE_UNI_IGNORE> <lower> <upper> */
135
0
        {
136
0
            SRE_CODE uch;
137
            /* ch is already lower cased */
138
0
            if (set[0] <= ch && ch <= set[1])
139
0
                return ok;
140
0
            uch = sre_upper_unicode(ch);
141
0
            if (set[0] <= uch && uch <= set[1])
142
0
                return ok;
143
0
            set += 2;
144
0
            break;
145
0
        }
146
147
16
        case SRE_OP_NEGATE:
148
16
            ok = !ok;
149
16
            break;
150
151
0
        case SRE_OP_BIGCHARSET:
152
            /* <BIGCHARSET> <blockcount> <256 blockindices> <blocks> */
153
0
        {
154
0
            Py_ssize_t count, block;
155
0
            count = *(set++);
156
157
0
            if (ch < 0x10000u)
158
0
                block = ((unsigned char*)set)[ch >> 8];
159
0
            else
160
0
                block = -1;
161
0
            set += 256/sizeof(SRE_CODE);
162
0
            if (block >=0 &&
163
0
                (set[(block * 256 + (ch & 255))/SRE_CODE_BITS] &
164
0
                    (1u << (ch & (SRE_CODE_BITS-1)))))
165
0
                return ok;
166
0
            set += count * (256/SRE_CODE_BITS);
167
0
            break;
168
0
        }
169
170
0
        default:
171
            /* internal error -- there's not much we can do about it
172
               here, so let's just pretend it didn't match... */
173
0
            return 0;
174
7.70M
        }
175
7.70M
    }
176
7.44M
}
sre.c:sre_ucs2_charset
Line
Count
Source
93
2.18M
{
94
    /* check if character is a member of the given set */
95
96
2.18M
    int ok = 1;
97
98
2.19M
    for (;;) {
99
2.19M
        switch (*set++) {
100
101
1.60k
        case SRE_OP_FAILURE:
102
1.60k
            return !ok;
103
104
0
        case SRE_OP_LITERAL:
105
            /* <LITERAL> <code> */
106
0
            if (ch == set[0])
107
0
                return ok;
108
0
            set++;
109
0
            break;
110
111
0
        case SRE_OP_CATEGORY:
112
            /* <CATEGORY> <code> */
113
0
            if (sre_category(set[0], (int) ch))
114
0
                return ok;
115
0
            set++;
116
0
            break;
117
118
2.18M
        case SRE_OP_CHARSET:
119
            /* <CHARSET> <bitmap> */
120
2.18M
            if (ch < 256 &&
121
2.18M
                (set[ch/SRE_CODE_BITS] & (1u << (ch & (SRE_CODE_BITS-1)))))
122
2.18M
                return ok;
123
1.60k
            set += 256/SRE_CODE_BITS;
124
1.60k
            break;
125
126
0
        case SRE_OP_RANGE:
127
            /* <RANGE> <lower> <upper> */
128
0
            if (set[0] <= ch && ch <= set[1])
129
0
                return ok;
130
0
            set += 2;
131
0
            break;
132
133
0
        case SRE_OP_RANGE_UNI_IGNORE:
134
            /* <RANGE_UNI_IGNORE> <lower> <upper> */
135
0
        {
136
0
            SRE_CODE uch;
137
            /* ch is already lower cased */
138
0
            if (set[0] <= ch && ch <= set[1])
139
0
                return ok;
140
0
            uch = sre_upper_unicode(ch);
141
0
            if (set[0] <= uch && uch <= set[1])
142
0
                return ok;
143
0
            set += 2;
144
0
            break;
145
0
        }
146
147
0
        case SRE_OP_NEGATE:
148
0
            ok = !ok;
149
0
            break;
150
151
0
        case SRE_OP_BIGCHARSET:
152
            /* <BIGCHARSET> <blockcount> <256 blockindices> <blocks> */
153
0
        {
154
0
            Py_ssize_t count, block;
155
0
            count = *(set++);
156
157
0
            if (ch < 0x10000u)
158
0
                block = ((unsigned char*)set)[ch >> 8];
159
0
            else
160
0
                block = -1;
161
0
            set += 256/sizeof(SRE_CODE);
162
0
            if (block >=0 &&
163
0
                (set[(block * 256 + (ch & 255))/SRE_CODE_BITS] &
164
0
                    (1u << (ch & (SRE_CODE_BITS-1)))))
165
0
                return ok;
166
0
            set += count * (256/SRE_CODE_BITS);
167
0
            break;
168
0
        }
169
170
0
        default:
171
            /* internal error -- there's not much we can do about it
172
               here, so let's just pretend it didn't match... */
173
0
            return 0;
174
2.19M
        }
175
2.19M
    }
176
2.18M
}
sre.c:sre_ucs4_charset
Line
Count
Source
93
2.73M
{
94
    /* check if character is a member of the given set */
95
96
2.73M
    int ok = 1;
97
98
2.73M
    for (;;) {
99
2.73M
        switch (*set++) {
100
101
2.11k
        case SRE_OP_FAILURE:
102
2.11k
            return !ok;
103
104
0
        case SRE_OP_LITERAL:
105
            /* <LITERAL> <code> */
106
0
            if (ch == set[0])
107
0
                return ok;
108
0
            set++;
109
0
            break;
110
111
0
        case SRE_OP_CATEGORY:
112
            /* <CATEGORY> <code> */
113
0
            if (sre_category(set[0], (int) ch))
114
0
                return ok;
115
0
            set++;
116
0
            break;
117
118
2.73M
        case SRE_OP_CHARSET:
119
            /* <CHARSET> <bitmap> */
120
2.73M
            if (ch < 256 &&
121
2.73M
                (set[ch/SRE_CODE_BITS] & (1u << (ch & (SRE_CODE_BITS-1)))))
122
2.73M
                return ok;
123
2.11k
            set += 256/SRE_CODE_BITS;
124
2.11k
            break;
125
126
0
        case SRE_OP_RANGE:
127
            /* <RANGE> <lower> <upper> */
128
0
            if (set[0] <= ch && ch <= set[1])
129
0
                return ok;
130
0
            set += 2;
131
0
            break;
132
133
0
        case SRE_OP_RANGE_UNI_IGNORE:
134
            /* <RANGE_UNI_IGNORE> <lower> <upper> */
135
0
        {
136
0
            SRE_CODE uch;
137
            /* ch is already lower cased */
138
0
            if (set[0] <= ch && ch <= set[1])
139
0
                return ok;
140
0
            uch = sre_upper_unicode(ch);
141
0
            if (set[0] <= uch && uch <= set[1])
142
0
                return ok;
143
0
            set += 2;
144
0
            break;
145
0
        }
146
147
0
        case SRE_OP_NEGATE:
148
0
            ok = !ok;
149
0
            break;
150
151
0
        case SRE_OP_BIGCHARSET:
152
            /* <BIGCHARSET> <blockcount> <256 blockindices> <blocks> */
153
0
        {
154
0
            Py_ssize_t count, block;
155
0
            count = *(set++);
156
157
0
            if (ch < 0x10000u)
158
0
                block = ((unsigned char*)set)[ch >> 8];
159
0
            else
160
0
                block = -1;
161
0
            set += 256/sizeof(SRE_CODE);
162
0
            if (block >=0 &&
163
0
                (set[(block * 256 + (ch & 255))/SRE_CODE_BITS] &
164
0
                    (1u << (ch & (SRE_CODE_BITS-1)))))
165
0
                return ok;
166
0
            set += count * (256/SRE_CODE_BITS);
167
0
            break;
168
0
        }
169
170
0
        default:
171
            /* internal error -- there's not much we can do about it
172
               here, so let's just pretend it didn't match... */
173
0
            return 0;
174
2.73M
        }
175
2.73M
    }
176
2.73M
}
177
178
/* Like SRE(charset), but matches both locale cases of ch against every set
179
   member.  Testing the whole set once per case would complement it before
180
   closing it under case instead of after, so that [^bc] matched b'B'.
181
   BIGCHARSET and RANGE_UNI_IGNORE are not handled: they never occur in a
182
   set of a bytes pattern. */
183
LOCAL(int)
184
SRE(charset_loc_ignore)(SRE_STATE* state, const SRE_CODE* set, SRE_CODE ch)
185
0
{
186
0
    SRE_CODE lo, up;
187
0
    int ok = 1;
188
189
0
    lo = sre_lower_locale(ch);
190
0
    up = sre_upper_locale(ch);
191
0
    if (up == lo)
192
0
        return SRE(charset)(state, set, lo);
193
194
0
    for (;;) {
195
0
        switch (*set++) {
196
197
0
        case SRE_OP_FAILURE:
198
0
            return !ok;
199
200
0
        case SRE_OP_LITERAL:
201
            /* <LITERAL> <code> */
202
0
            if (lo == set[0] || up == set[0])
203
0
                return ok;
204
0
            set++;
205
0
            break;
206
207
0
        case SRE_OP_CATEGORY:
208
            /* <CATEGORY> <code> */
209
0
            if (sre_category(set[0], (int) lo) ||
210
0
                sre_category(set[0], (int) up))
211
0
                return ok;
212
0
            set++;
213
0
            break;
214
215
0
        case SRE_OP_CHARSET:
216
            /* <CHARSET> <bitmap> */
217
0
            if ((lo < 256 && (set[lo/SRE_CODE_BITS]
218
0
                              & (1u << (lo & (SRE_CODE_BITS-1))))) ||
219
0
                (up < 256 && (set[up/SRE_CODE_BITS]
220
0
                              & (1u << (up & (SRE_CODE_BITS-1))))))
221
0
                return ok;
222
0
            set += 256/SRE_CODE_BITS;
223
0
            break;
224
225
0
        case SRE_OP_RANGE:
226
            /* <RANGE> <lower> <upper> */
227
0
            if ((set[0] <= lo && lo <= set[1]) ||
228
0
                (set[0] <= up && up <= set[1]))
229
0
                return ok;
230
0
            set += 2;
231
0
            break;
232
233
0
        case SRE_OP_NEGATE:
234
0
            ok = !ok;
235
0
            break;
236
237
0
        default:
238
            /* internal error -- there's not much we can do about it
239
               here, so let's just pretend it didn't match... */
240
0
            return 0;
241
0
        }
242
0
    }
243
0
}
Unexecuted instantiation: sre.c:sre_ucs1_charset_loc_ignore
Unexecuted instantiation: sre.c:sre_ucs2_charset_loc_ignore
Unexecuted instantiation: sre.c:sre_ucs4_charset_loc_ignore
244
245
LOCAL(Py_ssize_t) SRE(match)(SRE_STATE* state, const SRE_CODE* pattern, int toplevel);
246
247
LOCAL(Py_ssize_t)
248
SRE(count)(SRE_STATE* state, const SRE_CODE* pattern, Py_ssize_t maxcount)
249
1.24M
{
250
1.24M
    SRE_CODE chr;
251
1.24M
    SRE_CODE arg;
252
1.24M
    SRE_CHAR c;
253
1.24M
    const SRE_CHAR* ptr = (const SRE_CHAR *)state->ptr;
254
1.24M
    const SRE_CHAR* end = (const SRE_CHAR *)state->end;
255
1.24M
    Py_ssize_t i;
256
1.24M
    INIT_TRACE(state);
257
258
    /* adjust end */
259
1.24M
    if (maxcount < end - ptr && maxcount != SRE_MAXREPEAT)
260
1.23M
        end = ptr + maxcount;
261
262
1.24M
    switch (pattern[0]) {
263
264
9.71k
    case SRE_OP_IN:
265
        /* repeated set */
266
9.71k
        TRACE(("|%p|%p|COUNT IN\n", pattern, ptr));
267
11.0M
        while (ptr < end && SRE(charset)(state, pattern + 2, *ptr))
268
11.0M
            ptr++;
269
9.71k
        break;
270
271
0
    case SRE_OP_ANY:
272
        /* repeated dot wildcard. */
273
0
        TRACE(("|%p|%p|COUNT ANY\n", pattern, ptr));
274
0
        while (ptr < end && !SRE_IS_LINEBREAK(*ptr))
275
0
            ptr++;
276
0
        break;
277
278
0
    case SRE_OP_ANY_ALL:
279
        /* repeated dot wildcard.  skip to the end of the target
280
           string, and backtrack from there */
281
0
        TRACE(("|%p|%p|COUNT ANY_ALL\n", pattern, ptr));
282
0
        ptr = end;
283
0
        break;
284
285
586
    case SRE_OP_LITERAL:
286
        /* repeated literal */
287
586
        chr = pattern[1];
288
586
        TRACE(("|%p|%p|COUNT LITERAL %d\n", pattern, ptr, chr));
289
586
        c = (SRE_CHAR) chr;
290
#if SIZEOF_SRE_CHAR < 4
291
586
        if ((SRE_CODE) c != chr)
292
0
            ; /* literal can't match: doesn't fit in char width */
293
586
        else
294
586
#endif
295
458k
        while (ptr < end && *ptr == c)
296
457k
            ptr++;
297
586
        break;
298
299
0
    case SRE_OP_LITERAL_IGNORE:
300
        /* repeated literal */
301
0
        chr = pattern[1];
302
0
        TRACE(("|%p|%p|COUNT LITERAL_IGNORE %d\n", pattern, ptr, chr));
303
0
        while (ptr < end && (SRE_CODE) sre_lower_ascii(*ptr) == chr)
304
0
            ptr++;
305
0
        break;
306
307
0
    case SRE_OP_LITERAL_UNI_IGNORE:
308
        /* repeated literal */
309
0
        chr = pattern[1];
310
0
        TRACE(("|%p|%p|COUNT LITERAL_UNI_IGNORE %d\n", pattern, ptr, chr));
311
0
        while (ptr < end && (SRE_CODE) sre_lower_unicode(*ptr) == chr)
312
0
            ptr++;
313
0
        break;
314
315
0
    case SRE_OP_LITERAL_LOC_IGNORE:
316
        /* repeated literal */
317
0
        chr = pattern[1];
318
0
        TRACE(("|%p|%p|COUNT LITERAL_LOC_IGNORE %d\n", pattern, ptr, chr));
319
0
        while (ptr < end && char_loc_ignore(chr, *ptr))
320
0
            ptr++;
321
0
        break;
322
323
0
    case SRE_OP_NOT_LITERAL:
324
        /* repeated non-literal */
325
0
        chr = pattern[1];
326
0
        TRACE(("|%p|%p|COUNT NOT_LITERAL %d\n", pattern, ptr, chr));
327
0
        c = (SRE_CHAR) chr;
328
#if SIZEOF_SRE_CHAR < 4
329
0
        if ((SRE_CODE) c != chr)
330
0
            ptr = end; /* literal can't match: doesn't fit in char width */
331
0
        else
332
0
#endif
333
0
        while (ptr < end && *ptr != c)
334
0
            ptr++;
335
0
        break;
336
337
0
    case SRE_OP_NOT_LITERAL_IGNORE:
338
        /* repeated non-literal */
339
0
        chr = pattern[1];
340
0
        TRACE(("|%p|%p|COUNT NOT_LITERAL_IGNORE %d\n", pattern, ptr, chr));
341
0
        while (ptr < end && (SRE_CODE) sre_lower_ascii(*ptr) != chr)
342
0
            ptr++;
343
0
        break;
344
345
0
    case SRE_OP_NOT_LITERAL_UNI_IGNORE:
346
        /* repeated non-literal */
347
0
        chr = pattern[1];
348
0
        TRACE(("|%p|%p|COUNT NOT_LITERAL_UNI_IGNORE %d\n", pattern, ptr, chr));
349
0
        while (ptr < end && (SRE_CODE) sre_lower_unicode(*ptr) != chr)
350
0
            ptr++;
351
0
        break;
352
353
0
    case SRE_OP_NOT_LITERAL_LOC_IGNORE:
354
        /* repeated non-literal */
355
0
        chr = pattern[1];
356
0
        TRACE(("|%p|%p|COUNT NOT_LITERAL_LOC_IGNORE %d\n", pattern, ptr, chr));
357
0
        while (ptr < end && !char_loc_ignore(chr, *ptr))
358
0
            ptr++;
359
0
        break;
360
361
1.23M
    case SRE_OP_CATEGORY:
362
1.23M
        arg = pattern[1];
363
1.23M
        TRACE(("|%p|%p|COUNT CATEGORY %d\n", pattern, ptr, arg));
364
1.23M
        while (ptr < end && sre_category(arg, *ptr))
365
1.38k
            ptr++;
366
1.23M
        break;
367
368
0
    default:
369
        /* repeated single character pattern */
370
0
        TRACE(("|%p|%p|COUNT SUBPATTERN\n", pattern, ptr));
371
0
        while ((SRE_CHAR*) state->ptr < end) {
372
0
            i = SRE(match)(state, pattern, 0);
373
0
            if (i < 0)
374
0
                return i;
375
0
            if (!i)
376
0
                break;
377
0
        }
378
0
        TRACE(("|%p|%p|COUNT %zd\n", pattern, ptr,
379
0
               (SRE_CHAR*) state->ptr - ptr));
380
0
        return (SRE_CHAR*) state->ptr - ptr;
381
1.24M
    }
382
383
1.24M
    TRACE(("|%p|%p|COUNT %zd\n", pattern, ptr,
384
1.24M
           ptr - (SRE_CHAR*) state->ptr));
385
1.24M
    return ptr - (SRE_CHAR*) state->ptr;
386
1.24M
}
sre.c:sre_ucs1_count
Line
Count
Source
249
1.23M
{
250
1.23M
    SRE_CODE chr;
251
1.23M
    SRE_CODE arg;
252
1.23M
    SRE_CHAR c;
253
1.23M
    const SRE_CHAR* ptr = (const SRE_CHAR *)state->ptr;
254
1.23M
    const SRE_CHAR* end = (const SRE_CHAR *)state->end;
255
1.23M
    Py_ssize_t i;
256
1.23M
    INIT_TRACE(state);
257
258
    /* adjust end */
259
1.23M
    if (maxcount < end - ptr && maxcount != SRE_MAXREPEAT)
260
1.23M
        end = ptr + maxcount;
261
262
1.23M
    switch (pattern[0]) {
263
264
5.89k
    case SRE_OP_IN:
265
        /* repeated set */
266
5.89k
        TRACE(("|%p|%p|COUNT IN\n", pattern, ptr));
267
6.10M
        while (ptr < end && SRE(charset)(state, pattern + 2, *ptr))
268
6.09M
            ptr++;
269
5.89k
        break;
270
271
0
    case SRE_OP_ANY:
272
        /* repeated dot wildcard. */
273
0
        TRACE(("|%p|%p|COUNT ANY\n", pattern, ptr));
274
0
        while (ptr < end && !SRE_IS_LINEBREAK(*ptr))
275
0
            ptr++;
276
0
        break;
277
278
0
    case SRE_OP_ANY_ALL:
279
        /* repeated dot wildcard.  skip to the end of the target
280
           string, and backtrack from there */
281
0
        TRACE(("|%p|%p|COUNT ANY_ALL\n", pattern, ptr));
282
0
        ptr = end;
283
0
        break;
284
285
586
    case SRE_OP_LITERAL:
286
        /* repeated literal */
287
586
        chr = pattern[1];
288
586
        TRACE(("|%p|%p|COUNT LITERAL %d\n", pattern, ptr, chr));
289
586
        c = (SRE_CHAR) chr;
290
586
#if SIZEOF_SRE_CHAR < 4
291
586
        if ((SRE_CODE) c != chr)
292
0
            ; /* literal can't match: doesn't fit in char width */
293
586
        else
294
586
#endif
295
458k
        while (ptr < end && *ptr == c)
296
457k
            ptr++;
297
586
        break;
298
299
0
    case SRE_OP_LITERAL_IGNORE:
300
        /* repeated literal */
301
0
        chr = pattern[1];
302
0
        TRACE(("|%p|%p|COUNT LITERAL_IGNORE %d\n", pattern, ptr, chr));
303
0
        while (ptr < end && (SRE_CODE) sre_lower_ascii(*ptr) == chr)
304
0
            ptr++;
305
0
        break;
306
307
0
    case SRE_OP_LITERAL_UNI_IGNORE:
308
        /* repeated literal */
309
0
        chr = pattern[1];
310
0
        TRACE(("|%p|%p|COUNT LITERAL_UNI_IGNORE %d\n", pattern, ptr, chr));
311
0
        while (ptr < end && (SRE_CODE) sre_lower_unicode(*ptr) == chr)
312
0
            ptr++;
313
0
        break;
314
315
0
    case SRE_OP_LITERAL_LOC_IGNORE:
316
        /* repeated literal */
317
0
        chr = pattern[1];
318
0
        TRACE(("|%p|%p|COUNT LITERAL_LOC_IGNORE %d\n", pattern, ptr, chr));
319
0
        while (ptr < end && char_loc_ignore(chr, *ptr))
320
0
            ptr++;
321
0
        break;
322
323
0
    case SRE_OP_NOT_LITERAL:
324
        /* repeated non-literal */
325
0
        chr = pattern[1];
326
0
        TRACE(("|%p|%p|COUNT NOT_LITERAL %d\n", pattern, ptr, chr));
327
0
        c = (SRE_CHAR) chr;
328
0
#if SIZEOF_SRE_CHAR < 4
329
0
        if ((SRE_CODE) c != chr)
330
0
            ptr = end; /* literal can't match: doesn't fit in char width */
331
0
        else
332
0
#endif
333
0
        while (ptr < end && *ptr != c)
334
0
            ptr++;
335
0
        break;
336
337
0
    case SRE_OP_NOT_LITERAL_IGNORE:
338
        /* repeated non-literal */
339
0
        chr = pattern[1];
340
0
        TRACE(("|%p|%p|COUNT NOT_LITERAL_IGNORE %d\n", pattern, ptr, chr));
341
0
        while (ptr < end && (SRE_CODE) sre_lower_ascii(*ptr) != chr)
342
0
            ptr++;
343
0
        break;
344
345
0
    case SRE_OP_NOT_LITERAL_UNI_IGNORE:
346
        /* repeated non-literal */
347
0
        chr = pattern[1];
348
0
        TRACE(("|%p|%p|COUNT NOT_LITERAL_UNI_IGNORE %d\n", pattern, ptr, chr));
349
0
        while (ptr < end && (SRE_CODE) sre_lower_unicode(*ptr) != chr)
350
0
            ptr++;
351
0
        break;
352
353
0
    case SRE_OP_NOT_LITERAL_LOC_IGNORE:
354
        /* repeated non-literal */
355
0
        chr = pattern[1];
356
0
        TRACE(("|%p|%p|COUNT NOT_LITERAL_LOC_IGNORE %d\n", pattern, ptr, chr));
357
0
        while (ptr < end && !char_loc_ignore(chr, *ptr))
358
0
            ptr++;
359
0
        break;
360
361
1.23M
    case SRE_OP_CATEGORY:
362
1.23M
        arg = pattern[1];
363
1.23M
        TRACE(("|%p|%p|COUNT CATEGORY %d\n", pattern, ptr, arg));
364
1.23M
        while (ptr < end && sre_category(arg, *ptr))
365
1.38k
            ptr++;
366
1.23M
        break;
367
368
0
    default:
369
        /* repeated single character pattern */
370
0
        TRACE(("|%p|%p|COUNT SUBPATTERN\n", pattern, ptr));
371
0
        while ((SRE_CHAR*) state->ptr < end) {
372
0
            i = SRE(match)(state, pattern, 0);
373
0
            if (i < 0)
374
0
                return i;
375
0
            if (!i)
376
0
                break;
377
0
        }
378
0
        TRACE(("|%p|%p|COUNT %zd\n", pattern, ptr,
379
0
               (SRE_CHAR*) state->ptr - ptr));
380
0
        return (SRE_CHAR*) state->ptr - ptr;
381
1.23M
    }
382
383
1.23M
    TRACE(("|%p|%p|COUNT %zd\n", pattern, ptr,
384
1.23M
           ptr - (SRE_CHAR*) state->ptr));
385
1.23M
    return ptr - (SRE_CHAR*) state->ptr;
386
1.23M
}
sre.c:sre_ucs2_count
Line
Count
Source
249
1.65k
{
250
1.65k
    SRE_CODE chr;
251
1.65k
    SRE_CODE arg;
252
1.65k
    SRE_CHAR c;
253
1.65k
    const SRE_CHAR* ptr = (const SRE_CHAR *)state->ptr;
254
1.65k
    const SRE_CHAR* end = (const SRE_CHAR *)state->end;
255
1.65k
    Py_ssize_t i;
256
1.65k
    INIT_TRACE(state);
257
258
    /* adjust end */
259
1.65k
    if (maxcount < end - ptr && maxcount != SRE_MAXREPEAT)
260
0
        end = ptr + maxcount;
261
262
1.65k
    switch (pattern[0]) {
263
264
1.65k
    case SRE_OP_IN:
265
        /* repeated set */
266
1.65k
        TRACE(("|%p|%p|COUNT IN\n", pattern, ptr));
267
2.18M
        while (ptr < end && SRE(charset)(state, pattern + 2, *ptr))
268
2.18M
            ptr++;
269
1.65k
        break;
270
271
0
    case SRE_OP_ANY:
272
        /* repeated dot wildcard. */
273
0
        TRACE(("|%p|%p|COUNT ANY\n", pattern, ptr));
274
0
        while (ptr < end && !SRE_IS_LINEBREAK(*ptr))
275
0
            ptr++;
276
0
        break;
277
278
0
    case SRE_OP_ANY_ALL:
279
        /* repeated dot wildcard.  skip to the end of the target
280
           string, and backtrack from there */
281
0
        TRACE(("|%p|%p|COUNT ANY_ALL\n", pattern, ptr));
282
0
        ptr = end;
283
0
        break;
284
285
0
    case SRE_OP_LITERAL:
286
        /* repeated literal */
287
0
        chr = pattern[1];
288
0
        TRACE(("|%p|%p|COUNT LITERAL %d\n", pattern, ptr, chr));
289
0
        c = (SRE_CHAR) chr;
290
0
#if SIZEOF_SRE_CHAR < 4
291
0
        if ((SRE_CODE) c != chr)
292
0
            ; /* literal can't match: doesn't fit in char width */
293
0
        else
294
0
#endif
295
0
        while (ptr < end && *ptr == c)
296
0
            ptr++;
297
0
        break;
298
299
0
    case SRE_OP_LITERAL_IGNORE:
300
        /* repeated literal */
301
0
        chr = pattern[1];
302
0
        TRACE(("|%p|%p|COUNT LITERAL_IGNORE %d\n", pattern, ptr, chr));
303
0
        while (ptr < end && (SRE_CODE) sre_lower_ascii(*ptr) == chr)
304
0
            ptr++;
305
0
        break;
306
307
0
    case SRE_OP_LITERAL_UNI_IGNORE:
308
        /* repeated literal */
309
0
        chr = pattern[1];
310
0
        TRACE(("|%p|%p|COUNT LITERAL_UNI_IGNORE %d\n", pattern, ptr, chr));
311
0
        while (ptr < end && (SRE_CODE) sre_lower_unicode(*ptr) == chr)
312
0
            ptr++;
313
0
        break;
314
315
0
    case SRE_OP_LITERAL_LOC_IGNORE:
316
        /* repeated literal */
317
0
        chr = pattern[1];
318
0
        TRACE(("|%p|%p|COUNT LITERAL_LOC_IGNORE %d\n", pattern, ptr, chr));
319
0
        while (ptr < end && char_loc_ignore(chr, *ptr))
320
0
            ptr++;
321
0
        break;
322
323
0
    case SRE_OP_NOT_LITERAL:
324
        /* repeated non-literal */
325
0
        chr = pattern[1];
326
0
        TRACE(("|%p|%p|COUNT NOT_LITERAL %d\n", pattern, ptr, chr));
327
0
        c = (SRE_CHAR) chr;
328
0
#if SIZEOF_SRE_CHAR < 4
329
0
        if ((SRE_CODE) c != chr)
330
0
            ptr = end; /* literal can't match: doesn't fit in char width */
331
0
        else
332
0
#endif
333
0
        while (ptr < end && *ptr != c)
334
0
            ptr++;
335
0
        break;
336
337
0
    case SRE_OP_NOT_LITERAL_IGNORE:
338
        /* repeated non-literal */
339
0
        chr = pattern[1];
340
0
        TRACE(("|%p|%p|COUNT NOT_LITERAL_IGNORE %d\n", pattern, ptr, chr));
341
0
        while (ptr < end && (SRE_CODE) sre_lower_ascii(*ptr) != chr)
342
0
            ptr++;
343
0
        break;
344
345
0
    case SRE_OP_NOT_LITERAL_UNI_IGNORE:
346
        /* repeated non-literal */
347
0
        chr = pattern[1];
348
0
        TRACE(("|%p|%p|COUNT NOT_LITERAL_UNI_IGNORE %d\n", pattern, ptr, chr));
349
0
        while (ptr < end && (SRE_CODE) sre_lower_unicode(*ptr) != chr)
350
0
            ptr++;
351
0
        break;
352
353
0
    case SRE_OP_NOT_LITERAL_LOC_IGNORE:
354
        /* repeated non-literal */
355
0
        chr = pattern[1];
356
0
        TRACE(("|%p|%p|COUNT NOT_LITERAL_LOC_IGNORE %d\n", pattern, ptr, chr));
357
0
        while (ptr < end && !char_loc_ignore(chr, *ptr))
358
0
            ptr++;
359
0
        break;
360
361
0
    case SRE_OP_CATEGORY:
362
0
        arg = pattern[1];
363
0
        TRACE(("|%p|%p|COUNT CATEGORY %d\n", pattern, ptr, arg));
364
0
        while (ptr < end && sre_category(arg, *ptr))
365
0
            ptr++;
366
0
        break;
367
368
0
    default:
369
        /* repeated single character pattern */
370
0
        TRACE(("|%p|%p|COUNT SUBPATTERN\n", pattern, ptr));
371
0
        while ((SRE_CHAR*) state->ptr < end) {
372
0
            i = SRE(match)(state, pattern, 0);
373
0
            if (i < 0)
374
0
                return i;
375
0
            if (!i)
376
0
                break;
377
0
        }
378
0
        TRACE(("|%p|%p|COUNT %zd\n", pattern, ptr,
379
0
               (SRE_CHAR*) state->ptr - ptr));
380
0
        return (SRE_CHAR*) state->ptr - ptr;
381
1.65k
    }
382
383
1.65k
    TRACE(("|%p|%p|COUNT %zd\n", pattern, ptr,
384
1.65k
           ptr - (SRE_CHAR*) state->ptr));
385
1.65k
    return ptr - (SRE_CHAR*) state->ptr;
386
1.65k
}
sre.c:sre_ucs4_count
Line
Count
Source
249
2.16k
{
250
2.16k
    SRE_CODE chr;
251
2.16k
    SRE_CODE arg;
252
2.16k
    SRE_CHAR c;
253
2.16k
    const SRE_CHAR* ptr = (const SRE_CHAR *)state->ptr;
254
2.16k
    const SRE_CHAR* end = (const SRE_CHAR *)state->end;
255
2.16k
    Py_ssize_t i;
256
2.16k
    INIT_TRACE(state);
257
258
    /* adjust end */
259
2.16k
    if (maxcount < end - ptr && maxcount != SRE_MAXREPEAT)
260
0
        end = ptr + maxcount;
261
262
2.16k
    switch (pattern[0]) {
263
264
2.16k
    case SRE_OP_IN:
265
        /* repeated set */
266
2.16k
        TRACE(("|%p|%p|COUNT IN\n", pattern, ptr));
267
2.73M
        while (ptr < end && SRE(charset)(state, pattern + 2, *ptr))
268
2.73M
            ptr++;
269
2.16k
        break;
270
271
0
    case SRE_OP_ANY:
272
        /* repeated dot wildcard. */
273
0
        TRACE(("|%p|%p|COUNT ANY\n", pattern, ptr));
274
0
        while (ptr < end && !SRE_IS_LINEBREAK(*ptr))
275
0
            ptr++;
276
0
        break;
277
278
0
    case SRE_OP_ANY_ALL:
279
        /* repeated dot wildcard.  skip to the end of the target
280
           string, and backtrack from there */
281
0
        TRACE(("|%p|%p|COUNT ANY_ALL\n", pattern, ptr));
282
0
        ptr = end;
283
0
        break;
284
285
0
    case SRE_OP_LITERAL:
286
        /* repeated literal */
287
0
        chr = pattern[1];
288
0
        TRACE(("|%p|%p|COUNT LITERAL %d\n", pattern, ptr, chr));
289
0
        c = (SRE_CHAR) chr;
290
#if SIZEOF_SRE_CHAR < 4
291
        if ((SRE_CODE) c != chr)
292
            ; /* literal can't match: doesn't fit in char width */
293
        else
294
#endif
295
0
        while (ptr < end && *ptr == c)
296
0
            ptr++;
297
0
        break;
298
299
0
    case SRE_OP_LITERAL_IGNORE:
300
        /* repeated literal */
301
0
        chr = pattern[1];
302
0
        TRACE(("|%p|%p|COUNT LITERAL_IGNORE %d\n", pattern, ptr, chr));
303
0
        while (ptr < end && (SRE_CODE) sre_lower_ascii(*ptr) == chr)
304
0
            ptr++;
305
0
        break;
306
307
0
    case SRE_OP_LITERAL_UNI_IGNORE:
308
        /* repeated literal */
309
0
        chr = pattern[1];
310
0
        TRACE(("|%p|%p|COUNT LITERAL_UNI_IGNORE %d\n", pattern, ptr, chr));
311
0
        while (ptr < end && (SRE_CODE) sre_lower_unicode(*ptr) == chr)
312
0
            ptr++;
313
0
        break;
314
315
0
    case SRE_OP_LITERAL_LOC_IGNORE:
316
        /* repeated literal */
317
0
        chr = pattern[1];
318
0
        TRACE(("|%p|%p|COUNT LITERAL_LOC_IGNORE %d\n", pattern, ptr, chr));
319
0
        while (ptr < end && char_loc_ignore(chr, *ptr))
320
0
            ptr++;
321
0
        break;
322
323
0
    case SRE_OP_NOT_LITERAL:
324
        /* repeated non-literal */
325
0
        chr = pattern[1];
326
0
        TRACE(("|%p|%p|COUNT NOT_LITERAL %d\n", pattern, ptr, chr));
327
0
        c = (SRE_CHAR) chr;
328
#if SIZEOF_SRE_CHAR < 4
329
        if ((SRE_CODE) c != chr)
330
            ptr = end; /* literal can't match: doesn't fit in char width */
331
        else
332
#endif
333
0
        while (ptr < end && *ptr != c)
334
0
            ptr++;
335
0
        break;
336
337
0
    case SRE_OP_NOT_LITERAL_IGNORE:
338
        /* repeated non-literal */
339
0
        chr = pattern[1];
340
0
        TRACE(("|%p|%p|COUNT NOT_LITERAL_IGNORE %d\n", pattern, ptr, chr));
341
0
        while (ptr < end && (SRE_CODE) sre_lower_ascii(*ptr) != chr)
342
0
            ptr++;
343
0
        break;
344
345
0
    case SRE_OP_NOT_LITERAL_UNI_IGNORE:
346
        /* repeated non-literal */
347
0
        chr = pattern[1];
348
0
        TRACE(("|%p|%p|COUNT NOT_LITERAL_UNI_IGNORE %d\n", pattern, ptr, chr));
349
0
        while (ptr < end && (SRE_CODE) sre_lower_unicode(*ptr) != chr)
350
0
            ptr++;
351
0
        break;
352
353
0
    case SRE_OP_NOT_LITERAL_LOC_IGNORE:
354
        /* repeated non-literal */
355
0
        chr = pattern[1];
356
0
        TRACE(("|%p|%p|COUNT NOT_LITERAL_LOC_IGNORE %d\n", pattern, ptr, chr));
357
0
        while (ptr < end && !char_loc_ignore(chr, *ptr))
358
0
            ptr++;
359
0
        break;
360
361
0
    case SRE_OP_CATEGORY:
362
0
        arg = pattern[1];
363
0
        TRACE(("|%p|%p|COUNT CATEGORY %d\n", pattern, ptr, arg));
364
0
        while (ptr < end && sre_category(arg, *ptr))
365
0
            ptr++;
366
0
        break;
367
368
0
    default:
369
        /* repeated single character pattern */
370
0
        TRACE(("|%p|%p|COUNT SUBPATTERN\n", pattern, ptr));
371
0
        while ((SRE_CHAR*) state->ptr < end) {
372
0
            i = SRE(match)(state, pattern, 0);
373
0
            if (i < 0)
374
0
                return i;
375
0
            if (!i)
376
0
                break;
377
0
        }
378
0
        TRACE(("|%p|%p|COUNT %zd\n", pattern, ptr,
379
0
               (SRE_CHAR*) state->ptr - ptr));
380
0
        return (SRE_CHAR*) state->ptr - ptr;
381
2.16k
    }
382
383
2.16k
    TRACE(("|%p|%p|COUNT %zd\n", pattern, ptr,
384
2.16k
           ptr - (SRE_CHAR*) state->ptr));
385
2.16k
    return ptr - (SRE_CHAR*) state->ptr;
386
2.16k
}
387
388
/* The macros below should be used to protect recursive SRE(match)()
389
 * calls that *failed* and do *not* return immediately (IOW, those
390
 * that will backtrack). Explaining:
391
 *
392
 * - Recursive SRE(match)() returned true: that's usually a success
393
 *   (besides atypical cases like ASSERT_NOT), therefore there's no
394
 *   reason to restore lastmark;
395
 *
396
 * - Recursive SRE(match)() returned false but the current SRE(match)()
397
 *   is returning to the caller: If the current SRE(match)() is the
398
 *   top function of the recursion, returning false will be a matching
399
 *   failure, and it doesn't matter where lastmark is pointing to.
400
 *   If it's *not* the top function, it will be a recursive SRE(match)()
401
 *   failure by itself, and the calling SRE(match)() will have to deal
402
 *   with the failure by the same rules explained here (it will restore
403
 *   lastmark by itself if necessary);
404
 *
405
 * - Recursive SRE(match)() returned false, and will continue the
406
 *   outside 'for' loop: must be protected when breaking, since the next
407
 *   OP could potentially depend on lastmark;
408
 *
409
 * - Recursive SRE(match)() returned false, and will be called again
410
 *   inside a local for/while loop: must be protected between each
411
 *   loop iteration, since the recursive SRE(match)() could do anything,
412
 *   and could potentially depend on lastmark.
413
 *
414
 * For more information, check the discussion at SF patch #712900.
415
 */
416
#define LASTMARK_SAVE()     \
417
1.35M
    do { \
418
1.35M
        ctx->lastmark = state->lastmark; \
419
1.35M
        ctx->lastindex = state->lastindex; \
420
1.35M
    } while (0)
421
#define LASTMARK_RESTORE()  \
422
1.31M
    do { \
423
1.31M
        state->lastmark = ctx->lastmark; \
424
1.31M
        state->lastindex = ctx->lastindex; \
425
1.31M
    } while (0)
426
427
#define LAST_PTR_PUSH()     \
428
1.34M
    do { \
429
1.34M
        TRACE(("push last_ptr: %zd", \
430
1.34M
                PTR_TO_INDEX(ctx->u.rep->last_ptr))); \
431
1.34M
        DATA_PUSH(&ctx->u.rep->last_ptr); \
432
1.34M
    } while (0)
433
#define LAST_PTR_POP()  \
434
1.34M
    do { \
435
1.34M
        DATA_POP(&ctx->u.rep->last_ptr); \
436
1.34M
        TRACE(("pop last_ptr: %zd", \
437
1.34M
                PTR_TO_INDEX(ctx->u.rep->last_ptr))); \
438
1.34M
    } while (0)
439
440
0
#define RETURN_ERROR(i) do { return i; } while(0)
441
2.63M
#define RETURN_FAILURE do { ret = 0; goto exit; } while(0)
442
133k
#define RETURN_SUCCESS do { ret = 1; goto exit; } while(0)
443
444
#define RETURN_ON_ERROR(i) \
445
2.59M
    do { if (i < 0) RETURN_ERROR(i); } while (0)
446
#define RETURN_ON_SUCCESS(i) \
447
1.23M
    do { RETURN_ON_ERROR(i); if (i > 0) RETURN_SUCCESS; } while (0)
448
#define RETURN_ON_FAILURE(i) \
449
14
    do { RETURN_ON_ERROR(i); if (i == 0) RETURN_FAILURE; } while (0)
450
451
2.76M
#define DATA_STACK_ALLOC(state, type, ptr) \
452
2.76M
do { \
453
2.76M
    alloc_pos = state->data_stack_base; \
454
2.76M
    TRACE(("allocating %s in %zd (%zd)\n", \
455
2.76M
           Py_STRINGIFY(type), alloc_pos, sizeof(type))); \
456
2.76M
    if (sizeof(type) > state->data_stack_size - alloc_pos) { \
457
12.1k
        int j = data_stack_grow(state, sizeof(type)); \
458
12.1k
        if (j < 0) return j; \
459
12.1k
        if (ctx_pos != -1) \
460
12.1k
            DATA_STACK_LOOKUP_AT(state, SRE(match_context), ctx, ctx_pos); \
461
12.1k
    } \
462
2.76M
    ptr = (type*)(state->data_stack+alloc_pos); \
463
2.76M
    state->data_stack_base += sizeof(type); \
464
2.76M
} while (0)
465
466
4.00M
#define DATA_STACK_LOOKUP_AT(state, type, ptr, pos) \
467
4.00M
do { \
468
4.00M
    TRACE(("looking up %s at %zd\n", Py_STRINGIFY(type), pos)); \
469
4.00M
    ptr = (type*)(state->data_stack+pos); \
470
4.00M
} while (0)
471
472
2.60M
#define DATA_STACK_PUSH(state, data, size) \
473
2.60M
do { \
474
2.60M
    TRACE(("copy data in %p to %zd (%zd)\n", \
475
2.60M
           data, state->data_stack_base, size)); \
476
2.60M
    if (size > state->data_stack_size - state->data_stack_base) { \
477
594
        int j = data_stack_grow(state, size); \
478
594
        if (j < 0) return j; \
479
594
        if (ctx_pos != -1) \
480
594
            DATA_STACK_LOOKUP_AT(state, SRE(match_context), ctx, ctx_pos); \
481
594
    } \
482
2.60M
    memcpy(state->data_stack+state->data_stack_base, data, size); \
483
2.60M
    state->data_stack_base += size; \
484
2.60M
} while (0)
485
486
/* We add an explicit cast to memcpy here because MSVC has a bug when
487
   compiling C code where it believes that `const void**` cannot be
488
   safely casted to `void*`, see bpo-39943 for details. */
489
2.49M
#define DATA_STACK_POP(state, data, size, discard) \
490
2.49M
do { \
491
2.49M
    TRACE(("copy data to %p from %zd (%zd)\n", \
492
2.49M
           data, state->data_stack_base-size, size)); \
493
2.49M
    memcpy((void*) data, state->data_stack+state->data_stack_base-size, size); \
494
2.49M
    if (discard) \
495
2.49M
        state->data_stack_base -= size; \
496
2.49M
} while (0)
497
498
2.87M
#define DATA_STACK_POP_DISCARD(state, size) \
499
2.87M
do { \
500
2.87M
    TRACE(("discard data from %zd (%zd)\n", \
501
2.87M
           state->data_stack_base-size, size)); \
502
2.87M
    state->data_stack_base -= size; \
503
2.87M
} while(0)
504
505
#define DATA_PUSH(x) \
506
1.34M
    DATA_STACK_PUSH(state, (x), sizeof(*(x)))
507
#define DATA_POP(x) \
508
1.34M
    DATA_STACK_POP(state, (x), sizeof(*(x)), 1)
509
#define DATA_POP_DISCARD(x) \
510
2.76M
    DATA_STACK_POP_DISCARD(state, sizeof(*(x)))
511
#define DATA_ALLOC(t,p) \
512
2.76M
    DATA_STACK_ALLOC(state, t, p)
513
#define DATA_LOOKUP_AT(t,p,pos) \
514
3.99M
    DATA_STACK_LOOKUP_AT(state,t,p,pos)
515
516
#define PTR_TO_INDEX(ptr) \
517
    ((ptr) ? ((char*)(ptr) - (char*)state->beginning) / state->charsize : -1)
518
519
#if VERBOSE
520
#  define MARK_TRACE(label, lastmark) \
521
    do if (DO_TRACE) { \
522
        TRACE(("%s %d marks:", (label), (lastmark)+1)); \
523
        for (int j = 0; j <= (lastmark); j++) { \
524
            if (j && (j & 1) == 0) { \
525
                TRACE((" ")); \
526
            } \
527
            TRACE((" %zd", PTR_TO_INDEX(state->mark[j]))); \
528
        } \
529
        TRACE(("\n")); \
530
    } while (0)
531
#else
532
#  define MARK_TRACE(label, lastmark)
533
#endif
534
#define MARK_PUSH(lastmark) \
535
1.34M
    do if (lastmark >= 0) { \
536
1.26M
        MARK_TRACE("push", (lastmark)); \
537
1.26M
        size_t _marks_size = (lastmark+1) * sizeof(void*); \
538
1.26M
        DATA_STACK_PUSH(state, state->mark, _marks_size); \
539
1.34M
    } while (0)
540
#define MARK_POP(lastmark) \
541
1.23M
    do if (lastmark >= 0) { \
542
1.14M
        size_t _marks_size = (lastmark+1) * sizeof(void*); \
543
1.14M
        DATA_STACK_POP(state, state->mark, _marks_size, 1); \
544
1.14M
        MARK_TRACE("pop", (lastmark)); \
545
1.23M
    } while (0)
546
#define MARK_POP_KEEP(lastmark) \
547
0
    do if (lastmark >= 0) { \
548
0
        size_t _marks_size = (lastmark+1) * sizeof(void*); \
549
0
        DATA_STACK_POP(state, state->mark, _marks_size, 0); \
550
0
        MARK_TRACE("pop keep", (lastmark)); \
551
0
    } while (0)
552
#define MARK_POP_DISCARD(lastmark) \
553
114k
    do if (lastmark >= 0) { \
554
114k
        size_t _marks_size = (lastmark+1) * sizeof(void*); \
555
114k
        DATA_STACK_POP_DISCARD(state, _marks_size); \
556
114k
        MARK_TRACE("pop discard", (lastmark)); \
557
114k
    } while (0)
558
559
10.1k
#define JUMP_NONE            0
560
0
#define JUMP_MAX_UNTIL_1     1
561
1.34M
#define JUMP_MAX_UNTIL_2     2
562
1.23M
#define JUMP_MAX_UNTIL_3     3
563
0
#define JUMP_MIN_UNTIL_1     4
564
0
#define JUMP_MIN_UNTIL_2     5
565
0
#define JUMP_MIN_UNTIL_3     6
566
83.4k
#define JUMP_REPEAT          7
567
1
#define JUMP_REPEAT_ONE_1    8
568
94.1k
#define JUMP_REPEAT_ONE_2    9
569
0
#define JUMP_MIN_REPEAT_ONE  10
570
42
#define JUMP_BRANCH          11
571
14
#define JUMP_ASSERT          12
572
0
#define JUMP_ASSERT_NOT      13
573
0
#define JUMP_POSS_REPEAT_1   14
574
0
#define JUMP_POSS_REPEAT_2   15
575
0
#define JUMP_ATOMIC_GROUP    16
576
577
#define DO_JUMPX(jumpvalue, jumplabel, nextpattern, toplevel_) \
578
2.75M
    ctx->pattern = pattern; \
579
2.75M
    ctx->ptr = ptr; \
580
2.75M
    DATA_ALLOC(SRE(match_context), nextctx); \
581
2.75M
    nextctx->pattern = nextpattern; \
582
2.75M
    nextctx->toplevel = toplevel_; \
583
2.75M
    nextctx->jump = jumpvalue; \
584
2.75M
    nextctx->last_ctx_pos = ctx_pos; \
585
2.75M
    pattern = nextpattern; \
586
2.75M
    ctx_pos = alloc_pos; \
587
2.75M
    ctx = nextctx; \
588
2.75M
    goto entrance; \
589
2.75M
    jumplabel: \
590
2.75M
    pattern = ctx->pattern; \
591
2.75M
    ptr = ctx->ptr;
592
593
#define DO_JUMP(jumpvalue, jumplabel, nextpattern) \
594
2.75M
    DO_JUMPX(jumpvalue, jumplabel, nextpattern, ctx->toplevel)
595
596
#define DO_JUMP0(jumpvalue, jumplabel, nextpattern) \
597
14
    DO_JUMPX(jumpvalue, jumplabel, nextpattern, 0)
598
599
typedef struct {
600
    Py_ssize_t count;
601
    union {
602
        SRE_CODE chr;
603
        SRE_REPEAT* rep;
604
    } u;
605
    int lastmark;
606
    int lastindex;
607
    const SRE_CODE* pattern;
608
    const SRE_CHAR* ptr;
609
    int toplevel;
610
    int jump;
611
    Py_ssize_t last_ctx_pos;
612
} SRE(match_context);
613
614
#define _MAYBE_CHECK_SIGNALS                                       \
615
6.63M
    do {                                                           \
616
6.63M
        if ((0 == (++sigcount & 0xfff)) && PyErr_CheckSignals()) { \
617
0
            RETURN_ERROR(SRE_ERROR_INTERRUPTED);                   \
618
0
        }                                                          \
619
6.63M
    } while (0)
620
621
#ifdef Py_DEBUG
622
# define MAYBE_CHECK_SIGNALS                                       \
623
    do {                                                           \
624
        _MAYBE_CHECK_SIGNALS;                                      \
625
        if (state->fail_after_count >= 0) {                        \
626
            if (state->fail_after_count-- == 0) {                  \
627
                PyErr_SetNone(state->fail_after_exc);              \
628
                RETURN_ERROR(SRE_ERROR_INTERRUPTED);               \
629
            }                                                      \
630
        }                                                          \
631
    } while (0)
632
#else
633
6.63M
# define MAYBE_CHECK_SIGNALS _MAYBE_CHECK_SIGNALS
634
#endif /* Py_DEBUG */
635
636
#ifdef HAVE_COMPUTED_GOTOS
637
    #ifndef USE_COMPUTED_GOTOS
638
    #define USE_COMPUTED_GOTOS 1
639
    #endif
640
#elif defined(USE_COMPUTED_GOTOS) && USE_COMPUTED_GOTOS
641
    #error "Computed gotos are not supported on this compiler."
642
#else
643
    #undef USE_COMPUTED_GOTOS
644
    #define USE_COMPUTED_GOTOS 0
645
#endif
646
647
#if USE_COMPUTED_GOTOS
648
6.63M
    #define TARGET(OP) TARGET_ ## OP
649
    #define DISPATCH                       \
650
6.63M
        do {                               \
651
6.63M
            MAYBE_CHECK_SIGNALS;           \
652
6.63M
            goto *sre_targets[*pattern++]; \
653
6.63M
        } while (0)
654
#else
655
    #define TARGET(OP) case OP
656
    #define DISPATCH goto dispatch
657
#endif
658
659
/* check if string matches the given pattern.  returns <0 for
660
   error, 0 for failure, and 1 for success */
661
LOCAL(Py_ssize_t)
662
SRE(match)(SRE_STATE* state, const SRE_CODE* pattern, int toplevel)
663
10.1k
{
664
10.1k
    const SRE_CHAR* end = (const SRE_CHAR *)state->end;
665
10.1k
    Py_ssize_t alloc_pos, ctx_pos = -1;
666
10.1k
    Py_ssize_t ret = 0;
667
10.1k
    int jump;
668
10.1k
    unsigned int sigcount = state->sigcount;
669
670
10.1k
    SRE(match_context)* ctx;
671
10.1k
    SRE(match_context)* nextctx;
672
10.1k
    INIT_TRACE(state);
673
674
10.1k
    TRACE(("|%p|%p|ENTER\n", pattern, state->ptr));
675
676
10.1k
    DATA_ALLOC(SRE(match_context), ctx);
677
10.1k
    ctx->last_ctx_pos = -1;
678
10.1k
    ctx->jump = JUMP_NONE;
679
10.1k
    ctx->toplevel = toplevel;
680
10.1k
    ctx_pos = alloc_pos;
681
682
10.1k
#if USE_COMPUTED_GOTOS
683
10.1k
#include "sre_targets.h"
684
10.1k
#endif
685
686
2.76M
entrance:
687
688
2.76M
    ;  // Fashion statement.
689
2.76M
    const SRE_CHAR *ptr = (SRE_CHAR *)state->ptr;
690
691
2.76M
    if (pattern[0] == SRE_OP_INFO) {
692
        /* optimization info block */
693
        /* <INFO> <1=skip> <2=flags> <3=min> ... */
694
10.1k
        if (pattern[3] && (uintptr_t)(end - ptr) < pattern[3]) {
695
2
            TRACE(("reject (got %tu chars, need %zu)\n",
696
2
                   end - ptr, (size_t) pattern[3]));
697
2
            RETURN_FAILURE;
698
2
        }
699
10.1k
        pattern += pattern[1] + 1;
700
10.1k
    }
701
702
2.76M
#if USE_COMPUTED_GOTOS
703
2.76M
    DISPATCH;
704
#else
705
dispatch:
706
    MAYBE_CHECK_SIGNALS;
707
    switch (*pattern++)
708
#endif
709
2.76M
    {
710
711
2.76M
        TARGET(SRE_OP_MARK):
712
            /* set mark */
713
            /* <MARK> <gid> */
714
2.60M
            TRACE(("|%p|%p|MARK %d\n", pattern,
715
2.60M
                   ptr, pattern[0]));
716
2.60M
            {
717
2.60M
                int i = pattern[0];
718
2.60M
                if (i & 1)
719
1.26M
                    state->lastindex = i/2 + 1;
720
2.60M
                if (i > state->lastmark) {
721
                    /* state->lastmark is the highest valid index in the
722
                       state->mark array.  If it is increased by more than 1,
723
                       the intervening marks must be set to NULL to signal
724
                       that these marks have not been encountered. */
725
83.7k
                    int j = state->lastmark + 1;
726
84.0k
                    while (j < i)
727
244
                        state->mark[j++] = NULL;
728
83.7k
                    state->lastmark = i;
729
83.7k
                }
730
2.60M
                state->mark[i] = ptr;
731
2.60M
            }
732
2.60M
            pattern++;
733
2.60M
            DISPATCH;
734
735
2.60M
        TARGET(SRE_OP_LITERAL):
736
            /* match literal string */
737
            /* <LITERAL> <code> */
738
40
            TRACE(("|%p|%p|LITERAL %d\n", pattern,
739
40
                   ptr, *pattern));
740
40
            if (ptr >= end || (SRE_CODE) ptr[0] != pattern[0])
741
7
                RETURN_FAILURE;
742
33
            pattern++;
743
33
            ptr++;
744
33
            DISPATCH;
745
746
33
        TARGET(SRE_OP_NOT_LITERAL):
747
            /* match anything that is not literal character */
748
            /* <NOT_LITERAL> <code> */
749
0
            TRACE(("|%p|%p|NOT_LITERAL %d\n", pattern,
750
0
                   ptr, *pattern));
751
0
            if (ptr >= end || (SRE_CODE) ptr[0] == pattern[0])
752
0
                RETURN_FAILURE;
753
0
            pattern++;
754
0
            ptr++;
755
0
            DISPATCH;
756
757
8.56k
        TARGET(SRE_OP_SUCCESS):
758
            /* end of pattern */
759
8.56k
            TRACE(("|%p|%p|SUCCESS\n", pattern, ptr));
760
8.56k
            if (ctx->toplevel &&
761
8.56k
                ((state->match_all && ptr != state->end) ||
762
8.56k
                 (state->must_advance && ptr == state->start)))
763
0
            {
764
0
                RETURN_FAILURE;
765
0
            }
766
8.56k
            state->ptr = ptr;
767
8.56k
            RETURN_SUCCESS;
768
769
329
        TARGET(SRE_OP_AT):
770
            /* match at given position */
771
            /* <AT> <code> */
772
329
            TRACE(("|%p|%p|AT %d\n", pattern, ptr, *pattern));
773
329
            if (!SRE(at)(state, ptr, *pattern))
774
24
                RETURN_FAILURE;
775
305
            pattern++;
776
305
            DISPATCH;
777
778
305
        TARGET(SRE_OP_CATEGORY):
779
            /* match at given category */
780
            /* <CATEGORY> <code> */
781
12
            TRACE(("|%p|%p|CATEGORY %d\n", pattern,
782
12
                   ptr, *pattern));
783
12
            if (ptr >= end || !sre_category(pattern[0], ptr[0]))
784
12
                RETURN_FAILURE;
785
0
            pattern++;
786
0
            ptr++;
787
0
            DISPATCH;
788
789
4
        TARGET(SRE_OP_ANY):
790
            /* match anything (except a newline) */
791
            /* <ANY> */
792
4
            TRACE(("|%p|%p|ANY\n", pattern, ptr));
793
4
            if (ptr >= end || SRE_IS_LINEBREAK(ptr[0]))
794
1
                RETURN_FAILURE;
795
3
            ptr++;
796
3
            DISPATCH;
797
798
3
        TARGET(SRE_OP_ANY_ALL):
799
            /* match anything */
800
            /* <ANY_ALL> */
801
0
            TRACE(("|%p|%p|ANY_ALL\n", pattern, ptr));
802
0
            if (ptr >= end)
803
0
                RETURN_FAILURE;
804
0
            ptr++;
805
0
            DISPATCH;
806
807
1.34M
        TARGET(SRE_OP_IN):
808
            /* match set member (or non_member) */
809
            /* <IN> <skip> <set> */
810
1.34M
            TRACE(("|%p|%p|IN\n", pattern, ptr));
811
1.34M
            if (ptr >= end ||
812
1.34M
                !SRE(charset)(state, pattern + 1, *ptr))
813
83.3k
                RETURN_FAILURE;
814
1.26M
            pattern += pattern[0];
815
1.26M
            ptr++;
816
1.26M
            DISPATCH;
817
818
1.26M
        TARGET(SRE_OP_LITERAL_IGNORE):
819
0
            TRACE(("|%p|%p|LITERAL_IGNORE %d\n",
820
0
                   pattern, ptr, pattern[0]));
821
0
            if (ptr >= end ||
822
0
                sre_lower_ascii(*ptr) != *pattern)
823
0
                RETURN_FAILURE;
824
0
            pattern++;
825
0
            ptr++;
826
0
            DISPATCH;
827
828
28
        TARGET(SRE_OP_LITERAL_UNI_IGNORE):
829
28
            TRACE(("|%p|%p|LITERAL_UNI_IGNORE %d\n",
830
28
                   pattern, ptr, pattern[0]));
831
28
            if (ptr >= end ||
832
28
                sre_lower_unicode(*ptr) != *pattern)
833
0
                RETURN_FAILURE;
834
28
            pattern++;
835
28
            ptr++;
836
28
            DISPATCH;
837
838
28
        TARGET(SRE_OP_LITERAL_LOC_IGNORE):
839
0
            TRACE(("|%p|%p|LITERAL_LOC_IGNORE %d\n",
840
0
                   pattern, ptr, pattern[0]));
841
0
            if (ptr >= end
842
0
                || !char_loc_ignore(*pattern, *ptr))
843
0
                RETURN_FAILURE;
844
0
            pattern++;
845
0
            ptr++;
846
0
            DISPATCH;
847
848
0
        TARGET(SRE_OP_NOT_LITERAL_IGNORE):
849
0
            TRACE(("|%p|%p|NOT_LITERAL_IGNORE %d\n",
850
0
                   pattern, ptr, *pattern));
851
0
            if (ptr >= end ||
852
0
                sre_lower_ascii(*ptr) == *pattern)
853
0
                RETURN_FAILURE;
854
0
            pattern++;
855
0
            ptr++;
856
0
            DISPATCH;
857
858
0
        TARGET(SRE_OP_NOT_LITERAL_UNI_IGNORE):
859
0
            TRACE(("|%p|%p|NOT_LITERAL_UNI_IGNORE %d\n",
860
0
                   pattern, ptr, *pattern));
861
0
            if (ptr >= end ||
862
0
                sre_lower_unicode(*ptr) == *pattern)
863
0
                RETURN_FAILURE;
864
0
            pattern++;
865
0
            ptr++;
866
0
            DISPATCH;
867
868
0
        TARGET(SRE_OP_NOT_LITERAL_LOC_IGNORE):
869
0
            TRACE(("|%p|%p|NOT_LITERAL_LOC_IGNORE %d\n",
870
0
                   pattern, ptr, *pattern));
871
0
            if (ptr >= end
872
0
                || char_loc_ignore(*pattern, *ptr))
873
0
                RETURN_FAILURE;
874
0
            pattern++;
875
0
            ptr++;
876
0
            DISPATCH;
877
878
0
        TARGET(SRE_OP_IN_IGNORE):
879
0
            TRACE(("|%p|%p|IN_IGNORE\n", pattern, ptr));
880
0
            if (ptr >= end
881
0
                || !SRE(charset)(state, pattern+1,
882
0
                                 (SRE_CODE)sre_lower_ascii(*ptr)))
883
0
                RETURN_FAILURE;
884
0
            pattern += pattern[0];
885
0
            ptr++;
886
0
            DISPATCH;
887
888
24
        TARGET(SRE_OP_IN_UNI_IGNORE):
889
24
            TRACE(("|%p|%p|IN_UNI_IGNORE\n", pattern, ptr));
890
24
            if (ptr >= end
891
16
                || !SRE(charset)(state, pattern+1,
892
16
                                 (SRE_CODE)sre_lower_unicode(*ptr)))
893
16
                RETURN_FAILURE;
894
8
            pattern += pattern[0];
895
8
            ptr++;
896
8
            DISPATCH;
897
898
8
        TARGET(SRE_OP_IN_LOC_IGNORE):
899
0
            TRACE(("|%p|%p|IN_LOC_IGNORE\n", pattern, ptr));
900
0
            if (ptr >= end
901
0
                || !SRE(charset_loc_ignore)(state, pattern+1, *ptr))
902
0
                RETURN_FAILURE;
903
0
            pattern += pattern[0];
904
0
            ptr++;
905
0
            DISPATCH;
906
907
13
        TARGET(SRE_OP_JUMP):
908
13
        TARGET(SRE_OP_INFO):
909
            /* jump forward */
910
            /* <JUMP> <offset> */
911
13
            TRACE(("|%p|%p|JUMP %d\n", pattern,
912
13
                   ptr, pattern[0]));
913
13
            pattern += pattern[0];
914
13
            DISPATCH;
915
916
28
        TARGET(SRE_OP_BRANCH):
917
            /* alternation */
918
            /* <BRANCH> <0=skip> code <JUMP> ... <NULL> */
919
28
            TRACE(("|%p|%p|BRANCH\n", pattern, ptr));
920
28
            LASTMARK_SAVE();
921
28
            if (state->save_marks)
922
0
                MARK_PUSH(ctx->lastmark);
923
75
            for (; pattern[0]; pattern += pattern[0]) {
924
60
                if (pattern[1] == SRE_OP_LITERAL &&
925
20
                    (ptr >= end ||
926
20
                     (SRE_CODE) *ptr != pattern[2]))
927
18
                    continue;
928
42
                if (pattern[1] == SRE_OP_IN &&
929
0
                    (ptr >= end ||
930
0
                     !SRE(charset)(state, pattern + 3,
931
0
                                   (SRE_CODE) *ptr)))
932
0
                    continue;
933
42
                state->ptr = ptr;
934
42
                DO_JUMP(JUMP_BRANCH, jump_branch, pattern+1);
935
42
                if (ret) {
936
13
                    if (state->save_marks)
937
0
                        MARK_POP_DISCARD(ctx->lastmark);
938
13
                    RETURN_ON_ERROR(ret);
939
13
                    RETURN_SUCCESS;
940
13
                }
941
29
                if (state->save_marks)
942
0
                    MARK_POP_KEEP(ctx->lastmark);
943
29
                LASTMARK_RESTORE();
944
29
            }
945
15
            if (state->save_marks)
946
0
                MARK_POP_DISCARD(ctx->lastmark);
947
15
            RETURN_FAILURE;
948
949
1.24M
        TARGET(SRE_OP_REPEAT_ONE):
950
            /* match repeated sequence (maximizing regexp) */
951
952
            /* this operator only works if the repeated item is
953
               exactly one character wide, and we're not already
954
               collecting backtracking points.  for other cases,
955
               use the MAX_REPEAT operator */
956
957
            /* <REPEAT_ONE> <skip> <1=min> <2=max> item <SUCCESS> tail */
958
959
1.24M
            TRACE(("|%p|%p|REPEAT_ONE %d %d\n", pattern, ptr,
960
1.24M
                   pattern[1], pattern[2]));
961
962
1.24M
            if ((Py_ssize_t) pattern[1] > end - ptr)
963
538
                RETURN_FAILURE; /* cannot match */
964
965
1.24M
            state->ptr = ptr;
966
967
1.24M
            ret = SRE(count)(state, pattern+3, pattern[2]);
968
1.24M
            RETURN_ON_ERROR(ret);
969
1.24M
            DATA_LOOKUP_AT(SRE(match_context), ctx, ctx_pos);
970
1.24M
            ctx->count = ret;
971
1.24M
            ptr += ctx->count;
972
973
            /* when we arrive here, count contains the number of
974
               matches, and ptr points to the tail of the target
975
               string.  check if the rest of the pattern matches,
976
               and backtrack if not. */
977
978
1.24M
            if (ctx->count < (Py_ssize_t) pattern[1])
979
1.23M
                RETURN_FAILURE;
980
981
10.7k
            if (pattern[pattern[0]] == SRE_OP_SUCCESS &&
982
9.72k
                ptr == state->end &&
983
1.27k
                !(ctx->toplevel && state->must_advance && ptr == state->start))
984
1.27k
            {
985
                /* tail is empty.  we're finished */
986
1.27k
                state->ptr = ptr;
987
1.27k
                RETURN_SUCCESS;
988
1.27k
            }
989
990
9.45k
            LASTMARK_SAVE();
991
9.45k
            if (state->save_marks)
992
48
                MARK_PUSH(ctx->lastmark);
993
994
9.45k
            if (pattern[pattern[0]] == SRE_OP_LITERAL) {
995
                /* tail starts with a literal. skip positions where
996
                   the rest of the pattern cannot possibly match */
997
38
                ctx->u.chr = pattern[pattern[0]+1];
998
38
                for (;;) {
999
252k
                    while (ctx->count >= (Py_ssize_t) pattern[1] &&
1000
252k
                           (ptr >= end || *ptr != ctx->u.chr)) {
1001
252k
                        ptr--;
1002
252k
                        ctx->count--;
1003
252k
                    }
1004
38
                    if (ctx->count < (Py_ssize_t) pattern[1])
1005
37
                        break;
1006
1
                    state->ptr = ptr;
1007
1
                    DO_JUMP(JUMP_REPEAT_ONE_1, jump_repeat_one_1,
1008
1
                            pattern+pattern[0]);
1009
1
                    if (ret) {
1010
1
                        if (state->save_marks)
1011
0
                            MARK_POP_DISCARD(ctx->lastmark);
1012
1
                        RETURN_ON_ERROR(ret);
1013
1
                        RETURN_SUCCESS;
1014
1
                    }
1015
0
                    if (state->save_marks)
1016
0
                        MARK_POP_KEEP(ctx->lastmark);
1017
0
                    LASTMARK_RESTORE();
1018
1019
0
                    ptr--;
1020
0
                    ctx->count--;
1021
0
                }
1022
37
                if (state->save_marks)
1023
0
                    MARK_POP_DISCARD(ctx->lastmark);
1024
9.41k
            } else {
1025
                /* general case */
1026
94.9k
                while (ctx->count >= (Py_ssize_t) pattern[1]) {
1027
94.1k
                    state->ptr = ptr;
1028
94.1k
                    DO_JUMP(JUMP_REPEAT_ONE_2, jump_repeat_one_2,
1029
94.1k
                            pattern+pattern[0]);
1030
94.1k
                    if (ret) {
1031
8.67k
                        if (state->save_marks)
1032
48
                            MARK_POP_DISCARD(ctx->lastmark);
1033
8.67k
                        RETURN_ON_ERROR(ret);
1034
8.67k
                        RETURN_SUCCESS;
1035
8.67k
                    }
1036
85.5k
                    if (state->save_marks)
1037
0
                        MARK_POP_KEEP(ctx->lastmark);
1038
85.5k
                    LASTMARK_RESTORE();
1039
1040
85.5k
                    ptr--;
1041
85.5k
                    ctx->count--;
1042
85.5k
                }
1043
746
                if (state->save_marks)
1044
0
                    MARK_POP_DISCARD(ctx->lastmark);
1045
746
            }
1046
783
            RETURN_FAILURE;
1047
1048
32
        TARGET(SRE_OP_MIN_REPEAT_ONE):
1049
            /* match repeated sequence (minimizing regexp) */
1050
1051
            /* this operator only works if the repeated item is
1052
               exactly one character wide, and we're not already
1053
               collecting backtracking points.  for other cases,
1054
               use the MIN_REPEAT operator */
1055
1056
            /* <MIN_REPEAT_ONE> <skip> <1=min> <2=max> item <SUCCESS> tail */
1057
1058
32
            TRACE(("|%p|%p|MIN_REPEAT_ONE %d %d\n", pattern, ptr,
1059
32
                   pattern[1], pattern[2]));
1060
1061
32
            if ((Py_ssize_t) pattern[1] > end - ptr)
1062
0
                RETURN_FAILURE; /* cannot match */
1063
1064
32
            state->ptr = ptr;
1065
1066
32
            if (pattern[1] == 0)
1067
11
                ctx->count = 0;
1068
21
            else {
1069
                /* count using pattern min as the maximum */
1070
21
                ret = SRE(count)(state, pattern+3, pattern[1]);
1071
21
                RETURN_ON_ERROR(ret);
1072
21
                DATA_LOOKUP_AT(SRE(match_context), ctx, ctx_pos);
1073
21
                if (ret < (Py_ssize_t) pattern[1])
1074
                    /* didn't match minimum number of times */
1075
20
                    RETURN_FAILURE;
1076
                /* advance past minimum matches of repeat */
1077
1
                ctx->count = ret;
1078
1
                ptr += ctx->count;
1079
1
            }
1080
1081
12
            if (pattern[pattern[0]] == SRE_OP_SUCCESS &&
1082
12
                !(ctx->toplevel &&
1083
12
                  ((state->match_all && ptr != state->end) ||
1084
12
                   (state->must_advance && ptr == state->start))))
1085
12
            {
1086
                /* tail is empty.  we're finished */
1087
12
                state->ptr = ptr;
1088
12
                RETURN_SUCCESS;
1089
1090
12
            } else {
1091
                /* general case */
1092
0
                LASTMARK_SAVE();
1093
0
                if (state->save_marks)
1094
0
                    MARK_PUSH(ctx->lastmark);
1095
1096
0
                while ((Py_ssize_t)pattern[2] == SRE_MAXREPEAT
1097
0
                       || ctx->count <= (Py_ssize_t)pattern[2]) {
1098
0
                    state->ptr = ptr;
1099
0
                    DO_JUMP(JUMP_MIN_REPEAT_ONE,jump_min_repeat_one,
1100
0
                            pattern+pattern[0]);
1101
0
                    if (ret) {
1102
0
                        if (state->save_marks)
1103
0
                            MARK_POP_DISCARD(ctx->lastmark);
1104
0
                        RETURN_ON_ERROR(ret);
1105
0
                        RETURN_SUCCESS;
1106
0
                    }
1107
0
                    if (state->save_marks)
1108
0
                        MARK_POP_KEEP(ctx->lastmark);
1109
0
                    LASTMARK_RESTORE();
1110
1111
0
                    state->ptr = ptr;
1112
0
                    ret = SRE(count)(state, pattern+3, 1);
1113
0
                    RETURN_ON_ERROR(ret);
1114
0
                    DATA_LOOKUP_AT(SRE(match_context), ctx, ctx_pos);
1115
0
                    if (ret == 0)
1116
0
                        break;
1117
0
                    assert(ret == 1);
1118
0
                    ptr++;
1119
0
                    ctx->count++;
1120
0
                }
1121
0
                if (state->save_marks)
1122
0
                    MARK_POP_DISCARD(ctx->lastmark);
1123
0
            }
1124
0
            RETURN_FAILURE;
1125
1126
0
        TARGET(SRE_OP_POSSESSIVE_REPEAT_ONE):
1127
            /* match repeated sequence (maximizing regexp) without
1128
               backtracking */
1129
1130
            /* this operator only works if the repeated item is
1131
               exactly one character wide, and we're not already
1132
               collecting backtracking points.  for other cases,
1133
               use the MAX_REPEAT operator */
1134
1135
            /* <POSSESSIVE_REPEAT_ONE> <skip> <1=min> <2=max> item <SUCCESS>
1136
               tail */
1137
1138
0
            TRACE(("|%p|%p|POSSESSIVE_REPEAT_ONE %d %d\n", pattern,
1139
0
                   ptr, pattern[1], pattern[2]));
1140
1141
0
            if (ptr + pattern[1] > end) {
1142
0
                RETURN_FAILURE; /* cannot match */
1143
0
            }
1144
1145
0
            state->ptr = ptr;
1146
1147
0
            ret = SRE(count)(state, pattern + 3, pattern[2]);
1148
0
            RETURN_ON_ERROR(ret);
1149
0
            DATA_LOOKUP_AT(SRE(match_context), ctx, ctx_pos);
1150
0
            ctx->count = ret;
1151
0
            ptr += ctx->count;
1152
1153
            /* when we arrive here, count contains the number of
1154
               matches, and ptr points to the tail of the target
1155
               string.  check if the rest of the pattern matches,
1156
               and fail if not. */
1157
1158
            /* Test for not enough repetitions in match */
1159
0
            if (ctx->count < (Py_ssize_t) pattern[1]) {
1160
0
                RETURN_FAILURE;
1161
0
            }
1162
1163
            /* Update the pattern to point to the next op code */
1164
0
            pattern += pattern[0];
1165
1166
            /* Let the tail be evaluated separately and consider this
1167
               match successful. */
1168
0
            if (*pattern == SRE_OP_SUCCESS &&
1169
0
                ptr == state->end &&
1170
0
                !(ctx->toplevel && state->must_advance && ptr == state->start))
1171
0
            {
1172
                /* tail is empty.  we're finished */
1173
0
                state->ptr = ptr;
1174
0
                RETURN_SUCCESS;
1175
0
            }
1176
1177
            /* Attempt to match the rest of the string */
1178
0
            DISPATCH;
1179
1180
83.4k
        TARGET(SRE_OP_REPEAT):
1181
            /* create repeat context.  all the hard work is done
1182
               by the UNTIL operator (MAX_UNTIL, MIN_UNTIL) */
1183
            /* <REPEAT> <skip> <1=min> <2=max>
1184
               <3=repeat_index> item <UNTIL> tail */
1185
83.4k
            TRACE(("|%p|%p|REPEAT %d %d\n", pattern, ptr,
1186
83.4k
                   pattern[1], pattern[2]));
1187
1188
            /* install new repeat context */
1189
83.4k
            ctx->u.rep = repeat_pool_malloc(state);
1190
83.4k
            if (!ctx->u.rep) {
1191
0
                RETURN_ERROR(SRE_ERROR_MEMORY);
1192
0
            }
1193
83.4k
            ctx->u.rep->count = -1;
1194
83.4k
            ctx->u.rep->pattern = pattern;
1195
83.4k
            ctx->u.rep->prev = state->repeat;
1196
83.4k
            ctx->u.rep->last_ptr = NULL;
1197
83.4k
            state->repeat = ctx->u.rep;
1198
83.4k
            state->save_marks++;
1199
1200
83.4k
            state->ptr = ptr;
1201
83.4k
            DO_JUMP(JUMP_REPEAT, jump_repeat, pattern+pattern[0]);
1202
83.4k
            state->repeat = ctx->u.rep->prev;
1203
83.4k
            state->save_marks--;
1204
83.4k
            repeat_pool_free(state, ctx->u.rep);
1205
1206
83.4k
            if (ret) {
1207
119
                RETURN_ON_ERROR(ret);
1208
119
                RETURN_SUCCESS;
1209
119
            }
1210
83.3k
            RETURN_FAILURE;
1211
1212
1.34M
        TARGET(SRE_OP_MAX_UNTIL):
1213
            /* maximizing repeat */
1214
            /* <REPEAT> <skip> <1=min> <2=max> item <MAX_UNTIL> tail */
1215
1216
            /* FIXME: we probably need to deal with zero-width
1217
               matches in here... */
1218
1219
1.34M
            ctx->u.rep = state->repeat;
1220
1.34M
            if (!ctx->u.rep)
1221
0
                RETURN_ERROR(SRE_ERROR_STATE);
1222
1223
1.34M
            state->ptr = ptr;
1224
1225
1.34M
            ctx->count = ctx->u.rep->count+1;
1226
1227
1.34M
            TRACE(("|%p|%p|MAX_UNTIL %zd\n", pattern,
1228
1.34M
                   ptr, ctx->count));
1229
1230
1.34M
            if (ctx->count < (Py_ssize_t) ctx->u.rep->pattern[1]) {
1231
                /* not enough matches */
1232
0
                ctx->u.rep->count = ctx->count;
1233
0
                DO_JUMP(JUMP_MAX_UNTIL_1, jump_max_until_1,
1234
0
                        ctx->u.rep->pattern+3);
1235
0
                if (ret) {
1236
0
                    RETURN_ON_ERROR(ret);
1237
0
                    RETURN_SUCCESS;
1238
0
                }
1239
0
                ctx->u.rep->count = ctx->count-1;
1240
0
                state->ptr = ptr;
1241
0
                RETURN_FAILURE;
1242
0
            }
1243
1244
1.34M
            if ((ctx->count < (Py_ssize_t) ctx->u.rep->pattern[2] ||
1245
4
                ctx->u.rep->pattern[2] == SRE_MAXREPEAT) &&
1246
1.34M
                state->ptr != ctx->u.rep->last_ptr) {
1247
                /* we may have enough matches, but if we can
1248
                   match another item, do so */
1249
1.34M
                ctx->u.rep->count = ctx->count;
1250
1.34M
                LASTMARK_SAVE();
1251
1.34M
                MARK_PUSH(ctx->lastmark);
1252
                /* zero-width match protection */
1253
1.34M
                LAST_PTR_PUSH();
1254
1.34M
                ctx->u.rep->last_ptr = state->ptr;
1255
1.34M
                DO_JUMP(JUMP_MAX_UNTIL_2, jump_max_until_2,
1256
1.34M
                        ctx->u.rep->pattern+3);
1257
1.34M
                LAST_PTR_POP();
1258
1.34M
                if (ret) {
1259
114k
                    MARK_POP_DISCARD(ctx->lastmark);
1260
114k
                    RETURN_ON_ERROR(ret);
1261
114k
                    RETURN_SUCCESS;
1262
114k
                }
1263
1.23M
                MARK_POP(ctx->lastmark);
1264
1.23M
                LASTMARK_RESTORE();
1265
1.23M
                ctx->u.rep->count = ctx->count-1;
1266
1.23M
                state->ptr = ptr;
1267
1.23M
            }
1268
1269
            /* cannot match more repeated items here.  make sure the
1270
               tail matches */
1271
1.23M
            state->repeat = ctx->u.rep->prev;
1272
1.23M
            state->save_marks--;
1273
1.23M
            DO_JUMP(JUMP_MAX_UNTIL_3, jump_max_until_3, pattern);
1274
1.23M
            state->repeat = ctx->u.rep; // restore repeat before return
1275
1.23M
            state->save_marks++;
1276
1277
1.23M
            RETURN_ON_SUCCESS(ret);
1278
1.23M
            state->ptr = ptr;
1279
1.23M
            RETURN_FAILURE;
1280
1281
0
        TARGET(SRE_OP_MIN_UNTIL):
1282
            /* minimizing repeat */
1283
            /* <REPEAT> <skip> <1=min> <2=max> item <MIN_UNTIL> tail */
1284
1285
0
            ctx->u.rep = state->repeat;
1286
0
            if (!ctx->u.rep)
1287
0
                RETURN_ERROR(SRE_ERROR_STATE);
1288
1289
0
            state->ptr = ptr;
1290
1291
0
            ctx->count = ctx->u.rep->count+1;
1292
1293
0
            TRACE(("|%p|%p|MIN_UNTIL %zd %p\n", pattern,
1294
0
                   ptr, ctx->count, ctx->u.rep->pattern));
1295
1296
0
            if (ctx->count < (Py_ssize_t) ctx->u.rep->pattern[1]) {
1297
                /* not enough matches */
1298
0
                ctx->u.rep->count = ctx->count;
1299
0
                DO_JUMP(JUMP_MIN_UNTIL_1, jump_min_until_1,
1300
0
                        ctx->u.rep->pattern+3);
1301
0
                if (ret) {
1302
0
                    RETURN_ON_ERROR(ret);
1303
0
                    RETURN_SUCCESS;
1304
0
                }
1305
0
                ctx->u.rep->count = ctx->count-1;
1306
0
                state->ptr = ptr;
1307
0
                RETURN_FAILURE;
1308
0
            }
1309
1310
            /* see if the tail matches */
1311
0
            state->repeat = ctx->u.rep->prev;
1312
0
            state->save_marks--;
1313
1314
0
            LASTMARK_SAVE();
1315
0
            if (state->save_marks)
1316
0
                MARK_PUSH(ctx->lastmark);
1317
1318
0
            DO_JUMP(JUMP_MIN_UNTIL_2, jump_min_until_2, pattern);
1319
            /* save_marks is balanced across the jump, so this equals the
1320
               value tested for MARK_PUSH above */
1321
0
            int pushed = state->save_marks != 0;
1322
0
            state->repeat = ctx->u.rep; // restore repeat before return
1323
0
            state->save_marks++;
1324
1325
0
            if (ret) {
1326
0
                if (pushed)
1327
0
                    MARK_POP_DISCARD(ctx->lastmark);
1328
0
                RETURN_ON_ERROR(ret);
1329
0
                RETURN_SUCCESS;
1330
0
            }
1331
0
            if (pushed)
1332
0
                MARK_POP(ctx->lastmark);
1333
0
            LASTMARK_RESTORE();
1334
1335
0
            state->ptr = ptr;
1336
1337
0
            if ((ctx->count >= (Py_ssize_t) ctx->u.rep->pattern[2]
1338
0
                && ctx->u.rep->pattern[2] != SRE_MAXREPEAT) ||
1339
0
                state->ptr == ctx->u.rep->last_ptr)
1340
0
                RETURN_FAILURE;
1341
1342
0
            ctx->u.rep->count = ctx->count;
1343
            /* zero-width match protection */
1344
0
            LAST_PTR_PUSH();
1345
0
            ctx->u.rep->last_ptr = state->ptr;
1346
0
            DO_JUMP(JUMP_MIN_UNTIL_3,jump_min_until_3,
1347
0
                    ctx->u.rep->pattern+3);
1348
0
            LAST_PTR_POP();
1349
0
            if (ret) {
1350
0
                RETURN_ON_ERROR(ret);
1351
0
                RETURN_SUCCESS;
1352
0
            }
1353
0
            ctx->u.rep->count = ctx->count-1;
1354
0
            state->ptr = ptr;
1355
0
            RETURN_FAILURE;
1356
1357
0
        TARGET(SRE_OP_POSSESSIVE_REPEAT):
1358
            /* create possessive repeat contexts. */
1359
            /* <POSSESSIVE_REPEAT> <skip> <1=min> <2=max> pattern
1360
               <SUCCESS> tail */
1361
0
            TRACE(("|%p|%p|POSSESSIVE_REPEAT %d %d\n", pattern,
1362
0
                   ptr, pattern[1], pattern[2]));
1363
1364
            /* Set the global Input pointer to this context's Input
1365
               pointer */
1366
0
            state->ptr = ptr;
1367
1368
            /* Capture groups in the body can be revisited on backtracking
1369
               between iterations, so their marks must be saved and restored,
1370
               as is done inside a repeat. */
1371
0
            state->save_marks++;
1372
1373
            /* Initialize Count to 0 */
1374
0
            ctx->count = 0;
1375
1376
            /* Check for minimum required matches. */
1377
0
            while (ctx->count < (Py_ssize_t)pattern[1]) {
1378
                /* not enough matches */
1379
0
                DO_JUMP0(JUMP_POSS_REPEAT_1, jump_poss_repeat_1,
1380
0
                         &pattern[3]);
1381
0
                if (ret) {
1382
0
                    RETURN_ON_ERROR(ret);
1383
0
                    ctx->count++;
1384
0
                }
1385
0
                else {
1386
0
                    state->ptr = ptr;
1387
0
                    state->save_marks--;
1388
0
                    RETURN_FAILURE;
1389
0
                }
1390
0
            }
1391
1392
            /* Clear the context's Input stream pointer so that it
1393
               doesn't match the global state so that the while loop can
1394
               be entered. */
1395
0
            ptr = NULL;
1396
1397
            /* Keep trying to parse the <pattern> sub-pattern until the
1398
               end is reached, creating a new context each time. */
1399
0
            while ((ctx->count < (Py_ssize_t)pattern[2] ||
1400
0
                    (Py_ssize_t)pattern[2] == SRE_MAXREPEAT) &&
1401
0
                   state->ptr != ptr) {
1402
                /* Save the Capture Group Marker state into the current
1403
                   Context and back up the current highest number
1404
                   Capture Group marker. */
1405
0
                LASTMARK_SAVE();
1406
0
                MARK_PUSH(ctx->lastmark);
1407
1408
                /* zero-width match protection */
1409
                /* Set the context's Input Stream pointer to be the
1410
                   current Input Stream pointer from the global
1411
                   state.  When the loop reaches the next iteration,
1412
                   the context will then store the last known good
1413
                   position with the global state holding the Input
1414
                   Input Stream position that has been updated with
1415
                   the most recent match.  Thus, if state's Input
1416
                   stream remains the same as the one stored in the
1417
                   current Context, we know we have successfully
1418
                   matched an empty string and that all subsequent
1419
                   matches will also be the empty string until the
1420
                   maximum number of matches are counted, and because
1421
                   of this, we could immediately stop at that point and
1422
                   consider this match successful. */
1423
0
                ptr = state->ptr;
1424
1425
                /* We have not reached the maximin matches, so try to
1426
                   match once more. */
1427
0
                DO_JUMP0(JUMP_POSS_REPEAT_2, jump_poss_repeat_2,
1428
0
                         &pattern[3]);
1429
1430
                /* Check to see if the last attempted match
1431
                   succeeded. */
1432
0
                if (ret) {
1433
                    /* Drop the saved highest number Capture Group
1434
                       marker saved above and use the newly updated
1435
                       value. */
1436
0
                    MARK_POP_DISCARD(ctx->lastmark);
1437
0
                    RETURN_ON_ERROR(ret);
1438
1439
                    /* Success, increment the count. */
1440
0
                    ctx->count++;
1441
0
                }
1442
                /* Last attempted match failed. */
1443
0
                else {
1444
                    /* Restore the previously saved highest number
1445
                       Capture Group marker since the last iteration
1446
                       did not match, then restore that to the global
1447
                       state. */
1448
0
                    MARK_POP(ctx->lastmark);
1449
0
                    LASTMARK_RESTORE();
1450
1451
                    /* Restore the global Input Stream pointer
1452
                       since it can change after jumps. */
1453
0
                    state->ptr = ptr;
1454
1455
                    /* We have sufficient matches, so exit loop. */
1456
0
                    break;
1457
0
                }
1458
0
            }
1459
1460
0
            state->save_marks--;
1461
1462
            /* Evaluate Tail */
1463
            /* Jump to end of pattern indicated by skip, and then skip
1464
               the SUCCESS op code that follows it. */
1465
0
            pattern += pattern[0] + 1;
1466
0
            ptr = state->ptr;
1467
0
            DISPATCH;
1468
1469
0
        TARGET(SRE_OP_ATOMIC_GROUP):
1470
            /* Atomic Group Sub Pattern */
1471
            /* <ATOMIC_GROUP> <skip> pattern <SUCCESS> tail */
1472
0
            TRACE(("|%p|%p|ATOMIC_GROUP\n", pattern, ptr));
1473
1474
            /* Set the global Input pointer to this context's Input
1475
               pointer */
1476
0
            state->ptr = ptr;
1477
1478
            /* Evaluate the Atomic Group in a new context, terminating
1479
               when the end of the group, represented by a SUCCESS op
1480
               code, is reached. */
1481
            /* Group Pattern begins at an offset of 1 code. */
1482
0
            DO_JUMP0(JUMP_ATOMIC_GROUP, jump_atomic_group,
1483
0
                     &pattern[1]);
1484
1485
            /* Test Exit Condition */
1486
0
            RETURN_ON_ERROR(ret);
1487
1488
0
            if (ret == 0) {
1489
                /* Atomic Group failed to Match. */
1490
0
                state->ptr = ptr;
1491
0
                RETURN_FAILURE;
1492
0
            }
1493
1494
            /* Evaluate Tail */
1495
            /* Jump to end of pattern indicated by skip, and then skip
1496
               the SUCCESS op code that follows it. */
1497
0
            pattern += pattern[0];
1498
0
            ptr = state->ptr;
1499
0
            DISPATCH;
1500
1501
0
        TARGET(SRE_OP_GROUPREF):
1502
            /* match backreference */
1503
0
            TRACE(("|%p|%p|GROUPREF %d\n", pattern,
1504
0
                   ptr, pattern[0]));
1505
0
            {
1506
0
                int groupref = pattern[0] * 2;
1507
0
                if (groupref >= state->lastmark) {
1508
0
                    RETURN_FAILURE;
1509
0
                } else {
1510
0
                    SRE_CHAR* p = (SRE_CHAR*) state->mark[groupref];
1511
0
                    SRE_CHAR* e = (SRE_CHAR*) state->mark[groupref+1];
1512
0
                    if (!p || !e || e < p)
1513
0
                        RETURN_FAILURE;
1514
0
                    while (p < e) {
1515
0
                        if (ptr >= end || *ptr != *p)
1516
0
                            RETURN_FAILURE;
1517
0
                        p++;
1518
0
                        ptr++;
1519
0
                    }
1520
0
                }
1521
0
            }
1522
0
            pattern++;
1523
0
            DISPATCH;
1524
1525
0
        TARGET(SRE_OP_GROUPREF_IGNORE):
1526
            /* match backreference */
1527
0
            TRACE(("|%p|%p|GROUPREF_IGNORE %d\n", pattern,
1528
0
                   ptr, pattern[0]));
1529
0
            {
1530
0
                int groupref = pattern[0] * 2;
1531
0
                if (groupref >= state->lastmark) {
1532
0
                    RETURN_FAILURE;
1533
0
                } else {
1534
0
                    SRE_CHAR* p = (SRE_CHAR*) state->mark[groupref];
1535
0
                    SRE_CHAR* e = (SRE_CHAR*) state->mark[groupref+1];
1536
0
                    if (!p || !e || e < p)
1537
0
                        RETURN_FAILURE;
1538
0
                    while (p < e) {
1539
0
                        if (ptr >= end ||
1540
0
                            sre_lower_ascii(*ptr) != sre_lower_ascii(*p))
1541
0
                            RETURN_FAILURE;
1542
0
                        p++;
1543
0
                        ptr++;
1544
0
                    }
1545
0
                }
1546
0
            }
1547
0
            pattern++;
1548
0
            DISPATCH;
1549
1550
0
        TARGET(SRE_OP_GROUPREF_UNI_IGNORE):
1551
            /* match backreference */
1552
0
            TRACE(("|%p|%p|GROUPREF_UNI_IGNORE %d\n", pattern,
1553
0
                   ptr, pattern[0]));
1554
0
            {
1555
0
                int groupref = pattern[0] * 2;
1556
0
                if (groupref >= state->lastmark) {
1557
0
                    RETURN_FAILURE;
1558
0
                } else {
1559
0
                    SRE_CHAR* p = (SRE_CHAR*) state->mark[groupref];
1560
0
                    SRE_CHAR* e = (SRE_CHAR*) state->mark[groupref+1];
1561
0
                    if (!p || !e || e < p)
1562
0
                        RETURN_FAILURE;
1563
0
                    while (p < e) {
1564
0
                        if (ptr >= end ||
1565
0
                            sre_lower_unicode(*ptr) != sre_lower_unicode(*p))
1566
0
                            RETURN_FAILURE;
1567
0
                        p++;
1568
0
                        ptr++;
1569
0
                    }
1570
0
                }
1571
0
            }
1572
0
            pattern++;
1573
0
            DISPATCH;
1574
1575
0
        TARGET(SRE_OP_GROUPREF_LOC_IGNORE):
1576
            /* match backreference */
1577
0
            TRACE(("|%p|%p|GROUPREF_LOC_IGNORE %d\n", pattern,
1578
0
                   ptr, pattern[0]));
1579
0
            {
1580
0
                int groupref = pattern[0] * 2;
1581
0
                if (groupref >= state->lastmark) {
1582
0
                    RETURN_FAILURE;
1583
0
                } else {
1584
0
                    SRE_CHAR* p = (SRE_CHAR*) state->mark[groupref];
1585
0
                    SRE_CHAR* e = (SRE_CHAR*) state->mark[groupref+1];
1586
0
                    if (!p || !e || e < p)
1587
0
                        RETURN_FAILURE;
1588
0
                    while (p < e) {
1589
0
                        if (ptr >= end ||
1590
0
                            sre_lower_locale(*ptr) != sre_lower_locale(*p))
1591
0
                            RETURN_FAILURE;
1592
0
                        p++;
1593
0
                        ptr++;
1594
0
                    }
1595
0
                }
1596
0
            }
1597
0
            pattern++;
1598
0
            DISPATCH;
1599
1600
0
        TARGET(SRE_OP_GROUPREF_EXISTS):
1601
0
            TRACE(("|%p|%p|GROUPREF_EXISTS %d\n", pattern,
1602
0
                   ptr, pattern[0]));
1603
            /* <GROUPREF_EXISTS> <group> <skip> codeyes <JUMP> codeno ... */
1604
0
            {
1605
0
                int groupref = pattern[0] * 2;
1606
0
                if (groupref >= state->lastmark) {
1607
0
                    pattern += pattern[1];
1608
0
                    DISPATCH;
1609
0
                } else {
1610
0
                    SRE_CHAR* p = (SRE_CHAR*) state->mark[groupref];
1611
0
                    SRE_CHAR* e = (SRE_CHAR*) state->mark[groupref+1];
1612
0
                    if (!p || !e || e < p) {
1613
0
                        pattern += pattern[1];
1614
0
                        DISPATCH;
1615
0
                    }
1616
0
                }
1617
0
            }
1618
0
            pattern += 2;
1619
0
            DISPATCH;
1620
1621
14
        TARGET(SRE_OP_ASSERT):
1622
            /* assert subpattern */
1623
            /* <ASSERT> <skip> <back> <pattern> */
1624
14
            TRACE(("|%p|%p|ASSERT %d\n", pattern,
1625
14
                   ptr, pattern[1]));
1626
14
            if ((uintptr_t)(ptr - (SRE_CHAR *)state->beginning) < pattern[1])
1627
0
                RETURN_FAILURE;
1628
14
            state->ptr = ptr - pattern[1];
1629
14
            DO_JUMP0(JUMP_ASSERT, jump_assert, pattern+2);
1630
14
            RETURN_ON_FAILURE(ret);
1631
2
            pattern += pattern[0];
1632
2
            DISPATCH;
1633
1634
2
        TARGET(SRE_OP_ASSERT_NOT):
1635
            /* assert not subpattern */
1636
            /* <ASSERT_NOT> <skip> <back> <pattern> */
1637
0
            TRACE(("|%p|%p|ASSERT_NOT %d\n", pattern,
1638
0
                   ptr, pattern[1]));
1639
0
            if ((uintptr_t)(ptr - (SRE_CHAR *)state->beginning) >= pattern[1]) {
1640
0
                state->ptr = ptr - pattern[1];
1641
0
                LASTMARK_SAVE();
1642
0
                if (state->save_marks)
1643
0
                    MARK_PUSH(ctx->lastmark);
1644
1645
0
                DO_JUMP0(JUMP_ASSERT_NOT, jump_assert_not, pattern+2);
1646
0
                if (ret) {
1647
0
                    if (state->save_marks)
1648
0
                        MARK_POP_DISCARD(ctx->lastmark);
1649
0
                    RETURN_ON_ERROR(ret);
1650
0
                    RETURN_FAILURE;
1651
0
                }
1652
0
                if (state->save_marks)
1653
0
                    MARK_POP(ctx->lastmark);
1654
0
                LASTMARK_RESTORE();
1655
0
            }
1656
0
            pattern += pattern[0];
1657
0
            DISPATCH;
1658
1659
0
        TARGET(SRE_OP_FAILURE):
1660
            /* immediate failure */
1661
0
            TRACE(("|%p|%p|FAILURE\n", pattern, ptr));
1662
0
            RETURN_FAILURE;
1663
1664
#if !USE_COMPUTED_GOTOS
1665
        default:
1666
#endif
1667
        // Also any unused opcodes:
1668
0
        TARGET(SRE_OP_RANGE_UNI_IGNORE):
1669
0
        TARGET(SRE_OP_SUBPATTERN):
1670
0
        TARGET(SRE_OP_RANGE):
1671
0
        TARGET(SRE_OP_NEGATE):
1672
0
        TARGET(SRE_OP_BIGCHARSET):
1673
0
        TARGET(SRE_OP_CHARSET):
1674
0
            TRACE(("|%p|%p|UNKNOWN %d\n", pattern, ptr,
1675
0
                   pattern[-1]));
1676
0
            RETURN_ERROR(SRE_ERROR_ILLEGAL);
1677
1678
0
    }
1679
1680
2.76M
exit:
1681
2.76M
    ctx_pos = ctx->last_ctx_pos;
1682
2.76M
    jump = ctx->jump;
1683
2.76M
    DATA_POP_DISCARD(ctx);
1684
2.76M
    if (ctx_pos == -1) {
1685
10.1k
        state->sigcount = sigcount;
1686
10.1k
        return ret;
1687
10.1k
    }
1688
2.75M
    DATA_LOOKUP_AT(SRE(match_context), ctx, ctx_pos);
1689
1690
2.75M
    switch (jump) {
1691
1.34M
        case JUMP_MAX_UNTIL_2:
1692
1.34M
            TRACE(("|%p|%p|JUMP_MAX_UNTIL_2\n", pattern, ptr));
1693
1.34M
            goto jump_max_until_2;
1694
1.23M
        case JUMP_MAX_UNTIL_3:
1695
1.23M
            TRACE(("|%p|%p|JUMP_MAX_UNTIL_3\n", pattern, ptr));
1696
1.23M
            goto jump_max_until_3;
1697
0
        case JUMP_MIN_UNTIL_2:
1698
0
            TRACE(("|%p|%p|JUMP_MIN_UNTIL_2\n", pattern, ptr));
1699
0
            goto jump_min_until_2;
1700
0
        case JUMP_MIN_UNTIL_3:
1701
0
            TRACE(("|%p|%p|JUMP_MIN_UNTIL_3\n", pattern, ptr));
1702
0
            goto jump_min_until_3;
1703
42
        case JUMP_BRANCH:
1704
42
            TRACE(("|%p|%p|JUMP_BRANCH\n", pattern, ptr));
1705
42
            goto jump_branch;
1706
0
        case JUMP_MAX_UNTIL_1:
1707
0
            TRACE(("|%p|%p|JUMP_MAX_UNTIL_1\n", pattern, ptr));
1708
0
            goto jump_max_until_1;
1709
0
        case JUMP_MIN_UNTIL_1:
1710
0
            TRACE(("|%p|%p|JUMP_MIN_UNTIL_1\n", pattern, ptr));
1711
0
            goto jump_min_until_1;
1712
0
        case JUMP_POSS_REPEAT_1:
1713
0
            TRACE(("|%p|%p|JUMP_POSS_REPEAT_1\n", pattern, ptr));
1714
0
            goto jump_poss_repeat_1;
1715
0
        case JUMP_POSS_REPEAT_2:
1716
0
            TRACE(("|%p|%p|JUMP_POSS_REPEAT_2\n", pattern, ptr));
1717
0
            goto jump_poss_repeat_2;
1718
83.4k
        case JUMP_REPEAT:
1719
83.4k
            TRACE(("|%p|%p|JUMP_REPEAT\n", pattern, ptr));
1720
83.4k
            goto jump_repeat;
1721
1
        case JUMP_REPEAT_ONE_1:
1722
1
            TRACE(("|%p|%p|JUMP_REPEAT_ONE_1\n", pattern, ptr));
1723
1
            goto jump_repeat_one_1;
1724
94.1k
        case JUMP_REPEAT_ONE_2:
1725
94.1k
            TRACE(("|%p|%p|JUMP_REPEAT_ONE_2\n", pattern, ptr));
1726
94.1k
            goto jump_repeat_one_2;
1727
0
        case JUMP_MIN_REPEAT_ONE:
1728
0
            TRACE(("|%p|%p|JUMP_MIN_REPEAT_ONE\n", pattern, ptr));
1729
0
            goto jump_min_repeat_one;
1730
0
        case JUMP_ATOMIC_GROUP:
1731
0
            TRACE(("|%p|%p|JUMP_ATOMIC_GROUP\n", pattern, ptr));
1732
0
            goto jump_atomic_group;
1733
14
        case JUMP_ASSERT:
1734
14
            TRACE(("|%p|%p|JUMP_ASSERT\n", pattern, ptr));
1735
14
            goto jump_assert;
1736
0
        case JUMP_ASSERT_NOT:
1737
0
            TRACE(("|%p|%p|JUMP_ASSERT_NOT\n", pattern, ptr));
1738
0
            goto jump_assert_not;
1739
0
        case JUMP_NONE:
1740
0
            TRACE(("|%p|%p|RETURN %zd\n", pattern,
1741
0
                   ptr, ret));
1742
0
            break;
1743
2.75M
    }
1744
1745
0
    return ret; /* should never get here */
1746
2.75M
}
sre.c:sre_ucs1_match
Line
Count
Source
663
6.32k
{
664
6.32k
    const SRE_CHAR* end = (const SRE_CHAR *)state->end;
665
6.32k
    Py_ssize_t alloc_pos, ctx_pos = -1;
666
6.32k
    Py_ssize_t ret = 0;
667
6.32k
    int jump;
668
6.32k
    unsigned int sigcount = state->sigcount;
669
670
6.32k
    SRE(match_context)* ctx;
671
6.32k
    SRE(match_context)* nextctx;
672
6.32k
    INIT_TRACE(state);
673
674
6.32k
    TRACE(("|%p|%p|ENTER\n", pattern, state->ptr));
675
676
6.32k
    DATA_ALLOC(SRE(match_context), ctx);
677
6.32k
    ctx->last_ctx_pos = -1;
678
6.32k
    ctx->jump = JUMP_NONE;
679
6.32k
    ctx->toplevel = toplevel;
680
6.32k
    ctx_pos = alloc_pos;
681
682
6.32k
#if USE_COMPUTED_GOTOS
683
6.32k
#include "sre_targets.h"
684
6.32k
#endif
685
686
2.75M
entrance:
687
688
2.75M
    ;  // Fashion statement.
689
2.75M
    const SRE_CHAR *ptr = (SRE_CHAR *)state->ptr;
690
691
2.75M
    if (pattern[0] == SRE_OP_INFO) {
692
        /* optimization info block */
693
        /* <INFO> <1=skip> <2=flags> <3=min> ... */
694
6.32k
        if (pattern[3] && (uintptr_t)(end - ptr) < pattern[3]) {
695
2
            TRACE(("reject (got %tu chars, need %zu)\n",
696
2
                   end - ptr, (size_t) pattern[3]));
697
2
            RETURN_FAILURE;
698
2
        }
699
6.31k
        pattern += pattern[1] + 1;
700
6.31k
    }
701
702
2.75M
#if USE_COMPUTED_GOTOS
703
2.75M
    DISPATCH;
704
#else
705
dispatch:
706
    MAYBE_CHECK_SIGNALS;
707
    switch (*pattern++)
708
#endif
709
2.75M
    {
710
711
2.75M
        TARGET(SRE_OP_MARK):
712
            /* set mark */
713
            /* <MARK> <gid> */
714
2.60M
            TRACE(("|%p|%p|MARK %d\n", pattern,
715
2.60M
                   ptr, pattern[0]));
716
2.60M
            {
717
2.60M
                int i = pattern[0];
718
2.60M
                if (i & 1)
719
1.26M
                    state->lastindex = i/2 + 1;
720
2.60M
                if (i > state->lastmark) {
721
                    /* state->lastmark is the highest valid index in the
722
                       state->mark array.  If it is increased by more than 1,
723
                       the intervening marks must be set to NULL to signal
724
                       that these marks have not been encountered. */
725
83.7k
                    int j = state->lastmark + 1;
726
84.0k
                    while (j < i)
727
244
                        state->mark[j++] = NULL;
728
83.7k
                    state->lastmark = i;
729
83.7k
                }
730
2.60M
                state->mark[i] = ptr;
731
2.60M
            }
732
2.60M
            pattern++;
733
2.60M
            DISPATCH;
734
735
2.60M
        TARGET(SRE_OP_LITERAL):
736
            /* match literal string */
737
            /* <LITERAL> <code> */
738
40
            TRACE(("|%p|%p|LITERAL %d\n", pattern,
739
40
                   ptr, *pattern));
740
40
            if (ptr >= end || (SRE_CODE) ptr[0] != pattern[0])
741
7
                RETURN_FAILURE;
742
33
            pattern++;
743
33
            ptr++;
744
33
            DISPATCH;
745
746
33
        TARGET(SRE_OP_NOT_LITERAL):
747
            /* match anything that is not literal character */
748
            /* <NOT_LITERAL> <code> */
749
0
            TRACE(("|%p|%p|NOT_LITERAL %d\n", pattern,
750
0
                   ptr, *pattern));
751
0
            if (ptr >= end || (SRE_CODE) ptr[0] == pattern[0])
752
0
                RETURN_FAILURE;
753
0
            pattern++;
754
0
            ptr++;
755
0
            DISPATCH;
756
757
4.83k
        TARGET(SRE_OP_SUCCESS):
758
            /* end of pattern */
759
4.83k
            TRACE(("|%p|%p|SUCCESS\n", pattern, ptr));
760
4.83k
            if (ctx->toplevel &&
761
4.83k
                ((state->match_all && ptr != state->end) ||
762
4.83k
                 (state->must_advance && ptr == state->start)))
763
0
            {
764
0
                RETURN_FAILURE;
765
0
            }
766
4.83k
            state->ptr = ptr;
767
4.83k
            RETURN_SUCCESS;
768
769
329
        TARGET(SRE_OP_AT):
770
            /* match at given position */
771
            /* <AT> <code> */
772
329
            TRACE(("|%p|%p|AT %d\n", pattern, ptr, *pattern));
773
329
            if (!SRE(at)(state, ptr, *pattern))
774
24
                RETURN_FAILURE;
775
305
            pattern++;
776
305
            DISPATCH;
777
778
305
        TARGET(SRE_OP_CATEGORY):
779
            /* match at given category */
780
            /* <CATEGORY> <code> */
781
12
            TRACE(("|%p|%p|CATEGORY %d\n", pattern,
782
12
                   ptr, *pattern));
783
12
            if (ptr >= end || !sre_category(pattern[0], ptr[0]))
784
12
                RETURN_FAILURE;
785
0
            pattern++;
786
0
            ptr++;
787
0
            DISPATCH;
788
789
4
        TARGET(SRE_OP_ANY):
790
            /* match anything (except a newline) */
791
            /* <ANY> */
792
4
            TRACE(("|%p|%p|ANY\n", pattern, ptr));
793
4
            if (ptr >= end || SRE_IS_LINEBREAK(ptr[0]))
794
1
                RETURN_FAILURE;
795
3
            ptr++;
796
3
            DISPATCH;
797
798
3
        TARGET(SRE_OP_ANY_ALL):
799
            /* match anything */
800
            /* <ANY_ALL> */
801
0
            TRACE(("|%p|%p|ANY_ALL\n", pattern, ptr));
802
0
            if (ptr >= end)
803
0
                RETURN_FAILURE;
804
0
            ptr++;
805
0
            DISPATCH;
806
807
1.34M
        TARGET(SRE_OP_IN):
808
            /* match set member (or non_member) */
809
            /* <IN> <skip> <set> */
810
1.34M
            TRACE(("|%p|%p|IN\n", pattern, ptr));
811
1.34M
            if (ptr >= end ||
812
1.34M
                !SRE(charset)(state, pattern + 1, *ptr))
813
83.3k
                RETURN_FAILURE;
814
1.26M
            pattern += pattern[0];
815
1.26M
            ptr++;
816
1.26M
            DISPATCH;
817
818
1.26M
        TARGET(SRE_OP_LITERAL_IGNORE):
819
0
            TRACE(("|%p|%p|LITERAL_IGNORE %d\n",
820
0
                   pattern, ptr, pattern[0]));
821
0
            if (ptr >= end ||
822
0
                sre_lower_ascii(*ptr) != *pattern)
823
0
                RETURN_FAILURE;
824
0
            pattern++;
825
0
            ptr++;
826
0
            DISPATCH;
827
828
28
        TARGET(SRE_OP_LITERAL_UNI_IGNORE):
829
28
            TRACE(("|%p|%p|LITERAL_UNI_IGNORE %d\n",
830
28
                   pattern, ptr, pattern[0]));
831
28
            if (ptr >= end ||
832
28
                sre_lower_unicode(*ptr) != *pattern)
833
0
                RETURN_FAILURE;
834
28
            pattern++;
835
28
            ptr++;
836
28
            DISPATCH;
837
838
28
        TARGET(SRE_OP_LITERAL_LOC_IGNORE):
839
0
            TRACE(("|%p|%p|LITERAL_LOC_IGNORE %d\n",
840
0
                   pattern, ptr, pattern[0]));
841
0
            if (ptr >= end
842
0
                || !char_loc_ignore(*pattern, *ptr))
843
0
                RETURN_FAILURE;
844
0
            pattern++;
845
0
            ptr++;
846
0
            DISPATCH;
847
848
0
        TARGET(SRE_OP_NOT_LITERAL_IGNORE):
849
0
            TRACE(("|%p|%p|NOT_LITERAL_IGNORE %d\n",
850
0
                   pattern, ptr, *pattern));
851
0
            if (ptr >= end ||
852
0
                sre_lower_ascii(*ptr) == *pattern)
853
0
                RETURN_FAILURE;
854
0
            pattern++;
855
0
            ptr++;
856
0
            DISPATCH;
857
858
0
        TARGET(SRE_OP_NOT_LITERAL_UNI_IGNORE):
859
0
            TRACE(("|%p|%p|NOT_LITERAL_UNI_IGNORE %d\n",
860
0
                   pattern, ptr, *pattern));
861
0
            if (ptr >= end ||
862
0
                sre_lower_unicode(*ptr) == *pattern)
863
0
                RETURN_FAILURE;
864
0
            pattern++;
865
0
            ptr++;
866
0
            DISPATCH;
867
868
0
        TARGET(SRE_OP_NOT_LITERAL_LOC_IGNORE):
869
0
            TRACE(("|%p|%p|NOT_LITERAL_LOC_IGNORE %d\n",
870
0
                   pattern, ptr, *pattern));
871
0
            if (ptr >= end
872
0
                || char_loc_ignore(*pattern, *ptr))
873
0
                RETURN_FAILURE;
874
0
            pattern++;
875
0
            ptr++;
876
0
            DISPATCH;
877
878
0
        TARGET(SRE_OP_IN_IGNORE):
879
0
            TRACE(("|%p|%p|IN_IGNORE\n", pattern, ptr));
880
0
            if (ptr >= end
881
0
                || !SRE(charset)(state, pattern+1,
882
0
                                 (SRE_CODE)sre_lower_ascii(*ptr)))
883
0
                RETURN_FAILURE;
884
0
            pattern += pattern[0];
885
0
            ptr++;
886
0
            DISPATCH;
887
888
24
        TARGET(SRE_OP_IN_UNI_IGNORE):
889
24
            TRACE(("|%p|%p|IN_UNI_IGNORE\n", pattern, ptr));
890
24
            if (ptr >= end
891
16
                || !SRE(charset)(state, pattern+1,
892
16
                                 (SRE_CODE)sre_lower_unicode(*ptr)))
893
16
                RETURN_FAILURE;
894
8
            pattern += pattern[0];
895
8
            ptr++;
896
8
            DISPATCH;
897
898
8
        TARGET(SRE_OP_IN_LOC_IGNORE):
899
0
            TRACE(("|%p|%p|IN_LOC_IGNORE\n", pattern, ptr));
900
0
            if (ptr >= end
901
0
                || !SRE(charset_loc_ignore)(state, pattern+1, *ptr))
902
0
                RETURN_FAILURE;
903
0
            pattern += pattern[0];
904
0
            ptr++;
905
0
            DISPATCH;
906
907
13
        TARGET(SRE_OP_JUMP):
908
13
        TARGET(SRE_OP_INFO):
909
            /* jump forward */
910
            /* <JUMP> <offset> */
911
13
            TRACE(("|%p|%p|JUMP %d\n", pattern,
912
13
                   ptr, pattern[0]));
913
13
            pattern += pattern[0];
914
13
            DISPATCH;
915
916
28
        TARGET(SRE_OP_BRANCH):
917
            /* alternation */
918
            /* <BRANCH> <0=skip> code <JUMP> ... <NULL> */
919
28
            TRACE(("|%p|%p|BRANCH\n", pattern, ptr));
920
28
            LASTMARK_SAVE();
921
28
            if (state->save_marks)
922
0
                MARK_PUSH(ctx->lastmark);
923
75
            for (; pattern[0]; pattern += pattern[0]) {
924
60
                if (pattern[1] == SRE_OP_LITERAL &&
925
20
                    (ptr >= end ||
926
20
                     (SRE_CODE) *ptr != pattern[2]))
927
18
                    continue;
928
42
                if (pattern[1] == SRE_OP_IN &&
929
0
                    (ptr >= end ||
930
0
                     !SRE(charset)(state, pattern + 3,
931
0
                                   (SRE_CODE) *ptr)))
932
0
                    continue;
933
42
                state->ptr = ptr;
934
42
                DO_JUMP(JUMP_BRANCH, jump_branch, pattern+1);
935
42
                if (ret) {
936
13
                    if (state->save_marks)
937
0
                        MARK_POP_DISCARD(ctx->lastmark);
938
13
                    RETURN_ON_ERROR(ret);
939
13
                    RETURN_SUCCESS;
940
13
                }
941
29
                if (state->save_marks)
942
0
                    MARK_POP_KEEP(ctx->lastmark);
943
29
                LASTMARK_RESTORE();
944
29
            }
945
15
            if (state->save_marks)
946
0
                MARK_POP_DISCARD(ctx->lastmark);
947
15
            RETURN_FAILURE;
948
949
1.24M
        TARGET(SRE_OP_REPEAT_ONE):
950
            /* match repeated sequence (maximizing regexp) */
951
952
            /* this operator only works if the repeated item is
953
               exactly one character wide, and we're not already
954
               collecting backtracking points.  for other cases,
955
               use the MAX_REPEAT operator */
956
957
            /* <REPEAT_ONE> <skip> <1=min> <2=max> item <SUCCESS> tail */
958
959
1.24M
            TRACE(("|%p|%p|REPEAT_ONE %d %d\n", pattern, ptr,
960
1.24M
                   pattern[1], pattern[2]));
961
962
1.24M
            if ((Py_ssize_t) pattern[1] > end - ptr)
963
538
                RETURN_FAILURE; /* cannot match */
964
965
1.23M
            state->ptr = ptr;
966
967
1.23M
            ret = SRE(count)(state, pattern+3, pattern[2]);
968
1.23M
            RETURN_ON_ERROR(ret);
969
1.23M
            DATA_LOOKUP_AT(SRE(match_context), ctx, ctx_pos);
970
1.23M
            ctx->count = ret;
971
1.23M
            ptr += ctx->count;
972
973
            /* when we arrive here, count contains the number of
974
               matches, and ptr points to the tail of the target
975
               string.  check if the rest of the pattern matches,
976
               and backtrack if not. */
977
978
1.23M
            if (ctx->count < (Py_ssize_t) pattern[1])
979
1.23M
                RETURN_FAILURE;
980
981
6.90k
            if (pattern[pattern[0]] == SRE_OP_SUCCESS &&
982
5.89k
                ptr == state->end &&
983
1.17k
                !(ctx->toplevel && state->must_advance && ptr == state->start))
984
1.17k
            {
985
                /* tail is empty.  we're finished */
986
1.17k
                state->ptr = ptr;
987
1.17k
                RETURN_SUCCESS;
988
1.17k
            }
989
990
5.73k
            LASTMARK_SAVE();
991
5.73k
            if (state->save_marks)
992
48
                MARK_PUSH(ctx->lastmark);
993
994
5.73k
            if (pattern[pattern[0]] == SRE_OP_LITERAL) {
995
                /* tail starts with a literal. skip positions where
996
                   the rest of the pattern cannot possibly match */
997
38
                ctx->u.chr = pattern[pattern[0]+1];
998
38
                for (;;) {
999
252k
                    while (ctx->count >= (Py_ssize_t) pattern[1] &&
1000
252k
                           (ptr >= end || *ptr != ctx->u.chr)) {
1001
252k
                        ptr--;
1002
252k
                        ctx->count--;
1003
252k
                    }
1004
38
                    if (ctx->count < (Py_ssize_t) pattern[1])
1005
37
                        break;
1006
1
                    state->ptr = ptr;
1007
1
                    DO_JUMP(JUMP_REPEAT_ONE_1, jump_repeat_one_1,
1008
1
                            pattern+pattern[0]);
1009
1
                    if (ret) {
1010
1
                        if (state->save_marks)
1011
0
                            MARK_POP_DISCARD(ctx->lastmark);
1012
1
                        RETURN_ON_ERROR(ret);
1013
1
                        RETURN_SUCCESS;
1014
1
                    }
1015
0
                    if (state->save_marks)
1016
0
                        MARK_POP_KEEP(ctx->lastmark);
1017
0
                    LASTMARK_RESTORE();
1018
1019
0
                    ptr--;
1020
0
                    ctx->count--;
1021
0
                }
1022
37
                if (state->save_marks)
1023
0
                    MARK_POP_DISCARD(ctx->lastmark);
1024
5.69k
            } else {
1025
                /* general case */
1026
91.2k
                while (ctx->count >= (Py_ssize_t) pattern[1]) {
1027
90.4k
                    state->ptr = ptr;
1028
90.4k
                    DO_JUMP(JUMP_REPEAT_ONE_2, jump_repeat_one_2,
1029
90.4k
                            pattern+pattern[0]);
1030
90.4k
                    if (ret) {
1031
4.94k
                        if (state->save_marks)
1032
48
                            MARK_POP_DISCARD(ctx->lastmark);
1033
4.94k
                        RETURN_ON_ERROR(ret);
1034
4.94k
                        RETURN_SUCCESS;
1035
4.94k
                    }
1036
85.5k
                    if (state->save_marks)
1037
0
                        MARK_POP_KEEP(ctx->lastmark);
1038
85.5k
                    LASTMARK_RESTORE();
1039
1040
85.5k
                    ptr--;
1041
85.5k
                    ctx->count--;
1042
85.5k
                }
1043
746
                if (state->save_marks)
1044
0
                    MARK_POP_DISCARD(ctx->lastmark);
1045
746
            }
1046
783
            RETURN_FAILURE;
1047
1048
32
        TARGET(SRE_OP_MIN_REPEAT_ONE):
1049
            /* match repeated sequence (minimizing regexp) */
1050
1051
            /* this operator only works if the repeated item is
1052
               exactly one character wide, and we're not already
1053
               collecting backtracking points.  for other cases,
1054
               use the MIN_REPEAT operator */
1055
1056
            /* <MIN_REPEAT_ONE> <skip> <1=min> <2=max> item <SUCCESS> tail */
1057
1058
32
            TRACE(("|%p|%p|MIN_REPEAT_ONE %d %d\n", pattern, ptr,
1059
32
                   pattern[1], pattern[2]));
1060
1061
32
            if ((Py_ssize_t) pattern[1] > end - ptr)
1062
0
                RETURN_FAILURE; /* cannot match */
1063
1064
32
            state->ptr = ptr;
1065
1066
32
            if (pattern[1] == 0)
1067
11
                ctx->count = 0;
1068
21
            else {
1069
                /* count using pattern min as the maximum */
1070
21
                ret = SRE(count)(state, pattern+3, pattern[1]);
1071
21
                RETURN_ON_ERROR(ret);
1072
21
                DATA_LOOKUP_AT(SRE(match_context), ctx, ctx_pos);
1073
21
                if (ret < (Py_ssize_t) pattern[1])
1074
                    /* didn't match minimum number of times */
1075
20
                    RETURN_FAILURE;
1076
                /* advance past minimum matches of repeat */
1077
1
                ctx->count = ret;
1078
1
                ptr += ctx->count;
1079
1
            }
1080
1081
12
            if (pattern[pattern[0]] == SRE_OP_SUCCESS &&
1082
12
                !(ctx->toplevel &&
1083
12
                  ((state->match_all && ptr != state->end) ||
1084
12
                   (state->must_advance && ptr == state->start))))
1085
12
            {
1086
                /* tail is empty.  we're finished */
1087
12
                state->ptr = ptr;
1088
12
                RETURN_SUCCESS;
1089
1090
12
            } else {
1091
                /* general case */
1092
0
                LASTMARK_SAVE();
1093
0
                if (state->save_marks)
1094
0
                    MARK_PUSH(ctx->lastmark);
1095
1096
0
                while ((Py_ssize_t)pattern[2] == SRE_MAXREPEAT
1097
0
                       || ctx->count <= (Py_ssize_t)pattern[2]) {
1098
0
                    state->ptr = ptr;
1099
0
                    DO_JUMP(JUMP_MIN_REPEAT_ONE,jump_min_repeat_one,
1100
0
                            pattern+pattern[0]);
1101
0
                    if (ret) {
1102
0
                        if (state->save_marks)
1103
0
                            MARK_POP_DISCARD(ctx->lastmark);
1104
0
                        RETURN_ON_ERROR(ret);
1105
0
                        RETURN_SUCCESS;
1106
0
                    }
1107
0
                    if (state->save_marks)
1108
0
                        MARK_POP_KEEP(ctx->lastmark);
1109
0
                    LASTMARK_RESTORE();
1110
1111
0
                    state->ptr = ptr;
1112
0
                    ret = SRE(count)(state, pattern+3, 1);
1113
0
                    RETURN_ON_ERROR(ret);
1114
0
                    DATA_LOOKUP_AT(SRE(match_context), ctx, ctx_pos);
1115
0
                    if (ret == 0)
1116
0
                        break;
1117
0
                    assert(ret == 1);
1118
0
                    ptr++;
1119
0
                    ctx->count++;
1120
0
                }
1121
0
                if (state->save_marks)
1122
0
                    MARK_POP_DISCARD(ctx->lastmark);
1123
0
            }
1124
0
            RETURN_FAILURE;
1125
1126
0
        TARGET(SRE_OP_POSSESSIVE_REPEAT_ONE):
1127
            /* match repeated sequence (maximizing regexp) without
1128
               backtracking */
1129
1130
            /* this operator only works if the repeated item is
1131
               exactly one character wide, and we're not already
1132
               collecting backtracking points.  for other cases,
1133
               use the MAX_REPEAT operator */
1134
1135
            /* <POSSESSIVE_REPEAT_ONE> <skip> <1=min> <2=max> item <SUCCESS>
1136
               tail */
1137
1138
0
            TRACE(("|%p|%p|POSSESSIVE_REPEAT_ONE %d %d\n", pattern,
1139
0
                   ptr, pattern[1], pattern[2]));
1140
1141
0
            if (ptr + pattern[1] > end) {
1142
0
                RETURN_FAILURE; /* cannot match */
1143
0
            }
1144
1145
0
            state->ptr = ptr;
1146
1147
0
            ret = SRE(count)(state, pattern + 3, pattern[2]);
1148
0
            RETURN_ON_ERROR(ret);
1149
0
            DATA_LOOKUP_AT(SRE(match_context), ctx, ctx_pos);
1150
0
            ctx->count = ret;
1151
0
            ptr += ctx->count;
1152
1153
            /* when we arrive here, count contains the number of
1154
               matches, and ptr points to the tail of the target
1155
               string.  check if the rest of the pattern matches,
1156
               and fail if not. */
1157
1158
            /* Test for not enough repetitions in match */
1159
0
            if (ctx->count < (Py_ssize_t) pattern[1]) {
1160
0
                RETURN_FAILURE;
1161
0
            }
1162
1163
            /* Update the pattern to point to the next op code */
1164
0
            pattern += pattern[0];
1165
1166
            /* Let the tail be evaluated separately and consider this
1167
               match successful. */
1168
0
            if (*pattern == SRE_OP_SUCCESS &&
1169
0
                ptr == state->end &&
1170
0
                !(ctx->toplevel && state->must_advance && ptr == state->start))
1171
0
            {
1172
                /* tail is empty.  we're finished */
1173
0
                state->ptr = ptr;
1174
0
                RETURN_SUCCESS;
1175
0
            }
1176
1177
            /* Attempt to match the rest of the string */
1178
0
            DISPATCH;
1179
1180
83.4k
        TARGET(SRE_OP_REPEAT):
1181
            /* create repeat context.  all the hard work is done
1182
               by the UNTIL operator (MAX_UNTIL, MIN_UNTIL) */
1183
            /* <REPEAT> <skip> <1=min> <2=max>
1184
               <3=repeat_index> item <UNTIL> tail */
1185
83.4k
            TRACE(("|%p|%p|REPEAT %d %d\n", pattern, ptr,
1186
83.4k
                   pattern[1], pattern[2]));
1187
1188
            /* install new repeat context */
1189
83.4k
            ctx->u.rep = repeat_pool_malloc(state);
1190
83.4k
            if (!ctx->u.rep) {
1191
0
                RETURN_ERROR(SRE_ERROR_MEMORY);
1192
0
            }
1193
83.4k
            ctx->u.rep->count = -1;
1194
83.4k
            ctx->u.rep->pattern = pattern;
1195
83.4k
            ctx->u.rep->prev = state->repeat;
1196
83.4k
            ctx->u.rep->last_ptr = NULL;
1197
83.4k
            state->repeat = ctx->u.rep;
1198
83.4k
            state->save_marks++;
1199
1200
83.4k
            state->ptr = ptr;
1201
83.4k
            DO_JUMP(JUMP_REPEAT, jump_repeat, pattern+pattern[0]);
1202
83.4k
            state->repeat = ctx->u.rep->prev;
1203
83.4k
            state->save_marks--;
1204
83.4k
            repeat_pool_free(state, ctx->u.rep);
1205
1206
83.4k
            if (ret) {
1207
119
                RETURN_ON_ERROR(ret);
1208
119
                RETURN_SUCCESS;
1209
119
            }
1210
83.3k
            RETURN_FAILURE;
1211
1212
1.34M
        TARGET(SRE_OP_MAX_UNTIL):
1213
            /* maximizing repeat */
1214
            /* <REPEAT> <skip> <1=min> <2=max> item <MAX_UNTIL> tail */
1215
1216
            /* FIXME: we probably need to deal with zero-width
1217
               matches in here... */
1218
1219
1.34M
            ctx->u.rep = state->repeat;
1220
1.34M
            if (!ctx->u.rep)
1221
0
                RETURN_ERROR(SRE_ERROR_STATE);
1222
1223
1.34M
            state->ptr = ptr;
1224
1225
1.34M
            ctx->count = ctx->u.rep->count+1;
1226
1227
1.34M
            TRACE(("|%p|%p|MAX_UNTIL %zd\n", pattern,
1228
1.34M
                   ptr, ctx->count));
1229
1230
1.34M
            if (ctx->count < (Py_ssize_t) ctx->u.rep->pattern[1]) {
1231
                /* not enough matches */
1232
0
                ctx->u.rep->count = ctx->count;
1233
0
                DO_JUMP(JUMP_MAX_UNTIL_1, jump_max_until_1,
1234
0
                        ctx->u.rep->pattern+3);
1235
0
                if (ret) {
1236
0
                    RETURN_ON_ERROR(ret);
1237
0
                    RETURN_SUCCESS;
1238
0
                }
1239
0
                ctx->u.rep->count = ctx->count-1;
1240
0
                state->ptr = ptr;
1241
0
                RETURN_FAILURE;
1242
0
            }
1243
1244
1.34M
            if ((ctx->count < (Py_ssize_t) ctx->u.rep->pattern[2] ||
1245
4
                ctx->u.rep->pattern[2] == SRE_MAXREPEAT) &&
1246
1.34M
                state->ptr != ctx->u.rep->last_ptr) {
1247
                /* we may have enough matches, but if we can
1248
                   match another item, do so */
1249
1.34M
                ctx->u.rep->count = ctx->count;
1250
1.34M
                LASTMARK_SAVE();
1251
1.34M
                MARK_PUSH(ctx->lastmark);
1252
                /* zero-width match protection */
1253
1.34M
                LAST_PTR_PUSH();
1254
1.34M
                ctx->u.rep->last_ptr = state->ptr;
1255
1.34M
                DO_JUMP(JUMP_MAX_UNTIL_2, jump_max_until_2,
1256
1.34M
                        ctx->u.rep->pattern+3);
1257
1.34M
                LAST_PTR_POP();
1258
1.34M
                if (ret) {
1259
114k
                    MARK_POP_DISCARD(ctx->lastmark);
1260
114k
                    RETURN_ON_ERROR(ret);
1261
114k
                    RETURN_SUCCESS;
1262
114k
                }
1263
1.23M
                MARK_POP(ctx->lastmark);
1264
1.23M
                LASTMARK_RESTORE();
1265
1.23M
                ctx->u.rep->count = ctx->count-1;
1266
1.23M
                state->ptr = ptr;
1267
1.23M
            }
1268
1269
            /* cannot match more repeated items here.  make sure the
1270
               tail matches */
1271
1.23M
            state->repeat = ctx->u.rep->prev;
1272
1.23M
            state->save_marks--;
1273
1.23M
            DO_JUMP(JUMP_MAX_UNTIL_3, jump_max_until_3, pattern);
1274
1.23M
            state->repeat = ctx->u.rep; // restore repeat before return
1275
1.23M
            state->save_marks++;
1276
1277
1.23M
            RETURN_ON_SUCCESS(ret);
1278
1.23M
            state->ptr = ptr;
1279
1.23M
            RETURN_FAILURE;
1280
1281
0
        TARGET(SRE_OP_MIN_UNTIL):
1282
            /* minimizing repeat */
1283
            /* <REPEAT> <skip> <1=min> <2=max> item <MIN_UNTIL> tail */
1284
1285
0
            ctx->u.rep = state->repeat;
1286
0
            if (!ctx->u.rep)
1287
0
                RETURN_ERROR(SRE_ERROR_STATE);
1288
1289
0
            state->ptr = ptr;
1290
1291
0
            ctx->count = ctx->u.rep->count+1;
1292
1293
0
            TRACE(("|%p|%p|MIN_UNTIL %zd %p\n", pattern,
1294
0
                   ptr, ctx->count, ctx->u.rep->pattern));
1295
1296
0
            if (ctx->count < (Py_ssize_t) ctx->u.rep->pattern[1]) {
1297
                /* not enough matches */
1298
0
                ctx->u.rep->count = ctx->count;
1299
0
                DO_JUMP(JUMP_MIN_UNTIL_1, jump_min_until_1,
1300
0
                        ctx->u.rep->pattern+3);
1301
0
                if (ret) {
1302
0
                    RETURN_ON_ERROR(ret);
1303
0
                    RETURN_SUCCESS;
1304
0
                }
1305
0
                ctx->u.rep->count = ctx->count-1;
1306
0
                state->ptr = ptr;
1307
0
                RETURN_FAILURE;
1308
0
            }
1309
1310
            /* see if the tail matches */
1311
0
            state->repeat = ctx->u.rep->prev;
1312
0
            state->save_marks--;
1313
1314
0
            LASTMARK_SAVE();
1315
0
            if (state->save_marks)
1316
0
                MARK_PUSH(ctx->lastmark);
1317
1318
0
            DO_JUMP(JUMP_MIN_UNTIL_2, jump_min_until_2, pattern);
1319
            /* save_marks is balanced across the jump, so this equals the
1320
               value tested for MARK_PUSH above */
1321
0
            int pushed = state->save_marks != 0;
1322
0
            state->repeat = ctx->u.rep; // restore repeat before return
1323
0
            state->save_marks++;
1324
1325
0
            if (ret) {
1326
0
                if (pushed)
1327
0
                    MARK_POP_DISCARD(ctx->lastmark);
1328
0
                RETURN_ON_ERROR(ret);
1329
0
                RETURN_SUCCESS;
1330
0
            }
1331
0
            if (pushed)
1332
0
                MARK_POP(ctx->lastmark);
1333
0
            LASTMARK_RESTORE();
1334
1335
0
            state->ptr = ptr;
1336
1337
0
            if ((ctx->count >= (Py_ssize_t) ctx->u.rep->pattern[2]
1338
0
                && ctx->u.rep->pattern[2] != SRE_MAXREPEAT) ||
1339
0
                state->ptr == ctx->u.rep->last_ptr)
1340
0
                RETURN_FAILURE;
1341
1342
0
            ctx->u.rep->count = ctx->count;
1343
            /* zero-width match protection */
1344
0
            LAST_PTR_PUSH();
1345
0
            ctx->u.rep->last_ptr = state->ptr;
1346
0
            DO_JUMP(JUMP_MIN_UNTIL_3,jump_min_until_3,
1347
0
                    ctx->u.rep->pattern+3);
1348
0
            LAST_PTR_POP();
1349
0
            if (ret) {
1350
0
                RETURN_ON_ERROR(ret);
1351
0
                RETURN_SUCCESS;
1352
0
            }
1353
0
            ctx->u.rep->count = ctx->count-1;
1354
0
            state->ptr = ptr;
1355
0
            RETURN_FAILURE;
1356
1357
0
        TARGET(SRE_OP_POSSESSIVE_REPEAT):
1358
            /* create possessive repeat contexts. */
1359
            /* <POSSESSIVE_REPEAT> <skip> <1=min> <2=max> pattern
1360
               <SUCCESS> tail */
1361
0
            TRACE(("|%p|%p|POSSESSIVE_REPEAT %d %d\n", pattern,
1362
0
                   ptr, pattern[1], pattern[2]));
1363
1364
            /* Set the global Input pointer to this context's Input
1365
               pointer */
1366
0
            state->ptr = ptr;
1367
1368
            /* Capture groups in the body can be revisited on backtracking
1369
               between iterations, so their marks must be saved and restored,
1370
               as is done inside a repeat. */
1371
0
            state->save_marks++;
1372
1373
            /* Initialize Count to 0 */
1374
0
            ctx->count = 0;
1375
1376
            /* Check for minimum required matches. */
1377
0
            while (ctx->count < (Py_ssize_t)pattern[1]) {
1378
                /* not enough matches */
1379
0
                DO_JUMP0(JUMP_POSS_REPEAT_1, jump_poss_repeat_1,
1380
0
                         &pattern[3]);
1381
0
                if (ret) {
1382
0
                    RETURN_ON_ERROR(ret);
1383
0
                    ctx->count++;
1384
0
                }
1385
0
                else {
1386
0
                    state->ptr = ptr;
1387
0
                    state->save_marks--;
1388
0
                    RETURN_FAILURE;
1389
0
                }
1390
0
            }
1391
1392
            /* Clear the context's Input stream pointer so that it
1393
               doesn't match the global state so that the while loop can
1394
               be entered. */
1395
0
            ptr = NULL;
1396
1397
            /* Keep trying to parse the <pattern> sub-pattern until the
1398
               end is reached, creating a new context each time. */
1399
0
            while ((ctx->count < (Py_ssize_t)pattern[2] ||
1400
0
                    (Py_ssize_t)pattern[2] == SRE_MAXREPEAT) &&
1401
0
                   state->ptr != ptr) {
1402
                /* Save the Capture Group Marker state into the current
1403
                   Context and back up the current highest number
1404
                   Capture Group marker. */
1405
0
                LASTMARK_SAVE();
1406
0
                MARK_PUSH(ctx->lastmark);
1407
1408
                /* zero-width match protection */
1409
                /* Set the context's Input Stream pointer to be the
1410
                   current Input Stream pointer from the global
1411
                   state.  When the loop reaches the next iteration,
1412
                   the context will then store the last known good
1413
                   position with the global state holding the Input
1414
                   Input Stream position that has been updated with
1415
                   the most recent match.  Thus, if state's Input
1416
                   stream remains the same as the one stored in the
1417
                   current Context, we know we have successfully
1418
                   matched an empty string and that all subsequent
1419
                   matches will also be the empty string until the
1420
                   maximum number of matches are counted, and because
1421
                   of this, we could immediately stop at that point and
1422
                   consider this match successful. */
1423
0
                ptr = state->ptr;
1424
1425
                /* We have not reached the maximin matches, so try to
1426
                   match once more. */
1427
0
                DO_JUMP0(JUMP_POSS_REPEAT_2, jump_poss_repeat_2,
1428
0
                         &pattern[3]);
1429
1430
                /* Check to see if the last attempted match
1431
                   succeeded. */
1432
0
                if (ret) {
1433
                    /* Drop the saved highest number Capture Group
1434
                       marker saved above and use the newly updated
1435
                       value. */
1436
0
                    MARK_POP_DISCARD(ctx->lastmark);
1437
0
                    RETURN_ON_ERROR(ret);
1438
1439
                    /* Success, increment the count. */
1440
0
                    ctx->count++;
1441
0
                }
1442
                /* Last attempted match failed. */
1443
0
                else {
1444
                    /* Restore the previously saved highest number
1445
                       Capture Group marker since the last iteration
1446
                       did not match, then restore that to the global
1447
                       state. */
1448
0
                    MARK_POP(ctx->lastmark);
1449
0
                    LASTMARK_RESTORE();
1450
1451
                    /* Restore the global Input Stream pointer
1452
                       since it can change after jumps. */
1453
0
                    state->ptr = ptr;
1454
1455
                    /* We have sufficient matches, so exit loop. */
1456
0
                    break;
1457
0
                }
1458
0
            }
1459
1460
0
            state->save_marks--;
1461
1462
            /* Evaluate Tail */
1463
            /* Jump to end of pattern indicated by skip, and then skip
1464
               the SUCCESS op code that follows it. */
1465
0
            pattern += pattern[0] + 1;
1466
0
            ptr = state->ptr;
1467
0
            DISPATCH;
1468
1469
0
        TARGET(SRE_OP_ATOMIC_GROUP):
1470
            /* Atomic Group Sub Pattern */
1471
            /* <ATOMIC_GROUP> <skip> pattern <SUCCESS> tail */
1472
0
            TRACE(("|%p|%p|ATOMIC_GROUP\n", pattern, ptr));
1473
1474
            /* Set the global Input pointer to this context's Input
1475
               pointer */
1476
0
            state->ptr = ptr;
1477
1478
            /* Evaluate the Atomic Group in a new context, terminating
1479
               when the end of the group, represented by a SUCCESS op
1480
               code, is reached. */
1481
            /* Group Pattern begins at an offset of 1 code. */
1482
0
            DO_JUMP0(JUMP_ATOMIC_GROUP, jump_atomic_group,
1483
0
                     &pattern[1]);
1484
1485
            /* Test Exit Condition */
1486
0
            RETURN_ON_ERROR(ret);
1487
1488
0
            if (ret == 0) {
1489
                /* Atomic Group failed to Match. */
1490
0
                state->ptr = ptr;
1491
0
                RETURN_FAILURE;
1492
0
            }
1493
1494
            /* Evaluate Tail */
1495
            /* Jump to end of pattern indicated by skip, and then skip
1496
               the SUCCESS op code that follows it. */
1497
0
            pattern += pattern[0];
1498
0
            ptr = state->ptr;
1499
0
            DISPATCH;
1500
1501
0
        TARGET(SRE_OP_GROUPREF):
1502
            /* match backreference */
1503
0
            TRACE(("|%p|%p|GROUPREF %d\n", pattern,
1504
0
                   ptr, pattern[0]));
1505
0
            {
1506
0
                int groupref = pattern[0] * 2;
1507
0
                if (groupref >= state->lastmark) {
1508
0
                    RETURN_FAILURE;
1509
0
                } else {
1510
0
                    SRE_CHAR* p = (SRE_CHAR*) state->mark[groupref];
1511
0
                    SRE_CHAR* e = (SRE_CHAR*) state->mark[groupref+1];
1512
0
                    if (!p || !e || e < p)
1513
0
                        RETURN_FAILURE;
1514
0
                    while (p < e) {
1515
0
                        if (ptr >= end || *ptr != *p)
1516
0
                            RETURN_FAILURE;
1517
0
                        p++;
1518
0
                        ptr++;
1519
0
                    }
1520
0
                }
1521
0
            }
1522
0
            pattern++;
1523
0
            DISPATCH;
1524
1525
0
        TARGET(SRE_OP_GROUPREF_IGNORE):
1526
            /* match backreference */
1527
0
            TRACE(("|%p|%p|GROUPREF_IGNORE %d\n", pattern,
1528
0
                   ptr, pattern[0]));
1529
0
            {
1530
0
                int groupref = pattern[0] * 2;
1531
0
                if (groupref >= state->lastmark) {
1532
0
                    RETURN_FAILURE;
1533
0
                } else {
1534
0
                    SRE_CHAR* p = (SRE_CHAR*) state->mark[groupref];
1535
0
                    SRE_CHAR* e = (SRE_CHAR*) state->mark[groupref+1];
1536
0
                    if (!p || !e || e < p)
1537
0
                        RETURN_FAILURE;
1538
0
                    while (p < e) {
1539
0
                        if (ptr >= end ||
1540
0
                            sre_lower_ascii(*ptr) != sre_lower_ascii(*p))
1541
0
                            RETURN_FAILURE;
1542
0
                        p++;
1543
0
                        ptr++;
1544
0
                    }
1545
0
                }
1546
0
            }
1547
0
            pattern++;
1548
0
            DISPATCH;
1549
1550
0
        TARGET(SRE_OP_GROUPREF_UNI_IGNORE):
1551
            /* match backreference */
1552
0
            TRACE(("|%p|%p|GROUPREF_UNI_IGNORE %d\n", pattern,
1553
0
                   ptr, pattern[0]));
1554
0
            {
1555
0
                int groupref = pattern[0] * 2;
1556
0
                if (groupref >= state->lastmark) {
1557
0
                    RETURN_FAILURE;
1558
0
                } else {
1559
0
                    SRE_CHAR* p = (SRE_CHAR*) state->mark[groupref];
1560
0
                    SRE_CHAR* e = (SRE_CHAR*) state->mark[groupref+1];
1561
0
                    if (!p || !e || e < p)
1562
0
                        RETURN_FAILURE;
1563
0
                    while (p < e) {
1564
0
                        if (ptr >= end ||
1565
0
                            sre_lower_unicode(*ptr) != sre_lower_unicode(*p))
1566
0
                            RETURN_FAILURE;
1567
0
                        p++;
1568
0
                        ptr++;
1569
0
                    }
1570
0
                }
1571
0
            }
1572
0
            pattern++;
1573
0
            DISPATCH;
1574
1575
0
        TARGET(SRE_OP_GROUPREF_LOC_IGNORE):
1576
            /* match backreference */
1577
0
            TRACE(("|%p|%p|GROUPREF_LOC_IGNORE %d\n", pattern,
1578
0
                   ptr, pattern[0]));
1579
0
            {
1580
0
                int groupref = pattern[0] * 2;
1581
0
                if (groupref >= state->lastmark) {
1582
0
                    RETURN_FAILURE;
1583
0
                } else {
1584
0
                    SRE_CHAR* p = (SRE_CHAR*) state->mark[groupref];
1585
0
                    SRE_CHAR* e = (SRE_CHAR*) state->mark[groupref+1];
1586
0
                    if (!p || !e || e < p)
1587
0
                        RETURN_FAILURE;
1588
0
                    while (p < e) {
1589
0
                        if (ptr >= end ||
1590
0
                            sre_lower_locale(*ptr) != sre_lower_locale(*p))
1591
0
                            RETURN_FAILURE;
1592
0
                        p++;
1593
0
                        ptr++;
1594
0
                    }
1595
0
                }
1596
0
            }
1597
0
            pattern++;
1598
0
            DISPATCH;
1599
1600
0
        TARGET(SRE_OP_GROUPREF_EXISTS):
1601
0
            TRACE(("|%p|%p|GROUPREF_EXISTS %d\n", pattern,
1602
0
                   ptr, pattern[0]));
1603
            /* <GROUPREF_EXISTS> <group> <skip> codeyes <JUMP> codeno ... */
1604
0
            {
1605
0
                int groupref = pattern[0] * 2;
1606
0
                if (groupref >= state->lastmark) {
1607
0
                    pattern += pattern[1];
1608
0
                    DISPATCH;
1609
0
                } else {
1610
0
                    SRE_CHAR* p = (SRE_CHAR*) state->mark[groupref];
1611
0
                    SRE_CHAR* e = (SRE_CHAR*) state->mark[groupref+1];
1612
0
                    if (!p || !e || e < p) {
1613
0
                        pattern += pattern[1];
1614
0
                        DISPATCH;
1615
0
                    }
1616
0
                }
1617
0
            }
1618
0
            pattern += 2;
1619
0
            DISPATCH;
1620
1621
14
        TARGET(SRE_OP_ASSERT):
1622
            /* assert subpattern */
1623
            /* <ASSERT> <skip> <back> <pattern> */
1624
14
            TRACE(("|%p|%p|ASSERT %d\n", pattern,
1625
14
                   ptr, pattern[1]));
1626
14
            if ((uintptr_t)(ptr - (SRE_CHAR *)state->beginning) < pattern[1])
1627
0
                RETURN_FAILURE;
1628
14
            state->ptr = ptr - pattern[1];
1629
14
            DO_JUMP0(JUMP_ASSERT, jump_assert, pattern+2);
1630
14
            RETURN_ON_FAILURE(ret);
1631
2
            pattern += pattern[0];
1632
2
            DISPATCH;
1633
1634
2
        TARGET(SRE_OP_ASSERT_NOT):
1635
            /* assert not subpattern */
1636
            /* <ASSERT_NOT> <skip> <back> <pattern> */
1637
0
            TRACE(("|%p|%p|ASSERT_NOT %d\n", pattern,
1638
0
                   ptr, pattern[1]));
1639
0
            if ((uintptr_t)(ptr - (SRE_CHAR *)state->beginning) >= pattern[1]) {
1640
0
                state->ptr = ptr - pattern[1];
1641
0
                LASTMARK_SAVE();
1642
0
                if (state->save_marks)
1643
0
                    MARK_PUSH(ctx->lastmark);
1644
1645
0
                DO_JUMP0(JUMP_ASSERT_NOT, jump_assert_not, pattern+2);
1646
0
                if (ret) {
1647
0
                    if (state->save_marks)
1648
0
                        MARK_POP_DISCARD(ctx->lastmark);
1649
0
                    RETURN_ON_ERROR(ret);
1650
0
                    RETURN_FAILURE;
1651
0
                }
1652
0
                if (state->save_marks)
1653
0
                    MARK_POP(ctx->lastmark);
1654
0
                LASTMARK_RESTORE();
1655
0
            }
1656
0
            pattern += pattern[0];
1657
0
            DISPATCH;
1658
1659
0
        TARGET(SRE_OP_FAILURE):
1660
            /* immediate failure */
1661
0
            TRACE(("|%p|%p|FAILURE\n", pattern, ptr));
1662
0
            RETURN_FAILURE;
1663
1664
#if !USE_COMPUTED_GOTOS
1665
        default:
1666
#endif
1667
        // Also any unused opcodes:
1668
0
        TARGET(SRE_OP_RANGE_UNI_IGNORE):
1669
0
        TARGET(SRE_OP_SUBPATTERN):
1670
0
        TARGET(SRE_OP_RANGE):
1671
0
        TARGET(SRE_OP_NEGATE):
1672
0
        TARGET(SRE_OP_BIGCHARSET):
1673
0
        TARGET(SRE_OP_CHARSET):
1674
0
            TRACE(("|%p|%p|UNKNOWN %d\n", pattern, ptr,
1675
0
                   pattern[-1]));
1676
0
            RETURN_ERROR(SRE_ERROR_ILLEGAL);
1677
1678
0
    }
1679
1680
2.75M
exit:
1681
2.75M
    ctx_pos = ctx->last_ctx_pos;
1682
2.75M
    jump = ctx->jump;
1683
2.75M
    DATA_POP_DISCARD(ctx);
1684
2.75M
    if (ctx_pos == -1) {
1685
6.32k
        state->sigcount = sigcount;
1686
6.32k
        return ret;
1687
6.32k
    }
1688
2.75M
    DATA_LOOKUP_AT(SRE(match_context), ctx, ctx_pos);
1689
1690
2.75M
    switch (jump) {
1691
1.34M
        case JUMP_MAX_UNTIL_2:
1692
1.34M
            TRACE(("|%p|%p|JUMP_MAX_UNTIL_2\n", pattern, ptr));
1693
1.34M
            goto jump_max_until_2;
1694
1.23M
        case JUMP_MAX_UNTIL_3:
1695
1.23M
            TRACE(("|%p|%p|JUMP_MAX_UNTIL_3\n", pattern, ptr));
1696
1.23M
            goto jump_max_until_3;
1697
0
        case JUMP_MIN_UNTIL_2:
1698
0
            TRACE(("|%p|%p|JUMP_MIN_UNTIL_2\n", pattern, ptr));
1699
0
            goto jump_min_until_2;
1700
0
        case JUMP_MIN_UNTIL_3:
1701
0
            TRACE(("|%p|%p|JUMP_MIN_UNTIL_3\n", pattern, ptr));
1702
0
            goto jump_min_until_3;
1703
42
        case JUMP_BRANCH:
1704
42
            TRACE(("|%p|%p|JUMP_BRANCH\n", pattern, ptr));
1705
42
            goto jump_branch;
1706
0
        case JUMP_MAX_UNTIL_1:
1707
0
            TRACE(("|%p|%p|JUMP_MAX_UNTIL_1\n", pattern, ptr));
1708
0
            goto jump_max_until_1;
1709
0
        case JUMP_MIN_UNTIL_1:
1710
0
            TRACE(("|%p|%p|JUMP_MIN_UNTIL_1\n", pattern, ptr));
1711
0
            goto jump_min_until_1;
1712
0
        case JUMP_POSS_REPEAT_1:
1713
0
            TRACE(("|%p|%p|JUMP_POSS_REPEAT_1\n", pattern, ptr));
1714
0
            goto jump_poss_repeat_1;
1715
0
        case JUMP_POSS_REPEAT_2:
1716
0
            TRACE(("|%p|%p|JUMP_POSS_REPEAT_2\n", pattern, ptr));
1717
0
            goto jump_poss_repeat_2;
1718
83.4k
        case JUMP_REPEAT:
1719
83.4k
            TRACE(("|%p|%p|JUMP_REPEAT\n", pattern, ptr));
1720
83.4k
            goto jump_repeat;
1721
1
        case JUMP_REPEAT_ONE_1:
1722
1
            TRACE(("|%p|%p|JUMP_REPEAT_ONE_1\n", pattern, ptr));
1723
1
            goto jump_repeat_one_1;
1724
90.4k
        case JUMP_REPEAT_ONE_2:
1725
90.4k
            TRACE(("|%p|%p|JUMP_REPEAT_ONE_2\n", pattern, ptr));
1726
90.4k
            goto jump_repeat_one_2;
1727
0
        case JUMP_MIN_REPEAT_ONE:
1728
0
            TRACE(("|%p|%p|JUMP_MIN_REPEAT_ONE\n", pattern, ptr));
1729
0
            goto jump_min_repeat_one;
1730
0
        case JUMP_ATOMIC_GROUP:
1731
0
            TRACE(("|%p|%p|JUMP_ATOMIC_GROUP\n", pattern, ptr));
1732
0
            goto jump_atomic_group;
1733
14
        case JUMP_ASSERT:
1734
14
            TRACE(("|%p|%p|JUMP_ASSERT\n", pattern, ptr));
1735
14
            goto jump_assert;
1736
0
        case JUMP_ASSERT_NOT:
1737
0
            TRACE(("|%p|%p|JUMP_ASSERT_NOT\n", pattern, ptr));
1738
0
            goto jump_assert_not;
1739
0
        case JUMP_NONE:
1740
0
            TRACE(("|%p|%p|RETURN %zd\n", pattern,
1741
0
                   ptr, ret));
1742
0
            break;
1743
2.75M
    }
1744
1745
0
    return ret; /* should never get here */
1746
2.75M
}
sre.c:sre_ucs2_match
Line
Count
Source
663
1.65k
{
664
1.65k
    const SRE_CHAR* end = (const SRE_CHAR *)state->end;
665
1.65k
    Py_ssize_t alloc_pos, ctx_pos = -1;
666
1.65k
    Py_ssize_t ret = 0;
667
1.65k
    int jump;
668
1.65k
    unsigned int sigcount = state->sigcount;
669
670
1.65k
    SRE(match_context)* ctx;
671
1.65k
    SRE(match_context)* nextctx;
672
1.65k
    INIT_TRACE(state);
673
674
1.65k
    TRACE(("|%p|%p|ENTER\n", pattern, state->ptr));
675
676
1.65k
    DATA_ALLOC(SRE(match_context), ctx);
677
1.65k
    ctx->last_ctx_pos = -1;
678
1.65k
    ctx->jump = JUMP_NONE;
679
1.65k
    ctx->toplevel = toplevel;
680
1.65k
    ctx_pos = alloc_pos;
681
682
1.65k
#if USE_COMPUTED_GOTOS
683
1.65k
#include "sre_targets.h"
684
1.65k
#endif
685
686
3.26k
entrance:
687
688
3.26k
    ;  // Fashion statement.
689
3.26k
    const SRE_CHAR *ptr = (SRE_CHAR *)state->ptr;
690
691
3.26k
    if (pattern[0] == SRE_OP_INFO) {
692
        /* optimization info block */
693
        /* <INFO> <1=skip> <2=flags> <3=min> ... */
694
1.65k
        if (pattern[3] && (uintptr_t)(end - ptr) < pattern[3]) {
695
0
            TRACE(("reject (got %tu chars, need %zu)\n",
696
0
                   end - ptr, (size_t) pattern[3]));
697
0
            RETURN_FAILURE;
698
0
        }
699
1.65k
        pattern += pattern[1] + 1;
700
1.65k
    }
701
702
3.26k
#if USE_COMPUTED_GOTOS
703
3.26k
    DISPATCH;
704
#else
705
dispatch:
706
    MAYBE_CHECK_SIGNALS;
707
    switch (*pattern++)
708
#endif
709
3.26k
    {
710
711
3.26k
        TARGET(SRE_OP_MARK):
712
            /* set mark */
713
            /* <MARK> <gid> */
714
0
            TRACE(("|%p|%p|MARK %d\n", pattern,
715
0
                   ptr, pattern[0]));
716
0
            {
717
0
                int i = pattern[0];
718
0
                if (i & 1)
719
0
                    state->lastindex = i/2 + 1;
720
0
                if (i > state->lastmark) {
721
                    /* state->lastmark is the highest valid index in the
722
                       state->mark array.  If it is increased by more than 1,
723
                       the intervening marks must be set to NULL to signal
724
                       that these marks have not been encountered. */
725
0
                    int j = state->lastmark + 1;
726
0
                    while (j < i)
727
0
                        state->mark[j++] = NULL;
728
0
                    state->lastmark = i;
729
0
                }
730
0
                state->mark[i] = ptr;
731
0
            }
732
0
            pattern++;
733
0
            DISPATCH;
734
735
0
        TARGET(SRE_OP_LITERAL):
736
            /* match literal string */
737
            /* <LITERAL> <code> */
738
0
            TRACE(("|%p|%p|LITERAL %d\n", pattern,
739
0
                   ptr, *pattern));
740
0
            if (ptr >= end || (SRE_CODE) ptr[0] != pattern[0])
741
0
                RETURN_FAILURE;
742
0
            pattern++;
743
0
            ptr++;
744
0
            DISPATCH;
745
746
0
        TARGET(SRE_OP_NOT_LITERAL):
747
            /* match anything that is not literal character */
748
            /* <NOT_LITERAL> <code> */
749
0
            TRACE(("|%p|%p|NOT_LITERAL %d\n", pattern,
750
0
                   ptr, *pattern));
751
0
            if (ptr >= end || (SRE_CODE) ptr[0] == pattern[0])
752
0
                RETURN_FAILURE;
753
0
            pattern++;
754
0
            ptr++;
755
0
            DISPATCH;
756
757
1.60k
        TARGET(SRE_OP_SUCCESS):
758
            /* end of pattern */
759
1.60k
            TRACE(("|%p|%p|SUCCESS\n", pattern, ptr));
760
1.60k
            if (ctx->toplevel &&
761
1.60k
                ((state->match_all && ptr != state->end) ||
762
1.60k
                 (state->must_advance && ptr == state->start)))
763
0
            {
764
0
                RETURN_FAILURE;
765
0
            }
766
1.60k
            state->ptr = ptr;
767
1.60k
            RETURN_SUCCESS;
768
769
0
        TARGET(SRE_OP_AT):
770
            /* match at given position */
771
            /* <AT> <code> */
772
0
            TRACE(("|%p|%p|AT %d\n", pattern, ptr, *pattern));
773
0
            if (!SRE(at)(state, ptr, *pattern))
774
0
                RETURN_FAILURE;
775
0
            pattern++;
776
0
            DISPATCH;
777
778
0
        TARGET(SRE_OP_CATEGORY):
779
            /* match at given category */
780
            /* <CATEGORY> <code> */
781
0
            TRACE(("|%p|%p|CATEGORY %d\n", pattern,
782
0
                   ptr, *pattern));
783
0
            if (ptr >= end || !sre_category(pattern[0], ptr[0]))
784
0
                RETURN_FAILURE;
785
0
            pattern++;
786
0
            ptr++;
787
0
            DISPATCH;
788
789
0
        TARGET(SRE_OP_ANY):
790
            /* match anything (except a newline) */
791
            /* <ANY> */
792
0
            TRACE(("|%p|%p|ANY\n", pattern, ptr));
793
0
            if (ptr >= end || SRE_IS_LINEBREAK(ptr[0]))
794
0
                RETURN_FAILURE;
795
0
            ptr++;
796
0
            DISPATCH;
797
798
0
        TARGET(SRE_OP_ANY_ALL):
799
            /* match anything */
800
            /* <ANY_ALL> */
801
0
            TRACE(("|%p|%p|ANY_ALL\n", pattern, ptr));
802
0
            if (ptr >= end)
803
0
                RETURN_FAILURE;
804
0
            ptr++;
805
0
            DISPATCH;
806
807
0
        TARGET(SRE_OP_IN):
808
            /* match set member (or non_member) */
809
            /* <IN> <skip> <set> */
810
0
            TRACE(("|%p|%p|IN\n", pattern, ptr));
811
0
            if (ptr >= end ||
812
0
                !SRE(charset)(state, pattern + 1, *ptr))
813
0
                RETURN_FAILURE;
814
0
            pattern += pattern[0];
815
0
            ptr++;
816
0
            DISPATCH;
817
818
0
        TARGET(SRE_OP_LITERAL_IGNORE):
819
0
            TRACE(("|%p|%p|LITERAL_IGNORE %d\n",
820
0
                   pattern, ptr, pattern[0]));
821
0
            if (ptr >= end ||
822
0
                sre_lower_ascii(*ptr) != *pattern)
823
0
                RETURN_FAILURE;
824
0
            pattern++;
825
0
            ptr++;
826
0
            DISPATCH;
827
828
0
        TARGET(SRE_OP_LITERAL_UNI_IGNORE):
829
0
            TRACE(("|%p|%p|LITERAL_UNI_IGNORE %d\n",
830
0
                   pattern, ptr, pattern[0]));
831
0
            if (ptr >= end ||
832
0
                sre_lower_unicode(*ptr) != *pattern)
833
0
                RETURN_FAILURE;
834
0
            pattern++;
835
0
            ptr++;
836
0
            DISPATCH;
837
838
0
        TARGET(SRE_OP_LITERAL_LOC_IGNORE):
839
0
            TRACE(("|%p|%p|LITERAL_LOC_IGNORE %d\n",
840
0
                   pattern, ptr, pattern[0]));
841
0
            if (ptr >= end
842
0
                || !char_loc_ignore(*pattern, *ptr))
843
0
                RETURN_FAILURE;
844
0
            pattern++;
845
0
            ptr++;
846
0
            DISPATCH;
847
848
0
        TARGET(SRE_OP_NOT_LITERAL_IGNORE):
849
0
            TRACE(("|%p|%p|NOT_LITERAL_IGNORE %d\n",
850
0
                   pattern, ptr, *pattern));
851
0
            if (ptr >= end ||
852
0
                sre_lower_ascii(*ptr) == *pattern)
853
0
                RETURN_FAILURE;
854
0
            pattern++;
855
0
            ptr++;
856
0
            DISPATCH;
857
858
0
        TARGET(SRE_OP_NOT_LITERAL_UNI_IGNORE):
859
0
            TRACE(("|%p|%p|NOT_LITERAL_UNI_IGNORE %d\n",
860
0
                   pattern, ptr, *pattern));
861
0
            if (ptr >= end ||
862
0
                sre_lower_unicode(*ptr) == *pattern)
863
0
                RETURN_FAILURE;
864
0
            pattern++;
865
0
            ptr++;
866
0
            DISPATCH;
867
868
0
        TARGET(SRE_OP_NOT_LITERAL_LOC_IGNORE):
869
0
            TRACE(("|%p|%p|NOT_LITERAL_LOC_IGNORE %d\n",
870
0
                   pattern, ptr, *pattern));
871
0
            if (ptr >= end
872
0
                || char_loc_ignore(*pattern, *ptr))
873
0
                RETURN_FAILURE;
874
0
            pattern++;
875
0
            ptr++;
876
0
            DISPATCH;
877
878
0
        TARGET(SRE_OP_IN_IGNORE):
879
0
            TRACE(("|%p|%p|IN_IGNORE\n", pattern, ptr));
880
0
            if (ptr >= end
881
0
                || !SRE(charset)(state, pattern+1,
882
0
                                 (SRE_CODE)sre_lower_ascii(*ptr)))
883
0
                RETURN_FAILURE;
884
0
            pattern += pattern[0];
885
0
            ptr++;
886
0
            DISPATCH;
887
888
0
        TARGET(SRE_OP_IN_UNI_IGNORE):
889
0
            TRACE(("|%p|%p|IN_UNI_IGNORE\n", pattern, ptr));
890
0
            if (ptr >= end
891
0
                || !SRE(charset)(state, pattern+1,
892
0
                                 (SRE_CODE)sre_lower_unicode(*ptr)))
893
0
                RETURN_FAILURE;
894
0
            pattern += pattern[0];
895
0
            ptr++;
896
0
            DISPATCH;
897
898
0
        TARGET(SRE_OP_IN_LOC_IGNORE):
899
0
            TRACE(("|%p|%p|IN_LOC_IGNORE\n", pattern, ptr));
900
0
            if (ptr >= end
901
0
                || !SRE(charset_loc_ignore)(state, pattern+1, *ptr))
902
0
                RETURN_FAILURE;
903
0
            pattern += pattern[0];
904
0
            ptr++;
905
0
            DISPATCH;
906
907
0
        TARGET(SRE_OP_JUMP):
908
0
        TARGET(SRE_OP_INFO):
909
            /* jump forward */
910
            /* <JUMP> <offset> */
911
0
            TRACE(("|%p|%p|JUMP %d\n", pattern,
912
0
                   ptr, pattern[0]));
913
0
            pattern += pattern[0];
914
0
            DISPATCH;
915
916
0
        TARGET(SRE_OP_BRANCH):
917
            /* alternation */
918
            /* <BRANCH> <0=skip> code <JUMP> ... <NULL> */
919
0
            TRACE(("|%p|%p|BRANCH\n", pattern, ptr));
920
0
            LASTMARK_SAVE();
921
0
            if (state->save_marks)
922
0
                MARK_PUSH(ctx->lastmark);
923
0
            for (; pattern[0]; pattern += pattern[0]) {
924
0
                if (pattern[1] == SRE_OP_LITERAL &&
925
0
                    (ptr >= end ||
926
0
                     (SRE_CODE) *ptr != pattern[2]))
927
0
                    continue;
928
0
                if (pattern[1] == SRE_OP_IN &&
929
0
                    (ptr >= end ||
930
0
                     !SRE(charset)(state, pattern + 3,
931
0
                                   (SRE_CODE) *ptr)))
932
0
                    continue;
933
0
                state->ptr = ptr;
934
0
                DO_JUMP(JUMP_BRANCH, jump_branch, pattern+1);
935
0
                if (ret) {
936
0
                    if (state->save_marks)
937
0
                        MARK_POP_DISCARD(ctx->lastmark);
938
0
                    RETURN_ON_ERROR(ret);
939
0
                    RETURN_SUCCESS;
940
0
                }
941
0
                if (state->save_marks)
942
0
                    MARK_POP_KEEP(ctx->lastmark);
943
0
                LASTMARK_RESTORE();
944
0
            }
945
0
            if (state->save_marks)
946
0
                MARK_POP_DISCARD(ctx->lastmark);
947
0
            RETURN_FAILURE;
948
949
1.65k
        TARGET(SRE_OP_REPEAT_ONE):
950
            /* match repeated sequence (maximizing regexp) */
951
952
            /* this operator only works if the repeated item is
953
               exactly one character wide, and we're not already
954
               collecting backtracking points.  for other cases,
955
               use the MAX_REPEAT operator */
956
957
            /* <REPEAT_ONE> <skip> <1=min> <2=max> item <SUCCESS> tail */
958
959
1.65k
            TRACE(("|%p|%p|REPEAT_ONE %d %d\n", pattern, ptr,
960
1.65k
                   pattern[1], pattern[2]));
961
962
1.65k
            if ((Py_ssize_t) pattern[1] > end - ptr)
963
0
                RETURN_FAILURE; /* cannot match */
964
965
1.65k
            state->ptr = ptr;
966
967
1.65k
            ret = SRE(count)(state, pattern+3, pattern[2]);
968
1.65k
            RETURN_ON_ERROR(ret);
969
1.65k
            DATA_LOOKUP_AT(SRE(match_context), ctx, ctx_pos);
970
1.65k
            ctx->count = ret;
971
1.65k
            ptr += ctx->count;
972
973
            /* when we arrive here, count contains the number of
974
               matches, and ptr points to the tail of the target
975
               string.  check if the rest of the pattern matches,
976
               and backtrack if not. */
977
978
1.65k
            if (ctx->count < (Py_ssize_t) pattern[1])
979
0
                RETURN_FAILURE;
980
981
1.65k
            if (pattern[pattern[0]] == SRE_OP_SUCCESS &&
982
1.65k
                ptr == state->end &&
983
49
                !(ctx->toplevel && state->must_advance && ptr == state->start))
984
49
            {
985
                /* tail is empty.  we're finished */
986
49
                state->ptr = ptr;
987
49
                RETURN_SUCCESS;
988
49
            }
989
990
1.60k
            LASTMARK_SAVE();
991
1.60k
            if (state->save_marks)
992
0
                MARK_PUSH(ctx->lastmark);
993
994
1.60k
            if (pattern[pattern[0]] == SRE_OP_LITERAL) {
995
                /* tail starts with a literal. skip positions where
996
                   the rest of the pattern cannot possibly match */
997
0
                ctx->u.chr = pattern[pattern[0]+1];
998
0
                for (;;) {
999
0
                    while (ctx->count >= (Py_ssize_t) pattern[1] &&
1000
0
                           (ptr >= end || *ptr != ctx->u.chr)) {
1001
0
                        ptr--;
1002
0
                        ctx->count--;
1003
0
                    }
1004
0
                    if (ctx->count < (Py_ssize_t) pattern[1])
1005
0
                        break;
1006
0
                    state->ptr = ptr;
1007
0
                    DO_JUMP(JUMP_REPEAT_ONE_1, jump_repeat_one_1,
1008
0
                            pattern+pattern[0]);
1009
0
                    if (ret) {
1010
0
                        if (state->save_marks)
1011
0
                            MARK_POP_DISCARD(ctx->lastmark);
1012
0
                        RETURN_ON_ERROR(ret);
1013
0
                        RETURN_SUCCESS;
1014
0
                    }
1015
0
                    if (state->save_marks)
1016
0
                        MARK_POP_KEEP(ctx->lastmark);
1017
0
                    LASTMARK_RESTORE();
1018
1019
0
                    ptr--;
1020
0
                    ctx->count--;
1021
0
                }
1022
0
                if (state->save_marks)
1023
0
                    MARK_POP_DISCARD(ctx->lastmark);
1024
1.60k
            } else {
1025
                /* general case */
1026
1.60k
                while (ctx->count >= (Py_ssize_t) pattern[1]) {
1027
1.60k
                    state->ptr = ptr;
1028
1.60k
                    DO_JUMP(JUMP_REPEAT_ONE_2, jump_repeat_one_2,
1029
1.60k
                            pattern+pattern[0]);
1030
1.60k
                    if (ret) {
1031
1.60k
                        if (state->save_marks)
1032
0
                            MARK_POP_DISCARD(ctx->lastmark);
1033
1.60k
                        RETURN_ON_ERROR(ret);
1034
1.60k
                        RETURN_SUCCESS;
1035
1.60k
                    }
1036
0
                    if (state->save_marks)
1037
0
                        MARK_POP_KEEP(ctx->lastmark);
1038
0
                    LASTMARK_RESTORE();
1039
1040
0
                    ptr--;
1041
0
                    ctx->count--;
1042
0
                }
1043
0
                if (state->save_marks)
1044
0
                    MARK_POP_DISCARD(ctx->lastmark);
1045
0
            }
1046
0
            RETURN_FAILURE;
1047
1048
0
        TARGET(SRE_OP_MIN_REPEAT_ONE):
1049
            /* match repeated sequence (minimizing regexp) */
1050
1051
            /* this operator only works if the repeated item is
1052
               exactly one character wide, and we're not already
1053
               collecting backtracking points.  for other cases,
1054
               use the MIN_REPEAT operator */
1055
1056
            /* <MIN_REPEAT_ONE> <skip> <1=min> <2=max> item <SUCCESS> tail */
1057
1058
0
            TRACE(("|%p|%p|MIN_REPEAT_ONE %d %d\n", pattern, ptr,
1059
0
                   pattern[1], pattern[2]));
1060
1061
0
            if ((Py_ssize_t) pattern[1] > end - ptr)
1062
0
                RETURN_FAILURE; /* cannot match */
1063
1064
0
            state->ptr = ptr;
1065
1066
0
            if (pattern[1] == 0)
1067
0
                ctx->count = 0;
1068
0
            else {
1069
                /* count using pattern min as the maximum */
1070
0
                ret = SRE(count)(state, pattern+3, pattern[1]);
1071
0
                RETURN_ON_ERROR(ret);
1072
0
                DATA_LOOKUP_AT(SRE(match_context), ctx, ctx_pos);
1073
0
                if (ret < (Py_ssize_t) pattern[1])
1074
                    /* didn't match minimum number of times */
1075
0
                    RETURN_FAILURE;
1076
                /* advance past minimum matches of repeat */
1077
0
                ctx->count = ret;
1078
0
                ptr += ctx->count;
1079
0
            }
1080
1081
0
            if (pattern[pattern[0]] == SRE_OP_SUCCESS &&
1082
0
                !(ctx->toplevel &&
1083
0
                  ((state->match_all && ptr != state->end) ||
1084
0
                   (state->must_advance && ptr == state->start))))
1085
0
            {
1086
                /* tail is empty.  we're finished */
1087
0
                state->ptr = ptr;
1088
0
                RETURN_SUCCESS;
1089
1090
0
            } else {
1091
                /* general case */
1092
0
                LASTMARK_SAVE();
1093
0
                if (state->save_marks)
1094
0
                    MARK_PUSH(ctx->lastmark);
1095
1096
0
                while ((Py_ssize_t)pattern[2] == SRE_MAXREPEAT
1097
0
                       || ctx->count <= (Py_ssize_t)pattern[2]) {
1098
0
                    state->ptr = ptr;
1099
0
                    DO_JUMP(JUMP_MIN_REPEAT_ONE,jump_min_repeat_one,
1100
0
                            pattern+pattern[0]);
1101
0
                    if (ret) {
1102
0
                        if (state->save_marks)
1103
0
                            MARK_POP_DISCARD(ctx->lastmark);
1104
0
                        RETURN_ON_ERROR(ret);
1105
0
                        RETURN_SUCCESS;
1106
0
                    }
1107
0
                    if (state->save_marks)
1108
0
                        MARK_POP_KEEP(ctx->lastmark);
1109
0
                    LASTMARK_RESTORE();
1110
1111
0
                    state->ptr = ptr;
1112
0
                    ret = SRE(count)(state, pattern+3, 1);
1113
0
                    RETURN_ON_ERROR(ret);
1114
0
                    DATA_LOOKUP_AT(SRE(match_context), ctx, ctx_pos);
1115
0
                    if (ret == 0)
1116
0
                        break;
1117
0
                    assert(ret == 1);
1118
0
                    ptr++;
1119
0
                    ctx->count++;
1120
0
                }
1121
0
                if (state->save_marks)
1122
0
                    MARK_POP_DISCARD(ctx->lastmark);
1123
0
            }
1124
0
            RETURN_FAILURE;
1125
1126
0
        TARGET(SRE_OP_POSSESSIVE_REPEAT_ONE):
1127
            /* match repeated sequence (maximizing regexp) without
1128
               backtracking */
1129
1130
            /* this operator only works if the repeated item is
1131
               exactly one character wide, and we're not already
1132
               collecting backtracking points.  for other cases,
1133
               use the MAX_REPEAT operator */
1134
1135
            /* <POSSESSIVE_REPEAT_ONE> <skip> <1=min> <2=max> item <SUCCESS>
1136
               tail */
1137
1138
0
            TRACE(("|%p|%p|POSSESSIVE_REPEAT_ONE %d %d\n", pattern,
1139
0
                   ptr, pattern[1], pattern[2]));
1140
1141
0
            if (ptr + pattern[1] > end) {
1142
0
                RETURN_FAILURE; /* cannot match */
1143
0
            }
1144
1145
0
            state->ptr = ptr;
1146
1147
0
            ret = SRE(count)(state, pattern + 3, pattern[2]);
1148
0
            RETURN_ON_ERROR(ret);
1149
0
            DATA_LOOKUP_AT(SRE(match_context), ctx, ctx_pos);
1150
0
            ctx->count = ret;
1151
0
            ptr += ctx->count;
1152
1153
            /* when we arrive here, count contains the number of
1154
               matches, and ptr points to the tail of the target
1155
               string.  check if the rest of the pattern matches,
1156
               and fail if not. */
1157
1158
            /* Test for not enough repetitions in match */
1159
0
            if (ctx->count < (Py_ssize_t) pattern[1]) {
1160
0
                RETURN_FAILURE;
1161
0
            }
1162
1163
            /* Update the pattern to point to the next op code */
1164
0
            pattern += pattern[0];
1165
1166
            /* Let the tail be evaluated separately and consider this
1167
               match successful. */
1168
0
            if (*pattern == SRE_OP_SUCCESS &&
1169
0
                ptr == state->end &&
1170
0
                !(ctx->toplevel && state->must_advance && ptr == state->start))
1171
0
            {
1172
                /* tail is empty.  we're finished */
1173
0
                state->ptr = ptr;
1174
0
                RETURN_SUCCESS;
1175
0
            }
1176
1177
            /* Attempt to match the rest of the string */
1178
0
            DISPATCH;
1179
1180
0
        TARGET(SRE_OP_REPEAT):
1181
            /* create repeat context.  all the hard work is done
1182
               by the UNTIL operator (MAX_UNTIL, MIN_UNTIL) */
1183
            /* <REPEAT> <skip> <1=min> <2=max>
1184
               <3=repeat_index> item <UNTIL> tail */
1185
0
            TRACE(("|%p|%p|REPEAT %d %d\n", pattern, ptr,
1186
0
                   pattern[1], pattern[2]));
1187
1188
            /* install new repeat context */
1189
0
            ctx->u.rep = repeat_pool_malloc(state);
1190
0
            if (!ctx->u.rep) {
1191
0
                RETURN_ERROR(SRE_ERROR_MEMORY);
1192
0
            }
1193
0
            ctx->u.rep->count = -1;
1194
0
            ctx->u.rep->pattern = pattern;
1195
0
            ctx->u.rep->prev = state->repeat;
1196
0
            ctx->u.rep->last_ptr = NULL;
1197
0
            state->repeat = ctx->u.rep;
1198
0
            state->save_marks++;
1199
1200
0
            state->ptr = ptr;
1201
0
            DO_JUMP(JUMP_REPEAT, jump_repeat, pattern+pattern[0]);
1202
0
            state->repeat = ctx->u.rep->prev;
1203
0
            state->save_marks--;
1204
0
            repeat_pool_free(state, ctx->u.rep);
1205
1206
0
            if (ret) {
1207
0
                RETURN_ON_ERROR(ret);
1208
0
                RETURN_SUCCESS;
1209
0
            }
1210
0
            RETURN_FAILURE;
1211
1212
0
        TARGET(SRE_OP_MAX_UNTIL):
1213
            /* maximizing repeat */
1214
            /* <REPEAT> <skip> <1=min> <2=max> item <MAX_UNTIL> tail */
1215
1216
            /* FIXME: we probably need to deal with zero-width
1217
               matches in here... */
1218
1219
0
            ctx->u.rep = state->repeat;
1220
0
            if (!ctx->u.rep)
1221
0
                RETURN_ERROR(SRE_ERROR_STATE);
1222
1223
0
            state->ptr = ptr;
1224
1225
0
            ctx->count = ctx->u.rep->count+1;
1226
1227
0
            TRACE(("|%p|%p|MAX_UNTIL %zd\n", pattern,
1228
0
                   ptr, ctx->count));
1229
1230
0
            if (ctx->count < (Py_ssize_t) ctx->u.rep->pattern[1]) {
1231
                /* not enough matches */
1232
0
                ctx->u.rep->count = ctx->count;
1233
0
                DO_JUMP(JUMP_MAX_UNTIL_1, jump_max_until_1,
1234
0
                        ctx->u.rep->pattern+3);
1235
0
                if (ret) {
1236
0
                    RETURN_ON_ERROR(ret);
1237
0
                    RETURN_SUCCESS;
1238
0
                }
1239
0
                ctx->u.rep->count = ctx->count-1;
1240
0
                state->ptr = ptr;
1241
0
                RETURN_FAILURE;
1242
0
            }
1243
1244
0
            if ((ctx->count < (Py_ssize_t) ctx->u.rep->pattern[2] ||
1245
0
                ctx->u.rep->pattern[2] == SRE_MAXREPEAT) &&
1246
0
                state->ptr != ctx->u.rep->last_ptr) {
1247
                /* we may have enough matches, but if we can
1248
                   match another item, do so */
1249
0
                ctx->u.rep->count = ctx->count;
1250
0
                LASTMARK_SAVE();
1251
0
                MARK_PUSH(ctx->lastmark);
1252
                /* zero-width match protection */
1253
0
                LAST_PTR_PUSH();
1254
0
                ctx->u.rep->last_ptr = state->ptr;
1255
0
                DO_JUMP(JUMP_MAX_UNTIL_2, jump_max_until_2,
1256
0
                        ctx->u.rep->pattern+3);
1257
0
                LAST_PTR_POP();
1258
0
                if (ret) {
1259
0
                    MARK_POP_DISCARD(ctx->lastmark);
1260
0
                    RETURN_ON_ERROR(ret);
1261
0
                    RETURN_SUCCESS;
1262
0
                }
1263
0
                MARK_POP(ctx->lastmark);
1264
0
                LASTMARK_RESTORE();
1265
0
                ctx->u.rep->count = ctx->count-1;
1266
0
                state->ptr = ptr;
1267
0
            }
1268
1269
            /* cannot match more repeated items here.  make sure the
1270
               tail matches */
1271
0
            state->repeat = ctx->u.rep->prev;
1272
0
            state->save_marks--;
1273
0
            DO_JUMP(JUMP_MAX_UNTIL_3, jump_max_until_3, pattern);
1274
0
            state->repeat = ctx->u.rep; // restore repeat before return
1275
0
            state->save_marks++;
1276
1277
0
            RETURN_ON_SUCCESS(ret);
1278
0
            state->ptr = ptr;
1279
0
            RETURN_FAILURE;
1280
1281
0
        TARGET(SRE_OP_MIN_UNTIL):
1282
            /* minimizing repeat */
1283
            /* <REPEAT> <skip> <1=min> <2=max> item <MIN_UNTIL> tail */
1284
1285
0
            ctx->u.rep = state->repeat;
1286
0
            if (!ctx->u.rep)
1287
0
                RETURN_ERROR(SRE_ERROR_STATE);
1288
1289
0
            state->ptr = ptr;
1290
1291
0
            ctx->count = ctx->u.rep->count+1;
1292
1293
0
            TRACE(("|%p|%p|MIN_UNTIL %zd %p\n", pattern,
1294
0
                   ptr, ctx->count, ctx->u.rep->pattern));
1295
1296
0
            if (ctx->count < (Py_ssize_t) ctx->u.rep->pattern[1]) {
1297
                /* not enough matches */
1298
0
                ctx->u.rep->count = ctx->count;
1299
0
                DO_JUMP(JUMP_MIN_UNTIL_1, jump_min_until_1,
1300
0
                        ctx->u.rep->pattern+3);
1301
0
                if (ret) {
1302
0
                    RETURN_ON_ERROR(ret);
1303
0
                    RETURN_SUCCESS;
1304
0
                }
1305
0
                ctx->u.rep->count = ctx->count-1;
1306
0
                state->ptr = ptr;
1307
0
                RETURN_FAILURE;
1308
0
            }
1309
1310
            /* see if the tail matches */
1311
0
            state->repeat = ctx->u.rep->prev;
1312
0
            state->save_marks--;
1313
1314
0
            LASTMARK_SAVE();
1315
0
            if (state->save_marks)
1316
0
                MARK_PUSH(ctx->lastmark);
1317
1318
0
            DO_JUMP(JUMP_MIN_UNTIL_2, jump_min_until_2, pattern);
1319
            /* save_marks is balanced across the jump, so this equals the
1320
               value tested for MARK_PUSH above */
1321
0
            int pushed = state->save_marks != 0;
1322
0
            state->repeat = ctx->u.rep; // restore repeat before return
1323
0
            state->save_marks++;
1324
1325
0
            if (ret) {
1326
0
                if (pushed)
1327
0
                    MARK_POP_DISCARD(ctx->lastmark);
1328
0
                RETURN_ON_ERROR(ret);
1329
0
                RETURN_SUCCESS;
1330
0
            }
1331
0
            if (pushed)
1332
0
                MARK_POP(ctx->lastmark);
1333
0
            LASTMARK_RESTORE();
1334
1335
0
            state->ptr = ptr;
1336
1337
0
            if ((ctx->count >= (Py_ssize_t) ctx->u.rep->pattern[2]
1338
0
                && ctx->u.rep->pattern[2] != SRE_MAXREPEAT) ||
1339
0
                state->ptr == ctx->u.rep->last_ptr)
1340
0
                RETURN_FAILURE;
1341
1342
0
            ctx->u.rep->count = ctx->count;
1343
            /* zero-width match protection */
1344
0
            LAST_PTR_PUSH();
1345
0
            ctx->u.rep->last_ptr = state->ptr;
1346
0
            DO_JUMP(JUMP_MIN_UNTIL_3,jump_min_until_3,
1347
0
                    ctx->u.rep->pattern+3);
1348
0
            LAST_PTR_POP();
1349
0
            if (ret) {
1350
0
                RETURN_ON_ERROR(ret);
1351
0
                RETURN_SUCCESS;
1352
0
            }
1353
0
            ctx->u.rep->count = ctx->count-1;
1354
0
            state->ptr = ptr;
1355
0
            RETURN_FAILURE;
1356
1357
0
        TARGET(SRE_OP_POSSESSIVE_REPEAT):
1358
            /* create possessive repeat contexts. */
1359
            /* <POSSESSIVE_REPEAT> <skip> <1=min> <2=max> pattern
1360
               <SUCCESS> tail */
1361
0
            TRACE(("|%p|%p|POSSESSIVE_REPEAT %d %d\n", pattern,
1362
0
                   ptr, pattern[1], pattern[2]));
1363
1364
            /* Set the global Input pointer to this context's Input
1365
               pointer */
1366
0
            state->ptr = ptr;
1367
1368
            /* Capture groups in the body can be revisited on backtracking
1369
               between iterations, so their marks must be saved and restored,
1370
               as is done inside a repeat. */
1371
0
            state->save_marks++;
1372
1373
            /* Initialize Count to 0 */
1374
0
            ctx->count = 0;
1375
1376
            /* Check for minimum required matches. */
1377
0
            while (ctx->count < (Py_ssize_t)pattern[1]) {
1378
                /* not enough matches */
1379
0
                DO_JUMP0(JUMP_POSS_REPEAT_1, jump_poss_repeat_1,
1380
0
                         &pattern[3]);
1381
0
                if (ret) {
1382
0
                    RETURN_ON_ERROR(ret);
1383
0
                    ctx->count++;
1384
0
                }
1385
0
                else {
1386
0
                    state->ptr = ptr;
1387
0
                    state->save_marks--;
1388
0
                    RETURN_FAILURE;
1389
0
                }
1390
0
            }
1391
1392
            /* Clear the context's Input stream pointer so that it
1393
               doesn't match the global state so that the while loop can
1394
               be entered. */
1395
0
            ptr = NULL;
1396
1397
            /* Keep trying to parse the <pattern> sub-pattern until the
1398
               end is reached, creating a new context each time. */
1399
0
            while ((ctx->count < (Py_ssize_t)pattern[2] ||
1400
0
                    (Py_ssize_t)pattern[2] == SRE_MAXREPEAT) &&
1401
0
                   state->ptr != ptr) {
1402
                /* Save the Capture Group Marker state into the current
1403
                   Context and back up the current highest number
1404
                   Capture Group marker. */
1405
0
                LASTMARK_SAVE();
1406
0
                MARK_PUSH(ctx->lastmark);
1407
1408
                /* zero-width match protection */
1409
                /* Set the context's Input Stream pointer to be the
1410
                   current Input Stream pointer from the global
1411
                   state.  When the loop reaches the next iteration,
1412
                   the context will then store the last known good
1413
                   position with the global state holding the Input
1414
                   Input Stream position that has been updated with
1415
                   the most recent match.  Thus, if state's Input
1416
                   stream remains the same as the one stored in the
1417
                   current Context, we know we have successfully
1418
                   matched an empty string and that all subsequent
1419
                   matches will also be the empty string until the
1420
                   maximum number of matches are counted, and because
1421
                   of this, we could immediately stop at that point and
1422
                   consider this match successful. */
1423
0
                ptr = state->ptr;
1424
1425
                /* We have not reached the maximin matches, so try to
1426
                   match once more. */
1427
0
                DO_JUMP0(JUMP_POSS_REPEAT_2, jump_poss_repeat_2,
1428
0
                         &pattern[3]);
1429
1430
                /* Check to see if the last attempted match
1431
                   succeeded. */
1432
0
                if (ret) {
1433
                    /* Drop the saved highest number Capture Group
1434
                       marker saved above and use the newly updated
1435
                       value. */
1436
0
                    MARK_POP_DISCARD(ctx->lastmark);
1437
0
                    RETURN_ON_ERROR(ret);
1438
1439
                    /* Success, increment the count. */
1440
0
                    ctx->count++;
1441
0
                }
1442
                /* Last attempted match failed. */
1443
0
                else {
1444
                    /* Restore the previously saved highest number
1445
                       Capture Group marker since the last iteration
1446
                       did not match, then restore that to the global
1447
                       state. */
1448
0
                    MARK_POP(ctx->lastmark);
1449
0
                    LASTMARK_RESTORE();
1450
1451
                    /* Restore the global Input Stream pointer
1452
                       since it can change after jumps. */
1453
0
                    state->ptr = ptr;
1454
1455
                    /* We have sufficient matches, so exit loop. */
1456
0
                    break;
1457
0
                }
1458
0
            }
1459
1460
0
            state->save_marks--;
1461
1462
            /* Evaluate Tail */
1463
            /* Jump to end of pattern indicated by skip, and then skip
1464
               the SUCCESS op code that follows it. */
1465
0
            pattern += pattern[0] + 1;
1466
0
            ptr = state->ptr;
1467
0
            DISPATCH;
1468
1469
0
        TARGET(SRE_OP_ATOMIC_GROUP):
1470
            /* Atomic Group Sub Pattern */
1471
            /* <ATOMIC_GROUP> <skip> pattern <SUCCESS> tail */
1472
0
            TRACE(("|%p|%p|ATOMIC_GROUP\n", pattern, ptr));
1473
1474
            /* Set the global Input pointer to this context's Input
1475
               pointer */
1476
0
            state->ptr = ptr;
1477
1478
            /* Evaluate the Atomic Group in a new context, terminating
1479
               when the end of the group, represented by a SUCCESS op
1480
               code, is reached. */
1481
            /* Group Pattern begins at an offset of 1 code. */
1482
0
            DO_JUMP0(JUMP_ATOMIC_GROUP, jump_atomic_group,
1483
0
                     &pattern[1]);
1484
1485
            /* Test Exit Condition */
1486
0
            RETURN_ON_ERROR(ret);
1487
1488
0
            if (ret == 0) {
1489
                /* Atomic Group failed to Match. */
1490
0
                state->ptr = ptr;
1491
0
                RETURN_FAILURE;
1492
0
            }
1493
1494
            /* Evaluate Tail */
1495
            /* Jump to end of pattern indicated by skip, and then skip
1496
               the SUCCESS op code that follows it. */
1497
0
            pattern += pattern[0];
1498
0
            ptr = state->ptr;
1499
0
            DISPATCH;
1500
1501
0
        TARGET(SRE_OP_GROUPREF):
1502
            /* match backreference */
1503
0
            TRACE(("|%p|%p|GROUPREF %d\n", pattern,
1504
0
                   ptr, pattern[0]));
1505
0
            {
1506
0
                int groupref = pattern[0] * 2;
1507
0
                if (groupref >= state->lastmark) {
1508
0
                    RETURN_FAILURE;
1509
0
                } else {
1510
0
                    SRE_CHAR* p = (SRE_CHAR*) state->mark[groupref];
1511
0
                    SRE_CHAR* e = (SRE_CHAR*) state->mark[groupref+1];
1512
0
                    if (!p || !e || e < p)
1513
0
                        RETURN_FAILURE;
1514
0
                    while (p < e) {
1515
0
                        if (ptr >= end || *ptr != *p)
1516
0
                            RETURN_FAILURE;
1517
0
                        p++;
1518
0
                        ptr++;
1519
0
                    }
1520
0
                }
1521
0
            }
1522
0
            pattern++;
1523
0
            DISPATCH;
1524
1525
0
        TARGET(SRE_OP_GROUPREF_IGNORE):
1526
            /* match backreference */
1527
0
            TRACE(("|%p|%p|GROUPREF_IGNORE %d\n", pattern,
1528
0
                   ptr, pattern[0]));
1529
0
            {
1530
0
                int groupref = pattern[0] * 2;
1531
0
                if (groupref >= state->lastmark) {
1532
0
                    RETURN_FAILURE;
1533
0
                } else {
1534
0
                    SRE_CHAR* p = (SRE_CHAR*) state->mark[groupref];
1535
0
                    SRE_CHAR* e = (SRE_CHAR*) state->mark[groupref+1];
1536
0
                    if (!p || !e || e < p)
1537
0
                        RETURN_FAILURE;
1538
0
                    while (p < e) {
1539
0
                        if (ptr >= end ||
1540
0
                            sre_lower_ascii(*ptr) != sre_lower_ascii(*p))
1541
0
                            RETURN_FAILURE;
1542
0
                        p++;
1543
0
                        ptr++;
1544
0
                    }
1545
0
                }
1546
0
            }
1547
0
            pattern++;
1548
0
            DISPATCH;
1549
1550
0
        TARGET(SRE_OP_GROUPREF_UNI_IGNORE):
1551
            /* match backreference */
1552
0
            TRACE(("|%p|%p|GROUPREF_UNI_IGNORE %d\n", pattern,
1553
0
                   ptr, pattern[0]));
1554
0
            {
1555
0
                int groupref = pattern[0] * 2;
1556
0
                if (groupref >= state->lastmark) {
1557
0
                    RETURN_FAILURE;
1558
0
                } else {
1559
0
                    SRE_CHAR* p = (SRE_CHAR*) state->mark[groupref];
1560
0
                    SRE_CHAR* e = (SRE_CHAR*) state->mark[groupref+1];
1561
0
                    if (!p || !e || e < p)
1562
0
                        RETURN_FAILURE;
1563
0
                    while (p < e) {
1564
0
                        if (ptr >= end ||
1565
0
                            sre_lower_unicode(*ptr) != sre_lower_unicode(*p))
1566
0
                            RETURN_FAILURE;
1567
0
                        p++;
1568
0
                        ptr++;
1569
0
                    }
1570
0
                }
1571
0
            }
1572
0
            pattern++;
1573
0
            DISPATCH;
1574
1575
0
        TARGET(SRE_OP_GROUPREF_LOC_IGNORE):
1576
            /* match backreference */
1577
0
            TRACE(("|%p|%p|GROUPREF_LOC_IGNORE %d\n", pattern,
1578
0
                   ptr, pattern[0]));
1579
0
            {
1580
0
                int groupref = pattern[0] * 2;
1581
0
                if (groupref >= state->lastmark) {
1582
0
                    RETURN_FAILURE;
1583
0
                } else {
1584
0
                    SRE_CHAR* p = (SRE_CHAR*) state->mark[groupref];
1585
0
                    SRE_CHAR* e = (SRE_CHAR*) state->mark[groupref+1];
1586
0
                    if (!p || !e || e < p)
1587
0
                        RETURN_FAILURE;
1588
0
                    while (p < e) {
1589
0
                        if (ptr >= end ||
1590
0
                            sre_lower_locale(*ptr) != sre_lower_locale(*p))
1591
0
                            RETURN_FAILURE;
1592
0
                        p++;
1593
0
                        ptr++;
1594
0
                    }
1595
0
                }
1596
0
            }
1597
0
            pattern++;
1598
0
            DISPATCH;
1599
1600
0
        TARGET(SRE_OP_GROUPREF_EXISTS):
1601
0
            TRACE(("|%p|%p|GROUPREF_EXISTS %d\n", pattern,
1602
0
                   ptr, pattern[0]));
1603
            /* <GROUPREF_EXISTS> <group> <skip> codeyes <JUMP> codeno ... */
1604
0
            {
1605
0
                int groupref = pattern[0] * 2;
1606
0
                if (groupref >= state->lastmark) {
1607
0
                    pattern += pattern[1];
1608
0
                    DISPATCH;
1609
0
                } else {
1610
0
                    SRE_CHAR* p = (SRE_CHAR*) state->mark[groupref];
1611
0
                    SRE_CHAR* e = (SRE_CHAR*) state->mark[groupref+1];
1612
0
                    if (!p || !e || e < p) {
1613
0
                        pattern += pattern[1];
1614
0
                        DISPATCH;
1615
0
                    }
1616
0
                }
1617
0
            }
1618
0
            pattern += 2;
1619
0
            DISPATCH;
1620
1621
0
        TARGET(SRE_OP_ASSERT):
1622
            /* assert subpattern */
1623
            /* <ASSERT> <skip> <back> <pattern> */
1624
0
            TRACE(("|%p|%p|ASSERT %d\n", pattern,
1625
0
                   ptr, pattern[1]));
1626
0
            if ((uintptr_t)(ptr - (SRE_CHAR *)state->beginning) < pattern[1])
1627
0
                RETURN_FAILURE;
1628
0
            state->ptr = ptr - pattern[1];
1629
0
            DO_JUMP0(JUMP_ASSERT, jump_assert, pattern+2);
1630
0
            RETURN_ON_FAILURE(ret);
1631
0
            pattern += pattern[0];
1632
0
            DISPATCH;
1633
1634
0
        TARGET(SRE_OP_ASSERT_NOT):
1635
            /* assert not subpattern */
1636
            /* <ASSERT_NOT> <skip> <back> <pattern> */
1637
0
            TRACE(("|%p|%p|ASSERT_NOT %d\n", pattern,
1638
0
                   ptr, pattern[1]));
1639
0
            if ((uintptr_t)(ptr - (SRE_CHAR *)state->beginning) >= pattern[1]) {
1640
0
                state->ptr = ptr - pattern[1];
1641
0
                LASTMARK_SAVE();
1642
0
                if (state->save_marks)
1643
0
                    MARK_PUSH(ctx->lastmark);
1644
1645
0
                DO_JUMP0(JUMP_ASSERT_NOT, jump_assert_not, pattern+2);
1646
0
                if (ret) {
1647
0
                    if (state->save_marks)
1648
0
                        MARK_POP_DISCARD(ctx->lastmark);
1649
0
                    RETURN_ON_ERROR(ret);
1650
0
                    RETURN_FAILURE;
1651
0
                }
1652
0
                if (state->save_marks)
1653
0
                    MARK_POP(ctx->lastmark);
1654
0
                LASTMARK_RESTORE();
1655
0
            }
1656
0
            pattern += pattern[0];
1657
0
            DISPATCH;
1658
1659
0
        TARGET(SRE_OP_FAILURE):
1660
            /* immediate failure */
1661
0
            TRACE(("|%p|%p|FAILURE\n", pattern, ptr));
1662
0
            RETURN_FAILURE;
1663
1664
#if !USE_COMPUTED_GOTOS
1665
        default:
1666
#endif
1667
        // Also any unused opcodes:
1668
0
        TARGET(SRE_OP_RANGE_UNI_IGNORE):
1669
0
        TARGET(SRE_OP_SUBPATTERN):
1670
0
        TARGET(SRE_OP_RANGE):
1671
0
        TARGET(SRE_OP_NEGATE):
1672
0
        TARGET(SRE_OP_BIGCHARSET):
1673
0
        TARGET(SRE_OP_CHARSET):
1674
0
            TRACE(("|%p|%p|UNKNOWN %d\n", pattern, ptr,
1675
0
                   pattern[-1]));
1676
0
            RETURN_ERROR(SRE_ERROR_ILLEGAL);
1677
1678
0
    }
1679
1680
3.26k
exit:
1681
3.26k
    ctx_pos = ctx->last_ctx_pos;
1682
3.26k
    jump = ctx->jump;
1683
3.26k
    DATA_POP_DISCARD(ctx);
1684
3.26k
    if (ctx_pos == -1) {
1685
1.65k
        state->sigcount = sigcount;
1686
1.65k
        return ret;
1687
1.65k
    }
1688
1.60k
    DATA_LOOKUP_AT(SRE(match_context), ctx, ctx_pos);
1689
1690
1.60k
    switch (jump) {
1691
0
        case JUMP_MAX_UNTIL_2:
1692
0
            TRACE(("|%p|%p|JUMP_MAX_UNTIL_2\n", pattern, ptr));
1693
0
            goto jump_max_until_2;
1694
0
        case JUMP_MAX_UNTIL_3:
1695
0
            TRACE(("|%p|%p|JUMP_MAX_UNTIL_3\n", pattern, ptr));
1696
0
            goto jump_max_until_3;
1697
0
        case JUMP_MIN_UNTIL_2:
1698
0
            TRACE(("|%p|%p|JUMP_MIN_UNTIL_2\n", pattern, ptr));
1699
0
            goto jump_min_until_2;
1700
0
        case JUMP_MIN_UNTIL_3:
1701
0
            TRACE(("|%p|%p|JUMP_MIN_UNTIL_3\n", pattern, ptr));
1702
0
            goto jump_min_until_3;
1703
0
        case JUMP_BRANCH:
1704
0
            TRACE(("|%p|%p|JUMP_BRANCH\n", pattern, ptr));
1705
0
            goto jump_branch;
1706
0
        case JUMP_MAX_UNTIL_1:
1707
0
            TRACE(("|%p|%p|JUMP_MAX_UNTIL_1\n", pattern, ptr));
1708
0
            goto jump_max_until_1;
1709
0
        case JUMP_MIN_UNTIL_1:
1710
0
            TRACE(("|%p|%p|JUMP_MIN_UNTIL_1\n", pattern, ptr));
1711
0
            goto jump_min_until_1;
1712
0
        case JUMP_POSS_REPEAT_1:
1713
0
            TRACE(("|%p|%p|JUMP_POSS_REPEAT_1\n", pattern, ptr));
1714
0
            goto jump_poss_repeat_1;
1715
0
        case JUMP_POSS_REPEAT_2:
1716
0
            TRACE(("|%p|%p|JUMP_POSS_REPEAT_2\n", pattern, ptr));
1717
0
            goto jump_poss_repeat_2;
1718
0
        case JUMP_REPEAT:
1719
0
            TRACE(("|%p|%p|JUMP_REPEAT\n", pattern, ptr));
1720
0
            goto jump_repeat;
1721
0
        case JUMP_REPEAT_ONE_1:
1722
0
            TRACE(("|%p|%p|JUMP_REPEAT_ONE_1\n", pattern, ptr));
1723
0
            goto jump_repeat_one_1;
1724
1.60k
        case JUMP_REPEAT_ONE_2:
1725
1.60k
            TRACE(("|%p|%p|JUMP_REPEAT_ONE_2\n", pattern, ptr));
1726
1.60k
            goto jump_repeat_one_2;
1727
0
        case JUMP_MIN_REPEAT_ONE:
1728
0
            TRACE(("|%p|%p|JUMP_MIN_REPEAT_ONE\n", pattern, ptr));
1729
0
            goto jump_min_repeat_one;
1730
0
        case JUMP_ATOMIC_GROUP:
1731
0
            TRACE(("|%p|%p|JUMP_ATOMIC_GROUP\n", pattern, ptr));
1732
0
            goto jump_atomic_group;
1733
0
        case JUMP_ASSERT:
1734
0
            TRACE(("|%p|%p|JUMP_ASSERT\n", pattern, ptr));
1735
0
            goto jump_assert;
1736
0
        case JUMP_ASSERT_NOT:
1737
0
            TRACE(("|%p|%p|JUMP_ASSERT_NOT\n", pattern, ptr));
1738
0
            goto jump_assert_not;
1739
0
        case JUMP_NONE:
1740
0
            TRACE(("|%p|%p|RETURN %zd\n", pattern,
1741
0
                   ptr, ret));
1742
0
            break;
1743
1.60k
    }
1744
1745
0
    return ret; /* should never get here */
1746
1.60k
}
sre.c:sre_ucs4_match
Line
Count
Source
663
2.16k
{
664
2.16k
    const SRE_CHAR* end = (const SRE_CHAR *)state->end;
665
2.16k
    Py_ssize_t alloc_pos, ctx_pos = -1;
666
2.16k
    Py_ssize_t ret = 0;
667
2.16k
    int jump;
668
2.16k
    unsigned int sigcount = state->sigcount;
669
670
2.16k
    SRE(match_context)* ctx;
671
2.16k
    SRE(match_context)* nextctx;
672
2.16k
    INIT_TRACE(state);
673
674
2.16k
    TRACE(("|%p|%p|ENTER\n", pattern, state->ptr));
675
676
2.16k
    DATA_ALLOC(SRE(match_context), ctx);
677
2.16k
    ctx->last_ctx_pos = -1;
678
2.16k
    ctx->jump = JUMP_NONE;
679
2.16k
    ctx->toplevel = toplevel;
680
2.16k
    ctx_pos = alloc_pos;
681
682
2.16k
#if USE_COMPUTED_GOTOS
683
2.16k
#include "sre_targets.h"
684
2.16k
#endif
685
686
4.28k
entrance:
687
688
4.28k
    ;  // Fashion statement.
689
4.28k
    const SRE_CHAR *ptr = (SRE_CHAR *)state->ptr;
690
691
4.28k
    if (pattern[0] == SRE_OP_INFO) {
692
        /* optimization info block */
693
        /* <INFO> <1=skip> <2=flags> <3=min> ... */
694
2.16k
        if (pattern[3] && (uintptr_t)(end - ptr) < pattern[3]) {
695
0
            TRACE(("reject (got %tu chars, need %zu)\n",
696
0
                   end - ptr, (size_t) pattern[3]));
697
0
            RETURN_FAILURE;
698
0
        }
699
2.16k
        pattern += pattern[1] + 1;
700
2.16k
    }
701
702
4.28k
#if USE_COMPUTED_GOTOS
703
4.28k
    DISPATCH;
704
#else
705
dispatch:
706
    MAYBE_CHECK_SIGNALS;
707
    switch (*pattern++)
708
#endif
709
4.28k
    {
710
711
4.28k
        TARGET(SRE_OP_MARK):
712
            /* set mark */
713
            /* <MARK> <gid> */
714
0
            TRACE(("|%p|%p|MARK %d\n", pattern,
715
0
                   ptr, pattern[0]));
716
0
            {
717
0
                int i = pattern[0];
718
0
                if (i & 1)
719
0
                    state->lastindex = i/2 + 1;
720
0
                if (i > state->lastmark) {
721
                    /* state->lastmark is the highest valid index in the
722
                       state->mark array.  If it is increased by more than 1,
723
                       the intervening marks must be set to NULL to signal
724
                       that these marks have not been encountered. */
725
0
                    int j = state->lastmark + 1;
726
0
                    while (j < i)
727
0
                        state->mark[j++] = NULL;
728
0
                    state->lastmark = i;
729
0
                }
730
0
                state->mark[i] = ptr;
731
0
            }
732
0
            pattern++;
733
0
            DISPATCH;
734
735
0
        TARGET(SRE_OP_LITERAL):
736
            /* match literal string */
737
            /* <LITERAL> <code> */
738
0
            TRACE(("|%p|%p|LITERAL %d\n", pattern,
739
0
                   ptr, *pattern));
740
0
            if (ptr >= end || (SRE_CODE) ptr[0] != pattern[0])
741
0
                RETURN_FAILURE;
742
0
            pattern++;
743
0
            ptr++;
744
0
            DISPATCH;
745
746
0
        TARGET(SRE_OP_NOT_LITERAL):
747
            /* match anything that is not literal character */
748
            /* <NOT_LITERAL> <code> */
749
0
            TRACE(("|%p|%p|NOT_LITERAL %d\n", pattern,
750
0
                   ptr, *pattern));
751
0
            if (ptr >= end || (SRE_CODE) ptr[0] == pattern[0])
752
0
                RETURN_FAILURE;
753
0
            pattern++;
754
0
            ptr++;
755
0
            DISPATCH;
756
757
2.11k
        TARGET(SRE_OP_SUCCESS):
758
            /* end of pattern */
759
2.11k
            TRACE(("|%p|%p|SUCCESS\n", pattern, ptr));
760
2.11k
            if (ctx->toplevel &&
761
2.11k
                ((state->match_all && ptr != state->end) ||
762
2.11k
                 (state->must_advance && ptr == state->start)))
763
0
            {
764
0
                RETURN_FAILURE;
765
0
            }
766
2.11k
            state->ptr = ptr;
767
2.11k
            RETURN_SUCCESS;
768
769
0
        TARGET(SRE_OP_AT):
770
            /* match at given position */
771
            /* <AT> <code> */
772
0
            TRACE(("|%p|%p|AT %d\n", pattern, ptr, *pattern));
773
0
            if (!SRE(at)(state, ptr, *pattern))
774
0
                RETURN_FAILURE;
775
0
            pattern++;
776
0
            DISPATCH;
777
778
0
        TARGET(SRE_OP_CATEGORY):
779
            /* match at given category */
780
            /* <CATEGORY> <code> */
781
0
            TRACE(("|%p|%p|CATEGORY %d\n", pattern,
782
0
                   ptr, *pattern));
783
0
            if (ptr >= end || !sre_category(pattern[0], ptr[0]))
784
0
                RETURN_FAILURE;
785
0
            pattern++;
786
0
            ptr++;
787
0
            DISPATCH;
788
789
0
        TARGET(SRE_OP_ANY):
790
            /* match anything (except a newline) */
791
            /* <ANY> */
792
0
            TRACE(("|%p|%p|ANY\n", pattern, ptr));
793
0
            if (ptr >= end || SRE_IS_LINEBREAK(ptr[0]))
794
0
                RETURN_FAILURE;
795
0
            ptr++;
796
0
            DISPATCH;
797
798
0
        TARGET(SRE_OP_ANY_ALL):
799
            /* match anything */
800
            /* <ANY_ALL> */
801
0
            TRACE(("|%p|%p|ANY_ALL\n", pattern, ptr));
802
0
            if (ptr >= end)
803
0
                RETURN_FAILURE;
804
0
            ptr++;
805
0
            DISPATCH;
806
807
0
        TARGET(SRE_OP_IN):
808
            /* match set member (or non_member) */
809
            /* <IN> <skip> <set> */
810
0
            TRACE(("|%p|%p|IN\n", pattern, ptr));
811
0
            if (ptr >= end ||
812
0
                !SRE(charset)(state, pattern + 1, *ptr))
813
0
                RETURN_FAILURE;
814
0
            pattern += pattern[0];
815
0
            ptr++;
816
0
            DISPATCH;
817
818
0
        TARGET(SRE_OP_LITERAL_IGNORE):
819
0
            TRACE(("|%p|%p|LITERAL_IGNORE %d\n",
820
0
                   pattern, ptr, pattern[0]));
821
0
            if (ptr >= end ||
822
0
                sre_lower_ascii(*ptr) != *pattern)
823
0
                RETURN_FAILURE;
824
0
            pattern++;
825
0
            ptr++;
826
0
            DISPATCH;
827
828
0
        TARGET(SRE_OP_LITERAL_UNI_IGNORE):
829
0
            TRACE(("|%p|%p|LITERAL_UNI_IGNORE %d\n",
830
0
                   pattern, ptr, pattern[0]));
831
0
            if (ptr >= end ||
832
0
                sre_lower_unicode(*ptr) != *pattern)
833
0
                RETURN_FAILURE;
834
0
            pattern++;
835
0
            ptr++;
836
0
            DISPATCH;
837
838
0
        TARGET(SRE_OP_LITERAL_LOC_IGNORE):
839
0
            TRACE(("|%p|%p|LITERAL_LOC_IGNORE %d\n",
840
0
                   pattern, ptr, pattern[0]));
841
0
            if (ptr >= end
842
0
                || !char_loc_ignore(*pattern, *ptr))
843
0
                RETURN_FAILURE;
844
0
            pattern++;
845
0
            ptr++;
846
0
            DISPATCH;
847
848
0
        TARGET(SRE_OP_NOT_LITERAL_IGNORE):
849
0
            TRACE(("|%p|%p|NOT_LITERAL_IGNORE %d\n",
850
0
                   pattern, ptr, *pattern));
851
0
            if (ptr >= end ||
852
0
                sre_lower_ascii(*ptr) == *pattern)
853
0
                RETURN_FAILURE;
854
0
            pattern++;
855
0
            ptr++;
856
0
            DISPATCH;
857
858
0
        TARGET(SRE_OP_NOT_LITERAL_UNI_IGNORE):
859
0
            TRACE(("|%p|%p|NOT_LITERAL_UNI_IGNORE %d\n",
860
0
                   pattern, ptr, *pattern));
861
0
            if (ptr >= end ||
862
0
                sre_lower_unicode(*ptr) == *pattern)
863
0
                RETURN_FAILURE;
864
0
            pattern++;
865
0
            ptr++;
866
0
            DISPATCH;
867
868
0
        TARGET(SRE_OP_NOT_LITERAL_LOC_IGNORE):
869
0
            TRACE(("|%p|%p|NOT_LITERAL_LOC_IGNORE %d\n",
870
0
                   pattern, ptr, *pattern));
871
0
            if (ptr >= end
872
0
                || char_loc_ignore(*pattern, *ptr))
873
0
                RETURN_FAILURE;
874
0
            pattern++;
875
0
            ptr++;
876
0
            DISPATCH;
877
878
0
        TARGET(SRE_OP_IN_IGNORE):
879
0
            TRACE(("|%p|%p|IN_IGNORE\n", pattern, ptr));
880
0
            if (ptr >= end
881
0
                || !SRE(charset)(state, pattern+1,
882
0
                                 (SRE_CODE)sre_lower_ascii(*ptr)))
883
0
                RETURN_FAILURE;
884
0
            pattern += pattern[0];
885
0
            ptr++;
886
0
            DISPATCH;
887
888
0
        TARGET(SRE_OP_IN_UNI_IGNORE):
889
0
            TRACE(("|%p|%p|IN_UNI_IGNORE\n", pattern, ptr));
890
0
            if (ptr >= end
891
0
                || !SRE(charset)(state, pattern+1,
892
0
                                 (SRE_CODE)sre_lower_unicode(*ptr)))
893
0
                RETURN_FAILURE;
894
0
            pattern += pattern[0];
895
0
            ptr++;
896
0
            DISPATCH;
897
898
0
        TARGET(SRE_OP_IN_LOC_IGNORE):
899
0
            TRACE(("|%p|%p|IN_LOC_IGNORE\n", pattern, ptr));
900
0
            if (ptr >= end
901
0
                || !SRE(charset_loc_ignore)(state, pattern+1, *ptr))
902
0
                RETURN_FAILURE;
903
0
            pattern += pattern[0];
904
0
            ptr++;
905
0
            DISPATCH;
906
907
0
        TARGET(SRE_OP_JUMP):
908
0
        TARGET(SRE_OP_INFO):
909
            /* jump forward */
910
            /* <JUMP> <offset> */
911
0
            TRACE(("|%p|%p|JUMP %d\n", pattern,
912
0
                   ptr, pattern[0]));
913
0
            pattern += pattern[0];
914
0
            DISPATCH;
915
916
0
        TARGET(SRE_OP_BRANCH):
917
            /* alternation */
918
            /* <BRANCH> <0=skip> code <JUMP> ... <NULL> */
919
0
            TRACE(("|%p|%p|BRANCH\n", pattern, ptr));
920
0
            LASTMARK_SAVE();
921
0
            if (state->save_marks)
922
0
                MARK_PUSH(ctx->lastmark);
923
0
            for (; pattern[0]; pattern += pattern[0]) {
924
0
                if (pattern[1] == SRE_OP_LITERAL &&
925
0
                    (ptr >= end ||
926
0
                     (SRE_CODE) *ptr != pattern[2]))
927
0
                    continue;
928
0
                if (pattern[1] == SRE_OP_IN &&
929
0
                    (ptr >= end ||
930
0
                     !SRE(charset)(state, pattern + 3,
931
0
                                   (SRE_CODE) *ptr)))
932
0
                    continue;
933
0
                state->ptr = ptr;
934
0
                DO_JUMP(JUMP_BRANCH, jump_branch, pattern+1);
935
0
                if (ret) {
936
0
                    if (state->save_marks)
937
0
                        MARK_POP_DISCARD(ctx->lastmark);
938
0
                    RETURN_ON_ERROR(ret);
939
0
                    RETURN_SUCCESS;
940
0
                }
941
0
                if (state->save_marks)
942
0
                    MARK_POP_KEEP(ctx->lastmark);
943
0
                LASTMARK_RESTORE();
944
0
            }
945
0
            if (state->save_marks)
946
0
                MARK_POP_DISCARD(ctx->lastmark);
947
0
            RETURN_FAILURE;
948
949
2.16k
        TARGET(SRE_OP_REPEAT_ONE):
950
            /* match repeated sequence (maximizing regexp) */
951
952
            /* this operator only works if the repeated item is
953
               exactly one character wide, and we're not already
954
               collecting backtracking points.  for other cases,
955
               use the MAX_REPEAT operator */
956
957
            /* <REPEAT_ONE> <skip> <1=min> <2=max> item <SUCCESS> tail */
958
959
2.16k
            TRACE(("|%p|%p|REPEAT_ONE %d %d\n", pattern, ptr,
960
2.16k
                   pattern[1], pattern[2]));
961
962
2.16k
            if ((Py_ssize_t) pattern[1] > end - ptr)
963
0
                RETURN_FAILURE; /* cannot match */
964
965
2.16k
            state->ptr = ptr;
966
967
2.16k
            ret = SRE(count)(state, pattern+3, pattern[2]);
968
2.16k
            RETURN_ON_ERROR(ret);
969
2.16k
            DATA_LOOKUP_AT(SRE(match_context), ctx, ctx_pos);
970
2.16k
            ctx->count = ret;
971
2.16k
            ptr += ctx->count;
972
973
            /* when we arrive here, count contains the number of
974
               matches, and ptr points to the tail of the target
975
               string.  check if the rest of the pattern matches,
976
               and backtrack if not. */
977
978
2.16k
            if (ctx->count < (Py_ssize_t) pattern[1])
979
0
                RETURN_FAILURE;
980
981
2.16k
            if (pattern[pattern[0]] == SRE_OP_SUCCESS &&
982
2.16k
                ptr == state->end &&
983
47
                !(ctx->toplevel && state->must_advance && ptr == state->start))
984
47
            {
985
                /* tail is empty.  we're finished */
986
47
                state->ptr = ptr;
987
47
                RETURN_SUCCESS;
988
47
            }
989
990
2.11k
            LASTMARK_SAVE();
991
2.11k
            if (state->save_marks)
992
0
                MARK_PUSH(ctx->lastmark);
993
994
2.11k
            if (pattern[pattern[0]] == SRE_OP_LITERAL) {
995
                /* tail starts with a literal. skip positions where
996
                   the rest of the pattern cannot possibly match */
997
0
                ctx->u.chr = pattern[pattern[0]+1];
998
0
                for (;;) {
999
0
                    while (ctx->count >= (Py_ssize_t) pattern[1] &&
1000
0
                           (ptr >= end || *ptr != ctx->u.chr)) {
1001
0
                        ptr--;
1002
0
                        ctx->count--;
1003
0
                    }
1004
0
                    if (ctx->count < (Py_ssize_t) pattern[1])
1005
0
                        break;
1006
0
                    state->ptr = ptr;
1007
0
                    DO_JUMP(JUMP_REPEAT_ONE_1, jump_repeat_one_1,
1008
0
                            pattern+pattern[0]);
1009
0
                    if (ret) {
1010
0
                        if (state->save_marks)
1011
0
                            MARK_POP_DISCARD(ctx->lastmark);
1012
0
                        RETURN_ON_ERROR(ret);
1013
0
                        RETURN_SUCCESS;
1014
0
                    }
1015
0
                    if (state->save_marks)
1016
0
                        MARK_POP_KEEP(ctx->lastmark);
1017
0
                    LASTMARK_RESTORE();
1018
1019
0
                    ptr--;
1020
0
                    ctx->count--;
1021
0
                }
1022
0
                if (state->save_marks)
1023
0
                    MARK_POP_DISCARD(ctx->lastmark);
1024
2.11k
            } else {
1025
                /* general case */
1026
2.11k
                while (ctx->count >= (Py_ssize_t) pattern[1]) {
1027
2.11k
                    state->ptr = ptr;
1028
2.11k
                    DO_JUMP(JUMP_REPEAT_ONE_2, jump_repeat_one_2,
1029
2.11k
                            pattern+pattern[0]);
1030
2.11k
                    if (ret) {
1031
2.11k
                        if (state->save_marks)
1032
0
                            MARK_POP_DISCARD(ctx->lastmark);
1033
2.11k
                        RETURN_ON_ERROR(ret);
1034
2.11k
                        RETURN_SUCCESS;
1035
2.11k
                    }
1036
0
                    if (state->save_marks)
1037
0
                        MARK_POP_KEEP(ctx->lastmark);
1038
0
                    LASTMARK_RESTORE();
1039
1040
0
                    ptr--;
1041
0
                    ctx->count--;
1042
0
                }
1043
0
                if (state->save_marks)
1044
0
                    MARK_POP_DISCARD(ctx->lastmark);
1045
0
            }
1046
0
            RETURN_FAILURE;
1047
1048
0
        TARGET(SRE_OP_MIN_REPEAT_ONE):
1049
            /* match repeated sequence (minimizing regexp) */
1050
1051
            /* this operator only works if the repeated item is
1052
               exactly one character wide, and we're not already
1053
               collecting backtracking points.  for other cases,
1054
               use the MIN_REPEAT operator */
1055
1056
            /* <MIN_REPEAT_ONE> <skip> <1=min> <2=max> item <SUCCESS> tail */
1057
1058
0
            TRACE(("|%p|%p|MIN_REPEAT_ONE %d %d\n", pattern, ptr,
1059
0
                   pattern[1], pattern[2]));
1060
1061
0
            if ((Py_ssize_t) pattern[1] > end - ptr)
1062
0
                RETURN_FAILURE; /* cannot match */
1063
1064
0
            state->ptr = ptr;
1065
1066
0
            if (pattern[1] == 0)
1067
0
                ctx->count = 0;
1068
0
            else {
1069
                /* count using pattern min as the maximum */
1070
0
                ret = SRE(count)(state, pattern+3, pattern[1]);
1071
0
                RETURN_ON_ERROR(ret);
1072
0
                DATA_LOOKUP_AT(SRE(match_context), ctx, ctx_pos);
1073
0
                if (ret < (Py_ssize_t) pattern[1])
1074
                    /* didn't match minimum number of times */
1075
0
                    RETURN_FAILURE;
1076
                /* advance past minimum matches of repeat */
1077
0
                ctx->count = ret;
1078
0
                ptr += ctx->count;
1079
0
            }
1080
1081
0
            if (pattern[pattern[0]] == SRE_OP_SUCCESS &&
1082
0
                !(ctx->toplevel &&
1083
0
                  ((state->match_all && ptr != state->end) ||
1084
0
                   (state->must_advance && ptr == state->start))))
1085
0
            {
1086
                /* tail is empty.  we're finished */
1087
0
                state->ptr = ptr;
1088
0
                RETURN_SUCCESS;
1089
1090
0
            } else {
1091
                /* general case */
1092
0
                LASTMARK_SAVE();
1093
0
                if (state->save_marks)
1094
0
                    MARK_PUSH(ctx->lastmark);
1095
1096
0
                while ((Py_ssize_t)pattern[2] == SRE_MAXREPEAT
1097
0
                       || ctx->count <= (Py_ssize_t)pattern[2]) {
1098
0
                    state->ptr = ptr;
1099
0
                    DO_JUMP(JUMP_MIN_REPEAT_ONE,jump_min_repeat_one,
1100
0
                            pattern+pattern[0]);
1101
0
                    if (ret) {
1102
0
                        if (state->save_marks)
1103
0
                            MARK_POP_DISCARD(ctx->lastmark);
1104
0
                        RETURN_ON_ERROR(ret);
1105
0
                        RETURN_SUCCESS;
1106
0
                    }
1107
0
                    if (state->save_marks)
1108
0
                        MARK_POP_KEEP(ctx->lastmark);
1109
0
                    LASTMARK_RESTORE();
1110
1111
0
                    state->ptr = ptr;
1112
0
                    ret = SRE(count)(state, pattern+3, 1);
1113
0
                    RETURN_ON_ERROR(ret);
1114
0
                    DATA_LOOKUP_AT(SRE(match_context), ctx, ctx_pos);
1115
0
                    if (ret == 0)
1116
0
                        break;
1117
0
                    assert(ret == 1);
1118
0
                    ptr++;
1119
0
                    ctx->count++;
1120
0
                }
1121
0
                if (state->save_marks)
1122
0
                    MARK_POP_DISCARD(ctx->lastmark);
1123
0
            }
1124
0
            RETURN_FAILURE;
1125
1126
0
        TARGET(SRE_OP_POSSESSIVE_REPEAT_ONE):
1127
            /* match repeated sequence (maximizing regexp) without
1128
               backtracking */
1129
1130
            /* this operator only works if the repeated item is
1131
               exactly one character wide, and we're not already
1132
               collecting backtracking points.  for other cases,
1133
               use the MAX_REPEAT operator */
1134
1135
            /* <POSSESSIVE_REPEAT_ONE> <skip> <1=min> <2=max> item <SUCCESS>
1136
               tail */
1137
1138
0
            TRACE(("|%p|%p|POSSESSIVE_REPEAT_ONE %d %d\n", pattern,
1139
0
                   ptr, pattern[1], pattern[2]));
1140
1141
0
            if (ptr + pattern[1] > end) {
1142
0
                RETURN_FAILURE; /* cannot match */
1143
0
            }
1144
1145
0
            state->ptr = ptr;
1146
1147
0
            ret = SRE(count)(state, pattern + 3, pattern[2]);
1148
0
            RETURN_ON_ERROR(ret);
1149
0
            DATA_LOOKUP_AT(SRE(match_context), ctx, ctx_pos);
1150
0
            ctx->count = ret;
1151
0
            ptr += ctx->count;
1152
1153
            /* when we arrive here, count contains the number of
1154
               matches, and ptr points to the tail of the target
1155
               string.  check if the rest of the pattern matches,
1156
               and fail if not. */
1157
1158
            /* Test for not enough repetitions in match */
1159
0
            if (ctx->count < (Py_ssize_t) pattern[1]) {
1160
0
                RETURN_FAILURE;
1161
0
            }
1162
1163
            /* Update the pattern to point to the next op code */
1164
0
            pattern += pattern[0];
1165
1166
            /* Let the tail be evaluated separately and consider this
1167
               match successful. */
1168
0
            if (*pattern == SRE_OP_SUCCESS &&
1169
0
                ptr == state->end &&
1170
0
                !(ctx->toplevel && state->must_advance && ptr == state->start))
1171
0
            {
1172
                /* tail is empty.  we're finished */
1173
0
                state->ptr = ptr;
1174
0
                RETURN_SUCCESS;
1175
0
            }
1176
1177
            /* Attempt to match the rest of the string */
1178
0
            DISPATCH;
1179
1180
0
        TARGET(SRE_OP_REPEAT):
1181
            /* create repeat context.  all the hard work is done
1182
               by the UNTIL operator (MAX_UNTIL, MIN_UNTIL) */
1183
            /* <REPEAT> <skip> <1=min> <2=max>
1184
               <3=repeat_index> item <UNTIL> tail */
1185
0
            TRACE(("|%p|%p|REPEAT %d %d\n", pattern, ptr,
1186
0
                   pattern[1], pattern[2]));
1187
1188
            /* install new repeat context */
1189
0
            ctx->u.rep = repeat_pool_malloc(state);
1190
0
            if (!ctx->u.rep) {
1191
0
                RETURN_ERROR(SRE_ERROR_MEMORY);
1192
0
            }
1193
0
            ctx->u.rep->count = -1;
1194
0
            ctx->u.rep->pattern = pattern;
1195
0
            ctx->u.rep->prev = state->repeat;
1196
0
            ctx->u.rep->last_ptr = NULL;
1197
0
            state->repeat = ctx->u.rep;
1198
0
            state->save_marks++;
1199
1200
0
            state->ptr = ptr;
1201
0
            DO_JUMP(JUMP_REPEAT, jump_repeat, pattern+pattern[0]);
1202
0
            state->repeat = ctx->u.rep->prev;
1203
0
            state->save_marks--;
1204
0
            repeat_pool_free(state, ctx->u.rep);
1205
1206
0
            if (ret) {
1207
0
                RETURN_ON_ERROR(ret);
1208
0
                RETURN_SUCCESS;
1209
0
            }
1210
0
            RETURN_FAILURE;
1211
1212
0
        TARGET(SRE_OP_MAX_UNTIL):
1213
            /* maximizing repeat */
1214
            /* <REPEAT> <skip> <1=min> <2=max> item <MAX_UNTIL> tail */
1215
1216
            /* FIXME: we probably need to deal with zero-width
1217
               matches in here... */
1218
1219
0
            ctx->u.rep = state->repeat;
1220
0
            if (!ctx->u.rep)
1221
0
                RETURN_ERROR(SRE_ERROR_STATE);
1222
1223
0
            state->ptr = ptr;
1224
1225
0
            ctx->count = ctx->u.rep->count+1;
1226
1227
0
            TRACE(("|%p|%p|MAX_UNTIL %zd\n", pattern,
1228
0
                   ptr, ctx->count));
1229
1230
0
            if (ctx->count < (Py_ssize_t) ctx->u.rep->pattern[1]) {
1231
                /* not enough matches */
1232
0
                ctx->u.rep->count = ctx->count;
1233
0
                DO_JUMP(JUMP_MAX_UNTIL_1, jump_max_until_1,
1234
0
                        ctx->u.rep->pattern+3);
1235
0
                if (ret) {
1236
0
                    RETURN_ON_ERROR(ret);
1237
0
                    RETURN_SUCCESS;
1238
0
                }
1239
0
                ctx->u.rep->count = ctx->count-1;
1240
0
                state->ptr = ptr;
1241
0
                RETURN_FAILURE;
1242
0
            }
1243
1244
0
            if ((ctx->count < (Py_ssize_t) ctx->u.rep->pattern[2] ||
1245
0
                ctx->u.rep->pattern[2] == SRE_MAXREPEAT) &&
1246
0
                state->ptr != ctx->u.rep->last_ptr) {
1247
                /* we may have enough matches, but if we can
1248
                   match another item, do so */
1249
0
                ctx->u.rep->count = ctx->count;
1250
0
                LASTMARK_SAVE();
1251
0
                MARK_PUSH(ctx->lastmark);
1252
                /* zero-width match protection */
1253
0
                LAST_PTR_PUSH();
1254
0
                ctx->u.rep->last_ptr = state->ptr;
1255
0
                DO_JUMP(JUMP_MAX_UNTIL_2, jump_max_until_2,
1256
0
                        ctx->u.rep->pattern+3);
1257
0
                LAST_PTR_POP();
1258
0
                if (ret) {
1259
0
                    MARK_POP_DISCARD(ctx->lastmark);
1260
0
                    RETURN_ON_ERROR(ret);
1261
0
                    RETURN_SUCCESS;
1262
0
                }
1263
0
                MARK_POP(ctx->lastmark);
1264
0
                LASTMARK_RESTORE();
1265
0
                ctx->u.rep->count = ctx->count-1;
1266
0
                state->ptr = ptr;
1267
0
            }
1268
1269
            /* cannot match more repeated items here.  make sure the
1270
               tail matches */
1271
0
            state->repeat = ctx->u.rep->prev;
1272
0
            state->save_marks--;
1273
0
            DO_JUMP(JUMP_MAX_UNTIL_3, jump_max_until_3, pattern);
1274
0
            state->repeat = ctx->u.rep; // restore repeat before return
1275
0
            state->save_marks++;
1276
1277
0
            RETURN_ON_SUCCESS(ret);
1278
0
            state->ptr = ptr;
1279
0
            RETURN_FAILURE;
1280
1281
0
        TARGET(SRE_OP_MIN_UNTIL):
1282
            /* minimizing repeat */
1283
            /* <REPEAT> <skip> <1=min> <2=max> item <MIN_UNTIL> tail */
1284
1285
0
            ctx->u.rep = state->repeat;
1286
0
            if (!ctx->u.rep)
1287
0
                RETURN_ERROR(SRE_ERROR_STATE);
1288
1289
0
            state->ptr = ptr;
1290
1291
0
            ctx->count = ctx->u.rep->count+1;
1292
1293
0
            TRACE(("|%p|%p|MIN_UNTIL %zd %p\n", pattern,
1294
0
                   ptr, ctx->count, ctx->u.rep->pattern));
1295
1296
0
            if (ctx->count < (Py_ssize_t) ctx->u.rep->pattern[1]) {
1297
                /* not enough matches */
1298
0
                ctx->u.rep->count = ctx->count;
1299
0
                DO_JUMP(JUMP_MIN_UNTIL_1, jump_min_until_1,
1300
0
                        ctx->u.rep->pattern+3);
1301
0
                if (ret) {
1302
0
                    RETURN_ON_ERROR(ret);
1303
0
                    RETURN_SUCCESS;
1304
0
                }
1305
0
                ctx->u.rep->count = ctx->count-1;
1306
0
                state->ptr = ptr;
1307
0
                RETURN_FAILURE;
1308
0
            }
1309
1310
            /* see if the tail matches */
1311
0
            state->repeat = ctx->u.rep->prev;
1312
0
            state->save_marks--;
1313
1314
0
            LASTMARK_SAVE();
1315
0
            if (state->save_marks)
1316
0
                MARK_PUSH(ctx->lastmark);
1317
1318
0
            DO_JUMP(JUMP_MIN_UNTIL_2, jump_min_until_2, pattern);
1319
            /* save_marks is balanced across the jump, so this equals the
1320
               value tested for MARK_PUSH above */
1321
0
            int pushed = state->save_marks != 0;
1322
0
            state->repeat = ctx->u.rep; // restore repeat before return
1323
0
            state->save_marks++;
1324
1325
0
            if (ret) {
1326
0
                if (pushed)
1327
0
                    MARK_POP_DISCARD(ctx->lastmark);
1328
0
                RETURN_ON_ERROR(ret);
1329
0
                RETURN_SUCCESS;
1330
0
            }
1331
0
            if (pushed)
1332
0
                MARK_POP(ctx->lastmark);
1333
0
            LASTMARK_RESTORE();
1334
1335
0
            state->ptr = ptr;
1336
1337
0
            if ((ctx->count >= (Py_ssize_t) ctx->u.rep->pattern[2]
1338
0
                && ctx->u.rep->pattern[2] != SRE_MAXREPEAT) ||
1339
0
                state->ptr == ctx->u.rep->last_ptr)
1340
0
                RETURN_FAILURE;
1341
1342
0
            ctx->u.rep->count = ctx->count;
1343
            /* zero-width match protection */
1344
0
            LAST_PTR_PUSH();
1345
0
            ctx->u.rep->last_ptr = state->ptr;
1346
0
            DO_JUMP(JUMP_MIN_UNTIL_3,jump_min_until_3,
1347
0
                    ctx->u.rep->pattern+3);
1348
0
            LAST_PTR_POP();
1349
0
            if (ret) {
1350
0
                RETURN_ON_ERROR(ret);
1351
0
                RETURN_SUCCESS;
1352
0
            }
1353
0
            ctx->u.rep->count = ctx->count-1;
1354
0
            state->ptr = ptr;
1355
0
            RETURN_FAILURE;
1356
1357
0
        TARGET(SRE_OP_POSSESSIVE_REPEAT):
1358
            /* create possessive repeat contexts. */
1359
            /* <POSSESSIVE_REPEAT> <skip> <1=min> <2=max> pattern
1360
               <SUCCESS> tail */
1361
0
            TRACE(("|%p|%p|POSSESSIVE_REPEAT %d %d\n", pattern,
1362
0
                   ptr, pattern[1], pattern[2]));
1363
1364
            /* Set the global Input pointer to this context's Input
1365
               pointer */
1366
0
            state->ptr = ptr;
1367
1368
            /* Capture groups in the body can be revisited on backtracking
1369
               between iterations, so their marks must be saved and restored,
1370
               as is done inside a repeat. */
1371
0
            state->save_marks++;
1372
1373
            /* Initialize Count to 0 */
1374
0
            ctx->count = 0;
1375
1376
            /* Check for minimum required matches. */
1377
0
            while (ctx->count < (Py_ssize_t)pattern[1]) {
1378
                /* not enough matches */
1379
0
                DO_JUMP0(JUMP_POSS_REPEAT_1, jump_poss_repeat_1,
1380
0
                         &pattern[3]);
1381
0
                if (ret) {
1382
0
                    RETURN_ON_ERROR(ret);
1383
0
                    ctx->count++;
1384
0
                }
1385
0
                else {
1386
0
                    state->ptr = ptr;
1387
0
                    state->save_marks--;
1388
0
                    RETURN_FAILURE;
1389
0
                }
1390
0
            }
1391
1392
            /* Clear the context's Input stream pointer so that it
1393
               doesn't match the global state so that the while loop can
1394
               be entered. */
1395
0
            ptr = NULL;
1396
1397
            /* Keep trying to parse the <pattern> sub-pattern until the
1398
               end is reached, creating a new context each time. */
1399
0
            while ((ctx->count < (Py_ssize_t)pattern[2] ||
1400
0
                    (Py_ssize_t)pattern[2] == SRE_MAXREPEAT) &&
1401
0
                   state->ptr != ptr) {
1402
                /* Save the Capture Group Marker state into the current
1403
                   Context and back up the current highest number
1404
                   Capture Group marker. */
1405
0
                LASTMARK_SAVE();
1406
0
                MARK_PUSH(ctx->lastmark);
1407
1408
                /* zero-width match protection */
1409
                /* Set the context's Input Stream pointer to be the
1410
                   current Input Stream pointer from the global
1411
                   state.  When the loop reaches the next iteration,
1412
                   the context will then store the last known good
1413
                   position with the global state holding the Input
1414
                   Input Stream position that has been updated with
1415
                   the most recent match.  Thus, if state's Input
1416
                   stream remains the same as the one stored in the
1417
                   current Context, we know we have successfully
1418
                   matched an empty string and that all subsequent
1419
                   matches will also be the empty string until the
1420
                   maximum number of matches are counted, and because
1421
                   of this, we could immediately stop at that point and
1422
                   consider this match successful. */
1423
0
                ptr = state->ptr;
1424
1425
                /* We have not reached the maximin matches, so try to
1426
                   match once more. */
1427
0
                DO_JUMP0(JUMP_POSS_REPEAT_2, jump_poss_repeat_2,
1428
0
                         &pattern[3]);
1429
1430
                /* Check to see if the last attempted match
1431
                   succeeded. */
1432
0
                if (ret) {
1433
                    /* Drop the saved highest number Capture Group
1434
                       marker saved above and use the newly updated
1435
                       value. */
1436
0
                    MARK_POP_DISCARD(ctx->lastmark);
1437
0
                    RETURN_ON_ERROR(ret);
1438
1439
                    /* Success, increment the count. */
1440
0
                    ctx->count++;
1441
0
                }
1442
                /* Last attempted match failed. */
1443
0
                else {
1444
                    /* Restore the previously saved highest number
1445
                       Capture Group marker since the last iteration
1446
                       did not match, then restore that to the global
1447
                       state. */
1448
0
                    MARK_POP(ctx->lastmark);
1449
0
                    LASTMARK_RESTORE();
1450
1451
                    /* Restore the global Input Stream pointer
1452
                       since it can change after jumps. */
1453
0
                    state->ptr = ptr;
1454
1455
                    /* We have sufficient matches, so exit loop. */
1456
0
                    break;
1457
0
                }
1458
0
            }
1459
1460
0
            state->save_marks--;
1461
1462
            /* Evaluate Tail */
1463
            /* Jump to end of pattern indicated by skip, and then skip
1464
               the SUCCESS op code that follows it. */
1465
0
            pattern += pattern[0] + 1;
1466
0
            ptr = state->ptr;
1467
0
            DISPATCH;
1468
1469
0
        TARGET(SRE_OP_ATOMIC_GROUP):
1470
            /* Atomic Group Sub Pattern */
1471
            /* <ATOMIC_GROUP> <skip> pattern <SUCCESS> tail */
1472
0
            TRACE(("|%p|%p|ATOMIC_GROUP\n", pattern, ptr));
1473
1474
            /* Set the global Input pointer to this context's Input
1475
               pointer */
1476
0
            state->ptr = ptr;
1477
1478
            /* Evaluate the Atomic Group in a new context, terminating
1479
               when the end of the group, represented by a SUCCESS op
1480
               code, is reached. */
1481
            /* Group Pattern begins at an offset of 1 code. */
1482
0
            DO_JUMP0(JUMP_ATOMIC_GROUP, jump_atomic_group,
1483
0
                     &pattern[1]);
1484
1485
            /* Test Exit Condition */
1486
0
            RETURN_ON_ERROR(ret);
1487
1488
0
            if (ret == 0) {
1489
                /* Atomic Group failed to Match. */
1490
0
                state->ptr = ptr;
1491
0
                RETURN_FAILURE;
1492
0
            }
1493
1494
            /* Evaluate Tail */
1495
            /* Jump to end of pattern indicated by skip, and then skip
1496
               the SUCCESS op code that follows it. */
1497
0
            pattern += pattern[0];
1498
0
            ptr = state->ptr;
1499
0
            DISPATCH;
1500
1501
0
        TARGET(SRE_OP_GROUPREF):
1502
            /* match backreference */
1503
0
            TRACE(("|%p|%p|GROUPREF %d\n", pattern,
1504
0
                   ptr, pattern[0]));
1505
0
            {
1506
0
                int groupref = pattern[0] * 2;
1507
0
                if (groupref >= state->lastmark) {
1508
0
                    RETURN_FAILURE;
1509
0
                } else {
1510
0
                    SRE_CHAR* p = (SRE_CHAR*) state->mark[groupref];
1511
0
                    SRE_CHAR* e = (SRE_CHAR*) state->mark[groupref+1];
1512
0
                    if (!p || !e || e < p)
1513
0
                        RETURN_FAILURE;
1514
0
                    while (p < e) {
1515
0
                        if (ptr >= end || *ptr != *p)
1516
0
                            RETURN_FAILURE;
1517
0
                        p++;
1518
0
                        ptr++;
1519
0
                    }
1520
0
                }
1521
0
            }
1522
0
            pattern++;
1523
0
            DISPATCH;
1524
1525
0
        TARGET(SRE_OP_GROUPREF_IGNORE):
1526
            /* match backreference */
1527
0
            TRACE(("|%p|%p|GROUPREF_IGNORE %d\n", pattern,
1528
0
                   ptr, pattern[0]));
1529
0
            {
1530
0
                int groupref = pattern[0] * 2;
1531
0
                if (groupref >= state->lastmark) {
1532
0
                    RETURN_FAILURE;
1533
0
                } else {
1534
0
                    SRE_CHAR* p = (SRE_CHAR*) state->mark[groupref];
1535
0
                    SRE_CHAR* e = (SRE_CHAR*) state->mark[groupref+1];
1536
0
                    if (!p || !e || e < p)
1537
0
                        RETURN_FAILURE;
1538
0
                    while (p < e) {
1539
0
                        if (ptr >= end ||
1540
0
                            sre_lower_ascii(*ptr) != sre_lower_ascii(*p))
1541
0
                            RETURN_FAILURE;
1542
0
                        p++;
1543
0
                        ptr++;
1544
0
                    }
1545
0
                }
1546
0
            }
1547
0
            pattern++;
1548
0
            DISPATCH;
1549
1550
0
        TARGET(SRE_OP_GROUPREF_UNI_IGNORE):
1551
            /* match backreference */
1552
0
            TRACE(("|%p|%p|GROUPREF_UNI_IGNORE %d\n", pattern,
1553
0
                   ptr, pattern[0]));
1554
0
            {
1555
0
                int groupref = pattern[0] * 2;
1556
0
                if (groupref >= state->lastmark) {
1557
0
                    RETURN_FAILURE;
1558
0
                } else {
1559
0
                    SRE_CHAR* p = (SRE_CHAR*) state->mark[groupref];
1560
0
                    SRE_CHAR* e = (SRE_CHAR*) state->mark[groupref+1];
1561
0
                    if (!p || !e || e < p)
1562
0
                        RETURN_FAILURE;
1563
0
                    while (p < e) {
1564
0
                        if (ptr >= end ||
1565
0
                            sre_lower_unicode(*ptr) != sre_lower_unicode(*p))
1566
0
                            RETURN_FAILURE;
1567
0
                        p++;
1568
0
                        ptr++;
1569
0
                    }
1570
0
                }
1571
0
            }
1572
0
            pattern++;
1573
0
            DISPATCH;
1574
1575
0
        TARGET(SRE_OP_GROUPREF_LOC_IGNORE):
1576
            /* match backreference */
1577
0
            TRACE(("|%p|%p|GROUPREF_LOC_IGNORE %d\n", pattern,
1578
0
                   ptr, pattern[0]));
1579
0
            {
1580
0
                int groupref = pattern[0] * 2;
1581
0
                if (groupref >= state->lastmark) {
1582
0
                    RETURN_FAILURE;
1583
0
                } else {
1584
0
                    SRE_CHAR* p = (SRE_CHAR*) state->mark[groupref];
1585
0
                    SRE_CHAR* e = (SRE_CHAR*) state->mark[groupref+1];
1586
0
                    if (!p || !e || e < p)
1587
0
                        RETURN_FAILURE;
1588
0
                    while (p < e) {
1589
0
                        if (ptr >= end ||
1590
0
                            sre_lower_locale(*ptr) != sre_lower_locale(*p))
1591
0
                            RETURN_FAILURE;
1592
0
                        p++;
1593
0
                        ptr++;
1594
0
                    }
1595
0
                }
1596
0
            }
1597
0
            pattern++;
1598
0
            DISPATCH;
1599
1600
0
        TARGET(SRE_OP_GROUPREF_EXISTS):
1601
0
            TRACE(("|%p|%p|GROUPREF_EXISTS %d\n", pattern,
1602
0
                   ptr, pattern[0]));
1603
            /* <GROUPREF_EXISTS> <group> <skip> codeyes <JUMP> codeno ... */
1604
0
            {
1605
0
                int groupref = pattern[0] * 2;
1606
0
                if (groupref >= state->lastmark) {
1607
0
                    pattern += pattern[1];
1608
0
                    DISPATCH;
1609
0
                } else {
1610
0
                    SRE_CHAR* p = (SRE_CHAR*) state->mark[groupref];
1611
0
                    SRE_CHAR* e = (SRE_CHAR*) state->mark[groupref+1];
1612
0
                    if (!p || !e || e < p) {
1613
0
                        pattern += pattern[1];
1614
0
                        DISPATCH;
1615
0
                    }
1616
0
                }
1617
0
            }
1618
0
            pattern += 2;
1619
0
            DISPATCH;
1620
1621
0
        TARGET(SRE_OP_ASSERT):
1622
            /* assert subpattern */
1623
            /* <ASSERT> <skip> <back> <pattern> */
1624
0
            TRACE(("|%p|%p|ASSERT %d\n", pattern,
1625
0
                   ptr, pattern[1]));
1626
0
            if ((uintptr_t)(ptr - (SRE_CHAR *)state->beginning) < pattern[1])
1627
0
                RETURN_FAILURE;
1628
0
            state->ptr = ptr - pattern[1];
1629
0
            DO_JUMP0(JUMP_ASSERT, jump_assert, pattern+2);
1630
0
            RETURN_ON_FAILURE(ret);
1631
0
            pattern += pattern[0];
1632
0
            DISPATCH;
1633
1634
0
        TARGET(SRE_OP_ASSERT_NOT):
1635
            /* assert not subpattern */
1636
            /* <ASSERT_NOT> <skip> <back> <pattern> */
1637
0
            TRACE(("|%p|%p|ASSERT_NOT %d\n", pattern,
1638
0
                   ptr, pattern[1]));
1639
0
            if ((uintptr_t)(ptr - (SRE_CHAR *)state->beginning) >= pattern[1]) {
1640
0
                state->ptr = ptr - pattern[1];
1641
0
                LASTMARK_SAVE();
1642
0
                if (state->save_marks)
1643
0
                    MARK_PUSH(ctx->lastmark);
1644
1645
0
                DO_JUMP0(JUMP_ASSERT_NOT, jump_assert_not, pattern+2);
1646
0
                if (ret) {
1647
0
                    if (state->save_marks)
1648
0
                        MARK_POP_DISCARD(ctx->lastmark);
1649
0
                    RETURN_ON_ERROR(ret);
1650
0
                    RETURN_FAILURE;
1651
0
                }
1652
0
                if (state->save_marks)
1653
0
                    MARK_POP(ctx->lastmark);
1654
0
                LASTMARK_RESTORE();
1655
0
            }
1656
0
            pattern += pattern[0];
1657
0
            DISPATCH;
1658
1659
0
        TARGET(SRE_OP_FAILURE):
1660
            /* immediate failure */
1661
0
            TRACE(("|%p|%p|FAILURE\n", pattern, ptr));
1662
0
            RETURN_FAILURE;
1663
1664
#if !USE_COMPUTED_GOTOS
1665
        default:
1666
#endif
1667
        // Also any unused opcodes:
1668
0
        TARGET(SRE_OP_RANGE_UNI_IGNORE):
1669
0
        TARGET(SRE_OP_SUBPATTERN):
1670
0
        TARGET(SRE_OP_RANGE):
1671
0
        TARGET(SRE_OP_NEGATE):
1672
0
        TARGET(SRE_OP_BIGCHARSET):
1673
0
        TARGET(SRE_OP_CHARSET):
1674
0
            TRACE(("|%p|%p|UNKNOWN %d\n", pattern, ptr,
1675
0
                   pattern[-1]));
1676
0
            RETURN_ERROR(SRE_ERROR_ILLEGAL);
1677
1678
0
    }
1679
1680
4.28k
exit:
1681
4.28k
    ctx_pos = ctx->last_ctx_pos;
1682
4.28k
    jump = ctx->jump;
1683
4.28k
    DATA_POP_DISCARD(ctx);
1684
4.28k
    if (ctx_pos == -1) {
1685
2.16k
        state->sigcount = sigcount;
1686
2.16k
        return ret;
1687
2.16k
    }
1688
2.11k
    DATA_LOOKUP_AT(SRE(match_context), ctx, ctx_pos);
1689
1690
2.11k
    switch (jump) {
1691
0
        case JUMP_MAX_UNTIL_2:
1692
0
            TRACE(("|%p|%p|JUMP_MAX_UNTIL_2\n", pattern, ptr));
1693
0
            goto jump_max_until_2;
1694
0
        case JUMP_MAX_UNTIL_3:
1695
0
            TRACE(("|%p|%p|JUMP_MAX_UNTIL_3\n", pattern, ptr));
1696
0
            goto jump_max_until_3;
1697
0
        case JUMP_MIN_UNTIL_2:
1698
0
            TRACE(("|%p|%p|JUMP_MIN_UNTIL_2\n", pattern, ptr));
1699
0
            goto jump_min_until_2;
1700
0
        case JUMP_MIN_UNTIL_3:
1701
0
            TRACE(("|%p|%p|JUMP_MIN_UNTIL_3\n", pattern, ptr));
1702
0
            goto jump_min_until_3;
1703
0
        case JUMP_BRANCH:
1704
0
            TRACE(("|%p|%p|JUMP_BRANCH\n", pattern, ptr));
1705
0
            goto jump_branch;
1706
0
        case JUMP_MAX_UNTIL_1:
1707
0
            TRACE(("|%p|%p|JUMP_MAX_UNTIL_1\n", pattern, ptr));
1708
0
            goto jump_max_until_1;
1709
0
        case JUMP_MIN_UNTIL_1:
1710
0
            TRACE(("|%p|%p|JUMP_MIN_UNTIL_1\n", pattern, ptr));
1711
0
            goto jump_min_until_1;
1712
0
        case JUMP_POSS_REPEAT_1:
1713
0
            TRACE(("|%p|%p|JUMP_POSS_REPEAT_1\n", pattern, ptr));
1714
0
            goto jump_poss_repeat_1;
1715
0
        case JUMP_POSS_REPEAT_2:
1716
0
            TRACE(("|%p|%p|JUMP_POSS_REPEAT_2\n", pattern, ptr));
1717
0
            goto jump_poss_repeat_2;
1718
0
        case JUMP_REPEAT:
1719
0
            TRACE(("|%p|%p|JUMP_REPEAT\n", pattern, ptr));
1720
0
            goto jump_repeat;
1721
0
        case JUMP_REPEAT_ONE_1:
1722
0
            TRACE(("|%p|%p|JUMP_REPEAT_ONE_1\n", pattern, ptr));
1723
0
            goto jump_repeat_one_1;
1724
2.11k
        case JUMP_REPEAT_ONE_2:
1725
2.11k
            TRACE(("|%p|%p|JUMP_REPEAT_ONE_2\n", pattern, ptr));
1726
2.11k
            goto jump_repeat_one_2;
1727
0
        case JUMP_MIN_REPEAT_ONE:
1728
0
            TRACE(("|%p|%p|JUMP_MIN_REPEAT_ONE\n", pattern, ptr));
1729
0
            goto jump_min_repeat_one;
1730
0
        case JUMP_ATOMIC_GROUP:
1731
0
            TRACE(("|%p|%p|JUMP_ATOMIC_GROUP\n", pattern, ptr));
1732
0
            goto jump_atomic_group;
1733
0
        case JUMP_ASSERT:
1734
0
            TRACE(("|%p|%p|JUMP_ASSERT\n", pattern, ptr));
1735
0
            goto jump_assert;
1736
0
        case JUMP_ASSERT_NOT:
1737
0
            TRACE(("|%p|%p|JUMP_ASSERT_NOT\n", pattern, ptr));
1738
0
            goto jump_assert_not;
1739
0
        case JUMP_NONE:
1740
0
            TRACE(("|%p|%p|RETURN %zd\n", pattern,
1741
0
                   ptr, ret));
1742
0
            break;
1743
2.11k
    }
1744
1745
0
    return ret; /* should never get here */
1746
2.11k
}
1747
1748
/* need to reset capturing groups between two SRE(match) callings in loops */
1749
#define RESET_CAPTURE_GROUP() \
1750
0
    do { state->lastmark = state->lastindex = -1; } while (0)
1751
1752
LOCAL(Py_ssize_t)
1753
SRE(search)(SRE_STATE* state, SRE_CODE* pattern)
1754
0
{
1755
0
    SRE_CHAR* ptr = (SRE_CHAR *)state->start;
1756
0
    SRE_CHAR* end = (SRE_CHAR *)state->end;
1757
0
    Py_ssize_t status = 0;
1758
0
    Py_ssize_t prefix_len = 0;
1759
0
    Py_ssize_t prefix_skip = 0;
1760
0
    SRE_CODE* prefix = NULL;
1761
0
    SRE_CODE* charset = NULL;
1762
0
    SRE_CODE* overlap = NULL;
1763
0
    int flags = 0;
1764
0
    INIT_TRACE(state);
1765
1766
0
    if (ptr > end)
1767
0
        return 0;
1768
1769
0
    if (pattern[0] == SRE_OP_INFO) {
1770
        /* optimization info block */
1771
        /* <INFO> <1=skip> <2=flags> <3=min> <4=max> <5=prefix info>  */
1772
1773
0
        flags = pattern[2];
1774
1775
0
        if (pattern[3] && (uintptr_t)(end - ptr) < pattern[3]) {
1776
0
            TRACE(("reject (got %tu chars, need %zu)\n",
1777
0
                   end - ptr, (size_t) pattern[3]));
1778
0
            return 0;
1779
0
        }
1780
0
        if (pattern[3] > 1) {
1781
            /* adjust end point (but make sure we leave at least one
1782
               character in there, so literal search will work) */
1783
0
            end -= pattern[3] - 1;
1784
0
            if (end <= ptr)
1785
0
                end = ptr;
1786
0
        }
1787
1788
0
        if (flags & SRE_INFO_PREFIX) {
1789
            /* pattern starts with a known prefix */
1790
            /* <length> <skip> <prefix data> <overlap data> */
1791
0
            prefix_len = pattern[5];
1792
0
            prefix_skip = pattern[6];
1793
0
            prefix = pattern + 7;
1794
0
            overlap = prefix + prefix_len - 1;
1795
0
        } else if (flags & SRE_INFO_CHARSET)
1796
            /* pattern starts with a character from a known set */
1797
            /* <charset> */
1798
0
            charset = pattern + 5;
1799
1800
0
        pattern += 1 + pattern[1];
1801
0
    }
1802
1803
0
    TRACE(("prefix = %p %zd %zd\n",
1804
0
           prefix, prefix_len, prefix_skip));
1805
0
    TRACE(("charset = %p\n", charset));
1806
1807
0
    if (prefix_len == 1) {
1808
        /* pattern starts with a literal character */
1809
0
        SRE_CHAR c = (SRE_CHAR) prefix[0];
1810
#if SIZEOF_SRE_CHAR < 4
1811
0
        if ((SRE_CODE) c != prefix[0])
1812
0
            return 0; /* literal can't match: doesn't fit in char width */
1813
0
#endif
1814
0
        end = (SRE_CHAR *)state->end;
1815
0
        state->must_advance = 0;
1816
0
        while (ptr < end) {
1817
0
            while (*ptr != c) {
1818
0
                if (++ptr >= end)
1819
0
                    return 0;
1820
0
            }
1821
0
            TRACE(("|%p|%p|SEARCH LITERAL\n", pattern, ptr));
1822
0
            state->start = ptr;
1823
0
            state->ptr = ptr + prefix_skip;
1824
0
            if (flags & SRE_INFO_LITERAL)
1825
0
                return 1; /* we got all of it */
1826
0
            status = SRE(match)(state, pattern + 2*prefix_skip, 0);
1827
0
            if (status != 0)
1828
0
                return status;
1829
0
            ++ptr;
1830
0
            RESET_CAPTURE_GROUP();
1831
0
        }
1832
0
        return 0;
1833
0
    }
1834
1835
0
    if (prefix_len > 1) {
1836
        /* pattern starts with a known prefix.  use the overlap
1837
           table to skip forward as fast as we possibly can */
1838
0
        Py_ssize_t i = 0;
1839
1840
0
        end = (SRE_CHAR *)state->end;
1841
0
        if (prefix_len > end - ptr)
1842
0
            return 0;
1843
#if SIZEOF_SRE_CHAR < 4
1844
0
        for (i = 0; i < prefix_len; i++)
1845
0
            if ((SRE_CODE)(SRE_CHAR) prefix[i] != prefix[i])
1846
0
                return 0; /* literal can't match: doesn't fit in char width */
1847
0
#endif
1848
0
        while (ptr < end) {
1849
0
            SRE_CHAR c = (SRE_CHAR) prefix[0];
1850
0
            while (*ptr++ != c) {
1851
0
                if (ptr >= end)
1852
0
                    return 0;
1853
0
            }
1854
0
            if (ptr >= end)
1855
0
                return 0;
1856
1857
0
            i = 1;
1858
0
            state->must_advance = 0;
1859
0
            do {
1860
0
                if (*ptr == (SRE_CHAR) prefix[i]) {
1861
0
                    if (++i != prefix_len) {
1862
0
                        if (++ptr >= end)
1863
0
                            return 0;
1864
0
                        continue;
1865
0
                    }
1866
                    /* found a potential match */
1867
0
                    TRACE(("|%p|%p|SEARCH SCAN\n", pattern, ptr));
1868
0
                    state->start = ptr - (prefix_len - 1);
1869
0
                    state->ptr = ptr - (prefix_len - prefix_skip - 1);
1870
0
                    if (flags & SRE_INFO_LITERAL)
1871
0
                        return 1; /* we got all of it */
1872
0
                    status = SRE(match)(state, pattern + 2*prefix_skip, 0);
1873
0
                    if (status != 0)
1874
0
                        return status;
1875
                    /* close but no cigar -- try again */
1876
0
                    if (++ptr >= end)
1877
0
                        return 0;
1878
0
                    RESET_CAPTURE_GROUP();
1879
0
                }
1880
0
                i = overlap[i];
1881
0
            } while (i != 0);
1882
0
        }
1883
0
        return 0;
1884
0
    }
1885
1886
0
    if (charset) {
1887
        /* pattern starts with a character from a known set */
1888
0
        end = (SRE_CHAR *)state->end;
1889
0
        state->must_advance = 0;
1890
0
        for (;;) {
1891
0
            while (ptr < end && !SRE(charset)(state, charset, *ptr))
1892
0
                ptr++;
1893
0
            if (ptr >= end)
1894
0
                return 0;
1895
0
            TRACE(("|%p|%p|SEARCH CHARSET\n", pattern, ptr));
1896
0
            state->start = ptr;
1897
0
            state->ptr = ptr;
1898
0
            status = SRE(match)(state, pattern, 0);
1899
0
            if (status != 0)
1900
0
                break;
1901
0
            ptr++;
1902
0
            RESET_CAPTURE_GROUP();
1903
0
        }
1904
0
    } else {
1905
        /* general case */
1906
0
        assert(ptr <= end);
1907
0
        TRACE(("|%p|%p|SEARCH\n", pattern, ptr));
1908
0
        state->start = state->ptr = ptr;
1909
0
        status = SRE(match)(state, pattern, 1);
1910
0
        state->must_advance = 0;
1911
0
        if (status == 0 && pattern[0] == SRE_OP_AT &&
1912
0
            (pattern[1] == SRE_AT_BEGINNING ||
1913
0
             pattern[1] == SRE_AT_BEGINNING_STRING))
1914
0
        {
1915
0
            state->start = state->ptr = ptr = end;
1916
0
            return 0;
1917
0
        }
1918
0
        while (status == 0 && ptr < end) {
1919
0
            ptr++;
1920
0
            RESET_CAPTURE_GROUP();
1921
0
            TRACE(("|%p|%p|SEARCH\n", pattern, ptr));
1922
0
            state->start = state->ptr = ptr;
1923
0
            status = SRE(match)(state, pattern, 0);
1924
0
        }
1925
0
    }
1926
1927
0
    return status;
1928
0
}
Unexecuted instantiation: sre.c:sre_ucs1_search
Unexecuted instantiation: sre.c:sre_ucs2_search
Unexecuted instantiation: sre.c:sre_ucs4_search
1929
1930
#undef SRE_CHAR
1931
#undef SIZEOF_SRE_CHAR
1932
#undef SRE
1933
1934
/* vim:ts=4:sw=4:et
1935
*/