/[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 354 by ph10, Mon Jul 7 16:30:33 2008 UTC revision 518 by ph10, Tue May 18 15:47:01 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-2008 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 71  defined PCRE_ERROR_xxx codes, which are Line 71  defined PCRE_ERROR_xxx codes, which are
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 168  if ((ims & PCRE_CASELESS) != 0) Line 178  if ((ims & PCRE_CASELESS) != 0)
178  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
179    if (md->utf8)    if (md->utf8)
180      {      {
181      USPTR endptr = eptr + length;      USPTR endptr = eptr + length;
182      while (eptr < endptr)      while (eptr < endptr)
183        {        {
184        int c, d;        int c, d;
185        GETCHARINC(c, eptr);        GETCHARINC(c, eptr);
186        GETCHARINC(d, p);        GETCHARINC(d, p);
187        if (c != d && c != UCD_OTHERCASE(d)) return FALSE;        if (c != d && c != UCD_OTHERCASE(d)) return FALSE;
188        }        }
189      }      }
190    else    else
191  #endif  #endif
192  #endif  #endif
193    
194    /* The same code works when not in UTF-8 mode and in UTF-8 mode when there    /* The same code works when not in UTF-8 mode and in UTF-8 mode when there
195    is no UCP support. */    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  /* In the caseful case, we can just compare the bytes, whether or not we
202  are in UTF-8 mode. */  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 245  enum { RM1=1, RM2,  RM3,  RM4,  RM5,  RM Line 255  enum { RM1=1, RM2,  RM3,  RM4,  RM5,  RM
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, RM54 };         RM51,  RM52, RM53, RM54, RM55, RM56, RM57, RM58 };
259    
260  /* 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
261  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
262  actuall used in this definition. */  actually used in this definition. */
263    
264  #ifndef NO_RECURSE  #ifndef NO_RECURSE
265  #define REGISTER register  #define REGISTER register
266    
267  #ifdef DEBUG  #ifdef PCRE_DEBUG
268  #define RMATCH(ra,rb,rc,rd,re,rf,rg,rw) \  #define RMATCH(ra,rb,rc,rd,re,rf,rg,rw) \
269    { \    { \
270    printf("match() called in line %d\n", __LINE__); \    printf("match() called in line %d\n", __LINE__); \
271    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); \
272    printf("to line %d\n", __LINE__); \    printf("to line %d\n", __LINE__); \
273    }    }
274  #define RRETURN(ra) \  #define RRETURN(ra) \
# Line 268  actuall used in this definition. */ Line 278  actuall used in this definition. */
278    }    }
279  #else  #else
280  #define RMATCH(ra,rb,rc,rd,re,rf,rg,rw) \  #define RMATCH(ra,rb,rc,rd,re,rf,rg,rw) \
281    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)
282  #define RRETURN(ra) return ra  #define RRETURN(ra) return ra
283  #endif  #endif
284    
# Line 288  argument of match(), which never changes Line 298  argument of match(), which never changes
298    newframe->Xeptr = ra;\    newframe->Xeptr = ra;\
299    newframe->Xecode = rb;\    newframe->Xecode = rb;\
300    newframe->Xmstart = mstart;\    newframe->Xmstart = mstart;\
301      newframe->Xmarkptr = markptr;\
302    newframe->Xoffset_top = rc;\    newframe->Xoffset_top = rc;\
303    newframe->Xims = re;\    newframe->Xims = re;\
304    newframe->Xeptrb = rf;\    newframe->Xeptrb = rf;\
# Line 322  typedef struct heapframe { Line 333  typedef struct heapframe {
333    
334    /* Function arguments that may change */    /* Function arguments that may change */
335    
336    const uschar *Xeptr;    USPTR Xeptr;
337    const uschar *Xecode;    const uschar *Xecode;
338    const uschar *Xmstart;    USPTR Xmstart;
339      USPTR Xmarkptr;
340    int Xoffset_top;    int Xoffset_top;
341    long int Xims;    long int Xims;
342    eptrblock *Xeptrb;    eptrblock *Xeptrb;
# Line 333  typedef struct heapframe { Line 345  typedef struct heapframe {
345    
346    /* Function local variables */    /* Function local variables */
347    
348    const uschar *Xcallpat;    USPTR Xcallpat;
349    const uschar *Xcharptr;  #ifdef SUPPORT_UTF8
350    const uschar *Xdata;    USPTR Xcharptr;
351    const uschar *Xnext;  #endif
352    const uschar *Xpp;    USPTR Xdata;
353    const uschar *Xprev;    USPTR Xnext;
354    const uschar *Xsaved_eptr;    USPTR Xpp;
355      USPTR Xprev;
356      USPTR Xsaved_eptr;
357    
358    recursion_info Xnew_recursive;    recursion_info Xnew_recursive;
359    
# Line 360  typedef struct heapframe { Line 374  typedef struct heapframe {
374    uschar Xocchars[8];    uschar Xocchars[8];
375  #endif  #endif
376    
377      int Xcodelink;
378    int Xctype;    int Xctype;
379    unsigned int Xfc;    unsigned int Xfc;
380    int Xfi;    int Xfi;
# Line 395  typedef struct heapframe { Line 410  typedef struct heapframe {
410    
411  /* This function is called recursively in many circumstances. Whenever it  /* This function is called recursively in many circumstances. Whenever it
412  returns a negative (error) response, the outer incarnation must also return the  returns a negative (error) response, the outer incarnation must also return the
413  same response.  same response. */
414    
415    /* These macros pack up tests that are used for partial matching, and which
416    appears several times in the code. We set the "hit end" flag if the pointer is
417    at the end of the subject and also past the start of the subject (i.e.
418    something has been matched). For hard partial matching, we then return
419    immediately. The second one is used when we already know we are past the end of
420    the subject. */
421    
422    #define CHECK_PARTIAL()\
423      if (md->partial != 0 && eptr >= md->end_subject && eptr > mstart)\
424        {\
425        md->hitend = TRUE;\
426        if (md->partial > 1) MRRETURN(PCRE_ERROR_PARTIAL);\
427        }
428    
429  Performance note: It might be tempting to extract commonly used fields from the  #define SCHECK_PARTIAL()\
430  md structure (e.g. utf8, end_subject) into individual variables to improve    if (md->partial != 0 && eptr > mstart)\
431        {\
432        md->hitend = TRUE;\
433        if (md->partial > 1) MRRETURN(PCRE_ERROR_PARTIAL);\
434        }
435    
436    
437    /* Performance note: It might be tempting to extract commonly used fields from
438    the md structure (e.g. utf8, end_subject) into individual variables to improve
439  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
440  made performance worse.  made performance worse.
441    
# Line 407  Arguments: Line 444  Arguments:
444     ecode       pointer to current position in compiled code     ecode       pointer to current position in compiled code
445     mstart      pointer to the current match start position (can be modified     mstart      pointer to the current match start position (can be modified
446                   by encountering \K)                   by encountering \K)
447       markptr     pointer to the most recent MARK name, or NULL
448     offset_top  current top pointer     offset_top  current top pointer
449     md          pointer to "static" info for the match     md          pointer to "static" info for the match
450     ims         current /i, /m, and /s options     ims         current /i, /m, and /s options
# Line 420  Arguments: Line 458  Arguments:
458    
459  Returns:       MATCH_MATCH if matched            )  these values are >= 0  Returns:       MATCH_MATCH if matched            )  these values are >= 0
460                 MATCH_NOMATCH if failed to match  )                 MATCH_NOMATCH if failed to match  )
461                   a negative MATCH_xxx value for PRUNE, SKIP, etc
462                 a negative PCRE_ERROR_xxx value if aborted by an error condition                 a negative PCRE_ERROR_xxx value if aborted by an error condition
463                   (e.g. stopped by repeated call or recursion limit)                   (e.g. stopped by repeated call or recursion limit)
464  */  */
465    
466  static int  static int
467  match(REGISTER USPTR eptr, REGISTER const uschar *ecode, const uschar *mstart,  match(REGISTER USPTR eptr, REGISTER const uschar *ecode, USPTR mstart,
468    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,
469    int flags, unsigned int rdepth)    eptrblock *eptrb, int flags, unsigned int rdepth)
470  {  {
471  /* 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,
472  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 439  register unsigned int c;   /* Character Line 478  register unsigned int c;   /* Character
478  register BOOL utf8;        /* Local copy of UTF-8 flag for speed */  register BOOL utf8;        /* Local copy of UTF-8 flag for speed */
479    
480  BOOL minimize, possessive; /* Quantifier options */  BOOL minimize, possessive; /* Quantifier options */
481    int condcode;
482    
483  /* 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
484  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 454  frame->Xprevframe = NULL;            /* Line 494  frame->Xprevframe = NULL;            /*
494  frame->Xeptr = eptr;  frame->Xeptr = eptr;
495  frame->Xecode = ecode;  frame->Xecode = ecode;
496  frame->Xmstart = mstart;  frame->Xmstart = mstart;
497    frame->Xmarkptr = markptr;
498  frame->Xoffset_top = offset_top;  frame->Xoffset_top = offset_top;
499  frame->Xims = ims;  frame->Xims = ims;
500  frame->Xeptrb = eptrb;  frame->Xeptrb = eptrb;
# Line 469  HEAP_RECURSE: Line 510  HEAP_RECURSE:
510  #define eptr               frame->Xeptr  #define eptr               frame->Xeptr
511  #define ecode              frame->Xecode  #define ecode              frame->Xecode
512  #define mstart             frame->Xmstart  #define mstart             frame->Xmstart
513    #define markptr            frame->Xmarkptr
514  #define offset_top         frame->Xoffset_top  #define offset_top         frame->Xoffset_top
515  #define ims                frame->Xims  #define ims                frame->Xims
516  #define eptrb              frame->Xeptrb  #define eptrb              frame->Xeptrb
# Line 481  HEAP_RECURSE: Line 523  HEAP_RECURSE:
523  #define charptr            frame->Xcharptr  #define charptr            frame->Xcharptr
524  #endif  #endif
525  #define callpat            frame->Xcallpat  #define callpat            frame->Xcallpat
526    #define codelink           frame->Xcodelink
527  #define data               frame->Xdata  #define data               frame->Xdata
528  #define next               frame->Xnext  #define next               frame->Xnext
529  #define pp                 frame->Xpp  #define pp                 frame->Xpp
# Line 561  int oclength; Line 604  int oclength;
604  uschar occhars[8];  uschar occhars[8];
605  #endif  #endif
606    
607    int codelink;
608  int ctype;  int ctype;
609  int length;  int length;
610  int max;  int max;
# Line 594  TAIL_RECURSE: Line 638  TAIL_RECURSE:
638  /* 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
639  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
640  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()
641  and a "return", respectively (possibly with some debugging if DEBUG is  and a "return", respectively (possibly with some debugging if PCRE_DEBUG is
642  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
643  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,
644  however, impact performance when true recursion is being used. */  however, impact performance when true recursion is being used. */
# Line 636  for (;;) Line 680  for (;;)
680    minimize = possessive = FALSE;    minimize = possessive = FALSE;
681    op = *ecode;    op = *ecode;
682    
   /* 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;  
   
683    switch(op)    switch(op)
684      {      {
685        case OP_MARK:
686        markptr = ecode + 2;
687        RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode] + ecode[1], offset_top, md,
688          ims, eptrb, flags, RM55);
689    
690        /* A return of MATCH_SKIP_ARG means that matching failed at SKIP with an
691        argument, and we must check whether that argument matches this MARK's
692        argument. It is passed back in md->start_match_ptr (an overloading of that
693        variable). If it does match, we reset that variable to the current subject
694        position and return MATCH_SKIP. Otherwise, pass back the return code
695        unaltered. */
696    
697        if (rrc == MATCH_SKIP_ARG &&
698            strcmp((char *)markptr, (char *)(md->start_match_ptr)) == 0)
699          {
700          md->start_match_ptr = eptr;
701          RRETURN(MATCH_SKIP);
702          }
703    
704        if (md->mark == NULL) md->mark = markptr;
705        RRETURN(rrc);
706    
707      case OP_FAIL:      case OP_FAIL:
708      RRETURN(MATCH_NOMATCH);      MRRETURN(MATCH_NOMATCH);
709    
710        case OP_COMMIT:
711        RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,
712          ims, eptrb, flags, RM52);
713        if (rrc != MATCH_NOMATCH) RRETURN(rrc);
714        MRRETURN(MATCH_COMMIT);
715    
716      case OP_PRUNE:      case OP_PRUNE:
717      RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,      RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,
718        ims, eptrb, flags, RM51);        ims, eptrb, flags, RM51);
719      if (rrc != MATCH_NOMATCH) RRETURN(rrc);      if (rrc != MATCH_NOMATCH) RRETURN(rrc);
720      RRETURN(MATCH_PRUNE);      MRRETURN(MATCH_PRUNE);
721    
722      case OP_COMMIT:      case OP_PRUNE_ARG:
723      RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,      RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode] + ecode[1], offset_top, md,
724        ims, eptrb, flags, RM52);        ims, eptrb, flags, RM56);
725      if (rrc != MATCH_NOMATCH) RRETURN(rrc);      if (rrc != MATCH_NOMATCH) RRETURN(rrc);
726      RRETURN(MATCH_COMMIT);      md->mark = ecode + 2;
727        RRETURN(MATCH_PRUNE);
728    
729      case OP_SKIP:      case OP_SKIP:
730      RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,      RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,
731        ims, eptrb, flags, RM53);        ims, eptrb, flags, RM53);
732      if (rrc != MATCH_NOMATCH) RRETURN(rrc);      if (rrc != MATCH_NOMATCH) RRETURN(rrc);
733      md->start_match_ptr = eptr;   /* Pass back current position */      md->start_match_ptr = eptr;   /* Pass back current position */
734      RRETURN(MATCH_SKIP);      MRRETURN(MATCH_SKIP);
735    
736        case OP_SKIP_ARG:
737        RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode] + ecode[1], offset_top, md,
738          ims, eptrb, flags, RM57);
739        if (rrc != MATCH_NOMATCH) RRETURN(rrc);
740    
741        /* Pass back the current skip name by overloading md->start_match_ptr and
742        returning the special MATCH_SKIP_ARG return code. This will either be
743        caught by a matching MARK, or get to the top, where it is treated the same
744        as PRUNE. */
745    
746        md->start_match_ptr = ecode + 2;
747        RRETURN(MATCH_SKIP_ARG);
748    
749      case OP_THEN:      case OP_THEN:
750      RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,      RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,
751        ims, eptrb, flags, RM54);        ims, eptrb, flags, RM54);
752      if (rrc != MATCH_NOMATCH) RRETURN(rrc);      if (rrc != MATCH_NOMATCH) RRETURN(rrc);
753        MRRETURN(MATCH_THEN);
754    
755        case OP_THEN_ARG:
756        RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode] + ecode[1], offset_top, md,
757          ims, eptrb, flags, RM58);
758        if (rrc != MATCH_NOMATCH) RRETURN(rrc);
759        md->mark = ecode + 2;
760      RRETURN(MATCH_THEN);      RRETURN(MATCH_THEN);
761    
762      /* 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
# Line 693  for (;;) Line 778  for (;;)
778      number = GET2(ecode, 1+LINK_SIZE);      number = GET2(ecode, 1+LINK_SIZE);
779      offset = number << 1;      offset = number << 1;
780    
781  #ifdef DEBUG  #ifdef PCRE_DEBUG
782      printf("start bracket %d\n", number);      printf("start bracket %d\n", number);
783      printf("subject=");      printf("subject=");
784      pchars(eptr, 16, TRUE, md);      pchars(eptr, 16, TRUE, md);
# Line 727  for (;;) Line 812  for (;;)
812        md->offset_vector[offset+1] = save_offset2;        md->offset_vector[offset+1] = save_offset2;
813        md->offset_vector[md->offset_end - number] = save_offset3;        md->offset_vector[md->offset_end - number] = save_offset3;
814    
815          if (rrc != MATCH_THEN) md->mark = markptr;
816        RRETURN(MATCH_NOMATCH);        RRETURN(MATCH_NOMATCH);
817        }        }
818    
# Line 766  for (;;) Line 852  for (;;)
852    
853          RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md, ims,          RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md, ims,
854            eptrb, flags, RM48);            eptrb, flags, RM48);
855            if (rrc == MATCH_NOMATCH) md->mark = markptr;
856          RRETURN(rrc);          RRETURN(rrc);
857          }          }
858    
# Line 787  for (;;) Line 874  for (;;)
874    
875      case OP_COND:      case OP_COND:
876      case OP_SCOND:      case OP_SCOND:
877      if (ecode[LINK_SIZE+1] == OP_RREF)         /* Recursion test */      codelink= GET(ecode, 1);
878    
879        /* Because of the way auto-callout works during compile, a callout item is
880        inserted between OP_COND and an assertion condition. */
881    
882        if (ecode[LINK_SIZE+1] == OP_CALLOUT)
883        {        {
884        offset = GET2(ecode, LINK_SIZE + 2);     /* Recursion group number*/        if (pcre_callout != NULL)
885        condition = md->recursive != NULL &&          {
886          (offset == RREF_ANY || offset == md->recursive->group_num);          pcre_callout_block cb;
887        ecode += condition? 3 : GET(ecode, 1);          cb.version          = 1;   /* Version 1 of the callout block */
888            cb.callout_number   = ecode[LINK_SIZE+2];
889            cb.offset_vector    = md->offset_vector;
890            cb.subject          = (PCRE_SPTR)md->start_subject;
891            cb.subject_length   = md->end_subject - md->start_subject;
892            cb.start_match      = mstart - md->start_subject;
893            cb.current_position = eptr - md->start_subject;
894            cb.pattern_position = GET(ecode, LINK_SIZE + 3);
895            cb.next_item_length = GET(ecode, 3 + 2*LINK_SIZE);
896            cb.capture_top      = offset_top/2;
897            cb.capture_last     = md->capture_last;
898            cb.callout_data     = md->callout_data;
899            if ((rrc = (*pcre_callout)(&cb)) > 0) MRRETURN(MATCH_NOMATCH);
900            if (rrc < 0) RRETURN(rrc);
901            }
902          ecode += _pcre_OP_lengths[OP_CALLOUT];
903          }
904    
905        condcode = ecode[LINK_SIZE+1];
906    
907        /* Now see what the actual condition is */
908    
909        if (condcode == OP_RREF || condcode == OP_NRREF)    /* Recursion test */
910          {
911          if (md->recursive == NULL)                /* Not recursing => FALSE */
912            {
913            condition = FALSE;
914            ecode += GET(ecode, 1);
915            }
916          else
917            {
918            int recno = GET2(ecode, LINK_SIZE + 2);   /* Recursion group number*/
919            condition =  (recno == RREF_ANY || recno == md->recursive->group_num);
920    
921            /* If the test is for recursion into a specific subpattern, and it is
922            false, but the test was set up by name, scan the table to see if the
923            name refers to any other numbers, and test them. The condition is true
924            if any one is set. */
925    
926            if (!condition && condcode == OP_NRREF && recno != RREF_ANY)
927              {
928              uschar *slotA = md->name_table;
929              for (i = 0; i < md->name_count; i++)
930                {
931                if (GET2(slotA, 0) == recno) break;
932                slotA += md->name_entry_size;
933                }
934    
935              /* Found a name for the number - there can be only one; duplicate
936              names for different numbers are allowed, but not vice versa. First
937              scan down for duplicates. */
938    
939              if (i < md->name_count)
940                {
941                uschar *slotB = slotA;
942                while (slotB > md->name_table)
943                  {
944                  slotB -= md->name_entry_size;
945                  if (strcmp((char *)slotA + 2, (char *)slotB + 2) == 0)
946                    {
947                    condition = GET2(slotB, 0) == md->recursive->group_num;
948                    if (condition) break;
949                    }
950                  else break;
951                  }
952    
953                /* Scan up for duplicates */
954    
955                if (!condition)
956                  {
957                  slotB = slotA;
958                  for (i++; i < md->name_count; i++)
959                    {
960                    slotB += md->name_entry_size;
961                    if (strcmp((char *)slotA + 2, (char *)slotB + 2) == 0)
962                      {
963                      condition = GET2(slotB, 0) == md->recursive->group_num;
964                      if (condition) break;
965                      }
966                    else break;
967                    }
968                  }
969                }
970              }
971    
972            /* Chose branch according to the condition */
973    
974            ecode += condition? 3 : GET(ecode, 1);
975            }
976        }        }
977    
978      else if (ecode[LINK_SIZE+1] == OP_CREF)    /* Group used test */      else if (condcode == OP_CREF || condcode == OP_NCREF)  /* Group used test */
979        {        {
980        offset = GET2(ecode, LINK_SIZE+2) << 1;  /* Doubled ref number */        offset = GET2(ecode, LINK_SIZE+2) << 1;  /* Doubled ref number */
981        condition = offset < offset_top && md->offset_vector[offset] >= 0;        condition = offset < offset_top && md->offset_vector[offset] >= 0;
982    
983          /* If the numbered capture is unset, but the reference was by name,
984          scan the table to see if the name refers to any other numbers, and test
985          them. The condition is true if any one is set. This is tediously similar
986          to the code above, but not close enough to try to amalgamate. */
987    
988          if (!condition && condcode == OP_NCREF)
989            {
990            int refno = offset >> 1;
991            uschar *slotA = md->name_table;
992    
993            for (i = 0; i < md->name_count; i++)
994              {
995              if (GET2(slotA, 0) == refno) break;
996              slotA += md->name_entry_size;
997              }
998    
999            /* Found a name for the number - there can be only one; duplicate names
1000            for different numbers are allowed, but not vice versa. First scan down
1001            for duplicates. */
1002    
1003            if (i < md->name_count)
1004              {
1005              uschar *slotB = slotA;
1006              while (slotB > md->name_table)
1007                {
1008                slotB -= md->name_entry_size;
1009                if (strcmp((char *)slotA + 2, (char *)slotB + 2) == 0)
1010                  {
1011                  offset = GET2(slotB, 0) << 1;
1012                  condition = offset < offset_top &&
1013                    md->offset_vector[offset] >= 0;
1014                  if (condition) break;
1015                  }
1016                else break;
1017                }
1018    
1019              /* Scan up for duplicates */
1020    
1021              if (!condition)
1022                {
1023                slotB = slotA;
1024                for (i++; i < md->name_count; i++)
1025                  {
1026                  slotB += md->name_entry_size;
1027                  if (strcmp((char *)slotA + 2, (char *)slotB + 2) == 0)
1028                    {
1029                    offset = GET2(slotB, 0) << 1;
1030                    condition = offset < offset_top &&
1031                      md->offset_vector[offset] >= 0;
1032                    if (condition) break;
1033                    }
1034                  else break;
1035                  }
1036                }
1037              }
1038            }
1039    
1040          /* Chose branch according to the condition */
1041    
1042        ecode += condition? 3 : GET(ecode, 1);        ecode += condition? 3 : GET(ecode, 1);
1043        }        }
1044    
1045      else if (ecode[LINK_SIZE+1] == OP_DEF)     /* DEFINE - always false */      else if (condcode == OP_DEF)     /* DEFINE - always false */
1046        {        {
1047        condition = FALSE;        condition = FALSE;
1048        ecode += GET(ecode, 1);        ecode += GET(ecode, 1);
# Line 829  for (;;) Line 1069  for (;;)
1069        else        else
1070          {          {
1071          condition = FALSE;          condition = FALSE;
1072          ecode += GET(ecode, 1);          ecode += codelink;
1073          }          }
1074        }        }
1075    
# Line 852  for (;;) Line 1092  for (;;)
1092          goto TAIL_RECURSE;          goto TAIL_RECURSE;
1093          }          }
1094        }        }
1095      else                         /* Condition false & no 2nd alternative */      else                         /* Condition false & no alternative */
1096        {        {
1097        ecode += 1 + LINK_SIZE;        ecode += 1 + LINK_SIZE;
1098        }        }
1099      break;      break;
1100    
1101    
1102        /* Before OP_ACCEPT there may be any number of OP_CLOSE opcodes,
1103        to close any currently open capturing brackets. */
1104    
1105        case OP_CLOSE:
1106        number = GET2(ecode, 1);
1107        offset = number << 1;
1108    
1109    #ifdef PCRE_DEBUG
1110          printf("end bracket %d at *ACCEPT", number);
1111          printf("\n");
1112    #endif
1113    
1114        md->capture_last = number;
1115        if (offset >= md->offset_max) md->offset_overflow = TRUE; else
1116          {
1117          md->offset_vector[offset] =
1118            md->offset_vector[md->offset_end - number];
1119          md->offset_vector[offset+1] = eptr - md->start_subject;
1120          if (offset_top <= offset) offset_top = offset + 2;
1121          }
1122        ecode += 3;
1123        break;
1124    
1125    
1126      /* 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
1127      recursion, we should restore the offsets appropriately and continue from      recursion, we should restore the offsets appropriately and continue from
1128      after the call. */      after the call. */
# Line 872  for (;;) Line 1136  for (;;)
1136        md->recursive = rec->prevrec;        md->recursive = rec->prevrec;
1137        memmove(md->offset_vector, rec->offset_save,        memmove(md->offset_vector, rec->offset_save,
1138          rec->saved_max * sizeof(int));          rec->saved_max * sizeof(int));
1139        mstart = rec->save_start;        offset_top = rec->save_offset_top;
1140        ims = original_ims;        ims = original_ims;
1141        ecode = rec->after_call;        ecode = rec->after_call;
1142        break;        break;
1143        }        }
1144    
1145      /* 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
1146      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
1147        the subject. In both cases, backtracking will then try other alternatives,
1148        if any. */
1149    
1150        if (eptr == mstart &&
1151            (md->notempty ||
1152              (md->notempty_atstart &&
1153                mstart == md->start_subject + md->start_offset)))
1154          MRRETURN(MATCH_NOMATCH);
1155    
1156        /* Otherwise, we have a match. */
1157    
     if (md->notempty && eptr == mstart) RRETURN(MATCH_NOMATCH);  
