/[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 172 by ph10, Tue Jun 5 10:40:13 2007 UTC revision 500 by ph10, Sat Mar 6 19:00:29 2010 UTC
# Line 6  Line 6 
6  and semantics are as close as possible to those of the Perl 5 language.  and semantics are as close as possible to those of the Perl 5 language.
7    
8                         Written by Philip Hazel                         Written by Philip Hazel
9             Copyright (c) 1997-2007 University of Cambridge             Copyright (c) 1997-2010 University of Cambridge
10    
11  -----------------------------------------------------------------------------  -----------------------------------------------------------------------------
12  Redistribution and use in source and binary forms, with or without  Redistribution and use in source and binary forms, with or without
# Line 42  POSSIBILITY OF SUCH DAMAGE. Line 42  POSSIBILITY OF SUCH DAMAGE.
42  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
43  possible. There are also some static supporting functions. */  possible. There are also some static supporting functions. */
44    
45    #ifdef HAVE_CONFIG_H
46    #include "config.h"
47    #endif
48    
49  #define NLBLOCK md             /* Block containing newline information */  #define NLBLOCK md             /* Block containing newline information */
50  #define PSSTART start_subject  /* Field containing processed string start */  #define PSSTART start_subject  /* Field containing processed string start */
51  #define PSEND   end_subject    /* Field containing processed string end */  #define PSEND   end_subject    /* Field containing processed string end */
# Line 53  possible. There are also some static sup Line 57  possible. There are also some static sup
57  #undef min  #undef min
58  #undef max  #undef max
59    
 /* The chain of eptrblocks for tail recursions uses memory in stack workspace,  
 obtained at top level, the size of which is defined by EPTR_WORK_SIZE. */  
   
 #define EPTR_WORK_SIZE (1000)  
   
60  /* Flag bits for the match() function */  /* Flag bits for the match() function */
61    
62  #define match_condassert     0x01  /* Called to check a condition assertion */  #define match_condassert     0x01  /* Called to check a condition assertion */
63  #define match_cbegroup       0x02  /* Could-be-empty unlimited repeat group */  #define match_cbegroup       0x02  /* Could-be-empty unlimited repeat group */
 #define match_tail_recursed  0x04  /* Tail recursive call */  
64    
65  /* Non-error returns from the match() function. Error returns are externally  /* Non-error returns from the match() function. Error returns are externally
66  defined PCRE_ERROR_xxx codes, which are all negative. */  defined PCRE_ERROR_xxx codes, which are all negative. */
# Line 70  defined PCRE_ERROR_xxx codes, which are Line 68  defined PCRE_ERROR_xxx codes, which are
68  #define MATCH_MATCH        1  #define MATCH_MATCH        1
69  #define MATCH_NOMATCH      0  #define MATCH_NOMATCH      0
70    
71    /* Special internal returns from the match() function. Make them sufficiently
72    negative to avoid the external error codes. */
73    
74    #define MATCH_COMMIT       (-999)
75    #define MATCH_PRUNE        (-998)
76    #define MATCH_SKIP         (-997)
77    #define MATCH_THEN         (-996)
78    
79  /* Maximum number of ints of offset to save on the stack for recursive calls.  /* Maximum number of ints of offset to save on the stack for recursive calls.
80  If the offset vector is bigger, malloc is used. This should be a multiple of 3,  If the offset vector is bigger, malloc is used. This should be a multiple of 3,
81  because the offset vector is always a multiple of 3 long. */  because the offset vector is always a multiple of 3 long. */
# Line 83  static const char rep_max[] = { 0, 0, 0, Line 89  static const char rep_max[] = { 0, 0, 0,
89    
90    
91    
92  #ifdef DEBUG  #ifdef PCRE_DEBUG
93  /*************************************************  /*************************************************
94  *        Debugging function to print chars       *  *        Debugging function to print chars       *
95  *************************************************/  *************************************************/
# Line 135  match_ref(int offset, register USPTR ept Line 141  match_ref(int offset, register USPTR ept
141  {  {
142  USPTR p = md->start_subject + md->offset_vector[offset];  USPTR p = md->start_subject + md->offset_vector[offset];
143    
144  #ifdef DEBUG  #ifdef PCRE_DEBUG
145  if (eptr >= md->end_subject)  if (eptr >= md->end_subject)
146    printf("matching subject <null>");    printf("matching subject <null>");
147  else  else
# Line 152  printf("\n"); Line 158  printf("\n");
158    
159  if (length > md->end_subject - eptr) return FALSE;  if (length > md->end_subject - eptr) return FALSE;
160    
161  /* Separate the caselesss case for speed */  /* Separate the caseless case for speed. In UTF-8 mode we can only do this
162    properly if Unicode properties are supported. Otherwise, we can check only
163    ASCII characters. */
164    
165  if ((ims & PCRE_CASELESS) != 0)  if ((ims & PCRE_CASELESS) != 0)
166    {    {
167    #ifdef SUPPORT_UTF8
168    #ifdef SUPPORT_UCP
169      if (md->utf8)
170        {
171        USPTR endptr = eptr + length;
172        while (eptr < endptr)
173          {
174          int c, d;
175          GETCHARINC(c, eptr);
176          GETCHARINC(d, p);
177          if (c != d && c != UCD_OTHERCASE(d)) return FALSE;
178          }
179        }
180      else
181    #endif
182    #endif
183    
184      /* The same code works when not in UTF-8 mode and in UTF-8 mode when there
185      is no UCP support. */
186    
187    while (length-- > 0)    while (length-- > 0)
188      if (md->lcc[*p++] != md->lcc[*eptr++]) return FALSE;      { if (md->lcc[*p++] != md->lcc[*eptr++]) return FALSE; }
189    }    }
190    
191    /* In the caseful case, we can just compare the bytes, whether or not we
192    are in UTF-8 mode. */
193    
194  else  else
195    { while (length-- > 0) if (*p++ != *eptr++) return FALSE; }    { while (length-- > 0) if (*p++ != *eptr++) return FALSE; }
196    
# Line 205  variable instead of being passed in the Line 237  variable instead of being passed in the
237  ****************************************************************************  ****************************************************************************
238  ***************************************************************************/  ***************************************************************************/
239    
240    /* Numbers for RMATCH calls. When this list is changed, the code at HEAP_RETURN
241  /* Numbers for RMATCH calls */  below must be updated in sync.  */
242    
243  enum { RM1=1, RM2,  RM3,  RM4,  RM5,  RM6,  RM7,  RM8,  RM9,  RM10,  enum { RM1=1, RM2,  RM3,  RM4,  RM5,  RM6,  RM7,  RM8,  RM9,  RM10,
244         RM11,  RM12, RM13, RM14, RM15, RM16, RM17, RM18, RM19, RM20,         RM11,  RM12, RM13, RM14, RM15, RM16, RM17, RM18, RM19, RM20,
245         RM21,  RM22, RM23, RM24, RM25, RM26, RM27, RM28, RM29, RM30,         RM21,  RM22, RM23, RM24, RM25, RM26, RM27, RM28, RM29, RM30,
246         RM31,  RM32, RM33, RM34, RM35, RM36, RM37, RM38, RM39, RM40,         RM31,  RM32, RM33, RM34, RM35, RM36, RM37, RM38, RM39, RM40,
247         RM41,  RM42, RM43, RM44, RM45, RM46, RM47 };         RM41,  RM42, RM43, RM44, RM45, RM46, RM47, RM48, RM49, RM50,
248           RM51,  RM52, RM53, RM54 };
249    
250  /* 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
251  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 222  actuall used in this definition. */ Line 254  actuall used in this definition. */
254  #ifndef NO_RECURSE  #ifndef NO_RECURSE
255  #define REGISTER register  #define REGISTER register
256    
257  #ifdef DEBUG  #ifdef PCRE_DEBUG
258  #define RMATCH(ra,rb,rc,rd,re,rf,rg,rw) \  #define RMATCH(ra,rb,rc,rd,re,rf,rg,rw) \
259    { \    { \
260    printf("match() called in line %d\n", __LINE__); \    printf("match() called in line %d\n", __LINE__); \
# Line 290  typedef struct heapframe { Line 322  typedef struct heapframe {
322    
323    /* Function arguments that may change */    /* Function arguments that may change */
324    
325    const uschar *Xeptr;    USPTR Xeptr;
326    const uschar *Xecode;    const uschar *Xecode;
327    const uschar *Xmstart;    USPTR Xmstart;
328    int Xoffset_top;    int Xoffset_top;
329    long int Xims;    long int Xims;
330    eptrblock *Xeptrb;    eptrblock *Xeptrb;
# Line 301  typedef struct heapframe { Line 333  typedef struct heapframe {
333    
334    /* Function local variables */    /* Function local variables */
335    
336    const uschar *Xcallpat;    USPTR Xcallpat;
337    const uschar *Xcharptr;  #ifdef SUPPORT_UTF8
338    const uschar *Xdata;    USPTR Xcharptr;
339    const uschar *Xnext;  #endif
340    const uschar *Xpp;    USPTR Xdata;
341    const uschar *Xprev;    USPTR Xnext;
342    const uschar *Xsaved_eptr;    USPTR Xpp;
343      USPTR Xprev;
344      USPTR Xsaved_eptr;
345    
346    recursion_info Xnew_recursive;    recursion_info Xnew_recursive;
347    
# Line 328  typedef struct heapframe { Line 362  typedef struct heapframe {
362    uschar Xocchars[8];    uschar Xocchars[8];
363  #endif  #endif
364    
365      int Xcodelink;
366    int Xctype;    int Xctype;
367    unsigned int Xfc;    unsigned int Xfc;
368    int Xfi;    int Xfi;
# Line 363  typedef struct heapframe { Line 398  typedef struct heapframe {
398    
399  /* This function is called recursively in many circumstances. Whenever it  /* This function is called recursively in many circumstances. Whenever it
400  returns a negative (error) response, the outer incarnation must also return the  returns a negative (error) response, the outer incarnation must also return the
401  same response.  same response. */
402    
403    /* These macros pack up tests that are used for partial matching, and which
404    appears several times in the code. We set the "hit end" flag if the pointer is
405    at the end of the subject and also past the start of the subject (i.e.
406    something has been matched). For hard partial matching, we then return
407    immediately. The second one is used when we already know we are past the end of
408    the subject. */
409    
410  Performance note: It might be tempting to extract commonly used fields from the  #define CHECK_PARTIAL()\
411  md structure (e.g. utf8, end_subject) into individual variables to improve    if (md->partial != 0 && eptr >= md->end_subject && eptr > mstart)\
412        {\
413        md->hitend = TRUE;\
414        if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);\
415        }
416    
417    #define SCHECK_PARTIAL()\
418      if (md->partial != 0 && eptr > mstart)\
419        {\
420        md->hitend = TRUE;\
421        if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);\
422        }
423    
424    
425    /* Performance note: It might be tempting to extract commonly used fields from
426    the md structure (e.g. utf8, end_subject) into individual variables to improve
427  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
428  made performance worse.  made performance worse.
429    
# Line 384  Arguments: Line 441  Arguments:
441                   match_condassert - this is an assertion condition                   match_condassert - this is an assertion condition
442                   match_cbegroup - this is the start of an unlimited repeat                   match_cbegroup - this is the start of an unlimited repeat
443                     group that can match an empty string                     group that can match an empty string
                  match_tail_recursed - this is a tail_recursed group  
444     rdepth      the recursion depth     rdepth      the recursion depth
445    
446  Returns:       MATCH_MATCH if matched            )  these values are >= 0  Returns:       MATCH_MATCH if matched            )  these values are >= 0
# Line 394  Returns:       MATCH_MATCH if matched Line 450  Returns:       MATCH_MATCH if matched
450  */  */
451    
452  static int  static int
453  match(REGISTER USPTR eptr, REGISTER const uschar *ecode, const uschar *mstart,  match(REGISTER USPTR eptr, REGISTER const uschar *ecode, USPTR mstart,
454    int offset_top, match_data *md, unsigned long int ims, eptrblock *eptrb,    int offset_top, match_data *md, unsigned long int ims, eptrblock *eptrb,
455    int flags, unsigned int rdepth)    int flags, unsigned int rdepth)
456  {  {
# Line 408  register unsigned int c;   /* Character Line 464  register unsigned int c;   /* Character
464  register BOOL utf8;        /* Local copy of UTF-8 flag for speed */  register BOOL utf8;        /* Local copy of UTF-8 flag for speed */
465    
466  BOOL minimize, possessive; /* Quantifier options */  BOOL minimize, possessive; /* Quantifier options */
467    int condcode;
468    
469  /* 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
470  preserved over calls to RMATCH() are part of a "frame" which is obtained from  preserved over calls to RMATCH() are part of a "frame" which is obtained from
# Line 450  HEAP_RECURSE: Line 507  HEAP_RECURSE:
507  #define charptr            frame->Xcharptr  #define charptr            frame->Xcharptr
508  #endif  #endif
509  #define callpat            frame->Xcallpat  #define callpat            frame->Xcallpat
510    #define codelink           frame->Xcodelink
511  #define data               frame->Xdata  #define data               frame->Xdata
512  #define next               frame->Xnext  #define next               frame->Xnext
513  #define pp                 frame->Xpp  #define pp                 frame->Xpp
# Line 530  int oclength; Line 588  int oclength;
588  uschar occhars[8];  uschar occhars[8];
589  #endif  #endif
590    
591    int codelink;
592  int ctype;  int ctype;
593  int length;  int length;
594  int max;  int max;
# Line 563  TAIL_RECURSE: Line 622  TAIL_RECURSE:
622  /* OK, now we can get on with the real code of the function. Recursive calls  /* OK, now we can get on with the real code of the function. Recursive calls
623  are specified by the macro RMATCH and RRETURN is used to return. When  are specified by the macro RMATCH and RRETURN is used to return. When
624  NO_RECURSE is *not* defined, these just turn into a recursive call to match()  NO_RECURSE is *not* defined, these just turn into a recursive call to match()
625  and a "return", respectively (possibly with some debugging if DEBUG is  and a "return", respectively (possibly with some debugging if PCRE_DEBUG is
626  defined). However, RMATCH isn't like a function call because it's quite a  defined). However, RMATCH isn't like a function call because it's quite a
627  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,
628  however, impact performance when true recursion is being used. */  however, impact performance when true recursion is being used. */
# Line 586  original_ims = ims;    /* Save for reset Line 645  original_ims = ims;    /* Save for reset
645  string, the match_cbegroup flag is set. When this is the case, add the current  string, the match_cbegroup flag is set. When this is the case, add the current
646  subject pointer to the chain of such remembered pointers, to be checked when we  subject pointer to the chain of such remembered pointers, to be checked when we
647  hit the closing ket, in order to break infinite loops that match no characters.  hit the closing ket, in order to break infinite loops that match no characters.
648  When match() is called in other circumstances, don't add to the chain. If this  When match() is called in other circumstances, don't add to the chain. The
649  is a tail recursion, use a block from the workspace, as the one on the stack is  match_cbegroup flag must NOT be used with tail recursion, because the memory
650  already used. */  block that is used is on the stack, so a new one may be required for each
651    match(). */
652    
653  if ((flags & match_cbegroup) != 0)  if ((flags & match_cbegroup) != 0)
654    {    {
655    eptrblock *p;    newptrb.epb_saved_eptr = eptr;
656    if ((flags & match_tail_recursed) != 0)    newptrb.epb_prev = eptrb;
657      {    eptrb = &newptrb;
     if (md->eptrn >= EPTR_WORK_SIZE) RRETURN(PCRE_ERROR_NULLWSLIMIT);  
     p = md->eptrchain + md->eptrn++;  
     }  
   else p = &newptrb;  
   p->epb_saved_eptr = eptr;  
   p->epb_prev = eptrb;  
   eptrb = p;  
658    }    }
659    
660  /* Now start processing the opcodes. */  /* Now start processing the opcodes. */
# Line 611  for (;;) Line 664  for (;;)
664    minimize = possessive = FALSE;    minimize = possessive = FALSE;
665    op = *ecode;    op = *ecode;
666    
   /* For partial matching, remember if we ever hit the end of the subject after  
   matching at least one subject character. */  
   
   if (md->partial &&  
       eptr >= md->end_subject &&  
       eptr > mstart)  
     md->hitend = TRUE;  
   
667    switch(op)    switch(op)
668      {      {
669        case OP_FAIL:
670        RRETURN(MATCH_NOMATCH);
671    
672        case OP_PRUNE:
673        RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,
674          ims, eptrb, flags, RM51);
675        if (rrc != MATCH_NOMATCH) RRETURN(rrc);
676        RRETURN(MATCH_PRUNE);
677    
678        case OP_COMMIT:
679        RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,
680          ims, eptrb, flags, RM52);
681        if (rrc != MATCH_NOMATCH) RRETURN(rrc);
682        RRETURN(MATCH_COMMIT);
683    
684        case OP_SKIP:
685        RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,
686          ims, eptrb, flags, RM53);
687        if (rrc != MATCH_NOMATCH) RRETURN(rrc);
688        md->start_match_ptr = eptr;   /* Pass back current position */
689        RRETURN(MATCH_SKIP);
690    
691        case OP_THEN:
692        RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,
693          ims, eptrb, flags, RM54);
694        if (rrc != MATCH_NOMATCH) RRETURN(rrc);
695        RRETURN(MATCH_THEN);
696    
697      /* Handle a capturing bracket. If there is space in the offset vector, save      /* Handle a capturing bracket. If there is space in the offset vector, save
698      the current subject position in the working slot at the top of the vector.      the current subject position in the working slot at the top of the vector.
699      We mustn't change the current values of the data slot, because they may be      We mustn't change the current values of the data slot, because they may be
# Line 640  for (;;) Line 713  for (;;)
713      number = GET2(ecode, 1+LINK_SIZE);      number = GET2(ecode, 1+LINK_SIZE);
714      offset = number << 1;      offset = number << 1;
715    
716  #ifdef DEBUG  #ifdef PCRE_DEBUG
717      printf("start bracket %d\n", number);      printf("start bracket %d\n", number);
718      printf("subject=");      printf("subject=");
719      pchars(eptr, 16, TRUE, md);      pchars(eptr, 16, TRUE, md);
# Line 662  for (;;) Line 735  for (;;)
735          {          {
736          RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,          RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,
737            ims, eptrb, flags, RM1);            ims, eptrb, flags, RM1);
738          if (rrc != MATCH_NOMATCH) RRETURN(rrc);          if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);
739          md->capture_last = save_capture_last;          md->capture_last = save_capture_last;
740          ecode += GET(ecode, 1);          ecode += GET(ecode, 1);
741          }          }
# Line 677  for (;;) Line 750  for (;;)
750        RRETURN(MATCH_NOMATCH);        RRETURN(MATCH_NOMATCH);
751        }        }
752    
753      /* Insufficient room for saving captured contents. Treat as a non-capturing      /* FALL THROUGH ... Insufficient room for saving captured contents. Treat
754      bracket. */      as a non-capturing bracket. */
755    
756        /* VVVVVVVVVVVVVVVVVVVVVVVVV */
757        /* VVVVVVVVVVVVVVVVVVVVVVVVV */
758    
759      DPRINTF(("insufficient capture room: treat as non-capturing\n"));      DPRINTF(("insufficient capture room: treat as non-capturing\n"));
760    
761        /* VVVVVVVVVVVVVVVVVVVVVVVVV */
762        /* VVVVVVVVVVVVVVVVVVVVVVVVV */
763    
764      /* Non-capturing bracket. Loop for all the alternatives. When we get to the      /* Non-capturing bracket. Loop for all the alternatives. When we get to the
765      final alternative within the brackets, we would return the result of a      final alternative within the brackets, we would return the result of a
766      recursive call to match() whatever happened. We can reduce stack usage by      recursive call to match() whatever happened. We can reduce stack usage by
767      turning this into a tail recursion. */      turning this into a tail recursion, except in the case when match_cbegroup
768        is set.*/
769    
770      case OP_BRA:      case OP_BRA:
771      case OP_SBRA:      case OP_SBRA:
# Line 693  for (;;) Line 773  for (;;)
773      flags = (op >= OP_SBRA)? match_cbegroup : 0;      flags = (op >= OP_SBRA)? match_cbegroup : 0;
774      for (;;)      for (;;)
775        {        {
776        if (ecode[GET(ecode, 1)] != OP_ALT)        if (ecode[GET(ecode, 1)] != OP_ALT)   /* Final alternative */
777          {          {
778          ecode += _pcre_OP_lengths[*ecode];          if (flags == 0)    /* Not a possibly empty group */
779          flags |= match_tail_recursed;            {
780          DPRINTF(("bracket 0 tail recursion\n"));            ecode += _pcre_OP_lengths[*ecode];
781          goto TAIL_RECURSE;            DPRINTF(("bracket 0 tail recursion\n"));
782              goto TAIL_RECURSE;
783              }
784    
785            /* Possibly empty group; can't use tail recursion. */
786    
787            RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md, ims,
788              eptrb, flags, RM48);
789            RRETURN(rrc);
790          }          }
791    
792        /* For non-final alternatives, continue the loop for a NOMATCH result;        /* For non-final alternatives, continue the loop for a NOMATCH result;
# Line 706  for (;;) Line 794  for (;;)
794    
795        RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md, ims,        RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md, ims,
796          eptrb, flags, RM2);          eptrb, flags, RM2);
797        if (rrc != MATCH_NOMATCH) RRETURN(rrc);        if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);
798        ecode += GET(ecode, 1);        ecode += GET(ecode, 1);
799        }        }
800      /* Control never reaches here. */      /* Control never reaches here. */
# Line 719  for (;;) Line 807  for (;;)
807    
808      case OP_COND:      case OP_COND:
809      case OP_SCOND:      case OP_SCOND:
810      if (ecode[LINK_SIZE+1] == OP_RREF)         /* Recursion test */      codelink= GET(ecode, 1);
811    
812        /* Because of the way auto-callout works during compile, a callout item is
813        inserted between OP_COND and an assertion condition. */
814    
815        if (ecode[LINK_SIZE+1] == OP_CALLOUT)
816        {        {
817        offset = GET2(ecode, LINK_SIZE + 2);     /* Recursion group number*/        if (pcre_callout != NULL)
818        condition = md->recursive != NULL &&          {
819          (offset == RREF_ANY || offset == md->recursive->group_num);          pcre_callout_block cb;
820        ecode += condition? 3 : GET(ecode, 1);          cb.version          = 1;   /* Version 1 of the callout block */
821            cb.callout_number   = ecode[LINK_SIZE+2];
822            cb.offset_vector    = md->offset_vector;
823            cb.subject          = (PCRE_SPTR)md->start_subject;
824            cb.subject_length   = md->end_subject - md->start_subject;
825            cb.start_match      = mstart - md->start_subject;
826            cb.current_position = eptr - md->start_subject;
827            cb.pattern_position = GET(ecode, LINK_SIZE + 3);
828            cb.next_item_length = GET(ecode, 3 + 2*LINK_SIZE);
829            cb.capture_top      = offset_top/2;
830            cb.capture_last     = md->capture_last;
831            cb.callout_data     = md->callout_data;
832            if ((rrc = (*pcre_callout)(&cb)) > 0) RRETURN(MATCH_NOMATCH);
833            if (rrc < 0) RRETURN(rrc);
834            }
835          ecode += _pcre_OP_lengths[OP_CALLOUT];
836          }
837    
838        condcode = ecode[LINK_SIZE+1];
839    
840        /* Now see what the actual condition is */
841    
842        if (condcode == OP_RREF || condcode == OP_NRREF)    /* Recursion test */
843          {
844          if (md->recursive == NULL)                /* Not recursing => FALSE */
845            {
846            condition = FALSE;
847            ecode += GET(ecode, 1);
848            }
849          else
850            {
851            int recno = GET2(ecode, LINK_SIZE + 2);   /* Recursion group number*/
852            condition =  (recno == RREF_ANY || recno == md->recursive->group_num);
853    
854            /* If the test is for recursion into a specific subpattern, and it is
855            false, but the test was set up by name, scan the table to see if the
856            name refers to any other numbers, and test them. The condition is true
857            if any one is set. */
858    
859            if (!condition && condcode == OP_NRREF && recno != RREF_ANY)
860              {
861              uschar *slotA = md->name_table;
862              for (i = 0; i < md->name_count; i++)
863                {
864                if (GET2(slotA, 0) == recno) break;
865                slotA += md->name_entry_size;
866                }
867    
868              /* Found a name for the number - there can be only one; duplicate
869              names for different numbers are allowed, but not vice versa. First
870              scan down for duplicates. */
871    
872              if (i < md->name_count)
873                {
874                uschar *slotB = slotA;
875                while (slotB > md->name_table)
876                  {
877                  slotB -= md->name_entry_size;
878                  if (strcmp((char *)slotA + 2, (char *)slotB + 2) == 0)
879                    {
880                    condition = GET2(slotB, 0) == md->recursive->group_num;
881                    if (condition) break;
882                    }
883                  else break;
884                  }
885    
886                /* Scan up for duplicates */
887    
888                if (!condition)
889                  {
890                  slotB = slotA;
891                  for (i++; i < md->name_count; i++)
892                    {
893                    slotB += md->name_entry_size;
894                    if (strcmp((char *)slotA + 2, (char *)slotB + 2) == 0)
895                      {
896                      condition = GET2(slotB, 0) == md->recursive->group_num;
897                      if (condition) break;
898                      }
899                    else break;
900                    }
901                  }
902                }
903              }
904    
905            /* Chose branch according to the condition */
906    
907            ecode += condition? 3 : GET(ecode, 1);
908            }
909        }        }
910    
911      else if (ecode[LINK_SIZE+1] == OP_CREF)    /* Group used test */      else if (condcode == OP_CREF || condcode == OP_NCREF)  /* Group used test */
912        {        {
913        offset = GET2(ecode, LINK_SIZE+2) << 1;  /* Doubled ref number */        offset = GET2(ecode, LINK_SIZE+2) << 1;  /* Doubled ref number */
914        condition = offset < offset_top && md->offset_vector[offset] >= 0;        condition = offset < offset_top && md->offset_vector[offset] >= 0;
915    
916          /* If the numbered capture is unset, but the reference was by name,
917          scan the table to see if the name refers to any other numbers, and test
918          them. The condition is true if any one is set. This is tediously similar
919          to the code above, but not close enough to try to amalgamate. */
920    
921          if (!condition && condcode == OP_NCREF)
922            {
923            int refno = offset >> 1;
924            uschar *slotA = md->name_table;
925    
926            for (i = 0; i < md->name_count; i++)
927              {
928              if (GET2(slotA, 0) == refno) break;
929              slotA += md->name_entry_size;
930              }
931    
932            /* Found a name for the number - there can be only one; duplicate names
933            for different numbers are allowed, but not vice versa. First scan down
934            for duplicates. */
935    
936            if (i < md->name_count)
937              {
938              uschar *slotB = slotA;
939              while (slotB > md->name_table)
940                {
941                slotB -= md->name_entry_size;
942                if (strcmp((char *)slotA + 2, (char *)slotB + 2) == 0)
943                  {
944                  offset = GET2(slotB, 0) << 1;
945                  condition = offset < offset_top &&
946                    md->offset_vector[offset] >= 0;
947                  if (condition) break;
948                  }
949                else break;
950                }
951    
952              /* Scan up for duplicates */
953    
954              if (!condition)
955                {
956                slotB = slotA;
957                for (i++; i < md->name_count; i++)
958                  {
959                  slotB += md->name_entry_size;
960                  if (strcmp((char *)slotA + 2, (char *)slotB + 2) == 0)
961                    {
962                    offset = GET2(slotB, 0) << 1;
963                    condition = offset < offset_top &&
964                      md->offset_vector[offset] >= 0;
965                    if (condition) break;
966                    }
967                  else break;
968                  }
969                }
970              }
971            }
972    
973          /* Chose branch according to the condition */
974    
975        ecode += condition? 3 : GET(ecode, 1);        ecode += condition? 3 : GET(ecode, 1);
976        }        }
977    
978      else if (ecode[LINK_SIZE+1] == OP_DEF)     /* DEFINE - always false */      else if (condcode == OP_DEF)     /* DEFINE - always false */
979        {        {
980        condition = FALSE;        condition = FALSE;
981        ecode += GET(ecode, 1);        ecode += GET(ecode, 1);
# Line 754  for (;;) Line 995  for (;;)
995          ecode += 1 + LINK_SIZE + GET(ecode, LINK_SIZE + 2);          ecode += 1 + LINK_SIZE + GET(ecode, LINK_SIZE + 2);
996          while (*ecode == OP_ALT) ecode += GET(ecode, 1);          while (*ecode == OP_ALT) ecode += GET(ecode, 1);
997          }          }
998        else if (rrc != MATCH_NOMATCH)        else if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN)
999          {          {
1000          RRETURN(rrc);         /* Need braces because of following else */          RRETURN(rrc);         /* Need braces because of following else */
1001          }          }
1002        else        else
1003          {          {
1004          condition = FALSE;          condition = FALSE;
1005          ecode += GET(ecode, 1);          ecode += codelink;
1006          }          }
1007        }        }
1008    
1009      /* We are now at the branch that is to be obeyed. As there is only one,      /* We are now at the branch that is to be obeyed. As there is only one,
1010      we can use tail recursion to avoid using another stack frame. If the second      we can use tail recursion to avoid using another stack frame, except when
1011      alternative doesn't exist, we can just plough on. */      match_cbegroup is required for an unlimited repeat of a possibly empty
1012        group. If the second alternative doesn't exist, we can just plough on. */
1013    
1014      if (condition || *ecode == OP_ALT)      if (condition || *ecode == OP_ALT)
1015        {        {
1016        ecode += 1 + LINK_SIZE;        ecode += 1 + LINK_SIZE;
1017        flags = match_tail_recursed | ((op == OP_SCOND)? match_cbegroup : 0);        if (op == OP_SCOND)        /* Possibly empty group */
1018        goto TAIL_RECURSE;          {
1019            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, match_cbegroup, RM49);
1020            RRETURN(rrc);
1021            }
1022          else                       /* Group must match something */
1023            {
1024            flags = 0;
1025            goto TAIL_RECURSE;
1026            }
1027        }        }
1028      else      else                         /* Condition false & no alternative */
1029        {        {
1030        ecode += 1 + LINK_SIZE;        ecode += 1 + LINK_SIZE;
1031        }        }
1032      break;      break;
1033    
1034    
1035      /* End of the pattern. If we are in a top-level recursion, we should      /* Before OP_ACCEPT there may be any number of OP_CLOSE opcodes,
1036      restore the offsets appropriately and continue from after the call. */      to close any currently open capturing brackets. */
1037    
1038        case OP_CLOSE:
1039        number = GET2(ecode, 1);
1040        offset = number << 1;
1041    
1042    #ifdef PCRE_DEBUG
1043          printf("end bracket %d at *ACCEPT", number);
1044          printf("\n");
1045    #endif
1046    
1047        md->capture_last = number;
1048        if (offset >= md->offset_max) md->offset_overflow = TRUE; else
1049          {
1050          md->offset_vector[offset] =
1051            md->offset_vector[md->offset_end - number];
1052          md->offset_vector[offset+1] = eptr - md->start_subject;
1053          if (offset_top <= offset) offset_top = offset + 2;
1054          }
1055        ecode += 3;
1056        break;
1057    
1058    
1059        /* End of the pattern, either real or forced. If we are in a top-level
1060        recursion, we should restore the offsets appropriately and continue from
1061        after the call. */
1062    
1063        case OP_ACCEPT:
1064      case OP_END:      case OP_END:
1065      if (md->recursive != NULL && md->recursive->group_num == 0)      if (md->recursive != NULL && md->recursive->group_num == 0)
1066        {        {
# Line 793  for (;;) Line 1069  for (;;)
1069        md->recursive = rec->prevrec;        md->recursive = rec->prevrec;
1070        memmove(md->offset_vector, rec->offset_save,        memmove(md->offset_vector, rec->offset_save,
1071          rec->saved_max * sizeof(int));          rec->saved_max * sizeof(int));
1072        mstart = rec->save_start;        offset_top = rec->save_offset_top;
1073        ims = original_ims;        ims = original_ims;
1074        ecode = rec->after_call;        ecode = rec->after_call;
1075        break;        break;
1076        }        }
1077    
1078      /* Otherwise, if PCRE_NOTEMPTY is set, fail if we have matched an empty      /* Otherwise, if we have matched an empty string, fail if PCRE_NOTEMPTY is
1079      string - backtracking will then try other alternatives, if any. */      set, or if PCRE_NOTEMPTY_ATSTART is set and we have matched at the start of
1080        the subject. In both cases, backtracking will then try other alternatives,
1081        if any. */
1082    
1083        if (eptr == mstart &&
1084            (md->notempty ||
1085              (md->notempty_atstart &&
1086                mstart == md->start_subject + md->start_offset)))
1087          RRETURN(MATCH_NOMATCH);
1088    
1089        /* Otherwise, we have a match. */
1090    
     if (md->notempty && eptr == mstart) RRETURN(MATCH_NOMATCH);  
