/[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 403 by ph10, Sat Mar 21 17:33:11 2009 UTC revision 428 by ph10, Mon Aug 31 17:10:26 2009 UTC
# Line 322  typedef struct heapframe { Line 322  typedef struct heapframe {
322    
323    /* Function arguments that may change */    /* Function arguments that may change */
324    
325    const uschar *Xeptr;    USPTR Xeptr;
326    const uschar *Xecode;    const uschar *Xecode;
327    const uschar *Xmstart;    USPTR Xmstart;
328    int Xoffset_top;    int Xoffset_top;
329    long int Xims;    long int Xims;
330    eptrblock *Xeptrb;    eptrblock *Xeptrb;
# Line 333  typedef struct heapframe { Line 333  typedef struct heapframe {
333    
334    /* Function local variables */    /* Function local variables */
335    
336    const uschar *Xcallpat;    USPTR Xcallpat;
337  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
338    const uschar *Xcharptr;    USPTR Xcharptr;
339  #endif  #endif
340    const uschar *Xdata;    USPTR Xdata;
341    const uschar *Xnext;    USPTR Xnext;
342    const uschar *Xpp;    USPTR Xpp;
343    const uschar *Xprev;    USPTR Xprev;
344    const uschar *Xsaved_eptr;    USPTR Xsaved_eptr;
345    
346    recursion_info Xnew_recursive;    recursion_info Xnew_recursive;
347    
# Line 398  typedef struct heapframe { Line 398  typedef struct heapframe {
398    
399  /* This function is called recursively in many circumstances. Whenever it  /* This function is called recursively in many circumstances. Whenever it
400  returns a negative (error) response, the outer incarnation must also return the  returns a negative (error) response, the outer incarnation must also return the
401  same response.  same response. */
402    
403    /* These macros pack up tests that are used for partial matching, and which
404    appears several times in the code. We set the "hit end" flag if the pointer is
405    at the end of the subject and also past the start of the subject (i.e.
406    something has been matched). For hard partial matching, we then return
407    immediately. The second one is used when we already know we are past the end of
408    the subject. */
409    
410    #define CHECK_PARTIAL()\
411      if (md->partial && eptr >= md->end_subject && eptr > mstart)\
412        {\
413        md->hitend = TRUE;\
414        if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);\
415        }
416    
417    #define SCHECK_PARTIAL()\
418      if (md->partial && eptr > mstart)\
419        {\
420        md->hitend = TRUE;\
421        if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);\
422        }
423    
424    
425  Performance note: It might be tempting to extract commonly used fields from the  /* Performance note: It might be tempting to extract commonly used fields from
426  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
427  performance. Tests using gcc on a SPARC disproved this; in the first case, it  performance. Tests using gcc on a SPARC disproved this; in the first case, it
428  made performance worse.  made performance worse.
429    
# Line 428  Returns:       MATCH_MATCH if matched Line 450  Returns:       MATCH_MATCH if matched
450  */  */
451    
452  static int  static int
453  match(REGISTER USPTR eptr, REGISTER const uschar *ecode, const uschar *mstart,  match(REGISTER USPTR eptr, REGISTER const uschar *ecode, USPTR mstart,
454    int offset_top, match_data *md, unsigned long int ims, eptrblock *eptrb,    int offset_top, match_data *md, unsigned long int ims, eptrblock *eptrb,
455    int flags, unsigned int rdepth)    int flags, unsigned int rdepth)
456  {  {
# Line 642  for (;;) Line 664  for (;;)
664    minimize = possessive = FALSE;    minimize = possessive = FALSE;
665    op = *ecode;    op = *ecode;
666    
   /* For partial matching, remember if we ever hit the end of the subject after  
   matching at least one subject character. */  
   
   if (md->partial &&  
       eptr >= md->end_subject &&  
       eptr > mstart)  
     md->hitend = TRUE;  
   
667    switch(op)    switch(op)
668      {      {
669      case OP_FAIL:      case OP_FAIL:
# Line 794  for (;;) Line 808  for (;;)
808      case OP_COND:      case OP_COND:
809      case OP_SCOND:      case OP_SCOND:
810      codelink= GET(ecode, 1);      codelink= GET(ecode, 1);
811    
812      /* Because of the way auto-callout works during compile, a callout item is      /* Because of the way auto-callout works during compile, a callout item is
813      inserted between OP_COND and an assertion condition. */      inserted between OP_COND and an assertion condition. */
814    
# Line 822  for (;;) Line 836  for (;;)
836        }        }
837    
838      condcode = ecode[LINK_SIZE+1];      condcode = ecode[LINK_SIZE+1];
839    
840      /* Now see what the actual condition is */      /* Now see what the actual condition is */
841    
842      if (condcode == OP_RREF)         /* Recursion test */      if (condcode == OP_RREF)         /* Recursion test */
# Line 1461  for (;;) Line 1475  for (;;)
1475          {          {
1476          if (eptr == md->start_subject) prev_is_word = FALSE; else          if (eptr == md->start_subject) prev_is_word = FALSE; else
1477            {            {
1478            const uschar *lastptr = eptr - 1;            USPTR lastptr = eptr - 1;
1479            while((*lastptr & 0xc0) == 0x80) lastptr--;            while((*lastptr & 0xc0) == 0x80) lastptr--;
1480            GETCHAR(c, lastptr);            GETCHAR(c, lastptr);
1481            prev_is_word = c < 256 && (md->ctypes[c] & ctype_word) != 0;            prev_is_word = c < 256 && (md->ctypes[c] & ctype_word) != 0;
1482            }            }
1483          if (eptr >= md->end_subject) cur_is_word = FALSE; else          if (eptr >= md->end_subject)
1484              {
1485              SCHECK_PARTIAL();
1486              cur_is_word = FALSE;
1487              }
1488            else
1489            {            {
1490            GETCHAR(c, eptr);            GETCHAR(c, eptr);
1491            cur_is_word = c < 256 && (md->ctypes[c] & ctype_word) != 0;            cur_is_word = c < 256 && (md->ctypes[c] & ctype_word) != 0;
# Line 1475  for (;;) Line 1494  for (;;)
1494        else        else
1495  #endif  #endif
1496    
1497        /* More streamlined when not in UTF-8 mode */        /* Not in UTF-8 mode */
1498    
1499          {          {
1500          prev_is_word = (eptr != md->start_subject) &&          prev_is_word = (eptr != md->start_subject) &&
1501            ((md->ctypes[eptr[-1]] & ctype_word) != 0);            ((md->ctypes[eptr[-1]] & ctype_word) != 0);
1502          cur_is_word = (eptr < md->end_subject) &&          if (eptr >= md->end_subject)
1503            ((md->ctypes[*eptr] & ctype_word) != 0);            {
1504              SCHECK_PARTIAL();
1505              cur_is_word = FALSE;
1506              }
1507            else cur_is_word = ((md->ctypes[*eptr] & ctype_word) != 0);
1508          }          }
1509    
1510        /* Now see if the situation is what we want */        /* Now see if the situation is what we want */
# Line 1499  for (;;) Line 1522  for (;;)
1522      /* Fall through */      /* Fall through */
1523    
1524      case OP_ALLANY:      case OP_ALLANY:
1525      if (eptr++ >= md->end_subject) RRETURN(MATCH_NOMATCH);      if (eptr++ >= md->end_subject)
1526          {
1527          SCHECK_PARTIAL();
1528          RRETURN(MATCH_NOMATCH);
1529          }
1530      if (utf8) while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;      if (utf8) while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;
1531      ecode++;      ecode++;
1532      break;      break;
# Line 1508  for (;;) Line 1535  for (;;)
1535      any byte, even newline, independent of the setting of PCRE_DOTALL. */      any byte, even newline, independent of the setting of PCRE_DOTALL. */
1536    
1537      case OP_ANYBYTE:      case OP_ANYBYTE:
1538      if (eptr++ >= md->end_subject) RRETURN(MATCH_NOMATCH);      if (eptr++ >= md->end_subject)
1539          {
1540          SCHECK_PARTIAL();
1541          RRETURN(MATCH_NOMATCH);
1542          }
1543      ecode++;      ecode++;
1544      break;      break;
1545    
1546      case OP_NOT_DIGIT:      case OP_NOT_DIGIT:
1547      if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);      if (eptr >= md->end_subject)
1548          {
1549          SCHECK_PARTIAL();
1550          RRETURN(MATCH_NOMATCH);
1551          }
1552      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
1553      if (      if (
1554  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
# Line 1526  for (;;) Line 1561  for (;;)
1561      break;      break;
1562    
1563      case OP_DIGIT:      case OP_DIGIT:
1564      if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);      if (eptr >= md->end_subject)
1565          {
1566          SCHECK_PARTIAL();
1567          RRETURN(MATCH_NOMATCH);
1568          }
1569      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
1570      if (      if (
1571  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
# Line 1539  for (;;) Line 1578  for (;;)
1578      break;      break;
1579    
1580      case OP_NOT_WHITESPACE:      case OP_NOT_WHITESPACE:
1581      if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);      if (eptr >= md->end_subject)
1582          {
1583          SCHECK_PARTIAL();
1584          RRETURN(MATCH_NOMATCH);
1585          }
1586      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
1587      if (      if (
1588  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
# Line 1552  for (;;) Line 1595  for (;;)
1595      break;      break;
1596    
1597      case OP_WHITESPACE:      case OP_WHITESPACE:
1598      if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);      if (eptr >= md->end_subject)
1599          {
1600          SCHECK_PARTIAL();
1601          RRETURN(MATCH_NOMATCH);
1602          }
1603      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
1604      if (      if (
1605  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
# Line 1565  for (;;) Line 1612  for (;;)
1612      break;      break;
1613    
1614      case OP_NOT_WORDCHAR:      case OP_NOT_WORDCHAR:
1615      if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);      if (eptr >= md->end_subject)
1616          {
1617          SCHECK_PARTIAL();
1618          RRETURN(MATCH_NOMATCH);
1619          }
1620      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
1621      if (      if (
1622  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
# Line 1578  for (;;) Line 1629  for (;;)
1629      break;      break;
1630    
1631      case OP_WORDCHAR:      case OP_WORDCHAR:
1632      if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);      if (eptr >= md->end_subject)
1633          {
1634          SCHECK_PARTIAL();
1635          RRETURN(MATCH_NOMATCH);
1636          }
1637      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
1638      if (      if (
1639  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
# Line 1591  for (;;) Line 1646  for (;;)
1646      break;      break;
1647    
1648      case OP_ANYNL:      case OP_ANYNL:
1649      if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);      if (eptr >= md->end_subject)
1650          {
1651          SCHECK_PARTIAL();
1652          RRETURN(MATCH_NOMATCH);
1653          }
1654      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
1655      switch(c)      switch(c)
1656        {        {
# Line 1615  for (;;) Line 1674  for (;;)
1674      break;      break;
1675    
1676      case OP_NOT_HSPACE:      case OP_NOT_HSPACE:
1677      if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);      if (eptr >= md->end_subject)
1678          {
1679          SCHECK_PARTIAL();
1680          RRETURN(MATCH_NOMATCH);
1681          }
1682      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
1683      switch(c)      switch(c)
1684        {        {
# Line 1645  for (;;) Line 1708  for (;;)
1708      break;      break;
1709    
1710      case OP_HSPACE:      case OP_HSPACE:
1711      if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);      if (eptr >= md->end_subject)
1712          {
1713          SCHECK_PARTIAL();
1714          RRETURN(MATCH_NOMATCH);
1715          }
1716      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
1717      switch(c)      switch(c)
1718        {        {
# Line 1675  for (;;) Line 1742  for (;;)
1742      break;      break;
1743    
1744      case OP_NOT_VSPACE:      case OP_NOT_VSPACE:
1745      if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);      if (eptr >= md->end_subject)
1746          {
1747          SCHECK_PARTIAL();
1748          RRETURN(MATCH_NOMATCH);
1749          }
1750      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
1751      switch(c)      switch(c)
1752        {        {
# Line 1693  for (;;) Line 1764  for (;;)
1764      break;      break;
1765    
1766      case OP_VSPACE:      case OP_VSPACE:
1767      if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);      if (eptr >= md->end_subject)
1768          {
1769          SCHECK_PARTIAL();
1770          RRETURN(MATCH_NOMATCH);
1771          }
1772      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
1773      switch(c)      switch(c)
1774        {        {
# Line 1716  for (;;) Line 1791  for (;;)
1791    
1792      case OP_PROP:      case OP_PROP:
1793      case OP_NOTPROP:      case OP_NOTPROP:
1794      if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);      if (eptr >= md->end_subject)
1795          {
1796          SCHECK_PARTIAL();
1797          RRETURN(MATCH_NOMATCH);
1798          }
1799      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
1800        {        {
1801        const ucd_record *prop = GET_UCD(c);        const ucd_record *prop = GET_UCD(c);
# Line 1761  for (;;) Line 1840  for (;;)
1840      is in the binary; otherwise a compile-time error occurs. */      is in the binary; otherwise a compile-time error occurs. */
1841    
1842      case OP_EXTUNI:      case OP_EXTUNI:
1843      if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);      if (eptr >= md->end_subject)
1844          {
1845          SCHECK_PARTIAL();
1846          RRETURN(MATCH_NOMATCH);
1847          }
1848      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
1849        {        {
1850        int category = UCD_CATEGORY(c);        int category = UCD_CATEGORY(c);
# Line 1841  for (;;) Line 1924  for (;;)
1924          break;          break;
1925    
1926          default:               /* No repeat follows */          default:               /* No repeat follows */
1927          if (!match_ref(offset, eptr, length, md, ims)) RRETURN(MATCH_NOMATCH);          if (!match_ref(offset, eptr, length, md, ims))
1928              {
1929              CHECK_PARTIAL();
1930              RRETURN(MATCH_NOMATCH);
1931              }
1932          eptr += length;          eptr += length;
1933          continue;              /* With the main loop */          continue;              /* With the main loop */
1934          }          }
1935    
1936        /* If the length of the reference is zero, just continue with the        /* If the length of the reference is zero, just continue with the
1937        main loop. */        main loop. */
1938    
1939        if (length == 0) continue;        if (length == 0) continue;
1940    
1941        /* First, ensure the minimum number of matches are present. We get back        /* First, ensure the minimum number of matches are present. We get back
# Line 1857  for (;;) Line 1944  for (;;)
1944    
1945        for (i = 1; i <= min; i++)        for (i = 1; i <= min; i++)
1946          {          {
1947          if (!match_ref(offset, eptr, length, md, ims)) RRETURN(MATCH_NOMATCH);          if (!match_ref(offset, eptr, length, md, ims))
1948              {
1949              CHECK_PARTIAL();
1950              RRETURN(MATCH_NOMATCH);
1951              }
1952          eptr += length;          eptr += length;
1953          }          }
1954    
# Line 1874  for (;;) Line 1965  for (;;)
1965            {            {
1966            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM14);            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM14);
1967            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
1968            if (fi >= max || !match_ref(offset, eptr, length, md, ims))            if (fi >= max) RRETURN(MATCH_NOMATCH);
1969              if (!match_ref(offset, eptr, length, md, ims))
1970                {
1971                CHECK_PARTIAL();
1972              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
1973                }
1974            eptr += length;            eptr += length;
1975            }            }
1976          /* Control never gets here */          /* Control never gets here */
# Line 1902  for (;;) Line 1997  for (;;)
1997        }        }
1998      /* Control never gets here */      /* Control never gets here */
1999    
   
   
2000      /* Match a bit-mapped character class, possibly repeatedly. This op code is      /* Match a bit-mapped character class, possibly repeatedly. This op code is
2001      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,
2002      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 1958  for (;;) Line 2051  for (;;)
2051          {          {
2052          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
2053            {            {
2054            if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);            if (eptr >= md->end_subject)
2055                {
2056                SCHECK_PARTIAL();
2057                RRETURN(MATCH_NOMATCH);
2058                }
2059            GETCHARINC(c, eptr);            GETCHARINC(c, eptr);
2060            if (c > 255)            if (c > 255)
2061              {              {
# Line 1976  for (;;) Line 2073  for (;;)
2073          {          {
2074          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
2075            {            {
2076            if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);            if (eptr >= md->end_subject)
2077                {
2078                SCHECK_PARTIAL();
2079                RRETURN(MATCH_NOMATCH);
2080                }
2081            c = *eptr++;            c = *eptr++;
2082            if ((data[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);            if ((data[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);
2083            }            }
# Line 2000  for (;;) Line 2101  for (;;)
2101              {              {
2102              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM16);              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM16);
2103              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2104              if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);              if (fi >= max) RRETURN(MATCH_NOMATCH);
2105                if (eptr >= md->end_subject)
2106                  {
2107                  SCHECK_PARTIAL();
2108                  RRETURN(MATCH_NOMATCH);
2109                  }
2110              GETCHARINC(c, eptr);              GETCHARINC(c, eptr);
2111              if (c > 255)              if (c > 255)
2112                {                {
# Line 2020  for (;;) Line 2126  for (;;)
2126              {              {
2127              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM17);              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM17);
2128              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2129              if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);              if (fi >= max) RRETURN(MATCH_NOMATCH);
2130                if (eptr >= md->end_subject)
2131                  {
2132                  SCHECK_PARTIAL();
2133                  RRETURN(MATCH_NOMATCH);
2134                  }
2135              c = *eptr++;              c = *eptr++;
2136              if ((data[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);              if ((data[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);
2137              }              }
# Line 2129  for (;;) Line 2240  for (;;)
2240    
2241        for (i = 1; i <= min; i++)        for (i = 1; i <= min; i++)
2242          {          {
2243          if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);          if (eptr >= md->end_subject)
2244              {
2245              SCHECK_PARTIAL();
2246              RRETURN(MATCH_NOMATCH);
2247              }
2248          GETCHARINCTEST(c, eptr);          GETCHARINCTEST(c, eptr);
2249          if (!_pcre_xclass(c, data)) RRETURN(MATCH_NOMATCH);          if (!_pcre_xclass(c, data)) RRETURN(MATCH_NOMATCH);
2250          }          }
# Line 2148  for (;;) Line 2263  for (;;)
2263            {            {
2264            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM20);            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM20);
2265            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2266            if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);            if (fi >= max) RRETURN(MATCH_NOMATCH);
2267              if (eptr >= md->end_subject)
2268                {
2269                SCHECK_PARTIAL();
2270                RRETURN(MATCH_NOMATCH);
2271                }
2272            GETCHARINCTEST(c, eptr);            GETCHARINCTEST(c, eptr);
2273            if (!_pcre_xclass(c, data)) RRETURN(MATCH_NOMATCH);            if (!_pcre_xclass(c, data)) RRETURN(MATCH_NOMATCH);
2274            }            }
# Line 2191  for (;;) Line 2311  for (;;)
2311        length = 1;        length = 1;
2312        ecode++;        ecode++;
2313        GETCHARLEN(fc, ecode, length);        GETCHARLEN(fc, ecode, length);
2314        if (length > md->end_subject - eptr) RRETURN(MATCH_NOMATCH);        if (length > md->end_subject - eptr)
2315            {
2316            CHECK_PARTIAL();             /* Not SCHECK_PARTIAL() */
2317            RRETURN(MATCH_NOMATCH);
2318            }
2319        while (length-- > 0) if (*ecode++ != *eptr++) RRETURN(MATCH_NOMATCH);        while (length-- > 0) if (*ecode++ != *eptr++) RRETURN(MATCH_NOMATCH);
2320        }        }
2321      else      else
# Line 2199  for (;;) Line 2323  for (;;)
2323    
2324      /* Non-UTF-8 mode */      /* Non-UTF-8 mode */
2325        {        {
2326        if (md->end_subject - eptr < 1) RRETURN(MATCH_NOMATCH);        if (md->end_subject - eptr < 1)
2327            {
2328            SCHECK_PARTIAL();            /* This one can use SCHECK_PARTIAL() */
2329            RRETURN(MATCH_NOMATCH);
2330            }
2331        if (ecode[1] != *eptr++) RRETURN(MATCH_NOMATCH);        if (ecode[1] != *eptr++) RRETURN(MATCH_NOMATCH);
2332        ecode += 2;        ecode += 2;
2333        }        }
# Line 2215  for (;;) Line 2343  for (;;)
2343        ecode++;        ecode++;
2344        GETCHARLEN(fc, ecode, length);        GETCHARLEN(fc, ecode, length);
2345    
2346        if (length > md->end_subject - eptr) RRETURN(MATCH_NOMATCH);        if (length > md->end_subject - eptr)
2347            {
2348            CHECK_PARTIAL();             /* Not SCHECK_PARTIAL() */
2349            RRETURN(MATCH_NOMATCH);
2350            }
2351    
2352        /* 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
2353        can use the fast lookup table. */        can use the fast lookup table. */
# Line 2250  for (;;) Line 2382  for (;;)
2382    
2383      /* Non-UTF-8 mode */      /* Non-UTF-8 mode */
2384        {        {
2385        if (md->end_subject - eptr < 1) RRETURN(MATCH_NOMATCH);        if (md->end_subject - eptr < 1)
2386            {
2387            SCHECK_PARTIAL();            /* This one can use SCHECK_PARTIAL() */
2388            RRETURN(MATCH_NOMATCH);
2389            }
2390        if (md->lcc[ecode[1]] != md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH);        if (md->lcc[ecode[1]] != md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH);
2391        ecode += 2;        ecode += 2;
2392        }        }
# Line 2304  for (;;) Line 2440  for (;;)
2440      case OP_MINQUERY:      case OP_MINQUERY:
2441      c = *ecode++ - OP_STAR;      c = *ecode++ - OP_STAR;
2442      minimize = (c & 1) != 0;      minimize = (c & 1) != 0;
2443    
2444      min = rep_min[c];                 /* Pick up values from tables; */      min = rep_min[c];                 /* Pick up values from tables; */
2445      max = rep_max[c];                 /* zero for max => infinity */      max = rep_max[c];                 /* zero for max => infinity */
2446      if (max == 0) max = INT_MAX;      if (max == 0) max = INT_MAX;
2447    
2448      /* Common code for all repeated single-character matches. We can give      /* Common code for all repeated single-character matches. */
     up quickly if there are fewer than the minimum number of characters left in  
     the subject. */  
2449    
2450      REPEATCHAR:      REPEATCHAR:
2451  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
# Line 2319  for (;;) Line 2454  for (;;)
2454        length = 1;        length = 1;
2455        charptr = ecode;        charptr = ecode;
2456        GETCHARLEN(fc, ecode, length);        GETCHARLEN(fc, ecode, length);
       if (min * length > md->end_subject - eptr) RRETURN(MATCH_NOMATCH);  
2457        ecode += length;        ecode += length;
2458    
2459        /* Handle multibyte character matching specially here. There is        /* Handle multibyte character matching specially here. There is
# Line 2337  for (;;) Line 2471  for (;;)
2471    
2472          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
2473            {            {
2474            if (memcmp(eptr, charptr, length) == 0) eptr += length;            if (eptr <= md->end_subject - length &&
2475                memcmp(eptr, charptr, length) == 0) eptr += length;
2476  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2477            /* Need braces because of following else */            else if (oclength > 0 &&
2478            else if (oclength == 0) { RRETURN(MATCH_NOMATCH); }                     eptr <= md->end_subject - oclength &&
2479                       memcmp(eptr, occhars, oclength) == 0) eptr += oclength;
2480    #endif  /* SUPPORT_UCP */
2481            else            else
2482              {              {
2483              if (memcmp(eptr, occhars, oclength) != 0) RRETURN(MATCH_NOMATCH);              CHECK_PARTIAL();
2484              eptr += oclength;              RRETURN(MATCH_NOMATCH);
2485              }              }
 #else   /* without SUPPORT_UCP */  
           else { RRETURN(MATCH_NOMATCH); }  
 #endif  /* SUPPORT_UCP */  
2486            }            }
2487    
2488          if (min == max) continue;          if (min == max) continue;
# Line 2359  for (;;) Line 2493  for (;;)
2493              {              {
2494              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM22);              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM22);
2495              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2496              if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);              if (fi >= max) RRETURN(MATCH_NOMATCH);
2497              if (memcmp(eptr, charptr, length) == 0) eptr += length;              if (eptr <= md->end_subject - length &&
2498                  memcmp(eptr, charptr, length) == 0) eptr += length;
2499  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2500              /* Need braces because of following else */              else if (oclength > 0 &&
2501              else if (oclength == 0) { RRETURN(MATCH_NOMATCH); }                       eptr <= md->end_subject - oclength &&
2502                         memcmp(eptr, occhars, oclength) == 0) eptr += oclength;
2503    #endif  /* SUPPORT_UCP */
2504              else              else
2505                {                {
2506                if (memcmp(eptr, occhars, oclength) != 0) RRETURN(MATCH_NOMATCH);                CHECK_PARTIAL();
2507                eptr += oclength;                RRETURN(MATCH_NOMATCH);
2508                }                }
 #else   /* without SUPPORT_UCP */  
             else { RRETURN (MATCH_NOMATCH); }  
 #endif  /* SUPPORT_UCP */  
2509              }              }
2510            /* Control never gets here */            /* Control never gets here */
2511            }            }
# Line 2381  for (;;) Line 2515  for (;;)
2515            pp = eptr;            pp = eptr;
2516            for (i = min; i < max; i++)            for (i = min; i < max; i++)
2517              {              {
2518              if (eptr > md->end_subject - length) break;              if (eptr <= md->end_subject - length &&
2519              if (memcmp(eptr, charptr, length) == 0) eptr += length;                  memcmp(eptr, charptr, length) == 0) eptr += length;
2520  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2521              else if (oclength == 0) break;              else if (oclength > 0 &&
2522              else                       eptr <= md->end_subject - oclength &&
2523                {                       memcmp(eptr, occhars, oclength) == 0) eptr += oclength;
               if (memcmp(eptr, occhars, oclength) != 0) break;  
               eptr += oclength;  
               }  
 #else   /* without SUPPORT_UCP */  
             else break;  
2524  #endif  /* SUPPORT_UCP */  #endif  /* SUPPORT_UCP */
2525                else break;
2526              }              }
2527    
2528            if (possessive) continue;            if (possessive) continue;
2529    
2530            for(;;)            for(;;)
2531             {              {
2532             RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM23);              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM23);
2533             if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2534             if (eptr == pp) RRETURN(MATCH_NOMATCH);              if (eptr == pp) { RRETURN(MATCH_NOMATCH); }
2535  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2536             eptr--;              eptr--;
2537             BACKCHAR(eptr);              BACKCHAR(eptr);
2538  #else   /* without SUPPORT_UCP */  #else   /* without SUPPORT_UCP */
2539             eptr -= length;              eptr -= length;
2540  #endif  /* SUPPORT_UCP */  #endif  /* SUPPORT_UCP */
2541             }              }
2542            }            }
2543          /* Control never gets here */          /* Control never gets here */
2544          }          }
# Line 2420  for (;;) Line 2551  for (;;)
2551  #endif  /* SUPPORT_UTF8 */  #endif  /* SUPPORT_UTF8 */
2552    
2553      /* When not in UTF-8 mode, load a single-byte character. */      /* When not in UTF-8 mode, load a single-byte character. */
       {  
       if (min > md->end_subject - eptr) RRETURN(MATCH_NOMATCH);  
       fc = *ecode++;  
       }  
