/[pcre]/code/trunk/pcre_exec.c
ViewVC logotype

Diff of /code/trunk/pcre_exec.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 788 by ph10, Tue Dec 6 15:38:01 2011 UTC revision 892 by ph10, Wed Jan 18 17:23:20 2012 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-2011 University of Cambridge             Copyright (c) 1997-2012 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 113  Returns:     nothing Line 113  Returns:     nothing
113  */  */
114    
115  static void  static void
116  pchars(const uschar *p, int length, BOOL is_subject, match_data *md)  pchars(const pcre_uchar *p, int length, BOOL is_subject, match_data *md)
117  {  {
118  unsigned int c;  unsigned int c;
119  if (is_subject && length > md->end_subject - p) length = md->end_subject - p;  if (is_subject && length > md->end_subject - p) length = md->end_subject - p;
# Line 144  Returns:      < 0 if not matched, otherw Line 144  Returns:      < 0 if not matched, otherw
144  */  */
145    
146  static int  static int
147  match_ref(int offset, register USPTR eptr, int length, match_data *md,  match_ref(int offset, register PCRE_PUCHAR eptr, int length, match_data *md,
148    BOOL caseless)    BOOL caseless)
149  {  {
150  USPTR eptr_start = eptr;  PCRE_PUCHAR eptr_start = eptr;
151  register USPTR p = md->start_subject + md->offset_vector[offset];  register PCRE_PUCHAR p = md->start_subject + md->offset_vector[offset];
152    
153  #ifdef PCRE_DEBUG  #ifdef PCRE_DEBUG
154  if (eptr >= md->end_subject)  if (eptr >= md->end_subject)
# Line 173  ASCII characters. */ Line 173  ASCII characters. */
173    
174  if (caseless)  if (caseless)
175    {    {
176  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
177  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
178    if (md->utf8)    if (md->utf)
179      {      {
180      /* Match characters up to the end of the reference. NOTE: the number of      /* Match characters up to the end of the reference. NOTE: the number of
181      bytes matched may differ, because there are some characters whose upper and      bytes matched may differ, because there are some characters whose upper and
# Line 185  if (caseless) Line 185  if (caseless)
185      the latter. It is important, therefore, to check the length along the      the latter. It is important, therefore, to check the length along the
186      reference, not along the subject (earlier code did this wrong). */      reference, not along the subject (earlier code did this wrong). */
187    
188      USPTR endptr = p + length;      PCRE_PUCHAR endptr = p + length;
189      while (p < endptr)      while (p < endptr)
190        {        {
191        int c, d;        int c, d;
# Line 204  if (caseless) Line 204  if (caseless)
204      {      {
205      if (eptr + length > md->end_subject) return -1;      if (eptr + length > md->end_subject) return -1;
206      while (length-- > 0)      while (length-- > 0)
207        { if (md->lcc[*p++] != md->lcc[*eptr++]) return -1; }        {
208          if (TABLE_GET(*p, md->lcc, *p) != TABLE_GET(*eptr, md->lcc, *eptr)) return -1;
209          p++;
210          eptr++;
211          }
212      }      }
213    }    }
214    
# Line 307  argument of match(), which never changes Line 311  argument of match(), which never changes
311    
312  #define RMATCH(ra,rb,rc,rd,re,rw)\  #define RMATCH(ra,rb,rc,rd,re,rw)\
313    {\    {\
314    heapframe *newframe = (heapframe *)(pcre_stack_malloc)(sizeof(heapframe));\    heapframe *newframe = (heapframe *)(PUBL(stack_malloc))(sizeof(heapframe));\
315    if (newframe == NULL) RRETURN(PCRE_ERROR_NOMEMORY);\    if (newframe == NULL) RRETURN(PCRE_ERROR_NOMEMORY);\
316    frame->Xwhere = rw; \    frame->Xwhere = rw; \
317    newframe->Xeptr = ra;\    newframe->Xeptr = ra;\
# Line 328  argument of match(), which never changes Line 332  argument of match(), which never changes
332    {\    {\
333    heapframe *oldframe = frame;\    heapframe *oldframe = frame;\
334    frame = oldframe->Xprevframe;\    frame = oldframe->Xprevframe;\
335    (pcre_stack_free)(oldframe);\    if (oldframe != &frame_zero) (PUBL(stack_free))(oldframe);\
336    if (frame != NULL)\    if (frame != NULL)\
337      {\      {\
338      rrc = ra;\      rrc = ra;\
# Line 345  typedef struct heapframe { Line 349  typedef struct heapframe {
349    
350    /* Function arguments that may change */    /* Function arguments that may change */
351    
352    USPTR Xeptr;    PCRE_PUCHAR Xeptr;
353    const uschar *Xecode;    const pcre_uchar *Xecode;
354    USPTR Xmstart;    PCRE_PUCHAR Xmstart;
355    int Xoffset_top;    int Xoffset_top;
356    eptrblock *Xeptrb;    eptrblock *Xeptrb;
357    unsigned int Xrdepth;    unsigned int Xrdepth;
358    
359    /* Function local variables */    /* Function local variables */
360    
361    USPTR Xcallpat;    PCRE_PUCHAR Xcallpat;
362  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
363    USPTR Xcharptr;    PCRE_PUCHAR Xcharptr;
364  #endif  #endif
365    USPTR Xdata;    PCRE_PUCHAR Xdata;
366    USPTR Xnext;    PCRE_PUCHAR Xnext;
367    USPTR Xpp;    PCRE_PUCHAR Xpp;
368    USPTR Xprev;    PCRE_PUCHAR Xprev;
369    USPTR Xsaved_eptr;    PCRE_PUCHAR Xsaved_eptr;
370    
371    recursion_info Xnew_recursive;    recursion_info Xnew_recursive;
372    
# Line 375  typedef struct heapframe { Line 379  typedef struct heapframe {
379    int Xprop_value;    int Xprop_value;
380    int Xprop_fail_result;    int Xprop_fail_result;
381    int Xoclength;    int Xoclength;
382    uschar Xocchars[8];    pcre_uchar Xocchars[6];
383  #endif  #endif
384    
385    int Xcodelink;    int Xcodelink;
# Line 440  the subject. */ Line 444  the subject. */
444    
445    
446  /* Performance note: It might be tempting to extract commonly used fields from  /* Performance note: It might be tempting to extract commonly used fields from
447  the md structure (e.g. utf8, end_subject) into individual variables to improve  the md structure (e.g. utf, end_subject) into individual variables to improve
448  performance. Tests using gcc on a SPARC disproved this; in the first case, it  performance. Tests using gcc on a SPARC disproved this; in the first case, it
449  made performance worse.  made performance worse.
450    
# Line 463  Returns:       MATCH_MATCH if matched Line 467  Returns:       MATCH_MATCH if matched
467  */  */
468    
469  static int  static int
470  match(REGISTER USPTR eptr, REGISTER const uschar *ecode, USPTR mstart,  match(REGISTER PCRE_PUCHAR eptr, REGISTER const pcre_uchar *ecode,
471    int offset_top, match_data *md, eptrblock *eptrb, unsigned int rdepth)    PCRE_PUCHAR mstart, int offset_top, match_data *md, eptrblock *eptrb,
472      unsigned int rdepth)
473  {  {
474  /* These variables do not need to be preserved over recursion in this function,  /* These variables do not need to be preserved over recursion in this function,
475  so they can be ordinary variables in all cases. Mark some of them with  so they can be ordinary variables in all cases. Mark some of them with
# Line 473  so they can be ordinary variables in all Line 478  so they can be ordinary variables in all
478  register int  rrc;         /* Returns from recursive calls */  register int  rrc;         /* Returns from recursive calls */
479  register int  i;           /* Used for loops not involving calls to RMATCH() */  register int  i;           /* Used for loops not involving calls to RMATCH() */
480  register unsigned int c;   /* Character values not kept over RMATCH() calls */  register unsigned int c;   /* Character values not kept over RMATCH() calls */
481  register BOOL utf8;        /* Local copy of UTF-8 flag for speed */  register BOOL utf;         /* Local copy of UTF flag for speed */
482    
483  BOOL minimize, possessive; /* Quantifier options */  BOOL minimize, possessive; /* Quantifier options */
484  BOOL caseless;  BOOL caseless;
485  int condcode;  int condcode;
486    
487  /* When recursion is not being used, all "local" variables that have to be  /* When recursion is not being used, all "local" variables that have to be
488  preserved over calls to RMATCH() are part of a "frame" which is obtained from  preserved over calls to RMATCH() are part of a "frame". We set up the top-level
489  heap storage. Set up the top-level frame here; others are obtained from the  frame on the stack here; subsequent instantiations are obtained from the heap
490  heap whenever RMATCH() does a "recursion". See the macro definitions above. */  whenever RMATCH() does a "recursion". See the macro definitions above. Putting
491    the top-level on the stack rather than malloc-ing them all gives a performance
492    boost in many cases where there is not much "recursion". */
493    
494  #ifdef NO_RECURSE  #ifdef NO_RECURSE
495  heapframe *frame = (heapframe *)(pcre_stack_malloc)(sizeof(heapframe));  heapframe frame_zero;
496  if (frame == NULL) RRETURN(PCRE_ERROR_NOMEMORY);  heapframe *frame = &frame_zero;
497  frame->Xprevframe = NULL;            /* Marks the top level */  frame->Xprevframe = NULL;            /* Marks the top level */
498    
499  /* Copy in the original argument variables */  /* Copy in the original argument variables */
# Line 513  HEAP_RECURSE: Line 520  HEAP_RECURSE:
520    
521  /* Ditto for the local variables */  /* Ditto for the local variables */
522    
523  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
524  #define charptr            frame->Xcharptr  #define charptr            frame->Xcharptr
525  #endif  #endif
526  #define callpat            frame->Xcallpat  #define callpat            frame->Xcallpat
# Line 571  declarations can be cut out in a block. Line 578  declarations can be cut out in a block.
578  below are for variables that do not have to be preserved over a recursive call  below are for variables that do not have to be preserved over a recursive call
579  to RMATCH(). */  to RMATCH(). */
580    
581  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
582  const uschar *charptr;  const pcre_uchar *charptr;
583  #endif  #endif
584  const uschar *callpat;  const pcre_uchar *callpat;
585  const uschar *data;  const pcre_uchar *data;
586  const uschar *next;  const pcre_uchar *next;
587  USPTR         pp;  PCRE_PUCHAR       pp;
588  const uschar *prev;  const pcre_uchar *prev;
589  USPTR         saved_eptr;  PCRE_PUCHAR       saved_eptr;
590    
591  recursion_info new_recursive;  recursion_info new_recursive;
592    
# Line 592  int prop_type; Line 599  int prop_type;
599  int prop_value;  int prop_value;
600  int prop_fail_result;  int prop_fail_result;
601  int oclength;  int oclength;
602  uschar occhars[8];  pcre_uchar occhars[6];
603  #endif  #endif
604    
605  int codelink;  int codelink;
# Line 620  the alternative names that are used. */ Line 627  the alternative names that are used. */
627  #define code_offset   codelink  #define code_offset   codelink
628  #define condassert    condition  #define condassert    condition
629  #define matched_once  prev_is_word  #define matched_once  prev_is_word
630    #define foc           number
631    #define save_mark     data
632    
633  /* These statements are here to stop the compiler complaining about unitialized  /* These statements are here to stop the compiler complaining about unitialized
634  variables. */  variables. */
# Line 645  defined). However, RMATCH isn't like a f Line 654  defined). However, RMATCH isn't like a f
654  complicated macro. It has to be used in one particular way. This shouldn't,  complicated macro. It has to be used in one particular way. This shouldn't,
655  however, impact performance when true recursion is being used. */  however, impact performance when true recursion is being used. */
656    
657  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
658  utf8 = md->utf8;       /* Local copy of the flag */  utf = md->utf;       /* Local copy of the flag */
659  #else  #else
660  utf8 = FALSE;  utf = FALSE;
661  #endif  #endif
662    
663  /* First check that we haven't called match() too many times, or that we  /* First check that we haven't called match() too many times, or that we
# Line 689  for (;;) Line 698  for (;;)
698      case OP_MARK:      case OP_MARK:
699      md->nomatch_mark = ecode + 2;      md->nomatch_mark = ecode + 2;
700      md->mark = NULL;    /* In case previously set by assertion */      md->mark = NULL;    /* In case previously set by assertion */
701      RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode] + ecode[1], offset_top, md,      RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode] + ecode[1], offset_top, md,
702        eptrb, RM55);        eptrb, RM55);
703      if ((rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) &&      if ((rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) &&
704           md->mark == NULL) md->mark = ecode + 2;           md->mark == NULL) md->mark = ecode + 2;
# Line 702  for (;;) Line 711  for (;;)
711      unaltered. */      unaltered. */
712    
713      else if (rrc == MATCH_SKIP_ARG &&      else if (rrc == MATCH_SKIP_ARG &&
714          strcmp((char *)(ecode + 2), (char *)(md->start_match_ptr)) == 0)          STRCMP_UC_UC(ecode + 2, md->start_match_ptr) == 0)
715        {        {
716        md->start_match_ptr = eptr;        md->start_match_ptr = eptr;
717        RRETURN(MATCH_SKIP);        RRETURN(MATCH_SKIP);
# Line 715  for (;;) Line 724  for (;;)
724      /* COMMIT overrides PRUNE, SKIP, and THEN */      /* COMMIT overrides PRUNE, SKIP, and THEN */
725    
726      case OP_COMMIT:      case OP_COMMIT:
727      RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,      RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md,
728        eptrb, RM52);        eptrb, RM52);
729      if (rrc != MATCH_NOMATCH && rrc != MATCH_PRUNE &&      if (rrc != MATCH_NOMATCH && rrc != MATCH_PRUNE &&
730          rrc != MATCH_SKIP && rrc != MATCH_SKIP_ARG &&          rrc != MATCH_SKIP && rrc != MATCH_SKIP_ARG &&
# Line 726  for (;;) Line 735  for (;;)
735      /* PRUNE overrides THEN */      /* PRUNE overrides THEN */
736    
737      case OP_PRUNE:      case OP_PRUNE:
738      RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,      RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md,
739        eptrb, RM51);        eptrb, RM51);
740      if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);      if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);
741      RRETURN(MATCH_PRUNE);      RRETURN(MATCH_PRUNE);
# Line 734  for (;;) Line 743  for (;;)
743      case OP_PRUNE_ARG:      case OP_PRUNE_ARG:
744      md->nomatch_mark = ecode + 2;      md->nomatch_mark = ecode + 2;
745      md->mark = NULL;    /* In case previously set by assertion */      md->mark = NULL;    /* In case previously set by assertion */
746      RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode] + ecode[1], offset_top, md,      RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode] + ecode[1], offset_top, md,
747        eptrb, RM56);        eptrb, RM56);
748      if ((rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) &&      if ((rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) &&
749           md->mark == NULL) md->mark = ecode + 2;           md->mark == NULL) md->mark = ecode + 2;
# Line 744  for (;;) Line 753  for (;;)
753      /* SKIP overrides PRUNE and THEN */      /* SKIP overrides PRUNE and THEN */
754    
755      case OP_SKIP:      case OP_SKIP:
756      RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,      RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md,
757        eptrb, RM53);        eptrb, RM53);
758      if (rrc != MATCH_NOMATCH && rrc != MATCH_PRUNE && rrc != MATCH_THEN)      if (rrc != MATCH_NOMATCH && rrc != MATCH_PRUNE && rrc != MATCH_THEN)
759        RRETURN(rrc);        RRETURN(rrc);
# Line 758  for (;;) Line 767  for (;;)
767      case OP_SKIP_ARG:      case OP_SKIP_ARG:
768      if (md->ignore_skip_arg)      if (md->ignore_skip_arg)
769        {        {
770        ecode += _pcre_OP_lengths[*ecode] + ecode[1];        ecode += PRIV(OP_lengths)[*ecode] + ecode[1];
771        break;        break;
772        }        }
773      RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode] + ecode[1], offset_top, md,      RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode] + ecode[1], offset_top, md,
774        eptrb, RM57);        eptrb, RM57);
775      if (rrc != MATCH_NOMATCH && rrc != MATCH_PRUNE && rrc != MATCH_THEN)      if (rrc != MATCH_NOMATCH && rrc != MATCH_PRUNE && rrc != MATCH_THEN)
776        RRETURN(rrc);        RRETURN(rrc);
# Line 779  for (;;) Line 788  for (;;)
788      match pointer to do this. */      match pointer to do this. */
789    
790      case OP_THEN:      case OP_THEN:
791      RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,      RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md,
792        eptrb, RM54);        eptrb, RM54);
793      if (rrc != MATCH_NOMATCH) RRETURN(rrc);      if (rrc != MATCH_NOMATCH) RRETURN(rrc);
794      md->start_match_ptr = ecode;      md->start_match_ptr = ecode;
# Line 788  for (;;) Line 797  for (;;)
797      case OP_THEN_ARG:      case OP_THEN_ARG:
798      md->nomatch_mark = ecode + 2;      md->nomatch_mark = ecode + 2;
799      md->mark = NULL;    /* In case previously set by assertion */      md->mark = NULL;    /* In case previously set by assertion */
800      RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode] + ecode[1], offset_top,      RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode] + ecode[1], offset_top,
801        md, eptrb, RM58);        md, eptrb, RM58);
802      if ((rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) &&      if ((rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) &&
803           md->mark == NULL) md->mark = ecode + 2;           md->mark == NULL) md->mark = ecode + 2;
# Line 812  for (;;) Line 821  for (;;)
821      case OP_ONCE_NC:      case OP_ONCE_NC:
822      prev = ecode;      prev = ecode;
823      saved_eptr = eptr;      saved_eptr = eptr;
824        save_mark = md->mark;
825      do      do
826        {        {
827        RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, eptrb, RM64);        RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, eptrb, RM64);
# Line 830  for (;;) Line 840  for (;;)
840    
841        if (rrc != MATCH_NOMATCH) RRETURN(rrc);        if (rrc != MATCH_NOMATCH) RRETURN(rrc);
842        ecode += GET(ecode,1);        ecode += GET(ecode,1);
843          md->mark = save_mark;
844        }        }
845      while (*ecode == OP_ALT);      while (*ecode == OP_ALT);
846    
# Line 909  for (;;) Line 920  for (;;)
920        save_offset2 = md->offset_vector[offset+1];        save_offset2 = md->offset_vector[offset+1];
921        save_offset3 = md->offset_vector[md->offset_end - number];        save_offset3 = md->offset_vector[md->offset_end - number];
922        save_capture_last = md->capture_last;        save_capture_last = md->capture_last;
923          save_mark = md->mark;
924    
925        DPRINTF(("saving %d %d %d\n", save_offset1, save_offset2, save_offset3));        DPRINTF(("saving %d %d %d\n", save_offset1, save_offset2, save_offset3));
926        md->offset_vector[md->offset_end - number] =        md->offset_vector[md->offset_end - number] =
# Line 917  for (;;) Line 929  for (;;)
929        for (;;)        for (;;)
930          {          {
931          if (op >= OP_SBRA) md->match_function_type = MATCH_CBEGROUP;          if (op >= OP_SBRA) md->match_function_type = MATCH_CBEGROUP;
932          RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,          RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md,
933            eptrb, RM1);            eptrb, RM1);
934          if (rrc == MATCH_ONCE) break;  /* Backing up through an atomic group */          if (rrc == MATCH_ONCE) break;  /* Backing up through an atomic group */
935    
# Line 945  for (;;) Line 957  for (;;)
957          if (rrc != MATCH_NOMATCH) RRETURN(rrc);          if (rrc != MATCH_NOMATCH) RRETURN(rrc);
958          md->capture_last = save_capture_last;          md->capture_last = save_capture_last;
959          ecode += GET(ecode, 1);          ecode += GET(ecode, 1);
960            md->mark = save_mark;
961          if (*ecode != OP_ALT) break;          if (*ecode != OP_ALT) break;
962          }          }
963    
# Line 1004  for (;;) Line 1017  for (;;)
1017    
1018        else if (!md->hasthen && ecode[GET(ecode, 1)] != OP_ALT)        else if (!md->hasthen && ecode[GET(ecode, 1)] != OP_ALT)
1019          {          {
1020          ecode += _pcre_OP_lengths[*ecode];          ecode += PRIV(OP_lengths)[*ecode];
1021          goto TAIL_RECURSE;          goto TAIL_RECURSE;
1022          }          }
1023    
1024        /* In all other cases, we have to make another call to match(). */        /* In all other cases, we have to make another call to match(). */
1025    
1026        RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md, eptrb,        save_mark = md->mark;
1027          RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md, eptrb,
1028          RM2);          RM2);
1029    
1030        /* See comment in the code for capturing groups above about handling        /* See comment in the code for capturing groups above about handling
1031        THEN. */        THEN. */
1032    
# Line 1028  for (;;) Line 1042  for (;;)
1042          {          {
1043          if (rrc == MATCH_ONCE)          if (rrc == MATCH_ONCE)
1044            {            {
1045            const uschar *scode = ecode;            const pcre_uchar *scode = ecode;
1046            if (*scode != OP_ONCE)           /* If not at start, find it */            if (*scode != OP_ONCE)           /* If not at start, find it */
1047              {              {
1048              while (*scode == OP_ALT) scode += GET(scode, 1);              while (*scode == OP_ALT) scode += GET(scode, 1);
# Line 1039  for (;;) Line 1053  for (;;)
1053          RRETURN(rrc);          RRETURN(rrc);
1054          }          }
1055        ecode += GET(ecode, 1);        ecode += GET(ecode, 1);
1056          md->mark = save_mark;
1057        if (*ecode != OP_ALT) break;        if (*ecode != OP_ALT) break;
1058        }        }
1059    
# Line 1093  for (;;) Line 1108  for (;;)
1108          md->offset_vector[md->offset_end - number] =          md->offset_vector[md->offset_end - number] =
1109            (int)(eptr - md->start_subject);            (int)(eptr - md->start_subject);
1110          if (op >= OP_SBRA) md->match_function_type = MATCH_CBEGROUP;          if (op >= OP_SBRA) md->match_function_type = MATCH_CBEGROUP;
1111          RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,          RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md,
1112            eptrb, RM63);            eptrb, RM63);
1113          if (rrc == MATCH_KETRPOS)          if (rrc == MATCH_KETRPOS)
1114            {            {
# Line 1165  for (;;) Line 1180  for (;;)
1180      for (;;)      for (;;)
1181        {        {
1182        if (op >= OP_SBRA) md->match_function_type = MATCH_CBEGROUP;        if (op >= OP_SBRA) md->match_function_type = MATCH_CBEGROUP;
1183        RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,        RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md,
1184          eptrb, RM48);          eptrb, RM48);
1185        if (rrc == MATCH_KETRPOS)        if (rrc == MATCH_KETRPOS)
1186          {          {
# Line 1215  for (;;) Line 1230  for (;;)
1230    
1231      if (ecode[LINK_SIZE+1] == OP_CALLOUT)      if (ecode[LINK_SIZE+1] == OP_CALLOUT)
1232        {        {
1233        if (pcre_callout != NULL)        if (PUBL(callout) != NULL)
1234          {          {
1235          pcre_callout_block cb;          PUBL(callout_block) cb;
1236          cb.version          = 2;   /* Version 1 of the callout block */          cb.version          = 2;   /* Version 1 of the callout block */
1237          cb.callout_number   = ecode[LINK_SIZE+2];          cb.callout_number   = ecode[LINK_SIZE+2];
1238          cb.offset_vector    = md->offset_vector;          cb.offset_vector    = md->offset_vector;
1239    #ifdef COMPILE_PCRE8
1240          cb.subject          = (PCRE_SPTR)md->start_subject;          cb.subject          = (PCRE_SPTR)md->start_subject;
1241    #else
1242            cb.subject          = (PCRE_SPTR16)md->start_subject;
1243    #endif
1244          cb.subject_length   = (int)(md->end_subject - md->start_subject);          cb.subject_length   = (int)(md->end_subject - md->start_subject);
1245          cb.start_match      = (int)(mstart - md->start_subject);          cb.start_match      = (int)(mstart - md->start_subject);
1246          cb.current_position = (int)(eptr - md->start_subject);          cb.current_position = (int)(eptr - md->start_subject);
# Line 1231  for (;;) Line 1250  for (;;)
1250          cb.capture_last     = md->capture_last;          cb.capture_last     = md->capture_last;
1251          cb.callout_data     = md->callout_data;          cb.callout_data     = md->callout_data;
1252          cb.mark             = md->nomatch_mark;          cb.mark             = md->nomatch_mark;
1253          if ((rrc = (*pcre_callout)(&cb)) > 0) RRETURN(MATCH_NOMATCH);          if ((rrc = (*PUBL(callout))(&cb)) > 0) RRETURN(MATCH_NOMATCH);
1254          if (rrc < 0) RRETURN(rrc);          if (rrc < 0) RRETURN(rrc);
1255          }          }
1256        ecode += _pcre_OP_lengths[OP_CALLOUT];        ecode += PRIV(OP_lengths)[OP_CALLOUT];
1257        }        }
1258    
1259      condcode = ecode[LINK_SIZE+1];      condcode = ecode[LINK_SIZE+1];
# Line 1260  for (;;) Line 1279  for (;;)
1279    
1280          if (!condition && condcode == OP_NRREF)          if (!condition && condcode == OP_NRREF)
1281            {            {
1282            uschar *slotA = md->name_table;            pcre_uchar *slotA = md->name_table;
1283            for (i = 0; i < md->name_count; i++)            for (i = 0; i < md->name_count; i++)
1284              {              {
1285              if (GET2(slotA, 0) == recno) break;              if (GET2(slotA, 0) == recno) break;
# Line 1273  for (;;) Line 1292  for (;;)
1292    
1293            if (i < md->name_count)            if (i < md->name_count)
1294              {              {
1295              uschar *slotB = slotA;              pcre_uchar *slotB = slotA;
1296              while (slotB > md->name_table)              while (slotB > md->name_table)
1297                {                {
1298                slotB -= md->name_entry_size;                slotB -= md->name_entry_size;
1299                if (strcmp((char *)slotA + 2, (char *)slotB + 2) == 0)                if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
1300                  {                  {
1301                  condition = GET2(slotB, 0) == md->recursive->group_num;                  condition = GET2(slotB, 0) == md->recursive->group_num;
1302                  if (condition) break;                  if (condition) break;
# Line 1293  for (;;) Line 1312  for (;;)
1312                for (i++; i < md->name_count; i++)                for (i++; i < md->name_count; i++)
1313                  {                  {
1314                  slotB += md->name_entry_size;                  slotB += md->name_entry_size;
1315                  if (strcmp((char *)slotA + 2, (char *)slotB + 2) == 0)                  if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
1316                    {                    {
1317                    condition = GET2(slotB, 0) == md->recursive->group_num;                    condition = GET2(slotB, 0) == md->recursive->group_num;
1318                    if (condition) break;                    if (condition) break;
# Line 1306  for (;;) Line 1325  for (;;)
1325    
1326          /* Chose branch according to the condition */          /* Chose branch according to the condition */
1327    
1328          ecode += condition? 3 : GET(ecode, 1);          ecode += condition? 1 + IMM2_SIZE : GET(ecode, 1);
1329          }          }
1330        }        }
1331    
# Line 1323  for (;;) Line 1342  for (;;)
1342        if (!condition && condcode == OP_NCREF)        if (!condition && condcode == OP_NCREF)
1343          {          {
1344          int refno = offset >> 1;          int refno = offset >> 1;
1345          uschar *slotA = md->name_table;          pcre_uchar *slotA = md->name_table;
1346    
1347          for (i = 0; i < md->name_count; i++)          for (i = 0; i < md->name_count; i++)
1348            {            {
# Line 1337  for (;;) Line 1356  for (;;)
1356    
1357          if (i < md->name_count)          if (i < md->name_count)
1358            {            {
1359            uschar *slotB = slotA;            pcre_uchar *slotB = slotA;
1360            while (slotB > md->name_table)            while (slotB > md->name_table)
1361              {              {
1362              slotB -= md->name_entry_size;              slotB -= md->name_entry_size;
1363              if (strcmp((char *)slotA + 2, (char *)slotB + 2) == 0)              if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
1364                {                {
1365                offset = GET2(slotB, 0) << 1;                offset = GET2(slotB, 0) << 1;
1366                condition = offset < offset_top &&                condition = offset < offset_top &&
# Line 1359  for (;;) Line 1378  for (;;)
1378              for (i++; i < md->name_count; i++)              for (i++; i < md->name_count; i++)
1379                {                {
1380                slotB += md->name_entry_size;                slotB += md->name_entry_size;
1381                if (strcmp((char *)slotA + 2, (char *)slotB + 2) == 0)                if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
1382                  {                  {
1383                  offset = GET2(slotB, 0) << 1;                  offset = GET2(slotB, 0) << 1;
1384                  condition = offset < offset_top &&                  condition = offset < offset_top &&
# Line 1374  for (;;) Line 1393  for (;;)
1393    
1394        /* Chose branch according to the condition */        /* Chose branch according to the condition */
1395    
1396        ecode += condition? 3 : GET(ecode, 1);        ecode += condition? 1 + IMM2_SIZE : GET(ecode, 1);
1397        }        }
1398    
1399      else if (condcode == OP_DEF)     /* DEFINE - always false */      else if (condcode == OP_DEF)     /* DEFINE - always false */
# Line 1466  for (;;) Line 1485  for (;;)
1485        md->offset_vector[offset+1] = (int)(eptr - md->start_subject);        md->offset_vector[offset+1] = (int)(eptr - md->start_subject);
1486        if (offset_top <= offset) offset_top = offset + 2;        if (offset_top <= offset) offset_top = offset + 2;
1487        }        }
1488      ecode += 3;      ecode += 1 + IMM2_SIZE;
1489      break;      break;
1490    
1491    
# Line 1513  for (;;) Line 1532  for (;;)
1532    
1533      case OP_ASSERT:      case OP_ASSERT:
1534      case OP_ASSERTBACK:      case OP_ASSERTBACK:
1535        save_mark = md->mark;
1536      if (md->match_function_type == MATCH_CONDASSERT)      if (md->match_function_type == MATCH_CONDASSERT)
1537        {        {
1538        condassert = TRUE;        condassert = TRUE;
# Line 1534  for (;;) Line 1554  for (;;)
1554    
1555        if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);        if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);
1556        ecode += GET(ecode, 1);        ecode += GET(ecode, 1);
1557          md->mark = save_mark;
1558        }        }
1559      while (*ecode == OP_ALT);      while (*ecode == OP_ALT);
1560    
# Line 1557  for (;;) Line 1578  for (;;)
1578    
1579      case OP_ASSERT_NOT:      case OP_ASSERT_NOT:
1580      case OP_ASSERTBACK_NOT:      case OP_ASSERTBACK_NOT:
1581        save_mark = md->mark;
1582      if (md->match_function_type == MATCH_CONDASSERT)      if (md->match_function_type == MATCH_CONDASSERT)
1583        {        {
1584        condassert = TRUE;        condassert = TRUE;
# Line 1567  for (;;) Line 1589  for (;;)
1589      do      do
1590        {        {
1591        RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, NULL, RM5);        RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, NULL, RM5);
1592          md->mark = save_mark;
1593        if (rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) RRETURN(MATCH_NOMATCH);        if (rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) RRETURN(MATCH_NOMATCH);
1594        if (rrc == MATCH_SKIP || rrc == MATCH_PRUNE || rrc == MATCH_COMMIT)        if (rrc == MATCH_SKIP || rrc == MATCH_PRUNE || rrc == MATCH_COMMIT)
1595          {          {
# Line 1593  for (;;) Line 1616  for (;;)
1616      back a number of characters, not bytes. */      back a number of characters, not bytes. */
1617    
1618      case OP_REVERSE:      case OP_REVERSE:
1619  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1620      if (utf8)      if (utf)
1621        {        {
1622        i = GET(ecode, 1);        i = GET(ecode, 1);
1623        while (i-- > 0)        while (i-- > 0)
# Line 1625  for (;;) Line 1648  for (;;)
1648      function is able to force a failure. */      function is able to force a failure. */
1649    
1650      case OP_CALLOUT:      case OP_CALLOUT:
1651      if (pcre_callout != NULL)      if (PUBL(callout) != NULL)
1652        {        {
1653        pcre_callout_block cb;        PUBL(callout_block) cb;
1654        cb.version          = 2;   /* Version 1 of the callout block */        cb.version          = 2;   /* Version 1 of the callout block */
1655        cb.callout_number   = ecode[1];        cb.callout_number   = ecode[1];
1656        cb.offset_vector    = md->offset_vector;        cb.offset_vector    = md->offset_vector;
1657    #ifdef COMPILE_PCRE8
1658        cb.subject          = (PCRE_SPTR)md->start_subject;        cb.subject          = (PCRE_SPTR)md->start_subject;
1659    #else
1660          cb.subject          = (PCRE_SPTR16)md->start_subject;
1661    #endif
1662        cb.subject_length   = (int)(md->end_subject - md->start_subject);        cb.subject_length   = (int)(md->end_subject - md->start_subject);
1663        cb.start_match      = (int)(mstart - md->start_subject);        cb.start_match      = (int)(mstart - md->start_subject);
1664        cb.current_position = (int)(eptr - md->start_subject);        cb.current_position = (int)(eptr - md->start_subject);
# Line 1641  for (;;) Line 1668  for (;;)
1668        cb.capture_last     = md->capture_last;        cb.capture_last     = md->capture_last;
1669        cb.callout_data     = md->callout_data;        cb.callout_data     = md->callout_data;
1670        cb.mark             = md->nomatch_mark;        cb.mark             = md->nomatch_mark;
1671        if ((rrc = (*pcre_callout)(&cb)) > 0) RRETURN(MATCH_NOMATCH);        if ((rrc = (*PUBL(callout))(&cb)) > 0) RRETURN(MATCH_NOMATCH);
1672        if (rrc < 0) RRETURN(rrc);        if (rrc < 0) RRETURN(rrc);
1673        }        }
1674      ecode += 2 + 2*LINK_SIZE;      ecode += 2 + 2*LINK_SIZE;
# Line 1700  for (;;) Line 1727  for (;;)
1727        else        else
1728          {          {
1729          new_recursive.offset_save =          new_recursive.offset_save =
1730            (int *)(pcre_malloc)(new_recursive.saved_max * sizeof(int));            (int *)(PUBL(malloc))(new_recursive.saved_max * sizeof(int));
1731          if (new_recursive.offset_save == NULL) RRETURN(PCRE_ERROR_NOMEMORY);          if (new_recursive.offset_save == NULL) RRETURN(PCRE_ERROR_NOMEMORY);
1732          }          }
1733        memcpy(new_recursive.offset_save, md->offset_vector,        memcpy(new_recursive.offset_save, md->offset_vector,
# Line 1715  for (;;) Line 1742  for (;;)
1742        do        do
1743          {          {
1744          if (cbegroup) md->match_function_type = MATCH_CBEGROUP;          if (cbegroup) md->match_function_type = MATCH_CBEGROUP;
1745          RMATCH(eptr, callpat + _pcre_OP_lengths[*callpat], offset_top,          RMATCH(eptr, callpat + PRIV(OP_lengths)[*callpat], offset_top,
1746            md, eptrb, RM6);            md, eptrb, RM6);
1747          memcpy(md->offset_vector, new_recursive.offset_save,          memcpy(md->offset_vector, new_recursive.offset_save,
1748              new_recursive.saved_max * sizeof(int));              new_recursive.saved_max * sizeof(int));
# Line 1724  for (;;) Line 1751  for (;;)
1751            {            {
1752            DPRINTF(("Recursion matched\n"));            DPRINTF(("Recursion matched\n"));
1753            if (new_recursive.offset_save != stacksave)            if (new_recursive.offset_save != stacksave)
1754              (pcre_free)(new_recursive.offset_save);              (PUBL(free))(new_recursive.offset_save);
1755    
1756            /* Set where we got to in the subject, and reset the start in case            /* Set where we got to in the subject, and reset the start in case
1757            it was changed by \K. This *is* propagated back out of a recursion,            it was changed by \K. This *is* propagated back out of a recursion,
# Line 1742  for (;;) Line 1769  for (;;)
1769            {            {
1770            DPRINTF(("Recursion gave error %d\n", rrc));            DPRINTF(("Recursion gave error %d\n", rrc));
1771            if (new_recursive.offset_save != stacksave)            if (new_recursive.offset_save != stacksave)
1772              (pcre_free)(new_recursive.offset_save);              (PUBL(free))(new_recursive.offset_save);
1773            RRETURN(rrc);            RRETURN(rrc);
1774            }            }
1775    
# Line 1754  for (;;) Line 1781  for (;;)
1781        DPRINTF(("Recursion didn't match\n"));        DPRINTF(("Recursion didn't match\n"));
1782        md->recursive = new_recursive.prevrec;        md->recursive = new_recursive.prevrec;
1783        if (new_recursive.offset_save != stacksave)        if (new_recursive.offset_save != stacksave)
1784          (pcre_free)(new_recursive.offset_save);          (PUBL(free))(new_recursive.offset_save);
1785        RRETURN(MATCH_NOMATCH);        RRETURN(MATCH_NOMATCH);
1786        }        }
1787    
# Line 2066  for (;;) Line 2093  for (;;)
2093        be "non-word" characters. Remember the earliest consulted character for        be "non-word" characters. Remember the earliest consulted character for
2094        partial matching. */        partial matching. */
2095    
2096  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2097        if (utf8)        if (utf)
2098          {          {
2099          /* Get status of previous character */          /* Get status of previous character */
2100    
2101          if (eptr == md->start_subject) prev_is_word = FALSE; else          if (eptr == md->start_subject) prev_is_word = FALSE; else
2102            {            {
2103            USPTR lastptr = eptr - 1;            PCRE_PUCHAR lastptr = eptr - 1;
2104            while((*lastptr & 0xc0) == 0x80) lastptr--;            BACKCHAR(lastptr);
2105            if (lastptr < md->start_used_ptr) md->start_used_ptr = lastptr;            if (lastptr < md->start_used_ptr) md->start_used_ptr = lastptr;
2106            GETCHAR(c, lastptr);            GETCHAR(c, lastptr);
2107  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
# Line 2139  for (;;) Line 2166  for (;;)
2166              }              }
2167            else            else
2168  #endif  #endif
2169            prev_is_word = ((md->ctypes[eptr[-1]] & ctype_word) != 0);            prev_is_word = MAX_255(eptr[-1])
2170                && ((md->ctypes[eptr[-1]] & ctype_word) != 0);
2171            }            }
2172    
2173          /* Get status of next character */          /* Get status of next character */
# Line 2162  for (;;) Line 2190  for (;;)
2190            }            }
2191          else          else
2192  #endif  #endif
2193          cur_is_word = ((md->ctypes[*eptr] & ctype_word) != 0);          cur_is_word = MAX_255(*eptr)
2194              && ((md->ctypes[*eptr] & ctype_word) != 0);
2195          }          }
2196    
2197        /* Now see if the situation is what we want */        /* Now see if the situation is what we want */
# Line 2186  for (;;) Line 2215  for (;;)
2215        RRETURN(MATCH_NOMATCH);        RRETURN(MATCH_NOMATCH);
2216        }        }
2217      eptr++;      eptr++;
2218      if (utf8) while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;  #ifdef SUPPORT_UTF
2219        if (utf) ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
2220    #endif
2221      ecode++;      ecode++;
2222      break;      break;
2223    
# Line 2211  for (;;) Line 2242  for (;;)
2242        }        }
2243      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
2244      if (      if (
2245  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || !(defined COMPILE_PCRE8)
2246         c < 256 &&         c < 256 &&
2247  #endif  #endif
2248         (md->ctypes[c] & ctype_digit) != 0         (md->ctypes[c] & ctype_digit) != 0
# Line 2228  for (;;) Line 2259  for (;;)
2259        }        }
2260      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
2261      if (      if (
2262  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || !(defined COMPILE_PCRE8)
2263         c >= 256 ||         c > 255 ||
2264  #endif  #endif
2265         (md->ctypes[c] & ctype_digit) == 0         (md->ctypes[c] & ctype_digit) == 0
2266         )         )
# Line 2245  for (;;) Line 2276  for (;;)
2276        }        }
2277      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
2278      if (      if (
2279  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || !(defined COMPILE_PCRE8)
2280         c < 256 &&         c < 256 &&
2281  #endif  #endif
2282         (md->ctypes[c] & ctype_space) != 0         (md->ctypes[c] & ctype_space) != 0
# Line 2262  for (;;) Line 2293  for (;;)
2293        }        }
2294      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
2295      if (      if (
2296  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || !(defined COMPILE_PCRE8)
2297         c >= 256 ||         c > 255 ||
2298  #endif  #endif
2299         (md->ctypes[c] & ctype_space) == 0         (md->ctypes[c] & ctype_space) == 0
2300         )         )
# Line 2279  for (;;) Line 2310  for (;;)
2310        }        }
2311      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
2312      if (      if (
2313  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || !(defined COMPILE_PCRE8)
2314         c < 256 &&         c < 256 &&
2315  #endif  #endif
2316         (md->ctypes[c] & ctype_word) != 0         (md->ctypes[c] & ctype_word) != 0
# Line 2296  for (;;) Line 2327  for (;;)
2327        }        }
2328      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
2329      if (      if (
2330  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || !(defined COMPILE_PCRE8)
2331         c >= 256 ||         c > 255 ||
2332  #endif  #endif
2333         (md->ctypes[c] & ctype_word) == 0         (md->ctypes[c] & ctype_word) == 0
2334         )         )
# Line 2475  for (;;) Line 2506  for (;;)
2506          break;          break;
2507    
2508          case PT_GC:          case PT_GC:
2509          if ((ecode[2] != _pcre_ucp_gentype[prop->chartype]) == (op == OP_PROP))          if ((ecode[2] != PRIV(ucp_gentype)[prop->chartype]) == (op == OP_PROP))
2510            RRETURN(MATCH_NOMATCH);            RRETURN(MATCH_NOMATCH);
2511          break;          break;
2512    
# Line 2492  for (;;) Line 2523  for (;;)
2523          /* These are specials */          /* These are specials */
2524    
2525          case PT_ALNUM:          case PT_ALNUM:
2526          if ((_pcre_ucp_gentype[prop->chartype] == ucp_L ||          if ((PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
2527               _pcre_ucp_gentype[prop->chartype] == ucp_N) == (op == OP_NOTPROP))               PRIV(ucp_gentype)[prop->chartype] == ucp_N) == (op == OP_NOTPROP))
2528            RRETURN(MATCH_NOMATCH);            RRETURN(MATCH_NOMATCH);
2529          break;          break;
2530    
2531          case PT_SPACE:    /* Perl space */          case PT_SPACE:    /* Perl space */
2532          if ((_pcre_ucp_gentype[prop->chartype] == ucp_Z ||          if ((PRIV(ucp_gentype)[prop->chartype] == ucp_Z ||
2533               c == CHAR_HT || c == CHAR_NL || c == CHAR_FF || c == CHAR_CR)               c == CHAR_HT || c == CHAR_NL || c == CHAR_FF || c == CHAR_CR)
2534                 == (op == OP_NOTPROP))                 == (op == OP_NOTPROP))
2535            RRETURN(MATCH_NOMATCH);            RRETURN(MATCH_NOMATCH);
2536          break;          break;
2537    
2538          case PT_PXSPACE:  /* POSIX space */          case PT_PXSPACE:  /* POSIX space */
2539          if ((_pcre_ucp_gentype[prop->chartype] == ucp_Z ||          if ((PRIV(ucp_gentype)[prop->chartype] == ucp_Z ||
2540               c == CHAR_HT || c == CHAR_NL || c == CHAR_VT ||               c == CHAR_HT || c == CHAR_NL || c == CHAR_VT ||
2541               c == CHAR_FF || c == CHAR_CR)               c == CHAR_FF || c == CHAR_CR)
2542                 == (op == OP_NOTPROP))                 == (op == OP_NOTPROP))
# Line 2513  for (;;) Line 2544  for (;;)
2544          break;          break;
2545    
2546          case PT_WORD:          case PT_WORD:
2547          if ((_pcre_ucp_gentype[prop->chartype] == ucp_L ||          if ((PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
2548               _pcre_ucp_gentype[prop->chartype] == ucp_N ||               PRIV(ucp_gentype)[prop->chartype] == ucp_N ||
2549               c == CHAR_UNDERSCORE) == (op == OP_NOTPROP))               c == CHAR_UNDERSCORE) == (op == OP_NOTPROP))
2550            RRETURN(MATCH_NOMATCH);            RRETURN(MATCH_NOMATCH);
2551          break;          break;
# Line 2543  for (;;) Line 2574  for (;;)
2574      while (eptr < md->end_subject)      while (eptr < md->end_subject)
2575        {        {
2576        int len = 1;        int len = 1;
2577        if (!utf8) c = *eptr; else { GETCHARLEN(c, eptr, len); }        if (!utf) c = *eptr; else { GETCHARLEN(c, eptr, len); }
2578        if (UCD_CATEGORY(c) != ucp_M) break;        if (UCD_CATEGORY(c) != ucp_M) break;
2579        eptr += len;        eptr += len;
2580        }        }
# Line 2564  for (;;) Line 2595  for (;;)
2595      case OP_REFI:      case OP_REFI:
2596      caseless = op == OP_REFI;      caseless = op == OP_REFI;
2597      offset = GET2(ecode, 1) << 1;               /* Doubled ref number */      offset = GET2(ecode, 1) << 1;               /* Doubled ref number */
2598      ecode += 3;      ecode += 1 + IMM2_SIZE;
2599    
2600      /* If the reference is unset, there are two possibilities:      /* If the reference is unset, there are two possibilities:
2601    
# Line 2604  for (;;) Line 2635  for (;;)
2635        case OP_CRMINRANGE:        case OP_CRMINRANGE:
2636        minimize = (*ecode == OP_CRMINRANGE);        minimize = (*ecode == OP_CRMINRANGE);
2637        min = GET2(ecode, 1);        min = GET2(ecode, 1);
2638        max = GET2(ecode, 3);        max = GET2(ecode, 1 + IMM2_SIZE);
2639        if (max == 0) max = INT_MAX;        if (max == 0) max = INT_MAX;
2640        ecode += 5;        ecode += 1 + 2 * IMM2_SIZE;
2641        break;        break;
2642    
2643        default:               /* No repeat follows */        default:               /* No repeat follows */
# Line 2620  for (;;) Line 2651  for (;;)
2651        }        }
2652    
2653      /* Handle repeated back references. If the length of the reference is      /* Handle repeated back references. If the length of the reference is
2654      zero, just continue with the main loop. */      zero, just continue with the main loop. If the length is negative, it
2655        means the reference is unset in non-Java-compatible mode. If the minimum is
2656        zero, we can continue at the same level without recursion. For any other
2657        minimum, carrying on will result in NOMATCH. */
2658    
2659      if (length == 0) continue;      if (length == 0) continue;
2660        if (length < 0 && min == 0) continue;
2661    
2662      /* First, ensure the minimum number of matches are present. We get back      /* First, ensure the minimum number of matches are present. We get back
2663      the length of the reference string explicitly rather than passing the      the length of the reference string explicitly rather than passing the
# Line 2703  for (;;) Line 2738  for (;;)
2738      case OP_NCLASS:      case OP_NCLASS:
2739      case OP_CLASS:      case OP_CLASS:
2740        {        {
2741          /* The data variable is saved across frames, so the byte map needs to
2742          be stored there. */
2743    #define BYTE_MAP ((pcre_uint8 *)data)
2744        data = ecode + 1;                /* Save for matching */        data = ecode + 1;                /* Save for matching */
2745        ecode += 33;                     /* Advance past the item */        ecode += 1 + (32 / sizeof(pcre_uchar)); /* Advance past the item */
2746    
2747        switch (*ecode)        switch (*ecode)
2748          {          {
# Line 2725  for (;;) Line 2763  for (;;)
2763          case OP_CRMINRANGE:          case OP_CRMINRANGE:
2764          minimize = (*ecode == OP_CRMINRANGE);          minimize = (*ecode == OP_CRMINRANGE);
2765          min = GET2(ecode, 1);          min = GET2(ecode, 1);
2766          max = GET2(ecode, 3);          max = GET2(ecode, 1 + IMM2_SIZE);
2767          if (max == 0) max = INT_MAX;          if (max == 0) max = INT_MAX;
2768          ecode += 5;          ecode += 1 + 2 * IMM2_SIZE;
2769          break;          break;
2770    
2771          default:               /* No repeat follows */          default:               /* No repeat follows */
# Line 2737  for (;;) Line 2775  for (;;)
2775    
2776        /* First, ensure the minimum number of matches are present. */        /* First, ensure the minimum number of matches are present. */
2777    
2778  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2779        /* UTF-8 mode */        if (utf)
       if (utf8)  
2780          {          {
2781          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
2782            {            {
# Line 2754  for (;;) Line 2791  for (;;)
2791              if (op == OP_CLASS) RRETURN(MATCH_NOMATCH);              if (op == OP_CLASS) RRETURN(MATCH_NOMATCH);
2792              }              }
2793            else            else
2794              {              if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);
             if ((data[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);  
             }  
2795            }            }
2796          }          }
2797        else        else
2798  #endif  #endif
2799        /* Not UTF-8 mode */        /* Not UTF mode */
2800          {          {
2801          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
2802            {            {
# Line 2771  for (;;) Line 2806  for (;;)
2806              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
2807              }              }
2808            c = *eptr++;            c = *eptr++;
2809            if ((data[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);  #ifndef COMPILE_PCRE8
2810              if (c > 255)
2811                {
2812                if (op == OP_CLASS) RRETURN(MATCH_NOMATCH);
2813                }
2814              else
2815    #endif
2816                if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);
2817            }            }
2818          }          }
2819    
# Line 2785  for (;;) Line 2827  for (;;)
2827    
2828        if (minimize)        if (minimize)
2829          {          {
2830  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2831          /* UTF-8 mode */          if (utf)
         if (utf8)  
2832            {            {
2833            for (fi = min;; fi++)            for (fi = min;; fi++)
2834              {              {
# Line 2805  for (;;) Line 2846  for (;;)
2846                if (op == OP_CLASS) RRETURN(MATCH_NOMATCH);                if (op == OP_CLASS) RRETURN(MATCH_NOMATCH);
2847                }                }
2848              else              else
2849                {                if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);
               if ((data[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);  
               }  
2850              }              }
2851            }            }
2852          else          else
2853  #endif  #endif
2854          /* Not UTF-8 mode */          /* Not UTF mode */
2855            {            {
2856            for (fi = min;; fi++)            for (fi = min;; fi++)
2857              {              {
# Line 2825  for (;;) Line 2864  for (;;)
2864                RRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
2865                }                }
2866              c = *eptr++;              c = *eptr++;
2867              if ((data[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);  #ifndef COMPILE_PCRE8
2868                if (c > 255)
2869                  {
2870                  if (op == OP_CLASS) RRETURN(MATCH_NOMATCH);
2871                  }
2872                else
2873    #endif
2874                  if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);
2875              }              }
2876            }            }
2877          /* Control never gets here */          /* Control never gets here */
# Line 2837  for (;;) Line 2883  for (;;)
2883          {          {
2884          pp = eptr;          pp = eptr;
2885    
2886  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2887          /* UTF-8 mode */          if (utf)
         if (utf8)  
2888            {            {
2889            for (i = min; i < max; i++)            for (i = min; i < max; i++)
2890              {              {
# Line 2855  for (;;) Line 2900  for (;;)
2900                if (op == OP_CLASS) break;                if (op == OP_CLASS) break;
2901                }                }
2902              else              else
2903                {                if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) break;
               if ((data[c/8] & (1 << (c&7))) == 0) break;  
               }  
2904              eptr += len;              eptr += len;
2905              }              }
2906            for (;;)            for (;;)
# Line 2870  for (;;) Line 2913  for (;;)
2913            }            }
2914          else          else
2915  #endif  #endif
2916            /* Not UTF-8 mode */            /* Not UTF mode */
2917            {            {
2918            for (i = min; i < max; i++)            for (i = min; i < max; i++)
2919              {              {
# Line 2880  for (;;) Line 2923  for (;;)
2923                break;                break;
2924                }                }
2925              c = *eptr;              c = *eptr;
2926              if ((data[c/8] & (1 << (c&7))) == 0) break;  #ifndef COMPILE_PCRE8
2927                if (c > 255)
2928                  {
2929                  if (op == OP_CLASS) break;
2930                  }
2931                else
2932    #endif
2933                  if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) break;
2934              eptr++;              eptr++;
2935              }              }
2936            while (eptr >= pp)            while (eptr >= pp)
# Line 2893  for (;;) Line 2943  for (;;)
2943    
2944          RRETURN(MATCH_NOMATCH);          RRETURN(MATCH_NOMATCH);
2945          }          }
2946    #undef BYTE_MAP
2947        }        }
2948      /* Control never gets here */      /* Control never gets here */
2949    
# Line 2901  for (;;) Line 2952  for (;;)
2952      when UTF-8 mode mode is supported. Nevertheless, we may not be in UTF-8      when UTF-8 mode mode is supported. Nevertheless, we may not be in UTF-8
2953      mode, because Unicode properties are supported in non-UTF-8 mode. */      mode, because Unicode properties are supported in non-UTF-8 mode. */
2954    
2955  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
2956      case OP_XCLASS:      case OP_XCLASS:
2957        {        {
2958        data = ecode + 1 + LINK_SIZE;                /* Save for matching */        data = ecode + 1 + LINK_SIZE;                /* Save for matching */
# Line 2926  for (;;) Line 2977  for (;;)
2977          case OP_CRMINRANGE:          case OP_CRMINRANGE:
2978          minimize = (*ecode == OP_CRMINRANGE);          minimize = (*ecode == OP_CRMINRANGE);
2979          min = GET2(ecode, 1);          min = GET2(ecode, 1);
2980          max = GET2(ecode, 3);          max = GET2(ecode, 1 + IMM2_SIZE);
2981          if (max == 0) max = INT_MAX;          if (max == 0) max = INT_MAX;
2982          ecode += 5;          ecode += 1 + 2 * IMM2_SIZE;
2983          break;          break;
2984    
2985          default:               /* No repeat follows */          default:               /* No repeat follows */
# Line 2946  for (;;) Line 2997  for (;;)
2997            RRETURN(MATCH_NOMATCH);            RRETURN(MATCH_NOMATCH);
2998            }            }
2999          GETCHARINCTEST(c, eptr);          GETCHARINCTEST(c, eptr);
3000          if (!_pcre_xclass(c, data)) RRETURN(MATCH_NOMATCH);          if (!PRIV(xclass)(c, data, utf)) RRETURN(MATCH_NOMATCH);
3001          }          }
3002    
3003        /* If max == min we can continue with the main loop without the        /* If max == min we can continue with the main loop without the
# Line 2970  for (;;) Line 3021  for (;;)
3021              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
3022              }              }
3023            GETCHARINCTEST(c, eptr);            GETCHARINCTEST(c, eptr);
3024            if (!_pcre_xclass(c, data)) RRETURN(MATCH_NOMATCH);            if (!PRIV(xclass)(c, data, utf)) RRETURN(MATCH_NOMATCH);
3025            }            }
3026          /* Control never gets here */          /* Control never gets here */
3027          }          }
# Line 2988  for (;;) Line 3039  for (;;)
3039              SCHECK_PARTIAL();              SCHECK_PARTIAL();
3040              break;              break;
3041              }              }
3042    #ifdef SUPPORT_UTF
3043            GETCHARLENTEST(c, eptr, len);            GETCHARLENTEST(c, eptr, len);
3044            if (!_pcre_xclass(c, data)) break;  #else
3045              c = *eptr;
3046    #endif
3047              if (!PRIV(xclass)(c, data, utf)) break;
3048            eptr += len;            eptr += len;
3049            }            }
3050          for(;;)          for(;;)
# Line 2997  for (;;) Line 3052  for (;;)
3052            RMATCH(eptr, ecode, offset_top, md, eptrb, RM21);            RMATCH(eptr, ecode, offset_top, md, eptrb, RM21);
3053            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3054            if (eptr-- == pp) break;        /* Stop if tried at original pos */            if (eptr-- == pp) break;        /* Stop if tried at original pos */
3055            if (utf8) BACKCHAR(eptr);  #ifdef SUPPORT_UTF
3056              if (utf) BACKCHAR(eptr);
3057    #endif
3058            }            }
3059          RRETURN(MATCH_NOMATCH);          RRETURN(MATCH_NOMATCH);
3060          }          }
# Line 3009  for (;;) Line 3066  for (;;)
3066      /* Match a single character, casefully */      /* Match a single character, casefully */
3067    
3068      case OP_CHAR:      case OP_CHAR:
3069  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3070      if (utf8)      if (utf)
3071        {        {
3072        length = 1;        length = 1;
3073        ecode++;        ecode++;
# Line 3024  for (;;) Line 3081  for (;;)
3081        }        }
3082      else      else
3083  #endif  #endif
3084        /* Not UTF mode */
     /* Non-UTF-8 mode */  
3085        {        {
3086        if (md->end_subject - eptr < 1)        if (md->end_subject - eptr < 1)
3087          {          {
# Line 3047  for (;;) Line 3103  for (;;)
3103        RRETURN(MATCH_NOMATCH);        RRETURN(MATCH_NOMATCH);
3104        }        }
3105    
3106  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3107      if (utf8)      if (utf)
3108        {        {
3109        length = 1;        length = 1;
3110        ecode++;        ecode++;
# Line 3061  for (;;) Line 3117  for (;;)
3117    
3118        if (fc < 128)        if (fc < 128)
3119          {          {
3120          if (md->lcc[*ecode++] != md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH);          if (md->lcc[fc]
3121                != TABLE_GET(*eptr, md->lcc, *eptr)) RRETURN(MATCH_NOMATCH);
3122            ecode++;
3123            eptr++;
3124          }          }
3125    
3126        /* Otherwise we must pick up the subject character. Note that we cannot        /* Otherwise we must pick up the subject character. Note that we cannot
# Line 3087  for (;;) Line 3146  for (;;)
3146          }          }
3147        }        }
3148      else      else
3149  #endif   /* SUPPORT_UTF8 */  #endif   /* SUPPORT_UTF */
3150    
3151      /* Non-UTF-8 mode */      /* Not UTF mode */
3152        {        {
3153        if (md->lcc[ecode[1]] != md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH);        if (TABLE_GET(ecode[1], md->lcc, ecode[1])
3154              != TABLE_GET(*eptr, md->lcc, *eptr)) RRETURN(MATCH_NOMATCH);
3155          eptr++;
3156        ecode += 2;        ecode += 2;
3157        }        }
3158      break;      break;
# Line 3101  for (;;) Line 3162  for (;;)
3162      case OP_EXACT:      case OP_EXACT:
3163      case OP_EXACTI:      case OP_EXACTI:
3164      min = max = GET2(ecode, 1);      min = max = GET2(ecode, 1);
3165      ecode += 3;      ecode += 1 + IMM2_SIZE;
3166      goto REPEATCHAR;      goto REPEATCHAR;
3167    
3168      case OP_POSUPTO:      case OP_POSUPTO:
# Line 3116  for (;;) Line 3177  for (;;)
3177      min = 0;      min = 0;
3178      max = GET2(ecode, 1);      max = GET2(ecode, 1);
3179      minimize = *ecode == OP_MINUPTO || *ecode == OP_MINUPTOI;      minimize = *ecode == OP_MINUPTO || *ecode == OP_MINUPTOI;
3180      ecode += 3;      ecode += 1 + IMM2_SIZE;
3181      goto REPEATCHAR;      goto REPEATCHAR;
3182    
3183      case OP_POSSTAR:      case OP_POSSTAR:
# Line 3164  for (;;) Line 3225  for (;;)
3225      /* Common code for all repeated single-character matches. */      /* Common code for all repeated single-character matches. */
3226    
3227      REPEATCHAR:      REPEATCHAR:
3228  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3229      if (utf8)      if (utf)
3230        {        {
3231        length = 1;        length = 1;
3232        charptr = ecode;        charptr = ecode;
# Line 3181  for (;;) Line 3242  for (;;)
3242          unsigned int othercase;          unsigned int othercase;
3243          if (op >= OP_STARI &&     /* Caseless */          if (op >= OP_STARI &&     /* Caseless */
3244              (othercase = UCD_OTHERCASE(fc)) != fc)              (othercase = UCD_OTHERCASE(fc)) != fc)
3245            oclength = _pcre_ord2utf8(othercase, occhars);            oclength = PRIV(ord2utf)(othercase, occhars);
3246          else oclength = 0;          else oclength = 0;
3247  #endif  /* SUPPORT_UCP */  #endif  /* SUPPORT_UCP */
3248    
3249          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3250            {            {
3251            if (eptr <= md->end_subject - length &&            if (eptr <= md->end_subject - length &&
3252              memcmp(eptr, charptr, length) == 0) eptr += length;              memcmp(eptr, charptr, IN_UCHARS(length)) == 0) eptr += length;
3253  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3254            else if (oclength > 0 &&            else if (oclength > 0 &&
3255                     eptr <= md->end_subject - oclength &&                     eptr <= md->end_subject - oclength &&
3256                     memcmp(eptr, occhars, oclength) == 0) eptr += oclength;                     memcmp(eptr, occhars, IN_UCHARS(oclength)) == 0) eptr += oclength;
3257  #endif  /* SUPPORT_UCP */  #endif  /* SUPPORT_UCP */
3258            else            else
3259              {              {
# Line 3211  for (;;) Line 3272  for (;;)
3272              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3273              if (fi >= max) RRETURN(MATCH_NOMATCH);              if (fi >= max) RRETURN(MATCH_NOMATCH);
3274              if (eptr <= md->end_subject - length &&              if (eptr <= md->end_subject - length &&
3275                memcmp(eptr, charptr, length) == 0) eptr += length;                memcmp(eptr, charptr, IN_UCHARS(length)) == 0) eptr += length;
3276  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3277              else if (oclength > 0 &&              else if (oclength > 0 &&
3278                       eptr <= md->end_subject - oclength &&                       eptr <= md->end_subject - oclength &&
3279                       memcmp(eptr, occhars, oclength) == 0) eptr += oclength;                       memcmp(eptr, occhars, IN_UCHARS(oclength)) == 0) eptr += oclength;
3280  #endif  /* SUPPORT_UCP */  #endif  /* SUPPORT_UCP */
3281              else              else
3282                {                {
# Line 3232  for (;;) Line 3293  for (;;)
3293            for (i = min; i < max; i++)            for (i = min; i < max; i++)
3294              {              {
3295              if (eptr <= md->end_subject - length &&              if (eptr <= md->end_subject - length &&
3296                  memcmp(eptr, charptr, length) == 0) eptr += length;                  memcmp(eptr, charptr, IN_UCHARS(length)) == 0) eptr += length;
3297  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3298              else if (oclength > 0 &&              else if (oclength > 0 &&
3299                       eptr <= md->end_subject - oclength &&                       eptr <= md->end_subject - oclength &&
3300                       memcmp(eptr, occhars, oclength) == 0) eptr += oclength;                       memcmp(eptr, occhars, IN_UCHARS(oclength)) == 0) eptr += oclength;
3301  #endif  /* SUPPORT_UCP */  #endif  /* SUPPORT_UCP */
3302              else              else
3303                {                {
# Line 3268  for (;;) Line 3329  for (;;)
3329        value of fc will always be < 128. */        value of fc will always be < 128. */
3330        }        }
3331      else      else
3332  #endif  /* SUPPORT_UTF8 */  #endif  /* SUPPORT_UTF */
3333          /* When not in UTF-8 mode, load a single-byte character. */
3334      /* When not in UTF-8 mode, load a single-byte character. */        fc = *ecode++;
3335    
3336      fc = *ecode++;      /* The value of fc at this point is always one character, though we may
3337        or may not be in UTF mode. The code is duplicated for the caseless and
     /* The value of fc at this point is always less than 256, though we may or  
     may not be in UTF-8 mode. The code is duplicated for the caseless and  
3338      caseful cases, for speed, since matching characters is likely to be quite      caseful cases, for speed, since matching characters is likely to be quite
3339      common. First, ensure the minimum number of matches are present. If min =      common. First, ensure the minimum number of matches are present. If min =
3340      max, continue at the same level without recursing. Otherwise, if      max, continue at the same level without recursing. Otherwise, if
# Line 3288  for (;;) Line 3347  for (;;)
3347    
3348      if (op >= OP_STARI)  /* Caseless */      if (op >= OP_STARI)  /* Caseless */
3349        {        {
3350        fc = md->lcc[fc];  #ifdef COMPILE_PCRE8
3351          /* fc must be < 128 if UTF is enabled. */
3352          foc = md->fcc[fc];
3353    #else
3354    #ifdef SUPPORT_UTF
3355    #ifdef SUPPORT_UCP
3356          if (utf && fc > 127)
3357            foc = UCD_OTHERCASE(fc);
3358    #else
3359          if (utf && fc > 127)
3360            foc = fc;
3361    #endif /* SUPPORT_UCP */
3362          else
3363    #endif /* SUPPORT_UTF */
3364            foc = TABLE_GET(fc, md->fcc, fc);
3365    #endif /* COMPILE_PCRE8 */
3366    
3367        for (i = 1; i <= min; i++)        for (i = 1; i <= min; i++)
3368          {          {
3369          if (eptr >= md->end_subject)          if (eptr >= md->end_subject)
# Line 3296  for (;;) Line 3371  for (;;)
3371            SCHECK_PARTIAL();            SCHECK_PARTIAL();
3372            RRETURN(MATCH_NOMATCH);            RRETURN(MATCH_NOMATCH);
3373            }            }
3374          if (fc != md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH);          if (fc != *eptr && foc != *eptr) RRETURN(MATCH_NOMATCH);
3375            eptr++;
3376          }          }
3377        if (min == max) continue;        if (min == max) continue;
3378        if (minimize)        if (minimize)
# Line 3311  for (;;) Line 3387  for (;;)
3387              SCHECK_PARTIAL();              SCHECK_PARTIAL();
3388              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
3389              }              }
3390            if (fc != md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH);            if (fc != *eptr && foc != *eptr) RRETURN(MATCH_NOMATCH);
3391              eptr++;
3392            }            }
3393          /* Control never gets here */          /* Control never gets here */
3394          }          }
# Line 3325  for (;;) Line 3402  for (;;)
3402              SCHECK_PARTIAL();              SCHECK_PARTIAL();
3403              break;              break;
3404              }              }
3405            if (fc != md->lcc[*eptr]) break;            if (fc != *eptr && foc != *eptr) break;
3406            eptr++;            eptr++;
3407            }            }
3408    
# Line 3414  for (;;) Line 3491  for (;;)
3491      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
3492      if (op == OP_NOTI)         /* The caseless case */      if (op == OP_NOTI)         /* The caseless case */
3493        {        {
3494  #ifdef SUPPORT_UTF8        register int ch, och;
3495        if (c < 256)        ch = *ecode++;
3496  #endif  #ifdef COMPILE_PCRE8
3497        c = md->lcc[c];        /* ch must be < 128 if UTF is enabled. */
3498        if (md->lcc[*ecode++] == c) RRETURN(MATCH_NOMATCH);        och = md->fcc[ch];
3499    #else
3500    #ifdef SUPPORT_UTF
3501    #ifdef SUPPORT_UCP
3502          if (utf && ch > 127)
3503            och = UCD_OTHERCASE(ch);
3504    #else
3505          if (utf && ch > 127)
3506            och = ch;
3507    #endif /* SUPPORT_UCP */
3508          else
3509    #endif /* SUPPORT_UTF */
3510            och = TABLE_GET(ch, md->fcc, ch);
3511    #endif /* COMPILE_PCRE8 */
3512          if (ch == c || och == c) RRETURN(MATCH_NOMATCH);
3513        }        }
3514      else    /* Caseful */      else    /* Caseful */
3515        {        {
# Line 3436  for (;;) Line 3527  for (;;)
3527      case OP_NOTEXACT:      case OP_NOTEXACT:
3528      case OP_NOTEXACTI:      case OP_NOTEXACTI:
3529      min = max = GET2(ecode, 1);      min = max = GET2(ecode, 1);
3530      ecode += 3;      ecode += 1 + IMM2_SIZE;
3531      goto REPEATNOTCHAR;      goto REPEATNOTCHAR;
3532    
3533      case OP_NOTUPTO:      case OP_NOTUPTO:
# Line 3446  for (;;) Line 3537  for (;;)
3537      min = 0;      min = 0;
3538      max = GET2(ecode, 1);      max = GET2(ecode, 1);
3539      minimize = *ecode == OP_NOTMINUPTO || *ecode == OP_NOTMINUPTOI;      minimize = *ecode == OP_NOTMINUPTO || *ecode == OP_NOTMINUPTOI;
3540      ecode += 3;      ecode += 1 + IMM2_SIZE;
3541      goto REPEATNOTCHAR;      goto REPEATNOTCHAR;
3542    
3543      case OP_NOTPOSSTAR:      case OP_NOTPOSSTAR:
# Line 3478  for (;;) Line 3569  for (;;)
3569      possessive = TRUE;      possessive = TRUE;
3570      min = 0;      min = 0;
3571      max = GET2(ecode, 1);      max = GET2(ecode, 1);
3572      ecode += 3;      ecode += 1 + IMM2_SIZE;
3573      goto REPEATNOTCHAR;      goto REPEATNOTCHAR;
3574    
3575      case OP_NOTSTAR:      case OP_NOTSTAR:
# Line 3517  for (;;) Line 3608  for (;;)
3608    
3609      if (op >= OP_NOTSTARI)     /* Caseless */      if (op >= OP_NOTSTARI)     /* Caseless */
3610        {        {
3611        fc = md->lcc[fc];  #ifdef COMPILE_PCRE8
3612          /* fc must be < 128 if UTF is enabled. */
3613          foc = md->fcc[fc];
3614    #else
3615    #ifdef SUPPORT_UTF
3616    #ifdef SUPPORT_UCP
3617          if (utf && fc > 127)
3618            foc = UCD_OTHERCASE(fc);
3619    #else
3620          if (utf && fc > 127)
3621            foc = fc;
3622    #endif /* SUPPORT_UCP */
3623          else
3624    #endif /* SUPPORT_UTF */
3625            foc = TABLE_GET(fc, md->fcc, fc);
3626    #endif /* COMPILE_PCRE8 */
3627    
3628  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3629        /* UTF-8 mode */        if (utf)
       if (utf8)  
3630          {          {
3631          register unsigned int d;          register unsigned int d;
3632          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
# Line 3532  for (;;) Line 3637  for (;;)
3637              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
3638              }              }
3639            GETCHARINC(d, eptr);            GETCHARINC(d, eptr);
3640            if (d < 256) d = md->lcc[d];            if (fc == d || foc == d) RRETURN(MATCH_NOMATCH);
           if (fc == d) RRETURN(MATCH_NOMATCH);  
3641            }            }
3642          }          }
3643        else        else
3644  #endif  #endif
3645          /* Not UTF mode */
       /* Not UTF-8 mode */  
3646          {          {
3647          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3648            {            {
# Line 3548  for (;;) Line 3651  for (;;)
3651              SCHECK_PARTIAL();              SCHECK_PARTIAL();
3652              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
3653              }              }
3654            if (fc == md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH);            if (fc == *eptr || foc == *eptr) RRETURN(MATCH_NOMATCH);
3655              eptr++;
3656            }            }
3657          }          }
3658    
# Line 3556  for (;;) Line 3660  for (;;)
3660    
3661        if (minimize)        if (minimize)
3662          {          {
3663  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3664          /* UTF-8 mode */          if (utf)
         if (utf8)  
3665            {            {
3666            register unsigned int d;            register unsigned int d;
3667            for (fi = min;; fi++)            for (fi = min;; fi++)
# Line 3572  for (;;) Line 3675  for (;;)
3675                RRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
3676                }                }
3677              GETCHARINC(d, eptr);              GETCHARINC(d, eptr);
3678              if (d < 256) d = md->lcc[d];              if (fc == d || foc == d) RRETURN(MATCH_NOMATCH);
             if (fc == d) RRETURN(MATCH_NOMATCH);  
3679              }              }
3680            }            }
3681          else          else
3682  #endif  #endif
3683          /* Not UTF-8 mode */          /* Not UTF mode */
3684            {            {
3685            for (fi = min;; fi++)            for (fi = min;; fi++)
3686              {              {
# Line 3590  for (;;) Line 3692  for (;;)
3692                SCHECK_PARTIAL();                SCHECK_PARTIAL();
3693                RRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
3694                }                }
3695              if (fc == md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH);              if (fc == *eptr || foc == *eptr) RRETURN(MATCH_NOMATCH);
3696                eptr++;
3697              }              }
3698            }            }
3699          /* Control never gets here */          /* Control never gets here */
# Line 3602  for (;;) Line 3705  for (;;)
3705          {          {
3706          pp = eptr;          pp = eptr;
3707    
3708  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3709          /* UTF-8 mode */          if (utf)
         if (utf8)  
3710            {            {
3711            register unsigned int d;            register unsigned int d;
3712            for (i = min; i < max; i++)            for (i = min; i < max; i++)
# Line 3616  for (;;) Line 3718  for (;;)
3718                break;                break;
3719                }                }
3720              GETCHARLEN(d, eptr, len);              GETCHARLEN(d, eptr, len);
3721              if (d < 256) d = md->lcc[d];              if (fc == d || foc == d) break;
             if (fc == d) break;  
3722              eptr += len;              eptr += len;
3723              }              }
3724          if (possessive) continue;            if (possessive) continue;
3725          for(;;)            for(;;)
3726              {              {
3727              RMATCH(eptr, ecode, offset_top, md, eptrb, RM30);              RMATCH(eptr, ecode, offset_top, md, eptrb, RM30);
3728              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
# Line 3631  for (;;) Line 3732  for (;;)
3732            }            }
3733          else          else
3734  #endif  #endif
3735          /* Not UTF-8 mode */          /* Not UTF mode */
3736            {            {
3737            for (i = min; i < max; i++)            for (i = min; i < max; i++)
3738              {              {
# Line 3640  for (;;) Line 3741  for (;;)
3741                SCHECK_PARTIAL();                SCHECK_PARTIAL();
3742                break;                break;
3743                }                }
3744              if (fc == md->lcc[*eptr]) break;              if (fc == *eptr || foc == *eptr) break;
3745              eptr++;              eptr++;
3746              }              }
3747            if (possessive) continue;            if (possessive) continue;
# Line 3661  for (;;) Line 3762  for (;;)
3762    
3763      else      else
3764        {        {
3765  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3766        /* UTF-8 mode */        if (utf)
       if (utf8)  
3767          {          {
3768          register unsigned int d;          register unsigned int d;
3769          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
# Line 3679  for (;;) Line 3779  for (;;)
3779          }          }
3780        else        else
3781  #endif  #endif
3782        /* Not UTF-8 mode */        /* Not UTF mode */
3783          {          {
3784          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3785            {            {
# Line 3696  for (;;) Line 3796  for (;;)
3796    
3797        if (minimize)        if (minimize)
3798          {          {
3799  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3800          /* UTF-8 mode */          if (utf)
         if (utf8)  
3801            {            {
3802            register unsigned int d;            register unsigned int d;
3803            for (fi = min;; fi++)            for (fi = min;; fi++)
# Line 3717  for (;;) Line 3816  for (;;)
3816            }            }
3817          else          else
3818  #endif  #endif
3819          /* Not UTF-8 mode */          /* Not UTF mode */
3820            {            {
3821            for (fi = min;; fi++)            for (fi = min;; fi++)
3822              {              {
# Line 3741  for (;;) Line 3840  for (;;)
3840          {          {
3841          pp = eptr;          pp = eptr;
3842    
3843  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3844          /* UTF-8 mode */          if (utf)
         if (utf8)  
3845            {            {
3846            register unsigned int d;            register unsigned int d;
3847            for (i = min; i < max; i++)            for (i = min; i < max; i++)
# Line 3769  for (;;) Line 3867  for (;;)
3867            }            }
3868          else          else
3869  #endif  #endif
3870          /* Not UTF-8 mode */          /* Not UTF mode */
3871            {            {
3872            for (i = min; i < max; i++)            for (i = min; i < max; i++)
3873              {              {
# Line 3802  for (;;) Line 3900  for (;;)
3900      case OP_TYPEEXACT:      case OP_TYPEEXACT:
3901      min = max = GET2(ecode, 1);      min = max = GET2(ecode, 1);
3902      minimize = TRUE;      minimize = TRUE;
3903      ecode += 3;      ecode += 1 + IMM2_SIZE;
3904      goto REPEATTYPE;      goto REPEATTYPE;
3905    
3906      case OP_TYPEUPTO:      case OP_TYPEUPTO:
# Line 3810  for (;;) Line 3908  for (;;)
3908      min = 0;      min = 0;
3909      max = GET2(ecode, 1);      max = GET2(ecode, 1);
3910      minimize = *ecode == OP_TYPEMINUPTO;      minimize = *ecode == OP_TYPEMINUPTO;
3911      ecode += 3;      ecode += 1 + IMM2_SIZE;
3912      goto REPEATTYPE;      goto REPEATTYPE;
3913    
3914      case OP_TYPEPOSSTAR:      case OP_TYPEPOSSTAR:
# Line 3838  for (;;) Line 3936  for (;;)
3936      possessive = TRUE;      possessive = TRUE;
3937      min = 0;      min = 0;
3938      max = GET2(ecode, 1);      max = GET2(ecode, 1);
3939      ecode += 3;      ecode += 1 + IMM2_SIZE;
3940      goto REPEATTYPE;      goto REPEATTYPE;
3941    
3942      case OP_TYPESTAR:      case OP_TYPESTAR:
# Line 4045  for (;;) Line 4143  for (;;)
4143            while (eptr < md->end_subject)            while (eptr < md->end_subject)
4144              {              {
4145              int len = 1;              int len = 1;
4146              if (!utf8) c = *eptr; else { GETCHARLEN(c, eptr, len); }              if (!utf) c = *eptr; else { GETCHARLEN(c, eptr, len); }
4147              if (UCD_CATEGORY(c) != ucp_M) break;              if (UCD_CATEGORY(c) != ucp_M) break;
4148              eptr += len;              eptr += len;
4149              }              }
# Line 4057  for (;;) Line 4155  for (;;)
4155    
4156  /* Handle all other cases when the coding is UTF-8 */  /* Handle all other cases when the coding is UTF-8 */
4157    
4158  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
4159        if (utf8) switch(ctype)        if (utf) switch(ctype)
4160          {          {
4161          case OP_ANY:          case OP_ANY:
4162          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
# Line 4070  for (;;) Line 4168  for (;;)
4168              }              }
4169            if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH);            if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH);
4170            eptr++;            eptr++;
4171            while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;            ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
4172            }            }
4173          break;          break;
4174    
# Line 4083  for (;;) Line 4181  for (;;)
4181              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4182              }              }
4183            eptr++;            eptr++;
4184            while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;            ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
4185            }            }
4186          break;          break;
4187    
# Line 4265  for (;;) Line 4363  for (;;)
4363              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4364              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4365              }              }
4366            if (*eptr >= 128 || (md->ctypes[*eptr++] & ctype_digit) == 0)            if (*eptr >= 128 || (md->ctypes[*eptr] & ctype_digit) == 0)
4367              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4368              eptr++;
4369            /* No need to skip more bytes - we know it's a 1-byte character */            /* No need to skip more bytes - we know it's a 1-byte character */
4370            }            }
4371          break;          break;
# Line 4281  for (;;) Line 4380  for (;;)
4380              }              }
4381            if (*eptr < 128 && (md->ctypes[*eptr] & ctype_space) != 0)            if (*eptr < 128 && (md->ctypes[*eptr] & ctype_space) != 0)
4382              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4383            while (++eptr < md->end_subject && (*eptr & 0xc0) == 0x80);            eptr++;
4384              ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
4385            }            }
4386          break;          break;
4387    
# Line 4293  for (;;) Line 4393  for (;;)
4393              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4394              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4395              }              }
4396            if (*eptr >= 128 || (md->ctypes[*eptr++] & ctype_space) == 0)            if (*eptr >= 128 || (md->ctypes[*eptr] & ctype_space) == 0)
4397              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4398              eptr++;
4399            /* No need to skip more bytes - we know it's a 1-byte character */            /* No need to skip more bytes - we know it's a 1-byte character */
4400            }            }
4401          break;          break;
# Line 4309  for (;;) Line 4410  for (;;)
4410              }              }
4411            if (*eptr < 128 && (md->ctypes[*eptr] & ctype_word) != 0)            if (*eptr < 128 && (md->ctypes[*eptr] & ctype_word) != 0)
4412              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4413            while (++eptr < md->end_subject && (*eptr & 0xc0) == 0x80);            eptr++;
4414              ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
4415            }            }
4416          break;          break;
4417    
# Line 4321  for (;;) Line 4423  for (;;)
4423              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4424              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4425              }              }
4426            if (*eptr >= 128 || (md->ctypes[*eptr++] & ctype_word) == 0)            if (*eptr >= 128 || (md->ctypes[*eptr] & ctype_word) == 0)
4427              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4428              eptr++;
4429            /* No need to skip more bytes - we know it's a 1-byte character */            /* No need to skip more bytes - we know it's a 1-byte character */
4430            }            }
4431          break;          break;
# Line 4332  for (;;) Line 4435  for (;;)
4435          }  /* End switch(ctype) */          }  /* End switch(ctype) */
4436    
4437        else        else
4438  #endif     /* SUPPORT_UTF8 */  #endif     /* SUPPORT_UTF */
4439    
4440        /* Code for the non-UTF-8 case for minimum matching of operators other        /* Code for the non-UTF-8 case for minimum matching of operators other
4441        than OP_PROP and OP_NOTPROP. */        than OP_PROP and OP_NOTPROP. */
# Line 4392  for (;;) Line 4495  for (;;)
4495              case 0x000b:              case 0x000b:
4496              case 0x000c:              case 0x000c:
4497              case 0x0085:              case 0x0085:
4498    #ifdef COMPILE_PCRE16
4499                case 0x2028:
4500                case 0x2029:
4501    #endif
4502              if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH);              if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH);
4503              break;              break;
4504              }              }
# Line 4412  for (;;) Line 4519  for (;;)
4519              case 0x09:      /* HT */              case 0x09:      /* HT */
4520              case 0x20:      /* SPACE */              case 0x20:      /* SPACE */
4521              case 0xa0:      /* NBSP */              case 0xa0:      /* NBSP */
4522    #ifdef COMPILE_PCRE16
4523                case 0x1680:    /* OGHAM SPACE MARK */
4524                case 0x180e:    /* MONGOLIAN VOWEL SEPARATOR */
4525                case 0x2000:    /* EN QUAD */
4526                case 0x2001:    /* EM QUAD */
4527                case 0x2002:    /* EN SPACE */
4528                case 0x2003:    /* EM SPACE */
4529                case 0x2004:    /* THREE-PER-EM SPACE */
4530                case 0x2005:    /* FOUR-PER-EM SPACE */
4531                case 0x2006:    /* SIX-PER-EM SPACE */
4532                case 0x2007:    /* FIGURE SPACE */
4533                case 0x2008:    /* PUNCTUATION SPACE */
4534                case 0x2009:    /* THIN SPACE */
4535                case 0x200A:    /* HAIR SPACE */
4536                case 0x202f:    /* NARROW NO-BREAK SPACE */
4537                case 0x205f:    /* MEDIUM MATHEMATICAL SPACE */
4538                case 0x3000:    /* IDEOGRAPHIC SPACE */
4539    #endif
4540              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4541              }              }
4542            }            }
# Line 4431  for (;;) Line 4556  for (;;)
4556              case 0x09:      /* HT */              case 0x09:      /* HT */
4557              case 0x20:      /* SPACE */              case 0x20:      /* SPACE */
4558              case 0xa0:      /* NBSP */              case 0xa0:      /* NBSP */
4559    #ifdef COMPILE_PCRE16
4560                case 0x1680:    /* OGHAM SPACE MARK */
4561                case 0x180e:    /* MONGOLIAN VOWEL SEPARATOR */
4562                case 0x2000:    /* EN QUAD */
4563                case 0x2001:    /* EM QUAD */
4564                case 0x2002:    /* EN SPACE */
4565                case 0x2003:    /* EM SPACE */
4566                case 0x2004:    /* THREE-PER-EM SPACE */
4567                case 0x2005:    /* FOUR-PER-EM SPACE */
4568                case 0x2006:    /* SIX-PER-EM SPACE */
4569                case 0x2007:    /* FIGURE SPACE */
4570                case 0x2008:    /* PUNCTUATION SPACE */
4571                case 0x2009:    /* THIN SPACE */
4572                case 0x200A:    /* HAIR SPACE */
4573                case 0x202f:    /* NARROW NO-BREAK SPACE */
4574                case 0x205f:    /* MEDIUM MATHEMATICAL SPACE */
4575                case 0x3000:    /* IDEOGRAPHIC SPACE */
4576    #endif
4577              break;              break;
4578              }              }
4579            }            }
# Line 4452  for (;;) Line 4595  for (;;)
4595              case 0x0c:      /* FF */              case 0x0c:      /* FF */
4596              case 0x0d:      /* CR */              case 0x0d:      /* CR */
4597              case 0x85:      /* NEL */              case 0x85:      /* NEL */
4598    #ifdef COMPILE_PCRE16
4599                case 0x2028:    /* LINE SEPARATOR */
4600                case 0x2029:    /* PARAGRAPH SEPARATOR */
4601    #endif
4602              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4603              }              }
4604            }            }
# Line 4473  for (;;) Line 4620  for (;;)
4620              case 0x0c:      /* FF */              case 0x0c:      /* FF */
4621              case 0x0d:      /* CR */              case 0x0d:      /* CR */
4622              case 0x85:      /* NEL */              case 0x85:      /* NEL */
4623    #ifdef COMPILE_PCRE16
4624                case 0x2028:    /* LINE SEPARATOR */
4625                case 0x2029:    /* PARAGRAPH SEPARATOR */
4626    #endif
4627              break;              break;
4628              }              }
4629            }            }
# Line 4486  for (;;) Line 4637  for (;;)
4637              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4638              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4639              }              }
4640            if ((md->ctypes[*eptr++] & ctype_digit) != 0) RRETURN(MATCH_NOMATCH);            if (MAX_255(*eptr) && (md->ctypes[*eptr] & ctype_digit) != 0)
4641                RRETURN(MATCH_NOMATCH);
4642              eptr++;
4643            }            }
4644          break;          break;
4645    
# Line 4498  for (;;) Line 4651  for (;;)
4651              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4652              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4653              }              }
4654            if ((md->ctypes[*eptr++] & ctype_digit) == 0) RRETURN(MATCH_NOMATCH);            if (!MAX_255(*eptr) || (md->ctypes[*eptr] & ctype_digit) == 0)
4655                RRETURN(MATCH_NOMATCH);
4656              eptr++;
4657            }            }
4658          break;          break;
4659    
# Line 4510  for (;;) Line 4665  for (;;)
4665              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4666              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4667              }              }
4668            if ((md->ctypes[*eptr++] & ctype_space) != 0) RRETURN(MATCH_NOMATCH);            if (MAX_255(*eptr) && (md->ctypes[*eptr] & ctype_space) != 0)
4669                RRETURN(MATCH_NOMATCH);
4670              eptr++;
4671            }            }
4672          break;          break;
4673    
# Line 4522  for (;;) Line 4679  for (;;)
4679              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4680              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4681              }              }
4682            if ((md->ctypes[*eptr++] & ctype_space) == 0) RRETURN(MATCH_NOMATCH);            if (!MAX_255(*eptr) || (md->ctypes[*eptr] & ctype_space) == 0)
4683                RRETURN(MATCH_NOMATCH);
4684              eptr++;
4685            }            }
4686          break;          break;
4687    
# Line 4534  for (;;) Line 4693  for (;;)
4693              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4694              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4695              }              }
4696            if ((md->ctypes[*eptr++] & ctype_word) != 0)            if (MAX_255(*eptr) && (md->ctypes[*eptr] & ctype_word) != 0)
4697              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4698              eptr++;
4699            }            }
4700          break;          break;
4701    
# Line 4547  for (;;) Line 4707  for (;;)
4707              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4708              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4709              }              }
4710            if ((md->ctypes[*eptr++] & ctype_word) == 0)            if (!MAX_255(*eptr) || (md->ctypes[*eptr] & ctype_word) == 0)
4711              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4712              eptr++;
4713            }            }
4714          break;          break;
4715    
# Line 4766  for (;;) Line 4927  for (;;)
4927            while (eptr < md->end_subject)            while (eptr < md->end_subject)
4928              {              {
4929              int len = 1;              int len = 1;
4930              if (!utf8) c = *eptr; else { GETCHARLEN(c, eptr, len); }              if (!utf) c = *eptr; else { GETCHARLEN(c, eptr, len); }
4931              if (UCD_CATEGORY(c) != ucp_M) break;              if (UCD_CATEGORY(c) != ucp_M) break;
4932              eptr += len;              eptr += len;
4933              }              }
# Line 4775  for (;;) Line 4936  for (;;)
4936        else        else
4937  #endif     /* SUPPORT_UCP */  #endif     /* SUPPORT_UCP */
4938    
4939  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
4940        /* UTF-8 mode */        if (utf)
       if (utf8)  