1091      md->end_match_ptr = eptr;           /* Record where we ended */      md->end_match_ptr = eptr;           /* Record where we ended */
1092      md->end_offset_top = offset_top;    /* and how many extracts were taken */      md->end_offset_top = offset_top;    /* and how many extracts were taken */
1093      md->start_match_ptr = mstart;  /* and the start (\K can modify) */      md->start_match_ptr = mstart;       /* and the start (\K can modify) */
1094      RRETURN(MATCH_MATCH);      RRETURN(MATCH_MATCH);
1095    
1096      /* Change option settings */      /* Change option settings */
# Line 828  for (;;) Line 1113  for (;;)
1113        {        {
1114        RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, NULL, 0,        RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, NULL, 0,
1115          RM4);          RM4);
1116        if (rrc == MATCH_MATCH) break;        if (rrc == MATCH_MATCH)
1117        if (rrc != MATCH_NOMATCH) RRETURN(rrc);          {
1118            mstart = md->start_match_ptr;   /* In case \K reset it */
1119            break;
1120            }
1121          if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);
1122        ecode += GET(ecode, 1);        ecode += GET(ecode, 1);
1123        }        }
1124      while (*ecode == OP_ALT);      while (*ecode == OP_ALT);
# Line 847  for (;;) Line 1136  for (;;)
1136      offset_top = md->end_offset_top;      offset_top = md->end_offset_top;
1137      continue;      continue;
1138    
1139      /* Negative assertion: all branches must fail to match */      /* Negative assertion: all branches must fail to match. Encountering SKIP,
1140        PRUNE, or COMMIT means we must assume failure without checking subsequent
1141        branches. */
1142    
1143      case OP_ASSERT_NOT:      case OP_ASSERT_NOT:
1144      case OP_ASSERTBACK_NOT:      case OP_ASSERTBACK_NOT:
# Line 856  for (;;) Line 1147  for (;;)
1147        RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, NULL, 0,        RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, NULL, 0,
1148          RM5);          RM5);
1149        if (rrc == MATCH_MATCH) RRETURN(MATCH_NOMATCH);        if (rrc == MATCH_MATCH) RRETURN(MATCH_NOMATCH);
1150        if (rrc != MATCH_NOMATCH) RRETURN(rrc);        if (rrc == MATCH_SKIP || rrc == MATCH_PRUNE || rrc == MATCH_COMMIT)
1151            {
1152            do ecode += GET(ecode,1); while (*ecode == OP_ALT);
1153            break;
1154            }
1155          if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);
1156        ecode += GET(ecode,1);        ecode += GET(ecode,1);
1157        }        }
1158      while (*ecode == OP_ALT);      while (*ecode == OP_ALT);
# Line 880  for (;;) Line 1176  for (;;)
1176          {          {
1177          eptr--;          eptr--;
1178          if (eptr < md->start_subject) RRETURN(MATCH_NOMATCH);          if (eptr < md->start_subject) RRETURN(MATCH_NOMATCH);
1179          BACKCHAR(eptr)          BACKCHAR(eptr);
1180          }          }
1181        }        }
1182      else      else
# Line 893  for (;;) Line 1189  for (;;)
1189        if (eptr < md->start_subject) RRETURN(MATCH_NOMATCH);        if (eptr < md->start_subject) RRETURN(MATCH_NOMATCH);
1190        }        }
1191    
1192      /* Skip to next op code */      /* Save the earliest consulted character, then skip to next op code */
1193    
1194        if (eptr < md->start_used_ptr) md->start_used_ptr = eptr;
1195      ecode += 1 + LINK_SIZE;      ecode += 1 + LINK_SIZE;
1196      break;      break;
1197    
# Line 973  for (;;) Line 1270  for (;;)
1270    
1271        memcpy(new_recursive.offset_save, md->offset_vector,        memcpy(new_recursive.offset_save, md->offset_vector,
1272              new_recursive.saved_max * sizeof(int));              new_recursive.saved_max * sizeof(int));
1273        new_recursive.save_start = mstart;        new_recursive.save_offset_top = offset_top;
       mstart = eptr;  
1274    
1275        /* OK, now we can do the recursion. For each top-level alternative we        /* OK, now we can do the recursion. For each top-level alternative we
1276        restore the offset and recursion data. */        restore the offset and recursion data. */
# Line 993  for (;;) Line 1289  for (;;)
1289              (pcre_free)(new_recursive.offset_save);              (pcre_free)(new_recursive.offset_save);
1290            RRETURN(MATCH_MATCH);            RRETURN(MATCH_MATCH);
1291            }            }
1292          else if (rrc != MATCH_NOMATCH)          else if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN)
1293            {            {
1294            DPRINTF(("Recursion gave error %d\n", rrc));            DPRINTF(("Recursion gave error %d\n", rrc));
1295              if (new_recursive.offset_save != stacksave)
1296                (pcre_free)(new_recursive.offset_save);
1297            RRETURN(rrc);            RRETURN(rrc);
1298            }            }
1299    
# Line 1019  for (;;) Line 1317  for (;;)
1317      a move back into the brackets. Friedl calls these "atomic" subpatterns.      a move back into the brackets. Friedl calls these "atomic" subpatterns.
1318      Check the alternative branches in turn - the matching won't pass the KET      Check the alternative branches in turn - the matching won't pass the KET
1319      for this kind of subpattern. If any one branch matches, we carry on as at      for this kind of subpattern. If any one branch matches, we carry on as at
1320      the end of a normal bracket, leaving the subject pointer. */      the end of a normal bracket, leaving the subject pointer, but resetting
1321        the start-of-match value in case it was changed by \K. */
1322    
1323      case OP_ONCE:      case OP_ONCE:
1324      prev = ecode;      prev = ecode;
# Line 1027  for (;;) Line 1326  for (;;)
1326    
1327      do      do
1328        {        {
1329        RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims,        RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, eptrb, 0, RM7);
1330          eptrb, 0, RM7);        if (rrc == MATCH_MATCH)
1331        if (rrc == MATCH_MATCH) break;          {
1332        if (rrc != MATCH_NOMATCH) RRETURN(rrc);          mstart = md->start_match_ptr;
1333            break;
1334            }
1335          if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);
1336        ecode += GET(ecode,1);        ecode += GET(ecode,1);
1337        }        }
1338      while (*ecode == OP_ALT);      while (*ecode == OP_ALT);
# Line 1073  for (;;) Line 1375  for (;;)
1375    
1376      if (*ecode == OP_KETRMIN)      if (*ecode == OP_KETRMIN)
1377        {        {
1378        RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, eptrb, 0,        RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, eptrb, 0, RM8);
         RM8);  
