ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid-7.2/lib/pcre/pcre_exec.c
(Generate patch)

Comparing ircd-hybrid-7.2/lib/pcre/pcre_exec.c (file contents):
Revision 962 by lusky, Sun Oct 2 21:05:51 2005 UTC vs.
Revision 963 by michael, Sat Aug 1 12:23:39 2009 UTC

# Line 1 | Line 1
1 /* $Id$ */
2
1   /*************************************************
2   *      Perl-Compatible Regular Expressions       *
3   *************************************************/
# Line 8 | Line 6
6   and semantics are as close as possible to those of the Perl 5 language.
7  
8                         Written by Philip Hazel
9 <           Copyright (c) 1997-2005 University of Cambridge
9 >           Copyright (c) 1997-2009 University of Cambridge
10  
11   -----------------------------------------------------------------------------
12   Redistribution and use in source and binary forms, with or without
# Line 45 | Line 43 | pattern matching using an NFA algorithm,
43   possible. There are also some static supporting functions. */
44  
45  
46 + #define NLBLOCK md             /* Block containing newline information */
47 + #define PSSTART start_subject  /* Field containing processed string start */
48 + #define PSEND   end_subject    /* Field containing processed string end */
49 +
50   #include "pcre_internal.h"
51  
52 + /* Undefine some potentially clashing cpp symbols */
53  
54 < /* Structure for building a chain of data that actually lives on the
55 < stack, for holding the values of the subject pointer at the start of each
53 < subpattern, so as to detect when an empty string has been matched by a
54 < subpattern - to break infinite loops. When NO_RECURSE is set, these blocks
55 < are on the heap, not on the stack. */
56 <
57 < typedef struct eptrblock {
58 <  struct eptrblock *epb_prev;
59 <  const uschar *epb_saved_eptr;
60 < } eptrblock;
54 > #undef min
55 > #undef max
56  
57   /* Flag bits for the match() function */
58  
59 < #define match_condassert   0x01    /* Called to check a condition assertion */
60 < #define match_isgroup      0x02    /* Set if start of bracketed group */
59 > #define match_condassert     0x01  /* Called to check a condition assertion */
60 > #define match_cbegroup       0x02  /* Could-be-empty unlimited repeat group */
61  
62   /* Non-error returns from the match() function. Error returns are externally
63   defined PCRE_ERROR_xxx codes, which are all negative. */
# Line 70 | Line 65 | defined PCRE_ERROR_xxx codes, which are
65   #define MATCH_MATCH        1
66   #define MATCH_NOMATCH      0
67  
68 + /* Special internal returns from the match() function. Make them sufficiently
69 + negative to avoid the external error codes. */
70 +
71 + #define MATCH_COMMIT       (-999)
72 + #define MATCH_PRUNE        (-998)
73 + #define MATCH_SKIP         (-997)
74 + #define MATCH_THEN         (-996)
75 +
76   /* Maximum number of ints of offset to save on the stack for recursive calls.
77   If the offset vector is bigger, malloc is used. This should be a multiple of 3,
78   because the offset vector is always a multiple of 3 long. */
# Line 83 | Line 86 | static const char rep_max[] = { 0, 0, 0,
86  
87  
88  
86 #ifdef DEBUG
87 /*************************************************
88 *        Debugging function to print chars       *
89 *************************************************/
90
91 /* Print a sequence of chars in printable format, stopping at the end of the
92 subject if the requested.
93
94 Arguments:
95  p           points to characters
96  length      number to print
97  is_subject  TRUE if printing from within md->start_subject
98  md          pointer to matching data block, if is_subject is TRUE
99
100 Returns:     nothing
101 */
102
103 static void
104 pchars(const uschar *p, int length, BOOL is_subject, match_data *md)
105 {
106 int c;
107 if (is_subject && length > md->end_subject - p) length = md->end_subject - p;
108 while (length-- > 0)
109  if (isprint(c = *(p++))) printf("%c", c); else printf("\\x%02x", c);
110 }
111 #endif
89  
90  
91  
# Line 130 | Line 107 | Returns:      TRUE if matched
107   */
108  
109   static BOOL
110 < match_ref(int offset, register const uschar *eptr, int length, match_data *md,
110 > match_ref(int offset, register USPTR eptr, int length, match_data *md,
111    unsigned long int ims)
112   {
113 < const uschar *p = md->start_subject + md->offset_vector[offset];
113 > USPTR p = md->start_subject + md->offset_vector[offset];
114  
138 #ifdef DEBUG
139 if (eptr >= md->end_subject)
140  printf("matching subject <null>");
141 else
142  {
143  printf("matching subject ");
144  pchars(eptr, length, TRUE, md);
145  }
146 printf(" against backref ");
147 pchars(p, length, FALSE, md);
148 printf("\n");
149 #endif
115  
116   /* Always fail if not enough characters left */
117  
118   if (length > md->end_subject - eptr) return FALSE;
119  
120 < /* Separate the caselesss case for speed */
120 > /* Separate the caseless case for speed. In UTF-8 mode we can only do this
121 > properly if Unicode properties are supported. Otherwise, we can check only
122 > ASCII characters. */
123  
124   if ((ims & PCRE_CASELESS) != 0)
125    {
126 + #ifdef SUPPORT_UTF8
127 + #ifdef SUPPORT_UCP
128 +  if (md->utf8)
129 +    {
130 +    USPTR endptr = eptr + length;
131 +    while (eptr < endptr)
132 +      {
133 +      int c, d;
134 +      GETCHARINC(c, eptr);
135 +      GETCHARINC(d, p);
136 +      if (c != d && c != UCD_OTHERCASE(d)) return FALSE;
137 +      }
138 +    }
139 +  else
140 + #endif
141 + #endif
142 +
143 +  /* The same code works when not in UTF-8 mode and in UTF-8 mode when there
144 +  is no UCP support. */
145 +
146    while (length-- > 0)
147 <    if (md->lcc[*p++] != md->lcc[*eptr++]) return FALSE;
147 >    { if (md->lcc[*p++] != md->lcc[*eptr++]) return FALSE; }
148    }
149 +
150 + /* In the caseful case, we can just compare the bytes, whether or not we
151 + are in UTF-8 mode. */
152 +
153   else
154    { while (length-- > 0) if (*p++ != *eptr++) return FALSE; }
155  
# Line 171 | Line 162 | return TRUE;
162   ****************************************************************************
163                     RECURSION IN THE match() FUNCTION
164  
165 < The match() function is highly recursive. Some regular expressions can cause
166 < it to recurse thousands of times. I was writing for Unix, so I just let it
167 < call itself recursively. This uses the stack for saving everything that has
168 < to be saved for a recursive call. On Unix, the stack can be large, and this
169 < works fine.
170 <
171 < It turns out that on non-Unix systems there are problems with programs that
172 < use a lot of stack. (This despite the fact that every last chip has oodles
173 < of memory these days, and techniques for extending the stack have been known
174 < for decades.) So....
165 > The match() function is highly recursive, though not every recursive call
166 > increases the recursive depth. Nevertheless, some regular expressions can cause
167 > it to recurse to a great depth. I was writing for Unix, so I just let it call
168 > itself recursively. This uses the stack for saving everything that has to be
169 > saved for a recursive call. On Unix, the stack can be large, and this works
170 > fine.
171 >
172 > It turns out that on some non-Unix-like systems there are problems with
173 > programs that use a lot of stack. (This despite the fact that every last chip
174 > has oodles of memory these days, and techniques for extending the stack have
175 > been known for decades.) So....
176  
177   There is a fudge, triggered by defining NO_RECURSE, which avoids recursive
178   calls by keeping local variables that need to be preserved in blocks of memory
179 < obtained from malloc instead instead of on the stack. Macros are used to
179 > obtained from malloc() instead instead of on the stack. Macros are used to
180   achieve this so that the actual code doesn't look very different to what it
181   always used to.
182 +
183 + The original heap-recursive code used longjmp(). However, it seems that this
184 + can be very slow on some operating systems. Following a suggestion from Stan
185 + Switzer, the use of longjmp() has been abolished, at the cost of having to
186 + provide a unique number for each call to RMATCH. There is no way of generating
187 + a sequence of numbers at compile time in C. I have given them names, to make
188 + them stand out more clearly.
189 +
190 + Crude tests on x86 Linux show a small speedup of around 5-8%. However, on
191 + FreeBSD, avoiding longjmp() more than halves the time taken to run the standard
192 + tests. Furthermore, not using longjmp() means that local dynamic variables
193 + don't have indeterminate values; this has meant that the frame size can be
194 + reduced because the result can be "passed back" by straight setting of the
195 + variable instead of being passed in the frame.
196   ****************************************************************************
197   ***************************************************************************/
198  
199 + /* Numbers for RMATCH calls. When this list is changed, the code at HEAP_RETURN
200 + below must be updated in sync.  */
201  
202 < /* These versions of the macros use the stack, as normal */
202 > enum { RM1=1, RM2,  RM3,  RM4,  RM5,  RM6,  RM7,  RM8,  RM9,  RM10,
203 >       RM11,  RM12, RM13, RM14, RM15, RM16, RM17, RM18, RM19, RM20,
204 >       RM21,  RM22, RM23, RM24, RM25, RM26, RM27, RM28, RM29, RM30,
205 >       RM31,  RM32, RM33, RM34, RM35, RM36, RM37, RM38, RM39, RM40,
206 >       RM41,  RM42, RM43, RM44, RM45, RM46, RM47, RM48, RM49, RM50,
207 >       RM51,  RM52, RM53, RM54 };
208 >
209 > /* These versions of the macros use the stack, as normal. There are debugging
210 > versions and production versions. Note that the "rw" argument of RMATCH isn't
211 > actuall used in this definition. */
212  
213   #ifndef NO_RECURSE
214   #define REGISTER register
215 < #define RMATCH(rx,ra,rb,rc,rd,re,rf,rg) rx = match(ra,rb,rc,rd,re,rf,rg)
215 >
216 > #define RMATCH(ra,rb,rc,rd,re,rf,rg,rw) \
217 >  rrc = match(ra,rb,mstart,rc,rd,re,rf,rg,rdepth+1)
218   #define RRETURN(ra) return ra
219 +
220   #else
221  
222  
223 < /* These versions of the macros manage a private stack on the heap. Note
224 < that the rd argument of RMATCH isn't actually used. It's the md argument of
225 < match(), which never changes. */
223 > /* These versions of the macros manage a private stack on the heap. Note that
224 > the "rd" argument of RMATCH isn't actually used in this definition. It's the md
225 > argument of match(), which never changes. */
226  
227   #define REGISTER
228  
229 < #define RMATCH(rx,ra,rb,rc,rd,re,rf,rg)\
229 > #define RMATCH(ra,rb,rc,rd,re,rf,rg,rw)\
230    {\
231    heapframe *newframe = (pcre_stack_malloc)(sizeof(heapframe));\
232 <  if (setjmp(frame->Xwhere) == 0)\
233 <    {\
234 <    newframe->Xeptr = ra;\
235 <    newframe->Xecode = rb;\
236 <    newframe->Xoffset_top = rc;\
237 <    newframe->Xims = re;\
238 <    newframe->Xeptrb = rf;\
239 <    newframe->Xflags = rg;\
240 <    newframe->Xprevframe = frame;\
241 <    frame = newframe;\
242 <    DPRINTF(("restarting from line %d\n", __LINE__));\
243 <    goto HEAP_RECURSE;\
244 <    }\
245 <  else\
246 <    {\
227 <    DPRINTF(("longjumped back to line %d\n", __LINE__));\
228 <    frame = md->thisframe;\
229 <    rx = frame->Xresult;\
230 <    }\
232 >  frame->Xwhere = rw; \
233 >  newframe->Xeptr = ra;\
234 >  newframe->Xecode = rb;\
235 >  newframe->Xmstart = mstart;\
236 >  newframe->Xoffset_top = rc;\
237 >  newframe->Xims = re;\
238 >  newframe->Xeptrb = rf;\
239 >  newframe->Xflags = rg;\
240 >  newframe->Xrdepth = frame->Xrdepth + 1;\
241 >  newframe->Xprevframe = frame;\
242 >  frame = newframe;\
243 >  DPRINTF(("restarting from line %d\n", __LINE__));\
244 >  goto HEAP_RECURSE;\
245 >  L_##rw:\
246 >  DPRINTF(("jumped back to line %d\n", __LINE__));\
247    }
248  
249   #define RRETURN(ra)\
# Line 237 | Line 253 | match(), which never changes. */
253    (pcre_stack_free)(newframe);\
254    if (frame != NULL)\
255      {\
256 <    frame->Xresult = ra;\
257 <    md->thisframe = frame;\
242 <    longjmp(frame->Xwhere, 1);\
256 >    rrc = ra;\
257 >    goto HEAP_RETURN;\
258      }\
259    return ra;\
260    }
# Line 252 | Line 267 | typedef struct heapframe {
267  
268    /* Function arguments that may change */
269  
270 <  const uschar *Xeptr;
270 >  USPTR Xeptr;
271    const uschar *Xecode;
272 +  USPTR Xmstart;
273    int Xoffset_top;
274    long int Xims;
275    eptrblock *Xeptrb;
276    int Xflags;
277 +  unsigned int Xrdepth;
278  
279    /* Function local variables */
280  
281 <  const uschar *Xcallpat;
282 <  const uschar *Xcharptr;
283 <  const uschar *Xdata;
284 <  const uschar *Xnext;
285 <  const uschar *Xpp;
286 <  const uschar *Xprev;
287 <  const uschar *Xsaved_eptr;
281 >  USPTR Xcallpat;
282 > #ifdef SUPPORT_UTF8
283 >  USPTR Xcharptr;
284 > #endif
285 >  USPTR Xdata;
286 >  USPTR Xnext;
287 >  USPTR Xpp;
288 >  USPTR Xprev;
289 >  USPTR Xsaved_eptr;
290  
291    recursion_info Xnew_recursive;
292  
293    BOOL Xcur_is_word;
294    BOOL Xcondition;
276  BOOL Xminimize;
295    BOOL Xprev_is_word;
296  
297    unsigned long int Xoriginal_ims;
298  
299 + #ifdef SUPPORT_UCP
300 +  int Xprop_type;
301 +  int Xprop_value;
302 +  int Xprop_fail_result;
303 +  int Xprop_category;
304 +  int Xprop_chartype;
305 +  int Xprop_script;
306 +  int Xoclength;
307 +  uschar Xocchars[8];
308 + #endif
309 +
310 +  int Xcodelink;
311    int Xctype;
312 <  int Xfc;
312 >  unsigned int Xfc;
313    int Xfi;
314    int Xlength;
315    int Xmax;
# Line 293 | Line 323 | typedef struct heapframe {
323  
324    eptrblock Xnewptrb;
325  
326 <  /* Place to pass back result, and where to jump back to */
326 >  /* Where to jump back to */
327  
328 <  int  Xresult;
299 <  jmp_buf Xwhere;
328 >  int Xwhere;
329  
330   } heapframe;
331  
# Line 312 | Line 341 | typedef struct heapframe {
341   *         Match from current position            *
342   *************************************************/
343  
344 < /* On entry ecode points to the first opcode, and eptr to the first character
316 < in the subject string, while eptrb holds the value of eptr at the start of the
317 < last bracketed group - used for breaking infinite loops matching zero-length
318 < strings. This function is called recursively in many circumstances. Whenever it
344 > /* This function is called recursively in many circumstances. Whenever it
345   returns a negative (error) response, the outer incarnation must also return the
346   same response.
347  
# Line 325 | Line 351 | performance. Tests using gcc on a SPARC
351   made performance worse.
352  
353   Arguments:
354 <   eptr        pointer in subject
355 <   ecode       position in code
354 >   eptr        pointer to current character in subject
355 >   ecode       pointer to current position in compiled code
356 >   mstart      pointer to the current match start position (can be modified
357 >                 by encountering \K)
358     offset_top  current top pointer
359     md          pointer to "static" info for the match
360     ims         current /i, /m, and /s options
# Line 334 | Line 362 | Arguments:
362                   brackets - for testing for empty matches
363     flags       can contain
364                   match_condassert - this is an assertion condition
365 <                 match_isgroup - this is the start of a bracketed group
365 >                 match_cbegroup - this is the start of an unlimited repeat
366 >                   group that can match an empty string
367 >   rdepth      the recursion depth
368  
369   Returns:       MATCH_MATCH if matched            )  these values are >= 0
370                 MATCH_NOMATCH if failed to match  )
371                 a negative PCRE_ERROR_xxx value if aborted by an error condition
372 <                 (e.g. stopped by recursion limit)
372 >                 (e.g. stopped by repeated call or recursion limit)
373   */
374  
375   static int
376 < match(REGISTER const uschar *eptr, REGISTER const uschar *ecode,
376 > match(REGISTER USPTR eptr, REGISTER const uschar *ecode, USPTR mstart,
377    int offset_top, match_data *md, unsigned long int ims, eptrblock *eptrb,
378 <  int flags)
378 >  int flags, unsigned int rdepth)
379   {
380   /* These variables do not need to be preserved over recursion in this function,
381 < so they can be ordinary variables in all cases. Mark them with "register"
382 < because they are used a lot in loops. */
381 > so they can be ordinary variables in all cases. Mark some of them with
382 > "register" because they are used a lot in loops. */
383  
384 < register int  rrc;    /* Returns from recursive calls */
385 < register int  i;      /* Used for loops not involving calls to RMATCH() */
386 < register int  c;      /* Character values not kept over RMATCH() calls */
387 < register BOOL utf8;   /* Local copy of UTF-8 flag for speed */
384 > register int  rrc;         /* Returns from recursive calls */
385 > register int  i;           /* Used for loops not involving calls to RMATCH() */
386 > register unsigned int c;   /* Character values not kept over RMATCH() calls */
387 > register BOOL utf8;        /* Local copy of UTF-8 flag for speed */
388 >
389 > BOOL minimize, possessive; /* Quantifier options */
390 > int condcode;
391  
392   /* When recursion is not being used, all "local" variables that have to be
393   preserved over calls to RMATCH() are part of a "frame" which is obtained from
# Line 369 | Line 402 | frame->Xprevframe = NULL;            /*
402  
403   frame->Xeptr = eptr;
404   frame->Xecode = ecode;
405 + frame->Xmstart = mstart;
406   frame->Xoffset_top = offset_top;
407   frame->Xims = ims;
408   frame->Xeptrb = eptrb;
409   frame->Xflags = flags;
410 + frame->Xrdepth = rdepth;
411  
412   /* This is where control jumps back to to effect "recursion" */
413  
# Line 382 | Line 417 | HEAP_RECURSE:
417  
418   #define eptr               frame->Xeptr
419   #define ecode              frame->Xecode
420 + #define mstart             frame->Xmstart
421   #define offset_top         frame->Xoffset_top
422   #define ims                frame->Xims
423   #define eptrb              frame->Xeptrb
424   #define flags              frame->Xflags
425 + #define rdepth             frame->Xrdepth
426  
427   /* Ditto for the local variables */
428  
429 + #ifdef SUPPORT_UTF8
430 + #define charptr            frame->Xcharptr
431 + #endif
432   #define callpat            frame->Xcallpat
433 + #define codelink           frame->Xcodelink
434   #define data               frame->Xdata
435   #define next               frame->Xnext
436   #define pp                 frame->Xpp
# Line 400 | Line 441 | HEAP_RECURSE:
441  
442   #define cur_is_word        frame->Xcur_is_word
443   #define condition          frame->Xcondition
403 #define minimize           frame->Xminimize
444   #define prev_is_word       frame->Xprev_is_word
445  
446   #define original_ims       frame->Xoriginal_ims
447  
448 + #ifdef SUPPORT_UCP
449 + #define prop_type          frame->Xprop_type
450 + #define prop_value         frame->Xprop_value
451 + #define prop_fail_result   frame->Xprop_fail_result
452 + #define prop_category      frame->Xprop_category
453 + #define prop_chartype      frame->Xprop_chartype
454 + #define prop_script        frame->Xprop_script
455 + #define oclength           frame->Xoclength
456 + #define occhars            frame->Xocchars
457 + #endif
458 +
459   #define ctype              frame->Xctype
460   #define fc                 frame->Xfc
461   #define fi                 frame->Xfi
# Line 426 | Line 477 | HEAP_RECURSE:
477   get preserved during recursion in the normal way. In this environment, fi and
478   i, and fc and c, can be the same variables. */
479  
480 < #else
480 > #else         /* NO_RECURSE not defined */
481   #define fi i
482   #define fc c
483  
484  
485 < const uschar *callpat;             /* them within each of those blocks.    */
486 < const uschar *data;                /* However, in order to accommodate the */
487 < const uschar *next;                /* version of this code that uses an    */
488 < const uschar *pp;                  /* external "stack" implemented on the  */
489 < const uschar *prev;                /* heap, it is easier to declare them   */
490 < const uschar *saved_eptr;          /* all here, so the declarations can    */
491 <                                   /* be cut out in a block. The only      */
492 < recursion_info new_recursive;      /* declarations within blocks below are */
493 <                                   /* for variables that do not have to    */
494 < BOOL cur_is_word;                  /* be preserved over a recursive call   */
495 < BOOL condition;                    /* to RMATCH().                         */
496 < BOOL minimize;
485 > #ifdef SUPPORT_UTF8                /* Many of these variables are used only  */
486 > const uschar *charptr;             /* in small blocks of the code. My normal */
487 > #endif                             /* style of coding would have declared    */
488 > const uschar *callpat;             /* them within each of those blocks.      */
489 > const uschar *data;                /* However, in order to accommodate the   */
490 > const uschar *next;                /* version of this code that uses an      */
491 > USPTR         pp;                  /* external "stack" implemented on the    */
492 > const uschar *prev;                /* heap, it is easier to declare them all */
493 > USPTR         saved_eptr;          /* here, so the declarations can be cut   */
494 >                                   /* out in a block. The only declarations  */
495 > recursion_info new_recursive;      /* within blocks below are for variables  */
496 >                                   /* that do not have to be preserved over  */
497 > BOOL cur_is_word;                  /* a recursive call to RMATCH().          */
498 > BOOL condition;
499   BOOL prev_is_word;
500  
501   unsigned long int original_ims;
502  
503 + #ifdef SUPPORT_UCP
504 + int prop_type;
505 + int prop_value;
506 + int prop_fail_result;
507 + int prop_category;
508 + int prop_chartype;
509 + int prop_script;
510 + int oclength;
511 + uschar occhars[8];
512 + #endif
513  
514 + int codelink;
515   int ctype;
516   int length;
517   int max;
# Line 460 | Line 524 | int save_offset1, save_offset2, save_off
524   int stacksave[REC_STACK_SAVE_MAX];
525  
526   eptrblock newptrb;
527 + #endif     /* NO_RECURSE */
528 +
529 + /* These statements are here to stop the compiler complaining about unitialized
530 + variables. */
531 +
532 + #ifdef SUPPORT_UCP
533 + prop_value = 0;
534 + prop_fail_result = 0;
535   #endif
536  
537 < /* OK, now we can get on with the real code of the function. Recursion is
538 < specified by the macros RMATCH and RRETURN. When NO_RECURSE is *not* defined,
539 < these just turn into a recursive call to match() and a "return", respectively.
540 < However, RMATCH isn't like a function call because it's quite a complicated
541 < macro. It has to be used in one particular way. This shouldn't, however, impact
542 < performance when true recursion is being used. */
537 >
538 > /* This label is used for tail recursion, which is used in a few cases even
539 > when NO_RECURSE is not defined, in order to reduce the amount of stack that is
540 > used. Thanks to Ian Taylor for noticing this possibility and sending the
541 > original patch. */
542 >
543 > TAIL_RECURSE:
544 >
545 > /* OK, now we can get on with the real code of the function. Recursive calls
546 > are specified by the macro RMATCH and RRETURN is used to return. When
547 > NO_RECURSE is *not* defined, these just turn into a recursive call to match()
548 > and a "return", respectively (possibly with some debugging if DEBUG is
549 > defined). However, RMATCH isn't like a function call because it's quite a
550 > complicated macro. It has to be used in one particular way. This shouldn't,
551 > however, impact performance when true recursion is being used. */
552 >
553 > #ifdef SUPPORT_UTF8
554 > utf8 = md->utf8;       /* Local copy of the flag */
555 > #else
556 > utf8 = FALSE;
557 > #endif
558 >
559 > /* First check that we haven't called match() too many times, or that we
560 > haven't exceeded the recursive call limit. */
561  
562   if (md->match_call_count++ >= md->match_limit) RRETURN(PCRE_ERROR_MATCHLIMIT);
563 + if (rdepth >= md->match_limit_recursion) RRETURN(PCRE_ERROR_RECURSIONLIMIT);
564  
565   original_ims = ims;    /* Save for resetting on ')' */
475 utf8 = md->utf8;       /* Local copy of the flag */
566  
567 < /* At the start of a bracketed group, add the current subject pointer to the
568 < stack of such pointers, to be re-instated at the end of the group when we hit
569 < the closing ket. When match() is called in other circumstances, we don't add to
570 < this stack. */
567 > /* At the start of a group with an unlimited repeat that may match an empty
568 > string, the match_cbegroup flag is set. When this is the case, add the current
569 > subject pointer to the chain of such remembered pointers, to be checked when we
570 > hit the closing ket, in order to break infinite loops that match no characters.
571 > When match() is called in other circumstances, don't add to the chain. The
572 > match_cbegroup flag must NOT be used with tail recursion, because the memory
573 > block that is used is on the stack, so a new one may be required for each
574 > match(). */
575  
576 < if ((flags & match_isgroup) != 0)
576 > if ((flags & match_cbegroup) != 0)
577    {
484  newptrb.epb_prev = eptrb;
578    newptrb.epb_saved_eptr = eptr;
579 +  newptrb.epb_prev = eptrb;
580    eptrb = &newptrb;
581    }
582  
583 < /* Now start processing the operations. */
583 > /* Now start processing the opcodes. */
584  
585   for (;;)
586    {
587 +  minimize = possessive = FALSE;
588    op = *ecode;
494  minimize = FALSE;
589  
590    /* For partial matching, remember if we ever hit the end of the subject after
591    matching at least one subject character. */
592  
593    if (md->partial &&
594        eptr >= md->end_subject &&
595 <      eptr > md->start_match)
595 >      eptr > mstart)
596      md->hitend = TRUE;
597  
598 <  /* Opening capturing bracket. If there is space in the offset vector, save
505 <  the current subject position in the working slot at the top of the vector. We
506 <  mustn't change the current values of the data slot, because they may be set
507 <  from a previous iteration of this group, and be referred to by a reference
508 <  inside the group.
509 <
510 <  If the bracket fails to match, we need to restore this value and also the
511 <  values of the final offsets, in case they were set by a previous iteration of
512 <  the same bracket.
513 <
514 <  If there isn't enough space in the offset vector, treat this as if it were a
515 <  non-capturing bracket. Don't worry about setting the flag for the error case
516 <  here; that is handled in the code for KET. */
517 <
518 <  if (op > OP_BRA)
598 >  switch(op)
599      {
600 <    number = op - OP_BRA;
601 <
522 <    /* For extended extraction brackets (large number), we have to fish out the
523 <    number from a dummy opcode at the start. */
600 >    case OP_FAIL:
601 >    RRETURN(MATCH_NOMATCH);
602  
603 <    if (number > EXTRACT_BASIC_MAX)
604 <      number = GET2(ecode, 2+LINK_SIZE);
603 >    case OP_PRUNE:
604 >    RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,
605 >      ims, eptrb, flags, RM51);
606 >    if (rrc != MATCH_NOMATCH) RRETURN(rrc);
607 >    RRETURN(MATCH_PRUNE);
608 >
609 >    case OP_COMMIT:
610 >    RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,
611 >      ims, eptrb, flags, RM52);
612 >    if (rrc != MATCH_NOMATCH) RRETURN(rrc);
613 >    RRETURN(MATCH_COMMIT);
614 >
615 >    case OP_SKIP:
616 >    RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,
617 >      ims, eptrb, flags, RM53);
618 >    if (rrc != MATCH_NOMATCH) RRETURN(rrc);
619 >    md->start_match_ptr = eptr;   /* Pass back current position */
620 >    RRETURN(MATCH_SKIP);
621 >
622 >    case OP_THEN:
623 >    RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,
624 >      ims, eptrb, flags, RM54);
625 >    if (rrc != MATCH_NOMATCH) RRETURN(rrc);
626 >    RRETURN(MATCH_THEN);
627 >
628 >    /* Handle a capturing bracket. If there is space in the offset vector, save
629 >    the current subject position in the working slot at the top of the vector.
630 >    We mustn't change the current values of the data slot, because they may be
631 >    set from a previous iteration of this group, and be referred to by a
632 >    reference inside the group.
633 >
634 >    If the bracket fails to match, we need to restore this value and also the
635 >    values of the final offsets, in case they were set by a previous iteration
636 >    of the same bracket.
637 >
638 >    If there isn't enough space in the offset vector, treat this as if it were
639 >    a non-capturing bracket. Don't worry about setting the flag for the error
640 >    case here; that is handled in the code for KET. */
641 >
642 >    case OP_CBRA:
643 >    case OP_SCBRA:
644 >    number = GET2(ecode, 1+LINK_SIZE);
645      offset = number << 1;
646  
529 #ifdef DEBUG
530    printf("start bracket %d subject=", number);
531    pchars(eptr, 16, TRUE, md);
532    printf("\n");
533 #endif
534
647      if (offset < md->offset_max)
648        {
649        save_offset1 = md->offset_vector[offset];
# Line 542 | Line 654 | for (;;)
654        DPRINTF(("saving %d %d %d\n", save_offset1, save_offset2, save_offset3));
655        md->offset_vector[md->offset_end - number] = eptr - md->start_subject;
656  
657 +      flags = (op == OP_SCBRA)? match_cbegroup : 0;
658        do
659          {
660 <        RMATCH(rrc, eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, eptrb,
661 <          match_isgroup);
662 <        if (rrc != MATCH_NOMATCH) RRETURN(rrc);
660 >        RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,
661 >          ims, eptrb, flags, RM1);
662 >        if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);
663          md->capture_last = save_capture_last;
664          ecode += GET(ecode, 1);
665          }
# Line 561 | Line 674 | for (;;)
674        RRETURN(MATCH_NOMATCH);
675        }
676  
677 <    /* Insufficient room for saving captured contents */
677 >    /* FALL THROUGH ... Insufficient room for saving captured contents. Treat
678 >    as a non-capturing bracket. */
679  
680 <    else op = OP_BRA;
681 <    }
680 >    /* VVVVVVVVVVVVVVVVVVVVVVVVV */
681 >    /* VVVVVVVVVVVVVVVVVVVVVVVVV */
682  
683 <  /* Other types of node can be handled by a switch */
683 >    DPRINTF(("insufficient capture room: treat as non-capturing\n"));
684  
685 <  switch(op)
686 <    {
687 <    case OP_BRA:     /* Non-capturing bracket: optimized */
688 <    DPRINTF(("start bracket 0\n"));
689 <    do
685 >    /* VVVVVVVVVVVVVVVVVVVVVVVVV */
686 >    /* VVVVVVVVVVVVVVVVVVVVVVVVV */
687 >
688 >    /* Non-capturing bracket. Loop for all the alternatives. When we get to the
689 >    final alternative within the brackets, we would return the result of a
690 >    recursive call to match() whatever happened. We can reduce stack usage by
691 >    turning this into a tail recursion, except in the case when match_cbegroup
692 >    is set.*/
693 >
694 >    case OP_BRA:
695 >    case OP_SBRA:
696 >    DPRINTF(("start non-capturing bracket\n"));
697 >    flags = (op >= OP_SBRA)? match_cbegroup : 0;
698 >    for (;;)
699        {
700 <      RMATCH(rrc, eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, eptrb,
701 <        match_isgroup);
702 <      if (rrc != MATCH_NOMATCH) RRETURN(rrc);
700 >      if (ecode[GET(ecode, 1)] != OP_ALT)   /* Final alternative */
701 >        {
702 >        if (flags == 0)    /* Not a possibly empty group */
703 >          {
704 >          ecode += _pcre_OP_lengths[*ecode];
705 >          DPRINTF(("bracket 0 tail recursion\n"));
706 >          goto TAIL_RECURSE;
707 >          }
708 >
709 >        /* Possibly empty group; can't use tail recursion. */
710 >
711 >        RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md, ims,
712 >          eptrb, flags, RM48);
713 >        RRETURN(rrc);
714 >        }
715 >
716 >      /* For non-final alternatives, continue the loop for a NOMATCH result;
717 >      otherwise return. */
718 >
719 >      RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md, ims,
720 >        eptrb, flags, RM2);
721 >      if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);
722        ecode += GET(ecode, 1);
723        }
724 <    while (*ecode == OP_ALT);
583 <    DPRINTF(("bracket 0 failed\n"));
584 <    RRETURN(MATCH_NOMATCH);
724 >    /* Control never reaches here. */
725  
726      /* Conditional group: compilation checked that there are no more than
727      two branches. If the condition is false, skipping the first branch takes us
728      past the end if there is only one branch, but that's OK because that is
729 <    exactly what going to the ket would do. */
729 >    exactly what going to the ket would do. As there is only one branch to be
730 >    obeyed, we can use tail recursion to avoid using another stack frame. */
731  
732      case OP_COND:
733 <    if (ecode[LINK_SIZE+1] == OP_CREF) /* Condition extract or recurse test */
733 >    case OP_SCOND:
734 >    codelink= GET(ecode, 1);
735 >
736 >    /* Because of the way auto-callout works during compile, a callout item is
737 >    inserted between OP_COND and an assertion condition. */
738 >
739 >    if (ecode[LINK_SIZE+1] == OP_CALLOUT)
740 >      {
741 >      if (pcre_callout != NULL)
742 >        {
743 >        pcre_callout_block cb;
744 >        cb.version          = 1;   /* Version 1 of the callout block */
745 >        cb.callout_number   = ecode[LINK_SIZE+2];
746 >        cb.offset_vector    = md->offset_vector;
747 >        cb.subject          = (PCRE_SPTR)md->start_subject;
748 >        cb.subject_length   = md->end_subject - md->start_subject;
749 >        cb.start_match      = mstart - md->start_subject;
750 >        cb.current_position = eptr - md->start_subject;
751 >        cb.pattern_position = GET(ecode, LINK_SIZE + 3);
752 >        cb.next_item_length = GET(ecode, 3 + 2*LINK_SIZE);
753 >        cb.capture_top      = offset_top/2;
754 >        cb.capture_last     = md->capture_last;
755 >        cb.callout_data     = md->callout_data;
756 >        if ((rrc = (*pcre_callout)(&cb)) > 0) RRETURN(MATCH_NOMATCH);
757 >        if (rrc < 0) RRETURN(rrc);
758 >        }
759 >      ecode += _pcre_OP_lengths[OP_CALLOUT];
760 >      }
761 >
762 >    condcode = ecode[LINK_SIZE+1];
763 >
764 >    /* Now see what the actual condition is */
765 >
766 >    if (condcode == OP_RREF)         /* Recursion test */
767 >      {
768 >      offset = GET2(ecode, LINK_SIZE + 2);     /* Recursion group number*/
769 >      condition = md->recursive != NULL &&
770 >        (offset == RREF_ANY || offset == md->recursive->group_num);
771 >      ecode += condition? 3 : GET(ecode, 1);
772 >      }
773 >
774 >    else if (condcode == OP_CREF)    /* Group used test */
775        {
776        offset = GET2(ecode, LINK_SIZE+2) << 1;  /* Doubled ref number */
777 <      condition = (offset == CREF_RECURSE * 2)?
778 <        (md->recursive != NULL) :
779 <        (offset < offset_top && md->offset_vector[offset] >= 0);
780 <      RMATCH(rrc, eptr, ecode + (condition?
781 <        (LINK_SIZE + 4) : (LINK_SIZE + 1 + GET(ecode, 1))),
782 <        offset_top, md, ims, eptrb, match_isgroup);
783 <      RRETURN(rrc);
777 >      condition = offset < offset_top && md->offset_vector[offset] >= 0;
778 >      ecode += condition? 3 : GET(ecode, 1);
779 >      }
780 >
781 >    else if (condcode == OP_DEF)     /* DEFINE - always false */
782 >      {
783 >      condition = FALSE;
784 >      ecode += GET(ecode, 1);
785        }
786  
787      /* The condition is an assertion. Call match() to evaluate it - setting
788 <    the final argument TRUE causes it to stop at the end of an assertion. */
788 >    the final argument match_condassert causes it to stop at the end of an
789 >    assertion. */
790  
791      else
792        {
793 <      RMATCH(rrc, eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, NULL,
794 <          match_condassert | match_isgroup);
793 >      RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, NULL,
794 >          match_condassert, RM3);
795        if (rrc == MATCH_MATCH)
796          {
797 <        ecode += 1 + LINK_SIZE + GET(ecode, LINK_SIZE+2);
797 >        condition = TRUE;
798 >        ecode += 1 + LINK_SIZE + GET(ecode, LINK_SIZE + 2);
799          while (*ecode == OP_ALT) ecode += GET(ecode, 1);
800          }
801 <      else if (rrc != MATCH_NOMATCH)
801 >      else if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN)
802          {
803          RRETURN(rrc);         /* Need braces because of following else */
804          }
805 <      else ecode += GET(ecode, 1);
806 <      RMATCH(rrc, eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, eptrb,
807 <        match_isgroup);
808 <      RRETURN(rrc);
805 >      else
806 >        {
807 >        condition = FALSE;
808 >        ecode += codelink;
809 >        }
810        }
625    /* Control never reaches here */
811  
812 <    /* Skip over conditional reference or large extraction number data if
813 <    encountered. */
812 >    /* We are now at the branch that is to be obeyed. As there is only one,
813 >    we can use tail recursion to avoid using another stack frame, except when
814 >    match_cbegroup is required for an unlimited repeat of a possibly empty
815 >    group. If the second alternative doesn't exist, we can just plough on. */
816  
817 <    case OP_CREF:
818 <    case OP_BRANUMBER:
819 <    ecode += 3;
817 >    if (condition || *ecode == OP_ALT)
818 >      {
819 >      ecode += 1 + LINK_SIZE;
820 >      if (op == OP_SCOND)        /* Possibly empty group */
821 >        {
822 >        RMATCH(eptr, ecode, offset_top, md, ims, eptrb, match_cbegroup, RM49);
823 >        RRETURN(rrc);
824 >        }
825 >      else                       /* Group must match something */
826 >        {
827 >        flags = 0;
828 >        goto TAIL_RECURSE;
829 >        }
830 >      }
831 >    else                         /* Condition false & no alternative */
832 >      {
833 >      ecode += 1 + LINK_SIZE;
834 >      }
835      break;
836  
635    /* End of the pattern. If we are in a recursion, we should restore the
636    offsets appropriately and continue from after the call. */
837  
838 +    /* End of the pattern, either real or forced. If we are in a top-level
839 +    recursion, we should restore the offsets appropriately and continue from
840 +    after the call. */
841 +
842 +    case OP_ACCEPT:
843      case OP_END:
844      if (md->recursive != NULL && md->recursive->group_num == 0)
845        {
846        recursion_info *rec = md->recursive;
847 <      DPRINTF(("Hit the end in a (?0) recursion\n"));
847 >      DPRINTF(("End of pattern in a (?0) recursion\n"));
848        md->recursive = rec->prevrec;
849        memmove(md->offset_vector, rec->offset_save,
850          rec->saved_max * sizeof(int));
851 <      md->start_match = rec->save_start;
851 >      mstart = rec->save_start;
852        ims = original_ims;
853        ecode = rec->after_call;
854        break;
# Line 652 | Line 857 | for (;;)
857      /* Otherwise, if PCRE_NOTEMPTY is set, fail if we have matched an empty
858      string - backtracking will then try other alternatives, if any. */
859  
860 <    if (md->notempty && eptr == md->start_match) RRETURN(MATCH_NOMATCH);
861 <    md->end_match_ptr = eptr;          /* Record where we ended */
862 <    md->end_offset_top = offset_top;   /* and how many extracts were taken */
860 >    if (md->notempty && eptr == mstart) RRETURN(MATCH_NOMATCH);
861 >    md->end_match_ptr = eptr;           /* Record where we ended */
862 >    md->end_offset_top = offset_top;    /* and how many extracts were taken */
863 >    md->start_match_ptr = mstart;       /* and the start (\K can modify) */
864      RRETURN(MATCH_MATCH);
865  
866      /* Change option settings */
# Line 675 | Line 881 | for (;;)
881      case OP_ASSERTBACK:
882      do
883        {
884 <      RMATCH(rrc, eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, NULL,
885 <        match_isgroup);
884 >      RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, NULL, 0,
885 >        RM4);
886        if (rrc == MATCH_MATCH) break;
887 <      if (rrc != MATCH_NOMATCH) RRETURN(rrc);
887 >      if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);
888        ecode += GET(ecode, 1);
889        }
890      while (*ecode == OP_ALT);
# Line 702 | Line 908 | for (;;)
908      case OP_ASSERTBACK_NOT:
909      do
910        {
911 <      RMATCH(rrc, eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, NULL,
912 <        match_isgroup);
911 >      RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, NULL, 0,
912 >        RM5);
913        if (rrc == MATCH_MATCH) RRETURN(MATCH_NOMATCH);
914 <      if (rrc != MATCH_NOMATCH) RRETURN(rrc);
914 >      if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);
915        ecode += GET(ecode,1);
916        }
917      while (*ecode == OP_ALT);
# Line 721 | Line 927 | for (;;)
927      back a number of characters, not bytes. */
928  
929      case OP_REVERSE:
930 + #ifdef SUPPORT_UTF8
931 +    if (utf8)
932 +      {
933 +      i = GET(ecode, 1);
934 +      while (i-- > 0)
935 +        {
936 +        eptr--;
937 +        if (eptr < md->start_subject) RRETURN(MATCH_NOMATCH);
938 +        BACKCHAR(eptr);
939 +        }
940 +      }
941 +    else
942 + #endif
943 +
944      /* No UTF-8 support, or not in UTF-8 mode: count is byte count */
945  
946        {
947 <      eptr -= GET(ecode,1);
947 >      eptr -= GET(ecode, 1);
948        if (eptr < md->start_subject) RRETURN(MATCH_NOMATCH);
949        }
950  
# Line 744 | Line 964 | for (;;)
964        cb.version          = 1;   /* Version 1 of the callout block */
965        cb.callout_number   = ecode[1];
966        cb.offset_vector    = md->offset_vector;
967 <      cb.subject          = (const char *)md->start_subject;
967 >      cb.subject          = (PCRE_SPTR)md->start_subject;
968        cb.subject_length   = md->end_subject - md->start_subject;
969 <      cb.start_match      = md->start_match - md->start_subject;
969 >      cb.start_match      = mstart - md->start_subject;
970        cb.current_position = eptr - md->start_subject;
971        cb.pattern_position = GET(ecode, 2);
972        cb.next_item_length = GET(ecode, 2 + LINK_SIZE);
# Line 781 | Line 1001 | for (;;)
1001      case OP_RECURSE:
1002        {
1003        callpat = md->start_code + GET(ecode, 1);
1004 <      new_recursive.group_num = *callpat - OP_BRA;
1005 <
786 <      /* For extended extraction brackets (large number), we have to fish out
787 <      the number from a dummy opcode at the start. */
788 <
789 <      if (new_recursive.group_num > EXTRACT_BASIC_MAX)
790 <        new_recursive.group_num = GET2(callpat, 2+LINK_SIZE);
1004 >      new_recursive.group_num = (callpat == md->start_code)? 0 :
1005 >        GET2(callpat, 1 + LINK_SIZE);
1006  
1007        /* Add to "recursing stack" */
1008  
# Line 813 | Line 1028 | for (;;)
1028  
1029        memcpy(new_recursive.offset_save, md->offset_vector,
1030              new_recursive.saved_max * sizeof(int));
1031 <      new_recursive.save_start = md->start_match;
1032 <      md->start_match = eptr;
1031 >      new_recursive.save_start = mstart;
1032 >      mstart = eptr;
1033  
1034        /* OK, now we can do the recursion. For each top-level alternative we
1035        restore the offset and recursion data. */
1036  
1037        DPRINTF(("Recursing into group %d\n", new_recursive.group_num));
1038 +      flags = (*callpat >= OP_SBRA)? match_cbegroup : 0;
1039        do
1040          {
1041 <        RMATCH(rrc, eptr, callpat + 1 + LINK_SIZE, offset_top, md, ims,
1042 <            eptrb, match_isgroup);
1041 >        RMATCH(eptr, callpat + _pcre_OP_lengths[*callpat], offset_top,
1042 >          md, ims, eptrb, flags, RM6);
1043          if (rrc == MATCH_MATCH)
1044            {
1045 +          DPRINTF(("Recursion matched\n"));
1046            md->recursive = new_recursive.prevrec;
1047            if (new_recursive.offset_save != stacksave)
1048              (pcre_free)(new_recursive.offset_save);
1049            RRETURN(MATCH_MATCH);
1050            }
1051 <        else if (rrc != MATCH_NOMATCH) RRETURN(rrc);
1051 >        else if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN)
1052 >          {
1053 >          DPRINTF(("Recursion gave error %d\n", rrc));
1054 >          if (new_recursive.offset_save != stacksave)
1055 >            (pcre_free)(new_recursive.offset_save);
1056 >          RRETURN(rrc);
1057 >          }
1058  
1059          md->recursive = &new_recursive;
1060          memcpy(md->offset_vector, new_recursive.offset_save,
# Line 856 | Line 1079 | for (;;)
1079      the end of a normal bracket, leaving the subject pointer. */
1080  
1081      case OP_ONCE:
1082 <      {
1083 <      prev = ecode;
861 <      saved_eptr = eptr;
1082 >    prev = ecode;
1083 >    saved_eptr = eptr;
1084  
1085 <      do
1086 <        {
1087 <        RMATCH(rrc, eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims,
1088 <          eptrb, match_isgroup);
1089 <        if (rrc == MATCH_MATCH) break;
1090 <        if (rrc != MATCH_NOMATCH) RRETURN(rrc);
1091 <        ecode += GET(ecode,1);
1092 <        }
871 <      while (*ecode == OP_ALT);
1085 >    do
1086 >      {
1087 >      RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, eptrb, 0, RM7);
1088 >      if (rrc == MATCH_MATCH) break;
1089 >      if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);
1090 >      ecode += GET(ecode,1);
1091 >      }
1092 >    while (*ecode == OP_ALT);
1093  
1094 <      /* If hit the end of the group (which could be repeated), fail */
1094 >    /* If hit the end of the group (which could be repeated), fail */
1095  
1096 <      if (*ecode != OP_ONCE && *ecode != OP_ALT) RRETURN(MATCH_NOMATCH);
1096 >    if (*ecode != OP_ONCE && *ecode != OP_ALT) RRETURN(MATCH_NOMATCH);
1097  
1098 <      /* Continue as from after the assertion, updating the offsets high water
1099 <      mark, since extracts may have been taken. */
1098 >    /* Continue as from after the assertion, updating the offsets high water
1099 >    mark, since extracts may have been taken. */
1100  
1101 <      do ecode += GET(ecode,1); while (*ecode == OP_ALT);
1101 >    do ecode += GET(ecode, 1); while (*ecode == OP_ALT);
1102  
1103 <      offset_top = md->end_offset_top;
1104 <      eptr = md->end_match_ptr;
1103 >    offset_top = md->end_offset_top;
1104 >    eptr = md->end_match_ptr;
1105  
1106 <      /* For a non-repeating ket, just continue at this level. This also
1107 <      happens for a repeating ket if no characters were matched in the group.
1108 <      This is the forcible breaking of infinite loops as implemented in Perl
1109 <      5.005. If there is an options reset, it will get obeyed in the normal
1110 <      course of events. */
1106 >    /* For a non-repeating ket, just continue at this level. This also
1107 >    happens for a repeating ket if no characters were matched in the group.
1108 >    This is the forcible breaking of infinite loops as implemented in Perl
1109 >    5.005. If there is an options reset, it will get obeyed in the normal
1110 >    course of events. */
1111  
1112 <      if (*ecode == OP_KET || eptr == saved_eptr)
1113 <        {
1114 <        ecode += 1+LINK_SIZE;
1115 <        break;
1116 <        }
1112 >    if (*ecode == OP_KET || eptr == saved_eptr)
1113 >      {
1114 >      ecode += 1+LINK_SIZE;
1115 >      break;
1116 >      }
1117  
1118 <      /* The repeating kets try the rest of the pattern or restart from the
1119 <      preceding bracket, in the appropriate order. We need to reset any options
1120 <      that changed within the bracket before re-running it, so check the next
1121 <      opcode. */
1118 >    /* The repeating kets try the rest of the pattern or restart from the
1119 >    preceding bracket, in the appropriate order. The second "call" of match()
1120 >    uses tail recursion, to avoid using another stack frame. We need to reset
1121 >    any options that changed within the bracket before re-running it, so
1122 >    check the next opcode. */
1123  
1124 <      if (ecode[1+LINK_SIZE] == OP_OPT)
1125 <        {
1126 <        ims = (ims & ~PCRE_IMS) | ecode[4];
1127 <        DPRINTF(("ims set to %02lx at group repeat\n", ims));
1128 <        }
1124 >    if (ecode[1+LINK_SIZE] == OP_OPT)
1125 >      {
1126 >      ims = (ims & ~PCRE_IMS) | ecode[4];
1127 >      DPRINTF(("ims set to %02lx at group repeat\n", ims));
1128 >      }
1129  
1130 <      if (*ecode == OP_KETRMIN)
1131 <        {
1132 <        RMATCH(rrc, eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, eptrb, 0);
1133 <        if (rrc != MATCH_NOMATCH) RRETURN(rrc);
1134 <        RMATCH(rrc, eptr, prev, offset_top, md, ims, eptrb, match_isgroup);
1135 <        if (rrc != MATCH_NOMATCH) RRETURN(rrc);
1136 <        }
915 <      else  /* OP_KETRMAX */
916 <        {
917 <        RMATCH(rrc, eptr, prev, offset_top, md, ims, eptrb, match_isgroup);
918 <        if (rrc != MATCH_NOMATCH) RRETURN(rrc);
919 <        RMATCH(rrc, eptr, ecode + 1+LINK_SIZE, offset_top, md, ims, eptrb, 0);
920 <        if (rrc != MATCH_NOMATCH) RRETURN(rrc);
921 <        }
1130 >    if (*ecode == OP_KETRMIN)
1131 >      {
1132 >      RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, eptrb, 0, RM8);
1133 >      if (rrc != MATCH_NOMATCH) RRETURN(rrc);
1134 >      ecode = prev;
1135 >      flags = 0;
1136 >      goto TAIL_RECURSE;
1137        }
1138 <    RRETURN(MATCH_NOMATCH);
1138 >    else  /* OP_KETRMAX */
1139 >      {
1140 >      RMATCH(eptr, prev, offset_top, md, ims, eptrb, match_cbegroup, RM9);
1141 >      if (rrc != MATCH_NOMATCH) RRETURN(rrc);
1142 >      ecode += 1 + LINK_SIZE;
1143 >      flags = 0;
1144 >      goto TAIL_RECURSE;
1145 >      }
1146 >    /* Control never gets here */
1147  
1148      /* An alternation is the end of a branch; scan along to find the end of the
1149      bracketed group and go to there. */
# Line 929 | Line 1152 | for (;;)
1152      do ecode += GET(ecode,1); while (*ecode == OP_ALT);
1153      break;
1154  
1155 <    /* BRAZERO and BRAMINZERO occur just before a bracket group, indicating
1156 <    that it may occur zero times. It may repeat infinitely, or not at all -
1157 <    i.e. it could be ()* or ()? in the pattern. Brackets with fixed upper
1158 <    repeat limits are compiled as a number of copies, with the optional ones
1159 <    preceded by BRAZERO or BRAMINZERO. */
1155 >    /* BRAZERO, BRAMINZERO and SKIPZERO occur just before a bracket group,
1156 >    indicating that it may occur zero times. It may repeat infinitely, or not
1157 >    at all - i.e. it could be ()* or ()? or even (){0} in the pattern. Brackets
1158 >    with fixed upper repeat limits are compiled as a number of copies, with the
1159 >    optional ones preceded by BRAZERO or BRAMINZERO. */
1160  
1161      case OP_BRAZERO:
1162        {
1163        next = ecode+1;
1164 <      RMATCH(rrc, eptr, next, offset_top, md, ims, eptrb, match_isgroup);
1164 >      RMATCH(eptr, next, offset_top, md, ims, eptrb, 0, RM10);
1165        if (rrc != MATCH_NOMATCH) RRETURN(rrc);
1166        do next += GET(next,1); while (*next == OP_ALT);
1167 <      ecode = next + 1+LINK_SIZE;
1167 >      ecode = next + 1 + LINK_SIZE;
1168        }
1169      break;
1170  
1171      case OP_BRAMINZERO:
1172        {
1173        next = ecode+1;
1174 <      do next += GET(next,1); while (*next == OP_ALT);
1175 <      RMATCH(rrc, eptr, next + 1+LINK_SIZE, offset_top, md, ims, eptrb,
953 <        match_isgroup);
1174 >      do next += GET(next, 1); while (*next == OP_ALT);
1175 >      RMATCH(eptr, next + 1+LINK_SIZE, offset_top, md, ims, eptrb, 0, RM11);
1176        if (rrc != MATCH_NOMATCH) RRETURN(rrc);
1177        ecode++;
1178        }
1179      break;
1180  
1181 <    /* End of a group, repeated or non-repeating. If we are at the end of
1182 <    an assertion "group", stop matching and return MATCH_MATCH, but record the
1183 <    current high water mark for use by positive assertions. Do this also
1184 <    for the "once" (not-backup up) groups. */
1181 >    case OP_SKIPZERO:
1182 >      {
1183 >      next = ecode+1;
1184 >      do next += GET(next,1); while (*next == OP_ALT);
1185 >      ecode = next + 1 + LINK_SIZE;
1186 >      }
1187 >    break;
1188 >
1189 >    /* End of a group, repeated or non-repeating. */
1190  
1191      case OP_KET:
1192      case OP_KETRMIN:
1193      case OP_KETRMAX:
1194 +    prev = ecode - GET(ecode, 1);
1195 +
1196 +    /* If this was a group that remembered the subject start, in order to break
1197 +    infinite repeats of empty string matches, retrieve the subject start from
1198 +    the chain. Otherwise, set it NULL. */
1199 +
1200 +    if (*prev >= OP_SBRA)
1201        {
1202 <      prev = ecode - GET(ecode, 1);
1203 <      saved_eptr = eptrb->epb_saved_eptr;
1202 >      saved_eptr = eptrb->epb_saved_eptr;   /* Value at start of group */
1203 >      eptrb = eptrb->epb_prev;              /* Backup to previous group */
1204 >      }
1205 >    else saved_eptr = NULL;
1206  
1207 <      /* Back up the stack of bracket start pointers. */
1207 >    /* If we are at the end of an assertion group, stop matching and return
1208 >    MATCH_MATCH, but record the current high water mark for use by positive
1209 >    assertions. Do this also for the "once" (atomic) groups. */
1210 >
1211 >    if (*prev == OP_ASSERT || *prev == OP_ASSERT_NOT ||
1212 >        *prev == OP_ASSERTBACK || *prev == OP_ASSERTBACK_NOT ||
1213 >        *prev == OP_ONCE)
1214 >      {
1215 >      md->end_match_ptr = eptr;      /* For ONCE */
1216 >      md->end_offset_top = offset_top;
1217 >      RRETURN(MATCH_MATCH);
1218 >      }
1219  
1220 <      eptrb = eptrb->epb_prev;
1220 >    /* For capturing groups we have to check the group number back at the start
1221 >    and if necessary complete handling an extraction by setting the offsets and
1222 >    bumping the high water mark. Note that whole-pattern recursion is coded as
1223 >    a recurse into group 0, so it won't be picked up here. Instead, we catch it
1224 >    when the OP_END is reached. Other recursion is handled here. */
1225  
1226 <      if (*prev == OP_ASSERT || *prev == OP_ASSERT_NOT ||
1227 <          *prev == OP_ASSERTBACK || *prev == OP_ASSERTBACK_NOT ||
1228 <          *prev == OP_ONCE)
1226 >    if (*prev == OP_CBRA || *prev == OP_SCBRA)
1227 >      {
1228 >      number = GET2(prev, 1+LINK_SIZE);
1229 >      offset = number << 1;
1230 >
1231 >      md->capture_last = number;
1232 >      if (offset >= md->offset_max) md->offset_overflow = TRUE; else
1233          {
1234 <        md->end_match_ptr = eptr;      /* For ONCE */
1235 <        md->end_offset_top = offset_top;
1236 <        RRETURN(MATCH_MATCH);
1234 >        md->offset_vector[offset] =
1235 >          md->offset_vector[md->offset_end - number];
1236 >        md->offset_vector[offset+1] = eptr - md->start_subject;
1237 >        if (offset_top <= offset) offset_top = offset + 2;
1238          }
1239  
1240 <      /* In all other cases except a conditional group we have to check the
1241 <      group number back at the start and if necessary complete handling an
986 <      extraction by setting the offsets and bumping the high water mark. */
1240 >      /* Handle a recursively called group. Restore the offsets
1241 >      appropriately and continue from after the call. */
1242  
1243 <      if (*prev != OP_COND)
1243 >      if (md->recursive != NULL && md->recursive->group_num == number)
1244          {
1245 <        number = *prev - OP_BRA;
1246 <
1247 <        /* For extended extraction brackets (large number), we have to fish out
1248 <        the number from a dummy opcode at the start. */
1249 <
1250 <        if (number > EXTRACT_BASIC_MAX) number = GET2(prev, 2+LINK_SIZE);
1251 <        offset = number << 1;
1252 <
1253 < #ifdef DEBUG
999 <        printf("end bracket %d", number);
1000 <        printf("\n");
1001 < #endif
1002 <
1003 <        /* Test for a numbered group. This includes groups called as a result
1004 <        of recursion. Note that whole-pattern recursion is coded as a recurse
1005 <        into group 0, so it won't be picked up here. Instead, we catch it when
1006 <        the OP_END is reached. */
1007 <
1008 <        if (number > 0)
1009 <          {
1010 <          md->capture_last = number;
1011 <          if (offset >= md->offset_max) md->offset_overflow = TRUE; else
1012 <            {
1013 <            md->offset_vector[offset] =
1014 <              md->offset_vector[md->offset_end - number];
1015 <            md->offset_vector[offset+1] = eptr - md->start_subject;
1016 <            if (offset_top <= offset) offset_top = offset + 2;
1017 <            }
1018 <
1019 <          /* Handle a recursively called group. Restore the offsets
1020 <          appropriately and continue from after the call. */
1021 <
1022 <          if (md->recursive != NULL && md->recursive->group_num == number)
1023 <            {
1024 <            recursion_info *rec = md->recursive;
1025 <            DPRINTF(("Recursion (%d) succeeded - continuing\n", number));
1026 <            md->recursive = rec->prevrec;
1027 <            md->start_match = rec->save_start;
1028 <            memcpy(md->offset_vector, rec->offset_save,
1029 <              rec->saved_max * sizeof(int));
1030 <            ecode = rec->after_call;
1031 <            ims = original_ims;
1032 <            break;
1033 <            }
1034 <          }
1245 >        recursion_info *rec = md->recursive;
1246 >        DPRINTF(("Recursion (%d) succeeded - continuing\n", number));
1247 >        md->recursive = rec->prevrec;
1248 >        mstart = rec->save_start;
1249 >        memcpy(md->offset_vector, rec->offset_save,
1250 >          rec->saved_max * sizeof(int));
1251 >        ecode = rec->after_call;
1252 >        ims = original_ims;
1253 >        break;
1254          }
1255 +      }
1256  
1257 <      /* Reset the value of the ims flags, in case they got changed during
1258 <      the group. */
1257 >    /* For both capturing and non-capturing groups, reset the value of the ims
1258 >    flags, in case they got changed during the group. */
1259  
1260 <      ims = original_ims;
1261 <      DPRINTF(("ims reset to %02lx\n", ims));
1260 >    ims = original_ims;
1261 >    DPRINTF(("ims reset to %02lx\n", ims));
1262  
1263 <      /* For a non-repeating ket, just continue at this level. This also
1264 <      happens for a repeating ket if no characters were matched in the group.
1265 <      This is the forcible breaking of infinite loops as implemented in Perl
1266 <      5.005. If there is an options reset, it will get obeyed in the normal
1267 <      course of events. */
1263 >    /* For a non-repeating ket, just continue at this level. This also
1264 >    happens for a repeating ket if no characters were matched in the group.
1265 >    This is the forcible breaking of infinite loops as implemented in Perl
1266 >    5.005. If there is an options reset, it will get obeyed in the normal
1267 >    course of events. */
1268  
1269 <      if (*ecode == OP_KET || eptr == saved_eptr)
1270 <        {
1271 <        ecode += 1 + LINK_SIZE;
1272 <        break;
1273 <        }
1269 >    if (*ecode == OP_KET || eptr == saved_eptr)
1270 >      {
1271 >      ecode += 1 + LINK_SIZE;
1272 >      break;
1273 >      }
1274  
1275 <      /* The repeating kets try the rest of the pattern or restart from the
1276 <      preceding bracket, in the appropriate order. */
1275 >    /* The repeating kets try the rest of the pattern or restart from the
1276 >    preceding bracket, in the appropriate order. In the second case, we can use
1277 >    tail recursion to avoid using another stack frame, unless we have an
1278 >    unlimited repeat of a group that can match an empty string. */
1279  
1280 <      if (*ecode == OP_KETRMIN)
1281 <        {
1282 <        RMATCH(rrc, eptr, ecode + 1+LINK_SIZE, offset_top, md, ims, eptrb, 0);
1283 <        if (rrc != MATCH_NOMATCH) RRETURN(rrc);
1284 <        RMATCH(rrc, eptr, prev, offset_top, md, ims, eptrb, match_isgroup);
1285 <        if (rrc != MATCH_NOMATCH) RRETURN(rrc);
1286 <        }
1065 <      else  /* OP_KETRMAX */
1280 >    flags = (*prev >= OP_SBRA)? match_cbegroup : 0;
1281 >
1282 >    if (*ecode == OP_KETRMIN)
1283 >      {
1284 >      RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, eptrb, 0, RM12);
1285 >      if (rrc != MATCH_NOMATCH) RRETURN(rrc);
1286 >      if (flags != 0)    /* Could match an empty string */
1287          {
1288 <        RMATCH(rrc, eptr, prev, offset_top, md, ims, eptrb, match_isgroup);
1289 <        if (rrc != MATCH_NOMATCH) RRETURN(rrc);
1069 <        RMATCH(rrc, eptr, ecode + 1+LINK_SIZE, offset_top, md, ims, eptrb, 0);
1070 <        if (rrc != MATCH_NOMATCH) RRETURN(rrc);
1288 >        RMATCH(eptr, prev, offset_top, md, ims, eptrb, flags, RM50);
1289 >        RRETURN(rrc);
1290          }
1291 +      ecode = prev;
1292 +      goto TAIL_RECURSE;
1293        }
1294 <
1295 <    RRETURN(MATCH_NOMATCH);
1294 >    else  /* OP_KETRMAX */
1295 >      {
1296 >      RMATCH(eptr, prev, offset_top, md, ims, eptrb, flags, RM13);
1297 >      if (rrc != MATCH_NOMATCH) RRETURN(rrc);
1298 >      ecode += 1 + LINK_SIZE;
1299 >      flags = 0;
1300 >      goto TAIL_RECURSE;
1301 >      }
1302 >    /* Control never gets here */
1303  
1304      /* Start of subject unless notbol, or after internal newline if multiline */
1305  
# Line 1079 | Line 1307 | for (;;)
1307      if (md->notbol && eptr == md->start_subject) RRETURN(MATCH_NOMATCH);
1308      if ((ims & PCRE_MULTILINE) != 0)
1309        {
1310 <      if (eptr != md->start_subject && eptr[-1] != NEWLINE)
1310 >      if (eptr != md->start_subject &&
1311 >          (eptr == md->end_subject || !WAS_NEWLINE(eptr)))
1312          RRETURN(MATCH_NOMATCH);
1313        ecode++;
1314        break;
# Line 1100 | Line 1329 | for (;;)
1329      ecode++;
1330      break;
1331  
1332 +    /* Reset the start of match point */
1333 +
1334 +    case OP_SET_SOM:
1335 +    mstart = eptr;
1336 +    ecode++;
1337 +    break;
1338 +
1339      /* Assert before internal newline if multiline, or before a terminating
1340      newline unless endonly is set, else end of subject unless noteol is set. */
1341  
# Line 1107 | Line 1343 | for (;;)
1343      if ((ims & PCRE_MULTILINE) != 0)
1344        {
1345        if (eptr < md->end_subject)
1346 <        { if (*eptr != NEWLINE) RRETURN(MATCH_NOMATCH); }
1346 >        { if (!IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH); }
1347        else
1348          { if (md->noteol) RRETURN(MATCH_NOMATCH); }
1349        ecode++;
# Line 1118 | Line 1354 | for (;;)
1354        if (md->noteol) RRETURN(MATCH_NOMATCH);
1355        if (!md->endonly)
1356          {
1357 <        if (eptr < md->end_subject - 1 ||
1358 <           (eptr == md->end_subject - 1 && *eptr != NEWLINE))
1357 >        if (eptr != md->end_subject &&
1358 >            (!IS_NEWLINE(eptr) || eptr != md->end_subject - md->nllen))
1359            RRETURN(MATCH_NOMATCH);
1360          ecode++;
1361          break;
1362          }
1363        }
1364 <    /* ... else fall through */
1364 >    /* ... else fall through for endonly */
1365  
1366      /* End of subject assertion (\z) */
1367  
# Line 1137 | Line 1373 | for (;;)
1373      /* End of subject or ending \n assertion (\Z) */
1374  
1375      case OP_EODN:
1376 <    if (eptr < md->end_subject - 1 ||
1377 <       (eptr == md->end_subject - 1 && *eptr != NEWLINE)) RRETURN(MATCH_NOMATCH);
1376 >    if (eptr != md->end_subject &&
1377 >        (!IS_NEWLINE(eptr) || eptr != md->end_subject - md->nllen))
1378 >      RRETURN(MATCH_NOMATCH);
1379      ecode++;
1380      break;
1381  
# Line 1148 | Line 1385 | for (;;)
1385      case OP_WORD_BOUNDARY:
1386        {
1387  
1388 +      /* Find out if the previous and current characters are "word" characters.
1389 +      It takes a bit more work in UTF-8 mode. Characters > 255 are assumed to
1390 +      be "non-word" characters. */
1391 +
1392 + #ifdef SUPPORT_UTF8
1393 +      if (utf8)
1394 +        {
1395 +        if (eptr == md->start_subject) prev_is_word = FALSE; else
1396 +          {
1397 +          USPTR lastptr = eptr - 1;
1398 +          while((*lastptr & 0xc0) == 0x80) lastptr--;
1399 +          GETCHAR(c, lastptr);
1400 +          prev_is_word = c < 256 && (md->ctypes[c] & ctype_word) != 0;
1401 +          }
1402 +        if (eptr >= md->end_subject) cur_is_word = FALSE; else
1403 +          {
1404 +          GETCHAR(c, eptr);
1405 +          cur_is_word = c < 256 && (md->ctypes[c] & ctype_word) != 0;
1406 +          }
1407 +        }
1408 +      else
1409 + #endif
1410 +
1411        /* More streamlined when not in UTF-8 mode */
1412  
1413          {
# Line 1168 | Line 1428 | for (;;)
1428      /* Match a single character type; inline for speed */
1429  
1430      case OP_ANY:
1431 <    if ((ims & PCRE_DOTALL) == 0 && eptr < md->end_subject && *eptr == NEWLINE)
1432 <      RRETURN(MATCH_NOMATCH);
1431 >    if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH);
1432 >    /* Fall through */
1433 >
1434 >    case OP_ALLANY:
1435      if (eptr++ >= md->end_subject) RRETURN(MATCH_NOMATCH);
1436 +    if (utf8) while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;
1437      ecode++;
1438      break;
1439  
# Line 1185 | Line 1448 | for (;;)
1448      case OP_NOT_DIGIT:
1449      if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
1450      GETCHARINCTEST(c, eptr);
1451 <    if ((md->ctypes[c] & ctype_digit) != 0)
1451 >    if (
1452 > #ifdef SUPPORT_UTF8
1453 >       c < 256 &&
1454 > #endif
1455 >       (md->ctypes[c] & ctype_digit) != 0
1456 >       )
1457        RRETURN(MATCH_NOMATCH);
1458      ecode++;
1459      break;
# Line 1193 | Line 1461 | for (;;)
1461      case OP_DIGIT:
1462      if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
1463      GETCHARINCTEST(c, eptr);
1464 <    if ((md->ctypes[c] & ctype_digit) == 0)
1464 >    if (
1465 > #ifdef SUPPORT_UTF8
1466 >       c >= 256 ||
1467 > #endif
1468 >       (md->ctypes[c] & ctype_digit) == 0
1469 >       )
1470        RRETURN(MATCH_NOMATCH);
1471      ecode++;
1472      break;
# Line 1201 | Line 1474 | for (;;)
1474      case OP_NOT_WHITESPACE:
1475      if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
1476      GETCHARINCTEST(c, eptr);
1477 <    if ((md->ctypes[c] & ctype_space) != 0)
1477 >    if (
1478 > #ifdef SUPPORT_UTF8
1479 >       c < 256 &&
1480 > #endif
1481 >       (md->ctypes[c] & ctype_space) != 0
1482 >       )
1483        RRETURN(MATCH_NOMATCH);
1484      ecode++;
1485      break;
# Line 1209 | Line 1487 | for (;;)
1487      case OP_WHITESPACE:
1488      if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
1489      GETCHARINCTEST(c, eptr);
1490 <    if ((md->ctypes[c] & ctype_space) == 0)
1490 >    if (
1491 > #ifdef SUPPORT_UTF8
1492 >       c >= 256 ||
1493 > #endif
1494 >       (md->ctypes[c] & ctype_space) == 0
1495 >       )
1496        RRETURN(MATCH_NOMATCH);
1497      ecode++;
1498      break;
# Line 1217 | Line 1500 | for (;;)
1500      case OP_NOT_WORDCHAR:
1501      if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
1502      GETCHARINCTEST(c, eptr);
1503 <    if ((md->ctypes[c] & ctype_word) != 0)
1503 >    if (
1504 > #ifdef SUPPORT_UTF8
1505 >       c < 256 &&
1506 > #endif
1507 >       (md->ctypes[c] & ctype_word) != 0
1508 >       )
1509        RRETURN(MATCH_NOMATCH);
1510      ecode++;
1511      break;
# Line 1225 | Line 1513 | for (;;)
1513      case OP_WORDCHAR:
1514      if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
1515      GETCHARINCTEST(c, eptr);
1516 <    if ((md->ctypes[c] & ctype_word) == 0)
1516 >    if (
1517 > #ifdef SUPPORT_UTF8
1518 >       c >= 256 ||
1519 > #endif
1520 >       (md->ctypes[c] & ctype_word) == 0
1521 >       )
1522        RRETURN(MATCH_NOMATCH);
1523      ecode++;
1524      break;
1525  
1526 +    case OP_ANYNL:
1527 +    if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
1528 +    GETCHARINCTEST(c, eptr);
1529 +    switch(c)
1530 +      {
1531 +      default: RRETURN(MATCH_NOMATCH);
1532 +      case 0x000d:
1533 +      if (eptr < md->end_subject && *eptr == 0x0a) eptr++;
1534 +      break;
1535 +
1536 +      case 0x000a:
1537 +      break;
1538 +
1539 +      case 0x000b:
1540 +      case 0x000c:
1541 +      case 0x0085:
1542 +      case 0x2028:
1543 +      case 0x2029:
1544 +      if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH);
1545 +      break;
1546 +      }
1547 +    ecode++;
1548 +    break;
1549 +
1550 +    case OP_NOT_HSPACE:
1551 +    if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
1552 +    GETCHARINCTEST(c, eptr);
1553 +    switch(c)
1554 +      {
1555 +      default: break;
1556 +      case 0x09:      /* HT */
1557 +      case 0x20:      /* SPACE */
1558 +      case 0xa0:      /* NBSP */
1559 +      case 0x1680:    /* OGHAM SPACE MARK */
1560 +      case 0x180e:    /* MONGOLIAN VOWEL SEPARATOR */
1561 +      case 0x2000:    /* EN QUAD */
1562 +      case 0x2001:    /* EM QUAD */
1563 +      case 0x2002:    /* EN SPACE */
1564 +      case 0x2003:    /* EM SPACE */
1565 +      case 0x2004:    /* THREE-PER-EM SPACE */
1566 +      case 0x2005:    /* FOUR-PER-EM SPACE */
1567 +      case 0x2006:    /* SIX-PER-EM SPACE */
1568 +      case 0x2007:    /* FIGURE SPACE */
1569 +      case 0x2008:    /* PUNCTUATION SPACE */
1570 +      case 0x2009:    /* THIN SPACE */
1571 +      case 0x200A:    /* HAIR SPACE */
1572 +      case 0x202f:    /* NARROW NO-BREAK SPACE */
1573 +      case 0x205f:    /* MEDIUM MATHEMATICAL SPACE */
1574 +      case 0x3000:    /* IDEOGRAPHIC SPACE */
1575 +      RRETURN(MATCH_NOMATCH);
1576 +      }
1577 +    ecode++;
1578 +    break;
1579 +
1580 +    case OP_HSPACE:
1581 +    if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
1582 +    GETCHARINCTEST(c, eptr);
1583 +    switch(c)
1584 +      {
1585 +      default: RRETURN(MATCH_NOMATCH);
1586 +      case 0x09:      /* HT */
1587 +      case 0x20:      /* SPACE */
1588 +      case 0xa0:      /* NBSP */
1589 +      case 0x1680:    /* OGHAM SPACE MARK */
1590 +      case 0x180e:    /* MONGOLIAN VOWEL SEPARATOR */
1591 +      case 0x2000:    /* EN QUAD */
1592 +      case 0x2001:    /* EM QUAD */
1593 +      case 0x2002:    /* EN SPACE */
1594 +      case 0x2003:    /* EM SPACE */
1595 +      case 0x2004:    /* THREE-PER-EM SPACE */
1596 +      case 0x2005:    /* FOUR-PER-EM SPACE */
1597 +      case 0x2006:    /* SIX-PER-EM SPACE */
1598 +      case 0x2007:    /* FIGURE SPACE */
1599 +      case 0x2008:    /* PUNCTUATION SPACE */
1600 +      case 0x2009:    /* THIN SPACE */
1601 +      case 0x200A:    /* HAIR SPACE */
1602 +      case 0x202f:    /* NARROW NO-BREAK SPACE */
1603 +      case 0x205f:    /* MEDIUM MATHEMATICAL SPACE */
1604 +      case 0x3000:    /* IDEOGRAPHIC SPACE */
1605 +      break;
1606 +      }
1607 +    ecode++;
1608 +    break;
1609 +
1610 +    case OP_NOT_VSPACE:
1611 +    if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
1612 +    GETCHARINCTEST(c, eptr);
1613 +    switch(c)
1614 +      {
1615 +      default: break;
1616 +      case 0x0a:      /* LF */
1617 +      case 0x0b:      /* VT */
1618 +      case 0x0c:      /* FF */
1619 +      case 0x0d:      /* CR */
1620 +      case 0x85:      /* NEL */
1621 +      case 0x2028:    /* LINE SEPARATOR */
1622 +      case 0x2029:    /* PARAGRAPH SEPARATOR */
1623 +      RRETURN(MATCH_NOMATCH);
1624 +      }
1625 +    ecode++;
1626 +    break;
1627 +
1628 +    case OP_VSPACE:
1629 +    if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
1630 +    GETCHARINCTEST(c, eptr);
1631 +    switch(c)
1632 +      {
1633 +      default: RRETURN(MATCH_NOMATCH);
1634 +      case 0x0a:      /* LF */
1635 +      case 0x0b:      /* VT */
1636 +      case 0x0c:      /* FF */
1637 +      case 0x0d:      /* CR */
1638 +      case 0x85:      /* NEL */
1639 +      case 0x2028:    /* LINE SEPARATOR */
1640 +      case 0x2029:    /* PARAGRAPH SEPARATOR */
1641 +      break;
1642 +      }
1643 +    ecode++;
1644 +    break;
1645 +
1646 + #ifdef SUPPORT_UCP
1647 +    /* Check the next character by Unicode property. We will get here only
1648 +    if the support is in the binary; otherwise a compile-time error occurs. */
1649 +
1650 +    case OP_PROP:
1651 +    case OP_NOTPROP:
1652 +    if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
1653 +    GETCHARINCTEST(c, eptr);
1654 +      {
1655 +      const ucd_record *prop = GET_UCD(c);
1656 +
1657 +      switch(ecode[1])
1658 +        {
1659 +        case PT_ANY:
1660 +        if (op == OP_NOTPROP) RRETURN(MATCH_NOMATCH);
1661 +        break;
1662 +
1663 +        case PT_LAMP:
1664 +        if ((prop->chartype == ucp_Lu ||
1665 +             prop->chartype == ucp_Ll ||
1666 +             prop->chartype == ucp_Lt) == (op == OP_NOTPROP))
1667 +          RRETURN(MATCH_NOMATCH);
1668 +         break;
1669 +
1670 +        case PT_GC:
1671 +        if ((ecode[2] != _pcre_ucp_gentype[prop->chartype]) == (op == OP_PROP))
1672 +          RRETURN(MATCH_NOMATCH);
1673 +        break;
1674 +
1675 +        case PT_PC:
1676 +        if ((ecode[2] != prop->chartype) == (op == OP_PROP))
1677 +          RRETURN(MATCH_NOMATCH);
1678 +        break;
1679 +
1680 +        case PT_SC:
1681 +        if ((ecode[2] != prop->script) == (op == OP_PROP))
1682 +          RRETURN(MATCH_NOMATCH);
1683 +        break;
1684 +
1685 +        default:
1686 +        RRETURN(PCRE_ERROR_INTERNAL);
1687 +        }
1688 +
1689 +      ecode += 3;
1690 +      }
1691 +    break;
1692 +
1693 +    /* Match an extended Unicode sequence. We will get here only if the support
1694 +    is in the binary; otherwise a compile-time error occurs. */
1695 +
1696 +    case OP_EXTUNI:
1697 +    if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
1698 +    GETCHARINCTEST(c, eptr);
1699 +      {
1700 +      int category = UCD_CATEGORY(c);
1701 +      if (category == ucp_M) RRETURN(MATCH_NOMATCH);
1702 +      while (eptr < md->end_subject)
1703 +        {
1704 +        int len = 1;
1705 +        if (!utf8) c = *eptr; else
1706 +          {
1707 +          GETCHARLEN(c, eptr, len);
1708 +          }
1709 +        category = UCD_CATEGORY(c);
1710 +        if (category != ucp_M) break;
1711 +        eptr += len;
1712 +        }
1713 +      }
1714 +    ecode++;
1715 +    break;
1716 + #endif
1717 +
1718  
1719      /* Match a back reference, possibly repeatedly. Look past the end of the
1720      item to see if there is repeat information following. The code is similar
# Line 1242 | Line 1727 | for (;;)
1727      case OP_REF:
1728        {
1729        offset = GET2(ecode, 1) << 1;               /* Doubled ref number */
1730 <      ecode += 3;                                 /* Advance past item */
1730 >      ecode += 3;
1731  
1732 <      /* If the reference is unset, set the length to be longer than the amount
1733 <      of subject left; this ensures that every attempt at a match fails. We
1734 <      can't just fail here, because of the possibility of quantifiers with zero
1735 <      minima. */
1736 <
1737 <      length = (offset >= offset_top || md->offset_vector[offset] < 0)?
1738 <        md->end_subject - eptr + 1 :
1739 <        md->offset_vector[offset+1] - md->offset_vector[offset];
1732 >      /* If the reference is unset, there are two possibilities:
1733 >
1734 >      (a) In the default, Perl-compatible state, set the length to be longer
1735 >      than the amount of subject left; this ensures that every attempt at a
1736 >      match fails. We can't just fail here, because of the possibility of
1737 >      quantifiers with zero minima.
1738 >
1739 >      (b) If the JavaScript compatibility flag is set, set the length to zero
1740 >      so that the back reference matches an empty string.
1741 >
1742 >      Otherwise, set the length to the length of what was matched by the
1743 >      referenced subpattern. */
1744 >
1745 >      if (offset >= offset_top || md->offset_vector[offset] < 0)
1746 >        length = (md->jscript_compat)? 0 : md->end_subject - eptr + 1;
1747 >      else
1748 >        length = md->offset_vector[offset+1] - md->offset_vector[offset];
1749  
1750        /* Set up for repetition, or handle the non-repeated case */
1751  
# Line 1311 | Line 1805 | for (;;)
1805          {
1806          for (fi = min;; fi++)
1807            {
1808 <          RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);
1808 >          RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM14);
1809            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
1810            if (fi >= max || !match_ref(offset, eptr, length, md, ims))
1811              RRETURN(MATCH_NOMATCH);
# Line 1332 | Line 1826 | for (;;)
1826            }
1827          while (eptr >= pp)
1828            {
1829 <          RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);
1829 >          RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM15);
1830            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
1831            eptr -= length;
1832            }
# Line 1391 | Line 1885 | for (;;)
1885  
1886        /* First, ensure the minimum number of matches are present. */
1887  
1888 + #ifdef SUPPORT_UTF8
1889 +      /* UTF-8 mode */
1890 +      if (utf8)
1891 +        {
1892 +        for (i = 1; i <= min; i++)
1893 +          {
1894 +          if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
1895 +          GETCHARINC(c, eptr);
1896 +          if (c > 255)
1897 +            {
1898 +            if (op == OP_CLASS) RRETURN(MATCH_NOMATCH);
1899 +            }
1900 +          else
1901 +            {
1902 +            if ((data[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);
1903 +            }
1904 +          }
1905 +        }
1906 +      else
1907 + #endif
1908        /* Not UTF-8 mode */
1909          {
1910          for (i = 1; i <= min; i++)
# Line 1411 | Line 1925 | for (;;)
1925  
1926        if (minimize)
1927          {
1928 + #ifdef SUPPORT_UTF8
1929 +        /* UTF-8 mode */
1930 +        if (utf8)
1931 +          {
1932 +          for (fi = min;; fi++)
1933 +            {
1934 +            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM16);
1935 +            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
1936 +            if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
1937 +            GETCHARINC(c, eptr);
1938 +            if (c > 255)
1939 +              {
1940 +              if (op == OP_CLASS) RRETURN(MATCH_NOMATCH);
1941 +              }
1942 +            else
1943 +              {
1944 +              if ((data[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);
1945 +              }
1946 +            }
1947 +          }
1948 +        else
1949 + #endif
1950          /* Not UTF-8 mode */
1951            {
1952            for (fi = min;; fi++)
1953              {
1954 <            RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);
1954 >            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM17);
1955              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
1956              if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
1957              c = *eptr++;
# Line 1431 | Line 1967 | for (;;)
1967          {
1968          pp = eptr;
1969  
1970 + #ifdef SUPPORT_UTF8
1971 +        /* UTF-8 mode */
1972 +        if (utf8)
1973 +          {
1974 +          for (i = min; i < max; i++)
1975 +            {
1976 +            int len = 1;
1977 +            if (eptr >= md->end_subject) break;
1978 +            GETCHARLEN(c, eptr, len);
1979 +            if (c > 255)
1980 +              {
1981 +              if (op == OP_CLASS) break;
1982 +              }
1983 +            else
1984 +              {
1985 +              if ((data[c/8] & (1 << (c&7))) == 0) break;
1986 +              }
1987 +            eptr += len;
1988 +            }
1989 +          for (;;)
1990 +            {
1991 +            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM18);
1992 +            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
1993 +            if (eptr-- == pp) break;        /* Stop if tried at original pos */
1994 +            BACKCHAR(eptr);
1995 +            }
1996 +          }
1997 +        else
1998 + #endif
1999            /* Not UTF-8 mode */
2000            {
2001            for (i = min; i < max; i++)
# Line 1442 | Line 2007 | for (;;)
2007              }
2008            while (eptr >= pp)
2009              {
2010 <            RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);
1446 <            eptr--;
2010 >            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM19);
2011              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2012 +            eptr--;
2013              }
2014            }
2015  
# Line 1454 | Line 2019 | for (;;)
2019      /* Control never gets here */
2020  
2021  
2022 +    /* Match an extended character class. This opcode is encountered only
2023 +    when UTF-8 mode mode is supported. Nevertheless, we may not be in UTF-8
2024 +    mode, because Unicode properties are supported in non-UTF-8 mode. */
2025 +
2026 + #ifdef SUPPORT_UTF8
2027 +    case OP_XCLASS:
2028 +      {
2029 +      data = ecode + 1 + LINK_SIZE;                /* Save for matching */
2030 +      ecode += GET(ecode, 1);                      /* Advance past the item */
2031 +
2032 +      switch (*ecode)
2033 +        {
2034 +        case OP_CRSTAR:
2035 +        case OP_CRMINSTAR:
2036 +        case OP_CRPLUS:
2037 +        case OP_CRMINPLUS:
2038 +        case OP_CRQUERY:
2039 +        case OP_CRMINQUERY:
2040 +        c = *ecode++ - OP_CRSTAR;
2041 +        minimize = (c & 1) != 0;
2042 +        min = rep_min[c];                 /* Pick up values from tables; */
2043 +        max = rep_max[c];                 /* zero for max => infinity */
2044 +        if (max == 0) max = INT_MAX;
2045 +        break;
2046 +
2047 +        case OP_CRRANGE:
2048 +        case OP_CRMINRANGE:
2049 +        minimize = (*ecode == OP_CRMINRANGE);
2050 +        min = GET2(ecode, 1);
2051 +        max = GET2(ecode, 3);
2052 +        if (max == 0) max = INT_MAX;
2053 +        ecode += 5;
2054 +        break;
2055 +
2056 +        default:               /* No repeat follows */
2057 +        min = max = 1;
2058 +        break;
2059 +        }
2060 +
2061 +      /* First, ensure the minimum number of matches are present. */
2062 +
2063 +      for (i = 1; i <= min; i++)
2064 +        {
2065 +        if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
2066 +        GETCHARINCTEST(c, eptr);
2067 +        if (!_pcre_xclass(c, data)) RRETURN(MATCH_NOMATCH);
2068 +        }
2069 +
2070 +      /* If max == min we can continue with the main loop without the
2071 +      need to recurse. */
2072 +
2073 +      if (min == max) continue;
2074 +
2075 +      /* If minimizing, keep testing the rest of the expression and advancing
2076 +      the pointer while it matches the class. */
2077 +
2078 +      if (minimize)
2079 +        {
2080 +        for (fi = min;; fi++)
2081 +          {
2082 +          RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM20);
2083 +          if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2084 +          if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
2085 +          GETCHARINCTEST(c, eptr);
2086 +          if (!_pcre_xclass(c, data)) RRETURN(MATCH_NOMATCH);
2087 +          }
2088 +        /* Control never gets here */
2089 +        }
2090 +
2091 +      /* If maximizing, find the longest possible run, then work backwards. */
2092 +
2093 +      else
2094 +        {
2095 +        pp = eptr;
2096 +        for (i = min; i < max; i++)
2097 +          {
2098 +          int len = 1;
2099 +          if (eptr >= md->end_subject) break;
2100 +          GETCHARLENTEST(c, eptr, len);
2101 +          if (!_pcre_xclass(c, data)) break;
2102 +          eptr += len;
2103 +          }
2104 +        for(;;)
2105 +          {
2106 +          RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM21);
2107 +          if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2108 +          if (eptr-- == pp) break;        /* Stop if tried at original pos */
2109 +          if (utf8) BACKCHAR(eptr);
2110 +          }
2111 +        RRETURN(MATCH_NOMATCH);
2112 +        }
2113 +
2114 +      /* Control never gets here */
2115 +      }
2116 + #endif    /* End of XCLASS */
2117 +
2118      /* Match a single character, casefully */
2119  
2120      case OP_CHAR:
2121 + #ifdef SUPPORT_UTF8
2122 +    if (utf8)
2123 +      {
2124 +      length = 1;
2125 +      ecode++;
2126 +      GETCHARLEN(fc, ecode, length);
2127 +      if (length > md->end_subject - eptr) RRETURN(MATCH_NOMATCH);
2128 +      while (length-- > 0) if (*ecode++ != *eptr++) RRETURN(MATCH_NOMATCH);
2129 +      }
2130 +    else
2131 + #endif
2132 +
2133      /* Non-UTF-8 mode */
2134        {
2135        if (md->end_subject - eptr < 1) RRETURN(MATCH_NOMATCH);
# Line 1468 | Line 2141 | for (;;)
2141      /* Match a single character, caselessly */
2142  
2143      case OP_CHARNC:
2144 + #ifdef SUPPORT_UTF8
2145 +    if (utf8)
2146 +      {
2147 +      length = 1;
2148 +      ecode++;
2149 +      GETCHARLEN(fc, ecode, length);
2150 +
2151 +      if (length > md->end_subject - eptr) RRETURN(MATCH_NOMATCH);
2152 +
2153 +      /* If the pattern character's value is < 128, we have only one byte, and
2154 +      can use the fast lookup table. */
2155 +
2156 +      if (fc < 128)
2157 +        {
2158 +        if (md->lcc[*ecode++] != md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH);
2159 +        }
2160 +
2161 +      /* Otherwise we must pick up the subject character */
2162 +
2163 +      else
2164 +        {
2165 +        unsigned int dc;
2166 +        GETCHARINC(dc, eptr);
2167 +        ecode += length;
2168 +
2169 +        /* If we have Unicode property support, we can use it to test the other
2170 +        case of the character, if there is one. */
2171 +
2172 +        if (fc != dc)
2173 +          {
2174 + #ifdef SUPPORT_UCP
2175 +          if (dc != UCD_OTHERCASE(fc))
2176 + #endif
2177 +            RRETURN(MATCH_NOMATCH);
2178 +          }
2179 +        }
2180 +      }
2181 +    else
2182 + #endif   /* SUPPORT_UTF8 */
2183 +
2184      /* Non-UTF-8 mode */
2185        {
2186        if (md->end_subject - eptr < 1) RRETURN(MATCH_NOMATCH);
# Line 1476 | Line 2189 | for (;;)
2189        }
2190      break;
2191  
2192 <    /* Match a single character repeatedly; different opcodes share code. */
2192 >    /* Match a single character repeatedly. */
2193  
2194      case OP_EXACT:
2195      min = max = GET2(ecode, 1);
2196      ecode += 3;
2197      goto REPEATCHAR;
2198  
2199 +    case OP_POSUPTO:
2200 +    possessive = TRUE;
2201 +    /* Fall through */
2202 +
2203      case OP_UPTO:
2204      case OP_MINUPTO:
2205      min = 0;
# Line 1491 | Line 2208 | for (;;)
2208      ecode += 3;
2209      goto REPEATCHAR;
2210  
2211 +    case OP_POSSTAR:
2212 +    possessive = TRUE;
2213 +    min = 0;
2214 +    max = INT_MAX;
2215 +    ecode++;
2216 +    goto REPEATCHAR;
2217 +
2218 +    case OP_POSPLUS:
2219 +    possessive = TRUE;
2220 +    min = 1;
2221 +    max = INT_MAX;
2222 +    ecode++;
2223 +    goto REPEATCHAR;
2224 +
2225 +    case OP_POSQUERY:
2226 +    possessive = TRUE;
2227 +    min = 0;
2228 +    max = 1;
2229 +    ecode++;
2230 +    goto REPEATCHAR;
2231 +
2232      case OP_STAR:
2233      case OP_MINSTAR:
2234      case OP_PLUS:
# Line 1508 | Line 2246 | for (;;)
2246      the subject. */
2247  
2248      REPEATCHAR:
2249 + #ifdef SUPPORT_UTF8
2250 +    if (utf8)
2251 +      {
2252 +      length = 1;
2253 +      charptr = ecode;
2254 +      GETCHARLEN(fc, ecode, length);
2255 +      if (min * length > md->end_subject - eptr) RRETURN(MATCH_NOMATCH);
2256 +      ecode += length;
2257 +
2258 +      /* Handle multibyte character matching specially here. There is
2259 +      support for caseless matching if UCP support is present. */
2260 +
2261 +      if (length > 1)
2262 +        {
2263 + #ifdef SUPPORT_UCP
2264 +        unsigned int othercase;
2265 +        if ((ims & PCRE_CASELESS) != 0 &&
2266 +            (othercase = UCD_OTHERCASE(fc)) != fc)
2267 +          oclength = _pcre_ord2utf8(othercase, occhars);
2268 +        else oclength = 0;
2269 + #endif  /* SUPPORT_UCP */
2270 +
2271 +        for (i = 1; i <= min; i++)
2272 +          {
2273 +          if (memcmp(eptr, charptr, length) == 0) eptr += length;
2274 + #ifdef SUPPORT_UCP
2275 +          /* Need braces because of following else */
2276 +          else if (oclength == 0) { RRETURN(MATCH_NOMATCH); }
2277 +          else
2278 +            {
2279 +            if (memcmp(eptr, occhars, oclength) != 0) RRETURN(MATCH_NOMATCH);
2280 +            eptr += oclength;
2281 +            }
2282 + #else   /* without SUPPORT_UCP */
2283 +          else { RRETURN(MATCH_NOMATCH); }
2284 + #endif  /* SUPPORT_UCP */
2285 +          }
2286 +
2287 +        if (min == max) continue;
2288 +
2289 +        if (minimize)
2290 +          {
2291 +          for (fi = min;; fi++)
2292 +            {
2293 +            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM22);
2294 +            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2295 +            if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
2296 +            if (memcmp(eptr, charptr, length) == 0) eptr += length;
2297 + #ifdef SUPPORT_UCP
2298 +            /* Need braces because of following else */
2299 +            else if (oclength == 0) { RRETURN(MATCH_NOMATCH); }
2300 +            else
2301 +              {
2302 +              if (memcmp(eptr, occhars, oclength) != 0) RRETURN(MATCH_NOMATCH);
2303 +              eptr += oclength;
2304 +              }
2305 + #else   /* without SUPPORT_UCP */
2306 +            else { RRETURN (MATCH_NOMATCH); }
2307 + #endif  /* SUPPORT_UCP */
2308 +            }
2309 +          /* Control never gets here */
2310 +          }
2311 +
2312 +        else  /* Maximize */
2313 +          {
2314 +          pp = eptr;
2315 +          for (i = min; i < max; i++)
2316 +            {
2317 +            if (eptr > md->end_subject - length) break;
2318 +            if (memcmp(eptr, charptr, length) == 0) eptr += length;
2319 + #ifdef SUPPORT_UCP
2320 +            else if (oclength == 0) break;
2321 +            else
2322 +              {
2323 +              if (memcmp(eptr, occhars, oclength) != 0) break;
2324 +              eptr += oclength;
2325 +              }
2326 + #else   /* without SUPPORT_UCP */
2327 +            else break;
2328 + #endif  /* SUPPORT_UCP */
2329 +            }
2330 +
2331 +          if (possessive) continue;
2332 +          for(;;)
2333 +           {
2334 +           RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM23);
2335 +           if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2336 +           if (eptr == pp) RRETURN(MATCH_NOMATCH);
2337 + #ifdef SUPPORT_UCP
2338 +           eptr--;
2339 +           BACKCHAR(eptr);
2340 + #else   /* without SUPPORT_UCP */
2341 +           eptr -= length;
2342 + #endif  /* SUPPORT_UCP */
2343 +           }
2344 +          }
2345 +        /* Control never gets here */
2346 +        }
2347 +
2348 +      /* If the length of a UTF-8 character is 1, we fall through here, and
2349 +      obey the code as for non-UTF-8 characters below, though in this case the
2350 +      value of fc will always be < 128. */
2351 +      }
2352 +    else
2353 + #endif  /* SUPPORT_UTF8 */
2354 +
2355      /* When not in UTF-8 mode, load a single-byte character. */
2356        {
2357        if (min > md->end_subject - eptr) RRETURN(MATCH_NOMATCH);
# Line 1536 | Line 2380 | for (;;)
2380          {
2381          for (fi = min;; fi++)
2382            {
2383 <          RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);
2383 >          RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM24);
2384            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2385            if (fi >= max || eptr >= md->end_subject ||
2386                fc != md->lcc[*eptr++])
# Line 1544 | Line 2388 | for (;;)
2388            }
2389          /* Control never gets here */
2390          }
2391 <      else
2391 >      else  /* Maximize */
2392          {
2393          pp = eptr;
2394          for (i = min; i < max; i++)
# Line 1552 | Line 2396 | for (;;)
2396            if (eptr >= md->end_subject || fc != md->lcc[*eptr]) break;
2397            eptr++;
2398            }
2399 +        if (possessive) continue;
2400          while (eptr >= pp)
2401            {
2402 <          RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);
2402 >          RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM25);
2403            eptr--;
2404            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2405            }
# Line 1573 | Line 2418 | for (;;)
2418          {
2419          for (fi = min;; fi++)
2420            {
2421 <          RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);
2421 >          RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM26);
2422            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2423            if (fi >= max || eptr >= md->end_subject || fc != *eptr++)
2424              RRETURN(MATCH_NOMATCH);
2425            }
2426          /* Control never gets here */
2427          }
2428 <      else
2428 >      else  /* Maximize */
2429          {
2430          pp = eptr;
2431          for (i = min; i < max; i++)
# Line 1588 | Line 2433 | for (;;)
2433            if (eptr >= md->end_subject || fc != *eptr) break;
2434            eptr++;
2435            }
2436 +        if (possessive) continue;
2437          while (eptr >= pp)
2438            {
2439 <          RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);
2439 >          RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM27);
2440            eptr--;
2441            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2442            }
# Line 1608 | Line 2454 | for (;;)
2454      GETCHARINCTEST(c, eptr);
2455      if ((ims & PCRE_CASELESS) != 0)
2456        {
2457 + #ifdef SUPPORT_UTF8
2458 +      if (c < 256)
2459 + #endif
2460        c = md->lcc[c];
2461        if (md->lcc[*ecode++] == c) RRETURN(MATCH_NOMATCH);
2462        }
# Line 1637 | Line 2486 | for (;;)
2486      ecode += 3;
2487      goto REPEATNOTCHAR;
2488  
2489 +    case OP_NOTPOSSTAR:
2490 +    possessive = TRUE;
2491 +    min = 0;
2492 +    max = INT_MAX;
2493 +    ecode++;
2494 +    goto REPEATNOTCHAR;
2495 +
2496 +    case OP_NOTPOSPLUS:
2497 +    possessive = TRUE;
2498 +    min = 1;
2499 +    max = INT_MAX;
2500 +    ecode++;
2501 +    goto REPEATNOTCHAR;
2502 +
2503 +    case OP_NOTPOSQUERY:
2504 +    possessive = TRUE;
2505 +    min = 0;
2506 +    max = 1;
2507 +    ecode++;
2508 +    goto REPEATNOTCHAR;
2509 +
2510 +    case OP_NOTPOSUPTO:
2511 +    possessive = TRUE;
2512 +    min = 0;
2513 +    max = GET2(ecode, 1);
2514 +    ecode += 3;
2515 +    goto REPEATNOTCHAR;
2516 +
2517      case OP_NOTSTAR:
2518      case OP_NOTMINSTAR:
2519      case OP_NOTPLUS:
# Line 1672 | Line 2549 | for (;;)
2549        {
2550        fc = md->lcc[fc];
2551  
2552 + #ifdef SUPPORT_UTF8
2553 +      /* UTF-8 mode */
2554 +      if (utf8)
2555 +        {
2556 +        register unsigned int d;
2557 +        for (i = 1; i <= min; i++)
2558 +          {
2559 +          GETCHARINC(d, eptr);
2560 +          if (d < 256) d = md->lcc[d];
2561 +          if (fc == d) RRETURN(MATCH_NOMATCH);
2562 +          }
2563 +        }
2564 +      else
2565 + #endif
2566 +
2567        /* Not UTF-8 mode */
2568          {
2569          for (i = 1; i <= min; i++)
# Line 1682 | Line 2574 | for (;;)
2574  
2575        if (minimize)
2576          {
2577 + #ifdef SUPPORT_UTF8
2578 +        /* UTF-8 mode */
2579 +        if (utf8)
2580 +          {
2581 +          register unsigned int d;
2582 +          for (fi = min;; fi++)
2583 +            {
2584 +            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM28);
2585 +            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2586 +            if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
2587 +            GETCHARINC(d, eptr);
2588 +            if (d < 256) d = md->lcc[d];
2589 +            if (fc == d) RRETURN(MATCH_NOMATCH);
2590 +
2591 +            }
2592 +          }
2593 +        else
2594 + #endif
2595          /* Not UTF-8 mode */
2596            {
2597            for (fi = min;; fi++)
2598              {
2599 <            RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);
2599 >            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM29);
2600              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2601              if (fi >= max || eptr >= md->end_subject || fc == md->lcc[*eptr++])
2602                RRETURN(MATCH_NOMATCH);
# Line 1701 | Line 2611 | for (;;)
2611          {
2612          pp = eptr;
2613  
2614 + #ifdef SUPPORT_UTF8
2615 +        /* UTF-8 mode */
2616 +        if (utf8)
2617 +          {
2618 +          register unsigned int d;
2619 +          for (i = min; i < max; i++)
2620 +            {
2621 +            int len = 1;
2622 +            if (eptr >= md->end_subject) break;
2623 +            GETCHARLEN(d, eptr, len);
2624 +            if (d < 256) d = md->lcc[d];
2625 +            if (fc == d) break;
2626 +            eptr += len;
2627 +            }
2628 +        if (possessive) continue;
2629 +        for(;;)
2630 +            {
2631 +            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM30);
2632 +            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2633 +            if (eptr-- == pp) break;        /* Stop if tried at original pos */
2634 +            BACKCHAR(eptr);
2635 +            }
2636 +          }
2637 +        else
2638 + #endif
2639          /* Not UTF-8 mode */
2640            {
2641            for (i = min; i < max; i++)
# Line 1708 | Line 2643 | for (;;)
2643              if (eptr >= md->end_subject || fc == md->lcc[*eptr]) break;
2644              eptr++;
2645              }
2646 +          if (possessive) continue;
2647            while (eptr >= pp)
2648              {
2649 <            RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);
2649 >            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM31);
2650              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2651              eptr--;
2652              }
# Line 1725 | Line 2661 | for (;;)
2661  
2662      else
2663        {
2664 + #ifdef SUPPORT_UTF8
2665 +      /* UTF-8 mode */
2666 +      if (utf8)
2667 +        {
2668 +        register unsigned int d;
2669 +        for (i = 1; i <= min; i++)
2670 +          {
2671 +          GETCHARINC(d, eptr);
2672 +          if (fc == d) RRETURN(MATCH_NOMATCH);
2673 +          }
2674 +        }
2675 +      else
2676 + #endif
2677        /* Not UTF-8 mode */
2678          {
2679          for (i = 1; i <= min; i++)
# Line 1735 | Line 2684 | for (;;)
2684  
2685        if (minimize)
2686          {
2687 + #ifdef SUPPORT_UTF8
2688 +        /* UTF-8 mode */
2689 +        if (utf8)
2690 +          {
2691 +          register unsigned int d;
2692 +          for (fi = min;; fi++)
2693 +            {
2694 +            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM32);
2695 +            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2696 +            if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
2697 +            GETCHARINC(d, eptr);
2698 +            if (fc == d) RRETURN(MATCH_NOMATCH);
2699 +            }
2700 +          }
2701 +        else
2702 + #endif
2703          /* Not UTF-8 mode */
2704            {
2705            for (fi = min;; fi++)
2706              {
2707 <            RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);
2707 >            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM33);
2708              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2709              if (fi >= max || eptr >= md->end_subject || fc == *eptr++)
2710                RRETURN(MATCH_NOMATCH);
# Line 1754 | Line 2719 | for (;;)
2719          {
2720          pp = eptr;
2721  
2722 + #ifdef SUPPORT_UTF8
2723 +        /* UTF-8 mode */
2724 +        if (utf8)
2725 +          {
2726 +          register unsigned int d;
2727 +          for (i = min; i < max; i++)
2728 +            {
2729 +            int len = 1;
2730 +            if (eptr >= md->end_subject) break;
2731 +            GETCHARLEN(d, eptr, len);
2732 +            if (fc == d) break;
2733 +            eptr += len;
2734 +            }
2735 +          if (possessive) continue;
2736 +          for(;;)
2737 +            {
2738 +            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM34);
2739 +            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2740 +            if (eptr-- == pp) break;        /* Stop if tried at original pos */
2741 +            BACKCHAR(eptr);
2742 +            }
2743 +          }
2744 +        else
2745 + #endif
2746          /* Not UTF-8 mode */
2747            {
2748            for (i = min; i < max; i++)
# Line 1761 | Line 2750 | for (;;)
2750              if (eptr >= md->end_subject || fc == *eptr) break;
2751              eptr++;
2752              }
2753 +          if (possessive) continue;
2754            while (eptr >= pp)
2755              {
2756 <            RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);
2756 >            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM35);
2757              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2758              eptr--;
2759              }
# Line 1792 | Line 2782 | for (;;)
2782      ecode += 3;
2783      goto REPEATTYPE;
2784  
2785 +    case OP_TYPEPOSSTAR:
2786 +    possessive = TRUE;
2787 +    min = 0;
2788 +    max = INT_MAX;
2789 +    ecode++;
2790 +    goto REPEATTYPE;
2791 +
2792 +    case OP_TYPEPOSPLUS:
2793 +    possessive = TRUE;
2794 +    min = 1;
2795 +    max = INT_MAX;
2796 +    ecode++;
2797 +    goto REPEATTYPE;
2798 +
2799 +    case OP_TYPEPOSQUERY:
2800 +    possessive = TRUE;
2801 +    min = 0;
2802 +    max = 1;
2803 +    ecode++;
2804 +    goto REPEATTYPE;
2805 +
2806 +    case OP_TYPEPOSUPTO:
2807 +    possessive = TRUE;
2808 +    min = 0;
2809 +    max = GET2(ecode, 1);
2810 +    ecode += 3;
2811 +    goto REPEATTYPE;
2812 +
2813      case OP_TYPESTAR:
2814      case OP_TYPEMINSTAR:
2815      case OP_TYPEPLUS:
# Line 1811 | Line 2829 | for (;;)
2829      REPEATTYPE:
2830      ctype = *ecode++;      /* Code for the character type */
2831  
2832 + #ifdef SUPPORT_UCP
2833 +    if (ctype == OP_PROP || ctype == OP_NOTPROP)
2834 +      {
2835 +      prop_fail_result = ctype == OP_NOTPROP;
2836 +      prop_type = *ecode++;
2837 +      prop_value = *ecode++;
2838 +      }
2839 +    else prop_type = -1;
2840 + #endif
2841 +
2842      /* First, ensure the minimum number of matches are present. Use inline
2843      code for maximizing the speed, and do the type test once at the start
2844      (i.e. keep it out of the loop). Also we can test that there are at least
# Line 1822 | Line 2850 | for (;;)
2850      if (min > md->end_subject - eptr) RRETURN(MATCH_NOMATCH);
2851      if (min > 0)
2852        {
2853 + #ifdef SUPPORT_UCP
2854 +      if (prop_type >= 0)
2855 +        {
2856 +        switch(prop_type)
2857 +          {
2858 +          case PT_ANY:
2859 +          if (prop_fail_result) RRETURN(MATCH_NOMATCH);
2860 +          for (i = 1; i <= min; i++)
2861 +            {
2862 +            if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
2863 +            GETCHARINCTEST(c, eptr);
2864 +            }
2865 +          break;
2866 +
2867 +          case PT_LAMP:
2868 +          for (i = 1; i <= min; i++)
2869 +            {
2870 +            if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
2871 +            GETCHARINCTEST(c, eptr);
2872 +            prop_chartype = UCD_CHARTYPE(c);
2873 +            if ((prop_chartype == ucp_Lu ||
2874 +                 prop_chartype == ucp_Ll ||
2875 +                 prop_chartype == ucp_Lt) == prop_fail_result)
2876 +              RRETURN(MATCH_NOMATCH);
2877 +            }
2878 +          break;
2879 +
2880 +          case PT_GC:
2881 +          for (i = 1; i <= min; i++)
2882 +            {
2883 +            if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
2884 +            GETCHARINCTEST(c, eptr);
2885 +            prop_category = UCD_CATEGORY(c);
2886 +            if ((prop_category == prop_value) == prop_fail_result)
2887 +              RRETURN(MATCH_NOMATCH);
2888 +            }
2889 +          break;
2890 +
2891 +          case PT_PC:
2892 +          for (i = 1; i <= min; i++)
2893 +            {
2894 +            if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
2895 +            GETCHARINCTEST(c, eptr);
2896 +            prop_chartype = UCD_CHARTYPE(c);
2897 +            if ((prop_chartype == prop_value) == prop_fail_result)
2898 +              RRETURN(MATCH_NOMATCH);
2899 +            }
2900 +          break;
2901 +
2902 +          case PT_SC:
2903 +          for (i = 1; i <= min; i++)
2904 +            {
2905 +            if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
2906 +            GETCHARINCTEST(c, eptr);
2907 +            prop_script = UCD_SCRIPT(c);
2908 +            if ((prop_script == prop_value) == prop_fail_result)
2909 +              RRETURN(MATCH_NOMATCH);
2910 +            }
2911 +          break;
2912 +
2913 +          default:
2914 +          RRETURN(PCRE_ERROR_INTERNAL);
2915 +          }
2916 +        }
2917 +
2918 +      /* Match extended Unicode sequences. We will get here only if the
2919 +      support is in the binary; otherwise a compile-time error occurs. */
2920 +
2921 +      else if (ctype == OP_EXTUNI)
2922 +        {
2923 +        for (i = 1; i <= min; i++)
2924 +          {
2925 +          GETCHARINCTEST(c, eptr);
2926 +          prop_category = UCD_CATEGORY(c);
2927 +          if (prop_category == ucp_M) RRETURN(MATCH_NOMATCH);
2928 +          while (eptr < md->end_subject)
2929 +            {
2930 +            int len = 1;
2931 +            if (!utf8) c = *eptr; else
2932 +              {
2933 +              GETCHARLEN(c, eptr, len);
2934 +              }
2935 +            prop_category = UCD_CATEGORY(c);
2936 +            if (prop_category != ucp_M) break;
2937 +            eptr += len;
2938 +            }
2939 +          }
2940 +        }
2941 +
2942 +      else
2943 + #endif     /* SUPPORT_UCP */
2944 +
2945 + /* Handle all other cases when the coding is UTF-8 */
2946 +
2947 + #ifdef SUPPORT_UTF8
2948 +      if (utf8) switch(ctype)
2949 +        {
2950 +        case OP_ANY:
2951 +        for (i = 1; i <= min; i++)
2952 +          {
2953 +          if (eptr >= md->end_subject || IS_NEWLINE(eptr))
2954 +            RRETURN(MATCH_NOMATCH);
2955 +          eptr++;
2956 +          while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;
2957 +          }
2958 +        break;
2959 +
2960 +        case OP_ALLANY:
2961 +        for (i = 1; i <= min; i++)
2962 +          {
2963 +          if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
2964 +          eptr++;
2965 +          while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;
2966 +          }
2967 +        break;
2968 +
2969 +        case OP_ANYBYTE:
2970 +        eptr += min;
2971 +        break;
2972 +
2973 +        case OP_ANYNL:
2974 +        for (i = 1; i <= min; i++)
2975 +          {
2976 +          if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
2977 +          GETCHARINC(c, eptr);
2978 +          switch(c)
2979 +            {
2980 +            default: RRETURN(MATCH_NOMATCH);
2981 +            case 0x000d:
2982 +            if (eptr < md->end_subject && *eptr == 0x0a) eptr++;
2983 +            break;
2984 +
2985 +            case 0x000a:
2986 +            break;
2987 +
2988 +            case 0x000b:
2989 +            case 0x000c:
2990 +            case 0x0085:
2991 +            case 0x2028:
2992 +            case 0x2029:
2993 +            if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH);
2994 +            break;
2995 +            }
2996 +          }
2997 +        break;
2998 +
2999 +        case OP_NOT_HSPACE:
3000 +        for (i = 1; i <= min; i++)
3001 +          {
3002 +          if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
3003 +          GETCHARINC(c, eptr);
3004 +          switch(c)
3005 +            {
3006 +            default: break;
3007 +            case 0x09:      /* HT */
3008 +            case 0x20:      /* SPACE */
3009 +            case 0xa0:      /* NBSP */
3010 +            case 0x1680:    /* OGHAM SPACE MARK */
3011 +            case 0x180e:    /* MONGOLIAN VOWEL SEPARATOR */
3012 +            case 0x2000:    /* EN QUAD */
3013 +            case 0x2001:    /* EM QUAD */
3014 +            case 0x2002:    /* EN SPACE */
3015 +            case 0x2003:    /* EM SPACE */
3016 +            case 0x2004:    /* THREE-PER-EM SPACE */
3017 +            case 0x2005:    /* FOUR-PER-EM SPACE */
3018 +            case 0x2006:    /* SIX-PER-EM SPACE */
3019 +            case 0x2007:    /* FIGURE SPACE */
3020 +            case 0x2008:    /* PUNCTUATION SPACE */
3021 +            case 0x2009:    /* THIN SPACE */
3022 +            case 0x200A:    /* HAIR SPACE */
3023 +            case 0x202f:    /* NARROW NO-BREAK SPACE */
3024 +            case 0x205f:    /* MEDIUM MATHEMATICAL SPACE */
3025 +            case 0x3000:    /* IDEOGRAPHIC SPACE */
3026 +            RRETURN(MATCH_NOMATCH);
3027 +            }
3028 +          }
3029 +        break;
3030 +
3031 +        case OP_HSPACE:
3032 +        for (i = 1; i <= min; i++)
3033 +          {
3034 +          if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
3035 +          GETCHARINC(c, eptr);
3036 +          switch(c)
3037 +            {
3038 +            default: RRETURN(MATCH_NOMATCH);
3039 +            case 0x09:      /* HT */
3040 +            case 0x20:      /* SPACE */
3041 +            case 0xa0:      /* NBSP */
3042 +            case 0x1680:    /* OGHAM SPACE MARK */
3043 +            case 0x180e:    /* MONGOLIAN VOWEL SEPARATOR */
3044 +            case 0x2000:    /* EN QUAD */
3045 +            case 0x2001:    /* EM QUAD */
3046 +            case 0x2002:    /* EN SPACE */
3047 +            case 0x2003:    /* EM SPACE */
3048 +            case 0x2004:    /* THREE-PER-EM SPACE */
3049 +            case 0x2005:    /* FOUR-PER-EM SPACE */
3050 +            case 0x2006:    /* SIX-PER-EM SPACE */
3051 +            case 0x2007:    /* FIGURE SPACE */
3052 +            case 0x2008:    /* PUNCTUATION SPACE */
3053 +            case 0x2009:    /* THIN SPACE */
3054 +            case 0x200A:    /* HAIR SPACE */
3055 +            case 0x202f:    /* NARROW NO-BREAK SPACE */
3056 +            case 0x205f:    /* MEDIUM MATHEMATICAL SPACE */
3057 +            case 0x3000:    /* IDEOGRAPHIC SPACE */
3058 +            break;
3059 +            }
3060 +          }
3061 +        break;
3062 +
3063 +        case OP_NOT_VSPACE:
3064 +        for (i = 1; i <= min; i++)
3065 +          {
3066 +          if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
3067 +          GETCHARINC(c, eptr);
3068 +          switch(c)
3069 +            {
3070 +            default: break;
3071 +            case 0x0a:      /* LF */
3072 +            case 0x0b:      /* VT */
3073 +            case 0x0c:      /* FF */
3074 +            case 0x0d:      /* CR */
3075 +            case 0x85:      /* NEL */
3076 +            case 0x2028:    /* LINE SEPARATOR */
3077 +            case 0x2029:    /* PARAGRAPH SEPARATOR */
3078 +            RRETURN(MATCH_NOMATCH);
3079 +            }
3080 +          }
3081 +        break;
3082 +
3083 +        case OP_VSPACE:
3084 +        for (i = 1; i <= min; i++)
3085 +          {
3086 +          if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
3087 +          GETCHARINC(c, eptr);
3088 +          switch(c)
3089 +            {
3090 +            default: RRETURN(MATCH_NOMATCH);
3091 +            case 0x0a:      /* LF */
3092 +            case 0x0b:      /* VT */
3093 +            case 0x0c:      /* FF */
3094 +            case 0x0d:      /* CR */
3095 +            case 0x85:      /* NEL */
3096 +            case 0x2028:    /* LINE SEPARATOR */
3097 +            case 0x2029:    /* PARAGRAPH SEPARATOR */
3098 +            break;
3099 +            }
3100 +          }
3101 +        break;
3102 +
3103 +        case OP_NOT_DIGIT:
3104 +        for (i = 1; i <= min; i++)
3105 +          {
3106 +          if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
3107 +          GETCHARINC(c, eptr);
3108 +          if (c < 128 && (md->ctypes[c] & ctype_digit) != 0)
3109 +            RRETURN(MATCH_NOMATCH);
3110 +          }
3111 +        break;
3112 +
3113 +        case OP_DIGIT:
3114 +        for (i = 1; i <= min; i++)
3115 +          {
3116 +          if (eptr >= md->end_subject ||
3117 +             *eptr >= 128 || (md->ctypes[*eptr++] & ctype_digit) == 0)
3118 +            RRETURN(MATCH_NOMATCH);
3119 +          /* No need to skip more bytes - we know it's a 1-byte character */
3120 +          }
3121 +        break;
3122 +
3123 +        case OP_NOT_WHITESPACE:
3124 +        for (i = 1; i <= min; i++)
3125 +          {
3126 +          if (eptr >= md->end_subject ||
3127 +             (*eptr < 128 && (md->ctypes[*eptr] & ctype_space) != 0))
3128 +            RRETURN(MATCH_NOMATCH);
3129 +          while (++eptr < md->end_subject && (*eptr & 0xc0) == 0x80);
3130 +          }
3131 +        break;
3132 +
3133 +        case OP_WHITESPACE:
3134 +        for (i = 1; i <= min; i++)
3135 +          {
3136 +          if (eptr >= md->end_subject ||
3137 +             *eptr >= 128 || (md->ctypes[*eptr++] & ctype_space) == 0)
3138 +            RRETURN(MATCH_NOMATCH);
3139 +          /* No need to skip more bytes - we know it's a 1-byte character */
3140 +          }
3141 +        break;
3142 +
3143 +        case OP_NOT_WORDCHAR:
3144 +        for (i = 1; i <= min; i++)
3145 +          {
3146 +          if (eptr >= md->end_subject ||
3147 +             (*eptr < 128 && (md->ctypes[*eptr] & ctype_word) != 0))
3148 +            RRETURN(MATCH_NOMATCH);
3149 +          while (++eptr < md->end_subject && (*eptr & 0xc0) == 0x80);
3150 +          }
3151 +        break;
3152 +
3153 +        case OP_WORDCHAR:
3154 +        for (i = 1; i <= min; i++)
3155 +          {
3156 +          if (eptr >= md->end_subject ||
3157 +             *eptr >= 128 || (md->ctypes[*eptr++] & ctype_word) == 0)
3158 +            RRETURN(MATCH_NOMATCH);
3159 +          /* No need to skip more bytes - we know it's a 1-byte character */
3160 +          }
3161 +        break;
3162 +
3163 +        default:
3164 +        RRETURN(PCRE_ERROR_INTERNAL);
3165 +        }  /* End switch(ctype) */
3166 +
3167 +      else
3168 + #endif     /* SUPPORT_UTF8 */
3169 +
3170        /* Code for the non-UTF-8 case for minimum matching of operators other
3171 <      than OP_PROP and OP_NOTPROP. */
3171 >      than OP_PROP and OP_NOTPROP. We can assume that there are the minimum
3172 >      number of bytes present, as this was tested above. */
3173  
3174        switch(ctype)
3175          {
3176          case OP_ANY:
3177 <        if ((ims & PCRE_DOTALL) == 0)
3177 >        for (i = 1; i <= min; i++)
3178            {
3179 <          for (i = 1; i <= min; i++)
3180 <            if (*eptr++ == NEWLINE) RRETURN(MATCH_NOMATCH);
3179 >          if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH);
3180 >          eptr++;
3181            }
3182 <        else eptr += min;
3182 >        break;
3183 >
3184 >        case OP_ALLANY:
3185 >        eptr += min;
3186          break;
3187  
3188          case OP_ANYBYTE:
3189          eptr += min;
3190          break;
3191  
3192 +        /* Because of the CRLF case, we can't assume the minimum number of
3193 +        bytes are present in this case. */
3194 +
3195 +        case OP_ANYNL:
3196 +        for (i = 1; i <= min; i++)
3197 +          {
3198 +          if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
3199 +          switch(*eptr++)
3200 +            {
3201 +            default: RRETURN(MATCH_NOMATCH);
3202 +            case 0x000d:
3203 +            if (eptr < md->end_subject && *eptr == 0x0a) eptr++;
3204 +            break;
3205 +            case 0x000a:
3206 +            break;
3207 +
3208 +            case 0x000b:
3209 +            case 0x000c:
3210 +            case 0x0085:
3211 +            if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH);
3212 +            break;
3213 +            }
3214 +          }
3215 +        break;
3216 +
3217 +        case OP_NOT_HSPACE:
3218 +        for (i = 1; i <= min; i++)
3219 +          {
3220 +          if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
3221 +          switch(*eptr++)
3222 +            {
3223 +            default: break;
3224 +            case 0x09:      /* HT */
3225 +            case 0x20:      /* SPACE */
3226 +            case 0xa0:      /* NBSP */
3227 +            RRETURN(MATCH_NOMATCH);
3228 +            }
3229 +          }
3230 +        break;
3231 +
3232 +        case OP_HSPACE:
3233 +        for (i = 1; i <= min; i++)
3234 +          {
3235 +          if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
3236 +          switch(*eptr++)
3237 +            {
3238 +            default: RRETURN(MATCH_NOMATCH);
3239 +            case 0x09:      /* HT */
3240 +            case 0x20:      /* SPACE */
3241 +            case 0xa0:      /* NBSP */
3242 +            break;
3243 +            }
3244 +          }
3245 +        break;
3246 +
3247 +        case OP_NOT_VSPACE:
3248 +        for (i = 1; i <= min; i++)
3249 +          {
3250 +          if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
3251 +          switch(*eptr++)
3252 +            {
3253 +            default: break;
3254 +            case 0x0a:      /* LF */
3255 +            case 0x0b:      /* VT */
3256 +            case 0x0c:      /* FF */
3257 +            case 0x0d:      /* CR */
3258 +            case 0x85:      /* NEL */
3259 +            RRETURN(MATCH_NOMATCH);
3260 +            }
3261 +          }
3262 +        break;
3263 +
3264 +        case OP_VSPACE:
3265 +        for (i = 1; i <= min; i++)
3266 +          {
3267 +          if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
3268 +          switch(*eptr++)
3269 +            {
3270 +            default: RRETURN(MATCH_NOMATCH);
3271 +            case 0x0a:      /* LF */
3272 +            case 0x0b:      /* VT */
3273 +            case 0x0c:      /* FF */
3274 +            case 0x0d:      /* CR */
3275 +            case 0x85:      /* NEL */
3276 +            break;
3277 +            }
3278 +          }
3279 +        break;
3280 +
3281          case OP_NOT_DIGIT:
3282          for (i = 1; i <= min; i++)
3283            if ((md->ctypes[*eptr++] & ctype_digit) != 0) RRETURN(MATCH_NOMATCH);
# Line 1887 | Line 3325 | for (;;)
3325  
3326      if (minimize)
3327        {
3328 <      /* Not UTF-8 mode */
3328 > #ifdef SUPPORT_UCP
3329 >      if (prop_type >= 0)
3330 >        {
3331 >        switch(prop_type)
3332 >          {
3333 >          case PT_ANY:
3334 >          for (fi = min;; fi++)
3335 >            {
3336 >            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM36);
3337 >            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3338 >            if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
3339 >            GETCHARINC(c, eptr);
3340 >            if (prop_fail_result) RRETURN(MATCH_NOMATCH);
3341 >            }
3342 >          /* Control never gets here */
3343 >
3344 >          case PT_LAMP:
3345 >          for (fi = min;; fi++)
3346 >            {
3347 >            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM37);
3348 >            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3349 >            if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
3350 >            GETCHARINC(c, eptr);
3351 >            prop_chartype = UCD_CHARTYPE(c);
3352 >            if ((prop_chartype == ucp_Lu ||
3353 >                 prop_chartype == ucp_Ll ||
3354 >                 prop_chartype == ucp_Lt) == prop_fail_result)
3355 >              RRETURN(MATCH_NOMATCH);
3356 >            }
3357 >          /* Control never gets here */
3358 >
3359 >          case PT_GC:
3360 >          for (fi = min;; fi++)
3361 >            {
3362 >            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM38);
3363 >            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3364 >            if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
3365 >            GETCHARINC(c, eptr);
3366 >            prop_category = UCD_CATEGORY(c);
3367 >            if ((prop_category == prop_value) == prop_fail_result)
3368 >              RRETURN(MATCH_NOMATCH);
3369 >            }
3370 >          /* Control never gets here */
3371 >
3372 >          case PT_PC:
3373 >          for (fi = min;; fi++)
3374 >            {
3375 >            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM39);
3376 >            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3377 >            if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
3378 >            GETCHARINC(c, eptr);
3379 >            prop_chartype = UCD_CHARTYPE(c);
3380 >            if ((prop_chartype == prop_value) == prop_fail_result)
3381 >              RRETURN(MATCH_NOMATCH);
3382 >            }
3383 >          /* Control never gets here */
3384 >
3385 >          case PT_SC:
3386 >          for (fi = min;; fi++)
3387 >            {
3388 >            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM40);
3389 >            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3390 >            if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
3391 >            GETCHARINC(c, eptr);
3392 >            prop_script = UCD_SCRIPT(c);
3393 >            if ((prop_script == prop_value) == prop_fail_result)
3394 >              RRETURN(MATCH_NOMATCH);
3395 >            }
3396 >          /* Control never gets here */
3397 >
3398 >          default:
3399 >          RRETURN(PCRE_ERROR_INTERNAL);
3400 >          }
3401 >        }
3402 >
3403 >      /* Match extended Unicode sequences. We will get here only if the
3404 >      support is in the binary; otherwise a compile-time error occurs. */
3405 >
3406 >      else if (ctype == OP_EXTUNI)
3407          {
3408          for (fi = min;; fi++)
3409            {
3410 <          RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);
3410 >          RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM41);
3411            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3412            if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);
3413 <          c = *eptr++;
3413 >          GETCHARINCTEST(c, eptr);
3414 >          prop_category = UCD_CATEGORY(c);
3415 >          if (prop_category == ucp_M) RRETURN(MATCH_NOMATCH);
3416 >          while (eptr < md->end_subject)
3417 >            {
3418 >            int len = 1;
3419 >            if (!utf8) c = *eptr; else
3420 >              {
3421 >              GETCHARLEN(c, eptr, len);
3422 >              }
3423 >            prop_category = UCD_CATEGORY(c);
3424 >            if (prop_category != ucp_M) break;
3425 >            eptr += len;
3426 >            }
3427 >          }
3428 >        }
3429 >
3430 >      else
3431 > #endif     /* SUPPORT_UCP */
3432 >
3433 > #ifdef SUPPORT_UTF8
3434 >      /* UTF-8 mode */
3435 >      if (utf8)
3436 >        {
3437 >        for (fi = min;; fi++)
3438 >          {
3439 >          RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM42);
3440 >          if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3441 >          if (fi >= max || eptr >= md->end_subject ||
3442 >               (ctype == OP_ANY && IS_NEWLINE(eptr)))
3443 >            RRETURN(MATCH_NOMATCH);
3444 >
3445 >          GETCHARINC(c, eptr);
3446            switch(ctype)
3447              {
3448 <            case OP_ANY:
3449 <            if ((ims & PCRE_DOTALL) == 0 && c == NEWLINE) RRETURN(MATCH_NOMATCH);
3448 >            case OP_ANY:        /* This is the non-NL case */
3449 >            case OP_ALLANY:
3450 >            case OP_ANYBYTE:
3451 >            break;
3452 >
3453 >            case OP_ANYNL:
3454 >            switch(c)
3455 >              {
3456 >              default: RRETURN(MATCH_NOMATCH);
3457 >              case 0x000d:
3458 >              if (eptr < md->end_subject && *eptr == 0x0a) eptr++;
3459 >              break;
3460 >              case 0x000a:
3461 >              break;
3462 >
3463 >              case 0x000b:
3464 >              case 0x000c:
3465 >              case 0x0085:
3466 >              case 0x2028:
3467 >              case 0x2029:
3468 >              if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH);
3469 >              break;
3470 >              }
3471 >            break;
3472 >
3473 >            case OP_NOT_HSPACE:
3474 >            switch(c)
3475 >              {
3476 >              default: break;
3477 >              case 0x09:      /* HT */
3478 >              case 0x20:      /* SPACE */
3479 >              case 0xa0:      /* NBSP */
3480 >              case 0x1680:    /* OGHAM SPACE MARK */
3481 >              case 0x180e:    /* MONGOLIAN VOWEL SEPARATOR */
3482 >              case 0x2000:    /* EN QUAD */
3483 >              case 0x2001:    /* EM QUAD */
3484 >              case 0x2002:    /* EN SPACE */
3485 >              case 0x2003:    /* EM SPACE */
3486 >              case 0x2004:    /* THREE-PER-EM SPACE */
3487 >              case 0x2005:    /* FOUR-PER-EM SPACE */
3488 >              case 0x2006:    /* SIX-PER-EM SPACE */
3489 >              case 0x2007:    /* FIGURE SPACE */
3490 >              case 0x2008:    /* PUNCTUATION SPACE */
3491 >              case 0x2009:    /* THIN SPACE */
3492 >              case 0x200A:    /* HAIR SPACE */
3493 >              case 0x202f:    /* NARROW NO-BREAK SPACE */
3494 >              case 0x205f:    /* MEDIUM MATHEMATICAL SPACE */
3495 >              case 0x3000:    /* IDEOGRAPHIC SPACE */
3496 >              RRETURN(MATCH_NOMATCH);
3497 >              }
3498 >            break;
3499 >
3500 >            case OP_HSPACE:
3501 >            switch(c)
3502 >              {
3503 >              default: RRETURN(MATCH_NOMATCH);
3504 >              case 0x09:      /* HT */
3505 >              case 0x20:      /* SPACE */
3506 >              case 0xa0:      /* NBSP */
3507 >              case 0x1680:    /* OGHAM SPACE MARK */
3508 >              case 0x180e:    /* MONGOLIAN VOWEL SEPARATOR */
3509 >              case 0x2000:    /* EN QUAD */
3510 >              case 0x2001:    /* EM QUAD */
3511 >              case 0x2002:    /* EN SPACE */
3512 >              case 0x2003:    /* EM SPACE */
3513 >              case 0x2004:    /* THREE-PER-EM SPACE */
3514 >              case 0x2005:    /* FOUR-PER-EM SPACE */
3515 >              case 0x2006:    /* SIX-PER-EM SPACE */
3516 >              case 0x2007:    /* FIGURE SPACE */
3517 >              case 0x2008:    /* PUNCTUATION SPACE */
3518 >              case 0x2009:    /* THIN SPACE */
3519 >              case 0x200A:    /* HAIR SPACE */
3520 >              case 0x202f:    /* NARROW NO-BREAK SPACE */
3521 >              case 0x205f:    /* MEDIUM MATHEMATICAL SPACE */
3522 >              case 0x3000:    /* IDEOGRAPHIC SPACE */
3523 >              break;
3524 >              }
3525 >            break;
3526 >
3527 >            case OP_NOT_VSPACE:
3528 >            switch(c)
3529 >              {
3530 >              default: break;
3531 >              case 0x0a:      /* LF */
3532 >              case 0x0b:      /* VT */
3533 >              case 0x0c:      /* FF */
3534 >              case 0x0d:      /* CR */
3535 >              case 0x85:      /* NEL */
3536 >              case 0x2028:    /* LINE SEPARATOR */
3537 >              case 0x2029:    /* PARAGRAPH SEPARATOR */
3538 >              RRETURN(MATCH_NOMATCH);
3539 >              }
3540 >            break;
3541 >
3542 >            case OP_VSPACE:
3543 >            switch(c)
3544 >              {
3545 >              default: RRETURN(MATCH_NOMATCH);
3546 >              case 0x0a:      /* LF */
3547 >              case 0x0b:      /* VT */
3548 >              case 0x0c:      /* FF */
3549 >              case 0x0d:      /* CR */
3550 >              case 0x85:      /* NEL */
3551 >              case 0x2028:    /* LINE SEPARATOR */
3552 >              case 0x2029:    /* PARAGRAPH SEPARATOR */
3553 >              break;
3554 >              }
3555 >            break;
3556 >
3557 >            case OP_NOT_DIGIT:
3558 >            if (c < 256 && (md->ctypes[c] & ctype_digit) != 0)
3559 >              RRETURN(MATCH_NOMATCH);
3560              break;
3561  
3562 +            case OP_DIGIT:
3563 +            if (c >= 256 || (md->ctypes[c] & ctype_digit) == 0)
3564 +              RRETURN(MATCH_NOMATCH);
3565 +            break;
3566 +
3567 +            case OP_NOT_WHITESPACE:
3568 +            if (c < 256 && (md->ctypes[c] & ctype_space) != 0)
3569 +              RRETURN(MATCH_NOMATCH);
3570 +            break;
3571 +
3572 +            case OP_WHITESPACE:
3573 +            if  (c >= 256 || (md->ctypes[c] & ctype_space) == 0)
3574 +              RRETURN(MATCH_NOMATCH);
3575 +            break;
3576 +
3577 +            case OP_NOT_WORDCHAR:
3578 +            if (c < 256 && (md->ctypes[c] & ctype_word) != 0)
3579 +              RRETURN(MATCH_NOMATCH);
3580 +            break;
3581 +
3582 +            case OP_WORDCHAR:
3583 +            if (c >= 256 || (md->ctypes[c] & ctype_word) == 0)
3584 +              RRETURN(MATCH_NOMATCH);
3585 +            break;
3586 +
3587 +            default:
3588 +            RRETURN(PCRE_ERROR_INTERNAL);
3589 +            }
3590 +          }
3591 +        }
3592 +      else
3593 + #endif
3594 +      /* Not UTF-8 mode */
3595 +        {
3596 +        for (fi = min;; fi++)
3597 +          {
3598 +          RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM43);
3599 +          if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3600 +          if (fi >= max || eptr >= md->end_subject ||
3601 +               (ctype == OP_ANY && IS_NEWLINE(eptr)))
3602 +            RRETURN(MATCH_NOMATCH);
3603 +
3604 +          c = *eptr++;
3605 +          switch(ctype)
3606 +            {
3607 +            case OP_ANY:     /* This is the non-NL case */
3608 +            case OP_ALLANY:
3609              case OP_ANYBYTE:
3610              break;
3611  
3612 +            case OP_ANYNL:
3613 +            switch(c)
3614 +              {
3615 +              default: RRETURN(MATCH_NOMATCH);
3616 +              case 0x000d:
3617 +              if (eptr < md->end_subject && *eptr == 0x0a) eptr++;
3618 +              break;
3619 +
3620 +              case 0x000a:
3621 +              break;
3622 +
3623 +              case 0x000b:
3624 +              case 0x000c:
3625 +              case 0x0085:
3626 +              if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH);
3627 +              break;
3628 +              }
3629 +            break;
3630 +
3631 +            case OP_NOT_HSPACE:
3632 +            switch(c)
3633 +              {
3634 +              default: break;
3635 +              case 0x09:      /* HT */
3636 +              case 0x20:      /* SPACE */
3637 +              case 0xa0:      /* NBSP */
3638 +              RRETURN(MATCH_NOMATCH);
3639 +              }
3640 +            break;
3641 +
3642 +            case OP_HSPACE:
3643 +            switch(c)
3644 +              {
3645 +              default: RRETURN(MATCH_NOMATCH);
3646 +              case 0x09:      /* HT */
3647 +              case 0x20:      /* SPACE */
3648 +              case 0xa0:      /* NBSP */
3649 +              break;
3650 +              }
3651 +            break;
3652 +
3653 +            case OP_NOT_VSPACE:
3654 +            switch(c)
3655 +              {
3656 +              default: break;
3657 +              case 0x0a:      /* LF */
3658 +              case 0x0b:      /* VT */
3659 +              case 0x0c:      /* FF */
3660 +              case 0x0d:      /* CR */
3661 +              case 0x85:      /* NEL */
3662 +              RRETURN(MATCH_NOMATCH);
3663 +              }
3664 +            break;
3665 +
3666 +            case OP_VSPACE:
3667 +            switch(c)
3668 +              {
3669 +              default: RRETURN(MATCH_NOMATCH);
3670 +              case 0x0a:      /* LF */
3671 +              case 0x0b:      /* VT */
3672 +              case 0x0c:      /* FF */
3673 +              case 0x0d:      /* CR */
3674 +              case 0x85:      /* NEL */
3675 +              break;
3676 +              }
3677 +            break;
3678 +
3679              case OP_NOT_DIGIT:
3680              if ((md->ctypes[c] & ctype_digit) != 0) RRETURN(MATCH_NOMATCH);
3681              break;
# Line 1936 | Line 3708 | for (;;)
3708        /* Control never gets here */
3709        }
3710  
3711 <    /* If maximizing it is worth using inline code for speed, doing the type
3711 >    /* If maximizing, it is worth using inline code for speed, doing the type
3712      test once at the start (i.e. keep it out of the loop). Again, keep the
3713      UTF-8 and UCP stuff separate. */
3714  
# Line 1944 | Line 3716 | for (;;)
3716        {
3717        pp = eptr;  /* Remember where we started */
3718  
3719 <      /* Not UTF-8 mode */
3719 > #ifdef SUPPORT_UCP
3720 >      if (prop_type >= 0)
3721 >        {
3722 >        switch(prop_type)
3723 >          {
3724 >          case PT_ANY:
3725 >          for (i = min; i < max; i++)
3726 >            {
3727 >            int len = 1;
3728 >            if (eptr >= md->end_subject) break;
3729 >            GETCHARLEN(c, eptr, len);
3730 >            if (prop_fail_result) break;
3731 >            eptr+= len;
3732 >            }
3733 >          break;
3734 >
3735 >          case PT_LAMP:
3736 >          for (i = min; i < max; i++)
3737 >            {
3738 >            int len = 1;
3739 >            if (eptr >= md->end_subject) break;
3740 >            GETCHARLEN(c, eptr, len);
3741 >            prop_chartype = UCD_CHARTYPE(c);
3742 >            if ((prop_chartype == ucp_Lu ||
3743 >                 prop_chartype == ucp_Ll ||
3744 >                 prop_chartype == ucp_Lt) == prop_fail_result)
3745 >              break;
3746 >            eptr+= len;
3747 >            }
3748 >          break;
3749 >
3750 >          case PT_GC:
3751 >          for (i = min; i < max; i++)
3752 >            {
3753 >            int len = 1;
3754 >            if (eptr >= md->end_subject) break;
3755 >            GETCHARLEN(c, eptr, len);
3756 >            prop_category = UCD_CATEGORY(c);
3757 >            if ((prop_category == prop_value) == prop_fail_result)
3758 >              break;
3759 >            eptr+= len;
3760 >            }
3761 >          break;
3762 >
3763 >          case PT_PC:
3764 >          for (i = min; i < max; i++)
3765 >            {
3766 >            int len = 1;
3767 >            if (eptr >= md->end_subject) break;
3768 >            GETCHARLEN(c, eptr, len);
3769 >            prop_chartype = UCD_CHARTYPE(c);
3770 >            if ((prop_chartype == prop_value) == prop_fail_result)
3771 >              break;
3772 >            eptr+= len;
3773 >            }
3774 >          break;
3775 >
3776 >          case PT_SC:
3777 >          for (i = min; i < max; i++)
3778 >            {
3779 >            int len = 1;
3780 >            if (eptr >= md->end_subject) break;
3781 >            GETCHARLEN(c, eptr, len);
3782 >            prop_script = UCD_SCRIPT(c);
3783 >            if ((prop_script == prop_value) == prop_fail_result)
3784 >              break;
3785 >            eptr+= len;
3786 >            }
3787 >          break;
3788 >          }
3789 >
3790 >        /* eptr is now past the end of the maximum run */
3791 >
3792 >        if (possessive) continue;
3793 >        for(;;)
3794 >          {
3795 >          RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM44);
3796 >          if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3797 >          if (eptr-- == pp) break;        /* Stop if tried at original pos */
3798 >          if (utf8) BACKCHAR(eptr);
3799 >          }
3800 >        }
3801 >
3802 >      /* Match extended Unicode sequences. We will get here only if the
3803 >      support is in the binary; otherwise a compile-time error occurs. */
3804 >
3805 >      else if (ctype == OP_EXTUNI)
3806 >        {
3807 >        for (i = min; i < max; i++)
3808 >          {
3809 >          if (eptr >= md->end_subject) break;
3810 >          GETCHARINCTEST(c, eptr);
3811 >          prop_category = UCD_CATEGORY(c);
3812 >          if (prop_category == ucp_M) break;
3813 >          while (eptr < md->end_subject)
3814 >            {
3815 >            int len = 1;
3816 >            if (!utf8) c = *eptr; else
3817 >              {
3818 >              GETCHARLEN(c, eptr, len);
3819 >              }
3820 >            prop_category = UCD_CATEGORY(c);
3821 >            if (prop_category != ucp_M) break;
3822 >            eptr += len;
3823 >            }
3824 >          }
3825 >
3826 >        /* eptr is now past the end of the maximum run */
3827 >
3828 >        if (possessive) continue;
3829 >        for(;;)
3830 >          {
3831 >          RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM45);
3832 >          if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3833 >          if (eptr-- == pp) break;        /* Stop if tried at original pos */
3834 >          for (;;)                        /* Move back over one extended */
3835 >            {
3836 >            int len = 1;
3837 >            if (!utf8) c = *eptr; else
3838 >              {
3839 >              BACKCHAR(eptr);
3840 >              GETCHARLEN(c, eptr, len);
3841 >              }
3842 >            prop_category = UCD_CATEGORY(c);
3843 >            if (prop_category != ucp_M) break;
3844 >            eptr--;
3845 >            }
3846 >          }
3847 >        }
3848 >
3849 >      else
3850 > #endif   /* SUPPORT_UCP */
3851 >
3852 > #ifdef SUPPORT_UTF8
3853 >      /* UTF-8 mode */
3854 >
3855 >      if (utf8)
3856          {
3857          switch(ctype)
3858            {
3859            case OP_ANY:
3860 <          if ((ims & PCRE_DOTALL) == 0)
3860 >          if (max < INT_MAX)
3861              {
3862              for (i = min; i < max; i++)
3863                {
3864 <              if (eptr >= md->end_subject || *eptr == NEWLINE) break;
3864 >              if (eptr >= md->end_subject || IS_NEWLINE(eptr)) break;
3865                eptr++;
3866 +              while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;
3867                }
1959            break;
3868              }
1961          /* For DOTALL case, fall through and treat as \C */
3869  
3870 +          /* Handle unlimited UTF-8 repeat */
3871 +
3872 +          else
3873 +            {
3874 +            for (i = min; i < max; i++)
3875 +              {
3876 +              if (eptr >= md->end_subject || IS_NEWLINE(eptr)) break;
3877 +              eptr++;
3878 +              while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;
3879 +              }
3880 +            }
3881 +          break;
3882 +
3883 +          case OP_ALLANY:
3884 +          if (max < INT_MAX)
3885 +            {
3886 +            for (i = min; i < max; i++)
3887 +              {
3888 +              if (eptr >= md->end_subject) break;
3889 +              eptr++;
3890 +              while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;
3891 +              }
3892 +            }
3893 +          else eptr = md->end_subject;   /* Unlimited UTF-8 repeat */
3894 +          break;
3895 +
3896 +          /* The byte case is the same as non-UTF8 */
3897 +
3898 +          case OP_ANYBYTE:
3899 +          c = max - min;
3900 +          if (c > (unsigned int)(md->end_subject - eptr))
3901 +            c = md->end_subject - eptr;
3902 +          eptr += c;
3903 +          break;
3904 +
3905 +          case OP_ANYNL:
3906 +          for (i = min; i < max; i++)
3907 +            {
3908 +            int len = 1;
3909 +            if (eptr >= md->end_subject) break;
3910 +            GETCHARLEN(c, eptr, len);
3911 +            if (c == 0x000d)
3912 +              {
3913 +              if (++eptr >= md->end_subject) break;
3914 +              if (*eptr == 0x000a) eptr++;
3915 +              }
3916 +            else
3917 +              {
3918 +              if (c != 0x000a &&
3919 +                  (md->bsr_anycrlf ||
3920 +                   (c != 0x000b && c != 0x000c &&
3921 +                    c != 0x0085 && c != 0x2028 && c != 0x2029)))
3922 +                break;
3923 +              eptr += len;
3924 +              }
3925 +            }
3926 +          break;
3927 +
3928 +          case OP_NOT_HSPACE:
3929 +          case OP_HSPACE:
3930 +          for (i = min; i < max; i++)
3931 +            {
3932 +            BOOL gotspace;
3933 +            int len = 1;
3934 +            if (eptr >= md->end_subject) break;
3935 +            GETCHARLEN(c, eptr, len);
3936 +            switch(c)
3937 +              {
3938 +              default: gotspace = FALSE; break;
3939 +              case 0x09:      /* HT */
3940 +              case 0x20:      /* SPACE */
3941 +              case 0xa0:      /* NBSP */
3942 +              case 0x1680:    /* OGHAM SPACE MARK */
3943 +              case 0x180e:    /* MONGOLIAN VOWEL SEPARATOR */
3944 +              case 0x2000:    /* EN QUAD */
3945 +              case 0x2001:    /* EM QUAD */
3946 +              case 0x2002:    /* EN SPACE */
3947 +              case 0x2003:    /* EM SPACE */
3948 +              case 0x2004:    /* THREE-PER-EM SPACE */
3949 +              case 0x2005:    /* FOUR-PER-EM SPACE */
3950 +              case 0x2006:    /* SIX-PER-EM SPACE */
3951 +              case 0x2007:    /* FIGURE SPACE */
3952 +              case 0x2008:    /* PUNCTUATION SPACE */
3953 +              case 0x2009:    /* THIN SPACE */
3954 +              case 0x200A:    /* HAIR SPACE */
3955 +              case 0x202f:    /* NARROW NO-BREAK SPACE */
3956 +              case 0x205f:    /* MEDIUM MATHEMATICAL SPACE */
3957 +              case 0x3000:    /* IDEOGRAPHIC SPACE */
3958 +              gotspace = TRUE;
3959 +              break;
3960 +              }
3961 +            if (gotspace == (ctype == OP_NOT_HSPACE)) break;
3962 +            eptr += len;
3963 +            }
3964 +          break;
3965 +
3966 +          case OP_NOT_VSPACE:
3967 +          case OP_VSPACE:
3968 +          for (i = min; i < max; i++)
3969 +            {
3970 +            BOOL gotspace;
3971 +            int len = 1;
3972 +            if (eptr >= md->end_subject) break;
3973 +            GETCHARLEN(c, eptr, len);
3974 +            switch(c)
3975 +              {
3976 +              default: gotspace = FALSE; break;
3977 +              case 0x0a:      /* LF */
3978 +              case 0x0b:      /* VT */
3979 +              case 0x0c:      /* FF */
3980 +              case 0x0d:      /* CR */
3981 +              case 0x85:      /* NEL */
3982 +              case 0x2028:    /* LINE SEPARATOR */
3983 +              case 0x2029:    /* PARAGRAPH SEPARATOR */
3984 +              gotspace = TRUE;
3985 +              break;
3986 +              }
3987 +            if (gotspace == (ctype == OP_NOT_VSPACE)) break;
3988 +            eptr += len;
3989 +            }
3990 +          break;
3991 +
3992 +          case OP_NOT_DIGIT:
3993 +          for (i = min; i < max; i++)
3994 +            {
3995 +            int len = 1;
3996 +            if (eptr >= md->end_subject) break;
3997 +            GETCHARLEN(c, eptr, len);
3998 +            if (c < 256 && (md->ctypes[c] & ctype_digit) != 0) break;
3999 +            eptr+= len;
4000 +            }
4001 +          break;
4002 +
4003 +          case OP_DIGIT:
4004 +          for (i = min; i < max; i++)
4005 +            {
4006 +            int len = 1;
4007 +            if (eptr >= md->end_subject) break;
4008 +            GETCHARLEN(c, eptr, len);
4009 +            if (c >= 256 ||(md->ctypes[c] & ctype_digit) == 0) break;
4010 +            eptr+= len;
4011 +            }
4012 +          break;
4013 +
4014 +          case OP_NOT_WHITESPACE:
4015 +          for (i = min; i < max; i++)
4016 +            {
4017 +            int len = 1;
4018 +            if (eptr >= md->end_subject) break;
4019 +            GETCHARLEN(c, eptr, len);
4020 +            if (c < 256 && (md->ctypes[c] & ctype_space) != 0) break;
4021 +            eptr+= len;
4022 +            }
4023 +          break;
4024 +
4025 +          case OP_WHITESPACE:
4026 +          for (i = min; i < max; i++)
4027 +            {
4028 +            int len = 1;
4029 +            if (eptr >= md->end_subject) break;
4030 +            GETCHARLEN(c, eptr, len);
4031 +            if (c >= 256 ||(md->ctypes[c] & ctype_space) == 0) break;
4032 +            eptr+= len;
4033 +            }
4034 +          break;
4035 +
4036 +          case OP_NOT_WORDCHAR:
4037 +          for (i = min; i < max; i++)
4038 +            {
4039 +            int len = 1;
4040 +            if (eptr >= md->end_subject) break;
4041 +            GETCHARLEN(c, eptr, len);
4042 +            if (c < 256 && (md->ctypes[c] & ctype_word) != 0) break;
4043 +            eptr+= len;
4044 +            }
4045 +          break;
4046 +
4047 +          case OP_WORDCHAR:
4048 +          for (i = min; i < max; i++)
4049 +            {
4050 +            int len = 1;
4051 +            if (eptr >= md->end_subject) break;
4052 +            GETCHARLEN(c, eptr, len);
4053 +            if (c >= 256 || (md->ctypes[c] & ctype_word) == 0) break;
4054 +            eptr+= len;
4055 +            }
4056 +          break;
4057 +
4058 +          default:
4059 +          RRETURN(PCRE_ERROR_INTERNAL);
4060 +          }
4061 +
4062 +        /* eptr is now past the end of the maximum run */
4063 +
4064 +        if (possessive) continue;
4065 +        for(;;)
4066 +          {
4067 +          RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM46);
4068 +          if (rrc != MATCH_NOMATCH) RRETURN(rrc);
4069 +          if (eptr-- == pp) break;        /* Stop if tried at original pos */
4070 +          BACKCHAR(eptr);
4071 +          }
4072 +        }
4073 +      else
4074 + #endif  /* SUPPORT_UTF8 */
4075 +
4076 +      /* Not UTF-8 mode */
4077 +        {
4078 +        switch(ctype)
4079 +          {
4080 +          case OP_ANY:
4081 +          for (i = min; i < max; i++)
4082 +            {
4083 +            if (eptr >= md->end_subject || IS_NEWLINE(eptr)) break;
4084 +            eptr++;
4085 +            }
4086 +          break;
4087 +
4088 +          case OP_ALLANY:
4089            case OP_ANYBYTE:
4090            c = max - min;
4091 <          if (c > md->end_subject - eptr) c = md->end_subject - eptr;
4091 >          if (c > (unsigned int)(md->end_subject - eptr))
4092 >            c = md->end_subject - eptr;
4093            eptr += c;
4094            break;
4095  
4096 +          case OP_ANYNL:
4097 +          for (i = min; i < max; i++)
4098 +            {
4099 +            if (eptr >= md->end_subject) break;
4100 +            c = *eptr;
4101 +            if (c == 0x000d)
4102 +              {
4103 +              if (++eptr >= md->end_subject) break;
4104 +              if (*eptr == 0x000a) eptr++;
4105 +              }
4106 +            else
4107 +              {
4108 +              if (c != 0x000a &&
4109 +                  (md->bsr_anycrlf ||
4110 +                    (c != 0x000b && c != 0x000c && c != 0x0085)))
4111 +                break;
4112 +              eptr++;
4113 +              }
4114 +            }
4115 +          break;
4116 +
4117 +          case OP_NOT_HSPACE:
4118 +          for (i = min; i < max; i++)
4119 +            {
4120 +            if (eptr >= md->end_subject) break;
4121 +            c = *eptr;
4122 +            if (c == 0x09 || c == 0x20 || c == 0xa0) break;
4123 +            eptr++;
4124 +            }
4125 +          break;
4126 +
4127 +          case OP_HSPACE:
4128 +          for (i = min; i < max; i++)
4129 +            {
4130 +            if (eptr >= md->end_subject) break;
4131 +            c = *eptr;
4132 +            if (c != 0x09 && c != 0x20 && c != 0xa0) break;
4133 +            eptr++;
4134 +            }
4135 +          break;
4136 +
4137 +          case OP_NOT_VSPACE:
4138 +          for (i = min; i < max; i++)
4139 +            {
4140 +            if (eptr >= md->end_subject) break;
4141 +            c = *eptr;
4142 +            if (c == 0x0a || c == 0x0b || c == 0x0c || c == 0x0d || c == 0x85)
4143 +              break;
4144 +            eptr++;
4145 +            }
4146 +          break;
4147 +
4148 +          case OP_VSPACE:
4149 +          for (i = min; i < max; i++)
4150 +            {
4151 +            if (eptr >= md->end_subject) break;
4152 +            c = *eptr;
4153 +            if (c != 0x0a && c != 0x0b && c != 0x0c && c != 0x0d && c != 0x85)
4154 +              break;
4155 +            eptr++;
4156 +            }
4157 +          break;
4158 +
4159            case OP_NOT_DIGIT:
4160            for (i = min; i < max; i++)
4161              {
# Line 2026 | Line 4216 | for (;;)
4216  
4217          /* eptr is now past the end of the maximum run */
4218  
4219 +        if (possessive) continue;
4220          while (eptr >= pp)
4221            {
4222 <          RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);
4222 >          RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM47);
4223            eptr--;
4224            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
4225            }
# Line 2040 | Line 4231 | for (;;)
4231        }
4232      /* Control never gets here */
4233  
4234 <    /* There's been some horrible disaster. Since all codes > OP_BRA are
4235 <    for capturing brackets, and there shouldn't be any gaps between 0 and
2045 <    OP_BRA, arrival here can only mean there is something seriously wrong
2046 <    in the code above or the OP_xxx definitions. */
4234 >    /* There's been some horrible disaster. Arrival here can only mean there is
4235 >    something seriously wrong in the code above or the OP_xxx definitions. */
4236  
4237      default:
4238      DPRINTF(("Unknown opcode %d\n", *ecode));
4239 <    RRETURN(PCRE_ERROR_UNKNOWN_NODE);
4239 >    RRETURN(PCRE_ERROR_UNKNOWN_OPCODE);
4240      }
4241  
4242    /* Do not stick any code in here without much thought; it is assumed
# Line 2056 | Line 4245 | for (;;)
4245  
4246    }             /* End of main loop */
4247   /* Control never reaches here */
4248 +
4249 +
4250 + /* When compiling to use the heap rather than the stack for recursive calls to
4251 + match(), the RRETURN() macro jumps here. The number that is saved in
4252 + frame->Xwhere indicates which label we actually want to return to. */
4253 +
4254 + #ifdef NO_RECURSE
4255 + #define LBL(val) case val: goto L_RM##val;
4256 + HEAP_RETURN:
4257 + switch (frame->Xwhere)
4258 +  {
4259 +  LBL( 1) LBL( 2) LBL( 3) LBL( 4) LBL( 5) LBL( 6) LBL( 7) LBL( 8)
4260 +  LBL( 9) LBL(10) LBL(11) LBL(12) LBL(13) LBL(14) LBL(15) LBL(17)
4261 +  LBL(19) LBL(24) LBL(25) LBL(26) LBL(27) LBL(29) LBL(31) LBL(33)
4262 +  LBL(35) LBL(43) LBL(47) LBL(48) LBL(49) LBL(50) LBL(51) LBL(52)
4263 +  LBL(53) LBL(54)
4264 + #ifdef SUPPORT_UTF8
4265 +  LBL(16) LBL(18) LBL(20) LBL(21) LBL(22) LBL(23) LBL(28) LBL(30)
4266 +  LBL(32) LBL(34) LBL(42) LBL(46)
4267 + #ifdef SUPPORT_UCP
4268 +  LBL(36) LBL(37) LBL(38) LBL(39) LBL(40) LBL(41) LBL(44) LBL(45)
4269 + #endif  /* SUPPORT_UCP */
4270 + #endif  /* SUPPORT_UTF8 */
4271 +  default:
4272 +  DPRINTF(("jump error in pcre match: label %d non-existent\n", frame->Xwhere));
4273 +  return PCRE_ERROR_INTERNAL;
4274 +  }
4275 + #undef LBL
4276 + #endif  /* NO_RECURSE */
4277   }
4278  
4279  
# Line 2068 | Line 4286 | Undefine all the macros that were define
4286   #ifdef NO_RECURSE
4287   #undef eptr
4288   #undef ecode
4289 + #undef mstart
4290   #undef offset_top
4291   #undef ims
4292   #undef eptrb
# Line 2085 | Line 4304 | Undefine all the macros that were define
4304  
4305   #undef cur_is_word
4306   #undef condition
2088 #undef minimize
4307   #undef prev_is_word
4308  
4309   #undef original_ims
# Line 2141 | Line 4359 | Returns:          > 0 => success; value
4359                   < -1 => some kind of unexpected problem
4360   */
4361  
4362 < EXPORT int
4362 > PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
4363   pcre_exec(const pcre *argument_re, const pcre_extra *extra_data,
4364 <  const char *subject, int length, int start_offset, int options, int *offsets,
4364 >  PCRE_SPTR subject, int length, int start_offset, int options, int *offsets,
4365    int offsetcount)
4366   {
4367   int rc, resetcount, ocount;
4368   int first_byte = -1;
4369   int req_byte = -1;
4370   int req_byte2 = -1;
4371 < unsigned long int ims = 0;
4371 > int newline;
4372 > unsigned long int ims;
4373   BOOL using_temporary_offsets = FALSE;
4374   BOOL anchored;
4375   BOOL startline;
4376   BOOL firstline;
4377   BOOL first_byte_caseless = FALSE;
4378   BOOL req_byte_caseless = FALSE;
4379 + BOOL utf8;
4380   match_data match_block;
4381 + match_data *md = &match_block;
4382   const uschar *tables;
4383   const uschar *start_bits = NULL;
4384 < const uschar *start_match = (const uschar *)subject + start_offset;
4385 < const uschar *end_subject;
4386 < const uschar *req_byte_ptr = start_match - 1;
4384 > USPTR start_match = (USPTR)subject + start_offset;
4385 > USPTR end_subject;
4386 > USPTR req_byte_ptr = start_match - 1;
4387  
4388   pcre_study_data internal_study;
4389   const pcre_study_data *study;
# Line 2182 | Line 4403 | if (offsetcount < 0) return PCRE_ERROR_B
4403   the default values. */
4404  
4405   study = NULL;
4406 < match_block.match_limit = MATCH_LIMIT;
4407 < match_block.callout_data = NULL;
4406 > md->match_limit = MATCH_LIMIT;
4407 > md->match_limit_recursion = MATCH_LIMIT_RECURSION;
4408 > md->callout_data = NULL;
4409  
4410   /* The table pointer is always in native byte order. */
4411  
# Line 2195 | Line 4417 | if (extra_data != NULL)
4417    if ((flags & PCRE_EXTRA_STUDY_DATA) != 0)
4418      study = (const pcre_study_data *)extra_data->study_data;
4419    if ((flags & PCRE_EXTRA_MATCH_LIMIT) != 0)
4420 <    match_block.match_limit = extra_data->match_limit;
4420 >    md->match_limit = extra_data->match_limit;
4421 >  if ((flags & PCRE_EXTRA_MATCH_LIMIT_RECURSION) != 0)
4422 >    md->match_limit_recursion = extra_data->match_limit_recursion;
4423    if ((flags & PCRE_EXTRA_CALLOUT_DATA) != 0)
4424 <    match_block.callout_data = extra_data->callout_data;
4424 >    md->callout_data = extra_data->callout_data;
4425    if ((flags & PCRE_EXTRA_TABLES) != 0) tables = extra_data->tables;
4426    }
4427  
# Line 2222 | Line 4446 | if (re->magic_number != MAGIC_NUMBER)
4446   /* Set up other data */
4447  
4448   anchored = ((re->options | options) & PCRE_ANCHORED) != 0;
4449 < startline = (re->options & PCRE_STARTLINE) != 0;
4449 > startline = (re->flags & PCRE_STARTLINE) != 0;
4450   firstline = (re->options & PCRE_FIRSTLINE) != 0;
4451  
4452   /* The code starts after the real_pcre block and the capture name table. */
4453  
4454 < match_block.start_code = (const uschar *)external_re + re->name_table_offset +
4454 > md->start_code = (const uschar *)external_re + re->name_table_offset +
4455    re->name_count * re->name_entry_size;
4456  
4457 < match_block.start_subject = (const uschar *)subject;
4458 < match_block.start_offset = start_offset;
4459 < match_block.end_subject = match_block.start_subject + length;
4460 < end_subject = match_block.end_subject;
4461 <
4462 < match_block.endonly = (re->options & PCRE_DOLLAR_ENDONLY) != 0;
4463 < match_block.utf8 = (re->options & PCRE_UTF8) != 0;
4464 <
4465 < match_block.notbol = (options & PCRE_NOTBOL) != 0;
4466 < match_block.noteol = (options & PCRE_NOTEOL) != 0;
4467 < match_block.notempty = (options & PCRE_NOTEMPTY) != 0;
4468 < match_block.partial = (options & PCRE_PARTIAL) != 0;
4469 < match_block.hitend = FALSE;
4457 > md->start_subject = (USPTR)subject;
4458 > md->start_offset = start_offset;
4459 > md->end_subject = md->start_subject + length;
4460 > end_subject = md->end_subject;
4461 >
4462 > md->endonly = (re->options & PCRE_DOLLAR_ENDONLY) != 0;
4463 > utf8 = md->utf8 = (re->options & PCRE_UTF8) != 0;
4464 > md->jscript_compat = (re->options & PCRE_JAVASCRIPT_COMPAT) != 0;
4465 >
4466 > md->notbol = (options & PCRE_NOTBOL) != 0;
4467 > md->noteol = (options & PCRE_NOTEOL) != 0;
4468 > md->notempty = (options & PCRE_NOTEMPTY) != 0;
4469 > md->partial = (options & PCRE_PARTIAL) != 0;
4470 > md->hitend = FALSE;
4471 >
4472 > md->recursive = NULL;                   /* No recursion at top level */
4473 >
4474 > md->lcc = tables + lcc_offset;
4475 > md->ctypes = tables + ctypes_offset;
4476 >
4477 > /* Handle different \R options. */
4478 >
4479 > switch (options & (PCRE_BSR_ANYCRLF|PCRE_BSR_UNICODE))
4480 >  {
4481 >  case 0:
4482 >  if ((re->options & (PCRE_BSR_ANYCRLF|PCRE_BSR_UNICODE)) != 0)
4483 >    md->bsr_anycrlf = (re->options & PCRE_BSR_ANYCRLF) != 0;
4484 >  else
4485 > #ifdef BSR_ANYCRLF
4486 >  md->bsr_anycrlf = TRUE;
4487 > #else
4488 >  md->bsr_anycrlf = FALSE;
4489 > #endif
4490 >  break;
4491 >
4492 >  case PCRE_BSR_ANYCRLF:
4493 >  md->bsr_anycrlf = TRUE;
4494 >  break;
4495 >
4496 >  case PCRE_BSR_UNICODE:
4497 >  md->bsr_anycrlf = FALSE;
4498 >  break;
4499  
4500 < match_block.recursive = NULL;                   /* No recursion at top level */
4500 >  default: return PCRE_ERROR_BADNEWLINE;
4501 >  }
4502  
4503 < match_block.lcc = tables + lcc_offset;
4504 < match_block.ctypes = tables + ctypes_offset;
4503 > /* Handle different types of newline. The three bits give eight cases. If
4504 > nothing is set at run time, whatever was used at compile time applies. */
4505 >
4506 > switch ((((options & PCRE_NEWLINE_BITS) == 0)? re->options :
4507 >        (pcre_uint32)options) & PCRE_NEWLINE_BITS)
4508 >  {
4509 >  case 0: newline = NEWLINE; break;   /* Compile-time default */
4510 >  case PCRE_NEWLINE_CR: newline = CHAR_CR; break;
4511 >  case PCRE_NEWLINE_LF: newline = CHAR_NL; break;
4512 >  case PCRE_NEWLINE_CR+
4513 >       PCRE_NEWLINE_LF: newline = (CHAR_CR << 8) | CHAR_NL; break;
4514 >  case PCRE_NEWLINE_ANY: newline = -1; break;
4515 >  case PCRE_NEWLINE_ANYCRLF: newline = -2; break;
4516 >  default: return PCRE_ERROR_BADNEWLINE;
4517 >  }
4518 >
4519 > if (newline == -2)
4520 >  {
4521 >  md->nltype = NLTYPE_ANYCRLF;
4522 >  }
4523 > else if (newline < 0)
4524 >  {
4525 >  md->nltype = NLTYPE_ANY;
4526 >  }
4527 > else
4528 >  {
4529 >  md->nltype = NLTYPE_FIXED;
4530 >  if (newline > 255)
4531 >    {
4532 >    md->nllen = 2;
4533 >    md->nl[0] = (newline >> 8) & 255;
4534 >    md->nl[1] = newline & 255;
4535 >    }
4536 >  else
4537 >    {
4538 >    md->nllen = 1;
4539 >    md->nl[0] = newline;
4540 >    }
4541 >  }
4542  
4543   /* Partial matching is supported only for a restricted set of regexes at the
4544   moment. */
4545  
4546 < if (match_block.partial && (re->options & PCRE_NOPARTIAL) != 0)
4546 > if (md->partial && (re->flags & PCRE_NOPARTIAL) != 0)
4547    return PCRE_ERROR_BADPARTIAL;
4548  
4549 + /* Check a UTF-8 string if required. Unfortunately there's no way of passing
4550 + back the character offset. */
4551 +
4552 + #ifdef SUPPORT_UTF8
4553 + if (utf8 && (options & PCRE_NO_UTF8_CHECK) == 0)
4554 +  {
4555 +  if (_pcre_valid_utf8((USPTR)subject, length) >= 0)
4556 +    return PCRE_ERROR_BADUTF8;
4557 +  if (start_offset > 0 && start_offset < length)
4558 +    {
4559 +    int tb = ((USPTR)subject)[start_offset];
4560 +    if (tb > 127)
4561 +      {
4562 +      tb &= 0xc0;
4563 +      if (tb != 0 && tb != 0xc0) return PCRE_ERROR_BADUTF8_OFFSET;
4564 +      }
4565 +    }
4566 +  }
4567 + #endif
4568 +
4569   /* The ims options can vary during the matching as a result of the presence
4570   of (?ims) items in the pattern. They are kept in a local variable so that
4571   restoring at the exit of a group is easy. */
# Line 2271 | Line 4582 | ocount = offsetcount - (offsetcount % 3)
4582   if (re->top_backref > 0 && re->top_backref >= ocount/3)
4583    {
4584    ocount = re->top_backref * 3 + 3;
4585 <  match_block.offset_vector = (int *)(pcre_malloc)(ocount * sizeof(int));
4586 <  if (match_block.offset_vector == NULL) return PCRE_ERROR_NOMEMORY;
4585 >  md->offset_vector = (int *)(pcre_malloc)(ocount * sizeof(int));
4586 >  if (md->offset_vector == NULL) return PCRE_ERROR_NOMEMORY;
4587    using_temporary_offsets = TRUE;
4588    DPRINTF(("Got memory to hold back references\n"));
4589    }
4590 < else match_block.offset_vector = offsets;
4590 > else md->offset_vector = offsets;
4591  
4592 < match_block.offset_end = ocount;
4593 < match_block.offset_max = (2*ocount)/3;
4594 < match_block.offset_overflow = FALSE;
4595 < match_block.capture_last = -1;
4592 > md->offset_end = ocount;
4593 > md->offset_max = (2*ocount)/3;
4594 > md->offset_overflow = FALSE;
4595 > md->capture_last = -1;
4596  
4597   /* Compute the minimum number of offsets that we need to reset each time. Doing
4598   this makes a huge difference to execution time when there aren't many brackets
# Line 2294 | Line 4605 | if (resetcount > offsetcount) resetcount
4605   never be used unless previously set, but they get saved and restored, and so we
4606   initialize them to avoid reading uninitialized locations. */
4607  
4608 < if (match_block.offset_vector != NULL)
4608 > if (md->offset_vector != NULL)
4609    {
4610 <  register int *iptr = match_block.offset_vector + ocount;
4610 >  register int *iptr = md->offset_vector + ocount;
4611    register int *iend = iptr - resetcount/2 + 1;
4612    while (--iptr >= iend) *iptr = -1;
4613    }
# Line 2309 | Line 4620 | studied, there may be a bitmap of possib
4620  
4621   if (!anchored)
4622    {
4623 <  if ((re->options & PCRE_FIRSTSET) != 0)
4623 >  if ((re->flags & PCRE_FIRSTSET) != 0)
4624      {
4625      first_byte = re->first_byte & 255;
4626      if ((first_byte_caseless = ((re->first_byte & REQ_CASELESS) != 0)) == TRUE)
4627 <      first_byte = match_block.lcc[first_byte];
4627 >      first_byte = md->lcc[first_byte];
4628      }
4629    else
4630      if (!startline && study != NULL &&
# Line 2324 | Line 4635 | if (!anchored)
4635   /* For anchored or unanchored matches, there may be a "last known required
4636   character" set. */
4637  
4638 < if ((re->options & PCRE_REQCHSET) != 0)
4638 > if ((re->flags & PCRE_REQCHSET) != 0)
4639    {
4640    req_byte = re->req_byte & 255;
4641    req_byte_caseless = (re->req_byte & REQ_CASELESS) != 0;
4642    req_byte2 = (tables + fcc_offset)[req_byte];  /* case flipped */
4643    }
4644  
4645 +
4646 + /* ==========================================================================*/
4647 +
4648   /* Loop for handling unanchored repeated matching attempts; for anchored regexs
4649   the loop runs just once. */
4650  
4651 < do
4651 > for(;;)
4652    {
4653 <  const uschar *save_end_subject = end_subject;
4653 >  USPTR save_end_subject = end_subject;
4654 >  USPTR new_start_match;
4655  
4656    /* Reset the maximum number of extractions we might see. */
4657  
4658 <  if (match_block.offset_vector != NULL)
4658 >  if (md->offset_vector != NULL)
4659      {
4660 <    register int *iptr = match_block.offset_vector;
4660 >    register int *iptr = md->offset_vector;
4661      register int *iend = iptr + resetcount;
4662      while (iptr < iend) *iptr++ = -1;
4663      }
4664  
4665 <  /* Advance to a unique first char if possible. If firstline is TRUE, the
4666 <  start of the match is constrained to the first line of a multiline string.
4667 <  Implement this by temporarily adjusting end_subject so that we stop scanning
4668 <  at a newline. If the match fails at the newline, later code breaks this loop.
4669 <  */
4665 >  /* If firstline is TRUE, the start of the match is constrained to the first
4666 >  line of a multiline string. That is, the match must be before or at the first
4667 >  newline. Implement this by temporarily adjusting end_subject so that we stop
4668 >  scanning at a newline. If the match fails at the newline, later code breaks
4669 >  this loop. */
4670  
4671    if (firstline)
4672      {
4673 <    const uschar *t = start_match;
4674 <    while (t < save_end_subject && *t != '\n') t++;
4673 >    USPTR t = start_match;
4674 > #ifdef SUPPORT_UTF8
4675 >    if (utf8)
4676 >      {
4677 >      while (t < md->end_subject && !IS_NEWLINE(t))
4678 >        {
4679 >        t++;
4680 >        while (t < end_subject && (*t & 0xc0) == 0x80) t++;
4681 >        }
4682 >      }
4683 >    else
4684 > #endif
4685 >    while (t < md->end_subject && !IS_NEWLINE(t)) t++;
4686      end_subject = t;
4687      }
4688  
4689 <  /* Now test for a unique first byte */
4689 >  /* There are some optimizations that avoid running the match if a known
4690 >  starting point is not found, or if a known later character is not present.
4691 >  However, there is an option that disables these, for testing and for ensuring
4692 >  that all callouts do actually occur. */
4693  
4694 <  if (first_byte >= 0)
4694 >  if ((options & PCRE_NO_START_OPTIMIZE) == 0)
4695      {
4696 <    if (first_byte_caseless)
4697 <      while (start_match < end_subject &&
4698 <             match_block.lcc[*start_match] != first_byte)
4699 <        start_match++;
4700 <    else
4701 <      while (start_match < end_subject && *start_match != first_byte)
4702 <        start_match++;
4703 <    }
4696 >    /* Advance to a unique first byte if there is one. */
4697 >
4698 >    if (first_byte >= 0)
4699 >      {
4700 >      if (first_byte_caseless)
4701 >        while (start_match < end_subject && md->lcc[*start_match] != first_byte)
4702 >          start_match++;
4703 >      else
4704 >        while (start_match < end_subject && *start_match != first_byte)
4705 >          start_match++;
4706 >      }
4707  
4708 <  /* Or to just after \n for a multiline match if possible */
4708 >    /* Or to just after a linebreak for a multiline match */
4709  
4710 <  else if (startline)
2379 <    {
2380 <    if (start_match > match_block.start_subject + start_offset)
4710 >    else if (startline)
4711        {
4712 <      while (start_match < end_subject && start_match[-1] != NEWLINE)
4713 <        start_match++;
4712 >      if (start_match > md->start_subject + start_offset)
4713 >        {
4714 > #ifdef SUPPORT_UTF8
4715 >        if (utf8)
4716 >          {
4717 >          while (start_match < end_subject && !WAS_NEWLINE(start_match))
4718 >            {
4719 >            start_match++;
4720 >            while(start_match < end_subject && (*start_match & 0xc0) == 0x80)
4721 >              start_match++;
4722 >            }
4723 >          }
4724 >        else
4725 > #endif
4726 >        while (start_match < end_subject && !WAS_NEWLINE(start_match))
4727 >          start_match++;
4728 >
4729 >        /* If we have just passed a CR and the newline option is ANY or ANYCRLF,
4730 >        and we are now at a LF, advance the match position by one more character.
4731 >        */
4732 >
4733 >        if (start_match[-1] == CHAR_CR &&
4734 >             (md->nltype == NLTYPE_ANY || md->nltype == NLTYPE_ANYCRLF) &&
4735 >             start_match < end_subject &&
4736 >             *start_match == CHAR_NL)
4737 >          start_match++;
4738 >        }
4739        }
2385    }
4740  
4741 <  /* Or to a non-unique first char after study */
4741 >    /* Or to a non-unique first byte after study */
4742  
4743 <  else if (start_bits != NULL)
2390 <    {
2391 <    while (start_match < end_subject)
4743 >    else if (start_bits != NULL)
4744        {
4745 <      register unsigned int c = *start_match;
4746 <      if ((start_bits[c/8] & (1 << (c&7))) == 0) start_match++; else break;
4745 >      while (start_match < end_subject)
4746 >        {
4747 >        register unsigned int c = *start_match;
4748 >        if ((start_bits[c/8] & (1 << (c&7))) == 0) start_match++;
4749 >          else break;
4750 >        }
4751        }
4752 <    }
4752 >    }   /* Starting optimizations */
4753  
4754    /* Restore fudged end_subject */
4755  
4756    end_subject = save_end_subject;
4757  
2402 #ifdef DEBUG  /* Sigh. Some compilers never learn. */
2403  printf(">>>> Match against: ");
2404  pchars(start_match, end_subject - start_match, TRUE, &match_block);
2405  printf("\n");
2406 #endif
2407
2408  /* If req_byte is set, we know that that character must appear in the subject
2409  for the match to succeed. If the first character is set, req_byte must be
2410  later in the subject; otherwise the test starts at the match point. This
2411  optimization can save a huge amount of backtracking in patterns with nested
2412  unlimited repeats that aren't going to match. Writing separate code for
2413  cased/caseless versions makes it go faster, as does using an autoincrement
2414  and backing off on a match.
2415
2416  HOWEVER: when the subject string is very, very long, searching to its end can
2417  take a long time, and give bad performance on quite ordinary patterns. This
2418  showed up when somebody was matching /^C/ on a 32-megabyte string... so we
2419  don't do this when the string is sufficiently long.
4758  
4759 <  ALSO: this processing is disabled when partial matching is requested.
4760 <  */
4759 >  /* If req_byte is set, we know that that character must appear in the
4760 >  subject for the match to succeed. If the first character is set, req_byte
4761 >  must be later in the subject; otherwise the test starts at the match point.
4762 >  This optimization can save a huge amount of backtracking in patterns with
4763 >  nested unlimited repeats that aren't going to match. Writing separate code
4764 >  for cased/caseless versions makes it go faster, as does using an
4765 >  autoincrement and backing off on a match.
4766 >
4767 >  HOWEVER: when the subject string is very, very long, searching to its end
4768 >  can take a long time, and give bad performance on quite ordinary patterns.
4769 >  This showed up when somebody was matching something like /^\d+C/ on a
4770 >  32-megabyte string... so we don't do this when the string is sufficiently
4771 >  long.
4772 >
4773 >  ALSO: this processing is disabled when partial matching is requested, or if
4774 >  disabling is explicitly requested. */
4775  
4776 <  if (req_byte >= 0 &&
4776 >  if ((options & PCRE_NO_START_OPTIMIZE) == 0 &&
4777 >      req_byte >= 0 &&
4778        end_subject - start_match < REQ_BYTE_MAX &&
4779 <      !match_block.partial)
4779 >      !md->partial)
4780      {
4781 <    register const uschar *p = start_match + ((first_byte >= 0)? 1 : 0);
4781 >    register USPTR p = start_match + ((first_byte >= 0)? 1 : 0);
4782  
4783      /* We don't need to repeat the search if we haven't yet reached the
4784      place we found it at last time. */
# Line 2448 | Line 4801 | do
4801            }
4802          }
4803  
4804 <      /* If we can't find the required character, break the matching loop */
4804 >      /* If we can't find the required character, break the matching loop,
4805 >      forcing a match failure. */
4806  
4807 <      if (p >= end_subject) break;
4807 >      if (p >= end_subject)
4808 >        {
4809 >        rc = MATCH_NOMATCH;
4810 >        break;
4811 >        }
4812  
4813        /* If we have found the required character, save the point where we
4814        found it, so that we don't search again next time round the loop if
# Line 2460 | Line 4818 | do
4818        }
4819      }
4820  
4821 <  /* When a match occurs, substrings will be set for all internal extractions;
2464 <  we just need to set up the whole thing as substring 0 before returning. If
2465 <  there were too many extractions, set the return code to zero. In the case
2466 <  where we had to get some local store to hold offsets for backreferences, copy
2467 <  those back references that we can. In this case there need not be overflow
2468 <  if certain parts of the pattern were not used. */
2469 <
2470 <  match_block.start_match = start_match;
2471 <  match_block.match_call_count = 0;
2472 <
2473 <  rc = match(start_match, match_block.start_code, 2, &match_block, ims, NULL,
2474 <    match_isgroup);
2475 <
2476 <  /* When the result is no match, if the subject's first character was a
2477 <  newline and the PCRE_FIRSTLINE option is set, break (which will return
2478 <  PCRE_ERROR_NOMATCH). The option requests that a match occur before the first
2479 <  newline in the subject. Otherwise, advance the pointer to the next character
2480 <  and continue - but the continuation will actually happen only when the
2481 <  pattern is not anchored. */
4821 >  /* OK, we can now run the match. */
4822  
4823 <  if (rc == MATCH_NOMATCH)
4824 <    {
4825 <    if (firstline && *start_match == NEWLINE) break;
2486 <    start_match++;
2487 <    continue;
2488 <    }
4823 >  md->start_match_ptr = start_match;
4824 >  md->match_call_count = 0;
4825 >  rc = match(start_match, md->start_code, start_match, 2, md, ims, NULL, 0, 0);
4826  
4827 <  if (rc != MATCH_MATCH)
4827 >  switch(rc)
4828      {
4829 <    DPRINTF((">>>> error: returning %d\n", rc));
4830 <    return rc;
4829 >    /* NOMATCH and PRUNE advance by one character. THEN at this level acts
4830 >    exactly like PRUNE. */
4831 >
4832 >    case MATCH_NOMATCH:
4833 >    case MATCH_PRUNE:
4834 >    case MATCH_THEN:
4835 >    new_start_match = start_match + 1;
4836 > #ifdef SUPPORT_UTF8
4837 >    if (utf8)
4838 >      while(new_start_match < end_subject && (*new_start_match & 0xc0) == 0x80)
4839 >        new_start_match++;
4840 > #endif
4841 >    break;
4842 >
4843 >    /* SKIP passes back the next starting point explicitly. */
4844 >
4845 >    case MATCH_SKIP:
4846 >    new_start_match = md->start_match_ptr;
4847 >    break;
4848 >
4849 >    /* COMMIT disables the bumpalong, but otherwise behaves as NOMATCH. */
4850 >
4851 >    case MATCH_COMMIT:
4852 >    rc = MATCH_NOMATCH;
4853 >    goto ENDLOOP;
4854 >
4855 >    /* Any other return is some kind of error. */
4856 >
4857 >    default:
4858 >    goto ENDLOOP;
4859      }
4860  
4861 <  /* We have a match! Copy the offset information from temporary store if
4862 <  necessary */
4861 >  /* Control reaches here for the various types of "no match at this point"
4862 >  result. Reset the code to MATCH_NOMATCH for subsequent checking. */
4863 >
4864 >  rc = MATCH_NOMATCH;
4865 >
4866 >  /* If PCRE_FIRSTLINE is set, the match must happen before or at the first
4867 >  newline in the subject (though it may continue over the newline). Therefore,
4868 >  if we have just failed to match, starting at a newline, do not continue. */
4869 >
4870 >  if (firstline && IS_NEWLINE(start_match)) break;
4871 >
4872 >  /* Advance to new matching position */
4873 >
4874 >  start_match = new_start_match;
4875 >
4876 >  /* Break the loop if the pattern is anchored or if we have passed the end of
4877 >  the subject. */
4878  
4879 +  if (anchored || start_match > end_subject) break;
4880 +
4881 +  /* If we have just passed a CR and we are now at a LF, and the pattern does
4882 +  not contain any explicit matches for \r or \n, and the newline option is CRLF
4883 +  or ANY or ANYCRLF, advance the match position by one more character. */
4884 +
4885 +  if (start_match[-1] == CHAR_CR &&
4886 +      start_match < end_subject &&
4887 +      *start_match == CHAR_NL &&
4888 +      (re->flags & PCRE_HASCRORLF) == 0 &&
4889 +        (md->nltype == NLTYPE_ANY ||
4890 +         md->nltype == NLTYPE_ANYCRLF ||
4891 +         md->nllen == 2))
4892 +    start_match++;
4893 +
4894 +  }   /* End of for(;;) "bumpalong" loop */
4895 +
4896 + /* ==========================================================================*/
4897 +
4898 + /* We reach here when rc is not MATCH_NOMATCH, or if one of the stopping
4899 + conditions is true:
4900 +
4901 + (1) The pattern is anchored or the match was failed by (*COMMIT);
4902 +
4903 + (2) We are past the end of the subject;
4904 +
4905 + (3) PCRE_FIRSTLINE is set and we have failed to match at a newline, because
4906 +    this option requests that a match occur at or before the first newline in
4907 +    the subject.
4908 +
4909 + When we have a match and the offset vector is big enough to deal with any
4910 + backreferences, captured substring offsets will already be set up. In the case
4911 + where we had to get some local store to hold offsets for backreference
4912 + processing, copy those that we can. In this case there need not be overflow if
4913 + certain parts of the pattern were not used, even though there are more
4914 + capturing parentheses than vector slots. */
4915 +
4916 + ENDLOOP:
4917 +
4918 + if (rc == MATCH_MATCH)
4919 +  {
4920    if (using_temporary_offsets)
4921      {
4922      if (offsetcount >= 4)
4923        {
4924 <      memcpy(offsets + 2, match_block.offset_vector + 2,
4924 >      memcpy(offsets + 2, md->offset_vector + 2,
4925          (offsetcount - 2) * sizeof(int));
4926        DPRINTF(("Copied offsets from temporary memory\n"));
4927        }
4928 <    if (match_block.end_offset_top > offsetcount)
2508 <      match_block.offset_overflow = TRUE;
2509 <
4928 >    if (md->end_offset_top > offsetcount) md->offset_overflow = TRUE;
4929      DPRINTF(("Freeing temporary memory\n"));
4930 <    (pcre_free)(match_block.offset_vector);
4930 >    (pcre_free)(md->offset_vector);
4931      }
4932  
4933 <  rc = match_block.offset_overflow? 0 : match_block.end_offset_top/2;
4933 >  /* Set the return code to the number of captured strings, or 0 if there are
4934 >  too many to fit into the vector. */
4935 >
4936 >  rc = md->offset_overflow? 0 : md->end_offset_top/2;
4937 >
4938 >  /* If there is space, set up the whole thing as substring 0. The value of
4939 >  md->start_match_ptr might be modified if \K was encountered on the success
4940 >  matching path. */
4941  
4942    if (offsetcount < 2) rc = 0; else
4943      {
4944 <    offsets[0] = start_match - match_block.start_subject;
4945 <    offsets[1] = match_block.end_match_ptr - match_block.start_subject;
4944 >    offsets[0] = md->start_match_ptr - md->start_subject;
4945 >    offsets[1] = md->end_match_ptr - md->start_subject;
4946      }
4947  
4948    DPRINTF((">>>> returning %d\n", rc));
4949    return rc;
4950    }
4951  
4952 < /* This "while" is the end of the "do" above */
4953 <
2528 < while (!anchored && start_match <= end_subject);
4952 > /* Control gets here if there has been an error, or if the overall match
4953 > attempt has failed at all permitted starting positions. */
4954  
4955   if (using_temporary_offsets)
4956    {
4957    DPRINTF(("Freeing temporary memory\n"));
4958 <  (pcre_free)(match_block.offset_vector);
4958 >  (pcre_free)(md->offset_vector);
4959    }
4960  
4961 < if (match_block.partial && match_block.hitend)
4961 > if (rc != MATCH_NOMATCH)
4962 >  {
4963 >  DPRINTF((">>>> error: returning %d\n", rc));
4964 >  return rc;
4965 >  }
4966 > else if (md->partial && md->hitend)
4967    {
4968    DPRINTF((">>>> returning PCRE_ERROR_PARTIAL\n"));
4969    return PCRE_ERROR_PARTIAL;

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines