/[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 391 by ph10, Tue Mar 17 21:16:01 2009 UTC revision 426 by ph10, Wed Aug 26 15:38:32 2009 UTC
# Line 100  is invalid. */ Line 100  is invalid. */
100  #ifndef EBCDIC  #ifndef EBCDIC
101    
102  /* This is the "normal" table for ASCII systems or for EBCDIC systems running  /* This is the "normal" table for ASCII systems or for EBCDIC systems running
103  in UTF-8 mode. */  in UTF-8 mode. */
104    
105  static const short int escapes[] = {  static const short int escapes[] = {
106       0,                       0,       0,                       0,
107         0,                       0,
108         0,                       0,
109       0,                       0,       0,                       0,
      0,                       0,  
110       0,                       0,       0,                       0,
      0,                       0,  
111       CHAR_COLON,              CHAR_SEMICOLON,       CHAR_COLON,              CHAR_SEMICOLON,
112       CHAR_LESS_THAN_SIGN,     CHAR_EQUALS_SIGN,       CHAR_LESS_THAN_SIGN,     CHAR_EQUALS_SIGN,
113       CHAR_GREATER_THAN_SIGN,  CHAR_QUESTION_MARK,       CHAR_GREATER_THAN_SIGN,  CHAR_QUESTION_MARK,
114       CHAR_COMMERCIAL_AT,      -ESC_A,       CHAR_COMMERCIAL_AT,      -ESC_A,
115       -ESC_B,                  -ESC_C,       -ESC_B,                  -ESC_C,
116       -ESC_D,                  -ESC_E,       -ESC_D,                  -ESC_E,
117       0,                       -ESC_G,       0,                       -ESC_G,
118       -ESC_H,                  0,       -ESC_H,                  0,
119       0,                       -ESC_K,       0,                       -ESC_K,
120       0,                       0,       0,                       0,
121       0,                       0,       0,                       0,
122       -ESC_P,                  -ESC_Q,       -ESC_P,                  -ESC_Q,
123       -ESC_R,                  -ESC_S,       -ESC_R,                  -ESC_S,
124       0,                       0,       0,                       0,
125       -ESC_V,                  -ESC_W,       -ESC_V,                  -ESC_W,
126       -ESC_X,                  0,       -ESC_X,                  0,
127       -ESC_Z,                  CHAR_LEFT_SQUARE_BRACKET,       -ESC_Z,                  CHAR_LEFT_SQUARE_BRACKET,
128       CHAR_BACKSLASH,          CHAR_RIGHT_SQUARE_BRACKET,       CHAR_BACKSLASH,          CHAR_RIGHT_SQUARE_BRACKET,
129       CHAR_CIRCUMFLEX_ACCENT,  CHAR_UNDERSCORE,       CHAR_CIRCUMFLEX_ACCENT,  CHAR_UNDERSCORE,
130       CHAR_GRAVE_ACCENT,       7,       CHAR_GRAVE_ACCENT,       7,
131       -ESC_b,                  0,       -ESC_b,                  0,
132       -ESC_d,                  ESC_e,       -ESC_d,                  ESC_e,
133       ESC_f,                   0,       ESC_f,                   0,
134       -ESC_h,                  0,       -ESC_h,                  0,
135       0,                       -ESC_k,       0,                       -ESC_k,
136       0,                       0,       0,                       0,
137       ESC_n,                   0,       ESC_n,                   0,
138       -ESC_p,                  0,       -ESC_p,                  0,
139       ESC_r,                   -ESC_s,       ESC_r,                   -ESC_s,
140       ESC_tee,                 0,       ESC_tee,                 0,
141       -ESC_v,                  -ESC_w,       -ESC_v,                  -ESC_w,
142       0,                       0,       0,                       0,
143       -ESC_z       -ESC_z
144  };  };
145    
146  #else  #else
147    
148  /* This is the "abnormal" table for EBCDIC systems without UTF-8 support. */  /* This is the "abnormal" table for EBCDIC systems without UTF-8 support. */
149    
# Line 177  static const short int escapes[] = { Line 177  static const short int escapes[] = {
177    
178  /* Table of special "verbs" like (*PRUNE). This is a short table, so it is  /* Table of special "verbs" like (*PRUNE). This is a short table, so it is
179  searched linearly. Put all the names into a single string, in order to reduce  searched linearly. Put all the names into a single string, in order to reduce
180  the number of relocations when a shared library is dynamically linked. The  the number of relocations when a shared library is dynamically linked. The
181  string is built from string macros so that it works in UTF-8 mode on EBCDIC  string is built from string macros so that it works in UTF-8 mode on EBCDIC
182  platforms. */  platforms. */
183    
184  typedef struct verbitem {  typedef struct verbitem {
# Line 215  length entry. The first three must be al Line 215  length entry. The first three must be al
215  for handling case independence. */  for handling case independence. */
216    
217  static const char posix_names[] =  static const char posix_names[] =
218    STRING_alpha0 STRING_lower0 STRING_upper0 STRING_alnum0    STRING_alpha0 STRING_lower0 STRING_upper0 STRING_alnum0
219    STRING_ascii0 STRING_blank0 STRING_cntrl0 STRING_digit0    STRING_ascii0 STRING_blank0 STRING_cntrl0 STRING_digit0
220    STRING_graph0 STRING_print0 STRING_punct0 STRING_space0    STRING_graph0 STRING_print0 STRING_punct0 STRING_space0
221    STRING_word0  STRING_xdigit;    STRING_word0  STRING_xdigit;
222    
# Line 360  For convenience, we use the same bit def Line 360  For convenience, we use the same bit def
360    
361  Then we can use ctype_digit and ctype_xdigit in the code. */  Then we can use ctype_digit and ctype_xdigit in the code. */
362    
363  #ifndef EBCDIC  #ifndef EBCDIC
364    
365  /* This is the "normal" case, for ASCII systems, and EBCDIC systems running in  /* This is the "normal" case, for ASCII systems, and EBCDIC systems running in
366  UTF-8 mode. */  UTF-8 mode. */
367    
368  static const unsigned char digitab[] =  static const unsigned char digitab[] =
# Line 400  static const unsigned char digitab[] = Line 400  static const unsigned char digitab[] =
400    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 240-247 */    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 240-247 */
401    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};/* 248-255 */    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};/* 248-255 */
402    
403  #else  #else
404    
405  /* This is the "abnormal" case, for EBCDIC systems not running in UTF-8 mode. */  /* This is the "abnormal" case, for EBCDIC systems not running in UTF-8 mode. */
406    
# Line 1009  return p; Line 1009  return p;
1009    
1010    
1011  /*************************************************  /*************************************************
1012  *       Find forward referenced subpattern       *  *  Subroutine for finding forward reference      *
1013  *************************************************/  *************************************************/
1014    
1015  /* This function scans along a pattern's text looking for capturing  /* This recursive function is called only from find_parens() below. The
1016    top-level call starts at the beginning of the pattern. All other calls must
1017    start at a parenthesis. It scans along a pattern's text looking for capturing
1018  subpatterns, and counting them. If it finds a named pattern that matches the  subpatterns, and counting them. If it finds a named pattern that matches the
1019  name it is given, it returns its number. Alternatively, if the name is NULL, it  name it is given, it returns its number. Alternatively, if the name is NULL, it
1020  returns when it reaches a given numbered subpattern. This is used for forward  returns when it reaches a given numbered subpattern. We know that if (?P< is
1021  references to subpatterns. We know that if (?P< is encountered, the name will  encountered, the name will be terminated by '>' because that is checked in the
1022  be terminated by '>' because that is checked in the first pass.  first pass. Recursion is used to keep track of subpatterns that reset the
1023    capturing group numbers - the (?| feature.
1024    
1025  Arguments:  Arguments:
1026    ptr          current position in the pattern    ptrptr       address of the current character pointer (updated)
1027    cd           compile background data    cd           compile background data
1028    name         name to seek, or NULL if seeking a numbered subpattern    name         name to seek, or NULL if seeking a numbered subpattern
1029    lorn         name length, or subpattern number if name is NULL    lorn         name length, or subpattern number if name is NULL
1030    xmode        TRUE if we are in /x mode    xmode        TRUE if we are in /x mode
1031      count        pointer to the current capturing subpattern number (updated)
1032    
1033  Returns:       the number of the named subpattern, or -1 if not found  Returns:       the number of the named subpattern, or -1 if not found
1034  */  */
1035    
1036  static int  static int
1037  find_parens(const uschar *ptr, compile_data *cd, const uschar *name, int lorn,  find_parens_sub(uschar **ptrptr, compile_data *cd, const uschar *name, int lorn,
1038    BOOL xmode)    BOOL xmode, int *count)
1039  {  {
1040  const uschar *thisname;  uschar *ptr = *ptrptr;
1041  int count = cd->bracount;  int start_count = *count;
1042    int hwm_count = start_count;
1043    BOOL dup_parens = FALSE;
1044    
1045  for (; *ptr != 0; ptr++)  /* If the first character is a parenthesis, check on the type of group we are
1046    dealing with. The very first call may not start with a parenthesis. */
1047    
1048    if (ptr[0] == CHAR_LEFT_PARENTHESIS)
1049    {    {
1050    int term;    if (ptr[1] == CHAR_QUESTION_MARK &&
1051          ptr[2] == CHAR_VERTICAL_LINE)
1052        {
1053        ptr += 3;
1054        dup_parens = TRUE;
1055        }
1056    
1057      /* Handle a normal, unnamed capturing parenthesis */
1058    
1059      else if (ptr[1] != CHAR_QUESTION_MARK && ptr[1] != CHAR_ASTERISK)
1060        {
1061        *count += 1;
1062        if (name == NULL && *count == lorn) return *count;
1063        ptr++;
1064        }
1065    
1066      /* Handle a condition. If it is an assertion, just carry on so that it
1067      is processed as normal. If not, skip to the closing parenthesis of the
1068      condition (there can't be any nested parens. */
1069    
1070      else if (ptr[2] == CHAR_LEFT_PARENTHESIS)
1071        {
1072        ptr += 2;
1073        if (ptr[1] != CHAR_QUESTION_MARK)
1074          {
1075          while (*ptr != 0 && *ptr != CHAR_RIGHT_PARENTHESIS) ptr++;
1076          if (*ptr != 0) ptr++;
1077          }
1078        }
1079    
1080      /* We have either (? or (* and not a condition */
1081    
1082      else
1083        {
1084        ptr += 2;
1085        if (*ptr == CHAR_P) ptr++;                      /* Allow optional P */
1086    
1087        /* We have to disambiguate (?<! and (?<= from (?<name> for named groups */
1088    
1089        if ((*ptr == CHAR_LESS_THAN_SIGN && ptr[1] != CHAR_EXCLAMATION_MARK &&
1090            ptr[1] != CHAR_EQUALS_SIGN) || *ptr == CHAR_APOSTROPHE)
1091          {
1092          int term;
1093          const uschar *thisname;
1094          *count += 1;
1095          if (name == NULL && *count == lorn) return *count;
1096          term = *ptr++;
1097          if (term == CHAR_LESS_THAN_SIGN) term = CHAR_GREATER_THAN_SIGN;
1098          thisname = ptr;
1099          while (*ptr != term) ptr++;
1100          if (name != NULL && lorn == ptr - thisname &&
1101              strncmp((const char *)name, (const char *)thisname, lorn) == 0)
1102            return *count;
1103          }
1104        }
1105      }
1106    
1107    /* Past any initial parenthesis handling, scan for parentheses or vertical
1108    bars. */
1109    
1110    for (; *ptr != 0; ptr++)
1111      {
1112    /* Skip over backslashed characters and also entire \Q...\E */    /* Skip over backslashed characters and also entire \Q...\E */
1113    
1114    if (*ptr == CHAR_BACKSLASH)    if (*ptr == CHAR_BACKSLASH)
1115      {      {
1116      if (*(++ptr) == 0) return -1;      if (*(++ptr) == 0) goto FAIL_EXIT;
1117      if (*ptr == CHAR_Q) for (;;)      if (*ptr == CHAR_Q) for (;;)
1118        {        {
1119        while (*(++ptr) != 0 && *ptr != CHAR_BACKSLASH) {};        while (*(++ptr) != 0 && *ptr != CHAR_BACKSLASH) {};
1120        if (*ptr == 0) return -1;        if (*ptr == 0) goto FAIL_EXIT;
1121        if (*(++ptr) == CHAR_E) break;        if (*(++ptr) == CHAR_E) break;
1122        }        }
1123      continue;      continue;
# Line 1057  for (; *ptr != 0; ptr++) Line 1126  for (; *ptr != 0; ptr++)
1126    /* Skip over character classes; this logic must be similar to the way they    /* Skip over character classes; this logic must be similar to the way they
1127    are handled for real. If the first character is '^', skip it. Also, if the    are handled for real. If the first character is '^', skip it. Also, if the
1128    first few characters (either before or after ^) are \Q\E or \E we skip them    first few characters (either before or after ^) are \Q\E or \E we skip them
1129    too. This makes for compatibility with Perl. Note the use of STR macros to    too. This makes for compatibility with Perl. Note the use of STR macros to
1130    encode "Q\\E" so that it works in UTF-8 on EBCDIC platforms. */    encode "Q\\E" so that it works in UTF-8 on EBCDIC platforms. */
1131    
1132    if (*ptr == CHAR_LEFT_SQUARE_BRACKET)    if (*ptr == CHAR_LEFT_SQUARE_BRACKET)
# Line 1068  for (; *ptr != 0; ptr++) Line 1137  for (; *ptr != 0; ptr++)
1137        int c = *(++ptr);        int c = *(++ptr);
1138        if (c == CHAR_BACKSLASH)        if (c == CHAR_BACKSLASH)
1139          {          {
1140          if (ptr[1] == CHAR_E)          if (ptr[1] == CHAR_E)
1141            ptr++;            ptr++;
1142          else if (strncmp((const char *)ptr+1,          else if (strncmp((const char *)ptr+1,
1143                   STR_Q STR_BACKSLASH STR_E, 3) == 0)                   STR_Q STR_BACKSLASH STR_E, 3) == 0)
1144            ptr += 3;            ptr += 3;
1145          else          else
1146            break;            break;
1147          }          }
1148        else if (!negate_class && c == CHAR_CIRCUMFLEX_ACCENT)        else if (!negate_class && c == CHAR_CIRCUMFLEX_ACCENT)
# Line 1084  for (; *ptr != 0; ptr++) Line 1153  for (; *ptr != 0; ptr++)
1153      /* If the next character is ']', it is a data character that must be      /* If the next character is ']', it is a data character that must be
1154      skipped, except in JavaScript compatibility mode. */      skipped, except in JavaScript compatibility mode. */
1155    
1156      if (ptr[1] == CHAR_RIGHT_SQUARE_BRACKET &&      if (ptr[1] == CHAR_RIGHT_SQUARE_BRACKET &&
1157          (cd->external_options & PCRE_JAVASCRIPT_COMPAT) == 0)          (cd->external_options & PCRE_JAVASCRIPT_COMPAT) == 0)
1158        ptr++;        ptr++;
1159    
# Line 1093  for (; *ptr != 0; ptr++) Line 1162  for (; *ptr != 0; ptr++)
1162        if (*ptr == 0) return -1;        if (*ptr == 0) return -1;
1163        if (*ptr == CHAR_BACKSLASH)        if (*ptr == CHAR_BACKSLASH)
1164          {          {
1165          if (*(++ptr) == 0) return -1;          if (*(++ptr) == 0) goto FAIL_EXIT;
1166          if (*ptr == CHAR_Q) for (;;)          if (*ptr == CHAR_Q) for (;;)
1167            {            {
1168            while (*(++ptr) != 0 && *ptr != CHAR_BACKSLASH) {};            while (*(++ptr) != 0 && *ptr != CHAR_BACKSLASH) {};
1169            if (*ptr == 0) return -1;            if (*ptr == 0) goto FAIL_EXIT;
1170            if (*(++ptr) == CHAR_E) break;            if (*(++ptr) == CHAR_E) break;
1171            }            }
1172          continue;          continue;
# Line 1111  for (; *ptr != 0; ptr++) Line 1180  for (; *ptr != 0; ptr++)
1180    if (xmode && *ptr == CHAR_NUMBER_SIGN)    if (xmode && *ptr == CHAR_NUMBER_SIGN)
1181      {      {
1182      while (*(++ptr) != 0 && *ptr != CHAR_NL) {};      while (*(++ptr) != 0 && *ptr != CHAR_NL) {};
1183      if (*ptr == 0) return -1;      if (*ptr == 0) goto FAIL_EXIT;
1184      continue;      continue;
1185      }      }
1186    
1187    /* An opening parens must now be a real metacharacter */    /* Check for the special metacharacters */
1188    
1189    if (*ptr != CHAR_LEFT_PARENTHESIS) continue;    if (*ptr == CHAR_LEFT_PARENTHESIS)
   if (ptr[1] != CHAR_QUESTION_MARK && ptr[1] != CHAR_ASTERISK)  
1190      {      {
1191      count++;      int rc = find_parens_sub(&ptr, cd, name, lorn, xmode, count);
1192      if (name == NULL && count == lorn) return count;      if (rc > 0) return rc;
1193      continue;      if (*ptr == 0) goto FAIL_EXIT;
1194        }
1195    
1196      else if (*ptr == CHAR_RIGHT_PARENTHESIS)
1197        {
1198        if (dup_parens && *count < hwm_count) *count = hwm_count;
1199        *ptrptr = ptr;
1200        return -1;
1201        }
1202    
1203      else if (*ptr == CHAR_VERTICAL_LINE && dup_parens)
1204        {
1205        if (*count > hwm_count) hwm_count = *count;
1206        *count = start_count;
1207      }      }
1208      }
1209    
1210    FAIL_EXIT:
1211    *ptrptr = ptr;
1212    return -1;
1213    }
1214    
   ptr += 2;  
   if (*ptr == CHAR_P) ptr++;                      /* Allow optional P */  
1215    
   /* We have to disambiguate (?<! and (?<= from (?<name> */  
1216    
   if ((*ptr != CHAR_LESS_THAN_SIGN || ptr[1] == CHAR_EXCLAMATION_MARK ||  
       ptr[1] == CHAR_EQUALS_SIGN) && *ptr != CHAR_APOSTROPHE)  
     continue;  
1217    
1218    count++;  /*************************************************
1219    *       Find forward referenced subpattern       *
1220    *************************************************/
1221    
1222    /* This function scans along a pattern's text looking for capturing
1223    subpatterns, and counting them. If it finds a named pattern that matches the
1224    name it is given, it returns its number. Alternatively, if the name is NULL, it
1225    returns when it reaches a given numbered subpattern. This is used for forward
1226    references to subpatterns. We used to be able to start this scan from the
1227    current compiling point, using the current count value from cd->bracount, and
1228    do it all in a single loop, but the addition of the possibility of duplicate
1229    subpattern numbers means that we have to scan from the very start, in order to
1230    take account of such duplicates, and to use a recursive function to keep track
1231    of the different types of group.
1232    
1233    Arguments:
1234      cd           compile background data
1235      name         name to seek, or NULL if seeking a numbered subpattern
1236      lorn         name length, or subpattern number if name is NULL
1237      xmode        TRUE if we are in /x mode
1238    
1239    Returns:       the number of the found subpattern, or -1 if not found
1240    */
1241    
1242    static int
1243    find_parens(compile_data *cd, const uschar *name, int lorn, BOOL xmode)
1244    {
1245    uschar *ptr = (uschar *)cd->start_pattern;
1246    int count = 0;
1247    int rc;
1248    
1249    /* If the pattern does not start with an opening parenthesis, the first call
1250    to find_parens_sub() will scan right to the end (if necessary). However, if it
1251    does start with a parenthesis, find_parens_sub() will return when it hits the
1252    matching closing parens. That is why we have to have a loop. */
1253    
1254    if (name == NULL && count == lorn) return count;  for (;;)
1255    term = *ptr++;    {
1256    if (term == CHAR_LESS_THAN_SIGN) term = CHAR_GREATER_THAN_SIGN;    rc = find_parens_sub(&ptr, cd, name, lorn, xmode, &count);
1257    thisname = ptr;    if (rc > 0 || *ptr++ == 0) break;
   while (*ptr != term) ptr++;  
   if (name != NULL && lorn == ptr - thisname &&  
       strncmp((const char *)name, (const char *)thisname, lorn) == 0)  
     return count;  
1258    }    }
1259    
1260  return -1;  return rc;
1261  }  }
1262    
1263    
1264    
1265    
1266  /*************************************************  /*************************************************
1267  *      Find first significant op code            *  *      Find first significant op code            *
1268  *************************************************/  *************************************************/
# Line 1311  for (;;) Line 1423  for (;;)
1423      branchlength++;      branchlength++;
1424      cc += 2;      cc += 2;
1425  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
1426      if ((options & PCRE_UTF8) != 0)      if ((options & PCRE_UTF8) != 0 && cc[-1] >= 0xc0)
1427        {        cc += _pcre_utf8_table4[cc[-1] & 0x3f];
       while ((*cc & 0xc0) == 0x80) cc++;  
       }  
1428  #endif  #endif
1429      break;      break;
1430    
# Line 1325  for (;;) Line 1435  for (;;)
1435      branchlength += GET2(cc,1);      branchlength += GET2(cc,1);
1436      cc += 4;      cc += 4;
1437  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
1438      if ((options & PCRE_UTF8) != 0)      if ((options & PCRE_UTF8) != 0 && cc[-1] >= 0xc0)
1439        {        cc += _pcre_utf8_table4[cc[-1] & 0x3f];
       while((*cc & 0x80) == 0x80) cc++;  
       }  
1440  #endif  #endif
1441      break;      break;
1442    
# Line 1664  for (code = first_significant_code(code Line 1772  for (code = first_significant_code(code
1772      BOOL empty_branch;      BOOL empty_branch;
1773      if (GET(code, 1) == 0) return TRUE;    /* Hit unclosed bracket */      if (GET(code, 1) == 0) return TRUE;    /* Hit unclosed bracket */
1774    
1775      /* Scan a closed bracket */      /* If a conditional group has only one branch, there is a second, implied,
1776        empty branch, so just skip over the conditional, because it could be empty.
1777        Otherwise, scan the individual branches of the group. */
1778    
1779      empty_branch = FALSE;      if (c == OP_COND && code[GET(code, 1)] != OP_ALT)
     do  
       {  
       if (!empty_branch && could_be_empty_branch(code, endcode, utf8))  
         empty_branch = TRUE;  
1780        code += GET(code, 1);        code += GET(code, 1);
1781        else
1782          {
1783          empty_branch = FALSE;
1784          do
1785            {
1786            if (!empty_branch && could_be_empty_branch(code, endcode, utf8))
1787              empty_branch = TRUE;
1788            code += GET(code, 1);
1789            }
1790          while (*code == OP_ALT);
1791          if (!empty_branch) return FALSE;   /* All branches are non-empty */
1792        }        }
1793      while (*code == OP_ALT);  
     if (!empty_branch) return FALSE;   /* All branches are non-empty */  
1794      c = *code;      c = *code;
1795      continue;      continue;
1796      }      }
# Line 1792  for (code = first_significant_code(code Line 1908  for (code = first_significant_code(code
1908      case OP_QUERY:      case OP_QUERY:
1909      case OP_MINQUERY:      case OP_MINQUERY:
1910      case OP_POSQUERY:      case OP_POSQUERY:
1911        if (utf8 && code[1] >= 0xc0) code += _pcre_utf8_table4[code[1] & 0x3f];
1912        break;
1913    
1914      case OP_UPTO:      case OP_UPTO:
1915      case OP_MINUPTO:      case OP_MINUPTO:
1916      case OP_POSUPTO:      case OP_POSUPTO:
1917      if (utf8) while ((code[2] & 0xc0) == 0x80) code++;      if (utf8 && code[3] >= 0xc0) code += _pcre_utf8_table4[code[3] & 0x3f];
1918      break;      break;
1919  #endif  #endif
1920      }      }
# Line 2173  if ((options & PCRE_EXTENDED) != 0) Line 2292  if ((options & PCRE_EXTENDED) != 0)
2292    
2293  /* If the next thing is itself optional, we have to give up. */  /* If the next thing is itself optional, we have to give up. */
2294    
2295  if (*ptr == CHAR_ASTERISK || *ptr == CHAR_QUESTION_MARK ||  if (*ptr == CHAR_ASTERISK || *ptr == CHAR_QUESTION_MARK ||
2296    strncmp((char *)ptr, STR_LEFT_CURLY_BRACKET STR_0 STR_COMMA, 3) == 0)    strncmp((char *)ptr, STR_LEFT_CURLY_BRACKET STR_0 STR_COMMA, 3) == 0)
2297      return FALSE;      return FALSE;
2298    
# Line 2639  for (;; ptr++) Line 2758  for (;; ptr++)
2758    /* Fill in length of a previous callout, except when the next thing is    /* Fill in length of a previous callout, except when the next thing is
2759    a quantifier. */    a quantifier. */
2760    
2761    is_quantifier =    is_quantifier =
2762      c == CHAR_ASTERISK || c == CHAR_PLUS || c == CHAR_QUESTION_MARK ||      c == CHAR_ASTERISK || c == CHAR_PLUS || c == CHAR_QUESTION_MARK ||
2763      (c == CHAR_LEFT_CURLY_BRACKET && is_counted_repeat(ptr+1));      (c == CHAR_LEFT_CURLY_BRACKET && is_counted_repeat(ptr+1));
2764    
# Line 2759  for (;; ptr++) Line 2878  for (;; ptr++)
2878      /* PCRE supports POSIX class stuff inside a class. Perl gives an error if      /* PCRE supports POSIX class stuff inside a class. Perl gives an error if
2879      they are encountered at the top level, so we'll do that too. */      they are encountered at the top level, so we'll do that too. */
2880    
2881      if ((ptr[1] == CHAR_COLON || ptr[1] == CHAR_DOT ||      if ((ptr[1] == CHAR_COLON || ptr[1] == CHAR_DOT ||
2882           ptr[1] == CHAR_EQUALS_SIGN) &&           ptr[1] == CHAR_EQUALS_SIGN) &&
2883          check_posix_syntax(ptr, &tempptr))          check_posix_syntax(ptr, &tempptr))
2884        {        {
# Line 2777  for (;; ptr++) Line 2896  for (;; ptr++)
2896        c = *(++ptr);        c = *(++ptr);
2897        if (c == CHAR_BACKSLASH)        if (c == CHAR_BACKSLASH)
2898          {          {
2899          if (ptr[1] == CHAR_E)          if (ptr[1] == CHAR_E)
2900            ptr++;            ptr++;
2901          else if (strncmp((const char *)ptr+1,          else if (strncmp((const char *)ptr+1,
2902                            STR_Q STR_BACKSLASH STR_E, 3) == 0)                            STR_Q STR_BACKSLASH STR_E, 3) == 0)
2903            ptr += 3;            ptr += 3;
2904          else          else
2905            break;            break;
2906          }          }
2907        else if (!negate_class && c == CHAR_CIRCUMFLEX_ACCENT)        else if (!negate_class && c == CHAR_CIRCUMFLEX_ACCENT)
# Line 2795  for (;; ptr++) Line 2914  for (;; ptr++)
2914      that. In JS mode, [] must always fail, so generate OP_FAIL, whereas      that. In JS mode, [] must always fail, so generate OP_FAIL, whereas
2915      [^] must match any character, so generate OP_ALLANY. */      [^] must match any character, so generate OP_ALLANY. */
2916    
2917      if (c == CHAR_RIGHT_SQUARE_BRACKET &&      if (c == CHAR_RIGHT_SQUARE_BRACKET &&
2918          (cd->external_options & PCRE_JAVASCRIPT_COMPAT) != 0)          (cd->external_options & PCRE_JAVASCRIPT_COMPAT) != 0)
2919        {        {
2920        *code++ = negate_class? OP_ALLANY : OP_FAIL;        *code++ = negate_class? OP_ALLANY : OP_FAIL;
# Line 2877  for (;; ptr++) Line 2996  for (;; ptr++)
2996        5.6 and 5.8 do. */        5.6 and 5.8 do. */
2997    
2998        if (c == CHAR_LEFT_SQUARE_BRACKET &&        if (c == CHAR_LEFT_SQUARE_BRACKET &&
2999            (ptr[1] == CHAR_COLON || ptr[1] == CHAR_DOT ||            (ptr[1] == CHAR_COLON || ptr[1] == CHAR_DOT ||
3000             ptr[1] == CHAR_EQUALS_SIGN) && check_posix_syntax(ptr, &tempptr))             ptr[1] == CHAR_EQUALS_SIGN) && check_posix_syntax(ptr, &tempptr))
3001          {          {
3002          BOOL local_negate = FALSE;          BOOL local_negate = FALSE;
# Line 3227  for (;; ptr++) Line 3346  for (;; ptr++)
3346          while (*ptr == CHAR_BACKSLASH && ptr[1] == CHAR_Q)          while (*ptr == CHAR_BACKSLASH && ptr[1] == CHAR_Q)
3347            {            {
3348            ptr += 2;            ptr += 2;
3349            if (*ptr == CHAR_BACKSLASH && ptr[1] == CHAR_E)            if (*ptr == CHAR_BACKSLASH && ptr[1] == CHAR_E)
3350              { ptr += 2; continue; }              { ptr += 2; continue; }
3351            inescq = TRUE;            inescq = TRUE;
3352            break;            break;
# Line 3749  we set the flag only if there is a liter Line 3868  we set the flag only if there is a liter
3868    
3869        if (repeat_max == 0) goto END_REPEAT;        if (repeat_max == 0) goto END_REPEAT;
3870    
3871          /*--------------------------------------------------------------------*/
3872          /* This code is obsolete from release 8.00; the restriction was finally
3873          removed: */
3874    
3875        /* All real repeats make it impossible to handle partial matching (maybe        /* All real repeats make it impossible to handle partial matching (maybe
3876        one day we will be able to remove this restriction). */        one day we will be able to remove this restriction). */
3877    
3878        if (repeat_max != 1) cd->external_flags |= PCRE_NOPARTIAL;        /* if (repeat_max != 1) cd->external_flags |= PCRE_NOPARTIAL; */
3879          /*--------------------------------------------------------------------*/
3880    
3881        /* Combine the op_type with the repeat_type */        /* Combine the op_type with the repeat_type */
3882    
# Line 3899  we set the flag only if there is a liter Line 4023  we set the flag only if there is a liter
4023          goto END_REPEAT;          goto END_REPEAT;
4024          }          }
4025    
4026          /*--------------------------------------------------------------------*/
4027          /* This code is obsolete from release 8.00; the restriction was finally
4028          removed: */
4029    
4030        /* All real repeats make it impossible to handle partial matching (maybe        /* All real repeats make it impossible to handle partial matching (maybe
4031        one day we will be able to remove this restriction). */        one day we will be able to remove this restriction). */
4032    
4033        if (repeat_max != 1) cd->external_flags |= PCRE_NOPARTIAL;        /* if (repeat_max != 1) cd->external_flags |= PCRE_NOPARTIAL; */
4034          /*--------------------------------------------------------------------*/
4035    
4036        if (repeat_min == 0 && repeat_max == -1)        if (repeat_min == 0 && repeat_max == -1)
4037          *code++ = OP_CRSTAR + repeat_type;          *code++ = OP_CRSTAR + repeat_type;
# Line 4217  we set the flag only if there is a liter Line 4346  we set the flag only if there is a liter
4346      if (possessive_quantifier)      if (possessive_quantifier)
4347        {        {
4348        int len;        int len;
4349        if (*tempcode == OP_EXACT || *tempcode == OP_TYPEEXACT ||  
4350            *tempcode == OP_NOTEXACT)        if (*tempcode == OP_TYPEEXACT)
4351          tempcode += _pcre_OP_lengths[*tempcode] +          tempcode += _pcre_OP_lengths[*tempcode] +
4352            ((*tempcode == OP_TYPEEXACT &&            ((tempcode[3] == OP_PROP || tempcode[3] == OP_NOTPROP)? 2 : 0);
4353               (tempcode[3] == OP_PROP || tempcode[3] == OP_NOTPROP))? 2:0);  
4354          else if (*tempcode == OP_EXACT || *tempcode == OP_NOTEXACT)
4355            {
4356            tempcode += _pcre_OP_lengths[*tempcode];
4357    #ifdef SUPPORT_UTF8
4358            if (utf8 && tempcode[-1] >= 0xc0)
4359              tempcode += _pcre_utf8_table4[tempcode[-1] & 0x3f];
4360    #endif
4361            }
4362    
4363        len = code - tempcode;        len = code - tempcode;
4364        if (len > 0) switch (*tempcode)        if (len > 0) switch (*tempcode)
4365          {          {
# Line 4427  we set the flag only if there is a liter Line 4565  we set the flag only if there is a liter
4565            }            }
4566          namelen = ptr - name;          namelen = ptr - name;
4567    
4568          if ((terminator > 0 && *ptr++ != terminator) ||          if ((terminator > 0 && *ptr++ != terminator) ||
4569              *ptr++ != CHAR_RIGHT_PARENTHESIS)              *ptr++ != CHAR_RIGHT_PARENTHESIS)
4570            {            {
4571            ptr--;      /* Error offset */            ptr--;      /* Error offset */
# Line 4481  we set the flag only if there is a liter Line 4619  we set the flag only if there is a liter
4619    
4620          /* Search the pattern for a forward reference */          /* Search the pattern for a forward reference */
4621    
4622          else if ((i = find_parens(ptr, cd, name, namelen,          else if ((i = find_parens(cd, name, namelen,
4623                          (options & PCRE_EXTENDED) != 0)) > 0)                          (options & PCRE_EXTENDED) != 0)) > 0)
4624            {            {
4625            PUT2(code, 2+LINK_SIZE, i);            PUT2(code, 2+LINK_SIZE, i);
# Line 4626  we set the flag only if there is a liter Line 4764  we set the flag only if there is a liter
4764    
4765          /* ------------------------------------------------------------ */          /* ------------------------------------------------------------ */
4766          case CHAR_P:              /* Python-style named subpattern handling */          case CHAR_P:              /* Python-style named subpattern handling */
4767          if (*(++ptr) == CHAR_EQUALS_SIGN ||          if (*(++ptr) == CHAR_EQUALS_SIGN ||
4768              *ptr == CHAR_GREATER_THAN_SIGN)  /* Reference or recursion */              *ptr == CHAR_GREATER_THAN_SIGN)  /* Reference or recursion */
4769            {            {
4770            is_recurse = *ptr == CHAR_GREATER_THAN_SIGN;            is_recurse = *ptr == CHAR_GREATER_THAN_SIGN;
# Line 4645  we set the flag only if there is a liter Line 4783  we set the flag only if there is a liter
4783          DEFINE_NAME:    /* Come here from (?< handling */          DEFINE_NAME:    /* Come here from (?< handling */
4784          case CHAR_APOSTROPHE:          case CHAR_APOSTROPHE:
4785            {            {
4786            terminator = (*ptr == CHAR_LESS_THAN_SIGN)?            terminator = (*ptr == CHAR_LESS_THAN_SIGN)?
4787              CHAR_GREATER_THAN_SIGN : CHAR_APOSTROPHE;              CHAR_GREATER_THAN_SIGN : CHAR_APOSTROPHE;
4788            name = ++ptr;            name = ++ptr;
4789    
# Line 4780  we set the flag only if there is a liter Line 4918  we set the flag only if there is a liter
4918              recno = GET2(slot, 0);              recno = GET2(slot, 0);
4919              }              }
4920            else if ((recno =                /* Forward back reference */            else if ((recno =                /* Forward back reference */
4921                      find_parens(ptr, cd, name, namelen,                      find_parens(cd, name, namelen,
4922                        (options & PCRE_EXTENDED) != 0)) <= 0)                        (options & PCRE_EXTENDED) != 0)) <= 0)
4923              {              {
4924              *errorcodeptr = ERR15;              *errorcodeptr = ERR15;
# Line 4890  we set the flag only if there is a liter Line 5028  we set the flag only if there is a liter
5028    
5029              if (called == NULL)              if (called == NULL)
5030                {                {
5031                if (find_parens(ptr, cd, NULL, recno,                if (find_parens(cd, NULL, recno,
5032                      (options & PCRE_EXTENDED) != 0) < 0)                      (options & PCRE_EXTENDED) != 0) < 0)
5033                  {                  {
5034                  *errorcodeptr = ERR15;                  *errorcodeptr = ERR15;
# Line 5240  we set the flag only if there is a liter Line 5378  we set the flag only if there is a liter
5378        {        {
5379        if (-c == ESC_Q)            /* Handle start of quoted string */        if (-c == ESC_Q)            /* Handle start of quoted string */
5380          {          {
5381          if (ptr[1] == CHAR_BACKSLASH && ptr[2] == CHAR_E)          if (ptr[1] == CHAR_BACKSLASH && ptr[2] == CHAR_E)
5382            ptr += 2;               /* avoid empty string */            ptr += 2;               /* avoid empty string */
5383              else inescq = TRUE;              else inescq = TRUE;
5384          continue;          continue;
# Line 5270  we set the flag only if there is a liter Line 5408  we set the flag only if there is a liter
5408          {          {
5409          const uschar *p;          const uschar *p;
5410          save_hwm = cd->hwm;   /* Normally this is set when '(' is read */          save_hwm = cd->hwm;   /* Normally this is set when '(' is read */
5411          terminator = (*(++ptr) == CHAR_LESS_THAN_SIGN)?          terminator = (*(++ptr) == CHAR_LESS_THAN_SIGN)?
5412            CHAR_GREATER_THAN_SIGN : CHAR_APOSTROPHE;            CHAR_GREATER_THAN_SIGN : CHAR_APOSTROPHE;
5413    
5414          /* These two statements stop the compiler for warning about possibly          /* These two statements stop the compiler for warning about possibly
# Line 5321  we set the flag only if there is a liter Line 5459  we set the flag only if there is a liter
5459        /* \k<name> or \k'name' is a back reference by name (Perl syntax).        /* \k<name> or \k'name' is a back reference by name (Perl syntax).
5460        We also support \k{name} (.NET syntax) */        We also support \k{name} (.NET syntax) */
5461    
5462        if (-c == ESC_k && (ptr[1] == CHAR_LESS_THAN_SIGN ||        if (-c == ESC_k && (ptr[1] == CHAR_LESS_THAN_SIGN ||
5463            ptr[1] == CHAR_APOSTROPHE || ptr[1] == CHAR_LEFT_CURLY_BRACKET))            ptr[1] == CHAR_APOSTROPHE || ptr[1] == CHAR_LEFT_CURLY_BRACKET))
5464          {          {
5465          is_recurse = FALSE;          is_recurse = FALSE;
5466          terminator = (*(++ptr) == CHAR_LESS_THAN_SIGN)?          terminator = (*(++ptr) == CHAR_LESS_THAN_SIGN)?
5467            CHAR_GREATER_THAN_SIGN : (*ptr == CHAR_APOSTROPHE)?            CHAR_GREATER_THAN_SIGN : (*ptr == CHAR_APOSTROPHE)?
5468            CHAR_APOSTROPHE : CHAR_RIGHT_CURLY_BRACKET;            CHAR_APOSTROPHE : CHAR_RIGHT_CURLY_BRACKET;
5469          goto NAMED_REF_OR_RECURSE;          goto NAMED_REF_OR_RECURSE;
5470          }          }
# Line 5879  do { Line 6017  do {
6017     const uschar *scode = first_significant_code(code + _pcre_OP_lengths[*code],     const uschar *scode = first_significant_code(code + _pcre_OP_lengths[*code],
6018       NULL, 0, FALSE);       NULL, 0, FALSE);
6019     register int op = *scode;     register int op = *scode;
6020    
6021     /* If we are at the start of a conditional assertion group, *both* the     /* If we are at the start of a conditional assertion group, *both* the
6022     conditional assertion *and* what follows the condition must satisfy the test     conditional assertion *and* what follows the condition must satisfy the test
6023     for start of line. Other kinds of condition fail. Note that there may be an     for start of line. Other kinds of condition fail. Note that there may be an
# Line 5887  do { Line 6025  do {
6025    
6026     if (op == OP_COND)     if (op == OP_COND)
6027       {       {
6028       scode += 1 + LINK_SIZE;       scode += 1 + LINK_SIZE;
6029       if (*scode == OP_CALLOUT) scode += _pcre_OP_lengths[OP_CALLOUT];       if (*scode == OP_CALLOUT) scode += _pcre_OP_lengths[OP_CALLOUT];
6030       switch (*scode)       switch (*scode)
6031         {         {
6032         case OP_CREF:         case OP_CREF:
6033         case OP_RREF:         case OP_RREF:
6034         case OP_DEF:         case OP_DEF:
6035         return FALSE;         return FALSE;
6036    
6037         default:     /* Assertion */         default:     /* Assertion */
6038         if (!is_startline(scode, bracket_map, backref_map)) return FALSE;         if (!is_startline(scode, bracket_map, backref_map)) return FALSE;
6039         do scode += GET(scode, 1); while (*scode == OP_ALT);         do scode += GET(scode, 1); while (*scode == OP_ALT);
6040         scode += 1 + LINK_SIZE;         scode += 1 + LINK_SIZE;
6041         break;         break;
6042         }         }
6043       scode = first_significant_code(scode, NULL, 0, FALSE);       scode = first_significant_code(scode, NULL, 0, FALSE);
6044       op = *scode;       op = *scode;
6045       }       }
6046    
6047     /* Non-capturing brackets */     /* Non-capturing brackets */
6048    
# Line 5925  do { Line 6063  do {
6063     /* Other brackets */     /* Other brackets */
6064    
6065     else if (op == OP_ASSERT || op == OP_ONCE)     else if (op == OP_ASSERT || op == OP_ONCE)
6066       {       {
6067       if (!is_startline(scode, bracket_map, backref_map)) return FALSE;       if (!is_startline(scode, bracket_map, backref_map)) return FALSE;
6068       }       }
6069    
6070     /* .* means "start at start or after \n" if it isn't in brackets that     /* .* means "start at start or after \n" if it isn't in brackets that
# Line 6106  if (erroroffset == NULL) Line 6244  if (erroroffset == NULL)
6244    
6245  *erroroffset = 0;  *erroroffset = 0;
6246    
 /* Can't support UTF8 unless PCRE has been compiled to include the code. */  
   
 #ifdef SUPPORT_UTF8  
 utf8 = (options & PCRE_UTF8) != 0;  
 if (utf8 && (options & PCRE_NO_UTF8_CHECK) == 0 &&  
      (*erroroffset = _pcre_valid_utf8((uschar *)pattern, -1)) >= 0)  
   {  
   errorcode = ERR44;  
   goto PCRE_EARLY_ERROR_RETURN2;  
   }  
 #else  
 if ((options & PCRE_UTF8) != 0)  
   {  
   errorcode = ERR32;  
   goto PCRE_EARLY_ERROR_RETURN;  
   }  
 #endif  
   
 if ((options & ~PUBLIC_COMPILE_OPTIONS) != 0)  
   {  
   errorcode = ERR17;  
   goto PCRE_EARLY_ERROR_RETURN;  
   }  
   
6247  /* Set up pointers to the individual character tables */  /* Set up pointers to the individual character tables */
6248    
6249  if (tables == NULL) tables = _pcre_default_tables;  if (tables == NULL) tables = _pcre_default_tables;
# Line 6138  cd->fcc = tables + fcc_offset; Line 6252  cd->fcc = tables + fcc_offset;
6252  cd->cbits = tables + cbits_offset;  cd->cbits = tables + cbits_offset;
6253  cd->ctypes = tables + ctypes_offset;  cd->ctypes = tables + ctypes_offset;
6254    
6255    /* Check that all undefined public option bits are zero */
6256    
6257    if ((options & ~PUBLIC_COMPILE_OPTIONS) != 0)
6258      {
6259      errorcode = ERR17;
6260      goto PCRE_EARLY_ERROR_RETURN;
6261      }
6262    
6263  /* Check for global one-time settings at the start of the pattern, and remember  /* Check for global one-time settings at the start of the pattern, and remember
6264  the offset for later. */  the offset for later. */
6265    
6266  while (ptr[skipatstart] == CHAR_LEFT_PARENTHESIS &&  while (ptr[skipatstart] == CHAR_LEFT_PARENTHESIS &&
6267         ptr[skipatstart+1] == CHAR_ASTERISK)         ptr[skipatstart+1] == CHAR_ASTERISK)
6268    {    {
6269    int newnl = 0;    int newnl = 0;
6270    int newbsr = 0;    int newbsr = 0;
6271    
6272      if (strncmp((char *)(ptr+skipatstart+2), STRING_UTF8_RIGHTPAR, 5) == 0)
6273        { skipatstart += 7; options |= PCRE_UTF8; continue; }
6274    
6275    if (strncmp((char *)(ptr+skipatstart+2), STRING_CR_RIGHTPAR, 3) == 0)    if (strncmp((char *)(ptr+skipatstart+2), STRING_CR_RIGHTPAR, 3) == 0)
6276      { skipatstart += 5; newnl = PCRE_NEWLINE_CR; }      { skipatstart += 5; newnl = PCRE_NEWLINE_CR; }
6277    else if (strncmp((char *)(ptr+skipatstart+2), STRING_LF_RIGHTPAR, 3)  == 0)    else if (strncmp((char *)(ptr+skipatstart+2), STRING_LF_RIGHTPAR, 3)  == 0)
# Line 6170  while (ptr[skipatstart] == CHAR_LEFT_PAR Line 6295  while (ptr[skipatstart] == CHAR_LEFT_PAR
6295    else break;    else break;
6296    }    }
6297    
6298    /* Can't support UTF8 unless PCRE has been compiled to include the code. */
6299    
6300    #ifdef SUPPORT_UTF8
6301    utf8 = (options & PCRE_UTF8) != 0;
6302    if (utf8 && (options & PCRE_NO_UTF8_CHECK) == 0 &&
6303         (*erroroffset = _pcre_valid_utf8((uschar *)pattern, -1)) >= 0)
6304      {
6305      errorcode = ERR44;
6306      goto PCRE_EARLY_ERROR_RETURN2;
6307      }
6308    #else
6309    if ((options & PCRE_UTF8) != 0)
6310      {
6311      errorcode = ERR32;
6312      goto PCRE_EARLY_ERROR_RETURN;
6313      }
6314    #endif
6315    
6316  /* Check validity of \R options. */  /* Check validity of \R options. */
6317    
6318  switch (options & (PCRE_BSR_ANYCRLF|PCRE_BSR_UNICODE))  switch (options & (PCRE_BSR_ANYCRLF|PCRE_BSR_UNICODE))

Legend:
Removed from v.391  
changed lines
  Added in v.426

  ViewVC Help
Powered by ViewVC 1.1.5