1379        if (rrc != MATCH_NOMATCH) RRETURN(rrc);        if (rrc != MATCH_NOMATCH) RRETURN(rrc);
1380        ecode = prev;        ecode = prev;
1381        flags = match_tail_recursed;        flags = 0;
1382        goto TAIL_RECURSE;        goto TAIL_RECURSE;
1383        }        }
1384      else  /* OP_KETRMAX */      else  /* OP_KETRMAX */
# Line 1085  for (;;) Line 1386  for (;;)
1386        RMATCH(eptr, prev, offset_top, md, ims, eptrb, match_cbegroup, RM9);        RMATCH(eptr, prev, offset_top, md, ims, eptrb, match_cbegroup, RM9);
1387        if (rrc != MATCH_NOMATCH) RRETURN(rrc);        if (rrc != MATCH_NOMATCH) RRETURN(rrc);
1388        ecode += 1 + LINK_SIZE;        ecode += 1 + LINK_SIZE;
1389        flags = match_tail_recursed;        flags = 0;
1390        goto TAIL_RECURSE;        goto TAIL_RECURSE;
1391        }        }
1392      /* Control never gets here */      /* Control never gets here */
# Line 1097  for (;;) Line 1398  for (;;)
1398      do ecode += GET(ecode,1); while (*ecode == OP_ALT);      do ecode += GET(ecode,1); while (*ecode == OP_ALT);
1399      break;      break;
1400    
1401      /* BRAZERO and BRAMINZERO occur just before a bracket group, indicating      /* BRAZERO, BRAMINZERO and SKIPZERO occur just before a bracket group,
1402      that it may occur zero times. It may repeat infinitely, or not at all -      indicating that it may occur zero times. It may repeat infinitely, or not
1403      i.e. it could be ()* or ()? in the pattern. Brackets with fixed upper      at all - i.e. it could be ()* or ()? or even (){0} in the pattern. Brackets
1404      repeat limits are compiled as a number of copies, with the optional ones      with fixed upper repeat limits are compiled as a number of copies, with the
1405      preceded by BRAZERO or BRAMINZERO. */      optional ones preceded by BRAZERO or BRAMINZERO. */
1406    
1407      case OP_BRAZERO:      case OP_BRAZERO:
1408        {        {
# Line 1123  for (;;) Line 1424  for (;;)
1424        }        }
1425      break;      break;
1426    
1427        case OP_SKIPZERO:
1428          {
1429          next = ecode+1;
1430          do next += GET(next,1); while (*next == OP_ALT);
1431          ecode = next + 1 + LINK_SIZE;
1432          }
1433        break;
1434    
1435      /* End of a group, repeated or non-repeating. */      /* End of a group, repeated or non-repeating. */
1436    
1437      case OP_KET:      case OP_KET:
# Line 1141  for (;;) Line 1450  for (;;)
1450        }        }
1451      else saved_eptr = NULL;      else saved_eptr = NULL;
1452    
1453      /* If we are at the end of an assertion group, stop matching and return      /* If we are at the end of an assertion group or an atomic group, stop
1454      MATCH_MATCH, but record the current high water mark for use by positive      matching and return MATCH_MATCH, but record the current high water mark for
1455      assertions. Do this also for the "once" (atomic) groups. */      use by positive assertions. We also need to record the match start in case
1456        it was changed by \K. */
1457    
1458      if (*prev == OP_ASSERT || *prev == OP_ASSERT_NOT ||      if (*prev == OP_ASSERT || *prev == OP_ASSERT_NOT ||
1459          *prev == OP_ASSERTBACK || *prev == OP_ASSERTBACK_NOT ||          *prev == OP_ASSERTBACK || *prev == OP_ASSERTBACK_NOT ||
# Line 1151  for (;;) Line 1461  for (;;)
1461        {        {
1462        md->end_match_ptr = eptr;      /* For ONCE */        md->end_match_ptr = eptr;      /* For ONCE */
1463        md->end_offset_top = offset_top;        md->end_offset_top = offset_top;
1464          md->start_match_ptr = mstart;
1465        RRETURN(MATCH_MATCH);        RRETURN(MATCH_MATCH);
1466        }        }
1467    
# Line 1165  for (;;) Line 1476  for (;;)
1476        number = GET2(prev, 1+LINK_SIZE);        number = GET2(prev, 1+LINK_SIZE);
1477        offset = number << 1;        offset = number << 1;
1478    
1479  #ifdef DEBUG  #ifdef PCRE_DEBUG
1480        printf("end bracket %d", number);        printf("end bracket %d", number);
1481        printf("\n");        printf("\n");
1482  #endif  #endif
# Line 1187  for (;;) Line 1498  for (;;)
1498          recursion_info *rec = md->recursive;          recursion_info *rec = md->recursive;
1499          DPRINTF(("Recursion (%d) succeeded - continuing\n", number));          DPRINTF(("Recursion (%d) succeeded - continuing\n", number));
1500          md->recursive = rec->prevrec;          md->recursive = rec->prevrec;
         mstart = rec->save_start;  
1501          memcpy(md->offset_vector, rec->offset_save,          memcpy(md->offset_vector, rec->offset_save,
1502            rec->saved_max * sizeof(int));            rec->saved_max * sizeof(int));
1503            offset_top = rec->save_offset_top;
1504          ecode = rec->after_call;          ecode = rec->after_call;
1505          ims = original_ims;          ims = original_ims;
1506          break;          break;
# Line 1216  for (;;) Line 1527  for (;;)
1527    
1528      /* The repeating kets try the rest of the pattern or restart from the      /* The repeating kets try the rest of the pattern or restart from the
1529      preceding bracket, in the appropriate order. In the second case, we can use      preceding bracket, in the appropriate order. In the second case, we can use
1530      tail recursion to avoid using another stack frame. */      tail recursion to avoid using another stack frame, unless we have an
1531        unlimited repeat of a group that can match an empty string. */
1532    
1533      flags = (*prev >= OP_SBRA)? match_cbegroup : 0;      flags = (*prev >= OP_SBRA)? match_cbegroup : 0;
1534    
1535      if (*ecode == OP_KETRMIN)      if (*ecode == OP_KETRMIN)
1536        {        {
1537        RMATCH(eptr, ecode + 1+LINK_SIZE, offset_top, md, ims, eptrb, 0,        RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, eptrb, 0, RM12);
         RM12);  
1538        if (rrc != MATCH_NOMATCH) RRETURN(rrc);        if (rrc != MATCH_NOMATCH) RRETURN(rrc);
1539          if (flags != 0)    /* Could match an empty string */
1540            {
1541            RMATCH(eptr, prev, offset_top, md, ims, eptrb, flags, RM50);
1542            RRETURN(rrc);
1543            }
1544        ecode = prev;        ecode = prev;
       flags |= match_tail_recursed;  
1545        goto TAIL_RECURSE;        goto TAIL_RECURSE;
1546        }        }
1547      else  /* OP_KETRMAX */      else  /* OP_KETRMAX */
# Line 1234  for (;;) Line 1549  for (;;)
1549        RMATCH(eptr, prev, offset_top, md, ims, eptrb, flags, RM13);        RMATCH(eptr, prev, offset_top, md, ims, eptrb, flags, RM13);
1550        if (rrc != MATCH_NOMATCH) RRETURN(rrc);        if (rrc != MATCH_NOMATCH) RRETURN(rrc);
1551        ecode += 1 + LINK_SIZE;        ecode += 1 + LINK_SIZE;
1552        flags = match_tail_recursed;        flags = 0;
1553        goto TAIL_RECURSE;        goto TAIL_RECURSE;
1554        }        }
1555      /* Control never gets here */      /* Control never gets here */
# Line 1325  for (;;) Line 1640  for (;;)
1640    
1641        /* Find out if the previous and current characters are "word" characters.        /* Find out if the previous and current characters are "word" characters.
1642        It takes a bit more work in UTF-8 mode. Characters > 255 are assumed to        It takes a bit more work in UTF-8 mode. Characters > 255 are assumed to
1643        be "non-word" characters. */        be "non-word" characters. Remember the earliest consulted character for
1644          partial matching. */
1645    
1646  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
1647        if (utf8)        if (utf8)
1648          {          {
1649          if (eptr == md->start_subject) prev_is_word = FALSE; else          if (eptr == md->start_subject) prev_is_word = FALSE; else
1650            {            {
1651            const uschar *lastptr = eptr - 1;            USPTR lastptr = eptr - 1;
1652            while((*lastptr & 0xc0) == 0x80) lastptr--;            while((*lastptr & 0xc0) == 0x80) lastptr--;
1653              if (lastptr < md->start_used_ptr) md->start_used_ptr = lastptr;
1654            GETCHAR(c, lastptr);            GETCHAR(c, lastptr);
1655            prev_is_word = c < 256 && (md->ctypes[c] & ctype_word) != 0;            prev_is_word = c < 256 && (md->ctypes[c] & ctype_word) != 0;
1656            }            }
1657          if (eptr >= md->end_subject) cur_is_word = FALSE; else          if (eptr >= md->end_subject)
1658              {
1659              SCHECK_PARTIAL();
1660              cur_is_word = FALSE;
1661              }
1662            else
1663            {            {
1664            GETCHAR(c, eptr);            GETCHAR(c, eptr);
1665            cur_is_word = c < 256 && (md->ctypes[c] & ctype_word) != 0;            cur_is_word = c < 256 && (md->ctypes[c] & ctype_word) != 0;
# Line 1346  for (;;) Line 1668  for (;;)
1668        else        else
1669  #endif  #endif
1670    
1671        /* More streamlined when not in UTF-8 mode */        /* Not in UTF-8 mode */
1672    
1673          {          {
1674          prev_is_word = (eptr != md->start_subject) &&          if (eptr == md->start_subject) prev_is_word = FALSE; else
1675            ((md->ctypes[eptr[-1]] & ctype_word) != 0);            {
1676          cur_is_word = (eptr < md->end_subject) &&            if (eptr <= md->start_used_ptr) md->start_used_ptr = eptr - 1;
1677            ((md->ctypes[*eptr] & ctype_word) != 0);            prev_is_word = ((md->ctypes[eptr[-1]] & ctype_word) != 0);
1678              }
1679            if (eptr >= md->end_subject)
1680              {
1681              SCHECK_PARTIAL();
1682              cur_is_word = FALSE;
1683              }
1684            else cur_is_word = ((md->ctypes[*eptr] & ctype_word) != 0);
1685          }          }
1686    
1687        /* Now see if the situation is what we want */        /* Now see if the situation is what we want */
# Line 1366  for (;;) Line 1695  for (;;)
1695      /* Match a single character type; inline for speed */      /* Match a single character type; inline for speed */
1696    
1697      case OP_ANY:      case OP_ANY:
1698      if ((ims & PCRE_DOTALL) == 0)      if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH);
1699        /* Fall through */
1700    
1701        case OP_ALLANY:
1702        if (eptr++ >= md->end_subject)
1703        {        {
1704        if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH);        SCHECK_PARTIAL();
1705          RRETURN(MATCH_NOMATCH);
1706        }        }
1707      if (eptr++ >= md->end_subject) RRETURN(MATCH_NOMATCH);      if (utf8) while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;
     if (utf8)  
       while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;  
1708      ecode++;      ecode++;
1709      break;      break;
1710    
# Line 1380  for (;;) Line 1712  for (;;)
1712      any byte, even newline, independent of the setting of PCRE_DOTALL. */      any byte, even newline, independent of the setting of PCRE_DOTALL. */
1713    
1714      case OP_ANYBYTE:      case OP_ANYBYTE:
1715      if (eptr++ >= md->end_subject) RRETURN(MATCH_NOMATCH);      if (eptr++ >= md->end_subject)
1716          {
1717          SCHECK_PARTIAL();
1718          RRETURN(MATCH_NOMATCH);
1719          }
1720      ecode++;      ecode++;
1721      break;      break;
1722    
1723      case OP_NOT_DIGIT:      case OP_NOT_DIGIT:
1724      if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);      if (eptr >= md->end_subject)
1725          {
1726          SCHECK_PARTIAL();
1727          RRETURN(MATCH_NOMATCH);
1728          }
1729      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
1730      if (      if (
1731  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
# Line 1398  for (;;) Line 1738  for (;;)
1738      break;      break;
1739    
1740      case OP_DIGIT:      case OP_DIGIT:
1741      if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);      if (eptr >= md->end_subject)
1742          {
1743          SCHECK_PARTIAL();
1744          RRETURN(MATCH_NOMATCH);
1745          }
1746      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
1747      if (      if (
1748  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
# Line 1411  for (;;) Line 1755  for (;;)
1755      break;      break;
1756    
1757      case OP_NOT_WHITESPACE:      case OP_NOT_WHITESPACE:
1758      if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);      if (eptr >= md->end_subject)
1759          {
1760          SCHECK_PARTIAL();
1761          RRETURN(MATCH_NOMATCH);
1762          }
1763      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
1764      if (      if (
1765  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
# Line 1424  for (;;) Line 1772  for (;;)
1772      break;      break;
1773    
1774      case OP_WHITESPACE:      case OP_WHITESPACE:
1775      if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);      if (eptr >= md->end_subject)
1776          {
1777          SCHECK_PARTIAL();
1778          RRETURN(MATCH_NOMATCH);
1779          }
1780      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
1781      if (      if (
1782  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
# Line 1437  for (;;) Line 1789  for (;;)
1789      break;      break;
1790    
1791      case OP_NOT_WORDCHAR:      case OP_NOT_WORDCHAR:
1792      if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);      if (eptr >= md->end_subject)
1793          {
1794          SCHECK_PARTIAL();
1795          RRETURN(MATCH_NOMATCH);
1796          }
1797      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
1798      if (      if (
1799  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
# Line 1450  for (;;) Line 1806  for (;;)
1806      break;      break;
1807    
1808      case OP_WORDCHAR:      case OP_WORDCHAR:
1809      if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);      if (eptr >= md->end_subject)
1810          {
1811          SCHECK_PARTIAL();
1812          RRETURN(MATCH_NOMATCH);
1813          }
1814      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
1815      if (      if (
1816  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
# Line 1463  for (;;) Line 1823  for (;;)
1823      break;      break;
1824    
1825      case OP_ANYNL:      case OP_ANYNL:
1826      if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);      if (eptr >= md->end_subject)
1827          {
1828          SCHECK_PARTIAL();
1829          RRETURN(MATCH_NOMATCH);
1830          }
1831      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
1832      switch(c)      switch(c)
1833        {        {
# Line 1471  for (;;) Line 1835  for (;;)
1835        case 0x000d:        case 0x000d:
1836        if (eptr < md->end_subject && *eptr == 0x0a) eptr++;        if (eptr < md->end_subject && *eptr == 0x0a) eptr++;
1837        break;        break;
1838    
1839        case 0x000a:        case 0x000a:
1840          break;
1841    
1842        case 0x000b:        case 0x000b:
1843        case 0x000c:        case 0x000c:
1844        case 0x0085:        case 0x0085:
1845        case 0x2028:        case 0x2028:
1846        case 0x2029:        case 0x2029:
1847          if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH);
1848          break;
1849          }
1850        ecode++;
1851        break;
1852    
1853        case OP_NOT_HSPACE:
1854        if (eptr >= md->end_subject)
1855          {
1856          SCHECK_PARTIAL();
1857          RRETURN(MATCH_NOMATCH);
1858          }
1859        GETCHARINCTEST(c, eptr);
1860        switch(c)
1861          {
1862          default: break;
1863          case 0x09:      /* HT */
1864          case 0x20:      /* SPACE */
1865          case 0xa0:      /* NBSP */
1866          case 0x1680:    /* OGHAM SPACE MARK */
1867          case 0x180e:    /* MONGOLIAN VOWEL SEPARATOR */
1868          case 0x2000:    /* EN QUAD */
1869          case 0x2001:    /* EM QUAD */
1870          case 0x2002:    /* EN SPACE */
1871          case 0x2003:    /* EM SPACE */
1872          case 0x2004:    /* THREE-PER-EM SPACE */
1873          case 0x2005:    /* FOUR-PER-EM SPACE */
1874          case 0x2006:    /* SIX-PER-EM SPACE */
1875          case 0x2007:    /* FIGURE SPACE */
1876          case 0x2008:    /* PUNCTUATION SPACE */
1877          case 0x2009:    /* THIN SPACE */
1878          case 0x200A:    /* HAIR SPACE */
1879          case 0x202f:    /* NARROW NO-BREAK SPACE */
1880          case 0x205f:    /* MEDIUM MATHEMATICAL SPACE */
1881          case 0x3000:    /* IDEOGRAPHIC SPACE */
1882          RRETURN(MATCH_NOMATCH);
1883          }
1884        ecode++;
1885        break;
1886    
1887        case OP_HSPACE:
1888        if (eptr >= md->end_subject)
1889          {
1890          SCHECK_PARTIAL();
1891          RRETURN(MATCH_NOMATCH);
1892          }
1893        GETCHARINCTEST(c, eptr);
1894        switch(c)
1895          {
1896          default: RRETURN(MATCH_NOMATCH);
1897          case 0x09:      /* HT */
1898          case 0x20:      /* SPACE */
1899          case 0xa0:      /* NBSP */
1900          case 0x1680:    /* OGHAM SPACE MARK */
1901          case 0x180e:    /* MONGOLIAN VOWEL SEPARATOR */
1902          case 0x2000:    /* EN QUAD */
1903          case 0x2001:    /* EM QUAD */
1904          case 0x2002:    /* EN SPACE */
1905          case 0x2003:    /* EM SPACE */
1906          case 0x2004:    /* THREE-PER-EM SPACE */
1907          case 0x2005:    /* FOUR-PER-EM SPACE */
1908          case 0x2006:    /* SIX-PER-EM SPACE */
1909          case 0x2007:    /* FIGURE SPACE */
1910          case 0x2008:    /* PUNCTUATION SPACE */
1911          case 0x2009:    /* THIN SPACE */
1912          case 0x200A:    /* HAIR SPACE */
1913          case 0x202f:    /* NARROW NO-BREAK SPACE */
1914          case 0x205f:    /* MEDIUM MATHEMATICAL SPACE */
1915          case 0x3000:    /* IDEOGRAPHIC SPACE */
1916          break;
1917          }
1918        ecode++;
1919        break;
1920    
1921        case OP_NOT_VSPACE:
1922        if (eptr >= md->end_subject)
1923          {
1924          SCHECK_PARTIAL();
1925          RRETURN(MATCH_NOMATCH);
1926          }
1927        GETCHARINCTEST(c, eptr);
1928        switch(c)
1929          {
1930          default: break;
1931          case 0x0a:      /* LF */
1932          case 0x0b:      /* VT */
1933          case 0x0c:      /* FF */
1934          case 0x0d:      /* CR */
1935          case 0x85:      /* NEL */
1936          case 0x2028:    /* LINE SEPARATOR */
1937          case 0x2029:    /* PARAGRAPH SEPARATOR */
1938          RRETURN(MATCH_NOMATCH);
1939          }
1940        ecode++;
1941        break;
1942    
1943        case OP_VSPACE:
1944        if (eptr >= md->end_subject)
1945          {
1946          SCHECK_PARTIAL();
1947          RRETURN(MATCH_NOMATCH);
1948          }
1949        GETCHARINCTEST(c, eptr);
1950        switch(c)
1951          {
1952          default: RRETURN(MATCH_NOMATCH);
1953          case 0x0a:      /* LF */
1954          case 0x0b:      /* VT */
1955          case 0x0c:      /* FF */
1956          case 0x0d:      /* CR */
1957          case 0x85:      /* NEL */
1958          case 0x2028:    /* LINE SEPARATOR */
1959          case 0x2029:    /* PARAGRAPH SEPARATOR */
1960        break;        break;
1961        }        }
1962      ecode++;      ecode++;
# Line 1488  for (;;) Line 1968  for (;;)
1968    
1969      case OP_PROP:      case OP_PROP:
1970      case OP_NOTPROP:      case OP_NOTPROP:
1971      if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);      if (eptr >= md->end_subject)
1972          {
1973          SCHECK_PARTIAL();
1974          RRETURN(MATCH_NOMATCH);
1975          }
1976      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
1977        {        {
1978        int chartype, script;        const ucd_record *prop = GET_UCD(c);
       int category = _pcre_ucp_findprop(c, &chartype, &script);  
1979    
1980        switch(ecode[1])        switch(ecode[1])
1981          {          {
# Line 1501  for (;;) Line 1984  for (;;)
1984          break;          break;
1985    
1986          case PT_LAMP:          case PT_LAMP:
1987          if ((chartype == ucp_Lu ||          if ((prop->chartype == ucp_Lu ||
1988               chartype == ucp_Ll ||               prop->chartype == ucp_Ll ||
1989               chartype == ucp_Lt) == (op == OP_NOTPROP))               prop->chartype == ucp_Lt) == (op == OP_NOTPROP))
1990            RRETURN(MATCH_NOMATCH);            RRETURN(MATCH_NOMATCH);
1991           break;           break;
1992    
1993          case PT_GC:          case PT_GC:
1994          if ((ecode[2] != category) == (op == OP_PROP))          if ((ecode[2] != _pcre_ucp_gentype[prop->chartype]) == (op == OP_PROP))
1995            RRETURN(MATCH_NOMATCH);            RRETURN(MATCH_NOMATCH);
1996          break;          break;
1997    
1998          case PT_PC:          case PT_PC:
1999          if ((ecode[2] != chartype) == (op == OP_PROP))          if ((ecode[2] != prop->chartype) == (op == OP_PROP))
2000            RRETURN(MATCH_NOMATCH);            RRETURN(MATCH_NOMATCH);
2001          break;          break;
2002    
2003          case PT_SC:          case PT_SC:
2004          if ((ecode[2] != script) == (op == OP_PROP))          if ((ecode[2] != prop->script) == (op == OP_PROP))
2005            RRETURN(MATCH_NOMATCH);            RRETURN(MATCH_NOMATCH);
2006          break;          break;
2007    
# Line 1534  for (;;) Line 2017  for (;;)
2017      is in the binary; otherwise a compile-time error occurs. */      is in the binary; otherwise a compile-time error occurs. */
2018    
2019      case OP_EXTUNI:      case OP_EXTUNI:
2020      if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);      if (eptr >= md->end_subject)
2021          {
2022          SCHECK_PARTIAL();
2023          RRETURN(MATCH_NOMATCH);
2024          }
2025      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
2026        {        {
2027        int chartype, script;        int category = UCD_CATEGORY(c);
       int category = _pcre_ucp_findprop(c, &chartype, &script);  
2028        if (category == ucp_M) RRETURN(MATCH_NOMATCH);        if (category == ucp_M) RRETURN(MATCH_NOMATCH);
2029        while (eptr < md->end_subject)        while (eptr < md->end_subject)
2030          {          {
# Line 1547  for (;;) Line 2033  for (;;)
2033            {            {
2034            GETCHARLEN(c, eptr, len);            GETCHARLEN(c, eptr, len);
2035            }            }
2036          category = _pcre_ucp_findprop(c, &chartype, &script);          category = UCD_CATEGORY(c);
2037          if (category != ucp_M) break;          if (category != ucp_M) break;
2038          eptr += len;          eptr += len;
2039          }          }
# Line 1568  for (;;) Line 2054  for (;;)
2054      case OP_REF:      case OP_REF:
2055        {        {
2056        offset = GET2(ecode, 1) << 1;               /* Doubled ref number */        offset = GET2(ecode, 1) << 1;               /* Doubled ref number */
2057        ecode += 3;                                 /* Advance past item */        ecode += 3;
2058    
2059          /* If the reference is unset, there are two possibilities:
2060    
2061          (a) In the default, Perl-compatible state, set the length to be longer
2062          than the amount of subject left; this ensures that every attempt at a
2063          match fails. We can't just fail here, because of the possibility of
2064          quantifiers with zero minima.
2065    
2066          (b) If the JavaScript compatibility flag is set, set the length to zero
2067          so that the back reference matches an empty string.
2068    
2069        /* If the reference is unset, set the length to be longer than the amount        Otherwise, set the length to the length of what was matched by the
2070        of subject left; this ensures that every attempt at a match fails. We        referenced subpattern. */
2071        can't just fail here, because of the possibility of quantifiers with zero  
2072        minima. */        if (offset >= offset_top || md->offset_vector[offset] < 0)
2073            length = (md->jscript_compat)? 0 : md->end_subject - eptr + 1;
2074        length = (offset >= offset_top || md->offset_vector[offset] < 0)?        else
2075          md->end_subject - eptr + 1 :          length = md->offset_vector[offset+1] - md->offset_vector[offset];
         md->offset_vector[offset+1] - md->offset_vector[offset];  
2076    
2077        /* Set up for repetition, or handle the non-repeated case */        /* Set up for repetition, or handle the non-repeated case */
2078    
# Line 1606  for (;;) Line 2101  for (;;)
2101          break;          break;
2102    
2103          default:               /* No repeat follows */          default:               /* No repeat follows */
2104          if (!match_ref(offset, eptr, length, md, ims)) RRETURN(MATCH_NOMATCH);          if (!match_ref(offset, eptr, length, md, ims))
2105              {
2106              CHECK_PARTIAL();
2107              RRETURN(MATCH_NOMATCH);
2108              }
2109          eptr += length;          eptr += length;
2110          continue;              /* With the main loop */          continue;              /* With the main loop */
2111          }          }
# Line 1622  for (;;) Line 2121  for (;;)
2121    
2122        for (i = 1; i <= min; i++)        for (i = 1; i <= min; i++)
2123          {          {
2124          if (!match_ref(offset, eptr, length, md, ims)) RRETURN(MATCH_NOMATCH);          if (!match_ref(offset, eptr, length, md, ims))
2125              {
2126              CHECK_PARTIAL();
2127              RRETURN(MATCH_NOMATCH);
2128              }
2129          eptr += length;          eptr += length;
2130          }          }
2131    
# Line 1639  for (;;) Line 2142  for (;;)
2142            {            {
2143            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM14);            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM14);
2144            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2145            if (fi >= max || !match_ref(offset, eptr, length, md, ims))            if (fi >= max) RRETURN(MATCH_NOMATCH);
2146              if (!match_ref(offset, eptr, length, md, ims))
2147                {
2148                CHECK_PARTIAL();
2149              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
2150                }
2151            eptr += length;            eptr += length;
2152            }            }
2153          /* Control never gets here */          /* Control never gets here */
# Line 1653  for (;;) Line 2160  for (;;)
2160          pp = eptr;          pp = eptr;
2161          for (i = min; i < max; i++)          for (i = min; i < max; i++)
2162            {            {
2163            if (!match_ref(offset, eptr, length, md, ims)) break;            if (!match_ref(offset, eptr, length, md, ims))
2164                {
2165                CHECK_PARTIAL();
2166                break;
2167                }
2168            eptr += length;            eptr += length;
2169            }            }
2170          while (eptr >= pp)          while (eptr >= pp)
# Line 1667  for (;;) Line 2178  for (;;)
2178        }        }
2179      /* Control never gets here */      /* Control never gets here */
2180    
   
   
2181      /* Match a bit-mapped character class, possibly repeatedly. This op code is      /* Match a bit-mapped character class, possibly repeatedly. This op code is
2182      used when all the characters in the class have values in the range 0-255,      used when all the characters in the class have values in the range 0-255,
2183      and either the matching is caseful, or the characters are in the range      and either the matching is caseful, or the characters are in the range
# Line 1723  for (;;) Line 2232  for (;;)
2232          {          {
2233          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
2234            {            {
2235            if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);            if (eptr >= md->end_subject)
2236                {
2237                SCHECK_PARTIAL();
2238                RRETURN(MATCH_NOMATCH);
2239                }
2240            GETCHARINC(c, eptr);            GETCHARINC(c, eptr);
2241            if (c > 255)            if (c > 255)
2242              {              {
# Line 1741  for (;;) Line 2254  for (;;)
2254          {          {
2255          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
2256            {            {
2257            if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);            if (eptr >= md->end_subject)
2258                {
2259                SCHECK_PARTIAL();
2260                RRETURN(MATCH_NOMATCH);
2261                }
2262            c = *eptr++;            c = *eptr++;
2263            if ((data[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);            if ((data[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);
2264            }            }
# Line 1765  for (;;) Line 2282  for (;;)
2282              {              {
2283              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM16);              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM16);
2284              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2285              if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);              if (fi >= max) RRETURN(MATCH_NOMATCH);
2286                if (eptr >= md->end_subject)
2287                  {
2288                  SCHECK_PARTIAL();
2289                  RRETURN(MATCH_NOMATCH);
2290                  }
2291              GETCHARINC(c, eptr);              GETCHARINC(c, eptr);
2292              if (c > 255)              if (c > 255)
2293                {                {
# Line 1785  for (;;) Line 2307  for (;;)
2307              {              {
2308              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM17);              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM17);
2309              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2310              if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);              if (fi >= max) RRETURN(MATCH_NOMATCH);
2311                if (eptr >= md->end_subject)
2312                  {
2313                  SCHECK_PARTIAL();
2314                  RRETURN(MATCH_NOMATCH);
2315                  }
2316              c = *eptr++;              c = *eptr++;
2317              if ((data[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);              if ((data[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);
2318              }              }
# Line 1806  for (;;) Line 2333  for (;;)
2333            for (i = min; i < max; i++)            for (i = min; i < max; i++)
2334              {              {
2335              int len = 1;              int len = 1;
2336              if (eptr >= md->end_subject) break;              if (eptr >= md->end_subject)
2337                  {
2338                  SCHECK_PARTIAL();
2339                  break;
2340                  }
2341              GETCHARLEN(c, eptr, len);              GETCHARLEN(c, eptr, len);
2342              if (c > 255)              if (c > 255)
2343                {                {
# Line 1832  for (;;) Line 2363  for (;;)
2363            {            {
2364            for (i = min; i < max; i++)            for (i = min; i < max; i++)
2365              {              {
2366              if (eptr >= md->end_subject) break;              if (eptr >= md->end_subject)
2367                  {
2368                  SCHECK_PARTIAL();
2369                  break;
2370                  }
2371              c = *eptr;              c = *eptr;
2372              if ((data[c/8] & (1 << (c&7))) == 0) break;              if ((data[c/8] & (1 << (c&7))) == 0) break;
2373              eptr++;              eptr++;
# Line 1852  for (;;) Line 2387  for (;;)
2387    
2388    
2389      /* Match an extended character class. This opcode is encountered only      /* Match an extended character class. This opcode is encountered only
2390      in UTF-8 mode, because that's the only time it is compiled. */      when UTF-8 mode mode is supported. Nevertheless, we may not be in UTF-8
2391        mode, because Unicode properties are supported in non-UTF-8 mode. */
2392    
2393  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
2394      case OP_XCLASS:      case OP_XCLASS:
# Line 1893  for (;;) Line 2429  for (;;)
2429    
2430        for (i = 1; i <= min; i++)        for (i = 1; i <= min; i++)
2431          {          {
2432          if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);          if (eptr >= md->end_subject)
2433          GETCHARINC(c, eptr);            {
2434              SCHECK_PARTIAL();
2435              RRETURN(MATCH_NOMATCH);
2436              }
2437            GETCHARINCTEST(c, eptr);
2438          if (!_pcre_xclass(c, data)) RRETURN(MATCH_NOMATCH);          if (!_pcre_xclass(c, data)) RRETURN(MATCH_NOMATCH);
2439          }          }
2440    
# Line 1912  for (;;) Line 2452  for (;;)
2452            {            {
2453            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM20);            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM20);
2454            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2455            if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);            if (fi >= max) RRETURN(MATCH_NOMATCH);
2456            GETCHARINC(c, eptr);            if (eptr >= md->end_subject)
2457                {
2458                SCHECK_PARTIAL();
2459                RRETURN(MATCH_NOMATCH);
2460                }
2461              GETCHARINCTEST(c, eptr);
2462            if (!_pcre_xclass(c, data)) RRETURN(MATCH_NOMATCH);            if (!_pcre_xclass(c, data)) RRETURN(MATCH_NOMATCH);
2463            }            }
2464          /* Control never gets here */          /* Control never gets here */
# Line 1927  for (;;) Line 2472  for (;;)
2472          for (i = min; i < max; i++)          for (i = min; i < max; i++)
2473            {            {
2474            int len = 1;            int len = 1;
2475            if (eptr >= md->end_subject) break;            if (eptr >= md->end_subject)
2476            GETCHARLEN(c, eptr, len);              {
2477                SCHECK_PARTIAL();
2478                break;
2479                }
2480              GETCHARLENTEST(c, eptr, len);
2481            if (!_pcre_xclass(c, data)) break;            if (!_pcre_xclass(c, data)) break;
2482            eptr += len;            eptr += len;
2483            }            }
# Line 1937  for (;;) Line 2486  for (;;)
2486            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM21);            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM21);
2487            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2488            if (eptr-- == pp) break;        /* Stop if tried at original pos */            if (eptr-- == pp) break;        /* Stop if tried at original pos */
2489            BACKCHAR(eptr)            if (utf8) BACKCHAR(eptr);
2490            }            }
2491          RRETURN(MATCH_NOMATCH);          RRETURN(MATCH_NOMATCH);
2492          }          }
# Line 1955  for (;;) Line 2504  for (;;)
2504        length = 1;        length = 1;
2505        ecode++;        ecode++;
2506        GETCHARLEN(fc, ecode, length);        GETCHARLEN(fc, ecode, length);
2507        if (length > md->end_subject - eptr) RRETURN(MATCH_NOMATCH);        if (length > md->end_subject - eptr)
2508            {
2509            CHECK_PARTIAL();             /* Not SCHECK_PARTIAL() */
2510            RRETURN(MATCH_NOMATCH);
2511            }
2512        while (length-- > 0) if (*ecode++ != *eptr++) RRETURN(MATCH_NOMATCH);        while (length-- > 0) if (*ecode++ != *eptr++) RRETURN(MATCH_NOMATCH);
2513        }        }
2514      else      else
# Line 1963  for (;;) Line 2516  for (;;)
2516    
2517      /* Non-UTF-8 mode */      /* Non-UTF-8 mode */
2518        {        {
2519        if (md->end_subject - eptr < 1) RRETURN(MATCH_NOMATCH);        if (md->end_subject - eptr < 1)
2520            {
2521            SCHECK_PARTIAL();            /* This one can use SCHECK_PARTIAL() */
2522            RRETURN(MATCH_NOMATCH);
2523            }
2524        if (ecode[1] != *eptr++) RRETURN(MATCH_NOMATCH);        if (ecode[1] != *eptr++) RRETURN(MATCH_NOMATCH);
2525        ecode += 2;        ecode += 2;
2526        }        }
# Line 1979  for (;;) Line 2536  for (;;)
2536        ecode++;        ecode++;
2537        GETCHARLEN(fc, ecode, length);        GETCHARLEN(fc, ecode, length);
2538    
2539        if (length > md->end_subject - eptr) RRETURN(MATCH_NOMATCH);        if (length > md->end_subject - eptr)
2540            {
2541            CHECK_PARTIAL();             /* Not SCHECK_PARTIAL() */
2542            RRETURN(MATCH_NOMATCH);
2543            }
2544    
2545        /* If the pattern character's value is < 128, we have only one byte, and        /* If the pattern character's value is < 128, we have only one byte, and
2546        can use the fast lookup table. */        can use the fast lookup table. */
# Line 2003  for (;;) Line 2564  for (;;)
2564          if (fc != dc)          if (fc != dc)
2565            {            {
2566  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2567            if (dc != _pcre_ucp_othercase(fc))            if (dc != UCD_OTHERCASE(fc))
2568  #endif  #endif
2569              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
2570            }            }
# Line 2014  for (;;) Line 2575  for (;;)
2575    
2576      /* Non-UTF-8 mode */      /* Non-UTF-8 mode */
2577        {        {
2578        if (md->end_subject - eptr < 1) RRETURN(MATCH_NOMATCH);        if (md->end_subject - eptr < 1)
2579            {
2580            SCHECK_PARTIAL();            /* This one can use SCHECK_PARTIAL() */
2581            RRETURN(MATCH_NOMATCH);
2582            }
2583        if (md->lcc[ecode[1]] != md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH);        if (md->lcc[ecode[1]] != md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH);
2584        ecode += 2;        ecode += 2;
2585        }        }
# Line 2068  for (;;) Line 2633  for (;;)
2633      case OP_MINQUERY:      case OP_MINQUERY:
2634      c = *ecode++ - OP_STAR;      c = *ecode++ - OP_STAR;
2635      minimize = (c & 1) != 0;      minimize = (c & 1) != 0;
2636    
2637      min = rep_min[c];                 /* Pick up values from tables; */      min = rep_min[c];                 /* Pick up values from tables; */
2638      max = rep_max[c];                 /* zero for max => infinity */      max = rep_max[c];                 /* zero for max => infinity */
2639      if (max == 0) max = INT_MAX;      if (max == 0) max = INT_MAX;
2640    
2641      /* Common code for all repeated single-character matches. We can give      /* Common code for all repeated single-character matches. */
     up quickly if there are fewer than the minimum number of characters left in  
     the subject. */  
