/[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 771 by ph10, Tue Nov 29 15:34:12 2011 UTC revision 852 by zherczeg, Thu Jan 5 19:18:12 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 217  else Line 221  else
221    while (length-- > 0) if (*p++ != *eptr++) return -1;    while (length-- > 0) if (*p++ != *eptr++) return -1;
222    }    }
223    
224  return eptr - eptr_start;  return (int)(eptr - eptr_start);
225  }  }
226    
227    
# 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 417  returns a negative (error) response, the Line 421  returns a negative (error) response, the
421  same response. */  same response. */
422    
423  /* These macros pack up tests that are used for partial matching, and which  /* These macros pack up tests that are used for partial matching, and which
424  appears several times in the code. We set the "hit end" flag if the pointer is  appear several times in the code. We set the "hit end" flag if the pointer is
425  at the end of the subject and also past the start of the subject (i.e.  at the end of the subject and also past the start of the subject (i.e.
426  something has been matched). For hard partial matching, we then return  something has been matched). For hard partial matching, we then return
427  immediately. The second one is used when we already know we are past the end of  immediately. The second one is used when we already know we are past the end of
# 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    
630  /* These statements are here to stop the compiler complaining about unitialized  /* These statements are here to stop the compiler complaining about unitialized
631  variables. */  variables. */
# Line 645  defined). However, RMATCH isn't like a f Line 651  defined). However, RMATCH isn't like a f
651  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,
652  however, impact performance when true recursion is being used. */  however, impact performance when true recursion is being used. */
653    
654  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
655  utf8 = md->utf8;       /* Local copy of the flag */  utf = md->utf;       /* Local copy of the flag */
656  #else  #else
657  utf8 = FALSE;  utf = FALSE;
658  #endif  #endif
659    
660  /* 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 695  for (;;)
695      case OP_MARK:      case OP_MARK:
696      md->nomatch_mark = ecode + 2;      md->nomatch_mark = ecode + 2;
697      md->mark = NULL;    /* In case previously set by assertion */      md->mark = NULL;    /* In case previously set by assertion */
698      RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode] + ecode[1], offset_top, md,      RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode] + ecode[1], offset_top, md,
699        eptrb, RM55);        eptrb, RM55);
700      if ((rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) &&      if ((rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) &&
701           md->mark == NULL) md->mark = ecode + 2;           md->mark == NULL) md->mark = ecode + 2;
# Line 702  for (;;) Line 708  for (;;)
708      unaltered. */      unaltered. */
709    
710      else if (rrc == MATCH_SKIP_ARG &&      else if (rrc == MATCH_SKIP_ARG &&
711          strcmp((char *)(ecode + 2), (char *)(md->start_match_ptr)) == 0)          STRCMP_UC_UC(ecode + 2, md->start_match_ptr) == 0)
712        {        {
713        md->start_match_ptr = eptr;        md->start_match_ptr = eptr;
714        RRETURN(MATCH_SKIP);        RRETURN(MATCH_SKIP);
# Line 715  for (;;) Line 721  for (;;)
721      /* COMMIT overrides PRUNE, SKIP, and THEN */      /* COMMIT overrides PRUNE, SKIP, and THEN */
722    
723      case OP_COMMIT:      case OP_COMMIT:
724      RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,      RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md,
725        eptrb, RM52);        eptrb, RM52);
726      if (rrc != MATCH_NOMATCH && rrc != MATCH_PRUNE &&      if (rrc != MATCH_NOMATCH && rrc != MATCH_PRUNE &&
727          rrc != MATCH_SKIP && rrc != MATCH_SKIP_ARG &&          rrc != MATCH_SKIP && rrc != MATCH_SKIP_ARG &&
# Line 726  for (;;) Line 732  for (;;)
732      /* PRUNE overrides THEN */      /* PRUNE overrides THEN */
733    
734      case OP_PRUNE:      case OP_PRUNE:
735      RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,      RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md,
736        eptrb, RM51);        eptrb, RM51);
737      if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);      if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);
738      RRETURN(MATCH_PRUNE);      RRETURN(MATCH_PRUNE);
# Line 734  for (;;) Line 740  for (;;)
740      case OP_PRUNE_ARG:      case OP_PRUNE_ARG:
741      md->nomatch_mark = ecode + 2;      md->nomatch_mark = ecode + 2;
742      md->mark = NULL;    /* In case previously set by assertion */      md->mark = NULL;    /* In case previously set by assertion */
743      RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode] + ecode[1], offset_top, md,      RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode] + ecode[1], offset_top, md,
744        eptrb, RM56);        eptrb, RM56);
745      if ((rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) &&      if ((rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) &&
746           md->mark == NULL) md->mark = ecode + 2;           md->mark == NULL) md->mark = ecode + 2;
# Line 744  for (;;) Line 750  for (;;)
750      /* SKIP overrides PRUNE and THEN */      /* SKIP overrides PRUNE and THEN */
751    
752      case OP_SKIP:      case OP_SKIP:
753      RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,      RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md,
754        eptrb, RM53);        eptrb, RM53);
755      if (rrc != MATCH_NOMATCH && rrc != MATCH_PRUNE && rrc != MATCH_THEN)      if (rrc != MATCH_NOMATCH && rrc != MATCH_PRUNE && rrc != MATCH_THEN)
756        RRETURN(rrc);        RRETURN(rrc);
# Line 752  for (;;) Line 758  for (;;)
758      RRETURN(MATCH_SKIP);      RRETURN(MATCH_SKIP);
759    
760      /* Note that, for Perl compatibility, SKIP with an argument does NOT set      /* Note that, for Perl compatibility, SKIP with an argument does NOT set
761      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
762      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. */
763    
764      case OP_SKIP_ARG:      case OP_SKIP_ARG:
765      if (md->ignore_skip_arg)      if (md->ignore_skip_arg)
766        {        {
767        ecode += _pcre_OP_lengths[*ecode] + ecode[1];        ecode += PRIV(OP_lengths)[*ecode] + ecode[1];
768        break;        break;
769        }        }
770      RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode] + ecode[1], offset_top, md,      RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode] + ecode[1], offset_top, md,
771        eptrb, RM57);        eptrb, RM57);
772      if (rrc != MATCH_NOMATCH && rrc != MATCH_PRUNE && rrc != MATCH_THEN)      if (rrc != MATCH_NOMATCH && rrc != MATCH_PRUNE && rrc != MATCH_THEN)
773        RRETURN(rrc);        RRETURN(rrc);
774    
775      /* 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
776      returning the special MATCH_SKIP_ARG return code. This will either be      returning the special MATCH_SKIP_ARG return code. This will either be
777      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
778      with the md->ignore_skip_arg flag set. */      with the md->ignore_skip_arg flag set. */
779    
780      md->start_match_ptr = ecode + 2;      md->start_match_ptr = ecode + 2;
# Line 779  for (;;) Line 785  for (;;)
785      match pointer to do this. */      match pointer to do this. */
786    
787      case OP_THEN:      case OP_THEN:
788      RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,      RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md,
789        eptrb, RM54);        eptrb, RM54);
790      if (rrc != MATCH_NOMATCH) RRETURN(rrc);      if (rrc != MATCH_NOMATCH) RRETURN(rrc);
791      md->start_match_ptr = ecode;      md->start_match_ptr = ecode;
# Line 788  for (;;) Line 794  for (;;)
794      case OP_THEN_ARG:      case OP_THEN_ARG:
795      md->nomatch_mark = ecode + 2;      md->nomatch_mark = ecode + 2;
796      md->mark = NULL;    /* In case previously set by assertion */      md->mark = NULL;    /* In case previously set by assertion */
797      RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode] + ecode[1], offset_top,      RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode] + ecode[1], offset_top,
798        md, eptrb, RM58);        md, eptrb, RM58);
799      if ((rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) &&      if ((rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) &&
800           md->mark == NULL) md->mark = ecode + 2;           md->mark == NULL) md->mark = ecode + 2;
# Line 917  for (;;) Line 923  for (;;)
923        for (;;)        for (;;)
924          {          {
925          if (op >= OP_SBRA) md->match_function_type = MATCH_CBEGROUP;          if (op >= OP_SBRA) md->match_function_type = MATCH_CBEGROUP;
926          RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,          RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md,
927            eptrb, RM1);            eptrb, RM1);
928          if (rrc == MATCH_ONCE) break;  /* Backing up through an atomic group */          if (rrc == MATCH_ONCE) break;  /* Backing up through an atomic group */
929    
# Line 1004  for (;;) Line 1010  for (;;)
1010    
1011        else if (!md->hasthen && ecode[GET(ecode, 1)] != OP_ALT)        else if (!md->hasthen && ecode[GET(ecode, 1)] != OP_ALT)
1012          {          {
1013          ecode += _pcre_OP_lengths[*ecode];          ecode += PRIV(OP_lengths)[*ecode];
1014          goto TAIL_RECURSE;          goto TAIL_RECURSE;
1015          }          }
1016    
1017        /* In all other cases, we have to make another call to match(). */        /* In all other cases, we have to make another call to match(). */
1018    
1019        RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md, eptrb,        RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md, eptrb,
1020          RM2);          RM2);
1021    
1022        /* See comment in the code for capturing groups above about handling        /* See comment in the code for capturing groups above about handling
# Line 1028  for (;;) Line 1034  for (;;)
1034          {          {
1035          if (rrc == MATCH_ONCE)          if (rrc == MATCH_ONCE)
1036            {            {
1037            const uschar *scode = ecode;            const pcre_uchar *scode = ecode;
1038            if (*scode != OP_ONCE)           /* If not at start, find it */            if (*scode != OP_ONCE)           /* If not at start, find it */
1039              {              {
1040              while (*scode == OP_ALT) scode += GET(scode, 1);              while (*scode == OP_ALT) scode += GET(scode, 1);
# Line 1070  for (;;) Line 1076  for (;;)
1076      if (offset < md->offset_max)      if (offset < md->offset_max)
1077        {        {
1078        matched_once = FALSE;        matched_once = FALSE;
1079        code_offset = ecode - md->start_code;        code_offset = (int)(ecode - md->start_code);
1080    
1081        save_offset1 = md->offset_vector[offset];        save_offset1 = md->offset_vector[offset];
1082        save_offset2 = md->offset_vector[offset+1];        save_offset2 = md->offset_vector[offset+1];
# Line 1093  for (;;) Line 1099  for (;;)
1099          md->offset_vector[md->offset_end - number] =          md->offset_vector[md->offset_end - number] =
1100            (int)(eptr - md->start_subject);            (int)(eptr - md->start_subject);
1101          if (op >= OP_SBRA) md->match_function_type = MATCH_CBEGROUP;          if (op >= OP_SBRA) md->match_function_type = MATCH_CBEGROUP;
1102          RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,          RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md,
1103            eptrb, RM63);            eptrb, RM63);
1104          if (rrc == MATCH_KETRPOS)          if (rrc == MATCH_KETRPOS)
1105            {            {
# Line 1160  for (;;) Line 1166  for (;;)
1166    
1167      POSSESSIVE_NON_CAPTURE:      POSSESSIVE_NON_CAPTURE:
1168      matched_once = FALSE;      matched_once = FALSE;
1169      code_offset = ecode - md->start_code;      code_offset = (int)(ecode - md->start_code);
1170    
1171      for (;;)      for (;;)
1172        {        {
1173        if (op >= OP_SBRA) md->match_function_type = MATCH_CBEGROUP;        if (op >= OP_SBRA) md->match_function_type = MATCH_CBEGROUP;
1174        RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,        RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md,
1175          eptrb, RM48);          eptrb, RM48);
1176        if (rrc == MATCH_KETRPOS)        if (rrc == MATCH_KETRPOS)
1177          {          {
# Line 1215  for (;;) Line 1221  for (;;)
1221    
1222      if (ecode[LINK_SIZE+1] == OP_CALLOUT)      if (ecode[LINK_SIZE+1] == OP_CALLOUT)
1223        {        {
1224        if (pcre_callout != NULL)        if (PUBL(callout) != NULL)
1225          {          {
1226          pcre_callout_block cb;          PUBL(callout_block) cb;
1227          cb.version          = 2;   /* Version 1 of the callout block */          cb.version          = 2;   /* Version 1 of the callout block */
1228          cb.callout_number   = ecode[LINK_SIZE+2];          cb.callout_number   = ecode[LINK_SIZE+2];
1229          cb.offset_vector    = md->offset_vector;          cb.offset_vector    = md->offset_vector;
1230    #ifdef COMPILE_PCRE8
1231          cb.subject          = (PCRE_SPTR)md->start_subject;          cb.subject          = (PCRE_SPTR)md->start_subject;
1232    #else
1233            cb.subject          = (PCRE_SPTR16)md->start_subject;
1234    #endif
1235          cb.subject_length   = (int)(md->end_subject - md->start_subject);          cb.subject_length   = (int)(md->end_subject - md->start_subject);
1236          cb.start_match      = (int)(mstart - md->start_subject);          cb.start_match      = (int)(mstart - md->start_subject);
1237          cb.current_position = (int)(eptr - md->start_subject);          cb.current_position = (int)(eptr - md->start_subject);
# Line 1231  for (;;) Line 1241  for (;;)
1241          cb.capture_last     = md->capture_last;          cb.capture_last     = md->capture_last;
1242          cb.callout_data     = md->callout_data;          cb.callout_data     = md->callout_data;
1243          cb.mark             = md->nomatch_mark;          cb.mark             = md->nomatch_mark;
1244          if ((rrc = (*pcre_callout)(&cb)) > 0) RRETURN(MATCH_NOMATCH);          if ((rrc = (*PUBL(callout))(&cb)) > 0) RRETURN(MATCH_NOMATCH);
1245          if (rrc < 0) RRETURN(rrc);          if (rrc < 0) RRETURN(rrc);
1246          }          }
1247        ecode += _pcre_OP_lengths[OP_CALLOUT];        ecode += PRIV(OP_lengths)[OP_CALLOUT];
1248        }        }
1249    
1250      condcode = ecode[LINK_SIZE+1];      condcode = ecode[LINK_SIZE+1];
# Line 1260  for (;;) Line 1270  for (;;)
1270    
1271          if (!condition && condcode == OP_NRREF)          if (!condition && condcode == OP_NRREF)
1272            {            {
1273            uschar *slotA = md->name_table;            pcre_uchar *slotA = md->name_table;
1274            for (i = 0; i < md->name_count; i++)            for (i = 0; i < md->name_count; i++)
1275              {              {
1276              if (GET2(slotA, 0) == recno) break;              if (GET2(slotA, 0) == recno) break;
# Line 1273  for (;;) Line 1283  for (;;)
1283    
1284            if (i < md->name_count)            if (i < md->name_count)
1285              {              {
1286              uschar *slotB = slotA;              pcre_uchar *slotB = slotA;
1287              while (slotB > md->name_table)              while (slotB > md->name_table)
1288                {                {
1289                slotB -= md->name_entry_size;                slotB -= md->name_entry_size;
1290                if (strcmp((char *)slotA + 2, (char *)slotB + 2) == 0)                if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
1291                  {                  {
1292                  condition = GET2(slotB, 0) == md->recursive->group_num;                  condition = GET2(slotB, 0) == md->recursive->group_num;
1293                  if (condition) break;                  if (condition) break;
# Line 1293  for (;;) Line 1303  for (;;)
1303                for (i++; i < md->name_count; i++)                for (i++; i < md->name_count; i++)
1304                  {                  {
1305                  slotB += md->name_entry_size;                  slotB += md->name_entry_size;
1306                  if (strcmp((char *)slotA + 2, (char *)slotB + 2) == 0)                  if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
1307                    {                    {
1308                    condition = GET2(slotB, 0) == md->recursive->group_num;                    condition = GET2(slotB, 0) == md->recursive->group_num;
1309                    if (condition) break;                    if (condition) break;
# Line 1306  for (;;) Line 1316  for (;;)
1316    
1317          /* Chose branch according to the condition */          /* Chose branch according to the condition */
1318    
1319          ecode += condition? 3 : GET(ecode, 1);          ecode += condition? 1 + IMM2_SIZE : GET(ecode, 1);
1320          }          }
1321        }        }
1322    
# Line 1323  for (;;) Line 1333  for (;;)
1333        if (!condition && condcode == OP_NCREF)        if (!condition && condcode == OP_NCREF)
1334          {          {
1335          int refno = offset >> 1;          int refno = offset >> 1;
1336          uschar *slotA = md->name_table;          pcre_uchar *slotA = md->name_table;
1337    
1338          for (i = 0; i < md->name_count; i++)          for (i = 0; i < md->name_count; i++)
1339            {            {
# Line 1337  for (;;) Line 1347  for (;;)
1347    
1348          if (i < md->name_count)          if (i < md->name_count)
1349            {            {
1350            uschar *slotB = slotA;            pcre_uchar *slotB = slotA;
1351            while (slotB > md->name_table)            while (slotB > md->name_table)
1352              {              {
1353              slotB -= md->name_entry_size;              slotB -= md->name_entry_size;
1354              if (strcmp((char *)slotA + 2, (char *)slotB + 2) == 0)              if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
1355                {                {
1356                offset = GET2(slotB, 0) << 1;                offset = GET2(slotB, 0) << 1;
1357                condition = offset < offset_top &&                condition = offset < offset_top &&
# Line 1359  for (;;) Line 1369  for (;;)
1369              for (i++; i < md->name_count; i++)              for (i++; i < md->name_count; i++)
1370                {                {
1371                slotB += md->name_entry_size;                slotB += md->name_entry_size;
1372                if (strcmp((char *)slotA + 2, (char *)slotB + 2) == 0)                if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
1373                  {                  {
1374                  offset = GET2(slotB, 0) << 1;                  offset = GET2(slotB, 0) << 1;
1375                  condition = offset < offset_top &&                  condition = offset < offset_top &&
# Line 1374  for (;;) Line 1384  for (;;)
1384    
1385        /* Chose branch according to the condition */        /* Chose branch according to the condition */
1386    
1387        ecode += condition? 3 : GET(ecode, 1);        ecode += condition? 1 + IMM2_SIZE : GET(ecode, 1);
1388        }        }
1389    
1390      else if (condcode == OP_DEF)     /* DEFINE - always false */      else if (condcode == OP_DEF)     /* DEFINE - always false */
# Line 1466  for (;;) Line 1476  for (;;)
1476        md->offset_vector[offset+1] = (int)(eptr - md->start_subject);        md->offset_vector[offset+1] = (int)(eptr - md->start_subject);
1477        if (offset_top <= offset) offset_top = offset + 2;        if (offset_top <= offset) offset_top = offset + 2;
1478        }        }
1479      ecode += 3;      ecode += 1 + IMM2_SIZE;
1480      break;      break;
1481    
1482    
# Line 1593  for (;;) Line 1603  for (;;)
1603      back a number of characters, not bytes. */      back a number of characters, not bytes. */
1604    
1605      case OP_REVERSE:      case OP_REVERSE:
1606  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1607      if (utf8)      if (utf)
1608        {        {
1609        i = GET(ecode, 1);        i = GET(ecode, 1);
1610        while (i-- > 0)        while (i-- > 0)
# Line 1625  for (;;) Line 1635  for (;;)
1635      function is able to force a failure. */      function is able to force a failure. */
1636    
1637      case OP_CALLOUT:      case OP_CALLOUT:
1638      if (pcre_callout != NULL)      if (PUBL(callout) != NULL)
1639        {        {
1640        pcre_callout_block cb;        PUBL(callout_block) cb;
1641        cb.version          = 2;   /* Version 1 of the callout block */        cb.version          = 2;   /* Version 1 of the callout block */
1642        cb.callout_number   = ecode[1];        cb.callout_number   = ecode[1];
1643        cb.offset_vector    = md->offset_vector;        cb.offset_vector    = md->offset_vector;
1644    #ifdef COMPILE_PCRE8
1645        cb.subject          = (PCRE_SPTR)md->start_subject;        cb.subject          = (PCRE_SPTR)md->start_subject;
1646    #else
1647          cb.subject          = (PCRE_SPTR16)md->start_subject;
1648    #endif
1649        cb.subject_length   = (int)(md->end_subject - md->start_subject);        cb.subject_length   = (int)(md->end_subject - md->start_subject);
1650        cb.start_match      = (int)(mstart - md->start_subject);        cb.start_match      = (int)(mstart - md->start_subject);
1651        cb.current_position = (int)(eptr - md->start_subject);        cb.current_position = (int)(eptr - md->start_subject);
# Line 1641  for (;;) Line 1655  for (;;)
1655        cb.capture_last     = md->capture_last;        cb.capture_last     = md->capture_last;
1656        cb.callout_data     = md->callout_data;        cb.callout_data     = md->callout_data;
1657        cb.mark             = md->nomatch_mark;        cb.mark             = md->nomatch_mark;
1658        if ((rrc = (*pcre_callout)(&cb)) > 0) RRETURN(MATCH_NOMATCH);        if ((rrc = (*PUBL(callout))(&cb)) > 0) RRETURN(MATCH_NOMATCH);
1659        if (rrc < 0) RRETURN(rrc);        if (rrc < 0) RRETURN(rrc);
1660        }        }
1661      ecode += 2 + 2*LINK_SIZE;      ecode += 2 + 2*LINK_SIZE;
# Line 1700  for (;;) Line 1714  for (;;)
1714        else        else
1715          {          {
1716          new_recursive.offset_save =          new_recursive.offset_save =
1717            (int *)(pcre_malloc)(new_recursive.saved_max * sizeof(int));            (int *)(PUBL(malloc))(new_recursive.saved_max * sizeof(int));
1718          if (new_recursive.offset_save == NULL) RRETURN(PCRE_ERROR_NOMEMORY);          if (new_recursive.offset_save == NULL) RRETURN(PCRE_ERROR_NOMEMORY);
1719          }          }
1720        memcpy(new_recursive.offset_save, md->offset_vector,        memcpy(new_recursive.offset_save, md->offset_vector,
# Line 1715  for (;;) Line 1729  for (;;)
1729        do        do
1730          {          {
1731          if (cbegroup) md->match_function_type = MATCH_CBEGROUP;          if (cbegroup) md->match_function_type = MATCH_CBEGROUP;
1732          RMATCH(eptr, callpat + _pcre_OP_lengths[*callpat], offset_top,          RMATCH(eptr, callpat + PRIV(OP_lengths)[*callpat], offset_top,
1733            md, eptrb, RM6);            md, eptrb, RM6);
1734          memcpy(md->offset_vector, new_recursive.offset_save,          memcpy(md->offset_vector, new_recursive.offset_save,
1735              new_recursive.saved_max * sizeof(int));              new_recursive.saved_max * sizeof(int));
# Line 1724  for (;;) Line 1738  for (;;)
1738            {            {
1739            DPRINTF(("Recursion matched\n"));            DPRINTF(("Recursion matched\n"));
1740            if (new_recursive.offset_save != stacksave)            if (new_recursive.offset_save != stacksave)
1741              (pcre_free)(new_recursive.offset_save);              (PUBL(free))(new_recursive.offset_save);
1742    
1743            /* 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
1744            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 1756  for (;;)
1756            {            {
1757            DPRINTF(("Recursion gave error %d\n", rrc));            DPRINTF(("Recursion gave error %d\n", rrc));
1758            if (new_recursive.offset_save != stacksave)            if (new_recursive.offset_save != stacksave)
1759              (pcre_free)(new_recursive.offset_save);              (PUBL(free))(new_recursive.offset_save);
1760            RRETURN(rrc);            RRETURN(rrc);
1761            }            }
1762    
# Line 1754  for (;;) Line 1768  for (;;)
1768        DPRINTF(("Recursion didn't match\n"));        DPRINTF(("Recursion didn't match\n"));
1769        md->recursive = new_recursive.prevrec;        md->recursive = new_recursive.prevrec;
1770        if (new_recursive.offset_save != stacksave)        if (new_recursive.offset_save != stacksave)
1771          (pcre_free)(new_recursive.offset_save);          (PUBL(free))(new_recursive.offset_save);
1772        RRETURN(MATCH_NOMATCH);        RRETURN(MATCH_NOMATCH);
1773        }        }
1774    
# Line 2066  for (;;) Line 2080  for (;;)
2080        be "non-word" characters. Remember the earliest consulted character for        be "non-word" characters. Remember the earliest consulted character for
2081        partial matching. */        partial matching. */
2082    
2083  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2084        if (utf8)        if (utf)
2085          {          {
2086          /* Get status of previous character */          /* Get status of previous character */
2087    
2088          if (eptr == md->start_subject) prev_is_word = FALSE; else          if (eptr == md->start_subject) prev_is_word = FALSE; else
2089            {            {
2090            USPTR lastptr = eptr - 1;            PCRE_PUCHAR lastptr = eptr - 1;
2091            while((*lastptr & 0xc0) == 0x80) lastptr--;            BACKCHAR(lastptr);
2092            if (lastptr < md->start_used_ptr) md->start_used_ptr = lastptr;            if (lastptr < md->start_used_ptr) md->start_used_ptr = lastptr;
2093            GETCHAR(c, lastptr);            GETCHAR(c, lastptr);
2094  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
# Line 2139  for (;;) Line 2153  for (;;)
2153              }              }
2154            else            else
2155  #endif  #endif
2156            prev_is_word = ((md->ctypes[eptr[-1]] & ctype_word) != 0);            prev_is_word = MAX_255(eptr[-1])
2157                && ((md->ctypes[eptr[-1]] & ctype_word) != 0);
2158            }            }
2159    
2160          /* Get status of next character */          /* Get status of next character */
# Line 2162  for (;;) Line 2177  for (;;)
2177            }            }
2178          else          else
2179  #endif  #endif
2180          cur_is_word = ((md->ctypes[*eptr] & ctype_word) != 0);          cur_is_word = MAX_255(*eptr)
2181              && ((md->ctypes[*eptr] & ctype_word) != 0);
2182          }          }
2183    
2184        /* Now see if the situation is what we want */        /* Now see if the situation is what we want */
# Line 2186  for (;;) Line 2202  for (;;)
2202        RRETURN(MATCH_NOMATCH);        RRETURN(MATCH_NOMATCH);
2203        }        }
2204      eptr++;      eptr++;
2205      if (utf8) while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;  #ifdef SUPPORT_UTF
2206        if (utf) ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
2207    #endif
2208      ecode++;      ecode++;
2209      break;      break;
2210    
# Line 2211  for (;;) Line 2229  for (;;)
2229        }        }
2230      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
2231      if (      if (
2232  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || !(defined COMPILE_PCRE8)
2233         c < 256 &&         c < 256 &&
2234  #endif  #endif
2235         (md->ctypes[c] & ctype_digit) != 0         (md->ctypes[c] & ctype_digit) != 0
# Line 2228  for (;;) Line 2246  for (;;)
2246        }        }
2247      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
2248      if (      if (
2249  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || !(defined COMPILE_PCRE8)
2250         c >= 256 ||         c > 255 ||
2251  #endif  #endif
2252         (md->ctypes[c] & ctype_digit) == 0         (md->ctypes[c] & ctype_digit) == 0
2253         )         )
# Line 2245  for (;;) Line 2263  for (;;)
2263        }        }
2264      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
2265      if (      if (
2266  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || !(defined COMPILE_PCRE8)
2267         c < 256 &&         c < 256 &&
2268  #endif  #endif
2269         (md->ctypes[c] & ctype_space) != 0         (md->ctypes[c] & ctype_space) != 0
# Line 2262  for (;;) Line 2280  for (;;)
2280        }        }
2281      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
2282      if (      if (
2283  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || !(defined COMPILE_PCRE8)
2284         c >= 256 ||         c > 255 ||
2285  #endif  #endif
2286         (md->ctypes[c] & ctype_space) == 0         (md->ctypes[c] & ctype_space) == 0
2287         )         )
# Line 2279  for (;;) Line 2297  for (;;)
2297        }        }
2298      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
2299      if (      if (
2300  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || !(defined COMPILE_PCRE8)
2301         c < 256 &&         c < 256 &&
2302  #endif  #endif
2303         (md->ctypes[c] & ctype_word) != 0         (md->ctypes[c] & ctype_word) != 0
# Line 2296  for (;;) Line 2314  for (;;)
2314        }        }
2315      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
2316      if (      if (
2317  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || !(defined COMPILE_PCRE8)
2318         c >= 256 ||         c > 255 ||
2319  #endif  #endif
2320         (md->ctypes[c] & ctype_word) == 0         (md->ctypes[c] & ctype_word) == 0
2321         )         )
# Line 2475  for (;;) Line 2493  for (;;)
2493          break;          break;
2494    
2495          case PT_GC:          case PT_GC:
2496          if ((ecode[2] != _pcre_ucp_gentype[prop->chartype]) == (op == OP_PROP))          if ((ecode[2] != PRIV(ucp_gentype)[prop->chartype]) == (op == OP_PROP))
2497            RRETURN(MATCH_NOMATCH);            RRETURN(MATCH_NOMATCH);
2498          break;          break;
2499    
# Line 2492  for (;;) Line 2510  for (;;)
2510          /* These are specials */          /* These are specials */
2511    
2512          case PT_ALNUM:          case PT_ALNUM:
2513          if ((_pcre_ucp_gentype[prop->chartype] == ucp_L ||          if ((PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
2514               _pcre_ucp_gentype[prop->chartype] == ucp_N) == (op == OP_NOTPROP))               PRIV(ucp_gentype)[prop->chartype] == ucp_N) == (op == OP_NOTPROP))
2515            RRETURN(MATCH_NOMATCH);            RRETURN(MATCH_NOMATCH);
2516          break;          break;
2517    
2518          case PT_SPACE:    /* Perl space */          case PT_SPACE:    /* Perl space */
2519          if ((_pcre_ucp_gentype[prop->chartype] == ucp_Z ||          if ((PRIV(ucp_gentype)[prop->chartype] == ucp_Z ||
2520               c == CHAR_HT || c == CHAR_NL || c == CHAR_FF || c == CHAR_CR)               c == CHAR_HT || c == CHAR_NL || c == CHAR_FF || c == CHAR_CR)
2521                 == (op == OP_NOTPROP))                 == (op == OP_NOTPROP))
2522            RRETURN(MATCH_NOMATCH);            RRETURN(MATCH_NOMATCH);
2523          break;          break;
2524    
2525          case PT_PXSPACE:  /* POSIX space */          case PT_PXSPACE:  /* POSIX 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_VT ||               c == CHAR_HT || c == CHAR_NL || c == CHAR_VT ||
2528               c == CHAR_FF || c == CHAR_CR)               c == CHAR_FF || c == CHAR_CR)
2529                 == (op == OP_NOTPROP))                 == (op == OP_NOTPROP))
# Line 2513  for (;;) Line 2531  for (;;)
2531          break;          break;
2532    
2533          case PT_WORD:          case PT_WORD:
2534          if ((_pcre_ucp_gentype[prop->chartype] == ucp_L ||          if ((PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
2535               _pcre_ucp_gentype[prop->chartype] == ucp_N ||               PRIV(ucp_gentype)[prop->chartype] == ucp_N ||
2536               c == CHAR_UNDERSCORE) == (op == OP_NOTPROP))               c == CHAR_UNDERSCORE) == (op == OP_NOTPROP))
2537            RRETURN(MATCH_NOMATCH);            RRETURN(MATCH_NOMATCH);
2538          break;          break;
# Line 2543  for (;;) Line 2561  for (;;)
2561      while (eptr < md->end_subject)      while (eptr < md->end_subject)
2562        {        {
2563        int len = 1;        int len = 1;
2564        if (!utf8) c = *eptr; else { GETCHARLEN(c, eptr, len); }        if (!utf) c = *eptr; else { GETCHARLEN(c, eptr, len); }
2565        if (UCD_CATEGORY(c) != ucp_M) break;        if (UCD_CATEGORY(c) != ucp_M) break;
2566        eptr += len;        eptr += len;
2567        }        }
# Line 2564  for (;;) Line 2582  for (;;)
2582      case OP_REFI:      case OP_REFI:
2583      caseless = op == OP_REFI;      caseless = op == OP_REFI;
2584      offset = GET2(ecode, 1) << 1;               /* Doubled ref number */      offset = GET2(ecode, 1) << 1;               /* Doubled ref number */
2585      ecode += 3;      ecode += 1 + IMM2_SIZE;
2586    
2587      /* If the reference is unset, there are two possibilities:      /* If the reference is unset, there are two possibilities:
2588    
# Line 2604  for (;;) Line 2622  for (;;)
2622        case OP_CRMINRANGE:        case OP_CRMINRANGE:
2623        minimize = (*ecode == OP_CRMINRANGE);        minimize = (*ecode == OP_CRMINRANGE);
2624        min = GET2(ecode, 1);        min = GET2(ecode, 1);
2625        max = GET2(ecode, 3);        max = GET2(ecode, 1 + IMM2_SIZE);
2626        if (max == 0) max = INT_MAX;        if (max == 0) max = INT_MAX;
2627        ecode += 5;        ecode += 1 + 2 * IMM2_SIZE;
2628        break;        break;
2629    
2630        default:               /* No repeat follows */        default:               /* No repeat follows */
# Line 2620  for (;;) Line 2638  for (;;)
2638        }        }
2639    
2640      /* Handle repeated back references. If the length of the reference is      /* Handle repeated back references. If the length of the reference is
2641      zero, just continue with the main loop. */      zero, just continue with the main loop. If the length is negative, it
2642        means the reference is unset in non-Java-compatible mode. If the minimum is
2643        zero, we can continue at the same level without recursion. For any other
2644        minimum, carrying on will result in NOMATCH. */
2645    
2646      if (length == 0) continue;      if (length == 0) continue;
2647        if (length < 0 && min == 0) continue;
2648    
2649      /* First, ensure the minimum number of matches are present. We get back      /* First, ensure the minimum number of matches are present. We get back
2650      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 2725  for (;;)
2725      case OP_NCLASS:      case OP_NCLASS:
2726      case OP_CLASS:      case OP_CLASS:
2727        {        {
2728          /* The data variable is saved across frames, so the byte map needs to
2729          be stored there. */
2730    #define BYTE_MAP ((pcre_uint8 *)data)
2731        data = ecode + 1;                /* Save for matching */        data = ecode + 1;                /* Save for matching */
2732        ecode += 33;                     /* Advance past the item */        ecode += 1 + (32 / sizeof(pcre_uchar)); /* Advance past the item */
2733    
2734        switch (*ecode)        switch (*ecode)
2735          {          {
# Line 2725  for (;;) Line 2750  for (;;)
2750          case OP_CRMINRANGE:          case OP_CRMINRANGE:
2751          minimize = (*ecode == OP_CRMINRANGE);          minimize = (*ecode == OP_CRMINRANGE);
2752          min = GET2(ecode, 1);          min = GET2(ecode, 1);
2753          max = GET2(ecode, 3);          max = GET2(ecode, 1 + IMM2_SIZE);
2754          if (max == 0) max = INT_MAX;          if (max == 0) max = INT_MAX;
2755          ecode += 5;          ecode += 1 + 2 * IMM2_SIZE;
2756          break;          break;
2757    
2758          default:               /* No repeat follows */          default:               /* No repeat follows */
# Line 2737  for (;;) Line 2762  for (;;)
2762    
2763        /* First, ensure the minimum number of matches are present. */        /* First, ensure the minimum number of matches are present. */
2764    
2765  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2766        /* UTF-8 mode */        if (utf)
       if (utf8)  
2767          {          {
2768          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
2769            {            {
# Line 2754  for (;;) Line 2778  for (;;)
2778              if (op == OP_CLASS) RRETURN(MATCH_NOMATCH);              if (op == OP_CLASS) RRETURN(MATCH_NOMATCH);
2779              }              }
2780            else            else
2781              {              if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);
             if ((data[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);  
             }  
2782            }            }
2783          }          }
2784        else        else
2785  #endif  #endif
2786        /* Not UTF-8 mode */        /* Not UTF mode */
2787          {          {
2788          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
2789            {            {
# Line 2771  for (;;) Line 2793  for (;;)
2793              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
2794              }              }
2795            c = *eptr++;            c = *eptr++;
2796            if ((data[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);  #ifndef COMPILE_PCRE8
2797              if (c > 255)
2798                {
2799                if (op == OP_CLASS) RRETURN(MATCH_NOMATCH);
2800                }
2801              else
2802    #endif
2803                if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);
2804            }            }
2805          }          }
2806    
# Line 2785  for (;;) Line 2814  for (;;)
2814    
2815        if (minimize)        if (minimize)
2816          {          {
2817  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2818          /* UTF-8 mode */          if (utf)
         if (utf8)  
2819            {            {
2820            for (fi = min;; fi++)            for (fi = min;; fi++)
2821              {              {
# Line 2805  for (;;) Line 2833  for (;;)
2833                if (op == OP_CLASS) RRETURN(MATCH_NOMATCH);                if (op == OP_CLASS) RRETURN(MATCH_NOMATCH);
2834                }                }
2835              else              else
2836                {                if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);
               if ((data[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);  
               }  
2837              }              }
2838            }            }
2839          else          else
2840  #endif  #endif
2841          /* Not UTF-8 mode */          /* Not UTF mode */
2842            {            {
2843            for (fi = min;; fi++)            for (fi = min;; fi++)
2844              {              {
# Line 2825  for (;;) Line 2851  for (;;)
2851                RRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
2852                }                }
2853              c = *eptr++;              c = *eptr++;
2854              if ((data[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);  #ifndef COMPILE_PCRE8
2855                if (c > 255)
2856                  {
2857                  if (op == OP_CLASS) RRETURN(MATCH_NOMATCH);
2858                  }
2859                else
2860    #endif
2861                  if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);
2862              }              }
2863            }            }
2864          /* Control never gets here */          /* Control never gets here */
# Line 2837  for (;;) Line 2870  for (;;)
2870          {          {
2871          pp = eptr;          pp = eptr;
2872    
2873  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2874          /* UTF-8 mode */          if (utf)
         if (utf8)  
2875            {            {
2876            for (i = min; i < max; i++)            for (i = min; i < max; i++)
2877              {              {
# Line 2855  for (;;) Line 2887  for (;;)
2887                if (op == OP_CLASS) break;                if (op == OP_CLASS) break;
2888                }                }
2889              else              else
2890                {                if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) break;
               if ((data[c/8] & (1 << (c&7))) == 0) break;  
               }  
2891              eptr += len;              eptr += len;
2892              }              }
2893            for (;;)            for (;;)
# Line 2870  for (;;) Line 2900  for (;;)
2900            }            }
2901          else          else
2902  #endif  #endif
2903            /* Not UTF-8 mode */            /* Not UTF mode */
2904            {            {
2905            for (i = min; i < max; i++)            for (i = min; i < max; i++)
2906              {              {
# Line 2880  for (;;) Line 2910  for (;;)
2910                break;                break;
2911                }                }
2912              c = *eptr;              c = *eptr;
2913              if ((data[c/8] & (1 << (c&7))) == 0) break;  #ifndef COMPILE_PCRE8
2914                if (c > 255)
2915                  {
2916                  if (op == OP_CLASS) break;
2917                  }
2918                else
2919    #endif
2920                  if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) break;
2921              eptr++;              eptr++;
2922              }              }
2923            while (eptr >= pp)            while (eptr >= pp)
# Line 2893  for (;;) Line 2930  for (;;)
2930    
2931          RRETURN(MATCH_NOMATCH);          RRETURN(MATCH_NOMATCH);
2932          }          }
2933    #undef BYTE_MAP
2934        }        }
2935      /* Control never gets here */      /* Control never gets here */
2936    
# Line 2901  for (;;) Line 2939  for (;;)
2939      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
2940      mode, because Unicode properties are supported in non-UTF-8 mode. */      mode, because Unicode properties are supported in non-UTF-8 mode. */
2941    
2942  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
2943      case OP_XCLASS:      case OP_XCLASS:
2944        {        {
2945        data = ecode + 1 + LINK_SIZE;                /* Save for matching */        data = ecode + 1 + LINK_SIZE;                /* Save for matching */
# Line 2926  for (;;) Line 2964  for (;;)
2964          case OP_CRMINRANGE:          case OP_CRMINRANGE:
2965          minimize = (*ecode == OP_CRMINRANGE);          minimize = (*ecode == OP_CRMINRANGE);
2966          min = GET2(ecode, 1);          min = GET2(ecode, 1);
2967          max = GET2(ecode, 3);          max = GET2(ecode, 1 + IMM2_SIZE);
2968          if (max == 0) max = INT_MAX;          if (max == 0) max = INT_MAX;
2969          ecode += 5;          ecode += 1 + 2 * IMM2_SIZE;
2970          break;          break;
2971    
2972          default:               /* No repeat follows */          default:               /* No repeat follows */
# Line 2946  for (;;) Line 2984  for (;;)
2984            RRETURN(MATCH_NOMATCH);            RRETURN(MATCH_NOMATCH);
2985            }            }
2986          GETCHARINCTEST(c, eptr);          GETCHARINCTEST(c, eptr);
2987          if (!_pcre_xclass(c, data)) RRETURN(MATCH_NOMATCH);          if (!PRIV(xclass)(c, data, utf)) RRETURN(MATCH_NOMATCH);
2988          }          }
2989    
2990        /* 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 3008  for (;;)
3008              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
3009              }              }
3010            GETCHARINCTEST(c, eptr);            GETCHARINCTEST(c, eptr);
3011            if (!_pcre_xclass(c, data)) RRETURN(MATCH_NOMATCH);            if (!PRIV(xclass)(c, data, utf)) RRETURN(MATCH_NOMATCH);
3012            }            }
3013          /* Control never gets here */          /* Control never gets here */
3014          }          }
# Line 2988  for (;;) Line 3026  for (;;)
3026              SCHECK_PARTIAL();              SCHECK_PARTIAL();
3027              break;              break;
3028              }              }
3029    #ifdef SUPPORT_UTF
3030            GETCHARLENTEST(c, eptr, len);            GETCHARLENTEST(c, eptr, len);
3031            if (!_pcre_xclass(c, data)) break;  #else
3032              c = *eptr;
3033    #endif
3034              if (!PRIV(xclass)(c, data, utf)) break;
3035            eptr += len;            eptr += len;
3036            }            }
3037          for(;;)          for(;;)
# Line 2997  for (;;) Line 3039  for (;;)
3039            RMATCH(eptr, ecode, offset_top, md, eptrb, RM21);            RMATCH(eptr, ecode, offset_top, md, eptrb, RM21);
3040            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3041            if (eptr-- == pp) break;        /* Stop if tried at original pos */            if (eptr-- == pp) break;        /* Stop if tried at original pos */
3042            if (utf8) BACKCHAR(eptr);  #ifdef SUPPORT_UTF
3043              if (utf) BACKCHAR(eptr);
3044    #endif
3045            }            }
3046          RRETURN(MATCH_NOMATCH);          RRETURN(MATCH_NOMATCH);
3047          }          }
# Line 3009  for (;;) Line 3053  for (;;)
3053      /* Match a single character, casefully */      /* Match a single character, casefully */
3054    
3055      case OP_CHAR:      case OP_CHAR:
3056  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3057      if (utf8)      if (utf)
3058        {        {
3059        length = 1;        length = 1;
3060        ecode++;        ecode++;
# Line 3024  for (;;) Line 3068  for (;;)
3068        }        }
3069      else      else
3070  #endif  #endif
3071        /* Not UTF mode */
     /* Non-UTF-8 mode */  
3072        {        {
3073        if (md->end_subject - eptr < 1)        if (md->end_subject - eptr < 1)
3074          {          {
# Line 3037  for (;;) Line 3080  for (;;)
3080        }        }
3081      break;      break;
3082    
3083      /* Match a single character, caselessly */      /* Match a single character, caselessly. If we are at the end of the
3084        subject, give up immediately. */
3085    
3086      case OP_CHARI:      case OP_CHARI:
3087  #ifdef SUPPORT_UTF8      if (eptr >= md->end_subject)
3088      if (utf8)        {
3089          SCHECK_PARTIAL();
3090          RRETURN(MATCH_NOMATCH);
3091          }
3092    
3093    #ifdef SUPPORT_UTF
3094        if (utf)
3095        {        {
3096        length = 1;        length = 1;
3097        ecode++;        ecode++;
3098        GETCHARLEN(fc, ecode, length);        GETCHARLEN(fc, ecode, length);
3099    
       if (length > md->end_subject - eptr)  
         {  
         CHECK_PARTIAL();             /* Not SCHECK_PARTIAL() */  
         RRETURN(MATCH_NOMATCH);  
         }  
   
3100        /* 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
3101        can use the fast lookup table. */        we know that its other case must also be one byte long, so we can use the
3102          fast lookup table. We know that there is at least one byte left in the
3103          subject. */
3104    
3105        if (fc < 128)        if (fc < 128)
3106          {          {
3107          if (md->lcc[*ecode++] != md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH);          if (md->lcc[fc]
3108                != TABLE_GET(*eptr, md->lcc, *eptr)) RRETURN(MATCH_NOMATCH);
3109            ecode++;
3110            eptr++;
3111          }          }
3112    
3113        /* Otherwise we must pick up the subject character */        /* Otherwise we must pick up the subject character. Note that we cannot
3114          use the value of "length" to check for sufficient bytes left, because the
3115          other case of the character may have more or fewer bytes.  */
3116    
3117        else        else
3118          {          {
# Line 3082  for (;;) Line 3133  for (;;)
3133          }          }
3134        }        }
3135      else      else
3136  #endif   /* SUPPORT_UTF8 */  #endif   /* SUPPORT_UTF */
3137    
3138      /* Non-UTF-8 mode */      /* Not UTF mode */
3139        {        {
3140        if (md->end_subject - eptr < 1)        if (TABLE_GET(ecode[1], md->lcc, ecode[1])
3141          {            != TABLE_GET(*eptr, md->lcc, *eptr)) RRETURN(MATCH_NOMATCH);
3142          SCHECK_PARTIAL();            /* This one can use SCHECK_PARTIAL() */        eptr++;
         RRETURN(MATCH_NOMATCH);  
         }  
       if (md->lcc[ecode[1]] != md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH);  
3143        ecode += 2;        ecode += 2;
3144        }        }
3145      break;      break;
# Line 3101  for (;;) Line 3149  for (;;)
3149      case OP_EXACT:      case OP_EXACT:
3150      case OP_EXACTI:      case OP_EXACTI:
3151      min = max = GET2(ecode, 1);      min = max = GET2(ecode, 1);
3152      ecode += 3;      ecode += 1 + IMM2_SIZE;
3153      goto REPEATCHAR;      goto REPEATCHAR;
3154    
3155      case OP_POSUPTO:      case OP_POSUPTO:
# Line 3116  for (;;) Line 3164  for (;;)
3164      min = 0;      min = 0;
3165      max = GET2(ecode, 1);      max = GET2(ecode, 1);
3166      minimize = *ecode == OP_MINUPTO || *ecode == OP_MINUPTOI;      minimize = *ecode == OP_MINUPTO || *ecode == OP_MINUPTOI;
3167      ecode += 3;      ecode += 1 + IMM2_SIZE;
3168      goto REPEATCHAR;      goto REPEATCHAR;
3169    
3170      case OP_POSSTAR:      case OP_POSSTAR:
# Line 3164  for (;;) Line 3212  for (;;)
3212      /* Common code for all repeated single-character matches. */      /* Common code for all repeated single-character matches. */
3213    
3214      REPEATCHAR:      REPEATCHAR:
3215  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3216      if (utf8)      if (utf)
3217        {        {
3218        length = 1;        length = 1;
3219        charptr = ecode;        charptr = ecode;
# Line 3181  for (;;) Line 3229  for (;;)
3229          unsigned int othercase;          unsigned int othercase;
3230          if (op >= OP_STARI &&     /* Caseless */          if (op >= OP_STARI &&     /* Caseless */
3231              (othercase = UCD_OTHERCASE(fc)) != fc)              (othercase = UCD_OTHERCASE(fc)) != fc)
3232            oclength = _pcre_ord2utf8(othercase, occhars);            oclength = PRIV(ord2utf)(othercase, occhars);
3233          else oclength = 0;          else oclength = 0;
3234  #endif  /* SUPPORT_UCP */  #endif  /* SUPPORT_UCP */
3235    
3236          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3237            {            {
3238            if (eptr <= md->end_subject - length &&            if (eptr <= md->end_subject - length &&
3239              memcmp(eptr, charptr, length) == 0) eptr += length;              memcmp(eptr, charptr, IN_UCHARS(length)) == 0) eptr += length;
3240  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3241            else if (oclength > 0 &&            else if (oclength > 0 &&
3242                     eptr <= md->end_subject - oclength &&                     eptr <= md->end_subject - oclength &&
3243                     memcmp(eptr, occhars, oclength) == 0) eptr += oclength;                     memcmp(eptr, occhars, IN_UCHARS(oclength)) == 0) eptr += oclength;
3244  #endif  /* SUPPORT_UCP */  #endif  /* SUPPORT_UCP */
3245            else            else
3246              {              {
# Line 3211  for (;;) Line 3259  for (;;)
3259              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3260              if (fi >= max) RRETURN(MATCH_NOMATCH);              if (fi >= max) RRETURN(MATCH_NOMATCH);
3261              if (eptr <= md->end_subject - length &&              if (eptr <= md->end_subject - length &&
3262                memcmp(eptr, charptr, length) == 0) eptr += length;                memcmp(eptr, charptr, IN_UCHARS(length)) == 0) eptr += length;
3263  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3264              else if (oclength > 0 &&              else if (oclength > 0 &&
3265                       eptr <= md->end_subject - oclength &&                       eptr <= md->end_subject - oclength &&
3266                       memcmp(eptr, occhars, oclength) == 0) eptr += oclength;                       memcmp(eptr, occhars, IN_UCHARS(oclength)) == 0) eptr += oclength;
3267  #endif  /* SUPPORT_UCP */  #endif  /* SUPPORT_UCP */
3268              else              else
3269                {                {
# Line 3232  for (;;) Line 3280  for (;;)
3280            for (i = min; i < max; i++)            for (i = min; i < max; i++)
3281              {              {
3282              if (eptr <= md->end_subject - length &&              if (eptr <= md->end_subject - length &&
3283                  memcmp(eptr, charptr, length) == 0) eptr += length;                  memcmp(eptr, charptr, IN_UCHARS(length)) == 0) eptr += length;
3284  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3285              else if (oclength > 0 &&              else if (oclength > 0 &&
3286                       eptr <= md->end_subject - oclength &&                       eptr <= md->end_subject - oclength &&
3287                       memcmp(eptr, occhars, oclength) == 0) eptr += oclength;                       memcmp(eptr, occhars, IN_UCHARS(oclength)) == 0) eptr += oclength;
3288  #endif  /* SUPPORT_UCP */  #endif  /* SUPPORT_UCP */
3289              else              else
3290                {                {
# Line 3268  for (;;) Line 3316  for (;;)
3316        value of fc will always be < 128. */        value of fc will always be < 128. */
3317        }        }
3318      else      else
3319  #endif  /* SUPPORT_UTF8 */  #endif  /* SUPPORT_UTF */
3320          /* When not in UTF-8 mode, load a single-byte character. */
3321      /* When not in UTF-8 mode, load a single-byte character. */        fc = *ecode++;
   
     fc = *ecode++;  
3322    
3323      /* The value of fc at this point is always less than 256, though we may or      /* The value of fc at this point is always one character, though we may
3324      may not be in UTF-8 mode. The code is duplicated for the caseless and      or may not be in UTF mode. The code is duplicated for the caseless and
3325      caseful cases, for speed, since matching characters is likely to be quite      caseful cases, for speed, since matching characters is likely to be quite
3326      common. First, ensure the minimum number of matches are present. If min =      common. First, ensure the minimum number of matches are present. If min =
3327      max, continue at the same level without recursing. Otherwise, if      max, continue at the same level without recursing. Otherwise, if
# Line 3288  for (;;) Line 3334  for (;;)
3334    
3335      if (op >= OP_STARI)  /* Caseless */      if (op >= OP_STARI)  /* Caseless */
3336        {        {
3337        fc = md->lcc[fc];  #ifdef COMPILE_PCRE8
3338          /* fc must be < 128 if UTF is enabled. */
3339          foc = md->fcc[fc];
3340    #else
3341    #ifdef SUPPORT_UTF
3342    #ifdef SUPPORT_UCP
3343          if (utf && fc > 127)
3344            foc = UCD_OTHERCASE(fc);
3345    #else
3346          if (utf && fc > 127)
3347            foc = fc;
3348    #endif /* SUPPORT_UCP */
3349          else
3350    #endif /* SUPPORT_UTF */
3351            foc = TABLE_GET(fc, md->fcc, fc);
3352    #endif /* COMPILE_PCRE8 */
3353    
3354        for (i = 1; i <= min; i++)        for (i = 1; i <= min; i++)
3355          {          {
3356          if (eptr >= md->end_subject)          if (eptr >= md->end_subject)
# Line 3296  for (;;) Line 3358  for (;;)
3358            SCHECK_PARTIAL();            SCHECK_PARTIAL();
3359            RRETURN(MATCH_NOMATCH);            RRETURN(MATCH_NOMATCH);
3360            }            }
3361          if (fc != md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH);          if (fc != *eptr && foc != *eptr) RRETURN(MATCH_NOMATCH);
3362            eptr++;
3363          }          }
3364        if (min == max) continue;        if (min == max) continue;
3365        if (minimize)        if (minimize)
# Line 3311  for (;;) Line 3374  for (;;)
3374              SCHECK_PARTIAL();              SCHECK_PARTIAL();
3375              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
3376              }              }
3377            if (fc != md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH);            if (fc != *eptr && foc != *eptr) RRETURN(MATCH_NOMATCH);
3378              eptr++;
3379            }            }
3380          /* Control never gets here */          /* Control never gets here */
3381          }          }
# Line 3325  for (;;) Line 3389  for (;;)
3389              SCHECK_PARTIAL();              SCHECK_PARTIAL();
3390              break;              break;
3391              }              }
3392            if (fc != md->lcc[*eptr]) break;            if (fc != *eptr && foc != *eptr) break;
3393            eptr++;            eptr++;
3394            }            }
3395    
# Line 3414  for (;;) Line 3478  for (;;)
3478      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
3479      if (op == OP_NOTI)         /* The caseless case */      if (op == OP_NOTI)         /* The caseless case */
3480        {        {
3481  #ifdef SUPPORT_UTF8        register int ch, och;
3482        if (c < 256)        ch = *ecode++;
3483  #endif  #ifdef COMPILE_PCRE8
3484        c = md->lcc[c];        /* ch must be < 128 if UTF is enabled. */
3485        if (md->lcc[*ecode++] == c) RRETURN(MATCH_NOMATCH);        och = md->fcc[ch];
3486    #else
3487    #ifdef SUPPORT_UTF
3488    #ifdef SUPPORT_UCP
3489          if (utf && ch > 127)
3490            och = UCD_OTHERCASE(ch);
3491    #else
3492          if (utf && ch > 127)
3493            och = ch;
3494    #endif /* SUPPORT_UCP */
3495          else
3496    #endif /* SUPPORT_UTF */
3497            och = TABLE_GET(ch, md->fcc, ch);
3498    #endif /* COMPILE_PCRE8 */
3499          if (ch == c || och == c) RRETURN(MATCH_NOMATCH);
3500        }        }
3501      else    /* Caseful */      else    /* Caseful */
3502        {        {
# Line 3436  for (;;) Line 3514  for (;;)
3514      case OP_NOTEXACT:      case OP_NOTEXACT:
3515      case OP_NOTEXACTI:      case OP_NOTEXACTI:
3516      min = max = GET2(ecode, 1);      min = max = GET2(ecode, 1);
3517      ecode += 3;      ecode += 1 + IMM2_SIZE;
3518      goto REPEATNOTCHAR;      goto REPEATNOTCHAR;
3519    
3520      case OP_NOTUPTO:      case OP_NOTUPTO:
# Line 3446  for (;;) Line 3524  for (;;)
3524      min = 0;      min = 0;
3525      max = GET2(ecode, 1);      max = GET2(ecode, 1);
3526      minimize = *ecode == OP_NOTMINUPTO || *ecode == OP_NOTMINUPTOI;      minimize = *ecode == OP_NOTMINUPTO || *ecode == OP_NOTMINUPTOI;
3527      ecode += 3;      ecode += 1 + IMM2_SIZE;
3528      goto REPEATNOTCHAR;      goto REPEATNOTCHAR;
3529    
3530      case OP_NOTPOSSTAR:      case OP_NOTPOSSTAR:
# Line 3478  for (;;) Line 3556  for (;;)
3556      possessive = TRUE;      possessive = TRUE;
3557      min = 0;      min = 0;
3558      max = GET2(ecode, 1);      max = GET2(ecode, 1);
3559      ecode += 3;      ecode += 1 + IMM2_SIZE;
3560      goto REPEATNOTCHAR;      goto REPEATNOTCHAR;
3561    
3562      case OP_NOTSTAR:      case OP_NOTSTAR:
# Line 3517  for (;;) Line 3595  for (;;)
3595    
3596      if (op >= OP_NOTSTARI)     /* Caseless */      if (op >= OP_NOTSTARI)     /* Caseless */
3597        {        {
3598        fc = md->lcc[fc];  #ifdef COMPILE_PCRE8
3599          /* fc must be < 128 if UTF is enabled. */
3600          foc = md->fcc[fc];
3601    #else
3602    #ifdef SUPPORT_UTF
3603    #ifdef SUPPORT_UCP
3604          if (utf && fc > 127)
3605            foc = UCD_OTHERCASE(fc);
3606    #else
3607          if (utf && fc > 127)
3608            foc = fc;
3609    #endif /* SUPPORT_UCP */
3610          else
3611    #endif /* SUPPORT_UTF */
3612            foc = TABLE_GET(fc, md->fcc, fc);
3613    #endif /* COMPILE_PCRE8 */
3614    
3615  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3616        /* UTF-8 mode */        if (utf)
       if (utf8)  
3617          {          {
3618          register unsigned int d;          register unsigned int d;
3619          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
# Line 3532  for (;;) Line 3624  for (;;)
3624              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
3625              }              }
3626            GETCHARINC(d, eptr);            GETCHARINC(d, eptr);
3627            if (d < 256) d = md->lcc[d];            if (fc == d || foc == d) RRETURN(MATCH_NOMATCH);
           if (fc == d) RRETURN(MATCH_NOMATCH);  
3628            }            }
3629          }          }
3630        else        else
3631  #endif  #endif
3632          /* Not UTF mode */
       /* Not UTF-8 mode */  
3633          {          {
3634          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3635            {            {
# Line 3548  for (;;) Line 3638  for (;;)
3638              SCHECK_PARTIAL();              SCHECK_PARTIAL();
3639              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
3640              }              }
3641            if (fc == md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH);            if (fc == *eptr || foc == *eptr) RRETURN(MATCH_NOMATCH);
3642              eptr++;
3643            }            }
3644          }          }
3645    
# Line 3556  for (;;) Line 3647  for (;;)
3647    
3648        if (minimize)        if (minimize)
3649          {          {
3650  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3651          /* UTF-8 mode */          if (utf)
         if (utf8)  
3652            {            {
3653            register unsigned int d;            register unsigned int d;
3654            for (fi = min;; fi++)            for (fi = min;; fi++)
# Line 3572  for (;;) Line 3662  for (;;)
3662                RRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
3663                }                }
3664              GETCHARINC(d, eptr);              GETCHARINC(d, eptr);
3665              if (d < 256) d = md->lcc[d];              if (fc == d || foc == d) RRETURN(MATCH_NOMATCH);
             if (fc == d) RRETURN(MATCH_NOMATCH);  
3666              }              }
3667            }            }
3668          else          else
3669  #endif  #endif
3670          /* Not UTF-8 mode */          /* Not UTF mode */
3671            {            {
3672            for (fi = min;; fi++)            for (fi = min;; fi++)
3673              {              {
# Line 3590  for (;;) Line 3679  for (;;)
3679                SCHECK_PARTIAL();                SCHECK_PARTIAL();
3680                RRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
3681                }                }
3682              if (fc == md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH);              if (fc == *eptr || foc == *eptr) RRETURN(MATCH_NOMATCH);
3683                eptr++;
3684              }              }
3685            }            }
3686          /* Control never gets here */          /* Control never gets here */
# Line 3602  for (;;) Line 3692  for (;;)
3692          {          {
3693          pp = eptr;          pp = eptr;
3694    
3695  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3696          /* UTF-8 mode */          if (utf)
         if (utf8)  
3697            {            {
3698            register unsigned int d;            register unsigned int d;
3699            for (i = min; i < max; i++)            for (i = min; i < max; i++)
# Line 3616  for (;;) Line 3705  for (;;)
3705                break;                break;
3706                }                }
3707              GETCHARLEN(d, eptr, len);              GETCHARLEN(d, eptr, len);
3708              if (d < 256) d = md->lcc[d];              if (fc == d || foc == d) break;
             if (fc == d) break;  
3709              eptr += len;              eptr += len;
3710              }              }
3711          if (possessive) continue;          if (possessive) continue;
# Line 3631  for (;;) Line 3719  for (;;)
3719            }            }
3720          else          else
3721  #endif  #endif
3722          /* Not UTF-8 mode */          /* Not UTF mode */
3723            {            {
3724            for (i = min; i < max; i++)            for (i = min; i < max; i++)
3725              {              {
# Line 3640  for (;;) Line 3728  for (;;)
3728                SCHECK_PARTIAL();                SCHECK_PARTIAL();
3729                break;                break;
3730                }                }
3731              if (fc == md->lcc[*eptr]) break;              if (fc == *eptr || foc == *eptr) break;
3732              eptr++;              eptr++;
3733              }              }
3734            if (possessive) continue;            if (possessive) continue;
# Line 3661  for (;;) Line 3749  for (;;)
3749    
3750      else      else
3751        {        {
3752  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3753        /* UTF-8 mode */        if (utf)
       if (utf8)  
3754          {          {
3755          register unsigned int d;          register unsigned int d;
3756          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
# Line 3679  for (;;) Line 3766  for (;;)
3766          }          }
3767        else        else
3768  #endif  #endif
3769        /* Not UTF-8 mode */        /* Not UTF mode */
3770          {          {
3771          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3772            {            {
# Line 3696  for (;;) Line 3783  for (;;)
3783    
3784        if (minimize)        if (minimize)
3785          {          {
3786  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3787          /* UTF-8 mode */          if (utf)
         if (utf8)  
3788            {            {
3789            register unsigned int d;            register unsigned int d;
3790            for (fi = min;; fi++)            for (fi = min;; fi++)
# Line 3717  for (;;) Line 3803  for (;;)
3803            }            }
3804          else          else
3805  #endif  #endif
3806          /* Not UTF-8 mode */          /* Not UTF mode */
3807            {            {
3808            for (fi = min;; fi++)            for (fi = min;; fi++)
3809              {              {
# Line 3741  for (;;) Line 3827  for (;;)
3827          {          {
3828          pp = eptr;          pp = eptr;
3829    
3830  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3831          /* UTF-8 mode */          if (utf)
         if (utf8)  
3832            {            {
3833            register unsigned int d;            register unsigned int d;
3834            for (i = min; i < max; i++)            for (i = min; i < max; i++)
# Line 3769  for (;;) Line 3854  for (;;)
3854            }            }
3855          else          else
3856  #endif  #endif
3857          /* Not UTF-8 mode */          /* Not UTF mode */
3858            {            {
3859            for (i = min; i < max; i++)            for (i = min; i < max; i++)
3860              {              {
# Line 3802  for (;;) Line 3887  for (;;)
3887      case OP_TYPEEXACT:      case OP_TYPEEXACT:
3888      min = max = GET2(ecode, 1);      min = max = GET2(ecode, 1);
3889      minimize = TRUE;      minimize = TRUE;
3890      ecode += 3;      ecode += 1 + IMM2_SIZE;
3891      goto REPEATTYPE;      goto REPEATTYPE;
3892    
3893      case OP_TYPEUPTO:      case OP_TYPEUPTO:
# Line 3810  for (;;) Line 3895  for (;;)
3895      min = 0;      min = 0;
3896      max = GET2(ecode, 1);      max = GET2(ecode, 1);
3897      minimize = *ecode == OP_TYPEMINUPTO;      minimize = *ecode == OP_TYPEMINUPTO;
3898      ecode += 3;      ecode += 1 + IMM2_SIZE;
3899      goto REPEATTYPE;      goto REPEATTYPE;
3900    
3901      case OP_TYPEPOSSTAR:      case OP_TYPEPOSSTAR:
# Line 3838  for (;;) Line 3923  for (;;)
3923      possessive = TRUE;      possessive = TRUE;
3924      min = 0;      min = 0;
3925      max = GET2(ecode, 1);      max = GET2(ecode, 1);
3926      ecode += 3;      ecode += 1 + IMM2_SIZE;
3927      goto REPEATTYPE;      goto REPEATTYPE;
3928    
3929      case OP_TYPESTAR:      case OP_TYPESTAR:
# Line 4045  for (;;) Line 4130  for (;;)
4130            while (eptr < md->end_subject)            while (eptr < md->end_subject)
4131              {              {
4132              int len = 1;              int len = 1;
4133              if (!utf8) c = *eptr; else { GETCHARLEN(c, eptr, len); }              if (!utf) c = *eptr; else { GETCHARLEN(c, eptr, len); }
4134              if (UCD_CATEGORY(c) != ucp_M) break;              if (UCD_CATEGORY(c) != ucp_M) break;
4135              eptr += len;              eptr += len;
4136              }              }
# Line 4057  for (;;) Line 4142  for (;;)
4142    
4143  /* Handle all other cases when the coding is UTF-8 */  /* Handle all other cases when the coding is UTF-8 */
4144    
4145  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
4146        if (utf8) switch(ctype)        if (utf) switch(ctype)
4147          {          {
4148          case OP_ANY:          case OP_ANY:
4149          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
# Line 4070  for (;;) Line 4155  for (;;)
4155              }              }
4156            if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH);            if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH);
4157            eptr++;            eptr++;
4158            while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;            ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
4159            }            }
4160          break;          break;
4161    
# Line 4083  for (;;) Line 4168  for (;;)
4168              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4169              }              }
4170            eptr++;            eptr++;
4171            while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;            ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
4172            }            }
4173          break;          break;
4174    
# Line 4265  for (;;) Line 4350  for (;;)
4350              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4351              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4352              }              }
4353            if (*eptr >= 128 || (md->ctypes[*eptr++] & ctype_digit) == 0)            if (*eptr >= 128 || (md->ctypes[*eptr] & ctype_digit) == 0)
4354              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4355              eptr++;
4356            /* 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 */
4357            }            }
4358          break;          break;
# Line 4281  for (;;) Line 4367  for (;;)
4367              }              }
4368            if (*eptr < 128 && (md->ctypes[*eptr] & ctype_space) != 0)            if (*eptr < 128 && (md->ctypes[*eptr] & ctype_space) != 0)
4369              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4370            while (++eptr < md->end_subject && (*eptr & 0xc0) == 0x80);            eptr++;
4371              ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
4372            }            }
4373          break;          break;
4374    
# Line 4293  for (;;) Line 4380  for (;;)
4380              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4381              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4382              }              }
4383            if (*eptr >= 128 || (md->ctypes[*eptr++] & ctype_space) == 0)            if (*eptr >= 128 || (md->ctypes[*eptr] & ctype_space) == 0)
4384              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4385              eptr++;
4386            /* 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 */
4387            }            }
4388          break;          break;
# Line 4309  for (;;) Line 4397  for (;;)
4397              }              }
4398            if (*eptr < 128 && (md->ctypes[*eptr] & ctype_word) != 0)            if (*eptr < 128 && (md->ctypes[*eptr] & ctype_word) != 0)
4399              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4400            while (++eptr < md->end_subject && (*eptr & 0xc0) == 0x80);            eptr++;
4401              ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
4402            }            }
4403          break;          break;
4404    
# Line 4321  for (;;) Line 4410  for (;;)
4410              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4411              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4412              }              }
4413            if (*eptr >= 128 || (md->ctypes[*eptr++] & ctype_word) == 0)            if (*eptr >= 128 || (md->ctypes[*eptr] & ctype_word) == 0)
4414              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4415              eptr++;
4416            /* 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 */
4417            }            }
4418          break;          break;
# Line 4332  for (;;) Line 4422  for (;;)
4422          }  /* End switch(ctype) */          }  /* End switch(ctype) */
4423    
4424        else        else
4425  #endif     /* SUPPORT_UTF8 */  #endif     /* SUPPORT_UTF */
4426    
4427        /* 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
4428        than OP_PROP and OP_NOTPROP. */        than OP_PROP and OP_NOTPROP. */
# Line 4392  for (;;) Line 4482  for (;;)
4482              case 0x000b:              case 0x000b:
4483              case 0x000c:              case 0x000c:
4484              case 0x0085:              case 0x0085:
4485    #ifdef COMPILE_PCRE16
4486                case 0x2028:
4487                case 0x2029:
4488    #endif
4489              if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH);              if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH);
4490              break;              break;
4491              }              }
# Line 4412  for (;;) Line 4506  for (;;)
4506              case 0x09:      /* HT */              case 0x09:      /* HT */
4507              case 0x20:      /* SPACE */              case 0x20:      /* SPACE */
4508              case 0xa0:      /* NBSP */              case 0xa0:      /* NBSP */
4509    #ifdef COMPILE_PCRE16
4510                case 0x1680:    /* OGHAM SPACE MARK */
4511                case 0x180e:    /* MONGOLIAN VOWEL SEPARATOR */
4512                case 0x2000:    /* EN QUAD */
4513                case 0x2001:    /* EM QUAD */
4514                case 0x2002:    /* EN SPACE */
4515                case 0x2003:    /* EM SPACE */
4516                case 0x2004:    /* THREE-PER-EM SPACE */
4517                case 0x2005:    /* FOUR-PER-EM SPACE */
4518                case 0x2006:    /* SIX-PER-EM SPACE */
4519                case 0x2007:    /* FIGURE SPACE */
4520                case 0x2008:    /* PUNCTUATION SPACE */
4521                case 0x2009:    /* THIN SPACE */
4522                case 0x200A:    /* HAIR SPACE */
4523                case 0x202f:    /* NARROW NO-BREAK SPACE */
4524                case 0x205f:    /* MEDIUM MATHEMATICAL SPACE */
4525                case 0x3000:    /* IDEOGRAPHIC SPACE */
4526    #endif
4527              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4528              }              }
4529            }            }
# Line 4431  for (;;) Line 4543  for (;;)
4543              case 0x09:      /* HT */              case 0x09:      /* HT */
4544              case 0x20:      /* SPACE */              case 0x20:      /* SPACE */
4545              case 0xa0:      /* NBSP */              case 0xa0:      /* NBSP */
4546    #ifdef COMPILE_PCRE16
4547                case 0x1680:    /* OGHAM SPACE MARK */
4548                case 0x180e:    /* MONGOLIAN VOWEL SEPARATOR */
4549                case 0x2000:    /* EN QUAD */
4550                case 0x2001:    /* EM QUAD */
4551                case 0x2002:    /* EN SPACE */
4552                case 0x2003:    /* EM SPACE */
4553                case 0x2004:    /* THREE-PER-EM SPACE */
4554                case 0x2005:    /* FOUR-PER-EM SPACE */
4555                case 0x2006:    /* SIX-PER-EM SPACE */
4556                case 0x2007:    /* FIGURE SPACE */
4557                case 0x2008:    /* PUNCTUATION SPACE */
4558                case 0x2009:    /* THIN SPACE */
4559                case 0x200A:    /* HAIR SPACE */
4560                case 0x202f:    /* NARROW NO-BREAK SPACE */
4561                case 0x205f:    /* MEDIUM MATHEMATICAL SPACE */
4562                case 0x3000:    /* IDEOGRAPHIC SPACE */
4563    #endif
4564              break;              break;
4565              }              }
4566            }            }
# Line 4452  for (;;) Line 4582  for (;;)
4582              case 0x0c:      /* FF */              case 0x0c:      /* FF */
4583              case 0x0d:      /* CR */              case 0x0d:      /* CR */
4584              case 0x85:      /* NEL */              case 0x85:      /* NEL */
4585    #ifdef COMPILE_PCRE16
4586                case 0x2028:    /* LINE SEPARATOR */
4587                case 0x2029:    /* PARAGRAPH SEPARATOR */
4588    #endif
4589              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4590              }              }
4591            }            }
# Line 4473  for (;;) Line 4607  for (;;)
4607              case 0x0c:      /* FF */              case 0x0c:      /* FF */
4608              case 0x0d:      /* CR */              case 0x0d:      /* CR */
4609              case 0x85:      /* NEL */              case 0x85:      /* NEL */
4610    #ifdef COMPILE_PCRE16
4611                case 0x2028:    /* LINE SEPARATOR */
4612                case 0x2029:    /* PARAGRAPH SEPARATOR */
4613    #endif
4614              break;              break;
4615              }              }
4616            }            }
# Line 4486  for (;;) Line 4624  for (;;)
4624              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4625              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4626              }              }
4627            if ((md->ctypes[*eptr++] & ctype_digit) != 0) RRETURN(MATCH_NOMATCH);            if (MAX_255(*eptr) && (md->ctypes[*eptr] & ctype_digit) != 0)
4628                RRETURN(MATCH_NOMATCH);
4629              eptr++;
4630            }            }
4631          break;          break;
4632    
# Line 4498  for (;;) Line 4638  for (;;)
4638              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4639              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4640              }              }
4641            if ((md->ctypes[*eptr++] & ctype_digit) == 0) RRETURN(MATCH_NOMATCH);            if (!MAX_255(*eptr) || (md->ctypes[*eptr] & ctype_digit) == 0)
4642                RRETURN(MATCH_NOMATCH);
4643              eptr++;
4644            }            }
4645          break;          break;
4646    
# Line 4510  for (;;) Line 4652  for (;;)
4652              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4653              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4654              }              }
4655            if ((md->ctypes[*eptr++] & ctype_space) != 0) RRETURN(MATCH_NOMATCH);            if (MAX_255(*eptr) && (md->ctypes[*eptr] & ctype_space) != 0)
4656                RRETURN(MATCH_NOMATCH);
4657              eptr++;
4658            }            }
4659          break;          break;
4660    
# Line 4522  for (;;) Line 4666  for (;;)
4666              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4667              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4668              }              }
4669            if ((md->ctypes[*eptr++] & ctype_space) == 0) RRETURN(MATCH_NOMATCH);            if (!MAX_255(*eptr) || (md->ctypes[*eptr] & ctype_space) == 0)
4670                RRETURN(MATCH_NOMATCH);
4671              eptr++;
4672            }            }
4673          break;          break;
4674    
# Line 4534  for (;;) Line 4680  for (;;)
4680              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4681              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4682              }              }
4683            if ((md->ctypes[*eptr++] & ctype_word) != 0)            if (MAX_255(*eptr) && (md->ctypes[*eptr] & ctype_word) != 0)
4684              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4685              eptr++;
4686            }            }
4687          break;          break;
4688    
# Line 4547  for (;;) Line 4694  for (;;)
4694              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4695              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4696              }              }
4697            if ((md->ctypes[*eptr++] & ctype_word) == 0)            if (!MAX_255(*eptr) || (md->ctypes[*eptr] & ctype_word) == 0)
4698              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4699              eptr++;
4700            }            }
4701          break;          break;
4702    
# Line 4766  for (;;) Line 4914  for (;;)
4914            while (eptr < md->end_subject)            while (eptr < md->end_subject)
4915              {              {
4916              int len = 1;              int len = 1;
4917              if (!utf8) c = *eptr; else { GETCHARLEN(c, eptr, len); }              if (!utf) c = *eptr; else { GETCHARLEN(c, eptr, len); }
4918              if (UCD_CATEGORY(c) != ucp_M) break;              if (UCD_CATEGORY(c) != ucp_M) break;
4919              eptr += len;              eptr += len;
4920              }              }
# Line 4775  for (;;) Line 4923  for (;;)
4923        else        else
4924  #endif     /* SUPPORT_UCP */  #endif     /* SUPPORT_UCP */
4925    
4926  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
4927        /* UTF-8 mode */        if (utf)
       if (utf8)  
