/[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 145 by ph10, Wed Apr 4 14:06:52 2007 UTC revision 210 by ph10, Wed Aug 8 14:24:50 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 125  static const short int escapes[] = { Line 140  static const short int escapes[] = {
140  #endif  #endif
141    
142    
143    /* Table of special "verbs" like (*PRUNE) */
144    
145    typedef struct verbitem {
146      const char *name;
147      int   len;
148      int   op;
149    } verbitem;
150    
151    static verbitem verbs[] = {
152      { "ACCEPT", 6, OP_ACCEPT },
153      { "COMMIT", 6, OP_COMMIT },
154      { "F",      1, OP_FAIL },
155      { "FAIL",   4, OP_FAIL },
156      { "PRUNE",  5, OP_PRUNE },
157      { "SKIP",   4, OP_SKIP  },
158      { "THEN",   4, OP_THEN  }
159    };
160    
161    static int verbcount = sizeof(verbs)/sizeof(verbitem);
162    
163    
164  /* Tables of names of POSIX character classes and their lengths. The list is  /* Tables of names of POSIX character classes and their lengths. The list is
165  terminated by a zero length entry. The first three must be alpha, lower, upper,  terminated by a zero length entry. The first three must be alpha, lower, upper,
166  as this is assumed for handling case independence. */  as this is assumed for handling case independence. */
# Line 198  static const char *error_texts[] = { Line 234  static const char *error_texts[] = {
234    "missing ) after comment",    "missing ) after comment",
235    "parentheses nested too deeply",  /** DEAD **/    "parentheses nested too deeply",  /** DEAD **/
236    /* 20 */    /* 20 */
237    "regular expression too large",    "regular expression is too large",
238    "failed to get memory",    "failed to get memory",
239    "unmatched parentheses",    "unmatched parentheses",
240    "internal error: code overflow",    "internal error: code overflow",
# Line 208  static const char *error_texts[] = { Line 244  static const char *error_texts[] = {
244    "malformed number or name after (?(",    "malformed number or name after (?(",
245    "conditional group contains more than two branches",    "conditional group contains more than two branches",
246    "assertion expected after (?(",    "assertion expected after (?(",
247    "(?R or (?digits must be followed by )",    "(?R or (?[+-]digits must be followed by )",
248    /* 30 */    /* 30 */
249    "unknown POSIX class name",    "unknown POSIX class name",
250    "POSIX collating elements are not supported",    "POSIX collating elements are not supported",
# Line 234  static const char *error_texts[] = { Line 270  static const char *error_texts[] = {
270    "subpattern name is too long (maximum " XSTRING(MAX_NAME_SIZE) " characters)",    "subpattern name is too long (maximum " XSTRING(MAX_NAME_SIZE) " characters)",
271    "too many named subpatterns (maximum " XSTRING(MAX_NAME_COUNT) ")",    "too many named subpatterns (maximum " XSTRING(MAX_NAME_COUNT) ")",
272    /* 50 */    /* 50 */
273    "repeated subpattern is too long",    "repeated subpattern is too long",    /** DEAD **/
274    "octal value is greater than \\377 (not in UTF-8 mode)",    "octal value is greater than \\377 (not in UTF-8 mode)",
275    "internal error: overran compiling workspace",    "internal error: overran compiling workspace",
276    "internal error: previously-checked referenced subpattern not found",    "internal error: previously-checked referenced subpattern not found",
# Line 242  static const char *error_texts[] = { Line 278  static const char *error_texts[] = {
278    /* 55 */    /* 55 */
279    "repeating a DEFINE group is not allowed",    "repeating a DEFINE group is not allowed",
280    "inconsistent NEWLINE options",    "inconsistent NEWLINE options",
281    "\\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",
282      "(?+ or (?- or (?(+ or (?(- must be followed by a non-zero number",
283      "(*VERB) with an argument is not supported",
284      /* 60 */
285      "(*VERB) not recognized"
286  };  };
287    
288    
# Line 373  static const unsigned char ebcdic_charta Line 413  static const unsigned char ebcdic_charta
413  /* Definition to allow mutual recursion */  /* Definition to allow mutual recursion */
414    
415  static BOOL  static BOOL
416    compile_regex(int, int, uschar **, const uschar **, int *, BOOL, int, int *,    compile_regex(int, int, uschar **, const uschar **, int *, BOOL, BOOL, int,
417      int *, branch_chain *, compile_data *, int *);      int *, int *, branch_chain *, compile_data *, int *);
418    
419    
420    
# Line 452  else Line 492  else
492    
493      /* \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
494      is an absolute backreference. If negative, it is a relative backreference.      is an absolute backreference. If negative, it is a relative backreference.
495      This is a Perl 5.10 feature. */      This is a Perl 5.10 feature. Perl 5.10 also supports \g{name} as a
496        reference to a named group. This is part of Perl's movement towards a
497        unified syntax for back references. As this is synonymous with \k{name}, we
498        fudge it up by pretending it really was \k. */
499    
500      case 'g':      case 'g':
501      if (ptr[1] == '{')      if (ptr[1] == '{')
502        {        {
503          const uschar *p;
504          for (p = ptr+2; *p != 0 && *p != '}'; p++)
505            if (*p != '-' && (digitab[*p] & ctype_digit) == 0) break;
506          if (*p != 0 && *p != '}')
507            {
508            c = -ESC_k;
509            break;
510            }
511        braced = TRUE;        braced = TRUE;
512        ptr++;        ptr++;
513        }        }
# Line 684  if (c == '{') Line 735  if (c == '{')
735      *negptr = TRUE;      *negptr = TRUE;
736      ptr++;      ptr++;
737      }      }
738    for (i = 0; i < sizeof(name) - 1; i++)    for (i = 0; i < (int)sizeof(name) - 1; i++)
739      {      {
740      c = *(++ptr);      c = *(++ptr);
741      if (c == 0) goto ERROR_RETURN;      if (c == 0) goto ERROR_RETURN;
# Line 914  for (; *ptr != 0; ptr++) Line 965  for (; *ptr != 0; ptr++)
965    /* An opening parens must now be a real metacharacter */    /* An opening parens must now be a real metacharacter */
966    
967    if (*ptr != '(') continue;    if (*ptr != '(') continue;
968    if (ptr[1] != '?')    if (ptr[1] != '?' && ptr[1] != '*')
969      {      {
970      count++;      count++;
971      if (name == NULL && count == lorn) return count;      if (name == NULL && count == lorn) return count;
# Line 1370  for (code = first_significant_code(code Line 1421  for (code = first_significant_code(code
1421    
1422    c = *code;    c = *code;
1423    
1424    if (c == OP_BRA || c == OP_CBRA || c == OP_ONCE)    /* Groups with zero repeats can of course be empty; skip them. */
1425    
1426      if (c == OP_BRAZERO || c == OP_BRAMINZERO)
1427        {
1428        code += _pcre_OP_lengths[c];
1429        do code += GET(code, 1); while (*code == OP_ALT);
1430        c = *code;
1431        continue;
1432        }
1433    
1434      /* For other groups, scan the branches. */
1435    
1436      if (c == OP_BRA || c == OP_CBRA || c == OP_ONCE || c == OP_COND)
1437      {      {
1438      BOOL empty_branch;      BOOL empty_branch;
1439      if (GET(code, 1) == 0) return TRUE;    /* Hit unclosed bracket */      if (GET(code, 1) == 0) return TRUE;    /* Hit unclosed bracket */
# Line 1386  for (code = first_significant_code(code Line 1449  for (code = first_significant_code(code
1449        }        }
1450      while (*code == OP_ALT);      while (*code == OP_ALT);
1451      if (!empty_branch) return FALSE;   /* All branches are non-empty */      if (!empty_branch) return FALSE;   /* All branches are non-empty */
1452        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];  
1453      continue;      continue;
1454      }      }
1455    
# Line 1925  if (next >= 0) switch(op_code) Line 1983  if (next >= 0) switch(op_code)
1983    case OP_NOT_WORDCHAR:    case OP_NOT_WORDCHAR:
1984    return next <= 127 && (cd->ctypes[next] & ctype_word) != 0;    return next <= 127 && (cd->ctypes[next] & ctype_word) != 0;
1985    
1986      case OP_HSPACE:
1987      case OP_NOT_HSPACE:
1988      switch(next)
1989        {
1990        case 0x09:
1991        case 0x20:
1992        case 0xa0:
1993        case 0x1680:
1994        case 0x180e:
1995        case 0x2000:
1996        case 0x2001:
1997        case 0x2002:
1998        case 0x2003:
1999        case 0x2004:
2000        case 0x2005:
2001        case 0x2006:
2002        case 0x2007:
2003        case 0x2008:
2004        case 0x2009:
2005        case 0x200A:
2006        case 0x202f:
2007        case 0x205f:
2008        case 0x3000:
2009        return op_code != OP_HSPACE;
2010        default:
2011        return op_code == OP_HSPACE;
2012        }
2013    
2014      case OP_VSPACE:
2015      case OP_NOT_VSPACE:
2016      switch(next)
2017        {
2018        case 0x0a:
2019        case 0x0b:
2020        case 0x0c:
2021        case 0x0d:
2022        case 0x85:
2023        case 0x2028:
2024        case 0x2029:
2025        return op_code != OP_VSPACE;
2026        default:
2027        return op_code == OP_VSPACE;
2028        }
2029    
2030    default:    default:
2031    return FALSE;    return FALSE;
2032    }    }
# Line 1959  switch(op_code) Line 2061  switch(op_code)
2061      case ESC_W:      case ESC_W:
2062      return item <= 127 && (cd->ctypes[item] & ctype_word) != 0;      return item <= 127 && (cd->ctypes[item] & ctype_word) != 0;
2063    
2064        case ESC_h:
2065        case ESC_H:
2066        switch(item)
2067          {
2068          case 0x09:
2069          case 0x20:
2070          case 0xa0:
2071          case 0x1680:
2072          case 0x180e:
2073          case 0x2000:
2074          case 0x2001:
2075          case 0x2002:
2076          case 0x2003:
2077          case 0x2004:
2078          case 0x2005:
2079          case 0x2006:
2080          case 0x2007:
2081          case 0x2008:
2082          case 0x2009:
2083          case 0x200A:
2084          case 0x202f:
2085          case 0x205f:
2086          case 0x3000:
2087          return -next != ESC_h;
2088          default:
2089          return -next == ESC_h;
2090          }
2091    
2092        case ESC_v:
2093        case ESC_V:
2094        switch(item)
2095          {
2096          case 0x0a:
2097          case 0x0b:
2098          case 0x0c:
2099          case 0x0d:
2100          case 0x85:
2101          case 0x2028:
2102          case 0x2029:
2103          return -next != ESC_v;
2104          default:
2105          return -next == ESC_v;
2106          }
2107    
2108      default:      default:
2109      return FALSE;      return FALSE;
2110      }      }
2111    
2112    case OP_DIGIT:    case OP_DIGIT:
2113    return next == -ESC_D || next == -ESC_s || next == -ESC_W;    return next == -ESC_D || next == -ESC_s || next == -ESC_W ||
2114             next == -ESC_h || next == -ESC_v;
2115    
2116    case OP_NOT_DIGIT:    case OP_NOT_DIGIT:
2117    return next == -ESC_d;    return next == -ESC_d;
# Line 1973  switch(op_code) Line 2120  switch(op_code)
2120    return next == -ESC_S || next == -ESC_d || next == -ESC_w;    return next == -ESC_S || next == -ESC_d || next == -ESC_w;
2121    
2122    case OP_NOT_WHITESPACE:    case OP_NOT_WHITESPACE:
2123    return next == -ESC_s;    return next == -ESC_s || next == -ESC_h || next == -ESC_v;
2124    
2125      case OP_HSPACE:
2126      return next == -ESC_S || next == -ESC_H || next == -ESC_d || next == -ESC_w;
2127    
2128      case OP_NOT_HSPACE:
2129      return next == -ESC_h;
2130    
2131      /* Can't have \S in here because VT matches \S (Perl anomaly) */
2132      case OP_VSPACE:
2133      return next == -ESC_V || next == -ESC_d || next == -ESC_w;
2134    
2135      case OP_NOT_VSPACE:
2136      return next == -ESC_v;
2137    
2138    case OP_WORDCHAR:    case OP_WORDCHAR:
2139    return next == -ESC_W || next == -ESC_s;    return next == -ESC_W || next == -ESC_s || next == -ESC_h || next == -ESC_v;
2140    
2141    case OP_NOT_WORDCHAR:    case OP_NOT_WORDCHAR:
2142    return next == -ESC_w || next == -ESC_d;    return next == -ESC_w || next == -ESC_d;
# Line 2091  for (;; ptr++) Line 2251  for (;; ptr++)
2251    BOOL possessive_quantifier;    BOOL possessive_quantifier;
2252    BOOL is_quantifier;    BOOL is_quantifier;
2253    BOOL is_recurse;    BOOL is_recurse;
2254      BOOL reset_bracount;
2255    int class_charcount;    int class_charcount;
2256    int class_lastchar;    int class_lastchar;
2257    int newoptions;    int newoptions;
2258    int recno;    int recno;
2259      int refsign;
2260    int skipbytes;    int skipbytes;
2261    int subreqbyte;    int subreqbyte;
2262    int subfirstbyte;    int subfirstbyte;
# Line 2127  for (;; ptr++) Line 2289  for (;; ptr++)
2289      */      */
2290    
2291      if (code < last_code) code = last_code;      if (code < last_code) code = last_code;
2292    
2293        /* Paranoid check for integer overflow */
2294    
2295        if (OFLOW_MAX - *lengthptr < code - last_code)
2296          {
2297          *errorcodeptr = ERR20;
2298          goto FAILED;
2299          }
2300    
2301      *lengthptr += code - last_code;      *lengthptr += code - last_code;
2302      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));
2303    
# Line 2239  for (;; ptr++) Line 2410  for (;; ptr++)
2410      *ptrptr = ptr;      *ptrptr = ptr;
2411      if (lengthptr != NULL)      if (lengthptr != NULL)
2412        {        {
2413          if (OFLOW_MAX - *lengthptr < code - last_code)
2414            {
2415            *errorcodeptr = ERR20;
2416            goto FAILED;
2417            }
2418        *lengthptr += code - last_code;   /* To include callout length */        *lengthptr += code - last_code;   /* To include callout length */
2419        DPRINTF((">> end branch\n"));        DPRINTF((">> end branch\n"));
2420        }        }
# Line 2301  for (;; ptr++) Line 2477  for (;; ptr++)
2477        goto FAILED;        goto FAILED;
2478        }        }
2479    
2480      /* 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,
2481        if the first few characters (either before or after ^) are \Q\E or \E we
2482        skip them too. This makes for compatibility with Perl. */
2483    
2484      if ((c = *(++ptr)) == '^')      negate_class = FALSE;
2485        for (;;)
2486        {        {
       negate_class = TRUE;  
2487        c = *(++ptr);        c = *(++ptr);
2488        }        if (c == '\\')
2489      else          {
2490        {          if (ptr[1] == 'E') ptr++;
2491        negate_class = FALSE;            else if (strncmp((const char *)ptr+1, "Q\\E", 3) == 0) ptr += 3;
2492                else break;
2493            }
2494          else if (!negate_class && c == '^')
2495            negate_class = TRUE;
2496          else break;
2497        }        }
2498    
2499      /* 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 2451  for (;; ptr++) Line 2634  for (;; ptr++)
2634        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
2635        case. Inside a class (and only there) it is treated as backspace.        case. Inside a class (and only there) it is treated as backspace.
2636        Elsewhere it marks a word boundary. Other escapes have preset maps ready        Elsewhere it marks a word boundary. Other escapes have preset maps ready
2637        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
2638        character in them, so set class_charcount bigger than one. */        character in them, so set class_charcount bigger than one. */
2639    
2640        if (c == '\\')        if (c == '\\')
# Line 2519  for (;; ptr++) Line 2702  for (;; ptr++)
2702            else if (c == -ESC_d || c == -ESC_D || c == -ESC_w ||            else if (c == -ESC_d || c == -ESC_D || c == -ESC_w ||
2703                     c == -ESC_W || c == -ESC_s || c == -ESC_S) continue;                     c == -ESC_W || c == -ESC_s || c == -ESC_S) continue;
2704    
2705              /* We need to deal with \H, \h, \V, and \v in both phases because
2706              they use extra memory. */
2707    
2708              if (-c == ESC_h)
2709                {
2710                SETBIT(classbits, 0x09); /* VT */
2711                SETBIT(classbits, 0x20); /* SPACE */
2712                SETBIT(classbits, 0xa0); /* NSBP */
2713    #ifdef SUPPORT_UTF8
2714                if (utf8)
2715                  {
2716                  class_utf8 = TRUE;
2717                  *class_utf8data++ = XCL_SINGLE;
2718                  class_utf8data += _pcre_ord2utf8(0x1680, class_utf8data);
2719                  *class_utf8data++ = XCL_SINGLE;
2720                  class_utf8data += _pcre_ord2utf8(0x180e, class_utf8data);
2721                  *class_utf8data++ = XCL_RANGE;
2722                  class_utf8data += _pcre_ord2utf8(0x2000, class_utf8data);
2723                  class_utf8data += _pcre_ord2utf8(0x200A, class_utf8data);
2724                  *class_utf8data++ = XCL_SINGLE;
2725                  class_utf8data += _pcre_ord2utf8(0x202f, class_utf8data);
2726                  *class_utf8data++ = XCL_SINGLE;
2727                  class_utf8data += _pcre_ord2utf8(0x205f, class_utf8data);
2728                  *class_utf8data++ = XCL_SINGLE;
2729                  class_utf8data += _pcre_ord2utf8(0x3000, class_utf8data);
2730                  }
2731    #endif
2732                continue;
2733                }
2734    
2735              if (-c == ESC_H)
2736                {
2737                for (c = 0; c < 32; c++)
2738                  {
2739                  int x = 0xff;
2740                  switch (c)
2741                    {
2742                    case 0x09/8: x ^= 1 << (0x09%8); break;
2743                    case 0x20/8: x ^= 1 << (0x20%8); break;
2744                    case 0xa0/8: x ^= 1 << (0xa0%8); break;
2745                    default: break;
2746                    }
2747                  classbits[c] |= x;
2748                  }
2749    
2750    #ifdef SUPPORT_UTF8
2751                if (utf8)
2752                  {
2753                  class_utf8 = TRUE;
2754                  *class_utf8data++ = XCL_RANGE;
2755                  class_utf8data += _pcre_ord2utf8(0x0100, class_utf8data);
2756                  class_utf8data += _pcre_ord2utf8(0x167f, class_utf8data);
2757                  *class_utf8data++ = XCL_RANGE;
2758                  class_utf8data += _pcre_ord2utf8(0x1681, class_utf8data);
2759                  class_utf8data += _pcre_ord2utf8(0x180d, class_utf8data);
2760                  *class_utf8data++ = XCL_RANGE;
2761                  class_utf8data += _pcre_ord2utf8(0x180f, class_utf8data);
2762                  class_utf8data += _pcre_ord2utf8(0x1fff, class_utf8data);
2763                  *class_utf8data++ = XCL_RANGE;
2764                  class_utf8data += _pcre_ord2utf8(0x200B, class_utf8data);
2765                  class_utf8data += _pcre_ord2utf8(0x202e, class_utf8data);
2766                  *class_utf8data++ = XCL_RANGE;
2767                  class_utf8data += _pcre_ord2utf8(0x2030, class_utf8data);
2768                  class_utf8data += _pcre_ord2utf8(0x205e, class_utf8data);
2769                  *class_utf8data++ = XCL_RANGE;
2770                  class_utf8data += _pcre_ord2utf8(0x2060, class_utf8data);
2771                  class_utf8data += _pcre_ord2utf8(0x2fff, class_utf8data);
2772                  *class_utf8data++ = XCL_RANGE;
2773                  class_utf8data += _pcre_ord2utf8(0x3001, class_utf8data);
2774                  class_utf8data += _pcre_ord2utf8(0x7fffffff, class_utf8data);
2775                  }
2776    #endif
2777                continue;
2778                }
2779    
2780              if (-c == ESC_v)
2781                {
2782                SETBIT(classbits, 0x0a); /* LF */
2783                SETBIT(classbits, 0x0b); /* VT */
2784                SETBIT(classbits, 0x0c); /* FF */
2785                SETBIT(classbits, 0x0d); /* CR */
2786                SETBIT(classbits, 0x85); /* NEL */
2787    #ifdef SUPPORT_UTF8
2788                if (utf8)
2789                  {
2790                  class_utf8 = TRUE;
2791                  *class_utf8data++ = XCL_RANGE;
2792                  class_utf8data += _pcre_ord2utf8(0x2028, class_utf8data);
2793                  class_utf8data += _pcre_ord2utf8(0x2029, class_utf8data);
2794                  }
2795    #endif
2796                continue;
2797                }
2798    
2799              if (-c == ESC_V)
2800                {
2801                for (c = 0; c < 32; c++)
2802                  {
2803                  int x = 0xff;
2804                  switch (c)
2805                    {
2806                    case 0x0a/8: x ^= 1 << (0x0a%8);
2807                                 x ^= 1 << (0x0b%8);
2808                                 x ^= 1 << (0x0c%8);
2809                                 x ^= 1 << (0x0d%8);
2810                                 break;
2811                    case 0x85/8: x ^= 1 << (0x85%8); break;
2812                    default: break;
2813                    }
2814                  classbits[c] |= x;
2815                  }
2816    
2817    #ifdef SUPPORT_UTF8
2818                if (utf8)
2819                  {
2820                  class_utf8 = TRUE;
2821                  *class_utf8data++ = XCL_RANGE;
2822                  class_utf8data += _pcre_ord2utf8(0x0100, class_utf8data);
2823                  class_utf8data += _pcre_ord2utf8(0x2027, class_utf8data);
2824                  *class_utf8data++ = XCL_RANGE;
2825                  class_utf8data += _pcre_ord2utf8(0x2029, class_utf8data);
2826                  class_utf8data += _pcre_ord2utf8(0x7fffffff, class_utf8data);
2827                  }
2828    #endif
2829                continue;
2830                }
2831    
2832            /* We need to deal with \P and \p in both phases. */            /* We need to deal with \P and \p in both phases. */
2833    
2834  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
# Line 2659  for (;; ptr++) Line 2969  for (;; ptr++)
2969              unsigned int origd = d;              unsigned int origd = d;
2970              while (get_othercase_range(&cc, origd, &occ, &ocd))              while (get_othercase_range(&cc, origd, &occ, &ocd))
2971                {                {
2972                if (occ >= c && ocd <= d) continue;  /* Skip embedded ranges */                if (occ >= (unsigned int)c &&
2973                      ocd <= (unsigned int)d)
2974                    continue;                          /* Skip embedded ranges */
2975    
2976                if (occ < c  && ocd >= c - 1)        /* Extend the basic range */                if (occ < (unsigned int)c  &&
2977                      ocd >= (unsigned int)c - 1)      /* Extend the basic range */
2978                  {                                  /* if there is overlap,   */                  {                                  /* if there is overlap,   */
2979                  c = occ;                           /* noting that if occ < c */                  c = occ;                           /* noting that if occ < c */
2980                  continue;                          /* we can't have ocd > d  */                  continue;                          /* we can't have ocd > d  */
2981                  }                                  /* because a subrange is  */                  }                                  /* because a subrange is  */
2982                if (ocd > d && occ <= d + 1)         /* always shorter than    */                if (ocd > (unsigned int)d &&
2983                      occ <= (unsigned int)d + 1)      /* always shorter than    */
2984                  {                                  /* the basic range.       */                  {                                  /* the basic range.       */
2985                  d = ocd;                  d = ocd;
2986                  continue;                  continue;
# Line 3262  for (;; ptr++) Line 3576  for (;; ptr++)
3576          goto FAILED;          goto FAILED;
3577          }          }
3578    
       /* This is a paranoid check to stop integer overflow later on */  
   
       if (len > MAX_DUPLENGTH)  
         {  
         *errorcodeptr = ERR50;  
         goto FAILED;  
         }  
   
3579        /* 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
3580        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
3581        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 3664  for (;; ptr++)
3664          if (repeat_min > 1)          if (repeat_min > 1)
3665            {            {
3666            /* 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
3667            just adjust the length as if we had. */            just adjust the length as if we had. Do some paranoid checks for
3668              potential integer overflow. */
3669    
3670            if (lengthptr != NULL)            if (lengthptr != NULL)
3671              *lengthptr += (repeat_min - 1)*length_prevgroup;              {
3672                int delta = (repeat_min - 1)*length_prevgroup;
3673                if ((double)(repeat_min - 1)*(double)length_prevgroup >
3674                                                                (double)INT_MAX ||
3675                    OFLOW_MAX - *lengthptr < delta)
3676                  {
3677                  *errorcodeptr = ERR20;
3678                  goto FAILED;
3679                  }
3680                *lengthptr += delta;
3681                }
3682    
3683            /* This is compiling for real */            /* This is compiling for real */
3684    
# Line 3399  for (;; ptr++) Line 3716  for (;; ptr++)
3716          /* 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
3717          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
3718          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
3719          add 2 + 2*LINKSIZE to allow for the nesting that occurs. */          add 2 + 2*LINKSIZE to allow for the nesting that occurs. Do some
3720            paranoid checks to avoid integer overflow. */
3721    
3722          if (lengthptr != NULL && repeat_max > 0)          if (lengthptr != NULL && repeat_max > 0)
3723            *lengthptr += repeat_max * (length_prevgroup + 1 + 2 + 2*LINK_SIZE) -            {
3724              2 - 2*LINK_SIZE;  /* Last one doesn't nest */            int delta = repeat_max * (length_prevgroup + 1 + 2 + 2*LINK_SIZE) -
3725                          2 - 2*LINK_SIZE;   /* Last one doesn't nest */
3726              if ((double)repeat_max *
3727                    (double)(length_prevgroup + 1 + 2 + 2*LINK_SIZE)
3728                      > (double)INT_MAX ||
3729                  OFLOW_MAX - *lengthptr < delta)
3730                {
3731                *errorcodeptr = ERR20;
3732                goto FAILED;
3733                }
3734              *lengthptr += delta;
3735              }
3736    
3737          /* This is compiling for real */          /* This is compiling for real */
3738    
# Line 3555  for (;; ptr++) Line 3884  for (;; ptr++)
3884      /* ===================================================================*/      /* ===================================================================*/
3885      /* Start of nested parenthesized sub-expression, or comment or lookahead or      /* Start of nested parenthesized sub-expression, or comment or lookahead or
3886      lookbehind or option setting or condition or all the other extended      lookbehind or option setting or condition or all the other extended
3887      parenthesis forms. First deal with the specials; all are introduced by ?,      parenthesis forms.  */
     and the appearance of any of them means that this is not a capturing  
     group. */  
3888    
3889      case '(':      case '(':
3890      newoptions = options;      newoptions = options;
3891      skipbytes = 0;      skipbytes = 0;
3892      bravalue = OP_CBRA;      bravalue = OP_CBRA;
3893      save_hwm = cd->hwm;      save_hwm = cd->hwm;
3894        reset_bracount = FALSE;
3895    
3896        /* First deal with various "verbs" that can be introduced by '*'. */
3897    
3898        if (*(++ptr) == '*' && (cd->ctypes[ptr[1]] & ctype_letter) != 0)
3899          {
3900          int i, namelen;
3901          const uschar *name = ++ptr;
3902          previous = NULL;
3903          while ((cd->ctypes[*++ptr] & ctype_letter) != 0);
3904          if (*ptr == ':')
3905            {
3906            *errorcodeptr = ERR59;   /* Not supported */
3907            goto FAILED;
3908            }
3909          if (*ptr != ')')
3910            {
3911            *errorcodeptr = ERR60;
3912            goto FAILED;
3913            }
3914          namelen = ptr - name;
3915          for (i = 0; i < verbcount; i++)
3916            {
3917            if (namelen == verbs[i].len &&
3918                strncmp((char *)name, verbs[i].name, namelen) == 0)
3919              {
3920              *code = verbs[i].op;
3921              if (*code++ == OP_ACCEPT) cd->had_accept = TRUE;
3922              break;
3923              }
3924            }
3925          if (i < verbcount) continue;
3926          *errorcodeptr = ERR60;
3927          goto FAILED;
3928          }
3929    
3930        /* Deal with the extended parentheses; all are introduced by '?', and the
3931        appearance of any of them means that this is not a capturing group. */
3932    
3933      if (*(++ptr) == '?')      else if (*ptr == '?')
3934        {        {
3935        int i, set, unset, namelen;        int i, set, unset, namelen;
3936        int *optset;        int *optset;
# Line 3586  for (;; ptr++) Line 3951  for (;; ptr++)
3951    
3952    
3953          /* ------------------------------------------------------------ */          /* ------------------------------------------------------------ */
3954            case '|':                 /* Reset capture count for each branch */
3955            reset_bracount = TRUE;
3956            /* Fall through */
3957    
3958            /* ------------------------------------------------------------ */
3959          case ':':                 /* Non-capturing bracket */          case ':':                 /* Non-capturing bracket */
3960          bravalue = OP_BRA;          bravalue = OP_BRA;
3961          ptr++;          ptr++;
# Line 3621  for (;; ptr++) Line 3991  for (;; ptr++)
3991    
3992          code[1+LINK_SIZE] = OP_CREF;          code[1+LINK_SIZE] = OP_CREF;
3993          skipbytes = 3;          skipbytes = 3;
3994            refsign = -1;
3995    
3996          /* Check for a test for recursion in a named group. */          /* Check for a test for recursion in a named group. */
3997    
# Line 3644  for (;; ptr++) Line 4015  for (;; ptr++)
4015            terminator = '\'';            terminator = '\'';
4016            ptr++;            ptr++;
4017            }            }
4018          else terminator = 0;          else
4019              {
4020              terminator = 0;
4021              if (ptr[1] == '-' || ptr[1] == '+') refsign = *(++ptr);
4022              }
4023    
4024          /* 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 */
4025    
# Line 3680  for (;; ptr++) Line 4055  for (;; ptr++)
4055          if (lengthptr != NULL) break;          if (lengthptr != NULL) break;
4056    
4057          /* 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
4058          reference. */          reference. If the string started with "+" or "-" we require the rest to
4059            be digits, in which case recno will be set. */
4060    
4061            if (refsign > 0)
4062              {
4063              if (recno <= 0)
4064                {
4065                *errorcodeptr = ERR58;
4066                goto FAILED;
4067                }
4068              if (refsign == '-')
4069                {
4070                recno = cd->bracount - recno + 1;
4071                if (recno <= 0)
4072                  {
4073                  *errorcodeptr = ERR15;
4074                  goto FAILED;
4075                  }
4076                }
4077              else recno += cd->bracount;
4078              PUT2(code, 2+LINK_SIZE, recno);
4079              break;
4080              }
4081    
4082            /* Otherwise (did not start with "+" or "-"), start by looking for the
4083            name. */
4084    
4085          slot = cd->name_table;          slot = cd->name_table;
4086          for (i = 0; i < cd->names_found; i++)          for (i = 0; i < cd->names_found; i++)
# Line 3772  for (;; ptr++) Line 4172  for (;; ptr++)
4172    
4173          /* ------------------------------------------------------------ */          /* ------------------------------------------------------------ */
4174          case '!':                 /* Negative lookahead */          case '!':                 /* Negative lookahead */
         bravalue = OP_ASSERT_NOT;  
4175          ptr++;          ptr++;
4176            if (*ptr == ')')          /* Optimize (?!) */
4177              {
4178              *code++ = OP_FAIL;
4179              previous = NULL;
4180              continue;
4181              }
4182            bravalue = OP_ASSERT_NOT;
4183          break;          break;
4184    
4185    
# Line 3999  for (;; ptr++) Line 4405  for (;; ptr++)
4405    
4406    
4407          /* ------------------------------------------------------------ */          /* ------------------------------------------------------------ */
4408            case '-': case '+':
4409          case '0': case '1': case '2': case '3': case '4':   /* Recursion or */          case '0': case '1': case '2': case '3': case '4':   /* Recursion or */
4410          case '5': case '6': case '7': case '8': case '9':   /* subroutine */          case '5': case '6': case '7': case '8': case '9':   /* subroutine */
4411            {            {
4412            const uschar *called;            const uschar *called;
4413    
4414              if ((refsign = *ptr) == '+') ptr++;
4415              else if (refsign == '-')
4416                {
4417                if ((digitab[ptr[1]] & ctype_digit) == 0)
4418                  goto OTHER_CHAR_AFTER_QUERY;
4419                ptr++;
4420                }
4421    
4422            recno = 0;            recno = 0;
4423            while((digitab[*ptr] & ctype_digit) != 0)            while((digitab[*ptr] & ctype_digit) != 0)
4424              recno = recno * 10 + *ptr++ - '0';              recno = recno * 10 + *ptr++ - '0';
4425    
4426            if (*ptr != ')')            if (*ptr != ')')
4427              {              {
4428              *errorcodeptr = ERR29;              *errorcodeptr = ERR29;
4429              goto FAILED;              goto FAILED;
4430              }              }
4431    
4432              if (refsign == '-')
4433                {
4434                if (recno == 0)
4435                  {
4436                  *errorcodeptr = ERR58;
4437                  goto FAILED;
4438                  }
4439                recno = cd->bracount - recno + 1;
4440                if (recno <= 0)
4441                  {
4442                  *errorcodeptr = ERR15;
4443                  goto FAILED;
4444                  }
4445                }
4446              else if (refsign == '+')
4447                {
4448                if (recno == 0)
4449                  {
4450                  *errorcodeptr = ERR58;
4451                  goto FAILED;
4452                  }
4453                recno += cd->bracount;
4454                }
4455    
4456            /* Come here from code above that handles a named recursion */            /* Come here from code above that handles a named recursion */
4457    
4458            HANDLE_RECURSION:            HANDLE_RECURSION:
# Line 4084  for (;; ptr++) Line 4525  for (;; ptr++)
4525    
4526          /* ------------------------------------------------------------ */          /* ------------------------------------------------------------ */
4527          default:              /* Other characters: check option setting */          default:              /* Other characters: check option setting */
4528            OTHER_CHAR_AFTER_QUERY:
4529          set = unset = 0;          set = unset = 0;
4530          optset = &set;          optset = &set;
4531    
# Line 4218  for (;; ptr++) Line 4660  for (;; ptr++)
4660           errorcodeptr,                 /* Where to put an error message */           errorcodeptr,                 /* Where to put an error message */
4661           (bravalue == OP_ASSERTBACK ||           (bravalue == OP_ASSERTBACK ||
4662            bravalue == OP_ASSERTBACK_NOT), /* TRUE if back assert */            bravalue == OP_ASSERTBACK_NOT), /* TRUE if back assert */
4663             reset_bracount,               /* True if (?| group */
4664           skipbytes,                    /* Skip over bracket number */           skipbytes,                    /* Skip over bracket number */
4665           &subfirstbyte,                /* For possible first char */           &subfirstbyte,                /* For possible first char */
4666           &subreqbyte,                  /* For possible last char */           &subreqbyte,                  /* For possible last char */
# Line 4234  for (;; ptr++) Line 4677  for (;; ptr++)
4677      is on the bracket. */      is on the bracket. */
4678    
4679      /* 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
4680      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
4681        in the real compile phase, not in the pre-pass, where the whole group may
4682        not be available. */
4683    
4684      if (bravalue == OP_COND)      if (bravalue == OP_COND && lengthptr == NULL)
4685        {        {
4686        uschar *tc = code;        uschar *tc = code;
4687        int condcount = 0;        int condcount = 0;
# Line 4290  for (;; ptr++) Line 4735  for (;; ptr++)
4735    
4736      if (lengthptr != NULL)      if (lengthptr != NULL)
4737        {        {
4738          if (OFLOW_MAX - *lengthptr < length_prevgroup - 2 - 2*LINK_SIZE)
4739            {
4740            *errorcodeptr = ERR20;
4741            goto FAILED;
4742            }
4743        *lengthptr += length_prevgroup - 2 - 2*LINK_SIZE;        *lengthptr += length_prevgroup - 2 - 2*LINK_SIZE;
4744        code++;        code++;
4745        PUTINC(code, 0, 1 + LINK_SIZE);        PUTINC(code, 0, 1 + LINK_SIZE);
# Line 4396  for (;; ptr++) Line 4846  for (;; ptr++)
4846        zerofirstbyte = firstbyte;        zerofirstbyte = firstbyte;
4847        zeroreqbyte = reqbyte;        zeroreqbyte = reqbyte;
4848    
4849        /* \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).
4850          We also support \k{name} (.NET syntax) */
4851    
4852        if (-c == ESC_k && (ptr[1] == '<' || ptr[1] == '\''))        if (-c == ESC_k && (ptr[1] == '<' || ptr[1] == '\'' || ptr[1] == '{'))
4853          {          {
4854          is_recurse = FALSE;          is_recurse = FALSE;
4855          terminator = (*(++ptr) == '<')? '>' : '\'';          terminator = (*(++ptr) == '<')? '>' : (*ptr == '\'')? '\'' : '}';
4856          goto NAMED_REF_OR_RECURSE;          goto NAMED_REF_OR_RECURSE;
4857          }          }
4858    
# Line 4567  This function is used during the pre-com Line 5018  This function is used during the pre-com
5018  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
5019  value of lengthptr distinguishes the two phases.  value of lengthptr distinguishes the two phases.
5020    
5021  Argument:  Arguments:
5022    options        option bits, including any changes for this subpattern    options        option bits, including any changes for this subpattern
5023    oldims         previous settings of ims option bits    oldims         previous settings of ims option bits
5024    codeptr        -> the address of the current code pointer    codeptr        -> the address of the current code pointer
5025    ptrptr         -> the address of the current pattern pointer    ptrptr         -> the address of the current pattern pointer
5026    errorcodeptr   -> pointer to error code variable    errorcodeptr   -> pointer to error code variable
5027    lookbehind     TRUE if this is a lookbehind assertion    lookbehind     TRUE if this is a lookbehind assertion
5028      reset_bracount TRUE to reset the count for each branch
5029    skipbytes      skip this many bytes at start (for brackets and OP_COND)    skipbytes      skip this many bytes at start (for brackets and OP_COND)
5030    firstbyteptr   place to put the first required character, or a negative number    firstbyteptr   place to put the first required character, or a negative number
5031    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 5039  Returns: TRUE on success
5039    
5040  static BOOL  static BOOL
5041  compile_regex(int options, int oldims, uschar **codeptr, const uschar **ptrptr,  compile_regex(int options, int oldims, uschar **codeptr, const uschar **ptrptr,
5042    int *errorcodeptr, BOOL lookbehind, int skipbytes, int *firstbyteptr,    int *errorcodeptr, BOOL lookbehind, BOOL reset_bracount, int skipbytes,
5043    int *reqbyteptr, branch_chain *bcptr, compile_data *cd, int *lengthptr)    int *firstbyteptr, int *reqbyteptr, branch_chain *bcptr, compile_data *cd,
5044      int *lengthptr)
5045  {  {
5046  const uschar *ptr = *ptrptr;  const uschar *ptr = *ptrptr;
5047  uschar *code = *codeptr;  uschar *code = *codeptr;
# Line 4598  uschar *reverse_count = NULL; Line 5051  uschar *reverse_count = NULL;
5051  int firstbyte, reqbyte;  int firstbyte, reqbyte;
5052  int branchfirstbyte, branchreqbyte;  int branchfirstbyte, branchreqbyte;
5053  int length;  int length;
5054    int orig_bracount;
5055    int max_bracount;
5056  branch_chain bc;  branch_chain bc;
5057    
5058  bc.outer = bcptr;  bc.outer = bcptr;
# Line 4626  code += 1 + LINK_SIZE + skipbytes; Line 5081  code += 1 + LINK_SIZE + skipbytes;
5081    
5082  /* Loop for each alternative branch */  /* Loop for each alternative branch */
5083    
5084    orig_bracount = max_bracount = cd->bracount;
5085  for (;;)  for (;;)
5086    {    {
5087      /* For a (?| group, reset the capturing bracket count so that each branch
5088      uses the same numbers. */
5089    
5090      if (reset_bracount) cd->bracount = orig_bracount;
5091    
5092    /* Handle a change of ims options at the start of the branch */    /* Handle a change of ims options at the start of the branch */
5093    
5094    if ((options & PCRE_IMS) != oldims)    if ((options & PCRE_IMS) != oldims)
# Line 4657  for (;;) Line 5118  for (;;)
5118      return FALSE;      return FALSE;
5119      }      }
5120    
5121      /* Keep the highest bracket count in case (?| was used and some branch
5122      has fewer than the rest. */
5123    
5124      if (cd->bracount > max_bracount) max_bracount = cd->bracount;
5125    
5126    /* 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. */
5127    
5128    if (lengthptr == NULL)    if (lengthptr == NULL)
# Line 4720  for (;;) Line 5186  for (;;)
5186        }        }
5187      }      }
5188    
5189    /* Reached end of expression, either ')' or end of pattern. Go back through    /* Reached end of expression, either ')' or end of pattern. In the real
5190    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
5191    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
5192    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
5193    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
5194    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,
5195    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.
5196    at the terminating char. */    Return leaving the pointer at the terminating char. */
5197    
5198    if (*ptr != '|')    if (*ptr != '|')
5199      {      {
5200      int branch_length = code - last_branch;      if (lengthptr == NULL)
     do  
5201        {        {
5202        int prev_length = GET(last_branch, 1);        int branch_length = code - last_branch;
5203        PUT(last_branch, 1, branch_length);        do
5204        branch_length = prev_length;          {
5205        last_branch -= branch_length;          int prev_length = GET(last_branch, 1);
5206            PUT(last_branch, 1, branch_length);
5207            branch_length = prev_length;
5208            last_branch -= branch_length;
5209            }
5210          while (branch_length > 0);
5211        }        }
     while (branch_length > 0);  
5212    
5213      /* Fill in the ket */      /* Fill in the ket */
5214    
# Line 4756  for (;;) Line 5225  for (;;)
5225        length += 2;        length += 2;
5226        }        }
5227    
5228        /* Retain the highest bracket number, in case resetting was used. */
5229    
5230        cd->bracount = max_bracount;
5231    
5232      /* Set values to pass back */      /* Set values to pass back */
5233    
5234      *codeptr = code;      *codeptr = code;
5235      *ptrptr = ptr;      *ptrptr = ptr;
5236      *firstbyteptr = firstbyte;      *firstbyteptr = firstbyte;
5237      *reqbyteptr = reqbyte;      *reqbyteptr = reqbyte;
5238      if (lengthptr != NULL) *lengthptr += length;      if (lengthptr != NULL)
5239          {
5240          if (OFLOW_MAX - *lengthptr < length)
5241            {
5242            *errorcodeptr = ERR20;
5243            return FALSE;
5244            }
5245          *lengthptr += length;
5246          }
5247      return TRUE;      return TRUE;
5248      }      }
5249    
5250    /* 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
5251      pointer back to where it was for the start of the first branch. (That is,
5252      pretend that each branch is the only one.)
5253    
5254      In the real compile phase, insert an ALT node. Its length field points back
5255    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
5256    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
5257    zero offset until it is closed, making it possible to detect recursion. */    zero offset until it is closed, making it possible to detect recursion. */
5258    
5259    *code = OP_ALT;    if (lengthptr != NULL)
5260    PUT(code, 1, code - last_branch);      {
5261    bc.current = last_branch = code;      code = *codeptr + 1 + LINK_SIZE + skipbytes;
5262    code += 1 + LINK_SIZE;      length += 1 + LINK_SIZE;
5263        }
5264      else
5265        {
5266        *code = OP_ALT;
5267        PUT(code, 1, code - last_branch);
5268        bc.current = last_branch = code;
5269        code += 1 + LINK_SIZE;
5270        }
5271    
5272    ptr++;    ptr++;
   length += 1 + LINK_SIZE;  
5273    }    }
5274  /* Control never reaches here */  /* Control never reaches here */
5275  }  }
# Line 5138  cd->cbits = tables + cbits_offset; Line 5631  cd->cbits = tables + cbits_offset;
5631  cd->ctypes = tables + ctypes_offset;  cd->ctypes = tables + ctypes_offset;
5632    
5633  /* Handle different types of newline. The three bits give seven cases. The  /* Handle different types of newline. The three bits give seven cases. The
5634  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
5635    "anycrlf". */
5636    
5637  switch (options & (PCRE_NEWLINE_CRLF | PCRE_NEWLINE_ANY))  switch (options & (PCRE_NEWLINE_CRLF | PCRE_NEWLINE_ANY))
5638    {    {
# Line 5148  switch (options & (PCRE_NEWLINE_CRLF | P Line 5642  switch (options & (PCRE_NEWLINE_CRLF | P
5642    case PCRE_NEWLINE_CR+    case PCRE_NEWLINE_CR+
5643         PCRE_NEWLINE_LF: newline = ('\r' << 8) | '\n'; break;         PCRE_NEWLINE_LF: newline = ('\r' << 8) | '\n'; break;
5644    case PCRE_NEWLINE_ANY: newline = -1; break;    case PCRE_NEWLINE_ANY: newline = -1; break;
5645      case PCRE_NEWLINE_ANYCRLF: newline = -2; break;
5646    default: errorcode = ERR56; goto PCRE_EARLY_ERROR_RETURN;    default: errorcode = ERR56; goto PCRE_EARLY_ERROR_RETURN;
5647    }    }
5648    
5649  if (newline < 0)  if (newline == -2)
5650      {
5651      cd->nltype = NLTYPE_ANYCRLF;
5652      }
5653    else if (newline < 0)
5654    {    {
5655    cd->nltype = NLTYPE_ANY;    cd->nltype = NLTYPE_ANY;
5656    }    }
# Line 5212  outside can help speed up starting point Line 5711  outside can help speed up starting point
5711  code = cworkspace;  code = cworkspace;
5712  *code = OP_BRA;  *code = OP_BRA;
5713  (void)compile_regex(cd->external_options, cd->external_options & PCRE_IMS,  (void)compile_regex(cd->external_options, cd->external_options & PCRE_IMS,
5714    &code, &ptr, &errorcode, FALSE, 0, &firstbyte, &reqbyte, NULL, cd, &length);    &code, &ptr, &errorcode, FALSE, FALSE, 0, &firstbyte, &reqbyte, NULL, cd,
5715      &length);
5716  if (errorcode != 0) goto PCRE_EARLY_ERROR_RETURN;  if (errorcode != 0) goto PCRE_EARLY_ERROR_RETURN;
5717    
5718  DPRINTF(("end pre-compile: length=%d workspace=%d\n", length,  DPRINTF(("end pre-compile: length=%d workspace=%d\n", length,
# Line 5271  cd->start_code = codestart; Line 5771  cd->start_code = codestart;
5771  cd->hwm = cworkspace;  cd->hwm = cworkspace;
5772  cd->req_varyopt = 0;  cd->req_varyopt = 0;
5773  cd->nopartial = FALSE;  cd->nopartial = FALSE;
5774    cd->had_accept = FALSE;
5775    
5776  /* Set up a starting, non-extracting bracket, then compile the expression. On  /* Set up a starting, non-extracting bracket, then compile the expression. On
5777  error, errorcode will be set non-zero, so we don't need to look at the result  error, errorcode will be set non-zero, so we don't need to look at the result
# Line 5280  ptr = (const uschar *)pattern; Line 5781  ptr = (const uschar *)pattern;
5781  code = (uschar *)codestart;  code = (uschar *)codestart;
5782  *code = OP_BRA;  *code = OP_BRA;
5783  (void)compile_regex(re->options, re->options & PCRE_IMS, &code, &ptr,  (void)compile_regex(re->options, re->options & PCRE_IMS, &code, &ptr,
5784    &errorcode, FALSE, 0, &firstbyte, &reqbyte, NULL, cd, NULL);    &errorcode, FALSE, FALSE, 0, &firstbyte, &reqbyte, NULL, cd, NULL);
5785  re->top_bracket = cd->bracount;  re->top_bracket = cd->bracount;
5786  re->top_backref = cd->top_backref;  re->top_backref = cd->top_backref;
5787    
5788  if (cd->nopartial) re->options |= PCRE_NOPARTIAL;  if (cd->nopartial) re->options |= PCRE_NOPARTIAL;
5789    if (cd->had_accept) reqbyte = -1;   /* Must disable after (*ACCEPT) */
5790    
5791  /* If not reached end of pattern on success, there's an excess bracket. */  /* If not reached end of pattern on success, there's an excess bracket. */
5792    

Legend:
Removed from v.145  
changed lines
  Added in v.210

webmaster@exim.org
ViewVC Help
Powered by ViewVC 1.1.12