/[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 426 by ph10, Wed Aug 26 15:38:32 2009 UTC revision 501 by ph10, Sun Mar 7 11:49:54 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-2009 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 249  enum { RM1=1, RM2,  RM3,  RM4,  RM5,  RM Line 249  enum { RM1=1, RM2,  RM3,  RM4,  RM5,  RM
249    
250  /* These versions of the macros use the stack, as normal. There are debugging  /* These versions of the macros use the stack, as normal. There are debugging
251  versions and production versions. Note that the "rw" argument of RMATCH isn't  versions and production versions. Note that the "rw" argument of RMATCH isn't
252  actuall used in this definition. */  actually used in this definition. */
253    
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__); \
261    rrc = match(ra,rb,mstart,rc,rd,re,rf,rg,rdepth+1); \    rrc = match(ra,rb,mstart,markptr,rc,rd,re,rf,rg,rdepth+1); \
262    printf("to line %d\n", __LINE__); \    printf("to line %d\n", __LINE__); \
263    }    }
264  #define RRETURN(ra) \  #define RRETURN(ra) \
# Line 268  actuall used in this definition. */ Line 268  actuall used in this definition. */
268    }    }
269  #else  #else
270  #define RMATCH(ra,rb,rc,rd,re,rf,rg,rw) \  #define RMATCH(ra,rb,rc,rd,re,rf,rg,rw) \
271    rrc = match(ra,rb,mstart,rc,rd,re,rf,rg,rdepth+1)    rrc = match(ra,rb,mstart,markptr,rc,rd,re,rf,rg,rdepth+1)
272  #define RRETURN(ra) return ra  #define RRETURN(ra) return ra
273  #endif  #endif
274    
# Line 288  argument of match(), which never changes Line 288  argument of match(), which never changes
288    newframe->Xeptr = ra;\    newframe->Xeptr = ra;\
289    newframe->Xecode = rb;\    newframe->Xecode = rb;\
290    newframe->Xmstart = mstart;\    newframe->Xmstart = mstart;\
291      newframe->Xmarkptr = markptr;\
292    newframe->Xoffset_top = rc;\    newframe->Xoffset_top = rc;\
293    newframe->Xims = re;\    newframe->Xims = re;\
294    newframe->Xeptrb = rf;\    newframe->Xeptrb = rf;\
# Line 325  typedef struct heapframe { Line 326  typedef struct heapframe {
326    USPTR Xeptr;    USPTR Xeptr;
327    const uschar *Xecode;    const uschar *Xecode;
328    USPTR Xmstart;    USPTR Xmstart;
329      USPTR Xmarkptr;
330    int Xoffset_top;    int Xoffset_top;
331    long int Xims;    long int Xims;
332    eptrblock *Xeptrb;    eptrblock *Xeptrb;
# Line 403  same response. */ Line 405  same response. */
405  /* These macros pack up tests that are used for partial matching, and which  /* These macros pack up tests that are used for partial matching, and which
406  appears several times in the code. We set the "hit end" flag if the pointer is  appears several times in the code. We set the "hit end" flag if the pointer is
407  at the end of the subject and also past the start of the subject (i.e.  at the end of the subject and also past the start of the subject (i.e.
408  something has been matched). The second one is used when we already know we are  something has been matched). For hard partial matching, we then return
409  past the end of the subject. */  immediately. The second one is used when we already know we are past the end of
410    the subject. */
411    
412  #define CHECK_PARTIAL()\  #define CHECK_PARTIAL()\
413    if (md->partial && eptr >= md->end_subject && eptr > mstart)\    if (md->partial != 0 && eptr >= md->end_subject && eptr > mstart)\
414      md->hitend = TRUE      {\
415        md->hitend = TRUE;\
416        if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);\
417        }
418    
419  #define SCHECK_PARTIAL()\  #define SCHECK_PARTIAL()\
420    if (md->partial && eptr > mstart) md->hitend = TRUE    if (md->partial != 0 && eptr > mstart)\
421        {\
422        md->hitend = TRUE;\
423        if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);\
424        }
425    
426    
427  /* Performance note: It might be tempting to extract commonly used fields from  /* Performance note: It might be tempting to extract commonly used fields from
428  the md structure (e.g. utf8, end_subject) into individual variables to improve  the md structure (e.g. utf8, end_subject) into individual variables to improve
# Line 423  Arguments: Line 434  Arguments:
434     ecode       pointer to current position in compiled code     ecode       pointer to current position in compiled code
435     mstart      pointer to the current match start position (can be modified     mstart      pointer to the current match start position (can be modified
436                   by encountering \K)                   by encountering \K)
437       markptr     pointer to the most recent MARK name, or NULL
438     offset_top  current top pointer     offset_top  current top pointer
439     md          pointer to "static" info for the match     md          pointer to "static" info for the match
440     ims         current /i, /m, and /s options     ims         current /i, /m, and /s options
# Line 441  Returns:       MATCH_MATCH if matched Line 453  Returns:       MATCH_MATCH if matched
453  */  */
454    
455  static int  static int
456  match(REGISTER USPTR eptr, REGISTER const uschar *ecode, USPTR mstart,  match(REGISTER USPTR eptr, REGISTER const uschar *ecode, USPTR mstart, USPTR
457    int offset_top, match_data *md, unsigned long int ims, eptrblock *eptrb,    markptr, int offset_top, match_data *md, unsigned long int ims,
458    int flags, unsigned int rdepth)    eptrblock *eptrb, int flags, unsigned int rdepth)
459  {  {
460  /* These variables do not need to be preserved over recursion in this function,  /* These variables do not need to be preserved over recursion in this function,
461  so they can be ordinary variables in all cases. Mark some of them with  so they can be ordinary variables in all cases. Mark some of them with
# Line 471  frame->Xprevframe = NULL;            /* Line 483  frame->Xprevframe = NULL;            /*
483  frame->Xeptr = eptr;  frame->Xeptr = eptr;
484  frame->Xecode = ecode;  frame->Xecode = ecode;
485  frame->Xmstart = mstart;  frame->Xmstart = mstart;
486    frame->Xmarkptr = markptr;
487  frame->Xoffset_top = offset_top;  frame->Xoffset_top = offset_top;
488  frame->Xims = ims;  frame->Xims = ims;
489  frame->Xeptrb = eptrb;  frame->Xeptrb = eptrb;
# Line 486  HEAP_RECURSE: Line 499  HEAP_RECURSE:
499  #define eptr               frame->Xeptr  #define eptr               frame->Xeptr
500  #define ecode              frame->Xecode  #define ecode              frame->Xecode
501  #define mstart             frame->Xmstart  #define mstart             frame->Xmstart
502    #define markptr            frame->Xmarkptr
503  #define offset_top         frame->Xoffset_top  #define offset_top         frame->Xoffset_top
504  #define ims                frame->Xims  #define ims                frame->Xims
505  #define eptrb              frame->Xeptrb  #define eptrb              frame->Xeptrb
# Line 613  TAIL_RECURSE: Line 627  TAIL_RECURSE:
627  /* 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
628  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
629  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()
630  and a "return", respectively (possibly with some debugging if DEBUG is  and a "return", respectively (possibly with some debugging if PCRE_DEBUG is
631  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
632  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,
633  however, impact performance when true recursion is being used. */  however, impact performance when true recursion is being used. */
# Line 655  for (;;) Line 669  for (;;)
669    minimize = possessive = FALSE;    minimize = possessive = FALSE;
670    op = *ecode;    op = *ecode;
671    
   /* For partial matching, remember if we ever hit the end of the subject after  
   matching at least one subject character. This code is now wrapped in a macro  
   because it appears several times below. */  
   
   CHECK_PARTIAL();  
   
672    switch(op)    switch(op)
673      {      {
674      case OP_FAIL:      case OP_FAIL:
# Line 710  for (;;) Line 718  for (;;)
718      number = GET2(ecode, 1+LINK_SIZE);      number = GET2(ecode, 1+LINK_SIZE);
719      offset = number << 1;      offset = number << 1;
720    
721  #ifdef DEBUG  #ifdef PCRE_DEBUG
722      printf("start bracket %d\n", number);      printf("start bracket %d\n", number);
723      printf("subject=");      printf("subject=");
724      pchars(eptr, 16, TRUE, md);      pchars(eptr, 16, TRUE, md);
# Line 836  for (;;) Line 844  for (;;)
844    
845      /* Now see what the actual condition is */      /* Now see what the actual condition is */
846    
847      if (condcode == OP_RREF)         /* Recursion test */      if (condcode == OP_RREF || condcode == OP_NRREF)    /* Recursion test */
848        {        {
849        offset = GET2(ecode, LINK_SIZE + 2);     /* Recursion group number*/        if (md->recursive == NULL)                /* Not recursing => FALSE */
850        condition = md->recursive != NULL &&          {
851          (offset == RREF_ANY || offset == md->recursive->group_num);          condition = FALSE;
852        ecode += condition? 3 : GET(ecode, 1);          ecode += GET(ecode, 1);
853            }
854          else
855            {
856            int recno = GET2(ecode, LINK_SIZE + 2);   /* Recursion group number*/
857            condition =  (recno == RREF_ANY || recno == md->recursive->group_num);
858    
859            /* If the test is for recursion into a specific subpattern, and it is
860            false, but the test was set up by name, scan the table to see if the
861            name refers to any other numbers, and test them. The condition is true
862            if any one is set. */
863    
864            if (!condition && condcode == OP_NRREF && recno != RREF_ANY)
865              {
866              uschar *slotA = md->name_table;
867              for (i = 0; i < md->name_count; i++)
868                {
869                if (GET2(slotA, 0) == recno) break;
870                slotA += md->name_entry_size;
871                }
872    
873              /* Found a name for the number - there can be only one; duplicate
874              names for different numbers are allowed, but not vice versa. First
875              scan down for duplicates. */
876    
877              if (i < md->name_count)
878                {
879                uschar *slotB = slotA;
880                while (slotB > md->name_table)
881                  {
882                  slotB -= md->name_entry_size;
883                  if (strcmp((char *)slotA + 2, (char *)slotB + 2) == 0)
884                    {
885                    condition = GET2(slotB, 0) == md->recursive->group_num;
886                    if (condition) break;
887                    }
888                  else break;
889                  }
890    
891                /* Scan up for duplicates */
892    
893                if (!condition)
894                  {
895                  slotB = slotA;
896                  for (i++; i < md->name_count; i++)
897                    {
898                    slotB += md->name_entry_size;
899                    if (strcmp((char *)slotA + 2, (char *)slotB + 2) == 0)
900                      {
901                      condition = GET2(slotB, 0) == md->recursive->group_num;
902                      if (condition) break;
903                      }
904                    else break;
905                    }
906                  }
907                }
908              }
909    
910            /* Chose branch according to the condition */
911    
912            ecode += condition? 3 : GET(ecode, 1);
913            }
914        }        }
915    
916      else if (condcode == OP_CREF)    /* Group used test */      else if (condcode == OP_CREF || condcode == OP_NCREF)  /* Group used test */
917        {        {
918        offset = GET2(ecode, LINK_SIZE+2) << 1;  /* Doubled ref number */        offset = GET2(ecode, LINK_SIZE+2) << 1;  /* Doubled ref number */
919        condition = offset < offset_top && md->offset_vector[offset] >= 0;        condition = offset < offset_top && md->offset_vector[offset] >= 0;
920    
921          /* If the numbered capture is unset, but the reference was by name,
922          scan the table to see if the name refers to any other numbers, and test
923          them. The condition is true if any one is set. This is tediously similar
924          to the code above, but not close enough to try to amalgamate. */
925    
926          if (!condition && condcode == OP_NCREF)
927            {
928            int refno = offset >> 1;
929            uschar *slotA = md->name_table;
930    
931            for (i = 0; i < md->name_count; i++)
932              {
933              if (GET2(slotA, 0) == refno) break;
934              slotA += md->name_entry_size;
935              }
936    
937            /* Found a name for the number - there can be only one; duplicate names
938            for different numbers are allowed, but not vice versa. First scan down
939            for duplicates. */
940    
941            if (i < md->name_count)
942              {
943              uschar *slotB = slotA;
944              while (slotB > md->name_table)
945                {
946                slotB -= md->name_entry_size;
947                if (strcmp((char *)slotA + 2, (char *)slotB + 2) == 0)
948                  {
949                  offset = GET2(slotB, 0) << 1;
950                  condition = offset < offset_top &&
951                    md->offset_vector[offset] >= 0;
952                  if (condition) break;
953                  }
954                else break;
955                }
956    
957              /* Scan up for duplicates */
958    
959              if (!condition)
960                {
961                slotB = slotA;
962                for (i++; i < md->name_count; i++)
963                  {
964                  slotB += md->name_entry_size;
965                  if (strcmp((char *)slotA + 2, (char *)slotB + 2) == 0)
966                    {
967                    offset = GET2(slotB, 0) << 1;
968                    condition = offset < offset_top &&
969                      md->offset_vector[offset] >= 0;
970                    if (condition) break;
971                    }
972                  else break;
973                  }
974                }
975              }
976            }
977    
978          /* Chose branch according to the condition */
979    
980        ecode += condition? 3 : GET(ecode, 1);        ecode += condition? 3 : GET(ecode, 1);
981        }        }
982    
# Line 908  for (;;) Line 1037  for (;;)
1037      break;      break;
1038    
1039    
1040        /* Before OP_ACCEPT there may be any number of OP_CLOSE opcodes,
1041        to close any currently open capturing brackets. */
1042    
1043        case OP_CLOSE:
1044        number = GET2(ecode, 1);
1045        offset = number << 1;
1046    
1047    #ifdef PCRE_DEBUG
1048          printf("end bracket %d at *ACCEPT", number);
1049          printf("\n");
1050    #endif
1051    
1052        md->capture_last = number;
1053        if (offset >= md->offset_max) md->offset_overflow = TRUE; else
1054          {
1055          md->offset_vector[offset] =
1056            md->offset_vector[md->offset_end - number];
1057          md->offset_vector[offset+1] = eptr - md->start_subject;
1058          if (offset_top <= offset) offset_top = offset + 2;
1059          }
1060        ecode += 3;
1061        break;
1062    
1063    
1064      /* 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
1065      recursion, we should restore the offsets appropriately and continue from      recursion, we should restore the offsets appropriately and continue from
1066      after the call. */      after the call. */
# Line 921  for (;;) Line 1074  for (;;)
1074        md->recursive = rec->prevrec;        md->recursive = rec->prevrec;
1075        memmove(md->offset_vector, rec->offset_save,        memmove(md->offset_vector, rec->offset_save,
1076          rec->saved_max * sizeof(int));          rec->saved_max * sizeof(int));
1077        mstart = rec->save_start;        offset_top = rec->save_offset_top;
1078        ims = original_ims;        ims = original_ims;
1079        ecode = rec->after_call;        ecode = rec->after_call;
1080        break;        break;
1081        }        }
1082    
1083      /* 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
1084      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
1085        the subject. In both cases, backtracking will then try other alternatives,
1086        if any. */
1087    
1088        if (eptr == mstart &&
1089            (md->notempty ||
1090              (md->notempty_atstart &&
1091                mstart == md->start_subject + md->start_offset)))
1092          RRETURN(MATCH_NOMATCH);
1093    
1094        /* Otherwise, we have a match. */
1095    
     if (md->notempty && eptr == mstart) RRETURN(MATCH_NOMATCH);  
1096      md->end_match_ptr = eptr;           /* Record where we ended */      md->end_match_ptr = eptr;           /* Record where we ended */
1097      md->end_offset_top = offset_top;    /* and how many extracts were taken */      md->end_offset_top = offset_top;    /* and how many extracts were taken */
1098      md->start_match_ptr = mstart;       /* and the start (\K can modify) */      md->start_match_ptr = mstart;       /* and the start (\K can modify) */
# Line 956  for (;;) Line 1118  for (;;)
1118        {        {
1119        RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, NULL, 0,        RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, NULL, 0,
1120          RM4);          RM4);
1121        if (rrc == MATCH_MATCH) break;        if (rrc == MATCH_MATCH)
1122            {
1123            mstart = md->start_match_ptr;   /* In case \K reset it */
1124            break;
1125            }
1126        if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);        if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);
1127        ecode += GET(ecode, 1);        ecode += GET(ecode, 1);
1128        }        }
# Line 975  for (;;) Line 1141  for (;;)
1141      offset_top = md->end_offset_top;      offset_top = md->end_offset_top;
1142      continue;      continue;
1143    
1144      /* Negative assertion: all branches must fail to match */      /* Negative assertion: all branches must fail to match. Encountering SKIP,
1145        PRUNE, or COMMIT means we must assume failure without checking subsequent
1146        branches. */
1147    
1148      case OP_ASSERT_NOT:      case OP_ASSERT_NOT:
1149      case OP_ASSERTBACK_NOT:      case OP_ASSERTBACK_NOT:
# Line 984  for (;;) Line 1152  for (;;)
1152        RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, NULL, 0,        RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, NULL, 0,
1153          RM5);          RM5);
1154        if (rrc == MATCH_MATCH) RRETURN(MATCH_NOMATCH);        if (rrc == MATCH_MATCH) RRETURN(MATCH_NOMATCH);
1155          if (rrc == MATCH_SKIP || rrc == MATCH_PRUNE || rrc == MATCH_COMMIT)
1156            {
1157            do ecode += GET(ecode,1); while (*ecode == OP_ALT);
1158            break;
1159            }
1160        if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);        if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);
1161        ecode += GET(ecode,1);        ecode += GET(ecode,1);
1162        }        }
# Line 1021  for (;;) Line 1194  for (;;)
1194        if (eptr < md->start_subject) RRETURN(MATCH_NOMATCH);        if (eptr < md->start_subject) RRETURN(MATCH_NOMATCH);
1195        }        }
1196    
1197      /* Skip to next op code */      /* Save the earliest consulted character, then skip to next op code */
1198    
1199        if (eptr < md->start_used_ptr) md->start_used_ptr = eptr;
1200      ecode += 1 + LINK_SIZE;      ecode += 1 + LINK_SIZE;
1201      break;      break;
1202    
# Line 1101  for (;;) Line 1275  for (;;)
1275    
1276        memcpy(new_recursive.offset_save, md->offset_vector,        memcpy(new_recursive.offset_save, md->offset_vector,
1277              new_recursive.saved_max * sizeof(int));              new_recursive.saved_max * sizeof(int));
1278        new_recursive.save_start = mstart;        new_recursive.save_offset_top = offset_top;
       mstart = eptr;  
