/[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 922 by ph10, Mon Feb 20 18:44:42 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 140  Arguments: Line 140  Arguments:
140    md          points to match data block    md          points to match data block
141    caseless    TRUE if caseless    caseless    TRUE if caseless
142    
143  Returns:      < 0 if not matched, otherwise the number of subject bytes matched  Returns:      >= 0 the number of subject bytes matched
144                  -1 no match
145                  -2 partial match; always given if at end subject
146  */  */
147    
148  static int  static int
149  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,
150    BOOL caseless)    BOOL caseless)
151  {  {
152  USPTR eptr_start = eptr;  PCRE_PUCHAR eptr_start = eptr;
153  register USPTR p = md->start_subject + md->offset_vector[offset];  register PCRE_PUCHAR p = md->start_subject + md->offset_vector[offset];
154    
155  #ifdef PCRE_DEBUG  #ifdef PCRE_DEBUG
156  if (eptr >= md->end_subject)  if (eptr >= md->end_subject)
# Line 163  pchars(p, length, FALSE, md); Line 165  pchars(p, length, FALSE, md);
165  printf("\n");  printf("\n");
166  #endif  #endif
167    
168  /* Always fail if reference not set (and not JavaScript compatible). */  /* Always fail if reference not set (and not JavaScript compatible - in that
169    case the length is passed as zero). */
170    
171  if (length < 0) return -1;  if (length < 0) return -1;
172    
# Line 173  ASCII characters. */ Line 176  ASCII characters. */
176    
177  if (caseless)  if (caseless)
178    {    {
179  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
180  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
181    if (md->utf8)    if (md->utf)
182      {      {
183      /* 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
184      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 188  if (caseless)
188      the latter. It is important, therefore, to check the length along the      the latter. It is important, therefore, to check the length along the
189      reference, not along the subject (earlier code did this wrong). */      reference, not along the subject (earlier code did this wrong). */
190    
191      USPTR endptr = p + length;      PCRE_PUCHAR endptr = p + length;
192      while (p < endptr)      while (p < endptr)
193        {        {
194        int c, d;        int c, d;
195        if (eptr >= md->end_subject) return -1;        if (eptr >= md->end_subject) return -2;   /* Partial match */
196        GETCHARINC(c, eptr);        GETCHARINC(c, eptr);
197        GETCHARINC(d, p);        GETCHARINC(d, p);
198        if (c != d && c != UCD_OTHERCASE(d)) return -1;        if (c != d && c != UCD_OTHERCASE(d)) return -1;
# Line 202  if (caseless) Line 205  if (caseless)
205    /* The same code works when not in UTF-8 mode and in UTF-8 mode when there    /* The same code works when not in UTF-8 mode and in UTF-8 mode when there
206    is no UCP support. */    is no UCP support. */
207      {      {
     if (eptr + length > md->end_subject) return -1;  
208      while (length-- > 0)      while (length-- > 0)
209        { if (md->lcc[*p++] != md->lcc[*eptr++]) return -1; }        {
210          if (eptr >= md->end_subject) return -2;   /* Partial match */
211          if (TABLE_GET(*p, md->lcc, *p) != TABLE_GET(*eptr, md->lcc, *eptr)) return -1;
212          p++;
213          eptr++;
214          }
215      }      }
216    }    }
217    
# Line 213  are in UTF-8 mode. */ Line 220  are in UTF-8 mode. */
220    
221  else  else
222    {    {
223    if (eptr + length > md->end_subject) return -1;    while (length-- > 0)
224    while (length-- > 0) if (*p++ != *eptr++) return -1;      {
225        if (eptr >= md->end_subject) return -2;   /* Partial match */
226        if (*p++ != *eptr++) return -1;
227        }
228    }    }
229    
230  return eptr - eptr_start;  return (int)(eptr - eptr_start);
231  }  }
232    
233    
# Line 307  argument of match(), which never changes Line 317  argument of match(), which never changes
317    
318  #define RMATCH(ra,rb,rc,rd,re,rw)\  #define RMATCH(ra,rb,rc,rd,re,rw)\
319    {\    {\
320    heapframe *newframe = (heapframe *)(pcre_stack_malloc)(sizeof(heapframe));\    heapframe *newframe = (heapframe *)(PUBL(stack_malloc))(sizeof(heapframe));\
321    if (newframe == NULL) RRETURN(PCRE_ERROR_NOMEMORY);\    if (newframe == NULL) RRETURN(PCRE_ERROR_NOMEMORY);\
322    frame->Xwhere = rw; \    frame->Xwhere = rw; \
323    newframe->Xeptr = ra;\    newframe->Xeptr = ra;\
# Line 328  argument of match(), which never changes Line 338  argument of match(), which never changes
338    {\    {\
339    heapframe *oldframe = frame;\    heapframe *oldframe = frame;\
340    frame = oldframe->Xprevframe;\    frame = oldframe->Xprevframe;\
341    (pcre_stack_free)(oldframe);\    if (oldframe != &frame_zero) (PUBL(stack_free))(oldframe);\
342    if (frame != NULL)\    if (frame != NULL)\
343      {\      {\
344      rrc = ra;\      rrc = ra;\
# Line 345  typedef struct heapframe { Line 355  typedef struct heapframe {
355    
356    /* Function arguments that may change */    /* Function arguments that may change */
357    
358    USPTR Xeptr;    PCRE_PUCHAR Xeptr;
359    const uschar *Xecode;    const pcre_uchar *Xecode;
360    USPTR Xmstart;    PCRE_PUCHAR Xmstart;
361    int Xoffset_top;    int Xoffset_top;
362    eptrblock *Xeptrb;    eptrblock *Xeptrb;
363    unsigned int Xrdepth;    unsigned int Xrdepth;
364    
365    /* Function local variables */    /* Function local variables */
366    
367    USPTR Xcallpat;    PCRE_PUCHAR Xcallpat;
368  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
369    USPTR Xcharptr;    PCRE_PUCHAR Xcharptr;
370  #endif  #endif
371    USPTR Xdata;    PCRE_PUCHAR Xdata;
372    USPTR Xnext;    PCRE_PUCHAR Xnext;
373    USPTR Xpp;    PCRE_PUCHAR Xpp;
374    USPTR Xprev;    PCRE_PUCHAR Xprev;
375    USPTR Xsaved_eptr;    PCRE_PUCHAR Xsaved_eptr;
376    
377    recursion_info Xnew_recursive;    recursion_info Xnew_recursive;
378    
# Line 375  typedef struct heapframe { Line 385  typedef struct heapframe {
385    int Xprop_value;    int Xprop_value;
386    int Xprop_fail_result;    int Xprop_fail_result;
387    int Xoclength;    int Xoclength;
388    uschar Xocchars[8];    pcre_uchar Xocchars[6];
389  #endif  #endif
390    
391    int Xcodelink;    int Xcodelink;
# Line 417  returns a negative (error) response, the Line 427  returns a negative (error) response, the
427  same response. */  same response. */
428    
429  /* 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
430  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
431  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.
432  something has been matched). For hard partial matching, we then return  something has been matched). For hard partial matching, we then return
433  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 450  the subject. */
450    
451    
452  /* Performance note: It might be tempting to extract commonly used fields from  /* Performance note: It might be tempting to extract commonly used fields from
453  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
454  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
455  made performance worse.  made performance worse.
456    
# Line 463  Returns:       MATCH_MATCH if matched Line 473  Returns:       MATCH_MATCH if matched
473  */  */
474    
475  static int  static int
476  match(REGISTER USPTR eptr, REGISTER const uschar *ecode, USPTR mstart,  match(REGISTER PCRE_PUCHAR eptr, REGISTER const pcre_uchar *ecode,
477    int offset_top, match_data *md, eptrblock *eptrb, unsigned int rdepth)    PCRE_PUCHAR mstart, int offset_top, match_data *md, eptrblock *eptrb,
478      unsigned int rdepth)
479  {  {
480  /* 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,
481  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 484  so they can be ordinary variables in all
484  register int  rrc;         /* Returns from recursive calls */  register int  rrc;         /* Returns from recursive calls */
485  register int  i;           /* Used for loops not involving calls to RMATCH() */  register int  i;           /* Used for loops not involving calls to RMATCH() */
486  register unsigned int c;   /* Character values not kept over RMATCH() calls */  register unsigned int c;   /* Character values not kept over RMATCH() calls */
487  register BOOL utf8;        /* Local copy of UTF-8 flag for speed */  register BOOL utf;         /* Local copy of UTF flag for speed */
488    
489  BOOL minimize, possessive; /* Quantifier options */  BOOL minimize, possessive; /* Quantifier options */
490  BOOL caseless;  BOOL caseless;
491  int condcode;  int condcode;
492    
493  /* When recursion is not being used, all "local" variables that have to be  /* When recursion is not being used, all "local" variables that have to be
494  preserved over calls to RMATCH() are part of a "frame" which is obtained from  preserved over calls to RMATCH() are part of a "frame". We set up the top-level
495  heap storage. Set up the top-level frame here; others are obtained from the  frame on the stack here; subsequent instantiations are obtained from the heap
496  heap whenever RMATCH() does a "recursion". See the macro definitions above. */  whenever RMATCH() does a "recursion". See the macro definitions above. Putting
497    the top-level on the stack rather than malloc-ing them all gives a performance
498    boost in many cases where there is not much "recursion". */
499    
500  #ifdef NO_RECURSE  #ifdef NO_RECURSE
501  heapframe *frame = (heapframe *)(pcre_stack_malloc)(sizeof(heapframe));  heapframe frame_zero;
502  if (frame == NULL) RRETURN(PCRE_ERROR_NOMEMORY);  heapframe *frame = &frame_zero;
503  frame->Xprevframe = NULL;            /* Marks the top level */  frame->Xprevframe = NULL;            /* Marks the top level */
504    
505  /* Copy in the original argument variables */  /* Copy in the original argument variables */
# Line 513  HEAP_RECURSE: Line 526  HEAP_RECURSE:
526    
527  /* Ditto for the local variables */  /* Ditto for the local variables */
528    
529  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
530  #define charptr            frame->Xcharptr  #define charptr            frame->Xcharptr
531  #endif  #endif
532  #define callpat            frame->Xcallpat  #define callpat            frame->Xcallpat
# Line 571  declarations can be cut out in a block. Line 584  declarations can be cut out in a block.
584  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
585  to RMATCH(). */  to RMATCH(). */
586    
587  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
588  const uschar *charptr;  const pcre_uchar *charptr;
589  #endif  #endif
590  const uschar *callpat;  const pcre_uchar *callpat;
591  const uschar *data;  const pcre_uchar *data;
592  const uschar *next;  const pcre_uchar *next;
593  USPTR         pp;  PCRE_PUCHAR       pp;
594  const uschar *prev;  const pcre_uchar *prev;
595  USPTR         saved_eptr;  PCRE_PUCHAR       saved_eptr;
596    
597  recursion_info new_recursive;  recursion_info new_recursive;
598    
# Line 592  int prop_type; Line 605  int prop_type;
605  int prop_value;  int prop_value;
606  int prop_fail_result;  int prop_fail_result;
607  int oclength;  int oclength;
608  uschar occhars[8];  pcre_uchar occhars[6];
609  #endif  #endif
610    
611  int codelink;  int codelink;
# Line 608  int save_offset1, save_offset2, save_off Line 621  int save_offset1, save_offset2, save_off
621  int stacksave[REC_STACK_SAVE_MAX];  int stacksave[REC_STACK_SAVE_MAX];
622    
623  eptrblock newptrb;  eptrblock newptrb;
624    
625    /* There is a special fudge for calling match() in a way that causes it to
626    measure the size of its basic stack frame when the stack is being used for
627    recursion. The second argument (ecode) being NULL triggers this behaviour. It
628    cannot normally ever be NULL. The return is the negated value of the frame
629    size. */
630    
631    if (ecode == NULL)
632      {
633      if (rdepth == 0)
634        return match((PCRE_PUCHAR)&rdepth, NULL, NULL, 0, NULL, NULL, 1);
635      else
636        {
637        int len = (char *)&rdepth - (char *)eptr;
638        return (len > 0)? -len : len;
639        }
640      }
641  #endif     /* NO_RECURSE */  #endif     /* NO_RECURSE */
642    
643  /* To save space on the stack and in the heap frame, I have doubled up on some  /* To save space on the stack and in the heap frame, I have doubled up on some
# Line 620  the alternative names that are used. */ Line 650  the alternative names that are used. */
650  #define code_offset   codelink  #define code_offset   codelink
651  #define condassert    condition  #define condassert    condition
652  #define matched_once  prev_is_word  #define matched_once  prev_is_word
653    #define foc           number
654    #define save_mark     data
655    
656  /* These statements are here to stop the compiler complaining about unitialized  /* These statements are here to stop the compiler complaining about unitialized
657  variables. */  variables. */
# Line 645  defined). However, RMATCH isn't like a f Line 677  defined). However, RMATCH isn't like a f
677  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,
678  however, impact performance when true recursion is being used. */  however, impact performance when true recursion is being used. */
679    
680  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
681  utf8 = md->utf8;       /* Local copy of the flag */  utf = md->utf;       /* Local copy of the flag */
682  #else  #else
683  utf8 = FALSE;  utf = FALSE;
684  #endif  #endif
685    
686  /* 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 721  for (;;)
721      case OP_MARK:      case OP_MARK:
722      md->nomatch_mark = ecode + 2;      md->nomatch_mark = ecode + 2;
723      md->mark = NULL;    /* In case previously set by assertion */      md->mark = NULL;    /* In case previously set by assertion */
724      RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode] + ecode[1], offset_top, md,      RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode] + ecode[1], offset_top, md,
725        eptrb, RM55);        eptrb, RM55);
726      if ((rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) &&      if ((rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) &&
727           md->mark == NULL) md->mark = ecode + 2;           md->mark == NULL) md->mark = ecode + 2;
# Line 702  for (;;) Line 734  for (;;)
734      unaltered. */      unaltered. */
735    
736      else if (rrc == MATCH_SKIP_ARG &&      else if (rrc == MATCH_SKIP_ARG &&
737          strcmp((char *)(ecode + 2), (char *)(md->start_match_ptr)) == 0)          STRCMP_UC_UC(ecode + 2, md->start_match_ptr) == 0)
738        {        {
739        md->start_match_ptr = eptr;        md->start_match_ptr = eptr;
740        RRETURN(MATCH_SKIP);        RRETURN(MATCH_SKIP);
# Line 715  for (;;) Line 747  for (;;)
747      /* COMMIT overrides PRUNE, SKIP, and THEN */      /* COMMIT overrides PRUNE, SKIP, and THEN */
748    
749      case OP_COMMIT:      case OP_COMMIT:
750      RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,      RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md,
751        eptrb, RM52);        eptrb, RM52);
752      if (rrc != MATCH_NOMATCH && rrc != MATCH_PRUNE &&      if (rrc != MATCH_NOMATCH && rrc != MATCH_PRUNE &&
753          rrc != MATCH_SKIP && rrc != MATCH_SKIP_ARG &&          rrc != MATCH_SKIP && rrc != MATCH_SKIP_ARG &&
# Line 726  for (;;) Line 758  for (;;)
758      /* PRUNE overrides THEN */      /* PRUNE overrides THEN */
759    
760      case OP_PRUNE:      case OP_PRUNE:
761      RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,      RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md,
762        eptrb, RM51);        eptrb, RM51);
763      if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);      if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);
764      RRETURN(MATCH_PRUNE);      RRETURN(MATCH_PRUNE);
# Line 734  for (;;) Line 766  for (;;)
766      case OP_PRUNE_ARG:      case OP_PRUNE_ARG:
767      md->nomatch_mark = ecode + 2;      md->nomatch_mark = ecode + 2;
768      md->mark = NULL;    /* In case previously set by assertion */      md->mark = NULL;    /* In case previously set by assertion */
769      RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode] + ecode[1], offset_top, md,      RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode] + ecode[1], offset_top, md,
770        eptrb, RM56);        eptrb, RM56);
771      if ((rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) &&      if ((rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) &&
772           md->mark == NULL) md->mark = ecode + 2;           md->mark == NULL) md->mark = ecode + 2;
# Line 744  for (;;) Line 776  for (;;)
776      /* SKIP overrides PRUNE and THEN */      /* SKIP overrides PRUNE and THEN */
777    
778      case OP_SKIP:      case OP_SKIP:
779      RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,      RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md,
780        eptrb, RM53);        eptrb, RM53);
781      if (rrc != MATCH_NOMATCH && rrc != MATCH_PRUNE && rrc != MATCH_THEN)      if (rrc != MATCH_NOMATCH && rrc != MATCH_PRUNE && rrc != MATCH_THEN)
782        RRETURN(rrc);        RRETURN(rrc);
# Line 752  for (;;) Line 784  for (;;)
784      RRETURN(MATCH_SKIP);      RRETURN(MATCH_SKIP);
785    
786      /* Note that, for Perl compatibility, SKIP with an argument does NOT set      /* Note that, for Perl compatibility, SKIP with an argument does NOT set
787      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
788      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. */
789    
790      case OP_SKIP_ARG:      case OP_SKIP_ARG:
791      if (md->ignore_skip_arg)      if (md->ignore_skip_arg)
792        {        {
793        ecode += _pcre_OP_lengths[*ecode] + ecode[1];        ecode += PRIV(OP_lengths)[*ecode] + ecode[1];
794        break;        break;
795        }        }
796      RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode] + ecode[1], offset_top, md,      RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode] + ecode[1], offset_top, md,
797        eptrb, RM57);        eptrb, RM57);
798      if (rrc != MATCH_NOMATCH && rrc != MATCH_PRUNE && rrc != MATCH_THEN)      if (rrc != MATCH_NOMATCH && rrc != MATCH_PRUNE && rrc != MATCH_THEN)
799        RRETURN(rrc);        RRETURN(rrc);
800    
801      /* 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
802      returning the special MATCH_SKIP_ARG return code. This will either be      returning the special MATCH_SKIP_ARG return code. This will either be
803      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
804      with the md->ignore_skip_arg flag set. */      with the md->ignore_skip_arg flag set. */
805    
806      md->start_match_ptr = ecode + 2;      md->start_match_ptr = ecode + 2;
# Line 779  for (;;) Line 811  for (;;)
811      match pointer to do this. */      match pointer to do this. */
812    
813      case OP_THEN:      case OP_THEN:
814      RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,      RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md,
815        eptrb, RM54);        eptrb, RM54);
816      if (rrc != MATCH_NOMATCH) RRETURN(rrc);      if (rrc != MATCH_NOMATCH) RRETURN(rrc);
817      md->start_match_ptr = ecode;      md->start_match_ptr = ecode;
# Line 788  for (;;) Line 820  for (;;)
820      case OP_THEN_ARG:      case OP_THEN_ARG:
821      md->nomatch_mark = ecode + 2;      md->nomatch_mark = ecode + 2;
822      md->mark = NULL;    /* In case previously set by assertion */      md->mark = NULL;    /* In case previously set by assertion */
823      RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode] + ecode[1], offset_top,      RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode] + ecode[1], offset_top,
824        md, eptrb, RM58);        md, eptrb, RM58);
825      if ((rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) &&      if ((rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) &&
826           md->mark == NULL) md->mark = ecode + 2;           md->mark == NULL) md->mark = ecode + 2;
# Line 812  for (;;) Line 844  for (;;)
844      case OP_ONCE_NC:      case OP_ONCE_NC:
845      prev = ecode;      prev = ecode;
846      saved_eptr = eptr;      saved_eptr = eptr;
847        save_mark = md->mark;
848      do      do
849        {        {
850        RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, eptrb, RM64);        RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, eptrb, RM64);
# Line 830  for (;;) Line 863  for (;;)
863    
864        if (rrc != MATCH_NOMATCH) RRETURN(rrc);        if (rrc != MATCH_NOMATCH) RRETURN(rrc);
865        ecode += GET(ecode,1);        ecode += GET(ecode,1);
866          md->mark = save_mark;
867        }        }
868      while (*ecode == OP_ALT);      while (*ecode == OP_ALT);
869    
# Line 909  for (;;) Line 943  for (;;)
943        save_offset2 = md->offset_vector[offset+1];        save_offset2 = md->offset_vector[offset+1];
944        save_offset3 = md->offset_vector[md->offset_end - number];        save_offset3 = md->offset_vector[md->offset_end - number];
945        save_capture_last = md->capture_last;        save_capture_last = md->capture_last;
946          save_mark = md->mark;
947    
948        DPRINTF(("saving %d %d %d\n", save_offset1, save_offset2, save_offset3));        DPRINTF(("saving %d %d %d\n", save_offset1, save_offset2, save_offset3));
949        md->offset_vector[md->offset_end - number] =        md->offset_vector[md->offset_end - number] =
# Line 917  for (;;) Line 952  for (;;)
952        for (;;)        for (;;)
953          {          {
954          if (op >= OP_SBRA) md->match_function_type = MATCH_CBEGROUP;          if (op >= OP_SBRA) md->match_function_type = MATCH_CBEGROUP;
955          RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,          RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md,
956            eptrb, RM1);            eptrb, RM1);
957          if (rrc == MATCH_ONCE) break;  /* Backing up through an atomic group */          if (rrc == MATCH_ONCE) break;  /* Backing up through an atomic group */
958    
# Line 945  for (;;) Line 980  for (;;)
980          if (rrc != MATCH_NOMATCH) RRETURN(rrc);          if (rrc != MATCH_NOMATCH) RRETURN(rrc);
981          md->capture_last = save_capture_last;          md->capture_last = save_capture_last;
982          ecode += GET(ecode, 1);          ecode += GET(ecode, 1);
983            md->mark = save_mark;
984          if (*ecode != OP_ALT) break;          if (*ecode != OP_ALT) break;
985          }          }
986    
# Line 1004  for (;;) Line 1040  for (;;)
1040    
1041        else if (!md->hasthen && ecode[GET(ecode, 1)] != OP_ALT)        else if (!md->hasthen && ecode[GET(ecode, 1)] != OP_ALT)
1042          {          {
1043          ecode += _pcre_OP_lengths[*ecode];          ecode += PRIV(OP_lengths)[*ecode];
1044          goto TAIL_RECURSE;          goto TAIL_RECURSE;
1045          }          }
1046    
1047        /* In all other cases, we have to make another call to match(). */        /* In all other cases, we have to make another call to match(). */
1048    
1049        RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md, eptrb,        save_mark = md->mark;
1050          RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md, eptrb,
1051          RM2);          RM2);
1052    
1053        /* 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 1065  for (;;)
1065          {          {
1066          if (rrc == MATCH_ONCE)          if (rrc == MATCH_ONCE)
1067            {            {
1068            const uschar *scode = ecode;            const pcre_uchar *scode = ecode;
1069            if (*scode != OP_ONCE)           /* If not at start, find it */            if (*scode != OP_ONCE)           /* If not at start, find it */
1070              {              {
1071              while (*scode == OP_ALT) scode += GET(scode, 1);              while (*scode == OP_ALT) scode += GET(scode, 1);
# Line 1039  for (;;) Line 1076  for (;;)
1076          RRETURN(rrc);          RRETURN(rrc);
1077          }          }
1078        ecode += GET(ecode, 1);        ecode += GET(ecode, 1);
1079          md->mark = save_mark;
1080        if (*ecode != OP_ALT) break;        if (*ecode != OP_ALT) break;
1081        }        }
1082    
# Line 1070  for (;;) Line 1108  for (;;)
1108      if (offset < md->offset_max)      if (offset < md->offset_max)
1109        {        {
1110        matched_once = FALSE;        matched_once = FALSE;
1111        code_offset = ecode - md->start_code;        code_offset = (int)(ecode - md->start_code);
1112    
1113        save_offset1 = md->offset_vector[offset];        save_offset1 = md->offset_vector[offset];
1114        save_offset2 = md->offset_vector[offset+1];        save_offset2 = md->offset_vector[offset+1];
# Line 1093  for (;;) Line 1131  for (;;)
1131          md->offset_vector[md->offset_end - number] =          md->offset_vector[md->offset_end - number] =
1132            (int)(eptr - md->start_subject);            (int)(eptr - md->start_subject);
1133          if (op >= OP_SBRA) md->match_function_type = MATCH_CBEGROUP;          if (op >= OP_SBRA) md->match_function_type = MATCH_CBEGROUP;
1134          RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,          RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md,
1135            eptrb, RM63);            eptrb, RM63);
1136          if (rrc == MATCH_KETRPOS)          if (rrc == MATCH_KETRPOS)
1137            {            {
# Line 1160  for (;;) Line 1198  for (;;)
1198    
1199      POSSESSIVE_NON_CAPTURE:      POSSESSIVE_NON_CAPTURE:
1200      matched_once = FALSE;      matched_once = FALSE;
1201      code_offset = ecode - md->start_code;      code_offset = (int)(ecode - md->start_code);
1202    
1203      for (;;)      for (;;)
1204        {        {
1205        if (op >= OP_SBRA) md->match_function_type = MATCH_CBEGROUP;        if (op >= OP_SBRA) md->match_function_type = MATCH_CBEGROUP;
1206        RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,        RMATCH(eptr, ecode + PRIV(OP_lengths)[*ecode], offset_top, md,
1207          eptrb, RM48);          eptrb, RM48);
1208        if (rrc == MATCH_KETRPOS)        if (rrc == MATCH_KETRPOS)
1209          {          {
# Line 1215  for (;;) Line 1253  for (;;)
1253    
1254      if (ecode[LINK_SIZE+1] == OP_CALLOUT)      if (ecode[LINK_SIZE+1] == OP_CALLOUT)
1255        {        {
1256        if (pcre_callout != NULL)        if (PUBL(callout) != NULL)
1257          {          {
1258          pcre_callout_block cb;          PUBL(callout_block) cb;
1259          cb.version          = 2;   /* Version 1 of the callout block */          cb.version          = 2;   /* Version 1 of the callout block */
1260          cb.callout_number   = ecode[LINK_SIZE+2];          cb.callout_number   = ecode[LINK_SIZE+2];
1261          cb.offset_vector    = md->offset_vector;          cb.offset_vector    = md->offset_vector;
1262    #ifdef COMPILE_PCRE8
1263          cb.subject          = (PCRE_SPTR)md->start_subject;          cb.subject          = (PCRE_SPTR)md->start_subject;
1264    #else
1265            cb.subject          = (PCRE_SPTR16)md->start_subject;
1266    #endif
1267          cb.subject_length   = (int)(md->end_subject - md->start_subject);          cb.subject_length   = (int)(md->end_subject - md->start_subject);
1268          cb.start_match      = (int)(mstart - md->start_subject);          cb.start_match      = (int)(mstart - md->start_subject);
1269          cb.current_position = (int)(eptr - md->start_subject);          cb.current_position = (int)(eptr - md->start_subject);
# Line 1231  for (;;) Line 1273  for (;;)
1273          cb.capture_last     = md->capture_last;          cb.capture_last     = md->capture_last;
1274          cb.callout_data     = md->callout_data;          cb.callout_data     = md->callout_data;
1275          cb.mark             = md->nomatch_mark;          cb.mark             = md->nomatch_mark;
1276          if ((rrc = (*pcre_callout)(&cb)) > 0) RRETURN(MATCH_NOMATCH);          if ((rrc = (*PUBL(callout))(&cb)) > 0) RRETURN(MATCH_NOMATCH);
1277          if (rrc < 0) RRETURN(rrc);          if (rrc < 0) RRETURN(rrc);
1278          }          }
1279        ecode += _pcre_OP_lengths[OP_CALLOUT];        ecode += PRIV(OP_lengths)[OP_CALLOUT];
1280        }        }
1281    
1282      condcode = ecode[LINK_SIZE+1];      condcode = ecode[LINK_SIZE+1];
# Line 1260  for (;;) Line 1302  for (;;)
1302    
1303          if (!condition && condcode == OP_NRREF)          if (!condition && condcode == OP_NRREF)
1304            {            {
1305            uschar *slotA = md->name_table;            pcre_uchar *slotA = md->name_table;
1306            for (i = 0; i < md->name_count; i++)            for (i = 0; i < md->name_count; i++)
1307              {              {
1308              if (GET2(slotA, 0) == recno) break;              if (GET2(slotA, 0) == recno) break;
# Line 1273  for (;;) Line 1315  for (;;)
1315    
1316            if (i < md->name_count)            if (i < md->name_count)
1317              {              {
1318              uschar *slotB = slotA;              pcre_uchar *slotB = slotA;
1319              while (slotB > md->name_table)              while (slotB > md->name_table)
1320                {                {
1321                slotB -= md->name_entry_size;                slotB -= md->name_entry_size;
1322                if (strcmp((char *)slotA + 2, (char *)slotB + 2) == 0)                if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
1323                  {                  {
1324                  condition = GET2(slotB, 0) == md->recursive->group_num;                  condition = GET2(slotB, 0) == md->recursive->group_num;
1325                  if (condition) break;                  if (condition) break;
# Line 1293  for (;;) Line 1335  for (;;)
1335                for (i++; i < md->name_count; i++)                for (i++; i < md->name_count; i++)
1336                  {                  {
1337                  slotB += md->name_entry_size;                  slotB += md->name_entry_size;
1338                  if (strcmp((char *)slotA + 2, (char *)slotB + 2) == 0)                  if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
1339                    {                    {
1340                    condition = GET2(slotB, 0) == md->recursive->group_num;                    condition = GET2(slotB, 0) == md->recursive->group_num;
1341                    if (condition) break;                    if (condition) break;
# Line 1306  for (;;) Line 1348  for (;;)
1348    
1349          /* Chose branch according to the condition */          /* Chose branch according to the condition */
1350    
1351          ecode += condition? 3 : GET(ecode, 1);          ecode += condition? 1 + IMM2_SIZE : GET(ecode, 1);
1352          }          }
1353        }        }
1354    
# Line 1323  for (;;) Line 1365  for (;;)
1365        if (!condition && condcode == OP_NCREF)        if (!condition && condcode == OP_NCREF)
1366          {          {
1367          int refno = offset >> 1;          int refno = offset >> 1;
1368          uschar *slotA = md->name_table;          pcre_uchar *slotA = md->name_table;
1369    
1370          for (i = 0; i < md->name_count; i++)          for (i = 0; i < md->name_count; i++)
1371            {            {
# Line 1337  for (;;) Line 1379  for (;;)
1379    
1380          if (i < md->name_count)          if (i < md->name_count)
1381            {            {
1382            uschar *slotB = slotA;            pcre_uchar *slotB = slotA;
1383            while (slotB > md->name_table)            while (slotB > md->name_table)
1384              {              {
1385              slotB -= md->name_entry_size;              slotB -= md->name_entry_size;
1386              if (strcmp((char *)slotA + 2, (char *)slotB + 2) == 0)              if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
1387                {                {
1388                offset = GET2(slotB, 0) << 1;                offset = GET2(slotB, 0) << 1;
1389                condition = offset < offset_top &&                condition = offset < offset_top &&
# Line 1359  for (;;) Line 1401  for (;;)
1401              for (i++; i < md->name_count; i++)              for (i++; i < md->name_count; i++)
1402                {                {
1403                slotB += md->name_entry_size;                slotB += md->name_entry_size;
1404                if (strcmp((char *)slotA + 2, (char *)slotB + 2) == 0)                if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
1405                  {                  {
1406                  offset = GET2(slotB, 0) << 1;                  offset = GET2(slotB, 0) << 1;
1407                  condition = offset < offset_top &&                  condition = offset < offset_top &&
# Line 1374  for (;;) Line 1416  for (;;)
1416    
1417        /* Chose branch according to the condition */        /* Chose branch according to the condition */
1418    
1419        ecode += condition? 3 : GET(ecode, 1);        ecode += condition? 1 + IMM2_SIZE : GET(ecode, 1);
1420        }        }
1421    
1422      else if (condcode == OP_DEF)     /* DEFINE - always false */      else if (condcode == OP_DEF)     /* DEFINE - always false */
# Line 1466  for (;;) Line 1508  for (;;)
1508        md->offset_vector[offset+1] = (int)(eptr - md->start_subject);        md->offset_vector[offset+1] = (int)(eptr - md->start_subject);
1509        if (offset_top <= offset) offset_top = offset + 2;        if (offset_top <= offset) offset_top = offset + 2;
1510        }        }
1511      ecode += 3;      ecode += 1 + IMM2_SIZE;
1512      break;      break;
1513    
1514    
# Line 1513  for (;;) Line 1555  for (;;)
1555    
1556      case OP_ASSERT:      case OP_ASSERT:
1557      case OP_ASSERTBACK:      case OP_ASSERTBACK:
1558        save_mark = md->mark;
1559      if (md->match_function_type == MATCH_CONDASSERT)      if (md->match_function_type == MATCH_CONDASSERT)
1560        {        {
1561        condassert = TRUE;        condassert = TRUE;
# Line 1534  for (;;) Line 1577  for (;;)
1577    
1578        if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);        if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);
1579        ecode += GET(ecode, 1);        ecode += GET(ecode, 1);
1580          md->mark = save_mark;
1581        }        }
1582      while (*ecode == OP_ALT);      while (*ecode == OP_ALT);
1583    
# Line 1557  for (;;) Line 1601  for (;;)
1601    
1602      case OP_ASSERT_NOT:      case OP_ASSERT_NOT:
1603      case OP_ASSERTBACK_NOT:      case OP_ASSERTBACK_NOT:
1604        save_mark = md->mark;
1605      if (md->match_function_type == MATCH_CONDASSERT)      if (md->match_function_type == MATCH_CONDASSERT)
1606        {        {
1607        condassert = TRUE;        condassert = TRUE;
# Line 1567  for (;;) Line 1612  for (;;)
1612      do      do
1613        {        {
1614        RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, NULL, RM5);        RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, NULL, RM5);
1615          md->mark = save_mark;
1616        if (rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) RRETURN(MATCH_NOMATCH);        if (rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) RRETURN(MATCH_NOMATCH);
1617        if (rrc == MATCH_SKIP || rrc == MATCH_PRUNE || rrc == MATCH_COMMIT)        if (rrc == MATCH_SKIP || rrc == MATCH_PRUNE || rrc == MATCH_COMMIT)
1618          {          {
# Line 1593  for (;;) Line 1639  for (;;)
1639      back a number of characters, not bytes. */      back a number of characters, not bytes. */
1640    
1641      case OP_REVERSE:      case OP_REVERSE:
1642  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1643      if (utf8)      if (utf)
1644        {        {
1645        i = GET(ecode, 1);        i = GET(ecode, 1);
1646        while (i-- > 0)        while (i-- > 0)
# Line 1625  for (;;) Line 1671  for (;;)
1671      function is able to force a failure. */      function is able to force a failure. */
1672    
1673      case OP_CALLOUT:      case OP_CALLOUT:
1674      if (pcre_callout != NULL)      if (PUBL(callout) != NULL)
1675        {        {
1676        pcre_callout_block cb;        PUBL(callout_block) cb;
1677        cb.version          = 2;   /* Version 1 of the callout block */        cb.version          = 2;   /* Version 1 of the callout block */
1678        cb.callout_number   = ecode[1];        cb.callout_number   = ecode[1];
1679        cb.offset_vector    = md->offset_vector;        cb.offset_vector    = md->offset_vector;
1680    #ifdef COMPILE_PCRE8
1681        cb.subject          = (PCRE_SPTR)md->start_subject;        cb.subject          = (PCRE_SPTR)md->start_subject;
1682    #else
1683          cb.subject          = (PCRE_SPTR16)md->start_subject;
1684    #endif
1685        cb.subject_length   = (int)(md->end_subject - md->start_subject);        cb.subject_length   = (int)(md->end_subject - md->start_subject);
1686        cb.start_match      = (int)(mstart - md->start_subject);        cb.start_match      = (int)(mstart - md->start_subject);
1687        cb.current_position = (int)(eptr - md->start_subject);        cb.current_position = (int)(eptr - md->start_subject);
# Line 1641  for (;;) Line 1691  for (;;)
1691        cb.capture_last     = md->capture_last;        cb.capture_last     = md->capture_last;
1692        cb.callout_data     = md->callout_data;        cb.callout_data     = md->callout_data;
1693        cb.mark             = md->nomatch_mark;        cb.mark             = md->nomatch_mark;
1694        if ((rrc = (*pcre_callout)(&cb)) > 0) RRETURN(MATCH_NOMATCH);        if ((rrc = (*PUBL(callout))(&cb)) > 0) RRETURN(MATCH_NOMATCH);
1695        if (rrc < 0) RRETURN(rrc);        if (rrc < 0) RRETURN(rrc);
1696        }        }
1697      ecode += 2 + 2*LINK_SIZE;      ecode += 2 + 2*LINK_SIZE;
# Line 1700  for (;;) Line 1750  for (;;)
1750        else        else
1751          {          {
1752          new_recursive.offset_save =          new_recursive.offset_save =
1753            (int *)(pcre_malloc)(new_recursive.saved_max * sizeof(int));            (int *)(PUBL(malloc))(new_recursive.saved_max * sizeof(int));
1754          if (new_recursive.offset_save == NULL) RRETURN(PCRE_ERROR_NOMEMORY);          if (new_recursive.offset_save == NULL) RRETURN(PCRE_ERROR_NOMEMORY);
1755          }          }
1756        memcpy(new_recursive.offset_save, md->offset_vector,        memcpy(new_recursive.offset_save, md->offset_vector,
# Line 1715  for (;;) Line 1765  for (;;)
1765        do        do
1766          {          {
1767          if (cbegroup) md->match_function_type = MATCH_CBEGROUP;          if (cbegroup) md->match_function_type = MATCH_CBEGROUP;
1768          RMATCH(eptr, callpat + _pcre_OP_lengths[*callpat], offset_top,          RMATCH(eptr, callpat + PRIV(OP_lengths)[*callpat], offset_top,
1769            md, eptrb, RM6);            md, eptrb, RM6);
1770          memcpy(md->offset_vector, new_recursive.offset_save,          memcpy(md->offset_vector, new_recursive.offset_save,
1771              new_recursive.saved_max * sizeof(int));              new_recursive.saved_max * sizeof(int));
# Line 1724  for (;;) Line 1774  for (;;)
1774            {            {
1775            DPRINTF(("Recursion matched\n"));            DPRINTF(("Recursion matched\n"));
1776            if (new_recursive.offset_save != stacksave)            if (new_recursive.offset_save != stacksave)
1777              (pcre_free)(new_recursive.offset_save);              (PUBL(free))(new_recursive.offset_save);
1778    
1779            /* 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
1780            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 1792  for (;;)
1792            {            {
1793            DPRINTF(("Recursion gave error %d\n", rrc));            DPRINTF(("Recursion gave error %d\n", rrc));
1794            if (new_recursive.offset_save != stacksave)            if (new_recursive.offset_save != stacksave)
1795              (pcre_free)(new_recursive.offset_save);              (PUBL(free))(new_recursive.offset_save);
1796            RRETURN(rrc);            RRETURN(rrc);
1797            }            }
1798    
# Line 1754  for (;;) Line 1804  for (;;)
1804        DPRINTF(("Recursion didn't match\n"));        DPRINTF(("Recursion didn't match\n"));
1805        md->recursive = new_recursive.prevrec;        md->recursive = new_recursive.prevrec;
1806        if (new_recursive.offset_save != stacksave)        if (new_recursive.offset_save != stacksave)
1807          (pcre_free)(new_recursive.offset_save);          (PUBL(free))(new_recursive.offset_save);
1808        RRETURN(MATCH_NOMATCH);        RRETURN(MATCH_NOMATCH);
1809        }        }
1810    
# Line 2015  for (;;) Line 2065  for (;;)
2065    
2066      case OP_DOLLM:      case OP_DOLLM:
2067      if (eptr < md->end_subject)      if (eptr < md->end_subject)
2068        { if (!IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH); }        {
2069          if (!IS_NEWLINE(eptr))
2070            {
2071            if (md->partial != 0 &&
2072                eptr + 1 >= md->end_subject &&
2073                NLBLOCK->nltype == NLTYPE_FIXED &&
2074                NLBLOCK->nllen == 2 &&
2075                *eptr == NLBLOCK->nl[0])
2076              {
2077              md->hitend = TRUE;
2078              if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
2079              }
2080            RRETURN(MATCH_NOMATCH);
2081            }
2082          }
2083      else      else
2084        {        {
2085        if (md->noteol) RRETURN(MATCH_NOMATCH);        if (md->noteol) RRETURN(MATCH_NOMATCH);
# Line 2047  for (;;) Line 2111  for (;;)
2111      ASSERT_NL_OR_EOS:      ASSERT_NL_OR_EOS:
2112      if (eptr < md->end_subject &&      if (eptr < md->end_subject &&
2113          (!IS_NEWLINE(eptr) || eptr != md->end_subject - md->nllen))          (!IS_NEWLINE(eptr) || eptr != md->end_subject - md->nllen))
2114          {
2115          if (md->partial != 0 &&
2116              eptr + 1 >= md->end_subject &&
2117              NLBLOCK->nltype == NLTYPE_FIXED &&
2118              NLBLOCK->nllen == 2 &&
2119              *eptr == NLBLOCK->nl[0])
2120            {
2121            md->hitend = TRUE;
2122            if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
2123            }
2124        RRETURN(MATCH_NOMATCH);        RRETURN(MATCH_NOMATCH);
2125          }
2126    
2127      /* Either at end of string or \n before end. */      /* Either at end of string or \n before end. */
2128    
# Line 2066  for (;;) Line 2141  for (;;)
2141        be "non-word" characters. Remember the earliest consulted character for        be "non-word" characters. Remember the earliest consulted character for
2142        partial matching. */        partial matching. */
2143    
2144  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2145        if (utf8)        if (utf)
2146          {          {
2147          /* Get status of previous character */          /* Get status of previous character */
2148    
2149          if (eptr == md->start_subject) prev_is_word = FALSE; else          if (eptr == md->start_subject) prev_is_word = FALSE; else
2150            {            {
2151            USPTR lastptr = eptr - 1;            PCRE_PUCHAR lastptr = eptr - 1;
2152            while((*lastptr & 0xc0) == 0x80) lastptr--;            BACKCHAR(lastptr);
2153            if (lastptr < md->start_used_ptr) md->start_used_ptr = lastptr;            if (lastptr < md->start_used_ptr) md->start_used_ptr = lastptr;
2154            GETCHAR(c, lastptr);            GETCHAR(c, lastptr);
2155  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
# Line 2139  for (;;) Line 2214  for (;;)
2214              }              }
2215            else            else
2216  #endif  #endif
2217            prev_is_word = ((md->ctypes[eptr[-1]] & ctype_word) != 0);            prev_is_word = MAX_255(eptr[-1])
2218                && ((md->ctypes[eptr[-1]] & ctype_word) != 0);
2219            }            }
2220    
2221          /* Get status of next character */          /* Get status of next character */
# Line 2162  for (;;) Line 2238  for (;;)
2238            }            }
2239          else          else
2240  #endif  #endif
2241          cur_is_word = ((md->ctypes[*eptr] & ctype_word) != 0);          cur_is_word = MAX_255(*eptr)
2242              && ((md->ctypes[*eptr] & ctype_word) != 0);
2243          }          }
2244    
2245        /* Now see if the situation is what we want */        /* Now see if the situation is what we want */
# Line 2173  for (;;) Line 2250  for (;;)
2250        }        }
2251      break;      break;
2252    
2253      /* Match a single character type; inline for speed */      /* Match any single character type except newline; have to take care with
2254        CRLF newlines and partial matching. */
2255    
2256      case OP_ANY:      case OP_ANY:
2257      if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH);      if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH);
2258        if (md->partial != 0 &&
2259            eptr + 1 >= md->end_subject &&
2260            NLBLOCK->nltype == NLTYPE_FIXED &&
2261            NLBLOCK->nllen == 2 &&
2262            *eptr == NLBLOCK->nl[0])
2263          {
2264          md->hitend = TRUE;
2265          if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
2266          }
2267    
2268      /* Fall through */      /* Fall through */
2269    
2270        /* Match any single character whatsoever. */
2271    
2272      case OP_ALLANY:      case OP_ALLANY:
2273      if (eptr >= md->end_subject)   /* DO NOT merge the eptr++ here; it must */      if (eptr >= md->end_subject)   /* DO NOT merge the eptr++ here; it must */
2274        {                            /* not be updated before SCHECK_PARTIAL. */        {                            /* not be updated before SCHECK_PARTIAL. */
# Line 2186  for (;;) Line 2276  for (;;)
2276        RRETURN(MATCH_NOMATCH);        RRETURN(MATCH_NOMATCH);
2277        }        }
2278      eptr++;      eptr++;
2279      if (utf8) while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;  #ifdef SUPPORT_UTF
2280        if (utf) ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
2281    #endif
2282      ecode++;      ecode++;
2283      break;      break;
2284    
# Line 2211  for (;;) Line 2303  for (;;)
2303        }        }
2304      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
2305      if (      if (
2306  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || !(defined COMPILE_PCRE8)
2307         c < 256 &&         c < 256 &&
2308  #endif  #endif
2309         (md->ctypes[c] & ctype_digit) != 0         (md->ctypes[c] & ctype_digit) != 0
# Line 2228  for (;;) Line 2320  for (;;)
2320        }        }
2321      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
2322      if (      if (
2323  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || !(defined COMPILE_PCRE8)
2324         c >= 256 ||         c > 255 ||
2325  #endif  #endif
2326         (md->ctypes[c] & ctype_digit) == 0         (md->ctypes[c] & ctype_digit) == 0
2327         )         )
# Line 2245  for (;;) Line 2337  for (;;)
2337        }        }
2338      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
2339      if (      if (
2340  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || !(defined COMPILE_PCRE8)
2341         c < 256 &&         c < 256 &&
2342  #endif  #endif
2343         (md->ctypes[c] & ctype_space) != 0         (md->ctypes[c] & ctype_space) != 0
# Line 2262  for (;;) Line 2354  for (;;)
2354        }        }
2355      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
2356      if (      if (
2357  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || !(defined COMPILE_PCRE8)
2358         c >= 256 ||         c > 255 ||
2359  #endif  #endif
2360         (md->ctypes[c] & ctype_space) == 0         (md->ctypes[c] & ctype_space) == 0
2361         )         )
# Line 2279  for (;;) Line 2371  for (;;)
2371        }        }
2372      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
2373      if (      if (
2374  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || !(defined COMPILE_PCRE8)
2375         c < 256 &&         c < 256 &&
2376  #endif  #endif
2377         (md->ctypes[c] & ctype_word) != 0         (md->ctypes[c] & ctype_word) != 0
# Line 2296  for (;;) Line 2388  for (;;)
2388        }        }
2389      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
2390      if (      if (
2391  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || !(defined COMPILE_PCRE8)
2392         c >= 256 ||         c > 255 ||
2393  #endif  #endif
2394         (md->ctypes[c] & ctype_word) == 0         (md->ctypes[c] & ctype_word) == 0
2395         )         )
# Line 2317  for (;;) Line 2409  for (;;)
2409        default: RRETURN(MATCH_NOMATCH);        default: RRETURN(MATCH_NOMATCH);
2410    
2411        case 0x000d:        case 0x000d:
2412        if (eptr < md->end_subject && *eptr == 0x0a) eptr++;        if (eptr >= md->end_subject)
2413            {
2414            SCHECK_PARTIAL();
2415            }
2416          else if (*eptr == 0x0a) eptr++;
2417        break;        break;
2418    
2419        case 0x000a:        case 0x000a:
# Line 2475  for (;;) Line 2571  for (;;)
2571          break;          break;
2572    
2573          case PT_GC:          case PT_GC:
2574          if ((ecode[2] != _pcre_ucp_gentype[prop->chartype]) == (op == OP_PROP))          if ((ecode[2] != PRIV(ucp_gentype)[prop->chartype]) == (op == OP_PROP))
2575            RRETURN(MATCH_NOMATCH);            RRETURN(MATCH_NOMATCH);
2576          break;          break;
2577    
# Line 2492  for (;;) Line 2588  for (;;)
2588          /* These are specials */          /* These are specials */
2589    
2590          case PT_ALNUM:          case PT_ALNUM:
2591          if ((_pcre_ucp_gentype[prop->chartype] == ucp_L ||          if ((PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
2592               _pcre_ucp_gentype[prop->chartype] == ucp_N) == (op == OP_NOTPROP))               PRIV(ucp_gentype)[prop->chartype] == ucp_N) == (op == OP_NOTPROP))
2593            RRETURN(MATCH_NOMATCH);            RRETURN(MATCH_NOMATCH);
2594          break;          break;
2595    
2596          case PT_SPACE:    /* Perl space */          case PT_SPACE:    /* Perl space */
2597          if ((_pcre_ucp_gentype[prop->chartype] == ucp_Z ||          if ((PRIV(ucp_gentype)[prop->chartype] == ucp_Z ||
2598               c == CHAR_HT || c == CHAR_NL || c == CHAR_FF || c == CHAR_CR)               c == CHAR_HT || c == CHAR_NL || c == CHAR_FF || c == CHAR_CR)
2599                 == (op == OP_NOTPROP))                 == (op == OP_NOTPROP))
2600            RRETURN(MATCH_NOMATCH);            RRETURN(MATCH_NOMATCH);
2601          break;          break;
2602    
2603          case PT_PXSPACE:  /* POSIX space */          case PT_PXSPACE:  /* POSIX space */
2604          if ((_pcre_ucp_gentype[prop->chartype] == ucp_Z ||          if ((PRIV(ucp_gentype)[prop->chartype] == ucp_Z ||
2605               c == CHAR_HT || c == CHAR_NL || c == CHAR_VT ||               c == CHAR_HT || c == CHAR_NL || c == CHAR_VT ||
2606               c == CHAR_FF || c == CHAR_CR)               c == CHAR_FF || c == CHAR_CR)
2607                 == (op == OP_NOTPROP))                 == (op == OP_NOTPROP))
# Line 2513  for (;;) Line 2609  for (;;)
2609          break;          break;
2610    
2611          case PT_WORD:          case PT_WORD:
2612          if ((_pcre_ucp_gentype[prop->chartype] == ucp_L ||          if ((PRIV(ucp_gentype)[prop->chartype] == ucp_L ||
2613               _pcre_ucp_gentype[prop->chartype] == ucp_N ||               PRIV(ucp_gentype)[prop->chartype] == ucp_N ||
2614               c == CHAR_UNDERSCORE) == (op == OP_NOTPROP))               c == CHAR_UNDERSCORE) == (op == OP_NOTPROP))
2615            RRETURN(MATCH_NOMATCH);            RRETURN(MATCH_NOMATCH);
2616          break;          break;
# Line 2543  for (;;) Line 2639  for (;;)
2639      while (eptr < md->end_subject)      while (eptr < md->end_subject)
2640        {        {
2641        int len = 1;        int len = 1;
2642        if (!utf8) c = *eptr; else { GETCHARLEN(c, eptr, len); }        if (!utf) c = *eptr; else { GETCHARLEN(c, eptr, len); }
2643        if (UCD_CATEGORY(c) != ucp_M) break;        if (UCD_CATEGORY(c) != ucp_M) break;
2644        eptr += len;        eptr += len;
2645        }        }
2646        CHECK_PARTIAL();
2647      ecode++;      ecode++;
2648      break;      break;
2649  #endif  #endif
# Line 2564  for (;;) Line 2661  for (;;)
2661      case OP_REFI:      case OP_REFI:
2662      caseless = op == OP_REFI;      caseless = op == OP_REFI;
2663      offset = GET2(ecode, 1) << 1;               /* Doubled ref number */      offset = GET2(ecode, 1) << 1;               /* Doubled ref number */
2664      ecode += 3;      ecode += 1 + IMM2_SIZE;
2665    
2666      /* If the reference is unset, there are two possibilities:      /* If the reference is unset, there are two possibilities:
2667    
# Line 2604  for (;;) Line 2701  for (;;)
2701        case OP_CRMINRANGE:        case OP_CRMINRANGE:
2702        minimize = (*ecode == OP_CRMINRANGE);        minimize = (*ecode == OP_CRMINRANGE);
2703        min = GET2(ecode, 1);        min = GET2(ecode, 1);
2704        max = GET2(ecode, 3);        max = GET2(ecode, 1 + IMM2_SIZE);
2705        if (max == 0) max = INT_MAX;        if (max == 0) max = INT_MAX;
2706        ecode += 5;        ecode += 1 + 2 * IMM2_SIZE;
2707        break;        break;
2708    
2709        default:               /* No repeat follows */        default:               /* No repeat follows */
2710        if ((length = match_ref(offset, eptr, length, md, caseless)) < 0)        if ((length = match_ref(offset, eptr, length, md, caseless)) < 0)
2711          {          {
2712            if (length == -2) eptr = md->end_subject;   /* Partial match */
2713          CHECK_PARTIAL();          CHECK_PARTIAL();
2714          RRETURN(MATCH_NOMATCH);          RRETURN(MATCH_NOMATCH);
2715          }          }
# Line 2620  for (;;) Line 2718  for (;;)
2718        }        }
2719    
2720      /* Handle repeated back references. If the length of the reference is      /* Handle repeated back references. If the length of the reference is
2721      zero, just continue with the main loop. */      zero, just continue with the main loop. If the length is negative, it
2722        means the reference is unset in non-Java-compatible mode. If the minimum is
2723        zero, we can continue at the same level without recursion. For any other
2724        minimum, carrying on will result in NOMATCH. */
2725    
2726      if (length == 0) continue;      if (length == 0) continue;
2727        if (length < 0 && min == 0) continue;
2728    
2729      /* First, ensure the minimum number of matches are present. We get back      /* First, ensure the minimum number of matches are present. We get back
2730      the length of the reference string explicitly rather than passing the      the length of the reference string explicitly rather than passing the
# Line 2633  for (;;) Line 2735  for (;;)
2735        int slength;        int slength;
2736        if ((slength = match_ref(offset, eptr, length, md, caseless)) < 0)        if ((slength = match_ref(offset, eptr, length, md, caseless)) < 0)
2737          {          {
2738            if (slength == -2) eptr = md->end_subject;   /* Partial match */
2739          CHECK_PARTIAL();          CHECK_PARTIAL();
2740          RRETURN(MATCH_NOMATCH);          RRETURN(MATCH_NOMATCH);
2741          }          }
# Line 2656  for (;;) Line 2759  for (;;)
2759          if (fi >= max) RRETURN(MATCH_NOMATCH);          if (fi >= max) RRETURN(MATCH_NOMATCH);
2760          if ((slength = match_ref(offset, eptr, length, md, caseless)) < 0)          if ((slength = match_ref(offset, eptr, length, md, caseless)) < 0)
2761            {            {
2762              if (slength == -2) eptr = md->end_subject;   /* Partial match */
2763            CHECK_PARTIAL();            CHECK_PARTIAL();
2764            RRETURN(MATCH_NOMATCH);            RRETURN(MATCH_NOMATCH);
2765            }            }
# Line 2674  for (;;) Line 2778  for (;;)
2778          int slength;          int slength;
2779          if ((slength = match_ref(offset, eptr, length, md, caseless)) < 0)          if ((slength = match_ref(offset, eptr, length, md, caseless)) < 0)
2780            {            {
2781            CHECK_PARTIAL();            /* Can't use CHECK_PARTIAL because we don't want to update eptr in
2782              the soft partial matching case. */
2783    
2784              if (slength == -2 && md->partial != 0 &&
2785                  md->end_subject > md->start_used_ptr)
2786                {
2787                md->hitend = TRUE;
2788                if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
2789                }
2790            break;            break;
2791            }            }
2792          eptr += slength;          eptr += slength;
2793          }          }
2794    
2795        while (eptr >= pp)        while (eptr >= pp)
2796          {          {
2797          RMATCH(eptr, ecode, offset_top, md, eptrb, RM15);          RMATCH(eptr, ecode, offset_top, md, eptrb, RM15);
# Line 2703  for (;;) Line 2816  for (;;)
2816      case OP_NCLASS:      case OP_NCLASS:
2817      case OP_CLASS:      case OP_CLASS:
2818        {        {
2819          /* The data variable is saved across frames, so the byte map needs to
2820          be stored there. */
2821    #define BYTE_MAP ((pcre_uint8 *)data)
2822        data = ecode + 1;                /* Save for matching */        data = ecode + 1;                /* Save for matching */
2823        ecode += 33;                     /* Advance past the item */        ecode += 1 + (32 / sizeof(pcre_uchar)); /* Advance past the item */
2824    
2825        switch (*ecode)        switch (*ecode)
2826          {          {
# Line 2725  for (;;) Line 2841  for (;;)
2841          case OP_CRMINRANGE:          case OP_CRMINRANGE:
2842          minimize = (*ecode == OP_CRMINRANGE);          minimize = (*ecode == OP_CRMINRANGE);
2843          min = GET2(ecode, 1);          min = GET2(ecode, 1);
2844          max = GET2(ecode, 3);          max = GET2(ecode, 1 + IMM2_SIZE);
2845          if (max == 0) max = INT_MAX;          if (max == 0) max = INT_MAX;
2846          ecode += 5;          ecode += 1 + 2 * IMM2_SIZE;
2847          break;          break;
2848    
2849          default:               /* No repeat follows */          default:               /* No repeat follows */
# Line 2737  for (;;) Line 2853  for (;;)
2853    
2854        /* First, ensure the minimum number of matches are present. */        /* First, ensure the minimum number of matches are present. */
2855    
2856  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2857        /* UTF-8 mode */        if (utf)
       if (utf8)  
2858          {          {
2859          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
2860            {            {
# Line 2754  for (;;) Line 2869  for (;;)
2869              if (op == OP_CLASS) RRETURN(MATCH_NOMATCH);              if (op == OP_CLASS) RRETURN(MATCH_NOMATCH);
2870              }              }
2871            else            else
2872              {              if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);
             if ((data[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);  
             }  
2873            }            }
2874          }          }
2875        else        else
2876  #endif  #endif
2877        /* Not UTF-8 mode */        /* Not UTF mode */
2878          {          {
2879          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
2880            {            {
# Line 2771  for (;;) Line 2884  for (;;)
2884              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
2885              }              }
2886            c = *eptr++;            c = *eptr++;
2887            if ((data[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);  #ifndef COMPILE_PCRE8
2888              if (c > 255)
2889                {
2890                if (op == OP_CLASS) RRETURN(MATCH_NOMATCH);
2891                }
2892              else
2893    #endif
2894                if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);
2895            }            }
2896          }          }
2897    
# Line 2785  for (;;) Line 2905  for (;;)
2905    
2906        if (minimize)        if (minimize)
2907          {          {
2908  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2909          /* UTF-8 mode */          if (utf)
         if (utf8)  
2910            {            {
2911            for (fi = min;; fi++)            for (fi = min;; fi++)
2912              {              {
# Line 2805  for (;;) Line 2924  for (;;)
2924                if (op == OP_CLASS) RRETURN(MATCH_NOMATCH);                if (op == OP_CLASS) RRETURN(MATCH_NOMATCH);
2925                }                }
2926              else              else
2927                {                if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);
               if ((data[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);  
               }  
2928              }              }
2929            }            }
2930          else          else
2931  #endif  #endif
2932          /* Not UTF-8 mode */          /* Not UTF mode */
2933            {            {
2934            for (fi = min;; fi++)            for (fi = min;; fi++)
2935              {              {
# Line 2825  for (;;) Line 2942  for (;;)
2942                RRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
2943                }                }
2944              c = *eptr++;              c = *eptr++;
2945              if ((data[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);  #ifndef COMPILE_PCRE8
2946                if (c > 255)
2947                  {
2948                  if (op == OP_CLASS) RRETURN(MATCH_NOMATCH);
2949                  }
2950                else
2951    #endif
2952                  if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);
2953              }              }
2954            }            }
2955          /* Control never gets here */          /* Control never gets here */
# Line 2837  for (;;) Line 2961  for (;;)
2961          {          {
2962          pp = eptr;          pp = eptr;
2963    
2964  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2965          /* UTF-8 mode */          if (utf)
         if (utf8)  
2966            {            {
2967            for (i = min; i < max; i++)            for (i = min; i < max; i++)
2968              {              {
# Line 2855  for (;;) Line 2978  for (;;)
2978                if (op == OP_CLASS) break;                if (op == OP_CLASS) break;
2979                }                }
2980              else              else
2981                {                if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) break;
               if ((data[c/8] & (1 << (c&7))) == 0) break;  
               }  
2982              eptr += len;              eptr += len;
2983              }              }
2984            for (;;)            for (;;)
# Line 2870  for (;;) Line 2991  for (;;)
2991            }            }
2992          else          else
2993  #endif  #endif
2994            /* Not UTF-8 mode */            /* Not UTF mode */
2995            {            {
2996            for (i = min; i < max; i++)            for (i = min; i < max; i++)
2997              {              {
# Line 2880  for (;;) Line 3001  for (;;)
3001                break;                break;
3002                }                }
3003              c = *eptr;              c = *eptr;
3004              if ((data[c/8] & (1 << (c&7))) == 0) break;  #ifndef COMPILE_PCRE8
3005                if (c > 255)
3006                  {
3007                  if (op == OP_CLASS) break;
3008                  }
3009                else
3010    #endif
3011                  if ((BYTE_MAP[c/8] & (1 << (c&7))) == 0) break;
3012              eptr++;              eptr++;
3013              }              }
3014            while (eptr >= pp)            while (eptr >= pp)
# Line 2893  for (;;) Line 3021  for (;;)
3021    
3022          RRETURN(MATCH_NOMATCH);          RRETURN(MATCH_NOMATCH);
3023          }          }
3024    #undef BYTE_MAP
3025        }        }
3026      /* Control never gets here */      /* Control never gets here */
3027    
# Line 2901  for (;;) Line 3030  for (;;)
3030      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
3031      mode, because Unicode properties are supported in non-UTF-8 mode. */      mode, because Unicode properties are supported in non-UTF-8 mode. */
3032    
3033  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
3034      case OP_XCLASS:      case OP_XCLASS:
3035        {        {
3036        data = ecode + 1 + LINK_SIZE;                /* Save for matching */        data = ecode + 1 + LINK_SIZE;                /* Save for matching */
# Line 2926  for (;;) Line 3055  for (;;)
3055          case OP_CRMINRANGE:          case OP_CRMINRANGE:
3056          minimize = (*ecode == OP_CRMINRANGE);          minimize = (*ecode == OP_CRMINRANGE);
3057          min = GET2(ecode, 1);          min = GET2(ecode, 1);
3058          max = GET2(ecode, 3);          max = GET2(ecode, 1 + IMM2_SIZE);
3059          if (max == 0) max = INT_MAX;          if (max == 0) max = INT_MAX;
3060          ecode += 5;          ecode += 1 + 2 * IMM2_SIZE;
3061          break;          break;
3062    
3063          default:               /* No repeat follows */          default:               /* No repeat follows */
# Line 2946  for (;;) Line 3075  for (;;)
3075            RRETURN(MATCH_NOMATCH);            RRETURN(MATCH_NOMATCH);
3076            }            }
3077          GETCHARINCTEST(c, eptr);          GETCHARINCTEST(c, eptr);
3078          if (!_pcre_xclass(c, data)) RRETURN(MATCH_NOMATCH);          if (!PRIV(xclass)(c, data, utf)) RRETURN(MATCH_NOMATCH);
3079          }          }
3080    
3081        /* 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 3099  for (;;)
3099              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
3100              }              }
3101            GETCHARINCTEST(c, eptr);            GETCHARINCTEST(c, eptr);
3102            if (!_pcre_xclass(c, data)) RRETURN(MATCH_NOMATCH);            if (!PRIV(xclass)(c, data, utf)) RRETURN(MATCH_NOMATCH);
3103            }            }
3104          /* Control never gets here */          /* Control never gets here */
3105          }          }
# Line 2988  for (;;) Line 3117  for (;;)
3117              SCHECK_PARTIAL();              SCHECK_PARTIAL();
3118              break;              break;
3119              }              }
3120    #ifdef SUPPORT_UTF
3121            GETCHARLENTEST(c, eptr, len);            GETCHARLENTEST(c, eptr, len);
3122            if (!_pcre_xclass(c, data)) break;  #else
3123              c = *eptr;
3124    #endif
3125              if (!PRIV(xclass)(c, data, utf)) break;
3126            eptr += len;            eptr += len;
3127            }            }
3128          for(;;)          for(;;)
# Line 2997  for (;;) Line 3130  for (;;)
3130            RMATCH(eptr, ecode, offset_top, md, eptrb, RM21);            RMATCH(eptr, ecode, offset_top, md, eptrb, RM21);
3131            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3132            if (eptr-- == pp) break;        /* Stop if tried at original pos */            if (eptr-- == pp) break;        /* Stop if tried at original pos */
3133            if (utf8) BACKCHAR(eptr);  #ifdef SUPPORT_UTF
3134              if (utf) BACKCHAR(eptr);
3135    #endif
3136            }            }
3137          RRETURN(MATCH_NOMATCH);          RRETURN(MATCH_NOMATCH);
3138          }          }
# Line 3009  for (;;) Line 3144  for (;;)
3144      /* Match a single character, casefully */      /* Match a single character, casefully */
3145    
3146      case OP_CHAR:      case OP_CHAR:
3147  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3148      if (utf8)      if (utf)
3149        {        {
3150        length = 1;        length = 1;
3151        ecode++;        ecode++;
# Line 3024  for (;;) Line 3159  for (;;)
3159        }        }
3160      else      else
3161  #endif  #endif
3162        /* Not UTF mode */
     /* Non-UTF-8 mode */  
3163        {        {
3164        if (md->end_subject - eptr < 1)        if (md->end_subject - eptr < 1)
3165          {          {
# Line 3037  for (;;) Line 3171  for (;;)
3171        }        }
3172      break;      break;
3173    
3174      /* Match a single character, caselessly */      /* Match a single character, caselessly. If we are at the end of the
3175        subject, give up immediately. */
3176    
3177      case OP_CHARI:      case OP_CHARI:
3178  #ifdef SUPPORT_UTF8      if (eptr >= md->end_subject)
3179      if (utf8)        {
3180          SCHECK_PARTIAL();
3181          RRETURN(MATCH_NOMATCH);
3182          }
3183    
3184    #ifdef SUPPORT_UTF
3185        if (utf)
3186        {        {
3187        length = 1;        length = 1;
3188        ecode++;        ecode++;
3189        GETCHARLEN(fc, ecode, length);        GETCHARLEN(fc, ecode, length);
3190    
       if (length > md->end_subject - eptr)  
         {  
         CHECK_PARTIAL();             /* Not SCHECK_PARTIAL() */  
         RRETURN(MATCH_NOMATCH);  
         }  
   
3191        /* 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
3192        can use the fast lookup table. */        we know that its other case must also be one byte long, so we can use the
3193          fast lookup table. We know that there is at least one byte left in the
3194          subject. */
3195    
3196        if (fc < 128)        if (fc < 128)
3197          {          {
3198          if (md->lcc[*ecode++] != md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH);          if (md->lcc[fc]
3199                != TABLE_GET(*eptr, md->lcc, *eptr)) RRETURN(MATCH_NOMATCH);
3200            ecode++;
3201            eptr++;
3202          }          }
3203    
3204        /* Otherwise we must pick up the subject character */        /* Otherwise we must pick up the subject character. Note that we cannot
3205          use the value of "length" to check for sufficient bytes left, because the
3206          other case of the character may have more or fewer bytes.  */
3207    
3208        else        else
3209          {          {
# Line 3082  for (;;) Line 3224  for (;;)
3224          }          }
3225        }        }
3226      else      else
3227  #endif   /* SUPPORT_UTF8 */  #endif   /* SUPPORT_UTF */
3228    
3229      /* Non-UTF-8 mode */      /* Not UTF mode */
3230        {        {
3231        if (md->end_subject - eptr < 1)        if (TABLE_GET(ecode[1], md->lcc, ecode[1])
3232          {            != TABLE_GET(*eptr, md->lcc, *eptr)) RRETURN(MATCH_NOMATCH);
3233          SCHECK_PARTIAL();            /* This one can use SCHECK_PARTIAL() */        eptr++;
         RRETURN(MATCH_NOMATCH);  
         }  
       if (md->lcc[ecode[1]] != md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH);  
3234        ecode += 2;        ecode += 2;
3235        }        }
3236      break;      break;
# Line 3101  for (;;) Line 3240  for (;;)
3240      case OP_EXACT:      case OP_EXACT:
3241      case OP_EXACTI:      case OP_EXACTI:
3242      min = max = GET2(ecode, 1);      min = max = GET2(ecode, 1);
3243      ecode += 3;      ecode += 1 + IMM2_SIZE;
3244      goto REPEATCHAR;      goto REPEATCHAR;
3245    
3246      case OP_POSUPTO:      case OP_POSUPTO:
# Line 3116  for (;;) Line 3255  for (;;)
3255      min = 0;      min = 0;
3256      max = GET2(ecode, 1);      max = GET2(ecode, 1);
3257      minimize = *ecode == OP_MINUPTO || *ecode == OP_MINUPTOI;      minimize = *ecode == OP_MINUPTO || *ecode == OP_MINUPTOI;
3258      ecode += 3;      ecode += 1 + IMM2_SIZE;
3259      goto REPEATCHAR;      goto REPEATCHAR;
3260    
3261      case OP_POSSTAR:      case OP_POSSTAR:
# Line 3164  for (;;) Line 3303  for (;;)
3303      /* Common code for all repeated single-character matches. */      /* Common code for all repeated single-character matches. */
3304    
3305      REPEATCHAR:      REPEATCHAR:
3306  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3307      if (utf8)      if (utf)
3308        {        {
3309        length = 1;        length = 1;
3310        charptr = ecode;        charptr = ecode;
# Line 3181  for (;;) Line 3320  for (;;)
3320          unsigned int othercase;          unsigned int othercase;
3321          if (op >= OP_STARI &&     /* Caseless */          if (op >= OP_STARI &&     /* Caseless */
3322              (othercase = UCD_OTHERCASE(fc)) != fc)              (othercase = UCD_OTHERCASE(fc)) != fc)
3323            oclength = _pcre_ord2utf8(othercase, occhars);            oclength = PRIV(ord2utf)(othercase, occhars);
3324          else oclength = 0;          else oclength = 0;
3325  #endif  /* SUPPORT_UCP */  #endif  /* SUPPORT_UCP */
3326    
3327          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3328            {            {
3329            if (eptr <= md->end_subject - length &&            if (eptr <= md->end_subject - length &&
3330              memcmp(eptr, charptr, length) == 0) eptr += length;              memcmp(eptr, charptr, IN_UCHARS(length)) == 0) eptr += length;
3331  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3332            else if (oclength > 0 &&            else if (oclength > 0 &&
3333                     eptr <= md->end_subject - oclength &&                     eptr <= md->end_subject - oclength &&
3334                     memcmp(eptr, occhars, oclength) == 0) eptr += oclength;                     memcmp(eptr, occhars, IN_UCHARS(oclength)) == 0) eptr += oclength;
3335  #endif  /* SUPPORT_UCP */  #endif  /* SUPPORT_UCP */
3336            else            else
3337              {              {
# Line 3211  for (;;) Line 3350  for (;;)
3350              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3351              if (fi >= max) RRETURN(MATCH_NOMATCH);              if (fi >= max) RRETURN(MATCH_NOMATCH);
3352              if (eptr <= md->end_subject - length &&              if (eptr <= md->end_subject - length &&
3353                memcmp(eptr, charptr, length) == 0) eptr += length;                memcmp(eptr, charptr, IN_UCHARS(length)) == 0) eptr += length;
3354  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3355              else if (oclength > 0 &&              else if (oclength > 0 &&
3356                       eptr <= md->end_subject - oclength &&                       eptr <= md->end_subject - oclength &&
3357                       memcmp(eptr, occhars, oclength) == 0) eptr += oclength;                       memcmp(eptr, occhars, IN_UCHARS(oclength)) == 0) eptr += oclength;
3358  #endif  /* SUPPORT_UCP */  #endif  /* SUPPORT_UCP */
3359              else              else
3360                {                {
# Line 3232  for (;;) Line 3371  for (;;)
3371            for (i = min; i < max; i++)            for (i = min; i < max; i++)
3372              {              {
3373              if (eptr <= md->end_subject - length &&              if (eptr <= md->end_subject - length &&
3374                  memcmp(eptr, charptr, length) == 0) eptr += length;                  memcmp(eptr, charptr, IN_UCHARS(length)) == 0) eptr += length;
3375  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3376              else if (oclength > 0 &&              else if (oclength > 0 &&
3377                       eptr <= md->end_subject - oclength &&                       eptr <= md->end_subject - oclength &&
3378                       memcmp(eptr, occhars, oclength) == 0) eptr += oclength;                       memcmp(eptr, occhars, IN_UCHARS(oclength)) == 0) eptr += oclength;
3379  #endif  /* SUPPORT_UCP */  #endif  /* SUPPORT_UCP */
3380              else              else
3381                {                {
# Line 3268  for (;;) Line 3407  for (;;)
3407        value of fc will always be < 128. */        value of fc will always be < 128. */
3408        }        }
3409      else      else
3410  #endif  /* SUPPORT_UTF8 */  #endif  /* SUPPORT_UTF */
3411          /* When not in UTF-8 mode, load a single-byte character. */
3412          fc = *ecode++;
3413    
3414      /* When not in UTF-8 mode, load a single-byte character. */      /* The value of fc at this point is always one character, though we may
3415        or may not be in UTF mode. The code is duplicated for the caseless and
     fc = *ecode++;  
   
     /* The value of fc at this point is always less than 256, though we may or  
     may not be in UTF-8 mode. The code is duplicated for the caseless and  
3416      caseful cases, for speed, since matching characters is likely to be quite      caseful cases, for speed, since matching characters is likely to be quite
3417      common. First, ensure the minimum number of matches are present. If min =      common. First, ensure the minimum number of matches are present. If min =
3418      max, continue at the same level without recursing. Otherwise, if      max, continue at the same level without recursing. Otherwise, if
# Line 3288  for (;;) Line 3425  for (;;)
3425    
3426      if (op >= OP_STARI)  /* Caseless */      if (op >= OP_STARI)  /* Caseless */
3427        {        {
3428        fc = md->lcc[fc];  #ifdef COMPILE_PCRE8
3429          /* fc must be < 128 if UTF is enabled. */
3430          foc = md->fcc[fc];
3431    #else
3432    #ifdef SUPPORT_UTF
3433    #ifdef SUPPORT_UCP
3434          if (utf && fc > 127)
3435            foc = UCD_OTHERCASE(fc);
3436    #else
3437          if (utf && fc > 127)
3438            foc = fc;
3439    #endif /* SUPPORT_UCP */
3440          else
3441    #endif /* SUPPORT_UTF */
3442            foc = TABLE_GET(fc, md->fcc, fc);
3443    #endif /* COMPILE_PCRE8 */
3444    
3445        for (i = 1; i <= min; i++)        for (i = 1; i <= min; i++)
3446          {          {
3447          if (eptr >= md->end_subject)          if (eptr >= md->end_subject)
# Line 3296  for (;;) Line 3449  for (;;)
3449            SCHECK_PARTIAL();            SCHECK_PARTIAL();
3450            RRETURN(MATCH_NOMATCH);            RRETURN(MATCH_NOMATCH);
3451            }            }
3452          if (fc != md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH);          if (fc != *eptr && foc != *eptr) RRETURN(MATCH_NOMATCH);
3453            eptr++;
3454          }          }
3455        if (min == max) continue;        if (min == max) continue;
3456        if (minimize)        if (minimize)
# Line 3311  for (;;) Line 3465  for (;;)
3465              SCHECK_PARTIAL();              SCHECK_PARTIAL();
3466              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
3467              }              }
3468            if (fc != md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH);            if (fc != *eptr && foc != *eptr) RRETURN(MATCH_NOMATCH);
3469              eptr++;
3470            }            }
3471          /* Control never gets here */          /* Control never gets here */
3472          }          }
# Line 3325  for (;;) Line 3480  for (;;)
3480              SCHECK_PARTIAL();              SCHECK_PARTIAL();
3481              break;              break;
3482              }              }
3483            if (fc != md->lcc[*eptr]) break;            if (fc != *eptr && foc != *eptr) break;
3484            eptr++;            eptr++;
3485            }            }
3486    
# Line 3414  for (;;) Line 3569  for (;;)
3569      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
3570      if (op == OP_NOTI)         /* The caseless case */      if (op == OP_NOTI)         /* The caseless case */
3571        {        {
3572  #ifdef SUPPORT_UTF8        register unsigned int ch, och;
3573        if (c < 256)        ch = *ecode++;
3574  #endif  #ifdef COMPILE_PCRE8
3575        c = md->lcc[c];        /* ch must be < 128 if UTF is enabled. */
3576        if (md->lcc[*ecode++] == c) RRETURN(MATCH_NOMATCH);        och = md->fcc[ch];
3577    #else
3578    #ifdef SUPPORT_UTF
3579    #ifdef SUPPORT_UCP
3580          if (utf && ch > 127)
3581            och = UCD_OTHERCASE(ch);
3582    #else
3583          if (utf && ch > 127)
3584            och = ch;
3585    #endif /* SUPPORT_UCP */
3586          else
3587    #endif /* SUPPORT_UTF */
3588            och = TABLE_GET(ch, md->fcc, ch);
3589    #endif /* COMPILE_PCRE8 */
3590          if (ch == c || och == c) RRETURN(MATCH_NOMATCH);
3591        }        }
3592      else    /* Caseful */      else    /* Caseful */
3593        {        {
# Line 3436  for (;;) Line 3605  for (;;)
3605      case OP_NOTEXACT:      case OP_NOTEXACT:
3606      case OP_NOTEXACTI:      case OP_NOTEXACTI:
3607      min = max = GET2(ecode, 1);      min = max = GET2(ecode, 1);
3608      ecode += 3;      ecode += 1 + IMM2_SIZE;
3609      goto REPEATNOTCHAR;      goto REPEATNOTCHAR;
3610    
3611      case OP_NOTUPTO:      case OP_NOTUPTO:
# Line 3446  for (;;) Line 3615  for (;;)
3615      min = 0;      min = 0;
3616      max = GET2(ecode, 1);      max = GET2(ecode, 1);
3617      minimize = *ecode == OP_NOTMINUPTO || *ecode == OP_NOTMINUPTOI;      minimize = *ecode == OP_NOTMINUPTO || *ecode == OP_NOTMINUPTOI;
3618      ecode += 3;      ecode += 1 + IMM2_SIZE;
3619      goto REPEATNOTCHAR;      goto REPEATNOTCHAR;
3620    
3621      case OP_NOTPOSSTAR:      case OP_NOTPOSSTAR:
# Line 3478  for (;;) Line 3647  for (;;)
3647      possessive = TRUE;      possessive = TRUE;
3648      min = 0;      min = 0;
3649      max = GET2(ecode, 1);      max = GET2(ecode, 1);
3650      ecode += 3;      ecode += 1 + IMM2_SIZE;
3651      goto REPEATNOTCHAR;      goto REPEATNOTCHAR;
3652    
3653      case OP_NOTSTAR:      case OP_NOTSTAR:
# Line 3517  for (;;) Line 3686  for (;;)
3686    
3687      if (op >= OP_NOTSTARI)     /* Caseless */      if (op >= OP_NOTSTARI)     /* Caseless */
3688        {        {
3689        fc = md->lcc[fc];  #ifdef COMPILE_PCRE8
3690          /* fc must be < 128 if UTF is enabled. */
3691          foc = md->fcc[fc];
3692    #else
3693    #ifdef SUPPORT_UTF
3694    #ifdef SUPPORT_UCP
3695          if (utf && fc > 127)
3696            foc = UCD_OTHERCASE(fc);
3697    #else
3698          if (utf && fc > 127)
3699            foc = fc;
3700    #endif /* SUPPORT_UCP */
3701          else
3702    #endif /* SUPPORT_UTF */
3703            foc = TABLE_GET(fc, md->fcc, fc);
3704    #endif /* COMPILE_PCRE8 */
3705    
3706  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3707        /* UTF-8 mode */        if (utf)
       if (utf8)  
3708          {          {
3709          register unsigned int d;          register unsigned int d;
3710          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
# Line 3532  for (;;) Line 3715  for (;;)
3715              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
3716              }              }
3717            GETCHARINC(d, eptr);            GETCHARINC(d, eptr);
3718            if (d < 256) d = md->lcc[d];            if (fc == d || (unsigned int) foc == d) RRETURN(MATCH_NOMATCH);
           if (fc == d) RRETURN(MATCH_NOMATCH);  
3719            }            }
3720          }          }
3721        else        else
3722  #endif  #endif
3723          /* Not UTF mode */
       /* Not UTF-8 mode */  
3724          {          {
3725          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3726            {            {
# Line 3548  for (;;) Line 3729  for (;;)
3729              SCHECK_PARTIAL();              SCHECK_PARTIAL();
3730              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
3731              }              }
3732            if (fc == md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH);            if (fc == *eptr || foc == *eptr) RRETURN(MATCH_NOMATCH);
3733              eptr++;
3734            }            }
3735          }          }
3736    
# Line 3556  for (;;) Line 3738  for (;;)
3738    
3739        if (minimize)        if (minimize)
3740          {          {
3741  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3742          /* UTF-8 mode */          if (utf)
         if (utf8)  
3743            {            {
3744            register unsigned int d;            register unsigned int d;
3745            for (fi = min;; fi++)            for (fi = min;; fi++)
# Line 3572  for (;;) Line 3753  for (;;)
3753                RRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
3754                }                }
3755              GETCHARINC(d, eptr);              GETCHARINC(d, eptr);
3756              if (d < 256) d = md->lcc[d];              if (fc == d || (unsigned int)foc == d) RRETURN(MATCH_NOMATCH);
             if (fc == d) RRETURN(MATCH_NOMATCH);  
3757              }              }
3758            }            }
3759          else          else
3760  #endif  #endif
3761          /* Not UTF-8 mode */          /* Not UTF mode */
3762            {            {
3763            for (fi = min;; fi++)            for (fi = min;; fi++)
3764              {              {
# Line 3590  for (;;) Line 3770  for (;;)
3770                SCHECK_PARTIAL();                SCHECK_PARTIAL();
3771                RRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
3772                }                }
3773              if (fc == md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH);              if (fc == *eptr || foc == *eptr) RRETURN(MATCH_NOMATCH);
3774                eptr++;
3775              }              }
3776            }            }
3777          /* Control never gets here */          /* Control never gets here */
# Line 3602  for (;;) Line 3783  for (;;)
3783          {          {
3784          pp = eptr;          pp = eptr;
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 (i = min; i < max; i++)            for (i = min; i < max; i++)
# Line 3616  for (;;) Line 3796  for (;;)
3796                break;                break;
3797                }                }
3798              GETCHARLEN(d, eptr, len);              GETCHARLEN(d, eptr, len);
3799              if (d < 256) d = md->lcc[d];              if (fc == d || (unsigned int)foc == d) break;
             if (fc == d) break;  
