/[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 144 by ph10, Mon Apr 2 13:32:07 2007 UTC revision 527 by ph10, Sat May 29 15:50:39 2010 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-2007 University of Cambridge             Copyright (c) 1997-2010 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 42  POSSIBILITY OF SUCH DAMAGE. Line 42  POSSIBILITY OF SUCH DAMAGE.
42  pattern matching using an NFA algorithm, trying to mimic Perl as closely as  pattern matching using an NFA algorithm, trying to mimic Perl as closely as
43  possible. There are also some static supporting functions. */  possible. There are also some static supporting functions. */
44    
45    #ifdef HAVE_CONFIG_H
46    #include "config.h"
47    #endif
48    
49  #define NLBLOCK md             /* Block containing newline information */  #define NLBLOCK md             /* Block containing newline information */
50  #define PSSTART start_subject  /* Field containing processed string start */  #define PSSTART start_subject  /* Field containing processed string start */
51  #define PSEND   end_subject    /* Field containing processed string end */  #define PSEND   end_subject    /* Field containing processed string end */
# Line 53  possible. There are also some static sup Line 57  possible. There are also some static sup
57  #undef min  #undef min
58  #undef max  #undef max
59    
 /* The chain of eptrblocks for tail recursions uses memory in stack workspace,  
 obtained at top level, the size of which is defined by EPTR_WORK_SIZE. */  
   
 #define EPTR_WORK_SIZE (1000)  
   
60  /* Flag bits for the match() function */  /* Flag bits for the match() function */
61    
62  #define match_condassert     0x01  /* Called to check a condition assertion */  #define match_condassert     0x01  /* Called to check a condition assertion */
63  #define match_cbegroup       0x02  /* Could-be-empty unlimited repeat group */  #define match_cbegroup       0x02  /* Could-be-empty unlimited repeat group */
 #define match_tail_recursed  0x04  /* Tail recursive call */  
64    
65  /* Non-error returns from the match() function. Error returns are externally  /* Non-error returns from the match() function. Error returns are externally
66  defined PCRE_ERROR_xxx codes, which are all negative. */  defined PCRE_ERROR_xxx codes, which are all negative. */
# Line 70  defined PCRE_ERROR_xxx codes, which are Line 68  defined PCRE_ERROR_xxx codes, which are
68  #define MATCH_MATCH        1  #define MATCH_MATCH        1
69  #define MATCH_NOMATCH      0  #define MATCH_NOMATCH      0
70    
71    /* Special internal returns from the match() function. Make them sufficiently
72    negative to avoid the external error codes. */
73    
74    #define MATCH_ACCEPT       (-999)
75    #define MATCH_COMMIT       (-998)
76    #define MATCH_PRUNE        (-997)
77    #define MATCH_SKIP         (-996)
78    #define MATCH_SKIP_ARG     (-995)
79    #define MATCH_THEN         (-994)
80    
81    /* This is a convenience macro for code that occurs many times. */
82    
83    #define MRRETURN(ra) \
84      { \
85      md->mark = markptr; \
86      RRETURN(ra); \
87      }
88    
89  /* Maximum number of ints of offset to save on the stack for recursive calls.  /* Maximum number of ints of offset to save on the stack for recursive calls.
90  If the offset vector is bigger, malloc is used. This should be a multiple of 3,  If the offset vector is bigger, malloc is used. This should be a multiple of 3,
91  because the offset vector is always a multiple of 3 long. */  because the offset vector is always a multiple of 3 long. */
# Line 83  static const char rep_max[] = { 0, 0, 0, Line 99  static const char rep_max[] = { 0, 0, 0,
99    
100    
101    
102  #ifdef DEBUG  #ifdef PCRE_DEBUG
103  /*************************************************  /*************************************************
104  *        Debugging function to print chars       *  *        Debugging function to print chars       *
105  *************************************************/  *************************************************/
# Line 135  match_ref(int offset, register USPTR ept Line 151  match_ref(int offset, register USPTR ept
151  {  {
152  USPTR p = md->start_subject + md->offset_vector[offset];  USPTR p = md->start_subject + md->offset_vector[offset];
153    
154  #ifdef DEBUG  #ifdef PCRE_DEBUG
155  if (eptr >= md->end_subject)  if (eptr >= md->end_subject)
156    printf("matching subject <null>");    printf("matching subject <null>");
157  else  else
# Line 152  printf("\n"); Line 168  printf("\n");
168    
169  if (length > md->end_subject - eptr) return FALSE;  if (length > md->end_subject - eptr) return FALSE;
170    
171  /* Separate the caselesss case for speed */  /* Separate the caseless case for speed. In UTF-8 mode we can only do this
172    properly if Unicode properties are supported. Otherwise, we can check only
173    ASCII characters. */
174    
175  if ((ims & PCRE_CASELESS) != 0)  if ((ims & PCRE_CASELESS) != 0)
176    {    {
177    #ifdef SUPPORT_UTF8
178    #ifdef SUPPORT_UCP
179      if (md->utf8)
180        {
181        USPTR endptr = eptr + length;
182        while (eptr < endptr)
183          {
184          int c, d;
185          GETCHARINC(c, eptr);
186          GETCHARINC(d, p);
187          if (c != d && c != UCD_OTHERCASE(d)) return FALSE;
188          }
189        }
190      else
191    #endif
192    #endif
193    
194      /* The same code works when not in UTF-8 mode and in UTF-8 mode when there
195      is no UCP support. */
196    
197    while (length-- > 0)    while (length-- > 0)
198      if (md->lcc[*p++] != md->lcc[*eptr++]) return FALSE;      { if (md->lcc[*p++] != md->lcc[*eptr++]) return FALSE; }
199    }    }
200    
201    /* In the caseful case, we can just compare the bytes, whether or not we
202    are in UTF-8 mode. */
203    
204  else  else
205    { while (length-- > 0) if (*p++ != *eptr++) return FALSE; }    { while (length-- > 0) if (*p++ != *eptr++) return FALSE; }
206    
# Line 188  calls by keeping local variables that ne Line 230  calls by keeping local variables that ne
230  obtained from malloc() instead instead of on the stack. Macros are used to  obtained from malloc() instead instead of on the stack. Macros are used to
231  achieve this so that the actual code doesn't look very different to what it  achieve this so that the actual code doesn't look very different to what it
232  always used to.  always used to.
233    
234    The original heap-recursive code used longjmp(). However, it seems that this
235    can be very slow on some operating systems. Following a suggestion from Stan
236    Switzer, the use of longjmp() has been abolished, at the cost of having to
237    provide a unique number for each call to RMATCH. There is no way of generating
238    a sequence of numbers at compile time in C. I have given them names, to make
239    them stand out more clearly.
240    
241    Crude tests on x86 Linux show a small speedup of around 5-8%. However, on
242    FreeBSD, avoiding longjmp() more than halves the time taken to run the standard
243    tests. Furthermore, not using longjmp() means that local dynamic variables
244    don't have indeterminate values; this has meant that the frame size can be
245    reduced because the result can be "passed back" by straight setting of the
246    variable instead of being passed in the frame.
247  ****************************************************************************  ****************************************************************************
248  ***************************************************************************/  ***************************************************************************/
249    
250    /* Numbers for RMATCH calls. When this list is changed, the code at HEAP_RETURN
251    below must be updated in sync.  */
252    
253    enum { RM1=1, RM2,  RM3,  RM4,  RM5,  RM6,  RM7,  RM8,  RM9,  RM10,
254           RM11,  RM12, RM13, RM14, RM15, RM16, RM17, RM18, RM19, RM20,
255           RM21,  RM22, RM23, RM24, RM25, RM26, RM27, RM28, RM29, RM30,
256           RM31,  RM32, RM33, RM34, RM35, RM36, RM37, RM38, RM39, RM40,
257           RM41,  RM42, RM43, RM44, RM45, RM46, RM47, RM48, RM49, RM50,
258           RM51,  RM52, RM53, RM54, RM55, RM56, RM57, RM58, RM59, RM60,
259           RM61,  RM62 };
260    
261  /* These versions of the macros use the stack, as normal. There are debugging  /* These versions of the macros use the stack, as normal. There are debugging
262  versions and production versions. */  versions and production versions. Note that the "rw" argument of RMATCH isn't
263    actually used in this definition. */
264    
265  #ifndef NO_RECURSE  #ifndef NO_RECURSE
266  #define REGISTER register  #define REGISTER register
267  #ifdef DEBUG  
268  #define RMATCH(rx,ra,rb,rc,rd,re,rf,rg) \  #ifdef PCRE_DEBUG
269    #define RMATCH(ra,rb,rc,rd,re,rf,rg,rw) \
270    { \    { \
271    printf("match() called in line %d\n", __LINE__); \    printf("match() called in line %d\n", __LINE__); \
272    rx = match(ra,rb,rc,rd,re,rf,rg,rdepth+1); \    rrc = match(ra,rb,mstart,markptr,rc,rd,re,rf,rg,rdepth+1); \
273    printf("to line %d\n", __LINE__); \    printf("to line %d\n", __LINE__); \
274    }    }
275  #define RRETURN(ra) \  #define RRETURN(ra) \
# Line 210  versions and production versions. */ Line 278  versions and production versions. */
278    return ra; \    return ra; \
279    }    }
280  #else  #else
281  #define RMATCH(rx,ra,rb,rc,rd,re,rf,rg) \  #define RMATCH(ra,rb,rc,rd,re,rf,rg,rw) \
282    rx = match(ra,rb,rc,rd,re,rf,rg,rdepth+1)    rrc = match(ra,rb,mstart,markptr,rc,rd,re,rf,rg,rdepth+1)
283  #define RRETURN(ra) return ra  #define RRETURN(ra) return ra
284  #endif  #endif
285    
286  #else  #else
287    
288    
289  /* These versions of the macros manage a private stack on the heap. Note  /* These versions of the macros manage a private stack on the heap. Note that
290  that the rd argument of RMATCH isn't actually used. It's the md argument of  the "rd" argument of RMATCH isn't actually used in this definition. It's the md
291  match(), which never changes. */  argument of match(), which never changes. */
292    
293  #define REGISTER  #define REGISTER
294    
295  #define RMATCH(rx,ra,rb,rc,rd,re,rf,rg)\  #define RMATCH(ra,rb,rc,rd,re,rf,rg,rw)\
296    {\    {\
297    heapframe *newframe = (pcre_stack_malloc)(sizeof(heapframe));\    heapframe *newframe = (pcre_stack_malloc)(sizeof(heapframe));\
298    if (setjmp(frame->Xwhere) == 0)\    frame->Xwhere = rw; \
299      {\    newframe->Xeptr = ra;\
300      newframe->Xeptr = ra;\    newframe->Xecode = rb;\
301      newframe->Xecode = rb;\    newframe->Xmstart = mstart;\
302      newframe->Xoffset_top = rc;\    newframe->Xmarkptr = markptr;\
303      newframe->Xims = re;\    newframe->Xoffset_top = rc;\
304      newframe->Xeptrb = rf;\    newframe->Xims = re;\
305      newframe->Xflags = rg;\    newframe->Xeptrb = rf;\
306      newframe->Xrdepth = frame->Xrdepth + 1;\    newframe->Xflags = rg;\
307      newframe->Xprevframe = frame;\    newframe->Xrdepth = frame->Xrdepth + 1;\
308      frame = newframe;\    newframe->Xprevframe = frame;\
309      DPRINTF(("restarting from line %d\n", __LINE__));\    frame = newframe;\
310      goto HEAP_RECURSE;\    DPRINTF(("restarting from line %d\n", __LINE__));\
311      }\    goto HEAP_RECURSE;\
312    else\    L_##rw:\
313      {\    DPRINTF(("jumped back to line %d\n", __LINE__));\
     DPRINTF(("longjumped back to line %d\n", __LINE__));\  
     frame = md->thisframe;\  
     rx = frame->Xresult;\  
     }\  
314    }    }
315    
316  #define RRETURN(ra)\  #define RRETURN(ra)\
317    {\    {\
318    heapframe *newframe = frame;\    heapframe *oldframe = frame;\
319    frame = newframe->Xprevframe;\    frame = oldframe->Xprevframe;\
320    (pcre_stack_free)(newframe);\    (pcre_stack_free)(oldframe);\
321    if (frame != NULL)\    if (frame != NULL)\
322      {\      {\
323      frame->Xresult = ra;\      rrc = ra;\
324      md->thisframe = frame;\      goto HEAP_RETURN;\
     longjmp(frame->Xwhere, 1);\  
325      }\      }\
326    return ra;\    return ra;\
327    }    }
# Line 271  typedef struct heapframe { Line 334  typedef struct heapframe {
334    
335    /* Function arguments that may change */    /* Function arguments that may change */
336    
337    const uschar *Xeptr;    USPTR Xeptr;
338    const uschar *Xecode;    const uschar *Xecode;
339      USPTR Xmstart;
340      USPTR Xmarkptr;
341    int Xoffset_top;    int Xoffset_top;
342    long int Xims;    long int Xims;
343    eptrblock *Xeptrb;    eptrblock *Xeptrb;
# Line 281  typedef struct heapframe { Line 346  typedef struct heapframe {
346    
347    /* Function local variables */    /* Function local variables */
348    
349    const uschar *Xcallpat;    USPTR Xcallpat;
350    const uschar *Xcharptr;  #ifdef SUPPORT_UTF8
351    const uschar *Xdata;    USPTR Xcharptr;
352    const uschar *Xnext;  #endif
353    const uschar *Xpp;    USPTR Xdata;
354    const uschar *Xprev;    USPTR Xnext;
355    const uschar *Xsaved_eptr;    USPTR Xpp;
356      USPTR Xprev;
357      USPTR Xsaved_eptr;
358    
359    recursion_info Xnew_recursive;    recursion_info Xnew_recursive;
360    
# Line 308  typedef struct heapframe { Line 375  typedef struct heapframe {
375    uschar Xocchars[8];    uschar Xocchars[8];
376  #endif  #endif
377    
378      int Xcodelink;
379    int Xctype;    int Xctype;
380    unsigned int Xfc;    unsigned int Xfc;
381    int Xfi;    int Xfi;
# Line 323  typedef struct heapframe { Line 391  typedef struct heapframe {
391    
392    eptrblock Xnewptrb;    eptrblock Xnewptrb;
393    
394    /* Place to pass back result, and where to jump back to */    /* Where to jump back to */
395    
396    int  Xresult;    int Xwhere;
   jmp_buf Xwhere;  
397    
398  } heapframe;  } heapframe;
399    
# Line 344  typedef struct heapframe { Line 411  typedef struct heapframe {
411    
412  /* This function is called recursively in many circumstances. Whenever it  /* This function is called recursively in many circumstances. Whenever it
413  returns a negative (error) response, the outer incarnation must also return the  returns a negative (error) response, the outer incarnation must also return the
414  same response.  same response. */
415    
416  Performance note: It might be tempting to extract commonly used fields from the  /* These macros pack up tests that are used for partial matching, and which
417  md structure (e.g. utf8, end_subject) into individual variables to improve  appears several times in the code. We set the "hit end" flag if the pointer is
418    at the end of the subject and also past the start of the subject (i.e.
419    something has been matched). For hard partial matching, we then return
420    immediately. The second one is used when we already know we are past the end of
421    the subject. */
422    
423    #define CHECK_PARTIAL()\
424      if (md->partial != 0 && eptr >= md->end_subject && eptr > mstart)\
425        {\
426        md->hitend = TRUE;\
427        if (md->partial > 1) MRRETURN(PCRE_ERROR_PARTIAL);\
428        }
429    
430    #define SCHECK_PARTIAL()\
431      if (md->partial != 0 && eptr > mstart)\
432        {\
433        md->hitend = TRUE;\
434        if (md->partial > 1) MRRETURN(PCRE_ERROR_PARTIAL);\
435        }
436    
437    
438    /* Performance note: It might be tempting to extract commonly used fields from
439    the md structure (e.g. utf8, end_subject) into individual variables to improve
440  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
441  made performance worse.  made performance worse.
442    
443  Arguments:  Arguments:
444     eptr        pointer to current character in subject     eptr        pointer to current character in subject
445     ecode       pointer to current position in compiled code     ecode       pointer to current position in compiled code
446       mstart      pointer to the current match start position (can be modified
447                     by encountering \K)
448       markptr     pointer to the most recent MARK name, or NULL
449     offset_top  current top pointer     offset_top  current top pointer
450     md          pointer to "static" info for the match     md          pointer to "static" info for the match
451     ims         current /i, /m, and /s options     ims         current /i, /m, and /s options
# Line 363  Arguments: Line 455  Arguments:
455                   match_condassert - this is an assertion condition                   match_condassert - this is an assertion condition
456                   match_cbegroup - this is the start of an unlimited repeat                   match_cbegroup - this is the start of an unlimited repeat
457                     group that can match an empty string                     group that can match an empty string
                  match_tail_recursed - this is a tail_recursed group  
458     rdepth      the recursion depth     rdepth      the recursion depth
459    
460  Returns:       MATCH_MATCH if matched            )  these values are >= 0  Returns:       MATCH_MATCH if matched            )  these values are >= 0
461                 MATCH_NOMATCH if failed to match  )                 MATCH_NOMATCH if failed to match  )
462                   a negative MATCH_xxx value for PRUNE, SKIP, etc
463                 a negative PCRE_ERROR_xxx value if aborted by an error condition                 a negative PCRE_ERROR_xxx value if aborted by an error condition
464                   (e.g. stopped by repeated call or recursion limit)                   (e.g. stopped by repeated call or recursion limit)
465  */  */
466    
467  static int  static int
468  match(REGISTER USPTR eptr, REGISTER const uschar *ecode,  match(REGISTER USPTR eptr, REGISTER const uschar *ecode, USPTR mstart,
469    int offset_top, match_data *md, unsigned long int ims, eptrblock *eptrb,    const uschar *markptr, int offset_top, match_data *md, unsigned long int ims,
470    int flags, unsigned int rdepth)    eptrblock *eptrb, int flags, unsigned int rdepth)
471  {  {
472  /* 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,
473  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 387  register unsigned int c;   /* Character Line 479  register unsigned int c;   /* Character
479  register BOOL utf8;        /* Local copy of UTF-8 flag for speed */  register BOOL utf8;        /* Local copy of UTF-8 flag for speed */
480    
481  BOOL minimize, possessive; /* Quantifier options */  BOOL minimize, possessive; /* Quantifier options */
482    int condcode;
483    
484  /* 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
485  preserved over calls to RMATCH() are part of a "frame" which is obtained from  preserved over calls to RMATCH() are part of a "frame" which is obtained from
# Line 401  frame->Xprevframe = NULL;            /* Line 494  frame->Xprevframe = NULL;            /*
494    
495  frame->Xeptr = eptr;  frame->Xeptr = eptr;
496  frame->Xecode = ecode;  frame->Xecode = ecode;
497    frame->Xmstart = mstart;
498    frame->Xmarkptr = markptr;
499  frame->Xoffset_top = offset_top;  frame->Xoffset_top = offset_top;
500  frame->Xims = ims;  frame->Xims = ims;
501  frame->Xeptrb = eptrb;  frame->Xeptrb = eptrb;
# Line 415  HEAP_RECURSE: Line 510  HEAP_RECURSE:
510    
511  #define eptr               frame->Xeptr  #define eptr               frame->Xeptr
512  #define ecode              frame->Xecode  #define ecode              frame->Xecode
513    #define mstart             frame->Xmstart
514    #define markptr            frame->Xmarkptr
515  #define offset_top         frame->Xoffset_top  #define offset_top         frame->Xoffset_top
516  #define ims                frame->Xims  #define ims                frame->Xims
517  #define eptrb              frame->Xeptrb  #define eptrb              frame->Xeptrb
# Line 427  HEAP_RECURSE: Line 524  HEAP_RECURSE:
524  #define charptr            frame->Xcharptr  #define charptr            frame->Xcharptr
525  #endif  #endif
526  #define callpat            frame->Xcallpat  #define callpat            frame->Xcallpat
527    #define codelink           frame->Xcodelink
528  #define data               frame->Xdata  #define data               frame->Xdata
529  #define next               frame->Xnext  #define next               frame->Xnext
530  #define pp                 frame->Xpp  #define pp                 frame->Xpp
# Line 507  int oclength; Line 605  int oclength;
605  uschar occhars[8];  uschar occhars[8];
606  #endif  #endif
607    
608    int codelink;
609  int ctype;  int ctype;
610  int length;  int length;
611  int max;  int max;
# Line 540  TAIL_RECURSE: Line 639  TAIL_RECURSE:
639  /* OK, now we can get on with the real code of the function. Recursive calls  /* OK, now we can get on with the real code of the function. Recursive calls
640  are specified by the macro RMATCH and RRETURN is used to return. When  are specified by the macro RMATCH and RRETURN is used to return. When
641  NO_RECURSE is *not* defined, these just turn into a recursive call to match()  NO_RECURSE is *not* defined, these just turn into a recursive call to match()
642  and a "return", respectively (possibly with some debugging if DEBUG is  and a "return", respectively (possibly with some debugging if PCRE_DEBUG is
643  defined). However, RMATCH isn't like a function call because it's quite a  defined). However, RMATCH isn't like a function call because it's quite a
644  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,
645  however, impact performance when true recursion is being used. */  however, impact performance when true recursion is being used. */
646    
647    #ifdef SUPPORT_UTF8
648    utf8 = md->utf8;       /* Local copy of the flag */
649    #else
650    utf8 = FALSE;
651    #endif
652    
653  /* 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
654  haven't exceeded the recursive call limit. */  haven't exceeded the recursive call limit. */
655    
# Line 553  if (rdepth >= md->match_limit_recursion) Line 658  if (rdepth >= md->match_limit_recursion)
658    
659  original_ims = ims;    /* Save for resetting on ')' */  original_ims = ims;    /* Save for resetting on ')' */
660    
 #ifdef SUPPORT_UTF8  
 utf8 = md->utf8;       /* Local copy of the flag */  
 #else  
 utf8 = FALSE;  
 #endif  
   
661  /* At the start of a group with an unlimited repeat that may match an empty  /* At the start of a group with an unlimited repeat that may match an empty
662  string, the match_cbegroup flag is set. When this is the case, add the current  string, the match_cbegroup flag is set. When this is the case, add the current
663  subject pointer to the chain of such remembered pointers, to be checked when we  subject pointer to the chain of such remembered pointers, to be checked when we
664  hit the closing ket, in order to break infinite loops that match no characters.  hit the closing ket, in order to break infinite loops that match no characters.
665  When match() is called in other circumstances, don't add to the chain. If this  When match() is called in other circumstances, don't add to the chain. The
666  is a tail recursion, use a block from the workspace, as the one on the stack is  match_cbegroup flag must NOT be used with tail recursion, because the memory
667  already used. */  block that is used is on the stack, so a new one may be required for each
668    match(). */
669    
670  if ((flags & match_cbegroup) != 0)  if ((flags & match_cbegroup) != 0)
671    {    {
672    eptrblock *p;    newptrb.epb_saved_eptr = eptr;
673    if ((flags & match_tail_recursed) != 0)    newptrb.epb_prev = eptrb;
674      {    eptrb = &newptrb;
     if (md->eptrn >= EPTR_WORK_SIZE) RRETURN(PCRE_ERROR_NULLWSLIMIT);  
     p = md->eptrchain + md->eptrn++;  
     }  
   else p = &newptrb;  
   p->epb_saved_eptr = eptr;  
   p->epb_prev = eptrb;  
   eptrb = p;  
675    }    }
676    
677  /* Now start processing the opcodes. */  /* Now start processing the opcodes. */
# Line 588  for (;;) Line 681  for (;;)
681    minimize = possessive = FALSE;    minimize = possessive = FALSE;
682    op = *ecode;    op = *ecode;
683    
   /* For partial matching, remember if we ever hit the end of the subject after  
   matching at least one subject character. */  
   
   if (md->partial &&  
       eptr >= md->end_subject &&  
       eptr > md->start_match)  
     md->hitend = TRUE;  
   
684    switch(op)    switch(op)
685      {      {
686        case OP_MARK:
687        markptr = ecode + 2;
688        RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode] + ecode[1], offset_top, md,
689          ims, eptrb, flags, RM55);
690    
691        /* A return of MATCH_SKIP_ARG means that matching failed at SKIP with an
692        argument, and we must check whether that argument matches this MARK's
693        argument. It is passed back in md->start_match_ptr (an overloading of that
694        variable). If it does match, we reset that variable to the current subject
695        position and return MATCH_SKIP. Otherwise, pass back the return code
696        unaltered. */
697    
698        if (rrc == MATCH_SKIP_ARG &&
699            strcmp((char *)markptr, (char *)(md->start_match_ptr)) == 0)
700          {
701          md->start_match_ptr = eptr;
702          RRETURN(MATCH_SKIP);
703          }
704    
705        if (md->mark == NULL) md->mark = markptr;
706        RRETURN(rrc);
707    
708        case OP_FAIL:
709        MRRETURN(MATCH_NOMATCH);
710    
711        case OP_COMMIT:
712        RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,
713          ims, eptrb, flags, RM52);
714        if (rrc != MATCH_NOMATCH) RRETURN(rrc);
715        MRRETURN(MATCH_COMMIT);
716    
717        case OP_PRUNE:
718        RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,
719          ims, eptrb, flags, RM51);
720        if (rrc != MATCH_NOMATCH) RRETURN(rrc);
721        MRRETURN(MATCH_PRUNE);
722    
723        case OP_PRUNE_ARG:
724        RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode] + ecode[1], offset_top, md,
725          ims, eptrb, flags, RM56);
726        if (rrc != MATCH_NOMATCH) RRETURN(rrc);
727        md->mark = ecode + 2;
728        RRETURN(MATCH_PRUNE);
729    
730        case OP_SKIP:
731        RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,
732          ims, eptrb, flags, RM53);
733        if (rrc != MATCH_NOMATCH) RRETURN(rrc);
734        md->start_match_ptr = eptr;   /* Pass back current position */
735        MRRETURN(MATCH_SKIP);
736    
737        case OP_SKIP_ARG:
738        RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode] + ecode[1], offset_top, md,
739          ims, eptrb, flags, RM57);
740        if (rrc != MATCH_NOMATCH) RRETURN(rrc);
741    
742        /* Pass back the current skip name by overloading md->start_match_ptr and
743        returning the special MATCH_SKIP_ARG return code. This will either be
744        caught by a matching MARK, or get to the top, where it is treated the same
745        as PRUNE. */
746    
747        md->start_match_ptr = ecode + 2;
748        RRETURN(MATCH_SKIP_ARG);
749    
750        case OP_THEN:
751        RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,
752          ims, eptrb, flags, RM54);
753        if (rrc != MATCH_NOMATCH) RRETURN(rrc);
754        MRRETURN(MATCH_THEN);
755    
756        case OP_THEN_ARG:
757        RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode] + ecode[1], offset_top, md,
758          ims, eptrb, flags, RM58);
759        if (rrc != MATCH_NOMATCH) RRETURN(rrc);
760        md->mark = ecode + 2;
761        RRETURN(MATCH_THEN);
762    
763      /* Handle a capturing bracket. If there is space in the offset vector, save      /* Handle a capturing bracket. If there is space in the offset vector, save
764      the current subject position in the working slot at the top of the vector.      the current subject position in the working slot at the top of the vector.
765      We mustn't change the current values of the data slot, because they may be      We mustn't change the current values of the data slot, because they may be
# Line 617  for (;;) Line 779  for (;;)
779      number = GET2(ecode, 1+LINK_SIZE);      number = GET2(ecode, 1+LINK_SIZE);
780      offset = number << 1;      offset = number << 1;
781    
782  #ifdef DEBUG  #ifdef PCRE_DEBUG
783      printf("start bracket %d\n", number);      printf("start bracket %d\n", number);
784      printf("subject=");      printf("subject=");
785      pchars(eptr, 16, TRUE, md);      pchars(eptr, 16, TRUE, md);
# Line 637  for (;;) Line 799  for (;;)
799        flags = (op == OP_SCBRA)? match_cbegroup : 0;        flags = (op == OP_SCBRA)? match_cbegroup : 0;
800        do        do
801          {          {
802          RMATCH(rrc, eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,          RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,
803            ims, eptrb, flags);            ims, eptrb, flags, RM1);
804          if (rrc != MATCH_NOMATCH) RRETURN(rrc);          if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);
805          md->capture_last = save_capture_last;          md->capture_last = save_capture_last;
806          ecode += GET(ecode, 1);          ecode += GET(ecode, 1);
807          }          }
# Line 651  for (;;) Line 813  for (;;)
813        md->offset_vector[offset+1] = save_offset2;        md->offset_vector[offset+1] = save_offset2;
814        md->offset_vector[md->offset_end - number] = save_offset3;        md->offset_vector[md->offset_end - number] = save_offset3;
815    
816          if (rrc != MATCH_THEN) md->mark = markptr;
817        RRETURN(MATCH_NOMATCH);        RRETURN(MATCH_NOMATCH);
818        }        }
819    
820      /* Insufficient room for saving captured contents. Treat as a non-capturing      /* FALL THROUGH ... Insufficient room for saving captured contents. Treat
821      bracket. */      as a non-capturing bracket. */
822    
823        /* VVVVVVVVVVVVVVVVVVVVVVVVV */
824        /* VVVVVVVVVVVVVVVVVVVVVVVVV */
825    
826      DPRINTF(("insufficient capture room: treat as non-capturing\n"));      DPRINTF(("insufficient capture room: treat as non-capturing\n"));
827    
828        /* VVVVVVVVVVVVVVVVVVVVVVVVV */
829        /* VVVVVVVVVVVVVVVVVVVVVVVVV */
830    
831      /* Non-capturing bracket. Loop for all the alternatives. When we get to the      /* Non-capturing bracket. Loop for all the alternatives. When we get to the
832      final alternative within the brackets, we would return the result of a      final alternative within the brackets, we would return the result of a
833      recursive call to match() whatever happened. We can reduce stack usage by      recursive call to match() whatever happened. We can reduce stack usage by
834      turning this into a tail recursion. */      turning this into a tail recursion, except in the case when match_cbegroup
835        is set.*/
836    
837      case OP_BRA:      case OP_BRA:
838      case OP_SBRA:      case OP_SBRA:
# Line 670  for (;;) Line 840  for (;;)
840      flags = (op >= OP_SBRA)? match_cbegroup : 0;      flags = (op >= OP_SBRA)? match_cbegroup : 0;
841      for (;;)      for (;;)
842        {        {
843        if (ecode[GET(ecode, 1)] != OP_ALT)        if (ecode[GET(ecode, 1)] != OP_ALT)   /* Final alternative */
844          {          {
845          ecode += _pcre_OP_lengths[*ecode];          if (flags == 0)    /* Not a possibly empty group */
846          flags |= match_tail_recursed;            {
847          DPRINTF(("bracket 0 tail recursion\n"));            ecode += _pcre_OP_lengths[*ecode];
848          goto TAIL_RECURSE;            DPRINTF(("bracket 0 tail recursion\n"));
849              goto TAIL_RECURSE;
850              }
851    
852            /* Possibly empty group; can't use tail recursion. */
853    
854            RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md, ims,
855              eptrb, flags, RM48);
856            if (rrc == MATCH_NOMATCH) md->mark = markptr;
857            RRETURN(rrc);
858          }          }
859    
860        /* For non-final alternatives, continue the loop for a NOMATCH result;        /* For non-final alternatives, continue the loop for a NOMATCH result;
861        otherwise return. */        otherwise return. */
862    
863        RMATCH(rrc, eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md, ims,        RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md, ims,
864          eptrb, flags);          eptrb, flags, RM2);
865        if (rrc != MATCH_NOMATCH) RRETURN(rrc);        if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);
866        ecode += GET(ecode, 1);        ecode += GET(ecode, 1);
867        }        }
868      /* Control never reaches here. */      /* Control never reaches here. */
# Line 696  for (;;) Line 875  for (;;)
875    
876      case OP_COND:      case OP_COND:
877      case OP_SCOND:      case OP_SCOND:
878      if (ecode[LINK_SIZE+1] == OP_RREF)         /* Recursion test */      codelink= GET(ecode, 1);
879    
880        /* Because of the way auto-callout works during compile, a callout item is
881        inserted between OP_COND and an assertion condition. */
882    
883        if (ecode[LINK_SIZE+1] == OP_CALLOUT)
884        {        {
885        offset = GET2(ecode, LINK_SIZE + 2);     /* Recursion group number*/        if (pcre_callout != NULL)
886        condition = md->recursive != NULL &&          {
887          (offset == RREF_ANY || offset == md->recursive->group_num);          pcre_callout_block cb;
888        ecode += condition? 3 : GET(ecode, 1);          cb.version          = 1;   /* Version 1 of the callout block */
889            cb.callout_number   = ecode[LINK_SIZE+2];
890            cb.offset_vector    = md->offset_vector;
891            cb.subject          = (PCRE_SPTR)md->start_subject;
892            cb.subject_length   = md->end_subject - md->start_subject;
893            cb.start_match      = mstart - md->start_subject;
894            cb.current_position = eptr - md->start_subject;
895            cb.pattern_position = GET(ecode, LINK_SIZE + 3);
896            cb.next_item_length = GET(ecode, 3 + 2*LINK_SIZE);
897            cb.capture_top      = offset_top/2;
898            cb.capture_last     = md->capture_last;
899            cb.callout_data     = md->callout_data;
900            if ((rrc = (*pcre_callout)(&cb)) > 0) MRRETURN(MATCH_NOMATCH);
901            if (rrc < 0) RRETURN(rrc);
902            }
903          ecode += _pcre_OP_lengths[OP_CALLOUT];
904          }
905    
906        condcode = ecode[LINK_SIZE+1];
907    
908        /* Now see what the actual condition is */
909    
910        if (condcode == OP_RREF || condcode == OP_NRREF)    /* Recursion test */
911          {
912          if (md->recursive == NULL)                /* Not recursing => FALSE */
913            {
914            condition = FALSE;
915            ecode += GET(ecode, 1);
916            }
917          else
918            {
919            int recno = GET2(ecode, LINK_SIZE + 2);   /* Recursion group number*/
920            condition =  (recno == RREF_ANY || recno == md->recursive->group_num);
921    
922            /* If the test is for recursion into a specific subpattern, and it is
923            false, but the test was set up by name, scan the table to see if the
924            name refers to any other numbers, and test them. The condition is true
925            if any one is set. */
926    
927            if (!condition && condcode == OP_NRREF && recno != RREF_ANY)
928              {
929              uschar *slotA = md->name_table;
930              for (i = 0; i < md->name_count; i++)
931                {
932                if (GET2(slotA, 0) == recno) break;
933                slotA += md->name_entry_size;
934                }
935    
936              /* Found a name for the number - there can be only one; duplicate
937              names for different numbers are allowed, but not vice versa. First
938              scan down for duplicates. */
939    
940              if (i < md->name_count)
941                {
942                uschar *slotB = slotA;
943                while (slotB > md->name_table)
944                  {
945                  slotB -= md->name_entry_size;
946                  if (strcmp((char *)slotA + 2, (char *)slotB + 2) == 0)
947                    {
948                    condition = GET2(slotB, 0) == md->recursive->group_num;
949                    if (condition) break;
950                    }
951                  else break;
952                  }
953    
954                /* Scan up for duplicates */
955    
956                if (!condition)
957                  {
958                  slotB = slotA;
959                  for (i++; i < md->name_count; i++)
960                    {
961                    slotB += md->name_entry_size;
962                    if (strcmp((char *)slotA + 2, (char *)slotB + 2) == 0)
963                      {
964                      condition = GET2(slotB, 0) == md->recursive->group_num;
965                      if (condition) break;
966                      }
967                    else break;
968                    }
969                  }
970                }
971              }
972    
973            /* Chose branch according to the condition */
974    
975            ecode += condition? 3 : GET(ecode, 1);
976            }
977        }        }
978    
979      else if (ecode[LINK_SIZE+1] == OP_CREF)    /* Group used test */      else if (condcode == OP_CREF || condcode == OP_NCREF)  /* Group used test */
980        {        {
981        offset = GET2(ecode, LINK_SIZE+2) << 1;  /* Doubled ref number */        offset = GET2(ecode, LINK_SIZE+2) << 1;  /* Doubled ref number */
982        condition = offset < offset_top && md->offset_vector[offset] >= 0;        condition = offset < offset_top && md->offset_vector[offset] >= 0;
983    
984          /* If the numbered capture is unset, but the reference was by name,
985          scan the table to see if the name refers to any other numbers, and test
986          them. The condition is true if any one is set. This is tediously similar
987          to the code above, but not close enough to try to amalgamate. */
988    
989          if (!condition && condcode == OP_NCREF)
990            {
991            int refno = offset >> 1;
992            uschar *slotA = md->name_table;
993    
994            for (i = 0; i < md->name_count; i++)
995              {
996              if (GET2(slotA, 0) == refno) break;
997              slotA += md->name_entry_size;
998              }
999    
1000            /* Found a name for the number - there can be only one; duplicate names
1001            for different numbers are allowed, but not vice versa. First scan down
1002            for duplicates. */
1003    
1004            if (i < md->name_count)
1005              {
1006              uschar *slotB = slotA;
1007              while (slotB > md->name_table)
1008                {
1009                slotB -= md->name_entry_size;
1010                if (strcmp((char *)slotA + 2, (char *)slotB + 2) == 0)
1011                  {
1012                  offset = GET2(slotB, 0) << 1;
1013                  condition = offset < offset_top &&
1014                    md->offset_vector[offset] >= 0;
1015                  if (condition) break;
1016                  }
1017                else break;
1018                }
1019    
1020              /* Scan up for duplicates */
1021    
1022              if (!condition)
1023                {
1024                slotB = slotA;
1025                for (i++; i < md->name_count; i++)
1026                  {
1027                  slotB += md->name_entry_size;
1028                  if (strcmp((char *)slotA + 2, (char *)slotB + 2) == 0)
1029                    {
1030                    offset = GET2(slotB, 0) << 1;
1031                    condition = offset < offset_top &&
1032                      md->offset_vector[offset] >= 0;
1033                    if (condition) break;
1034                    }
1035                  else break;
1036                  }
1037                }
1038              }
1039            }
1040    
1041          /* Chose branch according to the condition */
1042    
1043        ecode += condition? 3 : GET(ecode, 1);        ecode += condition? 3 : GET(ecode, 1);
1044        }        }
1045    
1046      else if (ecode[LINK_SIZE+1] == OP_DEF)     /* DEFINE - always false */      else if (condcode == OP_DEF)     /* DEFINE - always false */
1047        {        {
1048        condition = FALSE;        condition = FALSE;
1049        ecode += GET(ecode, 1);        ecode += GET(ecode, 1);
# Line 723  for (;;) Line 1055  for (;;)
1055    
1056      else      else
1057        {        {
1058        RMATCH(rrc, eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, NULL,        RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, NULL,
1059            match_condassert);            match_condassert, RM3);
1060        if (rrc == MATCH_MATCH)        if (rrc == MATCH_MATCH)
1061          {          {
1062          condition = TRUE;          condition = TRUE;
1063          ecode += 1 + LINK_SIZE + GET(ecode, LINK_SIZE + 2);          ecode += 1 + LINK_SIZE + GET(ecode, LINK_SIZE + 2);
1064          while (*ecode == OP_ALT) ecode += GET(ecode, 1);          while (*ecode == OP_ALT) ecode += GET(ecode, 1);
1065          }          }
1066        else if (rrc != MATCH_NOMATCH)        else if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN)
1067          {          {
1068          RRETURN(rrc);         /* Need braces because of following else */          RRETURN(rrc);         /* Need braces because of following else */
1069          }          }
1070        else        else
1071          {          {
1072          condition = FALSE;          condition = FALSE;
1073          ecode += GET(ecode, 1);          ecode += codelink;
1074          }          }
1075        }        }
1076    
1077      /* We are now at the branch that is to be obeyed. As there is only one,      /* We are now at the branch that is to be obeyed. As there is only one,
1078      we can use tail recursion to avoid using another stack frame. If the second      we can use tail recursion to avoid using another stack frame, except when
1079      alternative doesn't exist, we can just plough on. */      match_cbegroup is required for an unlimited repeat of a possibly empty
1080        group. If the second alternative doesn't exist, we can just plough on. */
1081    
1082      if (condition || *ecode == OP_ALT)      if (condition || *ecode == OP_ALT)
1083        {        {
1084        ecode += 1 + LINK_SIZE;        ecode += 1 + LINK_SIZE;
1085        flags = match_tail_recursed | ((op == OP_SCOND)? match_cbegroup : 0);        if (op == OP_SCOND)        /* Possibly empty group */
1086        goto TAIL_RECURSE;          {
1087            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, match_cbegroup, RM49);
1088            RRETURN(rrc);
1089            }
1090          else                       /* Group must match something */
1091            {
1092            flags = 0;
1093            goto TAIL_RECURSE;
1094            }
1095        }        }
1096      else      else                         /* Condition false & no alternative */
1097        {        {
1098        ecode += 1 + LINK_SIZE;        ecode += 1 + LINK_SIZE;
1099        }        }
1100      break;      break;
1101    
1102    
1103      /* End of the pattern. If we are in a top-level recursion, we should      /* Before OP_ACCEPT there may be any number of OP_CLOSE opcodes,
1104      restore the offsets appropriately and continue from after the call. */      to close any currently open capturing brackets. */
1105    
1106        case OP_CLOSE:
1107        number = GET2(ecode, 1);
1108        offset = number << 1;
1109    
1110    #ifdef PCRE_DEBUG
1111          printf("end bracket %d at *ACCEPT", number);
1112          printf("\n");
1113    #endif
1114    
1115        md->capture_last = number;
1116        if (offset >= md->offset_max) md->offset_overflow = TRUE; else
1117          {
1118          md->offset_vector[offset] =
1119            md->offset_vector[md->offset_end - number];
1120          md->offset_vector[offset+1] = eptr - md->start_subject;
1121          if (offset_top <= offset) offset_top = offset + 2;
1122          }
1123        ecode += 3;
1124        break;
1125    
1126    
1127        /* End of the pattern, either real or forced. If we are in a top-level
1128        recursion, we should restore the offsets appropriately and continue from
1129        after the call. */
1130    
1131        case OP_ACCEPT:
1132      case OP_END:      case OP_END:
1133      if (md->recursive != NULL && md->recursive->group_num == 0)      if (md->recursive != NULL && md->recursive->group_num == 0)
1134        {        {
# Line 770  for (;;) Line 1137  for (;;)
1137        md->recursive = rec->prevrec;        md->recursive = rec->prevrec;
1138        memmove(md->offset_vector, rec->offset_save,        memmove(md->offset_vector, rec->offset_save,
1139          rec->saved_max * sizeof(int));          rec->saved_max * sizeof(int));
1140        md->start_match = rec->save_start;        offset_top = rec->save_offset_top;
1141        ims = original_ims;        ims = original_ims;
1142        ecode = rec->after_call;        ecode = rec->after_call;
1143        break;        break;
1144        }        }
1145    
1146      /* Otherwise, if PCRE_NOTEMPTY is set, fail if we have matched an empty      /* Otherwise, if we have matched an empty string, fail if PCRE_NOTEMPTY is
1147      string - backtracking will then try other alternatives, if any. */      set, or if PCRE_NOTEMPTY_ATSTART is set and we have matched at the start of
1148        the subject. In both cases, backtracking will then try other alternatives,
1149        if any. */
1150    
1151        if (eptr == mstart &&
1152            (md->notempty ||
1153              (md->notempty_atstart &&
1154                mstart == md->start_subject + md->start_offset)))
1155          MRRETURN(MATCH_NOMATCH);
1156    
1157        /* Otherwise, we have a match. */
1158    
1159        md->end_match_ptr = eptr;           /* Record where we ended */
1160        md->end_offset_top = offset_top;    /* and how many extracts were taken */
1161        md->start_match_ptr = mstart;       /* and the start (\K can modify) */
1162    
1163      if (md->notempty && eptr == md->start_match) RRETURN(MATCH_NOMATCH);      /* For some reason, the macros don't work properly if an expression is
1164      md->end_match_ptr = eptr;          /* Record where we ended */      given as the argument to MRRETURN when the heap is in use. */
1165      md->end_offset_top = offset_top;   /* and how many extracts were taken */  
1166      RRETURN(MATCH_MATCH);      rrc = (op == OP_END)? MATCH_MATCH : MATCH_ACCEPT;
1167        MRRETURN(rrc);
1168    
1169      /* Change option settings */      /* Change option settings */
1170    
# Line 802  for (;;) Line 1184  for (;;)
1184      case OP_ASSERTBACK:      case OP_ASSERTBACK:
1185      do      do
1186        {        {
1187        RMATCH(rrc, eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, NULL, 0);        RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, NULL, 0,
1188        if (rrc == MATCH_MATCH) break;          RM4);
1189        if (rrc != MATCH_NOMATCH) RRETURN(rrc);        if (rrc == MATCH_MATCH || rrc == MATCH_ACCEPT)
1190            {
1191            mstart = md->start_match_ptr;   /* In case \K reset it */
1192            break;
1193            }
1194          if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);
1195        ecode += GET(ecode, 1);        ecode += GET(ecode, 1);
1196        }        }
1197      while (*ecode == OP_ALT);      while (*ecode == OP_ALT);
1198      if (*ecode == OP_KET) RRETURN(MATCH_NOMATCH);      if (*ecode == OP_KET) MRRETURN(MATCH_NOMATCH);
1199    
1200      /* If checking an assertion for a condition, return MATCH_MATCH. */      /* If checking an assertion for a condition, return MATCH_MATCH. */
1201    
# Line 822  for (;;) Line 1209  for (;;)
1209      offset_top = md->end_offset_top;      offset_top = md->end_offset_top;
1210      continue;      continue;
1211    
1212      /* Negative assertion: all branches must fail to match */      /* Negative assertion: all branches must fail to match. Encountering SKIP,
1213        PRUNE, or COMMIT means we must assume failure without checking subsequent
1214        branches. */
1215    
1216      case OP_ASSERT_NOT:      case OP_ASSERT_NOT:
1217      case OP_ASSERTBACK_NOT:      case OP_ASSERTBACK_NOT:
1218      do      do
1219        {        {
1220        RMATCH(rrc, eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, NULL, 0);        RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, NULL, 0,
1221        if (rrc == MATCH_MATCH) RRETURN(MATCH_NOMATCH);          RM5);
1222        if (rrc != MATCH_NOMATCH) RRETURN(rrc);        if (rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) MRRETURN(MATCH_NOMATCH);
1223          if (rrc == MATCH_SKIP || rrc == MATCH_PRUNE || rrc == MATCH_COMMIT)
1224            {
1225            do ecode += GET(ecode,1); while (*ecode == OP_ALT);
1226            break;
1227            }
1228          if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);
1229        ecode += GET(ecode,1);        ecode += GET(ecode,1);
1230        }        }
1231      while (*ecode == OP_ALT);      while (*ecode == OP_ALT);
# Line 853  for (;;) Line 1248  for (;;)
1248        while (i-- > 0)        while (i-- > 0)
1249          {          {
1250          eptr--;          eptr--;
1251          if (eptr < md->start_subject) RRETURN(MATCH_NOMATCH);          if (eptr < md->start_subject) MRRETURN(MATCH_NOMATCH);
1252          BACKCHAR(eptr)          BACKCHAR(eptr);
1253          }          }
1254        }        }
1255      else      else
# Line 864  for (;;) Line 1259  for (;;)
1259    
1260        {        {
1261        eptr -= GET(ecode, 1);        eptr -= GET(ecode, 1);
1262        if (eptr < md->start_subject) RRETURN(MATCH_NOMATCH);        if (eptr < md->start_subject) MRRETURN(MATCH_NOMATCH);
1263        }        }
1264    
1265      /* Skip to next op code */      /* Save the earliest consulted character, then skip to next op code */
1266    
1267        if (eptr < md->start_used_ptr) md->start_used_ptr = eptr;
1268      ecode += 1 + LINK_SIZE;      ecode += 1 + LINK_SIZE;
1269      break;      break;
1270    
# Line 885  for (;;) Line 1281  for (;;)
1281        cb.offset_vector    = md->offset_vector;        cb.offset_vector    = md->offset_vector;
1282        cb.subject          = (PCRE_SPTR)md->start_subject;        cb.subject          = (PCRE_SPTR)md->start_subject;
1283        cb.subject_length   = md->end_subject - md->start_subject;        cb.subject_length   = md->end_subject - md->start_subject;
1284        cb.start_match      = md->start_match - md->start_subject;        cb.start_match      = mstart - md->start_subject;
1285        cb.current_position = eptr - md->start_subject;        cb.current_position = eptr - md->start_subject;
1286        cb.pattern_position = GET(ecode, 2);        cb.pattern_position = GET(ecode, 2);
1287        cb.next_item_length = GET(ecode, 2 + LINK_SIZE);        cb.next_item_length = GET(ecode, 2 + LINK_SIZE);
1288        cb.capture_top      = offset_top/2;        cb.capture_top      = offset_top/2;
1289        cb.capture_last     = md->capture_last;        cb.capture_last     = md->capture_last;
1290        cb.callout_data     = md->callout_data;        cb.callout_data     = md->callout_data;
1291        if ((rrc = (*pcre_callout)(&cb)) > 0) RRETURN(MATCH_NOMATCH);        if ((rrc = (*pcre_callout)(&cb)) > 0) MRRETURN(MATCH_NOMATCH);
1292        if (rrc < 0) RRETURN(rrc);        if (rrc < 0) RRETURN(rrc);
1293        }        }
1294      ecode += 2 + 2*LINK_SIZE;      ecode += 2 + 2*LINK_SIZE;
# Line 947  for (;;) Line 1343  for (;;)
1343    
1344        memcpy(new_recursive.offset_save, md->offset_vector,        memcpy(new_recursive.offset_save, md->offset_vector,
1345              new_recursive.saved_max * sizeof(int));              new_recursive.saved_max * sizeof(int));
1346        new_recursive.save_start = md->start_match;        new_recursive.save_offset_top = offset_top;
       md->start_match = eptr;  
