/[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 771 by ph10, Tue Nov 29 15:34:12 2011 UTC revision 1145 by ph10, Fri Oct 19 16:25:32 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 93  because the offset vector is always a mu Line 92  because the offset vector is always a mu
92  static const char rep_min[] = { 0, 0, 1, 1, 0, 0 };  static const char rep_min[] = { 0, 0, 1, 1, 0, 0 };
93  static const char rep_max[] = { 0, 0, 0, 0, 1, 1 };  static const char rep_max[] = { 0, 0, 0, 0, 1, 1 };
94    
   
   
95  #ifdef PCRE_DEBUG  #ifdef PCRE_DEBUG
96  /*************************************************  /*************************************************
97  *        Debugging function to print chars       *  *        Debugging function to print chars       *
# Line 113  Returns:     nothing Line 110  Returns:     nothing
110  */  */
111    
112  static void  static void
113  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)
114  {  {
115  unsigned int c;  pcre_uint32 c;
116    BOOL utf = md->utf;
117  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;
118  while (length-- > 0)  while (length-- > 0)
119    if (isprint(c = *(p++))) printf("%c", c); else printf("\\x%02x", c);    if (isprint(c = RAWUCHARINCTEST(p))) printf("%c", (char)c); else printf("\\x{%02x}", c);
120  }  }
121  #endif  #endif
122    
# Line 140  Arguments: Line 138  Arguments:
138    md          points to match data block    md          points to match data block
139    caseless    TRUE if caseless    caseless    TRUE if caseless
140    
141  Returns:      < 0 if not matched, otherwise the number of subject bytes matched  Returns:      >= 0 the number of subject bytes matched
142                  -1 no match
143                  -2 partial match; always given if at end subject
144  */  */
145    
146  static int  static int
147  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,
148    BOOL caseless)    BOOL caseless)
149  {  {
150  USPTR eptr_start = eptr;  PCRE_PUCHAR eptr_start = eptr;
151  register USPTR p = md->start_subject + md->offset_vector[offset];  register PCRE_PUCHAR p = md->start_subject + md->offset_vector[offset];
152    BOOL utf = md->utf;
153    
154  #ifdef PCRE_DEBUG  #ifdef PCRE_DEBUG
155  if (eptr >= md->end_subject)  if (eptr >= md->end_subject)
# Line 163  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 173  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 (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      data units matched may differ, because in UTF-8 there are some characters
184      lower case versions code as different numbers of bytes. For example, U+023A      whose upper and lower case versions code have different numbers of bytes.
185      (2 bytes in UTF-8) is the upper case version of U+2C65 (3 bytes in UTF-8);      For example, U+023A (2 bytes in UTF-8) is the upper case version of U+2C65
186      a sequence of 3 of the former uses 6 bytes, as does a sequence of two of      (3 bytes in UTF-8); a sequence of 3 of the former uses 6 bytes, as does a
187      the latter. It is important, therefore, to check the length along the      sequence of two of the latter. It is important, therefore, to check the
188      reference, not along the subject (earlier code did this wrong). */      length along the reference, not along the subject (earlier code did this
189        wrong). */
190    
191      USPTR endptr = p + length;      PCRE_PUCHAR endptr = p + length;
192      while (p < endptr)      while (p < endptr)
193        {        {
194        int c, d;        pcre_uint32 c, d;
195        if (eptr >= md->end_subject) return -1;        const ucd_record *ur;
196          if (eptr >= md->end_subject) return -2;   /* Partial match */
197        GETCHARINC(c, eptr);        GETCHARINC(c, eptr);
198        GETCHARINC(d, p);        GETCHARINC(d, p);
199        if (c != d && c != UCD_OTHERCASE(d)) return -1;        ur = GET_UCD(d);
200          if (c != d && c != d + ur->other_case)
201            {
202            const pcre_uint32 *pp = PRIV(ucd_caseless_sets) + ur->caseset;
203            for (;;)
204              {
205              if (c < *pp) return -1;
206              if (c == *pp++) break;
207              }
208            }
209        }        }
210      }      }
211    else    else
# Line 202  if (caseless) Line 215  if (caseless)
215    /* 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
216    is no UCP support. */    is no UCP support. */
217      {      {
     if (eptr + length > md->end_subject) return -1;  
218      while (length-- > 0)      while (length-- > 0)
219        { if (md->lcc[*p++] != md->lcc[*eptr++]) return -1; }        {
220          pcre_uchar cc, cp;
221          if (eptr >= md->end_subject) return -2;   /* Partial match */
222          cc = RAWUCHARTEST(eptr);
223          cp = RAWUCHARTEST(p);
224          if (TABLE_GET(cp, md->lcc, cp) != TABLE_GET(cc, md->lcc, cc)) return -1;
225          p++;
226          eptr++;
227          }
228      }      }
229    }    }
230    
# Line 213  are in UTF-8 mode. */ Line 233  are in UTF-8 mode. */
233    
234  else  else
235    {    {
236    if (eptr + length > md->end_subject) return -1;    while (length-- > 0)
237    while (length-- > 0) if (*p++ != *eptr++) return -1;      {
238        if (eptr >= md->end_subject) return -2;   /* Partial match */
239        if (RAWUCHARINCTEST(p) != RAWUCHARINCTEST(eptr)) return -1;
240        }
241    }    }
242    
243  return eptr - eptr_start;  return (int)(eptr - eptr_start);
244  }  }
245    
246    
# Line 287  actually used in this definition. */ Line 310  actually used in this definition. */
310    }    }
311  #define RRETURN(ra) \  #define RRETURN(ra) \
312    { \    { \
313    printf("match() returned %d from line %d ", ra, __LINE__); \    printf("match() returned %d from line %d\n", ra, __LINE__); \
314    return ra; \    return ra; \
315    }    }
316  #else  #else
# Line 307  argument of match(), which never changes Line 330  argument of match(), which never changes
330    
331  #define RMATCH(ra,rb,rc,rd,re,rw)\  #define RMATCH(ra,rb,rc,rd,re,rw)\
332    {\    {\
333    heapframe *newframe = (heapframe *)(pcre_stack_malloc)(sizeof(heapframe));\    heapframe *newframe = frame->Xnextframe;\
334    if (newframe == NULL) RRETURN(PCRE_ERROR_NOMEMORY);\    if (newframe == NULL)\
335    frame->Xwhere = rw; \      {\
336        newframe = (heapframe *)(PUBL(stack_malloc))(sizeof(heapframe));\
337        if (newframe == NULL) RRETURN(PCRE_ERROR_NOMEMORY);\
338        newframe->Xnextframe = NULL;\
339        frame->Xnextframe = newframe;\
340        }\
341      frame->Xwhere = rw;\
342    newframe->Xeptr = ra;\    newframe->Xeptr = ra;\
343    newframe->Xecode = rb;\    newframe->Xecode = rb;\
344    newframe->Xmstart = mstart;\    newframe->Xmstart = mstart;\
# Line 328  argument of match(), which never changes Line 357  argument of match(), which never changes
357    {\    {\
358    heapframe *oldframe = frame;\    heapframe *oldframe = frame;\
359    frame = oldframe->Xprevframe;\    frame = oldframe->Xprevframe;\
   (pcre_stack_free)(oldframe);\  
360    if (frame != NULL)\    if (frame != NULL)\
361      {\      {\
362      rrc = ra;\      rrc = ra;\
# Line 342  argument of match(), which never changes Line 370  argument of match(), which never changes
370    
371  typedef struct heapframe {  typedef struct heapframe {
372    struct heapframe *Xprevframe;    struct heapframe *Xprevframe;
373      struct heapframe *Xnextframe;
374    
375    /* Function arguments that may change */    /* Function arguments that may change */
376    
377    USPTR Xeptr;    PCRE_PUCHAR Xeptr;
378    const uschar *Xecode;    const pcre_uchar *Xecode;
379    USPTR Xmstart;    PCRE_PUCHAR Xmstart;
380    int Xoffset_top;    int Xoffset_top;
381    eptrblock *Xeptrb;    eptrblock *Xeptrb;
382    unsigned int Xrdepth;    unsigned int Xrdepth;
383    
384    /* Function local variables */    /* Function local variables */
385    
386    USPTR Xcallpat;    PCRE_PUCHAR Xcallpat;
387  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
388    USPTR Xcharptr;    PCRE_PUCHAR Xcharptr;
389  #endif  #endif
390    USPTR Xdata;    PCRE_PUCHAR Xdata;
391    USPTR Xnext;    PCRE_PUCHAR Xnext;
392    USPTR Xpp;    PCRE_PUCHAR Xpp;
393    USPTR Xprev;    PCRE_PUCHAR Xprev;
394    USPTR Xsaved_eptr;    PCRE_PUCHAR Xsaved_eptr;
395    
396    recursion_info Xnew_recursive;    recursion_info Xnew_recursive;
397    
# Line 372  typedef struct heapframe { Line 401  typedef struct heapframe {
401    
402  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
403    int Xprop_type;    int Xprop_type;
404    int Xprop_value;    unsigned int Xprop_value;
405    int Xprop_fail_result;    int Xprop_fail_result;
406    int Xoclength;    int Xoclength;
407    uschar Xocchars[8];    pcre_uchar Xocchars[6];
408  #endif  #endif
409    
410    int Xcodelink;    int Xcodelink;
# Line 417  returns a negative (error) response, the Line 446  returns a negative (error) response, the
446  same response. */  same response. */
447    
448  /* 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
449  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
450  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.
451  something has been matched). For hard partial matching, we then return  something has been matched). For hard partial matching, we then return
452  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 440  the subject. */ Line 469  the subject. */
469    
470    
471  /* Performance note: It might be tempting to extract commonly used fields from  /* Performance note: It might be tempting to extract commonly used fields from
472  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
473  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
474  made performance worse.  made performance worse.
475    
# Line 463  Returns:       MATCH_MATCH if matched Line 492  Returns:       MATCH_MATCH if matched
492  */  */
493    
494  static int  static int
495  match(REGISTER USPTR eptr, REGISTER const uschar *ecode, USPTR mstart,  match(REGISTER PCRE_PUCHAR eptr, REGISTER const pcre_uchar *ecode,
496    int offset_top, match_data *md, eptrblock *eptrb, unsigned int rdepth)    PCRE_PUCHAR mstart, int offset_top, match_data *md, eptrblock *eptrb,
497      unsigned int rdepth)
498  {  {
499  /* 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,
500  so they can be ordinary variables in all cases. Mark some of them with  so they can be ordinary variables in all cases. Mark some of them with
# Line 472  so they can be ordinary variables in all Line 502  so they can be ordinary variables in all
502    
503  register int  rrc;         /* Returns from recursive calls */  register int  rrc;         /* Returns from recursive calls */
504  register int  i;           /* Used for loops not involving calls to RMATCH() */  register int  i;           /* Used for loops not involving calls to RMATCH() */
505  register unsigned int c;   /* Character values not kept over RMATCH() calls */  register pcre_uint32 c;    /* Character values not kept over RMATCH() calls */
506  register BOOL utf8;        /* Local copy of UTF-8 flag for speed */  register BOOL utf;         /* Local copy of UTF flag for speed */
507    
508  BOOL minimize, possessive; /* Quantifier options */  BOOL minimize, possessive; /* Quantifier options */
509  BOOL caseless;  BOOL caseless;
510  int condcode;  int condcode;
511    
512  /* 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
513  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
514  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
515  heap whenever RMATCH() does a "recursion". See the macro definitions above. */  whenever RMATCH() does a "recursion". See the macro definitions above. Putting
516    the top-level on the stack rather than malloc-ing them all gives a performance
517    boost in many cases where there is not much "recursion". */
518    
519  #ifdef NO_RECURSE  #ifdef NO_RECURSE
520  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 */  
521    
522  /* Copy in the original argument variables */  /* Copy in the original argument variables */
523    
# Line 513  HEAP_RECURSE: Line 543  HEAP_RECURSE:
543    
544  /* Ditto for the local variables */  /* Ditto for the local variables */
545    
546  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
547  #define charptr            frame->Xcharptr  #define charptr            frame->Xcharptr
548  #endif  #endif
549  #define callpat            frame->Xcallpat  #define callpat            frame->Xcallpat
# Line 571  declarations can be cut out in a block. Line 601  declarations can be cut out in a block.
601  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
602  to RMATCH(). */  to RMATCH(). */
603    
604  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
605  const uschar *charptr;  const pcre_uchar *charptr;
606  #endif  #endif
607  const uschar *callpat;  const pcre_uchar *callpat;
608  const uschar *data;  const pcre_uchar *data;
609  const uschar *next;  const pcre_uchar *next;
610  USPTR         pp;  PCRE_PUCHAR       pp;
611  const uschar *prev;  const pcre_uchar *prev;
612  USPTR         saved_eptr;  PCRE_PUCHAR       saved_eptr;
613    
614  recursion_info new_recursive;  recursion_info new_recursive;
615    
# Line 589  BOOL prev_is_word; Line 619  BOOL prev_is_word;
619    
620  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
621  int prop_type;  int prop_type;
622  int prop_value;  unsigned int prop_value;
623  int prop_fail_result;  int prop_fail_result;
624  int oclength;  int oclength;
625  uschar occhars[8];  pcre_uchar occhars[6];
626  #endif  #endif
627    
628  int codelink;  int codelink;
# Line 600  int ctype; Line 630  int ctype;
630  int length;  int length;
631  int max;  int max;
632  int min;  int min;
633  int number;  unsigned int number;
634  int offset;  int offset;
635  int op;  pcre_uchar op;
636  int save_capture_last;  int save_capture_last;
637  int save_offset1, save_offset2, save_offset3;  int save_offset1, save_offset2, save_offset3;
638  int stacksave[REC_STACK_SAVE_MAX];  int stacksave[REC_STACK_SAVE_MAX];
639    
640  eptrblock newptrb;  eptrblock newptrb;
641    
642    /* There is a special fudge for calling match() in a way that causes it to
643    measure the size of its basic stack frame when the stack is being used for
644    recursion. The second argument (ecode) being NULL triggers this behaviour. It
645    cannot normally ever be NULL. The return is the negated value of the frame
646    size. */
647    
648    if (ecode == NULL)
649      {
650      if (rdepth == 0)
651        return match((PCRE_PUCHAR)&rdepth, NULL, NULL, 0, NULL, NULL, 1);
652      else
653        {
654        int len = (char *)&rdepth - (char *)eptr;
655        return (len > 0)? -len : len;
656        }
657      }
658  #endif     /* NO_RECURSE */  #endif     /* NO_RECURSE */
659    
660  /* 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 620  the alternative names that are used. */ Line 667  the alternative names that are used. */
667  #define code_offset   codelink  #define code_offset   codelink
668  #define condassert    condition  #define condassert    condition
669  #define matched_once  prev_is_word  #define matched_once  prev_is_word
670    #define foc           number
671    #define save_mark     data
672    
673  /* These statements are here to stop the compiler complaining about unitialized  /* These statements are here to stop the compiler complaining about unitialized
674  variables. */  variables. */
# Line 645  defined). However, RMATCH isn't like a f Line 694  defined). However, RMATCH isn't like a f
694  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,
695  however, impact performance when true recursion is being used. */  however, impact performance when true recursion is being used. */
696    
697  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
698  utf8 = md->utf8;       /* Local copy of the flag */  utf = md->utf;       /* Local copy of the flag */
699  #else  #else
700  utf8 = FALSE;  utf = FALSE;
701  #endif  #endif
702    
703  /* 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 689  for (;;) Line 738  for (;;)
738      case OP_MARK:      case OP_MARK:
739      md->nomatch_mark = ecode + 2;      md->nomatch_mark = ecode + 2;
740      md->mark = NULL;    /* In case previously set by assertion */      md->mark = NULL;    /* In case previously set by assertion */
741      RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode] + ecode[1], offset_top, md,      RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode] + ecode[1], offset_top, md,
742        eptrb, RM55);        eptrb, RM55);
743      if ((rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) &&      if ((rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) &&
744           md->mark == NULL) md->mark = ecode + 2;           md->mark == NULL) md->mark = ecode + 2;
# Line 702  for (;;) Line 751  for (;;)
751      unaltered. */      unaltered. */
752    
753      else if (rrc == MATCH_SKIP_ARG &&      else if (rrc == MATCH_SKIP_ARG &&
754          strcmp((char *)(ecode + 2), (char *)(md->start_match_ptr)) == 0)          STRCMP_UC_UC_TEST(ecode + 2, md->start_match_ptr) == 0)
755        {        {
756        md->start_match_ptr = eptr;        md->start_match_ptr = eptr;
757        RRETURN(MATCH_SKIP);        RRETURN(MATCH_SKIP);
# Line 715  for (;;) Line 764  for (;;)
764      /* COMMIT overrides PRUNE, SKIP, and THEN */      /* COMMIT overrides PRUNE, SKIP, and THEN */
765    
766      case OP_COMMIT:      case OP_COMMIT:
767      RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,      RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md,
768        eptrb, RM52);        eptrb, RM52);
769      if (rrc != MATCH_NOMATCH && rrc != MATCH_PRUNE &&      if (rrc != MATCH_NOMATCH && rrc != MATCH_PRUNE &&
770          rrc != MATCH_SKIP && rrc != MATCH_SKIP_ARG &&          rrc != MATCH_SKIP && rrc != MATCH_SKIP_ARG &&
# Line 726  for (;;) Line 775  for (;;)
775      /* PRUNE overrides THEN */      /* PRUNE overrides THEN */
776    
777      case OP_PRUNE:      case OP_PRUNE:
778      RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,      RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md,
779        eptrb, RM51);        eptrb, RM51);
780      if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);      if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);
781      RRETURN(MATCH_PRUNE);      RRETURN(MATCH_PRUNE);
# Line 734  for (;;) Line 783  for (;;)
783      case OP_PRUNE_ARG:      case OP_PRUNE_ARG:
784      md->nomatch_mark = ecode + 2;      md->nomatch_mark = ecode + 2;
785      md->mark = NULL;    /* In case previously set by assertion */      md->mark = NULL;    /* In case previously set by assertion */
786      RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode] + ecode[1], offset_top, md,      RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode] + ecode[1], offset_top, md,
787        eptrb, RM56);        eptrb, RM56);
788      if ((rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) &&      if ((rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) &&
789           md->mark == NULL) md->mark = ecode + 2;           md->mark == NULL) md->mark = ecode + 2;
# Line 744  for (;;) Line 793  for (;;)
793      /* SKIP overrides PRUNE and THEN */      /* SKIP overrides PRUNE and THEN */
794    
795      case OP_SKIP:      case OP_SKIP:
796      RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,      RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md,
797        eptrb, RM53);        eptrb, RM53);
798      if (rrc != MATCH_NOMATCH && rrc != MATCH_PRUNE && rrc != MATCH_THEN)      if (rrc != MATCH_NOMATCH && rrc != MATCH_PRUNE && rrc != MATCH_THEN)
799        RRETURN(rrc);        RRETURN(rrc);
# Line 752  for (;;) Line 801  for (;;)
801      RRETURN(MATCH_SKIP);      RRETURN(MATCH_SKIP);
802    
803      /* Note that, for Perl compatibility, SKIP with an argument does NOT set      /* Note that, for Perl compatibility, SKIP with an argument does NOT set
804      nomatch_mark. There is a flag that disables this opcode when re-matching a      nomatch_mark. There is a flag that disables this opcode when re-matching a
805      pattern that ended with a SKIP for which there was not a matching MARK. */      pattern that ended with a SKIP for which there was not a matching MARK. */
806    
807      case OP_SKIP_ARG:      case OP_SKIP_ARG:
808      if (md->ignore_skip_arg)      if (md->ignore_skip_arg)
809        {        {
810        ecode += _pcre_OP_lengths[*ecode] + ecode[1];        ecode += PRIV(OP_lengths)[*ecode] + ecode[1];
811        break;        break;
812        }        }
813      RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode] + ecode[1], offset_top, md,      RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode] + ecode[1], offset_top, md,
814        eptrb, RM57);        eptrb, RM57);
815      if (rrc != MATCH_NOMATCH && rrc != MATCH_PRUNE && rrc != MATCH_THEN)      if (rrc != MATCH_NOMATCH && rrc != MATCH_PRUNE && rrc != MATCH_THEN)
816        RRETURN(rrc);        RRETURN(rrc);
817    
818      /* 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
819      returning the special MATCH_SKIP_ARG return code. This will either be      returning the special MATCH_SKIP_ARG return code. This will either be
820      caught by a matching MARK, or get to the top, where it causes a rematch      caught by a matching MARK, or get to the top, where it causes a rematch
821      with the md->ignore_skip_arg flag set. */      with the md->ignore_skip_arg flag set. */
822    
823      md->start_match_ptr = ecode + 2;      md->start_match_ptr = ecode + 2;
# Line 779  for (;;) Line 828  for (;;)
828      match pointer to do this. */      match pointer to do this. */
829    
830      case OP_THEN:      case OP_THEN:
831      RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,      RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md,
832        eptrb, RM54);        eptrb, RM54);
833      if (rrc != MATCH_NOMATCH) RRETURN(rrc);      if (rrc != MATCH_NOMATCH) RRETURN(rrc);
834      md->start_match_ptr = ecode;      md->start_match_ptr = ecode;
# Line 788  for (;;) Line 837  for (;;)
837      case OP_THEN_ARG:      case OP_THEN_ARG:
838      md->nomatch_mark = ecode + 2;      md->nomatch_mark = ecode + 2;
839      md->mark = NULL;    /* In case previously set by assertion */      md->mark = NULL;    /* In case previously set by assertion */
840      RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode] + ecode[1], offset_top,      RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode] + ecode[1], offset_top,
841        md, eptrb, RM58);        md, eptrb, RM58);
842      if ((rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) &&      if ((rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) &&
843           md->mark == NULL) md->mark = ecode + 2;           md->mark == NULL) md->mark = ecode + 2;
# Line 812  for (;;) Line 861  for (;;)
861      case OP_ONCE_NC:      case OP_ONCE_NC:
862      prev = ecode;      prev = ecode;
863      saved_eptr = eptr;      saved_eptr = eptr;
864        save_mark = md->mark;
865      do      do
866        {        {
867        RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, eptrb, RM64);        RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, eptrb, RM64);
# Line 830  for (;;) Line 880  for (;;)
880    
881        if (rrc != MATCH_NOMATCH) RRETURN(rrc);        if (rrc != MATCH_NOMATCH) RRETURN(rrc);
882        ecode += GET(ecode,1);        ecode += GET(ecode,1);
883          md->mark = save_mark;
884        }        }
885      while (*ecode == OP_ALT);      while (*ecode == OP_ALT);
886    
# Line 869  for (;;) Line 920  for (;;)
920        }        }
921      else  /* OP_KETRMAX */      else  /* OP_KETRMAX */
922        {        {
       md->match_function_type = MATCH_CBEGROUP;  
923        RMATCH(eptr, prev, offset_top, md, eptrb, RM66);        RMATCH(eptr, prev, offset_top, md, eptrb, RM66);
924        if (rrc != MATCH_NOMATCH) RRETURN(rrc);        if (rrc != MATCH_NOMATCH) RRETURN(rrc);
925        ecode += 1 + LINK_SIZE;        ecode += 1 + LINK_SIZE;
# Line 909  for (;;) Line 959  for (;;)
959        save_offset2 = md->offset_vector[offset+1];        save_offset2 = md->offset_vector[offset+1];
960        save_offset3 = md->offset_vector[md->offset_end - number];        save_offset3 = md->offset_vector[md->offset_end - number];
961        save_capture_last = md->capture_last;        save_capture_last = md->capture_last;
962          save_mark = md->mark;
963    
964        DPRINTF(("saving %d %d %d\n", save_offset1, save_offset2, save_offset3));        DPRINTF(("saving %d %d %d\n", save_offset1, save_offset2, save_offset3));
965        md->offset_vector[md->offset_end - number] =        md->offset_vector[md->offset_end - number] =
# Line 917  for (;;) Line 968  for (;;)
968        for (;;)        for (;;)
969          {          {
970          if (op >= OP_SBRA) md->match_function_type = MATCH_CBEGROUP;          if (op >= OP_SBRA) md->match_function_type = MATCH_CBEGROUP;
971          RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,          RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md,
972            eptrb, RM1);            eptrb, RM1);
973          if (rrc == MATCH_ONCE) break;  /* Backing up through an atomic group */          if (rrc == MATCH_ONCE) break;  /* Backing up through an atomic group */
974    
# Line 945  for (;;) Line 996  for (;;)
996          if (rrc != MATCH_NOMATCH) RRETURN(rrc);          if (rrc != MATCH_NOMATCH) RRETURN(rrc);
997          md->capture_last = save_capture_last;          md->capture_last = save_capture_last;
998          ecode += GET(ecode, 1);          ecode += GET(ecode, 1);
999            md->mark = save_mark;
1000          if (*ecode != OP_ALT) break;          if (*ecode != OP_ALT) break;
1001          }          }
1002    
# Line 996  for (;;) Line 1048  for (;;)
1048    
1049      for (;;)      for (;;)
1050        {        {
1051        if (op >= OP_SBRA || op == OP_ONCE) md->match_function_type = MATCH_CBEGROUP;        if (op >= OP_SBRA || op == OP_ONCE)
1052            md->match_function_type = MATCH_CBEGROUP;
1053    
1054        /* 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
1055        the pattern, and this is the final alternative, optimize as described        the pattern, and this is the final alternative, optimize as described
# Line 1004  for (;;) Line 1057  for (;;)
1057    
1058        else if (!md->hasthen && ecode[GET(ecode, 1)] != OP_ALT)        else if (!md->hasthen && ecode[GET(ecode, 1)] != OP_ALT)
1059          {          {
1060          ecode += _pcre_OP_lengths[*ecode];          ecode += PRIV(OP_lengths)[*ecode];
1061          goto TAIL_RECURSE;          goto TAIL_RECURSE;
1062          }          }
1063    
1064        /* In all other cases, we have to make another call to match(). */        /* In all other cases, we have to make another call to match(). */
1065    
1066        RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md, eptrb,        save_mark = md->mark;
1067          RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md, eptrb,
1068          RM2);          RM2);
1069    
1070        /* See comment in the code for capturing groups above about handling        /* See comment in the code for capturing groups above about handling
# Line 1028  for (;;) Line 1082  for (;;)
1082          {          {
1083          if (rrc == MATCH_ONCE)          if (rrc == MATCH_ONCE)
1084            {            {
1085            const uschar *scode = ecode;            const pcre_uchar *scode = ecode;
1086            if (*scode != OP_ONCE)           /* If not at start, find it */            if (*scode != OP_ONCE)           /* If not at start, find it */
1087              {              {
1088              while (*scode == OP_ALT) scode += GET(scode, 1);              while (*scode == OP_ALT) scode += GET(scode, 1);
# Line 1039  for (;;) Line 1093  for (;;)
1093          RRETURN(rrc);          RRETURN(rrc);
1094          }          }
1095        ecode += GET(ecode, 1);        ecode += GET(ecode, 1);
1096          md->mark = save_mark;
1097        if (*ecode != OP_ALT) break;        if (*ecode != OP_ALT) break;
1098        }        }
1099    
# Line 1070  for (;;) Line 1125  for (;;)
1125      if (offset < md->offset_max)      if (offset < md->offset_max)
1126        {        {
1127        matched_once = FALSE;        matched_once = FALSE;
1128        code_offset = ecode - md->start_code;        code_offset = (int)(ecode - md->start_code);
1129    
1130        save_offset1 = md->offset_vector[offset];        save_offset1 = md->offset_vector[offset];
1131        save_offset2 = md->offset_vector[offset+1];        save_offset2 = md->offset_vector[offset+1];
# Line 1093  for (;;) Line 1148  for (;;)
1148          md->offset_vector[md->offset_end - number] =          md->offset_vector[md->offset_end - number] =
1149            (int)(eptr - md->start_subject);            (int)(eptr - md->start_subject);
1150          if (op >= OP_SBRA) md->match_function_type = MATCH_CBEGROUP;          if (op >= OP_SBRA) md->match_function_type = MATCH_CBEGROUP;
1151          RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,          RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md,
1152            eptrb, RM63);            eptrb, RM63);
1153          if (rrc == MATCH_KETRPOS)          if (rrc == MATCH_KETRPOS)
1154            {            {
# Line 1160  for (;;) Line 1215  for (;;)
1215    
1216      POSSESSIVE_NON_CAPTURE:      POSSESSIVE_NON_CAPTURE:
1217      matched_once = FALSE;      matched_once = FALSE;
1218      code_offset = ecode - md->start_code;      code_offset = (int)(ecode - md->start_code);
1219    
1220      for (;;)      for (;;)
1221        {        {
1222        if (op >= OP_SBRA) md->match_function_type = MATCH_CBEGROUP;        if (op >= OP_SBRA) md->match_function_type = MATCH_CBEGROUP;
1223        RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,        RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md,
1224          eptrb, RM48);          eptrb, RM48);
1225        if (rrc == MATCH_KETRPOS)        if (rrc == MATCH_KETRPOS)
1226          {          {
# Line 1215  for (;;) Line 1270  for (;;)
1270    
1271      if (ecode[LINK_SIZE+1] == OP_CALLOUT)      if (ecode[LINK_SIZE+1] == OP_CALLOUT)
1272        {        {
1273        if (pcre_callout != NULL)        if (PUBL(callout) != NULL)
1274          {          {
1275          pcre_callout_block cb;          PUBL(callout_block) cb;
1276          cb.version          = 2;   /* Version 1 of the callout block */          cb.version          = 2;   /* Version 1 of the callout block */
1277          cb.callout_number   = ecode[LINK_SIZE+2];          cb.callout_number   = ecode[LINK_SIZE+2];
1278          cb.offset_vector    = md->offset_vector;          cb.offset_vector    = md->offset_vector;
1279    #if defined COMPILE_PCRE8
1280          cb.subject          = (PCRE_SPTR)md->start_subject;          cb.subject          = (PCRE_SPTR)md->start_subject;
1281    #elif defined COMPILE_PCRE16
1282            cb.subject          = (PCRE_SPTR16)md->start_subject;
1283    #elif defined COMPILE_PCRE32
1284            cb.subject          = (PCRE_SPTR32)md->start_subject;
1285    #endif
1286          cb.subject_length   = (int)(md->end_subject - md->start_subject);          cb.subject_length   = (int)(md->end_subject - md->start_subject);
1287          cb.start_match      = (int)(mstart - md->start_subject);          cb.start_match      = (int)(mstart - md->start_subject);
1288          cb.current_position = (int)(eptr - md->start_subject);          cb.current_position = (int)(eptr - md->start_subject);
# Line 1231  for (;;) Line 1292  for (;;)
1292          cb.capture_last     = md->capture_last;          cb.capture_last     = md->capture_last;
1293          cb.callout_data     = md->callout_data;          cb.callout_data     = md->callout_data;
1294          cb.mark             = md->nomatch_mark;          cb.mark             = md->nomatch_mark;
1295          if ((rrc = (*pcre_callout)(&cb)) > 0) RRETURN(MATCH_NOMATCH);          if ((rrc = (*PUBL(callout))(&cb)) > 0) RRETURN(MATCH_NOMATCH);
1296          if (rrc < 0) RRETURN(rrc);          if (rrc < 0) RRETURN(rrc);
1297          }          }
1298        ecode += _pcre_OP_lengths[OP_CALLOUT];        ecode += PRIV(OP_lengths)[OP_CALLOUT];
1299        }        }
1300    
1301      condcode = ecode[LINK_SIZE+1];      condcode = ecode[LINK_SIZE+1];
# Line 1250  for (;;) Line 1311  for (;;)
1311          }          }
1312        else        else
1313          {          {
1314          int recno = GET2(ecode, LINK_SIZE + 2);   /* Recursion group number*/          unsigned int recno = GET2(ecode, LINK_SIZE + 2);   /* Recursion group number*/
1315          condition = (recno == RREF_ANY || recno == md->recursive->group_num);          condition = (recno == RREF_ANY || recno == md->recursive->group_num);
1316    
1317          /* 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
# Line 1260  for (;;) Line 1321  for (;;)
1321    
1322          if (!condition && condcode == OP_NRREF)          if (!condition && condcode == OP_NRREF)
1323            {            {
1324            uschar *slotA = md->name_table;            pcre_uchar *slotA = md->name_table;
1325            for (i = 0; i < md->name_count; i++)            for (i = 0; i < md->name_count; i++)
1326              {              {
1327              if (GET2(slotA, 0) == recno) break;              if (GET2(slotA, 0) == recno) break;
# Line 1273  for (;;) Line 1334  for (;;)
1334    
1335            if (i < md->name_count)            if (i < md->name_count)
1336              {              {
1337              uschar *slotB = slotA;              pcre_uchar *slotB = slotA;
1338              while (slotB > md->name_table)              while (slotB > md->name_table)
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 1293  for (;;) Line 1354  for (;;)
1354                for (i++; i < md->name_count; i++)                for (i++; i < md->name_count; i++)
1355                  {                  {
1356                  slotB += md->name_entry_size;                  slotB += md->name_entry_size;
1357                  if (strcmp((char *)slotA + 2, (char *)slotB + 2) == 0)                  if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
1358                    {                    {
1359                    condition = GET2(slotB, 0) == md->recursive->group_num;                    condition = GET2(slotB, 0) == md->recursive->group_num;
1360                    if (condition) break;                    if (condition) break;
# Line 1306  for (;;) Line 1367  for (;;)
1367    
1368          /* Chose branch according to the condition */          /* Chose branch according to the condition */
1369    
1370          ecode += condition? 3 : GET(ecode, 1);          ecode += condition? 1 + IMM2_SIZE : GET(ecode, 1);
1371          }          }
1372        }        }
1373    
# Line 1322  for (;;) Line 1383  for (;;)
1383    
1384        if (!condition && condcode == OP_NCREF)        if (!condition && condcode == OP_NCREF)
1385          {          {
1386          int refno = offset >> 1;          unsigned int refno = offset >> 1;
1387          uschar *slotA = md->name_table;          pcre_uchar *slotA = md->name_table;
1388    
1389          for (i = 0; i < md->name_count; i++)          for (i = 0; i < md->name_count; i++)
1390            {            {
# Line 1337  for (;;) Line 1398  for (;;)
1398    
1399          if (i < md->name_count)          if (i < md->name_count)
1400            {            {
1401            uschar *slotB = slotA;            pcre_uchar *slotB = slotA;
1402            while (slotB > md->name_table)            while (slotB > md->name_table)
1403              {              {
1404              slotB -= md->name_entry_size;              slotB -= md->name_entry_size;
1405              if (strcmp((char *)slotA + 2, (char *)slotB + 2) == 0)              if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
1406                {                {
1407                offset = GET2(slotB, 0) << 1;                offset = GET2(slotB, 0) << 1;
1408                condition = offset < offset_top &&                condition = offset < offset_top &&
# Line 1359  for (;;) Line 1420  for (;;)
1420              for (i++; i < md->name_count; i++)              for (i++; i < md->name_count; i++)
1421                {                {
1422                slotB += md->name_entry_size;                slotB += md->name_entry_size;
1423                if (strcmp((char *)slotA + 2, (char *)slotB + 2) == 0)                if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
1424                  {                  {
1425                  offset = GET2(slotB, 0) << 1;                  offset = GET2(slotB, 0) << 1;
1426                  condition = offset < offset_top &&                  condition = offset < offset_top &&
# Line 1374  for (;;) Line 1435  for (;;)
1435    
1436        /* Chose branch according to the condition */        /* Chose branch according to the condition */
1437    
1438        ecode += condition? 3 : GET(ecode, 1);        ecode += condition? 1 + IMM2_SIZE : GET(ecode, 1);
1439        }        }
1440    
1441      else if (condcode == OP_DEF)     /* DEFINE - always false */      else if (condcode == OP_DEF)     /* DEFINE - always false */
# Line 1466  for (;;) Line 1527  for (;;)
1527        md->offset_vector[offset+1] = (int)(eptr - md->start_subject);        md->offset_vector[offset+1] = (int)(eptr - md->start_subject);
1528        if (offset_top <= offset) offset_top = offset + 2;        if (offset_top <= offset) offset_top = offset + 2;
1529        }        }
1530      ecode += 3;      ecode += 1 + IMM2_SIZE;
1531      break;      break;
1532    
1533    
# Line 1513  for (;;) Line 1574  for (;;)
1574    
1575      case OP_ASSERT:      case OP_ASSERT:
1576      case OP_ASSERTBACK:      case OP_ASSERTBACK:
1577        save_mark = md->mark;
1578      if (md->match_function_type == MATCH_CONDASSERT)      if (md->match_function_type == MATCH_CONDASSERT)
1579        {        {
1580        condassert = TRUE;        condassert = TRUE;
# Line 1528  for (;;) Line 1590  for (;;)
1590          mstart = md->start_match_ptr;   /* In case \K reset it */          mstart = md->start_match_ptr;   /* In case \K reset it */
1591          break;          break;
1592          }          }
1593          md->mark = save_mark;
1594    
1595        /* PCRE does not allow THEN to escape beyond an assertion; it is treated        /* A COMMIT failure must fail the entire assertion, without trying any
1596        as NOMATCH. */        subsequent branches. */
1597    
1598          if (rrc == MATCH_COMMIT) RRETURN(MATCH_NOMATCH);
1599    
1600          /* PCRE does not allow THEN to escape beyond an assertion; it
1601          is treated as NOMATCH. */
1602    
1603        if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);        if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);
1604        ecode += GET(ecode, 1);        ecode += GET(ecode, 1);
# Line 1557  for (;;) Line 1625  for (;;)
1625    
1626      case OP_ASSERT_NOT:      case OP_ASSERT_NOT:
1627      case OP_ASSERTBACK_NOT:      case OP_ASSERTBACK_NOT:
1628        save_mark = md->mark;
1629      if (md->match_function_type == MATCH_CONDASSERT)      if (md->match_function_type == MATCH_CONDASSERT)
1630        {        {
1631        condassert = TRUE;        condassert = TRUE;
# Line 1567  for (;;) Line 1636  for (;;)
1636      do      do
1637        {        {
1638        RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, NULL, RM5);        RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, NULL, RM5);
1639          md->mark = save_mark;
1640        if (rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) RRETURN(MATCH_NOMATCH);        if (rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) RRETURN(MATCH_NOMATCH);
1641        if (rrc == MATCH_SKIP || rrc == MATCH_PRUNE || rrc == MATCH_COMMIT)        if (rrc == MATCH_SKIP || rrc == MATCH_PRUNE || rrc == MATCH_COMMIT)
1642          {          {
# Line 1593  for (;;) Line 1663  for (;;)
1663      back a number of characters, not bytes. */      back a number of characters, not bytes. */
1664    
1665      case OP_REVERSE:      case OP_REVERSE:
1666  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1667      if (utf8)      if (utf)
1668        {        {
1669        i = GET(ecode, 1);        i = GET(ecode, 1);
1670        while (i-- > 0)        while (i-- > 0)
# Line 1625  for (;;) Line 1695  for (;;)
1695      function is able to force a failure. */      function is able to force a failure. */
1696    
1697      case OP_CALLOUT:      case OP_CALLOUT:
1698      if (pcre_callout != NULL)      if (PUBL(callout) != NULL)
1699        {        {
1700        pcre_callout_block cb;        PUBL(callout_block) cb;
1701        cb.version          = 2;   /* Version 1 of the callout block */        cb.version          = 2;   /* Version 1 of the callout block */
1702        cb.callout_number   = ecode[1];        cb.callout_number   = ecode[1];
1703        cb.offset_vector    = md->offset_vector;        cb.offset_vector    = md->offset_vector;
1704    #if defined COMPILE_PCRE8
1705        cb.subject          = (PCRE_SPTR)md->start_subject;        cb.subject          = (PCRE_SPTR)md->start_subject;
1706    #elif defined COMPILE_PCRE16
1707          cb.subject          = (PCRE_SPTR16)md->start_subject;
1708    #elif defined COMPILE_PCRE32
1709          cb.subject          = (PCRE_SPTR32)md->start_subject;
1710    #endif
1711        cb.subject_length   = (int)(md->end_subject - md->start_subject);        cb.subject_length   = (int)(md->end_subject - md->start_subject);
1712        cb.start_match      = (int)(mstart - md->start_subject);        cb.start_match      = (int)(mstart - md->start_subject);
1713        cb.current_position = (int)(eptr - md->start_subject);        cb.current_position = (int)(eptr - md->start_subject);
# Line 1641  for (;;) Line 1717  for (;;)
1717        cb.capture_last     = md->capture_last;        cb.capture_last     = md->capture_last;
1718        cb.callout_data     = md->callout_data;        cb.callout_data     = md->callout_data;
1719        cb.mark             = md->nomatch_mark;        cb.mark             = md->nomatch_mark;
1720        if ((rrc = (*pcre_callout)(&cb)) > 0) RRETURN(MATCH_NOMATCH);        if ((rrc = (*PUBL(callout))(&cb)) > 0) RRETURN(MATCH_NOMATCH);
1721        if (rrc < 0) RRETURN(rrc);        if (rrc < 0) RRETURN(rrc);
1722        }        }
1723      ecode += 2 + 2*LINK_SIZE;      ecode += 2 + 2*LINK_SIZE;
# Line 1667  for (;;) Line 1743  for (;;)
1743      case OP_RECURSE:      case OP_RECURSE:
1744        {        {
1745        recursion_info *ri;        recursion_info *ri;
1746        int recno;        unsigned int recno;
1747    
1748        callpat = md->start_code + GET(ecode, 1);        callpat = md->start_code + GET(ecode, 1);
1749        recno = (callpat == md->start_code)? 0 :        recno = (callpat == md->start_code)? 0 :
# Line 1700  for (;;) Line 1776  for (;;)
1776        else        else
1777          {          {
1778          new_recursive.offset_save =          new_recursive.offset_save =
1779            (int *)(pcre_malloc)(new_recursive.saved_max * sizeof(int));            (int *)(PUBL(malloc))(new_recursive.saved_max * sizeof(int));
1780          if (new_recursive.offset_save == NULL) RRETURN(PCRE_ERROR_NOMEMORY);          if (new_recursive.offset_save == NULL) RRETURN(PCRE_ERROR_NOMEMORY);
1781          }          }
1782        memcpy(new_recursive.offset_save, md->offset_vector,        memcpy(new_recursive.offset_save, md->offset_vector,
# Line 1715  for (;;) Line 1791  for (;;)
1791        do        do
1792          {          {
1793          if (cbegroup) md->match_function_type = MATCH_CBEGROUP;          if (cbegroup) md->match_function_type = MATCH_CBEGROUP;
1794          RMATCH(eptr, callpat + _pcre_OP_lengths[*callpat], offset_top,          RMATCH(eptr, callpat + PRIV(OP_lengths)[*callpat], offset_top,
1795            md, eptrb, RM6);            md, eptrb, RM6);
1796          memcpy(md->offset_vector, new_recursive.offset_save,          memcpy(md->offset_vector, new_recursive.offset_save,
1797              new_recursive.saved_max * sizeof(int));              new_recursive.saved_max * sizeof(int));
# Line 1724  for (;;) Line 1800  for (;;)
1800            {            {
1801            DPRINTF(("Recursion matched\n"));            DPRINTF(("Recursion matched\n"));
1802            if (new_recursive.offset_save != stacksave)            if (new_recursive.offset_save != stacksave)
1803              (pcre_free)(new_recursive.offset_save);              (PUBL(free))(new_recursive.offset_save);
1804    
1805            /* 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
1806            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 1735  for (;;) Line 1811  for (;;)
1811            goto RECURSION_MATCHED;        /* Exit loop; end processing */            goto RECURSION_MATCHED;        /* Exit loop; end processing */
1812            }            }
1813    
1814          /* 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
1815          as NOMATCH. */          is treated as NOMATCH. */
1816    
1817          else if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN)          else if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN &&
1818                     rrc != MATCH_COMMIT)
1819            {            {
1820            DPRINTF(("Recursion gave error %d\n", rrc));            DPRINTF(("Recursion gave error %d\n", rrc));
1821            if (new_recursive.offset_save != stacksave)            if (new_recursive.offset_save != stacksave)
1822              (pcre_free)(new_recursive.offset_save);              (PUBL(free))(new_recursive.offset_save);
1823            RRETURN(rrc);            RRETURN(rrc);
1824            }            }
1825    
# Line 1754  for (;;) Line 1831  for (;;)
1831        DPRINTF(("Recursion didn't match\n"));        DPRINTF(("Recursion didn't match\n"));
1832        md->recursive = new_recursive.prevrec;        md->recursive = new_recursive.prevrec;
1833        if (new_recursive.offset_save != stacksave)        if (new_recursive.offset_save != stacksave)
1834          (pcre_free)(new_recursive.offset_save);          (PUBL(free))(new_recursive.offset_save);
1835        RRETURN(MATCH_NOMATCH);        RRETURN(MATCH_NOMATCH);
1836        }        }
1837    
# Line 1949  for (;;) Line 2026  for (;;)
2026          }          }
2027        if (*prev >= OP_SBRA)    /* Could match an empty string */        if (*prev >= OP_SBRA)    /* Could match an empty string */
2028          {          {
         md->match_function_type = MATCH_CBEGROUP;  
2029          RMATCH(eptr, prev, offset_top, md, eptrb, RM50);          RMATCH(eptr, prev, offset_top, md, eptrb, RM50);
2030          RRETURN(rrc);          RRETURN(rrc);
2031          }          }
# Line 1958  for (;;) Line 2034  for (;;)
2034        }        }
2035      else  /* OP_KETRMAX */      else  /* OP_KETRMAX */
2036        {        {
       if (*prev >= OP_SBRA) md->match_function_type = MATCH_CBEGROUP;  
2037        RMATCH(eptr, prev, offset_top, md, eptrb, RM13);        RMATCH(eptr, prev, offset_top, md, eptrb, RM13);
2038        if (rrc == MATCH_ONCE && md->once_target == prev) rrc = MATCH_NOMATCH;        if (rrc == MATCH_ONCE && md->once_target == prev) rrc = MATCH_NOMATCH;
2039        if (rrc != MATCH_NOMATCH) RRETURN(rrc);        if (rrc != MATCH_NOMATCH) RRETURN(rrc);
# Line 2015  for (;;) Line 2090  for (;;)
2090    
2091      case OP_DOLLM:      case OP_DOLLM:
2092      if (eptr < md->end_subject)      if (eptr < md->end_subject)
2093        { if (!IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH); }        {
2094          if (!IS_NEWLINE(eptr))
2095            {
2096            if (md->partial != 0 &&
2097                eptr + 1 >= md->end_subject &&
2098                NLBLOCK->nltype == NLTYPE_FIXED &&
2099                NLBLOCK->nllen == 2 &&
2100                RAWUCHARTEST(eptr) == NLBLOCK->nl[0])
2101              {
2102              md->hitend = TRUE;
2103              if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
2104              }
2105            RRETURN(MATCH_NOMATCH);
2106            }
2107          }
2108      else      else
2109        {        {
2110        if (md->noteol) RRETURN(MATCH_NOMATCH);        if (md->noteol) RRETURN(MATCH_NOMATCH);
# Line 2047  for (;;) Line 2136  for (;;)
2136      ASSERT_NL_OR_EOS:      ASSERT_NL_OR_EOS:
2137      if (eptr < md->end_subject &&      if (eptr < md->end_subject &&
2138          (!IS_NEWLINE(eptr) || eptr != md->end_subject - md->nllen))          (!IS_NEWLINE(eptr) || eptr != md->end_subject - md->nllen))
2139          {
2140          if (md->partial != 0 &&
2141              eptr + 1 >= md->end_subject &&
2142              NLBLOCK->nltype == NLTYPE_FIXED &&
2143              NLBLOCK->nllen == 2 &&
2144              RAWUCHARTEST(eptr) == NLBLOCK->nl[0])
2145            {
2146            md->hitend = TRUE;
2147            if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
2148            }
2149        RRETURN(MATCH_NOMATCH);        RRETURN(MATCH_NOMATCH);
2150          }
2151    
2152      /* Either at end of string or \n before end. */      /* Either at end of string or \n before end. */
2153    
# Line 2066  for (;;) Line 2166  for (;;)
2166        be "non-word" characters. Remember the earliest consulted character for        be "non-word" characters. Remember the earliest consulted character for
2167        partial matching. */        partial matching. */
2168    
2169  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2170        if (utf8)        if (utf)
2171          {          {
2172          /* Get status of previous character */          /* Get status of previous character */
2173    
2174          if (eptr == md->start_subject) prev_is_word = FALSE; else          if (eptr == md->start_subject) prev_is_word = FALSE; else
2175            {            {
2176            USPTR lastptr = eptr - 1;            PCRE_PUCHAR lastptr = eptr - 1;
2177            while((*lastptr & 0xc0) == 0x80) lastptr--;            BACKCHAR(lastptr);
2178            if (lastptr < md->start_used_ptr) md->start_used_ptr = lastptr;            if (lastptr < md->start_used_ptr) md->start_used_ptr = lastptr;
2179            GETCHAR(c, lastptr);            GETCHAR(c, lastptr);
2180  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
# Line 2139  for (;;) Line 2239  for (;;)
2239              }              }
2240            else            else
2241  #endif  #endif
2242            prev_is_word = ((md->ctypes[eptr[-1]] & ctype_word) != 0);            prev_is_word = MAX_255(eptr[-1])
2243                && ((md->ctypes[eptr[-1]] & ctype_word) != 0);
2244            }            }
2245    
2246          /* Get status of next character */          /* Get status of next character */
# Line 2162  for (;;) Line 2263  for (;;)
2263            }            }
2264          else          else
2265  #endif  #endif
2266          cur_is_word = ((md->ctypes[*eptr] & ctype_word) != 0);          cur_is_word = MAX_255(*eptr)
2267              && ((md->ctypes[*eptr] & ctype_word) != 0);
2268          }          }
2269    
2270        /* Now see if the situation is what we want */        /* Now see if the situation is what we want */
# Line 2173  for (;;) Line 2275  for (;;)
2275        }        }
2276      break;      break;
2277    
2278      /* Match a single character type; inline for speed */      /* Match any single character type except newline; have to take care with
2279        CRLF newlines and partial matching. */
2280    
2281      case OP_ANY:      case OP_ANY:
2282      if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH);      if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH);
2283        if (md->partial != 0 &&
2284            eptr + 1 >= md->end_subject &&
2285            NLBLOCK->nltype == NLTYPE_FIXED &&
2286            NLBLOCK->nllen == 2 &&
2287            RAWUCHARTEST(eptr) == NLBLOCK->nl[0])
2288          {
2289          md->hitend = TRUE;
2290          if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
2291          }
2292    
2293      /* Fall through */      /* Fall through */
2294    
2295        /* Match any single character whatsoever. */
2296    
2297      case OP_ALLANY:      case OP_ALLANY:
2298      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 */
2299        {                            /* not be updated before SCHECK_PARTIAL. */        {                            /* not be updated before SCHECK_PARTIAL. */
# Line 2186  for (;;) Line 2301  for (;;)
2301        RRETURN(MATCH_NOMATCH);        RRETURN(MATCH_NOMATCH);
2302        }        }
2303      eptr++;      eptr++;
2304      if (utf8) while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;  #ifdef SUPPORT_UTF
2305        if (utf) ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
2306    #endif
2307      ecode++;      ecode++;
2308      break;      break;
2309    
# Line 2211  for (;;) Line 2328  for (;;)
2328        }        }
2329      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
2330      if (      if (
2331  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || !(defined COMPILE_PCRE8)
2332         c < 256 &&         c < 256 &&
2333  #endif  #endif
2334         (md->ctypes[c] & ctype_digit) != 0         (md->ctypes[c] & ctype_digit) != 0
# Line 2228  for (;;) Line 2345  for (;;)
2345        }        }
2346      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
2347      if (      if (
2348  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || !(defined COMPILE_PCRE8)
2349         c >= 256 ||         c > 255 ||
2350  #endif  #endif
2351         (md->ctypes[c] & ctype_digit) == 0         (md->ctypes[c] & ctype_digit) == 0
2352         )         )
# Line 2245  for (;;) Line 2362  for (;;)
2362        }        }
2363      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
2364      if (      if (
2365  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || !(defined COMPILE_PCRE8)
2366         c < 256 &&         c < 256 &&
2367  #endif  #endif
2368         (md->ctypes[c] & ctype_space) != 0         (md->ctypes[c] & ctype_space) != 0
# Line 2262  for (;;) Line 2379  for (;;)
2379        }        }
2380      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
2381      if (      if (
2382  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || !(defined COMPILE_PCRE8)
2383         c >= 256 ||         c > 255 ||
2384  #endif  #endif
2385         (md->ctypes[c] & ctype_space) == 0         (md->ctypes[c] & ctype_space) == 0
2386         )         )
# Line 2279  for (;;) Line 2396  for (;;)
2396        }        }
2397      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
2398      if (      if (
2399  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || !(defined COMPILE_PCRE8)
2400         c < 256 &&         c < 256 &&
2401  #endif  #endif
2402         (md->ctypes[c] & ctype_word) != 0         (md->ctypes[c] & ctype_word) != 0
# Line 2296  for (;;) Line 2413  for (;;)
2413        }        }
2414      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
2415      if (      if (
2416  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || !(defined COMPILE_PCRE8)
2417         c >= 256 ||         c > 255 ||
2418  #endif  #endif
2419         (md->ctypes[c] & ctype_word) == 0         (md->ctypes[c] & ctype_word) == 0
2420         )         )
# Line 2316  for (;;) Line 2433  for (;;)
2433        {        {
2434        default: RRETURN(MATCH_NOMATCH);        default: RRETURN(MATCH_NOMATCH);
2435    
2436        case 0x000d:        case CHAR_CR:
2437        if (eptr < md->end_subject && *eptr == 0x0a) eptr++;        if (eptr >= md->end_subject)
2438            {
2439            SCHECK_PARTIAL();
2440            }
2441          else if (RAWUCHARTEST(eptr) == CHAR_LF) eptr++;
2442        break;        break;
2443    
2444        case 0x000a:        case CHAR_LF:
2445        break;        break;
2446    
2447        case 0x000b:        case CHAR_VT:
2448        case 0x000c:        case CHAR_FF:
2449        case 0x0085:        case CHAR_NEL:
2450    #ifndef EBCDIC
2451        case 0x2028:        case 0x2028:
2452        case 0x2029:        case 0x2029:
2453    #endif  /* Not EBCDIC */
2454        if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH);        if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH);
2455        break;        break;
2456        }        }
# Line 2343  for (;;) Line 2466  for (;;)
2466      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
2467      switch(c)      switch(c)
2468        {        {
2469          HSPACE_CASES: RRETURN(MATCH_NOMATCH);  /* Byte and multibyte cases */
2470        default: break;        default: break;
       case 0x09:      /* HT */  
       case 0x20:      /* SPACE */  
       case 0xa0:      /* NBSP */  
       case 0x1680:    /* OGHAM SPACE MARK */  
       case 0x180e:    /* MONGOLIAN VOWEL SEPARATOR */  
       case 0x2000:    /* EN QUAD */  
       case 0x2001:    /* EM QUAD */  
       case 0x2002:    /* EN SPACE */  
       case 0x2003:    /* EM SPACE */  
       case 0x2004:    /* THREE-PER-EM SPACE */  
       case 0x2005:    /* FOUR-PER-EM SPACE */  
       case 0x2006:    /* SIX-PER-EM SPACE */  
       case 0x2007:    /* FIGURE SPACE */  
       case 0x2008:    /* PUNCTUATION SPACE */  
       case 0x2009:    /* THIN SPACE */  
       case 0x200A:    /* HAIR SPACE */  
       case 0x202f:    /* NARROW NO-BREAK SPACE */  
       case 0x205f:    /* MEDIUM MATHEMATICAL SPACE */  
       case 0x3000:    /* IDEOGRAPHIC SPACE */  
       RRETURN(MATCH_NOMATCH);  
2471        }        }
2472      ecode++;      ecode++;
2473      break;      break;
# Line 2377  for (;;) Line 2481  for (;;)
2481      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
2482      switch(c)      switch(c)
2483        {        {
2484          HSPACE_CASES: break;  /* Byte and multibyte cases */
2485        default: RRETURN(MATCH_NOMATCH);        default: RRETURN(MATCH_NOMATCH);
       case 0x09:      /* HT */  
       case 0x20:      /* SPACE */  
       case 0xa0:      /* NBSP */  
       case 0x1680:    /* OGHAM SPACE MARK */  
       case 0x180e:    /* MONGOLIAN VOWEL SEPARATOR */  
       case 0x2000:    /* EN QUAD */  
       case 0x2001:    /* EM QUAD */  
       case 0x2002:    /* EN SPACE */  
       case 0x2003:    /* EM SPACE */  
       case 0x2004:    /* THREE-PER-EM SPACE */  
       case 0x2005:    /* FOUR-PER-EM SPACE */  
       case 0x2006:    /* SIX-PER-EM SPACE */  
       case 0x2007:    /* FIGURE SPACE */  
       case 0x2008:    /* PUNCTUATION SPACE */  
       case 0x2009:    /* THIN SPACE */  
       case 0x200A:    /* HAIR SPACE */  
       case 0x202f:    /* NARROW NO-BREAK SPACE */  
       case 0x205f:    /* MEDIUM MATHEMATICAL SPACE */  
       case 0x3000:    /* IDEOGRAPHIC SPACE */  
       break;  
2486        }        }
2487      ecode++;      ecode++;
2488      break;      break;
# Line 2411  for (;;) Line 2496  for (;;)
2496      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
2497      switch(c)      switch(c)
2498        {        {
2499          VSPACE_CASES: RRETURN(MATCH_NOMATCH);
2500        default: break;        default: break;
       case 0x0a:      /* LF */  
       case 0x0b:      /* VT */  
       case 0x0c:      /* FF */  
       case 0x0d:      /* CR */  
       case 0x85:      /* NEL */  
       case 0x2028:    /* LINE SEPARATOR */  
       case 0x2029:    /* PARAGRAPH SEPARATOR */  
       RRETURN(MATCH_NOMATCH);  
2501        }        }
2502      ecode++;      ecode++;
2503      break;      break;
# Line 2433  for (;;) Line 2511  for (;;)
2511      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
2512      switch(c)      switch(c)
2513        {        {
2514          VSPACE_CASES: break;
2515        default: RRETURN(MATCH_NOMATCH);        default: RRETURN(MATCH_NOMATCH);
       case 0x0a:      /* LF */  
       case 0x0b:      /* VT */  
       case 0x0c:      /* FF */  
       case 0x0d:      /* CR */  
       case 0x85:      /* NEL */  
       case 0x2028:    /* LINE SEPARATOR */  
       case 0x2029:    /* PARAGRAPH SEPARATOR */  
       break;  
2516        }        }
2517      ecode++;      ecode++;
2518      break;      break;
# Line 2459  for (;;) Line 2530  for (;;)
2530        }        }
2531      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
2532        {        {
2533          const pcre_uint32 *cp;
2534        const ucd_record *prop = GET_UCD(c);        const ucd_record *prop = GET_UCD(c);
2535    
2536        switch(ecode[1])        switch(ecode[1])
# Line 2475  for (;;) Line 2547  for (;;)
2547          break;          break;
2548    
2549          case PT_GC:          case PT_GC:
2550          if ((ecode[2] != _pcre_ucp_gentype[prop->chartype]) == (op == OP_PROP))          if ((ecode[2] != PRIV(ucp_gentype)[prop->chartype]) == (op == OP_PROP))
2551            RRETURN(MATCH_NOMATCH);            RRETURN(MATCH_NOMATCH);
2552          break;          break;
2553    
# Line 2492  for (;;) Line 2564  for (;;)
2564          /* These are specials */          /* These are specials */
2565    
2566          case PT_ALNUM:          case PT_ALNUM:
2567          if ((_pcre_ucp_gentype[prop->chartype] == ucp_L ||          if ((PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
2568               _pcre_ucp_gentype[prop->chartype] == ucp_N) == (op == OP_NOTPROP))               PRIV(ucp_gentype)[prop->chartype] == ucp_N) == (op == OP_NOTPROP))
2569            RRETURN(MATCH_NOMATCH);            RRETURN(MATCH_NOMATCH);
2570          break;          break;
2571    
2572          case PT_SPACE:    /* Perl space */          case PT_SPACE:    /* Perl space */
2573          if ((_pcre_ucp_gentype[prop->chartype] == ucp_Z ||          if ((PRIV(ucp_gentype)[prop->chartype] == ucp_Z ||
2574               c == CHAR_HT || c == CHAR_NL || c == CHAR_FF || c == CHAR_CR)               c == CHAR_HT || c == CHAR_NL || c == CHAR_FF || c == CHAR_CR)
2575                 == (op == OP_NOTPROP))                 == (op == OP_NOTPROP))
2576            RRETURN(MATCH_NOMATCH);            RRETURN(MATCH_NOMATCH);
2577          break;          break;
2578    
2579          case PT_PXSPACE:  /* POSIX space */          case PT_PXSPACE:  /* POSIX space */
2580          if ((_pcre_ucp_gentype[prop->chartype] == ucp_Z ||          if ((PRIV(ucp_gentype)[prop->chartype] == ucp_Z ||
2581               c == CHAR_HT || c == CHAR_NL || c == CHAR_VT ||               c == CHAR_HT || c == CHAR_NL || c == CHAR_VT ||
2582               c == CHAR_FF || c == CHAR_CR)               c == CHAR_FF || c == CHAR_CR)
2583                 == (op == OP_NOTPROP))                 == (op == OP_NOTPROP))
# Line 2513  for (;;) Line 2585  for (;;)
2585          break;          break;
2586    
2587          case PT_WORD:          case PT_WORD:
2588          if ((_pcre_ucp_gentype[prop->chartype] == ucp_L ||          if ((PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
2589               _pcre_ucp_gentype[prop->chartype] == ucp_N ||               PRIV(ucp_gentype)[prop->chartype] == ucp_N ||
2590               c == CHAR_UNDERSCORE) == (op == OP_NOTPROP))               c == CHAR_UNDERSCORE) == (op == OP_NOTPROP))
2591            RRETURN(MATCH_NOMATCH);            RRETURN(MATCH_NOMATCH);
2592          break;          break;
2593    
2594            case PT_CLIST:
2595            cp = PRIV(ucd_caseless_sets) + prop->caseset;
2596            for (;;)
2597              {
2598              if (c < *cp)
2599                { if (op == OP_PROP) { RRETURN(MATCH_NOMATCH); } else break; }
2600              if (c == *cp++)
2601                { if (op == OP_PROP) break; else { RRETURN(MATCH_NOMATCH); } }
2602              }
2603            break;
2604    
2605          /* This should never occur */          /* This should never occur */
2606    
2607          default:          default:
# Line 2538  for (;;) Line 2621  for (;;)
2621        SCHECK_PARTIAL();        SCHECK_PARTIAL();
2622        RRETURN(MATCH_NOMATCH);        RRETURN(MATCH_NOMATCH);
2623        }        }
2624      GETCHARINCTEST(c, eptr);      else
     if (UCD_CATEGORY(c) == ucp_M) RRETURN(MATCH_NOMATCH);  
     while (eptr < md->end_subject)  
