/[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 426 by ph10, Wed Aug 26 15:38:32 2009 UTC revision 551 by ph10, Sun Oct 10 17:33:07 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-2009 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 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, RM59, RM60,
259           RM61,  RM62 };
260    
261  /* These versions of the macros use the stack, as normal. There are debugging  /* These versions of the macros use the stack, as normal. There are debugging
262  versions and production versions. Note that the "rw" argument of RMATCH isn't  versions and production versions. Note that the "rw" argument of RMATCH isn't
263  actuall used in this definition. */  actually used in this definition. */
264    
265  #ifndef NO_RECURSE  #ifndef NO_RECURSE
266  #define REGISTER register  #define REGISTER register
267    
268  #ifdef DEBUG  #ifdef PCRE_DEBUG
269  #define RMATCH(ra,rb,rc,rd,re,rf,rg,rw) \  #define RMATCH(ra,rb,rc,rd,re,rf,rg,rw) \
270    { \    { \
271    printf("match() called in line %d\n", __LINE__); \    printf("match() called in line %d\n", __LINE__); \
272    rrc = match(ra,rb,mstart,rc,rd,re,rf,rg,rdepth+1); \    rrc = match(ra,rb,mstart,markptr,rc,rd,re,rf,rg,rdepth+1); \
273    printf("to line %d\n", __LINE__); \    printf("to line %d\n", __LINE__); \
274    }    }
275  #define RRETURN(ra) \  #define RRETURN(ra) \
# Line 268  actuall used in this definition. */ Line 279  actuall used in this definition. */
279    }    }
280  #else  #else
281  #define RMATCH(ra,rb,rc,rd,re,rf,rg,rw) \  #define RMATCH(ra,rb,rc,rd,re,rf,rg,rw) \
282    rrc = match(ra,rb,mstart,rc,rd,re,rf,rg,rdepth+1)    rrc = match(ra,rb,mstart,markptr,rc,rd,re,rf,rg,rdepth+1)
283  #define RRETURN(ra) return ra  #define RRETURN(ra) return ra
284  #endif  #endif
285    
# Line 284  argument of match(), which never changes Line 295  argument of match(), which never changes
295  #define RMATCH(ra,rb,rc,rd,re,rf,rg,rw)\  #define RMATCH(ra,rb,rc,rd,re,rf,rg,rw)\
296    {\    {\
297    heapframe *newframe = (pcre_stack_malloc)(sizeof(heapframe));\    heapframe *newframe = (pcre_stack_malloc)(sizeof(heapframe));\
298      if (newframe == NULL) RRETURN(PCRE_ERROR_NOMEMORY);\
299    frame->Xwhere = rw; \    frame->Xwhere = rw; \
300    newframe->Xeptr = ra;\    newframe->Xeptr = ra;\
301    newframe->Xecode = rb;\    newframe->Xecode = rb;\
302    newframe->Xmstart = mstart;\    newframe->Xmstart = mstart;\
303      newframe->Xmarkptr = markptr;\
304    newframe->Xoffset_top = rc;\    newframe->Xoffset_top = rc;\
305    newframe->Xims = re;\    newframe->Xims = re;\
306    newframe->Xeptrb = rf;\    newframe->Xeptrb = rf;\
# Line 303  argument of match(), which never changes Line 316  argument of match(), which never changes
316    
317  #define RRETURN(ra)\  #define RRETURN(ra)\
318    {\    {\
319    heapframe *newframe = frame;\    heapframe *oldframe = frame;\
320    frame = newframe->Xprevframe;\    frame = oldframe->Xprevframe;\
321    (pcre_stack_free)(newframe);\    (pcre_stack_free)(oldframe);\
322    if (frame != NULL)\    if (frame != NULL)\
323      {\      {\
324      rrc = ra;\      rrc = ra;\
# Line 325  typedef struct heapframe { Line 338  typedef struct heapframe {
338    USPTR Xeptr;    USPTR Xeptr;
339    const uschar *Xecode;    const uschar *Xecode;
340    USPTR Xmstart;    USPTR Xmstart;
341      USPTR Xmarkptr;
342    int Xoffset_top;    int Xoffset_top;
343    long int Xims;    long int Xims;
344    eptrblock *Xeptrb;    eptrblock *Xeptrb;
# Line 403  same response. */ Line 417  same response. */
417  /* These macros pack up tests that are used for partial matching, and which  /* These macros pack up tests that are used for partial matching, and which
418  appears several times in the code. We set the "hit end" flag if the pointer is  appears several times in the code. We set the "hit end" flag if the pointer is
419  at the end of the subject and also past the start of the subject (i.e.  at the end of the subject and also past the start of the subject (i.e.
420  something has been matched). The second one is used when we already know we are  something has been matched). For hard partial matching, we then return
421  past the end of the subject. */  immediately. The second one is used when we already know we are past the end of
422    the subject. */
423    
424  #define CHECK_PARTIAL()\  #define CHECK_PARTIAL()\
425    if (md->partial && eptr >= md->end_subject && eptr > mstart)\    if (md->partial != 0 && eptr >= md->end_subject && eptr > mstart)\
426      md->hitend = TRUE      {\
427        md->hitend = TRUE;\
428        if (md->partial > 1) MRRETURN(PCRE_ERROR_PARTIAL);\
429        }
430    
431  #define SCHECK_PARTIAL()\  #define SCHECK_PARTIAL()\
432    if (md->partial && eptr > mstart) md->hitend = TRUE    if (md->partial != 0 && eptr > mstart)\
433        {\
434        md->hitend = TRUE;\
435        if (md->partial > 1) MRRETURN(PCRE_ERROR_PARTIAL);\
436        }
437    
438    
439  /* Performance note: It might be tempting to extract commonly used fields from  /* Performance note: It might be tempting to extract commonly used fields from
440  the md structure (e.g. utf8, end_subject) into individual variables to improve  the md structure (e.g. utf8, end_subject) into individual variables to improve
# Line 423  Arguments: Line 446  Arguments:
446     ecode       pointer to current position in compiled code     ecode       pointer to current position in compiled code
447     mstart      pointer to the current match start position (can be modified     mstart      pointer to the current match start position (can be modified
448                   by encountering \K)                   by encountering \K)
449       markptr     pointer to the most recent MARK name, or NULL
450     offset_top  current top pointer     offset_top  current top pointer
451     md          pointer to "static" info for the match     md          pointer to "static" info for the match
452     ims         current /i, /m, and /s options     ims         current /i, /m, and /s options
# Line 436  Arguments: Line 460  Arguments:
460    
461  Returns:       MATCH_MATCH if matched            )  these values are >= 0  Returns:       MATCH_MATCH if matched            )  these values are >= 0
462                 MATCH_NOMATCH if failed to match  )                 MATCH_NOMATCH if failed to match  )
463                   a negative MATCH_xxx value for PRUNE, SKIP, etc
464                 a negative PCRE_ERROR_xxx value if aborted by an error condition                 a negative PCRE_ERROR_xxx value if aborted by an error condition
465                   (e.g. stopped by repeated call or recursion limit)                   (e.g. stopped by repeated call or recursion limit)
466  */  */
467    
468  static int  static int
469  match(REGISTER USPTR eptr, REGISTER const uschar *ecode, USPTR mstart,  match(REGISTER USPTR eptr, REGISTER const uschar *ecode, USPTR mstart,
470    int offset_top, match_data *md, unsigned long int ims, eptrblock *eptrb,    const uschar *markptr, int offset_top, match_data *md, unsigned long int ims,
471    int flags, unsigned int rdepth)    eptrblock *eptrb, int flags, unsigned int rdepth)
472  {  {
473  /* These variables do not need to be preserved over recursion in this function,  /* These variables do not need to be preserved over recursion in this function,
474  so they can be ordinary variables in all cases. Mark some of them with  so they can be ordinary variables in all cases. Mark some of them with
# Line 464  heap whenever RMATCH() does a "recursion Line 489  heap whenever RMATCH() does a "recursion
489    
490  #ifdef NO_RECURSE  #ifdef NO_RECURSE
491  heapframe *frame = (pcre_stack_malloc)(sizeof(heapframe));  heapframe *frame = (pcre_stack_malloc)(sizeof(heapframe));
492    if (frame == NULL) RRETURN(PCRE_ERROR_NOMEMORY);
493  frame->Xprevframe = NULL;            /* Marks the top level */  frame->Xprevframe = NULL;            /* Marks the top level */
494    
495  /* Copy in the original argument variables */  /* Copy in the original argument variables */
# Line 471  frame->Xprevframe = NULL; /* Line 497  frame->Xprevframe = NULL; /*
497  frame->Xeptr = eptr;  frame->Xeptr = eptr;
498  frame->Xecode = ecode;  frame->Xecode = ecode;
499  frame->Xmstart = mstart;  frame->Xmstart = mstart;
500    frame->Xmarkptr = markptr;
501  frame->Xoffset_top = offset_top;  frame->Xoffset_top = offset_top;
502  frame->Xims = ims;  frame->Xims = ims;
503  frame->Xeptrb = eptrb;  frame->Xeptrb = eptrb;
# Line 486  HEAP_RECURSE: Line 513  HEAP_RECURSE:
513  #define eptr               frame->Xeptr  #define eptr               frame->Xeptr
514  #define ecode              frame->Xecode  #define ecode              frame->Xecode
515  #define mstart             frame->Xmstart  #define mstart             frame->Xmstart
516    #define markptr            frame->Xmarkptr
517  #define offset_top         frame->Xoffset_top  #define offset_top         frame->Xoffset_top
518  #define ims                frame->Xims  #define ims                frame->Xims
519  #define eptrb              frame->Xeptrb  #define eptrb              frame->Xeptrb
# Line 613  TAIL_RECURSE: Line 641  TAIL_RECURSE:
641  /* OK, now we can get on with the real code of the function. Recursive calls  /* OK, now we can get on with the real code of the function. Recursive calls
642  are specified by the macro RMATCH and RRETURN is used to return. When  are specified by the macro RMATCH and RRETURN is used to return. When
643  NO_RECURSE is *not* defined, these just turn into a recursive call to match()  NO_RECURSE is *not* defined, these just turn into a recursive call to match()
644  and a "return", respectively (possibly with some debugging if DEBUG is  and a "return", respectively (possibly with some debugging if PCRE_DEBUG is
645  defined). However, RMATCH isn't like a function call because it's quite a  defined). However, RMATCH isn't like a function call because it's quite a
646  complicated macro. It has to be used in one particular way. This shouldn't,  complicated macro. It has to be used in one particular way. This shouldn't,
647  however, impact performance when true recursion is being used. */  however, impact performance when true recursion is being used. */
# Line 655  for (;;) Line 683  for (;;)
683    minimize = possessive = FALSE;    minimize = possessive = FALSE;
684    op = *ecode;    op = *ecode;
685    
   /* For partial matching, remember if we ever hit the end of the subject after  
   matching at least one subject character. This code is now wrapped in a macro  
   because it appears several times below. */  
   
   CHECK_PARTIAL();  
   
686    switch(op)    switch(op)
687      {      {
688        case OP_MARK:
689        markptr = ecode + 2;
690        RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode] + ecode[1], offset_top, md,
691          ims, eptrb, flags, RM55);
692    
693        /* A return of MATCH_SKIP_ARG means that matching failed at SKIP with an
694        argument, and we must check whether that argument matches this MARK's
695        argument. It is passed back in md->start_match_ptr (an overloading of that
696        variable). If it does match, we reset that variable to the current subject
697        position and return MATCH_SKIP. Otherwise, pass back the return code
698        unaltered. */
699    
700        if (rrc == MATCH_SKIP_ARG &&
701            strcmp((char *)markptr, (char *)(md->start_match_ptr)) == 0)
702          {
703          md->start_match_ptr = eptr;
704          RRETURN(MATCH_SKIP);
705          }
706    
707        if (md->mark == NULL) md->mark = markptr;
708        RRETURN(rrc);
709    
710      case OP_FAIL:      case OP_FAIL:
711      RRETURN(MATCH_NOMATCH);      MRRETURN(MATCH_NOMATCH);
712    
713        /* COMMIT overrides PRUNE, SKIP, and THEN */
714    
715        case OP_COMMIT:
716        RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,
717          ims, eptrb, flags, RM52);
718        if (rrc != MATCH_NOMATCH && rrc != MATCH_PRUNE &&
719            rrc != MATCH_SKIP && rrc != MATCH_SKIP_ARG &&
720            rrc != MATCH_THEN)
721          RRETURN(rrc);
722        MRRETURN(MATCH_COMMIT);
723    
724        /* PRUNE overrides THEN */
725    
726      case OP_PRUNE:      case OP_PRUNE:
727      RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,      RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,
728        ims, eptrb, flags, RM51);        ims, eptrb, flags, RM51);
729      if (rrc != MATCH_NOMATCH) RRETURN(rrc);      if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);
730      RRETURN(MATCH_PRUNE);      MRRETURN(MATCH_PRUNE);
731    
732      case OP_COMMIT:      case OP_PRUNE_ARG:
733      RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,      RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode] + ecode[1], offset_top, md,
734        ims, eptrb, flags, RM52);        ims, eptrb, flags, RM56);
735      if (rrc != MATCH_NOMATCH) RRETURN(rrc);      if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);
736      RRETURN(MATCH_COMMIT);      md->mark = ecode + 2;
737        RRETURN(MATCH_PRUNE);
738    
739        /* SKIP overrides PRUNE and THEN */
740    
741      case OP_SKIP:      case OP_SKIP:
742      RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,      RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,
743        ims, eptrb, flags, RM53);        ims, eptrb, flags, RM53);
744      if (rrc != MATCH_NOMATCH) RRETURN(rrc);      if (rrc != MATCH_NOMATCH && rrc != MATCH_PRUNE && rrc != MATCH_THEN)
745          RRETURN(rrc);
746      md->start_match_ptr = eptr;   /* Pass back current position */      md->start_match_ptr = eptr;   /* Pass back current position */
747      RRETURN(MATCH_SKIP);      MRRETURN(MATCH_SKIP);
748    
749        case OP_SKIP_ARG:
750        RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode] + ecode[1], offset_top, md,
751          ims, eptrb, flags, RM57);
752        if (rrc != MATCH_NOMATCH && rrc != MATCH_PRUNE && rrc != MATCH_THEN)
753          RRETURN(rrc);
754    
755        /* Pass back the current skip name by overloading md->start_match_ptr and
756        returning the special MATCH_SKIP_ARG return code. This will either be
757        caught by a matching MARK, or get to the top, where it is treated the same
758        as PRUNE. */
759    
760        md->start_match_ptr = ecode + 2;
761        RRETURN(MATCH_SKIP_ARG);
762    
763        /* For THEN (and THEN_ARG) we pass back the address of the bracket or
764        the alt that is at the start of the current branch. This makes it possible
765        to skip back past alternatives that precede the THEN within the current
766        branch. */
767    
768      case OP_THEN:      case OP_THEN:
769      RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,      RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,
770        ims, eptrb, flags, RM54);        ims, eptrb, flags, RM54);
771      if (rrc != MATCH_NOMATCH) RRETURN(rrc);      if (rrc != MATCH_NOMATCH) RRETURN(rrc);
772        md->start_match_ptr = ecode - GET(ecode, 1);
773        MRRETURN(MATCH_THEN);
774    
775        case OP_THEN_ARG:
776        RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode] + ecode[1+LINK_SIZE],
777          offset_top, md, ims, eptrb, flags, RM58);
778        if (rrc != MATCH_NOMATCH) RRETURN(rrc);
779        md->start_match_ptr = ecode - GET(ecode, 1);
780        md->mark = ecode + LINK_SIZE + 2;
781      RRETURN(MATCH_THEN);      RRETURN(MATCH_THEN);
782    
783      /* 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 710  for (;;) Line 799  for (;;)
799      number = GET2(ecode, 1+LINK_SIZE);      number = GET2(ecode, 1+LINK_SIZE);
800      offset = number << 1;      offset = number << 1;
801    
802  #ifdef DEBUG  #ifdef PCRE_DEBUG
803      printf("start bracket %d\n", number);      printf("start bracket %d\n", number);
804      printf("subject=");      printf("subject=");
805      pchars(eptr, 16, TRUE, md);      pchars(eptr, 16, TRUE, md);
# Line 725  for (;;) Line 814  for (;;)
814        save_capture_last = md->capture_last;        save_capture_last = md->capture_last;
815    
816        DPRINTF(("saving %d %d %d\n", save_offset1, save_offset2, save_offset3));        DPRINTF(("saving %d %d %d\n", save_offset1, save_offset2, save_offset3));
817        md->offset_vector[md->offset_end - number] = eptr - md->start_subject;        md->offset_vector[md->offset_end - number] =
818            (int)(eptr - md->start_subject);
819    
820        flags = (op == OP_SCBRA)? match_cbegroup : 0;        flags = (op == OP_SCBRA)? match_cbegroup : 0;
821        do        do
822          {          {
823          RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,          RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,
824            ims, eptrb, flags, RM1);            ims, eptrb, flags, RM1);
825          if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);          if (rrc != MATCH_NOMATCH &&
826                (rrc != MATCH_THEN || md->start_match_ptr != ecode))
827              RRETURN(rrc);
828          md->capture_last = save_capture_last;          md->capture_last = save_capture_last;
829          ecode += GET(ecode, 1);          ecode += GET(ecode, 1);
830          }          }
# Line 744  for (;;) Line 836  for (;;)
836        md->offset_vector[offset+1] = save_offset2;        md->offset_vector[offset+1] = save_offset2;
837        md->offset_vector[md->offset_end - number] = save_offset3;        md->offset_vector[md->offset_end - number] = save_offset3;
838    
839          if (rrc != MATCH_THEN) md->mark = markptr;
840        RRETURN(MATCH_NOMATCH);        RRETURN(MATCH_NOMATCH);
841        }        }
842    
# Line 783  for (;;) Line 876  for (;;)
876    
877          RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md, ims,          RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md, ims,
878            eptrb, flags, RM48);            eptrb, flags, RM48);
879            if (rrc == MATCH_NOMATCH) md->mark = markptr;
880          RRETURN(rrc);          RRETURN(rrc);
881          }          }
882    
# Line 791  for (;;) Line 885  for (;;)
885    
886        RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md, ims,        RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md, ims,
887          eptrb, flags, RM2);          eptrb, flags, RM2);
888        if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);        if (rrc != MATCH_NOMATCH &&
889              (rrc != MATCH_THEN || md->start_match_ptr != ecode))
890            RRETURN(rrc);
891        ecode += GET(ecode, 1);        ecode += GET(ecode, 1);
892        }        }
893      /* Control never reaches here. */      /* Control never reaches here. */
# Line 818  for (;;) Line 914  for (;;)
914          cb.callout_number   = ecode[LINK_SIZE+2];          cb.callout_number   = ecode[LINK_SIZE+2];
915          cb.offset_vector    = md->offset_vector;          cb.offset_vector    = md->offset_vector;
916          cb.subject          = (PCRE_SPTR)md->start_subject;          cb.subject          = (PCRE_SPTR)md->start_subject;
917          cb.subject_length   = md->end_subject - md->start_subject;          cb.subject_length   = (int)(md->end_subject - md->start_subject);
918          cb.start_match      = mstart - md->start_subject;          cb.start_match      = (int)(mstart - md->start_subject);
919          cb.current_position = eptr - md->start_subject;          cb.current_position = (int)(eptr - md->start_subject);
920          cb.pattern_position = GET(ecode, LINK_SIZE + 3);          cb.pattern_position = GET(ecode, LINK_SIZE + 3);
921          cb.next_item_length = GET(ecode, 3 + 2*LINK_SIZE);          cb.next_item_length = GET(ecode, 3 + 2*LINK_SIZE);
922          cb.capture_top      = offset_top/2;          cb.capture_top      = offset_top/2;
923          cb.capture_last     = md->capture_last;          cb.capture_last     = md->capture_last;
924          cb.callout_data     = md->callout_data;          cb.callout_data     = md->callout_data;
925          if ((rrc = (*pcre_callout)(&cb)) > 0) RRETURN(MATCH_NOMATCH);          if ((rrc = (*pcre_callout)(&cb)) > 0) MRRETURN(MATCH_NOMATCH);
926          if (rrc < 0) RRETURN(rrc);          if (rrc < 0) RRETURN(rrc);
927          }          }
928        ecode += _pcre_OP_lengths[OP_CALLOUT];        ecode += _pcre_OP_lengths[OP_CALLOUT];
# Line 836  for (;;) Line 932  for (;;)
932    
933      /* Now see what the actual condition is */      /* Now see what the actual condition is */
934    
935      if (condcode == OP_RREF)         /* Recursion test */      if (condcode == OP_RREF || condcode == OP_NRREF)    /* Recursion test */
936        {        {
937        offset = GET2(ecode, LINK_SIZE + 2);     /* Recursion group number*/        if (md->recursive == NULL)                /* Not recursing => FALSE */
938        condition = md->recursive != NULL &&          {
939          (offset == RREF_ANY || offset == md->recursive->group_num);          condition = FALSE;
940        ecode += condition? 3 : GET(ecode, 1);          ecode += GET(ecode, 1);
941            }
942          else
943            {
944            int recno = GET2(ecode, LINK_SIZE + 2);   /* Recursion group number*/
945            condition =  (recno == RREF_ANY || recno == md->recursive->group_num);
946    
947            /* If the test is for recursion into a specific subpattern, and it is
948            false, but the test was set up by name, scan the table to see if the
949            name refers to any other numbers, and test them. The condition is true
950            if any one is set. */
951    
952            if (!condition && condcode == OP_NRREF && recno != RREF_ANY)
953              {
954              uschar *slotA = md->name_table;
955              for (i = 0; i < md->name_count; i++)
956                {
957                if (GET2(slotA, 0) == recno) break;
958                slotA += md->name_entry_size;
959                }
960    
961              /* Found a name for the number - there can be only one; duplicate
962              names for different numbers are allowed, but not vice versa. First
963              scan down for duplicates. */
964    
965              if (i < md->name_count)
966                {
967                uschar *slotB = slotA;
968                while (slotB > md->name_table)
969                  {
970                  slotB -= md->name_entry_size;
971                  if (strcmp((char *)slotA + 2, (char *)slotB + 2) == 0)
972                    {
973                    condition = GET2(slotB, 0) == md->recursive->group_num;
974                    if (condition) break;
975                    }
976                  else break;
977                  }
978    
979                /* Scan up for duplicates */
980    
981                if (!condition)
982                  {
983                  slotB = slotA;
984                  for (i++; i < md->name_count; i++)
985                    {
986                    slotB += md->name_entry_size;
987                    if (strcmp((char *)slotA + 2, (char *)slotB + 2) == 0)
988                      {
989                      condition = GET2(slotB, 0) == md->recursive->group_num;
990                      if (condition) break;
991                      }
992                    else break;
993                    }
994                  }
995                }
996              }
997    
998            /* Chose branch according to the condition */
999    
1000            ecode += condition? 3 : GET(ecode, 1);
1001            }
1002        }        }
1003    
1004      else if (condcode == OP_CREF)    /* Group used test */      else if (condcode == OP_CREF || condcode == OP_NCREF)  /* Group used test */
1005        {        {
1006        offset = GET2(ecode, LINK_SIZE+2) << 1;  /* Doubled ref number */        offset = GET2(ecode, LINK_SIZE+2) << 1;  /* Doubled ref number */
1007        condition = offset < offset_top && md->offset_vector[offset] >= 0;        condition = offset < offset_top && md->offset_vector[offset] >= 0;
1008    
1009          /* If the numbered capture is unset, but the reference was by name,
1010          scan the table to see if the name refers to any other numbers, and test
1011          them. The condition is true if any one is set. This is tediously similar
1012          to the code above, but not close enough to try to amalgamate. */
1013    
1014          if (!condition && condcode == OP_NCREF)
1015            {
1016            int refno = offset >> 1;
1017            uschar *slotA = md->name_table;
1018    
1019            for (i = 0; i < md->name_count; i++)
1020              {
1021              if (GET2(slotA, 0) == refno) break;
1022              slotA += md->name_entry_size;
1023              }
1024    
1025            /* Found a name for the number - there can be only one; duplicate names
1026            for different numbers are allowed, but not vice versa. First scan down
1027            for duplicates. */
1028    
1029            if (i < md->name_count)
1030              {
1031              uschar *slotB = slotA;
1032              while (slotB > md->name_table)
1033                {
1034                slotB -= md->name_entry_size;
1035                if (strcmp((char *)slotA + 2, (char *)slotB + 2) == 0)
1036                  {
1037                  offset = GET2(slotB, 0) << 1;
1038                  condition = offset < offset_top &&
1039                    md->offset_vector[offset] >= 0;
1040                  if (condition) break;
1041                  }
1042                else break;
1043                }
1044    
1045              /* Scan up for duplicates */
1046    
1047              if (!condition)
1048                {
1049                slotB = slotA;
1050                for (i++; i < md->name_count; i++)
1051                  {
1052                  slotB += md->name_entry_size;
1053                  if (strcmp((char *)slotA + 2, (char *)slotB + 2) == 0)
1054                    {
1055                    offset = GET2(slotB, 0) << 1;
1056                    condition = offset < offset_top &&
1057                      md->offset_vector[offset] >= 0;
1058                    if (condition) break;
1059                    }
1060                  else break;
1061                  }
1062                }
1063              }
1064            }
1065    
1066          /* Chose branch according to the condition */
1067    
1068        ecode += condition? 3 : GET(ecode, 1);        ecode += condition? 3 : GET(ecode, 1);
1069        }        }
1070    
# Line 871  for (;;) Line 1088  for (;;)
1088          ecode += 1 + LINK_SIZE + GET(ecode, LINK_SIZE + 2);          ecode += 1 + LINK_SIZE + GET(ecode, LINK_SIZE + 2);
1089          while (*ecode == OP_ALT) ecode += GET(ecode, 1);          while (*ecode == OP_ALT) ecode += GET(ecode, 1);
1090          }          }
1091        else if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN)        else if (rrc != MATCH_NOMATCH &&
1092                  (rrc != MATCH_THEN || md->start_match_ptr != ecode))
1093          {          {
1094          RRETURN(rrc);         /* Need braces because of following else */          RRETURN(rrc);         /* Need braces because of following else */
1095          }          }
# Line 908  for (;;) Line 1126  for (;;)
1126      break;      break;
1127    
1128    
1129        /* Before OP_ACCEPT there may be any number of OP_CLOSE opcodes,
1130        to close any currently open capturing brackets. */
1131    
1132        case OP_CLOSE:
1133        number = GET2(ecode, 1);
1134        offset = number << 1;
1135    
1136    #ifdef PCRE_DEBUG
1137          printf("end bracket %d at *ACCEPT", number);
1138          printf("\n");
1139    #endif
1140    
1141        md->capture_last = number;
1142        if (offset >= md->offset_max) md->offset_overflow = TRUE; else
1143          {
1144          md->offset_vector[offset] =
1145            md->offset_vector[md->offset_end - number];
1146          md->offset_vector[offset+1] = (int)(eptr - md->start_subject);
1147          if (offset_top <= offset) offset_top = offset + 2;
1148          }
1149        ecode += 3;
1150        break;
1151    
1152    
1153      /* 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
1154      recursion, we should restore the offsets appropriately and continue from      recursion, we should restore the offsets appropriately and continue from
1155      after the call. */      after the call. */
# Line 921  for (;;) Line 1163  for (;;)
1163        md->recursive = rec->prevrec;        md->recursive = rec->prevrec;
1164        memmove(md->offset_vector, rec->offset_save,        memmove(md->offset_vector, rec->offset_save,
1165          rec->saved_max * sizeof(int));          rec->saved_max * sizeof(int));
1166        mstart = rec->save_start;        offset_top = rec->save_offset_top;
1167        ims = original_ims;        ims = original_ims;
1168        ecode = rec->after_call;        ecode = rec->after_call;
1169        break;        break;
1170        }        }
1171    
1172      /* 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
1173      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
1174        the subject. In both cases, backtracking will then try other alternatives,
1175        if any. */
1176    
1177        if (eptr == mstart &&
1178            (md->notempty ||
1179              (md->notempty_atstart &&
1180                mstart == md->start_subject + md->start_offset)))
1181          MRRETURN(MATCH_NOMATCH);
1182    
1183        /* Otherwise, we have a match. */
1184    
     if (md->notempty && eptr == mstart) RRETURN(MATCH_NOMATCH);  
