/[pcre]/code/trunk/pcre_exec.c
ViewVC logotype

Diff of /code/trunk/pcre_exec.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 210 by ph10, Wed Aug 8 14:24:50 2007 UTC revision 545 by ph10, Wed Jun 16 10:51:15 2010 UTC
# Line 6  Line 6 
6  and semantics are as close as possible to those of the Perl 5 language.  and semantics are as close as possible to those of the Perl 5 language.
7    
8                         Written by Philip Hazel                         Written by Philip Hazel
9             Copyright (c) 1997-2007 University of Cambridge             Copyright (c) 1997-2010 University of Cambridge
10    
11  -----------------------------------------------------------------------------  -----------------------------------------------------------------------------
12  Redistribution and use in source and binary forms, with or without  Redistribution and use in source and binary forms, with or without
# Line 43  pattern matching using an NFA algorithm, Line 43  pattern matching using an NFA algorithm,
43  possible. There are also some static supporting functions. */  possible. There are also some static supporting functions. */
44    
45  #ifdef HAVE_CONFIG_H  #ifdef HAVE_CONFIG_H
46  #include <config.h>  #include "config.h"
47  #endif  #endif
48    
49  #define NLBLOCK md             /* Block containing newline information */  #define NLBLOCK md             /* Block containing newline information */
# Line 68  defined PCRE_ERROR_xxx codes, which are Line 68  defined PCRE_ERROR_xxx codes, which are
68  #define MATCH_MATCH        1  #define MATCH_MATCH        1
69  #define MATCH_NOMATCH      0  #define MATCH_NOMATCH      0
70    
71  /* Special internal returns from the match() function. Make them sufficiently  /* Special internal returns from the match() function. Make them sufficiently
72  negative to avoid the external error codes. */  negative to avoid the external error codes. */
73    
74  #define MATCH_COMMIT       (-999)  #define MATCH_ACCEPT       (-999)
75  #define MATCH_PRUNE        (-998)  #define MATCH_COMMIT       (-998)
76  #define MATCH_SKIP         (-997)  #define MATCH_PRUNE        (-997)
77  #define MATCH_THEN         (-996)  #define MATCH_SKIP         (-996)
78    #define MATCH_SKIP_ARG     (-995)
79    #define MATCH_THEN         (-994)
80    
81    /* This is a convenience macro for code that occurs many times. */
82    
83    #define MRRETURN(ra) \
84      { \
85      md->mark = markptr; \
86      RRETURN(ra); \
87      }
88    
89  /* Maximum number of ints of offset to save on the stack for recursive calls.  /* Maximum number of ints of offset to save on the stack for recursive calls.
90  If the offset vector is bigger, malloc is used. This should be a multiple of 3,  If the offset vector is bigger, malloc is used. This should be a multiple of 3,
# Line 89  static const char rep_max[] = { 0, 0, 0, Line 99  static const char rep_max[] = { 0, 0, 0,
99    
100    
101    
102  #ifdef DEBUG  #ifdef PCRE_DEBUG
103  /*************************************************  /*************************************************
104  *        Debugging function to print chars       *  *        Debugging function to print chars       *
105  *************************************************/  *************************************************/
# Line 141  match_ref(int offset, register USPTR ept Line 151  match_ref(int offset, register USPTR ept
151  {  {
152  USPTR p = md->start_subject + md->offset_vector[offset];  USPTR p = md->start_subject + md->offset_vector[offset];
153    
154  #ifdef DEBUG  #ifdef PCRE_DEBUG
155  if (eptr >= md->end_subject)  if (eptr >= md->end_subject)
156    printf("matching subject <null>");    printf("matching subject <null>");
157  else  else
# Line 158  printf("\n"); Line 168  printf("\n");
168    
169  if (length > md->end_subject - eptr) return FALSE;  if (length > md->end_subject - eptr) return FALSE;
170    
171  /* Separate the caselesss case for speed */  /* Separate the caseless case for speed. In UTF-8 mode we can only do this
172    properly if Unicode properties are supported. Otherwise, we can check only
173    ASCII characters. */
174    
175  if ((ims & PCRE_CASELESS) != 0)  if ((ims & PCRE_CASELESS) != 0)
176    {    {
177    #ifdef SUPPORT_UTF8
178    #ifdef SUPPORT_UCP
179      if (md->utf8)
180        {
181        USPTR endptr = eptr + length;
182        while (eptr < endptr)
183          {
184          int c, d;
185          GETCHARINC(c, eptr);
186          GETCHARINC(d, p);
187          if (c != d && c != UCD_OTHERCASE(d)) return FALSE;
188          }
189        }
190      else
191    #endif
192    #endif
193    
194      /* The same code works when not in UTF-8 mode and in UTF-8 mode when there
195      is no UCP support. */
196    
197    while (length-- > 0)    while (length-- > 0)
198      if (md->lcc[*p++] != md->lcc[*eptr++]) return FALSE;      { if (md->lcc[*p++] != md->lcc[*eptr++]) return FALSE; }
199    }    }
200    
201    /* In the caseful case, we can just compare the bytes, whether or not we
202    are in UTF-8 mode. */
203    
204  else  else
205    { while (length-- > 0) if (*p++ != *eptr++) return FALSE; }    { while (length-- > 0) if (*p++ != *eptr++) return FALSE; }
206    
# Line 211  variable instead of being passed in the Line 247  variable instead of being passed in the
247  ****************************************************************************  ****************************************************************************
248  ***************************************************************************/  ***************************************************************************/
249    
250    /* Numbers for RMATCH calls. When this list is changed, the code at HEAP_RETURN
251  /* Numbers for RMATCH calls */  below must be updated in sync.  */
252    
253  enum { RM1=1, RM2,  RM3,  RM4,  RM5,  RM6,  RM7,  RM8,  RM9,  RM10,  enum { RM1=1, RM2,  RM3,  RM4,  RM5,  RM6,  RM7,  RM8,  RM9,  RM10,
254         RM11,  RM12, RM13, RM14, RM15, RM16, RM17, RM18, RM19, RM20,         RM11,  RM12, RM13, RM14, RM15, RM16, RM17, RM18, RM19, RM20,
255         RM21,  RM22, RM23, RM24, RM25, RM26, RM27, RM28, RM29, RM30,         RM21,  RM22, RM23, RM24, RM25, RM26, RM27, RM28, RM29, RM30,
256         RM31,  RM32, RM33, RM34, RM35, RM36, RM37, RM38, RM39, RM40,         RM31,  RM32, RM33, RM34, RM35, RM36, RM37, RM38, RM39, RM40,
257         RM41,  RM42, RM43, RM44, RM45, RM46, RM47, RM48, RM49, RM50,         RM41,  RM42, RM43, RM44, RM45, RM46, RM47, RM48, RM49, RM50,
258         RM51,  RM52, RM53 };         RM51,  RM52, RM53, RM54, RM55, RM56, RM57, RM58, RM59, RM60,
259           RM61,  RM62 };
260    
261  /* These versions of the macros use the stack, as normal. There are debugging  /* These versions of the macros use the stack, as normal. There are debugging
262  versions and production versions. Note that the "rw" argument of RMATCH isn't  versions and production versions. Note that the "rw" argument of RMATCH isn't
263  actuall used in this definition. */  actually used in this definition. */
264    
265  #ifndef NO_RECURSE  #ifndef NO_RECURSE
266  #define REGISTER register  #define REGISTER register
267    
268  #ifdef DEBUG  #ifdef PCRE_DEBUG
269  #define RMATCH(ra,rb,rc,rd,re,rf,rg,rw) \  #define RMATCH(ra,rb,rc,rd,re,rf,rg,rw) \
270    { \    { \
271    printf("match() called in line %d\n", __LINE__); \    printf("match() called in line %d\n", __LINE__); \
272    rrc = match(ra,rb,mstart,rc,rd,re,rf,rg,rdepth+1); \    rrc = match(ra,rb,mstart,markptr,rc,rd,re,rf,rg,rdepth+1); \
273    printf("to line %d\n", __LINE__); \    printf("to line %d\n", __LINE__); \
274    }    }
275  #define RRETURN(ra) \  #define RRETURN(ra) \
# Line 243  actuall used in this definition. */ Line 279  actuall used in this definition. */
279    }    }
280  #else  #else
281  #define RMATCH(ra,rb,rc,rd,re,rf,rg,rw) \  #define RMATCH(ra,rb,rc,rd,re,rf,rg,rw) \
282    rrc = match(ra,rb,mstart,rc,rd,re,rf,rg,rdepth+1)    rrc = match(ra,rb,mstart,markptr,rc,rd,re,rf,rg,rdepth+1)
283  #define RRETURN(ra) return ra  #define RRETURN(ra) return ra
284  #endif  #endif
285    
# Line 259  argument of match(), which never changes Line 295  argument of match(), which never changes
295  #define RMATCH(ra,rb,rc,rd,re,rf,rg,rw)\  #define RMATCH(ra,rb,rc,rd,re,rf,rg,rw)\
296    {\    {\
297    heapframe *newframe = (pcre_stack_malloc)(sizeof(heapframe));\    heapframe *newframe = (pcre_stack_malloc)(sizeof(heapframe));\
298      if (newframe == NULL) RRETURN(PCRE_ERROR_NOMEMORY);\
299    frame->Xwhere = rw; \    frame->Xwhere = rw; \
300    newframe->Xeptr = ra;\    newframe->Xeptr = ra;\
301    newframe->Xecode = rb;\    newframe->Xecode = rb;\
302    newframe->Xmstart = mstart;\    newframe->Xmstart = mstart;\
303      newframe->Xmarkptr = markptr;\
304    newframe->Xoffset_top = rc;\    newframe->Xoffset_top = rc;\
305    newframe->Xims = re;\    newframe->Xims = re;\
306    newframe->Xeptrb = rf;\    newframe->Xeptrb = rf;\
# Line 278  argument of match(), which never changes Line 316  argument of match(), which never changes
316    
317  #define RRETURN(ra)\  #define RRETURN(ra)\
318    {\    {\
319    heapframe *newframe = frame;\    heapframe *oldframe = frame;\
320    frame = newframe->Xprevframe;\    frame = oldframe->Xprevframe;\
321    (pcre_stack_free)(newframe);\    (pcre_stack_free)(oldframe);\
322    if (frame != NULL)\    if (frame != NULL)\
323      {\      {\
324      rrc = ra;\      rrc = ra;\
# Line 297  typedef struct heapframe { Line 335  typedef struct heapframe {
335    
336    /* Function arguments that may change */    /* Function arguments that may change */
337    
338    const uschar *Xeptr;    USPTR Xeptr;
339    const uschar *Xecode;    const uschar *Xecode;
340    const uschar *Xmstart;    USPTR Xmstart;
341      USPTR Xmarkptr;
342    int Xoffset_top;    int Xoffset_top;
343    long int Xims;    long int Xims;
344    eptrblock *Xeptrb;    eptrblock *Xeptrb;
# Line 308  typedef struct heapframe { Line 347  typedef struct heapframe {
347    
348    /* Function local variables */    /* Function local variables */
349    
350    const uschar *Xcallpat;    USPTR Xcallpat;
351    const uschar *Xcharptr;  #ifdef SUPPORT_UTF8
352    const uschar *Xdata;    USPTR Xcharptr;
353    const uschar *Xnext;  #endif
354    const uschar *Xpp;    USPTR Xdata;
355    const uschar *Xprev;    USPTR Xnext;
356    const uschar *Xsaved_eptr;    USPTR Xpp;
357      USPTR Xprev;
358      USPTR Xsaved_eptr;
359    
360    recursion_info Xnew_recursive;    recursion_info Xnew_recursive;
361    
# Line 335  typedef struct heapframe { Line 376  typedef struct heapframe {
376    uschar Xocchars[8];    uschar Xocchars[8];
377  #endif  #endif
378    
379      int Xcodelink;
380    int Xctype;    int Xctype;
381    unsigned int Xfc;    unsigned int Xfc;
382    int Xfi;    int Xfi;
# Line 370  typedef struct heapframe { Line 412  typedef struct heapframe {
412    
413  /* This function is called recursively in many circumstances. Whenever it  /* This function is called recursively in many circumstances. Whenever it
414  returns a negative (error) response, the outer incarnation must also return the  returns a negative (error) response, the outer incarnation must also return the
415  same response.  same response. */
416    
417    /* These macros pack up tests that are used for partial matching, and which
418    appears several times in the code. We set the "hit end" flag if the pointer is
419    at the end of the subject and also past the start of the subject (i.e.
420    something has been matched). For hard partial matching, we then return
421    immediately. The second one is used when we already know we are past the end of
422    the subject. */
423    
424    #define CHECK_PARTIAL()\
425      if (md->partial != 0 && eptr >= md->end_subject && eptr > mstart)\
426        {\
427        md->hitend = TRUE;\
428        if (md->partial > 1) MRRETURN(PCRE_ERROR_PARTIAL);\
429        }
430    
431    #define SCHECK_PARTIAL()\
432      if (md->partial != 0 && eptr > mstart)\
433        {\
434        md->hitend = TRUE;\
435        if (md->partial > 1) MRRETURN(PCRE_ERROR_PARTIAL);\
436        }
437    
438  Performance note: It might be tempting to extract commonly used fields from the  
439  md structure (e.g. utf8, end_subject) into individual variables to improve  /* Performance note: It might be tempting to extract commonly used fields from
440    the md structure (e.g. utf8, end_subject) into individual variables to improve
441  performance. Tests using gcc on a SPARC disproved this; in the first case, it  performance. Tests using gcc on a SPARC disproved this; in the first case, it
442  made performance worse.  made performance worse.
443    
# Line 382  Arguments: Line 446  Arguments:
446     ecode       pointer to current position in compiled code     ecode       pointer to current position in compiled code
447     mstart      pointer to the current match start position (can be modified     mstart      pointer to the current match start position (can be modified
448                   by encountering \K)                   by encountering \K)
449       markptr     pointer to the most recent MARK name, or NULL
450     offset_top  current top pointer     offset_top  current top pointer
451     md          pointer to "static" info for the match     md          pointer to "static" info for the match
452     ims         current /i, /m, and /s options     ims         current /i, /m, and /s options
# Line 395  Arguments: Line 460  Arguments:
460    
461  Returns:       MATCH_MATCH if matched            )  these values are >= 0  Returns:       MATCH_MATCH if matched            )  these values are >= 0
462                 MATCH_NOMATCH if failed to match  )                 MATCH_NOMATCH if failed to match  )
463                   a negative MATCH_xxx value for PRUNE, SKIP, etc
464                 a negative PCRE_ERROR_xxx value if aborted by an error condition                 a negative PCRE_ERROR_xxx value if aborted by an error condition
465                   (e.g. stopped by repeated call or recursion limit)                   (e.g. stopped by repeated call or recursion limit)
466  */  */
467    
468  static int  static int
469  match(REGISTER USPTR eptr, REGISTER const uschar *ecode, const uschar *mstart,  match(REGISTER USPTR eptr, REGISTER const uschar *ecode, USPTR mstart,
470    int offset_top, match_data *md, unsigned long int ims, eptrblock *eptrb,    const uschar *markptr, int offset_top, match_data *md, unsigned long int ims,
471    int flags, unsigned int rdepth)    eptrblock *eptrb, int flags, unsigned int rdepth)
472  {  {
473  /* These variables do not need to be preserved over recursion in this function,  /* These variables do not need to be preserved over recursion in this function,
474  so they can be ordinary variables in all cases. Mark some of them with  so they can be ordinary variables in all cases. Mark some of them with
# Line 414  register unsigned int c; /* Character Line 480  register unsigned int c; /* Character
480  register BOOL utf8;        /* Local copy of UTF-8 flag for speed */  register BOOL utf8;        /* Local copy of UTF-8 flag for speed */
481    
482  BOOL minimize, possessive; /* Quantifier options */  BOOL minimize, possessive; /* Quantifier options */
483    int condcode;
484    
485  /* When recursion is not being used, all "local" variables that have to be  /* When recursion is not being used, all "local" variables that have to be
486  preserved over calls to RMATCH() are part of a "frame" which is obtained from  preserved over calls to RMATCH() are part of a "frame" which is obtained from
# Line 422  heap whenever RMATCH() does a "recursion Line 489  heap whenever RMATCH() does a "recursion
489    
490  #ifdef NO_RECURSE  #ifdef NO_RECURSE
491  heapframe *frame = (pcre_stack_malloc)(sizeof(heapframe));  heapframe *frame = (pcre_stack_malloc)(sizeof(heapframe));
492    if (frame == NULL) RRETURN(PCRE_ERROR_NOMEMORY);
493  frame->Xprevframe = NULL;            /* Marks the top level */  frame->Xprevframe = NULL;            /* Marks the top level */
494    
495  /* Copy in the original argument variables */  /* Copy in the original argument variables */
# Line 429  frame->Xprevframe = NULL; /* Line 497  frame->Xprevframe = NULL; /*
497  frame->Xeptr = eptr;  frame->Xeptr = eptr;
498  frame->Xecode = ecode;  frame->Xecode = ecode;
499  frame->Xmstart = mstart;  frame->Xmstart = mstart;
500    frame->Xmarkptr = markptr;
501  frame->Xoffset_top = offset_top;  frame->Xoffset_top = offset_top;
502  frame->Xims = ims;  frame->Xims = ims;
503  frame->Xeptrb = eptrb;  frame->Xeptrb = eptrb;
# Line 444  HEAP_RECURSE: Line 513  HEAP_RECURSE:
513  #define eptr               frame->Xeptr  #define eptr               frame->Xeptr
514  #define ecode              frame->Xecode  #define ecode              frame->Xecode
515  #define mstart             frame->Xmstart  #define mstart             frame->Xmstart
516    #define markptr            frame->Xmarkptr
517  #define offset_top         frame->Xoffset_top  #define offset_top         frame->Xoffset_top
518  #define ims                frame->Xims  #define ims                frame->Xims
519  #define eptrb              frame->Xeptrb  #define eptrb              frame->Xeptrb
# Line 456  HEAP_RECURSE: Line 526  HEAP_RECURSE:
526  #define charptr            frame->Xcharptr  #define charptr            frame->Xcharptr
527  #endif  #endif
528  #define callpat            frame->Xcallpat  #define callpat            frame->Xcallpat
529    #define codelink           frame->Xcodelink
530  #define data               frame->Xdata  #define data               frame->Xdata
531  #define next               frame->Xnext  #define next               frame->Xnext
532  #define pp                 frame->Xpp  #define pp                 frame->Xpp
# Line 536  int oclength; Line 607  int oclength;
607  uschar occhars[8];  uschar occhars[8];
608  #endif  #endif
609    
610    int codelink;
611  int ctype;  int ctype;
612  int length;  int length;
613  int max;  int max;
# Line 569  TAIL_RECURSE: Line 641  TAIL_RECURSE:
641  /* OK, now we can get on with the real code of the function. Recursive calls  /* OK, now we can get on with the real code of the function. Recursive calls
642  are specified by the macro RMATCH and RRETURN is used to return. When  are specified by the macro RMATCH and RRETURN is used to return. When
643  NO_RECURSE is *not* defined, these just turn into a recursive call to match()  NO_RECURSE is *not* defined, these just turn into a recursive call to match()
644  and a "return", respectively (possibly with some debugging if DEBUG is  and a "return", respectively (possibly with some debugging if PCRE_DEBUG is
645  defined). However, RMATCH isn't like a function call because it's quite a  defined). However, RMATCH isn't like a function call because it's quite a
646  complicated macro. It has to be used in one particular way. This shouldn't,  complicated macro. It has to be used in one particular way. This shouldn't,
647  however, impact performance when true recursion is being used. */  however, impact performance when true recursion is being used. */
# Line 611  for (;;) Line 683  for (;;)
683    minimize = possessive = FALSE;    minimize = possessive = FALSE;
684    op = *ecode;    op = *ecode;
685    
   /* For partial matching, remember if we ever hit the end of the subject after  
   matching at least one subject character. */  
   
   if (md->partial &&  
       eptr >= md->end_subject &&  
       eptr > mstart)  
     md->hitend = TRUE;  
   
686    switch(op)    switch(op)
687      {      {
688        case OP_MARK:
689        markptr = ecode + 2;
690        RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode] + ecode[1], offset_top, md,
691          ims, eptrb, flags, RM55);
692    
693        /* A return of MATCH_SKIP_ARG means that matching failed at SKIP with an
694        argument, and we must check whether that argument matches this MARK's
695        argument. It is passed back in md->start_match_ptr (an overloading of that
696        variable). If it does match, we reset that variable to the current subject
697        position and return MATCH_SKIP. Otherwise, pass back the return code
698        unaltered. */
699    
700        if (rrc == MATCH_SKIP_ARG &&
701            strcmp((char *)markptr, (char *)(md->start_match_ptr)) == 0)
702          {
703          md->start_match_ptr = eptr;
704          RRETURN(MATCH_SKIP);
705          }
706    
707        if (md->mark == NULL) md->mark = markptr;
708        RRETURN(rrc);
709    
710      case OP_FAIL:      case OP_FAIL:
711      return MATCH_NOMATCH;      MRRETURN(MATCH_NOMATCH);
712    
713        case OP_COMMIT:
714        RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,
715          ims, eptrb, flags, RM52);
716        if (rrc != MATCH_NOMATCH) RRETURN(rrc);
717        MRRETURN(MATCH_COMMIT);
718    
719      case OP_PRUNE:      case OP_PRUNE:
720      RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,      RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,
721        ims, eptrb, flags, RM51);        ims, eptrb, flags, RM51);
722      if (rrc != MATCH_NOMATCH) RRETURN(rrc);      if (rrc != MATCH_NOMATCH) RRETURN(rrc);
723      return MATCH_PRUNE;      MRRETURN(MATCH_PRUNE);
724    
725      case OP_COMMIT:      case OP_PRUNE_ARG:
726      RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,      RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode] + ecode[1], offset_top, md,
727        ims, eptrb, flags, RM52);        ims, eptrb, flags, RM56);
728      if (rrc != MATCH_NOMATCH) RRETURN(rrc);      if (rrc != MATCH_NOMATCH) RRETURN(rrc);
729      return MATCH_COMMIT;      md->mark = ecode + 2;
730        RRETURN(MATCH_PRUNE);
731    
732      case OP_SKIP:      case OP_SKIP:
733      RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,      RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,
734        ims, eptrb, flags, RM53);        ims, eptrb, flags, RM53);
735      if (rrc != MATCH_NOMATCH) RRETURN(rrc);      if (rrc != MATCH_NOMATCH) RRETURN(rrc);
736      md->start_match_ptr = eptr;   /* Pass back current position */      md->start_match_ptr = eptr;   /* Pass back current position */
737      return MATCH_SKIP;      MRRETURN(MATCH_SKIP);
738    
739        case OP_SKIP_ARG:
740        RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode] + ecode[1], offset_top, md,
741          ims, eptrb, flags, RM57);
742        if (rrc != MATCH_NOMATCH) RRETURN(rrc);
743    
744        /* Pass back the current skip name by overloading md->start_match_ptr and
745        returning the special MATCH_SKIP_ARG return code. This will either be
746        caught by a matching MARK, or get to the top, where it is treated the same
747        as PRUNE. */
748    
749        md->start_match_ptr = ecode + 2;
750        RRETURN(MATCH_SKIP_ARG);
751    
752      case OP_THEN:      case OP_THEN:
753      RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,      RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,
754        ims, eptrb, flags, RM53);        ims, eptrb, flags, RM54);
755      if (rrc != MATCH_NOMATCH) RRETURN(rrc);      if (rrc != MATCH_NOMATCH) RRETURN(rrc);
756      return MATCH_THEN;      MRRETURN(MATCH_THEN);
757    
758        case OP_THEN_ARG:
759        RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode] + ecode[1], offset_top, md,
760          ims, eptrb, flags, RM58);
761        if (rrc != MATCH_NOMATCH) RRETURN(rrc);
762        md->mark = ecode + 2;
763        RRETURN(MATCH_THEN);
764    
765      /* Handle a capturing bracket. If there is space in the offset vector, save      /* Handle a capturing bracket. If there is space in the offset vector, save
766      the current subject position in the working slot at the top of the vector.      the current subject position in the working slot at the top of the vector.
767      We mustn't change the current values of the data slot, because they may be      We mustn't change the current values of the data slot, because they may be
# Line 668  for (;;) Line 781  for (;;)
781      number = GET2(ecode, 1+LINK_SIZE);      number = GET2(ecode, 1+LINK_SIZE);
782      offset = number << 1;      offset = number << 1;
783    
784  #ifdef DEBUG  #ifdef PCRE_DEBUG
785      printf("start bracket %d\n", number);      printf("start bracket %d\n", number);
786      printf("subject=");      printf("subject=");
787      pchars(eptr, 16, TRUE, md);      pchars(eptr, 16, TRUE, md);
# Line 683  for (;;) Line 796  for (;;)
796        save_capture_last = md->capture_last;        save_capture_last = md->capture_last;
797    
798        DPRINTF(("saving %d %d %d\n", save_offset1, save_offset2, save_offset3));        DPRINTF(("saving %d %d %d\n", save_offset1, save_offset2, save_offset3));
799        md->offset_vector[md->offset_end - number] = eptr - md->start_subject;        md->offset_vector[md->offset_end - number] =
800            (int)(eptr - md->start_subject);
801    
802        flags = (op == OP_SCBRA)? match_cbegroup : 0;        flags = (op == OP_SCBRA)? match_cbegroup : 0;
803        do        do
# Line 702  for (;;) Line 816  for (;;)
816        md->offset_vector[offset+1] = save_offset2;        md->offset_vector[offset+1] = save_offset2;
817        md->offset_vector[md->offset_end - number] = save_offset3;        md->offset_vector[md->offset_end - number] = save_offset3;
818    
819          if (rrc != MATCH_THEN) md->mark = markptr;
820        RRETURN(MATCH_NOMATCH);        RRETURN(MATCH_NOMATCH);
821        }        }
822    
# Line 741  for (;;) Line 856  for (;;)
856    
857          RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md, ims,          RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md, ims,
858            eptrb, flags, RM48);            eptrb, flags, RM48);
859            if (rrc == MATCH_NOMATCH) md->mark = markptr;
860          RRETURN(rrc);          RRETURN(rrc);
861          }          }
862    
# Line 762  for (;;) Line 878  for (;;)
878    
879      case OP_COND:      case OP_COND:
880      case OP_SCOND:      case OP_SCOND:
881      if (ecode[LINK_SIZE+1] == OP_RREF)         /* Recursion test */      codelink= GET(ecode, 1);
882    
883        /* Because of the way auto-callout works during compile, a callout item is
884        inserted between OP_COND and an assertion condition. */
885    
886        if (ecode[LINK_SIZE+1] == OP_CALLOUT)
887        {        {
888        offset = GET2(ecode, LINK_SIZE + 2);     /* Recursion group number*/        if (pcre_callout != NULL)
889        condition = md->recursive != NULL &&          {
890          (offset == RREF_ANY || offset == md->recursive->group_num);          pcre_callout_block cb;
891        ecode += condition? 3 : GET(ecode, 1);          cb.version          = 1;   /* Version 1 of the callout block */
892            cb.callout_number   = ecode[LINK_SIZE+2];
893            cb.offset_vector    = md->offset_vector;
894            cb.subject          = (PCRE_SPTR)md->start_subject;
895            cb.subject_length   = (int)(md->end_subject - md->start_subject);
896            cb.start_match      = (int)(mstart - md->start_subject);
897            cb.current_position = (int)(eptr - md->start_subject);
898            cb.pattern_position = GET(ecode, LINK_SIZE + 3);
899            cb.next_item_length = GET(ecode, 3 + 2*LINK_SIZE);
900            cb.capture_top      = offset_top/2;
901            cb.capture_last     = md->capture_last;
902            cb.callout_data     = md->callout_data;
903            if ((rrc = (*pcre_callout)(&cb)) > 0) MRRETURN(MATCH_NOMATCH);
904            if (rrc < 0) RRETURN(rrc);
905            }
906          ecode += _pcre_OP_lengths[OP_CALLOUT];
907          }
908    
909        condcode = ecode[LINK_SIZE+1];
910    
911        /* Now see what the actual condition is */
912    
913        if (condcode == OP_RREF || condcode == OP_NRREF)    /* Recursion test */
914          {
915          if (md->recursive == NULL)                /* Not recursing => FALSE */
916            {
917            condition = FALSE;
918            ecode += GET(ecode, 1);
919            }
920          else
921            {
922            int recno = GET2(ecode, LINK_SIZE + 2);   /* Recursion group number*/
923            condition =  (recno == RREF_ANY || recno == md->recursive->group_num);
924    
925            /* If the test is for recursion into a specific subpattern, and it is
926            false, but the test was set up by name, scan the table to see if the
927            name refers to any other numbers, and test them. The condition is true
928            if any one is set. */
929    
930            if (!condition && condcode == OP_NRREF && recno != RREF_ANY)
931              {
932              uschar *slotA = md->name_table;
933              for (i = 0; i < md->name_count; i++)
934                {
935                if (GET2(slotA, 0) == recno) break;
936                slotA += md->name_entry_size;
937                }
938    
939              /* Found a name for the number - there can be only one; duplicate
940              names for different numbers are allowed, but not vice versa. First
941              scan down for duplicates. */
942    
943              if (i < md->name_count)
944                {
945                uschar *slotB = slotA;
946                while (slotB > md->name_table)
947                  {
948                  slotB -= md->name_entry_size;
949                  if (strcmp((char *)slotA + 2, (char *)slotB + 2) == 0)
950                    {
951                    condition = GET2(slotB, 0) == md->recursive->group_num;
952                    if (condition) break;
953                    }
954                  else break;
955                  }
956    
957                /* Scan up for duplicates */
958    
959                if (!condition)
960                  {
961                  slotB = slotA;
962                  for (i++; i < md->name_count; i++)
963                    {
964                    slotB += md->name_entry_size;
965                    if (strcmp((char *)slotA + 2, (char *)slotB + 2) == 0)
966                      {
967                      condition = GET2(slotB, 0) == md->recursive->group_num;
968                      if (condition) break;
969                      }
970                    else break;
971                    }
972                  }
973                }
974              }
975    
976            /* Chose branch according to the condition */
977    
978            ecode += condition? 3 : GET(ecode, 1);
979            }
980        }        }
981    
982      else if (ecode[LINK_SIZE+1] == OP_CREF)    /* Group used test */      else if (condcode == OP_CREF || condcode == OP_NCREF)  /* Group used test */
983        {        {
984        offset = GET2(ecode, LINK_SIZE+2) << 1;  /* Doubled ref number */        offset = GET2(ecode, LINK_SIZE+2) << 1;  /* Doubled ref number */
985        condition = offset < offset_top && md->offset_vector[offset] >= 0;        condition = offset < offset_top && md->offset_vector[offset] >= 0;
986    
987          /* If the numbered capture is unset, but the reference was by name,
988          scan the table to see if the name refers to any other numbers, and test
989          them. The condition is true if any one is set. This is tediously similar
990          to the code above, but not close enough to try to amalgamate. */
991    
992          if (!condition && condcode == OP_NCREF)
993            {
994            int refno = offset >> 1;
995            uschar *slotA = md->name_table;
996    
997            for (i = 0; i < md->name_count; i++)
998              {
999              if (GET2(slotA, 0) == refno) break;
1000              slotA += md->name_entry_size;
1001              }
1002    
1003            /* Found a name for the number - there can be only one; duplicate names
1004            for different numbers are allowed, but not vice versa. First scan down
1005            for duplicates. */
1006    
1007            if (i < md->name_count)
1008              {
1009              uschar *slotB = slotA;
1010              while (slotB > md->name_table)
1011                {
1012                slotB -= md->name_entry_size;
1013                if (strcmp((char *)slotA + 2, (char *)slotB + 2) == 0)
1014                  {
1015                  offset = GET2(slotB, 0) << 1;
1016                  condition = offset < offset_top &&
1017                    md->offset_vector[offset] >= 0;
1018                  if (condition) break;
1019                  }
1020                else break;
1021                }
1022    
1023              /* Scan up for duplicates */
1024    
1025              if (!condition)
1026                {
1027                slotB = slotA;
1028                for (i++; i < md->name_count; i++)
1029                  {
1030                  slotB += md->name_entry_size;
1031                  if (strcmp((char *)slotA + 2, (char *)slotB + 2) == 0)
1032                    {
1033                    offset = GET2(slotB, 0) << 1;
1034                    condition = offset < offset_top &&
1035                      md->offset_vector[offset] >= 0;
1036                    if (condition) break;
1037                    }
1038                  else break;
1039                  }
1040                }
1041              }
1042            }
1043    
1044          /* Chose branch according to the condition */
1045    
1046        ecode += condition? 3 : GET(ecode, 1);        ecode += condition? 3 : GET(ecode, 1);
1047        }        }
1048    
1049      else if (ecode[LINK_SIZE+1] == OP_DEF)     /* DEFINE - always false */      else if (condcode == OP_DEF)     /* DEFINE - always false */
1050        {        {
1051        condition = FALSE;        condition = FALSE;
1052        ecode += GET(ecode, 1);        ecode += GET(ecode, 1);
# Line 804  for (;;) Line 1073  for (;;)
1073        else        else
1074          {          {
1075          condition = FALSE;          condition = FALSE;
1076          ecode += GET(ecode, 1);          ecode += codelink;
1077          }          }
1078        }        }
1079    
# Line 827  for (;;) Line 1096  for (;;)
1096          goto TAIL_RECURSE;          goto TAIL_RECURSE;
1097          }          }
1098        }        }
1099      else                         /* Condition false & no 2nd alternative */      else                         /* Condition false & no alternative */
1100        {        {
1101        ecode += 1 + LINK_SIZE;        ecode += 1 + LINK_SIZE;
1102        }        }
1103      break;      break;
1104    
1105    
1106        /* Before OP_ACCEPT there may be any number of OP_CLOSE opcodes,
1107        to close any currently open capturing brackets. */
1108    
1109        case OP_CLOSE:
1110        number = GET2(ecode, 1);
1111        offset = number << 1;
1112    
1113    #ifdef PCRE_DEBUG
1114          printf("end bracket %d at *ACCEPT", number);
1115          printf("\n");
1116    #endif
1117    
1118        md->capture_last = number;
1119        if (offset >= md->offset_max) md->offset_overflow = TRUE; else
1120          {
1121          md->offset_vector[offset] =
1122            md->offset_vector[md->offset_end - number];
1123          md->offset_vector[offset+1] = (int)(eptr - md->start_subject);
1124          if (offset_top <= offset) offset_top = offset + 2;
1125          }
1126        ecode += 3;
1127        break;
1128    
1129    
1130      /* End of the pattern, either real or forced. If we are in a top-level      /* End of the pattern, either real or forced. If we are in a top-level
1131      recursion, we should restore the offsets appropriately and continue from      recursion, we should restore the offsets appropriately and continue from
1132      after the call. */      after the call. */
# Line 847  for (;;) Line 1140  for (;;)
1140        md->recursive = rec->prevrec;        md->recursive = rec->prevrec;
1141        memmove(md->offset_vector, rec->offset_save,        memmove(md->offset_vector, rec->offset_save,
1142          rec->saved_max * sizeof(int));          rec->saved_max * sizeof(int));
1143        mstart = rec->save_start;        offset_top = rec->save_offset_top;
1144        ims = original_ims;        ims = original_ims;
1145        ecode = rec->after_call;        ecode = rec->after_call;
1146        break;        break;
1147        }        }
1148    
1149      /* Otherwise, if PCRE_NOTEMPTY is set, fail if we have matched an empty      /* Otherwise, if we have matched an empty string, fail if PCRE_NOTEMPTY is
1150      string - backtracking will then try other alternatives, if any. */      set, or if PCRE_NOTEMPTY_ATSTART is set and we have matched at the start of
1151        the subject. In both cases, backtracking will then try other alternatives,
1152        if any. */
1153    
1154        if (eptr == mstart &&
1155            (md->notempty ||
1156              (md->notempty_atstart &&
1157                mstart == md->start_subject + md->start_offset)))
1158          MRRETURN(MATCH_NOMATCH);
1159    
1160        /* Otherwise, we have a match. */
1161    
     if (md->notempty && eptr == mstart) RRETURN(MATCH_NOMATCH);  