2554    
2555        fc = *ecode++;
2556    
2557      /* The value of fc at this point is always less than 256, though we may or      /* The value of fc at this point is always less than 256, though we may or
2558      may not be in UTF-8 mode. The code is duplicated for the caseless and      may not be in UTF-8 mode. The code is duplicated for the caseless and
2559      caseful cases, for speed, since matching characters is likely to be quite      caseful cases, for speed, since matching characters is likely to be quite
# Line 2441  for (;;) Line 2570  for (;;)
2570        {        {
2571        fc = md->lcc[fc];        fc = md->lcc[fc];
2572        for (i = 1; i <= min; i++)        for (i = 1; i <= min; i++)
2573            {
2574            if (eptr >= md->end_subject)
2575              {
2576              SCHECK_PARTIAL();
2577              RRETURN(MATCH_NOMATCH);
2578              }
2579          if (fc != md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH);          if (fc != md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH);
2580            }
2581        if (min == max) continue;        if (min == max) continue;
2582        if (minimize)        if (minimize)
2583          {          {
# Line 2449  for (;;) Line 2585  for (;;)
2585            {            {
2586            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM24);            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM24);
2587            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2588            if (fi >= max || eptr >= md->end_subject ||            if (fi >= max) RRETURN(MATCH_NOMATCH);
2589                fc != md->lcc[*eptr++])            if (eptr >= md->end_subject)
2590                {
2591                SCHECK_PARTIAL();
2592              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
2593                }
2594              if (fc != md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH);
2595            }            }
2596          /* Control never gets here */          /* Control never gets here */
2597          }          }
# Line 2463  for (;;) Line 2603  for (;;)
2603            if (eptr >= md->end_subject || fc != md->lcc[*eptr]) break;            if (eptr >= md->end_subject || fc != md->lcc[*eptr]) break;
2604            eptr++;            eptr++;
2605            }            }
2606    
2607          if (possessive) continue;          if (possessive) continue;
2608    
2609          while (eptr >= pp)          while (eptr >= pp)
2610            {            {
2611            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM25);            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM25);
# Line 2479  for (;;) Line 2621  for (;;)
2621    
2622      else      else
2623        {        {
2624        for (i = 1; i <= min; i++) if (fc != *eptr++) RRETURN(MATCH_NOMATCH);        for (i = 1; i <= min; i++)
2625            {
2626            if (eptr >= md->end_subject)
2627              {
2628              SCHECK_PARTIAL();
2629              RRETURN(MATCH_NOMATCH);
2630              }
2631            if (fc != *eptr++) RRETURN(MATCH_NOMATCH);
2632            }
2633    
2634        if (min == max) continue;        if (min == max) continue;
2635    
2636        if (minimize)        if (minimize)
2637          {          {
2638          for (fi = min;; fi++)          for (fi = min;; fi++)
2639            {            {
2640            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM26);            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM26);
2641            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2642            if (fi >= max || eptr >= md->end_subject || fc != *eptr++)            if (fi >= max) RRETURN(MATCH_NOMATCH);
2643              if (eptr >= md->end_subject)
2644                {
2645                SCHECK_PARTIAL();
2646              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
2647                }
2648              if (fc != *eptr++) RRETURN(MATCH_NOMATCH);
2649            }            }
2650          /* Control never gets here */          /* Control never gets here */
2651          }          }
# Line 2501  for (;;) Line 2658  for (;;)
2658            eptr++;            eptr++;
2659            }            }
2660          if (possessive) continue;          if (possessive) continue;
2661    
2662          while (eptr >= pp)          while (eptr >= pp)
2663            {            {
2664            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM27);            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM27);
# Line 2516  for (;;) Line 2674  for (;;)
2674      checking can be multibyte. */      checking can be multibyte. */
2675    
2676      case OP_NOT:      case OP_NOT:
2677      if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);      if (eptr >= md->end_subject)
2678          {
2679          SCHECK_PARTIAL();
2680          RRETURN(MATCH_NOMATCH);
2681          }
2682      ecode++;      ecode++;
2683      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
2684      if ((ims & PCRE_CASELESS) != 0)      if ((ims & PCRE_CASELESS) != 0)
# Line 2593  for (;;) Line 2755  for (;;)
2755      max = rep_max[c];                 /* zero for max => infinity */      max = rep_max[c];                 /* zero for max => infinity */
2756      if (max == 0) max = INT_MAX;      if (max == 0) max = INT_MAX;
2757    
2758      /* Common code for all repeated single-byte matches. We can give up quickly      /* Common code for all repeated single-byte matches. */
     if there are fewer than the minimum number of bytes left in the  
     subject. */  
