/[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 788 by ph10, Tue Dec 6 15:38:01 2011 UTC revision 1238 by ph10, Sat Jan 5 16:27:59 2013 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 (int)(eptr - eptr_start);  return (int)(eptr - eptr_start);
# 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 385  typedef struct heapframe { Line 416  typedef struct heapframe {
416    int Xlength;    int Xlength;
417    int Xmax;    int Xmax;
418    int Xmin;    int Xmin;
419    int Xnumber;    unsigned int Xnumber;
420    int Xoffset;    int Xoffset;
421    int Xop;    unsigned int Xop;
422    int Xsave_capture_last;    int Xsave_capture_last;
423    int Xsave_offset1, Xsave_offset2, Xsave_offset3;    int Xsave_offset1, Xsave_offset2, Xsave_offset3;
424    int Xstacksave[REC_STACK_SAVE_MAX];    int Xstacksave[REC_STACK_SAVE_MAX];
# 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;  unsigned int 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 758  for (;;) Line 809  for (;;)
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);
# 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 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 1165  for (;;) Line 1222  for (;;)
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) + ecode[2];
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 3047  for (;;) Line 3176  for (;;)
3176        RRETURN(MATCH_NOMATCH);        RRETURN(MATCH_NOMATCH);
3177        }        }
3178    
3179  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3180      if (utf8)      if (utf)
3181        {        {
3182        length = 1;        length = 1;
3183        ecode++;        ecode++;
# Line 3061  for (;;) Line 3190  for (;;)
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. Note that we cannot        /* Otherwise we must pick up the subject character. Note that we cannot
# Line 3070  for (;;) Line 3202  for (;;)
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 3087  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->lcc[ecode[1]] != md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH);        if (TABLE_GET(ecode[1], md->lcc, ecode[1])
3227              != TABLE_GET(*eptr, md->lcc, *eptr)) RRETURN(MATCH_NOMATCH);
3228          eptr++;
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      /* When not in UTF-8 mode, load a single-byte character. */        fc = *ecode++;
   
     fc = *ecode++;  
3408    
3409      /* The value of fc at this point is always less than 256, though we may or      /* The value of fc at this point is always one character, though we may
3410      may not be in UTF-8 mode. The code is duplicated for the caseless and      or may not be in UTF 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_uint32 cc;                 /* Faster than pcre_uchar */
3443          if (eptr >= md->end_subject)          if (eptr >= md->end_subject)
3444            {            {
3445            SCHECK_PARTIAL();            SCHECK_PARTIAL();
3446            RRETURN(MATCH_NOMATCH);            RRETURN(MATCH_NOMATCH);
3447            }            }
3448          if (fc != md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH);          cc = RAWUCHARTEST(eptr);
3449            if (fc != cc && foc != cc) RRETURN(MATCH_NOMATCH);
3450            eptr++;
3451          }          }
3452        if (min == max) continue;        if (min == max) continue;
3453        if (minimize)        if (minimize)
3454          {          {
3455          for (fi = min;; fi++)          for (fi = min;; fi++)
3456            {            {
3457              pcre_uint32 cc;               /* Faster than pcre_uchar */
3458            RMATCH(eptr, ecode, offset_top, md, eptrb, RM24);            RMATCH(eptr, ecode, offset_top, md, eptrb, RM24);
3459            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3460            if (fi >= max) RRETURN(MATCH_NOMATCH);            if (fi >= max) RRETURN(MATCH_NOMATCH);
# Line 3311  for (;;) Line 3463  for (;;)
3463              SCHECK_PARTIAL();              SCHECK_PARTIAL();
3464              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
3465              }              }
3466            if (fc != md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH);            cc = RAWUCHARTEST(eptr);
3467              if (fc != cc && foc != cc) RRETURN(MATCH_NOMATCH);
3468              eptr++;
3469            }            }
3470          /* Control never gets here */          /* Control never gets here */
3471          }          }
# Line 3320  for (;;) Line 3474  for (;;)
3474          pp = eptr;          pp = eptr;
3475          for (i = min; i < max; i++)          for (i = min; i < max; i++)
3476            {            {
3477              pcre_uint32 cc;               /* Faster than pcre_uchar */
3478            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
3479              {              {
3480              SCHECK_PARTIAL();              SCHECK_PARTIAL();
3481              break;              break;
3482              }              }
3483            if (fc != md->lcc[*eptr]) break;            cc = RAWUCHARTEST(eptr);
3484              if (fc != cc && foc != cc) break;
3485            eptr++;            eptr++;
3486            }            }
3487    
# Line 3353  for (;;) Line 3509  for (;;)
3509            SCHECK_PARTIAL();            SCHECK_PARTIAL();
3510            RRETURN(MATCH_NOMATCH);            RRETURN(MATCH_NOMATCH);
3511            }            }
3512          if (fc != *eptr++) RRETURN(MATCH_NOMATCH);          if (fc != RAWUCHARINCTEST(eptr)) RRETURN(MATCH_NOMATCH);
3513          }          }
3514    
3515        if (min == max) continue;        if (min == max) continue;
# Line 3370  for (;;) Line 3526  for (;;)
3526              SCHECK_PARTIAL();              SCHECK_PARTIAL();
3527              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
3528              }              }
3529            if (fc != *eptr++) RRETURN(MATCH_NOMATCH);            if (fc != RAWUCHARINCTEST(eptr)) RRETURN(MATCH_NOMATCH);
3530            }            }
3531          /* Control never gets here */          /* Control never gets here */
3532          }          }
# Line 3384  for (;;) Line 3540  for (;;)
3540              SCHECK_PARTIAL();              SCHECK_PARTIAL();
3541              break;              break;
3542              }              }
3543            if (fc != *eptr) break;            if (fc != RAWUCHARTEST(eptr)) break;
3544            eptr++;            eptr++;
3545            }            }
3546          if (possessive) continue;          if (possessive) continue;
# Line 3410  for (;;) Line 3566  for (;;)
3566        SCHECK_PARTIAL();        SCHECK_PARTIAL();
3567        RRETURN(MATCH_NOMATCH);        RRETURN(MATCH_NOMATCH);
3568        }        }
3569      ecode++;  #ifdef SUPPORT_UTF
3570      GETCHARINCTEST(c, eptr);      if (utf)
     if (op == OP_NOTI)         /* The caseless case */  
