# Diff of /code/trunk/pcre_dfa_exec.c

revision 852 by zherczeg, Thu Jan 5 19:18:12 2012 UTC revision 1425 by ph10, Tue Dec 31 17:44:40 2013 UTC
# Line 7  and semantics are as close as possible t Line 7  and semantics are as close as possible t
7  below for why this module is different).  below for why this module is different).
8
9                         Written by Philip Hazel                         Written by Philip Hazel
10             Copyright (c) 1997-2012 University of Cambridge             Copyright (c) 1997-2013 University of Cambridge
11
12  -----------------------------------------------------------------------------  -----------------------------------------------------------------------------
13  Redistribution and use in source and binary forms, with or without  Redistribution and use in source and binary forms, with or without
# Line 38  POSSIBILITY OF SUCH DAMAGE. Line 38  POSSIBILITY OF SUCH DAMAGE.
38  -----------------------------------------------------------------------------  -----------------------------------------------------------------------------
39  */  */
40

41  /* This module contains the external function pcre_dfa_exec(), which is an  /* This module contains the external function pcre_dfa_exec(), which is an
42  alternative matching function that uses a sort of DFA algorithm (not a true  alternative matching function that uses a sort of DFA algorithm (not a true
43  FSM). This is NOT Perl- compatible, but it has advantages in certain  FSM). This is NOT Perl-compatible, but it has advantages in certain
44  applications. */  applications. */
45
46
# Line 121  static const pcre_uint8 coptable[] = { Line 120  static const pcre_uint8 coptable[] = {
120    0, 0,                          /* \P, \p                                 */    0, 0,                          /* \P, \p                                 */
121    0, 0, 0, 0, 0,                 /* \R, \H, \h, \V, \v                     */    0, 0, 0, 0, 0,                 /* \R, \H, \h, \V, \v                     */
122    0,                             /* \X                                     */    0,                             /* \X                                     */
123    0, 0, 0, 0, 0, 0,              /* \Z, \z, ^, ^M, \$, \$M                   */    0, 0, 0, 0, 0, 0,              /* \Z, \z, \$, \$M, ^, ^M                   */
124    1,                             /* Char                                   */    1,                             /* Char                                   */
125    1,                             /* Chari                                  */    1,                             /* Chari                                  */
126    1,                             /* not                                    */    1,                             /* not                                    */
# Line 152  static const pcre_uint8 coptable[] = { Line 151  static const pcre_uint8 coptable[] = {
151    /* Character class & ref repeats                                         */    /* Character class & ref repeats                                         */
152    0, 0, 0, 0, 0, 0,              /* *, *?, +, +?, ?, ??                    */    0, 0, 0, 0, 0, 0,              /* *, *?, +, +?, ?, ??                    */
153    0, 0,                          /* CRRANGE, CRMINRANGE                    */    0, 0,                          /* CRRANGE, CRMINRANGE                    */
154      0, 0, 0, 0,                    /* Possessive *+, ++, ?+, CRPOSRANGE      */
155    0,                             /* CLASS                                  */    0,                             /* CLASS                                  */
156    0,                             /* NCLASS                                 */    0,                             /* NCLASS                                 */
157    0,                             /* XCLASS - variable length               */    0,                             /* XCLASS - variable length               */
158    0,                             /* REF                                    */    0,                             /* REF                                    */
159    0,                             /* REFI                                   */    0,                             /* REFI                                   */
160      0,                             /* DNREF                                  */
161      0,                             /* DNREFI                                 */
162    0,                             /* RECURSE                                */    0,                             /* RECURSE                                */
163    0,                             /* CALLOUT                                */    0,                             /* CALLOUT                                */
164    0,                             /* Alt                                    */    0,                             /* Alt                                    */
# Line 172  static const pcre_uint8 coptable[] = { Line 174  static const pcre_uint8 coptable[] = {
174    0, 0,                          /* ONCE, ONCE_NC                          */    0, 0,                          /* ONCE, ONCE_NC                          */
175    0, 0, 0, 0, 0,                 /* BRA, BRAPOS, CBRA, CBRAPOS, COND       */    0, 0, 0, 0, 0,                 /* BRA, BRAPOS, CBRA, CBRAPOS, COND       */
176    0, 0, 0, 0, 0,                 /* SBRA, SBRAPOS, SCBRA, SCBRAPOS, SCOND  */    0, 0, 0, 0, 0,                 /* SBRA, SBRAPOS, SCBRA, SCBRAPOS, SCOND  */
177    0, 0,                          /* CREF, NCREF                            */    0, 0,                          /* CREF, DNCREF                           */
178    0, 0,                          /* RREF, NRREF                            */    0, 0,                          /* RREF, DNRREF                           */
179    0,                             /* DEF                                    */    0,                             /* DEF                                    */
180    0, 0, 0,                       /* BRAZERO, BRAMINZERO, BRAPOSZERO        */    0, 0, 0,                       /* BRAZERO, BRAMINZERO, BRAPOSZERO        */
181    0, 0, 0,                       /* MARK, PRUNE, PRUNE_ARG                 */    0, 0, 0,                       /* MARK, PRUNE, PRUNE_ARG                 */
# Line 195  static const pcre_uint8 poptable[] = { Line 197  static const pcre_uint8 poptable[] = {
197    1, 1,                          /* \P, \p                                 */    1, 1,                          /* \P, \p                                 */
198    1, 1, 1, 1, 1,                 /* \R, \H, \h, \V, \v                     */    1, 1, 1, 1, 1,                 /* \R, \H, \h, \V, \v                     */
199    1,                             /* \X                                     */    1,                             /* \X                                     */
200    0, 0, 0, 0, 0, 0,              /* \Z, \z, ^, ^M, \$, \$M                   */    0, 0, 0, 0, 0, 0,              /* \Z, \z, \$, \$M, ^, ^M                   */
201    1,                             /* Char                                   */    1,                             /* Char                                   */
202    1,                             /* Chari                                  */    1,                             /* Chari                                  */
203    1,                             /* not                                    */    1,                             /* not                                    */
# Line 221  static const pcre_uint8 poptable[] = { Line 223  static const pcre_uint8 poptable[] = {
223    /* Character class & ref repeats                                         */    /* Character class & ref repeats                                         */
224    1, 1, 1, 1, 1, 1,              /* *, *?, +, +?, ?, ??                    */    1, 1, 1, 1, 1, 1,              /* *, *?, +, +?, ?, ??                    */
225    1, 1,                          /* CRRANGE, CRMINRANGE                    */    1, 1,                          /* CRRANGE, CRMINRANGE                    */
226      1, 1, 1, 1,                    /* Possessive *+, ++, ?+, CRPOSRANGE      */
227    1,                             /* CLASS                                  */    1,                             /* CLASS                                  */
228    1,                             /* NCLASS                                 */    1,                             /* NCLASS                                 */
229    1,                             /* XCLASS - variable length               */    1,                             /* XCLASS - variable length               */
230    0,                             /* REF                                    */    0,                             /* REF                                    */
231    0,                             /* REFI                                   */    0,                             /* REFI                                   */
232      0,                             /* DNREF                                  */
233      0,                             /* DNREFI                                 */
234    0,                             /* RECURSE                                */    0,                             /* RECURSE                                */
235    0,                             /* CALLOUT                                */    0,                             /* CALLOUT                                */
236    0,                             /* Alt                                    */    0,                             /* Alt                                    */
# Line 241  static const pcre_uint8 poptable[] = { Line 246  static const pcre_uint8 poptable[] = {
246    0, 0,                          /* ONCE, ONCE_NC                          */    0, 0,                          /* ONCE, ONCE_NC                          */
247    0, 0, 0, 0, 0,                 /* BRA, BRAPOS, CBRA, CBRAPOS, COND       */    0, 0, 0, 0, 0,                 /* BRA, BRAPOS, CBRA, CBRAPOS, COND       */
248    0, 0, 0, 0, 0,                 /* SBRA, SBRAPOS, SCBRA, SCBRAPOS, SCOND  */    0, 0, 0, 0, 0,                 /* SBRA, SBRAPOS, SCBRA, SCBRAPOS, SCOND  */
249    0, 0,                          /* CREF, NCREF                            */    0, 0,                          /* CREF, DNCREF                           */
250    0, 0,                          /* RREF, NRREF                            */    0, 0,                          /* RREF, DNRREF                           */
251    0,                             /* DEF                                    */    0,                             /* DEF                                    */
252    0, 0, 0,                       /* BRAZERO, BRAMINZERO, BRAPOSZERO        */    0, 0, 0,                       /* BRAZERO, BRAMINZERO, BRAPOSZERO        */
253    0, 0, 0,                       /* MARK, PRUNE, PRUNE_ARG                 */    0, 0, 0,                       /* MARK, PRUNE, PRUNE_ARG                 */
# Line 282  typedef struct stateblock { Line 287  typedef struct stateblock {
287    int data;                       /* Some use extra data */    int data;                       /* Some use extra data */
288  } stateblock;  } stateblock;
289
290  #define INTS_PER_STATEBLOCK  (sizeof(stateblock)/sizeof(int))  #define INTS_PER_STATEBLOCK  (int)(sizeof(stateblock)/sizeof(int))
291
292
293  #ifdef PCRE_DEBUG  #ifdef PCRE_DEBUG
# Line 303  Returns:       nothing Line 308  Returns:       nothing
308  static void  static void
309  pchars(const pcre_uchar *p, int length, FILE *f)  pchars(const pcre_uchar *p, int length, FILE *f)
310  {  {
311  int c;  pcre_uint32 c;
312  while (length-- > 0)  while (length-- > 0)
313    {    {
314    if (isprint(c = *(p++)))    if (isprint(c = *(p++)))
315      fprintf(f, "%c", c);      fprintf(f, "%c", c);
316    else    else
317      fprintf(f, "\\x%02x", c);      fprintf(f, "\\x{%02x}", c);
318    }    }
319  }  }
320  #endif  #endif
# Line 382  for the current character, one for the f Line 387  for the current character, one for the f
387      next_new_state->count  = (y); \      next_new_state->count  = (y); \
388      next_new_state->data   = (z); \      next_new_state->data   = (z); \
389      next_new_state++; \      next_new_state++; \
390      DPRINTF(("%.*sADD_NEW_DATA(%d,%d,%d)\n", rlevel*2-2, SP, (x), (y), (z))); \      DPRINTF(("%.*sADD_NEW_DATA(%d,%d,%d) line %d\n", rlevel*2-2, SP, \
391          (x), (y), (z), __LINE__)); \
392      } \      } \
393    else return PCRE_ERROR_DFA_WSSIZE    else return PCRE_ERROR_DFA_WSSIZE
394
# Line 424  BOOL utf = (md->poptions & PCRE_UTF8) != Line 430  BOOL utf = (md->poptions & PCRE_UTF8) !=
430  BOOL utf = FALSE;  BOOL utf = FALSE;
431  #endif  #endif
432
433    BOOL reset_could_continue = FALSE;
434
435  rlevel++;  rlevel++;
436  offsetcount &= (-2);  offsetcount &= (-2);
437
# Line 569  for (;;) Line 577  for (;;)
577    {    {
578    int i, j;    int i, j;
579    int clen, dlen;    int clen, dlen;
580    unsigned int c, d;    pcre_uint32 c, d;
581    int forced_fail = 0;    int forced_fail = 0;
582    BOOL could_continue = FALSE;    BOOL partial_newline = FALSE;
583      BOOL could_continue = reset_could_continue;
584      reset_could_continue = FALSE;
585
586    /* Make the new state list into the active state list and empty the    /* Make the new state list into the active state list and empty the
587    new state list. */    new state list. */
# Line 607  for (;;) Line 617  for (;;)
617
618    if (ptr < end_subject)    if (ptr < end_subject)
619      {      {
620      clen = 1;        /* Number of bytes in the character */      clen = 1;        /* Number of data items in the character */
621  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
622      if (utf) { GETCHARLEN(c, ptr, clen); } else      GETCHARLENTEST(c, ptr, clen);
623  #endif  /* SUPPORT_UTF */  #else
624      c = *ptr;      c = *ptr;
625    #endif  /* SUPPORT_UTF */
626      }      }
627    else    else
628      {      {
# Line 630  for (;;) Line 641  for (;;)
641      BOOL caseless = FALSE;      BOOL caseless = FALSE;
642      const pcre_uchar *code;      const pcre_uchar *code;
643      int state_offset = current_state->offset;      int state_offset = current_state->offset;
644      int count, codevalue, rrc;      int codevalue, rrc;
645        int count;
646
647  #ifdef PCRE_DEBUG  #ifdef PCRE_DEBUG
648      printf ("%.*sProcessing state %d c=", rlevel*2-2, SP, state_offset);      printf ("%.*sProcessing state %d c=", rlevel*2-2, SP, state_offset);
# Line 641  for (;;) Line 653  for (;;)
653
654      /* A negative offset is a special case meaning "hold off going to this      /* A negative offset is a special case meaning "hold off going to this
655      (negated) state until the number of characters in the data field have      (negated) state until the number of characters in the data field have
656      been skipped". */      been skipped". If the could_continue flag was passed over from a previous
657        state, arrange for it to passed on. */
658
659      if (state_offset < 0)      if (state_offset < 0)
660        {        {
# Line 650  for (;;) Line 663  for (;;)
663          DPRINTF(("%.*sSkipping this character\n", rlevel*2-2, SP));          DPRINTF(("%.*sSkipping this character\n", rlevel*2-2, SP));
665            current_state->data - 1);            current_state->data - 1);
666            if (could_continue) reset_could_continue = TRUE;
667          continue;          continue;
668          }          }
669        else        else
# Line 689  for (;;) Line 703  for (;;)
703      permitted.      permitted.
704
705      We also use this mechanism for opcodes such as OP_TYPEPLUS that take an      We also use this mechanism for opcodes such as OP_TYPEPLUS that take an
706      argument that is not a data character - but is always one byte long. We      argument that is not a data character - but is always one byte long because
707      have to take special action to deal with  \P, \p, \H, \h, \V, \v and \X in      the values are small. We have to take special action to deal with  \P, \p,
708      this case. To keep the other cases fast, convert these ones to new opcodes.      \H, \h, \V, \v and \X in this case. To keep the other cases fast, convert
709      */      these ones to new opcodes. */
710
711      if (coptable[codevalue] > 0)      if (coptable[codevalue] > 0)
712        {        {
# Line 783  for (;;) Line 797  for (;;)
797              offsets[0] = (int)(current_subject - start_subject);              offsets[0] = (int)(current_subject - start_subject);
798              offsets[1] = (int)(ptr - start_subject);              offsets[1] = (int)(ptr - start_subject);
799              DPRINTF(("%.*sSet matched string = \"%.*s\"\n", rlevel*2-2, SP,              DPRINTF(("%.*sSet matched string = \"%.*s\"\n", rlevel*2-2, SP,
800                offsets[1] - offsets[0], current_subject));                offsets[1] - offsets[0], (char *)current_subject));
801              }              }
802            if ((md->moptions & PCRE_DFA_SHORTEST) != 0)            if ((md->moptions & PCRE_DFA_SHORTEST) != 0)
803              {              {
# Line 888  for (;;) Line 902  for (;;)
902        /*-----------------------------------------------------------------*/        /*-----------------------------------------------------------------*/
903        case OP_ANY:        case OP_ANY:
904        if (clen > 0 && !IS_NEWLINE(ptr))        if (clen > 0 && !IS_NEWLINE(ptr))
905          { ADD_NEW(state_offset + 1, 0); }          {
906            if (ptr + 1 >= md->end_subject &&
907                (md->moptions & (PCRE_PARTIAL_HARD)) != 0 &&
908                NLBLOCK->nltype == NLTYPE_FIXED &&
909                NLBLOCK->nllen == 2 &&
910                c == NLBLOCK->nl[0])
911              {
912              could_continue = partial_newline = TRUE;
913              }
914            else
915              {
917              }
918            }
919        break;        break;
920
921        /*-----------------------------------------------------------------*/        /*-----------------------------------------------------------------*/
# Line 916  for (;;) Line 943  for (;;)
943                 (ptr == end_subject - md->nllen)                 (ptr == end_subject - md->nllen)
944              ))              ))
945            { ADD_ACTIVE(state_offset + 1, 0); }            { ADD_ACTIVE(state_offset + 1, 0); }
946            else if (ptr + 1 >= md->end_subject &&
947                     (md->moptions & (PCRE_PARTIAL_HARD|PCRE_PARTIAL_SOFT)) != 0 &&
948                     NLBLOCK->nltype == NLTYPE_FIXED &&
949                     NLBLOCK->nllen == 2 &&
950                     c == NLBLOCK->nl[0])
951              {
952              if ((md->moptions & PCRE_PARTIAL_HARD) != 0)
953                {
954                reset_could_continue = TRUE;
955                ADD_NEW_DATA(-(state_offset + 1), 0, 1);
956                }
957              else could_continue = partial_newline = TRUE;
958              }
959          }          }
960        break;        break;
961
# Line 928  for (;;) Line 968  for (;;)
968          else if (clen == 0 ||          else if (clen == 0 ||
969              ((md->poptions & PCRE_DOLLAR_ENDONLY) == 0 && IS_NEWLINE(ptr)))              ((md->poptions & PCRE_DOLLAR_ENDONLY) == 0 && IS_NEWLINE(ptr)))
970            { ADD_ACTIVE(state_offset + 1, 0); }            { ADD_ACTIVE(state_offset + 1, 0); }
971            else if (ptr + 1 >= md->end_subject &&
972                     (md->moptions & (PCRE_PARTIAL_HARD|PCRE_PARTIAL_SOFT)) != 0 &&
973                     NLBLOCK->nltype == NLTYPE_FIXED &&
974                     NLBLOCK->nllen == 2 &&
975                     c == NLBLOCK->nl[0])
976              {
977              if ((md->moptions & PCRE_PARTIAL_HARD) != 0)
978                {
979                reset_could_continue = TRUE;
980                ADD_NEW_DATA(-(state_offset + 1), 0, 1);
981                }
982              else could_continue = partial_newline = TRUE;
983              }
984          }          }
985        else if (IS_NEWLINE(ptr))        else if (IS_NEWLINE(ptr))
986          { ADD_ACTIVE(state_offset + 1, 0); }          { ADD_ACTIVE(state_offset + 1, 0); }
# Line 962  for (;;) Line 1015  for (;;)
1015            {            {
1016            const pcre_uchar *temp = ptr - 1;            const pcre_uchar *temp = ptr - 1;
1017            if (temp < md->start_used_ptr) md->start_used_ptr = temp;            if (temp < md->start_used_ptr) md->start_used_ptr = temp;
1018  #ifdef SUPPORT_UTF  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
1019            if (utf) { BACKCHAR(temp); }            if (utf) { BACKCHAR(temp); }
1020  #endif  #endif
1021            GETCHARTEST(d, temp);            GETCHARTEST(d, temp);
# Line 1015  for (;;) Line 1068  for (;;)
1068        if (clen > 0)        if (clen > 0)
1069          {          {
1070          BOOL OK;          BOOL OK;
1071            const pcre_uint32 *cp;
1072          const ucd_record * prop = GET_UCD(c);          const ucd_record * prop = GET_UCD(c);
1073          switch(code[1])          switch(code[1])
1074            {            {
# Line 1046  for (;;) Line 1100  for (;;)
1100                 PRIV(ucp_gentype)[prop->chartype] == ucp_N;                 PRIV(ucp_gentype)[prop->chartype] == ucp_N;
1101            break;            break;
1102
1103            case PT_SPACE:    /* Perl space */            /* Perl space used to exclude VT, but from Perl 5.18 it is included,
1104            OK = PRIV(ucp_gentype)[prop->chartype] == ucp_Z ||            which means that Perl space and POSIX space are now identical. PCRE
1105                 c == CHAR_HT || c == CHAR_NL || c == CHAR_FF || c == CHAR_CR;            was changed at release 8.34. */
break;
1106
1107              case PT_SPACE:    /* Perl space */
1108            case PT_PXSPACE:  /* POSIX space */            case PT_PXSPACE:  /* POSIX space */
1109            OK = PRIV(ucp_gentype)[prop->chartype] == ucp_Z ||            switch(c)
1110                 c == CHAR_HT || c == CHAR_NL || c == CHAR_VT ||              {
1111                 c == CHAR_FF || c == CHAR_CR;              HSPACE_CASES:
1112                VSPACE_CASES:
1113                OK = TRUE;
1114                break;
1115
1116                default:
1117                OK = PRIV(ucp_gentype)[prop->chartype] == ucp_Z;
1118                break;
1119                }
1120            break;            break;
1121
1122            case PT_WORD:            case PT_WORD:
# Line 1063  for (;;) Line 1125  for (;;)
1125                 c == CHAR_UNDERSCORE;                 c == CHAR_UNDERSCORE;
1126            break;            break;
1127
1128              case PT_CLIST:
1129              cp = PRIV(ucd_caseless_sets) + code[2];
1130              for (;;)
1131                {
1132                if (c < *cp) { OK = FALSE; break; }
1133                if (c == *cp++) { OK = TRUE; break; }
1134                }
1135              break;
1136
1137              case PT_UCNC:
1138              OK = c == CHAR_DOLLAR_SIGN || c == CHAR_COMMERCIAL_AT ||
1139                   c == CHAR_GRAVE_ACCENT || (c >= 0xa0 && c <= 0xd7ff) ||
1140                   c >= 0xe000;
1141              break;
1142
1143            /* Should never occur, but keep compilers from grumbling. */            /* Should never occur, but keep compilers from grumbling. */
1144
1145            default:            default:
# Line 1090  for (;;) Line 1167  for (;;)
1167        if (count > 0) { ADD_ACTIVE(state_offset + 2, 0); }        if (count > 0) { ADD_ACTIVE(state_offset + 2, 0); }
1168        if (clen > 0)        if (clen > 0)
1169          {          {
1170          if ((c >= 256 && d != OP_DIGIT && d != OP_WHITESPACE && d != OP_WORDCHAR) ||          if (d == OP_ANY && ptr + 1 >= md->end_subject &&
1171                (md->moptions & (PCRE_PARTIAL_HARD)) != 0 &&
1172                NLBLOCK->nltype == NLTYPE_FIXED &&
1173                NLBLOCK->nllen == 2 &&
1174                c == NLBLOCK->nl[0])
1175              {
1176              could_continue = partial_newline = TRUE;
1177              }
1178            else if ((c >= 256 && d != OP_DIGIT && d != OP_WHITESPACE && d != OP_WORDCHAR) ||
1179              (c < 256 &&              (c < 256 &&
1180                (d != OP_ANY || !IS_NEWLINE(ptr)) &&                (d != OP_ANY || !IS_NEWLINE(ptr)) &&
1181                ((ctypes[c] & toptable1[d]) ^ toptable2[d]) != 0))                ((ctypes[c] & toptable1[d]) ^ toptable2[d]) != 0))
# Line 1113  for (;;) Line 1198  for (;;)
1199        if (clen > 0)        if (clen > 0)
1200          {          {
1201          if ((c >= 256 && d != OP_DIGIT && d != OP_WHITESPACE && d != OP_WORDCHAR) ||          if (d == OP_ANY && ptr + 1 >= md->end_subject &&
1202                (md->moptions & (PCRE_PARTIAL_HARD)) != 0 &&
1203                NLBLOCK->nltype == NLTYPE_FIXED &&
1204                NLBLOCK->nllen == 2 &&
1205                c == NLBLOCK->nl[0])
1206              {
1207              could_continue = partial_newline = TRUE;
1208              }
1209            else if ((c >= 256 && d != OP_DIGIT && d != OP_WHITESPACE && d != OP_WORDCHAR) ||
1210              (c < 256 &&              (c < 256 &&
1211                (d != OP_ANY || !IS_NEWLINE(ptr)) &&                (d != OP_ANY || !IS_NEWLINE(ptr)) &&
1212                ((ctypes[c] & toptable1[d]) ^ toptable2[d]) != 0))                ((ctypes[c] & toptable1[d]) ^ toptable2[d]) != 0))
# Line 1135  for (;;) Line 1228  for (;;)
1229        if (clen > 0)        if (clen > 0)
1230          {          {
1231          if ((c >= 256 && d != OP_DIGIT && d != OP_WHITESPACE && d != OP_WORDCHAR) ||          if (d == OP_ANY && ptr + 1 >= md->end_subject &&
1232                (md->moptions & (PCRE_PARTIAL_HARD)) != 0 &&
1233                NLBLOCK->nltype == NLTYPE_FIXED &&
1234                NLBLOCK->nllen == 2 &&
1235                c == NLBLOCK->nl[0])
1236              {
1237              could_continue = partial_newline = TRUE;
1238              }
1239            else if ((c >= 256 && d != OP_DIGIT && d != OP_WHITESPACE && d != OP_WORDCHAR) ||
1240              (c < 256 &&              (c < 256 &&
1241                (d != OP_ANY || !IS_NEWLINE(ptr)) &&                (d != OP_ANY || !IS_NEWLINE(ptr)) &&
1242                ((ctypes[c] & toptable1[d]) ^ toptable2[d]) != 0))                ((ctypes[c] & toptable1[d]) ^ toptable2[d]) != 0))
# Line 1155  for (;;) Line 1256  for (;;)
1256        count = current_state->count;  /* Number already matched */        count = current_state->count;  /* Number already matched */
1257        if (clen > 0)        if (clen > 0)
1258          {          {
1259          if ((c >= 256 && d != OP_DIGIT && d != OP_WHITESPACE && d != OP_WORDCHAR) ||          if (d == OP_ANY && ptr + 1 >= md->end_subject &&
1260                (md->moptions & (PCRE_PARTIAL_HARD)) != 0 &&
1261                NLBLOCK->nltype == NLTYPE_FIXED &&
1262                NLBLOCK->nllen == 2 &&
1263                c == NLBLOCK->nl[0])
1264              {
1265              could_continue = partial_newline = TRUE;
1266              }
1267            else if ((c >= 256 && d != OP_DIGIT && d != OP_WHITESPACE && d != OP_WORDCHAR) ||
1268              (c < 256 &&              (c < 256 &&
1269                (d != OP_ANY || !IS_NEWLINE(ptr)) &&                (d != OP_ANY || !IS_NEWLINE(ptr)) &&
1270                ((ctypes[c] & toptable1[d]) ^ toptable2[d]) != 0))                ((ctypes[c] & toptable1[d]) ^ toptable2[d]) != 0))
1271            {            {
1272            if (++count >= GET2(code, 1))            if (++count >= (int)GET2(code, 1))
1273              { ADD_NEW(state_offset + 1 + IMM2_SIZE + 1, 0); }              { ADD_NEW(state_offset + 1 + IMM2_SIZE + 1, 0); }
1274            else            else
# Line 1176  for (;;) Line 1285  for (;;)
1285        count = current_state->count;  /* Number already matched */        count = current_state->count;  /* Number already matched */
1286        if (clen > 0)        if (clen > 0)
1287          {          {
1288          if ((c >= 256 && d != OP_DIGIT && d != OP_WHITESPACE && d != OP_WORDCHAR) ||          if (d == OP_ANY && ptr + 1 >= md->end_subject &&
1289                (md->moptions & (PCRE_PARTIAL_HARD)) != 0 &&
1290                NLBLOCK->nltype == NLTYPE_FIXED &&
1291                NLBLOCK->nllen == 2 &&
1292                c == NLBLOCK->nl[0])
1293              {
1294              could_continue = partial_newline = TRUE;
1295              }
1296            else if ((c >= 256 && d != OP_DIGIT && d != OP_WHITESPACE && d != OP_WORDCHAR) ||
1297              (c < 256 &&              (c < 256 &&
1298                (d != OP_ANY || !IS_NEWLINE(ptr)) &&                (d != OP_ANY || !IS_NEWLINE(ptr)) &&
1299                ((ctypes[c] & toptable1[d]) ^ toptable2[d]) != 0))                ((ctypes[c] & toptable1[d]) ^ toptable2[d]) != 0))
# Line 1186  for (;;) Line 1303  for (;;)
1303              active_count--;           /* Remove non-match possibility */              active_count--;           /* Remove non-match possibility */
1304              next_active_state--;              next_active_state--;
1305              }              }
1306            if (++count >= GET2(code, 1))            if (++count >= (int)GET2(code, 1))
1307              { ADD_NEW(state_offset + 2 + IMM2_SIZE, 0); }              { ADD_NEW(state_offset + 2 + IMM2_SIZE, 0); }
1308            else            else
# Line 1209  for (;;) Line 1326  for (;;)
1326        if (clen > 0)        if (clen > 0)
1327          {          {
1328          BOOL OK;          BOOL OK;
1329            const pcre_uint32 *cp;
1330          const ucd_record * prop = GET_UCD(c);          const ucd_record * prop = GET_UCD(c);
1331          switch(code[2])          switch(code[2])
1332            {            {
# Line 1240  for (;;) Line 1358  for (;;)
1358                 PRIV(ucp_gentype)[prop->chartype] == ucp_N;                 PRIV(ucp_gentype)[prop->chartype] == ucp_N;
1359            break;            break;
1360
1361            case PT_SPACE:    /* Perl space */            /* Perl space used to exclude VT, but from Perl 5.18 it is included,
1362            OK = PRIV(ucp_gentype)[prop->chartype] == ucp_Z ||            which means that Perl space and POSIX space are now identical. PCRE
1363                 c == CHAR_HT || c == CHAR_NL || c == CHAR_FF || c == CHAR_CR;            was changed at release 8.34. */
break;
1364
1365              case PT_SPACE:    /* Perl space */
1366            case PT_PXSPACE:  /* POSIX space */            case PT_PXSPACE:  /* POSIX space */
1367            OK = PRIV(ucp_gentype)[prop->chartype] == ucp_Z ||            switch(c)
1368                 c == CHAR_HT || c == CHAR_NL || c == CHAR_VT ||              {
1369                 c == CHAR_FF || c == CHAR_CR;              HSPACE_CASES:
1370                VSPACE_CASES:
1371                OK = TRUE;
1372                break;
1373
1374                default:
1375                OK = PRIV(ucp_gentype)[prop->chartype] == ucp_Z;
1376                break;
1377                }
1378            break;            break;
1379
1380            case PT_WORD:            case PT_WORD:
# Line 1257  for (;;) Line 1383  for (;;)
1383                 c == CHAR_UNDERSCORE;                 c == CHAR_UNDERSCORE;
1384            break;            break;
1385
1386              case PT_CLIST:
1387              cp = PRIV(ucd_caseless_sets) + code[3];
1388              for (;;)
1389                {
1390                if (c < *cp) { OK = FALSE; break; }
1391                if (c == *cp++) { OK = TRUE; break; }
1392                }
1393              break;
1394
1395              case PT_UCNC:
1396              OK = c == CHAR_DOLLAR_SIGN || c == CHAR_COMMERCIAL_AT ||
1397                   c == CHAR_GRAVE_ACCENT || (c >= 0xa0 && c <= 0xd7ff) ||
1398                   c >= 0xe000;
1399              break;
1400
1401            /* Should never occur, but keep compilers from grumbling. */            /* Should never occur, but keep compilers from grumbling. */
1402
1403            default:            default:
# Line 1283  for (;;) Line 1424  for (;;)
1424        case OP_EXTUNI_EXTRA + OP_TYPEPOSPLUS:        case OP_EXTUNI_EXTRA + OP_TYPEPOSPLUS:
1425        count = current_state->count;  /* Already matched */        count = current_state->count;  /* Already matched */
1426        if (count > 0) { ADD_ACTIVE(state_offset + 2, 0); }        if (count > 0) { ADD_ACTIVE(state_offset + 2, 0); }
1427        if (clen > 0 && UCD_CATEGORY(c) != ucp_M)        if (clen > 0)
1428          {          {
1429            int lgb, rgb;
1430          const pcre_uchar *nptr = ptr + clen;          const pcre_uchar *nptr = ptr + clen;
1431          int ncount = 0;          int ncount = 0;
1432          if (count > 0 && codevalue == OP_EXTUNI_EXTRA + OP_TYPEPOSPLUS)          if (count > 0 && codevalue == OP_EXTUNI_EXTRA + OP_TYPEPOSPLUS)
# Line 1292  for (;;) Line 1434  for (;;)
1434            active_count--;           /* Remove non-match possibility */            active_count--;           /* Remove non-match possibility */
1435            next_active_state--;            next_active_state--;
1436            }            }
1437            lgb = UCD_GRAPHBREAK(c);
1438          while (nptr < end_subject)          while (nptr < end_subject)
1439            {            {
1440            int nd;            dlen = 1;
1441            int ndlen = 1;            if (!utf) d = *nptr; else { GETCHARLEN(d, nptr, dlen); }
1442            GETCHARLEN(nd, nptr, ndlen);            rgb = UCD_GRAPHBREAK(d);
1443            if (UCD_CATEGORY(nd) != ucp_M) break;            if ((PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0) break;
1444            ncount++;            ncount++;
1445            nptr += ndlen;            lgb = rgb;
1446              nptr += dlen;
1447            }            }
1448          count++;          count++;
# Line 1318  for (;;) Line 1462  for (;;)
1462          int ncount = 0;          int ncount = 0;
1463          switch (c)          switch (c)
1464            {            {
1465            case 0x000b:            case CHAR_VT:
1466            case 0x000c:            case CHAR_FF:
1467            case 0x0085:            case CHAR_NEL:
1468    #ifndef EBCDIC
1469            case 0x2028:            case 0x2028:
1470            case 0x2029:            case 0x2029:
1471    #endif  /* Not EBCDIC */
1472            if ((md->moptions & PCRE_BSR_ANYCRLF) != 0) break;            if ((md->moptions & PCRE_BSR_ANYCRLF) != 0) break;
1473            goto ANYNL01;            goto ANYNL01;
1474
1475            case 0x000d:            case CHAR_CR:
1476            if (ptr + 1 < end_subject && ptr[1] == 0x0a) ncount = 1;            if (ptr + 1 < end_subject && ptr[1] == CHAR_LF) ncount = 1;
1477            /* Fall through */            /* Fall through */
1478
1479            ANYNL01:            ANYNL01:
1480            case 0x000a:            case CHAR_LF:
1481            if (count > 0 && codevalue == OP_ANYNL_EXTRA + OP_TYPEPOSPLUS)            if (count > 0 && codevalue == OP_ANYNL_EXTRA + OP_TYPEPOSPLUS)
1482              {              {
1483              active_count--;           /* Remove non-match possibility */              active_count--;           /* Remove non-match possibility */
# Line 1358  for (;;) Line 1504  for (;;)
1504          BOOL OK;          BOOL OK;
1505          switch (c)          switch (c)
1506            {            {
1507            case 0x000a:            VSPACE_CASES:
case 0x000b:
case 0x000c:
case 0x000d:
case 0x0085:
case 0x2028:
case 0x2029:
1508            OK = TRUE;            OK = TRUE;
1509            break;            break;
1510
# Line 1397  for (;;) Line 1537  for (;;)
1537          BOOL OK;          BOOL OK;
1538          switch (c)          switch (c)
1539            {            {
1540            case 0x09:      /* HT */            HSPACE_CASES:
case 0x20:      /* SPACE */
case 0xa0:      /* NBSP */
case 0x1680:    /* OGHAM SPACE MARK */
case 0x180e:    /* MONGOLIAN VOWEL SEPARATOR */
case 0x2000:    /* EN QUAD */
case 0x2001:    /* EM QUAD */
case 0x2002:    /* EN SPACE */
case 0x2003:    /* EM SPACE */
case 0x2004:    /* THREE-PER-EM SPACE */
case 0x2005:    /* FOUR-PER-EM SPACE */
case 0x2006:    /* SIX-PER-EM SPACE */
case 0x2007:    /* FIGURE SPACE */
case 0x2008:    /* PUNCTUATION SPACE */
case 0x2009:    /* THIN SPACE */
case 0x200A:    /* HAIR SPACE */
case 0x202f:    /* NARROW NO-BREAK SPACE */
case 0x205f:    /* MEDIUM MATHEMATICAL SPACE */
case 0x3000:    /* IDEOGRAPHIC SPACE */
1541            OK = TRUE;            OK = TRUE;
1542            break;            break;
1543
# Line 1456  for (;;) Line 1578  for (;;)
1578        if (clen > 0)        if (clen > 0)
1579          {          {
1580          BOOL OK;          BOOL OK;
1581            const pcre_uint32 *cp;
1582          const ucd_record * prop = GET_UCD(c);          const ucd_record * prop = GET_UCD(c);
1583          switch(code[2])          switch(code[2])
1584            {            {
# Line 1487  for (;;) Line 1610  for (;;)
1610                 PRIV(ucp_gentype)[prop->chartype] == ucp_N;                 PRIV(ucp_gentype)[prop->chartype] == ucp_N;
1611            break;            break;
1612
1613            case PT_SPACE:    /* Perl space */            /* Perl space used to exclude VT, but from Perl 5.18 it is included,
1614            OK = PRIV(ucp_gentype)[prop->chartype] == ucp_Z ||            which means that Perl space and POSIX space are now identical. PCRE
1615                 c == CHAR_HT || c == CHAR_NL || c == CHAR_FF || c == CHAR_CR;            was changed at release 8.34. */
break;
1616
1617              case PT_SPACE:    /* Perl space */
1618            case PT_PXSPACE:  /* POSIX space */            case PT_PXSPACE:  /* POSIX space */
1619            OK = PRIV(ucp_gentype)[prop->chartype] == ucp_Z ||            switch(c)
1620                 c == CHAR_HT || c == CHAR_NL || c == CHAR_VT ||              {
1621                 c == CHAR_FF || c == CHAR_CR;              HSPACE_CASES:
1622                VSPACE_CASES:
1623                OK = TRUE;
1624                break;
1625
1626                default:
1627                OK = PRIV(ucp_gentype)[prop->chartype] == ucp_Z;
1628                break;
1629                }
1630            break;            break;
1631
1632            case PT_WORD:            case PT_WORD:
# Line 1504  for (;;) Line 1635  for (;;)
1635                 c == CHAR_UNDERSCORE;                 c == CHAR_UNDERSCORE;
1636            break;            break;
1637
1638              case PT_CLIST:
1639              cp = PRIV(ucd_caseless_sets) + code[3];
1640              for (;;)
1641                {
1642                if (c < *cp) { OK = FALSE; break; }
1643                if (c == *cp++) { OK = TRUE; break; }
1644                }
1645              break;
1646
1647              case PT_UCNC:
1648              OK = c == CHAR_DOLLAR_SIGN || c == CHAR_COMMERCIAL_AT ||
1649                   c == CHAR_GRAVE_ACCENT || (c >= 0xa0 && c <= 0xd7ff) ||
1650                   c >= 0xe000;
1651              break;
1652
1653            /* Should never occur, but keep compilers from grumbling. */            /* Should never occur, but keep compilers from grumbling. */
1654
1655            default:            default:
# Line 1539  for (;;) Line 1685  for (;;)
1685        QS2:        QS2:
1686
1688        if (clen > 0 && UCD_CATEGORY(c) != ucp_M)        if (clen > 0)
1689          {          {
1690            int lgb, rgb;
1691          const pcre_uchar *nptr = ptr + clen;          const pcre_uchar *nptr = ptr + clen;
1692          int ncount = 0;          int ncount = 0;
1693          if (codevalue == OP_EXTUNI_EXTRA + OP_TYPEPOSSTAR ||          if (codevalue == OP_EXTUNI_EXTRA + OP_TYPEPOSSTAR ||
# Line 1549  for (;;) Line 1696  for (;;)
1696            active_count--;           /* Remove non-match possibility */            active_count--;           /* Remove non-match possibility */
1697            next_active_state--;            next_active_state--;
1698            }            }
1699            lgb = UCD_GRAPHBREAK(c);
1700          while (nptr < end_subject)          while (nptr < end_subject)
1701            {            {
1702            int nd;            dlen = 1;
1703            int ndlen = 1;            if (!utf) d = *nptr; else { GETCHARLEN(d, nptr, dlen); }
1704            GETCHARLEN(nd, nptr, ndlen);            rgb = UCD_GRAPHBREAK(d);
1705            if (UCD_CATEGORY(nd) != ucp_M) break;            if ((PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0) break;
1706            ncount++;            ncount++;
1707            nptr += ndlen;            lgb = rgb;
1708              nptr += dlen;
1709            }            }
1711          }          }
# Line 1582  for (;;) Line 1731  for (;;)
1731          int ncount = 0;          int ncount = 0;
1732          switch (c)          switch (c)
1733            {            {
1734            case 0x000b:            case CHAR_VT:
1735            case 0x000c:            case CHAR_FF:
1736            case 0x0085:            case CHAR_NEL:
1737    #ifndef EBCDIC
1738            case 0x2028:            case 0x2028:
1739            case 0x2029:            case 0x2029:
1740    #endif  /* Not EBCDIC */
1741            if ((md->moptions & PCRE_BSR_ANYCRLF) != 0) break;            if ((md->moptions & PCRE_BSR_ANYCRLF) != 0) break;
1742            goto ANYNL02;            goto ANYNL02;
1743
1744            case 0x000d:            case CHAR_CR:
1745            if (ptr + 1 < end_subject && ptr[1] == 0x0a) ncount = 1;            if (ptr + 1 < end_subject && ptr[1] == CHAR_LF) ncount = 1;
1746            /* Fall through */            /* Fall through */
1747
1748            ANYNL02:            ANYNL02:
1749            case 0x000a:            case CHAR_LF:
1750            if (codevalue == OP_ANYNL_EXTRA + OP_TYPEPOSSTAR ||            if (codevalue == OP_ANYNL_EXTRA + OP_TYPEPOSSTAR ||
1751                codevalue == OP_ANYNL_EXTRA + OP_TYPEPOSQUERY)                codevalue == OP_ANYNL_EXTRA + OP_TYPEPOSQUERY)
1752              {              {
1753              active_count--;           /* Remove non-match possibility */              active_count--;           /* Remove non-match possibility */
1754              next_active_state--;              next_active_state--;
1755              }              }
1757            break;            break;
1758
1759            default:            default:
# Line 1630  for (;;) Line 1781  for (;;)
1781          BOOL OK;          BOOL OK;
1782          switch (c)          switch (c)
1783            {            {
1784            case 0x000a:            VSPACE_CASES:
case 0x000b:
case 0x000c:
case 0x000d:
case 0x0085:
case 0x2028:
case 0x2029:
1785            OK = TRUE;            OK = TRUE;
1786            break;            break;
1787
# Line 1652  for (;;) Line 1797  for (;;)
1797              active_count--;           /* Remove non-match possibility */              active_count--;           /* Remove non-match possibility */
1798              next_active_state--;              next_active_state--;
1799              }              }
1801            }            }
1802          }          }
1803        break;        break;
# Line 1676  for (;;) Line 1821  for (;;)
1821          BOOL OK;          BOOL OK;
1822          switch (c)          switch (c)
1823            {            {
1824            case 0x09:      /* HT */            HSPACE_CASES:
case 0x20:      /* SPACE */
case 0xa0:      /* NBSP */
case 0x1680:    /* OGHAM SPACE MARK */
case 0x180e:    /* MONGOLIAN VOWEL SEPARATOR */
case 0x2000:    /* EN QUAD */
case 0x2001:    /* EM QUAD */
case 0x2002:    /* EN SPACE */
case 0x2003:    /* EM SPACE */
case 0x2004:    /* THREE-PER-EM SPACE */
case 0x2005:    /* FOUR-PER-EM SPACE */
case 0x2006:    /* SIX-PER-EM SPACE */
case 0x2007:    /* FIGURE SPACE */
case 0x2008:    /* PUNCTUATION SPACE */
case 0x2009:    /* THIN SPACE */
case 0x200A:    /* HAIR SPACE */
case 0x202f:    /* NARROW NO-BREAK SPACE */
case 0x205f:    /* MEDIUM MATHEMATICAL SPACE */
case 0x3000:    /* IDEOGRAPHIC SPACE */
1825            OK = TRUE;            OK = TRUE;
1826            break;            break;
1827
# Line 1711  for (;;) Line 1838  for (;;)
1838              active_count--;           /* Remove non-match possibility */              active_count--;           /* Remove non-match possibility */
1839              next_active_state--;              next_active_state--;
1840              }              }
1842            }            }
1843          }          }
1844        break;        break;
# Line 1728  for (;;) Line 1855  for (;;)
1855        if (clen > 0)        if (clen > 0)
1856          {          {
1857          BOOL OK;          BOOL OK;
1858            const pcre_uint32 *cp;
1859          const ucd_record * prop = GET_UCD(c);          const ucd_record * prop = GET_UCD(c);
1860          switch(code[1 + IMM2_SIZE + 1])          switch(code[1 + IMM2_SIZE + 1])
1861            {            {
# Line 1759  for (;;) Line 1887  for (;;)
1887                 PRIV(ucp_gentype)[prop->chartype] == ucp_N;                 PRIV(ucp_gentype)[prop->chartype] == ucp_N;
1888            break;            break;
1889
1890            case PT_SPACE:    /* Perl space */            /* Perl space used to exclude VT, but from Perl 5.18 it is included,
1891            OK = PRIV(ucp_gentype)[prop->chartype] == ucp_Z ||            which means that Perl space and POSIX space are now identical. PCRE
1892                 c == CHAR_HT || c == CHAR_NL || c == CHAR_FF || c == CHAR_CR;            was changed at release 8.34. */
break;
1893
1894              case PT_SPACE:    /* Perl space */
1895            case PT_PXSPACE:  /* POSIX space */            case PT_PXSPACE:  /* POSIX space */
1896            OK = PRIV(ucp_gentype)[prop->chartype] == ucp_Z ||            switch(c)
1897                 c == CHAR_HT || c == CHAR_NL || c == CHAR_VT ||              {
1898                 c == CHAR_FF || c == CHAR_CR;              HSPACE_CASES:
1899                VSPACE_CASES:
1900                OK = TRUE;
1901                break;
1902
1903                default:
1904                OK = PRIV(ucp_gentype)[prop->chartype] == ucp_Z;
1905                break;
1906                }
1907            break;            break;
1908
1909            case PT_WORD:            case PT_WORD:
# Line 1776  for (;;) Line 1912  for (;;)
1912                 c == CHAR_UNDERSCORE;                 c == CHAR_UNDERSCORE;
1913            break;            break;
1914
1915              case PT_CLIST:
1916              cp = PRIV(ucd_caseless_sets) + code[1 + IMM2_SIZE + 2];
1917              for (;;)
1918                {
1919                if (c < *cp) { OK = FALSE; break; }
1920                if (c == *cp++) { OK = TRUE; break; }
1921                }
1922              break;
1923
1924              case PT_UCNC:
1925              OK = c == CHAR_DOLLAR_SIGN || c == CHAR_COMMERCIAL_AT ||
1926                   c == CHAR_GRAVE_ACCENT || (c >= 0xa0 && c <= 0xd7ff) ||
1927                   c >= 0xe000;
1928              break;
1929
1930            /* Should never occur, but keep compilers from grumbling. */            /* Should never occur, but keep compilers from grumbling. */
1931
1932            default:            default:
# Line 1790  for (;;) Line 1941  for (;;)
1941              active_count--;           /* Remove non-match possibility */              active_count--;           /* Remove non-match possibility */
1942              next_active_state--;              next_active_state--;
1943              }              }
1944            if (++count >= GET2(code, 1))            if (++count >= (int)GET2(code, 1))
1945              { ADD_NEW(state_offset + 1 + IMM2_SIZE + 3, 0); }              { ADD_NEW(state_offset + 1 + IMM2_SIZE + 3, 0); }
1946            else            else
# Line 1806  for (;;) Line 1957  for (;;)
1957        if (codevalue != OP_EXTUNI_EXTRA + OP_TYPEEXACT)        if (codevalue != OP_EXTUNI_EXTRA + OP_TYPEEXACT)
1958          { ADD_ACTIVE(state_offset + 2 + IMM2_SIZE, 0); }          { ADD_ACTIVE(state_offset + 2 + IMM2_SIZE, 0); }
1959        count = current_state->count;  /* Number already matched */        count = current_state->count;  /* Number already matched */
1960        if (clen > 0 && UCD_CATEGORY(c) != ucp_M)        if (clen > 0)
1961          {          {
1962            int lgb, rgb;
1963          const pcre_uchar *nptr = ptr + clen;          const pcre_uchar *nptr = ptr + clen;
1964          int ncount = 0;          int ncount = 0;
1965          if (codevalue == OP_EXTUNI_EXTRA + OP_TYPEPOSUPTO)          if (codevalue == OP_EXTUNI_EXTRA + OP_TYPEPOSUPTO)
# Line 1815  for (;;) Line 1967  for (;;)
1967            active_count--;           /* Remove non-match possibility */            active_count--;           /* Remove non-match possibility */
1968            next_active_state--;            next_active_state--;
1969            }            }
1970            lgb = UCD_GRAPHBREAK(c);
1971          while (nptr < end_subject)          while (nptr < end_subject)
1972            {            {
1973            int nd;            dlen = 1;
1974            int ndlen = 1;            if (!utf) d = *nptr; else { GETCHARLEN(d, nptr, dlen); }
1975            GETCHARLEN(nd, nptr, ndlen);            rgb = UCD_GRAPHBREAK(d);
1976            if (UCD_CATEGORY(nd) != ucp_M) break;            if ((PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0) break;
1977            ncount++;            ncount++;
1978            nptr += ndlen;            lgb = rgb;
1979              nptr += dlen;
1980            }            }
1981          if (++count >= GET2(code, 1))          if (nptr >= end_subject && (md->moptions & PCRE_PARTIAL_HARD) != 0)
1982                reset_could_continue = TRUE;
1983            if (++count >= (int)GET2(code, 1))
1984            { ADD_NEW_DATA(-(state_offset + 2 + IMM2_SIZE), 0, ncount); }            { ADD_NEW_DATA(-(state_offset + 2 + IMM2_SIZE), 0, ncount); }
1985          else          else
# Line 1845  for (;;) Line 2001  for (;;)
2001          int ncount = 0;          int ncount = 0;
2002          switch (c)          switch (c)
2003            {            {
2004            case 0x000b:            case CHAR_VT:
2005            case 0x000c:            case CHAR_FF:
2006            case 0x0085:            case CHAR_NEL:
2007    #ifndef EBCDIC
2008            case 0x2028:            case 0x2028:
2009            case 0x2029:            case 0x2029:
2010    #endif  /* Not EBCDIC */
2011            if ((md->moptions & PCRE_BSR_ANYCRLF) != 0) break;            if ((md->moptions & PCRE_BSR_ANYCRLF) != 0) break;
2012            goto ANYNL03;            goto ANYNL03;
2013
2014            case 0x000d:            case CHAR_CR:
2015            if (ptr + 1 < end_subject && ptr[1] == 0x0a) ncount = 1;            if (ptr + 1 < end_subject && ptr[1] == CHAR_LF) ncount = 1;
2016            /* Fall through */            /* Fall through */
2017
2018            ANYNL03:            ANYNL03:
2019            case 0x000a:            case CHAR_LF:
2020            if (codevalue == OP_ANYNL_EXTRA + OP_TYPEPOSUPTO)            if (codevalue == OP_ANYNL_EXTRA + OP_TYPEPOSUPTO)
2021              {              {
2022              active_count--;           /* Remove non-match possibility */              active_count--;           /* Remove non-match possibility */
2023              next_active_state--;              next_active_state--;
2024              }              }
2025            if (++count >= GET2(code, 1))            if (++count >= (int)GET2(code, 1))
2026              { ADD_NEW_DATA(-(state_offset + 2 + IMM2_SIZE), 0, ncount); }              { ADD_NEW_DATA(-(state_offset + 2 + IMM2_SIZE), 0, ncount); }
2027            else            else
# Line 1889  for (;;) Line 2047  for (;;)
2047          BOOL OK;          BOOL OK;
2048          switch (c)          switch (c)
2049            {            {
2050            case 0x000a:            VSPACE_CASES:
case 0x000b:
case 0x000c:
case 0x000d:
case 0x0085:
case 0x2028:
case 0x2029:
2051            OK = TRUE;            OK = TRUE;
2052            break;            break;
2053
# Line 1910  for (;;) Line 2062  for (;;)
2062              active_count--;           /* Remove non-match possibility */              active_count--;           /* Remove non-match possibility */
2063              next_active_state--;              next_active_state--;
2064              }              }
2065            if (++count >= GET2(code, 1))            if (++count >= (int)GET2(code, 1))
2066              { ADD_NEW_DATA(-(state_offset + 2 + IMM2_SIZE), 0, 0); }              { ADD_NEW_DATA(-(state_offset + 2 + IMM2_SIZE), 0, 0); }
2067            else            else
# Line 1931  for (;;) Line 2083  for (;;)
2083          BOOL OK;          BOOL OK;
2084          switch (c)          switch (c)
2085            {            {
2086            case 0x09:      /* HT */            HSPACE_CASES:
case 0x20:      /* SPACE */
case 0xa0:      /* NBSP */
case 0x1680:    /* OGHAM SPACE MARK */
case 0x180e:    /* MONGOLIAN VOWEL SEPARATOR */
case 0x2000:    /* EN QUAD */
case 0x2001:    /* EM QUAD */
case 0x2002:    /* EN SPACE */
case 0x2003:    /* EM SPACE */
case 0x2004:    /* THREE-PER-EM SPACE */
case 0x2005:    /* FOUR-PER-EM SPACE */
case 0x2006:    /* SIX-PER-EM SPACE */
case 0x2007:    /* FIGURE SPACE */
case 0x2008:    /* PUNCTUATION SPACE */
case 0x2009:    /* THIN SPACE */
case 0x200A:    /* HAIR SPACE */
case 0x202f:    /* NARROW NO-BREAK SPACE */
case 0x205f:    /* MEDIUM MATHEMATICAL SPACE */
case 0x3000:    /* IDEOGRAPHIC SPACE */
2087            OK = TRUE;            OK = TRUE;
2088            break;            break;
2089
# Line 1965  for (;;) Line 2099  for (;;)
2099              active_count--;           /* Remove non-match possibility */              active_count--;           /* Remove non-match possibility */
2100              next_active_state--;              next_active_state--;
2101              }              }
2102            if (++count >= GET2(code, 1))            if (++count >= (int)GET2(code, 1))
2103              { ADD_NEW_DATA(-(state_offset + 2 + IMM2_SIZE), 0, 0); }              { ADD_NEW_DATA(-(state_offset + 2 + IMM2_SIZE), 0, 0); }
2104            else            else
# Line 2025  for (;;) Line 2159  for (;;)
2159        to wait for them to pass before continuing. */        to wait for them to pass before continuing. */
2160
2161        case OP_EXTUNI:        case OP_EXTUNI:
2162        if (clen > 0 && UCD_CATEGORY(c) != ucp_M)        if (clen > 0)
2163          {          {
2164            int lgb, rgb;
2165          const pcre_uchar *nptr = ptr + clen;          const pcre_uchar *nptr = ptr + clen;
2166          int ncount = 0;          int ncount = 0;
2167            lgb = UCD_GRAPHBREAK(c);
2168          while (nptr < end_subject)          while (nptr < end_subject)
2169            {            {
2170            int nclen = 1;            dlen = 1;
2171            GETCHARLEN(c, nptr, nclen);            if (!utf) d = *nptr; else { GETCHARLEN(d, nptr, dlen); }
2172            if (UCD_CATEGORY(c) != ucp_M) break;            rgb = UCD_GRAPHBREAK(d);
2173              if ((PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0) break;
2174            ncount++;            ncount++;
2175            nptr += nclen;            lgb = rgb;
2176              nptr += dlen;
2177            }            }
2178            if (nptr >= end_subject && (md->moptions & PCRE_PARTIAL_HARD) != 0)
2179                reset_could_continue = TRUE;
2181          }          }
2182        break;        break;
# Line 2050  for (;;) Line 2190  for (;;)
2190        case OP_ANYNL:        case OP_ANYNL:
2191        if (clen > 0) switch(c)        if (clen > 0) switch(c)
2192          {          {
2193          case 0x000b:          case CHAR_VT:
2194          case 0x000c:          case CHAR_FF:
2195          case 0x0085:          case CHAR_NEL:
2196    #ifndef EBCDIC
2197          case 0x2028:          case 0x2028:
2198          case 0x2029:          case 0x2029:
2199    #endif  /* Not EBCDIC */
2200          if ((md->moptions & PCRE_BSR_ANYCRLF) != 0) break;          if ((md->moptions & PCRE_BSR_ANYCRLF) != 0) break;
2201
2202          case 0x000a:          case CHAR_LF:
2204          break;          break;
2205
2206          case 0x000d:          case CHAR_CR:
2207          if (ptr + 1 < end_subject && ptr[1] == 0x0a)          if (ptr + 1 >= end_subject)
2208              {
2210              if ((md->moptions & PCRE_PARTIAL_HARD) != 0)
2211                reset_could_continue = TRUE;
2212              }
2213            else if (ptr[1] == CHAR_LF)
2214            {            {
2216            }            }
# Line 2078  for (;;) Line 2226  for (;;)
2226        case OP_NOT_VSPACE:        case OP_NOT_VSPACE:
2227        if (clen > 0) switch(c)        if (clen > 0) switch(c)
2228          {          {
2229          case 0x000a:          VSPACE_CASES:
case 0x000b:
case 0x000c:
case 0x000d:
case 0x0085:
case 0x2028:
case 0x2029:
2230          break;          break;
2231
2232          default:          default:
# Line 2097  for (;;) Line 2239  for (;;)
2239        case OP_VSPACE:        case OP_VSPACE:
2240        if (clen > 0) switch(c)        if (clen > 0) switch(c)
2241          {          {
2242          case 0x000a:          VSPACE_CASES:
case 0x000b:
case 0x000c:
case 0x000d:
case 0x0085:
case 0x2028:
case 0x2029:
2244          break;          break;
2245
2246          default: break;          default:
2247            break;
2248          }          }
2249        break;        break;
2250
# Line 2115  for (;;) Line 2252  for (;;)
2252        case OP_NOT_HSPACE:        case OP_NOT_HSPACE:
2253        if (clen > 0) switch(c)        if (clen > 0) switch(c)
2254          {          {
2255          case 0x09:      /* HT */          HSPACE_CASES:
case 0x20:      /* SPACE */
case 0xa0:      /* NBSP */
case 0x1680:    /* OGHAM SPACE MARK */
case 0x180e:    /* MONGOLIAN VOWEL SEPARATOR */
case 0x2000:    /* EN QUAD */
case 0x2001:    /* EM QUAD */
case 0x2002:    /* EN SPACE */
case 0x2003:    /* EM SPACE */
case 0x2004:    /* THREE-PER-EM SPACE */
case 0x2005:    /* FOUR-PER-EM SPACE */
case 0x2006:    /* SIX-PER-EM SPACE */
case 0x2007:    /* FIGURE SPACE */
case 0x2008:    /* PUNCTUATION SPACE */
case 0x2009:    /* THIN SPACE */
case 0x200A:    /* HAIR SPACE */
case 0x202f:    /* NARROW NO-BREAK SPACE */
case 0x205f:    /* MEDIUM MATHEMATICAL SPACE */
case 0x3000:    /* IDEOGRAPHIC SPACE */
2256          break;          break;
2257
2258          default:          default:
# Line 2146  for (;;) Line 2265  for (;;)
2265        case OP_HSPACE:        case OP_HSPACE:
2266        if (clen > 0) switch(c)        if (clen > 0) switch(c)
2267          {          {
2268          case 0x09:      /* HT */          HSPACE_CASES:
case 0x20:      /* SPACE */
case 0xa0:      /* NBSP */
case 0x1680:    /* OGHAM SPACE MARK */
case 0x180e:    /* MONGOLIAN VOWEL SEPARATOR */
case 0x2000:    /* EN QUAD */
case 0x2001:    /* EM QUAD */
case 0x2002:    /* EN SPACE */
case 0x2003:    /* EM SPACE */
case 0x2004:    /* THREE-PER-EM SPACE */
case 0x2005:    /* FOUR-PER-EM SPACE */
case 0x2006:    /* SIX-PER-EM SPACE */
case 0x2007:    /* FIGURE SPACE */
case 0x2008:    /* PUNCTUATION SPACE */
case 0x2009:    /* THIN SPACE */
case 0x200A:    /* HAIR SPACE */
case 0x202f:    /* NARROW NO-BREAK SPACE */
case 0x205f:    /* MEDIUM MATHEMATICAL SPACE */
case 0x3000:    /* IDEOGRAPHIC SPACE */
2270          break;          break;
2271
2272            default:
2273            break;
2274          }          }
2275        break;        break;
2276
2277        /*-----------------------------------------------------------------*/        /*-----------------------------------------------------------------*/
2278        /* Match a negated single character casefully. This is only used for        /* Match a negated single character casefully. */
one-byte characters, that is, we know that d < 256. The character we are
checking (c) can be multibyte. */
2279
2280        case OP_NOT:        case OP_NOT:
2281        if (clen > 0 && c != d) { ADD_NEW(state_offset + dlen + 1, 0); }        if (clen > 0 && c != d) { ADD_NEW(state_offset + dlen + 1, 0); }
2282        break;        break;
2283
2284        /*-----------------------------------------------------------------*/        /*-----------------------------------------------------------------*/
2285        /* Match a negated single character caselessly. This is only used for        /* Match a negated single character caselessly. */
one-byte characters, that is, we know that d < 256. The character we are
checking (c) can be multibyte. */
2286
2287        case OP_NOTI:        case OP_NOTI:
2288        if (clen > 0 && c != d && c != fcc[d])        if (clen > 0)
2289          { ADD_NEW(state_offset + dlen + 1, 0); }          {
2290            unsigned int otherd;
2291    #ifdef SUPPORT_UTF
2292            if (utf && d >= 128)
2293              {
2294    #ifdef SUPPORT_UCP
2295              otherd = UCD_OTHERCASE(d);
2296    #endif  /* SUPPORT_UCP */
2297              }
2298            else
2299    #endif  /* SUPPORT_UTF */
2300            otherd = TABLE_GET(d, fcc, d);
2301            if (c != d && c != otherd)
2302              { ADD_NEW(state_offset + dlen + 1, 0); }
2303            }
2304        break;        break;
2305
2306        /*-----------------------------------------------------------------*/        /*-----------------------------------------------------------------*/
# Line 2210  for (;;) Line 2324  for (;;)
2324        if (count > 0) { ADD_ACTIVE(state_offset + dlen + 1, 0); }        if (count > 0) { ADD_ACTIVE(state_offset + dlen + 1, 0); }
2325        if (clen > 0)        if (clen > 0)
2326          {          {
2327          unsigned int otherd = NOTACHAR;          pcre_uint32 otherd = NOTACHAR;
2328          if (caseless)          if (caseless)
2329            {            {
2330  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
# Line 2257  for (;;) Line 2371  for (;;)
2371        ADD_ACTIVE(state_offset + dlen + 1, 0);        ADD_ACTIVE(state_offset + dlen + 1, 0);
2372        if (clen > 0)        if (clen > 0)
2373          {          {
2374          unsigned int otherd = NOTACHAR;          pcre_uint32 otherd = NOTACHAR;
2375          if (caseless)          if (caseless)
2376            {            {
2377  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
# Line 2302  for (;;) Line 2416  for (;;)
2416        ADD_ACTIVE(state_offset + dlen + 1, 0);        ADD_ACTIVE(state_offset + dlen + 1, 0);
2417        if (clen > 0)        if (clen > 0)
2418          {          {
2419          unsigned int otherd = NOTACHAR;          pcre_uint32 otherd = NOTACHAR;
2420          if (caseless)          if (caseless)
2421            {            {
2422  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
# Line 2339  for (;;) Line 2453  for (;;)
2453        count = current_state->count;  /* Number already matched */        count = current_state->count;  /* Number already matched */
2454        if (clen > 0)        if (clen > 0)
2455          {          {
2456          unsigned int otherd = NOTACHAR;          pcre_uint32 otherd = NOTACHAR;
2457          if (caseless)          if (caseless)
2458            {            {
2459  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
# Line 2355  for (;;) Line 2469  for (;;)
2469            }            }
2470          if ((c == d || c == otherd) == (codevalue < OP_NOTSTAR))          if ((c == d || c == otherd) == (codevalue < OP_NOTSTAR))
2471            {            {
2472            if (++count >= GET2(code, 1))            if (++count >= (int)GET2(code, 1))
2473              { ADD_NEW(state_offset + dlen + 1 + IMM2_SIZE, 0); }              { ADD_NEW(state_offset + dlen + 1 + IMM2_SIZE, 0); }
2474            else            else
# Line 2383  for (;;) Line 2497  for (;;)
2497        count = current_state->count;  /* Number already matched */        count = current_state->count;  /* Number already matched */
2498        if (clen > 0)        if (clen > 0)
2499          {          {
2500          unsigned int otherd = NOTACHAR;          pcre_uint32 otherd = NOTACHAR;
2501          if (caseless)          if (caseless)
2502            {            {
2503  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
# Line 2404  for (;;) Line 2518  for (;;)
2518              active_count--;             /* Remove non-match possibility */              active_count--;             /* Remove non-match possibility */
2519              next_active_state--;              next_active_state--;
2520              }              }
2521            if (++count >= GET2(code, 1))            if (++count >= (int)GET2(code, 1))
2522              { ADD_NEW(state_offset + dlen + 1 + IMM2_SIZE, 0); }              { ADD_NEW(state_offset + dlen + 1 + IMM2_SIZE, 0); }
2523            else            else
# Line 2457  for (;;) Line 2571  for (;;)
2571            {            {
2572            case OP_CRSTAR:            case OP_CRSTAR:
2573            case OP_CRMINSTAR:            case OP_CRMINSTAR:
2574              case OP_CRPOSSTAR:
2576            if (isinclass) { ADD_NEW(state_offset, 0); }            if (isinclass)
2577                {
2578                if (*ecode == OP_CRPOSSTAR)
2579                  {
2580                  active_count--;           /* Remove non-match possibility */
2581                  next_active_state--;
2582                  }
2584                }
2585            break;            break;
2586
2587            case OP_CRPLUS:            case OP_CRPLUS:
2588            case OP_CRMINPLUS:            case OP_CRMINPLUS:
2589              case OP_CRPOSPLUS:
2590            count = current_state->count;  /* Already matched */            count = current_state->count;  /* Already matched */
2591            if (count > 0) { ADD_ACTIVE(next_state_offset + 1, 0); }            if (count > 0) { ADD_ACTIVE(next_state_offset + 1, 0); }
2592            if (isinclass) { count++; ADD_NEW(state_offset, count); }            if (isinclass)
2593                {
2594                if (count > 0 && *ecode == OP_CRPOSPLUS)
2595                  {
2596                  active_count--;           /* Remove non-match possibility */
2597                  next_active_state--;
2598                  }
2599                count++;
2601                }
2602            break;            break;
2603
2604            case OP_CRQUERY:            case OP_CRQUERY:
2605            case OP_CRMINQUERY:            case OP_CRMINQUERY:
2606              case OP_CRPOSQUERY:
2608            if (isinclass) { ADD_NEW(next_state_offset + 1, 0); }            if (isinclass)
2609                {
2610                if (*ecode == OP_CRPOSQUERY)
2611                  {
2612                  active_count--;           /* Remove non-match possibility */
2613                  next_active_state--;
2614                  }
2616                }
2617            break;            break;
2618
2619            case OP_CRRANGE:            case OP_CRRANGE:
2620            case OP_CRMINRANGE:            case OP_CRMINRANGE:
2621              case OP_CRPOSRANGE:
2622            count = current_state->count;  /* Already matched */            count = current_state->count;  /* Already matched */
2623            if (count >= GET2(ecode, 1))            if (count >= (int)GET2(ecode, 1))
2624              { ADD_ACTIVE(next_state_offset + 1 + 2 * IMM2_SIZE, 0); }              { ADD_ACTIVE(next_state_offset + 1 + 2 * IMM2_SIZE, 0); }
2625            if (isinclass)            if (isinclass)
2626              {              {
2627              int max = GET2(ecode, 1 + IMM2_SIZE);              int max = (int)GET2(ecode, 1 + IMM2_SIZE);
2628                if (*ecode == OP_CRPOSRANGE)
2629                  {
2630                  active_count--;           /* Remove non-match possibility */
2631                  next_active_state--;
2632                  }
2633              if (++count >= max && max != 0)   /* Max 0 => no limit */              if (++count >= max && max != 0)   /* Max 0 => no limit */
2634                { ADD_NEW(next_state_offset + 1 + 2 * IMM2_SIZE, 0); }                { ADD_NEW(next_state_offset + 1 + 2 * IMM2_SIZE, 0); }
2635              else              else
# Line 2557  for (;;) Line 2705  for (;;)
2705              cb.version          = 1;   /* Version 1 of the callout block */              cb.version          = 1;   /* Version 1 of the callout block */
2707              cb.offset_vector    = offsets;              cb.offset_vector    = offsets;
2708  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
2709              cb.subject          = (PCRE_SPTR)start_subject;              cb.subject          = (PCRE_SPTR)start_subject;
2710  #else  #elif defined COMPILE_PCRE16
2711              cb.subject          = (PCRE_SPTR16)start_subject;              cb.subject          = (PCRE_SPTR16)start_subject;
2712    #elif defined COMPILE_PCRE32
2713                cb.subject          = (PCRE_SPTR32)start_subject;
2714  #endif  #endif
2715              cb.subject_length   = (int)(end_subject - start_subject);              cb.subject_length   = (int)(end_subject - start_subject);
2716              cb.start_match      = (int)(current_subject - start_subject);              cb.start_match      = (int)(current_subject - start_subject);
# Line 2579  for (;;) Line 2729  for (;;)
2729
2731
2732          /* Back reference conditions are not supported */          /* Back reference conditions and duplicate named recursion conditions
2733            are not supported */
2734
2735          if (condcode == OP_CREF || condcode == OP_NCREF)          if (condcode == OP_CREF || condcode == OP_DNCREF ||
2736                condcode == OP_DNRREF)
2737            return PCRE_ERROR_DFA_UCOND;            return PCRE_ERROR_DFA_UCOND;
2738
2739          /* The DEFINE condition is always false */          /* The DEFINE condition is always false */
# Line 2593  for (;;) Line 2745  for (;;)
2745          which means "test if in any recursion". We can't test for specifically          which means "test if in any recursion". We can't test for specifically
2746          recursed groups. */          recursed groups. */
2747
2748          else if (condcode == OP_RREF || condcode == OP_NRREF)          else if (condcode == OP_RREF)
2749            {            {
2750            int value = GET2(code, LINK_SIZE + 2);            int value = GET2(code, LINK_SIZE + 2);
2751            if (value != RREF_ANY) return PCRE_ERROR_DFA_UCOND;            if (value != RREF_ANY) return PCRE_ERROR_DFA_UCOND;
# Line 2690  for (;;) Line 2842  for (;;)
2842            {            {
2843            for (rc = rc*2 - 2; rc >= 0; rc -= 2)            for (rc = rc*2 - 2; rc >= 0; rc -= 2)
2844              {              {
const pcre_uchar *p = start_subject + local_offsets[rc];
const pcre_uchar *pp = start_subject + local_offsets[rc+1];
2845              int charcount = local_offsets[rc+1] - local_offsets[rc];              int charcount = local_offsets[rc+1] - local_offsets[rc];
2846  #ifdef SUPPORT_UTF  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
2847              while (p < pp) if (NOT_FIRSTCHAR(*p++)) charcount--;              if (utf)
2848                  {
2849                  const pcre_uchar *p = start_subject + local_offsets[rc];
2850                  const pcre_uchar *pp = start_subject + local_offsets[rc+1];
2851                  while (p < pp) if (NOT_FIRSTCHAR(*p++)) charcount--;
2852                  }
2853  #endif  #endif
2854              if (charcount > 0)              if (charcount > 0)
2855                {                {
# Line 2792  for (;;) Line 2947  for (;;)
2947              const pcre_uchar *p = ptr;              const pcre_uchar *p = ptr;
2948              const pcre_uchar *pp = local_ptr;              const pcre_uchar *pp = local_ptr;
2949              charcount = (int)(pp - p);              charcount = (int)(pp - p);
2950  #ifdef SUPPORT_UTF  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
2951              while (p < pp) if (NOT_FIRSTCHAR(*p++)) charcount--;              if (utf) while (p < pp) if (NOT_FIRSTCHAR(*p++)) charcount--;
2952  #endif  #endif
2954              }              }
# Line 2874  for (;;) Line 3029  for (;;)
3029              }              }
3030            else            else
3031              {              {
3032  #ifdef SUPPORT_UTF  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
3033              const pcre_uchar *p = start_subject + local_offsets[0];              if (utf)
3034              const pcre_uchar *pp = start_subject + local_offsets[1];                {
3035              while (p < pp) if (NOT_FIRSTCHAR(*p++)) charcount--;                const pcre_uchar *p = start_subject + local_offsets[0];
3036                  const pcre_uchar *pp = start_subject + local_offsets[1];
3037                  while (p < pp) if (NOT_FIRSTCHAR(*p++)) charcount--;
3038                  }
3039  #endif  #endif
3041              if (repeat_state_offset >= 0)              if (repeat_state_offset >= 0)
# Line 2900  for (;;) Line 3058  for (;;)
3058          cb.version          = 1;   /* Version 1 of the callout block */          cb.version          = 1;   /* Version 1 of the callout block */
3059          cb.callout_number   = code[1];          cb.callout_number   = code[1];
3060          cb.offset_vector    = offsets;          cb.offset_vector    = offsets;
3061  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
3062          cb.subject          = (PCRE_SPTR)start_subject;          cb.subject          = (PCRE_SPTR)start_subject;
3063  #else  #elif defined COMPILE_PCRE16
3064          cb.subject          = (PCRE_SPTR16)start_subject;          cb.subject          = (PCRE_SPTR16)start_subject;
3065    #elif defined COMPILE_PCRE32
3066            cb.subject          = (PCRE_SPTR32)start_subject;
3067  #endif  #endif
3068          cb.subject_length   = (int)(end_subject - start_subject);          cb.subject_length   = (int)(end_subject - start_subject);
3069          cb.start_match      = (int)(current_subject - start_subject);          cb.start_match      = (int)(current_subject - start_subject);
# Line 2946  for (;;) Line 3106  for (;;)
3106    if (new_count <= 0)    if (new_count <= 0)
3107      {      {
3108      if (rlevel == 1 &&                               /* Top level, and */      if (rlevel == 1 &&                               /* Top level, and */
3109          could_continue &&                            /* Some could go on */          could_continue &&                            /* Some could go on, and */
3110          forced_fail != workspace[1] &&               /* Not all forced fail & */          forced_fail != workspace[1] &&               /* Not all forced fail & */
3111          (                                            /* either... */          (                                            /* either... */
3112          (md->moptions & PCRE_PARTIAL_HARD) != 0      /* Hard partial */          (md->moptions & PCRE_PARTIAL_HARD) != 0      /* Hard partial */
# Line 2954  for (;;) Line 3114  for (;;)
3114          ((md->moptions & PCRE_PARTIAL_SOFT) != 0 &&  /* Soft partial and */          ((md->moptions & PCRE_PARTIAL_SOFT) != 0 &&  /* Soft partial and */
3115           match_count < 0)                            /* no matches */           match_count < 0)                            /* no matches */
3116          ) &&                                         /* And... */          ) &&                                         /* And... */
3117          ptr >= end_subject &&                  /* Reached end of subject */          (
3118          ptr > md->start_used_ptr)              /* Inspected non-empty string */          partial_newline ||                           /* Either partial NL */
3119        {            (                                          /* or ... */
3120        if (offsetcount >= 2)            ptr >= end_subject &&                /* End of subject and */
3121          {            ptr > md->start_used_ptr)            /* Inspected non-empty string */
3122          offsets[0] = (int)(md->start_used_ptr - start_subject);            )
3123          offsets[1] = (int)(end_subject - start_subject);          )
}
3124        match_count = PCRE_ERROR_PARTIAL;        match_count = PCRE_ERROR_PARTIAL;
}

3125      DPRINTF(("%.*sEnd of internal_dfa_exec %d: returning %d\n"      DPRINTF(("%.*sEnd of internal_dfa_exec %d: returning %d\n"
3126        "%.*s---------------------\n\n", rlevel*2-2, SP, rlevel, match_count,        "%.*s---------------------\n\n", rlevel*2-2, SP, rlevel, match_count,
3127        rlevel*2-2, SP));        rlevel*2-2, SP));
# Line 3014  Returns:          > 0 => number of match Line 3171  Returns:          > 0 => number of match
3171                   < -1 => some kind of unexpected problem                   < -1 => some kind of unexpected problem
3172  */  */
3173
3174  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
3175  PCRE_EXP_DEFN int PCRE_CALL_CONVENTION  PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
3176  pcre_dfa_exec(const pcre *argument_re, const pcre_extra *extra_data,  pcre_dfa_exec(const pcre *argument_re, const pcre_extra *extra_data,
3177    const char *subject, int length, int start_offset, int options, int *offsets,    const char *subject, int length, int start_offset, int options, int *offsets,
3178    int offsetcount, int *workspace, int wscount)    int offsetcount, int *workspace, int wscount)
3179  #else  #elif defined COMPILE_PCRE16
3180  PCRE_EXP_DEFN int PCRE_CALL_CONVENTION  PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
3181  pcre16_dfa_exec(const pcre16 *argument_re, const pcre16_extra *extra_data,  pcre16_dfa_exec(const pcre16 *argument_re, const pcre16_extra *extra_data,
3182    PCRE_SPTR16 subject, int length, int start_offset, int options, int *offsets,    PCRE_SPTR16 subject, int length, int start_offset, int options, int *offsets,
3183    int offsetcount, int *workspace, int wscount)    int offsetcount, int *workspace, int wscount)
3184    #elif defined COMPILE_PCRE32
3185    PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
3186    pcre32_dfa_exec(const pcre32 *argument_re, const pcre32_extra *extra_data,
3187      PCRE_SPTR32 subject, int length, int start_offset, int options, int *offsets,
3188      int offsetcount, int *workspace, int wscount)
3189  #endif  #endif
3190  {  {
3191  REAL_PCRE *re = (REAL_PCRE *)argument_re;  REAL_PCRE *re = (REAL_PCRE *)argument_re;
# Line 3031  dfa_match_data match_block; Line 3193  dfa_match_data match_block;
3193  dfa_match_data *md = &match_block;  dfa_match_data *md = &match_block;
3194  BOOL utf, anchored, startline, firstline;  BOOL utf, anchored, startline, firstline;
3195  const pcre_uchar *current_subject, *end_subject;  const pcre_uchar *current_subject, *end_subject;
const pcre_uint8 *lcc;

3196  const pcre_study_data *study = NULL;  const pcre_study_data *study = NULL;
3197
3198  const pcre_uchar *req_char_ptr;  const pcre_uchar *req_char_ptr;
# Line 3052  if (re == NULL || subject == NULL || wor Line 3212  if (re == NULL || subject == NULL || wor
3212     (offsets == NULL && offsetcount > 0)) return PCRE_ERROR_NULL;     (offsets == NULL && offsetcount > 0)) return PCRE_ERROR_NULL;
3213  if (offsetcount < 0) return PCRE_ERROR_BADCOUNT;  if (offsetcount < 0) return PCRE_ERROR_BADCOUNT;
3214  if (wscount < 20) return PCRE_ERROR_DFA_WSSIZE;  if (wscount < 20) return PCRE_ERROR_DFA_WSSIZE;
3215    if (length < 0) return PCRE_ERROR_BADLENGTH;
3216  if (start_offset < 0 || start_offset > length) return PCRE_ERROR_BADOFFSET;  if (start_offset < 0 || start_offset > length) return PCRE_ERROR_BADOFFSET;
3217
3218  /* We need to find the pointer to any study data before we test for byte  /* Check that the first field in the block is the magic number. If it is not,
3219  flipping, so we scan the extra_data block first. This may set two fields in the  return with PCRE_ERROR_BADMAGIC. However, if the magic number is equal to
3220  match block, so we must initialize them beforehand. However, the other fields  REVERSED_MAGIC_NUMBER we return with PCRE_ERROR_BADENDIANNESS, which
3221  in the match block must not be set until after the byte flipping. */  means that the pattern is likely compiled with different endianness. */
3222
3223    if (re->magic_number != MAGIC_NUMBER)
3224      return re->magic_number == REVERSED_MAGIC_NUMBER?
3226    if ((re->flags & PCRE_MODE) == 0) return PCRE_ERROR_BADMODE;
3227
3228    /* If restarting after a partial match, do some sanity checks on the contents
3229    of the workspace. */
3230
3231    if ((options & PCRE_DFA_RESTART) != 0)
3232      {
3233      if ((workspace[0] & (-2)) != 0 || workspace[1] < 1 ||
3234        workspace[1] > (wscount - 2)/INTS_PER_STATEBLOCK)
3236      }
3237
3238    /* Set up study, callout, and table data */
3239
3240  md->tables = re->tables;  md->tables = re->tables;
3241  md->callout_data = NULL;  md->callout_data = NULL;
# Line 3076  if (extra_data != NULL) Line 3254  if (extra_data != NULL)
3254      md->tables = extra_data->tables;      md->tables = extra_data->tables;
3255    }    }
3256
/* Check that the first field in the block is the magic number. If it is not,
return with PCRE_ERROR_BADMAGIC. However, if the magic number is equal to
REVERSED_MAGIC_NUMBER we return with PCRE_ERROR_BADENDIANNESS, which
means that the pattern is likely compiled with different endianness. */

if (re->magic_number != MAGIC_NUMBER)
return re->magic_number == REVERSED_MAGIC_NUMBER?
if ((re->flags & PCRE_MODE) == 0) return PCRE_ERROR_BADMODE;

3257  /* Set some local values */  /* Set some local values */
3258
3259  current_subject = (const pcre_uchar *)subject + start_offset;  current_subject = (const pcre_uchar *)subject + start_offset;
# Line 3093  end_subject = (const pcre_uchar *)subjec Line 3261  end_subject = (const pcre_uchar *)subjec
3261  req_char_ptr = current_subject - 1;  req_char_ptr = current_subject - 1;
3262
3263  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
3264  /* PCRE_UTF16 has the same value as PCRE_UTF8. */  /* PCRE_UTF(16|32) have the same value as PCRE_UTF8. */
3265  utf = (re->options & PCRE_UTF8) != 0;  utf = (re->options & PCRE_UTF8) != 0;
3266  #else  #else
3267  utf = FALSE;  utf = FALSE;
# Line 3179  if (utf && (options & PCRE_NO_UTF8_CHECK Line 3347  if (utf && (options & PCRE_NO_UTF8_CHECK
3347        offsets[0] = erroroffset;        offsets[0] = erroroffset;
3348        offsets[1] = errorcode;        offsets[1] = errorcode;
3349        }        }
3350      return (errorcode <= PCRE_UTF8_ERR5 && (options & PCRE_PARTIAL_HARD) != 0)?  #if defined COMPILE_PCRE8
3351        return (errorcode <= PCRE_UTF8_ERR5 && (options & PCRE_PARTIAL_HARD) != 0) ?
3353    #elif defined COMPILE_PCRE16
3354        return (errorcode <= PCRE_UTF16_ERR1 && (options & PCRE_PARTIAL_HARD) != 0) ?
3356    #elif defined COMPILE_PCRE32
3358    #endif
3359      }      }
3360    #if defined COMPILE_PCRE8 || defined COMPILE_PCRE16
3361    if (start_offset > 0 && start_offset < length &&    if (start_offset > 0 && start_offset < length &&
3362          NOT_FIRSTCHAR(((PCRE_PUCHAR)subject)[start_offset]))          NOT_FIRSTCHAR(((PCRE_PUCHAR)subject)[start_offset]))
3364    #endif
3365    }    }
3366  #endif  #endif
3367
# Line 3194  in other programs later. */ Line 3371  in other programs later. */
3371
3372  if (md->tables == NULL) md->tables = PRIV(default_tables);  if (md->tables == NULL) md->tables = PRIV(default_tables);
3373
3374  /* The lower casing table and the "must be at the start of a line" flag are  /* The "must be at the start of a line" flags are used in a loop when finding
3375  used in a loop when finding where to start. */  where to start. */
3376
lcc = md->tables + lcc_offset;
3377  startline = (re->flags & PCRE_STARTLINE) != 0;  startline = (re->flags & PCRE_STARTLINE) != 0;
3378  firstline = (re->options & PCRE_FIRSTLINE) != 0;  firstline = (re->options & PCRE_FIRSTLINE) != 0;
3379
# Line 3212  if (!anchored) Line 3388  if (!anchored)
3388    if ((re->flags & PCRE_FIRSTSET) != 0)    if ((re->flags & PCRE_FIRSTSET) != 0)
3389      {      {
3390      has_first_char = TRUE;      has_first_char = TRUE;
3391      first_char = first_char2 = re->first_char;      first_char = first_char2 = (pcre_uchar)(re->first_char);
3392      if ((re->flags & PCRE_FCH_CASELESS) != 0)      if ((re->flags & PCRE_FCH_CASELESS) != 0)
3393        {        {
3394        first_char2 = TABLE_GET(first_char, md->tables + fcc_offset, first_char);        first_char2 = TABLE_GET(first_char, md->tables + fcc_offset, first_char);
# Line 3236  character" set. */ Line 3412  character" set. */
3412  if ((re->flags & PCRE_REQCHSET) != 0)  if ((re->flags & PCRE_REQCHSET) != 0)
3413    {    {
3414    has_req_char = TRUE;    has_req_char = TRUE;
3415    req_char = req_char2 = re->req_char;    req_char = req_char2 = (pcre_uchar)(re->req_char);
3416    if ((re->flags & PCRE_RCH_CASELESS) != 0)    if ((re->flags & PCRE_RCH_CASELESS) != 0)
3417      {      {
3418      req_char2 = TABLE_GET(req_char, md->tables + fcc_offset, req_char);      req_char2 = TABLE_GET(req_char, md->tables + fcc_offset, req_char);
# Line 3295  for (;;) Line 3471  for (;;)
3471        if (has_first_char)        if (has_first_char)
3472          {          {
3473          if (first_char != first_char2)          if (first_char != first_char2)
3474              {
3475              pcre_uchar csc;
3476            while (current_subject < end_subject &&            while (current_subject < end_subject &&
3477                *current_subject != first_char && *current_subject != first_char2)                   (csc = *current_subject) != first_char && csc != first_char2)
3478              current_subject++;              current_subject++;
3479              }
3480          else          else
3481            while (current_subject < end_subject &&            while (current_subject < end_subject &&
3482                   *current_subject != first_char)                   *current_subject != first_char)
# Line 3332  for (;;) Line 3511  for (;;)
3511
3512            if (current_subject[-1] == CHAR_CR &&            if (current_subject[-1] == CHAR_CR &&
3513                 (md->nltype == NLTYPE_ANY || md->nltype == NLTYPE_ANYCRLF) &&                 (md->nltype == NLTYPE_ANY || md->nltype == NLTYPE_ANYCRLF) &&
3514                 current_subject < end_subject &&                 current_subject < end_subject && *current_subject == CHAR_NL)
*current_subject == CHAR_NL)
3515              current_subject++;              current_subject++;
3516            }            }
3517          }          }
# Line 3344  for (;;) Line 3522  for (;;)
3522          {          {
3523          while (current_subject < end_subject)          while (current_subject < end_subject)
3524            {            {
3525            register unsigned int c = *current_subject;            register pcre_uint32 c = *current_subject;
3526  #ifndef COMPILE_PCRE8  #ifndef COMPILE_PCRE8
3527            if (c > 255) c = 255;            if (c > 255) c = 255;
3528  #endif  #endif
# Line 3410  for (;;) Line 3588  for (;;)
3588              {              {
3589              while (p < end_subject)              while (p < end_subject)
3590                {                {
3591                register int pp = *p++;                register pcre_uint32 pp = *p++;
3592                if (pp == req_char || pp == req_char2) { p--; break; }                if (pp == req_char || pp == req_char2) { p--; break; }
3593                }                }
3594              }              }
# Line 3456  for (;;) Line 3634  for (;;)
3634    /* Anything other than "no match" means we are done, always; otherwise, carry    /* Anything other than "no match" means we are done, always; otherwise, carry
3635    on only if not anchored. */    on only if not anchored. */
3636
3637    if (rc != PCRE_ERROR_NOMATCH || anchored) return rc;    if (rc != PCRE_ERROR_NOMATCH || anchored)
3638        {
3639        if (rc == PCRE_ERROR_PARTIAL && offsetcount >= 2)
3640          {
3641          offsets[0] = (int)(md->start_used_ptr - (PCRE_PUCHAR)subject);
3642          offsets[1] = (int)(end_subject - (PCRE_PUCHAR)subject);
3643          if (offsetcount > 2)
3644            offsets[2] = (int)(current_subject - (PCRE_PUCHAR)subject);
3645          }
3646        return rc;
3647        }
3648
3649    /* Advance to the next subject character unless we are at the end of a line    /* Advance to the next subject character unless we are at the end of a line
3650    and firstline is set. */    and firstline is set. */

Legend:
 Removed from v.852 changed lines Added in v.1425