/[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 1171 by ph10, Wed Oct 24 15:22:42 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    #ifdef SUPPORT_UTF
153    BOOL utf = md->utf;
154    #endif
155    
156  #ifdef PCRE_DEBUG  #ifdef PCRE_DEBUG
157  if (eptr >= md->end_subject)  if (eptr >= md->end_subject)
# Line 163  pchars(p, length, FALSE, md); Line 166  pchars(p, length, FALSE, md);
166  printf("\n");  printf("\n");
167  #endif  #endif
168    
169  /* Always fail if reference not set (and not JavaScript compatible). */  /* Always fail if reference not set (and not JavaScript compatible - in that
170    case the length is passed as zero). */
171    
172  if (length < 0) return -1;  if (length < 0) return -1;
173    
# Line 173  ASCII characters. */ Line 177  ASCII characters. */
177    
178  if (caseless)  if (caseless)
179    {    {
180  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
181  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
182    if (md->utf8)    if (utf)
183      {      {
184      /* 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
185      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
186      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.
187      (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
188      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
189      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
190      reference, not along the subject (earlier code did this wrong). */      length along the reference, not along the subject (earlier code did this
191        wrong). */
192    
193      USPTR endptr = p + length;      PCRE_PUCHAR endptr = p + length;
194      while (p < endptr)      while (p < endptr)
195        {        {
196        int c, d;        pcre_uint32 c, d;
197        if (eptr >= md->end_subject) return -1;        const ucd_record *ur;
198          if (eptr >= md->end_subject) return -2;   /* Partial match */
199        GETCHARINC(c, eptr);        GETCHARINC(c, eptr);
200        GETCHARINC(d, p);        GETCHARINC(d, p);
201        if (c != d && c != UCD_OTHERCASE(d)) return -1;        ur = GET_UCD(d);
202          if (c != d && c != d + ur->other_case)
203            {
204            const pcre_uint32 *pp = PRIV(ucd_caseless_sets) + ur->caseset;
205            for (;;)
206              {
207              if (c < *pp) return -1;
208              if (c == *pp++) break;
209              }
210            }
211        }        }
212      }      }
213    else    else
# Line 202  if (caseless) Line 217  if (caseless)
217    /* 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
218    is no UCP support. */    is no UCP support. */
219      {      {
     if (eptr + length > md->end_subject) return -1;  
220      while (length-- > 0)      while (length-- > 0)
221        { if (md->lcc[*p++] != md->lcc[*eptr++]) return -1; }        {
222          pcre_uchar cc, cp;
223          if (eptr >= md->end_subject) return -2;   /* Partial match */
224          cc = RAWUCHARTEST(eptr);
225          cp = RAWUCHARTEST(p);
226          if (TABLE_GET(cp, md->lcc, cp) != TABLE_GET(cc, md->lcc, cc)) return -1;
227          p++;
228          eptr++;
229          }
230      }      }
231    }    }
232    
# Line 213  are in UTF-8 mode. */ Line 235  are in UTF-8 mode. */
235    
236  else  else
237    {    {
238    if (eptr + length > md->end_subject) return -1;    while (length-- > 0)
239    while (length-- > 0) if (*p++ != *eptr++) return -1;      {
240        if (eptr >= md->end_subject) return -2;   /* Partial match */
241        if (RAWUCHARINCTEST(p) != RAWUCHARINCTEST(eptr)) return -1;
242        }
243    }    }
244    
245  return eptr - eptr_start;  return (int)(eptr - eptr_start);
246  }  }
247    
248    
# Line 269  enum { RM1=1, RM2,  RM3,  RM4,  RM5,  RM Line 294  enum { RM1=1, RM2,  RM3,  RM4,  RM5,  RM
294         RM31,  RM32, RM33, RM34, RM35, RM36, RM37, RM38, RM39, RM40,         RM31,  RM32, RM33, RM34, RM35, RM36, RM37, RM38, RM39, RM40,
295         RM41,  RM42, RM43, RM44, RM45, RM46, RM47, RM48, RM49, RM50,         RM41,  RM42, RM43, RM44, RM45, RM46, RM47, RM48, RM49, RM50,
296         RM51,  RM52, RM53, RM54, RM55, RM56, RM57, RM58, RM59, RM60,         RM51,  RM52, RM53, RM54, RM55, RM56, RM57, RM58, RM59, RM60,
297         RM61,  RM62, RM63, RM64, RM65, RM66 };         RM61,  RM62, RM63, RM64, RM65, RM66, RM67 };
298    
299  /* These versions of the macros use the stack, as normal. There are debugging  /* These versions of the macros use the stack, as normal. There are debugging
300  versions and production versions. Note that the "rw" argument of RMATCH isn't  versions and production versions. Note that the "rw" argument of RMATCH isn't
# Line 287  actually used in this definition. */ Line 312  actually used in this definition. */
312    }    }
313  #define RRETURN(ra) \  #define RRETURN(ra) \
314    { \    { \
315    printf("match() returned %d from line %d ", ra, __LINE__); \    printf("match() returned %d from line %d\n", ra, __LINE__); \
316    return ra; \    return ra; \
317    }    }
318  #else  #else
# Line 307  argument of match(), which never changes Line 332  argument of match(), which never changes
332    
333  #define RMATCH(ra,rb,rc,rd,re,rw)\  #define RMATCH(ra,rb,rc,rd,re,rw)\
334    {\    {\
335    heapframe *newframe = (heapframe *)(pcre_stack_malloc)(sizeof(heapframe));\    heapframe *newframe = frame->Xnextframe;\
336    if (newframe == NULL) RRETURN(PCRE_ERROR_NOMEMORY);\    if (newframe == NULL)\
337    frame->Xwhere = rw; \      {\
338        newframe = (heapframe *)(PUBL(stack_malloc))(sizeof(heapframe));\
339        if (newframe == NULL) RRETURN(PCRE_ERROR_NOMEMORY);\
340        newframe->Xnextframe = NULL;\
341        frame->Xnextframe = newframe;\
342        }\
343      frame->Xwhere = rw;\
344    newframe->Xeptr = ra;\    newframe->Xeptr = ra;\
345    newframe->Xecode = rb;\    newframe->Xecode = rb;\
346    newframe->Xmstart = mstart;\    newframe->Xmstart = mstart;\
# Line 328  argument of match(), which never changes Line 359  argument of match(), which never changes
359    {\    {\
360    heapframe *oldframe = frame;\    heapframe *oldframe = frame;\
361    frame = oldframe->Xprevframe;\    frame = oldframe->Xprevframe;\
   (pcre_stack_free)(oldframe);\  
362    if (frame != NULL)\    if (frame != NULL)\
363      {\      {\
364      rrc = ra;\      rrc = ra;\
# Line 342  argument of match(), which never changes Line 372  argument of match(), which never changes
372    
373  typedef struct heapframe {  typedef struct heapframe {
374    struct heapframe *Xprevframe;    struct heapframe *Xprevframe;
375      struct heapframe *Xnextframe;
376    
377    /* Function arguments that may change */    /* Function arguments that may change */
378    
379    USPTR Xeptr;    PCRE_PUCHAR Xeptr;
380    const uschar *Xecode;    const pcre_uchar *Xecode;
381    USPTR Xmstart;    PCRE_PUCHAR Xmstart;
382    int Xoffset_top;    int Xoffset_top;
383    eptrblock *Xeptrb;    eptrblock *Xeptrb;
384    unsigned int Xrdepth;    unsigned int Xrdepth;
385    
386    /* Function local variables */    /* Function local variables */
387    
388    USPTR Xcallpat;    PCRE_PUCHAR Xcallpat;
389  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
390    USPTR Xcharptr;    PCRE_PUCHAR Xcharptr;
391  #endif  #endif
392    USPTR Xdata;    PCRE_PUCHAR Xdata;
393    USPTR Xnext;    PCRE_PUCHAR Xnext;
394    USPTR Xpp;    PCRE_PUCHAR Xpp;
395    USPTR Xprev;    PCRE_PUCHAR Xprev;
396    USPTR Xsaved_eptr;    PCRE_PUCHAR Xsaved_eptr;
397    
398    recursion_info Xnew_recursive;    recursion_info Xnew_recursive;
399    
# Line 372  typedef struct heapframe { Line 403  typedef struct heapframe {
403    
404  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
405    int Xprop_type;    int Xprop_type;
406    int Xprop_value;    unsigned int Xprop_value;
407    int Xprop_fail_result;    int Xprop_fail_result;
408    int Xoclength;    int Xoclength;
409    uschar Xocchars[8];    pcre_uchar Xocchars[6];
410  #endif  #endif
411    
412    int Xcodelink;    int Xcodelink;
# Line 417  returns a negative (error) response, the Line 448  returns a negative (error) response, the
448  same response. */  same response. */
449    
450  /* 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
451  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
452  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.
453  something has been matched). For hard partial matching, we then return  something has been matched). For hard partial matching, we then return
454  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 471  the subject. */
471    
472    
473  /* Performance note: It might be tempting to extract commonly used fields from  /* Performance note: It might be tempting to extract commonly used fields from
474  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
475  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
476  made performance worse.  made performance worse.
477    
# Line 463  Returns:       MATCH_MATCH if matched Line 494  Returns:       MATCH_MATCH if matched
494  */  */
495    
496  static int  static int
497  match(REGISTER USPTR eptr, REGISTER const uschar *ecode, USPTR mstart,  match(REGISTER PCRE_PUCHAR eptr, REGISTER const pcre_uchar *ecode,
498    int offset_top, match_data *md, eptrblock *eptrb, unsigned int rdepth)    PCRE_PUCHAR mstart, int offset_top, match_data *md, eptrblock *eptrb,
499      unsigned int rdepth)
500  {  {
501  /* 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,
502  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 504  so they can be ordinary variables in all
504    
505  register int  rrc;         /* Returns from recursive calls */  register int  rrc;         /* Returns from recursive calls */
506  register int  i;           /* Used for loops not involving calls to RMATCH() */  register int  i;           /* Used for loops not involving calls to RMATCH() */
507  register unsigned int c;   /* Character values not kept over RMATCH() calls */  register pcre_uint32 c;    /* Character values not kept over RMATCH() calls */
508  register BOOL utf8;        /* Local copy of UTF-8 flag for speed */  register BOOL utf;         /* Local copy of UTF flag for speed */
509    
510  BOOL minimize, possessive; /* Quantifier options */  BOOL minimize, possessive; /* Quantifier options */
511  BOOL caseless;  BOOL caseless;
512  int condcode;  int condcode;
513    
514  /* 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
515  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
516  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
517  heap whenever RMATCH() does a "recursion". See the macro definitions above. */  whenever RMATCH() does a "recursion". See the macro definitions above. Putting
518    the top-level on the stack rather than malloc-ing them all gives a performance
519    boost in many cases where there is not much "recursion". */
520    
521  #ifdef NO_RECURSE  #ifdef NO_RECURSE
522  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 */  
523    
524  /* Copy in the original argument variables */  /* Copy in the original argument variables */
525    
# Line 513  HEAP_RECURSE: Line 545  HEAP_RECURSE:
545    
546  /* Ditto for the local variables */  /* Ditto for the local variables */
547    
548  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
549  #define charptr            frame->Xcharptr  #define charptr            frame->Xcharptr
550  #endif  #endif
551  #define callpat            frame->Xcallpat  #define callpat            frame->Xcallpat
# Line 571  declarations can be cut out in a block. Line 603  declarations can be cut out in a block.
603  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
604  to RMATCH(). */  to RMATCH(). */
605    
606  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
607  const uschar *charptr;  const pcre_uchar *charptr;
608  #endif  #endif
609  const uschar *callpat;  const pcre_uchar *callpat;
610  const uschar *data;  const pcre_uchar *data;
611  const uschar *next;  const pcre_uchar *next;
612  USPTR         pp;  PCRE_PUCHAR       pp;
613  const uschar *prev;  const pcre_uchar *prev;
614  USPTR         saved_eptr;  PCRE_PUCHAR       saved_eptr;
615    
616  recursion_info new_recursive;  recursion_info new_recursive;
617    
# Line 589  BOOL prev_is_word; Line 621  BOOL prev_is_word;
621    
622  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
623  int prop_type;  int prop_type;
624  int prop_value;  unsigned int prop_value;
625  int prop_fail_result;  int prop_fail_result;
626  int oclength;  int oclength;
627  uschar occhars[8];  pcre_uchar occhars[6];
628  #endif  #endif
629    
630  int codelink;  int codelink;
# Line 600  int ctype; Line 632  int ctype;
632  int length;  int length;
633  int max;  int max;
634  int min;  int min;
635  int number;  unsigned int number;
636  int offset;  int offset;
637  int op;  pcre_uchar op;
638  int save_capture_last;  int save_capture_last;
639  int save_offset1, save_offset2, save_offset3;  int save_offset1, save_offset2, save_offset3;
640  int stacksave[REC_STACK_SAVE_MAX];  int stacksave[REC_STACK_SAVE_MAX];
641    
642  eptrblock newptrb;  eptrblock newptrb;
643    
644    /* There is a special fudge for calling match() in a way that causes it to
645    measure the size of its basic stack frame when the stack is being used for
646    recursion. The second argument (ecode) being NULL triggers this behaviour. It
647    cannot normally ever be NULL. The return is the negated value of the frame
648    size. */
649    
650    if (ecode == NULL)
651      {
652      if (rdepth == 0)
653        return match((PCRE_PUCHAR)&rdepth, NULL, NULL, 0, NULL, NULL, 1);
654      else
655        {
656        int len = (char *)&rdepth - (char *)eptr;
657        return (len > 0)? -len : len;
658        }
659      }
660  #endif     /* NO_RECURSE */  #endif     /* NO_RECURSE */
661    
662  /* 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 669  the alternative names that are used. */
669  #define code_offset   codelink  #define code_offset   codelink
670  #define condassert    condition  #define condassert    condition
671  #define matched_once  prev_is_word  #define matched_once  prev_is_word
672    #define foc           number
673    #define save_mark     data
674    
675  /* These statements are here to stop the compiler complaining about unitialized  /* These statements are here to stop the compiler complaining about unitialized
676  variables. */  variables. */
# Line 645  defined). However, RMATCH isn't like a f Line 696  defined). However, RMATCH isn't like a f
696  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,
697  however, impact performance when true recursion is being used. */  however, impact performance when true recursion is being used. */
698    
699  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
700  utf8 = md->utf8;       /* Local copy of the flag */  utf = md->utf;       /* Local copy of the flag */
701  #else  #else
702  utf8 = FALSE;  utf = FALSE;
703  #endif  #endif
704    
705  /* 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 740  for (;;)
740      case OP_MARK:      case OP_MARK:
741      md->nomatch_mark = ecode + 2;      md->nomatch_mark = ecode + 2;
742      md->mark = NULL;    /* In case previously set by assertion */      md->mark = NULL;    /* In case previously set by assertion */
743      RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode] + ecode[1], offset_top, md,      RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode] + ecode[1], offset_top, md,
744        eptrb, RM55);        eptrb, RM55);
745      if ((rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) &&      if ((rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) &&
746           md->mark == NULL) md->mark = ecode + 2;           md->mark == NULL) md->mark = ecode + 2;
# Line 702  for (;;) Line 753  for (;;)
753      unaltered. */      unaltered. */
754    
755      else if (rrc == MATCH_SKIP_ARG &&      else if (rrc == MATCH_SKIP_ARG &&
756          strcmp((char *)(ecode + 2), (char *)(md->start_match_ptr)) == 0)          STRCMP_UC_UC_TEST(ecode + 2, md->start_match_ptr) == 0)
757        {        {
758        md->start_match_ptr = eptr;        md->start_match_ptr = eptr;
759        RRETURN(MATCH_SKIP);        RRETURN(MATCH_SKIP);
# Line 715  for (;;) Line 766  for (;;)
766      /* COMMIT overrides PRUNE, SKIP, and THEN */      /* COMMIT overrides PRUNE, SKIP, and THEN */
767    
768      case OP_COMMIT:      case OP_COMMIT:
769      RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,      RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md,
770        eptrb, RM52);        eptrb, RM52);
771      if (rrc != MATCH_NOMATCH && rrc != MATCH_PRUNE &&      if (rrc != MATCH_NOMATCH && rrc != MATCH_PRUNE &&
772          rrc != MATCH_SKIP && rrc != MATCH_SKIP_ARG &&          rrc != MATCH_SKIP && rrc != MATCH_SKIP_ARG &&
# Line 726  for (;;) Line 777  for (;;)
777      /* PRUNE overrides THEN */      /* PRUNE overrides THEN */
778    
779      case OP_PRUNE:      case OP_PRUNE:
780      RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,      RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md,
781        eptrb, RM51);        eptrb, RM51);
782      if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);      if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);
783      RRETURN(MATCH_PRUNE);      RRETURN(MATCH_PRUNE);
# Line 734  for (;;) Line 785  for (;;)
785      case OP_PRUNE_ARG:      case OP_PRUNE_ARG:
786      md->nomatch_mark = ecode + 2;      md->nomatch_mark = ecode + 2;
787      md->mark = NULL;    /* In case previously set by assertion */      md->mark = NULL;    /* In case previously set by assertion */
788      RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode] + ecode[1], offset_top, md,      RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode] + ecode[1], offset_top, md,
789        eptrb, RM56);        eptrb, RM56);
790      if ((rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) &&      if ((rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) &&
791           md->mark == NULL) md->mark = ecode + 2;           md->mark == NULL) md->mark = ecode + 2;
# Line 744  for (;;) Line 795  for (;;)
795      /* SKIP overrides PRUNE and THEN */      /* SKIP overrides PRUNE and THEN */
796    
797      case OP_SKIP:      case OP_SKIP:
798      RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,      RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md,
799        eptrb, RM53);        eptrb, RM53);
800      if (rrc != MATCH_NOMATCH && rrc != MATCH_PRUNE && rrc != MATCH_THEN)      if (rrc != MATCH_NOMATCH && rrc != MATCH_PRUNE && rrc != MATCH_THEN)
801        RRETURN(rrc);        RRETURN(rrc);
# Line 752  for (;;) Line 803  for (;;)
803      RRETURN(MATCH_SKIP);      RRETURN(MATCH_SKIP);
804    
805      /* Note that, for Perl compatibility, SKIP with an argument does NOT set      /* Note that, for Perl compatibility, SKIP with an argument does NOT set
806      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
807      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. */
808    
809      case OP_SKIP_ARG:      case OP_SKIP_ARG:
810      if (md->ignore_skip_arg)      if (md->ignore_skip_arg)
811        {        {
812        ecode += _pcre_OP_lengths[*ecode] + ecode[1];        ecode += PRIV(OP_lengths)[*ecode] + ecode[1];
813        break;        break;
814        }        }
815      RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode] + ecode[1], offset_top, md,      RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode] + ecode[1], offset_top, md,
816        eptrb, RM57);        eptrb, RM57);
817      if (rrc != MATCH_NOMATCH && rrc != MATCH_PRUNE && rrc != MATCH_THEN)      if (rrc != MATCH_NOMATCH && rrc != MATCH_PRUNE && rrc != MATCH_THEN)
818        RRETURN(rrc);        RRETURN(rrc);
819    
820      /* 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
821      returning the special MATCH_SKIP_ARG return code. This will either be      returning the special MATCH_SKIP_ARG return code. This will either be
822      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
823      with the md->ignore_skip_arg flag set. */      with the md->ignore_skip_arg flag set. */
824    
825      md->start_match_ptr = ecode + 2;      md->start_match_ptr = ecode + 2;
# Line 779  for (;;) Line 830  for (;;)
830      match pointer to do this. */      match pointer to do this. */
831    
832      case OP_THEN:      case OP_THEN:
833      RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,      RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md,
834        eptrb, RM54);        eptrb, RM54);
835      if (rrc != MATCH_NOMATCH) RRETURN(rrc);      if (rrc != MATCH_NOMATCH) RRETURN(rrc);
836      md->start_match_ptr = ecode;      md->start_match_ptr = ecode;
# Line 788  for (;;) Line 839  for (;;)
839      case OP_THEN_ARG:      case OP_THEN_ARG:
840      md->nomatch_mark = ecode + 2;      md->nomatch_mark = ecode + 2;
841      md->mark = NULL;    /* In case previously set by assertion */      md->mark = NULL;    /* In case previously set by assertion */
842      RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode] + ecode[1], offset_top,      RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode] + ecode[1], offset_top,
843        md, eptrb, RM58);        md, eptrb, RM58);
844      if ((rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) &&      if ((rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) &&
845           md->mark == NULL) md->mark = ecode + 2;           md->mark == NULL) md->mark = ecode + 2;
# Line 812  for (;;) Line 863  for (;;)
863      case OP_ONCE_NC:      case OP_ONCE_NC:
864      prev = ecode;      prev = ecode;
865      saved_eptr = eptr;      saved_eptr = eptr;
866        save_mark = md->mark;
867      do      do
868        {        {
869        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 882  for (;;)
882    
883        if (rrc != MATCH_NOMATCH) RRETURN(rrc);        if (rrc != MATCH_NOMATCH) RRETURN(rrc);
884        ecode += GET(ecode,1);        ecode += GET(ecode,1);
885          md->mark = save_mark;
886        }        }
887      while (*ecode == OP_ALT);      while (*ecode == OP_ALT);
888    
# Line 869  for (;;) Line 922  for (;;)
922        }        }
923      else  /* OP_KETRMAX */      else  /* OP_KETRMAX */
924        {        {
       md->match_function_type = MATCH_CBEGROUP;  
925        RMATCH(eptr, prev, offset_top, md, eptrb, RM66);        RMATCH(eptr, prev, offset_top, md, eptrb, RM66);
926        if (rrc != MATCH_NOMATCH) RRETURN(rrc);        if (rrc != MATCH_NOMATCH) RRETURN(rrc);
927        ecode += 1 + LINK_SIZE;        ecode += 1 + LINK_SIZE;
# Line 909  for (;;) Line 961  for (;;)
961        save_offset2 = md->offset_vector[offset+1];        save_offset2 = md->offset_vector[offset+1];
962        save_offset3 = md->offset_vector[md->offset_end - number];        save_offset3 = md->offset_vector[md->offset_end - number];
963        save_capture_last = md->capture_last;        save_capture_last = md->capture_last;
964          save_mark = md->mark;
965    
966        DPRINTF(("saving %d %d %d\n", save_offset1, save_offset2, save_offset3));        DPRINTF(("saving %d %d %d\n", save_offset1, save_offset2, save_offset3));
967        md->offset_vector[md->offset_end - number] =        md->offset_vector[md->offset_end - number] =
# Line 917  for (;;) Line 970  for (;;)
970        for (;;)        for (;;)
971          {          {
972          if (op >= OP_SBRA) md->match_function_type = MATCH_CBEGROUP;          if (op >= OP_SBRA) md->match_function_type = MATCH_CBEGROUP;
973          RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,          RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md,
974            eptrb, RM1);            eptrb, RM1);
975          if (rrc == MATCH_ONCE) break;  /* Backing up through an atomic group */          if (rrc == MATCH_ONCE) break;  /* Backing up through an atomic group */
976    
# Line 945  for (;;) Line 998  for (;;)
998          if (rrc != MATCH_NOMATCH) RRETURN(rrc);          if (rrc != MATCH_NOMATCH) RRETURN(rrc);
999          md->capture_last = save_capture_last;          md->capture_last = save_capture_last;
1000          ecode += GET(ecode, 1);          ecode += GET(ecode, 1);
1001            md->mark = save_mark;
1002          if (*ecode != OP_ALT) break;          if (*ecode != OP_ALT) break;
1003          }          }
1004    
# Line 996  for (;;) Line 1050  for (;;)
1050    
1051      for (;;)      for (;;)
1052        {        {
1053        if (op >= OP_SBRA || op == OP_ONCE) md->match_function_type = MATCH_CBEGROUP;        if (op >= OP_SBRA || op == OP_ONCE)
1054            md->match_function_type = MATCH_CBEGROUP;
1055    
1056        /* 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
1057        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 1059  for (;;)
1059    
1060        else if (!md->hasthen && ecode[GET(ecode, 1)] != OP_ALT)        else if (!md->hasthen && ecode[GET(ecode, 1)] != OP_ALT)
1061          {          {
1062          ecode += _pcre_OP_lengths[*ecode];          ecode += PRIV(OP_lengths)[*ecode];
1063          goto TAIL_RECURSE;          goto TAIL_RECURSE;
1064          }          }
1065    
1066        /* In all other cases, we have to make another call to match(). */        /* In all other cases, we have to make another call to match(). */
1067    
1068        RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md, eptrb,        save_mark = md->mark;
1069          RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md, eptrb,
1070          RM2);          RM2);
1071    
1072        /* 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 1084  for (;;)
1084          {          {
1085          if (rrc == MATCH_ONCE)          if (rrc == MATCH_ONCE)
1086            {            {
1087            const uschar *scode = ecode;            const pcre_uchar *scode = ecode;
1088            if (*scode != OP_ONCE)           /* If not at start, find it */            if (*scode != OP_ONCE)           /* If not at start, find it */
1089              {              {
1090              while (*scode == OP_ALT) scode += GET(scode, 1);              while (*scode == OP_ALT) scode += GET(scode, 1);
# Line 1039  for (;;) Line 1095  for (;;)
1095          RRETURN(rrc);          RRETURN(rrc);
1096          }          }
1097        ecode += GET(ecode, 1);        ecode += GET(ecode, 1);
1098          md->mark = save_mark;
1099        if (*ecode != OP_ALT) break;        if (*ecode != OP_ALT) break;
1100        }        }
1101    
# Line 1070  for (;;) Line 1127  for (;;)
1127      if (offset < md->offset_max)      if (offset < md->offset_max)
1128        {        {
1129        matched_once = FALSE;        matched_once = FALSE;
1130        code_offset = ecode - md->start_code;        code_offset = (int)(ecode - md->start_code);
1131    
1132        save_offset1 = md->offset_vector[offset];        save_offset1 = md->offset_vector[offset];
1133        save_offset2 = md->offset_vector[offset+1];        save_offset2 = md->offset_vector[offset+1];
# Line 1093  for (;;) Line 1150  for (;;)
1150          md->offset_vector[md->offset_end - number] =          md->offset_vector[md->offset_end - number] =
1151            (int)(eptr - md->start_subject);            (int)(eptr - md->start_subject);
1152          if (op >= OP_SBRA) md->match_function_type = MATCH_CBEGROUP;          if (op >= OP_SBRA) md->match_function_type = MATCH_CBEGROUP;
1153          RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,          RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md,
1154            eptrb, RM63);            eptrb, RM63);
1155          if (rrc == MATCH_KETRPOS)          if (rrc == MATCH_KETRPOS)
1156            {            {
# Line 1160  for (;;) Line 1217  for (;;)
1217    
1218      POSSESSIVE_NON_CAPTURE:      POSSESSIVE_NON_CAPTURE:
1219      matched_once = FALSE;      matched_once = FALSE;
1220      code_offset = ecode - md->start_code;      code_offset = (int)(ecode - md->start_code);
1221    
1222      for (;;)      for (;;)
1223        {        {
1224        if (op >= OP_SBRA) md->match_function_type = MATCH_CBEGROUP;        if (op >= OP_SBRA) md->match_function_type = MATCH_CBEGROUP;
1225        RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,        RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md,
1226          eptrb, RM48);          eptrb, RM48);
1227        if (rrc == MATCH_KETRPOS)        if (rrc == MATCH_KETRPOS)
1228          {          {
# Line 1215  for (;;) Line 1272  for (;;)
1272    
1273      if (ecode[LINK_SIZE+1] == OP_CALLOUT)      if (ecode[LINK_SIZE+1] == OP_CALLOUT)
1274        {        {
1275        if (pcre_callout != NULL)        if (PUBL(callout) != NULL)
1276          {          {
1277          pcre_callout_block cb;          PUBL(callout_block) cb;
1278          cb.version          = 2;   /* Version 1 of the callout block */          cb.version          = 2;   /* Version 1 of the callout block */
1279          cb.callout_number   = ecode[LINK_SIZE+2];          cb.callout_number   = ecode[LINK_SIZE+2];
1280          cb.offset_vector    = md->offset_vector;          cb.offset_vector    = md->offset_vector;
1281    #if defined COMPILE_PCRE8
1282          cb.subject          = (PCRE_SPTR)md->start_subject;          cb.subject          = (PCRE_SPTR)md->start_subject;
1283    #elif defined COMPILE_PCRE16
1284            cb.subject          = (PCRE_SPTR16)md->start_subject;
1285    #elif defined COMPILE_PCRE32
1286            cb.subject          = (PCRE_SPTR32)md->start_subject;
1287    #endif
1288          cb.subject_length   = (int)(md->end_subject - md->start_subject);          cb.subject_length   = (int)(md->end_subject - md->start_subject);
1289          cb.start_match      = (int)(mstart - md->start_subject);          cb.start_match      = (int)(mstart - md->start_subject);
1290          cb.current_position = (int)(eptr - md->start_subject);          cb.current_position = (int)(eptr - md->start_subject);
# Line 1231  for (;;) Line 1294  for (;;)
1294          cb.capture_last     = md->capture_last;          cb.capture_last     = md->capture_last;
1295          cb.callout_data     = md->callout_data;          cb.callout_data     = md->callout_data;
1296          cb.mark             = md->nomatch_mark;          cb.mark             = md->nomatch_mark;
1297          if ((rrc = (*pcre_callout)(&cb)) > 0) RRETURN(MATCH_NOMATCH);          if ((rrc = (*PUBL(callout))(&cb)) > 0) RRETURN(MATCH_NOMATCH);
1298          if (rrc < 0) RRETURN(rrc);          if (rrc < 0) RRETURN(rrc);
1299          }          }
1300        ecode += _pcre_OP_lengths[OP_CALLOUT];        ecode += PRIV(OP_lengths)[OP_CALLOUT];
1301        }        }
1302    
1303      condcode = ecode[LINK_SIZE+1];      condcode = ecode[LINK_SIZE+1];
# Line 1250  for (;;) Line 1313  for (;;)
1313          }          }
1314        else        else
1315          {          {
1316          int recno = GET2(ecode, LINK_SIZE + 2);   /* Recursion group number*/          unsigned int recno = GET2(ecode, LINK_SIZE + 2);   /* Recursion group number*/
1317          condition = (recno == RREF_ANY || recno == md->recursive->group_num);          condition = (recno == RREF_ANY || recno == md->recursive->group_num);
1318    
1319          /* 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 1323  for (;;)
1323    
1324          if (!condition && condcode == OP_NRREF)          if (!condition && condcode == OP_NRREF)
1325            {            {
1326            uschar *slotA = md->name_table;            pcre_uchar *slotA = md->name_table;
1327            for (i = 0; i < md->name_count; i++)            for (i = 0; i < md->name_count; i++)
1328              {              {
1329              if (GET2(slotA, 0) == recno) break;              if (GET2(slotA, 0) == recno) break;
# Line 1273  for (;;) Line 1336  for (;;)
1336    
1337            if (i < md->name_count)            if (i < md->name_count)
1338              {              {
1339              uschar *slotB = slotA;              pcre_uchar *slotB = slotA;
1340              while (slotB > md->name_table)              while (slotB > md->name_table)
1341                {                {
1342                slotB -= md->name_entry_size;                slotB -= md->name_entry_size;
1343                if (strcmp((char *)slotA + 2, (char *)slotB + 2) == 0)                if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
1344                  {                  {
1345                  condition = GET2(slotB, 0) == md->recursive->group_num;                  condition = GET2(slotB, 0) == md->recursive->group_num;
1346                  if (condition) break;                  if (condition) break;
# Line 1293  for (;;) Line 1356  for (;;)
1356                for (i++; i < md->name_count; i++)                for (i++; i < md->name_count; i++)
1357                  {                  {
1358                  slotB += md->name_entry_size;                  slotB += md->name_entry_size;
1359                  if (strcmp((char *)slotA + 2, (char *)slotB + 2) == 0)                  if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
1360                    {                    {
1361                    condition = GET2(slotB, 0) == md->recursive->group_num;                    condition = GET2(slotB, 0) == md->recursive->group_num;
1362                    if (condition) break;                    if (condition) break;
# Line 1306  for (;;) Line 1369  for (;;)
1369    
1370          /* Chose branch according to the condition */          /* Chose branch according to the condition */
1371    
1372          ecode += condition? 3 : GET(ecode, 1);          ecode += condition? 1 + IMM2_SIZE : GET(ecode, 1);
1373          }          }
1374        }        }
1375    
# Line 1322  for (;;) Line 1385  for (;;)
1385    
1386        if (!condition && condcode == OP_NCREF)        if (!condition && condcode == OP_NCREF)
1387          {          {
1388          int refno = offset >> 1;          unsigned int refno = offset >> 1;
1389          uschar *slotA = md->name_table;          pcre_uchar *slotA = md->name_table;
1390    
1391          for (i = 0; i < md->name_count; i++)          for (i = 0; i < md->name_count; i++)
1392            {            {
# Line 1337  for (;;) Line 1400  for (;;)
1400    
1401          if (i < md->name_count)          if (i < md->name_count)
1402            {            {
1403            uschar *slotB = slotA;            pcre_uchar *slotB = slotA;
1404            while (slotB > md->name_table)            while (slotB > md->name_table)
1405              {              {
1406              slotB -= md->name_entry_size;              slotB -= md->name_entry_size;
1407              if (strcmp((char *)slotA + 2, (char *)slotB + 2) == 0)              if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
1408                {                {
1409                offset = GET2(slotB, 0) << 1;                offset = GET2(slotB, 0) << 1;
1410                condition = offset < offset_top &&                condition = offset < offset_top &&
# Line 1359  for (;;) Line 1422  for (;;)
1422              for (i++; i < md->name_count; i++)              for (i++; i < md->name_count; i++)
1423                {                {
1424                slotB += md->name_entry_size;                slotB += md->name_entry_size;
1425                if (strcmp((char *)slotA + 2, (char *)slotB + 2) == 0)                if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
1426                  {                  {
1427                  offset = GET2(slotB, 0) << 1;                  offset = GET2(slotB, 0) << 1;
1428                  condition = offset < offset_top &&                  condition = offset < offset_top &&
# Line 1374  for (;;) Line 1437  for (;;)
1437    
1438        /* Chose branch according to the condition */        /* Chose branch according to the condition */
1439    
1440        ecode += condition? 3 : GET(ecode, 1);        ecode += condition? 1 + IMM2_SIZE : GET(ecode, 1);
1441        }        }
1442    
1443      else if (condcode == OP_DEF)     /* DEFINE - always false */      else if (condcode == OP_DEF)     /* DEFINE - always false */
# Line 1466  for (;;) Line 1529  for (;;)
1529        md->offset_vector[offset+1] = (int)(eptr - md->start_subject);        md->offset_vector[offset+1] = (int)(eptr - md->start_subject);
1530        if (offset_top <= offset) offset_top = offset + 2;        if (offset_top <= offset) offset_top = offset + 2;
1531        }        }
1532      ecode += 3;      ecode += 1 + IMM2_SIZE;
1533      break;      break;
1534    
1535    
# Line 1513  for (;;) Line 1576  for (;;)
1576    
1577      case OP_ASSERT:      case OP_ASSERT:
1578      case OP_ASSERTBACK:      case OP_ASSERTBACK:
1579        save_mark = md->mark;
1580      if (md->match_function_type == MATCH_CONDASSERT)      if (md->match_function_type == MATCH_CONDASSERT)
1581        {        {
1582        condassert = TRUE;        condassert = TRUE;
# Line 1528  for (;;) Line 1592  for (;;)
1592          mstart = md->start_match_ptr;   /* In case \K reset it */          mstart = md->start_match_ptr;   /* In case \K reset it */
1593          break;          break;
1594          }          }
1595          md->mark = save_mark;
1596    
1597        /* PCRE does not allow THEN to escape beyond an assertion; it is treated        /* A COMMIT failure must fail the entire assertion, without trying any
1598        as NOMATCH. */        subsequent branches. */
1599    
1600          if (rrc == MATCH_COMMIT) RRETURN(MATCH_NOMATCH);
1601    
1602          /* PCRE does not allow THEN to escape beyond an assertion; it
1603          is treated as NOMATCH. */
1604    
1605        if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);        if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);
1606        ecode += GET(ecode, 1);        ecode += GET(ecode, 1);
# Line 1557  for (;;) Line 1627  for (;;)
1627    
1628      case OP_ASSERT_NOT:      case OP_ASSERT_NOT:
1629      case OP_ASSERTBACK_NOT:      case OP_ASSERTBACK_NOT:
1630        save_mark = md->mark;
1631      if (md->match_function_type == MATCH_CONDASSERT)      if (md->match_function_type == MATCH_CONDASSERT)
1632        {        {
1633        condassert = TRUE;        condassert = TRUE;
# Line 1567  for (;;) Line 1638  for (;;)
1638      do      do
1639        {        {
1640        RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, NULL, RM5);        RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, NULL, RM5);
1641          md->mark = save_mark;
1642        if (rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) RRETURN(MATCH_NOMATCH);        if (rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) RRETURN(MATCH_NOMATCH);
1643        if (rrc == MATCH_SKIP || rrc == MATCH_PRUNE || rrc == MATCH_COMMIT)        if (rrc == MATCH_SKIP || rrc == MATCH_PRUNE || rrc == MATCH_COMMIT)
1644          {          {
# Line 1593  for (;;) Line 1665  for (;;)
1665      back a number of characters, not bytes. */      back a number of characters, not bytes. */
1666    
1667      case OP_REVERSE:      case OP_REVERSE:
1668  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1669      if (utf8)      if (utf)
1670        {        {
1671        i = GET(ecode, 1);        i = GET(ecode, 1);
1672        while (i-- > 0)        while (i-- > 0)
# Line 1625  for (;;) Line 1697  for (;;)
1697      function is able to force a failure. */      function is able to force a failure. */
1698    
1699      case OP_CALLOUT:      case OP_CALLOUT:
1700      if (pcre_callout != NULL)      if (PUBL(callout) != NULL)
1701        {        {
1702        pcre_callout_block cb;        PUBL(callout_block) cb;
1703        cb.version          = 2;   /* Version 1 of the callout block */        cb.version          = 2;   /* Version 1 of the callout block */
1704        cb.callout_number   = ecode[1];        cb.callout_number   = ecode[1];
1705        cb.offset_vector    = md->offset_vector;        cb.offset_vector    = md->offset_vector;
1706    #if defined COMPILE_PCRE8
1707        cb.subject          = (PCRE_SPTR)md->start_subject;        cb.subject          = (PCRE_SPTR)md->start_subject;
1708    #elif defined COMPILE_PCRE16
1709          cb.subject          = (PCRE_SPTR16)md->start_subject;
1710    #elif defined COMPILE_PCRE32
1711          cb.subject          = (PCRE_SPTR32)md->start_subject;
1712    #endif
1713        cb.subject_length   = (int)(md->end_subject - md->start_subject);        cb.subject_length   = (int)(md->end_subject - md->start_subject);
1714        cb.start_match      = (int)(mstart - md->start_subject);        cb.start_match      = (int)(mstart - md->start_subject);
1715        cb.current_position = (int)(eptr - md->start_subject);        cb.current_position = (int)(eptr - md->start_subject);
# Line 1641  for (;;) Line 1719  for (;;)
1719        cb.capture_last     = md->capture_last;        cb.capture_last     = md->capture_last;
1720        cb.callout_data     = md->callout_data;        cb.callout_data     = md->callout_data;
1721        cb.mark             = md->nomatch_mark;        cb.mark             = md->nomatch_mark;
1722        if ((rrc = (*pcre_callout)(&cb)) > 0) RRETURN(MATCH_NOMATCH);        if ((rrc = (*PUBL(callout))(&cb)) > 0) RRETURN(MATCH_NOMATCH);
1723        if (rrc < 0) RRETURN(rrc);        if (rrc < 0) RRETURN(rrc);
1724        }        }
1725      ecode += 2 + 2*LINK_SIZE;      ecode += 2 + 2*LINK_SIZE;
# Line 1667  for (;;) Line 1745  for (;;)
1745      case OP_RECURSE:      case OP_RECURSE:
1746        {        {
1747        recursion_info *ri;        recursion_info *ri;
1748        int recno;        unsigned int recno;
1749    
1750        callpat = md->start_code + GET(ecode, 1);        callpat = md->start_code + GET(ecode, 1);
1751        recno = (callpat == md->start_code)? 0 :        recno = (callpat == md->start_code)? 0 :
# Line 1700  for (;;) Line 1778  for (;;)
1778        else        else
1779          {          {
1780          new_recursive.offset_save =          new_recursive.offset_save =
1781            (int *)(pcre_malloc)(new_recursive.saved_max * sizeof(int));            (int *)(PUBL(malloc))(new_recursive.saved_max * sizeof(int));
1782          if (new_recursive.offset_save == NULL) RRETURN(PCRE_ERROR_NOMEMORY);          if (new_recursive.offset_save == NULL) RRETURN(PCRE_ERROR_NOMEMORY);
1783          }          }
1784        memcpy(new_recursive.offset_save, md->offset_vector,        memcpy(new_recursive.offset_save, md->offset_vector,
# Line 1715  for (;;) Line 1793  for (;;)
1793        do        do
1794          {          {
1795          if (cbegroup) md->match_function_type = MATCH_CBEGROUP;          if (cbegroup) md->match_function_type = MATCH_CBEGROUP;
1796          RMATCH(eptr, callpat + _pcre_OP_lengths[*callpat], offset_top,          RMATCH(eptr, callpat + PRIV(OP_lengths)[*callpat], offset_top,
1797            md, eptrb, RM6);            md, eptrb, RM6);
1798          memcpy(md->offset_vector, new_recursive.offset_save,          memcpy(md->offset_vector, new_recursive.offset_save,
1799              new_recursive.saved_max * sizeof(int));              new_recursive.saved_max * sizeof(int));
# Line 1724  for (;;) Line 1802  for (;;)
1802            {            {
1803            DPRINTF(("Recursion matched\n"));            DPRINTF(("Recursion matched\n"));
1804            if (new_recursive.offset_save != stacksave)            if (new_recursive.offset_save != stacksave)
1805              (pcre_free)(new_recursive.offset_save);              (PUBL(free))(new_recursive.offset_save);
1806    
1807            /* 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
1808            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 1813  for (;;)
1813            goto RECURSION_MATCHED;        /* Exit loop; end processing */            goto RECURSION_MATCHED;        /* Exit loop; end processing */
1814            }            }
1815    
1816          /* 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
1817          as NOMATCH. */          is treated as NOMATCH. */
1818    
1819          else if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN)          else if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN &&
1820                     rrc != MATCH_COMMIT)
1821            {            {
1822            DPRINTF(("Recursion gave error %d\n", rrc));            DPRINTF(("Recursion gave error %d\n", rrc));
1823            if (new_recursive.offset_save != stacksave)            if (new_recursive.offset_save != stacksave)
1824              (pcre_free)(new_recursive.offset_save);              (PUBL(free))(new_recursive.offset_save);
1825            RRETURN(rrc);            RRETURN(rrc);
1826            }            }
1827    
# Line 1754  for (;;) Line 1833  for (;;)
1833        DPRINTF(("Recursion didn't match\n"));        DPRINTF(("Recursion didn't match\n"));
1834        md->recursive = new_recursive.prevrec;        md->recursive = new_recursive.prevrec;
1835        if (new_recursive.offset_save != stacksave)        if (new_recursive.offset_save != stacksave)
1836          (pcre_free)(new_recursive.offset_save);          (PUBL(free))(new_recursive.offset_save);
1837        RRETURN(MATCH_NOMATCH);        RRETURN(MATCH_NOMATCH);
1838        }        }
1839    
# Line 1949  for (;;) Line 2028  for (;;)
2028          }          }
2029        if (*prev >= OP_SBRA)    /* Could match an empty string */        if (*prev >= OP_SBRA)    /* Could match an empty string */
2030          {          {
         md->match_function_type = MATCH_CBEGROUP;  
2031          RMATCH(eptr, prev, offset_top, md, eptrb, RM50);          RMATCH(eptr, prev, offset_top, md, eptrb, RM50);
2032          RRETURN(rrc);          RRETURN(rrc);
2033          }          }
# Line 1958  for (;;) Line 2036  for (;;)
2036        }        }
2037      else  /* OP_KETRMAX */      else  /* OP_KETRMAX */
2038        {        {
       if (*prev >= OP_SBRA) md->match_function_type = MATCH_CBEGROUP;  
2039        RMATCH(eptr, prev, offset_top, md, eptrb, RM13);        RMATCH(eptr, prev, offset_top, md, eptrb, RM13);
2040        if (rrc == MATCH_ONCE && md->once_target == prev) rrc = MATCH_NOMATCH;        if (rrc == MATCH_ONCE && md->once_target == prev) rrc = MATCH_NOMATCH;
2041        if (rrc != MATCH_NOMATCH) RRETURN(rrc);        if (rrc != MATCH_NOMATCH) RRETURN(rrc);
# Line 2015  for (;;) Line 2092  for (;;)
2092    
2093      case OP_DOLLM:      case OP_DOLLM:
2094      if (eptr < md->end_subject)      if (eptr < md->end_subject)
2095        { if (!IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH); }        {
2096          if (!IS_NEWLINE(eptr))
2097            {
2098            if (md->partial != 0 &&
2099                eptr + 1 >= md->end_subject &&
2100                NLBLOCK->nltype == NLTYPE_FIXED &&
2101                NLBLOCK->nllen == 2 &&
2102                RAWUCHARTEST(eptr) == NLBLOCK->nl[0])
2103              {
2104              md->hitend = TRUE;
2105              if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
2106              }
2107            RRETURN(MATCH_NOMATCH);
2108            }
2109          }
2110      else      else
2111        {        {
2112        if (md->noteol) RRETURN(MATCH_NOMATCH);        if (md->noteol) RRETURN(MATCH_NOMATCH);
# Line 2047  for (;;) Line 2138  for (;;)
2138      ASSERT_NL_OR_EOS:      ASSERT_NL_OR_EOS:
2139      if (eptr < md->end_subject &&      if (eptr < md->end_subject &&
2140          (!IS_NEWLINE(eptr) || eptr != md->end_subject - md->nllen))          (!IS_NEWLINE(eptr) || eptr != md->end_subject - md->nllen))
2141          {
2142          if (md->partial != 0 &&
2143              eptr + 1 >= md->end_subject &&
2144              NLBLOCK->nltype == NLTYPE_FIXED &&
2145              NLBLOCK->nllen == 2 &&
2146              RAWUCHARTEST(eptr) == NLBLOCK->nl[0])
2147            {
2148            md->hitend = TRUE;
2149            if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
2150            }
2151        RRETURN(MATCH_NOMATCH);        RRETURN(MATCH_NOMATCH);
2152          }
2153    
2154      /* Either at end of string or \n before end. */      /* Either at end of string or \n before end. */
2155    
# Line 2066  for (;;) Line 2168  for (;;)
2168        be "non-word" characters. Remember the earliest consulted character for        be "non-word" characters. Remember the earliest consulted character for
2169        partial matching. */        partial matching. */
2170    
2171  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2172        if (utf8)        if (utf)
2173          {          {
2174          /* Get status of previous character */          /* Get status of previous character */
2175    
2176          if (eptr == md->start_subject) prev_is_word = FALSE; else          if (eptr == md->start_subject) prev_is_word = FALSE; else
2177            {            {
2178            USPTR lastptr = eptr - 1;            PCRE_PUCHAR lastptr = eptr - 1;
2179            while((*lastptr & 0xc0) == 0x80) lastptr--;            BACKCHAR(lastptr);
2180            if (lastptr < md->start_used_ptr) md->start_used_ptr = lastptr;            if (lastptr < md->start_used_ptr) md->start_used_ptr = lastptr;
2181            GETCHAR(c, lastptr);            GETCHAR(c, lastptr);
2182  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
# Line 2139  for (;;) Line 2241  for (;;)
2241              }              }
2242            else            else
2243  #endif  #endif
2244            prev_is_word = ((md->ctypes[eptr[-1]] & ctype_word) != 0);            prev_is_word = MAX_255(eptr[-1])
2245                && ((md->ctypes[eptr[-1]] & ctype_word) != 0);
2246            }            }
2247    
2248          /* Get status of next character */          /* Get status of next character */
# Line 2162  for (;;) Line 2265  for (;;)
2265            }            }
2266          else          else
2267  #endif  #endif
2268          cur_is_word = ((md->ctypes[*eptr] & ctype_word) != 0);          cur_is_word = MAX_255(*eptr)
2269              && ((md->ctypes[*eptr] & ctype_word) != 0);
2270          }          }
2271    
2272        /* Now see if the situation is what we want */        /* Now see if the situation is what we want */
# Line 2173  for (;;) Line 2277  for (;;)
2277        }        }
2278      break;      break;
2279    
2280      /* Match a single character type; inline for speed */      /* Match any single character type except newline; have to take care with
2281        CRLF newlines and partial matching. */
2282    
2283      case OP_ANY:      case OP_ANY:
2284      if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH);      if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH);
2285        if (md->partial != 0 &&
2286            eptr + 1 >= md->end_subject &&
2287            NLBLOCK->nltype == NLTYPE_FIXED &&
2288            NLBLOCK->nllen == 2 &&
2289            RAWUCHARTEST(eptr) == NLBLOCK->nl[0])
2290          {
2291          md->hitend = TRUE;
2292          if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
2293          }
2294    
2295      /* Fall through */      /* Fall through */
2296    
2297        /* Match any single character whatsoever. */
2298    
2299      case OP_ALLANY:      case OP_ALLANY:
2300      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 */
2301        {                            /* not be updated before SCHECK_PARTIAL. */        {                            /* not be updated before SCHECK_PARTIAL. */
# Line 2186  for (;;) Line 2303  for (;;)
2303        RRETURN(MATCH_NOMATCH);        RRETURN(MATCH_NOMATCH);
2304        }        }
2305      eptr++;      eptr++;
2306      if (utf8) while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;  #ifdef SUPPORT_UTF
2307        if (utf) ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
2308    #endif
2309      ecode++;      ecode++;
2310      break;      break;
2311    
# Line 2211  for (;;) Line 2330  for (;;)
2330        }        }
2331      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
2332      if (      if (
2333  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || !(defined COMPILE_PCRE8)
2334         c < 256 &&         c < 256 &&
2335  #endif  #endif
2336         (md->ctypes[c] & ctype_digit) != 0         (md->ctypes[c] & ctype_digit) != 0
# Line 2228  for (;;) Line 2347  for (;;)
2347        }        }
2348      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
2349      if (      if (
2350  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || !(defined COMPILE_PCRE8)
2351         c >= 256 ||         c > 255 ||
2352  #endif  #endif
2353         (md->ctypes[c] & ctype_digit) == 0         (md->ctypes[c] & ctype_digit) == 0
2354         )         )
# Line 2245  for (;;) Line 2364  for (;;)
2364        }        }
2365      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
2366      if (      if (
2367  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || !(defined COMPILE_PCRE8)
2368         c < 256 &&         c < 256 &&
2369  #endif  #endif
2370         (md->ctypes[c] & ctype_space) != 0         (md->ctypes[c] & ctype_space) != 0
# Line 2262  for (;;) Line 2381  for (;;)
2381        }        }
2382      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
2383      if (      if (
2384  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || !(defined COMPILE_PCRE8)
2385         c >= 256 ||         c > 255 ||
2386  #endif  #endif
2387         (md->ctypes[c] & ctype_space) == 0         (md->ctypes[c] & ctype_space) == 0
2388         )         )
# Line 2279  for (;;) Line 2398  for (;;)
2398        }        }
2399      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
2400      if (      if (
2401  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || !(defined COMPILE_PCRE8)
2402         c < 256 &&         c < 256 &&
2403  #endif  #endif
2404         (md->ctypes[c] & ctype_word) != 0         (md->ctypes[c] & ctype_word) != 0
# Line 2296  for (;;) Line 2415  for (;;)
2415        }        }
2416      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
2417      if (      if (
2418  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || !(defined COMPILE_PCRE8)
2419         c >= 256 ||         c > 255 ||
2420  #endif  #endif
2421         (md->ctypes[c] & ctype_word) == 0         (md->ctypes[c] & ctype_word) == 0
2422         )         )
# Line 2316  for (;;) Line 2435  for (;;)
2435        {        {
2436        default: RRETURN(MATCH_NOMATCH);        default: RRETURN(MATCH_NOMATCH);
2437    
2438        case 0x000d:        case CHAR_CR:
2439        if (eptr < md->end_subject && *eptr == 0x0a) eptr++;        if (eptr >= md->end_subject)
2440            {
2441            SCHECK_PARTIAL();
2442            }
2443          else if (RAWUCHARTEST(eptr) == CHAR_LF) eptr++;
2444        break;        break;
2445    
2446        case 0x000a:        case CHAR_LF:
2447        break;        break;
2448    
2449        case 0x000b:        case CHAR_VT:
2450        case 0x000c:        case CHAR_FF:
2451        case 0x0085:        case CHAR_NEL:
2452    #ifndef EBCDIC
2453        case 0x2028:        case 0x2028:
2454        case 0x2029:        case 0x2029:
2455    #endif  /* Not EBCDIC */
2456        if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH);        if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH);
2457        break;        break;
2458        }        }
# Line 2343  for (;;) Line 2468  for (;;)
2468      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
2469      switch(c)      switch(c)
2470        {        {
2471          HSPACE_CASES: RRETURN(MATCH_NOMATCH);  /* Byte and multibyte cases */
2472        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);  
2473        }        }
2474      ecode++;      ecode++;
2475      break;      break;
# Line 2377  for (;;) Line 2483  for (;;)
2483      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
2484      switch(c)      switch(c)
2485        {        {
2486          HSPACE_CASES: break;  /* Byte and multibyte cases */
2487        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;  
2488        }        }
2489      ecode++;      ecode++;
2490      break;      break;
# Line 2411  for (;;) Line 2498  for (;;)
2498      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
2499      switch(c)      switch(c)
2500        {        {
2501          VSPACE_CASES: RRETURN(MATCH_NOMATCH);
2502        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);  
2503        }        }
2504      ecode++;      ecode++;
2505      break;      break;
# Line 2433  for (;;) Line 2513  for (;;)
2513      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
2514      switch(c)      switch(c)
2515        {        {
2516          VSPACE_CASES: break;
2517        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;  
2518        }        }
2519      ecode++;      ecode++;
2520      break;      break;
# Line 2459  for (;;) Line 2532  for (;;)
2532        }        }
2533      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
2534        {        {
2535          const pcre_uint32 *cp;
2536        const ucd_record *prop = GET_UCD(c);        const ucd_record *prop = GET_UCD(c);
2537    
2538        switch(ecode[1])        switch(ecode[1])
# Line 2475  for (;;) Line 2549  for (;;)
2549          break;          break;
2550    
2551          case PT_GC:          case PT_GC:
2552          if ((ecode[2] != _pcre_ucp_gentype[prop->chartype]) == (op == OP_PROP))          if ((ecode[2] != PRIV(ucp_gentype)[prop->chartype]) == (op == OP_PROP))
2553            RRETURN(MATCH_NOMATCH);            RRETURN(MATCH_NOMATCH);
2554          break;          break;
2555    
# Line 2492  for (;;) Line 2566  for (;;)
2566          /* These are specials */          /* These are specials */
2567    
2568          case PT_ALNUM:          case PT_ALNUM:
2569          if ((_pcre_ucp_gentype[prop->chartype] == ucp_L ||          if ((PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
2570               _pcre_ucp_gentype[prop->chartype] == ucp_N) == (op == OP_NOTPROP))               PRIV(ucp_gentype)[prop->chartype] == ucp_N) == (op == OP_NOTPROP))
2571            RRETURN(MATCH_NOMATCH);            RRETURN(MATCH_NOMATCH);
2572          break;          break;
2573    
2574          case PT_SPACE:    /* Perl space */          case PT_SPACE:    /* Perl space */
2575          if ((_pcre_ucp_gentype[prop->chartype] == ucp_Z ||          if ((PRIV(ucp_gentype)[prop->chartype] == ucp_Z ||
2576               c == CHAR_HT || c == CHAR_NL || c == CHAR_FF || c == CHAR_CR)               c == CHAR_HT || c == CHAR_NL || c == CHAR_FF || c == CHAR_CR)
2577                 == (op == OP_NOTPROP))                 == (op == OP_NOTPROP))
2578            RRETURN(MATCH_NOMATCH);            RRETURN(MATCH_NOMATCH);
2579          break;          break;
2580    
2581          case PT_PXSPACE:  /* POSIX space */          case PT_PXSPACE:  /* POSIX space */
2582          if ((_pcre_ucp_gentype[prop->chartype] == ucp_Z ||          if ((PRIV(ucp_gentype)[prop->chartype] == ucp_Z ||
2583               c == CHAR_HT || c == CHAR_NL || c == CHAR_VT ||               c == CHAR_HT || c == CHAR_NL || c == CHAR_VT ||
2584               c == CHAR_FF || c == CHAR_CR)               c == CHAR_FF || c == CHAR_CR)
2585                 == (op == OP_NOTPROP))                 == (op == OP_NOTPROP))
# Line 2513  for (;;) Line 2587  for (;;)
2587          break;          break;
2588    
2589          case PT_WORD:          case PT_WORD:
2590          if ((_pcre_ucp_gentype[prop->chartype] == ucp_L ||          if ((PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
2591               _pcre_ucp_gentype[prop->chartype] == ucp_N ||               PRIV(ucp_gentype)[prop->chartype] == ucp_N ||
2592               c == CHAR_UNDERSCORE) == (op == OP_NOTPROP))               c == CHAR_UNDERSCORE) == (op == OP_NOTPROP))
2593            RRETURN(MATCH_NOMATCH);            RRETURN(MATCH_NOMATCH);
2594          break;          break;
2595    
2596            case PT_CLIST:
2597            cp = PRIV(ucd_caseless_sets) + prop->caseset;
2598            for (;;)
2599              {
2600              if (c < *cp)
2601                { if (op == OP_PROP) { RRETURN(MATCH_NOMATCH); } else break; }
2602              if (c == *cp++)
2603                { if (op == OP_PROP) break; else { RRETURN(MATCH_NOMATCH); } }
2604              }
2605            break;
2606    
2607          /* This should never occur */          /* This should never occur */
2608    
2609          default:          default:
# Line 2538  for (;;) Line 2623  for (;;)
2623        SCHECK_PARTIAL();        SCHECK_PARTIAL();
2624        RRETURN(MATCH_NOMATCH);        RRETURN(MATCH_NOMATCH);
2625        }        }
2626      GETCHARINCTEST(c, eptr);      else
     if (UCD_CATEGORY(c) == ucp_M) RRETURN(MATCH_NOMATCH);  
     while (eptr < md->end_subject)  