2625        {        {
2626        int len = 1;        int lgb, rgb;
2627        if (!utf8) c = *eptr; else { GETCHARLEN(c, eptr, len); }        GETCHARINCTEST(c, eptr);
2628        if (UCD_CATEGORY(c) != ucp_M) break;        lgb = UCD_GRAPHBREAK(c);
2629        eptr += len;        while (eptr < md->end_subject)
2630            {
2631            int len = 1;
2632            if (!utf) c = *eptr; else { GETCHARLEN(c, eptr, len); }
2633            rgb = UCD_GRAPHBREAK(c);
2634            if ((PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0) break;
2635            lgb = rgb;
2636            eptr += len;
2637            }
2638        }        }
2639        CHECK_PARTIAL();
2640      ecode++;      ecode++;
2641      break;      break;
2642  #endif  #endif  /* SUPPORT_UCP */
2643    
2644    
2645      /* Match a back reference, possibly repeatedly. Look past the end of the      /* Match a back reference, possibly repeatedly. Look past the end of the
# Line 2564  for (;;) Line 2654  for (;;)
2654      case OP_REFI:      case OP_REFI:
2655      caseless = op == OP_REFI;      caseless = op == OP_REFI;
2656      offset = GET2(ecode, 1) << 1;               /* Doubled ref number */      offset = GET2(ecode, 1) << 1;               /* Doubled ref number */
2657      ecode += 3;      ecode += 1 + IMM2_SIZE;
2658    
2659      /* If the reference is unset, there are two possibilities:      /* If the reference is unset, there are two possibilities:
2660    
# Line 2604  for (;;) Line 2694  for (;;)
2694        case OP_CRMINRANGE:        case OP_CRMINRANGE:
2695        minimize = (*ecode == OP_CRMINRANGE);        minimize = (*ecode == OP_CRMINRANGE);
2696        min = GET2(ecode, 1);        min = GET2(ecode, 1);
2697        max = GET2(ecode, 3);        max = GET2(ecode, 1 + IMM2_SIZE);
2698        if (max == 0) max = INT_MAX;        if (max == 0) max = INT_MAX;
2699        ecode += 5;        ecode += 1 + 2 * IMM2_SIZE;
2700        break;        break;
2701    
2702        default:               /* No repeat follows */        default:               /* No repeat follows */
2703        if ((length = match_ref(offset, eptr, length, md, caseless)) < 0)        if ((length = match_ref(offset, eptr, length, md, caseless)) < 0)
2704          {          {
2705            if (length == -2) eptr = md->end_subject;   /* Partial match */
2706          CHECK_PARTIAL();          CHECK_PARTIAL();
2707          RRETURN(MATCH_NOMATCH);          RRETURN(MATCH_NOMATCH);
2708          }          }
# Line 2620  for (;;) Line 2711  for (;;)
2711        }        }
2712    
2713      /* Handle repeated back references. If the length of the reference is      /* Handle repeated back references. If the length of the reference is
2714      zero, just continue with the main loop. */      zero, just continue with the main loop. If the length is negative, it
2715        means the reference is unset in non-Java-compatible mode. If the minimum is
2716        zero, we can continue at the same level without recursion. For any other
2717        minimum, carrying on will result in NOMATCH. */
2718    
2719      if (length == 0) continue;      if (length == 0) continue;
2720        if (length < 0 && min == 0) continue;
2721    
2722      /* First, ensure the minimum number of matches are present. We get back      /* First, ensure the minimum number of matches are present. We get back
2723      the length of the reference string explicitly rather than passing the      the length of the reference string explicitly rather than passing the
# Line 2633  for (;;) Line 2728  for (;;)
2728        int slength;        int slength;
2729        if ((slength = match_ref(offset, eptr, length, md, caseless)) < 0)        if ((slength = match_ref(offset, eptr, length, md, caseless)) < 0)
2730          {          {
2731            if (slength == -2) eptr = md->end_subject;   /* Partial match */
2732          CHECK_PARTIAL();          CHECK_PARTIAL();
2733          RRETURN(MATCH_NOMATCH);          RRETURN(MATCH_NOMATCH);
2734          }          }
# Line 2656  for (;;) Line 2752  for (;;)
2752          if (fi >= max) RRETURN(MATCH_NOMATCH);          if (fi >= max) RRETURN(MATCH_NOMATCH);
2753          if ((slength = match_ref(offset, eptr, length, md, caseless)) < 0)          if ((slength = match_ref(offset, eptr, length, md, caseless)) < 0)
2754            {            {
2755              if (slength == -2) eptr = md->end_subject;   /* Partial match */
2756            CHECK_PARTIAL();            CHECK_PARTIAL();
2757            RRETURN(MATCH_NOMATCH);            RRETURN(MATCH_NOMATCH);
2758            }            }
# Line 2674  for (;;) Line 2771  for (;;)
2771          int slength;          int slength;
2772          if ((slength = match_ref(offset, eptr, length, md, caseless)) < 0)          if ((slength = match_ref(offset, eptr, length, md, caseless)) < 0)
2773            {            {
2774            CHECK_PARTIAL();            /* Can't use CHECK_PARTIAL because we don't want to update eptr in
2775              the soft partial matching case. */
2776    
2777              if (slength == -2 && md->partial != 0 &&
2778                  md->end_subject > md->start_used_ptr)
2779                {
2780                md->hitend = TRUE;
2781                if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
2782                }
2783            break;            break;
2784            }            }
2785          eptr += slength;          eptr += slength;
2786          }          }
2787    
2788        while (eptr >= pp)        while (eptr >= pp)
2789          {          {
2790          RMATCH(eptr, ecode, offset_top, md, eptrb, RM15);          RMATCH(eptr, ecode, offset_top, md, eptrb, RM15);
# Line 2703  for (;;) Line 2809  for (;;)
2809      case OP_NCLASS:      case OP_NCLASS:
2810      case OP_CLASS:      case OP_CLASS:
2811        {        {
2812          /* The data variable is saved across frames, so the byte map needs to
2813          be stored there. */
2814    #define BYTE_MAP ((pcre_uint8 *)data)
2815        data = ecode + 1;                /* Save for matching */        data = ecode + 1;                /* Save for matching */
2816        ecode += 33;                     /* Advance past the item */        ecode += 1 + (32 / sizeof(pcre_uchar)); /* Advance past the item */
2817    
2818        switch (*ecode)        switch (*ecode)
2819          {          {
# Line 2725  for (;;) Line 2834  for (;;)
2834          case OP_CRMINRANGE:          case OP_CRMINRANGE:
2835          minimize = (*ecode == OP_CRMINRANGE);          minimize = (*ecode == OP_CRMINRANGE);
2836          min = GET2(ecode, 1);          min = GET2(ecode, 1);
2837          max = GET2(ecode, 3);          max = GET2(ecode, 1 + IMM2_SIZE);
2838          if (max == 0) max = INT_MAX;          if (max == 0) max = INT_MAX;
2839          ecode += 5;          ecode += 1 + 2 * IMM2_SIZE;
2840          break;          break;
2841    
2842          default:               /* No repeat follows */          default:               /* No repeat follows */
# Line 2737  for (;;) Line 2846  for (;;)
2846    
2847        /* First, ensure the minimum number of matches are present. */        /* First, ensure the minimum number of matches are present. */
2848    
2849  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2850        /* UTF-8 mode */        if (utf)
       if (utf8)  
2851          {          {
2852          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
2853            {            {
# Line 2754  for (;;) Line 2862  for (;;)
2862              if (op == OP_CLASS) RRETURN(MATCH_NOMATCH);              if (op == OP_CLASS) RRETURN(MATCH_NOMATCH);
2863              }              }
2864            else            else
2865              {              if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);
             if ((data[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);  
             }  
2866            }            }
2867          }          }
2868        else        else
2869  #endif  #endif
2870        /* Not UTF-8 mode */        /* Not UTF mode */
2871          {          {
2872          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
2873            {            {
# Line 2771  for (;;) Line 2877  for (;;)
2877              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
2878              }              }
2879            c = *eptr++;            c = *eptr++;
2880            if ((data[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);  #ifndef COMPILE_PCRE8
2881              if (c > 255)
2882                {
2883                if (op == OP_CLASS) RRETURN(MATCH_NOMATCH);
2884                }
2885              else
2886    #endif
2887                if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);
2888            }            }
2889          }          }
2890    
# Line 2785  for (;;) Line 2898  for (;;)
2898    
2899        if (minimize)        if (minimize)
2900          {          {
2901  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2902          /* UTF-8 mode */          if (utf)
         if (utf8)  
2903            {            {
2904            for (fi = min;; fi++)            for (fi = min;; fi++)
2905              {              {
# Line 2805  for (;;) Line 2917  for (;;)
2917                if (op == OP_CLASS) RRETURN(MATCH_NOMATCH);                if (op == OP_CLASS) RRETURN(MATCH_NOMATCH);
2918                }                }
2919              else              else
2920                {                if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);
               if ((data[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);  
               }  
2921              }              }
2922            }            }
2923          else          else
2924  #endif  #endif
2925          /* Not UTF-8 mode */          /* Not UTF mode */
2926            {            {
2927            for (fi = min;; fi++)            for (fi = min;; fi++)
2928              {              {
# Line 2825  for (;;) Line 2935  for (;;)
2935                RRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
2936                }                }
2937              c = *eptr++;              c = *eptr++;
2938              if ((data[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);  #ifndef COMPILE_PCRE8
2939                if (c > 255)
2940                  {
2941                  if (op == OP_CLASS) RRETURN(MATCH_NOMATCH);
2942                  }
2943                else
2944    #endif
2945                  if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);
2946              }              }
2947            }            }
2948          /* Control never gets here */          /* Control never gets here */
# Line 2837  for (;;) Line 2954  for (;;)
2954          {          {
2955          pp = eptr;          pp = eptr;
2956    
2957  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2958          /* UTF-8 mode */          if (utf)
         if (utf8)  
2959            {            {
2960            for (i = min; i < max; i++)            for (i = min; i < max; i++)
2961              {              {
# Line 2855  for (;;) Line 2971  for (;;)
2971                if (op == OP_CLASS) break;                if (op == OP_CLASS) break;
2972                }                }
2973              else              else
2974                {                if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) break;
               if ((data[c/8] & (1 << (c&7))) == 0) break;  
               }  
2975              eptr += len;              eptr += len;
2976              }              }
2977            for (;;)            for (;;)
# Line 2870  for (;;) Line 2984  for (;;)
2984            }            }
2985          else          else
2986  #endif  #endif
2987            /* Not UTF-8 mode */            /* Not UTF mode */
2988            {            {
2989            for (i = min; i < max; i++)            for (i = min; i < max; i++)
2990              {              {
# Line 2880  for (;;) Line 2994  for (;;)
2994                break;                break;
2995                }                }
2996              c = *eptr;              c = *eptr;
2997              if ((data[c/8] & (1 << (c&7))) == 0) break;  #ifndef COMPILE_PCRE8
2998                if (c > 255)
2999                  {
3000                  if (op == OP_CLASS) break;
3001                  }
3002                else
3003    #endif
3004                  if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) break;
3005              eptr++;              eptr++;
3006              }              }
3007            while (eptr >= pp)            while (eptr >= pp)
# Line 2893  for (;;) Line 3014  for (;;)
3014    
3015          RRETURN(MATCH_NOMATCH);          RRETURN(MATCH_NOMATCH);
3016          }          }
3017    #undef BYTE_MAP
3018        }        }
3019      /* Control never gets here */      /* Control never gets here */
3020    
# Line 2901  for (;;) Line 3023  for (;;)
3023      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
3024      mode, because Unicode properties are supported in non-UTF-8 mode. */      mode, because Unicode properties are supported in non-UTF-8 mode. */
3025    
3026  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
3027      case OP_XCLASS:      case OP_XCLASS:
3028        {        {
3029        data = ecode + 1 + LINK_SIZE;                /* Save for matching */        data = ecode + 1 + LINK_SIZE;                /* Save for matching */
# Line 2926  for (;;) Line 3048  for (;;)
3048          case OP_CRMINRANGE:          case OP_CRMINRANGE:
3049          minimize = (*ecode == OP_CRMINRANGE);          minimize = (*ecode == OP_CRMINRANGE);
3050          min = GET2(ecode, 1);          min = GET2(ecode, 1);
3051          max = GET2(ecode, 3);          max = GET2(ecode, 1 + IMM2_SIZE);
3052          if (max == 0) max = INT_MAX;          if (max == 0) max = INT_MAX;
3053          ecode += 5;          ecode += 1 + 2 * IMM2_SIZE;
3054          break;          break;
3055    
3056          default:               /* No repeat follows */          default:               /* No repeat follows */
# Line 2946  for (;;) Line 3068  for (;;)
3068            RRETURN(MATCH_NOMATCH);            RRETURN(MATCH_NOMATCH);
3069            }            }
3070          GETCHARINCTEST(c, eptr);          GETCHARINCTEST(c, eptr);
3071          if (!_pcre_xclass(c, data)) RRETURN(MATCH_NOMATCH);          if (!PRIV(xclass)(c, data, utf)) RRETURN(MATCH_NOMATCH);
3072          }          }
3073    
3074        /* 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 2970  for (;;) Line 3092  for (;;)
3092              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
3093              }              }
3094            GETCHARINCTEST(c, eptr);            GETCHARINCTEST(c, eptr);
3095            if (!_pcre_xclass(c, data)) RRETURN(MATCH_NOMATCH);            if (!PRIV(xclass)(c, data, utf)) RRETURN(MATCH_NOMATCH);
3096            }            }
3097          /* Control never gets here */          /* Control never gets here */
3098          }          }
# Line 2988  for (;;) Line 3110  for (;;)
3110              SCHECK_PARTIAL();              SCHECK_PARTIAL();
3111              break;              break;
3112              }              }
3113    #ifdef SUPPORT_UTF
3114            GETCHARLENTEST(c, eptr, len);            GETCHARLENTEST(c, eptr, len);
3115            if (!_pcre_xclass(c, data)) break;  #else
3116              c = *eptr;
3117    #endif
3118              if (!PRIV(xclass)(c, data, utf)) break;
3119            eptr += len;            eptr += len;
3120            }            }
3121          for(;;)          for(;;)
# Line 2997  for (;;) Line 3123  for (;;)
3123            RMATCH(eptr, ecode, offset_top, md, eptrb, RM21);            RMATCH(eptr, ecode, offset_top, md, eptrb, RM21);
3124            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3125            if (eptr-- == pp) break;        /* Stop if tried at original pos */            if (eptr-- == pp) break;        /* Stop if tried at original pos */
3126            if (utf8) BACKCHAR(eptr);  #ifdef SUPPORT_UTF
3127              if (utf) BACKCHAR(eptr);
3128    #endif
3129            }            }
3130          RRETURN(MATCH_NOMATCH);          RRETURN(MATCH_NOMATCH);
3131          }          }
# Line 3009  for (;;) Line 3137  for (;;)
3137      /* Match a single character, casefully */      /* Match a single character, casefully */
3138    
3139      case OP_CHAR:      case OP_CHAR:
3140  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3141      if (utf8)      if (utf)
3142        {        {
3143        length = 1;        length = 1;
3144        ecode++;        ecode++;
# Line 3020  for (;;) Line 3148  for (;;)
3148          CHECK_PARTIAL();             /* Not SCHECK_PARTIAL() */          CHECK_PARTIAL();             /* Not SCHECK_PARTIAL() */
3149          RRETURN(MATCH_NOMATCH);          RRETURN(MATCH_NOMATCH);
3150          }          }
3151        while (length-- > 0) if (*ecode++ != *eptr++) RRETURN(MATCH_NOMATCH);        while (length-- > 0) if (*ecode++ != RAWUCHARINC(eptr)) RRETURN(MATCH_NOMATCH);
3152        }        }
3153      else      else
3154  #endif  #endif
3155        /* Not UTF mode */
     /* Non-UTF-8 mode */  
