/[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 904 by ph10, Mon Jan 23 17:30:49 2012 UTC revision 976 by ph10, Sat Jun 16 17:53:17 2012 UTC
# Line 37  POSSIBILITY OF SUCH DAMAGE. Line 37  POSSIBILITY OF SUCH DAMAGE.
37  -----------------------------------------------------------------------------  -----------------------------------------------------------------------------
38  */  */
39    
   
40  /* This module contains pcre_exec(), the externally visible function that does  /* This module contains pcre_exec(), the externally visible function that does
41  pattern matching using an NFA algorithm, trying to mimic Perl as closely as  pattern matching using an NFA algorithm, trying to mimic Perl as closely as
42  possible. There are also some static supporting functions. */  possible. There are also some static supporting functions. */
# Line 140  Arguments: Line 139  Arguments:
139    md          points to match data block    md          points to match data block
140    caseless    TRUE if caseless    caseless    TRUE if caseless
141    
142  Returns:      < 0 if not matched, otherwise the number of subject bytes matched  Returns:      >= 0 the number of subject bytes matched
143                  -1 no match
144                  -2 partial match; always given if at end subject
145  */  */
146    
147  static int  static int
# Line 163  pchars(p, length, FALSE, md); Line 164  pchars(p, length, FALSE, md);
164  printf("\n");  printf("\n");
165  #endif  #endif
166    
167  /* Always fail if reference not set (and not JavaScript compatible). */  /* Always fail if reference not set (and not JavaScript compatible - in that
168    case the length is passed as zero). */
169    
170  if (length < 0) return -1;  if (length < 0) return -1;
171    
# Line 189  if (caseless) Line 191  if (caseless)
191      while (p < endptr)      while (p < endptr)
192        {        {
193        int c, d;        int c, d;
194        if (eptr >= md->end_subject) return -1;        if (eptr >= md->end_subject) return -2;   /* Partial match */
195        GETCHARINC(c, eptr);        GETCHARINC(c, eptr);
196        GETCHARINC(d, p);        GETCHARINC(d, p);
197        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)
204    /* 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
205    is no UCP support. */    is no UCP support. */
206      {      {
     if (eptr + length > md->end_subject) return -1;  
207      while (length-- > 0)      while (length-- > 0)
208        {        {
209          if (eptr >= md->end_subject) return -2;   /* Partial match */
210        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;
211        p++;        p++;
212        eptr++;        eptr++;
# Line 217  are in UTF-8 mode. */ Line 219  are in UTF-8 mode. */
219    
220  else  else
221    {    {
222    if (eptr + length > md->end_subject) return -1;    while (length-- > 0)
223    while (length-- > 0) if (*p++ != *eptr++) return -1;      {
224        if (eptr >= md->end_subject) return -2;   /* Partial match */
225        if (*p++ != *eptr++) return -1;
226        }
227    }    }
228    
229  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
316    
317  #define RMATCH(ra,rb,rc,rd,re,rw)\  #define RMATCH(ra,rb,rc,rd,re,rw)\
318    {\    {\
319    heapframe *newframe = (heapframe *)(PUBL(stack_malloc))(sizeof(heapframe));\    heapframe *newframe = frame->Xnextframe;\
320    if (newframe == NULL) RRETURN(PCRE_ERROR_NOMEMORY);\    if (newframe == NULL)\
321    frame->Xwhere = rw; \      {\
322        newframe = (heapframe *)(PUBL(stack_malloc))(sizeof(heapframe));\
323        if (newframe == NULL) RRETURN(PCRE_ERROR_NOMEMORY);\
324        newframe->Xnextframe = NULL;\
325        frame->Xnextframe = newframe;\
326        }\
327      frame->Xwhere = rw;\
328    newframe->Xeptr = ra;\    newframe->Xeptr = ra;\
329    newframe->Xecode = rb;\    newframe->Xecode = rb;\
330    newframe->Xmstart = mstart;\    newframe->Xmstart = mstart;\
# Line 332  argument of match(), which never changes Line 343  argument of match(), which never changes
343    {\    {\
344    heapframe *oldframe = frame;\    heapframe *oldframe = frame;\
345    frame = oldframe->Xprevframe;\    frame = oldframe->Xprevframe;\
   if (oldframe != &frame_zero) (PUBL(stack_free))(oldframe);\  
346    if (frame != NULL)\    if (frame != NULL)\
347      {\      {\
348      rrc = ra;\      rrc = ra;\
# Line 346  argument of match(), which never changes Line 356  argument of match(), which never changes
356    
357  typedef struct heapframe {  typedef struct heapframe {
358    struct heapframe *Xprevframe;    struct heapframe *Xprevframe;
359      struct heapframe *Xnextframe;
360    
361    /* Function arguments that may change */    /* Function arguments that may change */
362    
# Line 492  the top-level on the stack rather than m Line 503  the top-level on the stack rather than m
503  boost in many cases where there is not much "recursion". */  boost in many cases where there is not much "recursion". */
504    
505  #ifdef NO_RECURSE  #ifdef NO_RECURSE
506  heapframe frame_zero;  heapframe *frame = (heapframe *)md->match_frames_base;
 heapframe *frame = &frame_zero;  
 frame->Xprevframe = NULL;            /* Marks the top level */  
507    
508  /* Copy in the original argument variables */  /* Copy in the original argument variables */
509    
# Line 897  for (;;) Line 906  for (;;)
906        }        }
907      else  /* OP_KETRMAX */      else  /* OP_KETRMAX */
908        {        {
       md->match_function_type = MATCH_CBEGROUP;  
909        RMATCH(eptr, prev, offset_top, md, eptrb, RM66);        RMATCH(eptr, prev, offset_top, md, eptrb, RM66);
910        if (rrc != MATCH_NOMATCH) RRETURN(rrc);        if (rrc != MATCH_NOMATCH) RRETURN(rrc);
911        ecode += 1 + LINK_SIZE;        ecode += 1 + LINK_SIZE;
# Line 1026  for (;;) Line 1034  for (;;)
1034    
1035      for (;;)      for (;;)
1036        {        {
1037        if (op >= OP_SBRA || op == OP_ONCE) md->match_function_type = MATCH_CBEGROUP;        if (op >= OP_SBRA || op == OP_ONCE)
1038            md->match_function_type = MATCH_CBEGROUP;
1039    
1040        /* 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
1041        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 (;;)
1574          mstart = md->start_match_ptr;   /* In case \K reset it */          mstart = md->start_match_ptr;   /* In case \K reset it */
1575          break;          break;
1576          }          }
1577          md->mark = save_mark;
1578    
1579        /* PCRE does not allow THEN to escape beyond an assertion; it is treated        /* A COMMIT failure must fail the entire assertion, without trying any
1580        as NOMATCH. */        subsequent branches. */
1581    
1582          if (rrc == MATCH_COMMIT) RRETURN(MATCH_NOMATCH);
1583    
1584          /* PCRE does not allow THEN to escape beyond an assertion; it
1585          is treated as NOMATCH. */
1586    
1587        if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);        if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);
1588        ecode += GET(ecode, 1);        ecode += GET(ecode, 1);
       md->mark = save_mark;  
1589        }        }
1590      while (*ecode == OP_ALT);      while (*ecode == OP_ALT);
1591    
# Line 1779  for (;;) Line 1793  for (;;)
1793            goto RECURSION_MATCHED;        /* Exit loop; end processing */            goto RECURSION_MATCHED;        /* Exit loop; end processing */
1794            }            }
1795    
1796          /* 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
1797          as NOMATCH. */          is treated as NOMATCH. */
1798    
1799          else if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN)          else if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN &&
1800                     rrc != MATCH_COMMIT)
1801            {            {
1802            DPRINTF(("Recursion gave error %d\n", rrc));            DPRINTF(("Recursion gave error %d\n", rrc));
1803            if (new_recursive.offset_save != stacksave)            if (new_recursive.offset_save != stacksave)
# Line 1993  for (;;) Line 2008  for (;;)
2008          }          }
2009        if (*prev >= OP_SBRA)    /* Could match an empty string */        if (*prev >= OP_SBRA)    /* Could match an empty string */
2010          {          {
         md->match_function_type = MATCH_CBEGROUP;  
2011          RMATCH(eptr, prev, offset_top, md, eptrb, RM50);          RMATCH(eptr, prev, offset_top, md, eptrb, RM50);
2012          RRETURN(rrc);          RRETURN(rrc);
2013          }          }
# Line 2002  for (;;) Line 2016  for (;;)
2016        }        }
2017      else  /* OP_KETRMAX */      else  /* OP_KETRMAX */
2018        {        {
       if (*prev >= OP_SBRA) md->match_function_type = MATCH_CBEGROUP;  
2019        RMATCH(eptr, prev, offset_top, md, eptrb, RM13);        RMATCH(eptr, prev, offset_top, md, eptrb, RM13);
2020        if (rrc == MATCH_ONCE && md->once_target == prev) rrc = MATCH_NOMATCH;        if (rrc == MATCH_ONCE && md->once_target == prev) rrc = MATCH_NOMATCH;
2021        if (rrc != MATCH_NOMATCH) RRETURN(rrc);        if (rrc != MATCH_NOMATCH) RRETURN(rrc);
# Line 2059  for (;;) Line 2072  for (;;)
2072    
2073      case OP_DOLLM:      case OP_DOLLM:
2074      if (eptr < md->end_subject)      if (eptr < md->end_subject)
2075        { if (!IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH); }        {
2076          if (!IS_NEWLINE(eptr))
2077            {
2078            if (md->partial != 0 &&
2079                eptr + 1 >= md->end_subject &&
2080                NLBLOCK->nltype == NLTYPE_FIXED &&
2081                NLBLOCK->nllen == 2 &&
2082                *eptr == NLBLOCK->nl[0])
2083              {
2084              md->hitend = TRUE;
2085              if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
2086              }
2087            RRETURN(MATCH_NOMATCH);
2088            }
2089          }
2090      else      else
2091        {        {
2092        if (md->noteol) RRETURN(MATCH_NOMATCH);        if (md->noteol) RRETURN(MATCH_NOMATCH);
# Line 2091  for (;;) Line 2118  for (;;)
2118      ASSERT_NL_OR_EOS:      ASSERT_NL_OR_EOS:
2119      if (eptr < md->end_subject &&      if (eptr < md->end_subject &&
2120          (!IS_NEWLINE(eptr) || eptr != md->end_subject - md->nllen))          (!IS_NEWLINE(eptr) || eptr != md->end_subject - md->nllen))
2121          {
2122          if (md->partial != 0 &&
2123              eptr + 1 >= md->end_subject &&
2124              NLBLOCK->nltype == NLTYPE_FIXED &&
2125              NLBLOCK->nllen == 2 &&
2126              *eptr == NLBLOCK->nl[0])
2127            {
2128            md->hitend = TRUE;
2129            if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
2130            }
2131        RRETURN(MATCH_NOMATCH);        RRETURN(MATCH_NOMATCH);
2132          }
2133    
2134      /* Either at end of string or \n before end. */      /* Either at end of string or \n before end. */
2135    
# Line 2219  for (;;) Line 2257  for (;;)
2257        }        }
2258      break;      break;
2259    
2260      /* Match a single character type; inline for speed */      /* Match any single character type except newline; have to take care with
2261        CRLF newlines and partial matching. */
2262    
2263      case OP_ANY:      case OP_ANY:
2264      if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH);      if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH);
2265        if (md->partial != 0 &&
2266            eptr + 1 >= md->end_subject &&
2267            NLBLOCK->nltype == NLTYPE_FIXED &&
2268            NLBLOCK->nllen == 2 &&
2269            *eptr == NLBLOCK->nl[0])
2270          {
2271          md->hitend = TRUE;
2272          if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
2273          }
2274    
2275      /* Fall through */      /* Fall through */
2276    
2277        /* Match any single character whatsoever. */
2278    
2279      case OP_ALLANY:      case OP_ALLANY:
2280      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 */
2281        {                            /* not be updated before SCHECK_PARTIAL. */        {                            /* not be updated before SCHECK_PARTIAL. */
# Line 2365  for (;;) Line 2416  for (;;)
2416        default: RRETURN(MATCH_NOMATCH);        default: RRETURN(MATCH_NOMATCH);
2417    
2418        case 0x000d:        case 0x000d:
2419        if (eptr < md->end_subject && *eptr == 0x0a) eptr++;        if (eptr >= md->end_subject)
2420            {
2421            SCHECK_PARTIAL();
2422            }
2423          else if (*eptr == 0x0a) eptr++;
2424        break;        break;
2425    
2426        case 0x000a:        case 0x000a:
# Line 2595  for (;;) Line 2650  for (;;)
2650        if (UCD_CATEGORY(c) != ucp_M) break;        if (UCD_CATEGORY(c) != ucp_M) break;
2651        eptr += len;        eptr += len;
2652        }        }
2653        CHECK_PARTIAL();
2654      ecode++;      ecode++;
2655      break;      break;
2656  #endif  #endif
# Line 2660  for (;;) Line 2716  for (;;)
2716        default:               /* No repeat follows */        default:               /* No repeat follows */
2717        if ((length = match_ref(offset, eptr, length, md, caseless)) < 0)        if ((length = match_ref(offset, eptr, length, md, caseless)) < 0)
2718          {          {
2719            if (length == -2) eptr = md->end_subject;   /* Partial match */
2720          CHECK_PARTIAL();          CHECK_PARTIAL();
2721          RRETURN(MATCH_NOMATCH);          RRETURN(MATCH_NOMATCH);
2722          }          }
# Line 2685  for (;;) Line 2742  for (;;)
2742        int slength;        int slength;
2743        if ((slength = match_ref(offset, eptr, length, md, caseless)) < 0)        if ((slength = match_ref(offset, eptr, length, md, caseless)) < 0)
2744          {          {
2745            if (slength == -2) eptr = md->end_subject;   /* Partial match */
2746          CHECK_PARTIAL();          CHECK_PARTIAL();
2747          RRETURN(MATCH_NOMATCH);          RRETURN(MATCH_NOMATCH);
2748          }          }
# Line 2708  for (;;) Line 2766  for (;;)
2766          if (fi >= max) RRETURN(MATCH_NOMATCH);          if (fi >= max) RRETURN(MATCH_NOMATCH);
2767          if ((slength = match_ref(offset, eptr, length, md, caseless)) < 0)          if ((slength = match_ref(offset, eptr, length, md, caseless)) < 0)
2768            {            {
2769              if (slength == -2) eptr = md->end_subject;   /* Partial match */
2770            CHECK_PARTIAL();            CHECK_PARTIAL();
2771            RRETURN(MATCH_NOMATCH);            RRETURN(MATCH_NOMATCH);
2772            }            }
# Line 2726  for (;;) Line 2785  for (;;)
2785          int slength;          int slength;
2786          if ((slength = match_ref(offset, eptr, length, md, caseless)) < 0)          if ((slength = match_ref(offset, eptr, length, md, caseless)) < 0)
2787            {            {
2788            CHECK_PARTIAL();            /* Can't use CHECK_PARTIAL because we don't want to update eptr in
2789              the soft partial matching case. */
2790    
2791              if (slength == -2 && md->partial != 0 &&
2792                  md->end_subject > md->start_used_ptr)
2793                {
2794                md->hitend = TRUE;
2795                if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
2796                }
2797            break;            break;
2798            }            }
2799          eptr += slength;          eptr += slength;
2800          }          }
2801    
2802        while (eptr >= pp)        while (eptr >= pp)
2803          {          {
2804          RMATCH(eptr, ecode, offset_top, md, eptrb, RM15);          RMATCH(eptr, ecode, offset_top, md, eptrb, RM15);
# Line 3360  for (;;) Line 3428  for (;;)
3428      maximizing, find the maximum number of characters and work backwards. */      maximizing, find the maximum number of characters and work backwards. */
3429    
3430      DPRINTF(("matching %c{%d,%d} against subject %.*s\n", fc, min, max,      DPRINTF(("matching %c{%d,%d} against subject %.*s\n", fc, min, max,
3431        max, eptr));        max, (char *)eptr));
3432    
3433      if (op >= OP_STARI)  /* Caseless */      if (op >= OP_STARI)  /* Caseless */
3434        {        {
# Line 3504  for (;;) Line 3572  for (;;)
3572        SCHECK_PARTIAL();        SCHECK_PARTIAL();
3573        RRETURN(MATCH_NOMATCH);        RRETURN(MATCH_NOMATCH);
3574        }        }
3575      ecode++;  #ifdef SUPPORT_UTF
3576      GETCHARINCTEST(c, eptr);      if (utf)
     if (op == OP_NOTI)         /* The caseless case */  
3577        {        {
3578        register unsigned int ch, och;        register unsigned int ch, och;
3579        ch = *ecode++;  
3580  #ifdef COMPILE_PCRE8        ecode++;
3581        /* ch must be < 128 if UTF is enabled. */        GETCHARINC(ch, ecode);
3582        och = md->fcc[ch];        GETCHARINC(c, eptr);
3583  #else  
3584  #ifdef SUPPORT_UTF        if (op == OP_NOT)
3585            {
3586            if (ch == c) RRETURN(MATCH_NOMATCH);
3587            }
3588          else
3589            {
3590  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3591        if (utf && ch > 127)          if (ch > 127)
3592          och = UCD_OTHERCASE(ch);            och = UCD_OTHERCASE(ch);
3593  #else  #else
3594        if (utf && ch > 127)          if (ch > 127)
3595          och = ch;            och = ch;
3596  #endif /* SUPPORT_UCP */  #endif /* SUPPORT_UCP */
3597        else          else
3598  #endif /* SUPPORT_UTF */            och = TABLE_GET(ch, md->fcc, ch);
3599          och = TABLE_GET(ch, md->fcc, ch);          if (ch == c || och == c) RRETURN(MATCH_NOMATCH);
3600  #endif /* COMPILE_PCRE8 */          }
       if (ch == c || och == c) RRETURN(MATCH_NOMATCH);  
3601        }        }
3602      else    /* Caseful */      else
3603    #endif
3604        {        {
3605        if (*ecode++ == c) RRETURN(MATCH_NOMATCH);        register unsigned int ch = ecode[1];
3606          c = *eptr++;
3607          if (ch == c || (op == OP_NOTI && TABLE_GET(ch, md->fcc, ch) == c))
3608            RRETURN(MATCH_NOMATCH);
3609          ecode += 2;
3610        }        }
3611      break;      break;
3612    
# Line 3610  for (;;) Line 3686  for (;;)
3686      /* Common code for all repeated single-byte matches. */      /* Common code for all repeated single-byte matches. */
3687    
3688      REPEATNOTCHAR:      REPEATNOTCHAR:
3689      fc = *ecode++;      GETCHARINCTEST(fc, ecode);
3690    
3691      /* The code is duplicated for the caseless and caseful cases, for speed,      /* The code is duplicated for the caseless and caseful cases, for speed,
3692      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 (;;)
3697      characters and work backwards. */      characters and work backwards. */
3698    
3699      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,
3700        max, eptr));        max, (char *)eptr));
3701    
3702      if (op >= OP_NOTSTARI)     /* Caseless */      if (op >= OP_NOTSTARI)     /* Caseless */
3703        {        {
 #ifdef COMPILE_PCRE8  
       /* fc must be < 128 if UTF is enabled. */  
       foc = md->fcc[fc];  
 #else  
3704  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
3705  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3706        if (utf && fc > 127)        if (utf && fc > 127)
# Line 3640  for (;;) Line 3712  for (;;)
3712        else        else
3713  #endif /* SUPPORT_UTF */  #endif /* SUPPORT_UTF */
3714          foc = TABLE_GET(fc, md->fcc, fc);          foc = TABLE_GET(fc, md->fcc, fc);
 #endif /* COMPILE_PCRE8 */  
3715    
3716  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
3717        if (utf)        if (utf)
# Line 3654  for (;;) Line 3725  for (;;)
3725              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
3726              }              }
3727            GETCHARINC(d, eptr);            GETCHARINC(d, eptr);
3728            if (fc == d || (unsigned int) foc == d) RRETURN(MATCH_NOMATCH);            if (fc == d || (unsigned int)foc == d) RRETURN(MATCH_NOMATCH);
3729            }            }
3730          }          }
3731        else        else
# Line 4164  for (;;) Line 4235  for (;;)
4235              if (UCD_CATEGORY(c) != ucp_M) break;              if (UCD_CATEGORY(c) != ucp_M) break;
4236              eptr += len;              eptr += len;
4237              }              }
4238              CHECK_PARTIAL();
4239            }            }
4240          }          }
4241    
# Line 4184  for (;;) Line 4256  for (;;)
4256              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4257              }              }
4258            if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH);            if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH);
4259              if (md->partial != 0 &&
4260                  eptr + 1 >= md->end_subject &&
4261                  NLBLOCK->nltype == NLTYPE_FIXED &&
4262                  NLBLOCK->nllen == 2 &&
4263                  *eptr == NLBLOCK->nl[0])
4264                {
4265                md->hitend = TRUE;
4266                if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
4267                }
4268            eptr++;            eptr++;
4269            ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);            ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
4270            }            }
# Line 4468  for (;;) Line 4549  for (;;)
4549              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4550              }              }
4551            if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH);            if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH);
4552              if (md->partial != 0 &&
4553                  eptr + 1 >= md->end_subject &&
4554                  NLBLOCK->nltype == NLTYPE_FIXED &&
4555                  NLBLOCK->nllen == 2 &&
4556                  *eptr == NLBLOCK->nl[0])
4557                {
4558                md->hitend = TRUE;
4559                if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
4560                }
4561            eptr++;            eptr++;
4562            }            }
4563          break;          break;
# Line 4948  for (;;) Line 5038  for (;;)
5038              if (UCD_CATEGORY(c) != ucp_M) break;              if (UCD_CATEGORY(c) != ucp_M) break;
5039              eptr += len;              eptr += len;
5040              }              }
5041              CHECK_PARTIAL();
5042            }            }
5043          }          }
5044        else        else
# Line 4971  for (;;) Line 5062  for (;;)
5062            GETCHARINC(c, eptr);            GETCHARINC(c, eptr);
5063            switch(ctype)            switch(ctype)
5064              {              {
5065              case OP_ANY:        /* This is the non-NL case */              case OP_ANY:               /* This is the non-NL case */
5066                if (md->partial != 0 &&    /* Take care with CRLF partial */
5067                    eptr >= md->end_subject &&
5068                    NLBLOCK->nltype == NLTYPE_FIXED &&
5069                    NLBLOCK->nllen == 2 &&
5070                    c == NLBLOCK->nl[0])
5071                  {
5072                  md->hitend = TRUE;
5073                  if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
5074                  }
5075                break;
5076    
5077              case OP_ALLANY:              case OP_ALLANY:
5078              case OP_ANYBYTE:              case OP_ANYBYTE:
5079              break;              break;
# Line 5134  for (;;) Line 5236  for (;;)
5236            c = *eptr++;            c = *eptr++;
5237            switch(ctype)            switch(ctype)
5238              {              {
5239              case OP_ANY:     /* This is the non-NL case */              case OP_ANY:               /* This is the non-NL case */
5240                if (md->partial != 0 &&    /* Take care with CRLF partial */
5241                    eptr >= md->end_subject &&
5242                    NLBLOCK->nltype == NLTYPE_FIXED &&
5243                    NLBLOCK->nllen == 2 &&
5244                    c == NLBLOCK->nl[0])
5245                  {
5246                  md->hitend = TRUE;
5247                  if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
5248                  }
5249                break;
5250    
5251              case OP_ALLANY:              case OP_ALLANY:
5252              case OP_ANYBYTE:              case OP_ANYBYTE:
5253              break;              break;
# Line 5491  for (;;) Line 5604  for (;;)
5604              if (UCD_CATEGORY(c) != ucp_M) break;              if (UCD_CATEGORY(c) != ucp_M) break;
5605              eptr += len;              eptr += len;
5606              }              }
5607              CHECK_PARTIAL();
5608            }            }
5609    
5610          /* 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 (;;)
5648                  break;                  break;
5649                  }                  }
5650                if (IS_NEWLINE(eptr)) break;                if (IS_NEWLINE(eptr)) break;
5651                  if (md->partial != 0 &&    /* Take care with CRLF partial */
5652                      eptr + 1 >= md->end_subject &&
5653                      NLBLOCK->nltype == NLTYPE_FIXED &&
5654                      NLBLOCK->nllen == 2 &&
5655                      *eptr == NLBLOCK->nl[0])
5656                    {
5657                    md->hitend = TRUE;
5658                    if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
5659                    }
5660                eptr++;                eptr++;
5661                ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);                ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
5662                }                }
# Line 5551  for (;;) Line 5674  for (;;)
5674                  break;                  break;
5675                  }                  }
5676                if (IS_NEWLINE(eptr)) break;                if (IS_NEWLINE(eptr)) break;
5677                  if (md->partial != 0 &&    /* Take care with CRLF partial */
5678                      eptr + 1 >= md->end_subject &&
5679                      NLBLOCK->nltype == NLTYPE_FIXED &&
5680                      NLBLOCK->nllen == 2 &&
5681                      *eptr == NLBLOCK->nl[0])
5682                    {
5683                    md->hitend = TRUE;
5684                    if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
5685                    }
5686                eptr++;                eptr++;
5687                ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);                ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
5688                }                }
# Line 5815  for (;;) Line 5947  for (;;)
5947                break;                break;
5948                }                }
5949              if (IS_NEWLINE(eptr)) break;              if (IS_NEWLINE(eptr)) break;
5950                if (md->partial != 0 &&    /* Take care with CRLF partial */
5951                    eptr + 1 >= md->end_subject &&
5952                    NLBLOCK->nltype == NLTYPE_FIXED &&
5953                    NLBLOCK->nllen == 2 &&
5954                    *eptr == NLBLOCK->nl[0])
5955                  {
5956                  md->hitend = TRUE;
5957                  if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
5958                  }
5959              eptr++;              eptr++;
5960              }              }
5961            break;            break;
# Line 6145  Undefine all the macros that were define Line 6286  Undefine all the macros that were define
6286  ***************************************************************************/  ***************************************************************************/
6287    
6288    
6289    #ifdef NO_RECURSE
6290    /*************************************************
6291    *          Release allocated heap frames         *
6292    *************************************************/
6293    
6294    /* This function releases all the allocated frames. The base frame is on the
6295    machine stack, and so must not be freed.
6296    
6297    Argument: the address of the base frame
6298    Returns:  nothing
6299    */
6300    
6301    static void
6302    release_match_heapframes (heapframe *frame_base)
6303    {
6304    heapframe *nextframe = frame_base->Xnextframe;
6305    while (nextframe != NULL)
6306      {
6307      heapframe *oldframe = nextframe;
6308      nextframe = nextframe->Xnextframe;
6309      (PUBL(stack_free))(oldframe);
6310      }
6311    }
6312    #endif
6313    
6314    
6315  /*************************************************  /*************************************************
6316  *         Execute a Regular Expression           *  *         Execute a Regular Expression           *
# Line 6207  PCRE_PUCHAR req_char_ptr = start_match - Line 6373  PCRE_PUCHAR req_char_ptr = start_match -
6373  const pcre_study_data *study;  const pcre_study_data *study;
6374  const REAL_PCRE *re = (const REAL_PCRE *)argument_re;  const REAL_PCRE *re = (const REAL_PCRE *)argument_re;
6375    
6376    #ifdef NO_RECURSE
6377    heapframe frame_zero;
6378    frame_zero.Xprevframe = NULL;            /* Marks the top level */
6379    frame_zero.Xnextframe = NULL;            /* None are allocated yet */
6380    md->match_frames_base = &frame_zero;
6381    #endif
6382    
6383  /* 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
6384  per recursive call of match(). */  per recursive call of match(). Without the funny casting for sizeof, a Windows
6385    compiler gave this error: "unary minus operator applied to unsigned type,
6386    result still unsigned". Hopefully the cast fixes that. */
6387    
6388  if (re == NULL && extra_data == NULL && subject == NULL && length == -999 &&  if (re == NULL && extra_data == NULL && subject == NULL && length == -999 &&
6389      start_offset == -999)      start_offset == -999)
6390  #ifdef NO_RECURSE  #ifdef NO_RECURSE
6391    return -sizeof(heapframe);    return -((int)sizeof(heapframe));
6392  #else  #else
6393    return match(NULL, NULL, NULL, 0, NULL, NULL, 0);    return match(NULL, NULL, NULL, 0, NULL, NULL, 0);
6394  #endif  #endif
# Line 6280  if (utf && (options & PCRE_NO_UTF8_CHECK Line 6455  if (utf && (options & PCRE_NO_UTF8_CHECK
6455  /* If the pattern was successfully studied with JIT support, run the JIT  /* If the pattern was successfully studied with JIT support, run the JIT
6456  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
6457  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
6458  an unsupported flag is set. In particular, JIT does not support partial  an unsupported flag is set. */
 matching. */  