3571        {        {
3572  #ifdef SUPPORT_UTF8        register pcre_uint32 ch, och;
3573        if (c < 256)  
3574  #endif        ecode++;
3575        c = md->lcc[c];        GETCHARINC(ch, ecode);
3576        if (md->lcc[*ecode++] == c) RRETURN(MATCH_NOMATCH);        GETCHARINC(c, eptr);
3577    
3578          if (op == OP_NOT)
3579            {
3580            if (ch == c) RRETURN(MATCH_NOMATCH);
3581            }
3582          else
3583            {
3584    #ifdef SUPPORT_UCP
3585            if (ch > 127)
3586              och = UCD_OTHERCASE(ch);
3587    #else
3588            if (ch > 127)
3589              och = ch;
3590    #endif /* SUPPORT_UCP */
3591            else
3592              och = TABLE_GET(ch, md->fcc, ch);
3593            if (ch == c || och == c) RRETURN(MATCH_NOMATCH);
3594            }
3595        }        }
3596      else    /* Caseful */      else
3597    #endif
3598        {        {
3599        if (*ecode++ == c) RRETURN(MATCH_NOMATCH);        register pcre_uint32 ch = ecode[1];
3600          c = *eptr++;
3601          if (ch == c || (op == OP_NOTI && TABLE_GET(ch, md->fcc, ch) == c))
3602            RRETURN(MATCH_NOMATCH);
3603          ecode += 2;
3604        }        }
3605      break;      break;
3606    
# Line 3436  for (;;) Line 3614  for (;;)
3614      case OP_NOTEXACT:      case OP_NOTEXACT:
3615      case OP_NOTEXACTI:      case OP_NOTEXACTI:
3616      min = max = GET2(ecode, 1);      min = max = GET2(ecode, 1);
3617      ecode += 3;      ecode += 1 + IMM2_SIZE;
3618      goto REPEATNOTCHAR;      goto REPEATNOTCHAR;
3619    
3620      case OP_NOTUPTO:      case OP_NOTUPTO:
# Line 3446  for (;;) Line 3624  for (;;)
3624      min = 0;      min = 0;
3625      max = GET2(ecode, 1);      max = GET2(ecode, 1);
3626      minimize = *ecode == OP_NOTMINUPTO || *ecode == OP_NOTMINUPTOI;      minimize = *ecode == OP_NOTMINUPTO || *ecode == OP_NOTMINUPTOI;
3627      ecode += 3;      ecode += 1 + IMM2_SIZE;
3628      goto REPEATNOTCHAR;      goto REPEATNOTCHAR;
3629    
3630      case OP_NOTPOSSTAR:      case OP_NOTPOSSTAR:
# Line 3478  for (;;) Line 3656  for (;;)
3656      possessive = TRUE;      possessive = TRUE;
3657      min = 0;      min = 0;
3658      max = GET2(ecode, 1);      max = GET2(ecode, 1);
3659      ecode += 3;      ecode += 1 + IMM2_SIZE;
3660      goto REPEATNOTCHAR;      goto REPEATNOTCHAR;
3661    
3662      case OP_NOTSTAR:      case OP_NOTSTAR:
# Line 3502  for (;;) Line 3680  for (;;)
3680      /* Common code for all repeated single-byte matches. */      /* Common code for all repeated single-byte matches. */
3681    
3682      REPEATNOTCHAR:      REPEATNOTCHAR:
3683      fc = *ecode++;      GETCHARINCTEST(fc, ecode);
3684    
3685      /* The code is duplicated for the caseless and caseful cases, for speed,      /* The code is duplicated for the caseless and caseful cases, for speed,
3686      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 3691  for (;;)
3691      characters and work backwards. */      characters and work backwards. */
3692    
3693      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,
3694        max, eptr));        max, (char *)eptr));
3695    
3696      if (op >= OP_NOTSTARI)     /* Caseless */      if (op >= OP_NOTSTARI)     /* Caseless */
3697        {        {
3698        fc = md->lcc[fc];  #ifdef SUPPORT_UTF
3699    #ifdef SUPPORT_UCP
3700          if (utf && fc > 127)
3701            foc = UCD_OTHERCASE(fc);
3702    #else
3703          if (utf && fc > 127)
3704            foc = fc;
3705    #endif /* SUPPORT_UCP */
3706          else
3707    #endif /* SUPPORT_UTF */
3708            foc = TABLE_GET(fc, md->fcc, fc);
3709    
3710  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3711        /* UTF-8 mode */        if (utf)
       if (utf8)  
3712          {          {
3713          register unsigned int d;          register pcre_uint32 d;
3714          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3715            {            {
3716            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
# Line 3532  for (;;) Line 3719  for (;;)
3719              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
3720              }              }
3721            GETCHARINC(d, eptr);            GETCHARINC(d, eptr);
3722            if (d < 256) d = md->lcc[d];            if (fc == d || (unsigned int)foc == d) RRETURN(MATCH_NOMATCH);
           if (fc == d) RRETURN(MATCH_NOMATCH);  
3723            }            }
3724          }          }
3725        else        else
3726  #endif  #endif
3727          /* Not UTF mode */
       /* Not UTF-8 mode */  