2759    
2760      REPEATNOTCHAR:      REPEATNOTCHAR:
     if (min > md->end_subject - eptr) RRETURN(MATCH_NOMATCH);  
2761      fc = *ecode++;      fc = *ecode++;
2762    
2763      /* The code is duplicated for the caseless and caseful cases, for speed,      /* The code is duplicated for the caseless and caseful cases, for speed,
# Line 2623  for (;;) Line 2782  for (;;)
2782          register unsigned int d;          register unsigned int d;
2783          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
2784            {            {
2785              if (eptr >= md->end_subject)
2786                {
2787                SCHECK_PARTIAL();
2788                RRETURN(MATCH_NOMATCH);
2789                }
2790            GETCHARINC(d, eptr);            GETCHARINC(d, eptr);
2791            if (d < 256) d = md->lcc[d];            if (d < 256) d = md->lcc[d];
2792            if (fc == d) RRETURN(MATCH_NOMATCH);            if (fc == d) RRETURN(MATCH_NOMATCH);
# Line 2634  for (;;) Line 2798  for (;;)
2798        /* Not UTF-8 mode */        /* Not UTF-8 mode */
2799          {          {
2800          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
2801              {
2802              if (eptr >= md->end_subject)
2803                {
2804                SCHECK_PARTIAL();
2805                RRETURN(MATCH_NOMATCH);
2806                }
2807            if (fc == md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH);            if (fc == md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH);
2808              }
2809          }          }
2810    
2811        if (min == max) continue;        if (min == max) continue;
# Line 2650  for (;;) Line 2821  for (;;)
2821              {              {
2822              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM28);              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM28);
2823              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2824              if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);              if (fi >= max) RRETURN(MATCH_NOMATCH);
2825                if (eptr >= md->end_subject)
2826                  {
2827                  SCHECK_PARTIAL();
2828                  RRETURN(MATCH_NOMATCH);
2829                  }
2830              GETCHARINC(d, eptr);              GETCHARINC(d, eptr);
2831              if (d < 256) d = md->lcc[d];              if (d < 256) d = md->lcc[d];
2832              if (fc == d) RRETURN(MATCH_NOMATCH);              if (fc == d) RRETURN(MATCH_NOMATCH);
   