1347    
1348        /* OK, now we can do the recursion. For each top-level alternative we        /* OK, now we can do the recursion. For each top-level alternative we
1349        restore the offset and recursion data. */        restore the offset and recursion data. */
# Line 957  for (;;) Line 1352  for (;;)
1352        flags = (*callpat >= OP_SBRA)? match_cbegroup : 0;        flags = (*callpat >= OP_SBRA)? match_cbegroup : 0;
1353        do        do
1354          {          {
1355          RMATCH(rrc, eptr, callpat + _pcre_OP_lengths[*callpat], offset_top,          RMATCH(eptr, callpat + _pcre_OP_lengths[*callpat], offset_top,
1356            md, ims, eptrb, flags);            md, ims, eptrb, flags, RM6);
1357          if (rrc == MATCH_MATCH)          if (rrc == MATCH_MATCH || rrc == MATCH_ACCEPT)
1358            {            {
1359            DPRINTF(("Recursion matched\n"));            DPRINTF(("Recursion matched\n"));
1360            md->recursive = new_recursive.prevrec;            md->recursive = new_recursive.prevrec;
1361            if (new_recursive.offset_save != stacksave)            if (new_recursive.offset_save != stacksave)
1362              (pcre_free)(new_recursive.offset_save);              (pcre_free)(new_recursive.offset_save);
1363            RRETURN(MATCH_MATCH);            MRRETURN(MATCH_MATCH);
1364            }            }
1365          else if (rrc != MATCH_NOMATCH)          else if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN)
1366            {            {
1367            DPRINTF(("Recursion gave error %d\n", rrc));            DPRINTF(("Recursion gave error %d\n", rrc));
1368              if (new_recursive.offset_save != stacksave)
1369                (pcre_free)(new_recursive.offset_save);
1370            RRETURN(rrc);            RRETURN(rrc);
1371            }            }
1372    
# Line 984  for (;;) Line 1381  for (;;)
1381        md->recursive = new_recursive.prevrec;        md->recursive = new_recursive.prevrec;
1382        if (new_recursive.offset_save != stacksave)        if (new_recursive.offset_save != stacksave)
1383          (pcre_free)(new_recursive.offset_save);          (pcre_free)(new_recursive.offset_save);
1384        RRETURN(MATCH_NOMATCH);        MRRETURN(MATCH_NOMATCH);
1385        }        }
1386      /* Control never reaches here */      /* Control never reaches here */
1387    
# Line 993  for (;;) Line 1390  for (;;)
1390      a move back into the brackets. Friedl calls these "atomic" subpatterns.      a move back into the brackets. Friedl calls these "atomic" subpatterns.
1391      Check the alternative branches in turn - the matching won't pass the KET      Check the alternative branches in turn - the matching won't pass the KET
1392      for this kind of subpattern. If any one branch matches, we carry on as at      for this kind of subpattern. If any one branch matches, we carry on as at
1393      the end of a normal bracket, leaving the subject pointer. */      the end of a normal bracket, leaving the subject pointer, but resetting
1394        the start-of-match value in case it was changed by \K. */
1395    
1396      case OP_ONCE:      case OP_ONCE:
1397      prev = ecode;      prev = ecode;
# Line 1001  for (;;) Line 1399  for (;;)
1399    
1400      do      do
1401        {        {
1402        RMATCH(rrc, eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims,        RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, eptrb, 0, RM7);
1403          eptrb, 0);        if (rrc == MATCH_MATCH)  /* Note: _not_ MATCH_ACCEPT */
1404        if (rrc == MATCH_MATCH) break;          {
1405        if (rrc != MATCH_NOMATCH) RRETURN(rrc);          mstart = md->start_match_ptr;
1406            break;
1407            }
1408          if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);
1409        ecode += GET(ecode,1);        ecode += GET(ecode,1);
1410        }        }
1411      while (*ecode == OP_ALT);      while (*ecode == OP_ALT);
# Line 1047  for (;;) Line 1448  for (;;)
1448    
1449      if (*ecode == OP_KETRMIN)      if (*ecode == OP_KETRMIN)
1450        {        {
1451        RMATCH(rrc, eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, eptrb, 0);        RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, eptrb, 0, RM8);
1452        if (rrc != MATCH_NOMATCH) RRETURN(rrc);        if (rrc != MATCH_NOMATCH) RRETURN(rrc);
1453        ecode = prev;        ecode = prev;
1454        flags = match_tail_recursed;        flags = 0;
1455        goto TAIL_RECURSE;        goto TAIL_RECURSE;
1456        }        }
1457      else  /* OP_KETRMAX */      else  /* OP_KETRMAX */
1458        {        {
1459        RMATCH(rrc, eptr, prev, offset_top, md, ims, eptrb, match_cbegroup);        RMATCH(eptr, prev, offset_top, md, ims, eptrb, match_cbegroup, RM9);
1460        if (rrc != MATCH_NOMATCH) RRETURN(rrc);        if (rrc != MATCH_NOMATCH) RRETURN(rrc);
1461        ecode += 1 + LINK_SIZE;        ecode += 1 + LINK_SIZE;
1462        flags = match_tail_recursed;        flags = 0;
1463        goto TAIL_RECURSE;        goto TAIL_RECURSE;
1464        }        }
1465      /* Control never gets here */      /* Control never gets here */
# Line 1070  for (;;) Line 1471  for (;;)
1471      do ecode += GET(ecode,1); while (*ecode == OP_ALT);      do ecode += GET(ecode,1); while (*ecode == OP_ALT);
1472      break;      break;
1473    
1474      /* BRAZERO and BRAMINZERO occur just before a bracket group, indicating      /* BRAZERO, BRAMINZERO and SKIPZERO occur just before a bracket group,
1475      that it may occur zero times. It may repeat infinitely, or not at all -      indicating that it may occur zero times. It may repeat infinitely, or not
1476      i.e. it could be ()* or ()? in the pattern. Brackets with fixed upper      at all - i.e. it could be ()* or ()? or even (){0} in the pattern. Brackets
1477      repeat limits are compiled as a number of copies, with the optional ones      with fixed upper repeat limits are compiled as a number of copies, with the
1478      preceded by BRAZERO or BRAMINZERO. */      optional ones preceded by BRAZERO or BRAMINZERO. */
1479    
1480      case OP_BRAZERO:      case OP_BRAZERO:
1481        {        {
1482        next = ecode+1;        next = ecode+1;
1483        RMATCH(rrc, eptr, next, offset_top, md, ims, eptrb, 0);        RMATCH(eptr, next, offset_top, md, ims, eptrb, 0, RM10);
1484        if (rrc != MATCH_NOMATCH) RRETURN(rrc);        if (rrc != MATCH_NOMATCH) RRETURN(rrc);
1485        do next += GET(next,1); while (*next == OP_ALT);        do next += GET(next,1); while (*next == OP_ALT);
1486        ecode = next + 1 + LINK_SIZE;        ecode = next + 1 + LINK_SIZE;
# Line 1090  for (;;) Line 1491  for (;;)
1491        {        {
1492        next = ecode+1;        next = ecode+1;
1493        do next += GET(next, 1); while (*next == OP_ALT);        do next += GET(next, 1); while (*next == OP_ALT);
1494        RMATCH(rrc, eptr, next + 1+LINK_SIZE, offset_top, md, ims, eptrb, 0);        RMATCH(eptr, next + 1+LINK_SIZE, offset_top, md, ims, eptrb, 0, RM11);
1495        if (rrc != MATCH_NOMATCH) RRETURN(rrc);        if (rrc != MATCH_NOMATCH) RRETURN(rrc);
1496        ecode++;        ecode++;
1497        }        }
1498      break;      break;
1499    
1500        case OP_SKIPZERO:
1501          {
1502          next = ecode+1;
1503          do next += GET(next,1); while (*next == OP_ALT);
1504          ecode = next + 1 + LINK_SIZE;
1505          }
1506        break;
1507    
1508      /* End of a group, repeated or non-repeating. */      /* End of a group, repeated or non-repeating. */
1509    
1510      case OP_KET:      case OP_KET:
# Line 1114  for (;;) Line 1523  for (;;)
1523        }        }
1524      else saved_eptr = NULL;      else saved_eptr = NULL;
1525    
1526      /* If we are at the end of an assertion group, stop matching and return      /* If we are at the end of an assertion group or an atomic group, stop
1527      MATCH_MATCH, but record the current high water mark for use by positive      matching and return MATCH_MATCH, but record the current high water mark for
1528      assertions. Do this also for the "once" (atomic) groups. */      use by positive assertions. We also need to record the match start in case
1529        it was changed by \K. */
1530    
1531      if (*prev == OP_ASSERT || *prev == OP_ASSERT_NOT ||      if (*prev == OP_ASSERT || *prev == OP_ASSERT_NOT ||
1532          *prev == OP_ASSERTBACK || *prev == OP_ASSERTBACK_NOT ||          *prev == OP_ASSERTBACK || *prev == OP_ASSERTBACK_NOT ||
# Line 1124  for (;;) Line 1534  for (;;)
1534        {        {
1535        md->end_match_ptr = eptr;      /* For ONCE */        md->end_match_ptr = eptr;      /* For ONCE */
1536        md->end_offset_top = offset_top;        md->end_offset_top = offset_top;
1537        RRETURN(MATCH_MATCH);        md->start_match_ptr = mstart;
1538          MRRETURN(MATCH_MATCH);
1539        }        }
1540    
1541      /* For capturing groups we have to check the group number back at the start      /* For capturing groups we have to check the group number back at the start
# Line 1138  for (;;) Line 1549  for (;;)
1549        number = GET2(prev, 1+LINK_SIZE);        number = GET2(prev, 1+LINK_SIZE);
1550        offset = number << 1;        offset = number << 1;
1551    
1552  #ifdef DEBUG  #ifdef PCRE_DEBUG
1553        printf("end bracket %d", number);        printf("end bracket %d", number);
1554        printf("\n");        printf("\n");
1555  #endif  #endif
# Line 1160  for (;;) Line 1571  for (;;)
1571          recursion_info *rec = md->recursive;          recursion_info *rec = md->recursive;
1572          DPRINTF(("Recursion (%d) succeeded - continuing\n", number));          DPRINTF(("Recursion (%d) succeeded - continuing\n", number));
1573          md->recursive = rec->prevrec;          md->recursive = rec->prevrec;
         md->start_match = rec->save_start;  
1574          memcpy(md->offset_vector, rec->offset_save,          memcpy(md->offset_vector, rec->offset_save,
1575            rec->saved_max * sizeof(int));            rec->saved_max * sizeof(int));
1576            offset_top = rec->save_offset_top;
1577          ecode = rec->after_call;          ecode = rec->after_call;
1578          ims = original_ims;          ims = original_ims;
1579          break;          break;
# Line 1189  for (;;) Line 1600  for (;;)
1600    
1601      /* The repeating kets try the rest of the pattern or restart from the      /* The repeating kets try the rest of the pattern or restart from the
1602      preceding bracket, in the appropriate order. In the second case, we can use      preceding bracket, in the appropriate order. In the second case, we can use
1603      tail recursion to avoid using another stack frame. */      tail recursion to avoid using another stack frame, unless we have an
1604        unlimited repeat of a group that can match an empty string. */
1605    
1606      flags = (*prev >= OP_SBRA)? match_cbegroup : 0;      flags = (*prev >= OP_SBRA)? match_cbegroup : 0;
1607    
1608      if (*ecode == OP_KETRMIN)      if (*ecode == OP_KETRMIN)
1609        {        {
1610        RMATCH(rrc, eptr, ecode + 1+LINK_SIZE, offset_top, md, ims, eptrb, 0);        RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, eptrb, 0, RM12);
1611        if (rrc != MATCH_NOMATCH) RRETURN(rrc);        if (rrc != MATCH_NOMATCH) RRETURN(rrc);
1612          if (flags != 0)    /* Could match an empty string */
1613            {
1614            RMATCH(eptr, prev, offset_top, md, ims, eptrb, flags, RM50);
1615            RRETURN(rrc);
1616            }
1617        ecode = prev;        ecode = prev;
       flags |= match_tail_recursed;  
1618        goto TAIL_RECURSE;        goto TAIL_RECURSE;
1619        }        }
1620      else  /* OP_KETRMAX */      else  /* OP_KETRMAX */
1621        {        {
1622        RMATCH(rrc, eptr, prev, offset_top, md, ims, eptrb, flags);        RMATCH(eptr, prev, offset_top, md, ims, eptrb, flags, RM13);
1623        if (rrc != MATCH_NOMATCH) RRETURN(rrc);        if (rrc != MATCH_NOMATCH) RRETURN(rrc);
1624        ecode += 1 + LINK_SIZE;        ecode += 1 + LINK_SIZE;
1625        flags = match_tail_recursed;        flags = 0;
1626        goto TAIL_RECURSE;        goto TAIL_RECURSE;
1627        }        }
1628      /* Control never gets here */      /* Control never gets here */
# Line 1214  for (;;) Line 1630  for (;;)
1630      /* Start of subject unless notbol, or after internal newline if multiline */      /* Start of subject unless notbol, or after internal newline if multiline */
1631    
1632      case OP_CIRC:      case OP_CIRC:
1633      if (md->notbol && eptr == md->start_subject) RRETURN(MATCH_NOMATCH);      if (md->notbol && eptr == md->start_subject) MRRETURN(MATCH_NOMATCH);
1634      if ((ims & PCRE_MULTILINE) != 0)      if ((ims & PCRE_MULTILINE) != 0)
1635        {        {
1636        if (eptr != md->start_subject &&        if (eptr != md->start_subject &&
1637            (eptr == md->end_subject || !WAS_NEWLINE(eptr)))            (eptr == md->end_subject || !WAS_NEWLINE(eptr)))
1638          RRETURN(MATCH_NOMATCH);          MRRETURN(MATCH_NOMATCH);
1639        ecode++;        ecode++;
1640        break;        break;
1641        }        }
# Line 1228  for (;;) Line 1644  for (;;)
1644      /* Start of subject assertion */      /* Start of subject assertion */
1645    
1646      case OP_SOD:      case OP_SOD:
1647      if (eptr != md->start_subject) RRETURN(MATCH_NOMATCH);      if (eptr != md->start_subject) MRRETURN(MATCH_NOMATCH);
1648      ecode++;      ecode++;
1649      break;      break;
1650    
1651      /* Start of match assertion */      /* Start of match assertion */
1652    
1653      case OP_SOM:      case OP_SOM:
1654      if (eptr != md->start_subject + md->start_offset) RRETURN(MATCH_NOMATCH);      if (eptr != md->start_subject + md->start_offset) MRRETURN(MATCH_NOMATCH);
1655        ecode++;
1656        break;
1657    
1658        /* Reset the start of match point */
1659    
1660        case OP_SET_SOM:
1661        mstart = eptr;
1662      ecode++;      ecode++;
1663      break;      break;
1664    
# Line 1246  for (;;) Line 1669  for (;;)
1669      if ((ims & PCRE_MULTILINE) != 0)      if ((ims & PCRE_MULTILINE) != 0)
1670        {        {
1671        if (eptr < md->end_subject)        if (eptr < md->end_subject)
1672          { if (!IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH); }          { if (!IS_NEWLINE(eptr)) MRRETURN(MATCH_NOMATCH); }
1673        else        else
1674          { if (md->noteol) RRETURN(MATCH_NOMATCH); }          { if (md->noteol) MRRETURN(MATCH_NOMATCH); }
1675        ecode++;        ecode++;
1676        break;        break;
1677        }        }
1678      else      else
1679        {        {
1680        if (md->noteol) RRETURN(MATCH_NOMATCH);        if (md->noteol) MRRETURN(MATCH_NOMATCH);
1681        if (!md->endonly)        if (!md->endonly)
1682          {          {
1683          if (eptr != md->end_subject &&          if (eptr != md->end_subject &&
1684              (!IS_NEWLINE(eptr) || eptr != md->end_subject - md->nllen))              (!IS_NEWLINE(eptr) || eptr != md->end_subject - md->nllen))
1685            RRETURN(MATCH_NOMATCH);            MRRETURN(MATCH_NOMATCH);
1686          ecode++;          ecode++;
1687          break;          break;
1688          }          }
# Line 1269  for (;;) Line 1692  for (;;)
1692      /* End of subject assertion (\z) */      /* End of subject assertion (\z) */
1693    
1694      case OP_EOD:      case OP_EOD:
1695      if (eptr < md->end_subject) RRETURN(MATCH_NOMATCH);      if (eptr < md->end_subject) MRRETURN(MATCH_NOMATCH);
1696      ecode++;      ecode++;
1697      break;      break;
1698    
# Line 1278  for (;;) Line 1701  for (;;)
1701      case OP_EODN:      case OP_EODN:
1702      if (eptr != md->end_subject &&      if (eptr != md->end_subject &&
1703          (!IS_NEWLINE(eptr) || eptr != md->end_subject - md->nllen))          (!IS_NEWLINE(eptr) || eptr != md->end_subject - md->nllen))
1704        RRETURN(MATCH_NOMATCH);        MRRETURN(MATCH_NOMATCH);
1705      ecode++;      ecode++;
1706      break;      break;
1707    
# Line 1290  for (;;) Line 1713  for (;;)
1713    
1714        /* Find out if the previous and current characters are "word" characters.        /* Find out if the previous and current characters are "word" characters.
1715        It takes a bit more work in UTF-8 mode. Characters > 255 are assumed to        It takes a bit more work in UTF-8 mode. Characters > 255 are assumed to
1716        be "non-word" characters. */        be "non-word" characters. Remember the earliest consulted character for
1717          partial matching. */
1718    
1719  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
1720        if (utf8)        if (utf8)
1721          {          {
1722            /* Get status of previous character */
1723    
1724          if (eptr == md->start_subject) prev_is_word = FALSE; else          if (eptr == md->start_subject) prev_is_word = FALSE; else
1725            {            {
1726            const uschar *lastptr = eptr - 1;            USPTR lastptr = eptr - 1;
1727            while((*lastptr & 0xc0) == 0x80) lastptr--;            while((*lastptr & 0xc0) == 0x80) lastptr--;
1728              if (lastptr < md->start_used_ptr) md->start_used_ptr = lastptr;
1729            GETCHAR(c, lastptr);            GETCHAR(c, lastptr);
1730    #ifdef SUPPORT_UCP
1731              if (md->use_ucp)
1732                {
1733                if (c == '_') prev_is_word = TRUE; else
1734                  {
1735                  int cat = UCD_CATEGORY(c);
1736                  prev_is_word = (cat == ucp_L || cat == ucp_N);
1737                  }
1738                }
1739              else
1740    #endif
1741            prev_is_word = c < 256 && (md->ctypes[c] & ctype_word) != 0;            prev_is_word = c < 256 && (md->ctypes[c] & ctype_word) != 0;
1742            }            }
1743          if (eptr >= md->end_subject) cur_is_word = FALSE; else  
1744            /* Get status of next character */
1745    
1746            if (eptr >= md->end_subject)
1747              {
1748              SCHECK_PARTIAL();
1749              cur_is_word = FALSE;
1750              }
1751            else
1752            {            {
1753            GETCHAR(c, eptr);            GETCHAR(c, eptr);
1754    #ifdef SUPPORT_UCP
1755              if (md->use_ucp)
1756                {
1757                if (c == '_') cur_is_word = TRUE; else
1758                  {
1759                  int cat = UCD_CATEGORY(c);
1760                  cur_is_word = (cat == ucp_L || cat == ucp_N);
1761                  }
1762                }
1763              else
1764    #endif
1765            cur_is_word = c < 256 && (md->ctypes[c] & ctype_word) != 0;            cur_is_word = c < 256 && (md->ctypes[c] & ctype_word) != 0;
1766            }            }
1767          }          }
1768        else        else
1769  #endif  #endif
1770    
1771        /* More streamlined when not in UTF-8 mode */        /* Not in UTF-8 mode, but we may still have PCRE_UCP set, and for
1772          consistency with the behaviour of \w we do use it in this case. */
1773    
1774          {          {
1775          prev_is_word = (eptr != md->start_subject) &&          /* Get status of previous character */
1776            ((md->ctypes[eptr[-1]] & ctype_word) != 0);  
1777          cur_is_word = (eptr < md->end_subject) &&          if (eptr == md->start_subject) prev_is_word = FALSE; else
1778            ((md->ctypes[*eptr] & ctype_word) != 0);            {
1779              if (eptr <= md->start_used_ptr) md->start_used_ptr = eptr - 1;
1780    #ifdef SUPPORT_UCP
1781              if (md->use_ucp)
1782                {
1783                c = eptr[-1];
1784                if (c == '_') prev_is_word = TRUE; else
1785                  {
1786                  int cat = UCD_CATEGORY(c);
1787                  prev_is_word = (cat == ucp_L || cat == ucp_N);
1788                  }
1789                }
1790              else
1791    #endif
1792              prev_is_word = ((md->ctypes[eptr[-1]] & ctype_word) != 0);
1793              }
1794    
1795            /* Get status of next character */
1796    
1797            if (eptr >= md->end_subject)
1798              {
1799              SCHECK_PARTIAL();
1800              cur_is_word = FALSE;
1801              }
1802            else
1803    #ifdef SUPPORT_UCP
1804            if (md->use_ucp)
1805              {
1806              c = *eptr;
1807              if (c == '_') cur_is_word = TRUE; else
1808                {
1809                int cat = UCD_CATEGORY(c);
1810                cur_is_word = (cat == ucp_L || cat == ucp_N);
1811                }
1812              }
1813            else
1814    #endif
1815            cur_is_word = ((md->ctypes[*eptr] & ctype_word) != 0);
1816          }          }
1817    
1818        /* Now see if the situation is what we want */        /* Now see if the situation is what we want */
1819    
1820        if ((*ecode++ == OP_WORD_BOUNDARY)?        if ((*ecode++ == OP_WORD_BOUNDARY)?
1821             cur_is_word == prev_is_word : cur_is_word != prev_is_word)             cur_is_word == prev_is_word : cur_is_word != prev_is_word)
1822          RRETURN(MATCH_NOMATCH);          MRRETURN(MATCH_NOMATCH);
1823        }        }
1824      break;      break;
1825    
1826      /* Match a single character type; inline for speed */      /* Match a single character type; inline for speed */
1827    
1828      case OP_ANY:      case OP_ANY:
1829      if ((ims & PCRE_DOTALL) == 0)      if (IS_NEWLINE(eptr)) MRRETURN(MATCH_NOMATCH);
1830        /* Fall through */
1831    
1832        case OP_ALLANY:
1833        if (eptr++ >= md->end_subject)
1834        {        {
1835        if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH);        SCHECK_PARTIAL();
1836          MRRETURN(MATCH_NOMATCH);
1837        }        }
1838      if (eptr++ >= md->end_subject) RRETURN(MATCH_NOMATCH);      if (utf8) while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;
     if (utf8)  
       while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;  
