/[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 723 by ph10, Sat Oct 8 15:55:23 2011 UTC revision 1015 by ph10, Sun Aug 26 16:07:14 2012 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-2011 University of Cambridge             Copyright (c) 1997-2012 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 37  POSSIBILITY OF SUCH DAMAGE. Line 37  POSSIBILITY OF SUCH DAMAGE.
37  -----------------------------------------------------------------------------  -----------------------------------------------------------------------------
38  */  */
39    
   
40  /* This module contains pcre_exec(), the externally visible function that does  /* This module contains pcre_exec(), the externally visible function that does
41  pattern matching using an NFA algorithm, trying to mimic Perl as closely as  pattern matching using an NFA algorithm, trying to mimic Perl as closely as
42  possible. There are also some static supporting functions. */  possible. There are also some static supporting functions. */
# Line 82  negative to avoid the external error cod Line 81  negative to avoid the external error cod
81  #define MATCH_SKIP_ARG     (-993)  #define MATCH_SKIP_ARG     (-993)
82  #define MATCH_THEN         (-992)  #define MATCH_THEN         (-992)
83    
 /* This is a convenience macro for code that occurs many times. */  
   
 #define MRRETURN(ra) \  
   { \  
   md->mark = markptr; \  
   RRETURN(ra); \  
   }  
   
84  /* 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.
85  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,
86  because the offset vector is always a multiple of 3 long. */  because the offset vector is always a multiple of 3 long. */
# Line 121  Returns:     nothing Line 112  Returns:     nothing
112  */  */
113    
114  static void  static void
115  pchars(const uschar *p, int length, BOOL is_subject, match_data *md)  pchars(const pcre_uchar *p, int length, BOOL is_subject, match_data *md)
116  {  {
117  unsigned int c;  unsigned int c;
118  if (is_subject && length > md->end_subject - p) length = md->end_subject - p;  if (is_subject && length > md->end_subject - p) length = md->end_subject - p;
# Line 148  Arguments: Line 139  Arguments:
139    md          points to match data block    md          points to match data block
140    caseless    TRUE if caseless    caseless    TRUE if caseless
141    
142  Returns:      < 0 if not matched, otherwise the number of subject bytes matched  Returns:      >= 0 the number of subject bytes matched
143                  -1 no match
144                  -2 partial match; always given if at end subject
145  */  */
146    
147  static int  static int
148  match_ref(int offset, register USPTR eptr, int length, match_data *md,  match_ref(int offset, register PCRE_PUCHAR eptr, int length, match_data *md,
149    BOOL caseless)    BOOL caseless)
150  {  {
151  USPTR eptr_start = eptr;  PCRE_PUCHAR eptr_start = eptr;
152  register USPTR p = md->start_subject + md->offset_vector[offset];  register PCRE_PUCHAR p = md->start_subject + md->offset_vector[offset];
153    
154  #ifdef PCRE_DEBUG  #ifdef PCRE_DEBUG
155  if (eptr >= md->end_subject)  if (eptr >= md->end_subject)
# Line 171  pchars(p, length, FALSE, md); Line 164  pchars(p, length, FALSE, md);
164  printf("\n");  printf("\n");
165  #endif  #endif
166    
167  /* Always fail if reference not set (and not JavaScript compatible). */  /* Always fail if reference not set (and not JavaScript compatible - in that
168    case the length is passed as zero). */
169    
170  if (length < 0) return -1;  if (length < 0) return -1;
171    
# Line 181  ASCII characters. */ Line 175  ASCII characters. */
175    
176  if (caseless)  if (caseless)
177    {    {
178  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
179  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
180    if (md->utf8)    if (md->utf)
181      {      {
182      /* Match characters up to the end of the reference. NOTE: the number of      /* Match characters up to the end of the reference. NOTE: the number of
183      bytes matched may differ, because there are some characters whose upper and      bytes matched may differ, because there are some characters whose upper and
# Line 193  if (caseless) Line 187  if (caseless)
187      the latter. It is important, therefore, to check the length along the      the latter. It is important, therefore, to check the length along the
188      reference, not along the subject (earlier code did this wrong). */      reference, not along the subject (earlier code did this wrong). */
189    
190      USPTR endptr = p + length;      PCRE_PUCHAR endptr = p + length;
191      while (p < endptr)      while (p < endptr)
192        {        {
193        int c, d;        int c, d;
194        if (eptr >= md->end_subject) return -1;        if (eptr >= md->end_subject) return -2;   /* Partial match */
195        GETCHARINC(c, eptr);        GETCHARINC(c, eptr);
196        GETCHARINC(d, p);        GETCHARINC(d, p);
197        if (c != d && c != UCD_OTHERCASE(d)) return -1;        if (c != d && c != UCD_OTHERCASE(d)) return -1;
# Line 210  if (caseless) Line 204  if (caseless)
204    /* The same code works when not in UTF-8 mode and in UTF-8 mode when there    /* The same code works when not in UTF-8 mode and in UTF-8 mode when there
205    is no UCP support. */    is no UCP support. */
206      {      {
     if (eptr + length > md->end_subject) return -1;  
207      while (length-- > 0)      while (length-- > 0)
208        { if (md->lcc[*p++] != md->lcc[*eptr++]) return -1; }        {
209          if (eptr >= md->end_subject) return -2;   /* Partial match */
210          if (TABLE_GET(*p, md->lcc, *p) != TABLE_GET(*eptr, md->lcc, *eptr)) return -1;
211          p++;
212          eptr++;
213          }
214      }      }
215    }    }
216    
# Line 221  are in UTF-8 mode. */ Line 219  are in UTF-8 mode. */
219    
220  else  else
221    {    {
222    if (eptr + length > md->end_subject) return -1;    while (length-- > 0)
223    while (length-- > 0) if (*p++ != *eptr++) return -1;      {
224        if (eptr >= md->end_subject) return -2;   /* Partial match */
225        if (*p++ != *eptr++) return -1;
226        }
227    }    }
228    
229  return eptr - eptr_start;  return (int)(eptr - eptr_start);
230  }  }
231    
232    
# Line 290  actually used in this definition. */ Line 291  actually used in this definition. */
291  #define RMATCH(ra,rb,rc,rd,re,rw) \  #define RMATCH(ra,rb,rc,rd,re,rw) \
292    { \    { \
293    printf("match() called in line %d\n", __LINE__); \    printf("match() called in line %d\n", __LINE__); \
294    rrc = match(ra,rb,mstart,markptr,rc,rd,re,rdepth+1); \    rrc = match(ra,rb,mstart,rc,rd,re,rdepth+1); \
295    printf("to line %d\n", __LINE__); \    printf("to line %d\n", __LINE__); \
296    }    }
297  #define RRETURN(ra) \  #define RRETURN(ra) \
# Line 300  actually used in this definition. */ Line 301  actually used in this definition. */
301    }    }
302  #else  #else
303  #define RMATCH(ra,rb,rc,rd,re,rw) \  #define RMATCH(ra,rb,rc,rd,re,rw) \
304    rrc = match(ra,rb,mstart,markptr,rc,rd,re,rdepth+1)    rrc = match(ra,rb,mstart,rc,rd,re,rdepth+1)
305  #define RRETURN(ra) return ra  #define RRETURN(ra) return ra
306  #endif  #endif
307    
# Line 315  argument of match(), which never changes Line 316  argument of match(), which never changes
316    
317  #define RMATCH(ra,rb,rc,rd,re,rw)\  #define RMATCH(ra,rb,rc,rd,re,rw)\
318    {\    {\
319    heapframe *newframe = (heapframe *)(pcre_stack_malloc)(sizeof(heapframe));\    heapframe *newframe = frame->Xnextframe;\
320    if (newframe == NULL) RRETURN(PCRE_ERROR_NOMEMORY);\    if (newframe == NULL)\
321    frame->Xwhere = rw; \      {\
322        newframe = (heapframe *)(PUBL(stack_malloc))(sizeof(heapframe));\
323        if (newframe == NULL) RRETURN(PCRE_ERROR_NOMEMORY);\
324        newframe->Xnextframe = NULL;\
325        frame->Xnextframe = newframe;\
326        }\
327      frame->Xwhere = rw;\
328    newframe->Xeptr = ra;\    newframe->Xeptr = ra;\
329    newframe->Xecode = rb;\    newframe->Xecode = rb;\
330    newframe->Xmstart = mstart;\    newframe->Xmstart = mstart;\
   newframe->Xmarkptr = markptr;\  
331    newframe->Xoffset_top = rc;\    newframe->Xoffset_top = rc;\
332    newframe->Xeptrb = re;\    newframe->Xeptrb = re;\
333    newframe->Xrdepth = frame->Xrdepth + 1;\    newframe->Xrdepth = frame->Xrdepth + 1;\
# Line 337  argument of match(), which never changes Line 343  argument of match(), which never changes
343    {\    {\
344    heapframe *oldframe = frame;\    heapframe *oldframe = frame;\
345    frame = oldframe->Xprevframe;\    frame = oldframe->Xprevframe;\
   (pcre_stack_free)(oldframe);\  
346    if (frame != NULL)\    if (frame != NULL)\
347      {\      {\
348      rrc = ra;\      rrc = ra;\
# Line 351  argument of match(), which never changes Line 356  argument of match(), which never changes
356    
357  typedef struct heapframe {  typedef struct heapframe {
358    struct heapframe *Xprevframe;    struct heapframe *Xprevframe;
359      struct heapframe *Xnextframe;
360    
361    /* Function arguments that may change */    /* Function arguments that may change */
362    
363    USPTR Xeptr;    PCRE_PUCHAR Xeptr;
364    const uschar *Xecode;    const pcre_uchar *Xecode;
365    USPTR Xmstart;    PCRE_PUCHAR Xmstart;
   USPTR Xmarkptr;  
366    int Xoffset_top;    int Xoffset_top;
367    eptrblock *Xeptrb;    eptrblock *Xeptrb;
368    unsigned int Xrdepth;    unsigned int Xrdepth;
369    
370    /* Function local variables */    /* Function local variables */
371    
372    USPTR Xcallpat;    PCRE_PUCHAR Xcallpat;
373  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
374    USPTR Xcharptr;    PCRE_PUCHAR Xcharptr;
375  #endif  #endif
376    USPTR Xdata;    PCRE_PUCHAR Xdata;
377    USPTR Xnext;    PCRE_PUCHAR Xnext;
378    USPTR Xpp;    PCRE_PUCHAR Xpp;
379    USPTR Xprev;    PCRE_PUCHAR Xprev;
380    USPTR Xsaved_eptr;    PCRE_PUCHAR Xsaved_eptr;
381    
382    recursion_info Xnew_recursive;    recursion_info Xnew_recursive;
383    
# Line 385  typedef struct heapframe { Line 390  typedef struct heapframe {
390    int Xprop_value;    int Xprop_value;
391    int Xprop_fail_result;    int Xprop_fail_result;
392    int Xoclength;    int Xoclength;
393    uschar Xocchars[8];    pcre_uchar Xocchars[6];
394  #endif  #endif
395    
396    int Xcodelink;    int Xcodelink;
# Line 427  returns a negative (error) response, the Line 432  returns a negative (error) response, the
432  same response. */  same response. */
433    
434  /* 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
435  appears several times in the code. We set the "hit end" flag if the pointer is  appear several times in the code. We set the "hit end" flag if the pointer is
436  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.
437  something has been matched). For hard partial matching, we then return  something has been matched). For hard partial matching, we then return
438  immediately. The second one is used when we already know we are past the end of  immediately. The second one is used when we already know we are past the end of
# Line 438  the subject. */ Line 443  the subject. */
443        eptr > md->start_used_ptr) \        eptr > md->start_used_ptr) \
444      { \      { \
445      md->hitend = TRUE; \      md->hitend = TRUE; \
446      if (md->partial > 1) MRRETURN(PCRE_ERROR_PARTIAL); \      if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL); \
447      }      }
448    
449  #define SCHECK_PARTIAL()\  #define SCHECK_PARTIAL()\
450    if (md->partial != 0 && eptr > md->start_used_ptr) \    if (md->partial != 0 && eptr > md->start_used_ptr) \
451      { \      { \
452      md->hitend = TRUE; \      md->hitend = TRUE; \
453      if (md->partial > 1) MRRETURN(PCRE_ERROR_PARTIAL); \      if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL); \
454      }      }
455    
456    
457  /* Performance note: It might be tempting to extract commonly used fields from  /* Performance note: It might be tempting to extract commonly used fields from
458  the md structure (e.g. utf8, end_subject) into individual variables to improve  the md structure (e.g. utf, end_subject) into individual variables to improve
459  performance. Tests using gcc on a SPARC disproved this; in the first case, it  performance. Tests using gcc on a SPARC disproved this; in the first case, it
460  made performance worse.  made performance worse.
461    
# Line 459  Arguments: Line 464  Arguments:
464     ecode       pointer to current position in compiled code     ecode       pointer to current position in compiled code
465     mstart      pointer to the current match start position (can be modified     mstart      pointer to the current match start position (can be modified
466                   by encountering \K)                   by encountering \K)
    markptr     pointer to the most recent MARK name, or NULL  
467     offset_top  current top pointer     offset_top  current top pointer
468     md          pointer to "static" info for the match     md          pointer to "static" info for the match
469     eptrb       pointer to chain of blocks containing eptr at start of     eptrb       pointer to chain of blocks containing eptr at start of
# Line 474  Returns:       MATCH_MATCH if matched Line 478  Returns:       MATCH_MATCH if matched
478  */  */
479    
480  static int  static int
481  match(REGISTER USPTR eptr, REGISTER const uschar *ecode, USPTR mstart,  match(REGISTER PCRE_PUCHAR eptr, REGISTER const pcre_uchar *ecode,
482    const uschar *markptr, int offset_top, match_data *md, eptrblock *eptrb,    PCRE_PUCHAR mstart, int offset_top, match_data *md, eptrblock *eptrb,
483    unsigned int rdepth)    unsigned int rdepth)
484  {  {
485  /* 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,
# Line 485  so they can be ordinary variables in all Line 489  so they can be ordinary variables in all
489  register int  rrc;         /* Returns from recursive calls */  register int  rrc;         /* Returns from recursive calls */
490  register int  i;           /* Used for loops not involving calls to RMATCH() */  register int  i;           /* Used for loops not involving calls to RMATCH() */
491  register unsigned int c;   /* Character values not kept over RMATCH() calls */  register unsigned int c;   /* Character values not kept over RMATCH() calls */
492  register BOOL utf8;        /* Local copy of UTF-8 flag for speed */  register BOOL utf;         /* Local copy of UTF flag for speed */
493    
494  BOOL minimize, possessive; /* Quantifier options */  BOOL minimize, possessive; /* Quantifier options */
495  BOOL caseless;  BOOL caseless;
496  int condcode;  int condcode;
497    
498  /* When recursion is not being used, all "local" variables that have to be  /* When recursion is not being used, all "local" variables that have to be
499  preserved over calls to RMATCH() are part of a "frame" which is obtained from  preserved over calls to RMATCH() are part of a "frame". We set up the top-level
500  heap storage. Set up the top-level frame here; others are obtained from the  frame on the stack here; subsequent instantiations are obtained from the heap
501  heap whenever RMATCH() does a "recursion". See the macro definitions above. */  whenever RMATCH() does a "recursion". See the macro definitions above. Putting
502    the top-level on the stack rather than malloc-ing them all gives a performance
503    boost in many cases where there is not much "recursion". */
504    
505  #ifdef NO_RECURSE  #ifdef NO_RECURSE
506  heapframe *frame = (heapframe *)(pcre_stack_malloc)(sizeof(heapframe));  heapframe *frame = (heapframe *)md->match_frames_base;
 if (frame == NULL) RRETURN(PCRE_ERROR_NOMEMORY);  
 frame->Xprevframe = NULL;            /* Marks the top level */  
507    
508  /* Copy in the original argument variables */  /* Copy in the original argument variables */
509    
510  frame->Xeptr = eptr;  frame->Xeptr = eptr;
511  frame->Xecode = ecode;  frame->Xecode = ecode;
512  frame->Xmstart = mstart;  frame->Xmstart = mstart;
 frame->Xmarkptr = markptr;  
513  frame->Xoffset_top = offset_top;  frame->Xoffset_top = offset_top;
514  frame->Xeptrb = eptrb;  frame->Xeptrb = eptrb;
515  frame->Xrdepth = rdepth;  frame->Xrdepth = rdepth;
# Line 520  HEAP_RECURSE: Line 523  HEAP_RECURSE:
523  #define eptr               frame->Xeptr  #define eptr               frame->Xeptr
524  #define ecode              frame->Xecode  #define ecode              frame->Xecode
525  #define mstart             frame->Xmstart  #define mstart             frame->Xmstart
 #define markptr            frame->Xmarkptr  
526  #define offset_top         frame->Xoffset_top  #define offset_top         frame->Xoffset_top
527  #define eptrb              frame->Xeptrb  #define eptrb              frame->Xeptrb
528  #define rdepth             frame->Xrdepth  #define rdepth             frame->Xrdepth
529    
530  /* Ditto for the local variables */  /* Ditto for the local variables */
531    
532  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
533  #define charptr            frame->Xcharptr  #define charptr            frame->Xcharptr
534  #endif  #endif
535  #define callpat            frame->Xcallpat  #define callpat            frame->Xcallpat
# Line 585  declarations can be cut out in a block. Line 587  declarations can be cut out in a block.
587  below are for variables that do not have to be preserved over a recursive call  below are for variables that do not have to be preserved over a recursive call
588  to RMATCH(). */  to RMATCH(). */
589    
590  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
591  const uschar *charptr;  const pcre_uchar *charptr;
592  #endif  #endif
593  const uschar *callpat;  const pcre_uchar *callpat;
594  const uschar *data;  const pcre_uchar *data;
595  const uschar *next;  const pcre_uchar *next;
596  USPTR         pp;  PCRE_PUCHAR       pp;
597  const uschar *prev;  const pcre_uchar *prev;
598  USPTR         saved_eptr;  PCRE_PUCHAR       saved_eptr;
599    
600  recursion_info new_recursive;  recursion_info new_recursive;
601    
# Line 606  int prop_type; Line 608  int prop_type;
608  int prop_value;  int prop_value;
609  int prop_fail_result;  int prop_fail_result;
610  int oclength;  int oclength;
611  uschar occhars[8];  pcre_uchar occhars[6];
612  #endif  #endif
613    
614  int codelink;  int codelink;
# Line 622  int save_offset1, save_offset2, save_off Line 624  int save_offset1, save_offset2, save_off
624  int stacksave[REC_STACK_SAVE_MAX];  int stacksave[REC_STACK_SAVE_MAX];
625    
626  eptrblock newptrb;  eptrblock newptrb;
627    
628    /* There is a special fudge for calling match() in a way that causes it to
629    measure the size of its basic stack frame when the stack is being used for
630    recursion. The second argument (ecode) being NULL triggers this behaviour. It
631    cannot normally ever be NULL. The return is the negated value of the frame
632    size. */
633    
634    if (ecode == NULL)
635      {
636      if (rdepth == 0)
637        return match((PCRE_PUCHAR)&rdepth, NULL, NULL, 0, NULL, NULL, 1);
638      else
639        {
640        int len = (char *)&rdepth - (char *)eptr;
641        return (len > 0)? -len : len;
642        }
643      }
644  #endif     /* NO_RECURSE */  #endif     /* NO_RECURSE */
645    
646  /* To save space on the stack and in the heap frame, I have doubled up on some  /* To save space on the stack and in the heap frame, I have doubled up on some
# Line 634  the alternative names that are used. */ Line 653  the alternative names that are used. */
653  #define code_offset   codelink  #define code_offset   codelink
654  #define condassert    condition  #define condassert    condition
655  #define matched_once  prev_is_word  #define matched_once  prev_is_word
656    #define foc           number
657    #define save_mark     data
658    
659  /* These statements are here to stop the compiler complaining about unitialized  /* These statements are here to stop the compiler complaining about unitialized
660  variables. */  variables. */
# Line 659  defined). However, RMATCH isn't like a f Line 680  defined). However, RMATCH isn't like a f
680  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,
681  however, impact performance when true recursion is being used. */  however, impact performance when true recursion is being used. */
682    
683  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
684  utf8 = md->utf8;       /* Local copy of the flag */  utf = md->utf;       /* Local copy of the flag */
685  #else  #else
686  utf8 = FALSE;  utf = FALSE;
687  #endif  #endif
688    
689  /* First check that we haven't called match() too many times, or that we  /* First check that we haven't called match() too many times, or that we
# Line 701  for (;;) Line 722  for (;;)
722    switch(op)    switch(op)
723      {      {
724      case OP_MARK:      case OP_MARK:
725      markptr = ecode + 2;      md->nomatch_mark = ecode + 2;
726      RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode] + ecode[1], offset_top, md,      md->mark = NULL;    /* In case previously set by assertion */
727        RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode] + ecode[1], offset_top, md,
728        eptrb, RM55);        eptrb, RM55);
729        if ((rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) &&
730             md->mark == NULL) md->mark = ecode + 2;
731    
732      /* A return of MATCH_SKIP_ARG means that matching failed at SKIP with an      /* A return of MATCH_SKIP_ARG means that matching failed at SKIP with an
733      argument, and we must check whether that argument matches this MARK's      argument, and we must check whether that argument matches this MARK's
# Line 712  for (;;) Line 736  for (;;)
736      position and return MATCH_SKIP. Otherwise, pass back the return code      position and return MATCH_SKIP. Otherwise, pass back the return code
737      unaltered. */      unaltered. */
738    
739      if (rrc == MATCH_SKIP_ARG &&      else if (rrc == MATCH_SKIP_ARG &&
740          strcmp((char *)markptr, (char *)(md->start_match_ptr)) == 0)          STRCMP_UC_UC(ecode + 2, md->start_match_ptr) == 0)
741        {        {
742        md->start_match_ptr = eptr;        md->start_match_ptr = eptr;
743        RRETURN(MATCH_SKIP);        RRETURN(MATCH_SKIP);
744        }        }
   
     if (md->mark == NULL) md->mark = markptr;  
745      RRETURN(rrc);      RRETURN(rrc);
746    
747      case OP_FAIL:      case OP_FAIL:
748      MRRETURN(MATCH_NOMATCH);      RRETURN(MATCH_NOMATCH);
749    
750      /* COMMIT overrides PRUNE, SKIP, and THEN */      /* COMMIT overrides PRUNE, SKIP, and THEN */
751    
752      case OP_COMMIT:      case OP_COMMIT:
753      RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,      RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md,
754        eptrb, RM52);        eptrb, RM52);
755      if (rrc != MATCH_NOMATCH && rrc != MATCH_PRUNE &&      if (rrc != MATCH_NOMATCH && rrc != MATCH_PRUNE &&
756          rrc != MATCH_SKIP && rrc != MATCH_SKIP_ARG &&          rrc != MATCH_SKIP && rrc != MATCH_SKIP_ARG &&
757          rrc != MATCH_THEN)          rrc != MATCH_THEN)
758        RRETURN(rrc);        RRETURN(rrc);
759      MRRETURN(MATCH_COMMIT);      RRETURN(MATCH_COMMIT);
760    
761      /* PRUNE overrides THEN */      /* PRUNE overrides THEN */
762    
763      case OP_PRUNE:      case OP_PRUNE:
764      RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,      RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md,
765        eptrb, RM51);        eptrb, RM51);
766      if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);      if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);
767      MRRETURN(MATCH_PRUNE);      RRETURN(MATCH_PRUNE);
768    
769      case OP_PRUNE_ARG:      case OP_PRUNE_ARG:
770      RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode] + ecode[1], offset_top, md,      md->nomatch_mark = ecode + 2;
771        md->mark = NULL;    /* In case previously set by assertion */
772        RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode] + ecode[1], offset_top, md,
773        eptrb, RM56);        eptrb, RM56);
774        if ((rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) &&
775             md->mark == NULL) md->mark = ecode + 2;
776      if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);      if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);
     md->mark = ecode + 2;  