1162      md->end_match_ptr = eptr;           /* Record where we ended */      md->end_match_ptr = eptr;           /* Record where we ended */
1163      md->end_offset_top = offset_top;    /* and how many extracts were taken */      md->end_offset_top = offset_top;    /* and how many extracts were taken */
1164      md->start_match_ptr = mstart;       /* and the start (\K can modify) */      md->start_match_ptr = mstart;       /* and the start (\K can modify) */
1165      RRETURN(MATCH_MATCH);  
1166        /* For some reason, the macros don't work properly if an expression is
1167        given as the argument to MRRETURN when the heap is in use. */
1168    
1169        rrc = (op == OP_END)? MATCH_MATCH : MATCH_ACCEPT;
1170        MRRETURN(rrc);
1171    
1172      /* Change option settings */      /* Change option settings */
1173    
# Line 882  for (;;) Line 1189  for (;;)
1189        {        {
1190        RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, NULL, 0,        RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, NULL, 0,
1191          RM4);          RM4);
1192        if (rrc == MATCH_MATCH) break;        if (rrc == MATCH_MATCH || rrc == MATCH_ACCEPT)
1193            {
1194            mstart = md->start_match_ptr;   /* In case \K reset it */
1195            break;
1196            }
1197        if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);        if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);
1198        ecode += GET(ecode, 1);        ecode += GET(ecode, 1);
1199        }        }
1200      while (*ecode == OP_ALT);      while (*ecode == OP_ALT);
1201      if (*ecode == OP_KET) RRETURN(MATCH_NOMATCH);      if (*ecode == OP_KET) MRRETURN(MATCH_NOMATCH);
1202    
1203      /* If checking an assertion for a condition, return MATCH_MATCH. */      /* If checking an assertion for a condition, return MATCH_MATCH. */
1204    
# Line 901  for (;;) Line 1212  for (;;)
1212      offset_top = md->end_offset_top;      offset_top = md->end_offset_top;
1213      continue;      continue;
1214    
1215      /* Negative assertion: all branches must fail to match */      /* Negative assertion: all branches must fail to match. Encountering SKIP,
1216        PRUNE, or COMMIT means we must assume failure without checking subsequent
1217        branches. */
1218    
1219      case OP_ASSERT_NOT:      case OP_ASSERT_NOT:
1220      case OP_ASSERTBACK_NOT:      case OP_ASSERTBACK_NOT:
# Line 909  for (;;) Line 1222  for (;;)
1222        {        {
1223        RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, NULL, 0,        RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, NULL, 0,
1224          RM5);          RM5);
1225        if (rrc == MATCH_MATCH) RRETURN(MATCH_NOMATCH);        if (rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) MRRETURN(MATCH_NOMATCH);
1226          if (rrc == MATCH_SKIP || rrc == MATCH_PRUNE || rrc == MATCH_COMMIT)
1227            {
1228            do ecode += GET(ecode,1); while (*ecode == OP_ALT);
1229            break;
1230            }
1231        if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);        if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);
1232        ecode += GET(ecode,1);        ecode += GET(ecode,1);
1233        }        }
# Line 933  for (;;) Line 1251  for (;;)
1251        while (i-- > 0)        while (i-- > 0)
1252          {          {
1253          eptr--;          eptr--;
1254          if (eptr < md->start_subject) RRETURN(MATCH_NOMATCH);          if (eptr < md->start_subject) MRRETURN(MATCH_NOMATCH);
1255          BACKCHAR(eptr);          BACKCHAR(eptr);
1256          }          }
1257        }        }
# Line 944  for (;;) Line 1262  for (;;)
1262    
1263        {        {
1264        eptr -= GET(ecode, 1);        eptr -= GET(ecode, 1);
1265        if (eptr < md->start_subject) RRETURN(MATCH_NOMATCH);        if (eptr < md->start_subject) MRRETURN(MATCH_NOMATCH);
1266        }        }
1267    
1268      /* Skip to next op code */      /* Save the earliest consulted character, then skip to next op code */
1269    
1270        if (eptr < md->start_used_ptr) md->start_used_ptr = eptr;
1271      ecode += 1 + LINK_SIZE;      ecode += 1 + LINK_SIZE;
1272      break;      break;
1273    
# Line 964  for (;;) Line 1283  for (;;)
1283        cb.callout_number   = ecode[1];        cb.callout_number   = ecode[1];
1284        cb.offset_vector    = md->offset_vector;        cb.offset_vector    = md->offset_vector;
1285        cb.subject          = (PCRE_SPTR)md->start_subject;        cb.subject          = (PCRE_SPTR)md->start_subject;
1286        cb.subject_length   = md->end_subject - md->start_subject;        cb.subject_length   = (int)(md->end_subject - md->start_subject);
1287        cb.start_match      = mstart - md->start_subject;        cb.start_match      = (int)(mstart - md->start_subject);
1288        cb.current_position = eptr - md->start_subject;        cb.current_position = (int)(eptr - md->start_subject);
1289        cb.pattern_position = GET(ecode, 2);        cb.pattern_position = GET(ecode, 2);
1290        cb.next_item_length = GET(ecode, 2 + LINK_SIZE);        cb.next_item_length = GET(ecode, 2 + LINK_SIZE);
1291        cb.capture_top      = offset_top/2;        cb.capture_top      = offset_top/2;
1292        cb.capture_last     = md->capture_last;        cb.capture_last     = md->capture_last;
1293        cb.callout_data     = md->callout_data;        cb.callout_data     = md->callout_data;
1294        if ((rrc = (*pcre_callout)(&cb)) > 0) RRETURN(MATCH_NOMATCH);        if ((rrc = (*pcre_callout)(&cb)) > 0) MRRETURN(MATCH_NOMATCH);
1295        if (rrc < 0) RRETURN(rrc);        if (rrc < 0) RRETURN(rrc);
1296        }        }
1297      ecode += 2 + 2*LINK_SIZE;      ecode += 2 + 2*LINK_SIZE;
# Line 1027  for (;;) Line 1346  for (;;)
1346    
1347        memcpy(new_recursive.offset_save, md->offset_vector,        memcpy(new_recursive.offset_save, md->offset_vector,
1348              new_recursive.saved_max * sizeof(int));              new_recursive.saved_max * sizeof(int));
1349        new_recursive.save_start = mstart;        new_recursive.save_offset_top = offset_top;
       mstart = eptr;  