2627        {        {
2628        int len = 1;        int lgb, rgb;
2629        if (!utf8) c = *eptr; else { GETCHARLEN(c, eptr, len); }        GETCHARINCTEST(c, eptr);
2630        if (UCD_CATEGORY(c) != ucp_M) break;        lgb = UCD_GRAPHBREAK(c);
2631        eptr += len;        while (eptr < md->end_subject)
2632            {
2633            int len = 1;
2634            if (!utf) c = *eptr; else { GETCHARLEN(c, eptr, len); }
2635            rgb = UCD_GRAPHBREAK(c);
2636            if ((PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0) break;
2637            lgb = rgb;
2638            eptr += len;
2639            }
2640        }        }
2641        CHECK_PARTIAL();
2642      ecode++;      ecode++;
2643      break;      break;
2644  #endif  #endif  /* SUPPORT_UCP */
2645    
2646    
2647      /* 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 2656  for (;;)
2656      case OP_REFI:      case OP_REFI:
2657      caseless = op == OP_REFI;      caseless = op == OP_REFI;
2658      offset = GET2(ecode, 1) << 1;               /* Doubled ref number */      offset = GET2(ecode, 1) << 1;               /* Doubled ref number */
2659      ecode += 3;      ecode += 1 + IMM2_SIZE;
2660    
2661      /* If the reference is unset, there are two possibilities:      /* If the reference is unset, there are two possibilities:
2662    
# Line 2604  for (;;) Line 2696  for (;;)
2696        case OP_CRMINRANGE:        case OP_CRMINRANGE:
2697        minimize = (*ecode == OP_CRMINRANGE);        minimize = (*ecode == OP_CRMINRANGE);
2698        min = GET2(ecode, 1);        min = GET2(ecode, 1);
2699        max = GET2(ecode, 3);        max = GET2(ecode, 1 + IMM2_SIZE);
2700        if (max == 0) max = INT_MAX;        if (max == 0) max = INT_MAX;
2701        ecode += 5;        ecode += 1 + 2 * IMM2_SIZE;
2702        break;        break;
2703    
2704        default:               /* No repeat follows */        default:               /* No repeat follows */
2705        if ((length = match_ref(offset, eptr, length, md, caseless)) < 0)        if ((length = match_ref(offset, eptr, length, md, caseless)) < 0)
2706          {          {
2707            if (length == -2) eptr = md->end_subject;   /* Partial match */
2708          CHECK_PARTIAL();          CHECK_PARTIAL();
2709          RRETURN(MATCH_NOMATCH);          RRETURN(MATCH_NOMATCH);
2710          }          }
# Line 2620  for (;;) Line 2713  for (;;)
2713        }        }
2714    
2715      /* Handle repeated back references. If the length of the reference is      /* Handle repeated back references. If the length of the reference is
2716      zero, just continue with the main loop. */      zero, just continue with the main loop. If the length is negative, it
2717        means the reference is unset in non-Java-compatible mode. If the minimum is
2718        zero, we can continue at the same level without recursion. For any other
2719        minimum, carrying on will result in NOMATCH. */
2720    
2721      if (length == 0) continue;      if (length == 0) continue;
2722        if (length < 0 && min == 0) continue;
2723    
2724      /* First, ensure the minimum number of matches are present. We get back      /* First, ensure the minimum number of matches are present. We get back
2725      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 2730  for (;;)
2730        int slength;        int slength;
2731        if ((slength = match_ref(offset, eptr, length, md, caseless)) < 0)        if ((slength = match_ref(offset, eptr, length, md, caseless)) < 0)
2732          {          {
2733            if (slength == -2) eptr = md->end_subject;   /* Partial match */
2734          CHECK_PARTIAL();          CHECK_PARTIAL();
2735          RRETURN(MATCH_NOMATCH);          RRETURN(MATCH_NOMATCH);
2736          }          }
# Line 2656  for (;;) Line 2754  for (;;)
2754          if (fi >= max) RRETURN(MATCH_NOMATCH);          if (fi >= max) RRETURN(MATCH_NOMATCH);
2755          if ((slength = match_ref(offset, eptr, length, md, caseless)) < 0)          if ((slength = match_ref(offset, eptr, length, md, caseless)) < 0)
2756            {            {
2757              if (slength == -2) eptr = md->end_subject;   /* Partial match */
2758            CHECK_PARTIAL();            CHECK_PARTIAL();
2759            RRETURN(MATCH_NOMATCH);            RRETURN(MATCH_NOMATCH);
2760            }            }
# Line 2674  for (;;) Line 2773  for (;;)
2773          int slength;          int slength;
2774          if ((slength = match_ref(offset, eptr, length, md, caseless)) < 0)          if ((slength = match_ref(offset, eptr, length, md, caseless)) < 0)
2775            {            {
2776            CHECK_PARTIAL();            /* Can't use CHECK_PARTIAL because we don't want to update eptr in
2777              the soft partial matching case. */
2778    
2779              if (slength == -2 && md->partial != 0 &&
2780                  md->end_subject > md->start_used_ptr)
2781                {
2782                md->hitend = TRUE;
2783                if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
2784                }
2785            break;            break;
2786            }            }
2787          eptr += slength;          eptr += slength;
2788          }          }
2789    
2790        while (eptr >= pp)        while (eptr >= pp)
2791          {          {
2792          RMATCH(eptr, ecode, offset_top, md, eptrb, RM15);          RMATCH(eptr, ecode, offset_top, md, eptrb, RM15);
# Line 2703  for (;;) Line 2811  for (;;)
2811      case OP_NCLASS:      case OP_NCLASS:
2812      case OP_CLASS:      case OP_CLASS:
2813        {        {
2814          /* The data variable is saved across frames, so the byte map needs to
2815          be stored there. */
2816    #define BYTE_MAP ((pcre_uint8 *)data)
2817        data = ecode + 1;                /* Save for matching */        data = ecode + 1;                /* Save for matching */
2818        ecode += 33;                     /* Advance past the item */        ecode += 1 + (32 / sizeof(pcre_uchar)); /* Advance past the item */
2819    
2820        switch (*ecode)        switch (*ecode)
2821          {          {
# Line 2725  for (;;) Line 2836  for (;;)
2836          case OP_CRMINRANGE:          case OP_CRMINRANGE:
2837          minimize = (*ecode == OP_CRMINRANGE);          minimize = (*ecode == OP_CRMINRANGE);
2838          min = GET2(ecode, 1);          min = GET2(ecode, 1);
2839          max = GET2(ecode, 3);          max = GET2(ecode, 1 + IMM2_SIZE);
2840          if (max == 0) max = INT_MAX;          if (max == 0) max = INT_MAX;
2841          ecode += 5;          ecode += 1 + 2 * IMM2_SIZE;
2842          break;          break;
2843    
2844          default:               /* No repeat follows */          default:               /* No repeat follows */
# Line 2737  for (;;) Line 2848  for (;;)
2848    
2849        /* First, ensure the minimum number of matches are present. */        /* First, ensure the minimum number of matches are present. */
2850    
2851  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2852        /* UTF-8 mode */        if (utf)
       if (utf8)  
2853          {          {
2854          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
2855            {            {
# Line 2754  for (;;) Line 2864  for (;;)
2864              if (op == OP_CLASS) RRETURN(MATCH_NOMATCH);              if (op == OP_CLASS) RRETURN(MATCH_NOMATCH);
2865              }              }
2866            else            else
2867              {              if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);
             if ((data[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);  
             }  
2868            }            }
2869          }          }
2870        else        else
2871  #endif  #endif
2872        /* Not UTF-8 mode */        /* Not UTF mode */
2873          {          {
2874          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
2875            {            {
# Line 2771  for (;;) Line 2879  for (;;)
2879              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
2880              }              }
2881            c = *eptr++;            c = *eptr++;
2882            if ((data[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);  #ifndef COMPILE_PCRE8
2883              if (c > 255)
2884                {
2885                if (op == OP_CLASS) RRETURN(MATCH_NOMATCH);
2886                }
2887              else
2888    #endif
2889                if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);
2890            }            }
2891          }          }
2892    
# Line 2785  for (;;) Line 2900  for (;;)
2900    
2901        if (minimize)        if (minimize)
2902          {          {
2903  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2904          /* UTF-8 mode */          if (utf)
         if (utf8)  
2905            {            {
2906            for (fi = min;; fi++)            for (fi = min;; fi++)
2907              {              {
# Line 2805  for (;;) Line 2919  for (;;)
2919                if (op == OP_CLASS) RRETURN(MATCH_NOMATCH);                if (op == OP_CLASS) RRETURN(MATCH_NOMATCH);
2920                }                }
2921              else              else
2922                {                if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);
               if ((data[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);  
               }  
2923              }              }
2924            }            }
2925          else          else
2926  #endif  #endif
2927          /* Not UTF-8 mode */          /* Not UTF mode */
2928            {            {
2929            for (fi = min;; fi++)            for (fi = min;; fi++)
2930              {              {
# Line 2825  for (;;) Line 2937  for (;;)
2937                RRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
2938                }                }
2939              c = *eptr++;              c = *eptr++;
2940              if ((data[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);  #ifndef COMPILE_PCRE8
2941                if (c > 255)
2942                  {
2943                  if (op == OP_CLASS) RRETURN(MATCH_NOMATCH);
2944                  }
2945                else
2946    #endif
2947                  if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);
2948              }              }
2949            }            }
2950          /* Control never gets here */          /* Control never gets here */
# Line 2837  for (;;) Line 2956  for (;;)
2956          {          {
2957          pp = eptr;          pp = eptr;
2958    
2959  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2960          /* UTF-8 mode */          if (utf)
         if (utf8)  
2961            {            {
2962            for (i = min; i < max; i++)            for (i = min; i < max; i++)
2963              {              {
# Line 2855  for (;;) Line 2973  for (;;)
2973                if (op == OP_CLASS) break;                if (op == OP_CLASS) break;
2974                }                }
2975              else              else
2976                {                if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) break;
               if ((data[c/8] & (1 << (c&7))) == 0) break;  
               }  
2977              eptr += len;              eptr += len;
2978              }              }
2979            for (;;)            for (;;)
# Line 2870  for (;;) Line 2986  for (;;)
2986            }            }
2987          else          else
2988  #endif  #endif
2989            /* Not UTF-8 mode */            /* Not UTF mode */
2990            {            {
2991            for (i = min; i < max; i++)            for (i = min; i < max; i++)
2992              {              {
# Line 2880  for (;;) Line 2996  for (;;)
2996                break;                break;
2997                }                }
2998              c = *eptr;              c = *eptr;
2999              if ((data[c/8] & (1 << (c&7))) == 0) break;  #ifndef COMPILE_PCRE8
3000                if (c > 255)
3001                  {
3002                  if (op == OP_CLASS) break;
3003                  }
3004                else
3005    #endif
3006                  if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) break;
3007              eptr++;              eptr++;
3008              }              }
3009            while (eptr >= pp)            while (eptr >= pp)
# Line 2893  for (;;) Line 3016  for (;;)
3016    
3017          RRETURN(MATCH_NOMATCH);          RRETURN(MATCH_NOMATCH);
3018          }          }
3019    #undef BYTE_MAP
3020        }        }
3021      /* Control never gets here */      /* Control never gets here */
3022    
# Line 2901  for (;;) Line 3025  for (;;)
3025      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
3026      mode, because Unicode properties are supported in non-UTF-8 mode. */      mode, because Unicode properties are supported in non-UTF-8 mode. */
3027    
3028  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
3029      case OP_XCLASS:      case OP_XCLASS:
3030        {        {
3031        data = ecode + 1 + LINK_SIZE;                /* Save for matching */        data = ecode + 1 + LINK_SIZE;                /* Save for matching */
# Line 2926  for (;;) Line 3050  for (;;)
3050          case OP_CRMINRANGE:          case OP_CRMINRANGE:
3051          minimize = (*ecode == OP_CRMINRANGE);          minimize = (*ecode == OP_CRMINRANGE);
3052          min = GET2(ecode, 1);          min = GET2(ecode, 1);
3053          max = GET2(ecode, 3);          max = GET2(ecode, 1 + IMM2_SIZE);
3054          if (max == 0) max = INT_MAX;          if (max == 0) max = INT_MAX;
3055          ecode += 5;          ecode += 1 + 2 * IMM2_SIZE;
3056          break;          break;
3057    
3058          default:               /* No repeat follows */          default:               /* No repeat follows */
# Line 2946  for (;;) Line 3070  for (;;)
3070            RRETURN(MATCH_NOMATCH);            RRETURN(MATCH_NOMATCH);
3071            }            }
3072          GETCHARINCTEST(c, eptr);          GETCHARINCTEST(c, eptr);
3073          if (!_pcre_xclass(c, data)) RRETURN(MATCH_NOMATCH);          if (!PRIV(xclass)(c, data, utf)) RRETURN(MATCH_NOMATCH);
3074          }          }
3075    
3076        /* 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 3094  for (;;)
3094              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
3095              }              }
3096            GETCHARINCTEST(c, eptr);            GETCHARINCTEST(c, eptr);
3097            if (!_pcre_xclass(c, data)) RRETURN(MATCH_NOMATCH);            if (!PRIV(xclass)(c, data, utf)) RRETURN(MATCH_NOMATCH);
3098            }            }
3099          /* Control never gets here */          /* Control never gets here */
3100          }          }
# Line 2988  for (;;) Line 3112  for (;;)
3112              SCHECK_PARTIAL();              SCHECK_PARTIAL();
3113              break;              break;
3114              }              }
3115    #ifdef SUPPORT_UTF
3116            GETCHARLENTEST(c, eptr, len);            GETCHARLENTEST(c, eptr, len);
3117            if (!_pcre_xclass(c, data)) break;  #else
3118              c = *eptr;
3119    #endif
3120              if (!PRIV(xclass)(c, data, utf)) break;
3121            eptr += len;            eptr += len;
3122            }            }
3123          for(;;)          for(;;)
# Line 2997  for (;;) Line 3125  for (;;)
3125            RMATCH(eptr, ecode, offset_top, md, eptrb, RM21);            RMATCH(eptr, ecode, offset_top, md, eptrb, RM21);
3126            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3127            if (eptr-- == pp) break;        /* Stop if tried at original pos */            if (eptr-- == pp) break;        /* Stop if tried at original pos */
3128            if (utf8) BACKCHAR(eptr);  #ifdef SUPPORT_UTF
3129              if (utf) BACKCHAR(eptr);
3130    #endif
3131            }            }
3132          RRETURN(MATCH_NOMATCH);          RRETURN(MATCH_NOMATCH);
3133          }          }
# Line 3009  for (;;) Line 3139  for (;;)
3139      /* Match a single character, casefully */      /* Match a single character, casefully */
3140    
3141      case OP_CHAR:      case OP_CHAR:
3142  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3143      if (utf8)      if (utf)
3144        {        {
3145        length = 1;        length = 1;
3146        ecode++;        ecode++;
# Line 3020  for (;;) Line 3150  for (;;)
3150          CHECK_PARTIAL();             /* Not SCHECK_PARTIAL() */          CHECK_PARTIAL();             /* Not SCHECK_PARTIAL() */
3151          RRETURN(MATCH_NOMATCH);          RRETURN(MATCH_NOMATCH);
3152          }          }
3153        while (length-- > 0) if (*ecode++ != *eptr++) RRETURN(MATCH_NOMATCH);        while (length-- > 0) if (*ecode++ != RAWUCHARINC(eptr)) RRETURN(MATCH_NOMATCH);
3154        }        }
3155      else      else
3156  #endif  #endif
3157        /* Not UTF mode */
     /* Non-UTF-8 mode */  
