Diff for /embedaddon/pcre/pcre_exec.c between versions 1.1.1.2 and 1.1.1.3

version 1.1.1.2, 2012/02/21 23:50:25 version 1.1.1.3, 2012/10/09 09:19:17
Line 37  POSSIBILITY OF SUCH DAMAGE. Line 37  POSSIBILITY OF SUCH DAMAGE.
 -----------------------------------------------------------------------------  -----------------------------------------------------------------------------
 */  */
   
   
 /* This module contains pcre_exec(), the externally visible function that does  /* This module contains pcre_exec(), the externally visible function that does
 pattern matching using an NFA algorithm, trying to mimic Perl as closely as  pattern matching using an NFA algorithm, trying to mimic Perl as closely as
 possible. There are also some static supporting functions. */  possible. There are also some static supporting functions. */
Line 140  Arguments: Line 139  Arguments:
   md          points to match data block    md          points to match data block
   caseless    TRUE if caseless    caseless    TRUE if caseless
   
Returns:      < 0 if not matched, otherwise the number of subject bytes matchedReturns:      >= 0 the number of subject bytes matched
               -1 no match
               -2 partial match; always given if at end subject
 */  */
   
 static int  static int
Line 163  pchars(p, length, FALSE, md); Line 164  pchars(p, length, FALSE, md);
 printf("\n");  printf("\n");
 #endif  #endif
   
/* Always fail if reference not set (and not JavaScript compatible). *//* Always fail if reference not set (and not JavaScript compatible - in that
 case the length is passed as zero). */
   
 if (length < 0) return -1;  if (length < 0) return -1;
   
