/[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 97 by ph10, Mon Mar 5 12:36:47 2007 UTC revision 208 by ph10, Mon Aug 6 15:23:29 2007 UTC
# Line 6  Line 6 
6  and semantics are as close as possible to those of the Perl 5 language.  and semantics are as close as possible to those of the Perl 5 language.
7    
8                         Written by Philip Hazel                         Written by Philip Hazel
9             Copyright (c) 1997-2006 University of Cambridge             Copyright (c) 1997-2007 University of Cambridge
10    
11  -----------------------------------------------------------------------------  -----------------------------------------------------------------------------
12  Redistribution and use in source and binary forms, with or without  Redistribution and use in source and binary forms, with or without
# 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 1246  for (;;) Line 1273  for (;;)
1273    else    else
1274      {      {
1275      code += _pcre_OP_lengths[c];      code += _pcre_OP_lengths[c];
1276    #ifdef SUPPORT_UTF8
1277      if (utf8) switch(c)      if (utf8) switch(c)
1278        {        {
1279        case OP_CHAR:        case OP_CHAR:
# Line 1266  for (;;) Line 1294  for (;;)
1294        if (code[-1] >= 0xc0) code += _pcre_utf8_table4[code[-1] & 0x3f];        if (code[-1] >= 0xc0) code += _pcre_utf8_table4[code[-1] & 0x3f];
1295        break;        break;
1296        }        }
1297    #endif
1298      }      }
1299    }    }
1300  }  }
# Line 1309  for (;;) Line 1338  for (;;)
1338    else    else
1339      {      {
1340      code += _pcre_OP_lengths[c];      code += _pcre_OP_lengths[c];
1341    #ifdef SUPPORT_UTF8
1342      if (utf8) switch(c)      if (utf8) switch(c)
1343        {        {
1344        case OP_CHAR:        case OP_CHAR:
# Line 1329  for (;;) Line 1359  for (;;)
1359        if (code[-1] >= 0xc0) code += _pcre_utf8_table4[code[-1] & 0x3f];        if (code[-1] >= 0xc0) code += _pcre_utf8_table4[code[-1] & 0x3f];
1360        break;        break;
1361        }        }
1362    #endif
1363      }      }
1364    }    }
1365  }  }
# Line 1366  for (code = first_significant_code(code Line 1397  for (code = first_significant_code(code
1397    
1398    c = *code;    c = *code;
1399    
1400    if (c == OP_BRA || c == OP_CBRA || c == OP_ONCE)    /* 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 || c == OP_COND)
1413      {      {
1414      BOOL empty_branch;      BOOL empty_branch;
1415      if (GET(code, 1) == 0) return TRUE;    /* Hit unclosed bracket */      if (GET(code, 1) == 0) return TRUE;    /* Hit unclosed bracket */
# Line 1382  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 1921  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 1955  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 1969  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 2087  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 2123  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 2235  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 2297  for (;; ptr++) Line 2453  for (;; ptr++)
2453        goto FAILED;        goto FAILED;
2454        }        }
2455    
2456      /* If the first character is '^', set the negation flag and skip it. */      /* If the first character is '^', set the negation flag and skip it. Also,
2457        if the first few characters (either before or after ^) are \Q\E or \E we
2458        skip them too. This makes for compatibility with Perl. */
2459    
2460      if ((c = *(++ptr)) == '^')      negate_class = FALSE;
2461        for (;;)
2462        {        {
       negate_class = TRUE;  
2463        c = *(++ptr);        c = *(++ptr);
2464        }        if (c == '\\')
2465      else          {
2466        {          if (ptr[1] == 'E') ptr++;
2467        negate_class = FALSE;            else if (strncmp((const char *)ptr+1, "Q\\E", 3) == 0) ptr += 3;
2468                else break;
2469            }
2470          else if (!negate_class && c == '^')
2471            negate_class = TRUE;
2472          else break;
2473        }        }
2474    
2475      /* Keep a count of chars with values < 256 so that we can optimize the case      /* Keep a count of chars with values < 256 so that we can optimize the case
# Line 2447  for (;; ptr++) Line 2610  for (;; ptr++)
2610        of the specials, which just set a flag. The sequence \b is a special        of the specials, which just set a flag. The sequence \b is a special
2611        case. Inside a class (and only there) it is treated as backspace.        case. Inside a class (and only there) it is treated as backspace.
2612        Elsewhere it marks a word boundary. Other escapes have preset maps ready        Elsewhere it marks a word boundary. Other escapes have preset maps ready
2613        to or into the one we are building. We assume they have more than one        to 'or' into the one we are building. We assume they have more than one
2614        character in them, so set class_charcount bigger than one. */        character in them, so set class_charcount bigger than one. */
2615    
2616        if (c == '\\')        if (c == '\\')
# Line 2515  for (;; ptr++) Line 2678  for (;; ptr++)
2678            else if (c == -ESC_d || c == -ESC_D || c == -ESC_w ||            else if (c == -ESC_d || c == -ESC_D || c == -ESC_w ||
2679                     c == -ESC_W || c == -ESC_s || c == -ESC_S) continue;                     c == -ESC_W || c == -ESC_s || c == -ESC_S) continue;
2680    
2681              /* We need to deal with \H, \h, \V, and \v in both phases because
2682              they use extra memory. */
2683    
2684              if (-c == ESC_h)
2685                {
2686                SETBIT(classbits, 0x09); /* VT */
2687                SETBIT(classbits, 0x20); /* SPACE */
2688                SETBIT(classbits, 0xa0); /* NSBP */
2689    #ifdef SUPPORT_UTF8
2690                if (utf8)
2691                  {
2692                  class_utf8 = TRUE;
2693                  *class_utf8data++ = XCL_SINGLE;
2694                  class_utf8data += _pcre_ord2utf8(0x1680, class_utf8data);
2695                  *class_utf8data++ = XCL_SINGLE;
2696                  class_utf8data += _pcre_ord2utf8(0x180e, class_utf8data);
2697                  *class_utf8data++ = XCL_RANGE;
2698                  class_utf8data += _pcre_ord2utf8(0x2000, class_utf8data);
2699                  class_utf8data += _pcre_ord2utf8(0x200A, class_utf8data);
2700                  *class_utf8data++ = XCL_SINGLE;
2701                  class_utf8data += _pcre_ord2utf8(0x202f, class_utf8data);
2702                  *class_utf8data++ = XCL_SINGLE;
2703                  class_utf8data += _pcre_ord2utf8(0x205f, class_utf8data);
2704                  *class_utf8data++ = XCL_SINGLE;
2705                  class_utf8data += _pcre_ord2utf8(0x3000, class_utf8data);
2706                  }
2707    #endif
2708                continue;
2709                }
2710    
2711              if (-c == ESC_H)
2712                {
2713                for (c = 0; c < 32; c++)
2714                  {
2715                  int x = 0xff;
2716                  switch (c)
2717                    {
2718                    case 0x09/8: x ^= 1 << (0x09%8); break;
2719                    case 0x20/8: x ^= 1 << (0x20%8); break;
2720                    case 0xa0/8: x ^= 1 << (0xa0%8); break;
2721                    default: break;
2722                    }
2723                  classbits[c] |= x;
2724                  }
2725    
2726    #ifdef SUPPORT_UTF8
2727                if (utf8)
2728                  {
2729                  class_utf8 = TRUE;
2730                  *class_utf8data++ = XCL_RANGE;
2731                  class_utf8data += _pcre_ord2utf8(0x0100, class_utf8data);
2732                  class_utf8data += _pcre_ord2utf8(0x167f, class_utf8data);
2733                  *class_utf8data++ = XCL_RANGE;
2734                  class_utf8data += _pcre_ord2utf8(0x1681, class_utf8data);
2735                  class_utf8data += _pcre_ord2utf8(0x180d, class_utf8data);
2736                  *class_utf8data++ = XCL_RANGE;
2737                  class_utf8data += _pcre_ord2utf8(0x180f, class_utf8data);
2738                  class_utf8data += _pcre_ord2utf8(0x1fff, class_utf8data);
2739                  *class_utf8data++ = XCL_RANGE;
2740                  class_utf8data += _pcre_ord2utf8(0x200B, class_utf8data);
2741                  class_utf8data += _pcre_ord2utf8(0x202e, class_utf8data);
2742                  *class_utf8data++ = XCL_RANGE;
2743                  class_utf8data += _pcre_ord2utf8(0x2030, class_utf8data);
2744                  class_utf8data += _pcre_ord2utf8(0x205e, class_utf8data);
2745                  *class_utf8data++ = XCL_RANGE;
2746                  class_utf8data += _pcre_ord2utf8(0x2060, class_utf8data);
2747                  class_utf8data += _pcre_ord2utf8(0x2fff, class_utf8data);
2748                  *class_utf8data++ = XCL_RANGE;
2749                  class_utf8data += _pcre_ord2utf8(0x3001, class_utf8data);
2750                  class_utf8data += _pcre_ord2utf8(0x7fffffff, class_utf8data);
2751                  }
2752    #endif
2753                continue;
2754                }
2755    
2756              if (-c == ESC_v)
2757                {
2758                SETBIT(classbits, 0x0a); /* LF */
2759                SETBIT(classbits, 0x0b); /* VT */
2760                SETBIT(classbits, 0x0c); /* FF */
2761                SETBIT(classbits, 0x0d); /* CR */
2762                SETBIT(classbits, 0x85); /* NEL */
2763    #ifdef SUPPORT_UTF8
2764                if (utf8)
2765                  {
2766                  class_utf8 = TRUE;
2767                  *class_utf8data++ = XCL_RANGE;
2768                  class_utf8data += _pcre_ord2utf8(0x2028, class_utf8data);
2769                  class_utf8data += _pcre_ord2utf8(0x2029, class_utf8data);
2770                  }
2771    #endif
2772                continue;
2773                }
2774    
2775              if (-c == ESC_V)
2776                {
2777                for (c = 0; c < 32; c++)
2778                  {
2779                  int x = 0xff;
2780                  switch (c)
2781                    {
2782                    case 0x0a/8: x ^= 1 << (0x0a%8);
2783                                 x ^= 1 << (0x0b%8);
2784                                 x ^= 1 << (0x0c%8);
2785                                 x ^= 1 << (0x0d%8);
2786                                 break;
2787                    case 0x85/8: x ^= 1 << (0x85%8); break;
2788                    default: break;
2789                    }
2790                  classbits[c] |= x;
2791                  }
2792    
2793    #ifdef SUPPORT_UTF8
2794                if (utf8)
2795                  {
2796                  class_utf8 = TRUE;
2797                  *class_utf8data++ = XCL_RANGE;
2798                  class_utf8data += _pcre_ord2utf8(0x0100, class_utf8data);
2799                  class_utf8data += _pcre_ord2utf8(0x2027, class_utf8data);
2800                  *class_utf8data++ = XCL_RANGE;
2801                  class_utf8data += _pcre_ord2utf8(0x2029, class_utf8data);
2802                  class_utf8data += _pcre_ord2utf8(0x7fffffff, class_utf8data);
2803                  }
2804    #endif
2805                continue;
2806                }
2807    
2808            /* We need to deal with \P and \p in both phases. */            /* We need to deal with \P and \p in both phases. */
2809    
2810  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
# Line 2655  for (;; ptr++) Line 2945  for (;; ptr++)
2945              unsigned int origd = d;              unsigned int origd = d;
2946              while (get_othercase_range(&cc, origd, &occ, &ocd))              while (get_othercase_range(&cc, origd, &occ, &ocd))
2947                {                {
2948                if (occ >= c && ocd <= d) continue;  /* Skip embedded ranges */                if (occ >= (unsigned int)c &&
2949                      ocd <= (unsigned int)d)
2950                    continue;                          /* Skip embedded ranges */
2951    
2952                if (occ < c  && ocd >= c - 1)        /* Extend the basic range */                if (occ < (unsigned int)c  &&
2953                      ocd >= (unsigned int)c - 1)      /* Extend the basic range */
2954                  {                                  /* if there is overlap,   */                  {                                  /* if there is overlap,   */
2955                  c = occ;                           /* noting that if occ < c */                  c = occ;                           /* noting that if occ < c */
2956                  continue;                          /* we can't have ocd > d  */                  continue;                          /* we can't have ocd > d  */
2957                  }                                  /* because a subrange is  */                  }                                  /* because a subrange is  */
2958                if (ocd > d && occ <= d + 1)         /* always shorter than    */                if (ocd > (unsigned int)d &&
2959                      occ <= (unsigned int)d + 1)      /* always shorter than    */
2960                  {                                  /* the basic range.       */                  {                                  /* the basic range.       */
2961                  d = ocd;                  d = ocd;
2962                  continue;                  continue;
# Line 3258  for (;; ptr++) Line 3552  for (;; ptr++)
3552          goto FAILED;          goto FAILED;
3553          }          }
3554    
       /* This is a paranoid check to stop integer overflow later on */  
   
       if (len > MAX_DUPLENGTH)  
         {  
         *errorcodeptr = ERR50;  
         goto FAILED;  
         }  
   
3555        /* 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
3556        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
3557        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 3354  for (;; ptr++) Line 3640  for (;; ptr++)
3640          if (repeat_min > 1)          if (repeat_min > 1)
3641            {            {
3642            /* 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
3643            just adjust the length as if we had. */            just adjust the length as if we had. Do some paranoid checks for
3644              potential integer overflow. */
3645    
3646            if (lengthptr != NULL)            if (lengthptr != NULL)
3647              *lengthptr += (repeat_min - 1)*length_prevgroup;              {
3648                int delta = (repeat_min - 1)*length_prevgroup;
3649                if ((double)(repeat_min - 1)*(double)length_prevgroup >
3650                                                                (double)INT_MAX ||
3651                    OFLOW_MAX - *lengthptr < delta)
3652                  {
3653                  *errorcodeptr = ERR20;
3654                  goto FAILED;
3655                  }
3656                *lengthptr += delta;
3657                }
3658    
3659            /* This is compiling for real */            /* This is compiling for real */
3660    
# Line 3395  for (;; ptr++) Line 3692  for (;; ptr++)
3692          /* 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
3693          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
3694          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
3695          add 2 + 2*LINKSIZE to allow for the nesting that occurs. */          add 2 + 2*LINKSIZE to allow for the nesting that occurs. Do some
3696            paranoid checks to avoid integer overflow. */
3697    
3698          if (lengthptr != NULL && repeat_max > 0)          if (lengthptr != NULL && repeat_max > 0)
3699            *lengthptr += repeat_max * (length_prevgroup + 1 + 2 + 2*LINK_SIZE) -            {
3700              2 - 2*LINK_SIZE;  /* Last one doesn't nest */            int delta = repeat_max * (length_prevgroup + 1 + 2 + 2*LINK_SIZE) -
3701                          2 - 2*LINK_SIZE;   /* Last one doesn't nest */
3702              if ((double)repeat_max *
3703                    (double)(length_prevgroup + 1 + 2 + 2*LINK_SIZE)
3704                      > (double)INT_MAX ||
3705                  OFLOW_MAX - *lengthptr < delta)
3706                {
3707                *errorcodeptr = ERR20;
3708                goto FAILED;
3709                }
3710              *lengthptr += delta;
3711              }
3712    
3713          /* This is compiling for real */          /* This is compiling for real */
3714    
# Line 3560  for (;; ptr++) Line 3869  for (;; ptr++)
3869      skipbytes = 0;      skipbytes = 0;
3870      bravalue = OP_CBRA;      bravalue = OP_CBRA;
3871      save_hwm = cd->hwm;      save_hwm = cd->hwm;
3872        reset_bracount = FALSE;
3873    
3874      if (*(++ptr) == '?')      if (*(++ptr) == '?')
3875        {        {
# Line 3582  for (;; ptr++) Line 3892  for (;; ptr++)
3892    
3893    
3894          /* ------------------------------------------------------------ */          /* ------------------------------------------------------------ */
3895            case '|':                 /* Reset capture count for each branch */
3896            reset_bracount = TRUE;
3897            /* Fall through */
3898    
3899            /* ------------------------------------------------------------ */
3900          case ':':                 /* Non-capturing bracket */          case ':':                 /* Non-capturing bracket */
3901          bravalue = OP_BRA;          bravalue = OP_BRA;
3902          ptr++;          ptr++;
# Line 3617  for (;; ptr++) Line 3932  for (;; ptr++)
3932    
3933          code[1+LINK_SIZE] = OP_CREF;          code[1+LINK_SIZE] = OP_CREF;
3934          skipbytes = 3;          skipbytes = 3;
3935            refsign = -1;
3936    
3937          /* Check for a test for recursion in a named group. */          /* Check for a test for recursion in a named group. */
3938    
# Line 3640  for (;; ptr++) Line 3956  for (;; ptr++)
3956            terminator = '\'';            terminator = '\'';
3957            ptr++;            ptr++;
3958            }            }
3959          else terminator = 0;          else
3960              {
3961              terminator = 0;
3962              if (ptr[1] == '-' || ptr[1] == '+') refsign = *(++ptr);
3963              }
3964    
3965          /* 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 */
3966    
# Line 3676  for (;; ptr++) Line 3996  for (;; ptr++)
3996          if (lengthptr != NULL) break;          if (lengthptr != NULL) break;
3997    
3998          /* 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
3999          reference. */          reference. If the string started with "+" or "-" we require the rest to
4000            be digits, in which case recno will be set. */
4001    
4002            if (refsign > 0)
4003              {
4004              if (recno <= 0)
4005                {
4006                *errorcodeptr = ERR58;
4007                goto FAILED;
4008                }
4009              if (refsign == '-')
4010                {
4011                recno = cd->bracount - recno + 1;
4012                if (recno <= 0)
4013                  {
4014                  *errorcodeptr = ERR15;
4015                  goto FAILED;
4016                  }
4017                }
4018              else recno += cd->bracount;
4019              PUT2(code, 2+LINK_SIZE, recno);
4020              break;
4021              }
4022    
4023            /* Otherwise (did not start with "+" or "-"), start by looking for the
4024            name. */
4025    
4026          slot = cd->name_table;          slot = cd->name_table;
4027          for (i = 0; i < cd->names_found; i++)          for (i = 0; i < cd->names_found; i++)
# Line 3995  for (;; ptr++) Line 4340  for (;; ptr++)
4340    
4341    
4342          /* ------------------------------------------------------------ */          /* ------------------------------------------------------------ */
4343            case '-': case '+':
4344          case '0': case '1': case '2': case '3': case '4':   /* Recursion or */          case '0': case '1': case '2': case '3': case '4':   /* Recursion or */
4345          case '5': case '6': case '7': case '8': case '9':   /* subroutine */          case '5': case '6': case '7': case '8': case '9':   /* subroutine */
4346            {            {
4347            const uschar *called;            const uschar *called;
4348    
4349              if ((refsign = *ptr) == '+') ptr++;
4350              else if (refsign == '-')
4351                {
4352                if ((digitab[ptr[1]] & ctype_digit) == 0)
4353                  goto OTHER_CHAR_AFTER_QUERY;
4354                ptr++;
4355                }
4356    
4357            recno = 0;            recno = 0;
4358            while((digitab[*ptr] & ctype_digit) != 0)            while((digitab[*ptr] & ctype_digit) != 0)
4359              recno = recno * 10 + *ptr++ - '0';              recno = recno * 10 + *ptr++ - '0';
4360    
4361            if (*ptr != ')')            if (*ptr != ')')
4362              {              {
4363              *errorcodeptr = ERR29;              *errorcodeptr = ERR29;
4364              goto FAILED;              goto FAILED;
4365              }              }
4366    
4367              if (refsign == '-')
4368                {
4369                if (recno == 0)
4370                  {
4371                  *errorcodeptr = ERR58;
4372                  goto FAILED;
4373                  }
4374                recno = cd->bracount - recno + 1;
4375                if (recno <= 0)
4376                  {
4377                  *errorcodeptr = ERR15;
4378                  goto FAILED;
4379                  }
4380                }
4381              else if (refsign == '+')
4382                {
4383                if (recno == 0)
4384                  {
4385                  *errorcodeptr = ERR58;
4386                  goto FAILED;
4387                  }
4388                recno += cd->bracount;
4389                }
4390    
4391            /* Come here from code above that handles a named recursion */            /* Come here from code above that handles a named recursion */
4392    
4393            HANDLE_RECURSION:            HANDLE_RECURSION:
# Line 4080  for (;; ptr++) Line 4460  for (;; ptr++)
4460    
4461          /* ------------------------------------------------------------ */          /* ------------------------------------------------------------ */
4462          default:              /* Other characters: check option setting */          default:              /* Other characters: check option setting */
4463            OTHER_CHAR_AFTER_QUERY:
4464          set = unset = 0;          set = unset = 0;
4465          optset = &set;          optset = &set;
4466    
# Line 4214  for (;; ptr++) Line 4595  for (;; ptr++)
4595           errorcodeptr,                 /* Where to put an error message */           errorcodeptr,                 /* Where to put an error message */
4596           (bravalue == OP_ASSERTBACK ||           (bravalue == OP_ASSERTBACK ||
4597            bravalue == OP_ASSERTBACK_NOT), /* TRUE if back assert */            bravalue == OP_ASSERTBACK_NOT), /* TRUE if back assert */
4598             reset_bracount,               /* True if (?| group */
4599           skipbytes,                    /* Skip over bracket number */           skipbytes,                    /* Skip over bracket number */
4600           &subfirstbyte,                /* For possible first char */           &subfirstbyte,                /* For possible first char */
4601           &subreqbyte,                  /* For possible last char */           &subreqbyte,                  /* For possible last char */
# Line 4230  for (;; ptr++) Line 4612  for (;; ptr++)
4612      is on the bracket. */      is on the bracket. */
4613    
4614      /* 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
4615      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
4616        in the real compile phase, not in the pre-pass, where the whole group may
4617        not be available. */
4618    
4619      if (bravalue == OP_COND)      if (bravalue == OP_COND && lengthptr == NULL)
4620        {        {
4621        uschar *tc = code;        uschar *tc = code;
4622        int condcount = 0;        int condcount = 0;
# Line 4286  for (;; ptr++) Line 4670  for (;; ptr++)
4670    
4671      if (lengthptr != NULL)      if (lengthptr != NULL)
4672        {        {
4673          if (OFLOW_MAX - *lengthptr < length_prevgroup - 2 - 2*LINK_SIZE)
4674            {
4675            *errorcodeptr = ERR20;
4676            goto FAILED;
4677            }
4678        *lengthptr += length_prevgroup - 2 - 2*LINK_SIZE;        *lengthptr += length_prevgroup - 2 - 2*LINK_SIZE;
4679        code++;        code++;
4680        PUTINC(code, 0, 1 + LINK_SIZE);        PUTINC(code, 0, 1 + LINK_SIZE);
# Line 4392  for (;; ptr++) Line 4781  for (;; ptr++)
4781        zerofirstbyte = firstbyte;        zerofirstbyte = firstbyte;
4782        zeroreqbyte = reqbyte;        zeroreqbyte = reqbyte;
4783    
4784        /* \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).
4785          We also support \k{name} (.NET syntax) */
4786    
4787        if (-c == ESC_k && (ptr[1] == '<' || ptr[1] == '\''))        if (-c == ESC_k && (ptr[1] == '<' || ptr[1] == '\'' || ptr[1] == '{'))
4788          {          {
4789          is_recurse = FALSE;          is_recurse = FALSE;
4790          terminator = (*(++ptr) == '<')? '>' : '\'';          terminator = (*(++ptr) == '<')? '>' : (*ptr == '\'')? '\'' : '}';
4791          goto NAMED_REF_OR_RECURSE;          goto NAMED_REF_OR_RECURSE;
4792          }          }
4793    
# Line 4563  This function is used during the pre-com Line 4953  This function is used during the pre-com
4953  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
4954  value of lengthptr distinguishes the two phases.  value of lengthptr distinguishes the two phases.
4955    
4956  Argument:  Arguments:
4957    options        option bits, including any changes for this subpattern    options        option bits, including any changes for this subpattern
4958    oldims         previous settings of ims option bits    oldims         previous settings of ims option bits
4959    codeptr        -> the address of the current code pointer    codeptr        -> the address of the current code pointer
4960    ptrptr         -> the address of the current pattern pointer    ptrptr         -> the address of the current pattern pointer
4961    errorcodeptr   -> pointer to error code variable    errorcodeptr   -> pointer to error code variable
4962    lookbehind     TRUE if this is a lookbehind assertion    lookbehind     TRUE if this is a lookbehind assertion
4963      reset_bracount TRUE to reset the count for each branch
4964    skipbytes      skip this many bytes at start (for brackets and OP_COND)    skipbytes      skip this many bytes at start (for brackets and OP_COND)
4965    firstbyteptr   place to put the first required character, or a negative number    firstbyteptr   place to put the first required character, or a negative number
4966    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 4583  Returns: TRUE on success Line 4974  Returns: TRUE on success
4974    
4975  static BOOL  static BOOL
4976  compile_regex(int options, int oldims, uschar **codeptr, const uschar **ptrptr,  compile_regex(int options, int oldims, uschar **codeptr, const uschar **ptrptr,
4977    int *errorcodeptr, BOOL lookbehind, int skipbytes, int *firstbyteptr,    int *errorcodeptr, BOOL lookbehind, BOOL reset_bracount, int skipbytes,
4978    int *reqbyteptr, branch_chain *bcptr, compile_data *cd, int *lengthptr)    int *firstbyteptr, int *reqbyteptr, branch_chain *bcptr, compile_data *cd,
4979      int *lengthptr)
4980  {  {
4981  const uschar *ptr = *ptrptr;  const uschar *ptr = *ptrptr;
4982  uschar *code = *codeptr;  uschar *code = *codeptr;
# Line 4594  uschar *reverse_count = NULL; Line 4986  uschar *reverse_count = NULL;
4986  int firstbyte, reqbyte;  int firstbyte, reqbyte;
4987  int branchfirstbyte, branchreqbyte;  int branchfirstbyte, branchreqbyte;
4988  int length;  int length;
4989    int orig_bracount;
4990    int max_bracount;
4991  branch_chain bc;  branch_chain bc;
4992    
4993  bc.outer = bcptr;  bc.outer = bcptr;
# Line 4622  code += 1 + LINK_SIZE + skipbytes; Line 5016  code += 1 + LINK_SIZE + skipbytes;
5016    
5017  /* Loop for each alternative branch */  /* Loop for each alternative branch */
5018    
5019    orig_bracount = max_bracount = cd->bracount;
5020  for (;;)  for (;;)
5021    {    {
5022      /* For a (?| group, reset the capturing bracket count so that each branch
5023      uses the same numbers. */
5024    
5025      if (reset_bracount) cd->bracount = orig_bracount;
5026    
5027    /* Handle a change of ims options at the start of the branch */    /* Handle a change of ims options at the start of the branch */
5028    
5029    if ((options & PCRE_IMS) != oldims)    if ((options & PCRE_IMS) != oldims)
# Line 4653  for (;;) Line 5053  for (;;)
5053      return FALSE;      return FALSE;
5054      }      }
5055    
5056      /* Keep the highest bracket count in case (?| was used and some branch
5057      has fewer than the rest. */
5058    
5059      if (cd->bracount > max_bracount) max_bracount = cd->bracount;
5060    
5061    /* 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. */
5062    
5063    if (lengthptr == NULL)    if (lengthptr == NULL)
# Line 4716  for (;;) Line 5121  for (;;)
5121        }        }
5122      }      }
5123    
5124    /* Reached end of expression, either ')' or end of pattern. Go back through    /* Reached end of expression, either ')' or end of pattern. In the real
5125    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
5126    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
5127    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
5128    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
5129    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,
5130    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.
5131    at the terminating char. */    Return leaving the pointer at the terminating char. */
5132    
5133    if (*ptr != '|')    if (*ptr != '|')
5134      {      {
5135      int branch_length = code - last_branch;      if (lengthptr == NULL)
     do  
5136        {        {
5137        int prev_length = GET(last_branch, 1);        int branch_length = code - last_branch;
5138        PUT(last_branch, 1, branch_length);        do
5139        branch_length = prev_length;          {
5140        last_branch -= branch_length;          int prev_length = GET(last_branch, 1);
5141            PUT(last_branch, 1, branch_length);
5142            branch_length = prev_length;
5143            last_branch -= branch_length;
5144            }
5145          while (branch_length > 0);
5146        }        }
     while (branch_length > 0);  
5147    
5148      /* Fill in the ket */      /* Fill in the ket */
5149    
# Line 4752  for (;;) Line 5160  for (;;)
5160        length += 2;        length += 2;
5161        }        }
5162    
5163        /* Retain the highest bracket number, in case resetting was used. */
5164    
5165        cd->bracount = max_bracount;
5166    
5167      /* Set values to pass back */      /* Set values to pass back */
5168    
5169      *codeptr = code;      *codeptr = code;
5170      *ptrptr = ptr;      *ptrptr = ptr;
5171      *firstbyteptr = firstbyte;      *firstbyteptr = firstbyte;
5172      *reqbyteptr = reqbyte;      *reqbyteptr = reqbyte;
5173      if (lengthptr != NULL) *lengthptr += length;      if (lengthptr != NULL)
5174          {
5175          if (OFLOW_MAX - *lengthptr < length)
5176            {
5177            *errorcodeptr = ERR20;
5178            return FALSE;
5179            }
5180          *lengthptr += length;
5181          }
5182      return TRUE;      return TRUE;
5183      }      }
5184    
5185    /* 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
5186      pointer back to where it was for the start of the first branch. (That is,
5187      pretend that each branch is the only one.)
5188    
5189      In the real compile phase, insert an ALT node. Its length field points back
5190    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
5191    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
5192    zero offset until it is closed, making it possible to detect recursion. */    zero offset until it is closed, making it possible to detect recursion. */
5193    
5194    *code = OP_ALT;    if (lengthptr != NULL)
5195    PUT(code, 1, code - last_branch);      {
5196    bc.current = last_branch = code;      code = *codeptr + 1 + LINK_SIZE + skipbytes;
5197    code += 1 + LINK_SIZE;      length += 1 + LINK_SIZE;
5198        }
5199      else
5200        {
5201        *code = OP_ALT;
5202        PUT(code, 1, code - last_branch);
5203        bc.current = last_branch = code;
5204        code += 1 + LINK_SIZE;
5205        }
5206    
5207    ptr++;    ptr++;
   length += 1 + LINK_SIZE;  
5208    }    }
5209  /* Control never reaches here */  /* Control never reaches here */
5210  }  }
# Line 5039  Returns: pointer to compiled data Line 5471  Returns: pointer to compiled data
5471                  with errorptr and erroroffset set                  with errorptr and erroroffset set
5472  */  */
5473    
5474  PCRE_DATA_SCOPE pcre *  PCRE_EXP_DEFN pcre *
5475  pcre_compile(const char *pattern, int options, const char **errorptr,  pcre_compile(const char *pattern, int options, const char **errorptr,
5476    int *erroroffset, const unsigned char *tables)    int *erroroffset, const unsigned char *tables)
5477  {  {
# Line 5047  return pcre_compile2(pattern, options, N Line 5479  return pcre_compile2(pattern, options, N
5479  }  }
5480    
5481    
5482  PCRE_DATA_SCOPE pcre *  PCRE_EXP_DEFN pcre *
5483  pcre_compile2(const char *pattern, int options, int *errorcodeptr,  pcre_compile2(const char *pattern, int options, int *errorcodeptr,
5484    const char **errorptr, int *erroroffset, const unsigned char *tables)    const char **errorptr, int *erroroffset, const unsigned char *tables)
5485  {  {
# Line 5096  if (errorcodeptr != NULL) *errorcodeptr Line 5528  if (errorcodeptr != NULL) *errorcodeptr
5528  if (erroroffset == NULL)  if (erroroffset == NULL)
5529    {    {
5530    errorcode = ERR16;    errorcode = ERR16;
5531    goto PCRE_EARLY_ERROR_RETURN;    goto PCRE_EARLY_ERROR_RETURN2;
5532    }    }
5533    
5534  *erroroffset = 0;  *erroroffset = 0;
# Line 5109  if (utf8 && (options & PCRE_NO_UTF8_CHEC Line 5541  if (utf8 && (options & PCRE_NO_UTF8_CHEC
5541       (*erroroffset = _pcre_valid_utf8((uschar *)pattern, -1)) >= 0)       (*erroroffset = _pcre_valid_utf8((uschar *)pattern, -1)) >= 0)
5542    {    {
5543    errorcode = ERR44;    errorcode = ERR44;
5544    goto PCRE_UTF8_ERROR_RETURN;    goto PCRE_EARLY_ERROR_RETURN2;
5545    }    }
5546  #else  #else
5547  if ((options & PCRE_UTF8) != 0)  if ((options & PCRE_UTF8) != 0)
# Line 5134  cd->cbits = tables + cbits_offset; Line 5566  cd->cbits = tables + cbits_offset;
5566  cd->ctypes = tables + ctypes_offset;  cd->ctypes = tables + ctypes_offset;
5567    
5568  /* Handle different types of newline. The three bits give seven cases. The  /* Handle different types of newline. The three bits give seven cases. The
5569  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
5570    "anycrlf". */
5571    
5572  switch (options & (PCRE_NEWLINE_CRLF | PCRE_NEWLINE_ANY))  switch (options & (PCRE_NEWLINE_CRLF | PCRE_NEWLINE_ANY))
5573    {    {
# Line 5144  switch (options & (PCRE_NEWLINE_CRLF | P Line 5577  switch (options & (PCRE_NEWLINE_CRLF | P
5577    case PCRE_NEWLINE_CR+    case PCRE_NEWLINE_CR+
5578         PCRE_NEWLINE_LF: newline = ('\r' << 8) | '\n'; break;         PCRE_NEWLINE_LF: newline = ('\r' << 8) | '\n'; break;
5579    case PCRE_NEWLINE_ANY: newline = -1; break;    case PCRE_NEWLINE_ANY: newline = -1; break;
5580      case PCRE_NEWLINE_ANYCRLF: newline = -2; break;
5581    default: errorcode = ERR56; goto PCRE_EARLY_ERROR_RETURN;    default: errorcode = ERR56; goto PCRE_EARLY_ERROR_RETURN;
5582    }    }
5583    
5584  if (newline < 0)  if (newline == -2)
5585      {
5586      cd->nltype = NLTYPE_ANYCRLF;
5587      }
5588    else if (newline < 0)
5589    {    {
5590    cd->nltype = NLTYPE_ANY;    cd->nltype = NLTYPE_ANY;
5591    }    }
# Line 5208  outside can help speed up starting point Line 5646  outside can help speed up starting point
5646  code = cworkspace;  code = cworkspace;
5647  *code = OP_BRA;  *code = OP_BRA;
5648  (void)compile_regex(cd->external_options, cd->external_options & PCRE_IMS,  (void)compile_regex(cd->external_options, cd->external_options & PCRE_IMS,
5649    &code, &ptr, &errorcode, FALSE, 0, &firstbyte, &reqbyte, NULL, cd, &length);    &code, &ptr, &errorcode, FALSE, FALSE, 0, &firstbyte, &reqbyte, NULL, cd,
5650      &length);
5651  if (errorcode != 0) goto PCRE_EARLY_ERROR_RETURN;  if (errorcode != 0) goto PCRE_EARLY_ERROR_RETURN;
5652    
5653  DPRINTF(("end pre-compile: length=%d workspace=%d\n", length,  DPRINTF(("end pre-compile: length=%d workspace=%d\n", length,
# Line 5276  ptr = (const uschar *)pattern; Line 5715  ptr = (const uschar *)pattern;
5715  code = (uschar *)codestart;  code = (uschar *)codestart;
5716  *code = OP_BRA;  *code = OP_BRA;
5717  (void)compile_regex(re->options, re->options & PCRE_IMS, &code, &ptr,  (void)compile_regex(re->options, re->options & PCRE_IMS, &code, &ptr,
5718    &errorcode, FALSE, 0, &firstbyte, &reqbyte, NULL, cd, NULL);    &errorcode, FALSE, FALSE, 0, &firstbyte, &reqbyte, NULL, cd, NULL);
5719  re->top_bracket = cd->bracount;  re->top_bracket = cd->bracount;
5720  re->top_backref = cd->top_backref;  re->top_backref = cd->top_backref;
5721    
# Line 5321  if (errorcode != 0) Line 5760  if (errorcode != 0)
5760    (pcre_free)(re);    (pcre_free)(re);
5761    PCRE_EARLY_ERROR_RETURN:    PCRE_EARLY_ERROR_RETURN:
5762    *erroroffset = ptr - (const uschar *)pattern;    *erroroffset = ptr - (const uschar *)pattern;
5763  #ifdef SUPPORT_UTF8    PCRE_EARLY_ERROR_RETURN2:
   PCRE_UTF8_ERROR_RETURN:  
 #endif  
5764    *errorptr = error_texts[errorcode];    *errorptr = error_texts[errorcode];
5765    if (errorcodeptr != NULL) *errorcodeptr = errorcode;    if (errorcodeptr != NULL) *errorcodeptr = errorcode;
5766    return NULL;    return NULL;
# Line 5413  if ((re->options & PCRE_REQCHSET) != 0) Line 5850  if ((re->options & PCRE_REQCHSET) != 0)
5850      else printf("Req char = \\x%02x%s\n", ch, caseless);      else printf("Req char = \\x%02x%s\n", ch, caseless);
5851    }    }
5852    
5853  pcre_printint(re, stdout);  pcre_printint(re, stdout, TRUE);
5854    
5855  /* This check is done here in the debugging case so that the code that  /* This check is done here in the debugging case so that the code that
5856  was compiled can be seen. */  was compiled can be seen. */

Legend:
Removed from v.97  
changed lines
  Added in v.208

webmaster@exim.org
ViewVC Help
Powered by ViewVC 1.1.12