3158        {        {
3159        if (md->end_subject - eptr < 1)        if (md->end_subject - eptr < 1)
3160          {          {
# Line 3037  for (;;) Line 3166  for (;;)
3166        }        }
3167      break;      break;
3168    
3169      /* Match a single character, caselessly */      /* Match a single character, caselessly. If we are at the end of the
3170        subject, give up immediately. */
3171    
3172      case OP_CHARI:      case OP_CHARI:
3173  #ifdef SUPPORT_UTF8      if (eptr >= md->end_subject)
3174      if (utf8)        {
3175          SCHECK_PARTIAL();
3176          RRETURN(MATCH_NOMATCH);
3177          }
3178    
3179    #ifdef SUPPORT_UTF
3180        if (utf)
3181        {        {
3182        length = 1;        length = 1;
3183        ecode++;        ecode++;
3184        GETCHARLEN(fc, ecode, length);        GETCHARLEN(fc, ecode, length);
3185    
       if (length > md->end_subject - eptr)  
         {  
         CHECK_PARTIAL();             /* Not SCHECK_PARTIAL() */  
         RRETURN(MATCH_NOMATCH);  
         }  
   
3186        /* 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
3187        can use the fast lookup table. */        we know that its other case must also be one byte long, so we can use the
3188          fast lookup table. We know that there is at least one byte left in the
3189          subject. */
3190    
3191        if (fc < 128)        if (fc < 128)
3192          {          {
3193          if (md->lcc[*ecode++] != md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH);          pcre_uchar cc = RAWUCHAR(eptr);
3194            if (md->lcc[fc] != TABLE_GET(cc, md->lcc, cc)) RRETURN(MATCH_NOMATCH);
3195            ecode++;
3196            eptr++;
3197          }          }
3198    
3199        /* Otherwise we must pick up the subject character */        /* Otherwise we must pick up the subject character. Note that we cannot
3200          use the value of "length" to check for sufficient bytes left, because the
3201          other case of the character may have more or fewer bytes.  */
3202    
3203        else        else
3204          {          {
3205          unsigned int dc;          pcre_uint32 dc;
3206          GETCHARINC(dc, eptr);          GETCHARINC(dc, eptr);
3207          ecode += length;          ecode += length;
3208    
# Line 3082  for (;;) Line 3219  for (;;)
3219          }          }
3220        }        }
3221      else      else
3222  #endif   /* SUPPORT_UTF8 */  #endif   /* SUPPORT_UTF */
3223    
3224      /* Non-UTF-8 mode */      /* Not UTF mode */
3225        {        {
3226        if (md->end_subject - eptr < 1)        if (TABLE_GET(ecode[1], md->lcc, ecode[1])
3227          {            != TABLE_GET(*eptr, md->lcc, *eptr)) RRETURN(MATCH_NOMATCH);
3228          SCHECK_PARTIAL();            /* This one can use SCHECK_PARTIAL() */        eptr++;
         RRETURN(MATCH_NOMATCH);  
         }  
       if (md->lcc[ecode[1]] != md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH);  
3229        ecode += 2;        ecode += 2;
3230        }        }
3231      break;      break;
# Line 3101  for (;;) Line 3235  for (;;)
3235      case OP_EXACT:      case OP_EXACT:
3236      case OP_EXACTI:      case OP_EXACTI:
3237      min = max = GET2(ecode, 1);      min = max = GET2(ecode, 1);
3238      ecode += 3;      ecode += 1 + IMM2_SIZE;
3239      goto REPEATCHAR;      goto REPEATCHAR;
3240    
3241      case OP_POSUPTO:      case OP_POSUPTO:
# Line 3116  for (;;) Line 3250  for (;;)
3250      min = 0;      min = 0;
3251      max = GET2(ecode, 1);      max = GET2(ecode, 1);
3252      minimize = *ecode == OP_MINUPTO || *ecode == OP_MINUPTOI;      minimize = *ecode == OP_MINUPTO || *ecode == OP_MINUPTOI;
3253      ecode += 3;      ecode += 1 + IMM2_SIZE;
3254      goto REPEATCHAR;      goto REPEATCHAR;
3255    
3256      case OP_POSSTAR:      case OP_POSSTAR:
# Line 3164  for (;;) Line 3298  for (;;)
3298      /* Common code for all repeated single-character matches. */      /* Common code for all repeated single-character matches. */
3299    
3300      REPEATCHAR:      REPEATCHAR:
3301  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3302      if (utf8)      if (utf)
3303        {        {
3304        length = 1;        length = 1;
3305        charptr = ecode;        charptr = ecode;
# Line 3178  for (;;) Line 3312  for (;;)
3312        if (length > 1)        if (length > 1)
3313          {          {
3314  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3315          unsigned int othercase;          pcre_uint32 othercase;
3316          if (op >= OP_STARI &&     /* Caseless */          if (op >= OP_STARI &&     /* Caseless */
3317              (othercase = UCD_OTHERCASE(fc)) != fc)              (othercase = UCD_OTHERCASE(fc)) != fc)
3318            oclength = _pcre_ord2utf8(othercase, occhars);            oclength = PRIV(ord2utf)(othercase, occhars);
3319          else oclength = 0;          else oclength = 0;
3320  #endif  /* SUPPORT_UCP */  #endif  /* SUPPORT_UCP */
3321    
3322          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3323            {            {
3324            if (eptr <= md->end_subject - length &&            if (eptr <= md->end_subject - length &&
3325              memcmp(eptr, charptr, length) == 0) eptr += length;              memcmp(eptr, charptr, IN_UCHARS(length)) == 0) eptr += length;
3326  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3327            else if (oclength > 0 &&            else if (oclength > 0 &&
3328                     eptr <= md->end_subject - oclength &&                     eptr <= md->end_subject - oclength &&
3329                     memcmp(eptr, occhars, oclength) == 0) eptr += oclength;                     memcmp(eptr, occhars, IN_UCHARS(oclength)) == 0) eptr += oclength;
3330  #endif  /* SUPPORT_UCP */  #endif  /* SUPPORT_UCP */
3331            else            else
3332              {              {
# Line 3211  for (;;) Line 3345  for (;;)
3345              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3346              if (fi >= max) RRETURN(MATCH_NOMATCH);              if (fi >= max) RRETURN(MATCH_NOMATCH);
3347              if (eptr <= md->end_subject - length &&              if (eptr <= md->end_subject - length &&
3348                memcmp(eptr, charptr, length) == 0) eptr += length;                memcmp(eptr, charptr, IN_UCHARS(length)) == 0) eptr += length;
3349  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3350              else if (oclength > 0 &&              else if (oclength > 0 &&
3351                       eptr <= md->end_subject - oclength &&                       eptr <= md->end_subject - oclength &&
3352                       memcmp(eptr, occhars, oclength) == 0) eptr += oclength;                       memcmp(eptr, occhars, IN_UCHARS(oclength)) == 0) eptr += oclength;
3353  #endif  /* SUPPORT_UCP */  #endif  /* SUPPORT_UCP */
3354              else              else
3355                {                {
# Line 3232  for (;;) Line 3366  for (;;)
3366            for (i = min; i < max; i++)            for (i = min; i < max; i++)
3367              {              {
3368              if (eptr <= md->end_subject - length &&              if (eptr <= md->end_subject - length &&
3369                  memcmp(eptr, charptr, length) == 0) eptr += length;                  memcmp(eptr, charptr, IN_UCHARS(length)) == 0) eptr += length;
3370  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3371              else if (oclength > 0 &&              else if (oclength > 0 &&
3372                       eptr <= md->end_subject - oclength &&                       eptr <= md->end_subject - oclength &&
3373                       memcmp(eptr, occhars, oclength) == 0) eptr += oclength;                       memcmp(eptr, occhars, IN_UCHARS(oclength)) == 0) eptr += oclength;
3374  #endif  /* SUPPORT_UCP */  #endif  /* SUPPORT_UCP */
3375              else              else
3376                {                {
# Line 3268  for (;;) Line 3402  for (;;)
3402        value of fc will always be < 128. */        value of fc will always be < 128. */
3403        }        }
3404      else      else
3405  #endif  /* SUPPORT_UTF8 */  #endif  /* SUPPORT_UTF */
3406          /* When not in UTF-8 mode, load a single-byte character. */
3407          fc = *ecode++;
3408    
3409      /* When not in UTF-8 mode, load a single-byte character. */      /* The value of fc at this point is always one character, though we may
3410        or may not be in UTF mode. The code is duplicated for the caseless and
     fc = *ecode++;  
   
     /* The value of fc at this point is always less than 256, though we may or  
     may not be in UTF-8 mode. The code is duplicated for the caseless and  
3411      caseful cases, for speed, since matching characters is likely to be quite      caseful cases, for speed, since matching characters is likely to be quite
3412      common. First, ensure the minimum number of matches are present. If min =      common. First, ensure the minimum number of matches are present. If min =
3413      max, continue at the same level without recursing. Otherwise, if      max, continue at the same level without recursing. Otherwise, if
# Line 3284  for (;;) Line 3416  for (;;)
3416      maximizing, find the maximum number of characters and work backwards. */      maximizing, find the maximum number of characters and work backwards. */
3417    
3418      DPRINTF(("matching %c{%d,%d} against subject %.*s\n", fc, min, max,      DPRINTF(("matching %c{%d,%d} against subject %.*s\n", fc, min, max,
3419        max, eptr));        max, (char *)eptr));
3420    
3421      if (op >= OP_STARI)  /* Caseless */      if (op >= OP_STARI)  /* Caseless */
3422        {        {
3423        fc = md->lcc[fc];  #ifdef COMPILE_PCRE8
3424          /* fc must be < 128 if UTF is enabled. */
3425          foc = md->fcc[fc];
3426    #else
3427    #ifdef SUPPORT_UTF
3428    #ifdef SUPPORT_UCP
3429          if (utf && fc > 127)
3430            foc = UCD_OTHERCASE(fc);
3431    #else
3432          if (utf && fc > 127)
3433            foc = fc;
3434    #endif /* SUPPORT_UCP */
3435          else
3436    #endif /* SUPPORT_UTF */
3437            foc = TABLE_GET(fc, md->fcc, fc);
3438    #endif /* COMPILE_PCRE8 */
3439    
3440        for (i = 1; i <= min; i++)        for (i = 1; i <= min; i++)
3441          {          {
3442            pcre_uchar cc;
3443    
3444          if (eptr >= md->end_subject)          if (eptr >= md->end_subject)
3445            {            {
3446            SCHECK_PARTIAL();            SCHECK_PARTIAL();
3447            RRETURN(MATCH_NOMATCH);            RRETURN(MATCH_NOMATCH);
3448            }            }
3449          if (fc != md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH);          cc = RAWUCHARTEST(eptr);
3450            if (fc != cc && foc != cc) RRETURN(MATCH_NOMATCH);
3451            eptr++;
3452          }          }
3453        if (min == max) continue;        if (min == max) continue;
3454        if (minimize)        if (minimize)
3455          {          {
3456          for (fi = min;; fi++)          for (fi = min;; fi++)
3457            {            {
3458              pcre_uchar cc;
3459    
3460            RMATCH(eptr, ecode, offset_top, md, eptrb, RM24);            RMATCH(eptr, ecode, offset_top, md, eptrb, RM24);
3461            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3462            if (fi >= max) RRETURN(MATCH_NOMATCH);            if (fi >= max) RRETURN(MATCH_NOMATCH);
# Line 3311  for (;;) Line 3465  for (;;)
3465              SCHECK_PARTIAL();              SCHECK_PARTIAL();
3466              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
3467              }              }
3468            if (fc != md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH);            cc = RAWUCHARTEST(eptr);
3469              if (fc != cc && foc != cc) RRETURN(MATCH_NOMATCH);
3470              eptr++;
3471            }            }
3472          /* Control never gets here */          /* Control never gets here */
3473          }          }
# Line 3320  for (;;) Line 3476  for (;;)
3476          pp = eptr;          pp = eptr;
3477          for (i = min; i < max; i++)          for (i = min; i < max; i++)
3478            {            {
3479              pcre_uchar cc;
3480    
3481            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
3482              {              {
3483              SCHECK_PARTIAL();              SCHECK_PARTIAL();
3484              break;              break;
3485              }              }
3486            if (fc != md->lcc[*eptr]) break;            cc = RAWUCHARTEST(eptr);
3487              if (fc != cc && foc != cc) break;
3488            eptr++;            eptr++;
3489            }            }
3490    
# Line 3353  for (;;) Line 3512  for (;;)
3512            SCHECK_PARTIAL();            SCHECK_PARTIAL();
3513            RRETURN(MATCH_NOMATCH);            RRETURN(MATCH_NOMATCH);
3514            }            }
3515          if (fc != *eptr++) RRETURN(MATCH_NOMATCH);          if (fc != RAWUCHARINCTEST(eptr)) RRETURN(MATCH_NOMATCH);
3516          }          }
3517    
3518        if (min == max) continue;        if (min == max) continue;
# Line 3370  for (;;) Line 3529  for (;;)
3529              SCHECK_PARTIAL();              SCHECK_PARTIAL();
3530              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
3531              }              }
3532            if (fc != *eptr++) RRETURN(MATCH_NOMATCH);            if (fc != RAWUCHARINCTEST(eptr)) RRETURN(MATCH_NOMATCH);
3533            }            }
3534          /* Control never gets here */          /* Control never gets here */
3535          }          }
# Line 3384  for (;;) Line 3543  for (;;)
3543              SCHECK_PARTIAL();              SCHECK_PARTIAL();
3544              break;              break;
3545              }              }
3546            if (fc != *eptr) break;            if (fc != RAWUCHARTEST(eptr)) break;
3547            eptr++;            eptr++;
3548            }            }
3549          if (possessive) continue;          if (possessive) continue;
# Line 3410  for (;;) Line 3569  for (;;)
3569        SCHECK_PARTIAL();        SCHECK_PARTIAL();
3570        RRETURN(MATCH_NOMATCH);        RRETURN(MATCH_NOMATCH);
3571        }        }
3572      ecode++;  #ifdef SUPPORT_UTF
3573      GETCHARINCTEST(c, eptr);      if (utf)
     if (op == OP_NOTI)         /* The caseless case */  
