/[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 779 by ph10, Fri Dec 2 10:39:32 2011 UTC revision 882 by ph10, Sun Jan 15 18:45:27 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);\    (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;
# Line 485  heap storage. Set up the top-level frame Line 490  heap storage. Set up the top-level frame
490  heap whenever RMATCH() does a "recursion". See the macro definitions above. */  heap whenever RMATCH() does a "recursion". See the macro definitions above. */
491    
492  #ifdef NO_RECURSE  #ifdef NO_RECURSE
493  heapframe *frame = (heapframe *)(pcre_stack_malloc)(sizeof(heapframe));  heapframe *frame = (heapframe *)(PUBL(stack_malloc))(sizeof(heapframe));
494  if (frame == NULL) RRETURN(PCRE_ERROR_NOMEMORY);  if (frame == NULL) RRETURN(PCRE_ERROR_NOMEMORY);
495  frame->Xprevframe = NULL;            /* Marks the top level */  frame->Xprevframe = NULL;            /* Marks the top level */
496    
# Line 513  HEAP_RECURSE: Line 518  HEAP_RECURSE:
518    
519  /* Ditto for the local variables */  /* Ditto for the local variables */
520    
521  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
522  #define charptr            frame->Xcharptr  #define charptr            frame->Xcharptr
523  #endif  #endif
524  #define callpat            frame->Xcallpat  #define callpat            frame->Xcallpat
# Line 571  declarations can be cut out in a block. Line 576  declarations can be cut out in a block.
576  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
577  to RMATCH(). */  to RMATCH(). */
578    
579  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
580  const uschar *charptr;  const pcre_uchar *charptr;
581  #endif  #endif
582  const uschar *callpat;  const pcre_uchar *callpat;
583  const uschar *data;  const pcre_uchar *data;
584  const uschar *next;  const pcre_uchar *next;
585  USPTR         pp;  PCRE_PUCHAR       pp;
586  const uschar *prev;  const pcre_uchar *prev;
587  USPTR         saved_eptr;  PCRE_PUCHAR       saved_eptr;
588    
589  recursion_info new_recursive;  recursion_info new_recursive;
590    
# Line 592  int prop_type; Line 597  int prop_type;
597  int prop_value;  int prop_value;
598  int prop_fail_result;  int prop_fail_result;
599  int oclength;  int oclength;
600  uschar occhars[8];  pcre_uchar occhars[6];
601  #endif  #endif
602    
603  int codelink;  int codelink;
# Line 620  the alternative names that are used. */ Line 625  the alternative names that are used. */
625  #define code_offset   codelink  #define code_offset   codelink
626  #define condassert    condition  #define condassert    condition
627  #define matched_once  prev_is_word  #define matched_once  prev_is_word
628    #define foc           number
629    #define save_mark     data
630    
631  /* These statements are here to stop the compiler complaining about unitialized  /* These statements are here to stop the compiler complaining about unitialized
632  variables. */  variables. */
# Line 645  defined). However, RMATCH isn't like a f Line 652  defined). However, RMATCH isn't like a f
652  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,
653  however, impact performance when true recursion is being used. */  however, impact performance when true recursion is being used. */
654    
655  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
656  utf8 = md->utf8;       /* Local copy of the flag */  utf = md->utf;       /* Local copy of the flag */
657  #else  #else
658  utf8 = FALSE;  utf = FALSE;
659  #endif  #endif
660    
661  /* 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 696  for (;;)
696      case OP_MARK:      case OP_MARK:
697      md->nomatch_mark = ecode + 2;      md->nomatch_mark = ecode + 2;
698      md->mark = NULL;    /* In case previously set by assertion */      md->mark = NULL;    /* In case previously set by assertion */
699      RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode] + ecode[1], offset_top, md,      RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode] + ecode[1], offset_top, md,
700        eptrb, RM55);        eptrb, RM55);
701      if ((rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) &&      if ((rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) &&
702           md->mark == NULL) md->mark = ecode + 2;           md->mark == NULL) md->mark = ecode + 2;
# Line 702  for (;;) Line 709  for (;;)
709      unaltered. */      unaltered. */
710    
711      else if (rrc == MATCH_SKIP_ARG &&      else if (rrc == MATCH_SKIP_ARG &&
712          strcmp((char *)(ecode + 2), (char *)(md->start_match_ptr)) == 0)          STRCMP_UC_UC(ecode + 2, md->start_match_ptr) == 0)
713        {        {
714        md->start_match_ptr = eptr;        md->start_match_ptr = eptr;
715        RRETURN(MATCH_SKIP);        RRETURN(MATCH_SKIP);
# Line 715  for (;;) Line 722  for (;;)
722      /* COMMIT overrides PRUNE, SKIP, and THEN */      /* COMMIT overrides PRUNE, SKIP, and THEN */
723    
724      case OP_COMMIT:      case OP_COMMIT:
725      RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,      RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md,
726        eptrb, RM52);        eptrb, RM52);
727      if (rrc != MATCH_NOMATCH && rrc != MATCH_PRUNE &&      if (rrc != MATCH_NOMATCH && rrc != MATCH_PRUNE &&
728          rrc != MATCH_SKIP && rrc != MATCH_SKIP_ARG &&          rrc != MATCH_SKIP && rrc != MATCH_SKIP_ARG &&
# Line 726  for (;;) Line 733  for (;;)
733      /* PRUNE overrides THEN */      /* PRUNE overrides THEN */
734    
735      case OP_PRUNE:      case OP_PRUNE:
736      RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,      RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md,
737        eptrb, RM51);        eptrb, RM51);
738      if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);      if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);
739      RRETURN(MATCH_PRUNE);      RRETURN(MATCH_PRUNE);
# Line 734  for (;;) Line 741  for (;;)
741      case OP_PRUNE_ARG:      case OP_PRUNE_ARG:
742      md->nomatch_mark = ecode + 2;      md->nomatch_mark = ecode + 2;
743      md->mark = NULL;    /* In case previously set by assertion */      md->mark = NULL;    /* In case previously set by assertion */
744      RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode] + ecode[1], offset_top, md,      RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode] + ecode[1], offset_top, md,
745        eptrb, RM56);        eptrb, RM56);
746      if ((rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) &&      if ((rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) &&
747           md->mark == NULL) md->mark = ecode + 2;           md->mark == NULL) md->mark = ecode + 2;
# Line 744  for (;;) Line 751  for (;;)
751      /* SKIP overrides PRUNE and THEN */      /* SKIP overrides PRUNE and THEN */
752    
753      case OP_SKIP:      case OP_SKIP:
754      RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,      RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md,
755        eptrb, RM53);        eptrb, RM53);
756      if (rrc != MATCH_NOMATCH && rrc != MATCH_PRUNE && rrc != MATCH_THEN)      if (rrc != MATCH_NOMATCH && rrc != MATCH_PRUNE && rrc != MATCH_THEN)
757        RRETURN(rrc);        RRETURN(rrc);
# Line 752  for (;;) Line 759  for (;;)
759      RRETURN(MATCH_SKIP);      RRETURN(MATCH_SKIP);
760    
761      /* Note that, for Perl compatibility, SKIP with an argument does NOT set      /* Note that, for Perl compatibility, SKIP with an argument does NOT set
762      nomatch_mark. There is a flag that disables this opcode when re-matching a      nomatch_mark. There is a flag that disables this opcode when re-matching a
763      pattern that ended with a SKIP for which there was not a matching MARK. */      pattern that ended with a SKIP for which there was not a matching MARK. */
764    
765      case OP_SKIP_ARG:      case OP_SKIP_ARG:
766      if (md->ignore_skip_arg)      if (md->ignore_skip_arg)
767        {        {
768        ecode += _pcre_OP_lengths[*ecode] + ecode[1];        ecode += PRIV(OP_lengths)[*ecode] + ecode[1];
769        break;        break;
770        }        }
771      RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode] + ecode[1], offset_top, md,      RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode] + ecode[1], offset_top, md,
772        eptrb, RM57);        eptrb, RM57);
773      if (rrc != MATCH_NOMATCH && rrc != MATCH_PRUNE && rrc != MATCH_THEN)      if (rrc != MATCH_NOMATCH && rrc != MATCH_PRUNE && rrc != MATCH_THEN)
774        RRETURN(rrc);        RRETURN(rrc);
775    
776      /* Pass back the current skip name by overloading md->start_match_ptr and      /* Pass back the current skip name by overloading md->start_match_ptr and
777      returning the special MATCH_SKIP_ARG return code. This will either be      returning the special MATCH_SKIP_ARG return code. This will either be
778      caught by a matching MARK, or get to the top, where it causes a rematch      caught by a matching MARK, or get to the top, where it causes a rematch
779      with the md->ignore_skip_arg flag set. */      with the md->ignore_skip_arg flag set. */
780    
781      md->start_match_ptr = ecode + 2;      md->start_match_ptr = ecode + 2;
# Line 779  for (;;) Line 786  for (;;)
786      match pointer to do this. */      match pointer to do this. */
787    
788      case OP_THEN:      case OP_THEN:
789      RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,      RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md,
790        eptrb, RM54);        eptrb, RM54);
791      if (rrc != MATCH_NOMATCH) RRETURN(rrc);      if (rrc != MATCH_NOMATCH) RRETURN(rrc);
792      md->start_match_ptr = ecode;      md->start_match_ptr = ecode;
# Line 788  for (;;) Line 795  for (;;)
795      case OP_THEN_ARG:      case OP_THEN_ARG:
796      md->nomatch_mark = ecode + 2;      md->nomatch_mark = ecode + 2;
797      md->mark = NULL;    /* In case previously set by assertion */      md->mark = NULL;    /* In case previously set by assertion */
798      RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode] + ecode[1], offset_top,      RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode] + ecode[1], offset_top,
799        md, eptrb, RM58);        md, eptrb, RM58);
800      if ((rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) &&      if ((rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) &&
801           md->mark == NULL) md->mark = ecode + 2;           md->mark == NULL) md->mark = ecode + 2;
# Line 812  for (;;) Line 819  for (;;)
819      case OP_ONCE_NC:      case OP_ONCE_NC:
820      prev = ecode;      prev = ecode;
821      saved_eptr = eptr;      saved_eptr = eptr;
822        save_mark = md->mark;
823      do      do
824        {        {
825        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 838  for (;;)
838    
839        if (rrc != MATCH_NOMATCH) RRETURN(rrc);        if (rrc != MATCH_NOMATCH) RRETURN(rrc);
840        ecode += GET(ecode,1);        ecode += GET(ecode,1);
841          md->mark = save_mark;
842        }        }
843      while (*ecode == OP_ALT);      while (*ecode == OP_ALT);
844    
# Line 909  for (;;) Line 918  for (;;)
918        save_offset2 = md->offset_vector[offset+1];        save_offset2 = md->offset_vector[offset+1];
919        save_offset3 = md->offset_vector[md->offset_end - number];        save_offset3 = md->offset_vector[md->offset_end - number];
920        save_capture_last = md->capture_last;        save_capture_last = md->capture_last;
921          save_mark = md->mark;
922    
923        DPRINTF(("saving %d %d %d\n", save_offset1, save_offset2, save_offset3));        DPRINTF(("saving %d %d %d\n", save_offset1, save_offset2, save_offset3));
924        md->offset_vector[md->offset_end - number] =        md->offset_vector[md->offset_end - number] =
# Line 917  for (;;) Line 927  for (;;)
927        for (;;)        for (;;)
928          {          {
929          if (op >= OP_SBRA) md->match_function_type = MATCH_CBEGROUP;          if (op >= OP_SBRA) md->match_function_type = MATCH_CBEGROUP;
930          RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,          RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md,
931            eptrb, RM1);            eptrb, RM1);
932          if (rrc == MATCH_ONCE) break;  /* Backing up through an atomic group */          if (rrc == MATCH_ONCE) break;  /* Backing up through an atomic group */
933    
# Line 945  for (;;) Line 955  for (;;)
955          if (rrc != MATCH_NOMATCH) RRETURN(rrc);          if (rrc != MATCH_NOMATCH) RRETURN(rrc);
956          md->capture_last = save_capture_last;          md->capture_last = save_capture_last;
957          ecode += GET(ecode, 1);          ecode += GET(ecode, 1);
958            md->mark = save_mark;
959          if (*ecode != OP_ALT) break;          if (*ecode != OP_ALT) break;
960          }          }
961    
# Line 1004  for (;;) Line 1015  for (;;)
1015    
1016        else if (!md->hasthen && ecode[GET(ecode, 1)] != OP_ALT)        else if (!md->hasthen && ecode[GET(ecode, 1)] != OP_ALT)
1017          {          {
1018          ecode += _pcre_OP_lengths[*ecode];          ecode += PRIV(OP_lengths)[*ecode];
1019          goto TAIL_RECURSE;          goto TAIL_RECURSE;
1020          }          }
1021    
1022        /* In all other cases, we have to make another call to match(). */        /* In all other cases, we have to make another call to match(). */
1023    
1024        RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md, eptrb,        save_mark = md->mark;
1025          RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md, eptrb,
1026          RM2);          RM2);
1027    
1028        /* See comment in the code for capturing groups above about handling        /* See comment in the code for capturing groups above about handling
1029        THEN. */        THEN. */
1030    
# Line 1028  for (;;) Line 1040  for (;;)
1040          {          {
1041          if (rrc == MATCH_ONCE)          if (rrc == MATCH_ONCE)
1042            {            {
1043            const uschar *scode = ecode;            const pcre_uchar *scode = ecode;
1044            if (*scode != OP_ONCE)           /* If not at start, find it */            if (*scode != OP_ONCE)           /* If not at start, find it */
1045              {              {
1046              while (*scode == OP_ALT) scode += GET(scode, 1);              while (*scode == OP_ALT) scode += GET(scode, 1);
# Line 1039  for (;;) Line 1051  for (;;)
1051          RRETURN(rrc);          RRETURN(rrc);
1052          }          }
1053        ecode += GET(ecode, 1);        ecode += GET(ecode, 1);
1054          md->mark = save_mark;
1055        if (*ecode != OP_ALT) break;        if (*ecode != OP_ALT) break;
1056        }        }
1057    
# Line 1093  for (;;) Line 1106  for (;;)
1106          md->offset_vector[md->offset_end - number] =          md->offset_vector[md->offset_end - number] =
1107            (int)(eptr - md->start_subject);            (int)(eptr - md->start_subject);
1108          if (op >= OP_SBRA) md->match_function_type = MATCH_CBEGROUP;          if (op >= OP_SBRA) md->match_function_type = MATCH_CBEGROUP;
1109          RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,          RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md,
1110            eptrb, RM63);            eptrb, RM63);
1111          if (rrc == MATCH_KETRPOS)          if (rrc == MATCH_KETRPOS)
1112            {            {
# Line 1165  for (;;) Line 1178  for (;;)
1178      for (;;)      for (;;)
1179        {        {
1180        if (op >= OP_SBRA) md->match_function_type = MATCH_CBEGROUP;        if (op >= OP_SBRA) md->match_function_type = MATCH_CBEGROUP;
1181        RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,        RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md,
1182          eptrb, RM48);          eptrb, RM48);
1183        if (rrc == MATCH_KETRPOS)        if (rrc == MATCH_KETRPOS)
1184          {          {
# Line 1215  for (;;) Line 1228  for (;;)
1228    
1229      if (ecode[LINK_SIZE+1] == OP_CALLOUT)      if (ecode[LINK_SIZE+1] == OP_CALLOUT)
1230        {        {
1231        if (pcre_callout != NULL)        if (PUBL(callout) != NULL)
1232          {          {
1233          pcre_callout_block cb;          PUBL(callout_block) cb;
1234          cb.version          = 2;   /* Version 1 of the callout block */          cb.version          = 2;   /* Version 1 of the callout block */
1235          cb.callout_number   = ecode[LINK_SIZE+2];          cb.callout_number   = ecode[LINK_SIZE+2];
1236          cb.offset_vector    = md->offset_vector;          cb.offset_vector    = md->offset_vector;
1237    #ifdef COMPILE_PCRE8
1238          cb.subject          = (PCRE_SPTR)md->start_subject;          cb.subject          = (PCRE_SPTR)md->start_subject;
1239    #else
1240            cb.subject          = (PCRE_SPTR16)md->start_subject;
1241    #endif
1242          cb.subject_length   = (int)(md->end_subject - md->start_subject);          cb.subject_length   = (int)(md->end_subject - md->start_subject);
1243          cb.start_match      = (int)(mstart - md->start_subject);          cb.start_match      = (int)(mstart - md->start_subject);
1244          cb.current_position = (int)(eptr - md->start_subject);          cb.current_position = (int)(eptr - md->start_subject);
# Line 1231  for (;;) Line 1248  for (;;)
1248          cb.capture_last     = md->capture_last;          cb.capture_last     = md->capture_last;
1249          cb.callout_data     = md->callout_data;          cb.callout_data     = md->callout_data;
1250          cb.mark             = md->nomatch_mark;          cb.mark             = md->nomatch_mark;
1251          if ((rrc = (*pcre_callout)(&cb)) > 0) RRETURN(MATCH_NOMATCH);          if ((rrc = (*PUBL(callout))(&cb)) > 0) RRETURN(MATCH_NOMATCH);
1252          if (rrc < 0) RRETURN(rrc);          if (rrc < 0) RRETURN(rrc);
1253          }          }
1254        ecode += _pcre_OP_lengths[OP_CALLOUT];        ecode += PRIV(OP_lengths)[OP_CALLOUT];
1255        }        }
1256    
1257      condcode = ecode[LINK_SIZE+1];      condcode = ecode[LINK_SIZE+1];
# Line 1260  for (;;) Line 1277  for (;;)
1277    
1278          if (!condition && condcode == OP_NRREF)          if (!condition && condcode == OP_NRREF)
1279            {            {
1280            uschar *slotA = md->name_table;            pcre_uchar *slotA = md->name_table;
1281            for (i = 0; i < md->name_count; i++)            for (i = 0; i < md->name_count; i++)
1282              {              {
1283              if (GET2(slotA, 0) == recno) break;              if (GET2(slotA, 0) == recno) break;
# Line 1273  for (;;) Line 1290  for (;;)
1290    
1291            if (i < md->name_count)            if (i < md->name_count)
1292              {              {
1293              uschar *slotB = slotA;              pcre_uchar *slotB = slotA;
1294              while (slotB > md->name_table)              while (slotB > md->name_table)
1295                {                {
1296                slotB -= md->name_entry_size;                slotB -= md->name_entry_size;
1297                if (strcmp((char *)slotA + 2, (char *)slotB + 2) == 0)                if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
1298                  {                  {
1299                  condition = GET2(slotB, 0) == md->recursive->group_num;                  condition = GET2(slotB, 0) == md->recursive->group_num;
1300                  if (condition) break;                  if (condition) break;
# Line 1293  for (;;) Line 1310  for (;;)
1310                for (i++; i < md->name_count; i++)                for (i++; i < md->name_count; i++)
1311                  {                  {
1312                  slotB += md->name_entry_size;                  slotB += md->name_entry_size;
1313                  if (strcmp((char *)slotA + 2, (char *)slotB + 2) == 0)                  if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
1314                    {                    {
1315                    condition = GET2(slotB, 0) == md->recursive->group_num;                    condition = GET2(slotB, 0) == md->recursive->group_num;
1316                    if (condition) break;                    if (condition) break;
# Line 1306  for (;;) Line 1323  for (;;)
1323    
1324          /* Chose branch according to the condition */          /* Chose branch according to the condition */
1325    
1326          ecode += condition? 3 : GET(ecode, 1);          ecode += condition? 1 + IMM2_SIZE : GET(ecode, 1);
1327          }          }
1328        }        }
1329    
# Line 1323  for (;;) Line 1340  for (;;)
1340        if (!condition && condcode == OP_NCREF)        if (!condition && condcode == OP_NCREF)
1341          {          {
1342          int refno = offset >> 1;          int refno = offset >> 1;
1343          uschar *slotA = md->name_table;          pcre_uchar *slotA = md->name_table;
1344    
1345          for (i = 0; i < md->name_count; i++)          for (i = 0; i < md->name_count; i++)
1346            {            {
# Line 1337  for (;;) Line 1354  for (;;)
1354    
1355          if (i < md->name_count)          if (i < md->name_count)
1356            {            {
1357            uschar *slotB = slotA;            pcre_uchar *slotB = slotA;
1358            while (slotB > md->name_table)            while (slotB > md->name_table)
1359              {              {
1360              slotB -= md->name_entry_size;              slotB -= md->name_entry_size;
1361              if (strcmp((char *)slotA + 2, (char *)slotB + 2) == 0)              if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
1362                {                {
1363                offset = GET2(slotB, 0) << 1;                offset = GET2(slotB, 0) << 1;
1364                condition = offset < offset_top &&                condition = offset < offset_top &&
# Line 1359  for (;;) Line 1376  for (;;)
1376              for (i++; i < md->name_count; i++)              for (i++; i < md->name_count; i++)
1377                {                {
1378                slotB += md->name_entry_size;                slotB += md->name_entry_size;
1379                if (strcmp((char *)slotA + 2, (char *)slotB + 2) == 0)                if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
1380                  {                  {
1381                  offset = GET2(slotB, 0) << 1;                  offset = GET2(slotB, 0) << 1;
1382                  condition = offset < offset_top &&                  condition = offset < offset_top &&
# Line 1374  for (;;) Line 1391  for (;;)
1391    
1392        /* Chose branch according to the condition */        /* Chose branch according to the condition */
1393    
1394        ecode += condition? 3 : GET(ecode, 1);        ecode += condition? 1 + IMM2_SIZE : GET(ecode, 1);
1395        }        }
1396    
1397      else if (condcode == OP_DEF)     /* DEFINE - always false */      else if (condcode == OP_DEF)     /* DEFINE - always false */
# Line 1466  for (;;) Line 1483  for (;;)
1483        md->offset_vector[offset+1] = (int)(eptr - md->start_subject);        md->offset_vector[offset+1] = (int)(eptr - md->start_subject);
1484        if (offset_top <= offset) offset_top = offset + 2;        if (offset_top <= offset) offset_top = offset + 2;
1485        }        }
1486      ecode += 3;      ecode += 1 + IMM2_SIZE;
1487      break;      break;
1488    
1489    
# Line 1593  for (;;) Line 1610  for (;;)
1610      back a number of characters, not bytes. */      back a number of characters, not bytes. */
1611    
1612      case OP_REVERSE:      case OP_REVERSE:
1613  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1614      if (utf8)      if (utf)
1615        {        {
1616        i = GET(ecode, 1);        i = GET(ecode, 1);
1617        while (i-- > 0)        while (i-- > 0)
# Line 1625  for (;;) Line 1642  for (;;)
1642      function is able to force a failure. */      function is able to force a failure. */
1643    
1644      case OP_CALLOUT:      case OP_CALLOUT:
1645      if (pcre_callout != NULL)      if (PUBL(callout) != NULL)
1646        {        {
1647        pcre_callout_block cb;        PUBL(callout_block) cb;
1648        cb.version          = 2;   /* Version 1 of the callout block */        cb.version          = 2;   /* Version 1 of the callout block */
1649        cb.callout_number   = ecode[1];        cb.callout_number   = ecode[1];
1650        cb.offset_vector    = md->offset_vector;        cb.offset_vector    = md->offset_vector;
1651    #ifdef COMPILE_PCRE8
1652        cb.subject          = (PCRE_SPTR)md->start_subject;        cb.subject          = (PCRE_SPTR)md->start_subject;
1653    #else
1654          cb.subject          = (PCRE_SPTR16)md->start_subject;
1655    #endif
1656        cb.subject_length   = (int)(md->end_subject - md->start_subject);        cb.subject_length   = (int)(md->end_subject - md->start_subject);
1657        cb.start_match      = (int)(mstart - md->start_subject);        cb.start_match      = (int)(mstart - md->start_subject);
1658        cb.current_position = (int)(eptr - md->start_subject);        cb.current_position = (int)(eptr - md->start_subject);
# Line 1641  for (;;) Line 1662  for (;;)
1662        cb.capture_last     = md->capture_last;        cb.capture_last     = md->capture_last;
1663        cb.callout_data     = md->callout_data;        cb.callout_data     = md->callout_data;
1664        cb.mark             = md->nomatch_mark;        cb.mark             = md->nomatch_mark;
1665        if ((rrc = (*pcre_callout)(&cb)) > 0) RRETURN(MATCH_NOMATCH);        if ((rrc = (*PUBL(callout))(&cb)) > 0) RRETURN(MATCH_NOMATCH);
1666        if (rrc < 0) RRETURN(rrc);        if (rrc < 0) RRETURN(rrc);
1667        }        }
1668      ecode += 2 + 2*LINK_SIZE;      ecode += 2 + 2*LINK_SIZE;
# Line 1700  for (;;) Line 1721  for (;;)
1721        else        else
1722          {          {
1723          new_recursive.offset_save =          new_recursive.offset_save =
1724            (int *)(pcre_malloc)(new_recursive.saved_max * sizeof(int));            (int *)(PUBL(malloc))(new_recursive.saved_max * sizeof(int));
1725          if (new_recursive.offset_save == NULL) RRETURN(PCRE_ERROR_NOMEMORY);          if (new_recursive.offset_save == NULL) RRETURN(PCRE_ERROR_NOMEMORY);
1726          }          }
1727        memcpy(new_recursive.offset_save, md->offset_vector,        memcpy(new_recursive.offset_save, md->offset_vector,
# Line 1715  for (;;) Line 1736  for (;;)
1736        do        do
1737          {          {
1738          if (cbegroup) md->match_function_type = MATCH_CBEGROUP;          if (cbegroup) md->match_function_type = MATCH_CBEGROUP;
1739          RMATCH(eptr, callpat + _pcre_OP_lengths[*callpat], offset_top,          RMATCH(eptr, callpat + PRIV(OP_lengths)[*callpat], offset_top,
1740            md, eptrb, RM6);            md, eptrb, RM6);
1741          memcpy(md->offset_vector, new_recursive.offset_save,          memcpy(md->offset_vector, new_recursive.offset_save,
1742              new_recursive.saved_max * sizeof(int));              new_recursive.saved_max * sizeof(int));
# Line 1724  for (;;) Line 1745  for (;;)
1745            {            {
1746            DPRINTF(("Recursion matched\n"));            DPRINTF(("Recursion matched\n"));
1747            if (new_recursive.offset_save != stacksave)            if (new_recursive.offset_save != stacksave)
1748              (pcre_free)(new_recursive.offset_save);              (PUBL(free))(new_recursive.offset_save);
1749    
1750            /* 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
1751            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 1763  for (;;)
1763            {            {
1764            DPRINTF(("Recursion gave error %d\n", rrc));            DPRINTF(("Recursion gave error %d\n", rrc));
1765            if (new_recursive.offset_save != stacksave)            if (new_recursive.offset_save != stacksave)
1766              (pcre_free)(new_recursive.offset_save);              (PUBL(free))(new_recursive.offset_save);
1767            RRETURN(rrc);            RRETURN(rrc);
1768            }            }
1769    
# Line 1754  for (;;) Line 1775  for (;;)
1775        DPRINTF(("Recursion didn't match\n"));        DPRINTF(("Recursion didn't match\n"));
1776        md->recursive = new_recursive.prevrec;        md->recursive = new_recursive.prevrec;
1777        if (new_recursive.offset_save != stacksave)        if (new_recursive.offset_save != stacksave)
1778          (pcre_free)(new_recursive.offset_save);          (PUBL(free))(new_recursive.offset_save);
1779        RRETURN(MATCH_NOMATCH);        RRETURN(MATCH_NOMATCH);
1780        }        }
1781    
# Line 2066  for (;;) Line 2087  for (;;)
2087        be "non-word" characters. Remember the earliest consulted character for        be "non-word" characters. Remember the earliest consulted character for
2088        partial matching. */        partial matching. */
2089    
2090  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2091        if (utf8)        if (utf)
2092          {          {
2093          /* Get status of previous character */          /* Get status of previous character */
2094    
2095          if (eptr == md->start_subject) prev_is_word = FALSE; else          if (eptr == md->start_subject) prev_is_word = FALSE; else
2096            {            {
2097            USPTR lastptr = eptr - 1;            PCRE_PUCHAR lastptr = eptr - 1;
2098            while((*lastptr & 0xc0) == 0x80) lastptr--;            BACKCHAR(lastptr);
2099            if (lastptr < md->start_used_ptr) md->start_used_ptr = lastptr;            if (lastptr < md->start_used_ptr) md->start_used_ptr = lastptr;
2100            GETCHAR(c, lastptr);            GETCHAR(c, lastptr);
2101  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
# Line 2139  for (;;) Line 2160  for (;;)
2160              }              }
2161            else            else
2162  #endif  #endif
2163            prev_is_word = ((md->ctypes[eptr[-1]] & ctype_word) != 0);            prev_is_word = MAX_255(eptr[-1])
2164                && ((md->ctypes[eptr[-1]] & ctype_word) != 0);
2165            }            }
2166    
2167          /* Get status of next character */          /* Get status of next character */
# Line 2162  for (;;) Line 2184  for (;;)
2184            }            }
2185          else          else
2186  #endif  #endif
2187          cur_is_word = ((md->ctypes[*eptr] & ctype_word) != 0);          cur_is_word = MAX_255(*eptr)
2188              && ((md->ctypes[*eptr] & ctype_word) != 0);
2189          }          }
2190    
2191        /* Now see if the situation is what we want */        /* Now see if the situation is what we want */
# Line 2186  for (;;) Line 2209  for (;;)
2209        RRETURN(MATCH_NOMATCH);        RRETURN(MATCH_NOMATCH);
2210        }        }
2211      eptr++;      eptr++;
2212      if (utf8) while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;  #ifdef SUPPORT_UTF
2213        if (utf) ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
2214    #endif
2215      ecode++;      ecode++;
2216      break;      break;
2217    
# Line 2211  for (;;) Line 2236  for (;;)
2236        }        }
2237      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
2238      if (      if (
2239  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || !(defined COMPILE_PCRE8)
2240         c < 256 &&         c < 256 &&
2241  #endif  #endif
2242         (md->ctypes[c] & ctype_digit) != 0         (md->ctypes[c] & ctype_digit) != 0
# Line 2228  for (;;) Line 2253  for (;;)
2253        }        }
2254      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
2255      if (      if (
2256  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || !(defined COMPILE_PCRE8)
2257         c >= 256 ||         c > 255 ||
2258  #endif  #endif
2259         (md->ctypes[c] & ctype_digit) == 0         (md->ctypes[c] & ctype_digit) == 0
2260         )         )
# Line 2245  for (;;) Line 2270  for (;;)
2270        }        }
2271      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
2272      if (      if (
2273  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || !(defined COMPILE_PCRE8)
2274         c < 256 &&         c < 256 &&
2275  #endif  #endif
2276         (md->ctypes[c] & ctype_space) != 0         (md->ctypes[c] & ctype_space) != 0
# Line 2262  for (;;) Line 2287  for (;;)
2287        }        }
2288      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
2289      if (      if (
2290  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || !(defined COMPILE_PCRE8)
2291         c >= 256 ||         c > 255 ||
2292  #endif  #endif
2293         (md->ctypes[c] & ctype_space) == 0         (md->ctypes[c] & ctype_space) == 0
2294         )         )
# Line 2279  for (;;) Line 2304  for (;;)
2304        }        }
2305      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
2306      if (      if (
2307  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || !(defined COMPILE_PCRE8)
2308         c < 256 &&         c < 256 &&
2309  #endif  #endif
2310         (md->ctypes[c] & ctype_word) != 0         (md->ctypes[c] & ctype_word) != 0
# Line 2296  for (;;) Line 2321  for (;;)
2321        }        }
2322      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
2323      if (      if (
2324  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || !(defined COMPILE_PCRE8)
2325         c >= 256 ||         c > 255 ||
2326  #endif  #endif
2327         (md->ctypes[c] & ctype_word) == 0         (md->ctypes[c] & ctype_word) == 0
2328         )         )
# Line 2475  for (;;) Line 2500  for (;;)
2500          break;          break;
2501    
2502          case PT_GC:          case PT_GC:
2503          if ((ecode[2] != _pcre_ucp_gentype[prop->chartype]) == (op == OP_PROP))          if ((ecode[2] != PRIV(ucp_gentype)[prop->chartype]) == (op == OP_PROP))
2504            RRETURN(MATCH_NOMATCH);            RRETURN(MATCH_NOMATCH);
2505          break;          break;
2506    
# Line 2492  for (;;) Line 2517  for (;;)
2517          /* These are specials */          /* These are specials */
2518    
2519          case PT_ALNUM:          case PT_ALNUM:
2520          if ((_pcre_ucp_gentype[prop->chartype] == ucp_L ||          if ((PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
2521               _pcre_ucp_gentype[prop->chartype] == ucp_N) == (op == OP_NOTPROP))               PRIV(ucp_gentype)[prop->chartype] == ucp_N) == (op == OP_NOTPROP))
2522            RRETURN(MATCH_NOMATCH);            RRETURN(MATCH_NOMATCH);
2523          break;          break;
2524    
2525          case PT_SPACE:    /* Perl space */          case PT_SPACE:    /* Perl space */
2526          if ((_pcre_ucp_gentype[prop->chartype] == ucp_Z ||          if ((PRIV(ucp_gentype)[prop->chartype] == ucp_Z ||
2527               c == CHAR_HT || c == CHAR_NL || c == CHAR_FF || c == CHAR_CR)               c == CHAR_HT || c == CHAR_NL || c == CHAR_FF || c == CHAR_CR)
2528                 == (op == OP_NOTPROP))                 == (op == OP_NOTPROP))
2529            RRETURN(MATCH_NOMATCH);            RRETURN(MATCH_NOMATCH);
2530          break;          break;
2531    
2532          case PT_PXSPACE:  /* POSIX space */          case PT_PXSPACE:  /* POSIX space */
2533          if ((_pcre_ucp_gentype[prop->chartype] == ucp_Z ||          if ((PRIV(ucp_gentype)[prop->chartype] == ucp_Z ||
2534               c == CHAR_HT || c == CHAR_NL || c == CHAR_VT ||               c == CHAR_HT || c == CHAR_NL || c == CHAR_VT ||
2535               c == CHAR_FF || c == CHAR_CR)               c == CHAR_FF || c == CHAR_CR)
2536                 == (op == OP_NOTPROP))                 == (op == OP_NOTPROP))
# Line 2513  for (;;) Line 2538  for (;;)
2538          break;          break;
2539    
2540          case PT_WORD:          case PT_WORD:
2541          if ((_pcre_ucp_gentype[prop->chartype] == ucp_L ||          if ((PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
2542               _pcre_ucp_gentype[prop->chartype] == ucp_N ||               PRIV(ucp_gentype)[prop->chartype] == ucp_N ||
2543               c == CHAR_UNDERSCORE) == (op == OP_NOTPROP))               c == CHAR_UNDERSCORE) == (op == OP_NOTPROP))
2544            RRETURN(MATCH_NOMATCH);            RRETURN(MATCH_NOMATCH);
2545          break;          break;
# Line 2543  for (;;) Line 2568  for (;;)
2568      while (eptr < md->end_subject)      while (eptr < md->end_subject)
2569        {        {
2570        int len = 1;        int len = 1;
2571        if (!utf8) c = *eptr; else { GETCHARLEN(c, eptr, len); }        if (!utf) c = *eptr; else { GETCHARLEN(c, eptr, len); }
2572        if (UCD_CATEGORY(c) != ucp_M) break;        if (UCD_CATEGORY(c) != ucp_M) break;
2573        eptr += len;        eptr += len;
2574        }        }
# Line 2564  for (;;) Line 2589  for (;;)
2589      case OP_REFI:      case OP_REFI:
2590      caseless = op == OP_REFI;      caseless = op == OP_REFI;
2591      offset = GET2(ecode, 1) << 1;               /* Doubled ref number */      offset = GET2(ecode, 1) << 1;               /* Doubled ref number */
2592      ecode += 3;      ecode += 1 + IMM2_SIZE;
2593    
2594      /* If the reference is unset, there are two possibilities:      /* If the reference is unset, there are two possibilities:
2595    
# Line 2604  for (;;) Line 2629  for (;;)
2629        case OP_CRMINRANGE:        case OP_CRMINRANGE:
2630        minimize = (*ecode == OP_CRMINRANGE);        minimize = (*ecode == OP_CRMINRANGE);
2631        min = GET2(ecode, 1);        min = GET2(ecode, 1);
2632        max = GET2(ecode, 3);        max = GET2(ecode, 1 + IMM2_SIZE);
2633        if (max == 0) max = INT_MAX;        if (max == 0) max = INT_MAX;
2634        ecode += 5;        ecode += 1 + 2 * IMM2_SIZE;
2635        break;        break;
2636    
2637        default:               /* No repeat follows */        default:               /* No repeat follows */
# Line 2620  for (;;) Line 2645  for (;;)
2645        }        }
2646    
2647      /* Handle repeated back references. If the length of the reference is      /* Handle repeated back references. If the length of the reference is
2648      zero, just continue with the main loop. */      zero, just continue with the main loop. If the length is negative, it
2649        means the reference is unset in non-Java-compatible mode. If the minimum is
2650        zero, we can continue at the same level without recursion. For any other
2651        minimum, carrying on will result in NOMATCH. */
2652    
2653      if (length == 0) continue;      if (length == 0) continue;
2654        if (length < 0 && min == 0) continue;
2655    
2656      /* First, ensure the minimum number of matches are present. We get back      /* First, ensure the minimum number of matches are present. We get back
2657      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 2732  for (;;)
2732      case OP_NCLASS:      case OP_NCLASS:
2733      case OP_CLASS:      case OP_CLASS:
2734        {        {
2735          /* The data variable is saved across frames, so the byte map needs to
2736          be stored there. */
2737    #define BYTE_MAP ((pcre_uint8 *)data)
2738        data = ecode + 1;                /* Save for matching */        data = ecode + 1;                /* Save for matching */
2739        ecode += 33;                     /* Advance past the item */        ecode += 1 + (32 / sizeof(pcre_uchar)); /* Advance past the item */
2740    
2741        switch (*ecode)        switch (*ecode)
2742          {          {
# Line 2725  for (;;) Line 2757  for (;;)
2757          case OP_CRMINRANGE:          case OP_CRMINRANGE:
2758          minimize = (*ecode == OP_CRMINRANGE);          minimize = (*ecode == OP_CRMINRANGE);
2759          min = GET2(ecode, 1);          min = GET2(ecode, 1);
2760          max = GET2(ecode, 3);          max = GET2(ecode, 1 + IMM2_SIZE);
2761          if (max == 0) max = INT_MAX;          if (max == 0) max = INT_MAX;
2762          ecode += 5;          ecode += 1 + 2 * IMM2_SIZE;
2763          break;          break;
2764    
2765          default:               /* No repeat follows */          default:               /* No repeat follows */
# Line 2737  for (;;) Line 2769  for (;;)
2769    
2770        /* First, ensure the minimum number of matches are present. */        /* First, ensure the minimum number of matches are present. */
2771    
2772  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2773        /* UTF-8 mode */        if (utf)
       if (utf8)  
2774          {          {
2775          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
2776            {            {
# Line 2754  for (;;) Line 2785  for (;;)
2785              if (op == OP_CLASS) RRETURN(MATCH_NOMATCH);              if (op == OP_CLASS) RRETURN(MATCH_NOMATCH);
2786              }              }
2787            else            else
2788              {              if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);
             if ((data[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);  
             }  
2789            }            }
2790          }          }
2791        else        else
2792  #endif  #endif
2793        /* Not UTF-8 mode */        /* Not UTF mode */
2794          {          {
2795          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
2796            {            {
# Line 2771  for (;;) Line 2800  for (;;)
2800              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
2801              }              }
2802            c = *eptr++;            c = *eptr++;
2803            if ((data[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);  #ifndef COMPILE_PCRE8
2804              if (c > 255)
2805                {
2806                if (op == OP_CLASS) RRETURN(MATCH_NOMATCH);
2807                }
2808              else
2809    #endif
2810                if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);
2811            }            }
2812          }          }
2813    
# Line 2785  for (;;) Line 2821  for (;;)
2821    
2822        if (minimize)        if (minimize)
2823          {          {
2824  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2825          /* UTF-8 mode */          if (utf)
         if (utf8)  
2826            {            {
2827            for (fi = min;; fi++)            for (fi = min;; fi++)
2828              {              {
# Line 2805  for (;;) Line 2840  for (;;)
2840                if (op == OP_CLASS) RRETURN(MATCH_NOMATCH);                if (op == OP_CLASS) RRETURN(MATCH_NOMATCH);
2841                }                }
2842              else              else
2843                {                if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);
               if ((data[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);  
               }  
2844              }              }
2845            }            }
2846          else          else
2847  #endif  #endif
2848          /* Not UTF-8 mode */          /* Not UTF mode */
2849            {            {
2850            for (fi = min;; fi++)            for (fi = min;; fi++)
2851              {              {
# Line 2825  for (;;) Line 2858  for (;;)
2858                RRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
2859                }                }
2860              c = *eptr++;              c = *eptr++;
2861              if ((data[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);  #ifndef COMPILE_PCRE8
2862                if (c > 255)
2863                  {
2864                  if (op == OP_CLASS) RRETURN(MATCH_NOMATCH);
2865                  }
2866                else
2867    #endif
2868                  if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);
2869              }              }
2870            }            }
2871          /* Control never gets here */          /* Control never gets here */
# Line 2837  for (;;) Line 2877  for (;;)
2877          {          {
2878          pp = eptr;          pp = eptr;
2879    
2880  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2881          /* UTF-8 mode */          if (utf)
         if (utf8)  
2882            {            {
2883            for (i = min; i < max; i++)            for (i = min; i < max; i++)
2884              {              {
# Line 2855  for (;;) Line 2894  for (;;)
2894                if (op == OP_CLASS) break;                if (op == OP_CLASS) break;
2895                }                }
2896              else              else
2897                {                if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) break;
               if ((data[c/8] & (1 << (c&7))) == 0) break;  
               }  
2898              eptr += len;              eptr += len;
2899              }              }
2900            for (;;)            for (;;)
# Line 2870  for (;;) Line 2907  for (;;)
2907            }            }
2908          else          else
2909  #endif  #endif
2910            /* Not UTF-8 mode */            /* Not UTF mode */
2911            {            {
2912            for (i = min; i < max; i++)            for (i = min; i < max; i++)
2913              {              {
# Line 2880  for (;;) Line 2917  for (;;)
2917                break;                break;
2918                }                }
2919              c = *eptr;              c = *eptr;
2920              if ((data[c/8] & (1 << (c&7))) == 0) break;  #ifndef COMPILE_PCRE8
2921                if (c > 255)
2922                  {
2923                  if (op == OP_CLASS) break;
2924                  }
2925                else
2926    #endif
2927                  if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) break;
2928              eptr++;              eptr++;
2929              }              }
2930            while (eptr >= pp)            while (eptr >= pp)
# Line 2893  for (;;) Line 2937  for (;;)
2937    
2938          RRETURN(MATCH_NOMATCH);          RRETURN(MATCH_NOMATCH);
2939          }          }
2940    #undef BYTE_MAP
2941        }        }
2942      /* Control never gets here */      /* Control never gets here */
2943    
# Line 2901  for (;;) Line 2946  for (;;)
2946      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
2947      mode, because Unicode properties are supported in non-UTF-8 mode. */      mode, because Unicode properties are supported in non-UTF-8 mode. */
2948    
2949  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
2950      case OP_XCLASS:      case OP_XCLASS:
2951        {        {
2952        data = ecode + 1 + LINK_SIZE;                /* Save for matching */        data = ecode + 1 + LINK_SIZE;                /* Save for matching */
# Line 2926  for (;;) Line 2971  for (;;)
2971          case OP_CRMINRANGE:          case OP_CRMINRANGE:
2972          minimize = (*ecode == OP_CRMINRANGE);          minimize = (*ecode == OP_CRMINRANGE);
2973          min = GET2(ecode, 1);          min = GET2(ecode, 1);
2974          max = GET2(ecode, 3);          max = GET2(ecode, 1 + IMM2_SIZE);
2975          if (max == 0) max = INT_MAX;          if (max == 0) max = INT_MAX;
2976          ecode += 5;          ecode += 1 + 2 * IMM2_SIZE;
2977          break;          break;
2978    
2979          default:               /* No repeat follows */          default:               /* No repeat follows */
# Line 2946  for (;;) Line 2991  for (;;)
2991            RRETURN(MATCH_NOMATCH);            RRETURN(MATCH_NOMATCH);
2992            }            }
2993          GETCHARINCTEST(c, eptr);          GETCHARINCTEST(c, eptr);
2994          if (!_pcre_xclass(c, data)) RRETURN(MATCH_NOMATCH);          if (!PRIV(xclass)(c, data, utf)) RRETURN(MATCH_NOMATCH);
2995          }          }
2996    
2997        /* 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 3015  for (;;)
3015              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
3016              }              }
3017            GETCHARINCTEST(c, eptr);            GETCHARINCTEST(c, eptr);
3018            if (!_pcre_xclass(c, data)) RRETURN(MATCH_NOMATCH);            if (!PRIV(xclass)(c, data, utf)) RRETURN(MATCH_NOMATCH);
3019            }            }
3020          /* Control never gets here */          /* Control never gets here */
3021          }          }
# Line 2988  for (;;) Line 3033  for (;;)
3033              SCHECK_PARTIAL();              SCHECK_PARTIAL();
3034              break;              break;
3035              }              }
3036    #ifdef SUPPORT_UTF
3037            GETCHARLENTEST(c, eptr, len);            GETCHARLENTEST(c, eptr, len);
3038            if (!_pcre_xclass(c, data)) break;  #else
3039              c = *eptr;
3040    #endif
3041              if (!PRIV(xclass)(c, data, utf)) break;
3042            eptr += len;            eptr += len;
3043            }            }
3044          for(;;)          for(;;)
# Line 2997  for (;;) Line 3046  for (;;)
3046            RMATCH(eptr, ecode, offset_top, md, eptrb, RM21);            RMATCH(eptr, ecode, offset_top, md, eptrb, RM21);
3047            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3048            if (eptr-- == pp) break;        /* Stop if tried at original pos */            if (eptr-- == pp) break;        /* Stop if tried at original pos */
3049            if (utf8) BACKCHAR(eptr);  #ifdef SUPPORT_UTF
3050              if (utf) BACKCHAR(eptr);
3051    #endif
3052            }            }
3053          RRETURN(MATCH_NOMATCH);          RRETURN(MATCH_NOMATCH);
3054          }          }
# Line 3009  for (;;) Line 3060  for (;;)
3060      /* Match a single character, casefully */      /* Match a single character, casefully */
3061    
3062      case OP_CHAR:      case OP_CHAR:
3063  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3064      if (utf8)      if (utf)
3065        {        {
3066        length = 1;        length = 1;
3067        ecode++;        ecode++;
# Line 3024  for (;;) Line 3075  for (;;)
3075        }        }
3076      else      else
3077  #endif  #endif
3078        /* Not UTF mode */
     /* Non-UTF-8 mode */  