3156        {        {
3157        if (md->end_subject - eptr < 1)        if (md->end_subject - eptr < 1)
3158          {          {
# Line 3037  for (;;) Line 3164  for (;;)
3164        }        }
3165      break;      break;
3166    
3167      /* Match a single character, caselessly */      /* Match a single character, caselessly. If we are at the end of the
3168        subject, give up immediately. */
3169    
3170      case OP_CHARI:      case OP_CHARI:
3171  #ifdef SUPPORT_UTF8      if (eptr >= md->end_subject)
3172      if (utf8)        {
3173          SCHECK_PARTIAL();
3174          RRETURN(MATCH_NOMATCH);
3175          }
3176    
3177    #ifdef SUPPORT_UTF
3178        if (utf)
3179        {        {
3180        length = 1;        length = 1;
3181        ecode++;        ecode++;
3182        GETCHARLEN(fc, ecode, length);        GETCHARLEN(fc, ecode, length);
3183    
       if (length > md->end_subject - eptr)  
         {  
         CHECK_PARTIAL();             /* Not SCHECK_PARTIAL() */  
         RRETURN(MATCH_NOMATCH);  
         }  
   
3184        /* 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
3185        can use the fast lookup table. */        we know that its other case must also be one byte long, so we can use the
3186          fast lookup table. We know that there is at least one byte left in the
3187          subject. */
3188    
3189        if (fc < 128)        if (fc < 128)
3190          {          {
3191          if (md->lcc[*ecode++] != md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH);          pcre_uchar cc = RAWUCHAR(eptr);
3192            if (md->lcc[fc] != TABLE_GET(cc, md->lcc, cc)) RRETURN(MATCH_NOMATCH);
3193            ecode++;
3194            eptr++;
3195          }          }
3196    
3197        /* Otherwise we must pick up the subject character */        /* Otherwise we must pick up the subject character. Note that we cannot
3198          use the value of "length" to check for sufficient bytes left, because the
3199          other case of the character may have more or fewer bytes.  */
3200    
3201        else        else
3202          {          {
3203          unsigned int dc;          pcre_uint32 dc;
3204          GETCHARINC(dc, eptr);          GETCHARINC(dc, eptr);
3205          ecode += length;          ecode += length;
3206    
# Line 3082  for (;;) Line 3217  for (;;)
3217          }          }
3218        }        }
3219      else      else
3220  #endif   /* SUPPORT_UTF8 */  #endif   /* SUPPORT_UTF */
3221    
3222      /* Non-UTF-8 mode */      /* Not UTF mode */
3223        {        {
3224        if (md->end_subject - eptr < 1)        if (TABLE_GET(ecode[1], md->lcc, ecode[1])
3225          {            != TABLE_GET(*eptr, md->lcc, *eptr)) RRETURN(MATCH_NOMATCH);
3226          SCHECK_PARTIAL();            /* This one can use SCHECK_PARTIAL() */        eptr++;
         RRETURN(MATCH_NOMATCH);  
         }  
       if (md->lcc[ecode[1]] != md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH);  
3227        ecode += 2;        ecode += 2;
3228        }        }
3229      break;      break;
# Line 3101  for (;;) Line 3233  for (;;)
3233      case OP_EXACT:      case OP_EXACT:
3234      case OP_EXACTI:      case OP_EXACTI:
3235      min = max = GET2(ecode, 1);      min = max = GET2(ecode, 1);
3236      ecode += 3;      ecode += 1 + IMM2_SIZE;
3237      goto REPEATCHAR;      goto REPEATCHAR;
3238    
3239      case OP_POSUPTO:      case OP_POSUPTO:
# Line 3116  for (;;) Line 3248  for (;;)
3248      min = 0;      min = 0;
3249      max = GET2(ecode, 1);      max = GET2(ecode, 1);
3250      minimize = *ecode == OP_MINUPTO || *ecode == OP_MINUPTOI;      minimize = *ecode == OP_MINUPTO || *ecode == OP_MINUPTOI;
3251      ecode += 3;      ecode += 1 + IMM2_SIZE;
3252      goto REPEATCHAR;      goto REPEATCHAR;
3253    
3254      case OP_POSSTAR:      case OP_POSSTAR:
# Line 3164  for (;;) Line 3296  for (;;)
3296      /* Common code for all repeated single-character matches. */      /* Common code for all repeated single-character matches. */
3297    
3298      REPEATCHAR:      REPEATCHAR:
3299  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3300      if (utf8)      if (utf)
3301        {        {
3302        length = 1;        length = 1;
3303        charptr = ecode;        charptr = ecode;
# Line 3178  for (;;) Line 3310  for (;;)
3310        if (length > 1)        if (length > 1)
3311          {          {
3312  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3313          unsigned int othercase;          pcre_uint32 othercase;
3314          if (op >= OP_STARI &&     /* Caseless */          if (op >= OP_STARI &&     /* Caseless */
3315              (othercase = UCD_OTHERCASE(fc)) != fc)              (othercase = UCD_OTHERCASE(fc)) != fc)
3316            oclength = _pcre_ord2utf8(othercase, occhars);            oclength = PRIV(ord2utf)(othercase, occhars);
3317          else oclength = 0;          else oclength = 0;
3318  #endif  /* SUPPORT_UCP */  #endif  /* SUPPORT_UCP */
3319    
3320          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3321            {            {
3322            if (eptr <= md->end_subject - length &&            if (eptr <= md->end_subject - length &&
3323              memcmp(eptr, charptr, length) == 0) eptr += length;              memcmp(eptr, charptr, IN_UCHARS(length)) == 0) eptr += length;
3324  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3325            else if (oclength > 0 &&            else if (oclength > 0 &&
3326                     eptr <= md->end_subject - oclength &&                     eptr <= md->end_subject - oclength &&
3327                     memcmp(eptr, occhars, oclength) == 0) eptr += oclength;                     memcmp(eptr, occhars, IN_UCHARS(oclength)) == 0) eptr += oclength;
3328  #endif  /* SUPPORT_UCP */  #endif  /* SUPPORT_UCP */
3329            else            else
3330              {              {
# Line 3211  for (;;) Line 3343  for (;;)
3343              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3344              if (fi >= max) RRETURN(MATCH_NOMATCH);              if (fi >= max) RRETURN(MATCH_NOMATCH);
3345              if (eptr <= md->end_subject - length &&              if (eptr <= md->end_subject - length &&
3346                memcmp(eptr, charptr, length) == 0) eptr += length;                memcmp(eptr, charptr, IN_UCHARS(length)) == 0) eptr += length;
3347  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3348              else if (oclength > 0 &&              else if (oclength > 0 &&
3349                       eptr <= md->end_subject - oclength &&                       eptr <= md->end_subject - oclength &&
3350                       memcmp(eptr, occhars, oclength) == 0) eptr += oclength;                       memcmp(eptr, occhars, IN_UCHARS(oclength)) == 0) eptr += oclength;
3351  #endif  /* SUPPORT_UCP */  #endif  /* SUPPORT_UCP */
3352              else              else
3353                {                {
# Line 3232  for (;;) Line 3364  for (;;)
3364            for (i = min; i < max; i++)            for (i = min; i < max; i++)
3365              {              {
3366              if (eptr <= md->end_subject - length &&              if (eptr <= md->end_subject - length &&
3367                  memcmp(eptr, charptr, length) == 0) eptr += length;                  memcmp(eptr, charptr, IN_UCHARS(length)) == 0) eptr += length;
3368  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3369              else if (oclength > 0 &&              else if (oclength > 0 &&
3370                       eptr <= md->end_subject - oclength &&                       eptr <= md->end_subject - oclength &&
3371                       memcmp(eptr, occhars, oclength) == 0) eptr += oclength;                       memcmp(eptr, occhars, IN_UCHARS(oclength)) == 0) eptr += oclength;
3372  #endif  /* SUPPORT_UCP */  #endif  /* SUPPORT_UCP */
3373              else              else
3374                {                {
# Line 3268  for (;;) Line 3400  for (;;)
3400        value of fc will always be < 128. */        value of fc will always be < 128. */
3401        }        }
3402      else      else
3403  #endif  /* SUPPORT_UTF8 */  #endif  /* SUPPORT_UTF */
3404          /* When not in UTF-8 mode, load a single-byte character. */
3405      /* When not in UTF-8 mode, load a single-byte character. */        fc = *ecode++;
3406    
3407      fc = *ecode++;      /* The value of fc at this point is always one character, though we may
3408        or may not be in UTF mode. The code is duplicated for the caseless and
     /* 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  
3409      caseful cases, for speed, since matching characters is likely to be quite      caseful cases, for speed, since matching characters is likely to be quite
3410      common. First, ensure the minimum number of matches are present. If min =      common. First, ensure the minimum number of matches are present. If min =
3411      max, continue at the same level without recursing. Otherwise, if      max, continue at the same level without recursing. Otherwise, if
# Line 3284  for (;;) Line 3414  for (;;)
3414      maximizing, find the maximum number of characters and work backwards. */      maximizing, find the maximum number of characters and work backwards. */
3415    
3416      DPRINTF(("matching %c{%d,%d} against subject %.*s\n", fc, min, max,      DPRINTF(("matching %c{%d,%d} against subject %.*s\n", fc, min, max,
3417        max, eptr));        max, (char *)eptr));
3418    
3419      if (op >= OP_STARI)  /* Caseless */      if (op >= OP_STARI)  /* Caseless */
3420        {        {
3421        fc = md->lcc[fc];  #ifdef COMPILE_PCRE8
3422          /* fc must be < 128 if UTF is enabled. */
3423          foc = md->fcc[fc];
3424    #else
3425    #ifdef SUPPORT_UTF
3426    #ifdef SUPPORT_UCP
3427          if (utf && fc > 127)
3428            foc = UCD_OTHERCASE(fc);
3429    #else
3430          if (utf && fc > 127)
3431            foc = fc;
3432    #endif /* SUPPORT_UCP */
3433          else
3434    #endif /* SUPPORT_UTF */
3435            foc = TABLE_GET(fc, md->fcc, fc);
3436    #endif /* COMPILE_PCRE8 */
3437    
3438        for (i = 1; i <= min; i++)        for (i = 1; i <= min; i++)
3439          {          {
3440            pcre_uchar cc;
3441    
3442          if (eptr >= md->end_subject)          if (eptr >= md->end_subject)
3443            {            {
3444            SCHECK_PARTIAL();            SCHECK_PARTIAL();
3445            RRETURN(MATCH_NOMATCH);            RRETURN(MATCH_NOMATCH);
3446            }            }
3447          if (fc != md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH);          cc = RAWUCHARTEST(eptr);
3448            if (fc != cc && foc != cc) RRETURN(MATCH_NOMATCH);
3449            eptr++;
3450          }          }
3451        if (min == max) continue;        if (min == max) continue;
3452        if (minimize)        if (minimize)
3453          {          {
3454          for (fi = min;; fi++)          for (fi = min;; fi++)
3455            {            {
3456              pcre_uchar cc;
3457    
3458            RMATCH(eptr, ecode, offset_top, md, eptrb, RM24);            RMATCH(eptr, ecode, offset_top, md, eptrb, RM24);
3459            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3460            if (fi >= max) RRETURN(MATCH_NOMATCH);            if (fi >= max) RRETURN(MATCH_NOMATCH);
# Line 3311  for (;;) Line 3463  for (;;)
3463              SCHECK_PARTIAL();              SCHECK_PARTIAL();
3464              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
3465              }              }
3466            if (fc != md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH);            cc = RAWUCHARTEST(eptr);
3467              if (fc != cc && foc != cc) RRETURN(MATCH_NOMATCH);
3468              eptr++;
3469            }            }
3470          /* Control never gets here */          /* Control never gets here */
3471          }          }
# Line 3320  for (;;) Line 3474  for (;;)
3474          pp = eptr;          pp = eptr;
3475          for (i = min; i < max; i++)          for (i = min; i < max; i++)
3476            {            {
3477              pcre_uchar cc;
3478    
3479            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
3480              {              {
3481              SCHECK_PARTIAL();              SCHECK_PARTIAL();
3482              break;              break;
3483              }              }
3484            if (fc != md->lcc[*eptr]) break;            cc = RAWUCHARTEST(eptr);
3485              if (fc != cc && foc != cc) break;
3486            eptr++;            eptr++;
3487            }            }
3488    
# Line 3353  for (;;) Line 3510  for (;;)
3510            SCHECK_PARTIAL();            SCHECK_PARTIAL();
3511            RRETURN(MATCH_NOMATCH);            RRETURN(MATCH_NOMATCH);
3512            }            }
3513          if (fc != *eptr++) RRETURN(MATCH_NOMATCH);          if (fc != RAWUCHARINCTEST(eptr)) RRETURN(MATCH_NOMATCH);
3514          }          }
3515    
3516        if (min == max) continue;        if (min == max) continue;
# Line 3370  for (;;) Line 3527  for (;;)
3527              SCHECK_PARTIAL();              SCHECK_PARTIAL();
3528              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
3529              }              }
3530            if (fc != *eptr++) RRETURN(MATCH_NOMATCH);            if (fc != RAWUCHARINCTEST(eptr)) RRETURN(MATCH_NOMATCH);
3531            }            }
3532          /* Control never gets here */          /* Control never gets here */
3533          }          }
# Line 3384  for (;;) Line 3541  for (;;)
3541              SCHECK_PARTIAL();              SCHECK_PARTIAL();
3542              break;              break;
3543              }              }
3544            if (fc != *eptr) break;            if (fc != RAWUCHARTEST(eptr)) break;
3545            eptr++;            eptr++;
3546            }            }
3547          if (possessive) continue;          if (possessive) continue;
# Line 3410  for (;;) Line 3567  for (;;)
3567        SCHECK_PARTIAL();        SCHECK_PARTIAL();
3568        RRETURN(MATCH_NOMATCH);        RRETURN(MATCH_NOMATCH);
3569        }        }
3570      ecode++;  #ifdef SUPPORT_UTF
3571      GETCHARINCTEST(c, eptr);      if (utf)
     if (op == OP_NOTI)         /* The caseless case */  
