1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/tools/pcre/pcre_exec.c Tue Jul 28 17:51:34 2009 -0400
1.3 @@ -0,0 +1,5050 @@
1.4 +/*************************************************
1.5 +* Perl-Compatible Regular Expressions *
1.6 +*************************************************/
1.7 +
1.8 +/* PCRE is a library of functions to support regular expressions whose syntax
1.9 +and semantics are as close as possible to those of the Perl 5 language.
1.10 +
1.11 + Written by Philip Hazel
1.12 + Copyright (c) 1997-2009 University of Cambridge
1.13 +
1.14 +-----------------------------------------------------------------------------
1.15 +Redistribution and use in source and binary forms, with or without
1.16 +modification, are permitted provided that the following conditions are met:
1.17 +
1.18 + * Redistributions of source code must retain the above copyright notice,
1.19 + this list of conditions and the following disclaimer.
1.20 +
1.21 + * Redistributions in binary form must reproduce the above copyright
1.22 + notice, this list of conditions and the following disclaimer in the
1.23 + documentation and/or other materials provided with the distribution.
1.24 +
1.25 + * Neither the name of the University of Cambridge nor the names of its
1.26 + contributors may be used to endorse or promote products derived from
1.27 + this software without specific prior written permission.
1.28 +
1.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
1.30 +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1.31 +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1.32 +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
1.33 +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
1.34 +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
1.35 +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
1.36 +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
1.37 +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
1.38 +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
1.39 +POSSIBILITY OF SUCH DAMAGE.
1.40 +-----------------------------------------------------------------------------
1.41 +*/
1.42 +
1.43 +
1.44 +/* This module contains pcre_exec(), the externally visible function that does
1.45 +pattern matching using an NFA algorithm, trying to mimic Perl as closely as
1.46 +possible. There are also some static supporting functions. */
1.47 +
1.48 +#ifdef HAVE_CONFIG_H
1.49 +#include "config.h"
1.50 +#endif
1.51 +
1.52 +#define NLBLOCK md /* Block containing newline information */
1.53 +#define PSSTART start_subject /* Field containing processed string start */
1.54 +#define PSEND end_subject /* Field containing processed string end */
1.55 +
1.56 +#include "pcre_internal.h"
1.57 +
1.58 +/* Undefine some potentially clashing cpp symbols */
1.59 +
1.60 +#undef min
1.61 +#undef max
1.62 +
1.63 +/* Flag bits for the match() function */
1.64 +
1.65 +#define match_condassert 0x01 /* Called to check a condition assertion */
1.66 +#define match_cbegroup 0x02 /* Could-be-empty unlimited repeat group */
1.67 +
1.68 +/* Non-error returns from the match() function. Error returns are externally
1.69 +defined PCRE_ERROR_xxx codes, which are all negative. */
1.70 +
1.71 +#define MATCH_MATCH 1
1.72 +#define MATCH_NOMATCH 0
1.73 +
1.74 +/* Special internal returns from the match() function. Make them sufficiently
1.75 +negative to avoid the external error codes. */
1.76 +
1.77 +#define MATCH_COMMIT (-999)
1.78 +#define MATCH_PRUNE (-998)
1.79 +#define MATCH_SKIP (-997)
1.80 +#define MATCH_THEN (-996)
1.81 +
1.82 +/* Maximum number of ints of offset to save on the stack for recursive calls.
1.83 +If the offset vector is bigger, malloc is used. This should be a multiple of 3,
1.84 +because the offset vector is always a multiple of 3 long. */
1.85 +
1.86 +#define REC_STACK_SAVE_MAX 30
1.87 +
1.88 +/* Min and max values for the common repeats; for the maxima, 0 => infinity */
1.89 +
1.90 +static const char rep_min[] = { 0, 0, 1, 1, 0, 0 };
1.91 +static const char rep_max[] = { 0, 0, 0, 0, 1, 1 };
1.92 +
1.93 +
1.94 +
1.95 +#ifdef DEBUG
1.96 +/*************************************************
1.97 +* Debugging function to print chars *
1.98 +*************************************************/
1.99 +
1.100 +/* Print a sequence of chars in printable format, stopping at the end of the
1.101 +subject if the requested.
1.102 +
1.103 +Arguments:
1.104 + p points to characters
1.105 + length number to print
1.106 + is_subject TRUE if printing from within md->start_subject
1.107 + md pointer to matching data block, if is_subject is TRUE
1.108 +
1.109 +Returns: nothing
1.110 +*/
1.111 +
1.112 +static void
1.113 +pchars(const uschar *p, int length, BOOL is_subject, match_data *md)
1.114 +{
1.115 +unsigned int c;
1.116 +if (is_subject && length > md->end_subject - p) length = md->end_subject - p;
1.117 +while (length-- > 0)
1.118 + if (isprint(c = *(p++))) printf("%c", c); else printf("\\x%02x", c);
1.119 +}
1.120 +#endif
1.121 +
1.122 +
1.123 +
1.124 +/*************************************************
1.125 +* Match a back-reference *
1.126 +*************************************************/
1.127 +
1.128 +/* If a back reference hasn't been set, the length that is passed is greater
1.129 +than the number of characters left in the string, so the match fails.
1.130 +
1.131 +Arguments:
1.132 + offset index into the offset vector
1.133 + eptr points into the subject
1.134 + length length to be matched
1.135 + md points to match data block
1.136 + ims the ims flags
1.137 +
1.138 +Returns: TRUE if matched
1.139 +*/
1.140 +
1.141 +static BOOL
1.142 +match_ref(int offset, register USPTR eptr, int length, match_data *md,
1.143 + unsigned long int ims)
1.144 +{
1.145 +USPTR p = md->start_subject + md->offset_vector[offset];
1.146 +
1.147 +#ifdef DEBUG
1.148 +if (eptr >= md->end_subject)
1.149 + printf("matching subject <null>");
1.150 +else
1.151 + {
1.152 + printf("matching subject ");
1.153 + pchars(eptr, length, TRUE, md);
1.154 + }
1.155 +printf(" against backref ");
1.156 +pchars(p, length, FALSE, md);
1.157 +printf("\n");
1.158 +#endif
1.159 +
1.160 +/* Always fail if not enough characters left */
1.161 +
1.162 +if (length > md->end_subject - eptr) return FALSE;
1.163 +
1.164 +/* Separate the caseless case for speed. In UTF-8 mode we can only do this
1.165 +properly if Unicode properties are supported. Otherwise, we can check only
1.166 +ASCII characters. */
1.167 +
1.168 +if ((ims & PCRE_CASELESS) != 0)
1.169 + {
1.170 +#ifdef SUPPORT_UTF8
1.171 +#ifdef SUPPORT_UCP
1.172 + if (md->utf8)
1.173 + {
1.174 + USPTR endptr = eptr + length;
1.175 + while (eptr < endptr)
1.176 + {
1.177 + int c, d;
1.178 + GETCHARINC(c, eptr);
1.179 + GETCHARINC(d, p);
1.180 + if (c != d && c != UCD_OTHERCASE(d)) return FALSE;
1.181 + }
1.182 + }
1.183 + else
1.184 +#endif
1.185 +#endif
1.186 +
1.187 + /* The same code works when not in UTF-8 mode and in UTF-8 mode when there
1.188 + is no UCP support. */
1.189 +
1.190 + while (length-- > 0)
1.191 + { if (md->lcc[*p++] != md->lcc[*eptr++]) return FALSE; }
1.192 + }
1.193 +
1.194 +/* In the caseful case, we can just compare the bytes, whether or not we
1.195 +are in UTF-8 mode. */
1.196 +
1.197 +else
1.198 + { while (length-- > 0) if (*p++ != *eptr++) return FALSE; }
1.199 +
1.200 +return TRUE;
1.201 +}
1.202 +
1.203 +
1.204 +
1.205 +/***************************************************************************
1.206 +****************************************************************************
1.207 + RECURSION IN THE match() FUNCTION
1.208 +
1.209 +The match() function is highly recursive, though not every recursive call
1.210 +increases the recursive depth. Nevertheless, some regular expressions can cause
1.211 +it to recurse to a great depth. I was writing for Unix, so I just let it call
1.212 +itself recursively. This uses the stack for saving everything that has to be
1.213 +saved for a recursive call. On Unix, the stack can be large, and this works
1.214 +fine.
1.215 +
1.216 +It turns out that on some non-Unix-like systems there are problems with
1.217 +programs that use a lot of stack. (This despite the fact that every last chip
1.218 +has oodles of memory these days, and techniques for extending the stack have
1.219 +been known for decades.) So....
1.220 +
1.221 +There is a fudge, triggered by defining NO_RECURSE, which avoids recursive
1.222 +calls by keeping local variables that need to be preserved in blocks of memory
1.223 +obtained from malloc() instead instead of on the stack. Macros are used to
1.224 +achieve this so that the actual code doesn't look very different to what it
1.225 +always used to.
1.226 +
1.227 +The original heap-recursive code used longjmp(). However, it seems that this
1.228 +can be very slow on some operating systems. Following a suggestion from Stan
1.229 +Switzer, the use of longjmp() has been abolished, at the cost of having to
1.230 +provide a unique number for each call to RMATCH. There is no way of generating
1.231 +a sequence of numbers at compile time in C. I have given them names, to make
1.232 +them stand out more clearly.
1.233 +
1.234 +Crude tests on x86 Linux show a small speedup of around 5-8%. However, on
1.235 +FreeBSD, avoiding longjmp() more than halves the time taken to run the standard
1.236 +tests. Furthermore, not using longjmp() means that local dynamic variables
1.237 +don't have indeterminate values; this has meant that the frame size can be
1.238 +reduced because the result can be "passed back" by straight setting of the
1.239 +variable instead of being passed in the frame.
1.240 +****************************************************************************
1.241 +***************************************************************************/
1.242 +
1.243 +/* Numbers for RMATCH calls. When this list is changed, the code at HEAP_RETURN
1.244 +below must be updated in sync. */
1.245 +
1.246 +enum { RM1=1, RM2, RM3, RM4, RM5, RM6, RM7, RM8, RM9, RM10,
1.247 + RM11, RM12, RM13, RM14, RM15, RM16, RM17, RM18, RM19, RM20,
1.248 + RM21, RM22, RM23, RM24, RM25, RM26, RM27, RM28, RM29, RM30,
1.249 + RM31, RM32, RM33, RM34, RM35, RM36, RM37, RM38, RM39, RM40,
1.250 + RM41, RM42, RM43, RM44, RM45, RM46, RM47, RM48, RM49, RM50,
1.251 + RM51, RM52, RM53, RM54 };
1.252 +
1.253 +/* These versions of the macros use the stack, as normal. There are debugging
1.254 +versions and production versions. Note that the "rw" argument of RMATCH isn't
1.255 +actuall used in this definition. */
1.256 +
1.257 +#ifndef NO_RECURSE
1.258 +#define REGISTER register
1.259 +
1.260 +#ifdef DEBUG
1.261 +#define RMATCH(ra,rb,rc,rd,re,rf,rg,rw) \
1.262 + { \
1.263 + printf("match() called in line %d\n", __LINE__); \
1.264 + rrc = match(ra,rb,mstart,rc,rd,re,rf,rg,rdepth+1); \
1.265 + printf("to line %d\n", __LINE__); \
1.266 + }
1.267 +#define RRETURN(ra) \
1.268 + { \
1.269 + printf("match() returned %d from line %d ", ra, __LINE__); \
1.270 + return ra; \
1.271 + }
1.272 +#else
1.273 +#define RMATCH(ra,rb,rc,rd,re,rf,rg,rw) \
1.274 + rrc = match(ra,rb,mstart,rc,rd,re,rf,rg,rdepth+1)
1.275 +#define RRETURN(ra) return ra
1.276 +#endif
1.277 +
1.278 +#else
1.279 +
1.280 +
1.281 +/* These versions of the macros manage a private stack on the heap. Note that
1.282 +the "rd" argument of RMATCH isn't actually used in this definition. It's the md
1.283 +argument of match(), which never changes. */
1.284 +
1.285 +#define REGISTER
1.286 +
1.287 +#define RMATCH(ra,rb,rc,rd,re,rf,rg,rw)\
1.288 + {\
1.289 + heapframe *newframe = (pcre_stack_malloc)(sizeof(heapframe));\
1.290 + frame->Xwhere = rw; \
1.291 + newframe->Xeptr = ra;\
1.292 + newframe->Xecode = rb;\
1.293 + newframe->Xmstart = mstart;\
1.294 + newframe->Xoffset_top = rc;\
1.295 + newframe->Xims = re;\
1.296 + newframe->Xeptrb = rf;\
1.297 + newframe->Xflags = rg;\
1.298 + newframe->Xrdepth = frame->Xrdepth + 1;\
1.299 + newframe->Xprevframe = frame;\
1.300 + frame = newframe;\
1.301 + DPRINTF(("restarting from line %d\n", __LINE__));\
1.302 + goto HEAP_RECURSE;\
1.303 + L_##rw:\
1.304 + DPRINTF(("jumped back to line %d\n", __LINE__));\
1.305 + }
1.306 +
1.307 +#define RRETURN(ra)\
1.308 + {\
1.309 + heapframe *newframe = frame;\
1.310 + frame = newframe->Xprevframe;\
1.311 + (pcre_stack_free)(newframe);\
1.312 + if (frame != NULL)\
1.313 + {\
1.314 + rrc = ra;\
1.315 + goto HEAP_RETURN;\
1.316 + }\
1.317 + return ra;\
1.318 + }
1.319 +
1.320 +
1.321 +/* Structure for remembering the local variables in a private frame */
1.322 +
1.323 +typedef struct heapframe {
1.324 + struct heapframe *Xprevframe;
1.325 +
1.326 + /* Function arguments that may change */
1.327 +
1.328 + USPTR Xeptr;
1.329 + const uschar *Xecode;
1.330 + USPTR Xmstart;
1.331 + int Xoffset_top;
1.332 + long int Xims;
1.333 + eptrblock *Xeptrb;
1.334 + int Xflags;
1.335 + unsigned int Xrdepth;
1.336 +
1.337 + /* Function local variables */
1.338 +
1.339 + USPTR Xcallpat;
1.340 +#ifdef SUPPORT_UTF8
1.341 + USPTR Xcharptr;
1.342 +#endif
1.343 + USPTR Xdata;
1.344 + USPTR Xnext;
1.345 + USPTR Xpp;
1.346 + USPTR Xprev;
1.347 + USPTR Xsaved_eptr;
1.348 +
1.349 + recursion_info Xnew_recursive;
1.350 +
1.351 + BOOL Xcur_is_word;
1.352 + BOOL Xcondition;
1.353 + BOOL Xprev_is_word;
1.354 +
1.355 + unsigned long int Xoriginal_ims;
1.356 +
1.357 +#ifdef SUPPORT_UCP
1.358 + int Xprop_type;
1.359 + int Xprop_value;
1.360 + int Xprop_fail_result;
1.361 + int Xprop_category;
1.362 + int Xprop_chartype;
1.363 + int Xprop_script;
1.364 + int Xoclength;
1.365 + uschar Xocchars[8];
1.366 +#endif
1.367 +
1.368 + int Xcodelink;
1.369 + int Xctype;
1.370 + unsigned int Xfc;
1.371 + int Xfi;
1.372 + int Xlength;
1.373 + int Xmax;
1.374 + int Xmin;
1.375 + int Xnumber;
1.376 + int Xoffset;
1.377 + int Xop;
1.378 + int Xsave_capture_last;
1.379 + int Xsave_offset1, Xsave_offset2, Xsave_offset3;
1.380 + int Xstacksave[REC_STACK_SAVE_MAX];
1.381 +
1.382 + eptrblock Xnewptrb;
1.383 +
1.384 + /* Where to jump back to */
1.385 +
1.386 + int Xwhere;
1.387 +
1.388 +} heapframe;
1.389 +
1.390 +#endif
1.391 +
1.392 +
1.393 +/***************************************************************************
1.394 +***************************************************************************/
1.395 +
1.396 +
1.397 +
1.398 +/*************************************************
1.399 +* Match from current position *
1.400 +*************************************************/
1.401 +
1.402 +/* This function is called recursively in many circumstances. Whenever it
1.403 +returns a negative (error) response, the outer incarnation must also return the
1.404 +same response.
1.405 +
1.406 +Performance note: It might be tempting to extract commonly used fields from the
1.407 +md structure (e.g. utf8, end_subject) into individual variables to improve
1.408 +performance. Tests using gcc on a SPARC disproved this; in the first case, it
1.409 +made performance worse.
1.410 +
1.411 +Arguments:
1.412 + eptr pointer to current character in subject
1.413 + ecode pointer to current position in compiled code
1.414 + mstart pointer to the current match start position (can be modified
1.415 + by encountering \K)
1.416 + offset_top current top pointer
1.417 + md pointer to "static" info for the match
1.418 + ims current /i, /m, and /s options
1.419 + eptrb pointer to chain of blocks containing eptr at start of
1.420 + brackets - for testing for empty matches
1.421 + flags can contain
1.422 + match_condassert - this is an assertion condition
1.423 + match_cbegroup - this is the start of an unlimited repeat
1.424 + group that can match an empty string
1.425 + rdepth the recursion depth
1.426 +
1.427 +Returns: MATCH_MATCH if matched ) these values are >= 0
1.428 + MATCH_NOMATCH if failed to match )
1.429 + a negative PCRE_ERROR_xxx value if aborted by an error condition
1.430 + (e.g. stopped by repeated call or recursion limit)
1.431 +*/
1.432 +
1.433 +static int
1.434 +match(REGISTER USPTR eptr, REGISTER const uschar *ecode, USPTR mstart,
1.435 + int offset_top, match_data *md, unsigned long int ims, eptrblock *eptrb,
1.436 + int flags, unsigned int rdepth)
1.437 +{
1.438 +/* These variables do not need to be preserved over recursion in this function,
1.439 +so they can be ordinary variables in all cases. Mark some of them with
1.440 +"register" because they are used a lot in loops. */
1.441 +
1.442 +register int rrc; /* Returns from recursive calls */
1.443 +register int i; /* Used for loops not involving calls to RMATCH() */
1.444 +register unsigned int c; /* Character values not kept over RMATCH() calls */
1.445 +register BOOL utf8; /* Local copy of UTF-8 flag for speed */
1.446 +
1.447 +BOOL minimize, possessive; /* Quantifier options */
1.448 +int condcode;
1.449 +
1.450 +/* When recursion is not being used, all "local" variables that have to be
1.451 +preserved over calls to RMATCH() are part of a "frame" which is obtained from
1.452 +heap storage. Set up the top-level frame here; others are obtained from the
1.453 +heap whenever RMATCH() does a "recursion". See the macro definitions above. */
1.454 +
1.455 +#ifdef NO_RECURSE
1.456 +heapframe *frame = (pcre_stack_malloc)(sizeof(heapframe));
1.457 +frame->Xprevframe = NULL; /* Marks the top level */
1.458 +
1.459 +/* Copy in the original argument variables */
1.460 +
1.461 +frame->Xeptr = eptr;
1.462 +frame->Xecode = ecode;
1.463 +frame->Xmstart = mstart;
1.464 +frame->Xoffset_top = offset_top;
1.465 +frame->Xims = ims;
1.466 +frame->Xeptrb = eptrb;
1.467 +frame->Xflags = flags;
1.468 +frame->Xrdepth = rdepth;
1.469 +
1.470 +/* This is where control jumps back to to effect "recursion" */
1.471 +
1.472 +HEAP_RECURSE:
1.473 +
1.474 +/* Macros make the argument variables come from the current frame */
1.475 +
1.476 +#define eptr frame->Xeptr
1.477 +#define ecode frame->Xecode
1.478 +#define mstart frame->Xmstart
1.479 +#define offset_top frame->Xoffset_top
1.480 +#define ims frame->Xims
1.481 +#define eptrb frame->Xeptrb
1.482 +#define flags frame->Xflags
1.483 +#define rdepth frame->Xrdepth
1.484 +
1.485 +/* Ditto for the local variables */
1.486 +
1.487 +#ifdef SUPPORT_UTF8
1.488 +#define charptr frame->Xcharptr
1.489 +#endif
1.490 +#define callpat frame->Xcallpat
1.491 +#define codelink frame->Xcodelink
1.492 +#define data frame->Xdata
1.493 +#define next frame->Xnext
1.494 +#define pp frame->Xpp
1.495 +#define prev frame->Xprev
1.496 +#define saved_eptr frame->Xsaved_eptr
1.497 +
1.498 +#define new_recursive frame->Xnew_recursive
1.499 +
1.500 +#define cur_is_word frame->Xcur_is_word
1.501 +#define condition frame->Xcondition
1.502 +#define prev_is_word frame->Xprev_is_word
1.503 +
1.504 +#define original_ims frame->Xoriginal_ims
1.505 +
1.506 +#ifdef SUPPORT_UCP
1.507 +#define prop_type frame->Xprop_type
1.508 +#define prop_value frame->Xprop_value
1.509 +#define prop_fail_result frame->Xprop_fail_result
1.510 +#define prop_category frame->Xprop_category
1.511 +#define prop_chartype frame->Xprop_chartype
1.512 +#define prop_script frame->Xprop_script
1.513 +#define oclength frame->Xoclength
1.514 +#define occhars frame->Xocchars
1.515 +#endif
1.516 +
1.517 +#define ctype frame->Xctype
1.518 +#define fc frame->Xfc
1.519 +#define fi frame->Xfi
1.520 +#define length frame->Xlength
1.521 +#define max frame->Xmax
1.522 +#define min frame->Xmin
1.523 +#define number frame->Xnumber
1.524 +#define offset frame->Xoffset
1.525 +#define op frame->Xop
1.526 +#define save_capture_last frame->Xsave_capture_last
1.527 +#define save_offset1 frame->Xsave_offset1
1.528 +#define save_offset2 frame->Xsave_offset2
1.529 +#define save_offset3 frame->Xsave_offset3
1.530 +#define stacksave frame->Xstacksave
1.531 +
1.532 +#define newptrb frame->Xnewptrb
1.533 +
1.534 +/* When recursion is being used, local variables are allocated on the stack and
1.535 +get preserved during recursion in the normal way. In this environment, fi and
1.536 +i, and fc and c, can be the same variables. */
1.537 +
1.538 +#else /* NO_RECURSE not defined */
1.539 +#define fi i
1.540 +#define fc c
1.541 +
1.542 +
1.543 +#ifdef SUPPORT_UTF8 /* Many of these variables are used only */
1.544 +const uschar *charptr; /* in small blocks of the code. My normal */
1.545 +#endif /* style of coding would have declared */
1.546 +const uschar *callpat; /* them within each of those blocks. */
1.547 +const uschar *data; /* However, in order to accommodate the */
1.548 +const uschar *next; /* version of this code that uses an */
1.549 +USPTR pp; /* external "stack" implemented on the */
1.550 +const uschar *prev; /* heap, it is easier to declare them all */
1.551 +USPTR saved_eptr; /* here, so the declarations can be cut */
1.552 + /* out in a block. The only declarations */
1.553 +recursion_info new_recursive; /* within blocks below are for variables */
1.554 + /* that do not have to be preserved over */
1.555 +BOOL cur_is_word; /* a recursive call to RMATCH(). */
1.556 +BOOL condition;
1.557 +BOOL prev_is_word;
1.558 +
1.559 +unsigned long int original_ims;
1.560 +
1.561 +#ifdef SUPPORT_UCP
1.562 +int prop_type;
1.563 +int prop_value;
1.564 +int prop_fail_result;
1.565 +int prop_category;
1.566 +int prop_chartype;
1.567 +int prop_script;
1.568 +int oclength;
1.569 +uschar occhars[8];
1.570 +#endif
1.571 +
1.572 +int codelink;
1.573 +int ctype;
1.574 +int length;
1.575 +int max;
1.576 +int min;
1.577 +int number;
1.578 +int offset;
1.579 +int op;
1.580 +int save_capture_last;
1.581 +int save_offset1, save_offset2, save_offset3;
1.582 +int stacksave[REC_STACK_SAVE_MAX];
1.583 +
1.584 +eptrblock newptrb;
1.585 +#endif /* NO_RECURSE */
1.586 +
1.587 +/* These statements are here to stop the compiler complaining about unitialized
1.588 +variables. */
1.589 +
1.590 +#ifdef SUPPORT_UCP
1.591 +prop_value = 0;
1.592 +prop_fail_result = 0;
1.593 +#endif
1.594 +
1.595 +
1.596 +/* This label is used for tail recursion, which is used in a few cases even
1.597 +when NO_RECURSE is not defined, in order to reduce the amount of stack that is
1.598 +used. Thanks to Ian Taylor for noticing this possibility and sending the
1.599 +original patch. */
1.600 +
1.601 +TAIL_RECURSE:
1.602 +
1.603 +/* OK, now we can get on with the real code of the function. Recursive calls
1.604 +are specified by the macro RMATCH and RRETURN is used to return. When
1.605 +NO_RECURSE is *not* defined, these just turn into a recursive call to match()
1.606 +and a "return", respectively (possibly with some debugging if DEBUG is
1.607 +defined). However, RMATCH isn't like a function call because it's quite a
1.608 +complicated macro. It has to be used in one particular way. This shouldn't,
1.609 +however, impact performance when true recursion is being used. */
1.610 +
1.611 +#ifdef SUPPORT_UTF8
1.612 +utf8 = md->utf8; /* Local copy of the flag */
1.613 +#else
1.614 +utf8 = FALSE;
1.615 +#endif
1.616 +
1.617 +/* First check that we haven't called match() too many times, or that we
1.618 +haven't exceeded the recursive call limit. */
1.619 +
1.620 +if (md->match_call_count++ >= md->match_limit) RRETURN(PCRE_ERROR_MATCHLIMIT);
1.621 +if (rdepth >= md->match_limit_recursion) RRETURN(PCRE_ERROR_RECURSIONLIMIT);
1.622 +
1.623 +original_ims = ims; /* Save for resetting on ')' */
1.624 +
1.625 +/* At the start of a group with an unlimited repeat that may match an empty
1.626 +string, the match_cbegroup flag is set. When this is the case, add the current
1.627 +subject pointer to the chain of such remembered pointers, to be checked when we
1.628 +hit the closing ket, in order to break infinite loops that match no characters.
1.629 +When match() is called in other circumstances, don't add to the chain. The
1.630 +match_cbegroup flag must NOT be used with tail recursion, because the memory
1.631 +block that is used is on the stack, so a new one may be required for each
1.632 +match(). */
1.633 +
1.634 +if ((flags & match_cbegroup) != 0)
1.635 + {
1.636 + newptrb.epb_saved_eptr = eptr;
1.637 + newptrb.epb_prev = eptrb;
1.638 + eptrb = &newptrb;
1.639 + }
1.640 +
1.641 +/* Now start processing the opcodes. */
1.642 +
1.643 +for (;;)
1.644 + {
1.645 + minimize = possessive = FALSE;
1.646 + op = *ecode;
1.647 +
1.648 + /* For partial matching, remember if we ever hit the end of the subject after
1.649 + matching at least one subject character. */
1.650 +
1.651 + if (md->partial &&
1.652 + eptr >= md->end_subject &&
1.653 + eptr > mstart)
1.654 + md->hitend = TRUE;
1.655 +
1.656 + switch(op)
1.657 + {
1.658 + case OP_FAIL:
1.659 + RRETURN(MATCH_NOMATCH);
1.660 +
1.661 + case OP_PRUNE:
1.662 + RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,
1.663 + ims, eptrb, flags, RM51);
1.664 + if (rrc != MATCH_NOMATCH) RRETURN(rrc);
1.665 + RRETURN(MATCH_PRUNE);
1.666 +
1.667 + case OP_COMMIT:
1.668 + RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,
1.669 + ims, eptrb, flags, RM52);
1.670 + if (rrc != MATCH_NOMATCH) RRETURN(rrc);
1.671 + RRETURN(MATCH_COMMIT);
1.672 +
1.673 + case OP_SKIP:
1.674 + RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,
1.675 + ims, eptrb, flags, RM53);
1.676 + if (rrc != MATCH_NOMATCH) RRETURN(rrc);
1.677 + md->start_match_ptr = eptr; /* Pass back current position */
1.678 + RRETURN(MATCH_SKIP);
1.679 +
1.680 + case OP_THEN:
1.681 + RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,
1.682 + ims, eptrb, flags, RM54);
1.683 + if (rrc != MATCH_NOMATCH) RRETURN(rrc);
1.684 + RRETURN(MATCH_THEN);
1.685 +
1.686 + /* Handle a capturing bracket. If there is space in the offset vector, save
1.687 + the current subject position in the working slot at the top of the vector.
1.688 + We mustn't change the current values of the data slot, because they may be
1.689 + set from a previous iteration of this group, and be referred to by a
1.690 + reference inside the group.
1.691 +
1.692 + If the bracket fails to match, we need to restore this value and also the
1.693 + values of the final offsets, in case they were set by a previous iteration
1.694 + of the same bracket.
1.695 +
1.696 + If there isn't enough space in the offset vector, treat this as if it were
1.697 + a non-capturing bracket. Don't worry about setting the flag for the error
1.698 + case here; that is handled in the code for KET. */
1.699 +
1.700 + case OP_CBRA:
1.701 + case OP_SCBRA:
1.702 + number = GET2(ecode, 1+LINK_SIZE);
1.703 + offset = number << 1;
1.704 +
1.705 +#ifdef DEBUG
1.706 + printf("start bracket %d\n", number);
1.707 + printf("subject=");
1.708 + pchars(eptr, 16, TRUE, md);
1.709 + printf("\n");
1.710 +#endif
1.711 +
1.712 + if (offset < md->offset_max)
1.713 + {
1.714 + save_offset1 = md->offset_vector[offset];
1.715 + save_offset2 = md->offset_vector[offset+1];
1.716 + save_offset3 = md->offset_vector[md->offset_end - number];
1.717 + save_capture_last = md->capture_last;
1.718 +
1.719 + DPRINTF(("saving %d %d %d\n", save_offset1, save_offset2, save_offset3));
1.720 + md->offset_vector[md->offset_end - number] = eptr - md->start_subject;
1.721 +
1.722 + flags = (op == OP_SCBRA)? match_cbegroup : 0;
1.723 + do
1.724 + {
1.725 + RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,
1.726 + ims, eptrb, flags, RM1);
1.727 + if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);
1.728 + md->capture_last = save_capture_last;
1.729 + ecode += GET(ecode, 1);
1.730 + }
1.731 + while (*ecode == OP_ALT);
1.732 +
1.733 + DPRINTF(("bracket %d failed\n", number));
1.734 +
1.735 + md->offset_vector[offset] = save_offset1;
1.736 + md->offset_vector[offset+1] = save_offset2;
1.737 + md->offset_vector[md->offset_end - number] = save_offset3;
1.738 +
1.739 + RRETURN(MATCH_NOMATCH);
1.740 + }
1.741 +
1.742 + /* FALL THROUGH ... Insufficient room for saving captured contents. Treat
1.743 + as a non-capturing bracket. */
1.744 +
1.745 + /* VVVVVVVVVVVVVVVVVVVVVVVVV */
1.746 + /* VVVVVVVVVVVVVVVVVVVVVVVVV */
1.747 +
1.748 + DPRINTF(("insufficient capture room: treat as non-capturing\n"));
1.749 +
1.750 + /* VVVVVVVVVVVVVVVVVVVVVVVVV */
1.751 + /* VVVVVVVVVVVVVVVVVVVVVVVVV */
1.752 +
1.753 + /* Non-capturing bracket. Loop for all the alternatives. When we get to the
1.754 + final alternative within the brackets, we would return the result of a
1.755 + recursive call to match() whatever happened. We can reduce stack usage by
1.756 + turning this into a tail recursion, except in the case when match_cbegroup
1.757 + is set.*/
1.758 +
1.759 + case OP_BRA:
1.760 + case OP_SBRA:
1.761 + DPRINTF(("start non-capturing bracket\n"));
1.762 + flags = (op >= OP_SBRA)? match_cbegroup : 0;
1.763 + for (;;)
1.764 + {
1.765 + if (ecode[GET(ecode, 1)] != OP_ALT) /* Final alternative */
1.766 + {
1.767 + if (flags == 0) /* Not a possibly empty group */
1.768 + {
1.769 + ecode += _pcre_OP_lengths[*ecode];
1.770 + DPRINTF(("bracket 0 tail recursion\n"));
1.771 + goto TAIL_RECURSE;
1.772 + }
1.773 +
1.774 + /* Possibly empty group; can't use tail recursion. */
1.775 +
1.776 + RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md, ims,
1.777 + eptrb, flags, RM48);
1.778 + RRETURN(rrc);
1.779 + }
1.780 +
1.781 + /* For non-final alternatives, continue the loop for a NOMATCH result;
1.782 + otherwise return. */
1.783 +
1.784 + RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md, ims,
1.785 + eptrb, flags, RM2);
1.786 + if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);
1.787 + ecode += GET(ecode, 1);
1.788 + }
1.789 + /* Control never reaches here. */
1.790 +
1.791 + /* Conditional group: compilation checked that there are no more than
1.792 + two branches. If the condition is false, skipping the first branch takes us
1.793 + past the end if there is only one branch, but that's OK because that is
1.794 + exactly what going to the ket would do. As there is only one branch to be
1.795 + obeyed, we can use tail recursion to avoid using another stack frame. */
1.796 +
1.797 + case OP_COND:
1.798 + case OP_SCOND:
1.799 + codelink= GET(ecode, 1);
1.800 +
1.801 + /* Because of the way auto-callout works during compile, a callout item is
1.802 + inserted between OP_COND and an assertion condition. */
1.803 +
1.804 + if (ecode[LINK_SIZE+1] == OP_CALLOUT)
1.805 + {
1.806 + if (pcre_callout != NULL)
1.807 + {
1.808 + pcre_callout_block cb;
1.809 + cb.version = 1; /* Version 1 of the callout block */
1.810 + cb.callout_number = ecode[LINK_SIZE+2];
1.811 + cb.offset_vector = md->offset_vector;
1.812 + cb.subject = (PCRE_SPTR)md->start_subject;
1.813 + cb.subject_length = md->end_subject - md->start_subject;
1.814 + cb.start_match = mstart - md->start_subject;
1.815 + cb.current_position = eptr - md->start_subject;
1.816 + cb.pattern_position = GET(ecode, LINK_SIZE + 3);
1.817 + cb.next_item_length = GET(ecode, 3 + 2*LINK_SIZE);
1.818 + cb.capture_top = offset_top/2;
1.819 + cb.capture_last = md->capture_last;
1.820 + cb.callout_data = md->callout_data;
1.821 + if ((rrc = (*pcre_callout)(&cb)) > 0) RRETURN(MATCH_NOMATCH);
1.822 + if (rrc < 0) RRETURN(rrc);
1.823 + }
1.824 + ecode += _pcre_OP_lengths[OP_CALLOUT];
1.825 + }
1.826 +
1.827 + condcode = ecode[LINK_SIZE+1];
1.828 +
1.829 + /* Now see what the actual condition is */
1.830 +
1.831 + if (condcode == OP_RREF) /* Recursion test */
1.832 + {
1.833 + offset = GET2(ecode, LINK_SIZE + 2); /* Recursion group number*/
1.834 + condition = md->recursive != NULL &&
1.835 + (offset == RREF_ANY || offset == md->recursive->group_num);
1.836 + ecode += condition? 3 : GET(ecode, 1);
1.837 + }
1.838 +
1.839 + else if (condcode == OP_CREF) /* Group used test */
1.840 + {
1.841 + offset = GET2(ecode, LINK_SIZE+2) << 1; /* Doubled ref number */
1.842 + condition = offset < offset_top && md->offset_vector[offset] >= 0;
1.843 + ecode += condition? 3 : GET(ecode, 1);
1.844 + }
1.845 +
1.846 + else if (condcode == OP_DEF) /* DEFINE - always false */
1.847 + {
1.848 + condition = FALSE;
1.849 + ecode += GET(ecode, 1);
1.850 + }
1.851 +
1.852 + /* The condition is an assertion. Call match() to evaluate it - setting
1.853 + the final argument match_condassert causes it to stop at the end of an
1.854 + assertion. */
1.855 +
1.856 + else
1.857 + {
1.858 + RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, NULL,
1.859 + match_condassert, RM3);
1.860 + if (rrc == MATCH_MATCH)
1.861 + {
1.862 + condition = TRUE;
1.863 + ecode += 1 + LINK_SIZE + GET(ecode, LINK_SIZE + 2);
1.864 + while (*ecode == OP_ALT) ecode += GET(ecode, 1);
1.865 + }
1.866 + else if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN)
1.867 + {
1.868 + RRETURN(rrc); /* Need braces because of following else */
1.869 + }
1.870 + else
1.871 + {
1.872 + condition = FALSE;
1.873 + ecode += codelink;
1.874 + }
1.875 + }
1.876 +
1.877 + /* We are now at the branch that is to be obeyed. As there is only one,
1.878 + we can use tail recursion to avoid using another stack frame, except when
1.879 + match_cbegroup is required for an unlimited repeat of a possibly empty
1.880 + group. If the second alternative doesn't exist, we can just plough on. */
1.881 +
1.882 + if (condition || *ecode == OP_ALT)
1.883 + {
1.884 + ecode += 1 + LINK_SIZE;
1.885 + if (op == OP_SCOND) /* Possibly empty group */
1.886 + {
1.887 + RMATCH(eptr, ecode, offset_top, md, ims, eptrb, match_cbegroup, RM49);
1.888 + RRETURN(rrc);
1.889 + }
1.890 + else /* Group must match something */
1.891 + {
1.892 + flags = 0;
1.893 + goto TAIL_RECURSE;
1.894 + }
1.895 + }
1.896 + else /* Condition false & no alternative */
1.897 + {
1.898 + ecode += 1 + LINK_SIZE;
1.899 + }
1.900 + break;
1.901 +
1.902 +
1.903 + /* End of the pattern, either real or forced. If we are in a top-level
1.904 + recursion, we should restore the offsets appropriately and continue from
1.905 + after the call. */
1.906 +
1.907 + case OP_ACCEPT:
1.908 + case OP_END:
1.909 + if (md->recursive != NULL && md->recursive->group_num == 0)
1.910 + {
1.911 + recursion_info *rec = md->recursive;
1.912 + DPRINTF(("End of pattern in a (?0) recursion\n"));
1.913 + md->recursive = rec->prevrec;
1.914 + memmove(md->offset_vector, rec->offset_save,
1.915 + rec->saved_max * sizeof(int));
1.916 + mstart = rec->save_start;
1.917 + ims = original_ims;
1.918 + ecode = rec->after_call;
1.919 + break;
1.920 + }
1.921 +
1.922 + /* Otherwise, if PCRE_NOTEMPTY is set, fail if we have matched an empty
1.923 + string - backtracking will then try other alternatives, if any. */
1.924 +
1.925 + if (md->notempty && eptr == mstart) RRETURN(MATCH_NOMATCH);
1.926 + md->end_match_ptr = eptr; /* Record where we ended */
1.927 + md->end_offset_top = offset_top; /* and how many extracts were taken */
1.928 + md->start_match_ptr = mstart; /* and the start (\K can modify) */
1.929 + RRETURN(MATCH_MATCH);
1.930 +
1.931 + /* Change option settings */
1.932 +
1.933 + case OP_OPT:
1.934 + ims = ecode[1];
1.935 + ecode += 2;
1.936 + DPRINTF(("ims set to %02lx\n", ims));
1.937 + break;
1.938 +
1.939 + /* Assertion brackets. Check the alternative branches in turn - the
1.940 + matching won't pass the KET for an assertion. If any one branch matches,
1.941 + the assertion is true. Lookbehind assertions have an OP_REVERSE item at the
1.942 + start of each branch to move the current point backwards, so the code at
1.943 + this level is identical to the lookahead case. */
1.944 +
1.945 + case OP_ASSERT:
1.946 + case OP_ASSERTBACK:
1.947 + do
1.948 + {
1.949 + RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, NULL, 0,
1.950 + RM4);
1.951 + if (rrc == MATCH_MATCH) break;
1.952 + if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);
1.953 + ecode += GET(ecode, 1);
1.954 + }
1.955 + while (*ecode == OP_ALT);
1.956 + if (*ecode == OP_KET) RRETURN(MATCH_NOMATCH);
1.957 +
1.958 + /* If checking an assertion for a condition, return MATCH_MATCH. */
1.959 +
1.960 + if ((flags & match_condassert) != 0) RRETURN(MATCH_MATCH);
1.961 +
1.962 + /* Continue from after the assertion, updating the offsets high water
1.963 + mark, since extracts may have been taken during the assertion. */
1.964 +
1.965 + do ecode += GET(ecode,1); while (*ecode == OP_ALT);
1.966 + ecode += 1 + LINK_SIZE;
1.967 + offset_top = md->end_offset_top;
1.968 + continue;
1.969 +
1.970 + /* Negative assertion: all branches must fail to match */
1.971 +
1.972 + case OP_ASSERT_NOT:
1.973 + case OP_ASSERTBACK_NOT:
1.974 + do
1.975 + {
1.976 + RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, NULL, 0,
1.977 + RM5);
1.978 + if (rrc == MATCH_MATCH) RRETURN(MATCH_NOMATCH);
1.979 + if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);
1.980 + ecode += GET(ecode,1);
1.981 + }
1.982 + while (*ecode == OP_ALT);
1.983 +
1.984 + if ((flags & match_condassert) != 0) RRETURN(MATCH_MATCH);
1.985 +
1.986 + ecode += 1 + LINK_SIZE;
1.987 + continue;
1.988 +
1.989 + /* Move the subject pointer back. This occurs only at the start of
1.990 + each branch of a lookbehind assertion. If we are too close to the start to
1.991 + move back, this match function fails. When working with UTF-8 we move
1.992 + back a number of characters, not bytes. */
1.993 +
1.994 + case OP_REVERSE:
1.995 +#ifdef SUPPORT_UTF8
1.996 + if (utf8)
1.997 + {
1.998 + i = GET(ecode, 1);
1.999 + while (i-- > 0)
1.1000 + {
1.1001 + eptr--;
1.1002 + if (eptr < md->start_subject) RRETURN(MATCH_NOMATCH);
1.1003 + BACKCHAR(eptr);
1.1004 + }
1.1005 + }
1.1006 + else
1.1007 +#endif
1.1008 +
1.1009 + /* No UTF-8 support, or not in UTF-8 mode: count is byte count */
1.1010 +
1.1011 + {
1.1012 + eptr -= GET(ecode, 1);
1.1013 + if (eptr < md->start_subject) RRETURN(MATCH_NOMATCH);
1.1014 + }
1.1015 +
1.1016 + /* Skip to next op code */
1.1017 +
1.1018 + ecode += 1 + LINK_SIZE;
1.1019 + break;
1.1020 +
1.1021 + /* The callout item calls an external function, if one is provided, passing
1.1022 + details of the match so far. This is mainly for debugging, though the
1.1023 + function is able to force a failure. */
1.1024 +
1.1025 + case OP_CALLOUT:
1.1026 + if (pcre_callout != NULL)
1.1027 + {
1.1028 + pcre_callout_block cb;
1.1029 + cb.version = 1; /* Version 1 of the callout block */
1.1030 + cb.callout_number = ecode[1];
1.1031 + cb.offset_vector = md->offset_vector;
1.1032 + cb.subject = (PCRE_SPTR)md->start_subject;
1.1033 + cb.subject_length = md->end_subject - md->start_subject;
1.1034 + cb.start_match = mstart - md->start_subject;
1.1035 + cb.current_position = eptr - md->start_subject;
1.1036 + cb.pattern_position = GET(ecode, 2);
1.1037 + cb.next_item_length = GET(ecode, 2 + LINK_SIZE);
1.1038 + cb.capture_top = offset_top/2;
1.1039 + cb.capture_last = md->capture_last;
1.1040 + cb.callout_data = md->callout_data;
1.1041 + if ((rrc = (*pcre_callout)(&cb)) > 0) RRETURN(MATCH_NOMATCH);
1.1042 + if (rrc < 0) RRETURN(rrc);
1.1043 + }
1.1044 + ecode += 2 + 2*LINK_SIZE;
1.1045 + break;
1.1046 +
1.1047 + /* Recursion either matches the current regex, or some subexpression. The
1.1048 + offset data is the offset to the starting bracket from the start of the
1.1049 + whole pattern. (This is so that it works from duplicated subpatterns.)
1.1050 +
1.1051 + If there are any capturing brackets started but not finished, we have to
1.1052 + save their starting points and reinstate them after the recursion. However,
1.1053 + we don't know how many such there are (offset_top records the completed
1.1054 + total) so we just have to save all the potential data. There may be up to
1.1055 + 65535 such values, which is too large to put on the stack, but using malloc
1.1056 + for small numbers seems expensive. As a compromise, the stack is used when
1.1057 + there are no more than REC_STACK_SAVE_MAX values to store; otherwise malloc
1.1058 + is used. A problem is what to do if the malloc fails ... there is no way of
1.1059 + returning to the top level with an error. Save the top REC_STACK_SAVE_MAX
1.1060 + values on the stack, and accept that the rest may be wrong.
1.1061 +
1.1062 + There are also other values that have to be saved. We use a chained
1.1063 + sequence of blocks that actually live on the stack. Thanks to Robin Houston
1.1064 + for the original version of this logic. */
1.1065 +
1.1066 + case OP_RECURSE:
1.1067 + {
1.1068 + callpat = md->start_code + GET(ecode, 1);
1.1069 + new_recursive.group_num = (callpat == md->start_code)? 0 :
1.1070 + GET2(callpat, 1 + LINK_SIZE);
1.1071 +
1.1072 + /* Add to "recursing stack" */
1.1073 +
1.1074 + new_recursive.prevrec = md->recursive;
1.1075 + md->recursive = &new_recursive;
1.1076 +
1.1077 + /* Find where to continue from afterwards */
1.1078 +
1.1079 + ecode += 1 + LINK_SIZE;
1.1080 + new_recursive.after_call = ecode;
1.1081 +
1.1082 + /* Now save the offset data. */
1.1083 +
1.1084 + new_recursive.saved_max = md->offset_end;
1.1085 + if (new_recursive.saved_max <= REC_STACK_SAVE_MAX)
1.1086 + new_recursive.offset_save = stacksave;
1.1087 + else
1.1088 + {
1.1089 + new_recursive.offset_save =
1.1090 + (int *)(pcre_malloc)(new_recursive.saved_max * sizeof(int));
1.1091 + if (new_recursive.offset_save == NULL) RRETURN(PCRE_ERROR_NOMEMORY);
1.1092 + }
1.1093 +
1.1094 + memcpy(new_recursive.offset_save, md->offset_vector,
1.1095 + new_recursive.saved_max * sizeof(int));
1.1096 + new_recursive.save_start = mstart;
1.1097 + mstart = eptr;
1.1098 +
1.1099 + /* OK, now we can do the recursion. For each top-level alternative we
1.1100 + restore the offset and recursion data. */
1.1101 +
1.1102 + DPRINTF(("Recursing into group %d\n", new_recursive.group_num));
1.1103 + flags = (*callpat >= OP_SBRA)? match_cbegroup : 0;
1.1104 + do
1.1105 + {
1.1106 + RMATCH(eptr, callpat + _pcre_OP_lengths[*callpat], offset_top,
1.1107 + md, ims, eptrb, flags, RM6);
1.1108 + if (rrc == MATCH_MATCH)
1.1109 + {
1.1110 + DPRINTF(("Recursion matched\n"));
1.1111 + md->recursive = new_recursive.prevrec;
1.1112 + if (new_recursive.offset_save != stacksave)
1.1113 + (pcre_free)(new_recursive.offset_save);
1.1114 + RRETURN(MATCH_MATCH);
1.1115 + }
1.1116 + else if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN)
1.1117 + {
1.1118 + DPRINTF(("Recursion gave error %d\n", rrc));
1.1119 + if (new_recursive.offset_save != stacksave)
1.1120 + (pcre_free)(new_recursive.offset_save);
1.1121 + RRETURN(rrc);
1.1122 + }
1.1123 +
1.1124 + md->recursive = &new_recursive;
1.1125 + memcpy(md->offset_vector, new_recursive.offset_save,
1.1126 + new_recursive.saved_max * sizeof(int));
1.1127 + callpat += GET(callpat, 1);
1.1128 + }
1.1129 + while (*callpat == OP_ALT);
1.1130 +
1.1131 + DPRINTF(("Recursion didn't match\n"));
1.1132 + md->recursive = new_recursive.prevrec;
1.1133 + if (new_recursive.offset_save != stacksave)
1.1134 + (pcre_free)(new_recursive.offset_save);
1.1135 + RRETURN(MATCH_NOMATCH);
1.1136 + }
1.1137 + /* Control never reaches here */
1.1138 +
1.1139 + /* "Once" brackets are like assertion brackets except that after a match,
1.1140 + the point in the subject string is not moved back. Thus there can never be
1.1141 + a move back into the brackets. Friedl calls these "atomic" subpatterns.
1.1142 + Check the alternative branches in turn - the matching won't pass the KET
1.1143 + for this kind of subpattern. If any one branch matches, we carry on as at
1.1144 + the end of a normal bracket, leaving the subject pointer. */
1.1145 +
1.1146 + case OP_ONCE:
1.1147 + prev = ecode;
1.1148 + saved_eptr = eptr;
1.1149 +
1.1150 + do
1.1151 + {
1.1152 + RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, eptrb, 0, RM7);
1.1153 + if (rrc == MATCH_MATCH) break;
1.1154 + if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);
1.1155 + ecode += GET(ecode,1);
1.1156 + }
1.1157 + while (*ecode == OP_ALT);
1.1158 +
1.1159 + /* If hit the end of the group (which could be repeated), fail */
1.1160 +
1.1161 + if (*ecode != OP_ONCE && *ecode != OP_ALT) RRETURN(MATCH_NOMATCH);
1.1162 +
1.1163 + /* Continue as from after the assertion, updating the offsets high water
1.1164 + mark, since extracts may have been taken. */
1.1165 +
1.1166 + do ecode += GET(ecode, 1); while (*ecode == OP_ALT);
1.1167 +
1.1168 + offset_top = md->end_offset_top;
1.1169 + eptr = md->end_match_ptr;
1.1170 +
1.1171 + /* For a non-repeating ket, just continue at this level. This also
1.1172 + happens for a repeating ket if no characters were matched in the group.
1.1173 + This is the forcible breaking of infinite loops as implemented in Perl
1.1174 + 5.005. If there is an options reset, it will get obeyed in the normal
1.1175 + course of events. */
1.1176 +
1.1177 + if (*ecode == OP_KET || eptr == saved_eptr)
1.1178 + {
1.1179 + ecode += 1+LINK_SIZE;
1.1180 + break;
1.1181 + }
1.1182 +
1.1183 + /* The repeating kets try the rest of the pattern or restart from the
1.1184 + preceding bracket, in the appropriate order. The second "call" of match()
1.1185 + uses tail recursion, to avoid using another stack frame. We need to reset
1.1186 + any options that changed within the bracket before re-running it, so
1.1187 + check the next opcode. */
1.1188 +
1.1189 + if (ecode[1+LINK_SIZE] == OP_OPT)
1.1190 + {
1.1191 + ims = (ims & ~PCRE_IMS) | ecode[4];
1.1192 + DPRINTF(("ims set to %02lx at group repeat\n", ims));
1.1193 + }
1.1194 +
1.1195 + if (*ecode == OP_KETRMIN)
1.1196 + {
1.1197 + RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, eptrb, 0, RM8);
1.1198 + if (rrc != MATCH_NOMATCH) RRETURN(rrc);
1.1199 + ecode = prev;
1.1200 + flags = 0;
1.1201 + goto TAIL_RECURSE;
1.1202 + }
1.1203 + else /* OP_KETRMAX */
1.1204 + {
1.1205 + RMATCH(eptr, prev, offset_top, md, ims, eptrb, match_cbegroup, RM9);
1.1206 + if (rrc != MATCH_NOMATCH) RRETURN(rrc);
1.1207 + ecode += 1 + LINK_SIZE;
1.1208 + flags = 0;
1.1209 + goto TAIL_RECURSE;
1.1210 + }
1.1211 + /* Control never gets here */
1.1212 +
1.1213 + /* An alternation is the end of a branch; scan along to find the end of the
1.1214 + bracketed group and go to there. */
1.1215 +
1.1216 + case OP_ALT:
1.1217 + do ecode += GET(ecode,1); while (*ecode == OP_ALT);
1.1218 + break;
1.1219 +
1.1220 + /* BRAZERO, BRAMINZERO and SKIPZERO occur just before a bracket group,
1.1221 + indicating that it may occur zero times. It may repeat infinitely, or not
1.1222 + at all - i.e. it could be ()* or ()? or even (){0} in the pattern. Brackets
1.1223 + with fixed upper repeat limits are compiled as a number of copies, with the
1.1224 + optional ones preceded by BRAZERO or BRAMINZERO. */
1.1225 +
1.1226 + case OP_BRAZERO:
1.1227 + {
1.1228 + next = ecode+1;
1.1229 + RMATCH(eptr, next, offset_top, md, ims, eptrb, 0, RM10);
1.1230 + if (rrc != MATCH_NOMATCH) RRETURN(rrc);
1.1231 + do next += GET(next,1); while (*next == OP_ALT);
1.1232 + ecode = next + 1 + LINK_SIZE;
1.1233 + }
1.1234 + break;
1.1235 +
1.1236 + case OP_BRAMINZERO:
1.1237 + {
1.1238 + next = ecode+1;
1.1239 + do next += GET(next, 1); while (*next == OP_ALT);
1.1240 + RMATCH(eptr, next + 1+LINK_SIZE, offset_top, md, ims, eptrb, 0, RM11);
1.1241 + if (rrc != MATCH_NOMATCH) RRETURN(rrc);
1.1242 + ecode++;
1.1243 + }
1.1244 + break;
1.1245 +
1.1246 + case OP_SKIPZERO:
1.1247 + {
1.1248 + next = ecode+1;
1.1249 + do next += GET(next,1); while (*next == OP_ALT);
1.1250 + ecode = next + 1 + LINK_SIZE;
1.1251 + }
1.1252 + break;
1.1253 +
1.1254 + /* End of a group, repeated or non-repeating. */
1.1255 +
1.1256 + case OP_KET:
1.1257 + case OP_KETRMIN:
1.1258 + case OP_KETRMAX:
1.1259 + prev = ecode - GET(ecode, 1);
1.1260 +
1.1261 + /* If this was a group that remembered the subject start, in order to break
1.1262 + infinite repeats of empty string matches, retrieve the subject start from
1.1263 + the chain. Otherwise, set it NULL. */
1.1264 +
1.1265 + if (*prev >= OP_SBRA)
1.1266 + {
1.1267 + saved_eptr = eptrb->epb_saved_eptr; /* Value at start of group */
1.1268 + eptrb = eptrb->epb_prev; /* Backup to previous group */
1.1269 + }
1.1270 + else saved_eptr = NULL;
1.1271 +
1.1272 + /* If we are at the end of an assertion group, stop matching and return
1.1273 + MATCH_MATCH, but record the current high water mark for use by positive
1.1274 + assertions. Do this also for the "once" (atomic) groups. */
1.1275 +
1.1276 + if (*prev == OP_ASSERT || *prev == OP_ASSERT_NOT ||
1.1277 + *prev == OP_ASSERTBACK || *prev == OP_ASSERTBACK_NOT ||
1.1278 + *prev == OP_ONCE)
1.1279 + {
1.1280 + md->end_match_ptr = eptr; /* For ONCE */
1.1281 + md->end_offset_top = offset_top;
1.1282 + RRETURN(MATCH_MATCH);
1.1283 + }
1.1284 +
1.1285 + /* For capturing groups we have to check the group number back at the start
1.1286 + and if necessary complete handling an extraction by setting the offsets and
1.1287 + bumping the high water mark. Note that whole-pattern recursion is coded as
1.1288 + a recurse into group 0, so it won't be picked up here. Instead, we catch it
1.1289 + when the OP_END is reached. Other recursion is handled here. */
1.1290 +
1.1291 + if (*prev == OP_CBRA || *prev == OP_SCBRA)
1.1292 + {
1.1293 + number = GET2(prev, 1+LINK_SIZE);
1.1294 + offset = number << 1;
1.1295 +
1.1296 +#ifdef DEBUG
1.1297 + printf("end bracket %d", number);
1.1298 + printf("\n");
1.1299 +#endif
1.1300 +
1.1301 + md->capture_last = number;
1.1302 + if (offset >= md->offset_max) md->offset_overflow = TRUE; else
1.1303 + {
1.1304 + md->offset_vector[offset] =
1.1305 + md->offset_vector[md->offset_end - number];
1.1306 + md->offset_vector[offset+1] = eptr - md->start_subject;
1.1307 + if (offset_top <= offset) offset_top = offset + 2;
1.1308 + }
1.1309 +
1.1310 + /* Handle a recursively called group. Restore the offsets
1.1311 + appropriately and continue from after the call. */
1.1312 +
1.1313 + if (md->recursive != NULL && md->recursive->group_num == number)
1.1314 + {
1.1315 + recursion_info *rec = md->recursive;
1.1316 + DPRINTF(("Recursion (%d) succeeded - continuing\n", number));
1.1317 + md->recursive = rec->prevrec;
1.1318 + mstart = rec->save_start;
1.1319 + memcpy(md->offset_vector, rec->offset_save,
1.1320 + rec->saved_max * sizeof(int));
1.1321 + ecode = rec->after_call;
1.1322 + ims = original_ims;
1.1323 + break;
1.1324 + }
1.1325 + }
1.1326 +
1.1327 + /* For both capturing and non-capturing groups, reset the value of the ims
1.1328 + flags, in case they got changed during the group. */
1.1329 +
1.1330 + ims = original_ims;
1.1331 + DPRINTF(("ims reset to %02lx\n", ims));
1.1332 +
1.1333 + /* For a non-repeating ket, just continue at this level. This also
1.1334 + happens for a repeating ket if no characters were matched in the group.
1.1335 + This is the forcible breaking of infinite loops as implemented in Perl
1.1336 + 5.005. If there is an options reset, it will get obeyed in the normal
1.1337 + course of events. */
1.1338 +
1.1339 + if (*ecode == OP_KET || eptr == saved_eptr)
1.1340 + {
1.1341 + ecode += 1 + LINK_SIZE;
1.1342 + break;
1.1343 + }
1.1344 +
1.1345 + /* The repeating kets try the rest of the pattern or restart from the
1.1346 + preceding bracket, in the appropriate order. In the second case, we can use
1.1347 + tail recursion to avoid using another stack frame, unless we have an
1.1348 + unlimited repeat of a group that can match an empty string. */
1.1349 +
1.1350 + flags = (*prev >= OP_SBRA)? match_cbegroup : 0;
1.1351 +
1.1352 + if (*ecode == OP_KETRMIN)
1.1353 + {
1.1354 + RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, eptrb, 0, RM12);
1.1355 + if (rrc != MATCH_NOMATCH) RRETURN(rrc);
1.1356 + if (flags != 0) /* Could match an empty string */
1.1357 + {
1.1358 + RMATCH(eptr, prev, offset_top, md, ims, eptrb, flags, RM50);
1.1359 + RRETURN(rrc);
1.1360 + }
1.1361 + ecode = prev;
1.1362 + goto TAIL_RECURSE;
1.1363 + }
1.1364 + else /* OP_KETRMAX */
1.1365 + {
1.1366 + RMATCH(eptr, prev, offset_top, md, ims, eptrb, flags, RM13);
1.1367 + if (rrc != MATCH_NOMATCH) RRETURN(rrc);
1.1368 + ecode += 1 + LINK_SIZE;
1.1369 + flags = 0;
1.1370 + goto TAIL_RECURSE;
1.1371 + }
1.1372 + /* Control never gets here */
1.1373 +
1.1374 + /* Start of subject unless notbol, or after internal newline if multiline */
1.1375 +
1.1376 + case OP_CIRC:
1.1377 + if (md->notbol && eptr == md->start_subject) RRETURN(MATCH_NOMATCH);
1.1378 + if ((ims & PCRE_MULTILINE) != 0)
1.1379 + {
1.1380 + if (eptr != md->start_subject &&
1.1381 + (eptr == md->end_subject || !WAS_NEWLINE(eptr)))
1.1382 + RRETURN(MATCH_NOMATCH);
1.1383 + ecode++;
1.1384 + break;
1.1385 + }
1.1386 + /* ... else fall through */
1.1387 +
1.1388 + /* Start of subject assertion */
1.1389 +
1.1390 + case OP_SOD:
1.1391 + if (eptr != md->start_subject) RRETURN(MATCH_NOMATCH);
1.1392 + ecode++;
1.1393 + break;
1.1394 +
1.1395 + /* Start of match assertion */
1.1396 +
1.1397 + case OP_SOM:
1.1398 + if (eptr != md->start_subject + md->start_offset) RRETURN(MATCH_NOMATCH);
1.1399 + ecode++;
1.1400 + break;
1.1401 +
1.1402 + /* Reset the start of match point */
1.1403 +
1.1404 + case OP_SET_SOM:
1.1405 + mstart = eptr;
1.1406 + ecode++;
1.1407 + break;
1.1408 +
1.1409 + /* Assert before internal newline if multiline, or before a terminating
1.1410 + newline unless endonly is set, else end of subject unless noteol is set. */
1.1411 +
1.1412 + case OP_DOLL:
1.1413 + if ((ims & PCRE_MULTILINE) != 0)
1.1414 + {
1.1415 + if (eptr < md->end_subject)
1.1416 + { if (!IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH); }
1.1417 + else
1.1418 + { if (md->noteol) RRETURN(MATCH_NOMATCH); }
1.1419 + ecode++;
1.1420 + break;
1.1421 + }
1.1422 + else
1.1423 + {
1.1424 + if (md->noteol) RRETURN(MATCH_NOMATCH);
1.1425 + if (!md->endonly)
1.1426 + {
1.1427 + if (eptr != md->end_subject &&
1.1428 + (!IS_NEWLINE(eptr) || eptr != md->end_subject - md->nllen))
1.1429 + RRETURN(MATCH_NOMATCH);
1.1430 + ecode++;
1.1431 + break;
1.1432 + }
1.1433 + }
1.1434 + /* ... else fall through for endonly */
1.1435 +
1.1436 + /* End of subject assertion (\z) */
1.1437 +
1.1438 + case OP_EOD:
1.1439 + if (eptr < md->end_subject) RRETURN(MATCH_NOMATCH);
1.1440 + ecode++;
1.1441 + break;
1.1442 +
1.1443 + /* End of subject or ending \n assertion (\Z) */
1.1444 +
1.1445 + case OP_EODN:
1.1446 + if (eptr != md->end_subject &&
1.1447 + (!IS_NEWLINE(eptr) || eptr != md->end_subject - md->nllen))
1.1448 + RRETURN(MATCH_NOMATCH);
1.1449 + ecode++;
1.1450 + break;
1.1451 +
1.1452 + /* Word boundary assertions */
1.1453 +
1.1454 + case OP_NOT_WORD_BOUNDARY:
1.1455 + case OP_WORD_BOUNDARY:
1.1456 + {
1.1457 +
1.1458 + /* Find out if the previous and current characters are "word" characters.
1.1459 + It takes a bit more work in UTF-8 mode. Characters > 255 are assumed to
1.1460 + be "non-word" characters. */
1.1461 +
1.1462 +#ifdef SUPPORT_UTF8
1.1463 + if (utf8)
1.1464 + {
1.1465 + if (eptr == md->start_subject) prev_is_word = FALSE; else
1.1466 + {
1.1467 + USPTR lastptr = eptr - 1;
1.1468 + while((*lastptr & 0xc0) == 0x80) lastptr--;
1.1469 + GETCHAR(c, lastptr);
1.1470 + prev_is_word = c < 256 && (md->ctypes[c] & ctype_word) != 0;
1.1471 + }
1.1472 + if (eptr >= md->end_subject) cur_is_word = FALSE; else
1.1473 + {
1.1474 + GETCHAR(c, eptr);
1.1475 + cur_is_word = c < 256 && (md->ctypes[c] & ctype_word) != 0;
1.1476 + }
1.1477 + }
1.1478 + else
1.1479 +#endif
1.1480 +
1.1481 + /* More streamlined when not in UTF-8 mode */
1.1482 +
1.1483 + {
1.1484 + prev_is_word = (eptr != md->start_subject) &&
1.1485 + ((md->ctypes[eptr[-1]] & ctype_word) != 0);
1.1486 + cur_is_word = (eptr < md->end_subject) &&
1.1487 + ((md->ctypes[*eptr] & ctype_word) != 0);
1.1488 + }
1.1489 +
1.1490 + /* Now see if the situation is what we want */
1.1491 +
1.1492 + if ((*ecode++ == OP_WORD_BOUNDARY)?
1.1493 + cur_is_word == prev_is_word : cur_is_word != prev_is_word)
1.1494 + RRETURN(MATCH_NOMATCH);
1.1495 + }
1.1496 + break;
1.1497 +
1.1498 + /* Match a single character type; inline for speed */
1.1499 +
1.1500 + case OP_ANY:
1.1501 + if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH);
1.1502 + /* Fall through */
1.1503 +
1.1504 + case OP_ALLANY:
1.1505 + if (eptr++ >= md->end_subject) RRETURN(MATCH_NOMATCH);
1.1506 + if (utf8) while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;
1.1507 + ecode++;
1.1508 + break;
1.1509 +
1.1510 + /* Match a single byte, even in UTF-8 mode. This opcode really does match
1.1511 + any byte, even newline, independent of the setting of PCRE_DOTALL. */
1.1512 +
1.1513 + case OP_ANYBYTE:
1.1514 + if (eptr++ >= md->end_subject) RRETURN(MATCH_NOMATCH);
1.1515 + ecode++;
1.1516 + break;
1.1517 +
1.1518 + case OP_NOT_DIGIT:
1.1519 + if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
1.1520 + GETCHARINCTEST(c, eptr);
1.1521 + if (
1.1522 +#ifdef SUPPORT_UTF8
1.1523 + c < 256 &&
1.1524 +#endif
1.1525 + (md->ctypes[c] & ctype_digit) != 0
1.1526 + )
1.1527 + RRETURN(MATCH_NOMATCH);
1.1528 + ecode++;
1.1529 + break;
1.1530 +
1.1531 + case OP_DIGIT:
1.1532 + if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
1.1533 + GETCHARINCTEST(c, eptr);
1.1534 + if (
1.1535 +#ifdef SUPPORT_UTF8
1.1536 + c >= 256 ||
1.1537 +#endif
1.1538 + (md->ctypes[c] & ctype_digit) == 0
1.1539 + )
1.1540 + RRETURN(MATCH_NOMATCH);
1.1541 + ecode++;
1.1542 + break;
1.1543 +
1.1544 + case OP_NOT_WHITESPACE:
1.1545 + if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
1.1546 + GETCHARINCTEST(c, eptr);
1.1547 + if (
1.1548 +#ifdef SUPPORT_UTF8
1.1549 + c < 256 &&
1.1550 +#endif
1.1551 + (md->ctypes[c] & ctype_space) != 0
1.1552 + )
1.1553 + RRETURN(MATCH_NOMATCH);
1.1554 + ecode++;
1.1555 + break;
1.1556 +
1.1557 + case OP_WHITESPACE:
1.1558 + if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
1.1559 + GETCHARINCTEST(c, eptr);
1.1560 + if (
1.1561 +#ifdef SUPPORT_UTF8
1.1562 + c >= 256 ||
1.1563 +#endif
1.1564 + (md->ctypes[c] & ctype_space) == 0
1.1565 + )
1.1566 + RRETURN(MATCH_NOMATCH);
1.1567 + ecode++;
1.1568 + break;
1.1569 +
1.1570 + case OP_NOT_WORDCHAR:
1.1571 + if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
1.1572 + GETCHARINCTEST(c, eptr);
1.1573 + if (
1.1574 +#ifdef SUPPORT_UTF8
1.1575 + c < 256 &&
1.1576 +#endif
1.1577 + (md->ctypes[c] & ctype_word) != 0
1.1578 + )
1.1579 + RRETURN(MATCH_NOMATCH);
1.1580 + ecode++;
1.1581 + break;
1.1582 +
1.1583 + case OP_WORDCHAR:
1.1584 + if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
1.1585 + GETCHARINCTEST(c, eptr);
1.1586 + if (
1.1587 +#ifdef SUPPORT_UTF8
1.1588 + c >= 256 ||
1.1589 +#endif
1.1590 + (md->ctypes[c] & ctype_word) == 0
1.1591 + )
1.1592 + RRETURN(MATCH_NOMATCH);
1.1593 + ecode++;
1.1594 + break;
1.1595 +
1.1596 + case OP_ANYNL:
1.1597 + if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
1.1598 + GETCHARINCTEST(c, eptr);
1.1599 + switch(c)
1.1600 + {
1.1601 + default: RRETURN(MATCH_NOMATCH);
1.1602 + case 0x000d:
1.1603 + if (eptr < md->end_subject && *eptr == 0x0a) eptr++;
1.1604 + break;
1.1605 +
1.1606 + case 0x000a:
1.1607 + break;
1.1608 +
1.1609 + case 0x000b:
1.1610 + case 0x000c:
1.1611 + case 0x0085:
1.1612 + case 0x2028:
1.1613 + case 0x2029:
1.1614 + if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH);
1.1615 + break;
1.1616 + }
1.1617 + ecode++;
1.1618 + break;
1.1619 +
1.1620 + case OP_NOT_HSPACE:
1.1621 + if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
1.1622 + GETCHARINCTEST(c, eptr);
1.1623 + switch(c)
1.1624 + {
1.1625 + default: break;
1.1626 + case 0x09: /* HT */
1.1627 + case 0x20: /* SPACE */
1.1628 + case 0xa0: /* NBSP */
1.1629 + case 0x1680: /* OGHAM SPACE MARK */
1.1630 + case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */
1.1631 + case 0x2000: /* EN QUAD */
1.1632 + case 0x2001: /* EM QUAD */
1.1633 + case 0x2002: /* EN SPACE */
1.1634 + case 0x2003: /* EM SPACE */
1.1635 + case 0x2004: /* THREE-PER-EM SPACE */
1.1636 + case 0x2005: /* FOUR-PER-EM SPACE */
1.1637 + case 0x2006: /* SIX-PER-EM SPACE */
1.1638 + case 0x2007: /* FIGURE SPACE */
1.1639 + case 0x2008: /* PUNCTUATION SPACE */
1.1640 + case 0x2009: /* THIN SPACE */
1.1641 + case 0x200A: /* HAIR SPACE */
1.1642 + case 0x202f: /* NARROW NO-BREAK SPACE */
1.1643 + case 0x205f: /* MEDIUM MATHEMATICAL SPACE */
1.1644 + case 0x3000: /* IDEOGRAPHIC SPACE */
1.1645 + RRETURN(MATCH_NOMATCH);
1.1646 + }
1.1647 + ecode++;
1.1648 + break;
1.1649 +
1.1650 + case OP_HSPACE:
1.1651 + if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
1.1652 + GETCHARINCTEST(c, eptr);
1.1653 + switch(c)
1.1654 + {
1.1655 + default: RRETURN(MATCH_NOMATCH);
1.1656 + case 0x09: /* HT */
1.1657 + case 0x20: /* SPACE */
1.1658 + case 0xa0: /* NBSP */
1.1659 + case 0x1680: /* OGHAM SPACE MARK */
1.1660 + case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */
1.1661 + case 0x2000: /* EN QUAD */
1.1662 + case 0x2001: /* EM QUAD */
1.1663 + case 0x2002: /* EN SPACE */
1.1664 + case 0x2003: /* EM SPACE */
1.1665 + case 0x2004: /* THREE-PER-EM SPACE */
1.1666 + case 0x2005: /* FOUR-PER-EM SPACE */
1.1667 + case 0x2006: /* SIX-PER-EM SPACE */
1.1668 + case 0x2007: /* FIGURE SPACE */
1.1669 + case 0x2008: /* PUNCTUATION SPACE */
1.1670 + case 0x2009: /* THIN SPACE */
1.1671 + case 0x200A: /* HAIR SPACE */
1.1672 + case 0x202f: /* NARROW NO-BREAK SPACE */
1.1673 + case 0x205f: /* MEDIUM MATHEMATICAL SPACE */
1.1674 + case 0x3000: /* IDEOGRAPHIC SPACE */
1.1675 + break;
1.1676 + }
1.1677 + ecode++;
1.1678 + break;
1.1679 +
1.1680 + case OP_NOT_VSPACE:
1.1681 + if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
1.1682 + GETCHARINCTEST(c, eptr);
1.1683 + switch(c)
1.1684 + {
1.1685 + default: break;
1.1686 + case 0x0a: /* LF */
1.1687 + case 0x0b: /* VT */
1.1688 + case 0x0c: /* FF */
1.1689 + case 0x0d: /* CR */
1.1690 + case 0x85: /* NEL */
1.1691 + case 0x2028: /* LINE SEPARATOR */
1.1692 + case 0x2029: /* PARAGRAPH SEPARATOR */
1.1693 + RRETURN(MATCH_NOMATCH);
1.1694 + }
1.1695 + ecode++;
1.1696 + break;
1.1697 +
1.1698 + case OP_VSPACE:
1.1699 + if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
1.1700 + GETCHARINCTEST(c, eptr);
1.1701 + switch(c)
1.1702 + {
1.1703 + default: RRETURN(MATCH_NOMATCH);
1.1704 + case 0x0a: /* LF */
1.1705 + case 0x0b: /* VT */
1.1706 + case 0x0c: /* FF */
1.1707 + case 0x0d: /* CR */
1.1708 + case 0x85: /* NEL */
1.1709 + case 0x2028: /* LINE SEPARATOR */
1.1710 + case 0x2029: /* PARAGRAPH SEPARATOR */
1.1711 + break;
1.1712 + }
1.1713 + ecode++;
1.1714 + break;
1.1715 +
1.1716 +#ifdef SUPPORT_UCP
1.1717 + /* Check the next character by Unicode property. We will get here only
1.1718 + if the support is in the binary; otherwise a compile-time error occurs. */
1.1719 +
1.1720 + case OP_PROP:
1.1721 + case OP_NOTPROP:
1.1722 + if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
1.1723 + GETCHARINCTEST(c, eptr);
1.1724 + {
1.1725 + const ucd_record *prop = GET_UCD(c);
1.1726 +
1.1727 + switch(ecode[1])
1.1728 + {
1.1729 + case PT_ANY:
1.1730 + if (op == OP_NOTPROP) RRETURN(MATCH_NOMATCH);
1.1731 + break;
1.1732 +
1.1733 + case PT_LAMP:
1.1734 + if ((prop->chartype == ucp_Lu ||
1.1735 + prop->chartype == ucp_Ll ||
1.1736 + prop->chartype == ucp_Lt) == (op == OP_NOTPROP))
1.1737 + RRETURN(MATCH_NOMATCH);
1.1738 + break;
1.1739 +
1.1740 + case PT_GC:
1.1741 + if ((ecode[2] != _pcre_ucp_gentype[prop->chartype]) == (op == OP_PROP))
1.1742 + RRETURN(MATCH_NOMATCH);
1.1743 + break;
1.1744 +
1.1745 + case PT_PC:
1.1746 + if ((ecode[2] != prop->chartype) == (op == OP_PROP))
1.1747 + RRETURN(MATCH_NOMATCH);
1.1748 + break;
1.1749 +
1.1750 + case PT_SC:
1.1751 + if ((ecode[2] != prop->script) == (op == OP_PROP))
1.1752 + RRETURN(MATCH_NOMATCH);
1.1753 + break;
1.1754 +
1.1755 + default:
1.1756 + RRETURN(PCRE_ERROR_INTERNAL);
1.1757 + }
1.1758 +
1.1759 + ecode += 3;
1.1760 + }
1.1761 + break;
1.1762 +
1.1763 + /* Match an extended Unicode sequence. We will get here only if the support
1.1764 + is in the binary; otherwise a compile-time error occurs. */
1.1765 +
1.1766 + case OP_EXTUNI:
1.1767 + if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
1.1768 + GETCHARINCTEST(c, eptr);
1.1769 + {
1.1770 + int category = UCD_CATEGORY(c);
1.1771 + if (category == ucp_M) RRETURN(MATCH_NOMATCH);
1.1772 + while (eptr < md->end_subject)
1.1773 + {
1.1774 + int len = 1;
1.1775 + if (!utf8) c = *eptr; else
1.1776 + {
1.1777 + GETCHARLEN(c, eptr, len);
1.1778 + }
1.1779 + category = UCD_CATEGORY(c);
1.1780 + if (category != ucp_M) break;
1.1781 + eptr += len;
1.1782 + }
1.1783 + }
1.1784 + ecode++;
1.1785 + break;
1.1786 +#endif
1.1787 +
1.1788 +
1.1789 + /* Match a back reference, possibly repeatedly. Look past the end of the
1.1790 + item to see if there is repeat information following. The code is similar
1.1791 + to that for character classes, but repeated for efficiency. Then obey
1.1792 + similar code to character type repeats - written out again for speed.
1.1793 + However, if the referenced string is the empty string, always treat
1.1794 + it as matched, any number of times (otherwise there could be infinite
1.1795 + loops). */
1.1796 +
1.1797 + case OP_REF:
1.1798 + {
1.1799 + offset = GET2(ecode, 1) << 1; /* Doubled ref number */
1.1800 + ecode += 3;
1.1801 +
1.1802 + /* If the reference is unset, there are two possibilities:
1.1803 +
1.1804 + (a) In the default, Perl-compatible state, set the length to be longer
1.1805 + than the amount of subject left; this ensures that every attempt at a
1.1806 + match fails. We can't just fail here, because of the possibility of
1.1807 + quantifiers with zero minima.
1.1808 +
1.1809 + (b) If the JavaScript compatibility flag is set, set the length to zero
1.1810 + so that the back reference matches an empty string.
1.1811 +
1.1812 + Otherwise, set the length to the length of what was matched by the
1.1813 + referenced subpattern. */
1.1814 +
1.1815 + if (offset >= offset_top || md->offset_vector[offset] < 0)
1.1816 + length = (md->jscript_compat)? 0 : md->end_subject - eptr + 1;
1.1817 + else
1.1818 + length = md->offset_vector[offset+1] - md->offset_vector[offset];
1.1819 +
1.1820 + /* Set up for repetition, or handle the non-repeated case */
1.1821 +
1.1822 + switch (*ecode)
1.1823 + {
1.1824 + case OP_CRSTAR:
1.1825 + case OP_CRMINSTAR:
1.1826 + case OP_CRPLUS:
1.1827 + case OP_CRMINPLUS:
1.1828 + case OP_CRQUERY:
1.1829 + case OP_CRMINQUERY:
1.1830 + c = *ecode++ - OP_CRSTAR;
1.1831 + minimize = (c & 1) != 0;
1.1832 + min = rep_min[c]; /* Pick up values from tables; */
1.1833 + max = rep_max[c]; /* zero for max => infinity */
1.1834 + if (max == 0) max = INT_MAX;
1.1835 + break;
1.1836 +
1.1837 + case OP_CRRANGE:
1.1838 + case OP_CRMINRANGE:
1.1839 + minimize = (*ecode == OP_CRMINRANGE);
1.1840 + min = GET2(ecode, 1);
1.1841 + max = GET2(ecode, 3);
1.1842 + if (max == 0) max = INT_MAX;
1.1843 + ecode += 5;
1.1844 + break;
1.1845 +
1.1846 + default: /* No repeat follows */
1.1847 + if (!match_ref(offset, eptr, length, md, ims)) RRETURN(MATCH_NOMATCH);
1.1848 + eptr += length;
1.1849 + continue; /* With the main loop */
1.1850 + }
1.1851 +
1.1852 + /* If the length of the reference is zero, just continue with the
1.1853 + main loop. */
1.1854 +
1.1855 + if (length == 0) continue;
1.1856 +
1.1857 + /* First, ensure the minimum number of matches are present. We get back
1.1858 + the length of the reference string explicitly rather than passing the
1.1859 + address of eptr, so that eptr can be a register variable. */
1.1860 +
1.1861 + for (i = 1; i <= min; i++)
1.1862 + {
1.1863 + if (!match_ref(offset, eptr, length, md, ims)) RRETURN(MATCH_NOMATCH);
1.1864 + eptr += length;
1.1865 + }
1.1866 +
1.1867 + /* If min = max, continue at the same level without recursion.
1.1868 + They are not both allowed to be zero. */
1.1869 +
1.1870 + if (min == max) continue;
1.1871 +
1.1872 + /* If minimizing, keep trying and advancing the pointer */
1.1873 +
1.1874 + if (minimize)
1.1875 + {
1.1876 + for (fi = min;; fi++)
1.1877 + {
1.1878 + RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM14);
1.1879 + if (rrc != MATCH_NOMATCH) RRETURN(rrc);
1.1880 + if (fi >= max || !match_ref(offset, eptr, length, md, ims))
1.1881 + RRETURN(MATCH_NOMATCH);
1.1882 + eptr += length;
1.1883 + }
1.1884 + /* Control never gets here */
1.1885 + }
1.1886 +
1.1887 + /* If maximizing, find the longest string and work backwards */
1.1888 +
1.1889 + else
1.1890 + {
1.1891 + pp = eptr;
1.1892 + for (i = min; i < max; i++)
1.1893 + {
1.1894 + if (!match_ref(offset, eptr, length, md, ims)) break;
1.1895 + eptr += length;
1.1896 + }
1.1897 + while (eptr >= pp)
1.1898 + {
1.1899 + RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM15);
1.1900 + if (rrc != MATCH_NOMATCH) RRETURN(rrc);
1.1901 + eptr -= length;
1.1902 + }
1.1903 + RRETURN(MATCH_NOMATCH);
1.1904 + }
1.1905 + }
1.1906 + /* Control never gets here */
1.1907 +
1.1908 +
1.1909 +
1.1910 + /* Match a bit-mapped character class, possibly repeatedly. This op code is
1.1911 + used when all the characters in the class have values in the range 0-255,
1.1912 + and either the matching is caseful, or the characters are in the range
1.1913 + 0-127 when UTF-8 processing is enabled. The only difference between
1.1914 + OP_CLASS and OP_NCLASS occurs when a data character outside the range is
1.1915 + encountered.
1.1916 +
1.1917 + First, look past the end of the item to see if there is repeat information
1.1918 + following. Then obey similar code to character type repeats - written out
1.1919 + again for speed. */
1.1920 +
1.1921 + case OP_NCLASS:
1.1922 + case OP_CLASS:
1.1923 + {
1.1924 + data = ecode + 1; /* Save for matching */
1.1925 + ecode += 33; /* Advance past the item */
1.1926 +
1.1927 + switch (*ecode)
1.1928 + {
1.1929 + case OP_CRSTAR:
1.1930 + case OP_CRMINSTAR:
1.1931 + case OP_CRPLUS:
1.1932 + case OP_CRMINPLUS:
1.1933 + case OP_CRQUERY:
1.1934 + case OP_CRMINQUERY:
1.1935 + c = *ecode++ - OP_CRSTAR;
1.1936 + minimize = (c & 1) != 0;
1.1937 + min = rep_min[c]; /* Pick up values from tables; */
1.1938 + max = rep_max[c]; /* zero for max => infinity */
1.1939 + if (max == 0) max = INT_MAX;
1.1940 + break;
1.1941 +
1.1942 + case OP_CRRANGE:
1.1943 + case OP_CRMINRANGE:
1.1944 + minimize = (*ecode == OP_CRMINRANGE);
1.1945 + min = GET2(ecode, 1);
1.1946 + max = GET2(ecode, 3);
1.1947 + if (max == 0) max = INT_MAX;
1.1948 + ecode += 5;
1.1949 + break;
1.1950 +
1.1951 + default: /* No repeat follows */
1.1952 + min = max = 1;
1.1953 + break;
1.1954 + }
1.1955 +
1.1956 + /* First, ensure the minimum number of matches are present. */
1.1957 +
1.1958 +#ifdef SUPPORT_UTF8
1.1959 + /* UTF-8 mode */
1.1960 + if (utf8)
1.1961 + {
1.1962 + for (i = 1; i <= min; i++)
1.1963 + {
1.1964 + if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
1.1965 + GETCHARINC(c, eptr);
1.1966 + if (c > 255)
1.1967 + {
1.1968 + if (op == OP_CLASS) RRETURN(MATCH_NOMATCH);
1.1969 + }
1.1970 + else
1.1971 + {
1.1972 + if ((data[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);
1.1973 + }
1.1974 + }
1.1975 + }
1.1976 + else
1.1977 +#endif
1.1978 + /* Not UTF-8 mode */
1.1979 + {
1.1980 + for (i = 1; i <= min; i++)
1.1981 + {
1.1982 + if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
1.1983 + c = *eptr++;
1.1984 + if ((data[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);
1.1985 + }
1.1986 + }
1.1987 +
1.1988 + /* If max == min we can continue with the main loop without the
1.1989 + need to recurse. */
1.1990 +
1.1991 + if (min == max) continue;
1.1992 +
1.1993 + /* If minimizing, keep testing the rest of the expression and advancing
1.1994 + the pointer while it matches the class. */
1.1995 +
1.1996 + if (minimize)
1.1997 + {
1.1998 +#ifdef SUPPORT_UTF8
1.1999 + /* UTF-8 mode */
1.2000 + if (utf8)
1.2001 + {
1.2002 + for (fi = min;; fi++)
1.2003 + {
1.2004 + RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM16);
1.2005 + if (rrc != MATCH_NOMATCH) RRETURN(rrc);
1.2006 + if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
1.2007 + GETCHARINC(c, eptr);
1.2008 + if (c > 255)
1.2009 + {
1.2010 + if (op == OP_CLASS) RRETURN(MATCH_NOMATCH);
1.2011 + }
1.2012 + else
1.2013 + {
1.2014 + if ((data[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);
1.2015 + }
1.2016 + }
1.2017 + }
1.2018 + else
1.2019 +#endif
1.2020 + /* Not UTF-8 mode */
1.2021 + {
1.2022 + for (fi = min;; fi++)
1.2023 + {
1.2024 + RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM17);
1.2025 + if (rrc != MATCH_NOMATCH) RRETURN(rrc);
1.2026 + if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
1.2027 + c = *eptr++;
1.2028 + if ((data[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);
1.2029 + }
1.2030 + }
1.2031 + /* Control never gets here */
1.2032 + }
1.2033 +
1.2034 + /* If maximizing, find the longest possible run, then work backwards. */
1.2035 +
1.2036 + else
1.2037 + {
1.2038 + pp = eptr;
1.2039 +
1.2040 +#ifdef SUPPORT_UTF8
1.2041 + /* UTF-8 mode */
1.2042 + if (utf8)
1.2043 + {
1.2044 + for (i = min; i < max; i++)
1.2045 + {
1.2046 + int len = 1;
1.2047 + if (eptr >= md->end_subject) break;
1.2048 + GETCHARLEN(c, eptr, len);
1.2049 + if (c > 255)
1.2050 + {
1.2051 + if (op == OP_CLASS) break;
1.2052 + }
1.2053 + else
1.2054 + {
1.2055 + if ((data[c/8] & (1 << (c&7))) == 0) break;
1.2056 + }
1.2057 + eptr += len;
1.2058 + }
1.2059 + for (;;)
1.2060 + {
1.2061 + RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM18);
1.2062 + if (rrc != MATCH_NOMATCH) RRETURN(rrc);
1.2063 + if (eptr-- == pp) break; /* Stop if tried at original pos */
1.2064 + BACKCHAR(eptr);
1.2065 + }
1.2066 + }
1.2067 + else
1.2068 +#endif
1.2069 + /* Not UTF-8 mode */
1.2070 + {
1.2071 + for (i = min; i < max; i++)
1.2072 + {
1.2073 + if (eptr >= md->end_subject) break;
1.2074 + c = *eptr;
1.2075 + if ((data[c/8] & (1 << (c&7))) == 0) break;
1.2076 + eptr++;
1.2077 + }
1.2078 + while (eptr >= pp)
1.2079 + {
1.2080 + RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM19);
1.2081 + if (rrc != MATCH_NOMATCH) RRETURN(rrc);
1.2082 + eptr--;
1.2083 + }
1.2084 + }
1.2085 +
1.2086 + RRETURN(MATCH_NOMATCH);
1.2087 + }
1.2088 + }
1.2089 + /* Control never gets here */
1.2090 +
1.2091 +
1.2092 + /* Match an extended character class. This opcode is encountered only
1.2093 + when UTF-8 mode mode is supported. Nevertheless, we may not be in UTF-8
1.2094 + mode, because Unicode properties are supported in non-UTF-8 mode. */
1.2095 +
1.2096 +#ifdef SUPPORT_UTF8
1.2097 + case OP_XCLASS:
1.2098 + {
1.2099 + data = ecode + 1 + LINK_SIZE; /* Save for matching */
1.2100 + ecode += GET(ecode, 1); /* Advance past the item */
1.2101 +
1.2102 + switch (*ecode)
1.2103 + {
1.2104 + case OP_CRSTAR:
1.2105 + case OP_CRMINSTAR:
1.2106 + case OP_CRPLUS:
1.2107 + case OP_CRMINPLUS:
1.2108 + case OP_CRQUERY:
1.2109 + case OP_CRMINQUERY:
1.2110 + c = *ecode++ - OP_CRSTAR;
1.2111 + minimize = (c & 1) != 0;
1.2112 + min = rep_min[c]; /* Pick up values from tables; */
1.2113 + max = rep_max[c]; /* zero for max => infinity */
1.2114 + if (max == 0) max = INT_MAX;
1.2115 + break;
1.2116 +
1.2117 + case OP_CRRANGE:
1.2118 + case OP_CRMINRANGE:
1.2119 + minimize = (*ecode == OP_CRMINRANGE);
1.2120 + min = GET2(ecode, 1);
1.2121 + max = GET2(ecode, 3);
1.2122 + if (max == 0) max = INT_MAX;
1.2123 + ecode += 5;
1.2124 + break;
1.2125 +
1.2126 + default: /* No repeat follows */
1.2127 + min = max = 1;
1.2128 + break;
1.2129 + }
1.2130 +
1.2131 + /* First, ensure the minimum number of matches are present. */
1.2132 +
1.2133 + for (i = 1; i <= min; i++)
1.2134 + {
1.2135 + if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
1.2136 + GETCHARINCTEST(c, eptr);
1.2137 + if (!_pcre_xclass(c, data)) RRETURN(MATCH_NOMATCH);
1.2138 + }
1.2139 +
1.2140 + /* If max == min we can continue with the main loop without the
1.2141 + need to recurse. */
1.2142 +
1.2143 + if (min == max) continue;
1.2144 +
1.2145 + /* If minimizing, keep testing the rest of the expression and advancing
1.2146 + the pointer while it matches the class. */
1.2147 +
1.2148 + if (minimize)
1.2149 + {
1.2150 + for (fi = min;; fi++)
1.2151 + {
1.2152 + RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM20);
1.2153 + if (rrc != MATCH_NOMATCH) RRETURN(rrc);
1.2154 + if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
1.2155 + GETCHARINCTEST(c, eptr);
1.2156 + if (!_pcre_xclass(c, data)) RRETURN(MATCH_NOMATCH);
1.2157 + }
1.2158 + /* Control never gets here */
1.2159 + }
1.2160 +
1.2161 + /* If maximizing, find the longest possible run, then work backwards. */
1.2162 +
1.2163 + else
1.2164 + {
1.2165 + pp = eptr;
1.2166 + for (i = min; i < max; i++)
1.2167 + {
1.2168 + int len = 1;
1.2169 + if (eptr >= md->end_subject) break;
1.2170 + GETCHARLENTEST(c, eptr, len);
1.2171 + if (!_pcre_xclass(c, data)) break;
1.2172 + eptr += len;
1.2173 + }
1.2174 + for(;;)
1.2175 + {
1.2176 + RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM21);
1.2177 + if (rrc != MATCH_NOMATCH) RRETURN(rrc);
1.2178 + if (eptr-- == pp) break; /* Stop if tried at original pos */
1.2179 + if (utf8) BACKCHAR(eptr);
1.2180 + }
1.2181 + RRETURN(MATCH_NOMATCH);
1.2182 + }
1.2183 +
1.2184 + /* Control never gets here */
1.2185 + }
1.2186 +#endif /* End of XCLASS */
1.2187 +
1.2188 + /* Match a single character, casefully */
1.2189 +
1.2190 + case OP_CHAR:
1.2191 +#ifdef SUPPORT_UTF8
1.2192 + if (utf8)
1.2193 + {
1.2194 + length = 1;
1.2195 + ecode++;
1.2196 + GETCHARLEN(fc, ecode, length);
1.2197 + if (length > md->end_subject - eptr) RRETURN(MATCH_NOMATCH);
1.2198 + while (length-- > 0) if (*ecode++ != *eptr++) RRETURN(MATCH_NOMATCH);
1.2199 + }
1.2200 + else
1.2201 +#endif
1.2202 +
1.2203 + /* Non-UTF-8 mode */
1.2204 + {
1.2205 + if (md->end_subject - eptr < 1) RRETURN(MATCH_NOMATCH);
1.2206 + if (ecode[1] != *eptr++) RRETURN(MATCH_NOMATCH);
1.2207 + ecode += 2;
1.2208 + }
1.2209 + break;
1.2210 +
1.2211 + /* Match a single character, caselessly */
1.2212 +
1.2213 + case OP_CHARNC:
1.2214 +#ifdef SUPPORT_UTF8
1.2215 + if (utf8)
1.2216 + {
1.2217 + length = 1;
1.2218 + ecode++;
1.2219 + GETCHARLEN(fc, ecode, length);
1.2220 +
1.2221 + if (length > md->end_subject - eptr) RRETURN(MATCH_NOMATCH);
1.2222 +
1.2223 + /* If the pattern character's value is < 128, we have only one byte, and
1.2224 + can use the fast lookup table. */
1.2225 +
1.2226 + if (fc < 128)
1.2227 + {
1.2228 + if (md->lcc[*ecode++] != md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH);
1.2229 + }
1.2230 +
1.2231 + /* Otherwise we must pick up the subject character */
1.2232 +
1.2233 + else
1.2234 + {
1.2235 + unsigned int dc;
1.2236 + GETCHARINC(dc, eptr);
1.2237 + ecode += length;
1.2238 +
1.2239 + /* If we have Unicode property support, we can use it to test the other
1.2240 + case of the character, if there is one. */
1.2241 +
1.2242 + if (fc != dc)
1.2243 + {
1.2244 +#ifdef SUPPORT_UCP
1.2245 + if (dc != UCD_OTHERCASE(fc))
1.2246 +#endif
1.2247 + RRETURN(MATCH_NOMATCH);
1.2248 + }
1.2249 + }
1.2250 + }
1.2251 + else
1.2252 +#endif /* SUPPORT_UTF8 */
1.2253 +
1.2254 + /* Non-UTF-8 mode */
1.2255 + {
1.2256 + if (md->end_subject - eptr < 1) RRETURN(MATCH_NOMATCH);
1.2257 + if (md->lcc[ecode[1]] != md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH);
1.2258 + ecode += 2;
1.2259 + }
1.2260 + break;
1.2261 +
1.2262 + /* Match a single character repeatedly. */
1.2263 +
1.2264 + case OP_EXACT:
1.2265 + min = max = GET2(ecode, 1);
1.2266 + ecode += 3;
1.2267 + goto REPEATCHAR;
1.2268 +
1.2269 + case OP_POSUPTO:
1.2270 + possessive = TRUE;
1.2271 + /* Fall through */
1.2272 +
1.2273 + case OP_UPTO:
1.2274 + case OP_MINUPTO:
1.2275 + min = 0;
1.2276 + max = GET2(ecode, 1);
1.2277 + minimize = *ecode == OP_MINUPTO;
1.2278 + ecode += 3;
1.2279 + goto REPEATCHAR;
1.2280 +
1.2281 + case OP_POSSTAR:
1.2282 + possessive = TRUE;
1.2283 + min = 0;
1.2284 + max = INT_MAX;
1.2285 + ecode++;
1.2286 + goto REPEATCHAR;
1.2287 +
1.2288 + case OP_POSPLUS:
1.2289 + possessive = TRUE;
1.2290 + min = 1;
1.2291 + max = INT_MAX;
1.2292 + ecode++;
1.2293 + goto REPEATCHAR;
1.2294 +
1.2295 + case OP_POSQUERY:
1.2296 + possessive = TRUE;
1.2297 + min = 0;
1.2298 + max = 1;
1.2299 + ecode++;
1.2300 + goto REPEATCHAR;
1.2301 +
1.2302 + case OP_STAR:
1.2303 + case OP_MINSTAR:
1.2304 + case OP_PLUS:
1.2305 + case OP_MINPLUS:
1.2306 + case OP_QUERY:
1.2307 + case OP_MINQUERY:
1.2308 + c = *ecode++ - OP_STAR;
1.2309 + minimize = (c & 1) != 0;
1.2310 + min = rep_min[c]; /* Pick up values from tables; */
1.2311 + max = rep_max[c]; /* zero for max => infinity */
1.2312 + if (max == 0) max = INT_MAX;
1.2313 +
1.2314 + /* Common code for all repeated single-character matches. We can give
1.2315 + up quickly if there are fewer than the minimum number of characters left in
1.2316 + the subject. */
1.2317 +
1.2318 + REPEATCHAR:
1.2319 +#ifdef SUPPORT_UTF8
1.2320 + if (utf8)
1.2321 + {
1.2322 + length = 1;
1.2323 + charptr = ecode;
1.2324 + GETCHARLEN(fc, ecode, length);
1.2325 + if (min * length > md->end_subject - eptr) RRETURN(MATCH_NOMATCH);
1.2326 + ecode += length;
1.2327 +
1.2328 + /* Handle multibyte character matching specially here. There is
1.2329 + support for caseless matching if UCP support is present. */
1.2330 +
1.2331 + if (length > 1)
1.2332 + {
1.2333 +#ifdef SUPPORT_UCP
1.2334 + unsigned int othercase;
1.2335 + if ((ims & PCRE_CASELESS) != 0 &&
1.2336 + (othercase = UCD_OTHERCASE(fc)) != fc)
1.2337 + oclength = _pcre_ord2utf8(othercase, occhars);
1.2338 + else oclength = 0;
1.2339 +#endif /* SUPPORT_UCP */
1.2340 +
1.2341 + for (i = 1; i <= min; i++)
1.2342 + {
1.2343 + if (memcmp(eptr, charptr, length) == 0) eptr += length;
1.2344 +#ifdef SUPPORT_UCP
1.2345 + /* Need braces because of following else */
1.2346 + else if (oclength == 0) { RRETURN(MATCH_NOMATCH); }
1.2347 + else
1.2348 + {
1.2349 + if (memcmp(eptr, occhars, oclength) != 0) RRETURN(MATCH_NOMATCH);
1.2350 + eptr += oclength;
1.2351 + }
1.2352 +#else /* without SUPPORT_UCP */
1.2353 + else { RRETURN(MATCH_NOMATCH); }
1.2354 +#endif /* SUPPORT_UCP */
1.2355 + }
1.2356 +
1.2357 + if (min == max) continue;
1.2358 +
1.2359 + if (minimize)
1.2360 + {
1.2361 + for (fi = min;; fi++)
1.2362 + {
1.2363 + RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM22);
1.2364 + if (rrc != MATCH_NOMATCH) RRETURN(rrc);
1.2365 + if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
1.2366 + if (memcmp(eptr, charptr, length) == 0) eptr += length;
1.2367 +#ifdef SUPPORT_UCP
1.2368 + /* Need braces because of following else */
1.2369 + else if (oclength == 0) { RRETURN(MATCH_NOMATCH); }
1.2370 + else
1.2371 + {
1.2372 + if (memcmp(eptr, occhars, oclength) != 0) RRETURN(MATCH_NOMATCH);
1.2373 + eptr += oclength;
1.2374 + }
1.2375 +#else /* without SUPPORT_UCP */
1.2376 + else { RRETURN (MATCH_NOMATCH); }
1.2377 +#endif /* SUPPORT_UCP */
1.2378 + }
1.2379 + /* Control never gets here */
1.2380 + }
1.2381 +
1.2382 + else /* Maximize */
1.2383 + {
1.2384 + pp = eptr;
1.2385 + for (i = min; i < max; i++)
1.2386 + {
1.2387 + if (eptr > md->end_subject - length) break;
1.2388 + if (memcmp(eptr, charptr, length) == 0) eptr += length;
1.2389 +#ifdef SUPPORT_UCP
1.2390 + else if (oclength == 0) break;
1.2391 + else
1.2392 + {
1.2393 + if (memcmp(eptr, occhars, oclength) != 0) break;
1.2394 + eptr += oclength;
1.2395 + }
1.2396 +#else /* without SUPPORT_UCP */
1.2397 + else break;
1.2398 +#endif /* SUPPORT_UCP */
1.2399 + }
1.2400 +
1.2401 + if (possessive) continue;
1.2402 + for(;;)
1.2403 + {
1.2404 + RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM23);
1.2405 + if (rrc != MATCH_NOMATCH) RRETURN(rrc);
1.2406 + if (eptr == pp) RRETURN(MATCH_NOMATCH);
1.2407 +#ifdef SUPPORT_UCP
1.2408 + eptr--;
1.2409 + BACKCHAR(eptr);
1.2410 +#else /* without SUPPORT_UCP */
1.2411 + eptr -= length;
1.2412 +#endif /* SUPPORT_UCP */
1.2413 + }
1.2414 + }
1.2415 + /* Control never gets here */
1.2416 + }
1.2417 +
1.2418 + /* If the length of a UTF-8 character is 1, we fall through here, and
1.2419 + obey the code as for non-UTF-8 characters below, though in this case the
1.2420 + value of fc will always be < 128. */
1.2421 + }
1.2422 + else
1.2423 +#endif /* SUPPORT_UTF8 */
1.2424 +
1.2425 + /* When not in UTF-8 mode, load a single-byte character. */
1.2426 + {
1.2427 + if (min > md->end_subject - eptr) RRETURN(MATCH_NOMATCH);
1.2428 + fc = *ecode++;
1.2429 + }
1.2430 +
1.2431 + /* The value of fc at this point is always less than 256, though we may or
1.2432 + may not be in UTF-8 mode. The code is duplicated for the caseless and
1.2433 + caseful cases, for speed, since matching characters is likely to be quite
1.2434 + common. First, ensure the minimum number of matches are present. If min =
1.2435 + max, continue at the same level without recursing. Otherwise, if
1.2436 + minimizing, keep trying the rest of the expression and advancing one
1.2437 + matching character if failing, up to the maximum. Alternatively, if
1.2438 + maximizing, find the maximum number of characters and work backwards. */
1.2439 +
1.2440 + DPRINTF(("matching %c{%d,%d} against subject %.*s\n", fc, min, max,
1.2441 + max, eptr));
1.2442 +
1.2443 + if ((ims & PCRE_CASELESS) != 0)
1.2444 + {
1.2445 + fc = md->lcc[fc];
1.2446 + for (i = 1; i <= min; i++)
1.2447 + if (fc != md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH);
1.2448 + if (min == max) continue;
1.2449 + if (minimize)
1.2450 + {
1.2451 + for (fi = min;; fi++)
1.2452 + {
1.2453 + RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM24);
1.2454 + if (rrc != MATCH_NOMATCH) RRETURN(rrc);
1.2455 + if (fi >= max || eptr >= md->end_subject ||
1.2456 + fc != md->lcc[*eptr++])
1.2457 + RRETURN(MATCH_NOMATCH);
1.2458 + }
1.2459 + /* Control never gets here */
1.2460 + }
1.2461 + else /* Maximize */
1.2462 + {
1.2463 + pp = eptr;
1.2464 + for (i = min; i < max; i++)
1.2465 + {
1.2466 + if (eptr >= md->end_subject || fc != md->lcc[*eptr]) break;
1.2467 + eptr++;
1.2468 + }
1.2469 + if (possessive) continue;
1.2470 + while (eptr >= pp)
1.2471 + {
1.2472 + RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM25);
1.2473 + eptr--;
1.2474 + if (rrc != MATCH_NOMATCH) RRETURN(rrc);
1.2475 + }
1.2476 + RRETURN(MATCH_NOMATCH);
1.2477 + }
1.2478 + /* Control never gets here */
1.2479 + }
1.2480 +
1.2481 + /* Caseful comparisons (includes all multi-byte characters) */
1.2482 +
1.2483 + else
1.2484 + {
1.2485 + for (i = 1; i <= min; i++) if (fc != *eptr++) RRETURN(MATCH_NOMATCH);
1.2486 + if (min == max) continue;
1.2487 + if (minimize)
1.2488 + {
1.2489 + for (fi = min;; fi++)
1.2490 + {
1.2491 + RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM26);
1.2492 + if (rrc != MATCH_NOMATCH) RRETURN(rrc);
1.2493 + if (fi >= max || eptr >= md->end_subject || fc != *eptr++)
1.2494 + RRETURN(MATCH_NOMATCH);
1.2495 + }
1.2496 + /* Control never gets here */
1.2497 + }
1.2498 + else /* Maximize */
1.2499 + {
1.2500 + pp = eptr;
1.2501 + for (i = min; i < max; i++)
1.2502 + {
1.2503 + if (eptr >= md->end_subject || fc != *eptr) break;
1.2504 + eptr++;
1.2505 + }
1.2506 + if (possessive) continue;
1.2507 + while (eptr >= pp)
1.2508 + {
1.2509 + RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM27);
1.2510 + eptr--;
1.2511 + if (rrc != MATCH_NOMATCH) RRETURN(rrc);
1.2512 + }
1.2513 + RRETURN(MATCH_NOMATCH);
1.2514 + }
1.2515 + }
1.2516 + /* Control never gets here */
1.2517 +
1.2518 + /* Match a negated single one-byte character. The character we are
1.2519 + checking can be multibyte. */
1.2520 +
1.2521 + case OP_NOT:
1.2522 + if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
1.2523 + ecode++;
1.2524 + GETCHARINCTEST(c, eptr);
1.2525 + if ((ims & PCRE_CASELESS) != 0)
1.2526 + {
1.2527 +#ifdef SUPPORT_UTF8
1.2528 + if (c < 256)
1.2529 +#endif
1.2530 + c = md->lcc[c];
1.2531 + if (md->lcc[*ecode++] == c) RRETURN(MATCH_NOMATCH);
1.2532 + }
1.2533 + else
1.2534 + {
1.2535 + if (*ecode++ == c) RRETURN(MATCH_NOMATCH);
1.2536 + }
1.2537 + break;
1.2538 +
1.2539 + /* Match a negated single one-byte character repeatedly. This is almost a
1.2540 + repeat of the code for a repeated single character, but I haven't found a
1.2541 + nice way of commoning these up that doesn't require a test of the
1.2542 + positive/negative option for each character match. Maybe that wouldn't add
1.2543 + very much to the time taken, but character matching *is* what this is all
1.2544 + about... */
1.2545 +
1.2546 + case OP_NOTEXACT:
1.2547 + min = max = GET2(ecode, 1);
1.2548 + ecode += 3;
1.2549 + goto REPEATNOTCHAR;
1.2550 +
1.2551 + case OP_NOTUPTO:
1.2552 + case OP_NOTMINUPTO:
1.2553 + min = 0;
1.2554 + max = GET2(ecode, 1);
1.2555 + minimize = *ecode == OP_NOTMINUPTO;
1.2556 + ecode += 3;
1.2557 + goto REPEATNOTCHAR;
1.2558 +
1.2559 + case OP_NOTPOSSTAR:
1.2560 + possessive = TRUE;
1.2561 + min = 0;
1.2562 + max = INT_MAX;
1.2563 + ecode++;
1.2564 + goto REPEATNOTCHAR;
1.2565 +
1.2566 + case OP_NOTPOSPLUS:
1.2567 + possessive = TRUE;
1.2568 + min = 1;
1.2569 + max = INT_MAX;
1.2570 + ecode++;
1.2571 + goto REPEATNOTCHAR;
1.2572 +
1.2573 + case OP_NOTPOSQUERY:
1.2574 + possessive = TRUE;
1.2575 + min = 0;
1.2576 + max = 1;
1.2577 + ecode++;
1.2578 + goto REPEATNOTCHAR;
1.2579 +
1.2580 + case OP_NOTPOSUPTO:
1.2581 + possessive = TRUE;
1.2582 + min = 0;
1.2583 + max = GET2(ecode, 1);
1.2584 + ecode += 3;
1.2585 + goto REPEATNOTCHAR;
1.2586 +
1.2587 + case OP_NOTSTAR:
1.2588 + case OP_NOTMINSTAR:
1.2589 + case OP_NOTPLUS:
1.2590 + case OP_NOTMINPLUS:
1.2591 + case OP_NOTQUERY:
1.2592 + case OP_NOTMINQUERY:
1.2593 + c = *ecode++ - OP_NOTSTAR;
1.2594 + minimize = (c & 1) != 0;
1.2595 + min = rep_min[c]; /* Pick up values from tables; */
1.2596 + max = rep_max[c]; /* zero for max => infinity */
1.2597 + if (max == 0) max = INT_MAX;
1.2598 +
1.2599 + /* Common code for all repeated single-byte matches. We can give up quickly
1.2600 + if there are fewer than the minimum number of bytes left in the
1.2601 + subject. */
1.2602 +
1.2603 + REPEATNOTCHAR:
1.2604 + if (min > md->end_subject - eptr) RRETURN(MATCH_NOMATCH);
1.2605 + fc = *ecode++;
1.2606 +
1.2607 + /* The code is duplicated for the caseless and caseful cases, for speed,
1.2608 + since matching characters is likely to be quite common. First, ensure the
1.2609 + minimum number of matches are present. If min = max, continue at the same
1.2610 + level without recursing. Otherwise, if minimizing, keep trying the rest of
1.2611 + the expression and advancing one matching character if failing, up to the
1.2612 + maximum. Alternatively, if maximizing, find the maximum number of
1.2613 + characters and work backwards. */
1.2614 +
1.2615 + DPRINTF(("negative matching %c{%d,%d} against subject %.*s\n", fc, min, max,
1.2616 + max, eptr));
1.2617 +
1.2618 + if ((ims & PCRE_CASELESS) != 0)
1.2619 + {
1.2620 + fc = md->lcc[fc];
1.2621 +
1.2622 +#ifdef SUPPORT_UTF8
1.2623 + /* UTF-8 mode */
1.2624 + if (utf8)
1.2625 + {
1.2626 + register unsigned int d;
1.2627 + for (i = 1; i <= min; i++)
1.2628 + {
1.2629 + GETCHARINC(d, eptr);
1.2630 + if (d < 256) d = md->lcc[d];
1.2631 + if (fc == d) RRETURN(MATCH_NOMATCH);
1.2632 + }
1.2633 + }
1.2634 + else
1.2635 +#endif
1.2636 +
1.2637 + /* Not UTF-8 mode */
1.2638 + {
1.2639 + for (i = 1; i <= min; i++)
1.2640 + if (fc == md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH);
1.2641 + }
1.2642 +
1.2643 + if (min == max) continue;
1.2644 +
1.2645 + if (minimize)
1.2646 + {
1.2647 +#ifdef SUPPORT_UTF8
1.2648 + /* UTF-8 mode */
1.2649 + if (utf8)
1.2650 + {
1.2651 + register unsigned int d;
1.2652 + for (fi = min;; fi++)
1.2653 + {
1.2654 + RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM28);
1.2655 + if (rrc != MATCH_NOMATCH) RRETURN(rrc);
1.2656 + if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
1.2657 + GETCHARINC(d, eptr);
1.2658 + if (d < 256) d = md->lcc[d];
1.2659 + if (fc == d) RRETURN(MATCH_NOMATCH);
1.2660 +
1.2661 + }
1.2662 + }
1.2663 + else
1.2664 +#endif
1.2665 + /* Not UTF-8 mode */
1.2666 + {
1.2667 + for (fi = min;; fi++)
1.2668 + {
1.2669 + RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM29);
1.2670 + if (rrc != MATCH_NOMATCH) RRETURN(rrc);
1.2671 + if (fi >= max || eptr >= md->end_subject || fc == md->lcc[*eptr++])
1.2672 + RRETURN(MATCH_NOMATCH);
1.2673 + }
1.2674 + }
1.2675 + /* Control never gets here */
1.2676 + }
1.2677 +
1.2678 + /* Maximize case */
1.2679 +
1.2680 + else
1.2681 + {
1.2682 + pp = eptr;
1.2683 +
1.2684 +#ifdef SUPPORT_UTF8
1.2685 + /* UTF-8 mode */
1.2686 + if (utf8)
1.2687 + {
1.2688 + register unsigned int d;
1.2689 + for (i = min; i < max; i++)
1.2690 + {
1.2691 + int len = 1;
1.2692 + if (eptr >= md->end_subject) break;
1.2693 + GETCHARLEN(d, eptr, len);
1.2694 + if (d < 256) d = md->lcc[d];
1.2695 + if (fc == d) break;
1.2696 + eptr += len;
1.2697 + }
1.2698 + if (possessive) continue;
1.2699 + for(;;)
1.2700 + {
1.2701 + RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM30);
1.2702 + if (rrc != MATCH_NOMATCH) RRETURN(rrc);
1.2703 + if (eptr-- == pp) break; /* Stop if tried at original pos */
1.2704 + BACKCHAR(eptr);
1.2705 + }
1.2706 + }
1.2707 + else
1.2708 +#endif
1.2709 + /* Not UTF-8 mode */
1.2710 + {
1.2711 + for (i = min; i < max; i++)
1.2712 + {
1.2713 + if (eptr >= md->end_subject || fc == md->lcc[*eptr]) break;
1.2714 + eptr++;
1.2715 + }
1.2716 + if (possessive) continue;
1.2717 + while (eptr >= pp)
1.2718 + {
1.2719 + RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM31);
1.2720 + if (rrc != MATCH_NOMATCH) RRETURN(rrc);
1.2721 + eptr--;
1.2722 + }
1.2723 + }
1.2724 +
1.2725 + RRETURN(MATCH_NOMATCH);
1.2726 + }
1.2727 + /* Control never gets here */
1.2728 + }
1.2729 +
1.2730 + /* Caseful comparisons */
1.2731 +
1.2732 + else
1.2733 + {
1.2734 +#ifdef SUPPORT_UTF8
1.2735 + /* UTF-8 mode */
1.2736 + if (utf8)
1.2737 + {
1.2738 + register unsigned int d;
1.2739 + for (i = 1; i <= min; i++)
1.2740 + {
1.2741 + GETCHARINC(d, eptr);
1.2742 + if (fc == d) RRETURN(MATCH_NOMATCH);
1.2743 + }
1.2744 + }
1.2745 + else
1.2746 +#endif
1.2747 + /* Not UTF-8 mode */
1.2748 + {
1.2749 + for (i = 1; i <= min; i++)
1.2750 + if (fc == *eptr++) RRETURN(MATCH_NOMATCH);
1.2751 + }
1.2752 +
1.2753 + if (min == max) continue;
1.2754 +
1.2755 + if (minimize)
1.2756 + {
1.2757 +#ifdef SUPPORT_UTF8
1.2758 + /* UTF-8 mode */
1.2759 + if (utf8)
1.2760 + {
1.2761 + register unsigned int d;
1.2762 + for (fi = min;; fi++)
1.2763 + {
1.2764 + RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM32);
1.2765 + if (rrc != MATCH_NOMATCH) RRETURN(rrc);
1.2766 + if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
1.2767 + GETCHARINC(d, eptr);
1.2768 + if (fc == d) RRETURN(MATCH_NOMATCH);
1.2769 + }
1.2770 + }
1.2771 + else
1.2772 +#endif
1.2773 + /* Not UTF-8 mode */
1.2774 + {
1.2775 + for (fi = min;; fi++)
1.2776 + {
1.2777 + RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM33);
1.2778 + if (rrc != MATCH_NOMATCH) RRETURN(rrc);
1.2779 + if (fi >= max || eptr >= md->end_subject || fc == *eptr++)
1.2780 + RRETURN(MATCH_NOMATCH);
1.2781 + }
1.2782 + }
1.2783 + /* Control never gets here */
1.2784 + }
1.2785 +
1.2786 + /* Maximize case */
1.2787 +
1.2788 + else
1.2789 + {
1.2790 + pp = eptr;
1.2791 +
1.2792 +#ifdef SUPPORT_UTF8
1.2793 + /* UTF-8 mode */
1.2794 + if (utf8)
1.2795 + {
1.2796 + register unsigned int d;
1.2797 + for (i = min; i < max; i++)
1.2798 + {
1.2799 + int len = 1;
1.2800 + if (eptr >= md->end_subject) break;
1.2801 + GETCHARLEN(d, eptr, len);
1.2802 + if (fc == d) break;
1.2803 + eptr += len;
1.2804 + }
1.2805 + if (possessive) continue;
1.2806 + for(;;)
1.2807 + {
1.2808 + RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM34);
1.2809 + if (rrc != MATCH_NOMATCH) RRETURN(rrc);
1.2810 + if (eptr-- == pp) break; /* Stop if tried at original pos */
1.2811 + BACKCHAR(eptr);
1.2812 + }
1.2813 + }
1.2814 + else
1.2815 +#endif
1.2816 + /* Not UTF-8 mode */
1.2817 + {
1.2818 + for (i = min; i < max; i++)
1.2819 + {
1.2820 + if (eptr >= md->end_subject || fc == *eptr) break;
1.2821 + eptr++;
1.2822 + }
1.2823 + if (possessive) continue;
1.2824 + while (eptr >= pp)
1.2825 + {
1.2826 + RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM35);
1.2827 + if (rrc != MATCH_NOMATCH) RRETURN(rrc);
1.2828 + eptr--;
1.2829 + }
1.2830 + }
1.2831 +
1.2832 + RRETURN(MATCH_NOMATCH);
1.2833 + }
1.2834 + }
1.2835 + /* Control never gets here */
1.2836 +
1.2837 + /* Match a single character type repeatedly; several different opcodes
1.2838 + share code. This is very similar to the code for single characters, but we
1.2839 + repeat it in the interests of efficiency. */
1.2840 +
1.2841 + case OP_TYPEEXACT:
1.2842 + min = max = GET2(ecode, 1);
1.2843 + minimize = TRUE;
1.2844 + ecode += 3;
1.2845 + goto REPEATTYPE;
1.2846 +
1.2847 + case OP_TYPEUPTO:
1.2848 + case OP_TYPEMINUPTO:
1.2849 + min = 0;
1.2850 + max = GET2(ecode, 1);
1.2851 + minimize = *ecode == OP_TYPEMINUPTO;
1.2852 + ecode += 3;
1.2853 + goto REPEATTYPE;
1.2854 +
1.2855 + case OP_TYPEPOSSTAR:
1.2856 + possessive = TRUE;
1.2857 + min = 0;
1.2858 + max = INT_MAX;
1.2859 + ecode++;
1.2860 + goto REPEATTYPE;
1.2861 +
1.2862 + case OP_TYPEPOSPLUS:
1.2863 + possessive = TRUE;
1.2864 + min = 1;
1.2865 + max = INT_MAX;
1.2866 + ecode++;
1.2867 + goto REPEATTYPE;
1.2868 +
1.2869 + case OP_TYPEPOSQUERY:
1.2870 + possessive = TRUE;
1.2871 + min = 0;
1.2872 + max = 1;
1.2873 + ecode++;
1.2874 + goto REPEATTYPE;
1.2875 +
1.2876 + case OP_TYPEPOSUPTO:
1.2877 + possessive = TRUE;
1.2878 + min = 0;
1.2879 + max = GET2(ecode, 1);
1.2880 + ecode += 3;
1.2881 + goto REPEATTYPE;
1.2882 +
1.2883 + case OP_TYPESTAR:
1.2884 + case OP_TYPEMINSTAR:
1.2885 + case OP_TYPEPLUS:
1.2886 + case OP_TYPEMINPLUS:
1.2887 + case OP_TYPEQUERY:
1.2888 + case OP_TYPEMINQUERY:
1.2889 + c = *ecode++ - OP_TYPESTAR;
1.2890 + minimize = (c & 1) != 0;
1.2891 + min = rep_min[c]; /* Pick up values from tables; */
1.2892 + max = rep_max[c]; /* zero for max => infinity */
1.2893 + if (max == 0) max = INT_MAX;
1.2894 +
1.2895 + /* Common code for all repeated single character type matches. Note that
1.2896 + in UTF-8 mode, '.' matches a character of any length, but for the other
1.2897 + character types, the valid characters are all one-byte long. */
1.2898 +
1.2899 + REPEATTYPE:
1.2900 + ctype = *ecode++; /* Code for the character type */
1.2901 +
1.2902 +#ifdef SUPPORT_UCP
1.2903 + if (ctype == OP_PROP || ctype == OP_NOTPROP)
1.2904 + {
1.2905 + prop_fail_result = ctype == OP_NOTPROP;
1.2906 + prop_type = *ecode++;
1.2907 + prop_value = *ecode++;
1.2908 + }
1.2909 + else prop_type = -1;
1.2910 +#endif
1.2911 +
1.2912 + /* First, ensure the minimum number of matches are present. Use inline
1.2913 + code for maximizing the speed, and do the type test once at the start
1.2914 + (i.e. keep it out of the loop). Also we can test that there are at least
1.2915 + the minimum number of bytes before we start. This isn't as effective in
1.2916 + UTF-8 mode, but it does no harm. Separate the UTF-8 code completely as that
1.2917 + is tidier. Also separate the UCP code, which can be the same for both UTF-8
1.2918 + and single-bytes. */
1.2919 +
1.2920 + if (min > md->end_subject - eptr) RRETURN(MATCH_NOMATCH);
1.2921 + if (min > 0)
1.2922 + {
1.2923 +#ifdef SUPPORT_UCP
1.2924 + if (prop_type >= 0)
1.2925 + {
1.2926 + switch(prop_type)
1.2927 + {
1.2928 + case PT_ANY:
1.2929 + if (prop_fail_result) RRETURN(MATCH_NOMATCH);
1.2930 + for (i = 1; i <= min; i++)
1.2931 + {
1.2932 + if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
1.2933 + GETCHARINCTEST(c, eptr);
1.2934 + }
1.2935 + break;
1.2936 +
1.2937 + case PT_LAMP:
1.2938 + for (i = 1; i <= min; i++)
1.2939 + {
1.2940 + if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
1.2941 + GETCHARINCTEST(c, eptr);
1.2942 + prop_chartype = UCD_CHARTYPE(c);
1.2943 + if ((prop_chartype == ucp_Lu ||
1.2944 + prop_chartype == ucp_Ll ||
1.2945 + prop_chartype == ucp_Lt) == prop_fail_result)
1.2946 + RRETURN(MATCH_NOMATCH);
1.2947 + }
1.2948 + break;
1.2949 +
1.2950 + case PT_GC:
1.2951 + for (i = 1; i <= min; i++)
1.2952 + {
1.2953 + if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
1.2954 + GETCHARINCTEST(c, eptr);
1.2955 + prop_category = UCD_CATEGORY(c);
1.2956 + if ((prop_category == prop_value) == prop_fail_result)
1.2957 + RRETURN(MATCH_NOMATCH);
1.2958 + }
1.2959 + break;
1.2960 +
1.2961 + case PT_PC:
1.2962 + for (i = 1; i <= min; i++)
1.2963 + {
1.2964 + if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
1.2965 + GETCHARINCTEST(c, eptr);
1.2966 + prop_chartype = UCD_CHARTYPE(c);
1.2967 + if ((prop_chartype == prop_value) == prop_fail_result)
1.2968 + RRETURN(MATCH_NOMATCH);
1.2969 + }
1.2970 + break;
1.2971 +
1.2972 + case PT_SC:
1.2973 + for (i = 1; i <= min; i++)
1.2974 + {
1.2975 + if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
1.2976 + GETCHARINCTEST(c, eptr);
1.2977 + prop_script = UCD_SCRIPT(c);
1.2978 + if ((prop_script == prop_value) == prop_fail_result)
1.2979 + RRETURN(MATCH_NOMATCH);
1.2980 + }
1.2981 + break;
1.2982 +
1.2983 + default:
1.2984 + RRETURN(PCRE_ERROR_INTERNAL);
1.2985 + }
1.2986 + }
1.2987 +
1.2988 + /* Match extended Unicode sequences. We will get here only if the
1.2989 + support is in the binary; otherwise a compile-time error occurs. */
1.2990 +
1.2991 + else if (ctype == OP_EXTUNI)
1.2992 + {
1.2993 + for (i = 1; i <= min; i++)
1.2994 + {
1.2995 + GETCHARINCTEST(c, eptr);
1.2996 + prop_category = UCD_CATEGORY(c);
1.2997 + if (prop_category == ucp_M) RRETURN(MATCH_NOMATCH);
1.2998 + while (eptr < md->end_subject)
1.2999 + {
1.3000 + int len = 1;
1.3001 + if (!utf8) c = *eptr; else
1.3002 + {
1.3003 + GETCHARLEN(c, eptr, len);
1.3004 + }
1.3005 + prop_category = UCD_CATEGORY(c);
1.3006 + if (prop_category != ucp_M) break;
1.3007 + eptr += len;
1.3008 + }
1.3009 + }
1.3010 + }
1.3011 +
1.3012 + else
1.3013 +#endif /* SUPPORT_UCP */
1.3014 +
1.3015 +/* Handle all other cases when the coding is UTF-8 */
1.3016 +
1.3017 +#ifdef SUPPORT_UTF8
1.3018 + if (utf8) switch(ctype)
1.3019 + {
1.3020 + case OP_ANY:
1.3021 + for (i = 1; i <= min; i++)
1.3022 + {
1.3023 + if (eptr >= md->end_subject || IS_NEWLINE(eptr))
1.3024 + RRETURN(MATCH_NOMATCH);
1.3025 + eptr++;
1.3026 + while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;
1.3027 + }
1.3028 + break;
1.3029 +
1.3030 + case OP_ALLANY:
1.3031 + for (i = 1; i <= min; i++)
1.3032 + {
1.3033 + if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
1.3034 + eptr++;
1.3035 + while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;
1.3036 + }
1.3037 + break;
1.3038 +
1.3039 + case OP_ANYBYTE:
1.3040 + eptr += min;
1.3041 + break;
1.3042 +
1.3043 + case OP_ANYNL:
1.3044 + for (i = 1; i <= min; i++)
1.3045 + {
1.3046 + if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
1.3047 + GETCHARINC(c, eptr);
1.3048 + switch(c)
1.3049 + {
1.3050 + default: RRETURN(MATCH_NOMATCH);
1.3051 + case 0x000d:
1.3052 + if (eptr < md->end_subject && *eptr == 0x0a) eptr++;
1.3053 + break;
1.3054 +
1.3055 + case 0x000a:
1.3056 + break;
1.3057 +
1.3058 + case 0x000b:
1.3059 + case 0x000c:
1.3060 + case 0x0085:
1.3061 + case 0x2028:
1.3062 + case 0x2029:
1.3063 + if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH);
1.3064 + break;
1.3065 + }
1.3066 + }
1.3067 + break;
1.3068 +
1.3069 + case OP_NOT_HSPACE:
1.3070 + for (i = 1; i <= min; i++)
1.3071 + {
1.3072 + if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
1.3073 + GETCHARINC(c, eptr);
1.3074 + switch(c)
1.3075 + {
1.3076 + default: break;
1.3077 + case 0x09: /* HT */
1.3078 + case 0x20: /* SPACE */
1.3079 + case 0xa0: /* NBSP */
1.3080 + case 0x1680: /* OGHAM SPACE MARK */
1.3081 + case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */
1.3082 + case 0x2000: /* EN QUAD */
1.3083 + case 0x2001: /* EM QUAD */
1.3084 + case 0x2002: /* EN SPACE */
1.3085 + case 0x2003: /* EM SPACE */
1.3086 + case 0x2004: /* THREE-PER-EM SPACE */
1.3087 + case 0x2005: /* FOUR-PER-EM SPACE */
1.3088 + case 0x2006: /* SIX-PER-EM SPACE */
1.3089 + case 0x2007: /* FIGURE SPACE */
1.3090 + case 0x2008: /* PUNCTUATION SPACE */
1.3091 + case 0x2009: /* THIN SPACE */
1.3092 + case 0x200A: /* HAIR SPACE */
1.3093 + case 0x202f: /* NARROW NO-BREAK SPACE */
1.3094 + case 0x205f: /* MEDIUM MATHEMATICAL SPACE */
1.3095 + case 0x3000: /* IDEOGRAPHIC SPACE */
1.3096 + RRETURN(MATCH_NOMATCH);
1.3097 + }
1.3098 + }
1.3099 + break;
1.3100 +
1.3101 + case OP_HSPACE:
1.3102 + for (i = 1; i <= min; i++)
1.3103 + {
1.3104 + if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
1.3105 + GETCHARINC(c, eptr);
1.3106 + switch(c)
1.3107 + {
1.3108 + default: RRETURN(MATCH_NOMATCH);
1.3109 + case 0x09: /* HT */
1.3110 + case 0x20: /* SPACE */
1.3111 + case 0xa0: /* NBSP */
1.3112 + case 0x1680: /* OGHAM SPACE MARK */
1.3113 + case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */
1.3114 + case 0x2000: /* EN QUAD */
1.3115 + case 0x2001: /* EM QUAD */
1.3116 + case 0x2002: /* EN SPACE */
1.3117 + case 0x2003: /* EM SPACE */
1.3118 + case 0x2004: /* THREE-PER-EM SPACE */
1.3119 + case 0x2005: /* FOUR-PER-EM SPACE */
1.3120 + case 0x2006: /* SIX-PER-EM SPACE */
1.3121 + case 0x2007: /* FIGURE SPACE */
1.3122 + case 0x2008: /* PUNCTUATION SPACE */
1.3123 + case 0x2009: /* THIN SPACE */
1.3124 + case 0x200A: /* HAIR SPACE */
1.3125 + case 0x202f: /* NARROW NO-BREAK SPACE */
1.3126 + case 0x205f: /* MEDIUM MATHEMATICAL SPACE */
1.3127 + case 0x3000: /* IDEOGRAPHIC SPACE */
1.3128 + break;
1.3129 + }
1.3130 + }
1.3131 + break;
1.3132 +
1.3133 + case OP_NOT_VSPACE:
1.3134 + for (i = 1; i <= min; i++)
1.3135 + {
1.3136 + if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
1.3137 + GETCHARINC(c, eptr);
1.3138 + switch(c)
1.3139 + {
1.3140 + default: break;
1.3141 + case 0x0a: /* LF */
1.3142 + case 0x0b: /* VT */
1.3143 + case 0x0c: /* FF */
1.3144 + case 0x0d: /* CR */
1.3145 + case 0x85: /* NEL */
1.3146 + case 0x2028: /* LINE SEPARATOR */
1.3147 + case 0x2029: /* PARAGRAPH SEPARATOR */
1.3148 + RRETURN(MATCH_NOMATCH);
1.3149 + }
1.3150 + }
1.3151 + break;
1.3152 +
1.3153 + case OP_VSPACE:
1.3154 + for (i = 1; i <= min; i++)
1.3155 + {
1.3156 + if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
1.3157 + GETCHARINC(c, eptr);
1.3158 + switch(c)
1.3159 + {
1.3160 + default: RRETURN(MATCH_NOMATCH);
1.3161 + case 0x0a: /* LF */
1.3162 + case 0x0b: /* VT */
1.3163 + case 0x0c: /* FF */
1.3164 + case 0x0d: /* CR */
1.3165 + case 0x85: /* NEL */
1.3166 + case 0x2028: /* LINE SEPARATOR */
1.3167 + case 0x2029: /* PARAGRAPH SEPARATOR */
1.3168 + break;
1.3169 + }
1.3170 + }
1.3171 + break;
1.3172 +
1.3173 + case OP_NOT_DIGIT:
1.3174 + for (i = 1; i <= min; i++)
1.3175 + {
1.3176 + if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
1.3177 + GETCHARINC(c, eptr);
1.3178 + if (c < 128 && (md->ctypes[c] & ctype_digit) != 0)
1.3179 + RRETURN(MATCH_NOMATCH);
1.3180 + }
1.3181 + break;
1.3182 +
1.3183 + case OP_DIGIT:
1.3184 + for (i = 1; i <= min; i++)
1.3185 + {
1.3186 + if (eptr >= md->end_subject ||
1.3187 + *eptr >= 128 || (md->ctypes[*eptr++] & ctype_digit) == 0)
1.3188 + RRETURN(MATCH_NOMATCH);
1.3189 + /* No need to skip more bytes - we know it's a 1-byte character */
1.3190 + }
1.3191 + break;
1.3192 +
1.3193 + case OP_NOT_WHITESPACE:
1.3194 + for (i = 1; i <= min; i++)
1.3195 + {
1.3196 + if (eptr >= md->end_subject ||
1.3197 + (*eptr < 128 && (md->ctypes[*eptr] & ctype_space) != 0))
1.3198 + RRETURN(MATCH_NOMATCH);
1.3199 + while (++eptr < md->end_subject && (*eptr & 0xc0) == 0x80);
1.3200 + }
1.3201 + break;
1.3202 +
1.3203 + case OP_WHITESPACE:
1.3204 + for (i = 1; i <= min; i++)
1.3205 + {
1.3206 + if (eptr >= md->end_subject ||
1.3207 + *eptr >= 128 || (md->ctypes[*eptr++] & ctype_space) == 0)
1.3208 + RRETURN(MATCH_NOMATCH);
1.3209 + /* No need to skip more bytes - we know it's a 1-byte character */
1.3210 + }
1.3211 + break;
1.3212 +
1.3213 + case OP_NOT_WORDCHAR:
1.3214 + for (i = 1; i <= min; i++)
1.3215 + {
1.3216 + if (eptr >= md->end_subject ||
1.3217 + (*eptr < 128 && (md->ctypes[*eptr] & ctype_word) != 0))
1.3218 + RRETURN(MATCH_NOMATCH);
1.3219 + while (++eptr < md->end_subject && (*eptr & 0xc0) == 0x80);
1.3220 + }
1.3221 + break;
1.3222 +
1.3223 + case OP_WORDCHAR:
1.3224 + for (i = 1; i <= min; i++)
1.3225 + {
1.3226 + if (eptr >= md->end_subject ||
1.3227 + *eptr >= 128 || (md->ctypes[*eptr++] & ctype_word) == 0)
1.3228 + RRETURN(MATCH_NOMATCH);
1.3229 + /* No need to skip more bytes - we know it's a 1-byte character */
1.3230 + }
1.3231 + break;
1.3232 +
1.3233 + default:
1.3234 + RRETURN(PCRE_ERROR_INTERNAL);
1.3235 + } /* End switch(ctype) */
1.3236 +
1.3237 + else
1.3238 +#endif /* SUPPORT_UTF8 */
1.3239 +
1.3240 + /* Code for the non-UTF-8 case for minimum matching of operators other
1.3241 + than OP_PROP and OP_NOTPROP. We can assume that there are the minimum
1.3242 + number of bytes present, as this was tested above. */
1.3243 +
1.3244 + switch(ctype)
1.3245 + {
1.3246 + case OP_ANY:
1.3247 + for (i = 1; i <= min; i++)
1.3248 + {
1.3249 + if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH);
1.3250 + eptr++;
1.3251 + }
1.3252 + break;
1.3253 +
1.3254 + case OP_ALLANY:
1.3255 + eptr += min;
1.3256 + break;
1.3257 +
1.3258 + case OP_ANYBYTE:
1.3259 + eptr += min;
1.3260 + break;
1.3261 +
1.3262 + /* Because of the CRLF case, we can't assume the minimum number of
1.3263 + bytes are present in this case. */
1.3264 +
1.3265 + case OP_ANYNL:
1.3266 + for (i = 1; i <= min; i++)
1.3267 + {
1.3268 + if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
1.3269 + switch(*eptr++)
1.3270 + {
1.3271 + default: RRETURN(MATCH_NOMATCH);
1.3272 + case 0x000d:
1.3273 + if (eptr < md->end_subject && *eptr == 0x0a) eptr++;
1.3274 + break;
1.3275 + case 0x000a:
1.3276 + break;
1.3277 +
1.3278 + case 0x000b:
1.3279 + case 0x000c:
1.3280 + case 0x0085:
1.3281 + if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH);
1.3282 + break;
1.3283 + }
1.3284 + }
1.3285 + break;
1.3286 +
1.3287 + case OP_NOT_HSPACE:
1.3288 + for (i = 1; i <= min; i++)
1.3289 + {
1.3290 + if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
1.3291 + switch(*eptr++)
1.3292 + {
1.3293 + default: break;
1.3294 + case 0x09: /* HT */
1.3295 + case 0x20: /* SPACE */
1.3296 + case 0xa0: /* NBSP */
1.3297 + RRETURN(MATCH_NOMATCH);
1.3298 + }
1.3299 + }
1.3300 + break;
1.3301 +
1.3302 + case OP_HSPACE:
1.3303 + for (i = 1; i <= min; i++)
1.3304 + {
1.3305 + if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
1.3306 + switch(*eptr++)
1.3307 + {
1.3308 + default: RRETURN(MATCH_NOMATCH);
1.3309 + case 0x09: /* HT */
1.3310 + case 0x20: /* SPACE */
1.3311 + case 0xa0: /* NBSP */
1.3312 + break;
1.3313 + }
1.3314 + }
1.3315 + break;
1.3316 +
1.3317 + case OP_NOT_VSPACE:
1.3318 + for (i = 1; i <= min; i++)
1.3319 + {
1.3320 + if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
1.3321 + switch(*eptr++)
1.3322 + {
1.3323 + default: break;
1.3324 + case 0x0a: /* LF */
1.3325 + case 0x0b: /* VT */
1.3326 + case 0x0c: /* FF */
1.3327 + case 0x0d: /* CR */
1.3328 + case 0x85: /* NEL */
1.3329 + RRETURN(MATCH_NOMATCH);
1.3330 + }
1.3331 + }
1.3332 + break;
1.3333 +
1.3334 + case OP_VSPACE:
1.3335 + for (i = 1; i <= min; i++)
1.3336 + {
1.3337 + if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
1.3338 + switch(*eptr++)
1.3339 + {
1.3340 + default: RRETURN(MATCH_NOMATCH);
1.3341 + case 0x0a: /* LF */
1.3342 + case 0x0b: /* VT */
1.3343 + case 0x0c: /* FF */
1.3344 + case 0x0d: /* CR */
1.3345 + case 0x85: /* NEL */
1.3346 + break;
1.3347 + }
1.3348 + }
1.3349 + break;
1.3350 +
1.3351 + case OP_NOT_DIGIT:
1.3352 + for (i = 1; i <= min; i++)
1.3353 + if ((md->ctypes[*eptr++] & ctype_digit) != 0) RRETURN(MATCH_NOMATCH);
1.3354 + break;
1.3355 +
1.3356 + case OP_DIGIT:
1.3357 + for (i = 1; i <= min; i++)
1.3358 + if ((md->ctypes[*eptr++] & ctype_digit) == 0) RRETURN(MATCH_NOMATCH);
1.3359 + break;
1.3360 +
1.3361 + case OP_NOT_WHITESPACE:
1.3362 + for (i = 1; i <= min; i++)
1.3363 + if ((md->ctypes[*eptr++] & ctype_space) != 0) RRETURN(MATCH_NOMATCH);
1.3364 + break;
1.3365 +
1.3366 + case OP_WHITESPACE:
1.3367 + for (i = 1; i <= min; i++)
1.3368 + if ((md->ctypes[*eptr++] & ctype_space) == 0) RRETURN(MATCH_NOMATCH);
1.3369 + break;
1.3370 +
1.3371 + case OP_NOT_WORDCHAR:
1.3372 + for (i = 1; i <= min; i++)
1.3373 + if ((md->ctypes[*eptr++] & ctype_word) != 0)
1.3374 + RRETURN(MATCH_NOMATCH);
1.3375 + break;
1.3376 +
1.3377 + case OP_WORDCHAR:
1.3378 + for (i = 1; i <= min; i++)
1.3379 + if ((md->ctypes[*eptr++] & ctype_word) == 0)
1.3380 + RRETURN(MATCH_NOMATCH);
1.3381 + break;
1.3382 +
1.3383 + default:
1.3384 + RRETURN(PCRE_ERROR_INTERNAL);
1.3385 + }
1.3386 + }
1.3387 +
1.3388 + /* If min = max, continue at the same level without recursing */
1.3389 +
1.3390 + if (min == max) continue;
1.3391 +
1.3392 + /* If minimizing, we have to test the rest of the pattern before each
1.3393 + subsequent match. Again, separate the UTF-8 case for speed, and also
1.3394 + separate the UCP cases. */
1.3395 +
1.3396 + if (minimize)
1.3397 + {
1.3398 +#ifdef SUPPORT_UCP
1.3399 + if (prop_type >= 0)
1.3400 + {
1.3401 + switch(prop_type)
1.3402 + {
1.3403 + case PT_ANY:
1.3404 + for (fi = min;; fi++)
1.3405 + {
1.3406 + RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM36);
1.3407 + if (rrc != MATCH_NOMATCH) RRETURN(rrc);
1.3408 + if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
1.3409 + GETCHARINC(c, eptr);
1.3410 + if (prop_fail_result) RRETURN(MATCH_NOMATCH);
1.3411 + }
1.3412 + /* Control never gets here */
1.3413 +
1.3414 + case PT_LAMP:
1.3415 + for (fi = min;; fi++)
1.3416 + {
1.3417 + RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM37);
1.3418 + if (rrc != MATCH_NOMATCH) RRETURN(rrc);
1.3419 + if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
1.3420 + GETCHARINC(c, eptr);
1.3421 + prop_chartype = UCD_CHARTYPE(c);
1.3422 + if ((prop_chartype == ucp_Lu ||
1.3423 + prop_chartype == ucp_Ll ||
1.3424 + prop_chartype == ucp_Lt) == prop_fail_result)
1.3425 + RRETURN(MATCH_NOMATCH);
1.3426 + }
1.3427 + /* Control never gets here */
1.3428 +
1.3429 + case PT_GC:
1.3430 + for (fi = min;; fi++)
1.3431 + {
1.3432 + RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM38);
1.3433 + if (rrc != MATCH_NOMATCH) RRETURN(rrc);
1.3434 + if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
1.3435 + GETCHARINC(c, eptr);
1.3436 + prop_category = UCD_CATEGORY(c);
1.3437 + if ((prop_category == prop_value) == prop_fail_result)
1.3438 + RRETURN(MATCH_NOMATCH);
1.3439 + }
1.3440 + /* Control never gets here */
1.3441 +
1.3442 + case PT_PC:
1.3443 + for (fi = min;; fi++)
1.3444 + {
1.3445 + RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM39);
1.3446 + if (rrc != MATCH_NOMATCH) RRETURN(rrc);
1.3447 + if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
1.3448 + GETCHARINC(c, eptr);
1.3449 + prop_chartype = UCD_CHARTYPE(c);
1.3450 + if ((prop_chartype == prop_value) == prop_fail_result)
1.3451 + RRETURN(MATCH_NOMATCH);
1.3452 + }
1.3453 + /* Control never gets here */
1.3454 +
1.3455 + case PT_SC:
1.3456 + for (fi = min;; fi++)
1.3457 + {
1.3458 + RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM40);
1.3459 + if (rrc != MATCH_NOMATCH) RRETURN(rrc);
1.3460 + if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
1.3461 + GETCHARINC(c, eptr);
1.3462 + prop_script = UCD_SCRIPT(c);
1.3463 + if ((prop_script == prop_value) == prop_fail_result)
1.3464 + RRETURN(MATCH_NOMATCH);
1.3465 + }
1.3466 + /* Control never gets here */
1.3467 +
1.3468 + default:
1.3469 + RRETURN(PCRE_ERROR_INTERNAL);
1.3470 + }
1.3471 + }
1.3472 +
1.3473 + /* Match extended Unicode sequences. We will get here only if the
1.3474 + support is in the binary; otherwise a compile-time error occurs. */
1.3475 +
1.3476 + else if (ctype == OP_EXTUNI)
1.3477 + {
1.3478 + for (fi = min;; fi++)
1.3479 + {
1.3480 + RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM41);
1.3481 + if (rrc != MATCH_NOMATCH) RRETURN(rrc);
1.3482 + if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
1.3483 + GETCHARINCTEST(c, eptr);
1.3484 + prop_category = UCD_CATEGORY(c);
1.3485 + if (prop_category == ucp_M) RRETURN(MATCH_NOMATCH);
1.3486 + while (eptr < md->end_subject)
1.3487 + {
1.3488 + int len = 1;
1.3489 + if (!utf8) c = *eptr; else
1.3490 + {
1.3491 + GETCHARLEN(c, eptr, len);
1.3492 + }
1.3493 + prop_category = UCD_CATEGORY(c);
1.3494 + if (prop_category != ucp_M) break;
1.3495 + eptr += len;
1.3496 + }
1.3497 + }
1.3498 + }
1.3499 +
1.3500 + else
1.3501 +#endif /* SUPPORT_UCP */
1.3502 +
1.3503 +#ifdef SUPPORT_UTF8
1.3504 + /* UTF-8 mode */
1.3505 + if (utf8)
1.3506 + {
1.3507 + for (fi = min;; fi++)
1.3508 + {
1.3509 + RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM42);
1.3510 + if (rrc != MATCH_NOMATCH) RRETURN(rrc);
1.3511 + if (fi >= max || eptr >= md->end_subject ||
1.3512 + (ctype == OP_ANY && IS_NEWLINE(eptr)))
1.3513 + RRETURN(MATCH_NOMATCH);
1.3514 +
1.3515 + GETCHARINC(c, eptr);
1.3516 + switch(ctype)
1.3517 + {
1.3518 + case OP_ANY: /* This is the non-NL case */
1.3519 + case OP_ALLANY:
1.3520 + case OP_ANYBYTE:
1.3521 + break;
1.3522 +
1.3523 + case OP_ANYNL:
1.3524 + switch(c)
1.3525 + {
1.3526 + default: RRETURN(MATCH_NOMATCH);
1.3527 + case 0x000d:
1.3528 + if (eptr < md->end_subject && *eptr == 0x0a) eptr++;
1.3529 + break;
1.3530 + case 0x000a:
1.3531 + break;
1.3532 +
1.3533 + case 0x000b:
1.3534 + case 0x000c:
1.3535 + case 0x0085:
1.3536 + case 0x2028:
1.3537 + case 0x2029:
1.3538 + if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH);
1.3539 + break;
1.3540 + }
1.3541 + break;
1.3542 +
1.3543 + case OP_NOT_HSPACE:
1.3544 + switch(c)
1.3545 + {
1.3546 + default: break;
1.3547 + case 0x09: /* HT */
1.3548 + case 0x20: /* SPACE */
1.3549 + case 0xa0: /* NBSP */
1.3550 + case 0x1680: /* OGHAM SPACE MARK */
1.3551 + case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */
1.3552 + case 0x2000: /* EN QUAD */
1.3553 + case 0x2001: /* EM QUAD */
1.3554 + case 0x2002: /* EN SPACE */
1.3555 + case 0x2003: /* EM SPACE */
1.3556 + case 0x2004: /* THREE-PER-EM SPACE */
1.3557 + case 0x2005: /* FOUR-PER-EM SPACE */
1.3558 + case 0x2006: /* SIX-PER-EM SPACE */
1.3559 + case 0x2007: /* FIGURE SPACE */
1.3560 + case 0x2008: /* PUNCTUATION SPACE */
1.3561 + case 0x2009: /* THIN SPACE */
1.3562 + case 0x200A: /* HAIR SPACE */
1.3563 + case 0x202f: /* NARROW NO-BREAK SPACE */
1.3564 + case 0x205f: /* MEDIUM MATHEMATICAL SPACE */
1.3565 + case 0x3000: /* IDEOGRAPHIC SPACE */
1.3566 + RRETURN(MATCH_NOMATCH);
1.3567 + }
1.3568 + break;
1.3569 +
1.3570 + case OP_HSPACE:
1.3571 + switch(c)
1.3572 + {
1.3573 + default: RRETURN(MATCH_NOMATCH);
1.3574 + case 0x09: /* HT */
1.3575 + case 0x20: /* SPACE */
1.3576 + case 0xa0: /* NBSP */
1.3577 + case 0x1680: /* OGHAM SPACE MARK */
1.3578 + case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */
1.3579 + case 0x2000: /* EN QUAD */
1.3580 + case 0x2001: /* EM QUAD */
1.3581 + case 0x2002: /* EN SPACE */
1.3582 + case 0x2003: /* EM SPACE */
1.3583 + case 0x2004: /* THREE-PER-EM SPACE */
1.3584 + case 0x2005: /* FOUR-PER-EM SPACE */
1.3585 + case 0x2006: /* SIX-PER-EM SPACE */
1.3586 + case 0x2007: /* FIGURE SPACE */
1.3587 + case 0x2008: /* PUNCTUATION SPACE */
1.3588 + case 0x2009: /* THIN SPACE */
1.3589 + case 0x200A: /* HAIR SPACE */
1.3590 + case 0x202f: /* NARROW NO-BREAK SPACE */
1.3591 + case 0x205f: /* MEDIUM MATHEMATICAL SPACE */
1.3592 + case 0x3000: /* IDEOGRAPHIC SPACE */
1.3593 + break;
1.3594 + }
1.3595 + break;
1.3596 +
1.3597 + case OP_NOT_VSPACE:
1.3598 + switch(c)
1.3599 + {
1.3600 + default: break;
1.3601 + case 0x0a: /* LF */
1.3602 + case 0x0b: /* VT */
1.3603 + case 0x0c: /* FF */
1.3604 + case 0x0d: /* CR */
1.3605 + case 0x85: /* NEL */
1.3606 + case 0x2028: /* LINE SEPARATOR */
1.3607 + case 0x2029: /* PARAGRAPH SEPARATOR */
1.3608 + RRETURN(MATCH_NOMATCH);
1.3609 + }
1.3610 + break;
1.3611 +
1.3612 + case OP_VSPACE:
1.3613 + switch(c)
1.3614 + {
1.3615 + default: RRETURN(MATCH_NOMATCH);
1.3616 + case 0x0a: /* LF */
1.3617 + case 0x0b: /* VT */
1.3618 + case 0x0c: /* FF */
1.3619 + case 0x0d: /* CR */
1.3620 + case 0x85: /* NEL */
1.3621 + case 0x2028: /* LINE SEPARATOR */
1.3622 + case 0x2029: /* PARAGRAPH SEPARATOR */
1.3623 + break;
1.3624 + }
1.3625 + break;
1.3626 +
1.3627 + case OP_NOT_DIGIT:
1.3628 + if (c < 256 && (md->ctypes[c] & ctype_digit) != 0)
1.3629 + RRETURN(MATCH_NOMATCH);
1.3630 + break;
1.3631 +
1.3632 + case OP_DIGIT:
1.3633 + if (c >= 256 || (md->ctypes[c] & ctype_digit) == 0)
1.3634 + RRETURN(MATCH_NOMATCH);
1.3635 + break;
1.3636 +
1.3637 + case OP_NOT_WHITESPACE:
1.3638 + if (c < 256 && (md->ctypes[c] & ctype_space) != 0)
1.3639 + RRETURN(MATCH_NOMATCH);
1.3640 + break;
1.3641 +
1.3642 + case OP_WHITESPACE:
1.3643 + if (c >= 256 || (md->ctypes[c] & ctype_space) == 0)
1.3644 + RRETURN(MATCH_NOMATCH);
1.3645 + break;
1.3646 +
1.3647 + case OP_NOT_WORDCHAR:
1.3648 + if (c < 256 && (md->ctypes[c] & ctype_word) != 0)
1.3649 + RRETURN(MATCH_NOMATCH);
1.3650 + break;
1.3651 +
1.3652 + case OP_WORDCHAR:
1.3653 + if (c >= 256 || (md->ctypes[c] & ctype_word) == 0)
1.3654 + RRETURN(MATCH_NOMATCH);
1.3655 + break;
1.3656 +
1.3657 + default:
1.3658 + RRETURN(PCRE_ERROR_INTERNAL);
1.3659 + }
1.3660 + }
1.3661 + }
1.3662 + else
1.3663 +#endif
1.3664 + /* Not UTF-8 mode */
1.3665 + {
1.3666 + for (fi = min;; fi++)
1.3667 + {
1.3668 + RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM43);
1.3669 + if (rrc != MATCH_NOMATCH) RRETURN(rrc);
1.3670 + if (fi >= max || eptr >= md->end_subject ||
1.3671 + (ctype == OP_ANY && IS_NEWLINE(eptr)))
1.3672 + RRETURN(MATCH_NOMATCH);
1.3673 +
1.3674 + c = *eptr++;
1.3675 + switch(ctype)
1.3676 + {
1.3677 + case OP_ANY: /* This is the non-NL case */
1.3678 + case OP_ALLANY:
1.3679 + case OP_ANYBYTE:
1.3680 + break;
1.3681 +
1.3682 + case OP_ANYNL:
1.3683 + switch(c)
1.3684 + {
1.3685 + default: RRETURN(MATCH_NOMATCH);
1.3686 + case 0x000d:
1.3687 + if (eptr < md->end_subject && *eptr == 0x0a) eptr++;
1.3688 + break;
1.3689 +
1.3690 + case 0x000a:
1.3691 + break;
1.3692 +
1.3693 + case 0x000b:
1.3694 + case 0x000c:
1.3695 + case 0x0085:
1.3696 + if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH);
1.3697 + break;
1.3698 + }
1.3699 + break;
1.3700 +
1.3701 + case OP_NOT_HSPACE:
1.3702 + switch(c)
1.3703 + {
1.3704 + default: break;
1.3705 + case 0x09: /* HT */
1.3706 + case 0x20: /* SPACE */
1.3707 + case 0xa0: /* NBSP */
1.3708 + RRETURN(MATCH_NOMATCH);
1.3709 + }
1.3710 + break;
1.3711 +
1.3712 + case OP_HSPACE:
1.3713 + switch(c)
1.3714 + {
1.3715 + default: RRETURN(MATCH_NOMATCH);
1.3716 + case 0x09: /* HT */
1.3717 + case 0x20: /* SPACE */
1.3718 + case 0xa0: /* NBSP */
1.3719 + break;
1.3720 + }
1.3721 + break;
1.3722 +
1.3723 + case OP_NOT_VSPACE:
1.3724 + switch(c)
1.3725 + {
1.3726 + default: break;
1.3727 + case 0x0a: /* LF */
1.3728 + case 0x0b: /* VT */
1.3729 + case 0x0c: /* FF */
1.3730 + case 0x0d: /* CR */
1.3731 + case 0x85: /* NEL */
1.3732 + RRETURN(MATCH_NOMATCH);
1.3733 + }
1.3734 + break;
1.3735 +
1.3736 + case OP_VSPACE:
1.3737 + switch(c)
1.3738 + {
1.3739 + default: RRETURN(MATCH_NOMATCH);
1.3740 + case 0x0a: /* LF */
1.3741 + case 0x0b: /* VT */
1.3742 + case 0x0c: /* FF */
1.3743 + case 0x0d: /* CR */
1.3744 + case 0x85: /* NEL */
1.3745 + break;
1.3746 + }
1.3747 + break;
1.3748 +
1.3749 + case OP_NOT_DIGIT:
1.3750 + if ((md->ctypes[c] & ctype_digit) != 0) RRETURN(MATCH_NOMATCH);
1.3751 + break;
1.3752 +
1.3753 + case OP_DIGIT:
1.3754 + if ((md->ctypes[c] & ctype_digit) == 0) RRETURN(MATCH_NOMATCH);
1.3755 + break;
1.3756 +
1.3757 + case OP_NOT_WHITESPACE:
1.3758 + if ((md->ctypes[c] & ctype_space) != 0) RRETURN(MATCH_NOMATCH);
1.3759 + break;
1.3760 +
1.3761 + case OP_WHITESPACE:
1.3762 + if ((md->ctypes[c] & ctype_space) == 0) RRETURN(MATCH_NOMATCH);
1.3763 + break;
1.3764 +
1.3765 + case OP_NOT_WORDCHAR:
1.3766 + if ((md->ctypes[c] & ctype_word) != 0) RRETURN(MATCH_NOMATCH);
1.3767 + break;
1.3768 +
1.3769 + case OP_WORDCHAR:
1.3770 + if ((md->ctypes[c] & ctype_word) == 0) RRETURN(MATCH_NOMATCH);
1.3771 + break;
1.3772 +
1.3773 + default:
1.3774 + RRETURN(PCRE_ERROR_INTERNAL);
1.3775 + }
1.3776 + }
1.3777 + }
1.3778 + /* Control never gets here */
1.3779 + }
1.3780 +
1.3781 + /* If maximizing, it is worth using inline code for speed, doing the type
1.3782 + test once at the start (i.e. keep it out of the loop). Again, keep the
1.3783 + UTF-8 and UCP stuff separate. */
1.3784 +
1.3785 + else
1.3786 + {
1.3787 + pp = eptr; /* Remember where we started */
1.3788 +
1.3789 +#ifdef SUPPORT_UCP
1.3790 + if (prop_type >= 0)
1.3791 + {
1.3792 + switch(prop_type)
1.3793 + {
1.3794 + case PT_ANY:
1.3795 + for (i = min; i < max; i++)
1.3796 + {
1.3797 + int len = 1;
1.3798 + if (eptr >= md->end_subject) break;
1.3799 + GETCHARLEN(c, eptr, len);
1.3800 + if (prop_fail_result) break;
1.3801 + eptr+= len;
1.3802 + }
1.3803 + break;
1.3804 +
1.3805 + case PT_LAMP:
1.3806 + for (i = min; i < max; i++)
1.3807 + {
1.3808 + int len = 1;
1.3809 + if (eptr >= md->end_subject) break;
1.3810 + GETCHARLEN(c, eptr, len);
1.3811 + prop_chartype = UCD_CHARTYPE(c);
1.3812 + if ((prop_chartype == ucp_Lu ||
1.3813 + prop_chartype == ucp_Ll ||
1.3814 + prop_chartype == ucp_Lt) == prop_fail_result)
1.3815 + break;
1.3816 + eptr+= len;
1.3817 + }
1.3818 + break;
1.3819 +
1.3820 + case PT_GC:
1.3821 + for (i = min; i < max; i++)
1.3822 + {
1.3823 + int len = 1;
1.3824 + if (eptr >= md->end_subject) break;
1.3825 + GETCHARLEN(c, eptr, len);
1.3826 + prop_category = UCD_CATEGORY(c);
1.3827 + if ((prop_category == prop_value) == prop_fail_result)
1.3828 + break;
1.3829 + eptr+= len;
1.3830 + }
1.3831 + break;
1.3832 +
1.3833 + case PT_PC:
1.3834 + for (i = min; i < max; i++)
1.3835 + {
1.3836 + int len = 1;
1.3837 + if (eptr >= md->end_subject) break;
1.3838 + GETCHARLEN(c, eptr, len);
1.3839 + prop_chartype = UCD_CHARTYPE(c);
1.3840 + if ((prop_chartype == prop_value) == prop_fail_result)
1.3841 + break;
1.3842 + eptr+= len;
1.3843 + }
1.3844 + break;
1.3845 +
1.3846 + case PT_SC:
1.3847 + for (i = min; i < max; i++)
1.3848 + {
1.3849 + int len = 1;
1.3850 + if (eptr >= md->end_subject) break;
1.3851 + GETCHARLEN(c, eptr, len);
1.3852 + prop_script = UCD_SCRIPT(c);
1.3853 + if ((prop_script == prop_value) == prop_fail_result)
1.3854 + break;
1.3855 + eptr+= len;
1.3856 + }
1.3857 + break;
1.3858 + }
1.3859 +
1.3860 + /* eptr is now past the end of the maximum run */
1.3861 +
1.3862 + if (possessive) continue;
1.3863 + for(;;)
1.3864 + {
1.3865 + RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM44);
1.3866 + if (rrc != MATCH_NOMATCH) RRETURN(rrc);
1.3867 + if (eptr-- == pp) break; /* Stop if tried at original pos */
1.3868 + if (utf8) BACKCHAR(eptr);
1.3869 + }
1.3870 + }
1.3871 +
1.3872 + /* Match extended Unicode sequences. We will get here only if the
1.3873 + support is in the binary; otherwise a compile-time error occurs. */
1.3874 +
1.3875 + else if (ctype == OP_EXTUNI)
1.3876 + {
1.3877 + for (i = min; i < max; i++)
1.3878 + {
1.3879 + if (eptr >= md->end_subject) break;
1.3880 + GETCHARINCTEST(c, eptr);
1.3881 + prop_category = UCD_CATEGORY(c);
1.3882 + if (prop_category == ucp_M) break;
1.3883 + while (eptr < md->end_subject)
1.3884 + {
1.3885 + int len = 1;
1.3886 + if (!utf8) c = *eptr; else
1.3887 + {
1.3888 + GETCHARLEN(c, eptr, len);
1.3889 + }
1.3890 + prop_category = UCD_CATEGORY(c);
1.3891 + if (prop_category != ucp_M) break;
1.3892 + eptr += len;
1.3893 + }
1.3894 + }
1.3895 +
1.3896 + /* eptr is now past the end of the maximum run */
1.3897 +
1.3898 + if (possessive) continue;
1.3899 + for(;;)
1.3900 + {
1.3901 + RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM45);
1.3902 + if (rrc != MATCH_NOMATCH) RRETURN(rrc);
1.3903 + if (eptr-- == pp) break; /* Stop if tried at original pos */
1.3904 + for (;;) /* Move back over one extended */
1.3905 + {
1.3906 + int len = 1;
1.3907 + if (!utf8) c = *eptr; else
1.3908 + {
1.3909 + BACKCHAR(eptr);
1.3910 + GETCHARLEN(c, eptr, len);
1.3911 + }
1.3912 + prop_category = UCD_CATEGORY(c);
1.3913 + if (prop_category != ucp_M) break;
1.3914 + eptr--;
1.3915 + }
1.3916 + }
1.3917 + }
1.3918 +
1.3919 + else
1.3920 +#endif /* SUPPORT_UCP */
1.3921 +
1.3922 +#ifdef SUPPORT_UTF8
1.3923 + /* UTF-8 mode */
1.3924 +
1.3925 + if (utf8)
1.3926 + {
1.3927 + switch(ctype)
1.3928 + {
1.3929 + case OP_ANY:
1.3930 + if (max < INT_MAX)
1.3931 + {
1.3932 + for (i = min; i < max; i++)
1.3933 + {
1.3934 + if (eptr >= md->end_subject || IS_NEWLINE(eptr)) break;
1.3935 + eptr++;
1.3936 + while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;
1.3937 + }
1.3938 + }
1.3939 +
1.3940 + /* Handle unlimited UTF-8 repeat */
1.3941 +
1.3942 + else
1.3943 + {
1.3944 + for (i = min; i < max; i++)
1.3945 + {
1.3946 + if (eptr >= md->end_subject || IS_NEWLINE(eptr)) break;
1.3947 + eptr++;
1.3948 + while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;
1.3949 + }
1.3950 + }
1.3951 + break;
1.3952 +
1.3953 + case OP_ALLANY:
1.3954 + if (max < INT_MAX)
1.3955 + {
1.3956 + for (i = min; i < max; i++)
1.3957 + {
1.3958 + if (eptr >= md->end_subject) break;
1.3959 + eptr++;
1.3960 + while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;
1.3961 + }
1.3962 + }
1.3963 + else eptr = md->end_subject; /* Unlimited UTF-8 repeat */
1.3964 + break;
1.3965 +
1.3966 + /* The byte case is the same as non-UTF8 */
1.3967 +
1.3968 + case OP_ANYBYTE:
1.3969 + c = max - min;
1.3970 + if (c > (unsigned int)(md->end_subject - eptr))
1.3971 + c = md->end_subject - eptr;
1.3972 + eptr += c;
1.3973 + break;
1.3974 +
1.3975 + case OP_ANYNL:
1.3976 + for (i = min; i < max; i++)
1.3977 + {
1.3978 + int len = 1;
1.3979 + if (eptr >= md->end_subject) break;
1.3980 + GETCHARLEN(c, eptr, len);
1.3981 + if (c == 0x000d)
1.3982 + {
1.3983 + if (++eptr >= md->end_subject) break;
1.3984 + if (*eptr == 0x000a) eptr++;
1.3985 + }
1.3986 + else
1.3987 + {
1.3988 + if (c != 0x000a &&
1.3989 + (md->bsr_anycrlf ||
1.3990 + (c != 0x000b && c != 0x000c &&
1.3991 + c != 0x0085 && c != 0x2028 && c != 0x2029)))
1.3992 + break;
1.3993 + eptr += len;
1.3994 + }
1.3995 + }
1.3996 + break;
1.3997 +
1.3998 + case OP_NOT_HSPACE:
1.3999 + case OP_HSPACE:
1.4000 + for (i = min; i < max; i++)
1.4001 + {
1.4002 + BOOL gotspace;
1.4003 + int len = 1;
1.4004 + if (eptr >= md->end_subject) break;
1.4005 + GETCHARLEN(c, eptr, len);
1.4006 + switch(c)
1.4007 + {
1.4008 + default: gotspace = FALSE; break;
1.4009 + case 0x09: /* HT */
1.4010 + case 0x20: /* SPACE */
1.4011 + case 0xa0: /* NBSP */
1.4012 + case 0x1680: /* OGHAM SPACE MARK */
1.4013 + case 0x180e: /* MONGOLIAN VOWEL SEPARATOR */
1.4014 + case 0x2000: /* EN QUAD */
1.4015 + case 0x2001: /* EM QUAD */
1.4016 + case 0x2002: /* EN SPACE */
1.4017 + case 0x2003: /* EM SPACE */
1.4018 + case 0x2004: /* THREE-PER-EM SPACE */
1.4019 + case 0x2005: /* FOUR-PER-EM SPACE */
1.4020 + case 0x2006: /* SIX-PER-EM SPACE */
1.4021 + case 0x2007: /* FIGURE SPACE */
1.4022 + case 0x2008: /* PUNCTUATION SPACE */
1.4023 + case 0x2009: /* THIN SPACE */
1.4024 + case 0x200A: /* HAIR SPACE */
1.4025 + case 0x202f: /* NARROW NO-BREAK SPACE */
1.4026 + case 0x205f: /* MEDIUM MATHEMATICAL SPACE */
1.4027 + case 0x3000: /* IDEOGRAPHIC SPACE */
1.4028 + gotspace = TRUE;
1.4029 + break;
1.4030 + }
1.4031 + if (gotspace == (ctype == OP_NOT_HSPACE)) break;
1.4032 + eptr += len;
1.4033 + }
1.4034 + break;
1.4035 +
1.4036 + case OP_NOT_VSPACE:
1.4037 + case OP_VSPACE:
1.4038 + for (i = min; i < max; i++)
1.4039 + {
1.4040 + BOOL gotspace;
1.4041 + int len = 1;
1.4042 + if (eptr >= md->end_subject) break;
1.4043 + GETCHARLEN(c, eptr, len);
1.4044 + switch(c)
1.4045 + {
1.4046 + default: gotspace = FALSE; break;
1.4047 + case 0x0a: /* LF */
1.4048 + case 0x0b: /* VT */
1.4049 + case 0x0c: /* FF */
1.4050 + case 0x0d: /* CR */
1.4051 + case 0x85: /* NEL */
1.4052 + case 0x2028: /* LINE SEPARATOR */
1.4053 + case 0x2029: /* PARAGRAPH SEPARATOR */
1.4054 + gotspace = TRUE;
1.4055 + break;
1.4056 + }
1.4057 + if (gotspace == (ctype == OP_NOT_VSPACE)) break;
1.4058 + eptr += len;
1.4059 + }
1.4060 + break;
1.4061 +
1.4062 + case OP_NOT_DIGIT:
1.4063 + for (i = min; i < max; i++)
1.4064 + {
1.4065 + int len = 1;
1.4066 + if (eptr >= md->end_subject) break;
1.4067 + GETCHARLEN(c, eptr, len);
1.4068 + if (c < 256 && (md->ctypes[c] & ctype_digit) != 0) break;
1.4069 + eptr+= len;
1.4070 + }
1.4071 + break;
1.4072 +
1.4073 + case OP_DIGIT:
1.4074 + for (i = min; i < max; i++)
1.4075 + {
1.4076 + int len = 1;
1.4077 + if (eptr >= md->end_subject) break;
1.4078 + GETCHARLEN(c, eptr, len);
1.4079 + if (c >= 256 ||(md->ctypes[c] & ctype_digit) == 0) break;
1.4080 + eptr+= len;
1.4081 + }
1.4082 + break;
1.4083 +
1.4084 + case OP_NOT_WHITESPACE:
1.4085 + for (i = min; i < max; i++)
1.4086 + {
1.4087 + int len = 1;
1.4088 + if (eptr >= md->end_subject) break;
1.4089 + GETCHARLEN(c, eptr, len);
1.4090 + if (c < 256 && (md->ctypes[c] & ctype_space) != 0) break;
1.4091 + eptr+= len;
1.4092 + }
1.4093 + break;
1.4094 +
1.4095 + case OP_WHITESPACE:
1.4096 + for (i = min; i < max; i++)
1.4097 + {
1.4098 + int len = 1;
1.4099 + if (eptr >= md->end_subject) break;
1.4100 + GETCHARLEN(c, eptr, len);
1.4101 + if (c >= 256 ||(md->ctypes[c] & ctype_space) == 0) break;
1.4102 + eptr+= len;
1.4103 + }
1.4104 + break;
1.4105 +
1.4106 + case OP_NOT_WORDCHAR:
1.4107 + for (i = min; i < max; i++)
1.4108 + {
1.4109 + int len = 1;
1.4110 + if (eptr >= md->end_subject) break;
1.4111 + GETCHARLEN(c, eptr, len);
1.4112 + if (c < 256 && (md->ctypes[c] & ctype_word) != 0) break;
1.4113 + eptr+= len;
1.4114 + }
1.4115 + break;
1.4116 +
1.4117 + case OP_WORDCHAR:
1.4118 + for (i = min; i < max; i++)
1.4119 + {
1.4120 + int len = 1;
1.4121 + if (eptr >= md->end_subject) break;
1.4122 + GETCHARLEN(c, eptr, len);
1.4123 + if (c >= 256 || (md->ctypes[c] & ctype_word) == 0) break;
1.4124 + eptr+= len;
1.4125 + }
1.4126 + break;
1.4127 +
1.4128 + default:
1.4129 + RRETURN(PCRE_ERROR_INTERNAL);
1.4130 + }
1.4131 +
1.4132 + /* eptr is now past the end of the maximum run */
1.4133 +
1.4134 + if (possessive) continue;
1.4135 + for(;;)
1.4136 + {
1.4137 + RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM46);
1.4138 + if (rrc != MATCH_NOMATCH) RRETURN(rrc);
1.4139 + if (eptr-- == pp) break; /* Stop if tried at original pos */
1.4140 + BACKCHAR(eptr);
1.4141 + }
1.4142 + }
1.4143 + else
1.4144 +#endif /* SUPPORT_UTF8 */
1.4145 +
1.4146 + /* Not UTF-8 mode */
1.4147 + {
1.4148 + switch(ctype)
1.4149 + {
1.4150 + case OP_ANY:
1.4151 + for (i = min; i < max; i++)
1.4152 + {
1.4153 + if (eptr >= md->end_subject || IS_NEWLINE(eptr)) break;
1.4154 + eptr++;
1.4155 + }
1.4156 + break;
1.4157 +
1.4158 + case OP_ALLANY:
1.4159 + case OP_ANYBYTE:
1.4160 + c = max - min;
1.4161 + if (c > (unsigned int)(md->end_subject - eptr))
1.4162 + c = md->end_subject - eptr;
1.4163 + eptr += c;
1.4164 + break;
1.4165 +
1.4166 + case OP_ANYNL:
1.4167 + for (i = min; i < max; i++)
1.4168 + {
1.4169 + if (eptr >= md->end_subject) break;
1.4170 + c = *eptr;
1.4171 + if (c == 0x000d)
1.4172 + {
1.4173 + if (++eptr >= md->end_subject) break;
1.4174 + if (*eptr == 0x000a) eptr++;
1.4175 + }
1.4176 + else
1.4177 + {
1.4178 + if (c != 0x000a &&
1.4179 + (md->bsr_anycrlf ||
1.4180 + (c != 0x000b && c != 0x000c && c != 0x0085)))
1.4181 + break;
1.4182 + eptr++;
1.4183 + }
1.4184 + }
1.4185 + break;
1.4186 +
1.4187 + case OP_NOT_HSPACE:
1.4188 + for (i = min; i < max; i++)
1.4189 + {
1.4190 + if (eptr >= md->end_subject) break;
1.4191 + c = *eptr;
1.4192 + if (c == 0x09 || c == 0x20 || c == 0xa0) break;
1.4193 + eptr++;
1.4194 + }
1.4195 + break;
1.4196 +
1.4197 + case OP_HSPACE:
1.4198 + for (i = min; i < max; i++)
1.4199 + {
1.4200 + if (eptr >= md->end_subject) break;
1.4201 + c = *eptr;
1.4202 + if (c != 0x09 && c != 0x20 && c != 0xa0) break;
1.4203 + eptr++;
1.4204 + }
1.4205 + break;
1.4206 +
1.4207 + case OP_NOT_VSPACE:
1.4208 + for (i = min; i < max; i++)
1.4209 + {
1.4210 + if (eptr >= md->end_subject) break;
1.4211 + c = *eptr;
1.4212 + if (c == 0x0a || c == 0x0b || c == 0x0c || c == 0x0d || c == 0x85)
1.4213 + break;
1.4214 + eptr++;
1.4215 + }
1.4216 + break;
1.4217 +
1.4218 + case OP_VSPACE:
1.4219 + for (i = min; i < max; i++)
1.4220 + {
1.4221 + if (eptr >= md->end_subject) break;
1.4222 + c = *eptr;
1.4223 + if (c != 0x0a && c != 0x0b && c != 0x0c && c != 0x0d && c != 0x85)
1.4224 + break;
1.4225 + eptr++;
1.4226 + }
1.4227 + break;
1.4228 +
1.4229 + case OP_NOT_DIGIT:
1.4230 + for (i = min; i < max; i++)
1.4231 + {
1.4232 + if (eptr >= md->end_subject || (md->ctypes[*eptr] & ctype_digit) != 0)
1.4233 + break;
1.4234 + eptr++;
1.4235 + }
1.4236 + break;
1.4237 +
1.4238 + case OP_DIGIT:
1.4239 + for (i = min; i < max; i++)
1.4240 + {
1.4241 + if (eptr >= md->end_subject || (md->ctypes[*eptr] & ctype_digit) == 0)
1.4242 + break;
1.4243 + eptr++;
1.4244 + }
1.4245 + break;
1.4246 +
1.4247 + case OP_NOT_WHITESPACE:
1.4248 + for (i = min; i < max; i++)
1.4249 + {
1.4250 + if (eptr >= md->end_subject || (md->ctypes[*eptr] & ctype_space) != 0)
1.4251 + break;
1.4252 + eptr++;
1.4253 + }
1.4254 + break;
1.4255 +
1.4256 + case OP_WHITESPACE:
1.4257 + for (i = min; i < max; i++)
1.4258 + {
1.4259 + if (eptr >= md->end_subject || (md->ctypes[*eptr] & ctype_space) == 0)
1.4260 + break;
1.4261 + eptr++;
1.4262 + }
1.4263 + break;
1.4264 +
1.4265 + case OP_NOT_WORDCHAR:
1.4266 + for (i = min; i < max; i++)
1.4267 + {
1.4268 + if (eptr >= md->end_subject || (md->ctypes[*eptr] & ctype_word) != 0)
1.4269 + break;
1.4270 + eptr++;
1.4271 + }
1.4272 + break;
1.4273 +
1.4274 + case OP_WORDCHAR:
1.4275 + for (i = min; i < max; i++)
1.4276 + {
1.4277 + if (eptr >= md->end_subject || (md->ctypes[*eptr] & ctype_word) == 0)
1.4278 + break;
1.4279 + eptr++;
1.4280 + }
1.4281 + break;
1.4282 +
1.4283 + default:
1.4284 + RRETURN(PCRE_ERROR_INTERNAL);
1.4285 + }
1.4286 +
1.4287 + /* eptr is now past the end of the maximum run */
1.4288 +
1.4289 + if (possessive) continue;
1.4290 + while (eptr >= pp)
1.4291 + {
1.4292 + RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM47);
1.4293 + eptr--;
1.4294 + if (rrc != MATCH_NOMATCH) RRETURN(rrc);
1.4295 + }
1.4296 + }
1.4297 +
1.4298 + /* Get here if we can't make it match with any permitted repetitions */
1.4299 +
1.4300 + RRETURN(MATCH_NOMATCH);
1.4301 + }
1.4302 + /* Control never gets here */
1.4303 +
1.4304 + /* There's been some horrible disaster. Arrival here can only mean there is
1.4305 + something seriously wrong in the code above or the OP_xxx definitions. */
1.4306 +
1.4307 + default:
1.4308 + DPRINTF(("Unknown opcode %d\n", *ecode));
1.4309 + RRETURN(PCRE_ERROR_UNKNOWN_OPCODE);
1.4310 + }
1.4311 +
1.4312 + /* Do not stick any code in here without much thought; it is assumed
1.4313 + that "continue" in the code above comes out to here to repeat the main
1.4314 + loop. */
1.4315 +
1.4316 + } /* End of main loop */
1.4317 +/* Control never reaches here */
1.4318 +
1.4319 +
1.4320 +/* When compiling to use the heap rather than the stack for recursive calls to
1.4321 +match(), the RRETURN() macro jumps here. The number that is saved in
1.4322 +frame->Xwhere indicates which label we actually want to return to. */
1.4323 +
1.4324 +#ifdef NO_RECURSE
1.4325 +#define LBL(val) case val: goto L_RM##val;
1.4326 +HEAP_RETURN:
1.4327 +switch (frame->Xwhere)
1.4328 + {
1.4329 + LBL( 1) LBL( 2) LBL( 3) LBL( 4) LBL( 5) LBL( 6) LBL( 7) LBL( 8)
1.4330 + LBL( 9) LBL(10) LBL(11) LBL(12) LBL(13) LBL(14) LBL(15) LBL(17)
1.4331 + LBL(19) LBL(24) LBL(25) LBL(26) LBL(27) LBL(29) LBL(31) LBL(33)
1.4332 + LBL(35) LBL(43) LBL(47) LBL(48) LBL(49) LBL(50) LBL(51) LBL(52)
1.4333 + LBL(53) LBL(54)
1.4334 +#ifdef SUPPORT_UTF8
1.4335 + LBL(16) LBL(18) LBL(20) LBL(21) LBL(22) LBL(23) LBL(28) LBL(30)
1.4336 + LBL(32) LBL(34) LBL(42) LBL(46)
1.4337 +#ifdef SUPPORT_UCP
1.4338 + LBL(36) LBL(37) LBL(38) LBL(39) LBL(40) LBL(41) LBL(44) LBL(45)
1.4339 +#endif /* SUPPORT_UCP */
1.4340 +#endif /* SUPPORT_UTF8 */
1.4341 + default:
1.4342 + DPRINTF(("jump error in pcre match: label %d non-existent\n", frame->Xwhere));
1.4343 + return PCRE_ERROR_INTERNAL;
1.4344 + }
1.4345 +#undef LBL
1.4346 +#endif /* NO_RECURSE */
1.4347 +}
1.4348 +
1.4349 +
1.4350 +/***************************************************************************
1.4351 +****************************************************************************
1.4352 + RECURSION IN THE match() FUNCTION
1.4353 +
1.4354 +Undefine all the macros that were defined above to handle this. */
1.4355 +
1.4356 +#ifdef NO_RECURSE
1.4357 +#undef eptr
1.4358 +#undef ecode
1.4359 +#undef mstart
1.4360 +#undef offset_top
1.4361 +#undef ims
1.4362 +#undef eptrb
1.4363 +#undef flags
1.4364 +
1.4365 +#undef callpat
1.4366 +#undef charptr
1.4367 +#undef data
1.4368 +#undef next
1.4369 +#undef pp
1.4370 +#undef prev
1.4371 +#undef saved_eptr
1.4372 +
1.4373 +#undef new_recursive
1.4374 +
1.4375 +#undef cur_is_word
1.4376 +#undef condition
1.4377 +#undef prev_is_word
1.4378 +
1.4379 +#undef original_ims
1.4380 +
1.4381 +#undef ctype
1.4382 +#undef length
1.4383 +#undef max
1.4384 +#undef min
1.4385 +#undef number
1.4386 +#undef offset
1.4387 +#undef op
1.4388 +#undef save_capture_last
1.4389 +#undef save_offset1
1.4390 +#undef save_offset2
1.4391 +#undef save_offset3
1.4392 +#undef stacksave
1.4393 +
1.4394 +#undef newptrb
1.4395 +
1.4396 +#endif
1.4397 +
1.4398 +/* These two are defined as macros in both cases */
1.4399 +
1.4400 +#undef fc
1.4401 +#undef fi
1.4402 +
1.4403 +/***************************************************************************
1.4404 +***************************************************************************/
1.4405 +
1.4406 +
1.4407 +
1.4408 +/*************************************************
1.4409 +* Execute a Regular Expression *
1.4410 +*************************************************/
1.4411 +
1.4412 +/* This function applies a compiled re to a subject string and picks out
1.4413 +portions of the string if it matches. Two elements in the vector are set for
1.4414 +each substring: the offsets to the start and end of the substring.
1.4415 +
1.4416 +Arguments:
1.4417 + argument_re points to the compiled expression
1.4418 + extra_data points to extra data or is NULL
1.4419 + subject points to the subject string
1.4420 + length length of subject string (may contain binary zeros)
1.4421 + start_offset where to start in the subject string
1.4422 + options option bits
1.4423 + offsets points to a vector of ints to be filled in with offsets
1.4424 + offsetcount the number of elements in the vector
1.4425 +
1.4426 +Returns: > 0 => success; value is the number of elements filled in
1.4427 + = 0 => success, but offsets is not big enough
1.4428 + -1 => failed to match
1.4429 + < -1 => some kind of unexpected problem
1.4430 +*/
1.4431 +
1.4432 +PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
1.4433 +pcre_exec(const pcre *argument_re, const pcre_extra *extra_data,
1.4434 + PCRE_SPTR subject, int length, int start_offset, int options, int *offsets,
1.4435 + int offsetcount)
1.4436 +{
1.4437 +int rc, resetcount, ocount;
1.4438 +int first_byte = -1;
1.4439 +int req_byte = -1;
1.4440 +int req_byte2 = -1;
1.4441 +int newline;
1.4442 +unsigned long int ims;
1.4443 +BOOL using_temporary_offsets = FALSE;
1.4444 +BOOL anchored;
1.4445 +BOOL startline;
1.4446 +BOOL firstline;
1.4447 +BOOL first_byte_caseless = FALSE;
1.4448 +BOOL req_byte_caseless = FALSE;
1.4449 +BOOL utf8;
1.4450 +match_data match_block;
1.4451 +match_data *md = &match_block;
1.4452 +const uschar *tables;
1.4453 +const uschar *start_bits = NULL;
1.4454 +USPTR start_match = (USPTR)subject + start_offset;
1.4455 +USPTR end_subject;
1.4456 +USPTR req_byte_ptr = start_match - 1;
1.4457 +
1.4458 +pcre_study_data internal_study;
1.4459 +const pcre_study_data *study;
1.4460 +
1.4461 +real_pcre internal_re;
1.4462 +const real_pcre *external_re = (const real_pcre *)argument_re;
1.4463 +const real_pcre *re = external_re;
1.4464 +
1.4465 +/* Plausibility checks */
1.4466 +
1.4467 +if ((options & ~PUBLIC_EXEC_OPTIONS) != 0) return PCRE_ERROR_BADOPTION;
1.4468 +if (re == NULL || subject == NULL ||
1.4469 + (offsets == NULL && offsetcount > 0)) return PCRE_ERROR_NULL;
1.4470 +if (offsetcount < 0) return PCRE_ERROR_BADCOUNT;
1.4471 +
1.4472 +/* Fish out the optional data from the extra_data structure, first setting
1.4473 +the default values. */
1.4474 +
1.4475 +study = NULL;
1.4476 +md->match_limit = MATCH_LIMIT;
1.4477 +md->match_limit_recursion = MATCH_LIMIT_RECURSION;
1.4478 +md->callout_data = NULL;
1.4479 +
1.4480 +/* The table pointer is always in native byte order. */
1.4481 +
1.4482 +tables = external_re->tables;
1.4483 +
1.4484 +if (extra_data != NULL)
1.4485 + {
1.4486 + register unsigned int flags = extra_data->flags;
1.4487 + if ((flags & PCRE_EXTRA_STUDY_DATA) != 0)
1.4488 + study = (const pcre_study_data *)extra_data->study_data;
1.4489 + if ((flags & PCRE_EXTRA_MATCH_LIMIT) != 0)
1.4490 + md->match_limit = extra_data->match_limit;
1.4491 + if ((flags & PCRE_EXTRA_MATCH_LIMIT_RECURSION) != 0)
1.4492 + md->match_limit_recursion = extra_data->match_limit_recursion;
1.4493 + if ((flags & PCRE_EXTRA_CALLOUT_DATA) != 0)
1.4494 + md->callout_data = extra_data->callout_data;
1.4495 + if ((flags & PCRE_EXTRA_TABLES) != 0) tables = extra_data->tables;
1.4496 + }
1.4497 +
1.4498 +/* If the exec call supplied NULL for tables, use the inbuilt ones. This
1.4499 +is a feature that makes it possible to save compiled regex and re-use them
1.4500 +in other programs later. */
1.4501 +
1.4502 +if (tables == NULL) tables = _pcre_default_tables;
1.4503 +
1.4504 +/* Check that the first field in the block is the magic number. If it is not,
1.4505 +test for a regex that was compiled on a host of opposite endianness. If this is
1.4506 +the case, flipped values are put in internal_re and internal_study if there was
1.4507 +study data too. */
1.4508 +
1.4509 +if (re->magic_number != MAGIC_NUMBER)
1.4510 + {
1.4511 + re = _pcre_try_flipped(re, &internal_re, study, &internal_study);
1.4512 + if (re == NULL) return PCRE_ERROR_BADMAGIC;
1.4513 + if (study != NULL) study = &internal_study;
1.4514 + }
1.4515 +
1.4516 +/* Set up other data */
1.4517 +
1.4518 +anchored = ((re->options | options) & PCRE_ANCHORED) != 0;
1.4519 +startline = (re->flags & PCRE_STARTLINE) != 0;
1.4520 +firstline = (re->options & PCRE_FIRSTLINE) != 0;
1.4521 +
1.4522 +/* The code starts after the real_pcre block and the capture name table. */
1.4523 +
1.4524 +md->start_code = (const uschar *)external_re + re->name_table_offset +
1.4525 + re->name_count * re->name_entry_size;
1.4526 +
1.4527 +md->start_subject = (USPTR)subject;
1.4528 +md->start_offset = start_offset;
1.4529 +md->end_subject = md->start_subject + length;
1.4530 +end_subject = md->end_subject;
1.4531 +
1.4532 +md->endonly = (re->options & PCRE_DOLLAR_ENDONLY) != 0;
1.4533 +utf8 = md->utf8 = (re->options & PCRE_UTF8) != 0;
1.4534 +md->jscript_compat = (re->options & PCRE_JAVASCRIPT_COMPAT) != 0;
1.4535 +
1.4536 +md->notbol = (options & PCRE_NOTBOL) != 0;
1.4537 +md->noteol = (options & PCRE_NOTEOL) != 0;
1.4538 +md->notempty = (options & PCRE_NOTEMPTY) != 0;
1.4539 +md->partial = (options & PCRE_PARTIAL) != 0;
1.4540 +md->hitend = FALSE;
1.4541 +
1.4542 +md->recursive = NULL; /* No recursion at top level */
1.4543 +
1.4544 +md->lcc = tables + lcc_offset;
1.4545 +md->ctypes = tables + ctypes_offset;
1.4546 +
1.4547 +/* Handle different \R options. */
1.4548 +
1.4549 +switch (options & (PCRE_BSR_ANYCRLF|PCRE_BSR_UNICODE))
1.4550 + {
1.4551 + case 0:
1.4552 + if ((re->options & (PCRE_BSR_ANYCRLF|PCRE_BSR_UNICODE)) != 0)
1.4553 + md->bsr_anycrlf = (re->options & PCRE_BSR_ANYCRLF) != 0;
1.4554 + else
1.4555 +#ifdef BSR_ANYCRLF
1.4556 + md->bsr_anycrlf = TRUE;
1.4557 +#else
1.4558 + md->bsr_anycrlf = FALSE;
1.4559 +#endif
1.4560 + break;
1.4561 +
1.4562 + case PCRE_BSR_ANYCRLF:
1.4563 + md->bsr_anycrlf = TRUE;
1.4564 + break;
1.4565 +
1.4566 + case PCRE_BSR_UNICODE:
1.4567 + md->bsr_anycrlf = FALSE;
1.4568 + break;
1.4569 +
1.4570 + default: return PCRE_ERROR_BADNEWLINE;
1.4571 + }
1.4572 +
1.4573 +/* Handle different types of newline. The three bits give eight cases. If
1.4574 +nothing is set at run time, whatever was used at compile time applies. */
1.4575 +
1.4576 +switch ((((options & PCRE_NEWLINE_BITS) == 0)? re->options :
1.4577 + (pcre_uint32)options) & PCRE_NEWLINE_BITS)
1.4578 + {
1.4579 + case 0: newline = NEWLINE; break; /* Compile-time default */
1.4580 + case PCRE_NEWLINE_CR: newline = CHAR_CR; break;
1.4581 + case PCRE_NEWLINE_LF: newline = CHAR_NL; break;
1.4582 + case PCRE_NEWLINE_CR+
1.4583 + PCRE_NEWLINE_LF: newline = (CHAR_CR << 8) | CHAR_NL; break;
1.4584 + case PCRE_NEWLINE_ANY: newline = -1; break;
1.4585 + case PCRE_NEWLINE_ANYCRLF: newline = -2; break;
1.4586 + default: return PCRE_ERROR_BADNEWLINE;
1.4587 + }
1.4588 +
1.4589 +if (newline == -2)
1.4590 + {
1.4591 + md->nltype = NLTYPE_ANYCRLF;
1.4592 + }
1.4593 +else if (newline < 0)
1.4594 + {
1.4595 + md->nltype = NLTYPE_ANY;
1.4596 + }
1.4597 +else
1.4598 + {
1.4599 + md->nltype = NLTYPE_FIXED;
1.4600 + if (newline > 255)
1.4601 + {
1.4602 + md->nllen = 2;
1.4603 + md->nl[0] = (newline >> 8) & 255;
1.4604 + md->nl[1] = newline & 255;
1.4605 + }
1.4606 + else
1.4607 + {
1.4608 + md->nllen = 1;
1.4609 + md->nl[0] = newline;
1.4610 + }
1.4611 + }
1.4612 +
1.4613 +/* Partial matching is supported only for a restricted set of regexes at the
1.4614 +moment. */
1.4615 +
1.4616 +if (md->partial && (re->flags & PCRE_NOPARTIAL) != 0)
1.4617 + return PCRE_ERROR_BADPARTIAL;
1.4618 +
1.4619 +/* Check a UTF-8 string if required. Unfortunately there's no way of passing
1.4620 +back the character offset. */
1.4621 +
1.4622 +#ifdef SUPPORT_UTF8
1.4623 +if (utf8 && (options & PCRE_NO_UTF8_CHECK) == 0)
1.4624 + {
1.4625 + if (_pcre_valid_utf8((USPTR)subject, length) >= 0)
1.4626 + return PCRE_ERROR_BADUTF8;
1.4627 + if (start_offset > 0 && start_offset < length)
1.4628 + {
1.4629 + int tb = ((USPTR)subject)[start_offset];
1.4630 + if (tb > 127)
1.4631 + {
1.4632 + tb &= 0xc0;
1.4633 + if (tb != 0 && tb != 0xc0) return PCRE_ERROR_BADUTF8_OFFSET;
1.4634 + }
1.4635 + }
1.4636 + }
1.4637 +#endif
1.4638 +
1.4639 +/* The ims options can vary during the matching as a result of the presence
1.4640 +of (?ims) items in the pattern. They are kept in a local variable so that
1.4641 +restoring at the exit of a group is easy. */
1.4642 +
1.4643 +ims = re->options & (PCRE_CASELESS|PCRE_MULTILINE|PCRE_DOTALL);
1.4644 +
1.4645 +/* If the expression has got more back references than the offsets supplied can
1.4646 +hold, we get a temporary chunk of working store to use during the matching.
1.4647 +Otherwise, we can use the vector supplied, rounding down its size to a multiple
1.4648 +of 3. */
1.4649 +
1.4650 +ocount = offsetcount - (offsetcount % 3);
1.4651 +
1.4652 +if (re->top_backref > 0 && re->top_backref >= ocount/3)
1.4653 + {
1.4654 + ocount = re->top_backref * 3 + 3;
1.4655 + md->offset_vector = (int *)(pcre_malloc)(ocount * sizeof(int));
1.4656 + if (md->offset_vector == NULL) return PCRE_ERROR_NOMEMORY;
1.4657 + using_temporary_offsets = TRUE;
1.4658 + DPRINTF(("Got memory to hold back references\n"));
1.4659 + }
1.4660 +else md->offset_vector = offsets;
1.4661 +
1.4662 +md->offset_end = ocount;
1.4663 +md->offset_max = (2*ocount)/3;
1.4664 +md->offset_overflow = FALSE;
1.4665 +md->capture_last = -1;
1.4666 +
1.4667 +/* Compute the minimum number of offsets that we need to reset each time. Doing
1.4668 +this makes a huge difference to execution time when there aren't many brackets
1.4669 +in the pattern. */
1.4670 +
1.4671 +resetcount = 2 + re->top_bracket * 2;
1.4672 +if (resetcount > offsetcount) resetcount = ocount;
1.4673 +
1.4674 +/* Reset the working variable associated with each extraction. These should
1.4675 +never be used unless previously set, but they get saved and restored, and so we
1.4676 +initialize them to avoid reading uninitialized locations. */
1.4677 +
1.4678 +if (md->offset_vector != NULL)
1.4679 + {
1.4680 + register int *iptr = md->offset_vector + ocount;
1.4681 + register int *iend = iptr - resetcount/2 + 1;
1.4682 + while (--iptr >= iend) *iptr = -1;
1.4683 + }
1.4684 +
1.4685 +/* Set up the first character to match, if available. The first_byte value is
1.4686 +never set for an anchored regular expression, but the anchoring may be forced
1.4687 +at run time, so we have to test for anchoring. The first char may be unset for
1.4688 +an unanchored pattern, of course. If there's no first char and the pattern was
1.4689 +studied, there may be a bitmap of possible first characters. */
1.4690 +
1.4691 +if (!anchored)
1.4692 + {
1.4693 + if ((re->flags & PCRE_FIRSTSET) != 0)
1.4694 + {
1.4695 + first_byte = re->first_byte & 255;
1.4696 + if ((first_byte_caseless = ((re->first_byte & REQ_CASELESS) != 0)) == TRUE)
1.4697 + first_byte = md->lcc[first_byte];
1.4698 + }
1.4699 + else
1.4700 + if (!startline && study != NULL &&
1.4701 + (study->options & PCRE_STUDY_MAPPED) != 0)
1.4702 + start_bits = study->start_bits;
1.4703 + }
1.4704 +
1.4705 +/* For anchored or unanchored matches, there may be a "last known required
1.4706 +character" set. */
1.4707 +
1.4708 +if ((re->flags & PCRE_REQCHSET) != 0)
1.4709 + {
1.4710 + req_byte = re->req_byte & 255;
1.4711 + req_byte_caseless = (re->req_byte & REQ_CASELESS) != 0;
1.4712 + req_byte2 = (tables + fcc_offset)[req_byte]; /* case flipped */
1.4713 + }
1.4714 +
1.4715 +
1.4716 +/* ==========================================================================*/
1.4717 +
1.4718 +/* Loop for handling unanchored repeated matching attempts; for anchored regexs
1.4719 +the loop runs just once. */
1.4720 +
1.4721 +for(;;)
1.4722 + {
1.4723 + USPTR save_end_subject = end_subject;
1.4724 + USPTR new_start_match;
1.4725 +
1.4726 + /* Reset the maximum number of extractions we might see. */
1.4727 +
1.4728 + if (md->offset_vector != NULL)
1.4729 + {
1.4730 + register int *iptr = md->offset_vector;
1.4731 + register int *iend = iptr + resetcount;
1.4732 + while (iptr < iend) *iptr++ = -1;
1.4733 + }
1.4734 +
1.4735 + /* If firstline is TRUE, the start of the match is constrained to the first
1.4736 + line of a multiline string. That is, the match must be before or at the first
1.4737 + newline. Implement this by temporarily adjusting end_subject so that we stop
1.4738 + scanning at a newline. If the match fails at the newline, later code breaks
1.4739 + this loop. */
1.4740 +
1.4741 + if (firstline)
1.4742 + {
1.4743 + USPTR t = start_match;
1.4744 +#ifdef SUPPORT_UTF8
1.4745 + if (utf8)
1.4746 + {
1.4747 + while (t < md->end_subject && !IS_NEWLINE(t))
1.4748 + {
1.4749 + t++;
1.4750 + while (t < end_subject && (*t & 0xc0) == 0x80) t++;
1.4751 + }
1.4752 + }
1.4753 + else
1.4754 +#endif
1.4755 + while (t < md->end_subject && !IS_NEWLINE(t)) t++;
1.4756 + end_subject = t;
1.4757 + }
1.4758 +
1.4759 + /* There are some optimizations that avoid running the match if a known
1.4760 + starting point is not found, or if a known later character is not present.
1.4761 + However, there is an option that disables these, for testing and for ensuring
1.4762 + that all callouts do actually occur. */
1.4763 +
1.4764 + if ((options & PCRE_NO_START_OPTIMIZE) == 0)
1.4765 + {
1.4766 + /* Advance to a unique first byte if there is one. */
1.4767 +
1.4768 + if (first_byte >= 0)
1.4769 + {
1.4770 + if (first_byte_caseless)
1.4771 + while (start_match < end_subject && md->lcc[*start_match] != first_byte)
1.4772 + start_match++;
1.4773 + else
1.4774 + while (start_match < end_subject && *start_match != first_byte)
1.4775 + start_match++;
1.4776 + }
1.4777 +
1.4778 + /* Or to just after a linebreak for a multiline match */
1.4779 +
1.4780 + else if (startline)
1.4781 + {
1.4782 + if (start_match > md->start_subject + start_offset)
1.4783 + {
1.4784 +#ifdef SUPPORT_UTF8
1.4785 + if (utf8)
1.4786 + {
1.4787 + while (start_match < end_subject && !WAS_NEWLINE(start_match))
1.4788 + {
1.4789 + start_match++;
1.4790 + while(start_match < end_subject && (*start_match & 0xc0) == 0x80)
1.4791 + start_match++;
1.4792 + }
1.4793 + }
1.4794 + else
1.4795 +#endif
1.4796 + while (start_match < end_subject && !WAS_NEWLINE(start_match))
1.4797 + start_match++;
1.4798 +
1.4799 + /* If we have just passed a CR and the newline option is ANY or ANYCRLF,
1.4800 + and we are now at a LF, advance the match position by one more character.
1.4801 + */
1.4802 +
1.4803 + if (start_match[-1] == CHAR_CR &&
1.4804 + (md->nltype == NLTYPE_ANY || md->nltype == NLTYPE_ANYCRLF) &&
1.4805 + start_match < end_subject &&
1.4806 + *start_match == CHAR_NL)
1.4807 + start_match++;
1.4808 + }
1.4809 + }
1.4810 +
1.4811 + /* Or to a non-unique first byte after study */
1.4812 +
1.4813 + else if (start_bits != NULL)
1.4814 + {
1.4815 + while (start_match < end_subject)
1.4816 + {
1.4817 + register unsigned int c = *start_match;
1.4818 + if ((start_bits[c/8] & (1 << (c&7))) == 0) start_match++;
1.4819 + else break;
1.4820 + }
1.4821 + }
1.4822 + } /* Starting optimizations */
1.4823 +
1.4824 + /* Restore fudged end_subject */
1.4825 +
1.4826 + end_subject = save_end_subject;
1.4827 +
1.4828 +#ifdef DEBUG /* Sigh. Some compilers never learn. */
1.4829 + printf(">>>> Match against: ");
1.4830 + pchars(start_match, end_subject - start_match, TRUE, md);
1.4831 + printf("\n");
1.4832 +#endif
1.4833 +
1.4834 + /* If req_byte is set, we know that that character must appear in the
1.4835 + subject for the match to succeed. If the first character is set, req_byte
1.4836 + must be later in the subject; otherwise the test starts at the match point.
1.4837 + This optimization can save a huge amount of backtracking in patterns with
1.4838 + nested unlimited repeats that aren't going to match. Writing separate code
1.4839 + for cased/caseless versions makes it go faster, as does using an
1.4840 + autoincrement and backing off on a match.
1.4841 +
1.4842 + HOWEVER: when the subject string is very, very long, searching to its end
1.4843 + can take a long time, and give bad performance on quite ordinary patterns.
1.4844 + This showed up when somebody was matching something like /^\d+C/ on a
1.4845 + 32-megabyte string... so we don't do this when the string is sufficiently
1.4846 + long.
1.4847 +
1.4848 + ALSO: this processing is disabled when partial matching is requested, or if
1.4849 + disabling is explicitly requested. */
1.4850 +
1.4851 + if ((options & PCRE_NO_START_OPTIMIZE) == 0 &&
1.4852 + req_byte >= 0 &&
1.4853 + end_subject - start_match < REQ_BYTE_MAX &&
1.4854 + !md->partial)
1.4855 + {
1.4856 + register USPTR p = start_match + ((first_byte >= 0)? 1 : 0);
1.4857 +
1.4858 + /* We don't need to repeat the search if we haven't yet reached the
1.4859 + place we found it at last time. */
1.4860 +
1.4861 + if (p > req_byte_ptr)
1.4862 + {
1.4863 + if (req_byte_caseless)
1.4864 + {
1.4865 + while (p < end_subject)
1.4866 + {
1.4867 + register int pp = *p++;
1.4868 + if (pp == req_byte || pp == req_byte2) { p--; break; }
1.4869 + }
1.4870 + }
1.4871 + else
1.4872 + {
1.4873 + while (p < end_subject)
1.4874 + {
1.4875 + if (*p++ == req_byte) { p--; break; }
1.4876 + }
1.4877 + }
1.4878 +
1.4879 + /* If we can't find the required character, break the matching loop,
1.4880 + forcing a match failure. */
1.4881 +
1.4882 + if (p >= end_subject)
1.4883 + {
1.4884 + rc = MATCH_NOMATCH;
1.4885 + break;
1.4886 + }
1.4887 +
1.4888 + /* If we have found the required character, save the point where we
1.4889 + found it, so that we don't search again next time round the loop if
1.4890 + the start hasn't passed this character yet. */
1.4891 +
1.4892 + req_byte_ptr = p;
1.4893 + }
1.4894 + }
1.4895 +
1.4896 + /* OK, we can now run the match. */
1.4897 +
1.4898 + md->start_match_ptr = start_match;
1.4899 + md->match_call_count = 0;
1.4900 + rc = match(start_match, md->start_code, start_match, 2, md, ims, NULL, 0, 0);
1.4901 +
1.4902 + switch(rc)
1.4903 + {
1.4904 + /* NOMATCH and PRUNE advance by one character. THEN at this level acts
1.4905 + exactly like PRUNE. */
1.4906 +
1.4907 + case MATCH_NOMATCH:
1.4908 + case MATCH_PRUNE:
1.4909 + case MATCH_THEN:
1.4910 + new_start_match = start_match + 1;
1.4911 +#ifdef SUPPORT_UTF8
1.4912 + if (utf8)
1.4913 + while(new_start_match < end_subject && (*new_start_match & 0xc0) == 0x80)
1.4914 + new_start_match++;
1.4915 +#endif
1.4916 + break;
1.4917 +
1.4918 + /* SKIP passes back the next starting point explicitly. */
1.4919 +
1.4920 + case MATCH_SKIP:
1.4921 + new_start_match = md->start_match_ptr;
1.4922 + break;
1.4923 +
1.4924 + /* COMMIT disables the bumpalong, but otherwise behaves as NOMATCH. */
1.4925 +
1.4926 + case MATCH_COMMIT:
1.4927 + rc = MATCH_NOMATCH;
1.4928 + goto ENDLOOP;
1.4929 +
1.4930 + /* Any other return is some kind of error. */
1.4931 +
1.4932 + default:
1.4933 + goto ENDLOOP;
1.4934 + }
1.4935 +
1.4936 + /* Control reaches here for the various types of "no match at this point"
1.4937 + result. Reset the code to MATCH_NOMATCH for subsequent checking. */
1.4938 +
1.4939 + rc = MATCH_NOMATCH;
1.4940 +
1.4941 + /* If PCRE_FIRSTLINE is set, the match must happen before or at the first
1.4942 + newline in the subject (though it may continue over the newline). Therefore,
1.4943 + if we have just failed to match, starting at a newline, do not continue. */
1.4944 +
1.4945 + if (firstline && IS_NEWLINE(start_match)) break;
1.4946 +
1.4947 + /* Advance to new matching position */
1.4948 +
1.4949 + start_match = new_start_match;
1.4950 +
1.4951 + /* Break the loop if the pattern is anchored or if we have passed the end of
1.4952 + the subject. */
1.4953 +
1.4954 + if (anchored || start_match > end_subject) break;
1.4955 +
1.4956 + /* If we have just passed a CR and we are now at a LF, and the pattern does
1.4957 + not contain any explicit matches for \r or \n, and the newline option is CRLF
1.4958 + or ANY or ANYCRLF, advance the match position by one more character. */
1.4959 +
1.4960 + if (start_match[-1] == CHAR_CR &&
1.4961 + start_match < end_subject &&
1.4962 + *start_match == CHAR_NL &&
1.4963 + (re->flags & PCRE_HASCRORLF) == 0 &&
1.4964 + (md->nltype == NLTYPE_ANY ||
1.4965 + md->nltype == NLTYPE_ANYCRLF ||
1.4966 + md->nllen == 2))
1.4967 + start_match++;
1.4968 +
1.4969 + } /* End of for(;;) "bumpalong" loop */
1.4970 +
1.4971 +/* ==========================================================================*/
1.4972 +
1.4973 +/* We reach here when rc is not MATCH_NOMATCH, or if one of the stopping
1.4974 +conditions is true:
1.4975 +
1.4976 +(1) The pattern is anchored or the match was failed by (*COMMIT);
1.4977 +
1.4978 +(2) We are past the end of the subject;
1.4979 +
1.4980 +(3) PCRE_FIRSTLINE is set and we have failed to match at a newline, because
1.4981 + this option requests that a match occur at or before the first newline in
1.4982 + the subject.
1.4983 +
1.4984 +When we have a match and the offset vector is big enough to deal with any
1.4985 +backreferences, captured substring offsets will already be set up. In the case
1.4986 +where we had to get some local store to hold offsets for backreference
1.4987 +processing, copy those that we can. In this case there need not be overflow if
1.4988 +certain parts of the pattern were not used, even though there are more
1.4989 +capturing parentheses than vector slots. */
1.4990 +
1.4991 +ENDLOOP:
1.4992 +
1.4993 +if (rc == MATCH_MATCH)
1.4994 + {
1.4995 + if (using_temporary_offsets)
1.4996 + {
1.4997 + if (offsetcount >= 4)
1.4998 + {
1.4999 + memcpy(offsets + 2, md->offset_vector + 2,
1.5000 + (offsetcount - 2) * sizeof(int));
1.5001 + DPRINTF(("Copied offsets from temporary memory\n"));
1.5002 + }
1.5003 + if (md->end_offset_top > offsetcount) md->offset_overflow = TRUE;
1.5004 + DPRINTF(("Freeing temporary memory\n"));
1.5005 + (pcre_free)(md->offset_vector);
1.5006 + }
1.5007 +
1.5008 + /* Set the return code to the number of captured strings, or 0 if there are
1.5009 + too many to fit into the vector. */
1.5010 +
1.5011 + rc = md->offset_overflow? 0 : md->end_offset_top/2;
1.5012 +
1.5013 + /* If there is space, set up the whole thing as substring 0. The value of
1.5014 + md->start_match_ptr might be modified if \K was encountered on the success
1.5015 + matching path. */
1.5016 +
1.5017 + if (offsetcount < 2) rc = 0; else
1.5018 + {
1.5019 + offsets[0] = md->start_match_ptr - md->start_subject;
1.5020 + offsets[1] = md->end_match_ptr - md->start_subject;
1.5021 + }
1.5022 +
1.5023 + DPRINTF((">>>> returning %d\n", rc));
1.5024 + return rc;
1.5025 + }
1.5026 +
1.5027 +/* Control gets here if there has been an error, or if the overall match
1.5028 +attempt has failed at all permitted starting positions. */
1.5029 +
1.5030 +if (using_temporary_offsets)
1.5031 + {
1.5032 + DPRINTF(("Freeing temporary memory\n"));
1.5033 + (pcre_free)(md->offset_vector);
1.5034 + }
1.5035 +
1.5036 +if (rc != MATCH_NOMATCH)
1.5037 + {
1.5038 + DPRINTF((">>>> error: returning %d\n", rc));
1.5039 + return rc;
1.5040 + }
1.5041 +else if (md->partial && md->hitend)
1.5042 + {
1.5043 + DPRINTF((">>>> returning PCRE_ERROR_PARTIAL\n"));
1.5044 + return PCRE_ERROR_PARTIAL;
1.5045 + }
1.5046 +else
1.5047 + {
1.5048 + DPRINTF((">>>> returning PCRE_ERROR_NOMATCH\n"));
1.5049 + return PCRE_ERROR_NOMATCH;
1.5050 + }
1.5051 +}
1.5052 +
1.5053 +/* End of pcre_exec.c */