3079        {        {
3080        if (md->end_subject - eptr < 1)        if (md->end_subject - eptr < 1)
3081          {          {
# Line 3037  for (;;) Line 3087  for (;;)
3087        }        }
3088      break;      break;
3089    
3090      /* Match a single character, caselessly. If we are at the end of the      /* Match a single character, caselessly. If we are at the end of the
3091      subject, give up immediately. */      subject, give up immediately. */
3092    
3093      case OP_CHARI:      case OP_CHARI:
3094      if (eptr >= md->end_subject)      if (eptr >= md->end_subject)
3095        {        {
3096        SCHECK_PARTIAL();        SCHECK_PARTIAL();
3097        RRETURN(MATCH_NOMATCH);        RRETURN(MATCH_NOMATCH);
3098        }        }
3099    
3100  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3101      if (utf8)      if (utf)
3102        {        {
3103        length = 1;        length = 1;
3104        ecode++;        ecode++;
3105        GETCHARLEN(fc, ecode, length);        GETCHARLEN(fc, ecode, length);
3106    
3107        /* If the pattern character's value is < 128, we have only one byte, and        /* If the pattern character's value is < 128, we have only one byte, and
3108        we know that its other case must also be one byte long, so we can use the        we know that its other case must also be one byte long, so we can use the
3109        fast lookup table. We know that there is at least one byte left in the        fast lookup table. We know that there is at least one byte left in the
3110        subject. */        subject. */
3111    
3112        if (fc < 128)        if (fc < 128)
3113          {          {
3114          if (md->lcc[*ecode++] != md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH);          if (md->lcc[fc]
3115                != TABLE_GET(*eptr, md->lcc, *eptr)) RRETURN(MATCH_NOMATCH);
3116            ecode++;
3117            eptr++;
3118          }          }
3119    
3120        /* 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 3140  for (;;)
3140          }          }
3141        }        }
3142      else      else
3143  #endif   /* SUPPORT_UTF8 */  #endif   /* SUPPORT_UTF */
3144    
3145      /* Non-UTF-8 mode */      /* Not UTF mode */
3146        {        {
3147        if (md->lcc[ecode[1]] != md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH);        if (TABLE_GET(ecode[1], md->lcc, ecode[1])
3148              != TABLE_GET(*eptr, md->lcc, *eptr)) RRETURN(MATCH_NOMATCH);
3149          eptr++;
3150        ecode += 2;        ecode += 2;
3151        }        }
3152      break;      break;
# Line 3101  for (;;) Line 3156  for (;;)
3156      case OP_EXACT:      case OP_EXACT:
3157      case OP_EXACTI:      case OP_EXACTI:
3158      min = max = GET2(ecode, 1);      min = max = GET2(ecode, 1);
3159      ecode += 3;      ecode += 1 + IMM2_SIZE;
3160      goto REPEATCHAR;      goto REPEATCHAR;
3161    
3162      case OP_POSUPTO:      case OP_POSUPTO:
# Line 3116  for (;;) Line 3171  for (;;)
3171      min = 0;      min = 0;
3172      max = GET2(ecode, 1);      max = GET2(ecode, 1);
3173      minimize = *ecode == OP_MINUPTO || *ecode == OP_MINUPTOI;      minimize = *ecode == OP_MINUPTO || *ecode == OP_MINUPTOI;
3174      ecode += 3;      ecode += 1 + IMM2_SIZE;
3175      goto REPEATCHAR;      goto REPEATCHAR;
3176    
3177      case OP_POSSTAR:      case OP_POSSTAR:
# Line 3164  for (;;) Line 3219  for (;;)
3219      /* Common code for all repeated single-character matches. */      /* Common code for all repeated single-character matches. */
3220    
3221      REPEATCHAR:      REPEATCHAR:
3222  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3223      if (utf8)      if (utf)
3224        {        {
3225        length = 1;        length = 1;
3226        charptr = ecode;        charptr = ecode;
# Line 3181  for (;;) Line 3236  for (;;)
3236          unsigned int othercase;          unsigned int othercase;
3237          if (op >= OP_STARI &&     /* Caseless */          if (op >= OP_STARI &&     /* Caseless */
3238              (othercase = UCD_OTHERCASE(fc)) != fc)              (othercase = UCD_OTHERCASE(fc)) != fc)
3239            oclength = _pcre_ord2utf8(othercase, occhars);            oclength = PRIV(ord2utf)(othercase, occhars);
3240          else oclength = 0;          else oclength = 0;
3241  #endif  /* SUPPORT_UCP */  #endif  /* SUPPORT_UCP */
3242    
3243          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3244            {            {
3245            if (eptr <= md->end_subject - length &&            if (eptr <= md->end_subject - length &&
3246              memcmp(eptr, charptr, length) == 0) eptr += length;              memcmp(eptr, charptr, IN_UCHARS(length)) == 0) eptr += length;
3247  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3248            else if (oclength > 0 &&            else if (oclength > 0 &&
3249                     eptr <= md->end_subject - oclength &&                     eptr <= md->end_subject - oclength &&
3250                     memcmp(eptr, occhars, oclength) == 0) eptr += oclength;                     memcmp(eptr, occhars, IN_UCHARS(oclength)) == 0) eptr += oclength;
3251  #endif  /* SUPPORT_UCP */  #endif  /* SUPPORT_UCP */
3252            else            else
3253              {              {
# Line 3211  for (;;) Line 3266  for (;;)
3266              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3267              if (fi >= max) RRETURN(MATCH_NOMATCH);              if (fi >= max) RRETURN(MATCH_NOMATCH);
3268              if (eptr <= md->end_subject - length &&              if (eptr <= md->end_subject - length &&
3269                memcmp(eptr, charptr, length) == 0) eptr += length;                memcmp(eptr, charptr, IN_UCHARS(length)) == 0) eptr += length;
3270  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3271              else if (oclength > 0 &&              else if (oclength > 0 &&
3272                       eptr <= md->end_subject - oclength &&                       eptr <= md->end_subject - oclength &&
3273                       memcmp(eptr, occhars, oclength) == 0) eptr += oclength;                       memcmp(eptr, occhars, IN_UCHARS(oclength)) == 0) eptr += oclength;
3274  #endif  /* SUPPORT_UCP */  #endif  /* SUPPORT_UCP */
3275              else              else
3276                {                {
# Line 3232  for (;;) Line 3287  for (;;)
3287            for (i = min; i < max; i++)            for (i = min; i < max; i++)
3288              {              {
3289              if (eptr <= md->end_subject - length &&              if (eptr <= md->end_subject - length &&
3290                  memcmp(eptr, charptr, length) == 0) eptr += length;                  memcmp(eptr, charptr, IN_UCHARS(length)) == 0) eptr += length;
3291  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3292              else if (oclength > 0 &&              else if (oclength > 0 &&
3293                       eptr <= md->end_subject - oclength &&                       eptr <= md->end_subject - oclength &&
3294                       memcmp(eptr, occhars, oclength) == 0) eptr += oclength;                       memcmp(eptr, occhars, IN_UCHARS(oclength)) == 0) eptr += oclength;
3295  #endif  /* SUPPORT_UCP */  #endif  /* SUPPORT_UCP */
3296              else              else
3297                {                {
# Line 3268  for (;;) Line 3323  for (;;)
3323        value of fc will always be < 128. */        value of fc will always be < 128. */
3324        }        }
3325      else      else
3326  #endif  /* SUPPORT_UTF8 */  #endif  /* SUPPORT_UTF */
3327          /* When not in UTF-8 mode, load a single-byte character. */
3328      /* When not in UTF-8 mode, load a single-byte character. */        fc = *ecode++;
3329    
3330      fc = *ecode++;      /* The value of fc at this point is always one character, though we may
3331        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  
3332      caseful cases, for speed, since matching characters is likely to be quite      caseful cases, for speed, since matching characters is likely to be quite
3333      common. First, ensure the minimum number of matches are present. If min =      common. First, ensure the minimum number of matches are present. If min =
3334      max, continue at the same level without recursing. Otherwise, if      max, continue at the same level without recursing. Otherwise, if
# Line 3288  for (;;) Line 3341  for (;;)
3341    
3342      if (op >= OP_STARI)  /* Caseless */      if (op >= OP_STARI)  /* Caseless */
3343        {        {
3344        fc = md->lcc[fc];  #ifdef COMPILE_PCRE8
3345          /* fc must be < 128 if UTF is enabled. */
3346          foc = md->fcc[fc];
3347    #else
3348    #ifdef SUPPORT_UTF
3349    #ifdef SUPPORT_UCP
3350          if (utf && fc > 127)
3351            foc = UCD_OTHERCASE(fc);
3352    #else
3353          if (utf && fc > 127)
3354            foc = fc;
3355    #endif /* SUPPORT_UCP */
3356          else
3357    #endif /* SUPPORT_UTF */
3358            foc = TABLE_GET(fc, md->fcc, fc);
3359    #endif /* COMPILE_PCRE8 */
3360    
3361        for (i = 1; i <= min; i++)        for (i = 1; i <= min; i++)
3362          {          {
3363          if (eptr >= md->end_subject)          if (eptr >= md->end_subject)
# Line 3296  for (;;) Line 3365  for (;;)
3365            SCHECK_PARTIAL();            SCHECK_PARTIAL();
3366            RRETURN(MATCH_NOMATCH);            RRETURN(MATCH_NOMATCH);
3367            }            }
3368          if (fc != md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH);          if (fc != *eptr && foc != *eptr) RRETURN(MATCH_NOMATCH);
3369            eptr++;
3370          }          }
3371        if (min == max) continue;        if (min == max) continue;
3372        if (minimize)        if (minimize)
# Line 3311  for (;;) Line 3381  for (;;)
3381              SCHECK_PARTIAL();              SCHECK_PARTIAL();
3382              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
3383              }              }
3384            if (fc != md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH);            if (fc != *eptr && foc != *eptr) RRETURN(MATCH_NOMATCH);
3385              eptr++;
3386            }            }
3387          /* Control never gets here */          /* Control never gets here */
3388          }          }
# Line 3325  for (;;) Line 3396  for (;;)
3396              SCHECK_PARTIAL();              SCHECK_PARTIAL();
3397              break;              break;
3398              }              }
3399            if (fc != md->lcc[*eptr]) break;            if (fc != *eptr && foc != *eptr) break;
3400            eptr++;            eptr++;
3401            }            }
3402    
# Line 3414  for (;;) Line 3485  for (;;)
3485      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
3486      if (op == OP_NOTI)         /* The caseless case */      if (op == OP_NOTI)         /* The caseless case */
3487        {        {
3488  #ifdef SUPPORT_UTF8        register int ch, och;
3489        if (c < 256)        ch = *ecode++;
3490  #endif  #ifdef COMPILE_PCRE8
3491        c = md->lcc[c];        /* ch must be < 128 if UTF is enabled. */
3492        if (md->lcc[*ecode++] == c) RRETURN(MATCH_NOMATCH);        och = md->fcc[ch];
3493    #else
3494    #ifdef SUPPORT_UTF
3495    #ifdef SUPPORT_UCP
3496          if (utf && ch > 127)
3497            och = UCD_OTHERCASE(ch);
3498    #else
3499          if (utf && ch > 127)
3500            och = ch;
3501    #endif /* SUPPORT_UCP */
3502          else
3503    #endif /* SUPPORT_UTF */
3504            och = TABLE_GET(ch, md->fcc, ch);
3505    #endif /* COMPILE_PCRE8 */
3506          if (ch == c || och == c) RRETURN(MATCH_NOMATCH);
3507        }        }
3508      else    /* Caseful */      else    /* Caseful */
3509        {        {
# Line 3436  for (;;) Line 3521  for (;;)
3521      case OP_NOTEXACT:      case OP_NOTEXACT:
3522      case OP_NOTEXACTI:      case OP_NOTEXACTI:
3523      min = max = GET2(ecode, 1);      min = max = GET2(ecode, 1);
3524      ecode += 3;      ecode += 1 + IMM2_SIZE;
3525      goto REPEATNOTCHAR;      goto REPEATNOTCHAR;
3526    
3527      case OP_NOTUPTO:      case OP_NOTUPTO:
# Line 3446  for (;;) Line 3531  for (;;)
3531      min = 0;      min = 0;
3532      max = GET2(ecode, 1);      max = GET2(ecode, 1);
3533      minimize = *ecode == OP_NOTMINUPTO || *ecode == OP_NOTMINUPTOI;      minimize = *ecode == OP_NOTMINUPTO || *ecode == OP_NOTMINUPTOI;
3534      ecode += 3;      ecode += 1 + IMM2_SIZE;
3535      goto REPEATNOTCHAR;      goto REPEATNOTCHAR;
3536    
3537      case OP_NOTPOSSTAR:      case OP_NOTPOSSTAR:
# Line 3478  for (;;) Line 3563  for (;;)
3563      possessive = TRUE;      possessive = TRUE;
3564      min = 0;      min = 0;
3565      max = GET2(ecode, 1);      max = GET2(ecode, 1);
3566      ecode += 3;      ecode += 1 + IMM2_SIZE;
3567      goto REPEATNOTCHAR;      goto REPEATNOTCHAR;
3568    
3569      case OP_NOTSTAR:      case OP_NOTSTAR:
# Line 3517  for (;;) Line 3602  for (;;)
3602    
3603      if (op >= OP_NOTSTARI)     /* Caseless */      if (op >= OP_NOTSTARI)     /* Caseless */
3604        {        {
3605        fc = md->lcc[fc];  #ifdef COMPILE_PCRE8
3606          /* fc must be < 128 if UTF is enabled. */
3607          foc = md->fcc[fc];
3608    #else
3609    #ifdef SUPPORT_UTF
3610    #ifdef SUPPORT_UCP
3611          if (utf && fc > 127)
3612            foc = UCD_OTHERCASE(fc);
3613    #else
3614          if (utf && fc > 127)
3615            foc = fc;
3616    #endif /* SUPPORT_UCP */
3617          else
3618    #endif /* SUPPORT_UTF */
3619            foc = TABLE_GET(fc, md->fcc, fc);
3620    #endif /* COMPILE_PCRE8 */
3621    
3622  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3623        /* UTF-8 mode */        if (utf)
       if (utf8)  
3624          {          {
3625          register unsigned int d;          register unsigned int d;
3626          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
# Line 3532  for (;;) Line 3631  for (;;)
3631              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
3632              }              }
3633            GETCHARINC(d, eptr);            GETCHARINC(d, eptr);
3634            if (d < 256) d = md->lcc[d];            if (fc == d || foc == d) RRETURN(MATCH_NOMATCH);
           if (fc == d) RRETURN(MATCH_NOMATCH);  
3635            }            }
3636          }          }
3637        else        else
3638  #endif  #endif
3639          /* Not UTF mode */
       /* Not UTF-8 mode */  
3640          {          {
3641          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3642            {            {
# Line 3548  for (;;) Line 3645  for (;;)
3645              SCHECK_PARTIAL();              SCHECK_PARTIAL();
3646              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
3647              }              }
3648            if (fc == md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH);            if (fc == *eptr || foc == *eptr) RRETURN(MATCH_NOMATCH);
3649              eptr++;
3650            }            }
3651          }          }
3652    
# Line 3556  for (;;) Line 3654  for (;;)
3654    
3655        if (minimize)        if (minimize)
3656          {          {
3657  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3658          /* UTF-8 mode */          if (utf)
         if (utf8)  
3659            {            {
3660            register unsigned int d;            register unsigned int d;
3661            for (fi = min;; fi++)            for (fi = min;; fi++)
# Line 3572  for (;;) Line 3669  for (;;)
3669                RRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
3670                }                }
3671              GETCHARINC(d, eptr);              GETCHARINC(d, eptr);
3672              if (d < 256) d = md->lcc[d];              if (fc == d || foc == d) RRETURN(MATCH_NOMATCH);
             if (fc == d) RRETURN(MATCH_NOMATCH);  
3673              }              }
3674            }            }
3675          else          else
3676  #endif  #endif
3677          /* Not UTF-8 mode */          /* Not UTF mode */
3678            {            {
3679            for (fi = min;; fi++)            for (fi = min;; fi++)
3680              {              {
# Line 3590  for (;;) Line 3686  for (;;)
3686                SCHECK_PARTIAL();                SCHECK_PARTIAL();
3687                RRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
3688                }                }
3689              if (fc == md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH);              if (fc == *eptr || foc == *eptr) RRETURN(MATCH_NOMATCH);
3690                eptr++;
3691              }              }
3692            }            }
3693          /* Control never gets here */          /* Control never gets here */
# Line 3602  for (;;) Line 3699  for (;;)
3699          {          {
3700          pp = eptr;          pp = eptr;
3701    
3702  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3703          /* UTF-8 mode */          if (utf)
         if (utf8)  
3704            {            {
3705            register unsigned int d;            register unsigned int d;
3706            for (i = min; i < max; i++)            for (i = min; i < max; i++)
# Line 3616  for (;;) Line 3712  for (;;)
3712                break;                break;
3713                }                }
3714              GETCHARLEN(d, eptr, len);              GETCHARLEN(d, eptr, len);
3715              if (d < 256) d = md->lcc[d];              if (fc == d || foc == d) break;
             if (fc == d) break;  
3716              eptr += len;              eptr += len;
3717              }              }
3718          if (possessive) continue;          if (possessive) continue;
# Line 3631  for (;;) Line 3726  for (;;)
3726            }            }
3727          else          else
3728  #endif  #endif
3729          /* Not UTF-8 mode */          /* Not UTF mode */
3730            {            {
3731            for (i = min; i < max; i++)            for (i = min; i < max; i++)
3732              {              {
# Line 3640  for (;;) Line 3735  for (;;)
3735                SCHECK_PARTIAL();                SCHECK_PARTIAL();
3736                break;                break;
3737                }                }
3738              if (fc == md->lcc[*eptr]) break;              if (fc == *eptr || foc == *eptr) break;
3739              eptr++;              eptr++;
3740              }              }
3741            if (possessive) continue;            if (possessive) continue;
# Line 3661  for (;;) Line 3756  for (;;)
3756    
3757      else      else
3758        {        {
3759  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3760        /* UTF-8 mode */        if (utf)
       if (utf8)  
3761          {          {
3762          register unsigned int d;          register unsigned int d;
3763          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
# Line 3679  for (;;) Line 3773  for (;;)
3773          }          }
3774        else        else
3775  #endif  #endif
3776        /* Not UTF-8 mode */        /* Not UTF mode */
3777          {          {
3778          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3779            {            {
# Line 3696  for (;;) Line 3790  for (;;)
3790    
3791        if (minimize)        if (minimize)
3792          {          {
3793  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3794          /* UTF-8 mode */          if (utf)
         if (utf8)  
3795            {            {
3796            register unsigned int d;            register unsigned int d;
3797            for (fi = min;; fi++)            for (fi = min;; fi++)
# Line 3717  for (;;) Line 3810  for (;;)
3810            }            }
3811          else          else
3812  #endif  #endif
3813          /* Not UTF-8 mode */          /* Not UTF mode */
3814            {            {
3815            for (fi = min;; fi++)            for (fi = min;; fi++)
3816              {              {
# Line 3741  for (;;) Line 3834  for (;;)
3834          {          {
3835          pp = eptr;          pp = eptr;
3836    
3837  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3838          /* UTF-8 mode */          if (utf)
         if (utf8)  
3839            {            {
3840            register unsigned int d;            register unsigned int d;
3841            for (i = min; i < max; i++)            for (i = min; i < max; i++)
# Line 3769  for (;;) Line 3861  for (;;)
3861            }            }
3862          else          else
3863  #endif  #endif
3864          /* Not UTF-8 mode */          /* Not UTF mode */
3865            {            {
3866            for (i = min; i < max; i++)            for (i = min; i < max; i++)
3867              {              {
# Line 3802  for (;;) Line 3894  for (;;)
3894      case OP_TYPEEXACT:      case OP_TYPEEXACT:
3895      min = max = GET2(ecode, 1);      min = max = GET2(ecode, 1);
3896      minimize = TRUE;      minimize = TRUE;
3897      ecode += 3;      ecode += 1 + IMM2_SIZE;
3898      goto REPEATTYPE;      goto REPEATTYPE;
3899    
3900      case OP_TYPEUPTO:      case OP_TYPEUPTO:
# Line 3810  for (;;) Line 3902  for (;;)
3902      min = 0;      min = 0;
3903      max = GET2(ecode, 1);      max = GET2(ecode, 1);
3904      minimize = *ecode == OP_TYPEMINUPTO;      minimize = *ecode == OP_TYPEMINUPTO;
3905      ecode += 3;      ecode += 1 + IMM2_SIZE;
3906      goto REPEATTYPE;      goto REPEATTYPE;
3907    
3908      case OP_TYPEPOSSTAR:      case OP_TYPEPOSSTAR:
# Line 3838  for (;;) Line 3930  for (;;)
3930      possessive = TRUE;      possessive = TRUE;
3931      min = 0;      min = 0;
3932      max = GET2(ecode, 1);      max = GET2(ecode, 1);
3933      ecode += 3;      ecode += 1 + IMM2_SIZE;
3934      goto REPEATTYPE;      goto REPEATTYPE;
3935    
3936      case OP_TYPESTAR:      case OP_TYPESTAR:
# Line 4045  for (;;) Line 4137  for (;;)
4137            while (eptr < md->end_subject)            while (eptr < md->end_subject)
4138              {              {
4139              int len = 1;              int len = 1;
4140              if (!utf8) c = *eptr; else { GETCHARLEN(c, eptr, len); }              if (!utf) c = *eptr; else { GETCHARLEN(c, eptr, len); }
4141              if (UCD_CATEGORY(c) != ucp_M) break;              if (UCD_CATEGORY(c) != ucp_M) break;
4142              eptr += len;              eptr += len;
4143              }              }
# Line 4057  for (;;) Line 4149  for (;;)
4149    
4150  /* Handle all other cases when the coding is UTF-8 */  /* Handle all other cases when the coding is UTF-8 */
4151    
4152  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
4153        if (utf8) switch(ctype)        if (utf) switch(ctype)
4154          {          {
4155          case OP_ANY:          case OP_ANY:
4156          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
# Line 4070  for (;;) Line 4162  for (;;)
4162              }              }
4163            if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH);            if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH);
4164            eptr++;            eptr++;
4165            while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;            ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
4166            }            }
4167          break;          break;
4168    
# Line 4083  for (;;) Line 4175  for (;;)
4175              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4176              }              }
4177            eptr++;            eptr++;
4178            while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;            ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
4179            }            }
4180          break;          break;
4181    
# Line 4265  for (;;) Line 4357  for (;;)
4357              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4358              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4359              }              }
4360            if (*eptr >= 128 || (md->ctypes[*eptr++] & ctype_digit) == 0)            if (*eptr >= 128 || (md->ctypes[*eptr] & ctype_digit) == 0)
4361              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4362              eptr++;
4363            /* 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 */
4364            }            }
4365          break;          break;
# Line 4281  for (;;) Line 4374  for (;;)
4374              }              }
4375            if (*eptr < 128 && (md->ctypes[*eptr] & ctype_space) != 0)            if (*eptr < 128 && (md->ctypes[*eptr] & ctype_space) != 0)
4376              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4377            while (++eptr < md->end_subject && (*eptr & 0xc0) == 0x80);            eptr++;
4378              ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
4379            }            }
4380          break;          break;
4381    
# Line 4293  for (;;) Line 4387  for (;;)
4387              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4388              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4389              }              }
4390            if (*eptr >= 128 || (md->ctypes[*eptr++] & ctype_space) == 0)            if (*eptr >= 128 || (md->ctypes[*eptr] & ctype_space) == 0)
4391              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4392              eptr++;
4393            /* 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 */
4394            }            }
4395          break;          break;
# Line 4309  for (;;) Line 4404  for (;;)
4404              }              }
4405            if (*eptr < 128 && (md->ctypes[*eptr] & ctype_word) != 0)            if (*eptr < 128 && (md->ctypes[*eptr] & ctype_word) != 0)
4406              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4407            while (++eptr < md->end_subject && (*eptr & 0xc0) == 0x80);            eptr++;
4408              ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
4409            }            }
4410          break;          break;
4411    
# Line 4321  for (;;) Line 4417  for (;;)
4417              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4418              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4419              }              }
4420            if (*eptr >= 128 || (md->ctypes[*eptr++] & ctype_word) == 0)            if (*eptr >= 128 || (md->ctypes[*eptr] & ctype_word) == 0)
4421              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4422              eptr++;
4423            /* 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 */
4424            }            }
4425          break;          break;
# Line 4332  for (;;) Line 4429  for (;;)
4429          }  /* End switch(ctype) */          }  /* End switch(ctype) */
4430    
4431        else        else
4432  #endif     /* SUPPORT_UTF8 */  #endif     /* SUPPORT_UTF */
4433    
4434        /* 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
4435        than OP_PROP and OP_NOTPROP. */        than OP_PROP and OP_NOTPROP. */
# Line 4392  for (;;) Line 4489  for (;;)
4489              case 0x000b:              case 0x000b:
4490              case 0x000c:              case 0x000c:
4491              case 0x0085:              case 0x0085:
4492    #ifdef COMPILE_PCRE16
4493                case 0x2028:
4494                case 0x2029:
4495    #endif
4496              if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH);              if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH);
4497              break;              break;
4498              }              }
# Line 4412  for (;;) Line 4513  for (;;)
4513              case 0x09:      /* HT */              case 0x09:      /* HT */
4514              case 0x20:      /* SPACE */              case 0x20:      /* SPACE */
4515              case 0xa0:      /* NBSP */              case 0xa0:      /* NBSP */
4516    #ifdef COMPILE_PCRE16
4517                case 0x1680:    /* OGHAM SPACE MARK */
4518                case 0x180e:    /* MONGOLIAN VOWEL SEPARATOR */
4519                case 0x2000:    /* EN QUAD */
4520                case 0x2001:    /* EM QUAD */
4521                case 0x2002:    /* EN SPACE */
4522                case 0x2003:    /* EM SPACE */
4523                case 0x2004:    /* THREE-PER-EM SPACE */
4524                case 0x2005:    /* FOUR-PER-EM SPACE */
4525                case 0x2006:    /* SIX-PER-EM SPACE */
4526                case 0x2007:    /* FIGURE SPACE */
4527                case 0x2008:    /* PUNCTUATION SPACE */
4528                case 0x2009:    /* THIN SPACE */
4529                case 0x200A:    /* HAIR SPACE */
4530                case 0x202f:    /* NARROW NO-BREAK SPACE */
4531                case 0x205f:    /* MEDIUM MATHEMATICAL SPACE */
4532                case 0x3000:    /* IDEOGRAPHIC SPACE */
4533    #endif
4534              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4535              }              }
4536            }            }
# Line 4431  for (;;) Line 4550  for (;;)
4550              case 0x09:      /* HT */              case 0x09:      /* HT */
4551              case 0x20:      /* SPACE */              case 0x20:      /* SPACE */
4552              case 0xa0:      /* NBSP */              case 0xa0:      /* NBSP */
4553    #ifdef COMPILE_PCRE16
4554                case 0x1680:    /* OGHAM SPACE MARK */
4555                case 0x180e:    /* MONGOLIAN VOWEL SEPARATOR */
4556                case 0x2000:    /* EN QUAD */
4557                case 0x2001:    /* EM QUAD */
4558                case 0x2002:    /* EN SPACE */
4559                case 0x2003:    /* EM SPACE */
4560                case 0x2004:    /* THREE-PER-EM SPACE */
4561                case 0x2005:    /* FOUR-PER-EM SPACE */
4562                case 0x2006:    /* SIX-PER-EM SPACE */
4563                case 0x2007:    /* FIGURE SPACE */
4564                case 0x2008:    /* PUNCTUATION SPACE */
4565                case 0x2009:    /* THIN SPACE */
4566                case 0x200A:    /* HAIR SPACE */
4567                case 0x202f:    /* NARROW NO-BREAK SPACE */
4568                case 0x205f:    /* MEDIUM MATHEMATICAL SPACE */
4569                case 0x3000:    /* IDEOGRAPHIC SPACE */
4570    #endif
4571              break;              break;
4572              }              }
4573            }            }
# Line 4452  for (;;) Line 4589  for (;;)
4589              case 0x0c:      /* FF */              case 0x0c:      /* FF */
4590              case 0x0d:      /* CR */              case 0x0d:      /* CR */
4591              case 0x85:      /* NEL */              case 0x85:      /* NEL */
4592    #ifdef COMPILE_PCRE16
4593                case 0x2028:    /* LINE SEPARATOR */
4594                case 0x2029:    /* PARAGRAPH SEPARATOR */
4595    #endif
4596              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4597              }              }
4598            }            }
# Line 4473  for (;;) Line 4614  for (;;)
4614              case 0x0c:      /* FF */              case 0x0c:      /* FF */
4615              case 0x0d:      /* CR */              case 0x0d:      /* CR */
4616              case 0x85:      /* NEL */              case 0x85:      /* NEL */
4617    #ifdef COMPILE_PCRE16
4618                case 0x2028:    /* LINE SEPARATOR */
4619                case 0x2029:    /* PARAGRAPH SEPARATOR */
4620    #endif
4621              break;              break;
4622              }              }
4623            }            }
# Line 4486  for (;;) Line 4631  for (;;)
4631              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4632              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4633              }              }
4634            if ((md->ctypes[*eptr++] & ctype_digit) != 0) RRETURN(MATCH_NOMATCH);            if (MAX_255(*eptr) && (md->ctypes[*eptr] & ctype_digit) != 0)
4635                RRETURN(MATCH_NOMATCH);
4636              eptr++;
4637            }            }
4638          break;          break;
4639    
# Line 4498  for (;;) Line 4645  for (;;)
4645              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4646              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4647              }              }
4648            if ((md->ctypes[*eptr++] & ctype_digit) == 0) RRETURN(MATCH_NOMATCH);            if (!MAX_255(*eptr) || (md->ctypes[*eptr] & ctype_digit) == 0)
4649                RRETURN(MATCH_NOMATCH);
4650              eptr++;
4651            }            }
4652          break;          break;
4653    
# Line 4510  for (;;) Line 4659  for (;;)
4659              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4660              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4661              }              }
4662            if ((md->ctypes[*eptr++] & ctype_space) != 0) RRETURN(MATCH_NOMATCH);            if (MAX_255(*eptr) && (md->ctypes[*eptr] & ctype_space) != 0)
4663                RRETURN(MATCH_NOMATCH);
4664              eptr++;
4665            }            }
4666          break;          break;
4667    
# Line 4522  for (;;) Line 4673  for (;;)
4673              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4674              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4675              }              }
4676            if ((md->ctypes[*eptr++] & ctype_space) == 0) RRETURN(MATCH_NOMATCH);            if (!MAX_255(*eptr) || (md->ctypes[*eptr] & ctype_space) == 0)
4677                RRETURN(MATCH_NOMATCH);
4678              eptr++;
4679            }            }
4680          break;          break;
4681    
# Line 4534  for (;;) Line 4687  for (;;)
4687              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4688              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4689              }              }
4690            if ((md->ctypes[*eptr++] & ctype_word) != 0)            if (MAX_255(*eptr) && (md->ctypes[*eptr] & ctype_word) != 0)
4691              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4692              eptr++;
4693            }            }
4694          break;          break;
4695    
# Line 4547  for (;;) Line 4701  for (;;)
4701              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4702              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4703              }              }
4704            if ((md->ctypes[*eptr++] & ctype_word) == 0)            if (!MAX_255(*eptr) || (md->ctypes[*eptr] & ctype_word) == 0)
4705              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4706              eptr++;
4707            }            }
4708          break;          break;
4709    
# Line 4766  for (;;) Line 4921  for (;;)
4921            while (eptr < md->end_subject)            while (eptr < md->end_subject)
4922              {              {
4923              int len = 1;              int len = 1;
4924              if (!utf8) c = *eptr; else { GETCHARLEN(c, eptr, len); }              if (!utf) c = *eptr; else { GETCHARLEN(c, eptr, len); }
4925              if (UCD_CATEGORY(c) != ucp_M) break;              if (UCD_CATEGORY(c) != ucp_M) break;
4926              eptr += len;              eptr += len;
4927              }              }
# Line 4775  for (;;) Line 4930  for (;;)
4930        else        else
4931  #endif     /* SUPPORT_UCP */  #endif     /* SUPPORT_UCP */
4932    
4933  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
4934        /* UTF-8 mode */        if (utf)
       if (utf8)  