3572        {        {
3573  #ifdef SUPPORT_UTF8        register pcre_uint32 ch, och;
3574        if (c < 256)  
3575  #endif        ecode++;
3576        c = md->lcc[c];        GETCHARINC(ch, ecode);
3577        if (md->lcc[*ecode++] == c) RRETURN(MATCH_NOMATCH);        GETCHARINC(c, eptr);
3578    
3579          if (op == OP_NOT)
3580            {
3581            if (ch == c) RRETURN(MATCH_NOMATCH);
3582            }
3583          else
3584            {
3585    #ifdef SUPPORT_UCP
3586            if (ch > 127)
3587              och = UCD_OTHERCASE(ch);
3588    #else
3589            if (ch > 127)
3590              och = ch;
3591    #endif /* SUPPORT_UCP */
3592            else
3593              och = TABLE_GET(ch, md->fcc, ch);
3594            if (ch == c || och == c) RRETURN(MATCH_NOMATCH);
3595            }
3596        }        }
3597      else    /* Caseful */      else
3598    #endif
3599        {        {
3600        if (*ecode++ == c) RRETURN(MATCH_NOMATCH);        register pcre_uint32 ch = ecode[1];
3601          c = *eptr++;
3602          if (ch == c || (op == OP_NOTI && TABLE_GET(ch, md->fcc, ch) == c))
3603            RRETURN(MATCH_NOMATCH);
3604          ecode += 2;
3605        }        }
3606      break;      break;
3607    
# Line 3436  for (;;) Line 3615  for (;;)
3615      case OP_NOTEXACT:      case OP_NOTEXACT:
3616      case OP_NOTEXACTI:      case OP_NOTEXACTI:
3617      min = max = GET2(ecode, 1);      min = max = GET2(ecode, 1);
3618      ecode += 3;      ecode += 1 + IMM2_SIZE;
3619      goto REPEATNOTCHAR;      goto REPEATNOTCHAR;
3620    
3621      case OP_NOTUPTO:      case OP_NOTUPTO:
# Line 3446  for (;;) Line 3625  for (;;)
3625      min = 0;      min = 0;
3626      max = GET2(ecode, 1);      max = GET2(ecode, 1);
3627      minimize = *ecode == OP_NOTMINUPTO || *ecode == OP_NOTMINUPTOI;      minimize = *ecode == OP_NOTMINUPTO || *ecode == OP_NOTMINUPTOI;
3628      ecode += 3;      ecode += 1 + IMM2_SIZE;
3629      goto REPEATNOTCHAR;      goto REPEATNOTCHAR;
3630    
3631      case OP_NOTPOSSTAR:      case OP_NOTPOSSTAR:
# Line 3478  for (;;) Line 3657  for (;;)
3657      possessive = TRUE;      possessive = TRUE;
3658      min = 0;      min = 0;
3659      max = GET2(ecode, 1);      max = GET2(ecode, 1);
3660      ecode += 3;      ecode += 1 + IMM2_SIZE;
3661      goto REPEATNOTCHAR;      goto REPEATNOTCHAR;
3662    
3663      case OP_NOTSTAR:      case OP_NOTSTAR:
# Line 3502  for (;;) Line 3681  for (;;)
3681      /* Common code for all repeated single-byte matches. */      /* Common code for all repeated single-byte matches. */
3682    
3683      REPEATNOTCHAR:      REPEATNOTCHAR:
3684      fc = *ecode++;      GETCHARINCTEST(fc, ecode);
3685    
3686      /* The code is duplicated for the caseless and caseful cases, for speed,      /* The code is duplicated for the caseless and caseful cases, for speed,
3687      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 3513  for (;;) Line 3692  for (;;)
3692      characters and work backwards. */      characters and work backwards. */
3693    
3694      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,
3695        max, eptr));        max, (char *)eptr));
3696    
3697      if (op >= OP_NOTSTARI)     /* Caseless */      if (op >= OP_NOTSTARI)     /* Caseless */
3698        {        {
3699        fc = md->lcc[fc];  #ifdef SUPPORT_UTF
3700    #ifdef SUPPORT_UCP
3701          if (utf && fc > 127)
3702            foc = UCD_OTHERCASE(fc);
3703    #else
3704          if (utf && fc > 127)
3705            foc = fc;
3706    #endif /* SUPPORT_UCP */
3707          else
3708    #endif /* SUPPORT_UTF */
3709            foc = TABLE_GET(fc, md->fcc, fc);
3710    
3711  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3712        /* UTF-8 mode */        if (utf)
       if (utf8)  
3713          {          {
3714          register unsigned int d;          register pcre_uint32 d;
3715          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3716            {            {
3717            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
# Line 3532  for (;;) Line 3720  for (;;)
3720              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
3721              }              }
3722            GETCHARINC(d, eptr);            GETCHARINC(d, eptr);
3723            if (d < 256) d = md->lcc[d];            if (fc == d || (unsigned int)foc == d) RRETURN(MATCH_NOMATCH);
           if (fc == d) RRETURN(MATCH_NOMATCH);  
3724            }            }
3725          }          }
3726        else        else
3727  #endif  #endif
3728          /* Not UTF mode */
       /* Not UTF-8 mode */  