3800              eptr += len;              eptr += len;
3801              }              }
3802          if (possessive) continue;            if (possessive) continue;
3803          for(;;)            for(;;)
3804              {              {
3805              RMATCH(eptr, ecode, offset_top, md, eptrb, RM30);              RMATCH(eptr, ecode, offset_top, md, eptrb, RM30);
3806              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
# Line 3631  for (;;) Line 3810  for (;;)
3810            }            }
3811          else          else
3812  #endif  #endif
3813          /* Not UTF-8 mode */          /* Not UTF mode */
3814            {            {
3815            for (i = min; i < max; i++)            for (i = min; i < max; i++)
3816              {              {
# Line 3640  for (;;) Line 3819  for (;;)
3819                SCHECK_PARTIAL();                SCHECK_PARTIAL();
3820                break;                break;
3821                }                }
3822              if (fc == md->lcc[*eptr]) break;              if (fc == *eptr || foc == *eptr) break;
3823              eptr++;              eptr++;
3824              }              }
3825            if (possessive) continue;            if (possessive) continue;
# Line 3661  for (;;) Line 3840  for (;;)
3840    
3841      else      else
3842        {        {
3843  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3844        /* UTF-8 mode */        if (utf)
       if (utf8)  
3845          {          {
3846          register unsigned int d;          register unsigned int d;
3847          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
# Line 3679  for (;;) Line 3857  for (;;)
3857          }          }
3858        else        else
3859  #endif  #endif
3860        /* Not UTF-8 mode */        /* Not UTF mode */
3861          {          {
3862          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3863            {            {
# Line 3696  for (;;) Line 3874  for (;;)
3874    
3875        if (minimize)        if (minimize)
3876          {          {
3877  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3878          /* UTF-8 mode */          if (utf)
         if (utf8)  
3879            {            {
3880            register unsigned int d;            register unsigned int d;
3881            for (fi = min;; fi++)            for (fi = min;; fi++)
# Line 3717  for (;;) Line 3894  for (;;)
3894            }            }
3895          else          else
3896  #endif  #endif
3897          /* Not UTF-8 mode */          /* Not UTF mode */
3898            {            {
3899            for (fi = min;; fi++)            for (fi = min;; fi++)
3900              {              {
# Line 3741  for (;;) Line 3918  for (;;)
3918          {          {
3919          pp = eptr;          pp = eptr;
3920    
3921  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3922          /* UTF-8 mode */          if (utf)
         if (utf8)  
3923            {            {
3924            register unsigned int d;            register unsigned int d;
3925            for (i = min; i < max; i++)            for (i = min; i < max; i++)
# Line 3769  for (;;) Line 3945  for (;;)
3945            }            }
3946          else          else
3947  #endif  #endif
3948          /* Not UTF-8 mode */          /* Not UTF mode */
3949            {            {
3950            for (i = min; i < max; i++)            for (i = min; i < max; i++)
3951              {              {
# Line 3802  for (;;) Line 3978  for (;;)
3978      case OP_TYPEEXACT:      case OP_TYPEEXACT:
3979      min = max = GET2(ecode, 1);      min = max = GET2(ecode, 1);
3980      minimize = TRUE;      minimize = TRUE;
3981      ecode += 3;      ecode += 1 + IMM2_SIZE;
3982      goto REPEATTYPE;      goto REPEATTYPE;
3983    
3984      case OP_TYPEUPTO:      case OP_TYPEUPTO:
# Line 3810  for (;;) Line 3986  for (;;)
3986      min = 0;      min = 0;
3987      max = GET2(ecode, 1);      max = GET2(ecode, 1);
3988      minimize = *ecode == OP_TYPEMINUPTO;      minimize = *ecode == OP_TYPEMINUPTO;
3989      ecode += 3;      ecode += 1 + IMM2_SIZE;
3990      goto REPEATTYPE;      goto REPEATTYPE;
3991    
3992      case OP_TYPEPOSSTAR:      case OP_TYPEPOSSTAR:
# Line 3838  for (;;) Line 4014  for (;;)
4014      possessive = TRUE;      possessive = TRUE;
4015      min = 0;      min = 0;
4016      max = GET2(ecode, 1);      max = GET2(ecode, 1);
4017      ecode += 3;      ecode += 1 + IMM2_SIZE;
4018      goto REPEATTYPE;      goto REPEATTYPE;
4019    
4020      case OP_TYPESTAR:      case OP_TYPESTAR:
# Line 4045  for (;;) Line 4221  for (;;)
4221            while (eptr < md->end_subject)            while (eptr < md->end_subject)
4222              {              {
4223              int len = 1;              int len = 1;
4224              if (!utf8) c = *eptr; else { GETCHARLEN(c, eptr, len); }              if (!utf) c = *eptr; else { GETCHARLEN(c, eptr, len); }
4225              if (UCD_CATEGORY(c) != ucp_M) break;              if (UCD_CATEGORY(c) != ucp_M) break;
4226              eptr += len;              eptr += len;
4227              }              }
4228              CHECK_PARTIAL();
4229            }            }
4230          }          }
4231    
# Line 4057  for (;;) Line 4234  for (;;)
4234    
4235  /* Handle all other cases when the coding is UTF-8 */  /* Handle all other cases when the coding is UTF-8 */
4236    
4237  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
4238        if (utf8) switch(ctype)        if (utf) switch(ctype)
4239          {          {
4240          case OP_ANY:          case OP_ANY:
4241          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
# Line 4069  for (;;) Line 4246  for (;;)
4246              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4247              }              }
4248            if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH);            if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH);
4249              if (md->partial != 0 &&
4250                  eptr + 1 >= md->end_subject &&
4251                  NLBLOCK->nltype == NLTYPE_FIXED &&
4252                  NLBLOCK->nllen == 2 &&
4253                  *eptr == NLBLOCK->nl[0])
4254                {
4255                md->hitend = TRUE;
4256                if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
4257                }
4258            eptr++;            eptr++;
4259            while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;            ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
4260            }            }
4261          break;          break;
4262    
# Line 4083  for (;;) Line 4269  for (;;)
4269              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4270              }              }
4271            eptr++;            eptr++;
4272            while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;            ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
4273            }            }
4274          break;          break;
4275    
# Line 4265  for (;;) Line 4451  for (;;)
4451              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4452              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4453              }              }
4454            if (*eptr >= 128 || (md->ctypes[*eptr++] & ctype_digit) == 0)            if (*eptr >= 128 || (md->ctypes[*eptr] & ctype_digit) == 0)
4455              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4456              eptr++;
4457            /* 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 */
4458            }            }
4459          break;          break;
# Line 4281  for (;;) Line 4468  for (;;)
4468              }              }
4469            if (*eptr < 128 && (md->ctypes[*eptr] & ctype_space) != 0)            if (*eptr < 128 && (md->ctypes[*eptr] & ctype_space) != 0)
4470              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4471            while (++eptr < md->end_subject && (*eptr & 0xc0) == 0x80);            eptr++;
4472              ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
4473            }            }
4474          break;          break;
4475    
# Line 4293  for (;;) Line 4481  for (;;)
4481              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4482              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4483              }              }
4484            if (*eptr >= 128 || (md->ctypes[*eptr++] & ctype_space) == 0)            if (*eptr >= 128 || (md->ctypes[*eptr] & ctype_space) == 0)
4485              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4486              eptr++;
4487            /* 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 */
4488            }            }
4489          break;          break;
# Line 4309  for (;;) Line 4498  for (;;)
4498              }              }
4499            if (*eptr < 128 && (md->ctypes[*eptr] & ctype_word) != 0)            if (*eptr < 128 && (md->ctypes[*eptr] & ctype_word) != 0)
4500              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4501            while (++eptr < md->end_subject && (*eptr & 0xc0) == 0x80);            eptr++;
4502              ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
4503            }            }
4504          break;          break;
4505    
# Line 4321  for (;;) Line 4511  for (;;)
4511              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4512              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4513              }              }
4514            if (*eptr >= 128 || (md->ctypes[*eptr++] & ctype_word) == 0)            if (*eptr >= 128 || (md->ctypes[*eptr] & ctype_word) == 0)
4515              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4516              eptr++;
4517            /* 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 */
4518            }            }
4519          break;          break;
# Line 4332  for (;;) Line 4523  for (;;)
4523          }  /* End switch(ctype) */          }  /* End switch(ctype) */
4524    
4525        else        else
4526  #endif     /* SUPPORT_UTF8 */  #endif     /* SUPPORT_UTF */
4527    
4528        /* 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
4529        than OP_PROP and OP_NOTPROP. */        than OP_PROP and OP_NOTPROP. */
# Line 4348  for (;;) Line 4539  for (;;)
4539              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4540              }              }
4541            if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH);            if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH);
4542              if (md->partial != 0 &&
4543                  eptr + 1 >= md->end_subject &&
4544                  NLBLOCK->nltype == NLTYPE_FIXED &&
4545                  NLBLOCK->nllen == 2 &&
4546                  *eptr == NLBLOCK->nl[0])
4547                {
4548                md->hitend = TRUE;
4549                if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
4550                }
4551            eptr++;            eptr++;
4552            }            }
4553          break;          break;
# Line 4392  for (;;) Line 4592  for (;;)
4592              case 0x000b:              case 0x000b:
4593              case 0x000c:              case 0x000c:
4594              case 0x0085:              case 0x0085:
4595    #ifdef COMPILE_PCRE16
4596                case 0x2028:
4597                case 0x2029:
4598    #endif
4599              if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH);              if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH);
4600              break;              break;
4601              }              }
# Line 4412  for (;;) Line 4616  for (;;)
4616              case 0x09:      /* HT */              case 0x09:      /* HT */
4617              case 0x20:      /* SPACE */              case 0x20:      /* SPACE */
4618              case 0xa0:      /* NBSP */              case 0xa0:      /* NBSP */
4619    #ifdef COMPILE_PCRE16
4620                case 0x1680:    /* OGHAM SPACE MARK */
4621                case 0x180e:    /* MONGOLIAN VOWEL SEPARATOR */
4622                case 0x2000:    /* EN QUAD */
4623                case 0x2001:    /* EM QUAD */
4624                case 0x2002:    /* EN SPACE */
4625                case 0x2003:    /* EM SPACE */
4626                case 0x2004:    /* THREE-PER-EM SPACE */
4627                case 0x2005:    /* FOUR-PER-EM SPACE */
4628                case 0x2006:    /* SIX-PER-EM SPACE */
4629                case 0x2007:    /* FIGURE SPACE */
4630                case 0x2008:    /* PUNCTUATION SPACE */
4631                case 0x2009:    /* THIN SPACE */
4632                case 0x200A:    /* HAIR SPACE */
4633                case 0x202f:    /* NARROW NO-BREAK SPACE */
4634                case 0x205f:    /* MEDIUM MATHEMATICAL SPACE */
4635                case 0x3000:    /* IDEOGRAPHIC SPACE */
4636    #endif
4637              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4638              }              }
4639            }            }
# Line 4431  for (;;) Line 4653  for (;;)
4653              case 0x09:      /* HT */              case 0x09:      /* HT */
4654              case 0x20:      /* SPACE */              case 0x20:      /* SPACE */
4655              case 0xa0:      /* NBSP */              case 0xa0:      /* NBSP */
4656    #ifdef COMPILE_PCRE16
4657                case 0x1680:    /* OGHAM SPACE MARK */
4658                case 0x180e:    /* MONGOLIAN VOWEL SEPARATOR */
4659                case 0x2000:    /* EN QUAD */
4660                case 0x2001:    /* EM QUAD */
4661                case 0x2002:    /* EN SPACE */
4662                case 0x2003:    /* EM SPACE */
4663                case 0x2004:    /* THREE-PER-EM SPACE */
4664                case 0x2005:    /* FOUR-PER-EM SPACE */
4665                case 0x2006:    /* SIX-PER-EM SPACE */
4666                case 0x2007:    /* FIGURE SPACE */
4667                case 0x2008:    /* PUNCTUATION SPACE */
4668                case 0x2009:    /* THIN SPACE */
4669                case 0x200A:    /* HAIR SPACE */
4670                case 0x202f:    /* NARROW NO-BREAK SPACE */
4671                case 0x205f:    /* MEDIUM MATHEMATICAL SPACE */
4672                case 0x3000:    /* IDEOGRAPHIC SPACE */
4673    #endif
4674              break;              break;
4675              }              }
4676            }            }
# Line 4452  for (;;) Line 4692  for (;;)
4692              case 0x0c:      /* FF */              case 0x0c:      /* FF */
4693              case 0x0d:      /* CR */              case 0x0d:      /* CR */
4694              case 0x85:      /* NEL */              case 0x85:      /* NEL */
4695    #ifdef COMPILE_PCRE16
4696                case 0x2028:    /* LINE SEPARATOR */
4697                case 0x2029:    /* PARAGRAPH SEPARATOR */
4698    #endif
4699              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4700              }              }
4701            }            }
# Line 4473  for (;;) Line 4717  for (;;)
4717              case 0x0c:      /* FF */              case 0x0c:      /* FF */
4718              case 0x0d:      /* CR */              case 0x0d:      /* CR */
4719              case 0x85:      /* NEL */              case 0x85:      /* NEL */
4720    #ifdef COMPILE_PCRE16
4721                case 0x2028:    /* LINE SEPARATOR */
4722                case 0x2029:    /* PARAGRAPH SEPARATOR */
4723    #endif
4724              break;              break;
4725              }              }
4726            }            }
# Line 4486  for (;;) Line 4734  for (;;)
4734              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4735              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4736              }              }
4737            if ((md->ctypes[*eptr++] & ctype_digit) != 0) RRETURN(MATCH_NOMATCH);            if (MAX_255(*eptr) && (md->ctypes[*eptr] & ctype_digit) != 0)
4738                RRETURN(MATCH_NOMATCH);
4739              eptr++;
4740            }            }
4741          break;          break;
4742    
# Line 4498  for (;;) Line 4748  for (;;)
4748              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4749              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4750              }              }
4751            if ((md->ctypes[*eptr++] & ctype_digit) == 0) RRETURN(MATCH_NOMATCH);            if (!MAX_255(*eptr) || (md->ctypes[*eptr] & ctype_digit) == 0)
4752                RRETURN(MATCH_NOMATCH);
4753              eptr++;
4754            }            }
4755          break;          break;
4756    
# Line 4510  for (;;) Line 4762  for (;;)
4762              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4763              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4764              }              }
4765            if ((md->ctypes[*eptr++] & ctype_space) != 0) RRETURN(MATCH_NOMATCH);            if (MAX_255(*eptr) && (md->ctypes[*eptr] & ctype_space) != 0)
4766                RRETURN(MATCH_NOMATCH);
4767              eptr++;
4768            }            }
4769          break;          break;
4770    
# Line 4522  for (;;) Line 4776  for (;;)
4776              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4777              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4778              }              }
4779            if ((md->ctypes[*eptr++] & ctype_space) == 0) RRETURN(MATCH_NOMATCH);            if (!MAX_255(*eptr) || (md->ctypes[*eptr] & ctype_space) == 0)
4780                RRETURN(MATCH_NOMATCH);
4781              eptr++;
4782            }            }
4783          break;          break;
4784    
# Line 4534  for (;;) Line 4790  for (;;)
4790              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4791              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4792              }              }
4793            if ((md->ctypes[*eptr++] & ctype_word) != 0)            if (MAX_255(*eptr) && (md->ctypes[*eptr] & ctype_word) != 0)
4794              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4795              eptr++;
4796            }            }
4797          break;          break;
4798    
# Line 4547  for (;;) Line 4804  for (;;)
4804              SCHECK_PARTIAL();              SCHECK_PARTIAL();
4805              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4806              }              }
4807            if ((md->ctypes[*eptr++] & ctype_word) == 0)            if (!MAX_255(*eptr) || (md->ctypes[*eptr] & ctype_word) == 0)
4808              RRETURN(MATCH_NOMATCH);              RRETURN(MATCH_NOMATCH);
4809              eptr++;
4810            }            }
4811          break;          break;
4812    
# Line 4766  for (;;) Line 5024  for (;;)
5024            while (eptr < md->end_subject)            while (eptr < md->end_subject)
5025              {              {
5026              int len = 1;              int len = 1;
5027              if (!utf8) c = *eptr; else { GETCHARLEN(c, eptr, len); }              if (!utf) c = *eptr; else { GETCHARLEN(c, eptr, len); }
5028              if (UCD_CATEGORY(c) != ucp_M) break;              if (UCD_CATEGORY(c) != ucp_M) break;
5029              eptr += len;              eptr += len;
5030              }              }
5031              CHECK_PARTIAL();
5032            }            }
5033          }          }
5034        else        else
5035  #endif     /* SUPPORT_UCP */  #endif     /* SUPPORT_UCP */
5036    
5037  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
5038        /* UTF-8 mode */        if (utf)
       if (utf8)  