Line 189  if (caseless) Line 191  if (caseless)
     while (p < endptr)      while (p < endptr)
       {        {
       int c, d;        int c, d;
      if (eptr >= md->end_subject) return -1;      if (eptr >= md->end_subject) return -2;   /* Partial match */
       GETCHARINC(c, eptr);        GETCHARINC(c, eptr);
       GETCHARINC(d, p);        GETCHARINC(d, p);
       if (c != d && c != UCD_OTHERCASE(d)) return -1;        if (c != d && c != UCD_OTHERCASE(d)) return -1;
Line 202  if (caseless) Line 204  if (caseless)
   /* The same code works when not in UTF-8 mode and in UTF-8 mode when there    /* The same code works when not in UTF-8 mode and in UTF-8 mode when there
   is no UCP support. */    is no UCP support. */
     {      {
     if (eptr + length > md->end_subject) return -1;  
     while (length-- > 0)      while (length-- > 0)
       {        {
         if (eptr >= md->end_subject) return -2;   /* Partial match */
       if (TABLE_GET(*p, md->lcc, *p) != TABLE_GET(*eptr, md->lcc, *eptr)) return -1;        if (TABLE_GET(*p, md->lcc, *p) != TABLE_GET(*eptr, md->lcc, *eptr)) return -1;
       p++;        p++;
       eptr++;        eptr++;
Line 217  are in UTF-8 mode. */ Line 219  are in UTF-8 mode. */
   
 else  else
   {    {
  if (eptr + length > md->end_subject) return -1;  while (length-- > 0)
  while (length-- > 0) if (*p++ != *eptr++) return -1;    {
     if (eptr >= md->end_subject) return -2;   /* Partial match */
     if (*p++ != *eptr++) return -1;
     }
   }    }
   
 return (int)(eptr - eptr_start);  return (int)(eptr - eptr_start);
Line 311  argument of match(), which never changes. */ Line 316  argument of match(), which never changes. */
   
 #define RMATCH(ra,rb,rc,rd,re,rw)\  #define RMATCH(ra,rb,rc,rd,re,rw)\
   {\    {\
  heapframe *newframe = (heapframe *)(PUBL(stack_malloc))(sizeof(heapframe));\  heapframe *newframe = frame->Xnextframe;\
  if (newframe == NULL) RRETURN(PCRE_ERROR_NOMEMORY);\  if (newframe == NULL)\
  frame->Xwhere = rw; \    {\
     newframe = (heapframe *)(PUBL(stack_malloc))(sizeof(heapframe));\
     if (newframe == NULL) RRETURN(PCRE_ERROR_NOMEMORY);\
     newframe->Xnextframe = NULL;\
     frame->Xnextframe = newframe;\
     }\
   frame->Xwhere = rw;\
   newframe->Xeptr = ra;\    newframe->Xeptr = ra;\
   newframe->Xecode = rb;\    newframe->Xecode = rb;\
   newframe->Xmstart = mstart;\    newframe->Xmstart = mstart;\
Line 332  argument of match(), which never changes. */ Line 343  argument of match(), which never changes. */
   {\    {\
   heapframe *oldframe = frame;\    heapframe *oldframe = frame;\
   frame = oldframe->Xprevframe;\    frame = oldframe->Xprevframe;\
   if (oldframe != &frame_zero) (PUBL(stack_free))(oldframe);\  
   if (frame != NULL)\    if (frame != NULL)\
     {\      {\
     rrc = ra;\      rrc = ra;\
Line 346  argument of match(), which never changes. */ Line 356  argument of match(), which never changes. */
   
 typedef struct heapframe {  typedef struct heapframe {
   struct heapframe *Xprevframe;    struct heapframe *Xprevframe;
     struct heapframe *Xnextframe;
   
   /* Function arguments that may change */    /* Function arguments that may change */
   
Line 492  the top-level on the stack rather than malloc-ing them Line 503  the top-level on the stack rather than malloc-ing them
 boost in many cases where there is not much "recursion". */  boost in many cases where there is not much "recursion". */
   
 #ifdef NO_RECURSE  #ifdef NO_RECURSE
heapframe frame_zero;heapframe *frame = (heapframe *)md->match_frames_base;
heapframe *frame = &frame_zero; 
frame->Xprevframe = NULL;            /* Marks the top level */ 
   
 /* Copy in the original argument variables */  /* Copy in the original argument variables */
   
Line 897  for (;;) Line 906  for (;;)
       }        }
     else  /* OP_KETRMAX */      else  /* OP_KETRMAX */
       {        {
       md->match_function_type = MATCH_CBEGROUP;  
       RMATCH(eptr, prev, offset_top, md, eptrb, RM66);        RMATCH(eptr, prev, offset_top, md, eptrb, RM66);
       if (rrc != MATCH_NOMATCH) RRETURN(rrc);        if (rrc != MATCH_NOMATCH) RRETURN(rrc);
       ecode += 1 + LINK_SIZE;        ecode += 1 + LINK_SIZE;
Line 1026  for (;;) Line 1034  for (;;)
   
     for (;;)      for (;;)
       {        {
      if (op >= OP_SBRA || op == OP_ONCE) md->match_function_type = MATCH_CBEGROUP;      if (op >= OP_SBRA || op == OP_ONCE)
         md->match_function_type = MATCH_CBEGROUP;
   
       /* If this is not a possibly empty group, and there are no (*THEN)s in        /* If this is not a possibly empty group, and there are no (*THEN)s in
       the pattern, and this is the final alternative, optimize as described        the pattern, and this is the final alternative, optimize as described
Line 1565  for (;;) Line 1574  for (;;)
         mstart = md->start_match_ptr;   /* In case \K reset it */          mstart = md->start_match_ptr;   /* In case \K reset it */
         break;          break;
         }          }
         md->mark = save_mark;
   
      /* PCRE does not allow THEN to escape beyond an assertion; it is treated      /* A COMMIT failure must fail the entire assertion, without trying any
      as NOMATCH. */      subsequent branches. */
   
         if (rrc == MATCH_COMMIT) RRETURN(MATCH_NOMATCH);
   
         /* PCRE does not allow THEN to escape beyond an assertion; it
         is treated as NOMATCH. */
   
       if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);        if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);
       ecode += GET(ecode, 1);        ecode += GET(ecode, 1);
       md->mark = save_mark;  
       }        }
     while (*ecode == OP_ALT);      while (*ecode == OP_ALT);
   
Line 1779  for (;;) Line 1793  for (;;)
           goto RECURSION_MATCHED;        /* Exit loop; end processing */            goto RECURSION_MATCHED;        /* Exit loop; end processing */
           }            }
   
        /* PCRE does not allow THEN to escape beyond a recursion; it is treated        /* PCRE does not allow THEN or COMMIT to escape beyond a recursion; it
        as NOMATCH. */        is treated as NOMATCH. */
   
        else if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN)        else if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN &&
                  rrc != MATCH_COMMIT)
           {            {
           DPRINTF(("Recursion gave error %d\n", rrc));            DPRINTF(("Recursion gave error %d\n", rrc));
           if (new_recursive.offset_save != stacksave)            if (new_recursive.offset_save != stacksave)
Line 1993  for (;;) Line 2008  for (;;)
         }          }
       if (*prev >= OP_SBRA)    /* Could match an empty string */        if (*prev >= OP_SBRA)    /* Could match an empty string */
         {          {
         md->match_function_type = MATCH_CBEGROUP;  
         RMATCH(eptr, prev, offset_top, md, eptrb, RM50);          RMATCH(eptr, prev, offset_top, md, eptrb, RM50);
         RRETURN(rrc);          RRETURN(rrc);
         }          }
Line 2002  for (;;) Line 2016  for (;;)
       }        }
     else  /* OP_KETRMAX */      else  /* OP_KETRMAX */
       {        {
       if (*prev >= OP_SBRA) md->match_function_type = MATCH_CBEGROUP;  
       RMATCH(eptr, prev, offset_top, md, eptrb, RM13);        RMATCH(eptr, prev, offset_top, md, eptrb, RM13);
       if (rrc == MATCH_ONCE && md->once_target == prev) rrc = MATCH_NOMATCH;        if (rrc == MATCH_ONCE && md->once_target == prev) rrc = MATCH_NOMATCH;
       if (rrc != MATCH_NOMATCH) RRETURN(rrc);        if (rrc != MATCH_NOMATCH) RRETURN(rrc);
Line 2059  for (;;) Line 2072  for (;;)
   
     case OP_DOLLM:      case OP_DOLLM:
     if (eptr < md->end_subject)      if (eptr < md->end_subject)
      { if (!IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH); }      {
       if (!IS_NEWLINE(eptr))
         {
         if (md->partial != 0 &&
             eptr + 1 >= md->end_subject &&
             NLBLOCK->nltype == NLTYPE_FIXED &&
             NLBLOCK->nllen == 2 &&
             *eptr == NLBLOCK->nl[0])
           {
           md->hitend = TRUE;
           if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
           }
         RRETURN(MATCH_NOMATCH);
         }
       }
     else      else
       {        {
       if (md->noteol) RRETURN(MATCH_NOMATCH);        if (md->noteol) RRETURN(MATCH_NOMATCH);
Line 2091  for (;;) Line 2118  for (;;)
     ASSERT_NL_OR_EOS:      ASSERT_NL_OR_EOS:
     if (eptr < md->end_subject &&      if (eptr < md->end_subject &&
         (!IS_NEWLINE(eptr) || eptr != md->end_subject - md->nllen))          (!IS_NEWLINE(eptr) || eptr != md->end_subject - md->nllen))
         {
         if (md->partial != 0 &&
             eptr + 1 >= md->end_subject &&
             NLBLOCK->nltype == NLTYPE_FIXED &&
             NLBLOCK->nllen == 2 &&
             *eptr == NLBLOCK->nl[0])
           {
           md->hitend = TRUE;
           if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
           }
       RRETURN(MATCH_NOMATCH);        RRETURN(MATCH_NOMATCH);
         }
   
     /* Either at end of string or \n before end. */      /* Either at end of string or \n before end. */
   
Line 2219  for (;;) Line 2257  for (;;)
       }        }
     break;      break;
   
    /* Match a single character type; inline for speed */    /* Match any single character type except newline; have to take care with
     CRLF newlines and partial matching. */
   
     case OP_ANY:      case OP_ANY:
     if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH);      if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH);
       if (md->partial != 0 &&
           eptr + 1 >= md->end_subject &&
           NLBLOCK->nltype == NLTYPE_FIXED &&
           NLBLOCK->nllen == 2 &&
           *eptr == NLBLOCK->nl[0])
         {
         md->hitend = TRUE;
         if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
         }
   
     /* Fall through */      /* Fall through */
   
       /* Match any single character whatsoever. */
   
     case OP_ALLANY:      case OP_ALLANY:
     if (eptr >= md->end_subject)   /* DO NOT merge the eptr++ here; it must */      if (eptr >= md->end_subject)   /* DO NOT merge the eptr++ here; it must */
       {                            /* not be updated before SCHECK_PARTIAL. */        {                            /* not be updated before SCHECK_PARTIAL. */
Line 2365  for (;;) Line 2416  for (;;)
       default: RRETURN(MATCH_NOMATCH);        default: RRETURN(MATCH_NOMATCH);
   
       case 0x000d:        case 0x000d:
      if (eptr < md->end_subject && *eptr == 0x0a) eptr++;      if (eptr >= md->end_subject)
         {
         SCHECK_PARTIAL();
         }
       else if (*eptr == 0x0a) eptr++;
       break;        break;
   
       case 0x000a:        case 0x000a:
Line 2595  for (;;) Line 2650  for (;;)
       if (UCD_CATEGORY(c) != ucp_M) break;        if (UCD_CATEGORY(c) != ucp_M) break;
       eptr += len;        eptr += len;
       }        }
       CHECK_PARTIAL();
     ecode++;      ecode++;
     break;      break;
 #endif  #endif
Line 2660  for (;;) Line 2716  for (;;)
       default:               /* No repeat follows */        default:               /* No repeat follows */
       if ((length = match_ref(offset, eptr, length, md, caseless)) < 0)        if ((length = match_ref(offset, eptr, length, md, caseless)) < 0)
         {          {
           if (length == -2) eptr = md->end_subject;   /* Partial match */
         CHECK_PARTIAL();          CHECK_PARTIAL();
         RRETURN(MATCH_NOMATCH);          RRETURN(MATCH_NOMATCH);
         }          }
Line 2685  for (;;) Line 2742  for (;;)
       int slength;        int slength;
       if ((slength = match_ref(offset, eptr, length, md, caseless)) < 0)        if ((slength = match_ref(offset, eptr, length, md, caseless)) < 0)
         {          {
           if (slength == -2) eptr = md->end_subject;   /* Partial match */
         CHECK_PARTIAL();          CHECK_PARTIAL();
         RRETURN(MATCH_NOMATCH);          RRETURN(MATCH_NOMATCH);
         }          }
Line 2708  for (;;) Line 2766  for (;;)
         if (fi >= max) RRETURN(MATCH_NOMATCH);          if (fi >= max) RRETURN(MATCH_NOMATCH);
         if ((slength = match_ref(offset, eptr, length, md, caseless)) < 0)          if ((slength = match_ref(offset, eptr, length, md, caseless)) < 0)
           {            {
             if (slength == -2) eptr = md->end_subject;   /* Partial match */
           CHECK_PARTIAL();            CHECK_PARTIAL();
           RRETURN(MATCH_NOMATCH);            RRETURN(MATCH_NOMATCH);
           }            }
Line 2726  for (;;) Line 2785  for (;;)
         int slength;          int slength;
         if ((slength = match_ref(offset, eptr, length, md, caseless)) < 0)          if ((slength = match_ref(offset, eptr, length, md, caseless)) < 0)
           {            {
          CHECK_PARTIAL();          /* Can't use CHECK_PARTIAL because we don't want to update eptr in
           the soft partial matching case. */
 
           if (slength == -2 && md->partial != 0 &&
               md->end_subject > md->start_used_ptr)
             {
             md->hitend = TRUE;
             if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
             }
           break;            break;
           }            }
         eptr += slength;          eptr += slength;
         }          }
   
       while (eptr >= pp)        while (eptr >= pp)
         {          {
         RMATCH(eptr, ecode, offset_top, md, eptrb, RM15);          RMATCH(eptr, ecode, offset_top, md, eptrb, RM15);
Line 3360  for (;;) Line 3428  for (;;)
     maximizing, find the maximum number of characters and work backwards. */      maximizing, find the maximum number of characters and work backwards. */
   
     DPRINTF(("matching %c{%d,%d} against subject %.*s\n", fc, min, max,      DPRINTF(("matching %c{%d,%d} against subject %.*s\n", fc, min, max,
      max, eptr));      max, (char *)eptr));
   
     if (op >= OP_STARI)  /* Caseless */      if (op >= OP_STARI)  /* Caseless */
       {        {
Line 3504  for (;;) Line 3572  for (;;)
       SCHECK_PARTIAL();        SCHECK_PARTIAL();
       RRETURN(MATCH_NOMATCH);        RRETURN(MATCH_NOMATCH);
       }        }
    ecode++;#ifdef SUPPORT_UTF
    GETCHARINCTEST(c, eptr);    if (utf)
    if (op == OP_NOTI)         /* The caseless case */ 
       {        {
       register unsigned int ch, och;        register unsigned int ch, och;
      ch = *ecode++;
#ifdef COMPILE_PCRE8      ecode++;
      /* ch must be < 128 if UTF is enabled. */      GETCHARINC(ch, ecode);
      och = md->fcc[ch];      GETCHARINC(c, eptr);
#else
#ifdef SUPPORT_UTF      if (op == OP_NOT)
         {
         if (ch == c) RRETURN(MATCH_NOMATCH);
         }
       else
         {
 #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
      if (utf && ch > 127)        if (ch > 127)
        och = UCD_OTHERCASE(ch);          och = UCD_OTHERCASE(ch);
 #else  #else
      if (utf && ch > 127)        if (ch > 127)
        och = ch;          och = ch;
 #endif /* SUPPORT_UCP */  #endif /* SUPPORT_UCP */
      else        else
#endif /* SUPPORT_UTF */          och = TABLE_GET(ch, md->fcc, ch);
        och = TABLE_GET(ch, md->fcc, ch);        if (ch == c || och == c) RRETURN(MATCH_NOMATCH);
#endif /* COMPILE_PCRE8 */        }
      if (ch == c || och == c) RRETURN(MATCH_NOMATCH); 
       }        }
    else    /* Caseful */    else
 #endif
       {        {
      if (*ecode++ == c) RRETURN(MATCH_NOMATCH);      register unsigned int ch = ecode[1];
       c = *eptr++;
       if (ch == c || (op == OP_NOTI && TABLE_GET(ch, md->fcc, ch) == c))
         RRETURN(MATCH_NOMATCH);
       ecode += 2;
       }        }
     break;      break;
   
Line 3610  for (;;) Line 3686  for (;;)
     /* Common code for all repeated single-byte matches. */      /* Common code for all repeated single-byte matches. */
   
     REPEATNOTCHAR:      REPEATNOTCHAR:
    fc = *ecode++;    GETCHARINCTEST(fc, ecode);
   
     /* The code is duplicated for the caseless and caseful cases, for speed,      /* The code is duplicated for the caseless and caseful cases, for speed,
     since matching characters is likely to be quite common. First, ensure the      since matching characters is likely to be quite common. First, ensure the
Line 3621  for (;;) Line 3697  for (;;)
     characters and work backwards. */      characters and work backwards. */
   
     DPRINTF(("negative matching %c{%d,%d} against subject %.*s\n", fc, min, max,      DPRINTF(("negative matching %c{%d,%d} against subject %.*s\n", fc, min, max,
      max, eptr));      max, (char *)eptr));
   
     if (op >= OP_NOTSTARI)     /* Caseless */      if (op >= OP_NOTSTARI)     /* Caseless */
       {        {
 #ifdef COMPILE_PCRE8  
       /* fc must be < 128 if UTF is enabled. */  
       foc = md->fcc[fc];  
 #else  
 #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
 #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
       if (utf && fc > 127)        if (utf && fc > 127)
Line 3640  for (;;) Line 3712  for (;;)
       else        else
 #endif /* SUPPORT_UTF */  #endif /* SUPPORT_UTF */
         foc = TABLE_GET(fc, md->fcc, fc);          foc = TABLE_GET(fc, md->fcc, fc);
 #endif /* COMPILE_PCRE8 */  
   
 #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
       if (utf)        if (utf)
Line 3654  for (;;) Line 3725  for (;;)
             RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
             }              }
           GETCHARINC(d, eptr);            GETCHARINC(d, eptr);
          if (fc == d || (unsigned int) foc == d) RRETURN(MATCH_NOMATCH);          if (fc == d || (unsigned int)foc == d) RRETURN(MATCH_NOMATCH);
           }            }
         }          }
       else        else
Line 4164  for (;;) Line 4235  for (;;)
             if (UCD_CATEGORY(c) != ucp_M) break;              if (UCD_CATEGORY(c) != ucp_M) break;
             eptr += len;              eptr += len;
             }              }
             CHECK_PARTIAL();
           }            }
         }          }
   
