/[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 354 by ph10, Mon Jul 7 16:30:33 2008 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-2008 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 89  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 141  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 168  if ((ims & PCRE_CASELESS) != 0) Line 168  if ((ims & PCRE_CASELESS) != 0)
168  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
169    if (md->utf8)    if (md->utf8)
170      {      {
171      USPTR endptr = eptr + length;      USPTR endptr = eptr + length;
172      while (eptr < endptr)      while (eptr < endptr)
173        {        {
174        int c, d;        int c, d;
175        GETCHARINC(c, eptr);        GETCHARINC(c, eptr);
176        GETCHARINC(d, p);        GETCHARINC(d, p);
177        if (c != d && c != UCD_OTHERCASE(d)) return FALSE;        if (c != d && c != UCD_OTHERCASE(d)) return FALSE;
178        }        }
179      }      }
180    else    else
181  #endif  #endif
182  #endif  #endif
183    
184    /* The same code works when not in UTF-8 mode and in UTF-8 mode when there    /* The same code works when not in UTF-8 mode and in UTF-8 mode when there
185    is no UCP support. */    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  /* In the caseful case, we can just compare the bytes, whether or not we
192  are in UTF-8 mode. */  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 254  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 322  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 333  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 360  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 395  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 425  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 439  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 481  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 561  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 594  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 636  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:      case OP_FAIL:
# Line 693  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 787  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 829  for (;;) Line 1002  for (;;)
1002        else        else
1003          {          {
1004          condition = FALSE;          condition = FALSE;
1005          ecode += GET(ecode, 1);          ecode += codelink;
1006          }          }
1007        }        }
1008    
# Line 852  for (;;) Line 1025  for (;;)
1025          goto TAIL_RECURSE;          goto TAIL_RECURSE;
1026          }          }
1027        }        }
1028      else                         /* Condition false & no 2nd alternative */      else                         /* Condition false & no alternative */
1029        {        {
1030        ecode += 1 + LINK_SIZE;        ecode += 1 + LINK_SIZE;
1031        }        }
1032      break;      break;
1033    
1034    
1035        /* Before OP_ACCEPT there may be any number of OP_CLOSE opcodes,
1036        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      /* 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      recursion, we should restore the offsets appropriately and continue from
1061      after the call. */      after the call. */
# Line 872  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) */
# Line 907  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            {
1118            mstart = md->start_match_ptr;   /* In case \K reset it */
1119            break;
1120            }
1121        if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);        if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);
1122        ecode += GET(ecode, 1);        ecode += GET(ecode, 1);
1123        }        }
# Line 926  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 935  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_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);        if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);
1156        ecode += GET(ecode,1);        ecode += GET(ecode,1);
1157        }        }
# Line 972  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 1052  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 1075  for (;;) Line 1292  for (;;)
1292          else if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN)          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 1098  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 1107  for (;;) Line 1327  for (;;)
1327      do      do
1328        {        {
1329        RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, eptrb, 0, RM7);        RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, eptrb, 0, RM7);
1330        if (rrc == MATCH_MATCH) break;        if (rrc == MATCH_MATCH)
1331            {
1332            mstart = md->start_match_ptr;
1333            break;
1334            }
1335        if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);        if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);
1336        ecode += GET(ecode,1);        ecode += GET(ecode,1);
1337        }        }
# Line 1226  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 1236  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 1250  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 1272  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 1414  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 1435  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 1459  for (;;) Line 1699  for (;;)
1699      /* Fall through */      /* Fall through */
1700    
1701      case OP_ALLANY:      case OP_ALLANY:
1702      if (eptr++ >= md->end_subject) RRETURN(MATCH_NOMATCH);      if (eptr++ >= md->end_subject)
1703          {
1704          SCHECK_PARTIAL();
1705          RRETURN(MATCH_NOMATCH);
1706          }
1707      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;
# Line 1468  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 1486  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 1499  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 1512  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 1525  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 1538  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 1551  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 1575  for (;;) Line 1851  for (;;)
1851      break;      break;
1852    
1853      case OP_NOT_HSPACE:      case OP_NOT_HSPACE:
1854      if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);      if (eptr >= md->end_subject)
1855          {
1856          SCHECK_PARTIAL();
1857          RRETURN(MATCH_NOMATCH);
1858          }
1859      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
1860      switch(c)      switch(c)
1861        {        {
# Line 1605  for (;;) Line 1885  for (;;)
1885      break;      break;
1886    
1887      case OP_HSPACE:      case OP_HSPACE:
1888      if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);      if (eptr >= md->end_subject)
1889          {
1890          SCHECK_PARTIAL();
1891          RRETURN(MATCH_NOMATCH);
1892          }
1893      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
1894      switch(c)      switch(c)
1895        {        {
# Line 1635  for (;;) Line 1919  for (;;)
1919      break;      break;
1920    
1921      case OP_NOT_VSPACE:      case OP_NOT_VSPACE:
1922      if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);      if (eptr >= md->end_subject)
1923          {
1924          SCHECK_PARTIAL();
1925          RRETURN(MATCH_NOMATCH);
1926          }
1927      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
1928      switch(c)      switch(c)
1929        {        {
# Line 1653  for (;;) Line 1941  for (;;)
1941      break;      break;
1942    
1943      case OP_VSPACE:      case OP_VSPACE:
1944      if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);      if (eptr >= md->end_subject)
1945          {
1946          SCHECK_PARTIAL();
1947          RRETURN(MATCH_NOMATCH);
1948          }
1949      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
1950      switch(c)      switch(c)
1951        {        {
# Line 1676  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        const ucd_record * prop = GET_UCD(c);        const ucd_record *prop = GET_UCD(c);
1979    
1980        switch(ecode[1])        switch(ecode[1])
1981          {          {
# Line 1721  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 category = UCD_CATEGORY(c);        int category = UCD_CATEGORY(c);
# Line 1801  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 1817  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 1834  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 1848  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 1862  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 1918  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 1936  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 1960  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 1980  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 2001  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 2027  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 2047  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 2088  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 2107  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 2122  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 2150  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 2158  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 2174  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 2209  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 2263  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 2278  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 2296  for (;;) Line 2664  for (;;)
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 2318  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 2340  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 2379  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 2400  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 2408  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 2419  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 2438  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 2456  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            eptr++;              {
2861            }              SCHECK_PARTIAL();
2862                break;
2863                }
2864              if (fc != *eptr) break;
2865              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 2475  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 2552  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 2582  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 2593  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 2609  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 2623  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 2644  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 2665  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 2693  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 2702  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 2718  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 2731  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 2752  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 2772  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 2866  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 2884  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                  {
3355                  SCHECK_PARTIAL();
3356                  RRETURN(MATCH_NOMATCH);
3357                  }
3358              GETCHARINCTEST(c, eptr);              GETCHARINCTEST(c, eptr);
3359              }              }
3360            break;            break;
# Line 2892  for (;;) Line 3362  for (;;)
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                  {
3367                  SCHECK_PARTIAL();
3368                  RRETURN(MATCH_NOMATCH);
3369                  }
3370              GETCHARINCTEST(c, eptr);              GETCHARINCTEST(c, eptr);
3371              prop_chartype = UCD_CHARTYPE(c);              prop_chartype = UCD_CHARTYPE(c);
3372              if ((prop_chartype == ucp_Lu ||              if ((prop_chartype == ucp_Lu ||
# Line 2905  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                  {
3384                  SCHECK_PARTIAL();
3385                  RRETURN(MATCH_NOMATCH);
3386                  }
3387              GETCHARINCTEST(c, eptr);              GETCHARINCTEST(c, eptr);
3388              prop_category = UCD_CATEGORY(c);              prop_category = UCD_CATEGORY(c);
3389              if ((prop_category == prop_value) == prop_fail_result)              if ((prop_category == prop_value) == prop_fail_result)
# Line 2916  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                  {
3399                  SCHECK_PARTIAL();
3400                  RRETURN(MATCH_NOMATCH);
3401                  }
3402              GETCHARINCTEST(c, eptr);              GETCHARINCTEST(c, eptr);
3403              prop_chartype = UCD_CHARTYPE(c);              prop_chartype = UCD_CHARTYPE(c);
3404              if ((prop_chartype == prop_value) == prop_fail_result)              if ((prop_chartype == prop_value) == prop_fail_result)
# Line 2927  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                  {
3414                  SCHECK_PARTIAL();
3415                  RRETURN(MATCH_NOMATCH);
3416                  }
3417              GETCHARINCTEST(c, eptr);              GETCHARINCTEST(c, eptr);
3418              prop_script = UCD_SCRIPT(c);              prop_script = UCD_SCRIPT(c);
3419              if ((prop_script == prop_value) == prop_fail_result)              if ((prop_script == prop_value) == prop_fail_result)
# Line 2947  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 = UCD_CATEGORY(c);            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); }
               GETCHARLEN(c, eptr, len);  
               }  
3449              prop_category = UCD_CATEGORY(c);              prop_category = UCD_CATEGORY(c);
3450              if (prop_category != ucp_M) break;              if (prop_category != ucp_M) break;
3451              eptr += len;              eptr += len;
# Line 2975  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 || IS_NEWLINE(eptr))            if (eptr >= md->end_subject)
3468                {
3469                SCHECK_PARTIAL();
3470              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
3471                }
3472              if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH);
3473            eptr++;            eptr++;
3474            while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;            while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;
3475            }            }
# Line 2985  for (;;) Line 3478  for (;;)
3478          case OP_ALLANY:          case OP_ALLANY:
3479          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3480            {            {
3481            if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);            if (eptr >= md->end_subject)
3482                {
3483                SCHECK_PARTIAL();
3484                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 3024  for (;;) Line 3526  for (;;)
3526          case OP_NOT_HSPACE:          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            switch(c)            switch(c)
3536              {              {
# Line 3056  for (;;) Line 3562  for (;;)
3562          case OP_HSPACE:          case OP_HSPACE:
3563          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3564            {            {
3565            if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);            if (eptr >= md->end_subject)
3566                {
3567                SCHECK_PARTIAL();
3568                RRETURN(MATCH_NOMATCH);
3569                }
3570            GETCHARINC(c, eptr);            GETCHARINC(c, eptr);
3571            switch(c)            switch(c)
3572              {              {
# Line 3088  for (;;) Line 3598  for (;;)
3598          case OP_NOT_VSPACE:          case OP_NOT_VSPACE:
3599          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3600            {            {
3601            if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);            if (eptr >= md->end_subject)
3602                {
3603                SCHECK_PARTIAL();
3604                RRETURN(MATCH_NOMATCH);
3605                }
3606            GETCHARINC(c, eptr);            GETCHARINC(c, eptr);
3607            switch(c)            switch(c)
3608              {              {
# Line 3108  for (;;) Line 3622  for (;;)
3622          case OP_VSPACE:          case OP_VSPACE:
3623          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3624            {            {
3625            if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);            if (eptr >= md->end_subject)
3626                {
3627                SCHECK_PARTIAL();
3628                RRETURN(MATCH_NOMATCH);
3629                }
3630            GETCHARINC(c, eptr);            GETCHARINC(c, eptr);
3631            switch(c)            switch(c)
3632              {              {
# Line 3128  for (;;) Line 3646  for (;;)
3646          case OP_NOT_DIGIT:          case OP_NOT_DIGIT:
3647          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3648            {            {
3649            if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);            if (eptr >= md->end_subject)
3650                {
3651                SCHECK_PARTIAL();
3652                RRETURN(MATCH_NOMATCH);
3653                }
3654            GETCHARINC(c, eptr);            GETCHARINC(c, eptr);
3655            if (c < 128 && (md->ctypes[c] & ctype_digit) != 0)            if (c < 128 && (md->ctypes[c] & ctype_digit) != 0)
3656              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
# Line 3138  for (;;) Line 3660  for (;;)
3660          case OP_DIGIT:          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_digit) == 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            }            }
# Line 3148  for (;;) Line 3674  for (;;)
3674          case OP_NOT_WHITESPACE:          case OP_NOT_WHITESPACE:
3675          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3676            {            {
3677            if (eptr >= md->end_subject ||            if (eptr >= md->end_subject)
3678               (*eptr < 128 && (md->ctypes[*eptr] & ctype_space) != 0))              {
3679                SCHECK_PARTIAL();
3680                RRETURN(MATCH_NOMATCH);
3681                }
3682              if (*eptr < 128 && (md->ctypes[*eptr] & ctype_space) != 0)
3683              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
3684            while (++eptr < md->end_subject && (*eptr & 0xc0) == 0x80);            while (++eptr < md->end_subject && (*eptr & 0xc0) == 0x80);
3685            }            }
# Line 3158  for (;;) Line 3688  for (;;)
3688          case OP_WHITESPACE:          case OP_WHITESPACE:
3689          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3690            {            {
3691            if (eptr >= md->end_subject ||            if (eptr >= md->end_subject)
3692               *eptr >= 128 || (md->ctypes[*eptr++] & ctype_space) == 0)              {
3693                SCHECK_PARTIAL();
3694                RRETURN(MATCH_NOMATCH);
3695                }
3696              if (*eptr >= 128 || (md->ctypes[*eptr++] & ctype_space) == 0)
3697              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
3698            /* 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 */
3699            }            }
# Line 3168  for (;;) Line 3702  for (;;)
3702          case OP_NOT_WORDCHAR:          case OP_NOT_WORDCHAR:
3703          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3704            {            {
3705            if (eptr >= md->end_subject ||            if (eptr >= md->end_subject)
3706               (*eptr < 128 && (md->ctypes[*eptr] & ctype_word) != 0))              {
3707                SCHECK_PARTIAL();
3708                RRETURN(MATCH_NOMATCH);
3709                }
3710              if (*eptr < 128 && (md->ctypes[*eptr] & ctype_word) != 0)
3711              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
3712            while (++eptr < md->end_subject && (*eptr & 0xc0) == 0x80);            while (++eptr < md->end_subject && (*eptr & 0xc0) == 0x80);
3713            }            }
# Line 3178  for (;;) Line 3716  for (;;)
3716          case OP_WORDCHAR:          case OP_WORDCHAR:
3717          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3718            {            {
3719            if (eptr >= md->end_subject ||            if (eptr >= md->end_subject)
3720               *eptr >= 128 || (md->ctypes[*eptr++] & ctype_word) == 0)              {
3721                SCHECK_PARTIAL();
3722                RRETURN(MATCH_NOMATCH);
3723                }
3724              if (*eptr >= 128 || (md->ctypes[*eptr++] & ctype_word) == 0)
3725              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
3726            /* 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 */
3727            }            }
# Line 3193  for (;;) Line 3735  for (;;)
3735  #endif     /* SUPPORT_UTF8 */  #endif     /* SUPPORT_UTF8 */
3736    
3737        /* Code for the non-UTF-8 case for minimum matching of operators other        /* Code for the non-UTF-8 case for minimum matching of operators other
3738        than OP_PROP and OP_NOTPROP. We can assume that there are the minimum        than OP_PROP and OP_NOTPROP. */
       number of bytes present, as this was tested above. */  
3739    
3740        switch(ctype)        switch(ctype)
3741          {          {
3742          case OP_ANY:          case OP_ANY:
3743          for (i = 1; i <= min; i++)          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);            if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH);
3751            eptr++;            eptr++;
3752            }            }
3753          break;          break;
3754    
3755          case OP_ALLANY:          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          case OP_ANYBYTE:          case OP_ANYBYTE:
3765            if (eptr > md->end_subject - min)
3766              {
3767              SCHECK_PARTIAL();
3768              RRETURN(MATCH_NOMATCH);
3769              }
3770          eptr += min;          eptr += min;
3771          break;          break;
3772    
         /* Because of the CRLF case, we can't assume the minimum number of  
         bytes are present in this case. */  
   
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 3242  for (;;) Line 3799  for (;;)
3799          case OP_NOT_HSPACE:          case OP_NOT_HSPACE:
3800          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3801            {            {
3802            if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);            if (eptr >= md->end_subject)
3803                {
3804                SCHECK_PARTIAL();
3805                RRETURN(MATCH_NOMATCH);
3806                }
3807            switch(*eptr++)            switch(*eptr++)
3808              {              {
3809              default: break;              default: break;
# Line 3257  for (;;) Line 3818  for (;;)
3818          case OP_HSPACE:          case OP_HSPACE:
3819          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3820            {            {
3821            if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);            if (eptr >= md->end_subject)
3822                {
3823                SCHECK_PARTIAL();
3824                RRETURN(MATCH_NOMATCH);
3825                }
3826            switch(*eptr++)            switch(*eptr++)
3827              {              {
3828              default: RRETURN(MATCH_NOMATCH);              default: RRETURN(MATCH_NOMATCH);
# Line 3272  for (;;) Line 3837  for (;;)
3837          case OP_NOT_VSPACE:          case OP_NOT_VSPACE:
3838          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3839            {            {
3840            if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);            if (eptr >= md->end_subject)
3841                {
3842                SCHECK_PARTIAL();
3843                RRETURN(MATCH_NOMATCH);
3844                }
3845            switch(*eptr++)            switch(*eptr++)
3846              {              {
3847              default: break;              default: break;
# Line 3289  for (;;) Line 3858  for (;;)
3858          case OP_VSPACE:          case OP_VSPACE:
3859          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3860            {            {
3861            if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);            if (eptr >= md->end_subject)
3862                {
3863                SCHECK_PARTIAL();
3864                RRETURN(MATCH_NOMATCH);
3865                }
3866            switch(*eptr++)            switch(*eptr++)
3867              {              {
3868              default: RRETURN(MATCH_NOMATCH);              default: RRETURN(MATCH_NOMATCH);
# Line 3305  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 3360  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 3371  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_chartype = UCD_CHARTYPE(c);              prop_chartype = UCD_CHARTYPE(c);
4002              if ((prop_chartype == ucp_Lu ||              if ((prop_chartype == ucp_Lu ||
# Line 3386  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 = UCD_CATEGORY(c);              prop_category = UCD_CATEGORY(c);
4022              if ((prop_category == prop_value) == prop_fail_result)              if ((prop_category == prop_value) == prop_fail_result)
# Line 3399  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_chartype = UCD_CHARTYPE(c);              prop_chartype = UCD_CHARTYPE(c);
4040              if ((prop_chartype == prop_value) == prop_fail_result)              if ((prop_chartype == prop_value) == prop_fail_result)
# Line 3412  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_script = UCD_SCRIPT(c);              prop_script = UCD_SCRIPT(c);
4058              if ((prop_script == prop_value) == prop_fail_result)              if ((prop_script == prop_value) == prop_fail_result)
# Line 3434  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 = UCD_CATEGORY(c);            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); }
               GETCHARLEN(c, eptr, len);  
               }  
4091              prop_category = UCD_CATEGORY(c);              prop_category = UCD_CATEGORY(c);
4092              if (prop_category != ucp_M) break;              if (prop_category != ucp_M) break;
4093              eptr += len;              eptr += len;
# Line 3463  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 && IS_NEWLINE(eptr)))            if (eptr >= md->end_subject)
4111                {
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              {              {
# Line 3622  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                 (ctype == OP_ANY && 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              {              {
# Line 3750  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 3761  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_chartype = UCD_CHARTYPE(c);              prop_chartype = UCD_CHARTYPE(c);
4426              if ((prop_chartype == ucp_Lu ||              if ((prop_chartype == ucp_Lu ||
# Line 3776  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 = UCD_CATEGORY(c);              prop_category = UCD_CATEGORY(c);
4445              if ((prop_category == prop_value) == prop_fail_result)              if ((prop_category == prop_value) == prop_fail_result)
# Line 3789  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_chartype = UCD_CHARTYPE(c);              prop_chartype = UCD_CHARTYPE(c);
4462              if ((prop_chartype == prop_value) == prop_fail_result)              if ((prop_chartype == prop_value) == prop_fail_result)
# Line 3802  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_script = UCD_SCRIPT(c);              prop_script = UCD_SCRIPT(c);
4479              if ((prop_script == prop_value) == prop_fail_result)              if ((prop_script == prop_value) == prop_fail_result)
# Line 3831  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 = UCD_CATEGORY(c);            prop_category = UCD_CATEGORY(c);
4512            if (prop_category == ucp_M) break;            if (prop_category == ucp_M) break;
# Line 3851  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 3886  for (;;) Line 4562  for (;;)
4562              {              {
4563              for (i = min; i < max; i++)              for (i = min; i < max; i++)
4564                {                {
4565                if (eptr >= md->end_subject || IS_NEWLINE(eptr)) break;                if (eptr >= md->end_subject)
4566                    {
4567                    SCHECK_PARTIAL();
4568                    break;
4569                    }
4570                  if (IS_NEWLINE(eptr)) break;
4571                eptr++;                eptr++;
4572                while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;                while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;
4573                }                }
# Line 3898  for (;;) Line 4579  for (;;)
4579              {              {
4580              for (i = min; i < max; i++)              for (i = min; i < max; i++)
4581                {                {
4582                if (eptr >= md->end_subject || IS_NEWLINE(eptr)) break;                if (eptr >= md->end_subject)
4583                    {
4584                    SCHECK_PARTIAL();
4585                    break;
4586                    }
4587                  if (IS_NEWLINE(eptr)) break;
4588                eptr++;                eptr++;
4589                while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;                while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;
4590                }                }
# Line 3910  for (;;) Line 4596  for (;;)
4596              {              {
4597              for (i = min; i < max; i++)              for (i = min; i < max; i++)
4598                {                {
4599                if (eptr >= md->end_subject) break;                if (eptr >= md->end_subject)
4600                    {
4601                    SCHECK_PARTIAL();
4602                    break;
4603                    }
4604                eptr++;                eptr++;
4605                while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;                while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;
4606                }                }
# Line 3923  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 3956  for (;;) Line 4653  for (;;)
4653              {              {
4654              BOOL gotspace;              BOOL gotspace;
4655              int len = 1;              int len = 1;
4656              if (eptr >= md->end_subject) break;              if (eptr >= md->end_subject)
4657                  {
4658                  SCHECK_PARTIAL();
4659                  break;
4660                  }
4661              GETCHARLEN(c, eptr, len);              GETCHARLEN(c, eptr, len);
4662              switch(c)              switch(c)
4663                {                {
# Line 3994  for (;;) Line 4695  for (;;)
4695              {              {
4696              BOOL gotspace;              BOOL gotspace;
4697              int len = 1;              int len = 1;
4698              if (eptr >= md->end_subject) break;              if (eptr >= md->end_subject)
4699                  {
4700                  SCHECK_PARTIAL();
4701                  break;
4702                  }
4703              GETCHARLEN(c, eptr, len);              GETCHARLEN(c, eptr, len);
4704              switch(c)              switch(c)
4705                {                {
# Line 4018  for (;;) Line 4723  for (;;)
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 4029  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 4040  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 4051  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 4062  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 4073  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 4105  for (;;) Line 4834  for (;;)
4834            case OP_ANY:            case OP_ANY:
4835            for (i = min; i < max; i++)            for (i = min; i < max; i++)
4836              {              {
4837              if (eptr >= md->end_subject || IS_NEWLINE(eptr)) break;              if (eptr >= md->end_subject)
4838                  {
4839                  SCHECK_PARTIAL();
4840                  break;
4841                  }
4842                if (IS_NEWLINE(eptr)) break;
4843              eptr++;              eptr++;
4844              }              }
4845            break;            break;
# Line 4114  for (;;) Line 4848  for (;;)
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 4142  for (;;) Line 4883  for (;;)
4883            case OP_NOT_HSPACE:            case OP_NOT_HSPACE:
4884            for (i = min; i < max; i++)            for (i = min; i < max; i++)
4885              {              {
4886              if (eptr >= md->end_subject) break;              if (eptr >= md->end_subject)
4887                  {
4888                  SCHECK_PARTIAL();
4889                  break;
4890                  }
4891              c = *eptr;              c = *eptr;
4892              if (c == 0x09 || c == 0x20 || c == 0xa0) break;              if (c == 0x09 || c == 0x20 || c == 0xa0) break;
4893              eptr++;              eptr++;
# Line 4152  for (;;) Line 4897  for (;;)
4897            case OP_HSPACE:            case OP_HSPACE:
4898            for (i = min; i < max; i++)            for (i = min; i < max; i++)
4899              {              {
4900              if (eptr >= md->end_subject) break;              if (eptr >= md->end_subject)
4901                  {
4902                  SCHECK_PARTIAL();
4903                  break;
4904                  }
4905              c = *eptr;              c = *eptr;
4906              if (c != 0x09 && c != 0x20 && c != 0xa0) break;              if (c != 0x09 && c != 0x20 && c != 0xa0) break;
4907              eptr++;              eptr++;
# Line 4162  for (;;) Line 4911  for (;;)
4911            case OP_NOT_VSPACE:            case OP_NOT_VSPACE:
4912            for (i = min; i < max; i++)            for (i = min; i < max; i++)
4913              {              {
4914              if (eptr >= md->end_subject) break;              if (eptr >= md->end_subject)
4915                  {
4916                  SCHECK_PARTIAL();
4917                  break;
4918                  }
4919              c = *eptr;              c = *eptr;
4920              if (c == 0x0a || c == 0x0b || c == 0x0c || c == 0x0d || c == 0x85)              if (c == 0x0a || c == 0x0b || c == 0x0c || c == 0x0d || c == 0x85)
4921                break;                break;
# Line 4173  for (;;) Line 4926  for (;;)
4926            case OP_VSPACE:            case OP_VSPACE:
4927            for (i = min; i < max; i++)            for (i = min; i < max; i++)
4928              {              {
4929              if (eptr >= md->end_subject) break;              if (eptr >= md->end_subject)
4930                  {
4931                  SCHECK_PARTIAL();
4932                  break;
4933                  }
4934              c = *eptr;              c = *eptr;
4935              if (c != 0x0a && c != 0x0b && c != 0x0c && c != 0x0d && c != 0x85)              if (c != 0x0a && c != 0x0b && c != 0x0c && c != 0x0d && c != 0x85)
4936                break;                break;
# Line 4184  for (;;) Line 4941  for (;;)
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 4193  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 4202  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 4211  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 4220  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                  }
5001                if ((md->ctypes[*eptr] & ctype_word) != 0) break;
5002              eptr++;              eptr++;
5003              }              }
5004            break;            break;
# Line 4229  for (;;) Line 5006  for (;;)
5006            case OP_WORDCHAR:            case OP_WORDCHAR:
5007            for (i = min; i < max; i++)            for (i = min; i < max; i++)
5008              {              {
5009              if (eptr >= md->end_subject || (md->ctypes[*eptr] & ctype_word) == 0)              if (eptr >= md->end_subject)
5010                  {
5011                  SCHECK_PARTIAL();
5012                break;                break;
5013                  }
5014                if ((md->ctypes[*eptr] & ctype_word) == 0) break;
5015              eptr++;              eptr++;
5016              }              }
5017            break;            break;
# Line 4384  Returns:          > 0 => success; value Line 5165  Returns:          > 0 => success; value
5165                   < -1 => some kind of unexpected problem                   < -1 => some kind of unexpected problem
5166  */  */
5167    
5168  PCRE_EXP_DEFN int  PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
5169  pcre_exec(const pcre *argument_re, const pcre_extra *extra_data,  pcre_exec(const pcre *argument_re, const pcre_extra *extra_data,
5170    PCRE_SPTR subject, int length, int start_offset, int options, int *offsets,    PCRE_SPTR subject, int length, int start_offset, int options, int *offsets,
5171    int offsetcount)    int offsetcount)
# Line 4408  const uschar *tables; Line 5189  const uschar *tables;
5189  const uschar *start_bits = NULL;  const uschar *start_bits = NULL;
5190  USPTR start_match = (USPTR)subject + start_offset;  USPTR start_match = (USPTR)subject + start_offset;
5191  USPTR end_subject;  USPTR end_subject;
5192    USPTR start_partial = NULL;
5193  USPTR req_byte_ptr = start_match - 1;  USPTR req_byte_ptr = start_match - 1;
5194    
5195  pcre_study_data internal_study;  pcre_study_data internal_study;
# Line 4424  if (re == NULL || subject == NULL || Line 5206  if (re == NULL || subject == NULL ||
5206     (offsets == NULL && offsetcount > 0)) return PCRE_ERROR_NULL;     (offsets == NULL && offsetcount > 0)) return PCRE_ERROR_NULL;
5207  if (offsetcount < 0) return PCRE_ERROR_BADCOUNT;  if (offsetcount < 0) return PCRE_ERROR_BADCOUNT;
5208    
5209    /* This information is for finding all the numbers associated with a given
5210    name, for condition testing. */
5211    
5212    md->name_table = (uschar *)re + re->name_table_offset;
5213    md->name_count = re->name_count;
5214    md->name_entry_size = re->name_entry_size;
5215    
5216  /* Fish out the optional data from the extra_data structure, first setting  /* Fish out the optional data from the extra_data structure, first setting
5217  the default values. */  the default values. */
5218    
# Line 4491  md->jscript_compat = (re->options & PCRE Line 5280  md->jscript_compat = (re->options & PCRE
5280  md->notbol = (options & PCRE_NOTBOL) != 0;  md->notbol = (options & PCRE_NOTBOL) != 0;
5281  md->noteol = (options & PCRE_NOTEOL) != 0;  md->noteol = (options & PCRE_NOTEOL) != 0;
5282  md->notempty = (options & PCRE_NOTEMPTY) != 0;  md->notempty = (options & PCRE_NOTEMPTY) != 0;
5283  md->partial = (options & PCRE_PARTIAL) != 0;  md->notempty_atstart = (options & PCRE_NOTEMPTY_ATSTART) != 0;
5284    md->partial = ((options & PCRE_PARTIAL_HARD) != 0)? 2 :
5285                  ((options & PCRE_PARTIAL_SOFT) != 0)? 1 : 0;
5286  md->hitend = FALSE;  md->hitend = FALSE;
5287    
5288  md->recursive = NULL;                   /* No recursion at top level */  md->recursive = NULL;                   /* No recursion at top level */
# Line 4532  switch ((((options & PCRE_NEWLINE_BITS) Line 5323  switch ((((options & PCRE_NEWLINE_BITS)
5323          (pcre_uint32)options) & PCRE_NEWLINE_BITS)          (pcre_uint32)options) & PCRE_NEWLINE_BITS)
5324    {    {
5325    case 0: newline = NEWLINE; break;   /* Compile-time default */    case 0: newline = NEWLINE; break;   /* Compile-time default */
5326    case PCRE_NEWLINE_CR: newline = '\r'; break;    case PCRE_NEWLINE_CR: newline = CHAR_CR; break;
5327    case PCRE_NEWLINE_LF: newline = '\n'; break;    case PCRE_NEWLINE_LF: newline = CHAR_NL; break;
5328    case PCRE_NEWLINE_CR+    case PCRE_NEWLINE_CR+
5329         PCRE_NEWLINE_LF: newline = ('\r' << 8) | '\n'; break;         PCRE_NEWLINE_LF: newline = (CHAR_CR << 8) | CHAR_NL; break;
5330    case PCRE_NEWLINE_ANY: newline = -1; break;    case PCRE_NEWLINE_ANY: newline = -1; break;
5331    case PCRE_NEWLINE_ANYCRLF: newline = -2; break;    case PCRE_NEWLINE_ANYCRLF: newline = -2; break;
5332    default: return PCRE_ERROR_BADNEWLINE;    default: return PCRE_ERROR_BADNEWLINE;
# Line 4565  else Line 5356  else
5356      }      }
5357    }    }
5358    
5359  /* Partial matching is supported only for a restricted set of regexes at the  /* Partial matching was originally supported only for a restricted set of
5360  moment. */  regexes; from release 8.00 there are no restrictions, but the bits are still
5361    defined (though never set). So there's no harm in leaving this code. */
5362    
5363  if (md->partial && (re->flags & PCRE_NOPARTIAL) != 0)  if (md->partial && (re->flags & PCRE_NOPARTIAL) != 0)
5364    return PCRE_ERROR_BADPARTIAL;    return PCRE_ERROR_BADPARTIAL;
# Line 4577  back the character offset. */ Line 5369  back the character offset. */
5369  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
5370  if (utf8 && (options & PCRE_NO_UTF8_CHECK) == 0)  if (utf8 && (options & PCRE_NO_UTF8_CHECK) == 0)
5371    {    {
5372    if (_pcre_valid_utf8((uschar *)subject, length) >= 0)    if (_pcre_valid_utf8((USPTR)subject, length) >= 0)
5373      return PCRE_ERROR_BADUTF8;      return PCRE_ERROR_BADUTF8;
5374    if (start_offset > 0 && start_offset < length)    if (start_offset > 0 && start_offset < length)
5375      {      {
5376      int tb = ((uschar *)subject)[start_offset];      int tb = ((USPTR)subject)[start_offset];
5377      if (tb > 127)      if (tb > 127)
5378        {        {
5379        tb &= 0xc0;        tb &= 0xc0;
# Line 4653  if (!anchored) Line 5445  if (!anchored)
5445      }      }
5446    else    else
5447      if (!startline && study != NULL &&      if (!startline && study != NULL &&
5448        (study->options & PCRE_STUDY_MAPPED) != 0)        (study->flags & PCRE_STUDY_MAPPED) != 0)
5449          start_bits = study->start_bits;          start_bits = study->start_bits;
5450    }    }
5451    
# Line 4687  for(;;) Line 5479  for(;;)
5479      while (iptr < iend) *iptr++ = -1;      while (iptr < iend) *iptr++ = -1;
5480      }      }
5481    
5482    /* Advance to a unique first char if possible. If firstline is TRUE, the    /* If firstline is TRUE, the start of the match is constrained to the first
5483    start of the match is constrained to the first line of a multiline string.    line of a multiline string. That is, the match must be before or at the first
5484    That is, the match must be before or at the first newline. Implement this by    newline. Implement this by temporarily adjusting end_subject so that we stop
5485    temporarily adjusting end_subject so that we stop scanning at a newline. If    scanning at a newline. If the match fails at the newline, later code breaks
5486    the match fails at the newline, later code breaks this loop. */    this loop. */
5487    
5488    if (firstline)    if (firstline)
5489      {      {
5490      USPTR t = start_match;      USPTR t = start_match;
5491    #ifdef SUPPORT_UTF8
5492        if (utf8)
5493          {
5494          while (t < md->end_subject && !IS_NEWLINE(t))
5495            {
5496            t++;
5497            while (t < end_subject && (*t & 0xc0) == 0x80) t++;
5498            }
5499          }
5500        else
5501    #endif
5502      while (t < md->end_subject && !IS_NEWLINE(t)) t++;      while (t < md->end_subject && !IS_NEWLINE(t)) t++;
5503      end_subject = t;      end_subject = t;
5504      }      }
5505    
5506    /* Now test for a unique first byte */    /* There are some optimizations that avoid running the match if a known
5507      starting point is not found, or if a known later character is not present.
5508      However, there is an option that disables these, for testing and for ensuring
5509      that all callouts do actually occur. */
5510    
5511    if (first_byte >= 0)    if ((options & PCRE_NO_START_OPTIMIZE) == 0)
5512      {      {
5513      if (first_byte_caseless)      /* Advance to a unique first byte if there is one. */
       while (start_match < end_subject &&  
              md->lcc[*start_match] != first_byte)  
         { NEXTCHAR(start_match); }  
     else  
       while (start_match < end_subject && *start_match != first_byte)  
         { NEXTCHAR(start_match); }  
     }  
5514    
5515    /* Or to just after a linebreak for a multiline match if possible */      if (first_byte >= 0)
5516          {
5517          if (first_byte_caseless)
5518            while (start_match < end_subject && md->lcc[*start_match] != first_byte)
5519              start_match++;
5520          else
5521            while (start_match < end_subject && *start_match != first_byte)
5522              start_match++;
5523          }
5524    
5525    else if (startline)      /* Or to just after a linebreak for a multiline match */
5526      {  
5527      if (start_match > md->start_subject + start_offset)      else if (startline)
5528        {        {
5529        while (start_match <= end_subject && !WAS_NEWLINE(start_match))        if (start_match > md->start_subject + start_offset)
5530          { NEXTCHAR(start_match); }          {
5531    #ifdef SUPPORT_UTF8
5532            if (utf8)
5533              {
5534              while (start_match < end_subject && !WAS_NEWLINE(start_match))
5535                {
5536                start_match++;
5537                while(start_match < end_subject && (*start_match & 0xc0) == 0x80)
5538                  start_match++;
5539                }
5540              }
5541            else
5542    #endif
5543            while (start_match < end_subject && !WAS_NEWLINE(start_match))
5544              start_match++;
5545    
5546            /* If we have just passed a CR and the newline option is ANY or ANYCRLF,
5547            and we are now at a LF, advance the match position by one more character.
5548            */
5549    
5550        /* If we have just passed a CR and the newline option is ANY or ANYCRLF,          if (start_match[-1] == CHAR_CR &&
5551        and we are now at a LF, advance the match position by one more character.               (md->nltype == NLTYPE_ANY || md->nltype == NLTYPE_ANYCRLF) &&
5552        */               start_match < end_subject &&
5553                 *start_match == CHAR_NL)
5554        if (start_match[-1] == '\r' &&            start_match++;
5555             (md->nltype == NLTYPE_ANY || md->nltype == NLTYPE_ANYCRLF) &&          }
            start_match < end_subject &&  
            *start_match == '\n')  
         start_match++;  
5556        }        }
     }  
5557    
5558    /* Or to a non-unique first char after study */      /* Or to a non-unique first byte after study */
5559    
5560    else if (start_bits != NULL)      else if (start_bits != NULL)
     {  
     while (start_match < end_subject)  
5561        {        {
5562        register unsigned int c = *start_match;        while (start_match < end_subject)
5563        if ((start_bits[c/8] & (1 << (c&7))) == 0)          {
5564          { NEXTCHAR(start_match); }          register unsigned int c = *start_match;
5565        else break;          if ((start_bits[c/8] & (1 << (c&7))) == 0) start_match++;
5566              else break;
5567            }
5568        }        }
5569      }      }   /* Starting optimizations */
5570    
5571    /* Restore fudged end_subject */    /* Restore fudged end_subject */
5572    
5573    end_subject = save_end_subject;    end_subject = save_end_subject;
5574    
5575  #ifdef DEBUG  /* Sigh. Some compilers never learn. */    /* The following two optimizations are disabled for partial matching or if
5576    printf(">>>> Match against: ");    disabling is explicitly requested. */
   pchars(start_match, end_subject - start_match, TRUE, md);  
   printf("\n");  
 #endif  
5577    
5578    /* If req_byte is set, we know that that character must appear in the subject    if ((options & PCRE_NO_START_OPTIMIZE) == 0 && !md->partial)
   for the match to succeed. If the first character is set, req_byte must be  
   later in the subject; otherwise the test starts at the match point. This  
   optimization can save a huge amount of backtracking in patterns with nested  
   unlimited repeats that aren't going to match. Writing separate code for  
   cased/caseless versions makes it go faster, as does using an autoincrement  
   and backing off on a match.  
   
   HOWEVER: when the subject string is very, very long, searching to its end can  
   take a long time, and give bad performance on quite ordinary patterns. This  
   showed up when somebody was matching something like /^\d+C/ on a 32-megabyte  
   string... so we don't do this when the string is sufficiently long.  
   
   ALSO: this processing is disabled when partial matching is requested.  
   */  
   
   if (req_byte >= 0 &&  
       end_subject - start_match < REQ_BYTE_MAX &&  
       !md->partial)  
5579      {      {
5580      register USPTR p = start_match + ((first_byte >= 0)? 1 : 0);      /* If the pattern was studied, a minimum subject length may be set. This is
5581        a lower bound; no actual string of that length may actually match the
5582        pattern. Although the value is, strictly, in characters, we treat it as
5583        bytes to avoid spending too much time in this optimization. */
5584    
5585        if (study != NULL && (study->flags & PCRE_STUDY_MINLEN) != 0 &&
5586            (pcre_uint32)(end_subject - start_match) < study->minlength)
5587          {
5588          rc = MATCH_NOMATCH;
5589          break;
5590          }
5591    
5592      /* We don't need to repeat the search if we haven't yet reached the      /* If req_byte is set, we know that that character must appear in the
5593      place we found it at last time. */      subject for the match to succeed. If the first character is set, req_byte
5594        must be later in the subject; otherwise the test starts at the match point.
5595        This optimization can save a huge amount of backtracking in patterns with
5596        nested unlimited repeats that aren't going to match. Writing separate code
5597        for cased/caseless versions makes it go faster, as does using an
5598        autoincrement and backing off on a match.
5599    
5600      if (p > req_byte_ptr)      HOWEVER: when the subject string is very, very long, searching to its end
5601        can take a long time, and give bad performance on quite ordinary patterns.
5602        This showed up when somebody was matching something like /^\d+C/ on a
5603        32-megabyte string... so we don't do this when the string is sufficiently
5604        long. */
5605    
5606        if (req_byte >= 0 && end_subject - start_match < REQ_BYTE_MAX)
5607        {        {
5608        if (req_byte_caseless)        register USPTR p = start_match + ((first_byte >= 0)? 1 : 0);
5609    
5610          /* We don't need to repeat the search if we haven't yet reached the
5611          place we found it at last time. */
5612    
5613          if (p > req_byte_ptr)
5614          {          {
5615          while (p < end_subject)          if (req_byte_caseless)
5616            {            {
5617            register int pp = *p++;            while (p < end_subject)
5618            if (pp == req_byte || pp == req_byte2) { p--; break; }              {
5619                register int pp = *p++;
5620                if (pp == req_byte || pp == req_byte2) { p--; break; }
5621                }
5622            }            }
5623          }          else
       else  
         {  
         while (p < end_subject)  
5624            {            {
5625            if (*p++ == req_byte) { p--; break; }            while (p < end_subject)
5626                {
5627                if (*p++ == req_byte) { p--; break; }
5628                }
5629            }            }
         }  
5630    
5631        /* If we can't find the required character, break the matching loop,          /* If we can't find the required character, break the matching loop,
5632        forcing a match failure. */          forcing a match failure. */
5633    
5634        if (p >= end_subject)          if (p >= end_subject)
5635          {            {
5636          rc = MATCH_NOMATCH;            rc = MATCH_NOMATCH;
5637          break;            break;
5638          }            }
5639    
5640        /* If we have found the required character, save the point where we          /* If we have found the required character, save the point where we
5641        found it, so that we don't search again next time round the loop if          found it, so that we don't search again next time round the loop if
5642        the start hasn't passed this character yet. */          the start hasn't passed this character yet. */
5643    
5644        req_byte_ptr = p;          req_byte_ptr = p;
5645            }
5646        }        }
5647      }      }
5648    
5649    /* OK, we can now run the match. */  #ifdef PCRE_DEBUG  /* Sigh. Some compilers never learn. */
5650      printf(">>>> Match against: ");
5651      pchars(start_match, end_subject - start_match, TRUE, md);
5652      printf("\n");
5653    #endif
5654    
5655      /* OK, we can now run the match. If "hitend" is set afterwards, remember the
5656      first starting point for which a partial match was found. */
5657    
5658    md->start_match_ptr = start_match;    md->start_match_ptr = start_match;
5659      md->start_used_ptr = start_match;
5660    md->match_call_count = 0;    md->match_call_count = 0;
5661    rc = match(start_match, md->start_code, start_match, 2, md, ims, NULL, 0, 0);    rc = match(start_match, md->start_code, start_match, 2, md, ims, NULL, 0, 0);
5662      if (md->hitend && start_partial == NULL) start_partial = md->start_used_ptr;
5663    
5664    switch(rc)    switch(rc)
5665      {      {
# Line 4851  for(;;) Line 5689  for(;;)
5689      rc = MATCH_NOMATCH;      rc = MATCH_NOMATCH;
5690      goto ENDLOOP;      goto ENDLOOP;
5691    
5692      /* Any other return is some kind of error. */      /* Any other return is either a match, or some kind of error. */
5693    
5694      default:      default:
5695      goto ENDLOOP;      goto ENDLOOP;
# Line 4881  for(;;) Line 5719  for(;;)
5719    not contain any explicit matches for \r or \n, and the newline option is CRLF    not contain any explicit matches for \r or \n, and the newline option is CRLF
5720    or ANY or ANYCRLF, advance the match position by one more character. */    or ANY or ANYCRLF, advance the match position by one more character. */
5721    
5722    if (start_match[-1] == '\r' &&    if (start_match[-1] == CHAR_CR &&
5723        start_match < end_subject &&        start_match < end_subject &&
5724        *start_match == '\n' &&        *start_match == CHAR_NL &&
5725        (re->flags & PCRE_HASCRORLF) == 0 &&        (re->flags & PCRE_HASCRORLF) == 0 &&
5726          (md->nltype == NLTYPE_ANY ||          (md->nltype == NLTYPE_ANY ||
5727           md->nltype == NLTYPE_ANYCRLF ||           md->nltype == NLTYPE_ANYCRLF ||
# Line 4957  if (using_temporary_offsets) Line 5795  if (using_temporary_offsets)
5795    (pcre_free)(md->offset_vector);    (pcre_free)(md->offset_vector);
5796    }    }
5797    
5798  if (rc != MATCH_NOMATCH)  if (rc != MATCH_NOMATCH && rc != PCRE_ERROR_PARTIAL)
5799    {    {
5800    DPRINTF((">>>> error: returning %d\n", rc));    DPRINTF((">>>> error: returning %d\n", rc));
5801    return rc;    return rc;
5802    }    }
5803  else if (md->partial && md->hitend)  else if (start_partial != NULL)
5804    {    {
5805    DPRINTF((">>>> returning PCRE_ERROR_PARTIAL\n"));    DPRINTF((">>>> returning PCRE_ERROR_PARTIAL\n"));
5806      if (offsetcount > 1)
5807        {
5808        offsets[0] = start_partial - (USPTR)subject;
5809        offsets[1] = end_subject - (USPTR)subject;
5810        }
5811    return PCRE_ERROR_PARTIAL;    return PCRE_ERROR_PARTIAL;
5812    }    }
5813  else  else

Legend:
Removed from v.354  
changed lines
  Added in v.500

  ViewVC Help
Powered by ViewVC 1.1.5