/[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 1520 by ph10, Sun Feb 8 16:29:23 2015 UTC revision 1538 by ph10, Sun Mar 29 11:22:24 2015 UTC
# Line 2497  for (code = first_significant_code(code Line 2497  for (code = first_significant_code(code
2497        empty_branch = FALSE;        empty_branch = FALSE;
2498        do        do
2499          {          {
2500          if (!empty_branch && could_be_empty_branch(code, endcode, utf, cd, NULL))          if (!empty_branch && could_be_empty_branch(code, endcode, utf, cd,
2501            empty_branch = TRUE;            recurses)) empty_branch = TRUE;
2502          code += GET(code, 1);          code += GET(code, 1);
2503          }          }
2504        while (*code == OP_ALT);        while (*code == OP_ALT);
# Line 3093  Returns:      TRUE if the auto-possessif Line 3093  Returns:      TRUE if the auto-possessif
3093    
3094  static BOOL  static BOOL
3095  compare_opcodes(const pcre_uchar *code, BOOL utf, const compile_data *cd,  compare_opcodes(const pcre_uchar *code, BOOL utf, const compile_data *cd,
3096    const pcre_uint32 *base_list, const pcre_uchar *base_end)    const pcre_uint32 *base_list, const pcre_uchar *base_end, int *rec_limit)
3097  {  {
3098  pcre_uchar c;  pcre_uchar c;
3099  pcre_uint32 list[8];  pcre_uint32 list[8];
# Line 3110  pcre_uint32 chr; Line 3110  pcre_uint32 chr;
3110  BOOL accepted, invert_bits;  BOOL accepted, invert_bits;
3111  BOOL entered_a_group = FALSE;  BOOL entered_a_group = FALSE;
3112    
3113    if (*rec_limit == 0) return FALSE;
3114    --(*rec_limit);
3115    
3116  /* Note: the base_list[1] contains whether the current opcode has greedy  /* Note: the base_list[1] contains whether the current opcode has greedy
3117  (represented by a non-zero value) quantifier. This is a different from  (represented by a non-zero value) quantifier. This is a different from
3118  other character type lists, which stores here that the character iterator  other character type lists, which stores here that the character iterator
# Line 3180  for(;;) Line 3183  for(;;)
3183    
3184      while (*next_code == OP_ALT)      while (*next_code == OP_ALT)
3185        {        {
3186        if (!compare_opcodes(code, utf, cd, base_list, base_end)) return FALSE;        if (!compare_opcodes(code, utf, cd, base_list, base_end, rec_limit))
3187            return FALSE;
3188        code = next_code + 1 + LINK_SIZE;        code = next_code + 1 + LINK_SIZE;
3189        next_code += GET(next_code, 1);        next_code += GET(next_code, 1);
3190        }        }
# Line 3200  for(;;) Line 3204  for(;;)
3204      /* The bracket content will be checked by the      /* The bracket content will be checked by the
3205      OP_BRA/OP_CBRA case above. */      OP_BRA/OP_CBRA case above. */
3206      next_code += 1 + LINK_SIZE;      next_code += 1 + LINK_SIZE;
3207      if (!compare_opcodes(next_code, utf, cd, base_list, base_end))      if (!compare_opcodes(next_code, utf, cd, base_list, base_end, rec_limit))
3208        return FALSE;        return FALSE;
3209    
3210      code += PRIV(OP_lengths)[c];      code += PRIV(OP_lengths)[c];
# Line 3633  register pcre_uchar c; Line 3637  register pcre_uchar c;
3637  const pcre_uchar *end;  const pcre_uchar *end;
3638  pcre_uchar *repeat_opcode;  pcre_uchar *repeat_opcode;
3639  pcre_uint32 list[8];  pcre_uint32 list[8];
3640    int rec_limit;
3641    
3642  for (;;)  for (;;)
3643    {    {
3644    c = *code;    c = *code;
3645    
3646    /* When a pattern with bad UTF-8 encoding is compiled with NO_UTF_CHECK,    /* When a pattern with bad UTF-8 encoding is compiled with NO_UTF_CHECK,
3647    it may compile without complaining, but may get into a loop here if the code    it may compile without complaining, but may get into a loop here if the code
3648    pointer points to a bad value. This is, of course a documentated possibility,    pointer points to a bad value. This is, of course a documentated possibility,
3649    when NO_UTF_CHECK is set, so it isn't a bug, but we can detect this case and    when NO_UTF_CHECK is set, so it isn't a bug, but we can detect this case and
3650    just give up on this optimization. */    just give up on this optimization. */
3651    
3652    if (c >= OP_TABLE_LENGTH) return;    if (c >= OP_TABLE_LENGTH) return;
3653    
3654    if (c >= OP_STAR && c <= OP_TYPEPOSUPTO)    if (c >= OP_STAR && c <= OP_TYPEPOSUPTO)
3655      {      {
3656      c -= get_repeat_base(c) - OP_STAR;      c -= get_repeat_base(c) - OP_STAR;
# Line 3653  for (;;) Line 3658  for (;;)
3658        get_chr_property_list(code, utf, cd->fcc, list) : NULL;        get_chr_property_list(code, utf, cd->fcc, list) : NULL;
3659      list[1] = c == OP_STAR || c == OP_PLUS || c == OP_QUERY || c == OP_UPTO;      list[1] = c == OP_STAR || c == OP_PLUS || c == OP_QUERY || c == OP_UPTO;
3660    
3661      if (end != NULL && compare_opcodes(end, utf, cd, list, end))      rec_limit = 10000;
3662        if (end != NULL && compare_opcodes(end, utf, cd, list, end, &rec_limit))
3663        {        {
3664        switch(c)        switch(c)
3665          {          {
# Line 3709  for (;;) Line 3715  for (;;)
3715    
3716        list[1] = (c & 1) == 0;        list[1] = (c & 1) == 0;
3717    
3718        if (compare_opcodes(end, utf, cd, list, end))        rec_limit = 10000;
3719          if (compare_opcodes(end, utf, cd, list, end, &rec_limit))
3720          {          {
3721          switch (c)          switch (c)
3722            {            {
# Line 3983  Arguments: Line 3990  Arguments:
3990    adjust     the amount by which the group is to be moved    adjust     the amount by which the group is to be moved
3991    utf        TRUE in UTF-8 / UTF-16 / UTF-32 mode    utf        TRUE in UTF-8 / UTF-16 / UTF-32 mode
3992    cd         contains pointers to tables etc.    cd         contains pointers to tables etc.
3993    save_hwm   the hwm forward reference pointer at the start of the group    save_hwm_offset   the hwm forward reference offset at the start of the group
3994    
3995  Returns:     nothing  Returns:     nothing
3996  */  */
3997    
3998  static void  static void
3999  adjust_recurse(pcre_uchar *group, int adjust, BOOL utf, compile_data *cd,  adjust_recurse(pcre_uchar *group, int adjust, BOOL utf, compile_data *cd,
4000    pcre_uchar *save_hwm)    size_t save_hwm_offset)
4001  {  {
4002  pcre_uchar *ptr = group;  pcre_uchar *ptr = group;
4003    
# Line 4002  while ((ptr = (pcre_uchar *)find_recurse Line 4009  while ((ptr = (pcre_uchar *)find_recurse
4009    /* See if this recursion is on the forward reference list. If so, adjust the    /* See if this recursion is on the forward reference list. If so, adjust the
4010    reference. */    reference. */
4011    
4012    for (hc = save_hwm; hc < cd->hwm; hc += LINK_SIZE)    for (hc = (pcre_uchar *)cd->start_workspace + save_hwm_offset; hc < cd->hwm;
4013           hc += LINK_SIZE)
4014      {      {
4015      offset = (int)GET(hc, 0);      offset = (int)GET(hc, 0);
4016      if (cd->start_code + offset == ptr + 1)      if (cd->start_code + offset == ptr + 1)
# Line 4207  if ((options & PCRE_CASELESS) != 0) Line 4215  if ((options & PCRE_CASELESS) != 0)
4215        range. Otherwise, use a recursive call to add the additional range. */        range. Otherwise, use a recursive call to add the additional range. */
4216    
4217        else if (oc < start && od >= start - 1) start = oc; /* Extend downwards */        else if (oc < start && od >= start - 1) start = oc; /* Extend downwards */
4218        else if (od > end && oc <= end + 1) end = od;       /* Extend upwards */        else if (od > end && oc <= end + 1)
4219            {
4220            end = od;       /* Extend upwards */
4221            if (end > classbits_end) classbits_end = (end <= 0xff ? end : 0xff);
4222            }
4223        else n8 += add_to_class(classbits, uchardptr, options, cd, oc, od);        else n8 += add_to_class(classbits, uchardptr, options, cd, oc, od);
4224        }        }
4225      }      }
# Line 4447  const pcre_uchar *tempptr; Line 4459  const pcre_uchar *tempptr;
4459  const pcre_uchar *nestptr = NULL;  const pcre_uchar *nestptr = NULL;
4460  pcre_uchar *previous = NULL;  pcre_uchar *previous = NULL;
4461  pcre_uchar *previous_callout = NULL;  pcre_uchar *previous_callout = NULL;
4462  pcre_uchar *save_hwm = NULL;  size_t save_hwm_offset = 0;
4463  pcre_uint8 classbits[32];  pcre_uint8 classbits[32];
4464    
4465  /* We can fish out the UTF-8 setting once and for all into a BOOL, but we  /* We can fish out the UTF-8 setting once and for all into a BOOL, but we
# Line 5508  for (;; ptr++) Line 5520  for (;; ptr++)
5520        }        }
5521  #endif  #endif
5522    
5523        /* Even though any XCLASS list is now discarded, we must allow for
5524        its memory. */
5525    
5526        if (lengthptr != NULL)
5527          *lengthptr += (int)(class_uchardata - class_uchardata_base);
5528    
5529      /* If there are no characters > 255, or they are all to be included or      /* If there are no characters > 255, or they are all to be included or
5530      excluded, set the opcode to OP_CLASS or OP_NCLASS, depending on whether the      excluded, set the opcode to OP_CLASS or OP_NCLASS, depending on whether the
5531      whole class was negated and whether there were negative specials such as \S      whole class was negated and whether there were negative specials such as \S
# Line 5960  for (;; ptr++) Line 5978  for (;; ptr++)
5978          if (repeat_max <= 1)    /* Covers 0, 1, and unlimited */          if (repeat_max <= 1)    /* Covers 0, 1, and unlimited */
5979            {            {
5980            *code = OP_END;            *code = OP_END;
5981            adjust_recurse(previous, 1, utf, cd, save_hwm);            adjust_recurse(previous, 1, utf, cd, save_hwm_offset);
5982            memmove(previous + 1, previous, IN_UCHARS(len));            memmove(previous + 1, previous, IN_UCHARS(len));
5983            code++;            code++;
5984            if (repeat_max == 0)            if (repeat_max == 0)
# Line 5984  for (;; ptr++) Line 6002  for (;; ptr++)
6002            {            {
6003            int offset;            int offset;
6004            *code = OP_END;            *code = OP_END;
6005            adjust_recurse(previous, 2 + LINK_SIZE, utf, cd, save_hwm);            adjust_recurse(previous, 2 + LINK_SIZE, utf, cd, save_hwm_offset);
6006            memmove(previous + 2 + LINK_SIZE, previous, IN_UCHARS(len));            memmove(previous + 2 + LINK_SIZE, previous, IN_UCHARS(len));
6007            code += 2 + LINK_SIZE;            code += 2 + LINK_SIZE;
6008            *previous++ = OP_BRAZERO + repeat_type;            *previous++ = OP_BRAZERO + repeat_type;
# Line 6047  for (;; ptr++) Line 6065  for (;; ptr++)
6065              for (i = 1; i < repeat_min; i++)              for (i = 1; i < repeat_min; i++)
6066                {                {
6067                pcre_uchar *hc;                pcre_uchar *hc;
6068                pcre_uchar *this_hwm = cd->hwm;                size_t this_hwm_offset = cd->hwm - cd->start_workspace;
6069                memcpy(code, previous, IN_UCHARS(len));                memcpy(code, previous, IN_UCHARS(len));
6070    
6071                while (cd->hwm > cd->start_workspace + cd->workspace_size -                while (cd->hwm > cd->start_workspace + cd->workspace_size -
6072                       WORK_SIZE_SAFETY_MARGIN - (this_hwm - save_hwm))                       WORK_SIZE_SAFETY_MARGIN -
6073                         (this_hwm_offset - save_hwm_offset))
6074                  {                  {
                 size_t save_offset = save_hwm - cd->start_workspace;  
                 size_t this_offset = this_hwm - cd->start_workspace;  
6075                  *errorcodeptr = expand_workspace(cd);                  *errorcodeptr = expand_workspace(cd);
6076                  if (*errorcodeptr != 0) goto FAILED;                  if (*errorcodeptr != 0) goto FAILED;
                 save_hwm = (pcre_uchar *)cd->start_workspace + save_offset;  
                 this_hwm = (pcre_uchar *)cd->start_workspace + this_offset;  
6077                  }                  }
6078    
6079                for (hc = save_hwm; hc < this_hwm; hc += LINK_SIZE)                for (hc = (pcre_uchar *)cd->start_workspace + save_hwm_offset;
6080                       hc < (pcre_uchar *)cd->start_workspace + this_hwm_offset;
6081                       hc += LINK_SIZE)
6082                  {                  {
6083                  PUT(cd->hwm, 0, GET(hc, 0) + len);                  PUT(cd->hwm, 0, GET(hc, 0) + len);
6084                  cd->hwm += LINK_SIZE;                  cd->hwm += LINK_SIZE;
6085                  }                  }
6086                save_hwm = this_hwm;                save_hwm_offset = this_hwm_offset;
6087                code += len;                code += len;
6088                }                }
6089              }              }
# Line 6111  for (;; ptr++) Line 6128  for (;; ptr++)
6128          else for (i = repeat_max - 1; i >= 0; i--)          else for (i = repeat_max - 1; i >= 0; i--)
6129            {            {
6130            pcre_uchar *hc;            pcre_uchar *hc;
6131            pcre_uchar *this_hwm = cd->hwm;            size_t this_hwm_offset = cd->hwm - cd->start_workspace;
6132    
6133            *code++ = OP_BRAZERO + repeat_type;            *code++ = OP_BRAZERO + repeat_type;
6134    
# Line 6133  for (;; ptr++) Line 6150  for (;; ptr++)
6150            copying them. */            copying them. */
6151    
6152            while (cd->hwm > cd->start_workspace + cd->workspace_size -            while (cd->hwm > cd->start_workspace + cd->workspace_size -
6153                   WORK_SIZE_SAFETY_MARGIN - (this_hwm - save_hwm))                   WORK_SIZE_SAFETY_MARGIN -
6154                     (this_hwm_offset - save_hwm_offset))
6155              {              {
             size_t save_offset = save_hwm - cd->start_workspace;  
             size_t this_offset = this_hwm - cd->start_workspace;  
6156              *errorcodeptr = expand_workspace(cd);              *errorcodeptr = expand_workspace(cd);
6157              if (*errorcodeptr != 0) goto FAILED;              if (*errorcodeptr != 0) goto FAILED;
             save_hwm = (pcre_uchar *)cd->start_workspace + save_offset;  
             this_hwm = (pcre_uchar *)cd->start_workspace + this_offset;  
6158              }              }
6159    
6160            for (hc = save_hwm; hc < this_hwm; hc += LINK_SIZE)            for (hc = (pcre_uchar *)cd->start_workspace + save_hwm_offset;
6161                   hc < (pcre_uchar *)cd->start_workspace + this_hwm_offset;
6162                   hc += LINK_SIZE)
6163              {              {
6164              PUT(cd->hwm, 0, GET(hc, 0) + len + ((i != 0)? 2+LINK_SIZE : 1));              PUT(cd->hwm, 0, GET(hc, 0) + len + ((i != 0)? 2+LINK_SIZE : 1));
6165              cd->hwm += LINK_SIZE;              cd->hwm += LINK_SIZE;
6166              }              }
6167            save_hwm = this_hwm;            save_hwm_offset = this_hwm_offset;
6168            code += len;            code += len;
6169            }            }
6170    
# Line 6244  for (;; ptr++) Line 6260  for (;; ptr++)
6260                {                {
6261                int nlen = (int)(code - bracode);                int nlen = (int)(code - bracode);
6262                *code = OP_END;                *code = OP_END;
6263                adjust_recurse(bracode, 1 + LINK_SIZE, utf, cd, save_hwm);                adjust_recurse(bracode, 1 + LINK_SIZE, utf, cd, save_hwm_offset);
6264                memmove(bracode + 1 + LINK_SIZE, bracode, IN_UCHARS(nlen));                memmove(bracode + 1 + LINK_SIZE, bracode, IN_UCHARS(nlen));
6265                code += 1 + LINK_SIZE;                code += 1 + LINK_SIZE;
6266                nlen += 1 + LINK_SIZE;                nlen += 1 + LINK_SIZE;
# Line 6378  for (;; ptr++) Line 6394  for (;; ptr++)
6394          else          else
6395            {            {
6396            *code = OP_END;            *code = OP_END;
6397            adjust_recurse(tempcode, 1 + LINK_SIZE, utf, cd, save_hwm);            adjust_recurse(tempcode, 1 + LINK_SIZE, utf, cd, save_hwm_offset);
6398            memmove(tempcode + 1 + LINK_SIZE, tempcode, IN_UCHARS(len));            memmove(tempcode + 1 + LINK_SIZE, tempcode, IN_UCHARS(len));
6399            code += 1 + LINK_SIZE;            code += 1 + LINK_SIZE;
6400            len += 1 + LINK_SIZE;            len += 1 + LINK_SIZE;
# Line 6427  for (;; ptr++) Line 6443  for (;; ptr++)
6443    
6444          default:          default:
6445          *code = OP_END;          *code = OP_END;
6446          adjust_recurse(tempcode, 1 + LINK_SIZE, utf, cd, save_hwm);          adjust_recurse(tempcode, 1 + LINK_SIZE, utf, cd, save_hwm_offset);
6447          memmove(tempcode + 1 + LINK_SIZE, tempcode, IN_UCHARS(len));          memmove(tempcode + 1 + LINK_SIZE, tempcode, IN_UCHARS(len));
6448          code += 1 + LINK_SIZE;          code += 1 + LINK_SIZE;
6449          len += 1 + LINK_SIZE;          len += 1 + LINK_SIZE;
# Line 6456  for (;; ptr++) Line 6472  for (;; ptr++)
6472      parenthesis forms.  */      parenthesis forms.  */
6473    
6474      case CHAR_LEFT_PARENTHESIS:      case CHAR_LEFT_PARENTHESIS:
6475      newoptions = options;      ptr++;
     skipbytes = 0;  
     bravalue = OP_CBRA;  
     save_hwm = cd->hwm;  
     reset_bracount = FALSE;  
6476    
6477      /* First deal with various "verbs" that can be introduced by '*'. */      /* First deal with comments. Putting this code right at the start ensures
6478        that comments have no bad side effects. */
6479    
6480        if (ptr[0] == CHAR_QUESTION_MARK && ptr[1] == CHAR_NUMBER_SIGN)
6481          {
6482          ptr += 2;
6483          while (*ptr != CHAR_NULL && *ptr != CHAR_RIGHT_PARENTHESIS) ptr++;
6484          if (*ptr == CHAR_NULL)
6485            {
6486            *errorcodeptr = ERR18;
6487            goto FAILED;
6488            }
6489          continue;
6490          }
6491    
6492        /* Now deal with various "verbs" that can be introduced by '*'. */
6493    
     ptr++;  
6494      if (ptr[0] == CHAR_ASTERISK && (ptr[1] == ':'      if (ptr[0] == CHAR_ASTERISK && (ptr[1] == ':'
6495           || (MAX_255(ptr[1]) && ((cd->ctypes[ptr[1]] & ctype_letter) != 0))))           || (MAX_255(ptr[1]) && ((cd->ctypes[ptr[1]] & ctype_letter) != 0))))
6496        {        {
# Line 6585  for (;; ptr++) Line 6611  for (;; ptr++)
6611        goto FAILED;        goto FAILED;
6612        }        }
6613    
6614        /* Initialize for "real" parentheses */
6615    
6616        newoptions = options;
6617        skipbytes = 0;
6618        bravalue = OP_CBRA;
6619        save_hwm_offset = cd->hwm - cd->start_workspace;
6620        reset_bracount = FALSE;
6621    
6622      /* Deal with the extended parentheses; all are introduced by '?', and the      /* Deal with the extended parentheses; all are introduced by '?', and the
6623      appearance of any of them means that this is not a capturing group. */      appearance of any of them means that this is not a capturing group. */
6624    
6625      else if (*ptr == CHAR_QUESTION_MARK)      if (*ptr == CHAR_QUESTION_MARK)
6626        {        {
6627        int i, set, unset, namelen;        int i, set, unset, namelen;
6628        int *optset;        int *optset;
# Line 6597  for (;; ptr++) Line 6631  for (;; ptr++)
6631    
6632        switch (*(++ptr))        switch (*(++ptr))
6633          {          {
         case CHAR_NUMBER_SIGN:                 /* Comment; skip to ket */  
         ptr++;  
         while (*ptr != CHAR_NULL && *ptr != CHAR_RIGHT_PARENTHESIS) ptr++;  
         if (*ptr == CHAR_NULL)  
           {  
           *errorcodeptr = ERR18;  
           goto FAILED;  
           }  
         continue;  
   
   
6634          /* ------------------------------------------------------------ */          /* ------------------------------------------------------------ */
6635          case CHAR_VERTICAL_LINE:  /* Reset capture count for each branch */          case CHAR_VERTICAL_LINE:  /* Reset capture count for each branch */
6636          reset_bracount = TRUE;          reset_bracount = TRUE;
# Line 6657  for (;; ptr++) Line 6680  for (;; ptr++)
6680                (tempptr[2] == CHAR_EQUALS_SIGN ||                (tempptr[2] == CHAR_EQUALS_SIGN ||
6681                 tempptr[2] == CHAR_EXCLAMATION_MARK ||                 tempptr[2] == CHAR_EXCLAMATION_MARK ||
6682                 tempptr[2] == CHAR_LESS_THAN_SIGN))                 tempptr[2] == CHAR_LESS_THAN_SIGN))
6683              {
6684              cd->iscondassert = TRUE;
6685            break;            break;
6686              }
6687    
6688          /* Other conditions use OP_CREF/OP_DNCREF/OP_RREF/OP_DNRREF, and all          /* Other conditions use OP_CREF/OP_DNCREF/OP_RREF/OP_DNRREF, and all
6689          need to skip at least 1+IMM2_SIZE bytes at the start of the group. */          need to skip at least 1+IMM2_SIZE bytes at the start of the group. */
# Line 6734  for (;; ptr++) Line 6760  for (;; ptr++)
6760              ptr++;              ptr++;
6761              }              }
6762            namelen = (int)(ptr - name);            namelen = (int)(ptr - name);
6763            if (lengthptr != NULL && (options & PCRE_DUPNAMES) != 0)            if (lengthptr != NULL) *lengthptr += IMM2_SIZE;
             *lengthptr += IMM2_SIZE;  
6764            }            }
6765    
6766          /* Check the terminator */          /* Check the terminator */
# Line 6771  for (;; ptr++) Line 6796  for (;; ptr++)
6796              goto FAILED;              goto FAILED;
6797              }              }
6798            PUT2(code, 2+LINK_SIZE, recno);            PUT2(code, 2+LINK_SIZE, recno);
6799            if (recno > cd->top_backref) cd->top_backref = recno;            if (recno > cd->top_backref) cd->top_backref = recno;
6800            break;            break;
6801            }            }
6802    
# Line 6794  for (;; ptr++) Line 6819  for (;; ptr++)
6819            int offset = i++;            int offset = i++;
6820            int count = 1;            int count = 1;
6821            recno = GET2(slot, 0);   /* Number from first found */            recno = GET2(slot, 0);   /* Number from first found */
6822            if (recno > cd->top_backref) cd->top_backref = recno;            if (recno > cd->top_backref) cd->top_backref = recno;
6823            for (; i < cd->names_found; i++)            for (; i < cd->names_found; i++)
6824              {              {
6825              slot += cd->name_entry_size;              slot += cd->name_entry_size;
# Line 7152  for (;; ptr++) Line 7177  for (;; ptr++)
7177    
7178            if (!is_recurse) cd->namedrefcount++;            if (!is_recurse) cd->namedrefcount++;
7179    
7180            /* If duplicate names are permitted, we have to allow for a named            /* We have to allow for a named reference to a duplicated name (this
7181            reference to a duplicated name (this cannot be determined until the            cannot be determined until the second pass). This needs an extra
7182            second pass). This needs an extra 16-bit data item. */            16-bit data item. */
7183    
7184            if ((options & PCRE_DUPNAMES) != 0) *lengthptr += IMM2_SIZE;            *lengthptr += IMM2_SIZE;
7185            }            }
7186    
7187          /* In the real compile, search the name table. We check the name          /* In the real compile, search the name table. We check the name
# Line 7513  for (;; ptr++) Line 7538  for (;; ptr++)
7538        goto FAILED;        goto FAILED;
7539        }        }
7540    
7541      /* Assertions used not to be repeatable, but this was changed for Perl      /* All assertions used not to be repeatable, but this was changed for Perl
7542      compatibility, so all kinds can now be repeated. We copy code into a      compatibility. All kinds can now be repeated except for assertions that are
7543        conditions (Perl also forbids these to be repeated). We copy code into a
7544      non-register variable (tempcode) in order to be able to pass its address      non-register variable (tempcode) in order to be able to pass its address
7545      because some compilers complain otherwise. */      because some compilers complain otherwise. At the start of a conditional
7546        group whose condition is an assertion, cd->iscondassert is set. We unset it
7547        here so as to allow assertions later in the group to be quantified. */
7548    
7549        if (bravalue >= OP_ASSERT && bravalue <= OP_ASSERTBACK_NOT &&
7550            cd->iscondassert)
7551          {
7552          previous = NULL;
7553          cd->iscondassert = FALSE;
7554          }
7555        else previous = code;
7556    
     previous = code;                      /* For handling repetition */  
7557      *code = bravalue;      *code = bravalue;
7558      tempcode = code;      tempcode = code;
7559      tempreqvary = cd->req_varyopt;        /* Save value before bracket */      tempreqvary = cd->req_varyopt;        /* Save value before bracket */
# Line 7765  for (;; ptr++) Line 7800  for (;; ptr++)
7800          const pcre_uchar *p;          const pcre_uchar *p;
7801          pcre_uint32 cf;          pcre_uint32 cf;
7802    
7803          save_hwm = cd->hwm;   /* Normally this is set when '(' is read */          save_hwm_offset = cd->hwm - cd->start_workspace;   /* Normally this is set when '(' is read */
7804          terminator = (*(++ptr) == CHAR_LESS_THAN_SIGN)?          terminator = (*(++ptr) == CHAR_LESS_THAN_SIGN)?
7805            CHAR_GREATER_THAN_SIGN : CHAR_APOSTROPHE;            CHAR_GREATER_THAN_SIGN : CHAR_APOSTROPHE;
7806    
# Line 8092  int length; Line 8127  int length;
8127  unsigned int orig_bracount;  unsigned int orig_bracount;
8128  unsigned int max_bracount;  unsigned int max_bracount;
8129  branch_chain bc;  branch_chain bc;
8130    size_t save_hwm_offset;
8131    
8132  /* If set, call the external function that checks for stack availability. */  /* If set, call the external function that checks for stack availability. */
8133    
# Line 8109  bc.current_branch = code; Line 8145  bc.current_branch = code;
8145  firstchar = reqchar = 0;  firstchar = reqchar = 0;
8146  firstcharflags = reqcharflags = REQ_UNSET;  firstcharflags = reqcharflags = REQ_UNSET;
8147    
8148    save_hwm_offset = cd->hwm - cd->start_workspace;
8149    
8150  /* Accumulate the length for use in the pre-compile phase. Start with the  /* Accumulate the length for use in the pre-compile phase. Start with the
8151  length of the BRA and KET and any extra bytes that are required at the  length of the BRA and KET and any extra bytes that are required at the
8152  beginning. We accumulate in a local variable to save frequent testing of  beginning. We accumulate in a local variable to save frequent testing of
# Line 8311  for (;;) Line 8349  for (;;)
8349          {          {
8350          *code = OP_END;          *code = OP_END;
8351          adjust_recurse(start_bracket, 1 + LINK_SIZE,          adjust_recurse(start_bracket, 1 + LINK_SIZE,
8352            (options & PCRE_UTF8) != 0, cd, cd->hwm);            (options & PCRE_UTF8) != 0, cd, save_hwm_offset);
8353          memmove(start_bracket + 1 + LINK_SIZE, start_bracket,          memmove(start_bracket + 1 + LINK_SIZE, start_bracket,
8354            IN_UCHARS(code - start_bracket));            IN_UCHARS(code - start_bracket));
8355          *start_bracket = OP_ONCE;          *start_bracket = OP_ONCE;
# Line 8535  do { Line 8573  do {
8573         case OP_RREF:         case OP_RREF:
8574         case OP_DNRREF:         case OP_DNRREF:
8575         case OP_DEF:         case OP_DEF:
8576           case OP_FAIL:
8577         return FALSE;         return FALSE;
8578    
8579         default:     /* Assertion */         default:     /* Assertion */
# Line 9119  cd->dupnames = FALSE; Line 9158  cd->dupnames = FALSE;
9158  cd->namedrefcount = 0;  cd->namedrefcount = 0;
9159  cd->start_code = cworkspace;  cd->start_code = cworkspace;
9160  cd->hwm = cworkspace;  cd->hwm = cworkspace;
9161    cd->iscondassert = FALSE;
9162  cd->start_workspace = cworkspace;  cd->start_workspace = cworkspace;
9163  cd->workspace_size = COMPILE_WORK_SIZE;  cd->workspace_size = COMPILE_WORK_SIZE;
9164  cd->named_groups = named_groups;  cd->named_groups = named_groups;
# Line 9156  if (length > MAX_PATTERN_SIZE) Line 9196  if (length > MAX_PATTERN_SIZE)
9196    goto PCRE_EARLY_ERROR_RETURN;    goto PCRE_EARLY_ERROR_RETURN;
9197    }    }
9198    
 /* If there are groups with duplicate names and there are also references by  
 name, we must allow for the possibility of named references to duplicated  
 groups. These require an extra data item each. */  
   
 if (cd->dupnames && cd->namedrefcount > 0)  
   length += cd->namedrefcount * IMM2_SIZE * sizeof(pcre_uchar);  
   
9199  /* Compute the size of the data block for storing the compiled pattern. Integer  /* Compute the size of the data block for storing the compiled pattern. Integer
9200  overflow should no longer be possible because nowadays we limit the maximum  overflow should no longer be possible because nowadays we limit the maximum
9201  value of cd->names_found and cd->name_entry_size. */  value of cd->names_found and cd->name_entry_size. */
# Line 9221  cd->name_table = (pcre_uchar *)re + re-> Line 9254  cd->name_table = (pcre_uchar *)re + re->
9254  codestart = cd->name_table + re->name_entry_size * re->name_count;  codestart = cd->name_table + re->name_entry_size * re->name_count;
9255  cd->start_code = codestart;  cd->start_code = codestart;
9256  cd->hwm = (pcre_uchar *)(cd->start_workspace);  cd->hwm = (pcre_uchar *)(cd->start_workspace);
9257    cd->iscondassert = FALSE;
9258  cd->req_varyopt = 0;  cd->req_varyopt = 0;
9259  cd->had_accept = FALSE;  cd->had_accept = FALSE;
9260  cd->had_pruneorskip = FALSE;  cd->had_pruneorskip = FALSE;

Legend:
Removed from v.1520  
changed lines
  Added in v.1538

  ViewVC Help
Powered by ViewVC 1.1.5