2642    
2643      REPEATCHAR:      REPEATCHAR:
2644  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
# Line 2083  for (;;) Line 2647  for (;;)
2647        length = 1;        length = 1;
2648        charptr = ecode;        charptr = ecode;
2649        GETCHARLEN(fc, ecode, length);        GETCHARLEN(fc, ecode, length);
       if (min * length > md->end_subject - eptr) RRETURN(MATCH_NOMATCH);  
2650        ecode += length;        ecode += length;
2651    
2652        /* Handle multibyte character matching specially here. There is        /* Handle multibyte character matching specially here. There is
# Line 2094  for (;;) Line 2657  for (;;)
2657  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2658          unsigned int othercase;          unsigned int othercase;
2659          if ((ims & PCRE_CASELESS) != 0 &&          if ((ims & PCRE_CASELESS) != 0 &&
2660              (othercase = _pcre_ucp_othercase(fc)) != NOTACHAR)              (othercase = UCD_OTHERCASE(fc)) != fc)
2661            oclength = _pcre_ord2utf8(othercase, occhars);            oclength = _pcre_ord2utf8(othercase, occhars);
2662          else oclength = 0;          else oclength = 0;
2663  #endif  /* SUPPORT_UCP */  #endif  /* SUPPORT_UCP */
2664    
2665          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
2666            {            {
2667            if (memcmp(eptr, charptr, length) == 0) eptr += length;            if (eptr <= md->end_subject - length &&
2668                memcmp(eptr, charptr, length) == 0) eptr += length;
2669  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2670            /* Need braces because of following else */            else if (oclength > 0 &&
2671            else if (oclength == 0) { RRETURN(MATCH_NOMATCH); }                     eptr <= md->end_subject - oclength &&
2672                       memcmp(eptr, occhars, oclength) == 0) eptr += oclength;
2673    #endif  /* SUPPORT_UCP */
2674            else            else
2675              {              {
2676              if (memcmp(eptr, occhars, oclength) != 0) RRETURN(MATCH_NOMATCH);              CHECK_PARTIAL();
2677              eptr += oclength;              RRETURN(MATCH_NOMATCH);
2678              }              }
 #else   /* without SUPPORT_UCP */  
           else { RRETURN(MATCH_NOMATCH); }  
 #endif  /* SUPPORT_UCP */  
2679            }            }
2680    
2681          if (min == max) continue;          if (min == max) continue;
# Line 2123  for (;;) Line 2686  for (;;)
2686              {              {
2687              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM22);              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM22);
2688              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2689              if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);              if (fi >= max) RRETURN(MATCH_NOMATCH);
2690              if (memcmp(eptr, charptr, length) == 0) eptr += length;              if (eptr <= md->end_subject - length &&
2691                  memcmp(eptr, charptr, length) == 0) eptr += length;
2692  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2693              /* Need braces because of following else */              else if (oclength > 0 &&
2694              else if (oclength == 0) { RRETURN(MATCH_NOMATCH); }                       eptr <= md->end_subject - oclength &&
2695                         memcmp(eptr, occhars, oclength) == 0) eptr += oclength;
2696    #endif  /* SUPPORT_UCP */
2697              else              else
2698                {                {
2699                if (memcmp(eptr, occhars, oclength) != 0) RRETURN(MATCH_NOMATCH);                CHECK_PARTIAL();
2700                eptr += oclength;                RRETURN(MATCH_NOMATCH);
2701                }                }
 #else   /* without SUPPORT_UCP */  
             else { RRETURN (MATCH_NOMATCH); }  
 #endif  /* SUPPORT_UCP */  