5039          {          {
5040          for (fi = min;; fi++)          for (fi = min;; fi++)
5041            {            {
# Line 4794  for (;;) Line 5052  for (;;)
5052            GETCHARINC(c, eptr);            GETCHARINC(c, eptr);
5053            switch(ctype)            switch(ctype)
5054              {              {
5055              case OP_ANY:        /* This is the non-NL case */              case OP_ANY:               /* This is the non-NL case */
5056                if (md->partial != 0 &&    /* Take care with CRLF partial */
5057                    eptr >= md->end_subject &&
5058                    NLBLOCK->nltype == NLTYPE_FIXED &&
5059                    NLBLOCK->nllen == 2 &&
5060                    c == NLBLOCK->nl[0])
5061                  {
5062                  md->hitend = TRUE;
5063                  if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
5064                  }
5065                break;
5066    
5067              case OP_ALLANY:              case OP_ALLANY:
5068              case OP_ANYBYTE:              case OP_ANYBYTE:
5069              break;              break;
# Line 4919  for (;;) Line 5188  for (;;)
5188              break;              break;
5189    
5190              case OP_WHITESPACE:              case OP_WHITESPACE:
5191              if  (c >= 256 || (md->ctypes[c] & ctype_space) == 0)              if (c >= 256 || (md->ctypes[c] & ctype_space) == 0)
5192                RRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
5193              break;              break;
5194    
# Line 4940  for (;;) Line 5209  for (;;)
5209          }          }
5210        else        else
5211  #endif  #endif
5212        /* Not UTF-8 mode */        /* Not UTF mode */
5213          {          {
5214          for (fi = min;; fi++)          for (fi = min;; fi++)
5215            {            {
# Line 4957  for (;;) Line 5226  for (;;)
5226            c = *eptr++;            c = *eptr++;
5227            switch(ctype)            switch(ctype)
5228              {              {
5229              case OP_ANY:     /* This is the non-NL case */              case OP_ANY:               /* This is the non-NL case */
5230                if (md->partial != 0 &&    /* Take care with CRLF partial */
5231                    eptr >= md->end_subject &&
5232                    NLBLOCK->nltype == NLTYPE_FIXED &&
5233                    NLBLOCK->nllen == 2 &&
5234                    c == NLBLOCK->nl[0])
5235                  {
5236                  md->hitend = TRUE;
5237                  if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
5238                  }
5239                break;
5240    
5241              case OP_ALLANY:              case OP_ALLANY:
5242              case OP_ANYBYTE:              case OP_ANYBYTE:
5243              break;              break;
# Line 4976  for (;;) Line 5256  for (;;)
5256                case 0x000b:                case 0x000b:
5257                case 0x000c:                case 0x000c:
5258                case 0x0085:                case 0x0085:
5259    #ifdef COMPILE_PCRE16
5260                  case 0x2028:
5261                  case 0x2029:
5262    #endif
5263                if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH);                if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH);
5264                break;                break;
5265                }                }
# Line 4988  for (;;) Line 5272  for (;;)
5272                case 0x09:      /* HT */                case 0x09:      /* HT */
5273                case 0x20:      /* SPACE */                case 0x20:      /* SPACE */
5274                case 0xa0:      /* NBSP */                case 0xa0:      /* NBSP */
5275    #ifdef COMPILE_PCRE16
5276                  case 0x1680:    /* OGHAM SPACE MARK */
5277                  case 0x180e:    /* MONGOLIAN VOWEL SEPARATOR */
5278                  case 0x2000:    /* EN QUAD */
5279                  case 0x2001:    /* EM QUAD */
5280                  case 0x2002:    /* EN SPACE */
5281                  case 0x2003:    /* EM SPACE */
5282                  case 0x2004:    /* THREE-PER-EM SPACE */
5283                  case 0x2005:    /* FOUR-PER-EM SPACE */
5284                  case 0x2006:    /* SIX-PER-EM SPACE */
5285                  case 0x2007:    /* FIGURE SPACE */
5286                  case 0x2008:    /* PUNCTUATION SPACE */
5287                  case 0x2009:    /* THIN SPACE */
5288                  case 0x200A:    /* HAIR SPACE */
5289                  case 0x202f:    /* NARROW NO-BREAK SPACE */
5290                  case 0x205f:    /* MEDIUM MATHEMATICAL SPACE */
5291                  case 0x3000:    /* IDEOGRAPHIC SPACE */
5292    #endif
5293                RRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
5294                }                }
5295              break;              break;
# Line 4999  for (;;) Line 5301  for (;;)
5301                case 0x09:      /* HT */                case 0x09:      /* HT */
5302                case 0x20:      /* SPACE */                case 0x20:      /* SPACE */
5303                case 0xa0:      /* NBSP */                case 0xa0:      /* NBSP */
5304    #ifdef COMPILE_PCRE16
5305                  case 0x1680:    /* OGHAM SPACE MARK */
5306                  case 0x180e:    /* MONGOLIAN VOWEL SEPARATOR */
5307                  case 0x2000:    /* EN QUAD */
5308                  case 0x2001:    /* EM QUAD */
5309                  case 0x2002:    /* EN SPACE */
5310                  case 0x2003:    /* EM SPACE */
5311                  case 0x2004:    /* THREE-PER-EM SPACE */
5312                  case 0x2005:    /* FOUR-PER-EM SPACE */
5313                  case 0x2006:    /* SIX-PER-EM SPACE */
5314                  case 0x2007:    /* FIGURE SPACE */
5315                  case 0x2008:    /* PUNCTUATION SPACE */
5316                  case 0x2009:    /* THIN SPACE */
5317                  case 0x200A:    /* HAIR SPACE */
5318                  case 0x202f:    /* NARROW NO-BREAK SPACE */
5319                  case 0x205f:    /* MEDIUM MATHEMATICAL SPACE */
5320                  case 0x3000:    /* IDEOGRAPHIC SPACE */
5321    #endif
5322                break;                break;
5323                }                }
5324              break;              break;
# Line 5012  for (;;) Line 5332  for (;;)
5332                case 0x0c:      /* FF */                case 0x0c:      /* FF */
5333                case 0x0d:      /* CR */                case 0x0d:      /* CR */
5334                case 0x85:      /* NEL */                case 0x85:      /* NEL */
5335    #ifdef COMPILE_PCRE16
5336                  case 0x2028:    /* LINE SEPARATOR */
5337                  case 0x2029:    /* PARAGRAPH SEPARATOR */
5338    #endif
5339                RRETURN(MATCH_NOMATCH);                RRETURN(MATCH_NOMATCH);
5340                }                }
5341              break;              break;
# Line 5025  for (;;) Line 5349  for (;;)
5349                case 0x0c:      /* FF */                case 0x0c:      /* FF */
5350                case 0x0d:      /* CR */                case 0x0d:      /* CR */
5351                case 0x85:      /* NEL */                case 0x85:      /* NEL */
5352    #ifdef COMPILE_PCRE16
5353                  case 0x2028:    /* LINE SEPARATOR */
5354                  case 0x2029:    /* PARAGRAPH SEPARATOR */
5355    #endif
5356                break;                break;
5357                }                }
5358              break;              break;
5359    
5360              case OP_NOT_DIGIT:              case OP_NOT_DIGIT:
5361              if ((md->ctypes[c] & ctype_digit) != 0) RRETURN(MATCH_NOMATCH);              if (MAX_255(c) && (md->ctypes[c] & ctype_digit) != 0) RRETURN(MATCH_NOMATCH);
5362              break;              break;
5363    
5364              case OP_DIGIT:              case OP_DIGIT:
5365              if ((md->ctypes[c] & ctype_digit) == 0) RRETURN(MATCH_NOMATCH);              if (!MAX_255(c) || (md->ctypes[c] & ctype_digit) == 0) RRETURN(MATCH_NOMATCH);
5366              break;              break;
5367    
5368              case OP_NOT_WHITESPACE:              case OP_NOT_WHITESPACE:
5369              if ((md->ctypes[c] & ctype_space) != 0) RRETURN(MATCH_NOMATCH);              if (MAX_255(c) && (md->ctypes[c] & ctype_space) != 0) RRETURN(MATCH_NOMATCH);
5370              break;              break;
5371    
5372              case OP_WHITESPACE:              case OP_WHITESPACE:
5373              if  ((md->ctypes[c] & ctype_space) == 0) RRETURN(MATCH_NOMATCH);              if (!MAX_255(c) || (md->ctypes[c] & ctype_space) == 0) RRETURN(MATCH_NOMATCH);
5374              break;              break;
5375    
5376              case OP_NOT_WORDCHAR:              case OP_NOT_WORDCHAR:
5377              if ((md->ctypes[c] & ctype_word) != 0) RRETURN(MATCH_NOMATCH);              if (MAX_255(c) && (md->ctypes[c] & ctype_word) != 0) RRETURN(MATCH_NOMATCH);
5378              break;              break;
5379    
5380              case OP_WORDCHAR:              case OP_WORDCHAR:
5381              if ((md->ctypes[c] & ctype_word) == 0) RRETURN(MATCH_NOMATCH);              if (!MAX_255(c) || (md->ctypes[c] & ctype_word) == 0) RRETURN(MATCH_NOMATCH);
5382              break;              break;
5383    
5384              default:              default:
# Line 5239  for (;;) Line 5567  for (;;)
5567            RMATCH(eptr, ecode, offset_top, md, eptrb, RM44);            RMATCH(eptr, ecode, offset_top, md, eptrb, RM44);
5568            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
5569            if (eptr-- == pp) break;        /* Stop if tried at original pos */            if (eptr-- == pp) break;        /* Stop if tried at original pos */
5570            if (utf8) BACKCHAR(eptr);            if (utf) BACKCHAR(eptr);
5571            }            }
5572          }          }
5573    
# Line 5256  for (;;) Line 5584  for (;;)
5584              SCHECK_PARTIAL();              SCHECK_PARTIAL();
5585              break;              break;
5586              }              }
5587            if (!utf8) c = *eptr; else { GETCHARLEN(c, eptr, len); }            if (!utf) c = *eptr; else { GETCHARLEN(c, eptr, len); }
5588            if (UCD_CATEGORY(c) == ucp_M) break;            if (UCD_CATEGORY(c) == ucp_M) break;
5589            eptr += len;            eptr += len;
5590            while (eptr < md->end_subject)            while (eptr < md->end_subject)
5591              {              {
5592              len = 1;              len = 1;
5593              if (!utf8) c = *eptr; else { GETCHARLEN(c, eptr, len); }              if (!utf) c = *eptr; else { GETCHARLEN(c, eptr, len); }
5594              if (UCD_CATEGORY(c) != ucp_M) break;              if (UCD_CATEGORY(c) != ucp_M) break;
5595              eptr += len;              eptr += len;
5596              }              }
5597              CHECK_PARTIAL();
5598            }            }
5599    
5600          /* eptr is now past the end of the maximum run */          /* eptr is now past the end of the maximum run */
# Line 5279  for (;;) Line 5608  for (;;)
5608            if (eptr-- == pp) break;        /* Stop if tried at original pos */            if (eptr-- == pp) break;        /* Stop if tried at original pos */
5609            for (;;)                        /* Move back over one extended */            for (;;)                        /* Move back over one extended */
5610              {              {
5611              if (!utf8) c = *eptr; else              if (!utf) c = *eptr; else
5612                {                {
5613                BACKCHAR(eptr);                BACKCHAR(eptr);
5614                GETCHAR(c, eptr);                GETCHAR(c, eptr);
# Line 5293  for (;;) Line 5622  for (;;)
5622        else        else
5623  #endif   /* SUPPORT_UCP */  #endif   /* SUPPORT_UCP */
5624    
5625  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
5626        /* UTF-8 mode */        if (utf)
   
       if (utf8)  
5627          {          {
5628          switch(ctype)          switch(ctype)
5629            {            {
# Line 5311  for (;;) Line 5638  for (;;)
5638                  break;                  break;
5639                  }                  }
5640                if (IS_NEWLINE(eptr)) break;                if (IS_NEWLINE(eptr)) break;
5641                  if (md->partial != 0 &&    /* Take care with CRLF partial */
5642                      eptr + 1 >= md->end_subject &&
5643                      NLBLOCK->nltype == NLTYPE_FIXED &&
5644                      NLBLOCK->nllen == 2 &&
5645                      *eptr == NLBLOCK->nl[0])
5646                    {
5647                    md->hitend = TRUE;
5648                    if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
5649                    }
5650                eptr++;                eptr++;
5651                while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;                ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
5652                }                }
5653              }              }
5654    
# Line 5328  for (;;) Line 5664  for (;;)
5664                  break;                  break;
5665                  }                  }
5666                if (IS_NEWLINE(eptr)) break;                if (IS_NEWLINE(eptr)) break;
5667                  if (md->partial != 0 &&    /* Take care with CRLF partial */
5668                      eptr + 1 >= md->end_subject &&
5669                      NLBLOCK->nltype == NLTYPE_FIXED &&
5670                      NLBLOCK->nllen == 2 &&
5671                      *eptr == NLBLOCK->nl[0])
5672                    {
5673                    md->hitend = TRUE;
5674                    if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
5675                    }
5676                eptr++;                eptr++;
5677                while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;                ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
5678                }                }
5679              }              }
5680            break;            break;
# Line 5345  for (;;) Line 5690  for (;;)
5690                  break;                  break;
5691                  }                  }
5692                eptr++;                eptr++;
5693                while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;                ACROSSCHAR(eptr < md->end_subject, *eptr, eptr++);
5694                }                }
5695              }              }
5696            else            else
# Line 5578  for (;;) Line 5923  for (;;)
5923            }            }
5924          }          }
5925        else        else
5926  #endif  /* SUPPORT_UTF8 */  #endif  /* SUPPORT_UTF */
5927          /* Not UTF mode */
       /* Not UTF-8 mode */  