4941          {          {
4942          for (fi = min;; fi++)          for (fi = min;; fi++)
4943            {            {
# Line 4919  for (;;) Line 5079  for (;;)
5079              break;              break;
5080    
5081              case OP_WHITESPACE:              case OP_WHITESPACE:
5082              if  (c >= 256 || (md->ctypes[c] & ctype_space) == 0)              if (c >= 256 || (md->ctypes[c] & ctype_space) == 0)
5083                RRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
5084              break;              break;
5085    
# Line 4940  for (;;) Line 5100  for (;;)
5100          }          }
5101        else        else
5102  #endif  #endif
5103        /* Not UTF-8 mode */        /* Not UTF mode */
5104          {          {
5105          for (fi = min;; fi++)          for (fi = min;; fi++)
5106            {            {
# Line 4976  for (;;) Line 5136  for (;;)
5136                case 0x000b:                case 0x000b:
5137                case 0x000c:                case 0x000c:
5138                case 0x0085:                case 0x0085:
5139    #ifdef COMPILE_PCRE16
5140                  case 0x2028:
5141                  case 0x2029:
5142    #endif
5143                if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH);                if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH);
5144                break;                break;
5145                }                }
# Line 4988  for (;;) Line 5152  for (;;)
5152                case 0x09:      /* HT */                case 0x09:      /* HT */
5153                case 0x20:      /* SPACE */                case 0x20:      /* SPACE */
5154                case 0xa0:      /* NBSP */                case 0xa0:      /* NBSP */
5155    #ifdef COMPILE_PCRE16
5156                  case 0x1680:    /* OGHAM SPACE MARK */
5157                  case 0x180e:    /* MONGOLIAN VOWEL SEPARATOR */
5158                  case 0x2000:    /* EN QUAD */
5159                  case 0x2001:    /* EM QUAD */
5160                  case 0x2002:    /* EN SPACE */
5161                  case 0x2003:    /* EM SPACE */
5162                  case 0x2004:    /* THREE-PER-EM SPACE */
5163                  case 0x2005:    /* FOUR-PER-EM SPACE */
5164                  case 0x2006:    /* SIX-PER-EM SPACE */
5165                  case 0x2007:    /* FIGURE SPACE */
5166                  case 0x2008:    /* PUNCTUATION SPACE */
5167                  case 0x2009:    /* THIN SPACE */
5168                  case 0x200A:    /* HAIR SPACE */
5169                  case 0x202f:    /* NARROW NO-BREAK SPACE */
5170                  case 0x205f:    /* MEDIUM MATHEMATICAL SPACE */
5171                  case 0x3000:    /* IDEOGRAPHIC SPACE */
5172    #endif
5173                RRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
5174                }                }
5175              break;              break;
# Line 4999  for (;;) Line 5181  for (;;)
5181                case 0x09:      /* HT */                case 0x09:      /* HT */
5182                case 0x20:      /* SPACE */                case 0x20:      /* SPACE */
5183                case 0xa0:      /* NBSP */                case 0xa0:      /* NBSP */
5184    #ifdef COMPILE_PCRE16
5185                  case 0x1680:    /* OGHAM SPACE MARK */
5186                  case 0x180e:    /* MONGOLIAN VOWEL SEPARATOR */
5187                  case 0x2000:    /* EN QUAD */
5188                  case 0x2001:    /* EM QUAD */
5189                  case 0x2002:    /* EN SPACE */
5190                  case 0x2003:    /* EM SPACE */
5191                  case 0x2004:    /* THREE-PER-EM SPACE */
5192                  case 0x2005:    /* FOUR-PER-EM SPACE */
5193                  case 0x2006:    /* SIX-PER-EM SPACE */
5194                  case 0x2007:    /* FIGURE SPACE */
5195                  case 0x2008:    /* PUNCTUATION SPACE */
5196                  case 0x2009:    /* THIN SPACE */
5197                  case 0x200A:    /* HAIR SPACE */
5198                  case 0x202f:    /* NARROW NO-BREAK SPACE */
5199                  case 0x205f:    /* MEDIUM MATHEMATICAL SPACE */
5200                  case 0x3000:    /* IDEOGRAPHIC SPACE */
5201    #endif
5202                break;                break;
5203                }                }
5204              break;              break;
# Line 5012  for (;;) Line 5212  for (;;)
5212                case 0x0c:      /* FF */                case 0x0c:      /* FF */
5213                case 0x0d:      /* CR */                case 0x0d:      /* CR */
5214                case 0x85:      /* NEL */                case 0x85:      /* NEL */
5215    #ifdef COMPILE_PCRE16
5216                  case 0x2028:    /* LINE SEPARATOR */
5217                  case 0x2029:    /* PARAGRAPH SEPARATOR */
5218    #endif
5219                RRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
5220                }                }
5221              break;              break;
# Line 5025  for (;;) Line 5229  for (;;)
5229                case 0x0c:      /* FF */                case 0x0c:      /* FF */
5230                case 0x0d:      /* CR */                case 0x0d:      /* CR */
5231                case 0x85:      /* NEL */                case 0x85:      /* NEL */
5232    #ifdef COMPILE_PCRE16
5233                  case 0x2028:    /* LINE SEPARATOR */
5234                  case 0x2029:    /* PARAGRAPH SEPARATOR */
5235    #endif
5236                break;                break;
5237                }                }
5238              break;              break;
5239    
5240              case OP_NOT_DIGIT:              case OP_NOT_DIGIT:
5241              if ((md->ctypes[c] & ctype_digit) != 0) RRETURN(MATCH_NOMATCH);              if (MAX_255(c) && (md->ctypes[c] & ctype_digit) != 0) RRETURN(MATCH_NOMATCH);
5242              break;              break;
5243    
5244              case OP_DIGIT:              case OP_DIGIT:
5245              if ((md->ctypes[c] & ctype_digit) == 0) RRETURN(MATCH_NOMATCH);              if (!MAX_255(c) || (md->ctypes[c] & ctype_digit) == 0) RRETURN(MATCH_NOMATCH);
5246              break;              break;
5247    
5248              case OP_NOT_WHITESPACE:              case OP_NOT_WHITESPACE:
5249              if ((md->ctypes[c] & ctype_space) != 0) RRETURN(MATCH_NOMATCH);              if (MAX_255(c) && (md->ctypes[c] & ctype_space) != 0) RRETURN(MATCH_NOMATCH);
5250              break;              break;
5251    
5252              case OP_WHITESPACE:              case OP_WHITESPACE:
5253              if  ((md->ctypes[c] & ctype_space) == 0) RRETURN(MATCH_NOMATCH);              if (!MAX_255(c) || (md->ctypes[c] & ctype_space) == 0) RRETURN(MATCH_NOMATCH);
5254              break;              break;
5255    
5256              case OP_NOT_WORDCHAR:              case OP_NOT_WORDCHAR:
5257              if ((md->ctypes[c] & ctype_word) != 0) RRETURN(MATCH_NOMATCH);              if (MAX_255(c) && (md->ctypes[c] & ctype_word) != 0) RRETURN(MATCH_NOMATCH);
5258              break;              break;
5259    
5260              case OP_WORDCHAR:              case OP_WORDCHAR:
5261              if ((md->ctypes[c] & ctype_word) == 0) RRETURN(MATCH_NOMATCH);              if (!MAX_255(c) || (md->ctypes[c] & ctype_word) == 0) RRETURN(MATCH_NOMATCH);
5262              break;              break;
5263    
5264              default:              default:
# Line 5239  for (;;) Line 5447  for (;;)
5447            RMATCH(eptr, ecode, offset_top, md, eptrb, RM44);            RMATCH(eptr, ecode, offset_top, md, eptrb, RM44);
5448            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
5449            if (eptr-- == pp) break;        /* Stop if tried at original pos */            if (eptr-- == pp) break;        /* Stop if tried at original pos */
5450            if (utf8) BACKCHAR(eptr);            if (utf) BACKCHAR(eptr);
5451            }            }
5452          }          }
5453    
# Line 5256  for (;;) Line 5464  for (;;)
5464              SCHECK_PARTIAL();              SCHECK_PARTIAL();
5465              break;              break;
5466              }              }
5467            if (!utf8) c = *eptr; else { GETCHARLEN(c, eptr, len); }            if (!utf) c = *eptr; else { GETCHARLEN(c, eptr, len); }
5468            if (UCD_CATEGORY(c) == ucp_M) break;            if (UCD_CATEGORY(c) == ucp_M) break;
5469            eptr += len;            eptr += len;
5470            while (eptr < md->end_subject)            while (eptr < md->end_subject)
5471              {              {
5472              len = 1;              len = 1;
5473              if (!utf8) c = *eptr; else { GETCHARLEN(c, eptr, len); }              if (!utf) c = *eptr; else { GETCHARLEN(c, eptr, len); }
5474              if (UCD_CATEGORY(c) != ucp_M) break;              if (UCD_CATEGORY(c) != ucp_M) break;
5475              eptr += len;              eptr += len;
5476              }              }
# Line 5279  for (;;) Line 5487  for (;;)
5487            if (eptr-- == pp) break;        /* Stop if tried at original pos */            if (eptr-- == pp) break;        /* Stop if tried at original pos */
5488            for (;;)                        /* Move back over one extended */            for (;;)                        /* Move back over one extended */
5489              {              {
5490              if (!utf8) c = *eptr; else              if (!utf) c = *eptr; else
5491                {                {
5492                BACKCHAR(eptr);                BACKCHAR(eptr);
5493                GETCHAR(c, eptr);                GETCHAR(c, eptr);
# Line 5293  for (;;) Line 5501  for (;;)
5501        else        else
5502  #endif   /* SUPPORT_UCP */  #endif   /* SUPPORT_UCP */
5503    
5504  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
5505        /* UTF-8 mode */        if (utf)
   
       if (utf8)  
5506          {          {
5507          switch(ctype)          switch(ctype)
5508            {            {
# Line 5312  for (;;) Line 5518  for (;;)
5518                  }                  }
5519                if (IS_NEWLINE(eptr)) break;                if (IS_NEWLINE(eptr)) break;
5520                eptr++;                eptr++;
5521                while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;                ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
5522                }                }
5523              }              }
5524    
# Line 5329  for (;;) Line 5535  for (;;)
5535                  }                  }
5536                if (IS_NEWLINE(eptr)) break;                if (IS_NEWLINE(eptr)) break;
5537                eptr++;                eptr++;
5538                while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;                ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
5539                }                }
5540              }              }
5541            break;            break;
# Line 5345  for (;;) Line 5551  for (;;)
5551                  break;                  break;
5552                  }                  }
5553                eptr++;                eptr++;
5554                while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;                ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
5555                }                }
5556              }              }
5557            else            else
# Line 5578  for (;;) Line 5784  for (;;)
5784            }            }
5785          }          }
5786        else        else
5787  #endif  /* SUPPORT_UTF8 */  #endif  /* SUPPORT_UTF */
5788          /* Not UTF mode */
       /* Not UTF-8 mode */  