3574        {        {
3575  #ifdef SUPPORT_UTF8        register pcre_uint32 ch, och;
3576        if (c < 256)  
3577  #endif        ecode++;
3578        c = md->lcc[c];        GETCHARINC(ch, ecode);
3579        if (md->lcc[*ecode++] == c) RRETURN(MATCH_NOMATCH);        GETCHARINC(c, eptr);
3580    
3581          if (op == OP_NOT)
3582            {
3583            if (ch == c) RRETURN(MATCH_NOMATCH);
3584            }
3585          else
3586            {
3587    #ifdef SUPPORT_UCP
3588            if (ch > 127)
3589              och = UCD_OTHERCASE(ch);
3590    #else
3591            if (ch > 127)
3592              och = ch;
3593    #endif /* SUPPORT_UCP */
3594            else
3595              och = TABLE_GET(ch, md->fcc, ch);
3596            if (ch == c || och == c) RRETURN(MATCH_NOMATCH);
3597            }
3598        }        }
3599      else    /* Caseful */      else
3600    #endif
3601        {        {
3602        if (*ecode++ == c) RRETURN(MATCH_NOMATCH);        register pcre_uint32 ch = ecode[1];
3603          c = *eptr++;
3604          if (ch == c || (op == OP_NOTI && TABLE_GET(ch, md->fcc, ch) == c))
3605            RRETURN(MATCH_NOMATCH);
3606          ecode += 2;
3607        }        }
3608      break;      break;
3609    
# Line 3436  for (;;) Line 3617  for (;;)
3617      case OP_NOTEXACT:      case OP_NOTEXACT:
3618      case OP_NOTEXACTI:      case OP_NOTEXACTI:
3619      min = max = GET2(ecode, 1);      min = max = GET2(ecode, 1);
3620      ecode += 3;      ecode += 1 + IMM2_SIZE;
3621      goto REPEATNOTCHAR;      goto REPEATNOTCHAR;
3622    
3623      case OP_NOTUPTO:      case OP_NOTUPTO:
# Line 3446  for (;;) Line 3627  for (;;)
3627      min = 0;      min = 0;
3628      max = GET2(ecode, 1);      max = GET2(ecode, 1);
3629      minimize = *ecode == OP_NOTMINUPTO || *ecode == OP_NOTMINUPTOI;      minimize = *ecode == OP_NOTMINUPTO || *ecode == OP_NOTMINUPTOI;
3630      ecode += 3;      ecode += 1 + IMM2_SIZE;
3631      goto REPEATNOTCHAR;      goto REPEATNOTCHAR;
3632    
3633      case OP_NOTPOSSTAR:      case OP_NOTPOSSTAR:
# Line 3478  for (;;) Line 3659  for (;;)
3659      possessive = TRUE;      possessive = TRUE;
3660      min = 0;      min = 0;
3661      max = GET2(ecode, 1);      max = GET2(ecode, 1);
3662      ecode += 3;      ecode += 1 + IMM2_SIZE;
3663      goto REPEATNOTCHAR;      goto REPEATNOTCHAR;
3664    
3665      case OP_NOTSTAR:      case OP_NOTSTAR:
# Line 3502  for (;;) Line 3683  for (;;)
3683      /* Common code for all repeated single-byte matches. */      /* Common code for all repeated single-byte matches. */
3684    
3685      REPEATNOTCHAR:      REPEATNOTCHAR:
3686      fc = *ecode++;      GETCHARINCTEST(fc, ecode);
3687    
3688      /* The code is duplicated for the caseless and caseful cases, for speed,      /* The code is duplicated for the caseless and caseful cases, for speed,
3689      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 3694  for (;;)
3694      characters and work backwards. */      characters and work backwards. */
3695    
3696      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,
3697        max, eptr));        max, (char *)eptr));
3698    
3699      if (op >= OP_NOTSTARI)     /* Caseless */      if (op >= OP_NOTSTARI)     /* Caseless */
3700        {        {
3701        fc = md->lcc[fc];  #ifdef SUPPORT_UTF
3702    #ifdef SUPPORT_UCP
3703          if (utf && fc > 127)
3704            foc = UCD_OTHERCASE(fc);
3705    #else
3706          if (utf && fc > 127)
3707            foc = fc;
3708    #endif /* SUPPORT_UCP */
3709          else
3710    #endif /* SUPPORT_UTF */
3711            foc = TABLE_GET(fc, md->fcc, fc);
3712    
3713  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3714        /* UTF-8 mode */        if (utf)
       if (utf8)  
3715          {          {
3716          register unsigned int d;          register pcre_uint32 d;
3717          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3718            {            {
3719            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
# Line 3532  for (;;) Line 3722  for (;;)
3722              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
3723              }              }
3724            GETCHARINC(d, eptr);            GETCHARINC(d, eptr);
3725            if (d < 256) d = md->lcc[d];            if (fc == d || (unsigned int)foc == d) RRETURN(MATCH_NOMATCH);
           if (fc == d) RRETURN(MATCH_NOMATCH);  
3726            }            }
3727          }          }
3728        else        else
3729  #endif  #endif
3730          /* Not UTF mode */
       /* Not UTF-8 mode */  