1185      md->end_match_ptr = eptr;           /* Record where we ended */      md->end_match_ptr = eptr;           /* Record where we ended */
1186      md->end_offset_top = offset_top;    /* and how many extracts were taken */      md->end_offset_top = offset_top;    /* and how many extracts were taken */
1187      md->start_match_ptr = mstart;       /* and the start (\K can modify) */      md->start_match_ptr = mstart;       /* and the start (\K can modify) */
1188      RRETURN(MATCH_MATCH);  
1189        /* For some reason, the macros don't work properly if an expression is
1190        given as the argument to MRRETURN when the heap is in use. */
1191    
1192        rrc = (op == OP_END)? MATCH_MATCH : MATCH_ACCEPT;
1193        MRRETURN(rrc);
1194    
1195      /* Change option settings */      /* Change option settings */
1196    
# Line 956  for (;;) Line 1212  for (;;)
1212        {        {
1213        RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, NULL, 0,        RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, NULL, 0,
1214          RM4);          RM4);
1215        if (rrc == MATCH_MATCH) break;        if (rrc == MATCH_MATCH || rrc == MATCH_ACCEPT)
1216        if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);          {
1217            mstart = md->start_match_ptr;   /* In case \K reset it */
1218            break;
1219            }
1220          if (rrc != MATCH_NOMATCH &&
1221              (rrc != MATCH_THEN || md->start_match_ptr != ecode))
1222            RRETURN(rrc);
1223        ecode += GET(ecode, 1);        ecode += GET(ecode, 1);
1224        }        }
1225      while (*ecode == OP_ALT);      while (*ecode == OP_ALT);
1226      if (*ecode == OP_KET) RRETURN(MATCH_NOMATCH);      if (*ecode == OP_KET) MRRETURN(MATCH_NOMATCH);
1227    
1228      /* If checking an assertion for a condition, return MATCH_MATCH. */      /* If checking an assertion for a condition, return MATCH_MATCH. */
1229    
# Line 975  for (;;) Line 1237  for (;;)
1237      offset_top = md->end_offset_top;      offset_top = md->end_offset_top;
1238      continue;      continue;
1239    
1240      /* Negative assertion: all branches must fail to match */      /* Negative assertion: all branches must fail to match. Encountering SKIP,
1241        PRUNE, or COMMIT means we must assume failure without checking subsequent
1242        branches. */
1243    
1244      case OP_ASSERT_NOT:      case OP_ASSERT_NOT:
1245      case OP_ASSERTBACK_NOT:      case OP_ASSERTBACK_NOT:
# Line 983  for (;;) Line 1247  for (;;)
1247        {        {
1248        RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, NULL, 0,        RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, NULL, 0,
1249          RM5);          RM5);
1250        if (rrc == MATCH_MATCH) RRETURN(MATCH_NOMATCH);        if (rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) MRRETURN(MATCH_NOMATCH);
1251        if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);        if (rrc == MATCH_SKIP || rrc == MATCH_PRUNE || rrc == MATCH_COMMIT)
1252            {
1253            do ecode += GET(ecode,1); while (*ecode == OP_ALT);
1254            break;
1255            }
1256          if (rrc != MATCH_NOMATCH &&
1257              (rrc != MATCH_THEN || md->start_match_ptr != ecode))
1258            RRETURN(rrc);
1259        ecode += GET(ecode,1);        ecode += GET(ecode,1);
1260        }        }
1261      while (*ecode == OP_ALT);      while (*ecode == OP_ALT);
# Line 1007  for (;;) Line 1278  for (;;)
1278        while (i-- > 0)        while (i-- > 0)
1279          {          {
1280          eptr--;          eptr--;
1281          if (eptr < md->start_subject) RRETURN(MATCH_NOMATCH);          if (eptr < md->start_subject) MRRETURN(MATCH_NOMATCH);
1282          BACKCHAR(eptr);          BACKCHAR(eptr);
1283          }          }
1284        }        }
# Line 1018  for (;;) Line 1289  for (;;)
1289    
1290        {        {
1291        eptr -= GET(ecode, 1);        eptr -= GET(ecode, 1);
1292        if (eptr < md->start_subject) RRETURN(MATCH_NOMATCH);        if (eptr < md->start_subject) MRRETURN(MATCH_NOMATCH);
1293        }        }
1294    
1295      /* Skip to next op code */      /* Save the earliest consulted character, then skip to next op code */
1296    
1297        if (eptr < md->start_used_ptr) md->start_used_ptr = eptr;
1298      ecode += 1 + LINK_SIZE;      ecode += 1 + LINK_SIZE;
1299      break;      break;
1300    
# Line 1038  for (;;) Line 1310  for (;;)
1310        cb.callout_number   = ecode[1];        cb.callout_number   = ecode[1];
1311        cb.offset_vector    = md->offset_vector;        cb.offset_vector    = md->offset_vector;
1312        cb.subject          = (PCRE_SPTR)md->start_subject;        cb.subject          = (PCRE_SPTR)md->start_subject;
1313        cb.subject_length   = md->end_subject - md->start_subject;        cb.subject_length   = (int)(md->end_subject - md->start_subject);
1314        cb.start_match      = mstart - md->start_subject;        cb.start_match      = (int)(mstart - md->start_subject);
1315        cb.current_position = eptr - md->start_subject;        cb.current_position = (int)(eptr - md->start_subject);
1316        cb.pattern_position = GET(ecode, 2);        cb.pattern_position = GET(ecode, 2);
1317        cb.next_item_length = GET(ecode, 2 + LINK_SIZE);        cb.next_item_length = GET(ecode, 2 + LINK_SIZE);
1318        cb.capture_top      = offset_top/2;        cb.capture_top      = offset_top/2;
1319        cb.capture_last     = md->capture_last;        cb.capture_last     = md->capture_last;
1320        cb.callout_data     = md->callout_data;        cb.callout_data     = md->callout_data;
1321        if ((rrc = (*pcre_callout)(&cb)) > 0) RRETURN(MATCH_NOMATCH);        if ((rrc = (*pcre_callout)(&cb)) > 0) MRRETURN(MATCH_NOMATCH);
1322        if (rrc < 0) RRETURN(rrc);        if (rrc < 0) RRETURN(rrc);
1323        }        }
1324      ecode += 2 + 2*LINK_SIZE;      ecode += 2 + 2*LINK_SIZE;
# Line 1101  for (;;) Line 1373  for (;;)
1373    
1374        memcpy(new_recursive.offset_save, md->offset_vector,        memcpy(new_recursive.offset_save, md->offset_vector,
1375              new_recursive.saved_max * sizeof(int));              new_recursive.saved_max * sizeof(int));
1376        new_recursive.save_start = mstart;        new_recursive.save_offset_top = offset_top;
       mstart = eptr;  