1158      md->end_match_ptr = eptr;           /* Record where we ended */      md->end_match_ptr = eptr;           /* Record where we ended */
1159      md->end_offset_top = offset_top;    /* and how many extracts were taken */      md->end_offset_top = offset_top;    /* and how many extracts were taken */
1160      md->start_match_ptr = mstart;       /* and the start (\K can modify) */      md->start_match_ptr = mstart;       /* and the start (\K can modify) */
1161      RRETURN(MATCH_MATCH);  
1162        /* For some reason, the macros don't work properly if an expression is
1163        given as the argument to MRRETURN when the heap is in use. */
1164    
1165        rrc = (op == OP_END)? MATCH_MATCH : MATCH_ACCEPT;
1166        MRRETURN(rrc);
1167    
1168      /* Change option settings */      /* Change option settings */
1169    
# Line 907  for (;;) Line 1185  for (;;)
1185        {        {
1186        RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, NULL, 0,        RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, NULL, 0,
1187          RM4);          RM4);
1188        if (rrc == MATCH_MATCH) break;        if (rrc == MATCH_MATCH || rrc == MATCH_ACCEPT)
1189            {
1190            mstart = md->start_match_ptr;   /* In case \K reset it */
1191            break;
1192            }
1193        if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);        if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);
1194        ecode += GET(ecode, 1);        ecode += GET(ecode, 1);
1195        }        }
1196      while (*ecode == OP_ALT);      while (*ecode == OP_ALT);
1197      if (*ecode == OP_KET) RRETURN(MATCH_NOMATCH);      if (*ecode == OP_KET) MRRETURN(MATCH_NOMATCH);
1198    
1199      /* If checking an assertion for a condition, return MATCH_MATCH. */      /* If checking an assertion for a condition, return MATCH_MATCH. */
1200    
# Line 926  for (;;) Line 1208  for (;;)
1208      offset_top = md->end_offset_top;      offset_top = md->end_offset_top;
1209      continue;      continue;
1210    
1211      /* Negative assertion: all branches must fail to match */      /* Negative assertion: all branches must fail to match. Encountering SKIP,
1212        PRUNE, or COMMIT means we must assume failure without checking subsequent
1213        branches. */
1214    
1215      case OP_ASSERT_NOT:      case OP_ASSERT_NOT:
1216      case OP_ASSERTBACK_NOT:      case OP_ASSERTBACK_NOT:
# Line 934  for (;;) Line 1218  for (;;)
1218        {        {
1219        RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, NULL, 0,        RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, NULL, 0,
1220          RM5);          RM5);
1221        if (rrc == MATCH_MATCH) RRETURN(MATCH_NOMATCH);        if (rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) MRRETURN(MATCH_NOMATCH);
1222          if (rrc == MATCH_SKIP || rrc == MATCH_PRUNE || rrc == MATCH_COMMIT)
1223            {
1224            do ecode += GET(ecode,1); while (*ecode == OP_ALT);
1225            break;
1226            }
1227        if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);        if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);
1228        ecode += GET(ecode,1);        ecode += GET(ecode,1);
1229        }        }
# Line 958  for (;;) Line 1247  for (;;)
1247        while (i-- > 0)        while (i-- > 0)
1248          {          {
1249          eptr--;          eptr--;
1250          if (eptr < md->start_subject) RRETURN(MATCH_NOMATCH);          if (eptr < md->start_subject) MRRETURN(MATCH_NOMATCH);
1251          BACKCHAR(eptr);          BACKCHAR(eptr);
1252          }          }
1253        }        }
# Line 969  for (;;) Line 1258  for (;;)
1258    
1259        {        {
1260        eptr -= GET(ecode, 1);        eptr -= GET(ecode, 1);
1261        if (eptr < md->start_subject) RRETURN(MATCH_NOMATCH);        if (eptr < md->start_subject) MRRETURN(MATCH_NOMATCH);
1262        }        }
1263    
1264      /* Skip to next op code */      /* Save the earliest consulted character, then skip to next op code */
1265    
1266        if (eptr < md->start_used_ptr) md->start_used_ptr = eptr;
1267      ecode += 1 + LINK_SIZE;      ecode += 1 + LINK_SIZE;
1268      break;      break;
1269    
# Line 997  for (;;) Line 1287  for (;;)
1287        cb.capture_top      = offset_top/2;        cb.capture_top      = offset_top/2;
1288        cb.capture_last     = md->capture_last;        cb.capture_last     = md->capture_last;
1289        cb.callout_data     = md->callout_data;        cb.callout_data     = md->callout_data;
1290        if ((rrc = (*pcre_callout)(&cb)) > 0) RRETURN(MATCH_NOMATCH);        if ((rrc = (*pcre_callout)(&cb)) > 0) MRRETURN(MATCH_NOMATCH);
1291        if (rrc < 0) RRETURN(rrc);        if (rrc < 0) RRETURN(rrc);
1292        }        }
1293      ecode += 2 + 2*LINK_SIZE;      ecode += 2 + 2*LINK_SIZE;
# Line 1052  for (;;) Line 1342  for (;;)
1342    
1343        memcpy(new_recursive.offset_save, md->offset_vector,        memcpy(new_recursive.offset_save, md->offset_vector,
1344              new_recursive.saved_max * sizeof(int));              new_recursive.saved_max * sizeof(int));
1345        new_recursive.save_start = mstart;        new_recursive.save_offset_top = offset_top;
       mstart = eptr;  