Line 4184  for (;;) Line 4256  for (;;)
             RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
             }              }
           if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH);            if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH);
             if (md->partial != 0 &&
                 eptr + 1 >= md->end_subject &&
                 NLBLOCK->nltype == NLTYPE_FIXED &&
                 NLBLOCK->nllen == 2 &&
                 *eptr == NLBLOCK->nl[0])
               {
               md->hitend = TRUE;
               if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
               }
           eptr++;            eptr++;
           ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);            ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
           }            }
Line 4468  for (;;) Line 4549  for (;;)
             RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
             }              }
           if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH);            if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH);
             if (md->partial != 0 &&
                 eptr + 1 >= md->end_subject &&
                 NLBLOCK->nltype == NLTYPE_FIXED &&
                 NLBLOCK->nllen == 2 &&
                 *eptr == NLBLOCK->nl[0])
               {
               md->hitend = TRUE;
               if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
               }
           eptr++;            eptr++;
           }            }
         break;          break;
Line 4948  for (;;) Line 5038  for (;;)
             if (UCD_CATEGORY(c) != ucp_M) break;              if (UCD_CATEGORY(c) != ucp_M) break;
             eptr += len;              eptr += len;
             }              }
             CHECK_PARTIAL();
           }            }
         }          }
       else        else
Line 4971  for (;;) Line 5062  for (;;)
           GETCHARINC(c, eptr);            GETCHARINC(c, eptr);
           switch(ctype)            switch(ctype)
             {              {
            case OP_ANY:        /* This is the non-NL case */            case OP_ANY:               /* This is the non-NL case */
             if (md->partial != 0 &&    /* Take care with CRLF partial */
                 eptr >= md->end_subject &&
                 NLBLOCK->nltype == NLTYPE_FIXED &&
                 NLBLOCK->nllen == 2 &&
                 c == NLBLOCK->nl[0])
               {
               md->hitend = TRUE;
               if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
               }
             break;
 
             case OP_ALLANY:              case OP_ALLANY:
             case OP_ANYBYTE:              case OP_ANYBYTE:
             break;              break;
Line 5134  for (;;) Line 5236  for (;;)
           c = *eptr++;            c = *eptr++;
           switch(ctype)            switch(ctype)
             {              {
            case OP_ANY:     /* This is the non-NL case */            case OP_ANY:               /* This is the non-NL case */
             if (md->partial != 0 &&    /* Take care with CRLF partial */
                 eptr >= md->end_subject &&
                 NLBLOCK->nltype == NLTYPE_FIXED &&
                 NLBLOCK->nllen == 2 &&
                 c == NLBLOCK->nl[0])
               {
               md->hitend = TRUE;
               if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
               }
             break;
 
             case OP_ALLANY:              case OP_ALLANY:
             case OP_ANYBYTE:              case OP_ANYBYTE:
             break;              break;
Line 5491  for (;;) Line 5604  for (;;)
             if (UCD_CATEGORY(c) != ucp_M) break;              if (UCD_CATEGORY(c) != ucp_M) break;
             eptr += len;              eptr += len;
             }              }
             CHECK_PARTIAL();
           }            }
   
         /* eptr is now past the end of the maximum run */          /* eptr is now past the end of the maximum run */