1279    
1280        /* 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
1281        restore the offset and recursion data. */        restore the offset and recursion data. */
# Line 1149  for (;;) Line 1322  for (;;)
1322      a move back into the brackets. Friedl calls these "atomic" subpatterns.      a move back into the brackets. Friedl calls these "atomic" subpatterns.
1323      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
1324      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
1325      the end of a normal bracket, leaving the subject pointer. */      the end of a normal bracket, leaving the subject pointer, but resetting
1326        the start-of-match value in case it was changed by \K. */
1327    
1328      case OP_ONCE:      case OP_ONCE:
1329      prev = ecode;      prev = ecode;
# Line 1158  for (;;) Line 1332  for (;;)
1332      do      do
1333        {        {
1334        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);
1335        if (rrc == MATCH_MATCH) break;        if (rrc == MATCH_MATCH)
1336            {
1337            mstart = md->start_match_ptr;
1338            break;
1339            }
1340        if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);        if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);
1341        ecode += GET(ecode,1);        ecode += GET(ecode,1);
1342        }        }
# Line 1277  for (;;) Line 1455  for (;;)
1455        }        }
1456      else saved_eptr = NULL;      else saved_eptr = NULL;
1457    
1458      /* 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
1459      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
1460      assertions. Do this also for the "once" (atomic) groups. */      use by positive assertions. We also need to record the match start in case
1461        it was changed by \K. */
1462    
1463      if (*prev == OP_ASSERT || *prev == OP_ASSERT_NOT ||      if (*prev == OP_ASSERT || *prev == OP_ASSERT_NOT ||
1464          *prev == OP_ASSERTBACK || *prev == OP_ASSERTBACK_NOT ||          *prev == OP_ASSERTBACK || *prev == OP_ASSERTBACK_NOT ||
# Line 1287  for (;;) Line 1466  for (;;)
1466        {        {
1467        md->end_match_ptr = eptr;      /* For ONCE */        md->end_match_ptr = eptr;      /* For ONCE */
1468        md->end_offset_top = offset_top;        md->end_offset_top = offset_top;
1469          md->start_match_ptr = mstart;
1470        RRETURN(MATCH_MATCH);        RRETURN(MATCH_MATCH);
1471        }        }
1472    
# Line 1301  for (;;) Line 1481  for (;;)
1481        number = GET2(prev, 1+LINK_SIZE);        number = GET2(prev, 1+LINK_SIZE);
1482        offset = number << 1;        offset = number << 1;
1483    
1484  #ifdef DEBUG  #ifdef PCRE_DEBUG
1485        printf("end bracket %d", number);        printf("end bracket %d", number);
1486        printf("\n");        printf("\n");
1487  #endif  #endif
# Line 1323  for (;;) Line 1503  for (;;)
1503          recursion_info *rec = md->recursive;          recursion_info *rec = md->recursive;
1504          DPRINTF(("Recursion (%d) succeeded - continuing\n", number));          DPRINTF(("Recursion (%d) succeeded - continuing\n", number));
1505          md->recursive = rec->prevrec;          md->recursive = rec->prevrec;
         mstart = rec->save_start;  
1506          memcpy(md->offset_vector, rec->offset_save,          memcpy(md->offset_vector, rec->offset_save,
1507            rec->saved_max * sizeof(int));            rec->saved_max * sizeof(int));
1508            offset_top = rec->save_offset_top;
1509          ecode = rec->after_call;          ecode = rec->after_call;
1510          ims = original_ims;          ims = original_ims;
1511          break;          break;
# Line 1465  for (;;) Line 1645  for (;;)
1645    
1646        /* Find out if the previous and current characters are "word" characters.        /* Find out if the previous and current characters are "word" characters.
1647        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
1648        be "non-word" characters. */        be "non-word" characters. Remember the earliest consulted character for
1649          partial matching. */
1650    
1651  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
1652        if (utf8)        if (utf8)
# Line 1474  for (;;) Line 1655  for (;;)
1655            {            {
1656            USPTR lastptr = eptr - 1;            USPTR lastptr = eptr - 1;
1657            while((*lastptr & 0xc0) == 0x80) lastptr--;            while((*lastptr & 0xc0) == 0x80) lastptr--;
1658              if (lastptr < md->start_used_ptr) md->start_used_ptr = lastptr;
1659            GETCHAR(c, lastptr);            GETCHAR(c, lastptr);
1660            prev_is_word = c < 256 && (md->ctypes[c] & ctype_word) != 0;            prev_is_word = c < 256 && (md->ctypes[c] & ctype_word) != 0;
1661            }            }
1662          if (eptr >= md->end_subject) cur_is_word = FALSE; else          if (eptr >= md->end_subject)
1663              {
1664              SCHECK_PARTIAL();
1665              cur_is_word = FALSE;
1666              }
1667            else
1668            {            {
1669            GETCHAR(c, eptr);            GETCHAR(c, eptr);
1670            cur_is_word = c < 256 && (md->ctypes[c] & ctype_word) != 0;            cur_is_word = c < 256 && (md->ctypes[c] & ctype_word) != 0;
# Line 1486  for (;;) Line 1673  for (;;)
1673        else        else
1674  #endif  #endif
1675    
1676        /* More streamlined when not in UTF-8 mode */        /* Not in UTF-8 mode */
1677    
1678          {          {
1679          prev_is_word = (eptr != md->start_subject) &&          if (eptr == md->start_subject) prev_is_word = FALSE; else
1680            ((md->ctypes[eptr[-1]] & ctype_word) != 0);            {
1681          cur_is_word = (eptr < md->end_subject) &&            if (eptr <= md->start_used_ptr) md->start_used_ptr = eptr - 1;
1682            ((md->ctypes[*eptr] & ctype_word) != 0);            prev_is_word = ((md->ctypes[eptr[-1]] & ctype_word) != 0);
1683              }
1684            if (eptr >= md->end_subject)
1685              {
1686              SCHECK_PARTIAL();
1687              cur_is_word = FALSE;
1688              }
1689            else cur_is_word = ((md->ctypes[*eptr] & ctype_word) != 0);
1690          }          }
1691    
1692        /* Now see if the situation is what we want */        /* Now see if the situation is what we want */
# Line 1510  for (;;) Line 1704  for (;;)
1704      /* Fall through */      /* Fall through */
1705    
1706      case OP_ALLANY:      case OP_ALLANY:
1707      if (eptr++ >= md->end_subject) RRETURN(MATCH_NOMATCH);      if (eptr++ >= md->end_subject)
1708          {
1709          SCHECK_PARTIAL();
1710          RRETURN(MATCH_NOMATCH);
1711          }
1712      if (utf8) while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;      if (utf8) while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;
1713      ecode++;      ecode++;
1714      break;      break;
# Line 1519  for (;;) Line 1717  for (;;)
1717      any byte, even newline, independent of the setting of PCRE_DOTALL. */      any byte, even newline, independent of the setting of PCRE_DOTALL. */
1718    
1719      case OP_ANYBYTE:      case OP_ANYBYTE:
1720      if (eptr++ >= md->end_subject) RRETURN(MATCH_NOMATCH);      if (eptr++ >= md->end_subject)
1721          {
1722          SCHECK_PARTIAL();
1723          RRETURN(MATCH_NOMATCH);
1724          }
1725      ecode++;      ecode++;
1726      break;      break;
1727    
1728      case OP_NOT_DIGIT:      case OP_NOT_DIGIT:
1729      if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);      if (eptr >= md->end_subject)
1730          {
1731          SCHECK_PARTIAL();
1732          RRETURN(MATCH_NOMATCH);
1733          }
1734      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
1735      if (      if (
1736  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
# Line 1537  for (;;) Line 1743  for (;;)
1743      break;      break;
1744    
1745      case OP_DIGIT:      case OP_DIGIT:
1746      if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);      if (eptr >= md->end_subject)
1747          {
1748          SCHECK_PARTIAL();
1749          RRETURN(MATCH_NOMATCH);
1750          }
1751      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
1752      if (      if (
1753  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
# Line 1550  for (;;) Line 1760  for (;;)
1760      break;      break;
1761    
1762      case OP_NOT_WHITESPACE:      case OP_NOT_WHITESPACE:
1763      if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);      if (eptr >= md->end_subject)
1764          {
1765          SCHECK_PARTIAL();
1766          RRETURN(MATCH_NOMATCH);
1767          }
1768      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
1769      if (      if (
1770  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
# Line 1563  for (;;) Line 1777  for (;;)
1777      break;      break;
1778    
1779      case OP_WHITESPACE:      case OP_WHITESPACE:
1780      if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);      if (eptr >= md->end_subject)
1781          {
1782          SCHECK_PARTIAL();
1783          RRETURN(MATCH_NOMATCH);
1784          }
1785      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
1786      if (      if (
1787  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
# Line 1576  for (;;) Line 1794  for (;;)
1794      break;      break;
1795    
1796      case OP_NOT_WORDCHAR:      case OP_NOT_WORDCHAR:
1797      if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);      if (eptr >= md->end_subject)
1798          {
1799          SCHECK_PARTIAL();
1800          RRETURN(MATCH_NOMATCH);
1801          }
1802      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
1803      if (      if (
1804  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
# Line 1589  for (;;) Line 1811  for (;;)
1811      break;      break;
1812    
1813      case OP_WORDCHAR:      case OP_WORDCHAR:
1814      if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);      if (eptr >= md->end_subject)
1815          {
1816          SCHECK_PARTIAL();
1817          RRETURN(MATCH_NOMATCH);
1818          }
1819      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
1820      if (      if (
1821  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
# Line 1602  for (;;) Line 1828  for (;;)
1828      break;      break;
1829    
1830      case OP_ANYNL:      case OP_ANYNL:
1831      if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);      if (eptr >= md->end_subject)
1832          {
1833          SCHECK_PARTIAL();
1834          RRETURN(MATCH_NOMATCH);
1835          }
1836      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
1837      switch(c)      switch(c)
1838        {        {
# Line 1626  for (;;) Line 1856  for (;;)
1856      break;      break;
1857    
1858      case OP_NOT_HSPACE:      case OP_NOT_HSPACE:
1859      if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);      if (eptr >= md->end_subject)
1860          {
1861          SCHECK_PARTIAL();
1862          RRETURN(MATCH_NOMATCH);
1863          }
1864      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
1865      switch(c)      switch(c)
1866        {        {
# Line 1656  for (;;) Line 1890  for (;;)
1890      break;      break;
1891    
1892      case OP_HSPACE:      case OP_HSPACE:
1893      if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);      if (eptr >= md->end_subject)
1894          {
1895          SCHECK_PARTIAL();
1896          RRETURN(MATCH_NOMATCH);
1897          }
1898      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
1899      switch(c)      switch(c)
1900        {        {
# Line 1686  for (;;) Line 1924  for (;;)
1924      break;      break;
1925    
1926      case OP_NOT_VSPACE:      case OP_NOT_VSPACE:
1927      if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);      if (eptr >= md->end_subject)
1928          {
1929          SCHECK_PARTIAL();
1930          RRETURN(MATCH_NOMATCH);
1931          }
1932      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
1933      switch(c)      switch(c)
1934        {        {
# Line 1704  for (;;) Line 1946  for (;;)
1946      break;      break;
1947    
1948      case OP_VSPACE:      case OP_VSPACE:
1949      if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);      if (eptr >= md->end_subject)
1950          {
1951          SCHECK_PARTIAL();
1952          RRETURN(MATCH_NOMATCH);
1953          }
1954      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
1955      switch(c)      switch(c)
1956        {        {
# Line 1727  for (;;) Line 1973  for (;;)
1973    
1974      case OP_PROP:      case OP_PROP:
1975      case OP_NOTPROP:      case OP_NOTPROP:
1976      if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);      if (eptr >= md->end_subject)
1977          {
1978          SCHECK_PARTIAL();
1979          RRETURN(MATCH_NOMATCH);
1980          }
1981      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
1982        {        {
1983        const ucd_record *prop = GET_UCD(c);        const ucd_record *prop = GET_UCD(c);
# Line 1772  for (;;) Line 2022  for (;;)
2022      is in the binary; otherwise a compile-time error occurs. */      is in the binary; otherwise a compile-time error occurs. */
2023    
2024      case OP_EXTUNI:      case OP_EXTUNI:
2025      if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);      if (eptr >= md->end_subject)
2026          {
2027          SCHECK_PARTIAL();
2028          RRETURN(MATCH_NOMATCH);
2029          }
2030      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
2031        {        {
2032        int category = UCD_CATEGORY(c);        int category = UCD_CATEGORY(c);
# Line 1852  for (;;) Line 2106  for (;;)
2106          break;          break;
2107    
2108          default:               /* No repeat follows */          default:               /* No repeat follows */
2109          if (!match_ref(offset, eptr, length, md, ims)) RRETURN(MATCH_NOMATCH);          if (!match_ref(offset, eptr, length, md, ims))
2110              {
2111              CHECK_PARTIAL();
2112              RRETURN(MATCH_NOMATCH);
2113              }
2114          eptr += length;          eptr += length;
2115          continue;              /* With the main loop */          continue;              /* With the main loop */
2116          }          }
# Line 1868  for (;;) Line 2126  for (;;)
2126    
2127        for (i = 1; i <= min; i++)        for (i = 1; i <= min; i++)
2128          {          {
2129          if (!match_ref(offset, eptr, length, md, ims))          if (!match_ref(offset, eptr, length, md, ims))
2130            {            {
2131            CHECK_PARTIAL();            CHECK_PARTIAL();
2132            RRETURN(MATCH_NOMATCH);            RRETURN(MATCH_NOMATCH);
2133            }            }
2134          eptr += length;          eptr += length;
2135          }          }
2136    
# Line 1889  for (;;) Line 2147  for (;;)
2147            {            {
2148            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM14);            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM14);
2149            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2150            if (fi >= max || !match_ref(offset, eptr, length, md, ims))            if (fi >= max) RRETURN(MATCH_NOMATCH);
2151              if (!match_ref(offset, eptr, length, md, ims))
2152              {              {
2153              CHECK_PARTIAL();              CHECK_PARTIAL();
2154              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
2155              }              }
2156            eptr += length;            eptr += length;
2157            }            }
2158          /* Control never gets here */          /* Control never gets here */
# Line 1906  for (;;) Line 2165  for (;;)
2165          pp = eptr;          pp = eptr;
2166          for (i = min; i < max; i++)          for (i = min; i < max; i++)
2167            {            {
2168            if (!match_ref(offset, eptr, length, md, ims)) break;            if (!match_ref(offset, eptr, length, md, ims))
2169                {
2170                CHECK_PARTIAL();
2171                break;
2172                }
2173            eptr += length;            eptr += length;
2174            }            }
         CHECK_PARTIAL();  
2175          while (eptr >= pp)          while (eptr >= pp)
2176            {            {
2177            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM15);            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM15);
# Line 1921  for (;;) Line 2183  for (;;)
2183        }        }
2184      /* Control never gets here */      /* Control never gets here */
2185    
   
   
2186      /* Match a bit-mapped character class, possibly repeatedly. This op code is      /* Match a bit-mapped character class, possibly repeatedly. This op code is
2187      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,
2188      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 1977  for (;;) Line 2237  for (;;)
2237          {          {
2238          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
2239            {            {
2240            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
2241              {              {
2242              CHECK_PARTIAL();              SCHECK_PARTIAL();
2243              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
2244              }              }
2245            GETCHARINC(c, eptr);            GETCHARINC(c, eptr);
2246            if (c > 255)            if (c > 255)
2247              {              {
# Line 1999  for (;;) Line 2259  for (;;)
2259          {          {
2260          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
2261            {            {
2262            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
2263              {              {
2264              CHECK_PARTIAL();              SCHECK_PARTIAL();
2265              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
2266              }              }
2267            c = *eptr++;            c = *eptr++;
2268            if ((data[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);            if ((data[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);
2269            }            }
# Line 2027  for (;;) Line 2287  for (;;)
2287              {              {
2288              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM16);              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM16);
2289              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2290              if (fi >= max)              if (fi >= max) RRETURN(MATCH_NOMATCH);
2291                {              if (eptr >= md->end_subject)
               CHECK_PARTIAL();  
               RRETURN(MATCH_NOMATCH);  
               }  
             if (eptr >= md->end_subject)  
2292                {                {
2293                SCHECK_PARTIAL();                SCHECK_PARTIAL();
2294                RRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
2295                }                }
2296              GETCHARINC(c, eptr);              GETCHARINC(c, eptr);
2297              if (c > 255)              if (c > 255)
2298                {                {
# Line 2056  for (;;) Line 2312  for (;;)
2312              {              {
2313              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM17);              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM17);
2314              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2315              if (fi >= max)              if (fi >= max) RRETURN(MATCH_NOMATCH);
2316                {              if (eptr >= md->end_subject)
               CHECK_PARTIAL();  
               RRETURN(MATCH_NOMATCH);  
               }  
             if (eptr >= md->end_subject)  
2317                {                {
2318                SCHECK_PARTIAL();                SCHECK_PARTIAL();
2319                RRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
2320                }                }
2321              c = *eptr++;              c = *eptr++;
2322              if ((data[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);              if ((data[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);
2323              }              }
# Line 2086  for (;;) Line 2338  for (;;)
2338            for (i = min; i < max; i++)            for (i = min; i < max; i++)
2339              {              {
2340              int len = 1;              int len = 1;
2341              if (eptr >= md->end_subject) break;              if (eptr >= md->end_subject)
2342                  {
2343                  SCHECK_PARTIAL();
2344                  break;
2345                  }
2346              GETCHARLEN(c, eptr, len);              GETCHARLEN(c, eptr, len);
2347              if (c > 255)              if (c > 255)
2348                {                {
# Line 2098  for (;;) Line 2354  for (;;)
2354                }                }
2355              eptr += len;              eptr += len;
2356              }              }
           CHECK_PARTIAL();  
2357            for (;;)            for (;;)
2358              {              {
2359              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM18);              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM18);
# Line 2113  for (;;) Line 2368  for (;;)
2368            {            {
2369            for (i = min; i < max; i++)            for (i = min; i < max; i++)
2370              {              {
2371              if (eptr >= md->end_subject) break;              if (eptr >= md->end_subject)
2372                  {
2373                  SCHECK_PARTIAL();
2374                  break;
2375                  }
2376              c = *eptr;              c = *eptr;
2377              if ((data[c/8] & (1 << (c&7))) == 0) break;              if ((data[c/8] & (1 << (c&7))) == 0) break;
2378              eptr++;              eptr++;
2379              }              }
           CHECK_PARTIAL();  
2380            while (eptr >= pp)            while (eptr >= pp)
2381              {              {
2382              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM19);              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM19);
# Line 2176  for (;;) Line 2434  for (;;)
2434    
2435        for (i = 1; i <= min; i++)        for (i = 1; i <= min; i++)
2436          {          {
2437          if (eptr >= md->end_subject)          if (eptr >= md->end_subject)
2438            {            {
2439            SCHECK_PARTIAL();            SCHECK_PARTIAL();
2440            RRETURN(MATCH_NOMATCH);            RRETURN(MATCH_NOMATCH);
2441            }            }
2442          GETCHARINCTEST(c, eptr);          GETCHARINCTEST(c, eptr);
2443          if (!_pcre_xclass(c, data)) RRETURN(MATCH_NOMATCH);          if (!_pcre_xclass(c, data)) RRETURN(MATCH_NOMATCH);
2444          }          }
# Line 2199  for (;;) Line 2457  for (;;)
2457            {            {
2458            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM20);            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM20);
2459            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2460            if (fi >= max)            if (fi >= max) RRETURN(MATCH_NOMATCH);
2461              {            if (eptr >= md->end_subject)
             CHECK_PARTIAL();  
             RRETURN(MATCH_NOMATCH);  
             }  
           if (eptr >= md->end_subject)  
2462              {              {
2463              SCHECK_PARTIAL();              SCHECK_PARTIAL();
2464              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
2465              }              }
2466            GETCHARINCTEST(c, eptr);            GETCHARINCTEST(c, eptr);
2467            if (!_pcre_xclass(c, data)) RRETURN(MATCH_NOMATCH);            if (!_pcre_xclass(c, data)) RRETURN(MATCH_NOMATCH);
2468            }            }
# Line 2223  for (;;) Line 2477  for (;;)
2477          for (i = min; i < max; i++)          for (i = min; i < max; i++)
2478            {            {
2479            int len = 1;            int len = 1;
2480            if (eptr >= md->end_subject) break;            if (eptr >= md->end_subject)
2481                {
2482                SCHECK_PARTIAL();
2483                break;
2484                }
2485            GETCHARLENTEST(c, eptr, len);            GETCHARLENTEST(c, eptr, len);
2486            if (!_pcre_xclass(c, data)) break;            if (!_pcre_xclass(c, data)) break;
2487            eptr += len;            eptr += len;
2488            }            }
         CHECK_PARTIAL();  
2489          for(;;)          for(;;)
2490            {            {
2491            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM21);            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM21);
# Line 2252  for (;;) Line 2509  for (;;)
2509        length = 1;        length = 1;
2510        ecode++;        ecode++;
2511        GETCHARLEN(fc, ecode, length);        GETCHARLEN(fc, ecode, length);
2512        if (length > md->end_subject - eptr) RRETURN(MATCH_NOMATCH);        if (length > md->end_subject - eptr)
2513            {
2514            CHECK_PARTIAL();             /* Not SCHECK_PARTIAL() */
2515            RRETURN(MATCH_NOMATCH);
2516            }
2517        while (length-- > 0) if (*ecode++ != *eptr++) RRETURN(MATCH_NOMATCH);        while (length-- > 0) if (*ecode++ != *eptr++) RRETURN(MATCH_NOMATCH);
2518        }        }
2519      else      else
# Line 2260  for (;;) Line 2521  for (;;)
2521    
2522      /* Non-UTF-8 mode */      /* Non-UTF-8 mode */
2523        {        {
2524        if (md->end_subject - eptr < 1) RRETURN(MATCH_NOMATCH);        if (md->end_subject - eptr < 1)
2525            {
2526            SCHECK_PARTIAL();            /* This one can use SCHECK_PARTIAL() */
2527            RRETURN(MATCH_NOMATCH);
2528            }
2529        if (ecode[1] != *eptr++) RRETURN(MATCH_NOMATCH);        if (ecode[1] != *eptr++) RRETURN(MATCH_NOMATCH);
2530        ecode += 2;        ecode += 2;
2531        }        }
# Line 2276  for (;;) Line 2541  for (;;)
2541        ecode++;        ecode++;
2542        GETCHARLEN(fc, ecode, length);        GETCHARLEN(fc, ecode, length);
2543    
2544        if (length > md->end_subject - eptr) RRETURN(MATCH_NOMATCH);        if (length > md->end_subject - eptr)
2545            {
2546            CHECK_PARTIAL();             /* Not SCHECK_PARTIAL() */
2547            RRETURN(MATCH_NOMATCH);
2548            }
2549    
2550        /* 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
2551        can use the fast lookup table. */        can use the fast lookup table. */
# Line 2311  for (;;) Line 2580  for (;;)
2580    
2581      /* Non-UTF-8 mode */      /* Non-UTF-8 mode */
2582        {        {
2583        if (md->end_subject - eptr < 1) RRETURN(MATCH_NOMATCH);        if (md->end_subject - eptr < 1)
2584            {
2585            SCHECK_PARTIAL();            /* This one can use SCHECK_PARTIAL() */
2586            RRETURN(MATCH_NOMATCH);
2587            }
2588        if (md->lcc[ecode[1]] != md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH);        if (md->lcc[ecode[1]] != md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH);
2589        ecode += 2;        ecode += 2;
2590        }        }
# Line 2365  for (;;) Line 2638  for (;;)
2638      case OP_MINQUERY:      case OP_MINQUERY:
2639      c = *ecode++ - OP_STAR;      c = *ecode++ - OP_STAR;
2640      minimize = (c & 1) != 0;      minimize = (c & 1) != 0;
2641    
2642      min = rep_min[c];                 /* Pick up values from tables; */      min = rep_min[c];                 /* Pick up values from tables; */
2643      max = rep_max[c];                 /* zero for max => infinity */      max = rep_max[c];                 /* zero for max => infinity */
2644      if (max == 0) max = INT_MAX;      if (max == 0) max = INT_MAX;
# Line 2417  for (;;) Line 2691  for (;;)
2691              {              {
2692              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM22);              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM22);
2693              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2694              if (fi >= max)              if (fi >= max) RRETURN(MATCH_NOMATCH);
               {  
               CHECK_PARTIAL();  
               RRETURN(MATCH_NOMATCH);  
               }  
2695              if (eptr <= md->end_subject - length &&              if (eptr <= md->end_subject - length &&
2696                memcmp(eptr, charptr, length) == 0) eptr += length;                memcmp(eptr, charptr, length) == 0) eptr += length;
2697  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
# Line 2450  for (;;) Line 2720  for (;;)
2720                       eptr <= md->end_subject - oclength &&                       eptr <= md->end_subject - oclength &&
2721                       memcmp(eptr, occhars, oclength) == 0) eptr += oclength;                       memcmp(eptr, occhars, oclength) == 0) eptr += oclength;
2722  #endif  /* SUPPORT_UCP */  #endif  /* SUPPORT_UCP */
2723              else break;              else
2724                  {
2725                  CHECK_PARTIAL();
2726                  break;
2727                  }
2728              }              }
2729    
           CHECK_PARTIAL();  
2730            if (possessive) continue;            if (possessive) continue;
2731    
2732            for(;;)            for(;;)
2733              {              {
2734              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM23);              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM23);
# Line 2514  for (;;) Line 2787  for (;;)
2787            {            {
2788            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM24);            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM24);
2789            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2790            if (fi >= max)            if (fi >= max) RRETURN(MATCH_NOMATCH);
             {  
             CHECK_PARTIAL();  
             RRETURN(MATCH_NOMATCH);  
             }  
2791            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
2792              {              {
2793              SCHECK_PARTIAL();              SCHECK_PARTIAL();
2794              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
2795              }              }
2796            if (fc != md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH);            if (fc != md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH);
# Line 2533  for (;;) Line 2802  for (;;)
2802          pp = eptr;          pp = eptr;
2803          for (i = min; i < max; i++)          for (i = min; i < max; i++)
2804            {            {
2805            if (eptr >= md->end_subject || fc != md->lcc[*eptr]) break;            if (eptr >= md->end_subject)
2806                {
2807                SCHECK_PARTIAL();
2808                break;
2809                }
2810              if (fc != md->lcc[*eptr]) break;
2811            eptr++;            eptr++;
2812            }            }
2813    
         CHECK_PARTIAL();  
2814          if (possessive) continue;          if (possessive) continue;
2815    
2816          while (eptr >= pp)          while (eptr >= pp)
2817            {            {
2818            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM25);            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM25);
# Line 2555  for (;;) Line 2828  for (;;)
2828    
2829      else      else
2830        {        {
2831        for (i = 1; i <= min; i++)        for (i = 1; i <= min; i++)
2832          {          {
2833          if (eptr >= md->end_subject)          if (eptr >= md->end_subject)
2834            {            {
# Line 2563  for (;;) Line 2836  for (;;)
2836            RRETURN(MATCH_NOMATCH);            RRETURN(MATCH_NOMATCH);
2837            }            }
2838          if (fc != *eptr++) RRETURN(MATCH_NOMATCH);          if (fc != *eptr++) RRETURN(MATCH_NOMATCH);
2839          }          }
2840    
2841        if (min == max) continue;        if (min == max) continue;
2842    
2843        if (minimize)        if (minimize)
2844          {          {
2845          for (fi = min;; fi++)          for (fi = min;; fi++)
2846            {            {
2847            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM26);            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM26);
2848            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2849            if (fi >= max)            if (fi >= max) RRETURN(MATCH_NOMATCH);
             {  
             CHECK_PARTIAL();  
             RRETURN(MATCH_NOMATCH);  
             }  
2850            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
2851              {              {
2852              SCHECK_PARTIAL();              SCHECK_PARTIAL();
2853              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
2854              }              }
2855            if (fc != *eptr++) RRETURN(MATCH_NOMATCH);            if (fc != *eptr++) RRETURN(MATCH_NOMATCH);
2856            }            }
2857          /* Control never gets here */          /* Control never gets here */
# Line 2590  for (;;) Line 2861  for (;;)
2861          pp = eptr;          pp = eptr;
2862          for (i = min; i < max; i++)          for (i = min; i < max; i++)
2863            {            {
2864            if (eptr >= md->end_subject || fc != *eptr) break;            if (eptr >= md->end_subject)
2865                {
2866                SCHECK_PARTIAL();
2867                break;
2868                }
2869              if (fc != *eptr) break;
2870            eptr++;            eptr++;
2871            }            }
         CHECK_PARTIAL();  
2872          if (possessive) continue;          if (possessive) continue;
2873    
2874          while (eptr >= pp)          while (eptr >= pp)
2875            {            {
2876            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM27);            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM27);
# Line 2610  for (;;) Line 2886  for (;;)
2886      checking can be multibyte. */      checking can be multibyte. */
2887    
2888      case OP_NOT:      case OP_NOT:
2889      if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);      if (eptr >= md->end_subject)
2890          {
2891          SCHECK_PARTIAL();
2892          RRETURN(MATCH_NOMATCH);
2893          }
2894      ecode++;      ecode++;
2895      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
2896      if ((ims & PCRE_CASELESS) != 0)      if ((ims & PCRE_CASELESS) != 0)
# Line 2717  for (;;) Line 2997  for (;;)
2997            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
2998              {              {
2999              SCHECK_PARTIAL();              SCHECK_PARTIAL();
3000              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
3001              }              }
3002            GETCHARINC(d, eptr);            GETCHARINC(d, eptr);
3003            if (d < 256) d = md->lcc[d];            if (d < 256) d = md->lcc[d];
3004            if (fc == d) RRETURN(MATCH_NOMATCH);            if (fc == d) RRETURN(MATCH_NOMATCH);
# Line 2734  for (;;) Line 3014  for (;;)
3014            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
3015              {              {
3016              SCHECK_PARTIAL();              SCHECK_PARTIAL();
3017              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
3018              }              }
3019            if (fc == md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH);            if (fc == md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH);
3020            }            }
3021          }          }
3022    
3023        if (min == max) continue;        if (min == max) continue;
# Line 2753  for (;;) Line 3033  for (;;)
3033              {              {
3034              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM28);              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM28);
3035              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3036              if (fi >= max)              if (fi >= max) RRETURN(MATCH_NOMATCH);
3037                if (eptr >= md->end_subject)
3038                {                {
3039                CHECK_PARTIAL();                SCHECK_PARTIAL();
3040                RRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
3041                }                }
             if (eptr >= md->end_subject)  
               {  
               SCHECK_PARTIAL();  
               RRETURN(MATCH_NOMATCH);  
               }  
3042              GETCHARINC(d, eptr);              GETCHARINC(d, eptr);
3043              if (d < 256) d = md->lcc[d];              if (d < 256) d = md->lcc[d];
3044              if (fc == d) RRETURN(MATCH_NOMATCH);              if (fc == d) RRETURN(MATCH_NOMATCH);
# Line 2776  for (;;) Line 3052  for (;;)
3052              {              {
3053              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM29);              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM29);
3054              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3055              if (fi >= max)              if (fi >= max) RRETURN(MATCH_NOMATCH);
               {  
               CHECK_PARTIAL();  
               RRETURN(MATCH_NOMATCH);  
               }  
3056              if (eptr >= md->end_subject)              if (eptr >= md->end_subject)
3057                {                {
3058                SCHECK_PARTIAL();                SCHECK_PARTIAL();
# Line 2806  for (;;) Line 3078  for (;;)
3078            for (i = min; i < max; i++)            for (i = min; i < max; i++)
3079              {              {
3080              int len = 1;              int len = 1;
3081              if (eptr >= md->end_subject) break;              if (eptr >= md->end_subject)
3082                  {
3083                  SCHECK_PARTIAL();
3084                  break;
3085                  }
3086              GETCHARLEN(d, eptr, len);              GETCHARLEN(d, eptr, len);
3087              if (d < 256) d = md->lcc[d];              if (d < 256) d = md->lcc[d];
3088              if (fc == d) break;              if (fc == d) break;
3089              eptr += len;              eptr += len;
3090              }              }
         CHECK_PARTIAL();  
3091          if (possessive) continue;          if (possessive) continue;
3092          for(;;)          for(;;)
3093              {              {
# Line 2828  for (;;) Line 3103  for (;;)
3103            {            {
3104            for (i = min; i < max; i++)            for (i = min; i < max; i++)
3105              {              {
3106              if (eptr >= md->end_subject || fc == md->lcc[*eptr]) break;              if (eptr >= md->end_subject)
3107                  {
3108                  SCHECK_PARTIAL();
3109                  break;
3110                  }
3111                if (fc == md->lcc[*eptr]) break;
3112              eptr++;              eptr++;
3113              }              }
           CHECK_PARTIAL();  
3114            if (possessive) continue;            if (possessive) continue;
3115            while (eptr >= pp)            while (eptr >= pp)
3116              {              {
# Line 2860  for (;;) Line 3139  for (;;)
3139            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
3140              {              {
3141              SCHECK_PARTIAL();              SCHECK_PARTIAL();
3142              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
3143              }              }
3144            GETCHARINC(d, eptr);            GETCHARINC(d, eptr);
3145            if (fc == d) RRETURN(MATCH_NOMATCH);            if (fc == d) RRETURN(MATCH_NOMATCH);
3146            }            }
# Line 2875  for (;;) Line 3154  for (;;)
3154            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
3155              {              {
3156              SCHECK_PARTIAL();              SCHECK_PARTIAL();
3157              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
3158              }              }
3159            if (fc == *eptr++) RRETURN(MATCH_NOMATCH);            if (fc == *eptr++) RRETURN(MATCH_NOMATCH);
3160            }            }
3161          }          }
3162    
3163        if (min == max) continue;        if (min == max) continue;
# Line 2894  for (;;) Line 3173  for (;;)
3173              {              {
3174              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM32);              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM32);
3175              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3176              if (fi >= max)              if (fi >= max) RRETURN(MATCH_NOMATCH);
3177                {              if (eptr >= md->end_subject)
               CHECK_PARTIAL();  
               RRETURN(MATCH_NOMATCH);  
               }  
             if (eptr >= md->end_subject)  
3178                {                {
3179                SCHECK_PARTIAL();                SCHECK_PARTIAL();
3180                RRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
3181                }                }
3182              GETCHARINC(d, eptr);              GETCHARINC(d, eptr);
3183              if (fc == d) RRETURN(MATCH_NOMATCH);              if (fc == d) RRETURN(MATCH_NOMATCH);
3184              }              }
# Line 2916  for (;;) Line 3191  for (;;)
3191              {              {
3192              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM33);              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM33);
3193              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3194              if (fi >= max)              if (fi >= max) RRETURN(MATCH_NOMATCH);
               {  
               CHECK_PARTIAL();  
               RRETURN(MATCH_NOMATCH);  
               }  
3195              if (eptr >= md->end_subject)              if (eptr >= md->end_subject)
3196                {                {
3197                SCHECK_PARTIAL();                SCHECK_PARTIAL();
3198                RRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
3199                }                }
3200              if (fc == *eptr++) RRETURN(MATCH_NOMATCH);              if (fc == *eptr++) RRETURN(MATCH_NOMATCH);
3201              }              }
3202            }            }
# Line 2946  for (;;) Line 3217  for (;;)
3217            for (i = min; i < max; i++)            for (i = min; i < max; i++)
3218              {              {
3219              int len = 1;              int len = 1;
3220              if (eptr >= md->end_subject) break;              if (eptr >= md->end_subject)
3221                  {
3222                  SCHECK_PARTIAL();
3223                  break;
3224                  }
3225              GETCHARLEN(d, eptr, len);              GETCHARLEN(d, eptr, len);
3226              if (fc == d) break;              if (fc == d) break;
3227              eptr += len;              eptr += len;
3228              }              }
           CHECK_PARTIAL();  
