Coverage Report

Created: 2026-10-17 06:15

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
22.8M
{
18
    /* check if pointer is at given position */
19
20
22.8M
    Py_ssize_t thisp, thatp;
21
22
22.8M
    switch (at) {
23
24
11.1M
    case SRE_AT_BEGINNING:
25
11.1M
    case SRE_AT_BEGINNING_STRING:
26
11.1M
        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.31M
    case SRE_AT_END:
33
8.31M
        return (((SRE_CHAR *)state->end - ptr == 1 &&
34
21.7k
                 SRE_IS_LINEBREAK((int) ptr[0])) ||
35
8.31M
                ((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
3.32M
    case SRE_AT_END_STRING:
42
3.32M
        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
22.8M
    }
87
88
0
    return 0;
89
22.8M
}
sre.c:sre_ucs1_at
Line
Count
Source
17
17.8M
{
18
    /* check if pointer is at given position */
19
20
17.8M
    Py_ssize_t thisp, thatp;
21
22
17.8M
    switch (at) {
23
24
9.41M
    case SRE_AT_BEGINNING:
25
9.41M
    case SRE_AT_BEGINNING_STRING:
26
9.41M
        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.59M
    case SRE_AT_END:
33
6.59M
        return (((SRE_CHAR *)state->end - ptr == 1 &&
34
21.5k
                 SRE_IS_LINEBREAK((int) ptr[0])) ||
35
6.59M
                ((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.80M
    case SRE_AT_END_STRING:
42
1.80M
        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
17.8M
    }
87
88
0
    return 0;
89
17.8M
}
sre.c:sre_ucs2_at
Line
Count
Source
17
4.36M
{
18
    /* check if pointer is at given position */
19
20
4.36M
    Py_ssize_t thisp, thatp;
21
22
4.36M
    switch (at) {
23
24
1.74M
    case SRE_AT_BEGINNING:
25
1.74M
    case SRE_AT_BEGINNING_STRING:
26
1.74M
        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
99
                 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
950k
    case SRE_AT_END_STRING:
42
950k
        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.36M
    }
87
88
0
    return 0;
89
4.36M
}
sre.c:sre_ucs4_at
Line
Count
Source
17
631k
{
18
    /* check if pointer is at given position */
19
20
631k
    Py_ssize_t thisp, thatp;
21
22
631k
    switch (at) {
23
24
21.3k
    case SRE_AT_BEGINNING:
25
21.3k
    case SRE_AT_BEGINNING_STRING:
26
21.3k
        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.4k
    case SRE_AT_END:
33
48.4k
        return (((SRE_CHAR *)state->end - ptr == 1 &&
34
102
                 SRE_IS_LINEBREAK((int) ptr[0])) ||
35
48.4k
                ((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
562k
    case SRE_AT_END_STRING:
42
562k
        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
631k
    }
87
88
0
    return 0;
89
631k
}
90
91
LOCAL(int)
92
SRE(charset)(SRE_STATE* state, const SRE_CODE* set, SRE_CODE ch)
93
1.00G
{
94
    /* check if character is a member of the given set */
95
96
1.00G
    int ok = 1;
97
98
2.41G
    for (;;) {
99
2.41G
        switch (*set++) {
100
101
703M
        case SRE_OP_FAILURE:
102
703M
            return !ok;
103
104
1.09G
        case SRE_OP_LITERAL:
105
            /* <LITERAL> <code> */
106
1.09G
            if (ch == set[0])
107
16.7M
                return ok;
108
1.07G
            set++;
109
1.07G
            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
119M
        case SRE_OP_CHARSET:
119
            /* <CHARSET> <bitmap> */
120
119M
            if (ch < 256 &&
121
114M
                (set[ch/SRE_CODE_BITS] & (1u << (ch & (SRE_CODE_BITS-1)))))
122
23.5M
                return ok;
123
96.2M
            set += 256/SRE_CODE_BITS;
124
96.2M
            break;
125
126
387M
        case SRE_OP_RANGE:
127
            /* <RANGE> <lower> <upper> */
128
387M
            if (set[0] <= ch && ch <= set[1])
129
254M
                return ok;
130
133M
            set += 2;
131
133M
            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
98.7M
        case SRE_OP_NEGATE:
148
98.7M
            ok = !ok;
149
98.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
2.41G
        }
175
2.41G
    }
176
1.00G
}
sre.c:sre_ucs1_charset
Line
Count
Source
93
323M
{
94
    /* check if character is a member of the given set */
95
96
323M
    int ok = 1;
97
98
654M
    for (;;) {
99
654M
        switch (*set++) {
100
101
167M
        case SRE_OP_FAILURE:
102
167M
            return !ok;
103
104
207M
        case SRE_OP_LITERAL:
105
            /* <LITERAL> <code> */
106
207M
            if (ch == set[0])
107
11.9M
                return ok;
108
195M
            set++;
109
195M
            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
43.0M
        case SRE_OP_CHARSET:
119
            /* <CHARSET> <bitmap> */
120
43.0M
            if (ch < 256 &&
121
43.0M
                (set[ch/SRE_CODE_BITS] & (1u << (ch & (SRE_CODE_BITS-1)))))
122
10.6M
                return ok;
123
32.4M
            set += 256/SRE_CODE_BITS;
124
32.4M
            break;
125
126
198M
        case SRE_OP_RANGE:
127
            /* <RANGE> <lower> <upper> */
128
198M
            if (set[0] <= ch && ch <= set[1])
129
129M
                return ok;
130
68.6M
            set += 2;
131
68.6M
            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
32.8M
        case SRE_OP_NEGATE:
148
32.8M
            ok = !ok;
149
32.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
654M
        }
175
654M
    }
176
323M
}
sre.c:sre_ucs2_charset
Line
Count
Source
93
527M
{
94
    /* check if character is a member of the given set */
95
96
527M
    int ok = 1;
97
98
1.36G
    for (;;) {
99
1.36G
        switch (*set++) {
100
101
416M
        case SRE_OP_FAILURE:
102
416M
            return !ok;
103
104
677M
        case SRE_OP_LITERAL:
105
            /* <LITERAL> <code> */
106
677M
            if (ch == set[0])
107
4.06M
                return ok;
108
673M
            set++;
109
673M
            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
57.9M
        case SRE_OP_CHARSET:
119
            /* <CHARSET> <bitmap> */
120
57.9M
            if (ch < 256 &&
121
53.6M
                (set[ch/SRE_CODE_BITS] & (1u << (ch & (SRE_CODE_BITS-1)))))
122
7.33M
                return ok;
123
50.6M
            set += 256/SRE_CODE_BITS;
124
50.6M
            break;
125
126
156M
        case SRE_OP_RANGE:
127
            /* <RANGE> <lower> <upper> */
128
156M
            if (set[0] <= ch && ch <= set[1])
129
98.2M
                return ok;
130
58.7M
            set += 2;
131
58.7M
            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
52.5M
        case SRE_OP_NEGATE:
148
52.5M
            ok = !ok;
149
52.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
1.36G
        }
175
1.36G
    }
176
527M
}
sre.c:sre_ucs4_charset
Line
Count
Source
93
152M
{
94
    /* check if character is a member of the given set */
95
96
152M
    int ok = 1;
97
98
393M
    for (;;) {
99
393M
        switch (*set++) {
100
101
119M
        case SRE_OP_FAILURE:
102
119M
            return !ok;
103
104
208M
        case SRE_OP_LITERAL:
105
            /* <LITERAL> <code> */
106
208M
            if (ch == set[0])
107
725k
                return ok;
108
208M
            set++;
109
208M
            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
18.7M
        case SRE_OP_CHARSET:
119
            /* <CHARSET> <bitmap> */
120
18.7M
            if (ch < 256 &&
121
17.9M
                (set[ch/SRE_CODE_BITS] & (1u << (ch & (SRE_CODE_BITS-1)))))
122
5.57M
                return ok;
123
13.1M
            set += 256/SRE_CODE_BITS;
124
13.1M
            break;
125
126
32.5M
        case SRE_OP_RANGE:
127
            /* <RANGE> <lower> <upper> */
128
32.5M
            if (set[0] <= ch && ch <= set[1])
129
26.2M
                return ok;
130
6.31M
            set += 2;
131
6.31M
            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.4M
        case SRE_OP_NEGATE:
148
13.4M
            ok = !ok;
149
13.4M
            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
393M
        }
175
393M
    }
176
152M
}
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
287M
{
250
287M
    SRE_CODE chr;
251
287M
    SRE_CODE arg;
252
287M
    SRE_CHAR c;
253
287M
    const SRE_CHAR* ptr = (const SRE_CHAR *)state->ptr;
254
287M
    const SRE_CHAR* end = (const SRE_CHAR *)state->end;
255
287M
    Py_ssize_t i;
256
287M
    INIT_TRACE(state);
257
258
    /* adjust end */
259
287M
    if (maxcount < end - ptr && maxcount != SRE_MAXREPEAT)
260
53.3M
        end = ptr + maxcount;
261
262
287M
    switch (pattern[0]) {
263
264
215M
    case SRE_OP_IN:
265
        /* repeated set */
266
215M
        TRACE(("|%p|%p|COUNT IN\n", pattern, ptr));
267
385M
        while (ptr < end && SRE(charset)(state, pattern + 2, *ptr))
268
169M
            ptr++;
269
215M
        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
57.4M
    case SRE_OP_LITERAL:
286
        /* repeated literal */
287
57.4M
        chr = pattern[1];
288
57.4M
        TRACE(("|%p|%p|COUNT LITERAL %d\n", pattern, ptr, chr));
289
57.4M
        c = (SRE_CHAR) chr;
290
#if SIZEOF_SRE_CHAR < 4
291
44.1M
        if ((SRE_CODE) c != chr)
292
0
            ; /* literal can't match: doesn't fit in char width */
293
44.1M
        else
294
44.1M
#endif
295
57.7M
        while (ptr < end && *ptr == c)
296
276k
            ptr++;
297
57.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.3M
    case SRE_OP_CATEGORY:
362
11.3M
        arg = pattern[1];
363
11.3M
        TRACE(("|%p|%p|COUNT CATEGORY %d\n", pattern, ptr, arg));
364
19.4M
        while (ptr < end && sre_category(arg, *ptr))
365
8.17M
            ptr++;
366
11.3M
        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
287M
    }
382
383
287M
    TRACE(("|%p|%p|COUNT %zd\n", pattern, ptr,
384
287M
           ptr - (SRE_CHAR*) state->ptr));
385
287M
    return ptr - (SRE_CHAR*) state->ptr;
386
287M
}
sre.c:sre_ucs1_count
Line
Count
Source
249
96.1M
{
250
96.1M
    SRE_CODE chr;
251
96.1M
    SRE_CODE arg;
252
96.1M
    SRE_CHAR c;
253
96.1M
    const SRE_CHAR* ptr = (const SRE_CHAR *)state->ptr;
254
96.1M
    const SRE_CHAR* end = (const SRE_CHAR *)state->end;
255
96.1M
    Py_ssize_t i;
256
96.1M
    INIT_TRACE(state);
257
258
    /* adjust end */
259
96.1M
    if (maxcount < end - ptr && maxcount != SRE_MAXREPEAT)
260
22.2M
        end = ptr + maxcount;
261
262
96.1M
    switch (pattern[0]) {
263
264
57.2M
    case SRE_OP_IN:
265
        /* repeated set */
266
57.2M
        TRACE(("|%p|%p|COUNT IN\n", pattern, ptr));
267
144M
        while (ptr < end && SRE(charset)(state, pattern + 2, *ptr))
268
86.9M
            ptr++;
269
57.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
26.2M
    case SRE_OP_LITERAL:
286
        /* repeated literal */
287
26.2M
        chr = pattern[1];
288
26.2M
        TRACE(("|%p|%p|COUNT LITERAL %d\n", pattern, ptr, chr));
289
26.2M
        c = (SRE_CHAR) chr;
290
26.2M
#if SIZEOF_SRE_CHAR < 4
291
26.2M
        if ((SRE_CODE) c != chr)
292
0
            ; /* literal can't match: doesn't fit in char width */
293
26.2M
        else
294
26.2M
#endif
295
26.4M
        while (ptr < end && *ptr == c)
296
224k
            ptr++;
297
26.2M
        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.50M
    case SRE_OP_CATEGORY:
362
9.50M
        arg = pattern[1];
363
9.50M
        TRACE(("|%p|%p|COUNT CATEGORY %d\n", pattern, ptr, arg));
364
16.6M
        while (ptr < end && sre_category(arg, *ptr))
365
7.15M
            ptr++;
366
9.50M
        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
96.1M
    }
382
383
96.1M
    TRACE(("|%p|%p|COUNT %zd\n", pattern, ptr,
384
96.1M
           ptr - (SRE_CHAR*) state->ptr));
385
96.1M
    return ptr - (SRE_CHAR*) state->ptr;
386
96.1M
}
sre.c:sre_ucs2_count
Line
Count
Source
249
150M
{
250
150M
    SRE_CODE chr;
251
150M
    SRE_CODE arg;
252
150M
    SRE_CHAR c;
253
150M
    const SRE_CHAR* ptr = (const SRE_CHAR *)state->ptr;
254
150M
    const SRE_CHAR* end = (const SRE_CHAR *)state->end;
255
150M
    Py_ssize_t i;
256
150M
    INIT_TRACE(state);
257
258
    /* adjust end */
259
150M
    if (maxcount < end - ptr && maxcount != SRE_MAXREPEAT)
260
17.7M
        end = ptr + maxcount;
261
262
150M
    switch (pattern[0]) {
263
264
130M
    case SRE_OP_IN:
265
        /* repeated set */
266
130M
        TRACE(("|%p|%p|COUNT IN\n", pattern, ptr));
267
192M
        while (ptr < end && SRE(charset)(state, pattern + 2, *ptr))
268
61.6M
            ptr++;
269
130M
        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
17.9M
    case SRE_OP_LITERAL:
286
        /* repeated literal */
287
17.9M
        chr = pattern[1];
288
17.9M
        TRACE(("|%p|%p|COUNT LITERAL %d\n", pattern, ptr, chr));
289
17.9M
        c = (SRE_CHAR) chr;
290
17.9M
#if SIZEOF_SRE_CHAR < 4
291
17.9M
        if ((SRE_CODE) c != chr)
292
0
            ; /* literal can't match: doesn't fit in char width */
293
17.9M
        else
294
17.9M
#endif
295
17.9M
        while (ptr < end && *ptr == c)
296
51.8k
            ptr++;
297
17.9M
        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.42M
        while (ptr < end && sre_category(arg, *ptr))
365
634k
            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
150M
    }
382
383
150M
    TRACE(("|%p|%p|COUNT %zd\n", pattern, ptr,
384
150M
           ptr - (SRE_CHAR*) state->ptr));
385
150M
    return ptr - (SRE_CHAR*) state->ptr;
386
150M
}
sre.c:sre_ucs4_count
Line
Count
Source
249
41.0M
{
250
41.0M
    SRE_CODE chr;
251
41.0M
    SRE_CODE arg;
252
41.0M
    SRE_CHAR c;
253
41.0M
    const SRE_CHAR* ptr = (const SRE_CHAR *)state->ptr;
254
41.0M
    const SRE_CHAR* end = (const SRE_CHAR *)state->end;
255
41.0M
    Py_ssize_t i;
256
41.0M
    INIT_TRACE(state);
257
258
    /* adjust end */
259
41.0M
    if (maxcount < end - ptr && maxcount != SRE_MAXREPEAT)
260
13.3M
        end = ptr + maxcount;
261
262
41.0M
    switch (pattern[0]) {
263
264
27.7M
    case SRE_OP_IN:
265
        /* repeated set */
266
27.7M
        TRACE(("|%p|%p|COUNT IN\n", pattern, ptr));
267
48.7M
        while (ptr < end && SRE(charset)(state, pattern + 2, *ptr))
268
21.0M
            ptr++;
269
27.7M
        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
13.3M
    case SRE_OP_LITERAL:
286
        /* repeated literal */
287
13.3M
        chr = pattern[1];
288
13.3M
        TRACE(("|%p|%p|COUNT LITERAL %d\n", pattern, ptr, chr));
289
13.3M
        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
13.3M
        while (ptr < end && *ptr == c)
296
721
            ptr++;
297
13.3M
        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.0M
    }
382
383
41.0M
    TRACE(("|%p|%p|COUNT %zd\n", pattern, ptr,
384
41.0M
           ptr - (SRE_CHAR*) state->ptr));
385
41.0M
    return ptr - (SRE_CHAR*) state->ptr;
386
41.0M
}
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
413M
    do { \
418
413M
        ctx->lastmark = state->lastmark; \
419
413M
        ctx->lastindex = state->lastindex; \
420
413M
    } while (0)
421
#define LASTMARK_RESTORE()  \
422
190M
    do { \
423
190M
        state->lastmark = ctx->lastmark; \
424
190M
        state->lastindex = ctx->lastindex; \
425
190M
    } while (0)
426
427
#define LAST_PTR_PUSH()     \
428
178M
    do { \
429
178M
        TRACE(("push last_ptr: %zd", \
430
178M
                PTR_TO_INDEX(ctx->u.rep->last_ptr))); \
431
178M
        DATA_PUSH(&ctx->u.rep->last_ptr); \
432
178M
    } while (0)
433
#define LAST_PTR_POP()  \
434
178M
    do { \
435
178M
        DATA_POP(&ctx->u.rep->last_ptr); \
436
178M
        TRACE(("pop last_ptr: %zd", \
437
178M
                PTR_TO_INDEX(ctx->u.rep->last_ptr))); \
438
178M
    } while (0)
439
440
0
#define RETURN_ERROR(i) do { return i; } while(0)
441
429M
#define RETURN_FAILURE do { ret = 0; goto exit; } while(0)
442
426M
#define RETURN_SUCCESS do { ret = 1; goto exit; } while(0)
443
444
#define RETURN_ON_ERROR(i) \
445
601M
    do { if (i < 0) RETURN_ERROR(i); } while (0)
446
#define RETURN_ON_SUCCESS(i) \
447
24.5M
    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
855M
#define DATA_STACK_ALLOC(state, type, ptr) \
452
855M
do { \
453
855M
    alloc_pos = state->data_stack_base; \
454
855M
    TRACE(("allocating %s in %zd (%zd)\n", \
455
855M
           Py_STRINGIFY(type), alloc_pos, sizeof(type))); \
456
855M
    if (sizeof(type) > state->data_stack_size - alloc_pos) { \
457
136M
        int j = data_stack_grow(state, sizeof(type)); \
458
136M
        if (j < 0) return j; \
459
136M
        if (ctx_pos != -1) \
460
136M
            DATA_STACK_LOOKUP_AT(state, SRE(match_context), ctx, ctx_pos); \
461
136M
    } \
462
855M
    ptr = (type*)(state->data_stack+alloc_pos); \
463
855M
    state->data_stack_base += sizeof(type); \
464
855M
} while (0)
465
466
805M
#define DATA_STACK_LOOKUP_AT(state, type, ptr, pos) \
467
805M
do { \
468
805M
    TRACE(("looking up %s at %zd\n", Py_STRINGIFY(type), pos)); \
469
805M
    ptr = (type*)(state->data_stack+pos); \
470
805M
} while (0)
471
472
514M
#define DATA_STACK_PUSH(state, data, size) \
473
514M
do { \
474
514M
    TRACE(("copy data in %p to %zd (%zd)\n", \
475
514M
           data, state->data_stack_base, size)); \
476
514M
    if (size > state->data_stack_size - state->data_stack_base) { \
477
65.6k
        int j = data_stack_grow(state, size); \
478
65.6k
        if (j < 0) return j; \
479
65.6k
        if (ctx_pos != -1) \
480
65.6k
            DATA_STACK_LOOKUP_AT(state, SRE(match_context), ctx, ctx_pos); \
481
65.6k
    } \
482
514M
    memcpy(state->data_stack+state->data_stack_base, data, size); \
483
514M
    state->data_stack_base += size; \
484
514M
} 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
311M
#define DATA_STACK_POP(state, data, size, discard) \
490
311M
do { \
491
311M
    TRACE(("copy data to %p from %zd (%zd)\n", \
492
311M
           data, state->data_stack_base-size, size)); \
493
311M
    memcpy((void*) data, state->data_stack+state->data_stack_base-size, size); \
494
311M
    if (discard) \
495
311M
        state->data_stack_base -= size; \
496
311M
} while (0)
497
498
1.05G
#define DATA_STACK_POP_DISCARD(state, size) \
499
1.05G
do { \
500
1.05G
    TRACE(("discard data from %zd (%zd)\n", \
501
1.05G
           state->data_stack_base-size, size)); \
502
1.05G
    state->data_stack_base -= size; \
503
1.05G
} while(0)
504
505
#define DATA_PUSH(x) \
506
178M
    DATA_STACK_PUSH(state, (x), sizeof(*(x)))
507
#define DATA_POP(x) \
508
178M
    DATA_STACK_POP(state, (x), sizeof(*(x)), 1)
509
#define DATA_POP_DISCARD(x) \
510
855M
    DATA_STACK_POP_DISCARD(state, sizeof(*(x)))
511
#define DATA_ALLOC(t,p) \
512
855M
    DATA_STACK_ALLOC(state, t, p)
513
#define DATA_LOOKUP_AT(t,p,pos) \
514
802M
    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
361M
    do if (lastmark >= 0) { \
536
335M
        MARK_TRACE("push", (lastmark)); \
537
335M
        size_t _marks_size = (lastmark+1) * sizeof(void*); \
538
335M
        DATA_STACK_PUSH(state, state->mark, _marks_size); \
539
361M
    } 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
1.83M
    do if (lastmark >= 0) { \
548
1.05M
        size_t _marks_size = (lastmark+1) * sizeof(void*); \
549
1.05M
        DATA_STACK_POP(state, state->mark, _marks_size, 0); \
550
1.05M
        MARK_TRACE("pop keep", (lastmark)); \
551
1.83M
    } while (0)
552
#define MARK_POP_DISCARD(lastmark) \
553
229M
    do if (lastmark >= 0) { \
554
204M
        size_t _marks_size = (lastmark+1) * sizeof(void*); \
555
204M
        DATA_STACK_POP_DISCARD(state, _marks_size); \
556
204M
        MARK_TRACE("pop discard", (lastmark)); \
557
229M
    } while (0)
558
559
340M
#define JUMP_NONE            0
560
8.16M
#define JUMP_MAX_UNTIL_1     1
561
178M
#define JUMP_MAX_UNTIL_2     2
562
24.5M
#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
29.3M
#define JUMP_REPEAT          7
567
1.18M
#define JUMP_REPEAT_ONE_1    8
568
98.7M
#define JUMP_REPEAT_ONE_2    9
569
832
#define JUMP_MIN_REPEAT_ONE  10
570
53.7M
#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
515M
    ctx->pattern = pattern; \
579
515M
    ctx->ptr = ptr; \
580
515M
    DATA_ALLOC(SRE(match_context), nextctx); \
581
515M
    nextctx->pattern = nextpattern; \
582
515M
    nextctx->toplevel = toplevel_; \
583
515M
    nextctx->jump = jumpvalue; \
584
515M
    nextctx->last_ctx_pos = ctx_pos; \
585
515M
    pattern = nextpattern; \
586
515M
    ctx_pos = alloc_pos; \
587
515M
    ctx = nextctx; \
588
515M
    goto entrance; \
589
515M
    jumplabel: \
590
515M
    pattern = ctx->pattern; \
591
515M
    ptr = ctx->ptr;
592
593
#define DO_JUMP(jumpvalue, jumplabel, nextpattern) \
594
394M
    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.59G
    do {                                                           \
616
1.59G
        if ((0 == (++sigcount & 0xfff)) && PyErr_CheckSignals()) { \
617
0
            RETURN_ERROR(SRE_ERROR_INTERRUPTED);                   \
618
0
        }                                                          \
619
1.59G
    } 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.59G
# 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.61G
    #define TARGET(OP) TARGET_ ## OP
649
    #define DISPATCH                       \
650
1.59G
        do {                               \
651
1.59G
            MAYBE_CHECK_SIGNALS;           \
652
1.59G
            goto *sre_targets[*pattern++]; \
653
1.59G
        } 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
340M
{
664
340M
    const SRE_CHAR* end = (const SRE_CHAR *)state->end;
665
340M
    Py_ssize_t alloc_pos, ctx_pos = -1;
666
340M
    Py_ssize_t ret = 0;
667
340M
    int jump;
668
340M
    unsigned int sigcount = state->sigcount;
669
670
340M
    SRE(match_context)* ctx;
671
340M
    SRE(match_context)* nextctx;
672
340M
    INIT_TRACE(state);
673
674
340M
    TRACE(("|%p|%p|ENTER\n", pattern, state->ptr));
675
676
340M
    DATA_ALLOC(SRE(match_context), ctx);
677
340M
    ctx->last_ctx_pos = -1;
678
340M
    ctx->jump = JUMP_NONE;
679
340M
    ctx->toplevel = toplevel;
680
340M
    ctx_pos = alloc_pos;
681
682
340M
#if USE_COMPUTED_GOTOS
683
340M
#include "sre_targets.h"
684
340M
#endif
685
686
855M
entrance:
687
688
855M
    ;  // Fashion statement.
689
855M
    const SRE_CHAR *ptr = (SRE_CHAR *)state->ptr;
690
691
855M
    if (pattern[0] == SRE_OP_INFO) {
692
        /* optimization info block */
693
        /* <INFO> <1=skip> <2=flags> <3=min> ... */
694
43.0M
        if (pattern[3] && (uintptr_t)(end - ptr) < pattern[3]) {
695
6.33M
            TRACE(("reject (got %tu chars, need %zu)\n",
696
6.33M
                   end - ptr, (size_t) pattern[3]));
697
6.33M
            RETURN_FAILURE;
698
6.33M
        }
699
36.6M
        pattern += pattern[1] + 1;
700
36.6M
    }
701
702
849M
#if USE_COMPUTED_GOTOS
703
849M
    DISPATCH;
704
#else
705
dispatch:
706
    MAYBE_CHECK_SIGNALS;
707
    switch (*pattern++)
708
#endif
709
849M
    {
710
711
849M
        TARGET(SRE_OP_MARK):
712
            /* set mark */
713
            /* <MARK> <gid> */
714
298M
            TRACE(("|%p|%p|MARK %d\n", pattern,
715
298M
                   ptr, pattern[0]));
716
298M
            {
717
298M
                int i = pattern[0];
718
298M
                if (i & 1)
719
50.0M
                    state->lastindex = i/2 + 1;
720
298M
                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
296M
                    int j = state->lastmark + 1;
726
310M
                    while (j < i)
727
13.6M
                        state->mark[j++] = NULL;
728
296M
                    state->lastmark = i;
729
296M
                }
730
298M
                state->mark[i] = ptr;
731
298M
            }
732
298M
            pattern++;
733
298M
            DISPATCH;
734
735
298M
        TARGET(SRE_OP_LITERAL):
736
            /* match literal string */
737
            /* <LITERAL> <code> */
738
89.8M
            TRACE(("|%p|%p|LITERAL %d\n", pattern,
739
89.8M
                   ptr, *pattern));
740
89.8M
            if (ptr >= end || (SRE_CODE) ptr[0] != pattern[0])
741
50.6M
                RETURN_FAILURE;
742
39.2M
            pattern++;
743
39.2M
            ptr++;
744
39.2M
            DISPATCH;
745
746
39.2M
        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
119M
        TARGET(SRE_OP_SUCCESS):
758
            /* end of pattern */
759
119M
            TRACE(("|%p|%p|SUCCESS\n", pattern, ptr));
760
119M
            if (ctx->toplevel &&
761
28.0M
                ((state->match_all && ptr != state->end) ||
762
28.0M
                 (state->must_advance && ptr == state->start)))
763
76
            {
764
76
                RETURN_FAILURE;
765
76
            }
766
119M
            state->ptr = ptr;
767
119M
            RETURN_SUCCESS;
768
769
22.8M
        TARGET(SRE_OP_AT):
770
            /* match at given position */
771
            /* <AT> <code> */
772
22.8M
            TRACE(("|%p|%p|AT %d\n", pattern, ptr, *pattern));
773
22.8M
            if (!SRE(at)(state, ptr, *pattern))
774
3.70M
                RETURN_FAILURE;
775
19.1M
            pattern++;
776
19.1M
            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
255M
        TARGET(SRE_OP_IN):
808
            /* match set member (or non_member) */
809
            /* <IN> <skip> <set> */
810
255M
            TRACE(("|%p|%p|IN\n", pattern, ptr));
811
255M
            if (ptr >= end ||
812
249M
                !SRE(charset)(state, pattern + 1, *ptr))
813
117M
                RETURN_FAILURE;
814
137M
            pattern += pattern[0];
815
137M
            ptr++;
816
137M
            DISPATCH;
817
818
137M
        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.0M
        TARGET(SRE_OP_JUMP):
908
21.0M
        TARGET(SRE_OP_INFO):
909
            /* jump forward */
910
            /* <JUMP> <offset> */
911
21.0M
            TRACE(("|%p|%p|JUMP %d\n", pattern,
912
21.0M
                   ptr, pattern[0]));
913
21.0M
            pattern += pattern[0];
914
21.0M
            DISPATCH;
915
916
33.2M
        TARGET(SRE_OP_BRANCH):
917
            /* alternation */
918
            /* <BRANCH> <0=skip> code <JUMP> ... <NULL> */
919
33.2M
            TRACE(("|%p|%p|BRANCH\n", pattern, ptr));
920
33.2M
            LASTMARK_SAVE();
921
33.2M
            if (state->save_marks)
922
43.2k
                MARK_PUSH(ctx->lastmark);
923
91.6M
            for (; pattern[0]; pattern += pattern[0]) {
924
76.0M
                if (pattern[1] == SRE_OP_LITERAL &&
925
55.1M
                    (ptr >= end ||
926
55.1M
                     (SRE_CODE) *ptr != pattern[2]))
927
20.8M
                    continue;
928
55.2M
                if (pattern[1] == SRE_OP_IN &&
929
2.76M
                    (ptr >= end ||
930
2.76M
                     !SRE(charset)(state, pattern + 3,
931
2.76M
                                   (SRE_CODE) *ptr)))
932
1.47M
                    continue;
933
53.7M
                state->ptr = ptr;
934
53.7M
                DO_JUMP(JUMP_BRANCH, jump_branch, pattern+1);
935
53.7M
                if (ret) {
936
17.6M
                    if (state->save_marks)
937
34.9k
                        MARK_POP_DISCARD(ctx->lastmark);
938
17.6M
                    RETURN_ON_ERROR(ret);
939
17.6M
                    RETURN_SUCCESS;
940
17.6M
                }
941
36.0M
                if (state->save_marks)
942
17.4k
                    MARK_POP_KEEP(ctx->lastmark);
943
36.0M
                LASTMARK_RESTORE();
944
36.0M
            }
945
15.5M
            if (state->save_marks)
946
8.27k
                MARK_POP_DISCARD(ctx->lastmark);
947
15.5M
            RETURN_FAILURE;
948
949
288M
        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
288M
            TRACE(("|%p|%p|REPEAT_ONE %d %d\n", pattern, ptr,
960
288M
                   pattern[1], pattern[2]));
961
962
288M
            if ((Py_ssize_t) pattern[1] > end - ptr)
963
824k
                RETURN_FAILURE; /* cannot match */
964
965
287M
            state->ptr = ptr;
966
967
287M
            ret = SRE(count)(state, pattern+3, pattern[2]);
968
287M
            RETURN_ON_ERROR(ret);
969
287M
            DATA_LOOKUP_AT(SRE(match_context), ctx, ctx_pos);
970
287M
            ctx->count = ret;
971
287M
            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
287M
            if (ctx->count < (Py_ssize_t) pattern[1])
979
206M
                RETURN_FAILURE;
980
981
80.7M
            if (pattern[pattern[0]] == SRE_OP_SUCCESS &&
982
2.72M
                ptr == state->end &&
983
94.1k
                !(ctx->toplevel && state->must_advance && ptr == state->start))
984
94.1k
            {
985
                /* tail is empty.  we're finished */
986
94.1k
                state->ptr = ptr;
987
94.1k
                RETURN_SUCCESS;
988
94.1k
            }
989
990
80.6M
            LASTMARK_SAVE();
991
80.6M
            if (state->save_marks)
992
62.2M
                MARK_PUSH(ctx->lastmark);
993
994
80.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.30M
                ctx->u.chr = pattern[pattern[0]+1];
998
2.30M
                for (;;) {
999
11.9M
                    while (ctx->count >= (Py_ssize_t) pattern[1] &&
1000
10.8M
                           (ptr >= end || *ptr != ctx->u.chr)) {
1001
9.62M
                        ptr--;
1002
9.62M
                        ctx->count--;
1003
9.62M
                    }
1004
2.30M
                    if (ctx->count < (Py_ssize_t) pattern[1])
1005
1.11M
                        break;
1006
1.18M
                    state->ptr = ptr;
1007
1.18M
                    DO_JUMP(JUMP_REPEAT_ONE_1, jump_repeat_one_1,
1008
1.18M
                            pattern+pattern[0]);
1009
1.18M
                    if (ret) {
1010
1.18M
                        if (state->save_marks)
1011
0
                            MARK_POP_DISCARD(ctx->lastmark);
1012
1.18M
                        RETURN_ON_ERROR(ret);
1013
1.18M
                        RETURN_SUCCESS;
1014
1.18M
                    }
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.11M
                if (state->save_marks)
1023
32
                    MARK_POP_DISCARD(ctx->lastmark);
1024
78.3M
            } else {
1025
                /* general case */
1026
100M
                while (ctx->count >= (Py_ssize_t) pattern[1]) {
1027
98.7M
                    state->ptr = ptr;
1028
98.7M
                    DO_JUMP(JUMP_REPEAT_ONE_2, jump_repeat_one_2,
1029
98.7M
                            pattern+pattern[0]);
1030
98.7M
                    if (ret) {
1031
76.2M
                        if (state->save_marks)
1032
60.6M
                            MARK_POP_DISCARD(ctx->lastmark);
1033
76.2M
                        RETURN_ON_ERROR(ret);
1034
76.2M
                        RETURN_SUCCESS;
1035
76.2M
                    }
1036
22.4M
                    if (state->save_marks)
1037
1.82M
                        MARK_POP_KEEP(ctx->lastmark);
1038
22.4M
                    LASTMARK_RESTORE();
1039
1040
22.4M
                    ptr--;
1041
22.4M
                    ctx->count--;
1042
22.4M
                }
1043
2.11M
                if (state->save_marks)
1044
1.56M
                    MARK_POP_DISCARD(ctx->lastmark);
1045
2.11M
            }
1046
3.23M
            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
29.3M
        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
29.3M
            TRACE(("|%p|%p|REPEAT %d %d\n", pattern, ptr,
1186
29.3M
                   pattern[1], pattern[2]));
1187
1188
            /* install new repeat context */
1189
29.3M
            ctx->u.rep = repeat_pool_malloc(state);
1190
29.3M
            if (!ctx->u.rep) {
1191
0
                RETURN_ERROR(SRE_ERROR_MEMORY);
1192
0
            }
1193
29.3M
            ctx->u.rep->count = -1;
1194
29.3M
            ctx->u.rep->pattern = pattern;
1195
29.3M
            ctx->u.rep->prev = state->repeat;
1196
29.3M
            ctx->u.rep->last_ptr = NULL;
1197
29.3M
            state->repeat = ctx->u.rep;
1198
29.3M
            state->save_marks++;
1199
1200
29.3M
            state->ptr = ptr;
1201
29.3M
            DO_JUMP(JUMP_REPEAT, jump_repeat, pattern+pattern[0]);
1202
29.3M
            state->repeat = ctx->u.rep->prev;
1203
29.3M
            state->save_marks--;
1204
29.3M
            repeat_pool_free(state, ctx->u.rep);
1205
1206
29.3M
            if (ret) {
1207
24.0M
                RETURN_ON_ERROR(ret);
1208
24.0M
                RETURN_SUCCESS;
1209
24.0M
            }
1210
5.27M
            RETURN_FAILURE;
1211
1212
193M
        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
193M
            ctx->u.rep = state->repeat;
1220
193M
            if (!ctx->u.rep)
1221
0
                RETURN_ERROR(SRE_ERROR_STATE);
1222
1223
193M
            state->ptr = ptr;
1224
1225
193M
            ctx->count = ctx->u.rep->count+1;
1226
1227
193M
            TRACE(("|%p|%p|MAX_UNTIL %zd\n", pattern,
1228
193M
                   ptr, ctx->count));
1229
1230
193M
            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
185M
            if ((ctx->count < (Py_ssize_t) ctx->u.rep->pattern[2] ||
1245
6.26M
                ctx->u.rep->pattern[2] == SRE_MAXREPEAT) &&
1246
178M
                state->ptr != ctx->u.rep->last_ptr) {
1247
                /* we may have enough matches, but if we can
1248
                   match another item, do so */
1249
178M
                ctx->u.rep->count = ctx->count;
1250
178M
                LASTMARK_SAVE();
1251
178M
                MARK_PUSH(ctx->lastmark);
1252
                /* zero-width match protection */
1253
178M
                LAST_PTR_PUSH();
1254
178M
                ctx->u.rep->last_ptr = state->ptr;
1255
178M
                DO_JUMP(JUMP_MAX_UNTIL_2, jump_max_until_2,
1256
178M
                        ctx->u.rep->pattern+3);
1257
178M
                LAST_PTR_POP();
1258
178M
                if (ret) {
1259
160M
                    MARK_POP_DISCARD(ctx->lastmark);
1260
160M
                    RETURN_ON_ERROR(ret);
1261
160M
                    RETURN_SUCCESS;
1262
160M
                }
1263
18.2M
                MARK_POP(ctx->lastmark);
1264
18.2M
                LASTMARK_RESTORE();
1265
18.2M
                ctx->u.rep->count = ctx->count-1;
1266
18.2M
                state->ptr = ptr;
1267
18.2M
            }
1268
1269
            /* cannot match more repeated items here.  make sure the
1270
               tail matches */
1271
24.5M
            state->repeat = ctx->u.rep->prev;
1272
24.5M
            state->save_marks--;
1273
24.5M
            DO_JUMP(JUMP_MAX_UNTIL_3, jump_max_until_3, pattern);
1274
24.5M
            state->repeat = ctx->u.rep; // restore repeat before return
1275
24.5M
            state->save_marks++;
1276
1277
24.5M
            RETURN_ON_SUCCESS(ret);
1278
472k
            state->ptr = ptr;
1279
472k
            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
855M
exit:
1681
855M
    ctx_pos = ctx->last_ctx_pos;
1682
855M
    jump = ctx->jump;
1683
855M
    DATA_POP_DISCARD(ctx);
1684
855M
    if (ctx_pos == -1) {
1685
340M
        state->sigcount = sigcount;
1686
340M
        return ret;
1687
340M
    }
1688
515M
    DATA_LOOKUP_AT(SRE(match_context), ctx, ctx_pos);
1689
1690
515M
    switch (jump) {
1691
178M
        case JUMP_MAX_UNTIL_2:
1692
178M
            TRACE(("|%p|%p|JUMP_MAX_UNTIL_2\n", pattern, ptr));
1693
178M
            goto jump_max_until_2;
1694
24.5M
        case JUMP_MAX_UNTIL_3:
1695
24.5M
            TRACE(("|%p|%p|JUMP_MAX_UNTIL_3\n", pattern, ptr));
1696
24.5M
            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
53.7M
        case JUMP_BRANCH:
1704
53.7M
            TRACE(("|%p|%p|JUMP_BRANCH\n", pattern, ptr));
1705
53.7M
            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
29.3M
        case JUMP_REPEAT:
1719
29.3M
            TRACE(("|%p|%p|JUMP_REPEAT\n", pattern, ptr));
1720
29.3M
            goto jump_repeat;
1721
1.18M
        case JUMP_REPEAT_ONE_1:
1722
1.18M
            TRACE(("|%p|%p|JUMP_REPEAT_ONE_1\n", pattern, ptr));
1723
1.18M
            goto jump_repeat_one_1;
1724
98.7M
        case JUMP_REPEAT_ONE_2:
1725
98.7M
            TRACE(("|%p|%p|JUMP_REPEAT_ONE_2\n", pattern, ptr));
1726
98.7M
            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
515M
    }
1744
1745
0
    return ret; /* should never get here */
1746
515M
}
sre.c:sre_ucs1_match
Line
Count
Source
663
129M
{
664
129M
    const SRE_CHAR* end = (const SRE_CHAR *)state->end;
665
129M
    Py_ssize_t alloc_pos, ctx_pos = -1;
666
129M
    Py_ssize_t ret = 0;
667
129M
    int jump;
668
129M
    unsigned int sigcount = state->sigcount;
669
670
129M
    SRE(match_context)* ctx;
671
129M
    SRE(match_context)* nextctx;
672
129M
    INIT_TRACE(state);
673
674
129M
    TRACE(("|%p|%p|ENTER\n", pattern, state->ptr));
675
676
129M
    DATA_ALLOC(SRE(match_context), ctx);
677
129M
    ctx->last_ctx_pos = -1;
678
129M
    ctx->jump = JUMP_NONE;
679
129M
    ctx->toplevel = toplevel;
680
129M
    ctx_pos = alloc_pos;
681
682
129M
#if USE_COMPUTED_GOTOS
683
129M
#include "sre_targets.h"
684
129M
#endif
685
686
343M
entrance:
687
688
343M
    ;  // Fashion statement.
689
343M
    const SRE_CHAR *ptr = (SRE_CHAR *)state->ptr;
690
691
343M
    if (pattern[0] == SRE_OP_INFO) {
692
        /* optimization info block */
693
        /* <INFO> <1=skip> <2=flags> <3=min> ... */
694
36.5M
        if (pattern[3] && (uintptr_t)(end - ptr) < pattern[3]) {
695
6.19M
            TRACE(("reject (got %tu chars, need %zu)\n",
696
6.19M
                   end - ptr, (size_t) pattern[3]));
697
6.19M
            RETURN_FAILURE;
698
6.19M
        }
699
30.3M
        pattern += pattern[1] + 1;
700
30.3M
    }
701
702
336M
#if USE_COMPUTED_GOTOS
703
336M
    DISPATCH;
704
#else
705
dispatch:
706
    MAYBE_CHECK_SIGNALS;
707
    switch (*pattern++)
708
#endif
709
336M
    {
710
711
336M
        TARGET(SRE_OP_MARK):
712
            /* set mark */
713
            /* <MARK> <gid> */
714
114M
            TRACE(("|%p|%p|MARK %d\n", pattern,
715
114M
                   ptr, pattern[0]));
716
114M
            {
717
114M
                int i = pattern[0];
718
114M
                if (i & 1)
719
30.7M
                    state->lastindex = i/2 + 1;
720
114M
                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
112M
                    int j = state->lastmark + 1;
726
122M
                    while (j < i)
727
10.1M
                        state->mark[j++] = NULL;
728
112M
                    state->lastmark = i;
729
112M
                }
730
114M
                state->mark[i] = ptr;
731
114M
            }
732
114M
            pattern++;
733
114M
            DISPATCH;
734
735
114M
        TARGET(SRE_OP_LITERAL):
736
            /* match literal string */
737
            /* <LITERAL> <code> */
738
67.0M
            TRACE(("|%p|%p|LITERAL %d\n", pattern,
739
67.0M
                   ptr, *pattern));
740
67.0M
            if (ptr >= end || (SRE_CODE) ptr[0] != pattern[0])
741
30.4M
                RETURN_FAILURE;
742
36.6M
            pattern++;
743
36.6M
            ptr++;
744
36.6M
            DISPATCH;
745
746
36.6M
        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
68.2M
        TARGET(SRE_OP_SUCCESS):
758
            /* end of pattern */
759
68.2M
            TRACE(("|%p|%p|SUCCESS\n", pattern, ptr));
760
68.2M
            if (ctx->toplevel &&
761
23.8M
                ((state->match_all && ptr != state->end) ||
762
23.8M
                 (state->must_advance && ptr == state->start)))
763
76
            {
764
76
                RETURN_FAILURE;
765
76
            }
766
68.2M
            state->ptr = ptr;
767
68.2M
            RETURN_SUCCESS;
768
769
17.8M
        TARGET(SRE_OP_AT):
770
            /* match at given position */
771
            /* <AT> <code> */
772
17.8M
            TRACE(("|%p|%p|AT %d\n", pattern, ptr, *pattern));
773
17.8M
            if (!SRE(at)(state, ptr, *pattern))
774
2.10M
                RETURN_FAILURE;
775
15.7M
            pattern++;
776
15.7M
            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
83.6M
        TARGET(SRE_OP_IN):
808
            /* match set member (or non_member) */
809
            /* <IN> <skip> <set> */
810
83.6M
            TRACE(("|%p|%p|IN\n", pattern, ptr));
811
83.6M
            if (ptr >= end ||
812
82.3M
                !SRE(charset)(state, pattern + 1, *ptr))
813
21.3M
                RETURN_FAILURE;
814
62.2M
            pattern += pattern[0];
815
62.2M
            ptr++;
816
62.2M
            DISPATCH;
817
818
62.2M
        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
18.9M
        TARGET(SRE_OP_JUMP):
908
18.9M
        TARGET(SRE_OP_INFO):
909
            /* jump forward */
910
            /* <JUMP> <offset> */
911
18.9M
            TRACE(("|%p|%p|JUMP %d\n", pattern,
912
18.9M
                   ptr, pattern[0]));
913
18.9M
            pattern += pattern[0];
914
18.9M
            DISPATCH;
915
916
28.7M
        TARGET(SRE_OP_BRANCH):
917
            /* alternation */
918
            /* <BRANCH> <0=skip> code <JUMP> ... <NULL> */
919
28.7M
            TRACE(("|%p|%p|BRANCH\n", pattern, ptr));
920
28.7M
            LASTMARK_SAVE();
921
28.7M
            if (state->save_marks)
922
31.5k
                MARK_PUSH(ctx->lastmark);
923
77.1M
            for (; pattern[0]; pattern += pattern[0]) {
924
65.4M
                if (pattern[1] == SRE_OP_LITERAL &&
925
49.4M
                    (ptr >= end ||
926
49.4M
                     (SRE_CODE) *ptr != pattern[2]))
927
17.4M
                    continue;
928
47.9M
                if (pattern[1] == SRE_OP_IN &&
929
2.28M
                    (ptr >= end ||
930
2.28M
                     !SRE(charset)(state, pattern + 3,
931
2.28M
                                   (SRE_CODE) *ptr)))
932
1.29M
                    continue;
933
46.6M
                state->ptr = ptr;
934
46.6M
                DO_JUMP(JUMP_BRANCH, jump_branch, pattern+1);
935
46.6M
                if (ret) {
936
17.0M
                    if (state->save_marks)
937
28.6k
                        MARK_POP_DISCARD(ctx->lastmark);
938
17.0M
                    RETURN_ON_ERROR(ret);
939
17.0M
                    RETURN_SUCCESS;
940
17.0M
                }
941
29.6M
                if (state->save_marks)
942
7.56k
                    MARK_POP_KEEP(ctx->lastmark);
943
29.6M
                LASTMARK_RESTORE();
944
29.6M
            }
945
11.7M
            if (state->save_marks)
946
2.94k
                MARK_POP_DISCARD(ctx->lastmark);
947
11.7M
            RETURN_FAILURE;
948
949
96.8M
        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
96.8M
            TRACE(("|%p|%p|REPEAT_ONE %d %d\n", pattern, ptr,
960
96.8M
                   pattern[1], pattern[2]));
961
962
96.8M
            if ((Py_ssize_t) pattern[1] > end - ptr)
963
685k
                RETURN_FAILURE; /* cannot match */
964
965
96.1M
            state->ptr = ptr;
966
967
96.1M
            ret = SRE(count)(state, pattern+3, pattern[2]);
968
96.1M
            RETURN_ON_ERROR(ret);
969
96.1M
            DATA_LOOKUP_AT(SRE(match_context), ctx, ctx_pos);
970
96.1M
            ctx->count = ret;
971
96.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
96.1M
            if (ctx->count < (Py_ssize_t) pattern[1])
979
51.3M
                RETURN_FAILURE;
980
981
44.7M
            if (pattern[pattern[0]] == SRE_OP_SUCCESS &&
982
504k
                ptr == state->end &&
983
73.1k
                !(ctx->toplevel && state->must_advance && ptr == state->start))
984
73.1k
            {
985
                /* tail is empty.  we're finished */
986
73.1k
                state->ptr = ptr;
987
73.1k
                RETURN_SUCCESS;
988
73.1k
            }
989
990
44.7M
            LASTMARK_SAVE();
991
44.7M
            if (state->save_marks)
992
31.3M
                MARK_PUSH(ctx->lastmark);
993
994
44.7M
            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.27M
                ctx->u.chr = pattern[pattern[0]+1];
998
2.27M
                for (;;) {
999
9.92M
                    while (ctx->count >= (Py_ssize_t) pattern[1] &&
1000
8.81M
                           (ptr >= end || *ptr != ctx->u.chr)) {
1001
7.65M
                        ptr--;
1002
7.65M
                        ctx->count--;
1003
7.65M
                    }
1004
2.27M
                    if (ctx->count < (Py_ssize_t) pattern[1])
1005
1.10M
                        break;
1006
1.16M
                    state->ptr = ptr;
1007
1.16M
                    DO_JUMP(JUMP_REPEAT_ONE_1, jump_repeat_one_1,
1008
1.16M
                            pattern+pattern[0]);
1009
1.16M
                    if (ret) {
1010
1.16M
                        if (state->save_marks)
1011
0
                            MARK_POP_DISCARD(ctx->lastmark);
1012
1.16M
                        RETURN_ON_ERROR(ret);
1013
1.16M
                        RETURN_SUCCESS;
1014
1.16M
                    }
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.10M
                if (state->save_marks)
1023
32
                    MARK_POP_DISCARD(ctx->lastmark);
1024
42.4M
            } else {
1025
                /* general case */
1026
49.9M
                while (ctx->count >= (Py_ssize_t) pattern[1]) {
1027
48.3M
                    state->ptr = ptr;
1028
48.3M
                    DO_JUMP(JUMP_REPEAT_ONE_2, jump_repeat_one_2,
1029
48.3M
                            pattern+pattern[0]);
1030
48.3M
                    if (ret) {
1031
40.7M
                        if (state->save_marks)
1032
30.1M
                            MARK_POP_DISCARD(ctx->lastmark);
1033
40.7M
                        RETURN_ON_ERROR(ret);
1034
40.7M
                        RETURN_SUCCESS;
1035
40.7M
                    }
1036
7.52M
                    if (state->save_marks)
1037
1.34M
                        MARK_POP_KEEP(ctx->lastmark);
1038
7.52M
                    LASTMARK_RESTORE();
1039
1040
7.52M
                    ptr--;
1041
7.52M
                    ctx->count--;
1042
7.52M
                }
1043
1.64M
                if (state->save_marks)
1044
1.18M
                    MARK_POP_DISCARD(ctx->lastmark);
1045
1.64M
            }
1046
2.75M
            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
19.1M
        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
19.1M
            TRACE(("|%p|%p|REPEAT %d %d\n", pattern, ptr,
1186
19.1M
                   pattern[1], pattern[2]));
1187
1188
            /* install new repeat context */
1189
19.1M
            ctx->u.rep = repeat_pool_malloc(state);
1190
19.1M
            if (!ctx->u.rep) {
1191
0
                RETURN_ERROR(SRE_ERROR_MEMORY);
1192
0
            }
1193
19.1M
            ctx->u.rep->count = -1;
1194
19.1M
            ctx->u.rep->pattern = pattern;
1195
19.1M
            ctx->u.rep->prev = state->repeat;
1196
19.1M
            ctx->u.rep->last_ptr = NULL;
1197
19.1M
            state->repeat = ctx->u.rep;
1198
19.1M
            state->save_marks++;
1199
1200
19.1M
            state->ptr = ptr;
1201
19.1M
            DO_JUMP(JUMP_REPEAT, jump_repeat, pattern+pattern[0]);
1202
19.1M
            state->repeat = ctx->u.rep->prev;
1203
19.1M
            state->save_marks--;
1204
19.1M
            repeat_pool_free(state, ctx->u.rep);
1205
1206
19.1M
            if (ret) {
1207
15.5M
                RETURN_ON_ERROR(ret);
1208
15.5M
                RETURN_SUCCESS;
1209
15.5M
            }
1210
3.61M
            RETURN_FAILURE;
1211
1212
62.7M
        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
62.7M
            ctx->u.rep = state->repeat;
1220
62.7M
            if (!ctx->u.rep)
1221
0
                RETURN_ERROR(SRE_ERROR_STATE);
1222
1223
62.7M
            state->ptr = ptr;
1224
1225
62.7M
            ctx->count = ctx->u.rep->count+1;
1226
1227
62.7M
            TRACE(("|%p|%p|MAX_UNTIL %zd\n", pattern,
1228
62.7M
                   ptr, ctx->count));
1229
1230
62.7M
            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
59.1M
            if ((ctx->count < (Py_ssize_t) ctx->u.rep->pattern[2] ||
1245
5.91M
                ctx->u.rep->pattern[2] == SRE_MAXREPEAT) &&
1246
53.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
53.2M
                ctx->u.rep->count = ctx->count;
1250
53.2M
                LASTMARK_SAVE();
1251
53.2M
                MARK_PUSH(ctx->lastmark);
1252
                /* zero-width match protection */
1253
53.2M
                LAST_PTR_PUSH();
1254
53.2M
                ctx->u.rep->last_ptr = state->ptr;
1255
53.2M
                DO_JUMP(JUMP_MAX_UNTIL_2, jump_max_until_2,
1256
53.2M
                        ctx->u.rep->pattern+3);
1257
53.2M
                LAST_PTR_POP();
1258
53.2M
                if (ret) {
1259
43.2M
                    MARK_POP_DISCARD(ctx->lastmark);
1260
43.2M
                    RETURN_ON_ERROR(ret);
1261
43.2M
                    RETURN_SUCCESS;
1262
43.2M
                }
1263
9.98M
                MARK_POP(ctx->lastmark);
1264
9.98M
                LASTMARK_RESTORE();
1265
9.98M
                ctx->u.rep->count = ctx->count-1;
1266
9.98M
                state->ptr = ptr;
1267
9.98M
            }
1268
1269
            /* cannot match more repeated items here.  make sure the
1270
               tail matches */
1271
15.8M
            state->repeat = ctx->u.rep->prev;
1272
15.8M
            state->save_marks--;
1273
15.8M
            DO_JUMP(JUMP_MAX_UNTIL_3, jump_max_until_3, pattern);
1274
15.8M
            state->repeat = ctx->u.rep; // restore repeat before return
1275
15.8M
            state->save_marks++;
1276
1277
15.8M
            RETURN_ON_SUCCESS(ret);
1278
356k
            state->ptr = ptr;
1279
356k
            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
343M
exit:
1681
343M
    ctx_pos = ctx->last_ctx_pos;
1682
343M
    jump = ctx->jump;
1683
343M
    DATA_POP_DISCARD(ctx);
1684
343M
    if (ctx_pos == -1) {
1685
129M
        state->sigcount = sigcount;
1686
129M
        return ret;
1687
129M
    }
1688
213M
    DATA_LOOKUP_AT(SRE(match_context), ctx, ctx_pos);
1689
1690
213M
    switch (jump) {
1691
53.2M
        case JUMP_MAX_UNTIL_2:
1692
53.2M
            TRACE(("|%p|%p|JUMP_MAX_UNTIL_2\n", pattern, ptr));
1693
53.2M
            goto jump_max_until_2;
1694
15.8M
        case JUMP_MAX_UNTIL_3:
1695
15.8M
            TRACE(("|%p|%p|JUMP_MAX_UNTIL_3\n", pattern, ptr));
1696
15.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
46.6M
        case JUMP_BRANCH:
1704
46.6M
            TRACE(("|%p|%p|JUMP_BRANCH\n", pattern, ptr));
1705
46.6M
            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
19.1M
        case JUMP_REPEAT:
1719
19.1M
            TRACE(("|%p|%p|JUMP_REPEAT\n", pattern, ptr));
1720
19.1M
            goto jump_repeat;
1721
1.16M
        case JUMP_REPEAT_ONE_1:
1722
1.16M
            TRACE(("|%p|%p|JUMP_REPEAT_ONE_1\n", pattern, ptr));
1723
1.16M
            goto jump_repeat_one_1;
1724
48.3M
        case JUMP_REPEAT_ONE_2:
1725
48.3M
            TRACE(("|%p|%p|JUMP_REPEAT_ONE_2\n", pattern, ptr));
1726
48.3M
            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
213M
    }
1744
1745
0
    return ret; /* should never get here */
1746
213M
}
sre.c:sre_ucs2_match
Line
Count
Source
663
177M
{
664
177M
    const SRE_CHAR* end = (const SRE_CHAR *)state->end;
665
177M
    Py_ssize_t alloc_pos, ctx_pos = -1;
666
177M
    Py_ssize_t ret = 0;
667
177M
    int jump;
668
177M
    unsigned int sigcount = state->sigcount;
669
670
177M
    SRE(match_context)* ctx;
671
177M
    SRE(match_context)* nextctx;
672
177M
    INIT_TRACE(state);
673
674
177M
    TRACE(("|%p|%p|ENTER\n", pattern, state->ptr));
675
676
177M
    DATA_ALLOC(SRE(match_context), ctx);
677
177M
    ctx->last_ctx_pos = -1;
678
177M
    ctx->jump = JUMP_NONE;
679
177M
    ctx->toplevel = toplevel;
680
177M
    ctx_pos = alloc_pos;
681
682
177M
#if USE_COMPUTED_GOTOS
683
177M
#include "sre_targets.h"
684
177M
#endif
685
686
398M
entrance:
687
688
398M
    ;  // Fashion statement.
689
398M
    const SRE_CHAR *ptr = (SRE_CHAR *)state->ptr;
690
691
398M
    if (pattern[0] == SRE_OP_INFO) {
692
        /* optimization info block */
693
        /* <INFO> <1=skip> <2=flags> <3=min> ... */
694
6.06M
        if (pattern[3] && (uintptr_t)(end - ptr) < pattern[3]) {
695
135k
            TRACE(("reject (got %tu chars, need %zu)\n",
696
135k
                   end - ptr, (size_t) pattern[3]));
697
135k
            RETURN_FAILURE;
698
135k
        }
699
5.92M
        pattern += pattern[1] + 1;
700
5.92M
    }
701
702
398M
#if USE_COMPUTED_GOTOS
703
398M
    DISPATCH;
704
#else
705
dispatch:
706
    MAYBE_CHECK_SIGNALS;
707
    switch (*pattern++)
708
#endif
709
398M
    {
710
711
398M
        TARGET(SRE_OP_MARK):
712
            /* set mark */
713
            /* <MARK> <gid> */
714
149M
            TRACE(("|%p|%p|MARK %d\n", pattern,
715
149M
                   ptr, pattern[0]));
716
149M
            {
717
149M
                int i = pattern[0];
718
149M
                if (i & 1)
719
12.5M
                    state->lastindex = i/2 + 1;
720
149M
                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
149M
                    int j = state->lastmark + 1;
726
152M
                    while (j < i)
727
3.45M
                        state->mark[j++] = NULL;
728
149M
                    state->lastmark = i;
729
149M
                }
730
149M
                state->mark[i] = ptr;
731
149M
            }
732
149M
            pattern++;
733
149M
            DISPATCH;
734
735
149M
        TARGET(SRE_OP_LITERAL):
736
            /* match literal string */
737
            /* <LITERAL> <code> */
738
15.9M
            TRACE(("|%p|%p|LITERAL %d\n", pattern,
739
15.9M
                   ptr, *pattern));
740
15.9M
            if (ptr >= end || (SRE_CODE) ptr[0] != pattern[0])
741
14.0M
                RETURN_FAILURE;
742
1.81M
            pattern++;
743
1.81M
            ptr++;
744
1.81M
            DISPATCH;
745
746
1.81M
        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
45.3M
        TARGET(SRE_OP_SUCCESS):
758
            /* end of pattern */
759
45.3M
            TRACE(("|%p|%p|SUCCESS\n", pattern, ptr));
760
45.3M
            if (ctx->toplevel &&
761
3.92M
                ((state->match_all && ptr != state->end) ||
762
3.92M
                 (state->must_advance && ptr == state->start)))
763
0
            {
764
0
                RETURN_FAILURE;
765
0
            }
766
45.3M
            state->ptr = ptr;
767
45.3M
            RETURN_SUCCESS;
768
769
4.36M
        TARGET(SRE_OP_AT):
770
            /* match at given position */
771
            /* <AT> <code> */
772
4.36M
            TRACE(("|%p|%p|AT %d\n", pattern, ptr, *pattern));
773
4.36M
            if (!SRE(at)(state, ptr, *pattern))
774
1.00M
                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
132M
        TARGET(SRE_OP_IN):
808
            /* match set member (or non_member) */
809
            /* <IN> <skip> <set> */
810
132M
            TRACE(("|%p|%p|IN\n", pattern, ptr));
811
132M
            if (ptr >= end ||
812
127M
                !SRE(charset)(state, pattern + 1, *ptr))
813
75.6M
                RETURN_FAILURE;
814
56.5M
            pattern += pattern[0];
815
56.5M
            ptr++;
816
56.5M
            DISPATCH;
817
818
56.5M
        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.51M
        TARGET(SRE_OP_JUMP):
908
1.51M
        TARGET(SRE_OP_INFO):
909
            /* jump forward */
910
            /* <JUMP> <offset> */
911
1.51M
            TRACE(("|%p|%p|JUMP %d\n", pattern,
912
1.51M
                   ptr, pattern[0]));
913
1.51M
            pattern += pattern[0];
914
1.51M
            DISPATCH;
915
916
3.76M
        TARGET(SRE_OP_BRANCH):
917
            /* alternation */
918
            /* <BRANCH> <0=skip> code <JUMP> ... <NULL> */
919
3.76M
            TRACE(("|%p|%p|BRANCH\n", pattern, ptr));
920
3.76M
            LASTMARK_SAVE();
921
3.76M
            if (state->save_marks)
922
9.19k
                MARK_PUSH(ctx->lastmark);
923
11.9M
            for (; pattern[0]; pattern += pattern[0]) {
924
8.69M
                if (pattern[1] == SRE_OP_LITERAL &&
925
3.84M
                    (ptr >= end ||
926
3.84M
                     (SRE_CODE) *ptr != pattern[2]))
927
2.28M
                    continue;
928
6.41M
                if (pattern[1] == SRE_OP_IN &&
929
435k
                    (ptr >= end ||
930
435k
                     !SRE(charset)(state, pattern + 3,
931
435k
                                   (SRE_CODE) *ptr)))
932
172k
                    continue;
933
6.24M
                state->ptr = ptr;
934
6.24M
                DO_JUMP(JUMP_BRANCH, jump_branch, pattern+1);
935
6.24M
                if (ret) {
936
556k
                    if (state->save_marks)
937
5.04k
                        MARK_POP_DISCARD(ctx->lastmark);
938
556k
                    RETURN_ON_ERROR(ret);
939
556k
                    RETURN_SUCCESS;
940
556k
                }
941
5.68M
                if (state->save_marks)
942
7.75k
                    MARK_POP_KEEP(ctx->lastmark);
943
5.68M
                LASTMARK_RESTORE();
944
5.68M
            }
945
3.21M
            if (state->save_marks)
946
4.14k
                MARK_POP_DISCARD(ctx->lastmark);
947
3.21M
            RETURN_FAILURE;
948
949
150M
        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
150M
            TRACE(("|%p|%p|REPEAT_ONE %d %d\n", pattern, ptr,
960
150M
                   pattern[1], pattern[2]));
961
962
150M
            if ((Py_ssize_t) pattern[1] > end - ptr)
963
129k
                RETURN_FAILURE; /* cannot match */
964
965
150M
            state->ptr = ptr;
966
967
150M
            ret = SRE(count)(state, pattern+3, pattern[2]);
968
150M
            RETURN_ON_ERROR(ret);
969
150M
            DATA_LOOKUP_AT(SRE(match_context), ctx, ctx_pos);
970
150M
            ctx->count = ret;
971
150M
            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
150M
            if (ctx->count < (Py_ssize_t) pattern[1])
979
128M
                RETURN_FAILURE;
980
981
22.1M
            if (pattern[pattern[0]] == SRE_OP_SUCCESS &&
982
1.96M
                ptr == state->end &&
983
18.7k
                !(ctx->toplevel && state->must_advance && ptr == state->start))
984
18.7k
            {
985
                /* tail is empty.  we're finished */
986
18.7k
                state->ptr = ptr;
987
18.7k
                RETURN_SUCCESS;
988
18.7k
            }
989
990
22.1M
            LASTMARK_SAVE();
991
22.1M
            if (state->save_marks)
992
17.5M
                MARK_PUSH(ctx->lastmark);
993
994
22.1M
            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
23.9k
                ctx->u.chr = pattern[pattern[0]+1];
998
23.9k
                for (;;) {
999
416k
                    while (ctx->count >= (Py_ssize_t) pattern[1] &&
1000
408k
                           (ptr >= end || *ptr != ctx->u.chr)) {
1001
392k
                        ptr--;
1002
392k
                        ctx->count--;
1003
392k
                    }
1004
23.9k
                    if (ctx->count < (Py_ssize_t) pattern[1])
1005
7.81k
                        break;
1006
16.1k
                    state->ptr = ptr;
1007
16.1k
                    DO_JUMP(JUMP_REPEAT_ONE_1, jump_repeat_one_1,
1008
16.1k
                            pattern+pattern[0]);
1009
16.1k
                    if (ret) {
1010
16.1k
                        if (state->save_marks)
1011
0
                            MARK_POP_DISCARD(ctx->lastmark);
1012
16.1k
                        RETURN_ON_ERROR(ret);
1013
16.1k
                        RETURN_SUCCESS;
1014
16.1k
                    }
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
7.81k
                if (state->save_marks)
1023
0
                    MARK_POP_DISCARD(ctx->lastmark);
1024
22.1M
            } else {
1025
                /* general case */
1026
31.0M
                while (ctx->count >= (Py_ssize_t) pattern[1]) {
1027
30.6M
                    state->ptr = ptr;
1028
30.6M
                    DO_JUMP(JUMP_REPEAT_ONE_2, jump_repeat_one_2,
1029
30.6M
                            pattern+pattern[0]);
1030
30.6M
                    if (ret) {
1031
21.7M
                        if (state->save_marks)
1032
17.2M
                            MARK_POP_DISCARD(ctx->lastmark);
1033
21.7M
                        RETURN_ON_ERROR(ret);
1034
21.7M
                        RETURN_SUCCESS;
1035
21.7M
                    }
1036
8.92M
                    if (state->save_marks)
1037
374k
                        MARK_POP_KEEP(ctx->lastmark);
1038
8.92M
                    LASTMARK_RESTORE();
1039
1040
8.92M
                    ptr--;
1041
8.92M
                    ctx->count--;
1042
8.92M
                }
1043
397k
                if (state->save_marks)
1044
323k
                    MARK_POP_DISCARD(ctx->lastmark);
1045
397k
            }
1046
405k
            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.35M
        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.35M
            TRACE(("|%p|%p|REPEAT %d %d\n", pattern, ptr,
1186
8.35M
                   pattern[1], pattern[2]));
1187
1188
            /* install new repeat context */
1189
8.35M
            ctx->u.rep = repeat_pool_malloc(state);
1190
8.35M
            if (!ctx->u.rep) {
1191
0
                RETURN_ERROR(SRE_ERROR_MEMORY);
1192
0
            }
1193
8.35M
            ctx->u.rep->count = -1;
1194
8.35M
            ctx->u.rep->pattern = pattern;
1195
8.35M
            ctx->u.rep->prev = state->repeat;
1196
8.35M
            ctx->u.rep->last_ptr = NULL;
1197
8.35M
            state->repeat = ctx->u.rep;
1198
8.35M
            state->save_marks++;
1199
1200
8.35M
            state->ptr = ptr;
1201
8.35M
            DO_JUMP(JUMP_REPEAT, jump_repeat, pattern+pattern[0]);
1202
8.35M
            state->repeat = ctx->u.rep->prev;
1203
8.35M
            state->save_marks--;
1204
8.35M
            repeat_pool_free(state, ctx->u.rep);
1205
1206
8.35M
            if (ret) {
1207
6.73M
                RETURN_ON_ERROR(ret);
1208
6.73M
                RETURN_SUCCESS;
1209
6.73M
            }
1210
1.62M
            RETURN_FAILURE;
1211
1212
95.7M
        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
95.7M
            ctx->u.rep = state->repeat;
1220
95.7M
            if (!ctx->u.rep)
1221
0
                RETURN_ERROR(SRE_ERROR_STATE);
1222
1223
95.7M
            state->ptr = ptr;
1224
1225
95.7M
            ctx->count = ctx->u.rep->count+1;
1226
1227
95.7M
            TRACE(("|%p|%p|MAX_UNTIL %zd\n", pattern,
1228
95.7M
                   ptr, ctx->count));
1229
1230
95.7M
            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
92.9M
            if ((ctx->count < (Py_ssize_t) ctx->u.rep->pattern[2] ||
1245
300k
                ctx->u.rep->pattern[2] == SRE_MAXREPEAT) &&
1246
92.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
92.6M
                ctx->u.rep->count = ctx->count;
1250
92.6M
                LASTMARK_SAVE();
1251
92.6M
                MARK_PUSH(ctx->lastmark);
1252
                /* zero-width match protection */
1253
92.6M
                LAST_PTR_PUSH();
1254
92.6M
                ctx->u.rep->last_ptr = state->ptr;
1255
92.6M
                DO_JUMP(JUMP_MAX_UNTIL_2, jump_max_until_2,
1256
92.6M
                        ctx->u.rep->pattern+3);
1257
92.6M
                LAST_PTR_POP();
1258
92.6M
                if (ret) {
1259
86.1M
                    MARK_POP_DISCARD(ctx->lastmark);
1260
86.1M
                    RETURN_ON_ERROR(ret);
1261
86.1M
                    RETURN_SUCCESS;
1262
86.1M
                }
1263
6.49M
                MARK_POP(ctx->lastmark);
1264
6.49M
                LASTMARK_RESTORE();
1265
6.49M
                ctx->u.rep->count = ctx->count-1;
1266
6.49M
                state->ptr = ptr;
1267
6.49M
            }
1268
1269
            /* cannot match more repeated items here.  make sure the
1270
               tail matches */
1271
6.79M
            state->repeat = ctx->u.rep->prev;
1272
6.79M
            state->save_marks--;
1273
6.79M
            DO_JUMP(JUMP_MAX_UNTIL_3, jump_max_until_3, pattern);
1274
6.79M
            state->repeat = ctx->u.rep; // restore repeat before return
1275
6.79M
            state->save_marks++;
1276
1277
6.79M
            RETURN_ON_SUCCESS(ret);
1278
62.1k
            state->ptr = ptr;
1279
62.1k
            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
398M
exit:
1681
398M
    ctx_pos = ctx->last_ctx_pos;
1682
398M
    jump = ctx->jump;
1683
398M
    DATA_POP_DISCARD(ctx);
1684
398M
    if (ctx_pos == -1) {
1685
177M
        state->sigcount = sigcount;
1686
177M
        return ret;
1687
177M
    }
1688
221M
    DATA_LOOKUP_AT(SRE(match_context), ctx, ctx_pos);
1689
1690
221M
    switch (jump) {
1691
92.6M
        case JUMP_MAX_UNTIL_2:
1692
92.6M
            TRACE(("|%p|%p|JUMP_MAX_UNTIL_2\n", pattern, ptr));
1693
92.6M
            goto jump_max_until_2;
1694
6.79M
        case JUMP_MAX_UNTIL_3:
1695
6.79M
            TRACE(("|%p|%p|JUMP_MAX_UNTIL_3\n", pattern, ptr));
1696
6.79M
            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.24M
        case JUMP_BRANCH:
1704
6.24M
            TRACE(("|%p|%p|JUMP_BRANCH\n", pattern, ptr));
1705
6.24M
            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.35M
        case JUMP_REPEAT:
1719
8.35M
            TRACE(("|%p|%p|JUMP_REPEAT\n", pattern, ptr));
1720
8.35M
            goto jump_repeat;
1721
16.1k
        case JUMP_REPEAT_ONE_1:
1722
16.1k
            TRACE(("|%p|%p|JUMP_REPEAT_ONE_1\n", pattern, ptr));
1723
16.1k
            goto jump_repeat_one_1;
1724
30.6M
        case JUMP_REPEAT_ONE_2:
1725
30.6M
            TRACE(("|%p|%p|JUMP_REPEAT_ONE_2\n", pattern, ptr));
1726
30.6M
            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
221M
    }
1744
1745
0
    return ret; /* should never get here */
1746
221M
}
sre.c:sre_ucs4_match
Line
Count
Source
663
33.6M
{
664
33.6M
    const SRE_CHAR* end = (const SRE_CHAR *)state->end;
665
33.6M
    Py_ssize_t alloc_pos, ctx_pos = -1;
666
33.6M
    Py_ssize_t ret = 0;
667
33.6M
    int jump;
668
33.6M
    unsigned int sigcount = state->sigcount;
669
670
33.6M
    SRE(match_context)* ctx;
671
33.6M
    SRE(match_context)* nextctx;
672
33.6M
    INIT_TRACE(state);
673
674
33.6M
    TRACE(("|%p|%p|ENTER\n", pattern, state->ptr));
675
676
33.6M
    DATA_ALLOC(SRE(match_context), ctx);
677
33.6M
    ctx->last_ctx_pos = -1;
678
33.6M
    ctx->jump = JUMP_NONE;
679
33.6M
    ctx->toplevel = toplevel;
680
33.6M
    ctx_pos = alloc_pos;
681
682
33.6M
#if USE_COMPUTED_GOTOS
683
33.6M
#include "sre_targets.h"
684
33.6M
#endif
685
686
113M
entrance:
687
688
113M
    ;  // Fashion statement.
689
113M
    const SRE_CHAR *ptr = (SRE_CHAR *)state->ptr;
690
691
113M
    if (pattern[0] == SRE_OP_INFO) {
692
        /* optimization info block */
693
        /* <INFO> <1=skip> <2=flags> <3=min> ... */
694
383k
        if (pattern[3] && (uintptr_t)(end - ptr) < pattern[3]) {
695
4.73k
            TRACE(("reject (got %tu chars, need %zu)\n",
696
4.73k
                   end - ptr, (size_t) pattern[3]));
697
4.73k
            RETURN_FAILURE;
698
4.73k
        }
699
378k
        pattern += pattern[1] + 1;
700
378k
    }
701
702
113M
#if USE_COMPUTED_GOTOS
703
113M
    DISPATCH;
704
#else
705
dispatch:
706
    MAYBE_CHECK_SIGNALS;
707
    switch (*pattern++)
708
#endif
709
113M
    {
710
711
113M
        TARGET(SRE_OP_MARK):
712
            /* set mark */
713
            /* <MARK> <gid> */
714
34.8M
            TRACE(("|%p|%p|MARK %d\n", pattern,
715
34.8M
                   ptr, pattern[0]));
716
34.8M
            {
717
34.8M
                int i = pattern[0];
718
34.8M
                if (i & 1)
719
6.76M
                    state->lastindex = i/2 + 1;
720
34.8M
                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
34.8M
                    int j = state->lastmark + 1;
726
34.8M
                    while (j < i)
727
39.4k
                        state->mark[j++] = NULL;
728
34.8M
                    state->lastmark = i;
729
34.8M
                }
730
34.8M
                state->mark[i] = ptr;
731
34.8M
            }
732
34.8M
            pattern++;
733
34.8M
            DISPATCH;
734
735
34.8M
        TARGET(SRE_OP_LITERAL):
736
            /* match literal string */
737
            /* <LITERAL> <code> */
738
6.90M
            TRACE(("|%p|%p|LITERAL %d\n", pattern,
739
6.90M
                   ptr, *pattern));
740
6.90M
            if (ptr >= end || (SRE_CODE) ptr[0] != pattern[0])
741
6.14M
                RETURN_FAILURE;
742
759k
            pattern++;
743
759k
            ptr++;
744
759k
            DISPATCH;
745
746
759k
        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.70M
        TARGET(SRE_OP_SUCCESS):
758
            /* end of pattern */
759
5.70M
            TRACE(("|%p|%p|SUCCESS\n", pattern, ptr));
760
5.70M
            if (ctx->toplevel &&
761
310k
                ((state->match_all && ptr != state->end) ||
762
310k
                 (state->must_advance && ptr == state->start)))
763
0
            {
764
0
                RETURN_FAILURE;
765
0
            }
766
5.70M
            state->ptr = ptr;
767
5.70M
            RETURN_SUCCESS;
768
769
631k
        TARGET(SRE_OP_AT):
770
            /* match at given position */
771
            /* <AT> <code> */
772
631k
            TRACE(("|%p|%p|AT %d\n", pattern, ptr, *pattern));
773
631k
            if (!SRE(at)(state, ptr, *pattern))
774
596k
                RETURN_FAILURE;
775
35.4k
            pattern++;
776
35.4k
            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
39.2M
        TARGET(SRE_OP_IN):
808
            /* match set member (or non_member) */
809
            /* <IN> <skip> <set> */
810
39.2M
            TRACE(("|%p|%p|IN\n", pattern, ptr));
811
39.2M
            if (ptr >= end ||
812
39.2M
                !SRE(charset)(state, pattern + 1, *ptr))
813
20.6M
                RETURN_FAILURE;
814
18.5M
            pattern += pattern[0];
815
18.5M
            ptr++;
816
18.5M
            DISPATCH;
817
818
18.5M
        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
651k
        TARGET(SRE_OP_JUMP):
908
651k
        TARGET(SRE_OP_INFO):
909
            /* jump forward */
910
            /* <JUMP> <offset> */
911
651k
            TRACE(("|%p|%p|JUMP %d\n", pattern,
912
651k
                   ptr, pattern[0]));
913
651k
            pattern += pattern[0];
914
651k
            DISPATCH;
915
916
699k
        TARGET(SRE_OP_BRANCH):
917
            /* alternation */
918
            /* <BRANCH> <0=skip> code <JUMP> ... <NULL> */
919
699k
            TRACE(("|%p|%p|BRANCH\n", pattern, ptr));
920
699k
            LASTMARK_SAVE();
921
699k
            if (state->save_marks)
922
2.47k
                MARK_PUSH(ctx->lastmark);
923
2.54M
            for (; pattern[0]; pattern += pattern[0]) {
924
1.93M
                if (pattern[1] == SRE_OP_LITERAL &&
925
1.82M
                    (ptr >= end ||
926
1.82M
                     (SRE_CODE) *ptr != pattern[2]))
927
1.08M
                    continue;
928
851k
                if (pattern[1] == SRE_OP_IN &&
929
49.0k
                    (ptr >= end ||
930
49.0k
                     !SRE(charset)(state, pattern + 3,
931
49.0k
                                   (SRE_CODE) *ptr)))
932
14.0k
                    continue;
933
837k
                state->ptr = ptr;
934
837k
                DO_JUMP(JUMP_BRANCH, jump_branch, pattern+1);
935
837k
                if (ret) {
936
84.9k
                    if (state->save_marks)
937
1.29k
                        MARK_POP_DISCARD(ctx->lastmark);
938
84.9k
                    RETURN_ON_ERROR(ret);
939
84.9k
                    RETURN_SUCCESS;
940
84.9k
                }
941
752k
                if (state->save_marks)
942
2.09k
                    MARK_POP_KEEP(ctx->lastmark);
943
752k
                LASTMARK_RESTORE();
944
752k
            }
945
614k
            if (state->save_marks)
946
1.18k
                MARK_POP_DISCARD(ctx->lastmark);
947
614k
            RETURN_FAILURE;
948
949
41.0M
        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.0M
            TRACE(("|%p|%p|REPEAT_ONE %d %d\n", pattern, ptr,
960
41.0M
                   pattern[1], pattern[2]));
961
962
41.0M
            if ((Py_ssize_t) pattern[1] > end - ptr)
963
9.22k
                RETURN_FAILURE; /* cannot match */
964
965
41.0M
            state->ptr = ptr;
966
967
41.0M
            ret = SRE(count)(state, pattern+3, pattern[2]);
968
41.0M
            RETURN_ON_ERROR(ret);
969
41.0M
            DATA_LOOKUP_AT(SRE(match_context), ctx, ctx_pos);
970
41.0M
            ctx->count = ret;
971
41.0M
            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.0M
            if (ctx->count < (Py_ssize_t) pattern[1])
979
27.2M
                RETURN_FAILURE;
980
981
13.7M
            if (pattern[pattern[0]] == SRE_OP_SUCCESS &&
982
261k
                ptr == state->end &&
983
2.28k
                !(ctx->toplevel && state->must_advance && ptr == state->start))
984
2.28k
            {
985
                /* tail is empty.  we're finished */
986
2.28k
                state->ptr = ptr;
987
2.28k
                RETURN_SUCCESS;
988
2.28k
            }
989
990
13.7M
            LASTMARK_SAVE();
991
13.7M
            if (state->save_marks)
992
13.3M
                MARK_PUSH(ctx->lastmark);
993
994
13.7M
            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.89k
                ctx->u.chr = pattern[pattern[0]+1];
998
3.89k
                for (;;) {
999
1.58M
                    while (ctx->count >= (Py_ssize_t) pattern[1] &&
1000
1.58M
                           (ptr >= end || *ptr != ctx->u.chr)) {
1001
1.58M
                        ptr--;
1002
1.58M
                        ctx->count--;
1003
1.58M
                    }
1004
3.89k
                    if (ctx->count < (Py_ssize_t) pattern[1])
1005
1.64k
                        break;
1006
2.24k
                    state->ptr = ptr;
1007
2.24k
                    DO_JUMP(JUMP_REPEAT_ONE_1, jump_repeat_one_1,
1008
2.24k
                            pattern+pattern[0]);
1009
2.24k
                    if (ret) {
1010
2.24k
                        if (state->save_marks)
1011
0
                            MARK_POP_DISCARD(ctx->lastmark);
1012
2.24k
                        RETURN_ON_ERROR(ret);
1013
2.24k
                        RETURN_SUCCESS;
1014
2.24k
                    }
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.64k
                if (state->save_marks)
1023
0
                    MARK_POP_DISCARD(ctx->lastmark);
1024
13.7M
            } else {
1025
                /* general case */
1026
19.8M
                while (ctx->count >= (Py_ssize_t) pattern[1]) {
1027
19.7M
                    state->ptr = ptr;
1028
19.7M
                    DO_JUMP(JUMP_REPEAT_ONE_2, jump_repeat_one_2,
1029
19.7M
                            pattern+pattern[0]);
1030
19.7M
                    if (ret) {
1031
13.7M
                        if (state->save_marks)
1032
13.2M
                            MARK_POP_DISCARD(ctx->lastmark);
1033
13.7M
                        RETURN_ON_ERROR(ret);
1034
13.7M
                        RETURN_SUCCESS;
1035
13.7M
                    }
1036
6.03M
                    if (state->save_marks)
1037
96.0k
                        MARK_POP_KEEP(ctx->lastmark);
1038
6.03M
                    LASTMARK_RESTORE();
1039
1040
6.03M
                    ptr--;
1041
6.03M
                    ctx->count--;
1042
6.03M
                }
1043
66.9k
                if (state->save_marks)
1044
61.5k
                    MARK_POP_DISCARD(ctx->lastmark);
1045
66.9k
            }
1046
68.6k
            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.85M
        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.85M
            TRACE(("|%p|%p|REPEAT %d %d\n", pattern, ptr,
1186
1.85M
                   pattern[1], pattern[2]));
1187
1188
            /* install new repeat context */
1189
1.85M
            ctx->u.rep = repeat_pool_malloc(state);
1190
1.85M
            if (!ctx->u.rep) {
1191
0
                RETURN_ERROR(SRE_ERROR_MEMORY);
1192
0
            }
1193
1.85M
            ctx->u.rep->count = -1;
1194
1.85M
            ctx->u.rep->pattern = pattern;
1195
1.85M
            ctx->u.rep->prev = state->repeat;
1196
1.85M
            ctx->u.rep->last_ptr = NULL;
1197
1.85M
            state->repeat = ctx->u.rep;
1198
1.85M
            state->save_marks++;
1199
1200
1.85M
            state->ptr = ptr;
1201
1.85M
            DO_JUMP(JUMP_REPEAT, jump_repeat, pattern+pattern[0]);
1202
1.85M
            state->repeat = ctx->u.rep->prev;
1203
1.85M
            state->save_marks--;
1204
1.85M
            repeat_pool_free(state, ctx->u.rep);
1205
1206
1.85M
            if (ret) {
1207
1.82M
                RETURN_ON_ERROR(ret);
1208
1.82M
                RETURN_SUCCESS;
1209
1.82M
            }
1210
32.9k
            RETURN_FAILURE;
1211
1212
34.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
34.9M
            ctx->u.rep = state->repeat;
1220
34.9M
            if (!ctx->u.rep)
1221
0
                RETURN_ERROR(SRE_ERROR_STATE);
1222
1223
34.9M
            state->ptr = ptr;
1224
1225
34.9M
            ctx->count = ctx->u.rep->count+1;
1226
1227
34.9M
            TRACE(("|%p|%p|MAX_UNTIL %zd\n", pattern,
1228
34.9M
                   ptr, ctx->count));
1229
1230
34.9M
            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
33.2M
            if ((ctx->count < (Py_ssize_t) ctx->u.rep->pattern[2] ||
1245
53.2k
                ctx->u.rep->pattern[2] == SRE_MAXREPEAT) &&
1246
33.1M
                state->ptr != ctx->u.rep->last_ptr) {
1247
                /* we may have enough matches, but if we can
1248
                   match another item, do so */
1249
33.1M
                ctx->u.rep->count = ctx->count;
1250
33.1M
                LASTMARK_SAVE();
1251
33.1M
                MARK_PUSH(ctx->lastmark);
1252
                /* zero-width match protection */
1253
33.1M
                LAST_PTR_PUSH();
1254
33.1M
                ctx->u.rep->last_ptr = state->ptr;
1255
33.1M
                DO_JUMP(JUMP_MAX_UNTIL_2, jump_max_until_2,
1256
33.1M
                        ctx->u.rep->pattern+3);
1257
33.1M
                LAST_PTR_POP();
1258
33.1M
                if (ret) {
1259
31.3M
                    MARK_POP_DISCARD(ctx->lastmark);
1260
31.3M
                    RETURN_ON_ERROR(ret);
1261
31.3M
                    RETURN_SUCCESS;
1262
31.3M
                }
1263
1.82M
                MARK_POP(ctx->lastmark);
1264
1.82M
                LASTMARK_RESTORE();
1265
1.82M
                ctx->u.rep->count = ctx->count-1;
1266
1.82M
                state->ptr = ptr;
1267
1.82M
            }
1268
1269
            /* cannot match more repeated items here.  make sure the
1270
               tail matches */
1271
1.87M
            state->repeat = ctx->u.rep->prev;
1272
1.87M
            state->save_marks--;
1273
1.87M
            DO_JUMP(JUMP_MAX_UNTIL_3, jump_max_until_3, pattern);
1274
1.87M
            state->repeat = ctx->u.rep; // restore repeat before return
1275
1.87M
            state->save_marks++;
1276
1277
1.87M
            RETURN_ON_SUCCESS(ret);
1278
53.7k
            state->ptr = ptr;
1279
53.7k
            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
113M
exit:
1681
113M
    ctx_pos = ctx->last_ctx_pos;
1682
113M
    jump = ctx->jump;
1683
113M
    DATA_POP_DISCARD(ctx);
1684
113M
    if (ctx_pos == -1) {
1685
33.6M
        state->sigcount = sigcount;
1686
33.6M
        return ret;
1687
33.6M
    }
1688
79.8M
    DATA_LOOKUP_AT(SRE(match_context), ctx, ctx_pos);
1689
1690
79.8M
    switch (jump) {
1691
33.1M
        case JUMP_MAX_UNTIL_2:
1692
33.1M
            TRACE(("|%p|%p|JUMP_MAX_UNTIL_2\n", pattern, ptr));
1693
33.1M
            goto jump_max_until_2;
1694
1.87M
        case JUMP_MAX_UNTIL_3:
1695
1.87M
            TRACE(("|%p|%p|JUMP_MAX_UNTIL_3\n", pattern, ptr));
1696
1.87M
            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
837k
        case JUMP_BRANCH:
1704
837k
            TRACE(("|%p|%p|JUMP_BRANCH\n", pattern, ptr));
1705
837k
            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.85M
        case JUMP_REPEAT:
1719
1.85M
            TRACE(("|%p|%p|JUMP_REPEAT\n", pattern, ptr));
1720
1.85M
            goto jump_repeat;
1721
2.24k
        case JUMP_REPEAT_ONE_1:
1722
2.24k
            TRACE(("|%p|%p|JUMP_REPEAT_ONE_1\n", pattern, ptr));
1723
2.24k
            goto jump_repeat_one_1;
1724
19.7M
        case JUMP_REPEAT_ONE_2:
1725
19.7M
            TRACE(("|%p|%p|JUMP_REPEAT_ONE_2\n", pattern, ptr));
1726
19.7M
            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
79.8M
    }
1744
1745
0
    return ret; /* should never get here */
1746
79.8M
}
1747
1748
/* need to reset capturing groups between two SRE(match) callings in loops */
1749
#define RESET_CAPTURE_GROUP() \
1750
206M
    do { state->lastmark = state->lastindex = -1; } while (0)
1751
1752
LOCAL(Py_ssize_t)
1753
SRE(search)(SRE_STATE* state, SRE_CODE* pattern)
1754
97.1M
{
1755
97.1M
    SRE_CHAR* ptr = (SRE_CHAR *)state->start;
1756
97.1M
    SRE_CHAR* end = (SRE_CHAR *)state->end;
1757
97.1M
    Py_ssize_t status = 0;
1758
97.1M
    Py_ssize_t prefix_len = 0;
1759
97.1M
    Py_ssize_t prefix_skip = 0;
1760
97.1M
    SRE_CODE* prefix = NULL;
1761
97.1M
    SRE_CODE* charset = NULL;
1762
97.1M
    SRE_CODE* overlap = NULL;
1763
97.1M
    int flags = 0;
1764
97.1M
    INIT_TRACE(state);
1765
1766
97.1M
    if (ptr > end)
1767
0
        return 0;
1768
1769
97.1M
    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
97.1M
        flags = pattern[2];
1774
1775
97.1M
        if (pattern[3] && (uintptr_t)(end - ptr) < pattern[3]) {
1776
2.69M
            TRACE(("reject (got %tu chars, need %zu)\n",
1777
2.69M
                   end - ptr, (size_t) pattern[3]));
1778
2.69M
            return 0;
1779
2.69M
        }
1780
94.4M
        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
52.2k
            end -= pattern[3] - 1;
1784
52.2k
            if (end <= ptr)
1785
0
                end = ptr;
1786
52.2k
        }
1787
1788
94.4M
        if (flags & SRE_INFO_PREFIX) {
1789
            /* pattern starts with a known prefix */
1790
            /* <length> <skip> <prefix data> <overlap data> */
1791
52.2k
            prefix_len = pattern[5];
1792
52.2k
            prefix_skip = pattern[6];
1793
52.2k
            prefix = pattern + 7;
1794
52.2k
            overlap = prefix + prefix_len - 1;
1795
94.4M
        } else if (flags & SRE_INFO_CHARSET)
1796
            /* pattern starts with a character from a known set */
1797
            /* <charset> */
1798
85.1M
            charset = pattern + 5;
1799
1800
94.4M
        pattern += 1 + pattern[1];
1801
94.4M
    }
1802
1803
94.4M
    TRACE(("prefix = %p %zd %zd\n",
1804
94.4M
           prefix, prefix_len, prefix_skip));
1805
94.4M
    TRACE(("charset = %p\n", charset));
1806
1807
94.4M
    if (prefix_len == 1) {
1808
        /* pattern starts with a literal character */
1809
52.2k
        SRE_CHAR c = (SRE_CHAR) prefix[0];
1810
#if SIZEOF_SRE_CHAR < 4
1811
52.2k
        if ((SRE_CODE) c != prefix[0])
1812
0
            return 0; /* literal can't match: doesn't fit in char width */
1813
52.2k
#endif
1814
52.2k
        end = (SRE_CHAR *)state->end;
1815
52.2k
        state->must_advance = 0;
1816
80.8k
        while (ptr < end) {
1817
15.6M
            while (*ptr != c) {
1818
15.6M
                if (++ptr >= end)
1819
17.3k
                    return 0;
1820
15.6M
            }
1821
59.4k
            TRACE(("|%p|%p|SEARCH LITERAL\n", pattern, ptr));
1822
59.4k
            state->start = ptr;
1823
59.4k
            state->ptr = ptr + prefix_skip;
1824
59.4k
            if (flags & SRE_INFO_LITERAL)
1825
0
                return 1; /* we got all of it */
1826
59.4k
            status = SRE(match)(state, pattern + 2*prefix_skip, 0);
1827
59.4k
            if (status != 0)
1828
30.9k
                return status;
1829
28.5k
            ++ptr;
1830
28.5k
            RESET_CAPTURE_GROUP();
1831
28.5k
        }
1832
3.99k
        return 0;
1833
52.2k
    }
1834
1835
94.4M
    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
94.4M
    if (charset) {
1887
        /* pattern starts with a character from a known set */
1888
85.1M
        end = (SRE_CHAR *)state->end;
1889
85.1M
        state->must_advance = 0;
1890
88.5M
        for (;;) {
1891
372M
            while (ptr < end && !SRE(charset)(state, charset, *ptr))
1892
284M
                ptr++;
1893
88.5M
            if (ptr >= end)
1894
3.62M
                return 0;
1895
84.8M
            TRACE(("|%p|%p|SEARCH CHARSET\n", pattern, ptr));
1896
84.8M
            state->start = ptr;
1897
84.8M
            state->ptr = ptr;
1898
84.8M
            status = SRE(match)(state, pattern, 0);
1899
84.8M
            if (status != 0)
1900
81.5M
                break;
1901
3.31M
            ptr++;
1902
3.31M
            RESET_CAPTURE_GROUP();
1903
3.31M
        }
1904
85.1M
    } else {
1905
        /* general case */
1906
9.21M
        assert(ptr <= end);
1907
9.21M
        TRACE(("|%p|%p|SEARCH\n", pattern, ptr));
1908
9.21M
        state->start = state->ptr = ptr;
1909
9.21M
        status = SRE(match)(state, pattern, 1);
1910
9.21M
        state->must_advance = 0;
1911
9.21M
        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
207M
        while (status == 0 && ptr < end) {
1919
203M
            ptr++;
1920
203M
            RESET_CAPTURE_GROUP();
1921
203M
            TRACE(("|%p|%p|SEARCH\n", pattern, ptr));
1922
203M
            state->start = state->ptr = ptr;
1923
203M
            status = SRE(match)(state, pattern, 0);
1924
203M
        }
1925
3.88M
    }
1926
1927
85.4M
    return status;
1928
94.4M
}
sre.c:sre_ucs1_search
Line
Count
Source
1754
47.7M
{
1755
47.7M
    SRE_CHAR* ptr = (SRE_CHAR *)state->start;
1756
47.7M
    SRE_CHAR* end = (SRE_CHAR *)state->end;
1757
47.7M
    Py_ssize_t status = 0;
1758
47.7M
    Py_ssize_t prefix_len = 0;
1759
47.7M
    Py_ssize_t prefix_skip = 0;
1760
47.7M
    SRE_CODE* prefix = NULL;
1761
47.7M
    SRE_CODE* charset = NULL;
1762
47.7M
    SRE_CODE* overlap = NULL;
1763
47.7M
    int flags = 0;
1764
47.7M
    INIT_TRACE(state);
1765
1766
47.7M
    if (ptr > end)
1767
0
        return 0;
1768
1769
47.7M
    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
47.7M
        flags = pattern[2];
1774
1775
47.7M
        if (pattern[3] && (uintptr_t)(end - ptr) < pattern[3]) {
1776
2.62M
            TRACE(("reject (got %tu chars, need %zu)\n",
1777
2.62M
                   end - ptr, (size_t) pattern[3]));
1778
2.62M
            return 0;
1779
2.62M
        }
1780
45.0M
        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
52.2k
            end -= pattern[3] - 1;
1784
52.2k
            if (end <= ptr)
1785
0
                end = ptr;
1786
52.2k
        }
1787
1788
45.0M
        if (flags & SRE_INFO_PREFIX) {
1789
            /* pattern starts with a known prefix */
1790
            /* <length> <skip> <prefix data> <overlap data> */
1791
52.2k
            prefix_len = pattern[5];
1792
52.2k
            prefix_skip = pattern[6];
1793
52.2k
            prefix = pattern + 7;
1794
52.2k
            overlap = prefix + prefix_len - 1;
1795
45.0M
        } else if (flags & SRE_INFO_CHARSET)
1796
            /* pattern starts with a character from a known set */
1797
            /* <charset> */
1798
38.3M
            charset = pattern + 5;
1799
1800
45.0M
        pattern += 1 + pattern[1];
1801
45.0M
    }
1802
1803
45.0M
    TRACE(("prefix = %p %zd %zd\n",
1804
45.0M
           prefix, prefix_len, prefix_skip));
1805
45.0M
    TRACE(("charset = %p\n", charset));
1806
1807
45.0M
    if (prefix_len == 1) {
1808
        /* pattern starts with a literal character */
1809
52.2k
        SRE_CHAR c = (SRE_CHAR) prefix[0];
1810
52.2k
#if SIZEOF_SRE_CHAR < 4
1811
52.2k
        if ((SRE_CODE) c != prefix[0])
1812
0
            return 0; /* literal can't match: doesn't fit in char width */
1813
52.2k
#endif
1814
52.2k
        end = (SRE_CHAR *)state->end;
1815
52.2k
        state->must_advance = 0;
1816
80.8k
        while (ptr < end) {
1817
15.6M
            while (*ptr != c) {
1818
15.6M
                if (++ptr >= end)
1819
17.3k
                    return 0;
1820
15.6M
            }
1821
59.4k
            TRACE(("|%p|%p|SEARCH LITERAL\n", pattern, ptr));
1822
59.4k
            state->start = ptr;
1823
59.4k
            state->ptr = ptr + prefix_skip;
1824
59.4k
            if (flags & SRE_INFO_LITERAL)
1825
0
                return 1; /* we got all of it */
1826
59.4k
            status = SRE(match)(state, pattern + 2*prefix_skip, 0);
1827
59.4k
            if (status != 0)
1828
30.9k
                return status;
1829
28.5k
            ++ptr;
1830
28.5k
            RESET_CAPTURE_GROUP();
1831
28.5k
        }
1832
3.99k
        return 0;
1833
52.2k
    }
1834
1835
45.0M
    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
45.0M
    if (charset) {
1887
        /* pattern starts with a character from a known set */
1888
38.3M
        end = (SRE_CHAR *)state->end;
1889
38.3M
        state->must_advance = 0;
1890
40.2M
        for (;;) {
1891
100M
            while (ptr < end && !SRE(charset)(state, charset, *ptr))
1892
59.8M
                ptr++;
1893
40.2M
            if (ptr >= end)
1894
2.63M
                return 0;
1895
37.5M
            TRACE(("|%p|%p|SEARCH CHARSET\n", pattern, ptr));
1896
37.5M
            state->start = ptr;
1897
37.5M
            state->ptr = ptr;
1898
37.5M
            status = SRE(match)(state, pattern, 0);
1899
37.5M
            if (status != 0)
1900
35.7M
                break;
1901
1.80M
            ptr++;
1902
1.80M
            RESET_CAPTURE_GROUP();
1903
1.80M
        }
1904
38.3M
    } else {
1905
        /* general case */
1906
6.64M
        assert(ptr <= end);
1907
6.64M
        TRACE(("|%p|%p|SEARCH\n", pattern, ptr));
1908
6.64M
        state->start = state->ptr = ptr;
1909
6.64M
        status = SRE(match)(state, pattern, 1);
1910
6.64M
        state->must_advance = 0;
1911
6.64M
        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
51.5M
        while (status == 0 && ptr < end) {
1919
48.4M
            ptr++;
1920
48.4M
            RESET_CAPTURE_GROUP();
1921
48.4M
            TRACE(("|%p|%p|SEARCH\n", pattern, ptr));
1922
48.4M
            state->start = state->ptr = ptr;
1923
48.4M
            status = SRE(match)(state, pattern, 0);
1924
48.4M
        }
1925
3.04M
    }
1926
1927
38.8M
    return status;
1928
45.0M
}
sre.c:sre_ucs2_search
Line
Count
Source
1754
43.9M
{
1755
43.9M
    SRE_CHAR* ptr = (SRE_CHAR *)state->start;
1756
43.9M
    SRE_CHAR* end = (SRE_CHAR *)state->end;
1757
43.9M
    Py_ssize_t status = 0;
1758
43.9M
    Py_ssize_t prefix_len = 0;
1759
43.9M
    Py_ssize_t prefix_skip = 0;
1760
43.9M
    SRE_CODE* prefix = NULL;
1761
43.9M
    SRE_CODE* charset = NULL;
1762
43.9M
    SRE_CODE* overlap = NULL;
1763
43.9M
    int flags = 0;
1764
43.9M
    INIT_TRACE(state);
1765
1766
43.9M
    if (ptr > end)
1767
0
        return 0;
1768
1769
43.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
43.9M
        flags = pattern[2];
1774
1775
43.9M
        if (pattern[3] && (uintptr_t)(end - ptr) < pattern[3]) {
1776
69.6k
            TRACE(("reject (got %tu chars, need %zu)\n",
1777
69.6k
                   end - ptr, (size_t) pattern[3]));
1778
69.6k
            return 0;
1779
69.6k
        }
1780
43.9M
        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
43.9M
        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
43.9M
        } else if (flags & SRE_INFO_CHARSET)
1796
            /* pattern starts with a character from a known set */
1797
            /* <charset> */
1798
41.4M
            charset = pattern + 5;
1799
1800
43.9M
        pattern += 1 + pattern[1];
1801
43.9M
    }
1802
1803
43.9M
    TRACE(("prefix = %p %zd %zd\n",
1804
43.9M
           prefix, prefix_len, prefix_skip));
1805
43.9M
    TRACE(("charset = %p\n", charset));
1806
1807
43.9M
    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
43.9M
    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
43.9M
    if (charset) {
1887
        /* pattern starts with a character from a known set */
1888
41.4M
        end = (SRE_CHAR *)state->end;
1889
41.4M
        state->must_advance = 0;
1890
42.4M
        for (;;) {
1891
208M
            while (ptr < end && !SRE(charset)(state, charset, *ptr))
1892
165M
                ptr++;
1893
42.4M
            if (ptr >= end)
1894
945k
                return 0;
1895
41.4M
            TRACE(("|%p|%p|SEARCH CHARSET\n", pattern, ptr));
1896
41.4M
            state->start = ptr;
1897
41.4M
            state->ptr = ptr;
1898
41.4M
            status = SRE(match)(state, pattern, 0);
1899
41.4M
            if (status != 0)
1900
40.5M
                break;
1901
949k
            ptr++;
1902
949k
            RESET_CAPTURE_GROUP();
1903
949k
        }
1904
41.4M
    } else {
1905
        /* general case */
1906
2.43M
        assert(ptr <= end);
1907
2.43M
        TRACE(("|%p|%p|SEARCH\n", pattern, ptr));
1908
2.43M
        state->start = state->ptr = ptr;
1909
2.43M
        status = SRE(match)(state, pattern, 1);
1910
2.43M
        state->must_advance = 0;
1911
2.43M
        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
128M
        while (status == 0 && ptr < end) {
1919
127M
            ptr++;
1920
127M
            RESET_CAPTURE_GROUP();
1921
127M
            TRACE(("|%p|%p|SEARCH\n", pattern, ptr));
1922
127M
            state->start = state->ptr = ptr;
1923
127M
            status = SRE(match)(state, pattern, 0);
1924
127M
        }
1925
718k
    }
1926
1927
41.2M
    return status;
1928
43.9M
}
sre.c:sre_ucs4_search
Line
Count
Source
1754
5.45M
{
1755
5.45M
    SRE_CHAR* ptr = (SRE_CHAR *)state->start;
1756
5.45M
    SRE_CHAR* end = (SRE_CHAR *)state->end;
1757
5.45M
    Py_ssize_t status = 0;
1758
5.45M
    Py_ssize_t prefix_len = 0;
1759
5.45M
    Py_ssize_t prefix_skip = 0;
1760
5.45M
    SRE_CODE* prefix = NULL;
1761
5.45M
    SRE_CODE* charset = NULL;
1762
5.45M
    SRE_CODE* overlap = NULL;
1763
5.45M
    int flags = 0;
1764
5.45M
    INIT_TRACE(state);
1765
1766
5.45M
    if (ptr > end)
1767
0
        return 0;
1768
1769
5.45M
    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.45M
        flags = pattern[2];
1774
1775
5.45M
        if (pattern[3] && (uintptr_t)(end - ptr) < pattern[3]) {
1776
3.79k
            TRACE(("reject (got %tu chars, need %zu)\n",
1777
3.79k
                   end - ptr, (size_t) pattern[3]));
1778
3.79k
            return 0;
1779
3.79k
        }
1780
5.45M
        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.45M
        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.45M
        } else if (flags & SRE_INFO_CHARSET)
1796
            /* pattern starts with a character from a known set */
1797
            /* <charset> */
1798
5.31M
            charset = pattern + 5;
1799
1800
5.45M
        pattern += 1 + pattern[1];
1801
5.45M
    }
1802
1803
5.45M
    TRACE(("prefix = %p %zd %zd\n",
1804
5.45M
           prefix, prefix_len, prefix_skip));
1805
5.45M
    TRACE(("charset = %p\n", charset));
1806
1807
5.45M
    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.45M
    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.45M
    if (charset) {
1887
        /* pattern starts with a character from a known set */
1888
5.31M
        end = (SRE_CHAR *)state->end;
1889
5.31M
        state->must_advance = 0;
1890
5.87M
        for (;;) {
1891
64.5M
            while (ptr < end && !SRE(charset)(state, charset, *ptr))
1892
58.6M
                ptr++;
1893
5.87M
            if (ptr >= end)
1894
49.0k
                return 0;
1895
5.83M
            TRACE(("|%p|%p|SEARCH CHARSET\n", pattern, ptr));
1896
5.83M
            state->start = ptr;
1897
5.83M
            state->ptr = ptr;
1898
5.83M
            status = SRE(match)(state, pattern, 0);
1899
5.83M
            if (status != 0)
1900
5.26M
                break;
1901
561k
            ptr++;
1902
561k
            RESET_CAPTURE_GROUP();
1903
561k
        }
1904
5.31M
    } else {
1905
        /* general case */
1906
132k
        assert(ptr <= end);
1907
132k
        TRACE(("|%p|%p|SEARCH\n", pattern, ptr));
1908
132k
        state->start = state->ptr = ptr;
1909
132k
        status = SRE(match)(state, pattern, 1);
1910
132k
        state->must_advance = 0;
1911
132k
        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.3M
        while (status == 0 && ptr < end) {
1919
27.2M
            ptr++;
1920
27.2M
            RESET_CAPTURE_GROUP();
1921
27.2M
            TRACE(("|%p|%p|SEARCH\n", pattern, ptr));
1922
27.2M
            state->start = state->ptr = ptr;
1923
27.2M
            status = SRE(match)(state, pattern, 0);
1924
27.2M
        }
1925
116k
    }
1926
1927
5.38M
    return status;
1928
5.45M
}
1929
1930
#undef SRE_CHAR
1931
#undef SIZEOF_SRE_CHAR
1932
#undef SRE
1933
1934
/* vim:ts=4:sw=4:et
1935
*/