Line 5534  for (;;) Line 5648  for (;;)
                 break;                  break;
                 }                  }
               if (IS_NEWLINE(eptr)) break;                if (IS_NEWLINE(eptr)) break;
                 if (md->partial != 0 &&    /* Take care with CRLF partial */
                     eptr + 1 >= md->end_subject &&
                     NLBLOCK->nltype == NLTYPE_FIXED &&
                     NLBLOCK->nllen == 2 &&
                     *eptr == NLBLOCK->nl[0])
                   {
                   md->hitend = TRUE;
                   if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
                   }
               eptr++;                eptr++;
               ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);                ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
               }                }
Line 5551  for (;;) Line 5674  for (;;)
                 break;                  break;
                 }                  }
               if (IS_NEWLINE(eptr)) break;                if (IS_NEWLINE(eptr)) break;
                 if (md->partial != 0 &&    /* Take care with CRLF partial */
                     eptr + 1 >= md->end_subject &&
                     NLBLOCK->nltype == NLTYPE_FIXED &&
                     NLBLOCK->nllen == 2 &&
                     *eptr == NLBLOCK->nl[0])
                   {
                   md->hitend = TRUE;
                   if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
                   }
               eptr++;                eptr++;
               ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);                ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
               }                }
Line 5815  for (;;) Line 5947  for (;;)
               break;                break;
               }                }
             if (IS_NEWLINE(eptr)) break;              if (IS_NEWLINE(eptr)) break;
               if (md->partial != 0 &&    /* Take care with CRLF partial */
                   eptr + 1 >= md->end_subject &&
                   NLBLOCK->nltype == NLTYPE_FIXED &&
                   NLBLOCK->nllen == 2 &&
                   *eptr == NLBLOCK->nl[0])
                 {
                 md->hitend = TRUE;
                 if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
                 }
             eptr++;              eptr++;
             }              }
           break;            break;
