Coverage Report

Created: 2026-10-31 06:21

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/cpython/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
23.6M
{
18
    /* check if pointer is at given position */
19
20
23.6M
    Py_ssize_t thisp, thatp;
21
22
23.6M
    switch (at) {
23
24
12.0M
    case SRE_AT_BEGINNING:
25
12.0M
    case SRE_AT_BEGINNING_STRING:
26
12.0M
        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
8.67M
    case SRE_AT_END:
33
8.67M
        return (((SRE_CHAR *)state->end - ptr == 1 &&
34
23.2k
                 SRE_IS_LINEBREAK((int) ptr[0])) ||
35
8.67M
                ((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
2.98M
    case SRE_AT_END_STRING:
42
2.98M
        return ((void*) ptr == state->end);
43
44
0
    case SRE_AT_BOUNDARY:
45
0
        thatp = ((void*) ptr > state->beginning) ?
46
0
            SRE_IS_WORD((int) ptr[-1]) : 0;
47
0
        thisp = ((void*) ptr < state->end) ?
48
0
            SRE_IS_WORD((int) ptr[0]) : 0;
49
0
        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
23.6M
    }
87
88
0
    return 0;
89
23.6M
}
sre.c:sre_ucs1_at
Line
Count
Source
17
18.8M
{
18
    /* check if pointer is at given position */
19
20
18.8M
    Py_ssize_t thisp, thatp;
21
22
18.8M
    switch (at) {
23
24
10.2M
    case SRE_AT_BEGINNING:
25
10.2M
    case SRE_AT_BEGINNING_STRING:
26
10.2M
        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
6.95M
    case SRE_AT_END:
33
6.95M
        return (((SRE_CHAR *)state->end - ptr == 1 &&
34
23.0k
                 SRE_IS_LINEBREAK((int) ptr[0])) ||
35
6.95M
                ((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
1.68M
    case SRE_AT_END_STRING:
42
1.68M
        return ((void*) ptr == state->end);
43
44
0
    case SRE_AT_BOUNDARY:
45
0
        thatp = ((void*) ptr > state->beginning) ?
46
0
            SRE_IS_WORD((int) ptr[-1]) : 0;
47
0
        thisp = ((void*) ptr < state->end) ?
48
0
            SRE_IS_WORD((int) ptr[0]) : 0;
49
0
        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
18.8M
    }
87
88
0
    return 0;
89
18.8M
}
sre.c:sre_ucs2_at
Line
Count
Source
17
4.25M
{
18
    /* check if pointer is at given position */
19
20
4.25M
    Py_ssize_t thisp, thatp;
21
22
4.25M
    switch (at) {
23
24
1.75M
    case SRE_AT_BEGINNING:
25
1.75M
    case SRE_AT_BEGINNING_STRING:
26
1.75M
        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
1.66M
    case SRE_AT_END:
33
1.66M
        return (((SRE_CHAR *)state->end - ptr == 1 &&
34
122
                 SRE_IS_LINEBREAK((int) ptr[0])) ||
35
1.66M
                ((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
829k
    case SRE_AT_END_STRING:
42
829k
        return ((void*) ptr == state->end);
43
44
0
    case SRE_AT_BOUNDARY:
45
0
        thatp = ((void*) ptr > state->beginning) ?
46
0
            SRE_IS_WORD((int) ptr[-1]) : 0;
47
0
        thisp = ((void*) ptr < state->end) ?
48
0
            SRE_IS_WORD((int) ptr[0]) : 0;
49
0
        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
4.25M
    }
87
88
0
    return 0;
89
4.25M
}
sre.c:sre_ucs4_at
Line
Count
Source
17
543k
{
18
    /* check if pointer is at given position */
19
20
543k
    Py_ssize_t thisp, thatp;
21
22
543k
    switch (at) {
23
24
20.9k
    case SRE_AT_BEGINNING:
25
20.9k
    case SRE_AT_BEGINNING_STRING:
26
20.9k
        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
48.5k
    case SRE_AT_END:
33
48.5k
        return (((SRE_CHAR *)state->end - ptr == 1 &&
34
102
                 SRE_IS_LINEBREAK((int) ptr[0])) ||
35
48.5k
                ((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
473k
    case SRE_AT_END_STRING:
42
473k
        return ((void*) ptr == state->end);
43
44
0
    case SRE_AT_BOUNDARY:
45
0
        thatp = ((void*) ptr > state->beginning) ?
46
0
            SRE_IS_WORD((int) ptr[-1]) : 0;
47
0
        thisp = ((void*) ptr < state->end) ?
48
0
            SRE_IS_WORD((int) ptr[0]) : 0;
49
0
        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
543k
    }
87
88
0
    return 0;
89
543k
}
90
91
LOCAL(int)
92
SRE(charset)(SRE_STATE* state, const SRE_CODE* set, SRE_CODE ch)
93
1.07G
{
94
    /* check if character is a member of the given set */
95
96
1.07G
    int ok = 1;
97
98
2.56G
    for (;;) {
99
2.56G
        switch (*set++) {
100
101
745M
        case SRE_OP_FAILURE:
102
745M
            return !ok;
103
104
1.15G
        case SRE_OP_LITERAL:
105
            /* <LITERAL> <code> */
106
1.15G
            if (ch == set[0])
107
16.9M
                return ok;
108
1.13G
            set++;
109
1.13G
            break;
110
111
8.37M
        case SRE_OP_CATEGORY:
112
            /* <CATEGORY> <code> */
113
8.37M
            if (sre_category(set[0], (int) ch))
114
5.33M
                return ok;
115
3.04M
            set++;
116
3.04M
            break;
117
118
127M
        case SRE_OP_CHARSET:
119
            /* <CHARSET> <bitmap> */
120
127M
            if (ch < 256 &&
121
121M
                (set[ch/SRE_CODE_BITS] & (1u << (ch & (SRE_CODE_BITS-1)))))
122
23.5M
                return ok;
123
103M
            set += 256/SRE_CODE_BITS;
124
103M
            break;
125
126
423M
        case SRE_OP_RANGE:
127
            /* <RANGE> <lower> <upper> */
128
423M
            if (set[0] <= ch && ch <= set[1])
129
282M
                return ok;
130
140M
            set += 2;
131
140M
            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
106M
        case SRE_OP_NEGATE:
148
106M
            ok = !ok;
149
106M
            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.56G
        }
175
2.56G
    }
176
1.07G
}
sre.c:sre_ucs1_charset
Line
Count
Source
93
344M
{
94
    /* check if character is a member of the given set */
95
96
344M
    int ok = 1;
97
98
696M
    for (;;) {
99
696M
        switch (*set++) {
100
101
179M
        case SRE_OP_FAILURE:
102
179M
            return !ok;
103
104
213M
        case SRE_OP_LITERAL:
105
            /* <LITERAL> <code> */
106
213M
            if (ch == set[0])
107
11.9M
                return ok;
108
201M
            set++;
109
201M
            break;
110
111
5.54M
        case SRE_OP_CATEGORY:
112
            /* <CATEGORY> <code> */
113
5.54M
            if (sre_category(set[0], (int) ch))
114
3.59M
                return ok;
115
1.95M
            set++;
116
1.95M
            break;
117
118
45.9M
        case SRE_OP_CHARSET:
119
            /* <CHARSET> <bitmap> */
120
45.9M
            if (ch < 256 &&
121
45.9M
                (set[ch/SRE_CODE_BITS] & (1u << (ch & (SRE_CODE_BITS-1)))))
122
9.49M
                return ok;
123
36.4M
            set += 256/SRE_CODE_BITS;
124
36.4M
            break;
125
126
215M
        case SRE_OP_RANGE:
127
            /* <RANGE> <lower> <upper> */
128
215M
            if (set[0] <= ch && ch <= set[1])
129
140M
                return ok;
130
75.1M
            set += 2;
131
75.1M
            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
36.8M
        case SRE_OP_NEGATE:
148
36.8M
            ok = !ok;
149
36.8M
            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
696M
        }
175
696M
    }
176
344M
}
sre.c:sre_ucs2_charset
Line
Count
Source
93
574M
{
94
    /* check if character is a member of the given set */
95
96
574M
    int ok = 1;
97
98
1.46G
    for (;;) {
99
1.46G
        switch (*set++) {
100
101
444M
        case SRE_OP_FAILURE:
102
444M
            return !ok;
103
104
729M
        case SRE_OP_LITERAL:
105
            /* <LITERAL> <code> */
106
729M
            if (ch == set[0])
107
4.40M
                return ok;
108
725M
            set++;
109
725M
            break;
110
111
2.50M
        case SRE_OP_CATEGORY:
112
            /* <CATEGORY> <code> */
113
2.50M
            if (sre_category(set[0], (int) ch))
114
1.71M
                return ok;
115
785k
            set++;
116
785k
            break;
117
118
61.6M
        case SRE_OP_CHARSET:
119
            /* <CHARSET> <bitmap> */
120
61.6M
            if (ch < 256 &&
121
57.2M
                (set[ch/SRE_CODE_BITS] & (1u << (ch & (SRE_CODE_BITS-1)))))
122
7.89M
                return ok;
123
53.7M
            set += 256/SRE_CODE_BITS;
124
53.7M
            break;
125
126
173M
        case SRE_OP_RANGE:
127
            /* <RANGE> <lower> <upper> */
128
173M
            if (set[0] <= ch && ch <= set[1])
129
115M
                return ok;
130
58.1M
            set += 2;
131
58.1M
            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
55.7M
        case SRE_OP_NEGATE:
148
55.7M
            ok = !ok;
149
55.7M
            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
1.46G
        }
175
1.46G
    }
176
574M
}
sre.c:sre_ucs4_charset
Line
Count
Source
93
154M
{
94
    /* check if character is a member of the given set */
95
96
154M
    int ok = 1;
97
98
400M
    for (;;) {
99
400M
        switch (*set++) {
100
101
121M
        case SRE_OP_FAILURE:
102
121M
            return !ok;
103
104
211M
        case SRE_OP_LITERAL:
105
            /* <LITERAL> <code> */
106
211M
            if (ch == set[0])
107
655k
                return ok;
108
211M
            set++;
109
211M
            break;
110
111
326k
        case SRE_OP_CATEGORY:
112
            /* <CATEGORY> <code> */
113
326k
            if (sre_category(set[0], (int) ch))
114
16.2k
                return ok;
115
310k
            set++;
116
310k
            break;
117
118
19.4M
        case SRE_OP_CHARSET:
119
            /* <CHARSET> <bitmap> */
120
19.4M
            if (ch < 256 &&
121
18.6M
                (set[ch/SRE_CODE_BITS] & (1u << (ch & (SRE_CODE_BITS-1)))))
122
6.17M
                return ok;
123
13.2M
            set += 256/SRE_CODE_BITS;
124
13.2M
            break;
125
126
33.6M
        case SRE_OP_RANGE:
127
            /* <RANGE> <lower> <upper> */
128
33.6M
            if (set[0] <= ch && ch <= set[1])
129
26.4M
                return ok;
130
7.23M
            set += 2;
131
7.23M
            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
13.5M
        case SRE_OP_NEGATE:
148
13.5M
            ok = !ok;
149
13.5M
            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
400M
        }
175
400M
    }
176
154M
}
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
309M
{
250
309M
    SRE_CODE chr;
251
309M
    SRE_CODE arg;
252
309M
    SRE_CHAR c;
253
309M
    const SRE_CHAR* ptr = (const SRE_CHAR *)state->ptr;
254
309M
    const SRE_CHAR* end = (const SRE_CHAR *)state->end;
255
309M
    Py_ssize_t i;
256
309M
    INIT_TRACE(state);
257
258
    /* adjust end */
259
309M
    if (maxcount < end - ptr && maxcount != SRE_MAXREPEAT)
260
55.1M
        end = ptr + maxcount;
261
262
309M
    switch (pattern[0]) {
263
264
235M
    case SRE_OP_IN:
265
        /* repeated set */
266
235M
        TRACE(("|%p|%p|COUNT IN\n", pattern, ptr));
267
414M
        while (ptr < end && SRE(charset)(state, pattern + 2, *ptr))
268
179M
            ptr++;
269
235M
        break;
270
271
3.46M
    case SRE_OP_ANY:
272
        /* repeated dot wildcard. */
273
3.46M
        TRACE(("|%p|%p|COUNT ANY\n", pattern, ptr));
274
34.7M
        while (ptr < end && !SRE_IS_LINEBREAK(*ptr))
275
31.2M
            ptr++;
276
3.46M
        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
59.4M
    case SRE_OP_LITERAL:
286
        /* repeated literal */
287
59.4M
        chr = pattern[1];
288
59.4M
        TRACE(("|%p|%p|COUNT LITERAL %d\n", pattern, ptr, chr));
289
59.4M
        c = (SRE_CHAR) chr;
290
#if SIZEOF_SRE_CHAR < 4
291
46.5M
        if ((SRE_CODE) c != chr)
292
0
            ; /* literal can't match: doesn't fit in char width */
293
46.5M
        else
294
46.5M
#endif
295
59.7M
        while (ptr < end && *ptr == c)
296
303k
            ptr++;
297
59.4M
        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
8
    case SRE_OP_NOT_LITERAL:
324
        /* repeated non-literal */
325
8
        chr = pattern[1];
326
8
        TRACE(("|%p|%p|COUNT NOT_LITERAL %d\n", pattern, ptr, chr));
327
8
        c = (SRE_CHAR) chr;
328
#if SIZEOF_SRE_CHAR < 4
329
8
        if ((SRE_CODE) c != chr)
330
0
            ptr = end; /* literal can't match: doesn't fit in char width */
331
8
        else
332
8
#endif
333
420
        while (ptr < end && *ptr != c)
334
412
            ptr++;
335
8
        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
11.6M
    case SRE_OP_CATEGORY:
362
11.6M
        arg = pattern[1];
363
11.6M
        TRACE(("|%p|%p|COUNT CATEGORY %d\n", pattern, ptr, arg));
364
20.3M
        while (ptr < end && sre_category(arg, *ptr))
365
8.62M
            ptr++;
366
11.6M
        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
309M
    }
382
383
309M
    TRACE(("|%p|%p|COUNT %zd\n", pattern, ptr,
384
309M
           ptr - (SRE_CHAR*) state->ptr));
385
309M
    return ptr - (SRE_CHAR*) state->ptr;
386
309M
}
sre.c:sre_ucs1_count
Line
Count
Source
249
103M
{
250
103M
    SRE_CODE chr;
251
103M
    SRE_CODE arg;
252
103M
    SRE_CHAR c;
253
103M
    const SRE_CHAR* ptr = (const SRE_CHAR *)state->ptr;
254
103M
    const SRE_CHAR* end = (const SRE_CHAR *)state->end;
255
103M
    Py_ssize_t i;
256
103M
    INIT_TRACE(state);
257
258
    /* adjust end */
259
103M
    if (maxcount < end - ptr && maxcount != SRE_MAXREPEAT)
260
26.7M
        end = ptr + maxcount;
261
262
103M
    switch (pattern[0]) {
263
264
59.2M
    case SRE_OP_IN:
265
        /* repeated set */
266
59.2M
        TRACE(("|%p|%p|COUNT IN\n", pattern, ptr));
267
151M
        while (ptr < end && SRE(charset)(state, pattern + 2, *ptr))
268
92.2M
            ptr++;
269
59.2M
        break;
270
271
3.17M
    case SRE_OP_ANY:
272
        /* repeated dot wildcard. */
273
3.17M
        TRACE(("|%p|%p|COUNT ANY\n", pattern, ptr));
274
9.74M
        while (ptr < end && !SRE_IS_LINEBREAK(*ptr))
275
6.56M
            ptr++;
276
3.17M
        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
31.0M
    case SRE_OP_LITERAL:
286
        /* repeated literal */
287
31.0M
        chr = pattern[1];
288
31.0M
        TRACE(("|%p|%p|COUNT LITERAL %d\n", pattern, ptr, chr));
289
31.0M
        c = (SRE_CHAR) chr;
290
31.0M
#if SIZEOF_SRE_CHAR < 4
291
31.0M
        if ((SRE_CODE) c != chr)
292
0
            ; /* literal can't match: doesn't fit in char width */
293
31.0M
        else
294
31.0M
#endif
295
31.3M
        while (ptr < end && *ptr == c)
296
246k
            ptr++;
297
31.0M
        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
8
    case SRE_OP_NOT_LITERAL:
324
        /* repeated non-literal */
325
8
        chr = pattern[1];
326
8
        TRACE(("|%p|%p|COUNT NOT_LITERAL %d\n", pattern, ptr, chr));
327
8
        c = (SRE_CHAR) chr;
328
8
#if SIZEOF_SRE_CHAR < 4
329
8
        if ((SRE_CODE) c != chr)
330
0
            ptr = end; /* literal can't match: doesn't fit in char width */
331
8
        else
332
8
#endif
333
420
        while (ptr < end && *ptr != c)
334
412
            ptr++;
335
8
        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
9.87M
    case SRE_OP_CATEGORY:
362
9.87M
        arg = pattern[1];
363
9.87M
        TRACE(("|%p|%p|COUNT CATEGORY %d\n", pattern, ptr, arg));
364
17.6M
        while (ptr < end && sre_category(arg, *ptr))
365
7.79M
            ptr++;
366
9.87M
        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
103M
    }
382
383
103M
    TRACE(("|%p|%p|COUNT %zd\n", pattern, ptr,
384
103M
           ptr - (SRE_CHAR*) state->ptr));
385
103M
    return ptr - (SRE_CHAR*) state->ptr;
386
103M
}
sre.c:sre_ucs2_count
Line
Count
Source
249
165M
{
250
165M
    SRE_CODE chr;
251
165M
    SRE_CODE arg;
252
165M
    SRE_CHAR c;
253
165M
    const SRE_CHAR* ptr = (const SRE_CHAR *)state->ptr;
254
165M
    const SRE_CHAR* end = (const SRE_CHAR *)state->end;
255
165M
    Py_ssize_t i;
256
165M
    INIT_TRACE(state);
257
258
    /* adjust end */
259
165M
    if (maxcount < end - ptr && maxcount != SRE_MAXREPEAT)
260
15.4M
        end = ptr + maxcount;
261
262
165M
    switch (pattern[0]) {
263
264
147M
    case SRE_OP_IN:
265
        /* repeated set */
266
147M
        TRACE(("|%p|%p|COUNT IN\n", pattern, ptr));
267
212M
        while (ptr < end && SRE(charset)(state, pattern + 2, *ptr))
268
64.9M
            ptr++;
269
147M
        break;
270
271
271k
    case SRE_OP_ANY:
272
        /* repeated dot wildcard. */
273
271k
        TRACE(("|%p|%p|COUNT ANY\n", pattern, ptr));
274
14.2M
        while (ptr < end && !SRE_IS_LINEBREAK(*ptr))
275
14.0M
            ptr++;
276
271k
        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
15.4M
    case SRE_OP_LITERAL:
286
        /* repeated literal */
287
15.4M
        chr = pattern[1];
288
15.4M
        TRACE(("|%p|%p|COUNT LITERAL %d\n", pattern, ptr, chr));
289
15.4M
        c = (SRE_CHAR) chr;
290
15.4M
#if SIZEOF_SRE_CHAR < 4
291
15.4M
        if ((SRE_CODE) c != chr)
292
0
            ; /* literal can't match: doesn't fit in char width */
293
15.4M
        else
294
15.4M
#endif
295
15.5M
        while (ptr < end && *ptr == c)
296
56.4k
            ptr++;
297
15.4M
        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.78M
    case SRE_OP_CATEGORY:
362
1.78M
        arg = pattern[1];
363
1.78M
        TRACE(("|%p|%p|COUNT CATEGORY %d\n", pattern, ptr, arg));
364
2.22M
        while (ptr < end && sre_category(arg, *ptr))
365
435k
            ptr++;
366
1.78M
        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
165M
    }
382
383
165M
    TRACE(("|%p|%p|COUNT %zd\n", pattern, ptr,
384
165M
           ptr - (SRE_CHAR*) state->ptr));
385
165M
    return ptr - (SRE_CHAR*) state->ptr;
386
165M
}
sre.c:sre_ucs4_count
Line
Count
Source
249
41.1M
{
250
41.1M
    SRE_CODE chr;
251
41.1M
    SRE_CODE arg;
252
41.1M
    SRE_CHAR c;
253
41.1M
    const SRE_CHAR* ptr = (const SRE_CHAR *)state->ptr;
254
41.1M
    const SRE_CHAR* end = (const SRE_CHAR *)state->end;
255
41.1M
    Py_ssize_t i;
256
41.1M
    INIT_TRACE(state);
257
258
    /* adjust end */
259
41.1M
    if (maxcount < end - ptr && maxcount != SRE_MAXREPEAT)
260
12.9M
        end = ptr + maxcount;
261
262
41.1M
    switch (pattern[0]) {
263
264
28.1M
    case SRE_OP_IN:
265
        /* repeated set */
266
28.1M
        TRACE(("|%p|%p|COUNT IN\n", pattern, ptr));
267
50.7M
        while (ptr < end && SRE(charset)(state, pattern + 2, *ptr))
268
22.5M
            ptr++;
269
28.1M
        break;
270
271
12.0k
    case SRE_OP_ANY:
272
        /* repeated dot wildcard. */
273
12.0k
        TRACE(("|%p|%p|COUNT ANY\n", pattern, ptr));
274
10.7M
        while (ptr < end && !SRE_IS_LINEBREAK(*ptr))
275
10.6M
            ptr++;
276
12.0k
        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
12.8M
    case SRE_OP_LITERAL:
286
        /* repeated literal */
287
12.8M
        chr = pattern[1];
288
12.8M
        TRACE(("|%p|%p|COUNT LITERAL %d\n", pattern, ptr, chr));
289
12.8M
        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
12.8M
        while (ptr < end && *ptr == c)
296
695
            ptr++;
297
12.8M
        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
22.1k
    case SRE_OP_CATEGORY:
362
22.1k
        arg = pattern[1];
363
22.1k
        TRACE(("|%p|%p|COUNT CATEGORY %d\n", pattern, ptr, arg));
364
408k
        while (ptr < end && sre_category(arg, *ptr))
365
386k
            ptr++;
366
22.1k
        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
41.1M
    }
382
383
41.1M
    TRACE(("|%p|%p|COUNT %zd\n", pattern, ptr,
384
41.1M
           ptr - (SRE_CHAR*) state->ptr));
385
41.1M
    return ptr - (SRE_CHAR*) state->ptr;
386
41.1M
}
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
420M
    do { \
418
420M
        ctx->lastmark = state->lastmark; \
419
420M
        ctx->lastindex = state->lastindex; \
420
420M
    } while (0)
421
#define LASTMARK_RESTORE()  \
422
191M
    do { \
423
191M
        state->lastmark = ctx->lastmark; \
424
191M
        state->lastindex = ctx->lastindex; \
425
191M
    } while (0)
426
427
#define LAST_PTR_PUSH()     \
428
180M
    do { \
429
180M
        TRACE(("push last_ptr: %zd", \
430
180M
                PTR_TO_INDEX(ctx->u.rep->last_ptr))); \
431
180M
        DATA_PUSH(&ctx->u.rep->last_ptr); \
432
180M
    } while (0)
433
#define LAST_PTR_POP()  \
434
180M
    do { \
435
180M
        DATA_POP(&ctx->u.rep->last_ptr); \
436
180M
        TRACE(("pop last_ptr: %zd", \
437
180M
                PTR_TO_INDEX(ctx->u.rep->last_ptr))); \
438
180M
    } while (0)
439
440
0
#define RETURN_ERROR(i) do { return i; } while(0)
441
448M
#define RETURN_FAILURE do { ret = 0; goto exit; } while(0)
442
448M
#define RETURN_SUCCESS do { ret = 1; goto exit; } while(0)
443
444
#define RETURN_ON_ERROR(i) \
445
631M
    do { if (i < 0) RETURN_ERROR(i); } while (0)
446
#define RETURN_ON_SUCCESS(i) \
447
25.7M
    do { RETURN_ON_ERROR(i); if (i > 0) RETURN_SUCCESS; } while (0)
448
#define RETURN_ON_FAILURE(i) \
449
12
    do { RETURN_ON_ERROR(i); if (i == 0) RETURN_FAILURE; } while (0)
450
451
896M
#define DATA_STACK_ALLOC(state, type, ptr) \
452
896M
do { \
453
896M
    alloc_pos = state->data_stack_base; \
454
896M
    TRACE(("allocating %s in %zd (%zd)\n", \
455
896M
           Py_STRINGIFY(type), alloc_pos, sizeof(type))); \
456
896M
    if (sizeof(type) > state->data_stack_size - alloc_pos) { \
457
152M
        int j = data_stack_grow(state, sizeof(type)); \
458
152M
        if (j < 0) return j; \
459
152M
        if (ctx_pos != -1) \
460
152M
            DATA_STACK_LOOKUP_AT(state, SRE(match_context), ctx, ctx_pos); \
461
152M
    } \
462
896M
    ptr = (type*)(state->data_stack+alloc_pos); \
463
896M
    state->data_stack_base += sizeof(type); \
464
896M
} while (0)
465
466
836M
#define DATA_STACK_LOOKUP_AT(state, type, ptr, pos) \
467
836M
do { \
468
836M
    TRACE(("looking up %s at %zd\n", Py_STRINGIFY(type), pos)); \
469
836M
    ptr = (type*)(state->data_stack+pos); \
470
836M
} while (0)
471
472
513M
#define DATA_STACK_PUSH(state, data, size) \
473
513M
do { \
474
513M
    TRACE(("copy data in %p to %zd (%zd)\n", \
475
513M
           data, state->data_stack_base, size)); \
476
513M
    if (size > state->data_stack_size - state->data_stack_base) { \
477
83.1k
        int j = data_stack_grow(state, size); \
478
83.1k
        if (j < 0) return j; \
479
83.1k
        if (ctx_pos != -1) \
480
83.1k
            DATA_STACK_LOOKUP_AT(state, SRE(match_context), ctx, ctx_pos); \
481
83.1k
    } \
482
513M
    memcpy(state->data_stack+state->data_stack_base, data, size); \
483
513M
    state->data_stack_base += size; \
484
513M
} 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
314M
#define DATA_STACK_POP(state, data, size, discard) \
490
314M
do { \
491
314M
    TRACE(("copy data to %p from %zd (%zd)\n", \
492
314M
           data, state->data_stack_base-size, size)); \
493
314M
    memcpy((void*) data, state->data_stack+state->data_stack_base-size, size); \
494
314M
    if (discard) \
495
314M
        state->data_stack_base -= size; \
496
314M
} while (0)
497
498
1.09G
#define DATA_STACK_POP_DISCARD(state, size) \
499
1.09G
do { \
500
1.09G
    TRACE(("discard data from %zd (%zd)\n", \
501
1.09G
           state->data_stack_base-size, size)); \
502
1.09G
    state->data_stack_base -= size; \
503
1.09G
} while(0)
504
505
#define DATA_PUSH(x) \
506
180M
    DATA_STACK_PUSH(state, (x), sizeof(*(x)))
507
#define DATA_POP(x) \
508
180M
    DATA_STACK_POP(state, (x), sizeof(*(x)), 1)
509
#define DATA_POP_DISCARD(x) \
510
896M
    DATA_STACK_POP_DISCARD(state, sizeof(*(x)))
511
#define DATA_ALLOC(t,p) \
512
896M
    DATA_STACK_ALLOC(state, t, p)
513
#define DATA_LOOKUP_AT(t,p,pos) \
514
833M
    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
365M
    do if (lastmark >= 0) { \
536
332M
        MARK_TRACE("push", (lastmark)); \
537
332M
        size_t _marks_size = (lastmark+1) * sizeof(void*); \
538
332M
        DATA_STACK_PUSH(state, state->mark, _marks_size); \
539
365M
    } while (0)
540
#define MARK_POP(lastmark) \
541
132M
    do if (lastmark >= 0) { \
542
131M
        size_t _marks_size = (lastmark+1) * sizeof(void*); \
543
131M
        DATA_STACK_POP(state, state->mark, _marks_size, 1); \
544
131M
        MARK_TRACE("pop", (lastmark)); \
545
132M
    } while (0)
546
#define MARK_POP_KEEP(lastmark) \
547
2.26M
    do if (lastmark >= 0) { \
548
1.24M
        size_t _marks_size = (lastmark+1) * sizeof(void*); \
549
1.24M
        DATA_STACK_POP(state, state->mark, _marks_size, 0); \
550
1.24M
        MARK_TRACE("pop keep", (lastmark)); \
551
2.26M
    } while (0)
552
#define MARK_POP_DISCARD(lastmark) \
553
232M
    do if (lastmark >= 0) { \
554
200M
        size_t _marks_size = (lastmark+1) * sizeof(void*); \
555
200M
        DATA_STACK_POP_DISCARD(state, _marks_size); \
556
200M
        MARK_TRACE("pop discard", (lastmark)); \
557
232M
    } while (0)
558
559
372M
#define JUMP_NONE            0
560
8.16M
#define JUMP_MAX_UNTIL_1     1
561
180M
#define JUMP_MAX_UNTIL_2     2
562
25.7M
#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
30.5M
#define JUMP_REPEAT          7
567
1.71M
#define JUMP_REPEAT_ONE_1    8
568
102M
#define JUMP_REPEAT_ONE_2    9
569
832
#define JUMP_MIN_REPEAT_ONE  10
570
54.1M
#define JUMP_BRANCH          11
571
12
#define JUMP_ASSERT          12
572
120M
#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
523M
    ctx->pattern = pattern; \
579
523M
    ctx->ptr = ptr; \
580
523M
    DATA_ALLOC(SRE(match_context), nextctx); \
581
523M
    nextctx->pattern = nextpattern; \
582
523M
    nextctx->toplevel = toplevel_; \
583
523M
    nextctx->jump = jumpvalue; \
584
523M
    nextctx->last_ctx_pos = ctx_pos; \
585
523M
    pattern = nextpattern; \
586
523M
    ctx_pos = alloc_pos; \
587
523M
    ctx = nextctx; \
588
523M
    goto entrance; \
589
523M
    jumplabel: \
590
523M
    pattern = ctx->pattern; \
591
523M
    ptr = ctx->ptr;
592
593
#define DO_JUMP(jumpvalue, jumplabel, nextpattern) \
594
403M
    DO_JUMPX(jumpvalue, jumplabel, nextpattern, ctx->toplevel)
595
596
#define DO_JUMP0(jumpvalue, jumplabel, nextpattern) \
597
120M
    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
1.66G
    do {                                                           \
616
1.66G
        if ((0 == (++sigcount & 0xfff)) && PyErr_CheckSignals()) { \
617
0
            RETURN_ERROR(SRE_ERROR_INTERRUPTED);                   \
618
0
        }                                                          \
619
1.66G
    } 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
1.66G
# 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
1.69G
    #define TARGET(OP) TARGET_ ## OP
649
    #define DISPATCH                       \
650
1.66G
        do {                               \
651
1.66G
            MAYBE_CHECK_SIGNALS;           \
652
1.66G
            goto *sre_targets[*pattern++]; \
653
1.66G
        } 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
372M
{
664
372M
    const SRE_CHAR* end = (const SRE_CHAR *)state->end;
665
372M
    Py_ssize_t alloc_pos, ctx_pos = -1;
666
372M
    Py_ssize_t ret = 0;
667
372M
    int jump;
668
372M
    unsigned int sigcount = state->sigcount;
669
670
372M
    SRE(match_context)* ctx;
671
372M
    SRE(match_context)* nextctx;
672
372M
    INIT_TRACE(state);
673
674
372M
    TRACE(("|%p|%p|ENTER\n", pattern, state->ptr));
675
676
372M
    DATA_ALLOC(SRE(match_context), ctx);
677
372M
    ctx->last_ctx_pos = -1;
678
372M
    ctx->jump = JUMP_NONE;
679
372M
    ctx->toplevel = toplevel;
680
372M
    ctx_pos = alloc_pos;
681
682
372M
#if USE_COMPUTED_GOTOS
683
372M
#include "sre_targets.h"
684
372M
#endif
685
686
896M
entrance:
687
688
896M
    ;  // Fashion statement.
689
896M
    const SRE_CHAR *ptr = (SRE_CHAR *)state->ptr;
690
691
896M
    if (pattern[0] == SRE_OP_INFO) {
692
        /* optimization info block */
693
        /* <INFO> <1=skip> <2=flags> <3=min> ... */
694
45.1M
        if (pattern[3] && (uintptr_t)(end - ptr) < pattern[3]) {
695
6.68M
            TRACE(("reject (got %tu chars, need %zu)\n",
696
6.68M
                   end - ptr, (size_t) pattern[3]));
697
6.68M
            RETURN_FAILURE;
698
6.68M
        }
699
38.4M
        pattern += pattern[1] + 1;
700
38.4M
    }
701
702
889M
#if USE_COMPUTED_GOTOS
703
889M
    DISPATCH;
704
#else
705
dispatch:
706
    MAYBE_CHECK_SIGNALS;
707
    switch (*pattern++)
708
#endif
709
889M
    {
710
711
889M
        TARGET(SRE_OP_MARK):
712
            /* set mark */
713
            /* <MARK> <gid> */
714
321M
            TRACE(("|%p|%p|MARK %d\n", pattern,
715
321M
                   ptr, pattern[0]));
716
321M
            {
717
321M
                int i = pattern[0];
718
321M
                if (i & 1)
719
52.0M
                    state->lastindex = i/2 + 1;
720
321M
                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
318M
                    int j = state->lastmark + 1;
726
332M
                    while (j < i)
727
13.9M
                        state->mark[j++] = NULL;
728
318M
                    state->lastmark = i;
729
318M
                }
730
321M
                state->mark[i] = ptr;
731
321M
            }
732
321M
            pattern++;
733
321M
            DISPATCH;
734
735
321M
        TARGET(SRE_OP_LITERAL):
736
            /* match literal string */
737
            /* <LITERAL> <code> */
738
89.2M
            TRACE(("|%p|%p|LITERAL %d\n", pattern,
739
89.2M
                   ptr, *pattern));
740
89.2M
            if (ptr >= end || (SRE_CODE) ptr[0] != pattern[0])
741
50.2M
                RETURN_FAILURE;
742
39.0M
            pattern++;
743
39.0M
            ptr++;
744
39.0M
            DISPATCH;
745
746
39.0M
        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
133M
        TARGET(SRE_OP_SUCCESS):
758
            /* end of pattern */
759
133M
            TRACE(("|%p|%p|SUCCESS\n", pattern, ptr));
760
133M
            if (ctx->toplevel &&
761
29.0M
                ((state->match_all && ptr != state->end) ||
762
29.0M
                 (state->must_advance && ptr == state->start)))
763
217
            {
764
217
                RETURN_FAILURE;
765
217
            }
766
133M
            state->ptr = ptr;
767
133M
            RETURN_SUCCESS;
768
769
23.6M
        TARGET(SRE_OP_AT):
770
            /* match at given position */
771
            /* <AT> <code> */
772
23.6M
            TRACE(("|%p|%p|AT %d\n", pattern, ptr, *pattern));
773
23.6M
            if (!SRE(at)(state, ptr, *pattern))
774
3.38M
                RETURN_FAILURE;
775
20.2M
            pattern++;
776
20.2M
            DISPATCH;
777
778
119M
        TARGET(SRE_OP_CATEGORY):
779
            /* match at given category */
780
            /* <CATEGORY> <code> */
781
119M
            TRACE(("|%p|%p|CATEGORY %d\n", pattern,
782
119M
                   ptr, *pattern));
783
119M
            if (ptr >= end || !sre_category(pattern[0], ptr[0]))
784
6.87M
                RETURN_FAILURE;
785
112M
            pattern++;
786
112M
            ptr++;
787
112M
            DISPATCH;
788
789
112M
        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
269M
        TARGET(SRE_OP_IN):
808
            /* match set member (or non_member) */
809
            /* <IN> <skip> <set> */
810
269M
            TRACE(("|%p|%p|IN\n", pattern, ptr));
811
269M
            if (ptr >= end ||
812
263M
                !SRE(charset)(state, pattern + 1, *ptr))
813
118M
                RETURN_FAILURE;
814
150M
            pattern += pattern[0];
815
150M
            ptr++;
816
150M
            DISPATCH;
817
818
150M
        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
21.4M
        TARGET(SRE_OP_JUMP):
908
21.4M
        TARGET(SRE_OP_INFO):
909
            /* jump forward */
910
            /* <JUMP> <offset> */
911
21.4M
            TRACE(("|%p|%p|JUMP %d\n", pattern,
912
21.4M
                   ptr, pattern[0]));
913
21.4M
            pattern += pattern[0];
914
21.4M
            DISPATCH;
915
916
34.3M
        TARGET(SRE_OP_BRANCH):
917
            /* alternation */
918
            /* <BRANCH> <0=skip> code <JUMP> ... <NULL> */
919
34.3M
            TRACE(("|%p|%p|BRANCH\n", pattern, ptr));
920
34.3M
            LASTMARK_SAVE();
921
34.3M
            if (state->save_marks)
922
38.0k
                MARK_PUSH(ctx->lastmark);
923
94.4M
            for (; pattern[0]; pattern += pattern[0]) {
924
78.3M
                if (pattern[1] == SRE_OP_LITERAL &&
925
55.7M
                    (ptr >= end ||
926
55.7M
                     (SRE_CODE) *ptr != pattern[2]))
927
22.5M
                    continue;
928
55.7M
                if (pattern[1] == SRE_OP_IN &&
929
3.15M
                    (ptr >= end ||
930
3.15M
                     !SRE(charset)(state, pattern + 3,
931
3.15M
                                   (SRE_CODE) *ptr)))
932
1.62M
                    continue;
933
54.1M
                state->ptr = ptr;
934
54.1M
                DO_JUMP(JUMP_BRANCH, jump_branch, pattern+1);
935
54.1M
                if (ret) {
936
18.3M
                    if (state->save_marks)
937
32.2k
                        MARK_POP_DISCARD(ctx->lastmark);
938
18.3M
                    RETURN_ON_ERROR(ret);
939
18.3M
                    RETURN_SUCCESS;
940
18.3M
                }
941
35.8M
                if (state->save_marks)
942
12.9k
                    MARK_POP_KEEP(ctx->lastmark);
943
35.8M
                LASTMARK_RESTORE();
944
35.8M
            }
945
16.0M
            if (state->save_marks)
946
5.84k
                MARK_POP_DISCARD(ctx->lastmark);
947
16.0M
            RETURN_FAILURE;
948
949
310M
        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
310M
            TRACE(("|%p|%p|REPEAT_ONE %d %d\n", pattern, ptr,
960
310M
                   pattern[1], pattern[2]));
961
962
310M
            if ((Py_ssize_t) pattern[1] > end - ptr)
963
900k
                RETURN_FAILURE; /* cannot match */
964
965
309M
            state->ptr = ptr;
966
967
309M
            ret = SRE(count)(state, pattern+3, pattern[2]);
968
309M
            RETURN_ON_ERROR(ret);
969
309M
            DATA_LOOKUP_AT(SRE(match_context), ctx, ctx_pos);
970
309M
            ctx->count = ret;
971
309M
            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
309M
            if (ctx->count < (Py_ssize_t) pattern[1])
979
224M
                RETURN_FAILURE;
980
981
84.7M
            if (pattern[pattern[0]] == SRE_OP_SUCCESS &&
982
2.90M
                ptr == state->end &&
983
102k
                !(ctx->toplevel && state->must_advance && ptr == state->start))
984
102k
            {
985
                /* tail is empty.  we're finished */
986
102k
                state->ptr = ptr;
987
102k
                RETURN_SUCCESS;
988
102k
            }
989
990
84.6M
            LASTMARK_SAVE();
991
84.6M
            if (state->save_marks)
992
64.1M
                MARK_PUSH(ctx->lastmark);
993
994
84.6M
            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
2.75M
                ctx->u.chr = pattern[pattern[0]+1];
998
2.75M
                for (;;) {
999
11.6M
                    while (ctx->count >= (Py_ssize_t) pattern[1] &&
1000
10.5M
                           (ptr >= end || *ptr != ctx->u.chr)) {
1001
8.88M
                        ptr--;
1002
8.88M
                        ctx->count--;
1003
8.88M
                    }
1004
2.75M
                    if (ctx->count < (Py_ssize_t) pattern[1])
1005
1.04M
                        break;
1006
1.71M
                    state->ptr = ptr;
1007
1.71M
                    DO_JUMP(JUMP_REPEAT_ONE_1, jump_repeat_one_1,
1008
1.71M
                            pattern+pattern[0]);
1009
1.71M
                    if (ret) {
1010
1.71M
                        if (state->save_marks)
1011
0
                            MARK_POP_DISCARD(ctx->lastmark);
1012
1.71M
                        RETURN_ON_ERROR(ret);
1013
1.71M
                        RETURN_SUCCESS;
1014
1.71M
                    }
1015
16
                    if (state->save_marks)
1016
0
                        MARK_POP_KEEP(ctx->lastmark);
1017
16
                    LASTMARK_RESTORE();
1018
1019
16
                    ptr--;
1020
16
                    ctx->count--;
1021
16
                }
1022
1.04M
                if (state->save_marks)
1023
32
                    MARK_POP_DISCARD(ctx->lastmark);
1024
81.9M
            } else {
1025
                /* general case */
1026
104M
                while (ctx->count >= (Py_ssize_t) pattern[1]) {
1027
102M
                    state->ptr = ptr;
1028
102M
                    DO_JUMP(JUMP_REPEAT_ONE_2, jump_repeat_one_2,
1029
102M
                            pattern+pattern[0]);
1030
102M
                    if (ret) {
1031
79.2M
                        if (state->save_marks)
1032
62.1M
                            MARK_POP_DISCARD(ctx->lastmark);
1033
79.2M
                        RETURN_ON_ERROR(ret);
1034
79.2M
                        RETURN_SUCCESS;
1035
79.2M
                    }
1036
22.7M
                    if (state->save_marks)
1037
2.24M
                        MARK_POP_KEEP(ctx->lastmark);
1038
22.7M
                    LASTMARK_RESTORE();
1039
1040
22.7M
                    ptr--;
1041
22.7M
                    ctx->count--;
1042
22.7M
                }
1043
2.67M
                if (state->save_marks)
1044
1.99M
                    MARK_POP_DISCARD(ctx->lastmark);
1045
2.67M
            }
1046
3.71M
            RETURN_FAILURE;
1047
1048
16
        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
16
            TRACE(("|%p|%p|MIN_REPEAT_ONE %d %d\n", pattern, ptr,
1059
16
                   pattern[1], pattern[2]));
1060
1061
16
            if ((Py_ssize_t) pattern[1] > end - ptr)
1062
0
                RETURN_FAILURE; /* cannot match */
1063
1064
16
            state->ptr = ptr;
1065
1066
16
            if (pattern[1] == 0)
1067
16
                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
16
            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
16
            } else {
1091
                /* general case */
1092
16
                LASTMARK_SAVE();
1093
16
                if (state->save_marks)
1094
0
                    MARK_PUSH(ctx->lastmark);
1095
1096
832
                while ((Py_ssize_t)pattern[2] == SRE_MAXREPEAT
1097
832
                       || ctx->count <= (Py_ssize_t)pattern[2]) {
1098
832
                    state->ptr = ptr;
1099
832
                    DO_JUMP(JUMP_MIN_REPEAT_ONE,jump_min_repeat_one,
1100
832
                            pattern+pattern[0]);
1101
832
                    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
832
                    if (state->save_marks)
1108
0
                        MARK_POP_KEEP(ctx->lastmark);
1109
832
                    LASTMARK_RESTORE();
1110
1111
832
                    state->ptr = ptr;
1112
832
                    ret = SRE(count)(state, pattern+3, 1);
1113
832
                    RETURN_ON_ERROR(ret);
1114
832
                    DATA_LOOKUP_AT(SRE(match_context), ctx, ctx_pos);
1115
832
                    if (ret == 0)
1116
16
                        break;
1117
832
                    assert(ret == 1);
1118
816
                    ptr++;
1119
816
                    ctx->count++;
1120
816
                }
1121
16
                if (state->save_marks)
1122
0
                    MARK_POP_DISCARD(ctx->lastmark);
1123
16
            }
1124
16
            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
30.5M
        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
30.5M
            TRACE(("|%p|%p|REPEAT %d %d\n", pattern, ptr,
1186
30.5M
                   pattern[1], pattern[2]));
1187
1188
            /* install new repeat context */
1189
30.5M
            ctx->u.rep = repeat_pool_malloc(state);
1190
30.5M
            if (!ctx->u.rep) {
1191
0
                RETURN_ERROR(SRE_ERROR_MEMORY);
1192
0
            }
1193
30.5M
            ctx->u.rep->count = -1;
1194
30.5M
            ctx->u.rep->pattern = pattern;
1195
30.5M
            ctx->u.rep->prev = state->repeat;
1196
30.5M
            ctx->u.rep->last_ptr = NULL;
1197
30.5M
            state->repeat = ctx->u.rep;
1198
30.5M
            state->save_marks++;
1199
1200
30.5M
            state->ptr = ptr;
1201
30.5M
            DO_JUMP(JUMP_REPEAT, jump_repeat, pattern+pattern[0]);
1202
30.5M
            state->repeat = ctx->u.rep->prev;
1203
30.5M
            state->save_marks--;
1204
30.5M
            repeat_pool_free(state, ctx->u.rep);
1205
1206
30.5M
            if (ret) {
1207
25.3M
                RETURN_ON_ERROR(ret);
1208
25.3M
                RETURN_SUCCESS;
1209
25.3M
            }
1210
5.28M
            RETURN_FAILURE;
1211
1212
195M
        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
195M
            ctx->u.rep = state->repeat;
1220
195M
            if (!ctx->u.rep)
1221
0
                RETURN_ERROR(SRE_ERROR_STATE);
1222
1223
195M
            state->ptr = ptr;
1224
1225
195M
            ctx->count = ctx->u.rep->count+1;
1226
1227
195M
            TRACE(("|%p|%p|MAX_UNTIL %zd\n", pattern,
1228
195M
                   ptr, ctx->count));
1229
1230
195M
            if (ctx->count < (Py_ssize_t) ctx->u.rep->pattern[1]) {
1231
                /* not enough matches */
1232
8.16M
                ctx->u.rep->count = ctx->count;
1233
8.16M
                DO_JUMP(JUMP_MAX_UNTIL_1, jump_max_until_1,
1234
8.16M
                        ctx->u.rep->pattern+3);
1235
8.16M
                if (ret) {
1236
2.98M
                    RETURN_ON_ERROR(ret);
1237
2.98M
                    RETURN_SUCCESS;
1238
2.98M
                }
1239
5.18M
                ctx->u.rep->count = ctx->count-1;
1240
5.18M
                state->ptr = ptr;
1241
5.18M
                RETURN_FAILURE;
1242
5.18M
            }
1243
1244
187M
            if ((ctx->count < (Py_ssize_t) ctx->u.rep->pattern[2] ||
1245
6.73M
                ctx->u.rep->pattern[2] == SRE_MAXREPEAT) &&
1246
180M
                state->ptr != ctx->u.rep->last_ptr) {
1247
                /* we may have enough matches, but if we can
1248
                   match another item, do so */
1249
180M
                ctx->u.rep->count = ctx->count;
1250
180M
                LASTMARK_SAVE();
1251
180M
                MARK_PUSH(ctx->lastmark);
1252
                /* zero-width match protection */
1253
180M
                LAST_PTR_PUSH();
1254
180M
                ctx->u.rep->last_ptr = state->ptr;
1255
180M
                DO_JUMP(JUMP_MAX_UNTIL_2, jump_max_until_2,
1256
180M
                        ctx->u.rep->pattern+3);
1257
180M
                LAST_PTR_POP();
1258
180M
                if (ret) {
1259
161M
                    MARK_POP_DISCARD(ctx->lastmark);
1260
161M
                    RETURN_ON_ERROR(ret);
1261
161M
                    RETURN_SUCCESS;
1262
161M
                }
1263
19.0M
                MARK_POP(ctx->lastmark);
1264
19.0M
                LASTMARK_RESTORE();
1265
19.0M
                ctx->u.rep->count = ctx->count-1;
1266
19.0M
                state->ptr = ptr;
1267
19.0M
            }
1268
1269
            /* cannot match more repeated items here.  make sure the
1270
               tail matches */
1271
25.7M
            state->repeat = ctx->u.rep->prev;
1272
25.7M
            state->save_marks--;
1273
25.7M
            DO_JUMP(JUMP_MAX_UNTIL_3, jump_max_until_3, pattern);
1274
25.7M
            state->repeat = ctx->u.rep; // restore repeat before return
1275
25.7M
            state->save_marks++;
1276
1277
25.7M
            RETURN_ON_SUCCESS(ret);
1278
487k
            state->ptr = ptr;
1279
487k
            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
12
        TARGET(SRE_OP_ASSERT):
1622
            /* assert subpattern */
1623
            /* <ASSERT> <skip> <back> <pattern> */
1624
12
            TRACE(("|%p|%p|ASSERT %d\n", pattern,
1625
12
                   ptr, pattern[1]));
1626
12
            if ((uintptr_t)(ptr - (SRE_CHAR *)state->beginning) < pattern[1])
1627
0
                RETURN_FAILURE;
1628
12
            state->ptr = ptr - pattern[1];
1629
12
            DO_JUMP0(JUMP_ASSERT, jump_assert, pattern+2);
1630
12
            RETURN_ON_FAILURE(ret);
1631
0
            pattern += pattern[0];
1632
0
            DISPATCH;
1633
1634
120M
        TARGET(SRE_OP_ASSERT_NOT):
1635
            /* assert not subpattern */
1636
            /* <ASSERT_NOT> <skip> <back> <pattern> */
1637
120M
            TRACE(("|%p|%p|ASSERT_NOT %d\n", pattern,
1638
120M
                   ptr, pattern[1]));
1639
120M
            if ((uintptr_t)(ptr - (SRE_CHAR *)state->beginning) >= pattern[1]) {
1640
120M
                state->ptr = ptr - pattern[1];
1641
120M
                LASTMARK_SAVE();
1642
120M
                if (state->save_marks)
1643
120M
                    MARK_PUSH(ctx->lastmark);
1644
1645
240M
                DO_JUMP0(JUMP_ASSERT_NOT, jump_assert_not, pattern+2);
1646
240M
                if (ret) {
1647
6.40M
                    if (state->save_marks)
1648
6.40M
                        MARK_POP_DISCARD(ctx->lastmark);
1649
6.40M
                    RETURN_ON_ERROR(ret);
1650
6.40M
                    RETURN_FAILURE;
1651
6.40M
                }
1652
113M
                if (state->save_marks)
1653
113M
                    MARK_POP(ctx->lastmark);
1654
113M
                LASTMARK_RESTORE();
1655
113M
            }
1656
113M
            pattern += pattern[0];
1657
113M
            DISPATCH;
1658
1659
113M
        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
896M
exit:
1681
896M
    ctx_pos = ctx->last_ctx_pos;
1682
896M
    jump = ctx->jump;
1683
896M
    DATA_POP_DISCARD(ctx);
1684
896M
    if (ctx_pos == -1) {
1685
372M
        state->sigcount = sigcount;
1686
372M
        return ret;
1687
372M
    }
1688
523M
    DATA_LOOKUP_AT(SRE(match_context), ctx, ctx_pos);
1689
1690
523M
    switch (jump) {
1691
180M
        case JUMP_MAX_UNTIL_2:
1692
180M
            TRACE(("|%p|%p|JUMP_MAX_UNTIL_2\n", pattern, ptr));
1693
180M
            goto jump_max_until_2;
1694
25.7M
        case JUMP_MAX_UNTIL_3:
1695
25.7M
            TRACE(("|%p|%p|JUMP_MAX_UNTIL_3\n", pattern, ptr));
1696
25.7M
            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
54.1M
        case JUMP_BRANCH:
1704
54.1M
            TRACE(("|%p|%p|JUMP_BRANCH\n", pattern, ptr));
1705
54.1M
            goto jump_branch;
1706
8.16M
        case JUMP_MAX_UNTIL_1:
1707
8.16M
            TRACE(("|%p|%p|JUMP_MAX_UNTIL_1\n", pattern, ptr));
1708
8.16M
            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
30.5M
        case JUMP_REPEAT:
1719
30.5M
            TRACE(("|%p|%p|JUMP_REPEAT\n", pattern, ptr));
1720
30.5M
            goto jump_repeat;
1721
1.71M
        case JUMP_REPEAT_ONE_1:
1722
1.71M
            TRACE(("|%p|%p|JUMP_REPEAT_ONE_1\n", pattern, ptr));
1723
1.71M
            goto jump_repeat_one_1;
1724
102M
        case JUMP_REPEAT_ONE_2:
1725
102M
            TRACE(("|%p|%p|JUMP_REPEAT_ONE_2\n", pattern, ptr));
1726
102M
            goto jump_repeat_one_2;
1727
832
        case JUMP_MIN_REPEAT_ONE:
1728
832
            TRACE(("|%p|%p|JUMP_MIN_REPEAT_ONE\n", pattern, ptr));
1729
832
            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
12
        case JUMP_ASSERT:
1734
12
            TRACE(("|%p|%p|JUMP_ASSERT\n", pattern, ptr));
1735
12
            goto jump_assert;
1736
120M
        case JUMP_ASSERT_NOT:
1737
120M
            TRACE(("|%p|%p|JUMP_ASSERT_NOT\n", pattern, ptr));
1738
120M
            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
523M
    }
1744
1745
0
    return ret; /* should never get here */
1746
523M
}
sre.c:sre_ucs1_match
Line
Count
Source
663
134M
{
664
134M
    const SRE_CHAR* end = (const SRE_CHAR *)state->end;
665
134M
    Py_ssize_t alloc_pos, ctx_pos = -1;
666
134M
    Py_ssize_t ret = 0;
667
134M
    int jump;
668
134M
    unsigned int sigcount = state->sigcount;
669
670
134M
    SRE(match_context)* ctx;
671
134M
    SRE(match_context)* nextctx;
672
134M
    INIT_TRACE(state);
673
674
134M
    TRACE(("|%p|%p|ENTER\n", pattern, state->ptr));
675
676
134M
    DATA_ALLOC(SRE(match_context), ctx);
677
134M
    ctx->last_ctx_pos = -1;
678
134M
    ctx->jump = JUMP_NONE;
679
134M
    ctx->toplevel = toplevel;
680
134M
    ctx_pos = alloc_pos;
681
682
134M
#if USE_COMPUTED_GOTOS
683
134M
#include "sre_targets.h"
684
134M
#endif
685
686
361M
entrance:
687
688
361M
    ;  // Fashion statement.
689
361M
    const SRE_CHAR *ptr = (SRE_CHAR *)state->ptr;
690
691
361M
    if (pattern[0] == SRE_OP_INFO) {
692
        /* optimization info block */
693
        /* <INFO> <1=skip> <2=flags> <3=min> ... */
694
38.3M
        if (pattern[3] && (uintptr_t)(end - ptr) < pattern[3]) {
695
6.54M
            TRACE(("reject (got %tu chars, need %zu)\n",
696
6.54M
                   end - ptr, (size_t) pattern[3]));
697
6.54M
            RETURN_FAILURE;
698
6.54M
        }
699
31.8M
        pattern += pattern[1] + 1;
700
31.8M
    }
701
702
354M
#if USE_COMPUTED_GOTOS
703
354M
    DISPATCH;
704
#else
705
dispatch:
706
    MAYBE_CHECK_SIGNALS;
707
    switch (*pattern++)
708
#endif
709
354M
    {
710
711
354M
        TARGET(SRE_OP_MARK):
712
            /* set mark */
713
            /* <MARK> <gid> */
714
119M
            TRACE(("|%p|%p|MARK %d\n", pattern,
715
119M
                   ptr, pattern[0]));
716
119M
            {
717
119M
                int i = pattern[0];
718
119M
                if (i & 1)
719
32.8M
                    state->lastindex = i/2 + 1;
720
119M
                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
116M
                    int j = state->lastmark + 1;
726
127M
                    while (j < i)
727
10.4M
                        state->mark[j++] = NULL;
728
116M
                    state->lastmark = i;
729
116M
                }
730
119M
                state->mark[i] = ptr;
731
119M
            }
732
119M
            pattern++;
733
119M
            DISPATCH;
734
735
119M
        TARGET(SRE_OP_LITERAL):
736
            /* match literal string */
737
            /* <LITERAL> <code> */
738
66.9M
            TRACE(("|%p|%p|LITERAL %d\n", pattern,
739
66.9M
                   ptr, *pattern));
740
66.9M
            if (ptr >= end || (SRE_CODE) ptr[0] != pattern[0])
741
30.1M
                RETURN_FAILURE;
742
36.7M
            pattern++;
743
36.7M
            ptr++;
744
36.7M
            DISPATCH;
745
746
36.7M
        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
71.7M
        TARGET(SRE_OP_SUCCESS):
758
            /* end of pattern */
759
71.7M
            TRACE(("|%p|%p|SUCCESS\n", pattern, ptr));
760
71.7M
            if (ctx->toplevel &&
761
24.6M
                ((state->match_all && ptr != state->end) ||
762
24.6M
                 (state->must_advance && ptr == state->start)))
763
217
            {
764
217
                RETURN_FAILURE;
765
217
            }
766
71.7M
            state->ptr = ptr;
767
71.7M
            RETURN_SUCCESS;
768
769
18.8M
        TARGET(SRE_OP_AT):
770
            /* match at given position */
771
            /* <AT> <code> */
772
18.8M
            TRACE(("|%p|%p|AT %d\n", pattern, ptr, *pattern));
773
18.8M
            if (!SRE(at)(state, ptr, *pattern))
774
1.99M
                RETURN_FAILURE;
775
16.8M
            pattern++;
776
16.8M
            DISPATCH;
777
778
23.1M
        TARGET(SRE_OP_CATEGORY):
779
            /* match at given category */
780
            /* <CATEGORY> <code> */
781
23.1M
            TRACE(("|%p|%p|CATEGORY %d\n", pattern,
782
23.1M
                   ptr, *pattern));
783
23.1M
            if (ptr >= end || !sre_category(pattern[0], ptr[0]))
784
1.08M
                RETURN_FAILURE;
785
22.0M
            pattern++;
786
22.0M
            ptr++;
787
22.0M
            DISPATCH;
788
789
22.0M
        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
90.2M
        TARGET(SRE_OP_IN):
808
            /* match set member (or non_member) */
809
            /* <IN> <skip> <set> */
810
90.2M
            TRACE(("|%p|%p|IN\n", pattern, ptr));
811
90.2M
            if (ptr >= end ||
812
88.9M
                !SRE(charset)(state, pattern + 1, *ptr))
813
21.7M
                RETURN_FAILURE;
814
68.4M
            pattern += pattern[0];
815
68.4M
            ptr++;
816
68.4M
            DISPATCH;
817
818
68.4M
        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
19.3M
        TARGET(SRE_OP_JUMP):
908
19.3M
        TARGET(SRE_OP_INFO):
909
            /* jump forward */
910
            /* <JUMP> <offset> */
911
19.3M
            TRACE(("|%p|%p|JUMP %d\n", pattern,
912
19.3M
                   ptr, pattern[0]));
913
19.3M
            pattern += pattern[0];
914
19.3M
            DISPATCH;
915
916
29.8M
        TARGET(SRE_OP_BRANCH):
917
            /* alternation */
918
            /* <BRANCH> <0=skip> code <JUMP> ... <NULL> */
919
29.8M
            TRACE(("|%p|%p|BRANCH\n", pattern, ptr));
920
29.8M
            LASTMARK_SAVE();
921
29.8M
            if (state->save_marks)
922
31.3k
                MARK_PUSH(ctx->lastmark);
923
80.1M
            for (; pattern[0]; pattern += pattern[0]) {
924
67.8M
                if (pattern[1] == SRE_OP_LITERAL &&
925
50.5M
                    (ptr >= end ||
926
50.5M
                     (SRE_CODE) *ptr != pattern[2]))
927
19.3M
                    continue;
928
48.5M
                if (pattern[1] == SRE_OP_IN &&
929
2.52M
                    (ptr >= end ||
930
2.52M
                     !SRE(charset)(state, pattern + 3,
931
2.52M
                                   (SRE_CODE) *ptr)))
932
1.41M
                    continue;
933
47.1M
                state->ptr = ptr;
934
47.1M
                DO_JUMP(JUMP_BRANCH, jump_branch, pattern+1);
935
47.1M
                if (ret) {
936
17.5M
                    if (state->save_marks)
937
28.3k
                        MARK_POP_DISCARD(ctx->lastmark);
938
17.5M
                    RETURN_ON_ERROR(ret);
939
17.5M
                    RETURN_SUCCESS;
940
17.5M
                }
941
29.5M
                if (state->save_marks)
942
8.04k
                    MARK_POP_KEEP(ctx->lastmark);
943
29.5M
                LASTMARK_RESTORE();
944
29.5M
            }
945
12.3M
            if (state->save_marks)
946
2.93k
                MARK_POP_DISCARD(ctx->lastmark);
947
12.3M
            RETURN_FAILURE;
948
949
104M
        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
104M
            TRACE(("|%p|%p|REPEAT_ONE %d %d\n", pattern, ptr,
960
104M
                   pattern[1], pattern[2]));
961
962
104M
            if ((Py_ssize_t) pattern[1] > end - ptr)
963
757k
                RETURN_FAILURE; /* cannot match */
964
965
103M
            state->ptr = ptr;
966
967
103M
            ret = SRE(count)(state, pattern+3, pattern[2]);
968
103M
            RETURN_ON_ERROR(ret);
969
103M
            DATA_LOOKUP_AT(SRE(match_context), ctx, ctx_pos);
970
103M
            ctx->count = ret;
971
103M
            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
103M
            if (ctx->count < (Py_ssize_t) pattern[1])
979
52.0M
                RETURN_FAILURE;
980
981
51.3M
            if (pattern[pattern[0]] == SRE_OP_SUCCESS &&
982
600k
                ptr == state->end &&
983
83.1k
                !(ctx->toplevel && state->must_advance && ptr == state->start))
984
83.1k
            {
985
                /* tail is empty.  we're finished */
986
83.1k
                state->ptr = ptr;
987
83.1k
                RETURN_SUCCESS;
988
83.1k
            }
989
990
51.2M
            LASTMARK_SAVE();
991
51.2M
            if (state->save_marks)
992
36.0M
                MARK_PUSH(ctx->lastmark);
993
994
51.2M
            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
2.71M
                ctx->u.chr = pattern[pattern[0]+1];
998
2.71M
                for (;;) {
999
8.56M
                    while (ctx->count >= (Py_ssize_t) pattern[1] &&
1000
7.53M
                           (ptr >= end || *ptr != ctx->u.chr)) {
1001
5.84M
                        ptr--;
1002
5.84M
                        ctx->count--;
1003
5.84M
                    }
1004
2.71M
                    if (ctx->count < (Py_ssize_t) pattern[1])
1005
1.02M
                        break;
1006
1.69M
                    state->ptr = ptr;
1007
1.69M
                    DO_JUMP(JUMP_REPEAT_ONE_1, jump_repeat_one_1,
1008
1.69M
                            pattern+pattern[0]);
1009
1.69M
                    if (ret) {
1010
1.69M
                        if (state->save_marks)
1011
0
                            MARK_POP_DISCARD(ctx->lastmark);
1012
1.69M
                        RETURN_ON_ERROR(ret);
1013
1.69M
                        RETURN_SUCCESS;
1014
1.69M
                    }
1015
16
                    if (state->save_marks)
1016
0
                        MARK_POP_KEEP(ctx->lastmark);
1017
16
                    LASTMARK_RESTORE();
1018
1019
16
                    ptr--;
1020
16
                    ctx->count--;
1021
16
                }
1022
1.02M
                if (state->save_marks)
1023
32
                    MARK_POP_DISCARD(ctx->lastmark);
1024
48.5M
            } else {
1025
                /* general case */
1026
56.3M
                while (ctx->count >= (Py_ssize_t) pattern[1]) {
1027
54.4M
                    state->ptr = ptr;
1028
54.4M
                    DO_JUMP(JUMP_REPEAT_ONE_2, jump_repeat_one_2,
1029
54.4M
                            pattern+pattern[0]);
1030
54.4M
                    if (ret) {
1031
46.5M
                        if (state->save_marks)
1032
34.6M
                            MARK_POP_DISCARD(ctx->lastmark);
1033
46.5M
                        RETURN_ON_ERROR(ret);
1034
46.5M
                        RETURN_SUCCESS;
1035
46.5M
                    }
1036
7.80M
                    if (state->save_marks)
1037
1.60M
                        MARK_POP_KEEP(ctx->lastmark);
1038
7.80M
                    LASTMARK_RESTORE();
1039
1040
7.80M
                    ptr--;
1041
7.80M
                    ctx->count--;
1042
7.80M
                }
1043
1.97M
                if (state->save_marks)
1044
1.43M
                    MARK_POP_DISCARD(ctx->lastmark);
1045
1.97M
            }
1046
3.00M
            RETURN_FAILURE;
1047
1048
16
        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
16
            TRACE(("|%p|%p|MIN_REPEAT_ONE %d %d\n", pattern, ptr,
1059
16
                   pattern[1], pattern[2]));
1060
1061
16
            if ((Py_ssize_t) pattern[1] > end - ptr)
1062
0
                RETURN_FAILURE; /* cannot match */
1063
1064
16
            state->ptr = ptr;
1065
1066
16
            if (pattern[1] == 0)
1067
16
                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
16
            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
16
            } else {
1091
                /* general case */
1092
16
                LASTMARK_SAVE();
1093
16
                if (state->save_marks)
1094
0
                    MARK_PUSH(ctx->lastmark);
1095
1096
832
                while ((Py_ssize_t)pattern[2] == SRE_MAXREPEAT
1097
832
                       || ctx->count <= (Py_ssize_t)pattern[2]) {
1098
832
                    state->ptr = ptr;
1099
832
                    DO_JUMP(JUMP_MIN_REPEAT_ONE,jump_min_repeat_one,
1100
832
                            pattern+pattern[0]);
1101
832
                    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
832
                    if (state->save_marks)
1108
0
                        MARK_POP_KEEP(ctx->lastmark);
1109
832
                    LASTMARK_RESTORE();
1110
1111
832
                    state->ptr = ptr;
1112
832
                    ret = SRE(count)(state, pattern+3, 1);
1113
832
                    RETURN_ON_ERROR(ret);
1114
832
                    DATA_LOOKUP_AT(SRE(match_context), ctx, ctx_pos);
1115
832
                    if (ret == 0)
1116
16
                        break;
1117
832
                    assert(ret == 1);
1118
816
                    ptr++;
1119
816
                    ctx->count++;
1120
816
                }
1121
16
                if (state->save_marks)
1122
0
                    MARK_POP_DISCARD(ctx->lastmark);
1123
16
            }
1124
16
            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
20.0M
        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
20.0M
            TRACE(("|%p|%p|REPEAT %d %d\n", pattern, ptr,
1186
20.0M
                   pattern[1], pattern[2]));
1187
1188
            /* install new repeat context */
1189
20.0M
            ctx->u.rep = repeat_pool_malloc(state);
1190
20.0M
            if (!ctx->u.rep) {
1191
0
                RETURN_ERROR(SRE_ERROR_MEMORY);
1192
0
            }
1193
20.0M
            ctx->u.rep->count = -1;
1194
20.0M
            ctx->u.rep->pattern = pattern;
1195
20.0M
            ctx->u.rep->prev = state->repeat;
1196
20.0M
            ctx->u.rep->last_ptr = NULL;
1197
20.0M
            state->repeat = ctx->u.rep;
1198
20.0M
            state->save_marks++;
1199
1200
20.0M
            state->ptr = ptr;
1201
20.0M
            DO_JUMP(JUMP_REPEAT, jump_repeat, pattern+pattern[0]);
1202
20.0M
            state->repeat = ctx->u.rep->prev;
1203
20.0M
            state->save_marks--;
1204
20.0M
            repeat_pool_free(state, ctx->u.rep);
1205
1206
20.0M
            if (ret) {
1207
16.4M
                RETURN_ON_ERROR(ret);
1208
16.4M
                RETURN_SUCCESS;
1209
16.4M
            }
1210
3.62M
            RETURN_FAILURE;
1211
1212
67.9M
        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
67.9M
            ctx->u.rep = state->repeat;
1220
67.9M
            if (!ctx->u.rep)
1221
0
                RETURN_ERROR(SRE_ERROR_STATE);
1222
1223
67.9M
            state->ptr = ptr;
1224
1225
67.9M
            ctx->count = ctx->u.rep->count+1;
1226
1227
67.9M
            TRACE(("|%p|%p|MAX_UNTIL %zd\n", pattern,
1228
67.9M
                   ptr, ctx->count));
1229
1230
67.9M
            if (ctx->count < (Py_ssize_t) ctx->u.rep->pattern[1]) {
1231
                /* not enough matches */
1232
3.67M
                ctx->u.rep->count = ctx->count;
1233
3.67M
                DO_JUMP(JUMP_MAX_UNTIL_1, jump_max_until_1,
1234
3.67M
                        ctx->u.rep->pattern+3);
1235
3.67M
                if (ret) {
1236
150k
                    RETURN_ON_ERROR(ret);
1237
150k
                    RETURN_SUCCESS;
1238
150k
                }
1239
3.52M
                ctx->u.rep->count = ctx->count-1;
1240
3.52M
                state->ptr = ptr;
1241
3.52M
                RETURN_FAILURE;
1242
3.52M
            }
1243
1244
64.2M
            if ((ctx->count < (Py_ssize_t) ctx->u.rep->pattern[2] ||
1245
6.28M
                ctx->u.rep->pattern[2] == SRE_MAXREPEAT) &&
1246
57.9M
                state->ptr != ctx->u.rep->last_ptr) {
1247
                /* we may have enough matches, but if we can
1248
                   match another item, do so */
1249
57.9M
                ctx->u.rep->count = ctx->count;
1250
57.9M
                LASTMARK_SAVE();
1251
57.9M
                MARK_PUSH(ctx->lastmark);
1252
                /* zero-width match protection */
1253
57.9M
                LAST_PTR_PUSH();
1254
57.9M
                ctx->u.rep->last_ptr = state->ptr;
1255
57.9M
                DO_JUMP(JUMP_MAX_UNTIL_2, jump_max_until_2,
1256
57.9M
                        ctx->u.rep->pattern+3);
1257
57.9M
                LAST_PTR_POP();
1258
57.9M
                if (ret) {
1259
47.4M
                    MARK_POP_DISCARD(ctx->lastmark);
1260
47.4M
                    RETURN_ON_ERROR(ret);
1261
47.4M
                    RETURN_SUCCESS;
1262
47.4M
                }
1263
10.5M
                MARK_POP(ctx->lastmark);
1264
10.5M
                LASTMARK_RESTORE();
1265
10.5M
                ctx->u.rep->count = ctx->count-1;
1266
10.5M
                state->ptr = ptr;
1267
10.5M
            }
1268
1269
            /* cannot match more repeated items here.  make sure the
1270
               tail matches */
1271
16.8M
            state->repeat = ctx->u.rep->prev;
1272
16.8M
            state->save_marks--;
1273
16.8M
            DO_JUMP(JUMP_MAX_UNTIL_3, jump_max_until_3, pattern);
1274
16.8M
            state->repeat = ctx->u.rep; // restore repeat before return
1275
16.8M
            state->save_marks++;
1276
1277
16.8M
            RETURN_ON_SUCCESS(ret);
1278
371k
            state->ptr = ptr;
1279
371k
            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
12
        TARGET(SRE_OP_ASSERT):
1622
            /* assert subpattern */
1623
            /* <ASSERT> <skip> <back> <pattern> */
1624
12
            TRACE(("|%p|%p|ASSERT %d\n", pattern,
1625
12
                   ptr, pattern[1]));
1626
12
            if ((uintptr_t)(ptr - (SRE_CHAR *)state->beginning) < pattern[1])
1627
0
                RETURN_FAILURE;
1628
12
            state->ptr = ptr - pattern[1];
1629
12
            DO_JUMP0(JUMP_ASSERT, jump_assert, pattern+2);
1630
12
            RETURN_ON_FAILURE(ret);
1631
0
            pattern += pattern[0];
1632
0
            DISPATCH;
1633
1634
25.6M
        TARGET(SRE_OP_ASSERT_NOT):
1635
            /* assert not subpattern */
1636
            /* <ASSERT_NOT> <skip> <back> <pattern> */
1637
25.6M
            TRACE(("|%p|%p|ASSERT_NOT %d\n", pattern,
1638
25.6M
                   ptr, pattern[1]));
1639
25.6M
            if ((uintptr_t)(ptr - (SRE_CHAR *)state->beginning) >= pattern[1]) {
1640
25.6M
                state->ptr = ptr - pattern[1];
1641
25.6M
                LASTMARK_SAVE();
1642
25.6M
                if (state->save_marks)
1643
25.6M
                    MARK_PUSH(ctx->lastmark);
1644
1645
51.2M
                DO_JUMP0(JUMP_ASSERT_NOT, jump_assert_not, pattern+2);
1646
51.2M
                if (ret) {
1647
6.06M
                    if (state->save_marks)
1648
6.06M
                        MARK_POP_DISCARD(ctx->lastmark);
1649
6.06M
                    RETURN_ON_ERROR(ret);
1650
6.06M
                    RETURN_FAILURE;
1651
6.06M
                }
1652
19.5M
                if (state->save_marks)
1653
19.5M
                    MARK_POP(ctx->lastmark);
1654
19.5M
                LASTMARK_RESTORE();
1655
19.5M
            }
1656
19.5M
            pattern += pattern[0];
1657
19.5M
            DISPATCH;
1658
1659
19.5M
        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
361M
exit:
1681
361M
    ctx_pos = ctx->last_ctx_pos;
1682
361M
    jump = ctx->jump;
1683
361M
    DATA_POP_DISCARD(ctx);
1684
361M
    if (ctx_pos == -1) {
1685
134M
        state->sigcount = sigcount;
1686
134M
        return ret;
1687
134M
    }
1688
227M
    DATA_LOOKUP_AT(SRE(match_context), ctx, ctx_pos);
1689
1690
227M
    switch (jump) {
1691
57.9M
        case JUMP_MAX_UNTIL_2:
1692
57.9M
            TRACE(("|%p|%p|JUMP_MAX_UNTIL_2\n", pattern, ptr));
1693
57.9M
            goto jump_max_until_2;
1694
16.8M
        case JUMP_MAX_UNTIL_3:
1695
16.8M
            TRACE(("|%p|%p|JUMP_MAX_UNTIL_3\n", pattern, ptr));
1696
16.8M
            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
47.1M
        case JUMP_BRANCH:
1704
47.1M
            TRACE(("|%p|%p|JUMP_BRANCH\n", pattern, ptr));
1705
47.1M
            goto jump_branch;
1706
3.67M
        case JUMP_MAX_UNTIL_1:
1707
3.67M
            TRACE(("|%p|%p|JUMP_MAX_UNTIL_1\n", pattern, ptr));
1708
3.67M
            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
20.0M
        case JUMP_REPEAT:
1719
20.0M
            TRACE(("|%p|%p|JUMP_REPEAT\n", pattern, ptr));
1720
20.0M
            goto jump_repeat;
1721
1.69M
        case JUMP_REPEAT_ONE_1:
1722
1.69M
            TRACE(("|%p|%p|JUMP_REPEAT_ONE_1\n", pattern, ptr));
1723
1.69M
            goto jump_repeat_one_1;
1724
54.4M
        case JUMP_REPEAT_ONE_2:
1725
54.4M
            TRACE(("|%p|%p|JUMP_REPEAT_ONE_2\n", pattern, ptr));
1726
54.4M
            goto jump_repeat_one_2;
1727
832
        case JUMP_MIN_REPEAT_ONE:
1728
832
            TRACE(("|%p|%p|JUMP_MIN_REPEAT_ONE\n", pattern, ptr));
1729
832
            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
12
        case JUMP_ASSERT:
1734
12
            TRACE(("|%p|%p|JUMP_ASSERT\n", pattern, ptr));
1735
12
            goto jump_assert;
1736
25.6M
        case JUMP_ASSERT_NOT:
1737
25.6M
            TRACE(("|%p|%p|JUMP_ASSERT_NOT\n", pattern, ptr));
1738
25.6M
            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
227M
    }
1744
1745
0
    return ret; /* should never get here */
1746
227M
}
sre.c:sre_ucs2_match
Line
Count
Source
663
204M
{
664
204M
    const SRE_CHAR* end = (const SRE_CHAR *)state->end;
665
204M
    Py_ssize_t alloc_pos, ctx_pos = -1;
666
204M
    Py_ssize_t ret = 0;
667
204M
    int jump;
668
204M
    unsigned int sigcount = state->sigcount;
669
670
204M
    SRE(match_context)* ctx;
671
204M
    SRE(match_context)* nextctx;
672
204M
    INIT_TRACE(state);
673
674
204M
    TRACE(("|%p|%p|ENTER\n", pattern, state->ptr));
675
676
204M
    DATA_ALLOC(SRE(match_context), ctx);
677
204M
    ctx->last_ctx_pos = -1;
678
204M
    ctx->jump = JUMP_NONE;
679
204M
    ctx->toplevel = toplevel;
680
204M
    ctx_pos = alloc_pos;
681
682
204M
#if USE_COMPUTED_GOTOS
683
204M
#include "sre_targets.h"
684
204M
#endif
685
686
422M
entrance:
687
688
422M
    ;  // Fashion statement.
689
422M
    const SRE_CHAR *ptr = (SRE_CHAR *)state->ptr;
690
691
422M
    if (pattern[0] == SRE_OP_INFO) {
692
        /* optimization info block */
693
        /* <INFO> <1=skip> <2=flags> <3=min> ... */
694
6.33M
        if (pattern[3] && (uintptr_t)(end - ptr) < pattern[3]) {
695
136k
            TRACE(("reject (got %tu chars, need %zu)\n",
696
136k
                   end - ptr, (size_t) pattern[3]));
697
136k
            RETURN_FAILURE;
698
136k
        }
699
6.20M
        pattern += pattern[1] + 1;
700
6.20M
    }
701
702
422M
#if USE_COMPUTED_GOTOS
703
422M
    DISPATCH;
704
#else
705
dispatch:
706
    MAYBE_CHECK_SIGNALS;
707
    switch (*pattern++)
708
#endif
709
422M
    {
710
711
422M
        TARGET(SRE_OP_MARK):
712
            /* set mark */
713
            /* <MARK> <gid> */
714
166M
            TRACE(("|%p|%p|MARK %d\n", pattern,
715
166M
                   ptr, pattern[0]));
716
166M
            {
717
166M
                int i = pattern[0];
718
166M
                if (i & 1)
719
12.4M
                    state->lastindex = i/2 + 1;
720
166M
                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
166M
                    int j = state->lastmark + 1;
726
169M
                    while (j < i)
727
3.44M
                        state->mark[j++] = NULL;
728
166M
                    state->lastmark = i;
729
166M
                }
730
166M
                state->mark[i] = ptr;
731
166M
            }
732
166M
            pattern++;
733
166M
            DISPATCH;
734
735
166M
        TARGET(SRE_OP_LITERAL):
736
            /* match literal string */
737
            /* <LITERAL> <code> */
738
15.4M
            TRACE(("|%p|%p|LITERAL %d\n", pattern,
739
15.4M
                   ptr, *pattern));
740
15.4M
            if (ptr >= end || (SRE_CODE) ptr[0] != pattern[0])
741
13.9M
                RETURN_FAILURE;
742
1.53M
            pattern++;
743
1.53M
            ptr++;
744
1.53M
            DISPATCH;
745
746
1.53M
        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
55.8M
        TARGET(SRE_OP_SUCCESS):
758
            /* end of pattern */
759
55.8M
            TRACE(("|%p|%p|SUCCESS\n", pattern, ptr));
760
55.8M
            if (ctx->toplevel &&
761
4.06M
                ((state->match_all && ptr != state->end) ||
762
4.06M
                 (state->must_advance && ptr == state->start)))
763
0
            {
764
0
                RETURN_FAILURE;
765
0
            }
766
55.8M
            state->ptr = ptr;
767
55.8M
            RETURN_SUCCESS;
768
769
4.25M
        TARGET(SRE_OP_AT):
770
            /* match at given position */
771
            /* <AT> <code> */
772
4.25M
            TRACE(("|%p|%p|AT %d\n", pattern, ptr, *pattern));
773
4.25M
            if (!SRE(at)(state, ptr, *pattern))
774
881k
                RETURN_FAILURE;
775
3.36M
            pattern++;
776
3.36M
            DISPATCH;
777
778
75.3M
        TARGET(SRE_OP_CATEGORY):
779
            /* match at given category */
780
            /* <CATEGORY> <code> */
781
75.3M
            TRACE(("|%p|%p|CATEGORY %d\n", pattern,
782
75.3M
                   ptr, *pattern));
783
75.3M
            if (ptr >= end || !sre_category(pattern[0], ptr[0]))
784
4.05M
                RETURN_FAILURE;
785
71.3M
            pattern++;
786
71.3M
            ptr++;
787
71.3M
            DISPATCH;
788
789
71.3M
        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
140M
        TARGET(SRE_OP_IN):
808
            /* match set member (or non_member) */
809
            /* <IN> <skip> <set> */
810
140M
            TRACE(("|%p|%p|IN\n", pattern, ptr));
811
140M
            if (ptr >= end ||
812
135M
                !SRE(charset)(state, pattern + 1, *ptr))
813
75.8M
                RETURN_FAILURE;
814
64.3M
            pattern += pattern[0];
815
64.3M
            ptr++;
816
64.3M
            DISPATCH;
817
818
64.3M
        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
1.55M
        TARGET(SRE_OP_JUMP):
908
1.55M
        TARGET(SRE_OP_INFO):
909
            /* jump forward */
910
            /* <JUMP> <offset> */
911
1.55M
            TRACE(("|%p|%p|JUMP %d\n", pattern,
912
1.55M
                   ptr, pattern[0]));
913
1.55M
            pattern += pattern[0];
914
1.55M
            DISPATCH;
915
916
3.88M
        TARGET(SRE_OP_BRANCH):
917
            /* alternation */
918
            /* <BRANCH> <0=skip> code <JUMP> ... <NULL> */
919
3.88M
            TRACE(("|%p|%p|BRANCH\n", pattern, ptr));
920
3.88M
            LASTMARK_SAVE();
921
3.88M
            if (state->save_marks)
922
3.86k
                MARK_PUSH(ctx->lastmark);
923
12.0M
            for (; pattern[0]; pattern += pattern[0]) {
924
8.85M
                if (pattern[1] == SRE_OP_LITERAL &&
925
3.66M
                    (ptr >= end ||
926
3.66M
                     (SRE_CODE) *ptr != pattern[2]))
927
2.37M
                    continue;
928
6.48M
                if (pattern[1] == SRE_OP_IN &&
929
584k
                    (ptr >= end ||
930
584k
                     !SRE(charset)(state, pattern + 3,
931
584k
                                   (SRE_CODE) *ptr)))
932
201k
                    continue;
933
6.28M
                state->ptr = ptr;
934
6.28M
                DO_JUMP(JUMP_BRANCH, jump_branch, pattern+1);
935
6.28M
                if (ret) {
936
695k
                    if (state->save_marks)
937
2.20k
                        MARK_POP_DISCARD(ctx->lastmark);
938
695k
                    RETURN_ON_ERROR(ret);
939
695k
                    RETURN_SUCCESS;
940
695k
                }
941
5.58M
                if (state->save_marks)
942
2.79k
                    MARK_POP_KEEP(ctx->lastmark);
943
5.58M
                LASTMARK_RESTORE();
944
5.58M
            }
945
3.19M
            if (state->save_marks)
946
1.65k
                MARK_POP_DISCARD(ctx->lastmark);
947
3.19M
            RETURN_FAILURE;
948
949
165M
        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
165M
            TRACE(("|%p|%p|REPEAT_ONE %d %d\n", pattern, ptr,
960
165M
                   pattern[1], pattern[2]));
961
962
165M
            if ((Py_ssize_t) pattern[1] > end - ptr)
963
133k
                RETURN_FAILURE; /* cannot match */
964
965
165M
            state->ptr = ptr;
966
967
165M
            ret = SRE(count)(state, pattern+3, pattern[2]);
968
165M
            RETURN_ON_ERROR(ret);
969
165M
            DATA_LOOKUP_AT(SRE(match_context), ctx, ctx_pos);
970
165M
            ctx->count = ret;
971
165M
            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
165M
            if (ctx->count < (Py_ssize_t) pattern[1])
979
145M
                RETURN_FAILURE;
980
981
20.0M
            if (pattern[pattern[0]] == SRE_OP_SUCCESS &&
982
2.03M
                ptr == state->end &&
983
17.4k
                !(ctx->toplevel && state->must_advance && ptr == state->start))
984
17.4k
            {
985
                /* tail is empty.  we're finished */
986
17.4k
                state->ptr = ptr;
987
17.4k
                RETURN_SUCCESS;
988
17.4k
            }
989
990
20.0M
            LASTMARK_SAVE();
991
20.0M
            if (state->save_marks)
992
15.1M
                MARK_PUSH(ctx->lastmark);
993
994
20.0M
            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
28.2k
                ctx->u.chr = pattern[pattern[0]+1];
998
28.2k
                for (;;) {
999
430k
                    while (ctx->count >= (Py_ssize_t) pattern[1] &&
1000
418k
                           (ptr >= end || *ptr != ctx->u.chr)) {
1001
402k
                        ptr--;
1002
402k
                        ctx->count--;
1003
402k
                    }
1004
28.2k
                    if (ctx->count < (Py_ssize_t) pattern[1])
1005
11.5k
                        break;
1006
16.7k
                    state->ptr = ptr;
1007
16.7k
                    DO_JUMP(JUMP_REPEAT_ONE_1, jump_repeat_one_1,
1008
16.7k
                            pattern+pattern[0]);
1009
16.7k
                    if (ret) {
1010
16.7k
                        if (state->save_marks)
1011
0
                            MARK_POP_DISCARD(ctx->lastmark);
1012
16.7k
                        RETURN_ON_ERROR(ret);
1013
16.7k
                        RETURN_SUCCESS;
1014
16.7k
                    }
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
11.5k
                if (state->save_marks)
1023
0
                    MARK_POP_DISCARD(ctx->lastmark);
1024
20.0M
            } else {
1025
                /* general case */
1026
28.9M
                while (ctx->count >= (Py_ssize_t) pattern[1]) {
1027
28.3M
                    state->ptr = ptr;
1028
28.3M
                    DO_JUMP(JUMP_REPEAT_ONE_2, jump_repeat_one_2,
1029
28.3M
                            pattern+pattern[0]);
1030
28.3M
                    if (ret) {
1031
19.3M
                        if (state->save_marks)
1032
14.6M
                            MARK_POP_DISCARD(ctx->lastmark);
1033
19.3M
                        RETURN_ON_ERROR(ret);
1034
19.3M
                        RETURN_SUCCESS;
1035
19.3M
                    }
1036
8.96M
                    if (state->save_marks)
1037
551k
                        MARK_POP_KEEP(ctx->lastmark);
1038
8.96M
                    LASTMARK_RESTORE();
1039
1040
8.96M
                    ptr--;
1041
8.96M
                    ctx->count--;
1042
8.96M
                }
1043
633k
                if (state->save_marks)
1044
499k
                    MARK_POP_DISCARD(ctx->lastmark);
1045
633k
            }
1046
645k
            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
8.66M
        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
8.66M
            TRACE(("|%p|%p|REPEAT %d %d\n", pattern, ptr,
1186
8.66M
                   pattern[1], pattern[2]));
1187
1188
            /* install new repeat context */
1189
8.66M
            ctx->u.rep = repeat_pool_malloc(state);
1190
8.66M
            if (!ctx->u.rep) {
1191
0
                RETURN_ERROR(SRE_ERROR_MEMORY);
1192
0
            }
1193
8.66M
            ctx->u.rep->count = -1;
1194
8.66M
            ctx->u.rep->pattern = pattern;
1195
8.66M
            ctx->u.rep->prev = state->repeat;
1196
8.66M
            ctx->u.rep->last_ptr = NULL;
1197
8.66M
            state->repeat = ctx->u.rep;
1198
8.66M
            state->save_marks++;
1199
1200
8.66M
            state->ptr = ptr;
1201
8.66M
            DO_JUMP(JUMP_REPEAT, jump_repeat, pattern+pattern[0]);
1202
8.66M
            state->repeat = ctx->u.rep->prev;
1203
8.66M
            state->save_marks--;
1204
8.66M
            repeat_pool_free(state, ctx->u.rep);
1205
1206
8.66M
            if (ret) {
1207
7.04M
                RETURN_ON_ERROR(ret);
1208
7.04M
                RETURN_SUCCESS;
1209
7.04M
            }
1210
1.62M
            RETURN_FAILURE;
1211
1212
93.3M
        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
93.3M
            ctx->u.rep = state->repeat;
1220
93.3M
            if (!ctx->u.rep)
1221
0
                RETURN_ERROR(SRE_ERROR_STATE);
1222
1223
93.3M
            state->ptr = ptr;
1224
1225
93.3M
            ctx->count = ctx->u.rep->count+1;
1226
1227
93.3M
            TRACE(("|%p|%p|MAX_UNTIL %zd\n", pattern,
1228
93.3M
                   ptr, ctx->count));
1229
1230
93.3M
            if (ctx->count < (Py_ssize_t) ctx->u.rep->pattern[1]) {
1231
                /* not enough matches */
1232
2.76M
                ctx->u.rep->count = ctx->count;
1233
2.76M
                DO_JUMP(JUMP_MAX_UNTIL_1, jump_max_until_1,
1234
2.76M
                        ctx->u.rep->pattern+3);
1235
2.76M
                if (ret) {
1236
1.14M
                    RETURN_ON_ERROR(ret);
1237
1.14M
                    RETURN_SUCCESS;
1238
1.14M
                }
1239
1.62M
                ctx->u.rep->count = ctx->count-1;
1240
1.62M
                state->ptr = ptr;
1241
1.62M
                RETURN_FAILURE;
1242
1.62M
            }
1243
1244
90.6M
            if ((ctx->count < (Py_ssize_t) ctx->u.rep->pattern[2] ||
1245
396k
                ctx->u.rep->pattern[2] == SRE_MAXREPEAT) &&
1246
90.2M
                state->ptr != ctx->u.rep->last_ptr) {
1247
                /* we may have enough matches, but if we can
1248
                   match another item, do so */
1249
90.2M
                ctx->u.rep->count = ctx->count;
1250
90.2M
                LASTMARK_SAVE();
1251
90.2M
                MARK_PUSH(ctx->lastmark);
1252
                /* zero-width match protection */
1253
90.2M
                LAST_PTR_PUSH();
1254
90.2M
                ctx->u.rep->last_ptr = state->ptr;
1255
90.2M
                DO_JUMP(JUMP_MAX_UNTIL_2, jump_max_until_2,
1256
90.2M
                        ctx->u.rep->pattern+3);
1257
90.2M
                LAST_PTR_POP();
1258
90.2M
                if (ret) {
1259
83.5M
                    MARK_POP_DISCARD(ctx->lastmark);
1260
83.5M
                    RETURN_ON_ERROR(ret);
1261
83.5M
                    RETURN_SUCCESS;
1262
83.5M
                }
1263
6.70M
                MARK_POP(ctx->lastmark);
1264
6.70M
                LASTMARK_RESTORE();
1265
6.70M
                ctx->u.rep->count = ctx->count-1;
1266
6.70M
                state->ptr = ptr;
1267
6.70M
            }
1268
1269
            /* cannot match more repeated items here.  make sure the
1270
               tail matches */
1271
7.10M
            state->repeat = ctx->u.rep->prev;
1272
7.10M
            state->save_marks--;
1273
7.10M
            DO_JUMP(JUMP_MAX_UNTIL_3, jump_max_until_3, pattern);
1274
7.10M
            state->repeat = ctx->u.rep; // restore repeat before return
1275
7.10M
            state->save_marks++;
1276
1277
7.10M
            RETURN_ON_SUCCESS(ret);
1278
62.4k
            state->ptr = ptr;
1279
62.4k
            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
74.0M
        TARGET(SRE_OP_ASSERT_NOT):
1635
            /* assert not subpattern */
1636
            /* <ASSERT_NOT> <skip> <back> <pattern> */
1637
74.0M
            TRACE(("|%p|%p|ASSERT_NOT %d\n", pattern,
1638
74.0M
                   ptr, pattern[1]));
1639
74.0M
            if ((uintptr_t)(ptr - (SRE_CHAR *)state->beginning) >= pattern[1]) {
1640
74.0M
                state->ptr = ptr - pattern[1];
1641
74.0M
                LASTMARK_SAVE();
1642
74.0M
                if (state->save_marks)
1643
74.0M
                    MARK_PUSH(ctx->lastmark);
1644
1645
148M
                DO_JUMP0(JUMP_ASSERT_NOT, jump_assert_not, pattern+2);
1646
148M
                if (ret) {
1647
326k
                    if (state->save_marks)
1648
326k
                        MARK_POP_DISCARD(ctx->lastmark);
1649
326k
                    RETURN_ON_ERROR(ret);
1650
326k
                    RETURN_FAILURE;
1651
326k
                }
1652
73.6M
                if (state->save_marks)
1653
73.6M
                    MARK_POP(ctx->lastmark);
1654
73.6M
                LASTMARK_RESTORE();
1655
73.6M
            }
1656
73.6M
            pattern += pattern[0];
1657
73.6M
            DISPATCH;
1658
1659
73.6M
        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
422M
exit:
1681
422M
    ctx_pos = ctx->last_ctx_pos;
1682
422M
    jump = ctx->jump;
1683
422M
    DATA_POP_DISCARD(ctx);
1684
422M
    if (ctx_pos == -1) {
1685
204M
        state->sigcount = sigcount;
1686
204M
        return ret;
1687
204M
    }
1688
217M
    DATA_LOOKUP_AT(SRE(match_context), ctx, ctx_pos);
1689
1690
217M
    switch (jump) {
1691
90.2M
        case JUMP_MAX_UNTIL_2:
1692
90.2M
            TRACE(("|%p|%p|JUMP_MAX_UNTIL_2\n", pattern, ptr));
1693
90.2M
            goto jump_max_until_2;
1694
7.10M
        case JUMP_MAX_UNTIL_3:
1695
7.10M
            TRACE(("|%p|%p|JUMP_MAX_UNTIL_3\n", pattern, ptr));
1696
7.10M
            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
6.28M
        case JUMP_BRANCH:
1704
6.28M
            TRACE(("|%p|%p|JUMP_BRANCH\n", pattern, ptr));
1705
6.28M
            goto jump_branch;
1706
2.76M
        case JUMP_MAX_UNTIL_1:
1707
2.76M
            TRACE(("|%p|%p|JUMP_MAX_UNTIL_1\n", pattern, ptr));
1708
2.76M
            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
8.66M
        case JUMP_REPEAT:
1719
8.66M
            TRACE(("|%p|%p|JUMP_REPEAT\n", pattern, ptr));
1720
8.66M
            goto jump_repeat;
1721
16.7k
        case JUMP_REPEAT_ONE_1:
1722
16.7k
            TRACE(("|%p|%p|JUMP_REPEAT_ONE_1\n", pattern, ptr));
1723
16.7k
            goto jump_repeat_one_1;
1724
28.3M
        case JUMP_REPEAT_ONE_2:
1725
28.3M
            TRACE(("|%p|%p|JUMP_REPEAT_ONE_2\n", pattern, ptr));
1726
28.3M
            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
74.0M
        case JUMP_ASSERT_NOT:
1737
74.0M
            TRACE(("|%p|%p|JUMP_ASSERT_NOT\n", pattern, ptr));
1738
74.0M
            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
217M
    }
1744
1745
0
    return ret; /* should never get here */
1746
217M
}
sre.c:sre_ucs4_match
Line
Count
Source
663
33.9M
{
664
33.9M
    const SRE_CHAR* end = (const SRE_CHAR *)state->end;
665
33.9M
    Py_ssize_t alloc_pos, ctx_pos = -1;
666
33.9M
    Py_ssize_t ret = 0;
667
33.9M
    int jump;
668
33.9M
    unsigned int sigcount = state->sigcount;
669
670
33.9M
    SRE(match_context)* ctx;
671
33.9M
    SRE(match_context)* nextctx;
672
33.9M
    INIT_TRACE(state);
673
674
33.9M
    TRACE(("|%p|%p|ENTER\n", pattern, state->ptr));
675
676
33.9M
    DATA_ALLOC(SRE(match_context), ctx);
677
33.9M
    ctx->last_ctx_pos = -1;
678
33.9M
    ctx->jump = JUMP_NONE;
679
33.9M
    ctx->toplevel = toplevel;
680
33.9M
    ctx_pos = alloc_pos;
681
682
33.9M
#if USE_COMPUTED_GOTOS
683
33.9M
#include "sre_targets.h"
684
33.9M
#endif
685
686
112M
entrance:
687
688
112M
    ;  // Fashion statement.
689
112M
    const SRE_CHAR *ptr = (SRE_CHAR *)state->ptr;
690
691
112M
    if (pattern[0] == SRE_OP_INFO) {
692
        /* optimization info block */
693
        /* <INFO> <1=skip> <2=flags> <3=min> ... */
694
388k
        if (pattern[3] && (uintptr_t)(end - ptr) < pattern[3]) {
695
4.63k
            TRACE(("reject (got %tu chars, need %zu)\n",
696
4.63k
                   end - ptr, (size_t) pattern[3]));
697
4.63k
            RETURN_FAILURE;
698
4.63k
        }
699
383k
        pattern += pattern[1] + 1;
700
383k
    }
701
702
112M
#if USE_COMPUTED_GOTOS
703
112M
    DISPATCH;
704
#else
705
dispatch:
706
    MAYBE_CHECK_SIGNALS;
707
    switch (*pattern++)
708
#endif
709
112M
    {
710
711
112M
        TARGET(SRE_OP_MARK):
712
            /* set mark */
713
            /* <MARK> <gid> */
714
35.2M
            TRACE(("|%p|%p|MARK %d\n", pattern,
715
35.2M
                   ptr, pattern[0]));
716
35.2M
            {
717
35.2M
                int i = pattern[0];
718
35.2M
                if (i & 1)
719
6.69M
                    state->lastindex = i/2 + 1;
720
35.2M
                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
35.1M
                    int j = state->lastmark + 1;
726
35.2M
                    while (j < i)
727
40.2k
                        state->mark[j++] = NULL;
728
35.1M
                    state->lastmark = i;
729
35.1M
                }
730
35.2M
                state->mark[i] = ptr;
731
35.2M
            }
732
35.2M
            pattern++;
733
35.2M
            DISPATCH;
734
735
35.2M
        TARGET(SRE_OP_LITERAL):
736
            /* match literal string */
737
            /* <LITERAL> <code> */
738
6.82M
            TRACE(("|%p|%p|LITERAL %d\n", pattern,
739
6.82M
                   ptr, *pattern));
740
6.82M
            if (ptr >= end || (SRE_CODE) ptr[0] != pattern[0])
741
6.13M
                RETURN_FAILURE;
742
684k
            pattern++;
743
684k
            ptr++;
744
684k
            DISPATCH;
745
746
684k
        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
5.65M
        TARGET(SRE_OP_SUCCESS):
758
            /* end of pattern */
759
5.65M
            TRACE(("|%p|%p|SUCCESS\n", pattern, ptr));
760
5.65M
            if (ctx->toplevel &&
761
321k
                ((state->match_all && ptr != state->end) ||
762
321k
                 (state->must_advance && ptr == state->start)))
763
0
            {
764
0
                RETURN_FAILURE;
765
0
            }
766
5.65M
            state->ptr = ptr;
767
5.65M
            RETURN_SUCCESS;
768
769
543k
        TARGET(SRE_OP_AT):
770
            /* match at given position */
771
            /* <AT> <code> */
772
543k
            TRACE(("|%p|%p|AT %d\n", pattern, ptr, *pattern));
773
543k
            if (!SRE(at)(state, ptr, *pattern))
774
508k
                RETURN_FAILURE;
775
34.9k
            pattern++;
776
34.9k
            DISPATCH;
777
778
20.6M
        TARGET(SRE_OP_CATEGORY):
779
            /* match at given category */
780
            /* <CATEGORY> <code> */
781
20.6M
            TRACE(("|%p|%p|CATEGORY %d\n", pattern,
782
20.6M
                   ptr, *pattern));
783
20.6M
            if (ptr >= end || !sre_category(pattern[0], ptr[0]))
784
1.72M
                RETURN_FAILURE;
785
18.9M
            pattern++;
786
18.9M
            ptr++;
787
18.9M
            DISPATCH;
788
789
18.9M
        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
38.7M
        TARGET(SRE_OP_IN):
808
            /* match set member (or non_member) */
809
            /* <IN> <skip> <set> */
810
38.7M
            TRACE(("|%p|%p|IN\n", pattern, ptr));
811
38.7M
            if (ptr >= end ||
812
38.7M
                !SRE(charset)(state, pattern + 1, *ptr))
813
20.6M
                RETURN_FAILURE;
814
18.0M
            pattern += pattern[0];
815
18.0M
            ptr++;
816
18.0M
            DISPATCH;
817
818
18.0M
        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
559k
        TARGET(SRE_OP_JUMP):
908
559k
        TARGET(SRE_OP_INFO):
909
            /* jump forward */
910
            /* <JUMP> <offset> */
911
559k
            TRACE(("|%p|%p|JUMP %d\n", pattern,
912
559k
                   ptr, pattern[0]));
913
559k
            pattern += pattern[0];
914
559k
            DISPATCH;
915
916
611k
        TARGET(SRE_OP_BRANCH):
917
            /* alternation */
918
            /* <BRANCH> <0=skip> code <JUMP> ... <NULL> */
919
611k
            TRACE(("|%p|%p|BRANCH\n", pattern, ptr));
920
611k
            LASTMARK_SAVE();
921
611k
            if (state->save_marks)
922
2.88k
                MARK_PUSH(ctx->lastmark);
923
2.19M
            for (; pattern[0]; pattern += pattern[0]) {
924
1.66M
                if (pattern[1] == SRE_OP_LITERAL &&
925
1.56M
                    (ptr >= end ||
926
1.56M
                     (SRE_CODE) *ptr != pattern[2]))
927
904k
                    continue;
928
761k
                if (pattern[1] == SRE_OP_IN &&
929
41.6k
                    (ptr >= end ||
930
41.6k
                     !SRE(charset)(state, pattern + 3,
931
41.6k
                                   (SRE_CODE) *ptr)))
932
12.1k
                    continue;
933
749k
                state->ptr = ptr;
934
749k
                DO_JUMP(JUMP_BRANCH, jump_branch, pattern+1);
935
749k
                if (ret) {
936
85.0k
                    if (state->save_marks)
937
1.63k
                        MARK_POP_DISCARD(ctx->lastmark);
938
85.0k
                    RETURN_ON_ERROR(ret);
939
85.0k
                    RETURN_SUCCESS;
940
85.0k
                }
941
664k
                if (state->save_marks)
942
2.13k
                    MARK_POP_KEEP(ctx->lastmark);
943
664k
                LASTMARK_RESTORE();
944
664k
            }
945
526k
            if (state->save_marks)
946
1.25k
                MARK_POP_DISCARD(ctx->lastmark);
947
526k
            RETURN_FAILURE;
948
949
41.1M
        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
41.1M
            TRACE(("|%p|%p|REPEAT_ONE %d %d\n", pattern, ptr,
960
41.1M
                   pattern[1], pattern[2]));
961
962
41.1M
            if ((Py_ssize_t) pattern[1] > end - ptr)
963
9.52k
                RETURN_FAILURE; /* cannot match */
964
965
41.1M
            state->ptr = ptr;
966
967
41.1M
            ret = SRE(count)(state, pattern+3, pattern[2]);
968
41.1M
            RETURN_ON_ERROR(ret);
969
41.1M
            DATA_LOOKUP_AT(SRE(match_context), ctx, ctx_pos);
970
41.1M
            ctx->count = ret;
971
41.1M
            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
41.1M
            if (ctx->count < (Py_ssize_t) pattern[1])
979
27.7M
                RETURN_FAILURE;
980
981
13.3M
            if (pattern[pattern[0]] == SRE_OP_SUCCESS &&
982
273k
                ptr == state->end &&
983
2.11k
                !(ctx->toplevel && state->must_advance && ptr == state->start))
984
2.11k
            {
985
                /* tail is empty.  we're finished */
986
2.11k
                state->ptr = ptr;
987
2.11k
                RETURN_SUCCESS;
988
2.11k
            }
989
990
13.3M
            LASTMARK_SAVE();
991
13.3M
            if (state->save_marks)
992
12.9M
                MARK_PUSH(ctx->lastmark);
993
994
13.3M
            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
3.51k
                ctx->u.chr = pattern[pattern[0]+1];
998
3.51k
                for (;;) {
999
2.64M
                    while (ctx->count >= (Py_ssize_t) pattern[1] &&
1000
2.64M
                           (ptr >= end || *ptr != ctx->u.chr)) {
1001
2.63M
                        ptr--;
1002
2.63M
                        ctx->count--;
1003
2.63M
                    }
1004
3.51k
                    if (ctx->count < (Py_ssize_t) pattern[1])
1005
1.52k
                        break;
1006
1.98k
                    state->ptr = ptr;
1007
1.98k
                    DO_JUMP(JUMP_REPEAT_ONE_1, jump_repeat_one_1,
1008
1.98k
                            pattern+pattern[0]);
1009
1.98k
                    if (ret) {
1010
1.98k
                        if (state->save_marks)
1011
0
                            MARK_POP_DISCARD(ctx->lastmark);
1012
1.98k
                        RETURN_ON_ERROR(ret);
1013
1.98k
                        RETURN_SUCCESS;
1014
1.98k
                    }
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
1.52k
                if (state->save_marks)
1023
0
                    MARK_POP_DISCARD(ctx->lastmark);
1024
13.3M
            } else {
1025
                /* general case */
1026
19.3M
                while (ctx->count >= (Py_ssize_t) pattern[1]) {
1027
19.3M
                    state->ptr = ptr;
1028
19.3M
                    DO_JUMP(JUMP_REPEAT_ONE_2, jump_repeat_one_2,
1029
19.3M
                            pattern+pattern[0]);
1030
19.3M
                    if (ret) {
1031
13.2M
                        if (state->save_marks)
1032
12.8M
                            MARK_POP_DISCARD(ctx->lastmark);
1033
13.2M
                        RETURN_ON_ERROR(ret);
1034
13.2M
                        RETURN_SUCCESS;
1035
13.2M
                    }
1036
6.03M
                    if (state->save_marks)
1037
91.9k
                        MARK_POP_KEEP(ctx->lastmark);
1038
6.03M
                    LASTMARK_RESTORE();
1039
1040
6.03M
                    ptr--;
1041
6.03M
                    ctx->count--;
1042
6.03M
                }
1043
61.8k
                if (state->save_marks)
1044
57.5k
                    MARK_POP_DISCARD(ctx->lastmark);
1045
61.8k
            }
1046
63.3k
            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
1.84M
        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
1.84M
            TRACE(("|%p|%p|REPEAT %d %d\n", pattern, ptr,
1186
1.84M
                   pattern[1], pattern[2]));
1187
1188
            /* install new repeat context */
1189
1.84M
            ctx->u.rep = repeat_pool_malloc(state);
1190
1.84M
            if (!ctx->u.rep) {
1191
0
                RETURN_ERROR(SRE_ERROR_MEMORY);
1192
0
            }
1193
1.84M
            ctx->u.rep->count = -1;
1194
1.84M
            ctx->u.rep->pattern = pattern;
1195
1.84M
            ctx->u.rep->prev = state->repeat;
1196
1.84M
            ctx->u.rep->last_ptr = NULL;
1197
1.84M
            state->repeat = ctx->u.rep;
1198
1.84M
            state->save_marks++;
1199
1200
1.84M
            state->ptr = ptr;
1201
1.84M
            DO_JUMP(JUMP_REPEAT, jump_repeat, pattern+pattern[0]);
1202
1.84M
            state->repeat = ctx->u.rep->prev;
1203
1.84M
            state->save_marks--;
1204
1.84M
            repeat_pool_free(state, ctx->u.rep);
1205
1206
1.84M
            if (ret) {
1207
1.81M
                RETURN_ON_ERROR(ret);
1208
1.81M
                RETURN_SUCCESS;
1209
1.81M
            }
1210
33.0k
            RETURN_FAILURE;
1211
1212
34.4M
        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
34.4M
            ctx->u.rep = state->repeat;
1220
34.4M
            if (!ctx->u.rep)
1221
0
                RETURN_ERROR(SRE_ERROR_STATE);
1222
1223
34.4M
            state->ptr = ptr;
1224
1225
34.4M
            ctx->count = ctx->u.rep->count+1;
1226
1227
34.4M
            TRACE(("|%p|%p|MAX_UNTIL %zd\n", pattern,
1228
34.4M
                   ptr, ctx->count));
1229
1230
34.4M
            if (ctx->count < (Py_ssize_t) ctx->u.rep->pattern[1]) {
1231
                /* not enough matches */
1232
1.72M
                ctx->u.rep->count = ctx->count;
1233
1.72M
                DO_JUMP(JUMP_MAX_UNTIL_1, jump_max_until_1,
1234
1.72M
                        ctx->u.rep->pattern+3);
1235
1.72M
                if (ret) {
1236
1.69M
                    RETURN_ON_ERROR(ret);
1237
1.69M
                    RETURN_SUCCESS;
1238
1.69M
                }
1239
32.4k
                ctx->u.rep->count = ctx->count-1;
1240
32.4k
                state->ptr = ptr;
1241
32.4k
                RETURN_FAILURE;
1242
32.4k
            }
1243
1244
32.7M
            if ((ctx->count < (Py_ssize_t) ctx->u.rep->pattern[2] ||
1245
54.3k
                ctx->u.rep->pattern[2] == SRE_MAXREPEAT) &&
1246
32.6M
                state->ptr != ctx->u.rep->last_ptr) {
1247
                /* we may have enough matches, but if we can
1248
                   match another item, do so */
1249
32.6M
                ctx->u.rep->count = ctx->count;
1250
32.6M
                LASTMARK_SAVE();
1251
32.6M
                MARK_PUSH(ctx->lastmark);
1252
                /* zero-width match protection */
1253
32.6M
                LAST_PTR_PUSH();
1254
32.6M
                ctx->u.rep->last_ptr = state->ptr;
1255
32.6M
                DO_JUMP(JUMP_MAX_UNTIL_2, jump_max_until_2,
1256
32.6M
                        ctx->u.rep->pattern+3);
1257
32.6M
                LAST_PTR_POP();
1258
32.6M
                if (ret) {
1259
30.8M
                    MARK_POP_DISCARD(ctx->lastmark);
1260
30.8M
                    RETURN_ON_ERROR(ret);
1261
30.8M
                    RETURN_SUCCESS;
1262
30.8M
                }
1263
1.81M
                MARK_POP(ctx->lastmark);
1264
1.81M
                LASTMARK_RESTORE();
1265
1.81M
                ctx->u.rep->count = ctx->count-1;
1266
1.81M
                state->ptr = ptr;
1267
1.81M
            }
1268
1269
            /* cannot match more repeated items here.  make sure the
1270
               tail matches */
1271
1.86M
            state->repeat = ctx->u.rep->prev;
1272
1.86M
            state->save_marks--;
1273
1.86M
            DO_JUMP(JUMP_MAX_UNTIL_3, jump_max_until_3, pattern);
1274
1.86M
            state->repeat = ctx->u.rep; // restore repeat before return
1275
1.86M
            state->save_marks++;
1276
1277
1.86M
            RETURN_ON_SUCCESS(ret);
1278
53.8k
            state->ptr = ptr;
1279
53.8k
            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
20.6M
        TARGET(SRE_OP_ASSERT_NOT):
1635
            /* assert not subpattern */
1636
            /* <ASSERT_NOT> <skip> <back> <pattern> */
1637
20.6M
            TRACE(("|%p|%p|ASSERT_NOT %d\n", pattern,
1638
20.6M
                   ptr, pattern[1]));
1639
20.6M
            if ((uintptr_t)(ptr - (SRE_CHAR *)state->beginning) >= pattern[1]) {
1640
20.6M
                state->ptr = ptr - pattern[1];
1641
20.6M
                LASTMARK_SAVE();
1642
20.6M
                if (state->save_marks)
1643
20.6M
                    MARK_PUSH(ctx->lastmark);
1644
1645
41.2M
                DO_JUMP0(JUMP_ASSERT_NOT, jump_assert_not, pattern+2);
1646
41.2M
                if (ret) {
1647
16.2k
                    if (state->save_marks)
1648
16.2k
                        MARK_POP_DISCARD(ctx->lastmark);
1649
16.2k
                    RETURN_ON_ERROR(ret);
1650
16.2k
                    RETURN_FAILURE;
1651
16.2k
                }
1652
20.6M
                if (state->save_marks)
1653
20.6M
                    MARK_POP(ctx->lastmark);
1654
20.6M
                LASTMARK_RESTORE();
1655
20.6M
            }
1656
20.6M
            pattern += pattern[0];
1657
20.6M
            DISPATCH;
1658
1659
20.6M
        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
112M
exit:
1681
112M
    ctx_pos = ctx->last_ctx_pos;
1682
112M
    jump = ctx->jump;
1683
112M
    DATA_POP_DISCARD(ctx);
1684
112M
    if (ctx_pos == -1) {
1685
33.9M
        state->sigcount = sigcount;
1686
33.9M
        return ret;
1687
33.9M
    }
1688
78.8M
    DATA_LOOKUP_AT(SRE(match_context), ctx, ctx_pos);
1689
1690
78.8M
    switch (jump) {
1691
32.6M
        case JUMP_MAX_UNTIL_2:
1692
32.6M
            TRACE(("|%p|%p|JUMP_MAX_UNTIL_2\n", pattern, ptr));
1693
32.6M
            goto jump_max_until_2;
1694
1.86M
        case JUMP_MAX_UNTIL_3:
1695
1.86M
            TRACE(("|%p|%p|JUMP_MAX_UNTIL_3\n", pattern, ptr));
1696
1.86M
            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
749k
        case JUMP_BRANCH:
1704
749k
            TRACE(("|%p|%p|JUMP_BRANCH\n", pattern, ptr));
1705
749k
            goto jump_branch;
1706
1.72M
        case JUMP_MAX_UNTIL_1:
1707
1.72M
            TRACE(("|%p|%p|JUMP_MAX_UNTIL_1\n", pattern, ptr));
1708
1.72M
            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
1.84M
        case JUMP_REPEAT:
1719
1.84M
            TRACE(("|%p|%p|JUMP_REPEAT\n", pattern, ptr));
1720
1.84M
            goto jump_repeat;
1721
1.98k
        case JUMP_REPEAT_ONE_1:
1722
1.98k
            TRACE(("|%p|%p|JUMP_REPEAT_ONE_1\n", pattern, ptr));
1723
1.98k
            goto jump_repeat_one_1;
1724
19.3M
        case JUMP_REPEAT_ONE_2:
1725
19.3M
            TRACE(("|%p|%p|JUMP_REPEAT_ONE_2\n", pattern, ptr));
1726
19.3M
            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
20.6M
        case JUMP_ASSERT_NOT:
1737
20.6M
            TRACE(("|%p|%p|JUMP_ASSERT_NOT\n", pattern, ptr));
1738
20.6M
            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
78.8M
    }
1744
1745
0
    return ret; /* should never get here */
1746
78.8M
}
1747
1748
/* need to reset capturing groups between two SRE(match) callings in loops */
1749
#define RESET_CAPTURE_GROUP() \
1750
223M
    do { state->lastmark = state->lastindex = -1; } while (0)
1751
1752
LOCAL(Py_ssize_t)
1753
SRE(search)(SRE_STATE* state, SRE_CODE* pattern)
1754
110M
{
1755
110M
    SRE_CHAR* ptr = (SRE_CHAR *)state->start;
1756
110M
    SRE_CHAR* end = (SRE_CHAR *)state->end;
1757
110M
    Py_ssize_t status = 0;
1758
110M
    Py_ssize_t prefix_len = 0;
1759
110M
    Py_ssize_t prefix_skip = 0;
1760
110M
    SRE_CODE* prefix = NULL;
1761
110M
    SRE_CODE* charset = NULL;
1762
110M
    SRE_CODE* overlap = NULL;
1763
110M
    int flags = 0;
1764
110M
    INIT_TRACE(state);
1765
1766
110M
    if (ptr > end)
1767
0
        return 0;
1768
1769
110M
    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
110M
        flags = pattern[2];
1774
1775
110M
        if (pattern[3] && (uintptr_t)(end - ptr) < pattern[3]) {
1776
2.75M
            TRACE(("reject (got %tu chars, need %zu)\n",
1777
2.75M
                   end - ptr, (size_t) pattern[3]));
1778
2.75M
            return 0;
1779
2.75M
        }
1780
107M
        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
51.0k
            end -= pattern[3] - 1;
1784
51.0k
            if (end <= ptr)
1785
0
                end = ptr;
1786
51.0k
        }
1787
1788
107M
        if (flags & SRE_INFO_PREFIX) {
1789
            /* pattern starts with a known prefix */
1790
            /* <length> <skip> <prefix data> <overlap data> */
1791
51.0k
            prefix_len = pattern[5];
1792
51.0k
            prefix_skip = pattern[6];
1793
51.0k
            prefix = pattern + 7;
1794
51.0k
            overlap = prefix + prefix_len - 1;
1795
107M
        } else if (flags & SRE_INFO_CHARSET)
1796
            /* pattern starts with a character from a known set */
1797
            /* <charset> */
1798
97.8M
            charset = pattern + 5;
1799
1800
107M
        pattern += 1 + pattern[1];
1801
107M
    }
1802
1803
107M
    TRACE(("prefix = %p %zd %zd\n",
1804
107M
           prefix, prefix_len, prefix_skip));
1805
107M
    TRACE(("charset = %p\n", charset));
1806
1807
107M
    if (prefix_len == 1) {
1808
        /* pattern starts with a literal character */
1809
51.0k
        SRE_CHAR c = (SRE_CHAR) prefix[0];
1810
#if SIZEOF_SRE_CHAR < 4
1811
51.0k
        if ((SRE_CODE) c != prefix[0])
1812
0
            return 0; /* literal can't match: doesn't fit in char width */
1813
51.0k
#endif
1814
51.0k
        end = (SRE_CHAR *)state->end;
1815
51.0k
        state->must_advance = 0;
1816
82.0k
        while (ptr < end) {
1817
13.8M
            while (*ptr != c) {
1818
13.7M
                if (++ptr >= end)
1819
17.8k
                    return 0;
1820
13.7M
            }
1821
61.1k
            TRACE(("|%p|%p|SEARCH LITERAL\n", pattern, ptr));
1822
61.1k
            state->start = ptr;
1823
61.1k
            state->ptr = ptr + prefix_skip;
1824
61.1k
            if (flags & SRE_INFO_LITERAL)
1825
0
                return 1; /* we got all of it */
1826
61.1k
            status = SRE(match)(state, pattern + 2*prefix_skip, 0);
1827
61.1k
            if (status != 0)
1828
30.1k
                return status;
1829
31.0k
            ++ptr;
1830
31.0k
            RESET_CAPTURE_GROUP();
1831
31.0k
        }
1832
3.03k
        return 0;
1833
51.0k
    }
1834
1835
107M
    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
107M
    if (charset) {
1887
        /* pattern starts with a character from a known set */
1888
97.8M
        end = (SRE_CHAR *)state->end;
1889
97.8M
        state->must_advance = 0;
1890
100M
        for (;;) {
1891
400M
            while (ptr < end && !SRE(charset)(state, charset, *ptr))
1892
299M
                ptr++;
1893
100M
            if (ptr >= end)
1894
4.04M
                return 0;
1895
96.7M
            TRACE(("|%p|%p|SEARCH CHARSET\n", pattern, ptr));
1896
96.7M
            state->start = ptr;
1897
96.7M
            state->ptr = ptr;
1898
96.7M
            status = SRE(match)(state, pattern, 0);
1899
96.7M
            if (status != 0)
1900
93.8M
                break;
1901
2.97M
            ptr++;
1902
2.97M
            RESET_CAPTURE_GROUP();
1903
2.97M
        }
1904
97.8M
    } else {
1905
        /* general case */
1906
10.0M
        assert(ptr <= end);
1907
10.0M
        TRACE(("|%p|%p|SEARCH\n", pattern, ptr));
1908
10.0M
        state->start = state->ptr = ptr;
1909
10.0M
        status = SRE(match)(state, pattern, 1);
1910
10.0M
        state->must_advance = 0;
1911
10.0M
        if (status == 0 && pattern[0] == SRE_OP_AT &&
1912
5.32M
            (pattern[1] == SRE_AT_BEGINNING ||
1913
0
             pattern[1] == SRE_AT_BEGINNING_STRING))
1914
5.32M
        {
1915
5.32M
            state->start = state->ptr = ptr = end;
1916
5.32M
            return 0;
1917
5.32M
        }
1918
225M
        while (status == 0 && ptr < end) {
1919
220M
            ptr++;
1920
220M
            RESET_CAPTURE_GROUP();
1921
220M
            TRACE(("|%p|%p|SEARCH\n", pattern, ptr));
1922
220M
            state->start = state->ptr = ptr;
1923
220M
            status = SRE(match)(state, pattern, 0);
1924
220M
        }
1925
4.72M
    }
1926
1927
98.5M
    return status;
1928
107M
}
sre.c:sre_ucs1_search
Line
Count
Source
1754
50.9M
{
1755
50.9M
    SRE_CHAR* ptr = (SRE_CHAR *)state->start;
1756
50.9M
    SRE_CHAR* end = (SRE_CHAR *)state->end;
1757
50.9M
    Py_ssize_t status = 0;
1758
50.9M
    Py_ssize_t prefix_len = 0;
1759
50.9M
    Py_ssize_t prefix_skip = 0;
1760
50.9M
    SRE_CODE* prefix = NULL;
1761
50.9M
    SRE_CODE* charset = NULL;
1762
50.9M
    SRE_CODE* overlap = NULL;
1763
50.9M
    int flags = 0;
1764
50.9M
    INIT_TRACE(state);
1765
1766
50.9M
    if (ptr > end)
1767
0
        return 0;
1768
1769
50.9M
    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
50.9M
        flags = pattern[2];
1774
1775
50.9M
        if (pattern[3] && (uintptr_t)(end - ptr) < pattern[3]) {
1776
2.67M
            TRACE(("reject (got %tu chars, need %zu)\n",
1777
2.67M
                   end - ptr, (size_t) pattern[3]));
1778
2.67M
            return 0;
1779
2.67M
        }
1780
48.2M
        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
51.0k
            end -= pattern[3] - 1;
1784
51.0k
            if (end <= ptr)
1785
0
                end = ptr;
1786
51.0k
        }
1787
1788
48.2M
        if (flags & SRE_INFO_PREFIX) {
1789
            /* pattern starts with a known prefix */
1790
            /* <length> <skip> <prefix data> <overlap data> */
1791
51.0k
            prefix_len = pattern[5];
1792
51.0k
            prefix_skip = pattern[6];
1793
51.0k
            prefix = pattern + 7;
1794
51.0k
            overlap = prefix + prefix_len - 1;
1795
48.1M
        } else if (flags & SRE_INFO_CHARSET)
1796
            /* pattern starts with a character from a known set */
1797
            /* <charset> */
1798
40.8M
            charset = pattern + 5;
1799
1800
48.2M
        pattern += 1 + pattern[1];
1801
48.2M
    }
1802
1803
48.2M
    TRACE(("prefix = %p %zd %zd\n",
1804
48.2M
           prefix, prefix_len, prefix_skip));
1805
48.2M
    TRACE(("charset = %p\n", charset));
1806
1807
48.2M
    if (prefix_len == 1) {
1808
        /* pattern starts with a literal character */
1809
51.0k
        SRE_CHAR c = (SRE_CHAR) prefix[0];
1810
51.0k
#if SIZEOF_SRE_CHAR < 4
1811
51.0k
        if ((SRE_CODE) c != prefix[0])
1812
0
            return 0; /* literal can't match: doesn't fit in char width */
1813
51.0k
#endif
1814
51.0k
        end = (SRE_CHAR *)state->end;
1815
51.0k
        state->must_advance = 0;
1816
82.0k
        while (ptr < end) {
1817
13.8M
            while (*ptr != c) {
1818
13.7M
                if (++ptr >= end)
1819
17.8k
                    return 0;
1820
13.7M
            }
1821
61.1k
            TRACE(("|%p|%p|SEARCH LITERAL\n", pattern, ptr));
1822
61.1k
            state->start = ptr;
1823
61.1k
            state->ptr = ptr + prefix_skip;
1824
61.1k
            if (flags & SRE_INFO_LITERAL)
1825
0
                return 1; /* we got all of it */
1826
61.1k
            status = SRE(match)(state, pattern + 2*prefix_skip, 0);
1827
61.1k
            if (status != 0)
1828
30.1k
                return status;
1829
31.0k
            ++ptr;
1830
31.0k
            RESET_CAPTURE_GROUP();
1831
31.0k
        }
1832
3.03k
        return 0;
1833
51.0k
    }
1834
1835
48.1M
    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
0
#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
48.1M
    if (charset) {
1887
        /* pattern starts with a character from a known set */
1888
40.8M
        end = (SRE_CHAR *)state->end;
1889
40.8M
        state->must_advance = 0;
1890
42.5M
        for (;;) {
1891
108M
            while (ptr < end && !SRE(charset)(state, charset, *ptr))
1892
65.7M
                ptr++;
1893
42.5M
            if (ptr >= end)
1894
2.97M
                return 0;
1895
39.5M
            TRACE(("|%p|%p|SEARCH CHARSET\n", pattern, ptr));
1896
39.5M
            state->start = ptr;
1897
39.5M
            state->ptr = ptr;
1898
39.5M
            status = SRE(match)(state, pattern, 0);
1899
39.5M
            if (status != 0)
1900
37.8M
                break;
1901
1.67M
            ptr++;
1902
1.67M
            RESET_CAPTURE_GROUP();
1903
1.67M
        }
1904
40.8M
    } else {
1905
        /* general case */
1906
7.34M
        assert(ptr <= end);
1907
7.34M
        TRACE(("|%p|%p|SEARCH\n", pattern, ptr));
1908
7.34M
        state->start = state->ptr = ptr;
1909
7.34M
        status = SRE(match)(state, pattern, 1);
1910
7.34M
        state->must_advance = 0;
1911
7.34M
        if (status == 0 && pattern[0] == SRE_OP_AT &&
1912
3.59M
            (pattern[1] == SRE_AT_BEGINNING ||
1913
0
             pattern[1] == SRE_AT_BEGINNING_STRING))
1914
3.59M
        {
1915
3.59M
            state->start = state->ptr = ptr = end;
1916
3.59M
            return 0;
1917
3.59M
        }
1918
52.4M
        while (status == 0 && ptr < end) {
1919
48.7M
            ptr++;
1920
48.7M
            RESET_CAPTURE_GROUP();
1921
48.7M
            TRACE(("|%p|%p|SEARCH\n", pattern, ptr));
1922
48.7M
            state->start = state->ptr = ptr;
1923
48.7M
            status = SRE(match)(state, pattern, 0);
1924
48.7M
        }
1925
3.74M
    }
1926
1927
41.6M
    return status;
1928
48.1M
}
sre.c:sre_ucs2_search
Line
Count
Source
1754
54.4M
{
1755
54.4M
    SRE_CHAR* ptr = (SRE_CHAR *)state->start;
1756
54.4M
    SRE_CHAR* end = (SRE_CHAR *)state->end;
1757
54.4M
    Py_ssize_t status = 0;
1758
54.4M
    Py_ssize_t prefix_len = 0;
1759
54.4M
    Py_ssize_t prefix_skip = 0;
1760
54.4M
    SRE_CODE* prefix = NULL;
1761
54.4M
    SRE_CODE* charset = NULL;
1762
54.4M
    SRE_CODE* overlap = NULL;
1763
54.4M
    int flags = 0;
1764
54.4M
    INIT_TRACE(state);
1765
1766
54.4M
    if (ptr > end)
1767
0
        return 0;
1768
1769
54.4M
    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
54.4M
        flags = pattern[2];
1774
1775
54.4M
        if (pattern[3] && (uintptr_t)(end - ptr) < pattern[3]) {
1776
74.9k
            TRACE(("reject (got %tu chars, need %zu)\n",
1777
74.9k
                   end - ptr, (size_t) pattern[3]));
1778
74.9k
            return 0;
1779
74.9k
        }
1780
54.3M
        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
54.3M
        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
54.3M
        } else if (flags & SRE_INFO_CHARSET)
1796
            /* pattern starts with a character from a known set */
1797
            /* <charset> */
1798
51.7M
            charset = pattern + 5;
1799
1800
54.3M
        pattern += 1 + pattern[1];
1801
54.3M
    }
1802
1803
54.3M
    TRACE(("prefix = %p %zd %zd\n",
1804
54.3M
           prefix, prefix_len, prefix_skip));
1805
54.3M
    TRACE(("charset = %p\n", charset));
1806
1807
54.3M
    if (prefix_len == 1) {
1808
        /* pattern starts with a literal character */
1809
0
        SRE_CHAR c = (SRE_CHAR) prefix[0];
1810
0
#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
54.3M
    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
0
#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
54.3M
    if (charset) {
1887
        /* pattern starts with a character from a known set */
1888
51.7M
        end = (SRE_CHAR *)state->end;
1889
51.7M
        state->must_advance = 0;
1890
52.6M
        for (;;) {
1891
226M
            while (ptr < end && !SRE(charset)(state, charset, *ptr))
1892
173M
                ptr++;
1893
52.6M
            if (ptr >= end)
1894
1.01M
                return 0;
1895
51.5M
            TRACE(("|%p|%p|SEARCH CHARSET\n", pattern, ptr));
1896
51.5M
            state->start = ptr;
1897
51.5M
            state->ptr = ptr;
1898
51.5M
            status = SRE(match)(state, pattern, 0);
1899
51.5M
            if (status != 0)
1900
50.7M
                break;
1901
829k
            ptr++;
1902
829k
            RESET_CAPTURE_GROUP();
1903
829k
        }
1904
51.7M
    } else {
1905
        /* general case */
1906
2.55M
        assert(ptr <= end);
1907
2.55M
        TRACE(("|%p|%p|SEARCH\n", pattern, ptr));
1908
2.55M
        state->start = state->ptr = ptr;
1909
2.55M
        status = SRE(match)(state, pattern, 1);
1910
2.55M
        state->must_advance = 0;
1911
2.55M
        if (status == 0 && pattern[0] == SRE_OP_AT &&
1912
1.71M
            (pattern[1] == SRE_AT_BEGINNING ||
1913
0
             pattern[1] == SRE_AT_BEGINNING_STRING))
1914
1.71M
        {
1915
1.71M
            state->start = state->ptr = ptr = end;
1916
1.71M
            return 0;
1917
1.71M
        }
1918
145M
        while (status == 0 && ptr < end) {
1919
144M
            ptr++;
1920
144M
            RESET_CAPTURE_GROUP();
1921
144M
            TRACE(("|%p|%p|SEARCH\n", pattern, ptr));
1922
144M
            state->start = state->ptr = ptr;
1923
144M
            status = SRE(match)(state, pattern, 0);
1924
144M
        }
1925
838k
    }
1926
1927
51.6M
    return status;
1928
54.3M
}
sre.c:sre_ucs4_search
Line
Count
Source
1754
5.39M
{
1755
5.39M
    SRE_CHAR* ptr = (SRE_CHAR *)state->start;
1756
5.39M
    SRE_CHAR* end = (SRE_CHAR *)state->end;
1757
5.39M
    Py_ssize_t status = 0;
1758
5.39M
    Py_ssize_t prefix_len = 0;
1759
5.39M
    Py_ssize_t prefix_skip = 0;
1760
5.39M
    SRE_CODE* prefix = NULL;
1761
5.39M
    SRE_CODE* charset = NULL;
1762
5.39M
    SRE_CODE* overlap = NULL;
1763
5.39M
    int flags = 0;
1764
5.39M
    INIT_TRACE(state);
1765
1766
5.39M
    if (ptr > end)
1767
0
        return 0;
1768
1769
5.39M
    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
5.39M
        flags = pattern[2];
1774
1775
5.39M
        if (pattern[3] && (uintptr_t)(end - ptr) < pattern[3]) {
1776
3.62k
            TRACE(("reject (got %tu chars, need %zu)\n",
1777
3.62k
                   end - ptr, (size_t) pattern[3]));
1778
3.62k
            return 0;
1779
3.62k
        }
1780
5.39M
        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
5.39M
        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
5.39M
        } else if (flags & SRE_INFO_CHARSET)
1796
            /* pattern starts with a character from a known set */
1797
            /* <charset> */
1798
5.24M
            charset = pattern + 5;
1799
1800
5.39M
        pattern += 1 + pattern[1];
1801
5.39M
    }
1802
1803
5.39M
    TRACE(("prefix = %p %zd %zd\n",
1804
5.39M
           prefix, prefix_len, prefix_skip));
1805
5.39M
    TRACE(("charset = %p\n", charset));
1806
1807
5.39M
    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
        if ((SRE_CODE) c != prefix[0])
1812
            return 0; /* literal can't match: doesn't fit in char width */
1813
#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
5.39M
    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
        for (i = 0; i < prefix_len; i++)
1845
            if ((SRE_CODE)(SRE_CHAR) prefix[i] != prefix[i])
1846
                return 0; /* literal can't match: doesn't fit in char width */
1847
#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
5.39M
    if (charset) {
1887
        /* pattern starts with a character from a known set */
1888
5.24M
        end = (SRE_CHAR *)state->end;
1889
5.24M
        state->must_advance = 0;
1890
5.71M
        for (;;) {
1891
65.3M
            while (ptr < end && !SRE(charset)(state, charset, *ptr))
1892
59.6M
                ptr++;
1893
5.71M
            if (ptr >= end)
1894
52.9k
                return 0;
1895
5.66M
            TRACE(("|%p|%p|SEARCH CHARSET\n", pattern, ptr));
1896
5.66M
            state->start = ptr;
1897
5.66M
            state->ptr = ptr;
1898
5.66M
            status = SRE(match)(state, pattern, 0);
1899
5.66M
            if (status != 0)
1900
5.18M
                break;
1901
473k
            ptr++;
1902
473k
            RESET_CAPTURE_GROUP();
1903
473k
        }
1904
5.24M
    } else {
1905
        /* general case */
1906
154k
        assert(ptr <= end);
1907
154k
        TRACE(("|%p|%p|SEARCH\n", pattern, ptr));
1908
154k
        state->start = state->ptr = ptr;
1909
154k
        status = SRE(match)(state, pattern, 1);
1910
154k
        state->must_advance = 0;
1911
154k
        if (status == 0 && pattern[0] == SRE_OP_AT &&
1912
16.2k
            (pattern[1] == SRE_AT_BEGINNING ||
1913
0
             pattern[1] == SRE_AT_BEGINNING_STRING))
1914
16.2k
        {
1915
16.2k
            state->start = state->ptr = ptr = end;
1916
16.2k
            return 0;
1917
16.2k
        }
1918
27.8M
        while (status == 0 && ptr < end) {
1919
27.7M
            ptr++;
1920
27.7M
            RESET_CAPTURE_GROUP();
1921
27.7M
            TRACE(("|%p|%p|SEARCH\n", pattern, ptr));
1922
27.7M
            state->start = state->ptr = ptr;
1923
27.7M
            status = SRE(match)(state, pattern, 0);
1924
27.7M
        }
1925
137k
    }
1926
1927
5.32M
    return status;
1928
5.39M
}
1929
1930
#undef SRE_CHAR
1931
#undef SIZEOF_SRE_CHAR
1932
#undef SRE
1933
1934
/* vim:ts=4:sw=4:et
1935
*/