/[pcre]/code/trunk/pcre_compile.c
ViewVC logotype

Diff of /code/trunk/pcre_compile.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 178 by ph10, Wed Jun 13 08:44:34 2007 UTC revision 202 by ph10, Fri Aug 3 09:44:26 2007 UTC
# Line 42  POSSIBILITY OF SUCH DAMAGE. Line 42  POSSIBILITY OF SUCH DAMAGE.
42  supporting internal functions that are not used by other modules. */  supporting internal functions that are not used by other modules. */
43    
44    
45    #ifdef HAVE_CONFIG_H
46    #include <config.h>
47    #endif
48    
49  #define NLBLOCK cd             /* Block containing newline information */  #define NLBLOCK cd             /* Block containing newline information */
50  #define PSSTART start_pattern  /* Field containing processed string start */  #define PSSTART start_pattern  /* Field containing processed string start */
51  #define PSEND   end_pattern    /* Field containing processed string end */  #define PSEND   end_pattern    /* Field containing processed string end */
52    
   
53  #include "pcre_internal.h"  #include "pcre_internal.h"
54    
55    
# Line 62  used by pcretest. DEBUG is not defined w Line 65  used by pcretest. DEBUG is not defined w
65    
66  #define SETBIT(a,b) a[b/8] |= (1 << (b%8))  #define SETBIT(a,b) a[b/8] |= (1 << (b%8))
67    
68    /* Maximum length value to check against when making sure that the integer that
69    holds the compiled pattern length does not overflow. We make it a bit less than
70    INT_MAX to allow for adding in group terminating bytes, so that we don't have
71    to check them every time. */
72    
73    #define OFLOW_MAX (INT_MAX - 20)
74    
75    
76  /*************************************************  /*************************************************
77  *      Code parameters and static tables         *  *      Code parameters and static tables         *
# Line 120  static const short int escapes[] = { Line 130  static const short int escapes[] = {
130  /*  B8 */     0,     0,      0,       0,      0,   ']',    '=',    '-',  /*  B8 */     0,     0,      0,       0,      0,   ']',    '=',    '-',
131  /*  C0 */   '{',-ESC_A, -ESC_B,  -ESC_C, -ESC_D,-ESC_E,      0, -ESC_G,  /*  C0 */   '{',-ESC_A, -ESC_B,  -ESC_C, -ESC_D,-ESC_E,      0, -ESC_G,
132  /*  C8 */-ESC_H,     0,      0,       0,      0,     0,      0,      0,  /*  C8 */-ESC_H,     0,      0,       0,      0,     0,      0,      0,
133  /*  D0 */   '}',     0,      0,       0,      0,     0,      0, -ESC_P,  /*  D0 */   '}',     0, -ESC_K,       0,      0,     0,      0, -ESC_P,
134  /*  D8 */-ESC_Q,-ESC_R,      0,       0,      0,     0,      0,      0,  /*  D8 */-ESC_Q,-ESC_R,      0,       0,      0,     0,      0,      0,
135  /*  E0 */  '\\',     0, -ESC_S,       0,      0,-ESC_V, -ESC_W, -ESC_X,  /*  E0 */  '\\',     0, -ESC_S,       0,      0,-ESC_V, -ESC_W, -ESC_X,
136  /*  E8 */     0,-ESC_Z,      0,       0,      0,     0,      0,      0,  /*  E8 */     0,-ESC_Z,      0,       0,      0,     0,      0,      0,
# Line 203  static const char *error_texts[] = { Line 213  static const char *error_texts[] = {
213    "missing ) after comment",    "missing ) after comment",
214    "parentheses nested too deeply",  /** DEAD **/    "parentheses nested too deeply",  /** DEAD **/
215    /* 20 */    /* 20 */
216    "regular expression too large",    "regular expression is too large",
217    "failed to get memory",    "failed to get memory",
218    "unmatched parentheses",    "unmatched parentheses",
219    "internal error: code overflow",    "internal error: code overflow",
# Line 239  static const char *error_texts[] = { Line 249  static const char *error_texts[] = {
249    "subpattern name is too long (maximum " XSTRING(MAX_NAME_SIZE) " characters)",    "subpattern name is too long (maximum " XSTRING(MAX_NAME_SIZE) " characters)",
250    "too many named subpatterns (maximum " XSTRING(MAX_NAME_COUNT) ")",    "too many named subpatterns (maximum " XSTRING(MAX_NAME_COUNT) ")",
251    /* 50 */    /* 50 */
252    "repeated subpattern is too long",    "repeated subpattern is too long",    /** DEAD **/
253    "octal value is greater than \\377 (not in UTF-8 mode)",    "octal value is greater than \\377 (not in UTF-8 mode)",
254    "internal error: overran compiling workspace",    "internal error: overran compiling workspace",
255    "internal error: previously-checked referenced subpattern not found",    "internal error: previously-checked referenced subpattern not found",
# Line 379  static const unsigned char ebcdic_charta Line 389  static const unsigned char ebcdic_charta
389  /* Definition to allow mutual recursion */  /* Definition to allow mutual recursion */
390    
391  static BOOL  static BOOL
392    compile_regex(int, int, uschar **, const uschar **, int *, BOOL, BOOL, int,    compile_regex(int, int, uschar **, const uschar **, int *, BOOL, BOOL, int,
393      int *, int *, branch_chain *, compile_data *, int *);      int *, int *, branch_chain *, compile_data *, int *);
394    
395    
# Line 701  if (c == '{') Line 711  if (c == '{')
711      *negptr = TRUE;      *negptr = TRUE;
712      ptr++;      ptr++;
713      }      }
714    for (i = 0; i < sizeof(name) - 1; i++)    for (i = 0; i < (int)sizeof(name) - 1; i++)
715      {      {
716      c = *(++ptr);      c = *(++ptr);
717      if (c == 0) goto ERROR_RETURN;      if (c == 0) goto ERROR_RETURN;
# Line 1949  if (next >= 0) switch(op_code) Line 1959  if (next >= 0) switch(op_code)
1959    case OP_NOT_WORDCHAR:    case OP_NOT_WORDCHAR:
1960    return next <= 127 && (cd->ctypes[next] & ctype_word) != 0;    return next <= 127 && (cd->ctypes[next] & ctype_word) != 0;
1961    
1962      case OP_HSPACE:
1963      case OP_NOT_HSPACE:
1964      switch(next)
1965        {
1966        case 0x09:
1967        case 0x20:
1968        case 0xa0:
1969        case 0x1680:
1970        case 0x180e:
1971        case 0x2000:
1972        case 0x2001:
1973        case 0x2002:
1974        case 0x2003:
1975        case 0x2004:
1976        case 0x2005:
1977        case 0x2006:
1978        case 0x2007:
1979        case 0x2008:
1980        case 0x2009:
1981        case 0x200A:
1982        case 0x202f:
1983        case 0x205f:
1984        case 0x3000:
1985        return op_code != OP_HSPACE;
1986        default:
1987        return op_code == OP_HSPACE;
1988        }
1989    
1990      case OP_VSPACE:
1991      case OP_NOT_VSPACE:
1992      switch(next)
1993        {
1994        case 0x0a:
1995        case 0x0b:
1996        case 0x0c:
1997        case 0x0d:
1998        case 0x85:
1999        case 0x2028:
2000        case 0x2029:
2001        return op_code != OP_VSPACE;
2002        default:
2003        return op_code == OP_VSPACE;
2004        }
2005    
2006    default:    default:
2007    return FALSE;    return FALSE;
2008    }    }
# Line 1983  switch(op_code) Line 2037  switch(op_code)
2037      case ESC_W:      case ESC_W:
2038      return item <= 127 && (cd->ctypes[item] & ctype_word) != 0;      return item <= 127 && (cd->ctypes[item] & ctype_word) != 0;
2039    
2040        case ESC_h:
2041        case ESC_H:
2042        switch(item)
2043          {
2044          case 0x09:
2045          case 0x20:
2046          case 0xa0:
2047          case 0x1680:
2048          case 0x180e:
2049          case 0x2000:
2050          case 0x2001:
2051          case 0x2002:
2052          case 0x2003:
2053          case 0x2004:
2054          case 0x2005:
2055          case 0x2006:
2056          case 0x2007:
2057          case 0x2008:
2058          case 0x2009:
2059          case 0x200A:
2060          case 0x202f:
2061          case 0x205f:
2062          case 0x3000:
2063          return -next != ESC_h;
2064          default:
2065          return -next == ESC_h;
2066          }
2067    
2068        case ESC_v:
2069        case ESC_V:
2070        switch(item)
2071          {
2072          case 0x0a:
2073          case 0x0b:
2074          case 0x0c:
2075          case 0x0d:
2076          case 0x85:
2077          case 0x2028:
2078          case 0x2029:
2079          return -next != ESC_v;
2080          default:
2081          return -next == ESC_v;
2082          }
2083    
2084      default:      default:
2085      return FALSE;      return FALSE;
2086      }      }
2087    
2088    case OP_DIGIT:    case OP_DIGIT:
2089    return next == -ESC_D || next == -ESC_s || next == -ESC_W;    return next == -ESC_D || next == -ESC_s || next == -ESC_W ||
2090             next == -ESC_h || next == -ESC_v;
2091    
2092    case OP_NOT_DIGIT:    case OP_NOT_DIGIT:
2093    return next == -ESC_d;    return next == -ESC_d;
# Line 1997  switch(op_code) Line 2096  switch(op_code)
2096    return next == -ESC_S || next == -ESC_d || next == -ESC_w;    return next == -ESC_S || next == -ESC_d || next == -ESC_w;
2097    
2098    case OP_NOT_WHITESPACE:    case OP_NOT_WHITESPACE:
2099    return next == -ESC_s;    return next == -ESC_s || next == -ESC_h || next == -ESC_v;
2100    
2101      case OP_HSPACE:
2102      return next == -ESC_S || next == -ESC_H || next == -ESC_d || next == -ESC_w;
2103    
2104      case OP_NOT_HSPACE:
2105      return next == -ESC_h;
2106    
2107      /* Can't have \S in here because VT matches \S (Perl anomaly) */
2108      case OP_VSPACE:
2109      return next == -ESC_V || next == -ESC_d || next == -ESC_w;
2110    
2111      case OP_NOT_VSPACE:
2112      return next == -ESC_v;
2113    
2114    case OP_WORDCHAR:    case OP_WORDCHAR:
2115    return next == -ESC_W || next == -ESC_s;    return next == -ESC_W || next == -ESC_s || next == -ESC_h || next == -ESC_v;
2116    
2117    case OP_NOT_WORDCHAR:    case OP_NOT_WORDCHAR:
2118    return next == -ESC_w || next == -ESC_d;    return next == -ESC_w || next == -ESC_d;
# Line 2115  for (;; ptr++) Line 2227  for (;; ptr++)
2227    BOOL possessive_quantifier;    BOOL possessive_quantifier;
2228    BOOL is_quantifier;    BOOL is_quantifier;
2229    BOOL is_recurse;    BOOL is_recurse;
2230    BOOL reset_bracount;    BOOL reset_bracount;
2231    int class_charcount;    int class_charcount;
2232    int class_lastchar;    int class_lastchar;
2233    int newoptions;    int newoptions;
# Line 2153  for (;; ptr++) Line 2265  for (;; ptr++)
2265      */      */
2266    
2267      if (code < last_code) code = last_code;      if (code < last_code) code = last_code;
2268    
2269        /* Paranoid check for integer overflow */
2270    
2271        if (OFLOW_MAX - *lengthptr < code - last_code)
2272          {
2273          *errorcodeptr = ERR20;
2274          goto FAILED;
2275          }
2276    
2277      *lengthptr += code - last_code;      *lengthptr += code - last_code;
2278      DPRINTF(("length=%d added %d c=%c\n", *lengthptr, code - last_code, c));      DPRINTF(("length=%d added %d c=%c\n", *lengthptr, code - last_code, c));
2279    
# Line 2265  for (;; ptr++) Line 2386  for (;; ptr++)
2386      *ptrptr = ptr;      *ptrptr = ptr;
2387      if (lengthptr != NULL)      if (lengthptr != NULL)
2388        {        {
2389          if (OFLOW_MAX - *lengthptr < code - last_code)
2390            {
2391            *errorcodeptr = ERR20;
2392            goto FAILED;
2393            }
2394        *lengthptr += code - last_code;   /* To include callout length */        *lengthptr += code - last_code;   /* To include callout length */
2395        DPRINTF((">> end branch\n"));        DPRINTF((">> end branch\n"));
2396        }        }
# Line 2535  for (;; ptr++) Line 2661  for (;; ptr++)
2661    
2662              case ESC_E: /* Perl ignores an orphan \E */              case ESC_E: /* Perl ignores an orphan \E */
2663              continue;              continue;
2664    
2665              default:    /* Not recognized; fall through */              default:    /* Not recognized; fall through */
2666              break;      /* Need "default" setting to stop compiler warning. */              break;      /* Need "default" setting to stop compiler warning. */
2667              }              }
# Line 2544  for (;; ptr++) Line 2670  for (;; ptr++)
2670    
2671            else if (c == -ESC_d || c == -ESC_D || c == -ESC_w ||            else if (c == -ESC_d || c == -ESC_D || c == -ESC_w ||
2672                     c == -ESC_W || c == -ESC_s || c == -ESC_S) continue;                     c == -ESC_W || c == -ESC_s || c == -ESC_S) continue;
2673    
2674            /* We need to deal with \H, \h, \V, and \v in both phases because            /* We need to deal with \H, \h, \V, and \v in both phases because
2675            they use extra memory. */            they use extra memory. */
2676    
2677            if (-c == ESC_h)            if (-c == ESC_h)
2678              {              {
2679              SETBIT(classbits, 0x09); /* VT */              SETBIT(classbits, 0x09); /* VT */
2680              SETBIT(classbits, 0x20); /* SPACE */              SETBIT(classbits, 0x20); /* SPACE */
2681              SETBIT(classbits, 0xa0); /* NSBP */              SETBIT(classbits, 0xa0); /* NSBP */
2682  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
2683              if (utf8)              if (utf8)
2684                {                {
2685                class_utf8 = TRUE;                class_utf8 = TRUE;
2686                *class_utf8data++ = XCL_SINGLE;                *class_utf8data++ = XCL_SINGLE;
2687                class_utf8data += _pcre_ord2utf8(0x1680, class_utf8data);                class_utf8data += _pcre_ord2utf8(0x1680, class_utf8data);
2688                *class_utf8data++ = XCL_SINGLE;                *class_utf8data++ = XCL_SINGLE;
2689                class_utf8data += _pcre_ord2utf8(0x180e, class_utf8data);                class_utf8data += _pcre_ord2utf8(0x180e, class_utf8data);
2690                *class_utf8data++ = XCL_RANGE;                *class_utf8data++ = XCL_RANGE;
2691                class_utf8data += _pcre_ord2utf8(0x2000, class_utf8data);                class_utf8data += _pcre_ord2utf8(0x2000, class_utf8data);
2692                class_utf8data += _pcre_ord2utf8(0x200A, class_utf8data);                class_utf8data += _pcre_ord2utf8(0x200A, class_utf8data);
2693                *class_utf8data++ = XCL_SINGLE;                *class_utf8data++ = XCL_SINGLE;
2694                class_utf8data += _pcre_ord2utf8(0x202f, class_utf8data);                class_utf8data += _pcre_ord2utf8(0x202f, class_utf8data);
2695                *class_utf8data++ = XCL_SINGLE;                *class_utf8data++ = XCL_SINGLE;
2696                class_utf8data += _pcre_ord2utf8(0x205f, class_utf8data);                class_utf8data += _pcre_ord2utf8(0x205f, class_utf8data);
2697                *class_utf8data++ = XCL_SINGLE;                *class_utf8data++ = XCL_SINGLE;
2698                class_utf8data += _pcre_ord2utf8(0x3000, class_utf8data);                class_utf8data += _pcre_ord2utf8(0x3000, class_utf8data);
2699                }                }
2700  #endif  #endif
2701              continue;              continue;
2702              }              }
2703    
2704            if (-c == ESC_H)            if (-c == ESC_H)
2705              {              {
# Line 2581  for (;; ptr++) Line 2707  for (;; ptr++)
2707                {                {
2708                int x = 0xff;                int x = 0xff;
2709                switch (c)                switch (c)
2710                  {                  {
2711                  case 0x09/8: x ^= 1 << (0x09%8); break;                  case 0x09/8: x ^= 1 << (0x09%8); break;
2712                  case 0x20/8: x ^= 1 << (0x20%8); break;                  case 0x20/8: x ^= 1 << (0x20%8); break;
2713                  case 0xa0/8: x ^= 1 << (0xa0%8); break;                  case 0xa0/8: x ^= 1 << (0xa0%8); break;
2714                  default: break;                  default: break;
2715                  }                  }
2716                classbits[c] |= x;                classbits[c] |= x;
2717                }                }
2718    
2719  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
2720              if (utf8)              if (utf8)
2721                {                {
2722                class_utf8 = TRUE;                class_utf8 = TRUE;
2723                *class_utf8data++ = XCL_RANGE;                *class_utf8data++ = XCL_RANGE;
2724                class_utf8data += _pcre_ord2utf8(0x0100, class_utf8data);                class_utf8data += _pcre_ord2utf8(0x0100, class_utf8data);
2725                class_utf8data += _pcre_ord2utf8(0x167f, class_utf8data);                class_utf8data += _pcre_ord2utf8(0x167f, class_utf8data);
2726                *class_utf8data++ = XCL_RANGE;                *class_utf8data++ = XCL_RANGE;
2727                class_utf8data += _pcre_ord2utf8(0x1681, class_utf8data);                class_utf8data += _pcre_ord2utf8(0x1681, class_utf8data);
2728                class_utf8data += _pcre_ord2utf8(0x180d, class_utf8data);                class_utf8data += _pcre_ord2utf8(0x180d, class_utf8data);
2729                *class_utf8data++ = XCL_RANGE;                *class_utf8data++ = XCL_RANGE;
2730                class_utf8data += _pcre_ord2utf8(0x180f, class_utf8data);                class_utf8data += _pcre_ord2utf8(0x180f, class_utf8data);
2731                class_utf8data += _pcre_ord2utf8(0x1fff, class_utf8data);                class_utf8data += _pcre_ord2utf8(0x1fff, class_utf8data);
2732                *class_utf8data++ = XCL_RANGE;                *class_utf8data++ = XCL_RANGE;
2733                class_utf8data += _pcre_ord2utf8(0x200B, class_utf8data);                class_utf8data += _pcre_ord2utf8(0x200B, class_utf8data);
2734                class_utf8data += _pcre_ord2utf8(0x202e, class_utf8data);                class_utf8data += _pcre_ord2utf8(0x202e, class_utf8data);
2735                *class_utf8data++ = XCL_RANGE;                *class_utf8data++ = XCL_RANGE;
2736                class_utf8data += _pcre_ord2utf8(0x2030, class_utf8data);                class_utf8data += _pcre_ord2utf8(0x2030, class_utf8data);
2737                class_utf8data += _pcre_ord2utf8(0x205e, class_utf8data);                class_utf8data += _pcre_ord2utf8(0x205e, class_utf8data);
2738                *class_utf8data++ = XCL_RANGE;                *class_utf8data++ = XCL_RANGE;
2739                class_utf8data += _pcre_ord2utf8(0x2060, class_utf8data);                class_utf8data += _pcre_ord2utf8(0x2060, class_utf8data);
2740                class_utf8data += _pcre_ord2utf8(0x2fff, class_utf8data);                class_utf8data += _pcre_ord2utf8(0x2fff, class_utf8data);
2741                *class_utf8data++ = XCL_RANGE;                *class_utf8data++ = XCL_RANGE;
2742                class_utf8data += _pcre_ord2utf8(0x3001, class_utf8data);                class_utf8data += _pcre_ord2utf8(0x3001, class_utf8data);
2743                class_utf8data += _pcre_ord2utf8(0x7fffffff, class_utf8data);                class_utf8data += _pcre_ord2utf8(0x7fffffff, class_utf8data);
2744                }                }
2745  #endif  #endif
2746              continue;              continue;
2747              }              }
2748    
2749            if (-c == ESC_v)            if (-c == ESC_v)
2750              {              {
2751              SETBIT(classbits, 0x0a); /* LF */              SETBIT(classbits, 0x0a); /* LF */
2752              SETBIT(classbits, 0x0b); /* VT */              SETBIT(classbits, 0x0b); /* VT */
2753              SETBIT(classbits, 0x0c); /* FF */              SETBIT(classbits, 0x0c); /* FF */
2754              SETBIT(classbits, 0x0d); /* CR */              SETBIT(classbits, 0x0d); /* CR */
2755              SETBIT(classbits, 0x85); /* NEL */              SETBIT(classbits, 0x85); /* NEL */
2756  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
2757              if (utf8)              if (utf8)
2758                {                {
2759                class_utf8 = TRUE;                class_utf8 = TRUE;
2760                *class_utf8data++ = XCL_RANGE;                *class_utf8data++ = XCL_RANGE;
2761                class_utf8data += _pcre_ord2utf8(0x2028, class_utf8data);                class_utf8data += _pcre_ord2utf8(0x2028, class_utf8data);
2762                class_utf8data += _pcre_ord2utf8(0x2029, class_utf8data);                class_utf8data += _pcre_ord2utf8(0x2029, class_utf8data);
2763                }                }
2764  #endif  #endif
2765              continue;              continue;
2766              }              }
2767    
2768            if (-c == ESC_V)            if (-c == ESC_V)
2769              {              {
# Line 2645  for (;; ptr++) Line 2771  for (;; ptr++)
2771                {                {
2772                int x = 0xff;                int x = 0xff;
2773                switch (c)                switch (c)
2774                  {                  {
2775                  case 0x0a/8: x ^= 1 << (0x0a%8);                  case 0x0a/8: x ^= 1 << (0x0a%8);
2776                               x ^= 1 << (0x0b%8);                               x ^= 1 << (0x0b%8);
2777                               x ^= 1 << (0x0c%8);                               x ^= 1 << (0x0c%8);
2778                               x ^= 1 << (0x0d%8);                               x ^= 1 << (0x0d%8);
2779                               break;                               break;
2780                  case 0x85/8: x ^= 1 << (0x85%8); break;                  case 0x85/8: x ^= 1 << (0x85%8); break;
2781                  default: break;                  default: break;
2782                  }                  }
2783                classbits[c] |= x;                classbits[c] |= x;
2784                }                }
2785    
2786  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
2787              if (utf8)              if (utf8)
2788                {                {
2789                class_utf8 = TRUE;                class_utf8 = TRUE;
2790                *class_utf8data++ = XCL_RANGE;                *class_utf8data++ = XCL_RANGE;
2791                class_utf8data += _pcre_ord2utf8(0x0100, class_utf8data);                class_utf8data += _pcre_ord2utf8(0x0100, class_utf8data);
2792                class_utf8data += _pcre_ord2utf8(0x2027, class_utf8data);                class_utf8data += _pcre_ord2utf8(0x2027, class_utf8data);
2793                *class_utf8data++ = XCL_RANGE;                *class_utf8data++ = XCL_RANGE;
2794                class_utf8data += _pcre_ord2utf8(0x2029, class_utf8data);                class_utf8data += _pcre_ord2utf8(0x2029, class_utf8data);
2795                class_utf8data += _pcre_ord2utf8(0x7fffffff, class_utf8data);                class_utf8data += _pcre_ord2utf8(0x7fffffff, class_utf8data);
2796                }                }
2797  #endif  #endif
2798              continue;              continue;
2799              }              }
2800    
2801            /* We need to deal with \P and \p in both phases. */            /* We need to deal with \P and \p in both phases. */
2802    
# Line 2812  for (;; ptr++) Line 2938  for (;; ptr++)
2938              unsigned int origd = d;              unsigned int origd = d;
2939              while (get_othercase_range(&cc, origd, &occ, &ocd))              while (get_othercase_range(&cc, origd, &occ, &ocd))
2940                {                {
2941                if (occ >= (unsigned int)c &&                if (occ >= (unsigned int)c &&
2942                    ocd <= (unsigned int)d)                    ocd <= (unsigned int)d)
2943                  continue;                          /* Skip embedded ranges */                  continue;                          /* Skip embedded ranges */
2944    
2945                if (occ < (unsigned int)c  &&                if (occ < (unsigned int)c  &&
2946                    ocd >= (unsigned int)c - 1)      /* Extend the basic range */                    ocd >= (unsigned int)c - 1)      /* Extend the basic range */
2947                  {                                  /* if there is overlap,   */                  {                                  /* if there is overlap,   */
2948                  c = occ;                           /* noting that if occ < c */                  c = occ;                           /* noting that if occ < c */
2949                  continue;                          /* we can't have ocd > d  */                  continue;                          /* we can't have ocd > d  */
2950                  }                                  /* because a subrange is  */                  }                                  /* because a subrange is  */
2951                if (ocd > (unsigned int)d &&                if (ocd > (unsigned int)d &&
2952                    occ <= (unsigned int)d + 1)      /* always shorter than    */                    occ <= (unsigned int)d + 1)      /* always shorter than    */
2953                  {                                  /* the basic range.       */                  {                                  /* the basic range.       */
2954                  d = ocd;                  d = ocd;
# Line 3419  for (;; ptr++) Line 3545  for (;; ptr++)
3545          goto FAILED;          goto FAILED;
3546          }          }
3547    
       /* This is a paranoid check to stop integer overflow later on */  
   
       if (len > MAX_DUPLENGTH)  
         {  
         *errorcodeptr = ERR50;  
         goto FAILED;  
         }  
   
3548        /* If the maximum repeat count is unlimited, find the end of the bracket        /* If the maximum repeat count is unlimited, find the end of the bracket
3549        by scanning through from the start, and compute the offset back to it        by scanning through from the start, and compute the offset back to it
3550        from the current code pointer. There may be an OP_OPT setting following        from the current code pointer. There may be an OP_OPT setting following
# Line 3515  for (;; ptr++) Line 3633  for (;; ptr++)
3633          if (repeat_min > 1)          if (repeat_min > 1)
3634            {            {
3635            /* In the pre-compile phase, we don't actually do the replication. We            /* In the pre-compile phase, we don't actually do the replication. We
3636            just adjust the length as if we had. */            just adjust the length as if we had. Do some paranoid checks for
3637              potential integer overflow. */
3638    
3639            if (lengthptr != NULL)            if (lengthptr != NULL)
3640              *lengthptr += (repeat_min - 1)*length_prevgroup;              {
3641                int delta = (repeat_min - 1)*length_prevgroup;
3642                if ((double)(repeat_min - 1)*(double)length_prevgroup >
3643                                                                (double)INT_MAX ||
3644                    OFLOW_MAX - *lengthptr < delta)
3645                  {
3646                  *errorcodeptr = ERR20;
3647                  goto FAILED;
3648                  }
3649                *lengthptr += delta;
3650                }
3651    
3652            /* This is compiling for real */            /* This is compiling for real */
3653    
# Line 3556  for (;; ptr++) Line 3685  for (;; ptr++)
3685          /* In the pre-compile phase, we don't actually do the replication. We          /* In the pre-compile phase, we don't actually do the replication. We
3686          just adjust the length as if we had. For each repetition we must add 1          just adjust the length as if we had. For each repetition we must add 1
3687          to the length for BRAZERO and for all but the last repetition we must          to the length for BRAZERO and for all but the last repetition we must
3688          add 2 + 2*LINKSIZE to allow for the nesting that occurs. */          add 2 + 2*LINKSIZE to allow for the nesting that occurs. Do some
3689            paranoid checks to avoid integer overflow. */
3690    
3691          if (lengthptr != NULL && repeat_max > 0)          if (lengthptr != NULL && repeat_max > 0)
3692            *lengthptr += repeat_max * (length_prevgroup + 1 + 2 + 2*LINK_SIZE) -            {
3693              2 - 2*LINK_SIZE;  /* Last one doesn't nest */            int delta = repeat_max * (length_prevgroup + 1 + 2 + 2*LINK_SIZE) -
3694                          2 - 2*LINK_SIZE;   /* Last one doesn't nest */
3695              if ((double)repeat_max *
3696                    (double)(length_prevgroup + 1 + 2 + 2*LINK_SIZE)
3697                      > (double)INT_MAX ||
3698                  OFLOW_MAX - *lengthptr < delta)
3699                {
3700                *errorcodeptr = ERR20;
3701                goto FAILED;
3702                }
3703              *lengthptr += delta;
3704              }
3705    
3706          /* This is compiling for real */          /* This is compiling for real */
3707    
# Line 3721  for (;; ptr++) Line 3862  for (;; ptr++)
3862      skipbytes = 0;      skipbytes = 0;
3863      bravalue = OP_CBRA;      bravalue = OP_CBRA;
3864      save_hwm = cd->hwm;      save_hwm = cd->hwm;
3865      reset_bracount = FALSE;      reset_bracount = FALSE;
3866    
3867      if (*(++ptr) == '?')      if (*(++ptr) == '?')
3868        {        {
# Line 3746  for (;; ptr++) Line 3887  for (;; ptr++)
3887          /* ------------------------------------------------------------ */          /* ------------------------------------------------------------ */
3888          case '|':                 /* Reset capture count for each branch */          case '|':                 /* Reset capture count for each branch */
3889          reset_bracount = TRUE;          reset_bracount = TRUE;
3890          /* Fall through */          /* Fall through */
3891    
3892          /* ------------------------------------------------------------ */          /* ------------------------------------------------------------ */
3893          case ':':                 /* Non-capturing bracket */          case ':':                 /* Non-capturing bracket */
# Line 4447  for (;; ptr++) Line 4588  for (;; ptr++)
4588           errorcodeptr,                 /* Where to put an error message */           errorcodeptr,                 /* Where to put an error message */
4589           (bravalue == OP_ASSERTBACK ||           (bravalue == OP_ASSERTBACK ||
4590            bravalue == OP_ASSERTBACK_NOT), /* TRUE if back assert */            bravalue == OP_ASSERTBACK_NOT), /* TRUE if back assert */
4591           reset_bracount,               /* True if (?| group */           reset_bracount,               /* True if (?| group */
4592           skipbytes,                    /* Skip over bracket number */           skipbytes,                    /* Skip over bracket number */
4593           &subfirstbyte,                /* For possible first char */           &subfirstbyte,                /* For possible first char */
4594           &subreqbyte,                  /* For possible last char */           &subreqbyte,                  /* For possible last char */
# Line 4522  for (;; ptr++) Line 4663  for (;; ptr++)
4663    
4664      if (lengthptr != NULL)      if (lengthptr != NULL)
4665        {        {
4666          if (OFLOW_MAX - *lengthptr < length_prevgroup - 2 - 2*LINK_SIZE)
4667            {
4668            *errorcodeptr = ERR20;
4669            goto FAILED;
4670            }
4671        *lengthptr += length_prevgroup - 2 - 2*LINK_SIZE;        *lengthptr += length_prevgroup - 2 - 2*LINK_SIZE;
4672        code++;        code++;
4673        PUTINC(code, 0, 1 + LINK_SIZE);        PUTINC(code, 0, 1 + LINK_SIZE);
# Line 4807  Arguments: Line 4953  Arguments:
4953    ptrptr         -> the address of the current pattern pointer    ptrptr         -> the address of the current pattern pointer
4954    errorcodeptr   -> pointer to error code variable    errorcodeptr   -> pointer to error code variable
4955    lookbehind     TRUE if this is a lookbehind assertion    lookbehind     TRUE if this is a lookbehind assertion
4956    reset_bracount TRUE to reset the count for each branch    reset_bracount TRUE to reset the count for each branch
4957    skipbytes      skip this many bytes at start (for brackets and OP_COND)    skipbytes      skip this many bytes at start (for brackets and OP_COND)
4958    firstbyteptr   place to put the first required character, or a negative number    firstbyteptr   place to put the first required character, or a negative number
4959    reqbyteptr     place to put the last required character, or a negative number    reqbyteptr     place to put the last required character, or a negative number
# Line 4821  Returns:         TRUE on success Line 4967  Returns:         TRUE on success
4967    
4968  static BOOL  static BOOL
4969  compile_regex(int options, int oldims, uschar **codeptr, const uschar **ptrptr,  compile_regex(int options, int oldims, uschar **codeptr, const uschar **ptrptr,
4970    int *errorcodeptr, BOOL lookbehind, BOOL reset_bracount, int skipbytes,    int *errorcodeptr, BOOL lookbehind, BOOL reset_bracount, int skipbytes,
4971    int *firstbyteptr, int *reqbyteptr, branch_chain *bcptr, compile_data *cd,    int *firstbyteptr, int *reqbyteptr, branch_chain *bcptr, compile_data *cd,
4972    int *lengthptr)    int *lengthptr)
4973  {  {
4974  const uschar *ptr = *ptrptr;  const uschar *ptr = *ptrptr;
# Line 4867  orig_bracount = max_bracount = cd->braco Line 5013  orig_bracount = max_bracount = cd->braco
5013  for (;;)  for (;;)
5014    {    {
5015    /* For a (?| group, reset the capturing bracket count so that each branch    /* For a (?| group, reset the capturing bracket count so that each branch
5016    uses the same numbers. */    uses the same numbers. */
5017    
5018    if (reset_bracount) cd->bracount = orig_bracount;    if (reset_bracount) cd->bracount = orig_bracount;
5019    
5020    /* Handle a change of ims options at the start of the branch */    /* Handle a change of ims options at the start of the branch */
5021    
5022    if ((options & PCRE_IMS) != oldims)    if ((options & PCRE_IMS) != oldims)
# Line 4899  for (;;) Line 5045  for (;;)
5045      *ptrptr = ptr;      *ptrptr = ptr;
5046      return FALSE;      return FALSE;
5047      }      }
5048    
5049    /* Keep the highest bracket count in case (?| was used and some branch    /* Keep the highest bracket count in case (?| was used and some branch
5050    has fewer than the rest. */    has fewer than the rest. */
5051    
5052    if (cd->bracount > max_bracount) max_bracount = cd->bracount;    if (cd->bracount > max_bracount) max_bracount = cd->bracount;
5053    
5054    /* In the real compile phase, there is some post-processing to be done. */    /* In the real compile phase, there is some post-processing to be done. */
# Line 5006  for (;;) Line 5152  for (;;)
5152        *code++ = oldims;        *code++ = oldims;
5153        length += 2;        length += 2;
5154        }        }
5155    
5156      /* Retain the highest bracket number, in case resetting was used. */      /* Retain the highest bracket number, in case resetting was used. */
5157    
5158      cd->bracount = max_bracount;      cd->bracount = max_bracount;
5159    
5160      /* Set values to pass back */      /* Set values to pass back */
# Line 5017  for (;;) Line 5163  for (;;)
5163      *ptrptr = ptr;      *ptrptr = ptr;
5164      *firstbyteptr = firstbyte;      *firstbyteptr = firstbyte;
5165      *reqbyteptr = reqbyte;      *reqbyteptr = reqbyte;
5166      if (lengthptr != NULL) *lengthptr += length;      if (lengthptr != NULL)
5167          {
5168          if (OFLOW_MAX - *lengthptr < length)
5169            {
5170            *errorcodeptr = ERR20;
5171            return FALSE;
5172            }
5173          *lengthptr += length;
5174          }
5175      return TRUE;      return TRUE;
5176      }      }
5177    
# Line 5485  outside can help speed up starting point Line 5639  outside can help speed up starting point
5639  code = cworkspace;  code = cworkspace;
5640  *code = OP_BRA;  *code = OP_BRA;
5641  (void)compile_regex(cd->external_options, cd->external_options & PCRE_IMS,  (void)compile_regex(cd->external_options, cd->external_options & PCRE_IMS,
5642    &code, &ptr, &errorcode, FALSE, FALSE, 0, &firstbyte, &reqbyte, NULL, cd,    &code, &ptr, &errorcode, FALSE, FALSE, 0, &firstbyte, &reqbyte, NULL, cd,
5643    &length);    &length);
5644  if (errorcode != 0) goto PCRE_EARLY_ERROR_RETURN;  if (errorcode != 0) goto PCRE_EARLY_ERROR_RETURN;
5645    

Legend:
Removed from v.178  
changed lines
  Added in v.202

  ViewVC Help
Powered by ViewVC 1.1.5