3728          {          {
3729          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3730            {            {
# Line 3548  for (;;) Line 3733  for (;;)
3733              SCHECK_PARTIAL();              SCHECK_PARTIAL();
3734              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
3735              }              }
3736            if (fc == md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH);            if (fc == *eptr || foc == *eptr) RRETURN(MATCH_NOMATCH);
3737              eptr++;
3738            }            }
3739          }          }
3740    
# Line 3556  for (;;) Line 3742  for (;;)
3742    
3743        if (minimize)        if (minimize)
3744          {          {
3745  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3746          /* UTF-8 mode */          if (utf)
         if (utf8)  
3747            {            {
3748            register unsigned int d;            register pcre_uint32 d;
3749            for (fi = min;; fi++)            for (fi = min;; fi++)
3750              {              {
3751              RMATCH(eptr, ecode, offset_top, md, eptrb, RM28);              RMATCH(eptr, ecode, offset_top, md, eptrb, RM28);
# Line 3572  for (;;) Line 3757  for (;;)
3757                RRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
3758                }                }
3759              GETCHARINC(d, eptr);              GETCHARINC(d, eptr);
3760              if (d < 256) d = md->lcc[d];              if (fc == d || (unsigned int)foc == d) RRETURN(MATCH_NOMATCH);
             if (fc == d) RRETURN(MATCH_NOMATCH);  
3761              }              }
3762            }            }
3763          else          else
3764  #endif  #endif
3765          /* Not UTF-8 mode */          /* Not UTF mode */
3766            {            {
3767            for (fi = min;; fi++)            for (fi = min;; fi++)
3768              {              {
# Line 3590  for (;;) Line 3774  for (;;)
3774                SCHECK_PARTIAL();                SCHECK_PARTIAL();
3775                RRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
3776                }                }
3777              if (fc == md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH);              if (fc == *eptr || foc == *eptr) RRETURN(MATCH_NOMATCH);
3778                eptr++;
3779              }              }
3780            }            }
3781          /* Control never gets here */          /* Control never gets here */
# Line 3602  for (;;) Line 3787  for (;;)
3787          {          {
3788          pp = eptr;          pp = eptr;
3789    
3790  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3791          /* UTF-8 mode */          if (utf)
         if (utf8)  
3792            {            {
3793            register unsigned int d;            register pcre_uint32 d;
3794            for (i = min; i < max; i++)            for (i = min; i < max; i++)
3795              {              {
3796              int len = 1;              int len = 1;
# Line 3616  for (;;) Line 3800  for (;;)
3800                break;                break;
3801                }                }
3802              GETCHARLEN(d, eptr, len);              GETCHARLEN(d, eptr, len);
3803              if (d < 256) d = md->lcc[d];              if (fc == d || (unsigned int)foc == d) break;
             if (fc == d) break;  
3804              eptr += len;              eptr += len;
3805              }              }
3806          if (possessive) continue;            if (possessive) continue;
3807          for(;;)            for(;;)
3808              {              {
3809              RMATCH(eptr, ecode, offset_top, md, eptrb, RM30);              RMATCH(eptr, ecode, offset_top, md, eptrb, RM30);
3810              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
# Line 3631  for (;;) Line 3814  for (;;)
3814            }            }
3815          else          else
3816  #endif  #endif
3817          /* Not UTF-8 mode */          /* Not UTF mode */
3818            {            {
3819            for (i = min; i < max; i++)            for (i = min; i < max; i++)
3820              {              {
# Line 3640  for (;;) Line 3823  for (;;)
3823                SCHECK_PARTIAL();                SCHECK_PARTIAL();
3824                break;                break;
3825                }                }
3826              if (fc == md->lcc[*eptr]) break;              if (fc == *eptr || foc == *eptr) break;
3827              eptr++;              eptr++;
3828              }              }
3829            if (possessive) continue;            if (possessive) continue;
# Line 3661  for (;;) Line 3844  for (;;)
3844    
3845      else      else
3846        {        {
3847  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3848        /* UTF-8 mode */        if (utf)
       if (utf8)  
3849          {          {
3850          register unsigned int d;          register pcre_uint32 d;
3851          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3852            {            {
3853            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
# Line 3679  for (;;) Line 3861  for (;;)
3861          }          }
3862        else        else
3863  #endif  #endif
3864        /* Not UTF-8 mode */        /* Not UTF mode */
3865          {          {
3866          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3867            {            {
# Line 3696  for (;;) Line 3878  for (;;)
3878    
3879        if (minimize)        if (minimize)
3880          {          {
3881  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3882          /* UTF-8 mode */          if (utf)
         if (utf8)  
3883            {            {
3884            register unsigned int d;            register pcre_uint32 d;
3885            for (fi = min;; fi++)            for (fi = min;; fi++)
3886              {              {
3887              RMATCH(eptr, ecode, offset_top, md, eptrb, RM32);              RMATCH(eptr, ecode, offset_top, md, eptrb, RM32);
# Line 3717  for (;;) Line 3898  for (;;)
3898            }            }
3899          else          else
3900  #endif  #endif
3901          /* Not UTF-8 mode */          /* Not UTF mode */
3902            {            {
3903            for (fi = min;; fi++)            for (fi = min;; fi++)
3904              {              {
# Line 3741  for (;;) Line 3922  for (;;)
3922          {          {
3923          pp = eptr;          pp = eptr;
3924    
3925  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3926          /* UTF-8 mode */          if (utf)
         if (utf8)  
3927            {            {
3928            register unsigned int d;            register pcre_uint32 d;
3929            for (i = min; i < max; i++)            for (i = min; i < max; i++)
3930              {              {
3931              int len = 1;              int len = 1;
# Line 3769  for (;;) Line 3949  for (;;)
3949            }            }
3950          else          else
3951  #endif  #endif
3952          /* Not UTF-8 mode */          /* Not UTF mode */
3953            {            {
3954            for (i = min; i < max; i++)            for (i = min; i < max; i++)
3955              {              {
# Line 3802  for (;;) Line 3982  for (;;)
3982      case OP_TYPEEXACT:      case OP_TYPEEXACT:
3983      min = max = GET2(ecode, 1);      min = max = GET2(ecode, 1);
3984      minimize = TRUE;      minimize = TRUE;
3985      ecode += 3;      ecode += 1 + IMM2_SIZE;
3986      goto REPEATTYPE;      goto REPEATTYPE;
3987    
3988      case OP_TYPEUPTO:      case OP_TYPEUPTO:
# Line 3810  for (;;) Line 3990  for (;;)
3990      min = 0;      min = 0;
3991      max = GET2(ecode, 1);      max = GET2(ecode, 1);
3992      minimize = *ecode == OP_TYPEMINUPTO;      minimize = *ecode == OP_TYPEMINUPTO;
3993      ecode += 3;      ecode += 1 + IMM2_SIZE;
3994      goto REPEATTYPE;      goto REPEATTYPE;
3995    
3996      case OP_TYPEPOSSTAR:      case OP_TYPEPOSSTAR:
# Line 3838  for (;;) Line 4018  for (;;)
4018      possessive = TRUE;      possessive = TRUE;
4019      min = 0;      min = 0;
4020      max = GET2(ecode, 1);      max = GET2(ecode, 1);
4021      ecode += 3;      ecode += 1 + IMM2_SIZE;
4022      goto REPEATTYPE;      goto REPEATTYPE;
4023    
4024      case OP_TYPESTAR:      case OP_TYPESTAR:
# Line 4021  for (;;) Line 4201  for (;;)
4201              }              }
4202            break;            break;
4203    
4204              case PT_CLIST:
4205              for (i = 1; i <= min; i++)
4206                {
4207                const pcre_uint32 *cp;
4208                if (eptr >= md->end_subject)
4209                  {
4210                  SCHECK_PARTIAL();
4211                  RRETURN(MATCH_NOMATCH);
4212                  }
4213                GETCHARINCTEST(c, eptr);
4214                cp = PRIV(ucd_caseless_sets) + prop_value;
4215                for (;;)
4216                  {
4217                  if (c < *cp)
4218                    { if (prop_fail_result) break; else { RRETURN(MATCH_NOMATCH); } }
4219                  if (c == *cp++)
4220                    { if (prop_fail_result) { RRETURN(MATCH_NOMATCH); } else break; }
4221                  }
4222                }
4223              break;
4224    
4225            /* This should not occur */            /* This should not occur */
4226    
4227            default:            default:
# Line 4040  for (;;) Line 4241  for (;;)
4241              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4242              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4243              }              }
4244            GETCHARINCTEST(c, eptr);            else
           if (UCD_CATEGORY(c) == ucp_M) RRETURN(MATCH_NOMATCH);  
           while (eptr < md->end_subject)  
4245              {              {
4246              int len = 1;              int lgb, rgb;
4247              if (!utf8) c = *eptr; else { GETCHARLEN(c, eptr, len); }              GETCHARINCTEST(c, eptr);
4248              if (UCD_CATEGORY(c) != ucp_M) break;              lgb = UCD_GRAPHBREAK(c);
4249              eptr += len;             while (eptr < md->end_subject)
4250                  {
4251                  int len = 1;
4252                  if (!utf) c = *eptr; else { GETCHARLEN(c, eptr, len); }
4253                  rgb = UCD_GRAPHBREAK(c);
4254                  if ((PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0) break;
4255                  lgb = rgb;
4256                  eptr += len;
4257                  }
4258              }              }
4259              CHECK_PARTIAL();
4260            }            }
4261          }          }
4262    
# Line 4057  for (;;) Line 4265  for (;;)
4265    
4266  /* Handle all other cases when the coding is UTF-8 */  /* Handle all other cases when the coding is UTF-8 */
4267    
4268  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
4269        if (utf8) switch(ctype)        if (utf) switch(ctype)
4270          {          {
4271          case OP_ANY:          case OP_ANY:
4272          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
# Line 4069  for (;;) Line 4277  for (;;)
4277              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4278              }              }
4279            if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH);            if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH);
4280              if (md->partial != 0 &&
4281                  eptr + 1 >= md->end_subject &&
4282                  NLBLOCK->nltype == NLTYPE_FIXED &&
4283                  NLBLOCK->nllen == 2 &&
4284                  RAWUCHAR(eptr) == NLBLOCK->nl[0])
4285                {
4286                md->hitend = TRUE;
4287                if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
4288                }
4289            eptr++;            eptr++;
4290            while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;            ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
4291            }            }
4292          break;          break;
4293    
# Line 4083  for (;;) Line 4300  for (;;)
4300              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4301              }              }
4302            eptr++;            eptr++;
4303            while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;            ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
4304            }            }
4305          break;          break;
4306    
# Line 4105  for (;;) Line 4322  for (;;)
4322              {              {
4323              default: RRETURN(MATCH_NOMATCH);              default: RRETURN(MATCH_NOMATCH);
4324    
4325              case 0x000d:              case CHAR_CR:
4326              if (eptr < md->end_subject && *eptr == 0x0a) eptr++;              if (eptr < md->end_subject && RAWUCHAR(eptr) == CHAR_LF) eptr++;
4327              break;              break;
4328    
4329              case 0x000a:              case CHAR_LF:
4330              break;              break;
4331    
4332              case 0x000b:              case CHAR_VT:
4333              case 0x000c:              case CHAR_FF:
4334              case 0x0085:              case CHAR_NEL:
4335    #ifndef EBCDIC
4336              case 0x2028:              case 0x2028:
4337              case 0x2029:              case 0x2029:
4338    #endif  /* Not EBCDIC */
4339              if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH);              if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH);
4340              break;              break;
4341              }              }
# Line 4134  for (;;) Line 4353  for (;;)
4353            GETCHARINC(c, eptr);            GETCHARINC(c, eptr);
4354            switch(c)            switch(c)
4355              {              {
4356                HSPACE_CASES: RRETURN(MATCH_NOMATCH);  /* Byte and multibyte cases */
4357              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);  
4358              }              }
4359            }            }
4360          break;          break;
# Line 4170  for (;;) Line 4370  for (;;)
4370            GETCHARINC(c, eptr);            GETCHARINC(c, eptr);
4371            switch(c)            switch(c)
4372              {              {
4373                HSPACE_CASES: break;  /* Byte and multibyte cases */
4374              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;  
4375              }              }
4376            }            }
4377          break;          break;
# Line 4206  for (;;) Line 4387  for (;;)
4387            GETCHARINC(c, eptr);            GETCHARINC(c, eptr);
4388            switch(c)            switch(c)
4389              {              {
4390                VSPACE_CASES: RRETURN(MATCH_NOMATCH);
4391              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);  
4392              }              }
4393            }            }
4394          break;          break;
# Line 4230  for (;;) Line 4404  for (;;)
4404            GETCHARINC(c, eptr);            GETCHARINC(c, eptr);
4405            switch(c)            switch(c)
4406              {              {
4407                VSPACE_CASES: break;
4408              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;  
4409              }              }
4410            }            }
4411          break;          break;
# Line 4260  for (;;) Line 4427  for (;;)
4427          case OP_DIGIT:          case OP_DIGIT:
4428          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
4429            {            {
4430              pcre_uchar cc;
4431    
4432            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4433              {              {
4434              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4435              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4436              }              }
4437            if (*eptr >= 128 || (md->ctypes[*eptr++] & ctype_digit) == 0)            cc = RAWUCHAR(eptr);
4438              if (cc >= 128 || (md->ctypes[cc] & ctype_digit) == 0)
4439              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4440              eptr++;
4441            /* 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 */
4442            }            }
4443          break;          break;
# Line 4274  for (;;) Line 4445  for (;;)
4445          case OP_NOT_WHITESPACE:          case OP_NOT_WHITESPACE:
4446          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
4447            {            {
4448              pcre_uchar cc;
4449    
4450            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4451              {              {
4452              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4453              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4454              }              }
4455            if (*eptr < 128 && (md->ctypes[*eptr] & ctype_space) != 0)            cc = RAWUCHAR(eptr);
4456              if (cc < 128 && (md->ctypes[cc] & ctype_space) != 0)
4457              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4458            while (++eptr < md->end_subject && (*eptr & 0xc0) == 0x80);            eptr++;
4459              ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
4460            }            }
4461          break;          break;
4462    
4463          case OP_WHITESPACE:          case OP_WHITESPACE:
4464          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
4465            {            {
4466              pcre_uchar cc;
4467    
4468            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4469              {              {
4470              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4471              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4472              }              }
4473            if (*eptr >= 128 || (md->ctypes[*eptr++] & ctype_space) == 0)            cc = RAWUCHAR(eptr);
4474              if (cc >= 128 || (md->ctypes[cc] & ctype_space) == 0)
4475              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4476              eptr++;
4477            /* 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 */
4478            }            }
4479          break;          break;
# Line 4302  for (;;) Line 4481  for (;;)
4481          case OP_NOT_WORDCHAR:          case OP_NOT_WORDCHAR:
4482          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
4483            {            {
4484              pcre_uchar cc;
4485    
4486            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4487              {              {
4488              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4489              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4490              }              }
4491            if (*eptr < 128 && (md->ctypes[*eptr] & ctype_word) != 0)            cc = RAWUCHAR(eptr);
4492              if (cc < 128 && (md->ctypes[cc] & ctype_word) != 0)
4493              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4494            while (++eptr < md->end_subject && (*eptr & 0xc0) == 0x80);            eptr++;
4495              ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
4496            }            }
4497          break;          break;
4498    
4499          case OP_WORDCHAR:          case OP_WORDCHAR:
4500          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
4501            {            {
4502              pcre_uchar cc;
4503    
4504            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
4505              {              {
4506              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4507              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4508              }              }
4509            if (*eptr >= 128 || (md->ctypes[*eptr++] & ctype_word) == 0)            cc = RAWUCHAR(eptr);
4510              if (cc >= 128 || (md->ctypes[cc] & ctype_word) == 0)
4511              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4512              eptr++;
4513            /* 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 */
4514            }            }
4515          break;          break;
# Line 4332  for (;;) Line 4519  for (;;)
4519          }  /* End switch(ctype) */          }  /* End switch(ctype) */
4520    
4521        else        else
4522  #endif     /* SUPPORT_UTF8 */  #endif     /* SUPPORT_UTF */
4523    
4524        /* 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
4525        than OP_PROP and OP_NOTPROP. */        than OP_PROP and OP_NOTPROP. */
# Line 4348  for (;;) Line 4535  for (;;)
4535              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4536              }              }
4537            if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH);            if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH);
4538              if (md->partial != 0 &&
4539                  eptr + 1 >= md->end_subject &&
4540                  NLBLOCK->nltype == NLTYPE_FIXED &&
4541                  NLBLOCK->nllen == 2 &&
4542                  *eptr == NLBLOCK->nl[0])
4543                {
4544                md->hitend = TRUE;
4545                if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
4546                }
4547            eptr++;            eptr++;
4548            }            }
4549          break;          break;
# Line 4382  for (;;) Line 4578  for (;;)
4578              {              {
4579              default: RRETURN(MATCH_NOMATCH);              default: RRETURN(MATCH_NOMATCH);
4580    
4581              case 0x000d:              case CHAR_CR:
4582              if (eptr < md->end_subject && *eptr == 0x0a) eptr++;              if (eptr < md->end_subject && *eptr == CHAR_LF) eptr++;
4583              break;              break;
4584    
4585              case 0x000a:              case CHAR_LF:
4586              break;              break;
4587    
4588              case 0x000b:              case CHAR_VT:
4589              case 0x000c:              case CHAR_FF:
4590              case 0x0085:              case CHAR_NEL:
4591    #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
4592                case 0x2028:
4593                case 0x2029:
4594    #endif
4595              if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH);              if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH);
4596              break;              break;
4597              }              }
# Line 4409  for (;;) Line 4609  for (;;)
4609            switch(*eptr++)            switch(*eptr++)
4610              {              {
4611              default: break;              default: break;
4612              case 0x09:      /* HT */              HSPACE_BYTE_CASES:
4613              case 0x20:      /* SPACE */  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
4614              case 0xa0:      /* NBSP */              HSPACE_MULTIBYTE_CASES:
4615    #endif
4616              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4617              }              }
4618            }            }
# Line 4428  for (;;) Line 4629  for (;;)
4629            switch(*eptr++)            switch(*eptr++)
4630              {              {
4631              default: RRETURN(MATCH_NOMATCH);              default: RRETURN(MATCH_NOMATCH);
4632              case 0x09:      /* HT */              HSPACE_BYTE_CASES:
4633              case 0x20:      /* SPACE */  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
4634              case 0xa0:      /* NBSP */              HSPACE_MULTIBYTE_CASES:
4635    #endif
4636              break;              break;
4637              }              }
4638            }            }
# Line 4446  for (;;) Line 4648  for (;;)
4648              }              }
4649            switch(*eptr++)            switch(*eptr++)
4650              {              {
4651              default: break;              VSPACE_BYTE_CASES:
4652              case 0x0a:      /* LF */  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
4653              case 0x0b:      /* VT */              VSPACE_MULTIBYTE_CASES:
4654              case 0x0c:      /* FF */  #endif
             case 0x0d:      /* CR */  
             case 0x85:      /* NEL */  
4655              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4656                default: break;
4657              }              }
4658            }            }
4659          break;          break;
# Line 4468  for (;;) Line 4669  for (;;)
4669            switch(*eptr++)            switch(*eptr++)
4670              {              {
4671              default: RRETURN(MATCH_NOMATCH);              default: RRETURN(MATCH_NOMATCH);
4672              case 0x0a:      /* LF */              VSPACE_BYTE_CASES:
4673              case 0x0b:      /* VT */  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
4674              case 0x0c:      /* FF */              VSPACE_MULTIBYTE_CASES:
4675              case 0x0d:      /* CR */  #endif
             case 0x85:      /* NEL */  
4676              break;              break;
4677              }              }
4678            }            }
# Line 4486  for (;;) Line 4686  for (;;)
4686              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4687              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4688              }              }
4689            if ((md->ctypes[*eptr++] & ctype_digit) != 0) RRETURN(MATCH_NOMATCH);            if (MAX_255(*eptr) && (md->ctypes[*eptr] & ctype_digit) != 0)
4690                RRETURN(MATCH_NOMATCH);
4691              eptr++;
4692            }            }
4693          break;          break;
4694    
# Line 4498  for (;;) Line 4700  for (;;)
4700              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4701              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4702              }              }
4703            if ((md->ctypes[*eptr++] & ctype_digit) == 0) RRETURN(MATCH_NOMATCH);            if (!MAX_255(*eptr) || (md->ctypes[*eptr] & ctype_digit) == 0)
4704                RRETURN(MATCH_NOMATCH);
4705              eptr++;
4706            }            }
4707          break;          break;
4708    
# Line 4510  for (;;) Line 4714  for (;;)
4714              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4715              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4716              }              }
4717            if ((md->ctypes[*eptr++] & ctype_space) != 0) RRETURN(MATCH_NOMATCH);            if (MAX_255(*eptr) && (md->ctypes[*eptr] & ctype_space) != 0)
4718                RRETURN(MATCH_NOMATCH);
4719              eptr++;
4720            }            }
4721          break;          break;
4722    
# Line 4522  for (;;) Line 4728  for (;;)
4728              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4729              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4730              }              }
4731            if ((md->ctypes[*eptr++] & ctype_space) == 0) RRETURN(MATCH_NOMATCH);            if (!MAX_255(*eptr) || (md->ctypes[*eptr] & ctype_space) == 0)
4732                RRETURN(MATCH_NOMATCH);
4733              eptr++;
4734            }            }
4735          break;          break;
4736    
# Line 4534  for (;;) Line 4742  for (;;)
4742              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4743              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4744              }              }
4745            if ((md->ctypes[*eptr++] & ctype_word) != 0)            if (MAX_255(*eptr) && (md->ctypes[*eptr] & ctype_word) != 0)
4746              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4747              eptr++;
4748            }            }
4749          break;          break;
4750    
# Line 4547  for (;;) Line 4756  for (;;)
4756              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4757              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4758              }              }
4759            if ((md->ctypes[*eptr++] & ctype_word) == 0)            if (!MAX_255(*eptr) || (md->ctypes[*eptr] & ctype_word) == 0)
4760              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4761              eptr++;
4762            }            }
4763          break;          break;
4764    
# Line 4739  for (;;) Line 4949  for (;;)
4949              }              }
4950            /* Control never gets here */            /* Control never gets here */
4951    
4952            /* This should never occur */            case PT_CLIST:
4953              for (fi = min;; fi++)
4954                {
4955                const pcre_uint32 *cp;
4956                RMATCH(eptr, ecode, offset_top, md, eptrb, RM67);
4957                if (rrc != MATCH_NOMATCH) RRETURN(rrc);
4958                if (fi >= max) RRETURN(MATCH_NOMATCH);
4959                if (eptr >= md->end_subject)
4960                  {
4961                  SCHECK_PARTIAL();
4962                  RRETURN(MATCH_NOMATCH);
4963                  }
4964                GETCHARINCTEST(c, eptr);
4965                cp = PRIV(ucd_caseless_sets) + prop_value;
4966                for (;;)
4967                  {
4968                  if (c < *cp)
4969                    { if (prop_fail_result) break; else { RRETURN(MATCH_NOMATCH); } }
4970                  if (c == *cp++)
4971                    { if (prop_fail_result) { RRETURN(MATCH_NOMATCH); } else break; }
4972                  }
4973                }
4974              /* Control never gets here */
4975    
4976              /* This should never occur */
4977            default:            default:
4978            RRETURN(PCRE_ERROR_INTERNAL);            RRETURN(PCRE_ERROR_INTERNAL);
4979            }            }
# Line 4761  for (;;) Line 4994  for (;;)
4994              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4995              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4996              }              }
4997            GETCHARINCTEST(c, eptr);            else
           if (UCD_CATEGORY(c) == ucp_M) RRETURN(MATCH_NOMATCH);  
           while (eptr < md->end_subject)  