2702              }              }
2703            /* Control never gets here */            /* Control never gets here */
2704            }            }
# Line 2145  for (;;) Line 2708  for (;;)
2708            pp = eptr;            pp = eptr;
2709            for (i = min; i < max; i++)            for (i = min; i < max; i++)
2710              {              {
2711              if (eptr > md->end_subject - length) break;              if (eptr <= md->end_subject - length &&
2712              if (memcmp(eptr, charptr, length) == 0) eptr += length;                  memcmp(eptr, charptr, length) == 0) eptr += length;
2713  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2714              else if (oclength == 0) break;              else if (oclength > 0 &&
2715                         eptr <= md->end_subject - oclength &&
2716                         memcmp(eptr, occhars, oclength) == 0) eptr += oclength;
2717    #endif  /* SUPPORT_UCP */
2718              else              else
2719                {                {
2720                if (memcmp(eptr, occhars, oclength) != 0) break;                CHECK_PARTIAL();
2721                eptr += oclength;                break;
2722                }                }
 #else   /* without SUPPORT_UCP */  
             else break;  
 #endif  /* SUPPORT_UCP */  
2723              }              }
2724    
2725            if (possessive) continue;            if (possessive) continue;
2726    
2727            for(;;)            for(;;)
2728             {              {
2729             RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM23);              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM23);
2730             if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2731             if (eptr == pp) RRETURN(MATCH_NOMATCH);              if (eptr == pp) { RRETURN(MATCH_NOMATCH); }
2732  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2733             eptr--;              eptr--;
2734             BACKCHAR(eptr);              BACKCHAR(eptr);
2735  #else   /* without SUPPORT_UCP */  #else   /* without SUPPORT_UCP */
2736             eptr -= length;              eptr -= length;
2737  #endif  /* SUPPORT_UCP */  #endif  /* SUPPORT_UCP */
2738             }              }
2739            }            }
2740          /* Control never gets here */          /* Control never gets here */
2741          }          }
# Line 2184  for (;;) Line 2748  for (;;)
2748  #endif  /* SUPPORT_UTF8 */  #endif  /* SUPPORT_UTF8 */
2749    
2750      /* When not in UTF-8 mode, load a single-byte character. */      /* When not in UTF-8 mode, load a single-byte character. */
2751        {  
2752        if (min > md->end_subject - eptr) RRETURN(MATCH_NOMATCH);      fc = *ecode++;
       fc = *ecode++;  
       }  
2753    
2754      /* 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 less than 256, though we may or
2755      may not be in UTF-8 mode. The code is duplicated for the caseless and      may not be in UTF-8 mode. The code is duplicated for the caseless and
# Line 2205  for (;;) Line 2767  for (;;)
2767        {        {
2768        fc = md->lcc[fc];        fc = md->lcc[fc];
2769        for (i = 1; i <= min; i++)        for (i = 1; i <= min; i++)
2770            {
2771            if (eptr >= md->end_subject)
2772              {
2773              SCHECK_PARTIAL();
2774              RRETURN(MATCH_NOMATCH);
2775              }
2776          if (fc != md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH);          if (fc != md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH);
2777            }
2778        if (min == max) continue;        if (min == max) continue;
2779        if (minimize)        if (minimize)
2780          {          {
# Line 2213  for (;;) Line 2782  for (;;)
2782            {            {
2783            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM24);            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM24);
2784            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2785            if (fi >= max || eptr >= md->end_subject ||            if (fi >= max) RRETURN(MATCH_NOMATCH);
2786                fc != md->lcc[*eptr++])            if (eptr >= md->end_subject)
2787                {
2788                SCHECK_PARTIAL();
2789              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
2790                }
2791              if (fc != md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH);
2792            }            }
2793          /* Control never gets here */          /* Control never gets here */
2794          }          }
# Line 2224  for (;;) Line 2797  for (;;)
2797          pp = eptr;          pp = eptr;
2798          for (i = min; i < max; i++)          for (i = min; i < max; i++)
2799            {            {
2800            if (eptr >= md->end_subject || fc != md->lcc[*eptr]) break;            if (eptr >= md->end_subject)
2801                {
2802                SCHECK_PARTIAL();
2803                break;
2804                }
2805              if (fc != md->lcc[*eptr]) break;
2806            eptr++;            eptr++;
2807            }            }
2808    
2809          if (possessive) continue;          if (possessive) continue;
2810    
2811          while (eptr >= pp)          while (eptr >= pp)
2812            {            {
2813            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM25);            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM25);
# Line 2243  for (;;) Line 2823  for (;;)
2823    
2824      else      else
2825        {        {
2826        for (i = 1; i <= min; i++) if (fc != *eptr++) RRETURN(MATCH_NOMATCH);        for (i = 1; i <= min; i++)
2827            {
2828            if (eptr >= md->end_subject)
2829              {
2830              SCHECK_PARTIAL();
2831              RRETURN(MATCH_NOMATCH);
2832              }
2833            if (fc != *eptr++) RRETURN(MATCH_NOMATCH);
2834            }
2835    
2836        if (min == max) continue;        if (min == max) continue;
2837    
2838        if (minimize)        if (minimize)
2839          {          {
2840          for (fi = min;; fi++)          for (fi = min;; fi++)
2841            {            {
2842            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM26);            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM26);
2843            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2844            if (fi >= max || eptr >= md->end_subject || fc != *eptr++)            if (fi >= max) RRETURN(MATCH_NOMATCH);
2845              if (eptr >= md->end_subject)
2846                {
2847                SCHECK_PARTIAL();
2848              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
2849                }
2850              if (fc != *eptr++) RRETURN(MATCH_NOMATCH);
2851            }            }
2852          /* Control never gets here */          /* Control never gets here */
2853          }          }
# Line 2261  for (;;) Line 2856  for (;;)
2856          pp = eptr;          pp = eptr;
2857          for (i = min; i < max; i++)          for (i = min; i < max; i++)
2858            {            {
2859            if (eptr >= md->end_subject || fc != *eptr) break;            if (eptr >= md->end_subject)
2860                {
2861                SCHECK_PARTIAL();
2862                break;
2863                }
2864              if (fc != *eptr) break;
2865            eptr++;            eptr++;
2866            }            }
2867          if (possessive) continue;          if (possessive) continue;
2868    
2869          while (eptr >= pp)          while (eptr >= pp)
2870            {            {
2871            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM27);            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM27);
# Line 2280  for (;;) Line 2881  for (;;)
2881      checking can be multibyte. */      checking can be multibyte. */
2882    
2883      case OP_NOT:      case OP_NOT:
2884      if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);      if (eptr >= md->end_subject)
2885          {
2886          SCHECK_PARTIAL();
2887          RRETURN(MATCH_NOMATCH);
2888          }
2889      ecode++;      ecode++;
2890      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
2891      if ((ims & PCRE_CASELESS) != 0)      if ((ims & PCRE_CASELESS) != 0)
# Line 2357  for (;;) Line 2962  for (;;)
2962      max = rep_max[c];                 /* zero for max => infinity */      max = rep_max[c];                 /* zero for max => infinity */
2963      if (max == 0) max = INT_MAX;      if (max == 0) max = INT_MAX;
2964    
2965      /* Common code for all repeated single-byte matches. We can give up quickly      /* Common code for all repeated single-byte matches. */
     if there are fewer than the minimum number of bytes left in the  
     subject. */  
2966    
2967      REPEATNOTCHAR:      REPEATNOTCHAR:
     if (min > md->end_subject - eptr) RRETURN(MATCH_NOMATCH);  
2968      fc = *ecode++;      fc = *ecode++;
2969    
2970      /* The code is duplicated for the caseless and caseful cases, for speed,      /* The code is duplicated for the caseless and caseful cases, for speed,
# Line 2387  for (;;) Line 2989  for (;;)
2989          register unsigned int d;          register unsigned int d;
2990          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
2991            {            {
2992              if (eptr >= md->end_subject)
2993                {
2994                SCHECK_PARTIAL();
2995                RRETURN(MATCH_NOMATCH);
2996                }
2997            GETCHARINC(d, eptr);            GETCHARINC(d, eptr);
2998            if (d < 256) d = md->lcc[d];            if (d < 256) d = md->lcc[d];
2999            if (fc == d) RRETURN(MATCH_NOMATCH);            if (fc == d) RRETURN(MATCH_NOMATCH);
# Line 2398  for (;;) Line 3005  for (;;)
3005        /* Not UTF-8 mode */        /* Not UTF-8 mode */
3006          {          {
3007          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3008              {
3009              if (eptr >= md->end_subject)
3010                {
3011                SCHECK_PARTIAL();
3012                RRETURN(MATCH_NOMATCH);
3013                }
3014            if (fc == md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH);            if (fc == md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH);
3015              }
3016          }          }
3017    
3018        if (min == max) continue;        if (min == max) continue;
# Line 2414  for (;;) Line 3028  for (;;)
3028              {              {
3029              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM28);              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM28);
3030              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3031                if (fi >= max) RRETURN(MATCH_NOMATCH);
3032                if (eptr >= md->end_subject)
3033                  {
3034                  SCHECK_PARTIAL();
3035                  RRETURN(MATCH_NOMATCH);
3036                  }
3037              GETCHARINC(d, eptr);              GETCHARINC(d, eptr);
3038              if (d < 256) d = md->lcc[d];              if (d < 256) d = md->lcc[d];
3039              if (fi >= max || eptr >= md->end_subject || fc == d)              if (fc == d) RRETURN(MATCH_NOMATCH);
               RRETURN(MATCH_NOMATCH);  