1350    
1351        /* OK, now we can do the recursion. For each top-level alternative we        /* OK, now we can do the recursion. For each top-level alternative we
1352        restore the offset and recursion data. */        restore the offset and recursion data. */
# Line 1039  for (;;) Line 1357  for (;;)
1357          {          {
1358          RMATCH(eptr, callpat + _pcre_OP_lengths[*callpat], offset_top,          RMATCH(eptr, callpat + _pcre_OP_lengths[*callpat], offset_top,
1359            md, ims, eptrb, flags, RM6);            md, ims, eptrb, flags, RM6);
1360          if (rrc == MATCH_MATCH)          if (rrc == MATCH_MATCH || rrc == MATCH_ACCEPT)
1361            {            {
1362            DPRINTF(("Recursion matched\n"));            DPRINTF(("Recursion matched\n"));
1363            md->recursive = new_recursive.prevrec;            md->recursive = new_recursive.prevrec;
1364            if (new_recursive.offset_save != stacksave)            if (new_recursive.offset_save != stacksave)
1365              (pcre_free)(new_recursive.offset_save);              (pcre_free)(new_recursive.offset_save);
1366            RRETURN(MATCH_MATCH);            MRRETURN(MATCH_MATCH);
1367            }            }
1368          else if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN)          else if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN)
1369            {            {
1370            DPRINTF(("Recursion gave error %d\n", rrc));            DPRINTF(("Recursion gave error %d\n", rrc));
1371              if (new_recursive.offset_save != stacksave)
1372                (pcre_free)(new_recursive.offset_save);
1373            RRETURN(rrc);            RRETURN(rrc);
1374            }            }
1375    
# Line 1064  for (;;) Line 1384  for (;;)
1384        md->recursive = new_recursive.prevrec;        md->recursive = new_recursive.prevrec;
1385        if (new_recursive.offset_save != stacksave)        if (new_recursive.offset_save != stacksave)
1386          (pcre_free)(new_recursive.offset_save);          (pcre_free)(new_recursive.offset_save);
1387        RRETURN(MATCH_NOMATCH);        MRRETURN(MATCH_NOMATCH);
1388        }        }
1389      /* Control never reaches here */      /* Control never reaches here */
1390    
# Line 1073  for (;;) Line 1393  for (;;)
1393      a move back into the brackets. Friedl calls these "atomic" subpatterns.      a move back into the brackets. Friedl calls these "atomic" subpatterns.
1394      Check the alternative branches in turn - the matching won't pass the KET      Check the alternative branches in turn - the matching won't pass the KET
1395      for this kind of subpattern. If any one branch matches, we carry on as at      for this kind of subpattern. If any one branch matches, we carry on as at
1396      the end of a normal bracket, leaving the subject pointer. */      the end of a normal bracket, leaving the subject pointer, but resetting
1397        the start-of-match value in case it was changed by \K. */
1398    
1399      case OP_ONCE:      case OP_ONCE:
1400      prev = ecode;      prev = ecode;
# Line 1082  for (;;) Line 1403  for (;;)
1403      do      do
1404        {        {
1405        RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, eptrb, 0, RM7);        RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, eptrb, 0, RM7);
1406        if (rrc == MATCH_MATCH) break;        if (rrc == MATCH_MATCH)  /* Note: _not_ MATCH_ACCEPT */
1407            {
1408            mstart = md->start_match_ptr;
1409            break;
1410            }
1411        if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);        if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);
1412        ecode += GET(ecode,1);        ecode += GET(ecode,1);
1413        }        }
# Line 1149  for (;;) Line 1474  for (;;)
1474      do ecode += GET(ecode,1); while (*ecode == OP_ALT);      do ecode += GET(ecode,1); while (*ecode == OP_ALT);
1475      break;      break;
1476    
1477      /* BRAZERO and BRAMINZERO occur just before a bracket group, indicating      /* BRAZERO, BRAMINZERO and SKIPZERO occur just before a bracket group,
1478      that it may occur zero times. It may repeat infinitely, or not at all -      indicating that it may occur zero times. It may repeat infinitely, or not
1479      i.e. it could be ()* or ()? in the pattern. Brackets with fixed upper      at all - i.e. it could be ()* or ()? or even (){0} in the pattern. Brackets
1480      repeat limits are compiled as a number of copies, with the optional ones      with fixed upper repeat limits are compiled as a number of copies, with the
1481      preceded by BRAZERO or BRAMINZERO. */      optional ones preceded by BRAZERO or BRAMINZERO. */
1482    
1483      case OP_BRAZERO:      case OP_BRAZERO:
1484        {        {
# Line 1175  for (;;) Line 1500  for (;;)
1500        }        }
1501      break;      break;
1502    
1503        case OP_SKIPZERO:
1504          {
1505          next = ecode+1;
1506          do next += GET(next,1); while (*next == OP_ALT);
1507          ecode = next + 1 + LINK_SIZE;
1508          }
1509        break;
1510    
1511      /* End of a group, repeated or non-repeating. */      /* End of a group, repeated or non-repeating. */
1512    
1513      case OP_KET:      case OP_KET:
# Line 1193  for (;;) Line 1526  for (;;)
1526        }        }
1527      else saved_eptr = NULL;      else saved_eptr = NULL;
1528    
1529      /* If we are at the end of an assertion group, stop matching and return      /* If we are at the end of an assertion group or an atomic group, stop
1530      MATCH_MATCH, but record the current high water mark for use by positive      matching and return MATCH_MATCH, but record the current high water mark for
1531      assertions. Do this also for the "once" (atomic) groups. */      use by positive assertions. We also need to record the match start in case
1532        it was changed by \K. */
1533    
1534      if (*prev == OP_ASSERT || *prev == OP_ASSERT_NOT ||      if (*prev == OP_ASSERT || *prev == OP_ASSERT_NOT ||
1535          *prev == OP_ASSERTBACK || *prev == OP_ASSERTBACK_NOT ||          *prev == OP_ASSERTBACK || *prev == OP_ASSERTBACK_NOT ||
# Line 1203  for (;;) Line 1537  for (;;)
1537        {        {
1538        md->end_match_ptr = eptr;      /* For ONCE */        md->end_match_ptr = eptr;      /* For ONCE */
1539        md->end_offset_top = offset_top;        md->end_offset_top = offset_top;
1540        RRETURN(MATCH_MATCH);        md->start_match_ptr = mstart;
1541          MRRETURN(MATCH_MATCH);
1542        }        }
1543    
1544      /* For capturing groups we have to check the group number back at the start      /* For capturing groups we have to check the group number back at the start
# Line 1217  for (;;) Line 1552  for (;;)
1552        number = GET2(prev, 1+LINK_SIZE);        number = GET2(prev, 1+LINK_SIZE);
1553        offset = number << 1;        offset = number << 1;
1554    
1555  #ifdef DEBUG  #ifdef PCRE_DEBUG
1556        printf("end bracket %d", number);        printf("end bracket %d", number);
1557        printf("\n");        printf("\n");
1558  #endif  #endif
# Line 1227  for (;;) Line 1562  for (;;)
1562          {          {
1563          md->offset_vector[offset] =          md->offset_vector[offset] =
1564            md->offset_vector[md->offset_end - number];            md->offset_vector[md->offset_end - number];
1565          md->offset_vector[offset+1] = eptr - md->start_subject;          md->offset_vector[offset+1] = (int)(eptr - md->start_subject);
1566          if (offset_top <= offset) offset_top = offset + 2;          if (offset_top <= offset) offset_top = offset + 2;
1567          }          }
1568    
# Line 1239  for (;;) Line 1574  for (;;)
1574          recursion_info *rec = md->recursive;          recursion_info *rec = md->recursive;
1575          DPRINTF(("Recursion (%d) succeeded - continuing\n", number));          DPRINTF(("Recursion (%d) succeeded - continuing\n", number));
1576          md->recursive = rec->prevrec;          md->recursive = rec->prevrec;
         mstart = rec->save_start;  
1577          memcpy(md->offset_vector, rec->offset_save,          memcpy(md->offset_vector, rec->offset_save,
1578            rec->saved_max * sizeof(int));            rec->saved_max * sizeof(int));
1579            offset_top = rec->save_offset_top;
1580          ecode = rec->after_call;          ecode = rec->after_call;
1581          ims = original_ims;          ims = original_ims;
1582          break;          break;
# Line 1298  for (;;) Line 1633  for (;;)
1633      /* Start of subject unless notbol, or after internal newline if multiline */      /* Start of subject unless notbol, or after internal newline if multiline */
1634    
1635      case OP_CIRC:      case OP_CIRC:
1636      if (md->notbol && eptr == md->start_subject) RRETURN(MATCH_NOMATCH);      if (md->notbol && eptr == md->start_subject) MRRETURN(MATCH_NOMATCH);
1637      if ((ims & PCRE_MULTILINE) != 0)      if ((ims & PCRE_MULTILINE) != 0)
1638        {        {
1639        if (eptr != md->start_subject &&        if (eptr != md->start_subject &&
1640            (eptr == md->end_subject || !WAS_NEWLINE(eptr)))            (eptr == md->end_subject || !WAS_NEWLINE(eptr)))
1641          RRETURN(MATCH_NOMATCH);          MRRETURN(MATCH_NOMATCH);
1642        ecode++;        ecode++;
1643        break;        break;
1644        }        }
# Line 1312  for (;;) Line 1647  for (;;)
1647      /* Start of subject assertion */      /* Start of subject assertion */
1648    
1649      case OP_SOD:      case OP_SOD:
1650      if (eptr != md->start_subject) RRETURN(MATCH_NOMATCH);      if (eptr != md->start_subject) MRRETURN(MATCH_NOMATCH);
1651      ecode++;      ecode++;
1652      break;      break;
1653    
1654      /* Start of match assertion */      /* Start of match assertion */
1655    
1656      case OP_SOM:      case OP_SOM:
1657      if (eptr != md->start_subject + md->start_offset) RRETURN(MATCH_NOMATCH);      if (eptr != md->start_subject + md->start_offset) MRRETURN(MATCH_NOMATCH);
1658      ecode++;      ecode++;
1659      break;      break;
1660    
# Line 1337  for (;;) Line 1672  for (;;)
1672      if ((ims & PCRE_MULTILINE) != 0)      if ((ims & PCRE_MULTILINE) != 0)
1673        {        {
1674        if (eptr < md->end_subject)        if (eptr < md->end_subject)
1675          { if (!IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH); }          { if (!IS_NEWLINE(eptr)) MRRETURN(MATCH_NOMATCH); }
1676        else        else
1677          { if (md->noteol) RRETURN(MATCH_NOMATCH); }          { if (md->noteol) MRRETURN(MATCH_NOMATCH); }
1678        ecode++;        ecode++;
1679        break;        break;
1680        }        }
1681      else      else
1682        {        {
1683        if (md->noteol) RRETURN(MATCH_NOMATCH);        if (md->noteol) MRRETURN(MATCH_NOMATCH);
1684        if (!md->endonly)        if (!md->endonly)
1685          {          {
1686          if (eptr != md->end_subject &&          if (eptr != md->end_subject &&
1687              (!IS_NEWLINE(eptr) || eptr != md->end_subject - md->nllen))              (!IS_NEWLINE(eptr) || eptr != md->end_subject - md->nllen))
1688            RRETURN(MATCH_NOMATCH);            MRRETURN(MATCH_NOMATCH);
1689          ecode++;          ecode++;
1690          break;          break;
1691          }          }
# Line 1360  for (;;) Line 1695  for (;;)
1695      /* End of subject assertion (\z) */      /* End of subject assertion (\z) */
1696    
1697      case OP_EOD:      case OP_EOD:
1698      if (eptr < md->end_subject) RRETURN(MATCH_NOMATCH);      if (eptr < md->end_subject) MRRETURN(MATCH_NOMATCH);
1699      ecode++;      ecode++;
1700      break;      break;
1701    
# Line 1369  for (;;) Line 1704  for (;;)
1704      case OP_EODN:      case OP_EODN:
1705      if (eptr != md->end_subject &&      if (eptr != md->end_subject &&
1706          (!IS_NEWLINE(eptr) || eptr != md->end_subject - md->nllen))          (!IS_NEWLINE(eptr) || eptr != md->end_subject - md->nllen))
1707        RRETURN(MATCH_NOMATCH);        MRRETURN(MATCH_NOMATCH);
1708      ecode++;      ecode++;
1709      break;      break;
1710    
# Line 1381  for (;;) Line 1716  for (;;)
1716    
1717        /* Find out if the previous and current characters are "word" characters.        /* Find out if the previous and current characters are "word" characters.
1718        It takes a bit more work in UTF-8 mode. Characters > 255 are assumed to        It takes a bit more work in UTF-8 mode. Characters > 255 are assumed to
1719        be "non-word" characters. */        be "non-word" characters. Remember the earliest consulted character for
1720          partial matching. */
1721    
1722  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
1723        if (utf8)        if (utf8)
1724          {          {
1725            /* Get status of previous character */
1726    
1727          if (eptr == md->start_subject) prev_is_word = FALSE; else          if (eptr == md->start_subject) prev_is_word = FALSE; else
1728            {            {
1729            const uschar *lastptr = eptr - 1;            USPTR lastptr = eptr - 1;
1730            while((*lastptr & 0xc0) == 0x80) lastptr--;            while((*lastptr & 0xc0) == 0x80) lastptr--;
1731              if (lastptr < md->start_used_ptr) md->start_used_ptr = lastptr;
1732            GETCHAR(c, lastptr);            GETCHAR(c, lastptr);
1733    #ifdef SUPPORT_UCP
1734              if (md->use_ucp)
1735                {
1736                if (c == '_') prev_is_word = TRUE; else
1737                  {
1738                  int cat = UCD_CATEGORY(c);
1739                  prev_is_word = (cat == ucp_L || cat == ucp_N);
1740                  }
1741                }
1742              else
1743    #endif
1744            prev_is_word = c < 256 && (md->ctypes[c] & ctype_word) != 0;            prev_is_word = c < 256 && (md->ctypes[c] & ctype_word) != 0;
1745            }            }
1746          if (eptr >= md->end_subject) cur_is_word = FALSE; else  
1747            /* Get status of next character */
1748    
1749            if (eptr >= md->end_subject)
1750              {
1751              SCHECK_PARTIAL();
1752              cur_is_word = FALSE;
1753              }
1754            else
1755            {            {
1756            GETCHAR(c, eptr);            GETCHAR(c, eptr);
1757    #ifdef SUPPORT_UCP
1758              if (md->use_ucp)
1759                {
1760                if (c == '_') cur_is_word = TRUE; else
1761                  {
1762                  int cat = UCD_CATEGORY(c);
1763                  cur_is_word = (cat == ucp_L || cat == ucp_N);
1764                  }
1765                }
1766              else
1767    #endif
1768            cur_is_word = c < 256 && (md->ctypes[c] & ctype_word) != 0;            cur_is_word = c < 256 && (md->ctypes[c] & ctype_word) != 0;
1769            }            }
1770          }          }
1771        else        else
1772  #endif  #endif
1773    
1774        /* More streamlined when not in UTF-8 mode */        /* Not in UTF-8 mode, but we may still have PCRE_UCP set, and for
1775          consistency with the behaviour of \w we do use it in this case. */
1776    
1777          {          {
1778          prev_is_word = (eptr != md->start_subject) &&          /* Get status of previous character */
1779            ((md->ctypes[eptr[-1]] & ctype_word) != 0);  
1780          cur_is_word = (eptr < md->end_subject) &&          if (eptr == md->start_subject) prev_is_word = FALSE; else
1781            ((md->ctypes[*eptr] & ctype_word) != 0);            {
1782              if (eptr <= md->start_used_ptr) md->start_used_ptr = eptr - 1;
1783    #ifdef SUPPORT_UCP
1784              if (md->use_ucp)
1785                {
1786                c = eptr[-1];
1787                if (c == '_') prev_is_word = TRUE; else
1788                  {
1789                  int cat = UCD_CATEGORY(c);
1790                  prev_is_word = (cat == ucp_L || cat == ucp_N);
1791                  }
1792                }
1793              else
1794    #endif
1795              prev_is_word = ((md->ctypes[eptr[-1]] & ctype_word) != 0);
1796              }
1797    
1798            /* Get status of next character */
1799    
1800            if (eptr >= md->end_subject)
1801              {
1802              SCHECK_PARTIAL();
1803              cur_is_word = FALSE;
1804              }
1805            else
1806    #ifdef SUPPORT_UCP
1807            if (md->use_ucp)
1808              {
1809              c = *eptr;
1810              if (c == '_') cur_is_word = TRUE; else
1811                {
1812                int cat = UCD_CATEGORY(c);
1813                cur_is_word = (cat == ucp_L || cat == ucp_N);
1814                }
1815              }
1816            else
1817    #endif
1818            cur_is_word = ((md->ctypes[*eptr] & ctype_word) != 0);
1819          }          }
1820    
1821        /* Now see if the situation is what we want */        /* Now see if the situation is what we want */
1822    
1823        if ((*ecode++ == OP_WORD_BOUNDARY)?        if ((*ecode++ == OP_WORD_BOUNDARY)?
1824             cur_is_word == prev_is_word : cur_is_word != prev_is_word)             cur_is_word == prev_is_word : cur_is_word != prev_is_word)
1825          RRETURN(MATCH_NOMATCH);          MRRETURN(MATCH_NOMATCH);
1826        }        }
1827      break;      break;
1828    
1829      /* Match a single character type; inline for speed */      /* Match a single character type; inline for speed */
1830    
1831      case OP_ANY:      case OP_ANY:
1832      if ((ims & PCRE_DOTALL) == 0)      if (IS_NEWLINE(eptr)) MRRETURN(MATCH_NOMATCH);
1833        /* Fall through */
1834    
1835        case OP_ALLANY:
1836        if (eptr++ >= md->end_subject)
1837        {        {
1838        if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH);        SCHECK_PARTIAL();
1839          MRRETURN(MATCH_NOMATCH);
1840        }        }
1841      if (eptr++ >= md->end_subject) RRETURN(MATCH_NOMATCH);      if (utf8) while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;
     if (utf8)  
       while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;  
1842      ecode++;      ecode++;
1843      break;      break;
1844    
# Line 1436  for (;;) Line 1846  for (;;)
1846      any byte, even newline, independent of the setting of PCRE_DOTALL. */      any byte, even newline, independent of the setting of PCRE_DOTALL. */
1847    
1848      case OP_ANYBYTE:      case OP_ANYBYTE:
1849      if (eptr++ >= md->end_subject) RRETURN(MATCH_NOMATCH);      if (eptr++ >= md->end_subject)
1850          {
1851          SCHECK_PARTIAL();
1852          MRRETURN(MATCH_NOMATCH);
1853          }
1854      ecode++;      ecode++;
1855      break;      break;
1856    
1857      case OP_NOT_DIGIT:      case OP_NOT_DIGIT:
1858      if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);      if (eptr >= md->end_subject)
1859          {
1860          SCHECK_PARTIAL();
1861          MRRETURN(MATCH_NOMATCH);
1862          }
1863      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
1864      if (      if (
1865  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
# Line 1449  for (;;) Line 1867  for (;;)
1867  #endif  #endif
1868         (md->ctypes[c] & ctype_digit) != 0         (md->ctypes[c] & ctype_digit) != 0
1869         )         )
1870        RRETURN(MATCH_NOMATCH);        MRRETURN(MATCH_NOMATCH);
1871      ecode++;      ecode++;
1872      break;      break;
1873    
1874      case OP_DIGIT:      case OP_DIGIT:
1875      if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);      if (eptr >= md->end_subject)
1876          {
1877          SCHECK_PARTIAL();
1878          MRRETURN(MATCH_NOMATCH);
1879          }
1880      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
1881      if (      if (
1882  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
# Line 1462  for (;;) Line 1884  for (;;)
1884  #endif  #endif
1885         (md->ctypes[c] & ctype_digit) == 0         (md->ctypes[c] & ctype_digit) == 0
1886         )         )
1887        RRETURN(MATCH_NOMATCH);        MRRETURN(MATCH_NOMATCH);
1888      ecode++;      ecode++;
1889      break;      break;
1890    
1891      case OP_NOT_WHITESPACE:      case OP_NOT_WHITESPACE:
1892      if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);      if (eptr >= md->end_subject)
1893          {
1894          SCHECK_PARTIAL();
1895          MRRETURN(MATCH_NOMATCH);
1896          }
1897      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
1898      if (      if (
1899  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
# Line 1475  for (;;) Line 1901  for (;;)
1901  #endif  #endif
1902         (md->ctypes[c] & ctype_space) != 0         (md->ctypes[c] & ctype_space) != 0
1903         )         )
1904        RRETURN(MATCH_NOMATCH);        MRRETURN(MATCH_NOMATCH);
1905      ecode++;      ecode++;
1906      break;      break;
1907    
1908      case OP_WHITESPACE:      case OP_WHITESPACE:
1909      if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);      if (eptr >= md->end_subject)
1910          {
1911          SCHECK_PARTIAL();
1912          MRRETURN(MATCH_NOMATCH);
1913          }
1914      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
1915      if (      if (
1916  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
# Line 1488  for (;;) Line 1918  for (;;)
1918  #endif  #endif
1919         (md->ctypes[c] & ctype_space) == 0         (md->ctypes[c] & ctype_space) == 0
1920         )         )
1921        RRETURN(MATCH_NOMATCH);        MRRETURN(MATCH_NOMATCH);
1922      ecode++;      ecode++;
1923      break;      break;
1924    
1925      case OP_NOT_WORDCHAR:      case OP_NOT_WORDCHAR:
1926      if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);      if (eptr >= md->end_subject)
1927          {
1928          SCHECK_PARTIAL();
1929          MRRETURN(MATCH_NOMATCH);
1930          }
1931      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
1932      if (      if (
1933  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
# Line 1501  for (;;) Line 1935  for (;;)
1935  #endif  #endif
1936         (md->ctypes[c] & ctype_word) != 0         (md->ctypes[c] & ctype_word) != 0
1937         )         )
1938        RRETURN(MATCH_NOMATCH);        MRRETURN(MATCH_NOMATCH);
1939      ecode++;      ecode++;
1940      break;      break;
1941    
1942      case OP_WORDCHAR:      case OP_WORDCHAR:
1943      if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);      if (eptr >= md->end_subject)
1944          {
1945          SCHECK_PARTIAL();
1946          MRRETURN(MATCH_NOMATCH);
1947          }
1948      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
1949      if (      if (
1950  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
# Line 1514  for (;;) Line 1952  for (;;)
1952  #endif  #endif
1953         (md->ctypes[c] & ctype_word) == 0         (md->ctypes[c] & ctype_word) == 0
1954         )         )
1955        RRETURN(MATCH_NOMATCH);        MRRETURN(MATCH_NOMATCH);
1956      ecode++;      ecode++;
1957      break;      break;
1958    
1959      case OP_ANYNL:      case OP_ANYNL:
1960      if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);      if (eptr >= md->end_subject)
1961          {
1962          SCHECK_PARTIAL();
1963          MRRETURN(MATCH_NOMATCH);
1964          }
1965      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
1966      switch(c)      switch(c)
1967        {        {
1968        default: RRETURN(MATCH_NOMATCH);        default: MRRETURN(MATCH_NOMATCH);
1969        case 0x000d:        case 0x000d:
1970        if (eptr < md->end_subject && *eptr == 0x0a) eptr++;        if (eptr < md->end_subject && *eptr == 0x0a) eptr++;
1971        break;        break;
1972    
1973        case 0x000a:        case 0x000a:
1974          break;
1975    
1976        case 0x000b:        case 0x000b:
1977        case 0x000c:        case 0x000c:
1978        case 0x0085:        case 0x0085:
1979        case 0x2028:        case 0x2028:
1980        case 0x2029:        case 0x2029:
1981          if (md->bsr_anycrlf) MRRETURN(MATCH_NOMATCH);
1982        break;        break;
1983        }        }
1984      ecode++;      ecode++;
1985      break;      break;
1986    
1987      case OP_NOT_HSPACE:      case OP_NOT_HSPACE:
1988      if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);      if (eptr >= md->end_subject)
1989          {
1990          SCHECK_PARTIAL();
1991          MRRETURN(MATCH_NOMATCH);
1992          }
1993      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
1994      switch(c)      switch(c)
1995        {        {
# Line 1563  for (;;) Line 2013  for (;;)
2013        case 0x202f:    /* NARROW NO-BREAK SPACE */        case 0x202f:    /* NARROW NO-BREAK SPACE */
2014        case 0x205f:    /* MEDIUM MATHEMATICAL SPACE */        case 0x205f:    /* MEDIUM MATHEMATICAL SPACE */
2015        case 0x3000:    /* IDEOGRAPHIC SPACE */        case 0x3000:    /* IDEOGRAPHIC SPACE */
2016        RRETURN(MATCH_NOMATCH);        MRRETURN(MATCH_NOMATCH);
2017        }        }
2018      ecode++;      ecode++;
2019      break;      break;
2020    
2021      case OP_HSPACE:      case OP_HSPACE:
2022      if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);      if (eptr >= md->end_subject)
2023          {
2024          SCHECK_PARTIAL();
2025          MRRETURN(MATCH_NOMATCH);
2026          }
2027      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
2028      switch(c)      switch(c)
2029        {        {
2030        default: RRETURN(MATCH_NOMATCH);        default: MRRETURN(MATCH_NOMATCH);
2031        case 0x09:      /* HT */        case 0x09:      /* HT */
2032        case 0x20:      /* SPACE */        case 0x20:      /* SPACE */
2033        case 0xa0:      /* NBSP */        case 0xa0:      /* NBSP */
# Line 1599  for (;;) Line 2053  for (;;)
2053      break;      break;
2054    
2055      case OP_NOT_VSPACE:      case OP_NOT_VSPACE:
2056      if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);      if (eptr >= md->end_subject)
2057          {
2058          SCHECK_PARTIAL();
2059          MRRETURN(MATCH_NOMATCH);
2060          }
2061      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
2062      switch(c)      switch(c)
2063        {        {
# Line 1611  for (;;) Line 2069  for (;;)
2069        case 0x85:      /* NEL */        case 0x85:      /* NEL */
2070        case 0x2028:    /* LINE SEPARATOR */        case 0x2028:    /* LINE SEPARATOR */
2071        case 0x2029:    /* PARAGRAPH SEPARATOR */        case 0x2029:    /* PARAGRAPH SEPARATOR */
2072        RRETURN(MATCH_NOMATCH);        MRRETURN(MATCH_NOMATCH);
2073        }        }
2074      ecode++;      ecode++;
2075      break;      break;
2076    
2077      case OP_VSPACE:      case OP_VSPACE:
2078      if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);      if (eptr >= md->end_subject)
2079          {
2080          SCHECK_PARTIAL();
2081          MRRETURN(MATCH_NOMATCH);
2082          }
2083      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
2084      switch(c)      switch(c)
2085        {        {
2086        default: RRETURN(MATCH_NOMATCH);        default: MRRETURN(MATCH_NOMATCH);
2087        case 0x0a:      /* LF */        case 0x0a:      /* LF */
2088        case 0x0b:      /* VT */        case 0x0b:      /* VT */
2089        case 0x0c:      /* FF */        case 0x0c:      /* FF */
# Line 1640  for (;;) Line 2102  for (;;)
2102    
2103      case OP_PROP:      case OP_PROP:
2104      case OP_NOTPROP:      case OP_NOTPROP:
2105      if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);      if (eptr >= md->end_subject)
2106          {
2107          SCHECK_PARTIAL();
2108          MRRETURN(MATCH_NOMATCH);
2109          }
2110      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
2111        {        {
2112        int chartype, script;        const ucd_record *prop = GET_UCD(c);
       int category = _pcre_ucp_findprop(c, &chartype, &script);  
2113    
2114        switch(ecode[1])        switch(ecode[1])
2115          {          {
2116          case PT_ANY:          case PT_ANY:
2117          if (op == OP_NOTPROP) RRETURN(MATCH_NOMATCH);          if (op == OP_NOTPROP) MRRETURN(MATCH_NOMATCH);
2118          break;          break;
2119    
2120          case PT_LAMP:          case PT_LAMP:
2121          if ((chartype == ucp_Lu ||          if ((prop->chartype == ucp_Lu ||
2122               chartype == ucp_Ll ||               prop->chartype == ucp_Ll ||
2123               chartype == ucp_Lt) == (op == OP_NOTPROP))               prop->chartype == ucp_Lt) == (op == OP_NOTPROP))
2124            RRETURN(MATCH_NOMATCH);            MRRETURN(MATCH_NOMATCH);
2125           break;          break;
2126    
2127          case PT_GC:          case PT_GC:
2128          if ((ecode[2] != category) == (op == OP_PROP))          if ((ecode[2] != _pcre_ucp_gentype[prop->chartype]) == (op == OP_PROP))
2129            RRETURN(MATCH_NOMATCH);            MRRETURN(MATCH_NOMATCH);
2130          break;          break;
2131    
2132          case PT_PC:          case PT_PC:
2133          if ((ecode[2] != chartype) == (op == OP_PROP))          if ((ecode[2] != prop->chartype) == (op == OP_PROP))
2134            RRETURN(MATCH_NOMATCH);            MRRETURN(MATCH_NOMATCH);
2135          break;          break;
2136    
2137          case PT_SC:          case PT_SC:
2138          if ((ecode[2] != script) == (op == OP_PROP))          if ((ecode[2] != prop->script) == (op == OP_PROP))
2139            RRETURN(MATCH_NOMATCH);            MRRETURN(MATCH_NOMATCH);
2140          break;          break;
2141    
2142            /* These are specials */
2143    
2144            case PT_ALNUM:
2145            if ((_pcre_ucp_gentype[prop->chartype] == ucp_L ||
2146                 _pcre_ucp_gentype[prop->chartype] == ucp_N) == (op == OP_NOTPROP))
2147              MRRETURN(MATCH_NOMATCH);
2148            break;
2149    
2150            case PT_SPACE:    /* Perl space */
2151            if ((_pcre_ucp_gentype[prop->chartype] == ucp_Z ||
2152                 c == CHAR_HT || c == CHAR_NL || c == CHAR_FF || c == CHAR_CR)
2153                   == (op == OP_NOTPROP))
2154              MRRETURN(MATCH_NOMATCH);
2155            break;
2156    
2157            case PT_PXSPACE:  /* POSIX space */
2158            if ((_pcre_ucp_gentype[prop->chartype] == ucp_Z ||
2159                 c == CHAR_HT || c == CHAR_NL || c == CHAR_VT ||
2160                 c == CHAR_FF || c == CHAR_CR)
2161                   == (op == OP_NOTPROP))
2162              MRRETURN(MATCH_NOMATCH);
2163            break;
2164    
2165            case PT_WORD:
2166            if ((_pcre_ucp_gentype[prop->chartype] == ucp_L ||
2167                 _pcre_ucp_gentype[prop->chartype] == ucp_N ||
2168                 c == CHAR_UNDERSCORE) == (op == OP_NOTPROP))
2169              MRRETURN(MATCH_NOMATCH);
2170            break;
2171    
2172            /* This should never occur */
2173    
2174          default:          default:
2175          RRETURN(PCRE_ERROR_INTERNAL);          RRETURN(PCRE_ERROR_INTERNAL);
2176          }          }
# Line 1686  for (;;) Line 2183  for (;;)
2183      is in the binary; otherwise a compile-time error occurs. */      is in the binary; otherwise a compile-time error occurs. */
2184    
2185      case OP_EXTUNI:      case OP_EXTUNI:
2186      if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);      if (eptr >= md->end_subject)
2187          {
2188          SCHECK_PARTIAL();
2189          MRRETURN(MATCH_NOMATCH);
2190          }
2191      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
2192        {        {
2193        int chartype, script;        int category = UCD_CATEGORY(c);
2194        int category = _pcre_ucp_findprop(c, &chartype, &script);        if (category == ucp_M) MRRETURN(MATCH_NOMATCH);
       if (category == ucp_M) RRETURN(MATCH_NOMATCH);  
2195        while (eptr < md->end_subject)        while (eptr < md->end_subject)
2196          {          {
2197          int len = 1;          int len = 1;
# Line 1699  for (;;) Line 2199  for (;;)
2199            {            {
2200            GETCHARLEN(c, eptr, len);            GETCHARLEN(c, eptr, len);
2201            }            }
2202          category = _pcre_ucp_findprop(c, &chartype, &script);          category = UCD_CATEGORY(c);
2203          if (category != ucp_M) break;          if (category != ucp_M) break;
2204          eptr += len;          eptr += len;
2205          }          }
# Line 1720  for (;;) Line 2220  for (;;)
2220      case OP_REF:      case OP_REF:
2221        {        {
2222        offset = GET2(ecode, 1) << 1;               /* Doubled ref number */        offset = GET2(ecode, 1) << 1;               /* Doubled ref number */
2223        ecode += 3;                                 /* Advance past item */        ecode += 3;
2224    
2225        /* If the reference is unset, set the length to be longer than the amount        /* If the reference is unset, there are two possibilities:
       of subject left; this ensures that every attempt at a match fails. We  
       can't just fail here, because of the possibility of quantifiers with zero  
       minima. */  
   
       length = (offset >= offset_top || md->offset_vector[offset] < 0)?  
         md->end_subject - eptr + 1 :  
         md->offset_vector[offset+1] - md->offset_vector[offset];  
2226    
2227        /* Set up for repetition, or handle the non-repeated case */        (a) In the default, Perl-compatible state, set the length to be longer
2228          than the amount of subject left; this ensures that every attempt at a
2229          match fails. We can't just fail here, because of the possibility of
2230          quantifiers with zero minima.
2231    
2232        switch (*ecode)        (b) If the JavaScript compatibility flag is set, set the length to zero
2233          {        so that the back reference matches an empty string.
2234    
2235          Otherwise, set the length to the length of what was matched by the
2236          referenced subpattern. */
2237    
2238          if (offset >= offset_top || md->offset_vector[offset] < 0)
2239            length = (md->jscript_compat)? 0 : (int)(md->end_subject - eptr + 1);
2240          else
2241            length = md->offset_vector[offset+1] - md->offset_vector[offset];
2242    
2243          /* Set up for repetition, or handle the non-repeated case */
2244    
2245          switch (*ecode)
2246            {
2247          case OP_CRSTAR:          case OP_CRSTAR:
2248          case OP_CRMINSTAR:          case OP_CRMINSTAR:
2249          case OP_CRPLUS:          case OP_CRPLUS:
# Line 1758  for (;;) Line 2267  for (;;)
2267          break;          break;
2268    
2269          default:               /* No repeat follows */          default:               /* No repeat follows */
2270          if (!match_ref(offset, eptr, length, md, ims)) RRETURN(MATCH_NOMATCH);          if (!match_ref(offset, eptr, length, md, ims))
2271              {
2272              CHECK_PARTIAL();
2273              MRRETURN(MATCH_NOMATCH);
2274              }
2275          eptr += length;          eptr += length;
2276          continue;              /* With the main loop */          continue;              /* With the main loop */
2277          }          }
# Line 1774  for (;;) Line 2287  for (;;)
2287    
2288        for (i = 1; i <= min; i++)        for (i = 1; i <= min; i++)
2289          {          {
2290          if (!match_ref(offset, eptr, length, md, ims)) RRETURN(MATCH_NOMATCH);          if (!match_ref(offset, eptr, length, md, ims))
2291              {
2292              CHECK_PARTIAL();
2293              MRRETURN(MATCH_NOMATCH);
2294              }
2295          eptr += length;          eptr += length;
2296          }          }
2297    
# Line 1791  for (;;) Line 2308  for (;;)
2308            {            {
2309            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM14);            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM14);
2310            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2311            if (fi >= max || !match_ref(offset, eptr, length, md, ims))            if (fi >= max) MRRETURN(MATCH_NOMATCH);
2312              RRETURN(MATCH_NOMATCH);            if (!match_ref(offset, eptr, length, md, ims))
2313                {
2314                CHECK_PARTIAL();
2315                MRRETURN(MATCH_NOMATCH);
2316                }
2317            eptr += length;            eptr += length;
2318            }            }
2319          /* Control never gets here */          /* Control never gets here */
# Line 1805  for (;;) Line 2326  for (;;)
2326          pp = eptr;          pp = eptr;
2327          for (i = min; i < max; i++)          for (i = min; i < max; i++)
2328            {            {
2329            if (!match_ref(offset, eptr, length, md, ims)) break;            if (!match_ref(offset, eptr, length, md, ims))
2330                {
2331                CHECK_PARTIAL();
2332                break;
2333                }
2334            eptr += length;            eptr += length;
2335            }            }
2336          while (eptr >= pp)          while (eptr >= pp)
# Line 1814  for (;;) Line 2339  for (;;)
2339            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2340            eptr -= length;            eptr -= length;
2341            }            }
2342          RRETURN(MATCH_NOMATCH);          MRRETURN(MATCH_NOMATCH);
2343          }          }
2344        }        }
2345      /* Control never gets here */      /* Control never gets here */
2346    
   
   
2347      /* Match a bit-mapped character class, possibly repeatedly. This op code is      /* Match a bit-mapped character class, possibly repeatedly. This op code is
2348      used when all the characters in the class have values in the range 0-255,      used when all the characters in the class have values in the range 0-255,
2349      and either the matching is caseful, or the characters are in the range      and either the matching is caseful, or the characters are in the range
# Line 1875  for (;;) Line 2398  for (;;)
2398          {          {
2399          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
2400            {            {
2401            if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);            if (eptr >= md->end_subject)
2402                {
2403                SCHECK_PARTIAL();
2404                MRRETURN(MATCH_NOMATCH);
2405                }
2406            GETCHARINC(c, eptr);            GETCHARINC(c, eptr);
2407            if (c > 255)            if (c > 255)
2408              {              {
2409              if (op == OP_CLASS) RRETURN(MATCH_NOMATCH);              if (op == OP_CLASS) MRRETURN(MATCH_NOMATCH);
2410              }              }
2411            else            else
2412              {              {
2413              if ((data[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);              if ((data[c/8] & (1 << (c&7))) == 0) MRRETURN(MATCH_NOMATCH);
2414              }              }
2415            }            }
2416          }          }
# Line 1893  for (;;) Line 2420  for (;;)
2420          {          {
2421          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
2422            {            {
2423            if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);            if (eptr >= md->end_subject)
2424                {
2425                SCHECK_PARTIAL();
2426                MRRETURN(MATCH_NOMATCH);
2427                }
2428            c = *eptr++;            c = *eptr++;
2429            if ((data[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);            if ((data[c/8] & (1 << (c&7))) == 0) MRRETURN(MATCH_NOMATCH);
2430            }            }
2431          }          }
2432    
# Line 1917  for (;;) Line 2448  for (;;)
2448              {              {
2449              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM16);              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM16);
2450              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2451              if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);              if (fi >= max) MRRETURN(MATCH_NOMATCH);
2452                if (eptr >= md->end_subject)
2453                  {
2454                  SCHECK_PARTIAL();
2455                  MRRETURN(MATCH_NOMATCH);
2456                  }
2457              GETCHARINC(c, eptr);              GETCHARINC(c, eptr);
2458              if (c > 255)              if (c > 255)
2459                {                {
2460                if (op == OP_CLASS) RRETURN(MATCH_NOMATCH);                if (op == OP_CLASS) MRRETURN(MATCH_NOMATCH);
2461                }                }
2462              else              else
2463                {                {
2464                if ((data[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);                if ((data[c/8] & (1 << (c&7))) == 0) MRRETURN(MATCH_NOMATCH);
2465                }                }
2466              }              }
2467            }            }
# Line 1937  for (;;) Line 2473  for (;;)
2473              {              {
2474              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM17);              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM17);
2475              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2476              if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);              if (fi >= max) MRRETURN(MATCH_NOMATCH);
2477                if (eptr >= md->end_subject)
2478                  {
2479                  SCHECK_PARTIAL();
2480                  MRRETURN(MATCH_NOMATCH);
2481                  }
2482              c = *eptr++;              c = *eptr++;
2483              if ((data[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);              if ((data[c/8] & (1 << (c&7))) == 0) MRRETURN(MATCH_NOMATCH);
2484              }              }
2485            }            }
2486          /* Control never gets here */          /* Control never gets here */
# Line 1958  for (;;) Line 2499  for (;;)
2499            for (i = min; i < max; i++)            for (i = min; i < max; i++)
2500              {              {
2501              int len = 1;              int len = 1;
2502              if (eptr >= md->end_subject) break;              if (eptr >= md->end_subject)
2503                  {
2504                  SCHECK_PARTIAL();
2505                  break;
2506                  }
2507              GETCHARLEN(c, eptr, len);              GETCHARLEN(c, eptr, len);
2508              if (c > 255)              if (c > 255)
2509                {                {
# Line 1984  for (;;) Line 2529  for (;;)
2529            {            {
2530            for (i = min; i < max; i++)            for (i = min; i < max; i++)
2531              {              {
2532              if (eptr >= md->end_subject) break;              if (eptr >= md->end_subject)
2533                  {
2534                  SCHECK_PARTIAL();
2535                  break;
2536                  }
2537              c = *eptr;              c = *eptr;
2538              if ((data[c/8] & (1 << (c&7))) == 0) break;              if ((data[c/8] & (1 << (c&7))) == 0) break;
2539              eptr++;              eptr++;
# Line 1997  for (;;) Line 2546  for (;;)
2546              }              }
2547            }            }
2548    
2549          RRETURN(MATCH_NOMATCH);          MRRETURN(MATCH_NOMATCH);
2550          }          }
2551        }        }
2552      /* Control never gets here */      /* Control never gets here */
2553    
2554    
2555      /* Match an extended character class. This opcode is encountered only      /* Match an extended character class. This opcode is encountered only
2556      in UTF-8 mode, because that's the only time it is compiled. */      when UTF-8 mode mode is supported. Nevertheless, we may not be in UTF-8
2557        mode, because Unicode properties are supported in non-UTF-8 mode. */
2558    
2559  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
2560      case OP_XCLASS:      case OP_XCLASS:
# Line 2045  for (;;) Line 2595  for (;;)
2595    
2596        for (i = 1; i <= min; i++)        for (i = 1; i <= min; i++)
2597          {          {
2598          if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);          if (eptr >= md->end_subject)
2599          GETCHARINC(c, eptr);            {
2600          if (!_pcre_xclass(c, data)) RRETURN(MATCH_NOMATCH);            SCHECK_PARTIAL();
2601              MRRETURN(MATCH_NOMATCH);
2602              }
2603            GETCHARINCTEST(c, eptr);
2604            if (!_pcre_xclass(c, data)) MRRETURN(MATCH_NOMATCH);
2605          }          }
2606    
2607        /* If max == min we can continue with the main loop without the        /* If max == min we can continue with the main loop without the
# Line 2064  for (;;) Line 2618  for (;;)
2618            {            {
2619            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM20);            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM20);
2620            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2621            if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);            if (fi >= max) MRRETURN(MATCH_NOMATCH);
2622            GETCHARINC(c, eptr);            if (eptr >= md->end_subject)
2623            if (!_pcre_xclass(c, data)) RRETURN(MATCH_NOMATCH);              {
2624                SCHECK_PARTIAL();
2625                MRRETURN(MATCH_NOMATCH);
2626                }
2627              GETCHARINCTEST(c, eptr);
2628              if (!_pcre_xclass(c, data)) MRRETURN(MATCH_NOMATCH);
2629            }            }
2630          /* Control never gets here */          /* Control never gets here */
2631          }          }
# Line 2079  for (;;) Line 2638  for (;;)
2638          for (i = min; i < max; i++)          for (i = min; i < max; i++)
2639            {            {
2640            int len = 1;            int len = 1;
2641            if (eptr >= md->end_subject) break;            if (eptr >= md->end_subject)
2642            GETCHARLEN(c, eptr, len);              {
2643                SCHECK_PARTIAL();
2644                break;
2645                }
2646              GETCHARLENTEST(c, eptr, len);
2647            if (!_pcre_xclass(c, data)) break;            if (!_pcre_xclass(c, data)) break;
2648            eptr += len;            eptr += len;
2649            }            }
# Line 2089  for (;;) Line 2652  for (;;)
2652            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM21);            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM21);
2653            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2654            if (eptr-- == pp) break;        /* Stop if tried at original pos */            if (eptr-- == pp) break;        /* Stop if tried at original pos */
2655            BACKCHAR(eptr);            if (utf8) BACKCHAR(eptr);
2656            }            }
2657          RRETURN(MATCH_NOMATCH);          MRRETURN(MATCH_NOMATCH);
2658          }          }
2659    
2660        /* Control never gets here */        /* Control never gets here */
# Line 2107  for (;;) Line 2670  for (;;)
2670        length = 1;        length = 1;
2671        ecode++;        ecode++;
2672        GETCHARLEN(fc, ecode, length);        GETCHARLEN(fc, ecode, length);
2673        if (length > md->end_subject - eptr) RRETURN(MATCH_NOMATCH);        if (length > md->end_subject - eptr)
2674        while (length-- > 0) if (*ecode++ != *eptr++) RRETURN(MATCH_NOMATCH);          {
2675            CHECK_PARTIAL();             /* Not SCHECK_PARTIAL() */
2676            MRRETURN(MATCH_NOMATCH);
2677            }
2678          while (length-- > 0) if (*ecode++ != *eptr++) MRRETURN(MATCH_NOMATCH);
2679        }        }
2680      else      else
2681  #endif  #endif
2682    
2683      /* Non-UTF-8 mode */      /* Non-UTF-8 mode */
2684        {        {
2685        if (md->end_subject - eptr < 1) RRETURN(MATCH_NOMATCH);        if (md->end_subject - eptr < 1)
2686        if (ecode[1] != *eptr++) RRETURN(MATCH_NOMATCH);          {
2687            SCHECK_PARTIAL();            /* This one can use SCHECK_PARTIAL() */
2688            MRRETURN(MATCH_NOMATCH);
2689            }
2690          if (ecode[1] != *eptr++) MRRETURN(MATCH_NOMATCH);
2691        ecode += 2;        ecode += 2;
2692        }        }
2693      break;      break;
# Line 2131  for (;;) Line 2702  for (;;)
2702        ecode++;        ecode++;
2703        GETCHARLEN(fc, ecode, length);        GETCHARLEN(fc, ecode, length);
2704    
2705        if (length > md->end_subject - eptr) RRETURN(MATCH_NOMATCH);        if (length > md->end_subject - eptr)
2706            {
2707            CHECK_PARTIAL();             /* Not SCHECK_PARTIAL() */
2708            MRRETURN(MATCH_NOMATCH);
2709            }
2710    
2711        /* If the pattern character's value is < 128, we have only one byte, and        /* If the pattern character's value is < 128, we have only one byte, and
2712        can use the fast lookup table. */        can use the fast lookup table. */
2713    
2714        if (fc < 128)        if (fc < 128)
2715          {          {
2716          if (md->lcc[*ecode++] != md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH);          if (md->lcc[*ecode++] != md->lcc[*eptr++]) MRRETURN(MATCH_NOMATCH);
2717          }          }
2718    
2719        /* Otherwise we must pick up the subject character */        /* Otherwise we must pick up the subject character */
# Line 2155  for (;;) Line 2730  for (;;)
2730          if (fc != dc)          if (fc != dc)
2731            {            {
2732  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2733            if (dc != _pcre_ucp_othercase(fc))            if (dc != UCD_OTHERCASE(fc))
2734  #endif  #endif
2735              RRETURN(MATCH_NOMATCH);              MRRETURN(MATCH_NOMATCH);
2736            }            }
2737          }          }
2738        }        }
# Line 2166  for (;;) Line 2741  for (;;)
2741    
2742      /* Non-UTF-8 mode */      /* Non-UTF-8 mode */
2743        {        {
2744        if (md->end_subject - eptr < 1) RRETURN(MATCH_NOMATCH);        if (md->end_subject - eptr < 1)
2745        if (md->lcc[ecode[1]] != md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH);          {
2746            SCHECK_PARTIAL();            /* This one can use SCHECK_PARTIAL() */
2747            MRRETURN(MATCH_NOMATCH);
2748            }
2749          if (md->lcc[ecode[1]] != md->lcc[*eptr++]) MRRETURN(MATCH_NOMATCH);
2750        ecode += 2;        ecode += 2;
2751        }        }
2752      break;      break;
# Line 2220  for (;;) Line 2799  for (;;)
2799      case OP_MINQUERY:      case OP_MINQUERY:
2800      c = *ecode++ - OP_STAR;      c = *ecode++ - OP_STAR;
2801      minimize = (c & 1) != 0;      minimize = (c & 1) != 0;
2802    
2803      min = rep_min[c];                 /* Pick up values from tables; */      min = rep_min[c];                 /* Pick up values from tables; */
2804      max = rep_max[c];                 /* zero for max => infinity */      max = rep_max[c];                 /* zero for max => infinity */
2805      if (max == 0) max = INT_MAX;      if (max == 0) max = INT_MAX;
2806    
2807      /* Common code for all repeated single-character matches. We can give      /* Common code for all repeated single-character matches. */
     up quickly if there are fewer than the minimum number of characters left in  
     the subject. */  
