/[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 117 by ph10, Fri Mar 9 15:59:06 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 58  used by pcretest. DEBUG is not defined w Line 61  used by pcretest. DEBUG is not defined w
61  #endif  #endif
62    
63    
64    /* Macro for setting individual bits in class bitmaps. */
65    
66    #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         *
78  *************************************************/  *************************************************/
# Line 87  static const short int escapes[] = { Line 102  static const short int escapes[] = {
102       0,      0,      0,      0,      0,      0,      0,      0,   /* 0 - 7 */       0,      0,      0,      0,      0,      0,      0,      0,   /* 0 - 7 */
103       0,      0,    ':',    ';',    '<',    '=',    '>',    '?',   /* 8 - ? */       0,      0,    ':',    ';',    '<',    '=',    '>',    '?',   /* 8 - ? */
104     '@', -ESC_A, -ESC_B, -ESC_C, -ESC_D, -ESC_E,      0, -ESC_G,   /* @ - G */     '@', -ESC_A, -ESC_B, -ESC_C, -ESC_D, -ESC_E,      0, -ESC_G,   /* @ - G */
105       0,      0,      0,      0,      0,      0,      0,      0,   /* H - O */  -ESC_H,      0,      0, -ESC_K,      0,      0,      0,      0,   /* H - O */
106  -ESC_P, -ESC_Q, -ESC_R, -ESC_S,      0,      0,      0, -ESC_W,   /* P - W */  -ESC_P, -ESC_Q, -ESC_R, -ESC_S,      0,      0, -ESC_V, -ESC_W,   /* P - W */
107  -ESC_X,      0, -ESC_Z,    '[',   '\\',    ']',    '^',    '_',   /* X - _ */  -ESC_X,      0, -ESC_Z,    '[',   '\\',    ']',    '^',    '_',   /* X - _ */
108     '`',      7, -ESC_b,      0, -ESC_d,  ESC_e,  ESC_f,      0,   /* ` - g */     '`',      7, -ESC_b,      0, -ESC_d,  ESC_e,  ESC_f,      0,   /* ` - g */
109       0,      0,      0, -ESC_k,      0,      0,  ESC_n,      0,   /* h - o */  -ESC_h,      0,      0, -ESC_k,      0,      0,  ESC_n,      0,   /* h - o */
110  -ESC_p,      0,  ESC_r, -ESC_s,  ESC_tee,    0,      0, -ESC_w,   /* p - w */  -ESC_p,      0,  ESC_r, -ESC_s,  ESC_tee,    0, -ESC_v, -ESC_w,   /* p - w */
111       0,      0, -ESC_z                                            /* x - z */       0,      0, -ESC_z                                            /* x - z */
112  };  };
113    
# Line 106  static const short int escapes[] = { Line 121  static const short int escapes[] = {
121  /*  70 */     0,     0,      0,       0,      0,     0,      0,      0,  /*  70 */     0,     0,      0,       0,      0,     0,      0,      0,
122  /*  78 */     0,   '`',    ':',     '#',    '@',  '\'',    '=',    '"',  /*  78 */     0,   '`',    ':',     '#',    '@',  '\'',    '=',    '"',
123  /*  80 */     0,     7, -ESC_b,       0, -ESC_d, ESC_e,  ESC_f,      0,  /*  80 */     0,     7, -ESC_b,       0, -ESC_d, ESC_e,  ESC_f,      0,
124  /*  88 */     0,     0,      0,     '{',      0,     0,      0,      0,  /*  88 */-ESC_h,     0,      0,     '{',      0,     0,      0,      0,
125  /*  90 */     0,     0, -ESC_k,     'l',      0, ESC_n,      0, -ESC_p,  /*  90 */     0,     0, -ESC_k,     'l',      0, ESC_n,      0, -ESC_p,
126  /*  98 */     0, ESC_r,      0,     '}',      0,     0,      0,      0,  /*  98 */     0, ESC_r,      0,     '}',      0,     0,      0,      0,
127  /*  A0 */     0,   '~', -ESC_s, ESC_tee,      0,     0, -ESC_w,      0,  /*  A0 */     0,   '~', -ESC_s, ESC_tee,      0,-ESC_v, -ESC_w,      0,
128  /*  A8 */     0,-ESC_z,      0,       0,      0,   '[',      0,      0,  /*  A8 */     0,-ESC_z,      0,       0,      0,   '[',      0,      0,
129  /*  B0 */     0,     0,      0,       0,      0,     0,      0,      0,  /*  B0 */     0,     0,      0,       0,      0,     0,      0,      0,
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 */     0,     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,     0, -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,
137  /*  F0 */     0,     0,      0,       0,      0,     0,      0,      0,  /*  F0 */     0,     0,      0,       0,      0,     0,      0,      0,
138  /*  F8 */     0,     0,      0,       0,      0,     0,      0,      0  /*  F8 */     0,     0,      0,       0,      0,     0,      0,      0
# Line 198  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 208  static const char *error_texts[] = { Line 223  static const char *error_texts[] = {
223    "malformed number or name after (?(",    "malformed number or name after (?(",
224    "conditional group contains more than two branches",    "conditional group contains more than two branches",
225    "assertion expected after (?(",    "assertion expected after (?(",
226    "(?R or (?digits must be followed by )",    "(?R or (?[+-]digits must be followed by )",
227    /* 30 */    /* 30 */
228    "unknown POSIX class name",    "unknown POSIX class name",
229    "POSIX collating elements are not supported",    "POSIX collating elements are not supported",
# Line 234  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 242  static const char *error_texts[] = { Line 257  static const char *error_texts[] = {
257    /* 55 */    /* 55 */
258    "repeating a DEFINE group is not allowed",    "repeating a DEFINE group is not allowed",
259    "inconsistent NEWLINE options",    "inconsistent NEWLINE options",
260    "\\g is not followed by an (optionally braced) non-zero number"    "\\g is not followed by a braced name or an optionally braced non-zero number",
261      "(?+ or (?- or (?(+ or (?(- must be followed by a non-zero number"
262  };  };
263    
264    
# Line 373  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, int, int *,    compile_regex(int, int, uschar **, const uschar **, int *, BOOL, BOOL, int,
393      int *, branch_chain *, compile_data *, int *);      int *, int *, branch_chain *, compile_data *, int *);
394    
395    
396    
# Line 452  else Line 468  else
468    
469      /* \g must be followed by a number, either plain or braced. If positive, it      /* \g must be followed by a number, either plain or braced. If positive, it
470      is an absolute backreference. If negative, it is a relative backreference.      is an absolute backreference. If negative, it is a relative backreference.
471      This is a Perl 5.10 feature. */      This is a Perl 5.10 feature. Perl 5.10 also supports \g{name} as a
472        reference to a named group. This is part of Perl's movement towards a
473        unified syntax for back references. As this is synonymous with \k{name}, we
474        fudge it up by pretending it really was \k. */
475    
476      case 'g':      case 'g':
477      if (ptr[1] == '{')      if (ptr[1] == '{')
478        {        {
479          const uschar *p;
480          for (p = ptr+2; *p != 0 && *p != '}'; p++)
481            if (*p != '-' && (digitab[*p] & ctype_digit) == 0) break;
482          if (*p != 0 && *p != '}')
483            {
484            c = -ESC_k;
485            break;
486            }
487        braced = TRUE;        braced = TRUE;
488        ptr++;        ptr++;
489        }        }
# Line 684  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 1370  for (code = first_significant_code(code Line 1397  for (code = first_significant_code(code
1397    
1398    c = *code;    c = *code;
1399    
1400      /* Groups with zero repeats can of course be empty; skip them. */
1401    
1402      if (c == OP_BRAZERO || c == OP_BRAMINZERO)
1403        {
1404        code += _pcre_OP_lengths[c];
1405        do code += GET(code, 1); while (*code == OP_ALT);
1406        c = *code;
1407        continue;
1408        }
1409    
1410      /* For other groups, scan the branches. */
1411    
1412    if (c == OP_BRA || c == OP_CBRA || c == OP_ONCE)    if (c == OP_BRA || c == OP_CBRA || c == OP_ONCE)
1413      {      {
1414      BOOL empty_branch;      BOOL empty_branch;
# Line 1386  for (code = first_significant_code(code Line 1425  for (code = first_significant_code(code
1425        }        }
1426      while (*code == OP_ALT);      while (*code == OP_ALT);
1427      if (!empty_branch) return FALSE;   /* All branches are non-empty */      if (!empty_branch) return FALSE;   /* All branches are non-empty */
1428        c = *code;
     /* Move past the KET and fudge things so that the increment in the "for"  
     above has no effect. */  
   
     c = OP_END;  
     code += 1 + LINK_SIZE - _pcre_OP_lengths[c];  