1346    
1347        /* 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
1348        restore the offset and recursion data. */        restore the offset and recursion data. */
# Line 1064  for (;;) Line 1353  for (;;)
1353          {          {
1354          RMATCH(eptr, callpat + _pcre_OP_lengths[*callpat], offset_top,          RMATCH(eptr, callpat + _pcre_OP_lengths[*callpat], offset_top,
1355            md, ims, eptrb, flags, RM6);            md, ims, eptrb, flags, RM6);
1356          if (rrc == MATCH_MATCH)          if (rrc == MATCH_MATCH || rrc == MATCH_ACCEPT)
1357            {            {
1358            DPRINTF(("Recursion matched\n"));            DPRINTF(("Recursion matched\n"));
1359            md->recursive = new_recursive.prevrec;            md->recursive = new_recursive.prevrec;
1360            if (new_recursive.offset_save != stacksave)            if (new_recursive.offset_save != stacksave)
1361              (pcre_free)(new_recursive.offset_save);              (pcre_free)(new_recursive.offset_save);
1362            RRETURN(MATCH_MATCH);            MRRETURN(MATCH_MATCH);
1363            }            }
1364          else if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN)          else if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN)
1365            {            {
1366            DPRINTF(("Recursion gave error %d\n", rrc));            DPRINTF(("Recursion gave error %d\n", rrc));
1367              if (new_recursive.offset_save != stacksave)
1368                (pcre_free)(new_recursive.offset_save);
1369            RRETURN(rrc);            RRETURN(rrc);
1370            }            }
1371    
# Line 1089  for (;;) Line 1380  for (;;)
1380        md->recursive = new_recursive.prevrec;        md->recursive = new_recursive.prevrec;
1381        if (new_recursive.offset_save != stacksave)        if (new_recursive.offset_save != stacksave)
1382          (pcre_free)(new_recursive.offset_save);          (pcre_free)(new_recursive.offset_save);
1383        RRETURN(MATCH_NOMATCH);        MRRETURN(MATCH_NOMATCH);
1384        }        }
1385      /* Control never reaches here */      /* Control never reaches here */
1386    
# Line 1098  for (;;) Line 1389  for (;;)
1389      a move back into the brackets. Friedl calls these "atomic" subpatterns.      a move back into the brackets. Friedl calls these "atomic" subpatterns.
1390      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
1391      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
1392      the end of a normal bracket, leaving the subject pointer. */      the end of a normal bracket, leaving the subject pointer, but resetting
1393        the start-of-match value in case it was changed by \K. */
1394    
1395      case OP_ONCE:      case OP_ONCE:
1396      prev = ecode;      prev = ecode;
# Line 1107  for (;;) Line 1399  for (;;)
1399      do      do
1400        {        {
1401        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);
1402        if (rrc == MATCH_MATCH) break;        if (rrc == MATCH_MATCH)  /* Note: _not_ MATCH_ACCEPT */
1403            {
1404            mstart = md->start_match_ptr;
1405            break;
1406            }
1407        if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);        if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);
1408        ecode += GET(ecode,1);        ecode += GET(ecode,1);
1409        }        }
# Line 1226  for (;;) Line 1522  for (;;)
1522        }        }
1523      else saved_eptr = NULL;      else saved_eptr = NULL;
1524    
1525      /* 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
1526      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
1527      assertions. Do this also for the "once" (atomic) groups. */      use by positive assertions. We also need to record the match start in case
1528        it was changed by \K. */
1529    
1530      if (*prev == OP_ASSERT || *prev == OP_ASSERT_NOT ||      if (*prev == OP_ASSERT || *prev == OP_ASSERT_NOT ||
1531          *prev == OP_ASSERTBACK || *prev == OP_ASSERTBACK_NOT ||          *prev == OP_ASSERTBACK || *prev == OP_ASSERTBACK_NOT ||
# Line 1236  for (;;) Line 1533  for (;;)
1533        {        {
1534        md->end_match_ptr = eptr;      /* For ONCE */        md->end_match_ptr = eptr;      /* For ONCE */
1535        md->end_offset_top = offset_top;        md->end_offset_top = offset_top;
1536        RRETURN(MATCH_MATCH);        md->start_match_ptr = mstart;
1537          MRRETURN(MATCH_MATCH);
1538        }        }
1539    
1540      /* 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 1250  for (;;) Line 1548  for (;;)
1548        number = GET2(prev, 1+LINK_SIZE);        number = GET2(prev, 1+LINK_SIZE);
1549        offset = number << 1;        offset = number << 1;
1550    
1551  #ifdef DEBUG  #ifdef PCRE_DEBUG
1552        printf("end bracket %d", number);        printf("end bracket %d", number);
1553        printf("\n");        printf("\n");
1554  #endif  #endif
# Line 1272  for (;;) Line 1570  for (;;)
1570          recursion_info *rec = md->recursive;          recursion_info *rec = md->recursive;
1571          DPRINTF(("Recursion (%d) succeeded - continuing\n", number));          DPRINTF(("Recursion (%d) succeeded - continuing\n", number));
1572          md->recursive = rec->prevrec;          md->recursive = rec->prevrec;
         mstart = rec->save_start;  
1573          memcpy(md->offset_vector, rec->offset_save,          memcpy(md->offset_vector, rec->offset_save,
1574            rec->saved_max * sizeof(int));            rec->saved_max * sizeof(int));
1575            offset_top = rec->save_offset_top;
1576          ecode = rec->after_call;          ecode = rec->after_call;
1577          ims = original_ims;          ims = original_ims;
1578          break;          break;
# Line 1331  for (;;) Line 1629  for (;;)
1629      /* Start of subject unless notbol, or after internal newline if multiline */      /* Start of subject unless notbol, or after internal newline if multiline */
1630    
1631      case OP_CIRC:      case OP_CIRC:
1632      if (md->notbol && eptr == md->start_subject) RRETURN(MATCH_NOMATCH);      if (md->notbol && eptr == md->start_subject) MRRETURN(MATCH_NOMATCH);
1633      if ((ims & PCRE_MULTILINE) != 0)      if ((ims & PCRE_MULTILINE) != 0)
1634        {        {
1635        if (eptr != md->start_subject &&        if (eptr != md->start_subject &&
1636            (eptr == md->end_subject || !WAS_NEWLINE(eptr)))            (eptr == md->end_subject || !WAS_NEWLINE(eptr)))
1637          RRETURN(MATCH_NOMATCH);          MRRETURN(MATCH_NOMATCH);
1638        ecode++;        ecode++;
1639        break;        break;
1640        }        }
# Line 1345  for (;;) Line 1643  for (;;)
1643      /* Start of subject assertion */      /* Start of subject assertion */
1644    
1645      case OP_SOD:      case OP_SOD:
1646      if (eptr != md->start_subject) RRETURN(MATCH_NOMATCH);      if (eptr != md->start_subject) MRRETURN(MATCH_NOMATCH);
1647      ecode++;      ecode++;
1648      break;      break;
1649    
1650      /* Start of match assertion */      /* Start of match assertion */
1651    
1652      case OP_SOM:      case OP_SOM:
1653      if (eptr != md->start_subject + md->start_offset) RRETURN(MATCH_NOMATCH);      if (eptr != md->start_subject + md->start_offset) MRRETURN(MATCH_NOMATCH);
1654      ecode++;      ecode++;
1655      break;      break;
1656    
# Line 1370  for (;;) Line 1668  for (;;)
1668      if ((ims & PCRE_MULTILINE) != 0)      if ((ims & PCRE_MULTILINE) != 0)
1669        {        {
1670        if (eptr < md->end_subject)        if (eptr < md->end_subject)
1671          { if (!IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH); }          { if (!IS_NEWLINE(eptr)) MRRETURN(MATCH_NOMATCH); }
1672        else        else
1673          { if (md->noteol) RRETURN(MATCH_NOMATCH); }          { if (md->noteol) MRRETURN(MATCH_NOMATCH); }
1674        ecode++;        ecode++;
1675        break;        break;
1676        }        }
1677      else      else
1678        {        {
1679        if (md->noteol) RRETURN(MATCH_NOMATCH);        if (md->noteol) MRRETURN(MATCH_NOMATCH);
1680        if (!md->endonly)        if (!md->endonly)
1681          {          {
1682          if (eptr != md->end_subject &&          if (eptr != md->end_subject &&
1683              (!IS_NEWLINE(eptr) || eptr != md->end_subject - md->nllen))              (!IS_NEWLINE(eptr) || eptr != md->end_subject - md->nllen))
1684            RRETURN(MATCH_NOMATCH);            MRRETURN(MATCH_NOMATCH);
1685          ecode++;          ecode++;
1686          break;          break;
1687          }          }
# Line 1393  for (;;) Line 1691  for (;;)
1691      /* End of subject assertion (\z) */      /* End of subject assertion (\z) */
1692    
1693      case OP_EOD:      case OP_EOD:
1694      if (eptr < md->end_subject) RRETURN(MATCH_NOMATCH);      if (eptr < md->end_subject) MRRETURN(MATCH_NOMATCH);
1695      ecode++;      ecode++;
1696      break;      break;
1697    
# Line 1402  for (;;) Line 1700  for (;;)
1700      case OP_EODN:      case OP_EODN:
1701      if (eptr != md->end_subject &&      if (eptr != md->end_subject &&
1702          (!IS_NEWLINE(eptr) || eptr != md->end_subject - md->nllen))          (!IS_NEWLINE(eptr) || eptr != md->end_subject - md->nllen))
1703        RRETURN(MATCH_NOMATCH);        MRRETURN(MATCH_NOMATCH);
1704      ecode++;      ecode++;
1705      break;      break;
1706    
# Line 1414  for (;;) Line 1712  for (;;)
1712    
1713        /* Find out if the previous and current characters are "word" characters.        /* Find out if the previous and current characters are "word" characters.
1714        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
1715        be "non-word" characters. */        be "non-word" characters. Remember the earliest consulted character for
1716          partial matching. */
1717    
1718  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
1719        if (utf8)        if (utf8)
1720          {          {
1721            /* Get status of previous character */
1722    
1723          if (eptr == md->start_subject) prev_is_word = FALSE; else          if (eptr == md->start_subject) prev_is_word = FALSE; else
1724            {            {
1725            const uschar *lastptr = eptr - 1;            USPTR lastptr = eptr - 1;
1726            while((*lastptr & 0xc0) == 0x80) lastptr--;            while((*lastptr & 0xc0) == 0x80) lastptr--;
1727              if (lastptr < md->start_used_ptr) md->start_used_ptr = lastptr;
1728            GETCHAR(c, lastptr);            GETCHAR(c, lastptr);
1729    #ifdef SUPPORT_UCP
1730              if (md->use_ucp)
1731                {
1732                if (c == '_') prev_is_word = TRUE; else
1733                  {
1734                  int cat = UCD_CATEGORY(c);
1735                  prev_is_word = (cat == ucp_L || cat == ucp_N);
1736                  }
1737                }
1738              else
1739    #endif
1740            prev_is_word = c < 256 && (md->ctypes[c] & ctype_word) != 0;            prev_is_word = c < 256 && (md->ctypes[c] & ctype_word) != 0;
1741            }            }
1742          if (eptr >= md->end_subject) cur_is_word = FALSE; else  
1743            /* Get status of next character */
1744    
1745            if (eptr >= md->end_subject)
1746              {
1747              SCHECK_PARTIAL();
1748              cur_is_word = FALSE;
1749              }
1750            else
1751            {            {
1752            GETCHAR(c, eptr);            GETCHAR(c, eptr);
1753    #ifdef SUPPORT_UCP
1754              if (md->use_ucp)
1755                {
1756                if (c == '_') cur_is_word = TRUE; else
1757                  {
1758                  int cat = UCD_CATEGORY(c);
1759                  cur_is_word = (cat == ucp_L || cat == ucp_N);
1760                  }
1761                }
1762              else
1763    #endif
1764            cur_is_word = c < 256 && (md->ctypes[c] & ctype_word) != 0;            cur_is_word = c < 256 && (md->ctypes[c] & ctype_word) != 0;
1765            }            }
1766          }          }
1767        else        else
1768  #endif  #endif
1769    
1770        /* More streamlined when not in UTF-8 mode */        /* Not in UTF-8 mode, but we may still have PCRE_UCP set, and for
1771          consistency with the behaviour of \w we do use it in this case. */
1772    
1773          {          {
1774          prev_is_word = (eptr != md->start_subject) &&          /* Get status of previous character */
1775            ((md->ctypes[eptr[-1]] & ctype_word) != 0);  
1776          cur_is_word = (eptr < md->end_subject) &&          if (eptr == md->start_subject) prev_is_word = FALSE; else
1777            ((md->ctypes[*eptr] & ctype_word) != 0);            {
1778              if (eptr <= md->start_used_ptr) md->start_used_ptr = eptr - 1;
1779    #ifdef SUPPORT_UCP
1780              if (md->use_ucp)
1781                {
1782                c = eptr[-1];
1783                if (c == '_') prev_is_word = TRUE; else
1784                  {
1785                  int cat = UCD_CATEGORY(c);
1786                  prev_is_word = (cat == ucp_L || cat == ucp_N);
1787                  }
1788                }
1789              else
1790    #endif
1791              prev_is_word = ((md->ctypes[eptr[-1]] & ctype_word) != 0);
1792              }
1793    
1794            /* Get status of next character */
1795    
1796            if (eptr >= md->end_subject)
1797              {
1798              SCHECK_PARTIAL();
1799              cur_is_word = FALSE;
1800              }
1801            else
1802    #ifdef SUPPORT_UCP
1803            if (md->use_ucp)
1804              {
1805              c = *eptr;
1806              if (c == '_') cur_is_word = TRUE; else
1807                {
1808                int cat = UCD_CATEGORY(c);
1809                cur_is_word = (cat == ucp_L || cat == ucp_N);
1810                }
1811              }
1812            else
1813    #endif
1814            cur_is_word = ((md->ctypes[*eptr] & ctype_word) != 0);
1815          }          }
1816    
1817        /* Now see if the situation is what we want */        /* Now see if the situation is what we want */
1818    
1819        if ((*ecode++ == OP_WORD_BOUNDARY)?        if ((*ecode++ == OP_WORD_BOUNDARY)?
1820             cur_is_word == prev_is_word : cur_is_word != prev_is_word)             cur_is_word == prev_is_word : cur_is_word != prev_is_word)
1821          RRETURN(MATCH_NOMATCH);          MRRETURN(MATCH_NOMATCH);
1822        }        }
1823      break;      break;
1824    
1825      /* Match a single character type; inline for speed */      /* Match a single character type; inline for speed */
1826    
1827      case OP_ANY:      case OP_ANY:
1828      if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH);      if (IS_NEWLINE(eptr)) MRRETURN(MATCH_NOMATCH);
1829      /* Fall through */      /* Fall through */
1830    
1831      case OP_ALLANY:      case OP_ALLANY:
1832      if (eptr++ >= md->end_subject) RRETURN(MATCH_NOMATCH);      if (eptr++ >= md->end_subject)
1833          {
1834          SCHECK_PARTIAL();
1835          MRRETURN(MATCH_NOMATCH);
1836          }
1837      if (utf8) while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;      if (utf8) while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;
1838      ecode++;      ecode++;
1839      break;      break;
# Line 1468  for (;;) Line 1842  for (;;)
1842      any byte, even newline, independent of the setting of PCRE_DOTALL. */      any byte, even newline, independent of the setting of PCRE_DOTALL. */
1843    
1844      case OP_ANYBYTE:      case OP_ANYBYTE:
1845      if (eptr++ >= md->end_subject) RRETURN(MATCH_NOMATCH);      if (eptr++ >= md->end_subject)
1846          {
1847          SCHECK_PARTIAL();
1848          MRRETURN(MATCH_NOMATCH);
1849          }
1850      ecode++;      ecode++;
1851      break;      break;
1852    
1853      case OP_NOT_DIGIT:      case OP_NOT_DIGIT:
1854      if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);      if (eptr >= md->end_subject)
1855          {
1856          SCHECK_PARTIAL();
1857          MRRETURN(MATCH_NOMATCH);
1858          }
1859      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
1860      if (      if (
1861  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
# Line 1481  for (;;) Line 1863  for (;;)
1863  #endif  #endif
1864         (md->ctypes[c] & ctype_digit) != 0         (md->ctypes[c] & ctype_digit) != 0
1865         )         )
1866        RRETURN(MATCH_NOMATCH);        MRRETURN(MATCH_NOMATCH);
1867      ecode++;      ecode++;
1868      break;      break;
1869    
1870      case OP_DIGIT:      case OP_DIGIT:
1871      if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);      if (eptr >= md->end_subject)
1872          {
1873          SCHECK_PARTIAL();
1874          MRRETURN(MATCH_NOMATCH);
1875          }
1876      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
1877      if (      if (
1878  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
# Line 1494  for (;;) Line 1880  for (;;)
1880  #endif  #endif
1881         (md->ctypes[c] & ctype_digit) == 0         (md->ctypes[c] & ctype_digit) == 0
1882         )         )
1883        RRETURN(MATCH_NOMATCH);        MRRETURN(MATCH_NOMATCH);
1884      ecode++;      ecode++;
1885      break;      break;
1886    
1887      case OP_NOT_WHITESPACE:      case OP_NOT_WHITESPACE:
1888      if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);      if (eptr >= md->end_subject)
1889          {
1890          SCHECK_PARTIAL();
1891          MRRETURN(MATCH_NOMATCH);
1892          }
1893      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
1894      if (      if (
1895  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
# Line 1507  for (;;) Line 1897  for (;;)
1897  #endif  #endif
1898         (md->ctypes[c] & ctype_space) != 0         (md->ctypes[c] & ctype_space) != 0
1899         )         )
1900        RRETURN(MATCH_NOMATCH);        MRRETURN(MATCH_NOMATCH);
1901      ecode++;      ecode++;
1902      break;      break;
1903    
1904      case OP_WHITESPACE:      case OP_WHITESPACE:
1905      if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);      if (eptr >= md->end_subject)
1906          {
1907          SCHECK_PARTIAL();
1908          MRRETURN(MATCH_NOMATCH);
1909          }
1910      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
1911      if (      if (
1912  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
# Line 1520  for (;;) Line 1914  for (;;)
1914  #endif  #endif
1915         (md->ctypes[c] & ctype_space) == 0         (md->ctypes[c] & ctype_space) == 0
1916         )         )
1917        RRETURN(MATCH_NOMATCH);        MRRETURN(MATCH_NOMATCH);
1918      ecode++;      ecode++;
1919      break;      break;
1920    
1921      case OP_NOT_WORDCHAR:      case OP_NOT_WORDCHAR:
1922      if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);      if (eptr >= md->end_subject)
1923          {
1924          SCHECK_PARTIAL();
1925          MRRETURN(MATCH_NOMATCH);
1926          }
1927      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
1928      if (      if (
1929  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
# Line 1533  for (;;) Line 1931  for (;;)
1931  #endif  #endif
1932         (md->ctypes[c] & ctype_word) != 0         (md->ctypes[c] & ctype_word) != 0
1933         )         )
1934        RRETURN(MATCH_NOMATCH);        MRRETURN(MATCH_NOMATCH);
1935      ecode++;      ecode++;
1936      break;      break;
1937    
1938      case OP_WORDCHAR:      case OP_WORDCHAR:
1939      if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);      if (eptr >= md->end_subject)
1940          {
1941          SCHECK_PARTIAL();
1942          MRRETURN(MATCH_NOMATCH);
1943          }
1944      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
1945      if (      if (
1946  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
# Line 1546  for (;;) Line 1948  for (;;)
1948  #endif  #endif
1949         (md->ctypes[c] & ctype_word) == 0         (md->ctypes[c] & ctype_word) == 0
1950         )         )
1951        RRETURN(MATCH_NOMATCH);        MRRETURN(MATCH_NOMATCH);
1952      ecode++;      ecode++;
1953      break;      break;
1954    
1955      case OP_ANYNL:      case OP_ANYNL:
1956      if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);      if (eptr >= md->end_subject)
1957          {
1958          SCHECK_PARTIAL();
1959          MRRETURN(MATCH_NOMATCH);
1960          }
1961      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
1962      switch(c)      switch(c)
1963        {        {
1964        default: RRETURN(MATCH_NOMATCH);        default: MRRETURN(MATCH_NOMATCH);
1965        case 0x000d:        case 0x000d:
1966        if (eptr < md->end_subject && *eptr == 0x0a) eptr++;        if (eptr < md->end_subject && *eptr == 0x0a) eptr++;
1967        break;        break;
# Line 1568  for (;;) Line 1974  for (;;)
1974        case 0x0085:        case 0x0085:
1975        case 0x2028:        case 0x2028:
1976        case 0x2029:        case 0x2029:
1977        if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH);        if (md->bsr_anycrlf) MRRETURN(MATCH_NOMATCH);
1978        break;        break;
1979        }        }
1980      ecode++;      ecode++;
1981      break;      break;
1982    
1983      case OP_NOT_HSPACE:      case OP_NOT_HSPACE:
1984      if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);      if (eptr >= md->end_subject)
1985          {
1986          SCHECK_PARTIAL();
1987          MRRETURN(MATCH_NOMATCH);
1988          }
1989      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
1990      switch(c)      switch(c)
1991        {        {
# Line 1599  for (;;) Line 2009  for (;;)
2009        case 0x202f:    /* NARROW NO-BREAK SPACE */        case 0x202f:    /* NARROW NO-BREAK SPACE */
2010        case 0x205f:    /* MEDIUM MATHEMATICAL SPACE */        case 0x205f:    /* MEDIUM MATHEMATICAL SPACE */
2011        case 0x3000:    /* IDEOGRAPHIC SPACE */        case 0x3000:    /* IDEOGRAPHIC SPACE */
2012        RRETURN(MATCH_NOMATCH);        MRRETURN(MATCH_NOMATCH);
2013        }        }
2014      ecode++;      ecode++;
2015      break;      break;
2016    
2017      case OP_HSPACE:      case OP_HSPACE:
2018      if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);      if (eptr >= md->end_subject)
2019          {
2020          SCHECK_PARTIAL();
2021          MRRETURN(MATCH_NOMATCH);
2022          }
2023      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
2024      switch(c)      switch(c)
2025        {        {
2026        default: RRETURN(MATCH_NOMATCH);        default: MRRETURN(MATCH_NOMATCH);
2027        case 0x09:      /* HT */        case 0x09:      /* HT */
2028        case 0x20:      /* SPACE */        case 0x20:      /* SPACE */
2029        case 0xa0:      /* NBSP */        case 0xa0:      /* NBSP */
# Line 1635  for (;;) Line 2049  for (;;)
2049      break;      break;
2050    
2051      case OP_NOT_VSPACE:      case OP_NOT_VSPACE:
2052      if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);      if (eptr >= md->end_subject)
2053          {
2054          SCHECK_PARTIAL();
2055          MRRETURN(MATCH_NOMATCH);
2056          }
2057      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
2058      switch(c)      switch(c)
2059        {        {
# Line 1647  for (;;) Line 2065  for (;;)
2065        case 0x85:      /* NEL */        case 0x85:      /* NEL */
2066        case 0x2028:    /* LINE SEPARATOR */        case 0x2028:    /* LINE SEPARATOR */
2067        case 0x2029:    /* PARAGRAPH SEPARATOR */        case 0x2029:    /* PARAGRAPH SEPARATOR */
2068        RRETURN(MATCH_NOMATCH);        MRRETURN(MATCH_NOMATCH);
2069        }        }
2070      ecode++;      ecode++;
2071      break;      break;
2072    
2073      case OP_VSPACE:      case OP_VSPACE:
2074      if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);      if (eptr >= md->end_subject)
2075          {
2076          SCHECK_PARTIAL();
2077          MRRETURN(MATCH_NOMATCH);
2078          }
2079      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
2080      switch(c)      switch(c)
2081        {        {
2082        default: RRETURN(MATCH_NOMATCH);        default: MRRETURN(MATCH_NOMATCH);
2083        case 0x0a:      /* LF */        case 0x0a:      /* LF */
2084        case 0x0b:      /* VT */        case 0x0b:      /* VT */
2085        case 0x0c:      /* FF */        case 0x0c:      /* FF */
# Line 1676  for (;;) Line 2098  for (;;)
2098    
2099      case OP_PROP:      case OP_PROP:
2100      case OP_NOTPROP:      case OP_NOTPROP:
2101      if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);      if (eptr >= md->end_subject)
2102          {
2103          SCHECK_PARTIAL();
2104          MRRETURN(MATCH_NOMATCH);
2105          }
2106      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
2107        {        {
2108        const ucd_record * prop = GET_UCD(c);        const ucd_record *prop = GET_UCD(c);
2109    
2110        switch(ecode[1])        switch(ecode[1])
2111          {          {
2112          case PT_ANY:          case PT_ANY:
2113          if (op == OP_NOTPROP) RRETURN(MATCH_NOMATCH);          if (op == OP_NOTPROP) MRRETURN(MATCH_NOMATCH);
2114          break;          break;
2115    
2116          case PT_LAMP:          case PT_LAMP:
2117          if ((prop->chartype == ucp_Lu ||          if ((prop->chartype == ucp_Lu ||
2118               prop->chartype == ucp_Ll ||               prop->chartype == ucp_Ll ||
2119               prop->chartype == ucp_Lt) == (op == OP_NOTPROP))               prop->chartype == ucp_Lt) == (op == OP_NOTPROP))
2120            RRETURN(MATCH_NOMATCH);            MRRETURN(MATCH_NOMATCH);
2121           break;          break;
2122    
2123          case PT_GC:          case PT_GC:
2124          if ((ecode[2] != _pcre_ucp_gentype[prop->chartype]) == (op == OP_PROP))          if ((ecode[2] != _pcre_ucp_gentype[prop->chartype]) == (op == OP_PROP))
2125            RRETURN(MATCH_NOMATCH);            MRRETURN(MATCH_NOMATCH);
2126          break;          break;
2127    
2128          case PT_PC:          case PT_PC:
2129          if ((ecode[2] != prop->chartype) == (op == OP_PROP))          if ((ecode[2] != prop->chartype) == (op == OP_PROP))
2130            RRETURN(MATCH_NOMATCH);            MRRETURN(MATCH_NOMATCH);
2131          break;          break;
2132    
2133          case PT_SC:          case PT_SC:
2134          if ((ecode[2] != prop->script) == (op == OP_PROP))          if ((ecode[2] != prop->script) == (op == OP_PROP))
2135            RRETURN(MATCH_NOMATCH);            MRRETURN(MATCH_NOMATCH);
2136          break;          break;
2137    
2138            /* These are specials */
2139    
2140            case PT_ALNUM:
2141            if ((_pcre_ucp_gentype[prop->chartype] == ucp_L ||
2142                 _pcre_ucp_gentype[prop->chartype] == ucp_N) == (op == OP_NOTPROP))
2143              MRRETURN(MATCH_NOMATCH);
2144            break;
2145    
2146            case PT_SPACE:    /* Perl space */
2147            if ((_pcre_ucp_gentype[prop->chartype] == ucp_Z ||
2148                 c == CHAR_HT || c == CHAR_NL || c == CHAR_FF || c == CHAR_CR)
2149                   == (op == OP_NOTPROP))
2150              MRRETURN(MATCH_NOMATCH);
2151            break;
2152    
2153            case PT_PXSPACE:  /* POSIX space */
2154            if ((_pcre_ucp_gentype[prop->chartype] == ucp_Z ||
2155                 c == CHAR_HT || c == CHAR_NL || c == CHAR_VT ||
2156                 c == CHAR_FF || c == CHAR_CR)
2157                   == (op == OP_NOTPROP))
2158              MRRETURN(MATCH_NOMATCH);
2159            break;
2160    
2161            case PT_WORD:
2162            if ((_pcre_ucp_gentype[prop->chartype] == ucp_L ||
2163                 _pcre_ucp_gentype[prop->chartype] == ucp_N ||
2164                 c == CHAR_UNDERSCORE) == (op == OP_NOTPROP))
2165              MRRETURN(MATCH_NOMATCH);
2166            break;
2167    
2168            /* This should never occur */
2169    
2170          default:          default:
2171          RRETURN(PCRE_ERROR_INTERNAL);          RRETURN(PCRE_ERROR_INTERNAL);
# Line 1721  for (;;) Line 2179  for (;;)
2179      is in the binary; otherwise a compile-time error occurs. */      is in the binary; otherwise a compile-time error occurs. */
2180    
2181      case OP_EXTUNI:      case OP_EXTUNI:
2182      if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);      if (eptr >= md->end_subject)
2183          {
2184          SCHECK_PARTIAL();
2185          MRRETURN(MATCH_NOMATCH);
2186          }
2187      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
2188        {        {
2189        int category = UCD_CATEGORY(c);        int category = UCD_CATEGORY(c);
2190        if (category == ucp_M) RRETURN(MATCH_NOMATCH);        if (category == ucp_M) MRRETURN(MATCH_NOMATCH);
2191        while (eptr < md->end_subject)        while (eptr < md->end_subject)
2192          {          {
2193          int len = 1;          int len = 1;
# Line 1801  for (;;) Line 2263  for (;;)
2263          break;          break;
2264    
2265          default:               /* No repeat follows */          default:               /* No repeat follows */
2266          if (!match_ref(offset, eptr, length, md, ims)) RRETURN(MATCH_NOMATCH);          if (!match_ref(offset, eptr, length, md, ims))
2267              {
2268              CHECK_PARTIAL();
2269              MRRETURN(MATCH_NOMATCH);
2270              }
2271          eptr += length;          eptr += length;
2272          continue;              /* With the main loop */          continue;              /* With the main loop */
2273          }          }
# Line 1817  for (;;) Line 2283  for (;;)
2283    
2284        for (i = 1; i <= min; i++)        for (i = 1; i <= min; i++)
2285          {          {
2286          if (!match_ref(offset, eptr, length, md, ims)) RRETURN(MATCH_NOMATCH);          if (!match_ref(offset, eptr, length, md, ims))
2287              {
2288              CHECK_PARTIAL();
2289              MRRETURN(MATCH_NOMATCH);
2290              }
2291          eptr += length;          eptr += length;
2292          }          }
2293    
# Line 1834  for (;;) Line 2304  for (;;)
2304            {            {
2305            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM14);            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM14);
2306            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2307            if (fi >= max || !match_ref(offset, eptr, length, md, ims))            if (fi >= max) MRRETURN(MATCH_NOMATCH);
2308              RRETURN(MATCH_NOMATCH);            if (!match_ref(offset, eptr, length, md, ims))
2309                {
2310                CHECK_PARTIAL();
2311                MRRETURN(MATCH_NOMATCH);
2312                }
2313            eptr += length;            eptr += length;
2314            }            }
2315          /* Control never gets here */          /* Control never gets here */
# Line 1848  for (;;) Line 2322  for (;;)
2322          pp = eptr;          pp = eptr;
2323          for (i = min; i < max; i++)          for (i = min; i < max; i++)
2324            {            {
2325            if (!match_ref(offset, eptr, length, md, ims)) break;            if (!match_ref(offset, eptr, length, md, ims))
2326                {
2327                CHECK_PARTIAL();
2328                break;
2329                }
2330            eptr += length;            eptr += length;
2331            }            }
2332          while (eptr >= pp)          while (eptr >= pp)
# Line 1857  for (;;) Line 2335  for (;;)
2335            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2336            eptr -= length;            eptr -= length;
2337            }            }
2338          RRETURN(MATCH_NOMATCH);          MRRETURN(MATCH_NOMATCH);
2339          }          }
2340        }        }
2341      /* Control never gets here */      /* Control never gets here */
2342    
   
   
2343      /* Match a bit-mapped character class, possibly repeatedly. This op code is      /* Match a bit-mapped character class, possibly repeatedly. This op code is
2344      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,
2345      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 1918  for (;;) Line 2394  for (;;)
2394          {          {
2395          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
2396            {            {
2397            if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);            if (eptr >= md->end_subject)
2398                {
2399                SCHECK_PARTIAL();
2400                MRRETURN(MATCH_NOMATCH);
2401                }
2402            GETCHARINC(c, eptr);            GETCHARINC(c, eptr);
2403            if (c > 255)            if (c > 255)
2404              {              {
2405              if (op == OP_CLASS) RRETURN(MATCH_NOMATCH);              if (op == OP_CLASS) MRRETURN(MATCH_NOMATCH);
2406              }              }
2407            else            else
2408              {              {
2409              if ((data[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);              if ((data[c/8] & (1 << (c&7))) == 0) MRRETURN(MATCH_NOMATCH);
2410              }              }
2411            }            }
2412          }          }
# Line 1936  for (;;) Line 2416  for (;;)
2416          {          {
2417          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
2418            {            {
2419            if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);            if (eptr >= md->end_subject)
2420                {
2421                SCHECK_PARTIAL();
2422                MRRETURN(MATCH_NOMATCH);
2423                }
2424            c = *eptr++;            c = *eptr++;
2425            if ((data[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);            if ((data[c/8] & (1 << (c&7))) == 0) MRRETURN(MATCH_NOMATCH);
2426            }            }
2427          }          }
2428    
# Line 1960  for (;;) Line 2444  for (;;)
2444              {              {
2445              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM16);              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM16);
2446              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2447              if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);              if (fi >= max) MRRETURN(MATCH_NOMATCH);
2448                if (eptr >= md->end_subject)
2449                  {
2450                  SCHECK_PARTIAL();
2451                  MRRETURN(MATCH_NOMATCH);
2452                  }
2453              GETCHARINC(c, eptr);              GETCHARINC(c, eptr);
2454              if (c > 255)              if (c > 255)
2455                {                {
2456                if (op == OP_CLASS) RRETURN(MATCH_NOMATCH);                if (op == OP_CLASS) MRRETURN(MATCH_NOMATCH);
2457                }                }
2458              else              else
2459                {                {
2460                if ((data[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);                if ((data[c/8] & (1 << (c&7))) == 0) MRRETURN(MATCH_NOMATCH);
2461                }                }
2462              }              }
2463            }            }
# Line 1980  for (;;) Line 2469  for (;;)
2469              {              {
2470              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM17);              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM17);
2471              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2472              if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);              if (fi >= max) MRRETURN(MATCH_NOMATCH);
2473                if (eptr >= md->end_subject)
2474                  {
2475                  SCHECK_PARTIAL();
2476                  MRRETURN(MATCH_NOMATCH);
2477                  }
2478              c = *eptr++;              c = *eptr++;
2479              if ((data[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);              if ((data[c/8] & (1 << (c&7))) == 0) MRRETURN(MATCH_NOMATCH);
2480              }              }
2481            }            }
2482          /* Control never gets here */          /* Control never gets here */
# Line 2001  for (;;) Line 2495  for (;;)
2495            for (i = min; i < max; i++)            for (i = min; i < max; i++)
2496              {              {
2497              int len = 1;              int len = 1;
2498              if (eptr >= md->end_subject) break;              if (eptr >= md->end_subject)
2499                  {
2500                  SCHECK_PARTIAL();
2501                  break;
2502                  }
2503              GETCHARLEN(c, eptr, len);              GETCHARLEN(c, eptr, len);
2504              if (c > 255)              if (c > 255)
2505                {                {
# Line 2027  for (;;) Line 2525  for (;;)
2525            {            {
2526            for (i = min; i < max; i++)            for (i = min; i < max; i++)
2527              {              {
2528              if (eptr >= md->end_subject) break;              if (eptr >= md->end_subject)
2529                  {
2530                  SCHECK_PARTIAL();
2531                  break;
2532                  }
2533              c = *eptr;              c = *eptr;
2534              if ((data[c/8] & (1 << (c&7))) == 0) break;              if ((data[c/8] & (1 << (c&7))) == 0) break;
2535              eptr++;              eptr++;
# Line 2040  for (;;) Line 2542  for (;;)
2542              }              }
2543            }            }
2544    
2545          RRETURN(MATCH_NOMATCH);          MRRETURN(MATCH_NOMATCH);
2546          }          }
2547        }        }
2548      /* Control never gets here */      /* Control never gets here */
2549    
2550    
2551      /* Match an extended character class. This opcode is encountered only      /* Match an extended character class. This opcode is encountered only
2552      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
2553        mode, because Unicode properties are supported in non-UTF-8 mode. */
2554    
2555  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
2556      case OP_XCLASS:      case OP_XCLASS:
# Line 2088  for (;;) Line 2591  for (;;)
2591    
2592        for (i = 1; i <= min; i++)        for (i = 1; i <= min; i++)
2593          {          {
2594          if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);          if (eptr >= md->end_subject)
2595          GETCHARINC(c, eptr);            {
2596          if (!_pcre_xclass(c, data)) RRETURN(MATCH_NOMATCH);            SCHECK_PARTIAL();
2597              MRRETURN(MATCH_NOMATCH);
2598              }
2599            GETCHARINCTEST(c, eptr);
2600            if (!_pcre_xclass(c, data)) MRRETURN(MATCH_NOMATCH);
2601          }          }
2602    
2603        /* 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 2107  for (;;) Line 2614  for (;;)
2614            {            {
2615            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM20);            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM20);
2616            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2617            if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);            if (fi >= max) MRRETURN(MATCH_NOMATCH);
2618            GETCHARINC(c, eptr);            if (eptr >= md->end_subject)
2619            if (!_pcre_xclass(c, data)) RRETURN(MATCH_NOMATCH);              {
2620                SCHECK_PARTIAL();
2621                MRRETURN(MATCH_NOMATCH);
2622                }
2623              GETCHARINCTEST(c, eptr);
2624              if (!_pcre_xclass(c, data)) MRRETURN(MATCH_NOMATCH);
2625            }            }
2626          /* Control never gets here */          /* Control never gets here */
2627          }          }
# Line 2122  for (;;) Line 2634  for (;;)
2634          for (i = min; i < max; i++)          for (i = min; i < max; i++)
2635            {            {
2636            int len = 1;            int len = 1;
2637            if (eptr >= md->end_subject) break;            if (eptr >= md->end_subject)
2638            GETCHARLEN(c, eptr, len);              {
2639                SCHECK_PARTIAL();
2640                break;
2641                }
2642              GETCHARLENTEST(c, eptr, len);
2643            if (!_pcre_xclass(c, data)) break;            if (!_pcre_xclass(c, data)) break;
2644            eptr += len;            eptr += len;
2645            }            }
# Line 2134  for (;;) Line 2650  for (;;)
2650            if (eptr-- == pp) break;        /* Stop if tried at original pos */            if (eptr-- == pp) break;        /* Stop if tried at original pos */
2651            if (utf8) BACKCHAR(eptr);            if (utf8) BACKCHAR(eptr);
2652            }            }
2653          RRETURN(MATCH_NOMATCH);          MRRETURN(MATCH_NOMATCH);
2654          }          }
2655    
2656        /* Control never gets here */        /* Control never gets here */
# Line 2150  for (;;) Line 2666  for (;;)
2666        length = 1;        length = 1;
2667        ecode++;        ecode++;
2668        GETCHARLEN(fc, ecode, length);        GETCHARLEN(fc, ecode, length);
2669        if (length > md->end_subject - eptr) RRETURN(MATCH_NOMATCH);        if (length > md->end_subject - eptr)
2670        while (length-- > 0) if (*ecode++ != *eptr++) RRETURN(MATCH_NOMATCH);          {
2671            CHECK_PARTIAL();             /* Not SCHECK_PARTIAL() */
2672            MRRETURN(MATCH_NOMATCH);
2673            }
2674          while (length-- > 0) if (*ecode++ != *eptr++) MRRETURN(MATCH_NOMATCH);
2675        }        }
2676      else      else
2677  #endif  #endif
2678    
2679      /* Non-UTF-8 mode */      /* Non-UTF-8 mode */
2680        {        {
2681        if (md->end_subject - eptr < 1) RRETURN(MATCH_NOMATCH);        if (md->end_subject - eptr < 1)
2682        if (ecode[1] != *eptr++) RRETURN(MATCH_NOMATCH);          {
2683            SCHECK_PARTIAL();            /* This one can use SCHECK_PARTIAL() */
2684            MRRETURN(MATCH_NOMATCH);
2685            }
2686          if (ecode[1] != *eptr++) MRRETURN(MATCH_NOMATCH);
2687        ecode += 2;        ecode += 2;
2688        }        }
2689      break;      break;
# Line 2174  for (;;) Line 2698  for (;;)
2698        ecode++;        ecode++;
2699        GETCHARLEN(fc, ecode, length);        GETCHARLEN(fc, ecode, length);
2700    
2701        if (length > md->end_subject - eptr) RRETURN(MATCH_NOMATCH);        if (length > md->end_subject - eptr)
2702            {
2703            CHECK_PARTIAL();             /* Not SCHECK_PARTIAL() */
2704            MRRETURN(MATCH_NOMATCH);
2705            }
2706    
2707        /* 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
2708        can use the fast lookup table. */        can use the fast lookup table. */
2709    
2710        if (fc < 128)        if (fc < 128)
2711          {          {
2712          if (md->lcc[*ecode++] != md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH);          if (md->lcc[*ecode++] != md->lcc[*eptr++]) MRRETURN(MATCH_NOMATCH);
2713          }          }
2714    
2715        /* Otherwise we must pick up the subject character */        /* Otherwise we must pick up the subject character */
# Line 2200  for (;;) Line 2728  for (;;)
2728  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2729            if (dc != UCD_OTHERCASE(fc))            if (dc != UCD_OTHERCASE(fc))
2730  #endif  #endif
2731              RRETURN(MATCH_NOMATCH);              MRRETURN(MATCH_NOMATCH);
2732            }            }
2733          }          }
2734        }        }
# Line 2209  for (;;) Line 2737  for (;;)
2737    
2738      /* Non-UTF-8 mode */      /* Non-UTF-8 mode */
2739        {        {
2740        if (md->end_subject - eptr < 1) RRETURN(MATCH_NOMATCH);        if (md->end_subject - eptr < 1)
2741        if (md->lcc[ecode[1]] != md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH);          {
2742            SCHECK_PARTIAL();            /* This one can use SCHECK_PARTIAL() */
2743            MRRETURN(MATCH_NOMATCH);
2744            }
2745          if (md->lcc[ecode[1]] != md->lcc[*eptr++]) MRRETURN(MATCH_NOMATCH);
2746        ecode += 2;        ecode += 2;
2747        }        }
2748      break;      break;
# Line 2263  for (;;) Line 2795  for (;;)
2795      case OP_MINQUERY:      case OP_MINQUERY:
2796      c = *ecode++ - OP_STAR;      c = *ecode++ - OP_STAR;
2797      minimize = (c & 1) != 0;      minimize = (c & 1) != 0;
2798    
2799      min = rep_min[c];                 /* Pick up values from tables; */      min = rep_min[c];                 /* Pick up values from tables; */
2800      max = rep_max[c];                 /* zero for max => infinity */      max = rep_max[c];                 /* zero for max => infinity */
2801      if (max == 0) max = INT_MAX;      if (max == 0) max = INT_MAX;
2802    
2803      /* 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. */  
2804    
2805      REPEATCHAR:      REPEATCHAR:
2806  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
# Line 2278  for (;;) Line 2809  for (;;)
2809        length = 1;        length = 1;
2810        charptr = ecode;        charptr = ecode;
2811        GETCHARLEN(fc, ecode, length);        GETCHARLEN(fc, ecode, length);
       if (min * length > md->end_subject - eptr) RRETURN(MATCH_NOMATCH);  