5928          {          {
5929          switch(ctype)          switch(ctype)
5930            {            {
# Line 5593  for (;;) Line 5937  for (;;)
5937                break;                break;
5938                }                }
5939              if (IS_NEWLINE(eptr)) break;              if (IS_NEWLINE(eptr)) break;
5940                if (md->partial != 0 &&    /* Take care with CRLF partial */
5941                    eptr + 1 >= md->end_subject &&
5942                    NLBLOCK->nltype == NLTYPE_FIXED &&
5943                    NLBLOCK->nllen == 2 &&
5944                    *eptr == NLBLOCK->nl[0])
5945                  {
5946                  md->hitend = TRUE;
5947                  if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);
5948                  }
5949              eptr++;              eptr++;
5950              }              }
5951            break;            break;
# Line 5624  for (;;) Line 5977  for (;;)
5977                }                }
5978              else              else
5979                {                {
5980                if (c != 0x000a &&                if (c != 0x000a && (md->bsr_anycrlf ||
5981                    (md->bsr_anycrlf ||                  (c != 0x000b && c != 0x000c && c != 0x0085
5982                      (c != 0x000b && c != 0x000c && c != 0x0085)))  #ifdef COMPILE_PCRE16
5983                  break;                  && c != 0x2028 && c != 0x2029
5984    #endif
5985                    ))) break;
5986                eptr++;                eptr++;
5987                }                }
5988              }              }
# Line 5642  for (;;) Line 5997  for (;;)
5997                break;                break;
5998                }                }
5999              c = *eptr;              c = *eptr;
6000              if (c == 0x09 || c == 0x20 || c == 0xa0) break;              if (c == 0x09 || c == 0x20 || c == 0xa0
6001    #ifdef COMPILE_PCRE16
6002                  || c == 0x1680 || c == 0x180e || (c >= 0x2000 && c <= 0x200A)
6003                  || c == 0x202f || c == 0x205f || c == 0x3000
6004    #endif
6005                  ) break;
6006              eptr++;              eptr++;
6007              }              }
6008            break;            break;
# Line 5656  for (;;) Line 6016  for (;;)
6016                break;                break;
6017                }                }
6018              c = *eptr;              c = *eptr;
6019              if (c != 0x09 && c != 0x20 && c != 0xa0) break;              if (c != 0x09 && c != 0x20 && c != 0xa0
6020    #ifdef COMPILE_PCRE16
6021                  && c != 0x1680 && c != 0x180e && (c < 0x2000 || c > 0x200A)
6022                  && c != 0x202f && c != 0x205f && c != 0x3000
6023    #endif
6024                  ) break;
6025              eptr++;              eptr++;
6026              }              }
6027            break;            break;
# Line 5670  for (;;) Line 6035  for (;;)
6035                break;                break;
6036                }                }
6037              c = *eptr;              c = *eptr;
6038              if (c == 0x0a || c == 0x0b || c == 0x0c || c == 0x0d || c == 0x85)              if (c == 0x0a || c == 0x0b || c == 0x0c || c == 0x0d || c == 0x85
6039                break;  #ifdef COMPILE_PCRE16
6040                  || c == 0x2028 || c == 0x2029
6041    #endif
6042                  ) break;
6043              eptr++;              eptr++;
6044              }              }
6045            break;            break;
# Line 5685  for (;;) Line 6053  for (;;)
6053                break;                break;
6054                }                }
6055              c = *eptr;              c = *eptr;
6056              if (c != 0x0a && c != 0x0b && c != 0x0c && c != 0x0d && c != 0x85)              if (c != 0x0a && c != 0x0b && c != 0x0c && c != 0x0d && c != 0x85
6057                break;  #ifdef COMPILE_PCRE16
6058                  && c != 0x2028 && c != 0x2029
6059    #endif
6060                  ) break;
6061              eptr++;              eptr++;
6062              }              }
6063            break;            break;
# Line 5699  for (;;) Line 6070  for (;;)
6070                SCHECK_PARTIAL();                SCHECK_PARTIAL();
6071                break;                break;
6072                }                }
6073              if ((md->ctypes[*eptr] & ctype_digit) != 0) break;              if (MAX_255(*eptr) && (md->ctypes[*eptr] & ctype_digit) != 0) break;
6074              eptr++;              eptr++;
6075              }              }
6076            break;            break;
# Line 5712  for (;;) Line 6083  for (;;)
6083                SCHECK_PARTIAL();                SCHECK_PARTIAL();
6084                break;                break;
6085                }                }
6086              if ((md->ctypes[*eptr] & ctype_digit) == 0) break;              if (!MAX_255(*eptr) || (md->ctypes[*eptr] & ctype_digit) == 0) break;
6087              eptr++;              eptr++;
6088              }              }
6089            break;            break;
# Line 5725  for (;;) Line 6096  for (;;)
6096                SCHECK_PARTIAL();                SCHECK_PARTIAL();
6097                break;                break;
6098                }                }
6099              if ((md->ctypes[*eptr] & ctype_space) != 0) break;              if (MAX_255(*eptr) && (md->ctypes[*eptr] & ctype_space) != 0) break;
6100              eptr++;              eptr++;
6101              }              }
6102            break;            break;
# Line 5738  for (;;) Line 6109  for (;;)
6109                SCHECK_PARTIAL();                SCHECK_PARTIAL();
6110                break;                break;
6111                }                }
6112              if ((md->ctypes[*eptr] & ctype_space) == 0) break;              if (!MAX_255(*eptr) || (md->ctypes[*eptr] & ctype_space) == 0) break;
6113              eptr++;              eptr++;
6114              }              }
6115            break;            break;
# Line 5751  for (;;) Line 6122  for (;;)
6122                SCHECK_PARTIAL();                SCHECK_PARTIAL();
6123                break;                break;
6124                }                }
6125              if ((md->ctypes[*eptr] & ctype_word) != 0) break;              if (MAX_255(*eptr) && (md->ctypes[*eptr] & ctype_word) != 0) break;
6126              eptr++;              eptr++;
6127              }              }
6128            break;            break;
# Line 5764  for (;;) Line 6135  for (;;)
6135                SCHECK_PARTIAL();                SCHECK_PARTIAL();
6136                break;                break;
6137                }                }
6138              if ((md->ctypes[*eptr] & ctype_word) == 0) break;              if (!MAX_255(*eptr) || (md->ctypes[*eptr] & ctype_word) == 0) break;
6139              eptr++;              eptr++;
6140              }              }
6141            break;            break;
# Line 5827  switch (frame->Xwhere) Line 6198  switch (frame->Xwhere)
6198    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)
6199    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)
6200    LBL(65) LBL(66)    LBL(65) LBL(66)
6201  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
6202    LBL(16) LBL(18) LBL(20) LBL(21) LBL(22) LBL(23) LBL(28) LBL(30)    LBL(21)
6203    #endif
6204    #ifdef SUPPORT_UTF
6205      LBL(16) LBL(18) LBL(20)
6206      LBL(22) LBL(23) LBL(28) LBL(30)
6207    LBL(32) LBL(34) LBL(42) LBL(46)    LBL(32) LBL(34) LBL(42) LBL(46)
6208  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
6209    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)
6210    LBL(59) LBL(60) LBL(61) LBL(62)    LBL(59) LBL(60) LBL(61) LBL(62)
6211  #endif  /* SUPPORT_UCP */  #endif  /* SUPPORT_UCP */
6212  #endif  /* SUPPORT_UTF8 */  #endif  /* SUPPORT_UTF */
6213    default:    default:
6214    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));
6215    
6216    printf("+++jump error in pcre match: label %d non-existent\n", frame->Xwhere);
6217    
6218    return PCRE_ERROR_INTERNAL;    return PCRE_ERROR_INTERNAL;
6219    }    }
6220  #undef LBL  #undef LBL
# Line 5923  Returns:          > 0 => success; value Line 6301  Returns:          > 0 => success; value
6301                   < -1 => some kind of unexpected problem                   < -1 => some kind of unexpected problem
6302  */  */
6303    
6304    #ifdef COMPILE_PCRE8
6305  PCRE_EXP_DEFN int PCRE_CALL_CONVENTION  PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
6306  pcre_exec(const pcre *argument_re, const pcre_extra *extra_data,  pcre_exec(const pcre *argument_re, const pcre_extra *extra_data,
6307    PCRE_SPTR subject, int length, int start_offset, int options, int *offsets,    PCRE_SPTR subject, int length, int start_offset, int options, int *offsets,
6308    int offsetcount)    int offsetcount)
6309    #else
6310    PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
6311    pcre16_exec(const pcre16 *argument_re, const pcre16_extra *extra_data,
6312      PCRE_SPTR16 subject, int length, int start_offset, int options, int *offsets,
6313      int offsetcount)
6314    #endif
6315  {  {
6316  int rc, ocount, arg_offset_max;  int rc, ocount, arg_offset_max;
 int first_byte = -1;  
 int req_byte = -1;  
 int req_byte2 = -1;  
6317  int newline;  int newline;
6318  BOOL using_temporary_offsets = FALSE;  BOOL using_temporary_offsets = FALSE;
6319  BOOL anchored;  BOOL anchored;
6320  BOOL startline;  BOOL startline;
6321  BOOL firstline;  BOOL firstline;
6322  BOOL first_byte_caseless = FALSE;  BOOL utf;
6323  BOOL req_byte_caseless = FALSE;  BOOL has_first_char = FALSE;
6324  BOOL utf8;  BOOL has_req_char = FALSE;
6325    pcre_uchar first_char = 0;
6326    pcre_uchar first_char2 = 0;
6327    pcre_uchar req_char = 0;
6328    pcre_uchar req_char2 = 0;
6329  match_data match_block;  match_data match_block;
6330  match_data *md = &match_block;  match_data *md = &match_block;
6331  const uschar *tables;  const pcre_uint8 *tables;
6332  const uschar *start_bits = NULL;  const pcre_uint8 *start_bits = NULL;
6333  USPTR start_match = (USPTR)subject + start_offset;  PCRE_PUCHAR start_match = (PCRE_PUCHAR)subject + start_offset;
6334  USPTR end_subject;  PCRE_PUCHAR end_subject;
6335  USPTR start_partial = NULL;  PCRE_PUCHAR start_partial = NULL;
6336  USPTR req_byte_ptr = start_match - 1;  PCRE_PUCHAR req_char_ptr = start_match - 1;
6337    
 pcre_study_data internal_study;  
6338  const pcre_study_data *study;  const pcre_study_data *study;
6339    const REAL_PCRE *re = (const REAL_PCRE *)argument_re;
6340    
6341    /* Check for the special magic call that measures the size of the stack used
6342    per recursive call of match(). Without the funny casting for sizeof, a Windows
6343    compiler gave this error: "unary minus operator applied to unsigned type,
6344    result still unsigned". Hopefully the cast fixes that. */
6345    
6346  real_pcre internal_re;  if (re == NULL && extra_data == NULL && subject == NULL && length == -999 &&
6347  const real_pcre *external_re = (const real_pcre *)argument_re;      start_offset == -999)
6348  const real_pcre *re = external_re;  #ifdef NO_RECURSE
6349      return -((int)sizeof(heapframe));
6350    #else
6351      return match(NULL, NULL, NULL, 0, NULL, NULL, 0);
6352    #endif
6353    
6354  /* Plausibility checks */  /* Plausibility checks */
6355    
6356  if ((options & ~PUBLIC_EXEC_OPTIONS) != 0) return PCRE_ERROR_BADOPTION;  if ((options & ~PUBLIC_EXEC_OPTIONS) != 0) return PCRE_ERROR_BADOPTION;
6357  if (re == NULL || subject == NULL ||  if (re == NULL || subject == NULL || (offsets == NULL && offsetcount > 0))
6358     (offsets == NULL && offsetcount > 0)) return PCRE_ERROR_NULL;    return PCRE_ERROR_NULL;
6359  if (offsetcount < 0) return PCRE_ERROR_BADCOUNT;  if (offsetcount < 0) return PCRE_ERROR_BADCOUNT;
6360  if (start_offset < 0 || start_offset > length) return PCRE_ERROR_BADOFFSET;  if (start_offset < 0 || start_offset > length) return PCRE_ERROR_BADOFFSET;
6361    
6362    /* Check that the first field in the block is the magic number. If it is not,
6363    return with PCRE_ERROR_BADMAGIC. However, if the magic number is equal to
6364    REVERSED_MAGIC_NUMBER we return with PCRE_ERROR_BADENDIANNESS, which
6365    means that the pattern is likely compiled with different endianness. */
6366    
6367    if (re->magic_number != MAGIC_NUMBER)
6368      return re->magic_number == REVERSED_MAGIC_NUMBER?
6369        PCRE_ERROR_BADENDIANNESS:PCRE_ERROR_BADMAGIC;
6370    if ((re->flags & PCRE_MODE) == 0) return PCRE_ERROR_BADMODE;
6371    
6372  /* These two settings are used in the code for checking a UTF-8 string that  /* These two settings are used in the code for checking a UTF-8 string that
6373  follows immediately afterwards. Other values in the md block are used only  follows immediately afterwards. Other values in the md block are used only
6374  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,
6375  so they are set up later. */  so they are set up later. */
6376    
6377  utf8 = md->utf8 = (re->options & PCRE_UTF8) != 0;  /* PCRE_UTF16 has the same value as PCRE_UTF8. */
6378    utf = md->utf = (re->options & PCRE_UTF8) != 0;
6379  md->partial = ((options & PCRE_PARTIAL_HARD) != 0)? 2 :  md->partial = ((options & PCRE_PARTIAL_HARD) != 0)? 2 :
6380                ((options & PCRE_PARTIAL_SOFT) != 0)? 1 : 0;                ((options & PCRE_PARTIAL_SOFT) != 0)? 1 : 0;
6381    
6382  /* 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
6383  code for an invalid string if a results vector is available. */  code for an invalid string if a results vector is available. */
6384    
6385  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
6386  if (utf8 && (options & PCRE_NO_UTF8_CHECK) == 0)  if (utf && (options & PCRE_NO_UTF8_CHECK) == 0)
6387    {    {
6388    int erroroffset;    int erroroffset;
6389    int errorcode = _pcre_valid_utf8((USPTR)subject, length, &erroroffset);    int errorcode = PRIV(valid_utf)((PCRE_PUCHAR)subject, length, &erroroffset);
6390    if (errorcode != 0)    if (errorcode != 0)
6391      {      {
6392      if (offsetcount >= 2)      if (offsetcount >= 2)
# Line 5988  if (utf8 && (options & PCRE_NO_UTF8_CHEC Line 6394  if (utf8 && (options & PCRE_NO_UTF8_CHEC
6394        offsets[0] = erroroffset;        offsets[0] = erroroffset;
6395        offsets[1] = errorcode;        offsets[1] = errorcode;
6396        }        }
6397    #ifdef COMPILE_PCRE16
6398        return (errorcode <= PCRE_UTF16_ERR1 && md->partial > 1)?
6399          PCRE_ERROR_SHORTUTF16 : PCRE_ERROR_BADUTF16;
6400    #else
6401      return (errorcode <= PCRE_UTF8_ERR5 && md->partial > 1)?      return (errorcode <= PCRE_UTF8_ERR5 && md->partial > 1)?
6402        PCRE_ERROR_SHORTUTF8 : PCRE_ERROR_BADUTF8;        PCRE_ERROR_SHORTUTF8 : PCRE_ERROR_BADUTF8;
6403    #endif
6404      }      }
6405    
6406    /* 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. */
6407    if (start_offset > 0 && start_offset < length &&    if (start_offset > 0 && start_offset < length &&
6408        (((USPTR)subject)[start_offset] & 0xc0) == 0x80)        NOT_FIRSTCHAR(((PCRE_PUCHAR)subject)[start_offset]))
6409      return PCRE_ERROR_BADUTF8_OFFSET;      return PCRE_ERROR_BADUTF8_OFFSET;
6410    }    }
6411  #endif  #endif
# Line 6002  if (utf8 && (options & PCRE_NO_UTF8_CHEC Line 6413  if (utf8 && (options & PCRE_NO_UTF8_CHEC
6413  /* If the pattern was successfully studied with JIT support, run the JIT  /* If the pattern was successfully studied with JIT support, run the JIT
6414  executable instead of the rest of this function. Most options must be set at  executable instead of the rest of this function. Most options must be set at
6415  compile time for the JIT code to be usable. Fallback to the normal code path if  compile time for the JIT code to be usable. Fallback to the normal code path if
6416  an unsupported flag is set. In particular, JIT does not support partial  an unsupported flag is set. */
 matching. */  