1839      ecode++;      ecode++;
1840      break;      break;
1841    
# Line 1345  for (;;) Line 1843  for (;;)
1843      any byte, even newline, independent of the setting of PCRE_DOTALL. */      any byte, even newline, independent of the setting of PCRE_DOTALL. */
1844    
1845      case OP_ANYBYTE:      case OP_ANYBYTE:
1846      if (eptr++ >= md->end_subject) RRETURN(MATCH_NOMATCH);      if (eptr++ >= md->end_subject)
1847          {
1848          SCHECK_PARTIAL();
1849          MRRETURN(MATCH_NOMATCH);
1850          }
1851      ecode++;      ecode++;
1852      break;      break;
1853    
1854      case OP_NOT_DIGIT:      case OP_NOT_DIGIT:
1855      if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);      if (eptr >= md->end_subject)
1856          {
1857          SCHECK_PARTIAL();
1858          MRRETURN(MATCH_NOMATCH);
1859          }
1860      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
1861      if (      if (
1862  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
# Line 1358  for (;;) Line 1864  for (;;)
1864  #endif  #endif
1865         (md->ctypes[c] & ctype_digit) != 0         (md->ctypes[c] & ctype_digit) != 0
1866         )         )
1867        RRETURN(MATCH_NOMATCH);        MRRETURN(MATCH_NOMATCH);
1868      ecode++;      ecode++;
1869      break;      break;
1870    
1871      case OP_DIGIT:      case OP_DIGIT:
1872      if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);      if (eptr >= md->end_subject)
1873          {
1874          SCHECK_PARTIAL();
1875          MRRETURN(MATCH_NOMATCH);
1876          }
1877      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
1878      if (      if (
1879  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
# Line 1371  for (;;) Line 1881  for (;;)
1881  #endif  #endif
1882         (md->ctypes[c] & ctype_digit) == 0         (md->ctypes[c] & ctype_digit) == 0
1883         )         )
1884        RRETURN(MATCH_NOMATCH);        MRRETURN(MATCH_NOMATCH);
1885      ecode++;      ecode++;
1886      break;      break;
1887    
1888      case OP_NOT_WHITESPACE:      case OP_NOT_WHITESPACE:
1889      if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);      if (eptr >= md->end_subject)
1890          {
1891          SCHECK_PARTIAL();
1892          MRRETURN(MATCH_NOMATCH);
1893          }
1894      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
1895      if (      if (
1896  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
# Line 1384  for (;;) Line 1898  for (;;)
1898  #endif  #endif
1899         (md->ctypes[c] & ctype_space) != 0         (md->ctypes[c] & ctype_space) != 0
1900         )         )
1901        RRETURN(MATCH_NOMATCH);        MRRETURN(MATCH_NOMATCH);
1902      ecode++;      ecode++;
1903      break;      break;
1904    
1905      case OP_WHITESPACE:      case OP_WHITESPACE:
1906      if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);      if (eptr >= md->end_subject)
1907          {
1908          SCHECK_PARTIAL();
1909          MRRETURN(MATCH_NOMATCH);
1910          }
1911      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
1912      if (      if (
1913  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
# Line 1397  for (;;) Line 1915  for (;;)
1915  #endif  #endif
1916         (md->ctypes[c] & ctype_space) == 0         (md->ctypes[c] & ctype_space) == 0
1917         )         )
1918        RRETURN(MATCH_NOMATCH);        MRRETURN(MATCH_NOMATCH);
1919      ecode++;      ecode++;
1920      break;      break;
1921    
1922      case OP_NOT_WORDCHAR:      case OP_NOT_WORDCHAR:
1923      if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);      if (eptr >= md->end_subject)
1924          {
1925          SCHECK_PARTIAL();
1926          MRRETURN(MATCH_NOMATCH);
1927          }
1928      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
1929      if (      if (
1930  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
# Line 1410  for (;;) Line 1932  for (;;)
1932  #endif  #endif
1933         (md->ctypes[c] & ctype_word) != 0         (md->ctypes[c] & ctype_word) != 0
1934         )         )
1935        RRETURN(MATCH_NOMATCH);        MRRETURN(MATCH_NOMATCH);
1936      ecode++;      ecode++;
1937      break;      break;
1938    
1939      case OP_WORDCHAR:      case OP_WORDCHAR:
1940      if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);      if (eptr >= md->end_subject)
1941          {
1942          SCHECK_PARTIAL();
1943          MRRETURN(MATCH_NOMATCH);
1944          }
1945      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
1946      if (      if (
1947  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
# Line 1423  for (;;) Line 1949  for (;;)
1949  #endif  #endif
1950         (md->ctypes[c] & ctype_word) == 0         (md->ctypes[c] & ctype_word) == 0
1951         )         )
1952        RRETURN(MATCH_NOMATCH);        MRRETURN(MATCH_NOMATCH);
1953      ecode++;      ecode++;
1954      break;      break;
1955    
1956      case OP_ANYNL:      case OP_ANYNL:
1957      if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);      if (eptr >= md->end_subject)
1958          {
1959          SCHECK_PARTIAL();
1960          MRRETURN(MATCH_NOMATCH);
1961          }
1962      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
1963      switch(c)      switch(c)
1964        {        {
1965        default: RRETURN(MATCH_NOMATCH);        default: MRRETURN(MATCH_NOMATCH);
1966        case 0x000d:        case 0x000d:
1967        if (eptr < md->end_subject && *eptr == 0x0a) eptr++;        if (eptr < md->end_subject && *eptr == 0x0a) eptr++;
1968        break;        break;
1969    
1970        case 0x000a:        case 0x000a:
1971          break;
1972    
1973        case 0x000b:        case 0x000b:
1974        case 0x000c:        case 0x000c:
1975        case 0x0085:        case 0x0085:
1976        case 0x2028:        case 0x2028:
1977        case 0x2029:        case 0x2029:
1978          if (md->bsr_anycrlf) MRRETURN(MATCH_NOMATCH);
1979        break;        break;
1980        }        }
1981      ecode++;      ecode++;
1982      break;      break;
1983    
1984  #ifdef SUPPORT_UCP      case OP_NOT_HSPACE:
1985      /* Check the next character by Unicode property. We will get here only      if (eptr >= md->end_subject)
1986      if the support is in the binary; otherwise a compile-time error occurs. */        {
1987          SCHECK_PARTIAL();
1988      case OP_PROP:        MRRETURN(MATCH_NOMATCH);
1989          }
1990        GETCHARINCTEST(c, eptr);
1991        switch(c)
1992          {
1993          default: break;
1994          case 0x09:      /* HT */
1995          case 0x20:      /* SPACE */
1996          case 0xa0:      /* NBSP */
1997          case 0x1680:    /* OGHAM SPACE MARK */
1998          case 0x180e:    /* MONGOLIAN VOWEL SEPARATOR */
1999          case 0x2000:    /* EN QUAD */
2000          case 0x2001:    /* EM QUAD */
2001          case 0x2002:    /* EN SPACE */
2002          case 0x2003:    /* EM SPACE */
2003          case 0x2004:    /* THREE-PER-EM SPACE */
2004          case 0x2005:    /* FOUR-PER-EM SPACE */
2005          case 0x2006:    /* SIX-PER-EM SPACE */
2006          case 0x2007:    /* FIGURE SPACE */
2007          case 0x2008:    /* PUNCTUATION SPACE */
2008          case 0x2009:    /* THIN SPACE */
2009          case 0x200A:    /* HAIR SPACE */
2010          case 0x202f:    /* NARROW NO-BREAK SPACE */
2011          case 0x205f:    /* MEDIUM MATHEMATICAL SPACE */
2012          case 0x3000:    /* IDEOGRAPHIC SPACE */
2013          MRRETURN(MATCH_NOMATCH);
2014          }
2015        ecode++;
2016        break;
2017    
2018        case OP_HSPACE:
2019        if (eptr >= md->end_subject)
2020          {
2021          SCHECK_PARTIAL();
2022          MRRETURN(MATCH_NOMATCH);
2023          }
2024        GETCHARINCTEST(c, eptr);
2025        switch(c)
2026          {
2027          default: MRRETURN(MATCH_NOMATCH);
2028          case 0x09:      /* HT */
2029          case 0x20:      /* SPACE */
2030          case 0xa0:      /* NBSP */
2031          case 0x1680:    /* OGHAM SPACE MARK */
2032          case 0x180e:    /* MONGOLIAN VOWEL SEPARATOR */
2033          case 0x2000:    /* EN QUAD */
2034          case 0x2001:    /* EM QUAD */
2035          case 0x2002:    /* EN SPACE */
2036          case 0x2003:    /* EM SPACE */
2037          case 0x2004:    /* THREE-PER-EM SPACE */
2038          case 0x2005:    /* FOUR-PER-EM SPACE */
2039          case 0x2006:    /* SIX-PER-EM SPACE */
2040          case 0x2007:    /* FIGURE SPACE */
2041          case 0x2008:    /* PUNCTUATION SPACE */
2042          case 0x2009:    /* THIN SPACE */
2043          case 0x200A:    /* HAIR SPACE */
2044          case 0x202f:    /* NARROW NO-BREAK SPACE */
2045          case 0x205f:    /* MEDIUM MATHEMATICAL SPACE */
2046          case 0x3000:    /* IDEOGRAPHIC SPACE */
2047          break;
2048          }
2049        ecode++;
2050        break;
2051    
2052        case OP_NOT_VSPACE:
2053        if (eptr >= md->end_subject)
2054          {
2055          SCHECK_PARTIAL();
2056          MRRETURN(MATCH_NOMATCH);
2057          }
2058        GETCHARINCTEST(c, eptr);
2059        switch(c)
2060          {
2061          default: break;
2062          case 0x0a:      /* LF */
2063          case 0x0b:      /* VT */
2064          case 0x0c:      /* FF */
2065          case 0x0d:      /* CR */
2066          case 0x85:      /* NEL */
2067          case 0x2028:    /* LINE SEPARATOR */
2068          case 0x2029:    /* PARAGRAPH SEPARATOR */
2069          MRRETURN(MATCH_NOMATCH);
2070          }
2071        ecode++;
2072        break;
2073    
2074        case OP_VSPACE:
2075        if (eptr >= md->end_subject)
2076          {
2077          SCHECK_PARTIAL();
2078          MRRETURN(MATCH_NOMATCH);
2079          }
2080        GETCHARINCTEST(c, eptr);
2081        switch(c)
2082          {
2083          default: MRRETURN(MATCH_NOMATCH);
2084          case 0x0a:      /* LF */
2085          case 0x0b:      /* VT */
2086          case 0x0c:      /* FF */
2087          case 0x0d:      /* CR */
2088          case 0x85:      /* NEL */
2089          case 0x2028:    /* LINE SEPARATOR */
2090          case 0x2029:    /* PARAGRAPH SEPARATOR */
2091          break;
2092          }
2093        ecode++;
2094        break;
2095    
2096    #ifdef SUPPORT_UCP
2097        /* Check the next character by Unicode property. We will get here only
2098        if the support is in the binary; otherwise a compile-time error occurs. */
2099    
2100        case OP_PROP:
2101      case OP_NOTPROP:      case OP_NOTPROP:
2102      if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);      if (eptr >= md->end_subject)
2103          {
2104          SCHECK_PARTIAL();
2105          MRRETURN(MATCH_NOMATCH);
2106          }
2107      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
2108        {        {
2109        int chartype, script;        const ucd_record *prop = GET_UCD(c);
       int category = _pcre_ucp_findprop(c, &chartype, &script);  
2110    
2111        switch(ecode[1])        switch(ecode[1])
2112          {          {
2113          case PT_ANY:          case PT_ANY:
2114          if (op == OP_NOTPROP) RRETURN(MATCH_NOMATCH);          if (op == OP_NOTPROP) MRRETURN(MATCH_NOMATCH);
2115          break;          break;
2116    
2117          case PT_LAMP:          case PT_LAMP:
2118          if ((chartype == ucp_Lu ||          if ((prop->chartype == ucp_Lu ||
2119               chartype == ucp_Ll ||               prop->chartype == ucp_Ll ||
2120               chartype == ucp_Lt) == (op == OP_NOTPROP))               prop->chartype == ucp_Lt) == (op == OP_NOTPROP))
2121            RRETURN(MATCH_NOMATCH);            MRRETURN(MATCH_NOMATCH);
2122           break;          break;
2123    
2124          case PT_GC:          case PT_GC:
2125          if ((ecode[2] != category) == (op == OP_PROP))          if ((ecode[2] != _pcre_ucp_gentype[prop->chartype]) == (op == OP_PROP))
2126            RRETURN(MATCH_NOMATCH);            MRRETURN(MATCH_NOMATCH);
2127          break;          break;
2128    
2129          case PT_PC:          case PT_PC:
2130          if ((ecode[2] != chartype) == (op == OP_PROP))          if ((ecode[2] != prop->chartype) == (op == OP_PROP))
2131            RRETURN(MATCH_NOMATCH);            MRRETURN(MATCH_NOMATCH);
2132          break;          break;
2133    
2134          case PT_SC:          case PT_SC:
2135          if ((ecode[2] != script) == (op == OP_PROP))          if ((ecode[2] != prop->script) == (op == OP_PROP))
2136            RRETURN(MATCH_NOMATCH);            MRRETURN(MATCH_NOMATCH);
2137            break;
2138    
2139            /* These are specials */
2140    
2141            case PT_ALNUM:
2142            if ((_pcre_ucp_gentype[prop->chartype] == ucp_L ||
2143                 _pcre_ucp_gentype[prop->chartype] == ucp_N) == (op == OP_NOTPROP))
2144              MRRETURN(MATCH_NOMATCH);
2145            break;
2146    
2147            case PT_SPACE:    /* Perl space */
2148            if ((_pcre_ucp_gentype[prop->chartype] == ucp_Z ||
2149                 c == CHAR_HT || c == CHAR_NL || c == CHAR_FF || c == CHAR_CR)
2150                   == (op == OP_NOTPROP))
2151              MRRETURN(MATCH_NOMATCH);
2152            break;
2153    
2154            case PT_PXSPACE:  /* POSIX space */
2155            if ((_pcre_ucp_gentype[prop->chartype] == ucp_Z ||
2156                 c == CHAR_HT || c == CHAR_NL || c == CHAR_VT ||
2157                 c == CHAR_FF || c == CHAR_CR)
2158                   == (op == OP_NOTPROP))
2159              MRRETURN(MATCH_NOMATCH);
2160            break;
2161    
2162            case PT_WORD:
2163            if ((_pcre_ucp_gentype[prop->chartype] == ucp_L ||
2164                 _pcre_ucp_gentype[prop->chartype] == ucp_N ||
2165                 c == CHAR_UNDERSCORE) == (op == OP_NOTPROP))
2166              MRRETURN(MATCH_NOMATCH);
2167          break;          break;
2168    
2169            /* This should never occur */
2170    
2171          default:          default:
2172          RRETURN(PCRE_ERROR_INTERNAL);          RRETURN(PCRE_ERROR_INTERNAL);
2173          }          }
# Line 1499  for (;;) Line 2180  for (;;)
2180      is in the binary; otherwise a compile-time error occurs. */      is in the binary; otherwise a compile-time error occurs. */
2181    
2182      case OP_EXTUNI:      case OP_EXTUNI:
2183      if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);      if (eptr >= md->end_subject)
2184          {
2185          SCHECK_PARTIAL();
2186          MRRETURN(MATCH_NOMATCH);
2187          }
2188      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
2189        {        {
2190        int chartype, script;        int category = UCD_CATEGORY(c);
2191        int category = _pcre_ucp_findprop(c, &chartype, &script);        if (category == ucp_M) MRRETURN(MATCH_NOMATCH);
       if (category == ucp_M) RRETURN(MATCH_NOMATCH);  
2192        while (eptr < md->end_subject)        while (eptr < md->end_subject)
2193          {          {
2194          int len = 1;          int len = 1;
# Line 1512  for (;;) Line 2196  for (;;)
2196            {            {
2197            GETCHARLEN(c, eptr, len);            GETCHARLEN(c, eptr, len);
2198            }            }
2199          category = _pcre_ucp_findprop(c, &chartype, &script);          category = UCD_CATEGORY(c);
2200          if (category != ucp_M) break;          if (category != ucp_M) break;
2201          eptr += len;          eptr += len;
2202          }          }
# Line 1533  for (;;) Line 2217  for (;;)
2217      case OP_REF:      case OP_REF:
2218        {        {
2219        offset = GET2(ecode, 1) << 1;               /* Doubled ref number */        offset = GET2(ecode, 1) << 1;               /* Doubled ref number */
2220        ecode += 3;                                 /* Advance past item */        ecode += 3;
2221    
2222          /* If the reference is unset, there are two possibilities:
2223    
2224        /* If the reference is unset, set the length to be longer than the amount        (a) In the default, Perl-compatible state, set the length to be longer
2225        of subject left; this ensures that every attempt at a match fails. We        than the amount of subject left; this ensures that every attempt at a
2226        can't just fail here, because of the possibility of quantifiers with zero        match fails. We can't just fail here, because of the possibility of
2227        minima. */        quantifiers with zero minima.
2228    
2229        length = (offset >= offset_top || md->offset_vector[offset] < 0)?        (b) If the JavaScript compatibility flag is set, set the length to zero
2230          md->end_subject - eptr + 1 :        so that the back reference matches an empty string.
2231          md->offset_vector[offset+1] - md->offset_vector[offset];  
2232          Otherwise, set the length to the length of what was matched by the
2233          referenced subpattern. */
2234    
2235          if (offset >= offset_top || md->offset_vector[offset] < 0)
2236            length = (md->jscript_compat)? 0 : md->end_subject - eptr + 1;
2237          else
2238            length = md->offset_vector[offset+1] - md->offset_vector[offset];
2239    
2240        /* Set up for repetition, or handle the non-repeated case */        /* Set up for repetition, or handle the non-repeated case */
2241    
# Line 1571  for (;;) Line 2264  for (;;)
2264          break;          break;
2265    
2266          default:               /* No repeat follows */          default:               /* No repeat follows */
2267          if (!match_ref(offset, eptr, length, md, ims)) RRETURN(MATCH_NOMATCH);          if (!match_ref(offset, eptr, length, md, ims))
2268              {
2269              CHECK_PARTIAL();
2270              MRRETURN(MATCH_NOMATCH);
2271              }
2272          eptr += length;          eptr += length;
2273          continue;              /* With the main loop */          continue;              /* With the main loop */
2274          }          }
# Line 1587  for (;;) Line 2284  for (;;)
2284    
2285        for (i = 1; i <= min; i++)        for (i = 1; i <= min; i++)
2286          {          {
2287          if (!match_ref(offset, eptr, length, md, ims)) RRETURN(MATCH_NOMATCH);          if (!match_ref(offset, eptr, length, md, ims))
2288              {
2289              CHECK_PARTIAL();
2290              MRRETURN(MATCH_NOMATCH);
2291              }
2292          eptr += length;          eptr += length;
2293          }          }
2294    
# Line 1602  for (;;) Line 2303  for (;;)
2303          {          {
2304          for (fi = min;; fi++)          for (fi = min;; fi++)
2305            {            {
2306            RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM14);
2307            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2308            if (fi >= max || !match_ref(offset, eptr, length, md, ims))            if (fi >= max) MRRETURN(MATCH_NOMATCH);
2309              RRETURN(MATCH_NOMATCH);            if (!match_ref(offset, eptr, length, md, ims))
2310                {
2311                CHECK_PARTIAL();
2312                MRRETURN(MATCH_NOMATCH);
2313                }
2314            eptr += length;            eptr += length;
2315            }            }
2316          /* Control never gets here */          /* Control never gets here */
# Line 1618  for (;;) Line 2323  for (;;)
2323          pp = eptr;          pp = eptr;
2324          for (i = min; i < max; i++)          for (i = min; i < max; i++)
2325            {            {
2326            if (!match_ref(offset, eptr, length, md, ims)) break;            if (!match_ref(offset, eptr, length, md, ims))
2327                {
2328                CHECK_PARTIAL();
2329                break;
2330                }
2331            eptr += length;            eptr += length;
2332            }            }
2333          while (eptr >= pp)          while (eptr >= pp)
2334            {            {
2335            RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM15);
2336            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2337            eptr -= length;            eptr -= length;
2338            }            }
2339          RRETURN(MATCH_NOMATCH);          MRRETURN(MATCH_NOMATCH);
2340          }          }
2341        }        }
2342      /* Control never gets here */      /* Control never gets here */
2343    
   
   
2344      /* Match a bit-mapped character class, possibly repeatedly. This op code is      /* Match a bit-mapped character class, possibly repeatedly. This op code is
2345      used when all the characters in the class have values in the range 0-255,      used when all the characters in the class have values in the range 0-255,
2346      and either the matching is caseful, or the characters are in the range      and either the matching is caseful, or the characters are in the range
# Line 1688  for (;;) Line 2395  for (;;)
2395          {          {
2396          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
2397            {            {
2398            if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);            if (eptr >= md->end_subject)
2399                {
2400                SCHECK_PARTIAL();
2401                MRRETURN(MATCH_NOMATCH);
2402                }
2403            GETCHARINC(c, eptr);            GETCHARINC(c, eptr);
2404            if (c > 255)            if (c > 255)
2405              {              {
2406              if (op == OP_CLASS) RRETURN(MATCH_NOMATCH);              if (op == OP_CLASS) MRRETURN(MATCH_NOMATCH);
2407              }              }
2408            else            else
2409              {              {
2410              if ((data[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);              if ((data[c/8] & (1 << (c&7))) == 0) MRRETURN(MATCH_NOMATCH);
2411              }              }
2412            }            }
2413          }          }
# Line 1706  for (;;) Line 2417  for (;;)
2417          {          {
2418          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
2419            {            {
2420            if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);            if (eptr >= md->end_subject)
2421                {
2422                SCHECK_PARTIAL();
2423                MRRETURN(MATCH_NOMATCH);
2424                }
2425            c = *eptr++;            c = *eptr++;
2426            if ((data[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);            if ((data[c/8] & (1 << (c&7))) == 0) MRRETURN(MATCH_NOMATCH);
2427            }            }
2428          }          }
2429    
# Line 1728  for (;;) Line 2443  for (;;)
2443            {            {
2444            for (fi = min;; fi++)            for (fi = min;; fi++)
2445              {              {
2446              RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM16);
2447              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2448              if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);              if (fi >= max) MRRETURN(MATCH_NOMATCH);
2449                if (eptr >= md->end_subject)
2450                  {
2451                  SCHECK_PARTIAL();
2452                  MRRETURN(MATCH_NOMATCH);
2453                  }
2454              GETCHARINC(c, eptr);              GETCHARINC(c, eptr);
2455              if (c > 255)              if (c > 255)
2456                {                {
2457                if (op == OP_CLASS) RRETURN(MATCH_NOMATCH);                if (op == OP_CLASS) MRRETURN(MATCH_NOMATCH);
2458                }                }
2459              else              else
2460                {                {
2461                if ((data[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);                if ((data[c/8] & (1 << (c&7))) == 0) MRRETURN(MATCH_NOMATCH);
2462                }                }
2463              }              }
2464            }            }
# Line 1748  for (;;) Line 2468  for (;;)
2468            {            {
2469            for (fi = min;; fi++)            for (fi = min;; fi++)
2470              {              {
2471              RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM17);
2472              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2473              if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);              if (fi >= max) MRRETURN(MATCH_NOMATCH);
2474                if (eptr >= md->end_subject)
2475                  {
2476                  SCHECK_PARTIAL();
2477                  MRRETURN(MATCH_NOMATCH);
2478                  }
2479              c = *eptr++;              c = *eptr++;
2480              if ((data[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);              if ((data[c/8] & (1 << (c&7))) == 0) MRRETURN(MATCH_NOMATCH);
2481              }              }
2482            }            }
2483          /* Control never gets here */          /* Control never gets here */
# Line 1771  for (;;) Line 2496  for (;;)
2496            for (i = min; i < max; i++)            for (i = min; i < max; i++)
2497              {              {
2498              int len = 1;              int len = 1;
2499              if (eptr >= md->end_subject) break;              if (eptr >= md->end_subject)
2500                  {
2501                  SCHECK_PARTIAL();
2502                  break;
2503                  }
2504              GETCHARLEN(c, eptr, len);              GETCHARLEN(c, eptr, len);
2505              if (c > 255)              if (c > 255)
2506                {                {
# Line 1785  for (;;) Line 2514  for (;;)
2514              }              }
2515            for (;;)            for (;;)
2516              {              {
2517              RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM18);
2518              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2519              if (eptr-- == pp) break;        /* Stop if tried at original pos */              if (eptr-- == pp) break;        /* Stop if tried at original pos */
2520              BACKCHAR(eptr);              BACKCHAR(eptr);
# Line 1797  for (;;) Line 2526  for (;;)
2526            {            {
2527            for (i = min; i < max; i++)            for (i = min; i < max; i++)
2528              {              {
2529              if (eptr >= md->end_subject) break;              if (eptr >= md->end_subject)
2530                  {
2531                  SCHECK_PARTIAL();
2532                  break;
2533                  }
2534              c = *eptr;              c = *eptr;
2535              if ((data[c/8] & (1 << (c&7))) == 0) break;              if ((data[c/8] & (1 << (c&7))) == 0) break;
2536              eptr++;              eptr++;
2537              }              }
2538            while (eptr >= pp)            while (eptr >= pp)
2539              {              {
2540              RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM19);
2541              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2542              eptr--;              eptr--;
2543              }              }
2544            }            }
2545    
2546          RRETURN(MATCH_NOMATCH);          MRRETURN(MATCH_NOMATCH);
2547          }          }
2548        }        }
2549      /* Control never gets here */      /* Control never gets here */
2550    
2551    
2552      /* Match an extended character class. This opcode is encountered only      /* Match an extended character class. This opcode is encountered only
2553      in UTF-8 mode, because that's the only time it is compiled. */      when UTF-8 mode mode is supported. Nevertheless, we may not be in UTF-8
2554        mode, because Unicode properties are supported in non-UTF-8 mode. */
2555    
2556  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
2557      case OP_XCLASS:      case OP_XCLASS:
# Line 1858  for (;;) Line 2592  for (;;)
2592    
2593        for (i = 1; i <= min; i++)        for (i = 1; i <= min; i++)
2594          {          {
2595          if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);          if (eptr >= md->end_subject)
2596          GETCHARINC(c, eptr);            {
2597          if (!_pcre_xclass(c, data)) RRETURN(MATCH_NOMATCH);            SCHECK_PARTIAL();
2598              MRRETURN(MATCH_NOMATCH);
2599              }
2600            GETCHARINCTEST(c, eptr);
2601            if (!_pcre_xclass(c, data)) MRRETURN(MATCH_NOMATCH);
2602          }          }
2603    
2604        /* 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 1875  for (;;) Line 2613  for (;;)
2613          {          {
2614          for (fi = min;; fi++)          for (fi = min;; fi++)
2615            {            {
2616            RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM20);
2617            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2618            if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);            if (fi >= max) MRRETURN(MATCH_NOMATCH);
2619            GETCHARINC(c, eptr);            if (eptr >= md->end_subject)
2620            if (!_pcre_xclass(c, data)) RRETURN(MATCH_NOMATCH);              {
2621                SCHECK_PARTIAL();
2622                MRRETURN(MATCH_NOMATCH);
2623                }
2624              GETCHARINCTEST(c, eptr);
2625              if (!_pcre_xclass(c, data)) MRRETURN(MATCH_NOMATCH);
2626            }            }
2627          /* Control never gets here */          /* Control never gets here */
2628          }          }
# Line 1892  for (;;) Line 2635  for (;;)
2635          for (i = min; i < max; i++)          for (i = min; i < max; i++)
2636            {            {
2637            int len = 1;            int len = 1;
2638            if (eptr >= md->end_subject) break;            if (eptr >= md->end_subject)
2639            GETCHARLEN(c, eptr, len);              {
2640                SCHECK_PARTIAL();
2641                break;
2642                }
2643              GETCHARLENTEST(c, eptr, len);
2644            if (!_pcre_xclass(c, data)) break;            if (!_pcre_xclass(c, data)) break;
2645            eptr += len;            eptr += len;
2646            }            }
2647          for(;;)          for(;;)
2648            {            {
2649            RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM21);
2650            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2651            if (eptr-- == pp) break;        /* Stop if tried at original pos */            if (eptr-- == pp) break;        /* Stop if tried at original pos */
2652            BACKCHAR(eptr)            if (utf8) BACKCHAR(eptr);
2653            }            }
2654          RRETURN(MATCH_NOMATCH);          MRRETURN(MATCH_NOMATCH);
2655          }          }
2656    
2657        /* Control never gets here */        /* Control never gets here */
# Line 1920  for (;;) Line 2667  for (;;)
2667        length = 1;        length = 1;
2668        ecode++;        ecode++;
2669        GETCHARLEN(fc, ecode, length);        GETCHARLEN(fc, ecode, length);
2670        if (length > md->end_subject - eptr) RRETURN(MATCH_NOMATCH);        if (length > md->end_subject - eptr)
2671        while (length-- > 0) if (*ecode++ != *eptr++) RRETURN(MATCH_NOMATCH);          {
2672            CHECK_PARTIAL();             /* Not SCHECK_PARTIAL() */
2673            MRRETURN(MATCH_NOMATCH);
2674            }
2675          while (length-- > 0) if (*ecode++ != *eptr++) MRRETURN(MATCH_NOMATCH);
2676        }        }
2677      else      else
2678  #endif  #endif
2679    
2680      /* Non-UTF-8 mode */      /* Non-UTF-8 mode */
2681        {        {
2682        if (md->end_subject - eptr < 1) RRETURN(MATCH_NOMATCH);        if (md->end_subject - eptr < 1)
2683        if (ecode[1] != *eptr++) RRETURN(MATCH_NOMATCH);          {
2684            SCHECK_PARTIAL();            /* This one can use SCHECK_PARTIAL() */
2685            MRRETURN(MATCH_NOMATCH);
2686            }
2687          if (ecode[1] != *eptr++) MRRETURN(MATCH_NOMATCH);
2688        ecode += 2;        ecode += 2;
2689        }        }
2690      break;      break;
# Line 1944  for (;;) Line 2699  for (;;)
2699        ecode++;        ecode++;
2700        GETCHARLEN(fc, ecode, length);        GETCHARLEN(fc, ecode, length);
2701    
2702        if (length > md->end_subject - eptr) RRETURN(MATCH_NOMATCH);        if (length > md->end_subject - eptr)
2703            {
2704            CHECK_PARTIAL();             /* Not SCHECK_PARTIAL() */
2705            MRRETURN(MATCH_NOMATCH);
2706            }
2707    
2708        /* 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
2709        can use the fast lookup table. */        can use the fast lookup table. */
2710    
2711        if (fc < 128)        if (fc < 128)
2712          {          {
2713          if (md->lcc[*ecode++] != md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH);          if (md->lcc[*ecode++] != md->lcc[*eptr++]) MRRETURN(MATCH_NOMATCH);
2714          }          }
2715    
2716        /* Otherwise we must pick up the subject character */        /* Otherwise we must pick up the subject character */
# Line 1968  for (;;) Line 2727  for (;;)
2727          if (fc != dc)          if (fc != dc)
2728            {            {
2729  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2730            if (dc != _pcre_ucp_othercase(fc))            if (dc != UCD_OTHERCASE(fc))
2731  #endif  #endif
2732              RRETURN(MATCH_NOMATCH);              MRRETURN(MATCH_NOMATCH);
2733            }            }
2734          }          }
2735        }        }
# Line 1979  for (;;) Line 2738  for (;;)
2738    
2739      /* Non-UTF-8 mode */      /* Non-UTF-8 mode */
2740        {        {
2741        if (md->end_subject - eptr < 1) RRETURN(MATCH_NOMATCH);        if (md->end_subject - eptr < 1)
2742        if (md->lcc[ecode[1]] != md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH);          {
2743            SCHECK_PARTIAL();            /* This one can use SCHECK_PARTIAL() */
2744            MRRETURN(MATCH_NOMATCH);
2745            }
2746          if (md->lcc[ecode[1]] != md->lcc[*eptr++]) MRRETURN(MATCH_NOMATCH);
2747        ecode += 2;        ecode += 2;
2748        }        }
2749      break;      break;
# Line 2033  for (;;) Line 2796  for (;;)
2796      case OP_MINQUERY:      case OP_MINQUERY:
2797      c = *ecode++ - OP_STAR;      c = *ecode++ - OP_STAR;
2798      minimize = (c & 1) != 0;      minimize = (c & 1) != 0;
2799    
2800      min = rep_min[c];                 /* Pick up values from tables; */      min = rep_min[c];                 /* Pick up values from tables; */
2801      max = rep_max[c];                 /* zero for max => infinity */      max = rep_max[c];                 /* zero for max => infinity */
2802      if (max == 0) max = INT_MAX;      if (max == 0) max = INT_MAX;
2803    
2804      /* Common code for all repeated single-character matches. We can give      /* Common code for all repeated single-character matches. */
     up quickly if there are fewer than the minimum number of characters left in  
     the subject. */  