777      RRETURN(MATCH_PRUNE);      RRETURN(MATCH_PRUNE);
778    
779      /* SKIP overrides PRUNE and THEN */      /* SKIP overrides PRUNE and THEN */
780    
781      case OP_SKIP:      case OP_SKIP:
782      RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,      RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md,
783        eptrb, RM53);        eptrb, RM53);
784      if (rrc != MATCH_NOMATCH && rrc != MATCH_PRUNE && rrc != MATCH_THEN)      if (rrc != MATCH_NOMATCH && rrc != MATCH_PRUNE && rrc != MATCH_THEN)
785        RRETURN(rrc);        RRETURN(rrc);
786      md->start_match_ptr = eptr;   /* Pass back current position */      md->start_match_ptr = eptr;   /* Pass back current position */
787      MRRETURN(MATCH_SKIP);      RRETURN(MATCH_SKIP);
788    
789        /* Note that, for Perl compatibility, SKIP with an argument does NOT set
790        nomatch_mark. There is a flag that disables this opcode when re-matching a
791        pattern that ended with a SKIP for which there was not a matching MARK. */
792    
793      case OP_SKIP_ARG:      case OP_SKIP_ARG:
794      RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode] + ecode[1], offset_top, md,      if (md->ignore_skip_arg)
795          {
796          ecode += PRIV(OP_lengths)[*ecode] + ecode[1];
797          break;
798          }
799        RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode] + ecode[1], offset_top, md,
800        eptrb, RM57);        eptrb, RM57);
801      if (rrc != MATCH_NOMATCH && rrc != MATCH_PRUNE && rrc != MATCH_THEN)      if (rrc != MATCH_NOMATCH && rrc != MATCH_PRUNE && rrc != MATCH_THEN)
802        RRETURN(rrc);        RRETURN(rrc);
803    
804      /* Pass back the current skip name by overloading md->start_match_ptr and      /* Pass back the current skip name by overloading md->start_match_ptr and
805      returning the special MATCH_SKIP_ARG return code. This will either be      returning the special MATCH_SKIP_ARG return code. This will either be
806      caught by a matching MARK, or get to the top, where it is treated the same      caught by a matching MARK, or get to the top, where it causes a rematch
807      as PRUNE. */      with the md->ignore_skip_arg flag set. */
808    
809      md->start_match_ptr = ecode + 2;      md->start_match_ptr = ecode + 2;
810      RRETURN(MATCH_SKIP_ARG);      RRETURN(MATCH_SKIP_ARG);
# Line 780  for (;;) Line 814  for (;;)
814      match pointer to do this. */      match pointer to do this. */
815    
816      case OP_THEN:      case OP_THEN:
817      RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,      RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md,
818        eptrb, RM54);        eptrb, RM54);
819      if (rrc != MATCH_NOMATCH) RRETURN(rrc);      if (rrc != MATCH_NOMATCH) RRETURN(rrc);
820      md->start_match_ptr = ecode;      md->start_match_ptr = ecode;
821      MRRETURN(MATCH_THEN);      RRETURN(MATCH_THEN);
822    
823      case OP_THEN_ARG:      case OP_THEN_ARG:
824      RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode] + ecode[1], offset_top,      md->nomatch_mark = ecode + 2;
825        md->mark = NULL;    /* In case previously set by assertion */
826        RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode] + ecode[1], offset_top,
827        md, eptrb, RM58);        md, eptrb, RM58);
828        if ((rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) &&
829             md->mark == NULL) md->mark = ecode + 2;
830      if (rrc != MATCH_NOMATCH) RRETURN(rrc);      if (rrc != MATCH_NOMATCH) RRETURN(rrc);
831      md->start_match_ptr = ecode;      md->start_match_ptr = ecode;
     md->mark = ecode + 2;  
832      RRETURN(MATCH_THEN);      RRETURN(MATCH_THEN);
833    
834      /* Handle an atomic group that does not contain any capturing parentheses.      /* Handle an atomic group that does not contain any capturing parentheses.
835      This can be handled like an assertion. Prior to 8.13, all atomic groups      This can be handled like an assertion. Prior to 8.13, all atomic groups
836      were handled this way. In 8.13, the code was changed as below for ONCE, so      were handled this way. In 8.13, the code was changed as below for ONCE, so
837      that backups pass through the group and thereby reset captured values.      that backups pass through the group and thereby reset captured values.
838      However, this uses a lot more stack, so in 8.20, atomic groups that do not      However, this uses a lot more stack, so in 8.20, atomic groups that do not
839      contain any captures generate OP_ONCE_NC, which can be handled in the old,      contain any captures generate OP_ONCE_NC, which can be handled in the old,
840      less stack intensive way.      less stack intensive way.
841    
842      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
# Line 810  for (;;) Line 847  for (;;)
847      case OP_ONCE_NC:      case OP_ONCE_NC:
848      prev = ecode;      prev = ecode;
849      saved_eptr = eptr;      saved_eptr = eptr;
850        save_mark = md->mark;
851      do      do
852        {        {
853        RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, eptrb, RM64);        RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, eptrb, RM64);
# Line 821  for (;;) Line 859  for (;;)
859        if (rrc == MATCH_THEN)        if (rrc == MATCH_THEN)
860          {          {
861          next = ecode + GET(ecode,1);          next = ecode + GET(ecode,1);
862          if (md->start_match_ptr < next &&          if (md->start_match_ptr < next &&
863              (*ecode == OP_ALT || *next == OP_ALT))              (*ecode == OP_ALT || *next == OP_ALT))
864            rrc = MATCH_NOMATCH;            rrc = MATCH_NOMATCH;
865          }          }
866    
867        if (rrc != MATCH_NOMATCH) RRETURN(rrc);        if (rrc != MATCH_NOMATCH) RRETURN(rrc);
868        ecode += GET(ecode,1);        ecode += GET(ecode,1);
869          md->mark = save_mark;
870        }        }
871      while (*ecode == OP_ALT);      while (*ecode == OP_ALT);
872    
# Line 867  for (;;) Line 906  for (;;)
906        }        }
907      else  /* OP_KETRMAX */      else  /* OP_KETRMAX */
908        {        {
       md->match_function_type = MATCH_CBEGROUP;  
909        RMATCH(eptr, prev, offset_top, md, eptrb, RM66);        RMATCH(eptr, prev, offset_top, md, eptrb, RM66);
910        if (rrc != MATCH_NOMATCH) RRETURN(rrc);        if (rrc != MATCH_NOMATCH) RRETURN(rrc);
911        ecode += 1 + LINK_SIZE;        ecode += 1 + LINK_SIZE;
# Line 907  for (;;) Line 945  for (;;)
945        save_offset2 = md->offset_vector[offset+1];        save_offset2 = md->offset_vector[offset+1];
946        save_offset3 = md->offset_vector[md->offset_end - number];        save_offset3 = md->offset_vector[md->offset_end - number];
947        save_capture_last = md->capture_last;        save_capture_last = md->capture_last;
948          save_mark = md->mark;
949    
950        DPRINTF(("saving %d %d %d\n", save_offset1, save_offset2, save_offset3));        DPRINTF(("saving %d %d %d\n", save_offset1, save_offset2, save_offset3));
951        md->offset_vector[md->offset_end - number] =        md->offset_vector[md->offset_end - number] =
# Line 915  for (;;) Line 954  for (;;)
954        for (;;)        for (;;)
955          {          {
956          if (op >= OP_SBRA) md->match_function_type = MATCH_CBEGROUP;          if (op >= OP_SBRA) md->match_function_type = MATCH_CBEGROUP;
957          RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,          RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md,
958            eptrb, RM1);            eptrb, RM1);
959          if (rrc == MATCH_ONCE) break;  /* Backing up through an atomic group */          if (rrc == MATCH_ONCE) break;  /* Backing up through an atomic group */
960    
961          /* If we backed up to a THEN, check whether it is within the current          /* If we backed up to a THEN, check whether it is within the current
962          branch by comparing the address of the THEN that is passed back with          branch by comparing the address of the THEN that is passed back with
963          the end of the branch. If it is within the current branch, and the          the end of the branch. If it is within the current branch, and the
964          branch is one of two or more alternatives (it either starts or ends          branch is one of two or more alternatives (it either starts or ends
965          with OP_ALT), we have reached the limit of THEN's action, so convert          with OP_ALT), we have reached the limit of THEN's action, so convert
966          the return code to NOMATCH, which will cause normal backtracking to          the return code to NOMATCH, which will cause normal backtracking to
967          happen from now on. Otherwise, THEN is passed back to an outer          happen from now on. Otherwise, THEN is passed back to an outer
968          alternative. This implements Perl's treatment of parenthesized groups,          alternative. This implements Perl's treatment of parenthesized groups,
969          where a group not containing | does not affect the current alternative,          where a group not containing | does not affect the current alternative,
970          that is, (X) is NOT the same as (X|(*F)). */          that is, (X) is NOT the same as (X|(*F)). */
971    
972          if (rrc == MATCH_THEN)          if (rrc == MATCH_THEN)
973            {            {
974            next = ecode + GET(ecode,1);            next = ecode + GET(ecode,1);
975            if (md->start_match_ptr < next &&            if (md->start_match_ptr < next &&
976                (*ecode == OP_ALT || *next == OP_ALT))                (*ecode == OP_ALT || *next == OP_ALT))
977              rrc = MATCH_NOMATCH;              rrc = MATCH_NOMATCH;
978            }            }
979    
980          /* Anything other than NOMATCH is passed back. */          /* Anything other than NOMATCH is passed back. */
981    
982          if (rrc != MATCH_NOMATCH) RRETURN(rrc);          if (rrc != MATCH_NOMATCH) RRETURN(rrc);
983          md->capture_last = save_capture_last;          md->capture_last = save_capture_last;
984          ecode += GET(ecode, 1);          ecode += GET(ecode, 1);
985            md->mark = save_mark;
986          if (*ecode != OP_ALT) break;          if (*ecode != OP_ALT) break;
987          }          }
988    
# Line 953  for (;;) Line 993  for (;;)
993    
994        /* At this point, rrc will be one of MATCH_ONCE or MATCH_NOMATCH. */        /* At this point, rrc will be one of MATCH_ONCE or MATCH_NOMATCH. */
995    
       if (md->mark == NULL) md->mark = markptr;  
996        RRETURN(rrc);        RRETURN(rrc);
997        }        }
998    
# Line 995  for (;;) Line 1034  for (;;)
1034    
1035      for (;;)      for (;;)
1036        {        {
1037        if (op >= OP_SBRA || op == OP_ONCE) md->match_function_type = MATCH_CBEGROUP;        if (op >= OP_SBRA || op == OP_ONCE)
1038            md->match_function_type = MATCH_CBEGROUP;
1039    
1040        /* If this is not a possibly empty group, and there are no (*THEN)s in        /* If this is not a possibly empty group, and there are no (*THEN)s in
1041        the pattern, and this is the final alternative, optimize as described        the pattern, and this is the final alternative, optimize as described
# Line 1003  for (;;) Line 1043  for (;;)
1043    
1044        else if (!md->hasthen && ecode[GET(ecode, 1)] != OP_ALT)        else if (!md->hasthen && ecode[GET(ecode, 1)] != OP_ALT)
1045          {          {
1046          ecode += _pcre_OP_lengths[*ecode];          ecode += PRIV(OP_lengths)[*ecode];
1047          goto TAIL_RECURSE;          goto TAIL_RECURSE;
1048          }          }
1049    
1050        /* In all other cases, we have to make another call to match(). */        /* In all other cases, we have to make another call to match(). */
1051    
1052        RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md, eptrb,        save_mark = md->mark;
1053          RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md, eptrb,
1054          RM2);          RM2);
1055    
1056        /* See comment in the code for capturing groups above about handling        /* See comment in the code for capturing groups above about handling
1057        THEN. */        THEN. */
1058    
1059        if (rrc == MATCH_THEN)        if (rrc == MATCH_THEN)
1060          {          {
1061          next = ecode + GET(ecode,1);          next = ecode + GET(ecode,1);
1062          if (md->start_match_ptr < next &&          if (md->start_match_ptr < next &&
1063              (*ecode == OP_ALT || *next == OP_ALT))              (*ecode == OP_ALT || *next == OP_ALT))
1064            rrc = MATCH_NOMATCH;            rrc = MATCH_NOMATCH;
1065          }          }
1066    
1067        if (rrc != MATCH_NOMATCH)        if (rrc != MATCH_NOMATCH)
1068          {          {
1069          if (rrc == MATCH_ONCE)          if (rrc == MATCH_ONCE)
1070            {            {
1071            const uschar *scode = ecode;            const pcre_uchar *scode = ecode;
1072            if (*scode != OP_ONCE)           /* If not at start, find it */            if (*scode != OP_ONCE)           /* If not at start, find it */
1073              {              {
1074              while (*scode == OP_ALT) scode += GET(scode, 1);              while (*scode == OP_ALT) scode += GET(scode, 1);
# Line 1038  for (;;) Line 1079  for (;;)
1079          RRETURN(rrc);          RRETURN(rrc);
1080          }          }
1081        ecode += GET(ecode, 1);        ecode += GET(ecode, 1);
1082          md->mark = save_mark;
1083        if (*ecode != OP_ALT) break;        if (*ecode != OP_ALT) break;
1084        }        }
1085    
     if (md->mark == NULL) md->mark = markptr;  
1086      RRETURN(MATCH_NOMATCH);      RRETURN(MATCH_NOMATCH);
1087    
1088      /* Handle possessive capturing brackets with an unlimited repeat. We come      /* Handle possessive capturing brackets with an unlimited repeat. We come
# Line 1070  for (;;) Line 1111  for (;;)
1111      if (offset < md->offset_max)      if (offset < md->offset_max)
1112        {        {
1113        matched_once = FALSE;        matched_once = FALSE;
1114        code_offset = ecode - md->start_code;        code_offset = (int)(ecode - md->start_code);
1115    
1116        save_offset1 = md->offset_vector[offset];        save_offset1 = md->offset_vector[offset];
1117        save_offset2 = md->offset_vector[offset+1];        save_offset2 = md->offset_vector[offset+1];
# Line 1093  for (;;) Line 1134  for (;;)
1134          md->offset_vector[md->offset_end - number] =          md->offset_vector[md->offset_end - number] =
1135            (int)(eptr - md->start_subject);            (int)(eptr - md->start_subject);
1136          if (op >= OP_SBRA) md->match_function_type = MATCH_CBEGROUP;          if (op >= OP_SBRA) md->match_function_type = MATCH_CBEGROUP;
1137          RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,          RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md,
1138            eptrb, RM63);            eptrb, RM63);
1139          if (rrc == MATCH_KETRPOS)          if (rrc == MATCH_KETRPOS)
1140            {            {
# Line 1104  for (;;) Line 1145  for (;;)
1145            matched_once = TRUE;            matched_once = TRUE;
1146            continue;            continue;
1147            }            }
1148    
1149          /* See comment in the code for capturing groups above about handling          /* See comment in the code for capturing groups above about handling
1150          THEN. */          THEN. */
1151    
1152          if (rrc == MATCH_THEN)          if (rrc == MATCH_THEN)
1153            {            {
1154            next = ecode + GET(ecode,1);            next = ecode + GET(ecode,1);
1155            if (md->start_match_ptr < next &&            if (md->start_match_ptr < next &&
1156                (*ecode == OP_ALT || *next == OP_ALT))                (*ecode == OP_ALT || *next == OP_ALT))
1157              rrc = MATCH_NOMATCH;              rrc = MATCH_NOMATCH;
1158            }            }
1159    
1160          if (rrc != MATCH_NOMATCH) RRETURN(rrc);          if (rrc != MATCH_NOMATCH) RRETURN(rrc);
1161          md->capture_last = save_capture_last;          md->capture_last = save_capture_last;
# Line 1129  for (;;) Line 1170  for (;;)
1170          md->offset_vector[md->offset_end - number] = save_offset3;          md->offset_vector[md->offset_end - number] = save_offset3;
1171          }          }
1172    
       if (md->mark == NULL) md->mark = markptr;  