2808    
2809      REPEATCHAR:      REPEATCHAR:
2810  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
# Line 2235  for (;;) Line 2813  for (;;)
2813        length = 1;        length = 1;
2814        charptr = ecode;        charptr = ecode;
2815        GETCHARLEN(fc, ecode, length);        GETCHARLEN(fc, ecode, length);
       if (min * length > md->end_subject - eptr) RRETURN(MATCH_NOMATCH);  
2816        ecode += length;        ecode += length;
2817    
2818        /* Handle multibyte character matching specially here. There is        /* Handle multibyte character matching specially here. There is
# Line 2246  for (;;) Line 2823  for (;;)
2823  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2824          unsigned int othercase;          unsigned int othercase;
2825          if ((ims & PCRE_CASELESS) != 0 &&          if ((ims & PCRE_CASELESS) != 0 &&
2826              (othercase = _pcre_ucp_othercase(fc)) != NOTACHAR)              (othercase = UCD_OTHERCASE(fc)) != fc)
2827            oclength = _pcre_ord2utf8(othercase, occhars);            oclength = _pcre_ord2utf8(othercase, occhars);
2828          else oclength = 0;          else oclength = 0;
2829  #endif  /* SUPPORT_UCP */  #endif  /* SUPPORT_UCP */
2830    
2831          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
2832            {            {
2833            if (memcmp(eptr, charptr, length) == 0) eptr += length;            if (eptr <= md->end_subject - length &&
2834                memcmp(eptr, charptr, length) == 0) eptr += length;
2835  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2836            /* Need braces because of following else */            else if (oclength > 0 &&
2837            else if (oclength == 0) { RRETURN(MATCH_NOMATCH); }                     eptr <= md->end_subject - oclength &&
2838                       memcmp(eptr, occhars, oclength) == 0) eptr += oclength;
2839    #endif  /* SUPPORT_UCP */
2840            else            else
2841              {              {
2842              if (memcmp(eptr, occhars, oclength) != 0) RRETURN(MATCH_NOMATCH);              CHECK_PARTIAL();
2843              eptr += oclength;              MRRETURN(MATCH_NOMATCH);
2844              }              }
 #else   /* without SUPPORT_UCP */  
           else { RRETURN(MATCH_NOMATCH); }  
 #endif  /* SUPPORT_UCP */  
2845            }            }
2846    
2847          if (min == max) continue;          if (min == max) continue;
# Line 2275  for (;;) Line 2852  for (;;)
2852              {              {
2853              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM22);              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM22);
2854              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2855              if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);              if (fi >= max) MRRETURN(MATCH_NOMATCH);
2856              if (memcmp(eptr, charptr, length) == 0) eptr += length;              if (eptr <= md->end_subject - length &&
2857                  memcmp(eptr, charptr, length) == 0) eptr += length;
2858  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2859              /* Need braces because of following else */              else if (oclength > 0 &&
2860              else if (oclength == 0) { RRETURN(MATCH_NOMATCH); }                       eptr <= md->end_subject - oclength &&
2861                         memcmp(eptr, occhars, oclength) == 0) eptr += oclength;
2862    #endif  /* SUPPORT_UCP */
2863              else              else
2864                {                {
2865                if (memcmp(eptr, occhars, oclength) != 0) RRETURN(MATCH_NOMATCH);                CHECK_PARTIAL();
2866                eptr += oclength;                MRRETURN(MATCH_NOMATCH);
2867                }                }
 #else   /* without SUPPORT_UCP */  
             else { RRETURN (MATCH_NOMATCH); }  
 #endif  /* SUPPORT_UCP */  