4935          {          {
4936          for (fi = min;; fi++)          for (fi = min;; fi++)
4937            {            {
# Line 4919  for (;;) Line 5073  for (;;)
5073              break;              break;
5074    
5075              case OP_WHITESPACE:              case OP_WHITESPACE:
5076              if  (c >= 256 || (md->ctypes[c] & ctype_space) == 0)              if (c >= 256 || (md->ctypes[c] & ctype_space) == 0)
5077                RRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
5078              break;              break;
5079    
# Line 4940  for (;;) Line 5094  for (;;)
5094          }          }
5095        else        else
5096  #endif  #endif
5097        /* Not UTF-8 mode */        /* Not UTF mode */
5098          {          {
5099          for (fi = min;; fi++)          for (fi = min;; fi++)
5100            {            {
# Line 4976  for (;;) Line 5130  for (;;)
5130                case 0x000b:                case 0x000b:
5131                case 0x000c:                case 0x000c:
5132                case 0x0085:                case 0x0085:
5133    #ifdef COMPILE_PCRE16
5134                  case 0x2028:
5135                  case 0x2029:
5136    #endif
5137                if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH);                if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH);
5138                break;                break;
5139                }                }
# Line 4988  for (;;) Line 5146  for (;;)
5146                case 0x09:      /* HT */                case 0x09:      /* HT */
5147                case 0x20:      /* SPACE */                case 0x20:      /* SPACE */
5148                case 0xa0:      /* NBSP */                case 0xa0:      /* NBSP */
5149    #ifdef COMPILE_PCRE16
5150                  case 0x1680:    /* OGHAM SPACE MARK */
5151                  case 0x180e:    /* MONGOLIAN VOWEL SEPARATOR */
5152                  case 0x2000:    /* EN QUAD */
5153                  case 0x2001:    /* EM QUAD */
5154                  case 0x2002:    /* EN SPACE */
5155                  case 0x2003:    /* EM SPACE */
5156                  case 0x2004:    /* THREE-PER-EM SPACE */
5157                  case 0x2005:    /* FOUR-PER-EM SPACE */
5158                  case 0x2006:    /* SIX-PER-EM SPACE */
5159                  case 0x2007:    /* FIGURE SPACE */
5160                  case 0x2008:    /* PUNCTUATION SPACE */
5161                  case 0x2009:    /* THIN SPACE */
5162                  case 0x200A:    /* HAIR SPACE */
5163                  case 0x202f:    /* NARROW NO-BREAK SPACE */
5164                  case 0x205f:    /* MEDIUM MATHEMATICAL SPACE */
5165                  case 0x3000:    /* IDEOGRAPHIC SPACE */
5166    #endif
5167                RRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
5168                }                }
5169              break;              break;
# Line 4999  for (;;) Line 5175  for (;;)
5175                case 0x09:      /* HT */                case 0x09:      /* HT */
5176                case 0x20:      /* SPACE */                case 0x20:      /* SPACE */
5177                case 0xa0:      /* NBSP */                case 0xa0:      /* NBSP */
5178    #ifdef COMPILE_PCRE16
5179                  case 0x1680:    /* OGHAM SPACE MARK */
5180                  case 0x180e:    /* MONGOLIAN VOWEL SEPARATOR */
5181                  case 0x2000:    /* EN QUAD */
5182                  case 0x2001:    /* EM QUAD */
5183                  case 0x2002:    /* EN SPACE */
5184                  case 0x2003:    /* EM SPACE */
5185                  case 0x2004:    /* THREE-PER-EM SPACE */
5186                  case 0x2005:    /* FOUR-PER-EM SPACE */
5187                  case 0x2006:    /* SIX-PER-EM SPACE */
5188                  case 0x2007:    /* FIGURE SPACE */
5189                  case 0x2008:    /* PUNCTUATION SPACE */
5190                  case 0x2009:    /* THIN SPACE */
5191                  case 0x200A:    /* HAIR SPACE */
5192                  case 0x202f:    /* NARROW NO-BREAK SPACE */
5193                  case 0x205f:    /* MEDIUM MATHEMATICAL SPACE */
5194                  case 0x3000:    /* IDEOGRAPHIC SPACE */
5195    #endif
5196                break;                break;
5197                }                }
5198              break;              break;
# Line 5012  for (;;) Line 5206  for (;;)
5206                case 0x0c:      /* FF */                case 0x0c:      /* FF */
5207                case 0x0d:      /* CR */                case 0x0d:      /* CR */
5208                case 0x85:      /* NEL */                case 0x85:      /* NEL */
5209    #ifdef COMPILE_PCRE16
5210                  case 0x2028:    /* LINE SEPARATOR */
5211                  case 0x2029:    /* PARAGRAPH SEPARATOR */
5212    #endif
5213                RRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
5214                }                }
5215              break;              break;
# Line 5025  for (;;) Line 5223  for (;;)
5223                case 0x0c:      /* FF */                case 0x0c:      /* FF */
5224                case 0x0d:      /* CR */                case 0x0d:      /* CR */
5225                case 0x85:      /* NEL */                case 0x85:      /* NEL */
5226    #ifdef COMPILE_PCRE16
5227                  case 0x2028:    /* LINE SEPARATOR */
5228                  case 0x2029:    /* PARAGRAPH SEPARATOR */
5229    #endif
5230                break;                break;
5231                }                }
5232              break;              break;
5233    
5234              case OP_NOT_DIGIT:              case OP_NOT_DIGIT:
5235              if ((md->ctypes[c] & ctype_digit) != 0) RRETURN(MATCH_NOMATCH);              if (MAX_255(c) && (md->ctypes[c] & ctype_digit) != 0) RRETURN(MATCH_NOMATCH);
5236              break;              break;
5237    
5238              case OP_DIGIT:              case OP_DIGIT:
5239              if ((md->ctypes[c] & ctype_digit) == 0) RRETURN(MATCH_NOMATCH);              if (!MAX_255(c) || (md->ctypes[c] & ctype_digit) == 0) RRETURN(MATCH_NOMATCH);
5240              break;              break;
5241    
5242              case OP_NOT_WHITESPACE:              case OP_NOT_WHITESPACE:
5243              if ((md->ctypes[c] & ctype_space) != 0) RRETURN(MATCH_NOMATCH);              if (MAX_255(c) && (md->ctypes[c] & ctype_space) != 0) RRETURN(MATCH_NOMATCH);
5244              break;              break;
5245    
5246              case OP_WHITESPACE:              case OP_WHITESPACE:
5247              if  ((md->ctypes[c] & ctype_space) == 0) RRETURN(MATCH_NOMATCH);              if (!MAX_255(c) || (md->ctypes[c] & ctype_space) == 0) RRETURN(MATCH_NOMATCH);
5248              break;              break;
5249    
5250              case OP_NOT_WORDCHAR:              case OP_NOT_WORDCHAR:
5251              if ((md->ctypes[c] & ctype_word) != 0) RRETURN(MATCH_NOMATCH);              if (MAX_255(c) && (md->ctypes[c] & ctype_word) != 0) RRETURN(MATCH_NOMATCH);
5252              break;              break;
5253    
5254              case OP_WORDCHAR:              case OP_WORDCHAR:
5255              if ((md->ctypes[c] & ctype_word) == 0) RRETURN(MATCH_NOMATCH);              if (!MAX_255(c) || (md->ctypes[c] & ctype_word) == 0) RRETURN(MATCH_NOMATCH);
5256              break;              break;
5257    
5258              default:              default:
# Line 5239  for (;;) Line 5441  for (;;)
5441            RMATCH(eptr, ecode, offset_top, md, eptrb, RM44);            RMATCH(eptr, ecode, offset_top, md, eptrb, RM44);
5442            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
5443            if (eptr-- == pp) break;        /* Stop if tried at original pos */            if (eptr-- == pp) break;        /* Stop if tried at original pos */
5444            if (utf8) BACKCHAR(eptr);            if (utf) BACKCHAR(eptr);
5445            }            }
5446          }          }
5447    
# Line 5256  for (;;) Line 5458  for (;;)
5458              SCHECK_PARTIAL();              SCHECK_PARTIAL();
5459              break;              break;
5460              }              }
5461            if (!utf8) c = *eptr; else { GETCHARLEN(c, eptr, len); }            if (!utf) c = *eptr; else { GETCHARLEN(c, eptr, len); }
5462            if (UCD_CATEGORY(c) == ucp_M) break;            if (UCD_CATEGORY(c) == ucp_M) break;
5463            eptr += len;            eptr += len;
5464            while (eptr < md->end_subject)            while (eptr < md->end_subject)
5465              {              {
5466              len = 1;              len = 1;
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              }              }
# Line 5279  for (;;) Line 5481  for (;;)
5481            if (eptr-- == pp) break;        /* Stop if tried at original pos */            if (eptr-- == pp) break;        /* Stop if tried at original pos */
5482            for (;;)                        /* Move back over one extended */            for (;;)                        /* Move back over one extended */
5483              {              {
5484              if (!utf8) c = *eptr; else              if (!utf) c = *eptr; else
5485                {                {
5486                BACKCHAR(eptr);                BACKCHAR(eptr);
5487                GETCHAR(c, eptr);                GETCHAR(c, eptr);
# Line 5293  for (;;) Line 5495  for (;;)
5495        else        else
5496  #endif   /* SUPPORT_UCP */  #endif   /* SUPPORT_UCP */
5497    
5498  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
5499        /* UTF-8 mode */        if (utf)
   
       if (utf8)  
5500          {          {
5501          switch(ctype)          switch(ctype)
5502            {            {
# Line 5312  for (;;) Line 5512  for (;;)
5512                  }                  }
5513                if (IS_NEWLINE(eptr)) break;                if (IS_NEWLINE(eptr)) break;
5514                eptr++;                eptr++;
5515                while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;                ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
5516                }                }
5517              }              }
5518    
# Line 5329  for (;;) Line 5529  for (;;)
5529                  }                  }
5530                if (IS_NEWLINE(eptr)) break;                if (IS_NEWLINE(eptr)) break;
5531                eptr++;                eptr++;
5532                while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;                ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
5533                }                }
5534              }              }
5535            break;            break;
# Line 5345  for (;;) Line 5545  for (;;)
5545                  break;                  break;
5546                  }                  }
5547                eptr++;                eptr++;
5548                while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;                ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
5549                }                }
5550              }              }
5551            else            else
# Line 5578  for (;;) Line 5778  for (;;)
5778            }            }
5779          }          }
5780        else        else
5781  #endif  /* SUPPORT_UTF8 */  #endif  /* SUPPORT_UTF */
5782          /* Not UTF mode */
       /* Not UTF-8 mode */  