3040              }              }
3041            }            }
3042          else          else
# Line 2428  for (;;) Line 3047  for (;;)
3047              {              {
3048              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM29);              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM29);
3049              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3050              if (fi >= max || eptr >= md->end_subject || fc == md->lcc[*eptr++])              if (fi >= max) RRETURN(MATCH_NOMATCH);
3051                if (eptr >= md->end_subject)
3052                  {
3053                  SCHECK_PARTIAL();
3054                RRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
3055                  }
3056                if (fc == md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH);
3057              }              }
3058            }            }
3059          /* Control never gets here */          /* Control never gets here */
# Line 2449  for (;;) Line 3073  for (;;)
3073            for (i = min; i < max; i++)            for (i = min; i < max; i++)
3074              {              {
3075              int len = 1;              int len = 1;
3076              if (eptr >= md->end_subject) break;              if (eptr >= md->end_subject)
3077                  {
3078                  SCHECK_PARTIAL();
3079                  break;
3080                  }
3081              GETCHARLEN(d, eptr, len);              GETCHARLEN(d, eptr, len);
3082              if (d < 256) d = md->lcc[d];              if (d < 256) d = md->lcc[d];
3083              if (fc == d) break;              if (fc == d) break;
# Line 2470  for (;;) Line 3098  for (;;)
3098            {            {
3099            for (i = min; i < max; i++)            for (i = min; i < max; i++)
3100              {              {
3101              if (eptr >= md->end_subject || fc == md->lcc[*eptr]) break;              if (eptr >= md->end_subject)
3102                  {
3103                  SCHECK_PARTIAL();
3104                  break;
3105                  }
3106                if (fc == md->lcc[*eptr]) break;
3107              eptr++;              eptr++;
3108              }              }
3109            if (possessive) continue;            if (possessive) continue;
# Line 2498  for (;;) Line 3131  for (;;)
3131          register unsigned int d;          register unsigned int d;
3132          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3133            {            {
3134              if (eptr >= md->end_subject)
3135                {
3136                SCHECK_PARTIAL();
3137                RRETURN(MATCH_NOMATCH);
3138                }
3139            GETCHARINC(d, eptr);            GETCHARINC(d, eptr);
3140            if (fc == d) RRETURN(MATCH_NOMATCH);            if (fc == d) RRETURN(MATCH_NOMATCH);
3141            }            }
# Line 2507  for (;;) Line 3145  for (;;)
3145        /* Not UTF-8 mode */        /* Not UTF-8 mode */
3146          {          {
3147          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3148              {
3149              if (eptr >= md->end_subject)
3150                {
3151                SCHECK_PARTIAL();
3152                RRETURN(MATCH_NOMATCH);
3153                }
3154            if (fc == *eptr++) RRETURN(MATCH_NOMATCH);            if (fc == *eptr++) RRETURN(MATCH_NOMATCH);
3155              }
3156          }          }
3157    
3158        if (min == max) continue;        if (min == max) continue;
# Line 2523  for (;;) Line 3168  for (;;)
3168              {              {
3169              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM32);              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM32);
3170              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3171              GETCHARINC(d, eptr);              if (fi >= max) RRETURN(MATCH_NOMATCH);
3172              if (fi >= max || eptr >= md->end_subject || fc == d)              if (eptr >= md->end_subject)
3173                  {
3174                  SCHECK_PARTIAL();
3175                RRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
3176                  }
3177                GETCHARINC(d, eptr);
3178                if (fc == d) RRETURN(MATCH_NOMATCH);
3179              }              }
3180            }            }
3181          else          else
# Line 2536  for (;;) Line 3186  for (;;)
3186              {              {
3187              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM33);              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM33);
3188              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3189              if (fi >= max || eptr >= md->end_subject || fc == *eptr++)              if (fi >= max) RRETURN(MATCH_NOMATCH);
3190                if (eptr >= md->end_subject)
3191                  {
3192                  SCHECK_PARTIAL();
3193                RRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
3194                  }
3195                if (fc == *eptr++) RRETURN(MATCH_NOMATCH);
3196              }              }
3197            }            }
3198          /* Control never gets here */          /* Control never gets here */
# Line 2557  for (;;) Line 3212  for (;;)
3212            for (i = min; i < max; i++)            for (i = min; i < max; i++)
3213              {              {
3214              int len = 1;              int len = 1;
3215              if (eptr >= md->end_subject) break;              if (eptr >= md->end_subject)
3216                  {
3217                  SCHECK_PARTIAL();
3218                  break;
3219                  }
3220              GETCHARLEN(d, eptr, len);              GETCHARLEN(d, eptr, len);
3221              if (fc == d) break;              if (fc == d) break;
3222              eptr += len;              eptr += len;
# Line 2577  for (;;) Line 3236  for (;;)
3236            {            {
3237            for (i = min; i < max; i++)            for (i = min; i < max; i++)
3238              {              {
3239              if (eptr >= md->end_subject || fc == *eptr) break;              if (eptr >= md->end_subject)
3240                  {
3241                  SCHECK_PARTIAL();
3242                  break;
3243                  }
3244                if (fc == *eptr) break;
3245              eptr++;              eptr++;
3246              }              }
3247            if (possessive) continue;            if (possessive) continue;
# Line 2671  for (;;) Line 3335  for (;;)
3335    
3336      /* First, ensure the minimum number of matches are present. Use inline      /* First, ensure the minimum number of matches are present. Use inline
3337      code for maximizing the speed, and do the type test once at the start      code for maximizing the speed, and do the type test once at the start
3338      (i.e. keep it out of the loop). Also we can test that there are at least      (i.e. keep it out of the loop). Separate the UTF-8 code completely as that
     the minimum number of bytes before we start. This isn't as effective in  
     UTF-8 mode, but it does no harm. Separate the UTF-8 code completely as that  
3339      is tidier. Also separate the UCP code, which can be the same for both UTF-8      is tidier. Also separate the UCP code, which can be the same for both UTF-8
3340      and single-bytes. */      and single-bytes. */
3341    
     if (min > md->end_subject - eptr) RRETURN(MATCH_NOMATCH);  
3342      if (min > 0)      if (min > 0)
3343        {        {
3344  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
# Line 2689  for (;;) Line 3350  for (;;)
3350            if (prop_fail_result) RRETURN(MATCH_NOMATCH);            if (prop_fail_result) RRETURN(MATCH_NOMATCH);
3351            for (i = 1; i <= min; i++)            for (i = 1; i <= min; i++)
3352              {              {
3353              if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);              if (eptr >= md->end_subject)
3354              GETCHARINC(c, eptr);                {
3355                  SCHECK_PARTIAL();
3356                  RRETURN(MATCH_NOMATCH);
3357                  }
3358                GETCHARINCTEST(c, eptr);
3359              }              }
3360            break;            break;
3361    
3362            case PT_LAMP:            case PT_LAMP:
3363            for (i = 1; i <= min; i++)            for (i = 1; i <= min; i++)
3364              {              {
3365              if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);              if (eptr >= md->end_subject)
3366              GETCHARINC(c, eptr);                {
3367              prop_category = _pcre_ucp_findprop(c, &prop_chartype, &prop_script);                SCHECK_PARTIAL();
3368                  RRETURN(MATCH_NOMATCH);
3369                  }
3370                GETCHARINCTEST(c, eptr);
3371                prop_chartype = UCD_CHARTYPE(c);
3372              if ((prop_chartype == ucp_Lu ||              if ((prop_chartype == ucp_Lu ||
3373                   prop_chartype == ucp_Ll ||                   prop_chartype == ucp_Ll ||
3374                   prop_chartype == ucp_Lt) == prop_fail_result)                   prop_chartype == ucp_Lt) == prop_fail_result)
# Line 2710  for (;;) Line 3379  for (;;)
3379            case PT_GC:            case PT_GC:
3380            for (i = 1; i <= min; i++)            for (i = 1; i <= min; i++)
3381              {              {
3382              if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);              if (eptr >= md->end_subject)
3383              GETCHARINC(c, eptr);                {
3384              prop_category = _pcre_ucp_findprop(c, &prop_chartype, &prop_script);                SCHECK_PARTIAL();
3385                  RRETURN(MATCH_NOMATCH);
3386                  }
3387                GETCHARINCTEST(c, eptr);
3388                prop_category = UCD_CATEGORY(c);
3389              if ((prop_category == prop_value) == prop_fail_result)              if ((prop_category == prop_value) == prop_fail_result)
3390                RRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
3391              }              }
# Line 2721  for (;;) Line 3394  for (;;)
3394            case PT_PC:            case PT_PC:
3395            for (i = 1; i <= min; i++)            for (i = 1; i <= min; i++)
3396              {              {
3397              if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);              if (eptr >= md->end_subject)
3398              GETCHARINC(c, eptr);                {
3399              prop_category = _pcre_ucp_findprop(c, &prop_chartype, &prop_script);                SCHECK_PARTIAL();
3400                  RRETURN(MATCH_NOMATCH);
3401                  }
3402                GETCHARINCTEST(c, eptr);
3403                prop_chartype = UCD_CHARTYPE(c);
3404              if ((prop_chartype == prop_value) == prop_fail_result)              if ((prop_chartype == prop_value) == prop_fail_result)
3405                RRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
3406              }              }
# Line 2732  for (;;) Line 3409  for (;;)
3409            case PT_SC:            case PT_SC:
3410            for (i = 1; i <= min; i++)            for (i = 1; i <= min; i++)
3411              {              {
3412              if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);              if (eptr >= md->end_subject)
3413              GETCHARINC(c, eptr);                {
3414              prop_category = _pcre_ucp_findprop(c, &prop_chartype, &prop_script);                SCHECK_PARTIAL();
3415                  RRETURN(MATCH_NOMATCH);
3416                  }
3417                GETCHARINCTEST(c, eptr);
3418                prop_script = UCD_SCRIPT(c);
3419              if ((prop_script == prop_value) == prop_fail_result)              if ((prop_script == prop_value) == prop_fail_result)
3420                RRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
3421              }              }
# Line 2752  for (;;) Line 3433  for (;;)
3433          {          {
3434          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3435            {            {
3436              if (eptr >= md->end_subject)
3437                {
3438                SCHECK_PARTIAL();
3439                RRETURN(MATCH_NOMATCH);
3440                }
3441            GETCHARINCTEST(c, eptr);            GETCHARINCTEST(c, eptr);
3442            prop_category = _pcre_ucp_findprop(c, &prop_chartype, &prop_script);            prop_category = UCD_CATEGORY(c);
3443            if (prop_category == ucp_M) RRETURN(MATCH_NOMATCH);            if (prop_category == ucp_M) RRETURN(MATCH_NOMATCH);
3444            while (eptr < md->end_subject)            while (eptr < md->end_subject)
3445              {              {
3446              int len = 1;              int len = 1;
3447              if (!utf8) c = *eptr; else              if (!utf8) c = *eptr;
3448                {                else { GETCHARLEN(c, eptr, len); }
3449                GETCHARLEN(c, eptr, len);              prop_category = UCD_CATEGORY(c);
               }  
             prop_category = _pcre_ucp_findprop(c, &prop_chartype, &prop_script);  
3450              if (prop_category != ucp_M) break;              if (prop_category != ucp_M) break;
3451              eptr += len;              eptr += len;
3452              }              }
# Line 2780  for (;;) Line 3464  for (;;)
3464          case OP_ANY:          case OP_ANY:
3465          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3466            {            {
3467            if (eptr >= md->end_subject ||            if (eptr >= md->end_subject)
3468                 ((ims & PCRE_DOTALL) == 0 && IS_NEWLINE(eptr)))              {
3469                SCHECK_PARTIAL();
3470                RRETURN(MATCH_NOMATCH);
3471                }
3472              if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH);
3473              eptr++;
3474              while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;
3475              }
3476            break;
3477    
3478            case OP_ALLANY:
3479            for (i = 1; i <= min; i++)
3480              {
3481              if (eptr >= md->end_subject)
3482                {
3483                SCHECK_PARTIAL();
3484              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
3485                }
3486            eptr++;            eptr++;
3487            while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;            while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;
3488            }            }
3489          break;          break;
3490    
3491          case OP_ANYBYTE:          case OP_ANYBYTE:
3492            if (eptr > md->end_subject - min) RRETURN(MATCH_NOMATCH);
3493          eptr += min;          eptr += min;
3494          break;          break;
3495    
3496          case OP_ANYNL:          case OP_ANYNL:
3497          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3498            {            {
3499            if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);            if (eptr >= md->end_subject)
3500                {
3501                SCHECK_PARTIAL();
3502                RRETURN(MATCH_NOMATCH);
3503                }
3504            GETCHARINC(c, eptr);            GETCHARINC(c, eptr);
3505            switch(c)            switch(c)
3506              {              {
# Line 2803  for (;;) Line 3508  for (;;)
3508              case 0x000d:              case 0x000d:
3509              if (eptr < md->end_subject && *eptr == 0x0a) eptr++;              if (eptr < md->end_subject && *eptr == 0x0a) eptr++;
3510              break;              break;
3511    
3512              case 0x000a:              case 0x000a:
3513                break;
3514    
3515              case 0x000b:              case 0x000b:
3516              case 0x000c:              case 0x000c:
3517              case 0x0085:              case 0x0085:
3518              case 0x2028:              case 0x2028:
3519              case 0x2029:              case 0x2029:
3520                if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH);
3521              break;              break;
3522              }              }
3523            }            }
3524          break;          break;
3525    
3526          case OP_NOT_DIGIT:          case OP_NOT_HSPACE:
3527          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3528            {            {
3529            if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);            if (eptr >= md->end_subject)
3530                {
3531                SCHECK_PARTIAL();
3532                RRETURN(MATCH_NOMATCH);
3533                }
3534            GETCHARINC(c, eptr);            GETCHARINC(c, eptr);
3535            if (c < 128 && (md->ctypes[c] & ctype_digit) != 0)            switch(c)
3536                {
3537                default: break;
3538                case 0x09:      /* HT */
3539                case 0x20:      /* SPACE */
3540                case 0xa0:      /* NBSP */
3541                case 0x1680:    /* OGHAM SPACE MARK */
3542                case 0x180e:    /* MONGOLIAN VOWEL SEPARATOR */
3543                case 0x2000:    /* EN QUAD */
3544                case 0x2001:    /* EM QUAD */
3545                case 0x2002:    /* EN SPACE */
3546                case 0x2003:    /* EM SPACE */
3547                case 0x2004:    /* THREE-PER-EM SPACE */
3548                case 0x2005:    /* FOUR-PER-EM SPACE */
3549                case 0x2006:    /* SIX-PER-EM SPACE */
3550                case 0x2007:    /* FIGURE SPACE */
3551                case 0x2008:    /* PUNCTUATION SPACE */
3552                case 0x2009:    /* THIN SPACE */
3553                case 0x200A:    /* HAIR SPACE */
3554                case 0x202f:    /* NARROW NO-BREAK SPACE */
3555                case 0x205f:    /* MEDIUM MATHEMATICAL SPACE */
3556                case 0x3000:    /* IDEOGRAPHIC SPACE */
3557              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
3558                }
3559            }            }
3560          break;          break;
3561    
3562          case OP_DIGIT:          case OP_HSPACE:
3563          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3564            {            {
3565            if (eptr >= md->end_subject ||            if (eptr >= md->end_subject)
3566               *eptr >= 128 || (md->ctypes[*eptr++] & ctype_digit) == 0)              {
3567                SCHECK_PARTIAL();
3568              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
3569            /* No need to skip more bytes - we know it's a 1-byte character */              }
3570              GETCHARINC(c, eptr);
3571              switch(c)
3572                {
3573                default: RRETURN(MATCH_NOMATCH);
3574                case 0x09:      /* HT */
3575                case 0x20:      /* SPACE */
3576                case 0xa0:      /* NBSP */
3577                case 0x1680:    /* OGHAM SPACE MARK */
3578                case 0x180e:    /* MONGOLIAN VOWEL SEPARATOR */
3579                case 0x2000:    /* EN QUAD */
3580                case 0x2001:    /* EM QUAD */
3581                case 0x2002:    /* EN SPACE */
3582                case 0x2003:    /* EM SPACE */
3583                case 0x2004:    /* THREE-PER-EM SPACE */
3584                case 0x2005:    /* FOUR-PER-EM SPACE */
3585                case 0x2006:    /* SIX-PER-EM SPACE */
3586                case 0x2007:    /* FIGURE SPACE */
3587                case 0x2008:    /* PUNCTUATION SPACE */
3588                case 0x2009:    /* THIN SPACE */
3589                case 0x200A:    /* HAIR SPACE */
3590                case 0x202f:    /* NARROW NO-BREAK SPACE */
3591                case 0x205f:    /* MEDIUM MATHEMATICAL SPACE */
3592                case 0x3000:    /* IDEOGRAPHIC SPACE */
3593                break;
3594                }
3595            }            }
3596          break;          break;
3597    
3598          case OP_NOT_WHITESPACE:          case OP_NOT_VSPACE:
3599          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3600            {            {
3601            if (eptr >= md->end_subject ||            if (eptr >= md->end_subject)
3602               (*eptr < 128 && (md->ctypes[*eptr++] & ctype_space) != 0))              {
3603                SCHECK_PARTIAL();
3604              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
3605            while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;              }
3606              GETCHARINC(c, eptr);
3607              switch(c)
3608                {
3609                default: break;
3610                case 0x0a:      /* LF */
3611                case 0x0b:      /* VT */
3612                case 0x0c:      /* FF */
3613                case 0x0d:      /* CR */
3614                case 0x85:      /* NEL */
3615                case 0x2028:    /* LINE SEPARATOR */
3616                case 0x2029:    /* PARAGRAPH SEPARATOR */
3617                RRETURN(MATCH_NOMATCH);
3618                }
3619            }            }
3620          break;          break;
3621    
3622          case OP_WHITESPACE:          case OP_VSPACE:
3623          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3624            {            {
3625            if (eptr >= md->end_subject ||            if (eptr >= md->end_subject)
3626               *eptr >= 128 || (md->ctypes[*eptr++] & ctype_space) == 0)              {
3627                SCHECK_PARTIAL();
3628              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
3629            /* No need to skip more bytes - we know it's a 1-byte character */              }
3630              GETCHARINC(c, eptr);
3631              switch(c)
3632                {
3633                default: RRETURN(MATCH_NOMATCH);
3634                case 0x0a:      /* LF */
3635                case 0x0b:      /* VT */
3636                case 0x0c:      /* FF */
3637                case 0x0d:      /* CR */
3638                case 0x85:      /* NEL */
3639                case 0x2028:    /* LINE SEPARATOR */
3640                case 0x2029:    /* PARAGRAPH SEPARATOR */
3641                break;
3642                }
3643            }            }
3644          break;          break;
3645    
3646          case OP_NOT_WORDCHAR:          case OP_NOT_DIGIT:
3647          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3648            {            {
3649            if (eptr >= md->end_subject ||            if (eptr >= md->end_subject)
3650               (*eptr < 128 && (md->ctypes[*eptr++] & ctype_word) != 0))              {
3651                SCHECK_PARTIAL();
3652                RRETURN(MATCH_NOMATCH);
3653                }
3654              GETCHARINC(c, eptr);
3655              if (c < 128 && (md->ctypes[c] & ctype_digit) != 0)
3656              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
           while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;  
3657            }            }
3658          break;          break;
3659    
3660          case OP_WORDCHAR:          case OP_DIGIT:
3661          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3662            {            {
3663            if (eptr >= md->end_subject ||            if (eptr >= md->end_subject)
3664               *eptr >= 128 || (md->ctypes[*eptr++] & ctype_word) == 0)              {
3665                SCHECK_PARTIAL();
3666                RRETURN(MATCH_NOMATCH);
3667                }
3668              if (*eptr >= 128 || (md->ctypes[*eptr++] & ctype_digit) == 0)
3669              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
3670            /* 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 */
3671            }            }
3672          break;          break;
3673    
3674          default:          case OP_NOT_WHITESPACE:
3675          RRETURN(PCRE_ERROR_INTERNAL);          for (i = 1; i <= min; i++)
         }  /* End switch(ctype) */  
   
       else  
 #endif     /* SUPPORT_UTF8 */  
   
       /* Code for the non-UTF-8 case for minimum matching of operators other  
       than OP_PROP and OP_NOTPROP. We can assume that there are the minimum  
       number of bytes present, as this was tested above. */  
   
       switch(ctype)  
         {  
         case OP_ANY:  
         if ((ims & PCRE_DOTALL) == 0)  
3676            {            {
3677            for (i = 1; i <= min; i++)            if (eptr >= md->end_subject)
3678              {              {
3679              if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH);              SCHECK_PARTIAL();
3680              eptr++;              RRETURN(MATCH_NOMATCH);
3681              }              }
3682              if (*eptr < 128 && (md->ctypes[*eptr] & ctype_space) != 0)
3683                RRETURN(MATCH_NOMATCH);
3684              while (++eptr < md->end_subject && (*eptr & 0xc0) == 0x80);
3685            }            }
         else eptr += min;  
3686          break;          break;
3687    
3688          case OP_ANYBYTE:          case OP_WHITESPACE:
3689            for (i = 1; i <= min; i++)
3690              {
3691              if (eptr >= md->end_subject)
3692                {
3693                SCHECK_PARTIAL();
3694                RRETURN(MATCH_NOMATCH);
3695                }
3696              if (*eptr >= 128 || (md->ctypes[*eptr++] & ctype_space) == 0)
3697                RRETURN(MATCH_NOMATCH);
3698              /* No need to skip more bytes - we know it's a 1-byte character */
3699              }
3700            break;
3701    
3702            case OP_NOT_WORDCHAR:
3703            for (i = 1; i <= min; i++)
3704              {
3705              if (eptr >= md->end_subject)
3706                {
3707                SCHECK_PARTIAL();
3708                RRETURN(MATCH_NOMATCH);
3709                }
3710              if (*eptr < 128 && (md->ctypes[*eptr] & ctype_word) != 0)
3711                RRETURN(MATCH_NOMATCH);
3712              while (++eptr < md->end_subject && (*eptr & 0xc0) == 0x80);
3713              }
3714            break;
3715    
3716            case OP_WORDCHAR:
3717            for (i = 1; i <= min; i++)
3718              {
3719              if (eptr >= md->end_subject)
3720                {
3721                SCHECK_PARTIAL();
3722                RRETURN(MATCH_NOMATCH);
3723                }
3724              if (*eptr >= 128 || (md->ctypes[*eptr++] & ctype_word) == 0)
3725                RRETURN(MATCH_NOMATCH);
3726              /* No need to skip more bytes - we know it's a 1-byte character */
3727              }
3728            break;
3729    
3730            default:
3731            RRETURN(PCRE_ERROR_INTERNAL);
3732            }  /* End switch(ctype) */
3733    
3734          else
3735    #endif     /* SUPPORT_UTF8 */
3736    
3737          /* Code for the non-UTF-8 case for minimum matching of operators other
3738          than OP_PROP and OP_NOTPROP. */
3739    
3740          switch(ctype)
3741            {
3742            case OP_ANY:
3743            for (i = 1; i <= min; i++)
3744              {
3745              if (eptr >= md->end_subject)
3746                {
3747                SCHECK_PARTIAL();
3748                RRETURN(MATCH_NOMATCH);
3749                }
3750              if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH);
3751              eptr++;
3752              }
3753            break;
3754    
3755            case OP_ALLANY:
3756            if (eptr > md->end_subject - min)
3757              {
3758              SCHECK_PARTIAL();
3759              RRETURN(MATCH_NOMATCH);
3760              }
3761          eptr += min;          eptr += min;
3762          break;          break;
3763    
3764          /* Because of the CRLF case, we can't assume the minimum number of          case OP_ANYBYTE:
3765          bytes are present in this case. */          if (eptr > md->end_subject - min)
3766              {
3767              SCHECK_PARTIAL();
3768              RRETURN(MATCH_NOMATCH);
3769              }
3770            eptr += min;
3771            break;
3772    
3773          case OP_ANYNL:          case OP_ANYNL:
3774          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3775            {            {
3776            if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);            if (eptr >= md->end_subject)
3777                {
3778                SCHECK_PARTIAL();
3779                RRETURN(MATCH_NOMATCH);
3780                }
3781            switch(*eptr++)            switch(*eptr++)
3782              {              {
3783              default: RRETURN(MATCH_NOMATCH);              default: RRETURN(MATCH_NOMATCH);
# Line 2917  for (;;) Line 3785  for (;;)
3785              if (eptr < md->end_subject && *eptr == 0x0a) eptr++;              if (eptr < md->end_subject && *eptr == 0x0a) eptr++;
3786              break;              break;
3787              case 0x000a:              case 0x000a:
3788                break;
3789    
3790              case 0x000b:              case 0x000b:
3791              case 0x000c:              case 0x000c:
3792              case 0x0085:              case 0x0085:
3793                if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH);
3794                break;
3795                }
3796              }
3797            break;
3798    
3799            case OP_NOT_HSPACE:
3800            for (i = 1; i <= min; i++)
3801              {
3802              if (eptr >= md->end_subject)
3803                {
3804                SCHECK_PARTIAL();
3805                RRETURN(MATCH_NOMATCH);
3806                }
3807              switch(*eptr++)
3808                {
3809                default: break;
3810                case 0x09:      /* HT */
3811                case 0x20:      /* SPACE */
3812                case 0xa0:      /* NBSP */
3813                RRETURN(MATCH_NOMATCH);
3814                }
3815              }
3816            break;
3817    
3818            case OP_HSPACE:
3819            for (i = 1; i <= min; i++)
3820              {
3821              if (eptr >= md->end_subject)
3822                {
3823                SCHECK_PARTIAL();
3824                RRETURN(MATCH_NOMATCH);
3825                }
3826              switch(*eptr++)
3827                {
3828                default: RRETURN(MATCH_NOMATCH);
3829                case 0x09:      /* HT */
3830                case 0x20:      /* SPACE */
3831                case 0xa0:      /* NBSP */
3832                break;
3833                }
3834              }
3835            break;
3836    
3837            case OP_NOT_VSPACE:
3838            for (i = 1; i <= min; i++)
3839              {
3840              if (eptr >= md->end_subject)
3841                {
3842                SCHECK_PARTIAL();
3843                RRETURN(MATCH_NOMATCH);
3844                }
3845              switch(*eptr++)
3846                {
3847                default: break;
3848                case 0x0a:      /* LF */
3849                case 0x0b:      /* VT */
3850                case 0x0c:      /* FF */
3851                case 0x0d:      /* CR */
3852                case 0x85:      /* NEL */
3853                RRETURN(MATCH_NOMATCH);
3854                }
3855              }
3856            break;
3857    
3858            case OP_VSPACE:
3859            for (i = 1; i <= min; i++)
3860              {
3861              if (eptr >= md->end_subject)
3862                {
3863                SCHECK_PARTIAL();
3864                RRETURN(MATCH_NOMATCH);
3865                }
3866              switch(*eptr++)
3867                {
3868                default: RRETURN(MATCH_NOMATCH);
3869                case 0x0a:      /* LF */
3870                case 0x0b:      /* VT */
3871                case 0x0c:      /* FF */
3872                case 0x0d:      /* CR */
3873                case 0x85:      /* NEL */
3874              break;              break;
3875              }              }
3876            }            }
# Line 2927  for (;;) Line 3878  for (;;)
3878    
3879          case OP_NOT_DIGIT:          case OP_NOT_DIGIT:
3880          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3881              {
3882              if (eptr >= md->end_subject)
3883                {
3884                SCHECK_PARTIAL();
3885                RRETURN(MATCH_NOMATCH);
3886                }
3887            if ((md->ctypes[*eptr++] & ctype_digit) != 0) RRETURN(MATCH_NOMATCH);            if ((md->ctypes[*eptr++] & ctype_digit) != 0) RRETURN(MATCH_NOMATCH);
3888              }
3889          break;          break;
3890    
3891          case OP_DIGIT:          case OP_DIGIT:
3892          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3893              {
3894              if (eptr >= md->end_subject)
3895                {
3896                SCHECK_PARTIAL();
3897                RRETURN(MATCH_NOMATCH);
3898                }
3899            if ((md->ctypes[*eptr++] & ctype_digit) == 0) RRETURN(MATCH_NOMATCH);            if ((md->ctypes[*eptr++] & ctype_digit) == 0) RRETURN(MATCH_NOMATCH);
3900              }
3901          break;          break;
3902    
3903          case OP_NOT_WHITESPACE:          case OP_NOT_WHITESPACE:
3904          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3905              {
3906              if (eptr >= md->end_subject)
3907                {
3908                SCHECK_PARTIAL();
3909                RRETURN(MATCH_NOMATCH);
3910                }
3911            if ((md->ctypes[*eptr++] & ctype_space) != 0) RRETURN(MATCH_NOMATCH);            if ((md->ctypes[*eptr++] & ctype_space) != 0) RRETURN(MATCH_NOMATCH);
3912              }
3913          break;          break;
3914    
3915          case OP_WHITESPACE:          case OP_WHITESPACE:
3916          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3917              {
3918              if (eptr >= md->end_subject)
3919                {
3920                SCHECK_PARTIAL();
3921                RRETURN(MATCH_NOMATCH);
3922                }
3923            if ((md->ctypes[*eptr++] & ctype_space) == 0) RRETURN(MATCH_NOMATCH);            if ((md->ctypes[*eptr++] & ctype_space) == 0) RRETURN(MATCH_NOMATCH);
3924              }
3925          break;          break;
3926    
3927          case OP_NOT_WORDCHAR:          case OP_NOT_WORDCHAR:
3928          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3929              {
3930              if (eptr >= md->end_subject)
3931                {
3932                SCHECK_PARTIAL();
3933                RRETURN(MATCH_NOMATCH);
3934                }
3935            if ((md->ctypes[*eptr++] & ctype_word) != 0)            if ((md->ctypes[*eptr++] & ctype_word) != 0)
3936              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
3937              }
3938          break;          break;
3939    
3940          case OP_WORDCHAR:          case OP_WORDCHAR:
3941          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3942              {
3943              if (eptr >= md->end_subject)
3944                {
3945                SCHECK_PARTIAL();
3946                RRETURN(MATCH_NOMATCH);
3947                }
3948            if ((md->ctypes[*eptr++] & ctype_word) == 0)            if ((md->ctypes[*eptr++] & ctype_word) == 0)
3949              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
3950              }
3951          break;          break;
3952    
3953          default:          default:
# Line 2982  for (;;) Line 3975  for (;;)
3975              {              {
3976              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM36);              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM36);
3977              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3978              if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);              if (fi >= max) RRETURN(MATCH_NOMATCH);
3979                if (eptr >= md->end_subject)
3980                  {
3981                  SCHECK_PARTIAL();
3982                  RRETURN(MATCH_NOMATCH);
3983                  }
3984              GETCHARINC(c, eptr);              GETCHARINC(c, eptr);
3985              if (prop_fail_result) RRETURN(MATCH_NOMATCH);              if (prop_fail_result) RRETURN(MATCH_NOMATCH);
3986              }              }
# Line 2993  for (;;) Line 3991  for (;;)
3991              {              {
3992              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM37);              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM37);
3993              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3994              if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);              if (fi >= max) RRETURN(MATCH_NOMATCH);
3995                if (eptr >= md->end_subject)
3996                  {
3997                  SCHECK_PARTIAL();
3998                  RRETURN(MATCH_NOMATCH);
3999                  }
4000              GETCHARINC(c, eptr);              GETCHARINC(c, eptr);
4001              prop_category = _pcre_ucp_findprop(c, &prop_chartype, &prop_script);              prop_chartype = UCD_CHARTYPE(c);
4002              if ((prop_chartype == ucp_Lu ||              if ((prop_chartype == ucp_Lu ||
4003                   prop_chartype == ucp_Ll ||                   prop_chartype == ucp_Ll ||
4004                   prop_chartype == ucp_Lt) == prop_fail_result)                   prop_chartype == ucp_Lt) == prop_fail_result)
# Line 3008  for (;;) Line 4011  for (;;)
4011              {              {
4012              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM38);              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM38);
4013              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
4014              if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);              if (fi >= max) RRETURN(MATCH_NOMATCH);
4015                if (eptr >= md->end_subject)
4016                  {
4017                  SCHECK_PARTIAL();
4018                  RRETURN(MATCH_NOMATCH);
4019                  }
4020              GETCHARINC(c, eptr);              GETCHARINC(c, eptr);
4021              prop_category = _pcre_ucp_findprop(c, &prop_chartype, &prop_script);              prop_category = UCD_CATEGORY(c);
4022              if ((prop_category == prop_value) == prop_fail_result)              if ((prop_category == prop_value) == prop_fail_result)
4023                RRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4024              }              }
# Line 3021  for (;;) Line 4029  for (;;)
4029              {              {
4030              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM39);              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM39);
4031              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
4032              if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);              if (fi >= max) RRETURN(MATCH_NOMATCH);
4033                if (eptr >= md->end_subject)
4034                  {
4035                  SCHECK_PARTIAL();
4036                  RRETURN(MATCH_NOMATCH);
4037                  }
4038              GETCHARINC(c, eptr);              GETCHARINC(c, eptr);
4039              prop_category = _pcre_ucp_findprop(c, &prop_chartype, &prop_script);              prop_chartype = UCD_CHARTYPE(c);
4040              if ((prop_chartype == prop_value) == prop_fail_result)              if ((prop_chartype == prop_value) == prop_fail_result)
4041                RRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4042              }              }
# Line 3034  for (;;) Line 4047  for (;;)
4047              {              {
4048              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM40);              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM40);
4049              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
4050              if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);              if (fi >= max) RRETURN(MATCH_NOMATCH);
4051                if (eptr >= md->end_subject)
4052                  {
4053                  SCHECK_PARTIAL();
4054                  RRETURN(MATCH_NOMATCH);
4055                  }
4056              GETCHARINC(c, eptr);              GETCHARINC(c, eptr);
4057              prop_category = _pcre_ucp_findprop(c, &prop_chartype, &prop_script);              prop_script = UCD_SCRIPT(c);
4058              if ((prop_script == prop_value) == prop_fail_result)              if ((prop_script == prop_value) == prop_fail_result)
4059                RRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4060              }              }
# Line 3056  for (;;) Line 4074  for (;;)
4074            {            {
4075            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM41);            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM41);
4076            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
4077            if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);            if (fi >= max) RRETURN(MATCH_NOMATCH);
4078              if (eptr >= md->end_subject)
4079                {
4080                SCHECK_PARTIAL();
4081                RRETURN(MATCH_NOMATCH);
4082                }
4083            GETCHARINCTEST(c, eptr);            GETCHARINCTEST(c, eptr);
4084            prop_category = _pcre_ucp_findprop(c, &prop_chartype, &prop_script);            prop_category = UCD_CATEGORY(c);
4085            if (prop_category == ucp_M) RRETURN(MATCH_NOMATCH);            if (prop_category == ucp_M) RRETURN(MATCH_NOMATCH);
4086            while (eptr < md->end_subject)            while (eptr < md->end_subject)
4087              {              {
4088              int len = 1;              int len = 1;
4089              if (!utf8) c = *eptr; else              if (!utf8) c = *eptr;
4090                {                else { GETCHARLEN(c, eptr, len); }
4091                GETCHARLEN(c, eptr, len);              prop_category = UCD_CATEGORY(c);
               }  
             prop_category = _pcre_ucp_findprop(c, &prop_chartype, &prop_script);  
4092              if (prop_category != ucp_M) break;              if (prop_category != ucp_M) break;
4093              eptr += len;              eptr += len;
4094              }              }
# Line 3085  for (;;) Line 4106  for (;;)
4106            {            {
4107            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM42);            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM42);
4108            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
4109            if (fi >= max || eptr >= md->end_subject ||            if (fi >= max) RRETURN(MATCH_NOMATCH);
4110                 (ctype == OP_ANY && (ims & PCRE_DOTALL) == 0 &&            if (eptr >= md->end_subject)
4111                  IS_NEWLINE(eptr)))              {
4112                SCHECK_PARTIAL();
4113                RRETURN(MATCH_NOMATCH);
4114                }
4115              if (ctype == OP_ANY && IS_NEWLINE(eptr))
4116              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
   