2868              }              }
2869            /* Control never gets here */            /* Control never gets here */
2870            }            }
# Line 2297  for (;;) Line 2874  for (;;)
2874            pp = eptr;            pp = eptr;
2875            for (i = min; i < max; i++)            for (i = min; i < max; i++)
2876              {              {
2877              if (eptr > md->end_subject - length) break;              if (eptr <= md->end_subject - length &&
2878              if (memcmp(eptr, charptr, length) == 0) eptr += length;                  memcmp(eptr, charptr, length) == 0) eptr += length;
2879  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2880              else if (oclength == 0) break;              else if (oclength > 0 &&
2881                         eptr <= md->end_subject - oclength &&
2882                         memcmp(eptr, occhars, oclength) == 0) eptr += oclength;
2883    #endif  /* SUPPORT_UCP */
2884              else              else
2885                {                {
2886                if (memcmp(eptr, occhars, oclength) != 0) break;                CHECK_PARTIAL();
2887                eptr += oclength;                break;
2888                }                }
 #else   /* without SUPPORT_UCP */  
             else break;  
 #endif  /* SUPPORT_UCP */  
2889              }              }
2890    
2891            if (possessive) continue;            if (possessive) continue;
2892    
2893            for(;;)            for(;;)
2894             {              {
2895             RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM23);              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM23);
2896             if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2897             if (eptr == pp) RRETURN(MATCH_NOMATCH);              if (eptr == pp) { MRRETURN(MATCH_NOMATCH); }
2898  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2899             eptr--;              eptr--;
2900             BACKCHAR(eptr);              BACKCHAR(eptr);
2901  #else   /* without SUPPORT_UCP */  #else   /* without SUPPORT_UCP */
2902             eptr -= length;              eptr -= length;
2903  #endif  /* SUPPORT_UCP */  #endif  /* SUPPORT_UCP */
2904             }              }
2905            }            }
2906          /* Control never gets here */          /* Control never gets here */
2907          }          }
# Line 2336  for (;;) Line 2914  for (;;)
2914  #endif  /* SUPPORT_UTF8 */  #endif  /* SUPPORT_UTF8 */
2915    
2916      /* When not in UTF-8 mode, load a single-byte character. */      /* When not in UTF-8 mode, load a single-byte character. */
2917        {  
2918        if (min > md->end_subject - eptr) RRETURN(MATCH_NOMATCH);      fc = *ecode++;
       fc = *ecode++;  
       }  
2919    
2920      /* The value of fc at this point is always less than 256, though we may or      /* The value of fc at this point is always less than 256, though we may or
2921      may not be in UTF-8 mode. The code is duplicated for the caseless and      may not be in UTF-8 mode. The code is duplicated for the caseless and
# Line 2357  for (;;) Line 2933  for (;;)
2933        {        {
2934        fc = md->lcc[fc];        fc = md->lcc[fc];
2935        for (i = 1; i <= min; i++)        for (i = 1; i <= min; i++)
2936          if (fc != md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH);          {
2937            if (eptr >= md->end_subject)
2938              {
2939              SCHECK_PARTIAL();
2940              MRRETURN(MATCH_NOMATCH);
2941              }
2942            if (fc != md->lcc[*eptr++]) MRRETURN(MATCH_NOMATCH);
2943            }
2944        if (min == max) continue;        if (min == max) continue;
2945        if (minimize)        if (minimize)
2946          {          {
# Line 2365  for (;;) Line 2948  for (;;)
2948            {            {
2949            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM24);            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM24);
2950            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2951            if (fi >= max || eptr >= md->end_subject ||            if (fi >= max) MRRETURN(MATCH_NOMATCH);
2952                fc != md->lcc[*eptr++])            if (eptr >= md->end_subject)
2953              RRETURN(MATCH_NOMATCH);              {
2954                SCHECK_PARTIAL();
2955                MRRETURN(MATCH_NOMATCH);
2956                }
2957              if (fc != md->lcc[*eptr++]) MRRETURN(MATCH_NOMATCH);
2958            }            }
2959          /* Control never gets here */          /* Control never gets here */
2960          }          }
# Line 2376  for (;;) Line 2963  for (;;)
2963          pp = eptr;          pp = eptr;
2964          for (i = min; i < max; i++)          for (i = min; i < max; i++)
2965            {            {
2966            if (eptr >= md->end_subject || fc != md->lcc[*eptr]) break;            if (eptr >= md->end_subject)
2967                {
2968                SCHECK_PARTIAL();
2969                break;
2970                }
2971              if (fc != md->lcc[*eptr]) break;
2972            eptr++;            eptr++;
2973            }            }
2974    
2975          if (possessive) continue;          if (possessive) continue;
2976    
2977          while (eptr >= pp)          while (eptr >= pp)
2978            {            {
2979            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM25);            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM25);
2980            eptr--;            eptr--;
2981            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2982            }            }
2983          RRETURN(MATCH_NOMATCH);          MRRETURN(MATCH_NOMATCH);
2984          }          }
2985        /* Control never gets here */        /* Control never gets here */
2986        }        }
# Line 2395  for (;;) Line 2989  for (;;)
2989    
2990      else      else
2991        {        {
2992        for (i = 1; i <= min; i++) if (fc != *eptr++) RRETURN(MATCH_NOMATCH);        for (i = 1; i <= min; i++)
2993            {
2994            if (eptr >= md->end_subject)
2995              {
2996              SCHECK_PARTIAL();
2997              MRRETURN(MATCH_NOMATCH);
2998              }
2999            if (fc != *eptr++) MRRETURN(MATCH_NOMATCH);
3000            }
3001    
3002        if (min == max) continue;        if (min == max) continue;
3003    
3004        if (minimize)        if (minimize)
3005          {          {
3006          for (fi = min;; fi++)          for (fi = min;; fi++)
3007            {            {
3008            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM26);            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM26);
3009            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3010            if (fi >= max || eptr >= md->end_subject || fc != *eptr++)            if (fi >= max) MRRETURN(MATCH_NOMATCH);
3011              RRETURN(MATCH_NOMATCH);            if (eptr >= md->end_subject)
3012                {
3013                SCHECK_PARTIAL();
3014                MRRETURN(MATCH_NOMATCH);
3015                }
3016              if (fc != *eptr++) MRRETURN(MATCH_NOMATCH);
3017            }            }
3018          /* Control never gets here */          /* Control never gets here */
3019          }          }
# Line 2413  for (;;) Line 3022  for (;;)
3022          pp = eptr;          pp = eptr;
3023          for (i = min; i < max; i++)          for (i = min; i < max; i++)
3024            {            {
3025            if (eptr >= md->end_subject || fc != *eptr) break;            if (eptr >= md->end_subject)
3026                {
3027                SCHECK_PARTIAL();
3028                break;
3029                }
3030              if (fc != *eptr) break;
3031            eptr++;            eptr++;
3032            }            }
3033          if (possessive) continue;          if (possessive) continue;
3034    
3035          while (eptr >= pp)          while (eptr >= pp)
3036            {            {
3037            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM27);            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM27);
3038            eptr--;            eptr--;
3039            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3040            }            }
3041          RRETURN(MATCH_NOMATCH);          MRRETURN(MATCH_NOMATCH);
3042          }          }
3043        }        }
3044      /* Control never gets here */      /* Control never gets here */
# Line 2432  for (;;) Line 3047  for (;;)
3047      checking can be multibyte. */      checking can be multibyte. */
3048    
3049      case OP_NOT:      case OP_NOT:
3050      if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);      if (eptr >= md->end_subject)
3051          {
3052          SCHECK_PARTIAL();
3053          MRRETURN(MATCH_NOMATCH);
3054          }
3055      ecode++;      ecode++;
3056      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
3057      if ((ims & PCRE_CASELESS) != 0)      if ((ims & PCRE_CASELESS) != 0)
# Line 2441  for (;;) Line 3060  for (;;)
3060        if (c < 256)        if (c < 256)
3061  #endif  #endif
3062        c = md->lcc[c];        c = md->lcc[c];
3063        if (md->lcc[*ecode++] == c) RRETURN(MATCH_NOMATCH);        if (md->lcc[*ecode++] == c) MRRETURN(MATCH_NOMATCH);
3064        }        }
3065      else      else
3066        {        {
3067        if (*ecode++ == c) RRETURN(MATCH_NOMATCH);        if (*ecode++ == c) MRRETURN(MATCH_NOMATCH);
3068        }        }
3069      break;      break;
3070    
# Line 2509  for (;;) Line 3128  for (;;)
3128      max = rep_max[c];                 /* zero for max => infinity */      max = rep_max[c];                 /* zero for max => infinity */
3129      if (max == 0) max = INT_MAX;      if (max == 0) max = INT_MAX;
3130    
3131      /* Common code for all repeated single-byte matches. We can give up quickly      /* Common code for all repeated single-byte matches. */
     if there are fewer than the minimum number of bytes left in the  
     subject. */  
3132    
3133      REPEATNOTCHAR:      REPEATNOTCHAR:
     if (min > md->end_subject - eptr) RRETURN(MATCH_NOMATCH);  
3134      fc = *ecode++;      fc = *ecode++;
3135    
3136      /* The code is duplicated for the caseless and caseful cases, for speed,      /* The code is duplicated for the caseless and caseful cases, for speed,
# Line 2539  for (;;) Line 3155  for (;;)
3155          register unsigned int d;          register unsigned int d;
3156          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3157            {            {
3158              if (eptr >= md->end_subject)
3159                {
3160                SCHECK_PARTIAL();
3161                MRRETURN(MATCH_NOMATCH);
3162                }
3163            GETCHARINC(d, eptr);            GETCHARINC(d, eptr);
3164            if (d < 256) d = md->lcc[d];            if (d < 256) d = md->lcc[d];
3165            if (fc == d) RRETURN(MATCH_NOMATCH);            if (fc == d) MRRETURN(MATCH_NOMATCH);
3166            }            }
3167          }          }
3168        else        else
# Line 2550  for (;;) Line 3171  for (;;)
3171        /* Not UTF-8 mode */        /* Not UTF-8 mode */
3172          {          {
3173          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3174            if (fc == md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH);            {
3175              if (eptr >= md->end_subject)
3176                {
3177                SCHECK_PARTIAL();
3178                MRRETURN(MATCH_NOMATCH);
3179                }
3180              if (fc == md->lcc[*eptr++]) MRRETURN(MATCH_NOMATCH);
3181              }
3182          }          }
3183    
3184        if (min == max) continue;        if (min == max) continue;
# Line 2566  for (;;) Line 3194  for (;;)
3194              {              {
3195              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM28);              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM28);
3196              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3197                if (fi >= max) MRRETURN(MATCH_NOMATCH);
3198                if (eptr >= md->end_subject)
3199                  {
3200                  SCHECK_PARTIAL();
3201                  MRRETURN(MATCH_NOMATCH);
3202                  }
3203              GETCHARINC(d, eptr);              GETCHARINC(d, eptr);
3204              if (d < 256) d = md->lcc[d];              if (d < 256) d = md->lcc[d];
3205              if (fi >= max || eptr >= md->end_subject || fc == d)              if (fc == d) MRRETURN(MATCH_NOMATCH);
               RRETURN(MATCH_NOMATCH);  