1173        if (allow_zero || matched_once)        if (allow_zero || matched_once)
1174          {          {
1175          ecode += 1 + LINK_SIZE;          ecode += 1 + LINK_SIZE;
# Line 1161  for (;;) Line 1201  for (;;)
1201    
1202      POSSESSIVE_NON_CAPTURE:      POSSESSIVE_NON_CAPTURE:
1203      matched_once = FALSE;      matched_once = FALSE;
1204      code_offset = ecode - md->start_code;      code_offset = (int)(ecode - md->start_code);
1205    
1206      for (;;)      for (;;)
1207        {        {
1208        if (op >= OP_SBRA) md->match_function_type = MATCH_CBEGROUP;        if (op >= OP_SBRA) md->match_function_type = MATCH_CBEGROUP;
1209        RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,        RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md,
1210          eptrb, RM48);          eptrb, RM48);
1211        if (rrc == MATCH_KETRPOS)        if (rrc == MATCH_KETRPOS)
1212          {          {
# Line 1176  for (;;) Line 1216  for (;;)
1216          matched_once = TRUE;          matched_once = TRUE;
1217          continue;          continue;
1218          }          }
1219    
1220        /* See comment in the code for capturing groups above about handling        /* See comment in the code for capturing groups above about handling
1221        THEN. */        THEN. */
1222    
1223        if (rrc == MATCH_THEN)        if (rrc == MATCH_THEN)
1224          {          {
1225          next = ecode + GET(ecode,1);          next = ecode + GET(ecode,1);
1226          if (md->start_match_ptr < next &&          if (md->start_match_ptr < next &&
1227              (*ecode == OP_ALT || *next == OP_ALT))              (*ecode == OP_ALT || *next == OP_ALT))
1228            rrc = MATCH_NOMATCH;            rrc = MATCH_NOMATCH;
1229          }          }
1230    
1231        if (rrc != MATCH_NOMATCH) RRETURN(rrc);        if (rrc != MATCH_NOMATCH) RRETURN(rrc);
1232        ecode += GET(ecode, 1);        ecode += GET(ecode, 1);
# Line 1216  for (;;) Line 1256  for (;;)
1256    
1257      if (ecode[LINK_SIZE+1] == OP_CALLOUT)      if (ecode[LINK_SIZE+1] == OP_CALLOUT)
1258        {        {
1259        if (pcre_callout != NULL)        if (PUBL(callout) != NULL)
1260          {          {
1261          pcre_callout_block cb;          PUBL(callout_block) cb;
1262          cb.version          = 2;   /* Version 1 of the callout block */          cb.version          = 2;   /* Version 1 of the callout block */
1263          cb.callout_number   = ecode[LINK_SIZE+2];          cb.callout_number   = ecode[LINK_SIZE+2];
1264          cb.offset_vector    = md->offset_vector;          cb.offset_vector    = md->offset_vector;
1265    #ifdef COMPILE_PCRE8
1266          cb.subject          = (PCRE_SPTR)md->start_subject;          cb.subject          = (PCRE_SPTR)md->start_subject;
1267    #else
1268            cb.subject          = (PCRE_SPTR16)md->start_subject;
1269    #endif
1270          cb.subject_length   = (int)(md->end_subject - md->start_subject);          cb.subject_length   = (int)(md->end_subject - md->start_subject);
1271          cb.start_match      = (int)(mstart - md->start_subject);          cb.start_match      = (int)(mstart - md->start_subject);
1272          cb.current_position = (int)(eptr - md->start_subject);          cb.current_position = (int)(eptr - md->start_subject);
# Line 1231  for (;;) Line 1275  for (;;)
1275          cb.capture_top      = offset_top/2;          cb.capture_top      = offset_top/2;
1276          cb.capture_last     = md->capture_last;          cb.capture_last     = md->capture_last;
1277          cb.callout_data     = md->callout_data;          cb.callout_data     = md->callout_data;
1278          cb.mark             = markptr;          cb.mark             = md->nomatch_mark;
1279          if ((rrc = (*pcre_callout)(&cb)) > 0) MRRETURN(MATCH_NOMATCH);          if ((rrc = (*PUBL(callout))(&cb)) > 0) RRETURN(MATCH_NOMATCH);
1280          if (rrc < 0) RRETURN(rrc);          if (rrc < 0) RRETURN(rrc);
1281          }          }
1282        ecode += _pcre_OP_lengths[OP_CALLOUT];        ecode += PRIV(OP_lengths)[OP_CALLOUT];
1283        }        }
1284    
1285      condcode = ecode[LINK_SIZE+1];      condcode = ecode[LINK_SIZE+1];
# Line 1252  for (;;) Line 1296  for (;;)
1296        else        else
1297          {          {
1298          int recno = GET2(ecode, LINK_SIZE + 2);   /* Recursion group number*/          int recno = GET2(ecode, LINK_SIZE + 2);   /* Recursion group number*/
1299          condition =  (recno == RREF_ANY || recno == md->recursive->group_num);          condition = (recno == RREF_ANY || recno == md->recursive->group_num);
1300    
1301          /* If the test is for recursion into a specific subpattern, and it is          /* If the test is for recursion into a specific subpattern, and it is
1302          false, but the test was set up by name, scan the table to see if the          false, but the test was set up by name, scan the table to see if the
1303          name refers to any other numbers, and test them. The condition is true          name refers to any other numbers, and test them. The condition is true
1304          if any one is set. */          if any one is set. */
1305    
1306          if (!condition && condcode == OP_NRREF && recno != RREF_ANY)          if (!condition && condcode == OP_NRREF)
1307            {            {
1308            uschar *slotA = md->name_table;            pcre_uchar *slotA = md->name_table;
1309            for (i = 0; i < md->name_count; i++)            for (i = 0; i < md->name_count; i++)
1310              {              {
1311              if (GET2(slotA, 0) == recno) break;              if (GET2(slotA, 0) == recno) break;
# Line 1274  for (;;) Line 1318  for (;;)
1318    
1319            if (i < md->name_count)            if (i < md->name_count)
1320              {              {
1321              uschar *slotB = slotA;              pcre_uchar *slotB = slotA;
1322              while (slotB > md->name_table)              while (slotB > md->name_table)
1323                {                {
1324                slotB -= md->name_entry_size;                slotB -= md->name_entry_size;
1325                if (strcmp((char *)slotA + 2, (char *)slotB + 2) == 0)                if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
1326                  {                  {
1327                  condition = GET2(slotB, 0) == md->recursive->group_num;                  condition = GET2(slotB, 0) == md->recursive->group_num;
1328                  if (condition) break;                  if (condition) break;
# Line 1294  for (;;) Line 1338  for (;;)
1338                for (i++; i < md->name_count; i++)                for (i++; i < md->name_count; i++)
1339                  {                  {
1340                  slotB += md->name_entry_size;                  slotB += md->name_entry_size;
1341                  if (strcmp((char *)slotA + 2, (char *)slotB + 2) == 0)                  if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
1342                    {                    {
1343                    condition = GET2(slotB, 0) == md->recursive->group_num;                    condition = GET2(slotB, 0) == md->recursive->group_num;
1344                    if (condition) break;                    if (condition) break;
# Line 1307  for (;;) Line 1351  for (;;)
1351    
1352          /* Chose branch according to the condition */          /* Chose branch according to the condition */
1353    
1354          ecode += condition? 3 : GET(ecode, 1);          ecode += condition? 1 + IMM2_SIZE : GET(ecode, 1);
1355          }          }
1356        }        }
1357    
# Line 1324  for (;;) Line 1368  for (;;)
1368        if (!condition && condcode == OP_NCREF)        if (!condition && condcode == OP_NCREF)
1369          {          {
1370          int refno = offset >> 1;          int refno = offset >> 1;
1371          uschar *slotA = md->name_table;          pcre_uchar *slotA = md->name_table;
1372    
1373          for (i = 0; i < md->name_count; i++)          for (i = 0; i < md->name_count; i++)
1374            {            {
# Line 1338  for (;;) Line 1382  for (;;)
1382    
1383          if (i < md->name_count)          if (i < md->name_count)
1384            {            {
1385            uschar *slotB = slotA;            pcre_uchar *slotB = slotA;
1386            while (slotB > md->name_table)            while (slotB > md->name_table)
1387              {              {
1388              slotB -= md->name_entry_size;              slotB -= md->name_entry_size;
1389              if (strcmp((char *)slotA + 2, (char *)slotB + 2) == 0)              if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
1390                {                {
1391                offset = GET2(slotB, 0) << 1;                offset = GET2(slotB, 0) << 1;
1392                condition = offset < offset_top &&                condition = offset < offset_top &&
# Line 1360  for (;;) Line 1404  for (;;)
1404              for (i++; i < md->name_count; i++)              for (i++; i < md->name_count; i++)
1405                {                {
1406                slotB += md->name_entry_size;                slotB += md->name_entry_size;
1407                if (strcmp((char *)slotA + 2, (char *)slotB + 2) == 0)                if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
1408                  {                  {
1409                  offset = GET2(slotB, 0) << 1;                  offset = GET2(slotB, 0) << 1;
1410                  condition = offset < offset_top &&                  condition = offset < offset_top &&
# Line 1375  for (;;) Line 1419  for (;;)
1419    
1420        /* Chose branch according to the condition */        /* Chose branch according to the condition */
1421    
1422        ecode += condition? 3 : GET(ecode, 1);        ecode += condition? 1 + IMM2_SIZE : GET(ecode, 1);
1423        }        }
1424    
1425      else if (condcode == OP_DEF)     /* DEFINE - always false */      else if (condcode == OP_DEF)     /* DEFINE - always false */
# Line 1400  for (;;) Line 1444  for (;;)
1444          ecode += 1 + LINK_SIZE + GET(ecode, LINK_SIZE + 2);          ecode += 1 + LINK_SIZE + GET(ecode, LINK_SIZE + 2);
1445          while (*ecode == OP_ALT) ecode += GET(ecode, 1);          while (*ecode == OP_ALT) ecode += GET(ecode, 1);
1446          }          }
1447    
1448        /* PCRE doesn't allow the effect of (*THEN) to escape beyond an        /* PCRE doesn't allow the effect of (*THEN) to escape beyond an
1449        assertion; it is therefore treated as NOMATCH. */        assertion; it is therefore treated as NOMATCH. */
1450    
1451        else if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN)        else if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN)
1452          {          {
1453          RRETURN(rrc);         /* Need braces because of following else */          RRETURN(rrc);         /* Need braces because of following else */
1454          }          }
# Line 1432  for (;;) Line 1476  for (;;)
1476          ecode += 1 + LINK_SIZE;          ecode += 1 + LINK_SIZE;
1477          goto TAIL_RECURSE;          goto TAIL_RECURSE;
1478          }          }
1479    
1480        md->match_function_type = MATCH_CBEGROUP;        md->match_function_type = MATCH_CBEGROUP;
1481        RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, eptrb, RM49);        RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, eptrb, RM49);
1482        RRETURN(rrc);        RRETURN(rrc);
# Line 1467  for (;;) Line 1511  for (;;)
1511        md->offset_vector[offset+1] = (int)(eptr - md->start_subject);        md->offset_vector[offset+1] = (int)(eptr - md->start_subject);
1512        if (offset_top <= offset) offset_top = offset + 2;        if (offset_top <= offset) offset_top = offset + 2;
1513        }        }
1514      ecode += 3;      ecode += 1 + IMM2_SIZE;
1515      break;      break;
1516    
1517    
# Line 1487  for (;;) Line 1531  for (;;)
1531           (md->notempty ||           (md->notempty ||
1532             (md->notempty_atstart &&             (md->notempty_atstart &&
1533               mstart == md->start_subject + md->start_offset)))               mstart == md->start_subject + md->start_offset)))
1534        MRRETURN(MATCH_NOMATCH);        RRETURN(MATCH_NOMATCH);
1535    
1536      /* Otherwise, we have a match. */      /* Otherwise, we have a match. */
1537    
# Line 1496  for (;;) Line 1540  for (;;)
1540      md->start_match_ptr = mstart;       /* and the start (\K can modify) */      md->start_match_ptr = mstart;       /* and the start (\K can modify) */
1541    
1542      /* For some reason, the macros don't work properly if an expression is      /* For some reason, the macros don't work properly if an expression is
1543      given as the argument to MRRETURN when the heap is in use. */      given as the argument to RRETURN when the heap is in use. */
1544    
1545      rrc = (op == OP_END)? MATCH_MATCH : MATCH_ACCEPT;      rrc = (op == OP_END)? MATCH_MATCH : MATCH_ACCEPT;
1546      MRRETURN(rrc);      RRETURN(rrc);
1547    
1548      /* Assertion brackets. Check the alternative branches in turn - the      /* Assertion brackets. Check the alternative branches in turn - the
1549      matching won't pass the KET for an assertion. If any one branch matches,      matching won't pass the KET for an assertion. If any one branch matches,
# Line 1514  for (;;) Line 1558  for (;;)
1558    
1559      case OP_ASSERT:      case OP_ASSERT:
1560      case OP_ASSERTBACK:      case OP_ASSERTBACK:
1561        save_mark = md->mark;
1562      if (md->match_function_type == MATCH_CONDASSERT)      if (md->match_function_type == MATCH_CONDASSERT)
1563        {        {
1564        condassert = TRUE;        condassert = TRUE;
# Line 1527  for (;;) Line 1572  for (;;)
1572        if (rrc == MATCH_MATCH || rrc == MATCH_ACCEPT)        if (rrc == MATCH_MATCH || rrc == MATCH_ACCEPT)
1573          {          {
1574          mstart = md->start_match_ptr;   /* In case \K reset it */          mstart = md->start_match_ptr;   /* In case \K reset it */
         markptr = md->mark;  
1575          break;          break;
1576          }          }
1577          md->mark = save_mark;
1578        /* PCRE does not allow THEN to escape beyond an assertion; it is treated  
1579        as NOMATCH. */        /* A COMMIT failure must fail the entire assertion, without trying any
1580          subsequent branches. */
1581    
1582          if (rrc == MATCH_COMMIT) RRETURN(MATCH_NOMATCH);
1583    
1584          /* PCRE does not allow THEN to escape beyond an assertion; it
1585          is treated as NOMATCH. */
1586    
1587        if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);        if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);
1588        ecode += GET(ecode, 1);        ecode += GET(ecode, 1);
1589        }        }
1590      while (*ecode == OP_ALT);      while (*ecode == OP_ALT);
1591    
1592      if (*ecode == OP_KET) MRRETURN(MATCH_NOMATCH);      if (*ecode == OP_KET) RRETURN(MATCH_NOMATCH);
1593    
1594      /* If checking an assertion for a condition, return MATCH_MATCH. */      /* If checking an assertion for a condition, return MATCH_MATCH. */
1595    
# Line 1559  for (;;) Line 1609  for (;;)
1609    
1610      case OP_ASSERT_NOT:      case OP_ASSERT_NOT:
1611      case OP_ASSERTBACK_NOT:      case OP_ASSERTBACK_NOT:
1612        save_mark = md->mark;
1613      if (md->match_function_type == MATCH_CONDASSERT)      if (md->match_function_type == MATCH_CONDASSERT)
1614        {        {
1615        condassert = TRUE;        condassert = TRUE;
# Line 1569  for (;;) Line 1620  for (;;)
1620      do      do
1621        {        {
1622        RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, NULL, RM5);        RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, NULL, RM5);
1623        if (rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) MRRETURN(MATCH_NOMATCH);        md->mark = save_mark;
1624          if (rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) RRETURN(MATCH_NOMATCH);
1625        if (rrc == MATCH_SKIP || rrc == MATCH_PRUNE || rrc == MATCH_COMMIT)        if (rrc == MATCH_SKIP || rrc == MATCH_PRUNE || rrc == MATCH_COMMIT)
1626          {          {
1627          do ecode += GET(ecode,1); while (*ecode == OP_ALT);          do ecode += GET(ecode,1); while (*ecode == OP_ALT);
1628          break;          break;
1629          }          }
1630    
1631        /* PCRE does not allow THEN to escape beyond an assertion; it is treated        /* PCRE does not allow THEN to escape beyond an assertion; it is treated
1632        as NOMATCH. */        as NOMATCH. */
1633    
1634        if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);        if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);
# Line 1595  for (;;) Line 1647  for (;;)
1647      back a number of characters, not bytes. */      back a number of characters, not bytes. */
1648    
1649      case OP_REVERSE:      case OP_REVERSE:
1650  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1651      if (utf8)      if (utf)
1652        {        {
1653        i = GET(ecode, 1);        i = GET(ecode, 1);
1654        while (i-- > 0)        while (i-- > 0)
1655          {          {
1656          eptr--;          eptr--;
1657          if (eptr < md->start_subject) MRRETURN(MATCH_NOMATCH);          if (eptr < md->start_subject) RRETURN(MATCH_NOMATCH);
1658          BACKCHAR(eptr);          BACKCHAR(eptr);
1659          }          }
1660        }        }
# Line 1613  for (;;) Line 1665  for (;;)
1665    
1666        {        {
1667        eptr -= GET(ecode, 1);        eptr -= GET(ecode, 1);
1668        if (eptr < md->start_subject) MRRETURN(MATCH_NOMATCH);        if (eptr < md->start_subject) RRETURN(MATCH_NOMATCH);
1669        }        }
1670    
1671      /* Save the earliest consulted character, then skip to next op code */      /* Save the earliest consulted character, then skip to next op code */
# Line 1627  for (;;) Line 1679  for (;;)
1679      function is able to force a failure. */      function is able to force a failure. */
1680    
1681      case OP_CALLOUT:      case OP_CALLOUT:
1682      if (pcre_callout != NULL)      if (PUBL(callout) != NULL)
1683        {        {
1684        pcre_callout_block cb;        PUBL(callout_block) cb;
1685        cb.version          = 2;   /* Version 1 of the callout block */        cb.version          = 2;   /* Version 1 of the callout block */
1686        cb.callout_number   = ecode[1];        cb.callout_number   = ecode[1];
1687        cb.offset_vector    = md->offset_vector;        cb.offset_vector    = md->offset_vector;
1688    #ifdef COMPILE_PCRE8
1689        cb.subject          = (PCRE_SPTR)md->start_subject;        cb.subject          = (PCRE_SPTR)md->start_subject;
1690    #else
1691          cb.subject          = (PCRE_SPTR16)md->start_subject;
1692    #endif
1693        cb.subject_length   = (int)(md->end_subject - md->start_subject);        cb.subject_length   = (int)(md->end_subject - md->start_subject);
1694        cb.start_match      = (int)(mstart - md->start_subject);        cb.start_match      = (int)(mstart - md->start_subject);
1695        cb.current_position = (int)(eptr - md->start_subject);        cb.current_position = (int)(eptr - md->start_subject);
# Line 1642  for (;;) Line 1698  for (;;)
1698        cb.capture_top      = offset_top/2;        cb.capture_top      = offset_top/2;
1699        cb.capture_last     = md->capture_last;        cb.capture_last     = md->capture_last;
1700        cb.callout_data     = md->callout_data;        cb.callout_data     = md->callout_data;
1701        cb.mark             = markptr;        cb.mark             = md->nomatch_mark;
1702        if ((rrc = (*pcre_callout)(&cb)) > 0) MRRETURN(MATCH_NOMATCH);        if ((rrc = (*PUBL(callout))(&cb)) > 0) RRETURN(MATCH_NOMATCH);
1703        if (rrc < 0) RRETURN(rrc);        if (rrc < 0) RRETURN(rrc);
1704        }        }
1705      ecode += 2 + 2*LINK_SIZE;      ecode += 2 + 2*LINK_SIZE;
# Line 1702  for (;;) Line 1758  for (;;)
1758        else        else
1759          {          {
1760          new_recursive.offset_save =          new_recursive.offset_save =
1761            (int *)(pcre_malloc)(new_recursive.saved_max * sizeof(int));            (int *)(PUBL(malloc))(new_recursive.saved_max * sizeof(int));
1762          if (new_recursive.offset_save == NULL) RRETURN(PCRE_ERROR_NOMEMORY);          if (new_recursive.offset_save == NULL) RRETURN(PCRE_ERROR_NOMEMORY);
1763          }          }
1764        memcpy(new_recursive.offset_save, md->offset_vector,        memcpy(new_recursive.offset_save, md->offset_vector,
# Line 1717  for (;;) Line 1773  for (;;)
1773        do        do
1774          {          {
1775          if (cbegroup) md->match_function_type = MATCH_CBEGROUP;          if (cbegroup) md->match_function_type = MATCH_CBEGROUP;
1776          RMATCH(eptr, callpat + _pcre_OP_lengths[*callpat], offset_top,          RMATCH(eptr, callpat + PRIV(OP_lengths)[*callpat], offset_top,
1777            md, eptrb, RM6);            md, eptrb, RM6);
1778          memcpy(md->offset_vector, new_recursive.offset_save,          memcpy(md->offset_vector, new_recursive.offset_save,
1779              new_recursive.saved_max * sizeof(int));              new_recursive.saved_max * sizeof(int));
# Line 1726  for (;;) Line 1782  for (;;)
1782            {            {
1783            DPRINTF(("Recursion matched\n"));            DPRINTF(("Recursion matched\n"));
1784            if (new_recursive.offset_save != stacksave)            if (new_recursive.offset_save != stacksave)
1785              (pcre_free)(new_recursive.offset_save);              (PUBL(free))(new_recursive.offset_save);
1786    
1787            /* Set where we got to in the subject, and reset the start in case            /* Set where we got to in the subject, and reset the start in case
1788            it was changed by \K. This *is* propagated back out of a recursion,            it was changed by \K. This *is* propagated back out of a recursion,
# Line 1737  for (;;) Line 1793  for (;;)
1793            goto RECURSION_MATCHED;        /* Exit loop; end processing */            goto RECURSION_MATCHED;        /* Exit loop; end processing */
1794            }            }
1795    
1796          /* PCRE does not allow THEN to escape beyond a recursion; it is treated          /* PCRE does not allow THEN or COMMIT to escape beyond a recursion; it
1797          as NOMATCH. */          is treated as NOMATCH. */
1798    
1799          else if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN)          else if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN &&
1800                     rrc != MATCH_COMMIT)
1801            {            {
1802            DPRINTF(("Recursion gave error %d\n", rrc));            DPRINTF(("Recursion gave error %d\n", rrc));
1803            if (new_recursive.offset_save != stacksave)            if (new_recursive.offset_save != stacksave)
1804              (pcre_free)(new_recursive.offset_save);              (PUBL(free))(new_recursive.offset_save);
1805            RRETURN(rrc);            RRETURN(rrc);
1806            }            }
1807    
# Line 1756  for (;;) Line 1813  for (;;)
1813        DPRINTF(("Recursion didn't match\n"));        DPRINTF(("Recursion didn't match\n"));
1814        md->recursive = new_recursive.prevrec;        md->recursive = new_recursive.prevrec;
1815        if (new_recursive.offset_save != stacksave)        if (new_recursive.offset_save != stacksave)
1816          (pcre_free)(new_recursive.offset_save);          (PUBL(free))(new_recursive.offset_save);
1817        MRRETURN(MATCH_NOMATCH);        RRETURN(MATCH_NOMATCH);
1818        }        }
1819    
1820      RECURSION_MATCHED:      RECURSION_MATCHED:
# Line 1826  for (;;) Line 1883  for (;;)
1883        }        }
1884      else saved_eptr = NULL;      else saved_eptr = NULL;
1885    
1886      /* If we are at the end of an assertion group or a non-capturing atomic      /* If we are at the end of an assertion group or a non-capturing atomic
1887      group, stop matching and return MATCH_MATCH, but record the current high      group, stop matching and return MATCH_MATCH, but record the current high
1888      water mark for use by positive assertions. We also need to record the match      water mark for use by positive assertions. We also need to record the match
1889      start in case it was changed by \K. */      start in case it was changed by \K. */
1890    
1891      if ((*prev >= OP_ASSERT && *prev <= OP_ASSERTBACK_NOT) ||      if ((*prev >= OP_ASSERT && *prev <= OP_ASSERTBACK_NOT) ||
1892           *prev == OP_ONCE_NC)           *prev == OP_ONCE_NC)
1893        {        {
1894        md->end_match_ptr = eptr;      /* For ONCE_NC */        md->end_match_ptr = eptr;      /* For ONCE_NC */
1895        md->end_offset_top = offset_top;        md->end_offset_top = offset_top;
1896        md->start_match_ptr = mstart;        md->start_match_ptr = mstart;
1897        MRRETURN(MATCH_MATCH);         /* Sets md->mark */        RRETURN(MATCH_MATCH);         /* Sets md->mark */
1898        }        }
1899    
1900      /* 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 1951  for (;;) Line 2008  for (;;)
2008          }          }
2009        if (*prev >= OP_SBRA)    /* Could match an empty string */        if (*prev >= OP_SBRA)    /* Could match an empty string */
2010          {          {
         md->match_function_type = MATCH_CBEGROUP;  
2011          RMATCH(eptr, prev, offset_top, md, eptrb, RM50);          RMATCH(eptr, prev, offset_top, md, eptrb, RM50);
2012          RRETURN(rrc);          RRETURN(rrc);
2013          }          }
# Line 1960  for (;;) Line 2016  for (;;)
2016        }        }
2017      else  /* OP_KETRMAX */      else  /* OP_KETRMAX */
2018        {        {
       if (*prev >= OP_SBRA) md->match_function_type = MATCH_CBEGROUP;  
2019        RMATCH(eptr, prev, offset_top, md, eptrb, RM13);        RMATCH(eptr, prev, offset_top, md, eptrb, RM13);
2020        if (rrc == MATCH_ONCE && md->once_target == prev) rrc = MATCH_NOMATCH;        if (rrc == MATCH_ONCE && md->once_target == prev) rrc = MATCH_NOMATCH;
2021        if (rrc != MATCH_NOMATCH) RRETURN(rrc);        if (rrc != MATCH_NOMATCH) RRETURN(rrc);
# Line 1979  for (;;) Line 2034  for (;;)
2034      /* Not multiline mode: start of subject assertion, unless notbol. */      /* Not multiline mode: start of subject assertion, unless notbol. */
2035    
2036      case OP_CIRC:      case OP_CIRC:
2037      if (md->notbol && eptr == md->start_subject) MRRETURN(MATCH_NOMATCH);      if (md->notbol && eptr == md->start_subject) RRETURN(MATCH_NOMATCH);
2038    
2039      /* Start of subject assertion */      /* Start of subject assertion */
2040    
2041      case OP_SOD:      case OP_SOD:
2042      if (eptr != md->start_subject) MRRETURN(MATCH_NOMATCH);      if (eptr != md->start_subject) RRETURN(MATCH_NOMATCH);
2043      ecode++;      ecode++;
2044      break;      break;
2045    
2046      /* Multiline mode: start of subject unless notbol, or after any newline. */      /* Multiline mode: start of subject unless notbol, or after any newline. */
2047    
2048      case OP_CIRCM:      case OP_CIRCM:
2049      if (md->notbol && eptr == md->start_subject) MRRETURN(MATCH_NOMATCH);      if (md->notbol && eptr == md->start_subject) RRETURN(MATCH_NOMATCH);
2050      if (eptr != md->start_subject &&      if (eptr != md->start_subject &&
2051          (eptr == md->end_subject || !WAS_NEWLINE(eptr)))          (eptr == md->end_subject || !WAS_NEWLINE(eptr)))
2052        MRRETURN(MATCH_NOMATCH);        RRETURN(MATCH_NOMATCH);
2053      ecode++;      ecode++;
2054      break;      break;
2055    
2056      /* Start of match assertion */      /* Start of match assertion */
2057    
2058      case OP_SOM:      case OP_SOM:
2059      if (eptr != md->start_subject + md->start_offset) MRRETURN(MATCH_NOMATCH);      if (eptr != md->start_subject + md->start_offset) RRETURN(MATCH_NOMATCH);
2060      ecode++;      ecode++;
2061      break;      break;
2062    
# Line 2017  for (;;) Line 2072  for (;;)
2072    
2073      case OP_DOLLM:      case OP_DOLLM:
2074      if (eptr < md->end_subject)      if (eptr < md->end_subject)
2075        { if (!IS_NEWLINE(eptr)) MRRETURN(MATCH_NOMATCH); }        {
2076          if (!IS_NEWLINE(eptr))
2077            {
2078            if (md->partial != 0 &&
2079                eptr + 1 >= md->end_subject &&
2080                NLBLOCK->nltype == NLTYPE_FIXED &&
2081                NLBLOCK->nllen == 2 &&
2082                *eptr == NLBLOCK->nl[0])
2083              {
2084              md->hitend = TRUE;
2085              if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
2086              }
2087            RRETURN(MATCH_NOMATCH);
2088            }
2089          }
2090      else      else
2091        {        {
2092        if (md->noteol) MRRETURN(MATCH_NOMATCH);        if (md->noteol) RRETURN(MATCH_NOMATCH);
2093        SCHECK_PARTIAL();        SCHECK_PARTIAL();
2094        }        }
2095      ecode++;      ecode++;
# Line 2030  for (;;) Line 2099  for (;;)
2099      subject unless noteol is set. */      subject unless noteol is set. */
2100    
2101      case OP_DOLL:      case OP_DOLL:
2102      if (md->noteol) MRRETURN(MATCH_NOMATCH);      if (md->noteol) RRETURN(MATCH_NOMATCH);
2103      if (!md->endonly) goto ASSERT_NL_OR_EOS;      if (!md->endonly) goto ASSERT_NL_OR_EOS;
2104    
2105      /* ... else fall through for endonly */      /* ... else fall through for endonly */
# Line 2038  for (;;) Line 2107  for (;;)
2107      /* End of subject assertion (\z) */      /* End of subject assertion (\z) */
2108    
2109      case OP_EOD:      case OP_EOD:
2110      if (eptr < md->end_subject) MRRETURN(MATCH_NOMATCH);      if (eptr < md->end_subject) RRETURN(MATCH_NOMATCH);
2111      SCHECK_PARTIAL();      SCHECK_PARTIAL();
2112      ecode++;      ecode++;
2113      break;      break;
# Line 2049  for (;;) Line 2118  for (;;)
2118      ASSERT_NL_OR_EOS:      ASSERT_NL_OR_EOS:
2119      if (eptr < md->end_subject &&      if (eptr < md->end_subject &&
2120          (!IS_NEWLINE(eptr) || eptr != md->end_subject - md->nllen))          (!IS_NEWLINE(eptr) || eptr != md->end_subject - md->nllen))
2121        MRRETURN(MATCH_NOMATCH);        {
2122          if (md->partial != 0 &&
2123              eptr + 1 >= md->end_subject &&
2124              NLBLOCK->nltype == NLTYPE_FIXED &&
2125              NLBLOCK->nllen == 2 &&
2126              *eptr == NLBLOCK->nl[0])
2127            {
2128            md->hitend = TRUE;
2129            if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
2130            }
2131          RRETURN(MATCH_NOMATCH);
2132          }
2133    
2134      /* Either at end of string or \n before end. */      /* Either at end of string or \n before end. */
2135    
# Line 2068  for (;;) Line 2148  for (;;)
2148        be "non-word" characters. Remember the earliest consulted character for        be "non-word" characters. Remember the earliest consulted character for
2149        partial matching. */        partial matching. */
2150    
2151  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2152        if (utf8)        if (utf)
2153          {          {
2154          /* Get status of previous character */          /* Get status of previous character */
2155    
2156          if (eptr == md->start_subject) prev_is_word = FALSE; else          if (eptr == md->start_subject) prev_is_word = FALSE; else
2157            {            {
2158            USPTR lastptr = eptr - 1;            PCRE_PUCHAR lastptr = eptr - 1;
2159            while((*lastptr & 0xc0) == 0x80) lastptr--;            BACKCHAR(lastptr);
2160            if (lastptr < md->start_used_ptr) md->start_used_ptr = lastptr;            if (lastptr < md->start_used_ptr) md->start_used_ptr = lastptr;
2161            GETCHAR(c, lastptr);            GETCHAR(c, lastptr);
2162  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
# Line 2141  for (;;) Line 2221  for (;;)
2221              }              }
2222            else            else
2223  #endif  #endif
2224            prev_is_word = ((md->ctypes[eptr[-1]] & ctype_word) != 0);            prev_is_word = MAX_255(eptr[-1])
2225                && ((md->ctypes[eptr[-1]] & ctype_word) != 0);
2226            }            }
2227    
2228          /* Get status of next character */          /* Get status of next character */
# Line 2164  for (;;) Line 2245  for (;;)
2245            }            }
2246          else          else
2247  #endif  #endif
2248          cur_is_word = ((md->ctypes[*eptr] & ctype_word) != 0);          cur_is_word = MAX_255(*eptr)
2249              && ((md->ctypes[*eptr] & ctype_word) != 0);
2250          }          }
2251    
2252        /* Now see if the situation is what we want */        /* Now see if the situation is what we want */
2253    
2254        if ((*ecode++ == OP_WORD_BOUNDARY)?        if ((*ecode++ == OP_WORD_BOUNDARY)?
2255             cur_is_word == prev_is_word : cur_is_word != prev_is_word)             cur_is_word == prev_is_word : cur_is_word != prev_is_word)
2256          MRRETURN(MATCH_NOMATCH);          RRETURN(MATCH_NOMATCH);
2257        }        }
2258      break;      break;
2259    
2260      /* Match a single character type; inline for speed */      /* Match any single character type except newline; have to take care with
2261        CRLF newlines and partial matching. */
2262    
2263      case OP_ANY:      case OP_ANY:
2264      if (IS_NEWLINE(eptr)) MRRETURN(MATCH_NOMATCH);      if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH);
2265        if (md->partial != 0 &&
2266            eptr + 1 >= md->end_subject &&
2267            NLBLOCK->nltype == NLTYPE_FIXED &&
2268            NLBLOCK->nllen == 2 &&
2269            *eptr == NLBLOCK->nl[0])
2270          {
2271          md->hitend = TRUE;
2272          if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
2273          }
2274    
2275      /* Fall through */      /* Fall through */
2276    
2277        /* Match any single character whatsoever. */
2278    
2279      case OP_ALLANY:      case OP_ALLANY:
2280      if (eptr >= md->end_subject)   /* DO NOT merge the eptr++ here; it must */      if (eptr >= md->end_subject)   /* DO NOT merge the eptr++ here; it must */
2281        {                            /* not be updated before SCHECK_PARTIAL. */        {                            /* not be updated before SCHECK_PARTIAL. */
2282        SCHECK_PARTIAL();        SCHECK_PARTIAL();
2283        MRRETURN(MATCH_NOMATCH);        RRETURN(MATCH_NOMATCH);
2284        }        }
2285      eptr++;      eptr++;
2286      if (utf8) while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;  #ifdef SUPPORT_UTF
2287        if (utf) ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
2288    #endif
2289      ecode++;      ecode++;
2290      break;      break;
2291    
# Line 2199  for (;;) Line 2296  for (;;)
2296      if (eptr >= md->end_subject)   /* DO NOT merge the eptr++ here; it must */      if (eptr >= md->end_subject)   /* DO NOT merge the eptr++ here; it must */
2297        {                            /* not be updated before SCHECK_PARTIAL. */        {                            /* not be updated before SCHECK_PARTIAL. */
2298        SCHECK_PARTIAL();        SCHECK_PARTIAL();
2299        MRRETURN(MATCH_NOMATCH);        RRETURN(MATCH_NOMATCH);
2300        }        }
2301      eptr++;      eptr++;
2302      ecode++;      ecode++;
# Line 2209  for (;;) Line 2306  for (;;)
2306      if (eptr >= md->end_subject)      if (eptr >= md->end_subject)
2307        {        {
2308        SCHECK_PARTIAL();        SCHECK_PARTIAL();
2309        MRRETURN(MATCH_NOMATCH);        RRETURN(MATCH_NOMATCH);
2310        }        }
2311      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
2312      if (      if (
2313  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || !(defined COMPILE_PCRE8)
2314         c < 256 &&         c < 256 &&
2315  #endif  #endif
2316         (md->ctypes[c] & ctype_digit) != 0         (md->ctypes[c] & ctype_digit) != 0
2317         )         )
2318        MRRETURN(MATCH_NOMATCH);        RRETURN(MATCH_NOMATCH);
2319      ecode++;      ecode++;
2320      break;      break;
2321    
# Line 2226  for (;;) Line 2323  for (;;)
2323      if (eptr >= md->end_subject)      if (eptr >= md->end_subject)
2324        {        {
2325        SCHECK_PARTIAL();        SCHECK_PARTIAL();
2326        MRRETURN(MATCH_NOMATCH);        RRETURN(MATCH_NOMATCH);
2327        }        }
2328      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
2329      if (      if (
2330  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || !(defined COMPILE_PCRE8)
2331         c >= 256 ||         c > 255 ||
2332  #endif  #endif
2333         (md->ctypes[c] & ctype_digit) == 0         (md->ctypes[c] & ctype_digit) == 0
2334         )         )
2335        MRRETURN(MATCH_NOMATCH);        RRETURN(MATCH_NOMATCH);
2336      ecode++;      ecode++;
2337      break;      break;
2338    
# Line 2243  for (;;) Line 2340  for (;;)
2340      if (eptr >= md->end_subject)      if (eptr >= md->end_subject)
2341        {        {
2342        SCHECK_PARTIAL();        SCHECK_PARTIAL();
2343        MRRETURN(MATCH_NOMATCH);        RRETURN(MATCH_NOMATCH);
2344        }        }
2345      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
2346      if (      if (
2347  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || !(defined COMPILE_PCRE8)
2348         c < 256 &&         c < 256 &&
2349  #endif  #endif
2350         (md->ctypes[c] & ctype_space) != 0         (md->ctypes[c] & ctype_space) != 0
2351         )         )
2352        MRRETURN(MATCH_NOMATCH);        RRETURN(MATCH_NOMATCH);
2353      ecode++;      ecode++;
2354      break;      break;
2355    
# Line 2260  for (;;) Line 2357  for (;;)
2357      if (eptr >= md->end_subject)      if (eptr >= md->end_subject)
2358        {        {
2359        SCHECK_PARTIAL();        SCHECK_PARTIAL();
2360        MRRETURN(MATCH_NOMATCH);        RRETURN(MATCH_NOMATCH);
2361        }        }
2362      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
2363      if (      if (
2364  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || !(defined COMPILE_PCRE8)
2365         c >= 256 ||         c > 255 ||
2366  #endif  #endif
2367         (md->ctypes[c] & ctype_space) == 0         (md->ctypes[c] & ctype_space) == 0
2368         )         )
2369        MRRETURN(MATCH_NOMATCH);        RRETURN(MATCH_NOMATCH);
2370      ecode++;      ecode++;
2371      break;      break;
2372    
# Line 2277  for (;;) Line 2374  for (;;)
2374      if (eptr >= md->end_subject)      if (eptr >= md->end_subject)
2375        {        {
2376        SCHECK_PARTIAL();        SCHECK_PARTIAL();
2377        MRRETURN(MATCH_NOMATCH);        RRETURN(MATCH_NOMATCH);
2378        }        }
2379      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
2380      if (      if (
2381  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || !(defined COMPILE_PCRE8)
2382         c < 256 &&         c < 256 &&
2383  #endif  #endif
2384         (md->ctypes[c] & ctype_word) != 0         (md->ctypes[c] & ctype_word) != 0
2385         )         )
2386        MRRETURN(MATCH_NOMATCH);        RRETURN(MATCH_NOMATCH);
2387      ecode++;      ecode++;
2388      break;      break;
2389    
# Line 2294  for (;;) Line 2391  for (;;)
2391      if (eptr >= md->end_subject)      if (eptr >= md->end_subject)
2392        {        {
2393        SCHECK_PARTIAL();        SCHECK_PARTIAL();
2394        MRRETURN(MATCH_NOMATCH);        RRETURN(MATCH_NOMATCH);
2395        }        }
2396      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
2397      if (      if (
2398  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || !(defined COMPILE_PCRE8)
2399         c >= 256 ||         c > 255 ||
2400  #endif  #endif
2401         (md->ctypes[c] & ctype_word) == 0         (md->ctypes[c] & ctype_word) == 0
2402         )         )
2403        MRRETURN(MATCH_NOMATCH);        RRETURN(MATCH_NOMATCH);
2404      ecode++;      ecode++;
2405      break;      break;
2406    
# Line 2311  for (;;) Line 2408  for (;;)
2408      if (eptr >= md->end_subject)      if (eptr >= md->end_subject)
2409        {        {
2410        SCHECK_PARTIAL();        SCHECK_PARTIAL();
2411        MRRETURN(MATCH_NOMATCH);        RRETURN(MATCH_NOMATCH);
2412        }        }
2413      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
2414      switch(c)      switch(c)
2415        {        {
2416        default: MRRETURN(MATCH_NOMATCH);        default: RRETURN(MATCH_NOMATCH);
2417    
2418        case 0x000d:        case 0x000d:
2419        if (eptr < md->end_subject && *eptr == 0x0a) eptr++;        if (eptr >= md->end_subject)
2420            {
2421            SCHECK_PARTIAL();
2422            }
2423          else if (*eptr == 0x0a) eptr++;
2424        break;        break;
2425    
2426        case 0x000a:        case 0x000a:
# Line 2330  for (;;) Line 2431  for (;;)
2431        case 0x0085:        case 0x0085:
2432        case 0x2028:        case 0x2028:
2433        case 0x2029:        case 0x2029:
2434        if (md->bsr_anycrlf) MRRETURN(MATCH_NOMATCH);        if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH);
2435        break;        break;
2436        }        }
2437      ecode++;      ecode++;
# Line 2340  for (;;) Line 2441  for (;;)
2441      if (eptr >= md->end_subject)      if (eptr >= md->end_subject)
2442        {        {
2443        SCHECK_PARTIAL();        SCHECK_PARTIAL();
2444        MRRETURN(MATCH_NOMATCH);        RRETURN(MATCH_NOMATCH);
2445        }        }
2446      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
2447      switch(c)      switch(c)
# Line 2365  for (;;) Line 2466  for (;;)
2466        case 0x202f:    /* NARROW NO-BREAK SPACE */        case 0x202f:    /* NARROW NO-BREAK SPACE */
2467        case 0x205f:    /* MEDIUM MATHEMATICAL SPACE */        case 0x205f:    /* MEDIUM MATHEMATICAL SPACE */
2468        case 0x3000:    /* IDEOGRAPHIC SPACE */        case 0x3000:    /* IDEOGRAPHIC SPACE */
2469        MRRETURN(MATCH_NOMATCH);        RRETURN(MATCH_NOMATCH);
2470        }        }
2471      ecode++;      ecode++;
2472      break;      break;
# Line 2374  for (;;) Line 2475  for (;;)
2475      if (eptr >= md->end_subject)      if (eptr >= md->end_subject)
2476        {        {
2477        SCHECK_PARTIAL();        SCHECK_PARTIAL();
2478        MRRETURN(MATCH_NOMATCH);        RRETURN(MATCH_NOMATCH);
2479        }        }
2480      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
2481      switch(c)      switch(c)
2482        {        {
2483        default: MRRETURN(MATCH_NOMATCH);        default: RRETURN(MATCH_NOMATCH);
2484        case 0x09:      /* HT */        case 0x09:      /* HT */
2485        case 0x20:      /* SPACE */        case 0x20:      /* SPACE */
2486        case 0xa0:      /* NBSP */        case 0xa0:      /* NBSP */
# Line 2408  for (;;) Line 2509  for (;;)
2509      if (eptr >= md->end_subject)      if (eptr >= md->end_subject)
2510        {        {
2511        SCHECK_PARTIAL();        SCHECK_PARTIAL();
2512        MRRETURN(MATCH_NOMATCH);        RRETURN(MATCH_NOMATCH);
2513        }        }
2514      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
2515      switch(c)      switch(c)
# Line 2421  for (;;) Line 2522  for (;;)
2522        case 0x85:      /* NEL */        case 0x85:      /* NEL */
2523        case 0x2028:    /* LINE SEPARATOR */        case 0x2028:    /* LINE SEPARATOR */
2524        case 0x2029:    /* PARAGRAPH SEPARATOR */        case 0x2029:    /* PARAGRAPH SEPARATOR */
2525        MRRETURN(MATCH_NOMATCH);        RRETURN(MATCH_NOMATCH);
2526        }        }
2527      ecode++;      ecode++;
2528      break;      break;
# Line 2430  for (;;) Line 2531  for (;;)
2531      if (eptr >= md->end_subject)      if (eptr >= md->end_subject)
2532        {        {
2533        SCHECK_PARTIAL();        SCHECK_PARTIAL();
2534        MRRETURN(MATCH_NOMATCH);        RRETURN(MATCH_NOMATCH);
2535        }        }
2536      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
2537      switch(c)      switch(c)
2538        {        {
2539        default: MRRETURN(MATCH_NOMATCH);        default: RRETURN(MATCH_NOMATCH);
2540        case 0x0a:      /* LF */        case 0x0a:      /* LF */
2541        case 0x0b:      /* VT */        case 0x0b:      /* VT */
2542        case 0x0c:      /* FF */        case 0x0c:      /* FF */
# Line 2457  for (;;) Line 2558  for (;;)
2558      if (eptr >= md->end_subject)      if (eptr >= md->end_subject)
2559        {        {
2560        SCHECK_PARTIAL();        SCHECK_PARTIAL();
2561        MRRETURN(MATCH_NOMATCH);        RRETURN(MATCH_NOMATCH);
2562        }        }
2563      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
2564        {        {
# Line 2466  for (;;) Line 2567  for (;;)
2567        switch(ecode[1])        switch(ecode[1])
2568          {          {
2569          case PT_ANY:          case PT_ANY:
2570          if (op == OP_NOTPROP) MRRETURN(MATCH_NOMATCH);          if (op == OP_NOTPROP) RRETURN(MATCH_NOMATCH);
2571          break;          break;
2572    
2573          case PT_LAMP:          case PT_LAMP:
2574          if ((prop->chartype == ucp_Lu ||          if ((prop->chartype == ucp_Lu ||
2575               prop->chartype == ucp_Ll ||               prop->chartype == ucp_Ll ||
2576               prop->chartype == ucp_Lt) == (op == OP_NOTPROP))               prop->chartype == ucp_Lt) == (op == OP_NOTPROP))
2577            MRRETURN(MATCH_NOMATCH);            RRETURN(MATCH_NOMATCH);
2578          break;          break;
2579    
2580          case PT_GC:          case PT_GC:
2581          if ((ecode[2] != _pcre_ucp_gentype[prop->chartype]) == (op == OP_PROP))          if ((ecode[2] != PRIV(ucp_gentype)[prop->chartype]) == (op == OP_PROP))
2582            MRRETURN(MATCH_NOMATCH);            RRETURN(MATCH_NOMATCH);
2583          break;          break;
2584    
2585          case PT_PC:          case PT_PC:
2586          if ((ecode[2] != prop->chartype) == (op == OP_PROP))          if ((ecode[2] != prop->chartype) == (op == OP_PROP))
2587            MRRETURN(MATCH_NOMATCH);            RRETURN(MATCH_NOMATCH);
2588          break;          break;
2589    
2590          case PT_SC:          case PT_SC:
2591          if ((ecode[2] != prop->script) == (op == OP_PROP))          if ((ecode[2] != prop->script) == (op == OP_PROP))
2592            MRRETURN(MATCH_NOMATCH);            RRETURN(MATCH_NOMATCH);
2593          break;          break;
2594    
2595          /* These are specials */          /* These are specials */
2596    
2597          case PT_ALNUM:          case PT_ALNUM:
2598          if ((_pcre_ucp_gentype[prop->chartype] == ucp_L ||          if ((PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
2599               _pcre_ucp_gentype[prop->chartype] == ucp_N) == (op == OP_NOTPROP))               PRIV(ucp_gentype)[prop->chartype] == ucp_N) == (op == OP_NOTPROP))
2600            MRRETURN(MATCH_NOMATCH);            RRETURN(MATCH_NOMATCH);
2601          break;          break;
2602    
2603          case PT_SPACE:    /* Perl space */          case PT_SPACE:    /* Perl space */
2604          if ((_pcre_ucp_gentype[prop->chartype] == ucp_Z ||          if ((PRIV(ucp_gentype)[prop->chartype] == ucp_Z ||
2605               c == CHAR_HT || c == CHAR_NL || c == CHAR_FF || c == CHAR_CR)               c == CHAR_HT || c == CHAR_NL || c == CHAR_FF || c == CHAR_CR)
2606                 == (op == OP_NOTPROP))                 == (op == OP_NOTPROP))
2607            MRRETURN(MATCH_NOMATCH);            RRETURN(MATCH_NOMATCH);
2608          break;          break;
2609    
2610          case PT_PXSPACE:  /* POSIX space */          case PT_PXSPACE:  /* POSIX space */
2611          if ((_pcre_ucp_gentype[prop->chartype] == ucp_Z ||          if ((PRIV(ucp_gentype)[prop->chartype] == ucp_Z ||
2612               c == CHAR_HT || c == CHAR_NL || c == CHAR_VT ||               c == CHAR_HT || c == CHAR_NL || c == CHAR_VT ||
2613               c == CHAR_FF || c == CHAR_CR)               c == CHAR_FF || c == CHAR_CR)
2614                 == (op == OP_NOTPROP))                 == (op == OP_NOTPROP))
2615            MRRETURN(MATCH_NOMATCH);            RRETURN(MATCH_NOMATCH);
2616          break;          break;
2617    
2618          case PT_WORD:          case PT_WORD:
2619          if ((_pcre_ucp_gentype[prop->chartype] == ucp_L ||          if ((PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
2620               _pcre_ucp_gentype[prop->chartype] == ucp_N ||               PRIV(ucp_gentype)[prop->chartype] == ucp_N ||
2621               c == CHAR_UNDERSCORE) == (op == OP_NOTPROP))               c == CHAR_UNDERSCORE) == (op == OP_NOTPROP))
2622            MRRETURN(MATCH_NOMATCH);            RRETURN(MATCH_NOMATCH);
2623          break;          break;
2624    
2625          /* This should never occur */          /* This should never occur */
# Line 2538  for (;;) Line 2639  for (;;)
2639      if (eptr >= md->end_subject)      if (eptr >= md->end_subject)
2640        {        {
2641        SCHECK_PARTIAL();        SCHECK_PARTIAL();
2642        MRRETURN(MATCH_NOMATCH);        RRETURN(MATCH_NOMATCH);
2643        }        }
2644      GETCHARINCTEST(c, eptr);      else
2645      if (UCD_CATEGORY(c) == ucp_M) MRRETURN(MATCH_NOMATCH);        {
2646      while (eptr < md->end_subject)        int lgb, rgb;
2647        {        GETCHARINCTEST(c, eptr);
2648        int len = 1;        lgb = UCD_GRAPHBREAK(c);
2649        if (!utf8) c = *eptr; else { GETCHARLEN(c, eptr, len); }        while (eptr < md->end_subject)
2650        if (UCD_CATEGORY(c) != ucp_M) break;          {
2651        eptr += len;          int len = 1;
2652            if (!utf) c = *eptr; else { GETCHARLEN(c, eptr, len); }
2653            rgb = UCD_GRAPHBREAK(c);
2654            if ((PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0) break;
2655            lgb = rgb;
2656            eptr += len;
2657            }
2658        }        }
2659        CHECK_PARTIAL();
2660      ecode++;      ecode++;
2661      break;      break;
2662  #endif  #endif
# Line 2566  for (;;) Line 2674  for (;;)
2674      case OP_REFI:      case OP_REFI:
2675      caseless = op == OP_REFI;      caseless = op == OP_REFI;
2676      offset = GET2(ecode, 1) << 1;               /* Doubled ref number */      offset = GET2(ecode, 1) << 1;               /* Doubled ref number */
2677      ecode += 3;      ecode += 1 + IMM2_SIZE;
2678    
2679      /* If the reference is unset, there are two possibilities:      /* If the reference is unset, there are two possibilities:
2680    
# Line 2606  for (;;) Line 2714  for (;;)
2714        case OP_CRMINRANGE:        case OP_CRMINRANGE:
2715        minimize = (*ecode == OP_CRMINRANGE);        minimize = (*ecode == OP_CRMINRANGE);
2716        min = GET2(ecode, 1);        min = GET2(ecode, 1);
2717        max = GET2(ecode, 3);        max = GET2(ecode, 1 + IMM2_SIZE);
2718        if (max == 0) max = INT_MAX;        if (max == 0) max = INT_MAX;
2719        ecode += 5;        ecode += 1 + 2 * IMM2_SIZE;
2720        break;        break;
2721    
2722        default:               /* No repeat follows */        default:               /* No repeat follows */
2723        if ((length = match_ref(offset, eptr, length, md, caseless)) < 0)        if ((length = match_ref(offset, eptr, length, md, caseless)) < 0)
2724          {          {
2725            if (length == -2) eptr = md->end_subject;   /* Partial match */
2726          CHECK_PARTIAL();          CHECK_PARTIAL();
2727          MRRETURN(MATCH_NOMATCH);          RRETURN(MATCH_NOMATCH);
2728          }          }
2729        eptr += length;        eptr += length;
2730        continue;              /* With the main loop */        continue;              /* With the main loop */
2731        }        }
2732    
2733      /* Handle repeated back references. If the length of the reference is      /* Handle repeated back references. If the length of the reference is
2734      zero, just continue with the main loop. */      zero, just continue with the main loop. If the length is negative, it
2735        means the reference is unset in non-Java-compatible mode. If the minimum is
2736        zero, we can continue at the same level without recursion. For any other
2737        minimum, carrying on will result in NOMATCH. */
2738    
2739      if (length == 0) continue;      if (length == 0) continue;
2740        if (length < 0 && min == 0) continue;
2741    
2742      /* First, ensure the minimum number of matches are present. We get back      /* First, ensure the minimum number of matches are present. We get back
2743      the length of the reference string explicitly rather than passing the      the length of the reference string explicitly rather than passing the
# Line 2635  for (;;) Line 2748  for (;;)
2748        int slength;        int slength;
2749        if ((slength = match_ref(offset, eptr, length, md, caseless)) < 0)        if ((slength = match_ref(offset, eptr, length, md, caseless)) < 0)
2750          {          {
2751            if (slength == -2) eptr = md->end_subject;   /* Partial match */
2752          CHECK_PARTIAL();          CHECK_PARTIAL();
2753          MRRETURN(MATCH_NOMATCH);          RRETURN(MATCH_NOMATCH);
2754          }          }
2755        eptr += slength;        eptr += slength;
2756        }        }
# Line 2655  for (;;) Line 2769  for (;;)
2769          int slength;          int slength;
2770          RMATCH(eptr, ecode, offset_top, md, eptrb, RM14);          RMATCH(eptr, ecode, offset_top, md, eptrb, RM14);
2771          if (rrc != MATCH_NOMATCH) RRETURN(rrc);          if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2772          if (fi >= max) MRRETURN(MATCH_NOMATCH);          if (fi >= max) RRETURN(MATCH_NOMATCH);
2773          if ((slength = match_ref(offset, eptr, length, md, caseless)) < 0)          if ((slength = match_ref(offset, eptr, length, md, caseless)) < 0)
2774            {            {
2775              if (slength == -2) eptr = md->end_subject;   /* Partial match */
2776            CHECK_PARTIAL();            CHECK_PARTIAL();
2777            MRRETURN(MATCH_NOMATCH);            RRETURN(MATCH_NOMATCH);
2778            }            }
2779          eptr += slength;          eptr += slength;
2780          }          }
# Line 2676  for (;;) Line 2791  for (;;)
2791          int slength;          int slength;
2792          if ((slength = match_ref(offset, eptr, length, md, caseless)) < 0)          if ((slength = match_ref(offset, eptr, length, md, caseless)) < 0)
2793            {            {
2794            CHECK_PARTIAL();            /* Can't use CHECK_PARTIAL because we don't want to update eptr in
2795              the soft partial matching case. */
2796    
2797              if (slength == -2 && md->partial != 0 &&
2798                  md->end_subject > md->start_used_ptr)
2799                {
2800                md->hitend = TRUE;
2801                if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
2802                }
2803            break;            break;
2804            }            }
2805          eptr += slength;          eptr += slength;
2806          }          }
2807    
2808        while (eptr >= pp)        while (eptr >= pp)
2809          {          {
2810          RMATCH(eptr, ecode, offset_top, md, eptrb, RM15);          RMATCH(eptr, ecode, offset_top, md, eptrb, RM15);
2811          if (rrc != MATCH_NOMATCH) RRETURN(rrc);          if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2812          eptr -= length;          eptr -= length;
2813          }          }
2814        MRRETURN(MATCH_NOMATCH);        RRETURN(MATCH_NOMATCH);
2815        }        }
2816      /* Control never gets here */      /* Control never gets here */
2817    
# Line 2705  for (;;) Line 2829  for (;;)
2829      case OP_NCLASS:      case OP_NCLASS:
2830      case OP_CLASS:      case OP_CLASS:
2831        {        {
2832          /* The data variable is saved across frames, so the byte map needs to
2833          be stored there. */
2834    #define BYTE_MAP ((pcre_uint8 *)data)
2835        data = ecode + 1;                /* Save for matching */        data = ecode + 1;                /* Save for matching */
2836        ecode += 33;                     /* Advance past the item */        ecode += 1 + (32 / sizeof(pcre_uchar)); /* Advance past the item */
2837    
2838        switch (*ecode)        switch (*ecode)
2839          {          {
# Line 2727  for (;;) Line 2854  for (;;)
2854          case OP_CRMINRANGE:          case OP_CRMINRANGE:
2855          minimize = (*ecode == OP_CRMINRANGE);          minimize = (*ecode == OP_CRMINRANGE);
2856          min = GET2(ecode, 1);          min = GET2(ecode, 1);
2857          max = GET2(ecode, 3);          max = GET2(ecode, 1 + IMM2_SIZE);
2858          if (max == 0) max = INT_MAX;          if (max == 0) max = INT_MAX;
2859          ecode += 5;          ecode += 1 + 2 * IMM2_SIZE;
2860          break;          break;
2861    
2862          default:               /* No repeat follows */          default:               /* No repeat follows */
# Line 2739  for (;;) Line 2866  for (;;)
2866    
2867        /* First, ensure the minimum number of matches are present. */        /* First, ensure the minimum number of matches are present. */
2868    
2869  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2870        /* UTF-8 mode */        if (utf)
       if (utf8)  
2871          {          {
2872          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
2873            {            {
2874            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
2875              {              {
2876              SCHECK_PARTIAL();              SCHECK_PARTIAL();
2877              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
2878              }              }
2879            GETCHARINC(c, eptr);            GETCHARINC(c, eptr);
2880            if (c > 255)            if (c > 255)
2881              {              {
2882              if (op == OP_CLASS) MRRETURN(MATCH_NOMATCH);              if (op == OP_CLASS) RRETURN(MATCH_NOMATCH);
2883              }              }
2884            else            else
2885              {              if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);
             if ((data[c/8] & (1 << (c&7))) == 0) MRRETURN(MATCH_NOMATCH);  
             }  
2886            }            }
2887          }          }
2888        else        else
2889  #endif  #endif
2890        /* Not UTF-8 mode */        /* Not UTF mode */
2891          {          {
2892          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
2893            {            {
2894            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
2895              {              {
2896              SCHECK_PARTIAL();              SCHECK_PARTIAL();
2897              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
2898              }              }
2899            c = *eptr++;            c = *eptr++;
2900            if ((data[c/8] & (1 << (c&7))) == 0) MRRETURN(MATCH_NOMATCH);  #ifndef COMPILE_PCRE8
2901              if (c > 255)
2902                {
2903                if (op == OP_CLASS) RRETURN(MATCH_NOMATCH);
2904                }
2905              else
2906    #endif
2907                if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);
2908            }            }
2909          }          }
2910    
# Line 2787  for (;;) Line 2918  for (;;)
2918    
2919        if (minimize)        if (minimize)
2920          {          {
2921  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2922          /* UTF-8 mode */          if (utf)
         if (utf8)  
2923            {            {
2924            for (fi = min;; fi++)            for (fi = min;; fi++)
2925              {              {
2926              RMATCH(eptr, ecode, offset_top, md, eptrb, RM16);              RMATCH(eptr, ecode, offset_top, md, eptrb, RM16);
2927              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2928              if (fi >= max) MRRETURN(MATCH_NOMATCH);              if (fi >= max) RRETURN(MATCH_NOMATCH);
2929              if (eptr >= md->end_subject)              if (eptr >= md->end_subject)
2930                {                {
2931                SCHECK_PARTIAL();                SCHECK_PARTIAL();
2932                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
2933                }                }
2934              GETCHARINC(c, eptr);              GETCHARINC(c, eptr);
2935              if (c > 255)              if (c > 255)
2936                {                {
2937                if (op == OP_CLASS) MRRETURN(MATCH_NOMATCH);                if (op == OP_CLASS) RRETURN(MATCH_NOMATCH);
2938                }                }
2939              else              else
2940                {                if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);
               if ((data[c/8] & (1 << (c&7))) == 0) MRRETURN(MATCH_NOMATCH);  
               }  
2941              }              }
2942            }            }
2943          else          else
2944  #endif  #endif
2945          /* Not UTF-8 mode */          /* Not UTF mode */
2946            {            {
2947            for (fi = min;; fi++)            for (fi = min;; fi++)
2948              {              {
2949              RMATCH(eptr, ecode, offset_top, md, eptrb, RM17);              RMATCH(eptr, ecode, offset_top, md, eptrb, RM17);
2950              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2951              if (fi >= max) MRRETURN(MATCH_NOMATCH);              if (fi >= max) RRETURN(MATCH_NOMATCH);
2952              if (eptr >= md->end_subject)              if (eptr >= md->end_subject)
2953                {                {
2954                SCHECK_PARTIAL();                SCHECK_PARTIAL();
2955                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
2956                }                }
2957              c = *eptr++;              c = *eptr++;
2958              if ((data[c/8] & (1 << (c&7))) == 0) MRRETURN(MATCH_NOMATCH);  #ifndef COMPILE_PCRE8
2959                if (c > 255)
2960                  {
2961                  if (op == OP_CLASS) RRETURN(MATCH_NOMATCH);
2962                  }
2963                else
2964    #endif
2965                  if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);
2966              }              }
2967            }            }
2968          /* Control never gets here */          /* Control never gets here */
# Line 2839  for (;;) Line 2974  for (;;)
2974          {          {
2975          pp = eptr;          pp = eptr;
2976    
2977  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2978          /* UTF-8 mode */          if (utf)
         if (utf8)  
2979            {            {
2980            for (i = min; i < max; i++)            for (i = min; i < max; i++)
2981              {              {
# Line 2857  for (;;) Line 2991  for (;;)
2991                if (op == OP_CLASS) break;                if (op == OP_CLASS) break;
2992                }                }
2993              else              else
2994                {                if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) break;
               if ((data[c/8] & (1 << (c&7))) == 0) break;  
               }  
2995              eptr += len;              eptr += len;
2996              }              }
2997            for (;;)            for (;;)
# Line 2872  for (;;) Line 3004  for (;;)
3004            }            }
3005          else          else
3006  #endif  #endif
3007            /* Not UTF-8 mode */            /* Not UTF mode */
3008            {            {
3009            for (i = min; i < max; i++)            for (i = min; i < max; i++)
3010              {              {
# Line 2882  for (;;) Line 3014  for (;;)
3014                break;                break;
3015                }                }
3016              c = *eptr;              c = *eptr;
3017              if ((data[c/8] & (1 << (c&7))) == 0) break;  #ifndef COMPILE_PCRE8
3018                if (c > 255)
3019                  {
3020                  if (op == OP_CLASS) break;
3021                  }
3022                else
3023    #endif
3024                  if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) break;
3025              eptr++;              eptr++;
3026              }              }
3027            while (eptr >= pp)            while (eptr >= pp)
# Line 2893  for (;;) Line 3032  for (;;)
3032              }              }
3033            }            }
3034    
3035          MRRETURN(MATCH_NOMATCH);          RRETURN(MATCH_NOMATCH);
3036          }          }
3037    #undef BYTE_MAP
3038        }        }
3039      /* Control never gets here */      /* Control never gets here */
3040    
# Line 2903  for (;;) Line 3043  for (;;)
3043      when UTF-8 mode mode is supported. Nevertheless, we may not be in UTF-8      when UTF-8 mode mode is supported. Nevertheless, we may not be in UTF-8
3044      mode, because Unicode properties are supported in non-UTF-8 mode. */      mode, because Unicode properties are supported in non-UTF-8 mode. */
3045    
3046  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
3047      case OP_XCLASS:      case OP_XCLASS:
3048        {        {
3049        data = ecode + 1 + LINK_SIZE;                /* Save for matching */        data = ecode + 1 + LINK_SIZE;                /* Save for matching */
# Line 2928  for (;;) Line 3068  for (;;)
3068          case OP_CRMINRANGE:          case OP_CRMINRANGE:
3069          minimize = (*ecode == OP_CRMINRANGE);          minimize = (*ecode == OP_CRMINRANGE);
3070          min = GET2(ecode, 1);          min = GET2(ecode, 1);
3071          max = GET2(ecode, 3);          max = GET2(ecode, 1 + IMM2_SIZE);
3072          if (max == 0) max = INT_MAX;          if (max == 0) max = INT_MAX;
3073          ecode += 5;          ecode += 1 + 2 * IMM2_SIZE;
3074          break;          break;
3075    
3076          default:               /* No repeat follows */          default:               /* No repeat follows */
# Line 2945  for (;;) Line 3085  for (;;)
3085          if (eptr >= md->end_subject)          if (eptr >= md->end_subject)
3086            {            {
3087            SCHECK_PARTIAL();            SCHECK_PARTIAL();
3088            MRRETURN(MATCH_NOMATCH);            RRETURN(MATCH_NOMATCH);
3089            }            }
3090          GETCHARINCTEST(c, eptr);          GETCHARINCTEST(c, eptr);
3091          if (!_pcre_xclass(c, data)) MRRETURN(MATCH_NOMATCH);          if (!PRIV(xclass)(c, data, utf)) RRETURN(MATCH_NOMATCH);
3092          }          }
3093    
3094        /* 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 2965  for (;;) Line 3105  for (;;)
3105            {            {
3106            RMATCH(eptr, ecode, offset_top, md, eptrb, RM20);            RMATCH(eptr, ecode, offset_top, md, eptrb, RM20);
3107            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3108            if (fi >= max) MRRETURN(MATCH_NOMATCH);            if (fi >= max) RRETURN(MATCH_NOMATCH);
3109            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
3110              {              {
3111              SCHECK_PARTIAL();              SCHECK_PARTIAL();
3112              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
3113              }              }
3114            GETCHARINCTEST(c, eptr);            GETCHARINCTEST(c, eptr);
3115            if (!_pcre_xclass(c, data)) MRRETURN(MATCH_NOMATCH);            if (!PRIV(xclass)(c, data, utf)) RRETURN(MATCH_NOMATCH);
3116            }            }
3117          /* Control never gets here */          /* Control never gets here */
3118          }          }
# Line 2990  for (;;) Line 3130  for (;;)
3130              SCHECK_PARTIAL();              SCHECK_PARTIAL();
3131              break;              break;
3132              }              }
3133    #ifdef SUPPORT_UTF
3134            GETCHARLENTEST(c, eptr, len);            GETCHARLENTEST(c, eptr, len);
3135            if (!_pcre_xclass(c, data)) break;  #else
3136              c = *eptr;
3137    #endif
3138              if (!PRIV(xclass)(c, data, utf)) break;
3139            eptr += len;            eptr += len;
3140            }            }
3141          for(;;)          for(;;)
# Line 2999  for (;;) Line 3143  for (;;)
3143            RMATCH(eptr, ecode, offset_top, md, eptrb, RM21);            RMATCH(eptr, ecode, offset_top, md, eptrb, RM21);
3144            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3145            if (eptr-- == pp) break;        /* Stop if tried at original pos */            if (eptr-- == pp) break;        /* Stop if tried at original pos */
3146            if (utf8) BACKCHAR(eptr);  #ifdef SUPPORT_UTF
3147              if (utf) BACKCHAR(eptr);
3148    #endif
3149            }            }
3150          MRRETURN(MATCH_NOMATCH);          RRETURN(MATCH_NOMATCH);
3151          }          }
3152    
3153        /* Control never gets here */        /* Control never gets here */
# Line 3011  for (;;) Line 3157  for (;;)
3157      /* Match a single character, casefully */      /* Match a single character, casefully */
3158    
3159      case OP_CHAR:      case OP_CHAR:
3160  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3161      if (utf8)      if (utf)
3162        {        {
3163        length = 1;        length = 1;
3164        ecode++;        ecode++;
# Line 3020  for (;;) Line 3166  for (;;)
3166        if (length > md->end_subject - eptr)        if (length > md->end_subject - eptr)
3167          {          {
3168          CHECK_PARTIAL();             /* Not SCHECK_PARTIAL() */          CHECK_PARTIAL();             /* Not SCHECK_PARTIAL() */
3169          MRRETURN(MATCH_NOMATCH);          RRETURN(MATCH_NOMATCH);
3170          }          }
3171        while (length-- > 0) if (*ecode++ != *eptr++) MRRETURN(MATCH_NOMATCH);        while (length-- > 0) if (*ecode++ != *eptr++) RRETURN(MATCH_NOMATCH);
3172        }        }
3173      else      else
3174  #endif  #endif
3175        /* Not UTF mode */
     /* Non-UTF-8 mode */  