6417    
6418  #ifdef SUPPORT_JIT  #ifdef SUPPORT_JIT
6419  if (extra_data != NULL  if (extra_data != NULL
6420      && (extra_data->flags & PCRE_EXTRA_EXECUTABLE_JIT) != 0      && (extra_data->flags & (PCRE_EXTRA_EXECUTABLE_JIT |
6421                                 PCRE_EXTRA_TABLES)) == PCRE_EXTRA_EXECUTABLE_JIT
6422      && extra_data->executable_jit != NULL      && extra_data->executable_jit != NULL
     && (extra_data->flags & PCRE_EXTRA_TABLES) == 0  
6423      && (options & ~(PCRE_NO_UTF8_CHECK | PCRE_NOTBOL | PCRE_NOTEOL |      && (options & ~(PCRE_NO_UTF8_CHECK | PCRE_NOTBOL | PCRE_NOTEOL |
6424                      PCRE_NOTEMPTY | PCRE_NOTEMPTY_ATSTART)) == 0)                      PCRE_NOTEMPTY | PCRE_NOTEMPTY_ATSTART |
6425    return _pcre_jit_exec(re, extra_data->executable_jit, subject, length,                      PCRE_PARTIAL_SOFT | PCRE_PARTIAL_HARD)) == 0)
6426      start_offset, options, ((extra_data->flags & PCRE_EXTRA_MATCH_LIMIT) == 0)    {
6427      rc = PRIV(jit_exec)(re, extra_data->executable_jit,
6428        (const pcre_uchar *)subject, length, start_offset, options,
6429        ((extra_data->flags & PCRE_EXTRA_MATCH_LIMIT) == 0)
6430      ? MATCH_LIMIT : extra_data->match_limit, offsets, offsetcount);      ? MATCH_LIMIT : extra_data->match_limit, offsets, offsetcount);
6431    
6432      /* PCRE_ERROR_NULL means that the selected normal or partial matching
6433      mode is not compiled. In this case we simply fallback to interpreter. */
6434    
6435      if (rc != PCRE_ERROR_NULL)     /* JIT was used */
6436        {
6437        ((pcre_extra *)extra_data)->flags |= PCRE_EXTRA_USED_JIT;
6438        return rc;
6439        }
6440      }
6441  #endif  #endif
6442    
6443  /* 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
6444  numbers associated with a given name, for condition testing. */  numbers associated with a given name, for condition testing. */
6445    
6446  md->name_table = (uschar *)re + re->name_table_offset;  md->name_table = (pcre_uchar *)re + re->name_table_offset;
6447  md->name_count = re->name_count;  md->name_count = re->name_count;
6448  md->name_entry_size = re->name_entry_size;  md->name_entry_size = re->name_entry_size;
6449    
# Line 6034  md->callout_data = NULL; Line 6457  md->callout_data = NULL;
6457    
6458  /* The table pointer is always in native byte order. */  /* The table pointer is always in native byte order. */
6459    
6460  tables = external_re->tables;  tables = re->tables;
6461    
6462  if (extra_data != NULL)  if (extra_data != NULL)
6463    {    {
# Line 6048  if (extra_data != NULL) Line 6471  if (extra_data != NULL)
6471    if ((flags & PCRE_EXTRA_CALLOUT_DATA) != 0)    if ((flags & PCRE_EXTRA_CALLOUT_DATA) != 0)
6472      md->callout_data = extra_data->callout_data;      md->callout_data = extra_data->callout_data;
6473    if ((flags & PCRE_EXTRA_TABLES) != 0) tables = extra_data->tables;    if ((flags & PCRE_EXTRA_TABLES) != 0) tables = extra_data->tables;
6474      ((pcre_extra *)extra_data)->flags &= ~PCRE_EXTRA_USED_JIT;   /* JIT not used */
6475    }    }
6476    
6477  /* If the exec call supplied NULL for tables, use the inbuilt ones. This  /* If the exec call supplied NULL for tables, use the inbuilt ones. This
6478  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
6479  in other programs later. */  in other programs later. */
6480    
6481  if (tables == NULL) tables = _pcre_default_tables;  if (tables == NULL) tables = PRIV(default_tables);
   
 /* Check that the first field in the block is the magic number. If it is not,  
 test for a regex that was compiled on a host of opposite endianness. If this is  
 the case, flipped values are put in internal_re and internal_study if there was  
 study data too. */  
   
 if (re->magic_number != MAGIC_NUMBER)  
   {  
   re = _pcre_try_flipped(re, &internal_re, study, &internal_study);  
   if (re == NULL) return PCRE_ERROR_BADMAGIC;  
   if (study != NULL) study = &internal_study;  
   }  