5789          {          {
5790          switch(ctype)          switch(ctype)
5791            {            {
# Line 5624  for (;;) Line 5829  for (;;)
5829                }                }
5830              else              else
5831                {                {
5832                if (c != 0x000a &&                if (c != 0x000a && (md->bsr_anycrlf ||
5833                    (md->bsr_anycrlf ||                  (c != 0x000b && c != 0x000c && c != 0x0085
5834                      (c != 0x000b && c != 0x000c && c != 0x0085)))  #ifdef COMPILE_PCRE16
5835                  break;                  && c != 0x2028 && c != 0x2029
5836    #endif
5837                    ))) break;
5838                eptr++;                eptr++;
5839                }                }
5840              }              }
# Line 5642  for (;;) Line 5849  for (;;)
5849                break;                break;
5850                }                }
5851              c = *eptr;              c = *eptr;
5852              if (c == 0x09 || c == 0x20 || c == 0xa0) break;              if (c == 0x09 || c == 0x20 || c == 0xa0
5853    #ifdef COMPILE_PCRE16
5854                  || c == 0x1680 || c == 0x180e || (c >= 0x2000 && c <= 0x200A)
5855                  || c == 0x202f || c == 0x205f || c == 0x3000
5856    #endif
5857                  ) break;
5858              eptr++;              eptr++;
5859              }              }
5860            break;            break;
# Line 5656  for (;;) Line 5868  for (;;)
5868                break;                break;
5869                }                }
5870              c = *eptr;              c = *eptr;
5871              if (c != 0x09 && c != 0x20 && c != 0xa0) break;              if (c != 0x09 && c != 0x20 && c != 0xa0
5872    #ifdef COMPILE_PCRE16
5873                  && c != 0x1680 && c != 0x180e && (c < 0x2000 || c > 0x200A)
5874                  && c != 0x202f && c != 0x205f && c != 0x3000
5875    #endif
5876                  ) break;
5877              eptr++;              eptr++;
5878              }              }
5879            break;            break;
# Line 5670  for (;;) Line 5887  for (;;)
5887                break;                break;
5888                }                }
5889              c = *eptr;              c = *eptr;
5890              if (c == 0x0a || c == 0x0b || c == 0x0c || c == 0x0d || c == 0x85)              if (c == 0x0a || c == 0x0b || c == 0x0c || c == 0x0d || c == 0x85
5891                break;  #ifdef COMPILE_PCRE16
5892                  || c == 0x2028 || c == 0x2029
5893    #endif
5894                  ) break;
5895              eptr++;              eptr++;
5896              }              }
5897            break;            break;
# Line 5685  for (;;) Line 5905  for (;;)
5905                break;                break;
5906                }                }
5907              c = *eptr;              c = *eptr;
5908              if (c != 0x0a && c != 0x0b && c != 0x0c && c != 0x0d && c != 0x85)              if (c != 0x0a && c != 0x0b && c != 0x0c && c != 0x0d && c != 0x85
5909                break;  #ifdef COMPILE_PCRE16
5910                  && c != 0x2028 && c != 0x2029
5911    #endif
5912                  ) break;
5913              eptr++;              eptr++;
5914              }              }
5915            break;            break;
# Line 5699  for (;;) Line 5922  for (;;)
5922                SCHECK_PARTIAL();                SCHECK_PARTIAL();
5923                break;                break;
5924                }                }
5925              if ((md->ctypes[*eptr] & ctype_digit) != 0) break;              if (MAX_255(*eptr) && (md->ctypes[*eptr] & ctype_digit) != 0) break;
5926              eptr++;              eptr++;
5927              }              }
5928            break;            break;
# Line 5712  for (;;) Line 5935  for (;;)
5935                SCHECK_PARTIAL();                SCHECK_PARTIAL();
5936                break;                break;
5937                }                }
5938              if ((md->ctypes[*eptr] & ctype_digit) == 0) break;              if (!MAX_255(*eptr) || (md->ctypes[*eptr] & ctype_digit) == 0) break;
5939              eptr++;              eptr++;
5940              }              }
5941            break;            break;
# Line 5725  for (;;) Line 5948  for (;;)
5948                SCHECK_PARTIAL();                SCHECK_PARTIAL();
5949                break;                break;
5950                }                }
5951              if ((md->ctypes[*eptr] & ctype_space) != 0) break;              if (MAX_255(*eptr) && (md->ctypes[*eptr] & ctype_space) != 0) break;
5952              eptr++;              eptr++;
5953              }              }
5954            break;            break;
# Line 5738  for (;;) Line 5961  for (;;)
5961                SCHECK_PARTIAL();                SCHECK_PARTIAL();
5962                break;                break;
5963                }                }
5964              if ((md->ctypes[*eptr] & ctype_space) == 0) break;              if (!MAX_255(*eptr) || (md->ctypes[*eptr] & ctype_space) == 0) break;
5965              eptr++;              eptr++;
5966              }              }
5967            break;            break;
# Line 5751  for (;;) Line 5974  for (;;)
5974                SCHECK_PARTIAL();                SCHECK_PARTIAL();
5975                break;                break;
5976                }                }
5977              if ((md->ctypes[*eptr] & ctype_word) != 0) break;              if (MAX_255(*eptr) && (md->ctypes[*eptr] & ctype_word) != 0) break;
5978              eptr++;              eptr++;
5979              }              }
5980            break;            break;
# Line 5764  for (;;) Line 5987  for (;;)
5987                SCHECK_PARTIAL();                SCHECK_PARTIAL();
5988                break;                break;
5989                }                }
5990              if ((md->ctypes[*eptr] & ctype_word) == 0) break;              if (!MAX_255(*eptr) || (md->ctypes[*eptr] & ctype_word) == 0) break;
5991              eptr++;              eptr++;
5992              }              }
5993            break;            break;
# Line 5827  switch (frame->Xwhere) Line 6050  switch (frame->Xwhere)
6050    LBL(35) LBL(43) LBL(47) LBL(48) LBL(49) LBL(50) LBL(51) LBL(52)    LBL(35) LBL(43) LBL(47) LBL(48) LBL(49) LBL(50) LBL(51) LBL(52)
6051    LBL(53) LBL(54) LBL(55) LBL(56) LBL(57) LBL(58) LBL(63) LBL(64)    LBL(53) LBL(54) LBL(55) LBL(56) LBL(57) LBL(58) LBL(63) LBL(64)
6052    LBL(65) LBL(66)    LBL(65) LBL(66)
6053  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
6054    LBL(16) LBL(18) LBL(20) LBL(21) LBL(22) LBL(23) LBL(28) LBL(30)    LBL(21)
6055    #endif
6056    #ifdef SUPPORT_UTF
6057      LBL(16) LBL(18) LBL(20)
6058      LBL(22) LBL(23) LBL(28) LBL(30)
6059    LBL(32) LBL(34) LBL(42) LBL(46)    LBL(32) LBL(34) LBL(42) LBL(46)
6060  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
6061    LBL(36) LBL(37) LBL(38) LBL(39) LBL(40) LBL(41) LBL(44) LBL(45)    LBL(36) LBL(37) LBL(38) LBL(39) LBL(40) LBL(41) LBL(44) LBL(45)
6062    LBL(59) LBL(60) LBL(61) LBL(62)    LBL(59) LBL(60) LBL(61) LBL(62)
6063  #endif  /* SUPPORT_UCP */  #endif  /* SUPPORT_UCP */
6064  #endif  /* SUPPORT_UTF8 */  #endif  /* SUPPORT_UTF */
6065    default:    default:
6066    DPRINTF(("jump error in pcre match: label %d non-existent\n", frame->Xwhere));    DPRINTF(("jump error in pcre match: label %d non-existent\n", frame->Xwhere));
6067    
6068    printf("+++jump error in pcre match: label %d non-existent\n", frame->Xwhere);
6069    
6070    return PCRE_ERROR_INTERNAL;    return PCRE_ERROR_INTERNAL;
6071    }    }
6072  #undef LBL  #undef LBL
# Line 5923  Returns:          > 0 => success; value Line 6153  Returns:          > 0 => success; value
6153                   < -1 => some kind of unexpected problem                   < -1 => some kind of unexpected problem
6154  */  */
6155    
6156    #ifdef COMPILE_PCRE8
6157  PCRE_EXP_DEFN int PCRE_CALL_CONVENTION  PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
6158  pcre_exec(const pcre *argument_re, const pcre_extra *extra_data,  pcre_exec(const pcre *argument_re, const pcre_extra *extra_data,
6159    PCRE_SPTR subject, int length, int start_offset, int options, int *offsets,    PCRE_SPTR subject, int length, int start_offset, int options, int *offsets,
6160    int offsetcount)    int offsetcount)
6161    #else
6162    PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
6163    pcre16_exec(const pcre16 *argument_re, const pcre16_extra *extra_data,
6164      PCRE_SPTR16 subject, int length, int start_offset, int options, int *offsets,
6165      int offsetcount)
6166    #endif
6167  {  {
6168  int rc, ocount, arg_offset_max;  int rc, ocount, arg_offset_max;
 int first_byte = -1;  
 int req_byte = -1;  
 int req_byte2 = -1;  
6169  int newline;  int newline;
6170  BOOL using_temporary_offsets = FALSE;  BOOL using_temporary_offsets = FALSE;
6171  BOOL anchored;  BOOL anchored;
6172  BOOL startline;  BOOL startline;
6173  BOOL firstline;  BOOL firstline;
6174  BOOL first_byte_caseless = FALSE;  BOOL utf;
6175  BOOL req_byte_caseless = FALSE;  BOOL has_first_char = FALSE;
6176  BOOL utf8;  BOOL has_req_char = FALSE;
6177    pcre_uchar first_char = 0;
6178    pcre_uchar first_char2 = 0;
6179    pcre_uchar req_char = 0;
6180    pcre_uchar req_char2 = 0;
6181  match_data match_block;  match_data match_block;
6182  match_data *md = &match_block;  match_data *md = &match_block;
6183  const uschar *tables;  const pcre_uint8 *tables;
6184  const uschar *start_bits = NULL;  const pcre_uint8 *start_bits = NULL;
6185  USPTR start_match = (USPTR)subject + start_offset;  PCRE_PUCHAR start_match = (PCRE_PUCHAR)subject + start_offset;
6186  USPTR end_subject;  PCRE_PUCHAR end_subject;
6187  USPTR start_partial = NULL;  PCRE_PUCHAR start_partial = NULL;
6188  USPTR req_byte_ptr = start_match - 1;  PCRE_PUCHAR req_char_ptr = start_match - 1;
6189    
 pcre_study_data internal_study;  
6190  const pcre_study_data *study;  const pcre_study_data *study;
6191    const REAL_PCRE *re = (const REAL_PCRE *)argument_re;
 real_pcre internal_re;  
 const real_pcre *external_re = (const real_pcre *)argument_re;  
 const real_pcre *re = external_re;  
6192    
6193  /* Plausibility checks */  /* Plausibility checks */
6194    
# Line 5969  follows immediately afterwards. Other va Line 6203  follows immediately afterwards. Other va
6203  during "normal" pcre_exec() processing, not when the JIT support is in use,  during "normal" pcre_exec() processing, not when the JIT support is in use,
6204  so they are set up later. */  so they are set up later. */
6205    
6206  utf8 = md->utf8 = (re->options & PCRE_UTF8) != 0;  /* PCRE_UTF16 has the same value as PCRE_UTF8. */
6207    utf = md->utf = (re->options & PCRE_UTF8) != 0;
6208  md->partial = ((options & PCRE_PARTIAL_HARD) != 0)? 2 :  md->partial = ((options & PCRE_PARTIAL_HARD) != 0)? 2 :
6209                ((options & PCRE_PARTIAL_SOFT) != 0)? 1 : 0;                ((options & PCRE_PARTIAL_SOFT) != 0)? 1 : 0;
6210    
6211  /* Check a UTF-8 string if required. Pass back the character offset and error  /* Check a UTF-8 string if required. Pass back the character offset and error
6212  code for an invalid string if a results vector is available. */  code for an invalid string if a results vector is available. */
6213    
6214  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
6215  if (utf8 && (options & PCRE_NO_UTF8_CHECK) == 0)  if (utf && (options & PCRE_NO_UTF8_CHECK) == 0)
6216    {    {
6217    int erroroffset;    int erroroffset;
6218    int errorcode = _pcre_valid_utf8((USPTR)subject, length, &erroroffset);    int errorcode = PRIV(valid_utf)((PCRE_PUCHAR)subject, length, &erroroffset);
6219    if (errorcode != 0)    if (errorcode != 0)
6220      {      {
6221      if (offsetcount >= 2)      if (offsetcount >= 2)
# Line 5988  if (utf8 && (options & PCRE_NO_UTF8_CHEC Line 6223  if (utf8 && (options & PCRE_NO_UTF8_CHEC
6223        offsets[0] = erroroffset;        offsets[0] = erroroffset;
6224        offsets[1] = errorcode;        offsets[1] = errorcode;
6225        }        }
6226    #ifdef COMPILE_PCRE16
6227        return (errorcode <= PCRE_UTF16_ERR1 && md->partial > 1)?
6228          PCRE_ERROR_SHORTUTF16 : PCRE_ERROR_BADUTF16;
6229    #else
6230      return (errorcode <= PCRE_UTF8_ERR5 && md->partial > 1)?      return (errorcode <= PCRE_UTF8_ERR5 && md->partial > 1)?
6231        PCRE_ERROR_SHORTUTF8 : PCRE_ERROR_BADUTF8;        PCRE_ERROR_SHORTUTF8 : PCRE_ERROR_BADUTF8;
6232    #endif
6233      }      }
6234    
6235    /* Check that a start_offset points to the start of a UTF-8 character. */    /* Check that a start_offset points to the start of a UTF character. */
6236    if (start_offset > 0 && start_offset < length &&    if (start_offset > 0 && start_offset < length &&
6237        (((USPTR)subject)[start_offset] & 0xc0) == 0x80)        NOT_FIRSTCHAR(((PCRE_PUCHAR)subject)[start_offset]))
6238      return PCRE_ERROR_BADUTF8_OFFSET;      return PCRE_ERROR_BADUTF8_OFFSET;
6239    }    }
6240  #endif  #endif
# Line 6012  if (extra_data != NULL Line 6252  if (extra_data != NULL
6252      && (extra_data->flags & PCRE_EXTRA_TABLES) == 0      && (extra_data->flags & PCRE_EXTRA_TABLES) == 0
6253      && (options & ~(PCRE_NO_UTF8_CHECK | PCRE_NOTBOL | PCRE_NOTEOL |      && (options & ~(PCRE_NO_UTF8_CHECK | PCRE_NOTBOL | PCRE_NOTEOL |
6254                      PCRE_NOTEMPTY | PCRE_NOTEMPTY_ATSTART)) == 0)                      PCRE_NOTEMPTY | PCRE_NOTEMPTY_ATSTART)) == 0)
6255    return _pcre_jit_exec(re, extra_data->executable_jit, subject, length,    return PRIV(jit_exec)(re, extra_data->executable_jit,
6256      start_offset, options, ((extra_data->flags & PCRE_EXTRA_MATCH_LIMIT) == 0)      (const pcre_uchar *)subject, length, start_offset, options,
6257        ((extra_data->flags & PCRE_EXTRA_MATCH_LIMIT) == 0)
6258      ? MATCH_LIMIT : extra_data->match_limit, offsets, offsetcount);      ? MATCH_LIMIT : extra_data->match_limit, offsets, offsetcount);
6259  #endif  #endif
6260    
6261  /* Carry on with non-JIT matching. This information is for finding all the  /* Carry on with non-JIT matching. This information is for finding all the
6262  numbers associated with a given name, for condition testing. */  numbers associated with a given name, for condition testing. */
6263    
6264  md->name_table = (uschar *)re + re->name_table_offset;  md->name_table = (pcre_uchar *)re + re->name_table_offset;
6265  md->name_count = re->name_count;  md->name_count = re->name_count;
6266  md->name_entry_size = re->name_entry_size;  md->name_entry_size = re->name_entry_size;
6267    
# Line 6034  md->callout_data = NULL; Line 6275  md->callout_data = NULL;
6275    
6276  /* The table pointer is always in native byte order. */  /* The table pointer is always in native byte order. */
6277    
6278  tables = external_re->tables;  tables = re->tables;
6279    
6280  if (extra_data != NULL)  if (extra_data != NULL)
6281    {    {
# Line 6054  if (extra_data != NULL) Line 6295  if (extra_data != NULL)
6295  is a feature that makes it possible to save compiled regex and re-use them  is a feature that makes it possible to save compiled regex and re-use them
6296  in other programs later. */  in other programs later. */
6297    
6298  if (tables == NULL) tables = _pcre_default_tables;  if (tables == NULL) tables = PRIV(default_tables);
6299    
6300  /* Check that the first field in the block is the magic number. If it is not,  /* Check that the first field in the block is the magic number. If it is not,
6301  test for a regex that was compiled on a host of opposite endianness. If this is  return with PCRE_ERROR_BADMAGIC. However, if the magic number is equal to
6302  the case, flipped values are put in internal_re and internal_study if there was  REVERSED_MAGIC_NUMBER we return with PCRE_ERROR_BADENDIANNESS, which
6303  study data too. */  means that the pattern is likely compiled with different endianness. */
6304    
6305  if (re->magic_number != MAGIC_NUMBER)  if (re->magic_number != MAGIC_NUMBER)
6306    {    return re->magic_number == REVERSED_MAGIC_NUMBER?
6307    re = _pcre_try_flipped(re, &internal_re, study, &internal_study);      PCRE_ERROR_BADENDIANNESS:PCRE_ERROR_BADMAGIC;
6308    if (re == NULL) return PCRE_ERROR_BADMAGIC;  if ((re->flags & PCRE_MODE) == 0) return PCRE_ERROR_BADMODE;
   if (study != NULL) study = &internal_study;  
   }  
6309    
6310  /* Set up other data */  /* Set up other data */
6311    
# Line 6076  firstline = (re->options & PCRE_FIRSTLIN Line 6315  firstline = (re->options & PCRE_FIRSTLIN
6315    
6316  /* The code starts after the real_pcre block and the capture name table. */  /* The code starts after the real_pcre block and the capture name table. */
6317    
6318  md->start_code = (const uschar *)external_re + re->name_table_offset +  md->start_code = (const pcre_uchar *)re + re->name_table_offset +
6319    re->name_count * re->name_entry_size;    re->name_count * re->name_entry_size;
6320    
6321  md->start_subject = (USPTR)subject;  md->start_subject = (PCRE_PUCHAR)subject;
6322  md->start_offset = start_offset;  md->start_offset = start_offset;
6323  md->end_subject = md->start_subject + length;  md->end_subject = md->start_subject + length;
6324  end_subject = md->end_subject;  end_subject = md->end_subject;
# Line 6104  md->recursive = NULL; Line 6343  md->recursive = NULL;
6343  md->hasthen = (re->flags & PCRE_HASTHEN) != 0;  md->hasthen = (re->flags & PCRE_HASTHEN) != 0;
6344    
6345  md->lcc = tables + lcc_offset;  md->lcc = tables + lcc_offset;
6346    md->fcc = tables + fcc_offset;
6347  md->ctypes = tables + ctypes_offset;  md->ctypes = tables + ctypes_offset;
6348    
6349  /* Handle different \R options. */  /* Handle different \R options. */
# Line 6190  arg_offset_max = (2*ocount)/3; Line 6430  arg_offset_max = (2*ocount)/3;
6430  if (re->top_backref > 0 && re->top_backref >= ocount/3)  if (re->top_backref > 0 && re->top_backref >= ocount/3)
6431    {    {
6432    ocount = re->top_backref * 3 + 3;    ocount = re->top_backref * 3 + 3;
6433    md->offset_vector = (int *)(pcre_malloc)(ocount * sizeof(int));    md->offset_vector = (int *)(PUBL(malloc))(ocount * sizeof(int));
6434    if (md->offset_vector == NULL) return PCRE_ERROR_NOMEMORY;    if (md->offset_vector == NULL) return PCRE_ERROR_NOMEMORY;
6435    using_temporary_offsets = TRUE;    using_temporary_offsets = TRUE;
6436    DPRINTF(("Got memory to hold back references\n"));    DPRINTF(("Got memory to hold back references\n"));
# Line 6217  if (md->offset_vector != NULL) Line 6457  if (md->offset_vector != NULL)
6457    md->offset_vector[0] = md->offset_vector[1] = -1;    md->offset_vector[0] = md->offset_vector[1] = -1;
6458    }    }
6459    
6460  /* Set up the first character to match, if available. The first_byte value is  /* Set up the first character to match, if available. The first_char value is
6461  never set for an anchored regular expression, but the anchoring may be forced  never set for an anchored regular expression, but the anchoring may be forced
6462  at run time, so we have to test for anchoring. The first char may be unset for  at run time, so we have to test for anchoring. The first char may be unset for
6463  an unanchored pattern, of course. If there's no first char and the pattern was  an unanchored pattern, of course. If there's no first char and the pattern was
# Line 6227  if (!anchored) Line 6467  if (!anchored)
6467    {    {
6468    if ((re->flags & PCRE_FIRSTSET) != 0)    if ((re->flags & PCRE_FIRSTSET) != 0)
6469      {      {
6470      first_byte = re->first_byte & 255;      has_first_char = TRUE;
6471      if ((first_byte_caseless = ((re->first_byte & REQ_CASELESS) != 0)) == TRUE)      first_char = first_char2 = re->first_char;
6472        first_byte = md->lcc[first_byte];      if ((re->flags & PCRE_FCH_CASELESS) != 0)
6473          {
6474          first_char2 = TABLE_GET(first_char, md->fcc, first_char);
6475    #if defined SUPPORT_UCP && !(defined COMPILE_PCRE8)
6476          if (utf && first_char > 127)
6477            first_char2 = UCD_OTHERCASE(first_char);
6478    #endif
6479          }
6480      }      }
6481    else    else
6482      if (!startline && study != NULL &&      if (!startline && study != NULL &&
# Line 6242  character" set. */ Line 6489  character" set. */
6489    
6490  if ((re->flags & PCRE_REQCHSET) != 0)  if ((re->flags & PCRE_REQCHSET) != 0)
6491    {    {
6492    req_byte = re->req_byte & 255;    has_req_char = TRUE;
6493    req_byte_caseless = (re->req_byte & REQ_CASELESS) != 0;    req_char = req_char2 = re->req_char;
6494    req_byte2 = (tables + fcc_offset)[req_byte];  /* case flipped */    if ((re->flags & PCRE_RCH_CASELESS) != 0)
6495        {
6496        req_char2 = TABLE_GET(req_char, md->fcc, req_char);
6497    #if defined SUPPORT_UCP && !(defined COMPILE_PCRE8)
6498        if (utf && req_char > 127)
6499          req_char2 = UCD_OTHERCASE(req_char);
6500    #endif
6501        }
6502    }    }
6503    
6504    
   
   
6505  /* ==========================================================================*/  /* ==========================================================================*/
6506    
6507  /* Loop for handling unanchored repeated matching attempts; for anchored regexs  /* Loop for handling unanchored repeated matching attempts; for anchored regexs
# Line 6257  the loop runs just once. */ Line 6509  the loop runs just once. */
6509    
6510  for(;;)  for(;;)
6511    {    {
6512    USPTR save_end_subject = end_subject;    PCRE_PUCHAR save_end_subject = end_subject;
6513    USPTR new_start_match;    PCRE_PUCHAR new_start_match;
6514    
6515    /* If firstline is TRUE, the start of the match is constrained to the first    /* If firstline is TRUE, the start of the match is constrained to the first
6516    line of a multiline string. That is, the match must be before or at the first    line of a multiline string. That is, the match must be before or at the first
# Line 6268  for(;;) Line 6520  for(;;)
6520    
6521    if (firstline)    if (firstline)
6522      {      {
6523      USPTR t = start_match;      PCRE_PUCHAR t = start_match;
6524  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
6525      if (utf8)      if (utf)
6526        {        {
6527        while (t < md->end_subject && !IS_NEWLINE(t))        while (t < md->end_subject && !IS_NEWLINE(t))
6528          {          {
6529          t++;          t++;
6530          while (t < end_subject && (*t & 0xc0) == 0x80) t++;          ACROSSCHAR(t < end_subject, *t, t++);
6531          }          }
6532        }        }
6533      else      else
# Line 6292  for(;;) Line 6544  for(;;)
6544    
6545    if (((options | re->options) & PCRE_NO_START_OPTIMIZE) == 0)    if (((options | re->options) & PCRE_NO_START_OPTIMIZE) == 0)
6546      {      {
6547      /* Advance to a unique first byte if there is one. */      /* Advance to a unique first char if there is one. */
6548    
6549      if (first_byte >= 0)      if (has_first_char)
6550        {        {
6551        if (first_byte_caseless)        if (first_char != first_char2)
6552          while (start_match < end_subject && md->lcc[*start_match] != first_byte)          while (start_match < end_subject &&
6553                *start_match != first_char && *start_match != first_char2)
6554            start_match++;            start_match++;
6555        else        else
6556          while (start_match < end_subject && *start_match != first_byte)          while (start_match < end_subject && *start_match != first_char)
6557            start_match++;            start_match++;
6558        }        }
6559    
# Line 6310  for(;;) Line 6563  for(;;)
6563        {        {
6564        if (start_match > md->start_subject + start_offset)        if (start_match > md->start_subject + start_offset)
6565          {          {
6566  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
6567          if (utf8)          if (utf)
6568            {            {
6569            while (start_match < end_subject && !WAS_NEWLINE(start_match))            while (start_match < end_subject && !WAS_NEWLINE(start_match))
6570              {              {
6571              start_match++;              start_match++;
6572              while(start_match < end_subject && (*start_match & 0xc0) == 0x80)              ACROSSCHAR(start_match < end_subject, *start_match,
6573                start_match++;                start_match++);
6574              }              }
6575            }            }
6576          else          else
# Line 6344  for(;;) Line 6597  for(;;)
6597        while (start_match < end_subject)        while (start_match < end_subject)
6598          {          {
6599          register unsigned int c = *start_match;          register unsigned int c = *start_match;
6600    #ifndef COMPILE_PCRE8
6601            if (c > 255) c = 255;
6602    #endif
6603          if ((start_bits[c/8] & (1 << (c&7))) == 0)          if ((start_bits[c/8] & (1 << (c&7))) == 0)
6604            {            {
6605            start_match++;            start_match++;
6606  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF && defined COMPILE_PCRE8
6607            if (utf8)            /* In non 8-bit mode, the iteration will stop for
6608              while(start_match < end_subject && (*start_match & 0xc0) == 0x80)            characters > 255 at the beginning or not stop at all. */
6609                start_match++;            if (utf)
6610                ACROSSCHAR(start_match < end_subject, *start_match,
6611                  start_match++);
6612  #endif  #endif
6613            }            }
6614          else break;          else break;
# Line 6379  for(;;) Line 6637  for(;;)
6637        break;        break;
6638        }        }
6639    
6640      /* If req_byte is set, we know that that character must appear in the      /* If req_char is set, we know that that character must appear in the
6641      subject for the match to succeed. If the first character is set, req_byte      subject for the match to succeed. If the first character is set, req_char
6642      must be later in the subject; otherwise the test starts at the match point.      must be later in the subject; otherwise the test starts at the match point.
6643      This optimization can save a huge amount of backtracking in patterns with      This optimization can save a huge amount of backtracking in patterns with
6644      nested unlimited repeats that aren't going to match. Writing separate code      nested unlimited repeats that aren't going to match. Writing separate code
# Line 6393  for(;;) Line 6651  for(;;)
6651      32-megabyte string... so we don't do this when the string is sufficiently      32-megabyte string... so we don't do this when the string is sufficiently
6652      long. */      long. */
6653    
6654      if (req_byte >= 0 && end_subject - start_match < REQ_BYTE_MAX)      if (has_req_char && end_subject - start_match < REQ_BYTE_MAX)
6655        {        {
6656        register USPTR p = start_match + ((first_byte >= 0)? 1 : 0);        register PCRE_PUCHAR p = start_match + (has_first_char? 1:0);
6657    
6658        /* We don't need to repeat the search if we haven't yet reached the        /* We don't need to repeat the search if we haven't yet reached the
6659        place we found it at last time. */        place we found it at last time. */
6660    
6661        if (p > req_byte_ptr)        if (p > req_char_ptr)
6662          {          {
6663          if (req_byte_caseless)          if (req_char != req_char2)
6664            {            {
6665            while (p < end_subject)            while (p < end_subject)
6666              {              {
6667              register int pp = *p++;              register int pp = *p++;
6668              if (pp == req_byte || pp == req_byte2) { p--; break; }              if (pp == req_char || pp == req_char2) { p--; break; }
6669              }              }
6670            }            }
6671          else          else
6672            {            {
6673            while (p < end_subject)            while (p < end_subject)
6674              {              {
6675              if (*p++ == req_byte) { p--; break; }              if (*p++ == req_char) { p--; break; }
6676              }              }
6677            }            }
6678    
# Line 6431  for(;;) Line 6689  for(;;)
6689          found it, so that we don't search again next time round the loop if          found it, so that we don't search again next time round the loop if
6690          the start hasn't passed this character yet. */          the start hasn't passed this character yet. */
6691    
6692          req_byte_ptr = p;          req_char_ptr = p;
6693          }          }
6694        }        }
6695      }      }
# Line 6486  for(;;) Line 6744  for(;;)
6744      case MATCH_THEN:      case MATCH_THEN:
6745      md->ignore_skip_arg = FALSE;      md->ignore_skip_arg = FALSE;
6746      new_start_match = start_match + 1;      new_start_match = start_match + 1;
6747  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
6748      if (utf8)      if (utf)
6749        while(new_start_match < end_subject && (*new_start_match & 0xc0) == 0x80)        ACROSSCHAR(new_start_match < end_subject, *new_start_match,
6750          new_start_match++;          new_start_match++);
6751  #endif  #endif
6752      break;      break;
6753    
# Line 6527  for(;;) Line 6785  for(;;)
6785    
6786    /* If we have just passed a CR and we are now at a LF, and the pattern does    /* If we have just passed a CR and we are now at a LF, and the pattern does
6787    not contain any explicit matches for \r or \n, and the newline option is CRLF    not contain any explicit matches for \r or \n, and the newline option is CRLF
6788    or ANY or ANYCRLF, advance the match position by one more character. */    or ANY or ANYCRLF, advance the match position by one more character. In
6789      normal matching start_match will aways be greater than the first position at
6790      this stage, but a failed *SKIP can cause a return at the same point, which is
6791      why the first test exists. */
6792    
6793    if (start_match[-1] == CHAR_CR &&    if (start_match > (PCRE_PUCHAR)subject + start_offset &&
6794          start_match[-1] == CHAR_CR &&
6795        start_match < end_subject &&        start_match < end_subject &&
6796        *start_match == CHAR_NL &&        *start_match == CHAR_NL &&
6797        (re->flags & PCRE_HASCRORLF) == 0 &&        (re->flags & PCRE_HASCRORLF) == 0 &&
# Line 6575  if (rc == MATCH_MATCH || rc == MATCH_ACC Line 6837  if (rc == MATCH_MATCH || rc == MATCH_ACC
6837        }        }
6838      if (md->end_offset_top > arg_offset_max) md->offset_overflow = TRUE;      if (md->end_offset_top > arg_offset_max) md->offset_overflow = TRUE;
6839      DPRINTF(("Freeing temporary memory\n"));      DPRINTF(("Freeing temporary memory\n"));
6840      (pcre_free)(md->offset_vector);      (PUBL(free))(md->offset_vector);
6841      }      }
6842    
6843    /* Set the return code to the number of captured strings, or 0 if there were    /* Set the return code to the number of captured strings, or 0 if there were
# Line 6616  if (rc == MATCH_MATCH || rc == MATCH_ACC Line 6878  if (rc == MATCH_MATCH || rc == MATCH_ACC
6878    /* Return MARK data if requested */    /* Return MARK data if requested */
6879    
6880    if (extra_data != NULL && (extra_data->flags & PCRE_EXTRA_MARK) != 0)    if (extra_data != NULL && (extra_data->flags & PCRE_EXTRA_MARK) != 0)
6881      *(extra_data->mark) = (unsigned char *)(md->mark);      *(extra_data->mark) = (pcre_uchar *)md->mark;
6882    DPRINTF((">>>> returning %d\n", rc));    DPRINTF((">>>> returning %d\n", rc));
6883    return rc;    return rc;
6884    }    }
# Line 6627  attempt has failed at all permitted star Line 6889  attempt has failed at all permitted star
6889  if (using_temporary_offsets)  if (using_temporary_offsets)
6890    {    {
6891    DPRINTF(("Freeing temporary memory\n"));    DPRINTF(("Freeing temporary memory\n"));
6892    (pcre_free)(md->offset_vector);    (PUBL(free))(md->offset_vector);
6893    }    }
6894    
6895  /* For anything other than nomatch or partial match, just return the code. */  /* For anything other than nomatch or partial match, just return the code. */
# Line 6646  if (start_partial != NULL) Line 6908  if (start_partial != NULL)
6908    md->mark = NULL;    md->mark = NULL;
6909    if (offsetcount > 1)    if (offsetcount > 1)
6910      {      {
6911      offsets[0] = (int)(start_partial - (USPTR)subject);      offsets[0] = (int)(start_partial - (PCRE_PUCHAR)subject);
6912      offsets[1] = (int)(end_subject - (USPTR)subject);      offsets[1] = (int)(end_subject - (PCRE_PUCHAR)subject);
6913      }      }
6914    rc = PCRE_ERROR_PARTIAL;    rc = PCRE_ERROR_PARTIAL;
6915    }    }
# Line 6663  else Line 6925  else
6925  /* Return the MARK data if it has been requested. */  /* Return the MARK data if it has been requested. */
6926    
6927  if (extra_data != NULL && (extra_data->flags & PCRE_EXTRA_MARK) != 0)  if (extra_data != NULL && (extra_data->flags & PCRE_EXTRA_MARK) != 0)
6928    *(extra_data->mark) = (unsigned char *)(md->nomatch_mark);    *(extra_data->mark) = (pcre_uchar *)md->nomatch_mark;
6929  return rc;  return rc;
6930  }  }
6931    

Legend:
Removed from v.788  
changed lines
  Added in v.892

  ViewVC Help
Powered by ViewVC 1.1.5