3729          {          {
3730          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3731            {            {
# Line 3548  for (;;) Line 3734  for (;;)
3734              SCHECK_PARTIAL();              SCHECK_PARTIAL();
3735              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
3736              }              }
3737            if (fc == md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH);            if (fc == *eptr || foc == *eptr) RRETURN(MATCH_NOMATCH);
3738              eptr++;
3739            }            }
3740          }          }
3741    
# Line 3556  for (;;) Line 3743  for (;;)
3743    
3744        if (minimize)        if (minimize)
3745          {          {
3746  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3747          /* UTF-8 mode */          if (utf)
         if (utf8)  
3748            {            {
3749            register unsigned int d;            register pcre_uint32 d;
3750            for (fi = min;; fi++)            for (fi = min;; fi++)
3751              {              {
3752              RMATCH(eptr, ecode, offset_top, md, eptrb, RM28);              RMATCH(eptr, ecode, offset_top, md, eptrb, RM28);
# Line 3572  for (;;) Line 3758  for (;;)
3758                RRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
3759                }                }
3760              GETCHARINC(d, eptr);              GETCHARINC(d, eptr);
3761              if (d < 256) d = md->lcc[d];              if (fc == d || (unsigned int)foc == d) RRETURN(MATCH_NOMATCH);
             if (fc == d) RRETURN(MATCH_NOMATCH);  
3762              }              }
3763            }            }
3764          else          else
3765  #endif  #endif
3766          /* Not UTF-8 mode */          /* Not UTF mode */
3767            {            {
3768            for (fi = min;; fi++)            for (fi = min;; fi++)
3769              {              {
# Line 3590  for (;;) Line 3775  for (;;)
3775                SCHECK_PARTIAL();                SCHECK_PARTIAL();
3776                RRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
3777                }                }
3778              if (fc == md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH);              if (fc == *eptr || foc == *eptr) RRETURN(MATCH_NOMATCH);
3779                eptr++;
3780              }              }
3781            }            }
3782          /* Control never gets here */          /* Control never gets here */
# Line 3602  for (;;) Line 3788  for (;;)
3788          {          {
3789          pp = eptr;          pp = eptr;
3790    
3791  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3792          /* UTF-8 mode */          if (utf)
         if (utf8)  
3793            {            {
3794            register unsigned int d;            register pcre_uint32 d;
3795            for (i = min; i < max; i++)            for (i = min; i < max; i++)
3796              {              {
3797              int len = 1;              int len = 1;
# Line 3616  for (;;) Line 3801  for (;;)
3801                break;                break;
3802                }                }
3803              GETCHARLEN(d, eptr, len);              GETCHARLEN(d, eptr, len);
3804              if (d < 256) d = md->lcc[d];              if (fc == d || (unsigned int)foc == d) break;
             if (fc == d) break;  
3805              eptr += len;              eptr += len;
3806              }              }
3807          if (possessive) continue;            if (possessive) continue;
3808          for(;;)            for(;;)
3809              {              {
3810              RMATCH(eptr, ecode, offset_top, md, eptrb, RM30);              RMATCH(eptr, ecode, offset_top, md, eptrb, RM30);
3811              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
# Line 3631  for (;;) Line 3815  for (;;)
3815            }            }
3816          else          else
3817  #endif  #endif
3818          /* Not UTF-8 mode */          /* Not UTF mode */
3819            {            {
3820            for (i = min; i < max; i++)            for (i = min; i < max; i++)
3821              {              {
# Line 3640  for (;;) Line 3824  for (;;)
3824                SCHECK_PARTIAL();                SCHECK_PARTIAL();
3825                break;                break;
3826                }                }
3827              if (fc == md->lcc[*eptr]) break;              if (fc == *eptr || foc == *eptr) break;
3828              eptr++;              eptr++;
3829              }              }
3830            if (possessive) continue;            if (possessive) continue;
# Line 3661  for (;;) Line 3845  for (;;)
3845    
3846      else      else
3847        {        {
3848  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3849        /* UTF-8 mode */        if (utf)
       if (utf8)  
3850          {          {
3851          register unsigned int d;          register pcre_uint32 d;
3852          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3853            {            {
3854            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
# Line 3679  for (;;) Line 3862  for (;;)
3862          }          }
3863        else        else
3864  #endif  #endif
3865        /* Not UTF-8 mode */        /* Not UTF mode */
3866          {          {
3867          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3868            {            {
# Line 3696  for (;;) Line 3879  for (;;)
3879    
3880        if (minimize)        if (minimize)
3881          {          {
3882  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3883          /* UTF-8 mode */          if (utf)
         if (utf8)  
3884            {            {
3885            register unsigned int d;            register pcre_uint32 d;
3886            for (fi = min;; fi++)            for (fi = min;; fi++)
3887              {              {
3888              RMATCH(eptr, ecode, offset_top, md, eptrb, RM32);              RMATCH(eptr, ecode, offset_top, md, eptrb, RM32);
# Line 3717  for (;;) Line 3899  for (;;)
3899            }            }
3900          else          else
3901  #endif  #endif
3902          /* Not UTF-8 mode */          /* Not UTF mode */
3903            {            {
3904            for (fi = min;; fi++)            for (fi = min;; fi++)
3905              {              {
# Line 3741  for (;;) Line 3923  for (;;)
3923          {          {
3924          pp = eptr;          pp = eptr;
3925    
3926  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3927          /* UTF-8 mode */          if (utf)
         if (utf8)  
3928            {            {
3929            register unsigned int d;            register pcre_uint32 d;
3930            for (i = min; i < max; i++)            for (i = min; i < max; i++)
3931              {              {
3932              int len = 1;              int len = 1;
# Line 3769  for (;;) Line 3950  for (;;)
3950            }            }
3951          else          else
3952  #endif  #endif
3953          /* Not UTF-8 mode */          /* Not UTF mode */
3954            {            {
3955            for (i = min; i < max; i++)            for (i = min; i < max; i++)
3956              {              {
# Line 3802  for (;;) Line 3983  for (;;)
3983      case OP_TYPEEXACT:      case OP_TYPEEXACT:
3984      min = max = GET2(ecode, 1);      min = max = GET2(ecode, 1);
3985      minimize = TRUE;      minimize = TRUE;
3986      ecode += 3;      ecode += 1 + IMM2_SIZE;
3987      goto REPEATTYPE;      goto REPEATTYPE;
3988    
3989      case OP_TYPEUPTO:      case OP_TYPEUPTO:
# Line 3810  for (;;) Line 3991  for (;;)
3991      min = 0;      min = 0;
3992      max = GET2(ecode, 1);      max = GET2(ecode, 1);
3993      minimize = *ecode == OP_TYPEMINUPTO;      minimize = *ecode == OP_TYPEMINUPTO;
3994      ecode += 3;      ecode += 1 + IMM2_SIZE;
3995      goto REPEATTYPE;      goto REPEATTYPE;
3996    
3997      case OP_TYPEPOSSTAR:      case OP_TYPEPOSSTAR:
# Line 3838  for (;;) Line 4019  for (;;)
4019      possessive = TRUE;      possessive = TRUE;
4020      min = 0;      min = 0;
4021      max = GET2(ecode, 1);      max = GET2(ecode, 1);
4022      ecode += 3;      ecode += 1 + IMM2_SIZE;
4023      goto REPEATTYPE;      goto REPEATTYPE;
4024    
4025      case OP_TYPESTAR:      case OP_TYPESTAR:
# Line 4020  for (;;) Line 4201  for (;;)
4201                RRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4202              }              }
4203            break;            break;
4204    
4205              case PT_CLIST:
4206              for (i = 1; i <= min; i++)
4207                {
4208                const pcre_uint32 *cp;
4209                if (eptr >= md->end_subject)
4210                  {
4211                  SCHECK_PARTIAL();
4212                  RRETURN(MATCH_NOMATCH);
4213                  }
4214                GETCHARINCTEST(c, eptr);
4215                cp = PRIV(ucd_caseless_sets) + UCD_CASESET(c);
4216                for (;;)
4217                  {
4218                  if (c < *cp)
4219                    { if (prop_fail_result) break; else { RRETURN(MATCH_NOMATCH); } }
4220                  if (c == *cp++)
4221                    { if (prop_fail_result) { RRETURN(MATCH_NOMATCH); } else break; }
4222                  }
4223                }
4224              break;
4225    
4226            /* This should not occur */            /* This should not occur */
4227    
4228            default:            default:
# Line 4040  for (;;) Line 4242  for (;;)
4242              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4243              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4244              }              }
4245            GETCHARINCTEST(c, eptr);            else
           if (UCD_CATEGORY(c) == ucp_M) RRETURN(MATCH_NOMATCH);  
           while (eptr < md->end_subject)  
4246              {              {
4247              int len = 1;              int lgb, rgb;
4248              if (!utf8) c = *eptr; else { GETCHARLEN(c, eptr, len); }              GETCHARINCTEST(c, eptr);
4249              if (UCD_CATEGORY(c) != ucp_M) break;              lgb = UCD_GRAPHBREAK(c);
4250              eptr += len;             while (eptr < md->end_subject)
4251                  {
4252                  int len = 1;
4253                  if (!utf) c = *eptr; else { GETCHARLEN(c, eptr, len); }
4254                  rgb = UCD_GRAPHBREAK(c);
4255                  if ((PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0) break;
4256                  lgb = rgb;
4257                  eptr += len;
4258                  }
4259              }              }
4260              CHECK_PARTIAL();
4261            }            }
4262          }          }
4263    
# Line 4057  for (;;) Line 4266  for (;;)
4266    
4267  /* Handle all other cases when the coding is UTF-8 */  /* Handle all other cases when the coding is UTF-8 */
4268    
4269  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
4270        if (utf8) switch(ctype)        if (utf) switch(ctype)
4271          {          {
4272          case OP_ANY:          case OP_ANY:
4273          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
# Line 4069  for (;;) Line 4278  for (;;)
4278              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4279              }              }
4280            if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH);            if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH);
4281              if (md->partial != 0 &&
4282                  eptr + 1 >= md->end_subject &&
4283                  NLBLOCK->nltype == NLTYPE_FIXED &&
4284                  NLBLOCK->nllen == 2 &&
4285                  RAWUCHAR(eptr) == NLBLOCK->nl[0])
4286                {
4287                md->hitend = TRUE;
4288                if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
4289                }
4290            eptr++;            eptr++;
4291            while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;            ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
4292            }            }
4293          break;          break;
4294    
# Line 4083  for (;;) Line 4301  for (;;)
4301              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4302              }              }
4303            eptr++;            eptr++;
4304            while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;            ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
4305            }            }
4306          break;          break;
4307    
# Line 4105  for (;;) Line 4323  for (;;)
4323              {              {
4324              default: RRETURN(MATCH_NOMATCH);              default: RRETURN(MATCH_NOMATCH);
4325    
4326              case 0x000d:              case CHAR_CR:
4327              if (eptr < md->end_subject && *eptr == 0x0a) eptr++;              if (eptr < md->end_subject && RAWUCHAR(eptr) == CHAR_LF) eptr++;
4328              break;              break;
4329    
4330              case 0x000a:              case CHAR_LF:
4331              break;              break;
4332    
4333              case 0x000b:              case CHAR_VT:
4334              case 0x000c:              case CHAR_FF:
4335              case 0x0085:              case CHAR_NEL:
4336    #ifndef EBCDIC
4337              case 0x2028:              case 0x2028:
4338              case 0x2029:              case 0x2029:
4339    #endif  /* Not EBCDIC */
4340              if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH);              if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH);
4341              break;              break;
4342              }              }
# Line 4134  for (;;) Line 4354  for (;;)
4354            GETCHARINC(c, eptr);            GETCHARINC(c, eptr);
4355            switch(c)            switch(c)
4356              {              {
4357                HSPACE_CASES: RRETURN(MATCH_NOMATCH);  /* Byte and multibyte cases */
4358              default: break;              default: break;
             case 0x09:      /* HT */  
             case 0x20:      /* SPACE */  
             case 0xa0:      /* NBSP */  
             case 0x1680:    /* OGHAM SPACE MARK */  
             case 0x180e:    /* MONGOLIAN VOWEL SEPARATOR */  
             case 0x2000:    /* EN QUAD */  
             case 0x2001:    /* EM QUAD */  
             case 0x2002:    /* EN SPACE */  
             case 0x2003:    /* EM SPACE */  
             case 0x2004:    /* THREE-PER-EM SPACE */  
             case 0x2005:    /* FOUR-PER-EM SPACE */  
             case 0x2006:    /* SIX-PER-EM SPACE */  
             case 0x2007:    /* FIGURE SPACE */  
             case 0x2008:    /* PUNCTUATION SPACE */  
             case 0x2009:    /* THIN SPACE */  
             case 0x200A:    /* HAIR SPACE */  
             case 0x202f:    /* NARROW NO-BREAK SPACE */  
             case 0x205f:    /* MEDIUM MATHEMATICAL SPACE */  
             case 0x3000:    /* IDEOGRAPHIC SPACE */  
             RRETURN(MATCH_NOMATCH);  
4359              }              }
4360            }            }
4361          break;          break;
# Line 4170  for (;;) Line 4371  for (;;)
4371            GETCHARINC(c, eptr);            GETCHARINC(c, eptr);
4372            switch(c)            switch(c)
4373              {              {
4374                HSPACE_CASES: break;  /* Byte and multibyte cases */
4375              default: RRETURN(MATCH_NOMATCH);              default: RRETURN(MATCH_NOMATCH);
             case 0x09:      /* HT */  
             case 0x20:      /* SPACE */  
             case 0xa0:      /* NBSP */  
             case 0x1680:    /* OGHAM SPACE MARK */  
             case 0x180e:    /* MONGOLIAN VOWEL SEPARATOR */  
             case 0x2000:    /* EN QUAD */  
             case 0x2001:    /* EM QUAD */  
             case 0x2002:    /* EN SPACE */  
             case 0x2003:    /* EM SPACE */  
             case 0x2004:    /* THREE-PER-EM SPACE */  
             case 0x2005:    /* FOUR-PER-EM SPACE */  
             case 0x2006:    /* SIX-PER-EM SPACE */  
             case 0x2007:    /* FIGURE SPACE */  
             case 0x2008:    /* PUNCTUATION SPACE */  
             case 0x2009:    /* THIN SPACE */  
             case 0x200A:    /* HAIR SPACE */  
             case 0x202f:    /* NARROW NO-BREAK SPACE */  
             case 0x205f:    /* MEDIUM MATHEMATICAL SPACE */  
             case 0x3000:    /* IDEOGRAPHIC SPACE */  
             break;  
4376              }              }
4377            }            }
4378          break;          break;
# Line 4206  for (;;) Line 4388  for (;;)
4388            GETCHARINC(c, eptr);            GETCHARINC(c, eptr);
4389            switch(c)            switch(c)
4390              {              {
4391                VSPACE_CASES: RRETURN(MATCH_NOMATCH);
4392              default: break;              default: break;
             case 0x0a:      /* LF */  
             case 0x0b:      /* VT */  
             case 0x0c:      /* FF */  
             case 0x0d:      /* CR */  
             case 0x85:      /* NEL */  
             case 0x2028:    /* LINE SEPARATOR */  
             case 0x2029:    /* PARAGRAPH SEPARATOR */  
             RRETURN(MATCH_NOMATCH);  
4393              }              }
4394            }            }
4395          break;          break;
# Line 4230  for (;;) Line 4405  for (;;)
4405            GETCHARINC(c, eptr);            GETCHARINC(c, eptr);
4406            switch(c)            switch(c)
4407              {              {
4408                VSPACE_CASES: break;
4409              default: RRETURN(MATCH_NOMATCH);              default: RRETURN(MATCH_NOMATCH);
             case 0x0a:      /* LF */  
             case 0x0b:      /* VT */  
             case 0x0c:      /* FF */  
             case 0x0d:      /* CR */  
             case 0x85:      /* NEL */  
             case 0x2028:    /* LINE SEPARATOR */  
             case 0x2029:    /* PARAGRAPH SEPARATOR */  
             break;  
4410              }              }
4411            }            }
4412          break;          break;
# Line 4260  for (;;) Line 4428  for (;;)
4428          case OP_DIGIT:          case OP_DIGIT:
4429          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
4430            {            {
4431              pcre_uchar cc;
4432    
4433            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4434              {              {
4435              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4436              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4437              }              }
4438            if (*eptr >= 128 || (md->ctypes[*eptr++] & ctype_digit) == 0)            cc = RAWUCHAR(eptr);
4439              if (cc >= 128 || (md->ctypes[cc] & ctype_digit) == 0)
4440              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4441              eptr++;
4442            /* 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 */
4443            }            }
4444          break;          break;
# Line 4274  for (;;) Line 4446  for (;;)
4446          case OP_NOT_WHITESPACE:          case OP_NOT_WHITESPACE:
4447          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
4448            {            {
4449              pcre_uchar cc;
4450    
4451            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4452              {              {
4453              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4454              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4455              }              }
4456            if (*eptr < 128 && (md->ctypes[*eptr] & ctype_space) != 0)            cc = RAWUCHAR(eptr);
4457              if (cc < 128 && (md->ctypes[cc] & ctype_space) != 0)
4458              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4459            while (++eptr < md->end_subject && (*eptr & 0xc0) == 0x80);            eptr++;
4460              ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
4461            }            }
4462          break;          break;
4463    
4464          case OP_WHITESPACE:          case OP_WHITESPACE:
4465          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
4466            {            {
4467              pcre_uchar cc;
4468    
4469            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4470              {              {
4471              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4472              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4473              }              }
4474            if (*eptr >= 128 || (md->ctypes[*eptr++] & ctype_space) == 0)            cc = RAWUCHAR(eptr);
4475              if (cc >= 128 || (md->ctypes[cc] & ctype_space) == 0)
4476              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4477              eptr++;
4478            /* 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 */
4479            }            }
4480          break;          break;
# Line 4302  for (;;) Line 4482  for (;;)
4482          case OP_NOT_WORDCHAR:          case OP_NOT_WORDCHAR:
4483          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
4484            {            {
4485              pcre_uchar cc;
4486    
4487            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4488              {              {
4489              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4490              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4491              }              }
4492            if (*eptr < 128 && (md->ctypes[*eptr] & ctype_word) != 0)            cc = RAWUCHAR(eptr);
4493              if (cc < 128 && (md->ctypes[cc] & ctype_word) != 0)
4494              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4495            while (++eptr < md->end_subject && (*eptr & 0xc0) == 0x80);            eptr++;
4496              ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
4497            }            }
4498          break;          break;
4499    
4500          case OP_WORDCHAR:          case OP_WORDCHAR:
4501          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
4502            {            {
4503              pcre_uchar cc;
4504    
4505            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4506              {              {
4507              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4508              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4509              }              }
4510            if (*eptr >= 128 || (md->ctypes[*eptr++] & ctype_word) == 0)            cc = RAWUCHAR(eptr);
4511              if (cc >= 128 || (md->ctypes[cc] & ctype_word) == 0)
4512              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4513              eptr++;
4514            /* 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 */
4515            }            }
4516          break;          break;
# Line 4332  for (;;) Line 4520  for (;;)
4520          }  /* End switch(ctype) */          }  /* End switch(ctype) */
4521    
4522        else        else
4523  #endif     /* SUPPORT_UTF8 */  #endif     /* SUPPORT_UTF */
4524    
4525        /* 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
4526        than OP_PROP and OP_NOTPROP. */        than OP_PROP and OP_NOTPROP. */
# Line 4348  for (;;) Line 4536  for (;;)
4536              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4537              }              }
4538            if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH);            if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH);
4539              if (md->partial != 0 &&
4540                  eptr + 1 >= md->end_subject &&
4541                  NLBLOCK->nltype == NLTYPE_FIXED &&
4542                  NLBLOCK->nllen == 2 &&
4543                  *eptr == NLBLOCK->nl[0])
4544                {
4545                md->hitend = TRUE;
4546                if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
4547                }
4548            eptr++;            eptr++;
4549            }            }
4550          break;          break;
# Line 4382  for (;;) Line 4579  for (;;)
4579              {              {
4580              default: RRETURN(MATCH_NOMATCH);              default: RRETURN(MATCH_NOMATCH);
4581    
4582              case 0x000d:              case CHAR_CR:
4583              if (eptr < md->end_subject && *eptr == 0x0a) eptr++;              if (eptr < md->end_subject && *eptr == CHAR_LF) eptr++;
4584              break;              break;
4585    
4586              case 0x000a:              case CHAR_LF:
4587              break;              break;
4588    
4589              case 0x000b:              case CHAR_VT:
4590              case 0x000c:              case CHAR_FF:
4591              case 0x0085:              case CHAR_NEL:
4592    #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
4593                case 0x2028:
4594                case 0x2029:
4595    #endif
4596              if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH);              if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH);
4597              break;              break;
4598              }              }
# Line 4409  for (;;) Line 4610  for (;;)
4610            switch(*eptr++)            switch(*eptr++)
4611              {              {
4612              default: break;              default: break;
4613              case 0x09:      /* HT */              HSPACE_BYTE_CASES:
4614              case 0x20:      /* SPACE */  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
4615              case 0xa0:      /* NBSP */              HSPACE_MULTIBYTE_CASES:
4616    #endif
4617              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4618              }              }
4619            }            }
# Line 4428  for (;;) Line 4630  for (;;)
4630            switch(*eptr++)            switch(*eptr++)
4631              {              {
4632              default: RRETURN(MATCH_NOMATCH);              default: RRETURN(MATCH_NOMATCH);
4633              case 0x09:      /* HT */              HSPACE_BYTE_CASES:
4634              case 0x20:      /* SPACE */  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
4635              case 0xa0:      /* NBSP */              HSPACE_MULTIBYTE_CASES:
4636    #endif
4637              break;              break;
4638              }              }
4639            }            }
# Line 4446  for (;;) Line 4649  for (;;)
4649              }              }
4650            switch(*eptr++)            switch(*eptr++)
4651              {              {
4652              default: break;              VSPACE_BYTE_CASES:
4653              case 0x0a:      /* LF */  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
4654              case 0x0b:      /* VT */              VSPACE_MULTIBYTE_CASES:
4655              case 0x0c:      /* FF */  #endif
             case 0x0d:      /* CR */  
             case 0x85:      /* NEL */  
4656              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4657                default: break;
4658              }              }
4659            }            }
4660          break;          break;
# Line 4468  for (;;) Line 4670  for (;;)
4670            switch(*eptr++)            switch(*eptr++)
4671              {              {
4672              default: RRETURN(MATCH_NOMATCH);              default: RRETURN(MATCH_NOMATCH);
4673              case 0x0a:      /* LF */              VSPACE_BYTE_CASES:
4674              case 0x0b:      /* VT */  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
4675              case 0x0c:      /* FF */              VSPACE_MULTIBYTE_CASES:
4676              case 0x0d:      /* CR */  #endif
             case 0x85:      /* NEL */  
4677              break;              break;
4678              }              }
4679            }            }
# Line 4486  for (;;) Line 4687  for (;;)
4687              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4688              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4689              }              }
4690            if ((md->ctypes[*eptr++] & ctype_digit) != 0) RRETURN(MATCH_NOMATCH);            if (MAX_255(*eptr) && (md->ctypes[*eptr] & ctype_digit) != 0)
4691                RRETURN(MATCH_NOMATCH);
4692              eptr++;
4693            }            }
4694          break;          break;
4695    
# Line 4498  for (;;) Line 4701  for (;;)
4701              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4702              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4703              }              }
4704            if ((md->ctypes[*eptr++] & ctype_digit) == 0) RRETURN(MATCH_NOMATCH);            if (!MAX_255(*eptr) || (md->ctypes[*eptr] & ctype_digit) == 0)
4705                RRETURN(MATCH_NOMATCH);
4706              eptr++;
4707            }            }
4708          break;          break;
4709    
# Line 4510  for (;;) Line 4715  for (;;)
4715              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4716              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4717              }              }
4718            if ((md->ctypes[*eptr++] & ctype_space) != 0) RRETURN(MATCH_NOMATCH);            if (MAX_255(*eptr) && (md->ctypes[*eptr] & ctype_space) != 0)
4719                RRETURN(MATCH_NOMATCH);
4720              eptr++;
4721            }            }
4722          break;          break;
4723    
# Line 4522  for (;;) Line 4729  for (;;)
4729              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4730              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4731              }              }
4732            if ((md->ctypes[*eptr++] & ctype_space) == 0) RRETURN(MATCH_NOMATCH);            if (!MAX_255(*eptr) || (md->ctypes[*eptr] & ctype_space) == 0)
4733                RRETURN(MATCH_NOMATCH);
4734              eptr++;
4735            }            }
4736          break;          break;
4737    
# Line 4534  for (;;) Line 4743  for (;;)
4743              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4744              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4745              }              }
4746            if ((md->ctypes[*eptr++] & ctype_word) != 0)            if (MAX_255(*eptr) && (md->ctypes[*eptr] & ctype_word) != 0)
4747              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4748              eptr++;
4749            }            }
4750          break;          break;
4751    
# Line 4547  for (;;) Line 4757  for (;;)
4757              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4758              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4759              }              }
4760            if ((md->ctypes[*eptr++] & ctype_word) == 0)            if (!MAX_255(*eptr) || (md->ctypes[*eptr] & ctype_word) == 0)
4761              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4762              eptr++;
4763            }            }
4764          break;          break;
4765    
# Line 4739  for (;;) Line 4950  for (;;)
4950              }              }
4951            /* Control never gets here */            /* Control never gets here */
4952    
4953            /* This should never occur */            case PT_CLIST:
4954              for (fi = min;; fi++)
4955                {
4956                const pcre_uint32 *cp;
4957                RMATCH(eptr, ecode, offset_top, md, eptrb, RM62);
4958                if (rrc != MATCH_NOMATCH) RRETURN(rrc);
4959                if (fi >= max) RRETURN(MATCH_NOMATCH);
4960                if (eptr >= md->end_subject)
4961                  {
4962                  SCHECK_PARTIAL();
4963                  RRETURN(MATCH_NOMATCH);
4964                  }
4965                GETCHARINCTEST(c, eptr);
4966                cp = PRIV(ucd_caseless_sets) + UCD_CASESET(c);
4967                for (;;)
4968                  {
4969                  if (c < *cp)
4970                    { if (prop_fail_result) break; else { RRETURN(MATCH_NOMATCH); } }
4971                  if (c == *cp++)
4972                    { if (prop_fail_result) { RRETURN(MATCH_NOMATCH); } else break; }
4973                  }
4974                }
4975              /* Control never gets here */
4976    
4977              /* This should never occur */
4978            default:            default:
4979            RRETURN(PCRE_ERROR_INTERNAL);            RRETURN(PCRE_ERROR_INTERNAL);
4980            }            }
# Line 4761  for (;;) Line 4995  for (;;)
4995              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4996              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4997              }              }
4998            GETCHARINCTEST(c, eptr);            else
           if (UCD_CATEGORY(c) == ucp_M) RRETURN(MATCH_NOMATCH);  
           while (eptr < md->end_subject)  