2833              }              }
2834            }            }
2835          else          else
# Line 2665  for (;;) Line 2840  for (;;)
2840              {              {
2841              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM29);              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM29);
2842              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2843              if (fi >= max || eptr >= md->end_subject || fc == md->lcc[*eptr++])              if (fi >= max) RRETURN(MATCH_NOMATCH);
2844                if (eptr >= md->end_subject)
2845                  {
2846                  SCHECK_PARTIAL();
2847                RRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
2848                  }
2849                if (fc == md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH);
2850              }              }
2851            }            }
2852          /* Control never gets here */          /* Control never gets here */
# Line 2735  for (;;) Line 2915  for (;;)
2915          register unsigned int d;          register unsigned int d;
2916          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
2917            {            {
2918              if (eptr >= md->end_subject)
2919                {
2920                SCHECK_PARTIAL();
2921                RRETURN(MATCH_NOMATCH);
2922                }
2923            GETCHARINC(d, eptr);            GETCHARINC(d, eptr);
2924            if (fc == d) RRETURN(MATCH_NOMATCH);            if (fc == d) RRETURN(MATCH_NOMATCH);
2925            }            }
# Line 2744  for (;;) Line 2929  for (;;)
2929        /* Not UTF-8 mode */        /* Not UTF-8 mode */
2930          {          {
2931          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
2932              {
2933              if (eptr >= md->end_subject)
2934                {
2935                SCHECK_PARTIAL();
2936                RRETURN(MATCH_NOMATCH);
2937                }
2938            if (fc == *eptr++) RRETURN(MATCH_NOMATCH);            if (fc == *eptr++) RRETURN(MATCH_NOMATCH);
2939              }
2940          }          }
2941    
2942        if (min == max) continue;        if (min == max) continue;
# Line 2760  for (;;) Line 2952  for (;;)
2952              {              {
2953              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM32);              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM32);
2954              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2955              if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);              if (fi >= max) RRETURN(MATCH_NOMATCH);
2956                if (eptr >= md->end_subject)
2957                  {
2958                  SCHECK_PARTIAL();
2959                  RRETURN(MATCH_NOMATCH);
2960                  }
2961              GETCHARINC(d, eptr);              GETCHARINC(d, eptr);
2962              if (fc == d) RRETURN(MATCH_NOMATCH);              if (fc == d) RRETURN(MATCH_NOMATCH);
2963              }              }
# Line 2773  for (;;) Line 2970  for (;;)
2970              {              {
2971              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM33);              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM33);
2972              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2973              if (fi >= max || eptr >= md->end_subject || fc == *eptr++)              if (fi >= max) RRETURN(MATCH_NOMATCH);
2974                if (eptr >= md->end_subject)
2975                  {
2976                  SCHECK_PARTIAL();
2977                RRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
2978                  }
2979                if (fc == *eptr++) RRETURN(MATCH_NOMATCH);
2980              }              }
2981            }            }
2982          /* Control never gets here */          /* Control never gets here */
# Line 2908  for (;;) Line 3110  for (;;)
3110    
3111      /* First, ensure the minimum number of matches are present. Use inline      /* First, ensure the minimum number of matches are present. Use inline
3112      code for maximizing the speed, and do the type test once at the start      code for maximizing the speed, and do the type test once at the start
3113      (i.e. keep it out of the loop). Also we can test that there are at least      (i.e. keep it out of the loop). Separate the UTF-8 code completely as that
     the minimum number of bytes before we start. This isn't as effective in  
     UTF-8 mode, but it does no harm. Separate the UTF-8 code completely as that  
3114      is tidier. Also separate the UCP code, which can be the same for both UTF-8      is tidier. Also separate the UCP code, which can be the same for both UTF-8
3115      and single-bytes. */      and single-bytes. */
3116    
     if (min > md->end_subject - eptr) RRETURN(MATCH_NOMATCH);  