1377    
1378        /* 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
1379        restore the offset and recursion data. */        restore the offset and recursion data. */
# Line 1113  for (;;) Line 1384  for (;;)
1384          {          {
1385          RMATCH(eptr, callpat + _pcre_OP_lengths[*callpat], offset_top,          RMATCH(eptr, callpat + _pcre_OP_lengths[*callpat], offset_top,
1386            md, ims, eptrb, flags, RM6);            md, ims, eptrb, flags, RM6);
1387          if (rrc == MATCH_MATCH)          if (rrc == MATCH_MATCH || rrc == MATCH_ACCEPT)
1388            {            {
1389            DPRINTF(("Recursion matched\n"));            DPRINTF(("Recursion matched\n"));
1390            md->recursive = new_recursive.prevrec;            md->recursive = new_recursive.prevrec;
1391            if (new_recursive.offset_save != stacksave)            if (new_recursive.offset_save != stacksave)
1392              (pcre_free)(new_recursive.offset_save);              (pcre_free)(new_recursive.offset_save);
1393            RRETURN(MATCH_MATCH);            MRRETURN(MATCH_MATCH);
1394            }            }
1395          else if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN)          else if (rrc != MATCH_NOMATCH &&
1396                    (rrc != MATCH_THEN || md->start_match_ptr != ecode))
1397            {            {
1398            DPRINTF(("Recursion gave error %d\n", rrc));            DPRINTF(("Recursion gave error %d\n", rrc));
1399            if (new_recursive.offset_save != stacksave)            if (new_recursive.offset_save != stacksave)
# Line 1140  for (;;) Line 1412  for (;;)
1412        md->recursive = new_recursive.prevrec;        md->recursive = new_recursive.prevrec;
1413        if (new_recursive.offset_save != stacksave)        if (new_recursive.offset_save != stacksave)
1414          (pcre_free)(new_recursive.offset_save);          (pcre_free)(new_recursive.offset_save);
1415        RRETURN(MATCH_NOMATCH);        MRRETURN(MATCH_NOMATCH);
1416        }        }
1417      /* Control never reaches here */      /* Control never reaches here */
1418    
# Line 1149  for (;;) Line 1421  for (;;)
1421      a move back into the brackets. Friedl calls these "atomic" subpatterns.      a move back into the brackets. Friedl calls these "atomic" subpatterns.
1422      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
1423      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
1424      the end of a normal bracket, leaving the subject pointer. */      the end of a normal bracket, leaving the subject pointer, but resetting
1425        the start-of-match value in case it was changed by \K. */
1426    
1427      case OP_ONCE:      case OP_ONCE:
1428      prev = ecode;      prev = ecode;
# Line 1158  for (;;) Line 1431  for (;;)
1431      do      do
1432        {        {
1433        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);
1434        if (rrc == MATCH_MATCH) break;        if (rrc == MATCH_MATCH)  /* Note: _not_ MATCH_ACCEPT */
1435        if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);          {
1436            mstart = md->start_match_ptr;
1437            break;
1438            }
1439          if (rrc != MATCH_NOMATCH &&
1440              (rrc != MATCH_THEN || md->start_match_ptr != ecode))
1441            RRETURN(rrc);
1442        ecode += GET(ecode,1);        ecode += GET(ecode,1);
1443        }        }
1444      while (*ecode == OP_ALT);      while (*ecode == OP_ALT);
# Line 1277  for (;;) Line 1556  for (;;)
1556        }        }
1557      else saved_eptr = NULL;      else saved_eptr = NULL;
1558    
1559      /* 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
1560      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
1561      assertions. Do this also for the "once" (atomic) groups. */      use by positive assertions. We also need to record the match start in case
1562        it was changed by \K. */
1563    
1564      if (*prev == OP_ASSERT || *prev == OP_ASSERT_NOT ||      if (*prev == OP_ASSERT || *prev == OP_ASSERT_NOT ||
1565          *prev == OP_ASSERTBACK || *prev == OP_ASSERTBACK_NOT ||          *prev == OP_ASSERTBACK || *prev == OP_ASSERTBACK_NOT ||
# Line 1287  for (;;) Line 1567  for (;;)
1567        {        {
1568        md->end_match_ptr = eptr;      /* For ONCE */        md->end_match_ptr = eptr;      /* For ONCE */
1569        md->end_offset_top = offset_top;        md->end_offset_top = offset_top;
1570        RRETURN(MATCH_MATCH);        md->start_match_ptr = mstart;
1571          MRRETURN(MATCH_MATCH);
1572        }        }
1573    
1574      /* 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 1301  for (;;) Line 1582  for (;;)
1582        number = GET2(prev, 1+LINK_SIZE);        number = GET2(prev, 1+LINK_SIZE);
1583        offset = number << 1;        offset = number << 1;
1584    
1585  #ifdef DEBUG  #ifdef PCRE_DEBUG
1586        printf("end bracket %d", number);        printf("end bracket %d", number);
1587        printf("\n");        printf("\n");
1588  #endif  #endif
# Line 1311  for (;;) Line 1592  for (;;)
1592          {          {
1593          md->offset_vector[offset] =          md->offset_vector[offset] =
1594            md->offset_vector[md->offset_end - number];            md->offset_vector[md->offset_end - number];
1595          md->offset_vector[offset+1] = eptr - md->start_subject;          md->offset_vector[offset+1] = (int)(eptr - md->start_subject);
1596          if (offset_top <= offset) offset_top = offset + 2;          if (offset_top <= offset) offset_top = offset + 2;
1597          }          }
1598    
# Line 1323  for (;;) Line 1604  for (;;)
1604          recursion_info *rec = md->recursive;          recursion_info *rec = md->recursive;
1605          DPRINTF(("Recursion (%d) succeeded - continuing\n", number));          DPRINTF(("Recursion (%d) succeeded - continuing\n", number));
1606          md->recursive = rec->prevrec;          md->recursive = rec->prevrec;
         mstart = rec->save_start;  
1607          memcpy(md->offset_vector, rec->offset_save,          memcpy(md->offset_vector, rec->offset_save,
1608            rec->saved_max * sizeof(int));            rec->saved_max * sizeof(int));
1609            offset_top = rec->save_offset_top;
1610          ecode = rec->after_call;          ecode = rec->after_call;
1611          ims = original_ims;          ims = original_ims;
1612          break;          break;
# Line 1382  for (;;) Line 1663  for (;;)
1663      /* Start of subject unless notbol, or after internal newline if multiline */      /* Start of subject unless notbol, or after internal newline if multiline */
1664    
1665      case OP_CIRC:      case OP_CIRC:
1666      if (md->notbol && eptr == md->start_subject) RRETURN(MATCH_NOMATCH);      if (md->notbol && eptr == md->start_subject) MRRETURN(MATCH_NOMATCH);
1667      if ((ims & PCRE_MULTILINE) != 0)      if ((ims & PCRE_MULTILINE) != 0)
1668        {        {
1669        if (eptr != md->start_subject &&        if (eptr != md->start_subject &&
1670            (eptr == md->end_subject || !WAS_NEWLINE(eptr)))            (eptr == md->end_subject || !WAS_NEWLINE(eptr)))
1671          RRETURN(MATCH_NOMATCH);          MRRETURN(MATCH_NOMATCH);
1672        ecode++;        ecode++;
1673        break;        break;
1674        }        }
# Line 1396  for (;;) Line 1677  for (;;)
1677      /* Start of subject assertion */      /* Start of subject assertion */
1678    
1679      case OP_SOD:      case OP_SOD:
1680      if (eptr != md->start_subject) RRETURN(MATCH_NOMATCH);      if (eptr != md->start_subject) MRRETURN(MATCH_NOMATCH);
1681      ecode++;      ecode++;
1682      break;      break;
1683    
1684      /* Start of match assertion */      /* Start of match assertion */
1685    
1686      case OP_SOM:      case OP_SOM:
1687      if (eptr != md->start_subject + md->start_offset) RRETURN(MATCH_NOMATCH);      if (eptr != md->start_subject + md->start_offset) MRRETURN(MATCH_NOMATCH);
1688      ecode++;      ecode++;
1689      break;      break;
1690    
# Line 1421  for (;;) Line 1702  for (;;)
1702      if ((ims & PCRE_MULTILINE) != 0)      if ((ims & PCRE_MULTILINE) != 0)
1703        {        {
1704        if (eptr < md->end_subject)        if (eptr < md->end_subject)
1705          { if (!IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH); }          { if (!IS_NEWLINE(eptr)) MRRETURN(MATCH_NOMATCH); }
1706        else        else
1707          { if (md->noteol) RRETURN(MATCH_NOMATCH); }          { if (md->noteol) MRRETURN(MATCH_NOMATCH); }
1708        ecode++;        ecode++;
1709        break;        break;
1710        }        }
1711      else      else
1712        {        {
1713        if (md->noteol) RRETURN(MATCH_NOMATCH);        if (md->noteol) MRRETURN(MATCH_NOMATCH);
1714        if (!md->endonly)        if (!md->endonly)
1715          {          {
1716          if (eptr != md->end_subject &&          if (eptr != md->end_subject &&
1717              (!IS_NEWLINE(eptr) || eptr != md->end_subject - md->nllen))              (!IS_NEWLINE(eptr) || eptr != md->end_subject - md->nllen))
1718            RRETURN(MATCH_NOMATCH);            MRRETURN(MATCH_NOMATCH);
1719          ecode++;          ecode++;
1720          break;          break;
1721          }          }
# Line 1444  for (;;) Line 1725  for (;;)
1725      /* End of subject assertion (\z) */      /* End of subject assertion (\z) */
1726    
1727      case OP_EOD:      case OP_EOD:
1728      if (eptr < md->end_subject) RRETURN(MATCH_NOMATCH);      if (eptr < md->end_subject) MRRETURN(MATCH_NOMATCH);
1729      ecode++;      ecode++;
1730      break;      break;
1731    
# Line 1453  for (;;) Line 1734  for (;;)
1734      case OP_EODN:      case OP_EODN:
1735      if (eptr != md->end_subject &&      if (eptr != md->end_subject &&
1736          (!IS_NEWLINE(eptr) || eptr != md->end_subject - md->nllen))          (!IS_NEWLINE(eptr) || eptr != md->end_subject - md->nllen))
1737        RRETURN(MATCH_NOMATCH);        MRRETURN(MATCH_NOMATCH);
1738      ecode++;      ecode++;
1739      break;      break;
1740    
# Line 1465  for (;;) Line 1746  for (;;)
1746    
1747        /* Find out if the previous and current characters are "word" characters.        /* Find out if the previous and current characters are "word" characters.
1748        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
1749        be "non-word" characters. */        be "non-word" characters. Remember the earliest consulted character for
1750          partial matching. */
1751    
1752  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
1753        if (utf8)        if (utf8)
1754          {          {
1755            /* Get status of previous character */
1756    
1757          if (eptr == md->start_subject) prev_is_word = FALSE; else          if (eptr == md->start_subject) prev_is_word = FALSE; else
1758            {            {
1759            USPTR lastptr = eptr - 1;            USPTR lastptr = eptr - 1;
1760            while((*lastptr & 0xc0) == 0x80) lastptr--;            while((*lastptr & 0xc0) == 0x80) lastptr--;
1761              if (lastptr < md->start_used_ptr) md->start_used_ptr = lastptr;
1762            GETCHAR(c, lastptr);            GETCHAR(c, lastptr);
1763    #ifdef SUPPORT_UCP
1764              if (md->use_ucp)
1765                {
1766                if (c == '_') prev_is_word = TRUE; else
1767                  {
1768                  int cat = UCD_CATEGORY(c);
1769                  prev_is_word = (cat == ucp_L || cat == ucp_N);
1770                  }
1771                }
1772              else
1773    #endif
1774            prev_is_word = c < 256 && (md->ctypes[c] & ctype_word) != 0;            prev_is_word = c < 256 && (md->ctypes[c] & ctype_word) != 0;
1775            }            }
1776          if (eptr >= md->end_subject) cur_is_word = FALSE; else  
1777            /* Get status of next character */
1778    
1779            if (eptr >= md->end_subject)
1780              {
1781              SCHECK_PARTIAL();
1782              cur_is_word = FALSE;
1783              }
1784            else
1785            {            {
1786            GETCHAR(c, eptr);            GETCHAR(c, eptr);
1787    #ifdef SUPPORT_UCP
1788              if (md->use_ucp)
1789                {
1790                if (c == '_') cur_is_word = TRUE; else
1791                  {
1792                  int cat = UCD_CATEGORY(c);
1793                  cur_is_word = (cat == ucp_L || cat == ucp_N);
1794                  }
1795                }
1796              else
1797    #endif
1798            cur_is_word = c < 256 && (md->ctypes[c] & ctype_word) != 0;            cur_is_word = c < 256 && (md->ctypes[c] & ctype_word) != 0;
1799            }            }
1800          }          }
1801        else        else
1802  #endif  #endif
1803    
1804        /* More streamlined when not in UTF-8 mode */        /* Not in UTF-8 mode, but we may still have PCRE_UCP set, and for
1805          consistency with the behaviour of \w we do use it in this case. */
1806    
1807          {          {
1808          prev_is_word = (eptr != md->start_subject) &&          /* Get status of previous character */
1809            ((md->ctypes[eptr[-1]] & ctype_word) != 0);  
1810          cur_is_word = (eptr < md->end_subject) &&          if (eptr == md->start_subject) prev_is_word = FALSE; else
1811            ((md->ctypes[*eptr] & ctype_word) != 0);            {
1812              if (eptr <= md->start_used_ptr) md->start_used_ptr = eptr - 1;
1813    #ifdef SUPPORT_UCP
1814              if (md->use_ucp)
1815                {
1816                c = eptr[-1];
1817                if (c == '_') prev_is_word = TRUE; else
1818                  {
1819                  int cat = UCD_CATEGORY(c);
1820                  prev_is_word = (cat == ucp_L || cat == ucp_N);
1821                  }
1822                }
1823              else
1824    #endif
1825              prev_is_word = ((md->ctypes[eptr[-1]] & ctype_word) != 0);
1826              }
1827    
1828            /* Get status of next character */
1829    
1830            if (eptr >= md->end_subject)
1831              {
1832              SCHECK_PARTIAL();
1833              cur_is_word = FALSE;
1834              }
1835            else
1836    #ifdef SUPPORT_UCP
1837            if (md->use_ucp)
1838              {
1839              c = *eptr;
1840              if (c == '_') cur_is_word = TRUE; else
1841                {
1842                int cat = UCD_CATEGORY(c);
1843                cur_is_word = (cat == ucp_L || cat == ucp_N);
1844                }
1845              }
1846            else
1847    #endif
1848            cur_is_word = ((md->ctypes[*eptr] & ctype_word) != 0);
1849          }          }
1850    
1851        /* Now see if the situation is what we want */        /* Now see if the situation is what we want */
1852    
1853        if ((*ecode++ == OP_WORD_BOUNDARY)?        if ((*ecode++ == OP_WORD_BOUNDARY)?
1854             cur_is_word == prev_is_word : cur_is_word != prev_is_word)             cur_is_word == prev_is_word : cur_is_word != prev_is_word)
1855          RRETURN(MATCH_NOMATCH);          MRRETURN(MATCH_NOMATCH);
1856        }        }
1857      break;      break;
1858    
1859      /* Match a single character type; inline for speed */      /* Match a single character type; inline for speed */
1860    
1861      case OP_ANY:      case OP_ANY:
1862      if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH);      if (IS_NEWLINE(eptr)) MRRETURN(MATCH_NOMATCH);
1863      /* Fall through */      /* Fall through */
1864    
1865      case OP_ALLANY:      case OP_ALLANY:
1866      if (eptr++ >= md->end_subject) RRETURN(MATCH_NOMATCH);      if (eptr++ >= md->end_subject)
1867          {
1868          SCHECK_PARTIAL();
1869          MRRETURN(MATCH_NOMATCH);
1870          }
1871      if (utf8) while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;      if (utf8) while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;
1872      ecode++;      ecode++;
1873      break;      break;
# Line 1519  for (;;) Line 1876  for (;;)
1876      any byte, even newline, independent of the setting of PCRE_DOTALL. */      any byte, even newline, independent of the setting of PCRE_DOTALL. */
1877    
1878      case OP_ANYBYTE:      case OP_ANYBYTE:
1879      if (eptr++ >= md->end_subject) RRETURN(MATCH_NOMATCH);      if (eptr++ >= md->end_subject)
1880          {
1881          SCHECK_PARTIAL();
1882          MRRETURN(MATCH_NOMATCH);
1883          }
1884      ecode++;      ecode++;
1885      break;      break;
1886    
1887      case OP_NOT_DIGIT:      case OP_NOT_DIGIT:
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 1532  for (;;) Line 1897  for (;;)
1897  #endif  #endif
1898         (md->ctypes[c] & ctype_digit) != 0         (md->ctypes[c] & ctype_digit) != 0
1899         )         )
1900        RRETURN(MATCH_NOMATCH);        MRRETURN(MATCH_NOMATCH);
1901      ecode++;      ecode++;
1902      break;      break;
1903    
1904      case OP_DIGIT:      case OP_DIGIT:
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 1545  for (;;) Line 1914  for (;;)
1914  #endif  #endif
1915         (md->ctypes[c] & ctype_digit) == 0         (md->ctypes[c] & ctype_digit) == 0
1916         )         )
1917        RRETURN(MATCH_NOMATCH);        MRRETURN(MATCH_NOMATCH);
1918      ecode++;      ecode++;
1919      break;      break;
1920    
1921      case OP_NOT_WHITESPACE:      case OP_NOT_WHITESPACE:
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 1558  for (;;) Line 1931  for (;;)
1931  #endif  #endif
1932         (md->ctypes[c] & ctype_space) != 0         (md->ctypes[c] & ctype_space) != 0
1933         )         )
1934        RRETURN(MATCH_NOMATCH);        MRRETURN(MATCH_NOMATCH);
1935      ecode++;      ecode++;
1936      break;      break;
1937    
1938      case OP_WHITESPACE:      case OP_WHITESPACE:
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 1571  for (;;) Line 1948  for (;;)
1948  #endif  #endif
1949         (md->ctypes[c] & ctype_space) == 0         (md->ctypes[c] & ctype_space) == 0
1950         )         )
1951        RRETURN(MATCH_NOMATCH);        MRRETURN(MATCH_NOMATCH);
1952      ecode++;      ecode++;
1953      break;      break;
1954    
1955      case OP_NOT_WORDCHAR:      case OP_NOT_WORDCHAR:
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      if (      if (
1963  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
# Line 1584  for (;;) Line 1965  for (;;)
1965  #endif  #endif
1966         (md->ctypes[c] & ctype_word) != 0         (md->ctypes[c] & ctype_word) != 0
1967         )         )
1968        RRETURN(MATCH_NOMATCH);        MRRETURN(MATCH_NOMATCH);
1969      ecode++;      ecode++;
1970      break;      break;
1971    
1972      case OP_WORDCHAR:      case OP_WORDCHAR:
1973      if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);      if (eptr >= md->end_subject)
1974          {
1975          SCHECK_PARTIAL();
1976          MRRETURN(MATCH_NOMATCH);
1977          }
1978      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
1979      if (      if (
1980  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
# Line 1597  for (;;) Line 1982  for (;;)
1982  #endif  #endif
1983         (md->ctypes[c] & ctype_word) == 0         (md->ctypes[c] & ctype_word) == 0
1984         )         )
1985        RRETURN(MATCH_NOMATCH);        MRRETURN(MATCH_NOMATCH);
1986      ecode++;      ecode++;
1987      break;      break;
1988    
1989      case OP_ANYNL:      case OP_ANYNL:
1990      if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);      if (eptr >= md->end_subject)
1991          {
1992          SCHECK_PARTIAL();
1993          MRRETURN(MATCH_NOMATCH);
1994          }
1995      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
1996      switch(c)      switch(c)
1997        {        {
1998        default: RRETURN(MATCH_NOMATCH);        default: MRRETURN(MATCH_NOMATCH);
1999        case 0x000d:        case 0x000d:
2000        if (eptr < md->end_subject && *eptr == 0x0a) eptr++;        if (eptr < md->end_subject && *eptr == 0x0a) eptr++;
2001        break;        break;
# Line 1619  for (;;) Line 2008  for (;;)
2008        case 0x0085:        case 0x0085:
2009        case 0x2028:        case 0x2028:
2010        case 0x2029:        case 0x2029:
2011        if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH);        if (md->bsr_anycrlf) MRRETURN(MATCH_NOMATCH);
2012        break;        break;
2013        }        }
2014      ecode++;      ecode++;
2015      break;      break;
2016    
2017      case OP_NOT_HSPACE:      case OP_NOT_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        {        {
# Line 1650  for (;;) Line 2043  for (;;)
2043        case 0x202f:    /* NARROW NO-BREAK SPACE */        case 0x202f:    /* NARROW NO-BREAK SPACE */
2044        case 0x205f:    /* MEDIUM MATHEMATICAL SPACE */        case 0x205f:    /* MEDIUM MATHEMATICAL SPACE */
2045        case 0x3000:    /* IDEOGRAPHIC SPACE */        case 0x3000:    /* IDEOGRAPHIC SPACE */
2046        RRETURN(MATCH_NOMATCH);        MRRETURN(MATCH_NOMATCH);
2047        }        }
2048      ecode++;      ecode++;
2049      break;      break;
2050    
2051      case OP_HSPACE:      case OP_HSPACE:
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        {        {
2060        default: RRETURN(MATCH_NOMATCH);        default: MRRETURN(MATCH_NOMATCH);
2061        case 0x09:      /* HT */        case 0x09:      /* HT */
2062        case 0x20:      /* SPACE */        case 0x20:      /* SPACE */
2063        case 0xa0:      /* NBSP */        case 0xa0:      /* NBSP */
# Line 1686  for (;;) Line 2083  for (;;)
2083      break;      break;
2084    
2085      case OP_NOT_VSPACE:      case OP_NOT_VSPACE:
2086      if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);      if (eptr >= md->end_subject)
2087          {
2088          SCHECK_PARTIAL();
2089          MRRETURN(MATCH_NOMATCH);
2090          }
2091      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
2092      switch(c)      switch(c)
2093        {        {
# Line 1698  for (;;) Line 2099  for (;;)
2099        case 0x85:      /* NEL */        case 0x85:      /* NEL */
2100        case 0x2028:    /* LINE SEPARATOR */        case 0x2028:    /* LINE SEPARATOR */
2101        case 0x2029:    /* PARAGRAPH SEPARATOR */        case 0x2029:    /* PARAGRAPH SEPARATOR */
2102        RRETURN(MATCH_NOMATCH);        MRRETURN(MATCH_NOMATCH);
2103        }        }
2104      ecode++;      ecode++;
2105      break;      break;
2106    
2107      case OP_VSPACE:      case OP_VSPACE:
2108      if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);      if (eptr >= md->end_subject)
2109          {
2110          SCHECK_PARTIAL();
2111          MRRETURN(MATCH_NOMATCH);
2112          }
2113      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
2114      switch(c)      switch(c)
2115        {        {
2116        default: RRETURN(MATCH_NOMATCH);        default: MRRETURN(MATCH_NOMATCH);
2117        case 0x0a:      /* LF */        case 0x0a:      /* LF */
2118        case 0x0b:      /* VT */        case 0x0b:      /* VT */
2119        case 0x0c:      /* FF */        case 0x0c:      /* FF */
# Line 1727  for (;;) Line 2132  for (;;)
2132    
2133      case OP_PROP:      case OP_PROP:
2134      case OP_NOTPROP:      case OP_NOTPROP:
2135      if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);      if (eptr >= md->end_subject)
2136          {
2137          SCHECK_PARTIAL();
2138          MRRETURN(MATCH_NOMATCH);
2139          }
2140      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
2141        {        {
2142        const ucd_record *prop = GET_UCD(c);        const ucd_record *prop = GET_UCD(c);
# Line 1735  for (;;) Line 2144  for (;;)
2144        switch(ecode[1])        switch(ecode[1])
2145          {          {
2146          case PT_ANY:          case PT_ANY:
2147          if (op == OP_NOTPROP) RRETURN(MATCH_NOMATCH);          if (op == OP_NOTPROP) MRRETURN(MATCH_NOMATCH);
2148          break;          break;
2149    
2150          case PT_LAMP:          case PT_LAMP:
2151          if ((prop->chartype == ucp_Lu ||          if ((prop->chartype == ucp_Lu ||
2152               prop->chartype == ucp_Ll ||               prop->chartype == ucp_Ll ||
2153               prop->chartype == ucp_Lt) == (op == OP_NOTPROP))               prop->chartype == ucp_Lt) == (op == OP_NOTPROP))
2154            RRETURN(MATCH_NOMATCH);            MRRETURN(MATCH_NOMATCH);
2155           break;          break;
2156    
2157          case PT_GC:          case PT_GC:
2158          if ((ecode[2] != _pcre_ucp_gentype[prop->chartype]) == (op == OP_PROP))          if ((ecode[2] != _pcre_ucp_gentype[prop->chartype]) == (op == OP_PROP))
2159            RRETURN(MATCH_NOMATCH);            MRRETURN(MATCH_NOMATCH);
2160          break;          break;
2161    
2162          case PT_PC:          case PT_PC:
2163          if ((ecode[2] != prop->chartype) == (op == OP_PROP))          if ((ecode[2] != prop->chartype) == (op == OP_PROP))
2164            RRETURN(MATCH_NOMATCH);            MRRETURN(MATCH_NOMATCH);
2165          break;          break;
2166    
2167          case PT_SC:          case PT_SC:
2168          if ((ecode[2] != prop->script) == (op == OP_PROP))          if ((ecode[2] != prop->script) == (op == OP_PROP))
2169            RRETURN(MATCH_NOMATCH);            MRRETURN(MATCH_NOMATCH);
2170            break;
2171    
2172            /* These are specials */
2173    
2174            case PT_ALNUM:
2175            if ((_pcre_ucp_gentype[prop->chartype] == ucp_L ||
2176                 _pcre_ucp_gentype[prop->chartype] == ucp_N) == (op == OP_NOTPROP))
2177              MRRETURN(MATCH_NOMATCH);
2178            break;
2179    
2180            case PT_SPACE:    /* Perl space */
2181            if ((_pcre_ucp_gentype[prop->chartype] == ucp_Z ||
2182                 c == CHAR_HT || c == CHAR_NL || c == CHAR_FF || c == CHAR_CR)
2183                   == (op == OP_NOTPROP))
2184              MRRETURN(MATCH_NOMATCH);
2185          break;          break;
2186    
2187            case PT_PXSPACE:  /* POSIX space */
2188            if ((_pcre_ucp_gentype[prop->chartype] == ucp_Z ||
2189                 c == CHAR_HT || c == CHAR_NL || c == CHAR_VT ||
2190                 c == CHAR_FF || c == CHAR_CR)
2191                   == (op == OP_NOTPROP))
2192              MRRETURN(MATCH_NOMATCH);
2193            break;
2194    
2195            case PT_WORD:
2196            if ((_pcre_ucp_gentype[prop->chartype] == ucp_L ||
2197                 _pcre_ucp_gentype[prop->chartype] == ucp_N ||
2198                 c == CHAR_UNDERSCORE) == (op == OP_NOTPROP))
2199              MRRETURN(MATCH_NOMATCH);
2200            break;
2201    
2202            /* This should never occur */
2203    
2204          default:          default:
2205          RRETURN(PCRE_ERROR_INTERNAL);          RRETURN(PCRE_ERROR_INTERNAL);
2206          }          }
# Line 1772  for (;;) Line 2213  for (;;)
2213      is in the binary; otherwise a compile-time error occurs. */      is in the binary; otherwise a compile-time error occurs. */
2214    
2215      case OP_EXTUNI:      case OP_EXTUNI:
2216      if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);      if (eptr >= md->end_subject)
2217          {
2218          SCHECK_PARTIAL();
2219          MRRETURN(MATCH_NOMATCH);
2220          }
2221      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
2222        {        {
2223        int category = UCD_CATEGORY(c);        int category = UCD_CATEGORY(c);
2224        if (category == ucp_M) RRETURN(MATCH_NOMATCH);        if (category == ucp_M) MRRETURN(MATCH_NOMATCH);
2225        while (eptr < md->end_subject)        while (eptr < md->end_subject)
2226          {          {
2227          int len = 1;          int len = 1;
# Line 1821  for (;;) Line 2266  for (;;)
2266        referenced subpattern. */        referenced subpattern. */
2267    
2268        if (offset >= offset_top || md->offset_vector[offset] < 0)        if (offset >= offset_top || md->offset_vector[offset] < 0)
2269          length = (md->jscript_compat)? 0 : md->end_subject - eptr + 1;          length = (md->jscript_compat)? 0 : (int)(md->end_subject - eptr + 1);
2270        else        else
2271          length = md->offset_vector[offset+1] - md->offset_vector[offset];          length = md->offset_vector[offset+1] - md->offset_vector[offset];
2272    
# Line 1852  for (;;) Line 2297  for (;;)
2297          break;          break;
2298    
2299          default:               /* No repeat follows */          default:               /* No repeat follows */
2300          if (!match_ref(offset, eptr, length, md, ims)) RRETURN(MATCH_NOMATCH);          if (!match_ref(offset, eptr, length, md, ims))
2301              {
2302              CHECK_PARTIAL();
2303              MRRETURN(MATCH_NOMATCH);
2304              }
2305          eptr += length;          eptr += length;
2306          continue;              /* With the main loop */          continue;              /* With the main loop */
2307          }          }
# Line 1868  for (;;) Line 2317  for (;;)
2317    
2318        for (i = 1; i <= min; i++)        for (i = 1; i <= min; i++)
2319          {          {
2320          if (!match_ref(offset, eptr, length, md, ims))          if (!match_ref(offset, eptr, length, md, ims))
2321            {            {
2322            CHECK_PARTIAL();            CHECK_PARTIAL();
2323            RRETURN(MATCH_NOMATCH);            MRRETURN(MATCH_NOMATCH);
2324            }            }
2325          eptr += length;          eptr += length;
2326          }          }
2327    
# Line 1889  for (;;) Line 2338  for (;;)
2338            {            {
2339            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM14);            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM14);
2340            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2341            if (fi >= max || !match_ref(offset, eptr, length, md, ims))            if (fi >= max) MRRETURN(MATCH_NOMATCH);
2342              if (!match_ref(offset, eptr, length, md, ims))
2343              {              {
2344              CHECK_PARTIAL();              CHECK_PARTIAL();
2345              RRETURN(MATCH_NOMATCH);              MRRETURN(MATCH_NOMATCH);
2346              }              }
2347            eptr += length;            eptr += length;
2348            }            }
2349          /* Control never gets here */          /* Control never gets here */
# Line 1906  for (;;) Line 2356  for (;;)
2356          pp = eptr;          pp = eptr;
2357          for (i = min; i < max; i++)          for (i = min; i < max; i++)
2358            {            {
2359            if (!match_ref(offset, eptr, length, md, ims)) break;            if (!match_ref(offset, eptr, length, md, ims))
2360                {
2361                CHECK_PARTIAL();
2362                break;
2363                }
2364            eptr += length;            eptr += length;
2365            }            }
         CHECK_PARTIAL();  
2366          while (eptr >= pp)          while (eptr >= pp)
2367            {            {
2368            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM15);            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM15);
2369            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2370            eptr -= length;            eptr -= length;
2371            }            }
2372          RRETURN(MATCH_NOMATCH);          MRRETURN(MATCH_NOMATCH);
2373          }          }
2374        }        }
2375      /* Control never gets here */      /* Control never gets here */
2376    
   
   
2377      /* Match a bit-mapped character class, possibly repeatedly. This op code is      /* Match a bit-mapped character class, possibly repeatedly. This op code is
2378      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,
2379      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 1977  for (;;) Line 2428  for (;;)
2428          {          {
2429          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
2430            {            {
2431            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
2432              {              {
2433              CHECK_PARTIAL();              SCHECK_PARTIAL();
2434              RRETURN(MATCH_NOMATCH);              MRRETURN(MATCH_NOMATCH);
2435              }              }
2436            GETCHARINC(c, eptr);            GETCHARINC(c, eptr);
2437            if (c > 255)            if (c > 255)
2438              {              {
2439              if (op == OP_CLASS) RRETURN(MATCH_NOMATCH);              if (op == OP_CLASS) MRRETURN(MATCH_NOMATCH);
2440              }              }
2441            else            else
2442              {              {
2443              if ((data[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);              if ((data[c/8] & (1 << (c&7))) == 0) MRRETURN(MATCH_NOMATCH);
2444              }              }
2445            }            }
2446          }          }
# Line 1999  for (;;) Line 2450  for (;;)
2450          {          {
2451          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
2452            {            {
2453            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
2454              {              {
2455              CHECK_PARTIAL();              SCHECK_PARTIAL();
2456              RRETURN(MATCH_NOMATCH);              MRRETURN(MATCH_NOMATCH);
2457              }              }
2458            c = *eptr++;            c = *eptr++;
2459            if ((data[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);            if ((data[c/8] & (1 << (c&7))) == 0) MRRETURN(MATCH_NOMATCH);
2460            }            }
2461          }          }
2462    
# Line 2027  for (;;) Line 2478  for (;;)
2478              {              {
2479              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM16);              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM16);
2480              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2481              if (fi >= max)              if (fi >= max) MRRETURN(MATCH_NOMATCH);
2482                if (eptr >= md->end_subject)
2483                {                {
2484                CHECK_PARTIAL();                SCHECK_PARTIAL();
2485                RRETURN(MATCH_NOMATCH);                MRRETURN(MATCH_NOMATCH);
2486                }                }
             if (eptr >= md->end_subject)  
               {  
               SCHECK_PARTIAL();  
               RRETURN(MATCH_NOMATCH);  
               }  
2487              GETCHARINC(c, eptr);              GETCHARINC(c, eptr);
2488              if (c > 255)              if (c > 255)
2489                {                {
2490                if (op == OP_CLASS) RRETURN(MATCH_NOMATCH);                if (op == OP_CLASS) MRRETURN(MATCH_NOMATCH);
2491                }                }
2492              else              else
2493                {                {
2494                if ((data[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);                if ((data[c/8] & (1 << (c&7))) == 0) MRRETURN(MATCH_NOMATCH);
2495                }                }
2496              }              }
2497            }            }
# Line 2056  for (;;) Line 2503  for (;;)
2503              {              {
2504              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM17);              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM17);
2505              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2506              if (fi >= max)              if (fi >= max) MRRETURN(MATCH_NOMATCH);
2507                if (eptr >= md->end_subject)
2508                {                {
2509                CHECK_PARTIAL();                SCHECK_PARTIAL();
2510                RRETURN(MATCH_NOMATCH);                MRRETURN(MATCH_NOMATCH);
2511                }                }
             if (eptr >= md->end_subject)  
               {  
               SCHECK_PARTIAL();  
               RRETURN(MATCH_NOMATCH);  
               }  
2512              c = *eptr++;              c = *eptr++;
2513              if ((data[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);              if ((data[c/8] & (1 << (c&7))) == 0) MRRETURN(MATCH_NOMATCH);
2514              }              }
2515            }            }
2516          /* Control never gets here */          /* Control never gets here */
# Line 2086  for (;;) Line 2529  for (;;)
2529            for (i = min; i < max; i++)            for (i = min; i < max; i++)
2530              {              {
2531              int len = 1;              int len = 1;
2532              if (eptr >= md->end_subject) break;              if (eptr >= md->end_subject)
2533                  {
2534                  SCHECK_PARTIAL();
2535                  break;
2536                  }
2537              GETCHARLEN(c, eptr, len);              GETCHARLEN(c, eptr, len);
2538              if (c > 255)              if (c > 255)
2539                {                {
# Line 2098  for (;;) Line 2545  for (;;)
2545                }                }
2546              eptr += len;              eptr += len;
2547              }              }
           CHECK_PARTIAL();  
