/[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 807 by ph10, Sun Dec 18 10:03:38 2011 UTC revision 835 by ph10, Wed Dec 28 16:10:09 2011 UTC
# Line 88  so this number is very generous. Line 88  so this number is very generous.
88  The same workspace is used during the second, actual compile phase for  The same workspace is used during the second, actual compile phase for
89  remembering forward references to groups so that they can be filled in at the  remembering forward references to groups so that they can be filled in at the
90  end. Each entry in this list occupies LINK_SIZE bytes, so even when LINK_SIZE  end. Each entry in this list occupies LINK_SIZE bytes, so even when LINK_SIZE
91  is 4 there is plenty of room for most patterns. However, the memory can get  is 4 there is plenty of room. */
 filled up by repetitions of forward references, for example patterns like  
 /(?1){0,1999}(b)/, and one user did hit the limit. The code has been changed so  
 that the workspace is expanded using malloc() in this situation. The value  
 below is therefore a minimum, and we put a maximum on it for safety. The  
 minimum is now also defined in terms of LINK_SIZE so that the use of malloc()  
 kicks in at the same number of forward references in all cases. */  
92    
93  #define COMPILE_WORK_SIZE (2048*LINK_SIZE)  #define COMPILE_WORK_SIZE (4096)
 #define COMPILE_WORK_SIZE_MAX (100*COMPILE_WORK_SIZE)  
94    
95  /* The overrun tests check for a slightly smaller size so that they detect the  /* The overrun tests check for a slightly smaller size so that they detect the
96  overrun before it actually does run off the end of the data block. */  overrun before it actually does run off the end of the data block. */
97    
98  #define WORK_SIZE_SAFETY_MARGIN (100)  #define WORK_SIZE_CHECK (COMPILE_WORK_SIZE - 100)
99    
100    
101  /* Table for handling escaped characters in the range '0'-'z'. Positive returns  /* Table for handling escaped characters in the range '0'-'z'. Positive returns
# Line 419  static const char error_texts[] = Line 412  static const char error_texts[] =
412    "\\k is not followed by a braced, angle-bracketed, or quoted name\0"    "\\k is not followed by a braced, angle-bracketed, or quoted name\0"
413    /* 70 */    /* 70 */
414    "internal error: unknown opcode in find_fixedlength()\0"    "internal error: unknown opcode in find_fixedlength()\0"
   "\\N is not supported in a class\0"  
   "too many forward references\0"  
415    ;    ;
416    
417  /* Table to identify digits and hex digits. This is used when compiling  /* Table to identify digits and hex digits. This is used when compiling
# Line 589  return s; Line 580  return s;
580    
581    
582  /*************************************************  /*************************************************
 *           Expand the workspace                 *  
 *************************************************/  
   
 /* This function is called during the second compiling phase, if the number of  
 forward references fills the existing workspace, which is originally a block on  
 the stack. A larger block is obtained from malloc() unless the ultimate limit  
 has been reached or the increase will be rather small.  
   
 Argument: pointer to the compile data block  
 Returns:  0 if all went well, else an error number  
 */  
   
 static int  
 expand_workspace(compile_data *cd)  
 {  
 uschar *newspace;  
 int newsize = cd->workspace_size * 2;  
   
 if (newsize > COMPILE_WORK_SIZE_MAX) newsize = COMPILE_WORK_SIZE_MAX;  
 if (cd->workspace_size >= COMPILE_WORK_SIZE_MAX ||  
     newsize - cd->workspace_size < WORK_SIZE_SAFETY_MARGIN)  
  return ERR72;  
   
 newspace = (pcre_malloc)(newsize);  
 if (newspace == NULL) return ERR21;  
   
 memcpy(newspace, cd->start_workspace, cd->workspace_size);  
 cd->hwm = (uschar *)newspace + (cd->hwm - cd->start_workspace);  
 if (cd->workspace_size > COMPILE_WORK_SIZE)  
   (pcre_free)((void *)cd->start_workspace);  
 cd->start_workspace = newspace;  
 cd->workspace_size = newsize;  
 return 0;  
 }  
   
   
   
 /*************************************************  
583  *            Check for counted repeat            *  *            Check for counted repeat            *
584  *************************************************/  *************************************************/
585    
# Line 1655  for (;;) Line 1608  for (;;)
1608      case OP_ASSERTBACK:      case OP_ASSERTBACK:
1609      case OP_ASSERTBACK_NOT:      case OP_ASSERTBACK_NOT:
1610      do cc += GET(cc, 1); while (*cc == OP_ALT);      do cc += GET(cc, 1); while (*cc == OP_ALT);
1611      cc += _pcre_OP_lengths[*cc];      /* Fall through */
     break;  
1612    
1613      /* Skip over things that don't match chars */      /* Skip over things that don't match chars */
1614    
# Line 1750  for (;;) Line 1702  for (;;)
1702      cc++;      cc++;
1703      break;      break;
1704    
1705      /* The single-byte matcher isn't allowed. This only happens in UTF-8 mode;      /* The single-byte matcher isn't allowed. This only happens in UTF-8 mode;
1706      otherwise \C is coded as OP_ALLANY. */      otherwise \C is coded as OP_ALLANY. */
1707    
1708      case OP_ANYBYTE:      case OP_ANYBYTE:
# Line 3378  for (;; ptr++) Line 3330  for (;; ptr++)
3330  #ifdef PCRE_DEBUG  #ifdef PCRE_DEBUG
3331      if (code > cd->hwm) cd->hwm = code;                 /* High water info */      if (code > cd->hwm) cd->hwm = code;                 /* High water info */
3332  #endif  #endif
3333      if (code > cd->start_workspace + cd->workspace_size -      if (code > cd->start_workspace + WORK_SIZE_CHECK)   /* Check for overrun */
         WORK_SIZE_SAFETY_MARGIN)                       /* Check for overrun */  
3334        {        {
3335        *errorcodeptr = ERR52;        *errorcodeptr = ERR52;
3336        goto FAILED;        goto FAILED;
# Line 3429  for (;; ptr++) Line 3380  for (;; ptr++)
3380    /* In the real compile phase, just check the workspace used by the forward    /* In the real compile phase, just check the workspace used by the forward
3381    reference list. */    reference list. */
3382    
3383    else if (cd->hwm > cd->start_workspace + cd->workspace_size -    else if (cd->hwm > cd->start_workspace + WORK_SIZE_CHECK)
            WORK_SIZE_SAFETY_MARGIN)  
3384      {      {
3385      *errorcodeptr = ERR52;      *errorcodeptr = ERR52;
3386      goto FAILED;      goto FAILED;
# Line 3684  for (;; ptr++) Line 3634  for (;; ptr++)
3634    
3635        if (lengthptr != NULL)        if (lengthptr != NULL)
3636          {          {
3637          *lengthptr += (int)(class_utf8data - class_utf8data_base);          *lengthptr += class_utf8data - class_utf8data_base;
3638          class_utf8data = class_utf8data_base;          class_utf8data = class_utf8data_base;
3639          }          }
3640    
# Line 3820  for (;; ptr++) Line 3770  for (;; ptr++)
3770          if (*errorcodeptr != 0) goto FAILED;          if (*errorcodeptr != 0) goto FAILED;
3771    
3772          if (-c == ESC_b) c = CHAR_BS;    /* \b is backspace in a class */          if (-c == ESC_b) c = CHAR_BS;    /* \b is backspace in a class */
         else if (-c == ESC_N)            /* \N is not supported in a class */  
           {  
           *errorcodeptr = ERR71;  
           goto FAILED;  
           }  
3773          else if (-c == ESC_Q)            /* Handle start of quoted string */          else if (-c == ESC_Q)            /* Handle start of quoted string */
3774            {            {
3775            if (ptr[1] == CHAR_BACKSLASH && ptr[2] == CHAR_E)            if (ptr[1] == CHAR_BACKSLASH && ptr[2] == CHAR_E)
# Line 4383  for (;; ptr++) Line 4328  for (;; ptr++)
4328    
4329        /* Now fill in the complete length of the item */        /* Now fill in the complete length of the item */
4330    
4331        PUT(previous, 1, (int)(code - previous));        PUT(previous, 1, code - previous);
4332        break;   /* End of class handling */        break;   /* End of class handling */
4333        }        }
4334  #endif  #endif
# Line 4481  for (;; ptr++) Line 4426  for (;; ptr++)
4426      past, but it no longer happens for non-repeated recursions. In fact, the      past, but it no longer happens for non-repeated recursions. In fact, the
4427      repeated ones could be re-implemented independently so as not to need this,      repeated ones could be re-implemented independently so as not to need this,
4428      but for the moment we rely on the code for repeating groups. */      but for the moment we rely on the code for repeating groups. */
4429    
4430      if (*previous == OP_RECURSE)      if (*previous == OP_RECURSE)
4431        {        {
4432        memmove(previous + 1 + LINK_SIZE, previous, 1 + LINK_SIZE);        memmove(previous + 1 + LINK_SIZE, previous, 1 + LINK_SIZE);
# Line 4525  for (;; ptr++) Line 4470  for (;; ptr++)
4470          {          {
4471          uschar *lastchar = code - 1;          uschar *lastchar = code - 1;
4472          while((*lastchar & 0xc0) == 0x80) lastchar--;          while((*lastchar & 0xc0) == 0x80) lastchar--;
4473          c = (int)(code - lastchar);     /* Length of UTF-8 character */          c = code - lastchar;            /* Length of UTF-8 character */
4474          memcpy(utf8_char, lastchar, c); /* Save the char */          memcpy(utf8_char, lastchar, c); /* Save the char */
4475          c |= 0x80;                      /* Flag c as a length */          c |= 0x80;                      /* Flag c as a length */
4476          }          }
# Line 4932  for (;; ptr++) Line 4877  for (;; ptr++)
4877              *lengthptr += delta;              *lengthptr += delta;
4878              }              }
4879    
4880            /* This is compiling for real. If there is a set first byte for            /* This is compiling for real */
           the group, and we have not yet set a "required byte", set it. Make  
           sure there is enough workspace for copying forward references before  
           doing the copy. */  
4881    
4882            else            else
4883              {              {
4884              if (groupsetfirstbyte && reqbyte < 0) reqbyte = firstbyte;              if (groupsetfirstbyte && reqbyte < 0) reqbyte = firstbyte;
   
4885              for (i = 1; i < repeat_min; i++)              for (i = 1; i < repeat_min; i++)
4886                {                {
4887                uschar *hc;                uschar *hc;
4888                uschar *this_hwm = cd->hwm;                uschar *this_hwm = cd->hwm;
4889                memcpy(code, previous, len);                memcpy(code, previous, len);
   
               while (cd->hwm > cd->start_workspace + cd->workspace_size -  
                      WORK_SIZE_SAFETY_MARGIN - (this_hwm - save_hwm))  
                 {  
                 int save_offset = save_hwm - cd->start_workspace;  
                 int this_offset = this_hwm - cd->start_workspace;  
                 *errorcodeptr = expand_workspace(cd);  
                 if (*errorcodeptr != 0) goto FAILED;  
                 save_hwm = (uschar *)cd->start_workspace + save_offset;  
                 this_hwm = (uschar *)cd->start_workspace + this_offset;  
                 }  
   
4890                for (hc = save_hwm; hc < this_hwm; hc += LINK_SIZE)                for (hc = save_hwm; hc < this_hwm; hc += LINK_SIZE)
4891                  {                  {
4892                  PUT(cd->hwm, 0, GET(hc, 0) + len);                  PUT(cd->hwm, 0, GET(hc, 0) + len);
# Line 5025  for (;; ptr++) Line 4954  for (;; ptr++)
4954              }              }
4955    
4956            memcpy(code, previous, len);            memcpy(code, previous, len);
   
           /* Ensure there is enough workspace for forward references before  
           copying them. */  
   
           while (cd->hwm > cd->start_workspace + cd->workspace_size -  
                  WORK_SIZE_SAFETY_MARGIN - (this_hwm - save_hwm))  
             {  
             int save_offset = save_hwm - cd->start_workspace;  
             int this_offset = this_hwm - cd->start_workspace;  
             *errorcodeptr = expand_workspace(cd);  
             if (*errorcodeptr != 0) goto FAILED;  
             save_hwm = (uschar *)cd->start_workspace + save_offset;  
             this_hwm = (uschar *)cd->start_workspace + this_offset;  
             }  
   
4957            for (hc = save_hwm; hc < this_hwm; hc += LINK_SIZE)            for (hc = save_hwm; hc < this_hwm; hc += LINK_SIZE)
4958              {              {
4959              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));
# Line 5070  for (;; ptr++) Line 4984  for (;; ptr++)
4984        ONCE brackets can be converted into non-capturing brackets, as the        ONCE brackets can be converted into non-capturing brackets, as the
4985        behaviour of (?:xx)++ is the same as (?>xx)++ and this saves having to        behaviour of (?:xx)++ is the same as (?>xx)++ and this saves having to
4986        deal with possessive ONCEs specially.        deal with possessive ONCEs specially.
4987    
4988        Otherwise, when we are doing the actual compile phase, check to see        Otherwise, when we are doing the actual compile phase, check to see
4989        whether this group is one that could match an empty string. If so,        whether this group is one that could match an empty string. If so,
4990        convert the initial operator to the S form (e.g. OP_BRA -> OP_SBRA) so        convert the initial operator to the S form (e.g. OP_BRA -> OP_SBRA) so
4991        that runtime checking can be done. [This check is also applied to ONCE        that runtime checking can be done. [This check is also applied to ONCE
4992        groups at runtime, but in a different way.]        groups at runtime, but in a different way.]
4993    
4994        Then, if the quantifier was possessive and the bracket is not a        Then, if the quantifier was possessive and the bracket is not a
4995        conditional, we convert the BRA code to the POS form, and the KET code to        conditional, we convert the BRA code to the POS form, and the KET code to
4996        KETRPOS. (It turns out to be convenient at runtime to detect this kind of        KETRPOS. (It turns out to be convenient at runtime to detect this kind of
4997        subpattern at both the start and at the end.) The use of special opcodes        subpattern at both the start and at the end.) The use of special opcodes
4998        makes it possible to reduce greatly the stack usage in pcre_exec(). If        makes it possible to reduce greatly the stack usage in pcre_exec(). If
4999        the group is preceded by OP_BRAZERO, convert this to OP_BRAPOSZERO.        the group is preceded by OP_BRAZERO, convert this to OP_BRAPOSZERO.
5000    
5001        Then, if the minimum number of matches is 1 or 0, cancel the possessive        Then, if the minimum number of matches is 1 or 0, cancel the possessive
5002        flag so that the default action below, of wrapping everything inside        flag so that the default action below, of wrapping everything inside
5003        atomic brackets, does not happen. When the minimum is greater than 1,        atomic brackets, does not happen. When the minimum is greater than 1,
5004        there will be earlier copies of the group, and so we still have to wrap        there will be earlier copies of the group, and so we still have to wrap
5005        the whole thing. */        the whole thing. */
5006    
5007        else        else
# Line 5096  for (;; ptr++) Line 5010  for (;; ptr++)
5010          uschar *bracode = ketcode - GET(ketcode, 1);          uschar *bracode = ketcode - GET(ketcode, 1);
5011    
5012          /* Convert possessive ONCE brackets to non-capturing */          /* Convert possessive ONCE brackets to non-capturing */
5013    
5014          if ((*bracode == OP_ONCE || *bracode == OP_ONCE_NC) &&          if ((*bracode == OP_ONCE || *bracode == OP_ONCE_NC) &&
5015              possessive_quantifier) *bracode = OP_BRA;              possessive_quantifier) *bracode = OP_BRA;
5016    
5017          /* For non-possessive ONCE brackets, all we need to do is to          /* For non-possessive ONCE brackets, all we need to do is to
5018          set the KET. */          set the KET. */
5019    
5020          if (*bracode == OP_ONCE || *bracode == OP_ONCE_NC)          if (*bracode == OP_ONCE || *bracode == OP_ONCE_NC)
5021            *ketcode = OP_KETRMAX + repeat_type;            *ketcode = OP_KETRMAX + repeat_type;
5022    
5023          /* Handle non-ONCE brackets and possessive ONCEs (which have been          /* Handle non-ONCE brackets and possessive ONCEs (which have been
5024          converted to non-capturing above). */          converted to non-capturing above). */
5025    
5026          else          else
5027            {            {
5028            /* In the compile phase, check for empty string matching. */            /* In the compile phase, check for empty string matching. */
5029    
5030            if (lengthptr == NULL)            if (lengthptr == NULL)
5031              {              {
5032              uschar *scode = bracode;              uschar *scode = bracode;
# Line 5127  for (;; ptr++) Line 5041  for (;; ptr++)
5041                }                }
5042              while (*scode == OP_ALT);              while (*scode == OP_ALT);
5043              }              }
5044    
5045            /* Handle possessive quantifiers. */            /* Handle possessive quantifiers. */
5046    
5047            if (possessive_quantifier)            if (possessive_quantifier)
# Line 5136  for (;; ptr++) Line 5050  for (;; ptr++)
5050              repeated non-capturing bracket, because we have not invented POS              repeated non-capturing bracket, because we have not invented POS
5051              versions of the COND opcodes. Because we are moving code along, we              versions of the COND opcodes. Because we are moving code along, we
5052              must ensure that any pending recursive references are updated. */              must ensure that any pending recursive references are updated. */
5053    
5054              if (*bracode == OP_COND || *bracode == OP_SCOND)              if (*bracode == OP_COND || *bracode == OP_SCOND)
5055                {                {
5056                int nlen = (int)(code - bracode);                int nlen = (int)(code - bracode);
# Line 5149  for (;; ptr++) Line 5063  for (;; ptr++)
5063                *code++ = OP_KETRPOS;                *code++ = OP_KETRPOS;
5064                PUTINC(code, 0, nlen);                PUTINC(code, 0, nlen);
5065                PUT(bracode, 1, nlen);                PUT(bracode, 1, nlen);
5066                }                }
5067    
5068              /* For non-COND brackets, we modify the BRA code and use KETRPOS. */              /* For non-COND brackets, we modify the BRA code and use KETRPOS. */
5069    
5070              else              else
5071                {                {
5072                *bracode += 1;              /* Switch to xxxPOS opcodes */                *bracode += 1;              /* Switch to xxxPOS opcodes */
5073                *ketcode = OP_KETRPOS;                *ketcode = OP_KETRPOS;
5074                }                }
5075    
5076              /* If the minimum is zero, mark it as possessive, then unset the              /* If the minimum is zero, mark it as possessive, then unset the
5077              possessive flag when the minimum is 0 or 1. */              possessive flag when the minimum is 0 or 1. */
5078    
5079              if (brazeroptr != NULL) *brazeroptr = OP_BRAPOSZERO;              if (brazeroptr != NULL) *brazeroptr = OP_BRAPOSZERO;
5080              if (repeat_min < 2) possessive_quantifier = FALSE;              if (repeat_min < 2) possessive_quantifier = FALSE;
5081              }              }
5082    
5083            /* Non-possessive quantifier */            /* Non-possessive quantifier */
5084    
5085            else *ketcode = OP_KETRMAX + repeat_type;            else *ketcode = OP_KETRMAX + repeat_type;
5086            }            }
5087          }          }
# Line 6059  for (;; ptr++) Line 5973  for (;; ptr++)
5973                of the group. Then remember the forward reference. */                of the group. Then remember the forward reference. */
5974    
5975                called = cd->start_code + recno;                called = cd->start_code + recno;
               if (cd->hwm >= cd->start_workspace + cd->workspace_size -  
                   WORK_SIZE_SAFETY_MARGIN)  
                 {  
                 *errorcodeptr = expand_workspace(cd);  
                 if (*errorcodeptr != 0) goto FAILED;  
                 }  
5976                PUTINC(cd->hwm, 0, (int)(code + 1 - cd->start_code));                PUTINC(cd->hwm, 0, (int)(code + 1 - cd->start_code));
5977                }                }
5978    
# Line 6085  for (;; ptr++) Line 5993  for (;; ptr++)
5993                }                }
5994              }              }
5995    
5996            /* Insert the recursion/subroutine item. It does not have a set first            /* Insert the recursion/subroutine item. */
           byte (relevant if it is repeated, because it will then be wrapped  
           with ONCE brackets). */  