4998              {              {
4999              int len = 1;              int lgb, rgb;
5000              if (!utf8) c = *eptr; else { GETCHARLEN(c, eptr, len); }              GETCHARINCTEST(c, eptr);
5001              if (UCD_CATEGORY(c) != ucp_M) break;              lgb = UCD_GRAPHBREAK(c);
5002              eptr += len;              while (eptr < md->end_subject)
5003                  {
5004                  int len = 1;
5005                  if (!utf) c = *eptr; else { GETCHARLEN(c, eptr, len); }
5006                  rgb = UCD_GRAPHBREAK(c);
5007                  if ((PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0) break;
5008                  lgb = rgb;
5009                  eptr += len;
5010                  }
5011              }              }
5012              CHECK_PARTIAL();
5013            }            }
5014          }          }
5015        else        else
5016  #endif     /* SUPPORT_UCP */  #endif     /* SUPPORT_UCP */
5017    
5018  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
5019        /* UTF-8 mode */        if (utf)
       if (utf8)  
5020          {          {
5021          for (fi = min;; fi++)          for (fi = min;; fi++)
5022            {            {
# Line 4794  for (;;) Line 5033  for (;;)
5033            GETCHARINC(c, eptr);            GETCHARINC(c, eptr);
5034            switch(ctype)            switch(ctype)
5035              {              {
5036              case OP_ANY:        /* This is the non-NL case */              case OP_ANY:               /* This is the non-NL case */
5037                if (md->partial != 0 &&    /* Take care with CRLF partial */
5038                    eptr >= md->end_subject &&
5039                    NLBLOCK->nltype == NLTYPE_FIXED &&
5040                    NLBLOCK->nllen == 2 &&
5041                    c == NLBLOCK->nl[0])
5042                  {
5043                  md->hitend = TRUE;
5044                  if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
5045                  }
5046                break;
5047    
5048              case OP_ALLANY:              case OP_ALLANY:
5049              case OP_ANYBYTE:              case OP_ANYBYTE:
5050              break;              break;
# Line 4803  for (;;) Line 5053  for (;;)
5053              switch(c)              switch(c)
5054                {                {
5055                default: RRETURN(MATCH_NOMATCH);                default: RRETURN(MATCH_NOMATCH);
5056                case 0x000d:                case CHAR_CR:
5057                if (eptr < md->end_subject && *eptr == 0x0a) eptr++;                if (eptr < md->end_subject && RAWUCHAR(eptr) == CHAR_LF) eptr++;
5058                break;                break;
5059                case 0x000a:  
5060                  case CHAR_LF:
5061                break;                break;
5062    
5063                case 0x000b:                case CHAR_VT:
5064                case 0x000c:                case CHAR_FF:
5065                case 0x0085:                case CHAR_NEL:
5066    #ifndef EBCDIC
5067                case 0x2028:                case 0x2028:
5068                case 0x2029:                case 0x2029:
5069    #endif  /* Not EBCDIC */
5070                if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH);                if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH);
5071                break;                break;
5072                }                }
# Line 4822  for (;;) Line 5075  for (;;)
5075              case OP_NOT_HSPACE:              case OP_NOT_HSPACE:
5076              switch(c)              switch(c)
5077                {                {
5078                  HSPACE_CASES: RRETURN(MATCH_NOMATCH);
5079                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);  
5080                }                }
5081              break;              break;
5082    
5083              case OP_HSPACE:              case OP_HSPACE:
5084              switch(c)              switch(c)
5085                {                {
5086                  HSPACE_CASES: break;
5087                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;  
5088                }                }
5089              break;              break;
5090    
5091              case OP_NOT_VSPACE:              case OP_NOT_VSPACE:
5092              switch(c)              switch(c)
5093                {                {
5094                  VSPACE_CASES: RRETURN(MATCH_NOMATCH);
5095                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);  
5096                }                }
5097              break;              break;
5098    
5099              case OP_VSPACE:              case OP_VSPACE:
5100              switch(c)              switch(c)
5101                {                {
5102                  VSPACE_CASES: break;
5103                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;  
5104                }                }
5105              break;              break;
5106    
# Line 4919  for (;;) Line 5120  for (;;)
5120              break;              break;
5121    
5122              case OP_WHITESPACE:              case OP_WHITESPACE:
5123              if  (c >= 256 || (md->ctypes[c] & ctype_space) == 0)              if (c >= 256 || (md->ctypes[c] & ctype_space) == 0)
5124                RRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
5125              break;              break;
5126    
# Line 4940  for (;;) Line 5141  for (;;)
5141          }          }
5142        else        else
5143  #endif  #endif
5144        /* Not UTF-8 mode */        /* Not UTF mode */
5145          {          {
5146          for (fi = min;; fi++)          for (fi = min;; fi++)
5147            {            {
# Line 4957  for (;;) Line 5158  for (;;)
5158            c = *eptr++;            c = *eptr++;
5159            switch(ctype)            switch(ctype)
5160              {              {
5161              case OP_ANY:     /* This is the non-NL case */              case OP_ANY:               /* This is the non-NL case */
5162                if (md->partial != 0 &&    /* Take care with CRLF partial */
5163                    eptr >= md->end_subject &&
5164                    NLBLOCK->nltype == NLTYPE_FIXED &&
5165                    NLBLOCK->nllen == 2 &&
5166                    c == NLBLOCK->nl[0])
5167                  {
5168                  md->hitend = TRUE;
5169                  if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
5170                  }
5171                break;
5172    
5173              case OP_ALLANY:              case OP_ALLANY:
5174              case OP_ANYBYTE:              case OP_ANYBYTE:
5175              break;              break;
# Line 4966  for (;;) Line 5178  for (;;)
5178              switch(c)              switch(c)
5179                {                {
5180                default: RRETURN(MATCH_NOMATCH);                default: RRETURN(MATCH_NOMATCH);
5181                case 0x000d:                case CHAR_CR:
5182                if (eptr < md->end_subject && *eptr == 0x0a) eptr++;                if (eptr < md->end_subject && *eptr == CHAR_LF) eptr++;
5183                break;                break;
5184    
5185                case 0x000a:                case CHAR_LF:
5186                break;                break;
5187    
5188                case 0x000b:                case CHAR_VT:
5189                case 0x000c:                case CHAR_FF:
5190                case 0x0085:                case CHAR_NEL:
5191    #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
5192                  case 0x2028:
5193                  case 0x2029:
5194    #endif
5195                if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH);                if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH);
5196                break;                break;
5197                }                }
# Line 4985  for (;;) Line 5201  for (;;)
5201              switch(c)              switch(c)
5202                {                {
5203                default: break;                default: break;
5204                case 0x09:      /* HT */                HSPACE_BYTE_CASES:
5205                case 0x20:      /* SPACE */  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
5206                case 0xa0:      /* NBSP */                HSPACE_MULTIBYTE_CASES:
5207    #endif
5208                RRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
5209                }                }
5210              break;              break;
# Line 4996  for (;;) Line 5213  for (;;)
5213              switch(c)              switch(c)
5214                {                {
5215                default: RRETURN(MATCH_NOMATCH);                default: RRETURN(MATCH_NOMATCH);
5216                case 0x09:      /* HT */                HSPACE_BYTE_CASES:
5217                case 0x20:      /* SPACE */  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
5218                case 0xa0:      /* NBSP */                HSPACE_MULTIBYTE_CASES:
5219    #endif
5220                break;                break;
5221                }                }
5222              break;              break;
# Line 5007  for (;;) Line 5225  for (;;)
5225              switch(c)              switch(c)
5226                {                {
5227                default: break;                default: break;
5228                case 0x0a:      /* LF */                VSPACE_BYTE_CASES:
5229                case 0x0b:      /* VT */  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
5230                case 0x0c:      /* FF */                VSPACE_MULTIBYTE_CASES:
5231                case 0x0d:      /* CR */  #endif
               case 0x85:      /* NEL */  
5232                RRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
5233                }                }
5234              break;              break;
# Line 5020  for (;;) Line 5237  for (;;)
5237              switch(c)              switch(c)
5238                {                {
5239                default: RRETURN(MATCH_NOMATCH);                default: RRETURN(MATCH_NOMATCH);
5240                case 0x0a:      /* LF */                VSPACE_BYTE_CASES:
5241                case 0x0b:      /* VT */  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
5242                case 0x0c:      /* FF */                VSPACE_MULTIBYTE_CASES:
5243                case 0x0d:      /* CR */  #endif
               case 0x85:      /* NEL */  
5244                break;                break;
5245                }                }
5246              break;              break;
5247    
5248              case OP_NOT_DIGIT:              case OP_NOT_DIGIT:
5249              if ((md->ctypes[c] & ctype_digit) != 0) RRETURN(MATCH_NOMATCH);              if (MAX_255(c) && (md->ctypes[c] & ctype_digit) != 0) RRETURN(MATCH_NOMATCH);
5250              break;              break;
5251    
5252              case OP_DIGIT:              case OP_DIGIT:
5253              if ((md->ctypes[c] & ctype_digit) == 0) RRETURN(MATCH_NOMATCH);              if (!MAX_255(c) || (md->ctypes[c] & ctype_digit) == 0) RRETURN(MATCH_NOMATCH);
5254              break;              break;
5255    
5256              case OP_NOT_WHITESPACE:              case OP_NOT_WHITESPACE:
5257              if ((md->ctypes[c] & ctype_space) != 0) RRETURN(MATCH_NOMATCH);              if (MAX_255(c) && (md->ctypes[c] & ctype_space) != 0) RRETURN(MATCH_NOMATCH);
5258              break;              break;
5259    
5260              case OP_WHITESPACE:              case OP_WHITESPACE:
5261              if  ((md->ctypes[c] & ctype_space) == 0) RRETURN(MATCH_NOMATCH);              if (!MAX_255(c) || (md->ctypes[c] & ctype_space) == 0) RRETURN(MATCH_NOMATCH);
5262              break;              break;
5263    
5264              case OP_NOT_WORDCHAR:              case OP_NOT_WORDCHAR:
5265              if ((md->ctypes[c] & ctype_word) != 0) RRETURN(MATCH_NOMATCH);              if (MAX_255(c) && (md->ctypes[c] & ctype_word) != 0) RRETURN(MATCH_NOMATCH);
5266              break;              break;
5267    
5268              case OP_WORDCHAR:              case OP_WORDCHAR:
5269              if ((md->ctypes[c] & ctype_word) == 0) RRETURN(MATCH_NOMATCH);              if (!MAX_255(c) || (md->ctypes[c] & ctype_word) == 0) RRETURN(MATCH_NOMATCH);
5270              break;              break;
5271    
5272              default:              default:
# Line 5227  for (;;) Line 5443  for (;;)
5443              }              }
5444            break;            break;
5445    
5446              case PT_CLIST:
5447              for (i = min; i < max; i++)
5448                {
5449                const pcre_uint32 *cp;
5450                int len = 1;
5451                if (eptr >= md->end_subject)
5452                  {
5453                  SCHECK_PARTIAL();
5454                  break;
5455                  }
5456                GETCHARLENTEST(c, eptr, len);
5457                cp = PRIV(ucd_caseless_sets) + prop_value;
5458                for (;;)
5459                  {
5460                  if (c < *cp)
5461                    { if (prop_fail_result) break; else goto GOT_MAX; }
5462                  if (c == *cp++)
5463                    { if (prop_fail_result) goto GOT_MAX; else break; }
5464                  }
5465                eptr += len;
5466                }
5467              GOT_MAX:
5468              break;
5469    
5470            default:            default:
5471            RRETURN(PCRE_ERROR_INTERNAL);            RRETURN(PCRE_ERROR_INTERNAL);
5472            }            }
# Line 5239  for (;;) Line 5479  for (;;)
5479            RMATCH(eptr, ecode, offset_top, md, eptrb, RM44);            RMATCH(eptr, ecode, offset_top, md, eptrb, RM44);
5480            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
5481            if (eptr-- == pp) break;        /* Stop if tried at original pos */            if (eptr-- == pp) break;        /* Stop if tried at original pos */
5482            if (utf8) BACKCHAR(eptr);            if (utf) BACKCHAR(eptr);
5483            }            }
5484          }          }
5485    
# Line 5250  for (;;) Line 5490  for (;;)
5490          {          {
5491          for (i = min; i < max; i++)          for (i = min; i < max; i++)
5492            {            {
           int len = 1;  
5493            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
5494              {              {
5495              SCHECK_PARTIAL();              SCHECK_PARTIAL();
5496              break;              break;
5497              }              }
5498            if (!utf8) c = *eptr; else { GETCHARLEN(c, eptr, len); }            else
           if (UCD_CATEGORY(c) == ucp_M) break;  
           eptr += len;  
           while (eptr < md->end_subject)  
5499              {              {
5500              len = 1;              int lgb, rgb;
5501              if (!utf8) c = *eptr; else { GETCHARLEN(c, eptr, len); }              GETCHARINCTEST(c, eptr);
5502              if (UCD_CATEGORY(c) != ucp_M) break;              lgb = UCD_GRAPHBREAK(c);
5503              eptr += len;              while (eptr < md->end_subject)
5504                  {
5505                  int len = 1;
5506                  if (!utf) c = *eptr; else { GETCHARLEN(c, eptr, len); }
5507                  rgb = UCD_GRAPHBREAK(c);
5508                  if ((PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0) break;
5509                  lgb = rgb;
5510                  eptr += len;
5511                  }
5512              }              }
5513              CHECK_PARTIAL();
5514            }            }
5515    
5516          /* eptr is now past the end of the maximum run */          /* eptr is now past the end of the maximum run */
# Line 5279  for (;;) Line 5524  for (;;)
5524            if (eptr-- == pp) break;        /* Stop if tried at original pos */            if (eptr-- == pp) break;        /* Stop if tried at original pos */
5525            for (;;)                        /* Move back over one extended */            for (;;)                        /* Move back over one extended */
5526              {              {
5527              if (!utf8) c = *eptr; else              if (!utf) c = *eptr; else
5528                {                {
5529                BACKCHAR(eptr);                BACKCHAR(eptr);
5530                GETCHAR(c, eptr);                GETCHAR(c, eptr);
# Line 5293  for (;;) Line 5538  for (;;)
5538        else        else
5539  #endif   /* SUPPORT_UCP */  #endif   /* SUPPORT_UCP */
5540    
5541  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
5542        /* UTF-8 mode */        if (utf)
   
       if (utf8)  
5543          {          {
5544          switch(ctype)          switch(ctype)
5545            {            {
# Line 5311  for (;;) Line 5554  for (;;)
5554                  break;                  break;
5555                  }                  }
5556                if (IS_NEWLINE(eptr)) break;                if (IS_NEWLINE(eptr)) break;
5557                  if (md->partial != 0 &&    /* Take care with CRLF partial */
5558                      eptr + 1 >= md->end_subject &&
5559                      NLBLOCK->nltype == NLTYPE_FIXED &&
5560                      NLBLOCK->nllen == 2 &&
5561                      RAWUCHAR(eptr) == NLBLOCK->nl[0])
5562                    {
5563                    md->hitend = TRUE;
5564                    if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
5565                    }
5566                eptr++;                eptr++;
5567                while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;                ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
5568                }                }
5569              }              }
5570    
# Line 5328  for (;;) Line 5580  for (;;)
5580                  break;                  break;
5581                  }                  }
5582                if (IS_NEWLINE(eptr)) break;                if (IS_NEWLINE(eptr)) break;
5583                  if (md->partial != 0 &&    /* Take care with CRLF partial */
5584                      eptr + 1 >= md->end_subject &&
5585                      NLBLOCK->nltype == NLTYPE_FIXED &&
5586                      NLBLOCK->nllen == 2 &&
5587                      RAWUCHAR(eptr) == NLBLOCK->nl[0])
5588                    {
5589                    md->hitend = TRUE;
5590                    if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
5591                    }
5592                eptr++;                eptr++;
5593                while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;                ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
5594                }                }
5595              }              }
5596            break;            break;
# Line 5345  for (;;) Line 5606  for (;;)
5606                  break;                  break;
5607                  }                  }
5608                eptr++;                eptr++;
5609                while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;                ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
5610                }                }
5611              }              }
5612            else            else
# Line 5377  for (;;) Line 5638  for (;;)
5638                break;                break;
5639                }                }
5640              GETCHARLEN(c, eptr, len);              GETCHARLEN(c, eptr, len);
5641              if (c == 0x000d)              if (c == CHAR_CR)
5642                {                {
5643                if (++eptr >= md->end_subject) break;                if (++eptr >= md->end_subject) break;
5644                if (*eptr == 0x000a) eptr++;                if (RAWUCHAR(eptr) == CHAR_LF) eptr++;
5645                }                }
5646              else              else
5647                {                {
5648                if (c != 0x000a &&                if (c != CHAR_LF &&
5649                    (md->bsr_anycrlf ||                    (md->bsr_anycrlf ||
5650                     (c != 0x000b && c != 0x000c &&                     (c != CHAR_VT && c != CHAR_FF && c != CHAR_NEL
5651                      c != 0x0085 && c != 0x2028 && c != 0x2029)))  #ifndef EBCDIC
5652                        && c != 0x2028 && c != 0x2029
5653    #endif  /* Not EBCDIC */
5654                        )))
5655                  break;                  break;
5656                eptr += len;                eptr += len;
5657                }                }
# Line 5408  for (;;) Line 5672  for (;;)
5672              GETCHARLEN(c, eptr, len);              GETCHARLEN(c, eptr, len);
5673              switch(c)              switch(c)
5674                {                {
5675                  HSPACE_CASES: gotspace = TRUE; break;
5676                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;  
5677                }                }
5678              if (gotspace == (ctype == OP_NOT_HSPACE)) break;              if (gotspace == (ctype == OP_NOT_HSPACE)) break;
5679              eptr += len;              eptr += len;
# Line 5450  for (;;) Line 5694  for (;;)
5694              GETCHARLEN(c, eptr, len);              GETCHARLEN(c, eptr, len);
5695              switch(c)              switch(c)
5696                {                {
5697                  VSPACE_CASES: gotspace = TRUE; break;
5698                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;  
5699                }                }
5700              if (gotspace == (ctype == OP_NOT_VSPACE)) break;              if (gotspace == (ctype == OP_NOT_VSPACE)) break;
5701              eptr += len;              eptr += len;
# Line 5573  for (;;) Line 5809  for (;;)
5809            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
5810            if (eptr-- == pp) break;        /* Stop if tried at original pos */            if (eptr-- == pp) break;        /* Stop if tried at original pos */
5811            BACKCHAR(eptr);            BACKCHAR(eptr);
5812            if (ctype == OP_ANYNL && eptr > pp  && *eptr == '\n' &&            if (ctype == OP_ANYNL && eptr > pp  && RAWUCHAR(eptr) == CHAR_NL &&
5813                eptr[-1] == '\r') eptr--;                RAWUCHAR(eptr - 1) == CHAR_CR) eptr--;
5814            }            }
5815          }          }
5816        else        else
5817  #endif  /* SUPPORT_UTF8 */  #endif  /* SUPPORT_UTF */
5818          /* Not UTF mode */
       /* Not UTF-8 mode */  
