1*22dc650dSSadaf Ebrahimi /*************************************************
2*22dc650dSSadaf Ebrahimi * Perl-Compatible Regular Expressions *
3*22dc650dSSadaf Ebrahimi *************************************************/
4*22dc650dSSadaf Ebrahimi
5*22dc650dSSadaf Ebrahimi /* PCRE is a library of functions to support regular expressions whose syntax
6*22dc650dSSadaf Ebrahimi and semantics are as close as possible to those of the Perl 5 language.
7*22dc650dSSadaf Ebrahimi
8*22dc650dSSadaf Ebrahimi Written by Philip Hazel
9*22dc650dSSadaf Ebrahimi Original API code Copyright (c) 1997-2012 University of Cambridge
10*22dc650dSSadaf Ebrahimi New API code Copyright (c) 2015-2024 University of Cambridge
11*22dc650dSSadaf Ebrahimi
12*22dc650dSSadaf Ebrahimi -----------------------------------------------------------------------------
13*22dc650dSSadaf Ebrahimi Redistribution and use in source and binary forms, with or without
14*22dc650dSSadaf Ebrahimi modification, are permitted provided that the following conditions are met:
15*22dc650dSSadaf Ebrahimi
16*22dc650dSSadaf Ebrahimi * Redistributions of source code must retain the above copyright notice,
17*22dc650dSSadaf Ebrahimi this list of conditions and the following disclaimer.
18*22dc650dSSadaf Ebrahimi
19*22dc650dSSadaf Ebrahimi * Redistributions in binary form must reproduce the above copyright
20*22dc650dSSadaf Ebrahimi notice, this list of conditions and the following disclaimer in the
21*22dc650dSSadaf Ebrahimi documentation and/or other materials provided with the distribution.
22*22dc650dSSadaf Ebrahimi
23*22dc650dSSadaf Ebrahimi * Neither the name of the University of Cambridge nor the names of its
24*22dc650dSSadaf Ebrahimi contributors may be used to endorse or promote products derived from
25*22dc650dSSadaf Ebrahimi this software without specific prior written permission.
26*22dc650dSSadaf Ebrahimi
27*22dc650dSSadaf Ebrahimi THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
28*22dc650dSSadaf Ebrahimi AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29*22dc650dSSadaf Ebrahimi IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30*22dc650dSSadaf Ebrahimi ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
31*22dc650dSSadaf Ebrahimi LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
32*22dc650dSSadaf Ebrahimi CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
33*22dc650dSSadaf Ebrahimi SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
34*22dc650dSSadaf Ebrahimi INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
35*22dc650dSSadaf Ebrahimi CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
36*22dc650dSSadaf Ebrahimi ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37*22dc650dSSadaf Ebrahimi POSSIBILITY OF SUCH DAMAGE.
38*22dc650dSSadaf Ebrahimi -----------------------------------------------------------------------------
39*22dc650dSSadaf Ebrahimi */
40*22dc650dSSadaf Ebrahimi
41*22dc650dSSadaf Ebrahimi
42*22dc650dSSadaf Ebrahimi #ifdef HAVE_CONFIG_H
43*22dc650dSSadaf Ebrahimi #include "config.h"
44*22dc650dSSadaf Ebrahimi #endif
45*22dc650dSSadaf Ebrahimi
46*22dc650dSSadaf Ebrahimi #include "pcre2_internal.h"
47*22dc650dSSadaf Ebrahimi
48*22dc650dSSadaf Ebrahimi /* These defines enable debugging code */
49*22dc650dSSadaf Ebrahimi
50*22dc650dSSadaf Ebrahimi /* #define DEBUG_FRAMES_DISPLAY */
51*22dc650dSSadaf Ebrahimi /* #define DEBUG_SHOW_OPS */
52*22dc650dSSadaf Ebrahimi /* #define DEBUG_SHOW_RMATCH */
53*22dc650dSSadaf Ebrahimi
54*22dc650dSSadaf Ebrahimi #ifdef DEBUG_FRAMES_DISPLAY
55*22dc650dSSadaf Ebrahimi #include <stdarg.h>
56*22dc650dSSadaf Ebrahimi #endif
57*22dc650dSSadaf Ebrahimi
58*22dc650dSSadaf Ebrahimi #ifdef DEBUG_SHOW_OPS
59*22dc650dSSadaf Ebrahimi static const char *OP_names[] = { OP_NAME_LIST };
60*22dc650dSSadaf Ebrahimi #endif
61*22dc650dSSadaf Ebrahimi
62*22dc650dSSadaf Ebrahimi /* These defines identify the name of the block containing "static"
63*22dc650dSSadaf Ebrahimi information, and fields within it. */
64*22dc650dSSadaf Ebrahimi
65*22dc650dSSadaf Ebrahimi #define NLBLOCK mb /* Block containing newline information */
66*22dc650dSSadaf Ebrahimi #define PSSTART start_subject /* Field containing processed string start */
67*22dc650dSSadaf Ebrahimi #define PSEND end_subject /* Field containing processed string end */
68*22dc650dSSadaf Ebrahimi
69*22dc650dSSadaf Ebrahimi #define RECURSE_UNSET 0xffffffffu /* Bigger than max group number */
70*22dc650dSSadaf Ebrahimi
71*22dc650dSSadaf Ebrahimi /* Masks for identifying the public options that are permitted at match time. */
72*22dc650dSSadaf Ebrahimi
73*22dc650dSSadaf Ebrahimi #define PUBLIC_MATCH_OPTIONS \
74*22dc650dSSadaf Ebrahimi (PCRE2_ANCHORED|PCRE2_ENDANCHORED|PCRE2_NOTBOL|PCRE2_NOTEOL|PCRE2_NOTEMPTY| \
75*22dc650dSSadaf Ebrahimi PCRE2_NOTEMPTY_ATSTART|PCRE2_NO_UTF_CHECK|PCRE2_PARTIAL_HARD| \
76*22dc650dSSadaf Ebrahimi PCRE2_PARTIAL_SOFT|PCRE2_NO_JIT|PCRE2_COPY_MATCHED_SUBJECT| \
77*22dc650dSSadaf Ebrahimi PCRE2_DISABLE_RECURSELOOP_CHECK)
78*22dc650dSSadaf Ebrahimi
79*22dc650dSSadaf Ebrahimi #define PUBLIC_JIT_MATCH_OPTIONS \
80*22dc650dSSadaf Ebrahimi (PCRE2_NO_UTF_CHECK|PCRE2_NOTBOL|PCRE2_NOTEOL|PCRE2_NOTEMPTY|\
81*22dc650dSSadaf Ebrahimi PCRE2_NOTEMPTY_ATSTART|PCRE2_PARTIAL_SOFT|PCRE2_PARTIAL_HARD|\
82*22dc650dSSadaf Ebrahimi PCRE2_COPY_MATCHED_SUBJECT)
83*22dc650dSSadaf Ebrahimi
84*22dc650dSSadaf Ebrahimi /* Non-error returns from and within the match() function. Error returns are
85*22dc650dSSadaf Ebrahimi externally defined PCRE2_ERROR_xxx codes, which are all negative. */
86*22dc650dSSadaf Ebrahimi
87*22dc650dSSadaf Ebrahimi #define MATCH_MATCH 1
88*22dc650dSSadaf Ebrahimi #define MATCH_NOMATCH 0
89*22dc650dSSadaf Ebrahimi
90*22dc650dSSadaf Ebrahimi /* Special internal returns used in the match() function. Make them
91*22dc650dSSadaf Ebrahimi sufficiently negative to avoid the external error codes. */
92*22dc650dSSadaf Ebrahimi
93*22dc650dSSadaf Ebrahimi #define MATCH_ACCEPT (-999)
94*22dc650dSSadaf Ebrahimi #define MATCH_KETRPOS (-998)
95*22dc650dSSadaf Ebrahimi /* The next 5 must be kept together and in sequence so that a test that checks
96*22dc650dSSadaf Ebrahimi for any one of them can use a range. */
97*22dc650dSSadaf Ebrahimi #define MATCH_COMMIT (-997)
98*22dc650dSSadaf Ebrahimi #define MATCH_PRUNE (-996)
99*22dc650dSSadaf Ebrahimi #define MATCH_SKIP (-995)
100*22dc650dSSadaf Ebrahimi #define MATCH_SKIP_ARG (-994)
101*22dc650dSSadaf Ebrahimi #define MATCH_THEN (-993)
102*22dc650dSSadaf Ebrahimi #define MATCH_BACKTRACK_MAX MATCH_THEN
103*22dc650dSSadaf Ebrahimi #define MATCH_BACKTRACK_MIN MATCH_COMMIT
104*22dc650dSSadaf Ebrahimi
105*22dc650dSSadaf Ebrahimi /* Group frame type values. Zero means the frame is not a group frame. The
106*22dc650dSSadaf Ebrahimi lower 16 bits are used for data (e.g. the capture number). Group frames are
107*22dc650dSSadaf Ebrahimi used for most groups so that information about the start is easily available at
108*22dc650dSSadaf Ebrahimi the end without having to scan back through intermediate frames (backtrack
109*22dc650dSSadaf Ebrahimi points). */
110*22dc650dSSadaf Ebrahimi
111*22dc650dSSadaf Ebrahimi #define GF_CAPTURE 0x00010000u
112*22dc650dSSadaf Ebrahimi #define GF_NOCAPTURE 0x00020000u
113*22dc650dSSadaf Ebrahimi #define GF_CONDASSERT 0x00030000u
114*22dc650dSSadaf Ebrahimi #define GF_RECURSE 0x00040000u
115*22dc650dSSadaf Ebrahimi
116*22dc650dSSadaf Ebrahimi /* Masks for the identity and data parts of the group frame type. */
117*22dc650dSSadaf Ebrahimi
118*22dc650dSSadaf Ebrahimi #define GF_IDMASK(a) ((a) & 0xffff0000u)
119*22dc650dSSadaf Ebrahimi #define GF_DATAMASK(a) ((a) & 0x0000ffffu)
120*22dc650dSSadaf Ebrahimi
121*22dc650dSSadaf Ebrahimi /* Repetition types */
122*22dc650dSSadaf Ebrahimi
123*22dc650dSSadaf Ebrahimi enum { REPTYPE_MIN, REPTYPE_MAX, REPTYPE_POS };
124*22dc650dSSadaf Ebrahimi
125*22dc650dSSadaf Ebrahimi /* Min and max values for the common repeats; a maximum of UINT32_MAX =>
126*22dc650dSSadaf Ebrahimi infinity. */
127*22dc650dSSadaf Ebrahimi
128*22dc650dSSadaf Ebrahimi static const uint32_t rep_min[] = {
129*22dc650dSSadaf Ebrahimi 0, 0, /* * and *? */
130*22dc650dSSadaf Ebrahimi 1, 1, /* + and +? */
131*22dc650dSSadaf Ebrahimi 0, 0, /* ? and ?? */
132*22dc650dSSadaf Ebrahimi 0, 0, /* dummy placefillers for OP_CR[MIN]RANGE */
133*22dc650dSSadaf Ebrahimi 0, 1, 0 }; /* OP_CRPOS{STAR, PLUS, QUERY} */
134*22dc650dSSadaf Ebrahimi
135*22dc650dSSadaf Ebrahimi static const uint32_t rep_max[] = {
136*22dc650dSSadaf Ebrahimi UINT32_MAX, UINT32_MAX, /* * and *? */
137*22dc650dSSadaf Ebrahimi UINT32_MAX, UINT32_MAX, /* + and +? */
138*22dc650dSSadaf Ebrahimi 1, 1, /* ? and ?? */
139*22dc650dSSadaf Ebrahimi 0, 0, /* dummy placefillers for OP_CR[MIN]RANGE */
140*22dc650dSSadaf Ebrahimi UINT32_MAX, UINT32_MAX, 1 }; /* OP_CRPOS{STAR, PLUS, QUERY} */
141*22dc650dSSadaf Ebrahimi
142*22dc650dSSadaf Ebrahimi /* Repetition types - must include OP_CRPOSRANGE (not needed above) */
143*22dc650dSSadaf Ebrahimi
144*22dc650dSSadaf Ebrahimi static const uint32_t rep_typ[] = {
145*22dc650dSSadaf Ebrahimi REPTYPE_MAX, REPTYPE_MIN, /* * and *? */
146*22dc650dSSadaf Ebrahimi REPTYPE_MAX, REPTYPE_MIN, /* + and +? */
147*22dc650dSSadaf Ebrahimi REPTYPE_MAX, REPTYPE_MIN, /* ? and ?? */
148*22dc650dSSadaf Ebrahimi REPTYPE_MAX, REPTYPE_MIN, /* OP_CRRANGE and OP_CRMINRANGE */
149*22dc650dSSadaf Ebrahimi REPTYPE_POS, REPTYPE_POS, /* OP_CRPOSSTAR, OP_CRPOSPLUS */
150*22dc650dSSadaf Ebrahimi REPTYPE_POS, REPTYPE_POS }; /* OP_CRPOSQUERY, OP_CRPOSRANGE */
151*22dc650dSSadaf Ebrahimi
152*22dc650dSSadaf Ebrahimi /* Numbers for RMATCH calls at backtracking points. When these lists are
153*22dc650dSSadaf Ebrahimi changed, the code at RETURN_SWITCH below must be updated in sync. */
154*22dc650dSSadaf Ebrahimi
155*22dc650dSSadaf Ebrahimi enum { RM1=1, RM2, RM3, RM4, RM5, RM6, RM7, RM8, RM9, RM10,
156*22dc650dSSadaf Ebrahimi RM11, RM12, RM13, RM14, RM15, RM16, RM17, RM18, RM19, RM20,
157*22dc650dSSadaf Ebrahimi RM21, RM22, RM23, RM24, RM25, RM26, RM27, RM28, RM29, RM30,
158*22dc650dSSadaf Ebrahimi RM31, RM32, RM33, RM34, RM35, RM36, RM37 };
159*22dc650dSSadaf Ebrahimi
160*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_WIDE_CHARS
161*22dc650dSSadaf Ebrahimi enum { RM100=100, RM101 };
162*22dc650dSSadaf Ebrahimi #endif
163*22dc650dSSadaf Ebrahimi
164*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_UNICODE
165*22dc650dSSadaf Ebrahimi enum { RM200=200, RM201, RM202, RM203, RM204, RM205, RM206, RM207,
166*22dc650dSSadaf Ebrahimi RM208, RM209, RM210, RM211, RM212, RM213, RM214, RM215,
167*22dc650dSSadaf Ebrahimi RM216, RM217, RM218, RM219, RM220, RM221, RM222, RM223,
168*22dc650dSSadaf Ebrahimi RM224, RM225 };
169*22dc650dSSadaf Ebrahimi #endif
170*22dc650dSSadaf Ebrahimi
171*22dc650dSSadaf Ebrahimi /* Define short names for general fields in the current backtrack frame, which
172*22dc650dSSadaf Ebrahimi is always pointed to by the F variable. Occasional references to fields in
173*22dc650dSSadaf Ebrahimi other frames are written out explicitly. There are also some fields in the
174*22dc650dSSadaf Ebrahimi current frame whose names start with "temp" that are used for short-term,
175*22dc650dSSadaf Ebrahimi localised backtracking memory. These are #defined with Lxxx names at the point
176*22dc650dSSadaf Ebrahimi of use and undefined afterwards. */
177*22dc650dSSadaf Ebrahimi
178*22dc650dSSadaf Ebrahimi #define Fback_frame F->back_frame
179*22dc650dSSadaf Ebrahimi #define Fcapture_last F->capture_last
180*22dc650dSSadaf Ebrahimi #define Fcurrent_recurse F->current_recurse
181*22dc650dSSadaf Ebrahimi #define Fecode F->ecode
182*22dc650dSSadaf Ebrahimi #define Feptr F->eptr
183*22dc650dSSadaf Ebrahimi #define Fgroup_frame_type F->group_frame_type
184*22dc650dSSadaf Ebrahimi #define Flast_group_offset F->last_group_offset
185*22dc650dSSadaf Ebrahimi #define Flength F->length
186*22dc650dSSadaf Ebrahimi #define Fmark F->mark
187*22dc650dSSadaf Ebrahimi #define Frdepth F->rdepth
188*22dc650dSSadaf Ebrahimi #define Fstart_match F->start_match
189*22dc650dSSadaf Ebrahimi #define Foffset_top F->offset_top
190*22dc650dSSadaf Ebrahimi #define Foccu F->occu
191*22dc650dSSadaf Ebrahimi #define Fop F->op
192*22dc650dSSadaf Ebrahimi #define Fovector F->ovector
193*22dc650dSSadaf Ebrahimi #define Freturn_id F->return_id
194*22dc650dSSadaf Ebrahimi
195*22dc650dSSadaf Ebrahimi
196*22dc650dSSadaf Ebrahimi #ifdef DEBUG_FRAMES_DISPLAY
197*22dc650dSSadaf Ebrahimi /*************************************************
198*22dc650dSSadaf Ebrahimi * Display current frames and contents *
199*22dc650dSSadaf Ebrahimi *************************************************/
200*22dc650dSSadaf Ebrahimi
201*22dc650dSSadaf Ebrahimi /* This debugging function displays the current set of frames and their
202*22dc650dSSadaf Ebrahimi contents. It is not called automatically from anywhere, the intention being
203*22dc650dSSadaf Ebrahimi that calls can be inserted where necessary when debugging frame-related
204*22dc650dSSadaf Ebrahimi problems.
205*22dc650dSSadaf Ebrahimi
206*22dc650dSSadaf Ebrahimi Arguments:
207*22dc650dSSadaf Ebrahimi f the file to write to
208*22dc650dSSadaf Ebrahimi F the current top frame
209*22dc650dSSadaf Ebrahimi P a previous frame of interest
210*22dc650dSSadaf Ebrahimi frame_size the frame size
211*22dc650dSSadaf Ebrahimi mb points to the match block
212*22dc650dSSadaf Ebrahimi match_data points to the match data block
213*22dc650dSSadaf Ebrahimi s identification text
214*22dc650dSSadaf Ebrahimi
215*22dc650dSSadaf Ebrahimi Returns: nothing
216*22dc650dSSadaf Ebrahimi */
217*22dc650dSSadaf Ebrahimi
218*22dc650dSSadaf Ebrahimi static void
display_frames(FILE * f,heapframe * F,heapframe * P,PCRE2_SIZE frame_size,match_block * mb,pcre2_match_data * match_data,const char * s,...)219*22dc650dSSadaf Ebrahimi display_frames(FILE *f, heapframe *F, heapframe *P, PCRE2_SIZE frame_size,
220*22dc650dSSadaf Ebrahimi match_block *mb, pcre2_match_data *match_data, const char *s, ...)
221*22dc650dSSadaf Ebrahimi {
222*22dc650dSSadaf Ebrahimi uint32_t i;
223*22dc650dSSadaf Ebrahimi heapframe *Q;
224*22dc650dSSadaf Ebrahimi va_list ap;
225*22dc650dSSadaf Ebrahimi va_start(ap, s);
226*22dc650dSSadaf Ebrahimi
227*22dc650dSSadaf Ebrahimi fprintf(f, "FRAMES ");
228*22dc650dSSadaf Ebrahimi vfprintf(f, s, ap);
229*22dc650dSSadaf Ebrahimi va_end(ap);
230*22dc650dSSadaf Ebrahimi
231*22dc650dSSadaf Ebrahimi if (P != NULL) fprintf(f, " P=%lu",
232*22dc650dSSadaf Ebrahimi ((char *)P - (char *)(match_data->heapframes))/frame_size);
233*22dc650dSSadaf Ebrahimi fprintf(f, "\n");
234*22dc650dSSadaf Ebrahimi
235*22dc650dSSadaf Ebrahimi for (i = 0, Q = match_data->heapframes;
236*22dc650dSSadaf Ebrahimi Q <= F;
237*22dc650dSSadaf Ebrahimi i++, Q = (heapframe *)((char *)Q + frame_size))
238*22dc650dSSadaf Ebrahimi {
239*22dc650dSSadaf Ebrahimi fprintf(f, "Frame %d type=%x subj=%lu code=%d back=%lu id=%d",
240*22dc650dSSadaf Ebrahimi i, Q->group_frame_type, Q->eptr - mb->start_subject, *(Q->ecode),
241*22dc650dSSadaf Ebrahimi Q->back_frame, Q->return_id);
242*22dc650dSSadaf Ebrahimi
243*22dc650dSSadaf Ebrahimi if (Q->last_group_offset == PCRE2_UNSET)
244*22dc650dSSadaf Ebrahimi fprintf(f, " lgoffset=unset\n");
245*22dc650dSSadaf Ebrahimi else
246*22dc650dSSadaf Ebrahimi fprintf(f, " lgoffset=%lu\n", Q->last_group_offset/frame_size);
247*22dc650dSSadaf Ebrahimi }
248*22dc650dSSadaf Ebrahimi }
249*22dc650dSSadaf Ebrahimi
250*22dc650dSSadaf Ebrahimi #endif
251*22dc650dSSadaf Ebrahimi
252*22dc650dSSadaf Ebrahimi
253*22dc650dSSadaf Ebrahimi
254*22dc650dSSadaf Ebrahimi /*************************************************
255*22dc650dSSadaf Ebrahimi * Process a callout *
256*22dc650dSSadaf Ebrahimi *************************************************/
257*22dc650dSSadaf Ebrahimi
258*22dc650dSSadaf Ebrahimi /* This function is called for all callouts, whether "standalone" or at the
259*22dc650dSSadaf Ebrahimi start of a conditional group. Feptr will be pointing to either OP_CALLOUT or
260*22dc650dSSadaf Ebrahimi OP_CALLOUT_STR. A callout block is allocated in pcre2_match() and initialized
261*22dc650dSSadaf Ebrahimi with fixed values.
262*22dc650dSSadaf Ebrahimi
263*22dc650dSSadaf Ebrahimi Arguments:
264*22dc650dSSadaf Ebrahimi F points to the current backtracking frame
265*22dc650dSSadaf Ebrahimi mb points to the match block
266*22dc650dSSadaf Ebrahimi lengthptr where to return the length of the callout item
267*22dc650dSSadaf Ebrahimi
268*22dc650dSSadaf Ebrahimi Returns: the return from the callout
269*22dc650dSSadaf Ebrahimi or 0 if no callout function exists
270*22dc650dSSadaf Ebrahimi */
271*22dc650dSSadaf Ebrahimi
272*22dc650dSSadaf Ebrahimi static int
do_callout(heapframe * F,match_block * mb,PCRE2_SIZE * lengthptr)273*22dc650dSSadaf Ebrahimi do_callout(heapframe *F, match_block *mb, PCRE2_SIZE *lengthptr)
274*22dc650dSSadaf Ebrahimi {
275*22dc650dSSadaf Ebrahimi int rc;
276*22dc650dSSadaf Ebrahimi PCRE2_SIZE save0, save1;
277*22dc650dSSadaf Ebrahimi PCRE2_SIZE *callout_ovector;
278*22dc650dSSadaf Ebrahimi pcre2_callout_block *cb;
279*22dc650dSSadaf Ebrahimi
280*22dc650dSSadaf Ebrahimi *lengthptr = (*Fecode == OP_CALLOUT)?
281*22dc650dSSadaf Ebrahimi PRIV(OP_lengths)[OP_CALLOUT] : GET(Fecode, 1 + 2*LINK_SIZE);
282*22dc650dSSadaf Ebrahimi
283*22dc650dSSadaf Ebrahimi if (mb->callout == NULL) return 0; /* No callout function provided */
284*22dc650dSSadaf Ebrahimi
285*22dc650dSSadaf Ebrahimi /* The original matching code (pre 10.30) worked directly with the ovector
286*22dc650dSSadaf Ebrahimi passed by the user, and this was passed to callouts. Now that the working
287*22dc650dSSadaf Ebrahimi ovector is in the backtracking frame, it no longer needs to reserve space for
288*22dc650dSSadaf Ebrahimi the overall match offsets (which would waste space in the frame). For backward
289*22dc650dSSadaf Ebrahimi compatibility, however, we pass capture_top and offset_vector to the callout as
290*22dc650dSSadaf Ebrahimi if for the extended ovector, and we ensure that the first two slots are unset
291*22dc650dSSadaf Ebrahimi by preserving and restoring their current contents. Picky compilers complain if
292*22dc650dSSadaf Ebrahimi references such as Fovector[-2] are use directly, so we set up a separate
293*22dc650dSSadaf Ebrahimi pointer. */
294*22dc650dSSadaf Ebrahimi
295*22dc650dSSadaf Ebrahimi callout_ovector = (PCRE2_SIZE *)(Fovector) - 2;
296*22dc650dSSadaf Ebrahimi
297*22dc650dSSadaf Ebrahimi /* The cb->version, cb->subject, cb->subject_length, and cb->start_match fields
298*22dc650dSSadaf Ebrahimi are set externally. The first 3 never change; the last is updated for each
299*22dc650dSSadaf Ebrahimi bumpalong. */
300*22dc650dSSadaf Ebrahimi
301*22dc650dSSadaf Ebrahimi cb = mb->cb;
302*22dc650dSSadaf Ebrahimi cb->capture_top = (uint32_t)Foffset_top/2 + 1;
303*22dc650dSSadaf Ebrahimi cb->capture_last = Fcapture_last;
304*22dc650dSSadaf Ebrahimi cb->offset_vector = callout_ovector;
305*22dc650dSSadaf Ebrahimi cb->mark = mb->nomatch_mark;
306*22dc650dSSadaf Ebrahimi cb->current_position = (PCRE2_SIZE)(Feptr - mb->start_subject);
307*22dc650dSSadaf Ebrahimi cb->pattern_position = GET(Fecode, 1);
308*22dc650dSSadaf Ebrahimi cb->next_item_length = GET(Fecode, 1 + LINK_SIZE);
309*22dc650dSSadaf Ebrahimi
310*22dc650dSSadaf Ebrahimi if (*Fecode == OP_CALLOUT) /* Numerical callout */
311*22dc650dSSadaf Ebrahimi {
312*22dc650dSSadaf Ebrahimi cb->callout_number = Fecode[1 + 2*LINK_SIZE];
313*22dc650dSSadaf Ebrahimi cb->callout_string_offset = 0;
314*22dc650dSSadaf Ebrahimi cb->callout_string = NULL;
315*22dc650dSSadaf Ebrahimi cb->callout_string_length = 0;
316*22dc650dSSadaf Ebrahimi }
317*22dc650dSSadaf Ebrahimi else /* String callout */
318*22dc650dSSadaf Ebrahimi {
319*22dc650dSSadaf Ebrahimi cb->callout_number = 0;
320*22dc650dSSadaf Ebrahimi cb->callout_string_offset = GET(Fecode, 1 + 3*LINK_SIZE);
321*22dc650dSSadaf Ebrahimi cb->callout_string = Fecode + (1 + 4*LINK_SIZE) + 1;
322*22dc650dSSadaf Ebrahimi cb->callout_string_length =
323*22dc650dSSadaf Ebrahimi *lengthptr - (1 + 4*LINK_SIZE) - 2;
324*22dc650dSSadaf Ebrahimi }
325*22dc650dSSadaf Ebrahimi
326*22dc650dSSadaf Ebrahimi save0 = callout_ovector[0];
327*22dc650dSSadaf Ebrahimi save1 = callout_ovector[1];
328*22dc650dSSadaf Ebrahimi callout_ovector[0] = callout_ovector[1] = PCRE2_UNSET;
329*22dc650dSSadaf Ebrahimi rc = mb->callout(cb, mb->callout_data);
330*22dc650dSSadaf Ebrahimi callout_ovector[0] = save0;
331*22dc650dSSadaf Ebrahimi callout_ovector[1] = save1;
332*22dc650dSSadaf Ebrahimi cb->callout_flags = 0;
333*22dc650dSSadaf Ebrahimi return rc;
334*22dc650dSSadaf Ebrahimi }
335*22dc650dSSadaf Ebrahimi
336*22dc650dSSadaf Ebrahimi
337*22dc650dSSadaf Ebrahimi
338*22dc650dSSadaf Ebrahimi /*************************************************
339*22dc650dSSadaf Ebrahimi * Match a back-reference *
340*22dc650dSSadaf Ebrahimi *************************************************/
341*22dc650dSSadaf Ebrahimi
342*22dc650dSSadaf Ebrahimi /* This function is called only when it is known that the offset lies within
343*22dc650dSSadaf Ebrahimi the offsets that have so far been used in the match. Note that in caseless
344*22dc650dSSadaf Ebrahimi UTF-8 mode, the number of subject bytes matched may be different to the number
345*22dc650dSSadaf Ebrahimi of reference bytes. (In theory this could also happen in UTF-16 mode, but it
346*22dc650dSSadaf Ebrahimi seems unlikely.)
347*22dc650dSSadaf Ebrahimi
348*22dc650dSSadaf Ebrahimi Arguments:
349*22dc650dSSadaf Ebrahimi offset index into the offset vector
350*22dc650dSSadaf Ebrahimi caseless TRUE if caseless
351*22dc650dSSadaf Ebrahimi F the current backtracking frame pointer
352*22dc650dSSadaf Ebrahimi mb points to match block
353*22dc650dSSadaf Ebrahimi lengthptr pointer for returning the length matched
354*22dc650dSSadaf Ebrahimi
355*22dc650dSSadaf Ebrahimi Returns: = 0 sucessful match; number of code units matched is set
356*22dc650dSSadaf Ebrahimi < 0 no match
357*22dc650dSSadaf Ebrahimi > 0 partial match
358*22dc650dSSadaf Ebrahimi */
359*22dc650dSSadaf Ebrahimi
360*22dc650dSSadaf Ebrahimi static int
match_ref(PCRE2_SIZE offset,BOOL caseless,heapframe * F,match_block * mb,PCRE2_SIZE * lengthptr)361*22dc650dSSadaf Ebrahimi match_ref(PCRE2_SIZE offset, BOOL caseless, heapframe *F, match_block *mb,
362*22dc650dSSadaf Ebrahimi PCRE2_SIZE *lengthptr)
363*22dc650dSSadaf Ebrahimi {
364*22dc650dSSadaf Ebrahimi PCRE2_SPTR p;
365*22dc650dSSadaf Ebrahimi PCRE2_SIZE length;
366*22dc650dSSadaf Ebrahimi PCRE2_SPTR eptr;
367*22dc650dSSadaf Ebrahimi PCRE2_SPTR eptr_start;
368*22dc650dSSadaf Ebrahimi
369*22dc650dSSadaf Ebrahimi /* Deal with an unset group. The default is no match, but there is an option to
370*22dc650dSSadaf Ebrahimi match an empty string. */
371*22dc650dSSadaf Ebrahimi
372*22dc650dSSadaf Ebrahimi if (offset >= Foffset_top || Fovector[offset] == PCRE2_UNSET)
373*22dc650dSSadaf Ebrahimi {
374*22dc650dSSadaf Ebrahimi if ((mb->poptions & PCRE2_MATCH_UNSET_BACKREF) != 0)
375*22dc650dSSadaf Ebrahimi {
376*22dc650dSSadaf Ebrahimi *lengthptr = 0;
377*22dc650dSSadaf Ebrahimi return 0; /* Match */
378*22dc650dSSadaf Ebrahimi }
379*22dc650dSSadaf Ebrahimi else return -1; /* No match */
380*22dc650dSSadaf Ebrahimi }
381*22dc650dSSadaf Ebrahimi
382*22dc650dSSadaf Ebrahimi /* Separate the caseless and UTF cases for speed. */
383*22dc650dSSadaf Ebrahimi
384*22dc650dSSadaf Ebrahimi eptr = eptr_start = Feptr;
385*22dc650dSSadaf Ebrahimi p = mb->start_subject + Fovector[offset];
386*22dc650dSSadaf Ebrahimi length = Fovector[offset+1] - Fovector[offset];
387*22dc650dSSadaf Ebrahimi
388*22dc650dSSadaf Ebrahimi if (caseless)
389*22dc650dSSadaf Ebrahimi {
390*22dc650dSSadaf Ebrahimi #if defined SUPPORT_UNICODE
391*22dc650dSSadaf Ebrahimi BOOL utf = (mb->poptions & PCRE2_UTF) != 0;
392*22dc650dSSadaf Ebrahimi
393*22dc650dSSadaf Ebrahimi if (utf || (mb->poptions & PCRE2_UCP) != 0)
394*22dc650dSSadaf Ebrahimi {
395*22dc650dSSadaf Ebrahimi PCRE2_SPTR endptr = p + length;
396*22dc650dSSadaf Ebrahimi
397*22dc650dSSadaf Ebrahimi /* Match characters up to the end of the reference. NOTE: the number of
398*22dc650dSSadaf Ebrahimi code units matched may differ, because in UTF-8 there are some characters
399*22dc650dSSadaf Ebrahimi whose upper and lower case codes have different numbers of bytes. For
400*22dc650dSSadaf Ebrahimi example, U+023A (2 bytes in UTF-8) is the upper case version of U+2C65 (3
401*22dc650dSSadaf Ebrahimi bytes in UTF-8); a sequence of 3 of the former uses 6 bytes, as does a
402*22dc650dSSadaf Ebrahimi sequence of two of the latter. It is important, therefore, to check the
403*22dc650dSSadaf Ebrahimi length along the reference, not along the subject (earlier code did this
404*22dc650dSSadaf Ebrahimi wrong). UCP without uses Unicode properties but without UTF encoding. */
405*22dc650dSSadaf Ebrahimi
406*22dc650dSSadaf Ebrahimi while (p < endptr)
407*22dc650dSSadaf Ebrahimi {
408*22dc650dSSadaf Ebrahimi uint32_t c, d;
409*22dc650dSSadaf Ebrahimi const ucd_record *ur;
410*22dc650dSSadaf Ebrahimi if (eptr >= mb->end_subject) return 1; /* Partial match */
411*22dc650dSSadaf Ebrahimi
412*22dc650dSSadaf Ebrahimi if (utf)
413*22dc650dSSadaf Ebrahimi {
414*22dc650dSSadaf Ebrahimi GETCHARINC(c, eptr);
415*22dc650dSSadaf Ebrahimi GETCHARINC(d, p);
416*22dc650dSSadaf Ebrahimi }
417*22dc650dSSadaf Ebrahimi else
418*22dc650dSSadaf Ebrahimi {
419*22dc650dSSadaf Ebrahimi c = *eptr++;
420*22dc650dSSadaf Ebrahimi d = *p++;
421*22dc650dSSadaf Ebrahimi }
422*22dc650dSSadaf Ebrahimi
423*22dc650dSSadaf Ebrahimi ur = GET_UCD(d);
424*22dc650dSSadaf Ebrahimi if (c != d && c != (uint32_t)((int)d + ur->other_case))
425*22dc650dSSadaf Ebrahimi {
426*22dc650dSSadaf Ebrahimi const uint32_t *pp = PRIV(ucd_caseless_sets) + ur->caseset;
427*22dc650dSSadaf Ebrahimi for (;;)
428*22dc650dSSadaf Ebrahimi {
429*22dc650dSSadaf Ebrahimi if (c < *pp) return -1; /* No match */
430*22dc650dSSadaf Ebrahimi if (c == *pp++) break;
431*22dc650dSSadaf Ebrahimi }
432*22dc650dSSadaf Ebrahimi }
433*22dc650dSSadaf Ebrahimi }
434*22dc650dSSadaf Ebrahimi }
435*22dc650dSSadaf Ebrahimi else
436*22dc650dSSadaf Ebrahimi #endif
437*22dc650dSSadaf Ebrahimi
438*22dc650dSSadaf Ebrahimi /* Not in UTF or UCP mode */
439*22dc650dSSadaf Ebrahimi {
440*22dc650dSSadaf Ebrahimi for (; length > 0; length--)
441*22dc650dSSadaf Ebrahimi {
442*22dc650dSSadaf Ebrahimi uint32_t cc, cp;
443*22dc650dSSadaf Ebrahimi if (eptr >= mb->end_subject) return 1; /* Partial match */
444*22dc650dSSadaf Ebrahimi cc = UCHAR21TEST(eptr);
445*22dc650dSSadaf Ebrahimi cp = UCHAR21TEST(p);
446*22dc650dSSadaf Ebrahimi if (TABLE_GET(cp, mb->lcc, cp) != TABLE_GET(cc, mb->lcc, cc))
447*22dc650dSSadaf Ebrahimi return -1; /* No match */
448*22dc650dSSadaf Ebrahimi p++;
449*22dc650dSSadaf Ebrahimi eptr++;
450*22dc650dSSadaf Ebrahimi }
451*22dc650dSSadaf Ebrahimi }
452*22dc650dSSadaf Ebrahimi }
453*22dc650dSSadaf Ebrahimi
454*22dc650dSSadaf Ebrahimi /* In the caseful case, we can just compare the code units, whether or not we
455*22dc650dSSadaf Ebrahimi are in UTF and/or UCP mode. When partial matching, we have to do this unit by
456*22dc650dSSadaf Ebrahimi unit. */
457*22dc650dSSadaf Ebrahimi
458*22dc650dSSadaf Ebrahimi else
459*22dc650dSSadaf Ebrahimi {
460*22dc650dSSadaf Ebrahimi if (mb->partial != 0)
461*22dc650dSSadaf Ebrahimi {
462*22dc650dSSadaf Ebrahimi for (; length > 0; length--)
463*22dc650dSSadaf Ebrahimi {
464*22dc650dSSadaf Ebrahimi if (eptr >= mb->end_subject) return 1; /* Partial match */
465*22dc650dSSadaf Ebrahimi if (UCHAR21INCTEST(p) != UCHAR21INCTEST(eptr)) return -1; /* No match */
466*22dc650dSSadaf Ebrahimi }
467*22dc650dSSadaf Ebrahimi }
468*22dc650dSSadaf Ebrahimi
469*22dc650dSSadaf Ebrahimi /* Not partial matching */
470*22dc650dSSadaf Ebrahimi
471*22dc650dSSadaf Ebrahimi else
472*22dc650dSSadaf Ebrahimi {
473*22dc650dSSadaf Ebrahimi if ((PCRE2_SIZE)(mb->end_subject - eptr) < length) return 1; /* Partial */
474*22dc650dSSadaf Ebrahimi if (memcmp(p, eptr, CU2BYTES(length)) != 0) return -1; /* No match */
475*22dc650dSSadaf Ebrahimi eptr += length;
476*22dc650dSSadaf Ebrahimi }
477*22dc650dSSadaf Ebrahimi }
478*22dc650dSSadaf Ebrahimi
479*22dc650dSSadaf Ebrahimi *lengthptr = eptr - eptr_start;
480*22dc650dSSadaf Ebrahimi return 0; /* Match */
481*22dc650dSSadaf Ebrahimi }
482*22dc650dSSadaf Ebrahimi
483*22dc650dSSadaf Ebrahimi
484*22dc650dSSadaf Ebrahimi
485*22dc650dSSadaf Ebrahimi /******************************************************************************
486*22dc650dSSadaf Ebrahimi *******************************************************************************
487*22dc650dSSadaf Ebrahimi "Recursion" in the match() function
488*22dc650dSSadaf Ebrahimi
489*22dc650dSSadaf Ebrahimi The original match() function was highly recursive, but this proved to be the
490*22dc650dSSadaf Ebrahimi source of a number of problems over the years, mostly because of the relatively
491*22dc650dSSadaf Ebrahimi small system stacks that are commonly found. As new features were added to
492*22dc650dSSadaf Ebrahimi patterns, various kludges were invented to reduce the amount of stack used,
493*22dc650dSSadaf Ebrahimi making the code hard to understand in places.
494*22dc650dSSadaf Ebrahimi
495*22dc650dSSadaf Ebrahimi A version did exist that used individual frames on the heap instead of calling
496*22dc650dSSadaf Ebrahimi match() recursively, but this ran substantially slower. The current version is
497*22dc650dSSadaf Ebrahimi a refactoring that uses a vector of frames to remember backtracking points.
498*22dc650dSSadaf Ebrahimi This runs no slower, and possibly even a bit faster than the original recursive
499*22dc650dSSadaf Ebrahimi implementation.
500*22dc650dSSadaf Ebrahimi
501*22dc650dSSadaf Ebrahimi At first, an initial vector of size START_FRAMES_SIZE (enough for maybe 50
502*22dc650dSSadaf Ebrahimi frames) was allocated on the system stack. If this was not big enough, the heap
503*22dc650dSSadaf Ebrahimi was used for a larger vector. However, it turns out that there are environments
504*22dc650dSSadaf Ebrahimi where taking as little as 20KiB from the system stack is an embarrassment.
505*22dc650dSSadaf Ebrahimi After another refactoring, the heap is used exclusively, but a pointer the
506*22dc650dSSadaf Ebrahimi frames vector and its size are cached in the match_data block, so that there is
507*22dc650dSSadaf Ebrahimi no new memory allocation if the same match_data block is used for multiple
508*22dc650dSSadaf Ebrahimi matches (unless the frames vector has to be extended).
509*22dc650dSSadaf Ebrahimi *******************************************************************************
510*22dc650dSSadaf Ebrahimi ******************************************************************************/
511*22dc650dSSadaf Ebrahimi
512*22dc650dSSadaf Ebrahimi
513*22dc650dSSadaf Ebrahimi
514*22dc650dSSadaf Ebrahimi
515*22dc650dSSadaf Ebrahimi /*************************************************
516*22dc650dSSadaf Ebrahimi * Macros for the match() function *
517*22dc650dSSadaf Ebrahimi *************************************************/
518*22dc650dSSadaf Ebrahimi
519*22dc650dSSadaf Ebrahimi /* These macros pack up tests that are used for partial matching several times
520*22dc650dSSadaf Ebrahimi in the code. The second one is used when we already know we are past the end of
521*22dc650dSSadaf Ebrahimi the subject. We set the "hit end" flag if the pointer is at the end of the
522*22dc650dSSadaf Ebrahimi subject and either (a) the pointer is past the earliest inspected character
523*22dc650dSSadaf Ebrahimi (i.e. something has been matched, even if not part of the actual matched
524*22dc650dSSadaf Ebrahimi string), or (b) the pattern contains a lookbehind. These are the conditions for
525*22dc650dSSadaf Ebrahimi which adding more characters may allow the current match to continue.
526*22dc650dSSadaf Ebrahimi
527*22dc650dSSadaf Ebrahimi For hard partial matching, we immediately return a partial match. Otherwise,
528*22dc650dSSadaf Ebrahimi carrying on means that a complete match on the current subject will be sought.
529*22dc650dSSadaf Ebrahimi A partial match is returned only if no complete match can be found. */
530*22dc650dSSadaf Ebrahimi
531*22dc650dSSadaf Ebrahimi #define CHECK_PARTIAL()\
532*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject) \
533*22dc650dSSadaf Ebrahimi { \
534*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL(); \
535*22dc650dSSadaf Ebrahimi }
536*22dc650dSSadaf Ebrahimi
537*22dc650dSSadaf Ebrahimi #define SCHECK_PARTIAL()\
538*22dc650dSSadaf Ebrahimi if (mb->partial != 0 && \
539*22dc650dSSadaf Ebrahimi (Feptr > mb->start_used_ptr || mb->allowemptypartial)) \
540*22dc650dSSadaf Ebrahimi { \
541*22dc650dSSadaf Ebrahimi mb->hitend = TRUE; \
542*22dc650dSSadaf Ebrahimi if (mb->partial > 1) return PCRE2_ERROR_PARTIAL; \
543*22dc650dSSadaf Ebrahimi }
544*22dc650dSSadaf Ebrahimi
545*22dc650dSSadaf Ebrahimi
546*22dc650dSSadaf Ebrahimi /* These macros are used to implement backtracking. They simulate a recursive
547*22dc650dSSadaf Ebrahimi call to the match() function by means of a local vector of frames which
548*22dc650dSSadaf Ebrahimi remember the backtracking points. */
549*22dc650dSSadaf Ebrahimi
550*22dc650dSSadaf Ebrahimi #define RMATCH(ra,rb)\
551*22dc650dSSadaf Ebrahimi {\
552*22dc650dSSadaf Ebrahimi start_ecode = ra;\
553*22dc650dSSadaf Ebrahimi Freturn_id = rb;\
554*22dc650dSSadaf Ebrahimi goto MATCH_RECURSE;\
555*22dc650dSSadaf Ebrahimi L_##rb:;\
556*22dc650dSSadaf Ebrahimi }
557*22dc650dSSadaf Ebrahimi
558*22dc650dSSadaf Ebrahimi #define RRETURN(ra)\
559*22dc650dSSadaf Ebrahimi {\
560*22dc650dSSadaf Ebrahimi rrc = ra;\
561*22dc650dSSadaf Ebrahimi goto RETURN_SWITCH;\
562*22dc650dSSadaf Ebrahimi }
563*22dc650dSSadaf Ebrahimi
564*22dc650dSSadaf Ebrahimi
565*22dc650dSSadaf Ebrahimi
566*22dc650dSSadaf Ebrahimi /*************************************************
567*22dc650dSSadaf Ebrahimi * Match from current position *
568*22dc650dSSadaf Ebrahimi *************************************************/
569*22dc650dSSadaf Ebrahimi
570*22dc650dSSadaf Ebrahimi /* This function is called to run one match attempt at a single starting point
571*22dc650dSSadaf Ebrahimi in the subject.
572*22dc650dSSadaf Ebrahimi
573*22dc650dSSadaf Ebrahimi Performance note: It might be tempting to extract commonly used fields from the
574*22dc650dSSadaf Ebrahimi mb structure (e.g. end_subject) into individual variables to improve
575*22dc650dSSadaf Ebrahimi performance. Tests using gcc on a SPARC disproved this; in the first case, it
576*22dc650dSSadaf Ebrahimi made performance worse.
577*22dc650dSSadaf Ebrahimi
578*22dc650dSSadaf Ebrahimi Arguments:
579*22dc650dSSadaf Ebrahimi start_eptr starting character in subject
580*22dc650dSSadaf Ebrahimi start_ecode starting position in compiled code
581*22dc650dSSadaf Ebrahimi top_bracket number of capturing parentheses in the pattern
582*22dc650dSSadaf Ebrahimi frame_size size of each backtracking frame
583*22dc650dSSadaf Ebrahimi match_data pointer to the match_data block
584*22dc650dSSadaf Ebrahimi mb pointer to "static" variables block
585*22dc650dSSadaf Ebrahimi
586*22dc650dSSadaf Ebrahimi Returns: MATCH_MATCH if matched ) these values are >= 0
587*22dc650dSSadaf Ebrahimi MATCH_NOMATCH if failed to match )
588*22dc650dSSadaf Ebrahimi negative MATCH_xxx value for PRUNE, SKIP, etc
589*22dc650dSSadaf Ebrahimi negative PCRE2_ERROR_xxx value if aborted by an error condition
590*22dc650dSSadaf Ebrahimi (e.g. stopped by repeated call or depth limit)
591*22dc650dSSadaf Ebrahimi */
592*22dc650dSSadaf Ebrahimi
593*22dc650dSSadaf Ebrahimi static int
match(PCRE2_SPTR start_eptr,PCRE2_SPTR start_ecode,uint16_t top_bracket,PCRE2_SIZE frame_size,pcre2_match_data * match_data,match_block * mb)594*22dc650dSSadaf Ebrahimi match(PCRE2_SPTR start_eptr, PCRE2_SPTR start_ecode, uint16_t top_bracket,
595*22dc650dSSadaf Ebrahimi PCRE2_SIZE frame_size, pcre2_match_data *match_data, match_block *mb)
596*22dc650dSSadaf Ebrahimi {
597*22dc650dSSadaf Ebrahimi /* Frame-handling variables */
598*22dc650dSSadaf Ebrahimi
599*22dc650dSSadaf Ebrahimi heapframe *F; /* Current frame pointer */
600*22dc650dSSadaf Ebrahimi heapframe *N = NULL; /* Temporary frame pointers */
601*22dc650dSSadaf Ebrahimi heapframe *P = NULL;
602*22dc650dSSadaf Ebrahimi
603*22dc650dSSadaf Ebrahimi heapframe *frames_top; /* End of frames vector */
604*22dc650dSSadaf Ebrahimi heapframe *assert_accept_frame = NULL; /* For passing back a frame with captures */
605*22dc650dSSadaf Ebrahimi PCRE2_SIZE frame_copy_size; /* Amount to copy when creating a new frame */
606*22dc650dSSadaf Ebrahimi
607*22dc650dSSadaf Ebrahimi /* Local variables that do not need to be preserved over calls to RRMATCH(). */
608*22dc650dSSadaf Ebrahimi
609*22dc650dSSadaf Ebrahimi PCRE2_SPTR branch_end = NULL;
610*22dc650dSSadaf Ebrahimi PCRE2_SPTR branch_start;
611*22dc650dSSadaf Ebrahimi PCRE2_SPTR bracode; /* Temp pointer to start of group */
612*22dc650dSSadaf Ebrahimi PCRE2_SIZE offset; /* Used for group offsets */
613*22dc650dSSadaf Ebrahimi PCRE2_SIZE length; /* Used for various length calculations */
614*22dc650dSSadaf Ebrahimi
615*22dc650dSSadaf Ebrahimi int rrc; /* Return from functions & backtracking "recursions" */
616*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_UNICODE
617*22dc650dSSadaf Ebrahimi int proptype; /* Type of character property */
618*22dc650dSSadaf Ebrahimi #endif
619*22dc650dSSadaf Ebrahimi
620*22dc650dSSadaf Ebrahimi uint32_t i; /* Used for local loops */
621*22dc650dSSadaf Ebrahimi uint32_t fc; /* Character values */
622*22dc650dSSadaf Ebrahimi uint32_t number; /* Used for group and other numbers */
623*22dc650dSSadaf Ebrahimi uint32_t reptype = 0; /* Type of repetition (0 to avoid compiler warning) */
624*22dc650dSSadaf Ebrahimi uint32_t group_frame_type; /* Specifies type for new group frames */
625*22dc650dSSadaf Ebrahimi
626*22dc650dSSadaf Ebrahimi BOOL condition; /* Used in conditional groups */
627*22dc650dSSadaf Ebrahimi BOOL cur_is_word; /* Used in "word" tests */
628*22dc650dSSadaf Ebrahimi BOOL prev_is_word; /* Used in "word" tests */
629*22dc650dSSadaf Ebrahimi
630*22dc650dSSadaf Ebrahimi /* UTF and UCP flags */
631*22dc650dSSadaf Ebrahimi
632*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_UNICODE
633*22dc650dSSadaf Ebrahimi BOOL utf = (mb->poptions & PCRE2_UTF) != 0;
634*22dc650dSSadaf Ebrahimi BOOL ucp = (mb->poptions & PCRE2_UCP) != 0;
635*22dc650dSSadaf Ebrahimi #else
636*22dc650dSSadaf Ebrahimi BOOL utf = FALSE; /* Required for convenience even when no Unicode support */
637*22dc650dSSadaf Ebrahimi #endif
638*22dc650dSSadaf Ebrahimi
639*22dc650dSSadaf Ebrahimi /* This is the length of the last part of a backtracking frame that must be
640*22dc650dSSadaf Ebrahimi copied when a new frame is created. */
641*22dc650dSSadaf Ebrahimi
642*22dc650dSSadaf Ebrahimi frame_copy_size = frame_size - offsetof(heapframe, eptr);
643*22dc650dSSadaf Ebrahimi
644*22dc650dSSadaf Ebrahimi /* Set up the first frame and the end of the frames vector. */
645*22dc650dSSadaf Ebrahimi
646*22dc650dSSadaf Ebrahimi F = match_data->heapframes;
647*22dc650dSSadaf Ebrahimi frames_top = (heapframe *)((char *)F + match_data->heapframes_size);
648*22dc650dSSadaf Ebrahimi
649*22dc650dSSadaf Ebrahimi Frdepth = 0; /* "Recursion" depth */
650*22dc650dSSadaf Ebrahimi Fcapture_last = 0; /* Number of most recent capture */
651*22dc650dSSadaf Ebrahimi Fcurrent_recurse = RECURSE_UNSET; /* Not pattern recursing. */
652*22dc650dSSadaf Ebrahimi Fstart_match = Feptr = start_eptr; /* Current data pointer and start match */
653*22dc650dSSadaf Ebrahimi Fmark = NULL; /* Most recent mark */
654*22dc650dSSadaf Ebrahimi Foffset_top = 0; /* End of captures within the frame */
655*22dc650dSSadaf Ebrahimi Flast_group_offset = PCRE2_UNSET; /* Saved frame of most recent group */
656*22dc650dSSadaf Ebrahimi group_frame_type = 0; /* Not a start of group frame */
657*22dc650dSSadaf Ebrahimi goto NEW_FRAME; /* Start processing with this frame */
658*22dc650dSSadaf Ebrahimi
659*22dc650dSSadaf Ebrahimi /* Come back here when we want to create a new frame for remembering a
660*22dc650dSSadaf Ebrahimi backtracking point. */
661*22dc650dSSadaf Ebrahimi
662*22dc650dSSadaf Ebrahimi MATCH_RECURSE:
663*22dc650dSSadaf Ebrahimi
664*22dc650dSSadaf Ebrahimi /* Set up a new backtracking frame. If the vector is full, get a new one,
665*22dc650dSSadaf Ebrahimi doubling the size, but constrained by the heap limit (which is in KiB). */
666*22dc650dSSadaf Ebrahimi
667*22dc650dSSadaf Ebrahimi N = (heapframe *)((char *)F + frame_size);
668*22dc650dSSadaf Ebrahimi if ((heapframe *)((char *)N + frame_size) >= frames_top)
669*22dc650dSSadaf Ebrahimi {
670*22dc650dSSadaf Ebrahimi heapframe *new;
671*22dc650dSSadaf Ebrahimi PCRE2_SIZE newsize;
672*22dc650dSSadaf Ebrahimi PCRE2_SIZE usedsize = (char *)N - (char *)(match_data->heapframes);
673*22dc650dSSadaf Ebrahimi
674*22dc650dSSadaf Ebrahimi if (match_data->heapframes_size >= PCRE2_SIZE_MAX / 2)
675*22dc650dSSadaf Ebrahimi {
676*22dc650dSSadaf Ebrahimi if (match_data->heapframes_size == PCRE2_SIZE_MAX - 1)
677*22dc650dSSadaf Ebrahimi return PCRE2_ERROR_NOMEMORY;
678*22dc650dSSadaf Ebrahimi newsize = PCRE2_SIZE_MAX - 1;
679*22dc650dSSadaf Ebrahimi }
680*22dc650dSSadaf Ebrahimi else
681*22dc650dSSadaf Ebrahimi newsize = match_data->heapframes_size * 2;
682*22dc650dSSadaf Ebrahimi
683*22dc650dSSadaf Ebrahimi if (newsize / 1024 >= mb->heap_limit)
684*22dc650dSSadaf Ebrahimi {
685*22dc650dSSadaf Ebrahimi PCRE2_SIZE old_size = match_data->heapframes_size / 1024;
686*22dc650dSSadaf Ebrahimi if (mb->heap_limit <= old_size)
687*22dc650dSSadaf Ebrahimi return PCRE2_ERROR_HEAPLIMIT;
688*22dc650dSSadaf Ebrahimi else
689*22dc650dSSadaf Ebrahimi {
690*22dc650dSSadaf Ebrahimi PCRE2_SIZE max_delta = 1024 * (mb->heap_limit - old_size);
691*22dc650dSSadaf Ebrahimi int over_bytes = match_data->heapframes_size % 1024;
692*22dc650dSSadaf Ebrahimi if (over_bytes) max_delta -= (1024 - over_bytes);
693*22dc650dSSadaf Ebrahimi newsize = match_data->heapframes_size + max_delta;
694*22dc650dSSadaf Ebrahimi }
695*22dc650dSSadaf Ebrahimi }
696*22dc650dSSadaf Ebrahimi
697*22dc650dSSadaf Ebrahimi /* With a heap limit set, the permitted additional size may not be enough for
698*22dc650dSSadaf Ebrahimi another frame, so do a final check. */
699*22dc650dSSadaf Ebrahimi
700*22dc650dSSadaf Ebrahimi if (newsize - usedsize < frame_size) return PCRE2_ERROR_HEAPLIMIT;
701*22dc650dSSadaf Ebrahimi new = match_data->memctl.malloc(newsize, match_data->memctl.memory_data);
702*22dc650dSSadaf Ebrahimi if (new == NULL) return PCRE2_ERROR_NOMEMORY;
703*22dc650dSSadaf Ebrahimi memcpy(new, match_data->heapframes, usedsize);
704*22dc650dSSadaf Ebrahimi
705*22dc650dSSadaf Ebrahimi N = (heapframe *)((char *)new + usedsize);
706*22dc650dSSadaf Ebrahimi F = (heapframe *)((char *)N - frame_size);
707*22dc650dSSadaf Ebrahimi
708*22dc650dSSadaf Ebrahimi match_data->memctl.free(match_data->heapframes, match_data->memctl.memory_data);
709*22dc650dSSadaf Ebrahimi match_data->heapframes = new;
710*22dc650dSSadaf Ebrahimi match_data->heapframes_size = newsize;
711*22dc650dSSadaf Ebrahimi frames_top = (heapframe *)((char *)new + newsize);
712*22dc650dSSadaf Ebrahimi }
713*22dc650dSSadaf Ebrahimi
714*22dc650dSSadaf Ebrahimi #ifdef DEBUG_SHOW_RMATCH
715*22dc650dSSadaf Ebrahimi fprintf(stderr, "++ RMATCH %d frame=%d", Freturn_id, Frdepth + 1);
716*22dc650dSSadaf Ebrahimi if (group_frame_type != 0)
717*22dc650dSSadaf Ebrahimi {
718*22dc650dSSadaf Ebrahimi fprintf(stderr, " type=%x ", group_frame_type);
719*22dc650dSSadaf Ebrahimi switch (GF_IDMASK(group_frame_type))
720*22dc650dSSadaf Ebrahimi {
721*22dc650dSSadaf Ebrahimi case GF_CAPTURE:
722*22dc650dSSadaf Ebrahimi fprintf(stderr, "capture=%d", GF_DATAMASK(group_frame_type));
723*22dc650dSSadaf Ebrahimi break;
724*22dc650dSSadaf Ebrahimi
725*22dc650dSSadaf Ebrahimi case GF_NOCAPTURE:
726*22dc650dSSadaf Ebrahimi fprintf(stderr, "nocapture op=%d", GF_DATAMASK(group_frame_type));
727*22dc650dSSadaf Ebrahimi break;
728*22dc650dSSadaf Ebrahimi
729*22dc650dSSadaf Ebrahimi case GF_CONDASSERT:
730*22dc650dSSadaf Ebrahimi fprintf(stderr, "condassert op=%d", GF_DATAMASK(group_frame_type));
731*22dc650dSSadaf Ebrahimi break;
732*22dc650dSSadaf Ebrahimi
733*22dc650dSSadaf Ebrahimi case GF_RECURSE:
734*22dc650dSSadaf Ebrahimi fprintf(stderr, "recurse=%d", GF_DATAMASK(group_frame_type));
735*22dc650dSSadaf Ebrahimi break;
736*22dc650dSSadaf Ebrahimi
737*22dc650dSSadaf Ebrahimi default:
738*22dc650dSSadaf Ebrahimi fprintf(stderr, "*** unknown ***");
739*22dc650dSSadaf Ebrahimi break;
740*22dc650dSSadaf Ebrahimi }
741*22dc650dSSadaf Ebrahimi }
742*22dc650dSSadaf Ebrahimi fprintf(stderr, "\n");
743*22dc650dSSadaf Ebrahimi #endif
744*22dc650dSSadaf Ebrahimi
745*22dc650dSSadaf Ebrahimi /* Copy those fields that must be copied into the new frame, increase the
746*22dc650dSSadaf Ebrahimi "recursion" depth (i.e. the new frame's index) and then make the new frame
747*22dc650dSSadaf Ebrahimi current. */
748*22dc650dSSadaf Ebrahimi
749*22dc650dSSadaf Ebrahimi memcpy((char *)N + offsetof(heapframe, eptr),
750*22dc650dSSadaf Ebrahimi (char *)F + offsetof(heapframe, eptr),
751*22dc650dSSadaf Ebrahimi frame_copy_size);
752*22dc650dSSadaf Ebrahimi
753*22dc650dSSadaf Ebrahimi N->rdepth = Frdepth + 1;
754*22dc650dSSadaf Ebrahimi F = N;
755*22dc650dSSadaf Ebrahimi
756*22dc650dSSadaf Ebrahimi /* Carry on processing with a new frame. */
757*22dc650dSSadaf Ebrahimi
758*22dc650dSSadaf Ebrahimi NEW_FRAME:
759*22dc650dSSadaf Ebrahimi Fgroup_frame_type = group_frame_type;
760*22dc650dSSadaf Ebrahimi Fecode = start_ecode; /* Starting code pointer */
761*22dc650dSSadaf Ebrahimi Fback_frame = frame_size; /* Default is go back one frame */
762*22dc650dSSadaf Ebrahimi
763*22dc650dSSadaf Ebrahimi /* If this is a special type of group frame, remember its offset for quick
764*22dc650dSSadaf Ebrahimi access at the end of the group. If this is a recursion, set a new current
765*22dc650dSSadaf Ebrahimi recursion value. */
766*22dc650dSSadaf Ebrahimi
767*22dc650dSSadaf Ebrahimi if (group_frame_type != 0)
768*22dc650dSSadaf Ebrahimi {
769*22dc650dSSadaf Ebrahimi Flast_group_offset = (char *)F - (char *)match_data->heapframes;
770*22dc650dSSadaf Ebrahimi if (GF_IDMASK(group_frame_type) == GF_RECURSE)
771*22dc650dSSadaf Ebrahimi Fcurrent_recurse = GF_DATAMASK(group_frame_type);
772*22dc650dSSadaf Ebrahimi group_frame_type = 0;
773*22dc650dSSadaf Ebrahimi }
774*22dc650dSSadaf Ebrahimi
775*22dc650dSSadaf Ebrahimi
776*22dc650dSSadaf Ebrahimi /* ========================================================================= */
777*22dc650dSSadaf Ebrahimi /* This is the main processing loop. First check that we haven't recorded too
778*22dc650dSSadaf Ebrahimi many backtracks (search tree is too large), or that we haven't exceeded the
779*22dc650dSSadaf Ebrahimi recursive depth limit (used too many backtracking frames). If not, process the
780*22dc650dSSadaf Ebrahimi opcodes. */
781*22dc650dSSadaf Ebrahimi
782*22dc650dSSadaf Ebrahimi if (mb->match_call_count++ >= mb->match_limit) return PCRE2_ERROR_MATCHLIMIT;
783*22dc650dSSadaf Ebrahimi if (Frdepth >= mb->match_limit_depth) return PCRE2_ERROR_DEPTHLIMIT;
784*22dc650dSSadaf Ebrahimi
785*22dc650dSSadaf Ebrahimi #ifdef DEBUG_SHOW_OPS
786*22dc650dSSadaf Ebrahimi fprintf(stderr, "\n++ New frame: type=0x%x subject offset %ld\n",
787*22dc650dSSadaf Ebrahimi GF_IDMASK(Fgroup_frame_type), Feptr - mb->start_subject);
788*22dc650dSSadaf Ebrahimi #endif
789*22dc650dSSadaf Ebrahimi
790*22dc650dSSadaf Ebrahimi for (;;)
791*22dc650dSSadaf Ebrahimi {
792*22dc650dSSadaf Ebrahimi #ifdef DEBUG_SHOW_OPS
793*22dc650dSSadaf Ebrahimi fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode,
794*22dc650dSSadaf Ebrahimi OP_names[*Fecode]);
795*22dc650dSSadaf Ebrahimi #endif
796*22dc650dSSadaf Ebrahimi
797*22dc650dSSadaf Ebrahimi Fop = (uint8_t)(*Fecode); /* Cast needed for 16-bit and 32-bit modes */
798*22dc650dSSadaf Ebrahimi switch(Fop)
799*22dc650dSSadaf Ebrahimi {
800*22dc650dSSadaf Ebrahimi /* ===================================================================== */
801*22dc650dSSadaf Ebrahimi /* Before OP_ACCEPT there may be any number of OP_CLOSE opcodes, to close
802*22dc650dSSadaf Ebrahimi any currently open capturing brackets. Unlike reaching the end of a group,
803*22dc650dSSadaf Ebrahimi where we know the starting frame is at the top of the chained frames, in
804*22dc650dSSadaf Ebrahimi this case we have to search back for the relevant frame in case other types
805*22dc650dSSadaf Ebrahimi of group that use chained frames have intervened. Multiple OP_CLOSEs always
806*22dc650dSSadaf Ebrahimi come innermost first, which matches the chain order. We can ignore this in
807*22dc650dSSadaf Ebrahimi a recursion, because captures are not passed out of recursions. */
808*22dc650dSSadaf Ebrahimi
809*22dc650dSSadaf Ebrahimi case OP_CLOSE:
810*22dc650dSSadaf Ebrahimi if (Fcurrent_recurse == RECURSE_UNSET)
811*22dc650dSSadaf Ebrahimi {
812*22dc650dSSadaf Ebrahimi number = GET2(Fecode, 1);
813*22dc650dSSadaf Ebrahimi offset = Flast_group_offset;
814*22dc650dSSadaf Ebrahimi for(;;)
815*22dc650dSSadaf Ebrahimi {
816*22dc650dSSadaf Ebrahimi if (offset == PCRE2_UNSET) return PCRE2_ERROR_INTERNAL;
817*22dc650dSSadaf Ebrahimi N = (heapframe *)((char *)match_data->heapframes + offset);
818*22dc650dSSadaf Ebrahimi P = (heapframe *)((char *)N - frame_size);
819*22dc650dSSadaf Ebrahimi if (N->group_frame_type == (GF_CAPTURE | number)) break;
820*22dc650dSSadaf Ebrahimi offset = P->last_group_offset;
821*22dc650dSSadaf Ebrahimi }
822*22dc650dSSadaf Ebrahimi offset = (number << 1) - 2;
823*22dc650dSSadaf Ebrahimi Fcapture_last = number;
824*22dc650dSSadaf Ebrahimi Fovector[offset] = P->eptr - mb->start_subject;
825*22dc650dSSadaf Ebrahimi Fovector[offset+1] = Feptr - mb->start_subject;
826*22dc650dSSadaf Ebrahimi if (offset >= Foffset_top) Foffset_top = offset + 2;
827*22dc650dSSadaf Ebrahimi }
828*22dc650dSSadaf Ebrahimi Fecode += PRIV(OP_lengths)[*Fecode];
829*22dc650dSSadaf Ebrahimi break;
830*22dc650dSSadaf Ebrahimi
831*22dc650dSSadaf Ebrahimi
832*22dc650dSSadaf Ebrahimi /* ===================================================================== */
833*22dc650dSSadaf Ebrahimi /* Real or forced end of the pattern, assertion, or recursion. In an
834*22dc650dSSadaf Ebrahimi assertion ACCEPT, update the last used pointer and remember the current
835*22dc650dSSadaf Ebrahimi frame so that the captures and mark can be fished out of it. */
836*22dc650dSSadaf Ebrahimi
837*22dc650dSSadaf Ebrahimi case OP_ASSERT_ACCEPT:
838*22dc650dSSadaf Ebrahimi if (Feptr > mb->last_used_ptr) mb->last_used_ptr = Feptr;
839*22dc650dSSadaf Ebrahimi assert_accept_frame = F;
840*22dc650dSSadaf Ebrahimi RRETURN(MATCH_ACCEPT);
841*22dc650dSSadaf Ebrahimi
842*22dc650dSSadaf Ebrahimi /* For ACCEPT within a recursion, we have to find the most recent
843*22dc650dSSadaf Ebrahimi recursion. If not in a recursion, fall through to code that is common with
844*22dc650dSSadaf Ebrahimi OP_END. */
845*22dc650dSSadaf Ebrahimi
846*22dc650dSSadaf Ebrahimi case OP_ACCEPT:
847*22dc650dSSadaf Ebrahimi if (Fcurrent_recurse != RECURSE_UNSET)
848*22dc650dSSadaf Ebrahimi {
849*22dc650dSSadaf Ebrahimi #ifdef DEBUG_SHOW_OPS
850*22dc650dSSadaf Ebrahimi fprintf(stderr, "++ Accept within recursion\n");
851*22dc650dSSadaf Ebrahimi #endif
852*22dc650dSSadaf Ebrahimi offset = Flast_group_offset;
853*22dc650dSSadaf Ebrahimi for(;;)
854*22dc650dSSadaf Ebrahimi {
855*22dc650dSSadaf Ebrahimi if (offset == PCRE2_UNSET) return PCRE2_ERROR_INTERNAL;
856*22dc650dSSadaf Ebrahimi N = (heapframe *)((char *)match_data->heapframes + offset);
857*22dc650dSSadaf Ebrahimi P = (heapframe *)((char *)N - frame_size);
858*22dc650dSSadaf Ebrahimi if (GF_IDMASK(N->group_frame_type) == GF_RECURSE) break;
859*22dc650dSSadaf Ebrahimi offset = P->last_group_offset;
860*22dc650dSSadaf Ebrahimi }
861*22dc650dSSadaf Ebrahimi
862*22dc650dSSadaf Ebrahimi /* N is now the frame of the recursion; the previous frame is at the
863*22dc650dSSadaf Ebrahimi OP_RECURSE position. Go back there, copying the current subject position
864*22dc650dSSadaf Ebrahimi and mark, and the start_match position (\K might have changed it), and
865*22dc650dSSadaf Ebrahimi then move on past the OP_RECURSE. */
866*22dc650dSSadaf Ebrahimi
867*22dc650dSSadaf Ebrahimi P->eptr = Feptr;
868*22dc650dSSadaf Ebrahimi P->mark = Fmark;
869*22dc650dSSadaf Ebrahimi P->start_match = Fstart_match;
870*22dc650dSSadaf Ebrahimi F = P;
871*22dc650dSSadaf Ebrahimi Fecode += 1 + LINK_SIZE;
872*22dc650dSSadaf Ebrahimi continue;
873*22dc650dSSadaf Ebrahimi }
874*22dc650dSSadaf Ebrahimi /* Fall through */
875*22dc650dSSadaf Ebrahimi
876*22dc650dSSadaf Ebrahimi /* OP_END itself can never be reached within a recursion because that is
877*22dc650dSSadaf Ebrahimi picked up when the OP_KET that always precedes OP_END is reached. */
878*22dc650dSSadaf Ebrahimi
879*22dc650dSSadaf Ebrahimi case OP_END:
880*22dc650dSSadaf Ebrahimi
881*22dc650dSSadaf Ebrahimi /* Fail for an empty string match if either PCRE2_NOTEMPTY is set, or if
882*22dc650dSSadaf Ebrahimi PCRE2_NOTEMPTY_ATSTART is set and we have matched at the start of the
883*22dc650dSSadaf Ebrahimi subject. In both cases, backtracking will then try other alternatives, if
884*22dc650dSSadaf Ebrahimi any. */
885*22dc650dSSadaf Ebrahimi
886*22dc650dSSadaf Ebrahimi if (Feptr == Fstart_match &&
887*22dc650dSSadaf Ebrahimi ((mb->moptions & PCRE2_NOTEMPTY) != 0 ||
888*22dc650dSSadaf Ebrahimi ((mb->moptions & PCRE2_NOTEMPTY_ATSTART) != 0 &&
889*22dc650dSSadaf Ebrahimi Fstart_match == mb->start_subject + mb->start_offset)))
890*22dc650dSSadaf Ebrahimi {
891*22dc650dSSadaf Ebrahimi #ifdef DEBUG_SHOW_OPS
892*22dc650dSSadaf Ebrahimi fprintf(stderr, "++ Backtrack because empty string\n");
893*22dc650dSSadaf Ebrahimi #endif
894*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
895*22dc650dSSadaf Ebrahimi }
896*22dc650dSSadaf Ebrahimi
897*22dc650dSSadaf Ebrahimi /* Fail if PCRE2_ENDANCHORED is set and the end of the match is not
898*22dc650dSSadaf Ebrahimi the end of the subject. After (*ACCEPT) we fail the entire match (at this
899*22dc650dSSadaf Ebrahimi position) but backtrack if we've reached the end of the pattern. This
900*22dc650dSSadaf Ebrahimi applies whether or not we are in a recursion. */
901*22dc650dSSadaf Ebrahimi
902*22dc650dSSadaf Ebrahimi if (Feptr < mb->end_subject &&
903*22dc650dSSadaf Ebrahimi ((mb->moptions | mb->poptions) & PCRE2_ENDANCHORED) != 0)
904*22dc650dSSadaf Ebrahimi {
905*22dc650dSSadaf Ebrahimi if (Fop == OP_END)
906*22dc650dSSadaf Ebrahimi {
907*22dc650dSSadaf Ebrahimi #ifdef DEBUG_SHOW_OPS
908*22dc650dSSadaf Ebrahimi fprintf(stderr, "++ Backtrack because not at end (endanchored set)\n");
909*22dc650dSSadaf Ebrahimi #endif
910*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
911*22dc650dSSadaf Ebrahimi }
912*22dc650dSSadaf Ebrahimi
913*22dc650dSSadaf Ebrahimi #ifdef DEBUG_SHOW_OPS
914*22dc650dSSadaf Ebrahimi fprintf(stderr, "++ Failed ACCEPT not at end (endanchnored set)\n");
915*22dc650dSSadaf Ebrahimi #endif
916*22dc650dSSadaf Ebrahimi return MATCH_NOMATCH; /* (*ACCEPT) */
917*22dc650dSSadaf Ebrahimi }
918*22dc650dSSadaf Ebrahimi
919*22dc650dSSadaf Ebrahimi /* We have a successful match of the whole pattern. Record the result and
920*22dc650dSSadaf Ebrahimi then do a direct return from the function. If there is space in the offset
921*22dc650dSSadaf Ebrahimi vector, set any pairs that follow the highest-numbered captured string but
922*22dc650dSSadaf Ebrahimi are less than the number of capturing groups in the pattern to PCRE2_UNSET.
923*22dc650dSSadaf Ebrahimi It is documented that this happens. "Gaps" are set to PCRE2_UNSET
924*22dc650dSSadaf Ebrahimi dynamically. It is only those at the end that need setting here. */
925*22dc650dSSadaf Ebrahimi
926*22dc650dSSadaf Ebrahimi mb->end_match_ptr = Feptr; /* Record where we ended */
927*22dc650dSSadaf Ebrahimi mb->end_offset_top = Foffset_top; /* and how many extracts were taken */
928*22dc650dSSadaf Ebrahimi mb->mark = Fmark; /* and the last success mark */
929*22dc650dSSadaf Ebrahimi if (Feptr > mb->last_used_ptr) mb->last_used_ptr = Feptr;
930*22dc650dSSadaf Ebrahimi
931*22dc650dSSadaf Ebrahimi match_data->ovector[0] = Fstart_match - mb->start_subject;
932*22dc650dSSadaf Ebrahimi match_data->ovector[1] = Feptr - mb->start_subject;
933*22dc650dSSadaf Ebrahimi
934*22dc650dSSadaf Ebrahimi /* Set i to the smaller of the sizes of the external and frame ovectors. */
935*22dc650dSSadaf Ebrahimi
936*22dc650dSSadaf Ebrahimi i = 2 * ((top_bracket + 1 > match_data->oveccount)?
937*22dc650dSSadaf Ebrahimi match_data->oveccount : top_bracket + 1);
938*22dc650dSSadaf Ebrahimi memcpy(match_data->ovector + 2, Fovector, (i - 2) * sizeof(PCRE2_SIZE));
939*22dc650dSSadaf Ebrahimi while (--i >= Foffset_top + 2) match_data->ovector[i] = PCRE2_UNSET;
940*22dc650dSSadaf Ebrahimi return MATCH_MATCH; /* Note: NOT RRETURN */
941*22dc650dSSadaf Ebrahimi
942*22dc650dSSadaf Ebrahimi
943*22dc650dSSadaf Ebrahimi /*===================================================================== */
944*22dc650dSSadaf Ebrahimi /* Match any single character type except newline; have to take care with
945*22dc650dSSadaf Ebrahimi CRLF newlines and partial matching. */
946*22dc650dSSadaf Ebrahimi
947*22dc650dSSadaf Ebrahimi case OP_ANY:
948*22dc650dSSadaf Ebrahimi if (IS_NEWLINE(Feptr)) RRETURN(MATCH_NOMATCH);
949*22dc650dSSadaf Ebrahimi if (mb->partial != 0 &&
950*22dc650dSSadaf Ebrahimi Feptr == mb->end_subject - 1 &&
951*22dc650dSSadaf Ebrahimi NLBLOCK->nltype == NLTYPE_FIXED &&
952*22dc650dSSadaf Ebrahimi NLBLOCK->nllen == 2 &&
953*22dc650dSSadaf Ebrahimi UCHAR21TEST(Feptr) == NLBLOCK->nl[0])
954*22dc650dSSadaf Ebrahimi {
955*22dc650dSSadaf Ebrahimi mb->hitend = TRUE;
956*22dc650dSSadaf Ebrahimi if (mb->partial > 1) return PCRE2_ERROR_PARTIAL;
957*22dc650dSSadaf Ebrahimi }
958*22dc650dSSadaf Ebrahimi /* Fall through */
959*22dc650dSSadaf Ebrahimi
960*22dc650dSSadaf Ebrahimi /* Match any single character whatsoever. */
961*22dc650dSSadaf Ebrahimi
962*22dc650dSSadaf Ebrahimi case OP_ALLANY:
963*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject) /* DO NOT merge the Feptr++ here; it must */
964*22dc650dSSadaf Ebrahimi { /* not be updated before SCHECK_PARTIAL. */
965*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
966*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
967*22dc650dSSadaf Ebrahimi }
968*22dc650dSSadaf Ebrahimi Feptr++;
969*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_UNICODE
970*22dc650dSSadaf Ebrahimi if (utf) ACROSSCHAR(Feptr < mb->end_subject, Feptr, Feptr++);
971*22dc650dSSadaf Ebrahimi #endif
972*22dc650dSSadaf Ebrahimi Fecode++;
973*22dc650dSSadaf Ebrahimi break;
974*22dc650dSSadaf Ebrahimi
975*22dc650dSSadaf Ebrahimi
976*22dc650dSSadaf Ebrahimi /* ===================================================================== */
977*22dc650dSSadaf Ebrahimi /* Match a single code unit, even in UTF mode. This opcode really does
978*22dc650dSSadaf Ebrahimi match any code unit, even newline. (It really should be called ANYCODEUNIT,
979*22dc650dSSadaf Ebrahimi of course - the byte name is from pre-16 bit days.) */
980*22dc650dSSadaf Ebrahimi
981*22dc650dSSadaf Ebrahimi case OP_ANYBYTE:
982*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject) /* DO NOT merge the Feptr++ here; it must */
983*22dc650dSSadaf Ebrahimi { /* not be updated before SCHECK_PARTIAL. */
984*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
985*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
986*22dc650dSSadaf Ebrahimi }
987*22dc650dSSadaf Ebrahimi Feptr++;
988*22dc650dSSadaf Ebrahimi Fecode++;
989*22dc650dSSadaf Ebrahimi break;
990*22dc650dSSadaf Ebrahimi
991*22dc650dSSadaf Ebrahimi
992*22dc650dSSadaf Ebrahimi /* ===================================================================== */
993*22dc650dSSadaf Ebrahimi /* Match a single character, casefully */
994*22dc650dSSadaf Ebrahimi
995*22dc650dSSadaf Ebrahimi case OP_CHAR:
996*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_UNICODE
997*22dc650dSSadaf Ebrahimi if (utf)
998*22dc650dSSadaf Ebrahimi {
999*22dc650dSSadaf Ebrahimi Flength = 1;
1000*22dc650dSSadaf Ebrahimi Fecode++;
1001*22dc650dSSadaf Ebrahimi GETCHARLEN(fc, Fecode, Flength);
1002*22dc650dSSadaf Ebrahimi if (Flength > (PCRE2_SIZE)(mb->end_subject - Feptr))
1003*22dc650dSSadaf Ebrahimi {
1004*22dc650dSSadaf Ebrahimi CHECK_PARTIAL(); /* Not SCHECK_PARTIAL() */
1005*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
1006*22dc650dSSadaf Ebrahimi }
1007*22dc650dSSadaf Ebrahimi for (; Flength > 0; Flength--)
1008*22dc650dSSadaf Ebrahimi {
1009*22dc650dSSadaf Ebrahimi if (*Fecode++ != UCHAR21INC(Feptr)) RRETURN(MATCH_NOMATCH);
1010*22dc650dSSadaf Ebrahimi }
1011*22dc650dSSadaf Ebrahimi }
1012*22dc650dSSadaf Ebrahimi else
1013*22dc650dSSadaf Ebrahimi #endif
1014*22dc650dSSadaf Ebrahimi
1015*22dc650dSSadaf Ebrahimi /* Not UTF mode */
1016*22dc650dSSadaf Ebrahimi {
1017*22dc650dSSadaf Ebrahimi if (mb->end_subject - Feptr < 1)
1018*22dc650dSSadaf Ebrahimi {
1019*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL(); /* This one can use SCHECK_PARTIAL() */
1020*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
1021*22dc650dSSadaf Ebrahimi }
1022*22dc650dSSadaf Ebrahimi if (Fecode[1] != *Feptr++) RRETURN(MATCH_NOMATCH);
1023*22dc650dSSadaf Ebrahimi Fecode += 2;
1024*22dc650dSSadaf Ebrahimi }
1025*22dc650dSSadaf Ebrahimi break;
1026*22dc650dSSadaf Ebrahimi
1027*22dc650dSSadaf Ebrahimi
1028*22dc650dSSadaf Ebrahimi /* ===================================================================== */
1029*22dc650dSSadaf Ebrahimi /* Match a single character, caselessly. If we are at the end of the
1030*22dc650dSSadaf Ebrahimi subject, give up immediately. We get here only when the pattern character
1031*22dc650dSSadaf Ebrahimi has at most one other case. Characters with more than two cases are coded
1032*22dc650dSSadaf Ebrahimi as OP_PROP with the pseudo-property PT_CLIST. */
1033*22dc650dSSadaf Ebrahimi
1034*22dc650dSSadaf Ebrahimi case OP_CHARI:
1035*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
1036*22dc650dSSadaf Ebrahimi {
1037*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
1038*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
1039*22dc650dSSadaf Ebrahimi }
1040*22dc650dSSadaf Ebrahimi
1041*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_UNICODE
1042*22dc650dSSadaf Ebrahimi if (utf)
1043*22dc650dSSadaf Ebrahimi {
1044*22dc650dSSadaf Ebrahimi Flength = 1;
1045*22dc650dSSadaf Ebrahimi Fecode++;
1046*22dc650dSSadaf Ebrahimi GETCHARLEN(fc, Fecode, Flength);
1047*22dc650dSSadaf Ebrahimi
1048*22dc650dSSadaf Ebrahimi /* If the pattern character's value is < 128, we know that its other case
1049*22dc650dSSadaf Ebrahimi (if any) is also < 128 (and therefore only one code unit long in all
1050*22dc650dSSadaf Ebrahimi code-unit widths), so we can use the fast lookup table. We checked above
1051*22dc650dSSadaf Ebrahimi that there is at least one character left in the subject. */
1052*22dc650dSSadaf Ebrahimi
1053*22dc650dSSadaf Ebrahimi if (fc < 128)
1054*22dc650dSSadaf Ebrahimi {
1055*22dc650dSSadaf Ebrahimi uint32_t cc = UCHAR21(Feptr);
1056*22dc650dSSadaf Ebrahimi if (mb->lcc[fc] != TABLE_GET(cc, mb->lcc, cc)) RRETURN(MATCH_NOMATCH);
1057*22dc650dSSadaf Ebrahimi Fecode++;
1058*22dc650dSSadaf Ebrahimi Feptr++;
1059*22dc650dSSadaf Ebrahimi }
1060*22dc650dSSadaf Ebrahimi
1061*22dc650dSSadaf Ebrahimi /* Otherwise we must pick up the subject character and use Unicode
1062*22dc650dSSadaf Ebrahimi property support to test its other case. Note that we cannot use the
1063*22dc650dSSadaf Ebrahimi value of "Flength" to check for sufficient bytes left, because the other
1064*22dc650dSSadaf Ebrahimi case of the character may have more or fewer code units. */
1065*22dc650dSSadaf Ebrahimi
1066*22dc650dSSadaf Ebrahimi else
1067*22dc650dSSadaf Ebrahimi {
1068*22dc650dSSadaf Ebrahimi uint32_t dc;
1069*22dc650dSSadaf Ebrahimi GETCHARINC(dc, Feptr);
1070*22dc650dSSadaf Ebrahimi Fecode += Flength;
1071*22dc650dSSadaf Ebrahimi if (dc != fc && dc != UCD_OTHERCASE(fc)) RRETURN(MATCH_NOMATCH);
1072*22dc650dSSadaf Ebrahimi }
1073*22dc650dSSadaf Ebrahimi }
1074*22dc650dSSadaf Ebrahimi
1075*22dc650dSSadaf Ebrahimi /* If UCP is set without UTF we must do the same as above, but with one
1076*22dc650dSSadaf Ebrahimi character per code unit. */
1077*22dc650dSSadaf Ebrahimi
1078*22dc650dSSadaf Ebrahimi else if (ucp)
1079*22dc650dSSadaf Ebrahimi {
1080*22dc650dSSadaf Ebrahimi uint32_t cc = UCHAR21(Feptr);
1081*22dc650dSSadaf Ebrahimi fc = Fecode[1];
1082*22dc650dSSadaf Ebrahimi if (fc < 128)
1083*22dc650dSSadaf Ebrahimi {
1084*22dc650dSSadaf Ebrahimi if (mb->lcc[fc] != TABLE_GET(cc, mb->lcc, cc)) RRETURN(MATCH_NOMATCH);
1085*22dc650dSSadaf Ebrahimi }
1086*22dc650dSSadaf Ebrahimi else
1087*22dc650dSSadaf Ebrahimi {
1088*22dc650dSSadaf Ebrahimi if (cc != fc && cc != UCD_OTHERCASE(fc)) RRETURN(MATCH_NOMATCH);
1089*22dc650dSSadaf Ebrahimi }
1090*22dc650dSSadaf Ebrahimi Feptr++;
1091*22dc650dSSadaf Ebrahimi Fecode += 2;
1092*22dc650dSSadaf Ebrahimi }
1093*22dc650dSSadaf Ebrahimi
1094*22dc650dSSadaf Ebrahimi else
1095*22dc650dSSadaf Ebrahimi #endif /* SUPPORT_UNICODE */
1096*22dc650dSSadaf Ebrahimi
1097*22dc650dSSadaf Ebrahimi /* Not UTF or UCP mode; use the table for characters < 256. */
1098*22dc650dSSadaf Ebrahimi {
1099*22dc650dSSadaf Ebrahimi if (TABLE_GET(Fecode[1], mb->lcc, Fecode[1])
1100*22dc650dSSadaf Ebrahimi != TABLE_GET(*Feptr, mb->lcc, *Feptr)) RRETURN(MATCH_NOMATCH);
1101*22dc650dSSadaf Ebrahimi Feptr++;
1102*22dc650dSSadaf Ebrahimi Fecode += 2;
1103*22dc650dSSadaf Ebrahimi }
1104*22dc650dSSadaf Ebrahimi break;
1105*22dc650dSSadaf Ebrahimi
1106*22dc650dSSadaf Ebrahimi
1107*22dc650dSSadaf Ebrahimi /* ===================================================================== */
1108*22dc650dSSadaf Ebrahimi /* Match not a single character. */
1109*22dc650dSSadaf Ebrahimi
1110*22dc650dSSadaf Ebrahimi case OP_NOT:
1111*22dc650dSSadaf Ebrahimi case OP_NOTI:
1112*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
1113*22dc650dSSadaf Ebrahimi {
1114*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
1115*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
1116*22dc650dSSadaf Ebrahimi }
1117*22dc650dSSadaf Ebrahimi
1118*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_UNICODE
1119*22dc650dSSadaf Ebrahimi if (utf)
1120*22dc650dSSadaf Ebrahimi {
1121*22dc650dSSadaf Ebrahimi uint32_t ch;
1122*22dc650dSSadaf Ebrahimi Fecode++;
1123*22dc650dSSadaf Ebrahimi GETCHARINC(ch, Fecode);
1124*22dc650dSSadaf Ebrahimi GETCHARINC(fc, Feptr);
1125*22dc650dSSadaf Ebrahimi if (ch == fc)
1126*22dc650dSSadaf Ebrahimi {
1127*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH); /* Caseful match */
1128*22dc650dSSadaf Ebrahimi }
1129*22dc650dSSadaf Ebrahimi else if (Fop == OP_NOTI) /* If caseless */
1130*22dc650dSSadaf Ebrahimi {
1131*22dc650dSSadaf Ebrahimi if (ch > 127)
1132*22dc650dSSadaf Ebrahimi ch = UCD_OTHERCASE(ch);
1133*22dc650dSSadaf Ebrahimi else
1134*22dc650dSSadaf Ebrahimi ch = (mb->fcc)[ch];
1135*22dc650dSSadaf Ebrahimi if (ch == fc) RRETURN(MATCH_NOMATCH);
1136*22dc650dSSadaf Ebrahimi }
1137*22dc650dSSadaf Ebrahimi }
1138*22dc650dSSadaf Ebrahimi
1139*22dc650dSSadaf Ebrahimi /* UCP without UTF is as above, but with one character per code unit. */
1140*22dc650dSSadaf Ebrahimi
1141*22dc650dSSadaf Ebrahimi else if (ucp)
1142*22dc650dSSadaf Ebrahimi {
1143*22dc650dSSadaf Ebrahimi uint32_t ch;
1144*22dc650dSSadaf Ebrahimi fc = UCHAR21INC(Feptr);
1145*22dc650dSSadaf Ebrahimi ch = Fecode[1];
1146*22dc650dSSadaf Ebrahimi Fecode += 2;
1147*22dc650dSSadaf Ebrahimi
1148*22dc650dSSadaf Ebrahimi if (ch == fc)
1149*22dc650dSSadaf Ebrahimi {
1150*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH); /* Caseful match */
1151*22dc650dSSadaf Ebrahimi }
1152*22dc650dSSadaf Ebrahimi else if (Fop == OP_NOTI) /* If caseless */
1153*22dc650dSSadaf Ebrahimi {
1154*22dc650dSSadaf Ebrahimi if (ch > 127)
1155*22dc650dSSadaf Ebrahimi ch = UCD_OTHERCASE(ch);
1156*22dc650dSSadaf Ebrahimi else
1157*22dc650dSSadaf Ebrahimi ch = (mb->fcc)[ch];
1158*22dc650dSSadaf Ebrahimi if (ch == fc) RRETURN(MATCH_NOMATCH);
1159*22dc650dSSadaf Ebrahimi }
1160*22dc650dSSadaf Ebrahimi }
1161*22dc650dSSadaf Ebrahimi
1162*22dc650dSSadaf Ebrahimi else
1163*22dc650dSSadaf Ebrahimi #endif /* SUPPORT_UNICODE */
1164*22dc650dSSadaf Ebrahimi
1165*22dc650dSSadaf Ebrahimi /* Neither UTF nor UCP is set */
1166*22dc650dSSadaf Ebrahimi
1167*22dc650dSSadaf Ebrahimi {
1168*22dc650dSSadaf Ebrahimi uint32_t ch = Fecode[1];
1169*22dc650dSSadaf Ebrahimi fc = UCHAR21INC(Feptr);
1170*22dc650dSSadaf Ebrahimi if (ch == fc || (Fop == OP_NOTI && TABLE_GET(ch, mb->fcc, ch) == fc))
1171*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
1172*22dc650dSSadaf Ebrahimi Fecode += 2;
1173*22dc650dSSadaf Ebrahimi }
1174*22dc650dSSadaf Ebrahimi break;
1175*22dc650dSSadaf Ebrahimi
1176*22dc650dSSadaf Ebrahimi
1177*22dc650dSSadaf Ebrahimi /* ===================================================================== */
1178*22dc650dSSadaf Ebrahimi /* Match a single character repeatedly. */
1179*22dc650dSSadaf Ebrahimi
1180*22dc650dSSadaf Ebrahimi #define Loclength F->temp_size
1181*22dc650dSSadaf Ebrahimi #define Lstart_eptr F->temp_sptr[0]
1182*22dc650dSSadaf Ebrahimi #define Lcharptr F->temp_sptr[1]
1183*22dc650dSSadaf Ebrahimi #define Lmin F->temp_32[0]
1184*22dc650dSSadaf Ebrahimi #define Lmax F->temp_32[1]
1185*22dc650dSSadaf Ebrahimi #define Lc F->temp_32[2]
1186*22dc650dSSadaf Ebrahimi #define Loc F->temp_32[3]
1187*22dc650dSSadaf Ebrahimi
1188*22dc650dSSadaf Ebrahimi case OP_EXACT:
1189*22dc650dSSadaf Ebrahimi case OP_EXACTI:
1190*22dc650dSSadaf Ebrahimi Lmin = Lmax = GET2(Fecode, 1);
1191*22dc650dSSadaf Ebrahimi Fecode += 1 + IMM2_SIZE;
1192*22dc650dSSadaf Ebrahimi goto REPEATCHAR;
1193*22dc650dSSadaf Ebrahimi
1194*22dc650dSSadaf Ebrahimi case OP_POSUPTO:
1195*22dc650dSSadaf Ebrahimi case OP_POSUPTOI:
1196*22dc650dSSadaf Ebrahimi reptype = REPTYPE_POS;
1197*22dc650dSSadaf Ebrahimi Lmin = 0;
1198*22dc650dSSadaf Ebrahimi Lmax = GET2(Fecode, 1);
1199*22dc650dSSadaf Ebrahimi Fecode += 1 + IMM2_SIZE;
1200*22dc650dSSadaf Ebrahimi goto REPEATCHAR;
1201*22dc650dSSadaf Ebrahimi
1202*22dc650dSSadaf Ebrahimi case OP_UPTO:
1203*22dc650dSSadaf Ebrahimi case OP_UPTOI:
1204*22dc650dSSadaf Ebrahimi reptype = REPTYPE_MAX;
1205*22dc650dSSadaf Ebrahimi Lmin = 0;
1206*22dc650dSSadaf Ebrahimi Lmax = GET2(Fecode, 1);
1207*22dc650dSSadaf Ebrahimi Fecode += 1 + IMM2_SIZE;
1208*22dc650dSSadaf Ebrahimi goto REPEATCHAR;
1209*22dc650dSSadaf Ebrahimi
1210*22dc650dSSadaf Ebrahimi case OP_MINUPTO:
1211*22dc650dSSadaf Ebrahimi case OP_MINUPTOI:
1212*22dc650dSSadaf Ebrahimi reptype = REPTYPE_MIN;
1213*22dc650dSSadaf Ebrahimi Lmin = 0;
1214*22dc650dSSadaf Ebrahimi Lmax = GET2(Fecode, 1);
1215*22dc650dSSadaf Ebrahimi Fecode += 1 + IMM2_SIZE;
1216*22dc650dSSadaf Ebrahimi goto REPEATCHAR;
1217*22dc650dSSadaf Ebrahimi
1218*22dc650dSSadaf Ebrahimi case OP_POSSTAR:
1219*22dc650dSSadaf Ebrahimi case OP_POSSTARI:
1220*22dc650dSSadaf Ebrahimi reptype = REPTYPE_POS;
1221*22dc650dSSadaf Ebrahimi Lmin = 0;
1222*22dc650dSSadaf Ebrahimi Lmax = UINT32_MAX;
1223*22dc650dSSadaf Ebrahimi Fecode++;
1224*22dc650dSSadaf Ebrahimi goto REPEATCHAR;
1225*22dc650dSSadaf Ebrahimi
1226*22dc650dSSadaf Ebrahimi case OP_POSPLUS:
1227*22dc650dSSadaf Ebrahimi case OP_POSPLUSI:
1228*22dc650dSSadaf Ebrahimi reptype = REPTYPE_POS;
1229*22dc650dSSadaf Ebrahimi Lmin = 1;
1230*22dc650dSSadaf Ebrahimi Lmax = UINT32_MAX;
1231*22dc650dSSadaf Ebrahimi Fecode++;
1232*22dc650dSSadaf Ebrahimi goto REPEATCHAR;
1233*22dc650dSSadaf Ebrahimi
1234*22dc650dSSadaf Ebrahimi case OP_POSQUERY:
1235*22dc650dSSadaf Ebrahimi case OP_POSQUERYI:
1236*22dc650dSSadaf Ebrahimi reptype = REPTYPE_POS;
1237*22dc650dSSadaf Ebrahimi Lmin = 0;
1238*22dc650dSSadaf Ebrahimi Lmax = 1;
1239*22dc650dSSadaf Ebrahimi Fecode++;
1240*22dc650dSSadaf Ebrahimi goto REPEATCHAR;
1241*22dc650dSSadaf Ebrahimi
1242*22dc650dSSadaf Ebrahimi case OP_STAR:
1243*22dc650dSSadaf Ebrahimi case OP_STARI:
1244*22dc650dSSadaf Ebrahimi case OP_MINSTAR:
1245*22dc650dSSadaf Ebrahimi case OP_MINSTARI:
1246*22dc650dSSadaf Ebrahimi case OP_PLUS:
1247*22dc650dSSadaf Ebrahimi case OP_PLUSI:
1248*22dc650dSSadaf Ebrahimi case OP_MINPLUS:
1249*22dc650dSSadaf Ebrahimi case OP_MINPLUSI:
1250*22dc650dSSadaf Ebrahimi case OP_QUERY:
1251*22dc650dSSadaf Ebrahimi case OP_QUERYI:
1252*22dc650dSSadaf Ebrahimi case OP_MINQUERY:
1253*22dc650dSSadaf Ebrahimi case OP_MINQUERYI:
1254*22dc650dSSadaf Ebrahimi fc = *Fecode++ - ((Fop < OP_STARI)? OP_STAR : OP_STARI);
1255*22dc650dSSadaf Ebrahimi Lmin = rep_min[fc];
1256*22dc650dSSadaf Ebrahimi Lmax = rep_max[fc];
1257*22dc650dSSadaf Ebrahimi reptype = rep_typ[fc];
1258*22dc650dSSadaf Ebrahimi
1259*22dc650dSSadaf Ebrahimi /* Common code for all repeated single-character matches. We first check
1260*22dc650dSSadaf Ebrahimi for the minimum number of characters. If the minimum equals the maximum, we
1261*22dc650dSSadaf Ebrahimi are done. Otherwise, if minimizing, check the rest of the pattern for a
1262*22dc650dSSadaf Ebrahimi match; if there isn't one, advance up to the maximum, one character at a
1263*22dc650dSSadaf Ebrahimi time.
1264*22dc650dSSadaf Ebrahimi
1265*22dc650dSSadaf Ebrahimi If maximizing, advance up to the maximum number of matching characters,
1266*22dc650dSSadaf Ebrahimi until Feptr is past the end of the maximum run. If possessive, we are
1267*22dc650dSSadaf Ebrahimi then done (no backing up). Otherwise, match at this position; anything
1268*22dc650dSSadaf Ebrahimi other than no match is immediately returned. For nomatch, back up one
1269*22dc650dSSadaf Ebrahimi character, unless we are matching \R and the last thing matched was
1270*22dc650dSSadaf Ebrahimi \r\n, in which case, back up two code units until we reach the first
1271*22dc650dSSadaf Ebrahimi optional character position.
1272*22dc650dSSadaf Ebrahimi
1273*22dc650dSSadaf Ebrahimi The various UTF/non-UTF and caseful/caseless cases are handled separately,
1274*22dc650dSSadaf Ebrahimi for speed. */
1275*22dc650dSSadaf Ebrahimi
1276*22dc650dSSadaf Ebrahimi REPEATCHAR:
1277*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_UNICODE
1278*22dc650dSSadaf Ebrahimi if (utf)
1279*22dc650dSSadaf Ebrahimi {
1280*22dc650dSSadaf Ebrahimi Flength = 1;
1281*22dc650dSSadaf Ebrahimi Lcharptr = Fecode;
1282*22dc650dSSadaf Ebrahimi GETCHARLEN(fc, Fecode, Flength);
1283*22dc650dSSadaf Ebrahimi Fecode += Flength;
1284*22dc650dSSadaf Ebrahimi
1285*22dc650dSSadaf Ebrahimi /* Handle multi-code-unit character matching, caseful and caseless. */
1286*22dc650dSSadaf Ebrahimi
1287*22dc650dSSadaf Ebrahimi if (Flength > 1)
1288*22dc650dSSadaf Ebrahimi {
1289*22dc650dSSadaf Ebrahimi uint32_t othercase;
1290*22dc650dSSadaf Ebrahimi
1291*22dc650dSSadaf Ebrahimi if (Fop >= OP_STARI && /* Caseless */
1292*22dc650dSSadaf Ebrahimi (othercase = UCD_OTHERCASE(fc)) != fc)
1293*22dc650dSSadaf Ebrahimi Loclength = PRIV(ord2utf)(othercase, Foccu);
1294*22dc650dSSadaf Ebrahimi else Loclength = 0;
1295*22dc650dSSadaf Ebrahimi
1296*22dc650dSSadaf Ebrahimi for (i = 1; i <= Lmin; i++)
1297*22dc650dSSadaf Ebrahimi {
1298*22dc650dSSadaf Ebrahimi if (Feptr <= mb->end_subject - Flength &&
1299*22dc650dSSadaf Ebrahimi memcmp(Feptr, Lcharptr, CU2BYTES(Flength)) == 0) Feptr += Flength;
1300*22dc650dSSadaf Ebrahimi else if (Loclength > 0 &&
1301*22dc650dSSadaf Ebrahimi Feptr <= mb->end_subject - Loclength &&
1302*22dc650dSSadaf Ebrahimi memcmp(Feptr, Foccu, CU2BYTES(Loclength)) == 0)
1303*22dc650dSSadaf Ebrahimi Feptr += Loclength;
1304*22dc650dSSadaf Ebrahimi else
1305*22dc650dSSadaf Ebrahimi {
1306*22dc650dSSadaf Ebrahimi CHECK_PARTIAL();
1307*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
1308*22dc650dSSadaf Ebrahimi }
1309*22dc650dSSadaf Ebrahimi }
1310*22dc650dSSadaf Ebrahimi
1311*22dc650dSSadaf Ebrahimi if (Lmin == Lmax) continue;
1312*22dc650dSSadaf Ebrahimi
1313*22dc650dSSadaf Ebrahimi if (reptype == REPTYPE_MIN)
1314*22dc650dSSadaf Ebrahimi {
1315*22dc650dSSadaf Ebrahimi for (;;)
1316*22dc650dSSadaf Ebrahimi {
1317*22dc650dSSadaf Ebrahimi RMATCH(Fecode, RM202);
1318*22dc650dSSadaf Ebrahimi if (rrc != MATCH_NOMATCH) RRETURN(rrc);
1319*22dc650dSSadaf Ebrahimi if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH);
1320*22dc650dSSadaf Ebrahimi if (Feptr <= mb->end_subject - Flength &&
1321*22dc650dSSadaf Ebrahimi memcmp(Feptr, Lcharptr, CU2BYTES(Flength)) == 0) Feptr += Flength;
1322*22dc650dSSadaf Ebrahimi else if (Loclength > 0 &&
1323*22dc650dSSadaf Ebrahimi Feptr <= mb->end_subject - Loclength &&
1324*22dc650dSSadaf Ebrahimi memcmp(Feptr, Foccu, CU2BYTES(Loclength)) == 0)
1325*22dc650dSSadaf Ebrahimi Feptr += Loclength;
1326*22dc650dSSadaf Ebrahimi else
1327*22dc650dSSadaf Ebrahimi {
1328*22dc650dSSadaf Ebrahimi CHECK_PARTIAL();
1329*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
1330*22dc650dSSadaf Ebrahimi }
1331*22dc650dSSadaf Ebrahimi }
1332*22dc650dSSadaf Ebrahimi /* Control never gets here */
1333*22dc650dSSadaf Ebrahimi }
1334*22dc650dSSadaf Ebrahimi
1335*22dc650dSSadaf Ebrahimi else /* Maximize */
1336*22dc650dSSadaf Ebrahimi {
1337*22dc650dSSadaf Ebrahimi Lstart_eptr = Feptr;
1338*22dc650dSSadaf Ebrahimi for (i = Lmin; i < Lmax; i++)
1339*22dc650dSSadaf Ebrahimi {
1340*22dc650dSSadaf Ebrahimi if (Feptr <= mb->end_subject - Flength &&
1341*22dc650dSSadaf Ebrahimi memcmp(Feptr, Lcharptr, CU2BYTES(Flength)) == 0)
1342*22dc650dSSadaf Ebrahimi Feptr += Flength;
1343*22dc650dSSadaf Ebrahimi else if (Loclength > 0 &&
1344*22dc650dSSadaf Ebrahimi Feptr <= mb->end_subject - Loclength &&
1345*22dc650dSSadaf Ebrahimi memcmp(Feptr, Foccu, CU2BYTES(Loclength)) == 0)
1346*22dc650dSSadaf Ebrahimi Feptr += Loclength;
1347*22dc650dSSadaf Ebrahimi else
1348*22dc650dSSadaf Ebrahimi {
1349*22dc650dSSadaf Ebrahimi CHECK_PARTIAL();
1350*22dc650dSSadaf Ebrahimi break;
1351*22dc650dSSadaf Ebrahimi }
1352*22dc650dSSadaf Ebrahimi }
1353*22dc650dSSadaf Ebrahimi
1354*22dc650dSSadaf Ebrahimi /* After \C in UTF mode, Lstart_eptr might be in the middle of a
1355*22dc650dSSadaf Ebrahimi Unicode character. Use <= Lstart_eptr to ensure backtracking doesn't
1356*22dc650dSSadaf Ebrahimi go too far. */
1357*22dc650dSSadaf Ebrahimi
1358*22dc650dSSadaf Ebrahimi if (reptype != REPTYPE_POS) for(;;)
1359*22dc650dSSadaf Ebrahimi {
1360*22dc650dSSadaf Ebrahimi if (Feptr <= Lstart_eptr) break;
1361*22dc650dSSadaf Ebrahimi RMATCH(Fecode, RM203);
1362*22dc650dSSadaf Ebrahimi if (rrc != MATCH_NOMATCH) RRETURN(rrc);
1363*22dc650dSSadaf Ebrahimi Feptr--;
1364*22dc650dSSadaf Ebrahimi BACKCHAR(Feptr);
1365*22dc650dSSadaf Ebrahimi }
1366*22dc650dSSadaf Ebrahimi }
1367*22dc650dSSadaf Ebrahimi break; /* End of repeated wide character handling */
1368*22dc650dSSadaf Ebrahimi }
1369*22dc650dSSadaf Ebrahimi
1370*22dc650dSSadaf Ebrahimi /* Length of UTF character is 1. Put it into the preserved variable and
1371*22dc650dSSadaf Ebrahimi fall through to the non-UTF code. */
1372*22dc650dSSadaf Ebrahimi
1373*22dc650dSSadaf Ebrahimi Lc = fc;
1374*22dc650dSSadaf Ebrahimi }
1375*22dc650dSSadaf Ebrahimi else
1376*22dc650dSSadaf Ebrahimi #endif /* SUPPORT_UNICODE */
1377*22dc650dSSadaf Ebrahimi
1378*22dc650dSSadaf Ebrahimi /* When not in UTF mode, load a single-code-unit character. Then proceed as
1379*22dc650dSSadaf Ebrahimi above, using Unicode casing if either UTF or UCP is set. */
1380*22dc650dSSadaf Ebrahimi
1381*22dc650dSSadaf Ebrahimi Lc = *Fecode++;
1382*22dc650dSSadaf Ebrahimi
1383*22dc650dSSadaf Ebrahimi /* Caseless comparison */
1384*22dc650dSSadaf Ebrahimi
1385*22dc650dSSadaf Ebrahimi if (Fop >= OP_STARI)
1386*22dc650dSSadaf Ebrahimi {
1387*22dc650dSSadaf Ebrahimi #if PCRE2_CODE_UNIT_WIDTH == 8
1388*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_UNICODE
1389*22dc650dSSadaf Ebrahimi if (ucp && !utf && Lc > 127) Loc = UCD_OTHERCASE(Lc);
1390*22dc650dSSadaf Ebrahimi else
1391*22dc650dSSadaf Ebrahimi #endif /* SUPPORT_UNICODE */
1392*22dc650dSSadaf Ebrahimi /* Lc will be < 128 in UTF-8 mode. */
1393*22dc650dSSadaf Ebrahimi Loc = mb->fcc[Lc];
1394*22dc650dSSadaf Ebrahimi #else /* 16-bit & 32-bit */
1395*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_UNICODE
1396*22dc650dSSadaf Ebrahimi if ((utf || ucp) && Lc > 127) Loc = UCD_OTHERCASE(Lc);
1397*22dc650dSSadaf Ebrahimi else
1398*22dc650dSSadaf Ebrahimi #endif /* SUPPORT_UNICODE */
1399*22dc650dSSadaf Ebrahimi Loc = TABLE_GET(Lc, mb->fcc, Lc);
1400*22dc650dSSadaf Ebrahimi #endif /* PCRE2_CODE_UNIT_WIDTH == 8 */
1401*22dc650dSSadaf Ebrahimi
1402*22dc650dSSadaf Ebrahimi for (i = 1; i <= Lmin; i++)
1403*22dc650dSSadaf Ebrahimi {
1404*22dc650dSSadaf Ebrahimi uint32_t cc; /* Faster than PCRE2_UCHAR */
1405*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
1406*22dc650dSSadaf Ebrahimi {
1407*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
1408*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
1409*22dc650dSSadaf Ebrahimi }
1410*22dc650dSSadaf Ebrahimi cc = UCHAR21TEST(Feptr);
1411*22dc650dSSadaf Ebrahimi if (Lc != cc && Loc != cc) RRETURN(MATCH_NOMATCH);
1412*22dc650dSSadaf Ebrahimi Feptr++;
1413*22dc650dSSadaf Ebrahimi }
1414*22dc650dSSadaf Ebrahimi if (Lmin == Lmax) continue;
1415*22dc650dSSadaf Ebrahimi
1416*22dc650dSSadaf Ebrahimi if (reptype == REPTYPE_MIN)
1417*22dc650dSSadaf Ebrahimi {
1418*22dc650dSSadaf Ebrahimi for (;;)
1419*22dc650dSSadaf Ebrahimi {
1420*22dc650dSSadaf Ebrahimi uint32_t cc; /* Faster than PCRE2_UCHAR */
1421*22dc650dSSadaf Ebrahimi RMATCH(Fecode, RM25);
1422*22dc650dSSadaf Ebrahimi if (rrc != MATCH_NOMATCH) RRETURN(rrc);
1423*22dc650dSSadaf Ebrahimi if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH);
1424*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
1425*22dc650dSSadaf Ebrahimi {
1426*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
1427*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
1428*22dc650dSSadaf Ebrahimi }
1429*22dc650dSSadaf Ebrahimi cc = UCHAR21TEST(Feptr);
1430*22dc650dSSadaf Ebrahimi if (Lc != cc && Loc != cc) RRETURN(MATCH_NOMATCH);
1431*22dc650dSSadaf Ebrahimi Feptr++;
1432*22dc650dSSadaf Ebrahimi }
1433*22dc650dSSadaf Ebrahimi /* Control never gets here */
1434*22dc650dSSadaf Ebrahimi }
1435*22dc650dSSadaf Ebrahimi
1436*22dc650dSSadaf Ebrahimi else /* Maximize */
1437*22dc650dSSadaf Ebrahimi {
1438*22dc650dSSadaf Ebrahimi Lstart_eptr = Feptr;
1439*22dc650dSSadaf Ebrahimi for (i = Lmin; i < Lmax; i++)
1440*22dc650dSSadaf Ebrahimi {
1441*22dc650dSSadaf Ebrahimi uint32_t cc; /* Faster than PCRE2_UCHAR */
1442*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
1443*22dc650dSSadaf Ebrahimi {
1444*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
1445*22dc650dSSadaf Ebrahimi break;
1446*22dc650dSSadaf Ebrahimi }
1447*22dc650dSSadaf Ebrahimi cc = UCHAR21TEST(Feptr);
1448*22dc650dSSadaf Ebrahimi if (Lc != cc && Loc != cc) break;
1449*22dc650dSSadaf Ebrahimi Feptr++;
1450*22dc650dSSadaf Ebrahimi }
1451*22dc650dSSadaf Ebrahimi if (reptype != REPTYPE_POS) for (;;)
1452*22dc650dSSadaf Ebrahimi {
1453*22dc650dSSadaf Ebrahimi if (Feptr == Lstart_eptr) break;
1454*22dc650dSSadaf Ebrahimi RMATCH(Fecode, RM26);
1455*22dc650dSSadaf Ebrahimi Feptr--;
1456*22dc650dSSadaf Ebrahimi if (rrc != MATCH_NOMATCH) RRETURN(rrc);
1457*22dc650dSSadaf Ebrahimi }
1458*22dc650dSSadaf Ebrahimi }
1459*22dc650dSSadaf Ebrahimi }
1460*22dc650dSSadaf Ebrahimi
1461*22dc650dSSadaf Ebrahimi /* Caseful comparisons (includes all multi-byte characters) */
1462*22dc650dSSadaf Ebrahimi
1463*22dc650dSSadaf Ebrahimi else
1464*22dc650dSSadaf Ebrahimi {
1465*22dc650dSSadaf Ebrahimi for (i = 1; i <= Lmin; i++)
1466*22dc650dSSadaf Ebrahimi {
1467*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
1468*22dc650dSSadaf Ebrahimi {
1469*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
1470*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
1471*22dc650dSSadaf Ebrahimi }
1472*22dc650dSSadaf Ebrahimi if (Lc != UCHAR21INCTEST(Feptr)) RRETURN(MATCH_NOMATCH);
1473*22dc650dSSadaf Ebrahimi }
1474*22dc650dSSadaf Ebrahimi
1475*22dc650dSSadaf Ebrahimi if (Lmin == Lmax) continue;
1476*22dc650dSSadaf Ebrahimi
1477*22dc650dSSadaf Ebrahimi if (reptype == REPTYPE_MIN)
1478*22dc650dSSadaf Ebrahimi {
1479*22dc650dSSadaf Ebrahimi for (;;)
1480*22dc650dSSadaf Ebrahimi {
1481*22dc650dSSadaf Ebrahimi RMATCH(Fecode, RM27);
1482*22dc650dSSadaf Ebrahimi if (rrc != MATCH_NOMATCH) RRETURN(rrc);
1483*22dc650dSSadaf Ebrahimi if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH);
1484*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
1485*22dc650dSSadaf Ebrahimi {
1486*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
1487*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
1488*22dc650dSSadaf Ebrahimi }
1489*22dc650dSSadaf Ebrahimi if (Lc != UCHAR21INCTEST(Feptr)) RRETURN(MATCH_NOMATCH);
1490*22dc650dSSadaf Ebrahimi }
1491*22dc650dSSadaf Ebrahimi /* Control never gets here */
1492*22dc650dSSadaf Ebrahimi }
1493*22dc650dSSadaf Ebrahimi else /* Maximize */
1494*22dc650dSSadaf Ebrahimi {
1495*22dc650dSSadaf Ebrahimi Lstart_eptr = Feptr;
1496*22dc650dSSadaf Ebrahimi for (i = Lmin; i < Lmax; i++)
1497*22dc650dSSadaf Ebrahimi {
1498*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
1499*22dc650dSSadaf Ebrahimi {
1500*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
1501*22dc650dSSadaf Ebrahimi break;
1502*22dc650dSSadaf Ebrahimi }
1503*22dc650dSSadaf Ebrahimi
1504*22dc650dSSadaf Ebrahimi if (Lc != UCHAR21TEST(Feptr)) break;
1505*22dc650dSSadaf Ebrahimi Feptr++;
1506*22dc650dSSadaf Ebrahimi }
1507*22dc650dSSadaf Ebrahimi
1508*22dc650dSSadaf Ebrahimi if (reptype != REPTYPE_POS) for (;;)
1509*22dc650dSSadaf Ebrahimi {
1510*22dc650dSSadaf Ebrahimi if (Feptr <= Lstart_eptr) break;
1511*22dc650dSSadaf Ebrahimi RMATCH(Fecode, RM28);
1512*22dc650dSSadaf Ebrahimi Feptr--;
1513*22dc650dSSadaf Ebrahimi if (rrc != MATCH_NOMATCH) RRETURN(rrc);
1514*22dc650dSSadaf Ebrahimi }
1515*22dc650dSSadaf Ebrahimi }
1516*22dc650dSSadaf Ebrahimi }
1517*22dc650dSSadaf Ebrahimi break;
1518*22dc650dSSadaf Ebrahimi
1519*22dc650dSSadaf Ebrahimi #undef Loclength
1520*22dc650dSSadaf Ebrahimi #undef Lstart_eptr
1521*22dc650dSSadaf Ebrahimi #undef Lcharptr
1522*22dc650dSSadaf Ebrahimi #undef Lmin
1523*22dc650dSSadaf Ebrahimi #undef Lmax
1524*22dc650dSSadaf Ebrahimi #undef Lc
1525*22dc650dSSadaf Ebrahimi #undef Loc
1526*22dc650dSSadaf Ebrahimi
1527*22dc650dSSadaf Ebrahimi
1528*22dc650dSSadaf Ebrahimi /* ===================================================================== */
1529*22dc650dSSadaf Ebrahimi /* Match a negated single one-byte character repeatedly. This is almost a
1530*22dc650dSSadaf Ebrahimi repeat of the code for a repeated single character, but I haven't found a
1531*22dc650dSSadaf Ebrahimi nice way of commoning these up that doesn't require a test of the
1532*22dc650dSSadaf Ebrahimi positive/negative option for each character match. Maybe that wouldn't add
1533*22dc650dSSadaf Ebrahimi very much to the time taken, but character matching *is* what this is all
1534*22dc650dSSadaf Ebrahimi about... */
1535*22dc650dSSadaf Ebrahimi
1536*22dc650dSSadaf Ebrahimi #define Lstart_eptr F->temp_sptr[0]
1537*22dc650dSSadaf Ebrahimi #define Lmin F->temp_32[0]
1538*22dc650dSSadaf Ebrahimi #define Lmax F->temp_32[1]
1539*22dc650dSSadaf Ebrahimi #define Lc F->temp_32[2]
1540*22dc650dSSadaf Ebrahimi #define Loc F->temp_32[3]
1541*22dc650dSSadaf Ebrahimi
1542*22dc650dSSadaf Ebrahimi case OP_NOTEXACT:
1543*22dc650dSSadaf Ebrahimi case OP_NOTEXACTI:
1544*22dc650dSSadaf Ebrahimi Lmin = Lmax = GET2(Fecode, 1);
1545*22dc650dSSadaf Ebrahimi Fecode += 1 + IMM2_SIZE;
1546*22dc650dSSadaf Ebrahimi goto REPEATNOTCHAR;
1547*22dc650dSSadaf Ebrahimi
1548*22dc650dSSadaf Ebrahimi case OP_NOTUPTO:
1549*22dc650dSSadaf Ebrahimi case OP_NOTUPTOI:
1550*22dc650dSSadaf Ebrahimi Lmin = 0;
1551*22dc650dSSadaf Ebrahimi Lmax = GET2(Fecode, 1);
1552*22dc650dSSadaf Ebrahimi reptype = REPTYPE_MAX;
1553*22dc650dSSadaf Ebrahimi Fecode += 1 + IMM2_SIZE;
1554*22dc650dSSadaf Ebrahimi goto REPEATNOTCHAR;
1555*22dc650dSSadaf Ebrahimi
1556*22dc650dSSadaf Ebrahimi case OP_NOTMINUPTO:
1557*22dc650dSSadaf Ebrahimi case OP_NOTMINUPTOI:
1558*22dc650dSSadaf Ebrahimi Lmin = 0;
1559*22dc650dSSadaf Ebrahimi Lmax = GET2(Fecode, 1);
1560*22dc650dSSadaf Ebrahimi reptype = REPTYPE_MIN;
1561*22dc650dSSadaf Ebrahimi Fecode += 1 + IMM2_SIZE;
1562*22dc650dSSadaf Ebrahimi goto REPEATNOTCHAR;
1563*22dc650dSSadaf Ebrahimi
1564*22dc650dSSadaf Ebrahimi case OP_NOTPOSSTAR:
1565*22dc650dSSadaf Ebrahimi case OP_NOTPOSSTARI:
1566*22dc650dSSadaf Ebrahimi reptype = REPTYPE_POS;
1567*22dc650dSSadaf Ebrahimi Lmin = 0;
1568*22dc650dSSadaf Ebrahimi Lmax = UINT32_MAX;
1569*22dc650dSSadaf Ebrahimi Fecode++;
1570*22dc650dSSadaf Ebrahimi goto REPEATNOTCHAR;
1571*22dc650dSSadaf Ebrahimi
1572*22dc650dSSadaf Ebrahimi case OP_NOTPOSPLUS:
1573*22dc650dSSadaf Ebrahimi case OP_NOTPOSPLUSI:
1574*22dc650dSSadaf Ebrahimi reptype = REPTYPE_POS;
1575*22dc650dSSadaf Ebrahimi Lmin = 1;
1576*22dc650dSSadaf Ebrahimi Lmax = UINT32_MAX;
1577*22dc650dSSadaf Ebrahimi Fecode++;
1578*22dc650dSSadaf Ebrahimi goto REPEATNOTCHAR;
1579*22dc650dSSadaf Ebrahimi
1580*22dc650dSSadaf Ebrahimi case OP_NOTPOSQUERY:
1581*22dc650dSSadaf Ebrahimi case OP_NOTPOSQUERYI:
1582*22dc650dSSadaf Ebrahimi reptype = REPTYPE_POS;
1583*22dc650dSSadaf Ebrahimi Lmin = 0;
1584*22dc650dSSadaf Ebrahimi Lmax = 1;
1585*22dc650dSSadaf Ebrahimi Fecode++;
1586*22dc650dSSadaf Ebrahimi goto REPEATNOTCHAR;
1587*22dc650dSSadaf Ebrahimi
1588*22dc650dSSadaf Ebrahimi case OP_NOTPOSUPTO:
1589*22dc650dSSadaf Ebrahimi case OP_NOTPOSUPTOI:
1590*22dc650dSSadaf Ebrahimi reptype = REPTYPE_POS;
1591*22dc650dSSadaf Ebrahimi Lmin = 0;
1592*22dc650dSSadaf Ebrahimi Lmax = GET2(Fecode, 1);
1593*22dc650dSSadaf Ebrahimi Fecode += 1 + IMM2_SIZE;
1594*22dc650dSSadaf Ebrahimi goto REPEATNOTCHAR;
1595*22dc650dSSadaf Ebrahimi
1596*22dc650dSSadaf Ebrahimi case OP_NOTSTAR:
1597*22dc650dSSadaf Ebrahimi case OP_NOTSTARI:
1598*22dc650dSSadaf Ebrahimi case OP_NOTMINSTAR:
1599*22dc650dSSadaf Ebrahimi case OP_NOTMINSTARI:
1600*22dc650dSSadaf Ebrahimi case OP_NOTPLUS:
1601*22dc650dSSadaf Ebrahimi case OP_NOTPLUSI:
1602*22dc650dSSadaf Ebrahimi case OP_NOTMINPLUS:
1603*22dc650dSSadaf Ebrahimi case OP_NOTMINPLUSI:
1604*22dc650dSSadaf Ebrahimi case OP_NOTQUERY:
1605*22dc650dSSadaf Ebrahimi case OP_NOTQUERYI:
1606*22dc650dSSadaf Ebrahimi case OP_NOTMINQUERY:
1607*22dc650dSSadaf Ebrahimi case OP_NOTMINQUERYI:
1608*22dc650dSSadaf Ebrahimi fc = *Fecode++ - ((Fop >= OP_NOTSTARI)? OP_NOTSTARI: OP_NOTSTAR);
1609*22dc650dSSadaf Ebrahimi Lmin = rep_min[fc];
1610*22dc650dSSadaf Ebrahimi Lmax = rep_max[fc];
1611*22dc650dSSadaf Ebrahimi reptype = rep_typ[fc];
1612*22dc650dSSadaf Ebrahimi
1613*22dc650dSSadaf Ebrahimi /* Common code for all repeated single-character non-matches. */
1614*22dc650dSSadaf Ebrahimi
1615*22dc650dSSadaf Ebrahimi REPEATNOTCHAR:
1616*22dc650dSSadaf Ebrahimi GETCHARINCTEST(Lc, Fecode);
1617*22dc650dSSadaf Ebrahimi
1618*22dc650dSSadaf Ebrahimi /* The code is duplicated for the caseless and caseful cases, for speed,
1619*22dc650dSSadaf Ebrahimi since matching characters is likely to be quite common. First, ensure the
1620*22dc650dSSadaf Ebrahimi minimum number of matches are present. If Lmin = Lmax, we are done.
1621*22dc650dSSadaf Ebrahimi Otherwise, if minimizing, keep trying the rest of the expression and
1622*22dc650dSSadaf Ebrahimi advancing one matching character if failing, up to the maximum.
1623*22dc650dSSadaf Ebrahimi Alternatively, if maximizing, find the maximum number of characters and
1624*22dc650dSSadaf Ebrahimi work backwards. */
1625*22dc650dSSadaf Ebrahimi
1626*22dc650dSSadaf Ebrahimi if (Fop >= OP_NOTSTARI) /* Caseless */
1627*22dc650dSSadaf Ebrahimi {
1628*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_UNICODE
1629*22dc650dSSadaf Ebrahimi if ((utf || ucp) && Lc > 127)
1630*22dc650dSSadaf Ebrahimi Loc = UCD_OTHERCASE(Lc);
1631*22dc650dSSadaf Ebrahimi else
1632*22dc650dSSadaf Ebrahimi #endif /* SUPPORT_UNICODE */
1633*22dc650dSSadaf Ebrahimi
1634*22dc650dSSadaf Ebrahimi Loc = TABLE_GET(Lc, mb->fcc, Lc); /* Other case from table */
1635*22dc650dSSadaf Ebrahimi
1636*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_UNICODE
1637*22dc650dSSadaf Ebrahimi if (utf)
1638*22dc650dSSadaf Ebrahimi {
1639*22dc650dSSadaf Ebrahimi uint32_t d;
1640*22dc650dSSadaf Ebrahimi for (i = 1; i <= Lmin; i++)
1641*22dc650dSSadaf Ebrahimi {
1642*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
1643*22dc650dSSadaf Ebrahimi {
1644*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
1645*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
1646*22dc650dSSadaf Ebrahimi }
1647*22dc650dSSadaf Ebrahimi GETCHARINC(d, Feptr);
1648*22dc650dSSadaf Ebrahimi if (Lc == d || Loc == d) RRETURN(MATCH_NOMATCH);
1649*22dc650dSSadaf Ebrahimi }
1650*22dc650dSSadaf Ebrahimi }
1651*22dc650dSSadaf Ebrahimi else
1652*22dc650dSSadaf Ebrahimi #endif /* SUPPORT_UNICODE */
1653*22dc650dSSadaf Ebrahimi
1654*22dc650dSSadaf Ebrahimi /* Not UTF mode */
1655*22dc650dSSadaf Ebrahimi {
1656*22dc650dSSadaf Ebrahimi for (i = 1; i <= Lmin; i++)
1657*22dc650dSSadaf Ebrahimi {
1658*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
1659*22dc650dSSadaf Ebrahimi {
1660*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
1661*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
1662*22dc650dSSadaf Ebrahimi }
1663*22dc650dSSadaf Ebrahimi if (Lc == *Feptr || Loc == *Feptr) RRETURN(MATCH_NOMATCH);
1664*22dc650dSSadaf Ebrahimi Feptr++;
1665*22dc650dSSadaf Ebrahimi }
1666*22dc650dSSadaf Ebrahimi }
1667*22dc650dSSadaf Ebrahimi
1668*22dc650dSSadaf Ebrahimi if (Lmin == Lmax) continue; /* Finished for exact count */
1669*22dc650dSSadaf Ebrahimi
1670*22dc650dSSadaf Ebrahimi if (reptype == REPTYPE_MIN)
1671*22dc650dSSadaf Ebrahimi {
1672*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_UNICODE
1673*22dc650dSSadaf Ebrahimi if (utf)
1674*22dc650dSSadaf Ebrahimi {
1675*22dc650dSSadaf Ebrahimi uint32_t d;
1676*22dc650dSSadaf Ebrahimi for (;;)
1677*22dc650dSSadaf Ebrahimi {
1678*22dc650dSSadaf Ebrahimi RMATCH(Fecode, RM204);
1679*22dc650dSSadaf Ebrahimi if (rrc != MATCH_NOMATCH) RRETURN(rrc);
1680*22dc650dSSadaf Ebrahimi if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH);
1681*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
1682*22dc650dSSadaf Ebrahimi {
1683*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
1684*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
1685*22dc650dSSadaf Ebrahimi }
1686*22dc650dSSadaf Ebrahimi GETCHARINC(d, Feptr);
1687*22dc650dSSadaf Ebrahimi if (Lc == d || Loc == d) RRETURN(MATCH_NOMATCH);
1688*22dc650dSSadaf Ebrahimi }
1689*22dc650dSSadaf Ebrahimi }
1690*22dc650dSSadaf Ebrahimi else
1691*22dc650dSSadaf Ebrahimi #endif /*SUPPORT_UNICODE */
1692*22dc650dSSadaf Ebrahimi
1693*22dc650dSSadaf Ebrahimi /* Not UTF mode */
1694*22dc650dSSadaf Ebrahimi {
1695*22dc650dSSadaf Ebrahimi for (;;)
1696*22dc650dSSadaf Ebrahimi {
1697*22dc650dSSadaf Ebrahimi RMATCH(Fecode, RM29);
1698*22dc650dSSadaf Ebrahimi if (rrc != MATCH_NOMATCH) RRETURN(rrc);
1699*22dc650dSSadaf Ebrahimi if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH);
1700*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
1701*22dc650dSSadaf Ebrahimi {
1702*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
1703*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
1704*22dc650dSSadaf Ebrahimi }
1705*22dc650dSSadaf Ebrahimi if (Lc == *Feptr || Loc == *Feptr) RRETURN(MATCH_NOMATCH);
1706*22dc650dSSadaf Ebrahimi Feptr++;
1707*22dc650dSSadaf Ebrahimi }
1708*22dc650dSSadaf Ebrahimi }
1709*22dc650dSSadaf Ebrahimi /* Control never gets here */
1710*22dc650dSSadaf Ebrahimi }
1711*22dc650dSSadaf Ebrahimi
1712*22dc650dSSadaf Ebrahimi /* Maximize case */
1713*22dc650dSSadaf Ebrahimi
1714*22dc650dSSadaf Ebrahimi else
1715*22dc650dSSadaf Ebrahimi {
1716*22dc650dSSadaf Ebrahimi Lstart_eptr = Feptr;
1717*22dc650dSSadaf Ebrahimi
1718*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_UNICODE
1719*22dc650dSSadaf Ebrahimi if (utf)
1720*22dc650dSSadaf Ebrahimi {
1721*22dc650dSSadaf Ebrahimi uint32_t d;
1722*22dc650dSSadaf Ebrahimi for (i = Lmin; i < Lmax; i++)
1723*22dc650dSSadaf Ebrahimi {
1724*22dc650dSSadaf Ebrahimi int len = 1;
1725*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
1726*22dc650dSSadaf Ebrahimi {
1727*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
1728*22dc650dSSadaf Ebrahimi break;
1729*22dc650dSSadaf Ebrahimi }
1730*22dc650dSSadaf Ebrahimi GETCHARLEN(d, Feptr, len);
1731*22dc650dSSadaf Ebrahimi if (Lc == d || Loc == d) break;
1732*22dc650dSSadaf Ebrahimi Feptr += len;
1733*22dc650dSSadaf Ebrahimi }
1734*22dc650dSSadaf Ebrahimi
1735*22dc650dSSadaf Ebrahimi /* After \C in UTF mode, Lstart_eptr might be in the middle of a
1736*22dc650dSSadaf Ebrahimi Unicode character. Use <= Lstart_eptr to ensure backtracking doesn't
1737*22dc650dSSadaf Ebrahimi go too far. */
1738*22dc650dSSadaf Ebrahimi
1739*22dc650dSSadaf Ebrahimi if (reptype != REPTYPE_POS) for(;;)
1740*22dc650dSSadaf Ebrahimi {
1741*22dc650dSSadaf Ebrahimi if (Feptr <= Lstart_eptr) break;
1742*22dc650dSSadaf Ebrahimi RMATCH(Fecode, RM205);
1743*22dc650dSSadaf Ebrahimi if (rrc != MATCH_NOMATCH) RRETURN(rrc);
1744*22dc650dSSadaf Ebrahimi Feptr--;
1745*22dc650dSSadaf Ebrahimi BACKCHAR(Feptr);
1746*22dc650dSSadaf Ebrahimi }
1747*22dc650dSSadaf Ebrahimi }
1748*22dc650dSSadaf Ebrahimi else
1749*22dc650dSSadaf Ebrahimi #endif /* SUPPORT_UNICODE */
1750*22dc650dSSadaf Ebrahimi
1751*22dc650dSSadaf Ebrahimi /* Not UTF mode */
1752*22dc650dSSadaf Ebrahimi {
1753*22dc650dSSadaf Ebrahimi for (i = Lmin; i < Lmax; i++)
1754*22dc650dSSadaf Ebrahimi {
1755*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
1756*22dc650dSSadaf Ebrahimi {
1757*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
1758*22dc650dSSadaf Ebrahimi break;
1759*22dc650dSSadaf Ebrahimi }
1760*22dc650dSSadaf Ebrahimi if (Lc == *Feptr || Loc == *Feptr) break;
1761*22dc650dSSadaf Ebrahimi Feptr++;
1762*22dc650dSSadaf Ebrahimi }
1763*22dc650dSSadaf Ebrahimi if (reptype != REPTYPE_POS) for (;;)
1764*22dc650dSSadaf Ebrahimi {
1765*22dc650dSSadaf Ebrahimi if (Feptr == Lstart_eptr) break;
1766*22dc650dSSadaf Ebrahimi RMATCH(Fecode, RM30);
1767*22dc650dSSadaf Ebrahimi if (rrc != MATCH_NOMATCH) RRETURN(rrc);
1768*22dc650dSSadaf Ebrahimi Feptr--;
1769*22dc650dSSadaf Ebrahimi }
1770*22dc650dSSadaf Ebrahimi }
1771*22dc650dSSadaf Ebrahimi }
1772*22dc650dSSadaf Ebrahimi }
1773*22dc650dSSadaf Ebrahimi
1774*22dc650dSSadaf Ebrahimi /* Caseful comparisons */
1775*22dc650dSSadaf Ebrahimi
1776*22dc650dSSadaf Ebrahimi else
1777*22dc650dSSadaf Ebrahimi {
1778*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_UNICODE
1779*22dc650dSSadaf Ebrahimi if (utf)
1780*22dc650dSSadaf Ebrahimi {
1781*22dc650dSSadaf Ebrahimi uint32_t d;
1782*22dc650dSSadaf Ebrahimi for (i = 1; i <= Lmin; i++)
1783*22dc650dSSadaf Ebrahimi {
1784*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
1785*22dc650dSSadaf Ebrahimi {
1786*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
1787*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
1788*22dc650dSSadaf Ebrahimi }
1789*22dc650dSSadaf Ebrahimi GETCHARINC(d, Feptr);
1790*22dc650dSSadaf Ebrahimi if (Lc == d) RRETURN(MATCH_NOMATCH);
1791*22dc650dSSadaf Ebrahimi }
1792*22dc650dSSadaf Ebrahimi }
1793*22dc650dSSadaf Ebrahimi else
1794*22dc650dSSadaf Ebrahimi #endif
1795*22dc650dSSadaf Ebrahimi /* Not UTF mode */
1796*22dc650dSSadaf Ebrahimi {
1797*22dc650dSSadaf Ebrahimi for (i = 1; i <= Lmin; i++)
1798*22dc650dSSadaf Ebrahimi {
1799*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
1800*22dc650dSSadaf Ebrahimi {
1801*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
1802*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
1803*22dc650dSSadaf Ebrahimi }
1804*22dc650dSSadaf Ebrahimi if (Lc == *Feptr++) RRETURN(MATCH_NOMATCH);
1805*22dc650dSSadaf Ebrahimi }
1806*22dc650dSSadaf Ebrahimi }
1807*22dc650dSSadaf Ebrahimi
1808*22dc650dSSadaf Ebrahimi if (Lmin == Lmax) continue;
1809*22dc650dSSadaf Ebrahimi
1810*22dc650dSSadaf Ebrahimi if (reptype == REPTYPE_MIN)
1811*22dc650dSSadaf Ebrahimi {
1812*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_UNICODE
1813*22dc650dSSadaf Ebrahimi if (utf)
1814*22dc650dSSadaf Ebrahimi {
1815*22dc650dSSadaf Ebrahimi uint32_t d;
1816*22dc650dSSadaf Ebrahimi for (;;)
1817*22dc650dSSadaf Ebrahimi {
1818*22dc650dSSadaf Ebrahimi RMATCH(Fecode, RM206);
1819*22dc650dSSadaf Ebrahimi if (rrc != MATCH_NOMATCH) RRETURN(rrc);
1820*22dc650dSSadaf Ebrahimi if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH);
1821*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
1822*22dc650dSSadaf Ebrahimi {
1823*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
1824*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
1825*22dc650dSSadaf Ebrahimi }
1826*22dc650dSSadaf Ebrahimi GETCHARINC(d, Feptr);
1827*22dc650dSSadaf Ebrahimi if (Lc == d) RRETURN(MATCH_NOMATCH);
1828*22dc650dSSadaf Ebrahimi }
1829*22dc650dSSadaf Ebrahimi }
1830*22dc650dSSadaf Ebrahimi else
1831*22dc650dSSadaf Ebrahimi #endif
1832*22dc650dSSadaf Ebrahimi /* Not UTF mode */
1833*22dc650dSSadaf Ebrahimi {
1834*22dc650dSSadaf Ebrahimi for (;;)
1835*22dc650dSSadaf Ebrahimi {
1836*22dc650dSSadaf Ebrahimi RMATCH(Fecode, RM31);
1837*22dc650dSSadaf Ebrahimi if (rrc != MATCH_NOMATCH) RRETURN(rrc);
1838*22dc650dSSadaf Ebrahimi if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH);
1839*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
1840*22dc650dSSadaf Ebrahimi {
1841*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
1842*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
1843*22dc650dSSadaf Ebrahimi }
1844*22dc650dSSadaf Ebrahimi if (Lc == *Feptr++) RRETURN(MATCH_NOMATCH);
1845*22dc650dSSadaf Ebrahimi }
1846*22dc650dSSadaf Ebrahimi }
1847*22dc650dSSadaf Ebrahimi /* Control never gets here */
1848*22dc650dSSadaf Ebrahimi }
1849*22dc650dSSadaf Ebrahimi
1850*22dc650dSSadaf Ebrahimi /* Maximize case */
1851*22dc650dSSadaf Ebrahimi
1852*22dc650dSSadaf Ebrahimi else
1853*22dc650dSSadaf Ebrahimi {
1854*22dc650dSSadaf Ebrahimi Lstart_eptr = Feptr;
1855*22dc650dSSadaf Ebrahimi
1856*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_UNICODE
1857*22dc650dSSadaf Ebrahimi if (utf)
1858*22dc650dSSadaf Ebrahimi {
1859*22dc650dSSadaf Ebrahimi uint32_t d;
1860*22dc650dSSadaf Ebrahimi for (i = Lmin; i < Lmax; i++)
1861*22dc650dSSadaf Ebrahimi {
1862*22dc650dSSadaf Ebrahimi int len = 1;
1863*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
1864*22dc650dSSadaf Ebrahimi {
1865*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
1866*22dc650dSSadaf Ebrahimi break;
1867*22dc650dSSadaf Ebrahimi }
1868*22dc650dSSadaf Ebrahimi GETCHARLEN(d, Feptr, len);
1869*22dc650dSSadaf Ebrahimi if (Lc == d) break;
1870*22dc650dSSadaf Ebrahimi Feptr += len;
1871*22dc650dSSadaf Ebrahimi }
1872*22dc650dSSadaf Ebrahimi
1873*22dc650dSSadaf Ebrahimi /* After \C in UTF mode, Lstart_eptr might be in the middle of a
1874*22dc650dSSadaf Ebrahimi Unicode character. Use <= Lstart_eptr to ensure backtracking doesn't
1875*22dc650dSSadaf Ebrahimi go too far. */
1876*22dc650dSSadaf Ebrahimi
1877*22dc650dSSadaf Ebrahimi if (reptype != REPTYPE_POS) for(;;)
1878*22dc650dSSadaf Ebrahimi {
1879*22dc650dSSadaf Ebrahimi if (Feptr <= Lstart_eptr) break;
1880*22dc650dSSadaf Ebrahimi RMATCH(Fecode, RM207);
1881*22dc650dSSadaf Ebrahimi if (rrc != MATCH_NOMATCH) RRETURN(rrc);
1882*22dc650dSSadaf Ebrahimi Feptr--;
1883*22dc650dSSadaf Ebrahimi BACKCHAR(Feptr);
1884*22dc650dSSadaf Ebrahimi }
1885*22dc650dSSadaf Ebrahimi }
1886*22dc650dSSadaf Ebrahimi else
1887*22dc650dSSadaf Ebrahimi #endif
1888*22dc650dSSadaf Ebrahimi /* Not UTF mode */
1889*22dc650dSSadaf Ebrahimi {
1890*22dc650dSSadaf Ebrahimi for (i = Lmin; i < Lmax; i++)
1891*22dc650dSSadaf Ebrahimi {
1892*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
1893*22dc650dSSadaf Ebrahimi {
1894*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
1895*22dc650dSSadaf Ebrahimi break;
1896*22dc650dSSadaf Ebrahimi }
1897*22dc650dSSadaf Ebrahimi if (Lc == *Feptr) break;
1898*22dc650dSSadaf Ebrahimi Feptr++;
1899*22dc650dSSadaf Ebrahimi }
1900*22dc650dSSadaf Ebrahimi if (reptype != REPTYPE_POS) for (;;)
1901*22dc650dSSadaf Ebrahimi {
1902*22dc650dSSadaf Ebrahimi if (Feptr == Lstart_eptr) break;
1903*22dc650dSSadaf Ebrahimi RMATCH(Fecode, RM32);
1904*22dc650dSSadaf Ebrahimi if (rrc != MATCH_NOMATCH) RRETURN(rrc);
1905*22dc650dSSadaf Ebrahimi Feptr--;
1906*22dc650dSSadaf Ebrahimi }
1907*22dc650dSSadaf Ebrahimi }
1908*22dc650dSSadaf Ebrahimi }
1909*22dc650dSSadaf Ebrahimi }
1910*22dc650dSSadaf Ebrahimi break;
1911*22dc650dSSadaf Ebrahimi
1912*22dc650dSSadaf Ebrahimi #undef Lstart_eptr
1913*22dc650dSSadaf Ebrahimi #undef Lmin
1914*22dc650dSSadaf Ebrahimi #undef Lmax
1915*22dc650dSSadaf Ebrahimi #undef Lc
1916*22dc650dSSadaf Ebrahimi #undef Loc
1917*22dc650dSSadaf Ebrahimi
1918*22dc650dSSadaf Ebrahimi
1919*22dc650dSSadaf Ebrahimi /* ===================================================================== */
1920*22dc650dSSadaf Ebrahimi /* Match a bit-mapped character class, possibly repeatedly. These opcodes
1921*22dc650dSSadaf Ebrahimi are used when all the characters in the class have values in the range
1922*22dc650dSSadaf Ebrahimi 0-255, and either the matching is caseful, or the characters are in the
1923*22dc650dSSadaf Ebrahimi range 0-127 when UTF processing is enabled. The only difference between
1924*22dc650dSSadaf Ebrahimi OP_CLASS and OP_NCLASS occurs when a data character outside the range is
1925*22dc650dSSadaf Ebrahimi encountered. */
1926*22dc650dSSadaf Ebrahimi
1927*22dc650dSSadaf Ebrahimi #define Lmin F->temp_32[0]
1928*22dc650dSSadaf Ebrahimi #define Lmax F->temp_32[1]
1929*22dc650dSSadaf Ebrahimi #define Lstart_eptr F->temp_sptr[0]
1930*22dc650dSSadaf Ebrahimi #define Lbyte_map_address F->temp_sptr[1]
1931*22dc650dSSadaf Ebrahimi #define Lbyte_map ((unsigned char *)Lbyte_map_address)
1932*22dc650dSSadaf Ebrahimi
1933*22dc650dSSadaf Ebrahimi case OP_NCLASS:
1934*22dc650dSSadaf Ebrahimi case OP_CLASS:
1935*22dc650dSSadaf Ebrahimi {
1936*22dc650dSSadaf Ebrahimi Lbyte_map_address = Fecode + 1; /* Save for matching */
1937*22dc650dSSadaf Ebrahimi Fecode += 1 + (32 / sizeof(PCRE2_UCHAR)); /* Advance past the item */
1938*22dc650dSSadaf Ebrahimi
1939*22dc650dSSadaf Ebrahimi /* Look past the end of the item to see if there is repeat information
1940*22dc650dSSadaf Ebrahimi following. Then obey similar code to character type repeats. */
1941*22dc650dSSadaf Ebrahimi
1942*22dc650dSSadaf Ebrahimi switch (*Fecode)
1943*22dc650dSSadaf Ebrahimi {
1944*22dc650dSSadaf Ebrahimi case OP_CRSTAR:
1945*22dc650dSSadaf Ebrahimi case OP_CRMINSTAR:
1946*22dc650dSSadaf Ebrahimi case OP_CRPLUS:
1947*22dc650dSSadaf Ebrahimi case OP_CRMINPLUS:
1948*22dc650dSSadaf Ebrahimi case OP_CRQUERY:
1949*22dc650dSSadaf Ebrahimi case OP_CRMINQUERY:
1950*22dc650dSSadaf Ebrahimi case OP_CRPOSSTAR:
1951*22dc650dSSadaf Ebrahimi case OP_CRPOSPLUS:
1952*22dc650dSSadaf Ebrahimi case OP_CRPOSQUERY:
1953*22dc650dSSadaf Ebrahimi fc = *Fecode++ - OP_CRSTAR;
1954*22dc650dSSadaf Ebrahimi Lmin = rep_min[fc];
1955*22dc650dSSadaf Ebrahimi Lmax = rep_max[fc];
1956*22dc650dSSadaf Ebrahimi reptype = rep_typ[fc];
1957*22dc650dSSadaf Ebrahimi break;
1958*22dc650dSSadaf Ebrahimi
1959*22dc650dSSadaf Ebrahimi case OP_CRRANGE:
1960*22dc650dSSadaf Ebrahimi case OP_CRMINRANGE:
1961*22dc650dSSadaf Ebrahimi case OP_CRPOSRANGE:
1962*22dc650dSSadaf Ebrahimi Lmin = GET2(Fecode, 1);
1963*22dc650dSSadaf Ebrahimi Lmax = GET2(Fecode, 1 + IMM2_SIZE);
1964*22dc650dSSadaf Ebrahimi if (Lmax == 0) Lmax = UINT32_MAX; /* Max 0 => infinity */
1965*22dc650dSSadaf Ebrahimi reptype = rep_typ[*Fecode - OP_CRSTAR];
1966*22dc650dSSadaf Ebrahimi Fecode += 1 + 2 * IMM2_SIZE;
1967*22dc650dSSadaf Ebrahimi break;
1968*22dc650dSSadaf Ebrahimi
1969*22dc650dSSadaf Ebrahimi default: /* No repeat follows */
1970*22dc650dSSadaf Ebrahimi Lmin = Lmax = 1;
1971*22dc650dSSadaf Ebrahimi break;
1972*22dc650dSSadaf Ebrahimi }
1973*22dc650dSSadaf Ebrahimi
1974*22dc650dSSadaf Ebrahimi /* First, ensure the minimum number of matches are present. */
1975*22dc650dSSadaf Ebrahimi
1976*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_UNICODE
1977*22dc650dSSadaf Ebrahimi if (utf)
1978*22dc650dSSadaf Ebrahimi {
1979*22dc650dSSadaf Ebrahimi for (i = 1; i <= Lmin; i++)
1980*22dc650dSSadaf Ebrahimi {
1981*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
1982*22dc650dSSadaf Ebrahimi {
1983*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
1984*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
1985*22dc650dSSadaf Ebrahimi }
1986*22dc650dSSadaf Ebrahimi GETCHARINC(fc, Feptr);
1987*22dc650dSSadaf Ebrahimi if (fc > 255)
1988*22dc650dSSadaf Ebrahimi {
1989*22dc650dSSadaf Ebrahimi if (Fop == OP_CLASS) RRETURN(MATCH_NOMATCH);
1990*22dc650dSSadaf Ebrahimi }
1991*22dc650dSSadaf Ebrahimi else
1992*22dc650dSSadaf Ebrahimi if ((Lbyte_map[fc/8] & (1u << (fc&7))) == 0) RRETURN(MATCH_NOMATCH);
1993*22dc650dSSadaf Ebrahimi }
1994*22dc650dSSadaf Ebrahimi }
1995*22dc650dSSadaf Ebrahimi else
1996*22dc650dSSadaf Ebrahimi #endif
1997*22dc650dSSadaf Ebrahimi /* Not UTF mode */
1998*22dc650dSSadaf Ebrahimi {
1999*22dc650dSSadaf Ebrahimi for (i = 1; i <= Lmin; i++)
2000*22dc650dSSadaf Ebrahimi {
2001*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
2002*22dc650dSSadaf Ebrahimi {
2003*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
2004*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
2005*22dc650dSSadaf Ebrahimi }
2006*22dc650dSSadaf Ebrahimi fc = *Feptr++;
2007*22dc650dSSadaf Ebrahimi #if PCRE2_CODE_UNIT_WIDTH != 8
2008*22dc650dSSadaf Ebrahimi if (fc > 255)
2009*22dc650dSSadaf Ebrahimi {
2010*22dc650dSSadaf Ebrahimi if (Fop == OP_CLASS) RRETURN(MATCH_NOMATCH);
2011*22dc650dSSadaf Ebrahimi }
2012*22dc650dSSadaf Ebrahimi else
2013*22dc650dSSadaf Ebrahimi #endif
2014*22dc650dSSadaf Ebrahimi if ((Lbyte_map[fc/8] & (1u << (fc&7))) == 0) RRETURN(MATCH_NOMATCH);
2015*22dc650dSSadaf Ebrahimi }
2016*22dc650dSSadaf Ebrahimi }
2017*22dc650dSSadaf Ebrahimi
2018*22dc650dSSadaf Ebrahimi /* If Lmax == Lmin we are done. Continue with main loop. */
2019*22dc650dSSadaf Ebrahimi
2020*22dc650dSSadaf Ebrahimi if (Lmin == Lmax) continue;
2021*22dc650dSSadaf Ebrahimi
2022*22dc650dSSadaf Ebrahimi /* If minimizing, keep testing the rest of the expression and advancing
2023*22dc650dSSadaf Ebrahimi the pointer while it matches the class. */
2024*22dc650dSSadaf Ebrahimi
2025*22dc650dSSadaf Ebrahimi if (reptype == REPTYPE_MIN)
2026*22dc650dSSadaf Ebrahimi {
2027*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_UNICODE
2028*22dc650dSSadaf Ebrahimi if (utf)
2029*22dc650dSSadaf Ebrahimi {
2030*22dc650dSSadaf Ebrahimi for (;;)
2031*22dc650dSSadaf Ebrahimi {
2032*22dc650dSSadaf Ebrahimi RMATCH(Fecode, RM200);
2033*22dc650dSSadaf Ebrahimi if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2034*22dc650dSSadaf Ebrahimi if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH);
2035*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
2036*22dc650dSSadaf Ebrahimi {
2037*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
2038*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
2039*22dc650dSSadaf Ebrahimi }
2040*22dc650dSSadaf Ebrahimi GETCHARINC(fc, Feptr);
2041*22dc650dSSadaf Ebrahimi if (fc > 255)
2042*22dc650dSSadaf Ebrahimi {
2043*22dc650dSSadaf Ebrahimi if (Fop == OP_CLASS) RRETURN(MATCH_NOMATCH);
2044*22dc650dSSadaf Ebrahimi }
2045*22dc650dSSadaf Ebrahimi else
2046*22dc650dSSadaf Ebrahimi if ((Lbyte_map[fc/8] & (1u << (fc&7))) == 0) RRETURN(MATCH_NOMATCH);
2047*22dc650dSSadaf Ebrahimi }
2048*22dc650dSSadaf Ebrahimi }
2049*22dc650dSSadaf Ebrahimi else
2050*22dc650dSSadaf Ebrahimi #endif
2051*22dc650dSSadaf Ebrahimi /* Not UTF mode */
2052*22dc650dSSadaf Ebrahimi {
2053*22dc650dSSadaf Ebrahimi for (;;)
2054*22dc650dSSadaf Ebrahimi {
2055*22dc650dSSadaf Ebrahimi RMATCH(Fecode, RM23);
2056*22dc650dSSadaf Ebrahimi if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2057*22dc650dSSadaf Ebrahimi if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH);
2058*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
2059*22dc650dSSadaf Ebrahimi {
2060*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
2061*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
2062*22dc650dSSadaf Ebrahimi }
2063*22dc650dSSadaf Ebrahimi fc = *Feptr++;
2064*22dc650dSSadaf Ebrahimi #if PCRE2_CODE_UNIT_WIDTH != 8
2065*22dc650dSSadaf Ebrahimi if (fc > 255)
2066*22dc650dSSadaf Ebrahimi {
2067*22dc650dSSadaf Ebrahimi if (Fop == OP_CLASS) RRETURN(MATCH_NOMATCH);
2068*22dc650dSSadaf Ebrahimi }
2069*22dc650dSSadaf Ebrahimi else
2070*22dc650dSSadaf Ebrahimi #endif
2071*22dc650dSSadaf Ebrahimi if ((Lbyte_map[fc/8] & (1u << (fc&7))) == 0) RRETURN(MATCH_NOMATCH);
2072*22dc650dSSadaf Ebrahimi }
2073*22dc650dSSadaf Ebrahimi }
2074*22dc650dSSadaf Ebrahimi /* Control never gets here */
2075*22dc650dSSadaf Ebrahimi }
2076*22dc650dSSadaf Ebrahimi
2077*22dc650dSSadaf Ebrahimi /* If maximizing, find the longest possible run, then work backwards. */
2078*22dc650dSSadaf Ebrahimi
2079*22dc650dSSadaf Ebrahimi else
2080*22dc650dSSadaf Ebrahimi {
2081*22dc650dSSadaf Ebrahimi Lstart_eptr = Feptr;
2082*22dc650dSSadaf Ebrahimi
2083*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_UNICODE
2084*22dc650dSSadaf Ebrahimi if (utf)
2085*22dc650dSSadaf Ebrahimi {
2086*22dc650dSSadaf Ebrahimi for (i = Lmin; i < Lmax; i++)
2087*22dc650dSSadaf Ebrahimi {
2088*22dc650dSSadaf Ebrahimi int len = 1;
2089*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
2090*22dc650dSSadaf Ebrahimi {
2091*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
2092*22dc650dSSadaf Ebrahimi break;
2093*22dc650dSSadaf Ebrahimi }
2094*22dc650dSSadaf Ebrahimi GETCHARLEN(fc, Feptr, len);
2095*22dc650dSSadaf Ebrahimi if (fc > 255)
2096*22dc650dSSadaf Ebrahimi {
2097*22dc650dSSadaf Ebrahimi if (Fop == OP_CLASS) break;
2098*22dc650dSSadaf Ebrahimi }
2099*22dc650dSSadaf Ebrahimi else
2100*22dc650dSSadaf Ebrahimi if ((Lbyte_map[fc/8] & (1u << (fc&7))) == 0) break;
2101*22dc650dSSadaf Ebrahimi Feptr += len;
2102*22dc650dSSadaf Ebrahimi }
2103*22dc650dSSadaf Ebrahimi
2104*22dc650dSSadaf Ebrahimi if (reptype == REPTYPE_POS) continue; /* No backtracking */
2105*22dc650dSSadaf Ebrahimi
2106*22dc650dSSadaf Ebrahimi /* After \C in UTF mode, Lstart_eptr might be in the middle of a
2107*22dc650dSSadaf Ebrahimi Unicode character. Use <= Lstart_eptr to ensure backtracking doesn't
2108*22dc650dSSadaf Ebrahimi go too far. */
2109*22dc650dSSadaf Ebrahimi
2110*22dc650dSSadaf Ebrahimi for (;;)
2111*22dc650dSSadaf Ebrahimi {
2112*22dc650dSSadaf Ebrahimi RMATCH(Fecode, RM201);
2113*22dc650dSSadaf Ebrahimi if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2114*22dc650dSSadaf Ebrahimi if (Feptr-- <= Lstart_eptr) break; /* Tried at original position */
2115*22dc650dSSadaf Ebrahimi BACKCHAR(Feptr);
2116*22dc650dSSadaf Ebrahimi }
2117*22dc650dSSadaf Ebrahimi }
2118*22dc650dSSadaf Ebrahimi else
2119*22dc650dSSadaf Ebrahimi #endif
2120*22dc650dSSadaf Ebrahimi /* Not UTF mode */
2121*22dc650dSSadaf Ebrahimi {
2122*22dc650dSSadaf Ebrahimi for (i = Lmin; i < Lmax; i++)
2123*22dc650dSSadaf Ebrahimi {
2124*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
2125*22dc650dSSadaf Ebrahimi {
2126*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
2127*22dc650dSSadaf Ebrahimi break;
2128*22dc650dSSadaf Ebrahimi }
2129*22dc650dSSadaf Ebrahimi fc = *Feptr;
2130*22dc650dSSadaf Ebrahimi #if PCRE2_CODE_UNIT_WIDTH != 8
2131*22dc650dSSadaf Ebrahimi if (fc > 255)
2132*22dc650dSSadaf Ebrahimi {
2133*22dc650dSSadaf Ebrahimi if (Fop == OP_CLASS) break;
2134*22dc650dSSadaf Ebrahimi }
2135*22dc650dSSadaf Ebrahimi else
2136*22dc650dSSadaf Ebrahimi #endif
2137*22dc650dSSadaf Ebrahimi if ((Lbyte_map[fc/8] & (1u << (fc&7))) == 0) break;
2138*22dc650dSSadaf Ebrahimi Feptr++;
2139*22dc650dSSadaf Ebrahimi }
2140*22dc650dSSadaf Ebrahimi
2141*22dc650dSSadaf Ebrahimi if (reptype == REPTYPE_POS) continue; /* No backtracking */
2142*22dc650dSSadaf Ebrahimi
2143*22dc650dSSadaf Ebrahimi while (Feptr >= Lstart_eptr)
2144*22dc650dSSadaf Ebrahimi {
2145*22dc650dSSadaf Ebrahimi RMATCH(Fecode, RM24);
2146*22dc650dSSadaf Ebrahimi if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2147*22dc650dSSadaf Ebrahimi Feptr--;
2148*22dc650dSSadaf Ebrahimi }
2149*22dc650dSSadaf Ebrahimi }
2150*22dc650dSSadaf Ebrahimi
2151*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
2152*22dc650dSSadaf Ebrahimi }
2153*22dc650dSSadaf Ebrahimi }
2154*22dc650dSSadaf Ebrahimi /* Control never gets here */
2155*22dc650dSSadaf Ebrahimi
2156*22dc650dSSadaf Ebrahimi #undef Lbyte_map_address
2157*22dc650dSSadaf Ebrahimi #undef Lbyte_map
2158*22dc650dSSadaf Ebrahimi #undef Lstart_eptr
2159*22dc650dSSadaf Ebrahimi #undef Lmin
2160*22dc650dSSadaf Ebrahimi #undef Lmax
2161*22dc650dSSadaf Ebrahimi
2162*22dc650dSSadaf Ebrahimi
2163*22dc650dSSadaf Ebrahimi /* ===================================================================== */
2164*22dc650dSSadaf Ebrahimi /* Match an extended character class. In the 8-bit library, this opcode is
2165*22dc650dSSadaf Ebrahimi encountered only when UTF-8 mode mode is supported. In the 16-bit and
2166*22dc650dSSadaf Ebrahimi 32-bit libraries, codepoints greater than 255 may be encountered even when
2167*22dc650dSSadaf Ebrahimi UTF is not supported. */
2168*22dc650dSSadaf Ebrahimi
2169*22dc650dSSadaf Ebrahimi #define Lstart_eptr F->temp_sptr[0]
2170*22dc650dSSadaf Ebrahimi #define Lxclass_data F->temp_sptr[1]
2171*22dc650dSSadaf Ebrahimi #define Lmin F->temp_32[0]
2172*22dc650dSSadaf Ebrahimi #define Lmax F->temp_32[1]
2173*22dc650dSSadaf Ebrahimi
2174*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_WIDE_CHARS
2175*22dc650dSSadaf Ebrahimi case OP_XCLASS:
2176*22dc650dSSadaf Ebrahimi {
2177*22dc650dSSadaf Ebrahimi Lxclass_data = Fecode + 1 + LINK_SIZE; /* Save for matching */
2178*22dc650dSSadaf Ebrahimi Fecode += GET(Fecode, 1); /* Advance past the item */
2179*22dc650dSSadaf Ebrahimi
2180*22dc650dSSadaf Ebrahimi switch (*Fecode)
2181*22dc650dSSadaf Ebrahimi {
2182*22dc650dSSadaf Ebrahimi case OP_CRSTAR:
2183*22dc650dSSadaf Ebrahimi case OP_CRMINSTAR:
2184*22dc650dSSadaf Ebrahimi case OP_CRPLUS:
2185*22dc650dSSadaf Ebrahimi case OP_CRMINPLUS:
2186*22dc650dSSadaf Ebrahimi case OP_CRQUERY:
2187*22dc650dSSadaf Ebrahimi case OP_CRMINQUERY:
2188*22dc650dSSadaf Ebrahimi case OP_CRPOSSTAR:
2189*22dc650dSSadaf Ebrahimi case OP_CRPOSPLUS:
2190*22dc650dSSadaf Ebrahimi case OP_CRPOSQUERY:
2191*22dc650dSSadaf Ebrahimi fc = *Fecode++ - OP_CRSTAR;
2192*22dc650dSSadaf Ebrahimi Lmin = rep_min[fc];
2193*22dc650dSSadaf Ebrahimi Lmax = rep_max[fc];
2194*22dc650dSSadaf Ebrahimi reptype = rep_typ[fc];
2195*22dc650dSSadaf Ebrahimi break;
2196*22dc650dSSadaf Ebrahimi
2197*22dc650dSSadaf Ebrahimi case OP_CRRANGE:
2198*22dc650dSSadaf Ebrahimi case OP_CRMINRANGE:
2199*22dc650dSSadaf Ebrahimi case OP_CRPOSRANGE:
2200*22dc650dSSadaf Ebrahimi Lmin = GET2(Fecode, 1);
2201*22dc650dSSadaf Ebrahimi Lmax = GET2(Fecode, 1 + IMM2_SIZE);
2202*22dc650dSSadaf Ebrahimi if (Lmax == 0) Lmax = UINT32_MAX; /* Max 0 => infinity */
2203*22dc650dSSadaf Ebrahimi reptype = rep_typ[*Fecode - OP_CRSTAR];
2204*22dc650dSSadaf Ebrahimi Fecode += 1 + 2 * IMM2_SIZE;
2205*22dc650dSSadaf Ebrahimi break;
2206*22dc650dSSadaf Ebrahimi
2207*22dc650dSSadaf Ebrahimi default: /* No repeat follows */
2208*22dc650dSSadaf Ebrahimi Lmin = Lmax = 1;
2209*22dc650dSSadaf Ebrahimi break;
2210*22dc650dSSadaf Ebrahimi }
2211*22dc650dSSadaf Ebrahimi
2212*22dc650dSSadaf Ebrahimi /* First, ensure the minimum number of matches are present. */
2213*22dc650dSSadaf Ebrahimi
2214*22dc650dSSadaf Ebrahimi for (i = 1; i <= Lmin; i++)
2215*22dc650dSSadaf Ebrahimi {
2216*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
2217*22dc650dSSadaf Ebrahimi {
2218*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
2219*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
2220*22dc650dSSadaf Ebrahimi }
2221*22dc650dSSadaf Ebrahimi GETCHARINCTEST(fc, Feptr);
2222*22dc650dSSadaf Ebrahimi if (!PRIV(xclass)(fc, Lxclass_data, utf)) RRETURN(MATCH_NOMATCH);
2223*22dc650dSSadaf Ebrahimi }
2224*22dc650dSSadaf Ebrahimi
2225*22dc650dSSadaf Ebrahimi /* If Lmax == Lmin we can just continue with the main loop. */
2226*22dc650dSSadaf Ebrahimi
2227*22dc650dSSadaf Ebrahimi if (Lmin == Lmax) continue;
2228*22dc650dSSadaf Ebrahimi
2229*22dc650dSSadaf Ebrahimi /* If minimizing, keep testing the rest of the expression and advancing
2230*22dc650dSSadaf Ebrahimi the pointer while it matches the class. */
2231*22dc650dSSadaf Ebrahimi
2232*22dc650dSSadaf Ebrahimi if (reptype == REPTYPE_MIN)
2233*22dc650dSSadaf Ebrahimi {
2234*22dc650dSSadaf Ebrahimi for (;;)
2235*22dc650dSSadaf Ebrahimi {
2236*22dc650dSSadaf Ebrahimi RMATCH(Fecode, RM100);
2237*22dc650dSSadaf Ebrahimi if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2238*22dc650dSSadaf Ebrahimi if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH);
2239*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
2240*22dc650dSSadaf Ebrahimi {
2241*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
2242*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
2243*22dc650dSSadaf Ebrahimi }
2244*22dc650dSSadaf Ebrahimi GETCHARINCTEST(fc, Feptr);
2245*22dc650dSSadaf Ebrahimi if (!PRIV(xclass)(fc, Lxclass_data, utf)) RRETURN(MATCH_NOMATCH);
2246*22dc650dSSadaf Ebrahimi }
2247*22dc650dSSadaf Ebrahimi /* Control never gets here */
2248*22dc650dSSadaf Ebrahimi }
2249*22dc650dSSadaf Ebrahimi
2250*22dc650dSSadaf Ebrahimi /* If maximizing, find the longest possible run, then work backwards. */
2251*22dc650dSSadaf Ebrahimi
2252*22dc650dSSadaf Ebrahimi else
2253*22dc650dSSadaf Ebrahimi {
2254*22dc650dSSadaf Ebrahimi Lstart_eptr = Feptr;
2255*22dc650dSSadaf Ebrahimi for (i = Lmin; i < Lmax; i++)
2256*22dc650dSSadaf Ebrahimi {
2257*22dc650dSSadaf Ebrahimi int len = 1;
2258*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
2259*22dc650dSSadaf Ebrahimi {
2260*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
2261*22dc650dSSadaf Ebrahimi break;
2262*22dc650dSSadaf Ebrahimi }
2263*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_UNICODE
2264*22dc650dSSadaf Ebrahimi GETCHARLENTEST(fc, Feptr, len);
2265*22dc650dSSadaf Ebrahimi #else
2266*22dc650dSSadaf Ebrahimi fc = *Feptr;
2267*22dc650dSSadaf Ebrahimi #endif
2268*22dc650dSSadaf Ebrahimi if (!PRIV(xclass)(fc, Lxclass_data, utf)) break;
2269*22dc650dSSadaf Ebrahimi Feptr += len;
2270*22dc650dSSadaf Ebrahimi }
2271*22dc650dSSadaf Ebrahimi
2272*22dc650dSSadaf Ebrahimi if (reptype == REPTYPE_POS) continue; /* No backtracking */
2273*22dc650dSSadaf Ebrahimi
2274*22dc650dSSadaf Ebrahimi /* After \C in UTF mode, Lstart_eptr might be in the middle of a
2275*22dc650dSSadaf Ebrahimi Unicode character. Use <= Lstart_eptr to ensure backtracking doesn't
2276*22dc650dSSadaf Ebrahimi go too far. */
2277*22dc650dSSadaf Ebrahimi
2278*22dc650dSSadaf Ebrahimi for(;;)
2279*22dc650dSSadaf Ebrahimi {
2280*22dc650dSSadaf Ebrahimi RMATCH(Fecode, RM101);
2281*22dc650dSSadaf Ebrahimi if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2282*22dc650dSSadaf Ebrahimi if (Feptr-- <= Lstart_eptr) break; /* Tried at original position */
2283*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_UNICODE
2284*22dc650dSSadaf Ebrahimi if (utf) BACKCHAR(Feptr);
2285*22dc650dSSadaf Ebrahimi #endif
2286*22dc650dSSadaf Ebrahimi }
2287*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
2288*22dc650dSSadaf Ebrahimi }
2289*22dc650dSSadaf Ebrahimi
2290*22dc650dSSadaf Ebrahimi /* Control never gets here */
2291*22dc650dSSadaf Ebrahimi }
2292*22dc650dSSadaf Ebrahimi #endif /* SUPPORT_WIDE_CHARS: end of XCLASS */
2293*22dc650dSSadaf Ebrahimi
2294*22dc650dSSadaf Ebrahimi #undef Lstart_eptr
2295*22dc650dSSadaf Ebrahimi #undef Lxclass_data
2296*22dc650dSSadaf Ebrahimi #undef Lmin
2297*22dc650dSSadaf Ebrahimi #undef Lmax
2298*22dc650dSSadaf Ebrahimi
2299*22dc650dSSadaf Ebrahimi
2300*22dc650dSSadaf Ebrahimi /* ===================================================================== */
2301*22dc650dSSadaf Ebrahimi /* Match various character types when PCRE2_UCP is not set. These opcodes
2302*22dc650dSSadaf Ebrahimi are not generated when PCRE2_UCP is set - instead appropriate property
2303*22dc650dSSadaf Ebrahimi tests are compiled. */
2304*22dc650dSSadaf Ebrahimi
2305*22dc650dSSadaf Ebrahimi case OP_NOT_DIGIT:
2306*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
2307*22dc650dSSadaf Ebrahimi {
2308*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
2309*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
2310*22dc650dSSadaf Ebrahimi }
2311*22dc650dSSadaf Ebrahimi GETCHARINCTEST(fc, Feptr);
2312*22dc650dSSadaf Ebrahimi if (CHMAX_255(fc) && (mb->ctypes[fc] & ctype_digit) != 0)
2313*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
2314*22dc650dSSadaf Ebrahimi Fecode++;
2315*22dc650dSSadaf Ebrahimi break;
2316*22dc650dSSadaf Ebrahimi
2317*22dc650dSSadaf Ebrahimi case OP_DIGIT:
2318*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
2319*22dc650dSSadaf Ebrahimi {
2320*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
2321*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
2322*22dc650dSSadaf Ebrahimi }
2323*22dc650dSSadaf Ebrahimi GETCHARINCTEST(fc, Feptr);
2324*22dc650dSSadaf Ebrahimi if (!CHMAX_255(fc) || (mb->ctypes[fc] & ctype_digit) == 0)
2325*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
2326*22dc650dSSadaf Ebrahimi Fecode++;
2327*22dc650dSSadaf Ebrahimi break;
2328*22dc650dSSadaf Ebrahimi
2329*22dc650dSSadaf Ebrahimi case OP_NOT_WHITESPACE:
2330*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
2331*22dc650dSSadaf Ebrahimi {
2332*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
2333*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
2334*22dc650dSSadaf Ebrahimi }
2335*22dc650dSSadaf Ebrahimi GETCHARINCTEST(fc, Feptr);
2336*22dc650dSSadaf Ebrahimi if (CHMAX_255(fc) && (mb->ctypes[fc] & ctype_space) != 0)
2337*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
2338*22dc650dSSadaf Ebrahimi Fecode++;
2339*22dc650dSSadaf Ebrahimi break;
2340*22dc650dSSadaf Ebrahimi
2341*22dc650dSSadaf Ebrahimi case OP_WHITESPACE:
2342*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
2343*22dc650dSSadaf Ebrahimi {
2344*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
2345*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
2346*22dc650dSSadaf Ebrahimi }
2347*22dc650dSSadaf Ebrahimi GETCHARINCTEST(fc, Feptr);
2348*22dc650dSSadaf Ebrahimi if (!CHMAX_255(fc) || (mb->ctypes[fc] & ctype_space) == 0)
2349*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
2350*22dc650dSSadaf Ebrahimi Fecode++;
2351*22dc650dSSadaf Ebrahimi break;
2352*22dc650dSSadaf Ebrahimi
2353*22dc650dSSadaf Ebrahimi case OP_NOT_WORDCHAR:
2354*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
2355*22dc650dSSadaf Ebrahimi {
2356*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
2357*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
2358*22dc650dSSadaf Ebrahimi }
2359*22dc650dSSadaf Ebrahimi GETCHARINCTEST(fc, Feptr);
2360*22dc650dSSadaf Ebrahimi if (CHMAX_255(fc) && (mb->ctypes[fc] & ctype_word) != 0)
2361*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
2362*22dc650dSSadaf Ebrahimi Fecode++;
2363*22dc650dSSadaf Ebrahimi break;
2364*22dc650dSSadaf Ebrahimi
2365*22dc650dSSadaf Ebrahimi case OP_WORDCHAR:
2366*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
2367*22dc650dSSadaf Ebrahimi {
2368*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
2369*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
2370*22dc650dSSadaf Ebrahimi }
2371*22dc650dSSadaf Ebrahimi GETCHARINCTEST(fc, Feptr);
2372*22dc650dSSadaf Ebrahimi if (!CHMAX_255(fc) || (mb->ctypes[fc] & ctype_word) == 0)
2373*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
2374*22dc650dSSadaf Ebrahimi Fecode++;
2375*22dc650dSSadaf Ebrahimi break;
2376*22dc650dSSadaf Ebrahimi
2377*22dc650dSSadaf Ebrahimi case OP_ANYNL:
2378*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
2379*22dc650dSSadaf Ebrahimi {
2380*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
2381*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
2382*22dc650dSSadaf Ebrahimi }
2383*22dc650dSSadaf Ebrahimi GETCHARINCTEST(fc, Feptr);
2384*22dc650dSSadaf Ebrahimi switch(fc)
2385*22dc650dSSadaf Ebrahimi {
2386*22dc650dSSadaf Ebrahimi default: RRETURN(MATCH_NOMATCH);
2387*22dc650dSSadaf Ebrahimi
2388*22dc650dSSadaf Ebrahimi case CHAR_CR:
2389*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
2390*22dc650dSSadaf Ebrahimi {
2391*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
2392*22dc650dSSadaf Ebrahimi }
2393*22dc650dSSadaf Ebrahimi else if (UCHAR21TEST(Feptr) == CHAR_LF) Feptr++;
2394*22dc650dSSadaf Ebrahimi break;
2395*22dc650dSSadaf Ebrahimi
2396*22dc650dSSadaf Ebrahimi case CHAR_LF:
2397*22dc650dSSadaf Ebrahimi break;
2398*22dc650dSSadaf Ebrahimi
2399*22dc650dSSadaf Ebrahimi case CHAR_VT:
2400*22dc650dSSadaf Ebrahimi case CHAR_FF:
2401*22dc650dSSadaf Ebrahimi case CHAR_NEL:
2402*22dc650dSSadaf Ebrahimi #ifndef EBCDIC
2403*22dc650dSSadaf Ebrahimi case 0x2028:
2404*22dc650dSSadaf Ebrahimi case 0x2029:
2405*22dc650dSSadaf Ebrahimi #endif /* Not EBCDIC */
2406*22dc650dSSadaf Ebrahimi if (mb->bsr_convention == PCRE2_BSR_ANYCRLF) RRETURN(MATCH_NOMATCH);
2407*22dc650dSSadaf Ebrahimi break;
2408*22dc650dSSadaf Ebrahimi }
2409*22dc650dSSadaf Ebrahimi Fecode++;
2410*22dc650dSSadaf Ebrahimi break;
2411*22dc650dSSadaf Ebrahimi
2412*22dc650dSSadaf Ebrahimi case OP_NOT_HSPACE:
2413*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
2414*22dc650dSSadaf Ebrahimi {
2415*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
2416*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
2417*22dc650dSSadaf Ebrahimi }
2418*22dc650dSSadaf Ebrahimi GETCHARINCTEST(fc, Feptr);
2419*22dc650dSSadaf Ebrahimi switch(fc)
2420*22dc650dSSadaf Ebrahimi {
2421*22dc650dSSadaf Ebrahimi HSPACE_CASES: RRETURN(MATCH_NOMATCH); /* Byte and multibyte cases */
2422*22dc650dSSadaf Ebrahimi default: break;
2423*22dc650dSSadaf Ebrahimi }
2424*22dc650dSSadaf Ebrahimi Fecode++;
2425*22dc650dSSadaf Ebrahimi break;
2426*22dc650dSSadaf Ebrahimi
2427*22dc650dSSadaf Ebrahimi case OP_HSPACE:
2428*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
2429*22dc650dSSadaf Ebrahimi {
2430*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
2431*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
2432*22dc650dSSadaf Ebrahimi }
2433*22dc650dSSadaf Ebrahimi GETCHARINCTEST(fc, Feptr);
2434*22dc650dSSadaf Ebrahimi switch(fc)
2435*22dc650dSSadaf Ebrahimi {
2436*22dc650dSSadaf Ebrahimi HSPACE_CASES: break; /* Byte and multibyte cases */
2437*22dc650dSSadaf Ebrahimi default: RRETURN(MATCH_NOMATCH);
2438*22dc650dSSadaf Ebrahimi }
2439*22dc650dSSadaf Ebrahimi Fecode++;
2440*22dc650dSSadaf Ebrahimi break;
2441*22dc650dSSadaf Ebrahimi
2442*22dc650dSSadaf Ebrahimi case OP_NOT_VSPACE:
2443*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
2444*22dc650dSSadaf Ebrahimi {
2445*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
2446*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
2447*22dc650dSSadaf Ebrahimi }
2448*22dc650dSSadaf Ebrahimi GETCHARINCTEST(fc, Feptr);
2449*22dc650dSSadaf Ebrahimi switch(fc)
2450*22dc650dSSadaf Ebrahimi {
2451*22dc650dSSadaf Ebrahimi VSPACE_CASES: RRETURN(MATCH_NOMATCH);
2452*22dc650dSSadaf Ebrahimi default: break;
2453*22dc650dSSadaf Ebrahimi }
2454*22dc650dSSadaf Ebrahimi Fecode++;
2455*22dc650dSSadaf Ebrahimi break;
2456*22dc650dSSadaf Ebrahimi
2457*22dc650dSSadaf Ebrahimi case OP_VSPACE:
2458*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
2459*22dc650dSSadaf Ebrahimi {
2460*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
2461*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
2462*22dc650dSSadaf Ebrahimi }
2463*22dc650dSSadaf Ebrahimi GETCHARINCTEST(fc, Feptr);
2464*22dc650dSSadaf Ebrahimi switch(fc)
2465*22dc650dSSadaf Ebrahimi {
2466*22dc650dSSadaf Ebrahimi VSPACE_CASES: break;
2467*22dc650dSSadaf Ebrahimi default: RRETURN(MATCH_NOMATCH);
2468*22dc650dSSadaf Ebrahimi }
2469*22dc650dSSadaf Ebrahimi Fecode++;
2470*22dc650dSSadaf Ebrahimi break;
2471*22dc650dSSadaf Ebrahimi
2472*22dc650dSSadaf Ebrahimi
2473*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_UNICODE
2474*22dc650dSSadaf Ebrahimi
2475*22dc650dSSadaf Ebrahimi /* ===================================================================== */
2476*22dc650dSSadaf Ebrahimi /* Check the next character by Unicode property. We will get here only
2477*22dc650dSSadaf Ebrahimi if the support is in the binary; otherwise a compile-time error occurs. */
2478*22dc650dSSadaf Ebrahimi
2479*22dc650dSSadaf Ebrahimi case OP_PROP:
2480*22dc650dSSadaf Ebrahimi case OP_NOTPROP:
2481*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
2482*22dc650dSSadaf Ebrahimi {
2483*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
2484*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
2485*22dc650dSSadaf Ebrahimi }
2486*22dc650dSSadaf Ebrahimi GETCHARINCTEST(fc, Feptr);
2487*22dc650dSSadaf Ebrahimi {
2488*22dc650dSSadaf Ebrahimi const uint32_t *cp;
2489*22dc650dSSadaf Ebrahimi uint32_t chartype;
2490*22dc650dSSadaf Ebrahimi const ucd_record *prop = GET_UCD(fc);
2491*22dc650dSSadaf Ebrahimi BOOL notmatch = Fop == OP_NOTPROP;
2492*22dc650dSSadaf Ebrahimi
2493*22dc650dSSadaf Ebrahimi switch(Fecode[1])
2494*22dc650dSSadaf Ebrahimi {
2495*22dc650dSSadaf Ebrahimi case PT_ANY:
2496*22dc650dSSadaf Ebrahimi if (notmatch) RRETURN(MATCH_NOMATCH);
2497*22dc650dSSadaf Ebrahimi break;
2498*22dc650dSSadaf Ebrahimi
2499*22dc650dSSadaf Ebrahimi case PT_LAMP:
2500*22dc650dSSadaf Ebrahimi chartype = prop->chartype;
2501*22dc650dSSadaf Ebrahimi if ((chartype == ucp_Lu ||
2502*22dc650dSSadaf Ebrahimi chartype == ucp_Ll ||
2503*22dc650dSSadaf Ebrahimi chartype == ucp_Lt) == notmatch)
2504*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
2505*22dc650dSSadaf Ebrahimi break;
2506*22dc650dSSadaf Ebrahimi
2507*22dc650dSSadaf Ebrahimi case PT_GC:
2508*22dc650dSSadaf Ebrahimi if ((Fecode[2] == PRIV(ucp_gentype)[prop->chartype]) == notmatch)
2509*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
2510*22dc650dSSadaf Ebrahimi break;
2511*22dc650dSSadaf Ebrahimi
2512*22dc650dSSadaf Ebrahimi case PT_PC:
2513*22dc650dSSadaf Ebrahimi if ((Fecode[2] == prop->chartype) == notmatch)
2514*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
2515*22dc650dSSadaf Ebrahimi break;
2516*22dc650dSSadaf Ebrahimi
2517*22dc650dSSadaf Ebrahimi case PT_SC:
2518*22dc650dSSadaf Ebrahimi if ((Fecode[2] == prop->script) == notmatch)
2519*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
2520*22dc650dSSadaf Ebrahimi break;
2521*22dc650dSSadaf Ebrahimi
2522*22dc650dSSadaf Ebrahimi case PT_SCX:
2523*22dc650dSSadaf Ebrahimi {
2524*22dc650dSSadaf Ebrahimi BOOL ok = (Fecode[2] == prop->script ||
2525*22dc650dSSadaf Ebrahimi MAPBIT(PRIV(ucd_script_sets) + UCD_SCRIPTX_PROP(prop), Fecode[2]) != 0);
2526*22dc650dSSadaf Ebrahimi if (ok == notmatch) RRETURN(MATCH_NOMATCH);
2527*22dc650dSSadaf Ebrahimi }
2528*22dc650dSSadaf Ebrahimi break;
2529*22dc650dSSadaf Ebrahimi
2530*22dc650dSSadaf Ebrahimi /* These are specials */
2531*22dc650dSSadaf Ebrahimi
2532*22dc650dSSadaf Ebrahimi case PT_ALNUM:
2533*22dc650dSSadaf Ebrahimi chartype = prop->chartype;
2534*22dc650dSSadaf Ebrahimi if ((PRIV(ucp_gentype)[chartype] == ucp_L ||
2535*22dc650dSSadaf Ebrahimi PRIV(ucp_gentype)[chartype] == ucp_N) == notmatch)
2536*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
2537*22dc650dSSadaf Ebrahimi break;
2538*22dc650dSSadaf Ebrahimi
2539*22dc650dSSadaf Ebrahimi /* Perl space used to exclude VT, but from Perl 5.18 it is included,
2540*22dc650dSSadaf Ebrahimi which means that Perl space and POSIX space are now identical. PCRE
2541*22dc650dSSadaf Ebrahimi was changed at release 8.34. */
2542*22dc650dSSadaf Ebrahimi
2543*22dc650dSSadaf Ebrahimi case PT_SPACE: /* Perl space */
2544*22dc650dSSadaf Ebrahimi case PT_PXSPACE: /* POSIX space */
2545*22dc650dSSadaf Ebrahimi switch(fc)
2546*22dc650dSSadaf Ebrahimi {
2547*22dc650dSSadaf Ebrahimi HSPACE_CASES:
2548*22dc650dSSadaf Ebrahimi VSPACE_CASES:
2549*22dc650dSSadaf Ebrahimi if (notmatch) RRETURN(MATCH_NOMATCH);
2550*22dc650dSSadaf Ebrahimi break;
2551*22dc650dSSadaf Ebrahimi
2552*22dc650dSSadaf Ebrahimi default:
2553*22dc650dSSadaf Ebrahimi if ((PRIV(ucp_gentype)[prop->chartype] == ucp_Z) == notmatch)
2554*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
2555*22dc650dSSadaf Ebrahimi break;
2556*22dc650dSSadaf Ebrahimi }
2557*22dc650dSSadaf Ebrahimi break;
2558*22dc650dSSadaf Ebrahimi
2559*22dc650dSSadaf Ebrahimi case PT_WORD:
2560*22dc650dSSadaf Ebrahimi chartype = prop->chartype;
2561*22dc650dSSadaf Ebrahimi if ((PRIV(ucp_gentype)[chartype] == ucp_L ||
2562*22dc650dSSadaf Ebrahimi PRIV(ucp_gentype)[chartype] == ucp_N ||
2563*22dc650dSSadaf Ebrahimi chartype == ucp_Mn ||
2564*22dc650dSSadaf Ebrahimi chartype == ucp_Pc) == notmatch)
2565*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
2566*22dc650dSSadaf Ebrahimi break;
2567*22dc650dSSadaf Ebrahimi
2568*22dc650dSSadaf Ebrahimi case PT_CLIST:
2569*22dc650dSSadaf Ebrahimi #if PCRE2_CODE_UNIT_WIDTH == 32
2570*22dc650dSSadaf Ebrahimi if (fc > MAX_UTF_CODE_POINT)
2571*22dc650dSSadaf Ebrahimi {
2572*22dc650dSSadaf Ebrahimi if (notmatch) break;;
2573*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
2574*22dc650dSSadaf Ebrahimi }
2575*22dc650dSSadaf Ebrahimi #endif
2576*22dc650dSSadaf Ebrahimi cp = PRIV(ucd_caseless_sets) + Fecode[2];
2577*22dc650dSSadaf Ebrahimi for (;;)
2578*22dc650dSSadaf Ebrahimi {
2579*22dc650dSSadaf Ebrahimi if (fc < *cp)
2580*22dc650dSSadaf Ebrahimi { if (notmatch) break; else { RRETURN(MATCH_NOMATCH); } }
2581*22dc650dSSadaf Ebrahimi if (fc == *cp++)
2582*22dc650dSSadaf Ebrahimi { if (notmatch) { RRETURN(MATCH_NOMATCH); } else break; }
2583*22dc650dSSadaf Ebrahimi }
2584*22dc650dSSadaf Ebrahimi break;
2585*22dc650dSSadaf Ebrahimi
2586*22dc650dSSadaf Ebrahimi case PT_UCNC:
2587*22dc650dSSadaf Ebrahimi if ((fc == CHAR_DOLLAR_SIGN || fc == CHAR_COMMERCIAL_AT ||
2588*22dc650dSSadaf Ebrahimi fc == CHAR_GRAVE_ACCENT || (fc >= 0xa0 && fc <= 0xd7ff) ||
2589*22dc650dSSadaf Ebrahimi fc >= 0xe000) == notmatch)
2590*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
2591*22dc650dSSadaf Ebrahimi break;
2592*22dc650dSSadaf Ebrahimi
2593*22dc650dSSadaf Ebrahimi case PT_BIDICL:
2594*22dc650dSSadaf Ebrahimi if ((UCD_BIDICLASS_PROP(prop) == Fecode[2]) == notmatch)
2595*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
2596*22dc650dSSadaf Ebrahimi break;
2597*22dc650dSSadaf Ebrahimi
2598*22dc650dSSadaf Ebrahimi case PT_BOOL:
2599*22dc650dSSadaf Ebrahimi {
2600*22dc650dSSadaf Ebrahimi BOOL ok = MAPBIT(PRIV(ucd_boolprop_sets) +
2601*22dc650dSSadaf Ebrahimi UCD_BPROPS_PROP(prop), Fecode[2]) != 0;
2602*22dc650dSSadaf Ebrahimi if (ok == notmatch) RRETURN(MATCH_NOMATCH);
2603*22dc650dSSadaf Ebrahimi }
2604*22dc650dSSadaf Ebrahimi break;
2605*22dc650dSSadaf Ebrahimi
2606*22dc650dSSadaf Ebrahimi /* This should never occur */
2607*22dc650dSSadaf Ebrahimi
2608*22dc650dSSadaf Ebrahimi default:
2609*22dc650dSSadaf Ebrahimi return PCRE2_ERROR_INTERNAL;
2610*22dc650dSSadaf Ebrahimi }
2611*22dc650dSSadaf Ebrahimi
2612*22dc650dSSadaf Ebrahimi Fecode += 3;
2613*22dc650dSSadaf Ebrahimi }
2614*22dc650dSSadaf Ebrahimi break;
2615*22dc650dSSadaf Ebrahimi
2616*22dc650dSSadaf Ebrahimi
2617*22dc650dSSadaf Ebrahimi /* ===================================================================== */
2618*22dc650dSSadaf Ebrahimi /* Match an extended Unicode sequence. We will get here only if the support
2619*22dc650dSSadaf Ebrahimi is in the binary; otherwise a compile-time error occurs. */
2620*22dc650dSSadaf Ebrahimi
2621*22dc650dSSadaf Ebrahimi case OP_EXTUNI:
2622*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
2623*22dc650dSSadaf Ebrahimi {
2624*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
2625*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
2626*22dc650dSSadaf Ebrahimi }
2627*22dc650dSSadaf Ebrahimi else
2628*22dc650dSSadaf Ebrahimi {
2629*22dc650dSSadaf Ebrahimi GETCHARINCTEST(fc, Feptr);
2630*22dc650dSSadaf Ebrahimi Feptr = PRIV(extuni)(fc, Feptr, mb->start_subject, mb->end_subject, utf,
2631*22dc650dSSadaf Ebrahimi NULL);
2632*22dc650dSSadaf Ebrahimi }
2633*22dc650dSSadaf Ebrahimi CHECK_PARTIAL();
2634*22dc650dSSadaf Ebrahimi Fecode++;
2635*22dc650dSSadaf Ebrahimi break;
2636*22dc650dSSadaf Ebrahimi
2637*22dc650dSSadaf Ebrahimi #endif /* SUPPORT_UNICODE */
2638*22dc650dSSadaf Ebrahimi
2639*22dc650dSSadaf Ebrahimi
2640*22dc650dSSadaf Ebrahimi /* ===================================================================== */
2641*22dc650dSSadaf Ebrahimi /* Match a single character type repeatedly. Note that the property type
2642*22dc650dSSadaf Ebrahimi does not need to be in a stack frame as it is not used within an RMATCH()
2643*22dc650dSSadaf Ebrahimi loop. */
2644*22dc650dSSadaf Ebrahimi
2645*22dc650dSSadaf Ebrahimi #define Lstart_eptr F->temp_sptr[0]
2646*22dc650dSSadaf Ebrahimi #define Lmin F->temp_32[0]
2647*22dc650dSSadaf Ebrahimi #define Lmax F->temp_32[1]
2648*22dc650dSSadaf Ebrahimi #define Lctype F->temp_32[2]
2649*22dc650dSSadaf Ebrahimi #define Lpropvalue F->temp_32[3]
2650*22dc650dSSadaf Ebrahimi
2651*22dc650dSSadaf Ebrahimi case OP_TYPEEXACT:
2652*22dc650dSSadaf Ebrahimi Lmin = Lmax = GET2(Fecode, 1);
2653*22dc650dSSadaf Ebrahimi Fecode += 1 + IMM2_SIZE;
2654*22dc650dSSadaf Ebrahimi goto REPEATTYPE;
2655*22dc650dSSadaf Ebrahimi
2656*22dc650dSSadaf Ebrahimi case OP_TYPEUPTO:
2657*22dc650dSSadaf Ebrahimi case OP_TYPEMINUPTO:
2658*22dc650dSSadaf Ebrahimi Lmin = 0;
2659*22dc650dSSadaf Ebrahimi Lmax = GET2(Fecode, 1);
2660*22dc650dSSadaf Ebrahimi reptype = (*Fecode == OP_TYPEMINUPTO)? REPTYPE_MIN : REPTYPE_MAX;
2661*22dc650dSSadaf Ebrahimi Fecode += 1 + IMM2_SIZE;
2662*22dc650dSSadaf Ebrahimi goto REPEATTYPE;
2663*22dc650dSSadaf Ebrahimi
2664*22dc650dSSadaf Ebrahimi case OP_TYPEPOSSTAR:
2665*22dc650dSSadaf Ebrahimi reptype = REPTYPE_POS;
2666*22dc650dSSadaf Ebrahimi Lmin = 0;
2667*22dc650dSSadaf Ebrahimi Lmax = UINT32_MAX;
2668*22dc650dSSadaf Ebrahimi Fecode++;
2669*22dc650dSSadaf Ebrahimi goto REPEATTYPE;
2670*22dc650dSSadaf Ebrahimi
2671*22dc650dSSadaf Ebrahimi case OP_TYPEPOSPLUS:
2672*22dc650dSSadaf Ebrahimi reptype = REPTYPE_POS;
2673*22dc650dSSadaf Ebrahimi Lmin = 1;
2674*22dc650dSSadaf Ebrahimi Lmax = UINT32_MAX;
2675*22dc650dSSadaf Ebrahimi Fecode++;
2676*22dc650dSSadaf Ebrahimi goto REPEATTYPE;
2677*22dc650dSSadaf Ebrahimi
2678*22dc650dSSadaf Ebrahimi case OP_TYPEPOSQUERY:
2679*22dc650dSSadaf Ebrahimi reptype = REPTYPE_POS;
2680*22dc650dSSadaf Ebrahimi Lmin = 0;
2681*22dc650dSSadaf Ebrahimi Lmax = 1;
2682*22dc650dSSadaf Ebrahimi Fecode++;
2683*22dc650dSSadaf Ebrahimi goto REPEATTYPE;
2684*22dc650dSSadaf Ebrahimi
2685*22dc650dSSadaf Ebrahimi case OP_TYPEPOSUPTO:
2686*22dc650dSSadaf Ebrahimi reptype = REPTYPE_POS;
2687*22dc650dSSadaf Ebrahimi Lmin = 0;
2688*22dc650dSSadaf Ebrahimi Lmax = GET2(Fecode, 1);
2689*22dc650dSSadaf Ebrahimi Fecode += 1 + IMM2_SIZE;
2690*22dc650dSSadaf Ebrahimi goto REPEATTYPE;
2691*22dc650dSSadaf Ebrahimi
2692*22dc650dSSadaf Ebrahimi case OP_TYPESTAR:
2693*22dc650dSSadaf Ebrahimi case OP_TYPEMINSTAR:
2694*22dc650dSSadaf Ebrahimi case OP_TYPEPLUS:
2695*22dc650dSSadaf Ebrahimi case OP_TYPEMINPLUS:
2696*22dc650dSSadaf Ebrahimi case OP_TYPEQUERY:
2697*22dc650dSSadaf Ebrahimi case OP_TYPEMINQUERY:
2698*22dc650dSSadaf Ebrahimi fc = *Fecode++ - OP_TYPESTAR;
2699*22dc650dSSadaf Ebrahimi Lmin = rep_min[fc];
2700*22dc650dSSadaf Ebrahimi Lmax = rep_max[fc];
2701*22dc650dSSadaf Ebrahimi reptype = rep_typ[fc];
2702*22dc650dSSadaf Ebrahimi
2703*22dc650dSSadaf Ebrahimi /* Common code for all repeated character type matches. */
2704*22dc650dSSadaf Ebrahimi
2705*22dc650dSSadaf Ebrahimi REPEATTYPE:
2706*22dc650dSSadaf Ebrahimi Lctype = *Fecode++; /* Code for the character type */
2707*22dc650dSSadaf Ebrahimi
2708*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_UNICODE
2709*22dc650dSSadaf Ebrahimi if (Lctype == OP_PROP || Lctype == OP_NOTPROP)
2710*22dc650dSSadaf Ebrahimi {
2711*22dc650dSSadaf Ebrahimi proptype = *Fecode++;
2712*22dc650dSSadaf Ebrahimi Lpropvalue = *Fecode++;
2713*22dc650dSSadaf Ebrahimi }
2714*22dc650dSSadaf Ebrahimi else proptype = -1;
2715*22dc650dSSadaf Ebrahimi #endif
2716*22dc650dSSadaf Ebrahimi
2717*22dc650dSSadaf Ebrahimi /* First, ensure the minimum number of matches are present. Use inline
2718*22dc650dSSadaf Ebrahimi code for maximizing the speed, and do the type test once at the start
2719*22dc650dSSadaf Ebrahimi (i.e. keep it out of the loops). As there are no calls to RMATCH in the
2720*22dc650dSSadaf Ebrahimi loops, we can use an ordinary variable for "notmatch". The code for UTF
2721*22dc650dSSadaf Ebrahimi mode is separated out for tidiness, except for Unicode property tests. */
2722*22dc650dSSadaf Ebrahimi
2723*22dc650dSSadaf Ebrahimi if (Lmin > 0)
2724*22dc650dSSadaf Ebrahimi {
2725*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_UNICODE
2726*22dc650dSSadaf Ebrahimi if (proptype >= 0) /* Property tests in all modes */
2727*22dc650dSSadaf Ebrahimi {
2728*22dc650dSSadaf Ebrahimi BOOL notmatch = Lctype == OP_NOTPROP;
2729*22dc650dSSadaf Ebrahimi switch(proptype)
2730*22dc650dSSadaf Ebrahimi {
2731*22dc650dSSadaf Ebrahimi case PT_ANY:
2732*22dc650dSSadaf Ebrahimi if (notmatch) RRETURN(MATCH_NOMATCH);
2733*22dc650dSSadaf Ebrahimi for (i = 1; i <= Lmin; i++)
2734*22dc650dSSadaf Ebrahimi {
2735*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
2736*22dc650dSSadaf Ebrahimi {
2737*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
2738*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
2739*22dc650dSSadaf Ebrahimi }
2740*22dc650dSSadaf Ebrahimi GETCHARINCTEST(fc, Feptr);
2741*22dc650dSSadaf Ebrahimi }
2742*22dc650dSSadaf Ebrahimi break;
2743*22dc650dSSadaf Ebrahimi
2744*22dc650dSSadaf Ebrahimi case PT_LAMP:
2745*22dc650dSSadaf Ebrahimi for (i = 1; i <= Lmin; i++)
2746*22dc650dSSadaf Ebrahimi {
2747*22dc650dSSadaf Ebrahimi int chartype;
2748*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
2749*22dc650dSSadaf Ebrahimi {
2750*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
2751*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
2752*22dc650dSSadaf Ebrahimi }
2753*22dc650dSSadaf Ebrahimi GETCHARINCTEST(fc, Feptr);
2754*22dc650dSSadaf Ebrahimi chartype = UCD_CHARTYPE(fc);
2755*22dc650dSSadaf Ebrahimi if ((chartype == ucp_Lu ||
2756*22dc650dSSadaf Ebrahimi chartype == ucp_Ll ||
2757*22dc650dSSadaf Ebrahimi chartype == ucp_Lt) == notmatch)
2758*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
2759*22dc650dSSadaf Ebrahimi }
2760*22dc650dSSadaf Ebrahimi break;
2761*22dc650dSSadaf Ebrahimi
2762*22dc650dSSadaf Ebrahimi case PT_GC:
2763*22dc650dSSadaf Ebrahimi for (i = 1; i <= Lmin; i++)
2764*22dc650dSSadaf Ebrahimi {
2765*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
2766*22dc650dSSadaf Ebrahimi {
2767*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
2768*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
2769*22dc650dSSadaf Ebrahimi }
2770*22dc650dSSadaf Ebrahimi GETCHARINCTEST(fc, Feptr);
2771*22dc650dSSadaf Ebrahimi if ((UCD_CATEGORY(fc) == Lpropvalue) == notmatch)
2772*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
2773*22dc650dSSadaf Ebrahimi }
2774*22dc650dSSadaf Ebrahimi break;
2775*22dc650dSSadaf Ebrahimi
2776*22dc650dSSadaf Ebrahimi case PT_PC:
2777*22dc650dSSadaf Ebrahimi for (i = 1; i <= Lmin; i++)
2778*22dc650dSSadaf Ebrahimi {
2779*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
2780*22dc650dSSadaf Ebrahimi {
2781*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
2782*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
2783*22dc650dSSadaf Ebrahimi }
2784*22dc650dSSadaf Ebrahimi GETCHARINCTEST(fc, Feptr);
2785*22dc650dSSadaf Ebrahimi if ((UCD_CHARTYPE(fc) == Lpropvalue) == notmatch)
2786*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
2787*22dc650dSSadaf Ebrahimi }
2788*22dc650dSSadaf Ebrahimi break;
2789*22dc650dSSadaf Ebrahimi
2790*22dc650dSSadaf Ebrahimi case PT_SC:
2791*22dc650dSSadaf Ebrahimi for (i = 1; i <= Lmin; i++)
2792*22dc650dSSadaf Ebrahimi {
2793*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
2794*22dc650dSSadaf Ebrahimi {
2795*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
2796*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
2797*22dc650dSSadaf Ebrahimi }
2798*22dc650dSSadaf Ebrahimi GETCHARINCTEST(fc, Feptr);
2799*22dc650dSSadaf Ebrahimi if ((UCD_SCRIPT(fc) == Lpropvalue) == notmatch)
2800*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
2801*22dc650dSSadaf Ebrahimi }
2802*22dc650dSSadaf Ebrahimi break;
2803*22dc650dSSadaf Ebrahimi
2804*22dc650dSSadaf Ebrahimi case PT_SCX:
2805*22dc650dSSadaf Ebrahimi for (i = 1; i <= Lmin; i++)
2806*22dc650dSSadaf Ebrahimi {
2807*22dc650dSSadaf Ebrahimi BOOL ok;
2808*22dc650dSSadaf Ebrahimi const ucd_record *prop;
2809*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
2810*22dc650dSSadaf Ebrahimi {
2811*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
2812*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
2813*22dc650dSSadaf Ebrahimi }
2814*22dc650dSSadaf Ebrahimi GETCHARINCTEST(fc, Feptr);
2815*22dc650dSSadaf Ebrahimi prop = GET_UCD(fc);
2816*22dc650dSSadaf Ebrahimi ok = (prop->script == Lpropvalue ||
2817*22dc650dSSadaf Ebrahimi MAPBIT(PRIV(ucd_script_sets) + UCD_SCRIPTX_PROP(prop), Lpropvalue) != 0);
2818*22dc650dSSadaf Ebrahimi if (ok == notmatch)
2819*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
2820*22dc650dSSadaf Ebrahimi }
2821*22dc650dSSadaf Ebrahimi break;
2822*22dc650dSSadaf Ebrahimi
2823*22dc650dSSadaf Ebrahimi case PT_ALNUM:
2824*22dc650dSSadaf Ebrahimi for (i = 1; i <= Lmin; i++)
2825*22dc650dSSadaf Ebrahimi {
2826*22dc650dSSadaf Ebrahimi int category;
2827*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
2828*22dc650dSSadaf Ebrahimi {
2829*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
2830*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
2831*22dc650dSSadaf Ebrahimi }
2832*22dc650dSSadaf Ebrahimi GETCHARINCTEST(fc, Feptr);
2833*22dc650dSSadaf Ebrahimi category = UCD_CATEGORY(fc);
2834*22dc650dSSadaf Ebrahimi if ((category == ucp_L || category == ucp_N) == notmatch)
2835*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
2836*22dc650dSSadaf Ebrahimi }
2837*22dc650dSSadaf Ebrahimi break;
2838*22dc650dSSadaf Ebrahimi
2839*22dc650dSSadaf Ebrahimi /* Perl space used to exclude VT, but from Perl 5.18 it is included,
2840*22dc650dSSadaf Ebrahimi which means that Perl space and POSIX space are now identical. PCRE
2841*22dc650dSSadaf Ebrahimi was changed at release 8.34. */
2842*22dc650dSSadaf Ebrahimi
2843*22dc650dSSadaf Ebrahimi case PT_SPACE: /* Perl space */
2844*22dc650dSSadaf Ebrahimi case PT_PXSPACE: /* POSIX space */
2845*22dc650dSSadaf Ebrahimi for (i = 1; i <= Lmin; i++)
2846*22dc650dSSadaf Ebrahimi {
2847*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
2848*22dc650dSSadaf Ebrahimi {
2849*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
2850*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
2851*22dc650dSSadaf Ebrahimi }
2852*22dc650dSSadaf Ebrahimi GETCHARINCTEST(fc, Feptr);
2853*22dc650dSSadaf Ebrahimi switch(fc)
2854*22dc650dSSadaf Ebrahimi {
2855*22dc650dSSadaf Ebrahimi HSPACE_CASES:
2856*22dc650dSSadaf Ebrahimi VSPACE_CASES:
2857*22dc650dSSadaf Ebrahimi if (notmatch) RRETURN(MATCH_NOMATCH);
2858*22dc650dSSadaf Ebrahimi break;
2859*22dc650dSSadaf Ebrahimi
2860*22dc650dSSadaf Ebrahimi default:
2861*22dc650dSSadaf Ebrahimi if ((UCD_CATEGORY(fc) == ucp_Z) == notmatch)
2862*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
2863*22dc650dSSadaf Ebrahimi break;
2864*22dc650dSSadaf Ebrahimi }
2865*22dc650dSSadaf Ebrahimi }
2866*22dc650dSSadaf Ebrahimi break;
2867*22dc650dSSadaf Ebrahimi
2868*22dc650dSSadaf Ebrahimi case PT_WORD:
2869*22dc650dSSadaf Ebrahimi for (i = 1; i <= Lmin; i++)
2870*22dc650dSSadaf Ebrahimi {
2871*22dc650dSSadaf Ebrahimi int chartype, category;
2872*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
2873*22dc650dSSadaf Ebrahimi {
2874*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
2875*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
2876*22dc650dSSadaf Ebrahimi }
2877*22dc650dSSadaf Ebrahimi GETCHARINCTEST(fc, Feptr);
2878*22dc650dSSadaf Ebrahimi chartype = UCD_CHARTYPE(fc);
2879*22dc650dSSadaf Ebrahimi category = PRIV(ucp_gentype)[chartype];
2880*22dc650dSSadaf Ebrahimi if ((category == ucp_L || category == ucp_N ||
2881*22dc650dSSadaf Ebrahimi chartype == ucp_Mn || chartype == ucp_Pc) == notmatch)
2882*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
2883*22dc650dSSadaf Ebrahimi }
2884*22dc650dSSadaf Ebrahimi break;
2885*22dc650dSSadaf Ebrahimi
2886*22dc650dSSadaf Ebrahimi case PT_CLIST:
2887*22dc650dSSadaf Ebrahimi for (i = 1; i <= Lmin; i++)
2888*22dc650dSSadaf Ebrahimi {
2889*22dc650dSSadaf Ebrahimi const uint32_t *cp;
2890*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
2891*22dc650dSSadaf Ebrahimi {
2892*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
2893*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
2894*22dc650dSSadaf Ebrahimi }
2895*22dc650dSSadaf Ebrahimi GETCHARINCTEST(fc, Feptr);
2896*22dc650dSSadaf Ebrahimi #if PCRE2_CODE_UNIT_WIDTH == 32
2897*22dc650dSSadaf Ebrahimi if (fc > MAX_UTF_CODE_POINT)
2898*22dc650dSSadaf Ebrahimi {
2899*22dc650dSSadaf Ebrahimi if (notmatch) continue;
2900*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
2901*22dc650dSSadaf Ebrahimi }
2902*22dc650dSSadaf Ebrahimi #endif
2903*22dc650dSSadaf Ebrahimi cp = PRIV(ucd_caseless_sets) + Lpropvalue;
2904*22dc650dSSadaf Ebrahimi for (;;)
2905*22dc650dSSadaf Ebrahimi {
2906*22dc650dSSadaf Ebrahimi if (fc < *cp)
2907*22dc650dSSadaf Ebrahimi {
2908*22dc650dSSadaf Ebrahimi if (notmatch) break;
2909*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
2910*22dc650dSSadaf Ebrahimi }
2911*22dc650dSSadaf Ebrahimi if (fc == *cp++)
2912*22dc650dSSadaf Ebrahimi {
2913*22dc650dSSadaf Ebrahimi if (notmatch) RRETURN(MATCH_NOMATCH);
2914*22dc650dSSadaf Ebrahimi break;
2915*22dc650dSSadaf Ebrahimi }
2916*22dc650dSSadaf Ebrahimi }
2917*22dc650dSSadaf Ebrahimi }
2918*22dc650dSSadaf Ebrahimi break;
2919*22dc650dSSadaf Ebrahimi
2920*22dc650dSSadaf Ebrahimi case PT_UCNC:
2921*22dc650dSSadaf Ebrahimi for (i = 1; i <= Lmin; i++)
2922*22dc650dSSadaf Ebrahimi {
2923*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
2924*22dc650dSSadaf Ebrahimi {
2925*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
2926*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
2927*22dc650dSSadaf Ebrahimi }
2928*22dc650dSSadaf Ebrahimi GETCHARINCTEST(fc, Feptr);
2929*22dc650dSSadaf Ebrahimi if ((fc == CHAR_DOLLAR_SIGN || fc == CHAR_COMMERCIAL_AT ||
2930*22dc650dSSadaf Ebrahimi fc == CHAR_GRAVE_ACCENT || (fc >= 0xa0 && fc <= 0xd7ff) ||
2931*22dc650dSSadaf Ebrahimi fc >= 0xe000) == notmatch)
2932*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
2933*22dc650dSSadaf Ebrahimi }
2934*22dc650dSSadaf Ebrahimi break;
2935*22dc650dSSadaf Ebrahimi
2936*22dc650dSSadaf Ebrahimi case PT_BIDICL:
2937*22dc650dSSadaf Ebrahimi for (i = 1; i <= Lmin; i++)
2938*22dc650dSSadaf Ebrahimi {
2939*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
2940*22dc650dSSadaf Ebrahimi {
2941*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
2942*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
2943*22dc650dSSadaf Ebrahimi }
2944*22dc650dSSadaf Ebrahimi GETCHARINCTEST(fc, Feptr);
2945*22dc650dSSadaf Ebrahimi if ((UCD_BIDICLASS(fc) == Lpropvalue) == notmatch)
2946*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
2947*22dc650dSSadaf Ebrahimi }
2948*22dc650dSSadaf Ebrahimi break;
2949*22dc650dSSadaf Ebrahimi
2950*22dc650dSSadaf Ebrahimi case PT_BOOL:
2951*22dc650dSSadaf Ebrahimi for (i = 1; i <= Lmin; i++)
2952*22dc650dSSadaf Ebrahimi {
2953*22dc650dSSadaf Ebrahimi BOOL ok;
2954*22dc650dSSadaf Ebrahimi const ucd_record *prop;
2955*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
2956*22dc650dSSadaf Ebrahimi {
2957*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
2958*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
2959*22dc650dSSadaf Ebrahimi }
2960*22dc650dSSadaf Ebrahimi GETCHARINCTEST(fc, Feptr);
2961*22dc650dSSadaf Ebrahimi prop = GET_UCD(fc);
2962*22dc650dSSadaf Ebrahimi ok = MAPBIT(PRIV(ucd_boolprop_sets) +
2963*22dc650dSSadaf Ebrahimi UCD_BPROPS_PROP(prop), Lpropvalue) != 0;
2964*22dc650dSSadaf Ebrahimi if (ok == notmatch)
2965*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
2966*22dc650dSSadaf Ebrahimi }
2967*22dc650dSSadaf Ebrahimi break;
2968*22dc650dSSadaf Ebrahimi
2969*22dc650dSSadaf Ebrahimi /* This should not occur */
2970*22dc650dSSadaf Ebrahimi
2971*22dc650dSSadaf Ebrahimi default:
2972*22dc650dSSadaf Ebrahimi return PCRE2_ERROR_INTERNAL;
2973*22dc650dSSadaf Ebrahimi }
2974*22dc650dSSadaf Ebrahimi }
2975*22dc650dSSadaf Ebrahimi
2976*22dc650dSSadaf Ebrahimi /* Match extended Unicode sequences. We will get here only if the
2977*22dc650dSSadaf Ebrahimi support is in the binary; otherwise a compile-time error occurs. */
2978*22dc650dSSadaf Ebrahimi
2979*22dc650dSSadaf Ebrahimi else if (Lctype == OP_EXTUNI)
2980*22dc650dSSadaf Ebrahimi {
2981*22dc650dSSadaf Ebrahimi for (i = 1; i <= Lmin; i++)
2982*22dc650dSSadaf Ebrahimi {
2983*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
2984*22dc650dSSadaf Ebrahimi {
2985*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
2986*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
2987*22dc650dSSadaf Ebrahimi }
2988*22dc650dSSadaf Ebrahimi else
2989*22dc650dSSadaf Ebrahimi {
2990*22dc650dSSadaf Ebrahimi GETCHARINCTEST(fc, Feptr);
2991*22dc650dSSadaf Ebrahimi Feptr = PRIV(extuni)(fc, Feptr, mb->start_subject,
2992*22dc650dSSadaf Ebrahimi mb->end_subject, utf, NULL);
2993*22dc650dSSadaf Ebrahimi }
2994*22dc650dSSadaf Ebrahimi CHECK_PARTIAL();
2995*22dc650dSSadaf Ebrahimi }
2996*22dc650dSSadaf Ebrahimi }
2997*22dc650dSSadaf Ebrahimi else
2998*22dc650dSSadaf Ebrahimi #endif /* SUPPORT_UNICODE */
2999*22dc650dSSadaf Ebrahimi
3000*22dc650dSSadaf Ebrahimi /* Handle all other cases in UTF mode */
3001*22dc650dSSadaf Ebrahimi
3002*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_UNICODE
3003*22dc650dSSadaf Ebrahimi if (utf) switch(Lctype)
3004*22dc650dSSadaf Ebrahimi {
3005*22dc650dSSadaf Ebrahimi case OP_ANY:
3006*22dc650dSSadaf Ebrahimi for (i = 1; i <= Lmin; i++)
3007*22dc650dSSadaf Ebrahimi {
3008*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
3009*22dc650dSSadaf Ebrahimi {
3010*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
3011*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
3012*22dc650dSSadaf Ebrahimi }
3013*22dc650dSSadaf Ebrahimi if (IS_NEWLINE(Feptr)) RRETURN(MATCH_NOMATCH);
3014*22dc650dSSadaf Ebrahimi if (mb->partial != 0 &&
3015*22dc650dSSadaf Ebrahimi Feptr + 1 >= mb->end_subject &&
3016*22dc650dSSadaf Ebrahimi NLBLOCK->nltype == NLTYPE_FIXED &&
3017*22dc650dSSadaf Ebrahimi NLBLOCK->nllen == 2 &&
3018*22dc650dSSadaf Ebrahimi UCHAR21(Feptr) == NLBLOCK->nl[0])
3019*22dc650dSSadaf Ebrahimi {
3020*22dc650dSSadaf Ebrahimi mb->hitend = TRUE;
3021*22dc650dSSadaf Ebrahimi if (mb->partial > 1) return PCRE2_ERROR_PARTIAL;
3022*22dc650dSSadaf Ebrahimi }
3023*22dc650dSSadaf Ebrahimi Feptr++;
3024*22dc650dSSadaf Ebrahimi ACROSSCHAR(Feptr < mb->end_subject, Feptr, Feptr++);
3025*22dc650dSSadaf Ebrahimi }
3026*22dc650dSSadaf Ebrahimi break;
3027*22dc650dSSadaf Ebrahimi
3028*22dc650dSSadaf Ebrahimi case OP_ALLANY:
3029*22dc650dSSadaf Ebrahimi for (i = 1; i <= Lmin; i++)
3030*22dc650dSSadaf Ebrahimi {
3031*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
3032*22dc650dSSadaf Ebrahimi {
3033*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
3034*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
3035*22dc650dSSadaf Ebrahimi }
3036*22dc650dSSadaf Ebrahimi Feptr++;
3037*22dc650dSSadaf Ebrahimi ACROSSCHAR(Feptr < mb->end_subject, Feptr, Feptr++);
3038*22dc650dSSadaf Ebrahimi }
3039*22dc650dSSadaf Ebrahimi break;
3040*22dc650dSSadaf Ebrahimi
3041*22dc650dSSadaf Ebrahimi case OP_ANYBYTE:
3042*22dc650dSSadaf Ebrahimi if (Feptr > mb->end_subject - Lmin) RRETURN(MATCH_NOMATCH);
3043*22dc650dSSadaf Ebrahimi Feptr += Lmin;
3044*22dc650dSSadaf Ebrahimi break;
3045*22dc650dSSadaf Ebrahimi
3046*22dc650dSSadaf Ebrahimi case OP_ANYNL:
3047*22dc650dSSadaf Ebrahimi for (i = 1; i <= Lmin; i++)
3048*22dc650dSSadaf Ebrahimi {
3049*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
3050*22dc650dSSadaf Ebrahimi {
3051*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
3052*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
3053*22dc650dSSadaf Ebrahimi }
3054*22dc650dSSadaf Ebrahimi GETCHARINC(fc, Feptr);
3055*22dc650dSSadaf Ebrahimi switch(fc)
3056*22dc650dSSadaf Ebrahimi {
3057*22dc650dSSadaf Ebrahimi default: RRETURN(MATCH_NOMATCH);
3058*22dc650dSSadaf Ebrahimi
3059*22dc650dSSadaf Ebrahimi case CHAR_CR:
3060*22dc650dSSadaf Ebrahimi if (Feptr < mb->end_subject && UCHAR21(Feptr) == CHAR_LF) Feptr++;
3061*22dc650dSSadaf Ebrahimi break;
3062*22dc650dSSadaf Ebrahimi
3063*22dc650dSSadaf Ebrahimi case CHAR_LF:
3064*22dc650dSSadaf Ebrahimi break;
3065*22dc650dSSadaf Ebrahimi
3066*22dc650dSSadaf Ebrahimi case CHAR_VT:
3067*22dc650dSSadaf Ebrahimi case CHAR_FF:
3068*22dc650dSSadaf Ebrahimi case CHAR_NEL:
3069*22dc650dSSadaf Ebrahimi #ifndef EBCDIC
3070*22dc650dSSadaf Ebrahimi case 0x2028:
3071*22dc650dSSadaf Ebrahimi case 0x2029:
3072*22dc650dSSadaf Ebrahimi #endif /* Not EBCDIC */
3073*22dc650dSSadaf Ebrahimi if (mb->bsr_convention == PCRE2_BSR_ANYCRLF) RRETURN(MATCH_NOMATCH);
3074*22dc650dSSadaf Ebrahimi break;
3075*22dc650dSSadaf Ebrahimi }
3076*22dc650dSSadaf Ebrahimi }
3077*22dc650dSSadaf Ebrahimi break;
3078*22dc650dSSadaf Ebrahimi
3079*22dc650dSSadaf Ebrahimi case OP_NOT_HSPACE:
3080*22dc650dSSadaf Ebrahimi for (i = 1; i <= Lmin; i++)
3081*22dc650dSSadaf Ebrahimi {
3082*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
3083*22dc650dSSadaf Ebrahimi {
3084*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
3085*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
3086*22dc650dSSadaf Ebrahimi }
3087*22dc650dSSadaf Ebrahimi GETCHARINC(fc, Feptr);
3088*22dc650dSSadaf Ebrahimi switch(fc)
3089*22dc650dSSadaf Ebrahimi {
3090*22dc650dSSadaf Ebrahimi HSPACE_CASES: RRETURN(MATCH_NOMATCH);
3091*22dc650dSSadaf Ebrahimi default: break;
3092*22dc650dSSadaf Ebrahimi }
3093*22dc650dSSadaf Ebrahimi }
3094*22dc650dSSadaf Ebrahimi break;
3095*22dc650dSSadaf Ebrahimi
3096*22dc650dSSadaf Ebrahimi case OP_HSPACE:
3097*22dc650dSSadaf Ebrahimi for (i = 1; i <= Lmin; i++)
3098*22dc650dSSadaf Ebrahimi {
3099*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
3100*22dc650dSSadaf Ebrahimi {
3101*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
3102*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
3103*22dc650dSSadaf Ebrahimi }
3104*22dc650dSSadaf Ebrahimi GETCHARINC(fc, Feptr);
3105*22dc650dSSadaf Ebrahimi switch(fc)
3106*22dc650dSSadaf Ebrahimi {
3107*22dc650dSSadaf Ebrahimi HSPACE_CASES: break;
3108*22dc650dSSadaf Ebrahimi default: RRETURN(MATCH_NOMATCH);
3109*22dc650dSSadaf Ebrahimi }
3110*22dc650dSSadaf Ebrahimi }
3111*22dc650dSSadaf Ebrahimi break;
3112*22dc650dSSadaf Ebrahimi
3113*22dc650dSSadaf Ebrahimi case OP_NOT_VSPACE:
3114*22dc650dSSadaf Ebrahimi for (i = 1; i <= Lmin; i++)
3115*22dc650dSSadaf Ebrahimi {
3116*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
3117*22dc650dSSadaf Ebrahimi {
3118*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
3119*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
3120*22dc650dSSadaf Ebrahimi }
3121*22dc650dSSadaf Ebrahimi GETCHARINC(fc, Feptr);
3122*22dc650dSSadaf Ebrahimi switch(fc)
3123*22dc650dSSadaf Ebrahimi {
3124*22dc650dSSadaf Ebrahimi VSPACE_CASES: RRETURN(MATCH_NOMATCH);
3125*22dc650dSSadaf Ebrahimi default: break;
3126*22dc650dSSadaf Ebrahimi }
3127*22dc650dSSadaf Ebrahimi }
3128*22dc650dSSadaf Ebrahimi break;
3129*22dc650dSSadaf Ebrahimi
3130*22dc650dSSadaf Ebrahimi case OP_VSPACE:
3131*22dc650dSSadaf Ebrahimi for (i = 1; i <= Lmin; i++)
3132*22dc650dSSadaf Ebrahimi {
3133*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
3134*22dc650dSSadaf Ebrahimi {
3135*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
3136*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
3137*22dc650dSSadaf Ebrahimi }
3138*22dc650dSSadaf Ebrahimi GETCHARINC(fc, Feptr);
3139*22dc650dSSadaf Ebrahimi switch(fc)
3140*22dc650dSSadaf Ebrahimi {
3141*22dc650dSSadaf Ebrahimi VSPACE_CASES: break;
3142*22dc650dSSadaf Ebrahimi default: RRETURN(MATCH_NOMATCH);
3143*22dc650dSSadaf Ebrahimi }
3144*22dc650dSSadaf Ebrahimi }
3145*22dc650dSSadaf Ebrahimi break;
3146*22dc650dSSadaf Ebrahimi
3147*22dc650dSSadaf Ebrahimi case OP_NOT_DIGIT:
3148*22dc650dSSadaf Ebrahimi for (i = 1; i <= Lmin; i++)
3149*22dc650dSSadaf Ebrahimi {
3150*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
3151*22dc650dSSadaf Ebrahimi {
3152*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
3153*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
3154*22dc650dSSadaf Ebrahimi }
3155*22dc650dSSadaf Ebrahimi GETCHARINC(fc, Feptr);
3156*22dc650dSSadaf Ebrahimi if (fc < 128 && (mb->ctypes[fc] & ctype_digit) != 0)
3157*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
3158*22dc650dSSadaf Ebrahimi }
3159*22dc650dSSadaf Ebrahimi break;
3160*22dc650dSSadaf Ebrahimi
3161*22dc650dSSadaf Ebrahimi case OP_DIGIT:
3162*22dc650dSSadaf Ebrahimi for (i = 1; i <= Lmin; i++)
3163*22dc650dSSadaf Ebrahimi {
3164*22dc650dSSadaf Ebrahimi uint32_t cc;
3165*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
3166*22dc650dSSadaf Ebrahimi {
3167*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
3168*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
3169*22dc650dSSadaf Ebrahimi }
3170*22dc650dSSadaf Ebrahimi cc = UCHAR21(Feptr);
3171*22dc650dSSadaf Ebrahimi if (cc >= 128 || (mb->ctypes[cc] & ctype_digit) == 0)
3172*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
3173*22dc650dSSadaf Ebrahimi Feptr++;
3174*22dc650dSSadaf Ebrahimi /* No need to skip more code units - we know it has only one. */
3175*22dc650dSSadaf Ebrahimi }
3176*22dc650dSSadaf Ebrahimi break;
3177*22dc650dSSadaf Ebrahimi
3178*22dc650dSSadaf Ebrahimi case OP_NOT_WHITESPACE:
3179*22dc650dSSadaf Ebrahimi for (i = 1; i <= Lmin; i++)
3180*22dc650dSSadaf Ebrahimi {
3181*22dc650dSSadaf Ebrahimi uint32_t cc;
3182*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
3183*22dc650dSSadaf Ebrahimi {
3184*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
3185*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
3186*22dc650dSSadaf Ebrahimi }
3187*22dc650dSSadaf Ebrahimi cc = UCHAR21(Feptr);
3188*22dc650dSSadaf Ebrahimi if (cc < 128 && (mb->ctypes[cc] & ctype_space) != 0)
3189*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
3190*22dc650dSSadaf Ebrahimi Feptr++;
3191*22dc650dSSadaf Ebrahimi ACROSSCHAR(Feptr < mb->end_subject, Feptr, Feptr++);
3192*22dc650dSSadaf Ebrahimi }
3193*22dc650dSSadaf Ebrahimi break;
3194*22dc650dSSadaf Ebrahimi
3195*22dc650dSSadaf Ebrahimi case OP_WHITESPACE:
3196*22dc650dSSadaf Ebrahimi for (i = 1; i <= Lmin; i++)
3197*22dc650dSSadaf Ebrahimi {
3198*22dc650dSSadaf Ebrahimi uint32_t cc;
3199*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
3200*22dc650dSSadaf Ebrahimi {
3201*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
3202*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
3203*22dc650dSSadaf Ebrahimi }
3204*22dc650dSSadaf Ebrahimi cc = UCHAR21(Feptr);
3205*22dc650dSSadaf Ebrahimi if (cc >= 128 || (mb->ctypes[cc] & ctype_space) == 0)
3206*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
3207*22dc650dSSadaf Ebrahimi Feptr++;
3208*22dc650dSSadaf Ebrahimi /* No need to skip more code units - we know it has only one. */
3209*22dc650dSSadaf Ebrahimi }
3210*22dc650dSSadaf Ebrahimi break;
3211*22dc650dSSadaf Ebrahimi
3212*22dc650dSSadaf Ebrahimi case OP_NOT_WORDCHAR:
3213*22dc650dSSadaf Ebrahimi for (i = 1; i <= Lmin; i++)
3214*22dc650dSSadaf Ebrahimi {
3215*22dc650dSSadaf Ebrahimi uint32_t cc;
3216*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
3217*22dc650dSSadaf Ebrahimi {
3218*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
3219*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
3220*22dc650dSSadaf Ebrahimi }
3221*22dc650dSSadaf Ebrahimi cc = UCHAR21(Feptr);
3222*22dc650dSSadaf Ebrahimi if (cc < 128 && (mb->ctypes[cc] & ctype_word) != 0)
3223*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
3224*22dc650dSSadaf Ebrahimi Feptr++;
3225*22dc650dSSadaf Ebrahimi ACROSSCHAR(Feptr < mb->end_subject, Feptr, Feptr++);
3226*22dc650dSSadaf Ebrahimi }
3227*22dc650dSSadaf Ebrahimi break;
3228*22dc650dSSadaf Ebrahimi
3229*22dc650dSSadaf Ebrahimi case OP_WORDCHAR:
3230*22dc650dSSadaf Ebrahimi for (i = 1; i <= Lmin; i++)
3231*22dc650dSSadaf Ebrahimi {
3232*22dc650dSSadaf Ebrahimi uint32_t cc;
3233*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
3234*22dc650dSSadaf Ebrahimi {
3235*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
3236*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
3237*22dc650dSSadaf Ebrahimi }
3238*22dc650dSSadaf Ebrahimi cc = UCHAR21(Feptr);
3239*22dc650dSSadaf Ebrahimi if (cc >= 128 || (mb->ctypes[cc] & ctype_word) == 0)
3240*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
3241*22dc650dSSadaf Ebrahimi Feptr++;
3242*22dc650dSSadaf Ebrahimi /* No need to skip more code units - we know it has only one. */
3243*22dc650dSSadaf Ebrahimi }
3244*22dc650dSSadaf Ebrahimi break;
3245*22dc650dSSadaf Ebrahimi
3246*22dc650dSSadaf Ebrahimi default:
3247*22dc650dSSadaf Ebrahimi return PCRE2_ERROR_INTERNAL;
3248*22dc650dSSadaf Ebrahimi } /* End switch(Lctype) */
3249*22dc650dSSadaf Ebrahimi
3250*22dc650dSSadaf Ebrahimi else
3251*22dc650dSSadaf Ebrahimi #endif /* SUPPORT_UNICODE */
3252*22dc650dSSadaf Ebrahimi
3253*22dc650dSSadaf Ebrahimi /* Code for the non-UTF case for minimum matching of operators other
3254*22dc650dSSadaf Ebrahimi than OP_PROP and OP_NOTPROP. */
3255*22dc650dSSadaf Ebrahimi
3256*22dc650dSSadaf Ebrahimi switch(Lctype)
3257*22dc650dSSadaf Ebrahimi {
3258*22dc650dSSadaf Ebrahimi case OP_ANY:
3259*22dc650dSSadaf Ebrahimi for (i = 1; i <= Lmin; i++)
3260*22dc650dSSadaf Ebrahimi {
3261*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
3262*22dc650dSSadaf Ebrahimi {
3263*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
3264*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
3265*22dc650dSSadaf Ebrahimi }
3266*22dc650dSSadaf Ebrahimi if (IS_NEWLINE(Feptr)) RRETURN(MATCH_NOMATCH);
3267*22dc650dSSadaf Ebrahimi if (mb->partial != 0 &&
3268*22dc650dSSadaf Ebrahimi Feptr + 1 >= mb->end_subject &&
3269*22dc650dSSadaf Ebrahimi NLBLOCK->nltype == NLTYPE_FIXED &&
3270*22dc650dSSadaf Ebrahimi NLBLOCK->nllen == 2 &&
3271*22dc650dSSadaf Ebrahimi *Feptr == NLBLOCK->nl[0])
3272*22dc650dSSadaf Ebrahimi {
3273*22dc650dSSadaf Ebrahimi mb->hitend = TRUE;
3274*22dc650dSSadaf Ebrahimi if (mb->partial > 1) return PCRE2_ERROR_PARTIAL;
3275*22dc650dSSadaf Ebrahimi }
3276*22dc650dSSadaf Ebrahimi Feptr++;
3277*22dc650dSSadaf Ebrahimi }
3278*22dc650dSSadaf Ebrahimi break;
3279*22dc650dSSadaf Ebrahimi
3280*22dc650dSSadaf Ebrahimi case OP_ALLANY:
3281*22dc650dSSadaf Ebrahimi if (Feptr > mb->end_subject - Lmin)
3282*22dc650dSSadaf Ebrahimi {
3283*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
3284*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
3285*22dc650dSSadaf Ebrahimi }
3286*22dc650dSSadaf Ebrahimi Feptr += Lmin;
3287*22dc650dSSadaf Ebrahimi break;
3288*22dc650dSSadaf Ebrahimi
3289*22dc650dSSadaf Ebrahimi /* This OP_ANYBYTE case will never be reached because \C gets turned
3290*22dc650dSSadaf Ebrahimi into OP_ALLANY in non-UTF mode. Cut out the code so that coverage
3291*22dc650dSSadaf Ebrahimi reports don't complain about it's never being used. */
3292*22dc650dSSadaf Ebrahimi
3293*22dc650dSSadaf Ebrahimi /* case OP_ANYBYTE:
3294*22dc650dSSadaf Ebrahimi * if (Feptr > mb->end_subject - Lmin)
3295*22dc650dSSadaf Ebrahimi * {
3296*22dc650dSSadaf Ebrahimi * SCHECK_PARTIAL();
3297*22dc650dSSadaf Ebrahimi * RRETURN(MATCH_NOMATCH);
3298*22dc650dSSadaf Ebrahimi * }
3299*22dc650dSSadaf Ebrahimi * Feptr += Lmin;
3300*22dc650dSSadaf Ebrahimi * break;
3301*22dc650dSSadaf Ebrahimi */
3302*22dc650dSSadaf Ebrahimi case OP_ANYNL:
3303*22dc650dSSadaf Ebrahimi for (i = 1; i <= Lmin; i++)
3304*22dc650dSSadaf Ebrahimi {
3305*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
3306*22dc650dSSadaf Ebrahimi {
3307*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
3308*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
3309*22dc650dSSadaf Ebrahimi }
3310*22dc650dSSadaf Ebrahimi switch(*Feptr++)
3311*22dc650dSSadaf Ebrahimi {
3312*22dc650dSSadaf Ebrahimi default: RRETURN(MATCH_NOMATCH);
3313*22dc650dSSadaf Ebrahimi
3314*22dc650dSSadaf Ebrahimi case CHAR_CR:
3315*22dc650dSSadaf Ebrahimi if (Feptr < mb->end_subject && *Feptr == CHAR_LF) Feptr++;
3316*22dc650dSSadaf Ebrahimi break;
3317*22dc650dSSadaf Ebrahimi
3318*22dc650dSSadaf Ebrahimi case CHAR_LF:
3319*22dc650dSSadaf Ebrahimi break;
3320*22dc650dSSadaf Ebrahimi
3321*22dc650dSSadaf Ebrahimi case CHAR_VT:
3322*22dc650dSSadaf Ebrahimi case CHAR_FF:
3323*22dc650dSSadaf Ebrahimi case CHAR_NEL:
3324*22dc650dSSadaf Ebrahimi #if PCRE2_CODE_UNIT_WIDTH != 8
3325*22dc650dSSadaf Ebrahimi case 0x2028:
3326*22dc650dSSadaf Ebrahimi case 0x2029:
3327*22dc650dSSadaf Ebrahimi #endif
3328*22dc650dSSadaf Ebrahimi if (mb->bsr_convention == PCRE2_BSR_ANYCRLF) RRETURN(MATCH_NOMATCH);
3329*22dc650dSSadaf Ebrahimi break;
3330*22dc650dSSadaf Ebrahimi }
3331*22dc650dSSadaf Ebrahimi }
3332*22dc650dSSadaf Ebrahimi break;
3333*22dc650dSSadaf Ebrahimi
3334*22dc650dSSadaf Ebrahimi case OP_NOT_HSPACE:
3335*22dc650dSSadaf Ebrahimi for (i = 1; i <= Lmin; i++)
3336*22dc650dSSadaf Ebrahimi {
3337*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
3338*22dc650dSSadaf Ebrahimi {
3339*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
3340*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
3341*22dc650dSSadaf Ebrahimi }
3342*22dc650dSSadaf Ebrahimi switch(*Feptr++)
3343*22dc650dSSadaf Ebrahimi {
3344*22dc650dSSadaf Ebrahimi default: break;
3345*22dc650dSSadaf Ebrahimi HSPACE_BYTE_CASES:
3346*22dc650dSSadaf Ebrahimi #if PCRE2_CODE_UNIT_WIDTH != 8
3347*22dc650dSSadaf Ebrahimi HSPACE_MULTIBYTE_CASES:
3348*22dc650dSSadaf Ebrahimi #endif
3349*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
3350*22dc650dSSadaf Ebrahimi }
3351*22dc650dSSadaf Ebrahimi }
3352*22dc650dSSadaf Ebrahimi break;
3353*22dc650dSSadaf Ebrahimi
3354*22dc650dSSadaf Ebrahimi case OP_HSPACE:
3355*22dc650dSSadaf Ebrahimi for (i = 1; i <= Lmin; i++)
3356*22dc650dSSadaf Ebrahimi {
3357*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
3358*22dc650dSSadaf Ebrahimi {
3359*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
3360*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
3361*22dc650dSSadaf Ebrahimi }
3362*22dc650dSSadaf Ebrahimi switch(*Feptr++)
3363*22dc650dSSadaf Ebrahimi {
3364*22dc650dSSadaf Ebrahimi default: RRETURN(MATCH_NOMATCH);
3365*22dc650dSSadaf Ebrahimi HSPACE_BYTE_CASES:
3366*22dc650dSSadaf Ebrahimi #if PCRE2_CODE_UNIT_WIDTH != 8
3367*22dc650dSSadaf Ebrahimi HSPACE_MULTIBYTE_CASES:
3368*22dc650dSSadaf Ebrahimi #endif
3369*22dc650dSSadaf Ebrahimi break;
3370*22dc650dSSadaf Ebrahimi }
3371*22dc650dSSadaf Ebrahimi }
3372*22dc650dSSadaf Ebrahimi break;
3373*22dc650dSSadaf Ebrahimi
3374*22dc650dSSadaf Ebrahimi case OP_NOT_VSPACE:
3375*22dc650dSSadaf Ebrahimi for (i = 1; i <= Lmin; i++)
3376*22dc650dSSadaf Ebrahimi {
3377*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
3378*22dc650dSSadaf Ebrahimi {
3379*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
3380*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
3381*22dc650dSSadaf Ebrahimi }
3382*22dc650dSSadaf Ebrahimi switch(*Feptr++)
3383*22dc650dSSadaf Ebrahimi {
3384*22dc650dSSadaf Ebrahimi VSPACE_BYTE_CASES:
3385*22dc650dSSadaf Ebrahimi #if PCRE2_CODE_UNIT_WIDTH != 8
3386*22dc650dSSadaf Ebrahimi VSPACE_MULTIBYTE_CASES:
3387*22dc650dSSadaf Ebrahimi #endif
3388*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
3389*22dc650dSSadaf Ebrahimi default: break;
3390*22dc650dSSadaf Ebrahimi }
3391*22dc650dSSadaf Ebrahimi }
3392*22dc650dSSadaf Ebrahimi break;
3393*22dc650dSSadaf Ebrahimi
3394*22dc650dSSadaf Ebrahimi case OP_VSPACE:
3395*22dc650dSSadaf Ebrahimi for (i = 1; i <= Lmin; i++)
3396*22dc650dSSadaf Ebrahimi {
3397*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
3398*22dc650dSSadaf Ebrahimi {
3399*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
3400*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
3401*22dc650dSSadaf Ebrahimi }
3402*22dc650dSSadaf Ebrahimi switch(*Feptr++)
3403*22dc650dSSadaf Ebrahimi {
3404*22dc650dSSadaf Ebrahimi default: RRETURN(MATCH_NOMATCH);
3405*22dc650dSSadaf Ebrahimi VSPACE_BYTE_CASES:
3406*22dc650dSSadaf Ebrahimi #if PCRE2_CODE_UNIT_WIDTH != 8
3407*22dc650dSSadaf Ebrahimi VSPACE_MULTIBYTE_CASES:
3408*22dc650dSSadaf Ebrahimi #endif
3409*22dc650dSSadaf Ebrahimi break;
3410*22dc650dSSadaf Ebrahimi }
3411*22dc650dSSadaf Ebrahimi }
3412*22dc650dSSadaf Ebrahimi break;
3413*22dc650dSSadaf Ebrahimi
3414*22dc650dSSadaf Ebrahimi case OP_NOT_DIGIT:
3415*22dc650dSSadaf Ebrahimi for (i = 1; i <= Lmin; i++)
3416*22dc650dSSadaf Ebrahimi {
3417*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
3418*22dc650dSSadaf Ebrahimi {
3419*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
3420*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
3421*22dc650dSSadaf Ebrahimi }
3422*22dc650dSSadaf Ebrahimi if (MAX_255(*Feptr) && (mb->ctypes[*Feptr] & ctype_digit) != 0)
3423*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
3424*22dc650dSSadaf Ebrahimi Feptr++;
3425*22dc650dSSadaf Ebrahimi }
3426*22dc650dSSadaf Ebrahimi break;
3427*22dc650dSSadaf Ebrahimi
3428*22dc650dSSadaf Ebrahimi case OP_DIGIT:
3429*22dc650dSSadaf Ebrahimi for (i = 1; i <= Lmin; i++)
3430*22dc650dSSadaf Ebrahimi {
3431*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
3432*22dc650dSSadaf Ebrahimi {
3433*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
3434*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
3435*22dc650dSSadaf Ebrahimi }
3436*22dc650dSSadaf Ebrahimi if (!MAX_255(*Feptr) || (mb->ctypes[*Feptr] & ctype_digit) == 0)
3437*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
3438*22dc650dSSadaf Ebrahimi Feptr++;
3439*22dc650dSSadaf Ebrahimi }
3440*22dc650dSSadaf Ebrahimi break;
3441*22dc650dSSadaf Ebrahimi
3442*22dc650dSSadaf Ebrahimi case OP_NOT_WHITESPACE:
3443*22dc650dSSadaf Ebrahimi for (i = 1; i <= Lmin; i++)
3444*22dc650dSSadaf Ebrahimi {
3445*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
3446*22dc650dSSadaf Ebrahimi {
3447*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
3448*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
3449*22dc650dSSadaf Ebrahimi }
3450*22dc650dSSadaf Ebrahimi if (MAX_255(*Feptr) && (mb->ctypes[*Feptr] & ctype_space) != 0)
3451*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
3452*22dc650dSSadaf Ebrahimi Feptr++;
3453*22dc650dSSadaf Ebrahimi }
3454*22dc650dSSadaf Ebrahimi break;
3455*22dc650dSSadaf Ebrahimi
3456*22dc650dSSadaf Ebrahimi case OP_WHITESPACE:
3457*22dc650dSSadaf Ebrahimi for (i = 1; i <= Lmin; i++)
3458*22dc650dSSadaf Ebrahimi {
3459*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
3460*22dc650dSSadaf Ebrahimi {
3461*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
3462*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
3463*22dc650dSSadaf Ebrahimi }
3464*22dc650dSSadaf Ebrahimi if (!MAX_255(*Feptr) || (mb->ctypes[*Feptr] & ctype_space) == 0)
3465*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
3466*22dc650dSSadaf Ebrahimi Feptr++;
3467*22dc650dSSadaf Ebrahimi }
3468*22dc650dSSadaf Ebrahimi break;
3469*22dc650dSSadaf Ebrahimi
3470*22dc650dSSadaf Ebrahimi case OP_NOT_WORDCHAR:
3471*22dc650dSSadaf Ebrahimi for (i = 1; i <= Lmin; i++)
3472*22dc650dSSadaf Ebrahimi {
3473*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
3474*22dc650dSSadaf Ebrahimi {
3475*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
3476*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
3477*22dc650dSSadaf Ebrahimi }
3478*22dc650dSSadaf Ebrahimi if (MAX_255(*Feptr) && (mb->ctypes[*Feptr] & ctype_word) != 0)
3479*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
3480*22dc650dSSadaf Ebrahimi Feptr++;
3481*22dc650dSSadaf Ebrahimi }
3482*22dc650dSSadaf Ebrahimi break;
3483*22dc650dSSadaf Ebrahimi
3484*22dc650dSSadaf Ebrahimi case OP_WORDCHAR:
3485*22dc650dSSadaf Ebrahimi for (i = 1; i <= Lmin; i++)
3486*22dc650dSSadaf Ebrahimi {
3487*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
3488*22dc650dSSadaf Ebrahimi {
3489*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
3490*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
3491*22dc650dSSadaf Ebrahimi }
3492*22dc650dSSadaf Ebrahimi if (!MAX_255(*Feptr) || (mb->ctypes[*Feptr] & ctype_word) == 0)
3493*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
3494*22dc650dSSadaf Ebrahimi Feptr++;
3495*22dc650dSSadaf Ebrahimi }
3496*22dc650dSSadaf Ebrahimi break;
3497*22dc650dSSadaf Ebrahimi
3498*22dc650dSSadaf Ebrahimi default:
3499*22dc650dSSadaf Ebrahimi return PCRE2_ERROR_INTERNAL;
3500*22dc650dSSadaf Ebrahimi }
3501*22dc650dSSadaf Ebrahimi }
3502*22dc650dSSadaf Ebrahimi
3503*22dc650dSSadaf Ebrahimi /* If Lmin = Lmax we are done. Continue with the main loop. */
3504*22dc650dSSadaf Ebrahimi
3505*22dc650dSSadaf Ebrahimi if (Lmin == Lmax) continue;
3506*22dc650dSSadaf Ebrahimi
3507*22dc650dSSadaf Ebrahimi /* If minimizing, we have to test the rest of the pattern before each
3508*22dc650dSSadaf Ebrahimi subsequent match. This means we cannot use a local "notmatch" variable as
3509*22dc650dSSadaf Ebrahimi in the other cases. As all 4 temporary 32-bit values in the frame are
3510*22dc650dSSadaf Ebrahimi already in use, just test the type each time. */
3511*22dc650dSSadaf Ebrahimi
3512*22dc650dSSadaf Ebrahimi if (reptype == REPTYPE_MIN)
3513*22dc650dSSadaf Ebrahimi {
3514*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_UNICODE
3515*22dc650dSSadaf Ebrahimi if (proptype >= 0)
3516*22dc650dSSadaf Ebrahimi {
3517*22dc650dSSadaf Ebrahimi switch(proptype)
3518*22dc650dSSadaf Ebrahimi {
3519*22dc650dSSadaf Ebrahimi case PT_ANY:
3520*22dc650dSSadaf Ebrahimi for (;;)
3521*22dc650dSSadaf Ebrahimi {
3522*22dc650dSSadaf Ebrahimi RMATCH(Fecode, RM208);
3523*22dc650dSSadaf Ebrahimi if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3524*22dc650dSSadaf Ebrahimi if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH);
3525*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
3526*22dc650dSSadaf Ebrahimi {
3527*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
3528*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
3529*22dc650dSSadaf Ebrahimi }
3530*22dc650dSSadaf Ebrahimi GETCHARINCTEST(fc, Feptr);
3531*22dc650dSSadaf Ebrahimi if (Lctype == OP_NOTPROP) RRETURN(MATCH_NOMATCH);
3532*22dc650dSSadaf Ebrahimi }
3533*22dc650dSSadaf Ebrahimi /* Control never gets here */
3534*22dc650dSSadaf Ebrahimi
3535*22dc650dSSadaf Ebrahimi case PT_LAMP:
3536*22dc650dSSadaf Ebrahimi for (;;)
3537*22dc650dSSadaf Ebrahimi {
3538*22dc650dSSadaf Ebrahimi int chartype;
3539*22dc650dSSadaf Ebrahimi RMATCH(Fecode, RM209);
3540*22dc650dSSadaf Ebrahimi if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3541*22dc650dSSadaf Ebrahimi if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH);
3542*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
3543*22dc650dSSadaf Ebrahimi {
3544*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
3545*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
3546*22dc650dSSadaf Ebrahimi }
3547*22dc650dSSadaf Ebrahimi GETCHARINCTEST(fc, Feptr);
3548*22dc650dSSadaf Ebrahimi chartype = UCD_CHARTYPE(fc);
3549*22dc650dSSadaf Ebrahimi if ((chartype == ucp_Lu ||
3550*22dc650dSSadaf Ebrahimi chartype == ucp_Ll ||
3551*22dc650dSSadaf Ebrahimi chartype == ucp_Lt) == (Lctype == OP_NOTPROP))
3552*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
3553*22dc650dSSadaf Ebrahimi }
3554*22dc650dSSadaf Ebrahimi /* Control never gets here */
3555*22dc650dSSadaf Ebrahimi
3556*22dc650dSSadaf Ebrahimi case PT_GC:
3557*22dc650dSSadaf Ebrahimi for (;;)
3558*22dc650dSSadaf Ebrahimi {
3559*22dc650dSSadaf Ebrahimi RMATCH(Fecode, RM210);
3560*22dc650dSSadaf Ebrahimi if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3561*22dc650dSSadaf Ebrahimi if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH);
3562*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
3563*22dc650dSSadaf Ebrahimi {
3564*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
3565*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
3566*22dc650dSSadaf Ebrahimi }
3567*22dc650dSSadaf Ebrahimi GETCHARINCTEST(fc, Feptr);
3568*22dc650dSSadaf Ebrahimi if ((UCD_CATEGORY(fc) == Lpropvalue) == (Lctype == OP_NOTPROP))
3569*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
3570*22dc650dSSadaf Ebrahimi }
3571*22dc650dSSadaf Ebrahimi /* Control never gets here */
3572*22dc650dSSadaf Ebrahimi
3573*22dc650dSSadaf Ebrahimi case PT_PC:
3574*22dc650dSSadaf Ebrahimi for (;;)
3575*22dc650dSSadaf Ebrahimi {
3576*22dc650dSSadaf Ebrahimi RMATCH(Fecode, RM211);
3577*22dc650dSSadaf Ebrahimi if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3578*22dc650dSSadaf Ebrahimi if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH);
3579*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
3580*22dc650dSSadaf Ebrahimi {
3581*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
3582*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
3583*22dc650dSSadaf Ebrahimi }
3584*22dc650dSSadaf Ebrahimi GETCHARINCTEST(fc, Feptr);
3585*22dc650dSSadaf Ebrahimi if ((UCD_CHARTYPE(fc) == Lpropvalue) == (Lctype == OP_NOTPROP))
3586*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
3587*22dc650dSSadaf Ebrahimi }
3588*22dc650dSSadaf Ebrahimi /* Control never gets here */
3589*22dc650dSSadaf Ebrahimi
3590*22dc650dSSadaf Ebrahimi case PT_SC:
3591*22dc650dSSadaf Ebrahimi for (;;)
3592*22dc650dSSadaf Ebrahimi {
3593*22dc650dSSadaf Ebrahimi RMATCH(Fecode, RM212);
3594*22dc650dSSadaf Ebrahimi if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3595*22dc650dSSadaf Ebrahimi if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH);
3596*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
3597*22dc650dSSadaf Ebrahimi {
3598*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
3599*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
3600*22dc650dSSadaf Ebrahimi }
3601*22dc650dSSadaf Ebrahimi GETCHARINCTEST(fc, Feptr);
3602*22dc650dSSadaf Ebrahimi if ((UCD_SCRIPT(fc) == Lpropvalue) == (Lctype == OP_NOTPROP))
3603*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
3604*22dc650dSSadaf Ebrahimi }
3605*22dc650dSSadaf Ebrahimi /* Control never gets here */
3606*22dc650dSSadaf Ebrahimi
3607*22dc650dSSadaf Ebrahimi case PT_SCX:
3608*22dc650dSSadaf Ebrahimi for (;;)
3609*22dc650dSSadaf Ebrahimi {
3610*22dc650dSSadaf Ebrahimi BOOL ok;
3611*22dc650dSSadaf Ebrahimi const ucd_record *prop;
3612*22dc650dSSadaf Ebrahimi RMATCH(Fecode, RM225);
3613*22dc650dSSadaf Ebrahimi if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3614*22dc650dSSadaf Ebrahimi if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH);
3615*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
3616*22dc650dSSadaf Ebrahimi {
3617*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
3618*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
3619*22dc650dSSadaf Ebrahimi }
3620*22dc650dSSadaf Ebrahimi GETCHARINCTEST(fc, Feptr);
3621*22dc650dSSadaf Ebrahimi prop = GET_UCD(fc);
3622*22dc650dSSadaf Ebrahimi ok = (prop->script == Lpropvalue
3623*22dc650dSSadaf Ebrahimi || MAPBIT(PRIV(ucd_script_sets) + UCD_SCRIPTX_PROP(prop), Lpropvalue) != 0);
3624*22dc650dSSadaf Ebrahimi if (ok == (Lctype == OP_NOTPROP))
3625*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
3626*22dc650dSSadaf Ebrahimi }
3627*22dc650dSSadaf Ebrahimi /* Control never gets here */
3628*22dc650dSSadaf Ebrahimi
3629*22dc650dSSadaf Ebrahimi case PT_ALNUM:
3630*22dc650dSSadaf Ebrahimi for (;;)
3631*22dc650dSSadaf Ebrahimi {
3632*22dc650dSSadaf Ebrahimi int category;
3633*22dc650dSSadaf Ebrahimi RMATCH(Fecode, RM213);
3634*22dc650dSSadaf Ebrahimi if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3635*22dc650dSSadaf Ebrahimi if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH);
3636*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
3637*22dc650dSSadaf Ebrahimi {
3638*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
3639*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
3640*22dc650dSSadaf Ebrahimi }
3641*22dc650dSSadaf Ebrahimi GETCHARINCTEST(fc, Feptr);
3642*22dc650dSSadaf Ebrahimi category = UCD_CATEGORY(fc);
3643*22dc650dSSadaf Ebrahimi if ((category == ucp_L || category == ucp_N) == (Lctype == OP_NOTPROP))
3644*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
3645*22dc650dSSadaf Ebrahimi }
3646*22dc650dSSadaf Ebrahimi /* Control never gets here */
3647*22dc650dSSadaf Ebrahimi
3648*22dc650dSSadaf Ebrahimi /* Perl space used to exclude VT, but from Perl 5.18 it is included,
3649*22dc650dSSadaf Ebrahimi which means that Perl space and POSIX space are now identical. PCRE
3650*22dc650dSSadaf Ebrahimi was changed at release 8.34. */
3651*22dc650dSSadaf Ebrahimi
3652*22dc650dSSadaf Ebrahimi case PT_SPACE: /* Perl space */
3653*22dc650dSSadaf Ebrahimi case PT_PXSPACE: /* POSIX space */
3654*22dc650dSSadaf Ebrahimi for (;;)
3655*22dc650dSSadaf Ebrahimi {
3656*22dc650dSSadaf Ebrahimi RMATCH(Fecode, RM214);
3657*22dc650dSSadaf Ebrahimi if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3658*22dc650dSSadaf Ebrahimi if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH);
3659*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
3660*22dc650dSSadaf Ebrahimi {
3661*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
3662*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
3663*22dc650dSSadaf Ebrahimi }
3664*22dc650dSSadaf Ebrahimi GETCHARINCTEST(fc, Feptr);
3665*22dc650dSSadaf Ebrahimi switch(fc)
3666*22dc650dSSadaf Ebrahimi {
3667*22dc650dSSadaf Ebrahimi HSPACE_CASES:
3668*22dc650dSSadaf Ebrahimi VSPACE_CASES:
3669*22dc650dSSadaf Ebrahimi if (Lctype == OP_NOTPROP) RRETURN(MATCH_NOMATCH);
3670*22dc650dSSadaf Ebrahimi break;
3671*22dc650dSSadaf Ebrahimi
3672*22dc650dSSadaf Ebrahimi default:
3673*22dc650dSSadaf Ebrahimi if ((UCD_CATEGORY(fc) == ucp_Z) == (Lctype == OP_NOTPROP))
3674*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
3675*22dc650dSSadaf Ebrahimi break;
3676*22dc650dSSadaf Ebrahimi }
3677*22dc650dSSadaf Ebrahimi }
3678*22dc650dSSadaf Ebrahimi /* Control never gets here */
3679*22dc650dSSadaf Ebrahimi
3680*22dc650dSSadaf Ebrahimi case PT_WORD:
3681*22dc650dSSadaf Ebrahimi for (;;)
3682*22dc650dSSadaf Ebrahimi {
3683*22dc650dSSadaf Ebrahimi int chartype, category;
3684*22dc650dSSadaf Ebrahimi RMATCH(Fecode, RM215);
3685*22dc650dSSadaf Ebrahimi if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3686*22dc650dSSadaf Ebrahimi if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH);
3687*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
3688*22dc650dSSadaf Ebrahimi {
3689*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
3690*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
3691*22dc650dSSadaf Ebrahimi }
3692*22dc650dSSadaf Ebrahimi GETCHARINCTEST(fc, Feptr);
3693*22dc650dSSadaf Ebrahimi chartype = UCD_CHARTYPE(fc);
3694*22dc650dSSadaf Ebrahimi category = PRIV(ucp_gentype)[chartype];
3695*22dc650dSSadaf Ebrahimi if ((category == ucp_L ||
3696*22dc650dSSadaf Ebrahimi category == ucp_N ||
3697*22dc650dSSadaf Ebrahimi chartype == ucp_Mn ||
3698*22dc650dSSadaf Ebrahimi chartype == ucp_Pc) == (Lctype == OP_NOTPROP))
3699*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
3700*22dc650dSSadaf Ebrahimi }
3701*22dc650dSSadaf Ebrahimi /* Control never gets here */
3702*22dc650dSSadaf Ebrahimi
3703*22dc650dSSadaf Ebrahimi case PT_CLIST:
3704*22dc650dSSadaf Ebrahimi for (;;)
3705*22dc650dSSadaf Ebrahimi {
3706*22dc650dSSadaf Ebrahimi const uint32_t *cp;
3707*22dc650dSSadaf Ebrahimi RMATCH(Fecode, RM216);
3708*22dc650dSSadaf Ebrahimi if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3709*22dc650dSSadaf Ebrahimi if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH);
3710*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
3711*22dc650dSSadaf Ebrahimi {
3712*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
3713*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
3714*22dc650dSSadaf Ebrahimi }
3715*22dc650dSSadaf Ebrahimi GETCHARINCTEST(fc, Feptr);
3716*22dc650dSSadaf Ebrahimi #if PCRE2_CODE_UNIT_WIDTH == 32
3717*22dc650dSSadaf Ebrahimi if (fc > MAX_UTF_CODE_POINT)
3718*22dc650dSSadaf Ebrahimi {
3719*22dc650dSSadaf Ebrahimi if (Lctype == OP_NOTPROP) continue;
3720*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
3721*22dc650dSSadaf Ebrahimi }
3722*22dc650dSSadaf Ebrahimi #endif
3723*22dc650dSSadaf Ebrahimi cp = PRIV(ucd_caseless_sets) + Lpropvalue;
3724*22dc650dSSadaf Ebrahimi for (;;)
3725*22dc650dSSadaf Ebrahimi {
3726*22dc650dSSadaf Ebrahimi if (fc < *cp)
3727*22dc650dSSadaf Ebrahimi {
3728*22dc650dSSadaf Ebrahimi if (Lctype == OP_NOTPROP) break;
3729*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
3730*22dc650dSSadaf Ebrahimi }
3731*22dc650dSSadaf Ebrahimi if (fc == *cp++)
3732*22dc650dSSadaf Ebrahimi {
3733*22dc650dSSadaf Ebrahimi if (Lctype == OP_NOTPROP) RRETURN(MATCH_NOMATCH);
3734*22dc650dSSadaf Ebrahimi break;
3735*22dc650dSSadaf Ebrahimi }
3736*22dc650dSSadaf Ebrahimi }
3737*22dc650dSSadaf Ebrahimi }
3738*22dc650dSSadaf Ebrahimi /* Control never gets here */
3739*22dc650dSSadaf Ebrahimi
3740*22dc650dSSadaf Ebrahimi case PT_UCNC:
3741*22dc650dSSadaf Ebrahimi for (;;)
3742*22dc650dSSadaf Ebrahimi {
3743*22dc650dSSadaf Ebrahimi RMATCH(Fecode, RM217);
3744*22dc650dSSadaf Ebrahimi if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3745*22dc650dSSadaf Ebrahimi if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH);
3746*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
3747*22dc650dSSadaf Ebrahimi {
3748*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
3749*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
3750*22dc650dSSadaf Ebrahimi }
3751*22dc650dSSadaf Ebrahimi GETCHARINCTEST(fc, Feptr);
3752*22dc650dSSadaf Ebrahimi if ((fc == CHAR_DOLLAR_SIGN || fc == CHAR_COMMERCIAL_AT ||
3753*22dc650dSSadaf Ebrahimi fc == CHAR_GRAVE_ACCENT || (fc >= 0xa0 && fc <= 0xd7ff) ||
3754*22dc650dSSadaf Ebrahimi fc >= 0xe000) == (Lctype == OP_NOTPROP))
3755*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
3756*22dc650dSSadaf Ebrahimi }
3757*22dc650dSSadaf Ebrahimi /* Control never gets here */
3758*22dc650dSSadaf Ebrahimi
3759*22dc650dSSadaf Ebrahimi case PT_BIDICL:
3760*22dc650dSSadaf Ebrahimi for (;;)
3761*22dc650dSSadaf Ebrahimi {
3762*22dc650dSSadaf Ebrahimi RMATCH(Fecode, RM224);
3763*22dc650dSSadaf Ebrahimi if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3764*22dc650dSSadaf Ebrahimi if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH);
3765*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
3766*22dc650dSSadaf Ebrahimi {
3767*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
3768*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
3769*22dc650dSSadaf Ebrahimi }
3770*22dc650dSSadaf Ebrahimi GETCHARINCTEST(fc, Feptr);
3771*22dc650dSSadaf Ebrahimi if ((UCD_BIDICLASS(fc) == Lpropvalue) == (Lctype == OP_NOTPROP))
3772*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
3773*22dc650dSSadaf Ebrahimi }
3774*22dc650dSSadaf Ebrahimi /* Control never gets here */
3775*22dc650dSSadaf Ebrahimi
3776*22dc650dSSadaf Ebrahimi case PT_BOOL:
3777*22dc650dSSadaf Ebrahimi for (;;)
3778*22dc650dSSadaf Ebrahimi {
3779*22dc650dSSadaf Ebrahimi BOOL ok;
3780*22dc650dSSadaf Ebrahimi const ucd_record *prop;
3781*22dc650dSSadaf Ebrahimi RMATCH(Fecode, RM223);
3782*22dc650dSSadaf Ebrahimi if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3783*22dc650dSSadaf Ebrahimi if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH);
3784*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
3785*22dc650dSSadaf Ebrahimi {
3786*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
3787*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
3788*22dc650dSSadaf Ebrahimi }
3789*22dc650dSSadaf Ebrahimi GETCHARINCTEST(fc, Feptr);
3790*22dc650dSSadaf Ebrahimi prop = GET_UCD(fc);
3791*22dc650dSSadaf Ebrahimi ok = MAPBIT(PRIV(ucd_boolprop_sets) +
3792*22dc650dSSadaf Ebrahimi UCD_BPROPS_PROP(prop), Lpropvalue) != 0;
3793*22dc650dSSadaf Ebrahimi if (ok == (Lctype == OP_NOTPROP))
3794*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
3795*22dc650dSSadaf Ebrahimi }
3796*22dc650dSSadaf Ebrahimi /* Control never gets here */
3797*22dc650dSSadaf Ebrahimi
3798*22dc650dSSadaf Ebrahimi /* This should never occur */
3799*22dc650dSSadaf Ebrahimi default:
3800*22dc650dSSadaf Ebrahimi return PCRE2_ERROR_INTERNAL;
3801*22dc650dSSadaf Ebrahimi }
3802*22dc650dSSadaf Ebrahimi }
3803*22dc650dSSadaf Ebrahimi
3804*22dc650dSSadaf Ebrahimi /* Match extended Unicode sequences. We will get here only if the
3805*22dc650dSSadaf Ebrahimi support is in the binary; otherwise a compile-time error occurs. */
3806*22dc650dSSadaf Ebrahimi
3807*22dc650dSSadaf Ebrahimi else if (Lctype == OP_EXTUNI)
3808*22dc650dSSadaf Ebrahimi {
3809*22dc650dSSadaf Ebrahimi for (;;)
3810*22dc650dSSadaf Ebrahimi {
3811*22dc650dSSadaf Ebrahimi RMATCH(Fecode, RM218);
3812*22dc650dSSadaf Ebrahimi if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3813*22dc650dSSadaf Ebrahimi if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH);
3814*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
3815*22dc650dSSadaf Ebrahimi {
3816*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
3817*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
3818*22dc650dSSadaf Ebrahimi }
3819*22dc650dSSadaf Ebrahimi else
3820*22dc650dSSadaf Ebrahimi {
3821*22dc650dSSadaf Ebrahimi GETCHARINCTEST(fc, Feptr);
3822*22dc650dSSadaf Ebrahimi Feptr = PRIV(extuni)(fc, Feptr, mb->start_subject, mb->end_subject,
3823*22dc650dSSadaf Ebrahimi utf, NULL);
3824*22dc650dSSadaf Ebrahimi }
3825*22dc650dSSadaf Ebrahimi CHECK_PARTIAL();
3826*22dc650dSSadaf Ebrahimi }
3827*22dc650dSSadaf Ebrahimi }
3828*22dc650dSSadaf Ebrahimi else
3829*22dc650dSSadaf Ebrahimi #endif /* SUPPORT_UNICODE */
3830*22dc650dSSadaf Ebrahimi
3831*22dc650dSSadaf Ebrahimi /* UTF mode for non-property testing character types. */
3832*22dc650dSSadaf Ebrahimi
3833*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_UNICODE
3834*22dc650dSSadaf Ebrahimi if (utf)
3835*22dc650dSSadaf Ebrahimi {
3836*22dc650dSSadaf Ebrahimi for (;;)
3837*22dc650dSSadaf Ebrahimi {
3838*22dc650dSSadaf Ebrahimi RMATCH(Fecode, RM219);
3839*22dc650dSSadaf Ebrahimi if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3840*22dc650dSSadaf Ebrahimi if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH);
3841*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
3842*22dc650dSSadaf Ebrahimi {
3843*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
3844*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
3845*22dc650dSSadaf Ebrahimi }
3846*22dc650dSSadaf Ebrahimi if (Lctype == OP_ANY && IS_NEWLINE(Feptr)) RRETURN(MATCH_NOMATCH);
3847*22dc650dSSadaf Ebrahimi GETCHARINC(fc, Feptr);
3848*22dc650dSSadaf Ebrahimi switch(Lctype)
3849*22dc650dSSadaf Ebrahimi {
3850*22dc650dSSadaf Ebrahimi case OP_ANY: /* This is the non-NL case */
3851*22dc650dSSadaf Ebrahimi if (mb->partial != 0 && /* Take care with CRLF partial */
3852*22dc650dSSadaf Ebrahimi Feptr >= mb->end_subject &&
3853*22dc650dSSadaf Ebrahimi NLBLOCK->nltype == NLTYPE_FIXED &&
3854*22dc650dSSadaf Ebrahimi NLBLOCK->nllen == 2 &&
3855*22dc650dSSadaf Ebrahimi fc == NLBLOCK->nl[0])
3856*22dc650dSSadaf Ebrahimi {
3857*22dc650dSSadaf Ebrahimi mb->hitend = TRUE;
3858*22dc650dSSadaf Ebrahimi if (mb->partial > 1) return PCRE2_ERROR_PARTIAL;
3859*22dc650dSSadaf Ebrahimi }
3860*22dc650dSSadaf Ebrahimi break;
3861*22dc650dSSadaf Ebrahimi
3862*22dc650dSSadaf Ebrahimi case OP_ALLANY:
3863*22dc650dSSadaf Ebrahimi case OP_ANYBYTE:
3864*22dc650dSSadaf Ebrahimi break;
3865*22dc650dSSadaf Ebrahimi
3866*22dc650dSSadaf Ebrahimi case OP_ANYNL:
3867*22dc650dSSadaf Ebrahimi switch(fc)
3868*22dc650dSSadaf Ebrahimi {
3869*22dc650dSSadaf Ebrahimi default: RRETURN(MATCH_NOMATCH);
3870*22dc650dSSadaf Ebrahimi
3871*22dc650dSSadaf Ebrahimi case CHAR_CR:
3872*22dc650dSSadaf Ebrahimi if (Feptr < mb->end_subject && UCHAR21(Feptr) == CHAR_LF) Feptr++;
3873*22dc650dSSadaf Ebrahimi break;
3874*22dc650dSSadaf Ebrahimi
3875*22dc650dSSadaf Ebrahimi case CHAR_LF:
3876*22dc650dSSadaf Ebrahimi break;
3877*22dc650dSSadaf Ebrahimi
3878*22dc650dSSadaf Ebrahimi case CHAR_VT:
3879*22dc650dSSadaf Ebrahimi case CHAR_FF:
3880*22dc650dSSadaf Ebrahimi case CHAR_NEL:
3881*22dc650dSSadaf Ebrahimi #ifndef EBCDIC
3882*22dc650dSSadaf Ebrahimi case 0x2028:
3883*22dc650dSSadaf Ebrahimi case 0x2029:
3884*22dc650dSSadaf Ebrahimi #endif /* Not EBCDIC */
3885*22dc650dSSadaf Ebrahimi if (mb->bsr_convention == PCRE2_BSR_ANYCRLF)
3886*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
3887*22dc650dSSadaf Ebrahimi break;
3888*22dc650dSSadaf Ebrahimi }
3889*22dc650dSSadaf Ebrahimi break;
3890*22dc650dSSadaf Ebrahimi
3891*22dc650dSSadaf Ebrahimi case OP_NOT_HSPACE:
3892*22dc650dSSadaf Ebrahimi switch(fc)
3893*22dc650dSSadaf Ebrahimi {
3894*22dc650dSSadaf Ebrahimi HSPACE_CASES: RRETURN(MATCH_NOMATCH);
3895*22dc650dSSadaf Ebrahimi default: break;
3896*22dc650dSSadaf Ebrahimi }
3897*22dc650dSSadaf Ebrahimi break;
3898*22dc650dSSadaf Ebrahimi
3899*22dc650dSSadaf Ebrahimi case OP_HSPACE:
3900*22dc650dSSadaf Ebrahimi switch(fc)
3901*22dc650dSSadaf Ebrahimi {
3902*22dc650dSSadaf Ebrahimi HSPACE_CASES: break;
3903*22dc650dSSadaf Ebrahimi default: RRETURN(MATCH_NOMATCH);
3904*22dc650dSSadaf Ebrahimi }
3905*22dc650dSSadaf Ebrahimi break;
3906*22dc650dSSadaf Ebrahimi
3907*22dc650dSSadaf Ebrahimi case OP_NOT_VSPACE:
3908*22dc650dSSadaf Ebrahimi switch(fc)
3909*22dc650dSSadaf Ebrahimi {
3910*22dc650dSSadaf Ebrahimi VSPACE_CASES: RRETURN(MATCH_NOMATCH);
3911*22dc650dSSadaf Ebrahimi default: break;
3912*22dc650dSSadaf Ebrahimi }
3913*22dc650dSSadaf Ebrahimi break;
3914*22dc650dSSadaf Ebrahimi
3915*22dc650dSSadaf Ebrahimi case OP_VSPACE:
3916*22dc650dSSadaf Ebrahimi switch(fc)
3917*22dc650dSSadaf Ebrahimi {
3918*22dc650dSSadaf Ebrahimi VSPACE_CASES: break;
3919*22dc650dSSadaf Ebrahimi default: RRETURN(MATCH_NOMATCH);
3920*22dc650dSSadaf Ebrahimi }
3921*22dc650dSSadaf Ebrahimi break;
3922*22dc650dSSadaf Ebrahimi
3923*22dc650dSSadaf Ebrahimi case OP_NOT_DIGIT:
3924*22dc650dSSadaf Ebrahimi if (fc < 256 && (mb->ctypes[fc] & ctype_digit) != 0)
3925*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
3926*22dc650dSSadaf Ebrahimi break;
3927*22dc650dSSadaf Ebrahimi
3928*22dc650dSSadaf Ebrahimi case OP_DIGIT:
3929*22dc650dSSadaf Ebrahimi if (fc >= 256 || (mb->ctypes[fc] & ctype_digit) == 0)
3930*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
3931*22dc650dSSadaf Ebrahimi break;
3932*22dc650dSSadaf Ebrahimi
3933*22dc650dSSadaf Ebrahimi case OP_NOT_WHITESPACE:
3934*22dc650dSSadaf Ebrahimi if (fc < 256 && (mb->ctypes[fc] & ctype_space) != 0)
3935*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
3936*22dc650dSSadaf Ebrahimi break;
3937*22dc650dSSadaf Ebrahimi
3938*22dc650dSSadaf Ebrahimi case OP_WHITESPACE:
3939*22dc650dSSadaf Ebrahimi if (fc >= 256 || (mb->ctypes[fc] & ctype_space) == 0)
3940*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
3941*22dc650dSSadaf Ebrahimi break;
3942*22dc650dSSadaf Ebrahimi
3943*22dc650dSSadaf Ebrahimi case OP_NOT_WORDCHAR:
3944*22dc650dSSadaf Ebrahimi if (fc < 256 && (mb->ctypes[fc] & ctype_word) != 0)
3945*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
3946*22dc650dSSadaf Ebrahimi break;
3947*22dc650dSSadaf Ebrahimi
3948*22dc650dSSadaf Ebrahimi case OP_WORDCHAR:
3949*22dc650dSSadaf Ebrahimi if (fc >= 256 || (mb->ctypes[fc] & ctype_word) == 0)
3950*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
3951*22dc650dSSadaf Ebrahimi break;
3952*22dc650dSSadaf Ebrahimi
3953*22dc650dSSadaf Ebrahimi default:
3954*22dc650dSSadaf Ebrahimi return PCRE2_ERROR_INTERNAL;
3955*22dc650dSSadaf Ebrahimi }
3956*22dc650dSSadaf Ebrahimi }
3957*22dc650dSSadaf Ebrahimi }
3958*22dc650dSSadaf Ebrahimi else
3959*22dc650dSSadaf Ebrahimi #endif /* SUPPORT_UNICODE */
3960*22dc650dSSadaf Ebrahimi
3961*22dc650dSSadaf Ebrahimi /* Not UTF mode */
3962*22dc650dSSadaf Ebrahimi {
3963*22dc650dSSadaf Ebrahimi for (;;)
3964*22dc650dSSadaf Ebrahimi {
3965*22dc650dSSadaf Ebrahimi RMATCH(Fecode, RM33);
3966*22dc650dSSadaf Ebrahimi if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3967*22dc650dSSadaf Ebrahimi if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH);
3968*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
3969*22dc650dSSadaf Ebrahimi {
3970*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
3971*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
3972*22dc650dSSadaf Ebrahimi }
3973*22dc650dSSadaf Ebrahimi if (Lctype == OP_ANY && IS_NEWLINE(Feptr))
3974*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
3975*22dc650dSSadaf Ebrahimi fc = *Feptr++;
3976*22dc650dSSadaf Ebrahimi switch(Lctype)
3977*22dc650dSSadaf Ebrahimi {
3978*22dc650dSSadaf Ebrahimi case OP_ANY: /* This is the non-NL case */
3979*22dc650dSSadaf Ebrahimi if (mb->partial != 0 && /* Take care with CRLF partial */
3980*22dc650dSSadaf Ebrahimi Feptr >= mb->end_subject &&
3981*22dc650dSSadaf Ebrahimi NLBLOCK->nltype == NLTYPE_FIXED &&
3982*22dc650dSSadaf Ebrahimi NLBLOCK->nllen == 2 &&
3983*22dc650dSSadaf Ebrahimi fc == NLBLOCK->nl[0])
3984*22dc650dSSadaf Ebrahimi {
3985*22dc650dSSadaf Ebrahimi mb->hitend = TRUE;
3986*22dc650dSSadaf Ebrahimi if (mb->partial > 1) return PCRE2_ERROR_PARTIAL;
3987*22dc650dSSadaf Ebrahimi }
3988*22dc650dSSadaf Ebrahimi break;
3989*22dc650dSSadaf Ebrahimi
3990*22dc650dSSadaf Ebrahimi case OP_ALLANY:
3991*22dc650dSSadaf Ebrahimi case OP_ANYBYTE:
3992*22dc650dSSadaf Ebrahimi break;
3993*22dc650dSSadaf Ebrahimi
3994*22dc650dSSadaf Ebrahimi case OP_ANYNL:
3995*22dc650dSSadaf Ebrahimi switch(fc)
3996*22dc650dSSadaf Ebrahimi {
3997*22dc650dSSadaf Ebrahimi default: RRETURN(MATCH_NOMATCH);
3998*22dc650dSSadaf Ebrahimi
3999*22dc650dSSadaf Ebrahimi case CHAR_CR:
4000*22dc650dSSadaf Ebrahimi if (Feptr < mb->end_subject && *Feptr == CHAR_LF) Feptr++;
4001*22dc650dSSadaf Ebrahimi break;
4002*22dc650dSSadaf Ebrahimi
4003*22dc650dSSadaf Ebrahimi case CHAR_LF:
4004*22dc650dSSadaf Ebrahimi break;
4005*22dc650dSSadaf Ebrahimi
4006*22dc650dSSadaf Ebrahimi case CHAR_VT:
4007*22dc650dSSadaf Ebrahimi case CHAR_FF:
4008*22dc650dSSadaf Ebrahimi case CHAR_NEL:
4009*22dc650dSSadaf Ebrahimi #if PCRE2_CODE_UNIT_WIDTH != 8
4010*22dc650dSSadaf Ebrahimi case 0x2028:
4011*22dc650dSSadaf Ebrahimi case 0x2029:
4012*22dc650dSSadaf Ebrahimi #endif
4013*22dc650dSSadaf Ebrahimi if (mb->bsr_convention == PCRE2_BSR_ANYCRLF)
4014*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
4015*22dc650dSSadaf Ebrahimi break;
4016*22dc650dSSadaf Ebrahimi }
4017*22dc650dSSadaf Ebrahimi break;
4018*22dc650dSSadaf Ebrahimi
4019*22dc650dSSadaf Ebrahimi case OP_NOT_HSPACE:
4020*22dc650dSSadaf Ebrahimi switch(fc)
4021*22dc650dSSadaf Ebrahimi {
4022*22dc650dSSadaf Ebrahimi default: break;
4023*22dc650dSSadaf Ebrahimi HSPACE_BYTE_CASES:
4024*22dc650dSSadaf Ebrahimi #if PCRE2_CODE_UNIT_WIDTH != 8
4025*22dc650dSSadaf Ebrahimi HSPACE_MULTIBYTE_CASES:
4026*22dc650dSSadaf Ebrahimi #endif
4027*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
4028*22dc650dSSadaf Ebrahimi }
4029*22dc650dSSadaf Ebrahimi break;
4030*22dc650dSSadaf Ebrahimi
4031*22dc650dSSadaf Ebrahimi case OP_HSPACE:
4032*22dc650dSSadaf Ebrahimi switch(fc)
4033*22dc650dSSadaf Ebrahimi {
4034*22dc650dSSadaf Ebrahimi default: RRETURN(MATCH_NOMATCH);
4035*22dc650dSSadaf Ebrahimi HSPACE_BYTE_CASES:
4036*22dc650dSSadaf Ebrahimi #if PCRE2_CODE_UNIT_WIDTH != 8
4037*22dc650dSSadaf Ebrahimi HSPACE_MULTIBYTE_CASES:
4038*22dc650dSSadaf Ebrahimi #endif
4039*22dc650dSSadaf Ebrahimi break;
4040*22dc650dSSadaf Ebrahimi }
4041*22dc650dSSadaf Ebrahimi break;
4042*22dc650dSSadaf Ebrahimi
4043*22dc650dSSadaf Ebrahimi case OP_NOT_VSPACE:
4044*22dc650dSSadaf Ebrahimi switch(fc)
4045*22dc650dSSadaf Ebrahimi {
4046*22dc650dSSadaf Ebrahimi default: break;
4047*22dc650dSSadaf Ebrahimi VSPACE_BYTE_CASES:
4048*22dc650dSSadaf Ebrahimi #if PCRE2_CODE_UNIT_WIDTH != 8
4049*22dc650dSSadaf Ebrahimi VSPACE_MULTIBYTE_CASES:
4050*22dc650dSSadaf Ebrahimi #endif
4051*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
4052*22dc650dSSadaf Ebrahimi }
4053*22dc650dSSadaf Ebrahimi break;
4054*22dc650dSSadaf Ebrahimi
4055*22dc650dSSadaf Ebrahimi case OP_VSPACE:
4056*22dc650dSSadaf Ebrahimi switch(fc)
4057*22dc650dSSadaf Ebrahimi {
4058*22dc650dSSadaf Ebrahimi default: RRETURN(MATCH_NOMATCH);
4059*22dc650dSSadaf Ebrahimi VSPACE_BYTE_CASES:
4060*22dc650dSSadaf Ebrahimi #if PCRE2_CODE_UNIT_WIDTH != 8
4061*22dc650dSSadaf Ebrahimi VSPACE_MULTIBYTE_CASES:
4062*22dc650dSSadaf Ebrahimi #endif
4063*22dc650dSSadaf Ebrahimi break;
4064*22dc650dSSadaf Ebrahimi }
4065*22dc650dSSadaf Ebrahimi break;
4066*22dc650dSSadaf Ebrahimi
4067*22dc650dSSadaf Ebrahimi case OP_NOT_DIGIT:
4068*22dc650dSSadaf Ebrahimi if (MAX_255(fc) && (mb->ctypes[fc] & ctype_digit) != 0)
4069*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
4070*22dc650dSSadaf Ebrahimi break;
4071*22dc650dSSadaf Ebrahimi
4072*22dc650dSSadaf Ebrahimi case OP_DIGIT:
4073*22dc650dSSadaf Ebrahimi if (!MAX_255(fc) || (mb->ctypes[fc] & ctype_digit) == 0)
4074*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
4075*22dc650dSSadaf Ebrahimi break;
4076*22dc650dSSadaf Ebrahimi
4077*22dc650dSSadaf Ebrahimi case OP_NOT_WHITESPACE:
4078*22dc650dSSadaf Ebrahimi if (MAX_255(fc) && (mb->ctypes[fc] & ctype_space) != 0)
4079*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
4080*22dc650dSSadaf Ebrahimi break;
4081*22dc650dSSadaf Ebrahimi
4082*22dc650dSSadaf Ebrahimi case OP_WHITESPACE:
4083*22dc650dSSadaf Ebrahimi if (!MAX_255(fc) || (mb->ctypes[fc] & ctype_space) == 0)
4084*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
4085*22dc650dSSadaf Ebrahimi break;
4086*22dc650dSSadaf Ebrahimi
4087*22dc650dSSadaf Ebrahimi case OP_NOT_WORDCHAR:
4088*22dc650dSSadaf Ebrahimi if (MAX_255(fc) && (mb->ctypes[fc] & ctype_word) != 0)
4089*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
4090*22dc650dSSadaf Ebrahimi break;
4091*22dc650dSSadaf Ebrahimi
4092*22dc650dSSadaf Ebrahimi case OP_WORDCHAR:
4093*22dc650dSSadaf Ebrahimi if (!MAX_255(fc) || (mb->ctypes[fc] & ctype_word) == 0)
4094*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
4095*22dc650dSSadaf Ebrahimi break;
4096*22dc650dSSadaf Ebrahimi
4097*22dc650dSSadaf Ebrahimi default:
4098*22dc650dSSadaf Ebrahimi return PCRE2_ERROR_INTERNAL;
4099*22dc650dSSadaf Ebrahimi }
4100*22dc650dSSadaf Ebrahimi }
4101*22dc650dSSadaf Ebrahimi }
4102*22dc650dSSadaf Ebrahimi /* Control never gets here */
4103*22dc650dSSadaf Ebrahimi }
4104*22dc650dSSadaf Ebrahimi
4105*22dc650dSSadaf Ebrahimi /* If maximizing, it is worth using inline code for speed, doing the type
4106*22dc650dSSadaf Ebrahimi test once at the start (i.e. keep it out of the loops). Once again,
4107*22dc650dSSadaf Ebrahimi "notmatch" can be an ordinary local variable because the loops do not call
4108*22dc650dSSadaf Ebrahimi RMATCH. */
4109*22dc650dSSadaf Ebrahimi
4110*22dc650dSSadaf Ebrahimi else
4111*22dc650dSSadaf Ebrahimi {
4112*22dc650dSSadaf Ebrahimi Lstart_eptr = Feptr; /* Remember where we started */
4113*22dc650dSSadaf Ebrahimi
4114*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_UNICODE
4115*22dc650dSSadaf Ebrahimi if (proptype >= 0)
4116*22dc650dSSadaf Ebrahimi {
4117*22dc650dSSadaf Ebrahimi BOOL notmatch = Lctype == OP_NOTPROP;
4118*22dc650dSSadaf Ebrahimi switch(proptype)
4119*22dc650dSSadaf Ebrahimi {
4120*22dc650dSSadaf Ebrahimi case PT_ANY:
4121*22dc650dSSadaf Ebrahimi for (i = Lmin; i < Lmax; i++)
4122*22dc650dSSadaf Ebrahimi {
4123*22dc650dSSadaf Ebrahimi int len = 1;
4124*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
4125*22dc650dSSadaf Ebrahimi {
4126*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
4127*22dc650dSSadaf Ebrahimi break;
4128*22dc650dSSadaf Ebrahimi }
4129*22dc650dSSadaf Ebrahimi GETCHARLENTEST(fc, Feptr, len);
4130*22dc650dSSadaf Ebrahimi if (notmatch) break;
4131*22dc650dSSadaf Ebrahimi Feptr+= len;
4132*22dc650dSSadaf Ebrahimi }
4133*22dc650dSSadaf Ebrahimi break;
4134*22dc650dSSadaf Ebrahimi
4135*22dc650dSSadaf Ebrahimi case PT_LAMP:
4136*22dc650dSSadaf Ebrahimi for (i = Lmin; i < Lmax; i++)
4137*22dc650dSSadaf Ebrahimi {
4138*22dc650dSSadaf Ebrahimi int chartype;
4139*22dc650dSSadaf Ebrahimi int len = 1;
4140*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
4141*22dc650dSSadaf Ebrahimi {
4142*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
4143*22dc650dSSadaf Ebrahimi break;
4144*22dc650dSSadaf Ebrahimi }
4145*22dc650dSSadaf Ebrahimi GETCHARLENTEST(fc, Feptr, len);
4146*22dc650dSSadaf Ebrahimi chartype = UCD_CHARTYPE(fc);
4147*22dc650dSSadaf Ebrahimi if ((chartype == ucp_Lu ||
4148*22dc650dSSadaf Ebrahimi chartype == ucp_Ll ||
4149*22dc650dSSadaf Ebrahimi chartype == ucp_Lt) == notmatch)
4150*22dc650dSSadaf Ebrahimi break;
4151*22dc650dSSadaf Ebrahimi Feptr+= len;
4152*22dc650dSSadaf Ebrahimi }
4153*22dc650dSSadaf Ebrahimi break;
4154*22dc650dSSadaf Ebrahimi
4155*22dc650dSSadaf Ebrahimi case PT_GC:
4156*22dc650dSSadaf Ebrahimi for (i = Lmin; i < Lmax; i++)
4157*22dc650dSSadaf Ebrahimi {
4158*22dc650dSSadaf Ebrahimi int len = 1;
4159*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
4160*22dc650dSSadaf Ebrahimi {
4161*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
4162*22dc650dSSadaf Ebrahimi break;
4163*22dc650dSSadaf Ebrahimi }
4164*22dc650dSSadaf Ebrahimi GETCHARLENTEST(fc, Feptr, len);
4165*22dc650dSSadaf Ebrahimi if ((UCD_CATEGORY(fc) == Lpropvalue) == notmatch) break;
4166*22dc650dSSadaf Ebrahimi Feptr+= len;
4167*22dc650dSSadaf Ebrahimi }
4168*22dc650dSSadaf Ebrahimi break;
4169*22dc650dSSadaf Ebrahimi
4170*22dc650dSSadaf Ebrahimi case PT_PC:
4171*22dc650dSSadaf Ebrahimi for (i = Lmin; i < Lmax; i++)
4172*22dc650dSSadaf Ebrahimi {
4173*22dc650dSSadaf Ebrahimi int len = 1;
4174*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
4175*22dc650dSSadaf Ebrahimi {
4176*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
4177*22dc650dSSadaf Ebrahimi break;
4178*22dc650dSSadaf Ebrahimi }
4179*22dc650dSSadaf Ebrahimi GETCHARLENTEST(fc, Feptr, len);
4180*22dc650dSSadaf Ebrahimi if ((UCD_CHARTYPE(fc) == Lpropvalue) == notmatch) break;
4181*22dc650dSSadaf Ebrahimi Feptr+= len;
4182*22dc650dSSadaf Ebrahimi }
4183*22dc650dSSadaf Ebrahimi break;
4184*22dc650dSSadaf Ebrahimi
4185*22dc650dSSadaf Ebrahimi case PT_SC:
4186*22dc650dSSadaf Ebrahimi for (i = Lmin; i < Lmax; i++)
4187*22dc650dSSadaf Ebrahimi {
4188*22dc650dSSadaf Ebrahimi int len = 1;
4189*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
4190*22dc650dSSadaf Ebrahimi {
4191*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
4192*22dc650dSSadaf Ebrahimi break;
4193*22dc650dSSadaf Ebrahimi }
4194*22dc650dSSadaf Ebrahimi GETCHARLENTEST(fc, Feptr, len);
4195*22dc650dSSadaf Ebrahimi if ((UCD_SCRIPT(fc) == Lpropvalue) == notmatch) break;
4196*22dc650dSSadaf Ebrahimi Feptr+= len;
4197*22dc650dSSadaf Ebrahimi }
4198*22dc650dSSadaf Ebrahimi break;
4199*22dc650dSSadaf Ebrahimi
4200*22dc650dSSadaf Ebrahimi case PT_SCX:
4201*22dc650dSSadaf Ebrahimi for (i = Lmin; i < Lmax; i++)
4202*22dc650dSSadaf Ebrahimi {
4203*22dc650dSSadaf Ebrahimi BOOL ok;
4204*22dc650dSSadaf Ebrahimi const ucd_record *prop;
4205*22dc650dSSadaf Ebrahimi int len = 1;
4206*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
4207*22dc650dSSadaf Ebrahimi {
4208*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
4209*22dc650dSSadaf Ebrahimi break;
4210*22dc650dSSadaf Ebrahimi }
4211*22dc650dSSadaf Ebrahimi GETCHARLENTEST(fc, Feptr, len);
4212*22dc650dSSadaf Ebrahimi prop = GET_UCD(fc);
4213*22dc650dSSadaf Ebrahimi ok = (prop->script == Lpropvalue ||
4214*22dc650dSSadaf Ebrahimi MAPBIT(PRIV(ucd_script_sets) + UCD_SCRIPTX_PROP(prop), Lpropvalue) != 0);
4215*22dc650dSSadaf Ebrahimi if (ok == notmatch) break;
4216*22dc650dSSadaf Ebrahimi Feptr+= len;
4217*22dc650dSSadaf Ebrahimi }
4218*22dc650dSSadaf Ebrahimi break;
4219*22dc650dSSadaf Ebrahimi
4220*22dc650dSSadaf Ebrahimi case PT_ALNUM:
4221*22dc650dSSadaf Ebrahimi for (i = Lmin; i < Lmax; i++)
4222*22dc650dSSadaf Ebrahimi {
4223*22dc650dSSadaf Ebrahimi int category;
4224*22dc650dSSadaf Ebrahimi int len = 1;
4225*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
4226*22dc650dSSadaf Ebrahimi {
4227*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
4228*22dc650dSSadaf Ebrahimi break;
4229*22dc650dSSadaf Ebrahimi }
4230*22dc650dSSadaf Ebrahimi GETCHARLENTEST(fc, Feptr, len);
4231*22dc650dSSadaf Ebrahimi category = UCD_CATEGORY(fc);
4232*22dc650dSSadaf Ebrahimi if ((category == ucp_L || category == ucp_N) == notmatch)
4233*22dc650dSSadaf Ebrahimi break;
4234*22dc650dSSadaf Ebrahimi Feptr+= len;
4235*22dc650dSSadaf Ebrahimi }
4236*22dc650dSSadaf Ebrahimi break;
4237*22dc650dSSadaf Ebrahimi
4238*22dc650dSSadaf Ebrahimi /* Perl space used to exclude VT, but from Perl 5.18 it is included,
4239*22dc650dSSadaf Ebrahimi which means that Perl space and POSIX space are now identical. PCRE
4240*22dc650dSSadaf Ebrahimi was changed at release 8.34. */
4241*22dc650dSSadaf Ebrahimi
4242*22dc650dSSadaf Ebrahimi case PT_SPACE: /* Perl space */
4243*22dc650dSSadaf Ebrahimi case PT_PXSPACE: /* POSIX space */
4244*22dc650dSSadaf Ebrahimi for (i = Lmin; i < Lmax; i++)
4245*22dc650dSSadaf Ebrahimi {
4246*22dc650dSSadaf Ebrahimi int len = 1;
4247*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
4248*22dc650dSSadaf Ebrahimi {
4249*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
4250*22dc650dSSadaf Ebrahimi break;
4251*22dc650dSSadaf Ebrahimi }
4252*22dc650dSSadaf Ebrahimi GETCHARLENTEST(fc, Feptr, len);
4253*22dc650dSSadaf Ebrahimi switch(fc)
4254*22dc650dSSadaf Ebrahimi {
4255*22dc650dSSadaf Ebrahimi HSPACE_CASES:
4256*22dc650dSSadaf Ebrahimi VSPACE_CASES:
4257*22dc650dSSadaf Ebrahimi if (notmatch) goto ENDLOOP99; /* Break the loop */
4258*22dc650dSSadaf Ebrahimi break;
4259*22dc650dSSadaf Ebrahimi
4260*22dc650dSSadaf Ebrahimi default:
4261*22dc650dSSadaf Ebrahimi if ((UCD_CATEGORY(fc) == ucp_Z) == notmatch)
4262*22dc650dSSadaf Ebrahimi goto ENDLOOP99; /* Break the loop */
4263*22dc650dSSadaf Ebrahimi break;
4264*22dc650dSSadaf Ebrahimi }
4265*22dc650dSSadaf Ebrahimi Feptr+= len;
4266*22dc650dSSadaf Ebrahimi }
4267*22dc650dSSadaf Ebrahimi ENDLOOP99:
4268*22dc650dSSadaf Ebrahimi break;
4269*22dc650dSSadaf Ebrahimi
4270*22dc650dSSadaf Ebrahimi case PT_WORD:
4271*22dc650dSSadaf Ebrahimi for (i = Lmin; i < Lmax; i++)
4272*22dc650dSSadaf Ebrahimi {
4273*22dc650dSSadaf Ebrahimi int chartype, category;
4274*22dc650dSSadaf Ebrahimi int len = 1;
4275*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
4276*22dc650dSSadaf Ebrahimi {
4277*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
4278*22dc650dSSadaf Ebrahimi break;
4279*22dc650dSSadaf Ebrahimi }
4280*22dc650dSSadaf Ebrahimi GETCHARLENTEST(fc, Feptr, len);
4281*22dc650dSSadaf Ebrahimi chartype = UCD_CHARTYPE(fc);
4282*22dc650dSSadaf Ebrahimi category = PRIV(ucp_gentype)[chartype];
4283*22dc650dSSadaf Ebrahimi if ((category == ucp_L ||
4284*22dc650dSSadaf Ebrahimi category == ucp_N ||
4285*22dc650dSSadaf Ebrahimi chartype == ucp_Mn ||
4286*22dc650dSSadaf Ebrahimi chartype == ucp_Pc) == notmatch)
4287*22dc650dSSadaf Ebrahimi break;
4288*22dc650dSSadaf Ebrahimi Feptr+= len;
4289*22dc650dSSadaf Ebrahimi }
4290*22dc650dSSadaf Ebrahimi break;
4291*22dc650dSSadaf Ebrahimi
4292*22dc650dSSadaf Ebrahimi case PT_CLIST:
4293*22dc650dSSadaf Ebrahimi for (i = Lmin; i < Lmax; i++)
4294*22dc650dSSadaf Ebrahimi {
4295*22dc650dSSadaf Ebrahimi const uint32_t *cp;
4296*22dc650dSSadaf Ebrahimi int len = 1;
4297*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
4298*22dc650dSSadaf Ebrahimi {
4299*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
4300*22dc650dSSadaf Ebrahimi break;
4301*22dc650dSSadaf Ebrahimi }
4302*22dc650dSSadaf Ebrahimi GETCHARLENTEST(fc, Feptr, len);
4303*22dc650dSSadaf Ebrahimi #if PCRE2_CODE_UNIT_WIDTH == 32
4304*22dc650dSSadaf Ebrahimi if (fc > MAX_UTF_CODE_POINT)
4305*22dc650dSSadaf Ebrahimi {
4306*22dc650dSSadaf Ebrahimi if (!notmatch) goto GOT_MAX;
4307*22dc650dSSadaf Ebrahimi }
4308*22dc650dSSadaf Ebrahimi else
4309*22dc650dSSadaf Ebrahimi #endif
4310*22dc650dSSadaf Ebrahimi {
4311*22dc650dSSadaf Ebrahimi cp = PRIV(ucd_caseless_sets) + Lpropvalue;
4312*22dc650dSSadaf Ebrahimi for (;;)
4313*22dc650dSSadaf Ebrahimi {
4314*22dc650dSSadaf Ebrahimi if (fc < *cp)
4315*22dc650dSSadaf Ebrahimi { if (notmatch) break; else goto GOT_MAX; }
4316*22dc650dSSadaf Ebrahimi if (fc == *cp++)
4317*22dc650dSSadaf Ebrahimi { if (notmatch) goto GOT_MAX; else break; }
4318*22dc650dSSadaf Ebrahimi }
4319*22dc650dSSadaf Ebrahimi }
4320*22dc650dSSadaf Ebrahimi
4321*22dc650dSSadaf Ebrahimi Feptr += len;
4322*22dc650dSSadaf Ebrahimi }
4323*22dc650dSSadaf Ebrahimi GOT_MAX:
4324*22dc650dSSadaf Ebrahimi break;
4325*22dc650dSSadaf Ebrahimi
4326*22dc650dSSadaf Ebrahimi case PT_UCNC:
4327*22dc650dSSadaf Ebrahimi for (i = Lmin; i < Lmax; i++)
4328*22dc650dSSadaf Ebrahimi {
4329*22dc650dSSadaf Ebrahimi int len = 1;
4330*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
4331*22dc650dSSadaf Ebrahimi {
4332*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
4333*22dc650dSSadaf Ebrahimi break;
4334*22dc650dSSadaf Ebrahimi }
4335*22dc650dSSadaf Ebrahimi GETCHARLENTEST(fc, Feptr, len);
4336*22dc650dSSadaf Ebrahimi if ((fc == CHAR_DOLLAR_SIGN || fc == CHAR_COMMERCIAL_AT ||
4337*22dc650dSSadaf Ebrahimi fc == CHAR_GRAVE_ACCENT || (fc >= 0xa0 && fc <= 0xd7ff) ||
4338*22dc650dSSadaf Ebrahimi fc >= 0xe000) == notmatch)
4339*22dc650dSSadaf Ebrahimi break;
4340*22dc650dSSadaf Ebrahimi Feptr += len;
4341*22dc650dSSadaf Ebrahimi }
4342*22dc650dSSadaf Ebrahimi break;
4343*22dc650dSSadaf Ebrahimi
4344*22dc650dSSadaf Ebrahimi case PT_BIDICL:
4345*22dc650dSSadaf Ebrahimi for (i = Lmin; i < Lmax; i++)
4346*22dc650dSSadaf Ebrahimi {
4347*22dc650dSSadaf Ebrahimi int len = 1;
4348*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
4349*22dc650dSSadaf Ebrahimi {
4350*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
4351*22dc650dSSadaf Ebrahimi break;
4352*22dc650dSSadaf Ebrahimi }
4353*22dc650dSSadaf Ebrahimi GETCHARLENTEST(fc, Feptr, len);
4354*22dc650dSSadaf Ebrahimi if ((UCD_BIDICLASS(fc) == Lpropvalue) == notmatch) break;
4355*22dc650dSSadaf Ebrahimi Feptr+= len;
4356*22dc650dSSadaf Ebrahimi }
4357*22dc650dSSadaf Ebrahimi break;
4358*22dc650dSSadaf Ebrahimi
4359*22dc650dSSadaf Ebrahimi case PT_BOOL:
4360*22dc650dSSadaf Ebrahimi for (i = Lmin; i < Lmax; i++)
4361*22dc650dSSadaf Ebrahimi {
4362*22dc650dSSadaf Ebrahimi BOOL ok;
4363*22dc650dSSadaf Ebrahimi const ucd_record *prop;
4364*22dc650dSSadaf Ebrahimi int len = 1;
4365*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
4366*22dc650dSSadaf Ebrahimi {
4367*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
4368*22dc650dSSadaf Ebrahimi break;
4369*22dc650dSSadaf Ebrahimi }
4370*22dc650dSSadaf Ebrahimi GETCHARLENTEST(fc, Feptr, len);
4371*22dc650dSSadaf Ebrahimi prop = GET_UCD(fc);
4372*22dc650dSSadaf Ebrahimi ok = MAPBIT(PRIV(ucd_boolprop_sets) +
4373*22dc650dSSadaf Ebrahimi UCD_BPROPS_PROP(prop), Lpropvalue) != 0;
4374*22dc650dSSadaf Ebrahimi if (ok == notmatch) break;
4375*22dc650dSSadaf Ebrahimi Feptr+= len;
4376*22dc650dSSadaf Ebrahimi }
4377*22dc650dSSadaf Ebrahimi break;
4378*22dc650dSSadaf Ebrahimi
4379*22dc650dSSadaf Ebrahimi default:
4380*22dc650dSSadaf Ebrahimi return PCRE2_ERROR_INTERNAL;
4381*22dc650dSSadaf Ebrahimi }
4382*22dc650dSSadaf Ebrahimi
4383*22dc650dSSadaf Ebrahimi /* Feptr is now past the end of the maximum run */
4384*22dc650dSSadaf Ebrahimi
4385*22dc650dSSadaf Ebrahimi if (reptype == REPTYPE_POS) continue; /* No backtracking */
4386*22dc650dSSadaf Ebrahimi
4387*22dc650dSSadaf Ebrahimi /* After \C in UTF mode, Lstart_eptr might be in the middle of a
4388*22dc650dSSadaf Ebrahimi Unicode character. Use <= Lstart_eptr to ensure backtracking doesn't
4389*22dc650dSSadaf Ebrahimi go too far. */
4390*22dc650dSSadaf Ebrahimi
4391*22dc650dSSadaf Ebrahimi for(;;)
4392*22dc650dSSadaf Ebrahimi {
4393*22dc650dSSadaf Ebrahimi if (Feptr <= Lstart_eptr) break;
4394*22dc650dSSadaf Ebrahimi RMATCH(Fecode, RM222);
4395*22dc650dSSadaf Ebrahimi if (rrc != MATCH_NOMATCH) RRETURN(rrc);
4396*22dc650dSSadaf Ebrahimi Feptr--;
4397*22dc650dSSadaf Ebrahimi if (utf) BACKCHAR(Feptr);
4398*22dc650dSSadaf Ebrahimi }
4399*22dc650dSSadaf Ebrahimi }
4400*22dc650dSSadaf Ebrahimi
4401*22dc650dSSadaf Ebrahimi /* Match extended Unicode grapheme clusters. We will get here only if the
4402*22dc650dSSadaf Ebrahimi support is in the binary; otherwise a compile-time error occurs. */
4403*22dc650dSSadaf Ebrahimi
4404*22dc650dSSadaf Ebrahimi else if (Lctype == OP_EXTUNI)
4405*22dc650dSSadaf Ebrahimi {
4406*22dc650dSSadaf Ebrahimi for (i = Lmin; i < Lmax; i++)
4407*22dc650dSSadaf Ebrahimi {
4408*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
4409*22dc650dSSadaf Ebrahimi {
4410*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
4411*22dc650dSSadaf Ebrahimi break;
4412*22dc650dSSadaf Ebrahimi }
4413*22dc650dSSadaf Ebrahimi else
4414*22dc650dSSadaf Ebrahimi {
4415*22dc650dSSadaf Ebrahimi GETCHARINCTEST(fc, Feptr);
4416*22dc650dSSadaf Ebrahimi Feptr = PRIV(extuni)(fc, Feptr, mb->start_subject, mb->end_subject,
4417*22dc650dSSadaf Ebrahimi utf, NULL);
4418*22dc650dSSadaf Ebrahimi }
4419*22dc650dSSadaf Ebrahimi CHECK_PARTIAL();
4420*22dc650dSSadaf Ebrahimi }
4421*22dc650dSSadaf Ebrahimi
4422*22dc650dSSadaf Ebrahimi /* Feptr is now past the end of the maximum run */
4423*22dc650dSSadaf Ebrahimi
4424*22dc650dSSadaf Ebrahimi if (reptype == REPTYPE_POS) continue; /* No backtracking */
4425*22dc650dSSadaf Ebrahimi
4426*22dc650dSSadaf Ebrahimi /* We use <= Lstart_eptr rather than == Lstart_eptr to detect the start
4427*22dc650dSSadaf Ebrahimi of the run while backtracking because the use of \C in UTF mode can
4428*22dc650dSSadaf Ebrahimi cause BACKCHAR to move back past Lstart_eptr. This is just palliative;
4429*22dc650dSSadaf Ebrahimi the use of \C in UTF mode is fraught with danger. */
4430*22dc650dSSadaf Ebrahimi
4431*22dc650dSSadaf Ebrahimi for(;;)
4432*22dc650dSSadaf Ebrahimi {
4433*22dc650dSSadaf Ebrahimi int lgb, rgb;
4434*22dc650dSSadaf Ebrahimi PCRE2_SPTR fptr;
4435*22dc650dSSadaf Ebrahimi
4436*22dc650dSSadaf Ebrahimi if (Feptr <= Lstart_eptr) break; /* At start of char run */
4437*22dc650dSSadaf Ebrahimi RMATCH(Fecode, RM220);
4438*22dc650dSSadaf Ebrahimi if (rrc != MATCH_NOMATCH) RRETURN(rrc);
4439*22dc650dSSadaf Ebrahimi
4440*22dc650dSSadaf Ebrahimi /* Backtracking over an extended grapheme cluster involves inspecting
4441*22dc650dSSadaf Ebrahimi the previous two characters (if present) to see if a break is
4442*22dc650dSSadaf Ebrahimi permitted between them. */
4443*22dc650dSSadaf Ebrahimi
4444*22dc650dSSadaf Ebrahimi Feptr--;
4445*22dc650dSSadaf Ebrahimi if (!utf) fc = *Feptr; else
4446*22dc650dSSadaf Ebrahimi {
4447*22dc650dSSadaf Ebrahimi BACKCHAR(Feptr);
4448*22dc650dSSadaf Ebrahimi GETCHAR(fc, Feptr);
4449*22dc650dSSadaf Ebrahimi }
4450*22dc650dSSadaf Ebrahimi rgb = UCD_GRAPHBREAK(fc);
4451*22dc650dSSadaf Ebrahimi
4452*22dc650dSSadaf Ebrahimi for (;;)
4453*22dc650dSSadaf Ebrahimi {
4454*22dc650dSSadaf Ebrahimi if (Feptr <= Lstart_eptr) break; /* At start of char run */
4455*22dc650dSSadaf Ebrahimi fptr = Feptr - 1;
4456*22dc650dSSadaf Ebrahimi if (!utf) fc = *fptr; else
4457*22dc650dSSadaf Ebrahimi {
4458*22dc650dSSadaf Ebrahimi BACKCHAR(fptr);
4459*22dc650dSSadaf Ebrahimi GETCHAR(fc, fptr);
4460*22dc650dSSadaf Ebrahimi }
4461*22dc650dSSadaf Ebrahimi lgb = UCD_GRAPHBREAK(fc);
4462*22dc650dSSadaf Ebrahimi if ((PRIV(ucp_gbtable)[lgb] & (1u << rgb)) == 0) break;
4463*22dc650dSSadaf Ebrahimi Feptr = fptr;
4464*22dc650dSSadaf Ebrahimi rgb = lgb;
4465*22dc650dSSadaf Ebrahimi }
4466*22dc650dSSadaf Ebrahimi }
4467*22dc650dSSadaf Ebrahimi }
4468*22dc650dSSadaf Ebrahimi
4469*22dc650dSSadaf Ebrahimi else
4470*22dc650dSSadaf Ebrahimi #endif /* SUPPORT_UNICODE */
4471*22dc650dSSadaf Ebrahimi
4472*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_UNICODE
4473*22dc650dSSadaf Ebrahimi if (utf)
4474*22dc650dSSadaf Ebrahimi {
4475*22dc650dSSadaf Ebrahimi switch(Lctype)
4476*22dc650dSSadaf Ebrahimi {
4477*22dc650dSSadaf Ebrahimi case OP_ANY:
4478*22dc650dSSadaf Ebrahimi for (i = Lmin; i < Lmax; i++)
4479*22dc650dSSadaf Ebrahimi {
4480*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
4481*22dc650dSSadaf Ebrahimi {
4482*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
4483*22dc650dSSadaf Ebrahimi break;
4484*22dc650dSSadaf Ebrahimi }
4485*22dc650dSSadaf Ebrahimi if (IS_NEWLINE(Feptr)) break;
4486*22dc650dSSadaf Ebrahimi if (mb->partial != 0 && /* Take care with CRLF partial */
4487*22dc650dSSadaf Ebrahimi Feptr + 1 >= mb->end_subject &&
4488*22dc650dSSadaf Ebrahimi NLBLOCK->nltype == NLTYPE_FIXED &&
4489*22dc650dSSadaf Ebrahimi NLBLOCK->nllen == 2 &&
4490*22dc650dSSadaf Ebrahimi UCHAR21(Feptr) == NLBLOCK->nl[0])
4491*22dc650dSSadaf Ebrahimi {
4492*22dc650dSSadaf Ebrahimi mb->hitend = TRUE;
4493*22dc650dSSadaf Ebrahimi if (mb->partial > 1) return PCRE2_ERROR_PARTIAL;
4494*22dc650dSSadaf Ebrahimi }
4495*22dc650dSSadaf Ebrahimi Feptr++;
4496*22dc650dSSadaf Ebrahimi ACROSSCHAR(Feptr < mb->end_subject, Feptr, Feptr++);
4497*22dc650dSSadaf Ebrahimi }
4498*22dc650dSSadaf Ebrahimi break;
4499*22dc650dSSadaf Ebrahimi
4500*22dc650dSSadaf Ebrahimi case OP_ALLANY:
4501*22dc650dSSadaf Ebrahimi if (Lmax < UINT32_MAX)
4502*22dc650dSSadaf Ebrahimi {
4503*22dc650dSSadaf Ebrahimi for (i = Lmin; i < Lmax; i++)
4504*22dc650dSSadaf Ebrahimi {
4505*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
4506*22dc650dSSadaf Ebrahimi {
4507*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
4508*22dc650dSSadaf Ebrahimi break;
4509*22dc650dSSadaf Ebrahimi }
4510*22dc650dSSadaf Ebrahimi Feptr++;
4511*22dc650dSSadaf Ebrahimi ACROSSCHAR(Feptr < mb->end_subject, Feptr, Feptr++);
4512*22dc650dSSadaf Ebrahimi }
4513*22dc650dSSadaf Ebrahimi }
4514*22dc650dSSadaf Ebrahimi else
4515*22dc650dSSadaf Ebrahimi {
4516*22dc650dSSadaf Ebrahimi Feptr = mb->end_subject; /* Unlimited UTF-8 repeat */
4517*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
4518*22dc650dSSadaf Ebrahimi }
4519*22dc650dSSadaf Ebrahimi break;
4520*22dc650dSSadaf Ebrahimi
4521*22dc650dSSadaf Ebrahimi /* The "byte" (i.e. "code unit") case is the same as non-UTF */
4522*22dc650dSSadaf Ebrahimi
4523*22dc650dSSadaf Ebrahimi case OP_ANYBYTE:
4524*22dc650dSSadaf Ebrahimi fc = Lmax - Lmin;
4525*22dc650dSSadaf Ebrahimi if (fc > (uint32_t)(mb->end_subject - Feptr))
4526*22dc650dSSadaf Ebrahimi {
4527*22dc650dSSadaf Ebrahimi Feptr = mb->end_subject;
4528*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
4529*22dc650dSSadaf Ebrahimi }
4530*22dc650dSSadaf Ebrahimi else Feptr += fc;
4531*22dc650dSSadaf Ebrahimi break;
4532*22dc650dSSadaf Ebrahimi
4533*22dc650dSSadaf Ebrahimi case OP_ANYNL:
4534*22dc650dSSadaf Ebrahimi for (i = Lmin; i < Lmax; i++)
4535*22dc650dSSadaf Ebrahimi {
4536*22dc650dSSadaf Ebrahimi int len = 1;
4537*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
4538*22dc650dSSadaf Ebrahimi {
4539*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
4540*22dc650dSSadaf Ebrahimi break;
4541*22dc650dSSadaf Ebrahimi }
4542*22dc650dSSadaf Ebrahimi GETCHARLEN(fc, Feptr, len);
4543*22dc650dSSadaf Ebrahimi if (fc == CHAR_CR)
4544*22dc650dSSadaf Ebrahimi {
4545*22dc650dSSadaf Ebrahimi if (++Feptr >= mb->end_subject) break;
4546*22dc650dSSadaf Ebrahimi if (UCHAR21(Feptr) == CHAR_LF) Feptr++;
4547*22dc650dSSadaf Ebrahimi }
4548*22dc650dSSadaf Ebrahimi else
4549*22dc650dSSadaf Ebrahimi {
4550*22dc650dSSadaf Ebrahimi if (fc != CHAR_LF &&
4551*22dc650dSSadaf Ebrahimi (mb->bsr_convention == PCRE2_BSR_ANYCRLF ||
4552*22dc650dSSadaf Ebrahimi (fc != CHAR_VT && fc != CHAR_FF && fc != CHAR_NEL
4553*22dc650dSSadaf Ebrahimi #ifndef EBCDIC
4554*22dc650dSSadaf Ebrahimi && fc != 0x2028 && fc != 0x2029
4555*22dc650dSSadaf Ebrahimi #endif /* Not EBCDIC */
4556*22dc650dSSadaf Ebrahimi )))
4557*22dc650dSSadaf Ebrahimi break;
4558*22dc650dSSadaf Ebrahimi Feptr += len;
4559*22dc650dSSadaf Ebrahimi }
4560*22dc650dSSadaf Ebrahimi }
4561*22dc650dSSadaf Ebrahimi break;
4562*22dc650dSSadaf Ebrahimi
4563*22dc650dSSadaf Ebrahimi case OP_NOT_HSPACE:
4564*22dc650dSSadaf Ebrahimi case OP_HSPACE:
4565*22dc650dSSadaf Ebrahimi for (i = Lmin; i < Lmax; i++)
4566*22dc650dSSadaf Ebrahimi {
4567*22dc650dSSadaf Ebrahimi BOOL gotspace;
4568*22dc650dSSadaf Ebrahimi int len = 1;
4569*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
4570*22dc650dSSadaf Ebrahimi {
4571*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
4572*22dc650dSSadaf Ebrahimi break;
4573*22dc650dSSadaf Ebrahimi }
4574*22dc650dSSadaf Ebrahimi GETCHARLEN(fc, Feptr, len);
4575*22dc650dSSadaf Ebrahimi switch(fc)
4576*22dc650dSSadaf Ebrahimi {
4577*22dc650dSSadaf Ebrahimi HSPACE_CASES: gotspace = TRUE; break;
4578*22dc650dSSadaf Ebrahimi default: gotspace = FALSE; break;
4579*22dc650dSSadaf Ebrahimi }
4580*22dc650dSSadaf Ebrahimi if (gotspace == (Lctype == OP_NOT_HSPACE)) break;
4581*22dc650dSSadaf Ebrahimi Feptr += len;
4582*22dc650dSSadaf Ebrahimi }
4583*22dc650dSSadaf Ebrahimi break;
4584*22dc650dSSadaf Ebrahimi
4585*22dc650dSSadaf Ebrahimi case OP_NOT_VSPACE:
4586*22dc650dSSadaf Ebrahimi case OP_VSPACE:
4587*22dc650dSSadaf Ebrahimi for (i = Lmin; i < Lmax; i++)
4588*22dc650dSSadaf Ebrahimi {
4589*22dc650dSSadaf Ebrahimi BOOL gotspace;
4590*22dc650dSSadaf Ebrahimi int len = 1;
4591*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
4592*22dc650dSSadaf Ebrahimi {
4593*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
4594*22dc650dSSadaf Ebrahimi break;
4595*22dc650dSSadaf Ebrahimi }
4596*22dc650dSSadaf Ebrahimi GETCHARLEN(fc, Feptr, len);
4597*22dc650dSSadaf Ebrahimi switch(fc)
4598*22dc650dSSadaf Ebrahimi {
4599*22dc650dSSadaf Ebrahimi VSPACE_CASES: gotspace = TRUE; break;
4600*22dc650dSSadaf Ebrahimi default: gotspace = FALSE; break;
4601*22dc650dSSadaf Ebrahimi }
4602*22dc650dSSadaf Ebrahimi if (gotspace == (Lctype == OP_NOT_VSPACE)) break;
4603*22dc650dSSadaf Ebrahimi Feptr += len;
4604*22dc650dSSadaf Ebrahimi }
4605*22dc650dSSadaf Ebrahimi break;
4606*22dc650dSSadaf Ebrahimi
4607*22dc650dSSadaf Ebrahimi case OP_NOT_DIGIT:
4608*22dc650dSSadaf Ebrahimi for (i = Lmin; i < Lmax; i++)
4609*22dc650dSSadaf Ebrahimi {
4610*22dc650dSSadaf Ebrahimi int len = 1;
4611*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
4612*22dc650dSSadaf Ebrahimi {
4613*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
4614*22dc650dSSadaf Ebrahimi break;
4615*22dc650dSSadaf Ebrahimi }
4616*22dc650dSSadaf Ebrahimi GETCHARLEN(fc, Feptr, len);
4617*22dc650dSSadaf Ebrahimi if (fc < 256 && (mb->ctypes[fc] & ctype_digit) != 0) break;
4618*22dc650dSSadaf Ebrahimi Feptr+= len;
4619*22dc650dSSadaf Ebrahimi }
4620*22dc650dSSadaf Ebrahimi break;
4621*22dc650dSSadaf Ebrahimi
4622*22dc650dSSadaf Ebrahimi case OP_DIGIT:
4623*22dc650dSSadaf Ebrahimi for (i = Lmin; i < Lmax; i++)
4624*22dc650dSSadaf Ebrahimi {
4625*22dc650dSSadaf Ebrahimi int len = 1;
4626*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
4627*22dc650dSSadaf Ebrahimi {
4628*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
4629*22dc650dSSadaf Ebrahimi break;
4630*22dc650dSSadaf Ebrahimi }
4631*22dc650dSSadaf Ebrahimi GETCHARLEN(fc, Feptr, len);
4632*22dc650dSSadaf Ebrahimi if (fc >= 256 ||(mb->ctypes[fc] & ctype_digit) == 0) break;
4633*22dc650dSSadaf Ebrahimi Feptr+= len;
4634*22dc650dSSadaf Ebrahimi }
4635*22dc650dSSadaf Ebrahimi break;
4636*22dc650dSSadaf Ebrahimi
4637*22dc650dSSadaf Ebrahimi case OP_NOT_WHITESPACE:
4638*22dc650dSSadaf Ebrahimi for (i = Lmin; i < Lmax; i++)
4639*22dc650dSSadaf Ebrahimi {
4640*22dc650dSSadaf Ebrahimi int len = 1;
4641*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
4642*22dc650dSSadaf Ebrahimi {
4643*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
4644*22dc650dSSadaf Ebrahimi break;
4645*22dc650dSSadaf Ebrahimi }
4646*22dc650dSSadaf Ebrahimi GETCHARLEN(fc, Feptr, len);
4647*22dc650dSSadaf Ebrahimi if (fc < 256 && (mb->ctypes[fc] & ctype_space) != 0) break;
4648*22dc650dSSadaf Ebrahimi Feptr+= len;
4649*22dc650dSSadaf Ebrahimi }
4650*22dc650dSSadaf Ebrahimi break;
4651*22dc650dSSadaf Ebrahimi
4652*22dc650dSSadaf Ebrahimi case OP_WHITESPACE:
4653*22dc650dSSadaf Ebrahimi for (i = Lmin; i < Lmax; i++)
4654*22dc650dSSadaf Ebrahimi {
4655*22dc650dSSadaf Ebrahimi int len = 1;
4656*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
4657*22dc650dSSadaf Ebrahimi {
4658*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
4659*22dc650dSSadaf Ebrahimi break;
4660*22dc650dSSadaf Ebrahimi }
4661*22dc650dSSadaf Ebrahimi GETCHARLEN(fc, Feptr, len);
4662*22dc650dSSadaf Ebrahimi if (fc >= 256 ||(mb->ctypes[fc] & ctype_space) == 0) break;
4663*22dc650dSSadaf Ebrahimi Feptr+= len;
4664*22dc650dSSadaf Ebrahimi }
4665*22dc650dSSadaf Ebrahimi break;
4666*22dc650dSSadaf Ebrahimi
4667*22dc650dSSadaf Ebrahimi case OP_NOT_WORDCHAR:
4668*22dc650dSSadaf Ebrahimi for (i = Lmin; i < Lmax; i++)
4669*22dc650dSSadaf Ebrahimi {
4670*22dc650dSSadaf Ebrahimi int len = 1;
4671*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
4672*22dc650dSSadaf Ebrahimi {
4673*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
4674*22dc650dSSadaf Ebrahimi break;
4675*22dc650dSSadaf Ebrahimi }
4676*22dc650dSSadaf Ebrahimi GETCHARLEN(fc, Feptr, len);
4677*22dc650dSSadaf Ebrahimi if (fc < 256 && (mb->ctypes[fc] & ctype_word) != 0) break;
4678*22dc650dSSadaf Ebrahimi Feptr+= len;
4679*22dc650dSSadaf Ebrahimi }
4680*22dc650dSSadaf Ebrahimi break;
4681*22dc650dSSadaf Ebrahimi
4682*22dc650dSSadaf Ebrahimi case OP_WORDCHAR:
4683*22dc650dSSadaf Ebrahimi for (i = Lmin; i < Lmax; i++)
4684*22dc650dSSadaf Ebrahimi {
4685*22dc650dSSadaf Ebrahimi int len = 1;
4686*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
4687*22dc650dSSadaf Ebrahimi {
4688*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
4689*22dc650dSSadaf Ebrahimi break;
4690*22dc650dSSadaf Ebrahimi }
4691*22dc650dSSadaf Ebrahimi GETCHARLEN(fc, Feptr, len);
4692*22dc650dSSadaf Ebrahimi if (fc >= 256 || (mb->ctypes[fc] & ctype_word) == 0) break;
4693*22dc650dSSadaf Ebrahimi Feptr+= len;
4694*22dc650dSSadaf Ebrahimi }
4695*22dc650dSSadaf Ebrahimi break;
4696*22dc650dSSadaf Ebrahimi
4697*22dc650dSSadaf Ebrahimi default:
4698*22dc650dSSadaf Ebrahimi return PCRE2_ERROR_INTERNAL;
4699*22dc650dSSadaf Ebrahimi }
4700*22dc650dSSadaf Ebrahimi
4701*22dc650dSSadaf Ebrahimi if (reptype == REPTYPE_POS) continue; /* No backtracking */
4702*22dc650dSSadaf Ebrahimi
4703*22dc650dSSadaf Ebrahimi /* After \C in UTF mode, Lstart_eptr might be in the middle of a
4704*22dc650dSSadaf Ebrahimi Unicode character. Use <= Lstart_eptr to ensure backtracking doesn't go
4705*22dc650dSSadaf Ebrahimi too far. */
4706*22dc650dSSadaf Ebrahimi
4707*22dc650dSSadaf Ebrahimi for(;;)
4708*22dc650dSSadaf Ebrahimi {
4709*22dc650dSSadaf Ebrahimi if (Feptr <= Lstart_eptr) break;
4710*22dc650dSSadaf Ebrahimi RMATCH(Fecode, RM221);
4711*22dc650dSSadaf Ebrahimi if (rrc != MATCH_NOMATCH) RRETURN(rrc);
4712*22dc650dSSadaf Ebrahimi Feptr--;
4713*22dc650dSSadaf Ebrahimi BACKCHAR(Feptr);
4714*22dc650dSSadaf Ebrahimi if (Lctype == OP_ANYNL && Feptr > Lstart_eptr &&
4715*22dc650dSSadaf Ebrahimi UCHAR21(Feptr) == CHAR_NL && UCHAR21(Feptr - 1) == CHAR_CR)
4716*22dc650dSSadaf Ebrahimi Feptr--;
4717*22dc650dSSadaf Ebrahimi }
4718*22dc650dSSadaf Ebrahimi }
4719*22dc650dSSadaf Ebrahimi else
4720*22dc650dSSadaf Ebrahimi #endif /* SUPPORT_UNICODE */
4721*22dc650dSSadaf Ebrahimi
4722*22dc650dSSadaf Ebrahimi /* Not UTF mode */
4723*22dc650dSSadaf Ebrahimi {
4724*22dc650dSSadaf Ebrahimi switch(Lctype)
4725*22dc650dSSadaf Ebrahimi {
4726*22dc650dSSadaf Ebrahimi case OP_ANY:
4727*22dc650dSSadaf Ebrahimi for (i = Lmin; i < Lmax; i++)
4728*22dc650dSSadaf Ebrahimi {
4729*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
4730*22dc650dSSadaf Ebrahimi {
4731*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
4732*22dc650dSSadaf Ebrahimi break;
4733*22dc650dSSadaf Ebrahimi }
4734*22dc650dSSadaf Ebrahimi if (IS_NEWLINE(Feptr)) break;
4735*22dc650dSSadaf Ebrahimi if (mb->partial != 0 && /* Take care with CRLF partial */
4736*22dc650dSSadaf Ebrahimi Feptr + 1 >= mb->end_subject &&
4737*22dc650dSSadaf Ebrahimi NLBLOCK->nltype == NLTYPE_FIXED &&
4738*22dc650dSSadaf Ebrahimi NLBLOCK->nllen == 2 &&
4739*22dc650dSSadaf Ebrahimi *Feptr == NLBLOCK->nl[0])
4740*22dc650dSSadaf Ebrahimi {
4741*22dc650dSSadaf Ebrahimi mb->hitend = TRUE;
4742*22dc650dSSadaf Ebrahimi if (mb->partial > 1) return PCRE2_ERROR_PARTIAL;
4743*22dc650dSSadaf Ebrahimi }
4744*22dc650dSSadaf Ebrahimi Feptr++;
4745*22dc650dSSadaf Ebrahimi }
4746*22dc650dSSadaf Ebrahimi break;
4747*22dc650dSSadaf Ebrahimi
4748*22dc650dSSadaf Ebrahimi case OP_ALLANY:
4749*22dc650dSSadaf Ebrahimi case OP_ANYBYTE:
4750*22dc650dSSadaf Ebrahimi fc = Lmax - Lmin;
4751*22dc650dSSadaf Ebrahimi if (fc > (uint32_t)(mb->end_subject - Feptr))
4752*22dc650dSSadaf Ebrahimi {
4753*22dc650dSSadaf Ebrahimi Feptr = mb->end_subject;
4754*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
4755*22dc650dSSadaf Ebrahimi }
4756*22dc650dSSadaf Ebrahimi else Feptr += fc;
4757*22dc650dSSadaf Ebrahimi break;
4758*22dc650dSSadaf Ebrahimi
4759*22dc650dSSadaf Ebrahimi case OP_ANYNL:
4760*22dc650dSSadaf Ebrahimi for (i = Lmin; i < Lmax; i++)
4761*22dc650dSSadaf Ebrahimi {
4762*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
4763*22dc650dSSadaf Ebrahimi {
4764*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
4765*22dc650dSSadaf Ebrahimi break;
4766*22dc650dSSadaf Ebrahimi }
4767*22dc650dSSadaf Ebrahimi fc = *Feptr;
4768*22dc650dSSadaf Ebrahimi if (fc == CHAR_CR)
4769*22dc650dSSadaf Ebrahimi {
4770*22dc650dSSadaf Ebrahimi if (++Feptr >= mb->end_subject) break;
4771*22dc650dSSadaf Ebrahimi if (*Feptr == CHAR_LF) Feptr++;
4772*22dc650dSSadaf Ebrahimi }
4773*22dc650dSSadaf Ebrahimi else
4774*22dc650dSSadaf Ebrahimi {
4775*22dc650dSSadaf Ebrahimi if (fc != CHAR_LF && (mb->bsr_convention == PCRE2_BSR_ANYCRLF ||
4776*22dc650dSSadaf Ebrahimi (fc != CHAR_VT && fc != CHAR_FF && fc != CHAR_NEL
4777*22dc650dSSadaf Ebrahimi #if PCRE2_CODE_UNIT_WIDTH != 8
4778*22dc650dSSadaf Ebrahimi && fc != 0x2028 && fc != 0x2029
4779*22dc650dSSadaf Ebrahimi #endif
4780*22dc650dSSadaf Ebrahimi ))) break;
4781*22dc650dSSadaf Ebrahimi Feptr++;
4782*22dc650dSSadaf Ebrahimi }
4783*22dc650dSSadaf Ebrahimi }
4784*22dc650dSSadaf Ebrahimi break;
4785*22dc650dSSadaf Ebrahimi
4786*22dc650dSSadaf Ebrahimi case OP_NOT_HSPACE:
4787*22dc650dSSadaf Ebrahimi for (i = Lmin; i < Lmax; i++)
4788*22dc650dSSadaf Ebrahimi {
4789*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
4790*22dc650dSSadaf Ebrahimi {
4791*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
4792*22dc650dSSadaf Ebrahimi break;
4793*22dc650dSSadaf Ebrahimi }
4794*22dc650dSSadaf Ebrahimi switch(*Feptr)
4795*22dc650dSSadaf Ebrahimi {
4796*22dc650dSSadaf Ebrahimi default: Feptr++; break;
4797*22dc650dSSadaf Ebrahimi HSPACE_BYTE_CASES:
4798*22dc650dSSadaf Ebrahimi #if PCRE2_CODE_UNIT_WIDTH != 8
4799*22dc650dSSadaf Ebrahimi HSPACE_MULTIBYTE_CASES:
4800*22dc650dSSadaf Ebrahimi #endif
4801*22dc650dSSadaf Ebrahimi goto ENDLOOP00;
4802*22dc650dSSadaf Ebrahimi }
4803*22dc650dSSadaf Ebrahimi }
4804*22dc650dSSadaf Ebrahimi ENDLOOP00:
4805*22dc650dSSadaf Ebrahimi break;
4806*22dc650dSSadaf Ebrahimi
4807*22dc650dSSadaf Ebrahimi case OP_HSPACE:
4808*22dc650dSSadaf Ebrahimi for (i = Lmin; i < Lmax; i++)
4809*22dc650dSSadaf Ebrahimi {
4810*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
4811*22dc650dSSadaf Ebrahimi {
4812*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
4813*22dc650dSSadaf Ebrahimi break;
4814*22dc650dSSadaf Ebrahimi }
4815*22dc650dSSadaf Ebrahimi switch(*Feptr)
4816*22dc650dSSadaf Ebrahimi {
4817*22dc650dSSadaf Ebrahimi default: goto ENDLOOP01;
4818*22dc650dSSadaf Ebrahimi HSPACE_BYTE_CASES:
4819*22dc650dSSadaf Ebrahimi #if PCRE2_CODE_UNIT_WIDTH != 8
4820*22dc650dSSadaf Ebrahimi HSPACE_MULTIBYTE_CASES:
4821*22dc650dSSadaf Ebrahimi #endif
4822*22dc650dSSadaf Ebrahimi Feptr++; break;
4823*22dc650dSSadaf Ebrahimi }
4824*22dc650dSSadaf Ebrahimi }
4825*22dc650dSSadaf Ebrahimi ENDLOOP01:
4826*22dc650dSSadaf Ebrahimi break;
4827*22dc650dSSadaf Ebrahimi
4828*22dc650dSSadaf Ebrahimi case OP_NOT_VSPACE:
4829*22dc650dSSadaf Ebrahimi for (i = Lmin; i < Lmax; i++)
4830*22dc650dSSadaf Ebrahimi {
4831*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
4832*22dc650dSSadaf Ebrahimi {
4833*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
4834*22dc650dSSadaf Ebrahimi break;
4835*22dc650dSSadaf Ebrahimi }
4836*22dc650dSSadaf Ebrahimi switch(*Feptr)
4837*22dc650dSSadaf Ebrahimi {
4838*22dc650dSSadaf Ebrahimi default: Feptr++; break;
4839*22dc650dSSadaf Ebrahimi VSPACE_BYTE_CASES:
4840*22dc650dSSadaf Ebrahimi #if PCRE2_CODE_UNIT_WIDTH != 8
4841*22dc650dSSadaf Ebrahimi VSPACE_MULTIBYTE_CASES:
4842*22dc650dSSadaf Ebrahimi #endif
4843*22dc650dSSadaf Ebrahimi goto ENDLOOP02;
4844*22dc650dSSadaf Ebrahimi }
4845*22dc650dSSadaf Ebrahimi }
4846*22dc650dSSadaf Ebrahimi ENDLOOP02:
4847*22dc650dSSadaf Ebrahimi break;
4848*22dc650dSSadaf Ebrahimi
4849*22dc650dSSadaf Ebrahimi case OP_VSPACE:
4850*22dc650dSSadaf Ebrahimi for (i = Lmin; i < Lmax; i++)
4851*22dc650dSSadaf Ebrahimi {
4852*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
4853*22dc650dSSadaf Ebrahimi {
4854*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
4855*22dc650dSSadaf Ebrahimi break;
4856*22dc650dSSadaf Ebrahimi }
4857*22dc650dSSadaf Ebrahimi switch(*Feptr)
4858*22dc650dSSadaf Ebrahimi {
4859*22dc650dSSadaf Ebrahimi default: goto ENDLOOP03;
4860*22dc650dSSadaf Ebrahimi VSPACE_BYTE_CASES:
4861*22dc650dSSadaf Ebrahimi #if PCRE2_CODE_UNIT_WIDTH != 8
4862*22dc650dSSadaf Ebrahimi VSPACE_MULTIBYTE_CASES:
4863*22dc650dSSadaf Ebrahimi #endif
4864*22dc650dSSadaf Ebrahimi Feptr++; break;
4865*22dc650dSSadaf Ebrahimi }
4866*22dc650dSSadaf Ebrahimi }
4867*22dc650dSSadaf Ebrahimi ENDLOOP03:
4868*22dc650dSSadaf Ebrahimi break;
4869*22dc650dSSadaf Ebrahimi
4870*22dc650dSSadaf Ebrahimi case OP_NOT_DIGIT:
4871*22dc650dSSadaf Ebrahimi for (i = Lmin; i < Lmax; i++)
4872*22dc650dSSadaf Ebrahimi {
4873*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
4874*22dc650dSSadaf Ebrahimi {
4875*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
4876*22dc650dSSadaf Ebrahimi break;
4877*22dc650dSSadaf Ebrahimi }
4878*22dc650dSSadaf Ebrahimi if (MAX_255(*Feptr) && (mb->ctypes[*Feptr] & ctype_digit) != 0)
4879*22dc650dSSadaf Ebrahimi break;
4880*22dc650dSSadaf Ebrahimi Feptr++;
4881*22dc650dSSadaf Ebrahimi }
4882*22dc650dSSadaf Ebrahimi break;
4883*22dc650dSSadaf Ebrahimi
4884*22dc650dSSadaf Ebrahimi case OP_DIGIT:
4885*22dc650dSSadaf Ebrahimi for (i = Lmin; i < Lmax; i++)
4886*22dc650dSSadaf Ebrahimi {
4887*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
4888*22dc650dSSadaf Ebrahimi {
4889*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
4890*22dc650dSSadaf Ebrahimi break;
4891*22dc650dSSadaf Ebrahimi }
4892*22dc650dSSadaf Ebrahimi if (!MAX_255(*Feptr) || (mb->ctypes[*Feptr] & ctype_digit) == 0)
4893*22dc650dSSadaf Ebrahimi break;
4894*22dc650dSSadaf Ebrahimi Feptr++;
4895*22dc650dSSadaf Ebrahimi }
4896*22dc650dSSadaf Ebrahimi break;
4897*22dc650dSSadaf Ebrahimi
4898*22dc650dSSadaf Ebrahimi case OP_NOT_WHITESPACE:
4899*22dc650dSSadaf Ebrahimi for (i = Lmin; i < Lmax; i++)
4900*22dc650dSSadaf Ebrahimi {
4901*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
4902*22dc650dSSadaf Ebrahimi {
4903*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
4904*22dc650dSSadaf Ebrahimi break;
4905*22dc650dSSadaf Ebrahimi }
4906*22dc650dSSadaf Ebrahimi if (MAX_255(*Feptr) && (mb->ctypes[*Feptr] & ctype_space) != 0)
4907*22dc650dSSadaf Ebrahimi break;
4908*22dc650dSSadaf Ebrahimi Feptr++;
4909*22dc650dSSadaf Ebrahimi }
4910*22dc650dSSadaf Ebrahimi break;
4911*22dc650dSSadaf Ebrahimi
4912*22dc650dSSadaf Ebrahimi case OP_WHITESPACE:
4913*22dc650dSSadaf Ebrahimi for (i = Lmin; i < Lmax; i++)
4914*22dc650dSSadaf Ebrahimi {
4915*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
4916*22dc650dSSadaf Ebrahimi {
4917*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
4918*22dc650dSSadaf Ebrahimi break;
4919*22dc650dSSadaf Ebrahimi }
4920*22dc650dSSadaf Ebrahimi if (!MAX_255(*Feptr) || (mb->ctypes[*Feptr] & ctype_space) == 0)
4921*22dc650dSSadaf Ebrahimi break;
4922*22dc650dSSadaf Ebrahimi Feptr++;
4923*22dc650dSSadaf Ebrahimi }
4924*22dc650dSSadaf Ebrahimi break;
4925*22dc650dSSadaf Ebrahimi
4926*22dc650dSSadaf Ebrahimi case OP_NOT_WORDCHAR:
4927*22dc650dSSadaf Ebrahimi for (i = Lmin; i < Lmax; i++)
4928*22dc650dSSadaf Ebrahimi {
4929*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
4930*22dc650dSSadaf Ebrahimi {
4931*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
4932*22dc650dSSadaf Ebrahimi break;
4933*22dc650dSSadaf Ebrahimi }
4934*22dc650dSSadaf Ebrahimi if (MAX_255(*Feptr) && (mb->ctypes[*Feptr] & ctype_word) != 0)
4935*22dc650dSSadaf Ebrahimi break;
4936*22dc650dSSadaf Ebrahimi Feptr++;
4937*22dc650dSSadaf Ebrahimi }
4938*22dc650dSSadaf Ebrahimi break;
4939*22dc650dSSadaf Ebrahimi
4940*22dc650dSSadaf Ebrahimi case OP_WORDCHAR:
4941*22dc650dSSadaf Ebrahimi for (i = Lmin; i < Lmax; i++)
4942*22dc650dSSadaf Ebrahimi {
4943*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
4944*22dc650dSSadaf Ebrahimi {
4945*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
4946*22dc650dSSadaf Ebrahimi break;
4947*22dc650dSSadaf Ebrahimi }
4948*22dc650dSSadaf Ebrahimi if (!MAX_255(*Feptr) || (mb->ctypes[*Feptr] & ctype_word) == 0)
4949*22dc650dSSadaf Ebrahimi break;
4950*22dc650dSSadaf Ebrahimi Feptr++;
4951*22dc650dSSadaf Ebrahimi }
4952*22dc650dSSadaf Ebrahimi break;
4953*22dc650dSSadaf Ebrahimi
4954*22dc650dSSadaf Ebrahimi default:
4955*22dc650dSSadaf Ebrahimi return PCRE2_ERROR_INTERNAL;
4956*22dc650dSSadaf Ebrahimi }
4957*22dc650dSSadaf Ebrahimi
4958*22dc650dSSadaf Ebrahimi if (reptype == REPTYPE_POS) continue; /* No backtracking */
4959*22dc650dSSadaf Ebrahimi
4960*22dc650dSSadaf Ebrahimi for (;;)
4961*22dc650dSSadaf Ebrahimi {
4962*22dc650dSSadaf Ebrahimi if (Feptr == Lstart_eptr) break;
4963*22dc650dSSadaf Ebrahimi RMATCH(Fecode, RM34);
4964*22dc650dSSadaf Ebrahimi if (rrc != MATCH_NOMATCH) RRETURN(rrc);
4965*22dc650dSSadaf Ebrahimi Feptr--;
4966*22dc650dSSadaf Ebrahimi if (Lctype == OP_ANYNL && Feptr > Lstart_eptr && *Feptr == CHAR_LF &&
4967*22dc650dSSadaf Ebrahimi Feptr[-1] == CHAR_CR) Feptr--;
4968*22dc650dSSadaf Ebrahimi }
4969*22dc650dSSadaf Ebrahimi }
4970*22dc650dSSadaf Ebrahimi }
4971*22dc650dSSadaf Ebrahimi break; /* End of repeat character type processing */
4972*22dc650dSSadaf Ebrahimi
4973*22dc650dSSadaf Ebrahimi #undef Lstart_eptr
4974*22dc650dSSadaf Ebrahimi #undef Lmin
4975*22dc650dSSadaf Ebrahimi #undef Lmax
4976*22dc650dSSadaf Ebrahimi #undef Lctype
4977*22dc650dSSadaf Ebrahimi #undef Lpropvalue
4978*22dc650dSSadaf Ebrahimi
4979*22dc650dSSadaf Ebrahimi
4980*22dc650dSSadaf Ebrahimi /* ===================================================================== */
4981*22dc650dSSadaf Ebrahimi /* Match a back reference, possibly repeatedly. Look past the end of the
4982*22dc650dSSadaf Ebrahimi item to see if there is repeat information following. The OP_REF and
4983*22dc650dSSadaf Ebrahimi OP_REFI opcodes are used for a reference to a numbered group or to a
4984*22dc650dSSadaf Ebrahimi non-duplicated named group. For a duplicated named group, OP_DNREF and
4985*22dc650dSSadaf Ebrahimi OP_DNREFI are used. In this case we must scan the list of groups to which
4986*22dc650dSSadaf Ebrahimi the name refers, and use the first one that is set. */
4987*22dc650dSSadaf Ebrahimi
4988*22dc650dSSadaf Ebrahimi #define Lmin F->temp_32[0]
4989*22dc650dSSadaf Ebrahimi #define Lmax F->temp_32[1]
4990*22dc650dSSadaf Ebrahimi #define Lcaseless F->temp_32[2]
4991*22dc650dSSadaf Ebrahimi #define Lstart F->temp_sptr[0]
4992*22dc650dSSadaf Ebrahimi #define Loffset F->temp_size
4993*22dc650dSSadaf Ebrahimi
4994*22dc650dSSadaf Ebrahimi case OP_DNREF:
4995*22dc650dSSadaf Ebrahimi case OP_DNREFI:
4996*22dc650dSSadaf Ebrahimi Lcaseless = (Fop == OP_DNREFI);
4997*22dc650dSSadaf Ebrahimi {
4998*22dc650dSSadaf Ebrahimi int count = GET2(Fecode, 1+IMM2_SIZE);
4999*22dc650dSSadaf Ebrahimi PCRE2_SPTR slot = mb->name_table + GET2(Fecode, 1) * mb->name_entry_size;
5000*22dc650dSSadaf Ebrahimi Fecode += 1 + 2*IMM2_SIZE;
5001*22dc650dSSadaf Ebrahimi
5002*22dc650dSSadaf Ebrahimi while (count-- > 0)
5003*22dc650dSSadaf Ebrahimi {
5004*22dc650dSSadaf Ebrahimi Loffset = (GET2(slot, 0) << 1) - 2;
5005*22dc650dSSadaf Ebrahimi if (Loffset < Foffset_top && Fovector[Loffset] != PCRE2_UNSET) break;
5006*22dc650dSSadaf Ebrahimi slot += mb->name_entry_size;
5007*22dc650dSSadaf Ebrahimi }
5008*22dc650dSSadaf Ebrahimi }
5009*22dc650dSSadaf Ebrahimi goto REF_REPEAT;
5010*22dc650dSSadaf Ebrahimi
5011*22dc650dSSadaf Ebrahimi case OP_REF:
5012*22dc650dSSadaf Ebrahimi case OP_REFI:
5013*22dc650dSSadaf Ebrahimi Lcaseless = (Fop == OP_REFI);
5014*22dc650dSSadaf Ebrahimi Loffset = (GET2(Fecode, 1) << 1) - 2;
5015*22dc650dSSadaf Ebrahimi Fecode += 1 + IMM2_SIZE;
5016*22dc650dSSadaf Ebrahimi
5017*22dc650dSSadaf Ebrahimi /* Set up for repetition, or handle the non-repeated case. The maximum and
5018*22dc650dSSadaf Ebrahimi minimum must be in the heap frame, but as they are short-term values, we
5019*22dc650dSSadaf Ebrahimi use temporary fields. */
5020*22dc650dSSadaf Ebrahimi
5021*22dc650dSSadaf Ebrahimi REF_REPEAT:
5022*22dc650dSSadaf Ebrahimi switch (*Fecode)
5023*22dc650dSSadaf Ebrahimi {
5024*22dc650dSSadaf Ebrahimi case OP_CRSTAR:
5025*22dc650dSSadaf Ebrahimi case OP_CRMINSTAR:
5026*22dc650dSSadaf Ebrahimi case OP_CRPLUS:
5027*22dc650dSSadaf Ebrahimi case OP_CRMINPLUS:
5028*22dc650dSSadaf Ebrahimi case OP_CRQUERY:
5029*22dc650dSSadaf Ebrahimi case OP_CRMINQUERY:
5030*22dc650dSSadaf Ebrahimi fc = *Fecode++ - OP_CRSTAR;
5031*22dc650dSSadaf Ebrahimi Lmin = rep_min[fc];
5032*22dc650dSSadaf Ebrahimi Lmax = rep_max[fc];
5033*22dc650dSSadaf Ebrahimi reptype = rep_typ[fc];
5034*22dc650dSSadaf Ebrahimi break;
5035*22dc650dSSadaf Ebrahimi
5036*22dc650dSSadaf Ebrahimi case OP_CRRANGE:
5037*22dc650dSSadaf Ebrahimi case OP_CRMINRANGE:
5038*22dc650dSSadaf Ebrahimi Lmin = GET2(Fecode, 1);
5039*22dc650dSSadaf Ebrahimi Lmax = GET2(Fecode, 1 + IMM2_SIZE);
5040*22dc650dSSadaf Ebrahimi reptype = rep_typ[*Fecode - OP_CRSTAR];
5041*22dc650dSSadaf Ebrahimi if (Lmax == 0) Lmax = UINT32_MAX; /* Max 0 => infinity */
5042*22dc650dSSadaf Ebrahimi Fecode += 1 + 2 * IMM2_SIZE;
5043*22dc650dSSadaf Ebrahimi break;
5044*22dc650dSSadaf Ebrahimi
5045*22dc650dSSadaf Ebrahimi default: /* No repeat follows */
5046*22dc650dSSadaf Ebrahimi {
5047*22dc650dSSadaf Ebrahimi rrc = match_ref(Loffset, Lcaseless, F, mb, &length);
5048*22dc650dSSadaf Ebrahimi if (rrc != 0)
5049*22dc650dSSadaf Ebrahimi {
5050*22dc650dSSadaf Ebrahimi if (rrc > 0) Feptr = mb->end_subject; /* Partial match */
5051*22dc650dSSadaf Ebrahimi CHECK_PARTIAL();
5052*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
5053*22dc650dSSadaf Ebrahimi }
5054*22dc650dSSadaf Ebrahimi }
5055*22dc650dSSadaf Ebrahimi Feptr += length;
5056*22dc650dSSadaf Ebrahimi continue; /* With the main loop */
5057*22dc650dSSadaf Ebrahimi }
5058*22dc650dSSadaf Ebrahimi
5059*22dc650dSSadaf Ebrahimi /* Handle repeated back references. If a set group has length zero, just
5060*22dc650dSSadaf Ebrahimi continue with the main loop, because it matches however many times. For an
5061*22dc650dSSadaf Ebrahimi unset reference, if the minimum is zero, we can also just continue. We can
5062*22dc650dSSadaf Ebrahimi also continue if PCRE2_MATCH_UNSET_BACKREF is set, because this makes unset
5063*22dc650dSSadaf Ebrahimi group behave as a zero-length group. For any other unset cases, carrying
5064*22dc650dSSadaf Ebrahimi on will result in NOMATCH. */
5065*22dc650dSSadaf Ebrahimi
5066*22dc650dSSadaf Ebrahimi if (Loffset < Foffset_top && Fovector[Loffset] != PCRE2_UNSET)
5067*22dc650dSSadaf Ebrahimi {
5068*22dc650dSSadaf Ebrahimi if (Fovector[Loffset] == Fovector[Loffset + 1]) continue;
5069*22dc650dSSadaf Ebrahimi }
5070*22dc650dSSadaf Ebrahimi else /* Group is not set */
5071*22dc650dSSadaf Ebrahimi {
5072*22dc650dSSadaf Ebrahimi if (Lmin == 0 || (mb->poptions & PCRE2_MATCH_UNSET_BACKREF) != 0)
5073*22dc650dSSadaf Ebrahimi continue;
5074*22dc650dSSadaf Ebrahimi }
5075*22dc650dSSadaf Ebrahimi
5076*22dc650dSSadaf Ebrahimi /* First, ensure the minimum number of matches are present. */
5077*22dc650dSSadaf Ebrahimi
5078*22dc650dSSadaf Ebrahimi for (i = 1; i <= Lmin; i++)
5079*22dc650dSSadaf Ebrahimi {
5080*22dc650dSSadaf Ebrahimi PCRE2_SIZE slength;
5081*22dc650dSSadaf Ebrahimi rrc = match_ref(Loffset, Lcaseless, F, mb, &slength);
5082*22dc650dSSadaf Ebrahimi if (rrc != 0)
5083*22dc650dSSadaf Ebrahimi {
5084*22dc650dSSadaf Ebrahimi if (rrc > 0) Feptr = mb->end_subject; /* Partial match */
5085*22dc650dSSadaf Ebrahimi CHECK_PARTIAL();
5086*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
5087*22dc650dSSadaf Ebrahimi }
5088*22dc650dSSadaf Ebrahimi Feptr += slength;
5089*22dc650dSSadaf Ebrahimi }
5090*22dc650dSSadaf Ebrahimi
5091*22dc650dSSadaf Ebrahimi /* If min = max, we are done. They are not both allowed to be zero. */
5092*22dc650dSSadaf Ebrahimi
5093*22dc650dSSadaf Ebrahimi if (Lmin == Lmax) continue;
5094*22dc650dSSadaf Ebrahimi
5095*22dc650dSSadaf Ebrahimi /* If minimizing, keep trying and advancing the pointer. */
5096*22dc650dSSadaf Ebrahimi
5097*22dc650dSSadaf Ebrahimi if (reptype == REPTYPE_MIN)
5098*22dc650dSSadaf Ebrahimi {
5099*22dc650dSSadaf Ebrahimi for (;;)
5100*22dc650dSSadaf Ebrahimi {
5101*22dc650dSSadaf Ebrahimi PCRE2_SIZE slength;
5102*22dc650dSSadaf Ebrahimi RMATCH(Fecode, RM20);
5103*22dc650dSSadaf Ebrahimi if (rrc != MATCH_NOMATCH) RRETURN(rrc);
5104*22dc650dSSadaf Ebrahimi if (Lmin++ >= Lmax) RRETURN(MATCH_NOMATCH);
5105*22dc650dSSadaf Ebrahimi rrc = match_ref(Loffset, Lcaseless, F, mb, &slength);
5106*22dc650dSSadaf Ebrahimi if (rrc != 0)
5107*22dc650dSSadaf Ebrahimi {
5108*22dc650dSSadaf Ebrahimi if (rrc > 0) Feptr = mb->end_subject; /* Partial match */
5109*22dc650dSSadaf Ebrahimi CHECK_PARTIAL();
5110*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
5111*22dc650dSSadaf Ebrahimi }
5112*22dc650dSSadaf Ebrahimi Feptr += slength;
5113*22dc650dSSadaf Ebrahimi }
5114*22dc650dSSadaf Ebrahimi /* Control never gets here */
5115*22dc650dSSadaf Ebrahimi }
5116*22dc650dSSadaf Ebrahimi
5117*22dc650dSSadaf Ebrahimi /* If maximizing, find the longest string and work backwards, as long as
5118*22dc650dSSadaf Ebrahimi the matched lengths for each iteration are the same. */
5119*22dc650dSSadaf Ebrahimi
5120*22dc650dSSadaf Ebrahimi else
5121*22dc650dSSadaf Ebrahimi {
5122*22dc650dSSadaf Ebrahimi BOOL samelengths = TRUE;
5123*22dc650dSSadaf Ebrahimi Lstart = Feptr; /* Starting position */
5124*22dc650dSSadaf Ebrahimi Flength = Fovector[Loffset+1] - Fovector[Loffset];
5125*22dc650dSSadaf Ebrahimi
5126*22dc650dSSadaf Ebrahimi for (i = Lmin; i < Lmax; i++)
5127*22dc650dSSadaf Ebrahimi {
5128*22dc650dSSadaf Ebrahimi PCRE2_SIZE slength;
5129*22dc650dSSadaf Ebrahimi rrc = match_ref(Loffset, Lcaseless, F, mb, &slength);
5130*22dc650dSSadaf Ebrahimi if (rrc != 0)
5131*22dc650dSSadaf Ebrahimi {
5132*22dc650dSSadaf Ebrahimi /* Can't use CHECK_PARTIAL because we don't want to update Feptr in
5133*22dc650dSSadaf Ebrahimi the soft partial matching case. */
5134*22dc650dSSadaf Ebrahimi
5135*22dc650dSSadaf Ebrahimi if (rrc > 0 && mb->partial != 0 &&
5136*22dc650dSSadaf Ebrahimi mb->end_subject > mb->start_used_ptr)
5137*22dc650dSSadaf Ebrahimi {
5138*22dc650dSSadaf Ebrahimi mb->hitend = TRUE;
5139*22dc650dSSadaf Ebrahimi if (mb->partial > 1) return PCRE2_ERROR_PARTIAL;
5140*22dc650dSSadaf Ebrahimi }
5141*22dc650dSSadaf Ebrahimi break;
5142*22dc650dSSadaf Ebrahimi }
5143*22dc650dSSadaf Ebrahimi
5144*22dc650dSSadaf Ebrahimi if (slength != Flength) samelengths = FALSE;
5145*22dc650dSSadaf Ebrahimi Feptr += slength;
5146*22dc650dSSadaf Ebrahimi }
5147*22dc650dSSadaf Ebrahimi
5148*22dc650dSSadaf Ebrahimi /* If the length matched for each repetition is the same as the length of
5149*22dc650dSSadaf Ebrahimi the captured group, we can easily work backwards. This is the normal
5150*22dc650dSSadaf Ebrahimi case. However, in caseless UTF-8 mode there are pairs of case-equivalent
5151*22dc650dSSadaf Ebrahimi characters whose lengths (in terms of code units) differ. However, this
5152*22dc650dSSadaf Ebrahimi is very rare, so we handle it by re-matching fewer and fewer times. */
5153*22dc650dSSadaf Ebrahimi
5154*22dc650dSSadaf Ebrahimi if (samelengths)
5155*22dc650dSSadaf Ebrahimi {
5156*22dc650dSSadaf Ebrahimi while (Feptr >= Lstart)
5157*22dc650dSSadaf Ebrahimi {
5158*22dc650dSSadaf Ebrahimi RMATCH(Fecode, RM21);
5159*22dc650dSSadaf Ebrahimi if (rrc != MATCH_NOMATCH) RRETURN(rrc);
5160*22dc650dSSadaf Ebrahimi Feptr -= Flength;
5161*22dc650dSSadaf Ebrahimi }
5162*22dc650dSSadaf Ebrahimi }
5163*22dc650dSSadaf Ebrahimi
5164*22dc650dSSadaf Ebrahimi /* The rare case of non-matching lengths. Re-scan the repetition for each
5165*22dc650dSSadaf Ebrahimi iteration. We know that match_ref() will succeed every time. */
5166*22dc650dSSadaf Ebrahimi
5167*22dc650dSSadaf Ebrahimi else
5168*22dc650dSSadaf Ebrahimi {
5169*22dc650dSSadaf Ebrahimi Lmax = i;
5170*22dc650dSSadaf Ebrahimi for (;;)
5171*22dc650dSSadaf Ebrahimi {
5172*22dc650dSSadaf Ebrahimi RMATCH(Fecode, RM22);
5173*22dc650dSSadaf Ebrahimi if (rrc != MATCH_NOMATCH) RRETURN(rrc);
5174*22dc650dSSadaf Ebrahimi if (Feptr == Lstart) break; /* Failed after minimal repetition */
5175*22dc650dSSadaf Ebrahimi Feptr = Lstart;
5176*22dc650dSSadaf Ebrahimi Lmax--;
5177*22dc650dSSadaf Ebrahimi for (i = Lmin; i < Lmax; i++)
5178*22dc650dSSadaf Ebrahimi {
5179*22dc650dSSadaf Ebrahimi PCRE2_SIZE slength;
5180*22dc650dSSadaf Ebrahimi (void)match_ref(Loffset, Lcaseless, F, mb, &slength);
5181*22dc650dSSadaf Ebrahimi Feptr += slength;
5182*22dc650dSSadaf Ebrahimi }
5183*22dc650dSSadaf Ebrahimi }
5184*22dc650dSSadaf Ebrahimi }
5185*22dc650dSSadaf Ebrahimi
5186*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
5187*22dc650dSSadaf Ebrahimi }
5188*22dc650dSSadaf Ebrahimi /* Control never gets here */
5189*22dc650dSSadaf Ebrahimi
5190*22dc650dSSadaf Ebrahimi #undef Lcaseless
5191*22dc650dSSadaf Ebrahimi #undef Lmin
5192*22dc650dSSadaf Ebrahimi #undef Lmax
5193*22dc650dSSadaf Ebrahimi #undef Lstart
5194*22dc650dSSadaf Ebrahimi #undef Loffset
5195*22dc650dSSadaf Ebrahimi
5196*22dc650dSSadaf Ebrahimi
5197*22dc650dSSadaf Ebrahimi
5198*22dc650dSSadaf Ebrahimi /* ========================================================================= */
5199*22dc650dSSadaf Ebrahimi /* Opcodes for the start of various parenthesized items */
5200*22dc650dSSadaf Ebrahimi /* ========================================================================= */
5201*22dc650dSSadaf Ebrahimi
5202*22dc650dSSadaf Ebrahimi /* In all cases, if the result of RMATCH() is MATCH_THEN, check whether the
5203*22dc650dSSadaf Ebrahimi (*THEN) is within the current branch by comparing the address of OP_THEN
5204*22dc650dSSadaf Ebrahimi that is passed back with the end of the branch. If (*THEN) is within the
5205*22dc650dSSadaf Ebrahimi current branch, and the branch is one of two or more alternatives (it
5206*22dc650dSSadaf Ebrahimi either starts or ends with OP_ALT), we have reached the limit of THEN's
5207*22dc650dSSadaf Ebrahimi action, so convert the return code to NOMATCH, which will cause normal
5208*22dc650dSSadaf Ebrahimi backtracking to happen from now on. Otherwise, THEN is passed back to an
5209*22dc650dSSadaf Ebrahimi outer alternative. This implements Perl's treatment of parenthesized
5210*22dc650dSSadaf Ebrahimi groups, where a group not containing | does not affect the current
5211*22dc650dSSadaf Ebrahimi alternative, that is, (X) is NOT the same as (X|(*F)). */
5212*22dc650dSSadaf Ebrahimi
5213*22dc650dSSadaf Ebrahimi
5214*22dc650dSSadaf Ebrahimi /* ===================================================================== */
5215*22dc650dSSadaf Ebrahimi /* BRAZERO, BRAMINZERO and SKIPZERO occur just before a non-possessive
5216*22dc650dSSadaf Ebrahimi bracket group, indicating that it may occur zero times. It may repeat
5217*22dc650dSSadaf Ebrahimi infinitely, or not at all - i.e. it could be ()* or ()? or even (){0} in
5218*22dc650dSSadaf Ebrahimi the pattern. Brackets with fixed upper repeat limits are compiled as a
5219*22dc650dSSadaf Ebrahimi number of copies, with the optional ones preceded by BRAZERO or BRAMINZERO.
5220*22dc650dSSadaf Ebrahimi Possessive groups with possible zero repeats are preceded by BRAPOSZERO. */
5221*22dc650dSSadaf Ebrahimi
5222*22dc650dSSadaf Ebrahimi #define Lnext_ecode F->temp_sptr[0]
5223*22dc650dSSadaf Ebrahimi
5224*22dc650dSSadaf Ebrahimi case OP_BRAZERO:
5225*22dc650dSSadaf Ebrahimi Lnext_ecode = Fecode + 1;
5226*22dc650dSSadaf Ebrahimi RMATCH(Lnext_ecode, RM9);
5227*22dc650dSSadaf Ebrahimi if (rrc != MATCH_NOMATCH) RRETURN(rrc);
5228*22dc650dSSadaf Ebrahimi do Lnext_ecode += GET(Lnext_ecode, 1); while (*Lnext_ecode == OP_ALT);
5229*22dc650dSSadaf Ebrahimi Fecode = Lnext_ecode + 1 + LINK_SIZE;
5230*22dc650dSSadaf Ebrahimi break;
5231*22dc650dSSadaf Ebrahimi
5232*22dc650dSSadaf Ebrahimi case OP_BRAMINZERO:
5233*22dc650dSSadaf Ebrahimi Lnext_ecode = Fecode + 1;
5234*22dc650dSSadaf Ebrahimi do Lnext_ecode += GET(Lnext_ecode, 1); while (*Lnext_ecode == OP_ALT);
5235*22dc650dSSadaf Ebrahimi RMATCH(Lnext_ecode + 1 + LINK_SIZE, RM10);
5236*22dc650dSSadaf Ebrahimi if (rrc != MATCH_NOMATCH) RRETURN(rrc);
5237*22dc650dSSadaf Ebrahimi Fecode++;
5238*22dc650dSSadaf Ebrahimi break;
5239*22dc650dSSadaf Ebrahimi
5240*22dc650dSSadaf Ebrahimi #undef Lnext_ecode
5241*22dc650dSSadaf Ebrahimi
5242*22dc650dSSadaf Ebrahimi case OP_SKIPZERO:
5243*22dc650dSSadaf Ebrahimi Fecode++;
5244*22dc650dSSadaf Ebrahimi do Fecode += GET(Fecode,1); while (*Fecode == OP_ALT);
5245*22dc650dSSadaf Ebrahimi Fecode += 1 + LINK_SIZE;
5246*22dc650dSSadaf Ebrahimi break;
5247*22dc650dSSadaf Ebrahimi
5248*22dc650dSSadaf Ebrahimi
5249*22dc650dSSadaf Ebrahimi /* ===================================================================== */
5250*22dc650dSSadaf Ebrahimi /* Handle possessive brackets with an unlimited repeat. The end of these
5251*22dc650dSSadaf Ebrahimi brackets will always be OP_KETRPOS, which returns MATCH_KETRPOS without
5252*22dc650dSSadaf Ebrahimi going further in the pattern. */
5253*22dc650dSSadaf Ebrahimi
5254*22dc650dSSadaf Ebrahimi #define Lframe_type F->temp_32[0]
5255*22dc650dSSadaf Ebrahimi #define Lmatched_once F->temp_32[1]
5256*22dc650dSSadaf Ebrahimi #define Lzero_allowed F->temp_32[2]
5257*22dc650dSSadaf Ebrahimi #define Lstart_eptr F->temp_sptr[0]
5258*22dc650dSSadaf Ebrahimi #define Lstart_group F->temp_sptr[1]
5259*22dc650dSSadaf Ebrahimi
5260*22dc650dSSadaf Ebrahimi case OP_BRAPOSZERO:
5261*22dc650dSSadaf Ebrahimi Lzero_allowed = TRUE; /* Zero repeat is allowed */
5262*22dc650dSSadaf Ebrahimi Fecode += 1;
5263*22dc650dSSadaf Ebrahimi if (*Fecode == OP_CBRAPOS || *Fecode == OP_SCBRAPOS)
5264*22dc650dSSadaf Ebrahimi goto POSSESSIVE_CAPTURE;
5265*22dc650dSSadaf Ebrahimi goto POSSESSIVE_NON_CAPTURE;
5266*22dc650dSSadaf Ebrahimi
5267*22dc650dSSadaf Ebrahimi case OP_BRAPOS:
5268*22dc650dSSadaf Ebrahimi case OP_SBRAPOS:
5269*22dc650dSSadaf Ebrahimi Lzero_allowed = FALSE; /* Zero repeat not allowed */
5270*22dc650dSSadaf Ebrahimi
5271*22dc650dSSadaf Ebrahimi POSSESSIVE_NON_CAPTURE:
5272*22dc650dSSadaf Ebrahimi Lframe_type = GF_NOCAPTURE; /* Remembered frame type */
5273*22dc650dSSadaf Ebrahimi goto POSSESSIVE_GROUP;
5274*22dc650dSSadaf Ebrahimi
5275*22dc650dSSadaf Ebrahimi case OP_CBRAPOS:
5276*22dc650dSSadaf Ebrahimi case OP_SCBRAPOS:
5277*22dc650dSSadaf Ebrahimi Lzero_allowed = FALSE; /* Zero repeat not allowed */
5278*22dc650dSSadaf Ebrahimi
5279*22dc650dSSadaf Ebrahimi POSSESSIVE_CAPTURE:
5280*22dc650dSSadaf Ebrahimi number = GET2(Fecode, 1+LINK_SIZE);
5281*22dc650dSSadaf Ebrahimi Lframe_type = GF_CAPTURE | number; /* Remembered frame type */
5282*22dc650dSSadaf Ebrahimi
5283*22dc650dSSadaf Ebrahimi POSSESSIVE_GROUP:
5284*22dc650dSSadaf Ebrahimi Lmatched_once = FALSE; /* Never matched */
5285*22dc650dSSadaf Ebrahimi Lstart_group = Fecode; /* Start of this group */
5286*22dc650dSSadaf Ebrahimi
5287*22dc650dSSadaf Ebrahimi for (;;)
5288*22dc650dSSadaf Ebrahimi {
5289*22dc650dSSadaf Ebrahimi Lstart_eptr = Feptr; /* Position at group start */
5290*22dc650dSSadaf Ebrahimi group_frame_type = Lframe_type;
5291*22dc650dSSadaf Ebrahimi RMATCH(Fecode + PRIV(OP_lengths)[*Fecode], RM8);
5292*22dc650dSSadaf Ebrahimi if (rrc == MATCH_KETRPOS)
5293*22dc650dSSadaf Ebrahimi {
5294*22dc650dSSadaf Ebrahimi Lmatched_once = TRUE; /* Matched at least once */
5295*22dc650dSSadaf Ebrahimi if (Feptr == Lstart_eptr) /* Empty match; skip to end */
5296*22dc650dSSadaf Ebrahimi {
5297*22dc650dSSadaf Ebrahimi do Fecode += GET(Fecode, 1); while (*Fecode == OP_ALT);
5298*22dc650dSSadaf Ebrahimi break;
5299*22dc650dSSadaf Ebrahimi }
5300*22dc650dSSadaf Ebrahimi
5301*22dc650dSSadaf Ebrahimi Fecode = Lstart_group;
5302*22dc650dSSadaf Ebrahimi continue;
5303*22dc650dSSadaf Ebrahimi }
5304*22dc650dSSadaf Ebrahimi
5305*22dc650dSSadaf Ebrahimi /* See comment above about handling THEN. */
5306*22dc650dSSadaf Ebrahimi
5307*22dc650dSSadaf Ebrahimi if (rrc == MATCH_THEN)
5308*22dc650dSSadaf Ebrahimi {
5309*22dc650dSSadaf Ebrahimi PCRE2_SPTR next_ecode = Fecode + GET(Fecode,1);
5310*22dc650dSSadaf Ebrahimi if (mb->verb_ecode_ptr < next_ecode &&
5311*22dc650dSSadaf Ebrahimi (*Fecode == OP_ALT || *next_ecode == OP_ALT))
5312*22dc650dSSadaf Ebrahimi rrc = MATCH_NOMATCH;
5313*22dc650dSSadaf Ebrahimi }
5314*22dc650dSSadaf Ebrahimi
5315*22dc650dSSadaf Ebrahimi if (rrc != MATCH_NOMATCH) RRETURN(rrc);
5316*22dc650dSSadaf Ebrahimi Fecode += GET(Fecode, 1);
5317*22dc650dSSadaf Ebrahimi if (*Fecode != OP_ALT) break;
5318*22dc650dSSadaf Ebrahimi }
5319*22dc650dSSadaf Ebrahimi
5320*22dc650dSSadaf Ebrahimi /* Success if matched something or zero repeat allowed */
5321*22dc650dSSadaf Ebrahimi
5322*22dc650dSSadaf Ebrahimi if (Lmatched_once || Lzero_allowed)
5323*22dc650dSSadaf Ebrahimi {
5324*22dc650dSSadaf Ebrahimi Fecode += 1 + LINK_SIZE;
5325*22dc650dSSadaf Ebrahimi break;
5326*22dc650dSSadaf Ebrahimi }
5327*22dc650dSSadaf Ebrahimi
5328*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
5329*22dc650dSSadaf Ebrahimi
5330*22dc650dSSadaf Ebrahimi #undef Lmatched_once
5331*22dc650dSSadaf Ebrahimi #undef Lzero_allowed
5332*22dc650dSSadaf Ebrahimi #undef Lframe_type
5333*22dc650dSSadaf Ebrahimi #undef Lstart_eptr
5334*22dc650dSSadaf Ebrahimi #undef Lstart_group
5335*22dc650dSSadaf Ebrahimi
5336*22dc650dSSadaf Ebrahimi
5337*22dc650dSSadaf Ebrahimi /* ===================================================================== */
5338*22dc650dSSadaf Ebrahimi /* Handle non-capturing brackets that cannot match an empty string. When we
5339*22dc650dSSadaf Ebrahimi get to the final alternative within the brackets, as long as there are no
5340*22dc650dSSadaf Ebrahimi THEN's in the pattern, we can optimize by not recording a new backtracking
5341*22dc650dSSadaf Ebrahimi point. (Ideally we should test for a THEN within this group, but we don't
5342*22dc650dSSadaf Ebrahimi have that information.) Don't do this if we are at the very top level,
5343*22dc650dSSadaf Ebrahimi however, because that would make handling assertions and once-only brackets
5344*22dc650dSSadaf Ebrahimi messier when there is nothing to go back to. */
5345*22dc650dSSadaf Ebrahimi
5346*22dc650dSSadaf Ebrahimi #define Lframe_type F->temp_32[0] /* Set for all that use GROUPLOOP */
5347*22dc650dSSadaf Ebrahimi #define Lnext_branch F->temp_sptr[0] /* Used only in OP_BRA handling */
5348*22dc650dSSadaf Ebrahimi
5349*22dc650dSSadaf Ebrahimi case OP_BRA:
5350*22dc650dSSadaf Ebrahimi if (mb->hasthen || Frdepth == 0)
5351*22dc650dSSadaf Ebrahimi {
5352*22dc650dSSadaf Ebrahimi Lframe_type = 0;
5353*22dc650dSSadaf Ebrahimi goto GROUPLOOP;
5354*22dc650dSSadaf Ebrahimi }
5355*22dc650dSSadaf Ebrahimi
5356*22dc650dSSadaf Ebrahimi for (;;)
5357*22dc650dSSadaf Ebrahimi {
5358*22dc650dSSadaf Ebrahimi Lnext_branch = Fecode + GET(Fecode, 1);
5359*22dc650dSSadaf Ebrahimi if (*Lnext_branch != OP_ALT) break;
5360*22dc650dSSadaf Ebrahimi
5361*22dc650dSSadaf Ebrahimi /* This is never the final branch. We do not need to test for MATCH_THEN
5362*22dc650dSSadaf Ebrahimi here because this code is not used when there is a THEN in the pattern. */
5363*22dc650dSSadaf Ebrahimi
5364*22dc650dSSadaf Ebrahimi RMATCH(Fecode + PRIV(OP_lengths)[*Fecode], RM1);
5365*22dc650dSSadaf Ebrahimi if (rrc != MATCH_NOMATCH) RRETURN(rrc);
5366*22dc650dSSadaf Ebrahimi Fecode = Lnext_branch;
5367*22dc650dSSadaf Ebrahimi }
5368*22dc650dSSadaf Ebrahimi
5369*22dc650dSSadaf Ebrahimi /* Hit the start of the final branch. Continue at this level. */
5370*22dc650dSSadaf Ebrahimi
5371*22dc650dSSadaf Ebrahimi Fecode += PRIV(OP_lengths)[*Fecode];
5372*22dc650dSSadaf Ebrahimi break;
5373*22dc650dSSadaf Ebrahimi
5374*22dc650dSSadaf Ebrahimi #undef Lnext_branch
5375*22dc650dSSadaf Ebrahimi
5376*22dc650dSSadaf Ebrahimi
5377*22dc650dSSadaf Ebrahimi /* ===================================================================== */
5378*22dc650dSSadaf Ebrahimi /* Handle a capturing bracket, other than those that are possessive with an
5379*22dc650dSSadaf Ebrahimi unlimited repeat. */
5380*22dc650dSSadaf Ebrahimi
5381*22dc650dSSadaf Ebrahimi case OP_CBRA:
5382*22dc650dSSadaf Ebrahimi case OP_SCBRA:
5383*22dc650dSSadaf Ebrahimi Lframe_type = GF_CAPTURE | GET2(Fecode, 1+LINK_SIZE);
5384*22dc650dSSadaf Ebrahimi goto GROUPLOOP;
5385*22dc650dSSadaf Ebrahimi
5386*22dc650dSSadaf Ebrahimi
5387*22dc650dSSadaf Ebrahimi /* ===================================================================== */
5388*22dc650dSSadaf Ebrahimi /* Atomic groups and non-capturing brackets that can match an empty string
5389*22dc650dSSadaf Ebrahimi must record a backtracking point and also set up a chained frame. */
5390*22dc650dSSadaf Ebrahimi
5391*22dc650dSSadaf Ebrahimi case OP_ONCE:
5392*22dc650dSSadaf Ebrahimi case OP_SCRIPT_RUN:
5393*22dc650dSSadaf Ebrahimi case OP_SBRA:
5394*22dc650dSSadaf Ebrahimi Lframe_type = GF_NOCAPTURE | Fop;
5395*22dc650dSSadaf Ebrahimi
5396*22dc650dSSadaf Ebrahimi GROUPLOOP:
5397*22dc650dSSadaf Ebrahimi for (;;)
5398*22dc650dSSadaf Ebrahimi {
5399*22dc650dSSadaf Ebrahimi group_frame_type = Lframe_type;
5400*22dc650dSSadaf Ebrahimi RMATCH(Fecode + PRIV(OP_lengths)[*Fecode], RM2);
5401*22dc650dSSadaf Ebrahimi if (rrc == MATCH_THEN)
5402*22dc650dSSadaf Ebrahimi {
5403*22dc650dSSadaf Ebrahimi PCRE2_SPTR next_ecode = Fecode + GET(Fecode,1);
5404*22dc650dSSadaf Ebrahimi if (mb->verb_ecode_ptr < next_ecode &&
5405*22dc650dSSadaf Ebrahimi (*Fecode == OP_ALT || *next_ecode == OP_ALT))
5406*22dc650dSSadaf Ebrahimi rrc = MATCH_NOMATCH;
5407*22dc650dSSadaf Ebrahimi }
5408*22dc650dSSadaf Ebrahimi if (rrc != MATCH_NOMATCH) RRETURN(rrc);
5409*22dc650dSSadaf Ebrahimi Fecode += GET(Fecode, 1);
5410*22dc650dSSadaf Ebrahimi if (*Fecode != OP_ALT) RRETURN(MATCH_NOMATCH);
5411*22dc650dSSadaf Ebrahimi }
5412*22dc650dSSadaf Ebrahimi /* Control never reaches here. */
5413*22dc650dSSadaf Ebrahimi
5414*22dc650dSSadaf Ebrahimi #undef Lframe_type
5415*22dc650dSSadaf Ebrahimi
5416*22dc650dSSadaf Ebrahimi
5417*22dc650dSSadaf Ebrahimi /* ===================================================================== */
5418*22dc650dSSadaf Ebrahimi /* Pattern recursion either matches the current regex, or some
5419*22dc650dSSadaf Ebrahimi subexpression. The offset data is the offset to the starting bracket from
5420*22dc650dSSadaf Ebrahimi the start of the whole pattern. This is so that it works from duplicated
5421*22dc650dSSadaf Ebrahimi subpatterns. For a whole-pattern recursion, we have to infer the number
5422*22dc650dSSadaf Ebrahimi zero. */
5423*22dc650dSSadaf Ebrahimi
5424*22dc650dSSadaf Ebrahimi #define Lframe_type F->temp_32[0]
5425*22dc650dSSadaf Ebrahimi #define Lstart_branch F->temp_sptr[0]
5426*22dc650dSSadaf Ebrahimi
5427*22dc650dSSadaf Ebrahimi case OP_RECURSE:
5428*22dc650dSSadaf Ebrahimi bracode = mb->start_code + GET(Fecode, 1);
5429*22dc650dSSadaf Ebrahimi number = (bracode == mb->start_code)? 0 : GET2(bracode, 1 + LINK_SIZE);
5430*22dc650dSSadaf Ebrahimi
5431*22dc650dSSadaf Ebrahimi /* If we are already in a pattern recursion, check for repeating the same
5432*22dc650dSSadaf Ebrahimi one without changing the subject pointer or the last referenced character
5433*22dc650dSSadaf Ebrahimi in the subject. This should catch convoluted mutual recursions; some
5434*22dc650dSSadaf Ebrahimi simple cases are caught at compile time. However, there are rare cases when
5435*22dc650dSSadaf Ebrahimi this check needs to be turned off. In this case, actual recursion loops
5436*22dc650dSSadaf Ebrahimi will be caught by the match or heap limits. */
5437*22dc650dSSadaf Ebrahimi
5438*22dc650dSSadaf Ebrahimi if (Fcurrent_recurse != RECURSE_UNSET)
5439*22dc650dSSadaf Ebrahimi {
5440*22dc650dSSadaf Ebrahimi offset = Flast_group_offset;
5441*22dc650dSSadaf Ebrahimi while (offset != PCRE2_UNSET)
5442*22dc650dSSadaf Ebrahimi {
5443*22dc650dSSadaf Ebrahimi N = (heapframe *)((char *)match_data->heapframes + offset);
5444*22dc650dSSadaf Ebrahimi P = (heapframe *)((char *)N - frame_size);
5445*22dc650dSSadaf Ebrahimi if (N->group_frame_type == (GF_RECURSE | number))
5446*22dc650dSSadaf Ebrahimi {
5447*22dc650dSSadaf Ebrahimi if (Feptr == P->eptr && mb->last_used_ptr == P->recurse_last_used &&
5448*22dc650dSSadaf Ebrahimi (mb->moptions & PCRE2_DISABLE_RECURSELOOP_CHECK) == 0)
5449*22dc650dSSadaf Ebrahimi return PCRE2_ERROR_RECURSELOOP;
5450*22dc650dSSadaf Ebrahimi break;
5451*22dc650dSSadaf Ebrahimi }
5452*22dc650dSSadaf Ebrahimi offset = P->last_group_offset;
5453*22dc650dSSadaf Ebrahimi }
5454*22dc650dSSadaf Ebrahimi }
5455*22dc650dSSadaf Ebrahimi
5456*22dc650dSSadaf Ebrahimi /* Remember the current last referenced character and then run the
5457*22dc650dSSadaf Ebrahimi recursion branch by branch. */
5458*22dc650dSSadaf Ebrahimi
5459*22dc650dSSadaf Ebrahimi F->recurse_last_used = mb->last_used_ptr;
5460*22dc650dSSadaf Ebrahimi Lstart_branch = bracode;
5461*22dc650dSSadaf Ebrahimi Lframe_type = GF_RECURSE | number;
5462*22dc650dSSadaf Ebrahimi
5463*22dc650dSSadaf Ebrahimi for (;;)
5464*22dc650dSSadaf Ebrahimi {
5465*22dc650dSSadaf Ebrahimi PCRE2_SPTR next_ecode;
5466*22dc650dSSadaf Ebrahimi
5467*22dc650dSSadaf Ebrahimi group_frame_type = Lframe_type;
5468*22dc650dSSadaf Ebrahimi RMATCH(Lstart_branch + PRIV(OP_lengths)[*Lstart_branch], RM11);
5469*22dc650dSSadaf Ebrahimi next_ecode = Lstart_branch + GET(Lstart_branch,1);
5470*22dc650dSSadaf Ebrahimi
5471*22dc650dSSadaf Ebrahimi /* Handle backtracking verbs, which are defined in a range that can
5472*22dc650dSSadaf Ebrahimi easily be tested for. PCRE does not allow THEN, SKIP, PRUNE or COMMIT to
5473*22dc650dSSadaf Ebrahimi escape beyond a recursion; they cause a NOMATCH for the entire recursion.
5474*22dc650dSSadaf Ebrahimi
5475*22dc650dSSadaf Ebrahimi When one of these verbs triggers, the current recursion group number is
5476*22dc650dSSadaf Ebrahimi recorded. If it matches the recursion we are processing, the verb
5477*22dc650dSSadaf Ebrahimi happened within the recursion and we must deal with it. Otherwise it must
5478*22dc650dSSadaf Ebrahimi have happened after the recursion completed, and so has to be passed
5479*22dc650dSSadaf Ebrahimi back. See comment above about handling THEN. */
5480*22dc650dSSadaf Ebrahimi
5481*22dc650dSSadaf Ebrahimi if (rrc >= MATCH_BACKTRACK_MIN && rrc <= MATCH_BACKTRACK_MAX &&
5482*22dc650dSSadaf Ebrahimi mb->verb_current_recurse == (Lframe_type ^ GF_RECURSE))
5483*22dc650dSSadaf Ebrahimi {
5484*22dc650dSSadaf Ebrahimi if (rrc == MATCH_THEN && mb->verb_ecode_ptr < next_ecode &&
5485*22dc650dSSadaf Ebrahimi (*Lstart_branch == OP_ALT || *next_ecode == OP_ALT))
5486*22dc650dSSadaf Ebrahimi rrc = MATCH_NOMATCH;
5487*22dc650dSSadaf Ebrahimi else RRETURN(MATCH_NOMATCH);
5488*22dc650dSSadaf Ebrahimi }
5489*22dc650dSSadaf Ebrahimi
5490*22dc650dSSadaf Ebrahimi /* Note that carrying on after (*ACCEPT) in a recursion is handled in the
5491*22dc650dSSadaf Ebrahimi OP_ACCEPT code. Nothing needs to be done here. */
5492*22dc650dSSadaf Ebrahimi
5493*22dc650dSSadaf Ebrahimi if (rrc != MATCH_NOMATCH) RRETURN(rrc);
5494*22dc650dSSadaf Ebrahimi Lstart_branch = next_ecode;
5495*22dc650dSSadaf Ebrahimi if (*Lstart_branch != OP_ALT) RRETURN(MATCH_NOMATCH);
5496*22dc650dSSadaf Ebrahimi }
5497*22dc650dSSadaf Ebrahimi /* Control never reaches here. */
5498*22dc650dSSadaf Ebrahimi
5499*22dc650dSSadaf Ebrahimi #undef Lframe_type
5500*22dc650dSSadaf Ebrahimi #undef Lstart_branch
5501*22dc650dSSadaf Ebrahimi
5502*22dc650dSSadaf Ebrahimi
5503*22dc650dSSadaf Ebrahimi /* ===================================================================== */
5504*22dc650dSSadaf Ebrahimi /* Positive assertions are like other groups except that PCRE doesn't allow
5505*22dc650dSSadaf Ebrahimi the effect of (*THEN) to escape beyond an assertion; it is therefore
5506*22dc650dSSadaf Ebrahimi treated as NOMATCH. (*ACCEPT) is treated as successful assertion, with its
5507*22dc650dSSadaf Ebrahimi captures and mark retained. Any other return is an error. */
5508*22dc650dSSadaf Ebrahimi
5509*22dc650dSSadaf Ebrahimi #define Lframe_type F->temp_32[0]
5510*22dc650dSSadaf Ebrahimi
5511*22dc650dSSadaf Ebrahimi case OP_ASSERT:
5512*22dc650dSSadaf Ebrahimi case OP_ASSERTBACK:
5513*22dc650dSSadaf Ebrahimi case OP_ASSERT_NA:
5514*22dc650dSSadaf Ebrahimi case OP_ASSERTBACK_NA:
5515*22dc650dSSadaf Ebrahimi Lframe_type = GF_NOCAPTURE | Fop;
5516*22dc650dSSadaf Ebrahimi for (;;)
5517*22dc650dSSadaf Ebrahimi {
5518*22dc650dSSadaf Ebrahimi group_frame_type = Lframe_type;
5519*22dc650dSSadaf Ebrahimi RMATCH(Fecode + PRIV(OP_lengths)[*Fecode], RM3);
5520*22dc650dSSadaf Ebrahimi if (rrc == MATCH_ACCEPT)
5521*22dc650dSSadaf Ebrahimi {
5522*22dc650dSSadaf Ebrahimi memcpy(Fovector,
5523*22dc650dSSadaf Ebrahimi (char *)assert_accept_frame + offsetof(heapframe, ovector),
5524*22dc650dSSadaf Ebrahimi assert_accept_frame->offset_top * sizeof(PCRE2_SIZE));
5525*22dc650dSSadaf Ebrahimi Foffset_top = assert_accept_frame->offset_top;
5526*22dc650dSSadaf Ebrahimi Fmark = assert_accept_frame->mark;
5527*22dc650dSSadaf Ebrahimi break;
5528*22dc650dSSadaf Ebrahimi }
5529*22dc650dSSadaf Ebrahimi if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);
5530*22dc650dSSadaf Ebrahimi Fecode += GET(Fecode, 1);
5531*22dc650dSSadaf Ebrahimi if (*Fecode != OP_ALT) RRETURN(MATCH_NOMATCH);
5532*22dc650dSSadaf Ebrahimi }
5533*22dc650dSSadaf Ebrahimi
5534*22dc650dSSadaf Ebrahimi do Fecode += GET(Fecode, 1); while (*Fecode == OP_ALT);
5535*22dc650dSSadaf Ebrahimi Fecode += 1 + LINK_SIZE;
5536*22dc650dSSadaf Ebrahimi break;
5537*22dc650dSSadaf Ebrahimi
5538*22dc650dSSadaf Ebrahimi #undef Lframe_type
5539*22dc650dSSadaf Ebrahimi
5540*22dc650dSSadaf Ebrahimi
5541*22dc650dSSadaf Ebrahimi /* ===================================================================== */
5542*22dc650dSSadaf Ebrahimi /* Handle negative assertions. Loop for each non-matching branch as for
5543*22dc650dSSadaf Ebrahimi positive assertions. */
5544*22dc650dSSadaf Ebrahimi
5545*22dc650dSSadaf Ebrahimi #define Lframe_type F->temp_32[0]
5546*22dc650dSSadaf Ebrahimi
5547*22dc650dSSadaf Ebrahimi case OP_ASSERT_NOT:
5548*22dc650dSSadaf Ebrahimi case OP_ASSERTBACK_NOT:
5549*22dc650dSSadaf Ebrahimi Lframe_type = GF_NOCAPTURE | Fop;
5550*22dc650dSSadaf Ebrahimi
5551*22dc650dSSadaf Ebrahimi for (;;)
5552*22dc650dSSadaf Ebrahimi {
5553*22dc650dSSadaf Ebrahimi group_frame_type = Lframe_type;
5554*22dc650dSSadaf Ebrahimi RMATCH(Fecode + PRIV(OP_lengths)[*Fecode], RM4);
5555*22dc650dSSadaf Ebrahimi switch(rrc)
5556*22dc650dSSadaf Ebrahimi {
5557*22dc650dSSadaf Ebrahimi case MATCH_ACCEPT: /* Assertion matched, therefore it fails. */
5558*22dc650dSSadaf Ebrahimi case MATCH_MATCH:
5559*22dc650dSSadaf Ebrahimi RRETURN (MATCH_NOMATCH);
5560*22dc650dSSadaf Ebrahimi
5561*22dc650dSSadaf Ebrahimi case MATCH_NOMATCH: /* Branch failed, try next if present. */
5562*22dc650dSSadaf Ebrahimi case MATCH_THEN:
5563*22dc650dSSadaf Ebrahimi Fecode += GET(Fecode, 1);
5564*22dc650dSSadaf Ebrahimi if (*Fecode != OP_ALT) goto ASSERT_NOT_FAILED;
5565*22dc650dSSadaf Ebrahimi break;
5566*22dc650dSSadaf Ebrahimi
5567*22dc650dSSadaf Ebrahimi case MATCH_COMMIT: /* Assertion forced to fail, therefore continue. */
5568*22dc650dSSadaf Ebrahimi case MATCH_SKIP:
5569*22dc650dSSadaf Ebrahimi case MATCH_PRUNE:
5570*22dc650dSSadaf Ebrahimi do Fecode += GET(Fecode, 1); while (*Fecode == OP_ALT);
5571*22dc650dSSadaf Ebrahimi goto ASSERT_NOT_FAILED;
5572*22dc650dSSadaf Ebrahimi
5573*22dc650dSSadaf Ebrahimi default: /* Pass back any other return */
5574*22dc650dSSadaf Ebrahimi RRETURN(rrc);
5575*22dc650dSSadaf Ebrahimi }
5576*22dc650dSSadaf Ebrahimi }
5577*22dc650dSSadaf Ebrahimi
5578*22dc650dSSadaf Ebrahimi /* None of the branches have matched or there was a backtrack to (*COMMIT),
5579*22dc650dSSadaf Ebrahimi (*SKIP), (*PRUNE), or (*THEN) in the last branch. This is success for a
5580*22dc650dSSadaf Ebrahimi negative assertion, so carry on. */
5581*22dc650dSSadaf Ebrahimi
5582*22dc650dSSadaf Ebrahimi ASSERT_NOT_FAILED:
5583*22dc650dSSadaf Ebrahimi Fecode += 1 + LINK_SIZE;
5584*22dc650dSSadaf Ebrahimi break;
5585*22dc650dSSadaf Ebrahimi
5586*22dc650dSSadaf Ebrahimi #undef Lframe_type
5587*22dc650dSSadaf Ebrahimi
5588*22dc650dSSadaf Ebrahimi
5589*22dc650dSSadaf Ebrahimi /* ===================================================================== */
5590*22dc650dSSadaf Ebrahimi /* The callout item calls an external function, if one is provided, passing
5591*22dc650dSSadaf Ebrahimi details of the match so far. This is mainly for debugging, though the
5592*22dc650dSSadaf Ebrahimi function is able to force a failure. */
5593*22dc650dSSadaf Ebrahimi
5594*22dc650dSSadaf Ebrahimi case OP_CALLOUT:
5595*22dc650dSSadaf Ebrahimi case OP_CALLOUT_STR:
5596*22dc650dSSadaf Ebrahimi rrc = do_callout(F, mb, &length);
5597*22dc650dSSadaf Ebrahimi if (rrc > 0) RRETURN(MATCH_NOMATCH);
5598*22dc650dSSadaf Ebrahimi if (rrc < 0) RRETURN(rrc);
5599*22dc650dSSadaf Ebrahimi Fecode += length;
5600*22dc650dSSadaf Ebrahimi break;
5601*22dc650dSSadaf Ebrahimi
5602*22dc650dSSadaf Ebrahimi
5603*22dc650dSSadaf Ebrahimi /* ===================================================================== */
5604*22dc650dSSadaf Ebrahimi /* Conditional group: compilation checked that there are no more than two
5605*22dc650dSSadaf Ebrahimi branches. If the condition is false, skipping the first branch takes us
5606*22dc650dSSadaf Ebrahimi past the end of the item if there is only one branch, but that's exactly
5607*22dc650dSSadaf Ebrahimi what we want. */
5608*22dc650dSSadaf Ebrahimi
5609*22dc650dSSadaf Ebrahimi case OP_COND:
5610*22dc650dSSadaf Ebrahimi case OP_SCOND:
5611*22dc650dSSadaf Ebrahimi
5612*22dc650dSSadaf Ebrahimi /* The variable Flength will be added to Fecode when the condition is
5613*22dc650dSSadaf Ebrahimi false, to get to the second branch. Setting it to the offset to the ALT or
5614*22dc650dSSadaf Ebrahimi KET, then incrementing Fecode achieves this effect. However, if the second
5615*22dc650dSSadaf Ebrahimi branch is non-existent, we must point to the KET so that the end of the
5616*22dc650dSSadaf Ebrahimi group is correctly processed. We now have Fecode pointing to the condition
5617*22dc650dSSadaf Ebrahimi or callout. */
5618*22dc650dSSadaf Ebrahimi
5619*22dc650dSSadaf Ebrahimi Flength = GET(Fecode, 1); /* Offset to the second branch */
5620*22dc650dSSadaf Ebrahimi if (Fecode[Flength] != OP_ALT) Flength -= 1 + LINK_SIZE;
5621*22dc650dSSadaf Ebrahimi Fecode += 1 + LINK_SIZE; /* From this opcode */
5622*22dc650dSSadaf Ebrahimi
5623*22dc650dSSadaf Ebrahimi /* Because of the way auto-callout works during compile, a callout item is
5624*22dc650dSSadaf Ebrahimi inserted between OP_COND and an assertion condition. Such a callout can
5625*22dc650dSSadaf Ebrahimi also be inserted manually. */
5626*22dc650dSSadaf Ebrahimi
5627*22dc650dSSadaf Ebrahimi if (*Fecode == OP_CALLOUT || *Fecode == OP_CALLOUT_STR)
5628*22dc650dSSadaf Ebrahimi {
5629*22dc650dSSadaf Ebrahimi rrc = do_callout(F, mb, &length);
5630*22dc650dSSadaf Ebrahimi if (rrc > 0) RRETURN(MATCH_NOMATCH);
5631*22dc650dSSadaf Ebrahimi if (rrc < 0) RRETURN(rrc);
5632*22dc650dSSadaf Ebrahimi
5633*22dc650dSSadaf Ebrahimi /* Advance Fecode past the callout, so it now points to the condition. We
5634*22dc650dSSadaf Ebrahimi must adjust Flength so that the value of Fecode+Flength is unchanged. */
5635*22dc650dSSadaf Ebrahimi
5636*22dc650dSSadaf Ebrahimi Fecode += length;
5637*22dc650dSSadaf Ebrahimi Flength -= length;
5638*22dc650dSSadaf Ebrahimi }
5639*22dc650dSSadaf Ebrahimi
5640*22dc650dSSadaf Ebrahimi /* Test the various possible conditions */
5641*22dc650dSSadaf Ebrahimi
5642*22dc650dSSadaf Ebrahimi condition = FALSE;
5643*22dc650dSSadaf Ebrahimi switch(*Fecode)
5644*22dc650dSSadaf Ebrahimi {
5645*22dc650dSSadaf Ebrahimi case OP_RREF: /* Group recursion test */
5646*22dc650dSSadaf Ebrahimi if (Fcurrent_recurse != RECURSE_UNSET)
5647*22dc650dSSadaf Ebrahimi {
5648*22dc650dSSadaf Ebrahimi number = GET2(Fecode, 1);
5649*22dc650dSSadaf Ebrahimi condition = (number == RREF_ANY || number == Fcurrent_recurse);
5650*22dc650dSSadaf Ebrahimi }
5651*22dc650dSSadaf Ebrahimi break;
5652*22dc650dSSadaf Ebrahimi
5653*22dc650dSSadaf Ebrahimi case OP_DNRREF: /* Duplicate named group recursion test */
5654*22dc650dSSadaf Ebrahimi if (Fcurrent_recurse != RECURSE_UNSET)
5655*22dc650dSSadaf Ebrahimi {
5656*22dc650dSSadaf Ebrahimi int count = GET2(Fecode, 1 + IMM2_SIZE);
5657*22dc650dSSadaf Ebrahimi PCRE2_SPTR slot = mb->name_table + GET2(Fecode, 1) * mb->name_entry_size;
5658*22dc650dSSadaf Ebrahimi while (count-- > 0)
5659*22dc650dSSadaf Ebrahimi {
5660*22dc650dSSadaf Ebrahimi number = GET2(slot, 0);
5661*22dc650dSSadaf Ebrahimi condition = number == Fcurrent_recurse;
5662*22dc650dSSadaf Ebrahimi if (condition) break;
5663*22dc650dSSadaf Ebrahimi slot += mb->name_entry_size;
5664*22dc650dSSadaf Ebrahimi }
5665*22dc650dSSadaf Ebrahimi }
5666*22dc650dSSadaf Ebrahimi break;
5667*22dc650dSSadaf Ebrahimi
5668*22dc650dSSadaf Ebrahimi case OP_CREF: /* Numbered group used test */
5669*22dc650dSSadaf Ebrahimi offset = (GET2(Fecode, 1) << 1) - 2; /* Doubled ref number */
5670*22dc650dSSadaf Ebrahimi condition = offset < Foffset_top && Fovector[offset] != PCRE2_UNSET;
5671*22dc650dSSadaf Ebrahimi break;
5672*22dc650dSSadaf Ebrahimi
5673*22dc650dSSadaf Ebrahimi case OP_DNCREF: /* Duplicate named group used test */
5674*22dc650dSSadaf Ebrahimi {
5675*22dc650dSSadaf Ebrahimi int count = GET2(Fecode, 1 + IMM2_SIZE);
5676*22dc650dSSadaf Ebrahimi PCRE2_SPTR slot = mb->name_table + GET2(Fecode, 1) * mb->name_entry_size;
5677*22dc650dSSadaf Ebrahimi while (count-- > 0)
5678*22dc650dSSadaf Ebrahimi {
5679*22dc650dSSadaf Ebrahimi offset = (GET2(slot, 0) << 1) - 2;
5680*22dc650dSSadaf Ebrahimi condition = offset < Foffset_top && Fovector[offset] != PCRE2_UNSET;
5681*22dc650dSSadaf Ebrahimi if (condition) break;
5682*22dc650dSSadaf Ebrahimi slot += mb->name_entry_size;
5683*22dc650dSSadaf Ebrahimi }
5684*22dc650dSSadaf Ebrahimi }
5685*22dc650dSSadaf Ebrahimi break;
5686*22dc650dSSadaf Ebrahimi
5687*22dc650dSSadaf Ebrahimi case OP_FALSE:
5688*22dc650dSSadaf Ebrahimi case OP_FAIL: /* The assertion (?!) becomes OP_FAIL */
5689*22dc650dSSadaf Ebrahimi break;
5690*22dc650dSSadaf Ebrahimi
5691*22dc650dSSadaf Ebrahimi case OP_TRUE:
5692*22dc650dSSadaf Ebrahimi condition = TRUE;
5693*22dc650dSSadaf Ebrahimi break;
5694*22dc650dSSadaf Ebrahimi
5695*22dc650dSSadaf Ebrahimi /* The condition is an assertion. Run code similar to the assertion code
5696*22dc650dSSadaf Ebrahimi above. */
5697*22dc650dSSadaf Ebrahimi
5698*22dc650dSSadaf Ebrahimi #define Lpositive F->temp_32[0]
5699*22dc650dSSadaf Ebrahimi #define Lstart_branch F->temp_sptr[0]
5700*22dc650dSSadaf Ebrahimi
5701*22dc650dSSadaf Ebrahimi default:
5702*22dc650dSSadaf Ebrahimi Lpositive = (*Fecode == OP_ASSERT || *Fecode == OP_ASSERTBACK);
5703*22dc650dSSadaf Ebrahimi Lstart_branch = Fecode;
5704*22dc650dSSadaf Ebrahimi
5705*22dc650dSSadaf Ebrahimi for (;;)
5706*22dc650dSSadaf Ebrahimi {
5707*22dc650dSSadaf Ebrahimi group_frame_type = GF_CONDASSERT | *Fecode;
5708*22dc650dSSadaf Ebrahimi RMATCH(Lstart_branch + PRIV(OP_lengths)[*Lstart_branch], RM5);
5709*22dc650dSSadaf Ebrahimi
5710*22dc650dSSadaf Ebrahimi switch(rrc)
5711*22dc650dSSadaf Ebrahimi {
5712*22dc650dSSadaf Ebrahimi case MATCH_ACCEPT: /* Save captures */
5713*22dc650dSSadaf Ebrahimi memcpy(Fovector,
5714*22dc650dSSadaf Ebrahimi (char *)assert_accept_frame + offsetof(heapframe, ovector),
5715*22dc650dSSadaf Ebrahimi assert_accept_frame->offset_top * sizeof(PCRE2_SIZE));
5716*22dc650dSSadaf Ebrahimi Foffset_top = assert_accept_frame->offset_top;
5717*22dc650dSSadaf Ebrahimi
5718*22dc650dSSadaf Ebrahimi /* Fall through */
5719*22dc650dSSadaf Ebrahimi /* In the case of a match, the captures have already been put into
5720*22dc650dSSadaf Ebrahimi the current frame. */
5721*22dc650dSSadaf Ebrahimi
5722*22dc650dSSadaf Ebrahimi case MATCH_MATCH:
5723*22dc650dSSadaf Ebrahimi condition = Lpositive; /* TRUE for positive assertion */
5724*22dc650dSSadaf Ebrahimi break;
5725*22dc650dSSadaf Ebrahimi
5726*22dc650dSSadaf Ebrahimi /* PCRE doesn't allow the effect of (*THEN) to escape beyond an
5727*22dc650dSSadaf Ebrahimi assertion; it is therefore always treated as NOMATCH. */
5728*22dc650dSSadaf Ebrahimi
5729*22dc650dSSadaf Ebrahimi case MATCH_NOMATCH:
5730*22dc650dSSadaf Ebrahimi case MATCH_THEN:
5731*22dc650dSSadaf Ebrahimi Lstart_branch += GET(Lstart_branch, 1);
5732*22dc650dSSadaf Ebrahimi if (*Lstart_branch == OP_ALT) continue; /* Try next branch */
5733*22dc650dSSadaf Ebrahimi condition = !Lpositive; /* TRUE for negative assertion */
5734*22dc650dSSadaf Ebrahimi break;
5735*22dc650dSSadaf Ebrahimi
5736*22dc650dSSadaf Ebrahimi /* These force no match without checking other branches. */
5737*22dc650dSSadaf Ebrahimi
5738*22dc650dSSadaf Ebrahimi case MATCH_COMMIT:
5739*22dc650dSSadaf Ebrahimi case MATCH_SKIP:
5740*22dc650dSSadaf Ebrahimi case MATCH_PRUNE:
5741*22dc650dSSadaf Ebrahimi condition = !Lpositive;
5742*22dc650dSSadaf Ebrahimi break;
5743*22dc650dSSadaf Ebrahimi
5744*22dc650dSSadaf Ebrahimi default:
5745*22dc650dSSadaf Ebrahimi RRETURN(rrc);
5746*22dc650dSSadaf Ebrahimi }
5747*22dc650dSSadaf Ebrahimi break; /* Out of the branch loop */
5748*22dc650dSSadaf Ebrahimi }
5749*22dc650dSSadaf Ebrahimi
5750*22dc650dSSadaf Ebrahimi /* If the condition is true, find the end of the assertion so that
5751*22dc650dSSadaf Ebrahimi advancing past it gets us to the start of the first branch. */
5752*22dc650dSSadaf Ebrahimi
5753*22dc650dSSadaf Ebrahimi if (condition)
5754*22dc650dSSadaf Ebrahimi {
5755*22dc650dSSadaf Ebrahimi do Fecode += GET(Fecode, 1); while (*Fecode == OP_ALT);
5756*22dc650dSSadaf Ebrahimi }
5757*22dc650dSSadaf Ebrahimi break; /* End of assertion condition */
5758*22dc650dSSadaf Ebrahimi }
5759*22dc650dSSadaf Ebrahimi
5760*22dc650dSSadaf Ebrahimi #undef Lpositive
5761*22dc650dSSadaf Ebrahimi #undef Lstart_branch
5762*22dc650dSSadaf Ebrahimi
5763*22dc650dSSadaf Ebrahimi /* Choose branch according to the condition. */
5764*22dc650dSSadaf Ebrahimi
5765*22dc650dSSadaf Ebrahimi Fecode += condition? PRIV(OP_lengths)[*Fecode] : Flength;
5766*22dc650dSSadaf Ebrahimi
5767*22dc650dSSadaf Ebrahimi /* If the opcode is OP_SCOND it means we are at a repeated conditional
5768*22dc650dSSadaf Ebrahimi group that might match an empty string. We must therefore descend a level
5769*22dc650dSSadaf Ebrahimi so that the start is remembered for checking. For OP_COND we can just
5770*22dc650dSSadaf Ebrahimi continue at this level. */
5771*22dc650dSSadaf Ebrahimi
5772*22dc650dSSadaf Ebrahimi if (Fop == OP_SCOND)
5773*22dc650dSSadaf Ebrahimi {
5774*22dc650dSSadaf Ebrahimi group_frame_type = GF_NOCAPTURE | Fop;
5775*22dc650dSSadaf Ebrahimi RMATCH(Fecode, RM35);
5776*22dc650dSSadaf Ebrahimi RRETURN(rrc);
5777*22dc650dSSadaf Ebrahimi }
5778*22dc650dSSadaf Ebrahimi break;
5779*22dc650dSSadaf Ebrahimi
5780*22dc650dSSadaf Ebrahimi
5781*22dc650dSSadaf Ebrahimi
5782*22dc650dSSadaf Ebrahimi /* ========================================================================= */
5783*22dc650dSSadaf Ebrahimi /* End of start of parenthesis opcodes */
5784*22dc650dSSadaf Ebrahimi /* ========================================================================= */
5785*22dc650dSSadaf Ebrahimi
5786*22dc650dSSadaf Ebrahimi
5787*22dc650dSSadaf Ebrahimi /* ===================================================================== */
5788*22dc650dSSadaf Ebrahimi /* Move the subject pointer back by one fixed amount. This occurs at the
5789*22dc650dSSadaf Ebrahimi start of each branch that has a fixed length in a lookbehind assertion. If
5790*22dc650dSSadaf Ebrahimi we are too close to the start to move back, fail. When working with UTF-8
5791*22dc650dSSadaf Ebrahimi we move back a number of characters, not bytes. */
5792*22dc650dSSadaf Ebrahimi
5793*22dc650dSSadaf Ebrahimi case OP_REVERSE:
5794*22dc650dSSadaf Ebrahimi number = GET2(Fecode, 1);
5795*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_UNICODE
5796*22dc650dSSadaf Ebrahimi if (utf)
5797*22dc650dSSadaf Ebrahimi {
5798*22dc650dSSadaf Ebrahimi while (number-- > 0)
5799*22dc650dSSadaf Ebrahimi {
5800*22dc650dSSadaf Ebrahimi if (Feptr <= mb->check_subject) RRETURN(MATCH_NOMATCH);
5801*22dc650dSSadaf Ebrahimi Feptr--;
5802*22dc650dSSadaf Ebrahimi BACKCHAR(Feptr);
5803*22dc650dSSadaf Ebrahimi }
5804*22dc650dSSadaf Ebrahimi }
5805*22dc650dSSadaf Ebrahimi else
5806*22dc650dSSadaf Ebrahimi #endif
5807*22dc650dSSadaf Ebrahimi
5808*22dc650dSSadaf Ebrahimi /* No UTF support, or not in UTF mode: count is code unit count */
5809*22dc650dSSadaf Ebrahimi
5810*22dc650dSSadaf Ebrahimi {
5811*22dc650dSSadaf Ebrahimi if ((ptrdiff_t)number > Feptr - mb->start_subject) RRETURN(MATCH_NOMATCH);
5812*22dc650dSSadaf Ebrahimi Feptr -= number;
5813*22dc650dSSadaf Ebrahimi }
5814*22dc650dSSadaf Ebrahimi
5815*22dc650dSSadaf Ebrahimi /* Save the earliest consulted character, then skip to next opcode */
5816*22dc650dSSadaf Ebrahimi
5817*22dc650dSSadaf Ebrahimi if (Feptr < mb->start_used_ptr) mb->start_used_ptr = Feptr;
5818*22dc650dSSadaf Ebrahimi Fecode += 1 + IMM2_SIZE;
5819*22dc650dSSadaf Ebrahimi break;
5820*22dc650dSSadaf Ebrahimi
5821*22dc650dSSadaf Ebrahimi
5822*22dc650dSSadaf Ebrahimi /* ===================================================================== */
5823*22dc650dSSadaf Ebrahimi /* Move the subject pointer back by a variable amount. This occurs at the
5824*22dc650dSSadaf Ebrahimi start of each branch of a lookbehind assertion when the branch has a
5825*22dc650dSSadaf Ebrahimi variable, but limited, length. A loop is needed to try matching the branch
5826*22dc650dSSadaf Ebrahimi after moving back different numbers of characters. If we are too close to
5827*22dc650dSSadaf Ebrahimi the start to move back even the minimum amount, fail. When working with
5828*22dc650dSSadaf Ebrahimi UTF-8 we move back a number of characters, not bytes. */
5829*22dc650dSSadaf Ebrahimi
5830*22dc650dSSadaf Ebrahimi #define Lmin F->temp_32[0]
5831*22dc650dSSadaf Ebrahimi #define Lmax F->temp_32[1]
5832*22dc650dSSadaf Ebrahimi #define Leptr F->temp_sptr[0]
5833*22dc650dSSadaf Ebrahimi
5834*22dc650dSSadaf Ebrahimi case OP_VREVERSE:
5835*22dc650dSSadaf Ebrahimi Lmin = GET2(Fecode, 1);
5836*22dc650dSSadaf Ebrahimi Lmax = GET2(Fecode, 1 + IMM2_SIZE);
5837*22dc650dSSadaf Ebrahimi Leptr = Feptr;
5838*22dc650dSSadaf Ebrahimi
5839*22dc650dSSadaf Ebrahimi /* Move back by the maximum branch length and then work forwards. This
5840*22dc650dSSadaf Ebrahimi ensures that items such as \d{3,5} get the maximum length, which is
5841*22dc650dSSadaf Ebrahimi relevant for captures, and makes for Perl compatibility. */
5842*22dc650dSSadaf Ebrahimi
5843*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_UNICODE
5844*22dc650dSSadaf Ebrahimi if (utf)
5845*22dc650dSSadaf Ebrahimi {
5846*22dc650dSSadaf Ebrahimi for (i = 0; i < Lmax; i++)
5847*22dc650dSSadaf Ebrahimi {
5848*22dc650dSSadaf Ebrahimi if (Feptr == mb->start_subject)
5849*22dc650dSSadaf Ebrahimi {
5850*22dc650dSSadaf Ebrahimi if (i < Lmin) RRETURN(MATCH_NOMATCH);
5851*22dc650dSSadaf Ebrahimi Lmax = i;
5852*22dc650dSSadaf Ebrahimi break;
5853*22dc650dSSadaf Ebrahimi }
5854*22dc650dSSadaf Ebrahimi Feptr--;
5855*22dc650dSSadaf Ebrahimi BACKCHAR(Feptr);
5856*22dc650dSSadaf Ebrahimi }
5857*22dc650dSSadaf Ebrahimi }
5858*22dc650dSSadaf Ebrahimi else
5859*22dc650dSSadaf Ebrahimi #endif
5860*22dc650dSSadaf Ebrahimi
5861*22dc650dSSadaf Ebrahimi /* No UTF support or not in UTF mode */
5862*22dc650dSSadaf Ebrahimi
5863*22dc650dSSadaf Ebrahimi {
5864*22dc650dSSadaf Ebrahimi ptrdiff_t diff = Feptr - mb->start_subject;
5865*22dc650dSSadaf Ebrahimi uint32_t available = (diff > 65535)? 65535 : ((diff > 0)? (int)diff : 0);
5866*22dc650dSSadaf Ebrahimi if (Lmin > available) RRETURN(MATCH_NOMATCH);
5867*22dc650dSSadaf Ebrahimi if (Lmax > available) Lmax = available;
5868*22dc650dSSadaf Ebrahimi Feptr -= Lmax;
5869*22dc650dSSadaf Ebrahimi }
5870*22dc650dSSadaf Ebrahimi
5871*22dc650dSSadaf Ebrahimi /* Now try matching, moving forward one character on failure, until we
5872*22dc650dSSadaf Ebrahimi reach the mimimum back length. */
5873*22dc650dSSadaf Ebrahimi
5874*22dc650dSSadaf Ebrahimi for (;;)
5875*22dc650dSSadaf Ebrahimi {
5876*22dc650dSSadaf Ebrahimi RMATCH(Fecode + 1 + 2 * IMM2_SIZE, RM37);
5877*22dc650dSSadaf Ebrahimi if (rrc != MATCH_NOMATCH) RRETURN(rrc);
5878*22dc650dSSadaf Ebrahimi if (Lmax-- <= Lmin) RRETURN(MATCH_NOMATCH);
5879*22dc650dSSadaf Ebrahimi Feptr++;
5880*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_UNICODE
5881*22dc650dSSadaf Ebrahimi if (utf) { FORWARDCHARTEST(Feptr, mb->end_subject); }
5882*22dc650dSSadaf Ebrahimi #endif
5883*22dc650dSSadaf Ebrahimi }
5884*22dc650dSSadaf Ebrahimi /* Control never reaches here */
5885*22dc650dSSadaf Ebrahimi
5886*22dc650dSSadaf Ebrahimi #undef Lmin
5887*22dc650dSSadaf Ebrahimi #undef Lmax
5888*22dc650dSSadaf Ebrahimi #undef Leptr
5889*22dc650dSSadaf Ebrahimi
5890*22dc650dSSadaf Ebrahimi /* ===================================================================== */
5891*22dc650dSSadaf Ebrahimi /* An alternation is the end of a branch; scan along to find the end of the
5892*22dc650dSSadaf Ebrahimi bracketed group. */
5893*22dc650dSSadaf Ebrahimi
5894*22dc650dSSadaf Ebrahimi case OP_ALT:
5895*22dc650dSSadaf Ebrahimi branch_end = Fecode;
5896*22dc650dSSadaf Ebrahimi do Fecode += GET(Fecode,1); while (*Fecode == OP_ALT);
5897*22dc650dSSadaf Ebrahimi break;
5898*22dc650dSSadaf Ebrahimi
5899*22dc650dSSadaf Ebrahimi
5900*22dc650dSSadaf Ebrahimi /* ===================================================================== */
5901*22dc650dSSadaf Ebrahimi /* The end of a parenthesized group. For all but OP_BRA and OP_COND, the
5902*22dc650dSSadaf Ebrahimi starting frame was added to the chained frames in order to remember the
5903*22dc650dSSadaf Ebrahimi starting subject position for the group. (Not true for OP_BRA when it's a
5904*22dc650dSSadaf Ebrahimi whole pattern recursion, but that is handled separately below.)*/
5905*22dc650dSSadaf Ebrahimi
5906*22dc650dSSadaf Ebrahimi case OP_KET:
5907*22dc650dSSadaf Ebrahimi case OP_KETRMIN:
5908*22dc650dSSadaf Ebrahimi case OP_KETRMAX:
5909*22dc650dSSadaf Ebrahimi case OP_KETRPOS:
5910*22dc650dSSadaf Ebrahimi
5911*22dc650dSSadaf Ebrahimi bracode = Fecode - GET(Fecode, 1);
5912*22dc650dSSadaf Ebrahimi
5913*22dc650dSSadaf Ebrahimi if (branch_end == NULL) branch_end = Fecode;
5914*22dc650dSSadaf Ebrahimi branch_start = bracode;
5915*22dc650dSSadaf Ebrahimi while (branch_start + GET(branch_start, 1) != branch_end)
5916*22dc650dSSadaf Ebrahimi branch_start += GET(branch_start, 1);
5917*22dc650dSSadaf Ebrahimi branch_end = NULL;
5918*22dc650dSSadaf Ebrahimi
5919*22dc650dSSadaf Ebrahimi /* Point N to the frame at the start of the most recent group, and P to its
5920*22dc650dSSadaf Ebrahimi predecessor. Remember the subject pointer at the start of the group. */
5921*22dc650dSSadaf Ebrahimi
5922*22dc650dSSadaf Ebrahimi if (*bracode != OP_BRA && *bracode != OP_COND)
5923*22dc650dSSadaf Ebrahimi {
5924*22dc650dSSadaf Ebrahimi N = (heapframe *)((char *)match_data->heapframes + Flast_group_offset);
5925*22dc650dSSadaf Ebrahimi P = (heapframe *)((char *)N - frame_size);
5926*22dc650dSSadaf Ebrahimi Flast_group_offset = P->last_group_offset;
5927*22dc650dSSadaf Ebrahimi
5928*22dc650dSSadaf Ebrahimi #ifdef DEBUG_SHOW_RMATCH
5929*22dc650dSSadaf Ebrahimi fprintf(stderr, "++ KET for frame=%d type=%x prev char offset=%lu\n",
5930*22dc650dSSadaf Ebrahimi N->rdepth, N->group_frame_type,
5931*22dc650dSSadaf Ebrahimi (char *)P->eptr - (char *)mb->start_subject);
5932*22dc650dSSadaf Ebrahimi #endif
5933*22dc650dSSadaf Ebrahimi
5934*22dc650dSSadaf Ebrahimi /* If we are at the end of an assertion that is a condition, return a
5935*22dc650dSSadaf Ebrahimi match, discarding any intermediate backtracking points. Copy back the
5936*22dc650dSSadaf Ebrahimi mark setting and the captures into the frame before N so that they are
5937*22dc650dSSadaf Ebrahimi set on return. Doing this for all assertions, both positive and negative,
5938*22dc650dSSadaf Ebrahimi seems to match what Perl does. */
5939*22dc650dSSadaf Ebrahimi
5940*22dc650dSSadaf Ebrahimi if (GF_IDMASK(N->group_frame_type) == GF_CONDASSERT)
5941*22dc650dSSadaf Ebrahimi {
5942*22dc650dSSadaf Ebrahimi memcpy((char *)P + offsetof(heapframe, ovector), Fovector,
5943*22dc650dSSadaf Ebrahimi Foffset_top * sizeof(PCRE2_SIZE));
5944*22dc650dSSadaf Ebrahimi P->offset_top = Foffset_top;
5945*22dc650dSSadaf Ebrahimi P->mark = Fmark;
5946*22dc650dSSadaf Ebrahimi Fback_frame = (char *)F - (char *)P;
5947*22dc650dSSadaf Ebrahimi RRETURN(MATCH_MATCH);
5948*22dc650dSSadaf Ebrahimi }
5949*22dc650dSSadaf Ebrahimi }
5950*22dc650dSSadaf Ebrahimi else P = NULL; /* Indicates starting frame not recorded */
5951*22dc650dSSadaf Ebrahimi
5952*22dc650dSSadaf Ebrahimi /* The group was not a conditional assertion. */
5953*22dc650dSSadaf Ebrahimi
5954*22dc650dSSadaf Ebrahimi switch (*bracode)
5955*22dc650dSSadaf Ebrahimi {
5956*22dc650dSSadaf Ebrahimi /* Whole pattern recursion is handled as a recursion into group 0, but
5957*22dc650dSSadaf Ebrahimi the entire pattern is wrapped in OP_BRA/OP_KET rather than a capturing
5958*22dc650dSSadaf Ebrahimi group - a design mistake: it should perhaps have been capture group 0.
5959*22dc650dSSadaf Ebrahimi Anyway, that means the end of such recursion must be handled here. It is
5960*22dc650dSSadaf Ebrahimi detected by checking for an immediately following OP_END when we are
5961*22dc650dSSadaf Ebrahimi recursing in group 0. If this is not the end of a whole-pattern
5962*22dc650dSSadaf Ebrahimi recursion, there is nothing to be done. */
5963*22dc650dSSadaf Ebrahimi
5964*22dc650dSSadaf Ebrahimi case OP_BRA:
5965*22dc650dSSadaf Ebrahimi if (Fcurrent_recurse != 0 || Fecode[1+LINK_SIZE] != OP_END) break;
5966*22dc650dSSadaf Ebrahimi
5967*22dc650dSSadaf Ebrahimi /* It is the end of whole-pattern recursion. */
5968*22dc650dSSadaf Ebrahimi
5969*22dc650dSSadaf Ebrahimi offset = Flast_group_offset;
5970*22dc650dSSadaf Ebrahimi if (offset == PCRE2_UNSET) return PCRE2_ERROR_INTERNAL;
5971*22dc650dSSadaf Ebrahimi N = (heapframe *)((char *)match_data->heapframes + offset);
5972*22dc650dSSadaf Ebrahimi P = (heapframe *)((char *)N - frame_size);
5973*22dc650dSSadaf Ebrahimi Flast_group_offset = P->last_group_offset;
5974*22dc650dSSadaf Ebrahimi
5975*22dc650dSSadaf Ebrahimi /* Reinstate the previous set of captures and then carry on after the
5976*22dc650dSSadaf Ebrahimi recursion call. */
5977*22dc650dSSadaf Ebrahimi
5978*22dc650dSSadaf Ebrahimi memcpy((char *)F + offsetof(heapframe, ovector), P->ovector,
5979*22dc650dSSadaf Ebrahimi Foffset_top * sizeof(PCRE2_SIZE));
5980*22dc650dSSadaf Ebrahimi Foffset_top = P->offset_top;
5981*22dc650dSSadaf Ebrahimi Fcapture_last = P->capture_last;
5982*22dc650dSSadaf Ebrahimi Fcurrent_recurse = P->current_recurse;
5983*22dc650dSSadaf Ebrahimi Fecode = P->ecode + 1 + LINK_SIZE;
5984*22dc650dSSadaf Ebrahimi continue; /* With next opcode */
5985*22dc650dSSadaf Ebrahimi
5986*22dc650dSSadaf Ebrahimi case OP_COND: /* No need to do anything for these */
5987*22dc650dSSadaf Ebrahimi case OP_SCOND:
5988*22dc650dSSadaf Ebrahimi break;
5989*22dc650dSSadaf Ebrahimi
5990*22dc650dSSadaf Ebrahimi /* Non-atomic positive assertions are like OP_BRA, except that the
5991*22dc650dSSadaf Ebrahimi subject pointer must be put back to where it was at the start of the
5992*22dc650dSSadaf Ebrahimi assertion. For a variable lookbehind, check its end point. */
5993*22dc650dSSadaf Ebrahimi
5994*22dc650dSSadaf Ebrahimi case OP_ASSERTBACK_NA:
5995*22dc650dSSadaf Ebrahimi if (branch_start[1 + LINK_SIZE] == OP_VREVERSE && Feptr != P->eptr)
5996*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
5997*22dc650dSSadaf Ebrahimi /* Fall through */
5998*22dc650dSSadaf Ebrahimi
5999*22dc650dSSadaf Ebrahimi case OP_ASSERT_NA:
6000*22dc650dSSadaf Ebrahimi if (Feptr > mb->last_used_ptr) mb->last_used_ptr = Feptr;
6001*22dc650dSSadaf Ebrahimi Feptr = P->eptr;
6002*22dc650dSSadaf Ebrahimi break;
6003*22dc650dSSadaf Ebrahimi
6004*22dc650dSSadaf Ebrahimi /* Atomic positive assertions are like OP_ONCE, except that in addition
6005*22dc650dSSadaf Ebrahimi the subject pointer must be put back to where it was at the start of the
6006*22dc650dSSadaf Ebrahimi assertion. For a variable lookbehind, check its end point. */
6007*22dc650dSSadaf Ebrahimi
6008*22dc650dSSadaf Ebrahimi case OP_ASSERTBACK:
6009*22dc650dSSadaf Ebrahimi if (branch_start[1 + LINK_SIZE] == OP_VREVERSE && Feptr != P->eptr)
6010*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
6011*22dc650dSSadaf Ebrahimi /* Fall through */
6012*22dc650dSSadaf Ebrahimi
6013*22dc650dSSadaf Ebrahimi case OP_ASSERT:
6014*22dc650dSSadaf Ebrahimi if (Feptr > mb->last_used_ptr) mb->last_used_ptr = Feptr;
6015*22dc650dSSadaf Ebrahimi Feptr = P->eptr;
6016*22dc650dSSadaf Ebrahimi /* Fall through */
6017*22dc650dSSadaf Ebrahimi
6018*22dc650dSSadaf Ebrahimi /* For an atomic group, discard internal backtracking points. We must
6019*22dc650dSSadaf Ebrahimi also ensure that any remaining branches within the top-level of the group
6020*22dc650dSSadaf Ebrahimi are not tried. Do this by adjusting the code pointer within the backtrack
6021*22dc650dSSadaf Ebrahimi frame so that it points to the final branch. */
6022*22dc650dSSadaf Ebrahimi
6023*22dc650dSSadaf Ebrahimi case OP_ONCE:
6024*22dc650dSSadaf Ebrahimi Fback_frame = ((char *)F - (char *)P);
6025*22dc650dSSadaf Ebrahimi for (;;)
6026*22dc650dSSadaf Ebrahimi {
6027*22dc650dSSadaf Ebrahimi uint32_t y = GET(P->ecode,1);
6028*22dc650dSSadaf Ebrahimi if ((P->ecode)[y] != OP_ALT) break;
6029*22dc650dSSadaf Ebrahimi P->ecode += y;
6030*22dc650dSSadaf Ebrahimi }
6031*22dc650dSSadaf Ebrahimi break;
6032*22dc650dSSadaf Ebrahimi
6033*22dc650dSSadaf Ebrahimi /* A matching negative assertion returns MATCH, which is turned into
6034*22dc650dSSadaf Ebrahimi NOMATCH at the assertion level. For a variable lookbehind, check its end
6035*22dc650dSSadaf Ebrahimi point. */
6036*22dc650dSSadaf Ebrahimi
6037*22dc650dSSadaf Ebrahimi case OP_ASSERTBACK_NOT:
6038*22dc650dSSadaf Ebrahimi if (branch_start[1 + LINK_SIZE] == OP_VREVERSE && Feptr != P->eptr)
6039*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
6040*22dc650dSSadaf Ebrahimi /* Fall through */
6041*22dc650dSSadaf Ebrahimi
6042*22dc650dSSadaf Ebrahimi case OP_ASSERT_NOT:
6043*22dc650dSSadaf Ebrahimi RRETURN(MATCH_MATCH);
6044*22dc650dSSadaf Ebrahimi
6045*22dc650dSSadaf Ebrahimi /* At the end of a script run, apply the script-checking rules. This code
6046*22dc650dSSadaf Ebrahimi will never by exercised if Unicode support it not compiled, because in
6047*22dc650dSSadaf Ebrahimi that environment script runs cause an error at compile time. */
6048*22dc650dSSadaf Ebrahimi
6049*22dc650dSSadaf Ebrahimi case OP_SCRIPT_RUN:
6050*22dc650dSSadaf Ebrahimi if (!PRIV(script_run)(P->eptr, Feptr, utf)) RRETURN(MATCH_NOMATCH);
6051*22dc650dSSadaf Ebrahimi break;
6052*22dc650dSSadaf Ebrahimi
6053*22dc650dSSadaf Ebrahimi /* Whole-pattern recursion is coded as a recurse into group 0, and is
6054*22dc650dSSadaf Ebrahimi handled with OP_BRA above. Other recursion is handled here. */
6055*22dc650dSSadaf Ebrahimi
6056*22dc650dSSadaf Ebrahimi case OP_CBRA:
6057*22dc650dSSadaf Ebrahimi case OP_CBRAPOS:
6058*22dc650dSSadaf Ebrahimi case OP_SCBRA:
6059*22dc650dSSadaf Ebrahimi case OP_SCBRAPOS:
6060*22dc650dSSadaf Ebrahimi number = GET2(bracode, 1+LINK_SIZE);
6061*22dc650dSSadaf Ebrahimi
6062*22dc650dSSadaf Ebrahimi /* Handle a recursively called group. We reinstate the previous set of
6063*22dc650dSSadaf Ebrahimi captures and then carry on after the recursion call. */
6064*22dc650dSSadaf Ebrahimi
6065*22dc650dSSadaf Ebrahimi if (Fcurrent_recurse == number)
6066*22dc650dSSadaf Ebrahimi {
6067*22dc650dSSadaf Ebrahimi P = (heapframe *)((char *)N - frame_size);
6068*22dc650dSSadaf Ebrahimi memcpy((char *)F + offsetof(heapframe, ovector), P->ovector,
6069*22dc650dSSadaf Ebrahimi Foffset_top * sizeof(PCRE2_SIZE));
6070*22dc650dSSadaf Ebrahimi Foffset_top = P->offset_top;
6071*22dc650dSSadaf Ebrahimi Fcapture_last = P->capture_last;
6072*22dc650dSSadaf Ebrahimi Fcurrent_recurse = P->current_recurse;
6073*22dc650dSSadaf Ebrahimi Fecode = P->ecode + 1 + LINK_SIZE;
6074*22dc650dSSadaf Ebrahimi continue; /* With next opcode */
6075*22dc650dSSadaf Ebrahimi }
6076*22dc650dSSadaf Ebrahimi
6077*22dc650dSSadaf Ebrahimi /* Deal with actual capturing. */
6078*22dc650dSSadaf Ebrahimi
6079*22dc650dSSadaf Ebrahimi offset = (number << 1) - 2;
6080*22dc650dSSadaf Ebrahimi Fcapture_last = number;
6081*22dc650dSSadaf Ebrahimi Fovector[offset] = P->eptr - mb->start_subject;
6082*22dc650dSSadaf Ebrahimi Fovector[offset+1] = Feptr - mb->start_subject;
6083*22dc650dSSadaf Ebrahimi if (offset >= Foffset_top) Foffset_top = offset + 2;
6084*22dc650dSSadaf Ebrahimi break;
6085*22dc650dSSadaf Ebrahimi } /* End actions relating to the starting opcode */
6086*22dc650dSSadaf Ebrahimi
6087*22dc650dSSadaf Ebrahimi /* OP_KETRPOS is a possessive repeating ket. Remember the current position,
6088*22dc650dSSadaf Ebrahimi and return the MATCH_KETRPOS. This makes it possible to do the repeats one
6089*22dc650dSSadaf Ebrahimi at a time from the outer level. This must precede the empty string test -
6090*22dc650dSSadaf Ebrahimi in this case that test is done at the outer level. */
6091*22dc650dSSadaf Ebrahimi
6092*22dc650dSSadaf Ebrahimi if (*Fecode == OP_KETRPOS)
6093*22dc650dSSadaf Ebrahimi {
6094*22dc650dSSadaf Ebrahimi memcpy((char *)P + offsetof(heapframe, eptr),
6095*22dc650dSSadaf Ebrahimi (char *)F + offsetof(heapframe, eptr),
6096*22dc650dSSadaf Ebrahimi frame_copy_size);
6097*22dc650dSSadaf Ebrahimi RRETURN(MATCH_KETRPOS);
6098*22dc650dSSadaf Ebrahimi }
6099*22dc650dSSadaf Ebrahimi
6100*22dc650dSSadaf Ebrahimi /* Handle the different kinds of closing brackets. A non-repeating ket
6101*22dc650dSSadaf Ebrahimi needs no special action, just continuing at this level. This also happens
6102*22dc650dSSadaf Ebrahimi for the repeating kets if the group matched no characters, in order to
6103*22dc650dSSadaf Ebrahimi forcibly break infinite loops. Otherwise, the repeating kets try the rest
6104*22dc650dSSadaf Ebrahimi of the pattern or restart from the preceding bracket, in the appropriate
6105*22dc650dSSadaf Ebrahimi order. */
6106*22dc650dSSadaf Ebrahimi
6107*22dc650dSSadaf Ebrahimi if (Fop != OP_KET && (P == NULL || Feptr != P->eptr))
6108*22dc650dSSadaf Ebrahimi {
6109*22dc650dSSadaf Ebrahimi if (Fop == OP_KETRMIN)
6110*22dc650dSSadaf Ebrahimi {
6111*22dc650dSSadaf Ebrahimi RMATCH(Fecode + 1 + LINK_SIZE, RM6);
6112*22dc650dSSadaf Ebrahimi if (rrc != MATCH_NOMATCH) RRETURN(rrc);
6113*22dc650dSSadaf Ebrahimi Fecode -= GET(Fecode, 1);
6114*22dc650dSSadaf Ebrahimi break; /* End of ket processing */
6115*22dc650dSSadaf Ebrahimi }
6116*22dc650dSSadaf Ebrahimi
6117*22dc650dSSadaf Ebrahimi /* Repeat the maximum number of times (KETRMAX) */
6118*22dc650dSSadaf Ebrahimi
6119*22dc650dSSadaf Ebrahimi RMATCH(bracode, RM7);
6120*22dc650dSSadaf Ebrahimi if (rrc != MATCH_NOMATCH) RRETURN(rrc);
6121*22dc650dSSadaf Ebrahimi }
6122*22dc650dSSadaf Ebrahimi
6123*22dc650dSSadaf Ebrahimi /* Carry on at this level for a non-repeating ket, or after matching an
6124*22dc650dSSadaf Ebrahimi empty string, or after repeating for a maximum number of times. */
6125*22dc650dSSadaf Ebrahimi
6126*22dc650dSSadaf Ebrahimi Fecode += 1 + LINK_SIZE;
6127*22dc650dSSadaf Ebrahimi break;
6128*22dc650dSSadaf Ebrahimi
6129*22dc650dSSadaf Ebrahimi
6130*22dc650dSSadaf Ebrahimi /* ===================================================================== */
6131*22dc650dSSadaf Ebrahimi /* Start and end of line assertions, not multiline mode. */
6132*22dc650dSSadaf Ebrahimi
6133*22dc650dSSadaf Ebrahimi case OP_CIRC: /* Start of line, unless PCRE2_NOTBOL is set. */
6134*22dc650dSSadaf Ebrahimi if (Feptr != mb->start_subject || (mb->moptions & PCRE2_NOTBOL) != 0)
6135*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
6136*22dc650dSSadaf Ebrahimi Fecode++;
6137*22dc650dSSadaf Ebrahimi break;
6138*22dc650dSSadaf Ebrahimi
6139*22dc650dSSadaf Ebrahimi case OP_SOD: /* Unconditional start of subject */
6140*22dc650dSSadaf Ebrahimi if (Feptr != mb->start_subject) RRETURN(MATCH_NOMATCH);
6141*22dc650dSSadaf Ebrahimi Fecode++;
6142*22dc650dSSadaf Ebrahimi break;
6143*22dc650dSSadaf Ebrahimi
6144*22dc650dSSadaf Ebrahimi /* When PCRE2_NOTEOL is unset, assert before the subject end, or a
6145*22dc650dSSadaf Ebrahimi terminating newline unless PCRE2_DOLLAR_ENDONLY is set. */
6146*22dc650dSSadaf Ebrahimi
6147*22dc650dSSadaf Ebrahimi case OP_DOLL:
6148*22dc650dSSadaf Ebrahimi if ((mb->moptions & PCRE2_NOTEOL) != 0) RRETURN(MATCH_NOMATCH);
6149*22dc650dSSadaf Ebrahimi if ((mb->poptions & PCRE2_DOLLAR_ENDONLY) == 0) goto ASSERT_NL_OR_EOS;
6150*22dc650dSSadaf Ebrahimi
6151*22dc650dSSadaf Ebrahimi /* Fall through */
6152*22dc650dSSadaf Ebrahimi /* Unconditional end of subject assertion (\z). */
6153*22dc650dSSadaf Ebrahimi
6154*22dc650dSSadaf Ebrahimi case OP_EOD:
6155*22dc650dSSadaf Ebrahimi if (Feptr < mb->true_end_subject) RRETURN(MATCH_NOMATCH);
6156*22dc650dSSadaf Ebrahimi if (mb->partial != 0)
6157*22dc650dSSadaf Ebrahimi {
6158*22dc650dSSadaf Ebrahimi mb->hitend = TRUE;
6159*22dc650dSSadaf Ebrahimi if (mb->partial > 1) return PCRE2_ERROR_PARTIAL;
6160*22dc650dSSadaf Ebrahimi }
6161*22dc650dSSadaf Ebrahimi Fecode++;
6162*22dc650dSSadaf Ebrahimi break;
6163*22dc650dSSadaf Ebrahimi
6164*22dc650dSSadaf Ebrahimi /* End of subject or ending \n assertion (\Z) */
6165*22dc650dSSadaf Ebrahimi
6166*22dc650dSSadaf Ebrahimi case OP_EODN:
6167*22dc650dSSadaf Ebrahimi ASSERT_NL_OR_EOS:
6168*22dc650dSSadaf Ebrahimi if (Feptr < mb->end_subject &&
6169*22dc650dSSadaf Ebrahimi (!IS_NEWLINE(Feptr) || Feptr != mb->end_subject - mb->nllen))
6170*22dc650dSSadaf Ebrahimi {
6171*22dc650dSSadaf Ebrahimi if (mb->partial != 0 &&
6172*22dc650dSSadaf Ebrahimi Feptr + 1 >= mb->end_subject &&
6173*22dc650dSSadaf Ebrahimi NLBLOCK->nltype == NLTYPE_FIXED &&
6174*22dc650dSSadaf Ebrahimi NLBLOCK->nllen == 2 &&
6175*22dc650dSSadaf Ebrahimi UCHAR21TEST(Feptr) == NLBLOCK->nl[0])
6176*22dc650dSSadaf Ebrahimi {
6177*22dc650dSSadaf Ebrahimi mb->hitend = TRUE;
6178*22dc650dSSadaf Ebrahimi if (mb->partial > 1) return PCRE2_ERROR_PARTIAL;
6179*22dc650dSSadaf Ebrahimi }
6180*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
6181*22dc650dSSadaf Ebrahimi }
6182*22dc650dSSadaf Ebrahimi
6183*22dc650dSSadaf Ebrahimi /* Either at end of string or \n before end. */
6184*22dc650dSSadaf Ebrahimi
6185*22dc650dSSadaf Ebrahimi if (mb->partial != 0)
6186*22dc650dSSadaf Ebrahimi {
6187*22dc650dSSadaf Ebrahimi mb->hitend = TRUE;
6188*22dc650dSSadaf Ebrahimi if (mb->partial > 1) return PCRE2_ERROR_PARTIAL;
6189*22dc650dSSadaf Ebrahimi }
6190*22dc650dSSadaf Ebrahimi Fecode++;
6191*22dc650dSSadaf Ebrahimi break;
6192*22dc650dSSadaf Ebrahimi
6193*22dc650dSSadaf Ebrahimi
6194*22dc650dSSadaf Ebrahimi /* ===================================================================== */
6195*22dc650dSSadaf Ebrahimi /* Start and end of line assertions, multiline mode. */
6196*22dc650dSSadaf Ebrahimi
6197*22dc650dSSadaf Ebrahimi /* Start of subject unless notbol, or after any newline except for one at
6198*22dc650dSSadaf Ebrahimi the very end, unless PCRE2_ALT_CIRCUMFLEX is set. */
6199*22dc650dSSadaf Ebrahimi
6200*22dc650dSSadaf Ebrahimi case OP_CIRCM:
6201*22dc650dSSadaf Ebrahimi if ((mb->moptions & PCRE2_NOTBOL) != 0 && Feptr == mb->start_subject)
6202*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
6203*22dc650dSSadaf Ebrahimi if (Feptr != mb->start_subject &&
6204*22dc650dSSadaf Ebrahimi ((Feptr == mb->end_subject &&
6205*22dc650dSSadaf Ebrahimi (mb->poptions & PCRE2_ALT_CIRCUMFLEX) == 0) ||
6206*22dc650dSSadaf Ebrahimi !WAS_NEWLINE(Feptr)))
6207*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
6208*22dc650dSSadaf Ebrahimi Fecode++;
6209*22dc650dSSadaf Ebrahimi break;
6210*22dc650dSSadaf Ebrahimi
6211*22dc650dSSadaf Ebrahimi /* Assert before any newline, or before end of subject unless noteol is
6212*22dc650dSSadaf Ebrahimi set. */
6213*22dc650dSSadaf Ebrahimi
6214*22dc650dSSadaf Ebrahimi case OP_DOLLM:
6215*22dc650dSSadaf Ebrahimi if (Feptr < mb->end_subject)
6216*22dc650dSSadaf Ebrahimi {
6217*22dc650dSSadaf Ebrahimi if (!IS_NEWLINE(Feptr))
6218*22dc650dSSadaf Ebrahimi {
6219*22dc650dSSadaf Ebrahimi if (mb->partial != 0 &&
6220*22dc650dSSadaf Ebrahimi Feptr + 1 >= mb->end_subject &&
6221*22dc650dSSadaf Ebrahimi NLBLOCK->nltype == NLTYPE_FIXED &&
6222*22dc650dSSadaf Ebrahimi NLBLOCK->nllen == 2 &&
6223*22dc650dSSadaf Ebrahimi UCHAR21TEST(Feptr) == NLBLOCK->nl[0])
6224*22dc650dSSadaf Ebrahimi {
6225*22dc650dSSadaf Ebrahimi mb->hitend = TRUE;
6226*22dc650dSSadaf Ebrahimi if (mb->partial > 1) return PCRE2_ERROR_PARTIAL;
6227*22dc650dSSadaf Ebrahimi }
6228*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
6229*22dc650dSSadaf Ebrahimi }
6230*22dc650dSSadaf Ebrahimi }
6231*22dc650dSSadaf Ebrahimi else
6232*22dc650dSSadaf Ebrahimi {
6233*22dc650dSSadaf Ebrahimi if ((mb->moptions & PCRE2_NOTEOL) != 0) RRETURN(MATCH_NOMATCH);
6234*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
6235*22dc650dSSadaf Ebrahimi }
6236*22dc650dSSadaf Ebrahimi Fecode++;
6237*22dc650dSSadaf Ebrahimi break;
6238*22dc650dSSadaf Ebrahimi
6239*22dc650dSSadaf Ebrahimi
6240*22dc650dSSadaf Ebrahimi /* ===================================================================== */
6241*22dc650dSSadaf Ebrahimi /* Start of match assertion */
6242*22dc650dSSadaf Ebrahimi
6243*22dc650dSSadaf Ebrahimi case OP_SOM:
6244*22dc650dSSadaf Ebrahimi if (Feptr != mb->start_subject + mb->start_offset) RRETURN(MATCH_NOMATCH);
6245*22dc650dSSadaf Ebrahimi Fecode++;
6246*22dc650dSSadaf Ebrahimi break;
6247*22dc650dSSadaf Ebrahimi
6248*22dc650dSSadaf Ebrahimi
6249*22dc650dSSadaf Ebrahimi /* ===================================================================== */
6250*22dc650dSSadaf Ebrahimi /* Reset the start of match point */
6251*22dc650dSSadaf Ebrahimi
6252*22dc650dSSadaf Ebrahimi case OP_SET_SOM:
6253*22dc650dSSadaf Ebrahimi Fstart_match = Feptr;
6254*22dc650dSSadaf Ebrahimi Fecode++;
6255*22dc650dSSadaf Ebrahimi break;
6256*22dc650dSSadaf Ebrahimi
6257*22dc650dSSadaf Ebrahimi
6258*22dc650dSSadaf Ebrahimi /* ===================================================================== */
6259*22dc650dSSadaf Ebrahimi /* Word boundary assertions. Find out if the previous and current
6260*22dc650dSSadaf Ebrahimi characters are "word" characters. It takes a bit more work in UTF mode.
6261*22dc650dSSadaf Ebrahimi Characters > 255 are assumed to be "non-word" characters when PCRE2_UCP is
6262*22dc650dSSadaf Ebrahimi not set. When it is set, use Unicode properties if available, even when not
6263*22dc650dSSadaf Ebrahimi in UTF mode. Remember the earliest and latest consulted characters. */
6264*22dc650dSSadaf Ebrahimi
6265*22dc650dSSadaf Ebrahimi case OP_NOT_WORD_BOUNDARY:
6266*22dc650dSSadaf Ebrahimi case OP_WORD_BOUNDARY:
6267*22dc650dSSadaf Ebrahimi case OP_NOT_UCP_WORD_BOUNDARY:
6268*22dc650dSSadaf Ebrahimi case OP_UCP_WORD_BOUNDARY:
6269*22dc650dSSadaf Ebrahimi if (Feptr == mb->check_subject) prev_is_word = FALSE; else
6270*22dc650dSSadaf Ebrahimi {
6271*22dc650dSSadaf Ebrahimi PCRE2_SPTR lastptr = Feptr - 1;
6272*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_UNICODE
6273*22dc650dSSadaf Ebrahimi if (utf)
6274*22dc650dSSadaf Ebrahimi {
6275*22dc650dSSadaf Ebrahimi BACKCHAR(lastptr);
6276*22dc650dSSadaf Ebrahimi GETCHAR(fc, lastptr);
6277*22dc650dSSadaf Ebrahimi }
6278*22dc650dSSadaf Ebrahimi else
6279*22dc650dSSadaf Ebrahimi #endif /* SUPPORT_UNICODE */
6280*22dc650dSSadaf Ebrahimi fc = *lastptr;
6281*22dc650dSSadaf Ebrahimi if (lastptr < mb->start_used_ptr) mb->start_used_ptr = lastptr;
6282*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_UNICODE
6283*22dc650dSSadaf Ebrahimi if (Fop == OP_UCP_WORD_BOUNDARY || Fop == OP_NOT_UCP_WORD_BOUNDARY)
6284*22dc650dSSadaf Ebrahimi {
6285*22dc650dSSadaf Ebrahimi int chartype = UCD_CHARTYPE(fc);
6286*22dc650dSSadaf Ebrahimi int category = PRIV(ucp_gentype)[chartype];
6287*22dc650dSSadaf Ebrahimi prev_is_word = (category == ucp_L || category == ucp_N ||
6288*22dc650dSSadaf Ebrahimi chartype == ucp_Mn || chartype == ucp_Pc);
6289*22dc650dSSadaf Ebrahimi }
6290*22dc650dSSadaf Ebrahimi else
6291*22dc650dSSadaf Ebrahimi #endif /* SUPPORT_UNICODE */
6292*22dc650dSSadaf Ebrahimi prev_is_word = CHMAX_255(fc) && (mb->ctypes[fc] & ctype_word) != 0;
6293*22dc650dSSadaf Ebrahimi }
6294*22dc650dSSadaf Ebrahimi
6295*22dc650dSSadaf Ebrahimi /* Get status of next character */
6296*22dc650dSSadaf Ebrahimi
6297*22dc650dSSadaf Ebrahimi if (Feptr >= mb->end_subject)
6298*22dc650dSSadaf Ebrahimi {
6299*22dc650dSSadaf Ebrahimi SCHECK_PARTIAL();
6300*22dc650dSSadaf Ebrahimi cur_is_word = FALSE;
6301*22dc650dSSadaf Ebrahimi }
6302*22dc650dSSadaf Ebrahimi else
6303*22dc650dSSadaf Ebrahimi {
6304*22dc650dSSadaf Ebrahimi PCRE2_SPTR nextptr = Feptr + 1;
6305*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_UNICODE
6306*22dc650dSSadaf Ebrahimi if (utf)
6307*22dc650dSSadaf Ebrahimi {
6308*22dc650dSSadaf Ebrahimi FORWARDCHARTEST(nextptr, mb->end_subject);
6309*22dc650dSSadaf Ebrahimi GETCHAR(fc, Feptr);
6310*22dc650dSSadaf Ebrahimi }
6311*22dc650dSSadaf Ebrahimi else
6312*22dc650dSSadaf Ebrahimi #endif /* SUPPORT_UNICODE */
6313*22dc650dSSadaf Ebrahimi fc = *Feptr;
6314*22dc650dSSadaf Ebrahimi if (nextptr > mb->last_used_ptr) mb->last_used_ptr = nextptr;
6315*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_UNICODE
6316*22dc650dSSadaf Ebrahimi if (Fop == OP_UCP_WORD_BOUNDARY || Fop == OP_NOT_UCP_WORD_BOUNDARY)
6317*22dc650dSSadaf Ebrahimi {
6318*22dc650dSSadaf Ebrahimi int chartype = UCD_CHARTYPE(fc);
6319*22dc650dSSadaf Ebrahimi int category = PRIV(ucp_gentype)[chartype];
6320*22dc650dSSadaf Ebrahimi cur_is_word = (category == ucp_L || category == ucp_N ||
6321*22dc650dSSadaf Ebrahimi chartype == ucp_Mn || chartype == ucp_Pc);
6322*22dc650dSSadaf Ebrahimi }
6323*22dc650dSSadaf Ebrahimi else
6324*22dc650dSSadaf Ebrahimi #endif /* SUPPORT_UNICODE */
6325*22dc650dSSadaf Ebrahimi cur_is_word = CHMAX_255(fc) && (mb->ctypes[fc] & ctype_word) != 0;
6326*22dc650dSSadaf Ebrahimi }
6327*22dc650dSSadaf Ebrahimi
6328*22dc650dSSadaf Ebrahimi /* Now see if the situation is what we want */
6329*22dc650dSSadaf Ebrahimi
6330*22dc650dSSadaf Ebrahimi if ((*Fecode++ == OP_WORD_BOUNDARY || Fop == OP_UCP_WORD_BOUNDARY)?
6331*22dc650dSSadaf Ebrahimi cur_is_word == prev_is_word : cur_is_word != prev_is_word)
6332*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
6333*22dc650dSSadaf Ebrahimi break;
6334*22dc650dSSadaf Ebrahimi
6335*22dc650dSSadaf Ebrahimi
6336*22dc650dSSadaf Ebrahimi /* ===================================================================== */
6337*22dc650dSSadaf Ebrahimi /* Backtracking (*VERB)s, with and without arguments. Note that if the
6338*22dc650dSSadaf Ebrahimi pattern is successfully matched, we do not come back from RMATCH. */
6339*22dc650dSSadaf Ebrahimi
6340*22dc650dSSadaf Ebrahimi case OP_MARK:
6341*22dc650dSSadaf Ebrahimi Fmark = mb->nomatch_mark = Fecode + 2;
6342*22dc650dSSadaf Ebrahimi RMATCH(Fecode + PRIV(OP_lengths)[*Fecode] + Fecode[1], RM12);
6343*22dc650dSSadaf Ebrahimi
6344*22dc650dSSadaf Ebrahimi /* A return of MATCH_SKIP_ARG means that matching failed at SKIP with an
6345*22dc650dSSadaf Ebrahimi argument, and we must check whether that argument matches this MARK's
6346*22dc650dSSadaf Ebrahimi argument. It is passed back in mb->verb_skip_ptr. If it does match, we
6347*22dc650dSSadaf Ebrahimi return MATCH_SKIP with mb->verb_skip_ptr now pointing to the subject
6348*22dc650dSSadaf Ebrahimi position that corresponds to this mark. Otherwise, pass back the return
6349*22dc650dSSadaf Ebrahimi code unaltered. */
6350*22dc650dSSadaf Ebrahimi
6351*22dc650dSSadaf Ebrahimi if (rrc == MATCH_SKIP_ARG &&
6352*22dc650dSSadaf Ebrahimi PRIV(strcmp)(Fecode + 2, mb->verb_skip_ptr) == 0)
6353*22dc650dSSadaf Ebrahimi {
6354*22dc650dSSadaf Ebrahimi mb->verb_skip_ptr = Feptr; /* Pass back current position */
6355*22dc650dSSadaf Ebrahimi RRETURN(MATCH_SKIP);
6356*22dc650dSSadaf Ebrahimi }
6357*22dc650dSSadaf Ebrahimi RRETURN(rrc);
6358*22dc650dSSadaf Ebrahimi
6359*22dc650dSSadaf Ebrahimi case OP_FAIL:
6360*22dc650dSSadaf Ebrahimi RRETURN(MATCH_NOMATCH);
6361*22dc650dSSadaf Ebrahimi
6362*22dc650dSSadaf Ebrahimi /* Record the current recursing group number in mb->verb_current_recurse
6363*22dc650dSSadaf Ebrahimi when a backtracking return such as MATCH_COMMIT is given. This enables the
6364*22dc650dSSadaf Ebrahimi recurse processing to catch verbs from within the recursion. */
6365*22dc650dSSadaf Ebrahimi
6366*22dc650dSSadaf Ebrahimi case OP_COMMIT:
6367*22dc650dSSadaf Ebrahimi RMATCH(Fecode + PRIV(OP_lengths)[*Fecode], RM13);
6368*22dc650dSSadaf Ebrahimi if (rrc != MATCH_NOMATCH) RRETURN(rrc);
6369*22dc650dSSadaf Ebrahimi mb->verb_current_recurse = Fcurrent_recurse;
6370*22dc650dSSadaf Ebrahimi RRETURN(MATCH_COMMIT);
6371*22dc650dSSadaf Ebrahimi
6372*22dc650dSSadaf Ebrahimi case OP_COMMIT_ARG:
6373*22dc650dSSadaf Ebrahimi Fmark = mb->nomatch_mark = Fecode + 2;
6374*22dc650dSSadaf Ebrahimi RMATCH(Fecode + PRIV(OP_lengths)[*Fecode] + Fecode[1], RM36);
6375*22dc650dSSadaf Ebrahimi if (rrc != MATCH_NOMATCH) RRETURN(rrc);
6376*22dc650dSSadaf Ebrahimi mb->verb_current_recurse = Fcurrent_recurse;
6377*22dc650dSSadaf Ebrahimi RRETURN(MATCH_COMMIT);
6378*22dc650dSSadaf Ebrahimi
6379*22dc650dSSadaf Ebrahimi case OP_PRUNE:
6380*22dc650dSSadaf Ebrahimi RMATCH(Fecode + PRIV(OP_lengths)[*Fecode], RM14);
6381*22dc650dSSadaf Ebrahimi if (rrc != MATCH_NOMATCH) RRETURN(rrc);
6382*22dc650dSSadaf Ebrahimi mb->verb_current_recurse = Fcurrent_recurse;
6383*22dc650dSSadaf Ebrahimi RRETURN(MATCH_PRUNE);
6384*22dc650dSSadaf Ebrahimi
6385*22dc650dSSadaf Ebrahimi case OP_PRUNE_ARG:
6386*22dc650dSSadaf Ebrahimi Fmark = mb->nomatch_mark = Fecode + 2;
6387*22dc650dSSadaf Ebrahimi RMATCH(Fecode + PRIV(OP_lengths)[*Fecode] + Fecode[1], RM15);
6388*22dc650dSSadaf Ebrahimi if (rrc != MATCH_NOMATCH) RRETURN(rrc);
6389*22dc650dSSadaf Ebrahimi mb->verb_current_recurse = Fcurrent_recurse;
6390*22dc650dSSadaf Ebrahimi RRETURN(MATCH_PRUNE);
6391*22dc650dSSadaf Ebrahimi
6392*22dc650dSSadaf Ebrahimi case OP_SKIP:
6393*22dc650dSSadaf Ebrahimi RMATCH(Fecode + PRIV(OP_lengths)[*Fecode], RM16);
6394*22dc650dSSadaf Ebrahimi if (rrc != MATCH_NOMATCH) RRETURN(rrc);
6395*22dc650dSSadaf Ebrahimi mb->verb_skip_ptr = Feptr; /* Pass back current position */
6396*22dc650dSSadaf Ebrahimi mb->verb_current_recurse = Fcurrent_recurse;
6397*22dc650dSSadaf Ebrahimi RRETURN(MATCH_SKIP);
6398*22dc650dSSadaf Ebrahimi
6399*22dc650dSSadaf Ebrahimi /* Note that, for Perl compatibility, SKIP with an argument does NOT set
6400*22dc650dSSadaf Ebrahimi nomatch_mark. When a pattern match ends with a SKIP_ARG for which there was
6401*22dc650dSSadaf Ebrahimi not a matching mark, we have to re-run the match, ignoring the SKIP_ARG
6402*22dc650dSSadaf Ebrahimi that failed and any that precede it (either they also failed, or were not
6403*22dc650dSSadaf Ebrahimi triggered). To do this, we maintain a count of executed SKIP_ARGs. If a
6404*22dc650dSSadaf Ebrahimi SKIP_ARG gets to top level, the match is re-run with mb->ignore_skip_arg
6405*22dc650dSSadaf Ebrahimi set to the count of the one that failed. */
6406*22dc650dSSadaf Ebrahimi
6407*22dc650dSSadaf Ebrahimi case OP_SKIP_ARG:
6408*22dc650dSSadaf Ebrahimi mb->skip_arg_count++;
6409*22dc650dSSadaf Ebrahimi if (mb->skip_arg_count <= mb->ignore_skip_arg)
6410*22dc650dSSadaf Ebrahimi {
6411*22dc650dSSadaf Ebrahimi Fecode += PRIV(OP_lengths)[*Fecode] + Fecode[1];
6412*22dc650dSSadaf Ebrahimi break;
6413*22dc650dSSadaf Ebrahimi }
6414*22dc650dSSadaf Ebrahimi RMATCH(Fecode + PRIV(OP_lengths)[*Fecode] + Fecode[1], RM17);
6415*22dc650dSSadaf Ebrahimi if (rrc != MATCH_NOMATCH) RRETURN(rrc);
6416*22dc650dSSadaf Ebrahimi
6417*22dc650dSSadaf Ebrahimi /* Pass back the current skip name and return the special MATCH_SKIP_ARG
6418*22dc650dSSadaf Ebrahimi return code. This will either be caught by a matching MARK, or get to the
6419*22dc650dSSadaf Ebrahimi top, where it causes a rematch with mb->ignore_skip_arg set to the value of
6420*22dc650dSSadaf Ebrahimi mb->skip_arg_count. */
6421*22dc650dSSadaf Ebrahimi
6422*22dc650dSSadaf Ebrahimi mb->verb_skip_ptr = Fecode + 2;
6423*22dc650dSSadaf Ebrahimi mb->verb_current_recurse = Fcurrent_recurse;
6424*22dc650dSSadaf Ebrahimi RRETURN(MATCH_SKIP_ARG);
6425*22dc650dSSadaf Ebrahimi
6426*22dc650dSSadaf Ebrahimi /* For THEN (and THEN_ARG) we pass back the address of the opcode, so that
6427*22dc650dSSadaf Ebrahimi the branch in which it occurs can be determined. */
6428*22dc650dSSadaf Ebrahimi
6429*22dc650dSSadaf Ebrahimi case OP_THEN:
6430*22dc650dSSadaf Ebrahimi RMATCH(Fecode + PRIV(OP_lengths)[*Fecode], RM18);
6431*22dc650dSSadaf Ebrahimi if (rrc != MATCH_NOMATCH) RRETURN(rrc);
6432*22dc650dSSadaf Ebrahimi mb->verb_ecode_ptr = Fecode;
6433*22dc650dSSadaf Ebrahimi mb->verb_current_recurse = Fcurrent_recurse;
6434*22dc650dSSadaf Ebrahimi RRETURN(MATCH_THEN);
6435*22dc650dSSadaf Ebrahimi
6436*22dc650dSSadaf Ebrahimi case OP_THEN_ARG:
6437*22dc650dSSadaf Ebrahimi Fmark = mb->nomatch_mark = Fecode + 2;
6438*22dc650dSSadaf Ebrahimi RMATCH(Fecode + PRIV(OP_lengths)[*Fecode] + Fecode[1], RM19);
6439*22dc650dSSadaf Ebrahimi if (rrc != MATCH_NOMATCH) RRETURN(rrc);
6440*22dc650dSSadaf Ebrahimi mb->verb_ecode_ptr = Fecode;
6441*22dc650dSSadaf Ebrahimi mb->verb_current_recurse = Fcurrent_recurse;
6442*22dc650dSSadaf Ebrahimi RRETURN(MATCH_THEN);
6443*22dc650dSSadaf Ebrahimi
6444*22dc650dSSadaf Ebrahimi
6445*22dc650dSSadaf Ebrahimi /* ===================================================================== */
6446*22dc650dSSadaf Ebrahimi /* There's been some horrible disaster. Arrival here can only mean there is
6447*22dc650dSSadaf Ebrahimi something seriously wrong in the code above or the OP_xxx definitions. */
6448*22dc650dSSadaf Ebrahimi
6449*22dc650dSSadaf Ebrahimi default:
6450*22dc650dSSadaf Ebrahimi return PCRE2_ERROR_INTERNAL;
6451*22dc650dSSadaf Ebrahimi }
6452*22dc650dSSadaf Ebrahimi
6453*22dc650dSSadaf Ebrahimi /* Do not insert any code in here without much thought; it is assumed
6454*22dc650dSSadaf Ebrahimi that "continue" in the code above comes out to here to repeat the main
6455*22dc650dSSadaf Ebrahimi loop. */
6456*22dc650dSSadaf Ebrahimi
6457*22dc650dSSadaf Ebrahimi } /* End of main loop */
6458*22dc650dSSadaf Ebrahimi /* Control never reaches here */
6459*22dc650dSSadaf Ebrahimi
6460*22dc650dSSadaf Ebrahimi
6461*22dc650dSSadaf Ebrahimi /* ========================================================================= */
6462*22dc650dSSadaf Ebrahimi /* The RRETURN() macro jumps here. The number that is saved in Freturn_id
6463*22dc650dSSadaf Ebrahimi indicates which label we actually want to return to. The value in Frdepth is
6464*22dc650dSSadaf Ebrahimi the index number of the frame in the vector. The return value has been placed
6465*22dc650dSSadaf Ebrahimi in rrc. */
6466*22dc650dSSadaf Ebrahimi
6467*22dc650dSSadaf Ebrahimi #define LBL(val) case val: goto L_RM##val;
6468*22dc650dSSadaf Ebrahimi
6469*22dc650dSSadaf Ebrahimi RETURN_SWITCH:
6470*22dc650dSSadaf Ebrahimi if (Feptr > mb->last_used_ptr) mb->last_used_ptr = Feptr;
6471*22dc650dSSadaf Ebrahimi if (Frdepth == 0) return rrc; /* Exit from the top level */
6472*22dc650dSSadaf Ebrahimi F = (heapframe *)((char *)F - Fback_frame); /* Backtrack */
6473*22dc650dSSadaf Ebrahimi mb->cb->callout_flags |= PCRE2_CALLOUT_BACKTRACK; /* Note for callouts */
6474*22dc650dSSadaf Ebrahimi
6475*22dc650dSSadaf Ebrahimi #ifdef DEBUG_SHOW_RMATCH
6476*22dc650dSSadaf Ebrahimi fprintf(stderr, "++ RETURN %d to RM%d\n", rrc, Freturn_id);
6477*22dc650dSSadaf Ebrahimi #endif
6478*22dc650dSSadaf Ebrahimi
6479*22dc650dSSadaf Ebrahimi switch (Freturn_id)
6480*22dc650dSSadaf Ebrahimi {
6481*22dc650dSSadaf Ebrahimi LBL( 1) LBL( 2) LBL( 3) LBL( 4) LBL( 5) LBL( 6) LBL( 7) LBL( 8)
6482*22dc650dSSadaf Ebrahimi LBL( 9) LBL(10) LBL(11) LBL(12) LBL(13) LBL(14) LBL(15) LBL(16)
6483*22dc650dSSadaf Ebrahimi LBL(17) LBL(18) LBL(19) LBL(20) LBL(21) LBL(22) LBL(23) LBL(24)
6484*22dc650dSSadaf Ebrahimi LBL(25) LBL(26) LBL(27) LBL(28) LBL(29) LBL(30) LBL(31) LBL(32)
6485*22dc650dSSadaf Ebrahimi LBL(33) LBL(34) LBL(35) LBL(36) LBL(37)
6486*22dc650dSSadaf Ebrahimi
6487*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_WIDE_CHARS
6488*22dc650dSSadaf Ebrahimi LBL(100) LBL(101)
6489*22dc650dSSadaf Ebrahimi #endif
6490*22dc650dSSadaf Ebrahimi
6491*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_UNICODE
6492*22dc650dSSadaf Ebrahimi LBL(200) LBL(201) LBL(202) LBL(203) LBL(204) LBL(205) LBL(206)
6493*22dc650dSSadaf Ebrahimi LBL(207) LBL(208) LBL(209) LBL(210) LBL(211) LBL(212) LBL(213)
6494*22dc650dSSadaf Ebrahimi LBL(214) LBL(215) LBL(216) LBL(217) LBL(218) LBL(219) LBL(220)
6495*22dc650dSSadaf Ebrahimi LBL(221) LBL(222) LBL(223) LBL(224) LBL(225)
6496*22dc650dSSadaf Ebrahimi #endif
6497*22dc650dSSadaf Ebrahimi
6498*22dc650dSSadaf Ebrahimi default:
6499*22dc650dSSadaf Ebrahimi return PCRE2_ERROR_INTERNAL;
6500*22dc650dSSadaf Ebrahimi }
6501*22dc650dSSadaf Ebrahimi #undef LBL
6502*22dc650dSSadaf Ebrahimi }
6503*22dc650dSSadaf Ebrahimi
6504*22dc650dSSadaf Ebrahimi
6505*22dc650dSSadaf Ebrahimi /*************************************************
6506*22dc650dSSadaf Ebrahimi * Match a Regular Expression *
6507*22dc650dSSadaf Ebrahimi *************************************************/
6508*22dc650dSSadaf Ebrahimi
6509*22dc650dSSadaf Ebrahimi /* This function applies a compiled pattern to a subject string and picks out
6510*22dc650dSSadaf Ebrahimi portions of the string if it matches. Two elements in the vector are set for
6511*22dc650dSSadaf Ebrahimi each substring: the offsets to the start and end of the substring.
6512*22dc650dSSadaf Ebrahimi
6513*22dc650dSSadaf Ebrahimi Arguments:
6514*22dc650dSSadaf Ebrahimi code points to the compiled expression
6515*22dc650dSSadaf Ebrahimi subject points to the subject string
6516*22dc650dSSadaf Ebrahimi length length of subject string (may contain binary zeros)
6517*22dc650dSSadaf Ebrahimi start_offset where to start in the subject string
6518*22dc650dSSadaf Ebrahimi options option bits
6519*22dc650dSSadaf Ebrahimi match_data points to a match_data block
6520*22dc650dSSadaf Ebrahimi mcontext points a PCRE2 context
6521*22dc650dSSadaf Ebrahimi
6522*22dc650dSSadaf Ebrahimi Returns: > 0 => success; value is the number of ovector pairs filled
6523*22dc650dSSadaf Ebrahimi = 0 => success, but ovector is not big enough
6524*22dc650dSSadaf Ebrahimi = -1 => failed to match (PCRE2_ERROR_NOMATCH)
6525*22dc650dSSadaf Ebrahimi = -2 => partial match (PCRE2_ERROR_PARTIAL)
6526*22dc650dSSadaf Ebrahimi < -2 => some kind of unexpected problem
6527*22dc650dSSadaf Ebrahimi */
6528*22dc650dSSadaf Ebrahimi
6529*22dc650dSSadaf Ebrahimi PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
pcre2_match(const pcre2_code * code,PCRE2_SPTR subject,PCRE2_SIZE length,PCRE2_SIZE start_offset,uint32_t options,pcre2_match_data * match_data,pcre2_match_context * mcontext)6530*22dc650dSSadaf Ebrahimi pcre2_match(const pcre2_code *code, PCRE2_SPTR subject, PCRE2_SIZE length,
6531*22dc650dSSadaf Ebrahimi PCRE2_SIZE start_offset, uint32_t options, pcre2_match_data *match_data,
6532*22dc650dSSadaf Ebrahimi pcre2_match_context *mcontext)
6533*22dc650dSSadaf Ebrahimi {
6534*22dc650dSSadaf Ebrahimi int rc;
6535*22dc650dSSadaf Ebrahimi int was_zero_terminated = 0;
6536*22dc650dSSadaf Ebrahimi const uint8_t *start_bits = NULL;
6537*22dc650dSSadaf Ebrahimi const pcre2_real_code *re = (const pcre2_real_code *)code;
6538*22dc650dSSadaf Ebrahimi
6539*22dc650dSSadaf Ebrahimi BOOL anchored;
6540*22dc650dSSadaf Ebrahimi BOOL firstline;
6541*22dc650dSSadaf Ebrahimi BOOL has_first_cu = FALSE;
6542*22dc650dSSadaf Ebrahimi BOOL has_req_cu = FALSE;
6543*22dc650dSSadaf Ebrahimi BOOL startline;
6544*22dc650dSSadaf Ebrahimi
6545*22dc650dSSadaf Ebrahimi #if PCRE2_CODE_UNIT_WIDTH == 8
6546*22dc650dSSadaf Ebrahimi PCRE2_SPTR memchr_found_first_cu;
6547*22dc650dSSadaf Ebrahimi PCRE2_SPTR memchr_found_first_cu2;
6548*22dc650dSSadaf Ebrahimi #endif
6549*22dc650dSSadaf Ebrahimi
6550*22dc650dSSadaf Ebrahimi PCRE2_UCHAR first_cu = 0;
6551*22dc650dSSadaf Ebrahimi PCRE2_UCHAR first_cu2 = 0;
6552*22dc650dSSadaf Ebrahimi PCRE2_UCHAR req_cu = 0;
6553*22dc650dSSadaf Ebrahimi PCRE2_UCHAR req_cu2 = 0;
6554*22dc650dSSadaf Ebrahimi
6555*22dc650dSSadaf Ebrahimi PCRE2_SPTR bumpalong_limit;
6556*22dc650dSSadaf Ebrahimi PCRE2_SPTR end_subject;
6557*22dc650dSSadaf Ebrahimi PCRE2_SPTR true_end_subject;
6558*22dc650dSSadaf Ebrahimi PCRE2_SPTR start_match;
6559*22dc650dSSadaf Ebrahimi PCRE2_SPTR req_cu_ptr;
6560*22dc650dSSadaf Ebrahimi PCRE2_SPTR start_partial;
6561*22dc650dSSadaf Ebrahimi PCRE2_SPTR match_partial;
6562*22dc650dSSadaf Ebrahimi
6563*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_JIT
6564*22dc650dSSadaf Ebrahimi BOOL use_jit;
6565*22dc650dSSadaf Ebrahimi #endif
6566*22dc650dSSadaf Ebrahimi
6567*22dc650dSSadaf Ebrahimi /* This flag is needed even when Unicode is not supported for convenience
6568*22dc650dSSadaf Ebrahimi (it is used by the IS_NEWLINE macro). */
6569*22dc650dSSadaf Ebrahimi
6570*22dc650dSSadaf Ebrahimi BOOL utf = FALSE;
6571*22dc650dSSadaf Ebrahimi
6572*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_UNICODE
6573*22dc650dSSadaf Ebrahimi BOOL ucp = FALSE;
6574*22dc650dSSadaf Ebrahimi BOOL allow_invalid;
6575*22dc650dSSadaf Ebrahimi uint32_t fragment_options = 0;
6576*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_JIT
6577*22dc650dSSadaf Ebrahimi BOOL jit_checked_utf = FALSE;
6578*22dc650dSSadaf Ebrahimi #endif
6579*22dc650dSSadaf Ebrahimi #endif /* SUPPORT_UNICODE */
6580*22dc650dSSadaf Ebrahimi
6581*22dc650dSSadaf Ebrahimi PCRE2_SIZE frame_size;
6582*22dc650dSSadaf Ebrahimi PCRE2_SIZE heapframes_size;
6583*22dc650dSSadaf Ebrahimi
6584*22dc650dSSadaf Ebrahimi /* We need to have mb as a pointer to a match block, because the IS_NEWLINE
6585*22dc650dSSadaf Ebrahimi macro is used below, and it expects NLBLOCK to be defined as a pointer. */
6586*22dc650dSSadaf Ebrahimi
6587*22dc650dSSadaf Ebrahimi pcre2_callout_block cb;
6588*22dc650dSSadaf Ebrahimi match_block actual_match_block;
6589*22dc650dSSadaf Ebrahimi match_block *mb = &actual_match_block;
6590*22dc650dSSadaf Ebrahimi
6591*22dc650dSSadaf Ebrahimi /* Recognize NULL, length 0 as an empty string. */
6592*22dc650dSSadaf Ebrahimi
6593*22dc650dSSadaf Ebrahimi if (subject == NULL && length == 0) subject = (PCRE2_SPTR)"";
6594*22dc650dSSadaf Ebrahimi
6595*22dc650dSSadaf Ebrahimi /* Plausibility checks */
6596*22dc650dSSadaf Ebrahimi
6597*22dc650dSSadaf Ebrahimi if ((options & ~PUBLIC_MATCH_OPTIONS) != 0) return PCRE2_ERROR_BADOPTION;
6598*22dc650dSSadaf Ebrahimi if (code == NULL || subject == NULL || match_data == NULL)
6599*22dc650dSSadaf Ebrahimi return PCRE2_ERROR_NULL;
6600*22dc650dSSadaf Ebrahimi
6601*22dc650dSSadaf Ebrahimi start_match = subject + start_offset;
6602*22dc650dSSadaf Ebrahimi req_cu_ptr = start_match - 1;
6603*22dc650dSSadaf Ebrahimi if (length == PCRE2_ZERO_TERMINATED)
6604*22dc650dSSadaf Ebrahimi {
6605*22dc650dSSadaf Ebrahimi length = PRIV(strlen)(subject);
6606*22dc650dSSadaf Ebrahimi was_zero_terminated = 1;
6607*22dc650dSSadaf Ebrahimi }
6608*22dc650dSSadaf Ebrahimi true_end_subject = end_subject = subject + length;
6609*22dc650dSSadaf Ebrahimi
6610*22dc650dSSadaf Ebrahimi if (start_offset > length) return PCRE2_ERROR_BADOFFSET;
6611*22dc650dSSadaf Ebrahimi
6612*22dc650dSSadaf Ebrahimi /* Check that the first field in the block is the magic number. */
6613*22dc650dSSadaf Ebrahimi
6614*22dc650dSSadaf Ebrahimi if (re->magic_number != MAGIC_NUMBER) return PCRE2_ERROR_BADMAGIC;
6615*22dc650dSSadaf Ebrahimi
6616*22dc650dSSadaf Ebrahimi /* Check the code unit width. */
6617*22dc650dSSadaf Ebrahimi
6618*22dc650dSSadaf Ebrahimi if ((re->flags & PCRE2_MODE_MASK) != PCRE2_CODE_UNIT_WIDTH/8)
6619*22dc650dSSadaf Ebrahimi return PCRE2_ERROR_BADMODE;
6620*22dc650dSSadaf Ebrahimi
6621*22dc650dSSadaf Ebrahimi /* PCRE2_NOTEMPTY and PCRE2_NOTEMPTY_ATSTART are match-time flags in the
6622*22dc650dSSadaf Ebrahimi options variable for this function. Users of PCRE2 who are not calling the
6623*22dc650dSSadaf Ebrahimi function directly would like to have a way of setting these flags, in the same
6624*22dc650dSSadaf Ebrahimi way that they can set pcre2_compile() flags like PCRE2_NO_AUTOPOSSESS with
6625*22dc650dSSadaf Ebrahimi constructions like (*NO_AUTOPOSSESS). To enable this, (*NOTEMPTY) and
6626*22dc650dSSadaf Ebrahimi (*NOTEMPTY_ATSTART) set bits in the pattern's "flag" function which we now
6627*22dc650dSSadaf Ebrahimi transfer to the options for this function. The bits are guaranteed to be
6628*22dc650dSSadaf Ebrahimi adjacent, but do not have the same values. This bit of Boolean trickery assumes
6629*22dc650dSSadaf Ebrahimi that the match-time bits are not more significant than the flag bits. If by
6630*22dc650dSSadaf Ebrahimi accident this is not the case, a compile-time division by zero error will
6631*22dc650dSSadaf Ebrahimi occur. */
6632*22dc650dSSadaf Ebrahimi
6633*22dc650dSSadaf Ebrahimi #define FF (PCRE2_NOTEMPTY_SET|PCRE2_NE_ATST_SET)
6634*22dc650dSSadaf Ebrahimi #define OO (PCRE2_NOTEMPTY|PCRE2_NOTEMPTY_ATSTART)
6635*22dc650dSSadaf Ebrahimi options |= (re->flags & FF) / ((FF & (~FF+1)) / (OO & (~OO+1)));
6636*22dc650dSSadaf Ebrahimi #undef FF
6637*22dc650dSSadaf Ebrahimi #undef OO
6638*22dc650dSSadaf Ebrahimi
6639*22dc650dSSadaf Ebrahimi /* If the pattern was successfully studied with JIT support, we will run the
6640*22dc650dSSadaf Ebrahimi JIT executable instead of the rest of this function. Most options must be set
6641*22dc650dSSadaf Ebrahimi at compile time for the JIT code to be usable. */
6642*22dc650dSSadaf Ebrahimi
6643*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_JIT
6644*22dc650dSSadaf Ebrahimi use_jit = (re->executable_jit != NULL &&
6645*22dc650dSSadaf Ebrahimi (options & ~PUBLIC_JIT_MATCH_OPTIONS) == 0);
6646*22dc650dSSadaf Ebrahimi #endif
6647*22dc650dSSadaf Ebrahimi
6648*22dc650dSSadaf Ebrahimi /* Initialize UTF/UCP parameters. */
6649*22dc650dSSadaf Ebrahimi
6650*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_UNICODE
6651*22dc650dSSadaf Ebrahimi utf = (re->overall_options & PCRE2_UTF) != 0;
6652*22dc650dSSadaf Ebrahimi allow_invalid = (re->overall_options & PCRE2_MATCH_INVALID_UTF) != 0;
6653*22dc650dSSadaf Ebrahimi ucp = (re->overall_options & PCRE2_UCP) != 0;
6654*22dc650dSSadaf Ebrahimi #endif /* SUPPORT_UNICODE */
6655*22dc650dSSadaf Ebrahimi
6656*22dc650dSSadaf Ebrahimi /* Convert the partial matching flags into an integer. */
6657*22dc650dSSadaf Ebrahimi
6658*22dc650dSSadaf Ebrahimi mb->partial = ((options & PCRE2_PARTIAL_HARD) != 0)? 2 :
6659*22dc650dSSadaf Ebrahimi ((options & PCRE2_PARTIAL_SOFT) != 0)? 1 : 0;
6660*22dc650dSSadaf Ebrahimi
6661*22dc650dSSadaf Ebrahimi /* Partial matching and PCRE2_ENDANCHORED are currently not allowed at the same
6662*22dc650dSSadaf Ebrahimi time. */
6663*22dc650dSSadaf Ebrahimi
6664*22dc650dSSadaf Ebrahimi if (mb->partial != 0 &&
6665*22dc650dSSadaf Ebrahimi ((re->overall_options | options) & PCRE2_ENDANCHORED) != 0)
6666*22dc650dSSadaf Ebrahimi return PCRE2_ERROR_BADOPTION;
6667*22dc650dSSadaf Ebrahimi
6668*22dc650dSSadaf Ebrahimi /* It is an error to set an offset limit without setting the flag at compile
6669*22dc650dSSadaf Ebrahimi time. */
6670*22dc650dSSadaf Ebrahimi
6671*22dc650dSSadaf Ebrahimi if (mcontext != NULL && mcontext->offset_limit != PCRE2_UNSET &&
6672*22dc650dSSadaf Ebrahimi (re->overall_options & PCRE2_USE_OFFSET_LIMIT) == 0)
6673*22dc650dSSadaf Ebrahimi return PCRE2_ERROR_BADOFFSETLIMIT;
6674*22dc650dSSadaf Ebrahimi
6675*22dc650dSSadaf Ebrahimi /* If the match data block was previously used with PCRE2_COPY_MATCHED_SUBJECT,
6676*22dc650dSSadaf Ebrahimi free the memory that was obtained. Set the field to NULL for no match cases. */
6677*22dc650dSSadaf Ebrahimi
6678*22dc650dSSadaf Ebrahimi if ((match_data->flags & PCRE2_MD_COPIED_SUBJECT) != 0)
6679*22dc650dSSadaf Ebrahimi {
6680*22dc650dSSadaf Ebrahimi match_data->memctl.free((void *)match_data->subject,
6681*22dc650dSSadaf Ebrahimi match_data->memctl.memory_data);
6682*22dc650dSSadaf Ebrahimi match_data->flags &= ~PCRE2_MD_COPIED_SUBJECT;
6683*22dc650dSSadaf Ebrahimi }
6684*22dc650dSSadaf Ebrahimi match_data->subject = NULL;
6685*22dc650dSSadaf Ebrahimi
6686*22dc650dSSadaf Ebrahimi /* Zero the error offset in case the first code unit is invalid UTF. */
6687*22dc650dSSadaf Ebrahimi
6688*22dc650dSSadaf Ebrahimi match_data->startchar = 0;
6689*22dc650dSSadaf Ebrahimi
6690*22dc650dSSadaf Ebrahimi
6691*22dc650dSSadaf Ebrahimi /* ============================= JIT matching ============================== */
6692*22dc650dSSadaf Ebrahimi
6693*22dc650dSSadaf Ebrahimi /* Prepare for JIT matching. Check a UTF string for validity unless no check is
6694*22dc650dSSadaf Ebrahimi requested or invalid UTF can be handled. We check only the portion of the
6695*22dc650dSSadaf Ebrahimi subject that might be be inspected during matching - from the offset minus the
6696*22dc650dSSadaf Ebrahimi maximum lookbehind to the given length. This saves time when a small part of a
6697*22dc650dSSadaf Ebrahimi large subject is being matched by the use of a starting offset. Note that the
6698*22dc650dSSadaf Ebrahimi maximum lookbehind is a number of characters, not code units. */
6699*22dc650dSSadaf Ebrahimi
6700*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_JIT
6701*22dc650dSSadaf Ebrahimi if (use_jit)
6702*22dc650dSSadaf Ebrahimi {
6703*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_UNICODE
6704*22dc650dSSadaf Ebrahimi if (utf && (options & PCRE2_NO_UTF_CHECK) == 0 && !allow_invalid)
6705*22dc650dSSadaf Ebrahimi {
6706*22dc650dSSadaf Ebrahimi #if PCRE2_CODE_UNIT_WIDTH != 32
6707*22dc650dSSadaf Ebrahimi unsigned int i;
6708*22dc650dSSadaf Ebrahimi #endif
6709*22dc650dSSadaf Ebrahimi
6710*22dc650dSSadaf Ebrahimi /* For 8-bit and 16-bit UTF, check that the first code unit is a valid
6711*22dc650dSSadaf Ebrahimi character start. */
6712*22dc650dSSadaf Ebrahimi
6713*22dc650dSSadaf Ebrahimi #if PCRE2_CODE_UNIT_WIDTH != 32
6714*22dc650dSSadaf Ebrahimi if (start_match < end_subject && NOT_FIRSTCU(*start_match))
6715*22dc650dSSadaf Ebrahimi {
6716*22dc650dSSadaf Ebrahimi if (start_offset > 0) return PCRE2_ERROR_BADUTFOFFSET;
6717*22dc650dSSadaf Ebrahimi #if PCRE2_CODE_UNIT_WIDTH == 8
6718*22dc650dSSadaf Ebrahimi return PCRE2_ERROR_UTF8_ERR20; /* Isolated 0x80 byte */
6719*22dc650dSSadaf Ebrahimi #else
6720*22dc650dSSadaf Ebrahimi return PCRE2_ERROR_UTF16_ERR3; /* Isolated low surrogate */
6721*22dc650dSSadaf Ebrahimi #endif
6722*22dc650dSSadaf Ebrahimi }
6723*22dc650dSSadaf Ebrahimi #endif /* WIDTH != 32 */
6724*22dc650dSSadaf Ebrahimi
6725*22dc650dSSadaf Ebrahimi /* Move back by the maximum lookbehind, just in case it happens at the very
6726*22dc650dSSadaf Ebrahimi start of matching. */
6727*22dc650dSSadaf Ebrahimi
6728*22dc650dSSadaf Ebrahimi #if PCRE2_CODE_UNIT_WIDTH != 32
6729*22dc650dSSadaf Ebrahimi for (i = re->max_lookbehind; i > 0 && start_match > subject; i--)
6730*22dc650dSSadaf Ebrahimi {
6731*22dc650dSSadaf Ebrahimi start_match--;
6732*22dc650dSSadaf Ebrahimi while (start_match > subject &&
6733*22dc650dSSadaf Ebrahimi #if PCRE2_CODE_UNIT_WIDTH == 8
6734*22dc650dSSadaf Ebrahimi (*start_match & 0xc0) == 0x80)
6735*22dc650dSSadaf Ebrahimi #else /* 16-bit */
6736*22dc650dSSadaf Ebrahimi (*start_match & 0xfc00) == 0xdc00)
6737*22dc650dSSadaf Ebrahimi #endif
6738*22dc650dSSadaf Ebrahimi start_match--;
6739*22dc650dSSadaf Ebrahimi }
6740*22dc650dSSadaf Ebrahimi #else /* PCRE2_CODE_UNIT_WIDTH != 32 */
6741*22dc650dSSadaf Ebrahimi
6742*22dc650dSSadaf Ebrahimi /* In the 32-bit library, one code unit equals one character. However,
6743*22dc650dSSadaf Ebrahimi we cannot just subtract the lookbehind and then compare pointers, because
6744*22dc650dSSadaf Ebrahimi a very large lookbehind could create an invalid pointer. */
6745*22dc650dSSadaf Ebrahimi
6746*22dc650dSSadaf Ebrahimi if (start_offset >= re->max_lookbehind)
6747*22dc650dSSadaf Ebrahimi start_match -= re->max_lookbehind;
6748*22dc650dSSadaf Ebrahimi else
6749*22dc650dSSadaf Ebrahimi start_match = subject;
6750*22dc650dSSadaf Ebrahimi #endif /* PCRE2_CODE_UNIT_WIDTH != 32 */
6751*22dc650dSSadaf Ebrahimi
6752*22dc650dSSadaf Ebrahimi /* Validate the relevant portion of the subject. Adjust the offset of an
6753*22dc650dSSadaf Ebrahimi invalid code point to be an absolute offset in the whole string. */
6754*22dc650dSSadaf Ebrahimi
6755*22dc650dSSadaf Ebrahimi match_data->rc = PRIV(valid_utf)(start_match,
6756*22dc650dSSadaf Ebrahimi length - (start_match - subject), &(match_data->startchar));
6757*22dc650dSSadaf Ebrahimi if (match_data->rc != 0)
6758*22dc650dSSadaf Ebrahimi {
6759*22dc650dSSadaf Ebrahimi match_data->startchar += start_match - subject;
6760*22dc650dSSadaf Ebrahimi return match_data->rc;
6761*22dc650dSSadaf Ebrahimi }
6762*22dc650dSSadaf Ebrahimi jit_checked_utf = TRUE;
6763*22dc650dSSadaf Ebrahimi }
6764*22dc650dSSadaf Ebrahimi #endif /* SUPPORT_UNICODE */
6765*22dc650dSSadaf Ebrahimi
6766*22dc650dSSadaf Ebrahimi /* If JIT returns BADOPTION, which means that the selected complete or
6767*22dc650dSSadaf Ebrahimi partial matching mode was not compiled, fall through to the interpreter. */
6768*22dc650dSSadaf Ebrahimi
6769*22dc650dSSadaf Ebrahimi rc = pcre2_jit_match(code, subject, length, start_offset, options,
6770*22dc650dSSadaf Ebrahimi match_data, mcontext);
6771*22dc650dSSadaf Ebrahimi if (rc != PCRE2_ERROR_JIT_BADOPTION)
6772*22dc650dSSadaf Ebrahimi {
6773*22dc650dSSadaf Ebrahimi match_data->subject_length = length;
6774*22dc650dSSadaf Ebrahimi if (rc >= 0 && (options & PCRE2_COPY_MATCHED_SUBJECT) != 0)
6775*22dc650dSSadaf Ebrahimi {
6776*22dc650dSSadaf Ebrahimi length = CU2BYTES(length + was_zero_terminated);
6777*22dc650dSSadaf Ebrahimi match_data->subject = match_data->memctl.malloc(length,
6778*22dc650dSSadaf Ebrahimi match_data->memctl.memory_data);
6779*22dc650dSSadaf Ebrahimi if (match_data->subject == NULL) return PCRE2_ERROR_NOMEMORY;
6780*22dc650dSSadaf Ebrahimi memcpy((void *)match_data->subject, subject, length);
6781*22dc650dSSadaf Ebrahimi match_data->flags |= PCRE2_MD_COPIED_SUBJECT;
6782*22dc650dSSadaf Ebrahimi }
6783*22dc650dSSadaf Ebrahimi return rc;
6784*22dc650dSSadaf Ebrahimi }
6785*22dc650dSSadaf Ebrahimi }
6786*22dc650dSSadaf Ebrahimi #endif /* SUPPORT_JIT */
6787*22dc650dSSadaf Ebrahimi
6788*22dc650dSSadaf Ebrahimi /* ========================= End of JIT matching ========================== */
6789*22dc650dSSadaf Ebrahimi
6790*22dc650dSSadaf Ebrahimi
6791*22dc650dSSadaf Ebrahimi /* Proceed with non-JIT matching. The default is to allow lookbehinds to the
6792*22dc650dSSadaf Ebrahimi start of the subject. A UTF check when there is a non-zero offset may change
6793*22dc650dSSadaf Ebrahimi this. */
6794*22dc650dSSadaf Ebrahimi
6795*22dc650dSSadaf Ebrahimi mb->check_subject = subject;
6796*22dc650dSSadaf Ebrahimi
6797*22dc650dSSadaf Ebrahimi /* If a UTF subject string was not checked for validity in the JIT code above,
6798*22dc650dSSadaf Ebrahimi check it here, and handle support for invalid UTF strings. The check above
6799*22dc650dSSadaf Ebrahimi happens only when invalid UTF is not supported and PCRE2_NO_CHECK_UTF is unset.
6800*22dc650dSSadaf Ebrahimi If we get here in those circumstances, it means the subject string is valid,
6801*22dc650dSSadaf Ebrahimi but for some reason JIT matching was not successful. There is no need to check
6802*22dc650dSSadaf Ebrahimi the subject again.
6803*22dc650dSSadaf Ebrahimi
6804*22dc650dSSadaf Ebrahimi We check only the portion of the subject that might be be inspected during
6805*22dc650dSSadaf Ebrahimi matching - from the offset minus the maximum lookbehind to the given length.
6806*22dc650dSSadaf Ebrahimi This saves time when a small part of a large subject is being matched by the
6807*22dc650dSSadaf Ebrahimi use of a starting offset. Note that the maximum lookbehind is a number of
6808*22dc650dSSadaf Ebrahimi characters, not code units.
6809*22dc650dSSadaf Ebrahimi
6810*22dc650dSSadaf Ebrahimi Note also that support for invalid UTF forces a check, overriding the setting
6811*22dc650dSSadaf Ebrahimi of PCRE2_NO_CHECK_UTF. */
6812*22dc650dSSadaf Ebrahimi
6813*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_UNICODE
6814*22dc650dSSadaf Ebrahimi if (utf &&
6815*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_JIT
6816*22dc650dSSadaf Ebrahimi !jit_checked_utf &&
6817*22dc650dSSadaf Ebrahimi #endif
6818*22dc650dSSadaf Ebrahimi ((options & PCRE2_NO_UTF_CHECK) == 0 || allow_invalid))
6819*22dc650dSSadaf Ebrahimi {
6820*22dc650dSSadaf Ebrahimi #if PCRE2_CODE_UNIT_WIDTH != 32
6821*22dc650dSSadaf Ebrahimi BOOL skipped_bad_start = FALSE;
6822*22dc650dSSadaf Ebrahimi #endif
6823*22dc650dSSadaf Ebrahimi
6824*22dc650dSSadaf Ebrahimi /* For 8-bit and 16-bit UTF, check that the first code unit is a valid
6825*22dc650dSSadaf Ebrahimi character start. If we are handling invalid UTF, just skip over such code
6826*22dc650dSSadaf Ebrahimi units. Otherwise, give an appropriate error. */
6827*22dc650dSSadaf Ebrahimi
6828*22dc650dSSadaf Ebrahimi #if PCRE2_CODE_UNIT_WIDTH != 32
6829*22dc650dSSadaf Ebrahimi if (allow_invalid)
6830*22dc650dSSadaf Ebrahimi {
6831*22dc650dSSadaf Ebrahimi while (start_match < end_subject && NOT_FIRSTCU(*start_match))
6832*22dc650dSSadaf Ebrahimi {
6833*22dc650dSSadaf Ebrahimi start_match++;
6834*22dc650dSSadaf Ebrahimi skipped_bad_start = TRUE;
6835*22dc650dSSadaf Ebrahimi }
6836*22dc650dSSadaf Ebrahimi }
6837*22dc650dSSadaf Ebrahimi else if (start_match < end_subject && NOT_FIRSTCU(*start_match))
6838*22dc650dSSadaf Ebrahimi {
6839*22dc650dSSadaf Ebrahimi if (start_offset > 0) return PCRE2_ERROR_BADUTFOFFSET;
6840*22dc650dSSadaf Ebrahimi #if PCRE2_CODE_UNIT_WIDTH == 8
6841*22dc650dSSadaf Ebrahimi return PCRE2_ERROR_UTF8_ERR20; /* Isolated 0x80 byte */
6842*22dc650dSSadaf Ebrahimi #else
6843*22dc650dSSadaf Ebrahimi return PCRE2_ERROR_UTF16_ERR3; /* Isolated low surrogate */
6844*22dc650dSSadaf Ebrahimi #endif
6845*22dc650dSSadaf Ebrahimi }
6846*22dc650dSSadaf Ebrahimi #endif /* WIDTH != 32 */
6847*22dc650dSSadaf Ebrahimi
6848*22dc650dSSadaf Ebrahimi /* The mb->check_subject field points to the start of UTF checking;
6849*22dc650dSSadaf Ebrahimi lookbehinds can go back no further than this. */
6850*22dc650dSSadaf Ebrahimi
6851*22dc650dSSadaf Ebrahimi mb->check_subject = start_match;
6852*22dc650dSSadaf Ebrahimi
6853*22dc650dSSadaf Ebrahimi /* Move back by the maximum lookbehind, just in case it happens at the very
6854*22dc650dSSadaf Ebrahimi start of matching, but don't do this if we skipped bad 8-bit or 16-bit code
6855*22dc650dSSadaf Ebrahimi units above. */
6856*22dc650dSSadaf Ebrahimi
6857*22dc650dSSadaf Ebrahimi #if PCRE2_CODE_UNIT_WIDTH != 32
6858*22dc650dSSadaf Ebrahimi if (!skipped_bad_start)
6859*22dc650dSSadaf Ebrahimi {
6860*22dc650dSSadaf Ebrahimi unsigned int i;
6861*22dc650dSSadaf Ebrahimi for (i = re->max_lookbehind; i > 0 && mb->check_subject > subject; i--)
6862*22dc650dSSadaf Ebrahimi {
6863*22dc650dSSadaf Ebrahimi mb->check_subject--;
6864*22dc650dSSadaf Ebrahimi while (mb->check_subject > subject &&
6865*22dc650dSSadaf Ebrahimi #if PCRE2_CODE_UNIT_WIDTH == 8
6866*22dc650dSSadaf Ebrahimi (*mb->check_subject & 0xc0) == 0x80)
6867*22dc650dSSadaf Ebrahimi #else /* 16-bit */
6868*22dc650dSSadaf Ebrahimi (*mb->check_subject & 0xfc00) == 0xdc00)
6869*22dc650dSSadaf Ebrahimi #endif
6870*22dc650dSSadaf Ebrahimi mb->check_subject--;
6871*22dc650dSSadaf Ebrahimi }
6872*22dc650dSSadaf Ebrahimi }
6873*22dc650dSSadaf Ebrahimi #else /* PCRE2_CODE_UNIT_WIDTH != 32 */
6874*22dc650dSSadaf Ebrahimi
6875*22dc650dSSadaf Ebrahimi /* In the 32-bit library, one code unit equals one character. However,
6876*22dc650dSSadaf Ebrahimi we cannot just subtract the lookbehind and then compare pointers, because
6877*22dc650dSSadaf Ebrahimi a very large lookbehind could create an invalid pointer. */
6878*22dc650dSSadaf Ebrahimi
6879*22dc650dSSadaf Ebrahimi if (start_offset >= re->max_lookbehind)
6880*22dc650dSSadaf Ebrahimi mb->check_subject -= re->max_lookbehind;
6881*22dc650dSSadaf Ebrahimi else
6882*22dc650dSSadaf Ebrahimi mb->check_subject = subject;
6883*22dc650dSSadaf Ebrahimi #endif /* PCRE2_CODE_UNIT_WIDTH != 32 */
6884*22dc650dSSadaf Ebrahimi
6885*22dc650dSSadaf Ebrahimi /* Validate the relevant portion of the subject. There's a loop in case we
6886*22dc650dSSadaf Ebrahimi encounter bad UTF in the characters preceding start_match which we are
6887*22dc650dSSadaf Ebrahimi scanning because of a lookbehind. */
6888*22dc650dSSadaf Ebrahimi
6889*22dc650dSSadaf Ebrahimi for (;;)
6890*22dc650dSSadaf Ebrahimi {
6891*22dc650dSSadaf Ebrahimi match_data->rc = PRIV(valid_utf)(mb->check_subject,
6892*22dc650dSSadaf Ebrahimi length - (mb->check_subject - subject), &(match_data->startchar));
6893*22dc650dSSadaf Ebrahimi
6894*22dc650dSSadaf Ebrahimi if (match_data->rc == 0) break; /* Valid UTF string */
6895*22dc650dSSadaf Ebrahimi
6896*22dc650dSSadaf Ebrahimi /* Invalid UTF string. Adjust the offset to be an absolute offset in the
6897*22dc650dSSadaf Ebrahimi whole string. If we are handling invalid UTF strings, set end_subject to
6898*22dc650dSSadaf Ebrahimi stop before the bad code unit, and set the options to "not end of line".
6899*22dc650dSSadaf Ebrahimi Otherwise return the error. */
6900*22dc650dSSadaf Ebrahimi
6901*22dc650dSSadaf Ebrahimi match_data->startchar += mb->check_subject - subject;
6902*22dc650dSSadaf Ebrahimi if (!allow_invalid || match_data->rc > 0) return match_data->rc;
6903*22dc650dSSadaf Ebrahimi end_subject = subject + match_data->startchar;
6904*22dc650dSSadaf Ebrahimi
6905*22dc650dSSadaf Ebrahimi /* If the end precedes start_match, it means there is invalid UTF in the
6906*22dc650dSSadaf Ebrahimi extra code units we reversed over because of a lookbehind. Advance past the
6907*22dc650dSSadaf Ebrahimi first bad code unit, and then skip invalid character starting code units in
6908*22dc650dSSadaf Ebrahimi 8-bit and 16-bit modes, and try again with the original end point. */
6909*22dc650dSSadaf Ebrahimi
6910*22dc650dSSadaf Ebrahimi if (end_subject < start_match)
6911*22dc650dSSadaf Ebrahimi {
6912*22dc650dSSadaf Ebrahimi mb->check_subject = end_subject + 1;
6913*22dc650dSSadaf Ebrahimi #if PCRE2_CODE_UNIT_WIDTH != 32
6914*22dc650dSSadaf Ebrahimi while (mb->check_subject < start_match && NOT_FIRSTCU(*mb->check_subject))
6915*22dc650dSSadaf Ebrahimi mb->check_subject++;
6916*22dc650dSSadaf Ebrahimi #endif
6917*22dc650dSSadaf Ebrahimi end_subject = true_end_subject;
6918*22dc650dSSadaf Ebrahimi }
6919*22dc650dSSadaf Ebrahimi
6920*22dc650dSSadaf Ebrahimi /* Otherwise, set the not end of line option, and do the match. */
6921*22dc650dSSadaf Ebrahimi
6922*22dc650dSSadaf Ebrahimi else
6923*22dc650dSSadaf Ebrahimi {
6924*22dc650dSSadaf Ebrahimi fragment_options = PCRE2_NOTEOL;
6925*22dc650dSSadaf Ebrahimi break;
6926*22dc650dSSadaf Ebrahimi }
6927*22dc650dSSadaf Ebrahimi }
6928*22dc650dSSadaf Ebrahimi }
6929*22dc650dSSadaf Ebrahimi #endif /* SUPPORT_UNICODE */
6930*22dc650dSSadaf Ebrahimi
6931*22dc650dSSadaf Ebrahimi /* A NULL match context means "use a default context", but we take the memory
6932*22dc650dSSadaf Ebrahimi control functions from the pattern. */
6933*22dc650dSSadaf Ebrahimi
6934*22dc650dSSadaf Ebrahimi if (mcontext == NULL)
6935*22dc650dSSadaf Ebrahimi {
6936*22dc650dSSadaf Ebrahimi mcontext = (pcre2_match_context *)(&PRIV(default_match_context));
6937*22dc650dSSadaf Ebrahimi mb->memctl = re->memctl;
6938*22dc650dSSadaf Ebrahimi }
6939*22dc650dSSadaf Ebrahimi else mb->memctl = mcontext->memctl;
6940*22dc650dSSadaf Ebrahimi
6941*22dc650dSSadaf Ebrahimi anchored = ((re->overall_options | options) & PCRE2_ANCHORED) != 0;
6942*22dc650dSSadaf Ebrahimi firstline = !anchored && (re->overall_options & PCRE2_FIRSTLINE) != 0;
6943*22dc650dSSadaf Ebrahimi startline = (re->flags & PCRE2_STARTLINE) != 0;
6944*22dc650dSSadaf Ebrahimi bumpalong_limit = (mcontext->offset_limit == PCRE2_UNSET)?
6945*22dc650dSSadaf Ebrahimi true_end_subject : subject + mcontext->offset_limit;
6946*22dc650dSSadaf Ebrahimi
6947*22dc650dSSadaf Ebrahimi /* Initialize and set up the fixed fields in the callout block, with a pointer
6948*22dc650dSSadaf Ebrahimi in the match block. */
6949*22dc650dSSadaf Ebrahimi
6950*22dc650dSSadaf Ebrahimi mb->cb = &cb;
6951*22dc650dSSadaf Ebrahimi cb.version = 2;
6952*22dc650dSSadaf Ebrahimi cb.subject = subject;
6953*22dc650dSSadaf Ebrahimi cb.subject_length = (PCRE2_SIZE)(end_subject - subject);
6954*22dc650dSSadaf Ebrahimi cb.callout_flags = 0;
6955*22dc650dSSadaf Ebrahimi
6956*22dc650dSSadaf Ebrahimi /* Fill in the remaining fields in the match block, except for moptions, which
6957*22dc650dSSadaf Ebrahimi gets set later. */
6958*22dc650dSSadaf Ebrahimi
6959*22dc650dSSadaf Ebrahimi mb->callout = mcontext->callout;
6960*22dc650dSSadaf Ebrahimi mb->callout_data = mcontext->callout_data;
6961*22dc650dSSadaf Ebrahimi
6962*22dc650dSSadaf Ebrahimi mb->start_subject = subject;
6963*22dc650dSSadaf Ebrahimi mb->start_offset = start_offset;
6964*22dc650dSSadaf Ebrahimi mb->end_subject = end_subject;
6965*22dc650dSSadaf Ebrahimi mb->true_end_subject = true_end_subject;
6966*22dc650dSSadaf Ebrahimi mb->hasthen = (re->flags & PCRE2_HASTHEN) != 0;
6967*22dc650dSSadaf Ebrahimi mb->allowemptypartial = (re->max_lookbehind > 0) ||
6968*22dc650dSSadaf Ebrahimi (re->flags & PCRE2_MATCH_EMPTY) != 0;
6969*22dc650dSSadaf Ebrahimi mb->poptions = re->overall_options; /* Pattern options */
6970*22dc650dSSadaf Ebrahimi mb->ignore_skip_arg = 0;
6971*22dc650dSSadaf Ebrahimi mb->mark = mb->nomatch_mark = NULL; /* In case never set */
6972*22dc650dSSadaf Ebrahimi
6973*22dc650dSSadaf Ebrahimi /* The name table is needed for finding all the numbers associated with a
6974*22dc650dSSadaf Ebrahimi given name, for condition testing. The code follows the name table. */
6975*22dc650dSSadaf Ebrahimi
6976*22dc650dSSadaf Ebrahimi mb->name_table = (PCRE2_UCHAR *)((uint8_t *)re + sizeof(pcre2_real_code));
6977*22dc650dSSadaf Ebrahimi mb->name_count = re->name_count;
6978*22dc650dSSadaf Ebrahimi mb->name_entry_size = re->name_entry_size;
6979*22dc650dSSadaf Ebrahimi mb->start_code = mb->name_table + re->name_count * re->name_entry_size;
6980*22dc650dSSadaf Ebrahimi
6981*22dc650dSSadaf Ebrahimi /* Process the \R and newline settings. */
6982*22dc650dSSadaf Ebrahimi
6983*22dc650dSSadaf Ebrahimi mb->bsr_convention = re->bsr_convention;
6984*22dc650dSSadaf Ebrahimi mb->nltype = NLTYPE_FIXED;
6985*22dc650dSSadaf Ebrahimi switch(re->newline_convention)
6986*22dc650dSSadaf Ebrahimi {
6987*22dc650dSSadaf Ebrahimi case PCRE2_NEWLINE_CR:
6988*22dc650dSSadaf Ebrahimi mb->nllen = 1;
6989*22dc650dSSadaf Ebrahimi mb->nl[0] = CHAR_CR;
6990*22dc650dSSadaf Ebrahimi break;
6991*22dc650dSSadaf Ebrahimi
6992*22dc650dSSadaf Ebrahimi case PCRE2_NEWLINE_LF:
6993*22dc650dSSadaf Ebrahimi mb->nllen = 1;
6994*22dc650dSSadaf Ebrahimi mb->nl[0] = CHAR_NL;
6995*22dc650dSSadaf Ebrahimi break;
6996*22dc650dSSadaf Ebrahimi
6997*22dc650dSSadaf Ebrahimi case PCRE2_NEWLINE_NUL:
6998*22dc650dSSadaf Ebrahimi mb->nllen = 1;
6999*22dc650dSSadaf Ebrahimi mb->nl[0] = CHAR_NUL;
7000*22dc650dSSadaf Ebrahimi break;
7001*22dc650dSSadaf Ebrahimi
7002*22dc650dSSadaf Ebrahimi case PCRE2_NEWLINE_CRLF:
7003*22dc650dSSadaf Ebrahimi mb->nllen = 2;
7004*22dc650dSSadaf Ebrahimi mb->nl[0] = CHAR_CR;
7005*22dc650dSSadaf Ebrahimi mb->nl[1] = CHAR_NL;
7006*22dc650dSSadaf Ebrahimi break;
7007*22dc650dSSadaf Ebrahimi
7008*22dc650dSSadaf Ebrahimi case PCRE2_NEWLINE_ANY:
7009*22dc650dSSadaf Ebrahimi mb->nltype = NLTYPE_ANY;
7010*22dc650dSSadaf Ebrahimi break;
7011*22dc650dSSadaf Ebrahimi
7012*22dc650dSSadaf Ebrahimi case PCRE2_NEWLINE_ANYCRLF:
7013*22dc650dSSadaf Ebrahimi mb->nltype = NLTYPE_ANYCRLF;
7014*22dc650dSSadaf Ebrahimi break;
7015*22dc650dSSadaf Ebrahimi
7016*22dc650dSSadaf Ebrahimi default: return PCRE2_ERROR_INTERNAL;
7017*22dc650dSSadaf Ebrahimi }
7018*22dc650dSSadaf Ebrahimi
7019*22dc650dSSadaf Ebrahimi /* The backtracking frames have fixed data at the front, and a PCRE2_SIZE
7020*22dc650dSSadaf Ebrahimi vector at the end, whose size depends on the number of capturing parentheses in
7021*22dc650dSSadaf Ebrahimi the pattern. It is not used at all if there are no capturing parentheses.
7022*22dc650dSSadaf Ebrahimi
7023*22dc650dSSadaf Ebrahimi frame_size is the total size of each frame
7024*22dc650dSSadaf Ebrahimi match_data->heapframes is the pointer to the frames vector
7025*22dc650dSSadaf Ebrahimi match_data->heapframes_size is the allocated size of the vector
7026*22dc650dSSadaf Ebrahimi
7027*22dc650dSSadaf Ebrahimi We must pad the frame_size for alignment to ensure subsequent frames are as
7028*22dc650dSSadaf Ebrahimi aligned as heapframe. Whilst ovector is word-aligned due to being a PCRE2_SIZE
7029*22dc650dSSadaf Ebrahimi array, that does not guarantee it is suitably aligned for pointers, as some
7030*22dc650dSSadaf Ebrahimi architectures have pointers that are larger than a size_t. */
7031*22dc650dSSadaf Ebrahimi
7032*22dc650dSSadaf Ebrahimi frame_size = (offsetof(heapframe, ovector) +
7033*22dc650dSSadaf Ebrahimi re->top_bracket * 2 * sizeof(PCRE2_SIZE) + HEAPFRAME_ALIGNMENT - 1) &
7034*22dc650dSSadaf Ebrahimi ~(HEAPFRAME_ALIGNMENT - 1);
7035*22dc650dSSadaf Ebrahimi
7036*22dc650dSSadaf Ebrahimi /* Limits set in the pattern override the match context only if they are
7037*22dc650dSSadaf Ebrahimi smaller. */
7038*22dc650dSSadaf Ebrahimi
7039*22dc650dSSadaf Ebrahimi mb->heap_limit = ((mcontext->heap_limit < re->limit_heap)?
7040*22dc650dSSadaf Ebrahimi mcontext->heap_limit : re->limit_heap);
7041*22dc650dSSadaf Ebrahimi
7042*22dc650dSSadaf Ebrahimi mb->match_limit = (mcontext->match_limit < re->limit_match)?
7043*22dc650dSSadaf Ebrahimi mcontext->match_limit : re->limit_match;
7044*22dc650dSSadaf Ebrahimi
7045*22dc650dSSadaf Ebrahimi mb->match_limit_depth = (mcontext->depth_limit < re->limit_depth)?
7046*22dc650dSSadaf Ebrahimi mcontext->depth_limit : re->limit_depth;
7047*22dc650dSSadaf Ebrahimi
7048*22dc650dSSadaf Ebrahimi /* If a pattern has very many capturing parentheses, the frame size may be very
7049*22dc650dSSadaf Ebrahimi large. Set the initial frame vector size to ensure that there are at least 10
7050*22dc650dSSadaf Ebrahimi available frames, but enforce a minimum of START_FRAMES_SIZE. If this is
7051*22dc650dSSadaf Ebrahimi greater than the heap limit, get as large a vector as possible. */
7052*22dc650dSSadaf Ebrahimi
7053*22dc650dSSadaf Ebrahimi heapframes_size = frame_size * 10;
7054*22dc650dSSadaf Ebrahimi if (heapframes_size < START_FRAMES_SIZE) heapframes_size = START_FRAMES_SIZE;
7055*22dc650dSSadaf Ebrahimi if (heapframes_size / 1024 > mb->heap_limit)
7056*22dc650dSSadaf Ebrahimi {
7057*22dc650dSSadaf Ebrahimi PCRE2_SIZE max_size = 1024 * mb->heap_limit;
7058*22dc650dSSadaf Ebrahimi if (max_size < frame_size) return PCRE2_ERROR_HEAPLIMIT;
7059*22dc650dSSadaf Ebrahimi heapframes_size = max_size;
7060*22dc650dSSadaf Ebrahimi }
7061*22dc650dSSadaf Ebrahimi
7062*22dc650dSSadaf Ebrahimi /* If an existing frame vector in the match_data block is large enough, we can
7063*22dc650dSSadaf Ebrahimi use it. Otherwise, free any pre-existing vector and get a new one. */
7064*22dc650dSSadaf Ebrahimi
7065*22dc650dSSadaf Ebrahimi if (match_data->heapframes_size < heapframes_size)
7066*22dc650dSSadaf Ebrahimi {
7067*22dc650dSSadaf Ebrahimi match_data->memctl.free(match_data->heapframes,
7068*22dc650dSSadaf Ebrahimi match_data->memctl.memory_data);
7069*22dc650dSSadaf Ebrahimi match_data->heapframes = match_data->memctl.malloc(heapframes_size,
7070*22dc650dSSadaf Ebrahimi match_data->memctl.memory_data);
7071*22dc650dSSadaf Ebrahimi if (match_data->heapframes == NULL)
7072*22dc650dSSadaf Ebrahimi {
7073*22dc650dSSadaf Ebrahimi match_data->heapframes_size = 0;
7074*22dc650dSSadaf Ebrahimi return PCRE2_ERROR_NOMEMORY;
7075*22dc650dSSadaf Ebrahimi }
7076*22dc650dSSadaf Ebrahimi match_data->heapframes_size = heapframes_size;
7077*22dc650dSSadaf Ebrahimi }
7078*22dc650dSSadaf Ebrahimi
7079*22dc650dSSadaf Ebrahimi /* Write to the ovector within the first frame to mark every capture unset and
7080*22dc650dSSadaf Ebrahimi to avoid uninitialized memory read errors when it is copied to a new frame. */
7081*22dc650dSSadaf Ebrahimi
7082*22dc650dSSadaf Ebrahimi memset((char *)(match_data->heapframes) + offsetof(heapframe, ovector), 0xff,
7083*22dc650dSSadaf Ebrahimi frame_size - offsetof(heapframe, ovector));
7084*22dc650dSSadaf Ebrahimi
7085*22dc650dSSadaf Ebrahimi /* Pointers to the individual character tables */
7086*22dc650dSSadaf Ebrahimi
7087*22dc650dSSadaf Ebrahimi mb->lcc = re->tables + lcc_offset;
7088*22dc650dSSadaf Ebrahimi mb->fcc = re->tables + fcc_offset;
7089*22dc650dSSadaf Ebrahimi mb->ctypes = re->tables + ctypes_offset;
7090*22dc650dSSadaf Ebrahimi
7091*22dc650dSSadaf Ebrahimi /* Set up the first code unit to match, if available. If there's no first code
7092*22dc650dSSadaf Ebrahimi unit there may be a bitmap of possible first characters. */
7093*22dc650dSSadaf Ebrahimi
7094*22dc650dSSadaf Ebrahimi if ((re->flags & PCRE2_FIRSTSET) != 0)
7095*22dc650dSSadaf Ebrahimi {
7096*22dc650dSSadaf Ebrahimi has_first_cu = TRUE;
7097*22dc650dSSadaf Ebrahimi first_cu = first_cu2 = (PCRE2_UCHAR)(re->first_codeunit);
7098*22dc650dSSadaf Ebrahimi if ((re->flags & PCRE2_FIRSTCASELESS) != 0)
7099*22dc650dSSadaf Ebrahimi {
7100*22dc650dSSadaf Ebrahimi first_cu2 = TABLE_GET(first_cu, mb->fcc, first_cu);
7101*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_UNICODE
7102*22dc650dSSadaf Ebrahimi #if PCRE2_CODE_UNIT_WIDTH == 8
7103*22dc650dSSadaf Ebrahimi if (first_cu > 127 && ucp && !utf) first_cu2 = UCD_OTHERCASE(first_cu);
7104*22dc650dSSadaf Ebrahimi #else
7105*22dc650dSSadaf Ebrahimi if (first_cu > 127 && (utf || ucp)) first_cu2 = UCD_OTHERCASE(first_cu);
7106*22dc650dSSadaf Ebrahimi #endif
7107*22dc650dSSadaf Ebrahimi #endif /* SUPPORT_UNICODE */
7108*22dc650dSSadaf Ebrahimi }
7109*22dc650dSSadaf Ebrahimi }
7110*22dc650dSSadaf Ebrahimi else
7111*22dc650dSSadaf Ebrahimi if (!startline && (re->flags & PCRE2_FIRSTMAPSET) != 0)
7112*22dc650dSSadaf Ebrahimi start_bits = re->start_bitmap;
7113*22dc650dSSadaf Ebrahimi
7114*22dc650dSSadaf Ebrahimi /* There may also be a "last known required character" set. */
7115*22dc650dSSadaf Ebrahimi
7116*22dc650dSSadaf Ebrahimi if ((re->flags & PCRE2_LASTSET) != 0)
7117*22dc650dSSadaf Ebrahimi {
7118*22dc650dSSadaf Ebrahimi has_req_cu = TRUE;
7119*22dc650dSSadaf Ebrahimi req_cu = req_cu2 = (PCRE2_UCHAR)(re->last_codeunit);
7120*22dc650dSSadaf Ebrahimi if ((re->flags & PCRE2_LASTCASELESS) != 0)
7121*22dc650dSSadaf Ebrahimi {
7122*22dc650dSSadaf Ebrahimi req_cu2 = TABLE_GET(req_cu, mb->fcc, req_cu);
7123*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_UNICODE
7124*22dc650dSSadaf Ebrahimi #if PCRE2_CODE_UNIT_WIDTH == 8
7125*22dc650dSSadaf Ebrahimi if (req_cu > 127 && ucp && !utf) req_cu2 = UCD_OTHERCASE(req_cu);
7126*22dc650dSSadaf Ebrahimi #else
7127*22dc650dSSadaf Ebrahimi if (req_cu > 127 && (utf || ucp)) req_cu2 = UCD_OTHERCASE(req_cu);
7128*22dc650dSSadaf Ebrahimi #endif
7129*22dc650dSSadaf Ebrahimi #endif /* SUPPORT_UNICODE */
7130*22dc650dSSadaf Ebrahimi }
7131*22dc650dSSadaf Ebrahimi }
7132*22dc650dSSadaf Ebrahimi
7133*22dc650dSSadaf Ebrahimi
7134*22dc650dSSadaf Ebrahimi /* ==========================================================================*/
7135*22dc650dSSadaf Ebrahimi
7136*22dc650dSSadaf Ebrahimi /* Loop for handling unanchored repeated matching attempts; for anchored regexs
7137*22dc650dSSadaf Ebrahimi the loop runs just once. */
7138*22dc650dSSadaf Ebrahimi
7139*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_UNICODE
7140*22dc650dSSadaf Ebrahimi FRAGMENT_RESTART:
7141*22dc650dSSadaf Ebrahimi #endif
7142*22dc650dSSadaf Ebrahimi
7143*22dc650dSSadaf Ebrahimi start_partial = match_partial = NULL;
7144*22dc650dSSadaf Ebrahimi mb->hitend = FALSE;
7145*22dc650dSSadaf Ebrahimi
7146*22dc650dSSadaf Ebrahimi #if PCRE2_CODE_UNIT_WIDTH == 8
7147*22dc650dSSadaf Ebrahimi memchr_found_first_cu = NULL;
7148*22dc650dSSadaf Ebrahimi memchr_found_first_cu2 = NULL;
7149*22dc650dSSadaf Ebrahimi #endif
7150*22dc650dSSadaf Ebrahimi
7151*22dc650dSSadaf Ebrahimi for(;;)
7152*22dc650dSSadaf Ebrahimi {
7153*22dc650dSSadaf Ebrahimi PCRE2_SPTR new_start_match;
7154*22dc650dSSadaf Ebrahimi
7155*22dc650dSSadaf Ebrahimi /* ----------------- Start of match optimizations ---------------- */
7156*22dc650dSSadaf Ebrahimi
7157*22dc650dSSadaf Ebrahimi /* There are some optimizations that avoid running the match if a known
7158*22dc650dSSadaf Ebrahimi starting point is not found, or if a known later code unit is not present.
7159*22dc650dSSadaf Ebrahimi However, there is an option (settable at compile time) that disables these,
7160*22dc650dSSadaf Ebrahimi for testing and for ensuring that all callouts do actually occur. */
7161*22dc650dSSadaf Ebrahimi
7162*22dc650dSSadaf Ebrahimi if ((re->overall_options & PCRE2_NO_START_OPTIMIZE) == 0)
7163*22dc650dSSadaf Ebrahimi {
7164*22dc650dSSadaf Ebrahimi /* If firstline is TRUE, the start of the match is constrained to the first
7165*22dc650dSSadaf Ebrahimi line of a multiline string. That is, the match must be before or at the
7166*22dc650dSSadaf Ebrahimi first newline following the start of matching. Temporarily adjust
7167*22dc650dSSadaf Ebrahimi end_subject so that we stop the scans for a first code unit at a newline.
7168*22dc650dSSadaf Ebrahimi If the match fails at the newline, later code breaks the loop. */
7169*22dc650dSSadaf Ebrahimi
7170*22dc650dSSadaf Ebrahimi if (firstline)
7171*22dc650dSSadaf Ebrahimi {
7172*22dc650dSSadaf Ebrahimi PCRE2_SPTR t = start_match;
7173*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_UNICODE
7174*22dc650dSSadaf Ebrahimi if (utf)
7175*22dc650dSSadaf Ebrahimi {
7176*22dc650dSSadaf Ebrahimi while (t < end_subject && !IS_NEWLINE(t))
7177*22dc650dSSadaf Ebrahimi {
7178*22dc650dSSadaf Ebrahimi t++;
7179*22dc650dSSadaf Ebrahimi ACROSSCHAR(t < end_subject, t, t++);
7180*22dc650dSSadaf Ebrahimi }
7181*22dc650dSSadaf Ebrahimi }
7182*22dc650dSSadaf Ebrahimi else
7183*22dc650dSSadaf Ebrahimi #endif
7184*22dc650dSSadaf Ebrahimi while (t < end_subject && !IS_NEWLINE(t)) t++;
7185*22dc650dSSadaf Ebrahimi end_subject = t;
7186*22dc650dSSadaf Ebrahimi }
7187*22dc650dSSadaf Ebrahimi
7188*22dc650dSSadaf Ebrahimi /* Anchored: check the first code unit if one is recorded. This may seem
7189*22dc650dSSadaf Ebrahimi pointless but it can help in detecting a no match case without scanning for
7190*22dc650dSSadaf Ebrahimi the required code unit. */
7191*22dc650dSSadaf Ebrahimi
7192*22dc650dSSadaf Ebrahimi if (anchored)
7193*22dc650dSSadaf Ebrahimi {
7194*22dc650dSSadaf Ebrahimi if (has_first_cu || start_bits != NULL)
7195*22dc650dSSadaf Ebrahimi {
7196*22dc650dSSadaf Ebrahimi BOOL ok = start_match < end_subject;
7197*22dc650dSSadaf Ebrahimi if (ok)
7198*22dc650dSSadaf Ebrahimi {
7199*22dc650dSSadaf Ebrahimi PCRE2_UCHAR c = UCHAR21TEST(start_match);
7200*22dc650dSSadaf Ebrahimi ok = has_first_cu && (c == first_cu || c == first_cu2);
7201*22dc650dSSadaf Ebrahimi if (!ok && start_bits != NULL)
7202*22dc650dSSadaf Ebrahimi {
7203*22dc650dSSadaf Ebrahimi #if PCRE2_CODE_UNIT_WIDTH != 8
7204*22dc650dSSadaf Ebrahimi if (c > 255) c = 255;
7205*22dc650dSSadaf Ebrahimi #endif
7206*22dc650dSSadaf Ebrahimi ok = (start_bits[c/8] & (1u << (c&7))) != 0;
7207*22dc650dSSadaf Ebrahimi }
7208*22dc650dSSadaf Ebrahimi }
7209*22dc650dSSadaf Ebrahimi if (!ok)
7210*22dc650dSSadaf Ebrahimi {
7211*22dc650dSSadaf Ebrahimi rc = MATCH_NOMATCH;
7212*22dc650dSSadaf Ebrahimi break;
7213*22dc650dSSadaf Ebrahimi }
7214*22dc650dSSadaf Ebrahimi }
7215*22dc650dSSadaf Ebrahimi }
7216*22dc650dSSadaf Ebrahimi
7217*22dc650dSSadaf Ebrahimi /* Not anchored. Advance to a unique first code unit if there is one. */
7218*22dc650dSSadaf Ebrahimi
7219*22dc650dSSadaf Ebrahimi else
7220*22dc650dSSadaf Ebrahimi {
7221*22dc650dSSadaf Ebrahimi if (has_first_cu)
7222*22dc650dSSadaf Ebrahimi {
7223*22dc650dSSadaf Ebrahimi if (first_cu != first_cu2) /* Caseless */
7224*22dc650dSSadaf Ebrahimi {
7225*22dc650dSSadaf Ebrahimi /* In 16-bit and 32_bit modes we have to do our own search, so can
7226*22dc650dSSadaf Ebrahimi look for both cases at once. */
7227*22dc650dSSadaf Ebrahimi
7228*22dc650dSSadaf Ebrahimi #if PCRE2_CODE_UNIT_WIDTH != 8
7229*22dc650dSSadaf Ebrahimi PCRE2_UCHAR smc;
7230*22dc650dSSadaf Ebrahimi while (start_match < end_subject &&
7231*22dc650dSSadaf Ebrahimi (smc = UCHAR21TEST(start_match)) != first_cu &&
7232*22dc650dSSadaf Ebrahimi smc != first_cu2)
7233*22dc650dSSadaf Ebrahimi start_match++;
7234*22dc650dSSadaf Ebrahimi #else
7235*22dc650dSSadaf Ebrahimi /* In 8-bit mode, the use of memchr() gives a big speed up, even
7236*22dc650dSSadaf Ebrahimi though we have to call it twice in order to find the earliest
7237*22dc650dSSadaf Ebrahimi occurrence of the code unit in either of its cases. Caching is used
7238*22dc650dSSadaf Ebrahimi to remember the positions of previously found code units. This can
7239*22dc650dSSadaf Ebrahimi make a huge difference when the strings are very long and only one
7240*22dc650dSSadaf Ebrahimi case is actually present. */
7241*22dc650dSSadaf Ebrahimi
7242*22dc650dSSadaf Ebrahimi PCRE2_SPTR pp1 = NULL;
7243*22dc650dSSadaf Ebrahimi PCRE2_SPTR pp2 = NULL;
7244*22dc650dSSadaf Ebrahimi PCRE2_SIZE searchlength = end_subject - start_match;
7245*22dc650dSSadaf Ebrahimi
7246*22dc650dSSadaf Ebrahimi /* If we haven't got a previously found position for first_cu, or if
7247*22dc650dSSadaf Ebrahimi the current starting position is later, we need to do a search. If
7248*22dc650dSSadaf Ebrahimi the code unit is not found, set it to the end. */
7249*22dc650dSSadaf Ebrahimi
7250*22dc650dSSadaf Ebrahimi if (memchr_found_first_cu == NULL ||
7251*22dc650dSSadaf Ebrahimi start_match > memchr_found_first_cu)
7252*22dc650dSSadaf Ebrahimi {
7253*22dc650dSSadaf Ebrahimi pp1 = memchr(start_match, first_cu, searchlength);
7254*22dc650dSSadaf Ebrahimi memchr_found_first_cu = (pp1 == NULL)? end_subject : pp1;
7255*22dc650dSSadaf Ebrahimi }
7256*22dc650dSSadaf Ebrahimi
7257*22dc650dSSadaf Ebrahimi /* If the start is before a previously found position, use the
7258*22dc650dSSadaf Ebrahimi previous position, or NULL if a previous search failed. */
7259*22dc650dSSadaf Ebrahimi
7260*22dc650dSSadaf Ebrahimi else pp1 = (memchr_found_first_cu == end_subject)? NULL :
7261*22dc650dSSadaf Ebrahimi memchr_found_first_cu;
7262*22dc650dSSadaf Ebrahimi
7263*22dc650dSSadaf Ebrahimi /* Do the same thing for the other case. */
7264*22dc650dSSadaf Ebrahimi
7265*22dc650dSSadaf Ebrahimi if (memchr_found_first_cu2 == NULL ||
7266*22dc650dSSadaf Ebrahimi start_match > memchr_found_first_cu2)
7267*22dc650dSSadaf Ebrahimi {
7268*22dc650dSSadaf Ebrahimi pp2 = memchr(start_match, first_cu2, searchlength);
7269*22dc650dSSadaf Ebrahimi memchr_found_first_cu2 = (pp2 == NULL)? end_subject : pp2;
7270*22dc650dSSadaf Ebrahimi }
7271*22dc650dSSadaf Ebrahimi
7272*22dc650dSSadaf Ebrahimi else pp2 = (memchr_found_first_cu2 == end_subject)? NULL :
7273*22dc650dSSadaf Ebrahimi memchr_found_first_cu2;
7274*22dc650dSSadaf Ebrahimi
7275*22dc650dSSadaf Ebrahimi /* Set the start to the end of the subject if neither case was found.
7276*22dc650dSSadaf Ebrahimi Otherwise, use the earlier found point. */
7277*22dc650dSSadaf Ebrahimi
7278*22dc650dSSadaf Ebrahimi if (pp1 == NULL)
7279*22dc650dSSadaf Ebrahimi start_match = (pp2 == NULL)? end_subject : pp2;
7280*22dc650dSSadaf Ebrahimi else
7281*22dc650dSSadaf Ebrahimi start_match = (pp2 == NULL || pp1 < pp2)? pp1 : pp2;
7282*22dc650dSSadaf Ebrahimi
7283*22dc650dSSadaf Ebrahimi #endif /* 8-bit handling */
7284*22dc650dSSadaf Ebrahimi }
7285*22dc650dSSadaf Ebrahimi
7286*22dc650dSSadaf Ebrahimi /* The caseful case is much simpler. */
7287*22dc650dSSadaf Ebrahimi
7288*22dc650dSSadaf Ebrahimi else
7289*22dc650dSSadaf Ebrahimi {
7290*22dc650dSSadaf Ebrahimi #if PCRE2_CODE_UNIT_WIDTH != 8
7291*22dc650dSSadaf Ebrahimi while (start_match < end_subject && UCHAR21TEST(start_match) !=
7292*22dc650dSSadaf Ebrahimi first_cu)
7293*22dc650dSSadaf Ebrahimi start_match++;
7294*22dc650dSSadaf Ebrahimi #else
7295*22dc650dSSadaf Ebrahimi start_match = memchr(start_match, first_cu, end_subject - start_match);
7296*22dc650dSSadaf Ebrahimi if (start_match == NULL) start_match = end_subject;
7297*22dc650dSSadaf Ebrahimi #endif
7298*22dc650dSSadaf Ebrahimi }
7299*22dc650dSSadaf Ebrahimi
7300*22dc650dSSadaf Ebrahimi /* If we can't find the required first code unit, having reached the
7301*22dc650dSSadaf Ebrahimi true end of the subject, break the bumpalong loop, to force a match
7302*22dc650dSSadaf Ebrahimi failure, except when doing partial matching, when we let the next cycle
7303*22dc650dSSadaf Ebrahimi run at the end of the subject. To see why, consider the pattern
7304*22dc650dSSadaf Ebrahimi /(?<=abc)def/, which partially matches "abc", even though the string
7305*22dc650dSSadaf Ebrahimi does not contain the starting character "d". If we have not reached the
7306*22dc650dSSadaf Ebrahimi true end of the subject (PCRE2_FIRSTLINE caused end_subject to be
7307*22dc650dSSadaf Ebrahimi temporarily modified) we also let the cycle run, because the matching
7308*22dc650dSSadaf Ebrahimi string is legitimately allowed to start with the first code unit of a
7309*22dc650dSSadaf Ebrahimi newline. */
7310*22dc650dSSadaf Ebrahimi
7311*22dc650dSSadaf Ebrahimi if (mb->partial == 0 && start_match >= mb->end_subject)
7312*22dc650dSSadaf Ebrahimi {
7313*22dc650dSSadaf Ebrahimi rc = MATCH_NOMATCH;
7314*22dc650dSSadaf Ebrahimi break;
7315*22dc650dSSadaf Ebrahimi }
7316*22dc650dSSadaf Ebrahimi }
7317*22dc650dSSadaf Ebrahimi
7318*22dc650dSSadaf Ebrahimi /* If there's no first code unit, advance to just after a linebreak for a
7319*22dc650dSSadaf Ebrahimi multiline match if required. */
7320*22dc650dSSadaf Ebrahimi
7321*22dc650dSSadaf Ebrahimi else if (startline)
7322*22dc650dSSadaf Ebrahimi {
7323*22dc650dSSadaf Ebrahimi if (start_match > mb->start_subject + start_offset)
7324*22dc650dSSadaf Ebrahimi {
7325*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_UNICODE
7326*22dc650dSSadaf Ebrahimi if (utf)
7327*22dc650dSSadaf Ebrahimi {
7328*22dc650dSSadaf Ebrahimi while (start_match < end_subject && !WAS_NEWLINE(start_match))
7329*22dc650dSSadaf Ebrahimi {
7330*22dc650dSSadaf Ebrahimi start_match++;
7331*22dc650dSSadaf Ebrahimi ACROSSCHAR(start_match < end_subject, start_match, start_match++);
7332*22dc650dSSadaf Ebrahimi }
7333*22dc650dSSadaf Ebrahimi }
7334*22dc650dSSadaf Ebrahimi else
7335*22dc650dSSadaf Ebrahimi #endif
7336*22dc650dSSadaf Ebrahimi while (start_match < end_subject && !WAS_NEWLINE(start_match))
7337*22dc650dSSadaf Ebrahimi start_match++;
7338*22dc650dSSadaf Ebrahimi
7339*22dc650dSSadaf Ebrahimi /* If we have just passed a CR and the newline option is ANY or
7340*22dc650dSSadaf Ebrahimi ANYCRLF, and we are now at a LF, advance the match position by one
7341*22dc650dSSadaf Ebrahimi more code unit. */
7342*22dc650dSSadaf Ebrahimi
7343*22dc650dSSadaf Ebrahimi if (start_match[-1] == CHAR_CR &&
7344*22dc650dSSadaf Ebrahimi (mb->nltype == NLTYPE_ANY || mb->nltype == NLTYPE_ANYCRLF) &&
7345*22dc650dSSadaf Ebrahimi start_match < end_subject &&
7346*22dc650dSSadaf Ebrahimi UCHAR21TEST(start_match) == CHAR_NL)
7347*22dc650dSSadaf Ebrahimi start_match++;
7348*22dc650dSSadaf Ebrahimi }
7349*22dc650dSSadaf Ebrahimi }
7350*22dc650dSSadaf Ebrahimi
7351*22dc650dSSadaf Ebrahimi /* If there's no first code unit or a requirement for a multiline line
7352*22dc650dSSadaf Ebrahimi start, advance to a non-unique first code unit if any have been
7353*22dc650dSSadaf Ebrahimi identified. The bitmap contains only 256 bits. When code units are 16 or
7354*22dc650dSSadaf Ebrahimi 32 bits wide, all code units greater than 254 set the 255 bit. */
7355*22dc650dSSadaf Ebrahimi
7356*22dc650dSSadaf Ebrahimi else if (start_bits != NULL)
7357*22dc650dSSadaf Ebrahimi {
7358*22dc650dSSadaf Ebrahimi while (start_match < end_subject)
7359*22dc650dSSadaf Ebrahimi {
7360*22dc650dSSadaf Ebrahimi uint32_t c = UCHAR21TEST(start_match);
7361*22dc650dSSadaf Ebrahimi #if PCRE2_CODE_UNIT_WIDTH != 8
7362*22dc650dSSadaf Ebrahimi if (c > 255) c = 255;
7363*22dc650dSSadaf Ebrahimi #endif
7364*22dc650dSSadaf Ebrahimi if ((start_bits[c/8] & (1u << (c&7))) != 0) break;
7365*22dc650dSSadaf Ebrahimi start_match++;
7366*22dc650dSSadaf Ebrahimi }
7367*22dc650dSSadaf Ebrahimi
7368*22dc650dSSadaf Ebrahimi /* See comment above in first_cu checking about the next few lines. */
7369*22dc650dSSadaf Ebrahimi
7370*22dc650dSSadaf Ebrahimi if (mb->partial == 0 && start_match >= mb->end_subject)
7371*22dc650dSSadaf Ebrahimi {
7372*22dc650dSSadaf Ebrahimi rc = MATCH_NOMATCH;
7373*22dc650dSSadaf Ebrahimi break;
7374*22dc650dSSadaf Ebrahimi }
7375*22dc650dSSadaf Ebrahimi }
7376*22dc650dSSadaf Ebrahimi } /* End first code unit handling */
7377*22dc650dSSadaf Ebrahimi
7378*22dc650dSSadaf Ebrahimi /* Restore fudged end_subject */
7379*22dc650dSSadaf Ebrahimi
7380*22dc650dSSadaf Ebrahimi end_subject = mb->end_subject;
7381*22dc650dSSadaf Ebrahimi
7382*22dc650dSSadaf Ebrahimi /* The following two optimizations must be disabled for partial matching. */
7383*22dc650dSSadaf Ebrahimi
7384*22dc650dSSadaf Ebrahimi if (mb->partial == 0)
7385*22dc650dSSadaf Ebrahimi {
7386*22dc650dSSadaf Ebrahimi PCRE2_SPTR p;
7387*22dc650dSSadaf Ebrahimi
7388*22dc650dSSadaf Ebrahimi /* The minimum matching length is a lower bound; no string of that length
7389*22dc650dSSadaf Ebrahimi may actually match the pattern. Although the value is, strictly, in
7390*22dc650dSSadaf Ebrahimi characters, we treat it as code units to avoid spending too much time in
7391*22dc650dSSadaf Ebrahimi this optimization. */
7392*22dc650dSSadaf Ebrahimi
7393*22dc650dSSadaf Ebrahimi if (end_subject - start_match < re->minlength)
7394*22dc650dSSadaf Ebrahimi {
7395*22dc650dSSadaf Ebrahimi rc = MATCH_NOMATCH;
7396*22dc650dSSadaf Ebrahimi break;
7397*22dc650dSSadaf Ebrahimi }
7398*22dc650dSSadaf Ebrahimi
7399*22dc650dSSadaf Ebrahimi /* If req_cu is set, we know that that code unit must appear in the
7400*22dc650dSSadaf Ebrahimi subject for the (non-partial) match to succeed. If the first code unit is
7401*22dc650dSSadaf Ebrahimi set, req_cu must be later in the subject; otherwise the test starts at
7402*22dc650dSSadaf Ebrahimi the match point. This optimization can save a huge amount of backtracking
7403*22dc650dSSadaf Ebrahimi in patterns with nested unlimited repeats that aren't going to match.
7404*22dc650dSSadaf Ebrahimi Writing separate code for caseful/caseless versions makes it go faster,
7405*22dc650dSSadaf Ebrahimi as does using an autoincrement and backing off on a match. As in the case
7406*22dc650dSSadaf Ebrahimi of the first code unit, using memchr() in the 8-bit library gives a big
7407*22dc650dSSadaf Ebrahimi speed up. Unlike the first_cu check above, we do not need to call
7408*22dc650dSSadaf Ebrahimi memchr() twice in the caseless case because we only need to check for the
7409*22dc650dSSadaf Ebrahimi presence of the character in either case, not find the first occurrence.
7410*22dc650dSSadaf Ebrahimi
7411*22dc650dSSadaf Ebrahimi The search can be skipped if the code unit was found later than the
7412*22dc650dSSadaf Ebrahimi current starting point in a previous iteration of the bumpalong loop.
7413*22dc650dSSadaf Ebrahimi
7414*22dc650dSSadaf Ebrahimi HOWEVER: when the subject string is very, very long, searching to its end
7415*22dc650dSSadaf Ebrahimi can take a long time, and give bad performance on quite ordinary
7416*22dc650dSSadaf Ebrahimi anchored patterns. This showed up when somebody was matching something
7417*22dc650dSSadaf Ebrahimi like /^\d+C/ on a 32-megabyte string... so we don't do this when the
7418*22dc650dSSadaf Ebrahimi string is sufficiently long, but it's worth searching a lot more for
7419*22dc650dSSadaf Ebrahimi unanchored patterns. */
7420*22dc650dSSadaf Ebrahimi
7421*22dc650dSSadaf Ebrahimi p = start_match + (has_first_cu? 1:0);
7422*22dc650dSSadaf Ebrahimi if (has_req_cu && p > req_cu_ptr)
7423*22dc650dSSadaf Ebrahimi {
7424*22dc650dSSadaf Ebrahimi PCRE2_SIZE check_length = end_subject - start_match;
7425*22dc650dSSadaf Ebrahimi
7426*22dc650dSSadaf Ebrahimi if (check_length < REQ_CU_MAX ||
7427*22dc650dSSadaf Ebrahimi (!anchored && check_length < REQ_CU_MAX * 1000))
7428*22dc650dSSadaf Ebrahimi {
7429*22dc650dSSadaf Ebrahimi if (req_cu != req_cu2) /* Caseless */
7430*22dc650dSSadaf Ebrahimi {
7431*22dc650dSSadaf Ebrahimi #if PCRE2_CODE_UNIT_WIDTH != 8
7432*22dc650dSSadaf Ebrahimi while (p < end_subject)
7433*22dc650dSSadaf Ebrahimi {
7434*22dc650dSSadaf Ebrahimi uint32_t pp = UCHAR21INCTEST(p);
7435*22dc650dSSadaf Ebrahimi if (pp == req_cu || pp == req_cu2) { p--; break; }
7436*22dc650dSSadaf Ebrahimi }
7437*22dc650dSSadaf Ebrahimi #else /* 8-bit code units */
7438*22dc650dSSadaf Ebrahimi PCRE2_SPTR pp = p;
7439*22dc650dSSadaf Ebrahimi p = memchr(pp, req_cu, end_subject - pp);
7440*22dc650dSSadaf Ebrahimi if (p == NULL)
7441*22dc650dSSadaf Ebrahimi {
7442*22dc650dSSadaf Ebrahimi p = memchr(pp, req_cu2, end_subject - pp);
7443*22dc650dSSadaf Ebrahimi if (p == NULL) p = end_subject;
7444*22dc650dSSadaf Ebrahimi }
7445*22dc650dSSadaf Ebrahimi #endif /* PCRE2_CODE_UNIT_WIDTH != 8 */
7446*22dc650dSSadaf Ebrahimi }
7447*22dc650dSSadaf Ebrahimi
7448*22dc650dSSadaf Ebrahimi /* The caseful case */
7449*22dc650dSSadaf Ebrahimi
7450*22dc650dSSadaf Ebrahimi else
7451*22dc650dSSadaf Ebrahimi {
7452*22dc650dSSadaf Ebrahimi #if PCRE2_CODE_UNIT_WIDTH != 8
7453*22dc650dSSadaf Ebrahimi while (p < end_subject)
7454*22dc650dSSadaf Ebrahimi {
7455*22dc650dSSadaf Ebrahimi if (UCHAR21INCTEST(p) == req_cu) { p--; break; }
7456*22dc650dSSadaf Ebrahimi }
7457*22dc650dSSadaf Ebrahimi
7458*22dc650dSSadaf Ebrahimi #else /* 8-bit code units */
7459*22dc650dSSadaf Ebrahimi p = memchr(p, req_cu, end_subject - p);
7460*22dc650dSSadaf Ebrahimi if (p == NULL) p = end_subject;
7461*22dc650dSSadaf Ebrahimi #endif
7462*22dc650dSSadaf Ebrahimi }
7463*22dc650dSSadaf Ebrahimi
7464*22dc650dSSadaf Ebrahimi /* If we can't find the required code unit, break the bumpalong loop,
7465*22dc650dSSadaf Ebrahimi forcing a match failure. */
7466*22dc650dSSadaf Ebrahimi
7467*22dc650dSSadaf Ebrahimi if (p >= end_subject)
7468*22dc650dSSadaf Ebrahimi {
7469*22dc650dSSadaf Ebrahimi rc = MATCH_NOMATCH;
7470*22dc650dSSadaf Ebrahimi break;
7471*22dc650dSSadaf Ebrahimi }
7472*22dc650dSSadaf Ebrahimi
7473*22dc650dSSadaf Ebrahimi /* If we have found the required code unit, save the point where we
7474*22dc650dSSadaf Ebrahimi found it, so that we don't search again next time round the bumpalong
7475*22dc650dSSadaf Ebrahimi loop if the start hasn't yet passed this code unit. */
7476*22dc650dSSadaf Ebrahimi
7477*22dc650dSSadaf Ebrahimi req_cu_ptr = p;
7478*22dc650dSSadaf Ebrahimi }
7479*22dc650dSSadaf Ebrahimi }
7480*22dc650dSSadaf Ebrahimi }
7481*22dc650dSSadaf Ebrahimi }
7482*22dc650dSSadaf Ebrahimi
7483*22dc650dSSadaf Ebrahimi /* ------------ End of start of match optimizations ------------ */
7484*22dc650dSSadaf Ebrahimi
7485*22dc650dSSadaf Ebrahimi /* Give no match if we have passed the bumpalong limit. */
7486*22dc650dSSadaf Ebrahimi
7487*22dc650dSSadaf Ebrahimi if (start_match > bumpalong_limit)
7488*22dc650dSSadaf Ebrahimi {
7489*22dc650dSSadaf Ebrahimi rc = MATCH_NOMATCH;
7490*22dc650dSSadaf Ebrahimi break;
7491*22dc650dSSadaf Ebrahimi }
7492*22dc650dSSadaf Ebrahimi
7493*22dc650dSSadaf Ebrahimi /* OK, we can now run the match. If "hitend" is set afterwards, remember the
7494*22dc650dSSadaf Ebrahimi first starting point for which a partial match was found. */
7495*22dc650dSSadaf Ebrahimi
7496*22dc650dSSadaf Ebrahimi cb.start_match = (PCRE2_SIZE)(start_match - subject);
7497*22dc650dSSadaf Ebrahimi cb.callout_flags |= PCRE2_CALLOUT_STARTMATCH;
7498*22dc650dSSadaf Ebrahimi
7499*22dc650dSSadaf Ebrahimi mb->start_used_ptr = start_match;
7500*22dc650dSSadaf Ebrahimi mb->last_used_ptr = start_match;
7501*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_UNICODE
7502*22dc650dSSadaf Ebrahimi mb->moptions = options | fragment_options;
7503*22dc650dSSadaf Ebrahimi #else
7504*22dc650dSSadaf Ebrahimi mb->moptions = options;
7505*22dc650dSSadaf Ebrahimi #endif
7506*22dc650dSSadaf Ebrahimi mb->match_call_count = 0;
7507*22dc650dSSadaf Ebrahimi mb->end_offset_top = 0;
7508*22dc650dSSadaf Ebrahimi mb->skip_arg_count = 0;
7509*22dc650dSSadaf Ebrahimi
7510*22dc650dSSadaf Ebrahimi #ifdef DEBUG_SHOW_OPS
7511*22dc650dSSadaf Ebrahimi fprintf(stderr, "++ Calling match()\n");
7512*22dc650dSSadaf Ebrahimi #endif
7513*22dc650dSSadaf Ebrahimi
7514*22dc650dSSadaf Ebrahimi rc = match(start_match, mb->start_code, re->top_bracket, frame_size,
7515*22dc650dSSadaf Ebrahimi match_data, mb);
7516*22dc650dSSadaf Ebrahimi
7517*22dc650dSSadaf Ebrahimi #ifdef DEBUG_SHOW_OPS
7518*22dc650dSSadaf Ebrahimi fprintf(stderr, "++ match() returned %d\n\n", rc);
7519*22dc650dSSadaf Ebrahimi #endif
7520*22dc650dSSadaf Ebrahimi
7521*22dc650dSSadaf Ebrahimi if (mb->hitend && start_partial == NULL)
7522*22dc650dSSadaf Ebrahimi {
7523*22dc650dSSadaf Ebrahimi start_partial = mb->start_used_ptr;
7524*22dc650dSSadaf Ebrahimi match_partial = start_match;
7525*22dc650dSSadaf Ebrahimi }
7526*22dc650dSSadaf Ebrahimi
7527*22dc650dSSadaf Ebrahimi switch(rc)
7528*22dc650dSSadaf Ebrahimi {
7529*22dc650dSSadaf Ebrahimi /* If MATCH_SKIP_ARG reaches this level it means that a MARK that matched
7530*22dc650dSSadaf Ebrahimi the SKIP's arg was not found. In this circumstance, Perl ignores the SKIP
7531*22dc650dSSadaf Ebrahimi entirely. The only way we can do that is to re-do the match at the same
7532*22dc650dSSadaf Ebrahimi point, with a flag to force SKIP with an argument to be ignored. Just
7533*22dc650dSSadaf Ebrahimi treating this case as NOMATCH does not work because it does not check other
7534*22dc650dSSadaf Ebrahimi alternatives in patterns such as A(*SKIP:A)B|AC when the subject is AC. */
7535*22dc650dSSadaf Ebrahimi
7536*22dc650dSSadaf Ebrahimi case MATCH_SKIP_ARG:
7537*22dc650dSSadaf Ebrahimi new_start_match = start_match;
7538*22dc650dSSadaf Ebrahimi mb->ignore_skip_arg = mb->skip_arg_count;
7539*22dc650dSSadaf Ebrahimi break;
7540*22dc650dSSadaf Ebrahimi
7541*22dc650dSSadaf Ebrahimi /* SKIP passes back the next starting point explicitly, but if it is no
7542*22dc650dSSadaf Ebrahimi greater than the match we have just done, treat it as NOMATCH. */
7543*22dc650dSSadaf Ebrahimi
7544*22dc650dSSadaf Ebrahimi case MATCH_SKIP:
7545*22dc650dSSadaf Ebrahimi if (mb->verb_skip_ptr > start_match)
7546*22dc650dSSadaf Ebrahimi {
7547*22dc650dSSadaf Ebrahimi new_start_match = mb->verb_skip_ptr;
7548*22dc650dSSadaf Ebrahimi break;
7549*22dc650dSSadaf Ebrahimi }
7550*22dc650dSSadaf Ebrahimi /* Fall through */
7551*22dc650dSSadaf Ebrahimi
7552*22dc650dSSadaf Ebrahimi /* NOMATCH and PRUNE advance by one character. THEN at this level acts
7553*22dc650dSSadaf Ebrahimi exactly like PRUNE. Unset ignore SKIP-with-argument. */
7554*22dc650dSSadaf Ebrahimi
7555*22dc650dSSadaf Ebrahimi case MATCH_NOMATCH:
7556*22dc650dSSadaf Ebrahimi case MATCH_PRUNE:
7557*22dc650dSSadaf Ebrahimi case MATCH_THEN:
7558*22dc650dSSadaf Ebrahimi mb->ignore_skip_arg = 0;
7559*22dc650dSSadaf Ebrahimi new_start_match = start_match + 1;
7560*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_UNICODE
7561*22dc650dSSadaf Ebrahimi if (utf)
7562*22dc650dSSadaf Ebrahimi ACROSSCHAR(new_start_match < end_subject, new_start_match,
7563*22dc650dSSadaf Ebrahimi new_start_match++);
7564*22dc650dSSadaf Ebrahimi #endif
7565*22dc650dSSadaf Ebrahimi break;
7566*22dc650dSSadaf Ebrahimi
7567*22dc650dSSadaf Ebrahimi /* COMMIT disables the bumpalong, but otherwise behaves as NOMATCH. */
7568*22dc650dSSadaf Ebrahimi
7569*22dc650dSSadaf Ebrahimi case MATCH_COMMIT:
7570*22dc650dSSadaf Ebrahimi rc = MATCH_NOMATCH;
7571*22dc650dSSadaf Ebrahimi goto ENDLOOP;
7572*22dc650dSSadaf Ebrahimi
7573*22dc650dSSadaf Ebrahimi /* Any other return is either a match, or some kind of error. */
7574*22dc650dSSadaf Ebrahimi
7575*22dc650dSSadaf Ebrahimi default:
7576*22dc650dSSadaf Ebrahimi goto ENDLOOP;
7577*22dc650dSSadaf Ebrahimi }
7578*22dc650dSSadaf Ebrahimi
7579*22dc650dSSadaf Ebrahimi /* Control reaches here for the various types of "no match at this point"
7580*22dc650dSSadaf Ebrahimi result. Reset the code to MATCH_NOMATCH for subsequent checking. */
7581*22dc650dSSadaf Ebrahimi
7582*22dc650dSSadaf Ebrahimi rc = MATCH_NOMATCH;
7583*22dc650dSSadaf Ebrahimi
7584*22dc650dSSadaf Ebrahimi /* If PCRE2_FIRSTLINE is set, the match must happen before or at the first
7585*22dc650dSSadaf Ebrahimi newline in the subject (though it may continue over the newline). Therefore,
7586*22dc650dSSadaf Ebrahimi if we have just failed to match, starting at a newline, do not continue. */
7587*22dc650dSSadaf Ebrahimi
7588*22dc650dSSadaf Ebrahimi if (firstline && IS_NEWLINE(start_match)) break;
7589*22dc650dSSadaf Ebrahimi
7590*22dc650dSSadaf Ebrahimi /* Advance to new matching position */
7591*22dc650dSSadaf Ebrahimi
7592*22dc650dSSadaf Ebrahimi start_match = new_start_match;
7593*22dc650dSSadaf Ebrahimi
7594*22dc650dSSadaf Ebrahimi /* Break the loop if the pattern is anchored or if we have passed the end of
7595*22dc650dSSadaf Ebrahimi the subject. */
7596*22dc650dSSadaf Ebrahimi
7597*22dc650dSSadaf Ebrahimi if (anchored || start_match > end_subject) break;
7598*22dc650dSSadaf Ebrahimi
7599*22dc650dSSadaf Ebrahimi /* If we have just passed a CR and we are now at a LF, and the pattern does
7600*22dc650dSSadaf Ebrahimi not contain any explicit matches for \r or \n, and the newline option is CRLF
7601*22dc650dSSadaf Ebrahimi or ANY or ANYCRLF, advance the match position by one more code unit. In
7602*22dc650dSSadaf Ebrahimi normal matching start_match will aways be greater than the first position at
7603*22dc650dSSadaf Ebrahimi this stage, but a failed *SKIP can cause a return at the same point, which is
7604*22dc650dSSadaf Ebrahimi why the first test exists. */
7605*22dc650dSSadaf Ebrahimi
7606*22dc650dSSadaf Ebrahimi if (start_match > subject + start_offset &&
7607*22dc650dSSadaf Ebrahimi start_match[-1] == CHAR_CR &&
7608*22dc650dSSadaf Ebrahimi start_match < end_subject &&
7609*22dc650dSSadaf Ebrahimi *start_match == CHAR_NL &&
7610*22dc650dSSadaf Ebrahimi (re->flags & PCRE2_HASCRORLF) == 0 &&
7611*22dc650dSSadaf Ebrahimi (mb->nltype == NLTYPE_ANY ||
7612*22dc650dSSadaf Ebrahimi mb->nltype == NLTYPE_ANYCRLF ||
7613*22dc650dSSadaf Ebrahimi mb->nllen == 2))
7614*22dc650dSSadaf Ebrahimi start_match++;
7615*22dc650dSSadaf Ebrahimi
7616*22dc650dSSadaf Ebrahimi mb->mark = NULL; /* Reset for start of next match attempt */
7617*22dc650dSSadaf Ebrahimi } /* End of for(;;) "bumpalong" loop */
7618*22dc650dSSadaf Ebrahimi
7619*22dc650dSSadaf Ebrahimi /* ==========================================================================*/
7620*22dc650dSSadaf Ebrahimi
7621*22dc650dSSadaf Ebrahimi /* When we reach here, one of the following stopping conditions is true:
7622*22dc650dSSadaf Ebrahimi
7623*22dc650dSSadaf Ebrahimi (1) The match succeeded, either completely, or partially;
7624*22dc650dSSadaf Ebrahimi
7625*22dc650dSSadaf Ebrahimi (2) The pattern is anchored or the match was failed after (*COMMIT);
7626*22dc650dSSadaf Ebrahimi
7627*22dc650dSSadaf Ebrahimi (3) We are past the end of the subject or the bumpalong limit;
7628*22dc650dSSadaf Ebrahimi
7629*22dc650dSSadaf Ebrahimi (4) PCRE2_FIRSTLINE is set and we have failed to match at a newline, because
7630*22dc650dSSadaf Ebrahimi this option requests that a match occur at or before the first newline in
7631*22dc650dSSadaf Ebrahimi the subject.
7632*22dc650dSSadaf Ebrahimi
7633*22dc650dSSadaf Ebrahimi (5) Some kind of error occurred.
7634*22dc650dSSadaf Ebrahimi
7635*22dc650dSSadaf Ebrahimi */
7636*22dc650dSSadaf Ebrahimi
7637*22dc650dSSadaf Ebrahimi ENDLOOP:
7638*22dc650dSSadaf Ebrahimi
7639*22dc650dSSadaf Ebrahimi /* If end_subject != true_end_subject, it means we are handling invalid UTF,
7640*22dc650dSSadaf Ebrahimi and have just processed a non-terminal fragment. If this resulted in no match
7641*22dc650dSSadaf Ebrahimi or a partial match we must carry on to the next fragment (a partial match is
7642*22dc650dSSadaf Ebrahimi returned to the caller only at the very end of the subject). A loop is used to
7643*22dc650dSSadaf Ebrahimi avoid trying to match against empty fragments; if the pattern can match an
7644*22dc650dSSadaf Ebrahimi empty string it would have done so already. */
7645*22dc650dSSadaf Ebrahimi
7646*22dc650dSSadaf Ebrahimi #ifdef SUPPORT_UNICODE
7647*22dc650dSSadaf Ebrahimi if (utf && end_subject != true_end_subject &&
7648*22dc650dSSadaf Ebrahimi (rc == MATCH_NOMATCH || rc == PCRE2_ERROR_PARTIAL))
7649*22dc650dSSadaf Ebrahimi {
7650*22dc650dSSadaf Ebrahimi for (;;)
7651*22dc650dSSadaf Ebrahimi {
7652*22dc650dSSadaf Ebrahimi /* Advance past the first bad code unit, and then skip invalid character
7653*22dc650dSSadaf Ebrahimi starting code units in 8-bit and 16-bit modes. */
7654*22dc650dSSadaf Ebrahimi
7655*22dc650dSSadaf Ebrahimi start_match = end_subject + 1;
7656*22dc650dSSadaf Ebrahimi
7657*22dc650dSSadaf Ebrahimi #if PCRE2_CODE_UNIT_WIDTH != 32
7658*22dc650dSSadaf Ebrahimi while (start_match < true_end_subject && NOT_FIRSTCU(*start_match))
7659*22dc650dSSadaf Ebrahimi start_match++;
7660*22dc650dSSadaf Ebrahimi #endif
7661*22dc650dSSadaf Ebrahimi
7662*22dc650dSSadaf Ebrahimi /* If we have hit the end of the subject, there isn't another non-empty
7663*22dc650dSSadaf Ebrahimi fragment, so give up. */
7664*22dc650dSSadaf Ebrahimi
7665*22dc650dSSadaf Ebrahimi if (start_match >= true_end_subject)
7666*22dc650dSSadaf Ebrahimi {
7667*22dc650dSSadaf Ebrahimi rc = MATCH_NOMATCH; /* In case it was partial */
7668*22dc650dSSadaf Ebrahimi match_partial = NULL;
7669*22dc650dSSadaf Ebrahimi break;
7670*22dc650dSSadaf Ebrahimi }
7671*22dc650dSSadaf Ebrahimi
7672*22dc650dSSadaf Ebrahimi /* Check the rest of the subject */
7673*22dc650dSSadaf Ebrahimi
7674*22dc650dSSadaf Ebrahimi mb->check_subject = start_match;
7675*22dc650dSSadaf Ebrahimi rc = PRIV(valid_utf)(start_match, length - (start_match - subject),
7676*22dc650dSSadaf Ebrahimi &(match_data->startchar));
7677*22dc650dSSadaf Ebrahimi
7678*22dc650dSSadaf Ebrahimi /* The rest of the subject is valid UTF. */
7679*22dc650dSSadaf Ebrahimi
7680*22dc650dSSadaf Ebrahimi if (rc == 0)
7681*22dc650dSSadaf Ebrahimi {
7682*22dc650dSSadaf Ebrahimi mb->end_subject = end_subject = true_end_subject;
7683*22dc650dSSadaf Ebrahimi fragment_options = PCRE2_NOTBOL;
7684*22dc650dSSadaf Ebrahimi goto FRAGMENT_RESTART;
7685*22dc650dSSadaf Ebrahimi }
7686*22dc650dSSadaf Ebrahimi
7687*22dc650dSSadaf Ebrahimi /* A subsequent UTF error has been found; if the next fragment is
7688*22dc650dSSadaf Ebrahimi non-empty, set up to process it. Otherwise, let the loop advance. */
7689*22dc650dSSadaf Ebrahimi
7690*22dc650dSSadaf Ebrahimi else if (rc < 0)
7691*22dc650dSSadaf Ebrahimi {
7692*22dc650dSSadaf Ebrahimi mb->end_subject = end_subject = start_match + match_data->startchar;
7693*22dc650dSSadaf Ebrahimi if (end_subject > start_match)
7694*22dc650dSSadaf Ebrahimi {
7695*22dc650dSSadaf Ebrahimi fragment_options = PCRE2_NOTBOL|PCRE2_NOTEOL;
7696*22dc650dSSadaf Ebrahimi goto FRAGMENT_RESTART;
7697*22dc650dSSadaf Ebrahimi }
7698*22dc650dSSadaf Ebrahimi }
7699*22dc650dSSadaf Ebrahimi }
7700*22dc650dSSadaf Ebrahimi }
7701*22dc650dSSadaf Ebrahimi #endif /* SUPPORT_UNICODE */
7702*22dc650dSSadaf Ebrahimi
7703*22dc650dSSadaf Ebrahimi /* Fill in fields that are always returned in the match data. */
7704*22dc650dSSadaf Ebrahimi
7705*22dc650dSSadaf Ebrahimi match_data->code = re;
7706*22dc650dSSadaf Ebrahimi match_data->mark = mb->mark;
7707*22dc650dSSadaf Ebrahimi match_data->matchedby = PCRE2_MATCHEDBY_INTERPRETER;
7708*22dc650dSSadaf Ebrahimi
7709*22dc650dSSadaf Ebrahimi /* Handle a fully successful match. Set the return code to the number of
7710*22dc650dSSadaf Ebrahimi captured strings, or 0 if there were too many to fit into the ovector, and then
7711*22dc650dSSadaf Ebrahimi set the remaining returned values before returning. Make a copy of the subject
7712*22dc650dSSadaf Ebrahimi string if requested. */
7713*22dc650dSSadaf Ebrahimi
7714*22dc650dSSadaf Ebrahimi if (rc == MATCH_MATCH)
7715*22dc650dSSadaf Ebrahimi {
7716*22dc650dSSadaf Ebrahimi match_data->rc = ((int)mb->end_offset_top >= 2 * match_data->oveccount)?
7717*22dc650dSSadaf Ebrahimi 0 : (int)mb->end_offset_top/2 + 1;
7718*22dc650dSSadaf Ebrahimi match_data->subject_length = length;
7719*22dc650dSSadaf Ebrahimi match_data->startchar = start_match - subject;
7720*22dc650dSSadaf Ebrahimi match_data->leftchar = mb->start_used_ptr - subject;
7721*22dc650dSSadaf Ebrahimi match_data->rightchar = ((mb->last_used_ptr > mb->end_match_ptr)?
7722*22dc650dSSadaf Ebrahimi mb->last_used_ptr : mb->end_match_ptr) - subject;
7723*22dc650dSSadaf Ebrahimi if ((options & PCRE2_COPY_MATCHED_SUBJECT) != 0)
7724*22dc650dSSadaf Ebrahimi {
7725*22dc650dSSadaf Ebrahimi length = CU2BYTES(length + was_zero_terminated);
7726*22dc650dSSadaf Ebrahimi match_data->subject = match_data->memctl.malloc(length,
7727*22dc650dSSadaf Ebrahimi match_data->memctl.memory_data);
7728*22dc650dSSadaf Ebrahimi if (match_data->subject == NULL) return PCRE2_ERROR_NOMEMORY;
7729*22dc650dSSadaf Ebrahimi memcpy((void *)match_data->subject, subject, length);
7730*22dc650dSSadaf Ebrahimi match_data->flags |= PCRE2_MD_COPIED_SUBJECT;
7731*22dc650dSSadaf Ebrahimi }
7732*22dc650dSSadaf Ebrahimi else match_data->subject = subject;
7733*22dc650dSSadaf Ebrahimi
7734*22dc650dSSadaf Ebrahimi return match_data->rc;
7735*22dc650dSSadaf Ebrahimi }
7736*22dc650dSSadaf Ebrahimi
7737*22dc650dSSadaf Ebrahimi /* Control gets here if there has been a partial match, an error, or if the
7738*22dc650dSSadaf Ebrahimi overall match attempt has failed at all permitted starting positions. Any mark
7739*22dc650dSSadaf Ebrahimi data is in the nomatch_mark field. */
7740*22dc650dSSadaf Ebrahimi
7741*22dc650dSSadaf Ebrahimi match_data->mark = mb->nomatch_mark;
7742*22dc650dSSadaf Ebrahimi
7743*22dc650dSSadaf Ebrahimi /* For anything other than nomatch or partial match, just return the code. */
7744*22dc650dSSadaf Ebrahimi
7745*22dc650dSSadaf Ebrahimi if (rc != MATCH_NOMATCH && rc != PCRE2_ERROR_PARTIAL) match_data->rc = rc;
7746*22dc650dSSadaf Ebrahimi
7747*22dc650dSSadaf Ebrahimi /* Handle a partial match. If a "soft" partial match was requested, searching
7748*22dc650dSSadaf Ebrahimi for a complete match will have continued, and the value of rc at this point
7749*22dc650dSSadaf Ebrahimi will be MATCH_NOMATCH. For a "hard" partial match, it will already be
7750*22dc650dSSadaf Ebrahimi PCRE2_ERROR_PARTIAL. */
7751*22dc650dSSadaf Ebrahimi
7752*22dc650dSSadaf Ebrahimi else if (match_partial != NULL)
7753*22dc650dSSadaf Ebrahimi {
7754*22dc650dSSadaf Ebrahimi match_data->subject = subject;
7755*22dc650dSSadaf Ebrahimi match_data->subject_length = length;
7756*22dc650dSSadaf Ebrahimi match_data->ovector[0] = match_partial - subject;
7757*22dc650dSSadaf Ebrahimi match_data->ovector[1] = end_subject - subject;
7758*22dc650dSSadaf Ebrahimi match_data->startchar = match_partial - subject;
7759*22dc650dSSadaf Ebrahimi match_data->leftchar = start_partial - subject;
7760*22dc650dSSadaf Ebrahimi match_data->rightchar = end_subject - subject;
7761*22dc650dSSadaf Ebrahimi match_data->rc = PCRE2_ERROR_PARTIAL;
7762*22dc650dSSadaf Ebrahimi }
7763*22dc650dSSadaf Ebrahimi
7764*22dc650dSSadaf Ebrahimi /* Else this is the classic nomatch case. */
7765*22dc650dSSadaf Ebrahimi
7766*22dc650dSSadaf Ebrahimi else match_data->rc = PCRE2_ERROR_NOMATCH;
7767*22dc650dSSadaf Ebrahimi
7768*22dc650dSSadaf Ebrahimi return match_data->rc;
7769*22dc650dSSadaf Ebrahimi }
7770*22dc650dSSadaf Ebrahimi
7771*22dc650dSSadaf Ebrahimi /* These #undefs are here to enable unity builds with CMake. */
7772*22dc650dSSadaf Ebrahimi
7773*22dc650dSSadaf Ebrahimi #undef NLBLOCK /* Block containing newline information */
7774*22dc650dSSadaf Ebrahimi #undef PSSTART /* Field containing processed string start */
7775*22dc650dSSadaf Ebrahimi #undef PSEND /* Field containing processed string end */
7776*22dc650dSSadaf Ebrahimi
7777*22dc650dSSadaf Ebrahimi /* End of pcre2_match.c */
7778