2548            for (;;)            for (;;)
2549              {              {
2550              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM18);              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM18);
# Line 2113  for (;;) Line 2559  for (;;)
2559            {            {
2560            for (i = min; i < max; i++)            for (i = min; i < max; i++)
2561              {              {
2562              if (eptr >= md->end_subject) break;              if (eptr >= md->end_subject)
2563                  {
2564                  SCHECK_PARTIAL();
2565                  break;
2566                  }
2567              c = *eptr;              c = *eptr;
2568              if ((data[c/8] & (1 << (c&7))) == 0) break;              if ((data[c/8] & (1 << (c&7))) == 0) break;
2569              eptr++;              eptr++;
2570              }              }
           CHECK_PARTIAL();  
2571            while (eptr >= pp)            while (eptr >= pp)
2572              {              {
2573              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM19);              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM19);
# Line 2127  for (;;) Line 2576  for (;;)
2576              }              }
2577            }            }
2578    
2579          RRETURN(MATCH_NOMATCH);          MRRETURN(MATCH_NOMATCH);
2580          }          }
2581        }        }
2582      /* Control never gets here */      /* Control never gets here */
# Line 2176  for (;;) Line 2625  for (;;)
2625    
2626        for (i = 1; i <= min; i++)        for (i = 1; i <= min; i++)
2627          {          {
2628          if (eptr >= md->end_subject)          if (eptr >= md->end_subject)
2629            {            {
2630            SCHECK_PARTIAL();            SCHECK_PARTIAL();
2631            RRETURN(MATCH_NOMATCH);            MRRETURN(MATCH_NOMATCH);
2632            }            }
2633          GETCHARINCTEST(c, eptr);          GETCHARINCTEST(c, eptr);
2634          if (!_pcre_xclass(c, data)) RRETURN(MATCH_NOMATCH);          if (!_pcre_xclass(c, data)) MRRETURN(MATCH_NOMATCH);
2635          }          }
2636    
2637        /* 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 2199  for (;;) Line 2648  for (;;)
2648            {            {
2649            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM20);            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM20);
2650            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2651            if (fi >= max)            if (fi >= max) MRRETURN(MATCH_NOMATCH);
2652              if (eptr >= md->end_subject)
2653              {              {
2654              CHECK_PARTIAL();              SCHECK_PARTIAL();
2655              RRETURN(MATCH_NOMATCH);              MRRETURN(MATCH_NOMATCH);
2656              }              }
           if (eptr >= md->end_subject)  
             {  
             SCHECK_PARTIAL();  
             RRETURN(MATCH_NOMATCH);  
             }  
2657            GETCHARINCTEST(c, eptr);            GETCHARINCTEST(c, eptr);
2658            if (!_pcre_xclass(c, data)) RRETURN(MATCH_NOMATCH);            if (!_pcre_xclass(c, data)) MRRETURN(MATCH_NOMATCH);
2659            }            }
2660          /* Control never gets here */          /* Control never gets here */
2661          }          }
# Line 2223  for (;;) Line 2668  for (;;)
2668          for (i = min; i < max; i++)          for (i = min; i < max; i++)
2669            {            {
2670            int len = 1;            int len = 1;
2671            if (eptr >= md->end_subject) break;            if (eptr >= md->end_subject)
2672                {
2673                SCHECK_PARTIAL();
2674                break;
2675                }
2676            GETCHARLENTEST(c, eptr, len);            GETCHARLENTEST(c, eptr, len);
2677            if (!_pcre_xclass(c, data)) break;            if (!_pcre_xclass(c, data)) break;
2678            eptr += len;            eptr += len;
2679            }            }
         CHECK_PARTIAL();  
2680          for(;;)          for(;;)
2681            {            {
2682            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM21);            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM21);
# Line 2236  for (;;) Line 2684  for (;;)
2684            if (eptr-- == pp) break;        /* Stop if tried at original pos */            if (eptr-- == pp) break;        /* Stop if tried at original pos */
2685            if (utf8) BACKCHAR(eptr);            if (utf8) BACKCHAR(eptr);
2686            }            }
2687          RRETURN(MATCH_NOMATCH);          MRRETURN(MATCH_NOMATCH);
2688          }          }
2689    
2690        /* Control never gets here */        /* Control never gets here */
# Line 2252  for (;;) Line 2700  for (;;)
2700        length = 1;        length = 1;
2701        ecode++;        ecode++;
2702        GETCHARLEN(fc, ecode, length);        GETCHARLEN(fc, ecode, length);
2703        if (length > md->end_subject - eptr) RRETURN(MATCH_NOMATCH);        if (length > md->end_subject - eptr)
2704        while (length-- > 0) if (*ecode++ != *eptr++) RRETURN(MATCH_NOMATCH);          {
2705            CHECK_PARTIAL();             /* Not SCHECK_PARTIAL() */
2706            MRRETURN(MATCH_NOMATCH);
2707            }
2708          while (length-- > 0) if (*ecode++ != *eptr++) MRRETURN(MATCH_NOMATCH);
2709        }        }
2710      else      else
2711  #endif  #endif
2712    
2713      /* Non-UTF-8 mode */      /* Non-UTF-8 mode */
2714        {        {
2715        if (md->end_subject - eptr < 1) RRETURN(MATCH_NOMATCH);        if (md->end_subject - eptr < 1)
2716        if (ecode[1] != *eptr++) RRETURN(MATCH_NOMATCH);          {
2717            SCHECK_PARTIAL();            /* This one can use SCHECK_PARTIAL() */
2718            MRRETURN(MATCH_NOMATCH);
2719            }
2720          if (ecode[1] != *eptr++) MRRETURN(MATCH_NOMATCH);
2721        ecode += 2;        ecode += 2;
2722        }        }
2723      break;      break;
# Line 2276  for (;;) Line 2732  for (;;)
2732        ecode++;        ecode++;
2733        GETCHARLEN(fc, ecode, length);        GETCHARLEN(fc, ecode, length);
2734    
2735        if (length > md->end_subject - eptr) RRETURN(MATCH_NOMATCH);        if (length > md->end_subject - eptr)
2736            {
2737            CHECK_PARTIAL();             /* Not SCHECK_PARTIAL() */
2738            MRRETURN(MATCH_NOMATCH);
2739            }
2740    
2741        /* 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
2742        can use the fast lookup table. */        can use the fast lookup table. */
2743    
2744        if (fc < 128)        if (fc < 128)
2745          {          {
2746          if (md->lcc[*ecode++] != md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH);          if (md->lcc[*ecode++] != md->lcc[*eptr++]) MRRETURN(MATCH_NOMATCH);
2747          }          }
2748    
2749        /* Otherwise we must pick up the subject character */        /* Otherwise we must pick up the subject character */
# Line 2302  for (;;) Line 2762  for (;;)
2762  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2763            if (dc != UCD_OTHERCASE(fc))            if (dc != UCD_OTHERCASE(fc))
2764  #endif  #endif
2765              RRETURN(MATCH_NOMATCH);              MRRETURN(MATCH_NOMATCH);
2766            }            }
2767          }          }
2768        }        }
# Line 2311  for (;;) Line 2771  for (;;)
2771    
2772      /* Non-UTF-8 mode */      /* Non-UTF-8 mode */
2773        {        {
2774        if (md->end_subject - eptr < 1) RRETURN(MATCH_NOMATCH);        if (md->end_subject - eptr < 1)
2775        if (md->lcc[ecode[1]] != md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH);          {
2776            SCHECK_PARTIAL();            /* This one can use SCHECK_PARTIAL() */
2777            MRRETURN(MATCH_NOMATCH);
2778            }
2779          if (md->lcc[ecode[1]] != md->lcc[*eptr++]) MRRETURN(MATCH_NOMATCH);
2780        ecode += 2;        ecode += 2;
2781        }        }
2782      break;      break;
# Line 2365  for (;;) Line 2829  for (;;)
2829      case OP_MINQUERY:      case OP_MINQUERY:
2830      c = *ecode++ - OP_STAR;      c = *ecode++ - OP_STAR;
2831      minimize = (c & 1) != 0;      minimize = (c & 1) != 0;
2832    
2833      min = rep_min[c];                 /* Pick up values from tables; */      min = rep_min[c];                 /* Pick up values from tables; */
2834      max = rep_max[c];                 /* zero for max => infinity */      max = rep_max[c];                 /* zero for max => infinity */
2835      if (max == 0) max = INT_MAX;      if (max == 0) max = INT_MAX;
# Line 2405  for (;;) Line 2870  for (;;)
2870            else            else
2871              {              {
2872              CHECK_PARTIAL();              CHECK_PARTIAL();
2873              RRETURN(MATCH_NOMATCH);              MRRETURN(MATCH_NOMATCH);
2874              }              }
2875            }            }
2876    
# Line 2417  for (;;) Line 2882  for (;;)
2882              {              {
2883              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM22);              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM22);
2884              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2885              if (fi >= max)              if (fi >= max) MRRETURN(MATCH_NOMATCH);
               {  
               CHECK_PARTIAL();  
               RRETURN(MATCH_NOMATCH);  
               }  
2886              if (eptr <= md->end_subject - length &&              if (eptr <= md->end_subject - length &&
2887                memcmp(eptr, charptr, length) == 0) eptr += length;                memcmp(eptr, charptr, length) == 0) eptr += length;
2888  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
# Line 2432  for (;;) Line 2893  for (;;)
2893              else              else
2894                {                {
2895                CHECK_PARTIAL();                CHECK_PARTIAL();
2896                RRETURN(MATCH_NOMATCH);                MRRETURN(MATCH_NOMATCH);
2897                }                }
2898              }              }
2899            /* Control never gets here */            /* Control never gets here */
# Line 2450  for (;;) Line 2911  for (;;)
2911                       eptr <= md->end_subject - oclength &&                       eptr <= md->end_subject - oclength &&
2912                       memcmp(eptr, occhars, oclength) == 0) eptr += oclength;                       memcmp(eptr, occhars, oclength) == 0) eptr += oclength;
2913  #endif  /* SUPPORT_UCP */  #endif  /* SUPPORT_UCP */
2914              else break;              else
2915                  {
2916                  CHECK_PARTIAL();
2917                  break;
2918                  }
2919              }              }
2920    
           CHECK_PARTIAL();  