3731          {          {
3732          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3733            {            {
# Line 3548  for (;;) Line 3736  for (;;)
3736              SCHECK_PARTIAL();              SCHECK_PARTIAL();
3737              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
3738              }              }
3739            if (fc == md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH);            if (fc == *eptr || foc == *eptr) RRETURN(MATCH_NOMATCH);
3740              eptr++;
3741            }            }
3742          }          }
3743    
# Line 3556  for (;;) Line 3745  for (;;)
3745    
3746        if (minimize)        if (minimize)
3747          {          {
3748  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3749          /* UTF-8 mode */          if (utf)
         if (utf8)  
3750            {            {
3751            register unsigned int d;            register pcre_uint32 d;
3752            for (fi = min;; fi++)            for (fi = min;; fi++)
3753              {              {
3754              RMATCH(eptr, ecode, offset_top, md, eptrb, RM28);              RMATCH(eptr, ecode, offset_top, md, eptrb, RM28);
# Line 3572  for (;;) Line 3760  for (;;)
3760                RRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
3761                }                }
3762              GETCHARINC(d, eptr);              GETCHARINC(d, eptr);
3763              if (d < 256) d = md->lcc[d];              if (fc == d || (unsigned int)foc == d) RRETURN(MATCH_NOMATCH);
             if (fc == d) RRETURN(MATCH_NOMATCH);  
3764              }              }
3765            }            }
3766          else          else
3767  #endif  #endif
3768          /* Not UTF-8 mode */          /* Not UTF mode */
3769            {            {
3770            for (fi = min;; fi++)            for (fi = min;; fi++)
3771              {              {
# Line 3590  for (;;) Line 3777  for (;;)
3777                SCHECK_PARTIAL();                SCHECK_PARTIAL();
3778                RRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
3779                }                }
3780              if (fc == md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH);              if (fc == *eptr || foc == *eptr) RRETURN(MATCH_NOMATCH);
3781                eptr++;
3782              }              }
3783            }            }
3784          /* Control never gets here */          /* Control never gets here */
# Line 3602  for (;;) Line 3790  for (;;)
3790          {          {
3791          pp = eptr;          pp = eptr;
3792    
3793  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3794          /* UTF-8 mode */          if (utf)
         if (utf8)  
3795            {            {
3796            register unsigned int d;            register pcre_uint32 d;
3797            for (i = min; i < max; i++)            for (i = min; i < max; i++)
3798              {              {
3799              int len = 1;              int len = 1;
# Line 3616  for (;;) Line 3803  for (;;)
3803                break;                break;
3804                }                }
3805              GETCHARLEN(d, eptr, len);              GETCHARLEN(d, eptr, len);
3806              if (d < 256) d = md->lcc[d];              if (fc == d || (unsigned int)foc == d) break;
             if (fc == d) break;  
3807              eptr += len;              eptr += len;
3808              }              }
3809          if (possessive) continue;            if (possessive) continue;
3810          for(;;)            for(;;)
3811              {              {
3812              RMATCH(eptr, ecode, offset_top, md, eptrb, RM30);              RMATCH(eptr, ecode, offset_top, md, eptrb, RM30);
3813              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
# Line 3631  for (;;) Line 3817  for (;;)
3817            }            }
3818          else          else
3819  #endif  #endif
3820          /* Not UTF-8 mode */          /* Not UTF mode */
3821            {            {
3822            for (i = min; i < max; i++)            for (i = min; i < max; i++)
3823              {              {
# Line 3640  for (;;) Line 3826  for (;;)
3826                SCHECK_PARTIAL();                SCHECK_PARTIAL();
3827                break;                break;
3828                }                }
3829              if (fc == md->lcc[*eptr]) break;              if (fc == *eptr || foc == *eptr) break;
3830              eptr++;              eptr++;
3831              }              }
3832            if (possessive) continue;            if (possessive) continue;
# Line 3661  for (;;) Line 3847  for (;;)
3847    
3848      else      else
3849        {        {
3850  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3851        /* UTF-8 mode */        if (utf)
       if (utf8)  
3852          {          {
3853          register unsigned int d;          register pcre_uint32 d;
3854          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3855            {            {
3856            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
# Line 3679  for (;;) Line 3864  for (;;)
3864          }          }
3865        else        else
3866  #endif  #endif
3867        /* Not UTF-8 mode */        /* Not UTF mode */
3868          {          {
3869          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3870            {            {
# Line 3696  for (;;) Line 3881  for (;;)
3881    
3882        if (minimize)        if (minimize)
3883          {          {
3884  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3885          /* UTF-8 mode */          if (utf)
         if (utf8)  
3886            {            {
3887            register unsigned int d;            register pcre_uint32 d;
3888            for (fi = min;; fi++)            for (fi = min;; fi++)
3889              {              {
3890              RMATCH(eptr, ecode, offset_top, md, eptrb, RM32);              RMATCH(eptr, ecode, offset_top, md, eptrb, RM32);
# Line 3717  for (;;) Line 3901  for (;;)
3901            }            }
3902          else          else
3903  #endif  #endif
3904          /* Not UTF-8 mode */          /* Not UTF mode */
3905            {            {
3906            for (fi = min;; fi++)            for (fi = min;; fi++)
3907              {              {
# Line 3741  for (;;) Line 3925  for (;;)
3925          {          {
3926          pp = eptr;          pp = eptr;
3927    
3928  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3929          /* UTF-8 mode */          if (utf)
         if (utf8)  
3930            {            {
3931            register unsigned int d;            register pcre_uint32 d;
3932            for (i = min; i < max; i++)            for (i = min; i < max; i++)
3933              {              {
3934              int len = 1;              int len = 1;
# Line 3769  for (;;) Line 3952  for (;;)
3952            }            }
3953          else          else
3954  #endif  #endif
3955          /* Not UTF-8 mode */          /* Not UTF mode */
3956            {            {
3957            for (i = min; i < max; i++)            for (i = min; i < max; i++)
3958              {              {
# Line 3802  for (;;) Line 3985  for (;;)
3985      case OP_TYPEEXACT:      case OP_TYPEEXACT:
3986      min = max = GET2(ecode, 1);      min = max = GET2(ecode, 1);
3987      minimize = TRUE;      minimize = TRUE;
3988      ecode += 3;      ecode += 1 + IMM2_SIZE;
3989      goto REPEATTYPE;      goto REPEATTYPE;
3990    
3991      case OP_TYPEUPTO:      case OP_TYPEUPTO:
# Line 3810  for (;;) Line 3993  for (;;)
3993      min = 0;      min = 0;
3994      max = GET2(ecode, 1);      max = GET2(ecode, 1);
3995      minimize = *ecode == OP_TYPEMINUPTO;      minimize = *ecode == OP_TYPEMINUPTO;
3996      ecode += 3;      ecode += 1 + IMM2_SIZE;
3997      goto REPEATTYPE;      goto REPEATTYPE;
3998    
3999      case OP_TYPEPOSSTAR:      case OP_TYPEPOSSTAR:
# Line 3838  for (;;) Line 4021  for (;;)
4021      possessive = TRUE;      possessive = TRUE;
4022      min = 0;      min = 0;
4023      max = GET2(ecode, 1);      max = GET2(ecode, 1);
4024      ecode += 3;      ecode += 1 + IMM2_SIZE;
4025      goto REPEATTYPE;      goto REPEATTYPE;
4026    
4027      case OP_TYPESTAR:      case OP_TYPESTAR:
# Line 4020  for (;;) Line 4203  for (;;)
4203                RRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4204              }              }
4205            break;            break;
4206    
4207              case PT_CLIST:
4208              for (i = 1; i <= min; i++)
4209                {
4210                const pcre_uint32 *cp;
4211                if (eptr >= md->end_subject)
4212                  {
4213                  SCHECK_PARTIAL();
4214                  RRETURN(MATCH_NOMATCH);
4215                  }
4216                GETCHARINCTEST(c, eptr);
4217                cp = PRIV(ucd_caseless_sets) + UCD_CASESET(c);
4218                for (;;)
4219                  {
4220                  if (c < *cp)
4221                    { if (prop_fail_result) break; else { RRETURN(MATCH_NOMATCH); } }
4222                  if (c == *cp++)
4223                    { if (prop_fail_result) { RRETURN(MATCH_NOMATCH); } else break; }
4224                  }
4225                }
4226              break;
4227    
4228            /* This should not occur */            /* This should not occur */
4229    
4230            default:            default:
# Line 4040  for (;;) Line 4244  for (;;)
4244              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4245              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4246              }              }
4247            GETCHARINCTEST(c, eptr);            else
           if (UCD_CATEGORY(c) == ucp_M) RRETURN(MATCH_NOMATCH);  
           while (eptr < md->end_subject)  
4248              {              {
4249              int len = 1;              int lgb, rgb;
4250              if (!utf8) c = *eptr; else { GETCHARLEN(c, eptr, len); }              GETCHARINCTEST(c, eptr);
4251              if (UCD_CATEGORY(c) != ucp_M) break;              lgb = UCD_GRAPHBREAK(c);
4252              eptr += len;             while (eptr < md->end_subject)
4253                  {
4254                  int len = 1;
4255                  if (!utf) c = *eptr; else { GETCHARLEN(c, eptr, len); }
4256                  rgb = UCD_GRAPHBREAK(c);
4257                  if ((PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0) break;
4258                  lgb = rgb;
4259                  eptr += len;
4260                  }
4261              }              }
4262              CHECK_PARTIAL();
4263            }            }
4264          }          }
4265    
# Line 4057  for (;;) Line 4268  for (;;)
4268    
4269  /* Handle all other cases when the coding is UTF-8 */  /* Handle all other cases when the coding is UTF-8 */
4270    
4271  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
4272        if (utf8) switch(ctype)        if (utf) switch(ctype)
4273          {          {
4274          case OP_ANY:          case OP_ANY:
4275          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
# Line 4069  for (;;) Line 4280  for (;;)
4280              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4281              }              }
4282            if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH);            if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH);
4283              if (md->partial != 0 &&
4284                  eptr + 1 >= md->end_subject &&
4285                  NLBLOCK->nltype == NLTYPE_FIXED &&
4286                  NLBLOCK->nllen == 2 &&
4287                  RAWUCHAR(eptr) == NLBLOCK->nl[0])
4288                {
4289                md->hitend = TRUE;
4290                if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
4291                }
4292            eptr++;            eptr++;
4293            while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;            ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
4294            }            }
4295          break;          break;
4296    
# Line 4083  for (;;) Line 4303  for (;;)
4303              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4304              }              }
4305            eptr++;            eptr++;
4306            while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;            ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
4307            }            }
4308          break;          break;
4309    
# Line 4105  for (;;) Line 4325  for (;;)
4325              {              {
4326              default: RRETURN(MATCH_NOMATCH);              default: RRETURN(MATCH_NOMATCH);
4327    
4328              case 0x000d:              case CHAR_CR:
4329              if (eptr < md->end_subject && *eptr == 0x0a) eptr++;              if (eptr < md->end_subject && RAWUCHAR(eptr) == CHAR_LF) eptr++;
4330              break;              break;
4331    
4332              case 0x000a:              case CHAR_LF:
4333              break;              break;
4334    
4335              case 0x000b:              case CHAR_VT:
4336              case 0x000c:              case CHAR_FF:
4337              case 0x0085:              case CHAR_NEL:
4338    #ifndef EBCDIC
4339              case 0x2028:              case 0x2028:
4340              case 0x2029:              case 0x2029:
4341    #endif  /* Not EBCDIC */
4342              if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH);              if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH);
4343              break;              break;
4344              }              }
# Line 4134  for (;;) Line 4356  for (;;)
4356            GETCHARINC(c, eptr);            GETCHARINC(c, eptr);
4357            switch(c)            switch(c)
4358              {              {
4359                HSPACE_CASES: RRETURN(MATCH_NOMATCH);  /* Byte and multibyte cases */
4360              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);  
4361              }              }
4362            }            }
4363          break;          break;
# Line 4170  for (;;) Line 4373  for (;;)
4373            GETCHARINC(c, eptr);            GETCHARINC(c, eptr);
4374            switch(c)            switch(c)
4375              {              {
4376                HSPACE_CASES: break;  /* Byte and multibyte cases */
4377              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;  
4378              }              }
4379            }            }
4380          break;          break;
# Line 4206  for (;;) Line 4390  for (;;)
4390            GETCHARINC(c, eptr);            GETCHARINC(c, eptr);
4391            switch(c)            switch(c)
4392              {              {
4393                VSPACE_CASES: RRETURN(MATCH_NOMATCH);
4394              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);  
4395              }              }
4396            }            }
4397          break;          break;
# Line 4230  for (;;) Line 4407  for (;;)
4407            GETCHARINC(c, eptr);            GETCHARINC(c, eptr);
4408            switch(c)            switch(c)
4409              {              {
4410                VSPACE_CASES: break;
4411              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;  
4412              }              }
4413            }            }
4414          break;          break;
# Line 4260  for (;;) Line 4430  for (;;)
4430          case OP_DIGIT:          case OP_DIGIT:
4431          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
4432            {            {
4433              pcre_uchar cc;
4434    
4435            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4436              {              {
4437              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4438              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4439              }              }
4440            if (*eptr >= 128 || (md->ctypes[*eptr++] & ctype_digit) == 0)            cc = RAWUCHAR(eptr);
4441              if (cc >= 128 || (md->ctypes[cc] & ctype_digit) == 0)
4442              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4443              eptr++;
4444            /* 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 */
4445            }            }
4446          break;          break;
# Line 4274  for (;;) Line 4448  for (;;)
4448          case OP_NOT_WHITESPACE:          case OP_NOT_WHITESPACE:
4449          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
4450            {            {
4451              pcre_uchar cc;
4452    
4453            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4454              {              {
4455              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4456              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4457              }              }
4458            if (*eptr < 128 && (md->ctypes[*eptr] & ctype_space) != 0)            cc = RAWUCHAR(eptr);
4459              if (cc < 128 && (md->ctypes[cc] & ctype_space) != 0)
4460              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4461            while (++eptr < md->end_subject && (*eptr & 0xc0) == 0x80);            eptr++;
4462              ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
4463            }            }
4464          break;          break;
4465    
4466          case OP_WHITESPACE:          case OP_WHITESPACE:
4467          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
4468            {            {
4469              pcre_uchar cc;
4470    
4471            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4472              {              {
4473              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4474              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4475              }              }
4476            if (*eptr >= 128 || (md->ctypes[*eptr++] & ctype_space) == 0)            cc = RAWUCHAR(eptr);
4477              if (cc >= 128 || (md->ctypes[cc] & ctype_space) == 0)
4478              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4479              eptr++;
4480            /* 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 */
4481            }            }
4482          break;          break;
# Line 4302  for (;;) Line 4484  for (;;)
4484          case OP_NOT_WORDCHAR:          case OP_NOT_WORDCHAR:
4485          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
4486            {            {
4487              pcre_uchar cc;
4488    
4489            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4490              {              {
4491              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4492              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4493              }              }
4494            if (*eptr < 128 && (md->ctypes[*eptr] & ctype_word) != 0)            cc = RAWUCHAR(eptr);
4495              if (cc < 128 && (md->ctypes[cc] & ctype_word) != 0)
4496              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4497            while (++eptr < md->end_subject && (*eptr & 0xc0) == 0x80);            eptr++;
4498              ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
4499            }            }
4500          break;          break;
4501    
4502          case OP_WORDCHAR:          case OP_WORDCHAR:
4503          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
4504            {            {
4505              pcre_uchar cc;
4506    
4507            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4508              {              {
4509              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4510              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4511              }              }
4512            if (*eptr >= 128 || (md->ctypes[*eptr++] & ctype_word) == 0)            cc = RAWUCHAR(eptr);
4513              if (cc >= 128 || (md->ctypes[cc] & ctype_word) == 0)
4514              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4515              eptr++;
4516            /* 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 */
4517            }            }
4518          break;          break;
# Line 4332  for (;;) Line 4522  for (;;)
4522          }  /* End switch(ctype) */          }  /* End switch(ctype) */
4523    
4524        else        else
4525  #endif     /* SUPPORT_UTF8 */  #endif     /* SUPPORT_UTF */
4526    
4527        /* 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
4528        than OP_PROP and OP_NOTPROP. */        than OP_PROP and OP_NOTPROP. */
# Line 4348  for (;;) Line 4538  for (;;)
4538              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4539              }              }
4540            if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH);            if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH);
4541              if (md->partial != 0 &&
4542                  eptr + 1 >= md->end_subject &&
4543                  NLBLOCK->nltype == NLTYPE_FIXED &&
4544                  NLBLOCK->nllen == 2 &&
4545                  *eptr == NLBLOCK->nl[0])
4546                {
4547                md->hitend = TRUE;
4548                if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
4549                }
4550            eptr++;            eptr++;
4551            }            }
4552          break;          break;
# Line 4382  for (;;) Line 4581  for (;;)
4581              {              {
4582              default: RRETURN(MATCH_NOMATCH);              default: RRETURN(MATCH_NOMATCH);
4583    
4584              case 0x000d:              case CHAR_CR:
4585              if (eptr < md->end_subject && *eptr == 0x0a) eptr++;              if (eptr < md->end_subject && *eptr == CHAR_LF) eptr++;
4586              break;              break;
4587    
4588              case 0x000a:              case CHAR_LF:
4589              break;              break;
4590    
4591              case 0x000b:              case CHAR_VT:
4592              case 0x000c:              case CHAR_FF:
4593              case 0x0085:              case CHAR_NEL:
4594    #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
4595                case 0x2028:
4596                case 0x2029:
4597    #endif
4598              if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH);              if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH);
4599              break;              break;
4600              }              }
# Line 4409  for (;;) Line 4612  for (;;)
4612            switch(*eptr++)            switch(*eptr++)
4613              {              {
4614              default: break;              default: break;
4615              case 0x09:      /* HT */              HSPACE_BYTE_CASES:
4616              case 0x20:      /* SPACE */  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
4617              case 0xa0:      /* NBSP */              HSPACE_MULTIBYTE_CASES:
4618    #endif
4619              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4620              }              }
4621            }            }
# Line 4428  for (;;) Line 4632  for (;;)
4632            switch(*eptr++)            switch(*eptr++)
4633              {              {
4634              default: RRETURN(MATCH_NOMATCH);              default: RRETURN(MATCH_NOMATCH);
4635              case 0x09:      /* HT */              HSPACE_BYTE_CASES:
4636              case 0x20:      /* SPACE */  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
4637              case 0xa0:      /* NBSP */              HSPACE_MULTIBYTE_CASES:
4638    #endif
4639              break;              break;
4640              }              }
4641            }            }
# Line 4446  for (;;) Line 4651  for (;;)
4651              }              }
4652            switch(*eptr++)            switch(*eptr++)
4653              {              {
4654              default: break;              VSPACE_BYTE_CASES:
4655              case 0x0a:      /* LF */  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
4656              case 0x0b:      /* VT */              VSPACE_MULTIBYTE_CASES:
4657              case 0x0c:      /* FF */  #endif
             case 0x0d:      /* CR */  
             case 0x85:      /* NEL */  
4658              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4659                default: break;
4660              }              }
4661            }            }
4662          break;          break;
# Line 4468  for (;;) Line 4672  for (;;)
4672            switch(*eptr++)            switch(*eptr++)
4673              {              {
4674              default: RRETURN(MATCH_NOMATCH);              default: RRETURN(MATCH_NOMATCH);
4675              case 0x0a:      /* LF */              VSPACE_BYTE_CASES:
4676              case 0x0b:      /* VT */  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
4677              case 0x0c:      /* FF */              VSPACE_MULTIBYTE_CASES:
4678              case 0x0d:      /* CR */  #endif
             case 0x85:      /* NEL */  
4679              break;              break;
4680              }              }
4681            }            }
# Line 4486  for (;;) Line 4689  for (;;)
4689              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4690              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4691              }              }
4692            if ((md->ctypes[*eptr++] & ctype_digit) != 0) RRETURN(MATCH_NOMATCH);            if (MAX_255(*eptr) && (md->ctypes[*eptr] & ctype_digit) != 0)
4693                RRETURN(MATCH_NOMATCH);
4694              eptr++;
4695            }            }
4696          break;          break;
4697    
# Line 4498  for (;;) Line 4703  for (;;)
4703              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4704              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4705              }              }
4706            if ((md->ctypes[*eptr++] & ctype_digit) == 0) RRETURN(MATCH_NOMATCH);            if (!MAX_255(*eptr) || (md->ctypes[*eptr] & ctype_digit) == 0)
4707                RRETURN(MATCH_NOMATCH);
4708              eptr++;
4709            }            }
4710          break;          break;
4711    
# Line 4510  for (;;) Line 4717  for (;;)
4717              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4718              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4719              }              }
4720            if ((md->ctypes[*eptr++] & ctype_space) != 0) RRETURN(MATCH_NOMATCH);            if (MAX_255(*eptr) && (md->ctypes[*eptr] & ctype_space) != 0)
4721                RRETURN(MATCH_NOMATCH);
4722              eptr++;
4723            }            }
4724          break;          break;
4725    
# Line 4522  for (;;) Line 4731  for (;;)
4731              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4732              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4733              }              }
4734            if ((md->ctypes[*eptr++] & ctype_space) == 0) RRETURN(MATCH_NOMATCH);            if (!MAX_255(*eptr) || (md->ctypes[*eptr] & ctype_space) == 0)
4735                RRETURN(MATCH_NOMATCH);
4736              eptr++;
4737            }            }
4738          break;          break;
4739    
# Line 4534  for (;;) Line 4745  for (;;)
4745              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4746              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4747              }              }
4748            if ((md->ctypes[*eptr++] & ctype_word) != 0)            if (MAX_255(*eptr) && (md->ctypes[*eptr] & ctype_word) != 0)
4749              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4750              eptr++;
4751            }            }
4752          break;          break;
4753    
# Line 4547  for (;;) Line 4759  for (;;)
4759              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4760              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4761              }              }
4762            if ((md->ctypes[*eptr++] & ctype_word) == 0)            if (!MAX_255(*eptr) || (md->ctypes[*eptr] & ctype_word) == 0)
4763              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4764              eptr++;
4765            }            }
4766          break;          break;
4767    
# Line 4739  for (;;) Line 4952  for (;;)
4952              }              }
4953            /* Control never gets here */            /* Control never gets here */
4954    
4955            /* This should never occur */            case PT_CLIST:
4956              for (fi = min;; fi++)
4957                {
4958                const pcre_uint32 *cp;
4959                RMATCH(eptr, ecode, offset_top, md, eptrb, RM67);
4960                if (rrc != MATCH_NOMATCH) RRETURN(rrc);
4961                if (fi >= max) RRETURN(MATCH_NOMATCH);
4962                if (eptr >= md->end_subject)
4963                  {
4964                  SCHECK_PARTIAL();
4965                  RRETURN(MATCH_NOMATCH);
4966                  }
4967                GETCHARINCTEST(c, eptr);
4968                cp = PRIV(ucd_caseless_sets) + UCD_CASESET(c);
4969                for (;;)
4970                  {
4971                  if (c < *cp)
4972                    { if (prop_fail_result) break; else { RRETURN(MATCH_NOMATCH); } }
4973                  if (c == *cp++)
4974                    { if (prop_fail_result) { RRETURN(MATCH_NOMATCH); } else break; }
4975                  }
4976                }
4977              /* Control never gets here */
4978    
4979              /* This should never occur */
4980            default:            default:
4981            RRETURN(PCRE_ERROR_INTERNAL);            RRETURN(PCRE_ERROR_INTERNAL);
4982            }            }
# Line 4761  for (;;) Line 4997  for (;;)
4997              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4998              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4999              }              }
5000            GETCHARINCTEST(c, eptr);            else
           if (UCD_CATEGORY(c) == ucp_M) RRETURN(MATCH_NOMATCH);  
           while (eptr < md->end_subject)  