4999              {              {
5000              int len = 1;              int lgb, rgb;
5001              if (!utf8) c = *eptr; else { GETCHARLEN(c, eptr, len); }              GETCHARINCTEST(c, eptr);
5002              if (UCD_CATEGORY(c) != ucp_M) break;              lgb = UCD_GRAPHBREAK(c);
5003              eptr += len;              while (eptr < md->end_subject)
5004                  {
5005                  int len = 1;
5006                  if (!utf) c = *eptr; else { GETCHARLEN(c, eptr, len); }
5007                  rgb = UCD_GRAPHBREAK(c);
5008                  if ((PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0) break;
5009                  lgb = rgb;
5010                  eptr += len;
5011                  }
5012              }              }
5013              CHECK_PARTIAL();
5014            }            }
5015          }          }
5016        else        else
5017  #endif     /* SUPPORT_UCP */  #endif     /* SUPPORT_UCP */
5018    
5019  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
5020        /* UTF-8 mode */        if (utf)
       if (utf8)  
5021          {          {
5022          for (fi = min;; fi++)          for (fi = min;; fi++)
5023            {            {
# Line 4794  for (;;) Line 5034  for (;;)
5034            GETCHARINC(c, eptr);            GETCHARINC(c, eptr);
5035            switch(ctype)            switch(ctype)
5036              {              {
5037              case OP_ANY:        /* This is the non-NL case */              case OP_ANY:               /* This is the non-NL case */
5038                if (md->partial != 0 &&    /* Take care with CRLF partial */
5039                    eptr >= md->end_subject &&
5040                    NLBLOCK->nltype == NLTYPE_FIXED &&
5041                    NLBLOCK->nllen == 2 &&
5042                    c == NLBLOCK->nl[0])
5043                  {
5044                  md->hitend = TRUE;
5045                  if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
5046                  }
5047                break;
5048    
5049              case OP_ALLANY:              case OP_ALLANY:
5050              case OP_ANYBYTE:              case OP_ANYBYTE:
5051              break;              break;
# Line 4803  for (;;) Line 5054  for (;;)
5054              switch(c)              switch(c)
5055                {                {
5056                default: RRETURN(MATCH_NOMATCH);                default: RRETURN(MATCH_NOMATCH);
5057                case 0x000d:                case CHAR_CR:
5058                if (eptr < md->end_subject && *eptr == 0x0a) eptr++;                if (eptr < md->end_subject && RAWUCHAR(eptr) == CHAR_LF) eptr++;
5059                break;                break;
5060                case 0x000a:  
5061                  case CHAR_LF:
5062                break;                break;
5063    
5064                case 0x000b:                case CHAR_VT:
5065                case 0x000c:                case CHAR_FF:
5066                case 0x0085:                case CHAR_NEL:
5067    #ifndef EBCDIC
5068                case 0x2028:                case 0x2028:
5069                case 0x2029:                case 0x2029:
5070    #endif  /* Not EBCDIC */
5071                if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH);                if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH);
5072                break;                break;
5073                }                }
# Line 4822  for (;;) Line 5076  for (;;)
5076              case OP_NOT_HSPACE:              case OP_NOT_HSPACE:
5077              switch(c)              switch(c)
5078                {                {
5079                  HSPACE_CASES: RRETURN(MATCH_NOMATCH);
5080                default: break;                default: break;
               case 0x09:      /* HT */  
               case 0x20:      /* SPACE */  
               case 0xa0:      /* NBSP */  
               case 0x1680:    /* OGHAM SPACE MARK */  
               case 0x180e:    /* MONGOLIAN VOWEL SEPARATOR */  
               case 0x2000:    /* EN QUAD */  
               case 0x2001:    /* EM QUAD */  
               case 0x2002:    /* EN SPACE */  
               case 0x2003:    /* EM SPACE */  
               case 0x2004:    /* THREE-PER-EM SPACE */  
               case 0x2005:    /* FOUR-PER-EM SPACE */  
               case 0x2006:    /* SIX-PER-EM SPACE */  
               case 0x2007:    /* FIGURE SPACE */  
               case 0x2008:    /* PUNCTUATION SPACE */  
               case 0x2009:    /* THIN SPACE */  
               case 0x200A:    /* HAIR SPACE */  
               case 0x202f:    /* NARROW NO-BREAK SPACE */  
               case 0x205f:    /* MEDIUM MATHEMATICAL SPACE */  
               case 0x3000:    /* IDEOGRAPHIC SPACE */  
               RRETURN(MATCH_NOMATCH);  
5081                }                }
5082              break;              break;
5083    
5084              case OP_HSPACE:              case OP_HSPACE:
5085              switch(c)              switch(c)
5086                {                {
5087                  HSPACE_CASES: break;
5088                default: RRETURN(MATCH_NOMATCH);                default: RRETURN(MATCH_NOMATCH);
               case 0x09:      /* HT */  
               case 0x20:      /* SPACE */  
               case 0xa0:      /* NBSP */  
               case 0x1680:    /* OGHAM SPACE MARK */  
               case 0x180e:    /* MONGOLIAN VOWEL SEPARATOR */  
               case 0x2000:    /* EN QUAD */  
               case 0x2001:    /* EM QUAD */  
               case 0x2002:    /* EN SPACE */  
               case 0x2003:    /* EM SPACE */  
               case 0x2004:    /* THREE-PER-EM SPACE */  
               case 0x2005:    /* FOUR-PER-EM SPACE */  
               case 0x2006:    /* SIX-PER-EM SPACE */  
               case 0x2007:    /* FIGURE SPACE */  
               case 0x2008:    /* PUNCTUATION SPACE */  
               case 0x2009:    /* THIN SPACE */  
               case 0x200A:    /* HAIR SPACE */  
               case 0x202f:    /* NARROW NO-BREAK SPACE */  
               case 0x205f:    /* MEDIUM MATHEMATICAL SPACE */  
               case 0x3000:    /* IDEOGRAPHIC SPACE */  
               break;  
5089                }                }
5090              break;              break;
5091    
5092              case OP_NOT_VSPACE:              case OP_NOT_VSPACE:
5093              switch(c)              switch(c)
5094                {                {
5095                  VSPACE_CASES: RRETURN(MATCH_NOMATCH);
5096                default: break;                default: break;
               case 0x0a:      /* LF */  
               case 0x0b:      /* VT */  
               case 0x0c:      /* FF */  
               case 0x0d:      /* CR */  
               case 0x85:      /* NEL */  
               case 0x2028:    /* LINE SEPARATOR */  
               case 0x2029:    /* PARAGRAPH SEPARATOR */  
               RRETURN(MATCH_NOMATCH);  
5097                }                }
5098              break;              break;
5099    
5100              case OP_VSPACE:              case OP_VSPACE:
5101              switch(c)              switch(c)
5102                {                {
5103                  VSPACE_CASES: break;
5104                default: RRETURN(MATCH_NOMATCH);                default: RRETURN(MATCH_NOMATCH);
               case 0x0a:      /* LF */  
               case 0x0b:      /* VT */  
               case 0x0c:      /* FF */  
               case 0x0d:      /* CR */  
               case 0x85:      /* NEL */  
               case 0x2028:    /* LINE SEPARATOR */  
               case 0x2029:    /* PARAGRAPH SEPARATOR */  
               break;  
5105                }                }
5106              break;              break;
5107    
# Line 4919  for (;;) Line 5121  for (;;)
5121              break;              break;
5122    
5123              case OP_WHITESPACE:              case OP_WHITESPACE:
5124              if  (c >= 256 || (md->ctypes[c] & ctype_space) == 0)              if (c >= 256 || (md->ctypes[c] & ctype_space) == 0)
5125                RRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
5126              break;              break;
5127    
# Line 4940  for (;;) Line 5142  for (;;)
5142          }          }
5143        else        else
5144  #endif  #endif
5145        /* Not UTF-8 mode */        /* Not UTF mode */
5146          {          {
5147          for (fi = min;; fi++)          for (fi = min;; fi++)
5148            {            {
# Line 4957  for (;;) Line 5159  for (;;)
5159            c = *eptr++;            c = *eptr++;
5160            switch(ctype)            switch(ctype)
5161              {              {
5162              case OP_ANY:     /* This is the non-NL case */              case OP_ANY:               /* This is the non-NL case */
5163                if (md->partial != 0 &&    /* Take care with CRLF partial */
5164                    eptr >= md->end_subject &&
5165                    NLBLOCK->nltype == NLTYPE_FIXED &&
5166                    NLBLOCK->nllen == 2 &&
5167                    c == NLBLOCK->nl[0])
5168                  {
5169                  md->hitend = TRUE;
5170                  if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
5171                  }
5172                break;
5173    
5174              case OP_ALLANY:              case OP_ALLANY:
5175              case OP_ANYBYTE:              case OP_ANYBYTE:
5176              break;              break;
# Line 4966  for (;;) Line 5179  for (;;)
5179              switch(c)              switch(c)
5180                {                {
5181                default: RRETURN(MATCH_NOMATCH);                default: RRETURN(MATCH_NOMATCH);
5182                case 0x000d:                case CHAR_CR:
5183                if (eptr < md->end_subject && *eptr == 0x0a) eptr++;                if (eptr < md->end_subject && *eptr == CHAR_LF) eptr++;
5184                break;                break;
5185    
5186                case 0x000a:                case CHAR_LF:
5187                break;                break;
5188    
5189                case 0x000b:                case CHAR_VT:
5190                case 0x000c:                case CHAR_FF:
5191                case 0x0085:                case CHAR_NEL:
5192    #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
5193                  case 0x2028:
5194                  case 0x2029:
5195    #endif
5196                if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH);                if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH);
5197                break;                break;
5198                }                }
# Line 4985  for (;;) Line 5202  for (;;)
5202              switch(c)              switch(c)
5203                {                {
5204                default: break;                default: break;
5205                case 0x09:      /* HT */                HSPACE_BYTE_CASES:
5206                case 0x20:      /* SPACE */  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
5207                case 0xa0:      /* NBSP */                HSPACE_MULTIBYTE_CASES:
5208    #endif
5209                RRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
5210                }                }
5211              break;              break;
# Line 4996  for (;;) Line 5214  for (;;)
5214              switch(c)              switch(c)
5215                {                {
5216                default: RRETURN(MATCH_NOMATCH);                default: RRETURN(MATCH_NOMATCH);
5217                case 0x09:      /* HT */                HSPACE_BYTE_CASES:
5218                case 0x20:      /* SPACE */  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
5219                case 0xa0:      /* NBSP */                HSPACE_MULTIBYTE_CASES:
5220    #endif
5221                break;                break;
5222                }                }
5223              break;              break;
# Line 5007  for (;;) Line 5226  for (;;)
5226              switch(c)              switch(c)
5227                {                {
5228                default: break;                default: break;
5229                case 0x0a:      /* LF */                VSPACE_BYTE_CASES:
5230                case 0x0b:      /* VT */  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
5231                case 0x0c:      /* FF */                VSPACE_MULTIBYTE_CASES:
5232                case 0x0d:      /* CR */  #endif
               case 0x85:      /* NEL */  
5233                RRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
5234                }                }
5235              break;              break;
# Line 5020  for (;;) Line 5238  for (;;)
5238              switch(c)              switch(c)
5239                {                {
5240                default: RRETURN(MATCH_NOMATCH);                default: RRETURN(MATCH_NOMATCH);
5241                case 0x0a:      /* LF */                VSPACE_BYTE_CASES:
5242                case 0x0b:      /* VT */  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
5243                case 0x0c:      /* FF */                VSPACE_MULTIBYTE_CASES:
5244                case 0x0d:      /* CR */  #endif
               case 0x85:      /* NEL */  
5245                break;                break;
5246                }                }
5247              break;              break;
5248    
5249              case OP_NOT_DIGIT:              case OP_NOT_DIGIT:
5250              if ((md->ctypes[c] & ctype_digit) != 0) RRETURN(MATCH_NOMATCH);              if (MAX_255(c) && (md->ctypes[c] & ctype_digit) != 0) RRETURN(MATCH_NOMATCH);
5251              break;              break;
5252    
5253              case OP_DIGIT:              case OP_DIGIT:
5254              if ((md->ctypes[c] & ctype_digit) == 0) RRETURN(MATCH_NOMATCH);              if (!MAX_255(c) || (md->ctypes[c] & ctype_digit) == 0) RRETURN(MATCH_NOMATCH);
5255              break;              break;
5256    
5257              case OP_NOT_WHITESPACE:              case OP_NOT_WHITESPACE:
5258              if ((md->ctypes[c] & ctype_space) != 0) RRETURN(MATCH_NOMATCH);              if (MAX_255(c) && (md->ctypes[c] & ctype_space) != 0) RRETURN(MATCH_NOMATCH);
5259              break;              break;
5260    
5261              case OP_WHITESPACE:              case OP_WHITESPACE:
5262              if  ((md->ctypes[c] & ctype_space) == 0) RRETURN(MATCH_NOMATCH);              if (!MAX_255(c) || (md->ctypes[c] & ctype_space) == 0) RRETURN(MATCH_NOMATCH);
5263              break;              break;
5264    
5265              case OP_NOT_WORDCHAR:              case OP_NOT_WORDCHAR:
5266              if ((md->ctypes[c] & ctype_word) != 0) RRETURN(MATCH_NOMATCH);              if (MAX_255(c) && (md->ctypes[c] & ctype_word) != 0) RRETURN(MATCH_NOMATCH);
5267              break;              break;
5268    
5269              case OP_WORDCHAR:              case OP_WORDCHAR:
5270              if ((md->ctypes[c] & ctype_word) == 0) RRETURN(MATCH_NOMATCH);              if (!MAX_255(c) || (md->ctypes[c] & ctype_word) == 0) RRETURN(MATCH_NOMATCH);
5271              break;              break;
5272    
5273              default:              default:
# Line 5226  for (;;) Line 5443  for (;;)
5443              eptr+= len;              eptr+= len;
5444              }              }
5445            break;            break;
5446    
5447              case PT_CLIST:
5448              for (i = min; i < max; i++)
5449                {
5450                const pcre_uint32 *cp;
5451                int len = 1;
5452                if (eptr >= md->end_subject)
5453                  {
5454                  SCHECK_PARTIAL();
5455                  break;
5456                  }
5457                GETCHARLENTEST(c, eptr, len);
5458                cp = PRIV(ucd_caseless_sets) + UCD_CASESET(c);
5459                for (;;)
5460                  {
5461                  if (c < *cp)
5462                    { if (prop_fail_result) break; else goto GOT_MAX; }
5463                  if (c == *cp++)
5464                    { if (prop_fail_result) goto GOT_MAX; else break; }
5465                  }
5466                eptr += len;
5467                }
5468              GOT_MAX:
5469              break;
5470    
5471            default:            default:
5472            RRETURN(PCRE_ERROR_INTERNAL);            RRETURN(PCRE_ERROR_INTERNAL);
# Line 5239  for (;;) Line 5480  for (;;)
5480            RMATCH(eptr, ecode, offset_top, md, eptrb, RM44);            RMATCH(eptr, ecode, offset_top, md, eptrb, RM44);
5481            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
5482            if (eptr-- == pp) break;        /* Stop if tried at original pos */            if (eptr-- == pp) break;        /* Stop if tried at original pos */
5483            if (utf8) BACKCHAR(eptr);            if (utf) BACKCHAR(eptr);
5484            }            }
5485          }          }
5486    
# Line 5250  for (;;) Line 5491  for (;;)
5491          {          {
5492          for (i = min; i < max; i++)          for (i = min; i < max; i++)
5493            {            {
           int len = 1;  
5494            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
5495              {              {
5496              SCHECK_PARTIAL();              SCHECK_PARTIAL();
5497              break;              break;
5498              }              }
5499            if (!utf8) c = *eptr; else { GETCHARLEN(c, eptr, len); }            else
           if (UCD_CATEGORY(c) == ucp_M) break;  
           eptr += len;  
           while (eptr < md->end_subject)  
5500              {              {
5501              len = 1;              int lgb, rgb;
5502              if (!utf8) c = *eptr; else { GETCHARLEN(c, eptr, len); }              GETCHARINCTEST(c, eptr);
5503              if (UCD_CATEGORY(c) != ucp_M) break;              lgb = UCD_GRAPHBREAK(c);
5504              eptr += len;              while (eptr < md->end_subject)
5505                  {
5506                  int len = 1;
5507                  if (!utf) c = *eptr; else { GETCHARLEN(c, eptr, len); }
5508                  rgb = UCD_GRAPHBREAK(c);
5509                  if ((PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0) break;
5510                  lgb = rgb;
5511                  eptr += len;
5512                  }
5513              }              }
5514              CHECK_PARTIAL();
5515            }            }
5516    
5517          /* eptr is now past the end of the maximum run */          /* eptr is now past the end of the maximum run */
# Line 5279  for (;;) Line 5525  for (;;)
5525            if (eptr-- == pp) break;        /* Stop if tried at original pos */            if (eptr-- == pp) break;        /* Stop if tried at original pos */
5526            for (;;)                        /* Move back over one extended */            for (;;)                        /* Move back over one extended */
5527              {              {
5528              if (!utf8) c = *eptr; else              if (!utf) c = *eptr; else
5529                {                {
5530                BACKCHAR(eptr);                BACKCHAR(eptr);
5531                GETCHAR(c, eptr);                GETCHAR(c, eptr);
# Line 5293  for (;;) Line 5539  for (;;)
5539        else        else
5540  #endif   /* SUPPORT_UCP */  #endif   /* SUPPORT_UCP */
5541    
5542  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
5543        /* UTF-8 mode */        if (utf)
   
       if (utf8)  
5544          {          {
5545          switch(ctype)          switch(ctype)
5546            {            {
# Line 5311  for (;;) Line 5555  for (;;)
5555                  break;                  break;
5556                  }                  }
5557                if (IS_NEWLINE(eptr)) break;                if (IS_NEWLINE(eptr)) break;
5558                  if (md->partial != 0 &&    /* Take care with CRLF partial */
5559                      eptr + 1 >= md->end_subject &&
5560                      NLBLOCK->nltype == NLTYPE_FIXED &&
5561                      NLBLOCK->nllen == 2 &&
5562                      RAWUCHAR(eptr) == NLBLOCK->nl[0])
5563                    {
5564                    md->hitend = TRUE;
5565                    if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
5566                    }
5567                eptr++;                eptr++;
5568                while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;                ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
5569                }                }
5570              }              }
5571    
# Line 5328  for (;;) Line 5581  for (;;)
5581                  break;                  break;
5582                  }                  }
5583                if (IS_NEWLINE(eptr)) break;                if (IS_NEWLINE(eptr)) break;
5584                  if (md->partial != 0 &&    /* Take care with CRLF partial */
5585                      eptr + 1 >= md->end_subject &&
5586                      NLBLOCK->nltype == NLTYPE_FIXED &&
5587                      NLBLOCK->nllen == 2 &&
5588                      RAWUCHAR(eptr) == NLBLOCK->nl[0])
5589                    {
5590                    md->hitend = TRUE;
5591                    if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
5592                    }
5593                eptr++;                eptr++;
5594                while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;                ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
5595                }                }
5596              }              }
5597            break;            break;
# Line 5345  for (;;) Line 5607  for (;;)
5607                  break;                  break;
5608                  }                  }
5609                eptr++;                eptr++;
5610                while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;                ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
5611                }                }
5612              }              }
5613            else            else
# Line 5377  for (;;) Line 5639  for (;;)
5639                break;                break;
5640                }                }
5641              GETCHARLEN(c, eptr, len);              GETCHARLEN(c, eptr, len);
5642              if (c == 0x000d)              if (c == CHAR_CR)
5643                {                {
5644                if (++eptr >= md->end_subject) break;                if (++eptr >= md->end_subject) break;
5645                if (*eptr == 0x000a) eptr++;                if (RAWUCHAR(eptr) == CHAR_LF) eptr++;
5646                }                }
5647              else              else
5648                {                {
5649                if (c != 0x000a &&                if (c != CHAR_LF &&
5650                    (md->bsr_anycrlf ||                    (md->bsr_anycrlf ||
5651                     (c != 0x000b && c != 0x000c &&                     (c != CHAR_VT && c != CHAR_FF && c != CHAR_NEL
5652                      c != 0x0085 && c != 0x2028 && c != 0x2029)))  #ifndef EBCDIC
5653                        && c != 0x2028 && c != 0x2029
5654    #endif  /* Not EBCDIC */
5655                        )))
5656                  break;                  break;
5657                eptr += len;                eptr += len;
5658                }                }
# Line 5408  for (;;) Line 5673  for (;;)
5673              GETCHARLEN(c, eptr, len);              GETCHARLEN(c, eptr, len);
5674              switch(c)              switch(c)
5675                {                {
5676                  HSPACE_CASES: gotspace = TRUE; break;
5677                default: gotspace = FALSE; break;                default: gotspace = FALSE; break;
               case 0x09:      /* HT */  
               case 0x20:      /* SPACE */  
               case 0xa0:      /* NBSP */  
               case 0x1680:    /* OGHAM SPACE MARK */  
               case 0x180e:    /* MONGOLIAN VOWEL SEPARATOR */  
               case 0x2000:    /* EN QUAD */  
               case 0x2001:    /* EM QUAD */  
               case 0x2002:    /* EN SPACE */  
               case 0x2003:    /* EM SPACE */  
               case 0x2004:    /* THREE-PER-EM SPACE */  
               case 0x2005:    /* FOUR-PER-EM SPACE */  
               case 0x2006:    /* SIX-PER-EM SPACE */  
               case 0x2007:    /* FIGURE SPACE */  
               case 0x2008:    /* PUNCTUATION SPACE */  
               case 0x2009:    /* THIN SPACE */  
               case 0x200A:    /* HAIR SPACE */  
               case 0x202f:    /* NARROW NO-BREAK SPACE */  
               case 0x205f:    /* MEDIUM MATHEMATICAL SPACE */  
               case 0x3000:    /* IDEOGRAPHIC SPACE */  
               gotspace = TRUE;  
               break;  
5678                }                }
5679              if (gotspace == (ctype == OP_NOT_HSPACE)) break;              if (gotspace == (ctype == OP_NOT_HSPACE)) break;
5680              eptr += len;              eptr += len;
# Line 5450  for (;;) Line 5695  for (;;)
5695              GETCHARLEN(c, eptr, len);              GETCHARLEN(c, eptr, len);
5696              switch(c)              switch(c)
5697                {                {
5698                  VSPACE_CASES: gotspace = TRUE; break;
5699                default: gotspace = FALSE; break;                default: gotspace = FALSE; break;
               case 0x0a:      /* LF */  
               case 0x0b:      /* VT */  
               case 0x0c:      /* FF */  
               case 0x0d:      /* CR */  
               case 0x85:      /* NEL */  
               case 0x2028:    /* LINE SEPARATOR */  
               case 0x2029:    /* PARAGRAPH SEPARATOR */  
               gotspace = TRUE;  
               break;  
5700                }                }
5701              if (gotspace == (ctype == OP_NOT_VSPACE)) break;              if (gotspace == (ctype == OP_NOT_VSPACE)) break;
5702              eptr += len;              eptr += len;
# Line 5573  for (;;) Line 5810  for (;;)
5810            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
5811            if (eptr-- == pp) break;        /* Stop if tried at original pos */            if (eptr-- == pp) break;        /* Stop if tried at original pos */
5812            BACKCHAR(eptr);            BACKCHAR(eptr);
5813            if (ctype == OP_ANYNL && eptr > pp  && *eptr == '\n' &&            if (ctype == OP_ANYNL && eptr > pp  && RAWUCHAR(eptr) == CHAR_NL &&
5814                eptr[-1] == '\r') eptr--;                RAWUCHAR(eptr - 1) == CHAR_CR) eptr--;
5815            }            }
5816          }          }
5817        else        else
5818  #endif  /* SUPPORT_UTF8 */  #endif  /* SUPPORT_UTF */
5819          /* Not UTF mode */
       /* Not UTF-8 mode */  