3206              }              }
3207            }            }
3208          else          else
# Line 2580  for (;;) Line 3213  for (;;)
3213              {              {
3214              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM29);              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM29);
3215              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3216              if (fi >= max || eptr >= md->end_subject || fc == md->lcc[*eptr++])              if (fi >= max) MRRETURN(MATCH_NOMATCH);
3217                RRETURN(MATCH_NOMATCH);              if (eptr >= md->end_subject)
3218                  {
3219                  SCHECK_PARTIAL();
3220                  MRRETURN(MATCH_NOMATCH);
3221                  }
3222                if (fc == md->lcc[*eptr++]) MRRETURN(MATCH_NOMATCH);
3223              }              }
3224            }            }
3225          /* Control never gets here */          /* Control never gets here */
# Line 2601  for (;;) Line 3239  for (;;)
3239            for (i = min; i < max; i++)            for (i = min; i < max; i++)
3240              {              {
3241              int len = 1;              int len = 1;
3242              if (eptr >= md->end_subject) break;              if (eptr >= md->end_subject)
3243                  {
3244                  SCHECK_PARTIAL();
3245                  break;
3246                  }
3247              GETCHARLEN(d, eptr, len);              GETCHARLEN(d, eptr, len);
3248              if (d < 256) d = md->lcc[d];              if (d < 256) d = md->lcc[d];
3249              if (fc == d) break;              if (fc == d) break;
# Line 2622  for (;;) Line 3264  for (;;)
3264            {            {
3265            for (i = min; i < max; i++)            for (i = min; i < max; i++)
3266              {              {
3267              if (eptr >= md->end_subject || fc == md->lcc[*eptr]) break;              if (eptr >= md->end_subject)
3268                  {
3269                  SCHECK_PARTIAL();
3270                  break;
3271                  }
3272                if (fc == md->lcc[*eptr]) break;
3273              eptr++;              eptr++;
3274              }              }
3275            if (possessive) continue;            if (possessive) continue;
# Line 2634  for (;;) Line 3281  for (;;)
3281              }              }
3282            }            }
3283    
3284          RRETURN(MATCH_NOMATCH);          MRRETURN(MATCH_NOMATCH);
3285          }          }
3286        /* Control never gets here */        /* Control never gets here */
3287        }        }
# Line 2650  for (;;) Line 3297  for (;;)
3297          register unsigned int d;          register unsigned int d;
3298          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3299            {            {
3300              if (eptr >= md->end_subject)
3301                {
3302                SCHECK_PARTIAL();
3303                MRRETURN(MATCH_NOMATCH);
3304                }
3305            GETCHARINC(d, eptr);            GETCHARINC(d, eptr);
3306            if (fc == d) RRETURN(MATCH_NOMATCH);            if (fc == d) MRRETURN(MATCH_NOMATCH);
3307            }            }
3308          }          }
3309        else        else
# Line 2659  for (;;) Line 3311  for (;;)
3311        /* Not UTF-8 mode */        /* Not UTF-8 mode */
3312          {          {
3313          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3314            if (fc == *eptr++) RRETURN(MATCH_NOMATCH);            {
3315              if (eptr >= md->end_subject)
3316                {
3317                SCHECK_PARTIAL();
3318                MRRETURN(MATCH_NOMATCH);
3319                }
3320              if (fc == *eptr++) MRRETURN(MATCH_NOMATCH);
3321              }
3322          }          }
3323    
3324        if (min == max) continue;        if (min == max) continue;
# Line 2675  for (;;) Line 3334  for (;;)
3334              {              {
3335              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM32);              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM32);
3336              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3337                if (fi >= max) MRRETURN(MATCH_NOMATCH);
3338                if (eptr >= md->end_subject)
3339                  {
3340                  SCHECK_PARTIAL();
3341                  MRRETURN(MATCH_NOMATCH);
3342                  }
3343              GETCHARINC(d, eptr);              GETCHARINC(d, eptr);
3344              if (fi >= max || eptr >= md->end_subject || fc == d)              if (fc == d) MRRETURN(MATCH_NOMATCH);
               RRETURN(MATCH_NOMATCH);  
3345              }              }
3346            }            }
3347          else          else
# Line 2688  for (;;) Line 3352  for (;;)
3352              {              {
3353              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM33);              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM33);
3354              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3355              if (fi >= max || eptr >= md->end_subject || fc == *eptr++)              if (fi >= max) MRRETURN(MATCH_NOMATCH);
3356                RRETURN(MATCH_NOMATCH);              if (eptr >= md->end_subject)
3357                  {
3358                  SCHECK_PARTIAL();
3359                  MRRETURN(MATCH_NOMATCH);
3360                  }
3361                if (fc == *eptr++) MRRETURN(MATCH_NOMATCH);
3362              }              }
3363            }            }
3364          /* Control never gets here */          /* Control never gets here */
# Line 2709  for (;;) Line 3378  for (;;)
3378            for (i = min; i < max; i++)            for (i = min; i < max; i++)
3379              {              {
3380              int len = 1;              int len = 1;
3381              if (eptr >= md->end_subject) break;              if (eptr >= md->end_subject)
3382                  {
3383                  SCHECK_PARTIAL();
3384                  break;
3385                  }
3386              GETCHARLEN(d, eptr, len);              GETCHARLEN(d, eptr, len);
3387              if (fc == d) break;              if (fc == d) break;
3388              eptr += len;              eptr += len;
# Line 2729  for (;;) Line 3402  for (;;)
3402            {            {
3403            for (i = min; i < max; i++)            for (i = min; i < max; i++)
3404              {              {
3405              if (eptr >= md->end_subject || fc == *eptr) break;              if (eptr >= md->end_subject)
3406                  {
3407                  SCHECK_PARTIAL();
3408                  break;
3409                  }
3410                if (fc == *eptr) break;
3411              eptr++;              eptr++;
3412              }              }
3413            if (possessive) continue;            if (possessive) continue;
# Line 2741  for (;;) Line 3419  for (;;)
3419              }              }
3420            }            }
3421    
3422          RRETURN(MATCH_NOMATCH);          MRRETURN(MATCH_NOMATCH);
3423          }          }
3424        }        }
3425      /* Control never gets here */      /* Control never gets here */
# Line 2823  for (;;) Line 3501  for (;;)
3501    
3502      /* First, ensure the minimum number of matches are present. Use inline      /* First, ensure the minimum number of matches are present. Use inline
3503      code for maximizing the speed, and do the type test once at the start      code for maximizing the speed, and do the type test once at the start
3504      (i.e. keep it out of the loop). Also we can test that there are at least      (i.e. keep it out of the loop). Separate the UTF-8 code completely as that
     the minimum number of bytes before we start. This isn't as effective in  
     UTF-8 mode, but it does no harm. Separate the UTF-8 code completely as that  
3505      is tidier. Also separate the UCP code, which can be the same for both UTF-8      is tidier. Also separate the UCP code, which can be the same for both UTF-8
3506      and single-bytes. */      and single-bytes. */
3507    
     if (min > md->end_subject - eptr) RRETURN(MATCH_NOMATCH);  