5001              {              {
5002              int len = 1;              int lgb, rgb;
5003              if (!utf8) c = *eptr; else { GETCHARLEN(c, eptr, len); }              GETCHARINCTEST(c, eptr);
5004              if (UCD_CATEGORY(c) != ucp_M) break;              lgb = UCD_GRAPHBREAK(c);
5005              eptr += len;              while (eptr < md->end_subject)
5006                  {
5007                  int len = 1;
5008                  if (!utf) c = *eptr; else { GETCHARLEN(c, eptr, len); }
5009                  rgb = UCD_GRAPHBREAK(c);
5010                  if ((PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0) break;
5011                  lgb = rgb;
5012                  eptr += len;
5013                  }
5014              }              }
5015              CHECK_PARTIAL();
5016            }            }
5017          }          }
5018        else        else
5019  #endif     /* SUPPORT_UCP */  #endif     /* SUPPORT_UCP */
5020    
5021  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
5022        /* UTF-8 mode */        if (utf)
       if (utf8)  
5023          {          {
5024          for (fi = min;; fi++)          for (fi = min;; fi++)
5025            {            {
# Line 4794  for (;;) Line 5036  for (;;)
5036            GETCHARINC(c, eptr);            GETCHARINC(c, eptr);
5037            switch(ctype)            switch(ctype)
5038              {              {
5039              case OP_ANY:        /* This is the non-NL case */              case OP_ANY:               /* This is the non-NL case */
5040                if (md->partial != 0 &&    /* Take care with CRLF partial */
5041                    eptr >= md->end_subject &&
5042                    NLBLOCK->nltype == NLTYPE_FIXED &&
5043                    NLBLOCK->nllen == 2 &&
5044                    c == NLBLOCK->nl[0])
5045                  {
5046                  md->hitend = TRUE;
5047                  if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
5048                  }
5049                break;
5050    
5051              case OP_ALLANY:              case OP_ALLANY:
5052              case OP_ANYBYTE:              case OP_ANYBYTE:
5053              break;              break;
# Line 4803  for (;;) Line 5056  for (;;)
5056              switch(c)              switch(c)
5057                {                {
5058                default: RRETURN(MATCH_NOMATCH);                default: RRETURN(MATCH_NOMATCH);
5059                case 0x000d:                case CHAR_CR:
5060                if (eptr < md->end_subject && *eptr == 0x0a) eptr++;                if (eptr < md->end_subject && RAWUCHAR(eptr) == CHAR_LF) eptr++;
5061                break;                break;
5062                case 0x000a:  
5063                  case CHAR_LF:
5064                break;                break;
5065    
5066                case 0x000b:                case CHAR_VT:
5067                case 0x000c:                case CHAR_FF:
5068                case 0x0085:                case CHAR_NEL:
5069    #ifndef EBCDIC
5070                case 0x2028:                case 0x2028:
5071                case 0x2029:                case 0x2029:
5072    #endif  /* Not EBCDIC */
5073                if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH);                if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH);
5074                break;                break;
5075                }                }
# Line 4822  for (;;) Line 5078  for (;;)
5078              case OP_NOT_HSPACE:              case OP_NOT_HSPACE:
5079              switch(c)              switch(c)
5080                {                {
5081                  HSPACE_CASES: RRETURN(MATCH_NOMATCH);
5082                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);  
5083                }                }
5084              break;              break;
5085    
5086              case OP_HSPACE:              case OP_HSPACE:
5087              switch(c)              switch(c)
5088                {                {
5089                  HSPACE_CASES: break;
5090                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;  
5091                }                }
5092              break;              break;
5093    
5094              case OP_NOT_VSPACE:              case OP_NOT_VSPACE:
5095              switch(c)              switch(c)
5096                {                {
5097                  VSPACE_CASES: RRETURN(MATCH_NOMATCH);
5098                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);  
5099                }                }
5100              break;              break;
5101    
5102              case OP_VSPACE:              case OP_VSPACE:
5103              switch(c)              switch(c)
5104                {                {
5105                  VSPACE_CASES: break;
5106                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;  
5107                }                }
5108              break;              break;
5109    
# Line 4919  for (;;) Line 5123  for (;;)
5123              break;              break;
5124    
5125              case OP_WHITESPACE:              case OP_WHITESPACE:
5126              if  (c >= 256 || (md->ctypes[c] & ctype_space) == 0)              if (c >= 256 || (md->ctypes[c] & ctype_space) == 0)
5127                RRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
5128              break;              break;
5129    
# Line 4940  for (;;) Line 5144  for (;;)
5144          }          }
5145        else        else
5146  #endif  #endif
5147        /* Not UTF-8 mode */        /* Not UTF mode */
5148          {          {
5149          for (fi = min;; fi++)          for (fi = min;; fi++)
5150            {            {
# Line 4957  for (;;) Line 5161  for (;;)
5161            c = *eptr++;            c = *eptr++;
5162            switch(ctype)            switch(ctype)
5163              {              {
5164              case OP_ANY:     /* This is the non-NL case */              case OP_ANY:               /* This is the non-NL case */
5165                if (md->partial != 0 &&    /* Take care with CRLF partial */
5166                    eptr >= md->end_subject &&
5167                    NLBLOCK->nltype == NLTYPE_FIXED &&
5168                    NLBLOCK->nllen == 2 &&
5169                    c == NLBLOCK->nl[0])
5170                  {
5171                  md->hitend = TRUE;
5172                  if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
5173                  }
5174                break;
5175    
5176              case OP_ALLANY:              case OP_ALLANY:
5177              case OP_ANYBYTE:              case OP_ANYBYTE:
5178              break;              break;
# Line 4966  for (;;) Line 5181  for (;;)
5181              switch(c)              switch(c)
5182                {                {
5183                default: RRETURN(MATCH_NOMATCH);                default: RRETURN(MATCH_NOMATCH);
5184                case 0x000d:                case CHAR_CR:
5185                if (eptr < md->end_subject && *eptr == 0x0a) eptr++;                if (eptr < md->end_subject && *eptr == CHAR_LF) eptr++;
5186                break;                break;
5187    
5188                case 0x000a:                case CHAR_LF:
5189                break;                break;
5190    
5191                case 0x000b:                case CHAR_VT:
5192                case 0x000c:                case CHAR_FF:
5193                case 0x0085:                case CHAR_NEL:
5194    #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
5195                  case 0x2028:
5196                  case 0x2029:
5197    #endif
5198                if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH);                if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH);
5199                break;                break;
5200                }                }
# Line 4985  for (;;) Line 5204  for (;;)
5204              switch(c)              switch(c)
5205                {                {
5206                default: break;                default: break;
5207                case 0x09:      /* HT */                HSPACE_BYTE_CASES:
5208                case 0x20:      /* SPACE */  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
5209                case 0xa0:      /* NBSP */                HSPACE_MULTIBYTE_CASES:
5210    #endif
5211                RRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
5212                }                }
5213              break;              break;
# Line 4996  for (;;) Line 5216  for (;;)
5216              switch(c)              switch(c)
5217                {                {
5218                default: RRETURN(MATCH_NOMATCH);                default: RRETURN(MATCH_NOMATCH);
5219                case 0x09:      /* HT */                HSPACE_BYTE_CASES:
5220                case 0x20:      /* SPACE */  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
5221                case 0xa0:      /* NBSP */                HSPACE_MULTIBYTE_CASES:
5222    #endif
5223                break;                break;
5224                }                }
5225              break;              break;
# Line 5007  for (;;) Line 5228  for (;;)
5228              switch(c)              switch(c)
5229                {                {
5230                default: break;                default: break;
5231                case 0x0a:      /* LF */                VSPACE_BYTE_CASES:
5232                case 0x0b:      /* VT */  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
5233                case 0x0c:      /* FF */                VSPACE_MULTIBYTE_CASES:
5234                case 0x0d:      /* CR */  #endif
               case 0x85:      /* NEL */  
5235                RRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
5236                }                }
5237              break;              break;
# Line 5020  for (;;) Line 5240  for (;;)
5240              switch(c)              switch(c)
5241                {                {
5242                default: RRETURN(MATCH_NOMATCH);                default: RRETURN(MATCH_NOMATCH);
5243                case 0x0a:      /* LF */                VSPACE_BYTE_CASES:
5244                case 0x0b:      /* VT */  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
5245                case 0x0c:      /* FF */                VSPACE_MULTIBYTE_CASES:
5246                case 0x0d:      /* CR */  #endif
               case 0x85:      /* NEL */  
5247                break;                break;
5248                }                }
5249              break;              break;
5250    
5251              case OP_NOT_DIGIT:              case OP_NOT_DIGIT:
5252              if ((md->ctypes[c] & ctype_digit) != 0) RRETURN(MATCH_NOMATCH);              if (MAX_255(c) && (md->ctypes[c] & ctype_digit) != 0) RRETURN(MATCH_NOMATCH);
5253              break;              break;
5254    
5255              case OP_DIGIT:              case OP_DIGIT:
5256              if ((md->ctypes[c] & ctype_digit) == 0) RRETURN(MATCH_NOMATCH);              if (!MAX_255(c) || (md->ctypes[c] & ctype_digit) == 0) RRETURN(MATCH_NOMATCH);
5257              break;              break;
5258    
5259              case OP_NOT_WHITESPACE:              case OP_NOT_WHITESPACE:
5260              if ((md->ctypes[c] & ctype_space) != 0) RRETURN(MATCH_NOMATCH);              if (MAX_255(c) && (md->ctypes[c] & ctype_space) != 0) RRETURN(MATCH_NOMATCH);
5261              break;              break;
5262    
5263              case OP_WHITESPACE:              case OP_WHITESPACE:
5264              if  ((md->ctypes[c] & ctype_space) == 0) RRETURN(MATCH_NOMATCH);              if (!MAX_255(c) || (md->ctypes[c] & ctype_space) == 0) RRETURN(MATCH_NOMATCH);
5265              break;              break;
5266    
5267              case OP_NOT_WORDCHAR:              case OP_NOT_WORDCHAR:
5268              if ((md->ctypes[c] & ctype_word) != 0) RRETURN(MATCH_NOMATCH);              if (MAX_255(c) && (md->ctypes[c] & ctype_word) != 0) RRETURN(MATCH_NOMATCH);
5269              break;              break;
5270    
5271              case OP_WORDCHAR:              case OP_WORDCHAR:
5272              if ((md->ctypes[c] & ctype_word) == 0) RRETURN(MATCH_NOMATCH);              if (!MAX_255(c) || (md->ctypes[c] & ctype_word) == 0) RRETURN(MATCH_NOMATCH);
5273              break;              break;
5274    
5275              default:              default:
# Line 5226  for (;;) Line 5445  for (;;)
5445              eptr+= len;              eptr+= len;
5446              }              }
5447            break;            break;
5448    
5449              case PT_CLIST:
5450              for (i = min; i < max; i++)
5451                {
5452                const pcre_uint32 *cp;
5453                int len = 1;
5454                if (eptr >= md->end_subject)
5455                  {
5456                  SCHECK_PARTIAL();
5457                  break;
5458                  }
5459                GETCHARLENTEST(c, eptr, len);
5460                cp = PRIV(ucd_caseless_sets) + UCD_CASESET(c);
5461                for (;;)
5462                  {
5463                  if (c < *cp)
5464                    { if (prop_fail_result) break; else goto GOT_MAX; }
5465                  if (c == *cp++)
5466                    { if (prop_fail_result) goto GOT_MAX; else break; }
5467                  }
5468                eptr += len;
5469                }
5470              GOT_MAX:
5471              break;
5472    
5473            default:            default:
5474            RRETURN(PCRE_ERROR_INTERNAL);            RRETURN(PCRE_ERROR_INTERNAL);
# Line 5239  for (;;) Line 5482  for (;;)
5482            RMATCH(eptr, ecode, offset_top, md, eptrb, RM44);            RMATCH(eptr, ecode, offset_top, md, eptrb, RM44);
5483            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
5484            if (eptr-- == pp) break;        /* Stop if tried at original pos */            if (eptr-- == pp) break;        /* Stop if tried at original pos */
5485            if (utf8) BACKCHAR(eptr);            if (utf) BACKCHAR(eptr);
5486            }            }
5487          }          }
5488    
# Line 5250  for (;;) Line 5493  for (;;)
5493          {          {
5494          for (i = min; i < max; i++)          for (i = min; i < max; i++)
5495            {            {
           int len = 1;  
5496            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
5497              {              {
5498              SCHECK_PARTIAL();              SCHECK_PARTIAL();
5499              break;              break;
5500              }              }
5501            if (!utf8) c = *eptr; else { GETCHARLEN(c, eptr, len); }            else
           if (UCD_CATEGORY(c) == ucp_M) break;  
           eptr += len;  
           while (eptr < md->end_subject)  
5502              {              {
5503              len = 1;              int lgb, rgb;
5504              if (!utf8) c = *eptr; else { GETCHARLEN(c, eptr, len); }              GETCHARINCTEST(c, eptr);
5505              if (UCD_CATEGORY(c) != ucp_M) break;              lgb = UCD_GRAPHBREAK(c);
5506              eptr += len;              while (eptr < md->end_subject)
5507                  {
5508                  int len = 1;
5509                  if (!utf) c = *eptr; else { GETCHARLEN(c, eptr, len); }
5510                  rgb = UCD_GRAPHBREAK(c);
5511                  if ((PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0) break;
5512                  lgb = rgb;
5513                  eptr += len;
5514                  }
5515              }              }
5516              CHECK_PARTIAL();
5517            }            }
5518    
5519          /* eptr is now past the end of the maximum run */          /* eptr is now past the end of the maximum run */
# Line 5279  for (;;) Line 5527  for (;;)
5527            if (eptr-- == pp) break;        /* Stop if tried at original pos */            if (eptr-- == pp) break;        /* Stop if tried at original pos */
5528            for (;;)                        /* Move back over one extended */            for (;;)                        /* Move back over one extended */
5529              {              {
5530              if (!utf8) c = *eptr; else              if (!utf) c = *eptr; else
5531                {                {
5532                BACKCHAR(eptr);                BACKCHAR(eptr);
5533                GETCHAR(c, eptr);                GETCHAR(c, eptr);
# Line 5293  for (;;) Line 5541  for (;;)
5541        else        else
5542  #endif   /* SUPPORT_UCP */  #endif   /* SUPPORT_UCP */
5543    
5544  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
5545        /* UTF-8 mode */        if (utf)
   
       if (utf8)  
5546          {          {
5547          switch(ctype)          switch(ctype)
5548            {            {
# Line 5311  for (;;) Line 5557  for (;;)
5557                  break;                  break;
5558                  }                  }
5559                if (IS_NEWLINE(eptr)) break;                if (IS_NEWLINE(eptr)) break;
5560                  if (md->partial != 0 &&    /* Take care with CRLF partial */
5561                      eptr + 1 >= md->end_subject &&
5562                      NLBLOCK->nltype == NLTYPE_FIXED &&
5563                      NLBLOCK->nllen == 2 &&
5564                      RAWUCHAR(eptr) == NLBLOCK->nl[0])
5565                    {
5566                    md->hitend = TRUE;
5567                    if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
5568                    }
5569                eptr++;                eptr++;
5570                while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;                ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
5571                }                }
5572              }              }
5573    
# Line 5328  for (;;) Line 5583  for (;;)
5583                  break;                  break;
5584                  }                  }
5585                if (IS_NEWLINE(eptr)) break;                if (IS_NEWLINE(eptr)) break;
5586                  if (md->partial != 0 &&    /* Take care with CRLF partial */
5587                      eptr + 1 >= md->end_subject &&
5588                      NLBLOCK->nltype == NLTYPE_FIXED &&
5589                      NLBLOCK->nllen == 2 &&
5590                      RAWUCHAR(eptr) == NLBLOCK->nl[0])
5591                    {
5592                    md->hitend = TRUE;
5593                    if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
5594                    }
5595                eptr++;                eptr++;
5596                while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;                ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
5597                }                }
5598              }              }
5599            break;            break;
# Line 5345  for (;;) Line 5609  for (;;)
5609                  break;                  break;
5610                  }                  }
5611                eptr++;                eptr++;
5612                while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;                ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
5613                }                }
5614              }              }
5615            else            else
# Line 5377  for (;;) Line 5641  for (;;)
5641                break;                break;
5642                }                }
5643              GETCHARLEN(c, eptr, len);              GETCHARLEN(c, eptr, len);
5644              if (c == 0x000d)              if (c == CHAR_CR)
5645                {                {
5646                if (++eptr >= md->end_subject) break;                if (++eptr >= md->end_subject) break;
5647                if (*eptr == 0x000a) eptr++;                if (RAWUCHAR(eptr) == CHAR_LF) eptr++;
5648                }                }
5649              else              else
5650                {                {
5651                if (c != 0x000a &&                if (c != CHAR_LF &&
5652                    (md->bsr_anycrlf ||                    (md->bsr_anycrlf ||
5653                     (c != 0x000b && c != 0x000c &&                     (c != CHAR_VT && c != CHAR_FF && c != CHAR_NEL
5654                      c != 0x0085 && c != 0x2028 && c != 0x2029)))  #ifndef EBCDIC
5655                        && c != 0x2028 && c != 0x2029
5656    #endif  /* Not EBCDIC */
5657                        )))
5658                  break;                  break;
5659                eptr += len;                eptr += len;
5660                }                }
# Line 5408  for (;;) Line 5675  for (;;)
5675              GETCHARLEN(c, eptr, len);              GETCHARLEN(c, eptr, len);
5676              switch(c)              switch(c)
5677                {                {
5678                  HSPACE_CASES: gotspace = TRUE; break;
5679                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;  
5680                }                }
5681              if (gotspace == (ctype == OP_NOT_HSPACE)) break;              if (gotspace == (ctype == OP_NOT_HSPACE)) break;
5682              eptr += len;              eptr += len;
# Line 5450  for (;;) Line 5697  for (;;)
5697              GETCHARLEN(c, eptr, len);              GETCHARLEN(c, eptr, len);
5698              switch(c)              switch(c)
5699                {                {
5700                  VSPACE_CASES: gotspace = TRUE; break;
5701                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;  
5702                }                }
5703              if (gotspace == (ctype == OP_NOT_VSPACE)) break;              if (gotspace == (ctype == OP_NOT_VSPACE)) break;
5704              eptr += len;              eptr += len;
# Line 5573  for (;;) Line 5812  for (;;)
5812            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
5813            if (eptr-- == pp) break;        /* Stop if tried at original pos */            if (eptr-- == pp) break;        /* Stop if tried at original pos */
5814            BACKCHAR(eptr);            BACKCHAR(eptr);
5815            if (ctype == OP_ANYNL && eptr > pp  && *eptr == '\n' &&            if (ctype == OP_ANYNL && eptr > pp  && RAWUCHAR(eptr) == CHAR_NL &&
5816                eptr[-1] == '\r') eptr--;                RAWUCHAR(eptr - 1) == CHAR_CR) eptr--;
5817            }            }
5818          }          }
5819        else        else
5820  #endif  /* SUPPORT_UTF8 */  #endif  /* SUPPORT_UTF */
5821          /* Not UTF mode */
       /* Not UTF-8 mode */  