4928          {          {
4929          for (fi = min;; fi++)          for (fi = min;; fi++)
4930            {            {
# Line 4919  for (;;) Line 5066  for (;;)
5066              break;              break;
5067    
5068              case OP_WHITESPACE:              case OP_WHITESPACE:
5069              if  (c >= 256 || (md->ctypes[c] & ctype_space) == 0)              if (c >= 256 || (md->ctypes[c] & ctype_space) == 0)
5070                RRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
5071              break;              break;
5072    
# Line 4940  for (;;) Line 5087  for (;;)
5087          }          }
5088        else        else
5089  #endif  #endif
5090        /* Not UTF-8 mode */        /* Not UTF mode */
5091          {          {
5092          for (fi = min;; fi++)          for (fi = min;; fi++)
5093            {            {
# Line 4976  for (;;) Line 5123  for (;;)
5123                case 0x000b:                case 0x000b:
5124                case 0x000c:                case 0x000c:
5125                case 0x0085:                case 0x0085:
5126    #ifdef COMPILE_PCRE16
5127                  case 0x2028:
5128                  case 0x2029:
5129    #endif
5130                if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH);                if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH);
5131                break;                break;
5132                }                }
# Line 4988  for (;;) Line 5139  for (;;)
5139                case 0x09:      /* HT */                case 0x09:      /* HT */
5140                case 0x20:      /* SPACE */                case 0x20:      /* SPACE */
5141                case 0xa0:      /* NBSP */                case 0xa0:      /* NBSP */
5142    #ifdef COMPILE_PCRE16
5143                  case 0x1680:    /* OGHAM SPACE MARK */
5144                  case 0x180e:    /* MONGOLIAN VOWEL SEPARATOR */
5145                  case 0x2000:    /* EN QUAD */
5146                  case 0x2001:    /* EM QUAD */
5147                  case 0x2002:    /* EN SPACE */
5148                  case 0x2003:    /* EM SPACE */
5149                  case 0x2004:    /* THREE-PER-EM SPACE */
5150                  case 0x2005:    /* FOUR-PER-EM SPACE */
5151                  case 0x2006:    /* SIX-PER-EM SPACE */
5152                  case 0x2007:    /* FIGURE SPACE */
5153                  case 0x2008:    /* PUNCTUATION SPACE */
5154                  case 0x2009:    /* THIN SPACE */
5155                  case 0x200A:    /* HAIR SPACE */
5156                  case 0x202f:    /* NARROW NO-BREAK SPACE */
5157                  case 0x205f:    /* MEDIUM MATHEMATICAL SPACE */
5158                  case 0x3000:    /* IDEOGRAPHIC SPACE */
5159    #endif
5160                RRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
5161                }                }
5162              break;              break;
# Line 4999  for (;;) Line 5168  for (;;)
5168                case 0x09:      /* HT */                case 0x09:      /* HT */
5169                case 0x20:      /* SPACE */                case 0x20:      /* SPACE */
5170                case 0xa0:      /* NBSP */                case 0xa0:      /* NBSP */
5171    #ifdef COMPILE_PCRE16
5172                  case 0x1680:    /* OGHAM SPACE MARK */
5173                  case 0x180e:    /* MONGOLIAN VOWEL SEPARATOR */
5174                  case 0x2000:    /* EN QUAD */
5175                  case 0x2001:    /* EM QUAD */
5176                  case 0x2002:    /* EN SPACE */
5177                  case 0x2003:    /* EM SPACE */
5178                  case 0x2004:    /* THREE-PER-EM SPACE */
5179                  case 0x2005:    /* FOUR-PER-EM SPACE */
5180                  case 0x2006:    /* SIX-PER-EM SPACE */
5181                  case 0x2007:    /* FIGURE SPACE */
5182                  case 0x2008:    /* PUNCTUATION SPACE */
5183                  case 0x2009:    /* THIN SPACE */
5184                  case 0x200A:    /* HAIR SPACE */
5185                  case 0x202f:    /* NARROW NO-BREAK SPACE */
5186                  case 0x205f:    /* MEDIUM MATHEMATICAL SPACE */
5187                  case 0x3000:    /* IDEOGRAPHIC SPACE */
5188    #endif
5189                break;                break;
5190                }                }
5191              break;              break;
# Line 5012  for (;;) Line 5199  for (;;)
5199                case 0x0c:      /* FF */                case 0x0c:      /* FF */
5200                case 0x0d:      /* CR */                case 0x0d:      /* CR */
5201                case 0x85:      /* NEL */                case 0x85:      /* NEL */
5202    #ifdef COMPILE_PCRE16
5203                  case 0x2028:    /* LINE SEPARATOR */
5204                  case 0x2029:    /* PARAGRAPH SEPARATOR */
5205    #endif
5206                RRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
5207                }                }
5208              break;              break;
# Line 5025  for (;;) Line 5216  for (;;)
5216                case 0x0c:      /* FF */                case 0x0c:      /* FF */
5217                case 0x0d:      /* CR */                case 0x0d:      /* CR */
5218                case 0x85:      /* NEL */                case 0x85:      /* NEL */
5219    #ifdef COMPILE_PCRE16
5220                  case 0x2028:    /* LINE SEPARATOR */
5221                  case 0x2029:    /* PARAGRAPH SEPARATOR */
5222    #endif
5223                break;                break;
5224                }                }
5225              break;              break;
5226    
5227              case OP_NOT_DIGIT:              case OP_NOT_DIGIT:
5228              if ((md->ctypes[c] & ctype_digit) != 0) RRETURN(MATCH_NOMATCH);              if (MAX_255(c) && (md->ctypes[c] & ctype_digit) != 0) RRETURN(MATCH_NOMATCH);
5229              break;              break;
5230    
5231              case OP_DIGIT:              case OP_DIGIT:
5232              if ((md->ctypes[c] & ctype_digit) == 0) RRETURN(MATCH_NOMATCH);              if (!MAX_255(c) || (md->ctypes[c] & ctype_digit) == 0) RRETURN(MATCH_NOMATCH);
5233              break;              break;
5234    
5235              case OP_NOT_WHITESPACE:              case OP_NOT_WHITESPACE:
5236              if ((md->ctypes[c] & ctype_space) != 0) RRETURN(MATCH_NOMATCH);              if (MAX_255(c) && (md->ctypes[c] & ctype_space) != 0) RRETURN(MATCH_NOMATCH);
5237              break;              break;
5238    
5239              case OP_WHITESPACE:              case OP_WHITESPACE:
5240              if  ((md->ctypes[c] & ctype_space) == 0) RRETURN(MATCH_NOMATCH);              if (!MAX_255(c) || (md->ctypes[c] & ctype_space) == 0) RRETURN(MATCH_NOMATCH);
5241              break;              break;
5242    
5243              case OP_NOT_WORDCHAR:              case OP_NOT_WORDCHAR:
5244              if ((md->ctypes[c] & ctype_word) != 0) RRETURN(MATCH_NOMATCH);              if (MAX_255(c) && (md->ctypes[c] & ctype_word) != 0) RRETURN(MATCH_NOMATCH);
5245              break;              break;
5246    
5247              case OP_WORDCHAR:              case OP_WORDCHAR:
5248              if ((md->ctypes[c] & ctype_word) == 0) RRETURN(MATCH_NOMATCH);              if (!MAX_255(c) || (md->ctypes[c] & ctype_word) == 0) RRETURN(MATCH_NOMATCH);
5249              break;              break;
5250    
5251              default:              default:
# Line 5239  for (;;) Line 5434  for (;;)
5434            RMATCH(eptr, ecode, offset_top, md, eptrb, RM44);            RMATCH(eptr, ecode, offset_top, md, eptrb, RM44);
5435            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
5436            if (eptr-- == pp) break;        /* Stop if tried at original pos */            if (eptr-- == pp) break;        /* Stop if tried at original pos */
5437            if (utf8) BACKCHAR(eptr);            if (utf) BACKCHAR(eptr);
5438            }            }
5439          }          }
5440    
# Line 5256  for (;;) Line 5451  for (;;)
5451              SCHECK_PARTIAL();              SCHECK_PARTIAL();
5452              break;              break;
5453              }              }
5454            if (!utf8) c = *eptr; else { GETCHARLEN(c, eptr, len); }            if (!utf) c = *eptr; else { GETCHARLEN(c, eptr, len); }
5455            if (UCD_CATEGORY(c) == ucp_M) break;            if (UCD_CATEGORY(c) == ucp_M) break;
5456            eptr += len;            eptr += len;
5457            while (eptr < md->end_subject)            while (eptr < md->end_subject)
5458              {              {
5459              len = 1;              len = 1;
5460              if (!utf8) c = *eptr; else { GETCHARLEN(c, eptr, len); }              if (!utf) c = *eptr; else { GETCHARLEN(c, eptr, len); }
5461              if (UCD_CATEGORY(c) != ucp_M) break;              if (UCD_CATEGORY(c) != ucp_M) break;
5462              eptr += len;              eptr += len;
5463              }              }
# Line 5279  for (;;) Line 5474  for (;;)
5474            if (eptr-- == pp) break;        /* Stop if tried at original pos */            if (eptr-- == pp) break;        /* Stop if tried at original pos */
5475            for (;;)                        /* Move back over one extended */            for (;;)                        /* Move back over one extended */
5476              {              {
5477              if (!utf8) c = *eptr; else              if (!utf) c = *eptr; else
5478                {                {
5479                BACKCHAR(eptr);                BACKCHAR(eptr);
5480                GETCHAR(c, eptr);                GETCHAR(c, eptr);
# Line 5293  for (;;) Line 5488  for (;;)
5488        else        else
5489  #endif   /* SUPPORT_UCP */  #endif   /* SUPPORT_UCP */
5490    
5491  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
5492        /* UTF-8 mode */        if (utf)
   
       if (utf8)  
5493          {          {
5494          switch(ctype)          switch(ctype)
5495            {            {
# Line 5312  for (;;) Line 5505  for (;;)
5505                  }                  }
5506                if (IS_NEWLINE(eptr)) break;                if (IS_NEWLINE(eptr)) break;
5507                eptr++;                eptr++;
5508                while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;                ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
5509                }                }
5510              }              }
5511    
# Line 5329  for (;;) Line 5522  for (;;)
5522                  }                  }
5523                if (IS_NEWLINE(eptr)) break;                if (IS_NEWLINE(eptr)) break;
5524                eptr++;                eptr++;
5525                while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;                ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
5526                }                }
5527              }              }
5528            break;            break;
# Line 5345  for (;;) Line 5538  for (;;)
5538                  break;                  break;
5539                  }                  }
5540                eptr++;                eptr++;
5541                while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;                ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
5542                }                }
5543              }              }
5544            else            else
# Line 5578  for (;;) Line 5771  for (;;)
5771            }            }
5772          }          }
5773        else        else
5774  #endif  /* SUPPORT_UTF8 */  #endif  /* SUPPORT_UTF */
5775          /* Not UTF mode */
       /* Not UTF-8 mode */  