5997    
5998            *code = OP_RECURSE;            *code = OP_RECURSE;
5999            PUT(code, 1, (int)(called - cd->start_code));            PUT(code, 1, (int)(called - cd->start_code));
6000            code += 1 + LINK_SIZE;            code += 1 + LINK_SIZE;
           groupsetfirstbyte = FALSE;  
6001            }            }
6002    
6003          /* Can't determine a first byte now */          /* Can't determine a first byte now */
# Line 6451  for (;; ptr++) Line 6356  for (;; ptr++)
6356    
6357          if (ptr[1] != CHAR_PLUS && ptr[1] != CHAR_MINUS)          if (ptr[1] != CHAR_PLUS && ptr[1] != CHAR_MINUS)
6358            {            {
6359            BOOL is_a_number = TRUE;            BOOL isnumber = TRUE;
6360            for (p = ptr + 1; *p != 0 && *p != terminator; p++)            for (p = ptr + 1; *p != 0 && *p != terminator; p++)
6361              {              {
6362              if ((cd->ctypes[*p] & ctype_digit) == 0) is_a_number = FALSE;              if ((cd->ctypes[*p] & ctype_digit) == 0) isnumber = FALSE;
6363              if ((cd->ctypes[*p] & ctype_word) == 0) break;              if ((cd->ctypes[*p] & ctype_word) == 0) break;
6364              }              }
6365            if (*p != terminator)            if (*p != terminator)
# Line 6462  for (;; ptr++) Line 6367  for (;; ptr++)
6367              *errorcodeptr = ERR57;              *errorcodeptr = ERR57;
6368              break;              break;
6369              }              }
6370            if (is_a_number)            if (isnumber)
6371              {              {
6372              ptr++;              ptr++;
6373              goto HANDLE_NUMERICAL_RECURSION;              goto HANDLE_NUMERICAL_RECURSION;
# Line 6576  for (;; ptr++) Line 6481  for (;; ptr++)
6481  #endif  #endif
6482          /* In non-UTF-8 mode, we turn \C into OP_ALLANY instead of OP_ANYBYTE          /* In non-UTF-8 mode, we turn \C into OP_ALLANY instead of OP_ANYBYTE
6483          so that it works in DFA mode and in lookbehinds. */          so that it works in DFA mode and in lookbehinds. */
6484    
6485            {            {
6486            previous = (-c > ESC_b && -c < ESC_Z)? code : NULL;            previous = (-c > ESC_b && -c < ESC_Z)? code : NULL;
6487            *code++ = (!utf8 && c == -ESC_C)? OP_ALLANY : -c;            *code++ = (!utf8 && c == -ESC_C)? OP_ALLANY : -c;
6488            }            }
# Line 7315  compile_data *cd = &compile_block; Line 7220  compile_data *cd = &compile_block;
7220  computing the amount of memory that is needed. Compiled items are thrown away  computing the amount of memory that is needed. Compiled items are thrown away
7221  as soon as possible, so that a fairly large buffer should be sufficient for  as soon as possible, so that a fairly large buffer should be sufficient for
7222  this purpose. The same space is used in the second phase for remembering where  this purpose. The same space is used in the second phase for remembering where
7223  to fill in forward references to subpatterns. That may overflow, in which case  to fill in forward references to subpatterns. */
 new memory is obtained from malloc(). */  
7224    
7225  uschar cworkspace[COMPILE_WORK_SIZE];  uschar cworkspace[COMPILE_WORK_SIZE];
7226    
# Line 7506  cd->bracount = cd->final_bracount = 0; Line 7410  cd->bracount = cd->final_bracount = 0;
7410  cd->names_found = 0;  cd->names_found = 0;
7411  cd->name_entry_size = 0;  cd->name_entry_size = 0;
7412  cd->name_table = NULL;  cd->name_table = NULL;
7413    cd->start_workspace = cworkspace;
7414  cd->start_code = cworkspace;  cd->start_code = cworkspace;
7415  cd->hwm = cworkspace;  cd->hwm = cworkspace;
 cd->start_workspace = cworkspace;  
 cd->workspace_size = COMPILE_WORK_SIZE;  
7416  cd->start_pattern = (const uschar *)pattern;  cd->start_pattern = (const uschar *)pattern;
7417  cd->end_pattern = (const uschar *)(pattern + strlen(pattern));  cd->end_pattern = (const uschar *)(pattern + strlen(pattern));
7418  cd->req_varyopt = 0;  cd->req_varyopt = 0;
# Line 7544  externally provided function. Integer ov Line 7447  externally provided function. Integer ov
7447  because nowadays we limit the maximum value of cd->names_found and  because nowadays we limit the maximum value of cd->names_found and
7448  cd->name_entry_size. */  cd->name_entry_size. */
7449    
7450  size = length + sizeof(real_pcre) + cd->names_found * cd->name_entry_size;  size = length + sizeof(real_pcre) + cd->names_found * (cd->name_entry_size + 3);
7451  re = (real_pcre *)(pcre_malloc)(size);  re = (real_pcre *)(pcre_malloc)(size);
7452    
7453  if (re == NULL)  if (re == NULL)
# Line 7587  cd->names_found = 0; Line 7490  cd->names_found = 0;
7490  cd->name_table = (uschar *)re + re->name_table_offset;  cd->name_table = (uschar *)re + re->name_table_offset;
7491  codestart = cd->name_table + re->name_entry_size * re->name_count;  codestart = cd->name_table + re->name_entry_size * re->name_count;
7492  cd->start_code = codestart;  cd->start_code = codestart;
7493  cd->hwm = (uschar *)(cd->start_workspace);  cd->hwm = cworkspace;
7494  cd->req_varyopt = 0;  cd->req_varyopt = 0;
7495  cd->had_accept = FALSE;  cd->had_accept = FALSE;
7496  cd->check_lookbehind = FALSE;  cd->check_lookbehind = FALSE;
# Line 7621  if debugging, leave the test till after Line 7524  if debugging, leave the test till after
7524  if (code - codestart > length) errorcode = ERR23;  if (code - codestart > length) errorcode = ERR23;
7525  #endif  #endif
7526    
7527  /* Fill in any forward references that are required. There may be repeated  /* Fill in any forward references that are required. */
 references; optimize for them, as searching a large regex takes time. */  
7528    
7529  if (cd->hwm > cd->start_workspace)  while (errorcode == 0 && cd->hwm > cworkspace)
7530    {    {
7531    int prev_recno = -1;    int offset, recno;
7532    const uschar *groupptr = NULL;    const uschar *groupptr;
7533    while (errorcode == 0 && cd->hwm > cd->start_workspace)    cd->hwm -= LINK_SIZE;
7534      {    offset = GET(cd->hwm, 0);
7535      int offset, recno;    recno = GET(codestart, offset);
7536      cd->hwm -= LINK_SIZE;    groupptr = _pcre_find_bracket(codestart, utf8, recno);
7537      offset = GET(cd->hwm, 0);    if (groupptr == NULL) errorcode = ERR53;
7538      recno = GET(codestart, offset);      else PUT(((uschar *)codestart), offset, (int)(groupptr - codestart));
     if (recno != prev_recno)  
       {  
       groupptr = _pcre_find_bracket(codestart, utf8, recno);  
       prev_recno = recno;  
       }  
     if (groupptr == NULL) errorcode = ERR53;  
       else PUT(((uschar *)codestart), offset, (int)(groupptr - codestart));  
     }  
7539    }    }
7540    
 /* If the workspace had to be expanded, free the new memory. */  
   
 if (cd->workspace_size > COMPILE_WORK_SIZE)  
   (pcre_free)((void *)cd->start_workspace);  
   
7541  /* Give an error if there's back reference to a non-existent capturing  /* Give an error if there's back reference to a non-existent capturing
7542  subpattern. */  subpattern. */
7543    

Legend:
Removed from v.807  
changed lines
  Added in v.835

  ViewVC Help
Powered by ViewVC 1.1.5