2921            if (possessive) continue;            if (possessive) continue;
2922    
2923            for(;;)            for(;;)
2924              {              {
2925              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM23);              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM23);
2926              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2927              if (eptr == pp) { RRETURN(MATCH_NOMATCH); }              if (eptr == pp) { MRRETURN(MATCH_NOMATCH); }
2928  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2929              eptr--;              eptr--;
2930              BACKCHAR(eptr);              BACKCHAR(eptr);
# Line 2503  for (;;) Line 2967  for (;;)
2967          if (eptr >= md->end_subject)          if (eptr >= md->end_subject)
2968            {            {
2969            SCHECK_PARTIAL();            SCHECK_PARTIAL();
2970            RRETURN(MATCH_NOMATCH);            MRRETURN(MATCH_NOMATCH);
2971            }            }
2972          if (fc != md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH);          if (fc != md->lcc[*eptr++]) MRRETURN(MATCH_NOMATCH);
2973          }          }
2974        if (min == max) continue;        if (min == max) continue;
2975        if (minimize)        if (minimize)
# Line 2514  for (;;) Line 2978  for (;;)
2978            {            {
2979            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM24);            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM24);
2980            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2981            if (fi >= max)            if (fi >= max) MRRETURN(MATCH_NOMATCH);
             {  
             CHECK_PARTIAL();  
             RRETURN(MATCH_NOMATCH);  
             }  
2982            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
2983              {              {
2984              SCHECK_PARTIAL();              SCHECK_PARTIAL();
2985              RRETURN(MATCH_NOMATCH);              MRRETURN(MATCH_NOMATCH);
2986              }              }
2987            if (fc != md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH);            if (fc != md->lcc[*eptr++]) MRRETURN(MATCH_NOMATCH);
2988            }            }
2989          /* Control never gets here */          /* Control never gets here */
2990          }          }
# Line 2533  for (;;) Line 2993  for (;;)
2993          pp = eptr;          pp = eptr;
2994          for (i = min; i < max; i++)          for (i = min; i < max; i++)
2995            {            {
2996            if (eptr >= md->end_subject || fc != md->lcc[*eptr]) break;            if (eptr >= md->end_subject)
2997                {
2998                SCHECK_PARTIAL();
2999                break;
3000                }
3001              if (fc != md->lcc[*eptr]) break;
3002            eptr++;            eptr++;
3003            }            }
3004    
         CHECK_PARTIAL();  
3005          if (possessive) continue;          if (possessive) continue;
3006    
3007          while (eptr >= pp)          while (eptr >= pp)
3008            {            {
3009            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM25);            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM25);
3010            eptr--;            eptr--;
3011            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3012            }            }
3013          RRETURN(MATCH_NOMATCH);          MRRETURN(MATCH_NOMATCH);
3014          }          }
3015        /* Control never gets here */        /* Control never gets here */
3016        }        }
# Line 2555  for (;;) Line 3019  for (;;)
3019    
3020      else      else
3021        {        {
3022        for (i = 1; i <= min; i++)        for (i = 1; i <= min; i++)
3023          {          {
3024          if (eptr >= md->end_subject)          if (eptr >= md->end_subject)
3025            {            {
3026            SCHECK_PARTIAL();            SCHECK_PARTIAL();
3027            RRETURN(MATCH_NOMATCH);            MRRETURN(MATCH_NOMATCH);
3028            }            }
3029          if (fc != *eptr++) RRETURN(MATCH_NOMATCH);          if (fc != *eptr++) MRRETURN(MATCH_NOMATCH);
3030          }          }
3031    
3032        if (min == max) continue;        if (min == max) continue;
3033    
3034        if (minimize)        if (minimize)
3035          {          {
3036          for (fi = min;; fi++)          for (fi = min;; fi++)
3037            {            {
3038            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM26);            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM26);
3039            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3040            if (fi >= max)            if (fi >= max) MRRETURN(MATCH_NOMATCH);
             {  
             CHECK_PARTIAL();  
             RRETURN(MATCH_NOMATCH);  
             }  
3041            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
3042              {              {
3043              SCHECK_PARTIAL();              SCHECK_PARTIAL();
3044              RRETURN(MATCH_NOMATCH);              MRRETURN(MATCH_NOMATCH);
3045              }              }
3046            if (fc != *eptr++) RRETURN(MATCH_NOMATCH);            if (fc != *eptr++) MRRETURN(MATCH_NOMATCH);
3047            }            }
3048          /* Control never gets here */          /* Control never gets here */
3049          }          }
# Line 2590  for (;;) Line 3052  for (;;)
3052          pp = eptr;          pp = eptr;
3053          for (i = min; i < max; i++)          for (i = min; i < max; i++)
3054            {            {
3055            if (eptr >= md->end_subject || fc != *eptr) break;            if (eptr >= md->end_subject)
3056                {
3057                SCHECK_PARTIAL();
3058                break;
3059                }
3060              if (fc != *eptr) break;
3061            eptr++;            eptr++;
3062            }            }
         CHECK_PARTIAL();  
3063          if (possessive) continue;          if (possessive) continue;
3064    
3065          while (eptr >= pp)          while (eptr >= pp)
3066            {            {
3067            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM27);            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM27);
3068            eptr--;            eptr--;
3069            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3070            }            }
3071          RRETURN(MATCH_NOMATCH);          MRRETURN(MATCH_NOMATCH);
3072          }          }
3073        }        }
3074      /* Control never gets here */      /* Control never gets here */
# Line 2610  for (;;) Line 3077  for (;;)
3077      checking can be multibyte. */      checking can be multibyte. */
3078    
3079      case OP_NOT:      case OP_NOT:
3080      if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);      if (eptr >= md->end_subject)
3081          {
3082          SCHECK_PARTIAL();
3083          MRRETURN(MATCH_NOMATCH);
3084          }
3085      ecode++;      ecode++;
3086      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
3087      if ((ims & PCRE_CASELESS) != 0)      if ((ims & PCRE_CASELESS) != 0)
# Line 2619  for (;;) Line 3090  for (;;)
3090        if (c < 256)        if (c < 256)
3091  #endif  #endif
3092        c = md->lcc[c];        c = md->lcc[c];
3093        if (md->lcc[*ecode++] == c) RRETURN(MATCH_NOMATCH);        if (md->lcc[*ecode++] == c) MRRETURN(MATCH_NOMATCH);
3094        }        }
3095      else      else
3096        {        {
3097        if (*ecode++ == c) RRETURN(MATCH_NOMATCH);        if (*ecode++ == c) MRRETURN(MATCH_NOMATCH);
3098        }        }
3099      break;      break;
3100    
# Line 2717  for (;;) Line 3188  for (;;)
3188            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
3189              {              {
3190              SCHECK_PARTIAL();              SCHECK_PARTIAL();
3191              RRETURN(MATCH_NOMATCH);              MRRETURN(MATCH_NOMATCH);
3192              }              }
3193            GETCHARINC(d, eptr);            GETCHARINC(d, eptr);
3194            if (d < 256) d = md->lcc[d];            if (d < 256) d = md->lcc[d];
3195            if (fc == d) RRETURN(MATCH_NOMATCH);            if (fc == d) MRRETURN(MATCH_NOMATCH);
3196            }            }
3197          }          }
3198        else        else
# Line 2734  for (;;) Line 3205  for (;;)
3205            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
3206              {              {
3207              SCHECK_PARTIAL();              SCHECK_PARTIAL();
3208              RRETURN(MATCH_NOMATCH);              MRRETURN(MATCH_NOMATCH);
3209              }              }
3210            if (fc == md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH);            if (fc == md->lcc[*eptr++]) MRRETURN(MATCH_NOMATCH);
3211            }            }
3212          }          }
3213    
3214        if (min == max) continue;        if (min == max) continue;
# Line 2753  for (;;) Line 3224  for (;;)
3224              {              {
3225              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM28);              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM28);
3226              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3227              if (fi >= max)              if (fi >= max) MRRETURN(MATCH_NOMATCH);
3228                if (eptr >= md->end_subject)
3229                {                {
3230                CHECK_PARTIAL();                SCHECK_PARTIAL();
3231                RRETURN(MATCH_NOMATCH);                MRRETURN(MATCH_NOMATCH);
3232                }                }
             if (eptr >= md->end_subject)  
               {  
               SCHECK_PARTIAL();  
               RRETURN(MATCH_NOMATCH);  
               }  
3233              GETCHARINC(d, eptr);              GETCHARINC(d, eptr);
3234              if (d < 256) d = md->lcc[d];              if (d < 256) d = md->lcc[d];
3235              if (fc == d) RRETURN(MATCH_NOMATCH);              if (fc == d) MRRETURN(MATCH_NOMATCH);
3236              }              }
3237            }            }
3238          else          else
# Line 2776  for (;;) Line 3243  for (;;)
3243              {              {
3244              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM29);              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM29);
3245              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3246              if (fi >= max)              if (fi >= max) MRRETURN(MATCH_NOMATCH);
               {  
               CHECK_PARTIAL();  
               RRETURN(MATCH_NOMATCH);  
               }  
3247              if (eptr >= md->end_subject)              if (eptr >= md->end_subject)
3248                {                {
3249                SCHECK_PARTIAL();                SCHECK_PARTIAL();
3250                RRETURN(MATCH_NOMATCH);                MRRETURN(MATCH_NOMATCH);
3251                }                }
3252              if (fc == md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH);              if (fc == md->lcc[*eptr++]) MRRETURN(MATCH_NOMATCH);
3253              }              }
3254            }            }
3255          /* Control never gets here */          /* Control never gets here */
# Line 2806  for (;;) Line 3269  for (;;)
3269            for (i = min; i < max; i++)            for (i = min; i < max; i++)
3270              {              {
3271              int len = 1;              int len = 1;
3272              if (eptr >= md->end_subject) break;              if (eptr >= md->end_subject)
3273                  {
3274                  SCHECK_PARTIAL();
3275                  break;
3276                  }
3277              GETCHARLEN(d, eptr, len);              GETCHARLEN(d, eptr, len);
3278              if (d < 256) d = md->lcc[d];              if (d < 256) d = md->lcc[d];
3279              if (fc == d) break;              if (fc == d) break;
3280              eptr += len;              eptr += len;
3281              }              }
         CHECK_PARTIAL();  
3282          if (possessive) continue;          if (possessive) continue;
3283          for(;;)          for(;;)
3284              {              {
# Line 2828  for (;;) Line 3294  for (;;)
3294            {            {
3295            for (i = min; i < max; i++)            for (i = min; i < max; i++)
3296              {              {
3297              if (eptr >= md->end_subject || fc == md->lcc[*eptr]) break;              if (eptr >= md->end_subject)
3298                  {
3299                  SCHECK_PARTIAL();
3300                  break;
3301                  }
3302                if (fc == md->lcc[*eptr]) break;
3303              eptr++;              eptr++;
3304              }              }
           CHECK_PARTIAL();  
3305            if (possessive) continue;            if (possessive) continue;
3306            while (eptr >= pp)            while (eptr >= pp)
3307              {              {
# Line 2841  for (;;) Line 3311  for (;;)
3311              }              }
3312            }            }
3313    
3314          RRETURN(MATCH_NOMATCH);          MRRETURN(MATCH_NOMATCH);
3315          }          }
3316        /* Control never gets here */        /* Control never gets here */
3317        }        }
# Line 2860  for (;;) Line 3330  for (;;)
3330            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
3331              {              {
3332              SCHECK_PARTIAL();              SCHECK_PARTIAL();
3333              RRETURN(MATCH_NOMATCH);              MRRETURN(MATCH_NOMATCH);
3334              }              }
3335            GETCHARINC(d, eptr);            GETCHARINC(d, eptr);
3336            if (fc == d) RRETURN(MATCH_NOMATCH);            if (fc == d) MRRETURN(MATCH_NOMATCH);
3337            }            }
3338          }          }
3339        else        else
# Line 2875  for (;;) Line 3345  for (;;)
3345            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
3346              {              {
3347              SCHECK_PARTIAL();              SCHECK_PARTIAL();
3348              RRETURN(MATCH_NOMATCH);              MRRETURN(MATCH_NOMATCH);
3349              }              }
3350            if (fc == *eptr++) RRETURN(MATCH_NOMATCH);            if (fc == *eptr++) MRRETURN(MATCH_NOMATCH);
3351            }            }
3352          }          }
3353    
3354        if (min == max) continue;        if (min == max) continue;
# Line 2894  for (;;) Line 3364  for (;;)
3364              {              {
3365              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM32);              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM32);
3366              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3367              if (fi >= max)              if (fi >= max) MRRETURN(MATCH_NOMATCH);
3368                if (eptr >= md->end_subject)
3369                {                {
3370                CHECK_PARTIAL();                SCHECK_PARTIAL();
3371                RRETURN(MATCH_NOMATCH);                MRRETURN(MATCH_NOMATCH);
3372                }                }
             if (eptr >= md->end_subject)  
               {  
               SCHECK_PARTIAL();  
               RRETURN(MATCH_NOMATCH);  
               }  
3373              GETCHARINC(d, eptr);              GETCHARINC(d, eptr);
3374              if (fc == d) RRETURN(MATCH_NOMATCH);              if (fc == d) MRRETURN(MATCH_NOMATCH);
3375              }              }
3376            }            }
3377          else          else
# Line 2916  for (;;) Line 3382  for (;;)
3382              {              {
3383              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM33);              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM33);
3384              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3385              if (fi >= max)              if (fi >= max) MRRETURN(MATCH_NOMATCH);
               {  
               CHECK_PARTIAL();  
               RRETURN(MATCH_NOMATCH);  
               }  
3386              if (eptr >= md->end_subject)              if (eptr >= md->end_subject)
3387                {                {
3388                SCHECK_PARTIAL();                SCHECK_PARTIAL();
3389                RRETURN(MATCH_NOMATCH);                MRRETURN(MATCH_NOMATCH);
3390                }                }
3391              if (fc == *eptr++) RRETURN(MATCH_NOMATCH);              if (fc == *eptr++) MRRETURN(MATCH_NOMATCH);
3392              }              }
3393            }            }
3394          /* Control never gets here */          /* Control never gets here */
# Line 2946  for (;;) Line 3408  for (;;)
3408            for (i = min; i < max; i++)            for (i = min; i < max; i++)
3409              {              {
3410              int len = 1;              int len = 1;
3411              if (eptr >= md->end_subject) break;              if (eptr >= md->end_subject)
3412                  {
3413                  SCHECK_PARTIAL();
3414                  break;
3415                  }
3416              GETCHARLEN(d, eptr, len);              GETCHARLEN(d, eptr, len);
3417              if (fc == d) break;              if (fc == d) break;
3418              eptr += len;              eptr += len;
3419              }              }
           CHECK_PARTIAL();  