Line 6145  Undefine all the macros that were defined above to han Line 6286  Undefine all the macros that were defined above to han
 ***************************************************************************/  ***************************************************************************/
   
   
   #ifdef NO_RECURSE
   /*************************************************
   *          Release allocated heap frames         *
   *************************************************/
   
   /* This function releases all the allocated frames. The base frame is on the
   machine stack, and so must not be freed.
   
   Argument: the address of the base frame
   Returns:  nothing
   */
   
   static void
   release_match_heapframes (heapframe *frame_base)
   {
   heapframe *nextframe = frame_base->Xnextframe;
   while (nextframe != NULL)
     {
     heapframe *oldframe = nextframe;
     nextframe = nextframe->Xnextframe;
     (PUBL(stack_free))(oldframe);
     }
   }
   #endif
   
   
 /*************************************************  /*************************************************
 *         Execute a Regular Expression           *  *         Execute a Regular Expression           *
 *************************************************/  *************************************************/
Line 6207  PCRE_PUCHAR req_char_ptr = start_match - 1; Line 6373  PCRE_PUCHAR req_char_ptr = start_match - 1;
 const pcre_study_data *study;  const pcre_study_data *study;
 const REAL_PCRE *re = (const REAL_PCRE *)argument_re;  const REAL_PCRE *re = (const REAL_PCRE *)argument_re;
   
   #ifdef NO_RECURSE
   heapframe frame_zero;
   frame_zero.Xprevframe = NULL;            /* Marks the top level */
   frame_zero.Xnextframe = NULL;            /* None are allocated yet */
   md->match_frames_base = &frame_zero;
   #endif
   
 /* Check for the special magic call that measures the size of the stack used  /* Check for the special magic call that measures the size of the stack used
per recursive call of match(). */per recursive call of match(). Without the funny casting for sizeof, a Windows
 compiler gave this error: "unary minus operator applied to unsigned type,
 result still unsigned". Hopefully the cast fixes that. */
   
 if (re == NULL && extra_data == NULL && subject == NULL && length == -999 &&  if (re == NULL && extra_data == NULL && subject == NULL && length == -999 &&
     start_offset == -999)      start_offset == -999)
 #ifdef NO_RECURSE  #ifdef NO_RECURSE
  return -sizeof(heapframe);  return -((int)sizeof(heapframe));
 #else  #else
   return match(NULL, NULL, NULL, 0, NULL, NULL, 0);    return match(NULL, NULL, NULL, 0, NULL, NULL, 0);
 #endif  #endif
