/[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 200 by ph10, Wed Aug 1 09:10:40 2007 UTC revision 213 by ph10, Wed Aug 15 11:34:14 2007 UTC
# Line 65  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 133  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 206  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 242  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 251  static const char *error_texts[] = { Line 279  static const char *error_texts[] = {
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 a braced name or 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"    "(?+ 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      "number is too big"
287  };  };
288    
289    
# Line 408  Arguments: Line 440  Arguments:
440    
441  Returns:         zero or positive => a data character  Returns:         zero or positive => a data character
442                   negative => a special escape sequence                   negative => a special escape sequence
443                   on error, errorptr is set                   on error, errorcodeptr is set
444  */  */
445    
446  static int  static int
# Line 492  else Line 524  else
524      c = 0;      c = 0;
525      while ((digitab[ptr[1]] & ctype_digit) != 0)      while ((digitab[ptr[1]] & ctype_digit) != 0)
526        c = c * 10 + *(++ptr) - '0';        c = c * 10 + *(++ptr) - '0';
527    
528        if (c < 0)
529          {
530          *errorcodeptr = ERR61;
531          break;
532          }
533    
534      if (c == 0 || (braced && *(++ptr) != '}'))      if (c == 0 || (braced && *(++ptr) != '}'))
535        {        {
536        *errorcodeptr = ERR57;        *errorcodeptr = ERR57;
537        return 0;        break;
538        }        }
539    
540      if (negated)      if (negated)
# Line 504  else Line 542  else
542        if (c > bracount)        if (c > bracount)
543          {          {
544          *errorcodeptr = ERR15;          *errorcodeptr = ERR15;
545          return 0;          break;
546          }          }
547        c = bracount - (c - 1);        c = bracount - (c - 1);
548        }        }
# Line 533  else Line 571  else
571        c -= '0';        c -= '0';
572        while ((digitab[ptr[1]] & ctype_digit) != 0)        while ((digitab[ptr[1]] & ctype_digit) != 0)
573          c = c * 10 + *(++ptr) - '0';          c = c * 10 + *(++ptr) - '0';
574          if (c < 0)
575            {
576            *errorcodeptr = ERR61;
577            break;
578            }
579        if (c < 10 || c <= bracount)        if (c < 10 || c <= bracount)
580          {          {
581          c = -(ESC_REF + c);          c = -(ESC_REF + c);
# Line 628  else Line 671  else
671      if (c == 0)      if (c == 0)
672        {        {
673        *errorcodeptr = ERR2;        *errorcodeptr = ERR2;
674        return 0;        break;
675        }        }
676    
677  #ifndef EBCDIC  /* ASCII coding */  #ifndef EBCDIC  /* ASCII coding */
# Line 934  for (; *ptr != 0; ptr++) Line 977  for (; *ptr != 0; ptr++)
977    /* An opening parens must now be a real metacharacter */    /* An opening parens must now be a real metacharacter */
978    
979    if (*ptr != '(') continue;    if (*ptr != '(') continue;
980    if (ptr[1] != '?')    if (ptr[1] != '?' && ptr[1] != '*')
981      {      {
982      count++;      count++;
983      if (name == NULL && count == lorn) return count;      if (name == NULL && count == lorn) return count;
# Line 1402  for (code = first_significant_code(code Line 1445  for (code = first_significant_code(code
1445    
1446    /* For other groups, scan the branches. */    /* For other groups, scan the branches. */
1447    
1448    if (c == OP_BRA || c == OP_CBRA || c == OP_ONCE)    if (c == OP_BRA || c == OP_CBRA || c == OP_ONCE || c == OP_COND)
1449      {      {
1450      BOOL empty_branch;      BOOL empty_branch;
1451      if (GET(code, 1) == 0) return TRUE;    /* Hit unclosed bracket */      if (GET(code, 1) == 0) return TRUE;    /* Hit unclosed bracket */
# Line 2258  for (;; ptr++) Line 2301  for (;; ptr++)
2301      */      */
2302    
2303      if (code < last_code) code = last_code;      if (code < last_code) code = last_code;
2304    
2305        /* Paranoid check for integer overflow */
2306    
2307        if (OFLOW_MAX - *lengthptr < code - last_code)
2308          {
2309          *errorcodeptr = ERR20;
2310          goto FAILED;
2311          }
2312    
2313      *lengthptr += code - last_code;      *lengthptr += code - last_code;
2314      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));
2315    
# Line 2370  for (;; ptr++) Line 2422  for (;; ptr++)
2422      *ptrptr = ptr;      *ptrptr = ptr;
2423      if (lengthptr != NULL)      if (lengthptr != NULL)
2424        {        {
2425          if (OFLOW_MAX - *lengthptr < code - last_code)
2426            {
2427            *errorcodeptr = ERR20;
2428            goto FAILED;
2429            }
2430        *lengthptr += code - last_code;   /* To include callout length */        *lengthptr += code - last_code;   /* To include callout length */
2431        DPRINTF((">> end branch\n"));        DPRINTF((">> end branch\n"));
2432        }        }
# Line 2432  for (;; ptr++) Line 2489  for (;; ptr++)
2489        goto FAILED;        goto FAILED;
2490        }        }
2491    
2492      /* 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,
2493        if the first few characters (either before or after ^) are \Q\E or \E we
2494        skip them too. This makes for compatibility with Perl. */
2495    
2496      if ((c = *(++ptr)) == '^')      negate_class = FALSE;
2497        for (;;)
2498        {        {
       negate_class = TRUE;  
2499        c = *(++ptr);        c = *(++ptr);
2500        }        if (c == '\\')
2501      else          {
2502        {          if (ptr[1] == 'E') ptr++;
2503        negate_class = FALSE;            else if (strncmp((const char *)ptr+1, "Q\\E", 3) == 0) ptr += 3;
2504                else break;
2505            }
2506          else if (!negate_class && c == '^')
2507            negate_class = TRUE;
2508          else break;
2509        }        }
2510    
2511      /* 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 2582  for (;; ptr++) Line 2646  for (;; ptr++)
2646        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
2647        case. Inside a class (and only there) it is treated as backspace.        case. Inside a class (and only there) it is treated as backspace.
2648        Elsewhere it marks a word boundary. Other escapes have preset maps ready        Elsewhere it marks a word boundary. Other escapes have preset maps ready
2649        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
2650        character in them, so set class_charcount bigger than one. */        character in them, so set class_charcount bigger than one. */
2651    
2652        if (c == '\\')        if (c == '\\')
# Line 3524  for (;; ptr++) Line 3588  for (;; ptr++)
3588          goto FAILED;          goto FAILED;
3589          }          }
3590    
       /* This is a paranoid check to stop integer overflow later on */  
   
       if (len > MAX_DUPLENGTH)  
         {  
         *errorcodeptr = ERR50;  
         goto FAILED;  
         }  
   