3229            if (possessive) continue;            if (possessive) continue;
3230            for(;;)            for(;;)
3231              {              {
# Line 2967  for (;;) Line 3241  for (;;)
3241            {            {
3242            for (i = min; i < max; i++)            for (i = min; i < max; i++)
3243              {              {
3244              if (eptr >= md->end_subject || fc == *eptr) break;              if (eptr >= md->end_subject)
3245                  {
3246                  SCHECK_PARTIAL();
3247                  break;
3248                  }
3249                if (fc == *eptr) break;
3250              eptr++;              eptr++;
3251              }              }
           CHECK_PARTIAL();  
3252            if (possessive) continue;            if (possessive) continue;
3253            while (eptr >= pp)            while (eptr >= pp)
3254              {              {
# Line 3077  for (;;) Line 3355  for (;;)
3355            if (prop_fail_result) RRETURN(MATCH_NOMATCH);            if (prop_fail_result) RRETURN(MATCH_NOMATCH);
3356            for (i = 1; i <= min; i++)            for (i = 1; i <= min; i++)
3357              {              {
3358              if (eptr >= md->end_subject)              if (eptr >= md->end_subject)
3359                {                {
3360                SCHECK_PARTIAL();                SCHECK_PARTIAL();
3361                RRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
3362                }                }
3363              GETCHARINCTEST(c, eptr);              GETCHARINCTEST(c, eptr);
3364              }              }
3365            break;            break;
# Line 3089  for (;;) Line 3367  for (;;)
3367            case PT_LAMP:            case PT_LAMP:
3368            for (i = 1; i <= min; i++)            for (i = 1; i <= min; i++)
3369              {              {
3370              if (eptr >= md->end_subject)              if (eptr >= md->end_subject)
3371                {                {
3372                SCHECK_PARTIAL();                SCHECK_PARTIAL();
3373                RRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
3374                }                }
3375              GETCHARINCTEST(c, eptr);              GETCHARINCTEST(c, eptr);
3376              prop_chartype = UCD_CHARTYPE(c);              prop_chartype = UCD_CHARTYPE(c);
3377              if ((prop_chartype == ucp_Lu ||              if ((prop_chartype == ucp_Lu ||
# Line 3106  for (;;) Line 3384  for (;;)
3384            case PT_GC:            case PT_GC:
3385            for (i = 1; i <= min; i++)            for (i = 1; i <= min; i++)
3386              {              {
3387              if (eptr >= md->end_subject)              if (eptr >= md->end_subject)
3388                {                {
3389                SCHECK_PARTIAL();                SCHECK_PARTIAL();
3390                RRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
3391                }                }
3392              GETCHARINCTEST(c, eptr);              GETCHARINCTEST(c, eptr);
3393              prop_category = UCD_CATEGORY(c);              prop_category = UCD_CATEGORY(c);
3394              if ((prop_category == prop_value) == prop_fail_result)              if ((prop_category == prop_value) == prop_fail_result)
# Line 3121  for (;;) Line 3399  for (;;)
3399            case PT_PC:            case PT_PC:
3400            for (i = 1; i <= min; i++)            for (i = 1; i <= min; i++)
3401              {              {
3402              if (eptr >= md->end_subject)              if (eptr >= md->end_subject)
3403                {                {
3404                SCHECK_PARTIAL();                SCHECK_PARTIAL();
3405                RRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
3406                }                }
3407              GETCHARINCTEST(c, eptr);              GETCHARINCTEST(c, eptr);
3408              prop_chartype = UCD_CHARTYPE(c);              prop_chartype = UCD_CHARTYPE(c);
3409              if ((prop_chartype == prop_value) == prop_fail_result)              if ((prop_chartype == prop_value) == prop_fail_result)
# Line 3136  for (;;) Line 3414  for (;;)
3414            case PT_SC:            case PT_SC:
3415            for (i = 1; i <= min; i++)            for (i = 1; i <= min; i++)
3416              {              {
3417              if (eptr >= md->end_subject)              if (eptr >= md->end_subject)
3418                {                {
3419                SCHECK_PARTIAL();                SCHECK_PARTIAL();
3420                RRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
3421                }                }
3422              GETCHARINCTEST(c, eptr);              GETCHARINCTEST(c, eptr);
3423              prop_script = UCD_SCRIPT(c);              prop_script = UCD_SCRIPT(c);
3424              if ((prop_script == prop_value) == prop_fail_result)              if ((prop_script == prop_value) == prop_fail_result)
# Line 3160  for (;;) Line 3438  for (;;)
3438          {          {
3439          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3440            {            {
3441            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
3442              {              {
3443              SCHECK_PARTIAL();              SCHECK_PARTIAL();
3444              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
3445              }              }
3446            GETCHARINCTEST(c, eptr);            GETCHARINCTEST(c, eptr);
3447            prop_category = UCD_CATEGORY(c);            prop_category = UCD_CATEGORY(c);
3448            if (prop_category == ucp_M) RRETURN(MATCH_NOMATCH);            if (prop_category == ucp_M) RRETURN(MATCH_NOMATCH);
# Line 3193  for (;;) Line 3471  for (;;)
3471            {            {
3472            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
3473              {              {
3474              SCHECK_PARTIAL();              SCHECK_PARTIAL();
3475              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
3476              }              }
3477            if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH);            if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH);
3478            eptr++;            eptr++;
3479            while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;            while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;
# Line 3205  for (;;) Line 3483  for (;;)
3483          case OP_ALLANY:          case OP_ALLANY:
3484          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3485            {            {
3486            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
3487              {              {
3488              SCHECK_PARTIAL();              SCHECK_PARTIAL();
3489              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
3490              }              }
3491            eptr++;            eptr++;
3492            while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;            while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;
3493            }            }
3494          break;          break;
3495    
3496          case OP_ANYBYTE:          case OP_ANYBYTE:
3497          if (eptr > md->end_subject - min) RRETURN(MATCH_NOMATCH);          if (eptr > md->end_subject - min) RRETURN(MATCH_NOMATCH);
3498          eptr += min;          eptr += min;
3499          break;          break;
3500    
3501          case OP_ANYNL:          case OP_ANYNL:
3502          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3503            {            {
3504            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
3505              {              {
3506              SCHECK_PARTIAL();              SCHECK_PARTIAL();
3507              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
3508              }              }
3509            GETCHARINC(c, eptr);            GETCHARINC(c, eptr);
3510            switch(c)            switch(c)
3511              {              {
# Line 3253  for (;;) Line 3531  for (;;)
3531          case OP_NOT_HSPACE:          case OP_NOT_HSPACE:
3532          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3533            {            {
3534            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
3535              {              {
3536              SCHECK_PARTIAL();              SCHECK_PARTIAL();
3537              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
3538              }              }
3539            GETCHARINC(c, eptr);            GETCHARINC(c, eptr);
3540            switch(c)            switch(c)
3541              {              {
# Line 3289  for (;;) Line 3567  for (;;)
3567          case OP_HSPACE:          case OP_HSPACE:
3568          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3569            {            {
3570            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
3571              {              {
3572              SCHECK_PARTIAL();              SCHECK_PARTIAL();
3573              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
3574              }              }
3575            GETCHARINC(c, eptr);            GETCHARINC(c, eptr);
3576            switch(c)            switch(c)
3577              {              {
# Line 3325  for (;;) Line 3603  for (;;)
3603          case OP_NOT_VSPACE:          case OP_NOT_VSPACE:
3604          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3605            {            {
3606            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
3607              {              {
3608              SCHECK_PARTIAL();              SCHECK_PARTIAL();
3609              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
3610              }              }
3611            GETCHARINC(c, eptr);            GETCHARINC(c, eptr);
3612            switch(c)            switch(c)
3613              {              {
# Line 3349  for (;;) Line 3627  for (;;)
3627          case OP_VSPACE:          case OP_VSPACE:
3628          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3629            {            {
3630            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
3631              {              {
3632              SCHECK_PARTIAL();              SCHECK_PARTIAL();
3633              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
3634              }              }
3635            GETCHARINC(c, eptr);            GETCHARINC(c, eptr);
3636            switch(c)            switch(c)
3637              {              {
# Line 3373  for (;;) Line 3651  for (;;)
3651          case OP_NOT_DIGIT:          case OP_NOT_DIGIT:
3652          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3653            {            {
3654            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
3655              {              {
3656              SCHECK_PARTIAL();              SCHECK_PARTIAL();
3657              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
3658              }              }
3659            GETCHARINC(c, eptr);            GETCHARINC(c, eptr);
3660            if (c < 128 && (md->ctypes[c] & ctype_digit) != 0)            if (c < 128 && (md->ctypes[c] & ctype_digit) != 0)
3661              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
# Line 3387  for (;;) Line 3665  for (;;)
3665          case OP_DIGIT:          case OP_DIGIT:
3666          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3667            {            {
3668            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
3669              {              {
3670              SCHECK_PARTIAL();              SCHECK_PARTIAL();
3671              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
3672              }              }
3673            if (*eptr >= 128 || (md->ctypes[*eptr++] & ctype_digit) == 0)            if (*eptr >= 128 || (md->ctypes[*eptr++] & ctype_digit) == 0)
3674              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
3675            /* 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 */
# Line 3401  for (;;) Line 3679  for (;;)
3679          case OP_NOT_WHITESPACE:          case OP_NOT_WHITESPACE:
3680          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3681            {            {
3682            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
3683              {              {
3684              SCHECK_PARTIAL();              SCHECK_PARTIAL();
3685              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
3686              }              }
3687            if (*eptr < 128 && (md->ctypes[*eptr] & ctype_space) != 0)            if (*eptr < 128 && (md->ctypes[*eptr] & ctype_space) != 0)
3688              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
3689            while (++eptr < md->end_subject && (*eptr & 0xc0) == 0x80);            while (++eptr < md->end_subject && (*eptr & 0xc0) == 0x80);
# Line 3415  for (;;) Line 3693  for (;;)
3693          case OP_WHITESPACE:          case OP_WHITESPACE:
3694          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3695            {            {
3696            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
3697              {              {
3698              SCHECK_PARTIAL();              SCHECK_PARTIAL();
3699              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
3700              }              }
3701            if (*eptr >= 128 || (md->ctypes[*eptr++] & ctype_space) == 0)            if (*eptr >= 128 || (md->ctypes[*eptr++] & ctype_space) == 0)
3702              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
3703            /* 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 */
# Line 3429  for (;;) Line 3707  for (;;)
3707          case OP_NOT_WORDCHAR:          case OP_NOT_WORDCHAR:
3708          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3709            {            {
3710            if (eptr >= md->end_subject ||            if (eptr >= md->end_subject)
3711               (*eptr < 128 && (md->ctypes[*eptr] & ctype_word) != 0))              {
3712                SCHECK_PARTIAL();
3713                RRETURN(MATCH_NOMATCH);
3714                }
3715              if (*eptr < 128 && (md->ctypes[*eptr] & ctype_word) != 0)
3716              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
3717            while (++eptr < md->end_subject && (*eptr & 0xc0) == 0x80);            while (++eptr < md->end_subject && (*eptr & 0xc0) == 0x80);
3718            }            }
# Line 3439  for (;;) Line 3721  for (;;)
3721          case OP_WORDCHAR:          case OP_WORDCHAR:
3722          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3723            {            {
3724            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
3725              {              {
3726              SCHECK_PARTIAL();              SCHECK_PARTIAL();
3727              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
3728              }              }
3729            if (*eptr >= 128 || (md->ctypes[*eptr++] & ctype_word) == 0)            if (*eptr >= 128 || (md->ctypes[*eptr++] & ctype_word) == 0)
3730              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
3731            /* 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 */
# Line 3465  for (;;) Line 3747  for (;;)
3747          case OP_ANY:          case OP_ANY:
3748          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3749            {            {
3750            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
3751              {              {
3752              SCHECK_PARTIAL();              SCHECK_PARTIAL();
3753              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
3754              }              }
3755            if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH);            if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH);
3756            eptr++;            eptr++;
3757            }            }
3758          break;          break;
3759    
3760          case OP_ALLANY:          case OP_ALLANY:
3761          if (eptr > md->end_subject - min) RRETURN(MATCH_NOMATCH);          if (eptr > md->end_subject - min)
3762              {
3763              SCHECK_PARTIAL();
3764              RRETURN(MATCH_NOMATCH);
3765              }
3766          eptr += min;          eptr += min;
3767          break;          break;
3768    
3769          case OP_ANYBYTE:          case OP_ANYBYTE:
3770          if (eptr > md->end_subject - min) RRETURN(MATCH_NOMATCH);          if (eptr > md->end_subject - min)
3771              {
3772              SCHECK_PARTIAL();
3773              RRETURN(MATCH_NOMATCH);
3774              }
3775          eptr += min;          eptr += min;
3776          break;          break;
3777    
3778          case OP_ANYNL:          case OP_ANYNL:
3779          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3780            {            {
3781            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
3782              {              {
3783              SCHECK_PARTIAL();              SCHECK_PARTIAL();
3784              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
3785              }              }
3786            switch(*eptr++)            switch(*eptr++)
3787              {              {
3788              default: RRETURN(MATCH_NOMATCH);              default: RRETURN(MATCH_NOMATCH);
# Line 3514  for (;;) Line 3804  for (;;)
3804          case OP_NOT_HSPACE:          case OP_NOT_HSPACE:
3805          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3806            {            {
3807            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
3808              {              {
3809              SCHECK_PARTIAL();              SCHECK_PARTIAL();
3810              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
3811              }              }
3812            switch(*eptr++)            switch(*eptr++)
3813              {              {
3814              default: break;              default: break;
# Line 3533  for (;;) Line 3823  for (;;)
3823          case OP_HSPACE:          case OP_HSPACE:
3824          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3825            {            {
3826            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
3827              {              {
3828              SCHECK_PARTIAL();              SCHECK_PARTIAL();
3829              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
3830              }              }
3831            switch(*eptr++)            switch(*eptr++)
3832              {              {
3833              default: RRETURN(MATCH_NOMATCH);              default: RRETURN(MATCH_NOMATCH);
# Line 3552  for (;;) Line 3842  for (;;)
3842          case OP_NOT_VSPACE:          case OP_NOT_VSPACE:
3843          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3844            {            {
3845            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
3846              {              {
3847              SCHECK_PARTIAL();              SCHECK_PARTIAL();
3848              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
3849              }              }
3850            switch(*eptr++)            switch(*eptr++)
3851              {              {
3852              default: break;              default: break;
# Line 3573  for (;;) Line 3863  for (;;)
3863          case OP_VSPACE:          case OP_VSPACE:
3864          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3865            {            {
3866            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
3867              {              {
3868              SCHECK_PARTIAL();              SCHECK_PARTIAL();
3869              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
3870              }              }
3871            switch(*eptr++)            switch(*eptr++)
3872              {              {
3873              default: RRETURN(MATCH_NOMATCH);              default: RRETURN(MATCH_NOMATCH);
# Line 3593  for (;;) Line 3883  for (;;)
3883    
3884          case OP_NOT_DIGIT:          case OP_NOT_DIGIT:
3885          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3886            {            {
3887            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
3888              {              {
3889              SCHECK_PARTIAL();              SCHECK_PARTIAL();
3890              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
3891              }              }
3892            if ((md->ctypes[*eptr++] & ctype_digit) != 0) RRETURN(MATCH_NOMATCH);            if ((md->ctypes[*eptr++] & ctype_digit) != 0) RRETURN(MATCH_NOMATCH);
3893            }            }
3894          break;          break;
3895    
3896          case OP_DIGIT:          case OP_DIGIT:
3897          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3898            {            {
3899            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
3900              {              {
3901              SCHECK_PARTIAL();              SCHECK_PARTIAL();
3902              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
3903              }              }
3904            if ((md->ctypes[*eptr++] & ctype_digit) == 0) RRETURN(MATCH_NOMATCH);            if ((md->ctypes[*eptr++] & ctype_digit) == 0) RRETURN(MATCH_NOMATCH);
3905            }            }
3906          break;          break;
3907    
3908          case OP_NOT_WHITESPACE:          case OP_NOT_WHITESPACE:
3909          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3910            {            {
3911            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
3912              {              {
3913              SCHECK_PARTIAL();              SCHECK_PARTIAL();
3914              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
3915              }              }
3916            if ((md->ctypes[*eptr++] & ctype_space) != 0) RRETURN(MATCH_NOMATCH);            if ((md->ctypes[*eptr++] & ctype_space) != 0) RRETURN(MATCH_NOMATCH);
3917            }            }
3918          break;          break;
3919    
3920          case OP_WHITESPACE:          case OP_WHITESPACE:
3921          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3922            {            {
3923            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
3924              {              {
3925              SCHECK_PARTIAL();              SCHECK_PARTIAL();
3926              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
3927              }              }
3928            if ((md->ctypes[*eptr++] & ctype_space) == 0) RRETURN(MATCH_NOMATCH);            if ((md->ctypes[*eptr++] & ctype_space) == 0) RRETURN(MATCH_NOMATCH);
3929            }            }
3930          break;          break;
3931    
3932          case OP_NOT_WORDCHAR:          case OP_NOT_WORDCHAR:
3933          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3934            {            {
3935            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
3936              {              {
3937              SCHECK_PARTIAL();              SCHECK_PARTIAL();
3938              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
3939              }              }
3940            if ((md->ctypes[*eptr++] & ctype_word) != 0)            if ((md->ctypes[*eptr++] & ctype_word) != 0)
3941              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
3942            }            }
3943          break;          break;
3944    
3945          case OP_WORDCHAR:          case OP_WORDCHAR:
3946          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3947            {            {
3948            if (eptr >= md->end_subject)            if (eptr >= md->end_subject)
3949              {              {
3950              SCHECK_PARTIAL();              SCHECK_PARTIAL();
3951              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
3952              }              }
3953            if ((md->ctypes[*eptr++] & ctype_word) == 0)            if ((md->ctypes[*eptr++] & ctype_word) == 0)
3954              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
3955            }            }
3956          break;          break;
3957    
3958          default:          default:
# Line 3690  for (;;) Line 3980  for (;;)
3980              {              {
3981              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM36);              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM36);
3982              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3983              if (fi >= max)              if (fi >= max) RRETURN(MATCH_NOMATCH);
3984                {              if (eptr >= md->end_subject)
               CHECK_PARTIAL();  
               RRETURN(MATCH_NOMATCH);  
               }  
             if (eptr >= md->end_subject)  
3985                {                {
3986                SCHECK_PARTIAL();                SCHECK_PARTIAL();
3987                RRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
3988                }                }
3989              GETCHARINC(c, eptr);              GETCHARINC(c, eptr);
3990              if (prop_fail_result) RRETURN(MATCH_NOMATCH);              if (prop_fail_result) RRETURN(MATCH_NOMATCH);
3991              }              }
# Line 3710  for (;;) Line 3996  for (;;)
3996              {              {
3997              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM37);              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM37);
3998              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3999              if (fi >= max)              if (fi >= max) RRETURN(MATCH_NOMATCH);
4000                {              if (eptr >= md->end_subject)
               CHECK_PARTIAL();  
               RRETURN(MATCH_NOMATCH);  
               }  
             if (eptr >= md->end_subject)  
4001                {                {
4002                SCHECK_PARTIAL();                SCHECK_PARTIAL();
4003                RRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4004                }                }
4005              GETCHARINC(c, eptr);              GETCHARINC(c, eptr);
4006              prop_chartype = UCD_CHARTYPE(c);              prop_chartype = UCD_CHARTYPE(c);
4007              if ((prop_chartype == ucp_Lu ||              if ((prop_chartype == ucp_Lu ||
# Line 3734  for (;;) Line 4016  for (;;)
4016              {              {
4017              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM38);              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM38);
4018              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
4019              if (fi >= max)              if (fi >= max) RRETURN(MATCH_NOMATCH);
4020                {              if (eptr >= md->end_subject)
               CHECK_PARTIAL();  
               RRETURN(MATCH_NOMATCH);  
               }  
             if (eptr >= md->end_subject)  
4021                {                {
4022                SCHECK_PARTIAL();                SCHECK_PARTIAL();
4023                RRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4024                }                }
4025              GETCHARINC(c, eptr);              GETCHARINC(c, eptr);
4026              prop_category = UCD_CATEGORY(c);              prop_category = UCD_CATEGORY(c);
4027              if ((prop_category == prop_value) == prop_fail_result)              if ((prop_category == prop_value) == prop_fail_result)
# Line 3756  for (;;) Line 4034  for (;;)
4034              {              {
4035              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM39);              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM39);
4036              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
4037              if (fi >= max)              if (fi >= max) RRETURN(MATCH_NOMATCH);
4038                {              if (eptr >= md->end_subject)
               CHECK_PARTIAL();  
               RRETURN(MATCH_NOMATCH);  
               }  
             if (eptr >= md->end_subject)  
4039                {                {
4040                SCHECK_PARTIAL();                SCHECK_PARTIAL();
4041                RRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4042                }                }
4043              GETCHARINC(c, eptr);              GETCHARINC(c, eptr);
4044              prop_chartype = UCD_CHARTYPE(c);              prop_chartype = UCD_CHARTYPE(c);
4045              if ((prop_chartype == prop_value) == prop_fail_result)              if ((prop_chartype == prop_value) == prop_fail_result)
# Line 3778  for (;;) Line 4052  for (;;)
4052              {              {
4053              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM40);              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM40);
4054              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
4055              if (fi >= max)              if (fi >= max) RRETURN(MATCH_NOMATCH);
4056                {              if (eptr >= md->end_subject)
               CHECK_PARTIAL();  
               RRETURN(MATCH_NOMATCH);  
               }  
             if (eptr >= md->end_subject)  
4057                {                {
4058                SCHECK_PARTIAL();                SCHECK_PARTIAL();
4059                RRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
4060                }                }
4061              GETCHARINC(c, eptr);              GETCHARINC(c, eptr);
4062              prop_script = UCD_SCRIPT(c);              prop_script = UCD_SCRIPT(c);
4063              if ((prop_script == prop_value) == prop_fail_result)              if ((prop_script == prop_value) == prop_fail_result)
# Line 3809  for (;;) Line 4079  for (;;)
4079            {            {
4080            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM41);            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM41);
4081            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
4082            if (fi >= max)            if (fi >= max) RRETURN(MATCH_NOMATCH);
4083              {            if (eptr >= md->end_subject)
             CHECK_PARTIAL();  
             RRETURN(MATCH_NOMATCH);  
             }  
           if (eptr >= md->end_subject)  
4084              {              {
4085              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4086              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4087              }              }
4088            GETCHARINCTEST(c, eptr);            GETCHARINCTEST(c, eptr);
4089            prop_category = UCD_CATEGORY(c);            prop_category = UCD_CATEGORY(c);
4090            if (prop_category == ucp_M) RRETURN(MATCH_NOMATCH);            if (prop_category == ucp_M) RRETURN(MATCH_NOMATCH);
# Line 3845  for (;;) Line 4111  for (;;)
4111            {            {
4112            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM42);            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM42);
4113            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
4114            if (fi >= max)            if (fi >= max) RRETURN(MATCH_NOMATCH);
4115              {            if (eptr >= md->end_subject)
             CHECK_PARTIAL();  
             RRETURN(MATCH_NOMATCH);  
             }  
           if (eptr >= md->end_subject)  
4116              {              {
4117              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4118              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4119              }              }
4120            if (ctype == OP_ANY && IS_NEWLINE(eptr))            if (ctype == OP_ANY && IS_NEWLINE(eptr))
4121              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4122            GETCHARINC(c, eptr);            GETCHARINC(c, eptr);
# Line 4012  for (;;) Line 4274  for (;;)
4274            {            {
4275            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM43);            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM43);
4276            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
4277            if (fi >= max)            if (fi >= max) RRETURN(MATCH_NOMATCH);
4278              {            if (eptr >= md->end_subject)
             CHECK_PARTIAL();  
             RRETURN(MATCH_NOMATCH);  
             }  
           if (eptr >= md->end_subject)  
4279              {              {
4280              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4281              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4282              }              }
4283            if (ctype == OP_ANY && IS_NEWLINE(eptr))            if (ctype == OP_ANY && IS_NEWLINE(eptr))
4284              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4285            c = *eptr++;            c = *eptr++;
# Line 4148  for (;;) Line 4406  for (;;)
4406            for (i = min; i < max; i++)            for (i = min; i < max; i++)
4407              {              {
4408              int len = 1;              int len = 1;
4409              if (eptr >= md->end_subject) break;              if (eptr >= md->end_subject)
4410                  {
4411                  SCHECK_PARTIAL();
4412                  break;
4413                  }
4414              GETCHARLEN(c, eptr, len);              GETCHARLEN(c, eptr, len);
4415              if (prop_fail_result) break;              if (prop_fail_result) break;
4416              eptr+= len;              eptr+= len;
# Line 4159  for (;;) Line 4421  for (;;)
4421            for (i = min; i < max; i++)            for (i = min; i < max; i++)
4422              {              {
4423              int len = 1;              int len = 1;
4424              if (eptr >= md->end_subject) break;              if (eptr >= md->end_subject)
4425                  {
4426                  SCHECK_PARTIAL();
4427                  break;
4428                  }
4429              GETCHARLEN(c, eptr, len);              GETCHARLEN(c, eptr, len);
4430              prop_chartype = UCD_CHARTYPE(c);              prop_chartype = UCD_CHARTYPE(c);
4431              if ((prop_chartype == ucp_Lu ||              if ((prop_chartype == ucp_Lu ||
# Line 4174  for (;;) Line 4440  for (;;)
4440            for (i = min; i < max; i++)            for (i = min; i < max; i++)
4441              {              {
4442              int len = 1;              int len = 1;
4443              if (eptr >= md->end_subject) break;              if (eptr >= md->end_subject)
4444                  {
4445                  SCHECK_PARTIAL();
4446                  break;
4447                  }
4448              GETCHARLEN(c, eptr, len);              GETCHARLEN(c, eptr, len);
4449              prop_category = UCD_CATEGORY(c);              prop_category = UCD_CATEGORY(c);
4450              if ((prop_category == prop_value) == prop_fail_result)              if ((prop_category == prop_value) == prop_fail_result)
# Line 4187  for (;;) Line 4457  for (;;)
4457            for (i = min; i < max; i++)            for (i = min; i < max; i++)
4458              {              {
4459              int len = 1;              int len = 1;
4460              if (eptr >= md->end_subject) break;              if (eptr >= md->end_subject)
4461                  {
4462                  SCHECK_PARTIAL();
4463                  break;
4464                  }
4465              GETCHARLEN(c, eptr, len);              GETCHARLEN(c, eptr, len);
4466              prop_chartype = UCD_CHARTYPE(c);              prop_chartype = UCD_CHARTYPE(c);
4467              if ((prop_chartype == prop_value) == prop_fail_result)              if ((prop_chartype == prop_value) == prop_fail_result)
# Line 4200  for (;;) Line 4474  for (;;)
4474            for (i = min; i < max; i++)            for (i = min; i < max; i++)
4475              {              {
4476              int len = 1;              int len = 1;
4477              if (eptr >= md->end_subject) break;              if (eptr >= md->end_subject)
4478                  {
4479                  SCHECK_PARTIAL();
4480                  break;
4481                  }
4482              GETCHARLEN(c, eptr, len);              GETCHARLEN(c, eptr, len);
4483              prop_script = UCD_SCRIPT(c);              prop_script = UCD_SCRIPT(c);
4484              if ((prop_script == prop_value) == prop_fail_result)              if ((prop_script == prop_value) == prop_fail_result)
# Line 4212  for (;;) Line 4490  for (;;)
4490    
4491          /* eptr is now past the end of the maximum run */          /* eptr is now past the end of the maximum run */
4492    
         CHECK_PARTIAL();  
4493          if (possessive) continue;          if (possessive) continue;
4494          for(;;)          for(;;)
4495            {            {
# Line 4230  for (;;) Line 4507  for (;;)
4507          {          {
4508          for (i = min; i < max; i++)          for (i = min; i < max; i++)
4509            {            {
4510            if (eptr >= md->end_subject) break;            if (eptr >= md->end_subject)
4511                {
4512                SCHECK_PARTIAL();
4513                break;
4514                }
4515            GETCHARINCTEST(c, eptr);            GETCHARINCTEST(c, eptr);
4516            prop_category = UCD_CATEGORY(c);            prop_category = UCD_CATEGORY(c);
4517            if (prop_category == ucp_M) break;            if (prop_category == ucp_M) break;
# Line 4249  for (;;) Line 4530  for (;;)
4530    
4531          /* eptr is now past the end of the maximum run */          /* eptr is now past the end of the maximum run */
4532    
         CHECK_PARTIAL();  
4533          if (possessive) continue;          if (possessive) continue;
4534    
4535          for(;;)          for(;;)
4536            {            {
4537            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM45);            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM45);
# Line 4286  for (;;) Line 4567  for (;;)
4567              {              {
4568              for (i = min; i < max; i++)              for (i = min; i < max; i++)
4569                {                {
4570                if (eptr >= md->end_subject || IS_NEWLINE(eptr)) break;                if (eptr >= md->end_subject)
4571                    {
4572                    SCHECK_PARTIAL();
4573                    break;
4574                    }
4575                  if (IS_NEWLINE(eptr)) break;
4576                eptr++;                eptr++;
4577                while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;                while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;
4578                }                }
# Line 4298  for (;;) Line 4584  for (;;)
4584              {              {
4585              for (i = min; i < max; i++)              for (i = min; i < max; i++)
4586                {                {
4587                if (eptr >= md->end_subject || IS_NEWLINE(eptr)) break;                if (eptr >= md->end_subject)
4588                    {
4589                    SCHECK_PARTIAL();
4590                    break;
4591                    }
4592                  if (IS_NEWLINE(eptr)) break;
4593                eptr++;                eptr++;
4594                while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;                while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;
4595                }                }
# Line 4310  for (;;) Line 4601  for (;;)
4601              {              {
4602              for (i = min; i < max; i++)              for (i = min; i < max; i++)
4603                {                {
4604                if (eptr >= md->end_subject) break;                if (eptr >= md->end_subject)
4605                    {
4606                    SCHECK_PARTIAL();
4607                    break;
4608                    }
4609                eptr++;                eptr++;
4610                while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;                while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;
4611                }                }
# Line 4323  for (;;) Line 4618  for (;;)
4618            case OP_ANYBYTE:            case OP_ANYBYTE:
4619            c = max - min;            c = max - min;
4620            if (c > (unsigned int)(md->end_subject - eptr))            if (c > (unsigned int)(md->end_subject - eptr))
4621              c = md->end_subject - eptr;              {
4622            eptr += c;              eptr = md->end_subject;
4623                SCHECK_PARTIAL();
4624                }
4625              else eptr += c;
4626            break;            break;
4627    
4628            case OP_ANYNL:            case OP_ANYNL:
4629            for (i = min; i < max; i++)            for (i = min; i < max; i++)
4630              {              {
4631              int len = 1;              int len = 1;
4632              if (eptr >= md->end_subject) break;              if (eptr >= md->end_subject)
4633                  {
4634                  SCHECK_PARTIAL();
4635                  break;
4636                  }
4637              GETCHARLEN(c, eptr, len);              GETCHARLEN(c, eptr, len);
4638              if (c == 0x000d)              if (c == 0x000d)
4639                {                {
# Line 4356  for (;;) Line 4658  for (;;)
4658              {              {
4659              BOOL gotspace;              BOOL gotspace;
4660              int len = 1;              int len = 1;
4661              if (eptr >= md->end_subject) break;              if (eptr >= md->end_subject)
4662                  {
4663                  SCHECK_PARTIAL();
4664                  break;
4665                  }
4666              GETCHARLEN(c, eptr, len);              GETCHARLEN(c, eptr, len);
4667              switch(c)              switch(c)
4668                {                {
# Line 4394  for (;;) Line 4700  for (;;)
4700              {              {
4701              BOOL gotspace;              BOOL gotspace;
4702              int len = 1;              int len = 1;
4703              if (eptr >= md->end_subject) break;              if (eptr >= md->end_subject)
4704                  {
4705                  SCHECK_PARTIAL();
4706                  break;
4707                  }
4708              GETCHARLEN(c, eptr, len);              GETCHARLEN(c, eptr, len);
4709              switch(c)              switch(c)
4710                {                {
# Line 4418  for (;;) Line 4728  for (;;)
4728            for (i = min; i < max; i++)            for (i = min; i < max; i++)
4729              {              {
4730              int len = 1;              int len = 1;
4731              if (eptr >= md->end_subject) break;              if (eptr >= md->end_subject)
4732                  {
4733                  SCHECK_PARTIAL();
4734                  break;
4735                  }
4736              GETCHARLEN(c, eptr, len);              GETCHARLEN(c, eptr, len);
4737              if (c < 256 && (md->ctypes[c] & ctype_digit) != 0) break;              if (c < 256 && (md->ctypes[c] & ctype_digit) != 0) break;
4738              eptr+= len;              eptr+= len;
# Line 4429  for (;;) Line 4743  for (;;)
4743            for (i = min; i < max; i++)            for (i = min; i < max; i++)
4744              {              {
4745              int len = 1;              int len = 1;
4746              if (eptr >= md->end_subject) break;              if (eptr >= md->end_subject)
4747                  {
4748                  SCHECK_PARTIAL();
4749                  break;
4750                  }
4751              GETCHARLEN(c, eptr, len);              GETCHARLEN(c, eptr, len);
4752              if (c >= 256 ||(md->ctypes[c] & ctype_digit) == 0) break;              if (c >= 256 ||(md->ctypes[c] & ctype_digit) == 0) break;
4753              eptr+= len;              eptr+= len;
# Line 4440  for (;;) Line 4758  for (;;)
4758            for (i = min; i < max; i++)            for (i = min; i < max; i++)
4759              {              {
4760              int len = 1;              int len = 1;
4761              if (eptr >= md->end_subject) break;              if (eptr >= md->end_subject)
4762                  {
4763                  SCHECK_PARTIAL();
4764                  break;
4765                  }
4766              GETCHARLEN(c, eptr, len);              GETCHARLEN(c, eptr, len);
4767              if (c < 256 && (md->ctypes[c] & ctype_space) != 0) break;              if (c < 256 && (md->ctypes[c] & ctype_space) != 0) break;
4768              eptr+= len;              eptr+= len;
# Line 4451  for (;;) Line 4773  for (;;)
4773            for (i = min; i < max; i++)            for (i = min; i < max; i++)
4774              {              {
4775              int len = 1;              int len = 1;
4776              if (eptr >= md->end_subject) break;              if (eptr >= md->end_subject)
4777                  {
4778                  SCHECK_PARTIAL();
4779                  break;
4780                  }
4781              GETCHARLEN(c, eptr, len);              GETCHARLEN(c, eptr, len);
4782              if (c >= 256 ||(md->ctypes[c] & ctype_space) == 0) break;              if (c >= 256 ||(md->ctypes[c] & ctype_space) == 0) break;
4783              eptr+= len;              eptr+= len;
# Line 4462  for (;;) Line 4788  for (;;)
4788            for (i = min; i < max; i++)            for (i = min; i < max; i++)
4789              {              {
4790              int len = 1;              int len = 1;
4791              if (eptr >= md->end_subject) break;              if (eptr >= md->end_subject)
4792                  {
4793                  SCHECK_PARTIAL();
4794                  break;
4795                  }
4796              GETCHARLEN(c, eptr, len);              GETCHARLEN(c, eptr, len);
4797              if (c < 256 && (md->ctypes[c] & ctype_word) != 0) break;              if (c < 256 && (md->ctypes[c] & ctype_word) != 0) break;
4798              eptr+= len;              eptr+= len;
# Line 4473  for (;;) Line 4803  for (;;)
4803            for (i = min; i < max; i++)            for (i = min; i < max; i++)
4804              {              {
4805              int len = 1;              int len = 1;
4806              if (eptr >= md->end_subject) break;              if (eptr >= md->end_subject)
4807                  {
4808                  SCHECK_PARTIAL();
4809                  break;
4810                  }
4811              GETCHARLEN(c, eptr, len);              GETCHARLEN(c, eptr, len);
4812              if (c >= 256 || (md->ctypes[c] & ctype_word) == 0) break;              if (c >= 256 || (md->ctypes[c] & ctype_word) == 0) break;
4813              eptr+= len;              eptr+= len;
# Line 4486  for (;;) Line 4820  for (;;)
4820    
4821          /* eptr is now past the end of the maximum run */          /* eptr is now past the end of the maximum run */
4822    
         CHECK_PARTIAL();  
4823          if (possessive) continue;          if (possessive) continue;
4824          for(;;)          for(;;)
4825            {            {
# Line 4506  for (;;) Line 4839  for (;;)
4839            case OP_ANY:            case OP_ANY:
4840            for (i = min; i < max; i++)            for (i = min; i < max; i++)
4841              {              {
4842              if (eptr >= md->end_subject || IS_NEWLINE(eptr)) break;              if (eptr >= md->end_subject)
4843                  {
4844                  SCHECK_PARTIAL();
4845                  break;
4846                  }
4847                if (IS_NEWLINE(eptr)) break;
4848              eptr++;              eptr++;
4849              }              }
4850            break;            break;
# Line 4515  for (;;) Line 4853  for (;;)
4853            case OP_ANYBYTE:            case OP_ANYBYTE:
4854            c = max - min;            c = max - min;
4855            if (c > (unsigned int)(md->end_subject - eptr))            if (c > (unsigned int)(md->end_subject - eptr))
4856              c = md->end_subject - eptr;              {
4857            eptr += c;              eptr = md->end_subject;
4858                SCHECK_PARTIAL();
4859                }
4860              else eptr += c;
4861            break;            break;
4862    
4863            case OP_ANYNL:            case OP_ANYNL:
4864            for (i = min; i < max; i++)            for (i = min; i < max; i++)
4865              {              {
4866              if (eptr >= md->end_subject) break;              if (eptr >= md->end_subject)
4867                  {
4868                  SCHECK_PARTIAL();
4869                  break;
4870                  }
4871              c = *eptr;              c = *eptr;
4872              if (c == 0x000d)              if (c == 0x000d)
4873                {                {
# Line 4543  for (;;) Line 4888  for (;;)
4888            case OP_NOT_HSPACE:            case OP_NOT_HSPACE:
4889            for (i = min; i < max; i++)            for (i = min; i < max; i++)
4890              {              {
4891              if (eptr >= md->end_subject) break;              if (eptr >= md->end_subject)
4892                  {
4893                  SCHECK_PARTIAL();
4894                  break;
4895                  }
4896              c = *eptr;              c = *eptr;
4897              if (c == 0x09 || c == 0x20 || c == 0xa0) break;              if (c == 0x09 || c == 0x20 || c == 0xa0) break;
4898              eptr++;              eptr++;
# Line 4553  for (;;) Line 4902  for (;;)
4902            case OP_HSPACE:            case OP_HSPACE:
4903            for (i = min; i < max; i++)            for (i = min; i < max; i++)
4904              {              {
4905              if (eptr >= md->end_subject) break;              if (eptr >= md->end_subject)
4906                  {
4907                  SCHECK_PARTIAL();
4908                  break;
4909                  }
4910              c = *eptr;              c = *eptr;
4911              if (c != 0x09 && c != 0x20 && c != 0xa0) break;              if (c != 0x09 && c != 0x20 && c != 0xa0) break;
4912              eptr++;              eptr++;
# Line 4563  for (;;) Line 4916  for (;;)
4916            case OP_NOT_VSPACE:            case OP_NOT_VSPACE:
4917            for (i = min; i < max; i++)            for (i = min; i < max; i++)
4918              {              {
4919              if (eptr >= md->end_subject) break;              if (eptr >= md->end_subject)
4920                  {
4921                  SCHECK_PARTIAL();
4922                  break;
4923                  }
4924              c = *eptr;              c = *eptr;
4925              if (c == 0x0a || c == 0x0b || c == 0x0c || c == 0x0d || c == 0x85)              if (c == 0x0a || c == 0x0b || c == 0x0c || c == 0x0d || c == 0x85)
4926                break;                break;
# Line 4574  for (;;) Line 4931  for (;;)
4931            case OP_VSPACE:            case OP_VSPACE:
4932            for (i = min; i < max; i++)            for (i = min; i < max; i++)
4933              {              {
4934              if (eptr >= md->end_subject) break;              if (eptr >= md->end_subject)
4935                  {
4936                  SCHECK_PARTIAL();
4937                  break;
4938                  }
4939              c = *eptr;              c = *eptr;
4940              if (c != 0x0a && c != 0x0b && c != 0x0c && c != 0x0d && c != 0x85)              if (c != 0x0a && c != 0x0b && c != 0x0c && c != 0x0d && c != 0x85)
4941                break;                break;
# Line 4585  for (;;) Line 4946  for (;;)
4946            case OP_NOT_DIGIT:            case OP_NOT_DIGIT:
4947            for (i = min; i < max; i++)            for (i = min; i < max; i++)
4948              {              {
4949              if (eptr >= md->end_subject || (md->ctypes[*eptr] & ctype_digit) != 0)              if (eptr >= md->end_subject)
4950                  {
4951                  SCHECK_PARTIAL();
4952                break;                break;
4953                  }
4954                if ((md->ctypes[*eptr] & ctype_digit) != 0) break;
4955              eptr++;              eptr++;
4956              }              }
4957            break;            break;
# Line 4594  for (;;) Line 4959  for (;;)
4959            case OP_DIGIT:            case OP_DIGIT:
4960            for (i = min; i < max; i++)            for (i = min; i < max; i++)
4961              {              {
4962              if (eptr >= md->end_subject || (md->ctypes[*eptr] & ctype_digit) == 0)              if (eptr >= md->end_subject)
4963                  {
4964                  SCHECK_PARTIAL();
4965                break;                break;
4966                  }
4967                if ((md->ctypes[*eptr] & ctype_digit) == 0) break;
4968              eptr++;              eptr++;
4969              }              }
4970            break;            break;
# Line 4603  for (;;) Line 4972  for (;;)
4972            case OP_NOT_WHITESPACE:            case OP_NOT_WHITESPACE:
4973            for (i = min; i < max; i++)            for (i = min; i < max; i++)
4974              {              {
4975              if (eptr >= md->end_subject || (md->ctypes[*eptr] & ctype_space) != 0)              if (eptr >= md->end_subject)
4976                  {
4977                  SCHECK_PARTIAL();
4978                break;                break;
4979                  }
4980                if ((md->ctypes[*eptr] & ctype_space) != 0) break;
4981              eptr++;              eptr++;
4982              }              }
4983            break;            break;
# Line 4612  for (;;) Line 4985  for (;;)
4985            case OP_WHITESPACE:            case OP_WHITESPACE:
4986            for (i = min; i < max; i++)            for (i = min; i < max; i++)
4987              {              {
4988              if (eptr >= md->end_subject || (md->ctypes[*eptr] & ctype_space) == 0)              if (eptr >= md->end_subject)
4989                  {
4990                  SCHECK_PARTIAL();
4991                break;                break;
4992                  }
4993                if ((md->ctypes[*eptr] & ctype_space) == 0) break;
4994              eptr++;              eptr++;
4995              }              }
4996            break;            break;
# Line 4621  for (;;) Line 4998  for (;;)
4998            case OP_NOT_WORDCHAR:            case OP_NOT_WORDCHAR:
4999            for (i = min; i < max; i++)            for (i = min; i < max; i++)
5000              {              {
5001              if (eptr >= md->end_subject || (md->ctypes[*eptr] & ctype_word) != 0)              if (eptr >= md->end_subject)
5002                  {
5003                  SCHECK_PARTIAL();
5004                break;                break;
5005                  }
5006                if ((md->ctypes[*eptr] & ctype_word) != 0) break;
5007              eptr++;              eptr++;
5008              }              }
5009            break;            break;
# Line 4630  for (;;) Line 5011  for (;;)
5011            case OP_WORDCHAR:            case OP_WORDCHAR:
5012            for (i = min; i < max; i++)            for (i = min; i < max; i++)
5013              {              {
5014              if (eptr >= md->end_subject || (md->ctypes[*eptr] & ctype_word) == 0)              if (eptr >= md->end_subject)
5015                  {
5016                  SCHECK_PARTIAL();
5017                break;                break;
5018                  }
5019                if ((md->ctypes[*eptr] & ctype_word) == 0) break;
5020              eptr++;              eptr++;
5021              }              }
5022            break;            break;
# Line 4642  for (;;) Line 5027  for (;;)
5027    
5028          /* eptr is now past the end of the maximum run */          /* eptr is now past the end of the maximum run */
5029    
         CHECK_PARTIAL();  
5030          if (possessive) continue;          if (possessive) continue;
5031          while (eptr >= pp)          while (eptr >= pp)
5032            {            {
# Line 4827  if (re == NULL || subject == NULL || Line 5211  if (re == NULL || subject == NULL ||
5211     (offsets == NULL && offsetcount > 0)) return PCRE_ERROR_NULL;     (offsets == NULL && offsetcount > 0)) return PCRE_ERROR_NULL;
5212  if (offsetcount < 0) return PCRE_ERROR_BADCOUNT;  if (offsetcount < 0) return PCRE_ERROR_BADCOUNT;
5213    
5214    /* This information is for finding all the numbers associated with a given
5215    name, for condition testing. */
5216    
5217    md->name_table = (uschar *)re + re->name_table_offset;
5218    md->name_count = re->name_count;
5219    md->name_entry_size = re->name_entry_size;
5220    
5221  /* Fish out the optional data from the extra_data structure, first setting  /* Fish out the optional data from the extra_data structure, first setting
5222  the default values. */  the default values. */
5223    
# Line 4894  md->jscript_compat = (re->options & PCRE Line 5285  md->jscript_compat = (re->options & PCRE
5285  md->notbol = (options & PCRE_NOTBOL) != 0;  md->notbol = (options & PCRE_NOTBOL) != 0;
5286  md->noteol = (options & PCRE_NOTEOL) != 0;  md->noteol = (options & PCRE_NOTEOL) != 0;
5287  md->notempty = (options & PCRE_NOTEMPTY) != 0;  md->notempty = (options & PCRE_NOTEMPTY) != 0;
5288  md->partial = (options & PCRE_PARTIAL) != 0;  md->notempty_atstart = (options & PCRE_NOTEMPTY_ATSTART) != 0;
5289    md->partial = ((options & PCRE_PARTIAL_HARD) != 0)? 2 :
5290                  ((options & PCRE_PARTIAL_SOFT) != 0)? 1 : 0;
5291  md->hitend = FALSE;  md->hitend = FALSE;
5292    
5293  md->recursive = NULL;                   /* No recursion at top level */  md->recursive = NULL;                   /* No recursion at top level */
# Line 5057  if (!anchored) Line 5450  if (!anchored)
5450      }      }
5451    else    else
5452      if (!startline && study != NULL &&      if (!startline && study != NULL &&
5453        (study->options & PCRE_STUDY_MAPPED) != 0)        (study->flags & PCRE_STUDY_MAPPED) != 0)
5454          start_bits = study->start_bits;          start_bits = study->start_bits;
5455    }    }
5456    
# Line 5184  for(;;) Line 5577  for(;;)
5577    
5578    end_subject = save_end_subject;    end_subject = save_end_subject;
5579    
5580  #ifdef DEBUG  /* Sigh. Some compilers never learn. */    /* The following two optimizations are disabled for partial matching or if
   printf(">>>> Match against: ");  
   pchars(start_match, end_subject - start_match, TRUE, md);  
   printf("\n");  
 #endif  
   
   /* If req_byte is set, we know that that character must appear in the  
   subject 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, or if  
5581    disabling is explicitly requested. */    disabling is explicitly requested. */
5582    
5583    if ((options & PCRE_NO_START_OPTIMIZE) == 0 &&    if ((options & PCRE_NO_START_OPTIMIZE) == 0 && !md->partial)
       req_byte >= 0 &&  
       end_subject - start_match < REQ_BYTE_MAX &&  
       !md->partial)  
5584      {      {
5585      register USPTR p = start_match + ((first_byte >= 0)? 1 : 0);      /* If the pattern was studied, a minimum subject length may be set. This is
5586        a lower bound; no actual string of that length may actually match the
5587        pattern. Although the value is, strictly, in characters, we treat it as
5588        bytes to avoid spending too much time in this optimization. */
5589    
5590      /* We don't need to repeat the search if we haven't yet reached the      if (study != NULL && (study->flags & PCRE_STUDY_MINLEN) != 0 &&
5591      place we found it at last time. */          (pcre_uint32)(end_subject - start_match) < study->minlength)
5592          {
5593          rc = MATCH_NOMATCH;
5594          break;
5595          }
5596    
5597        /* If req_byte is set, we know that that character must appear in the
5598        subject for the match to succeed. If the first character is set, req_byte
5599        must be later in the subject; otherwise the test starts at the match point.
5600        This optimization can save a huge amount of backtracking in patterns with
5601        nested unlimited repeats that aren't going to match. Writing separate code
5602        for cased/caseless versions makes it go faster, as does using an
5603        autoincrement and backing off on a match.
5604    
5605      if (p > req_byte_ptr)      HOWEVER: when the subject string is very, very long, searching to its end
5606        can take a long time, and give bad performance on quite ordinary patterns.
5607        This showed up when somebody was matching something like /^\d+C/ on a
5608        32-megabyte string... so we don't do this when the string is sufficiently
5609        long. */
5610    
5611        if (req_byte >= 0 && end_subject - start_match < REQ_BYTE_MAX)
5612        {        {
5613        if (req_byte_caseless)        register USPTR p = start_match + ((first_byte >= 0)? 1 : 0);
5614    
5615          /* We don't need to repeat the search if we haven't yet reached the
5616          place we found it at last time. */
5617    
5618          if (p > req_byte_ptr)
5619          {          {
5620          while (p < end_subject)          if (req_byte_caseless)
5621            {            {
5622            register int pp = *p++;            while (p < end_subject)
5623            if (pp == req_byte || pp == req_byte2) { p--; break; }              {
5624                register int pp = *p++;
5625                if (pp == req_byte || pp == req_byte2) { p--; break; }
5626                }
5627            }            }
5628          }          else
       else  
         {  
         while (p < end_subject)  
5629            {            {
5630            if (*p++ == req_byte) { p--; break; }            while (p < end_subject)
5631                {
5632                if (*p++ == req_byte) { p--; break; }
5633                }
5634            }            }
         }  
5635    
5636        /* If we can't find the required character, break the matching loop,          /* If we can't find the required character, break the matching loop,
5637        forcing a match failure. */          forcing a match failure. */
5638    
5639        if (p >= end_subject)          if (p >= end_subject)
5640          {            {
5641          rc = MATCH_NOMATCH;            rc = MATCH_NOMATCH;
5642          break;            break;
5643          }            }
5644    
5645        /* If we have found the required character, save the point where we          /* If we have found the required character, save the point where we
5646        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
5647        the start hasn't passed this character yet. */          the start hasn't passed this character yet. */
5648    
5649        req_byte_ptr = p;          req_byte_ptr = p;
5650            }
5651        }        }
5652      }      }
5653    
5654    /* OK, we can now run the match. If "hitend" is set afterwards, remember the  #ifdef PCRE_DEBUG  /* Sigh. Some compilers never learn. */
5655      printf(">>>> Match against: ");
5656      pchars(start_match, end_subject - start_match, TRUE, md);
5657      printf("\n");
5658    #endif
5659    
5660      /* OK, we can now run the match. If "hitend" is set afterwards, remember the
5661    first starting point for which a partial match was found. */    first starting point for which a partial match was found. */
5662    
5663    md->start_match_ptr = start_match;    md->start_match_ptr = start_match;
5664      md->start_used_ptr = start_match;
5665    md->match_call_count = 0;    md->match_call_count = 0;
5666    rc = match(start_match, md->start_code, start_match, 2, md, ims, NULL, 0, 0);    rc = match(start_match, md->start_code, start_match, NULL, 2, md, ims, NULL,
5667    if (md->hitend && start_partial == NULL) start_partial = start_match;      0, 0);
5668      if (md->hitend && start_partial == NULL) start_partial = md->start_used_ptr;
5669    
5670    switch(rc)    switch(rc)
5671      {      {
# Line 5288  for(;;) Line 5695  for(;;)
5695      rc = MATCH_NOMATCH;      rc = MATCH_NOMATCH;
5696      goto ENDLOOP;      goto ENDLOOP;
5697    
5698      /* Any other return is some kind of error. */      /* Any other return is either a match, or some kind of error. */
5699    
5700      default:      default:
5701      goto ENDLOOP;      goto ENDLOOP;
# Line 5394  if (using_temporary_offsets) Line 5801  if (using_temporary_offsets)
5801    (pcre_free)(md->offset_vector);    (pcre_free)(md->offset_vector);
5802    }    }
5803    
5804  if (rc != MATCH_NOMATCH)  if (rc != MATCH_NOMATCH && rc != PCRE_ERROR_PARTIAL)
5805    {    {
5806    DPRINTF((">>>> error: returning %d\n", rc));    DPRINTF((">>>> error: returning %d\n", rc));
5807    return rc;    return rc;
5808    }    }
5809  else if (md->partial && start_partial != NULL)  else if (start_partial != NULL)
5810    {    {
5811    DPRINTF((">>>> returning PCRE_ERROR_PARTIAL\n"));    DPRINTF((">>>> returning PCRE_ERROR_PARTIAL\n"));
5812    if (offsetcount > 1)    if (offsetcount > 1)
5813      {      {
5814      offsets[0] = start_partial - (USPTR)subject;      offsets[0] = start_partial - (USPTR)subject;
5815      offsets[1] = end_subject - (USPTR)subject;      offsets[1] = end_subject - (USPTR)subject;
5816      }      }
5817    return PCRE_ERROR_PARTIAL;    return PCRE_ERROR_PARTIAL;
5818    }    }
5819  else  else

Legend:
Removed from v.426  
changed lines
  Added in v.501

  ViewVC Help
Powered by ViewVC 1.1.5