2812        ecode += length;        ecode += length;
2813    
2814        /* Handle multibyte character matching specially here. There is        /* Handle multibyte character matching specially here. There is
# Line 2296  for (;;) Line 2826  for (;;)
2826    
2827          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
2828            {            {
2829            if (memcmp(eptr, charptr, length) == 0) eptr += length;            if (eptr <= md->end_subject - length &&
2830                memcmp(eptr, charptr, length) == 0) eptr += length;
2831  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2832            /* Need braces because of following else */            else if (oclength > 0 &&
2833            else if (oclength == 0) { RRETURN(MATCH_NOMATCH); }                     eptr <= md->end_subject - oclength &&
2834                       memcmp(eptr, occhars, oclength) == 0) eptr += oclength;
2835    #endif  /* SUPPORT_UCP */
2836            else            else
2837              {              {
2838              if (memcmp(eptr, occhars, oclength) != 0) RRETURN(MATCH_NOMATCH);              CHECK_PARTIAL();
2839              eptr += oclength;              MRRETURN(MATCH_NOMATCH);
2840              }              }
 #else   /* without SUPPORT_UCP */  
           else { RRETURN(MATCH_NOMATCH); }  
 #endif  /* SUPPORT_UCP */  
2841            }            }
2842    
2843          if (min == max) continue;          if (min == max) continue;
# Line 2318  for (;;) Line 2848  for (;;)
2848              {              {
2849              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM22);              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM22);
2850              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2851              if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);              if (fi >= max) MRRETURN(MATCH_NOMATCH);
2852              if (memcmp(eptr, charptr, length) == 0) eptr += length;              if (eptr <= md->end_subject - length &&
2853                  memcmp(eptr, charptr, length) == 0) eptr += length;
2854  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2855              /* Need braces because of following else */              else if (oclength > 0 &&
2856              else if (oclength == 0) { RRETURN(MATCH_NOMATCH); }                       eptr <= md->end_subject - oclength &&
2857                         memcmp(eptr, occhars, oclength) == 0) eptr += oclength;
2858    #endif  /* SUPPORT_UCP */
2859              else              else
2860                {                {
2861                if (memcmp(eptr, occhars, oclength) != 0) RRETURN(MATCH_NOMATCH);                CHECK_PARTIAL();
2862                eptr += oclength;                MRRETURN(MATCH_NOMATCH);
2863                }                }
 #else   /* without SUPPORT_UCP */  
             else { RRETURN (MATCH_NOMATCH); }  
 #endif  /* SUPPORT_UCP */  