3176        {        {
3177        if (md->end_subject - eptr < 1)        if (md->end_subject - eptr < 1)
3178          {          {
3179          SCHECK_PARTIAL();            /* This one can use SCHECK_PARTIAL() */          SCHECK_PARTIAL();            /* This one can use SCHECK_PARTIAL() */
3180          MRRETURN(MATCH_NOMATCH);          RRETURN(MATCH_NOMATCH);
3181          }          }
3182        if (ecode[1] != *eptr++) MRRETURN(MATCH_NOMATCH);        if (ecode[1] != *eptr++) RRETURN(MATCH_NOMATCH);
3183        ecode += 2;        ecode += 2;
3184        }        }
3185      break;      break;
3186    
3187      /* Match a single character, caselessly */      /* Match a single character, caselessly. If we are at the end of the
3188        subject, give up immediately. */
3189    
3190      case OP_CHARI:      case OP_CHARI:
3191  #ifdef SUPPORT_UTF8      if (eptr >= md->end_subject)
3192      if (utf8)        {
3193          SCHECK_PARTIAL();
3194          RRETURN(MATCH_NOMATCH);
3195          }
3196    
3197    #ifdef SUPPORT_UTF
3198        if (utf)
3199        {        {
3200        length = 1;        length = 1;
3201        ecode++;        ecode++;
3202        GETCHARLEN(fc, ecode, length);        GETCHARLEN(fc, ecode, length);
3203    
       if (length > md->end_subject - eptr)  
         {  
         CHECK_PARTIAL();             /* Not SCHECK_PARTIAL() */  
         MRRETURN(MATCH_NOMATCH);  
         }  
   
3204        /* 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
3205        can use the fast lookup table. */        we know that its other case must also be one byte long, so we can use the
3206          fast lookup table. We know that there is at least one byte left in the
3207          subject. */
3208    
3209        if (fc < 128)        if (fc < 128)
3210          {          {
3211          if (md->lcc[*ecode++] != md->lcc[*eptr++]) MRRETURN(MATCH_NOMATCH);          if (md->lcc[fc]
3212                != TABLE_GET(*eptr, md->lcc, *eptr)) RRETURN(MATCH_NOMATCH);
3213            ecode++;
3214            eptr++;
3215          }          }
3216    
3217        /* Otherwise we must pick up the subject character */        /* Otherwise we must pick up the subject character. Note that we cannot
3218          use the value of "length" to check for sufficient bytes left, because the
3219          other case of the character may have more or fewer bytes.  */
3220    
3221        else        else
3222          {          {
# Line 3079  for (;;) Line 3232  for (;;)
3232  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3233            if (dc != UCD_OTHERCASE(fc))            if (dc != UCD_OTHERCASE(fc))
3234  #endif  #endif
3235              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
3236            }            }
3237          }          }
3238        }        }
3239      else      else
3240  #endif   /* SUPPORT_UTF8 */  #endif   /* SUPPORT_UTF */
3241    
3242      /* Non-UTF-8 mode */      /* Not UTF mode */
3243        {        {
3244        if (md->end_subject - eptr < 1)        if (TABLE_GET(ecode[1], md->lcc, ecode[1])
3245          {            != TABLE_GET(*eptr, md->lcc, *eptr)) RRETURN(MATCH_NOMATCH);
3246          SCHECK_PARTIAL();            /* This one can use SCHECK_PARTIAL() */        eptr++;
         MRRETURN(MATCH_NOMATCH);  
         }  
       if (md->lcc[ecode[1]] != md->lcc[*eptr++]) MRRETURN(MATCH_NOMATCH);  
3247        ecode += 2;        ecode += 2;
3248        }        }
3249      break;      break;
# Line 3103  for (;;) Line 3253  for (;;)
3253      case OP_EXACT:      case OP_EXACT:
3254      case OP_EXACTI:      case OP_EXACTI:
3255      min = max = GET2(ecode, 1);      min = max = GET2(ecode, 1);
3256      ecode += 3;      ecode += 1 + IMM2_SIZE;
3257      goto REPEATCHAR;      goto REPEATCHAR;
3258    
3259      case OP_POSUPTO:      case OP_POSUPTO:
# Line 3118  for (;;) Line 3268  for (;;)
3268      min = 0;      min = 0;
3269      max = GET2(ecode, 1);      max = GET2(ecode, 1);
3270      minimize = *ecode == OP_MINUPTO || *ecode == OP_MINUPTOI;      minimize = *ecode == OP_MINUPTO || *ecode == OP_MINUPTOI;
3271      ecode += 3;      ecode += 1 + IMM2_SIZE;
3272      goto REPEATCHAR;      goto REPEATCHAR;
3273    
3274      case OP_POSSTAR:      case OP_POSSTAR:
# Line 3166  for (;;) Line 3316  for (;;)
3316      /* Common code for all repeated single-character matches. */      /* Common code for all repeated single-character matches. */
3317    
3318      REPEATCHAR:      REPEATCHAR:
3319  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3320      if (utf8)      if (utf)
3321        {        {
3322        length = 1;        length = 1;
3323        charptr = ecode;        charptr = ecode;
# Line 3183  for (;;) Line 3333  for (;;)
3333          unsigned int othercase;          unsigned int othercase;
3334          if (op >= OP_STARI &&     /* Caseless */          if (op >= OP_STARI &&     /* Caseless */
3335              (othercase = UCD_OTHERCASE(fc)) != fc)              (othercase = UCD_OTHERCASE(fc)) != fc)
3336            oclength = _pcre_ord2utf8(othercase, occhars);            oclength = PRIV(ord2utf)(othercase, occhars);
3337          else oclength = 0;          else oclength = 0;
3338  #endif  /* SUPPORT_UCP */  #endif  /* SUPPORT_UCP */
3339    
3340          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3341            {            {
3342            if (eptr <= md->end_subject - length &&            if (eptr <= md->end_subject - length &&
3343              memcmp(eptr, charptr, length) == 0) eptr += length;              memcmp(eptr, charptr, IN_UCHARS(length)) == 0) eptr += length;
3344  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3345            else if (oclength > 0 &&            else if (oclength > 0 &&
3346                     eptr <= md->end_subject - oclength &&                     eptr <= md->end_subject - oclength &&
3347                     memcmp(eptr, occhars, oclength) == 0) eptr += oclength;                     memcmp(eptr, occhars, IN_UCHARS(oclength)) == 0) eptr += oclength;
3348  #endif  /* SUPPORT_UCP */  #endif  /* SUPPORT_UCP */
3349            else            else
3350              {              {
3351              CHECK_PARTIAL();              CHECK_PARTIAL();
3352              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
3353              }              }
3354            }            }
3355    
# Line 3211  for (;;) Line 3361  for (;;)
3361              {              {
3362              RMATCH(eptr, ecode, offset_top, md, eptrb, RM22);              RMATCH(eptr, ecode, offset_top, md, eptrb, RM22);
3363              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3364              if (fi >= max) MRRETURN(MATCH_NOMATCH);              if (fi >= max) RRETURN(MATCH_NOMATCH);
3365              if (eptr <= md->end_subject - length &&              if (eptr <= md->end_subject - length &&
3366                memcmp(eptr, charptr, length) == 0) eptr += length;                memcmp(eptr, charptr, IN_UCHARS(length)) == 0) eptr += length;
3367  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3368              else if (oclength > 0 &&              else if (oclength > 0 &&
3369                       eptr <= md->end_subject - oclength &&                       eptr <= md->end_subject - oclength &&
3370                       memcmp(eptr, occhars, oclength) == 0) eptr += oclength;                       memcmp(eptr, occhars, IN_UCHARS(oclength)) == 0) eptr += oclength;
3371  #endif  /* SUPPORT_UCP */  #endif  /* SUPPORT_UCP */
3372              else              else
3373                {                {
3374                CHECK_PARTIAL();                CHECK_PARTIAL();
3375                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
3376                }                }
3377              }              }
3378            /* Control never gets here */            /* Control never gets here */
# Line 3234  for (;;) Line 3384  for (;;)
3384            for (i = min; i < max; i++)            for (i = min; i < max; i++)
3385              {              {
3386              if (eptr <= md->end_subject - length &&              if (eptr <= md->end_subject - length &&
3387                  memcmp(eptr, charptr, length) == 0) eptr += length;                  memcmp(eptr, charptr, IN_UCHARS(length)) == 0) eptr += length;
3388  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3389              else if (oclength > 0 &&              else if (oclength > 0 &&
3390                       eptr <= md->end_subject - oclength &&                       eptr <= md->end_subject - oclength &&
3391                       memcmp(eptr, occhars, oclength) == 0) eptr += oclength;                       memcmp(eptr, occhars, IN_UCHARS(oclength)) == 0) eptr += oclength;
3392  #endif  /* SUPPORT_UCP */  #endif  /* SUPPORT_UCP */
3393              else              else
3394                {                {
# Line 3253  for (;;) Line 3403  for (;;)
3403              {              {
3404              RMATCH(eptr, ecode, offset_top, md, eptrb, RM23);              RMATCH(eptr, ecode, offset_top, md, eptrb, RM23);
3405              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3406              if (eptr == pp) { MRRETURN(MATCH_NOMATCH); }              if (eptr == pp) { RRETURN(MATCH_NOMATCH); }
3407  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3408              eptr--;              eptr--;
3409              BACKCHAR(eptr);              BACKCHAR(eptr);
# Line 3270  for (;;) Line 3420  for (;;)
3420        value of fc will always be < 128. */        value of fc will always be < 128. */
3421        }        }
3422      else      else
3423  #endif  /* SUPPORT_UTF8 */  #endif  /* SUPPORT_UTF */
3424          /* When not in UTF-8 mode, load a single-byte character. */
3425          fc = *ecode++;
3426    
3427      /* When not in UTF-8 mode, load a single-byte character. */      /* The value of fc at this point is always one character, though we may
3428        or may not be in UTF mode. The code is duplicated for the caseless and
     fc = *ecode++;  
   
     /* The value of fc at this point is always less than 256, though we may or  
     may not be in UTF-8 mode. The code is duplicated for the caseless and  
3429      caseful cases, for speed, since matching characters is likely to be quite      caseful cases, for speed, since matching characters is likely to be quite
3430      common. First, ensure the minimum number of matches are present. If min =      common. First, ensure the minimum number of matches are present. If min =
3431      max, continue at the same level without recursing. Otherwise, if      max, continue at the same level without recursing. Otherwise, if
# Line 3286  for (;;) Line 3434  for (;;)
3434      maximizing, find the maximum number of characters and work backwards. */      maximizing, find the maximum number of characters and work backwards. */
3435    
3436      DPRINTF(("matching %c{%d,%d} against subject %.*s\n", fc, min, max,      DPRINTF(("matching %c{%d,%d} against subject %.*s\n", fc, min, max,
3437        max, eptr));        max, (char *)eptr));
3438    
3439      if (op >= OP_STARI)  /* Caseless */      if (op >= OP_STARI)  /* Caseless */
3440        {        {
3441        fc = md->lcc[fc];  #ifdef COMPILE_PCRE8
3442          /* fc must be < 128 if UTF is enabled. */
3443          foc = md->fcc[fc];
3444    #else
3445    #ifdef SUPPORT_UTF
3446    #ifdef SUPPORT_UCP
3447          if (utf && fc > 127)
3448            foc = UCD_OTHERCASE(fc);
3449    #else
3450          if (utf && fc > 127)
3451            foc = fc;
3452    #endif /* SUPPORT_UCP */
3453          else
3454    #endif /* SUPPORT_UTF */
3455            foc = TABLE_GET(fc, md->fcc, fc);
3456    #endif /* COMPILE_PCRE8 */
3457    
3458        for (i = 1; i <= min; i++)        for (i = 1; i <= min; i++)
3459          {          {
3460          if (eptr >= md->end_subject)          if (eptr >= md->end_subject)
3461            {            {
3462            SCHECK_PARTIAL();            SCHECK_PARTIAL();
3463            MRRETURN(MATCH_NOMATCH);            RRETURN(MATCH_NOMATCH);
3464            }            }
3465          if (fc != md->lcc[*eptr++]) MRRETURN(MATCH_NOMATCH);          if (fc != *eptr && foc != *eptr) RRETURN(MATCH_NOMATCH);
3466            eptr++;
3467          }          }
3468        if (min == max) continue;        if (min == max) continue;
3469        if (minimize)        if (minimize)
# Line 3307  for (;;) Line 3472  for (;;)
3472            {            {
3473            RMATCH(eptr, ecode, offset_top, md, eptrb, RM24);            RMATCH(eptr, ecode, offset_top, md, eptrb, RM24);
3474            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3475            if (fi >= max) MRRETURN(MATCH_NOMATCH);            if (fi >= max) RRETURN(MATCH_NOMATCH);
3476            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
3477              {              {
3478              SCHECK_PARTIAL();              SCHECK_PARTIAL();
3479              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
3480              }              }
3481            if (fc != md->lcc[*eptr++]) MRRETURN(MATCH_NOMATCH);            if (fc != *eptr && foc != *eptr) RRETURN(MATCH_NOMATCH);
3482              eptr++;
3483            }            }
3484          /* Control never gets here */          /* Control never gets here */
3485          }          }
# Line 3327  for (;;) Line 3493  for (;;)
3493              SCHECK_PARTIAL();              SCHECK_PARTIAL();
3494              break;              break;
3495              }              }
3496            if (fc != md->lcc[*eptr]) break;            if (fc != *eptr && foc != *eptr) break;
3497            eptr++;            eptr++;
3498            }            }
3499    
# Line 3339  for (;;) Line 3505  for (;;)
3505            eptr--;            eptr--;
3506            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3507            }            }
3508          MRRETURN(MATCH_NOMATCH);          RRETURN(MATCH_NOMATCH);
3509          }          }
3510        /* Control never gets here */        /* Control never gets here */
3511        }        }
# Line 3353  for (;;) Line 3519  for (;;)
3519          if (eptr >= md->end_subject)          if (eptr >= md->end_subject)
3520            {            {
3521            SCHECK_PARTIAL();            SCHECK_PARTIAL();
3522            MRRETURN(MATCH_NOMATCH);            RRETURN(MATCH_NOMATCH);
3523            }            }
3524          if (fc != *eptr++) MRRETURN(MATCH_NOMATCH);          if (fc != *eptr++) RRETURN(MATCH_NOMATCH);
3525          }          }
3526    
3527        if (min == max) continue;        if (min == max) continue;
# Line 3366  for (;;) Line 3532  for (;;)
3532            {            {
3533            RMATCH(eptr, ecode, offset_top, md, eptrb, RM26);            RMATCH(eptr, ecode, offset_top, md, eptrb, RM26);
3534            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3535            if (fi >= max) MRRETURN(MATCH_NOMATCH);            if (fi >= max) RRETURN(MATCH_NOMATCH);
3536            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
3537              {              {
3538              SCHECK_PARTIAL();              SCHECK_PARTIAL();
3539              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
3540              }              }
3541            if (fc != *eptr++) MRRETURN(MATCH_NOMATCH);            if (fc != *eptr++) RRETURN(MATCH_NOMATCH);
3542            }            }
3543          /* Control never gets here */          /* Control never gets here */
3544          }          }
# Line 3397  for (;;) Line 3563  for (;;)
3563            eptr--;            eptr--;
3564            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3565            }            }
3566          MRRETURN(MATCH_NOMATCH);          RRETURN(MATCH_NOMATCH);
3567          }          }
3568        }        }
3569      /* Control never gets here */      /* Control never gets here */
# Line 3410  for (;;) Line 3576  for (;;)
3576      if (eptr >= md->end_subject)      if (eptr >= md->end_subject)
3577        {        {
3578        SCHECK_PARTIAL();        SCHECK_PARTIAL();
3579        MRRETURN(MATCH_NOMATCH);        RRETURN(MATCH_NOMATCH);
3580        }        }
3581      ecode++;  #ifdef SUPPORT_UTF
3582      GETCHARINCTEST(c, eptr);      if (utf)
     if (op == OP_NOTI)         /* The caseless case */  