5783          {          {
5784          switch(ctype)          switch(ctype)
5785            {            {
# Line 5624  for (;;) Line 5823  for (;;)
5823                }                }
5824              else              else
5825                {                {
5826                if (c != 0x000a &&                if (c != 0x000a && (md->bsr_anycrlf ||
5827                    (md->bsr_anycrlf ||                  (c != 0x000b && c != 0x000c && c != 0x0085
5828                      (c != 0x000b && c != 0x000c && c != 0x0085)))  #ifdef COMPILE_PCRE16
5829                  break;                  && c != 0x2028 && c != 0x2029
5830    #endif
5831                    ))) break;
5832                eptr++;                eptr++;
5833                }                }
5834              }              }
# Line 5642  for (;;) Line 5843  for (;;)
5843                break;                break;
5844                }                }
5845              c = *eptr;              c = *eptr;
5846              if (c == 0x09 || c == 0x20 || c == 0xa0) break;              if (c == 0x09 || c == 0x20 || c == 0xa0
5847    #ifdef COMPILE_PCRE16
5848                  || c == 0x1680 || c == 0x180e || (c >= 0x2000 && c <= 0x200A)
5849                  || c == 0x202f || c == 0x205f || c == 0x3000
5850    #endif
5851                  ) break;
5852              eptr++;              eptr++;
5853              }              }
5854            break;            break;
# Line 5656  for (;;) Line 5862  for (;;)
5862                break;                break;
5863                }                }
5864              c = *eptr;              c = *eptr;
5865              if (c != 0x09 && c != 0x20 && c != 0xa0) break;              if (c != 0x09 && c != 0x20 && c != 0xa0
5866    #ifdef COMPILE_PCRE16
5867                  && c != 0x1680 && c != 0x180e && (c < 0x2000 || c > 0x200A)
5868                  && c != 0x202f && c != 0x205f && c != 0x3000
5869    #endif
5870                  ) break;
5871              eptr++;              eptr++;
5872              }              }
5873            break;            break;
# Line 5670  for (;;) Line 5881  for (;;)
5881                break;                break;
5882                }                }
5883              c = *eptr;              c = *eptr;
5884              if (c == 0x0a || c == 0x0b || c == 0x0c || c == 0x0d || c == 0x85)              if (c == 0x0a || c == 0x0b || c == 0x0c || c == 0x0d || c == 0x85
5885                break;  #ifdef COMPILE_PCRE16
5886                  || c == 0x2028 || c == 0x2029
5887    #endif
5888                  ) break;
5889              eptr++;              eptr++;
5890              }              }
5891            break;            break;
# Line 5685  for (;;) Line 5899  for (;;)
5899                break;                break;
5900                }                }
5901              c = *eptr;              c = *eptr;
5902              if (c != 0x0a && c != 0x0b && c != 0x0c && c != 0x0d && c != 0x85)              if (c != 0x0a && c != 0x0b && c != 0x0c && c != 0x0d && c != 0x85
5903                break;  #ifdef COMPILE_PCRE16
5904                  && c != 0x2028 && c != 0x2029
5905    #endif
5906                  ) break;
5907              eptr++;              eptr++;
5908              }              }
5909            break;            break;
# Line 5699  for (;;) Line 5916  for (;;)
5916                SCHECK_PARTIAL();                SCHECK_PARTIAL();
5917                break;                break;
5918                }                }
5919              if ((md->ctypes[*eptr] & ctype_digit) != 0) break;              if (MAX_255(*eptr) && (md->ctypes[*eptr] & ctype_digit) != 0) break;
5920              eptr++;              eptr++;
5921              }              }
5922            break;            break;
# Line 5712  for (;;) Line 5929  for (;;)
5929                SCHECK_PARTIAL();                SCHECK_PARTIAL();
5930                break;                break;
5931                }                }
5932              if ((md->ctypes[*eptr] & ctype_digit) == 0) break;              if (!MAX_255(*eptr) || (md->ctypes[*eptr] & ctype_digit) == 0) break;
5933              eptr++;              eptr++;
5934              }              }
5935            break;            break;
# Line 5725  for (;;) Line 5942  for (;;)
5942                SCHECK_PARTIAL();                SCHECK_PARTIAL();
5943                break;                break;
5944                }                }
5945              if ((md->ctypes[*eptr] & ctype_space) != 0) break;              if (MAX_255(*eptr) && (md->ctypes[*eptr] & ctype_space) != 0) break;
5946              eptr++;              eptr++;
5947              }              }
5948            break;            break;
# Line 5738  for (;;) Line 5955  for (;;)
5955                SCHECK_PARTIAL();                SCHECK_PARTIAL();
5956                break;                break;
5957                }                }
5958              if ((md->ctypes[*eptr] & ctype_space) == 0) break;              if (!MAX_255(*eptr) || (md->ctypes[*eptr] & ctype_space) == 0) break;
5959              eptr++;              eptr++;
5960              }              }
5961            break;            break;
# Line 5751  for (;;) Line 5968  for (;;)
5968                SCHECK_PARTIAL();                SCHECK_PARTIAL();
5969                break;                break;
5970                }                }
5971              if ((md->ctypes[*eptr] & ctype_word) != 0) break;              if (MAX_255(*eptr) && (md->ctypes[*eptr] & ctype_word) != 0) break;
5972              eptr++;              eptr++;
5973              }              }
5974            break;            break;
# Line 5764  for (;;) Line 5981  for (;;)
5981                SCHECK_PARTIAL();                SCHECK_PARTIAL();
5982                break;                break;
5983                }                }
5984              if ((md->ctypes[*eptr] & ctype_word) == 0) break;              if (!MAX_255(*eptr) || (md->ctypes[*eptr] & ctype_word) == 0) break;
5985              eptr++;              eptr++;
5986              }              }
5987            break;            break;
# Line 5827  switch (frame->Xwhere) Line 6044  switch (frame->Xwhere)
6044    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)
6045    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)
6046    LBL(65) LBL(66)    LBL(65) LBL(66)
6047  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
6048    LBL(16) LBL(18) LBL(20) LBL(21) LBL(22) LBL(23) LBL(28) LBL(30)    LBL(21)
6049    #endif
6050    #ifdef SUPPORT_UTF
6051      LBL(16) LBL(18) LBL(20)
6052      LBL(22) LBL(23) LBL(28) LBL(30)
6053    LBL(32) LBL(34) LBL(42) LBL(46)    LBL(32) LBL(34) LBL(42) LBL(46)
6054  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
6055    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)
6056    LBL(59) LBL(60) LBL(61) LBL(62)    LBL(59) LBL(60) LBL(61) LBL(62)
6057  #endif  /* SUPPORT_UCP */  #endif  /* SUPPORT_UCP */
6058  #endif  /* SUPPORT_UTF8 */  #endif  /* SUPPORT_UTF */
6059    default:    default:
6060    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));
6061    
6062    printf("+++jump error in pcre match: label %d non-existent\n", frame->Xwhere);
6063    
6064    return PCRE_ERROR_INTERNAL;    return PCRE_ERROR_INTERNAL;
6065    }    }
6066  #undef LBL  #undef LBL
# Line 5923  Returns:          > 0 => success; value Line 6147  Returns:          > 0 => success; value
6147                   < -1 => some kind of unexpected problem                   < -1 => some kind of unexpected problem
6148  */  */
6149    
6150    #ifdef COMPILE_PCRE8
6151  PCRE_EXP_DEFN int PCRE_CALL_CONVENTION  PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
6152  pcre_exec(const pcre *argument_re, const pcre_extra *extra_data,  pcre_exec(const pcre *argument_re, const pcre_extra *extra_data,
6153    PCRE_SPTR subject, int length, int start_offset, int options, int *offsets,    PCRE_SPTR subject, int length, int start_offset, int options, int *offsets,
6154    int offsetcount)    int offsetcount)
6155    #else
6156    PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
6157    pcre16_exec(const pcre16 *argument_re, const pcre16_extra *extra_data,
6158      PCRE_SPTR16 subject, int length, int start_offset, int options, int *offsets,
6159      int offsetcount)
6160    #endif
6161  {  {
6162  int rc, ocount, arg_offset_max;  int rc, ocount, arg_offset_max;
 int first_byte = -1;  
 int req_byte = -1;  
 int req_byte2 = -1;  
6163  int newline;  int newline;
6164  BOOL using_temporary_offsets = FALSE;  BOOL using_temporary_offsets = FALSE;
6165  BOOL anchored;  BOOL anchored;
6166  BOOL startline;  BOOL startline;
6167  BOOL firstline;  BOOL firstline;
6168  BOOL first_byte_caseless = FALSE;  BOOL utf;
6169  BOOL req_byte_caseless = FALSE;  BOOL has_first_char = FALSE;
6170  BOOL utf8;  BOOL has_req_char = FALSE;
6171    pcre_uchar first_char = 0;
6172    pcre_uchar first_char2 = 0;
6173    pcre_uchar req_char = 0;
6174    pcre_uchar req_char2 = 0;
6175  match_data match_block;  match_data match_block;
6176  match_data *md = &match_block;  match_data *md = &match_block;
6177  const uschar *tables;  const pcre_uint8 *tables;
6178  const uschar *start_bits = NULL;  const pcre_uint8 *start_bits = NULL;
6179  USPTR start_match = (USPTR)subject + start_offset;  PCRE_PUCHAR start_match = (PCRE_PUCHAR)subject + start_offset;
6180  USPTR end_subject;  PCRE_PUCHAR end_subject;
6181  USPTR start_partial = NULL;  PCRE_PUCHAR start_partial = NULL;
6182  USPTR req_byte_ptr = start_match - 1;  PCRE_PUCHAR req_char_ptr = start_match - 1;
6183    
 pcre_study_data internal_study;  
6184  const pcre_study_data *study;  const pcre_study_data *study;
6185    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;  
6186    
6187  /* Plausibility checks */  /* Plausibility checks */
6188    
# Line 5969  follows immediately afterwards. Other va Line 6197  follows immediately afterwards. Other va
6197  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,
6198  so they are set up later. */  so they are set up later. */
6199    
6200  utf8 = md->utf8 = (re->options & PCRE_UTF8) != 0;  /* PCRE_UTF16 has the same value as PCRE_UTF8. */
6201    utf = md->utf = (re->options & PCRE_UTF8) != 0;
6202  md->partial = ((options & PCRE_PARTIAL_HARD) != 0)? 2 :  md->partial = ((options & PCRE_PARTIAL_HARD) != 0)? 2 :
6203                ((options & PCRE_PARTIAL_SOFT) != 0)? 1 : 0;                ((options & PCRE_PARTIAL_SOFT) != 0)? 1 : 0;
6204    
6205  /* 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
6206  code for an invalid string if a results vector is available. */  code for an invalid string if a results vector is available. */
6207    
6208  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
6209  if (utf8 && (options & PCRE_NO_UTF8_CHECK) == 0)  if (utf && (options & PCRE_NO_UTF8_CHECK) == 0)
6210    {    {
6211    int erroroffset;    int erroroffset;
6212    int errorcode = _pcre_valid_utf8((USPTR)subject, length, &erroroffset);    int errorcode = PRIV(valid_utf)((PCRE_PUCHAR)subject, length, &erroroffset);
6213    if (errorcode != 0)    if (errorcode != 0)
6214      {      {
6215      if (offsetcount >= 2)      if (offsetcount >= 2)
# Line 5988  if (utf8 && (options & PCRE_NO_UTF8_CHEC Line 6217  if (utf8 && (options & PCRE_NO_UTF8_CHEC
6217        offsets[0] = erroroffset;        offsets[0] = erroroffset;
6218        offsets[1] = errorcode;        offsets[1] = errorcode;
6219        }        }
6220    #ifdef COMPILE_PCRE16
6221        return (errorcode <= PCRE_UTF16_ERR1 && md->partial > 1)?
6222          PCRE_ERROR_SHORTUTF16 : PCRE_ERROR_BADUTF16;
6223    #else
6224      return (errorcode <= PCRE_UTF8_ERR5 && md->partial > 1)?      return (errorcode <= PCRE_UTF8_ERR5 && md->partial > 1)?
6225        PCRE_ERROR_SHORTUTF8 : PCRE_ERROR_BADUTF8;        PCRE_ERROR_SHORTUTF8 : PCRE_ERROR_BADUTF8;
6226    #endif
6227      }      }
6228    
6229    /* 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. */
6230    if (start_offset > 0 && start_offset < length &&    if (start_offset > 0 && start_offset < length &&
6231        (((USPTR)subject)[start_offset] & 0xc0) == 0x80)        NOT_FIRSTCHAR(((PCRE_PUCHAR)subject)[start_offset]))
6232      return PCRE_ERROR_BADUTF8_OFFSET;      return PCRE_ERROR_BADUTF8_OFFSET;
6233    }    }
6234  #endif  #endif
# Line 6012  if (extra_data != NULL Line 6246  if (extra_data != NULL
6246      && (extra_data->flags & PCRE_EXTRA_TABLES) == 0      && (extra_data->flags & PCRE_EXTRA_TABLES) == 0
6247      && (options & ~(PCRE_NO_UTF8_CHECK | PCRE_NOTBOL | PCRE_NOTEOL |      && (options & ~(PCRE_NO_UTF8_CHECK | PCRE_NOTBOL | PCRE_NOTEOL |
6248                      PCRE_NOTEMPTY | PCRE_NOTEMPTY_ATSTART)) == 0)                      PCRE_NOTEMPTY | PCRE_NOTEMPTY_ATSTART)) == 0)
6249    return _pcre_jit_exec(re, extra_data->executable_jit, subject, length,    return PRIV(jit_exec)(re, extra_data->executable_jit,
6250      start_offset, options, ((extra_data->flags & PCRE_EXTRA_MATCH_LIMIT) == 0)      (const pcre_uchar *)subject, length, start_offset, options,
6251        ((extra_data->flags & PCRE_EXTRA_MATCH_LIMIT) == 0)
6252      ? MATCH_LIMIT : extra_data->match_limit, offsets, offsetcount);      ? MATCH_LIMIT : extra_data->match_limit, offsets, offsetcount);
6253  #endif  #endif
6254    
6255  /* 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
6256  numbers associated with a given name, for condition testing. */  numbers associated with a given name, for condition testing. */
6257    
6258  md->name_table = (uschar *)re + re->name_table_offset;  md->name_table = (pcre_uchar *)re + re->name_table_offset;
6259  md->name_count = re->name_count;  md->name_count = re->name_count;
6260  md->name_entry_size = re->name_entry_size;  md->name_entry_size = re->name_entry_size;
6261    
# Line 6034  md->callout_data = NULL; Line 6269  md->callout_data = NULL;
6269    
6270  /* The table pointer is always in native byte order. */  /* The table pointer is always in native byte order. */
6271    
6272  tables = external_re->tables;  tables = re->tables;
6273    
6274  if (extra_data != NULL)  if (extra_data != NULL)
6275    {    {
# Line 6054  if (extra_data != NULL) Line 6289  if (extra_data != NULL)
6289  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
6290  in other programs later. */  in other programs later. */
6291    
6292  if (tables == NULL) tables = _pcre_default_tables;  if (tables == NULL) tables = PRIV(default_tables);
6293    
6294  /* 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,
6295  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
6296  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
6297  study data too. */  means that the pattern is likely compiled with different endianness. */
6298    
6299  if (re->magic_number != MAGIC_NUMBER)  if (re->magic_number != MAGIC_NUMBER)
6300    {    return re->magic_number == REVERSED_MAGIC_NUMBER?
6301    re = _pcre_try_flipped(re, &internal_re, study, &internal_study);      PCRE_ERROR_BADENDIANNESS:PCRE_ERROR_BADMAGIC;
6302    if (re == NULL) return PCRE_ERROR_BADMAGIC;  if ((re->flags & PCRE_MODE) == 0) return PCRE_ERROR_BADMODE;
   if (study != NULL) study = &internal_study;  
   }  
6303    
6304  /* Set up other data */  /* Set up other data */
6305    
# Line 6076  firstline = (re->options & PCRE_FIRSTLIN Line 6309  firstline = (re->options & PCRE_FIRSTLIN
6309    
6310  /* 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. */
6311    
6312  md->start_code = (const uschar *)external_re + re->name_table_offset +  md->start_code = (const pcre_uchar *)re + re->name_table_offset +
6313    re->name_count * re->name_entry_size;    re->name_count * re->name_entry_size;
6314    
6315  md->start_subject = (USPTR)subject;  md->start_subject = (PCRE_PUCHAR)subject;
6316  md->start_offset = start_offset;  md->start_offset = start_offset;
6317  md->end_subject = md->start_subject + length;  md->end_subject = md->start_subject + length;
6318  end_subject = md->end_subject;  end_subject = md->end_subject;
# Line 6104  md->recursive = NULL; Line 6337  md->recursive = NULL;
6337  md->hasthen = (re->flags & PCRE_HASTHEN) != 0;  md->hasthen = (re->flags & PCRE_HASTHEN) != 0;
6338    
6339  md->lcc = tables + lcc_offset;  md->lcc = tables + lcc_offset;
6340    md->fcc = tables + fcc_offset;
6341  md->ctypes = tables + ctypes_offset;  md->ctypes = tables + ctypes_offset;
6342    
6343  /* Handle different \R options. */  /* Handle different \R options. */
# Line 6190  arg_offset_max = (2*ocount)/3; Line 6424  arg_offset_max = (2*ocount)/3;
6424  if (re->top_backref > 0 && re->top_backref >= ocount/3)  if (re->top_backref > 0 && re->top_backref >= ocount/3)
6425    {    {
6426    ocount = re->top_backref * 3 + 3;    ocount = re->top_backref * 3 + 3;
6427    md->offset_vector = (int *)(pcre_malloc)(ocount * sizeof(int));    md->offset_vector = (int *)(PUBL(malloc))(ocount * sizeof(int));
6428    if (md->offset_vector == NULL) return PCRE_ERROR_NOMEMORY;    if (md->offset_vector == NULL) return PCRE_ERROR_NOMEMORY;
6429    using_temporary_offsets = TRUE;    using_temporary_offsets = TRUE;
6430    DPRINTF(("Got memory to hold back references\n"));    DPRINTF(("Got memory to hold back references\n"));
# Line 6217  if (md->offset_vector != NULL) Line 6451  if (md->offset_vector != NULL)
6451    md->offset_vector[0] = md->offset_vector[1] = -1;    md->offset_vector[0] = md->offset_vector[1] = -1;
6452    }    }
6453    
6454  /* 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
6455  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
6456  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
6457  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 6461  if (!anchored)
6461    {    {
6462    if ((re->flags & PCRE_FIRSTSET) != 0)    if ((re->flags & PCRE_FIRSTSET) != 0)
6463      {      {
6464      first_byte = re->first_byte & 255;      has_first_char = TRUE;
6465      if ((first_byte_caseless = ((re->first_byte & REQ_CASELESS) != 0)) == TRUE)      first_char = first_char2 = re->first_char;
6466        first_byte = md->lcc[first_byte];      if ((re->flags & PCRE_FCH_CASELESS) != 0)
6467          {
6468          first_char2 = TABLE_GET(first_char, md->fcc, first_char);
6469    #if defined SUPPORT_UCP && !(defined COMPILE_PCRE8)
6470          if (utf && first_char > 127)
6471            first_char2 = UCD_OTHERCASE(first_char);
6472    #endif
6473          }
6474      }      }
6475    else    else
6476      if (!startline && study != NULL &&      if (!startline && study != NULL &&
# Line 6242  character" set. */ Line 6483  character" set. */
6483    
6484  if ((re->flags & PCRE_REQCHSET) != 0)  if ((re->flags & PCRE_REQCHSET) != 0)
6485    {    {
6486    req_byte = re->req_byte & 255;    has_req_char = TRUE;
6487    req_byte_caseless = (re->req_byte & REQ_CASELESS) != 0;    req_char = req_char2 = re->req_char;
6488    req_byte2 = (tables + fcc_offset)[req_byte];  /* case flipped */    if ((re->flags & PCRE_RCH_CASELESS) != 0)
6489        {
6490        req_char2 = TABLE_GET(req_char, md->fcc, req_char);
6491    #if defined SUPPORT_UCP && !(defined COMPILE_PCRE8)
6492        if (utf && req_char > 127)
6493          req_char2 = UCD_OTHERCASE(req_char);
6494    #endif
6495        }
6496    }    }
6497    
6498    
   
   
6499  /* ==========================================================================*/  /* ==========================================================================*/
6500    
6501  /* 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 6503  the loop runs just once. */
6503    
6504  for(;;)  for(;;)
6505    {    {
6506    USPTR save_end_subject = end_subject;    PCRE_PUCHAR save_end_subject = end_subject;
6507    USPTR new_start_match;    PCRE_PUCHAR new_start_match;
6508    
6509    /* 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
6510    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 6514  for(;;)
6514    
6515    if (firstline)    if (firstline)
6516      {      {
6517      USPTR t = start_match;      PCRE_PUCHAR t = start_match;
6518  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
6519      if (utf8)      if (utf)
6520        {        {
6521        while (t < md->end_subject && !IS_NEWLINE(t))        while (t < md->end_subject && !IS_NEWLINE(t))
6522          {          {
6523          t++;          t++;
6524          while (t < end_subject && (*t & 0xc0) == 0x80) t++;          ACROSSCHAR(t < end_subject, *t, t++);
6525          }          }
6526        }        }
6527      else      else
# Line 6292  for(;;) Line 6538  for(;;)
6538    
6539    if (((options | re->options) & PCRE_NO_START_OPTIMIZE) == 0)    if (((options | re->options) & PCRE_NO_START_OPTIMIZE) == 0)
6540      {      {
6541      /* Advance to a unique first byte if there is one. */      /* Advance to a unique first char if there is one. */
6542    
6543      if (first_byte >= 0)      if (has_first_char)
6544        {        {
6545        if (first_byte_caseless)        if (first_char != first_char2)
6546          while (start_match < end_subject && md->lcc[*start_match] != first_byte)          while (start_match < end_subject &&
6547                *start_match != first_char && *start_match != first_char2)
6548            start_match++;            start_match++;
6549        else        else
6550          while (start_match < end_subject && *start_match != first_byte)          while (start_match < end_subject && *start_match != first_char)
6551            start_match++;            start_match++;
6552        }        }
6553    
# Line 6310  for(;;) Line 6557  for(;;)
6557        {        {
6558        if (start_match > md->start_subject + start_offset)        if (start_match > md->start_subject + start_offset)
6559          {          {
6560  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
6561          if (utf8)          if (utf)
6562            {            {
6563            while (start_match < end_subject && !WAS_NEWLINE(start_match))            while (start_match < end_subject && !WAS_NEWLINE(start_match))
6564              {              {
6565              start_match++;              start_match++;
6566              while(start_match < end_subject && (*start_match & 0xc0) == 0x80)              ACROSSCHAR(start_match < end_subject, *start_match,
6567                start_match++;                start_match++);
6568              }              }
6569            }            }
6570          else          else
# Line 6344  for(;;) Line 6591  for(;;)
6591        while (start_match < end_subject)        while (start_match < end_subject)
6592          {          {
6593          register unsigned int c = *start_match;          register unsigned int c = *start_match;
6594    #ifndef COMPILE_PCRE8
6595            if (c > 255) c = 255;
6596    #endif
6597          if ((start_bits[c/8] & (1 << (c&7))) == 0)          if ((start_bits[c/8] & (1 << (c&7))) == 0)
6598            {            {
6599            start_match++;            start_match++;
6600  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF && defined COMPILE_PCRE8
6601            if (utf8)            /* In non 8-bit mode, the iteration will stop for
6602              while(start_match < end_subject && (*start_match & 0xc0) == 0x80)            characters > 255 at the beginning or not stop at all. */
6603                start_match++;            if (utf)
6604                ACROSSCHAR(start_match < end_subject, *start_match,
6605                  start_match++);
6606  #endif  #endif
6607            }            }
6608          else break;          else break;
# Line 6379  for(;;) Line 6631  for(;;)
6631        break;        break;
6632        }        }
6633    
6634      /* 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
6635      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
6636      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.
6637      This optimization can save a huge amount of backtracking in patterns with      This optimization can save a huge amount of backtracking in patterns with
6638      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 6645  for(;;)
6645      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
6646      long. */      long. */
6647    
6648      if (req_byte >= 0 && end_subject - start_match < REQ_BYTE_MAX)      if (has_req_char && end_subject - start_match < REQ_BYTE_MAX)
6649        {        {
6650        register USPTR p = start_match + ((first_byte >= 0)? 1 : 0);        register PCRE_PUCHAR p = start_match + (has_first_char? 1:0);
6651    
6652        /* 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
6653        place we found it at last time. */        place we found it at last time. */
6654    
6655        if (p > req_byte_ptr)        if (p > req_char_ptr)
6656          {          {
6657          if (req_byte_caseless)          if (req_char != req_char2)
6658            {            {
6659            while (p < end_subject)            while (p < end_subject)
6660              {              {
6661              register int pp = *p++;              register int pp = *p++;
6662              if (pp == req_byte || pp == req_byte2) { p--; break; }              if (pp == req_char || pp == req_char2) { p--; break; }
6663              }              }
6664            }            }
6665          else          else
6666            {            {
6667            while (p < end_subject)            while (p < end_subject)
6668              {              {
6669              if (*p++ == req_byte) { p--; break; }              if (*p++ == req_char) { p--; break; }
6670              }              }
6671            }            }
6672    
# Line 6431  for(;;) Line 6683  for(;;)
6683          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
6684          the start hasn't passed this character yet. */          the start hasn't passed this character yet. */
6685    
6686          req_byte_ptr = p;          req_char_ptr = p;
6687          }          }
6688        }        }
6689      }      }
# Line 6456  for(;;) Line 6708  for(;;)
6708    switch(rc)    switch(rc)
6709      {      {
6710      /* If MATCH_SKIP_ARG reaches this level it means that a MARK that matched      /* If MATCH_SKIP_ARG reaches this level it means that a MARK that matched
6711      the SKIP's arg was not found. In this circumstance, Perl ignores the SKIP      the SKIP's arg was not found. In this circumstance, Perl ignores the SKIP
6712      entirely. The only way we can do that is to re-do the match at the same      entirely. The only way we can do that is to re-do the match at the same
6713      point, with a flag to force SKIP with an argument to be ignored. Just      point, with a flag to force SKIP with an argument to be ignored. Just
6714      treating this case as NOMATCH does not work because it does not check other      treating this case as NOMATCH does not work because it does not check other
6715      alternatives in patterns such as A(*SKIP:A)B|AC when the subject is AC. */      alternatives in patterns such as A(*SKIP:A)B|AC when the subject is AC. */
6716    
6717      case MATCH_SKIP_ARG:      case MATCH_SKIP_ARG:
6718      new_start_match = start_match;      new_start_match = start_match;
6719      md->ignore_skip_arg = TRUE;      md->ignore_skip_arg = TRUE;
6720      break;      break;
6721    
6722      /* SKIP passes back the next starting point explicitly, but if it is the      /* SKIP passes back the next starting point explicitly, but if it is the
6723      same as the match we have just done, treat it as NOMATCH. */      same as the match we have just done, treat it as NOMATCH. */
# Line 6486  for(;;) Line 6738  for(;;)
6738      case MATCH_THEN:      case MATCH_THEN:
6739      md->ignore_skip_arg = FALSE;      md->ignore_skip_arg = FALSE;
6740      new_start_match = start_match + 1;      new_start_match = start_match + 1;
6741  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
6742      if (utf8)      if (utf)
6743        while(new_start_match < end_subject && (*new_start_match & 0xc0) == 0x80)        ACROSSCHAR(new_start_match < end_subject, *new_start_match,
6744          new_start_match++;          new_start_match++);
6745  #endif  #endif
6746      break;      break;
6747    
# Line 6527  for(;;) Line 6779  for(;;)
6779    
6780    /* 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
6781    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
6782    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
6783      normal matching start_match will aways be greater than the first position at
6784      this stage, but a failed *SKIP can cause a return at the same point, which is
6785      why the first test exists. */
6786    
6787    if (start_match[-1] == CHAR_CR &&    if (start_match > (PCRE_PUCHAR)subject + start_offset &&
6788          start_match[-1] == CHAR_CR &&
6789        start_match < end_subject &&        start_match < end_subject &&
6790        *start_match == CHAR_NL &&        *start_match == CHAR_NL &&
6791        (re->flags & PCRE_HASCRORLF) == 0 &&        (re->flags & PCRE_HASCRORLF) == 0 &&
# Line 6575  if (rc == MATCH_MATCH || rc == MATCH_ACC Line 6831  if (rc == MATCH_MATCH || rc == MATCH_ACC
6831        }        }
6832      if (md->end_offset_top > arg_offset_max) md->offset_overflow = TRUE;      if (md->end_offset_top > arg_offset_max) md->offset_overflow = TRUE;
6833      DPRINTF(("Freeing temporary memory\n"));      DPRINTF(("Freeing temporary memory\n"));
6834      (pcre_free)(md->offset_vector);      (PUBL(free))(md->offset_vector);
6835      }      }
6836    
6837    /* 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 6614  if (rc == MATCH_MATCH || rc == MATCH_ACC Line 6870  if (rc == MATCH_MATCH || rc == MATCH_ACC
6870      }      }
6871    
6872    /* Return MARK data if requested */    /* Return MARK data if requested */
6873    
6874    if (extra_data != NULL && (extra_data->flags & PCRE_EXTRA_MARK) != 0)    if (extra_data != NULL && (extra_data->flags & PCRE_EXTRA_MARK) != 0)
6875      *(extra_data->mark) = (unsigned char *)(md->mark);      *(extra_data->mark) = (pcre_uchar *)md->mark;
6876    DPRINTF((">>>> returning %d\n", rc));    DPRINTF((">>>> returning %d\n", rc));
6877    return rc;    return rc;
6878    }    }
# Line 6627  attempt has failed at all permitted star Line 6883  attempt has failed at all permitted star
6883  if (using_temporary_offsets)  if (using_temporary_offsets)
6884    {    {
6885    DPRINTF(("Freeing temporary memory\n"));    DPRINTF(("Freeing temporary memory\n"));
6886    (pcre_free)(md->offset_vector);    (PUBL(free))(md->offset_vector);
6887    }    }
6888    
6889  /* 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 6902  if (start_partial != NULL)
6902    md->mark = NULL;    md->mark = NULL;
6903    if (offsetcount > 1)    if (offsetcount > 1)
6904      {      {
6905      offsets[0] = (int)(start_partial - (USPTR)subject);      offsets[0] = (int)(start_partial - (PCRE_PUCHAR)subject);
6906      offsets[1] = (int)(end_subject - (USPTR)subject);      offsets[1] = (int)(end_subject - (PCRE_PUCHAR)subject);
6907      }      }
6908    rc = PCRE_ERROR_PARTIAL;    rc = PCRE_ERROR_PARTIAL;
6909    }    }
# Line 6663  else Line 6919  else
6919  /* Return the MARK data if it has been requested. */  /* Return the MARK data if it has been requested. */
6920    
6921  if (extra_data != NULL && (extra_data->flags & PCRE_EXTRA_MARK) != 0)  if (extra_data != NULL && (extra_data->flags & PCRE_EXTRA_MARK) != 0)
6922    *(extra_data->mark) = (unsigned char *)(md->nomatch_mark);    *(extra_data->mark) = (pcre_uchar *)md->nomatch_mark;
6923  return rc;  return rc;
6924  }  }
6925    

Legend:
Removed from v.779  
changed lines
  Added in v.882

  ViewVC Help
Powered by ViewVC 1.1.5