5819          {          {
5820          switch(ctype)          switch(ctype)
5821            {            {
# Line 5593  for (;;) Line 5828  for (;;)
5828                break;                break;
5829                }                }
5830              if (IS_NEWLINE(eptr)) break;              if (IS_NEWLINE(eptr)) break;
5831                if (md->partial != 0 &&    /* Take care with CRLF partial */
5832                    eptr + 1 >= md->end_subject &&
5833                    NLBLOCK->nltype == NLTYPE_FIXED &&
5834                    NLBLOCK->nllen == 2 &&
5835                    *eptr == NLBLOCK->nl[0])
5836                  {
5837                  md->hitend = TRUE;
5838                  if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
5839                  }
5840              eptr++;              eptr++;
5841              }              }
5842            break;            break;
# Line 5617  for (;;) Line 5861  for (;;)
5861                break;                break;
5862                }                }
5863              c = *eptr;              c = *eptr;
5864              if (c == 0x000d)              if (c == CHAR_CR)
5865                {                {
5866                if (++eptr >= md->end_subject) break;                if (++eptr >= md->end_subject) break;
5867                if (*eptr == 0x000a) eptr++;                if (*eptr == CHAR_LF) eptr++;
5868                }                }
5869              else              else
5870                {                {
5871                if (c != 0x000a &&                if (c != CHAR_LF && (md->bsr_anycrlf ||
5872                    (md->bsr_anycrlf ||                   (c != CHAR_VT && c != CHAR_FF && c != CHAR_NEL
5873                      (c != 0x000b && c != 0x000c && c != 0x0085)))  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
5874                  break;                   && c != 0x2028 && c != 0x2029
5875    #endif
5876                     ))) break;
5877                eptr++;                eptr++;
5878                }                }
5879              }              }
# Line 5641  for (;;) Line 5887  for (;;)
5887                SCHECK_PARTIAL();                SCHECK_PARTIAL();
5888                break;                break;
5889                }                }
5890              c = *eptr;              switch(*eptr)
5891              if (c == 0x09 || c == 0x20 || c == 0xa0) break;                {
5892              eptr++;                default: eptr++; break;
5893                  HSPACE_BYTE_CASES:
5894    #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
5895                  HSPACE_MULTIBYTE_CASES:
5896    #endif
5897                  goto ENDLOOP00;
5898                  }
5899              }              }
5900              ENDLOOP00:
5901            break;            break;
5902    
5903            case OP_HSPACE:            case OP_HSPACE:
# Line 5655  for (;;) Line 5908  for (;;)
5908                SCHECK_PARTIAL();                SCHECK_PARTIAL();
5909                break;                break;
5910                }                }
5911              c = *eptr;              switch(*eptr)
5912              if (c != 0x09 && c != 0x20 && c != 0xa0) break;                {
5913              eptr++;                default: goto ENDLOOP01;
5914                  HSPACE_BYTE_CASES:
5915    #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
5916                  HSPACE_MULTIBYTE_CASES:
5917    #endif
5918                  eptr++; break;
5919                  }
5920              }              }
5921              ENDLOOP01:
5922            break;            break;
5923    
5924            case OP_NOT_VSPACE:            case OP_NOT_VSPACE:
# Line 5669  for (;;) Line 5929  for (;;)
5929                SCHECK_PARTIAL();                SCHECK_PARTIAL();
5930                break;                break;
5931                }                }
5932              c = *eptr;              switch(*eptr)
5933              if (c == 0x0a || c == 0x0b || c == 0x0c || c == 0x0d || c == 0x85)                {
5934                break;                default: eptr++; break;
5935              eptr++;                VSPACE_BYTE_CASES:
5936    #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
5937                  VSPACE_MULTIBYTE_CASES:
5938    #endif
5939                  goto ENDLOOP02;
5940                  }
5941              }              }
5942              ENDLOOP02:
5943            break;            break;
5944    
5945            case OP_VSPACE:            case OP_VSPACE:
# Line 5684  for (;;) Line 5950