3583        {        {
3584  #ifdef SUPPORT_UTF8        register unsigned int ch, och;
3585        if (c < 256)  
3586  #endif        ecode++;
3587        c = md->lcc[c];        GETCHARINC(ch, ecode);
3588        if (md->lcc[*ecode++] == c) MRRETURN(MATCH_NOMATCH);        GETCHARINC(c, eptr);
3589    
3590          if (op == OP_NOT)
3591            {
3592            if (ch == c) RRETURN(MATCH_NOMATCH);
3593            }
3594          else
3595            {
3596    #ifdef SUPPORT_UCP
3597            if (ch > 127)
3598              och = UCD_OTHERCASE(ch);
3599    #else
3600            if (ch > 127)
3601              och = ch;
3602    #endif /* SUPPORT_UCP */
3603            else
3604              och = TABLE_GET(ch, md->fcc, ch);
3605            if (ch == c || och == c) RRETURN(MATCH_NOMATCH);
3606            }
3607        }        }
3608      else    /* Caseful */      else
3609    #endif
3610        {        {
3611        if (*ecode++ == c) MRRETURN(MATCH_NOMATCH);        register unsigned int ch = ecode[1];
3612          c = *eptr++;
3613          if (ch == c || (op == OP_NOTI && TABLE_GET(ch, md->fcc, ch) == c))
3614            RRETURN(MATCH_NOMATCH);
3615          ecode += 2;
3616        }        }
3617      break;      break;
3618    
# Line 3438  for (;;) Line 3626  for (;;)
3626      case OP_NOTEXACT:      case OP_NOTEXACT:
3627      case OP_NOTEXACTI:      case OP_NOTEXACTI:
3628      min = max = GET2(ecode, 1);      min = max = GET2(ecode, 1);
3629      ecode += 3;      ecode += 1 + IMM2_SIZE;
3630      goto REPEATNOTCHAR;      goto REPEATNOTCHAR;
3631    
3632      case OP_NOTUPTO:      case OP_NOTUPTO:
# Line 3448  for (;;) Line 3636  for (;;)
3636      min = 0;      min = 0;
3637      max = GET2(ecode, 1);      max = GET2(ecode, 1);
3638      minimize = *ecode == OP_NOTMINUPTO || *ecode == OP_NOTMINUPTOI;      minimize = *ecode == OP_NOTMINUPTO || *ecode == OP_NOTMINUPTOI;
3639      ecode += 3;      ecode += 1 + IMM2_SIZE;
3640      goto REPEATNOTCHAR;      goto REPEATNOTCHAR;
3641    
3642      case OP_NOTPOSSTAR:      case OP_NOTPOSSTAR:
# Line 3480  for (;;) Line 3668  for (;;)
3668      possessive = TRUE;      possessive = TRUE;
3669      min = 0;      min = 0;
3670      max = GET2(ecode, 1);      max = GET2(ecode, 1);
3671      ecode += 3;      ecode += 1 + IMM2_SIZE;
3672      goto REPEATNOTCHAR;      goto REPEATNOTCHAR;
3673    
3674      case OP_NOTSTAR:      case OP_NOTSTAR:
# Line 3504  for (;;) Line 3692  for (;;)
3692      /* Common code for all repeated single-byte matches. */      /* Common code for all repeated single-byte matches. */
3693    
3694      REPEATNOTCHAR:      REPEATNOTCHAR:
3695      fc = *ecode++;      GETCHARINCTEST(fc, ecode);
3696    
3697      /* The code is duplicated for the caseless and caseful cases, for speed,      /* The code is duplicated for the caseless and caseful cases, for speed,
3698      since matching characters is likely to be quite common. First, ensure the      since matching characters is likely to be quite common. First, ensure the
# Line 3515  for (;;) Line 3703  for (;;)
3703      characters and work backwards. */      characters and work backwards. */
3704    
3705      DPRINTF(("negative matching %c{%d,%d} against subject %.*s\n", fc, min, max,      DPRINTF(("negative matching %c{%d,%d} against subject %.*s\n", fc, min, max,
3706        max, eptr));        max, (char *)eptr));
3707    
3708      if (op >= OP_NOTSTARI)     /* Caseless */      if (op >= OP_NOTSTARI)     /* Caseless */
3709        {        {
3710        fc = md->lcc[fc];  #ifdef SUPPORT_UTF
3711    #ifdef SUPPORT_UCP
3712          if (utf && fc > 127)
3713            foc = UCD_OTHERCASE(fc);
3714    #else
3715          if (utf && fc > 127)
3716            foc = fc;
3717    #endif /* SUPPORT_UCP */
3718          else
3719    #endif /* SUPPORT_UTF */
3720            foc = TABLE_GET(fc, md->fcc, fc);
3721    
3722  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3723        /* UTF-8 mode */        if (utf)
       if (utf8)  
3724          {          {
3725          register unsigned int d;          register unsigned int d;
3726          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
# Line 3531  for (;;) Line 3728  for (;;)
3728            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
3729              {              {
3730              SCHECK_PARTIAL();              SCHECK_PARTIAL();
3731              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
3732              }              }
3733            GETCHARINC(d, eptr);            GETCHARINC(d, eptr);
3734            if (d < 256) d = md->lcc[d];            if (fc == d || (unsigned int)foc == d) RRETURN(MATCH_NOMATCH);
           if (fc == d) MRRETURN(MATCH_NOMATCH);  
3735            }            }
3736          }          }
3737        else        else
3738  #endif  #endif
3739          /* Not UTF mode */
       /* Not UTF-8 mode */  