2864              }              }
2865            /* Control never gets here */            /* Control never gets here */
2866            }            }
# Line 2340  for (;;) Line 2870  for (;;)
2870            pp = eptr;            pp = eptr;
2871            for (i = min; i < max; i++)            for (i = min; i < max; i++)
2872              {              {
2873              if (eptr > md->end_subject - length) break;              if (eptr <= md->end_subject - length &&
2874              if (memcmp(eptr, charptr, length) == 0) eptr += length;                  memcmp(eptr, charptr, length) == 0) eptr += length;
2875  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2876              else if (oclength == 0) break;              else if (oclength > 0 &&
2877                         eptr <= md->end_subject - oclength &&
2878                         memcmp(eptr, occhars, oclength) == 0) eptr += oclength;
2879    #endif  /* SUPPORT_UCP */
2880              else              else
2881                {                {
2882                if (memcmp(eptr, occhars, oclength) != 0) break;                CHECK_PARTIAL();
2883                eptr += oclength;                break;
2884                }                }
 #else   /* without SUPPORT_UCP */  
             else break;  
 #endif  /* SUPPORT_UCP */  
2885              }              }
2886    
2887            if (possessive) continue;            if (possessive) continue;
2888    
2889            for(;;)            for(;;)
2890             {              {
2891             RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM23);              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM23);
2892             if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2893             if (eptr == pp) RRETURN(MATCH_NOMATCH);              if (eptr == pp) { MRRETURN(MATCH_NOMATCH); }
2894  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2895             eptr--;              eptr--;
2896             BACKCHAR(eptr);              BACKCHAR(eptr);
2897  #else   /* without SUPPORT_UCP */  #else   /* without SUPPORT_UCP */
2898             eptr -= length;              eptr -= length;
2899  #endif  /* SUPPORT_UCP */  #endif  /* SUPPORT_UCP */
2900             }              }
2901            }            }
2902          /* Control never gets here */          /* Control never gets here */
2903          }          }
# Line 2379  for (;;) Line 2910  for (;;)
2910  #endif  /* SUPPORT_UTF8 */  #endif  /* SUPPORT_UTF8 */
2911    
2912      /* When not in UTF-8 mode, load a single-byte character. */      /* When not in UTF-8 mode, load a single-byte character. */
2913        {  
2914        if (min > md->end_subject - eptr) RRETURN(MATCH_NOMATCH);      fc = *ecode++;
       fc = *ecode++;  
       }  
2915    
2916      /* 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
2917      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 2400  for (;;) Line 2929  for (;;)
2929        {        {
2930        fc = md->lcc[fc];        fc = md->lcc[fc];
2931        for (i = 1; i <= min; i++)        for (i = 1; i <= min; i++)
2932          if (fc != md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH);          {
2933            if (eptr >= md->end_subject)
2934              {
2935              SCHECK_PARTIAL();
2936              MRRETURN(MATCH_NOMATCH);
2937              }
2938            if (fc != md->lcc[*eptr++]) MRRETURN(MATCH_NOMATCH);
2939            }
2940        if (min == max) continue;        if (min == max) continue;
2941        if (minimize)        if (minimize)
2942          {          {
# Line 2408  for (;;) Line 2944  for (;;)
2944            {            {
2945            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM24);            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM24);
2946            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2947            if (fi >= max || eptr >= md->end_subject ||            if (fi >= max) MRRETURN(MATCH_NOMATCH);
2948                fc != md->lcc[*eptr++])            if (eptr >= md->end_subject)
2949              RRETURN(MATCH_NOMATCH);              {
2950                SCHECK_PARTIAL();
2951                MRRETURN(MATCH_NOMATCH);
2952                }
2953              if (fc != md->lcc[*eptr++]) MRRETURN(MATCH_NOMATCH);
2954            }            }
2955          /* Control never gets here */          /* Control never gets here */
2956          }          }
# Line 2419  for (;;) Line 2959  for (;;)
2959          pp = eptr;          pp = eptr;
2960          for (i = min; i < max; i++)          for (i = min; i < max; i++)
2961            {            {
2962            if (eptr >= md->end_subject || fc != md->lcc[*eptr]) break;            if (eptr >= md->end_subject)
2963                {
2964                SCHECK_PARTIAL();
2965                break;
2966                }
2967              if (fc != md->lcc[*eptr]) break;
2968            eptr++;            eptr++;
2969            }            }
2970    
2971          if (possessive) continue;          if (possessive) continue;
2972    
2973          while (eptr >= pp)          while (eptr >= pp)
2974            {            {
2975            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM25);            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM25);
2976            eptr--;            eptr--;
2977            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2978            }            }
2979          RRETURN(MATCH_NOMATCH);          MRRETURN(MATCH_NOMATCH);
2980          }          }
2981        /* Control never gets here */        /* Control never gets here */
2982        }        }
# Line 2438  for (;;) Line 2985  for (;;)
2985    
2986      else      else
2987        {        {
2988        for (i = 1; i <= min; i++) if (fc != *eptr++) RRETURN(MATCH_NOMATCH);        for (i = 1; i <= min; i++)
2989        if (min == max) continue;          {
2990        if (minimize)          if (eptr >= md->end_subject)
2991              {
2992              SCHECK_PARTIAL();
2993              MRRETURN(MATCH_NOMATCH);
2994              }
2995            if (fc != *eptr++) MRRETURN(MATCH_NOMATCH);
2996            }
2997    
2998          if (min == max) continue;
2999    
3000          if (minimize)
3001          {          {
3002          for (fi = min;; fi++)          for (fi = min;; fi++)
3003            {            {
3004            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM26);            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM26);
3005            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3006            if (fi >= max || eptr >= md->end_subject || fc != *eptr++)            if (fi >= max) MRRETURN(MATCH_NOMATCH);
3007              RRETURN(MATCH_NOMATCH);            if (eptr >= md->end_subject)
3008                {
3009                SCHECK_PARTIAL();
3010                MRRETURN(MATCH_NOMATCH);
3011                }
3012              if (fc != *eptr++) MRRETURN(MATCH_NOMATCH);
3013            }            }
3014          /* Control never gets here */          /* Control never gets here */
3015          }          }
# Line 2456  for (;;) Line 3018  for (;;)
3018          pp = eptr;          pp = eptr;
3019          for (i = min; i < max; i++)          for (i = min; i < max; i++)
3020            {            {
3021            if (eptr >= md->end_subject || fc != *eptr) break;            if (eptr >= md->end_subject)
3022                {
3023                SCHECK_PARTIAL();
3024                break;
3025                }
3026              if (fc != *eptr) break;
3027            eptr++;            eptr++;
3028            }            }
3029          if (possessive) continue;          if (possessive) continue;
3030    
3031          while (eptr >= pp)          while (eptr >= pp)
3032            {            {
3033            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM27);            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM27);
3034            eptr--;            eptr--;
3035            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3036            }            }
3037          RRETURN(MATCH_NOMATCH);          MRRETURN(MATCH_NOMATCH);
3038          }          }
3039        }        }
3040      /* Control never gets here */      /* Control never gets here */
# Line 2475  for (;;) Line 3043  for (;;)
3043      checking can be multibyte. */      checking can be multibyte. */
3044    
3045      case OP_NOT:      case OP_NOT:
3046      if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);      if (eptr >= md->end_subject)
3047          {
3048          SCHECK_PARTIAL();
3049          MRRETURN(MATCH_NOMATCH);
3050          }
3051      ecode++;      ecode++;
3052      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
3053      if ((ims & PCRE_CASELESS) != 0)      if ((ims & PCRE_CASELESS) != 0)
# Line 2484  for (;;) Line 3056  for (;;)
3056        if (c < 256)        if (c < 256)
3057  #endif  #endif
3058        c = md->lcc[c];        c = md->lcc[c];
3059        if (md->lcc[*ecode++] == c) RRETURN(MATCH_NOMATCH);        if (md->lcc[*ecode++] == c) MRRETURN(MATCH_NOMATCH);
3060        }        }
3061      else      else
3062        {        {
3063        if (*ecode++ == c) RRETURN(MATCH_NOMATCH);        if (*ecode++ == c) MRRETURN(MATCH_NOMATCH);
3064        }        }
3065      break;      break;
3066    
# Line 2552  for (;;) Line 3124  for (;;)
3124      max = rep_max[c];                 /* zero for max => infinity */      max = rep_max[c];                 /* zero for max => infinity */
3125      if (max == 0) max = INT_MAX;      if (max == 0) max = INT_MAX;
3126    
3127      /* 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. */  
3128    
3129      REPEATNOTCHAR:      REPEATNOTCHAR:
     if (min > md->end_subject - eptr) RRETURN(MATCH_NOMATCH);  
3130      fc = *ecode++;      fc = *ecode++;
3131    
3132      /* 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 2582  for (;;) Line 3151  for (;;)
3151          register unsigned int d;          register unsigned int d;
3152          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3153            {            {
3154              if (eptr >= md->end_subject)
3155                {
3156                SCHECK_PARTIAL();
3157                MRRETURN(MATCH_NOMATCH);
3158                }
3159            GETCHARINC(d, eptr);            GETCHARINC(d, eptr);
3160            if (d < 256) d = md->lcc[d];            if (d < 256) d = md->lcc[d];
3161            if (fc == d) RRETURN(MATCH_NOMATCH);            if (fc == d) MRRETURN(MATCH_NOMATCH);
3162            }            }
3163          }          }
3164        else        else
# Line 2593  for (;;) Line 3167  for (;;)
3167        /* Not UTF-8 mode */        /* Not UTF-8 mode */
3168          {          {
3169          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3170            if (fc == md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH);            {
3171              if (eptr >= md->end_subject)
3172                {
3173                SCHECK_PARTIAL();
3174                MRRETURN(MATCH_NOMATCH);
3175                }
3176              if (fc == md->lcc[*eptr++]) MRRETURN(MATCH_NOMATCH);
3177              }
3178          }          }
3179    
3180        if (min == max) continue;        if (min == max) continue;
# Line 2609  for (;;) Line 3190  for (;;)
3190              {              {
3191              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM28);              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM28);
3192              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3193                if (fi >= max) MRRETURN(MATCH_NOMATCH);
3194                if (eptr >= md->end_subject)
3195                  {
3196                  SCHECK_PARTIAL();
3197                  MRRETURN(MATCH_NOMATCH);
3198                  }
3199              GETCHARINC(d, eptr);              GETCHARINC(d, eptr);
3200              if (d < 256) d = md->lcc[d];              if (d < 256) d = md->lcc[d];
3201              if (fi >= max || eptr >= md->end_subject || fc == d)              if (fc == d) MRRETURN(MATCH_NOMATCH);
               RRETURN(MATCH_NOMATCH);  
3202              }              }
3203            }            }
3204          else          else
# Line 2623  for (;;) Line 3209  for (;;)
3209              {              {
3210              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM29);              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM29);
3211              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3212              if (fi >= max || eptr >= md->end_subject || fc == md->lcc[*eptr++])              if (fi >= max) MRRETURN(MATCH_NOMATCH);
3213                RRETURN(MATCH_NOMATCH);              if (eptr >= md->end_subject)
3214                  {
3215                  SCHECK_PARTIAL();
3216                  MRRETURN(MATCH_NOMATCH);
3217                  }
3218                if (fc == md->lcc[*eptr++]) MRRETURN(MATCH_NOMATCH);
3219              }              }
3220            }            }
3221          /* Control never gets here */          /* Control never gets here */
# Line 2644  for (;;) Line 3235  for (;;)
3235            for (i = min; i < max; i++)            for (i = min; i < max; i++)
3236              {              {
3237              int len = 1;              int len = 1;
3238              if (eptr >= md->end_subject) break;              if (eptr >= md->end_subject)
3239                  {
3240                  SCHECK_PARTIAL();
3241                  break;
3242                  }
3243              GETCHARLEN(d, eptr, len);              GETCHARLEN(d, eptr, len);
3244              if (d < 256) d = md->lcc[d];              if (d < 256) d = md->lcc[d];
3245              if (fc == d) break;              if (fc == d) break;
# Line 2665  for (;;) Line 3260  for (;;)
3260            {            {
3261            for (i = min; i < max; i++)            for (i = min; i < max; i++)
3262              {              {
3263              if (eptr >= md->end_subject || fc == md->lcc[*eptr]) break;              if (eptr >= md->end_subject)
3264                  {
3265                  SCHECK_PARTIAL();
3266                  break;
3267                  }
3268                if (fc == md->lcc[*eptr]) break;
3269              eptr++;              eptr++;
3270              }              }
3271            if (possessive) continue;            if (possessive) continue;
# Line 2677  for (;;) Line 3277  for (;;)
3277              }              }
3278            }            }
3279    
3280          RRETURN(MATCH_NOMATCH);          MRRETURN(MATCH_NOMATCH);
3281          }          }
3282        /* Control never gets here */        /* Control never gets here */
3283        }        }
# Line 2693  for (;;) Line 3293  for (;;)
3293          register unsigned int d;          register unsigned int d;
3294          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3295            {            {
3296              if (eptr >= md->end_subject)
3297                {
3298                SCHECK_PARTIAL();
3299                MRRETURN(MATCH_NOMATCH);
3300                }
3301            GETCHARINC(d, eptr);            GETCHARINC(d, eptr);
3302            if (fc == d) RRETURN(MATCH_NOMATCH);            if (fc == d) MRRETURN(MATCH_NOMATCH);
3303            }            }
3304          }          }
3305        else        else
# Line 2702  for (;;) Line 3307  for (;;)
3307        /* Not UTF-8 mode */        /* Not UTF-8 mode */
3308          {          {
3309          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3310            if (fc == *eptr++) RRETURN(MATCH_NOMATCH);            {
3311              if (eptr >= md->end_subject)
3312                {
3313                SCHECK_PARTIAL();
3314                MRRETURN(MATCH_NOMATCH);
3315                }
3316              if (fc == *eptr++) MRRETURN(MATCH_NOMATCH);
3317              }
3318          }          }
3319    
3320        if (min == max) continue;        if (min == max) continue;
# Line 2718  for (;;) Line 3330  for (;;)
3330              {              {
3331              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM32);              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM32);
3332              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3333                if (fi >= max) MRRETURN(MATCH_NOMATCH);
3334                if (eptr >= md->end_subject)
3335                  {
3336                  SCHECK_PARTIAL();
3337                  MRRETURN(MATCH_NOMATCH);
3338                  }
3339              GETCHARINC(d, eptr);              GETCHARINC(d, eptr);
3340              if (fi >= max || eptr >= md->end_subject || fc == d)              if (fc == d) MRRETURN(MATCH_NOMATCH);
               RRETURN(MATCH_NOMATCH);  