2805    
2806      REPEATCHAR:      REPEATCHAR:
2807  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
# Line 2048  for (;;) Line 2810  for (;;)
2810        length = 1;        length = 1;
2811        charptr = ecode;        charptr = ecode;
2812        GETCHARLEN(fc, ecode, length);        GETCHARLEN(fc, ecode, length);
       if (min * length > md->end_subject - eptr) RRETURN(MATCH_NOMATCH);  
2813        ecode += length;        ecode += length;
2814    
2815        /* Handle multibyte character matching specially here. There is        /* Handle multibyte character matching specially here. There is
# Line 2059  for (;;) Line 2820  for (;;)
2820  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2821          unsigned int othercase;          unsigned int othercase;
2822          if ((ims & PCRE_CASELESS) != 0 &&          if ((ims & PCRE_CASELESS) != 0 &&
2823              (othercase = _pcre_ucp_othercase(fc)) != NOTACHAR)              (othercase = UCD_OTHERCASE(fc)) != fc)
2824            oclength = _pcre_ord2utf8(othercase, occhars);            oclength = _pcre_ord2utf8(othercase, occhars);
2825          else oclength = 0;          else oclength = 0;
2826  #endif  /* SUPPORT_UCP */  #endif  /* SUPPORT_UCP */
2827    
2828          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
2829            {            {
2830            if (memcmp(eptr, charptr, length) == 0) eptr += length;            if (eptr <= md->end_subject - length &&
2831                memcmp(eptr, charptr, length) == 0) eptr += length;
2832  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2833            /* Need braces because of following else */            else if (oclength > 0 &&
2834            else if (oclength == 0) { RRETURN(MATCH_NOMATCH); }                     eptr <= md->end_subject - oclength &&
2835                       memcmp(eptr, occhars, oclength) == 0) eptr += oclength;
2836    #endif  /* SUPPORT_UCP */
2837            else            else
2838              {              {
2839              if (memcmp(eptr, occhars, oclength) != 0) RRETURN(MATCH_NOMATCH);              CHECK_PARTIAL();
2840              eptr += oclength;              MRRETURN(MATCH_NOMATCH);
2841              }              }
 #else   /* without SUPPORT_UCP */  
           else { RRETURN(MATCH_NOMATCH); }  
 #endif  /* SUPPORT_UCP */  
2842            }            }
2843    
2844          if (min == max) continue;          if (min == max) continue;
# Line 2086  for (;;) Line 2847  for (;;)
2847            {            {
2848            for (fi = min;; fi++)            for (fi = min;; fi++)
2849              {              {
2850              RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM22);
2851              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2852              if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);              if (fi >= max) MRRETURN(MATCH_NOMATCH);
2853              if (memcmp(eptr, charptr, length) == 0) eptr += length;              if (eptr <= md->end_subject - length &&
2854                  memcmp(eptr, charptr, length) == 0) eptr += length;
2855  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2856              /* Need braces because of following else */              else if (oclength > 0 &&
2857              else if (oclength == 0) { RRETURN(MATCH_NOMATCH); }                       eptr <= md->end_subject - oclength &&
2858                         memcmp(eptr, occhars, oclength) == 0) eptr += oclength;
2859    #endif  /* SUPPORT_UCP */
2860              else              else
2861                {                {
2862                if (memcmp(eptr, occhars, oclength) != 0) RRETURN(MATCH_NOMATCH);                CHECK_PARTIAL();
2863                eptr += oclength;                MRRETURN(MATCH_NOMATCH);
2864                }                }
 #else   /* without SUPPORT_UCP */  
             else { RRETURN (MATCH_NOMATCH); }  
 #endif  /* SUPPORT_UCP */  
2865              }              }
2866            /* Control never gets here */            /* Control never gets here */
2867            }            }
# Line 2110  for (;;) Line 2871  for (;;)
2871            pp = eptr;            pp = eptr;
2872            for (i = min; i < max; i++)            for (i = min; i < max; i++)
2873              {              {
2874              if (eptr > md->end_subject - length) break;              if (eptr <= md->end_subject - length &&
2875              if (memcmp(eptr, charptr, length) == 0) eptr += length;                  memcmp(eptr, charptr, length) == 0) eptr += length;
2876  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2877              else if (oclength == 0) break;              else if (oclength > 0 &&
2878                         eptr <= md->end_subject - oclength &&
2879                         memcmp(eptr, occhars, oclength) == 0) eptr += oclength;
2880    #endif  /* SUPPORT_UCP */
2881              else              else
2882                {                {
2883                if (memcmp(eptr, occhars, oclength) != 0) break;                CHECK_PARTIAL();
2884                eptr += oclength;                break;
2885                }                }
 #else   /* without SUPPORT_UCP */  
             else break;  
 #endif  /* SUPPORT_UCP */  
2886              }              }
2887    
2888            if (possessive) continue;            if (possessive) continue;
2889    
2890            for(;;)            for(;;)
2891             {              {
2892             RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM23);
2893             if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2894             if (eptr == pp) RRETURN(MATCH_NOMATCH);              if (eptr == pp) { MRRETURN(MATCH_NOMATCH); }
2895  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2896             eptr--;              eptr--;
2897             BACKCHAR(eptr);              BACKCHAR(eptr);
2898  #else   /* without SUPPORT_UCP */  #else   /* without SUPPORT_UCP */
2899             eptr -= length;              eptr -= length;
2900  #endif  /* SUPPORT_UCP */  #endif  /* SUPPORT_UCP */
2901             }              }
2902            }            }
2903          /* Control never gets here */          /* Control never gets here */
2904          }          }
# Line 2149  for (;;) Line 2911  for (;;)
2911  #endif  /* SUPPORT_UTF8 */  #endif  /* SUPPORT_UTF8 */
2912    
2913      /* When not in UTF-8 mode, load a single-byte character. */      /* When not in UTF-8 mode, load a single-byte character. */
2914        {  
2915        if (min > md->end_subject - eptr) RRETURN(MATCH_NOMATCH);      fc = *ecode++;
       fc = *ecode++;  
       }  