3591        /* 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
3592        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
3593        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 3620  for (;; ptr++) Line 3676  for (;; ptr++)
3676          if (repeat_min > 1)          if (repeat_min > 1)
3677            {            {
3678            /* 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
3679            just adjust the length as if we had. */            just adjust the length as if we had. Do some paranoid checks for
3680              potential integer overflow. */
3681    
3682            if (lengthptr != NULL)            if (lengthptr != NULL)
3683              *lengthptr += (repeat_min - 1)*length_prevgroup;              {
3684                int delta = (repeat_min - 1)*length_prevgroup;
3685                if ((double)(repeat_min - 1)*(double)length_prevgroup >
3686                                                                (double)INT_MAX ||
3687                    OFLOW_MAX - *lengthptr < delta)
3688                  {
3689                  *errorcodeptr = ERR20;
3690                  goto FAILED;
3691                  }
3692                *lengthptr += delta;
3693                }
3694    
3695            /* This is compiling for real */            /* This is compiling for real */
3696    
# Line 3661  for (;; ptr++) Line 3728  for (;; ptr++)
3728          /* 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
3729          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
3730          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
3731          add 2 + 2*LINKSIZE to allow for the nesting that occurs. */          add 2 + 2*LINKSIZE to allow for the nesting that occurs. Do some
3732            paranoid checks to avoid integer overflow. */
3733    
3734          if (lengthptr != NULL && repeat_max > 0)          if (lengthptr != NULL && repeat_max > 0)
3735            *lengthptr += repeat_max * (length_prevgroup + 1 + 2 + 2*LINK_SIZE) -            {
3736              2 - 2*LINK_SIZE;  /* Last one doesn't nest */            int delta = repeat_max * (length_prevgroup + 1 + 2 + 2*LINK_SIZE) -
3737                          2 - 2*LINK_SIZE;   /* Last one doesn't nest */
3738              if ((double)repeat_max *
3739                    (double)(length_prevgroup + 1 + 2 + 2*LINK_SIZE)
3740                      > (double)INT_MAX ||
3741                  OFLOW_MAX - *lengthptr < delta)
3742                {
3743                *errorcodeptr = ERR20;
3744                goto FAILED;
3745                }
3746              *lengthptr += delta;
3747              }
3748    
3749          /* This is compiling for real */          /* This is compiling for real */
3750    
# Line 3817  for (;; ptr++) Line 3896  for (;; ptr++)
3896      /* ===================================================================*/      /* ===================================================================*/
3897      /* Start of nested parenthesized sub-expression, or comment or lookahead or      /* Start of nested parenthesized sub-expression, or comment or lookahead or
3898      lookbehind or option setting or condition or all the other extended      lookbehind or option setting or condition or all the other extended
3899      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. */  
3900    
3901      case '(':      case '(':
3902      newoptions = options;      newoptions = options;
# Line 3828  for (;; ptr++) Line 3905  for (;; ptr++)
3905      save_hwm = cd->hwm;      save_hwm = cd->hwm;
3906      reset_bracount = FALSE;      reset_bracount = FALSE;
3907    
3908      if (*(++ptr) == '?')      /* First deal with various "verbs" that can be introduced by '*'. */
3909    
3910        if (*(++ptr) == '*' && (cd->ctypes[ptr[1]] & ctype_letter) != 0)
3911          {
3912          int i, namelen;
3913          const uschar *name = ++ptr;
3914          previous = NULL;
3915          while ((cd->ctypes[*++ptr] & ctype_letter) != 0);
3916          if (*ptr == ':')
3917            {
3918            *errorcodeptr = ERR59;   /* Not supported */
3919            goto FAILED;
3920            }
3921          if (*ptr != ')')
3922            {
3923            *errorcodeptr = ERR60;
3924            goto FAILED;
3925            }
3926          namelen = ptr - name;
3927          for (i = 0; i < verbcount; i++)
3928            {
3929            if (namelen == verbs[i].len &&
3930                strncmp((char *)name, verbs[i].name, namelen) == 0)
3931              {
3932              *code = verbs[i].op;
3933              if (*code++ == OP_ACCEPT) cd->had_accept = TRUE;
3934              break;
3935              }
3936            }
3937          if (i < verbcount) continue;
3938          *errorcodeptr = ERR60;
3939          goto FAILED;
3940          }
3941    
3942        /* Deal with the extended parentheses; all are introduced by '?', and the
3943        appearance of any of them means that this is not a capturing group. */
3944    
3945        else if (*ptr == '?')
3946        {        {
3947        int i, set, unset, namelen;        int i, set, unset, namelen;
3948        int *optset;        int *optset;
# Line 4070  for (;; ptr++) Line 4184  for (;; ptr++)
4184    
4185          /* ------------------------------------------------------------ */          /* ------------------------------------------------------------ */
4186          case '!':                 /* Negative lookahead */          case '!':                 /* Negative lookahead */
         bravalue = OP_ASSERT_NOT;  
4187          ptr++;          ptr++;
4188            if (*ptr == ')')          /* Optimize (?!) */
4189              {
4190              *code++ = OP_FAIL;
4191              previous = NULL;
4192              continue;
4193              }
4194            bravalue = OP_ASSERT_NOT;
4195          break;          break;
4196    
4197    
# Line 4627  for (;; ptr++) Line 4747  for (;; ptr++)
4747    
4748      if (lengthptr != NULL)      if (lengthptr != NULL)
4749        {        {
4750          if (OFLOW_MAX - *lengthptr < length_prevgroup - 2 - 2*LINK_SIZE)
4751            {
4752            *errorcodeptr = ERR20;
4753            goto FAILED;
4754            }
4755        *lengthptr += length_prevgroup - 2 - 2*LINK_SIZE;        *lengthptr += length_prevgroup - 2 - 2*LINK_SIZE;
4756        code++;        code++;
4757        PUTINC(code, 0, 1 + LINK_SIZE);        PUTINC(code, 0, 1 + LINK_SIZE);
# Line 5122  for (;;) Line 5247  for (;;)
5247      *ptrptr = ptr;      *ptrptr = ptr;
5248      *firstbyteptr = firstbyte;      *firstbyteptr = firstbyte;
5249      *reqbyteptr = reqbyte;      *reqbyteptr = reqbyte;
5250      if (lengthptr != NULL) *lengthptr += length;      if (lengthptr != NULL)
5251          {
5252          if (OFLOW_MAX - *lengthptr < length)
5253            {
5254            *errorcodeptr = ERR20;
5255            return FALSE;
5256            }
5257          *lengthptr += length;
5258          }
5259      return TRUE;      return TRUE;
5260      }      }
5261    
# Line 5650  cd->start_code = codestart; Line 5783  cd->start_code = codestart;
5783  cd->hwm = cworkspace;  cd->hwm = cworkspace;
5784  cd->req_varyopt = 0;  cd->req_varyopt = 0;
5785  cd->nopartial = FALSE;  cd->nopartial = FALSE;
5786    cd->had_accept = FALSE;
5787    
5788  /* Set up a starting, non-extracting bracket, then compile the expression. On  /* Set up a starting, non-extracting bracket, then compile the expression. On
5789  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 5664  re->top_bracket = cd->bracount; Line 5798  re->top_bracket = cd->bracount;
5798  re->top_backref = cd->top_backref;  re->top_backref = cd->top_backref;
5799    
5800  if (cd->nopartial) re->options |= PCRE_NOPARTIAL;  if (cd->nopartial) re->options |= PCRE_NOPARTIAL;
5801    if (cd->had_accept) reqbyte = -1;   /* Must disable after (*ACCEPT) */
5802    
5803  /* 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. */
5804    

Legend:
Removed from v.200  
changed lines
  Added in v.213

  ViewVC Help
Powered by ViewVC 1.1.5