/[pcre]/code/branches/pcre16/pcre_compile.c
ViewVC logotype

Diff of /code/branches/pcre16/pcre_compile.c

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

revision 180 by ph10, Wed Jun 13 10:59:18 2007 UTC revision 206 by ph10, Fri Aug 3 14:53:04 2007 UTC
# Line 42  POSSIBILITY OF SUCH DAMAGE. Line 42  POSSIBILITY OF SUCH DAMAGE.
42  supporting internal functions that are not used by other modules. */  supporting internal functions that are not used by other modules. */
43    
44    
45    #ifdef HAVE_CONFIG_H
46    #include <config.h>
47    #endif
48    
49  #define NLBLOCK cd             /* Block containing newline information */  #define NLBLOCK cd             /* Block containing newline information */
50  #define PSSTART start_pattern  /* Field containing processed string start */  #define PSSTART start_pattern  /* Field containing processed string start */
51  #define PSEND   end_pattern    /* Field containing processed string end */  #define PSEND   end_pattern    /* Field containing processed string end */
52    
   
53  #include "pcre_internal.h"  #include "pcre_internal.h"
54    
55    
# Line 62  used by pcretest. DEBUG is not defined w Line 65  used by pcretest. DEBUG is not defined w
65    
66  #define SETBIT(a,b) a[b/8] |= (1 << (b%8))  #define SETBIT(a,b) a[b/8] |= (1 << (b%8))
67    
68    /* Maximum length value to check against when making sure that the integer that
69    holds the compiled pattern length does not overflow. We make it a bit less than
70    INT_MAX to allow for adding in group terminating bytes, so that we don't have
71    to check them every time. */
72    
73    #define OFLOW_MAX (INT_MAX - 20)
74    
75    
76  /*************************************************  /*************************************************
77  *      Code parameters and static tables         *  *      Code parameters and static tables         *
# Line 120  static const short int escapes[] = { Line 130  static const short int escapes[] = {
130  /*  B8 */     0,     0,      0,       0,      0,   ']',    '=',    '-',  /*  B8 */     0,     0,      0,       0,      0,   ']',    '=',    '-',
131  /*  C0 */   '{',-ESC_A, -ESC_B,  -ESC_C, -ESC_D,-ESC_E,      0, -ESC_G,  /*  C0 */   '{',-ESC_A, -ESC_B,  -ESC_C, -ESC_D,-ESC_E,      0, -ESC_G,
132  /*  C8 */-ESC_H,     0,      0,       0,      0,     0,      0,      0,  /*  C8 */-ESC_H,     0,      0,       0,      0,     0,      0,      0,
133  /*  D0 */   '}',     0,      0,       0,      0,     0,      0, -ESC_P,  /*  D0 */   '}',     0, -ESC_K,       0,      0,     0,      0, -ESC_P,
134  /*  D8 */-ESC_Q,-ESC_R,      0,       0,      0,     0,      0,      0,  /*  D8 */-ESC_Q,-ESC_R,      0,       0,      0,     0,      0,      0,
135  /*  E0 */  '\\',     0, -ESC_S,       0,      0,-ESC_V, -ESC_W, -ESC_X,  /*  E0 */  '\\',     0, -ESC_S,       0,      0,-ESC_V, -ESC_W, -ESC_X,
136  /*  E8 */     0,-ESC_Z,      0,       0,      0,     0,      0,      0,  /*  E8 */     0,-ESC_Z,      0,       0,      0,     0,      0,      0,
# Line 203  static const char *error_texts[] = { Line 213  static const char *error_texts[] = {
213    "missing ) after comment",    "missing ) after comment",
214    "parentheses nested too deeply",  /** DEAD **/    "parentheses nested too deeply",  /** DEAD **/
215    /* 20 */    /* 20 */
216    "regular expression too large",    "regular expression is too large",
217    "failed to get memory",    "failed to get memory",
218    "unmatched parentheses",    "unmatched parentheses",
219    "internal error: code overflow",    "internal error: code overflow",
# Line 239  static const char *error_texts[] = { Line 249  static const char *error_texts[] = {
249    "subpattern name is too long (maximum " XSTRING(MAX_NAME_SIZE) " characters)",    "subpattern name is too long (maximum " XSTRING(MAX_NAME_SIZE) " characters)",
250    "too many named subpatterns (maximum " XSTRING(MAX_NAME_COUNT) ")",    "too many named subpatterns (maximum " XSTRING(MAX_NAME_COUNT) ")",
251    /* 50 */    /* 50 */
252    "repeated subpattern is too long",    "repeated subpattern is too long",    /** DEAD **/
253    "octal value is greater than \\377 (not in UTF-8 mode)",    "octal value is greater than \\377 (not in UTF-8 mode)",
254    "internal error: overran compiling workspace",    "internal error: overran compiling workspace",
255    "internal error: previously-checked referenced subpattern not found",    "internal error: previously-checked referenced subpattern not found",
# Line 701  if (c == '{') Line 711  if (c == '{')
711      *negptr = TRUE;      *negptr = TRUE;
712      ptr++;      ptr++;
713      }      }
714    for (i = 0; i < sizeof(name) - 1; i++)    for (i = 0; i < (int)sizeof(name) - 1; i++)
715      {      {
716      c = *(++ptr);      c = *(++ptr);
717      if (c == 0) goto ERROR_RETURN;      if (c == 0) goto ERROR_RETURN;
# Line 1399  for (code = first_significant_code(code Line 1409  for (code = first_significant_code(code
1409    
1410    /* For other groups, scan the branches. */    /* For other groups, scan the branches. */
1411    
1412    if (c == OP_BRA || c == OP_CBRA || c == OP_ONCE)    if (c == OP_BRA || c == OP_CBRA || c == OP_ONCE || 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 2026  switch(op_code) Line 2036  switch(op_code)
2036    
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:      case ESC_h:
2041      case ESC_H:      case ESC_H:
2042      switch(item)      switch(item)
# Line 2053  switch(op_code) Line 2063  switch(op_code)
2063        return -next != ESC_h;        return -next != ESC_h;
2064        default:        default:
2065        return -next == ESC_h;        return -next == ESC_h;
2066        }        }
2067    
2068      case ESC_v:      case ESC_v:
2069      case ESC_V:      case ESC_V:
2070      switch(item)      switch(item)
# Line 2069  switch(op_code) Line 2079  switch(op_code)
2079        return -next != ESC_v;        return -next != ESC_v;
2080        default:        default:
2081        return -next == ESC_v;        return -next == ESC_v;
2082        }        }
2083    
2084      default:      default:
2085      return FALSE;      return FALSE;
# Line 2093  switch(op_code) Line 2103  switch(op_code)
2103    
2104    case OP_NOT_HSPACE:    case OP_NOT_HSPACE:
2105    return next == -ESC_h;    return next == -ESC_h;
2106    
2107    /* Can't have \S in here because VT matches \S (Perl anomaly) */    /* Can't have \S in here because VT matches \S (Perl anomaly) */
2108    case OP_VSPACE:    case OP_VSPACE:
2109    return next == -ESC_V || next == -ESC_d || next == -ESC_w;    return next == -ESC_V || next == -ESC_d || next == -ESC_w;
2110    
2111    case OP_NOT_VSPACE:    case OP_NOT_VSPACE:
2112    return next == -ESC_v;    return next == -ESC_v;
2113    
2114    case OP_WORDCHAR:    case OP_WORDCHAR:
2115    return next == -ESC_W || next == -ESC_s || next == -ESC_h || next == -ESC_v;    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;
2119    
2120    default:    default:
2121    return FALSE;    return FALSE;
2122    }    }
# Line 2255  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 2367  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 2429  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      if ((c = *(++ptr)) == '^')      skip them too. This makes for compatibility with Perl. */
2459    
2460        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
2476      of just a single character (as long as it's < 256). However, For higher      of just a single character (as long as it's < 256). However, For higher
# Line 2579  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 3044  for (;; ptr++) Line 3075  for (;; ptr++)
3075        *errorcodeptr = ERR6;        *errorcodeptr = ERR6;
3076        goto FAILED;        goto FAILED;
3077        }        }
3078    
3079      /* If class_charcount is 1, we saw precisely one character whose value is      /* If class_charcount is 1, we saw precisely one character whose value is
3080      less than 256. In non-UTF-8 mode we can always optimize. In UTF-8 mode, we      less than 256. In non-UTF-8 mode we can always optimize. In UTF-8 mode, we
3081      can optimize the negative case only if there were no characters >= 128      can optimize the negative case only if there were no characters >= 128
# Line 3521  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 3617  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 3658  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 4624  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 5119  for (;;) Line 5170  for (;;)
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    

Legend:
Removed from v.180  
changed lines
  Added in v.206

  ViewVC Help
Powered by ViewVC 1.1.5