2916    
2917      /* The value of fc at this point is always less than 256, though we may or      /* The value of fc at this point is always less than 256, though we may or
2918      may not be in UTF-8 mode. The code is duplicated for the caseless and      may not be in UTF-8 mode. The code is duplicated for the caseless and
# Line 2170  for (;;) Line 2930  for (;;)
2930        {        {
2931        fc = md->lcc[fc];        fc = md->lcc[fc];
2932        for (i = 1; i <= min; i++)        for (i = 1; i <= min; i++)
2933          if (fc != md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH);          {
2934            if (eptr >= md->end_subject)
2935              {
2936              SCHECK_PARTIAL();
2937              MRRETURN(MATCH_NOMATCH);
2938              }
2939            if (fc != md->lcc[*eptr++]) MRRETURN(MATCH_NOMATCH);
2940            }
2941        if (min == max) continue;        if (min == max) continue;
2942        if (minimize)        if (minimize)
2943          {          {
2944          for (fi = min;; fi++)          for (fi = min;; fi++)
2945            {            {
2946            RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM24);
2947            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2948            if (fi >= max || eptr >= md->end_subject ||            if (fi >= max) MRRETURN(MATCH_NOMATCH);
2949                fc != md->lcc[*eptr++])            if (eptr >= md->end_subject)
2950              RRETURN(MATCH_NOMATCH);              {
2951                SCHECK_PARTIAL();
2952                MRRETURN(MATCH_NOMATCH);
2953                }
2954              if (fc != md->lcc[*eptr++]) MRRETURN(MATCH_NOMATCH);
2955            }            }
2956          /* Control never gets here */          /* Control never gets here */
2957          }          }
# Line 2189  for (;;) Line 2960  for (;;)
2960          pp = eptr;          pp = eptr;
2961          for (i = min; i < max; i++)          for (i = min; i < max; i++)
2962            {            {
2963            if (eptr >= md->end_subject || fc != md->lcc[*eptr]) break;            if (eptr >= md->end_subject)
2964                {
2965                SCHECK_PARTIAL();
2966                break;
2967                }
2968              if (fc != md->lcc[*eptr]) break;
2969            eptr++;            eptr++;
2970            }            }
2971    
2972          if (possessive) continue;          if (possessive) continue;
2973    
2974          while (eptr >= pp)          while (eptr >= pp)
2975            {            {
2976            RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM25);
2977            eptr--;            eptr--;
2978            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2979            }            }
2980          RRETURN(MATCH_NOMATCH);          MRRETURN(MATCH_NOMATCH);
2981          }          }
2982        /* Control never gets here */        /* Control never gets here */
2983        }        }
# Line 2208  for (;;) Line 2986  for (;;)
2986    
2987      else      else
2988        {        {
2989        for (i = 1; i <= min; i++) if (fc != *eptr++) RRETURN(MATCH_NOMATCH);        for (i = 1; i <= min; i++)
2990            {
2991            if (eptr >= md->end_subject)
2992              {
2993              SCHECK_PARTIAL();
2994              MRRETURN(MATCH_NOMATCH);
2995              }
2996            if (fc != *eptr++) MRRETURN(MATCH_NOMATCH);
2997            }
2998    
2999        if (min == max) continue;        if (min == max) continue;
3000    
3001        if (minimize)        if (minimize)
3002          {          {
3003          for (fi = min;; fi++)          for (fi = min;; fi++)
3004            {            {
3005            RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM26);
3006            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3007            if (fi >= max || eptr >= md->end_subject || fc != *eptr++)            if (fi >= max) MRRETURN(MATCH_NOMATCH);
3008              RRETURN(MATCH_NOMATCH);            if (eptr >= md->end_subject)
3009                {
3010                SCHECK_PARTIAL();
3011                MRRETURN(MATCH_NOMATCH);
3012                }
3013              if (fc != *eptr++) MRRETURN(MATCH_NOMATCH);
3014            }            }
3015          /* Control never gets here */          /* Control never gets here */
3016          }          }
# Line 2226  for (;;) Line 3019  for (;;)
3019          pp = eptr;          pp = eptr;
3020          for (i = min; i < max; i++)          for (i = min; i < max; i++)
3021            {            {
3022            if (eptr >= md->end_subject || fc != *eptr) break;            if (eptr >= md->end_subject)
3023                {
3024                SCHECK_PARTIAL();
3025                break;
3026                }
3027              if (fc != *eptr) break;
3028            eptr++;            eptr++;
3029            }            }
3030          if (possessive) continue;          if (possessive) continue;
3031    
3032          while (eptr >= pp)          while (eptr >= pp)
3033            {            {
3034            RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM27);
3035            eptr--;            eptr--;
3036            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3037            }            }
3038          RRETURN(MATCH_NOMATCH);          MRRETURN(MATCH_NOMATCH);
3039          }          }
3040        }        }
3041      /* Control never gets here */      /* Control never gets here */
# Line 2245  for (;;) Line 3044  for (;;)
3044      checking can be multibyte. */      checking can be multibyte. */
3045    
3046      case OP_NOT:      case OP_NOT:
3047      if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);      if (eptr >= md->end_subject)
3048          {
3049          SCHECK_PARTIAL();
3050          MRRETURN(MATCH_NOMATCH);
3051          }
3052      ecode++;      ecode++;
3053      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
3054      if ((ims & PCRE_CASELESS) != 0)      if ((ims & PCRE_CASELESS) != 0)
# Line 2254  for (;;) Line 3057  for (;;)
3057        if (c < 256)        if (c < 256)
3058  #endif  #endif
3059        c = md->lcc[c];        c = md->lcc[c];
3060        if (md->lcc[*ecode++] == c) RRETURN(MATCH_NOMATCH);        if (md->lcc[*ecode++] == c) MRRETURN(MATCH_NOMATCH);
3061        }        }
3062      else      else
3063        {        {
3064        if (*ecode++ == c) RRETURN(MATCH_NOMATCH);        if (*ecode++ == c) MRRETURN(MATCH_NOMATCH);
3065        }        }
3066      break;      break;
3067    
# Line 2322  for (;;) Line 3125  for (;;)
3125      max = rep_max[c];                 /* zero for max => infinity */      max = rep_max[c];                 /* zero for max => infinity */
3126      if (max == 0) max = INT_MAX;      if (max == 0) max = INT_MAX;
3127    
3128      /* Common code for all repeated single-byte matches. We can give up quickly      /* Common code for all repeated single-byte matches. */
     if there are fewer than the minimum number of bytes left in the  
     subject. */  