3117      if (min > 0)      if (min > 0)
3118        {        {
3119  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
# Line 2926  for (;;) Line 3125  for (;;)
3125            if (prop_fail_result) RRETURN(MATCH_NOMATCH);            if (prop_fail_result) RRETURN(MATCH_NOMATCH);
3126            for (i = 1; i <= min; i++)            for (i = 1; i <= min; i++)
3127              {              {
3128              if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);              if (eptr >= md->end_subject)
3129                  {
3130                  SCHECK_PARTIAL();
3131                  RRETURN(MATCH_NOMATCH);
3132                  }
3133              GETCHARINCTEST(c, eptr);              GETCHARINCTEST(c, eptr);
3134              }              }
3135            break;            break;
# Line 2934  for (;;) Line 3137  for (;;)
3137            case PT_LAMP:            case PT_LAMP:
3138            for (i = 1; i <= min; i++)            for (i = 1; i <= min; i++)
3139              {              {
3140              if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);              if (eptr >= md->end_subject)
3141                  {
3142                  SCHECK_PARTIAL();
3143                  RRETURN(MATCH_NOMATCH);
3144                  }
3145              GETCHARINCTEST(c, eptr);              GETCHARINCTEST(c, eptr);
3146              prop_chartype = UCD_CHARTYPE(c);              prop_chartype = UCD_CHARTYPE(c);
3147              if ((prop_chartype == ucp_Lu ||              if ((prop_chartype == ucp_Lu ||
# Line 2947  for (;;) Line 3154  for (;;)
3154            case PT_GC:            case PT_GC:
3155            for (i = 1; i <= min; i++)            for (i = 1; i <= min; i++)
3156              {              {
3157              if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);              if (eptr >= md->end_subject)
3158                  {
3159                  SCHECK_PARTIAL();
3160                  RRETURN(MATCH_NOMATCH);
3161                  }
3162              GETCHARINCTEST(c, eptr);              GETCHARINCTEST(c, eptr);
3163              prop_category = UCD_CATEGORY(c);              prop_category = UCD_CATEGORY(c);
3164              if ((prop_category == prop_value) == prop_fail_result)              if ((prop_category == prop_value) == prop_fail_result)
# Line 2958  for (;;) Line 3169  for (;;)
3169            case PT_PC:            case PT_PC:
3170            for (i = 1; i <= min; i++)            for (i = 1; i <= min; i++)
3171              {              {
3172              if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);              if (eptr >= md->end_subject)
3173                  {
3174                  SCHECK_PARTIAL();
3175                  RRETURN(MATCH_NOMATCH);
3176                  }
3177              GETCHARINCTEST(c, eptr);              GETCHARINCTEST(c, eptr);
3178              prop_chartype = UCD_CHARTYPE(c);              prop_chartype = UCD_CHARTYPE(c);
3179              if ((prop_chartype == prop_value) == prop_fail_result)              if ((prop_chartype == prop_value) == prop_fail_result)
# Line 2969  for (;;) Line 3184  for (;;)
3184            case PT_SC:            case PT_SC:
3185            for (i = 1; i <= min; i++)            for (i = 1; i <= min; i++)
3186              {              {
3187              if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);              if (eptr >= md->end_subject)
3188                  {
3189                  SCHECK_PARTIAL();
3190                  RRETURN(MATCH_NOMATCH);
3191                  }
3192              GETCHARINCTEST(c, eptr);              GETCHARINCTEST(c, eptr);
3193              prop_script = UCD_SCRIPT(c);              prop_script = UCD_SCRIPT(c);
3194              if ((prop_script == prop_value) == prop_fail_result)              if ((prop_script == prop_value) == prop_fail_result)
# Line 2989  for (;;) Line 3208  for (;;)
3208          {          {
3209          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3210            {            {
3211              if (eptr >= md->end_subject)
3212                {
3213                SCHECK_PARTIAL();
3214                RRETURN(MATCH_NOMATCH);
3215                }
3216            GETCHARINCTEST(c, eptr);            GETCHARINCTEST(c, eptr);
3217            prop_category = UCD_CATEGORY(c);            prop_category = UCD_CATEGORY(c);
3218            if (prop_category == ucp_M) RRETURN(MATCH_NOMATCH);            if (prop_category == ucp_M) RRETURN(MATCH_NOMATCH);
3219            while (eptr < md->end_subject)            while (eptr < md->end_subject)
3220              {              {
3221              int len = 1;              int len = 1;
3222              if (!utf8) c = *eptr; else              if (!utf8) c = *eptr;
3223                {                else { GETCHARLEN(c, eptr, len); }
               GETCHARLEN(c, eptr, len);  
               }  
3224              prop_category = UCD_CATEGORY(c);              prop_category = UCD_CATEGORY(c);
3225              if (prop_category != ucp_M) break;              if (prop_category != ucp_M) break;
3226              eptr += len;              eptr += len;
# Line 3017  for (;;) Line 3239  for (;;)
3239          case OP_ANY:          case OP_ANY:
3240          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3241            {            {
3242            if (eptr >= md->end_subject || IS_NEWLINE(eptr))            if (eptr >= md->end_subject)
3243                {
3244                SCHECK_PARTIAL();
3245              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
3246                }
3247              if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH);
3248            eptr++;            eptr++;
3249            while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;            while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;
3250            }            }
# Line 3027  for (;;) Line 3253  for (;;)
3253          case OP_ALLANY:          case OP_ALLANY:
3254          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3255            {            {
3256            if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);            if (eptr >= md->end_subject)
3257                {
3258                SCHECK_PARTIAL();
3259                RRETURN(MATCH_NOMATCH);
3260                }
3261            eptr++;            eptr++;
3262            while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;            while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;
3263            }            }
3264          break;          break;
3265    
3266          case OP_ANYBYTE:          case OP_ANYBYTE:
3267            if (eptr > md->end_subject - min) RRETURN(MATCH_NOMATCH);
3268          eptr += min;          eptr += min;
3269          break;          break;
3270    
3271          case OP_ANYNL:          case OP_ANYNL:
3272          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3273            {            {
3274            if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);            if (eptr >= md->end_subject)
3275                {
3276                SCHECK_PARTIAL();
3277                RRETURN(MATCH_NOMATCH);
3278                }
3279            GETCHARINC(c, eptr);            GETCHARINC(c, eptr);
3280            switch(c)            switch(c)
3281              {              {
# Line 3066  for (;;) Line 3301  for (;;)
3301          case OP_NOT_HSPACE:          case OP_NOT_HSPACE:
3302          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3303            {            {
3304            if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);            if (eptr >= md->end_subject)
3305                {
3306                SCHECK_PARTIAL();
3307                RRETURN(MATCH_NOMATCH);
3308                }
3309            GETCHARINC(c, eptr);            GETCHARINC(c, eptr);
3310            switch(c)            switch(c)
3311              {              {
# Line 3098  for (;;) Line 3337  for (;;)
3337          case OP_HSPACE:          case OP_HSPACE:
3338          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3339            {            {
3340            if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);            if (eptr >= md->end_subject)
3341                {
3342                SCHECK_PARTIAL();
3343                RRETURN(MATCH_NOMATCH);
3344                }
3345            GETCHARINC(c, eptr);            GETCHARINC(c, eptr);
3346            switch(c)            switch(c)
3347              {              {
# Line 3130  for (;;) Line 3373  for (;;)
3373          case OP_NOT_VSPACE:          case OP_NOT_VSPACE:
3374          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3375            {            {
3376            if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);            if (eptr >= md->end_subject)
3377                {
3378                SCHECK_PARTIAL();
3379                RRETURN(MATCH_NOMATCH);
3380                }
3381            GETCHARINC(c, eptr);            GETCHARINC(c, eptr);
3382            switch(c)            switch(c)
3383              {              {
# Line 3150  for (;;) Line 3397  for (;;)
3397          case OP_VSPACE:          case OP_VSPACE:
3398          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3399            {            {
3400            if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);            if (eptr >= md->end_subject)
3401                {
3402                SCHECK_PARTIAL();
3403                RRETURN(MATCH_NOMATCH);
3404                }
3405            GETCHARINC(c, eptr);            GETCHARINC(c, eptr);
3406            switch(c)            switch(c)
3407              {              {
# Line 3170  for (;;) Line 3421  for (;;)
3421          case OP_NOT_DIGIT:          case OP_NOT_DIGIT:
3422          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3423            {            {
3424            if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);            if (eptr >= md->end_subject)
3425                {
3426                SCHECK_PARTIAL();
3427                RRETURN(MATCH_NOMATCH);
3428                }
3429            GETCHARINC(c, eptr);            GETCHARINC(c, eptr);
3430            if (c < 128 && (md->ctypes[c] & ctype_digit) != 0)            if (c < 128 && (md->ctypes[c] & ctype_digit) != 0)
3431              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
# Line 3180  for (;;) Line 3435  for (;;)
3435          case OP_DIGIT:          case OP_DIGIT:
3436          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3437            {            {
3438            if (eptr >= md->end_subject ||            if (eptr >= md->end_subject)
3439               *eptr >= 128 || (md->ctypes[*eptr++] & ctype_digit) == 0)              {
3440                SCHECK_PARTIAL();
3441                RRETURN(MATCH_NOMATCH);
3442                }
3443              if (*eptr >= 128 || (md->ctypes[*eptr++] & ctype_digit) == 0)
3444              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
3445            /* 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 */
3446            }            }
# Line 3190  for (;;) Line 3449  for (;;)
3449          case OP_NOT_WHITESPACE:          case OP_NOT_WHITESPACE:
3450          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3451            {            {
3452            if (eptr >= md->end_subject ||            if (eptr >= md->end_subject)
3453               (*eptr < 128 && (md->ctypes[*eptr] & ctype_space) != 0))              {
3454                SCHECK_PARTIAL();
3455                RRETURN(MATCH_NOMATCH);
3456                }
3457              if (*eptr < 128 && (md->ctypes[*eptr] & ctype_space) != 0)
3458              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
3459            while (++eptr < md->end_subject && (*eptr & 0xc0) == 0x80);            while (++eptr < md->end_subject && (*eptr & 0xc0) == 0x80);
3460            }            }
# Line 3200  for (;;) Line 3463  for (;;)
3463          case OP_WHITESPACE:          case OP_WHITESPACE:
3464          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3465            {            {
3466            if (eptr >= md->end_subject ||            if (eptr >= md->end_subject)
3467               *eptr >= 128 || (md->ctypes[*eptr++] & ctype_space) == 0)              {
3468                SCHECK_PARTIAL();
3469                RRETURN(MATCH_NOMATCH);
3470                }
3471              if (*eptr >= 128 || (md->ctypes[*eptr++] & ctype_space) == 0)
3472              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
3473            /* 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 */
3474            }            }
# Line 3220  for (;;) Line 3487  for (;;)
3487          case OP_WORDCHAR:          case OP_WORDCHAR:
3488          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3489            {            {
3490            if (eptr >= md->end_subject ||            if (eptr >= md->end_subject)
3491               *eptr >= 128 || (md->ctypes[*eptr++] & ctype_word) == 0)              {
3492                SCHECK_PARTIAL();
3493                RRETURN(MATCH_NOMATCH);
3494                }
3495              if (*eptr >= 128 || (md->ctypes[*eptr++] & ctype_word) == 0)
3496              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
3497            /* 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 */
3498            }            }
# Line 3235  for (;;) Line 3506  for (;;)
3506  #endif     /* SUPPORT_UTF8 */  #endif     /* SUPPORT_UTF8 */
3507    
3508        /* Code for the non-UTF-8 case for minimum matching of operators other        /* Code for the non-UTF-8 case for minimum matching of operators other
3509        than OP_PROP and OP_NOTPROP. We can assume that there are the minimum        than OP_PROP and OP_NOTPROP. */
       number of bytes present, as this was tested above. */  
3510    
3511        switch(ctype)        switch(ctype)
3512          {          {
3513          case OP_ANY:          case OP_ANY:
3514          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3515            {            {
3516              if (eptr >= md->end_subject)
3517                {
3518                SCHECK_PARTIAL();
3519                RRETURN(MATCH_NOMATCH);
3520                }
3521            if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH);            if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH);
3522            eptr++;            eptr++;
3523            }            }
3524          break;          break;
3525    
3526          case OP_ALLANY:          case OP_ALLANY:
3527            if (eptr > md->end_subject - min)
3528              {
3529              SCHECK_PARTIAL();
3530              RRETURN(MATCH_NOMATCH);
3531              }
3532          eptr += min;          eptr += min;
3533          break;          break;
3534    
3535          case OP_ANYBYTE:          case OP_ANYBYTE:
3536            if (eptr > md->end_subject - min)
3537              {
3538              SCHECK_PARTIAL();
3539              RRETURN(MATCH_NOMATCH);
3540              }
3541          eptr += min;          eptr += min;
3542          break;          break;
3543    
         /* Because of the CRLF case, we can't assume the minimum number of  
         bytes are present in this case. */  
   
3544          case OP_ANYNL:          case OP_ANYNL:
3545          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3546            {            {
3547            if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);            if (eptr >= md->end_subject)
3548                {
3549                SCHECK_PARTIAL();
3550                RRETURN(MATCH_NOMATCH);
3551                }
3552            switch(*eptr++)            switch(*eptr++)
3553              {              {
3554              default: RRETURN(MATCH_NOMATCH);              default: RRETURN(MATCH_NOMATCH);
# Line 3284  for (;;) Line 3570  for (;;)
3570          case OP_NOT_HSPACE:          case OP_NOT_HSPACE:
3571          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3572            {            {
3573            if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);            if (eptr >= md->end_subject)
3574                {
3575                SCHECK_PARTIAL();
3576                RRETURN(MATCH_NOMATCH);
3577                }
3578            switch(*eptr++)            switch(*eptr++)
3579              {              {
3580              default: break;              default: break;
# Line 3299  for (;;) Line 3589  for (;;)
3589          case OP_HSPACE:          case OP_HSPACE:
3590          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3591            {            {
3592            if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);            if (eptr >= md->end_subject)
3593                {
3594                SCHECK_PARTIAL();
3595                RRETURN(MATCH_NOMATCH);
3596                }
3597            switch(*eptr++)            switch(*eptr++)
3598              {              {
3599              default: RRETURN(MATCH_NOMATCH);              default: RRETURN(MATCH_NOMATCH);
# Line 3314  for (;;) Line 3608  for (;;)
3608          case OP_NOT_VSPACE:          case OP_NOT_VSPACE:
3609          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3610            {            {
3611            if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);            if (eptr >= md->end_subject)
3612                {
3613                SCHECK_PARTIAL();
3614                RRETURN(MATCH_NOMATCH);
3615                }
3616            switch(*eptr++)            switch(*eptr++)
3617              {              {
3618              default: break;              default: break;
# Line 3331  for (;;) Line 3629  for (;;)
3629          case OP_VSPACE:          case OP_VSPACE:
3630          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3631            {            {
3632            if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);            if (eptr >= md->end_subject)
3633                {
3634                SCHECK_PARTIAL();
3635                RRETURN(MATCH_NOMATCH);
3636                }
3637            switch(*eptr++)            switch(*eptr++)
3638              {              {
3639              default: RRETURN(MATCH_NOMATCH);              default: RRETURN(MATCH_NOMATCH);
# Line 3347  for (;;) Line 3649  for (;;)
3649    
3650          case OP_NOT_DIGIT:          case OP_NOT_DIGIT:
3651          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3652              {
3653              if (eptr >= md->end_subject)
3654                {
3655                SCHECK_PARTIAL();
3656                RRETURN(MATCH_NOMATCH);
3657                }
3658            if ((md->ctypes[*eptr++] & ctype_digit) != 0) RRETURN(MATCH_NOMATCH);            if ((md->ctypes[*eptr++] & ctype_digit) != 0) RRETURN(MATCH_NOMATCH);
3659              }
3660          break;          break;
3661    
3662          case OP_DIGIT:          case OP_DIGIT:
3663          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3664              {
3665              if (eptr >= md->end_subject)
3666                {
3667                SCHECK_PARTIAL();
3668                RRETURN(MATCH_NOMATCH);
3669                }
3670            if ((md->ctypes[*eptr++] & ctype_digit) == 0) RRETURN(MATCH_NOMATCH);            if ((md->ctypes[*eptr++] & ctype_digit) == 0) RRETURN(MATCH_NOMATCH);
3671              }
3672          break;          break;
3673    
3674          case OP_NOT_WHITESPACE:          case OP_NOT_WHITESPACE:
3675          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3676              {
3677              if (eptr >= md->end_subject)
3678                {
3679                SCHECK_PARTIAL();
3680                RRETURN(MATCH_NOMATCH);
3681                }
3682            if ((md->ctypes[*eptr++] & ctype_space) != 0) RRETURN(MATCH_NOMATCH);            if ((md->ctypes[*eptr++] & ctype_space) != 0) RRETURN(MATCH_NOMATCH);
3683              }
3684          break;          break;
3685    
3686          case OP_WHITESPACE:          case OP_WHITESPACE:
3687          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3688              {
3689              if (eptr >= md->end_subject)
3690                {
3691                SCHECK_PARTIAL();
3692                RRETURN(MATCH_NOMATCH);
3693                }
3694            if ((md->ctypes[*eptr++] & ctype_space) == 0) RRETURN(MATCH_NOMATCH);            if ((md->ctypes[*eptr++] & ctype_space) == 0) RRETURN(MATCH_NOMATCH);
3695              }
3696          break;          break;
3697    
3698          case OP_NOT_WORDCHAR:          case OP_NOT_WORDCHAR:
3699          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3700              {
3701              if (eptr >= md->end_subject)
3702                {
3703                SCHECK_PARTIAL();
3704                RRETURN(MATCH_NOMATCH);
3705                }
3706            if ((md->ctypes[*eptr++] & ctype_word) != 0)            if ((md->ctypes[*eptr++] & ctype_word) != 0)
3707              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
3708              }
3709          break;          break;
3710    
3711          case OP_WORDCHAR:          case OP_WORDCHAR:
3712          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3713              {
3714              if (eptr >= md->end_subject)
3715                {
3716                SCHECK_PARTIAL();
3717                RRETURN(MATCH_NOMATCH);
3718                }
3719            if ((md->ctypes[*eptr++] & ctype_word) == 0)            if ((md->ctypes[*eptr++] & ctype_word) == 0)
3720              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
3721              }
3722          break;          break;
3723    
3724          default:          default:
# Line 3402  for (;;) Line 3746  for (;;)
3746              {              {
3747              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM36);              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM36);
3748              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3749              if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);              if (fi >= max) RRETURN(MATCH_NOMATCH);
3750                if (eptr >= md->end_subject)
3751                  {
3752                  SCHECK_PARTIAL();
3753                  RRETURN(MATCH_NOMATCH);
3754                  }
3755              GETCHARINC(c, eptr);              GETCHARINC(c, eptr);
3756              if (prop_fail_result) RRETURN(MATCH_NOMATCH);              if (prop_fail_result) RRETURN(MATCH_NOMATCH);
3757              }              }
# Line 3413  for (;;) Line 3762  for (;;)
3762              {              {
3763              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM37);              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM37);
3764              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3765              if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);              if (fi >= max) RRETURN(MATCH_NOMATCH);
3766                if (eptr >= md->end_subject)
3767                  {
3768                  SCHECK_PARTIAL();
3769                  RRETURN(MATCH_NOMATCH);
3770                  }
3771              GETCHARINC(c, eptr);              GETCHARINC(c, eptr);
3772              prop_chartype = UCD_CHARTYPE(c);              prop_chartype = UCD_CHARTYPE(c);
3773              if ((prop_chartype == ucp_Lu ||              if ((prop_chartype == ucp_Lu ||
# Line 3428  for (;;) Line 3782  for (;;)
3782              {              {
3783              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM38);              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM38);
3784              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3785              if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);              if (fi >= max) RRETURN(MATCH_NOMATCH);
3786                if (eptr >= md->end_subject)
3787                  {
3788                  SCHECK_PARTIAL();
3789                  RRETURN(MATCH_NOMATCH);
3790                  }
3791              GETCHARINC(c, eptr);              GETCHARINC(c, eptr);
3792              prop_category = UCD_CATEGORY(c);              prop_category = UCD_CATEGORY(c);
3793              if ((prop_category == prop_value) == prop_fail_result)              if ((prop_category == prop_value) == prop_fail_result)
# Line 3441  for (;;) Line 3800  for (;;)
3800              {              {
3801              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM39);              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM39);
3802              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3803              if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);              if (fi >= max) RRETURN(MATCH_NOMATCH);
3804                if (eptr >= md->end_subject)
3805                  {
3806                  SCHECK_PARTIAL();
3807                  RRETURN(MATCH_NOMATCH);
3808                  }
3809              GETCHARINC(c, eptr);              GETCHARINC(c, eptr);
3810              prop_chartype = UCD_CHARTYPE(c);              prop_chartype = UCD_CHARTYPE(c);
3811              if ((prop_chartype == prop_value) == prop_fail_result)              if ((prop_chartype == prop_value) == prop_fail_result)
# Line 3454  for (;;) Line 3818  for (;;)
3818              {              {
3819              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM40);              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM40);
3820              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3821              if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);              if (fi >= max) RRETURN(MATCH_NOMATCH);
3822                if (eptr >= md->end_subject)
3823                  {
3824                  SCHECK_PARTIAL();
3825                  RRETURN(MATCH_NOMATCH);
3826                  }
3827              GETCHARINC(c, eptr);              GETCHARINC(c, eptr);
3828              prop_script = UCD_SCRIPT(c);              prop_script = UCD_SCRIPT(c);
3829              if ((prop_script == prop_value) == prop_fail_result)              if ((prop_script == prop_value) == prop_fail_result)
# Line 3476  for (;;) Line 3845  for (;;)
3845            {            {
3846            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM41);            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM41);
3847            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3848            if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);            if (fi >= max) RRETURN(MATCH_NOMATCH);
3849              if (eptr >= md->end_subject)
3850                {
3851                SCHECK_PARTIAL();
3852                RRETURN(MATCH_NOMATCH);
3853                }
3854            GETCHARINCTEST(c, eptr);            GETCHARINCTEST(c, eptr);
3855            prop_category = UCD_CATEGORY(c);            prop_category = UCD_CATEGORY(c);
3856            if (prop_category == ucp_M) RRETURN(MATCH_NOMATCH);            if (prop_category == ucp_M) RRETURN(MATCH_NOMATCH);
3857            while (eptr < md->end_subject)            while (eptr < md->end_subject)
3858              {              {
3859              int len = 1;              int len = 1;
3860              if (!utf8) c = *eptr; else              if (!utf8) c = *eptr;
3861                {                else { GETCHARLEN(c, eptr, len); }
               GETCHARLEN(c, eptr, len);  
               }  
3862              prop_category = UCD_CATEGORY(c);              prop_category = UCD_CATEGORY(c);
3863              if (prop_category != ucp_M) break;              if (prop_category != ucp_M) break;
3864              eptr += len;              eptr += len;
# Line 3505  for (;;) Line 3877  for (;;)
3877            {            {
3878            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM42);            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM42);
3879            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3880            if (fi >= max || eptr >= md->end_subject ||            if (fi >= max) RRETURN(MATCH_NOMATCH);
3881                 (ctype == OP_ANY && IS_NEWLINE(eptr)))            if (eptr >= md->end_subject)
3882                {
3883                SCHECK_PARTIAL();
3884                RRETURN(MATCH_NOMATCH);
3885                }
3886              if (ctype == OP_ANY && IS_NEWLINE(eptr))
3887              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
   
3888            GETCHARINC(c, eptr);            GETCHARINC(c, eptr);
3889            switch(ctype)            switch(ctype)
3890              {              {
# Line 3664  for (;;) Line 4040  for (;;)
4040            {            {
4041            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM43);            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM43);
4042            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
4043            if (fi >= max || eptr >= md->end_subject ||            if (fi >= max) RRETURN(MATCH_NOMATCH);
4044                 (ctype == OP_ANY && IS_NEWLINE(eptr)))            if (eptr >= md->end_subject)
4045                {
4046                SCHECK_PARTIAL();
4047                RRETURN(MATCH_NOMATCH);
4048                }
4049              if (ctype == OP_ANY && IS_NEWLINE(eptr))
4050              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
   
4051            c = *eptr++;            c = *eptr++;
4052            switch(ctype)            switch(ctype)
4053              {              {
# Line 4450  const uschar *tables; Line 4830  const uschar *tables;
4830  const uschar *start_bits = NULL;  const uschar *start_bits = NULL;
4831  USPTR start_match = (USPTR)subject + start_offset;  USPTR start_match = (USPTR)subject + start_offset;
4832  USPTR end_subject;  USPTR end_subject;
4833    USPTR start_partial = NULL;
4834  USPTR req_byte_ptr = start_match - 1;  USPTR req_byte_ptr = start_match - 1;
4835    
4836  pcre_study_data internal_study;  pcre_study_data internal_study;
# Line 4533  md->jscript_compat = (re->options & PCRE Line 4914  md->jscript_compat = (re->options & PCRE
4914  md->notbol = (options & PCRE_NOTBOL) != 0;  md->notbol = (options & PCRE_NOTBOL) != 0;
4915  md->noteol = (options & PCRE_NOTEOL) != 0;  md->noteol = (options & PCRE_NOTEOL) != 0;
4916  md->notempty = (options & PCRE_NOTEMPTY) != 0;  md->notempty = (options & PCRE_NOTEMPTY) != 0;
4917  md->partial = (options & PCRE_PARTIAL) != 0;  md->partial = ((options & PCRE_PARTIAL_HARD) != 0)? 2 :
4918                  ((options & PCRE_PARTIAL_SOFT) != 0)? 1 : 0;
4919  md->hitend = FALSE;  md->hitend = FALSE;
4920    
4921  md->recursive = NULL;                   /* No recursion at top level */  md->recursive = NULL;                   /* No recursion at top level */
# Line 4607  else Line 4989  else
4989      }      }
4990    }    }
4991    
4992  /* Partial matching is supported only for a restricted set of regexes at the  /* Partial matching was originally supported only for a restricted set of
4993  moment. */  regexes; from release 8.00 there are no restrictions, but the bits are still
4994    defined (though never set). So there's no harm in leaving this code. */
4995    
4996  if (md->partial && (re->flags & PCRE_NOPARTIAL) != 0)  if (md->partial && (re->flags & PCRE_NOPARTIAL) != 0)
4997    return PCRE_ERROR_BADPARTIAL;    return PCRE_ERROR_BADPARTIAL;
# Line 4619  back the character offset. */ Line 5002  back the character offset. */
5002  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
5003  if (utf8 && (options & PCRE_NO_UTF8_CHECK) == 0)  if (utf8 && (options & PCRE_NO_UTF8_CHECK) == 0)
5004    {    {
5005    if (_pcre_valid_utf8((uschar *)subject, length) >= 0)    if (_pcre_valid_utf8((USPTR)subject, length) >= 0)
5006      return PCRE_ERROR_BADUTF8;      return PCRE_ERROR_BADUTF8;
5007    if (start_offset > 0 && start_offset < length)    if (start_offset > 0 && start_offset < length)
5008      {      {
5009      int tb = ((uschar *)subject)[start_offset];      int tb = ((USPTR)subject)[start_offset];
5010      if (tb > 127)      if (tb > 127)
5011        {        {
5012        tb &= 0xc0;        tb &= 0xc0;
# Line 4890  for(;;) Line 5273  for(;;)
5273        }        }
5274      }      }
5275    
5276    /* OK, we can now run the match. */    /* OK, we can now run the match. If "hitend" is set afterwards, remember the
5277      first starting point for which a partial match was found. */
5278    
5279    md->start_match_ptr = start_match;    md->start_match_ptr = start_match;
5280    md->match_call_count = 0;    md->match_call_count = 0;
5281    rc = match(start_match, md->start_code, start_match, 2, md, ims, NULL, 0, 0);    rc = match(start_match, md->start_code, start_match, 2, md, ims, NULL, 0, 0);
5282      if (md->hitend && start_partial == NULL) start_partial = start_match;
5283    
5284    switch(rc)    switch(rc)
5285      {      {
# Line 5030  if (using_temporary_offsets) Line 5415  if (using_temporary_offsets)
5415    (pcre_free)(md->offset_vector);    (pcre_free)(md->offset_vector);
5416    }    }
5417    
5418  if (rc != MATCH_NOMATCH)  if (rc != MATCH_NOMATCH && rc != PCRE_ERROR_PARTIAL)
5419    {    {
5420    DPRINTF((">>>> error: returning %d\n", rc));    DPRINTF((">>>> error: returning %d\n", rc));
5421    return rc;    return rc;
5422    }    }
5423  else if (md->partial && md->hitend)  else if (start_partial != NULL)
5424    {    {
5425    DPRINTF((">>>> returning PCRE_ERROR_PARTIAL\n"));    DPRINTF((">>>> returning PCRE_ERROR_PARTIAL\n"));
5426      if (offsetcount > 1)
5427        {
5428        offsets[0] = start_partial - (USPTR)subject;
5429        offsets[1] = end_subject - (USPTR)subject;
5430        }
5431    return PCRE_ERROR_PARTIAL;    return PCRE_ERROR_PARTIAL;
5432    }    }
5433  else  else

Legend:
Removed from v.403  
changed lines
  Added in v.428

  ViewVC Help
Powered by ViewVC 1.1.5