5822          {          {
5823          switch(ctype)          switch(ctype)
5824            {            {
# Line 5593  for (;;) Line 5831  for (;;)
5831                break;                break;
5832                }                }
5833              if (IS_NEWLINE(eptr)) break;              if (IS_NEWLINE(eptr)) break;
5834                if (md->partial != 0 &&    /* Take care with CRLF partial */
5835                    eptr + 1 >= md->end_subject &&
5836                    NLBLOCK->nltype == NLTYPE_FIXED &&
5837                    NLBLOCK->nllen == 2 &&
5838                    *eptr == NLBLOCK->nl[0])
5839                  {
5840                  md->hitend = TRUE;
5841                  if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
5842                  }
5843              eptr++;              eptr++;
5844              }              }
5845            break;            break;
# Line 5617  for (;;) Line 5864  for (;;)
5864                break;                break;
5865                }                }
5866              c = *eptr;              c = *eptr;
5867              if (c == 0x000d)              if (c == CHAR_CR)
5868                {                {
5869                if (++eptr >= md->end_subject) break;                if (++eptr >= md->end_subject) break;
5870                if (*eptr == 0x000a) eptr++;                if (*eptr == CHAR_LF) eptr++;
5871                }                }
5872              else              else
5873                {                {
5874                if (c != 0x000a &&                if (c != CHAR_LF && (md->bsr_anycrlf ||
5875                    (md->bsr_anycrlf ||                   (c != CHAR_VT && c != CHAR_FF && c != CHAR_NEL
5876                      (c != 0x000b && c != 0x000c && c != 0x0085)))  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
5877                  break;                   && c != 0x2028 && c != 0x2029
5878    #endif
5879                     ))) break;
5880                eptr++;                eptr++;
5881                }                }
5882              }              }
# Line 5641  for (;;) Line 5890  for (;;)
5890                SCHECK_PARTIAL();                SCHECK_PARTIAL();
5891                break;                break;
5892                }                }
5893              c = *eptr;              switch(*eptr)
5894              if (c == 0x09 || c == 0x20 || c == 0xa0) break;                {
5895              eptr++;                default: eptr++; break;
5896                  HSPACE_BYTE_CASES:
5897    #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
5898                  HSPACE_MULTIBYTE_CASES:
5899    #endif
5900                  goto ENDLOOP00;
5901                  }
5902              }              }
5903              ENDLOOP00:
5904            break;            break;
5905    
5906            case OP_HSPACE:            case OP_HSPACE:
# Line 5655  for (;;) Line 5911  for (;;)
5911                SCHECK_PARTIAL();                SCHECK_PARTIAL();
5912                break;                break;
5913                }                }
5914              c = *eptr;              switch(*eptr)
5915              if (c != 0x09 && c != 0x20 && c != 0xa0) break;                {
5916              eptr++;                default: goto ENDLOOP01;
5917                  HSPACE_BYTE_CASES:
5918    #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
5919                  HSPACE_MULTIBYTE_CASES:
5920    #endif
5921                  eptr++; break;
5922                  }
5923              }              }
5924              ENDLOOP01:
5925            break;            break;
5926    
5927            case OP_NOT_VSPACE:            case OP_NOT_VSPACE:
# Line 5669  for (;;) Line 5932  for (;;)
5932                SCHECK_PARTIAL();                SCHECK_PARTIAL();
5933                break;                break;
5934                }                }
5935              c = *eptr;              switch(*eptr)
5936              if (c == 0x0a || c == 0x0b || c == 0x0c || c == 0x0d || c == 0x85)                {
5937                break;                default: eptr++; break;
5938              eptr++;                VSPACE_BYTE_CASES:
5939    #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
5940                  VSPACE_MULTIBYTE_CASES:
5941    #endif
5942                  goto ENDLOOP02;
5943                  }
5944              }              }
5945              ENDLOOP02:
5946            break;            break;
5947    
5948            case OP_VSPACE:            case OP_VSPACE:
# Line 5684  for (;;) Line 5953  for (;;)
5953                SCHECK_PARTIAL();                SCHECK_PARTIAL();
5954                break;                break;
5955                }                }
5956              c = *eptr;              switch(*eptr)
5957              if (c != 0x0a && c != 0x0b && c != 0x0c && c != 0x0d && c != 0x85)                {
5958                break;                default: goto ENDLOOP03;
5959              eptr++;                VSPACE_BYTE_CASES:
5960    #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
5961                  VSPACE_MULTIBYTE_CASES:
5962    #endif
5963                  eptr++; break;
5964                  }
5965              }              }
5966              ENDLOOP03:
5967            break;            break;
5968    
5969            case OP_NOT_DIGIT:            case OP_NOT_DIGIT:
# Line 5699  for (;;) Line 5974  for (;;)
5974                SCHECK_PARTIAL();                SCHECK_PARTIAL();
5975                break;                break;
5976                }                }
5977              if ((md->ctypes[*eptr] & ctype_digit) != 0) break;              if (MAX_255(*eptr) && (md->ctypes[*eptr] & ctype_digit) != 0) break;
5978              eptr++;              eptr++;
5979              }              }
5980            break;            break;
# Line 5712  for (;;) Line 5987  for (;;)
5987                SCHECK_PARTIAL();                SCHECK_PARTIAL();
5988                break;                break;
5989                }                }
5990              if ((md->ctypes[*eptr] & ctype_digit) == 0) break;              if (!MAX_255(*eptr) || (md->ctypes[*eptr] & ctype_digit) == 0) break;
5991              eptr++;              eptr++;
5992              }              }
5993            break;            break;
# Line 5725  for (;;) Line 6000  for (;;)
6000                SCHECK_PARTIAL();                SCHECK_PARTIAL();
6001                break;                break;
6002                }                }
6003              if ((md->ctypes[*eptr] & ctype_space) != 0) break;              if (MAX_255(*eptr) && (md->ctypes[*eptr] & ctype_space) != 0) break;
6004              eptr++;              eptr++;
6005              }              }
6006            break;            break;
# Line 5738  for (;;) Line 6013  for (;;)
6013                SCHECK_PARTIAL();                SCHECK_PARTIAL();
6014                break;                break;
6015                }                }
6016              if ((md->ctypes[*eptr] & ctype_space) == 0) break;              if (!MAX_255(*eptr) || (md->ctypes[*eptr] & ctype_space) == 0) break;
6017              eptr++;              eptr++;
6018              }              }
6019            break;            break;
# Line 5751  for (;;) Line 6026  for (;;)
6026                SCHECK_PARTIAL();                SCHECK_PARTIAL();
6027                break;                break;
6028                }                }
6029              if ((md->ctypes[*eptr] & ctype_word) != 0) break;              if (MAX_255(*eptr) && (md->ctypes[*eptr] & ctype_word) != 0) break;
6030              eptr++;              eptr++;
6031              }              }
6032            break;            break;
# Line 5764  for (;;) Line 6039  for (;;)
6039                SCHECK_PARTIAL();                SCHECK_PARTIAL();
6040                break;                break;
6041                }                }
6042              if ((md->ctypes[*eptr] & ctype_word) == 0) break;              if (!MAX_255(*eptr) || (md->ctypes[*eptr] & ctype_word) == 0) break;
6043              eptr++;              eptr++;
6044              }              }
6045            break;            break;
# Line 5785  for (;;) Line 6060  for (;;)
6060            RMATCH(eptr, ecode, offset_top, md, eptrb, RM47);            RMATCH(eptr, ecode, offset_top, md, eptrb, RM47);
6061            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
6062            eptr--;            eptr--;
6063            if (ctype == OP_ANYNL && eptr > pp  && *eptr == '\n' &&            if (ctype == OP_ANYNL && eptr > pp  && *eptr == CHAR_LF &&
6064                eptr[-1] == '\r') eptr--;                eptr[-1] == CHAR_CR) eptr--;
6065            }            }