3129    
3130      REPEATNOTCHAR:      REPEATNOTCHAR:
     if (min > md->end_subject - eptr) RRETURN(MATCH_NOMATCH);  
3131      fc = *ecode++;      fc = *ecode++;
3132    
3133      /* The code is duplicated for the caseless and caseful cases, for speed,      /* The code is duplicated for the caseless and caseful cases, for speed,
# Line 2352  for (;;) Line 3152  for (;;)
3152          register unsigned int d;          register unsigned int d;
3153          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3154            {            {
3155              if (eptr >= md->end_subject)
3156                {
3157                SCHECK_PARTIAL();
3158                MRRETURN(MATCH_NOMATCH);
3159                }
3160            GETCHARINC(d, eptr);            GETCHARINC(d, eptr);
3161            if (d < 256) d = md->lcc[d];            if (d < 256) d = md->lcc[d];
3162            if (fc == d) RRETURN(MATCH_NOMATCH);            if (fc == d) MRRETURN(MATCH_NOMATCH);
3163            }            }
3164          }          }
3165        else        else
# Line 2363  for (;;) Line 3168  for (;;)
3168        /* Not UTF-8 mode */        /* Not UTF-8 mode */
3169          {          {
3170          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3171            if (fc == md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH);            {
3172              if (eptr >= md->end_subject)
3173                {
3174                SCHECK_PARTIAL();
3175                MRRETURN(MATCH_NOMATCH);
3176                }
3177              if (fc == md->lcc[*eptr++]) MRRETURN(MATCH_NOMATCH);
3178              }
3179          }          }
3180    
3181        if (min == max) continue;        if (min == max) continue;
# Line 2377  for (;;) Line 3189  for (;;)
3189            register unsigned int d;            register unsigned int d;
3190            for (fi = min;; fi++)            for (fi = min;; fi++)
3191              {              {
3192              RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM28);
3193              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3194                if (fi >= max) MRRETURN(MATCH_NOMATCH);
3195                if (eptr >= md->end_subject)
3196                  {
3197                  SCHECK_PARTIAL();
3198                  MRRETURN(MATCH_NOMATCH);
3199                  }
3200              GETCHARINC(d, eptr);              GETCHARINC(d, eptr);
3201              if (d < 256) d = md->lcc[d];              if (d < 256) d = md->lcc[d];
3202              if (fi >= max || eptr >= md->end_subject || fc == d)              if (fc == d) MRRETURN(MATCH_NOMATCH);
               RRETURN(MATCH_NOMATCH);  
3203              }              }
3204            }            }
3205          else          else
# Line 2391  for (;;) Line 3208  for (;;)
3208            {            {
3209            for (fi = min;; fi++)            for (fi = min;; fi++)
3210              {              {
3211              RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM29);
3212              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3213              if (fi >= max || eptr >= md->end_subject || fc == md->lcc[*eptr++])              if (fi >= max) MRRETURN(MATCH_NOMATCH);
3214                RRETURN(MATCH_NOMATCH);              if (eptr >= md->end_subject)
3215                  {
3216                  SCHECK_PARTIAL();
3217                  MRRETURN(MATCH_NOMATCH);
3218                  }
3219                if (fc == md->lcc[*eptr++]) MRRETURN(MATCH_NOMATCH);
3220              }              }
3221            }            }
3222          /* Control never gets here */          /* Control never gets here */
# Line 2414  for (;;) Line 3236  for (;;)
3236            for (i = min; i < max; i++)            for (i = min; i < max; i++)
3237              {              {
3238              int len = 1;              int len = 1;
3239              if (eptr >= md->end_subject) break;              if (eptr >= md->end_subject)
3240                  {
3241                  SCHECK_PARTIAL();
3242                  break;
3243                  }
3244              GETCHARLEN(d, eptr, len);              GETCHARLEN(d, eptr, len);
3245              if (d < 256) d = md->lcc[d];              if (d < 256) d = md->lcc[d];
3246              if (fc == d) break;              if (fc == d) break;
# Line 2423  for (;;) Line 3249  for (;;)
3249          if (possessive) continue;          if (possessive) continue;
3250          for(;;)          for(;;)
3251              {              {
3252              RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM30);
3253              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3254              if (eptr-- == pp) break;        /* Stop if tried at original pos */              if (eptr-- == pp) break;        /* Stop if tried at original pos */
3255              BACKCHAR(eptr);              BACKCHAR(eptr);
# Line 2435  for (;;) Line 3261  for (;;)
3261            {            {
3262            for (i = min; i < max; i++)            for (i = min; i < max; i++)
3263              {              {
3264              if (eptr >= md->end_subject || fc == md->lcc[*eptr]) break;              if (eptr >= md->end_subject)
3265                  {
3266                  SCHECK_PARTIAL();
3267                  break;
3268                  }
3269                if (fc == md->lcc[*eptr]) break;
3270              eptr++;              eptr++;
3271              }              }
3272            if (possessive) continue;            if (possessive) continue;
3273            while (eptr >= pp)            while (eptr >= pp)
3274              {              {
3275              RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM31);
3276              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3277              eptr--;              eptr--;
3278              }              }
3279            }            }
3280    
3281          RRETURN(MATCH_NOMATCH);          MRRETURN(MATCH_NOMATCH);
3282          }          }
3283        /* Control never gets here */        /* Control never gets here */
3284        }        }
# Line 2463  for (;;) Line 3294  for (;;)
3294          register unsigned int d;          register unsigned int d;
3295          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3296            {            {
3297              if (eptr >= md->end_subject)
3298                {
3299                SCHECK_PARTIAL();
3300                MRRETURN(MATCH_NOMATCH);
3301                }
3302            GETCHARINC(d, eptr);            GETCHARINC(d, eptr);
3303            if (fc == d) RRETURN(MATCH_NOMATCH);            if (fc == d) MRRETURN(MATCH_NOMATCH);
3304            }            }
3305          }          }
3306        else        else
# Line 2472  for (;;) Line 3308  for (;;)
3308        /* Not UTF-8 mode */        /* Not UTF-8 mode */
3309          {          {
3310          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3311            if (fc == *eptr++) RRETURN(MATCH_NOMATCH);            {
3312              if (eptr >= md->end_subject)
3313                {
3314                SCHECK_PARTIAL();
3315                MRRETURN(MATCH_NOMATCH);
3316                }
3317              if (fc == *eptr++) MRRETURN(MATCH_NOMATCH);
3318              }
3319          }          }
3320    
3321        if (min == max) continue;        if (min == max) continue;
# Line 2486  for (;;) Line 3329  for (;;)
3329            register unsigned int d;            register unsigned int d;
3330            for (fi = min;; fi++)            for (fi = min;; fi++)
3331              {              {
3332              RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM32);
3333              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3334                if (fi >= max) MRRETURN(MATCH_NOMATCH);
3335                if (eptr >= md->end_subject)
3336                  {
3337                  SCHECK_PARTIAL();
3338                  MRRETURN(MATCH_NOMATCH);
3339                  }
3340              GETCHARINC(d, eptr);              GETCHARINC(d, eptr);
3341              if (fi >= max || eptr >= md->end_subject || fc == d)              if (fc == d) MRRETURN(MATCH_NOMATCH);
               RRETURN(MATCH_NOMATCH);  
3342              }              }
3343            }            }
3344          else          else
# Line 2499  for (;;) Line 3347  for (;;)
3347            {            {
3348            for (fi = min;; fi++)            for (fi = min;; fi++)
3349              {              {
3350              RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM33);
3351              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3352              if (fi >= max || eptr >= md->end_subject || fc == *eptr++)              if (fi >= max) MRRETURN(MATCH_NOMATCH);
3353                RRETURN(MATCH_NOMATCH);              if (eptr >= md->end_subject)
3354                  {
3355                  SCHECK_PARTIAL();
3356                  MRRETURN(MATCH_NOMATCH);
3357                  }
3358                if (fc == *eptr++) MRRETURN(MATCH_NOMATCH);
3359              }              }
3360            }            }
3361          /* Control never gets here */          /* Control never gets here */
# Line 2522  for (;;) Line 3375  for (;;)
3375            for (i = min; i < max; i++)            for (i = min; i < max; i++)
3376              {              {
3377              int len = 1;              int len = 1;
3378              if (eptr >= md->end_subject) break;              if (eptr >= md->end_subject)
3379                  {
3380                  SCHECK_PARTIAL();
3381                  break;
3382                  }
3383              GETCHARLEN(d, eptr, len);              GETCHARLEN(d, eptr, len);
3384              if (fc == d) break;              if (fc == d) break;
3385              eptr += len;              eptr += len;
# Line 2530  for (;;) Line 3387  for (;;)
3387            if (possessive) continue;            if (possessive) continue;
3388            for(;;)            for(;;)
3389              {              {
3390              RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM34);
3391              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3392              if (eptr-- == pp) break;        /* Stop if tried at original pos */              if (eptr-- == pp) break;        /* Stop if tried at original pos */
3393              BACKCHAR(eptr);              BACKCHAR(eptr);
# Line 2542  for (;;) Line 3399  for (;;)
3399            {            {
3400            for (i = min; i < max; i++)            for (i = min; i < max; i++)
3401              {              {
3402              if (eptr >= md->end_subject || fc == *eptr) break;              if (eptr >= md->end_subject)
3403                  {
3404                  SCHECK_PARTIAL();
3405                  break;
3406                  }
3407                if (fc == *eptr) break;
3408              eptr++;              eptr++;
3409              }              }
3410            if (possessive) continue;            if (possessive) continue;
3411            while (eptr >= pp)            while (eptr >= pp)
3412              {              {
3413              RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM35);
3414              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3415              eptr--;              eptr--;
3416              }              }
3417            }            }
3418    
3419          RRETURN(MATCH_NOMATCH);          MRRETURN(MATCH_NOMATCH);
3420          }          }
3421        }        }
3422      /* Control never gets here */      /* Control never gets here */
# Line 2636  for (;;) Line 3498  for (;;)
3498    
3499      /* First, ensure the minimum number of matches are present. Use inline      /* First, ensure the minimum number of matches are present. Use inline
3500      code for maximizing the speed, and do the type test once at the start      code for maximizing the speed, and do the type test once at the start
3501      (i.e. keep it out of the loop). Also we can test that there are at least      (i.e. keep it out of the loop). Separate the UTF-8 code completely as that
     the minimum number of bytes before we start. This isn't as effective in  
     UTF-8 mode, but it does no harm. Separate the UTF-8 code completely as that  
3502      is tidier. Also separate the UCP code, which can be the same for both UTF-8      is tidier. Also separate the UCP code, which can be the same for both UTF-8
3503      and single-bytes. */      and single-bytes. */
3504    
     if (min > md->end_subject - eptr) RRETURN(MATCH_NOMATCH);  