4117            GETCHARINC(c, eptr);            GETCHARINC(c, eptr);
4118            switch(ctype)            switch(ctype)
4119              {              {
4120              case OP_ANY:        /* This is the DOTALL case */              case OP_ANY:        /* This is the non-NL case */
4121              break;              case OP_ALLANY:
   
4122              case OP_ANYBYTE:              case OP_ANYBYTE:
4123              break;              break;
4124    
# Line 3107  for (;;) Line 4130  for (;;)
4130                if (eptr < md->end_subject && *eptr == 0x0a) eptr++;                if (eptr < md->end_subject && *eptr == 0x0a) eptr++;
4131                break;                break;
4132                case 0x000a:                case 0x000a:
4133                  break;
4134    
4135                case 0x000b:                case 0x000b:
4136                case 0x000c:                case 0x000c:
4137                case 0x0085:                case 0x0085:
4138                case 0x2028:                case 0x2028:
4139                case 0x2029:                case 0x2029:
4140                  if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH);
4141                  break;
4142                  }
4143                break;
4144    
4145                case OP_NOT_HSPACE:
4146                switch(c)
4147                  {
4148                  default: break;
4149                  case 0x09:      /* HT */
4150                  case 0x20:      /* SPACE */
4151                  case 0xa0:      /* NBSP */
4152                  case 0x1680:    /* OGHAM SPACE MARK */
4153                  case 0x180e:    /* MONGOLIAN VOWEL SEPARATOR */
4154                  case 0x2000:    /* EN QUAD */
4155                  case 0x2001:    /* EM QUAD */
4156                  case 0x2002:    /* EN SPACE */
4157                  case 0x2003:    /* EM SPACE */
4158                  case 0x2004:    /* THREE-PER-EM SPACE */
4159                  case 0x2005:    /* FOUR-PER-EM SPACE */
4160                  case 0x2006:    /* SIX-PER-EM SPACE */
4161                  case 0x2007:    /* FIGURE SPACE */
4162                  case 0x2008:    /* PUNCTUATION SPACE */
4163                  case 0x2009:    /* THIN SPACE */
4164                  case 0x200A:    /* HAIR SPACE */
4165                  case 0x202f:    /* NARROW NO-BREAK SPACE */
4166                  case 0x205f:    /* MEDIUM MATHEMATICAL SPACE */
4167                  case 0x3000:    /* IDEOGRAPHIC SPACE */
4168                  RRETURN(MATCH_NOMATCH);
4169                  }
4170                break;
4171    
4172                case OP_HSPACE:
4173                switch(c)
4174                  {
4175                  default: RRETURN(MATCH_NOMATCH);
4176                  case 0x09:      /* HT */
4177                  case 0x20:      /* SPACE */
4178                  case 0xa0:      /* NBSP */
4179                  case 0x1680:    /* OGHAM SPACE MARK */
4180                  case 0x180e:    /* MONGOLIAN VOWEL SEPARATOR */
4181                  case 0x2000:    /* EN QUAD */
4182                  case 0x2001:    /* EM QUAD */
4183                  case 0x2002:    /* EN SPACE */
4184                  case 0x2003:    /* EM SPACE */
4185                  case 0x2004:    /* THREE-PER-EM SPACE */
4186                  case 0x2005:    /* FOUR-PER-EM SPACE */
4187                  case 0x2006:    /* SIX-PER-EM SPACE */
4188                  case 0x2007:    /* FIGURE SPACE */
4189                  case 0x2008:    /* PUNCTUATION SPACE */
4190                  case 0x2009:    /* THIN SPACE */
4191                  case 0x200A:    /* HAIR SPACE */
4192                  case 0x202f:    /* NARROW NO-BREAK SPACE */
4193                  case 0x205f:    /* MEDIUM MATHEMATICAL SPACE */
4194                  case 0x3000:    /* IDEOGRAPHIC SPACE */
4195                  break;
4196                  }
4197                break;
4198    
4199                case OP_NOT_VSPACE:
4200                switch(c)
4201                  {
4202                  default: break;
4203                  case 0x0a:      /* LF */
4204                  case 0x0b:      /* VT */
4205                  case 0x0c:      /* FF */
4206                  case 0x0d:      /* CR */
4207                  case 0x85:      /* NEL */
4208                  case 0x2028:    /* LINE SEPARATOR */
4209                  case 0x2029:    /* PARAGRAPH SEPARATOR */
4210                  RRETURN(MATCH_NOMATCH);
4211                  }
4212                break;
4213    
4214                case OP_VSPACE:
4215                switch(c)
4216                  {
4217                  default: RRETURN(MATCH_NOMATCH);
4218                  case 0x0a:      /* LF */
4219                  case 0x0b:      /* VT */
4220                  case 0x0c:      /* FF */
4221                  case 0x0d:      /* CR */
4222                  case 0x85:      /* NEL */
4223                  case 0x2028:    /* LINE SEPARATOR */
4224                  case 0x2029:    /* PARAGRAPH SEPARATOR */
4225                break;                break;
4226                }                }
4227              break;              break;
# Line 3159  for (;;) Line 4269  for (;;)
4269            {            {
4270            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM43);            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM43);
4271            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
4272            if (fi >= max || eptr >= md->end_subject ||            if (fi >= max) RRETURN(MATCH_NOMATCH);
4273                 ((ims & PCRE_DOTALL) == 0 && IS_NEWLINE(eptr)))            if (eptr >= md->end_subject)
4274                {
4275                SCHECK_PARTIAL();
4276                RRETURN(MATCH_NOMATCH);
4277                }
4278              if (ctype == OP_ANY && IS_NEWLINE(eptr))
4279              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
   