5820          {          {
5821          switch(ctype)          switch(ctype)
5822            {            {
# Line 5593  for (;;) Line 5829  for (;;)
5829                break;                break;
5830                }                }
5831              if (IS_NEWLINE(eptr)) break;              if (IS_NEWLINE(eptr)) break;
5832                if (md->partial != 0 &&    /* Take care with CRLF partial */
5833                    eptr + 1 >= md->end_subject &&
5834                    NLBLOCK->nltype == NLTYPE_FIXED &&
5835                    NLBLOCK->nllen == 2 &&
5836                    *eptr == NLBLOCK->nl[0])
5837                  {
5838                  md->hitend = TRUE;
5839                  if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
5840                  }
5841              eptr++;              eptr++;
5842              }              }
5843            break;            break;
# Line 5617  for (;;) Line 5862  for (;;)
5862                break;                break;
5863                }                }
5864              c = *eptr;              c = *eptr;
5865              if (c == 0x000d)              if (c == CHAR_CR)
5866                {                {
5867                if (++eptr >= md->end_subject) break;                if (++eptr >= md->end_subject) break;
5868                if (*eptr == 0x000a) eptr++;                if (*eptr == CHAR_LF) eptr++;
5869                }                }
5870              else              else
5871                {                {
5872                if (c != 0x000a &&                if (c != CHAR_LF && (md->bsr_anycrlf ||
5873                    (md->bsr_anycrlf ||                   (c != CHAR_VT && c != CHAR_FF && c != CHAR_NEL
5874                      (c != 0x000b && c != 0x000c && c != 0x0085)))  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
5875                  break;                   && c != 0x2028 && c != 0x2029
5876    #endif
5877                     ))) break;
5878                eptr++;                eptr++;
5879                }                }
5880              }              }
# Line 5641  for (;;) Line 5888  for (;;)
5888                SCHECK_PARTIAL();                SCHECK_PARTIAL();
5889                break;                break;
5890                }                }
5891              c = *eptr;              switch(*eptr)
5892              if (c == 0x09 || c == 0x20 || c == 0xa0) break;                {
5893              eptr++;                default: eptr++; break;
5894                  HSPACE_BYTE_CASES:
5895    #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
5896                  HSPACE_MULTIBYTE_CASES:
5897    #endif
5898                  goto ENDLOOP00;
5899                  }
5900              }              }
5901              ENDLOOP00:
5902            break;            break;
5903    
5904            case OP_HSPACE:            case OP_HSPACE:
# Line 5655  for (;;) Line 5909  for (;;)
5909                SCHECK_PARTIAL();                SCHECK_PARTIAL();
5910                break;                break;
5911                }                }
5912              c = *eptr;              switch(*eptr)
5913              if (c != 0x09 && c != 0x20 && c != 0xa0) break;                {
5914              eptr++;                default: goto ENDLOOP01;
5915                  HSPACE_BYTE_CASES:
5916    #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
5917                  HSPACE_MULTIBYTE_CASES:
5918    #endif
5919                  eptr++; break;
5920                  }
5921              }              }
5922              ENDLOOP01:
5923            break;            break;
5924    
5925            case OP_NOT_VSPACE:            case OP_NOT_VSPACE:
# Line 5669  for (;;) Line 5930  for (;;)
5930                SCHECK_PARTIAL();                SCHECK_PARTIAL();
5931                break;                break;
5932                }                }
5933              c = *eptr;              switch(*eptr)
5934              if (c == 0x0a || c == 0x0b || c == 0x0c || c == 0x0d || c == 0x85)                {
5935                break;                default: eptr++; break;
5936              eptr++;                VSPACE_BYTE_CASES:
5937    #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
5938                  VSPACE_MULTIBYTE_CASES:
5939    #endif
5940                  goto ENDLOOP02;
5941                  }
5942              }              }
5943              ENDLOOP02:
5944            break;            break;
5945    
5946            case OP_VSPACE:            case OP_VSPACE:
# Line 5684  for (;;) Line 5951  for (;;)
5951                SCHECK_PARTIAL();                SCHECK_PARTIAL();
5952                break;                break;
5953                }                }
5954              c = *eptr;              switch(*eptr)
5955              if (c != 0x0a && c != 0x0b && c != 0x0c && c != 0x0d && c != 0x85)                {
5956                break;                default: goto ENDLOOP03;
5957              eptr++;                VSPACE_BYTE_CASES:
5958    #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
5959                  VSPACE_MULTIBYTE_CASES:
5960    #endif
5961                  eptr++; break;
5962                  }
5963              }              }
5964              ENDLOOP03:
5965            break;            break;
5966    
5967            case OP_NOT_DIGIT:            case OP_NOT_DIGIT:
# Line 5699  for (;;) Line 5972  for (;;)
5972                SCHECK_PARTIAL();                SCHECK_PARTIAL();
5973                break;                break;
5974                }                }
5975              if ((md->ctypes[*eptr] & ctype_digit) != 0) break;              if (MAX_255(*eptr) && (md->ctypes[*eptr] & ctype_digit) != 0) break;
5976              eptr++;              eptr++;
5977              }              }
5978            break;            break;
# Line 5712  for (;;) Line 5985  for (;;)
5985                SCHECK_PARTIAL();                SCHECK_PARTIAL();
5986                break;                break;
5987                }                }
5988              if ((md->ctypes[*eptr] & ctype_digit) == 0) break;              if (!MAX_255(*eptr) || (md->ctypes[*eptr] & ctype_digit) == 0) break;
5989              eptr++;              eptr++;
5990              }              }
5991            break;            break;
# Line 5725  for (;;) Line 5998  for (;;)
5998                SCHECK_PARTIAL();                SCHECK_PARTIAL();
5999                break;                break;
6000                }                }
6001              if ((md->ctypes[*eptr] & ctype_space) != 0) break;              if (MAX_255(*eptr) && (md->ctypes[*eptr] & ctype_space) != 0) break;
6002              eptr++;              eptr++;
6003              }              }
6004            break;            break;
# Line 5738  for (;;) Line 6011  for (;;)
6011                SCHECK_PARTIAL();                SCHECK_PARTIAL();
6012                break;                break;
6013                }                }
6014              if ((md->ctypes[*eptr] & ctype_space) == 0) break;              if (!MAX_255(*eptr) || (md->ctypes[*eptr] & ctype_space) == 0) break;
6015              eptr++;              eptr++;
6016              }              }
6017            break;            break;
# Line 5751  for (;;) Line 6024  for (;;)
6024                SCHECK_PARTIAL();                SCHECK_PARTIAL();
6025                break;                break;
6026                }                }
6027              if ((md->ctypes[*eptr] & ctype_word) != 0) break;              if (MAX_255(*eptr) && (md->ctypes[*eptr] & ctype_word) != 0) break;
6028              eptr++;              eptr++;
6029              }              }
6030            break;            break;
# Line 5764  for (;;) Line 6037  for (;;)
6037                SCHECK_PARTIAL();                SCHECK_PARTIAL();
6038                break;                break;
6039                }                }
6040              if ((md->ctypes[*eptr] & ctype_word) == 0) break;              if (!MAX_255(*eptr) || (md->ctypes[*eptr] & ctype_word) == 0) break;
6041              eptr++;              eptr++;
6042              }              }
6043            break;            break;
# Line 5785  for (;;) Line 6058  for (;;)
6058            RMATCH(eptr, ecode, offset_top, md, eptrb, RM47);            RMATCH(eptr, ecode, offset_top, md, eptrb, RM47);
6059            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
6060            eptr--;            eptr--;
6061            if (ctype == OP_ANYNL && eptr > pp  && *eptr == '\n' &&            if (ctype == OP_ANYNL && eptr > pp  && *eptr == CHAR_LF &&
6062                eptr[-1] == '\r') eptr--;                eptr[-1] == CHAR_CR) eptr--;
6063            }            }
6064          }          }
6065    
# Line 5827  switch (frame->Xwhere) Line 6100  switch (frame->Xwhere)
6100    LBL(35) LBL(43) LBL(47) LBL(48) LBL(49) LBL(50) LBL(51) LBL(52)    LBL(35) LBL(43) LBL(47) LBL(48) LBL(49) LBL(50) LBL(51) LBL(52)
6101    LBL(53) LBL(54) LBL(55) LBL(56) LBL(57) LBL(58) LBL(63) LBL(64)    LBL(53) LBL(54) LBL(55) LBL(56) LBL(57) LBL(58) LBL(63) LBL(64)
6102    LBL(65) LBL(66)    LBL(65) LBL(66)
6103  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
6104    LBL(16) LBL(18) LBL(20) LBL(21) LBL(22) LBL(23) LBL(28) LBL(30)    LBL(21)
6105    #endif
6106    #ifdef SUPPORT_UTF
6107      LBL(16) LBL(18) LBL(20)
6108      LBL(22) LBL(23) LBL(28) LBL(30)
6109    L