1429      continue;      continue;
1430      }      }
1431    
# Line 1925  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 1959  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 1973  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 2091  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;
2231    int class_charcount;    int class_charcount;
2232    int class_lastchar;    int class_lastchar;
2233    int newoptions;    int newoptions;
2234    int recno;    int recno;
2235      int refsign;
2236    int skipbytes;    int skipbytes;
2237    int subreqbyte;    int subreqbyte;
2238    int subfirstbyte;    int subfirstbyte;
# Line 2127  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 2239  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 2519  for (;; ptr++) Line 2671  for (;; ptr++)
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
2675              they use extra memory. */
2676    
2677              if (-c == ESC_h)
2678                {
2679                SETBIT(classbits, 0x09); /* VT */
2680                SETBIT(classbits, 0x20); /* SPACE */
2681                SETBIT(classbits, 0xa0); /* NSBP */
2682    #ifdef SUPPORT_UTF8
2683                if (utf8)
2684                  {
2685                  class_utf8 = TRUE;
2686                  *class_utf8data++ = XCL_SINGLE;
2687                  class_utf8data += _pcre_ord2utf8(0x1680, class_utf8data);
2688                  *class_utf8data++ = XCL_SINGLE;
2689                  class_utf8data += _pcre_ord2utf8(0x180e, class_utf8data);
2690                  *class_utf8data++ = XCL_RANGE;
2691                  class_utf8data += _pcre_ord2utf8(0x2000, class_utf8data);
2692                  class_utf8data += _pcre_ord2utf8(0x200A, class_utf8data);
2693                  *class_utf8data++ = XCL_SINGLE;
2694                  class_utf8data += _pcre_ord2utf8(0x202f, class_utf8data);
2695                  *class_utf8data++ = XCL_SINGLE;
2696                  class_utf8data += _pcre_ord2utf8(0x205f, class_utf8data);
2697                  *class_utf8data++ = XCL_SINGLE;
2698                  class_utf8data += _pcre_ord2utf8(0x3000, class_utf8data);
2699                  }
2700    #endif
2701                continue;
2702                }
2703    
2704              if (-c == ESC_H)
2705                {
2706                for (c = 0; c < 32; c++)
2707                  {
2708                  int x = 0xff;
2709                  switch (c)
2710                    {
2711                    case 0x09/8: x ^= 1 << (0x09%8); break;
2712                    case 0x20/8: x ^= 1 << (0x20%8); break;
2713                    case 0xa0/8: x ^= 1 << (0xa0%8); break;
2714                    default: break;
2715                    }
2716                  classbits[c] |= x;
2717                  }
2718    
2719    #ifdef SUPPORT_UTF8
2720                if (utf8)
2721                  {
2722                  class_utf8 = TRUE;
2723                  *class_utf8data++ = XCL_RANGE;
2724                  class_utf8data += _pcre_ord2utf8(0x0100, class_utf8data);
2725                  class_utf8data += _pcre_ord2utf8(0x167f, class_utf8data);
2726                  *class_utf8data++ = XCL_RANGE;
2727                  class_utf8data += _pcre_ord2utf8(0x1681, class_utf8data);
2728                  class_utf8data += _pcre_ord2utf8(0x180d, class_utf8data);
2729                  *class_utf8data++ = XCL_RANGE;
2730                  class_utf8data += _pcre_ord2utf8(0x180f, class_utf8data);
2731                  class_utf8data += _pcre_ord2utf8(0x1fff, class_utf8data);
2732                  *class_utf8data++ = XCL_RANGE;
2733                  class_utf8data += _pcre_ord2utf8(0x200B, class_utf8data);
2734                  class_utf8data += _pcre_ord2utf8(0x202e, class_utf8data);
2735                  *class_utf8data++ = XCL_RANGE;
2736                  class_utf8data += _pcre_ord2utf8(0x2030, class_utf8data);
2737                  class_utf8data += _pcre_ord2utf8(0x205e, class_utf8data);
2738                  *class_utf8data++ = XCL_RANGE;
2739                  class_utf8data += _pcre_ord2utf8(0x2060, class_utf8data);
2740                  class_utf8data += _pcre_ord2utf8(0x2fff, class_utf8data);
2741                  *class_utf8data++ = XCL_RANGE;
2742                  class_utf8data += _pcre_ord2utf8(0x3001, class_utf8data);
2743                  class_utf8data += _pcre_ord2utf8(0x7fffffff, class_utf8data);
2744                  }
2745    #endif
2746                continue;
2747                }
2748    
2749              if (-c == ESC_v)
2750                {
2751                SETBIT(classbits, 0x0a); /* LF */
2752                SETBIT(classbits, 0x0b); /* VT */
2753                SETBIT(classbits, 0x0c); /* FF */
2754                SETBIT(classbits, 0x0d); /* CR */
2755                SETBIT(classbits, 0x85); /* NEL */
2756    #ifdef SUPPORT_UTF8
2757                if (utf8)
2758                  {
2759                  class_utf8 = TRUE;
2760                  *class_utf8data++ = XCL_RANGE;
2761                  class_utf8data += _pcre_ord2utf8(0x2028, class_utf8data);
2762                  class_utf8data += _pcre_ord2utf8(0x2029, class_utf8data);
2763                  }
2764    #endif
2765                continue;
2766                }
2767    
2768              if (-c == ESC_V)
2769                {
2770                for (c = 0; c < 32; c++)
2771                  {
2772                  int x = 0xff;
2773                  switch (c)
2774                    {
2775                    case 0x0a/8: x ^= 1 << (0x0a%8);
2776                                 x ^= 1 << (0x0b%8);
2777                                 x ^= 1 << (0x0c%8);
2778                                 x ^= 1 << (0x0d%8);
2779                                 break;
2780                    case 0x85/8: x ^= 1 << (0x85%8); break;
2781                    default: break;
2782                    }
2783                  classbits[c] |= x;
2784                  }
2785    
2786    #ifdef SUPPORT_UTF8
2787                if (utf8)
2788                  {
2789                  class_utf8 = TRUE;
2790                  *class_utf8data++ = XCL_RANGE;
2791                  class_utf8data += _pcre_ord2utf8(0x0100, class_utf8data);
2792                  class_utf8data += _pcre_ord2utf8(0x2027, class_utf8data);
2793                  *class_utf8data++ = XCL_RANGE;
2794                  class_utf8data += _pcre_ord2utf8(0x2029, class_utf8data);
2795                  class_utf8data += _pcre_ord2utf8(0x7fffffff, class_utf8data);
2796                  }
2797    #endif
2798                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    
2803  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
# Line 2659  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 >= c && ocd <= d) continue;  /* Skip embedded ranges */                if (occ >= (unsigned int)c &&
2942                      ocd <= (unsigned int)d)
2943                    continue;                          /* Skip embedded ranges */
2944    
2945                if (occ < c  && ocd >= c - 1)        /* Extend the basic range */                if (occ < (unsigned int)c  &&
2946                      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 > d && occ <= d + 1)         /* always shorter than    */                if (ocd > (unsigned int)d &&
2952                      occ <= (unsigned int)d + 1)      /* always shorter than    */
2953                  {                                  /* the basic range.       */                  {                                  /* the basic range.       */
2954                  d = ocd;                  d = ocd;
2955                  continue;                  continue;
# Line 3262  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 3358  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 3399  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 3564  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;
3866    
3867      if (*(++ptr) == '?')      if (*(++ptr) == '?')
3868        {        {
# Line 3586  for (;; ptr++) Line 3885  for (;; ptr++)
3885    
3886    
3887          /* ------------------------------------------------------------ */          /* ------------------------------------------------------------ */
3888            case '|':                 /* Reset capture count for each branch */
3889            reset_bracount = TRUE;
3890            /* Fall through */
3891    
3892            /* ------------------------------------------------------------ */
3893          case ':':                 /* Non-capturing bracket */          case ':':                 /* Non-capturing bracket */
3894          bravalue = OP_BRA;          bravalue = OP_BRA;
3895          ptr++;          ptr++;
# Line 3621  for (;; ptr++) Line 3925  for (;; ptr++)
3925    
3926          code[1+LINK_SIZE] = OP_CREF;          code[1+LINK_SIZE] = OP_CREF;
3927          skipbytes = 3;          skipbytes = 3;
3928            refsign = -1;
3929    
3930          /* Check for a test for recursion in a named group. */          /* Check for a test for recursion in a named group. */
3931    
# Line 3644  for (;; ptr++) Line 3949  for (;; ptr++)
3949            terminator = '\'';            terminator = '\'';
3950            ptr++;            ptr++;
3951            }            }
3952          else terminator = 0;          else
3953              {
3954              terminator = 0;
3955              if (ptr[1] == '-' || ptr[1] == '+') refsign = *(++ptr);
3956              }
3957    
3958          /* We now expect to read a name; any thing else is an error */          /* We now expect to read a name; any thing else is an error */
3959    
# Line 3680  for (;; ptr++) Line 3989  for (;; ptr++)
3989          if (lengthptr != NULL) break;          if (lengthptr != NULL) break;
3990    
3991          /* In the real compile we do the work of looking for the actual          /* In the real compile we do the work of looking for the actual
3992          reference. */          reference. If the string started with "+" or "-" we require the rest to
3993            be digits, in which case recno will be set. */
3994    
3995            if (refsign > 0)
3996              {
3997              if (recno <= 0)
3998                {
3999                *errorcodeptr = ERR58;
4000                goto FAILED;
4001                }
4002              if (refsign == '-')
4003                {
4004                recno = cd->bracount - recno + 1;
4005                if (recno <= 0)
4006                  {
4007                  *errorcodeptr = ERR15;
4008                  goto FAILED;
4009                  }
4010                }
4011              else recno += cd->bracount;
4012              PUT2(code, 2+LINK_SIZE, recno);
4013              break;
4014              }
4015    
4016            /* Otherwise (did not start with "+" or "-"), start by looking for the
4017            name. */
4018    
4019          slot = cd->name_table;          slot = cd->name_table;
4020          for (i = 0; i < cd->names_found; i++)          for (i = 0; i < cd->names_found; i++)
# Line 3999  for (;; ptr++) Line 4333  for (;; ptr++)
4333    
4334    
4335          /* ------------------------------------------------------------ */          /* ------------------------------------------------------------ */
4336            case '-': case '+':
4337          case '0': case '1': case '2': case '3': case '4':   /* Recursion or */          case '0': case '1': case '2': case '3': case '4':   /* Recursion or */
4338          case '5': case '6': case '7': case '8': case '9':   /* subroutine */          case '5': case '6': case '7': case '8': case '9':   /* subroutine */
4339            {            {
4340            const uschar *called;            const uschar *called;
4341    
4342              if ((refsign = *ptr) == '+') ptr++;
4343              else if (refsign == '-')
4344                {
4345                if ((digitab[ptr[1]] & ctype_digit) == 0)
4346                  goto OTHER_CHAR_AFTER_QUERY;
4347                ptr++;
4348                }
4349    
4350            recno = 0;            recno = 0;
4351            while((digitab[*ptr] & ctype_digit) != 0)            while((digitab[*ptr] & ctype_digit) != 0)
4352              recno = recno * 10 + *ptr++ - '0';              recno = recno * 10 + *ptr++ - '0';
4353    
4354            if (*ptr != ')')            if (*ptr != ')')
4355              {              {
4356              *errorcodeptr = ERR29;              *errorcodeptr = ERR29;
4357              goto FAILED;              goto FAILED;
4358              }              }
4359    
4360              if (refsign == '-')
4361                {
4362                if (recno == 0)
4363                  {
4364                  *errorcodeptr = ERR58;
4365                  goto FAILED;
4366                  }
4367                recno = cd->bracount - recno + 1;
4368                if (recno <= 0)
4369                  {
4370                  *errorcodeptr = ERR15;
4371                  goto FAILED;
4372                  }
4373                }
4374              else if (refsign == '+')
4375                {
4376                if (recno == 0)
4377                  {
4378                  *errorcodeptr = ERR58;
4379                  goto FAILED;
4380                  }
4381                recno += cd->bracount;
4382                }
4383    
4384            /* Come here from code above that handles a named recursion */            /* Come here from code above that handles a named recursion */
4385    
4386            HANDLE_RECURSION:            HANDLE_RECURSION:
# Line 4084  for (;; ptr++) Line 4453  for (;; ptr++)
4453    
4454          /* ------------------------------------------------------------ */          /* ------------------------------------------------------------ */
4455          default:              /* Other characters: check option setting */          default:              /* Other characters: check option setting */
4456            OTHER_CHAR_AFTER_QUERY:
4457          set = unset = 0;          set = unset = 0;
4458          optset = &set;          optset = &set;
4459    
# Line 4218  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 */
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 4234  for (;; ptr++) Line 4605  for (;; ptr++)
4605      is on the bracket. */      is on the bracket. */
4606    
4607      /* If this is a conditional bracket, check that there are no more than      /* If this is a conditional bracket, check that there are no more than
4608      two branches in the group, or just one if it's a DEFINE group. */      two branches in the group, or just one if it's a DEFINE group. We do this
4609        in the real compile phase, not in the pre-pass, where the whole group may
4610        not be available. */
4611    
4612      if (bravalue == OP_COND)      if (bravalue == OP_COND && lengthptr == NULL)
4613        {        {
4614        uschar *tc = code;        uschar *tc = code;
4615        int condcount = 0;        int condcount = 0;
# Line 4290  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 4396  for (;; ptr++) Line 4774  for (;; ptr++)
4774        zerofirstbyte = firstbyte;        zerofirstbyte = firstbyte;
4775        zeroreqbyte = reqbyte;        zeroreqbyte = reqbyte;
4776    
4777        /* \k<name> or \k'name' is a back reference by name (Perl syntax) */        /* \k<name> or \k'name' is a back reference by name (Perl syntax).
4778          We also support \k{name} (.NET syntax) */
4779    
4780        if (-c == ESC_k && (ptr[1] == '<' || ptr[1] == '\''))        if (-c == ESC_k && (ptr[1] == '<' || ptr[1] == '\'' || ptr[1] == '{'))
4781          {          {
4782          is_recurse = FALSE;          is_recurse = FALSE;
4783          terminator = (*(++ptr) == '<')? '>' : '\'';          terminator = (*(++ptr) == '<')? '>' : (*ptr == '\'')? '\'' : '}';
4784          goto NAMED_REF_OR_RECURSE;          goto NAMED_REF_OR_RECURSE;
4785          }          }
4786    
# Line 4567  This function is used during the pre-com Line 4946  This function is used during the pre-com
4946  out the amount of memory needed, as well as during the real compile phase. The  out the amount of memory needed, as well as during the real compile phase. The
4947  value of lengthptr distinguishes the two phases.  value of lengthptr distinguishes the two phases.
4948    
4949  Argument:  Arguments:
4950    options        option bits, including any changes for this subpattern    options        option bits, including any changes for this subpattern
4951    oldims         previous settings of ims option bits    oldims         previous settings of ims option bits
4952    codeptr        -> the address of the current code pointer    codeptr        -> the address of the current code pointer
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
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 4587  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, int skipbytes, int *firstbyteptr,    int *errorcodeptr, BOOL lookbehind, BOOL reset_bracount, int skipbytes,
4971    int *reqbyteptr, branch_chain *bcptr, compile_data *cd, int *lengthptr)    int *firstbyteptr, int *reqbyteptr, branch_chain *bcptr, compile_data *cd,
4972      int *lengthptr)
4973  {  {
4974  const uschar *ptr = *ptrptr;  const uschar *ptr = *ptrptr;
4975  uschar *code = *codeptr;  uschar *code = *codeptr;
# Line 4598  uschar *reverse_count = NULL; Line 4979  uschar *reverse_count = NULL;
4979  int firstbyte, reqbyte;  int firstbyte, reqbyte;
4980  int branchfirstbyte, branchreqbyte;  int branchfirstbyte, branchreqbyte;
4981  int length;  int length;
4982    int orig_bracount;
4983    int max_bracount;
4984  branch_chain bc;  branch_chain bc;
4985    
4986  bc.outer = bcptr;  bc.outer = bcptr;
# Line 4626  code += 1 + LINK_SIZE + skipbytes; Line 5009  code += 1 + LINK_SIZE + skipbytes;
5009    
5010  /* Loop for each alternative branch */  /* Loop for each alternative branch */
5011    
5012    orig_bracount = max_bracount = cd->bracount;
5013  for (;;)  for (;;)
5014    {    {
5015      /* For a (?| group, reset the capturing bracket count so that each branch
5016      uses the same numbers. */
5017    
5018      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 4657  for (;;) Line 5046  for (;;)
5046      return FALSE;      return FALSE;
5047      }      }
5048    
5049      /* Keep the highest bracket count in case (?| was used and some branch
5050      has fewer than the rest. */
5051    
5052      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. */
5055    
5056    if (lengthptr == NULL)    if (lengthptr == NULL)
# Line 4720  for (;;) Line 5114  for (;;)
5114        }        }
5115      }      }
5116    
5117    /* Reached end of expression, either ')' or end of pattern. Go back through    /* Reached end of expression, either ')' or end of pattern. In the real
5118    the alternative branches and reverse the chain of offsets, with the field in    compile phase, go back through the alternative branches and reverse the chain
5119    the BRA item now becoming an offset to the first alternative. If there are    of offsets, with the field in the BRA item now becoming an offset to the
5120    no alternatives, it points to the end of the group. The length in the    first alternative. If there are no alternatives, it points to the end of the
5121    terminating ket is always the length of the whole bracketed item. If any of    group. The length in the terminating ket is always the length of the whole
5122    the ims options were changed inside the group, compile a resetting op-code    bracketed item. If any of the ims options were changed inside the group,
5123    following, except at the very end of the pattern. Return leaving the pointer    compile a resetting op-code following, except at the very end of the pattern.
5124    at the terminating char. */    Return leaving the pointer at the terminating char. */
5125    
5126    if (*ptr != '|')    if (*ptr != '|')
5127      {      {
5128      int branch_length = code - last_branch;      if (lengthptr == NULL)
     do  
5129        {        {
5130        int prev_length = GET(last_branch, 1);        int branch_length = code - last_branch;
5131        PUT(last_branch, 1, branch_length);        do
5132        branch_length = prev_length;          {
5133        last_branch -= branch_length;          int prev_length = GET(last_branch, 1);
5134            PUT(last_branch, 1, branch_length);
5135            branch_length = prev_length;
5136            last_branch -= branch_length;
5137            }
5138          while (branch_length > 0);
5139        }        }
     while (branch_length > 0);  
5140    
5141      /* Fill in the ket */      /* Fill in the ket */
5142    
# Line 4756  for (;;) Line 5153  for (;;)
5153        length += 2;        length += 2;
5154        }        }
5155    
5156        /* Retain the highest bracket number, in case resetting was used. */
5157    
5158        cd->bracount = max_bracount;
5159    
5160      /* Set values to pass back */      /* Set values to pass back */
5161    
5162      *codeptr = code;      *codeptr = code;
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    
5178    /* Another branch follows; insert an "or" node. Its length field points back    /* Another branch follows. In the pre-compile phase, we can move the code
5179      pointer back to where it was for the start of the first branch. (That is,
5180      pretend that each branch is the only one.)
5181    
5182      In the real compile phase, insert an ALT node. Its length field points back
5183    to the previous branch while the bracket remains open. At the end the chain    to the previous branch while the bracket remains open. At the end the chain
5184    is reversed. It's done like this so that the start of the bracket has a    is reversed. It's done like this so that the start of the bracket has a
5185    zero offset until it is closed, making it possible to detect recursion. */    zero offset until it is closed, making it possible to detect recursion. */
5186    
5187    *code = OP_ALT;    if (lengthptr != NULL)
5188    PUT(code, 1, code - last_branch);      {
5189    bc.current = last_branch = code;      code = *codeptr + 1 + LINK_SIZE + skipbytes;
5190    code += 1 + LINK_SIZE;      length += 1 + LINK_SIZE;
5191        }
5192      else
5193        {
5194        *code = OP_ALT;
5195        PUT(code, 1, code - last_branch);
5196        bc.current = last_branch = code;
5197        code += 1 + LINK_SIZE;
5198        }
5199    
5200    ptr++;    ptr++;
   length += 1 + LINK_SIZE;  
5201    }    }
5202  /* Control never reaches here */  /* Control never reaches here */
5203  }  }
# Line 5043  Returns: pointer to compiled data Line 5464  Returns: pointer to compiled data
5464                  with errorptr and erroroffset set                  with errorptr and erroroffset set
5465  */  */
5466    
5467  PCRE_DATA_SCOPE pcre *  PCRE_EXP_DEFN pcre *
5468  pcre_compile(const char *pattern, int options, const char **errorptr,  pcre_compile(const char *pattern, int options, const char **errorptr,
5469    int *erroroffset, const unsigned char *tables)    int *erroroffset, const unsigned char *tables)
5470  {  {
# Line 5051  return pcre_compile2(pattern, options, N Line 5472  return pcre_compile2(pattern, options, N
5472  }  }
5473    
5474    
5475  PCRE_DATA_SCOPE pcre *  PCRE_EXP_DEFN pcre *
5476  pcre_compile2(const char *pattern, int options, int *errorcodeptr,  pcre_compile2(const char *pattern, int options, int *errorcodeptr,
5477    const char **errorptr, int *erroroffset, const unsigned char *tables)    const char **errorptr, int *erroroffset, const unsigned char *tables)
5478  {  {
# Line 5100  if (errorcodeptr != NULL) *errorcodeptr Line 5521  if (errorcodeptr != NULL) *errorcodeptr
5521  if (erroroffset == NULL)  if (erroroffset == NULL)
5522    {    {
5523    errorcode = ERR16;    errorcode = ERR16;
5524    goto PCRE_EARLY_ERROR_RETURN;    goto PCRE_EARLY_ERROR_RETURN2;
5525    }    }
5526    
5527  *erroroffset = 0;  *erroroffset = 0;
# Line 5113  if (utf8 && (options & PCRE_NO_UTF8_CHEC Line 5534  if (utf8 && (options & PCRE_NO_UTF8_CHEC
5534       (*erroroffset = _pcre_valid_utf8((uschar *)pattern, -1)) >= 0)       (*erroroffset = _pcre_valid_utf8((uschar *)pattern, -1)) >= 0)
5535    {    {
5536    errorcode = ERR44;    errorcode = ERR44;
5537    goto PCRE_UTF8_ERROR_RETURN;    goto PCRE_EARLY_ERROR_RETURN2;
5538    }    }
5539  #else  #else
5540  if ((options & PCRE_UTF8) != 0)  if ((options & PCRE_UTF8) != 0)
# Line 5138  cd->cbits = tables + cbits_offset; Line 5559  cd->cbits = tables + cbits_offset;
5559  cd->ctypes = tables + ctypes_offset;  cd->ctypes = tables + ctypes_offset;
5560    
5561  /* Handle different types of newline. The three bits give seven cases. The  /* Handle different types of newline. The three bits give seven cases. The
5562  current code allows for fixed one- or two-byte sequences, plus "any". */  current code allows for fixed one- or two-byte sequences, plus "any" and
5563    "anycrlf". */
5564    
5565  switch (options & (PCRE_NEWLINE_CRLF | PCRE_NEWLINE_ANY))  switch (options & (PCRE_NEWLINE_CRLF | PCRE_NEWLINE_ANY))
5566    {    {
# Line 5148  switch (options & (PCRE_NEWLINE_CRLF | P Line 5570  switch (options & (PCRE_NEWLINE_CRLF | P
5570    case PCRE_NEWLINE_CR+    case PCRE_NEWLINE_CR+
5571         PCRE_NEWLINE_LF: newline = ('\r' << 8) | '\n'; break;         PCRE_NEWLINE_LF: newline = ('\r' << 8) | '\n'; break;
5572    case PCRE_NEWLINE_ANY: newline = -1; break;    case PCRE_NEWLINE_ANY: newline = -1; break;
5573      case PCRE_NEWLINE_ANYCRLF: newline = -2; break;
5574    default: errorcode = ERR56; goto PCRE_EARLY_ERROR_RETURN;    default: errorcode = ERR56; goto PCRE_EARLY_ERROR_RETURN;
5575    }    }
5576    
5577  if (newline < 0)  if (newline == -2)
5578      {
5579      cd->nltype = NLTYPE_ANYCRLF;
5580      }
5581    else if (newline < 0)
5582    {    {
5583    cd->nltype = NLTYPE_ANY;    cd->nltype = NLTYPE_ANY;
5584    }    }
# Line 5212  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, 0, &firstbyte, &reqbyte, NULL, cd, &length);    &code, &ptr, &errorcode, FALSE, FALSE, 0, &firstbyte, &reqbyte, NULL, cd,
5643      &length);
5644  if (errorcode != 0) goto PCRE_EARLY_ERROR_RETURN;  if (errorcode != 0) goto PCRE_EARLY_ERROR_RETURN;
5645    
5646  DPRINTF(("end pre-compile: length=%d workspace=%d\n", length,  DPRINTF(("end pre-compile: length=%d workspace=%d\n", length,
# Line 5280  ptr = (const uschar *)pattern; Line 5708  ptr = (const uschar *)pattern;
5708  code = (uschar *)codestart;  code = (uschar *)codestart;
5709  *code = OP_BRA;  *code = OP_BRA;
5710  (void)compile_regex(re->options, re->options & PCRE_IMS, &code, &ptr,  (void)compile_regex(re->options, re->options & PCRE_IMS, &code, &ptr,
5711    &errorcode, FALSE, 0, &firstbyte, &reqbyte, NULL, cd, NULL);    &errorcode, FALSE, FALSE, 0, &firstbyte, &reqbyte, NULL, cd, NULL);
5712  re->top_bracket = cd->bracount;  re->top_bracket = cd->bracount;
5713  re->top_backref = cd->top_backref;  re->top_backref = cd->top_backref;
5714    
# Line 5325  if (errorcode != 0) Line 5753  if (errorcode != 0)
5753    (pcre_free)(re);    (pcre_free)(re);
5754    PCRE_EARLY_ERROR_RETURN:    PCRE_EARLY_ERROR_RETURN:
5755    *erroroffset = ptr - (const uschar *)pattern;    *erroroffset = ptr - (const uschar *)pattern;
5756  #ifdef SUPPORT_UTF8    PCRE_EARLY_ERROR_RETURN2:
   PCRE_UTF8_ERROR_RETURN:  
 #endif  
5757    *errorptr = error_texts[errorcode];    *errorptr = error_texts[errorcode];
5758    if (errorcodeptr != NULL) *errorcodeptr = errorcode;    if (errorcodeptr != NULL) *errorcodeptr = errorcode;
5759    return NULL;    return NULL;

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

webmaster@exim.org
ViewVC Help
Powered by ViewVC 1.1.12