Line 6280  if (utf && (options & PCRE_NO_UTF8_CHECK) == 0) Line 6455  if (utf && (options & PCRE_NO_UTF8_CHECK) == 0)
 /* If the pattern was successfully studied with JIT support, run the JIT  /* If the pattern was successfully studied with JIT support, run the JIT
 executable instead of the rest of this function. Most options must be set at  executable instead of the rest of this function. Most options must be set at
 compile time for the JIT code to be usable. Fallback to the normal code path if  compile time for the JIT code to be usable. Fallback to the normal code path if
an unsupported flag is set. In particular, JIT does not support partialan unsupported flag is set. */
matching. */ 
   
 #ifdef SUPPORT_JIT  #ifdef SUPPORT_JIT
 if (extra_data != NULL  if (extra_data != NULL
    && (extra_data->flags & PCRE_EXTRA_EXECUTABLE_JIT) != 0    && (extra_data->flags & (PCRE_EXTRA_EXECUTABLE_JIT |
                              PCRE_EXTRA_TABLES)) == PCRE_EXTRA_EXECUTABLE_JIT
     && extra_data->executable_jit != NULL      && extra_data->executable_jit != NULL
     && (extra_data->flags & PCRE_EXTRA_TABLES) == 0  
     && (options & ~(PCRE_NO_UTF8_CHECK | PCRE_NOTBOL | PCRE_NOTEOL |      && (options & ~(PCRE_NO_UTF8_CHECK | PCRE_NOTBOL | PCRE_NOTEOL |
                    PCRE_NOTEMPTY | PCRE_NOTEMPTY_ATSTART)) == 0)                    PCRE_NOTEMPTY | PCRE_NOTEMPTY_ATSTART |
  return PRIV(jit_exec)(re, extra_data->executable_jit,                    PCRE_PARTIAL_SOFT | PCRE_PARTIAL_HARD)) == 0)
    (const pcre_uchar *)subject, length, start_offset, options,  {
    ((extra_data->flags & PCRE_EXTRA_MATCH_LIMIT) == 0)  rc = PRIV(jit_exec)(re, extra_data, (const pcre_uchar *)subject, length,
    ? MATCH_LIMIT : extra_data->match_limit, offsets, offsetcount);       start_offset, options, offsets, offsetcount);
 
   /* PCRE_ERROR_NULL means that the selected normal or partial matching
   mode is not compiled. In this case we simply fallback to interpreter. */
 
   if (rc != PCRE_ERROR_NULL) return rc;
   }
 #endif  #endif
   
 /* Carry on with non-JIT matching. This information is for finding all the  /* Carry on with non-JIT matching. This information is for finding all the
Line 6887  if (rc == MATCH_MATCH || rc == MATCH_ACCEPT) Line 7067  if (rc == MATCH_MATCH || rc == MATCH_ACCEPT)
     {      {
     register int *iptr, *iend;      register int *iptr, *iend;
     int resetcount = 2 + re->top_bracket * 2;      int resetcount = 2 + re->top_bracket * 2;
    if (resetcount > offsetcount) resetcount = ocount;    if (resetcount > offsetcount) resetcount = offsetcount;
     iptr = offsets + md->end_offset_top;      iptr = offsets + md->end_offset_top;
     iend = offsets + resetcount;      iend = offsets + resetcount;
     while (iptr < iend) *iptr++ = -1;      while (iptr < iend) *iptr++ = -1;
Line 6908  if (rc == MATCH_MATCH || rc == MATCH_ACCEPT) Line 7088  if (rc == MATCH_MATCH || rc == MATCH_ACCEPT)
   if (extra_data != NULL && (extra_data->flags & PCRE_EXTRA_MARK) != 0)    if (extra_data != NULL && (extra_data->flags & PCRE_EXTRA_MARK) != 0)
     *(extra_data->mark) = (pcre_uchar *)md->mark;      *(extra_data->mark) = (pcre_uchar *)md->mark;
   DPRINTF((">>>> returning %d\n", rc));    DPRINTF((">>>> returning %d\n", rc));
   #ifdef NO_RECURSE
     release_match_heapframes(&frame_zero);
   #endif
   return rc;    return rc;
   }    }
   
Line 6925  if (using_temporary_offsets) Line 7108  if (using_temporary_offsets)
 if (rc != MATCH_NOMATCH && rc != PCRE_ERROR_PARTIAL)  if (rc != MATCH_NOMATCH && rc != PCRE_ERROR_PARTIAL)
   {    {
   DPRINTF((">>>> error: returning %d\n", rc));    DPRINTF((">>>> error: returning %d\n", rc));
   #ifdef NO_RECURSE
     release_match_heapframes(&frame_zero);
   #endif
   return rc;    return rc;
   }    }
   
Line 6954  else Line 7140  else
   
 if (extra_data != NULL && (extra_data->flags & PCRE_EXTRA_MARK) != 0)  if (extra_data != NULL && (extra_data->flags & PCRE_EXTRA_MARK) != 0)
   *(extra_data->mark) = (pcre_uchar *)md->nomatch_mark;    *(extra_data->mark) = (pcre_uchar *)md->nomatch_mark;
   #ifdef NO_RECURSE
     release_match_heapframes(&frame_zero);
   #endif
 return rc;  return rc;
 }  }
   

Removed from v.1.1.1.2  
changed lines
  Added in v.1.1.1.3


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>