3740          {          {
3741          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3742            {            {
3743            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
3744              {              {
3745              SCHECK_PARTIAL();              SCHECK_PARTIAL();
3746              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
3747              }              }
3748            if (fc == md->lcc[*eptr++]) MRRETURN(MATCH_NOMATCH);            if (fc == *eptr || foc == *eptr) RRETURN(MATCH_NOMATCH);
3749              eptr++;
3750            }            }
3751          }          }
3752    
# Line 3558  for (;;) Line 3754  for (;;)
3754    
3755        if (minimize)        if (minimize)
3756          {          {
3757  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3758          /* UTF-8 mode */          if (utf)
         if (utf8)  
3759            {            {
3760            register unsigned int d;            register unsigned int d;
3761            for (fi = min;; fi++)            for (fi = min;; fi++)
3762              {              {
3763              RMATCH(eptr, ecode, offset_top, md, eptrb, RM28);              RMATCH(eptr, ecode, offset_top, md, eptrb, RM28);
3764              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3765              if (fi >= max) MRRETURN(MATCH_NOMATCH);              if (fi >= max) RRETURN(MATCH_NOMATCH);
3766              if (eptr >= md->end_subject)              if (eptr >= md->end_subject)
3767                {                {
3768                SCHECK_PARTIAL();                SCHECK_PARTIAL();
3769                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
3770                }                }
3771              GETCHARINC(d, eptr);              GETCHARINC(d, eptr);
3772              if (d < 256) d = md->lcc[d];              if (fc == d || (unsigned int)foc == d) RRETURN(MATCH_NOMATCH);
             if (fc == d) MRRETURN(MATCH_NOMATCH);  
3773              }              }
3774            }            }
3775          else          else
3776  #endif  #endif
3777          /* Not UTF-8 mode */          /* Not UTF mode */
3778            {            {
3779            for (fi = min;; fi++)            for (fi = min;; fi++)
3780              {              {
3781              RMATCH(eptr, ecode, offset_top, md, eptrb, RM29);              RMATCH(eptr, ecode, offset_top, md, eptrb, RM29);
3782              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3783              if (fi >= max) MRRETURN(MATCH_NOMATCH);              if (fi >= max) RRETURN(MATCH_NOMATCH);
3784              if (eptr >= md->end_subject)              if (eptr >= md->end_subject)
3785                {                {
3786                SCHECK_PARTIAL();                SCHECK_PARTIAL();
3787                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
3788                }                }
3789              if (fc == md->lcc[*eptr++]) MRRETURN(MATCH_NOMATCH);              if (fc == *eptr || foc == *eptr) RRETURN(MATCH_NOMATCH);
3790                eptr++;
3791              }              }
3792            }            }
3793          /* Control never gets here */          /* Control never gets here */
# Line 3604  for (;;) Line 3799  for (;;)
3799          {          {
3800          pp = eptr;          pp = eptr;
3801    
3802  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3803          /* UTF-8 mode */          if (utf)
         if (utf8)  
3804            {            {
3805            register unsigned int d;            register unsigned int d;
3806            for (i = min; i < max; i++)            for (i = min; i < max; i++)
# Line 3618  for (;;) Line 3812  for (;;)
3812                break;                break;
3813                }                }
3814              GETCHARLEN(d, eptr, len);              GETCHARLEN(d, eptr, len);
3815              if (d < 256) d = md->lcc[d];              if (fc == d || (unsigned int)foc == d) break;
             if (fc == d) break;  
3816              eptr += len;              eptr += len;
3817              }              }
3818          if (possessive) continue;            if (possessive) continue;
3819          for(;;)            for(;;)
3820              {              {
3821              RMATCH(eptr, ecode, offset_top, md, eptrb, RM30);              RMATCH(eptr, ecode, offset_top, md, eptrb, RM30);
3822              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
# Line 3633  for (;;) Line 3826  for (;;)
3826            }            }
3827          else          else
3828  #endif  #endif
3829          /* Not UTF-8 mode */          /* Not UTF mode */
3830            {            {
3831            for (i = min; i < max; i++)            for (i = min; i < max; i++)
3832              {              {
# Line 3642  for (;;) Line 3835  for (;;)
3835                SCHECK_PARTIAL();                SCHECK_PARTIAL();
3836                break;                break;
3837                }                }
3838              if (fc == md->lcc[*eptr]) break;              if (fc == *eptr || foc == *eptr) break;
3839              eptr++;              eptr++;
3840              }              }
3841            if (possessive) continue;            if (possessive) continue;
# Line 3654  for (;;) Line 3847  for (;;)
3847              }              }
3848            }            }
3849    
3850          MRRETURN(MATCH_NOMATCH);          RRETURN(MATCH_NOMATCH);
3851          }          }
3852        /* Control never gets here */        /* Control never gets here */
3853        }        }
# Line 3663  for (;;) Line 3856  for (;;)
3856    
3857      else      else
3858        {        {
3859  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3860        /* UTF-8 mode */        if (utf)
       if (utf8)  
3861          {          {
3862          register unsigned int d;          register unsigned int d;
3863          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
# Line 3673  for (;;) Line 3865  for (;;)
3865            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
3866              {              {
3867              SCHECK_PARTIAL();              SCHECK_PARTIAL();
3868              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
3869              }              }
3870            GETCHARINC(d, eptr);            GETCHARINC(d, eptr);
3871            if (fc == d) MRRETURN(MATCH_NOMATCH);            if (fc == d) RRETURN(MATCH_NOMATCH);
3872            }            }
3873          }          }
3874        else        else
3875  #endif  #endif
3876        /* Not UTF-8 mode */        /* Not UTF mode */
3877          {          {
3878          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3879            {            {
3880            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
3881              {              {
3882              SCHECK_PARTIAL();              SCHECK_PARTIAL();
3883              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
3884              }              }
3885            if (fc == *eptr++) MRRETURN(MATCH_NOMATCH);            if (fc == *eptr++) RRETURN(MATCH_NOMATCH);
3886            }            }
3887          }          }
3888    
# Line 3698  for (;;) Line 3890  for (;;)
3890    
3891        if (minimize)        if (minimize)
3892          {          {
3893  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3894          /* UTF-8 mode */          if (utf)
         if (utf8)  
3895            {            {
3896            register unsigned int d;            register unsigned int d;
3897            for (fi = min;; fi++)            for (fi = min;; fi++)
3898              {              {
3899              RMATCH(eptr, ecode, offset_top, md, eptrb, RM32);              RMATCH(eptr, ecode, offset_top, md, eptrb, RM32);
3900              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3901              if (fi >= max) MRRETURN(MATCH_NOMATCH);              if (fi >= max) RRETURN(MATCH_NOMATCH);
3902              if (eptr >= md->end_subject)              if (eptr >= md->end_subject)
3903                {                {
3904                SCHECK_PARTIAL();                SCHECK_PARTIAL();
3905                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
3906                }                }
3907              GETCHARINC(d, eptr);              GETCHARINC(d, eptr);
3908              if (fc == d) MRRETURN(MATCH_NOMATCH);              if (fc == d) RRETURN(MATCH_NOMATCH);
3909              }              }
3910            }            }
3911          else          else
3912  #endif  #endif
3913          /* Not UTF-8 mode */          /* Not UTF mode */
3914            {            {
3915            for (fi = min;; fi++)            for (fi = min;; fi++)
3916              {              {
3917              RMATCH(eptr, ecode, offset_top, md, eptrb, RM33);              RMATCH(eptr, ecode, offset_top, md, eptrb, RM33);
3918              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3919              if (fi >= max) MRRETURN(MATCH_NOMATCH);              if (fi >= max) RRETURN(MATCH_NOMATCH);
3920              if (eptr >= md->end_subject)              if (eptr >= md->end_subject)
3921                {                {
3922                SCHECK_PARTIAL();                SCHECK_PARTIAL();
3923                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
3924                }                }
3925              if (fc == *eptr++) MRRETURN(MATCH_NOMATCH);              if (fc == *eptr++) RRETURN(MATCH_NOMATCH);
3926              }              }
3927            }            }
3928          /* Control never gets here */          /* Control never gets here */
# Line 3743  for (;;) Line 3934  for (;;)
3934          {          {
3935          pp = eptr;          pp = eptr;
3936    
3937  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3938          /* UTF-8 mode */          if (utf)
         if (utf8)  
3939            {            {
3940            register unsigned int d;            register unsigned int d;
3941            for (i = min; i < max; i++)            for (i = min; i < max; i++)
# Line 3771  for (;;) Line 3961  for (;;)
3961            }            }
3962          else          else
3963  #endif  #endif
3964          /* Not UTF-8 mode */          /* Not UTF mode */
3965            {            {
3966            for (i = min; i < max; i++)            for (i = min; i < max; i++)
3967              {              {
# Line 3792  for (;;) Line 3982  for (;;)
3982              }              }
3983            }            }
3984    
3985          MRRETURN(MATCH_NOMATCH);          RRETURN(MATCH_NOMATCH);
3986          }          }
3987        }        }
3988      /* Control never gets here */      /* Control never gets here */
# Line 3804  for (;;) Line 3994  for (;;)
3994      case OP_TYPEEXACT:      case OP_TYPEEXACT:
3995      min = max = GET2(ecode, 1);      min = max = GET2(ecode, 1);
3996      minimize = TRUE;      minimize = TRUE;
3997      ecode += 3;      ecode += 1 + IMM2_SIZE;
3998      goto REPEATTYPE;      goto REPEATTYPE;
3999    
4000      case OP_TYPEUPTO:      case OP_TYPEUPTO:
# Line 3812  for (;;) Line 4002  for (;;)
4002      min = 0;      min = 0;
4003      max = GET2(ecode, 1);      max = GET2(ecode, 1);
4004      minimize = *ecode == OP_TYPEMINUPTO;      minimize = *ecode == OP_TYPEMINUPTO;
4005      ecode += 3;      ecode += 1 + IMM2_SIZE;
4006      goto REPEATTYPE;      goto REPEATTYPE;
4007    
4008      case OP_TYPEPOSSTAR:      case OP_TYPEPOSSTAR:
# Line 3840  for (;;) Line 4030  for (;;)
4030      possessive = TRUE;      possessive = TRUE;
4031      min = 0;      min = 0;
4032      max = GET2(ecode, 1);      max = GET2(ecode, 1);
4033      ecode += 3;      ecode += 1 + IMM2_SIZE;
4034      goto REPEATTYPE;      goto REPEATTYPE;
4035    
4036      case OP_TYPESTAR:      case OP_TYPESTAR:
# Line 3886  for (;;) Line 4076  for (;;)
4076          switch(prop_type)          switch(prop_type)
4077            {            {
4078            case PT_ANY:            case PT_ANY:
4079            if (prop_fail_result) MRRETURN(MATCH_NOMATCH);            if (prop_fail_result) RRETURN(MATCH_NOMATCH);
4080            for (i = 1; i <= min; i++)            for (i = 1; i <= min; i++)
4081              {              {
4082              if (eptr >= md->end_subject)              if (eptr >= md->end_subject)
4083                {                {
4084                SCHECK_PARTIAL();                SCHECK_PARTIAL();
4085                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4086                }                }
4087              GETCHARINCTEST(c, eptr);              GETCHARINCTEST(c, eptr);
4088              }              }
# Line 3905  for (;;) Line 4095  for (;;)
4095              if (eptr >= md->end_subject)              if (eptr >= md->end_subject)
4096                {                {
4097                SCHECK_PARTIAL();                SCHECK_PARTIAL();
4098                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4099                }                }
4100              GETCHARINCTEST(c, eptr);              GETCHARINCTEST(c, eptr);
4101              chartype = UCD_CHARTYPE(c);              chartype = UCD_CHARTYPE(c);
4102              if ((chartype == ucp_Lu ||              if ((chartype == ucp_Lu ||
4103                   chartype == ucp_Ll ||                   chartype == ucp_Ll ||
4104                   chartype == ucp_Lt) == prop_fail_result)                   chartype == ucp_Lt) == prop_fail_result)
4105                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4106              }              }
4107            break;            break;
4108    
# Line 3922  for (;;) Line 4112  for (;;)
4112              if (eptr >= md->end_subject)              if (eptr >= md->end_subject)
4113                {                {
4114                SCHECK_PARTIAL();                SCHECK_PARTIAL();
4115                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4116                }                }
4117              GETCHARINCTEST(c, eptr);              GETCHARINCTEST(c, eptr);
4118              if ((UCD_CATEGORY(c) == prop_value) == prop_fail_result)              if ((UCD_CATEGORY(c) == prop_value) == prop_fail_result)
4119                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4120              }              }
4121            break;            break;
4122    
# Line 3936  for (;;) Line 4126  for (;;)
4126              if (eptr >= md->end_subject)              if (eptr >= md->end_subject)
4127                {                {
4128                SCHECK_PARTIAL();                SCHECK_PARTIAL();
4129                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4130                }                }
4131              GETCHARINCTEST(c, eptr);              GETCHARINCTEST(c, eptr);
4132              if ((UCD_CHARTYPE(c) == prop_value) == prop_fail_result)              if ((UCD_CHARTYPE(c) == prop_value) == prop_fail_result)
4133                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4134              }              }
4135            break;            break;
4136    
# Line 3950  for (;;) Line 4140  for (;;)
4140              if (eptr >= md->end_subject)              if (eptr >= md->end_subject)
4141                {                {
4142                SCHECK_PARTIAL();                SCHECK_PARTIAL();
4143                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4144                }                }
4145              GETCHARINCTEST(c, eptr);              GETCHARINCTEST(c, eptr);
4146              if ((UCD_SCRIPT(c) == prop_value) == prop_fail_result)              if ((UCD_SCRIPT(c) == prop_value) == prop_fail_result)
4147                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4148              }              }
4149            break;            break;
4150    
# Line 3965  for (;;) Line 4155  for (;;)
4155              if (eptr >= md->end_subject)              if (eptr >= md->end_subject)
4156                {                {
4157                SCHECK_PARTIAL();                SCHECK_PARTIAL();
4158                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4159                }                }
4160              GETCHARINCTEST(c, eptr);              GETCHARINCTEST(c, eptr);
4161              category = UCD_CATEGORY(c);              category = UCD_CATEGORY(c);
4162              if ((category == ucp_L || category == ucp_N) == prop_fail_result)              if ((category == ucp_L || category == ucp_N) == prop_fail_result)
4163                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4164              }              }
4165            break;            break;
4166    
# Line 3980  for (;;) Line 4170  for (;;)
4170              if (eptr >= md->end_subject)              if (eptr >= md->end_subject)
4171                {                {
4172                SCHECK_PARTIAL();                SCHECK_PARTIAL();
4173                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4174                }                }
4175              GETCHARINCTEST(c, eptr);              GETCHARINCTEST(c, eptr);
4176              if ((UCD_CATEGORY(c) == ucp_Z || c == CHAR_HT || c == CHAR_NL ||              if ((UCD_CATEGORY(c) == ucp_Z || c == CHAR_HT || c == CHAR_NL ||
4177                   c == CHAR_FF || c == CHAR_CR)                   c == CHAR_FF || c == CHAR_CR)
4178                     == prop_fail_result)                     == prop_fail_result)
4179                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4180              }              }
4181            break;            break;
4182    
# Line 3996  for (;;) Line 4186  for (;;)
4186              if (eptr >= md->end_subject)              if (eptr >= md->end_subject)
4187                {                {
4188                SCHECK_PARTIAL();                SCHECK_PARTIAL();
4189                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4190                }                }
4191              GETCHARINCTEST(c, eptr);              GETCHARINCTEST(c, eptr);
4192              if ((UCD_CATEGORY(c) == ucp_Z || c == CHAR_HT || c == CHAR_NL ||              if ((UCD_CATEGORY(c) == ucp_Z || c == CHAR_HT || c == CHAR_NL ||
4193                   c == CHAR_VT || c == CHAR_FF || c == CHAR_CR)                   c == CHAR_VT || c == CHAR_FF || c == CHAR_CR)
4194                     == prop_fail_result)                     == prop_fail_result)
4195                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4196              }              }
4197            break;            break;
4198    
# Line 4013  for (;;) Line 4203  for (;;)
4203              if (eptr >= md->end_subject)              if (eptr >= md->end_subject)
4204                {                {
4205                SCHECK_PARTIAL();                SCHECK_PARTIAL();
4206                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4207                }                }
4208              GETCHARINCTEST(c, eptr);              GETCHARINCTEST(c, eptr);
4209              category = UCD_CATEGORY(c);              category = UCD_CATEGORY(c);
4210              if ((category == ucp_L || category == ucp_N || c == CHAR_UNDERSCORE)              if ((category == ucp_L || category == ucp_N || c == CHAR_UNDERSCORE)
4211                     == prop_fail_result)                     == prop_fail_result)
4212                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4213              }              }
4214            break;            break;
4215    
# Line 4040  for (;;) Line 4230  for (;;)
4230            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4231              {              {
4232              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4233              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4234              }              }
4235            GETCHARINCTEST(c, eptr);            else
4236            if (UCD_CATEGORY(c) == ucp_M) MRRETURN(MATCH_NOMATCH);              {
4237            while (eptr < md->end_subject)              int lgb, rgb;
4238              {              GETCHARINCTEST(c, eptr);
4239              int len = 1;              lgb = UCD_GRAPHBREAK(c);
4240              if (!utf8) c = *eptr; else { GETCHARLEN(c, eptr, len); }             while (eptr < md->end_subject)
4241              if (UCD_CATEGORY(c) != ucp_M) break;                {
4242              eptr += len;                int len = 1;
4243                  if (!utf) c = *eptr; else { GETCHARLEN(c, eptr, len); }
4244                  rgb = UCD_GRAPHBREAK(c);
4245                  if ((PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0) break;
4246                  lgb = rgb;
4247                  eptr += len;
4248                  }
4249              }              }
4250              CHECK_PARTIAL();
4251            }            }
4252          }          }
4253    
# Line 4059  for (;;) Line 4256  for (;;)
4256    
4257  /* Handle all other cases when the coding is UTF-8 */  /* Handle all other cases when the coding is UTF-8 */
4258    
4259  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
4260        if (utf8) switch(ctype)        if (utf) switch(ctype)
4261          {          {
4262          case OP_ANY:          case OP_ANY:
4263          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
# Line 4068  for (;;) Line 4265  for (;;)
4265            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4266              {              {
4267              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4268              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4269                }
4270              if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH);
4271              if (md->partial != 0 &&
4272                  eptr + 1 >= md->end_subject &&
4273                  NLBLOCK->nltype == NLTYPE_FIXED &&
4274                  NLBLOCK->nllen == 2 &&
4275                  *eptr == NLBLOCK->nl[0])
4276                {
4277                md->hitend = TRUE;
4278                if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
4279              }              }
           if (IS_NEWLINE(eptr)) MRRETURN(MATCH_NOMATCH);  
4280            eptr++;            eptr++;
4281            while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;            ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
4282            }            }
4283          break;          break;
4284    
# Line 4082  for (;;) Line 4288  for (;;)
4288            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4289              {              {
4290              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4291              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4292              }              }
4293            eptr++;            eptr++;
4294            while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;            ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
4295            }            }
4296          break;          break;
4297    
4298          case OP_ANYBYTE:          case OP_ANYBYTE:
4299          if (eptr > md->end_subject - min) MRRETURN(MATCH_NOMATCH);          if (eptr > md->end_subject - min) RRETURN(MATCH_NOMATCH);
4300          eptr += min;          eptr += min;
4301          break;          break;
4302    
# Line 4100  for (;;) Line 4306  for (;;)
4306            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4307              {              {
4308              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4309              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4310              }              }
4311            GETCHARINC(c, eptr);            GETCHARINC(c, eptr);
4312            switch(c)            switch(c)
4313              {              {
4314              default: MRRETURN(MATCH_NOMATCH);              default: RRETURN(MATCH_NOMATCH);
4315    
4316              case 0x000d:              case 0x000d:
4317              if (eptr < md->end_subject && *eptr == 0x0a) eptr++;              if (eptr < md->end_subject && *eptr == 0x0a) eptr++;
# Line 4119  for (;;) Line 4325  for (;;)
4325              case 0x0085:              case 0x0085:
4326              case 0x2028:              case 0x2028:
4327              case 0x2029:              case 0x2029:
4328              if (md->bsr_anycrlf) MRRETURN(MATCH_NOMATCH);              if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH);
4329              break;              break;
4330              }              }
4331            }            }
# Line 4131  for (;;) Line 4337  for (;;)
4337            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4338              {              {
4339              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4340              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4341              }              }
4342            GETCHARINC(c, eptr);            GETCHARINC(c, eptr);
4343            switch(c)            switch(c)
# Line 4156  for (;;) Line 4362  for (;;)
4362              case 0x202f:    /* NARROW NO-BREAK SPACE */              case 0x202f:    /* NARROW NO-BREAK SPACE */
4363              case 0x205f:    /* MEDIUM MATHEMATICAL SPACE */              case 0x205f:    /* MEDIUM MATHEMATICAL SPACE */
4364              case 0x3000:    /* IDEOGRAPHIC SPACE */              case 0x3000:    /* IDEOGRAPHIC SPACE */
4365              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4366              }              }
4367            }            }
4368          break;          break;
# Line 4167  for (;;) Line 4373  for (;;)
4373            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4374              {              {
4375              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4376              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4377              }              }
4378            GETCHARINC(c, eptr);            GETCHARINC(c, eptr);
4379            switch(c)            switch(c)
4380              {              {
4381              default: MRRETURN(MATCH_NOMATCH);              default: RRETURN(MATCH_NOMATCH);
4382              case 0x09:      /* HT */              case 0x09:      /* HT */
4383              case 0x20:      /* SPACE */              case 0x20:      /* SPACE */
4384              case 0xa0:      /* NBSP */              case 0xa0:      /* NBSP */
# Line 4203  for (;;) Line 4409  for (;;)
4409            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4410              {              {
4411              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4412              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4413              }              }
4414            GETCHARINC(c, eptr);            GETCHARINC(c, eptr);
4415            switch(c)            switch(c)
# Line 4216  for (;;) Line 4422  for (;;)
4422              case 0x85:      /* NEL */              case 0x85:      /* NEL */
4423              case 0x2028:    /* LINE SEPARATOR */              case 0x2028:    /* LINE SEPARATOR */
4424              case 0x2029:    /* PARAGRAPH SEPARATOR */              case 0x2029:    /* PARAGRAPH SEPARATOR */
4425              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4426              }              }
4427            }            }
4428          break;          break;
# Line 4227  for (;;) Line 4433  for (;;)
4433            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4434              {              {
4435              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4436              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4437              }              }
4438            GETCHARINC(c, eptr);            GETCHARINC(c, eptr);
4439            switch(c)            switch(c)
4440              {              {
4441              default: MRRETURN(MATCH_NOMATCH);              default: RRETURN(MATCH_NOMATCH);
4442              case 0x0a:      /* LF */              case 0x0a:      /* LF */
4443              case 0x0b:      /* VT */              case 0x0b:      /* VT */
4444              case 0x0c:      /* FF */              case 0x0c:      /* FF */
# Line 4251  for (;;) Line 4457  for (;;)
4457            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4458              {              {
4459              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4460              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4461              }              }
4462            GETCHARINC(c, eptr);            GETCHARINC(c, eptr);
4463            if (c < 128 && (md->ctypes[c] & ctype_digit) != 0)            if (c < 128 && (md->ctypes[c] & ctype_digit) != 0)
4464              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4465            }            }
4466          break;          break;
4467    
# Line 4265  for (;;) Line 4471  for (;;)
4471            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4472              {              {
4473              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4474              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4475              }              }
4476            if (*eptr >= 128 || (md->ctypes[*eptr++] & ctype_digit) == 0)            if (*eptr >= 128 || (md->ctypes[*eptr] & ctype_digit) == 0)
4477              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4478              eptr++;
4479            /* 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 */
4480            }            }
4481          break;          break;
# Line 4279  for (;;) Line 4486  for (;;)
4486            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4487              {              {
4488              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4489              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4490              }              }
4491            if (*eptr < 128 && (md->ctypes[*eptr] & ctype_space) != 0)            if (*eptr < 128 && (md->ctypes[*eptr] & ctype_space) != 0)
4492              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4493            while (++eptr < md->end_subject && (*eptr & 0xc0) == 0x80);            eptr++;
4494              ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
4495            }            }
4496          break;          break;
4497    
# Line 4293  for (;;) Line 4501  for (;;)
4501            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4502              {              {
4503              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4504              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4505              }              }
4506            if (*eptr >= 128 || (md->ctypes[*eptr++] & ctype_space) == 0)            if (*eptr >= 128 || (md->ctypes[*eptr] & ctype_space) == 0)
4507              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4508              eptr++;
4509            /* 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 */
4510            }            }
4511          break;          break;
# Line 4307  for (;;) Line 4516  for (;;)
4516            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4517              {              {
4518              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4519              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4520              }              }
4521            if (*eptr < 128 && (md->ctypes[*eptr] & ctype_word) != 0)            if (*eptr < 128 && (md->ctypes[*eptr] & ctype_word) != 0)
4522              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4523            while (++eptr < md->end_subject && (*eptr & 0xc0) == 0x80);            eptr++;
4524              ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
4525            }            }
4526          break;          break;
4527    
# Line 4321  for (;;) Line 4531  for (;;)
4531            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4532              {              {
4533              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4534              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4535              }              }
4536            if (*eptr >= 128 || (md->ctypes[*eptr++] & ctype_word) == 0)            if (*eptr >= 128 || (md->ctypes[*eptr] & ctype_word) == 0)
4537              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4538              eptr++;
4539            /* 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 */
4540            }            }
4541          break;          break;
# Line 4334  for (;;) Line 4545  for (;;)
4545          }  /* End switch(ctype) */          }  /* End switch(ctype) */
4546    
4547        else        else
4548  #endif     /* SUPPORT_UTF8 */  #endif     /* SUPPORT_UTF */
4549    
4550        /* Code for the non-UTF-8 case for minimum matching of operators other        /* Code for the non-UTF-8 case for minimum matching of operators other
4551        than OP_PROP and OP_NOTPROP. */        than OP_PROP and OP_NOTPROP. */
# Line 4347  for (;;) Line 4558  for (;;)
4558            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4559              {              {
4560              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4561              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4562                }
4563              if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH);
4564              if (md->partial != 0 &&
4565                  eptr + 1 >= md->end_subject &&
4566                  NLBLOCK->nltype == NLTYPE_FIXED &&
4567                  NLBLOCK->nllen == 2 &&
4568                  *eptr == NLBLOCK->nl[0])
4569                {
4570                md->hitend = TRUE;
4571                if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
4572              }              }
           if (IS_NEWLINE(eptr)) MRRETURN(MATCH_NOMATCH);  