4280            c = *eptr++;            c = *eptr++;
4281            switch(ctype)            switch(ctype)
4282              {              {
4283              case OP_ANY:   /* This is the DOTALL case */              case OP_ANY:     /* This is the non-NL case */
4284              break;              case OP_ALLANY:
   
4285              case OP_ANYBYTE:              case OP_ANYBYTE:
4286              break;              break;
4287    
# Line 3179  for (;;) Line 4292  for (;;)
4292                case 0x000d:                case 0x000d:
4293                if (eptr < md->end_subject && *eptr == 0x0a) eptr++;                if (eptr < md->end_subject && *eptr == 0x0a) eptr++;
4294                break;                break;
4295    
4296                case 0x000a:                case 0x000a:
4297                  break;
4298    
4299                case 0x000b:                case 0x000b:
4300                case 0x000c:                case 0x000c:
4301                case 0x0085:                case 0x0085:
4302                  if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH);
4303                  break;
4304                  }
4305                break;
4306    
4307                case OP_NOT_HSPACE:
4308                switch(c)
4309                  {
4310                  default: break;
4311                  case 0x09:      /* HT */
4312                  case 0x20:      /* SPACE */
4313                  case 0xa0:      /* NBSP */
4314                  RRETURN(MATCH_NOMATCH);
4315                  }
4316                break;
4317    
4318                case OP_HSPACE:
4319                switch(c)
4320                  {
4321                  default: RRETURN(MATCH_NOMATCH);
4322                  case 0x09:      /* HT */
4323                  case 0x20:      /* SPACE */
4324                  case 0xa0:      /* NBSP */
4325                  break;
4326                  }
4327                break;
4328    
4329                case OP_NOT_VSPACE:
4330                switch(c)
4331                  {
4332                  default: break;
4333                  case 0x0a:      /* LF */
4334                  case 0x0b:      /* VT */
4335                  case 0x0c:      /* FF */
4336                  case 0x0d:      /* CR */
4337                  case 0x85:      /* NEL */
4338                  RRETURN(MATCH_NOMATCH);
4339                  }
4340                break;
4341    
4342                case OP_VSPACE:
4343                switch(c)
4344                  {
4345                  default: RRETURN(MATCH_NOMATCH);
4346                  case 0x0a:      /* LF */
4347                  case 0x0b:      /* VT */
4348                  case 0x0c:      /* FF */
4349                  case 0x0d:      /* CR */
4350                  case 0x85:      /* NEL */
4351                break;                break;
4352                }                }
4353              break;              break;
# Line 3236  for (;;) Line 4401  for (;;)
4401            for (i = min; i < max; i++)            for (i = min; i < max; i++)
4402              {              {
4403              int len = 1;              int len = 1;
4404              if (eptr >= md->end_subject) break;              if (eptr >= md->end_subject)
4405                  {
4406                  SCHECK_PARTIAL();
4407                  break;
4408                  }
4409              GETCHARLEN(c, eptr, len);              GETCHARLEN(c, eptr, len);
4410              if (prop_fail_result) break;              if (prop_fail_result) break;
4411              eptr+= len;              eptr+= len;
# Line 3247  for (;;) Line 4416  for (;;)
4416            for (i = min; i < max; i++)            for (i = min; i < max; i++)
4417              {              {
4418              int len = 1;              int len = 1;
4419              if (eptr >= md->end_subject) break;              if (eptr >= md->end_subject)
4420                  {
4421                  SCHECK_PARTIAL();
4422                  break;
4423                  }
4424              GETCHARLEN(c, eptr, len);              GETCHARLEN(c, eptr, len);
4425              prop_category = _pcre_ucp_findprop(c, &prop_chartype, &prop_script);              prop_chartype = UCD_CHARTYPE(c);
4426              if ((prop_chartype == ucp_Lu ||              if ((prop_chartype == ucp_Lu ||
4427                   prop_chartype == ucp_Ll ||                   prop_chartype == ucp_Ll ||
4428                   prop_chartype == ucp_Lt) == prop_fail_result)                   prop_chartype == ucp_Lt) == prop_fail_result)
# Line 3262  for (;;) Line 4435  for (;;)
4435            for (i = min; i < max; i++)            for (i = min; i < max; i++)
4436              {              {
4437              int len = 1;              int len = 1;
4438              if (eptr >= md->end_subject) break;              if (eptr >= md->end_subject)
4439                  {
4440                  SCHECK_PARTIAL();
4441                  break;
4442                  }
4443              GETCHARLEN(c, eptr, len);              GETCHARLEN(c, eptr, len);
4444              prop_category = _pcre_ucp_findprop(c, &prop_chartype, &prop_script);              prop_category = UCD_CATEGORY(c);
4445              if ((prop_category == prop_value) == prop_fail_result)              if ((prop_category == prop_value) == prop_fail_result)
4446                break;                break;
4447              eptr+= len;              eptr+= len;
# Line 3275  for (;;) Line 4452  for (;;)
4452            for (i = min; i < max; i++)            for (i = min; i < max; i++)
4453              {              {
4454              int len = 1;              int len = 1;
4455              if (eptr >= md->end_subject) break;              if (eptr >= md->end_subject)
4456                  {
4457                  SCHECK_PARTIAL();
4458                  break;
4459                  }
4460              GETCHARLEN(c, eptr, len);              GETCHARLEN(c, eptr, len);
4461              prop_category = _pcre_ucp_findprop(c, &prop_chartype, &prop_script);              prop_chartype = UCD_CHARTYPE(c);
4462              if ((prop_chartype == prop_value) == prop_fail_result)              if ((prop_chartype == prop_value) == prop_fail_result)
4463                break;                break;
4464              eptr+= len;              eptr+= len;
# Line 3288  for (;;) Line 4469  for (;;)
4469            for (i = min; i < max; i++)            for (i = min; i < max; i++)
4470              {              {
4471              int len = 1;              int len = 1;
4472              if (eptr >= md->end_subject) break;              if (eptr >= md->end_subject)
4473                  {
4474                  SCHECK_PARTIAL();
4475                  break;
4476                  }
4477              GETCHARLEN(c, eptr, len);              GETCHARLEN(c, eptr, len);
4478              prop_category = _pcre_ucp_findprop(c, &prop_chartype, &prop_script);              prop_script = UCD_SCRIPT(c);
4479              if ((prop_script == prop_value) == prop_fail_result)              if ((prop_script == prop_value) == prop_fail_result)
4480                break;                break;
4481              eptr+= len;              eptr+= len;
# Line 3306  for (;;) Line 4491  for (;;)
4491            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM44);            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM44);
4492            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
4493            if (eptr-- == pp) break;        /* Stop if tried at original pos */            if (eptr-- == pp) break;        /* Stop if tried at original pos */
4494            BACKCHAR(eptr);            if (utf8) BACKCHAR(eptr);
4495            }            }
4496          }          }
4497    
# Line 3317  for (;;) Line 4502  for (;;)
4502          {          {
4503          for (i = min; i < max; i++)          for (i = min; i < max; i++)
4504            {            {
4505            if (eptr >= md->end_subject) break;            if (eptr >= md->end_subject)
4506                {
4507                SCHECK_PARTIAL();
4508                break;
4509                }
4510            GETCHARINCTEST(c, eptr);            GETCHARINCTEST(c, eptr);
4511            prop_category = _pcre_ucp_findprop(c, &prop_chartype, &prop_script);            prop_category = UCD_CATEGORY(c);
4512            if (prop_category == ucp_M) break;            if (prop_category == ucp_M) break;
4513            while (eptr < md->end_subject)            while (eptr < md->end_subject)
4514              {              {
# Line 3328  for (;;) Line 4517  for (;;)
4517                {                {
4518                GETCHARLEN(c, eptr, len);                GETCHARLEN(c, eptr, len);
4519                }                }
4520              prop_category = _pcre_ucp_findprop(c, &prop_chartype, &prop_script);              prop_category = UCD_CATEGORY(c);
4521              if (prop_category != ucp_M) break;              if (prop_category != ucp_M) break;
4522              eptr += len;              eptr += len;
4523              }              }
# Line 3337  for (;;) Line 4526  for (;;)
4526          /* eptr is now past the end of the maximum run */          /* eptr is now past the end of the maximum run */
4527    
4528          if (possessive) continue;          if (possessive) continue;
4529    
4530          for(;;)          for(;;)
4531            {            {
4532            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM45);            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM45);
# Line 3345  for (;;) Line 4535  for (;;)
4535            for (;;)                        /* Move back over one extended */            for (;;)                        /* Move back over one extended */
4536              {              {
4537              int len = 1;              int len = 1;
             BACKCHAR(eptr);  
4538              if (!utf8) c = *eptr; else              if (!utf8) c = *eptr; else
4539                {                {
4540                  BACKCHAR(eptr);
4541                GETCHARLEN(c, eptr, len);                GETCHARLEN(c, eptr, len);
4542                }                }
4543              prop_category = _pcre_ucp_findprop(c, &prop_chartype, &prop_script);              prop_category = UCD_CATEGORY(c);
4544              if (prop_category != ucp_M) break;              if (prop_category != ucp_M) break;
4545              eptr--;              eptr--;
4546              }              }
# Line 3368  for (;;) Line 4558  for (;;)
4558          switch(ctype)          switch(ctype)
4559            {            {
4560            case OP_ANY:            case OP_ANY:
   
           /* Special code is required for UTF8, but when the maximum is  
           unlimited we don't need it, so we repeat the non-UTF8 code. This is  
           probably worth it, because .* is quite a common idiom. */  
   
4561            if (max < INT_MAX)            if (max < INT_MAX)
4562              {              {
4563              if ((ims & PCRE_DOTALL) == 0)              for (i = min; i < max; i++)
               {  
               for (i = min; i < max; i++)  
                 {  
                 if (eptr >= md->end_subject || IS_NEWLINE(eptr)) break;  
                 eptr++;  
                 while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;  
                 }  
               }  
             else  
4564                {                {
4565                for (i = min; i < max; i++)                if (eptr >= md->end_subject)
4566                  {                  {
4567                  if (eptr >= md->end_subject) break;                  SCHECK_PARTIAL();
4568                  eptr++;                  break;
                 while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;  
4569                  }                  }
4570                  if (IS_NEWLINE(eptr)) break;
4571                  eptr++;
4572                  while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;
4573                }                }
4574              }              }
4575    
# Line 3399  for (;;) Line 4577  for (;;)
4577    
4578            else            else
4579              {              {
4580              if ((ims & PCRE_DOTALL) == 0)              for (i = min; i < max; i++)
4581                {                {
4582                for (i = min; i < max; i++)                if (eptr >= md->end_subject)
4583                  {                  {
4584                  if (eptr >= md->end_subject || IS_NEWLINE(eptr)) break;                  SCHECK_PARTIAL();
4585                  eptr++;                  break;
4586                  }                  }
4587                break;                if (IS_NEWLINE(eptr)) break;
4588                  eptr++;
4589                  while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;
4590                }                }
4591              else              }
4592              break;
4593    
4594              case OP_ALLANY:
4595              if (max < INT_MAX)
4596                {
4597                for (i = min; i < max; i++)
4598                {                {
4599                c = max - min;                if (eptr >= md->end_subject)
4600                if (c > (unsigned int)(md->end_subject - eptr))                  {
4601                  c = md->end_subject - eptr;                  SCHECK_PARTIAL();
4602                eptr += c;                  break;
4603                    }
4604                  eptr++;
4605                  while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;
4606                }                }
4607              }              }
4608              else eptr = md->end_subject;   /* Unlimited UTF-8 repeat */
4609            break;            break;
4610    
4611            /* The byte case is the same as non-UTF8 */            /* The byte case is the same as non-UTF8 */
# Line 3423  for (;;) Line 4613  for (;;)
4613            case OP_ANYBYTE:            case OP_ANYBYTE:
4614            c = max - min;            c = max - min;
4615            if (c > (unsigned int)(md->end_subject - eptr))            if (c > (unsigned int)(md->end_subject - eptr))
4616              c = md->end_subject - eptr;              {
4617            eptr += c;              eptr = md->end_subject;
4618                SCHECK_PARTIAL();
4619                }
4620              else eptr += c;
4621            break;            break;
4622    
4623            case OP_ANYNL:            case OP_ANYNL:
4624            for (i = min; i < max; i++)            for (i = min; i < max; i++)
4625              {              {
4626              int len = 1;              int len = 1;
4627              if (eptr >= md->end_subject) break;              if (eptr >= md->end_subject)
4628                  {
4629                  SCHECK_PARTIAL();
4630                  break;
4631                  }
4632              GETCHARLEN(c, eptr, len);              GETCHARLEN(c, eptr, len);
4633              if (c == 0x000d)              if (c == 0x000d)
4634                {                {
# Line 3440  for (;;) Line 4637  for (;;)
4637                }                }
4638              else              else
4639                {                {
4640                if (c != 0x000a && c != 0x000b && c != 0x000c &&                if (c != 0x000a &&
4641                    c != 0x0085 && c != 0x2028 && c != 0x2029)                    (md->bsr_anycrlf ||
4642                       (c != 0x000b && c != 0x000c &&
4643                        c != 0x0085 && c != 0x2028 && c != 0x2029)))
4644                  break;                  break;
4645                eptr += len;                eptr += len;
4646                }                }
4647              }              }
4648            break;            break;
4649    
4650              case OP_NOT_HSPACE:
4651              case OP_HSPACE:
4652              for (i = min; i < max; i++)
4653                {
4654                BOOL gotspace;
4655                int len = 1;
4656                if (eptr >= md->end_subject)
4657                  {
4658                  SCHECK_PARTIAL();
4659                  break;
4660                  }
4661                GETCHARLEN(c, eptr, len);
4662                switch(c)
4663                  {
4664                  default: gotspace = FALSE; break;
4665                  case 0x09:      /* HT */
4666                  case 0x20:      /* SPACE */
4667                  case 0xa0:      /* NBSP */
4668                  case 0x1680:    /* OGHAM SPACE MARK */
4669                  case 0x180e:    /* MONGOLIAN VOWEL SEPARATOR */
4670                  case 0x2000:    /* EN QUAD */
4671                  case 0x2001:    /* EM QUAD */
4672                  case 0x2002:    /* EN SPACE */
4673                  case 0x2003:    /* EM SPACE */
4674                  case 0x2004:    /* THREE-PER-EM SPACE */
4675                  case 0x2005:    /* FOUR-PER-EM SPACE */
4676                  case 0x2006:    /* SIX-PER-EM SPACE */
4677                  case 0x2007:    /* FIGURE SPACE */
4678                  case 0x2008:    /* PUNCTUATION SPACE */
4679                  case 0x2009:    /* THIN SPACE */
4680                  case 0x200A:    /* HAIR SPACE */
4681                  case 0x202f:    /* NARROW NO-BREAK SPACE */
4682                  case 0x205f:    /* MEDIUM MATHEMATICAL SPACE */
4683                  case 0x3000:    /* IDEOGRAPHIC SPACE */
4684                  gotspace = TRUE;
4685                  break;
4686                  }
4687                if (gotspace == (ctype == OP_NOT_HSPACE)) break;
4688                eptr += len;
4689                }
4690              break;
4691    
4692              case OP_NOT_VSPACE:
4693              case OP_VSPACE:
4694              for (i = min; i < max; i++)
4695                {
4696                BOOL gotspace;
4697                int len = 1;
4698                if (eptr >= md->end_subject)
4699                  {
4700                  SCHECK_PARTIAL();
4701                  break;
4702                  }
4703                GETCHARLEN(c, eptr, len);
4704                switch(c)
4705                  {
4706                  default: gotspace = FALSE; break;
4707                  case 0x0a:      /* LF */
4708                  case 0x0b:      /* VT */
4709                  case 0x0c:      /* FF */
4710                  case 0x0d:      /* CR */
4711                  case 0x85:      /* NEL */
4712                  case 0x2028:    /* LINE SEPARATOR */
4713                  case 0x2029:    /* PARAGRAPH SEPARATOR */
4714                  gotspace = TRUE;
4715                  break;
4716                  }
4717                if (gotspace == (ctype == OP_NOT_VSPACE)) break;
4718                eptr += len;
4719                }
4720              break;
4721    
4722            case OP_NOT_DIGIT:            case OP_NOT_DIGIT:
4723            for (i = min; i < max; i++)            for (i = min; i < max; i++)
4724              {              {
4725              int len = 1;              int len = 1;
4726              if (eptr >= md->end_subject) break;              if (eptr >= md->end_subject)
4727                  {
4728                  SCHECK_PARTIAL();
4729                  break;
4730                  }
4731              GETCHARLEN(c, eptr, len);              GETCHARLEN(c, eptr, len);
4732              if (c < 256 && (md->ctypes[c] & ctype_digit) != 0) break;              if (c < 256 && (md->ctypes[c] & ctype_digit) != 0) break;
4733              eptr+= len;              eptr+= len;
# Line 3463  for (;;) Line 4738  for (;;)
4738            for (i = min; i < max; i++)            for (i = min; i < max; i++)
4739              {              {
4740              int len = 1;              int len = 1;
4741              if (eptr >= md->end_subject) break;              if (eptr >= md->end_subject)
4742                  {
4743                  SCHECK_PARTIAL();
4744                  break;
4745                  }
4746              GETCHARLEN(c, eptr, len);              GETCHARLEN(c, eptr, len);
4747              if (c >= 256 ||(md->ctypes[c] & ctype_digit) == 0) break;              if (c >= 256 ||(md->ctypes[c] & ctype_digit) == 0) break;
4748              eptr+= len;              eptr+= len;
# Line 3474  for (;;) Line 4753  for (;;)
4753            for (i = min; i < max; i++)            for (i = min; i < max; i++)
4754              {              {
4755              int len = 1;              int len = 1;
4756              if (eptr >= md->end_subject) break;              if (eptr >= md->end_subject)
4757                  {
4758                  SCHECK_PARTIAL();
4759                  break;
4760                  }
4761              GETCHARLEN(c, eptr, len);              GETCHARLEN(c, eptr, len);
4762              if (c < 256 && (md->ctypes[c] & ctype_space) != 0) break;              if (c < 256 && (md->ctypes[c] & ctype_space) != 0) break;
4763              eptr+= len;              eptr+= len;
# Line 3485  for (;;) Line 4768  for (;;)
4768            for (i = min; i < max; i++)            for (i = min; i < max; i++)
4769              {              {
4770              int len = 1;              int len = 1;
4771              if (eptr >= md->end_subject) break;              if (eptr >= md->end_subject)
4772                  {
4773                  SCHECK_PARTIAL();
4774                  break;
4775                  }
4776              GETCHARLEN(c, eptr, len);              GETCHARLEN(c, eptr, len);
4777              if (c >= 256 ||(md->ctypes[c] & ctype_space) == 0) break;              if (c >= 256 ||(md->ctypes[c] & ctype_space) == 0) break;
4778              eptr+= len;              eptr+= len;
# Line 3496  for (;;) Line 4783  for (;;)
4783            for (i = min; i < max; i++)            for (i = min; i < max; i++)
4784              {              {
4785              int len = 1;              int len = 1;
4786              if (eptr >= md->end_subject) break;              if (eptr >= md->end_subject)
4787                  {
4788                  SCHECK_PARTIAL();
4789                  break;
4790                  }
4791              GETCHARLEN(c, eptr, len);              GETCHARLEN(c, eptr, len);
4792              if (c < 256 && (md->ctypes[c] & ctype_word) != 0) break;              if (c < 256 && (md->ctypes[c] & ctype_word) != 0) break;
4793              eptr+= len;              eptr+= len;
# Line 3507  for (;;) Line 4798  for (;;)
4798            for (i = min; i < max; i++)            for (i = min; i < max; i++)
4799              {              {
4800              int len = 1;              int len = 1;
4801              if (eptr >= md->end_subject) break;              if (eptr >= md->end_subject)
4802                  {
4803                  SCHECK_PARTIAL();
4804                  break;
4805                  }
4806              GETCHARLEN(c, eptr, len);              GETCHARLEN(c, eptr, len);
4807              if (c >= 256 || (md->ctypes[c] & ctype_word) == 0) break;              if (c >= 256 || (md->ctypes[c] & ctype_word) == 0) break;
4808              eptr+= len;              eptr+= len;
# Line 3530  for (;;) Line 4825  for (;;)
4825            }            }
4826          }          }
4827        else        else
4828  #endif  #endif  /* SUPPORT_UTF8 */
4829    
4830        /* Not UTF-8 mode */        /* Not UTF-8 mode */
4831          {          {
4832          switch(ctype)          switch(ctype)
4833            {            {
4834            case OP_ANY:            case OP_ANY:
4835            if ((ims & PCRE_DOTALL) == 0)            for (i = min; i < max; i++)
4836              {              {
4837              for (i = min; i < max; i++)              if (eptr >= md->end_subject)
4838                {                {
4839                if (eptr >= md->end_subject || IS_NEWLINE(eptr)) break;                SCHECK_PARTIAL();
4840                eptr++;                break;
4841                }                }
4842              break;              if (IS_NEWLINE(eptr)) break;
4843                eptr++;
4844              }              }
4845            /* For DOTALL case, fall through and treat as \C */            break;
4846    
4847              case OP_ALLANY:
4848            case OP_ANYBYTE:            case OP_ANYBYTE:
4849            c = max - min;            c = max - min;
4850            if (c > (unsigned int)(md->end_subject - eptr))            if (c > (unsigned int)(md->end_subject - eptr))
4851              c = md->end_subject - eptr;              {
4852            eptr += c;              eptr = md->end_subject;
4853                SCHECK_PARTIAL();
4854                }
4855              else eptr += c;
4856            break;            break;
4857    
4858            case OP_ANYNL:            case OP_ANYNL:
4859            for (i = min; i < max; i++)            for (i = min; i < max; i++)
4860              {              {
4861              if (eptr >= md->end_subject) break;              if (eptr >= md->end_subject)
4862                  {
4863                  SCHECK_PARTIAL();
4864                  break;
4865                  }
4866              c = *eptr;              c = *eptr;
4867              if (c == 0x000d)              if (c == 0x000d)
4868                {                {
# Line 3567  for (;;) Line 4871  for (;;)
4871                }                }
4872              else              else
4873                {                {
4874                if (c != 0x000a && c != 0x000b && c != 0x000c && c != 0x0085)                if (c != 0x000a &&
4875                      (md->bsr_anycrlf ||
4876                        (c != 0x000b && c != 0x000c && c != 0x0085)))
4877                  break;                  break;
4878                eptr++;                eptr++;
4879                }                }
4880              }              }
4881            break;            break;
4882    
4883              case OP_NOT_HSPACE:
4884              for (i = min; i < max; i++)
4885                {
4886                if (eptr >= md->end_subject)
4887                  {
4888                  SCHECK_PARTIAL();
4889                  break;
4890                  }
4891                c = *eptr;
4892                if (c == 0x09 || c == 0x20 || c == 0xa0) break;
4893                eptr++;
4894                }
4895              break;
4896    
4897              case OP_HSPACE:
4898              for (i = min; i < max; i++)
4899                {
4900                if (eptr >= md->end_subject)
4901                  {
4902                  SCHECK_PARTIAL();
4903                  break;
4904                  }
4905                c = *eptr;
4906                if (c != 0x09 && c != 0x20 && c != 0xa0) break;
4907                eptr++;
4908                }
4909              break;
4910    
4911              case OP_NOT_VSPACE:
4912              for (i = min; i < max; i++)
4913                {
4914                if (eptr >= md->end_subject)
4915                  {
4916                  SCHECK_PARTIAL();
4917                  break;
4918                  }
4919                c = *eptr;
4920                if (c == 0x0a || c == 0x0b || c == 0x0c || c == 0x0d || c == 0x85)
4921                  break;
4922                eptr++;
4923                }
4924              break;
4925    
4926              case OP_VSPACE:
4927              for (i = min; i < max; i++)
4928                {
4929                if (eptr >= md->end_subject)
4930                  {
4931                  SCHECK_PARTIAL();
4932                  break;
4933                  }
4934                c = *eptr;
4935                if (c != 0x0a && c != 0x0b && c != 0x0c && c != 0x0d && c != 0x85)
4936                  break;
4937                eptr++;
4938                }
4939              break;
4940    
4941            case OP_NOT_DIGIT:            case OP_NOT_DIGIT:
4942            for (i = min; i < max; i++)            for (i = min; i < max; i++)
4943              {              {
4944              if (eptr >= md->end_subject || (md->ctypes[*eptr] & ctype_digit) != 0)              if (eptr >= md->end_subject)
4945                  {
4946                  SCHECK_PARTIAL();
4947                break;                break;
4948                  }
4949                if ((md->ctypes[*eptr] & ctype_digit) != 0) break;
4950              eptr++;              eptr++;
4951              }              }
4952            break;            break;
# Line 3586  for (;;) Line 4954  for (;;)
4954            case OP_DIGIT:            case OP_DIGIT:
4955            for (i = min; i < max; i++)            for (i = min; i < max; i++)
4956              {              {
4957              if (eptr >= md->end_subject || (md->ctypes[*eptr] & ctype_digit) == 0)              if (eptr >= md->end_subject)
4958                  {
4959                  SCHECK_PARTIAL();
4960                break;                break;
4961                  }
4962                if ((md->ctypes[*eptr] & ctype_digit) == 0) break;
4963              eptr++;              eptr++;
4964              }              }
4965            break;            break;
# Line 3595  for (;;) Line 4967  for (;;)
4967            case OP_NOT_WHITESPACE:            case OP_NOT_WHITESPACE:
4968            for (i = min; i < max; i++)            for (i = min; i < max; i++)
4969              {              {
4970              if (eptr >= md->end_subject || (md->ctypes[*eptr] & ctype_space) != 0)              if (eptr >= md->end_subject)
4971                  {
4972                  SCHECK_PARTIAL();
4973                break;                break;
4974                  }
4975                if ((md->ctypes[*eptr] & ctype_space) != 0) break;
4976              eptr++;              eptr++;
4977              }              }
4978            break;            break;
# Line 3604  for (;;) Line 4980  for (;;)
4980            case OP_WHITESPACE:            case OP_WHITESPACE:
4981            for (i = min; i < max; i++)            for (i = min; i < max; i++)
4982              {              {
4983              if (eptr >= md->end_subject || (md->ctypes[*eptr] & ctype_space) == 0)              if (eptr >= md->end_subject)
4984                  {
4985                  SCHECK_PARTIAL();
4986                break;                break;
4987                  }
4988                if ((md->ctypes[*eptr] & ctype_space) == 0) break;
4989              eptr++;              eptr++;
4990              }              }
4991            break;            break;
# Line 3613  for (;;) Line 4993  for (;;)
4993            case OP_NOT_WORDCHAR:            case OP_NOT_WORDCHAR:
4994            for (i = min; i < max; i++)            for (i = min; i < max; i++)
4995              {              {
4996              if (eptr >= md->end_subject || (md->ctypes[*eptr] & ctype_word) != 0)              if (eptr >= md->end_subject)
4997                  {
4998                  SCHECK_PARTIAL();
4999                break;                break;
5000                  }