6482    
6483  /* Set up other data */  /* Set up other data */
6484    
# Line 6076  firstline = (re->options & PCRE_FIRSTLIN Line 6488  firstline = (re->options & PCRE_FIRSTLIN
6488    
6489  /* 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. */
6490    
6491  md->start_code = (const uschar *)external_re + re->name_table_offset +  md->start_code = (const pcre_uchar *)re + re->name_table_offset +
6492    re->name_count * re->name_entry_size;    re->name_count * re->name_entry_size;
6493    
6494  md->start_subject = (USPTR)subject;  md->start_subject = (PCRE_PUCHAR)subject;
6495  md->start_offset = start_offset;  md->start_offset = start_offset;
6496  md->end_subject = md->start_subject + length;  md->end_subject = md->start_subject + length;
6497  end_subject = md->end_subject;  end_subject = md->end_subject;
# Line 6104  md->recursive = NULL; Line 6516  md->recursive = NULL;
6516  md->hasthen = (re->flags & PCRE_HASTHEN) != 0;  md->hasthen = (re->flags & PCRE_HASTHEN) != 0;
6517    
6518  md->lcc = tables + lcc_offset;  md->lcc = tables + lcc_offset;
6519    md->fcc = tables + fcc_offset;
6520  md->ctypes = tables + ctypes_offset;  md->ctypes = tables + ctypes_offset;
6521    
6522  /* Handle different \R options. */  /* Handle different \R options. */
# Line 6190  arg_offset_max = (2*ocount)/3; Line 6603  arg_offset_max = (2*ocount)/3;
6603  if (re->top_backref > 0 && re->top_backref >= ocount/3)  if (re->top_backref > 0 && re->top_backref >= ocount/3)
6604    {    {
6605    ocount = re->top_backref * 3 + 3;    ocount = re->top_backref * 3 + 3;
6606    md->offset_vector = (int *)(pcre_malloc)(ocount * sizeof(int));    md->offset_vector = (int *)(PUBL(malloc))(ocount * sizeof(int));
6607    if (md->offset_vector == NULL) return PCRE_ERROR_NOMEMORY;    if (md->offset_vector == NULL) return PCRE_ERROR_NOMEMORY;
6608    using_temporary_offsets = TRUE;    using_temporary_offsets = TRUE;
6609    DPRINTF(("Got memory to hold back references\n"));    DPRINTF(("Got memory to hold back references\n"));
# Line 6217  if (md->offset_vector != NULL) Line 6630  if (md->offset_vector != NULL)
6630    md->offset_vector[0] = md->offset_vector[1] = -1;    md->offset_vector[0] = md->offset_vector[1] = -1;
6631    }    }
6632    
6633  /* 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
6634  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
6635  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
6636  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 6640  if (!anchored)
6640    {    {
6641    if ((re->flags & PCRE_FIRSTSET) != 0)    if ((re->flags & PCRE_FIRSTSET) != 0)
6642      {      {
6643      first_byte = re->first_byte & 255;      has_first_char = TRUE;
6644      if ((first_byte_caseless = ((re->first_byte & REQ_CASELESS) != 0)) == TRUE)      first_char = first_char2 = (pcre_uchar)(re->first_char);
6645        first_byte = md->lcc[first_byte];      if ((re->flags & PCRE_FCH_CASELESS) != 0)
6646          {
6647          first_char2 = TABLE_GET(first_char, md->fcc, first_char);
6648    #if defined SUPPORT_UCP && !(defined COMPILE_PCRE8)
6649          if (utf && first_char > 127)
6650            first_char2 = UCD_OTHERCASE(first_char);
6651    #endif
6652          }
6653      }      }
6654    else    else
6655      if (!startline && study != NULL &&      if (!startline && study != NULL &&
# Line 6242  character" set. */ Line 6662  character" set. */
6662    
6663  if ((re->flags & PCRE_REQCHSET) != 0)  if ((re->flags & PCRE_REQCHSET) != 0)
6664    {    {
6665    req_byte = re->req_byte & 255;    has_req_char = TRUE;
6666    req_byte_caseless = (re->req_byte & REQ_CASELESS) != 0;    req_char = req_char2 = (pcre_uchar)(re->req_char);
6667    req_byte2 = (tables + fcc_offset)[req_byte];  /* case flipped */    if ((re->flags & PCRE_RCH_CASELESS) != 0)
6668        {
6669        req_char2 = TABLE_GET(req_char, md->fcc, req_char);
6670    #if defined SUPPORT_UCP && !(defined COMPILE_PCRE8)
6671        if (utf && req_char > 127)
6672          req_char2 = UCD_OTHERCASE(req_char);
6673    #endif
6674        }
6675    }    }
6676    
6677    
   
   
6678  /* ==========================================================================*/  /* ==========================================================================*/
6679    
6680  /* 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 6682  the loop runs just once. */
6682    
6683  for(;;)  for(;;)
6684    {    {
6685    USPTR save_end_subject = end_subject;    PCRE_PUCHAR save_end_subject = end_subject;
6686    USPTR new_start_match;    PCRE_PUCHAR new_start_match;
6687    
6688    /* 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
6689    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 6693  for(;;)
6693    
6694    if (firstline)    if (firstline)
6695      {      {
6696      USPTR t = start_match;      PCRE_PUCHAR t = start_match;
6697  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
6698      if (utf8)      if (utf)
6699        {        {
6700        while (t < md->end_subject && !IS_NEWLINE(t))        while (t < md->end_subject && !IS_NEWLINE(t))
6701          {          {
6702          t++;          t++;
6703          while (t < end_subject && (*t & 0xc0) == 0x80) t++;          ACROSSCHAR(t < end_subject, *t, t++);
6704          }          }
6705        }        }
6706      else      else
# Line 6292  for(;;) Line 6717  for(;;)
6717    
6718    if (((options | re->options) & PCRE_NO_START_OPTIMIZE) == 0)    if (((options | re->options) & PCRE_NO_START_OPTIMIZE) == 0)
6719      {      {
6720      /* Advance to a unique first byte if there is one. */      /* Advance to a unique first char if there is one. */
6721    
6722      if (first_byte >= 0)      if (has_first_char)
6723        {        {
6724        if (first_byte_caseless)        if (first_char != first_char2)
6725          while (start_match < end_subject && md->lcc[*start_match] != first_byte)          while (start_match < end_subject &&
6726                *start_match != first_char && *start_match != first_char2)
6727            start_match++;            start_match++;
6728        else        else
6729          while (start_match < end_subject && *start_match != first_byte)          while (start_match < end_subject && *start_match != first_char)
6730            start_match++;            start_match++;
6731        }        }
6732    
# Line 6310  for(;;) Line 6736  for(;;)
6736        {        {
6737        if (start_match > md->start_subject + start_offset)        if (start_match > md->start_subject + start_offset)
6738          {          {
6739  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
6740          if (utf8)          if (utf)
6741            {            {
6742            while (start_match < end_subject && !WAS_NEWLINE(start_match))            while (start_match < end_subject && !WAS_NEWLINE(start_match))
6743              {              {
6744              start_match++;              start_match++;
6745              while(start_match < end_subject && (*start_match & 0xc0) == 0x80)              ACROSSCHAR(start_match < end_subject, *start_match,
6746                start_match++;                start_match++);
6747              }              }
6748            }            }
6749          else          else
# Line 6344  for(;;) Line 6770  for(;;)
6770        while (start_match < end_subject)        while (start_match < end_subject)
6771          {          {
6772          register unsigned int c = *start_match;          register unsigned int c = *start_match;
6773    #ifndef COMPILE_PCRE8
6774            if (c > 255) c = 255;
6775    #endif
6776          if ((start_bits[c/8] & (1 << (c&7))) == 0)          if ((start_bits[c/8] & (1 << (c&7))) == 0)
6777            {            {
6778            start_match++;            start_match++;
6779  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF && defined COMPILE_PCRE8
6780            if (utf8)            /* In non 8-bit mode, the iteration will stop for
6781              while(start_match < end_subject && (*start_match & 0xc0) == 0x80)            characters > 255 at the beginning or not stop at all. */
6782                start_match++;            if (utf)
6783                ACROSSCHAR(start_match < end_subject, *start_match,
6784                  start_match++);
6785  #endif  #endif
6786            }            }
6787          else break;          else break;
# Line 6379  for(;;) Line 6810  for(;;)
6810        break;        break;
6811        }        }
6812    
6813      /* 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
6814      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
6815      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.
6816      This optimization can save a huge amount of backtracking in patterns with      This optimization can save a huge amount of backtracking in patterns with
6817      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 6824  for(;;)
6824      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
6825      long. */      long. */
6826    
6827      if (req_byte >= 0 && end_subject - start_match < REQ_BYTE_MAX)      if (has_req_char && end_subject - start_match < REQ_BYTE_MAX)
6828        {        {
6829        register USPTR p = start_match + ((first_byte >= 0)? 1 : 0);        register PCRE_PUCHAR p = start_match + (has_first_char? 1:0);
6830    
6831        /* 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
6832        place we found it at last time. */        place we found it at last time. */
6833    
6834        if (p > req_byte_ptr)        if (p > req_char_ptr)
6835          {          {
6836          if (req_byte_caseless)          if (req_char != req_char2)
6837            {            {
6838            while (p < end_subject)            while (p < end_subject)
6839              {              {
6840              register int pp = *p++;              register int pp = *p++;
6841              if (pp == req_byte || pp == req_byte2) { p--; break; }              if (pp == req_char || pp == req_char2) { p--; break; }
6842              }              }
6843            }            }
6844          else          else
6845            {            {
6846            while (p < end_subject)            while (p < end_subject)
6847              {              {
6848              if (*p++ == req_byte) { p--; break; }              if (*p++ == req_char) { p--; break; }
6849              }              }
6850            }            }
6851    
# Line 6431  for(;;) Line 6862  for(;;)
6862          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
6863          the start hasn't passed this character yet. */          the start hasn't passed this character yet. */
6864    
6865          req_byte_ptr = p;          req_char_ptr = p;
6866          }          }
6867        }        }
6868      }      }
# Line 6456  for(;;) Line 6887  for(;;)
6887    switch(rc)    switch(rc)
6888      {      {
6889      /* 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
6890      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
6891      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
6892      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
6893      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
6894      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. */
6895    
6896      case MATCH_SKIP_ARG:      case MATCH_SKIP_ARG:
6897      new_start_match = start_match;      new_start_match = start_match;
6898      md->ignore_skip_arg = TRUE;      md->ignore_skip_arg = TRUE;
6899      break;      break;
6900    
6901      /* 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
6902      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 6917  for(;;)
6917      case MATCH_THEN:      case MATCH_THEN:
6918      md->ignore_skip_arg = FALSE;      md->ignore_skip_arg = FALSE;
6919      new_start_match = start_match + 1;      new_start_match = start_match + 1;
6920  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
6921      if (utf8)      if (utf)
6922        while(new_start_match < end_subject && (*new_start_match & 0xc0) == 0x80)        ACROSSCHAR(new_start_match < end_subject, *new_start_match,
6923          new_start_match++;          new_start_match++);
6924  #endif  #endif
6925      break;      break;
6926    
# Line 6527  for(;;) Line 6958  for(;;)
6958    
6959    /* 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
6960    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
6961    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
6962      normal matching start_match will aways be greater than the first position at
6963      this stage, but a failed *SKIP can cause a return at the same point, which is
6964      why the first test exists. */
6965    
6966    if (start_match[-1] == CHAR_CR &&    if (start_match > (PCRE_PUCHAR)subject + start_offset &&
6967          start_match[-1] == CHAR_CR &&
6968        start_match < end_subject &&        start_match < end_subject &&
6969        *start_match == CHAR_NL &&        *start_match == CHAR_NL &&
6970        (re->flags & PCRE_HASCRORLF) == 0 &&        (re->flags & PCRE_HASCRORLF) == 0 &&
# Line 6575  if (rc == MATCH_MATCH || rc == MATCH_ACC Line 7010  if (rc == MATCH_MATCH || rc == MATCH_ACC
7010        }        }
7011      if (md->end_offset_top > arg_offset_max) md->offset_overflow = TRUE;      if (md->end_offset_top > arg_offset_max) md->offset_overflow = TRUE;
7012      DPRINTF(("Freeing temporary memory\n"));      DPRINTF(("Freeing temporary memory\n"));
7013      (pcre_free)(md->offset_vector);      (PUBL(free))(md->offset_vector);
7014      }      }
7015    
7016    /* 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 7049  if (rc == MATCH_MATCH || rc == MATCH_ACC
7049      }      }
7050    
7051    /* Return MARK data if requested */    /* Return MARK data if requested */
7052    
7053    if (extra_data != NULL && (extra_data->flags & PCRE_EXTRA_MARK) != 0)    if (extra_data != NULL && (extra_data->flags & PCRE_EXTRA_MARK) != 0)
7054      *(extra_data->mark) = (unsigned char *)(md->mark);      *(extra_data->mark) = (pcre_uchar *)md->mark;
7055    DPRINTF((">>>> returning %d\n", rc));    DPRINTF((">>>> returning %d\n", rc));
7056    return rc;    return rc;
7057    }    }
# Line 6627  attempt has failed at all permitted star Line 7062  attempt has failed at all permitted star
7062  if (using_temporary_offsets)  if (using_temporary_offsets)
7063    {    {
7064    DPRINTF(("Freeing temporary memory\n"));    DPRINTF(("Freeing temporary memory\n"));
7065    (pcre_free)(md->offset_vector);    (PUBL(free))(md->offset_vector);
7066    }    }
7067    
7068  /* 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 7081  if (start_partial != NULL)
7081    md->mark = NULL;    md->mark = NULL;
7082    if (offsetcount > 1)    if (offsetcount > 1)
7083      {      {
7084      offsets[0] = (int)(start_partial - (USPTR)subject);      offsets[0] = (int)(start_partial - (PCRE_PUCHAR)subject);
7085      offsets[1] = (int)(end_subject - (USPTR)subject);      offsets[1] = (int)(end_subject - (PCRE_PUCHAR)subject);
7086      }      }
7087    rc = PCRE_ERROR_PARTIAL;    rc = PCRE_ERROR_PARTIAL;
7088    }    }
# Line 6663  else Line 7098  else
7098  /* Return the MARK data if it has been requested. */  /* Return the MARK data if it has been requested. */
7099    
7100  if (extra_data != NULL && (extra_data->flags & PCRE_EXTRA_MARK) != 0)  if (extra_data != NULL && (extra_data->flags & PCRE_EXTRA_MARK) != 0)
7101    *(extra_data->mark) = (unsigned char *)(md->nomatch_mark);    *(extra_data->mark) = (pcre_uchar *)md->nomatch_mark;
7102  return rc;  return rc;
7103  }  }
7104    

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

  ViewVC Help
Powered by ViewVC 1.1.5