3508      if (min > 0)      if (min > 0)
3509        {        {
3510  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
# Line 2838  for (;;) Line 3513  for (;;)
3513          switch(prop_type)          switch(prop_type)
3514            {            {
3515            case PT_ANY:            case PT_ANY:
3516            if (prop_fail_result) RRETURN(MATCH_NOMATCH);            if (prop_fail_result) MRRETURN(MATCH_NOMATCH);
3517            for (i = 1; i <= min; i++)            for (i = 1; i <= min; i++)
3518              {              {
3519              if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);              if (eptr >= md->end_subject)
3520                  {
3521                  SCHECK_PARTIAL();
3522                  MRRETURN(MATCH_NOMATCH);
3523                  }
3524              GETCHARINCTEST(c, eptr);              GETCHARINCTEST(c, eptr);
3525              }              }
3526            break;            break;
# Line 2849  for (;;) Line 3528  for (;;)
3528            case PT_LAMP:            case PT_LAMP:
3529            for (i = 1; i <= min; i++)            for (i = 1; i <= min; i++)
3530              {              {
3531              if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);              if (eptr >= md->end_subject)
3532                  {
3533                  SCHECK_PARTIAL();
3534                  MRRETURN(MATCH_NOMATCH);
3535                  }
3536              GETCHARINCTEST(c, eptr);              GETCHARINCTEST(c, eptr);
3537              prop_category = _pcre_ucp_findprop(c, &prop_chartype, &prop_script);              prop_chartype = UCD_CHARTYPE(c);
3538              if ((prop_chartype == ucp_Lu ||              if ((prop_chartype == ucp_Lu ||
3539                   prop_chartype == ucp_Ll ||                   prop_chartype == ucp_Ll ||
3540                   prop_chartype == ucp_Lt) == prop_fail_result)                   prop_chartype == ucp_Lt) == prop_fail_result)
3541                RRETURN(MATCH_NOMATCH);                MRRETURN(MATCH_NOMATCH);
3542              }              }
3543            break;            break;
3544    
3545            case PT_GC:            case PT_GC:
3546            for (i = 1; i <= min; i++)            for (i = 1; i <= min; i++)
3547              {              {
3548              if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);              if (eptr >= md->end_subject)
3549                  {
3550                  SCHECK_PARTIAL();
3551                  MRRETURN(MATCH_NOMATCH);
3552                  }
3553              GETCHARINCTEST(c, eptr);              GETCHARINCTEST(c, eptr);
3554              prop_category = _pcre_ucp_findprop(c, &prop_chartype, &prop_script);              prop_category = UCD_CATEGORY(c);
3555              if ((prop_category == prop_value) == prop_fail_result)              if ((prop_category == prop_value) == prop_fail_result)
3556                RRETURN(MATCH_NOMATCH);                MRRETURN(MATCH_NOMATCH);
3557              }              }
3558            break;            break;
3559    
3560            case PT_PC:            case PT_PC:
3561            for (i = 1; i <= min; i++)            for (i = 1; i <= min; i++)
3562              {              {
3563              if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);              if (eptr >= md->end_subject)
3564                  {
3565                  SCHECK_PARTIAL();
3566                  MRRETURN(MATCH_NOMATCH);
3567                  }
3568              GETCHARINCTEST(c, eptr);              GETCHARINCTEST(c, eptr);
3569              prop_category = _pcre_ucp_findprop(c, &prop_chartype, &prop_script);              prop_chartype = UCD_CHARTYPE(c);
3570              if ((prop_chartype == prop_value) == prop_fail_result)              if ((prop_chartype == prop_value) == prop_fail_result)
3571                RRETURN(MATCH_NOMATCH);                MRRETURN(MATCH_NOMATCH);
3572              }              }
3573            break;            break;
3574    
3575            case PT_SC:            case PT_SC:
3576            for (i = 1; i <= min; i++)            for (i = 1; i <= min; i++)
3577              {              {
3578              if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);              if (eptr >= md->end_subject)
3579                  {
3580                  SCHECK_PARTIAL();
3581                  MRRETURN(MATCH_NOMATCH);
3582                  }
3583              GETCHARINCTEST(c, eptr);              GETCHARINCTEST(c, eptr);
3584              prop_category = _pcre_ucp_findprop(c, &prop_chartype, &prop_script);              prop_script = UCD_SCRIPT(c);
3585              if ((prop_script == prop_value) == prop_fail_result)              if ((prop_script == prop_value) == prop_fail_result)
3586                RRETURN(MATCH_NOMATCH);                MRRETURN(MATCH_NOMATCH);
3587                }
3588              break;
3589    
3590              case PT_ALNUM:
3591              for (i = 1; i <= min; i++)
3592                {
3593                if (eptr >= md->end_subject)
3594                  {
3595                  SCHECK_PARTIAL();
3596                  MRRETURN(MATCH_NOMATCH);
3597                  }
3598                GETCHARINCTEST(c, eptr);
3599                prop_category = UCD_CATEGORY(c);
3600                if ((prop_category == ucp_L || prop_category == ucp_N)
3601                       == prop_fail_result)
3602                  MRRETURN(MATCH_NOMATCH);
3603                }
3604              break;
3605    
3606              case PT_SPACE:    /* Perl space */
3607              for (i = 1; i <= min; i++)
3608                {
3609                if (eptr >= md->end_subject)
3610                  {
3611                  SCHECK_PARTIAL();
3612                  MRRETURN(MATCH_NOMATCH);
3613                  }
3614                GETCHARINCTEST(c, eptr);
3615                prop_category = UCD_CATEGORY(c);
3616                if ((prop_category == ucp_Z || c == CHAR_HT || c == CHAR_NL ||
3617                     c == CHAR_FF || c == CHAR_CR)
3618                       == prop_fail_result)
3619                  MRRETURN(MATCH_NOMATCH);
3620                }
3621              break;
3622    
3623              case PT_PXSPACE:  /* POSIX space */
3624              for (i = 1; i <= min; i++)
3625                {
3626                if (eptr >= md->end_subject)
3627                  {
3628                  SCHECK_PARTIAL();
3629                  MRRETURN(MATCH_NOMATCH);
3630                  }
3631                GETCHARINCTEST(c, eptr);
3632                prop_category = UCD_CATEGORY(c);
3633                if ((prop_category == ucp_Z || c == CHAR_HT || c == CHAR_NL ||
3634                     c == CHAR_VT || c == CHAR_FF || c == CHAR_CR)
3635                       == prop_fail_result)
3636                  MRRETURN(MATCH_NOMATCH);
3637                }
3638              break;
3639    
3640              case PT_WORD:
3641              for (i = 1; i <= min; i++)
3642                {
3643                if (eptr >= md->end_subject)
3644                  {
3645                  SCHECK_PARTIAL();
3646                  MRRETURN(MATCH_NOMATCH);
3647                  }
3648                GETCHARINCTEST(c, eptr);
3649                prop_category = UCD_CATEGORY(c);
3650                if ((prop_category == ucp_L || prop_category == ucp_N ||
3651                     c == CHAR_UNDERSCORE)
3652                       == prop_fail_result)
3653                  MRRETURN(MATCH_NOMATCH);
3654              }              }
3655            break;            break;
3656    
3657              /* This should not occur */
3658    
3659            default:            default:
3660            RRETURN(PCRE_ERROR_INTERNAL);            RRETURN(PCRE_ERROR_INTERNAL);
3661            }            }
# Line 2904  for (;;) Line 3668  for (;;)
3668          {          {
3669          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3670            {            {
3671              if (eptr >= md->end_subject)
3672                {
3673                SCHECK_PARTIAL();
3674                MRRETURN(MATCH_NOMATCH);
3675                }
3676            GETCHARINCTEST(c, eptr);            GETCHARINCTEST(c, eptr);
3677            prop_category = _pcre_ucp_findprop(c, &prop_chartype, &prop_script);            prop_category = UCD_CATEGORY(c);
3678            if (prop_category == ucp_M) RRETURN(MATCH_NOMATCH);            if (prop_category == ucp_M) MRRETURN(MATCH_NOMATCH);
3679            while (eptr < md->end_subject)            while (eptr < md->end_subject)
3680              {              {
3681              int len = 1;              int len = 1;
3682              if (!utf8) c = *eptr; else              if (!utf8) c = *eptr;
3683                {                else { GETCHARLEN(c, eptr, len); }
3684                GETCHARLEN(c, eptr, len);              prop_category = UCD_CATEGORY(c);
               }  
             prop_category = _pcre_ucp_findprop(c, &prop_chartype, &prop_script);  
3685              if (prop_category != ucp_M) break;              if (prop_category != ucp_M) break;
3686              eptr += len;              eptr += len;
3687              }              }
# Line 2932  for (;;) Line 3699  for (;;)
3699          case OP_ANY:          case OP_ANY:
3700          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3701            {            {
3702            if (eptr >= md->end_subject ||            if (eptr >= md->end_subject)
3703                 ((ims & PCRE_DOTALL) == 0 && IS_NEWLINE(eptr)))              {
3704              RRETURN(MATCH_NOMATCH);              SCHECK_PARTIAL();
3705                MRRETURN(MATCH_NOMATCH);
3706                }
3707              if (IS_NEWLINE(eptr)) MRRETURN(MATCH_NOMATCH);
3708              eptr++;
3709              while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;
3710              }
3711            break;
3712    
3713            case OP_ALLANY:
3714            for (i = 1; i <= min; i++)
3715              {
3716              if (eptr >= md->end_subject)
3717                {
3718                SCHECK_PARTIAL();
3719                MRRETURN(MATCH_NOMATCH);
3720                }
3721            eptr++;            eptr++;
3722            while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;            while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;
3723            }            }
3724          break;          break;
3725    
3726          case OP_ANYBYTE:          case OP_ANYBYTE:
3727            if (eptr > md->end_subject - min) MRRETURN(MATCH_NOMATCH);
3728          eptr += min;          eptr += min;
3729          break;          break;
3730    
3731          case OP_ANYNL:          case OP_ANYNL:
3732          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3733            {            {
3734            if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);            if (eptr >= md->end_subject)
3735                {
3736                SCHECK_PARTIAL();
3737                MRRETURN(MATCH_NOMATCH);
3738                }
3739            GETCHARINC(c, eptr);            GETCHARINC(c, eptr);
3740            switch(c)            switch(c)
3741              {              {
3742              default: RRETURN(MATCH_NOMATCH);              default: MRRETURN(MATCH_NOMATCH);
3743              case 0x000d:              case 0x000d:
3744              if (eptr < md->end_subject && *eptr == 0x0a) eptr++;              if (eptr < md->end_subject && *eptr == 0x0a) eptr++;
3745              break;              break;
3746    
3747              case 0x000a:              case 0x000a:
3748                break;
3749    
3750              case 0x000b:              case 0x000b:
3751              case 0x000c:              case 0x000c:
3752              case 0x0085:              case 0x0085:
3753              case 0x2028:              case 0x2028:
3754              case 0x2029:              case 0x2029:
3755                if (md->bsr_anycrlf) MRRETURN(MATCH_NOMATCH);
3756              break;              break;
3757              }              }
3758            }            }
# Line 2969  for (;;) Line 3761  for (;;)
3761          case OP_NOT_HSPACE:          case OP_NOT_HSPACE:
3762          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3763            {            {
3764            if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);            if (eptr >= md->end_subject)
3765                {
3766                SCHECK_PARTIAL();
3767                MRRETURN(MATCH_NOMATCH);
3768                }
3769            GETCHARINC(c, eptr);            GETCHARINC(c, eptr);
3770            switch(c)            switch(c)
3771              {              {
# Line 2993  for (;;) Line 3789  for (;;)
3789              case 0x202f:    /* NARROW NO-BREAK SPACE */              case 0x202f:    /* NARROW NO-BREAK SPACE */
3790              case 0x205f:    /* MEDIUM MATHEMATICAL SPACE */              case 0x205f:    /* MEDIUM MATHEMATICAL SPACE */
3791              case 0x3000:    /* IDEOGRAPHIC SPACE */              case 0x3000:    /* IDEOGRAPHIC SPACE */
3792              RRETURN(MATCH_NOMATCH);              MRRETURN(MATCH_NOMATCH);
3793              }              }
3794            }            }
3795          break;          break;
# Line 3001  for (;;) Line 3797  for (;;)
3797          case OP_HSPACE:          case OP_HSPACE:
3798          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3799            {            {
3800            if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);            if (eptr >= md->end_subject)
3801                {
3802                SCHECK_PARTIAL();
3803                MRRETURN(MATCH_NOMATCH);
3804                }
3805            GETCHARINC(c, eptr);            GETCHARINC(c, eptr);
3806            switch(c)            switch(c)
3807              {              {
3808              default: RRETURN(MATCH_NOMATCH);              default: MRRETURN(MATCH_NOMATCH);
3809              case 0x09:      /* HT */              case 0x09:      /* HT */
3810              case 0x20:      /* SPACE */              case 0x20:      /* SPACE */
3811              case 0xa0:      /* NBSP */              case 0xa0:      /* NBSP */
# Line 3033  for (;;) Line 3833  for (;;)
3833          case OP_NOT_VSPACE:          case OP_NOT_VSPACE:
3834          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3835            {            {
3836            if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);            if (eptr >= md->end_subject)
3837                {
3838                SCHECK_PARTIAL();
3839                MRRETURN(MATCH_NOMATCH);
3840                }
3841            GETCHARINC(c, eptr);            GETCHARINC(c, eptr);
3842            switch(c)            switch(c)
3843              {              {
# Line 3045  for (;;) Line 3849  for (;;)
3849              case 0x85:      /* NEL */              case 0x85:      /* NEL */
3850              case 0x2028:    /* LINE SEPARATOR */              case 0x2028:    /* LINE SEPARATOR */
3851              case 0x2029:    /* PARAGRAPH SEPARATOR */              case 0x2029:    /* PARAGRAPH SEPARATOR */
3852              RRETURN(MATCH_NOMATCH);              MRRETURN(MATCH_NOMATCH);
3853              }              }
3854            }            }
3855          break;          break;
# Line 3053  for (;;) Line 3857  for (;;)
3857          case OP_VSPACE:          case OP_VSPACE:
3858          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3859            {            {
3860            if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);            if (eptr >= md->end_subject)
3861                {
3862                SCHECK_PARTIAL();
3863                MRRETURN(MATCH_NOMATCH);
3864                }
3865            GETCHARINC(c, eptr);            GETCHARINC(c, eptr);
3866            switch(c)            switch(c)
3867              {              {
3868              default: RRETURN(MATCH_NOMATCH);              default: MRRETURN(MATCH_NOMATCH);
3869              case 0x0a:      /* LF */              case 0x0a:      /* LF */
3870              case 0x0b:      /* VT */              case 0x0b:      /* VT */
3871              case 0x0c:      /* FF */              case 0x0c:      /* FF */
# Line 3073  for (;;) Line 3881  for (;;)
3881          case OP_NOT_DIGIT:          case OP_NOT_DIGIT:
3882          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3883            {            {
3884            if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);            if (eptr >= md->end_subject)
3885                {
3886                SCHECK_PARTIAL();
3887                MRRETURN(MATCH_NOMATCH);
3888                }
3889            GETCHARINC(c, eptr);            GETCHARINC(c, eptr);
3890            if (c < 128 && (md->ctypes[c] & ctype_digit) != 0)            if (c < 128 && (md->ctypes[c] & ctype_digit) != 0)
3891              RRETURN(MATCH_NOMATCH);              MRRETURN(MATCH_NOMATCH);
3892            }            }
3893          break;          break;
3894    
3895          case OP_DIGIT:          case OP_DIGIT:
3896          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3897            {            {
3898            if (eptr >= md->end_subject ||            if (eptr >= md->end_subject)
3899               *eptr >= 128 || (md->ctypes[*eptr++] & ctype_digit) == 0)              {
3900              RRETURN(MATCH_NOMATCH);              SCHECK_PARTIAL();
3901                MRRETURN(MATCH_NOMATCH);
3902                }
3903              if (*eptr >= 128 || (md->ctypes[*eptr++] & ctype_digit) == 0)
3904                MRRETURN(MATCH_NOMATCH);
3905            /* No need to skip more bytes - we know it's a 1-byte character */            /* No need to skip more bytes - we know it's a 1-byte character */
3906            }            }
3907          break;          break;
# Line 3093  for (;;) Line 3909  for (;;)
3909          case OP_NOT_WHITESPACE:          case OP_NOT_WHITESPACE:
3910          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3911            {            {
3912            if (eptr >= md->end_subject ||            if (eptr >= md->end_subject)
3913               (*eptr < 128 && (md->ctypes[*eptr++] & ctype_space) != 0))              {
3914              RRETURN(MATCH_NOMATCH);              SCHECK_PARTIAL();
3915            while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;              MRRETURN(MATCH_NOMATCH);
3916                }
3917              if (*eptr < 128 && (md->ctypes[*eptr] & ctype_space) != 0)
3918                MRRETURN(MATCH_NOMATCH);
3919              while (++eptr < md->end_subject && (*eptr & 0xc0) == 0x80);
3920            }            }
3921          break;          break;
3922    
3923          case OP_WHITESPACE:          case OP_WHITESPACE:
3924          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3925            {            {
3926            if (eptr >= md->end_subject ||            if (eptr >= md->end_subject)
3927               *eptr >= 128 || (md->ctypes[*eptr++] & ctype_space) == 0)              {
3928              RRETURN(MATCH_NOMATCH);              SCHECK_PARTIAL();
3929                MRRETURN(MATCH_NOMATCH);
3930                }
3931              if (*eptr >= 128 || (md->ctypes[*eptr++] & ctype_space) == 0)
3932                MRRETURN(MATCH_NOMATCH);
3933            /* No need to skip more bytes - we know it's a 1-byte character */            /* No need to skip more bytes - we know it's a 1-byte character */
3934            }            }
3935          break;          break;
# Line 3113  for (;;) Line 3937  for (;;)
3937          case OP_NOT_WORDCHAR:          case OP_NOT_WORDCHAR:
3938          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3939            {            {
3940            if (eptr >= md->end_subject ||            if (eptr >= md->end_subject)
3941               (*eptr < 128 && (md->ctypes[*eptr++] & ctype_word) != 0))              {
3942              RRETURN(MATCH_NOMATCH);              SCHECK_PARTIAL();
3943            while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;              MRRETURN(MATCH_NOMATCH);
3944                }
3945              if (*eptr < 128 && (md->ctypes[*eptr] & ctype_word) != 0)
3946                MRRETURN(MATCH_NOMATCH);
3947              while (++eptr < md->end_subject && (*eptr & 0xc0) == 0x80);
3948            }            }
3949          break;          break;
3950    
3951          case OP_WORDCHAR:          case OP_WORDCHAR:
3952          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3953            {            {
3954            if (eptr >= md->end_subject ||            if (eptr >= md->end_subject)
3955               *eptr >= 128 || (md->ctypes[*eptr++] & ctype_word) == 0)              {
3956              RRETURN(MATCH_NOMATCH);              SCHECK_PARTIAL();
3957                MRRETURN(MATCH_NOMATCH);
3958                }
3959              if (*eptr >= 128 || (md->ctypes[*eptr++] & ctype_word) == 0)
3960                MRRETURN(MATCH_NOMATCH);
3961            /* No need to skip more bytes - we know it's a 1-byte character */            /* No need to skip more bytes - we know it's a 1-byte character */
3962            }            }
3963          break;          break;
# Line 3138  for (;;) Line 3970  for (;;)
3970  #endif     /* SUPPORT_UTF8 */  #endif     /* SUPPORT_UTF8 */
3971    
3972        /* Code for the non-UTF-8 case for minimum matching of operators other        /* Code for the non-UTF-8 case for minimum matching of operators other
3973        than OP_PROP and OP_NOTPROP. We can assume that there are the minimum        than OP_PROP and OP_NOTPROP. */
       number of bytes present, as this was tested above. */  
3974    
3975        switch(ctype)        switch(ctype)
3976          {          {
3977          case OP_ANY:          case OP_ANY:
3978          if ((ims & PCRE_DOTALL) == 0)          for (i = 1; i <= min; i++)
3979            {            {
3980            for (i = 1; i <= min; i++)            if (eptr >= md->end_subject)
3981              {              {
3982              if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH);              SCHECK_PARTIAL();
3983              eptr++;              MRRETURN(MATCH_NOMATCH);
3984              }              }
3985              if (IS_NEWLINE(eptr)) MRRETURN(MATCH_NOMATCH);
3986              eptr++;
3987            }            }
         else eptr += min;  
3988          break;          break;
3989    
3990          case OP_ANYBYTE:          case OP_ALLANY:
3991            if (eptr > md->end_subject - min)
3992              {
3993              SCHECK_PARTIAL();
3994              MRRETURN(MATCH_NOMATCH);
3995              }
3996          eptr += min;          eptr += min;
3997          break;          break;
3998    
3999          /* Because of the CRLF case, we can't assume the minimum number of          case OP_ANYBYTE:
4000          bytes are present in this case. */          if (eptr > md->end_subject - min)
4001              {
4002              SCHECK_PARTIAL();
4003              MRRETURN(MATCH_NOMATCH);
4004              }
4005            eptr += min;
4006            break;
4007    
4008          case OP_ANYNL:          case OP_ANYNL:
4009          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
4010            {            {
4011            if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);            if (eptr >= md->end_subject)
4012                {
4013                SCHECK_PARTIAL();
4014                MRRETURN(MATCH_NOMATCH);
4015                }
4016            switch(*eptr++)            switch(*eptr++)
4017              {              {
4018              default: RRETURN(MATCH_NOMATCH);              default: MRRETURN(MATCH_NOMATCH);
4019              case 0x000d:              case 0x000d:
4020              if (eptr < md->end_subject && *eptr == 0x0a) eptr++;              if (eptr < md->end_subject && *eptr == 0x0a) eptr++;
4021              break;              break;
4022              case 0x000a:              case 0x000a:
4023                break;
4024    
4025              case 0x000b:              case 0x000b:
4026              case 0x000c:              case 0x000c:
4027              case 0x0085:              case 0x0085:
4028                if (md->bsr_anycrlf) MRRETURN(MATCH_NOMATCH);
4029              break;              break;
4030              }              }
4031            }            }
# Line 3184  for (;;) Line 4034  for (;;)
4034          case OP_NOT_HSPACE:          case OP_NOT_HSPACE:
4035          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
4036            {            {
4037            if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);            if (eptr >= md->end_subject)
4038                {
4039                SCHECK_PARTIAL();
4040                MRRETURN(MATCH_NOMATCH);
4041                }
4042            switch(*eptr++)            switch(*eptr++)
4043              {              {
4044              default: break;              default: break;
4045              case 0x09:      /* HT */              case 0x09:      /* HT */
4046              case 0x20:      /* SPACE */              case 0x20:      /* SPACE */
4047              case 0xa0:      /* NBSP */              case 0xa0:      /* NBSP */
4048              RRETURN(MATCH_NOMATCH);              MRRETURN(MATCH_NOMATCH);
4049              }              }
4050            }            }
4051          break;          break;
# Line 3199  for (;;) Line 4053  for (;;)
4053          case OP_HSPACE:          case OP_HSPACE:
4054          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
4055            {            {
4056            if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);            if (eptr >= md->end_subject)
4057                {
4058                SCHECK_PARTIAL();
4059                MRRETURN(MATCH_NOMATCH);
4060                }
4061            switch(*eptr++)            switch(*eptr++)
4062              {              {
4063              default: RRETURN(MATCH_NOMATCH);              default: MRRETURN(MATCH_NOMATCH);
4064              case 0x09:      /* HT */              case 0x09:      /* HT */
4065              case 0x20:      /* SPACE */              case 0x20:      /* SPACE */
4066              case 0xa0:      /* NBSP */              case 0xa0:      /* NBSP */
# Line 3214  for (;;) Line 4072  for (;;)
4072          case OP_NOT_VSPACE:          case OP_NOT_VSPACE:
4073          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
4074            {            {
4075            if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);            if (eptr >= md->end_subject)
4076                {
4077                SCHECK_PARTIAL();
4078                MRRETURN(MATCH_NOMATCH);
4079                }
4080            switch(*eptr++)            switch(*eptr++)
4081              {              {
4082              default: break;              default: break;
# Line 3223  for (;;) Line 4085  for (;;)
4085              case 0x0c:      /* FF */              case 0x0c:      /* FF */
4086              case 0x0d:      /* CR */              case 0x0d:      /* CR */
4087              case 0x85:      /* NEL */              case 0x85:      /* NEL */
4088              RRETURN(MATCH_NOMATCH);              MRRETURN(MATCH_NOMATCH);
4089              }              }
4090            }            }
4091          break;          break;
# Line 3231  for (;;) Line 4093  for (;;)
4093          case OP_VSPACE:          case OP_VSPACE:
4094          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
4095            {            {
4096            if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);            if (eptr >= md->end_subject)
4097                {
4098                SCHECK_PARTIAL();
4099                MRRETURN(MATCH_NOMATCH);
4100                }
4101            switch(*eptr++)            switch(*eptr++)
4102              {              {
4103              default: RRETURN(MATCH_NOMATCH);              default: MRRETURN(MATCH_NOMATCH);
4104              case 0x0a:      /* LF */              case 0x0a:      /* LF */
4105              case 0x0b:      /* VT */              case 0x0b:      /* VT */
4106              case 0x0c:      /* FF */              case 0x0c:      /* FF */
# Line 3247  for (;;) Line 4113  for (;;)
4113    
4114          case OP_NOT_DIGIT:          case OP_NOT_DIGIT:
4115          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
4116            if ((md->ctypes[*eptr++] & ctype_digit) != 0) RRETURN(MATCH_NOMATCH);            {
4117              if (eptr >= md->end_subject)
4118                {
4119                SCHECK_PARTIAL();
4120                MRRETURN(MATCH_NOMATCH);
4121                }
4122              if ((md->ctypes[*eptr++] & ctype_digit) != 0) MRRETURN(MATCH_NOMATCH);
4123              }
4124          break;          break;
4125    
4126          case OP_DIGIT:          case OP_DIGIT:
4127          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
4128            if ((md->ctypes[*eptr++] & ctype_digit) == 0) RRETURN(MATCH_NOMATCH);            {
4129              if (eptr >= md->end_subject)
4130                {
4131                SCHECK_PARTIAL();
4132                MRRETURN(MATCH_NOMATCH);
4133                }
4134              if ((md->ctypes[*eptr++] & ctype_digit) == 0) MRRETURN(MATCH_NOMATCH);
4135              }
4136          break;          break;
4137    
4138          case OP_NOT_WHITESPACE:          case OP_NOT_WHITESPACE:
4139          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
4140            if ((md->ctypes[*eptr++] & ctype_space) != 0) RRETURN(MATCH_NOMATCH);            {
4141              if (eptr >= md->end_subject)
4142                {
4143                SCHECK_PARTIAL();
4144                MRRETURN(MATCH_NOMATCH);
4145                }
4146              if ((md->ctypes[*eptr++] & ctype_space) != 0) MRRETURN(MATCH_NOMATCH);
4147              }
4148          break;          break;
4149    
4150          case OP_WHITESPACE:          case OP_WHITESPACE:
4151          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
4152            if ((md->ctypes[*eptr++] & ctype_space) == 0) RRETURN(MATCH_NOMATCH);            {
4153              if (eptr >= md->end_subject)
4154                {
4155                SCHECK_PARTIAL();
4156                MRRETURN(MATCH_NOMATCH);
4157                }
4158              if ((md->ctypes[*eptr++] & ctype_space) == 0) MRRETURN(MATCH_NOMATCH);
4159              }
4160          break;          break;
4161    
4162          case OP_NOT_WORDCHAR:          case OP_NOT_WORDCHAR:
4163          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
4164              {
4165              if (eptr >= md->end_subject)
4166                {
4167                SCHECK_PARTIAL();
4168                MRRETURN(MATCH_NOMATCH);
4169                }
4170            if ((md->ctypes[*eptr++] & ctype_word) != 0)            if ((md->ctypes[*eptr++] & ctype_word) != 0)
4171              RRETURN(MATCH_NOMATCH);              MRRETURN(MATCH_NOMATCH);
4172              }
4173          break;          break;
4174    
4175          case OP_WORDCHAR:          case OP_WORDCHAR:
4176          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
4177              {
4178              if (eptr >= md->end_subject)
4179                {
4180                SCHECK_PARTIAL();
4181                MRRETURN(MATCH_NOMATCH);
4182                }
4183            if ((md->ctypes[*eptr++] & ctype_word) == 0)            if ((md->ctypes[*eptr++] & ctype_word) == 0)
4184              RRETURN(MATCH_NOMATCH);              MRRETURN(MATCH_NOMATCH);
4185              }
4186          break;          break;
4187    
4188          default:          default:
# Line 3302  for (;;) Line 4210  for (;;)
4210              {              {
4211              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM36);              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM36);
4212              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
4213              if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);              if (fi >= max) MRRETURN(MATCH_NOMATCH);
4214              GETCHARINC(c, eptr);              if (eptr >= md->end_subject)
4215              if (prop_fail_result) RRETURN(MATCH_NOMATCH);                {
4216                  SCHECK_PARTIAL();
4217                  MRRETURN(MATCH_NOMATCH);
4218                  }
4219                GETCHARINCTEST(c, eptr);
4220                if (prop_fail_result) MRRETURN(MATCH_NOMATCH);
4221              }              }
4222            /* Control never gets here */            /* Control never gets here */
4223    
# Line 3313  for (;;) Line 4226  for (;;)
4226              {              {
4227              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM37);              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM37);
4228              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
4229              if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);              if (fi >= max) MRRETURN(MATCH_NOMATCH);
4230              GETCHARINC(c, eptr);              if (eptr >= md->end_subject)
4231              prop_category = _pcre_ucp_findprop(c, &prop_chartype, &prop_script);                {
4232                  SCHECK_PARTIAL();
4233                  MRRETURN(MATCH_NOMATCH);
4234                  }
4235                GETCHARINCTEST(c, eptr);
4236                prop_chartype = UCD_CHARTYPE(c);
4237              if ((prop_chartype == ucp_Lu ||              if ((prop_chartype == ucp_Lu ||
4238                   prop_chartype == ucp_Ll ||                   prop_chartype == ucp_Ll ||
4239                   prop_chartype == ucp_Lt) == prop_fail_result)                   prop_chartype == ucp_Lt) == prop_fail_result)
4240                RRETURN(MATCH_NOMATCH);                MRRETURN(MATCH_NOMATCH);
4241              }              }
4242            /* Control never gets here */            /* Control never gets here */
4243    
# Line 3328  for (;;) Line 4246  for (;;)
4246              {              {
4247              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM38);              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM38);
4248              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
4249              if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);              if (fi >= max) MRRETURN(MATCH_NOMATCH);
4250              GETCHARINC(c, eptr);              if (eptr >= md->end_subject)
4251              prop_category = _pcre_ucp_findprop(c, &prop_chartype, &prop_script);                {
4252                  SCHECK_PARTIAL();
4253                  MRRETURN(MATCH_NOMATCH);
4254                  }
4255                GETCHARINCTEST(c, eptr);
4256                prop_category = UCD_CATEGORY(c);
4257              if ((prop_category == prop_value) == prop_fail_result)              if ((prop_category == prop_value) == prop_fail_result)
4258                RRETURN(MATCH_NOMATCH);                MRRETURN(MATCH_NOMATCH);
4259              }              }
4260            /* Control never gets here */            /* Control never gets here */
4261    
# Line 3341  for (;;) Line 4264  for (;;)
4264              {              {
4265              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM39);              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM39);
4266              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
4267              if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);              if (fi >= max) MRRETURN(MATCH_NOMATCH);
4268              GETCHARINC(c, eptr);              if (eptr >= md->end_subject)
4269              prop_category = _pcre_ucp_findprop(c, &prop_chartype, &prop_script);                {
4270                  SCHECK_PARTIAL();
4271                  MRRETURN(MATCH_NOMATCH);
4272                  }
4273                GETCHARINCTEST(c, eptr);
4274                prop_chartype = UCD_CHARTYPE(c);
4275              if ((prop_chartype == prop_value) == prop_fail_result)              if ((prop_chartype == prop_value) == prop_fail_result)
4276                RRETURN(MATCH_NOMATCH);                MRRETURN(MATCH_NOMATCH);
4277              }              }
4278            /* Control never gets here */            /* Control never gets here */
4279    
# Line 3354  for (;;) Line 4282  for (;;)
4282              {              {
4283              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM40);              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM40);
4284              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
4285              if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);              if (fi >= max) MRRETURN(MATCH_NOMATCH);
4286              GETCHARINC(c, eptr);              if (eptr >= md->end_subject)
4287              prop_category = _pcre_ucp_findprop(c, &prop_chartype, &prop_script);                {
4288                  SCHECK_PARTIAL();
4289                  MRRETURN(MATCH_NOMATCH);
4290                  }
4291                GETCHARINCTEST(c, eptr);
4292                prop_script = UCD_SCRIPT(c);
4293              if ((prop_script == prop_value) == prop_fail_result)              if ((prop_script == prop_value) == prop_fail_result)
4294                RRETURN(MATCH_NOMATCH);                MRRETURN(MATCH_NOMATCH);
4295              }              }
4296            /* Control never gets here */            /* Control never gets here */
4297    
4298              case PT_ALNUM:
4299              for (fi = min;; fi++)
4300                {
4301                RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM59);
4302                if (rrc != MATCH_NOMATCH) RRETURN(rrc);
4303                if (fi >= max) MRRETURN(MATCH_NOMATCH);
4304                if (eptr >= md->end_subject)
4305                  {
4306                  SCHECK_PARTIAL();
4307                  MRRETURN(MATCH_NOMATCH);
4308                  }
4309                GETCHARINCTEST(c, eptr);
4310                prop_category = UCD_CATEGORY(c);
4311                if ((prop_category == ucp_L || prop_category == ucp_N)
4312                       == prop_fail_result)
4313                  MRRETURN(MATCH_NOMATCH);
4314                }
4315              /* Control never gets here */
4316    
4317              case PT_SPACE:    /* Perl space */
4318              for (fi = min;; fi++)
4319                {
4320                RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM60);
4321                if (rrc != MATCH_NOMATCH) RRETURN(rrc);
4322                if (fi >= max) MRRETURN(MATCH_NOMATCH);
4323                if (eptr >= md->end_subject)
4324                  {
4325                  SCHECK_PARTIAL();
4326                  MRRETURN(MATCH_NOMATCH);
4327                  }
4328                GETCHARINCTEST(c, eptr);
4329                prop_category = UCD_CATEGORY(c);
4330                if ((prop_category == ucp_Z || c == CHAR_HT || c == CHAR_NL ||
4331                     c == CHAR_FF || c == CHAR_CR)
4332                       == prop_fail_result)
4333                  MRRETURN(MATCH_NOMATCH);
4334                }
4335              /* Control never gets here */
4336    
4337              case PT_PXSPACE:  /* POSIX space */
4338              for (fi = min;; fi++)
4339                {
4340                RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM61);
4341                if (rrc != MATCH_NOMATCH) RRETURN(rrc);
4342                if (fi >= max) MRRETURN(MATCH_NOMATCH);
4343                if (eptr >= md->end_subject)
4344                  {
4345                  SCHECK_PARTIAL();
4346                  MRRETURN(MATCH_NOMATCH);
4347                  }
4348                GETCHARINCTEST(c, eptr);
4349                prop_category = UCD_CATEGORY(c);
4350                if ((prop_category == ucp_Z || c == CHAR_HT || c == CHAR_NL ||
4351                     c == CHAR_VT || c == CHAR_FF || c == CHAR_CR)
4352                       == prop_fail_result)
4353                  MRRETURN(MATCH_NOMATCH);
4354                }
4355              /* Control never gets here */
4356    
4357              case PT_WORD:
4358              for (fi = min;; fi++)
4359                {
4360                RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM62);
4361                if (rrc != MATCH_NOMATCH) RRETURN(rrc);
4362                if (fi >= max) MRRETURN(MATCH_NOMATCH);
4363                if (eptr >= md->end_subject)
4364                  {
4365                  SCHECK_PARTIAL();
4366                  MRRETURN(MATCH_NOMATCH);
4367                  }
4368                GETCHARINCTEST(c, eptr);
4369                prop_category = UCD_CATEGORY(c);
4370                if ((prop_category == ucp_L ||
4371                     prop_category == ucp_N ||
4372                     c == CHAR_UNDERSCORE)
4373                       == prop_fail_result)
4374                  MRRETURN(MATCH_NOMATCH);
4375                }
4376              /* Control never gets here */
4377    
4378              /* This should never occur */
4379    
4380            default:            default:
4381            RRETURN(PCRE_ERROR_INTERNAL);            RRETURN(PCRE_ERROR_INTERNAL);
4382            }            }
# Line 3376  for (;;) Line 4391  for (;;)
4391            {            {
4392            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM41);            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM41);
4393            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
4394            if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);            if (fi >= max) MRRETURN(MATCH_NOMATCH);
4395              if (eptr >= md->end_subject)
4396                {
4397                SCHECK_PARTIAL();
4398                MRRETURN(MATCH_NOMATCH);
4399                }
4400            GETCHARINCTEST(c, eptr);            GETCHARINCTEST(c, eptr);
4401            prop_category = _pcre_ucp_findprop(c, &prop_chartype, &prop_script);            prop_category = UCD_CATEGORY(c);
4402            if (prop_category == ucp_M) RRETURN(MATCH_NOMATCH);            if (prop_category == ucp_M) MRRETURN(MATCH_NOMATCH);
4403            while (eptr < md->end_subject)            while (eptr < md->end_subject)
4404              {              {
4405              int len = 1;              int len = 1;
4406              if (!utf8) c = *eptr; else              if (!utf8) c = *eptr;
4407                {                else { GETCHARLEN(c, eptr, len); }
4408                GETCHARLEN(c, eptr, len);              prop_category = UCD_CATEGORY(c);
               }  
             prop_category = _pcre_ucp_findprop(c, &prop_chartype, &prop_script);  
4409              if (prop_category != ucp_M) break;              if (prop_category != ucp_M) break;
4410              eptr += len;              eptr += len;
4411              }              }
# Line 3405  for (;;) Line 4423  for (;;)
4423            {            {
4424            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM42);            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM42);
4425            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
4426            if (fi >= max || eptr >= md->end_subject ||            if (fi >= max) MRRETURN(MATCH_NOMATCH);
4427                 (ctype == OP_ANY && (ims & PCRE_DOTALL) == 0 &&            if (eptr >= md->end_subject)
4428                  IS_NEWLINE(eptr)))              {
4429              RRETURN(MATCH_NOMATCH);              SCHECK_PARTIAL();
4430                MRRETURN(MATCH_NOMATCH);
4431                }
4432              if (ctype == OP_ANY && IS_NEWLINE(eptr))
4433                MRRETURN(MATCH_NOMATCH);
4434            GETCHARINC(c, eptr);            GETCHARINC(c, eptr);
4435            switch(ctype)            switch(ctype)
4436              {              {
4437              case OP_ANY:        /* This is the DOTALL case */              case OP_ANY:        /* This is the non-NL case */
4438              break;              case OP_ALLANY:
   
4439              case OP_ANYBYTE:              case OP_ANYBYTE:
4440              break;              break;
4441    
4442              case OP_ANYNL:              case OP_ANYNL:
4443              switch(c)              switch(c)
4444                {                {
4445                default: RRETURN(MATCH_NOMATCH);                default: MRRETURN(MATCH_NOMATCH);
4446                case 0x000d:                case 0x000d:
4447                if (eptr < md->end_subject && *eptr == 0x0a) eptr++;                if (eptr < md->end_subject && *eptr == 0x0a) eptr++;
4448                break;                break;
4449                case 0x000a:                case 0x000a:
4450                  break;
4451    
4452                case 0x000b:                case 0x000b:
4453                case 0x000c:                case 0x000c:
4454                case 0x0085:                case 0x0085:
4455                case 0x2028:                case 0x2028:
4456                case 0x2029:                case 0x2029:
4457                  if (md->bsr_anycrlf) MRRETURN(MATCH_NOMATCH);
4458                break;                break;
4459                }                }
4460              break;              break;
# Line 3459  for (;;) Line 4482  for (;;)
4482                case 0x202f:    /* NARROW NO-BREAK SPACE */                case 0x202f:    /* NARROW NO-BREAK SPACE */
4483                case 0x205f:    /* MEDIUM MATHEMATICAL SPACE */                case 0x205f:    /* MEDIUM MATHEMATICAL SPACE */
4484                case 0x3000:    /* IDEOGRAPHIC SPACE */                case 0x3000:    /* IDEOGRAPHIC SPACE */
4485                RRETURN(MATCH_NOMATCH);                MRRETURN(MATCH_NOMATCH);
4486                }                }
4487              break;              break;
4488    
4489              case OP_HSPACE:              case OP_HSPACE:
4490              switch(c)              switch(c)
4491                {                {
4492                default: RRETURN(MATCH_NOMATCH);                default: MRRETURN(MATCH_NOMATCH);
4493                case 0x09:      /* HT */                case 0x09:      /* HT */
4494                case 0x20:      /* SPACE */                case 0x20:      /* SPACE */
4495                case 0xa0:      /* NBSP */                case 0xa0:      /* NBSP */
# Line 3501  for (;;) Line 4524  for (;;)
4524                case 0x85:      /* NEL */                case 0x85:      /* NEL */
4525                case 0x2028:    /* LINE SEPARATOR */                case 0x2028:    /* LINE SEPARATOR */
4526                case 0x2029:    /* PARAGRAPH SEPARATOR */                case 0x2029:    /* PARAGRAPH SEPARATOR */
4527                RRETURN(MATCH_NOMATCH);                MRRETURN(MATCH_NOMATCH);
4528                }                }
4529              break;              break;
4530    
4531              case OP_VSPACE:              case OP_VSPACE:
4532              switch(c)              switch(c)
4533                {                {
4534                default: RRETURN(MATCH_NOMATCH);                default: MRRETURN(MATCH_NOMATCH);
4535                case 0x0a:      /* LF */                case 0x0a:      /* LF */
4536                case 0x0b:      /* VT */                case 0x0b:      /* VT */
4537                case 0x0c:      /* FF */                case 0x0c:      /* FF */
# Line 3522  for (;;) Line 4545  for (;;)
4545    
4546              case OP_NOT_DIGIT:              case OP_NOT_DIGIT:
4547              if (c < 256 && (md->ctypes[c] & ctype_digit) != 0)              if (c < 256 && (md->ctypes[c] & ctype_digit) != 0)
4548                RRETURN(MATCH_NOMATCH);                MRRETURN(MATCH_NOMATCH);
4549              break;              break;
4550    
4551              case OP_DIGIT:              case OP_DIGIT:
4552              if (c >= 256 || (md->ctypes[c] & ctype_digit) == 0)              if (c >= 256 || (md->ctypes[c] & ctype_digit) == 0)
4553                RRETURN(MATCH_NOMATCH);                MRRETURN(MATCH_NOMATCH);
4554              break;              break;
4555    
4556              case OP_NOT_WHITESPACE:              case OP_NOT_WHITESPACE:
4557              if (c < 256 && (md->ctypes[c] & ctype_space) != 0)              if (c < 256 && (md->ctypes[c] & ctype_space) != 0)
4558                RRETURN(MATCH_NOMATCH);                MRRETURN(MATCH_NOMATCH);
4559              break;              break;
4560    
4561              case OP_WHITESPACE:              case OP_WHITESPACE:
4562              if  (c >= 256 || (md->ctypes[c] & ctype_space) == 0)              if  (c >= 256 || (md->ctypes[c] & ctype_space) == 0)
4563                RRETURN(MATCH_NOMATCH);                MRRETURN(MATCH_NOMATCH);
4564              break;              break;
4565    
4566              case OP_NOT_WORDCHAR:              case OP_NOT_WORDCHAR:
4567              if (c < 256 && (md->ctypes[c] & ctype_word) != 0)              if (c < 256 && (md->ctypes[c] & ctype_word) != 0)
4568                RRETURN(MATCH_NOMATCH);                MRRETURN(MATCH_NOMATCH);
4569              break;              break;
4570    
4571              case OP_WORDCHAR:              case OP_WORDCHAR:
4572              if (c >= 256 || (md->ctypes[c] & ctype_word) == 0)              if (c >= 256 || (md->ctypes[c] & ctype_word) == 0)
4573                RRETURN(MATCH_NOMATCH);                MRRETURN(MATCH_NOMATCH);
4574              break;              break;
4575    
4576              default:              default:
# Line 3563  for (;;) Line 4586  for (;;)
4586            {            {
4587            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM43);            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM43);
4588            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
4589            if (fi >= max || eptr >= md->end_subject ||            if (fi >= max) MRRETURN(MATCH_NOMATCH);
4590                 ((ims & PCRE_DOTALL) == 0 && IS_NEWLINE(eptr)))            if (eptr >= md->end_subject)
4591              RRETURN(MATCH_NOMATCH);              {
4592                SCHECK_PARTIAL();
4593                MRRETURN(MATCH_NOMATCH);
4594                }
4595              if (ctype == OP_ANY && IS_NEWLINE(eptr))
4596                MRRETURN(MATCH_NOMATCH);
4597            c = *eptr++;            c = *eptr++;
4598            switch(ctype)            switch(ctype)
4599              {              {
4600              case OP_ANY:   /* This is the DOTALL case */              case OP_ANY:     /* This is the non-NL case */
4601              break;              case OP_ALLANY:
   
4602              case OP_ANYBYTE:              case OP_ANYBYTE:
4603              break;              break;
4604    
4605              case OP_ANYNL:              case OP_ANYNL:
4606              switch(c)              switch(c)
4607                {                {
4608                default: RRETURN(MATCH_NOMATCH);                default: MRRETURN(MATCH_NOMATCH);
4609                case 0x000d:                case 0x000d:
4610                if (eptr < md->end_subject && *eptr == 0x0a) eptr++;                if (eptr < md->end_subject && *eptr == 0x0a) eptr++;
4611                break;                break;
4612    
4613                case 0x000a:                case 0x000a:
4614                  break;
4615    
4616                case 0x000b:                case 0x000b:
4617                case 0x000c:                case 0x000c:
4618                case 0x0085:                case 0x0085:
4619                  if (md->bsr_anycrlf) MRRETURN(MATCH_NOMATCH);
4620                break;                break;
4621                }                }
4622              break;              break;
# Line 3598  for (;;) Line 4628  for (;;)
4628                case 0x09:      /* HT */                case 0x09:      /* HT */
4629                case 0x20:      /* SPACE */                case 0x20:      /* SPACE */
4630                case 0xa0:      /* NBSP */                case 0xa0:      /* NBSP */
4631                RRETURN(MATCH_NOMATCH);                MRRETURN(MATCH_NOMATCH);
4632                }                }
4633              break;              break;
4634    
4635              case OP_HSPACE:              case OP_HSPACE:
4636              switch(c)              switch(c)
4637                {                {
4638                default: RRETURN(MATCH_NOMATCH);                default: MRRETURN(MATCH_NOMATCH);
4639                case 0x09:      /* HT */                case 0x09:      /* HT */
4640                case 0x20:      /* SPACE */                case 0x20:      /* SPACE */
4641                case 0xa0:      /* NBSP */                case 0xa0:      /* NBSP */
# Line 3622  for (;;) Line 4652  for (;;)
4652                case 0x0c:      /* FF */                case 0x0c:      /* FF */
4653                case 0x0d:      /* CR */                case 0x0d:      /* CR */
4654                case 0x85:      /* NEL */                case 0x85:      /* NEL */
4655                RRETURN(MATCH_NOMATCH);                MRRETURN(MATCH_NOMATCH);
4656                }                }
4657              break;              break;
4658    
4659              case OP_VSPACE:              case OP_VSPACE:
4660              switch(c)              switch(c)
4661                {                {
4662                default: RRETURN(MATCH_NOMATCH);                default: MRRETURN(MATCH_NOMATCH);
4663                case 0x0a:      /* LF */                case 0x0a:      /* LF */
4664                case 0x0b:      /* VT */                case 0x0b:      /* VT */
4665                case 0x0c:      /* FF */                case 0x0c:      /* FF */
# Line 3640  for (;;) Line 4670  for (;;)
4670              break;              break;
4671    
4672              case OP_NOT_DIGIT:              case OP_NOT_DIGIT:
4673              if ((md->ctypes[c] & ctype_digit) != 0) RRETURN(MATCH_NOMATCH);              if ((md->ctypes[c] & ctype_digit) != 0) MRRETURN(MATCH_NOMATCH);
4674              break;              break;
4675    
4676              case OP_DIGIT:              case OP_DIGIT:
4677              if ((md->ctypes[c] & ctype_digit) == 0) RRETURN(MATCH_NOMATCH);              if ((md->ctypes[c] & ctype_digit) == 0) MRRETURN(MATCH_NOMATCH);
4678              break;              break;
4679    
4680              case OP_NOT_WHITESPACE:              case OP_NOT_WHITESPACE:
4681              if ((md->ctypes[c] & ctype_space) != 0) RRETURN(MATCH_NOMATCH);              if ((md->ctypes[c] & ctype_space) != 0) MRRETURN(MATCH_NOMATCH);
4682              break;              break;
4683    
4684              case OP_WHITESPACE:              case OP_WHITESPACE:
4685              if  ((md->ctypes[c] & ctype_space) == 0) RRETURN(MATCH_NOMATCH);              if  ((md->ctypes[c] & ctype_space) == 0) MRRETURN(MATCH_NOMATCH);
4686              break;              break;
4687    
4688              case OP_NOT_WORDCHAR:              case OP_NOT_WORDCHAR:
4689              if ((md->ctypes[c] & ctype_word) != 0) RRETURN(MATCH_NOMATCH);              if ((md->ctypes[c] & ctype_word) != 0) MRRETURN(MATCH_NOMATCH);
4690              break;              break;
4691    
4692              case OP_WORDCHAR:              case OP_WORDCHAR:
4693              if ((md->ctypes[c] & ctype_word) == 0) RRETURN(MATCH_NOMATCH);              if ((md->ctypes[c] & ctype_word) == 0) MRRETURN(MATCH_NOMATCH);
4694              break;              break;
4695    
4696              default:              default:
# Line 3688  for (;;) Line 4718  for (;;)
4718            for (i = min; i < max; i++)            for (i = min; i < max; i++)
4719              {              {
4720              int len = 1;              int len = 1;
4721              if (eptr >= md->end_subject) break;              if (eptr >= md->end_subject)
4722              GETCHARLEN(c, eptr, len);                {
4723                  SCHECK_PARTIAL();
4724                  break;
4725                  }
4726                GETCHARLENTEST(c, eptr, len);
4727              if (prop_fail_result) break;              if (prop_fail_result) break;
4728              eptr+= len;              eptr+= len;
4729              }              }
# Line 3699  for (;;) Line 4733  for (;;)
4733            for (i = min; i < max; i++)            for (i = min; i < max; i++)
4734              {              {
4735              int len = 1;              int len = 1;
4736              if (eptr >= md->end_subject) break;              if (eptr >= md->end_subject)
4737              GETCHARLEN(c, eptr, len);                {
4738              prop_category = _pcre_ucp_findprop(c, &prop_chartype, &prop_script);                SCHECK_PARTIAL();
4739                  break;
4740                  }
4741                GETCHARLENTEST(c, eptr, len);
4742                prop_chartype = UCD_CHARTYPE(c);
4743              if ((prop_chartype == ucp_Lu ||              if ((prop_chartype == ucp_Lu ||
4744                   prop_chartype == ucp_Ll ||                   prop_chartype == ucp_Ll ||
4745                   prop_chartype == ucp_Lt) == prop_fail_result)                   prop_chartype == ucp_Lt) == prop_fail_result)
# Line 3714  for (;;) Line 4752  for (;;)
4752            for (i = min; i < max; i++)            for (i = min; i < max; i++)
4753              {              {
4754              int len = 1;              int len = 1;
4755              if (eptr >= md->end_subject) break;              if (eptr >= md->end_subject)
4756              GETCHARLEN(c, eptr, len);                {
4757              prop_category = _pcre_ucp_findprop(c, &prop_chartype, &prop_script);                SCHECK_PARTIAL();
4758                  break;
4759                  }
4760                GETCHARLENTEST(c, eptr, len);
4761                prop_category = UCD_CATEGORY(c);
4762              if ((prop_category == prop_value) == prop_fail_result)              if ((prop_category == prop_value) == prop_fail_result)
4763                break;                break;
4764              eptr+= len;              eptr+= len;
# Line 3727  for (;;) Line 4769  for (;;)
4769            for (i = min; i < max; i++)            for (i = min; i < max; i++)
4770              {              {
4771              int len = 1;              int len = 1;
4772              if (eptr >= md->end_subject) break;              if (eptr >= md->end_subject)
4773              GETCHARLEN(c, eptr, len);                {
4774              prop_category = _pcre_ucp_findprop(c, &prop_chartype, &prop_script);                SCHECK_PARTIAL();
4775                  break;
4776                  }
4777                GETCHARLENTEST(c, eptr, len);
4778                prop_chartype = UCD_CHARTYPE(c);
4779              if ((prop_chartype == prop_value) == prop_fail_result)              if ((prop_chartype == prop_value) == prop_fail_result)
4780                break;                break;
4781              eptr+= len;              eptr+= len;
# Line 3740  for (;;) Line 4786  for (;;)
4786            for (i = min; i < max; i++)            for (i = min; i < max; i++)
4787              {              {
4788              int len = 1;              int len = 1;
4789              if (eptr >= md->end_subject) break;              if (eptr >= md->end_subject)
4790              GETCHARLEN(c, eptr, len);                {
4791              prop_category = _pcre_ucp_findprop(c, &prop_chartype, &prop_script);                SCHECK_PARTIAL();
4792                  break;
4793                  }
4794                GETCHARLENTEST(c, eptr, len);
4795                prop_script = UCD_SCRIPT(c);
4796              if ((prop_script == prop_value) == prop_fail_result)              if ((prop_script == prop_value) == prop_fail_result)
4797                break;                break;
4798              eptr+= len;              eptr+= len;
4799              }              }
4800            break;            break;
4801    
4802              case PT_ALNUM:
4803              for (i = min; i < max; i++)
4804                {
4805                int len = 1;
4806                if (eptr >= md->end_subject)
4807                  {
4808                  SCHECK_PARTIAL();
4809                  break;
4810                  }
4811                GETCHARLENTEST(c, eptr, len);
4812                prop_category = UCD_CATEGORY(c);
4813                if ((prop_category == ucp_L || prop_category == ucp_N)
4814                     == prop_fail_result)
4815                  break;
4816                eptr+= len;
4817                }
4818              break;
4819    
4820              case PT_SPACE:    /* Perl space */
4821              for (i = min; i < max; i++)
4822                {
4823                int len = 1;
4824                if (eptr >= md->end_subject)
4825                  {
4826                  SCHECK_PARTIAL();
4827                  break;
4828                  }
4829                GETCHARLENTEST(c, eptr, len);
4830                prop_category = UCD_CATEGORY(c);
4831                if ((prop_category == ucp_Z || c == CHAR_HT || c == CHAR_NL ||
4832                     c == CHAR_FF || c == CHAR_CR)
4833                     == prop_fail_result)
4834                  break;
4835                eptr+= len;
4836                }
4837              break;
4838    
4839              case PT_PXSPACE:  /* POSIX space */
4840              for (i = min; i < max; i++)
4841                {
4842                int len = 1;
4843                if (eptr >= md->end_subject)
4844                  {
4845                  SCHECK_PARTIAL();
4846                  break;
4847                  }
4848                GETCHARLENTEST(c, eptr, len);
4849                prop_category = UCD_CATEGORY(c);
4850                if ((prop_category == ucp_Z || c == CHAR_HT || c == CHAR_NL ||
4851                     c == CHAR_VT || c == CHAR_FF || c == CHAR_CR)
4852                     == prop_fail_result)
4853                  break;
4854                eptr+= len;
4855                }
4856              break;
4857    
4858              case PT_WORD:
4859              for (i = min; i < max; i++)
4860                {
4861                int len = 1;
4862                if (eptr >= md->end_subject)
4863                  {
4864                  SCHECK_PARTIAL();
4865                  break;
4866                  }
4867                GETCHARLENTEST(c, eptr, len);
4868                prop_category = UCD_CATEGORY(c);
4869                if ((prop_category == ucp_L || prop_category == ucp_N ||
4870                     c == CHAR_UNDERSCORE) == prop_fail_result)
4871                  break;
4872                eptr+= len;
4873                }
4874              break;
4875    
4876              default:
4877              RRETURN(PCRE_ERROR_INTERNAL);
4878            }            }
4879    
4880          /* eptr is now past the end of the maximum run */          /* eptr is now past the end of the maximum run */
# Line 3769  for (;;) Line 4896  for (;;)
4896          {          {
4897          for (i = min; i < max; i++)          for (i = min; i < max; i++)
4898            {            {
4899            if (eptr >= md->end_subject) break;            if (eptr >= md->end_subject)
4900                {
4901                SCHECK_PARTIAL();
4902                break;
4903                }
4904            GETCHARINCTEST(c, eptr);            GETCHARINCTEST(c, eptr);
4905            prop_category = _pcre_ucp_findprop(c, &prop_chartype, &prop_script);            prop_category = UCD_CATEGORY(c);
4906            if (prop_category == ucp_M) break;            if (prop_category == ucp_M) break;
4907            while (eptr < md->end_subject)            while (eptr < md->end_subject)
4908              {              {
# Line 3780  for (;;) Line 4911  for (;;)
4911                {                {
4912                GETCHARLEN(c, eptr, len);                GETCHARLEN(c, eptr, len);
4913                }                }
4914              prop_category = _pcre_ucp_findprop(c, &prop_chartype, &prop_script);              prop_category = UCD_CATEGORY(c);
4915              if (prop_category != ucp_M) break;              if (prop_category != ucp_M) break;
4916              eptr += len;              eptr += len;
4917              }              }
# Line 3789  for (;;) Line 4920  for (;;)
4920          /* eptr is now past the end of the maximum run */          /* eptr is now past the end of the maximum run */
4921    
4922          if (possessive) continue;          if (possessive) continue;
4923    
4924          for(;;)          for(;;)
4925            {            {
4926            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM45);            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM45);
# Line 3802  for (;;) Line 4934  for (;;)
4934                BACKCHAR(eptr);                BACKCHAR(eptr);
4935                GETCHARLEN(c, eptr, len);                GETCHARLEN(c, eptr, len);
4936                }                }
4937              prop_category = _pcre_ucp_findprop(c, &prop_chartype, &prop_script);              prop_category = UCD_CATEGORY(c);
4938              if (prop_category != ucp_M) break;             &