3505      if (min > 0)      if (min > 0)
3506        {        {
3507  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
# Line 2651  for (;;) Line 3510  for (;;)
3510          switch(prop_type)          switch(prop_type)
3511            {            {
3512            case PT_ANY:            case PT_ANY:
3513            if (prop_fail_result) RRETURN(MATCH_NOMATCH);            if (prop_fail_result) MRRETURN(MATCH_NOMATCH);
3514            for (i = 1; i <= min; i++)            for (i = 1; i <= min; i++)
3515              {              {
3516              if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);              if (eptr >= md->end_subject)
3517              GETCHARINC(c, eptr);                {
3518                  SCHECK_PARTIAL();
3519                  MRRETURN(MATCH_NOMATCH);
3520                  }
3521                GETCHARINCTEST(c, eptr);
3522              }              }
3523            break;            break;
3524    
3525            case PT_LAMP:            case PT_LAMP:
3526            for (i = 1; i <= min; i++)            for (i = 1; i <= min; i++)
3527              {              {
3528              if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);              if (eptr >= md->end_subject)
3529              GETCHARINC(c, eptr);                {
3530              prop_category = _pcre_ucp_findprop(c, &prop_chartype, &prop_script);                SCHECK_PARTIAL();
3531                  MRRETURN(MATCH_NOMATCH);
3532                  }
3533                GETCHARINCTEST(c, eptr);
3534                prop_chartype = UCD_CHARTYPE(c);
3535              if ((prop_chartype == ucp_Lu ||              if ((prop_chartype == ucp_Lu ||
3536                   prop_chartype == ucp_Ll ||                   prop_chartype == ucp_Ll ||
3537                   prop_chartype == ucp_Lt) == prop_fail_result)                   prop_chartype == ucp_Lt) == prop_fail_result)
3538                RRETURN(MATCH_NOMATCH);                MRRETURN(MATCH_NOMATCH);
3539              }              }
3540            break;            break;
3541    
3542            case PT_GC:            case PT_GC:
3543            for (i = 1; i <= min; i++)            for (i = 1; i <= min; i++)
3544              {              {
3545              if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);              if (eptr >= md->end_subject)
3546              GETCHARINC(c, eptr);                {
3547              prop_category = _pcre_ucp_findprop(c, &prop_chartype, &prop_script);                SCHECK_PARTIAL();
3548                  MRRETURN(MATCH_NOMATCH);
3549                  }
3550                GETCHARINCTEST(c, eptr);
3551                prop_category = UCD_CATEGORY(c);
3552              if ((prop_category == prop_value) == prop_fail_result)              if ((prop_category == prop_value) == prop_fail_result)
3553                RRETURN(MATCH_NOMATCH);                MRRETURN(MATCH_NOMATCH);
3554              }              }
3555            break;            break;
3556    
3557            case PT_PC:            case PT_PC:
3558            for (i = 1; i <= min; i++)            for (i = 1; i <= min; i++)
3559              {              {
3560              if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);              if (eptr >= md->end_subject)
3561              GETCHARINC(c, eptr);                {
3562              prop_category = _pcre_ucp_findprop(c, &prop_chartype, &prop_script);                SCHECK_PARTIAL();
3563                  MRRETURN(MATCH_NOMATCH);
3564                  }
3565                GETCHARINCTEST(c, eptr);
3566                prop_chartype = UCD_CHARTYPE(c);
3567              if ((prop_chartype == prop_value) == prop_fail_result)              if ((prop_chartype == prop_value) == prop_fail_result)
3568                RRETURN(MATCH_NOMATCH);                MRRETURN(MATCH_NOMATCH);
3569              }              }
3570            break;            break;
3571    
3572            case PT_SC:            case PT_SC:
3573            for (i = 1; i <= min; i++)            for (i = 1; i <= min; i++)
3574              {              {
3575              if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);              if (eptr >= md->end_subject)
3576              GETCHARINC(c, eptr);                {
3577              prop_category = _pcre_ucp_findprop(c, &prop_chartype, &prop_script);                SCHECK_PARTIAL();
3578                  MRRETURN(MATCH_NOMATCH);
3579                  }
3580                GETCHARINCTEST(c, eptr);
3581                prop_script = UCD_SCRIPT(c);
3582              if ((prop_script == prop_value) == prop_fail_result)              if ((prop_script == prop_value) == prop_fail_result)
3583                RRETURN(MATCH_NOMATCH);                MRRETURN(MATCH_NOMATCH);
3584                }
3585              break;
3586    
3587              case PT_ALNUM:
3588              for (i = 1; i <= min; i++)
3589                {
3590                if (eptr >= md->end_subject)
3591                  {
3592                  SCHECK_PARTIAL();
3593                  MRRETURN(MATCH_NOMATCH);
3594                  }
3595                GETCHARINCTEST(c, eptr);
3596                prop_category = UCD_CATEGORY(c);
3597                if ((prop_category == ucp_L || prop_category == ucp_N)
3598                       == prop_fail_result)
3599                  MRRETURN(MATCH_NOMATCH);
3600                }
3601              break;
3602    
3603              case PT_SPACE:    /* Perl space */
3604              for (i = 1; i <= min; i++)
3605                {
3606                if (eptr >= md->end_subject)
3607                  {
3608                  SCHECK_PARTIAL();
3609                  MRRETURN(MATCH_NOMATCH);
3610                  }
3611                GETCHARINCTEST(c, eptr);
3612                prop_category = UCD_CATEGORY(c);
3613                if ((prop_category == ucp_Z || c == CHAR_HT || c == CHAR_NL ||
3614                     c == CHAR_FF || c == CHAR_CR)
3615                       == prop_fail_result)
3616                  MRRETURN(MATCH_NOMATCH);
3617                }
3618              break;
3619    
3620              case PT_PXSPACE:  /* POSIX space */
3621              for (i = 1; i <= min; i++)
3622                {
3623                if (eptr >= md->end_subject)
3624                  {
3625                  SCHECK_PARTIAL();
3626                  MRRETURN(MATCH_NOMATCH);
3627                  }
3628                GETCHARINCTEST(c, eptr);
3629                prop_category = UCD_CATEGORY(c);
3630                if ((prop_category == ucp_Z || c == CHAR_HT || c == CHAR_NL ||
3631                     c == CHAR_VT || c == CHAR_FF || c == CHAR_CR)
3632                       == prop_fail_result)
3633                  MRRETURN(MATCH_NOMATCH);
3634                }
3635              break;
3636    
3637              case PT_WORD:
3638              for (i = 1; i <= min; i++)
3639                {
3640                if (eptr >= md->end_subject)
3641                  {
3642                  SCHECK_PARTIAL();
3643                  MRRETURN(MATCH_NOMATCH);
3644                  }
3645                GETCHARINCTEST(c, eptr);
3646                prop_category = UCD_CATEGORY(c);
3647                if ((prop_category == ucp_L || prop_category == ucp_N ||
3648                     c == CHAR_UNDERSCORE)
3649                       == prop_fail_result)
3650                  MRRETURN(MATCH_NOMATCH);
3651              }              }
3652            break;            break;
3653    
3654              /* This should not occur */
3655    
3656            default:            default:
3657            RRETURN(PCRE_ERROR_INTERNAL);            RRETURN(PCRE_ERROR_INTERNAL);
3658            }            }
# Line 2717  for (;;) Line 3665  for (;;)
3665          {          {
3666          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3667            {            {
3668              if (eptr >= md->end_subject)
3669                {
3670                SCHECK_PARTIAL();
3671                MRRETURN(MATCH_NOMATCH);
3672                }
3673            GETCHARINCTEST(c, eptr);            GETCHARINCTEST(c, eptr);
3674            prop_category = _pcre_ucp_findprop(c, &prop_chartype, &prop_script);            prop_category = UCD_CATEGORY(c);
3675            if (prop_category == ucp_M) RRETURN(MATCH_NOMATCH);            if (prop_category == ucp_M) MRRETURN(MATCH_NOMATCH);
3676            while (eptr < md->end_subject)            while (eptr < md->end_subject)
3677              {              {
3678              int len = 1;              int len = 1;
3679              if (!utf8) c = *eptr; else              if (!utf8) c = *eptr;
3680                {                else { GETCHARLEN(c, eptr, len); }
3681                GETCHARLEN(c, eptr, len);              prop_category = UCD_CATEGORY(c);
               }  
             prop_category = _pcre_ucp_findprop(c, &prop_chartype, &prop_script);  
3682              if (prop_category != ucp_M) break;              if (prop_category != ucp_M) break;
3683              eptr += len;              eptr += len;
3684              }              }
# Line 2745  for (;;) Line 3696  for (;;)
3696          case OP_ANY:          case OP_ANY:
3697          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3698            {            {
3699            if (eptr >= md->end_subject ||            if (eptr >= md->end_subject)
3700                 ((ims & PCRE_DOTALL) == 0 && IS_NEWLINE(eptr)))              {
3701              RRETURN(MATCH_NOMATCH);              SCHECK_PARTIAL();
3702                MRRETURN(MATCH_NOMATCH);
3703                }
3704              if (IS_NEWLINE(eptr)) MRRETURN(MATCH_NOMATCH);
3705              eptr++;
3706              while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;
3707              }
3708            break;
3709    
3710            case OP_ALLANY:
3711            for (i = 1; i <= min; i++)
3712              {
3713              if (eptr >= md->end_subject)
3714                {
3715                SCHECK_PARTIAL();
3716                MRRETURN(MATCH_NOMATCH);
3717                }
3718            eptr++;            eptr++;
3719            while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;            while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;
3720            }            }
3721          break;          break;
3722    
3723          case OP_ANYBYTE:          case OP_ANYBYTE:
3724            if (eptr > md->end_subject - min) MRRETURN(MATCH_NOMATCH);
3725          eptr += min;          eptr += min;
3726          break;          break;
3727    
3728          case OP_ANYNL:          case OP_ANYNL:
3729          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3730            {            {
3731            if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);            if (eptr >= md->end_subject)
3732                {
3733                SCHECK_PARTIAL();
3734                MRRETURN(MATCH_NOMATCH);
3735                }
3736            GETCHARINC(c, eptr);            GETCHARINC(c, eptr);
3737            switch(c)            switch(c)
3738              {              {
3739              default: RRETURN(MATCH_NOMATCH);              default: MRRETURN(MATCH_NOMATCH);
3740              case 0x000d:              case 0x000d:
3741              if (eptr < md->end_subject && *eptr == 0x0a) eptr++;              if (eptr < md->end_subject && *eptr == 0x0a) eptr++;
3742              break;              break;
3743    
3744              case 0x000a:              case 0x000a:
3745                break;
3746    
3747              case 0x000b:              case 0x000b:
3748              case 0x000c:              case 0x000c:
3749              case 0x0085:              case 0x0085:
3750              case 0x2028:              case 0x2028:
3751              case 0x2029:              case 0x2029:
3752                if (md->bsr_anycrlf) MRRETURN(MATCH_NOMATCH);
3753              break;              break;
3754              }              }
3755            }            }
3756          break;          break;
3757    
3758          case OP_NOT_DIGIT:          case OP_NOT_HSPACE:
3759          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3760            {            {
3761            if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);            if (eptr >= md->end_subject)
3762                {
3763                SCHECK_PARTIAL();
3764                MRRETURN(MATCH_NOMATCH);
3765                }
3766              GETCHARINC(c, eptr);
3767              switch(c)
3768                {
3769                default: break;
3770                case 0x09:      /* HT */
3771                case 0x20:      /* SPACE */
3772                case 0xa0:      /* NBSP */
3773                case 0x1680:    /* OGHAM SPACE MARK */
3774                case 0x180e:    /* MONGOLIAN VOWEL SEPARATOR */
3775                case 0x2000:    /* EN QUAD */
3776                case 0x2001:    /* EM QUAD */
3777                case 0x2002:    /* EN SPACE */
3778                case 0x2003:    /* EM SPACE */
3779                case 0x2004:    /* THREE-PER-EM SPACE */
3780                case 0x2005:    /* FOUR-PER-EM SPACE */
3781                case 0x2006:    /* SIX-PER-EM SPACE */
3782                case 0x2007:    /* FIGURE SPACE */
3783                case 0x2008:    /* PUNCTUATION SPACE */
3784                case 0x2009:    /* THIN SPACE */
3785                case 0x200A:    /* HAIR SPACE */
3786                case 0x202f:    /* NARROW NO-BREAK SPACE */
3787                case 0x205f:    /* MEDIUM MATHEMATICAL SPACE */
3788                case 0x3000:    /* IDEOGRAPHIC SPACE */
3789                MRRETURN(MATCH_NOMATCH);
3790                }
3791              }
3792            break;
3793    
3794            case OP_HSPACE:
3795            for (i = 1; i <= min; i++)
3796              {
3797              if (eptr >= md->end_subject)
3798                {
3799                SCHECK_PARTIAL();
3800                MRRETURN(MATCH_NOMATCH);
3801                }
3802              GETCHARINC(c, eptr);
3803              switch(c)
3804                {
3805                default: MRRETURN(MATCH_NOMATCH);
3806                case 0x09:      /* HT */
3807                case 0x20:      /* SPACE */
3808                case 0xa0:      /* NBSP */
3809                case 0x1680:    /* OGHAM SPACE MARK */
3810                case 0x180e:    /* MONGOLIAN VOWEL SEPARATOR */
3811                case 0x2000:    /* EN QUAD */
3812                case 0x2001:    /* EM QUAD */
3813                case 0x2002:    /* EN SPACE */
3814                case 0x2003:    /* EM SPACE */
3815                case 0x2004:    /* THREE-PER-EM SPACE */
3816                case 0x2005:    /* FOUR-PER-EM SPACE */
3817                case 0x2006:    /* SIX-PER-EM SPACE */
3818                case 0x2007:    /* FIGURE SPACE */
3819                case 0x2008:    /* PUNCTUATION SPACE */
3820                case 0x2009:    /* THIN SPACE */
3821                case 0x200A:    /* HAIR SPACE */
3822                case 0x202f:    /* NARROW NO-BREAK SPACE */
3823                case 0x205f:    /* MEDIUM MATHEMATICAL SPACE */
3824                case 0x3000:    /* IDEOGRAPHIC SPACE */
3825                break;
3826                }
3827              }
3828            break;
3829    
3830            case OP_NOT_VSPACE:
3831            for (i = 1; i <= min; i++)
3832              {
3833              if (eptr >= md->end_subject)
3834                {
3835                SCHECK_PARTIAL();
3836                MRRETURN(MATCH_NOMATCH);
3837                }
3838              GETCHARINC(c, eptr);
3839              switch(c)
3840                {
3841                default: break;
3842                case 0x0a:      /* LF */
3843                case 0x0b:      /* VT */
3844                case 0x0c:      /* FF */
3845                case 0x0d:      /* CR */
3846                case 0x85:      /* NEL */
3847                case 0x2028:    /* LINE SEPARATOR */
3848                case 0x2029:    /* PARAGRAPH SEPARATOR */
3849                MRRETURN(MATCH_NOMATCH);
3850                }
3851              }
3852            break;
3853    
3854            case OP_VSPACE:
3855            for (i = 1; i <= min; i++)
3856              {
3857              if (eptr >= md->end_subject)
3858                {
3859                SCHECK_PARTIAL();
3860                MRRETURN(MATCH_NOMATCH);
3861                }
3862              GETCHARINC(c, eptr);
3863              switch(c)
3864                {
3865                default: MRRETURN(MATCH_NOMATCH);
3866                case 0x0a:      /* LF */
3867                case 0x0b:      /* VT */
3868                case 0x0c:      /* FF */
3869                case 0x0d:      /* CR */
3870                case 0x85:      /* NEL */
3871                case 0x2028:    /* LINE SEPARATOR */
3872                case 0x2029:    /* PARAGRAPH SEPARATOR */
3873                break;
3874                }
3875              }
3876            break;
3877    
3878            case OP_NOT_DIGIT:
3879            for (i = 1; i <= min; i++)
3880              {
3881              if (eptr >= md->end_subject)
3882                {
3883                SCHECK_PARTIAL();
3884                MRRETURN(MATCH_NOMATCH);
3885                }
3886            GETCHARINC(c, eptr);            GETCHARINC(c, eptr);
3887            if (c < 128 && (md->ctypes[c] & ctype_digit) != 0)            if (c < 128 && (md->ctypes[c] & ctype_digit) != 0)
3888              RRETURN(MATCH_NOMATCH);              MRRETURN(MATCH_NOMATCH);
3889            }            }
3890          break;          break;
3891    
3892          case OP_DIGIT:          case OP_DIGIT:
3893          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3894            {            {
3895            if (eptr >= md->end_subject ||            if (eptr >= md->end_subject)
3896               *eptr >= 128 || (md->ctypes[*eptr++] & ctype_digit) == 0)              {
3897              RRETURN(MATCH_NOMATCH);              SCHECK_PARTIAL();
3898                MRRETURN(MATCH_NOMATCH);
3899                }
3900              if (*eptr >= 128 || (md->ctypes[*eptr++] & ctype_digit) == 0)
3901                MRRETURN(MATCH_NOMATCH);
3902            /* 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 */
3903            }            }
3904          break;          break;
# Line 2802  for (;;) Line 3906  for (;;)
3906          case OP_NOT_WHITESPACE:          case OP_NOT_WHITESPACE:
3907          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3908            {            {
3909            if (eptr >= md->end_subject ||            if (eptr >= md->end_subject)
3910               (*eptr < 128 && (md->ctypes[*eptr++] & ctype_space) != 0))              {
3911              RRETURN(MATCH_NOMATCH);              SCHECK_PARTIAL();
3912            while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;              MRRETURN(MATCH_NOMATCH);
3913                }
3914              if (*eptr < 128 && (md->ctypes[*eptr] & ctype_space) != 0)
3915                MRRETURN(MATCH_NOMATCH);
3916              while (++eptr < md->end_subject && (*eptr & 0xc0) == 0x80);
3917            }            }
3918          break;          break;
3919    
3920          case OP_WHITESPACE:          case OP_WHITESPACE:
3921          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3922            {            {
3923            if (eptr >= md->end_subject ||            if (eptr >= md->end_subject)
3924               *eptr >= 128 || (md->ctypes[*eptr++] & ctype_space) == 0)              {
3925              RRETURN(MATCH_NOMATCH);              SCHECK_PARTIAL();
3926                MRRETURN(MATCH_NOMATCH);
3927                }
3928              if (*eptr >= 128 || (md->ctypes[*eptr++] & ctype_space) == 0)
3929                MRRETURN(MATCH_NOMATCH);
3930            /* 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 */
3931            }            }
3932          break;          break;
# Line 2822  for (;;) Line 3934  for (;;)
3934          case OP_NOT_WORDCHAR:          case OP_NOT_WORDCHAR:
3935          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3936            {            {
3937            if (eptr >= md->end_subject ||            if (eptr >= md->end_subject)
3938               (*eptr < 128 && (md->ctypes[*eptr++] & ctype_word) != 0))              {
3939              RRETURN(MATCH_NOMATCH);              SCHECK_PARTIAL();
3940            while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;              MRRETURN(MATCH_NOMATCH);
3941                }
3942              if (*eptr < 128 && (md->ctypes[*eptr] & ctype_word) != 0)
3943                MRRETURN(MATCH_NOMATCH);
3944              while (++eptr < md->end_subject && (*eptr & 0xc0) == 0x80);
3945            }            }
3946          break;          break;
3947    
3948          case OP_WORDCHAR:          case OP_WORDCHAR:
3949          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3950            {            {
3951            if (eptr >= md->end_subject ||            if (eptr >= md->end_subject)
3952               *eptr >= 128 || (md->ctypes[*eptr++] & ctype_word) == 0)              {
3953              RRETURN(MATCH_NOMATCH);              SCHECK_PARTIAL();
3954                MRRETURN(MATCH_NOMATCH);
3955                }
3956              if (*eptr >= 128 || (md->ctypes[*eptr++] & ctype_word) == 0)
3957                MRRETURN(MATCH_NOMATCH);
3958            /* 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 */
3959            }            }
3960          break;          break;
# Line 2847  for (;;) Line 3967  for (;;)
3967  #endif     /* SUPPORT_UTF8 */  #endif     /* SUPPORT_UTF8 */
3968    
3969        /* 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
3970        than OP_PROP and OP_NOTPROP. We can assume that there are the minimum        than OP_PROP and OP_NOTPROP. */
       number of bytes present, as this was tested above. */  
3971    
3972        switch(ctype)        switch(ctype)
3973          {          {
3974          case OP_ANY:          case OP_ANY:
3975          if ((ims & PCRE_DOTALL) == 0)          for (i = 1; i <= min; i++)
3976            {            {
3977            for (i = 1; i <= min; i++)            if (eptr >= md->end_subject)
3978              {              {
3979              if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH);              SCHECK_PARTIAL();
3980              eptr++;              MRRETURN(MATCH_NOMATCH);
3981              }              }
3982              if (IS_NEWLINE(eptr)) MRRETURN(MATCH_NOMATCH);
3983              eptr++;
3984            }            }
         else eptr += min;  
3985          break;          break;
3986    
3987          case OP_ANYBYTE:          case OP_ALLANY:
3988            if (eptr > md->end_subject - min)
3989              {
3990              SCHECK_PARTIAL();
3991              MRRETURN(MATCH_NOMATCH);
3992              }
3993          eptr += min;          eptr += min;
3994          break;          break;
3995    
3996          /* Because of the CRLF case, we can't assume the minimum number of          case OP_ANYBYTE:
3997          bytes are present in this case. */          if (eptr > md->end_subject - min)
3998              {
3999              SCHECK_PARTIAL();
4000              MRRETURN(MATCH_NOMATCH);
4001              }
4002            eptr += min;
4003            break;
4004    
4005          case OP_ANYNL:          case OP_ANYNL:
4006          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
4007            {            {
4008            if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);            if (eptr >= md->end_subject)
4009                {
4010                SCHECK_PARTIAL();
4011                MRRETURN(MATCH_NOMATCH);
4012                }
4013            switch(*eptr++)            switch(*eptr++)
4014              {              {
4015              default: RRETURN(MATCH_NOMATCH);              default: MRRETURN(MATCH_NOMATCH);
4016              case 0x000d:              case 0x000d:
4017              if (eptr < md->end_subject && *eptr == 0x0a) eptr++;              if (eptr < md->end_subject && *eptr == 0x0a) eptr++;
4018              break;              break;
4019              case 0x000a:              case 0x000a:
4020                break;
4021    
4022              case 0x000b:              case 0x000b:
4023              case 0x000c:              case 0x000c:
4024              case 0x0085:              case 0x0085:
4025                if (md->bsr_anycrlf) MRRETURN(MATCH_NOMATCH);
4026                break;
4027                }
4028              }
4029            break;
4030    
4031            case OP_NOT_HSPACE:
4032            for (i = 1; i <= min; i++)
4033              {
4034              if (eptr >= md->end_subject)
4035                {
4036                SCHECK_PARTIAL();
4037                MRRETURN(MATCH_NOMATCH);
4038                }
4039              switch(*eptr++)
4040                {
4041                default: break;
4042                case 0x09:      /* HT */
4043                case 0x20:      /* SPACE */
4044                case 0xa0:      /* NBSP */
4045                MRRETURN(MATCH_NOMATCH);
4046                }
4047              }
4048            break;
4049    
4050            case OP_HSPACE:
4051            for (i = 1; i <= min; i++)
4052              {
4053              if (eptr >= md->end_subject)
4054                {
4055                SCHECK_PARTIAL();
4056                MRRETURN(MATCH_NOMATCH);
4057                }
4058              switch(*eptr++)
4059                {
4060                default: MRRETURN(MATCH_NOMATCH);
4061                case 0x09:      /* HT */
4062                case 0x20:      /* SPACE */
4063                case 0xa0:      /* NBSP */
4064                break;
4065                }
4066              }
4067            break;
4068    
4069            case OP_NOT_VSPACE:
4070            for (i = 1; i <= min; i++)
4071              {
4072              if (eptr >= md->end_subject)
4073                {
4074                SCHECK_PARTIAL();
4075                MRRETURN(MATCH_NOMATCH);
4076                }
4077              switch(*eptr++)
4078                {
4079                default: break;
4080                case 0x0a:      /* LF */
4081                case 0x0b:      /* VT */
4082                case 0x0c:      /* FF */
4083                case 0x0d:      /* CR */
4084                case 0x85:      /* NEL */
4085                MRRETURN(MATCH_NOMATCH);
4086                }
4087              }
4088            break;
4089    
4090            case OP_VSPACE:
4091            for (i = 1; i <= min; i++)
4092              {
4093              if (eptr >= md->end_subject)
4094                {
4095                SCHECK_PARTIAL();
4096                MRRETURN(MATCH_NOMATCH);
4097                }
4098              switch(*eptr++)
4099                {
4100                default: MRRETURN(MATCH_NOMATCH);
4101                case 0x0a:      /* LF */
4102                case 0x0b:      /* VT */
4103                case 0x0c:      /* FF */
4104                case 0x0d:      /* CR */
4105                case 0x85:      /* NEL */
4106              break;              break;
4107              }              }
4108            }            }
# Line 2892  for (;;) Line 4110  for (;;)
4110    
4111          case OP_NOT_DIGIT:          case OP_NOT_DIGIT:
4112          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
4113            if ((md->ctypes[*eptr++] & ctype_digit) != 0) RRETURN(MATCH_NOMATCH);            {
4114              if (eptr >= md->end_subject)
4115                {
4116                SCHECK_PARTIAL();
4117                MRRETURN(MATCH_NOMATCH);
4118                }
4119              if ((md->ctypes[*eptr++] & ctype_digit) != 0) MRRETURN(MATCH_NOMATCH);
4120              }
4121          break;          break;
4122    
4123          case OP_DIGIT:          case OP_DIGIT:
4124          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
4125            if ((md->ctypes[*eptr++] & ctype_digit) == 0) RRETURN(MATCH_NOMATCH);            {
4126              if (eptr >= md->end_subject)
4127                {
4128                SCHECK_PARTIAL();
4129                MRRETURN(MATCH_NOMATCH);
4130                }
4131              if ((md->ctypes[*eptr++] & ctype_digit) == 0) MRRETURN(MATCH_NOMATCH);
4132              }
4133          break;          break;
4134    
4135          case OP_NOT_WHITESPACE:          case OP_NOT_WHITESPACE:
4136          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
4137            if ((md->ctypes[*eptr++] & ctype_space) != 0) RRETURN(MATCH_NOMATCH);            {
4138              if (eptr >= md->end_subject)
4139                {
4140                SCHECK_PARTIAL();
4141                MRRETURN(MATCH_NOMATCH);
4142                }
4143              if ((md->ctypes[*eptr++] & ctype_space) != 0) MRRETURN(MATCH_NOMATCH);
4144              }
4145          break;          break;
4146    
4147          case OP_WHITESPACE:          case OP_WHITESPACE:
4148          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
4149            if ((md->ctypes[*eptr++] & ctype_space) == 0) RRETURN(MATCH_NOMATCH);            {
4150              if (eptr >= md->end_subject)
4151                {
4152                SCHECK_PARTIAL();
4153                MRRETURN(MATCH_NOMATCH);
4154                }
4155              if ((md->ctypes[*eptr++] & ctype_space) == 0) MRRETURN(MATCH_NOMATCH);
4156              }
4157          break;          break;
4158    
4159          case OP_NOT_WORDCHAR:          case OP_NOT_WORDCHAR:
4160          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
4161              {
4162              if (eptr >= md->end_subject)
4163                {
4164                SCHECK_PARTIAL();
4165                MRRETURN(MATCH_NOMATCH);
4166                }
4167            if ((md->ctypes[*eptr++] & ctype_word) != 0)            if ((md->ctypes[*eptr++] & ctype_word) != 0)
4168              RRETURN(MATCH_NOMATCH);              MRRETURN(MATCH_NOMATCH);
4169              }
4170          break;          break;
4171    
4172          case OP_WORDCHAR:          case OP_WORDCHAR:
4173          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
4174              {
4175              if (eptr >= md->end_subject)
4176