5776          {          {
5777          switch(ctype)          switch(ctype)
5778            {            {
# Line 5624  for (;;) Line 5816  for (;;)
5816                }                }
5817              else              else
5818                {                {
5819                if (c != 0x000a &&                if (c != 0x000a && (md->bsr_anycrlf ||
5820                    (md->bsr_anycrlf ||                  (c != 0x000b && c != 0x000c && c != 0x0085
5821                      (c != 0x000b && c != 0x000c && c != 0x0085)))  #ifdef COMPILE_PCRE16
5822                  break;                  && c != 0x2028 && c != 0x2029
5823    #endif
5824                    ))) break;
5825                eptr++;                eptr++;
5826                }                }
5827              }              }
# Line 5642  for (;;) Line 5836  for (;;)
5836                break;                break;
5837                }                }
5838              c = *eptr;              c = *eptr;
5839              if (c == 0x09 || c == 0x20 || c == 0xa0) break;              if (c == 0x09 || c == 0x20 || c == 0xa0
5840    #ifdef COMPILE_PCRE16
5841                  || c == 0x1680 || c == 0x180e || (c >= 0x2000 && c <= 0x200A)
5842                  || c == 0x202f || c == 0x205f || c == 0x3000
5843    #endif
5844                  ) break;
5845              eptr++;              eptr++;
5846              }              }
5847            break;            break;
# Line 5656  for (;;) Line 5855  for (;;)
5855                break;                break;
5856                }                }
5857              c = *eptr;              c = *eptr;
5858              if (c != 0x09 && c != 0x20 && c != 0xa0) break;              if (c != 0x09 && c != 0x20 && c != 0xa0
5859    #ifdef COMPILE_PCRE16
5860                  && c != 0x1680 && c != 0x180e && (c < 0x2000 || c > 0x200A)
5861                  && c != 0x202f && c != 0x205f && c != 0x3000
5862    #endif
5863                  ) break;
5864              eptr++;              eptr++;
5865              }              }
5866            break;            break;
# Line 5670  for (;;) Line 5874  for (;;)
5874                break;                break;
5875                }                }
5876              c = *eptr;              c = *eptr;
5877              if (c == 0x0a || c == 0x0b || c == 0x0c || c == 0x0d || c == 0x85)              if (c == 0x0a || c == 0x0b || c == 0x0c || c == 0x0d || c == 0x85
5878                break;  #ifdef COMPILE_PCRE16
5879                  || c == 0x2028 || c == 0x2029
5880    #endif
5881                  ) break;
5882              eptr++;              eptr++;
5883              }              }
5884            break;            break;
# Line 5685  for (;;) Line 5892  for (;;)
5892                break;                break;
5893                }                }
5894              c = *eptr;              c = *eptr;
5895              if (c != 0x0a && c != 0x0b && c != 0x0c && c != 0x0d && c != 0x85)              if (c != 0x0a && c != 0x0b && c != 0x0c && c != 0x0d && c != 0x85
5896                break;  #ifdef COMPILE_PCRE16
5897                  && c != 0x2028 && c != 0x2029
5898    #endif
5899                  ) break;
5900              eptr++;              eptr++;
5901              }              }
5902            break;            break;
# Line 5699  for (;;) Line 5909  for (;;)
5909                SCHECK_PARTIAL();                SCHECK_PARTIAL();
5910                break;                break;
5911                }                }
5912              if ((md->ctypes[*eptr] & ctype_digit) != 0) break;              if (MAX_255(*eptr) && (md->ctypes[*eptr] & ctype_digit) != 0) break;
5913              eptr++;              eptr++;
5914              }              }
5915            break;            break;
# Line 5712  for (;;) Line 5922  for (;;)
5922                SCHECK_PARTIAL();                SCHECK_PARTIAL();
5923                break;                break;
5924                }                }
5925              if ((md->ctypes[*eptr] & ctype_digit) == 0) break;              if (!MAX_255(*eptr) || (md->ctypes[*eptr] & ctype_digit) == 0) break;
5926              eptr++;              eptr++;
5927              }              }
5928            break;            break;
# Line 5725  for (;;) Line 5935  for (;;)
5935                SCHECK_PARTIAL();                SCHECK_PARTIAL();
5936                break;                break;
5937                }                }
5938              if ((md->ctypes[*eptr] & ctype_space) != 0) break;              if (MAX_255(*eptr) && (md->ctypes[*eptr] & ctype_space) != 0) break;
5939              eptr++;              eptr++;
5940              }              }
5941            break;            break;
# Line 5738  for (;;) Line 5948  for (;;)
5948                SCHECK_PARTIAL();                SCHECK_PARTIAL();
5949                break;                break;
5950                }                }
5951              if ((md->ctypes[*eptr] & ctype_space) == 0) break;              if (!MAX_255(*eptr) || (md->ctypes[*eptr] & ctype_space) == 0) break;
5952              eptr++;              eptr++;
5953              }              }
5954            break;            break;
# Line 5751  for (;;) Line 5961  for (;;)
5961                SCHECK_PARTIAL();                SCHECK_PARTIAL();
5962                break;                break;
5963                }                }
5964              if ((md->ctypes[*eptr] & ctype_word) != 0) break;              if (MAX_255(*eptr) && (md->ctypes[*eptr] & ctype_word) != 0) break;
5965              eptr++;              eptr++;
5966              }              }
5967            break;            break;
# Line 5764  for (;;) Line 5974  for (;;)
5974                SCHECK_PARTIAL();                SCHECK_PARTIAL();
5975                break;                break;
5976                }                }
5977              if ((md->ctypes[*eptr] & ctype_word) == 0) break;              if (!MAX_255(*eptr) || (md->ctypes[*eptr] & ctype_word) == 0) break;
5978              eptr++;              eptr++;
5979              }              }
5980            break;            break;
# Line 5827  switch (frame->Xwhere) Line 6037  switch (frame->Xwhere)
6037    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)
6038    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)
6039    LBL(65) LBL(66)    LBL(65) LBL(66)
6040  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
6041    LBL(16) LBL(18) LBL(20) LBL(21) LBL(22) LBL(23) LBL(28) LBL(30)    LBL(21)
6042    #endif
6043    #ifdef SUPPORT_UTF
6044      LBL(16) LBL(18) LBL(20)
6045      LBL(22) LBL(23) LBL(28) LBL(30)
6046    LBL(32) LBL(34) LBL(42) LBL(46)    LBL(32) LBL(34) LBL(42) LBL(46)
6047  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
6048    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)
6049    LBL(59) LBL(60) LBL(61) LBL(62)    LBL(59) LBL(60) LBL(61) LBL(62)
6050  #endif  /* SUPPORT_UCP */  #endif  /* SUPPORT_UCP */
6051  #endif  /* SUPPORT_UTF8 */  #endif  /* SUPPORT_UTF */
6052    default:    default:
6053    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));
6054    
6055    printf("+++jump error in pcre match: label %d non-existent\n", frame->Xwhere);
6056    
6057    return PCRE_ERROR_INTERNAL;    return PCRE_ERROR_INTERNAL;
6058    }    }
6059  #undef LBL  #undef LBL
# Line 5923  Returns:          > 0 => success; value Line 6140  Returns:          > 0 => success; value
6140                   < -1 => some kind of unexpected problem                   < -1 => some kind of unexpected problem
6141  */  */
6142    
6143    #ifdef COMPILE_PCRE8
6144  PCRE_EXP_DEFN int PCRE_CALL_CONVENTION  PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
6145  pcre_exec(const pcre *argument_re, const pcre_extra *extra_data,  pcre_exec(const pcre *argument_re, const pcre_extra *extra_data,
6146    PCRE_SPTR subject, int length, int start_offset, int options, int *offsets,    PCRE_SPTR subject, int length, int start_offset, int options, int *offsets,
6147    int offsetcount)    int offsetcount)
6148    #else
6149    PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
6150    pcre16_exec(const pcre16 *argument_re, const pcre16_extra *extra_data,
6151      PCRE_SPTR16 subject, int length, int start_offset, int options, int *offsets,
6152      int offsetcount)
6153    #endif
6154  {  {
6155  int rc, ocount, arg_offset_max;  int rc, ocount, arg_offset_max;
 int first_byte = -1;  
 int req_byte = -1;  
 int req_byte2 = -1;  
6156  int newline;  int newline;
6157  BOOL using_temporary_offsets = FALSE;  BOOL using_temporary_offsets = FALSE;
6158  BOOL anchored;  BOOL anchored;
6159  BOOL startline;  BOOL startline;
6160  BOOL firstline;  BOOL firstline;
6161  BOOL first_byte_caseless = FALSE;  BOOL utf;
6162  BOOL req_byte_caseless = FALSE;  BOOL has_first_char = FALSE;
6163  BOOL utf8;  BOOL has_req_char = FALSE;
6164    pcre_uchar first_char = 0;
6165    pcre_uchar first_char2 = 0;
6166    pcre_uchar req_char = 0;
6167    pcre_uchar req_char2 = 0;
6168  match_data match_block;  match_data match_block;
6169  match_data *md = &match_block;  match_data *md = &match_block;
6170  const uschar *tables;  const pcre_uint8 *tables;
6171  const uschar *start_bits = NULL;  const pcre_uint8 *start_bits = NULL;
6172  USPTR start_match = (USPTR)subject + start_offset;  PCRE_PUCHAR start_match = (PCRE_PUCHAR)subject + start_offset;
6173  USPTR end_subject;  PCRE_PUCHAR end_subject;
6174  USPTR start_partial = NULL;  PCRE_PUCHAR start_partial = NULL;
6175  USPTR req_byte_ptr = start_match - 1;  PCRE_PUCHAR req_char_ptr = start_match - 1;
6176    
 pcre_study_data internal_study;  
6177  const pcre_study_data *study;  const pcre_study_data *study;
6178    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;  
6179    
6180  /* Plausibility checks */  /* Plausibility checks */
6181    
# Line 5969  follows immediately afterwards. Other va Line 6190  follows immediately afterwards. Other va
6190  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,
6191  so they are set up later. */  so they are set up later. */
6192    
6193  utf8 = md->utf8 = (re->options & PCRE_UTF8) != 0;  /* PCRE_UTF16 has the same value as PCRE_UTF8. */
6194    utf = md->utf = (re->options & PCRE_UTF8) != 0;
6195  md->partial = ((options & PCRE_PARTIAL_HARD) != 0)? 2 :  md->partial = ((options & PCRE_PARTIAL_HARD) != 0)? 2 :
6196                ((options & PCRE_PARTIAL_SOFT) != 0)? 1 : 0;                ((options & PCRE_PARTIAL_SOFT) != 0)? 1 : 0;
6197    
6198  /* 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
6199  code for an invalid string if a results vector is available. */  code for an invalid string if a results vector is available. */
6200    
6201  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
6202  if (utf8 && (options & PCRE_NO_UTF8_CHECK) == 0)  if (utf && (options & PCRE_NO_UTF8_CHECK) == 0)
6203    {    {
6204    int erroroffset;    int erroroffset;
6205    int errorcode = _pcre_valid_utf8((USPTR)subject, length, &erroroffset);    int errorcode = PRIV(valid_utf)((PCRE_PUCHAR)subject, length, &erroroffset);
6206    if (errorcode != 0)    if (errorcode != 0)
6207      {      {
6208      if (offsetcount >= 2)      if (offsetcount >= 2)
# Line 5988  if (utf8 && (options & PCRE_NO_UTF8_CHEC Line 6210  if (utf8 && (options & PCRE_NO_UTF8_CHEC
6210        offsets[0] = erroroffset;        offsets[0] = erroroffset;
6211        offsets[1] = errorcode;        offsets[1] = errorcode;
6212        }        }
6213    #ifdef COMPILE_PCRE16
6214        return (errorcode <= PCRE_UTF16_ERR1 && md->partial > 1)?
6215          PCRE_ERROR_SHORTUTF16 : PCRE_ERROR_BADUTF16;
6216    #else
6217      return (errorcode <= PCRE_UTF8_ERR5 && md->partial > 1)?      return (errorcode <= PCRE_UTF8_ERR5 && md->partial > 1)?
6218        PCRE_ERROR_SHORTUTF8 : PCRE_ERROR_BADUTF8;        PCRE_ERROR_SHORTUTF8 : PCRE_ERROR_BADUTF8;
6219    #endif
6220      }      }
6221    
6222    /* 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. */
6223    if (start_offset > 0 && start_offset < length &&    if (start_offset > 0 && start_offset < length &&
6224        (((USPTR)subject)[start_offset] & 0xc0) == 0x80)        NOT_FIRSTCHAR(((PCRE_PUCHAR)subject)[start_offset]))
6225      return PCRE_ERROR_BADUTF8_OFFSET;      return PCRE_ERROR_BADUTF8_OFFSET;
6226    }    }
6227  #endif  #endif
# Line 6012  if (extra_data != NULL Line 6239  if (extra_data != NULL
6239      && (extra_data->flags & PCRE_EXTRA_TABLES) == 0      && (extra_data->flags & PCRE_EXTRA_TABLES) == 0
6240      && (options & ~(PCRE_NO_UTF8_CHECK | PCRE_NOTBOL | PCRE_NOTEOL |      && (options & ~(PCRE_NO_UTF8_CHECK | PCRE_NOTBOL | PCRE_NOTEOL |
6241                      PCRE_NOTEMPTY | PCRE_NOTEMPTY_ATSTART)) == 0)                      PCRE_NOTEMPTY | PCRE_NOTEMPTY_ATSTART)) == 0)
6242    return _pcre_jit_exec(re, extra_data->executable_jit, subject, length,    return PRIV(jit_exec)(re, extra_data->executable_jit,
6243      start_offset, options, ((extra_data->flags & PCRE_EXTRA_MATCH_LIMIT) == 0)      (const pcre_uchar *)subject, length, start_offset, options,
6244        ((extra_data->flags & PCRE_EXTRA_MATCH_LIMIT) == 0)
6245      ? MATCH_LIMIT : extra_data->match_limit, offsets, offsetcount);      ? MATCH_LIMIT : extra_data->match_limit, offsets, offsetcount);
6246  #endif  #endif
6247    
6248  /* 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
6249  numbers associated with a given name, for condition testing. */  numbers associated with a given name, for condition testing. */
6250    
6251  md->name_table = (uschar *)re + re->name_table_offset;  md->name_table = (pcre_uchar *)re + re->name_table_offset;
6252  md->name_count = re->name_count;  md->name_count = re->name_count;
6253  md->name_entry_size = re->name_entry_size;  md->name_entry_size = re->name_entry_size;
6254    
# Line 6034  md->callout_data = NULL; Line 6262  md->callout_data = NULL;
6262    
6263  /* The table pointer is always in native byte order. */  /* The table pointer is always in native byte order. */
6264    
6265  tables = external_re->tables;  tables = re->tables;
6266    
6267  if (extra_data != NULL)  if (extra_data != NULL)
6268    {    {
# Line 6054  if (extra_data != NULL) Line 6282  if (extra_data != NULL)
6282  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
6283  in other programs later. */  in other programs later. */
6284    
6285  if (tables == NULL) tables = _pcre_default_tables;  if (tables == NULL) tables = PRIV(default_tables);
6286    
6287  /* 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,
6288  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
6289  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
6290  study data too. */  means that the pattern is likely compiled with different endianness. */
6291    
6292  if (re->magic_number != MAGIC_NUMBER)  if (re->magic_number != MAGIC_NUMBER)
6293    {    return re->magic_number == REVERSED_MAGIC_NUMBER?
6294    re = _pcre_try_flipped(re, &internal_re, study, &internal_study);      PCRE_ERROR_BADENDIANNESS:PCRE_ERROR_BADMAGIC;
6295    if (re == NULL) return PCRE_ERROR_BADMAGIC;  if ((re->flags & PCRE_MODE) == 0) return PCRE_ERROR_BADMODE;
   if (study != NULL) study = &internal_study;  
   }  
6296    
6297  /* Set up other data */  /* Set up other data */
6298    
# Line 6076  firstline = (re->options & PCRE_FIRSTLIN Line 6302  firstline = (re->options & PCRE_FIRSTLIN
6302    
6303  /* 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. */
6304    
6305  md->start_code = (const uschar *)external_re + re->name_table_offset +  md->start_code = (const pcre_uchar *)re + re->name_table_offset +
6306    re->name_count * re->name_entry_size;    re->name_count * re->name_entry_size;
6307    
6308  md->start_subject = (USPTR)subject;  md->start_subject = (PCRE_PUCHAR)subject;
6309  md->start_offset = start_offset;  md->start_offset = start_offset;
6310  md->end_subject = md->start_subject + length;  md->end_subject = md->start_subject + length;
6311  end_subject = md->end_subject;  end_subject = md->end_subject;
# Line 6104  md->recursive = NULL; Line 6330  md->recursive = NULL;
6330  md->hasthen = (re->flags & PCRE_HASTHEN) != 0;  md->hasthen = (re->flags & PCRE_HASTHEN) != 0;
6331    
6332  md->lcc = tables + lcc_offset;  md->lcc = tables + lcc_offset;
6333    md->fcc = tables + fcc_offset;
6334  md->ctypes = tables + ctypes_offset;  md->ctypes = tables + ctypes_offset;
6335    
6336  /* Handle different \R options. */  /* Handle different \R options. */
# Line 6190  arg_offset_max = (2*ocount)/3; Line 6417  arg_offset_max = (2*ocount)/3;
6417  if (re->top_backref > 0 && re->top_backref >= ocount/3)  if (re->top_backref > 0 && re->top_backref >= ocount/3)
6418    {    {
6419    ocount = re->top_backref * 3 + 3;    ocount = re->top_backref * 3 + 3;
6420    md->offset_vector = (int *)(pcre_malloc)(ocount * sizeof(int));    md->offset_vector = (int *)(PUBL(malloc))(ocount * sizeof(int));
6421    if (md->offset_vector == NULL) return PCRE_ERROR_NOMEMORY;    if (md->offset_vector == NULL) return PCRE_ERROR_NOMEMORY;
6422    using_temporary_offsets = TRUE;    using_temporary_offsets = TRUE;
6423    DPRINTF(("Got memory to hold back references\n"));    DPRINTF(("Got memory to hold back references\n"));
# Line 6217  if (md->offset_vector != NULL) Line 6444  if (md->offset_vector != NULL)
6444    md->offset_vector[0] = md->offset_vector[1] = -1;    md->offset_vector[0] = md->offset_vector[1] = -1;
6445    }    }
6446    
6447  /* 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
6448  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
6449  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
6450  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 6454  if (!anchored)
6454    {    {
6455    if ((re->flags & PCRE_FIRSTSET) != 0)    if ((re->flags & PCRE_FIRSTSET) != 0)
6456      {      {
6457      first_byte = re->first_byte & 255;      has_first_char = TRUE;
6458      if ((first_byte_caseless = ((re->first_byte & REQ_CASELESS) != 0)) == TRUE)      first_char = first_char2 = re->first_char;
6459        first_byte = md->lcc[first_byte];      if ((re->flags & PCRE_FCH_CASELESS) != 0)
6460          {
6461          first_char2 = TABLE_GET(first_char, md->fcc, first_char);
6462    #if defined SUPPORT_UCP && !(defined COMPILE_PCRE8)
6463          if (utf && first_char > 127)
6464            first_char2 = UCD_OTHERCASE(first_char);
6465    #endif
6466          }
6467      }      }
6468    else    else
6469      if (!startline && study != NULL &&      if (!startline && study != NULL &&
# Line 6242  character" set. */ Line 6476  character" set. */
6476    
6477  if ((re->flags & PCRE_REQCHSET) != 0)  if ((re->flags & PCRE_REQCHSET) != 0)
6478    {    {
6479    req_byte = re->req_byte & 255;    has_req_char = TRUE;
6480    req_byte_caseless = (re->req_byte & REQ_CASELESS) != 0;    req_char = req_char2 = re->req_char;
6481    req_byte2 = (tables + fcc_offset)[req_byte];  /* case flipped */    if ((re->flags & PCRE_RCH_CASELESS) != 0)
6482        {
6483        req_char2 = TABLE_GET(req_char, md->fcc, req_char);
6484    #if defined SUPPORT_UCP && !(defined COMPILE_PCRE8)
6485        if (utf && req_char > 127)
6486          req_char2 = UCD_OTHERCASE(req_char);
6487    #endif
6488        }
6489    }    }
6490    
6491    
   
   
6492  /* ==========================================================================*/  /* ==========================================================================*/
6493    
6494  /* 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 6496  the loop runs just once. */
6496    
6497  for(;;)  for(;;)
6498    {    {
6499    USPTR save_end_subject = end_subject;    PCRE_PUCHAR save_end_subject = end_subject;
6500    USPTR new_start_match;    PCRE_PUCHAR new_start_match;
6501    
6502    /* 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
6503    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 6507  for(;;)
6507    
6508    if (firstline)    if (firstline)
6509      {      {
6510      USPTR t = start_match;      PCRE_PUCHAR t = start_match;
6511  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
6512      if (utf8)      if (utf)
6513        {        {
6514        while (t < md->end_subject && !IS_NEWLINE(t))        while (t < md->end_subject && !IS_NEWLINE(t))
6515          {          {
6516          t++;          t++;
6517          while (t < end_subject && (*t & 0xc0) == 0x80) t++;          ACROSSCHAR(t < end_subject, *t, t++);
6518          }          }
6519        }        }
6520      else      else
# Line 6292  for(;;) Line 6531  for(;;)
6531    
6532    if (((options | re->options) & PCRE_NO_START_OPTIMIZE) == 0)    if (((options | re->options) & PCRE_NO_START_OPTIMIZE) == 0)
6533      {      {
6534      /* Advance to a unique first byte if there is one. */      /* Advance to a unique first char if there is one. */
6535    
6536      if (first_byte >= 0)      if (has_first_char)
6537        {        {
6538        if (first_byte_caseless)        if (first_char != first_char2)
6539          while (start_match < end_subject && md->lcc[*start_match] != first_byte)          while (start_match < end_subject &&
6540                *start_match != first_char && *start_match != first_char2)
6541            start_match++;            start_match++;
6542        else        else
6543          while (start_match < end_subject && *start_match != first_byte)          while (start_match < end_subject && *start_match != first_char)
6544            start_match++;            start_match++;
6545        }        }
6546    
# Line 6310  for(;;) Line 6550  for(;;)
6550        {        {
6551        if (start_match > md->start_subject + start_offset)        if (start_match > md->start_subject + start_offset)
6552          {          {
6553  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
6554          if (utf8)          if (utf)
6555            {            {
6556            while (start_match < end_subject && !WAS_NEWLINE(start_match))            while (start_match < end_subject && !WAS_NEWLINE(start_match))
6557              {              {
6558              start_match++;              start_match++;
6559              while(start_match < end_subject && (*start_match & 0xc0) == 0x80)              ACROSSCHAR(start_match < end_subject, *start_match,
6560                start_match++;                start_match++);
6561              }              }
6562            }            }
6563          else          else
# Line 6344  for(;;) Line 6584  for(;;)
6584        while (start_match < end_subject)        while (start_match < end_subject)
6585          {          {
6586          register unsigned int c = *start_match;          register unsigned int c = *start_match;
6587    #ifndef COMPILE_PCRE8
6588            if (c > 255) c = 255;
6589    #endif
6590          if ((start_bits[c/8] & (1 << (c&7))) == 0)          if ((start_bits[c/8] & (1 << (c&7))) == 0)
6591            {            {
6592            start_match++;            start_match++;
6593  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF && defined COMPILE_PCRE8
6594            if (utf8)            /* In non 8-bit mode, the iteration will stop for
6595              while(start_match < end_subject && (*start_match & 0xc0) == 0x80)            characters > 255 at the beginning or not stop at all. */
6596                start_match++;            if (utf)
6597                ACROSSCHAR(start_match < end_subject, *start_match,
6598                  start_match++);
6599  #endif  #endif
6600            }            }
6601          else break;          else break;
# Line 6379  for(;;) Line 6624  for(;;)
6624        break;        break;
6625        }        }
6626    
6627      /* 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
6628      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
6629      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.
6630      This optimization can save a huge amount of backtracking in patterns with      This optimization can save a huge amount of backtracking in patterns with
6631      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 6638  for(;;)
6638      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
6639      long. */      long. */
6640    
6641      if (req_byte >= 0 && end_subject - start_match < REQ_BYTE_MAX)      if (has_req_char && end_subject - start_match < REQ_BYTE_MAX)
6642        {        {
6643        register USPTR p = start_match + ((first_byte >= 0)? 1 : 0);        register PCRE_PUCHAR p = start_match + (has_first_char? 1:0);
6644    
6645        /* 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
6646        place we found it at last time. */        place we found it at last time. */
6647    
6648        if (p > req_byte_ptr)        if (p > req_char_ptr)
6649          {          {
6650          if (req_byte_caseless)          if (req_char != req_char2)
6651            {            {
6652            while (p < end_subject)            while (p < end_subject)
6653              {              {
6654              register int pp = *p++;              register int pp = *p++;
6655              if (pp == req_byte || pp == req_byte2) { p--; break; }              if (pp == req_char || pp == req_char2) { p--; break; }
6656              }              }
6657            }            }
6658          else          else
6659            {            {
6660            while (p < end_subject)            while (p < end_subject)
6661              {              {
6662              if (*p++ == req_byte) { p--; break; }              if (*p++ == req_char) { p--; break; }
6663              }              }
6664            }            }
6665    
# Line 6431  for(;;) Line 6676  for(;;)
6676          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
6677          the start hasn't passed this character yet. */          the start hasn't passed this character yet. */
6678    
6679          req_byte_ptr = p;          req_char_ptr = p;
6680          }          }
6681        }        }
6682      }      }
# Line 6456  for(;;) Line 6701  for(;;)
6701    switch(rc)    switch(rc)
6702      {      {
6703      /* 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
6704      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
6705      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
6706      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
6707      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
6708      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. */
6709    
6710      case MATCH_SKIP_ARG:      case MATCH_SKIP_ARG:
6711      new_start_match = start_match;      new_start_match = start_match;
6712      md->ignore_skip_arg = TRUE;      md->ignore_skip_arg = TRUE;
6713      break;      break;
6714    
6715      /* 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
6716      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 6731  for(;;)
6731      case MATCH_THEN:      case MATCH_THEN:
6732      md->ignore_skip_arg = FALSE;      md->ignore_skip_arg = FALSE;
6733      new_start_match = start_match + 1;      new_start_match = start_match + 1;
6734  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
6735      if (utf8)      if (utf)
6736        while(new_start_match < end_subject && (*new_start_match & 0xc0) == 0x80)        ACROSSCHAR(new_start_match < end_subject, *new_start_match,
6737          new_start_match++;          new_start_match++);
6738  #endif  #endif
6739      break;      break;
6740    
# Line 6527  for(;;) Line 6772  for(;;)
6772    
6773    /* 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
6774    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
6775    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
6776      normal matching start_match will aways be greater than the first position at
6777      this stage, but a failed *SKIP can cause a return at the same point, which is
6778      why the first test exists. */
6779    
6780    if (start_match[-1] == CHAR_CR &&    if (start_match > (PCRE_PUCHAR)subject + start_offset &&
6781          start_match[-1] == CHAR_CR &&
6782        start_match < end_subject &&        start_match < end_subject &&
6783        *start_match == CHAR_NL &&        *start_match == CHAR_NL &&
6784        (re->flags & PCRE_HASCRORLF) == 0 &&        (re->flags & PCRE_HASCRORLF) == 0 &&
# Line 6575  if (rc == MATCH_MATCH || rc == MATCH_ACC Line 6824  if (rc == MATCH_MATCH || rc == MATCH_ACC
6824        }        }
6825      if (md->end_offset_top > arg_offset_max) md->offset_overflow = TRUE;      if (md->end_offset_top > arg_offset_max) md->offset_overflow = TRUE;
6826      DPRINTF(("Freeing temporary memory\n"));      DPRINTF(("Freeing temporary memory\n"));
6827      (pcre_free)(md->offset_vector);      (PUBL(free))(md->offset_vector);
6828      }      }
6829    
6830    /* 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 6863  if (rc == MATCH_MATCH || rc == MATCH_ACC
6863      }      }
6864    
6865    /* Return MARK data if requested */    /* Return MARK data if requested */
6866    
6867    if (extra_data != NULL && (extra_data->flags & PCRE_EXTRA_MARK) != 0)    if (extra_data != NULL && (extra_data->flags & PCRE_EXTRA_MARK) != 0)
6868      *(extra_data->mark) = (unsigned char *)(md->mark);      *(extra_data->mark) = (pcre_uchar *)md->mark;
6869    DPRINTF((">>>> returning %d\n", rc));    DPRINTF((">>>> returning %d\n", rc));
6870    return rc;    return rc;
6871    }    }
# Line 6627  attempt has failed at all permitted star Line 6876  attempt has failed at all permitted star
6876  if (using_temporary_offsets)  if (using_temporary_offsets)
6877    {    {
6878    DPRINTF(("Freeing temporary memory\n"));    DPRINTF(("Freeing temporary memory\n"));
6879    (pcre_free)(md->offset_vector);    (PUBL(free))(md->offset_vector);
6880    }    }
6881    
6882  /* 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 6895  if (start_partial != NULL)
6895    md->mark = NULL;    md->mark = NULL;
6896    if (offsetcount > 1)    if (offsetcount > 1)
6897      {      {
6898      offsets[0] = (int)(start_partial - (USPTR)subject);      offsets[0] = (int)(start_partial - (PCRE_PUCHAR)subject);
6899      offsets[1] = (int)(end_subject - (USPTR)subject);      offsets[1] = (int)(end_subject - (PCRE_PUCHAR)subject);
6900      }      }
6901    rc = PCRE_ERROR_PARTIAL;    rc = PCRE_ERROR_PARTIAL;
6902    }    }
# Line 6663  else Line 6912  else
6912  /* Return the MARK data if it has been requested. */  /* Return the MARK data if it has been requested. */
6913    
6914  if (extra_data != NULL && (extra_data->flags & PCRE_EXTRA_MARK) != 0)  if (extra_data != NULL && (extra_data->flags & PCRE_EXTRA_MARK) != 0)
6915    *(extra_data->mark) = (unsigned char *)(md->nomatch_mark);    *(extra_data->mark) = (pcre_uchar *)md->nomatch_mark;
6916  return rc;  return rc;
6917  }  }
6918    

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

  ViewVC Help
Powered by ViewVC 1.1.5