/[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 552 by ph10, Wed Oct 13 10:15:41 2010 UTC revision 598 by ph10, Sat May 7 15:37:31 2011 UTC
# Line 6  Line 6 
6  and semantics are as close as possible to those of the Perl 5 language.  and semantics are as close as possible to those of the Perl 5 language.
7    
8                         Written by Philip Hazel                         Written by Philip Hazel
9             Copyright (c) 1997-2010 University of Cambridge             Copyright (c) 1997-2011 University of Cambridge
10    
11  -----------------------------------------------------------------------------  -----------------------------------------------------------------------------
12  Redistribution and use in source and binary forms, with or without  Redistribution and use in source and binary forms, with or without
# Line 408  static const char error_texts[] = Line 408  static const char error_texts[] =
408    "different names for subpatterns of the same number are not allowed\0"    "different names for subpatterns of the same number are not allowed\0"
409    "(*MARK) must have an argument\0"    "(*MARK) must have an argument\0"
410    "this version of PCRE is not compiled with PCRE_UCP support\0"    "this version of PCRE is not compiled with PCRE_UCP support\0"
411      "\\c must be followed by an ASCII character\0"
412    ;    ;
413    
414  /* 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 841  else Line 842  else
842      break;      break;
843    
844      /* For \c, a following letter is upper-cased; then the 0x40 bit is flipped.      /* For \c, a following letter is upper-cased; then the 0x40 bit is flipped.
845      This coding is ASCII-specific, but then the whole concept of \cx is      An error is given if the byte following \c is not an ASCII character. This
846        coding is ASCII-specific, but then the whole concept of \cx is
847      ASCII-specific. (However, an EBCDIC equivalent has now been added.) */      ASCII-specific. (However, an EBCDIC equivalent has now been added.) */
848    
849      case CHAR_c:      case CHAR_c:
# Line 851  else Line 853  else
853        *errorcodeptr = ERR2;        *errorcodeptr = ERR2;
854        break;        break;
855        }        }
856    #ifndef EBCDIC    /* ASCII/UTF-8 coding */
857  #ifndef EBCDIC  /* ASCII/UTF-8 coding */      if (c > 127)  /* Excludes all non-ASCII in either mode */
858          {
859          *errorcodeptr = ERR68;
860          break;
861          }
862      if (c >= CHAR_a && c <= CHAR_z) c -= 32;      if (c >= CHAR_a && c <= CHAR_z) c -= 32;
863      c ^= 0x40;      c ^= 0x40;
864  #else           /* EBCDIC coding */  #else             /* EBCDIC coding */
865      if (c >= CHAR_a && c <= CHAR_z) c += 64;      if (c >= CHAR_a && c <= CHAR_z) c += 64;
866      c ^= 0xC0;      c ^= 0xC0;
867  #endif  #endif
# Line 1099  top-level call starts at the beginning o Line 1105  top-level call starts at the beginning o
1105  start at a parenthesis. It scans along a pattern's text looking for capturing  start at a parenthesis. It scans along a pattern's text looking for capturing
1106  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
1107  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
1108  returns when it reaches a given numbered subpattern. We know that if (?P< is  returns when it reaches a given numbered subpattern. Recursion is used to keep
1109  encountered, the name will be terminated by '>' because that is checked in the  track of subpatterns that reset the capturing group numbers - the (?| feature.
1110  first pass. Recursion is used to keep track of subpatterns that reset the  
1111  capturing group numbers - the (?| feature.  This function was originally called only from the second pass, in which we know
1112    that if (?< or (?' or (?P< is encountered, the name will be correctly
1113    terminated because that is checked in the first pass. There is now one call to
1114    this function in the first pass, to check for a recursive back reference by
1115    name (so that we can make the whole group atomic). In this case, we need check
1116    only up to the current position in the pattern, and that is still OK because
1117    and previous occurrences will have been checked. To make this work, the test
1118    for "end of pattern" is a check against cd->end_pattern in the main loop,
1119    instead of looking for a binary zero. This means that the special first-pass
1120    call can adjust cd->end_pattern temporarily. (Checks for binary zero while
1121    processing items within the loop are OK, because afterwards the main loop will
1122    terminate.)
1123    
1124  Arguments:  Arguments:
1125    ptrptr       address of the current character pointer (updated)    ptrptr       address of the current character pointer (updated)
# Line 1110  Arguments: Line 1127  Arguments:
1127    name         name to seek, or NULL if seeking a numbered subpattern    name         name to seek, or NULL if seeking a numbered subpattern
1128    lorn         name length, or subpattern number if name is NULL    lorn         name length, or subpattern number if name is NULL
1129    xmode        TRUE if we are in /x mode    xmode        TRUE if we are in /x mode
1130      utf8         TRUE if we are in UTF-8 mode
1131    count        pointer to the current capturing subpattern number (updated)    count        pointer to the current capturing subpattern number (updated)
1132    
1133  Returns:       the number of the named subpattern, or -1 if not found  Returns:       the number of the named subpattern, or -1 if not found
# Line 1117  Returns:       the number of the named s Line 1135  Returns:       the number of the named s
1135    
1136  static int  static int
1137  find_parens_sub(uschar **ptrptr, compile_data *cd, const uschar *name, int lorn,  find_parens_sub(uschar **ptrptr, compile_data *cd, const uschar *name, int lorn,
1138    BOOL xmode, int *count)    BOOL xmode, BOOL utf8, int *count)
1139  {  {
1140  uschar *ptr = *ptrptr;  uschar *ptr = *ptrptr;
1141  int start_count = *count;  int start_count = *count;
# Line 1202  if (ptr[0] == CHAR_LEFT_PARENTHESIS) Line 1220  if (ptr[0] == CHAR_LEFT_PARENTHESIS)
1220    }    }
1221    
1222  /* Past any initial parenthesis handling, scan for parentheses or vertical  /* Past any initial parenthesis handling, scan for parentheses or vertical
1223  bars. */  bars. Stop if we get to cd->end_pattern. Note that this is important for the
1224    first-pass call when this value is temporarily adjusted to stop at the current
1225    position. So DO NOT change this to a test for binary zero. */
1226    
1227  for (; *ptr != 0; ptr++)  for (; ptr < cd->end_pattern; ptr++)
1228    {    {
1229    /* Skip over backslashed characters and also entire \Q...\E */    /* Skip over backslashed characters and also entire \Q...\E */
1230    
# Line 1278  for (; *ptr != 0; ptr++) Line 1298  for (; *ptr != 0; ptr++)
1298    
1299    if (xmode && *ptr == CHAR_NUMBER_SIGN)    if (xmode && *ptr == CHAR_NUMBER_SIGN)
1300      {      {
1301      while (*(++ptr) != 0 && *ptr != CHAR_NL) {};      ptr++;
1302        while (*ptr != 0)
1303          {
1304          if (IS_NEWLINE(ptr)) { ptr += cd->nllen - 1; break; }
1305          ptr++;
1306    #ifdef SUPPORT_UTF8
1307          if (utf8) while ((*ptr & 0xc0) == 0x80) ptr++;
1308    #endif
1309          }
1310      if (*ptr == 0) goto FAIL_EXIT;      if (*ptr == 0) goto FAIL_EXIT;
1311      continue;      continue;
1312      }      }
# Line 1287  for (; *ptr != 0; ptr++) Line 1315  for (; *ptr != 0; ptr++)
1315    
1316    if (*ptr == CHAR_LEFT_PARENTHESIS)    if (*ptr == CHAR_LEFT_PARENTHESIS)
1317      {      {
1318      int rc = find_parens_sub(&ptr, cd, name, lorn, xmode, count);      int rc = find_parens_sub(&ptr, cd, name, lorn, xmode, utf8, count);
1319      if (rc > 0) return rc;      if (rc > 0) return rc;
1320      if (*ptr == 0) goto FAIL_EXIT;      if (*ptr == 0) goto FAIL_EXIT;
1321      }      }
# Line 1333  Arguments: Line 1361  Arguments:
1361    name         name to seek, or NULL if seeking a numbered subpattern    name         name to seek, or NULL if seeking a numbered subpattern
1362    lorn         name length, or subpattern number if name is NULL    lorn         name length, or subpattern number if name is NULL
1363    xmode        TRUE if we are in /x mode    xmode        TRUE if we are in /x mode
1364      utf8         TRUE if we are in UTF-8 mode
1365    
1366  Returns:       the number of the found subpattern, or -1 if not found  Returns:       the number of the found subpattern, or -1 if not found
1367  */  */
1368    
1369  static int  static int
1370  find_parens(compile_data *cd, const uschar *name, int lorn, BOOL xmode)  find_parens(compile_data *cd, const uschar *name, int lorn, BOOL xmode,
1371      BOOL utf8)
1372  {  {
1373  uschar *ptr = (uschar *)cd->start_pattern;  uschar *ptr = (uschar *)cd->start_pattern;
1374  int count = 0;  int count = 0;
# Line 1351  matching closing parens. That is why we Line 1381  matching closing parens. That is why we
1381    
1382  for (;;)  for (;;)
1383    {    {
1384    rc = find_parens_sub(&ptr, cd, name, lorn, xmode, &count);    rc = find_parens_sub(&ptr, cd, name, lorn, xmode, utf8, &count);
1385    if (rc > 0 || *ptr++ == 0) break;    if (rc > 0 || *ptr++ == 0) break;
1386    }    }
1387    
# Line 2515  if ((options & PCRE_EXTENDED) != 0) Line 2545  if ((options & PCRE_EXTENDED) != 0)
2545      while ((cd->ctypes[*ptr] & ctype_space) != 0) ptr++;      while ((cd->ctypes[*ptr] & ctype_space) != 0) ptr++;
2546      if (*ptr == CHAR_NUMBER_SIGN)      if (*ptr == CHAR_NUMBER_SIGN)
2547        {        {
2548        while (*(++ptr) != 0)        ptr++;
2549          while (*ptr != 0)
2550            {
2551          if (IS_NEWLINE(ptr)) { ptr += cd->nllen; break; }          if (IS_NEWLINE(ptr)) { ptr += cd->nllen; break; }
2552            ptr++;
2553    #ifdef SUPPORT_UTF8
2554            if (utf8) while ((*ptr & 0xc0) == 0x80) ptr++;
2555    #endif
2556            }
2557        }        }
2558      else break;      else break;
2559      }      }
# Line 2552  if ((options & PCRE_EXTENDED) != 0) Line 2589  if ((options & PCRE_EXTENDED) != 0)
2589      while ((cd->ctypes[*ptr] & ctype_space) != 0) ptr++;      while ((cd->ctypes[*ptr] & ctype_space) != 0) ptr++;
2590      if (*ptr == CHAR_NUMBER_SIGN)      if (*ptr == CHAR_NUMBER_SIGN)
2591        {        {
2592        while (*(++ptr) != 0)        ptr++;
2593          while (*ptr != 0)
2594            {
2595          if (IS_NEWLINE(ptr)) { ptr += cd->nllen; break; }          if (IS_NEWLINE(ptr)) { ptr += cd->nllen; break; }
2596            ptr++;
2597    #ifdef SUPPORT_UTF8
2598            if (utf8) while ((*ptr & 0xc0) == 0x80) ptr++;
2599    #endif
2600            }
2601        }        }
2602      else break;      else break;
2603      }      }
# Line 3126  for (;; ptr++) Line 3170  for (;; ptr++)
3170      if ((cd->ctypes[c] & ctype_space) != 0) continue;      if ((cd->ctypes[c] & ctype_space) != 0) continue;
3171      if (c == CHAR_NUMBER_SIGN)      if (c == CHAR_NUMBER_SIGN)
3172        {        {
3173        while (*(++ptr) != 0)        ptr++;
3174          while (*ptr != 0)
3175          {          {
3176          if (IS_NEWLINE(ptr)) { ptr += cd->nllen - 1; break; }          if (IS_NEWLINE(ptr)) { ptr += cd->nllen - 1; break; }
3177            ptr++;
3178    #ifdef SUPPORT_UTF8
3179            if (utf8) while ((*ptr & 0xc0) == 0x80) ptr++;
3180    #endif
3181          }          }
3182        if (*ptr != 0) continue;        if (*ptr != 0) continue;
3183    
# Line 3504  for (;; ptr++) Line 3553  for (;; ptr++)
3553              continue;              continue;
3554    
3555              /* Perl 5.004 onwards omits VT from \s, but we must preserve it              /* Perl 5.004 onwards omits VT from \s, but we must preserve it
3556              if it was previously set by something earlier in the character              if it was previously set by something earlier in the character
3557              class. */              class. */
3558    
3559              case ESC_s:              case ESC_s:
3560              classbits[0] |= cbits[cbit_space];              classbits[0] |= cbits[cbit_space];
3561              classbits[1] |= cbits[cbit_space+1] & ~0x08;              classbits[1] |= cbits[cbit_space+1] & ~0x08;
3562              for (c = 2; c < 32; c++) classbits[c] |= cbits[c+cbit_space];              for (c = 2; c < 32; c++) classbits[c] |= cbits[c+cbit_space];
3563              continue;              continue;
3564    
# Line 4826  for (;; ptr++) Line 4875  for (;; ptr++)
4875              if (*code++ == OP_THEN)              if (*code++ == OP_THEN)
4876                {                {
4877                PUT(code, 0, code - bcptr->current_branch - 1);                PUT(code, 0, code - bcptr->current_branch - 1);
4878                code += LINK_SIZE;                code += LINK_SIZE;
4879                }                }
4880              }              }
4881    
4882            else            else
# Line 4841  for (;; ptr++) Line 4890  for (;; ptr++)
4890              if (*code++ == OP_THEN_ARG)              if (*code++ == OP_THEN_ARG)
4891                {                {
4892                PUT(code, 0, code - bcptr->current_branch - 1);                PUT(code, 0, code - bcptr->current_branch - 1);
4893                code += LINK_SIZE;                code += LINK_SIZE;
4894                }                }
4895              *code++ = arglen;              *code++ = arglen;
4896              memcpy(code, arg, arglen);              memcpy(code, arg, arglen);
4897              code += arglen;              code += arglen;
# Line 5036  for (;; ptr++) Line 5085  for (;; ptr++)
5085          /* Search the pattern for a forward reference */          /* Search the pattern for a forward reference */
5086    
5087          else if ((i = find_parens(cd, name, namelen,          else if ((i = find_parens(cd, name, namelen,
5088                          (options & PCRE_EXTENDED) != 0)) > 0)                          (options & PCRE_EXTENDED) != 0, utf8)) > 0)
5089            {            {
5090            PUT2(code, 2+LINK_SIZE, i);            PUT2(code, 2+LINK_SIZE, i);
5091            code[1+LINK_SIZE]++;            code[1+LINK_SIZE]++;
# Line 5337  for (;; ptr++) Line 5386  for (;; ptr++)
5386          while ((cd->ctypes[*ptr] & ctype_word) != 0) ptr++;          while ((cd->ctypes[*ptr] & ctype_word) != 0) ptr++;
5387          namelen = (int)(ptr - name);          namelen = (int)(ptr - name);
5388    
5389          /* In the pre-compile phase, do a syntax check and set a dummy          /* In the pre-compile phase, do a syntax check. We used to just set
5390          reference number. */          a dummy reference number, because it was not used in the first pass.
5391            However, with the change of recursive back references to be atomic,
5392            we have to look for the number so that this state can be identified, as
5393            otherwise the incorrect length is computed. If it's not a backwards
5394            reference, the dummy number will do. */
5395    
5396          if (lengthptr != NULL)          if (lengthptr != NULL)
5397            {            {
5398              const uschar *temp;
5399    
5400            if (namelen == 0)            if (namelen == 0)
5401              {              {
5402              *errorcodeptr = ERR62;              *errorcodeptr = ERR62;
# Line 5357  for (;; ptr++) Line 5412  for (;; ptr++)
5412              *errorcodeptr = ERR48;              *errorcodeptr = ERR48;
5413              goto FAILED;              goto FAILED;
5414              }              }
5415            recno = 0;  
5416              /* The name table does not exist in the first pass, so we cannot
5417              do a simple search as in the code below. Instead, we have to scan the
5418              pattern to find the number. It is important that we scan it only as
5419              far as we have got because the syntax of named subpatterns has not
5420              been checked for the rest of the pattern, and find_parens() assumes
5421              correct syntax. In any case, it's a waste of resources to scan
5422              further. We stop the scan at the current point by temporarily
5423              adjusting the value of cd->endpattern. */
5424    
5425              temp = cd->end_pattern;
5426              cd->end_pattern = ptr;
5427              recno = find_parens(cd, name, namelen,
5428                (options & PCRE_EXTENDED) != 0, utf8);
5429              cd->end_pattern = temp;
5430              if (recno < 0) recno = 0;    /* Forward ref; set dummy number */
5431            }            }
5432    
5433          /* In the real compile, seek the name in the table. We check the name          /* In the real compile, seek the name in the table. We check the name
# Line 5382  for (;; ptr++) Line 5452  for (;; ptr++)
5452              }              }
5453            else if ((recno =                /* Forward back reference */            else if ((recno =                /* Forward back reference */
5454                      find_parens(cd, name, namelen,                      find_parens(cd, name, namelen,
5455                        (options & PCRE_EXTENDED) != 0)) <= 0)                        (options & PCRE_EXTENDED) != 0, utf8)) <= 0)
5456              {              {
5457              *errorcodeptr = ERR15;              *errorcodeptr = ERR15;
5458              goto FAILED;              goto FAILED;
# Line 5493  for (;; ptr++) Line 5563  for (;; ptr++)
5563              if (called == NULL)              if (called == NULL)
5564                {                {
5565                if (find_parens(cd, NULL, recno,                if (find_parens(cd, NULL, recno,
5566                      (options & PCRE_EXTENDED) != 0) < 0)                      (options & PCRE_EXTENDED) != 0, utf8) < 0)
5567                  {                  {
5568                  *errorcodeptr = ERR15;                  *errorcodeptr = ERR15;
5569                  goto FAILED;                  goto FAILED;
# Line 6823  while (ptr[skipatstart] == CHAR_LEFT_PAR Line 6893  while (ptr[skipatstart] == CHAR_LEFT_PAR
6893      { skipatstart += 7; options |= PCRE_UTF8; continue; }      { skipatstart += 7; options |= PCRE_UTF8; continue; }
6894    else if (strncmp((char *)(ptr+skipatstart+2), STRING_UCP_RIGHTPAR, 4) == 0)    else if (strncmp((char *)(ptr+skipatstart+2), STRING_UCP_RIGHTPAR, 4) == 0)
6895      { skipatstart += 6; options |= PCRE_UCP; continue; }      { skipatstart += 6; options |= PCRE_UCP; continue; }
6896      else if (strncmp((char *)(ptr+skipatstart+2), STRING_NO_START_OPT_RIGHTPAR, 13) == 0)
6897        { skipatstart += 15; options |= PCRE_NO_START_OPTIMIZE; continue; }
6898    
6899    if (strncmp((char *)(ptr+skipatstart+2), STRING_CR_RIGHTPAR, 3) == 0)    if (strncmp((char *)(ptr+skipatstart+2), STRING_CR_RIGHTPAR, 3) == 0)
6900      { skipatstart += 5; newnl = PCRE_NEWLINE_CR; }      { skipatstart += 5; newnl = PCRE_NEWLINE_CR; }
# Line 6849  while (ptr[skipatstart] == CHAR_LEFT_PAR Line 6921  while (ptr[skipatstart] == CHAR_LEFT_PAR
6921    
6922  utf8 = (options & PCRE_UTF8) != 0;  utf8 = (options & PCRE_UTF8) != 0;
6923    
6924  /* Can't support UTF8 unless PCRE has been compiled to include the code. */  /* Can't support UTF8 unless PCRE has been compiled to include the code. The
6925    return of an error code from _pcre_valid_utf8() is a new feature, introduced in
6926    release 8.13. The only use we make of it here is to adjust the offset value to
6927    the end of the string for a short string error, for compatibility with previous
6928    versions. */
6929    
6930  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
6931  if (utf8 && (options & PCRE_NO_UTF8_CHECK) == 0 &&  if (utf8 && (options & PCRE_NO_UTF8_CHECK) == 0 &&
6932       (*erroroffset = _pcre_valid_utf8((USPTR)pattern, -1)) >= 0)       (*erroroffset = _pcre_valid_utf8((USPTR)pattern, -1, &errorcode)) >= 0)
6933    {    {
6934    errorcode = ERR44;    errorcode = ERR44;
6935    goto PCRE_EARLY_ERROR_RETURN2;    goto PCRE_EARLY_ERROR_RETURN2;

Legend:
Removed from v.552  
changed lines
  Added in v.598

  ViewVC Help
Powered by ViewVC 1.1.5