/src/libgit2/deps/pcre2/pcre2_find_bracket.c
Line | Count | Source |
1 | | /************************************************* |
2 | | * Perl-Compatible Regular Expressions * |
3 | | *************************************************/ |
4 | | |
5 | | /* PCRE is a library of functions to support regular expressions whose syntax |
6 | | and semantics are as close as possible to those of the Perl 5 language. |
7 | | |
8 | | Written by Philip Hazel |
9 | | Original API code Copyright (c) 1997-2012 University of Cambridge |
10 | | New API code Copyright (c) 2016-2024 University of Cambridge |
11 | | |
12 | | ----------------------------------------------------------------------------- |
13 | | Redistribution and use in source and binary forms, with or without |
14 | | modification, are permitted provided that the following conditions are met: |
15 | | |
16 | | * Redistributions of source code must retain the above copyright notice, |
17 | | this list of conditions and the following disclaimer. |
18 | | |
19 | | * Redistributions in binary form must reproduce the above copyright |
20 | | notice, this list of conditions and the following disclaimer in the |
21 | | documentation and/or other materials provided with the distribution. |
22 | | |
23 | | * Neither the name of the University of Cambridge nor the names of its |
24 | | contributors may be used to endorse or promote products derived from |
25 | | this software without specific prior written permission. |
26 | | |
27 | | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
28 | | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
29 | | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
30 | | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE |
31 | | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
32 | | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
33 | | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
34 | | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
35 | | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
36 | | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
37 | | POSSIBILITY OF SUCH DAMAGE. |
38 | | ----------------------------------------------------------------------------- |
39 | | */ |
40 | | |
41 | | |
42 | | /* This module contains a single function that scans through a compiled pattern |
43 | | until it finds a capturing bracket with the given number, or, if the number is |
44 | | negative, an instance of OP_REVERSE or OP_VREVERSE for a lookbehind. The |
45 | | function is called from pcre2_compile.c and also from pcre2_study.c when |
46 | | finding the minimum matching length. */ |
47 | | |
48 | | |
49 | | #include "pcre2_internal.h" |
50 | | |
51 | | |
52 | | |
53 | | /************************************************* |
54 | | * Scan compiled regex for specific bracket * |
55 | | *************************************************/ |
56 | | |
57 | | /* |
58 | | Arguments: |
59 | | code points to start of expression |
60 | | utf TRUE in UTF mode |
61 | | number the required bracket number or negative to find a lookbehind |
62 | | |
63 | | Returns: pointer to the opcode for the bracket, or NULL if not found |
64 | | */ |
65 | | |
66 | | PCRE2_SPTR |
67 | | PRIV(find_bracket)(PCRE2_SPTR code, BOOL utf, int number) |
68 | 17.2k | { |
69 | 17.2k | for (;;) |
70 | 1.74M | { |
71 | 1.74M | PCRE2_UCHAR c = *code; |
72 | | |
73 | 1.74M | if (c == OP_END) return NULL; |
74 | | |
75 | | /* XCLASS is used for classes that cannot be represented just by a bit map. |
76 | | This includes negated single high-valued characters. ECLASS is used for |
77 | | classes that use set operations internally. CALLOUT_STR is used for |
78 | | callouts with string arguments. In each case the length in the table is |
79 | | zero; the actual length is stored in the compiled code. */ |
80 | | |
81 | 1.74M | if (c == OP_XCLASS || c == OP_ECLASS) code += GET(code, 1); |
82 | 1.73M | else if (c == OP_CALLOUT_STR) code += GET(code, 1 + 2*LINK_SIZE); |
83 | | |
84 | | /* Handle lookbehind */ |
85 | | |
86 | 1.73M | else if (c == OP_REVERSE || c == OP_VREVERSE) |
87 | 1.31k | { |
88 | 1.31k | if (number < 0) return code; |
89 | 1.31k | code += PRIV(OP_lengths)[c]; |
90 | 1.31k | } |
91 | | |
92 | | /* Handle capturing bracket */ |
93 | | |
94 | 1.73M | else if (c == OP_CBRA || c == OP_SCBRA || |
95 | 1.43M | c == OP_CBRAPOS || c == OP_SCBRAPOS) |
96 | 301k | { |
97 | 301k | int n = (int)GET2(code, 1+LINK_SIZE); |
98 | 301k | if (n == number) return code; |
99 | 284k | code += PRIV(OP_lengths)[c]; |
100 | 284k | } |
101 | | |
102 | | /* Otherwise, we can get the item's length from the table, except that for |
103 | | repeated character types, we have to test for \p and \P, which have an extra |
104 | | two bytes of parameters, and for MARK/PRUNE/SKIP/THEN with an argument, we |
105 | | must add in its length. */ |
106 | | |
107 | 1.43M | else |
108 | 1.43M | { |
109 | 1.43M | switch(c) |
110 | 1.43M | { |
111 | 296 | case OP_TYPESTAR: |
112 | 1.38k | case OP_TYPEMINSTAR: |
113 | 4.49k | case OP_TYPEPLUS: |
114 | 5.51k | case OP_TYPEMINPLUS: |
115 | 7.29k | case OP_TYPEQUERY: |
116 | 7.62k | case OP_TYPEMINQUERY: |
117 | 7.98k | case OP_TYPEPOSSTAR: |
118 | 11.7k | case OP_TYPEPOSPLUS: |
119 | 12.0k | case OP_TYPEPOSQUERY: |
120 | 12.0k | if (code[1] == OP_PROP || code[1] == OP_NOTPROP) code += 2; |
121 | 12.0k | break; |
122 | | |
123 | 1.26k | case OP_TYPEUPTO: |
124 | 1.90k | case OP_TYPEMINUPTO: |
125 | 2.68k | case OP_TYPEEXACT: |
126 | 2.91k | case OP_TYPEPOSUPTO: |
127 | 2.91k | if (code[1 + IMM2_SIZE] == OP_PROP || code[1 + IMM2_SIZE] == OP_NOTPROP) |
128 | 696 | code += 2; |
129 | 2.91k | break; |
130 | | |
131 | 874 | case OP_MARK: |
132 | 1.45k | case OP_COMMIT_ARG: |
133 | 1.71k | case OP_PRUNE_ARG: |
134 | 2.03k | case OP_SKIP_ARG: |
135 | 2.37k | case OP_THEN_ARG: |
136 | 2.37k | code += code[1]; |
137 | 2.37k | break; |
138 | 1.43M | } |
139 | | |
140 | | /* Add in the fixed length from the table */ |
141 | | |
142 | 1.43M | code += PRIV(OP_lengths)[c]; |
143 | | |
144 | | /* In UTF-8 and UTF-16 modes, opcodes that are followed by a character may be |
145 | | followed by a multi-byte character. The length in the table is a minimum, so |
146 | | we have to arrange to skip the extra bytes. */ |
147 | | |
148 | 1.43M | #ifdef MAYBE_UTF_MULTI |
149 | 1.43M | if (utf) switch(c) |
150 | 30.0k | { |
151 | 7.35k | case OP_CHAR: |
152 | 7.40k | case OP_CHARI: |
153 | 7.40k | case OP_NOT: |
154 | 7.40k | case OP_NOTI: |
155 | 7.40k | case OP_EXACT: |
156 | 7.40k | case OP_EXACTI: |
157 | 7.40k | case OP_NOTEXACT: |
158 | 7.40k | case OP_NOTEXACTI: |
159 | 7.40k | case OP_UPTO: |
160 | 7.40k | case OP_UPTOI: |
161 | 7.40k | case OP_NOTUPTO: |
162 | 7.40k | case OP_NOTUPTOI: |
163 | 7.40k | case OP_MINUPTO: |
164 | 7.40k | case OP_MINUPTOI: |
165 | 7.40k | case OP_NOTMINUPTO: |
166 | 7.40k | case OP_NOTMINUPTOI: |
167 | 7.40k | case OP_POSUPTO: |
168 | 7.40k | case OP_POSUPTOI: |
169 | 7.40k | case OP_NOTPOSUPTO: |
170 | 7.40k | case OP_NOTPOSUPTOI: |
171 | 7.40k | case OP_STAR: |
172 | 7.40k | case OP_STARI: |
173 | 7.40k | case OP_NOTSTAR: |
174 | 7.40k | case OP_NOTSTARI: |
175 | 7.40k | case OP_MINSTAR: |
176 | 7.40k | case OP_MINSTARI: |
177 | 7.40k | case OP_NOTMINSTAR: |
178 | 7.40k | case OP_NOTMINSTARI: |
179 | 7.40k | case OP_POSSTAR: |
180 | 7.40k | case OP_POSSTARI: |
181 | 7.40k | case OP_NOTPOSSTAR: |
182 | 7.40k | case OP_NOTPOSSTARI: |
183 | 7.40k | case OP_PLUS: |
184 | 7.40k | case OP_PLUSI: |
185 | 7.40k | case OP_NOTPLUS: |
186 | 7.40k | case OP_NOTPLUSI: |
187 | 7.40k | case OP_MINPLUS: |
188 | 7.40k | case OP_MINPLUSI: |
189 | 7.40k | case OP_NOTMINPLUS: |
190 | 7.40k | case OP_NOTMINPLUSI: |
191 | 7.42k | case OP_POSPLUS: |
192 | 7.42k | case OP_POSPLUSI: |
193 | 7.42k | case OP_NOTPOSPLUS: |
194 | 7.42k | case OP_NOTPOSPLUSI: |
195 | 7.43k | case OP_QUERY: |
196 | 7.43k | case OP_QUERYI: |
197 | 7.43k | case OP_NOTQUERY: |
198 | 7.43k | case OP_NOTQUERYI: |
199 | 7.43k | case OP_MINQUERY: |
200 | 7.43k | case OP_MINQUERYI: |
201 | 7.43k | case OP_NOTMINQUERY: |
202 | 7.43k | case OP_NOTMINQUERYI: |
203 | 7.43k | case OP_POSQUERY: |
204 | 7.43k | case OP_POSQUERYI: |
205 | 7.43k | case OP_NOTPOSQUERY: |
206 | 7.43k | case OP_NOTPOSQUERYI: |
207 | 7.43k | if (HAS_EXTRALEN(code[-1])) code += GET_EXTRALEN(code[-1]); |
208 | 7.43k | break; |
209 | 30.0k | } |
210 | | #else |
211 | | (void)(utf); /* Keep compiler happy by referencing function argument */ |
212 | | #endif /* MAYBE_UTF_MULTI */ |
213 | 1.43M | } |
214 | 1.74M | } |
215 | 17.2k | } |
216 | | |
217 | | /* End of pcre2_find_bracket.c */ |