3341              }              }
3342            }            }
3343          else          else
# Line 2731  for (;;) Line 3348  for (;;)
3348              {              {
3349              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM33);              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM33);
3350              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3351              if (fi >= max || eptr >= md->end_subject || fc == *eptr++)              if (fi >= max) MRRETURN(MATCH_NOMATCH);
3352                RRETURN(MATCH_NOMATCH);              if (eptr >= md->end_subject)
3353                  {
3354                  SCHECK_PARTIAL();
3355                  MRRETURN(MATCH_NOMATCH);
3356                  }
3357                if (fc == *eptr++) MRRETURN(MATCH_NOMATCH);
3358              }              }
3359            }            }
3360          /* Control never gets here */          /* Control never gets here */
# Line 2752  for (;;) Line 3374  for (;;)
3374            for (i = min; i < max; i++)            for (i = min; i < max; i++)
3375              {              {
3376              int len = 1;              int len = 1;
3377              if (eptr >= md->end_subject) break;              if (eptr >= md->end_subject)
3378                  {
3379                  SCHECK_PARTIAL();
3380                  break;
3381                  }
3382              GETCHARLEN(d, eptr, len);              GETCHARLEN(d, eptr, len);
3383              if (fc == d) break;              if (fc == d) break;
3384              eptr += len;              eptr += len;
# Line 2772  for (;;) Line 3398  for (;;)
3398            {            {
3399            for (i = min; i < max; i++)            for (i = min; i < max; i++)
3400              {              {
3401              if (eptr >= md->end_subject || fc == *eptr) break;              if (eptr >= md->end_subject)
3402                  {
3403                  SCHECK_PARTIAL();
3404                  break;
3405                  }
3406                if (fc == *eptr) break;
3407              eptr++;              eptr++;
3408              }              }
3409            if (possessive) continue;            if (possessive) continue;
# Line 2784  for (;;) Line 3415  for (;;)
3415              }              }
3416            }            }
3417    
3418          RRETURN(MATCH_NOMATCH);          MRRETURN(MATCH_NOMATCH);
3419          }          }
3420        }        }
3421      /* Control never gets here */      /* Control never gets here */
# Line 2866  for (;;) Line 3497  for (;;)
3497    
3498      /* First, ensure the minimum number of matches are present. Use inline      /* First, ensure the minimum number of matches are present. Use inline
3499      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
3500      (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  
3501      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
3502      and single-bytes. */      and single-bytes. */
3503    
     if (min > md->end_subject - eptr) RRETURN(MATCH_NOMATCH);  