3420            if (possessive) continue;            if (possessive) continue;
3421            for(;;)            for(;;)
3422              {              {
# Line 2967  for (;;) Line 3432  for (;;)
3432            {            {
3433            for (i = min; i < max; i++)            for (i = min; i < max; i++)
3434              {              {
3435              if (eptr >= md->end_subject || fc == *eptr) break;              if (eptr >= md->end_subject)
3436                  {
3437                  SCHECK_PARTIAL();
3438                  break;
3439                  }
3440                if (fc == *eptr) break;
3441              eptr++;              eptr++;
3442              }              }
           CHECK_PARTIAL();  
3443            if (possessive) continue;            if (possessive) continue;
3444            while (eptr >= pp)            while (eptr >= pp)
3445              {              {
# Line 2980  for (;;) Line 3449  for (;;)
3449              }              }
3450            }            }
3451    
3452          RRETURN(MATCH_NOMATCH);          MRRETURN(MATCH_NOMATCH);
3453          }          }
3454        }        }
3455      /* Control never gets here */      /* Control never gets here */
# Line 3074  for (;;) Line 3543  for (;;)
3543          switch(prop_type)          switch(prop_type)
3544            {            {
3545            case PT_ANY:            case PT_ANY:
3546            if (prop_fail_result) RRETURN(MATCH_NOMATCH);            if (prop_fail_result) MRRETURN(MATCH_NOMATCH);
3547            for (i = 1; i <= min; i++)            for (i = 1; i <= min; i++)
3548              {              {
3549              if (eptr >= md->end_subject)              if (eptr >= md->end_subject)
3550                {                {
3551                SCHECK_PARTIAL();                SCHECK_PARTIAL();
3552                RRETURN(MATCH_NOMATCH);                MRRETURN(MATCH_NOMATCH);
3553                }                }
3554              GETCHARINCTEST(c, eptr);              GETCHARINCTEST(c, eptr);
3555              }              }
3556            break;            break;
# Line 3089  for (;;) Line 3558  for (;;)
3558            case PT_LAMP:            case PT_LAMP:
3559            for (i = 1; i <= min; i++)            for (i = 1; i <= min; i++)
3560              {              {
3561              if (eptr >= md->end_subject)              if (eptr >= md->end_subject)
3562                {                {
3563                SCHECK_PARTIAL();                SCHECK_PARTIAL();
3564                RRETURN(MATCH_NOMATCH);                MRRETURN(MATCH_NOMATCH);
3565                }                }
3566              GETCHARINCTEST(c, eptr);              GETCHARINCTEST(c, eptr);
3567              prop_chartype = UCD_CHARTYPE(c);              prop_chartype = UCD_CHARTYPE(c);
3568              if ((prop_chartype == ucp_Lu ||              if ((prop_chartype == ucp_Lu ||
3569                   prop_chartype == ucp_Ll ||                   prop_chartype == ucp_Ll ||
3570                   prop_chartype == ucp_Lt) == prop_fail_result)                   prop_chartype == ucp_Lt) == prop_fail_result)
3571                RRETURN(MATCH_NOMATCH);                MRRETURN(MATCH_NOMATCH);
3572              }              }
3573            break;            break;
3574    
3575            case PT_GC:            case PT_GC:
3576            for (i = 1; i <= min; i++)            for (i = 1; i <= min; i++)
3577              {              {
3578              if (eptr >= md->end_subject)              if (eptr >= md->end_subject)
3579                {                {
3580                SCHECK_PARTIAL();                SCHECK_PARTIAL();
3581                RRETURN(MATCH_NOMATCH);                MRRETURN(MATCH_NOMATCH);
3582                }                }
3583              GETCHARINCTEST(c, eptr);              GETCHARINCTEST(c, eptr);
3584              prop_category = UCD_CATEGORY(c);              prop_category = UCD_CATEGORY(c);
3585              if ((prop_category == prop_value) == prop_fail_result)              if ((prop_category == prop_value) == prop_fail_result)
3586                RRETURN(MATCH_NOMATCH);                MRRETURN(MATCH_NOMATCH);
3587              }              }
3588            break;            break;
3589    
3590            case PT_PC:            case PT_PC:
3591            for (i = 1; i <= min; i++)            for (i = 1; i <= min; i++)
3592              {              {
3593              if (eptr >= md->end_subject)              if (eptr >= md->end_subject)
3594                {                {
3595                SCHECK_PARTIAL();                SCHECK_PARTIAL();
3596                RRETURN(MATCH_NOMATCH);                MRRETURN(MATCH_NOMATCH);
3597                }                }
3598              GETCHARINCTEST(c, eptr);              GETCHARINCTEST(c, eptr);
3599              prop_chartype = UCD_CHARTYPE(c);              prop_chartype = UCD_CHARTYPE(c);
3600              if ((prop_chartype == prop_value) == prop_fail_result)              if ((prop_chartype == prop_value) == prop_fail_result)
3601                RRETURN(MATCH_NOMATCH);                MRRETURN(MATCH_NOMATCH);
3602              }              }
3603            break;            break;
3604    
3605            case PT_SC:            case PT_SC:
3606            for (i = 1; i <= min; i++)            for (i = 1; i <= min; i++)
3607              {              {
3608              if (eptr >= md->end_subject)              if (eptr >= md->end_subject)
3609                {                {
3610                SCHECK_PARTIAL();                SCHECK_PARTIAL();
3611                RRETURN(MATCH_NOMATCH);                MRRETURN(MATCH_NOMATCH);
3612                }                }
3613              GETCHARINCTEST(c, eptr);              GETCHARINCTEST(c, eptr);
3614              prop_script = UCD_SCRIPT(c);              prop_script = UCD_SCRIPT(c);
3615              if ((prop_script == prop_value) == prop_fail_result)              if ((prop_script == prop_value) == prop_fail_result)
3616                RRETURN(MATCH_NOMATCH);                MRRETURN(MATCH_NOMATCH);
3617                }
3618              break;
3619    
3620              case PT_ALNUM:
3621              for (i = 1; i <= min; i++)
3622                {
3623                if (eptr >= md->end_subject)
3624                  {
3625                  SCHECK_PARTIAL();
3626                  MRRETURN(MATCH_NOMATCH);
3627                  }
3628                GETCHARINCTEST(c, eptr);
3629                prop_category = UCD_CATEGORY(c);
3630                if ((prop_category == ucp_L || prop_category == ucp_N)
3631                       == prop_fail_result)
3632                  MRRETURN(MATCH_NOMATCH);
3633                }
3634              break;
3635    
3636              case PT_SPACE:    /* Perl space */
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_Z || c == CHAR_HT || c == CHAR_NL ||
3647                     c == CHAR_FF || c == CHAR_CR)
3648                       == prop_fail_result)
3649                  MRRETURN(MATCH_NOMATCH);
3650                }
3651              break;
3652    
3653              case PT_PXSPACE:  /* POSIX space */
3654              for (i = 1; i <= min; i++)
3655                {
3656                if (eptr >= md->end_subject)
3657                  {
3658                  SCHECK_PARTIAL();
3659                  MRRETURN(MATCH_NOMATCH);
3660                  }
3661                GETCHARINCTEST(c, eptr);
3662                prop_category = UCD_CATEGORY(c);
3663                if ((prop_category == ucp_Z || c == CHAR_HT || c == CHAR_NL ||
3664                     c == CHAR_VT || c == CHAR_FF || c == CHAR_CR)
3665                       == prop_fail_result)
3666                  MRRETURN(MATCH_NOMATCH);
3667                }
3668              break;
3669    
3670              case PT_WORD:
3671              for (i = 1; i <= min; i++)
3672                {
3673                if (eptr >= md->end_subject)
3674                  {
3675                  SCHECK_PARTIAL();
3676                  MRRETURN(MATCH_NOMATCH);
3677                  }
3678                GETCHARINCTEST(c, eptr);
3679                prop_category = UCD_CATEGORY(c);
3680                if ((prop_category == ucp_L || prop_category == ucp_N ||
3681                     c == CHAR_UNDERSCORE)
3682                       == prop_fail_result)
3683                  MRRETURN(MATCH_NOMATCH);
3684              }              }
3685            break;            break;
3686    
3687              /* This should not occur */
3688    
3689            default:            default:
3690            RRETURN(PCRE_ERROR_INTERNAL);            RRETURN(PCRE_ERROR_INTERNAL);
3691            }            }
# Line 3160  for (;;) Line 3698  for (;;)
3698          {          {
3699          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3700            {            {
3701            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
3702              {              {
3703              SCHECK_PARTIAL();              SCHECK_PARTIAL();
3704              RRETURN(MATCH_NOMATCH);              MRRETURN(MATCH_NOMATCH);
3705              }              }
3706            GETCHARINCTEST(c, eptr);            GETCHARINCTEST(c, eptr);
3707            prop_category = UCD_CATEGORY(c);            prop_category = UCD_CATEGORY(c);
3708            if (prop_category == ucp_M) RRETURN(MATCH_NOMATCH);            if (prop_category == ucp_M) MRRETURN(MATCH_NOMATCH);
3709            while (eptr < md->end_subject)            while (eptr < md->end_subject)
3710              {              {
3711              int len = 1;              int len = 1;
# Line 3193  for (;;) Line 3731  for (;;)
3731            {            {
3732            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
3733              {              {
3734              SCHECK_PARTIAL();              SCHECK_PARTIAL();
3735              RRETURN(MATCH_NOMATCH);              MRRETURN(MATCH_NOMATCH);
3736              }              }
3737            if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH);            if (IS_NEWLINE(eptr)) MRRETURN(MATCH_NOMATCH);
3738            eptr++;            eptr++;
3739            while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;            while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;
3740            }            }
# Line 3205  for (;;) Line 3743  for (;;)
3743          case OP_ALLANY:          case OP_ALLANY:
3744          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3745            {            {
3746            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
3747              {              {
3748              SCHECK_PARTIAL();              SCHECK_PARTIAL();
3749              RRETURN(MATCH_NOMATCH);              MRRETURN(MATCH_NOMATCH);
3750              }              }
3751            eptr++;            eptr++;
3752            while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;            while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;
3753            }            }
3754          break;          break;
3755    
3756          case OP_ANYBYTE:          case OP_ANYBYTE:
3757          if (eptr > md->end_subject - min) RRETURN(MATCH_NOMATCH);          if (eptr > md->end_subject - min) MRRETURN(MATCH_NOMATCH);
3758          eptr += min;          eptr += min;
3759          break;          break;
3760    
3761          case OP_ANYNL:          case OP_ANYNL:
3762          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3763            {            {
3764            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
3765              {              {
3766              SCHECK_PARTIAL();              SCHECK_PARTIAL();
3767              RRETURN(MATCH_NOMATCH);              MRRETURN(MATCH_NOMATCH);
3768              }              }
3769            GETCHARINC(c, eptr);            GETCHARINC(c, eptr);
3770            switch(c)            switch(c)
3771              {              {
3772              default: RRETURN(MATCH_NOMATCH);              default: MRRETURN(MATCH_NOMATCH);
3773              case 0x000d:              case 0x000d:
3774              if (eptr < md->end_subject && *eptr == 0x0a) eptr++;              if (eptr < md->end_subject && *eptr == 0x0a) eptr++;
3775              break;              break;
# Line 3244  for (;;) Line 3782  for (;;)
3782              case 0x0085:              case 0x0085:
3783              case 0x2028:              case 0x2028:
3784              case 0x2029:              case 0x2029:
3785              if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH);              if (md->bsr_anycrlf) MRRETURN(MATCH_NOMATCH);
3786              break;              break;
3787              }              }
3788            }            }
# Line 3253  for (;;) Line 3791  for (;;)
3791          case OP_NOT_HSPACE:          case OP_NOT_HSPACE:
3792          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3793            {            {
3794            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
3795              {              {
3796              SCHECK_PARTIAL();              SCHECK_PARTIAL();
3797              RRETURN(MATCH_NOMATCH);              MRRETURN(MATCH_NOMATCH);
3798              }              }
3799            GETCHARINC(c, eptr);            GETCHARINC(c, eptr);
3800            switch(c)            switch(c)
3801              {              {
# Line 3281  for (;;) Line 3819  for (;;)
3819              case 0x202f:    /* NARROW NO-BREAK SPACE */              case 0x202f:    /* NARROW NO-BREAK SPACE */
3820              case 0x205f:    /* MEDIUM MATHEMATICAL SPACE */              case 0x205f:    /* MEDIUM MATHEMATICAL SPACE */
3821              case 0x3000:    /* IDEOGRAPHIC SPACE */              case 0x3000:    /* IDEOGRAPHIC SPACE */
3822              RRETURN(MATCH_NOMATCH);              MRRETURN(MATCH_NOMATCH);
3823              }              }
3824            }            }
3825          break;          break;
# Line 3289  for (;;) Line 3827  for (;;)
3827          case OP_HSPACE:          case OP_HSPACE:
3828          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3829            {            {
3830            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
3831              {              {
3832              SCHECK_PARTIAL();              SCHECK_PARTIAL();
3833              RRETURN(MATCH_NOMATCH);              MRRETURN(MATCH_NOMATCH);
3834              }              }
3835            GETCHARINC(c, eptr);            GETCHARINC(c, eptr);
3836            switch(c)            switch(c)
3837              {              {
3838              default: RRETURN(MATCH_NOMATCH);              default: MRRETURN(MATCH_NOMATCH);
3839              case 0x09:      /* HT */              case 0x09:      /* HT */
3840              case 0x20:      /* SPACE */              case 0x20:      /* SPACE */
3841              case 0xa0:      /* NBSP */              case 0xa0:      /* NBSP */
# Line 3325  for (;;) Line 3863  for (;;)
3863          case OP_NOT_VSPACE:          case OP_NOT_VSPACE:
3864          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3865            {            {
3866            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
3867              {              {
3868              SCHECK_PARTIAL();              SCHECK_PARTIAL();
3869              RRETURN(MATCH_NOMATCH);              MRRETURN(MATCH_NOMATCH);
3870              }              }
3871            GETCHARINC(c, eptr);            GETCHARINC(c, eptr);
3872            switch(c)            switch(c)
3873              {              {
# Line 3341  for (;;) Line 3879  for (;;)
3879              case 0x85:      /* NEL */              case 0x85:      /* NEL */
3880              case 0x2028:    /* LINE SEPARATOR */              case 0x2028:    /* LINE SEPARATOR */
3881              case 0x2029:    /* PARAGRAPH SEPARATOR */              case 0x2029:    /* PARAGRAPH SEPARATOR */
3882              RRETURN(MATCH_NOMATCH);              MRRETURN(MATCH_NOMATCH);
3883              }              }
3884            }            }
3885          break;          break;
# Line 3349  for (;;) Line 3887  for (;;)
3887          case OP_VSPACE:          case OP_VSPACE:
3888          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3889            {            {
3890            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
3891              {              {
3892              SCHECK_PARTIAL();              SCHECK_PARTIAL();
3893              RRETURN(MATCH_NOMATCH);              MRRETURN(MATCH_NOMATCH);
3894              }              }
3895            GETCHARINC(c, eptr);            GETCHARINC(c, eptr);
3896            switch(c)            switch(c)
3897              {              {
3898              default: RRETURN(MATCH_NOMATCH);              default: MRRETURN(MATCH_NOMATCH);
3899              case 0x0a:      /* LF */              case 0x0a:      /* LF */
3900              case 0x0b:      /* VT */              case 0x0b:      /* VT */
3901              case 0x0c:      /* FF */              case 0x0c:      /* FF */
# Line 3373  for (;;) Line 3911  for (;;)
3911          case OP_NOT_DIGIT:          case OP_NOT_DIGIT:
3912          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3913            {            {
3914            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
3915              {              {
3916              SCHECK_PARTIAL();              SCHECK_PARTIAL();
3917              RRETURN(MATCH_NOMATCH);              MRRETURN(MATCH_NOMATCH);
3918              }              }
3919            GETCHARINC(c, eptr);            GETCHARINC(c, eptr);
3920            if (c < 128 && (md->ctypes[c] & ctype_digit) != 0)            if (c < 128 && (md->ctypes[c] & ctype_digit) != 0)
3921              RRETURN(MATCH_NOMATCH);              MRRETURN(MATCH_NOMATCH);
3922            }            }
3923          break;          break;
3924    
3925          case OP_DIGIT:          case OP_DIGIT:
3926          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3927            {            {
3928            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
3929              {              {
3930              SCHECK_PARTIAL();              SCHECK_PARTIAL();
3931              RRETURN(MATCH_NOMATCH);              MRRETURN(MATCH_NOMATCH);
3932              }              }
3933            if (*eptr >= 128 || (md->ctypes[*eptr++] & ctype_digit) == 0)            if (*eptr >= 128 || (md->ctypes[*eptr++] & ctype_digit) == 0)
3934              RRETURN(MATCH_NOMATCH);              MRRETURN(MATCH_NOMATCH);
3935            /* 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 */
3936            }            }
3937          break;          break;
# Line 3401  for (;;) Line 3939  for (;;)
3939          case OP_NOT_WHITESPACE:          case OP_NOT_WHITESPACE:
3940          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3941            {            {
3942            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
3943              {              {
3944              SCHECK_PARTIAL();              SCHECK_PARTIAL();
3945              RRETURN(MATCH_NOMATCH);              MRRETURN(MATCH_NOMATCH);
3946              }              }
3947            if (*eptr < 128 && (md->ctypes[*eptr] & ctype_space) != 0)            if (*eptr < 128 && (md->ctypes[*eptr] & ctype_space) != 0)
3948              RRETURN(MATCH_NOMATCH);              MRRETURN(MATCH_NOMATCH);
3949            while (++eptr < md->end_subject && (*eptr & 0xc0) == 0x80);            while (++eptr < md->end_subject && (*eptr & 0xc0) == 0x80);
3950            }            }
3951          break;          break;
# Line 3415  for (;;) Line 3953  for (;;)
3953          case OP_WHITESPACE:          case OP_WHITESPACE:
3954          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3955            {            {
3956            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
3957              {              {
3958              SCHECK_PARTIAL();              SCHECK_PARTIAL();
3959              RRETURN(MATCH_NOMATCH);              MRRETURN(MATCH_NOMATCH);
3960              }              }
3961            if (*eptr >= 128 || (md->ctypes[*eptr++] & ctype_space) == 0)            if (*eptr >= 128 || (md->ctypes[*eptr++] & ctype_space) == 0)
3962              RRETURN(MATCH_NOMATCH);              MRRETURN(MATCH_NOMATCH);
3963            /* 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 */
3964            }            }
3965          break;          break;
# Line 3429  for (;;) Line 3967  for (;;)
3967          case OP_NOT_WORDCHAR:          case OP_NOT_WORDCHAR:
3968          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3969            {            {
3970            if (eptr >= md->end_subject ||            if (eptr >= md->end_subject)
3971               (*eptr < 128 && (md->ctypes[*eptr] & ctype_word) != 0))              {
3972              RRETURN(MATCH_NOMATCH);              SCHECK_PARTIAL();
3973                MRRETURN(MATCH_NOMATCH);
3974                }
3975              if (*eptr < 128 && (md->ctypes[*eptr] & ctype_word) != 0)
3976                MRRETURN(MATCH_NOMATCH);
3977            while (++eptr < md->end_subject && (*eptr & 0xc0) == 0x80);            while (++eptr < md->end_subject && (*eptr & 0xc0) == 0x80);
3978            }            }
3979          break;          break;
# Line 3439  for (;;) Line 3981  for (;;)
3981          case OP_WORDCHAR:          case OP_WORDCHAR:
3982          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3983            {            {
3984            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
3985              {              {
3986              SCHECK_PARTIAL();              SCHECK_PARTIAL();
3987              RRETURN(MATCH_NOMATCH);              MRRETURN(MATCH_NOMATCH);
3988              }              }
3989            if (*eptr >= 128 || (md->ctypes[*eptr++] & ctype_word) == 0)            if (*eptr >= 128 || (md->ctypes[*eptr++] & ctype_word) == 0)
3990              RRETURN(MATCH_NOMATCH);              MRRETURN(MATCH_NOMATCH);
3991            /* 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 */
3992            }            }
3993          break;          break;
# Line 3465  for (;;) Line 4007  for (;;)
4007          case OP_ANY:          case OP_ANY:
4008          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
4009            {            {
4010            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4011              {              {
4012              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4013              RRETURN(MATCH_NOMATCH);              MRRETURN(MATCH_NOMATCH);
4014              }              }
4015            if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH);            if (IS_NEWLINE(eptr)) MRRETURN(MATCH_NOMATCH);
4016            eptr++;            eptr++;
4017            }            }
4018          break;          break;
4019    
4020          case OP_ALLANY:          case OP_ALLANY:
4021          if (eptr > md->end_subject - min) RRETURN(MATCH_NOMATCH);          if (eptr > md->end_subject - min)
4022              {
4023              SCHECK_PARTIAL();
4024              MRRETURN(MATCH_NOMATCH);
4025              }
4026          eptr += min;          eptr += min;
4027          break;          break;
4028    
4029          case OP_ANYBYTE:          case OP_ANYBYTE:
4030          if (eptr > md->end_subject - min) RRETURN(MATCH_NOMATCH);          if (eptr > md->end_subject - min)
4031              {
4032              SCHECK_PARTIAL();
4033              MRRETURN(MATCH_NOMATCH);
4034              }
4035          eptr += min;          eptr += min;
4036          break;          break;
4037    
4038          case OP_ANYNL:          case OP_ANYNL:
4039          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
4040            {            {
4041            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4042              {              {
4043              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4044              RRETURN(MATCH_NOMATCH);              MRRETURN(MATCH_NOMATCH);
4045              }              }
4046            switch(*eptr++)            switch(*eptr++)
4047              {              {
4048              default: RRETURN(MATCH_NOMATCH);              default: MRRETURN(MATCH_NOMATCH);
4049              case 0x000d:              case 0x000d:
4050              if (eptr < md->end_subject && *eptr == 0x0a) eptr++;              if (eptr < md->end_subject && *eptr == 0x0a) eptr++;
4051              break;              break;
# Line 3505  for (;;) Line 4055  for (;;)
4055              case 0x000b:              case 0x000b:
4056              case 0x000c:              case 0x000c:
4057              case 0x0085:              case 0x0085:
4058              if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH);              if (md->bsr_anycrlf) MRRETURN(MATCH_NOMATCH);
4059              break;              break;
4060              }              }
4061            }            }
# Line 3514  for (;;) Line 4064  for (;;)
4064          case OP_NOT_HSPACE:          case OP_NOT_HSPACE:
4065          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
4066            {            {
4067            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4068              {              {
4069              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4070              RRETURN(MATCH_NOMATCH);              MRRETURN(MATCH_NOMATCH);
4071              }              }
4072            switch(*eptr++)            switch(*eptr++)
4073              {              {
4074              default: break;              default: break;
4075              case 0x09:      /* HT */              case 0x09:      /* HT */
4076              case 0x20:      /* SPACE */              case 0x20:      /* SPACE */
4077              case 0xa0:      /* NBSP */              case 0xa0:      /* NBSP */
4078              RRETURN(MATCH_NOMATCH);              MRRETURN(MATCH_NOMATCH);
4079              }              }
4080            }            }
4081          break;          break;
# Line 3533  for (;;) Line 4083  for (;;)
4083          case OP_HSPACE:          case OP_HSPACE:
4084          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
4085            {            {
4086            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4087              {              {
4088              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4089              RRETURN(MATCH_NOMATCH);              MRRETURN(MATCH_NOMATCH);
4090              }              }
4091            switch(*eptr++)            switch(*eptr++)
4092              {              {
4093              default: RRETURN(MATCH_NOMATCH);              default: MRRETURN(MATCH_NOMATCH);
4094              case 0x09:      /* HT */              case 0x09:      /* HT */
4095              case 0x20:      /* SPACE */              case 0x20:      /* SPACE */
4096              case 0xa0:      /* NBSP */              case 0xa0:      /* NBSP */
# Line 3552  for (;;) Line 4102  for (;;)
4102          case OP_NOT_VSPACE:          case OP_NOT_VSPACE:
4103          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
4104            {            {
4105            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4106              {              {
4107              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4108              RRETURN(MATCH_NOMATCH);              MRRETURN(MATCH_NOMATCH);
4109              }              }
4110            switch(*eptr++)            switch(*eptr++)
4111              {              {
4112              default: break;              default: break;
# Line 3565  for (;;) Line 4115  for (;;)
4115              case 0x0c:      /* FF */              case 0x0c:      /* FF */
4116              case 0x0d:      /* CR */              case 0x0d:      /* CR */
4117              case 0x85:      /* NEL */              case 0x85:      /* NEL */
4118              RRETURN(MATCH_NOMATCH);              MRRETURN(MATCH_NOMATCH);
4119              }              }
4120            }            }
4121          break;          break;
# Line 3573  for (;;) Line 4123  for (;;)
4123          case OP_VSPACE:          case OP_VSPACE:
4124          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
4125            {            {
4126            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4127              {              {
4128              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4129              RRETURN(MATCH_NOMATCH);              MRRETURN(MATCH_NOMATCH);
4130              }              }
4131            switch(*eptr++)            switch(*eptr++)
4132              {              {
4133              default: RRETURN(MATCH_NOMATCH);              default: MRRETURN(MATCH_NOMATCH);
4134              case 0x0a:      /* LF */              case 0x0a:      /* LF */
4135              case 0x0b:      /* VT */              case 0x0b:      /* VT */
4136              case 0x0c:      /* FF */              case 0x0c:      /* FF */
# Line 3593  for (;;) Line 4143  for (;;)
4143    
4144          case OP_NOT_DIGIT:          case OP_NOT_DIGIT:
4145          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
4146            {            {
4147            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4148              {              {
4149              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4150              RRETURN(MATCH_NOMATCH);              MRRETURN(MATCH_NOMATCH);
4151              }              }
4152            if ((md->ctypes[*eptr++] & ctype_digit) != 0) RRETURN(MATCH_NOMATCH);            if ((md->ctypes[*eptr++] & ctype_digit) != 0) MRRETURN(MATCH_NOMATCH);
4153            }            }
4154          break;          break;
4155    
4156          case OP_DIGIT:          case OP_DIGIT:
4157          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
4158            {            {
4159            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4160              {              {
4161              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4162              RRETURN(MATCH_NOMATCH);              MRRETURN(MATCH_NOMATCH);
4163              }              }
4164            if ((md->ctypes[*eptr++] & ctype_digit) == 0) RRETURN(MATCH_NOMATCH);            if ((md->ctypes[*eptr++] & ctype_digit) == 0) MRRETURN(MATCH_NOMATCH);
4165            }            }
4166          break;          break;
4167    
4168          case OP_NOT_WHITESPACE:          case OP_NOT_WHITESPACE:
4169          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
4170            {            {
4171            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4172              {              {
4173              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4174              RRETURN(MATCH_NOMATCH);              MRRETURN(MATCH_NOMATCH);
4175              }              }
4176            if ((md->ctypes[*eptr++] & ctype_space) != 0) RRETURN(MATCH_NOMATCH);            if ((md->ctypes[*eptr++] & ctype_space) != 0) MRRETURN(MATCH_NOMATCH);
4177            }            }
4178          break;          break;
4179    
4180          case OP_WHITESPACE:          case OP_WHITESPACE:
4181          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
4182            {            {
4183            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4184              {              {
4185              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4186              RRETURN(MATCH_NOMATCH);              MRRETURN(MATCH_NOMATCH);
4187              }              }
4188            if ((md->ctypes[*eptr++] & ctype_space) == 0) RRETURN(MATCH_NOMATCH);            if ((md->ctypes[*eptr++] & ctype_space) == 0) MRRETURN(MATCH_NOMATCH);
4189            }            }
4190          break;          break;
4191    
4192          case OP_NOT_WORDCHAR:          case OP_NOT_WORDCHAR:
4193          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
4194            {            {
4195            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4196              {              {
4197              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4198              RRETURN(MATCH_NOMATCH);              MRRETURN(MATCH_NOMATCH);
4199              }              }
4200            if ((md->ctypes[*eptr++] & ctype_word) != 0)            if ((md->ctypes[*eptr++] & ctype_word) != 0)
4201              RRETURN(MATCH_NOMATCH);              MRRETURN(MATCH_NOMATCH);
4202            }            }
4203          break;          break;
4204    
4205          case OP_WORDCHAR:          case OP_WORDCHAR:
4206          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
4207            {            {
4208            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4209              {              {
4210              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4211              RRETURN(MATCH_NOMATCH);              MRRETURN(MATCH_NOMATCH);
4212              }              }
4213            if ((md->ctypes[*eptr++] & ctype_word) == 0)            if ((md->ctypes[*eptr++] & ctype_word) == 0)
4214              RRETURN(MATCH_NOMATCH);              MRRETURN(MATCH_NOMATCH);
4215            }            }
4216          break;          break;
4217    
4218          default:          default:
# Line 3690  for (;;) Line 4240  for (;;)
4240              {              {
4241              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM36);              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM36);
4242              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
4243              if (fi >= max)              if (fi >= max) MRRETURN(MATCH_NOMATCH);
4244                if (eptr >= md->end_subject)
4245                {                {
4246                CHECK_PARTIAL();                SCHECK_PARTIAL();
4247                RRETURN(MATCH_NOMATCH);                MRRETURN(MATCH_NOMATCH);
4248                }                }
4249              if (eptr >= md->end_subject)              GETCHARINCTEST(c, eptr);
4250                {              if (prop_fail_result) MRRETURN(MATCH_NOMATCH);
               SCHECK_PARTIAL();  
               RRETURN(MATCH_NOMATCH);  
               }  
             GETCHARINC(c, eptr);  
             if (prop_fail_result) RRETURN(MATCH_NOMATCH);  
4251              }              }
4252            /* Control never gets here */            /* Control never gets here */
4253    
# Line 3710  for (;;) Line 4256  for (;;)
4256              {              {
4257              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM37);              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM37);
4258              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
4259              if (fi >= max)              if (fi >= max) MRRETURN(MATCH_NOMATCH);
4260                if (eptr >= md->end_subject)
4261                {                {
4262                CHECK_PARTIAL();                SCHECK_PARTIAL();
4263                RRETURN(MATCH_NOMATCH);                MRRETURN(MATCH_NOMATCH);
4264                }                }
4265              if (eptr >= md->end_subject)              GETCHARINCTEST(c, eptr);
               {  
               SCHECK_PARTIAL();  
               RRETURN(MATCH_NOMATCH);  
               }  
             GETCHARINC(c, eptr);  
4266              prop_chartype = UCD_CHARTYPE(c);              prop_chartype = UCD_CHARTYPE(c);
4267              if ((prop_chartype == ucp_Lu ||              if ((prop_chartype == ucp_Lu ||
4268                   prop_chartype == ucp_Ll ||                   prop_chartype == ucp_Ll ||
4269                   prop_chartype == ucp_Lt) == prop_fail_result)                   prop_chartype == ucp_Lt) == prop_fail_result)
4270                RRETURN(MATCH_NOMATCH);                MRRETURN(MATCH_NOMATCH);
4271              }              }
4272            /* Control never gets here */            /* Control never gets here */
4273    
# Line 3734  for (;;) Line 4276  for (;;)
4276              {              {
4277              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM38);              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM38);
4278              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
4279              if (fi >= max)              if (fi >= max) MRRETURN(MATCH_NOMATCH);
4280                if (eptr >= md->end_subject)
4281                {                {
4282                CHECK_PARTIAL();                SCHECK_PARTIAL();
4283                RRETURN(MATCH_NOMATCH);                MRRETURN(MATCH_NOMATCH);
4284                }                }
4285              if (eptr >= md->end_subject)              GETCHARINCTEST(c, eptr);
               {  
               SCHECK_PARTIAL();  
               RRETURN(MATCH_NOMATCH);  
               }  
             GETCHARINC(c, eptr);  
4286              prop_category = UCD_CATEGORY(c);              prop_category = UCD_CATEGORY(c);
4287              if ((prop_category == prop_value) == prop_fail_result)              if ((prop_category == prop_value) == prop_fail_result)
4288                RRETURN(MATCH_NOMATCH);                MRRETURN(MATCH_NOMATCH);
4289              }              }
4290            /* Control never gets here */            /* Control never gets here */
4291    
# Line 3756  for (;;) Line 4294  for (;;)
4294              {              {
4295              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM39);              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM39);
4296              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
4297              if (fi >= max)              if (fi >= max) MRRETURN(MATCH_NOMATCH);
4298                if (eptr >= md->end_subject)
4299                {                {
4300                CHECK_PARTIAL();                SCHECK_PARTIAL();
4301                RRETURN(MATCH_NOMATCH);                MRRETURN(MATCH_NOMATCH);
4302                }                }
4303              if (eptr >= md->end_subject)              GETCHARINCTEST(c, eptr);
4304                {              prop_chartype = UCD_CHARTYPE(c);
               SCHECK_PARTIAL();  
               RRETURN(MATCH_NOMATCH);  
               }  
             GETCHARINC(c, eptr);  
             prop_chartype = UCD_CHARTYPE(c);  
4305              if ((prop_chartype == prop_value) == prop_fail_result)              if ((prop_chartype == prop_value) == prop_fail_result)
4306                RRETURN(MATCH_NOMATCH);                MRRETURN(MATCH_NOMATCH);
4307              }              }
4308            /* Control never gets here */            /* Control never gets here */
4309    
# Line 3778  for (;;) Line 4312  for (;;)
4312              {              {
4313              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM40);              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM40);
4314              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
4315              if (fi >= max)              if (fi >= max) MRRETURN(MATCH_NOMATCH);
4316                if (eptr >= md->end_subject)
4317                {                {
4318                CHECK_PARTIAL();                SCHECK_PARTIAL();
4319                RRETURN(MATCH_NOMATCH);                MRRETURN(MATCH_NOMATCH);
4320                }                }
4321              if (eptr >= md->end_subject)              GETCHARINCTEST(c, eptr);
               {  
               SCHECK_PARTIAL();  
               RRETURN(MATCH_NOMATCH);  
               }  
             GETCHARINC(c, eptr);  
4322              prop_script = UCD_SCRIPT(c);              prop_script = UCD_SCRIPT(c);
4323              if ((prop_script == prop_value) == prop_fail_result)              if ((prop_script == prop_value) == prop_fail_result)
4324                RRETURN(MATCH_NOMATCH);                MRRETURN(MATCH_NOMATCH);
4325                }
4326              /* Control never gets here */
4327    
4328              case PT_ALNUM:
4329              for (fi = min;; fi++)
4330                {
4331                RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM59);
4332                if (rrc != MATCH_NOMATCH) RRETURN(rrc);
4333                if (fi >= max) MRRETURN(MATCH_NOMATCH);
4334                if (eptr >= md->end_subject)
4335                  {
4336                  SCHECK_PARTIAL();
4337                  MRRETURN(MATCH_NOMATCH);
4338                  }
4339                GETCHARINCTEST(c, eptr);
4340                prop_category = UCD_CATEGORY(c);
4341                if ((prop_category == ucp_L || prop_category == ucp_N)
4342                       == prop_fail_result)
4343                  MRRETURN(MATCH_NOMATCH);
4344              }              }
4345            /* Control never gets here */            /* Control never gets here */
4346    
4347              case PT_SPACE:    /* Perl space */
4348              for (fi = min;; fi++)
4349                {
4350                RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM60);
4351                if (rrc != MATCH_NOMATCH) RRETURN(rrc);
4352                if (fi >= max) MRRETURN(MATCH_NOMATCH);
4353                if (eptr >= md->end_subject)
4354                  {
4355                  SCHECK_PARTIAL();
4356                  MRRETURN(MATCH_NOMATCH);
4357                  }
4358                GETCHARINCTEST(c, eptr);
4359                prop_category = UCD_CATEGORY(c);
4360                if ((prop_category == ucp_Z || c == CHAR_HT || c == CHAR_NL ||
4361                     c == CHAR_FF || c == CHAR_CR)
4362                       == prop_fail_result)
4363                  MRRETURN(MATCH_NOMATCH);
4364                }
4365              /* Control never gets here */
4366    
4367              case PT_PXSPACE:  /* POSIX space */
4368              for (fi = min;; fi++)
4369                {
4370                RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM61);
4371                if (rrc != MATCH_NOMATCH) RRETURN(rrc);
4372                if (fi >= max) MRRETURN(MATCH_NOMATCH);
4373                if (eptr >= md->end_subject)
4374                  {
4375                  SCHECK_PARTIAL();
4376                  MRRETURN(MATCH_NOMATCH);
4377                  }
4378                GETCHARINCTEST(c, eptr);
4379                prop_category = UCD_CATEGORY(c);
4380                if ((prop_category == ucp_Z || c == CHAR_HT || c == CHAR_NL ||
4381                     c == CHAR_VT || c == CHAR_FF || c == CHAR_CR)
4382                       == prop_fail_result)
4383                  MRRETURN(MATCH_NOMATCH);
4384                }
4385              /* Control never gets here */
4386    
4387              case PT_WORD:
4388              for (fi = min;; fi++)
4389                {
4390                RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM62);
4391                if (rrc != MATCH_NOMATCH) RRETURN(rrc);
4392                if (fi >= max) MRRETURN(MATCH_NOMATCH);
4393                if (eptr >= md->end_subject)
4394                  {
4395                  SCHECK_PARTIAL();
4396                  MRRETURN(MATCH_NOMATCH);
4397                  }
4398                GETCHARINCTEST(c, eptr);
4399                prop_category = UCD_CATEGORY(c);
4400                if ((prop_category == ucp_L ||
4401                     prop_category == ucp_N ||
4402                     c == CHAR_UNDERSCORE)
4403                       == prop_fail_result)
4404                  MRRETURN(MATCH_NOMATCH);
4405                }
4406              /* Control never gets here */
4407    
4408              /* This should never occur */
4409    
4410            default:            default:
4411            RRETURN(PCRE_ERROR_INTERNAL);            RRETURN(PCRE_ERROR_INTERNAL);
4412            }            }
# Line 3809  for (;;) Line 4421  for (;;)
4421            {            {
4422            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM41);            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM41);
4423            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
4424            if (fi >= max)            if (fi >= max) MRRETURN(MATCH_NOMATCH);
4425              if (eptr >= md->end_subject)
4426              {              {
4427              CHECK_PARTIAL();              SCHECK_PARTIAL();
4428              RRETURN(MATCH_NOMATCH);              MRRETURN(MATCH_NOMATCH);
4429              }              }
           if (eptr >= md->end_subject)  
             {  
             SCHECK_PARTIAL();  
             RRETURN(MATCH_NOMATCH);  
             }  
4430            GETCHARINCTEST(c, eptr);            GETCHARINCTEST(c, eptr);
4431            prop_category = UCD_CATEGORY(c);            prop_category = UCD_CATEGORY(c);
4432            if (prop_category == ucp_M) RRETURN(MATCH_NOMATCH);            if (prop_category == ucp_M) MRRETURN(MATCH_NOMATCH);
4433            while (eptr < md->end_subject)            while (eptr < md->end_subject)
4434              {              {
4435              int len = 1;              int len = 1;
# Line 3845  for (;;) Line 4453  for (;;)
4453            {            {
4454            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM42);            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM42);
4455            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
4456            if (fi >= max)            if (fi >= max) MRRETURN(MATCH_NOMATCH);
4457              if (eptr >= md->end_subject)
4458              {              {
4459              CHECK_PARTIAL();              SCHECK_PARTIAL();
4460              RRETURN(MATCH_NOMATCH);              MRRETURN(MATCH_NOMATCH);
4461              }              }
           if (eptr >= md->end_subject)  
             {  
             SCHECK_PARTIAL();  
             RRETURN(MATCH_NOMATCH);  
             }  
4462            if (ctype == OP_ANY && IS_NEWLINE(eptr))            if (ctype == OP_ANY && IS_NEWLINE(eptr))
4463              RRETURN(MATCH_NOMATCH);              MRRETURN(MATCH_NOMATCH);
4464            GETCHARINC(c, eptr);            GETCHARINC(c, eptr);
4465            switch(ctype)            switch(ctype)
4466              {              {
# Line 3868  for (;;) Line 4472  for (;;)
4472              case OP_ANYNL:              case OP_ANYNL:
4473              switch(c)              switch(c)
4474                {                {
4475                default: RRETURN(MATCH_NOMATCH);                default: MRRETURN(MATCH_NOMATCH);
4476                case 0x000d:                case 0x000d:
4477                if (eptr < md->end_subject && *eptr == 0x0a) eptr++;                if (eptr < md->end_subject && *eptr == 0x0a) eptr++;
4478                break;                break;
# Line 3880  for (;;) Line 4484  for (;;)
4484                case 0x0085:                case 0x0085:
4485                case 0x2028:                case 0x2028:
4486                case 0x2029:                case 0x2029:
4487                if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH);                if (md->bsr_anycrlf) MRRETURN(MATCH_NOMATCH);
4488                break;                break;
4489                }                }
4490              break;              break;
# Line 3908  for (;;) Line 4512  for (;;)
4512                case 0x202f:    /* NARROW NO-BREAK SPACE */                case 0x202f:    /* NARROW NO-BREAK SPACE */
4513                case 0x205f:    /* MEDIUM MATHEMATICAL SPACE */                case 0x205f:    /* MEDIUM MATHEMATICAL SPACE */
4514                case 0x3000:    /* IDEOGRAPHIC SPACE */                case 0x3000:    /* IDEOGRAPHIC SPACE */
4515                RRETURN(MATCH_NOMATCH);                MRRETURN(MATCH_NOMATCH);
4516                }                }
4517              break;              break;
4518    
4519              case OP_HSPACE:              case OP_HSPACE:
4520              switch(c)              switch(c)
4521                {                {
4522                default: RRETURN(MATCH_NOMATCH);                default: MRRETURN(MATCH_NOMATCH);
4523                case 0x09:      /* HT */                case 0x09:      /* HT */
4524                case 0x20:      /* SPACE */                case 0x20:      /* SPACE */
4525                case 0xa0:      /* NBSP */                case 0xa0:      /* NBSP */
# Line 3950  for (;;) Line 4554  for (;;)
4554                case 0x85:      /* NEL */                case 0x85:      /* NEL */
4555                case 0x2028:    /* LINE SEPARATOR */                case 0x2028:    /* LINE SEPARATOR */
4556                case 0x2029:    /* PARAGRAPH SEPARATOR */                case 0x2029:    /* PARAGRAPH SEPARATOR */
4557                RRETURN(MATCH_NOMATCH);                MRRETURN(MATCH_NOMATCH);
4558                }                }
4559              break;              break;
4560    
4561              case OP_VSPACE:              case OP_VSPACE:
4562              switch(c)              switch(c)
4563                {                {
4564                default: RRETURN(MATCH_NOMATCH);                default: MRRETURN(MATCH_NOMATCH);
4565                case 0x0a:      /* LF */                case 0x0a:      /* LF */
4566                case 0x0b:      /* VT */                case 0x0b:      /* VT */
4567                case 0x0c:      /* FF */                case 0x0c:      /* FF */
# Line 3971  for (;;) Line 4575  for (;;)
4575    
4576              case OP_NOT_DIGIT:              case OP_NOT_DIGIT:
4577              if (c < 256 && (md->ctypes[c] & ctype_digit) != 0)              if (c < 256 && (md->ctypes[c] & ctype_digit) != 0)
4578                RRETURN(MATCH_NOMATCH);                MRRETURN(MATCH_NOMATCH);
4579              break;              break;
4580    
4581              case OP_DIGIT:              case OP_DIGIT:
4582              if (c >= 256 || (md->ctypes[c] & ctype_digit) == 0)              if (c >= 256 || (md->ctypes[c] & ctype_digit) == 0)
4583                RRETURN(MATCH_NOMATCH);                MRRETURN(MATCH_NOMATCH);
4584              break;              break;
4585    
4586              case OP_NOT_WHITESPACE:              case OP_NOT_WHITESPACE:
4587              if (c < 256 && (md->ctypes[c] & ctype_space) != 0)              if (c < 256 && (md->ctypes[c] & ctype_space) != 0)
4588                RRETURN(MATCH_NOMATCH);                MRRETURN(MATCH_NOMATCH);
4589              break;              break;
4590    
4591              case OP_WHITESPACE:              case OP_WHITESPACE:
4592              if  (c >= 256 || (md->ctypes[c] & ctype_space) == 0)              if  (c >= 256 || (md->ctypes[c] & ctype_space) == 0)
4593                RRETURN(MATCH_NOMATCH);                MRRETURN(MATCH_NOMATCH);
4594              break;              break;
4595    
4596              case OP_NOT_WORDCHAR:              case OP_NOT_WORDCHAR:
4597              if (c < 256 && (md->ctypes[c] & ctype_word) != 0)              if (c < 256 && (md->ctypes[c] & ctype_word) != 0)
4598                RRETURN(MATCH_NOMATCH);                MRRETURN(MATCH_NOMATCH);
4599              break;              break;
4600    
4601              case OP_WORDCHAR:              case OP_WORDCHAR:
4602              if (c >= 256 || (md->ctypes[c] & ctype_word) == 0)              if (c >= 256 || (md->ctypes[c] & ctype_word) == 0)
4603                RRETURN(MATCH_NOMATCH);                MRRETURN(MATCH_NOMATCH);
4604              break;              break;
4605    
4606              default:              default:
# Line 4012  for (;;) Line 4616  for (;;)
4616            {            {
4617            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM43);            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM43);
4618            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
4619            if (fi >= max)            if (fi >= max) MRRETURN(MATCH_NOMATCH);
4620              if (eptr >= md->end_subject)
4621              {              {
4622              CHECK_PARTIAL();              SCHECK_PARTIAL();
4623              RRETURN(MATCH_NOMATCH);              MRRETURN(MATCH_NOMATCH);
4624              }              }
           if (eptr >= md->end_subject)  
             {  
             SCHECK_PARTIAL();  
             RRETURN(MATCH_NOMATCH);  
             }  
4625            if (ctype == OP_ANY && IS_NEWLINE(eptr))            if (ctype == OP_ANY && IS_NEWLINE(eptr))
4626              RRETURN(MATCH_NOMATCH);              MRRETURN(MATCH_NOMATCH);
4627            c = *eptr++;            c = *eptr++;
4628            switch(ctype)            switch(ctype)
4629              {              {
# Line 4035  for (;;) Line 4635  for (;;)
4635              case OP_ANYNL:              case OP_ANYNL:
4636              switch(c)              switch(c)
4637                {                {
4638                default: RRETURN(MATCH_NOMATCH);                default: MRRETURN(MATCH_NOMATCH);
4639                case 0x000d:                case 0x000d:
4640                if (eptr < md->end_subject && *eptr == 0x0a) eptr++;                if (eptr < md->end_subject && *eptr == 0x0a) eptr++;
4641                break;                break;
# Line 4046  for (;;) Line 4646  for (;;)
4646                case 0x000b:                case 0x000b:
4647                case 0x000c:                case 0x000c:
4648                case 0x0085:                case 0x0085:
4649                if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH);                if (md->bsr_anycrlf) MRRETURN(MATCH_NOMATCH);
4650                break;                break;
4651                }                }
4652              break;              break;
# Line 4058  for (;;) Line 4658  for (;;)
4658                case 0x09:      /* HT */                case 0x09:      /* HT */
4659                case 0x20:      /* SPACE */                case 0x20:      /* SPACE */
4660                case 0xa0:      /* NBSP */                case 0xa0:      /* NBSP */
4661                RRETURN(MATCH_NOMATCH);                MRRETURN(MATCH_NOMATCH);
4662                }                }
4663              break;              break;
4664    
4665              case OP_HSPACE:              case OP_HSPACE:
4666              switch(c)              switch(c)
4667                {                {
4668                default: RRETURN(MATCH_NOMATCH);                default: MRRETURN(MATCH_NOMATCH);
4669                case 0x09:      /* HT */                case 0x09:      /* HT */
4670                case 0x20:      /* SPACE */                case 0x20:      /* SPACE */
4671                case 0xa0:      /* NBSP */                case 0xa0:      /* NBSP */
# Line 4082  for (;;) Line 4682  for (;;)
4682                case 0x0c:      /* FF */                case 0x0c:      /* FF */
4683                case 0x0d:      /* CR */                case 0x0d:      /* CR */
4684                case 0x85:      /* NEL */                case 0x85:      /* NEL */
4685                RRETURN(MATCH_NOMATCH);                MRRETURN(MATCH_NOMATCH);
4686                }                }
4687              break;              break;
4688    
4689              case OP_VSPACE:              case OP_VSPACE:
4690              switch(c)              switch(c)
4691                {                {
4692                default: RRETURN(MATCH_NOMATCH);                default: MRRETURN(MATCH_NOMATCH);
4693                case 0x0a:      /* LF */                case 0x0a:      /* LF */
4694                case 0x0b:      /* VT */                case 0x0b:      /* VT */
4695                case 0x0c:      /* FF */                case 0x0c:      /* FF */
# Line 4100  for (;;) Line 4700  for (;;)
4700              break;              break;
4701    
4702              case OP_NOT_DIGIT:              case OP_NOT_DIGIT:
4703              if ((md->ctypes[c] & ctype_digit) != 0) RRETURN(MATCH_NOMATCH);              if ((md->ctypes[c] & ctype_digit) != 0) MRRETURN(MATCH_NOMATCH);
4704              break;              break;
4705    
4706              case OP_DIGIT:              case OP_DIGIT:
4707              if ((md->ctypes[c] & ctype_digit) == 0) RRETURN(MATCH_NOMATCH);              if ((md->ctypes[c] & ctype_digit) == 0) MRRETURN(MATCH_NOMATCH);
4708              break;              break;
4709    
4710              case OP_NOT_WHITESPACE:              case OP_NOT_WHITESPACE:
4711              if ((md->ctypes[c] & ctype_space) != 0) RRETURN(MATCH_NOMATCH);              if ((md->ctypes[c] & ctype_space) != 0) MRRETURN(MATCH_NOMATCH);
4712              break;              break;
4713    
4714              case OP_WHITESPACE:              case OP_WHITESPACE:
4715              if  ((md->ctypes[c] & ctype_space) == 0) RRETURN(MATCH_NOMATCH);              if  ((md->ctypes[c] & ctype_space) == 0) MRRETURN(MATCH_NOMATCH);
4716              break;              break;
4717    
4718              case OP_NOT_WORDCHAR:              case OP_NOT_WORDCHAR:
4719              if ((md->ctypes[c] & ctype_word) != 0) RRETURN(MATCH_NOMATCH);              if ((md->ctypes[c] & ctype_word) != 0) MRRETURN(MATCH_NOMATCH);
4720              break;              break;
4721    
4722              case OP_WORDCHAR:              case OP_WORDCHAR:
4723              if ((md->ctypes[c] & ctype_word) == 0) RRETURN(MATCH_NOMATCH);              if ((md->ctypes[c] & ctype_word) == 0) MRRETURN(MATCH_NOMATCH);
4724              break;              break;
4725    
4726              default:              default:
# Line 4148  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              GETCHARLEN(c, eptr, len);                {
4753                  SCHECK_PARTIAL();
4754                  break;
4755                  }
4756                GETCHARLENTEST(c, eptr, len);
4757              if (prop_fail_result) break;              if (prop_fail_result) break;
4758              eptr+= len;              eptr+= len;
4759              }              }
# Line 4159  for (;;) Line 4763  for (;;)
4763            for (i = min; i < max; i++)            for (i = min; i < max; i++)
4764              {              {
4765              int len = 1;              int len = 1;
4766              if (eptr >= md->end_subject) break;              if (eptr >= md->end_subject)
4767              GETCHARLEN(c, eptr, len);                {
4768                  SCHECK_PARTIAL();
4769                  break;
4770                  }
4771                GETCHARLENTEST(c, eptr, len);
4772              prop_chartype = UCD_CHARTYPE(c);              prop_chartype = UCD_CHARTYPE(c);
4773              if ((prop_chartype == ucp_Lu ||              if ((prop_chartype == ucp_Lu ||
4774                   prop_chartype == ucp_Ll ||                   prop_chartype == ucp_Ll ||
# Line 4174  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              GETCHARLEN(c, eptr, len);                {
4787                  SCHECK_PARTIAL();
4788                  break;
4789                  }
4790                GETCHARLENTEST(c, eptr, len);
4791              prop_category = UCD_CATEGORY(c);              prop_category = UCD_CATEGORY(c);
4792              if ((prop_category == prop_value) == prop_fail_result)              if ((prop_category == prop_value) == prop_fail_result)
4793                break;                break;
# Line 4187  for (;;) Line 4799  for (;;)
4799            for (i = min; i < max; i++)            for (i = min; i < max; i++)
4800              {              {
4801              int len = 1;              int len = 1;
4802              if (eptr >= md->end_subject) break;              if (eptr >= md->end_subject)
4803              GETCHARLEN(c, eptr, len);                {
4804                  SCHECK_PARTIAL();
4805                  break;
4806                  }
4807                GETCHARLENTEST(c, eptr, len);
4808              prop_chartype = UCD_CHARTYPE(c);              prop_chartype = UCD_CHARTYPE(c);
4809              if ((prop_chartype == prop_value) == prop_fail_result)              if ((prop_chartype == prop_value) == prop_fail_result)
4810                break;                break;
# Line 4200  for (;;) Line 4816  for (;;)
4816            for (i = min; i < max; i++)            for (i = min; i < max; i++)
4817              {              {
4818              int len = 1;              int len = 1;
4819              if (eptr >= md->end_subject) break;              if (eptr >= md->end_subject)
4820              GETCHARLEN(c, eptr, len);                {
4821                  SCHECK_PARTIAL();
4822                  break;
4823                  }
4824                GETCHARLENTEST(c, eptr, len);
4825              prop_script = UCD_SCRIPT(c);              prop_script = UCD_SCRIPT(c);
4826              if ((prop_script == prop_value) == prop_fail_result)              if ((prop_script == prop_value) == prop_fail_result)
4827                break;                break;
4828              eptr+= len;              eptr+= len;
4829              }              }
4830            break;            break;
4831    
4832              case PT_ALNUM:
4833              for (i = min; i < max; i++)
4834                {
4835                int len = 1;
4836                if (eptr >= md->end_subject)
4837                  {
4838                  SCHECK_PARTIAL();
4839                  break;
4840                  }
4841                GETCHARLENTEST(c, eptr, len);
4842                prop_category = UCD_CATEGORY(c);
4843                if ((prop_category == ucp_L || prop_category == ucp_N)
4844                     == prop_fail_result)
4845                  break;
4846                eptr+= len;
4847                }
4848              break;
4849    
4850              case PT_SPACE:    /* Perl space */
4851              for (i = min; i < max; i++)
4852                {
4853                int len = 1;
4854                if (eptr >= md->end_subject)
4855                  {
4856                  SCHECK_PARTIAL();
4857                  break;
4858                  }
4859                GETCHARLENTEST(c, eptr, len);
4860                prop_category = UCD_CATEGORY(c);
4861                if ((prop_category == ucp_Z || c == CHAR_HT || c == CHAR_NL ||
4862                     c == CHAR_FF || c == CHAR_CR)
4863                     == prop_fail_result)
4864                  break;
4865                eptr+= len;
4866                }
4867              break;
4868    
4869              case PT_PXSPACE:  /* POSIX space */
4870              for (i = min; i < max; i++)
4871                {
4872                int len = 1;
4873                if (eptr >= md->end_subject)
4874                  {
4875                  SCHECK_PARTIAL();
4876                  break;
4877                  }
4878                GETCHARLENTEST(c, eptr, len);
4879                prop_category = UCD_CATEGORY(c);
4880                if ((prop_category == ucp_Z || c == CHAR_HT || c == CHAR_NL ||
4881                     c == CHAR_VT || c == CHAR_FF || c == CHAR_CR)
4882                     == prop_fail_result)
4883                  break;
4884                eptr+= len;
4885                }
4886              break;
4887    
4888              case PT_WORD:
4889              for (i = min; i < max; i++)
4890                {
4891                int len = 1;
4892                if (eptr >= md->end_subject)
4893                  {
4894                  SCHECK_PARTIAL();
4895                  break;
4896                  }
4897                GETCHARLENTEST(c, eptr, len);
4898                prop_category = UCD_CATEGORY(c);
4899                if ((prop_category == ucp_L || prop_category == ucp_N ||
4900                     c == CHAR_UNDERSCORE) == prop_fail_result)
4901                  break;
4902                eptr+= len;
4903                }
4904              break;
4905    
4906              default:
4907              RRETURN(PCRE_ERROR_INTERNAL);
4908            }            }
4909    
4910          /* eptr is now past the end of the maximum run */          /* eptr is now past the end of the maximum run */
4911    
         CHECK_PARTIAL();  
4912          if (possessive) continue;          if (possessive) continue;
4913          for(;;)          for(;;)
4914            {            {
# Line 4230  for (;;) Line 4926  for (;;)
4926          {          {
4927          for (i = min; i < max; i++)          for (i = min; i < max; i++)
4928            {            {
4929            if (eptr >= md->end_subject) break;            if (eptr >= md->end_subject)
4930                {
4931                SCHECK_PARTIAL();
4932                break;
4933                }
4934            GETCHARINCTEST(c, eptr);            GETCHARINCTEST(c, eptr);
4935            prop_category = UCD_CATEGORY(c);            prop_category = UCD_CATEGORY(c);
4936            if (prop_category == ucp_M) break;            if (prop_category == ucp_M) break;
# Line 4249  for (;;) Line 4949  for (;;)
4949    
4950          /* eptr is now past the end of the maximum run */          /* eptr is now past the end of the maximum run */
4951    
         CHECK_PARTIAL();  
4952          if (possessive) continue;          if (possessive) continue;
4953    
4954          for(;;)          for(;;)
4955            {            {
4956            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM45);            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM45);
# Line 4286  for (;;) Line 4986  for (;;)
4986              {              {
4987              for (i = min; i < max; i++)              for (i = min; i < max; i++)
4988                {                {
4989                if (eptr >= md->end_subject || IS_NEWLINE(eptr)) break;                if (eptr >= md->end_subject)
4990                    {
4991                    SCHECK_PARTIAL();
4992                    break;
4993                    }
4994                  if (IS_NEWLINE(eptr)) break;
4995                eptr++;                eptr++;
4996                while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;                while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;
4997                }                }
# Line 4298  for (;;) Line 5003  for (;;)
5003              {              {
5004              for (i = min; i < max; i++)              for (i = min; i < max; i++)
5005                {                {
5006                if (eptr >= md->end_subject || IS_NEWLINE(eptr)) break;                if (eptr >= md->end_subject)
5007                    {
5008                    SCHECK_PARTIAL();
5009                    break;
5010                    }
5011                  if (IS_NEWLINE(eptr)) break;
5012                eptr++;                eptr++;
5013                while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;                while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;
5014                }                }
# Line 4310  for (;;) Line 5020  for (;;)
5020              {              {
5021              for (i = min; i < max; i++)              for (i = min; i < max; i++)
5022                {                {
5023                if (eptr >= md->end_subject) break;                if (eptr >= md->end_subject)
5024                    {
5025                    SCHECK_PARTIAL();
5026                    break;
5027                    }
5028                eptr++;                eptr++;
5029                while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;                while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;
5030                }                }
# Line 4323  for (;;) Line 5037  for (;;)
5037            case OP_ANYBYTE:            case OP_ANYBYTE:
5038            c = max - min;            c = max - min;
5039            if (c > (unsigned int)(md->end_subject - eptr))            if (c > (unsigned int)(md->end_subject - eptr))
5040              c = md->end_subject - eptr;              {
5041            eptr += c;              eptr = md->end_subject;
5042                SCHECK_PARTIAL();
5043                }
5044              else eptr += c;
5045            break;            break;
5046    
5047            case OP_ANYNL:            case OP_ANYNL:
5048            for (i = min; i < max; i++)            for (i = min; i < max; i++)
5049              {              {
5050              int len = 1;              int len = 1;
5051              if (eptr >= md->end_subject) break;              if (eptr >= md->end_subject)
5052                  {
5053                  SCHECK_PARTIAL();
5054                  break;
5055                  }
5056              GETCHARLEN(c, eptr, len);              GETCHARLEN(c, eptr, len);
5057              if (c == 0x000d)              if (c == 0x000d)
5058                {                {
# Line 4356  for (;;) Line 5077  for (;;)
5077              {              {
5078              BOOL gotspace;              BOOL gotspace;
5079              int len = 1;              int len = 1;
5080              if (eptr >= md->end_subject) break;              if (eptr >= md->end_subject)
5081                  {
5082                  SCHECK_PARTIAL();
5083                  break;
5084                  }
5085              GETCHARLEN(c, eptr, len);              GETCHARLEN(c, eptr, len);
5086              switch(c)              switch(c)
5087                {                {
# Line 4394  for (;;) Line 5119  for (;;)
5119              {              {
5120              BOOL gotspace;              BOOL gotspace;
5121              int len = 1;              int len = 1;
5122              if (eptr >= md->end_subject) break;              if (eptr >= md->end_subject)
5123                  {
5124                  SCHECK_PARTIAL();
5125                  break;
5126                  }
5127              GETCHARLEN(c, eptr, len);              GETCHARLEN(c, eptr, len);
5128              switch(c)              switch(c)
5129                {                {
# Line 4418  for (;;) Line 5147  for (;;)
5147            for (i = min; i < max; i++)            for (i = min; i < max; i++)
5148              {              {
5149              int len = 1;              int len = 1;
5150              if (eptr >= md->end_subject) break;              if (eptr >= md->end_subject)
5151                  {
5152                  SCHECK_PARTIAL();
5153                  break;
5154                  }
5155              GETCHARLEN(c, eptr, len);              GETCHARLEN(c, eptr, len);
5156              if (c < 256 && (md->ctypes[c] & ctype_digit) != 0) break;              if (c < 256 && (md->ctypes[c] & ctype_digit) != 0) break;
5157              eptr+= len;              eptr+= len;
# Line 4429  for (;;) Line 5162  for (;;)
5162            for (i = min; i < max; i++)            for (i = min; i < max; i++)
5163              {              {
5164              int len = 1;              int len = 1;
5165              if (eptr >= md->end_subject) break;              if (eptr >= md->end_subject)
5166                  {
5167                  SCHECK_PARTIAL();
5168                  break;
5169                  }
5170              GETCHARLEN(c, eptr, len);              GETCHARLEN(c, eptr, len);
5171              if (c >= 256 ||(md->ctypes[c] & ctype_digit) == 0) break;              if (c >= 256 ||(md->ctypes[c] & ctype_digit) == 0) break;
5172              eptr+= len;              eptr+= len;
# Line 4440  for (;;) Line 5177  for (;;)
5177            for (i = min; i < max; i++)            for (i = min; i < max; i++)
5178              {              {
5179              int len = 1;              int len = 1;
5180              if (eptr >= md->end_subject) break;              if (eptr >= md->end_subject)
5181                  {
5182                  SCHECK_PARTIAL();
5183                  break;
5184                  }
5185              GETCHARLEN(c, eptr, len);              GETCHARLEN(c, eptr, len);
5186              if (c < 256 && (md->ctypes[c] & ctype_space) != 0) break;              if (c < 256 && (md->ctypes[c] & ctype_space) != 0) break;
5187              eptr+= len;              eptr+= len;
# Line 4451  for (;;) Line 5192  for (;;)
5192            for (i = min; i < max; i++)            for (i = min; i < max; i++)
5193              {              {
5194              int len = 1;              int len = 1;
5195              if (eptr >= md->end_subject) break;              if (eptr >= md->end_subject)
5196                  {
5197                  SCHECK_PARTIAL();
5198                  break;
5199                  }
5200              GETCHARLEN(c, eptr, len);              GETCHARLEN(c, eptr, len);
5201              if (c >= 256 ||(md->ctypes[c] & ctype_space) == 0) break;              if (c >= 256 ||(md->ctypes[c] & ctype_space) == 0) break;
5202              eptr+= len;              eptr+= len;
# Line 4462  for (;;) Line 5207  for (;;)
5207            for (i = min; i < max; i++)            for (i = min; i < max; i++)
5208              {              {
5209              int len = 1;              int len = 1;
5210              if (eptr >= md->end_subject) break;              if (eptr >= md->end_subject)
5211                  {
5212                  SCHECK_PARTIAL();
5213                  break;
5214                  }
5215              GETCHARLEN(c, eptr, len);              GETCHARLEN(c, eptr, len);
5216              if (c < 256 && (md->ctypes[c] & ctype_word) != 0) break;              if (c < 256 && (md->ctypes[c] & ctype_word) != 0) break;
5217              eptr+= len;              eptr+= len;
# Line 4473  for (;;) Line 5222  for (;;)
5222            for (i = min; i < max; i++)            for (i = min; i < max; i++)
5223              {              {
5224              int len = 1;              int len = 1;
5225              if (eptr >= md->end_subject) break;              if (eptr >= md->end_subject)
5226                  {
5227                  SCHECK_PARTIAL();
5228                  break;
5229                  }
5230              GETCHARLEN(c, eptr, len);              GETCHARLEN(c, eptr, len);
5231              if (c >= 256 || (md->ctypes[c] & ctype_word) == 0) break;              if (c >= 256 || (md->ctypes[c] & ctype_word) == 0) break;
5232              eptr+= len;              eptr+= len;
# Line 4486  for (;;) Line 5239  for (;;)
5239    
5240          /* eptr is now past the end of the maximum run */          /* eptr is now past the end of the maximum run */
5241    
         CHECK_PARTIAL();  
5242          if (possessive) continue;          if (possessive) continue;
5243          for(;;)          for(;;)
5244            {            {
# Line 4506  for (;;) Line 5258  for (;;)
5258            case OP_ANY:            case OP_ANY:
5259            for (i = min; i < max; i++)            for (i = min; i < max; i++)
5260              {              {
5261              if (eptr >= md->end_subject || IS_NEWLINE(eptr)) break;              if (eptr >= md->end_subject)
5262                  {
5263                  SCHECK_PARTIAL();
5264                  break;
5265                  }
5266                if (IS_NEWLINE(eptr)) break;
5267              eptr++;              eptr++;
5268              }              }
5269            break;            break;
# Line 4515  for (;;) Line 5272  for (;;)
5272            case OP_ANYBYTE:            case OP_ANYBYTE:
5273            c = max - min;            c = max - min;
5274            if (c > (unsigned int)(md->end_subject - eptr))            if (c > (unsigned int)(md->end_subject - eptr))
5275              c = md->end_subject - eptr;              {
5276            eptr += c;              eptr = md->end_subject;
5277                SCHECK_PARTIAL();
5278                }
5279              else eptr += c;
5280            break;            break;
5281    
5282            case OP_ANYNL:            case OP_ANYNL:
5283            for (i = min; i < max; i++)            for (i = min; i < max; i++)
5284              {              {
5285              if (eptr >= md->end_subject) break;              if (eptr >= md->end_subject)
5286                  {
5287                  SCHECK_PARTIAL();
5288                  break;
5289                  }
5290              c = *eptr;              c = *eptr;
5291              if (c == 0x000d)              if (c == 0x000d)
5292                {                {
# Line 4543