4573            eptr++;            eptr++;
4574            }            }
4575          break;          break;
# Line 4358  for (;;) Line 4578  for (;;)
4578          if (eptr > md->end_subject - min)          if (eptr > md->end_subject - min)
4579            {            {
4580            SCHECK_PARTIAL();            SCHECK_PARTIAL();
4581            MRRETURN(MATCH_NOMATCH);            RRETURN(MATCH_NOMATCH);
4582            }            }
4583          eptr += min;          eptr += min;
4584          break;          break;
# Line 4367  for (;;) Line 4587  for (;;)
4587          if (eptr > md->end_subject - min)          if (eptr > md->end_subject - min)
4588            {            {
4589            SCHECK_PARTIAL();            SCHECK_PARTIAL();
4590            MRRETURN(MATCH_NOMATCH);            RRETURN(MATCH_NOMATCH);
4591            }            }
4592          eptr += min;          eptr += min;
4593          break;          break;
# Line 4378  for (;;) Line 4598  for (;;)
4598            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4599              {              {
4600              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4601              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4602              }              }
4603            switch(*eptr++)            switch(*eptr++)
4604              {              {
4605              default: MRRETURN(MATCH_NOMATCH);              default: RRETURN(MATCH_NOMATCH);
4606    
4607              case 0x000d:              case 0x000d:
4608              if (eptr < md->end_subject && *eptr == 0x0a) eptr++;              if (eptr < md->end_subject && *eptr == 0x0a) eptr++;
# Line 4394  for (;;) Line 4614  for (;;)
4614              case 0x000b:              case 0x000b:
4615              case 0x000c:              case 0x000c:
4616              case 0x0085:              case 0x0085:
4617              if (md->bsr_anycrlf) MRRETURN(MATCH_NOMATCH);  #ifdef COMPILE_PCRE16
4618                case 0x2028:
4619                case 0x2029:
4620    #endif
4621                if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH);
4622              break;              break;
4623              }              }
4624            }            }
# Line 4406  for (;;) Line 4630  for (;;)
4630            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4631              {              {
4632              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4633              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4634              }              }
4635            switch(*eptr++)            switch(*eptr++)
4636              {              {
# Line 4414  for (;;) Line 4638  for (;;)
4638              case 0x09:      /* HT */              case 0x09:      /* HT */
4639              case 0x20:      /* SPACE */              case 0x20:      /* SPACE */
4640              case 0xa0:      /* NBSP */              case 0xa0:      /* NBSP */
4641              MRRETURN(MATCH_NOMATCH);  #ifdef COMPILE_PCRE16
4642                case 0x1680:    /* OGHAM SPACE MARK */
4643                case 0x180e:    /* MONGOLIAN VOWEL SEPARATOR */
4644                case 0x2000:    /* EN QUAD */
4645                case 0x2001:    /* EM QUAD */
4646                case 0x2002:    /* EN SPACE */
4647                case 0x2003:    /* EM SPACE */
4648                case 0x2004:    /* THREE-PER-EM SPACE */
4649                case 0x2005:    /* FOUR-PER-EM SPACE */
4650                case 0x2006:    /* SIX-PER-EM SPACE */
4651                case 0x2007:    /* FIGURE SPACE */
4652                case 0x2008:    /* PUNCTUATION SPACE */
4653                case 0x2009:    /* THIN SPACE */
4654                case 0x200A:    /* HAIR SPACE */
4655                case 0x202f:    /* NARROW NO-BREAK SPACE */
4656                case 0x205f:    /* MEDIUM MATHEMATICAL SPACE */
4657                case 0x3000:    /* IDEOGRAPHIC SPACE */
4658    #endif
4659                RRETURN(MATCH_NOMATCH);
4660              }              }
4661            }            }
4662          break;          break;
# Line 4425  for (;;) Line 4667  for (;;)
4667            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4668              {              {
4669              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4670              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4671              }              }
4672            switch(*eptr++)            switch(*eptr++)
4673              {              {
4674              default: MRRETURN(MATCH_NOMATCH);              default: RRETURN(MATCH_NOMATCH);
4675              case 0x09:      /* HT */              case 0x09:      /* HT */
4676              case 0x20:      /* SPACE */              case 0x20:      /* SPACE */
4677              case 0xa0:      /* NBSP */              case 0xa0:      /* NBSP */
4678    #ifdef COMPILE_PCRE16
4679                case 0x1680:    /* OGHAM SPACE MARK */
4680                case 0x180e:    /* MONGOLIAN VOWEL SEPARATOR */
4681                case 0x2000:    /* EN QUAD */
4682                case 0x2001:    /* EM QUAD */
4683                case 0x2002:    /* EN SPACE */
4684                case 0x2003:    /* EM SPACE */
4685                case 0x2004:    /* THREE-PER-EM SPACE */
4686                case 0x2005:    /* FOUR-PER-EM SPACE */
4687                case 0x2006:    /* SIX-PER-EM SPACE */
4688                case 0x2007:    /* FIGURE SPACE */
4689                case 0x2008:    /* PUNCTUATION SPACE */
4690                case 0x2009:    /* THIN SPACE */
4691                case 0x200A:    /* HAIR SPACE */
4692                case 0x202f:    /* NARROW NO-BREAK SPACE */
4693                case 0x205f:    /* MEDIUM MATHEMATICAL SPACE */
4694                case 0x3000:    /* IDEOGRAPHIC SPACE */
4695    #endif
4696              break;              break;
4697              }              }
4698            }            }
# Line 4444  for (;;) Line 4704  for (;;)
4704            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4705              {              {
4706              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4707              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4708              }              }
4709            switch(*eptr++)            switch(*eptr++)
4710              {              {
# Line 4454  for (;;) Line 4714  for (;;)
4714              case 0x0c:      /* FF */              case 0x0c:      /* FF */
4715              case 0x0d:      /* CR */              case 0x0d:      /* CR */
4716              case 0x85:      /* NEL */              case 0x85:      /* NEL */
4717              MRRETURN(MATCH_NOMATCH);  #ifdef COMPILE_PCRE16
4718                case 0x2028:    /* LINE SEPARATOR */
4719                case 0x2029:    /* PARAGRAPH SEPARATOR */
4720    #endif
4721                RRETURN(MATCH_NOMATCH);
4722              }              }
4723            }            }
4724          break;          break;
# Line 4465  for (;;) Line 4729  for (;;)
4729            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4730              {              {
4731              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4732              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4733              }              }
4734            switch(*eptr++)            switch(*eptr++)
4735              {              {
4736              default: MRRETURN(MATCH_NOMATCH);              default: RRETURN(MATCH_NOMATCH);
4737              case 0x0a:      /* LF */              case 0x0a:      /* LF */
4738              case 0x0b:      /* VT */              case 0x0b:      /* VT */
4739              case 0x0c:      /* FF */              case 0x0c:      /* FF */
4740              case 0x0d:      /* CR */              case 0x0d:      /* CR */
4741              case 0x85:      /* NEL */              case 0x85:      /* NEL */
4742    #ifdef COMPILE_PCRE16
4743                case 0x2028:    /* LINE SEPARATOR */
4744                case 0x2029:    /* PARAGRAPH SEPARATOR */
4745    #endif
4746              break;              break;
4747              }              }
4748            }            }
# Line 4486  for (;;) Line 4754  for (;;)
4754            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4755              {              {
4756              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4757              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4758              }              }
4759            if ((md->ctypes[*eptr++] & ctype_digit) != 0) MRRETURN(MATCH_NOMATCH);            if (MAX_255(*eptr) && (md->ctypes[*eptr] & ctype_digit) != 0)
4760                RRETURN(MATCH_NOMATCH);
4761              eptr++;
4762            }            }
4763          break;          break;
4764    
# Line 4498  for (;;) Line 4768  for (;;)
4768            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4769              {              {
4770              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4771              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4772              }              }
4773            if ((md->ctypes[*eptr++] & ctype_digit) == 0) MRRETURN(MATCH_NOMATCH);            if (!MAX_255(*eptr) || (md->ctypes[*eptr] & ctype_digit) == 0)
4774                RRETURN(MATCH_NOMATCH);
4775              eptr++;
4776            }            }
4777          break;          break;
4778    
# Line 4510  for (;;) Line 4782  for (;;)
4782            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4783              {              {
4784              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4785              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4786              }              }
4787            if ((md->ctypes[*eptr++] & ctype_space) != 0) MRRETURN(MATCH_NOMATCH);            if (MAX_255(*eptr) && (md->ctypes[*eptr] & ctype_space) != 0)
4788                RRETURN(MATCH_NOMATCH);
4789              eptr++;
4790            }            }
4791          break;          break;
4792    
# Line 4522  for (;;) Line 4796  for (;;)
4796            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4797              {              {
4798              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4799              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4800              }              }
4801            if ((md->ctypes[*eptr++] & ctype_space) == 0) MRRETURN(MATCH_NOMATCH);            if (!MAX_255(*eptr) || (md->ctypes[*eptr] & ctype_space) == 0)
4802                RRETURN(MATCH_NOMATCH);
4803              eptr++;
4804            }            }
4805          break;          break;
4806    
# Line 4534  for (;;) Line 4810  for (;;)
4810            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4811              {              {
4812              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4813              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4814              }              }
4815            if ((md->ctypes[*eptr++] & ctype_word) != 0)            if (MAX_255(*eptr) && (md->ctypes[*eptr] & ctype_word) != 0)
4816              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4817              eptr++;
4818            }            }
4819          break;          break;
4820    
# Line 4547  for (;;) Line 4824  for (;;)
4824            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4825              {              {
4826              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4827              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4828              }              }
4829            if ((md->ctypes[*eptr++] & ctype_word) == 0)            if (!MAX_255(*eptr) || (md->ctypes[*eptr] & ctype_word) == 0)
4830              MRRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4831              eptr++;
4832            }            }
4833          break;          break;
4834    
# Line 4579  for (;;) Line 4857  for (;;)
4857              {              {
4858              RMATCH(eptr, ecode, offset_top, md, eptrb, RM36);              RMATCH(eptr, ecode, offset_top, md, eptrb, RM36);
4859              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
4860              if (fi >= max) MRRETURN(MATCH_NOMATCH);              if (fi >= max) RRETURN(MATCH_NOMATCH);
4861              if (eptr >= md->end_subject)              if (eptr >= md->end_subject)
4862                {                {
4863                SCHECK_PARTIAL();                SCHECK_PARTIAL();
4864                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4865                }                }
4866              GETCHARINCTEST(c, eptr);              GETCHARINCTEST(c, eptr);
4867              if (prop_fail_result) MRRETURN(MATCH_NOMATCH);              if (prop_fail_result) RRETURN(MATCH_NOMATCH);
4868              }              }
4869            /* Control never gets here */            /* Control never gets here */
4870    
# Line 4596  for (;;) Line 4874  for (;;)
4874              int chartype;              int chartype;
4875              RMATCH(eptr, ecode, offset_top, md, eptrb, RM37);              RMATCH(eptr, ecode, offset_top, md, eptrb, RM37);
4876              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
4877              if (fi >= max) MRRETURN(MATCH_NOMATCH);              if (fi >= max) RRETURN(MATCH_NOMATCH);
4878              if (eptr >= md->end_subject)              if (eptr >= md->end_subject)
4879                {                {
4880                SCHECK_PARTIAL();                SCHECK_PARTIAL();
4881                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4882                }                }
4883              GETCHARINCTEST(c, eptr);              GETCHARINCTEST(c, eptr);
4884              chartype = UCD_CHARTYPE(c);              chartype = UCD_CHARTYPE(c);
4885              if ((chartype == ucp_Lu ||              if ((chartype == ucp_Lu ||
4886                   chartype == ucp_Ll ||                   chartype == ucp_Ll ||
4887                   chartype == ucp_Lt) == prop_fail_result)                   chartype == ucp_Lt) == prop_fail_result)
4888                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4889              }              }
4890            /* Control never gets here */            /* Control never gets here */
4891    
# Line 4616  for (;;) Line 4894  for (;;)
4894              {              {
4895              RMATCH(eptr, ecode, offset_top, md, eptrb, RM38);              RMATCH(eptr, ecode, offset_top, md, eptrb, RM38);
4896              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
4897              if (fi >= max) MRRETURN(MATCH_NOMATCH);              if (fi >= max) RRETURN(MATCH_NOMATCH);
4898              if (eptr >= md->end_subject)              if (eptr >= md->end_subject)
4899                {                {
4900                SCHECK_PARTIAL();                SCHECK_PARTIAL();
4901                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4902                }                }
4903              GETCHARINCTEST(c, eptr);              GETCHARINCTEST(c, eptr);
4904              if ((UCD_CATEGORY(c) == prop_value) == prop_fail_result)              if ((UCD_CATEGORY(c) == prop_value) == prop_fail_result)
4905                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4906              }              }
4907            /* Control never gets here */            /* Control never gets here */
4908    
# Line 4633  for (;;) Line 4911  for (;;)
4911              {              {
4912              RMATCH(eptr, ecode, offset_top, md, eptrb, RM39);              RMATCH(eptr, ecode, offset_top, md, eptrb, RM39);
4913              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
4914              if (fi >= max) MRRETURN(MATCH_NOMATCH);              if (fi >= max) RRETURN(MATCH_NOMATCH);
4915              if (eptr >= md->end_subject)              if (eptr >= md->end_subject)
4916                {                {
4917                SCHECK_PARTIAL();                SCHECK_PARTIAL();
4918                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4919                }                }
4920              GETCHARINCTEST(c, eptr);              GETCHARINCTEST(c, eptr);
4921              if ((UCD_CHARTYPE(c) == prop_value) == prop_fail_result)              if ((UCD_CHARTYPE(c) == prop_value) == prop_fail_result)
4922                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4923              }              }
4924            /* Control never gets here */            /* Control never gets here */
4925    
# Line 4650  for (;;) Line 4928  for (;;)
4928              {              {
4929              RMATCH(eptr, ecode, offset_top, md, eptrb, RM40);              RMATCH(eptr, ecode, offset_top, md, eptrb, RM40);
4930              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
4931              if (fi >= max) MRRETURN(MATCH_NOMATCH);              if (fi >= max) RRETURN(MATCH_NOMATCH);
4932              if (eptr >= md->end_subject)              if (eptr >= md->end_subject)
4933                {                {
4934                SCHECK_PARTIAL();                SCHECK_PARTIAL();
4935                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4936                }                }
4937              GETCHARINCTEST(c, eptr);              GETCHARINCTEST(c, eptr);
4938              if ((UCD_SCRIPT(c) == prop_value) == prop_fail_result)              if ((UCD_SCRIPT(c) == prop_value) == prop_fail_result)
4939                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4940              }              }
4941            /* Control never gets here */            /* Control never gets here */
4942    
# Line 4668  for (;;) Line 4946  for (;;)
4946              int category;              int category;
4947              RMATCH(eptr, ecode, offset_top, md, eptrb, RM59);              RMATCH(eptr, ecode, offset_top, md, eptrb, RM59);
4948              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
4949              if (fi >= max) MRRETURN(MATCH_NOMATCH);              if (fi >= max) RRETURN(MATCH_NOMATCH);
4950              if (eptr >= md->end_subject)              if (eptr >= md->end_subject)
4951                {                {
4952                SCHECK_PARTIAL();                SCHECK_PARTIAL();
4953                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4954                }                }
4955              GETCHARINCTEST(c, eptr);              GETCHARINCTEST(c, eptr);
4956              category = UCD_CATEGORY(c);              category = UCD_CATEGORY(c);
4957              if ((category == ucp_L || category == ucp_N) == prop_fail_result)              if ((category == ucp_L || category == ucp_N) == prop_fail_result)
4958                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4959              }              }
4960            /* Control never gets here */            /* Control never gets here */
4961    
# Line 4686  for (;;) Line 4964  for (;;)
4964              {              {
4965              RMATCH(eptr, ecode, offset_top, md, eptrb, RM60);              RMATCH(eptr, ecode, offset_top, md, eptrb, RM60);
4966              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
4967              if (fi >= max) MRRETURN(MATCH_NOMATCH);              if (fi >= max) RRETURN(MATCH_NOMATCH);
4968              if (eptr >= md->end_subject)              if (eptr >= md->end_subject)
4969                {                {
4970                SCHECK_PARTIAL();                SCHECK_PARTIAL();
4971                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4972                }                }
4973              GETCHARINCTEST(c, eptr);              GETCHARINCTEST(c, eptr);
4974              if ((UCD_CATEGORY(c) == ucp_Z || c == CHAR_HT || c == CHAR_NL ||              if ((UCD_CATEGORY(c) == ucp_Z || c == CHAR_HT || c == CHAR_NL ||
4975                   c == CHAR_FF || c == CHAR_CR)                   c == CHAR_FF || c == CHAR_CR)
4976                     == prop_fail_result)                     == prop_fail_result)
4977                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4978              }              }
4979            /* Control never gets here */            /* Control never gets here */
4980    
# Line 4705  for (;;) Line 4983  for (;;)
4983              {              {
4984              RMATCH(eptr, ecode, offset_top, md, eptrb, RM61);              RMATCH(eptr, ecode, offset_top, md, eptrb, RM61);
4985              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
4986              if (fi >= max) MRRETURN(MATCH_NOMATCH);              if (fi >= max) RRETURN(MATCH_NOMATCH);
4987              if (eptr >= md->end_subject)              if (eptr >= md->end_subject)
4988                {                {
4989                SCHECK_PARTIAL();                SCHECK_PARTIAL();
4990                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4991                }                }
4992              GETCHARINCTEST(c, eptr);              GETCHARINCTEST(c, eptr);
4993              if ((UCD_CATEGORY(c) == ucp_Z || c == CHAR_HT || c == CHAR_NL ||              if ((UCD_CATEGORY(c) == ucp_Z || c == CHAR_HT || c == CHAR_NL ||
4994                   c == CHAR_VT || c == CHAR_FF || c == CHAR_CR)                   c == CHAR_VT || c == CHAR_FF || c == CHAR_CR)
4995                     == prop_fail_result)                     == prop_fail_result)
4996                MRRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4997              }              }
4998            /* Control never gets here */            /* Control never gets here */
4999    
# Line 4725  for (;;) Line 5003  for (;;)
5003              int category;              int category;
5004              RMATCH(eptr, ecode, offset_top, md, eptrb, RM62);              RMATCH(eptr, ecode, offset_top, md, eptrb, RM62);
5005              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
5006              if (fi >= max) MRRETURN(MATCH_NOMATCH);              if (fi >= max) RRETURN(MATCH_NOMATCH);
5007              if (eptr >= md->end_subject)              if (eptr >= md->end_subject)