3504      if (min > 0)      if (min > 0)
3505        {        {
3506  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
# Line 2881  for (;;) Line 3509  for (;;)
3509          switch(prop_type)          switch(prop_type)
3510            {            {
3511            case PT_ANY:            case PT_ANY:
3512            if (prop_fail_result) RRETURN(MATCH_NOMATCH);            if (prop_fail_result) MRRETURN(MATCH_NOMATCH);
3513            for (i = 1; i <= min; i++)            for (i = 1; i <= min; i++)
3514              {              {
3515              if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);              if (eptr >= md->end_subject)
3516                  {
3517                  SCHECK_PARTIAL();
3518                  MRRETURN(MATCH_NOMATCH);
3519                  }
3520              GETCHARINCTEST(c, eptr);              GETCHARINCTEST(c, eptr);
3521              }              }
3522            break;            break;
# Line 2892  for (;;) Line 3524  for (;;)
3524            case PT_LAMP:            case PT_LAMP:
3525            for (i = 1; i <= min; i++)            for (i = 1; i <= min; i++)
3526              {              {
3527              if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);              if (eptr >= md->end_subject)
3528                  {
3529                  SCHECK_PARTIAL();
3530                  MRRETURN(MATCH_NOMATCH);
3531                  }
3532              GETCHARINCTEST(c, eptr);              GETCHARINCTEST(c, eptr);
3533              prop_chartype = UCD_CHARTYPE(c);              prop_chartype = UCD_CHARTYPE(c);
3534              if ((prop_chartype == ucp_Lu ||              if ((prop_chartype == ucp_Lu ||
3535                   prop_chartype == ucp_Ll ||                   prop_chartype == ucp_Ll ||
3536                   prop_chartype == ucp_Lt) == prop_fail_result)                   prop_chartype == ucp_Lt) == prop_fail_result)
3537                RRETURN(MATCH_NOMATCH);                MRRETURN(MATCH_NOMATCH);
3538              }              }
3539            break;            break;
3540    
3541            case PT_GC:            case PT_GC:
3542            for (i = 1; i <= min; i++)            for (i = 1; i <= min; i++)
3543              {              {
3544              if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);              if (eptr >= md->end_subject)
3545                  {
3546                  SCHECK_PARTIAL();
3547                  MRRETURN(MATCH_NOMATCH);
3548                  }
3549              GETCHARINCTEST(c, eptr);              GETCHARINCTEST(c, eptr);
3550              prop_category = UCD_CATEGORY(c);              prop_category = UCD_CATEGORY(c);
3551              if ((prop_category == prop_value) == prop_fail_result)              if ((prop_category == prop_value) == prop_fail_result)
3552                RRETURN(MATCH_NOMATCH);                MRRETURN(MATCH_NOMATCH);
3553              }              }
3554            break;            break;
3555    
3556            case PT_PC:            case PT_PC:
3557            for (i = 1; i <= min; i++)            for (i = 1; i <= min; i++)
3558              {              {
3559              if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);              if (eptr >= md->end_subject)
3560                  {
3561                  SCHECK_PARTIAL();
3562                  MRRETURN(MATCH_NOMATCH);
3563                  }
3564              GETCHARINCTEST(c, eptr);              GETCHARINCTEST(c, eptr);
3565              prop_chartype = UCD_CHARTYPE(c);              prop_chartype = UCD_CHARTYPE(c);
3566              if ((prop_chartype == prop_value) == prop_fail_result)              if ((prop_chartype == prop_value) == prop_fail_result)
3567                RRETURN(MATCH_NOMATCH);                MRRETURN(MATCH_NOMATCH);
3568              }              }
3569            break;            break;
3570    
3571            case PT_SC:            case PT_SC:
3572            for (i = 1; i <= min; i++)            for (i = 1; i <= min; i++)
3573              {              {
3574              if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);              if (eptr >= md->end_subject)
3575                  {
3576                  SCHECK_PARTIAL();
3577                  MRRETURN(MATCH_NOMATCH);
3578                  }
3579              GETCHARINCTEST(c, eptr);              GETCHARINCTEST(c, eptr);
3580              prop_script = UCD_SCRIPT(c);              prop_script = UCD_SCRIPT(c);
3581              if ((prop_script == prop_value) == prop_fail_result)              if ((prop_script == prop_value) == prop_fail_result)
3582                RRETURN(MATCH_NOMATCH);                MRRETURN(MATCH_NOMATCH);
3583                }
3584              break;
3585    
3586              case PT_ALNUM:
3587              for (i = 1; i <= min; i++)
3588                {
3589                if (eptr >= md->end_subject)
3590                  {
3591                  SCHECK_PARTIAL();
3592                  MRRETURN(MATCH_NOMATCH);
3593                  }
3594                GETCHARINCTEST(c, eptr);
3595                prop_category = UCD_CATEGORY(c);
3596                if ((prop_category == ucp_L || prop_category == ucp_N)
3597                       == prop_fail_result)
3598                  MRRETURN(MATCH_NOMATCH);
3599                }
3600              break;
3601    
3602              case PT_SPACE:    /* Perl space */
3603              for (i = 1; i <= min; i++)
3604                {
3605                if (eptr >= md->end_subject)
3606                  {
3607                  SCHECK_PARTIAL();
3608                  MRRETURN(MATCH_NOMATCH);
3609                  }
3610                GETCHARINCTEST(c, eptr);
3611                prop_category = UCD_CATEGORY(c);
3612                if ((prop_category == ucp_Z || c == CHAR_HT || c == CHAR_NL ||
3613                     c == CHAR_FF || c == CHAR_CR)
3614                       == prop_fail_result)
3615                  MRRETURN(MATCH_NOMATCH);
3616                }
3617              break;
3618    
3619              case PT_PXSPACE:  /* POSIX space */
3620              for (i = 1; i <= min; i++)
3621                {
3622                if (eptr >= md->end_subject)
3623                  {
3624                  SCHECK_PARTIAL();
3625                  MRRETURN(MATCH_NOMATCH);
3626                  }
3627                GETCHARINCTEST(c, eptr);
3628                prop_category = UCD_CATEGORY(c);
3629                if ((prop_category == ucp_Z || c == CHAR_HT || c == CHAR_NL ||
3630                     c == CHAR_VT || c == CHAR_FF || c == CHAR_CR)
3631                       == prop_fail_result)
3632                  MRRETURN(MATCH_NOMATCH);
3633                }
3634              break;
3635    
3636              case PT_WORD:
3637              for (i = 1; i <= min; i++)
3638                {
3639                if (eptr >= md->end_subject)
3640                  {
3641                  SCHECK_PARTIAL();
3642                  MRRETURN(MATCH_NOMATCH);
3643                  }
3644                GETCHARINCTEST(c, eptr);
3645                prop_category = UCD_CATEGORY(c);
3646                if ((prop_category == ucp_L || prop_category == ucp_N ||
3647                     c == CHAR_UNDERSCORE)
3648                       == prop_fail_result)
3649                  MRRETURN(MATCH_NOMATCH);
3650              }              }
3651            break;            break;
3652    
3653              /* This should not occur */
3654    
3655            default:            default:
3656            RRETURN(PCRE_ERROR_INTERNAL);            RRETURN(PCRE_ERROR_INTERNAL);
# Line 2947  for (;;) Line 3664  for (;;)
3664          {          {
3665          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3666            {            {
3667              if (eptr >= md->end_subject)
3668                {
3669                SCHECK_PARTIAL();
3670                MRRETURN(MATCH_NOMATCH);
3671                }
3672            GETCHARINCTEST(c, eptr);            GETCHARINCTEST(c, eptr);
3673            prop_category = UCD_CATEGORY(c);            prop_category = UCD_CATEGORY(c);
3674            if (prop_category == ucp_M) RRETURN(MATCH_NOMATCH);            if (prop_category == ucp_M) MRRETURN(MATCH_NOMATCH);
3675            while (eptr < md->end_subject)            while (eptr < md->end_subject)
3676              {              {
3677              int len = 1;              int len = 1;
3678              if (!utf8) c = *eptr; else              if (!utf8) c = *eptr;
3679                {                else { GETCHARLEN(c, eptr, len); }
               GETCHARLEN(c, eptr, len);  
               }  
3680              prop_category = UCD_CATEGORY(c);              prop_category = UCD_CATEGORY(c);
3681              if (prop_category != ucp_M) break;              if (prop_category != ucp_M) break;
3682              eptr += len;              eptr += len;
# Line 2975  for (;;) Line 3695  for (;;)
3695          case OP_ANY:          case OP_ANY:
3696          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3697            {            {
3698            if (eptr >= md->end_subject || IS_NEWLINE(eptr))            if (eptr >= md->end_subject)
3699              RRETURN(MATCH_NOMATCH);              {
3700                SCHECK_PARTIAL();
3701                MRRETURN(MATCH_NOMATCH);
3702                }
3703              if (IS_NEWLINE(eptr)) MRRETURN(MATCH_NOMATCH);
3704            eptr++;            eptr++;
3705            while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;            while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;
3706            }            }
# Line 2985  for (;;) Line 3709  for (;;)
3709          case OP_ALLANY:          case OP_ALLANY:
3710          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3711            {            {
3712            if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);            if (eptr >= md->end_subject)
3713                {
3714                SCHECK_PARTIAL();
3715                MRRETURN(MATCH_NOMATCH);
3716                }
3717            eptr++;            eptr++;
3718            while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;            while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;
3719            }            }
3720          break;          break;
3721    
3722          case OP_ANYBYTE:          case OP_ANYBYTE:
3723            if (eptr > md->end_subject - min) MRRETURN(MATCH_NOMATCH);
3724          eptr += min;          eptr += min;
3725          break;          break;
3726    
3727          case OP_ANYNL:          case OP_ANYNL:
3728          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3729            {            {
3730            if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);            if (eptr >= md->end_subject)
3731                {
3732                SCHECK_PARTIAL();
3733                MRRETURN(MATCH_NOMATCH);
3734                }
3735            GETCHARINC(c, eptr);            GETCHARINC(c, eptr);
3736            switch(c)            switch(c)
3737              {              {
3738              default: RRETURN(MATCH_NOMATCH);              default: MRRETURN(MATCH_NOMATCH);
3739              case 0x000d:              case 0x000d:
3740              if (eptr < md->end_subject && *eptr == 0x0a) eptr++;              if (eptr < md->end_subject && *eptr == 0x0a) eptr++;
3741              break;              break;
# Line 3015  for (;;) Line 3748  for (;;)
3748              case 0x0085:              case 0x0085:
3749              case 0x2028:              case 0x2028:
3750              case 0x2029:              case 0x2029:
3751              if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH);              if (md->bsr_anycrlf) MRRETURN(MATCH_NOMATCH);
3752              break;              break;
3753              }              }
3754            }            }
# Line 3024  for (;;) Line 3757  for (;;)
3757          case OP_NOT_HSPACE:          case OP_NOT_HSPACE:
3758          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3759            {            {
3760            if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);            if (eptr >= md->end_subject)
3761                {
3762                SCHECK_PARTIAL();
3763                MRRETURN(MATCH_NOMATCH);
3764                }
3765            GETCHARINC(c, eptr);            GETCHARINC(c, eptr);
3766            switch(c)            switch(c)
3767              {              {
# Line 3048  for (;;) Line 3785  for (;;)
3785              case 0x202f:    /* NARROW NO-BREAK SPACE */              case 0x202f:    /* NARROW NO-BREAK SPACE */
3786              case 0x205f:    /* MEDIUM MATHEMATICAL SPACE */              case 0x205f:    /* MEDIUM MATHEMATICAL SPACE */
3787              case 0x3000:    /* IDEOGRAPHIC SPACE */              case 0x3000:    /* IDEOGRAPHIC SPACE */
3788              RRETURN(MATCH_NOMATCH);              MRRETURN(MATCH_NOMATCH);
3789              }              }
3790            }            }
3791          break;          break;
# Line 3056  for (;;) Line 3793  for (;;)
3793          case OP_HSPACE:          case OP_HSPACE:
3794          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3795            {            {
3796            if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);            if (eptr >= md->end_subject)
3797                {
3798                SCHECK_PARTIAL();
3799                MRRETURN(MATCH_NOMATCH);
3800                }
3801            GETCHARINC(c, eptr);            GETCHARINC(c, eptr);
3802            switch(c)            switch(c)
3803              {              {
3804              default: RRETURN(MATCH_NOMATCH);              default: MRRETURN(MATCH_NOMATCH);
3805              case 0x09:      /* HT */              case 0x09:      /* HT */
3806              case 0x20:      /* SPACE */              case 0x20:      /* SPACE */
3807              case 0xa0:      /* NBSP */              case 0xa0:      /* NBSP */
# Line 3088  for (;;) Line 3829  for (;;)
3829          case OP_NOT_VSPACE:          case OP_NOT_VSPACE:
3830          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3831            {            {
3832            if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);            if (eptr >= md->end_subject)
3833                {
3834                SCHECK_PARTIAL();
3835                MRRETURN(MATCH_NOMATCH);
3836                }
3837            GETCHARINC(c, eptr);            GETCHARINC(c, eptr);
3838            switch(c)            switch(c)
3839              {              {
# Line 3100  for (;;) Line 3845  for (;;)
3845              case 0x85:      /* NEL */              case 0x85:      /* NEL */
3846              case 0x2028:    /* LINE SEPARATOR */              case 0x2028:    /* LINE SEPARATOR */
3847              case 0x2029:    /* PARAGRAPH SEPARATOR */              case 0x2029:    /* PARAGRAPH SEPARATOR */
3848              RRETURN(MATCH_NOMATCH);              MRRETURN(MATCH_NOMATCH);
3849              }              }
3850            }            }
3851          break;          break;
# Line 3108  for (;;) Line 3853  for (;;)
3853          case OP_VSPACE:          case OP_VSPACE:
3854          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3855            {            {
3856            if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);            if (eptr >= md->end_subject)
3857                {
3858                SCHECK_PARTIAL();
3859                MRRETURN(MATCH_NOMATCH);
3860                }
3861            GETCHARINC(c, eptr);            GETCHARINC(c, eptr);
3862            switch(c)            switch(c)
3863              {              {
3864              default: RRETURN(MATCH_NOMATCH);              default: MRRETURN(MATCH_NOMATCH);
3865              case 0x0a:      /* LF */              case 0x0a:      /* LF */
3866              case 0x0b:      /* VT */              case 0x0b:      /* VT */
3867              case 0x0c:      /* FF */              case 0x0c:      /* FF */
# Line 3128  for (;;) Line 3877  for (;;)
3877          case OP_NOT_DIGIT:          case OP_NOT_DIGIT:
3878          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3879            {            {
3880            if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);            if (eptr >= md->end_subject)
3881                {
3882                SCHECK_PARTIAL();
3883                MRRETURN(MATCH_NOMATCH);
3884                }
3885            GETCHARINC(c, eptr);            GETCHARINC(c, eptr);
3886            if (c < 128 && (md->ctypes[c] & ctype_digit) != 0)            if (c < 128 && (md->ctypes[c] & ctype_digit) != 0)
3887              RRETURN(MATCH_NOMATCH);              MRRETURN(MATCH_NOMATCH);
3888            }            }
3889          break;          break;
3890    
3891          case OP_DIGIT:          case OP_DIGIT:
3892          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3893            {            {
3894            if (eptr >= md->end_subject ||            if (eptr >= md->end_subject)
3895               *eptr >= 128 || (md->ctypes[*eptr++] & ctype_digit) == 0)              {
3896              RRETURN(MATCH_NOMATCH);              SCHECK_PARTIAL();
3897                MRRETURN(MATCH_NOMATCH);
3898                }
3899              if (*eptr >= 128 || (md->ctypes[*eptr++] & ctype_digit) == 0)
3900                MRRETURN(MATCH_NOMATCH);
3901            /* 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 */
3902            }            }
3903          break;          break;
# Line 3148  for (;;) Line 3905  for (;;)
3905          case OP_NOT_WHITESPACE:          case OP_NOT_WHITESPACE:
3906          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3907            {            {
3908            if (eptr >= md->end_subject ||            if (eptr >= md->end_subject)
3909               (*eptr < 128 && (md->ctypes[*eptr] & ctype_space) != 0))              {
3910              RRETURN(MATCH_NOMATCH);              SCHECK_PARTIAL();
3911                MRRETURN(MATCH_NOMATCH);
3912                }
3913              if (*eptr < 128 && (md->ctypes[*eptr] & ctype_space) != 0)
3914                MRRETURN(MATCH_NOMATCH);
3915            while (++eptr < md->end_subject && (*eptr & 0xc0) == 0x80);            while (++eptr < md->end_subject && (*eptr & 0xc0) == 0x80);
3916            }            }
3917          break;          break;
# Line 3158  for (;;) Line 3919  for (;;)
3919          case OP_WHITESPACE:          case OP_WHITESPACE:
3920          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3921            {            {
3922            if (eptr >= md->end_subject ||            if (eptr >= md->end_subject)
3923               *eptr >= 128 || (md->ctypes[*eptr++] & ctype_space) == 0)              {
3924              RRETURN(MATCH_NOMATCH);              SCHECK_PARTIAL();
3925                MRRETURN(MATCH_NOMATCH);
3926                }
3927              if (*eptr >= 128 || (md->ctypes[*eptr++] & ctype_space) == 0)
3928                MRRETURN(MATCH_NOMATCH);
3929            /* 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 */
3930            }            }
3931          break;          break;
# Line 3168  for (;;) Line 3933  for (;;)
3933          case OP_NOT_WORDCHAR:          case OP_NOT_WORDCHAR:
3934          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3935            {            {
3936            if (eptr >= md->end_subject ||            if (eptr >= md->end_subject)
3937               (*eptr < 128 && (md->ctypes[*eptr] & ctype_word) != 0))              {
3938              RRETURN(MATCH_NOMATCH);              SCHECK_PARTIAL();
3939                MRRETURN(MATCH_NOMATCH);
3940                }
3941              if (*eptr < 128 && (md->ctypes[*eptr] & ctype_word) != 0)
3942                MRRETURN(MATCH_NOMATCH);
3943            while (++eptr < md->end_subject && (*eptr & 0xc0) == 0x80);            while (++eptr < md->end_subject && (*eptr & 0xc0) == 0x80);
3944            }            }
3945          break;          break;
# Line 3178  for (;;) Line 3947  for (;;)
3947          case OP_WORDCHAR:          case OP_WORDCHAR:
3948          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3949            {            {
3950            if (eptr >= md->end_subject ||            if (eptr >= md->end_subject)
3951               *eptr >= 128 || (md->ctypes[*eptr++] & ctype_word) == 0)              {
3952              RRETURN(MATCH_NOMATCH);              SCHECK_PARTIAL();
3953                MRRETURN(MATCH_NOMATCH);
3954                }
3955              if (*eptr >= 128 || (md->ctypes[*eptr++] & ctype_word) == 0)
3956                MRRETURN(MATCH_NOMATCH);
3957            /* 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 */
3958            }            }
3959          break;          break;
# Line 3193  for (;;) Line 3966  for (;;)
3966  #endif     /* SUPPORT_UTF8 */  #endif     /* SUPPORT_UTF8 */
3967    
3968        /* 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
3969        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. */  
3970    
3971        switch(ctype)        switch(ctype)
3972          {          {
3973          case OP_ANY:          case OP_ANY:
3974          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3975            {            {
3976            if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH);            if (eptr >= md->end_subject)
3977                {
3978                SCHECK_PARTIAL();
3979                MRRETURN(MATCH_NOMATCH);
3980                }
3981              if (IS_NEWLINE(eptr)) MRRETURN(MATCH_NOMATCH);
3982            eptr++;            eptr++;
3983            }            }
3984          break;          break;
3985    
3986          case OP_ALLANY:          case OP_ALLANY:
3987            if (eptr > md->end_subject - min)
3988              {
3989              SCHECK_PARTIAL();
3990              MRRETURN(MATCH_NOMATCH);
3991              }
3992          eptr += min;          eptr += min;
3993          break;          break;
3994    
3995          case OP_ANYBYTE:          case OP_ANYBYTE:
3996            if (eptr > md->end_subject - min)
3997              {
3998              SCHECK_PARTIAL();
3999              MRRETURN(MATCH_NOMATCH);
4000              }
4001          eptr += min;          eptr += min;
4002          break;          break;
4003    
         /* Because of the CRLF case, we can't assume the minimum number of  
         bytes are present in this case. */  
   
4004          case OP_ANYNL:          case OP_ANYNL:
4005          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
4006            {            {
4007            if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);            if (eptr >= md->end_subject)
4008                {
4009                SCHECK_PARTIAL();
4010                MRRETURN(MATCH_NOMATCH);
4011                }
4012            switch(*eptr++)            switch(*eptr++)
4013              {              {
4014              default: RRETURN(MATCH_NOMATCH);              default: MRRETURN(MATCH_NOMATCH);
4015              case 0x000d:              case 0x000d:
4016              if (eptr < md->end_subject && *eptr == 0x0a) eptr++;              if (eptr < md->end_subject && *eptr == 0x0a) eptr++;
4017              break;              break;
# Line 3233  for (;;) Line 4021  for (;;)
4021              case 0x000b:              case 0x000b:
4022              case 0x000c:              case 0x000c:
4023              case 0x0085:              case 0x0085:
4024              if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH);              if (md->bsr_anycrlf) MRRETURN(MATCH_NOMATCH);
4025              break;              break;
4026              }              }
4027            }            }
# Line 3242  for (;;) Line 4030  for (;;)
4030          case OP_NOT_HSPACE:          case OP_NOT_HSPACE:
4031          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
4032            {            {
4033            if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);            if (eptr >= md->end_subject)
4034                {
4035                SCHECK_PARTIAL();
4036                MRRETURN(MATCH_NOMATCH);
4037                }
4038            switch(*eptr++)            switch(*eptr++)
4039              {              {
4040              default: break;              default: break;
4041              case 0x09:      /* HT */              case 0x09:      /* HT */
4042              case 0x20:      /* SPACE */              case 0x20:      /* SPACE */
4043              case 0xa0:      /* NBSP */              case 0xa0:      /* NBSP */
4044              RRETURN(MATCH_NOMATCH);              MRRETURN(MATCH_NOMATCH);
4045              }              }
4046            }            }
4047          break;          break;
# Line 3257  for (;;) Line 4049  for (;;)
4049          case OP_HSPACE:          case OP_HSPACE:
4050          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
4051            {            {
4052            if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);            if (eptr >= md->end_subject)
4053                {
4054                SCHECK_PARTIAL();
4055                MRRETURN(MATCH_NOMATCH);
4056                }
4057            switch(*eptr++)            switch(*eptr++)
4058              {              {
4059              default: RRETURN(MATCH_NOMATCH);              default: MRRETURN(MATCH_NOMATCH);
4060              case 0x09:      /* HT */              case 0x09:      /* HT */
4061              case 0x20:      /* SPACE */              case 0x20:      /* SPACE */
4062              case 0xa0:      /* NBSP */              case 0xa0:      /* NBSP */
# Line 3272  for (;;) Line 4068  for (;;)
4068          case OP_NOT_VSPACE:          case OP_NOT_VSPACE:
4069          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
4070            {            {
4071            if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);            if (eptr >= md->end_subject)
4072                {
4073                SCHECK_PARTIAL();
4074                MRRETURN(MATCH_NOMATCH);
4075                }
4076            switch(*eptr++)            switch(*eptr++)
4077              {              {
4078              default: break;              default: break;
# Line 3281  for (;;) Line 4081  for (;;)
4081              case 0x0c:      /* FF */              case 0x0c:      /* FF */
4082              case 0x0d:      /* CR */              case 0x0d:      /* CR */
4083              case 0x85:      /* NEL */              case 0x85:      /* NEL */
4084              RRETURN(MATCH_NOMATCH);              MRRETURN(MATCH_NOMATCH);
4085              }              }
4086            }            }
4087          break;          break;
# Line 3289  for (;;) Line 4089  for (;;)
4089          case OP_VSPACE:          case OP_VSPACE:
4090          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
4091            {            {
4092            if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);            if (eptr >= md->end_subject)
4093                {
4094                SCHECK_PARTIAL();
4095                MRRETURN(MATCH_NOMATCH);
4096                }
4097            switch(*eptr++)            switch(*eptr++)
4098              {              {
4099              default: RRETURN(MATCH_NOMATCH);              default: MRRETURN(MATCH_NOMATCH);
4100              case 0x0a:      /* LF */              case 0x0a:      /* LF */
4101              case 0x0b:      /* VT */              case 0x0b:      /* VT */
4102              case 0x0c:      /* FF */              case 0x0c:      /* FF */
# Line 3305  for (;;) Line 4109  for (;;)
4109    
4110          case OP_NOT_DIGIT:          case OP_NOT_DIGIT:
4111          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
4112            if ((md->ctypes[*eptr++] & ctype_digit) != 0) RRETURN(MATCH_NOMATCH);            {
4113              if (eptr >= md->end_subject)
4114                {
4115                SCHECK_PARTIAL();
4116                MRRETURN(MATCH_NOMATCH);
4117                }
4118              if ((md->ctypes[*eptr++] & ctype_digit) != 0) MRRETURN(MATCH_NOMATCH);
4119              }
4120          break;          break;
4121    
4122          case OP_DIGIT:          case OP_DIGIT:
4123          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
4124            if ((md->ctypes[*eptr++] & ctype_digit) == 0) RRETURN(MATCH_NOMATCH);            {
4125              if (eptr >= md->end_subject)
4126                {
4127                SCHECK_PARTIAL();
4128                MRRETURN(MATCH_NOMATCH);
4129                }
4130              if ((md->ctypes[*eptr++] & ctype_digit) == 0) MRRETURN(MATCH_NOMATCH);
4131              }
4132          break;          break;
4133    
4134          case OP_NOT_WHITESPACE:          case OP_NOT_WHITESPACE:
4135          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
4136            if ((md->ctypes[*eptr++] & ctype_space) != 0) RRETURN(MATCH_NOMATCH);            {
4137              if (eptr >= md->end_subject)
4138                {
4139                SCHECK_PARTIAL();
4140                MRRETURN(MATCH_NOMATCH);
4141                }
4142              if ((md->ctypes[*eptr++] & ctype_space) != 0) MRRETURN(MATCH_NOMATCH);
4143              }
4144          break;          break;
4145    
4146          case OP_WHITESPACE:          case OP_WHITESPACE:
4147          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
4148            if ((md->ctypes[*eptr++] & ctype_space) == 0) RRETURN(MATCH_NOMATCH);            {
4149              if (eptr >= md->end_subject)
4150                {
4151                SCHECK_PARTIAL();
4152                MRRETURN(MATCH_NOMATCH);
4153                }
4154              if ((md->ctypes[*eptr++] & ctype_space) == 0) MRRETURN(MATCH_NOMATCH);
4155              }
4156          break;          break;
4157    
4158          case OP_NOT_WORDCHAR:          case OP_NOT_WORDCHAR:
4159          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
4160              {
4161              if (eptr >= md->end_subject)
4162                {
4163                SCHECK_PARTIAL();
4164                MRRETURN(MATCH_NOMATCH);
4165                }
4166            if ((md->ctypes[*eptr++] & ctype_word) != 0)            if ((md->ctypes[*eptr++] & ctype_word) != 0)
4167              RRETURN(MATCH_NOMATCH);              MRRETURN(MATCH_NOMATCH);
4168              }
4169          break;          break;
4170    
4171          case OP_WORDCHAR:          case OP_WORDCHAR:
4172          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
4173              {
4174              if (eptr >= md->end_subject)
4175                {
4176                SCHECK_PARTIAL();
4177                MRRETURN(MATCH_NOMATCH);
4178                }
4179            if ((md->ctypes[*eptr++] & ctype_word) == 0)            if ((md->ctypes[*eptr++] & ctype_word) == 0)
4180              RRETURN(MATCH_NOMATCH);              MRRETURN(MATCH_NOMATCH);
4181              }
4182          break;          break;
4183    
4184          default:          default:
# Line 3360  for (;;) Line 4206  for (;;)
4206              {              {
4207              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM36);              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM36);
4208              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
4209              if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);              if (fi >= max) MRRETURN(MATCH_NOMATCH);
4210                if (eptr >= md->end_subject)
4211                  {
4212                  SCHECK_PARTIAL();
4213                  MRRETURN(MATCH_NOMATCH);
4214                  }
4215              GETCHARINC(c, eptr);              GETCHARINC(c, eptr);
4216              if (prop_fail_result) RRETURN(MATCH_NOMATCH);              if (prop_fail_result) MRRETURN(MATCH_NOMATCH);
4217              }              }
4218            /* Control never gets here */            /* Control never gets here */
4219    
# Line 3371  for (;;) Line 4222  for (;;)
4222              {              {
4223              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM37);              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM37);
4224              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
4225              if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);              if (fi >= max) MRRETURN(MATCH_NOMATCH);
4226                if (eptr >= md->end_subject)
4227                  {
4228                  SCHECK_PARTIAL();
4229                  MRRETURN(MATCH_NOMATCH);
4230                  }
4231              GETCHARINC(c, eptr);              GETCHARINC(c, eptr);
4232              prop_chartype = UCD_CHARTYPE(c);              prop_chartype = UCD_CHARTYPE(c);
4233              if ((prop_chartype == ucp_Lu ||              if ((prop_chartype == ucp_Lu ||
4234                   prop_chartype == ucp_Ll ||                   prop_chartype == ucp_Ll ||
4235                   prop_chartype == ucp_Lt) == prop_fail_result)                   prop_chartype == ucp_Lt) == prop_fail_result)
4236                RRETURN(MATCH_NOMATCH);                MRRETURN(MATCH_NOMATCH);
4237              }              }
4238            /* Control never gets here */            /* Control never gets here */
4239    
# Line 3386  for (;;) Line 4242  for (;;)
4242              {              {
4243              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM38);              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM38);
4244              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
4245              if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);              if (fi >= max) MRRETURN(MATCH_NOMATCH);
4246                if (eptr >= md->end_subject)
4247                  {
4248                  SCHECK_PARTIAL();
4249                  MRRETURN(MATCH_NOMATCH);
4250                  }
4251              GETCHARINC(c, eptr);              GETCHARINC(c, eptr);
4252              prop_category = UCD_CATEGORY(c);              prop_category = UCD_CATEGORY(c);
4253              if ((prop_category == prop_value) == prop_fail_result)              if ((prop_category == prop_value) == prop_fail_result)
4254                RRETURN(MATCH_NOMATCH);                MRRETURN(MATCH_NOMATCH);
4255              }              }
4256            /* Control never gets here */            /* Control never gets here */
4257    
# Line 3399  for (;;) Line 4260  for (;;)
4260              {              {
4261              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM39);              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM39);
4262              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
4263              if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);              if (fi >= max) MRRETURN(MATCH_NOMATCH);
4264                if (eptr >= md->end_subject)
4265                  {
4266                  SCHECK_PARTIAL();
4267                  MRRETURN(MATCH_NOMATCH);
4268                  }
4269              GETCHARINC(c, eptr);              GETCHARINC(c, eptr);
4270              prop_chartype = UCD_CHARTYPE(c);              prop_chartype = UCD_CHARTYPE(c);
4271              if ((prop_chartype == prop_value) == prop_fail_result)              if ((prop_chartype == prop_value) == prop_fail_result)
4272                RRETURN(MATCH_NOMATCH);                MRRETURN(MATCH_NOMATCH);
4273              }              }
4274            /* Control never gets here */            /* Control never gets here */
4275    
# Line 3412  for (;;) Line 4278  for (;;)
4278              {              {
4279              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM40);              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM40);
4280              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
4281              if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);              if (fi >= max) MRRETURN(MATCH_NOMATCH);
4282                if (eptr >= md->end_subject)
4283                  {
4284                  SCHECK_PARTIAL();
4285                  MRRETURN(MATCH_NOMATCH);
4286                  }
4287              GETCHARINC(c, eptr);              GETCHARINC(c, eptr);
4288              prop_script = UCD_SCRIPT(c);              prop_script = UCD_SCRIPT(c);
4289              if ((prop_script == prop_value) == prop_fail_result)              if ((prop_script == prop_value) == prop_fail_result)
4290                RRETURN(MATCH_NOMATCH);                MRRETURN(MATCH_NOMATCH);
4291                }
4292              /* Control never gets here */
4293    
4294              case PT_ALNUM:
4295              for (fi = min;; fi++)
4296                {
4297                RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM39);
4298                if (rrc != MATCH_NOMATCH) RRETURN(rrc);
4299                if (fi >= max) MRRETURN(MATCH_NOMATCH);
4300                if (eptr >= md->end_subject)
4301                  {
4302                  SCHECK_PARTIAL();
4303                  MRRETURN(MATCH_NOMATCH);
4304                  }
4305                GETCHARINC(c, eptr);
4306                prop_category = UCD_CATEGORY(c);
4307                if ((prop_category == ucp_L || prop_category == ucp_N)
4308                       == prop_fail_result)
4309                  MRRETURN(MATCH_NOMATCH);
4310                }
4311              /* Control never gets here */
4312    
4313              case PT_SPACE:    /* Perl space */
4314              for (fi = min;; fi++)
4315                {
4316                RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM39);
4317                if (rrc != MATCH_NOMATCH) RRETURN(rrc);
4318                if (fi >= max) MRRETURN(MATCH_NOMATCH);
4319                if (eptr >= md->end_subject)
4320                  {
4321                  SCHECK_PARTIAL();
4322                  MRRETURN(MATCH_NOMATCH);
4323                  }
4324                GETCHARINC(c, eptr);
4325                prop_category = UCD_CATEGORY(c);
4326                if ((prop_category == ucp_Z || c == CHAR_HT || c == CHAR_NL ||
4327                     c == CHAR_FF || c == CHAR_CR)
4328                       == prop_fail_result)
4329                  MRRETURN(MATCH_NOMATCH);
4330                }
4331              /* Control never gets here */
4332    
4333              case PT_PXSPACE:  /* POSIX space */
4334              for (fi = min;; fi++)
4335                {
4336                RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM39);
4337                if (rrc != MATCH_NOMATCH) RRETURN(rrc);
4338                if (fi >= max) MRRETURN(MATCH_NOMATCH);
4339                if (eptr >= md->end_subject)
4340                  {
4341                  SCHECK_PARTIAL();
4342                  MRRETURN(MATCH_NOMATCH);
4343                  }
4344                GETCHARINC(c, eptr);
4345                prop_category = UCD_CATEGORY(c);
4346                if ((prop_category == ucp_Z || c == CHAR_HT || c == CHAR_NL ||
4347                     c == CHAR_VT || c == CHAR_FF || c == CHAR_CR)
4348                       == prop_fail_result)
4349                  MRRETURN(MATCH_NOMATCH);
4350                }
4351              /* Control never gets here */
4352    
4353              case PT_WORD:
4354              for (fi = min;; fi++)
4355                {
4356                RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM39);
4357                if (rrc != MATCH_NOMATCH) RRETURN(rrc);
4358                if (fi >= max) MRRETURN(MATCH_NOMATCH);
4359                if (eptr >= md->end_subject)
4360                  {
4361                  SCHECK_PARTIAL();
4362                  MRRETURN(MATCH_NOMATCH);
4363                  }
4364                GETCHARINC(c, eptr);
4365                prop_category = UCD_CATEGORY(c);
4366                if ((prop_category == ucp_L ||
4367                     prop_category == ucp_N ||
4368                     c == CHAR_UNDERSCORE)
4369                       == prop_fail_result)
4370                  MRRETURN(MATCH_NOMATCH);
4371              }              }
4372            /* Control never gets here */            /* Control never gets here */
4373    
4374              /* This should never occur */
4375    
4376            default:            default:
4377            RRETURN(PCRE_ERROR_INTERNAL);            RRETURN(PCRE_ERROR_INTERNAL);
4378            }            }
# Line 3434  for (;;) Line 4387  for (;;)
4387            {            {
4388            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM41);            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM41);
4389            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
4390            if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);            if (fi >= max) MRRETURN(MATCH_NOMATCH);
4391              if (eptr >= md->end_subject)
4392                {
4393                SCHECK_PARTIAL();
4394                MRRETURN(MATCH_NOMATCH);
4395                }
4396            GETCHARINCTEST(c, eptr);            GETCHARINCTEST(c, eptr);
4397            prop_category = UCD_CATEGORY(c);            prop_category = UCD_CATEGORY(c);
4398            if (prop_category == ucp_M) RRETURN(MATCH_NOMATCH);            if (prop_category == ucp_M) MRRETURN(MATCH_NOMATCH);
4399            while (eptr < md->end_subject)            while (eptr < md->end_subject)
4400              {              {
4401              int len = 1;              int len = 1;
4402              if (!utf8) c = *eptr; else              if (!utf8) c = *eptr;
4403                {                else { GETCHARLEN(c, eptr, len); }
               GETCHARLEN(c, eptr, len);  
               }  
4404              prop_category = UCD_CATEGORY(c);              prop_category = UCD_CATEGORY(c);
4405              if (prop_category != ucp_M) break;              if (prop_category != ucp_M) break;
4406              eptr += len;              eptr += len;
# Line 3463  for (;;) Line 4419  for (;;)
4419            {            {
4420            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM42);            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM42);
4421            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
4422            if (fi >= max || eptr >= md->end_subject ||            if (fi >= max) MRRETURN(MATCH_NOMATCH);
4423                 (ctype == OP_ANY && IS_NEWLINE(eptr)))            if (eptr >= md->end_subject)
4424              RRETURN(MATCH_NOMATCH);              {
4425                SCHECK_PARTIAL();
4426                MRRETURN(MATCH_NOMATCH);
4427                }
4428              if (ctype == OP_ANY && IS_NEWLINE(eptr))
4429                MRRETURN(MATCH_NOMATCH);
4430            GETCHARINC(c, eptr);            GETCHARINC(c, eptr);
4431            switch(ctype)            switch(ctype)
4432              {              {
# Line 3478  for (;;) Line 4438  for (;;)
4438              case OP_ANYNL:              case OP_ANYNL:
4439              switch(c)              switch(c)
4440                {                {
4441                default: RRETURN(MATCH_NOMATCH);                default: MRRETURN(MATCH_NOMATCH);
4442                case 0x000d:                case 0x000d:
4443                if (eptr < md->end_subject && *eptr == 0x0a) eptr++;                if (eptr < md->end_subject && *eptr == 0x0a) eptr++;
4444                break;                break;
# Line 3490  for (;;) Line 4450  for (;;)
4450                case 0x0085:                case 0x0085:
4451                case 0x2028:                case 0x2028:
4452                case 0x2029:                case 0x2029:
4453                if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH);                if (md->bsr_anycrlf) MRRETURN(MATCH_NOMATCH);
4454                break;                break;
4455                }                }
4456              break;              break;
# Line 3518  for (;;) Line 4478  for (;;)
4478                case 0x202f:    /* NARROW NO-BREAK SPACE */                case 0x202f:    /* NARROW NO-BREAK SPACE */
4479                case 0x205f:    /* MEDIUM MATHEMATICAL SPACE */                case 0x205f:    /* MEDIUM MATHEMATICAL SPACE */
4480                case 0x3000:    /* IDEOGRAPHIC SPACE */                case 0x3000:    /* IDEOGRAPHIC SPACE */
4481                RRETURN(MATCH_NOMATCH);                MRRETURN(MATCH_NOMATCH);
4482                }                }
4483              break;              break;
4484    
4485              case OP_HSPACE:              case OP_HSPACE:
4486              switch(c)              switch(c)
4487                {                {
4488                default: RRETURN(MATCH_NOMATCH);                default: MRRETURN(MATCH_NOMATCH);
4489                case 0x09:      /* HT */                case 0x09:      /* HT */
4490                case 0x20:      /* SPACE */                case 0x20:      /* SPACE */
4491                case 0xa0:      /* NBSP */                case 0xa0:      /* NBSP */
# Line 3560  for (;;) Line 4520  for (;;)
4520                case 0x85:      /* NEL */                case 0x85:      /* NEL */
4521                case 0x2028:    /* LINE SEPARATOR */                case 0x2028:    /* LINE SEPARATOR */
4522                case 0x2029:    /* PARAGRAPH SEPARATOR */                case 0x2029:    /* PARAGRAPH SEPARATOR */
4523                RRETURN(MATCH_NOMATCH);                MRRETURN(MATCH_NOMATCH);
4524                }                }
4525              break;              break;
4526    
4527              case OP_VSPACE:              case OP_VSPACE:
4528              switch(c)              switch(c)
4529                {                {
4530                default: RRETURN(MATCH_NOMATCH);                default: MRRETURN(MATCH_NOMATCH);
4531                case 0x0a:      /* LF */                case 0x0a:      /* LF */
4532                case 0x0b:      /* VT */                case 0x0b:      /* VT */
4533                case 0x0c:      /* FF */                case 0x0c:      /* FF */
# Line 3581  for (;;) Line 4541  for (;;)
4541    
4542              case OP_NOT_DIGIT:              case OP_NOT_DIGIT:
4543              if (c < 256 && (md->ctypes[c] & ctype_digit) != 0)              if (c < 256 && (md->ctypes[c] & ctype_digit) != 0)
4544                RRETURN(MATCH_NOMATCH);                MRRETURN(MATCH_NOMATCH);
4545              break;              break;
4546    
4547              case OP_DIGIT:              case OP_DIGIT:
4548              if (c >= 256 || (md->ctypes[c] & ctype_digit) == 0)              if (c >= 256 || (md->ctypes[c] & ctype_digit) == 0)
4549                RRETURN(MATCH_NOMATCH);                MRRETURN(MATCH_NOMATCH);
4550              break;              break;
4551    
4552              case OP_NOT_WHITESPACE:              case OP_NOT_WHITESPACE:
4553              if (c < 256 && (md->ctypes[c] & ctype_space) != 0)              if (c < 256 && (md->ctypes[c] & ctype_space) != 0)
4554                RRETURN(MATCH_NOMATCH);                MRRETURN(MATCH_NOMATCH);
4555              break;              break;
4556    
4557              case OP_WHITESPACE:              case OP_WHITESPACE:
4558              if  (c >= 256 || (md->ctypes[c] & ctype_space) == 0)              if  (c >= 256 || (md->ctypes[c] & ctype_space) == 0)
4559                RRETURN(MATCH_NOMATCH);                MRRETURN(MATCH_NOMATCH);
4560              break;              break;
4561    
4562              case OP_NOT_WORDCHAR:              case OP_NOT_WORDCHAR:
4563              if (c < 256 && (md->ctypes[c] & ctype_word) != 0)              if (c < 256 && (md->ctypes[c] & ctype_word) != 0)
4564                RRETURN(MATCH_NOMATCH);                MRRETURN(MATCH_NOMATCH);
4565              break;              break;
4566    
4567              case OP_WORDCHAR:              case OP_WORDCHAR:
4568              if (c >= 256 || (md->ctypes[c] & ctype_word) == 0)              if (c >= 256 || (md->ctypes[c] & ctype_word) == 0)
4569                RRETURN(MATCH_NOMATCH);                MRRETURN(MATCH_NOMATCH);
4570              break;              break;
4571    
4572              default:              default:
# Line 3622  for (;;) Line 4582  for (;;)
4582            {            {
4583            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM43);            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM43);
4584            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
4585            if (fi >= max || eptr >= md->end_subject ||            if (fi >= max) MRRETURN(MATCH_NOMATCH);
4586                 (ctype == OP_ANY && IS_NEWLINE(eptr)))            if (eptr >= md->end_subject)
4587              RRETURN(MATCH_NOMATCH);              {
4588                SCHECK_PARTIAL();
4589                MRRETURN(MATCH_NOMATCH);
4590                }
4591              if (ctype == OP_ANY && IS_NEWLINE(eptr))
4592                MRRETURN(MATCH_NOMATCH);
4593            c = *eptr++;            c = *eptr++;
4594            switch(ctype)            switch(ctype)
4595              {              {
# Line 3637  for (;;) Line 4601  for (;;)
4601              case OP_ANYNL:              case OP_ANYNL:
4602              switch(c)              switch(c)
4603                {                {
4604                default: RRETURN(MATCH_NOMATCH);                default: MRRETURN(MATCH_NOMATCH);
4605                case 0x000d:                case 0x000d:
4606                if (eptr < md->end_subject && *eptr == 0x0a) eptr++;                if (eptr < md->end_subject && *eptr == 0x0a) eptr++;
4607                break;                break;
# Line 3648  for (;;) Line 4612  for (;;)
4612                case 0x000b:                case 0x000b:
4613                case 0x000c:                case 0x000c:
4614                case 0x0085:                case 0x0085:
4615                if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH);                if (md->bsr_anycrlf) MRRETURN(MATCH_NOMATCH);
4616                break;                break;
4617                }                }
4618              break;              break;
# Line 3660  for (;;) Line 4624  for (;;)
4624                case 0x09:      /* HT */                case 0x09:      /* HT */
4625                case 0x20:      /* SPACE */                case 0x20:      /* SPACE */
4626                case 0xa0:      /* NBSP */                case 0xa0:      /* NBSP */
4627                RRETURN(MATCH_NOMATCH);                MRRETURN(MATCH_NOMATCH);
4628                }                }
4629              break;              break;
4630    
4631              case OP_HSPACE:              case OP_HSPACE:
4632              switch(c)              switch(c)
4633                {                {
4634                default: RRETURN(MATCH_NOMATCH);                default: MRRETURN(MATCH_NOMATCH);
4635                case 0x09:      /* HT */                case 0x09:      /* HT */
4636                case 0x20:      /* SPACE */                case 0x20:      /* SPACE */
4637                case 0xa0:      /* NBSP */                case 0xa0:      /* NBSP */
# Line 3684  for (;;) Line 4648  for (;;)
4648                case 0x0c:      /* FF */                case 0x0c:      /* FF */
4649                case 0x0d:      /* CR */                case 0x0d:      /* CR */
4650                case 0x85:      /* NEL */                case 0x85:      /* NEL */
4651                RRETURN(MATCH_NOMATCH);                MRRETURN(MATCH_NOMATCH);
4652                }                }
4653              break;              break;
4654    
4655              case OP_VSPACE:              case OP_VSPACE:
4656              switch(c)              switch(c)
4657                {                {
4658                default: RRETURN(MATCH_NOMATCH);                default: MRRETURN(MATCH_NOMATCH);
4659                case 0x0a:      /* LF */                case 0x0a:      /* LF */
4660                case 0x0b:      /* VT */                case 0x0b:      /* VT */
4661                case 0x0c:      /* FF */                case 0x0c:      /* FF */
# Line 3702  for (;;) Line 4666  for (;;)
4666              break;              break;
4667    
4668              case OP_NOT_DIGIT:              case OP_NOT_DIGIT:
4669              if ((md->ctypes[c] & ctype_digit) != 0) RRETURN(MATCH_NOMATCH);              if ((md->ctypes[c] & ctype_digit) != 0) MRRETURN(MATCH_NOMATCH);
4670              break;              break;
4671    
4672              case OP_DIGIT:              case OP_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_NOT_WHITESPACE:              case OP_NOT_WHITESPACE:
4677              if ((md->ctypes[c] & ctype_space) != 0) RRETURN(MATCH_NOMATCH);              if ((md->ctypes[c] & ctype_space) != 0) MRRETURN(MATCH_NOMATCH);
4678              break;              break;
4679    
4680              case OP_WHITESPACE:              case OP_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_NOT_WORDCHAR:              case OP_NOT_WORDCHAR:
4685              if ((md->ctypes[c] & ctype_word) != 0) RRETURN(MATCH_NOMATCH);              if ((md->ctypes[c] & ctype_word) != 0) MRRETURN(MATCH_NOMATCH);
4686              break;              break;
4687    
4688              case OP_WORDCHAR:              case OP_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              default:              default:
# Line 3750  for (;;) Line 4714  for (;;)
4714            for (i = min; i < max; i++)            for (i = min; i < max; i++)
4715              {              {
4716              int len = 1;              int len = 1;
4717              if (eptr >= md->end_subject) break;              if (eptr >= md->end_subject)
4718                  {
4719                  SCHECK_PARTIAL();
4720                  break;
4721                  }
4722              GETCHARLEN(c, eptr, len);              GETCHARLEN(c, eptr, len);
4723              if (prop_fail_result) break;              if (prop_fail_result) break;
4724              eptr+= len;              eptr+= len;
# Line 3761  for (;;) Line 4729  for (;;)
4729            for (i = min; i < max; i++)            for (i = min; i < max; i++)
4730              {              {
4731              int len = 1;              int len = 1;
4732              if (eptr >= md->end_subject) break;              if (eptr >= md->end_subject)
4733                  {
4734                  SCHECK_PARTIAL();
4735                  break;
4736                  }
4737              GETCHARLEN(c, eptr, len);              GETCHARLEN(c, eptr, len);
4738              prop_chartype = UCD_CHARTYPE(c);              prop_chartype = UCD_CHARTYPE(c);
4739              if ((prop_chartype == ucp_Lu ||              if ((prop_chartype == ucp_Lu ||
# Line 3776  for (;;) Line 4748  for (;;)
4748            for (i = min; i < max; i++)            for (i = min; i < max; i++)
4749              {              {
4750              int len = 1;              int len = 1;
4751              if (eptr >= md->end_subject) break;              if (eptr >= md->end_subject)
4752                  {
4753                  SCHECK_PARTIAL();
4754                  break;
4755                  }
4756              GETCHARLEN(c, eptr, len);              GETCHARLEN(c, eptr, len);
4757              prop_category = UCD_CATEGORY(c);              prop_category = UCD_CATEGORY(c);
4758              if ((prop_category == prop_value) == prop_fail_result)              if ((prop_category == prop_value) == prop_fail_result)
# Line 3789  for (;;) Line 4765  for (;;)
4765            for (i = min; i < max; i++)            for (i = min; i < max; i++)
4766              {              {
4767              int len = 1;              int len = 1;
4768              if (eptr >= md->end_subject) break;              if (eptr >= md->end_subject)
4769                  {
4770                  SCHECK_PARTIAL();
4771                  break;
4772                  }
4773              GETCHARLEN(c, eptr, len);              GETCHARLEN(c, eptr, len);
4774              prop_chartype = UCD_CHARTYPE(c);              prop_chartype = UCD_CHARTYPE(c);
4775              if ((prop_chartype == prop_value) == prop_fail_result)              if ((prop_chartype == prop_value) == prop_fail_result)
# Line 3802  for (;;) Line 4782  for (;;)
4782            for (i = min; i < max; i++)            for (i = min; i < max; i++)
4783              {              {
4784              int len = 1;              int len = 1;
4785              if (eptr >= md->end_subject) break;              if (eptr >= md->end_subject)
4786                  {
4787                  SCHECK_PARTIAL();
4788                  break;
4789                  }
4790              GETCHARLEN(c, eptr, len);              GETCHARLEN(c, eptr, len);
4791              prop_script = UCD_SCRIPT(c);              prop_script = UCD_SCRIPT(c);
4792              if ((prop_script == prop_value) == prop_fail_result)              if ((prop_script == prop_value) == prop_fail_result)
# Line 3810  for (;;) Line 4794  for (;;)
4794              eptr+= len;              eptr+= len;
4795              }              }
4796            break;            break;
4797    
4798              case PT_ALNUM:
4799              for (i = min; i < max; i++)
4800                {
4801                int len = 1;
4802                if (eptr >= md->end_subject)
4803                  {
4804                  SCHECK_PARTIAL();
4805                  break;
4806                  }
4807                GETCHARLEN(c, eptr, len);
4808                prop_category = UCD_CATEGORY(c);
4809                if ((prop_category == ucp_L || prop_category == ucp_N)
4810                     == prop_fail_result)
4811                  break;
4812                eptr+= len;
4813                }
4814              break;
4815    
4816              case PT_SPACE:    /* Perl space */
4817              for (i = min; i < max; i++)
4818                {
4819                int len = 1;
4820                if (eptr >= md->end_subject)
4821                  {
4822                  SCHECK_PARTIAL();
4823                  break;
4824                  }
4825                GETCHARLEN(c, eptr, len);
4826                prop_category = UCD_CATEGORY(c);
4827                if ((prop_category == ucp_Z || c == CHAR_HT || c == CHAR_NL ||
4828                     c == CHAR_FF || c == CHAR_CR)
4829                     == prop_fail_result)
4830                  break;
4831                eptr+= len;
4832                }
4833              break;
4834    
4835              case PT_PXSPACE:  /* POSIX space */
4836              for (i = min; i < max; i++)
4837                {
4838                int len = 1;
4839                if (eptr >= md->end_subject)
4840                  {
4841                  SCHECK_PARTIAL();
4842                  break;
4843                  }
4844                GETCHARLEN(c, eptr, len);
4845                prop_category = UCD_CATEGORY(c);
4846                if ((prop_category == ucp_Z || c == CHAR_HT || c == CHAR_NL ||
4847                     c == CHAR_VT || c == CHAR_FF || c == CHAR_CR)
4848                     == prop_fail_result)
4849                  break;
4850                eptr+= len;
4851                }
4852              break;
4853    
4854              case PT_WORD:
4855              for (i = min; i < max; i++)
4856                {
4857                int len = 1;
4858                if (eptr >= md->end_subject)
4859                  {
4860                  SCHECK_PARTIAL();
4861                  break;