6459    
6460  #ifdef SUPPORT_JIT  #ifdef SUPPORT_JIT
6461  if (extra_data != NULL  if (extra_data != NULL
6462      && (extra_data->flags & PCRE_EXTRA_EXECUTABLE_JIT) != 0      && (extra_data->flags & (PCRE_EXTRA_EXECUTABLE_JIT |
6463                                 PCRE_EXTRA_TABLES)) == PCRE_EXTRA_EXECUTABLE_JIT
6464      && extra_data->executable_jit != NULL      && extra_data->executable_jit != NULL
     && (extra_data->flags & PCRE_EXTRA_TABLES) == 0  
6465      && (options & ~(PCRE_NO_UTF8_CHECK | PCRE_NOTBOL | PCRE_NOTEOL |      && (options & ~(PCRE_NO_UTF8_CHECK | PCRE_NOTBOL | PCRE_NOTEOL |
6466                      PCRE_NOTEMPTY | PCRE_NOTEMPTY_ATSTART)) == 0)                      PCRE_NOTEMPTY | PCRE_NOTEMPTY_ATSTART |
6467    return PRIV(jit_exec)(re, extra_data->executable_jit,                      PCRE_PARTIAL_SOFT | PCRE_PARTIAL_HARD)) == 0)
6468      (const pcre_uchar *)subject, length, start_offset, options,    {
6469      ((extra_data->flags & PCRE_EXTRA_MATCH_LIMIT) == 0)    rc = PRIV(jit_exec)(re, extra_data, (const pcre_uchar *)subject, length,
6470      ? MATCH_LIMIT : extra_data->match_limit, offsets, offsetcount);         start_offset, options, offsets, offsetcount);
6471    
6472      /* PCRE_ERROR_NULL means that the selected normal or partial matching
6473      mode is not compiled. In this case we simply fallback to interpreter. */
6474    
6475      if (rc != PCRE_ERROR_NULL) return rc;
6476      }
6477  #endif  #endif
6478    
6479  /* 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_ACC Line 7067  if (rc == MATCH_MATCH || rc == MATCH_ACC
7067      {      {
7068      register int *iptr, *iend;      register int *iptr, *iend;
7069      int resetcount = 2 + re->top_bracket * 2;      int resetcount = 2 + re->top_bracket * 2;
7070      if (resetcount > offsetcount) resetcount = ocount;      if (resetcount > offsetcount) resetcount = offsetcount;
7071      iptr = offsets + md->end_offset_top;      iptr = offsets + md->end_offset_top;
7072      iend = offsets + resetcount;      iend = offsets + resetcount;
7073      while (iptr < iend) *iptr++ = -1;      while (iptr < iend) *iptr++ = -1;
# Line 6908  if (rc == MATCH_MATCH || rc == MATCH_ACC Line 7088  if (rc == MATCH_MATCH || rc == MATCH_ACC
7088    if (extra_data != NULL && (extra_data->flags & PCRE_EXTRA_MARK) != 0)    if (extra_data != NULL && (extra_data->flags & PCRE_EXTRA_MARK) != 0)
7089      *(extra_data->mark) = (pcre_uchar *)md->mark;      *(extra_data->mark) = (pcre_uchar *)md->mark;
7090    DPRINTF((">>>> returning %d\n", rc));    DPRINTF((">>>> returning %d\n", rc));
7091    #ifdef NO_RECURSE
7092      release_match_heapframes(&frame_zero);
7093    #endif
7094    return rc;    return rc;
7095    }    }
7096    
# Line 6925  if (using_temporary_offsets) Line 7108  if (using_temporary_offsets)
7108  if (rc != MATCH_NOMATCH && rc != PCRE_ERROR_PARTIAL)  if (rc != MATCH_NOMATCH && rc != PCRE_ERROR_PARTIAL)
7109    {    {
7110    DPRINTF((">>>> error: returning %d\n", rc));    DPRINTF((">>>> error: returning %d\n", rc));
7111    #ifdef NO_RECURSE
7112      release_match_heapframes(&frame_zero);
7113    #endif
7114    return rc;    return rc;
7115    }    }
7116    
# Line 6954  else Line 7140  else
7140    
7141  if (extra_data != NULL && (extra_data->flags & PCRE_EXTRA_MARK) != 0)  if (extra_data != NULL && (extra_data->flags & PCRE_EXTRA_MARK) != 0)
7142    *(extra_data->mark) = (pcre_uchar *)md->nomatch_mark;    *(extra_data->mark) = (pcre_uchar *)md->nomatch_mark;
7143    #ifdef NO_RECURSE
7144      release_match_heapframes(&frame_zero);
7145    #endif
7146  return rc;  return rc;
7147  }  }
7148    

Legend:
Removed from v.904  
changed lines
  Added in v.976

  ViewVC Help
Powered by ViewVC 1.1.5