/[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 130 by ph10, Mon Mar 26 15:09:47 2007 UTC revision 597 by ph10, Mon May 2 17:08:52 2011 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 */
52    
53  #include "pcre_internal.h"  #include "pcre_internal.h"
54    
55  /* The chain of eptrblocks for tail recursions uses memory in stack workspace,  /* Undefine some potentially clashing cpp symbols */
 obtained at top level, the size of which is defined by EPTR_WORK_SIZE. */  
56    
57  #define EPTR_WORK_SIZE (1000)  #undef min
58    #undef max
59    
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 65  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 78  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 111  while (length-- > 0) Line 132  while (length-- > 0)
132  *          Match a back-reference                *  *          Match a back-reference                *
133  *************************************************/  *************************************************/
134    
135  /* If a back reference hasn't been set, the length that is passed is greater  /* Normally, if a back reference hasn't been set, the length that is passed is
136  than the number of characters left in the string, so the match fails.  negative, so the match always fails. However, in JavaScript compatibility mode,
137    the length passed is zero. Note that in caseless UTF-8 mode, the number of
138    subject bytes matched may be different to the number of reference bytes.
139    
140  Arguments:  Arguments:
141    offset      index into the offset vector    offset      index into the offset vector
142    eptr        points into the subject    eptr        pointer into the subject
143    length      length to be matched    length      length of reference to be matched (number of bytes)
144    md          points to match data block    md          points to match data block
145    ims         the ims flags    ims         the ims flags
146    
147  Returns:      TRUE if matched  Returns:      < 0 if not matched, otherwise the number of subject bytes matched
148  */  */
149    
150  static BOOL  static int
151  match_ref(int offset, register USPTR eptr, int length, match_data *md,  match_ref(int offset, register USPTR eptr, int length, match_data *md,
152    unsigned long int ims)    unsigned long int ims)
153  {  {
154  USPTR p = md->start_subject + md->offset_vector[offset];  USPTR eptr_start = eptr;
155    register USPTR p = md->start_subject + md->offset_vector[offset];
156    
157  #ifdef DEBUG  #ifdef PCRE_DEBUG
158  if (eptr >= md->end_subject)  if (eptr >= md->end_subject)
159    printf("matching subject <null>");    printf("matching subject <null>");
160  else  else
# Line 143  pchars(p, length, FALSE, md); Line 167  pchars(p, length, FALSE, md);
167  printf("\n");  printf("\n");
168  #endif  #endif
169    
170  /* Always fail if not enough characters left */  /* Always fail if reference not set (and not JavaScript compatible). */
171    
172  if (length > md->end_subject - eptr) return FALSE;  if (length < 0) return -1;
173    
174  /* Separate the caselesss case for speed */  /* Separate the caseless case for speed. In UTF-8 mode we can only do this
175    properly if Unicode properties are supported. Otherwise, we can check only
176    ASCII characters. */
177    
178  if ((ims & PCRE_CASELESS) != 0)  if ((ims & PCRE_CASELESS) != 0)
179    {    {
180    while (length-- > 0)  #ifdef SUPPORT_UTF8
181      if (md->lcc[*p++] != md->lcc[*eptr++]) return FALSE;  #ifdef SUPPORT_UCP
182      if (md->utf8)
183        {
184        /* Match characters up to the end of the reference. NOTE: the number of
185        bytes matched may differ, because there are some characters whose upper and
186        lower case versions code as different numbers of bytes. For example, U+023A
187        (2 bytes in UTF-8) is the upper case version of U+2C65 (3 bytes in UTF-8);
188        a sequence of 3 of the former uses 6 bytes, as does a sequence of two of
189        the latter. It is important, therefore, to check the length along the
190        reference, not along the subject (earlier code did this wrong). */
191    
192        USPTR endptr = p + length;
193        while (p < endptr)
194          {
195          int c, d;
196          if (eptr >= md->end_subject) return -1;
197          GETCHARINC(c, eptr);
198          GETCHARINC(d, p);
199          if (c != d && c != UCD_OTHERCASE(d)) return -1;
200          }
201        }
202      else
203    #endif
204    #endif
205    
206      /* The same code works when not in UTF-8 mode and in UTF-8 mode when there
207      is no UCP support. */
208        {
209        if (eptr + length > md->end_subject) return -1;
210        while (length-- > 0)
211          { if (md->lcc[*p++] != md->lcc[*eptr++]) return -1; }
212        }
213    }    }
214    
215    /* In the caseful case, we can just compare the bytes, whether or not we
216    are in UTF-8 mode. */
217    
218  else  else
219    { while (length-- > 0) if (*p++ != *eptr++) return FALSE; }    {
220      if (eptr + length > md->end_subject) return -1;
221      while (length-- > 0) if (*p++ != *eptr++) return -1;
222      }
223    
224  return TRUE;  return eptr - eptr_start;
225  }  }
226    
227    
# Line 183  calls by keeping local variables that ne Line 247  calls by keeping local variables that ne
247  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
248  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
249  always used to.  always used to.
250    
251    The original heap-recursive code used longjmp(). However, it seems that this
252    can be very slow on some operating systems. Following a suggestion from Stan
253    Switzer, the use of longjmp() has been abolished, at the cost of having to
254    provide a unique number for each call to RMATCH. There is no way of generating
255    a sequence of numbers at compile time in C. I have given them names, to make
256    them stand out more clearly.
257    
258    Crude tests on x86 Linux show a small speedup of around 5-8%. However, on
259    FreeBSD, avoiding longjmp() more than halves the time taken to run the standard
260    tests. Furthermore, not using longjmp() means that local dynamic variables
261    don't have indeterminate values; this has meant that the frame size can be
262    reduced because the result can be "passed back" by straight setting of the
263    variable instead of being passed in the frame.
264  ****************************************************************************  ****************************************************************************
265  ***************************************************************************/  ***************************************************************************/
266    
267    /* Numbers for RMATCH calls. When this list is changed, the code at HEAP_RETURN
268    below must be updated in sync.  */
269    
270    enum { RM1=1, RM2,  RM3,  RM4,  RM5,  RM6,  RM7,  RM8,  RM9,  RM10,
271           RM11,  RM12, RM13, RM14, RM15, RM16, RM17, RM18, RM19, RM20,
272           RM21,  RM22, RM23, RM24, RM25, RM26, RM27, RM28, RM29, RM30,
273           RM31,  RM32, RM33, RM34, RM35, RM36, RM37, RM38, RM39, RM40,
274           RM41,  RM42, RM43, RM44, RM45, RM46, RM47, RM48, RM49, RM50,
275           RM51,  RM52, RM53, RM54, RM55, RM56, RM57, RM58, RM59, RM60,
276           RM61,  RM62 };
277    
278  /* 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
279  versions and production versions. */  versions and production versions. Note that the "rw" argument of RMATCH isn't
280    actually used in this definition. */
281    
282  #ifndef NO_RECURSE  #ifndef NO_RECURSE
283  #define REGISTER register  #define REGISTER register
284  #ifdef DEBUG  
285  #define RMATCH(rx,ra,rb,rc,rd,re,rf,rg) \  #ifdef PCRE_DEBUG
286    #define RMATCH(ra,rb,rc,rd,re,rf,rg,rw) \
287    { \    { \
288    printf("match() called in line %d\n", __LINE__); \    printf("match() called in line %d\n", __LINE__); \
289    rx = match(ra,rb,rc,rd,re,rf,rg,rdepth+1); \    rrc = match(ra,rb,mstart,markptr,rc,rd,re,rf,rg,rdepth+1); \
290    printf("to line %d\n", __LINE__); \    printf("to line %d\n", __LINE__); \
291    }    }
292  #define RRETURN(ra) \  #define RRETURN(ra) \
# Line 205  versions and production versions. */ Line 295  versions and production versions. */
295    return ra; \    return ra; \
296    }    }
297  #else  #else
298  #define RMATCH(rx,ra,rb,rc,rd,re,rf,rg) \  #define RMATCH(ra,rb,rc,rd,re,rf,rg,rw) \
299    rx = match(ra,rb,rc,rd,re,rf,rg,rdepth+1)    rrc = match(ra,rb,mstart,markptr,rc,rd,re,rf,rg,rdepth+1)
300  #define RRETURN(ra) return ra  #define RRETURN(ra) return ra
301  #endif  #endif
302    
303  #else  #else
304    
305    
306  /* 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
307  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
308  match(), which never changes. */  argument of match(), which never changes. */
309    
310  #define REGISTER  #define REGISTER
311    
312  #define RMATCH(rx,ra,rb,rc,rd,re,rf,rg)\  #define RMATCH(ra,rb,rc,rd,re,rf,rg,rw)\
313    {\    {\
314    heapframe *newframe = (pcre_stack_malloc)(sizeof(heapframe));\    heapframe *newframe = (heapframe *)(pcre_stack_malloc)(sizeof(heapframe));\
315    if (setjmp(frame->Xwhere) == 0)\    if (newframe == NULL) RRETURN(PCRE_ERROR_NOMEMORY);\
316      {\    frame->Xwhere = rw; \
317      newframe->Xeptr = ra;\    newframe->Xeptr = ra;\
318      newframe->Xecode = rb;\    newframe->Xecode = rb;\
319      newframe->Xoffset_top = rc;\    newframe->Xmstart = mstart;\
320      newframe->Xims = re;\    newframe->Xmarkptr = markptr;\
321      newframe->Xeptrb = rf;\    newframe->Xoffset_top = rc;\
322      newframe->Xflags = rg;\    newframe->Xims = re;\
323      newframe->Xrdepth = frame->Xrdepth + 1;\    newframe->Xeptrb = rf;\
324      newframe->Xprevframe = frame;\    newframe->Xflags = rg;\
325      frame = newframe;\    newframe->Xrdepth = frame->Xrdepth + 1;\
326      DPRINTF(("restarting from line %d\n", __LINE__));\    newframe->Xprevframe = frame;\
327      goto HEAP_RECURSE;\    frame = newframe;\
328      }\    DPRINTF(("restarting from line %d\n", __LINE__));\
329    else\    goto HEAP_RECURSE;\
330      {\    L_##rw:\
331      DPRINTF(("longjumped back to line %d\n", __LINE__));\    DPRINTF(("jumped back to line %d\n", __LINE__));\
     frame = md->thisframe;\  
     rx = frame->Xresult;\  
     }\  
332    }    }
333    
334  #define RRETURN(ra)\  #define RRETURN(ra)\
335    {\    {\
336    heapframe *newframe = frame;\    heapframe *oldframe = frame;\
337    frame = newframe->Xprevframe;\    frame = oldframe->Xprevframe;\
338    (pcre_stack_free)(newframe);\    (pcre_stack_free)(oldframe);\
339    if (frame != NULL)\    if (frame != NULL)\
340      {\      {\
341      frame->Xresult = ra;\      rrc = ra;\
342      md->thisframe = frame;\      goto HEAP_RETURN;\
     longjmp(frame->Xwhere, 1);\  
343      }\      }\
344    return ra;\    return ra;\
345    }    }
# Line 266  typedef struct heapframe { Line 352  typedef struct heapframe {
352    
353    /* Function arguments that may change */    /* Function arguments that may change */
354    
355    const uschar *Xeptr;    USPTR Xeptr;
356    const uschar *Xecode;    const uschar *Xecode;
357      USPTR Xmstart;
358      USPTR Xmarkptr;
359    int Xoffset_top;    int Xoffset_top;
360    long int Xims;    long int Xims;
361    eptrblock *Xeptrb;    eptrblock *Xeptrb;
# Line 276  typedef struct heapframe { Line 364  typedef struct heapframe {
364    
365    /* Function local variables */    /* Function local variables */
366    
367    const uschar *Xcallpat;    USPTR Xcallpat;
368    const uschar *Xcharptr;  #ifdef SUPPORT_UTF8
369    const uschar *Xdata;    USPTR Xcharptr;
370    const uschar *Xnext;  #endif
371    const uschar *Xpp;    USPTR Xdata;
372    const uschar *Xprev;    USPTR Xnext;
373    const uschar *Xsaved_eptr;    USPTR Xpp;
374      USPTR Xprev;
375      USPTR Xsaved_eptr;
376    
377    recursion_info Xnew_recursive;    recursion_info Xnew_recursive;
378    
# Line 303  typedef struct heapframe { Line 393  typedef struct heapframe {
393    uschar Xocchars[8];    uschar Xocchars[8];
394  #endif  #endif
395    
396      int Xcodelink;
397    int Xctype;    int Xctype;
398    unsigned int Xfc;    unsigned int Xfc;
399    int Xfi;    int Xfi;
# Line 318  typedef struct heapframe { Line 409  typedef struct heapframe {
409    
410    eptrblock Xnewptrb;    eptrblock Xnewptrb;
411    
412    /* Place to pass back result, and where to jump back to */    /* Where to jump back to */
413    
414    int  Xresult;    int Xwhere;
   jmp_buf Xwhere;  
415    
416  } heapframe;  } heapframe;
417    
# Line 339  typedef struct heapframe { Line 429  typedef struct heapframe {
429    
430  /* This function is called recursively in many circumstances. Whenever it  /* This function is called recursively in many circumstances. Whenever it
431  returns a negative (error) response, the outer incarnation must also return the  returns a negative (error) response, the outer incarnation must also return the
432  same response.  same response. */
433    
434    /* These macros pack up tests that are used for partial matching, and which
435    appears several times in the code. We set the "hit end" flag if the pointer is
436    at the end of the subject and also past the start of the subject (i.e.
437    something has been matched). For hard partial matching, we then return
438    immediately. The second one is used when we already know we are past the end of
439    the subject. */
440    
441    #define CHECK_PARTIAL()\
442      if (md->partial != 0 && eptr >= md->end_subject && \
443          eptr > md->start_used_ptr) \
444        { \
445        md->hitend = TRUE; \
446        if (md->partial > 1) MRRETURN(PCRE_ERROR_PARTIAL); \
447        }
448    
449    #define SCHECK_PARTIAL()\
450      if (md->partial != 0 && eptr > md->start_used_ptr) \
451        { \
452        md->hitend = TRUE; \
453        if (md->partial > 1) MRRETURN(PCRE_ERROR_PARTIAL); \
454        }
455    
456    
457  Performance note: It might be tempting to extract commonly used fields from the  /* Performance note: It might be tempting to extract commonly used fields from
458  md structure (e.g. utf8, end_subject) into individual variables to improve  the md structure (e.g. utf8, end_subject) into individual variables to improve
459  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
460  made performance worse.  made performance worse.
461    
462  Arguments:  Arguments:
463     eptr        pointer to current character in subject     eptr        pointer to current character in subject
464     ecode       pointer to current position in compiled code     ecode       pointer to current position in compiled code
465       mstart      pointer to the current match start position (can be modified
466                     by encountering \K)
467       markptr     pointer to the most recent MARK name, or NULL
468     offset_top  current top pointer     offset_top  current top pointer
469     md          pointer to "static" info for the match     md          pointer to "static" info for the match
470     ims         current /i, /m, and /s options     ims         current /i, /m, and /s options
# Line 358  Arguments: Line 474  Arguments:
474                   match_condassert - this is an assertion condition                   match_condassert - this is an assertion condition
475                   match_cbegroup - this is the start of an unlimited repeat                   match_cbegroup - this is the start of an unlimited repeat
476                     group that can match an empty string                     group that can match an empty string
                  match_tail_recursed - this is a tail_recursed group  
477     rdepth      the recursion depth     rdepth      the recursion depth
478    
479  Returns:       MATCH_MATCH if matched            )  these values are >= 0  Returns:       MATCH_MATCH if matched            )  these values are >= 0
480                 MATCH_NOMATCH if failed to match  )                 MATCH_NOMATCH if failed to match  )
481                   a negative MATCH_xxx value for PRUNE, SKIP, etc
482                 a negative PCRE_ERROR_xxx value if aborted by an error condition                 a negative PCRE_ERROR_xxx value if aborted by an error condition
483                   (e.g. stopped by repeated call or recursion limit)                   (e.g. stopped by repeated call or recursion limit)
484  */  */
485    
486  static int  static int
487  match(REGISTER USPTR eptr, REGISTER const uschar *ecode,  match(REGISTER USPTR eptr, REGISTER const uschar *ecode, USPTR mstart,
488    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,
489    int flags, unsigned int rdepth)    eptrblock *eptrb, int flags, unsigned int rdepth)
490  {  {
491  /* 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,
492  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 382  register unsigned int c; /* Character Line 498  register unsigned int c; /* Character
498  register BOOL utf8;        /* Local copy of UTF-8 flag for speed */  register BOOL utf8;        /* Local copy of UTF-8 flag for speed */
499    
500  BOOL minimize, possessive; /* Quantifier options */  BOOL minimize, possessive; /* Quantifier options */
501    int condcode;
502    
503  /* 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
504  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 389  heap storage. Set up the top-level frame Line 506  heap storage. Set up the top-level frame
506  heap whenever RMATCH() does a "recursion". See the macro definitions above. */  heap whenever RMATCH() does a "recursion". See the macro definitions above. */
507    
508  #ifdef NO_RECURSE  #ifdef NO_RECURSE
509  heapframe *frame = (pcre_stack_malloc)(sizeof(heapframe));  heapframe *frame = (heapframe *)(pcre_stack_malloc)(sizeof(heapframe));
510    if (frame == NULL) RRETURN(PCRE_ERROR_NOMEMORY);
511  frame->Xprevframe = NULL;            /* Marks the top level */  frame->Xprevframe = NULL;            /* Marks the top level */
512    
513  /* Copy in the original argument variables */  /* Copy in the original argument variables */
514    
515  frame->Xeptr = eptr;  frame->Xeptr = eptr;
516  frame->Xecode = ecode;  frame->Xecode = ecode;
517    frame->Xmstart = mstart;
518    frame->Xmarkptr = markptr;
519  frame->Xoffset_top = offset_top;  frame->Xoffset_top = offset_top;
520  frame->Xims = ims;  frame->Xims = ims;
521  frame->Xeptrb = eptrb;  frame->Xeptrb = eptrb;
# Line 410  HEAP_RECURSE: Line 530  HEAP_RECURSE:
530    
531  #define eptr               frame->Xeptr  #define eptr               frame->Xeptr
532  #define ecode              frame->Xecode  #define ecode              frame->Xecode
533    #define mstart             frame->Xmstart
534    #define markptr            frame->Xmarkptr
535  #define offset_top         frame->Xoffset_top  #define offset_top         frame->Xoffset_top
536  #define ims                frame->Xims  #define ims                frame->Xims
537  #define eptrb              frame->Xeptrb  #define eptrb              frame->Xeptrb
# Line 422  HEAP_RECURSE: Line 544  HEAP_RECURSE:
544  #define charptr            frame->Xcharptr  #define charptr            frame->Xcharptr
545  #endif  #endif
546  #define callpat            frame->Xcallpat  #define callpat            frame->Xcallpat
547    #define codelink           frame->Xcodelink
548  #define data               frame->Xdata  #define data               frame->Xdata
549  #define next               frame->Xnext  #define next               frame->Xnext
550  #define pp                 frame->Xpp  #define pp                 frame->Xpp
# Line 502  int oclength; Line 625  int oclength;
625  uschar occhars[8];  uschar occhars[8];
626  #endif  #endif
627    
628    int codelink;
629  int ctype;  int ctype;
630  int length;  int length;
631  int max;  int max;
# Line 535  TAIL_RECURSE: Line 659  TAIL_RECURSE:
659  /* 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
660  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
661  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()
662  and a "return", respectively (possibly with some debugging if DEBUG is  and a "return", respectively (possibly with some debugging if PCRE_DEBUG is
663  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
664  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,
665  however, impact performance when true recursion is being used. */  however, impact performance when true recursion is being used. */
666    
667    #ifdef SUPPORT_UTF8
668    utf8 = md->utf8;       /* Local copy of the flag */
669    #else
670    utf8 = FALSE;
671    #endif
672    
673  /* 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
674  haven't exceeded the recursive call limit. */  haven't exceeded the recursive call limit. */
675    
# Line 548  if (rdepth >= md->match_limit_recursion) Line 678  if (rdepth >= md->match_limit_recursion)
678    
679  original_ims = ims;    /* Save for resetting on ')' */  original_ims = ims;    /* Save for resetting on ')' */
680    
 #ifdef SUPPORT_UTF8  
 utf8 = md->utf8;       /* Local copy of the flag */  
 #else  
 utf8 = FALSE;  
 #endif  
   
681  /* 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
682  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
683  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
684  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.
685  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
686  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
687  already used. */  block that is used is on the stack, so a new one may be required for each
688    match(). */
689    
690  if ((flags & match_cbegroup) != 0)  if ((flags & match_cbegroup) != 0)
691    {    {
692    eptrblock *p;    newptrb.epb_saved_eptr = eptr;
693    if ((flags & match_tail_recursed) != 0)    newptrb.epb_prev = eptrb;
694      {    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;  
695    }    }
696    
697  /* Now start processing the opcodes. */  /* Now start processing the opcodes. */
# Line 583  for (;;) Line 701  for (;;)
701    minimize = possessive = FALSE;    minimize = possessive = FALSE;
702    op = *ecode;    op = *ecode;
703    
   /* 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;  
   
704    switch(op)    switch(op)
705      {      {
706        case OP_MARK:
707        markptr = ecode + 2;
708        RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode] + ecode[1], offset_top, md,
709          ims, eptrb, flags, RM55);
710    
711        /* A return of MATCH_SKIP_ARG means that matching failed at SKIP with an
712        argument, and we must check whether that argument matches this MARK's
713        argument. It is passed back in md->start_match_ptr (an overloading of that
714        variable). If it does match, we reset that variable to the current subject
715        position and return MATCH_SKIP. Otherwise, pass back the return code
716        unaltered. */
717    
718        if (rrc == MATCH_SKIP_ARG &&
719            strcmp((char *)markptr, (char *)(md->start_match_ptr)) == 0)
720          {
721          md->start_match_ptr = eptr;
722          RRETURN(MATCH_SKIP);
723          }
724    
725        if (md->mark == NULL) md->mark = markptr;
726        RRETURN(rrc);
727    
728        case OP_FAIL:
729        MRRETURN(MATCH_NOMATCH);
730    
731        /* COMMIT overrides PRUNE, SKIP, and THEN */
732    
733        case OP_COMMIT:
734        RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,
735          ims, eptrb, flags, RM52);
736        if (rrc != MATCH_NOMATCH && rrc != MATCH_PRUNE &&
737            rrc != MATCH_SKIP && rrc != MATCH_SKIP_ARG &&
738            rrc != MATCH_THEN)
739          RRETURN(rrc);
740        MRRETURN(MATCH_COMMIT);
741    
742        /* PRUNE overrides THEN */
743    
744        case OP_PRUNE:
745        RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,
746          ims, eptrb, flags, RM51);
747        if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);
748        MRRETURN(MATCH_PRUNE);
749    
750        case OP_PRUNE_ARG:
751        RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode] + ecode[1], offset_top, md,
752          ims, eptrb, flags, RM56);
753        if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);
754        md->mark = ecode + 2;
755        RRETURN(MATCH_PRUNE);
756    
757        /* SKIP overrides PRUNE and THEN */
758    
759        case OP_SKIP:
760        RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,
761          ims, eptrb, flags, RM53);
762        if (rrc != MATCH_NOMATCH && rrc != MATCH_PRUNE && rrc != MATCH_THEN)
763          RRETURN(rrc);
764        md->start_match_ptr = eptr;   /* Pass back current position */
765        MRRETURN(MATCH_SKIP);
766    
767        case OP_SKIP_ARG:
768        RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode] + ecode[1], offset_top, md,
769          ims, eptrb, flags, RM57);
770        if (rrc != MATCH_NOMATCH && rrc != MATCH_PRUNE && rrc != MATCH_THEN)
771          RRETURN(rrc);
772    
773        /* Pass back the current skip name by overloading md->start_match_ptr and
774        returning the special MATCH_SKIP_ARG return code. This will either be
775        caught by a matching MARK, or get to the top, where it is treated the same
776        as PRUNE. */
777    
778        md->start_match_ptr = ecode + 2;
779        RRETURN(MATCH_SKIP_ARG);
780    
781        /* For THEN (and THEN_ARG) we pass back the address of the bracket or
782        the alt that is at the start of the current branch. This makes it possible
783        to skip back past alternatives that precede the THEN within the current
784        branch. */
785    
786        case OP_THEN:
787        RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,
788          ims, eptrb, flags, RM54);
789        if (rrc != MATCH_NOMATCH) RRETURN(rrc);
790        md->start_match_ptr = ecode - GET(ecode, 1);
791        MRRETURN(MATCH_THEN);
792    
793        case OP_THEN_ARG:
794        RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode] + ecode[1+LINK_SIZE],
795          offset_top, md, ims, eptrb, flags, RM58);
796        if (rrc != MATCH_NOMATCH) RRETURN(rrc);
797        md->start_match_ptr = ecode - GET(ecode, 1);
798        md->mark = ecode + LINK_SIZE + 2;
799        RRETURN(MATCH_THEN);
800    
801      /* 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
802      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.
803      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 612  for (;;) Line 817  for (;;)
817      number = GET2(ecode, 1+LINK_SIZE);      number = GET2(ecode, 1+LINK_SIZE);
818      offset = number << 1;      offset = number << 1;
819    
820  #ifdef DEBUG  #ifdef PCRE_DEBUG
821      printf("start bracket %d\n", number);      printf("start bracket %d\n", number);
822      printf("subject=");      printf("subject=");
823      pchars(eptr, 16, TRUE, md);      pchars(eptr, 16, TRUE, md);
# Line 627  for (;;) Line 832  for (;;)
832        save_capture_last = md->capture_last;        save_capture_last = md->capture_last;
833    
834        DPRINTF(("saving %d %d %d\n", save_offset1, save_offset2, save_offset3));        DPRINTF(("saving %d %d %d\n", save_offset1, save_offset2, save_offset3));
835        md->offset_vector[md->offset_end - number] = eptr - md->start_subject;        md->offset_vector[md->offset_end - number] =
836            (int)(eptr - md->start_subject);
837    
838        flags = (op == OP_SCBRA)? match_cbegroup : 0;        flags = (op == OP_SCBRA)? match_cbegroup : 0;
839        do        do
840          {          {
841          RMATCH(rrc, eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,          RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,
842            ims, eptrb, flags);            ims, eptrb, flags, RM1);
843          if (rrc != MATCH_NOMATCH) RRETURN(rrc);          if (rrc != MATCH_NOMATCH &&
844                (rrc != MATCH_THEN || md->start_match_ptr != ecode))
845              RRETURN(rrc);
846          md->capture_last = save_capture_last;          md->capture_last = save_capture_last;
847          ecode += GET(ecode, 1);          ecode += GET(ecode, 1);
848          }          }
# Line 646  for (;;) Line 854  for (;;)
854        md->offset_vector[offset+1] = save_offset2;        md->offset_vector[offset+1] = save_offset2;
855        md->offset_vector[md->offset_end - number] = save_offset3;        md->offset_vector[md->offset_end - number] = save_offset3;
856    
857          if (rrc != MATCH_THEN) md->mark = markptr;
858        RRETURN(MATCH_NOMATCH);        RRETURN(MATCH_NOMATCH);
859        }        }
860    
861      /* Insufficient room for saving captured contents. Treat as a non-capturing      /* FALL THROUGH ... Insufficient room for saving captured contents. Treat
862      bracket. */      as a non-capturing bracket. */
863    
864        /* VVVVVVVVVVVVVVVVVVVVVVVVV */
865        /* VVVVVVVVVVVVVVVVVVVVVVVVV */
866    
867      DPRINTF(("insufficient capture room: treat as non-capturing\n"));      DPRINTF(("insufficient capture room: treat as non-capturing\n"));
868    
869        /* VVVVVVVVVVVVVVVVVVVVVVVVV */
870        /* VVVVVVVVVVVVVVVVVVVVVVVVV */
871    
872      /* 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
873      final alternative within the brackets, we would return the result of a      final alternative within the brackets, we would return the result of a
874      recursive call to match() whatever happened. We can reduce stack usage by      recursive call to match() whatever happened. We can reduce stack usage by
875      turning this into a tail recursion. */      turning this into a tail recursion, except in the case when match_cbegroup
876        is set.*/
877    
878      case OP_BRA:      case OP_BRA:
879      case OP_SBRA:      case OP_SBRA:
# Line 665  for (;;) Line 881  for (;;)
881      flags = (op >= OP_SBRA)? match_cbegroup : 0;      flags = (op >= OP_SBRA)? match_cbegroup : 0;
882      for (;;)      for (;;)
883        {        {
884        if (ecode[GET(ecode, 1)] != OP_ALT)        if (ecode[GET(ecode, 1)] != OP_ALT)   /* Final alternative */
885          {          {
886          ecode += _pcre_OP_lengths[*ecode];          if (flags == 0)    /* Not a possibly empty group */
887          flags |= match_tail_recursed;            {
888          DPRINTF(("bracket 0 tail recursion\n"));            ecode += _pcre_OP_lengths[*ecode];
889          goto TAIL_RECURSE;            DPRINTF(("bracket 0 tail recursion\n"));
890              goto TAIL_RECURSE;
891              }
892    
893            /* Possibly empty group; can't use tail recursion. */
894    
895            RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md, ims,
896              eptrb, flags, RM48);
897            if (rrc == MATCH_NOMATCH) md->mark = markptr;
898            RRETURN(rrc);
899          }          }
900    
901        /* For non-final alternatives, continue the loop for a NOMATCH result;        /* For non-final alternatives, continue the loop for a NOMATCH result;
902        otherwise return. */        otherwise return. */
903    
904        RMATCH(rrc, eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md, ims,        RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md, ims,
905          eptrb, flags);          eptrb, flags, RM2);
906        if (rrc != MATCH_NOMATCH) RRETURN(rrc);        if (rrc != MATCH_NOMATCH &&
907              (rrc != MATCH_THEN || md->start_match_ptr != ecode))
908            RRETURN(rrc);
909        ecode += GET(ecode, 1);        ecode += GET(ecode, 1);
910        }        }
911      /* Control never reaches here. */      /* Control never reaches here. */
# Line 691  for (;;) Line 918  for (;;)
918    
919      case OP_COND:      case OP_COND:
920      case OP_SCOND:      case OP_SCOND:
921      if (ecode[LINK_SIZE+1] == OP_RREF)         /* Recursion test */      codelink= GET(ecode, 1);
922    
923        /* Because of the way auto-callout works during compile, a callout item is
924        inserted between OP_COND and an assertion condition. */
925    
926        if (ecode[LINK_SIZE+1] == OP_CALLOUT)
927        {        {
928        offset = GET2(ecode, LINK_SIZE + 2);     /* Recursion group number*/        if (pcre_callout != NULL)
929        condition = md->recursive != NULL &&          {
930          (offset == RREF_ANY || offset == md->recursive->group_num);          pcre_callout_block cb;
931        ecode += condition? 3 : GET(ecode, 1);          cb.version          = 1;   /* Version 1 of the callout block */
932            cb.callout_number   = ecode[LINK_SIZE+2];
933            cb.offset_vector    = md->offset_vector;
934            cb.subject          = (PCRE_SPTR)md->start_subject;
935            cb.subject_length   = (int)(md->end_subject - md->start_subject);
936            cb.start_match      = (int)(mstart - md->start_subject);
937            cb.current_position = (int)(eptr - md->start_subject);
938            cb.pattern_position = GET(ecode, LINK_SIZE + 3);
939            cb.next_item_length = GET(ecode, 3 + 2*LINK_SIZE);
940            cb.capture_top      = offset_top/2;
941            cb.capture_last     = md->capture_last;
942            cb.callout_data     = md->callout_data;
943            if ((rrc = (*pcre_callout)(&cb)) > 0) MRRETURN(MATCH_NOMATCH);
944            if (rrc < 0) RRETURN(rrc);
945            }
946          ecode += _pcre_OP_lengths[OP_CALLOUT];
947          }
948    
949        condcode = ecode[LINK_SIZE+1];
950    
951        /* Now see what the actual condition is */
952    
953        if (condcode == OP_RREF || condcode == OP_NRREF)    /* Recursion test */
954          {
955          if (md->recursive == NULL)                /* Not recursing => FALSE */
956            {
957            condition = FALSE;
958            ecode += GET(ecode, 1);
959            }
960          else
961            {
962            int recno = GET2(ecode, LINK_SIZE + 2);   /* Recursion group number*/
963            condition =  (recno == RREF_ANY || recno == md->recursive->group_num);
964    
965            /* If the test is for recursion into a specific subpattern, and it is
966            false, but the test was set up by name, scan the table to see if the
967            name refers to any other numbers, and test them. The condition is true
968            if any one is set. */
969    
970            if (!condition && condcode == OP_NRREF && recno != RREF_ANY)
971              {
972              uschar *slotA = md->name_table;
973              for (i = 0; i < md->name_count; i++)
974                {
975                if (GET2(slotA, 0) == recno) break;
976                slotA += md->name_entry_size;
977                }
978    
979              /* Found a name for the number - there can be only one; duplicate
980              names for different numbers are allowed, but not vice versa. First
981              scan down for duplicates. */
982    
983              if (i < md->name_count)
984                {
985                uschar *slotB = slotA;
986                while (slotB > md->name_table)
987                  {
988                  slotB -= md->name_entry_size;
989                  if (strcmp((char *)slotA + 2, (char *)slotB + 2) == 0)
990                    {
991                    condition = GET2(slotB, 0) == md->recursive->group_num;
992                    if (condition) break;
993                    }
994                  else break;
995                  }
996    
997                /* Scan up for duplicates */
998    
999                if (!condition)
1000                  {
1001                  slotB = slotA;
1002                  for (i++; i < md->name_count; i++)
1003                    {
1004                    slotB += md->name_entry_size;
1005                    if (strcmp((char *)slotA + 2, (char *)slotB + 2) == 0)
1006                      {
1007                      condition = GET2(slotB, 0) == md->recursive->group_num;
1008                      if (condition) break;
1009                      }
1010                    else break;
1011                    }
1012                  }
1013                }
1014              }
1015    
1016            /* Chose branch according to the condition */
1017    
1018            ecode += condition? 3 : GET(ecode, 1);
1019            }
1020        }        }
1021    
1022      else if (ecode[LINK_SIZE+1] == OP_CREF)    /* Group used test */      else if (condcode == OP_CREF || condcode == OP_NCREF)  /* Group used test */
1023        {        {
1024        offset = GET2(ecode, LINK_SIZE+2) << 1;  /* Doubled ref number */        offset = GET2(ecode, LINK_SIZE+2) << 1;  /* Doubled ref number */
1025        condition = offset < offset_top && md->offset_vector[offset] >= 0;        condition = offset < offset_top && md->offset_vector[offset] >= 0;
1026    
1027          /* If the numbered capture is unset, but the reference was by name,
1028          scan the table to see if the name refers to any other numbers, and test
1029          them. The condition is true if any one is set. This is tediously similar
1030          to the code above, but not close enough to try to amalgamate. */
1031    
1032          if (!condition && condcode == OP_NCREF)
1033            {
1034            int refno = offset >> 1;
1035            uschar *slotA = md->name_table;
1036    
1037            for (i = 0; i < md->name_count; i++)
1038              {
1039              if (GET2(slotA, 0) == refno) break;
1040              slotA += md->name_entry_size;
1041              }
1042    
1043            /* Found a name for the number - there can be only one; duplicate names
1044            for different numbers are allowed, but not vice versa. First scan down
1045            for duplicates. */
1046    
1047            if (i < md->name_count)
1048              {
1049              uschar *slotB = slotA;
1050              while (slotB > md->name_table)
1051                {
1052                slotB -= md->name_entry_size;
1053                if (strcmp((char *)slotA + 2, (char *)slotB + 2) == 0)
1054                  {
1055                  offset = GET2(slotB, 0) << 1;
1056                  condition = offset < offset_top &&
1057                    md->offset_vector[offset] >= 0;
1058                  if (condition) break;
1059                  }
1060                else break;
1061                }
1062    
1063              /* Scan up for duplicates */
1064    
1065              if (!condition)
1066                {
1067                slotB = slotA;
1068                for (i++; i < md->name_count; i++)
1069                  {
1070                  slotB += md->name_entry_size;
1071                  if (strcmp((char *)slotA + 2, (char *)slotB + 2) == 0)
1072                    {
1073                    offset = GET2(slotB, 0) << 1;
1074                    condition = offset < offset_top &&
1075                      md->offset_vector[offset] >= 0;
1076                    if (condition) break;
1077                    }
1078                  else break;
1079                  }
1080                }
1081              }
1082            }
1083    
1084          /* Chose branch according to the condition */
1085    
1086        ecode += condition? 3 : GET(ecode, 1);        ecode += condition? 3 : GET(ecode, 1);
1087        }        }
1088    
1089      else if (ecode[LINK_SIZE+1] == OP_DEF)     /* DEFINE - always false */      else if (condcode == OP_DEF)     /* DEFINE - always false */
1090        {        {
1091        condition = FALSE;        condition = FALSE;
1092        ecode += GET(ecode, 1);        ecode += GET(ecode, 1);
# Line 718  for (;;) Line 1098  for (;;)
1098    
1099      else      else
1100        {        {
1101        RMATCH(rrc, eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, NULL,        RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, NULL,
1102            match_condassert);            match_condassert, RM3);
1103        if (rrc == MATCH_MATCH)        if (rrc == MATCH_MATCH)
1104          {          {
1105          condition = TRUE;          condition = TRUE;
1106          ecode += 1 + LINK_SIZE + GET(ecode, LINK_SIZE + 2);          ecode += 1 + LINK_SIZE + GET(ecode, LINK_SIZE + 2);
1107          while (*ecode == OP_ALT) ecode += GET(ecode, 1);          while (*ecode == OP_ALT) ecode += GET(ecode, 1);
1108          }          }
1109        else if (rrc != MATCH_NOMATCH)        else if (rrc != MATCH_NOMATCH &&
1110                  (rrc != MATCH_THEN || md->start_match_ptr != ecode))
1111          {          {
1112          RRETURN(rrc);         /* Need braces because of following else */          RRETURN(rrc);         /* Need braces because of following else */
1113          }          }
1114        else        else
1115          {          {
1116          condition = FALSE;          condition = FALSE;
1117          ecode += GET(ecode, 1);          ecode += codelink;
1118          }          }
1119        }        }
1120    
1121      /* 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,
1122      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
1123      alternative doesn't exist, we can just plough on. */      match_cbegroup is required for an unlimited repeat of a possibly empty
1124        group. If the second alternative doesn't exist, we can just plough on. */
1125    
1126      if (condition || *ecode == OP_ALT)      if (condition || *ecode == OP_ALT)
1127        {        {
1128        ecode += 1 + LINK_SIZE;        ecode += 1 + LINK_SIZE;
1129        flags = match_tail_recursed | ((op == OP_SCOND)? match_cbegroup : 0);        if (op == OP_SCOND)        /* Possibly empty group */
1130        goto TAIL_RECURSE;          {
1131            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, match_cbegroup, RM49);
1132            RRETURN(rrc);
1133            }
1134          else                       /* Group must match something */
1135            {
1136            flags = 0;
1137            goto TAIL_RECURSE;
1138            }
1139        }        }
1140      else      else                         /* Condition false & no alternative */
1141        {        {
1142        ecode += 1 + LINK_SIZE;        ecode += 1 + LINK_SIZE;
1143        }        }
1144      break;      break;
1145    
1146    
1147      /* 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,
1148      restore the offsets appropriately and continue from after the call. */      to close any currently open capturing brackets. */
1149    
1150        case OP_CLOSE:
1151        number = GET2(ecode, 1);
1152        offset = number << 1;
1153    
1154    #ifdef PCRE_DEBUG
1155          printf("end bracket %d at *ACCEPT", number);
1156          printf("\n");
1157    #endif
1158    
1159        md->capture_last = number;
1160        if (offset >= md->offset_max) md->offset_overflow = TRUE; else
1161          {
1162          md->offset_vector[offset] =
1163            md->offset_vector[md->offset_end - number];
1164          md->offset_vector[offset+1] = (int)(eptr - md->start_subject);
1165          if (offset_top <= offset) offset_top = offset + 2;
1166          }
1167        ecode += 3;
1168        break;
1169    
1170    
1171        /* End of the pattern, either real or forced. If we are in a top-level
1172        recursion, we should restore the offsets appropriately and continue from
1173        after the call. */
1174    
1175        case OP_ACCEPT:
1176      case OP_END:      case OP_END:
1177      if (md->recursive != NULL && md->recursive->group_num == 0)      if (md->recursive != NULL && md->recursive->group_num == 0)
1178        {        {
# Line 765  for (;;) Line 1181  for (;;)
1181        md->recursive = rec->prevrec;        md->recursive = rec->prevrec;
1182        memmove(md->offset_vector, rec->offset_save,        memmove(md->offset_vector, rec->offset_save,
1183          rec->saved_max * sizeof(int));          rec->saved_max * sizeof(int));
1184        md->start_match = rec->save_start;        offset_top = rec->save_offset_top;
1185        ims = original_ims;        ims = original_ims;
1186        ecode = rec->after_call;        ecode = rec->after_call;
1187        break;        break;
1188        }        }
1189    
1190      /* 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
1191      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
1192        the subject. In both cases, backtracking will then try other alternatives,
1193        if any. */
1194    
1195        if (eptr == mstart &&
1196            (md->notempty ||
1197              (md->notempty_atstart &&
1198                mstart == md->start_subject + md->start_offset)))
1199          MRRETURN(MATCH_NOMATCH);
1200    
1201        /* Otherwise, we have a match. */
1202    
1203        md->end_match_ptr = eptr;           /* Record where we ended */
1204        md->end_offset_top = offset_top;    /* and how many extracts were taken */
1205        md->start_match_ptr = mstart;       /* and the start (\K can modify) */
1206    
1207      if (md->notempty && eptr == md->start_match) RRETURN(MATCH_NOMATCH);      /* For some reason, the macros don't work properly if an expression is
1208      md->end_match_ptr = eptr;          /* Record where we ended */      given as the argument to MRRETURN when the heap is in use. */
1209      md->end_offset_top = offset_top;   /* and how many extracts were taken */  
1210      RRETURN(MATCH_MATCH);      rrc = (op == OP_END)? MATCH_MATCH : MATCH_ACCEPT;
1211        MRRETURN(rrc);
1212    
1213      /* Change option settings */      /* Change option settings */
1214    
# Line 797  for (;;) Line 1228  for (;;)
1228      case OP_ASSERTBACK:      case OP_ASSERTBACK:
1229      do      do
1230        {        {
1231        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,
1232        if (rrc == MATCH_MATCH) break;          RM4);
1233        if (rrc != MATCH_NOMATCH) RRETURN(rrc);        if (rrc == MATCH_MATCH || rrc == MATCH_ACCEPT)
1234            {
1235            mstart = md->start_match_ptr;   /* In case \K reset it */
1236            break;
1237            }
1238          if (rrc != MATCH_NOMATCH &&
1239              (rrc != MATCH_THEN || md->start_match_ptr != ecode))
1240            RRETURN(rrc);
1241        ecode += GET(ecode, 1);        ecode += GET(ecode, 1);
1242        }        }
1243      while (*ecode == OP_ALT);      while (*ecode == OP_ALT);
1244      if (*ecode == OP_KET) RRETURN(MATCH_NOMATCH);      if (*ecode == OP_KET) MRRETURN(MATCH_NOMATCH);
1245    
1246      /* If checking an assertion for a condition, return MATCH_MATCH. */      /* If checking an assertion for a condition, return MATCH_MATCH. */
1247    
# Line 817  for (;;) Line 1255  for (;;)
1255      offset_top = md->end_offset_top;      offset_top = md->end_offset_top;
1256      continue;      continue;
1257    
1258      /* Negative assertion: all branches must fail to match */      /* Negative assertion: all branches must fail to match. Encountering SKIP,
1259        PRUNE, or COMMIT means we must assume failure without checking subsequent
1260        branches. */
1261    
1262      case OP_ASSERT_NOT:      case OP_ASSERT_NOT:
1263      case OP_ASSERTBACK_NOT:      case OP_ASSERTBACK_NOT:
1264      do      do
1265        {        {
1266        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,
1267        if (rrc == MATCH_MATCH) RRETURN(MATCH_NOMATCH);          RM5);
1268        if (rrc != MATCH_NOMATCH) RRETURN(rrc);        if (rrc == MATCH_MATCH || rrc == MATCH_ACCEPT) MRRETURN(MATCH_NOMATCH);
1269          if (rrc == MATCH_SKIP || rrc == MATCH_PRUNE || rrc == MATCH_COMMIT)
1270            {
1271            do ecode += GET(ecode,1); while (*ecode == OP_ALT);
1272            break;
1273            }
1274          if (rrc != MATCH_NOMATCH &&
1275              (rrc != MATCH_THEN || md->start_match_ptr != ecode))
1276            RRETURN(rrc);
1277        ecode += GET(ecode,1);        ecode += GET(ecode,1);
1278        }        }
1279      while (*ecode == OP_ALT);      while (*ecode == OP_ALT);
# Line 848  for (;;) Line 1296  for (;;)
1296        while (i-- > 0)        while (i-- > 0)
1297          {          {
1298          eptr--;          eptr--;
1299          if (eptr < md->start_subject) RRETURN(MATCH_NOMATCH);          if (eptr < md->start_subject) MRRETURN(MATCH_NOMATCH);
1300          BACKCHAR(eptr)          BACKCHAR(eptr);
1301          }          }
1302        }        }
1303      else      else
# Line 859  for (;;) Line 1307  for (;;)
1307    
1308        {        {
1309        eptr -= GET(ecode, 1);        eptr -= GET(ecode, 1);
1310        if (eptr < md->start_subject) RRETURN(MATCH_NOMATCH);        if (eptr < md->start_subject) MRRETURN(MATCH_NOMATCH);
1311        }        }
1312    
1313      /* Skip to next op code */      /* Save the earliest consulted character, then skip to next op code */
1314    
1315        if (eptr < md->start_used_ptr) md->start_used_ptr = eptr;
1316      ecode += 1 + LINK_SIZE;      ecode += 1 + LINK_SIZE;
1317      break;      break;
1318    
# Line 879  for (;;) Line 1328  for (;;)
1328        cb.callout_number   = ecode[1];        cb.callout_number   = ecode[1];
1329        cb.offset_vector    = md->offset_vector;        cb.offset_vector    = md->offset_vector;
1330        cb.subject          = (PCRE_SPTR)md->start_subject;        cb.subject          = (PCRE_SPTR)md->start_subject;
1331        cb.subject_length   = md->end_subject - md->start_subject;        cb.subject_length   = (int)(md->end_subject - md->start_subject);
1332        cb.start_match      = md->start_match - md->start_subject;        cb.start_match      = (int)(mstart - md->start_subject);
1333        cb.current_position = eptr - md->start_subject;        cb.current_position = (int)(eptr - md->start_subject);
1334        cb.pattern_position = GET(ecode, 2);        cb.pattern_position = GET(ecode, 2);
1335        cb.next_item_length = GET(ecode, 2 + LINK_SIZE);        cb.next_item_length = GET(ecode, 2 + LINK_SIZE);
1336        cb.capture_top      = offset_top/2;        cb.capture_top      = offset_top/2;
1337        cb.capture_last     = md->capture_last;        cb.capture_last     = md->capture_last;
1338        cb.callout_data     = md->callout_data;        cb.callout_data     = md->callout_data;
1339        if ((rrc = (*pcre_callout)(&cb)) > 0) RRETURN(MATCH_NOMATCH);        if ((rrc = (*pcre_callout)(&cb)) > 0) MRRETURN(MATCH_NOMATCH);
1340        if (rrc < 0) RRETURN(rrc);        if (rrc < 0) RRETURN(rrc);
1341        }        }
1342      ecode += 2 + 2*LINK_SIZE;      ecode += 2 + 2*LINK_SIZE;
# Line 942  for (;;) Line 1391  for (;;)
1391    
1392        memcpy(new_recursive.offset_save, md->offset_vector,        memcpy(new_recursive.offset_save, md->offset_vector,
1393              new_recursive.saved_max * sizeof(int));              new_recursive.saved_max * sizeof(int));
1394        new_recursive.save_start = md->start_match;        new_recursive.save_offset_top = offset_top;
       md->start_match = eptr;  
1395    
1396        /* 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
1397        restore the offset and recursion data. */        restore the offset and recursion data. */
# Line 952  for (;;) Line 1400  for (;;)
1400        flags = (*callpat >= OP_SBRA)? match_cbegroup : 0;        flags = (*callpat >= OP_SBRA)? match_cbegroup : 0;
1401        do        do
1402          {          {
1403          RMATCH(rrc, eptr, callpat + _pcre_OP_lengths[*callpat], offset_top,          RMATCH(eptr, callpat + _pcre_OP_lengths[*callpat], offset_top,
1404            md, ims, eptrb, flags);            md, ims, eptrb, flags, RM6);
1405          if (rrc == MATCH_MATCH)          if (rrc == MATCH_MATCH || rrc == MATCH_ACCEPT)
1406            {            {
1407            DPRINTF(("Recursion matched\n"));            DPRINTF(("Recursion matched\n"));
1408            md->recursive = new_recursive.prevrec;            md->recursive = new_recursive.prevrec;
1409            if (new_recursive.offset_save != stacksave)            if (new_recursive.offset_save != stacksave)
1410              (pcre_free)(new_recursive.offset_save);              (pcre_free)(new_recursive.offset_save);
1411            RRETURN(MATCH_MATCH);            MRRETURN(MATCH_MATCH);
1412            }            }
1413          else if (rrc != MATCH_NOMATCH)          else if (rrc != MATCH_NOMATCH &&
1414                    (rrc != MATCH_THEN || md->start_match_ptr != ecode))
1415            {            {
1416            DPRINTF(("Recursion gave error %d\n", rrc));            DPRINTF(("Recursion gave error %d\n", rrc));
1417              if (new_recursive.offset_save != stacksave)
1418                (pcre_free)(new_recursive.offset_save);
1419            RRETURN(rrc);            RRETURN(rrc);
1420            }            }
1421    
# Line 979  for (;;) Line 1430  for (;;)
1430        md->recursive = new_recursive.prevrec;        md->recursive = new_recursive.prevrec;
1431        if (new_recursive.offset_save != stacksave)        if (new_recursive.offset_save != stacksave)
1432          (pcre_free)(new_recursive.offset_save);          (pcre_free)(new_recursive.offset_save);
1433        RRETURN(MATCH_NOMATCH);        MRRETURN(MATCH_NOMATCH);
1434        }        }
1435      /* Control never reaches here */      /* Control never reaches here */
1436    
# Line 988  for (;;) Line 1439  for (;;)
1439      a move back into the brackets. Friedl calls these "atomic" subpatterns.      a move back into the brackets. Friedl calls these "atomic" subpatterns.
1440      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
1441      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
1442      the end of a normal bracket, leaving the subject pointer. */      the end of a normal bracket, leaving the subject pointer, but resetting
1443        the start-of-match value in case it was changed by \K. */
1444    
1445      case OP_ONCE:      case OP_ONCE:
1446      prev = ecode;      prev = ecode;
# Line 996  for (;;) Line 1448  for (;;)
1448    
1449      do      do
1450        {        {
1451        RMATCH(rrc, eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims,        RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, eptrb, 0, RM7);
1452          eptrb, 0);        if (rrc == MATCH_MATCH)  /* Note: _not_ MATCH_ACCEPT */
1453        if (rrc == MATCH_MATCH) break;          {
1454        if (rrc != MATCH_NOMATCH) RRETURN(rrc);          mstart = md->start_match_ptr;
1455            break;
1456            }
1457          if (rrc != MATCH_NOMATCH &&
1458              (rrc != MATCH_THEN || md->start_match_ptr != ecode))
1459            RRETURN(rrc);
1460        ecode += GET(ecode,1);        ecode += GET(ecode,1);
1461        }        }
1462      while (*ecode == OP_ALT);      while (*ecode == OP_ALT);
# Line 1042  for (;;) Line 1499  for (;;)
1499    
1500      if (*ecode == OP_KETRMIN)      if (*ecode == OP_KETRMIN)
1501        {        {
1502        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);
1503        if (rrc != MATCH_NOMATCH) RRETURN(rrc);        if (rrc != MATCH_NOMATCH) RRETURN(rrc);
1504        ecode = prev;        ecode = prev;
1505        flags = match_tail_recursed;        flags = 0;
1506        goto TAIL_RECURSE;        goto TAIL_RECURSE;
1507        }        }
1508      else  /* OP_KETRMAX */      else  /* OP_KETRMAX */
1509        {        {
1510        RMATCH(rrc, eptr, prev, offset_top, md, ims, eptrb, match_cbegroup);        RMATCH(eptr, prev, offset_top, md, ims, eptrb, match_cbegroup, RM9);
1511        if (rrc != MATCH_NOMATCH) RRETURN(rrc);        if (rrc != MATCH_NOMATCH) RRETURN(rrc);
1512        ecode += 1 + LINK_SIZE;        ecode += 1 + LINK_SIZE;
1513        flags = match_tail_recursed;        flags = 0;
1514        goto TAIL_RECURSE;        goto TAIL_RECURSE;
1515        }        }
1516      /* Control never gets here */      /* Control never gets here */
# Line 1065  for (;;) Line 1522  for (;;)
1522      do ecode += GET(ecode,1); while (*ecode == OP_ALT);      do ecode += GET(ecode,1); while (*ecode == OP_ALT);
1523      break;      break;
1524    
1525      /* BRAZERO and BRAMINZERO occur just before a bracket group, indicating      /* BRAZERO, BRAMINZERO and SKIPZERO occur just before a bracket group,
1526      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
1527      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
1528      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
1529      preceded by BRAZERO or BRAMINZERO. */      optional ones preceded by BRAZERO or BRAMINZERO. */
1530    
1531      case OP_BRAZERO:      case OP_BRAZERO:
1532        {        {
1533        next = ecode+1;        next = ecode+1;
1534        RMATCH(rrc, eptr, next, offset_top, md, ims, eptrb, 0);        RMATCH(eptr, next, offset_top, md, ims, eptrb, 0, RM10);
1535        if (rrc != MATCH_NOMATCH) RRETURN(rrc);        if (rrc != MATCH_NOMATCH) RRETURN(rrc);
1536        do next += GET(next,1); while (*next == OP_ALT);        do next += GET(next,1); while (*next == OP_ALT);
1537        ecode = next + 1 + LINK_SIZE;        ecode = next + 1 + LINK_SIZE;
# Line 1085  for (;;) Line 1542  for (;;)
1542        {        {
1543        next = ecode+1;        next = ecode+1;
1544        do next += GET(next, 1); while (*next == OP_ALT);        do next += GET(next, 1); while (*next == OP_ALT);
1545        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);
1546        if (rrc != MATCH_NOMATCH) RRETURN(rrc);        if (rrc != MATCH_NOMATCH) RRETURN(rrc);
1547        ecode++;        ecode++;
1548        }        }
1549      break;      break;
1550    
1551        case OP_SKIPZERO:
1552          {
1553          next = ecode+1;
1554          do next += GET(next,1); while (*next == OP_ALT);
1555          ecode = next + 1 + LINK_SIZE;
1556          }
1557        break;
1558    
1559      /* End of a group, repeated or non-repeating. */      /* End of a group, repeated or non-repeating. */
1560    
1561      case OP_KET:      case OP_KET:
# Line 1109  for (;;) Line 1574  for (;;)
1574        }        }
1575      else saved_eptr = NULL;      else saved_eptr = NULL;
1576    
1577      /* 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
1578      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
1579      assertions. Do this also for the "once" (atomic) groups. */      use by positive assertions. We also need to record the match start in case
1580        it was changed by \K. */
1581    
1582      if (*prev == OP_ASSERT || *prev == OP_ASSERT_NOT ||      if (*prev == OP_ASSERT || *prev == OP_ASSERT_NOT ||
1583          *prev == OP_ASSERTBACK || *prev == OP_ASSERTBACK_NOT ||          *prev == OP_ASSERTBACK || *prev == OP_ASSERTBACK_NOT ||
# Line 1119  for (;;) Line 1585  for (;;)
1585        {        {
1586        md->end_match_ptr = eptr;      /* For ONCE */        md->end_match_ptr = eptr;      /* For ONCE */
1587        md->end_offset_top = offset_top;        md->end_offset_top = offset_top;
1588        RRETURN(MATCH_MATCH);        md->start_match_ptr = mstart;
1589          MRRETURN(MATCH_MATCH);
1590        }        }
1591    
1592      /* 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 1133  for (;;) Line 1600  for (;;)
1600        number = GET2(prev, 1+LINK_SIZE);        number = GET2(prev, 1+LINK_SIZE);
1601        offset = number << 1;        offset = number << 1;
1602    
1603  #ifdef DEBUG  #ifdef PCRE_DEBUG
1604        printf("end bracket %d", number);        printf("end bracket %d", number);
1605        printf("\n");        printf("\n");
1606  #endif  #endif
# Line 1143  for (;;) Line 1610  for (;;)
1610          {          {
1611          md->offset_vector[offset] =          md->offset_vector[offset] =
1612            md->offset_vector[md->offset_end - number];            md->offset_vector[md->offset_end - number];
1613          md->offset_vector[offset+1] = eptr - md->start_subject;          md->offset_vector[offset+1] = (int)(eptr - md->start_subject);
1614          if (offset_top <= offset) offset_top = offset + 2;          if (offset_top <= offset) offset_top = offset + 2;
1615          }          }
1616    
# Line 1155  for (;;) Line 1622  for (;;)
1622          recursion_info *rec = md->recursive;          recursion_info *rec = md->recursive;
1623          DPRINTF(("Recursion (%d) succeeded - continuing\n", number));          DPRINTF(("Recursion (%d) succeeded - continuing\n", number));
1624          md->recursive = rec->prevrec;          md->recursive = rec->prevrec;
         md->start_match = rec->save_start;  
1625          memcpy(md->offset_vector, rec->offset_save,          memcpy(md->offset_vector, rec->offset_save,
1626            rec->saved_max * sizeof(int));            rec->saved_max * sizeof(int));
1627            offset_top = rec->save_offset_top;
1628          ecode = rec->after_call;          ecode = rec->after_call;
1629          ims = original_ims;          ims = original_ims;
1630          break;          break;
# Line 1184  for (;;) Line 1651  for (;;)
1651    
1652      /* 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
1653      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
1654      tail recursion to avoid using another stack frame. */      tail recursion to avoid using another stack frame, unless we have an
1655        unlimited repeat of a group that can match an empty string. */
1656    
1657      flags = (*prev >= OP_SBRA)? match_cbegroup : 0;      flags = (*prev >= OP_SBRA)? match_cbegroup : 0;
1658    
1659      if (*ecode == OP_KETRMIN)      if (*ecode == OP_KETRMIN)
1660        {        {
1661        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);
1662        if (rrc != MATCH_NOMATCH) RRETURN(rrc);        if (rrc != MATCH_NOMATCH) RRETURN(rrc);
1663          if (flags != 0)    /* Could match an empty string */
1664            {
1665            RMATCH(eptr, prev, offset_top, md, ims, eptrb, flags, RM50);
1666            RRETURN(rrc);
1667            }
1668        ecode = prev;        ecode = prev;
       flags |= match_tail_recursed;  
1669        goto TAIL_RECURSE;        goto TAIL_RECURSE;
1670        }        }
1671      else  /* OP_KETRMAX */      else  /* OP_KETRMAX */
1672        {        {
1673        RMATCH(rrc, eptr, prev, offset_top, md, ims, eptrb, flags);        RMATCH(eptr, prev, offset_top, md, ims, eptrb, flags, RM13);
1674        if (rrc != MATCH_NOMATCH) RRETURN(rrc);        if (rrc != MATCH_NOMATCH) RRETURN(rrc);
1675        ecode += 1 + LINK_SIZE;        ecode += 1 + LINK_SIZE;
1676        flags = match_tail_recursed;        flags = 0;
1677        goto TAIL_RECURSE;        goto TAIL_RECURSE;
1678        }        }
1679      /* Control never gets here */      /* Control never gets here */
# Line 1209  for (;;) Line 1681  for (;;)
1681      /* Start of subject unless notbol, or after internal newline if multiline */      /* Start of subject unless notbol, or after internal newline if multiline */
1682    
1683      case OP_CIRC:      case OP_CIRC:
1684      if (md->notbol && eptr == md->start_subject) RRETURN(MATCH_NOMATCH);      if (md->notbol && eptr == md->start_subject) MRRETURN(MATCH_NOMATCH);
1685      if ((ims & PCRE_MULTILINE) != 0)      if ((ims & PCRE_MULTILINE) != 0)
1686        {        {
1687        if (eptr != md->start_subject &&        if (eptr != md->start_subject &&
1688            (eptr == md->end_subject || !WAS_NEWLINE(eptr)))            (eptr == md->end_subject || !WAS_NEWLINE(eptr)))
1689          RRETURN(MATCH_NOMATCH);          MRRETURN(MATCH_NOMATCH);
1690        ecode++;        ecode++;
1691        break;        break;
1692        }        }
# Line 1223  for (;;) Line 1695  for (;;)
1695      /* Start of subject assertion */      /* Start of subject assertion */
1696    
1697      case OP_SOD:      case OP_SOD:
1698      if (eptr != md->start_subject) RRETURN(MATCH_NOMATCH);      if (eptr != md->start_subject) MRRETURN(MATCH_NOMATCH);
1699      ecode++;      ecode++;
1700      break;      break;
1701    
1702      /* Start of match assertion */      /* Start of match assertion */
1703    
1704      case OP_SOM:      case OP_SOM:
1705      if (eptr != md->start_subject + md->start_offset) RRETURN(MATCH_NOMATCH);      if (eptr != md->start_subject + md->start_offset) MRRETURN(MATCH_NOMATCH);
1706        ecode++;
1707        break;
1708    
1709        /* Reset the start of match point */
1710    
1711        case OP_SET_SOM:
1712        mstart = eptr;
1713      ecode++;      ecode++;
1714      break;      break;
1715    
# Line 1241  for (;;) Line 1720  for (;;)
1720      if ((ims & PCRE_MULTILINE) != 0)      if ((ims & PCRE_MULTILINE) != 0)
1721        {        {
1722        if (eptr < md->end_subject)        if (eptr < md->end_subject)
1723          { if (!IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH); }          { if (!IS_NEWLINE(eptr)) MRRETURN(MATCH_NOMATCH); }
1724        else        else
1725          { if (md->noteol) RRETURN(MATCH_NOMATCH); }          {
1726            if (md->noteol) MRRETURN(MATCH_NOMATCH);
1727            SCHECK_PARTIAL();
1728            }
1729        ecode++;        ecode++;
1730        break;        break;
1731        }        }
1732      else      else  /* Not multiline */
1733        {        {
1734        if (md->noteol) RRETURN(MATCH_NOMATCH);        if (md->noteol) MRRETURN(MATCH_NOMATCH);
1735        if (!md->endonly)        if (!md->endonly) goto ASSERT_NL_OR_EOS;
         {  
         if (eptr != md->end_subject &&  
             (!IS_NEWLINE(eptr) || eptr != md->end_subject - md->nllen))  
           RRETURN(MATCH_NOMATCH);  
         ecode++;  
         break;  
         }  
1736        }        }
1737    
1738      /* ... else fall through for endonly */      /* ... else fall through for endonly */
1739    
1740      /* End of subject assertion (\z) */      /* End of subject assertion (\z) */
1741    
1742      case OP_EOD:      case OP_EOD:
1743      if (eptr < md->end_subject) RRETURN(MATCH_NOMATCH);      if (eptr < md->end_subject) MRRETURN(MATCH_NOMATCH);
1744        SCHECK_PARTIAL();
1745      ecode++;      ecode++;
1746      break;      break;
1747    
1748      /* End of subject or ending \n assertion (\Z) */      /* End of subject or ending \n assertion (\Z) */
1749    
1750      case OP_EODN:      case OP_EODN:
1751      if (eptr != md->end_subject &&      ASSERT_NL_OR_EOS:
1752        if (eptr < md->end_subject &&
1753          (!IS_NEWLINE(eptr) || eptr != md->end_subject - md->nllen))          (!IS_NEWLINE(eptr) || eptr != md->end_subject - md->nllen))
1754        RRETURN(MATCH_NOMATCH);        MRRETURN(MATCH_NOMATCH);
1755    
1756        /* Either at end of string or \n before end. */
1757    
1758        SCHECK_PARTIAL();
1759      ecode++;      ecode++;
1760      break;      break;
1761    
# Line 1285  for (;;) Line 1767  for (;;)
1767    
1768        /* Find out if the previous and current characters are "word" characters.        /* Find out if the previous and current characters are "word" characters.
1769        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
1770        be "non-word" characters. */        be "non-word" characters. Remember the earliest consulted character for
1771          partial matching. */
1772    
1773  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
1774        if (utf8)        if (utf8)
1775          {          {
1776            /* Get status of previous character */
1777    
1778          if (eptr == md->start_subject) prev_is_word = FALSE; else          if (eptr == md->start_subject) prev_is_word = FALSE; else
1779            {            {
1780            const uschar *lastptr = eptr - 1;            USPTR lastptr = eptr - 1;
1781            while((*lastptr & 0xc0) == 0x80) lastptr--;            while((*lastptr & 0xc0) == 0x80) lastptr--;
1782              if (lastptr < md->start_used_ptr) md->start_used_ptr = lastptr;
1783            GETCHAR(c, lastptr);            GETCHAR(c, lastptr);
1784    #ifdef SUPPORT_UCP
1785              if (md->use_ucp)
1786                {
1787                if (c == '_') prev_is_word = TRUE; else
1788                  {
1789                  int cat = UCD_CATEGORY(c);
1790                  prev_is_word = (cat == ucp_L || cat == ucp_N);
1791                  }
1792                }
1793              else
1794    #endif
1795            prev_is_word = c < 256 && (md->ctypes[c] & ctype_word) != 0;            prev_is_word = c < 256 && (md->ctypes[c] & ctype_word) != 0;
1796            }            }
1797          if (eptr >= md->end_subject) cur_is_word = FALSE; else  
1798            /* Get status of next character */
1799    
1800            if (eptr >= md->end_subject)
1801              {
1802              SCHECK_PARTIAL();
1803              cur_is_word = FALSE;
1804              }
1805            else
1806            {            {
1807            GETCHAR(c, eptr);            GETCHAR(c, eptr);
1808    #ifdef SUPPORT_UCP
1809              if (md->use_ucp)
1810                {
1811                if (c == '_') cur_is_word = TRUE; else
1812                  {
1813                  int cat = UCD_CATEGORY(c);
1814                  cur_is_word = (cat == ucp_L || cat == ucp_N);
1815                  }
1816                }
1817              else
1818    #endif
1819            cur_is_word = c < 256 && (md->ctypes[c] & ctype_word) != 0;            cur_is_word = c < 256 && (md->ctypes[c] & ctype_word) != 0;
1820            }            }
1821          }          }
1822        else        else
1823  #endif  #endif
1824    
1825        /* More streamlined when not in UTF-8 mode */        /* Not in UTF-8 mode, but we may still have PCRE_UCP set, and for
1826          consistency with the behaviour of \w we do use it in this case. */
1827    
1828          {          {
1829          prev_is_word = (eptr != md->start_subject) &&          /* Get status of previous character */
1830            ((md->ctypes[eptr[-1]] & ctype_word) != 0);  
1831          cur_is_word = (eptr < md->end_subject) &&          if (eptr == md->start_subject) prev_is_word = FALSE; else
1832            ((md->ctypes[*eptr] & ctype_word) != 0);            {
1833              if (eptr <= md->start_used_ptr) md->start_used_ptr = eptr - 1;
1834    #ifdef SUPPORT_UCP
1835              if (md->use_ucp)
1836                {
1837                c = eptr[-1];
1838                if (c == '_') prev_is_word = TRUE; else
1839                  {
1840                  int cat = UCD_CATEGORY(c);
1841                  prev_is_word = (cat == ucp_L || cat == ucp_N);
1842                  }
1843                }
1844              else
1845    #endif
1846              prev_is_word = ((md->ctypes[eptr[-1]] & ctype_word) != 0);
1847              }
1848    
1849            /* Get status of next character */
1850    
1851            if (eptr >= md->end_subject)
1852              {
1853              SCHECK_PARTIAL();
1854              cur_is_word = FALSE;
1855              }
1856            else
1857    #ifdef SUPPORT_UCP
1858            if (md->use_ucp)
1859              {
1860              c = *eptr;
1861              if (c == '_') cur_is_word = TRUE; else
1862                {
1863                int cat = UCD_CATEGORY(c);
1864                cur_is_word = (cat == ucp_L || cat == ucp_N);
1865                }
1866              }
1867            else
1868    #endif
1869            cur_is_word = ((md->ctypes[*eptr] & ctype_word) != 0);
1870          }          }
1871    
1872        /* Now see if the situation is what we want */        /* Now see if the situation is what we want */
1873    
1874        if ((*ecode++ == OP_WORD_BOUNDARY)?        if ((*ecode++ == OP_WORD_BOUNDARY)?
1875             cur_is_word == prev_is_word : cur_is_word != prev_is_word)             cur_is_word == prev_is_word : cur_is_word != prev_is_word)
1876          RRETURN(MATCH_NOMATCH);          MRRETURN(MATCH_NOMATCH);
1877        }        }
1878      break;      break;
1879    
1880      /* Match a single character type; inline for speed */      /* Match a single character type; inline for speed */
1881    
1882      case OP_ANY:      case OP_ANY:
1883      if ((ims & PCRE_DOTALL) == 0)      if (IS_NEWLINE(eptr)) MRRETURN(MATCH_NOMATCH);
1884        /* Fall through */
1885    
1886        case OP_ALLANY:
1887        if (eptr++ >= md->end_subject)
1888        {        {
1889        if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH);        SCHECK_PARTIAL();
1890          MRRETURN(MATCH_NOMATCH);
1891        }        }
1892      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++;  
1893      ecode++;      ecode++;
1894      break;      break;
1895    
# Line 1340  for (;;) Line 1897  for (;;)
1897      any byte, even newline, independent of the setting of PCRE_DOTALL. */      any byte, even newline, independent of the setting of PCRE_DOTALL. */
1898    
1899      case OP_ANYBYTE:      case OP_ANYBYTE:
1900      if (eptr++ >= md->end_subject) RRETURN(MATCH_NOMATCH);      if (eptr++ >= md->end_subject)
1901          {
1902          SCHECK_PARTIAL();
1903          MRRETURN(MATCH_NOMATCH);
1904          }
1905      ecode++;      ecode++;
1906      break;      break;
1907    
1908      case OP_NOT_DIGIT:      case OP_NOT_DIGIT:
1909      if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);      if (eptr >= md->end_subject)
1910          {
1911          SCHECK_PARTIAL();
1912          MRRETURN(MATCH_NOMATCH);
1913          }
1914      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
1915      if (      if (
1916  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
# Line 1353  for (;;) Line 1918  for (;;)
1918  #endif  #endif
1919         (md->ctypes[c] & ctype_digit) != 0         (md->ctypes[c] & ctype_digit) != 0
1920         )         )
1921        RRETURN(MATCH_NOMATCH);        MRRETURN(MATCH_NOMATCH);
1922      ecode++;      ecode++;
1923      break;      break;
1924    
1925      case OP_DIGIT:      case OP_DIGIT:
1926      if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);      if (eptr >= md->end_subject)
1927          {
1928          SCHECK_PARTIAL();
1929          MRRETURN(MATCH_NOMATCH);
1930          }
1931      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
1932      if (      if (
1933  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
# Line 1366  for (;;) Line 1935  for (;;)
1935  #endif  #endif
1936         (md->ctypes[c] & ctype_digit) == 0         (md->ctypes[c] & ctype_digit) == 0
1937         )         )
1938        RRETURN(MATCH_NOMATCH);        MRRETURN(MATCH_NOMATCH);
1939      ecode++;      ecode++;
1940      break;      break;
1941    
1942      case OP_NOT_WHITESPACE:      case OP_NOT_WHITESPACE:
1943      if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);      if (eptr >= md->end_subject)
1944          {
1945          SCHECK_PARTIAL();
1946          MRRETURN(MATCH_NOMATCH);
1947          }
1948      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
1949      if (      if (
1950  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
# Line 1379  for (;;) Line 1952  for (;;)
1952  #endif  #endif
1953         (md->ctypes[c] & ctype_space) != 0         (md->ctypes[c] & ctype_space) != 0
1954         )         )
1955        RRETURN(MATCH_NOMATCH);        MRRETURN(MATCH_NOMATCH);
1956      ecode++;      ecode++;
1957      break;      break;
1958    
1959      case OP_WHITESPACE:      case OP_WHITESPACE:
1960      if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);      if (eptr >= md->end_subject)
1961          {
1962          SCHECK_PARTIAL();
1963          MRRETURN(MATCH_NOMATCH);
1964          }
1965      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
1966      if (      if (
1967  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
# Line 1392  for (;;) Line 1969  for (;;)
1969  #endif  #endif
1970         (md->ctypes[c] & ctype_space) == 0         (md->ctypes[c] & ctype_space) == 0
1971         )         )
1972        RRETURN(MATCH_NOMATCH);        MRRETURN(MATCH_NOMATCH);
1973      ecode++;      ecode++;
1974      break;      break;
1975    
1976      case OP_NOT_WORDCHAR:      case OP_NOT_WORDCHAR:
1977      if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);      if (eptr >= md->end_subject)
1978          {
1979          SCHECK_PARTIAL();
1980          MRRETURN(MATCH_NOMATCH);
1981          }
1982      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
1983      if (      if (
1984  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
# Line 1405  for (;;) Line 1986  for (;;)
1986  #endif  #endif
1987         (md->ctypes[c] & ctype_word) != 0         (md->ctypes[c] & ctype_word) != 0
1988         )         )
1989        RRETURN(MATCH_NOMATCH);        MRRETURN(MATCH_NOMATCH);
1990      ecode++;      ecode++;
1991      break;      break;
1992    
1993      case OP_WORDCHAR:      case OP_WORDCHAR:
1994      if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);      if (eptr >= md->end_subject)
1995          {
1996          SCHECK_PARTIAL();
1997          MRRETURN(MATCH_NOMATCH);
1998          }
1999      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
2000      if (      if (
2001  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
# Line 1418  for (;;) Line 2003  for (;;)
2003  #endif  #endif
2004         (md->ctypes[c] & ctype_word) == 0         (md->ctypes[c] & ctype_word) == 0
2005         )         )
2006        RRETURN(MATCH_NOMATCH);        MRRETURN(MATCH_NOMATCH);
2007      ecode++;      ecode++;
2008      break;      break;
2009    
2010      case OP_ANYNL:      case OP_ANYNL:
2011      if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);      if (eptr >= md->end_subject)
2012      GETCHARINCTEST(c, eptr);        {
2013          SCHECK_PARTIAL();
2014          MRRETURN(MATCH_NOMATCH);
2015          }
2016        GETCHARINCTEST(c, eptr);
2017      switch(c)      switch(c)
2018        {        {
2019        default: RRETURN(MATCH_NOMATCH);        default: MRRETURN(MATCH_NOMATCH);
2020        case 0x000d:        case 0x000d:
2021        if (eptr < md->end_subject && *eptr == 0x0a) eptr++;        if (eptr < md->end_subject && *eptr == 0x0a) eptr++;
2022        break;        break;
2023    
2024        case 0x000a:        case 0x000a:
2025          break;
2026    
2027        case 0x000b:        case 0x000b:
2028        case 0x000c:        case 0x000c:
2029        case 0x0085:        case 0x0085:
2030        case 0x2028:        case 0x2028:
2031        case 0x2029:        case 0x2029:
2032          if (md->bsr_anycrlf) MRRETURN(MATCH_NOMATCH);
2033          break;
2034          }
2035        ecode++;
2036        break;
2037    
2038        case OP_NOT_HSPACE:
2039        if (eptr >= md->end_subject)
2040          {
2041          SCHECK_PARTIAL();
2042          MRRETURN(MATCH_NOMATCH);
2043          }
2044        GETCHARINCTEST(c, eptr);
2045        switch(c)
2046          {
2047          default: break;
2048          case 0x09:      /* HT */
2049          case 0x20:      /* SPACE */
2050          case 0xa0:      /* NBSP */
2051          case 0x1680:    /* OGHAM SPACE MARK */
2052          case 0x180e:    /* MONGOLIAN VOWEL SEPARATOR */
2053          case 0x2000:    /* EN QUAD */
2054          case 0x2001:    /* EM QUAD */
2055          case 0x2002:    /* EN SPACE */
2056          case 0x2003:    /* EM SPACE */
2057          case 0x2004:    /* THREE-PER-EM SPACE */
2058          case 0x2005:    /* FOUR-PER-EM SPACE */
2059          case 0x2006:    /* SIX-PER-EM SPACE */
2060          case 0x2007:    /* FIGURE SPACE */
2061          case 0x2008:    /* PUNCTUATION SPACE */
2062          case 0x2009:    /* THIN SPACE */
2063          case 0x200A:    /* HAIR SPACE */
2064          case 0x202f:    /* NARROW NO-BREAK SPACE */
2065          case 0x205f:    /* MEDIUM MATHEMATICAL SPACE */
2066          case 0x3000:    /* IDEOGRAPHIC SPACE */
2067          MRRETURN(MATCH_NOMATCH);
2068          }
2069        ecode++;
2070        break;
2071    
2072        case OP_HSPACE:
2073        if (eptr >= md->end_subject)
2074          {
2075          SCHECK_PARTIAL();
2076          MRRETURN(MATCH_NOMATCH);
2077          }
2078        GETCHARINCTEST(c, eptr);
2079        switch(c)
2080          {
2081          default: MRRETURN(MATCH_NOMATCH);
2082          case 0x09:      /* HT */
2083          case 0x20:      /* SPACE */
2084          case 0xa0:      /* NBSP */
2085          case 0x1680:    /* OGHAM SPACE MARK */
2086          case 0x180e:    /* MONGOLIAN VOWEL SEPARATOR */
2087          case 0x2000:    /* EN QUAD */
2088          case 0x2001:    /* EM QUAD */
2089          case 0x2002:    /* EN SPACE */
2090          case 0x2003:    /* EM SPACE */
2091          case 0x2004:    /* THREE-PER-EM SPACE */
2092          case 0x2005:    /* FOUR-PER-EM SPACE */
2093          case 0x2006:    /* SIX-PER-EM SPACE */
2094          case 0x2007:    /* FIGURE SPACE */
2095          case 0x2008:    /* PUNCTUATION SPACE */
2096          case 0x2009:    /* THIN SPACE */
2097          case 0x200A:    /* HAIR SPACE */
2098          case 0x202f:    /* NARROW NO-BREAK SPACE */
2099          case 0x205f:    /* MEDIUM MATHEMATICAL SPACE */
2100          case 0x3000:    /* IDEOGRAPHIC SPACE */
2101          break;
2102          }
2103        ecode++;
2104        break;
2105    
2106        case OP_NOT_VSPACE:
2107        if (eptr >= md->end_subject)
2108          {
2109          SCHECK_PARTIAL();
2110          MRRETURN(MATCH_NOMATCH);
2111          }
2112        GETCHARINCTEST(c, eptr);
2113        switch(c)
2114          {
2115          default: break;
2116          case 0x0a:      /* LF */
2117          case 0x0b:      /* VT */
2118          case 0x0c:      /* FF */
2119          case 0x0d:      /* CR */
2120          case 0x85:      /* NEL */
2121          case 0x2028:    /* LINE SEPARATOR */
2122          case 0x2029:    /* PARAGRAPH SEPARATOR */
2123          MRRETURN(MATCH_NOMATCH);
2124          }
2125        ecode++;
2126        break;
2127    
2128        case OP_VSPACE:
2129        if (eptr >= md->end_subject)
2130          {
2131          SCHECK_PARTIAL();
2132          MRRETURN(MATCH_NOMATCH);
2133          }
2134        GETCHARINCTEST(c, eptr);
2135        switch(c)
2136          {
2137          default: MRRETURN(MATCH_NOMATCH);
2138          case 0x0a:      /* LF */
2139          case 0x0b:      /* VT */
2140          case 0x0c:      /* FF */
2141          case 0x0d:      /* CR */
2142          case 0x85:      /* NEL */
2143          case 0x2028:    /* LINE SEPARATOR */
2144          case 0x2029:    /* PARAGRAPH SEPARATOR */
2145        break;        break;
2146        }        }
2147      ecode++;      ecode++;
# Line 1448  for (;;) Line 2153  for (;;)
2153    
2154      case OP_PROP:      case OP_PROP:
2155      case OP_NOTPROP:      case OP_NOTPROP:
2156      if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);      if (eptr >= md->end_subject)
2157          {
2158          SCHECK_PARTIAL();
2159          MRRETURN(MATCH_NOMATCH);
2160          }
2161      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
2162        {        {
2163        int chartype, script;        const ucd_record *prop = GET_UCD(c);
       int category = _pcre_ucp_findprop(c, &chartype, &script);  
2164    
2165        switch(ecode[1])        switch(ecode[1])
2166          {          {
2167          case PT_ANY:          case PT_ANY:
2168          if (op == OP_NOTPROP) RRETURN(MATCH_NOMATCH);          if (op == OP_NOTPROP) MRRETURN(MATCH_NOMATCH);
2169          break;          break;
2170    
2171          case PT_LAMP:          case PT_LAMP:
2172          if ((chartype == ucp_Lu ||          if ((prop->chartype == ucp_Lu ||
2173               chartype == ucp_Ll ||               prop->chartype == ucp_Ll ||
2174               chartype == ucp_Lt) == (op == OP_NOTPROP))               prop->chartype == ucp_Lt) == (op == OP_NOTPROP))
2175            RRETURN(MATCH_NOMATCH);            MRRETURN(MATCH_NOMATCH);
2176           break;          break;
2177    
2178          case PT_GC:          case PT_GC:
2179          if ((ecode[2] != category) == (op == OP_PROP))          if ((ecode[2] != _pcre_ucp_gentype[prop->chartype]) == (op == OP_PROP))
2180            RRETURN(MATCH_NOMATCH);            MRRETURN(MATCH_NOMATCH);
2181          break;          break;
2182    
2183          case PT_PC:          case PT_PC:
2184          if ((ecode[2] != chartype) == (op == OP_PROP))          if ((ecode[2] != prop->chartype) == (op == OP_PROP))
2185            RRETURN(MATCH_NOMATCH);            MRRETURN(MATCH_NOMATCH);
2186          break;          break;
2187    
2188          case PT_SC:          case PT_SC:
2189          if ((ecode[2] != script) == (op == OP_PROP))          if ((ecode[2] != prop->script) == (op == OP_PROP))
2190            RRETURN(MATCH_NOMATCH);            MRRETURN(MATCH_NOMATCH);
2191            break;
2192    
2193            /* These are specials */
2194    
2195            case PT_ALNUM:
2196            if ((_pcre_ucp_gentype[prop->chartype] == ucp_L ||
2197                 _pcre_ucp_gentype[prop->chartype] == ucp_N) == (op == OP_NOTPROP))
2198              MRRETURN(MATCH_NOMATCH);
2199            break;
2200    
2201            case PT_SPACE:    /* Perl space */
2202            if ((_pcre_ucp_gentype[prop->chartype] == ucp_Z ||
2203                 c == CHAR_HT || c == CHAR_NL || c == CHAR_FF || c == CHAR_CR)
2204                   == (op == OP_NOTPROP))
2205              MRRETURN(MATCH_NOMATCH);
2206            break;
2207    
2208            case PT_PXSPACE:  /* POSIX space */
2209            if ((_pcre_ucp_gentype[prop->chartype] == ucp_Z ||
2210                 c == CHAR_HT || c == CHAR_NL || c == CHAR_VT ||
2211                 c == CHAR_FF || c == CHAR_CR)
2212                   == (op == OP_NOTPROP))
2213              MRRETURN(MATCH_NOMATCH);
2214            break;
2215    
2216            case PT_WORD:
2217            if ((_pcre_ucp_gentype[prop->chartype] == ucp_L ||
2218                 _pcre_ucp_gentype[prop->chartype] == ucp_N ||
2219                 c == CHAR_UNDERSCORE) == (op == OP_NOTPROP))
2220              MRRETURN(MATCH_NOMATCH);
2221          break;          break;
2222    
2223            /* This should never occur */
2224    
2225          default:          default:
2226          RRETURN(PCRE_ERROR_INTERNAL);          RRETURN(PCRE_ERROR_INTERNAL);
2227          }          }
# Line 1494  for (;;) Line 2234  for (;;)
2234      is in the binary; otherwise a compile-time error occurs. */      is in the binary; otherwise a compile-time error occurs. */
2235    
2236      case OP_EXTUNI:      case OP_EXTUNI:
2237      if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);      if (eptr >= md->end_subject)
2238          {
2239          SCHECK_PARTIAL();
2240          MRRETURN(MATCH_NOMATCH);
2241          }
2242      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
2243        {        {
2244        int chartype, script;        int category = UCD_CATEGORY(c);
2245        int category = _pcre_ucp_findprop(c, &chartype, &script);        if (category == ucp_M) MRRETURN(MATCH_NOMATCH);
       if (category == ucp_M) RRETURN(MATCH_NOMATCH);  
2246        while (eptr < md->end_subject)        while (eptr < md->end_subject)
2247          {          {
2248          int len = 1;          int len = 1;
# Line 1507  for (;;) Line 2250  for (;;)
2250            {            {
2251            GETCHARLEN(c, eptr, len);            GETCHARLEN(c, eptr, len);
2252            }            }
2253          category = _pcre_ucp_findprop(c, &chartype, &script);          category = UCD_CATEGORY(c);
2254          if (category != ucp_M) break;          if (category != ucp_M) break;
2255          eptr += len;          eptr += len;
2256          }          }
# Line 1526  for (;;) Line 2269  for (;;)
2269      loops). */      loops). */
2270    
2271      case OP_REF:      case OP_REF:
2272        {      offset = GET2(ecode, 1) << 1;               /* Doubled ref number */
2273        offset = GET2(ecode, 1) << 1;               /* Doubled ref number */      ecode += 3;
       ecode += 3;                                 /* Advance past item */  
2274    
2275        /* If the reference is unset, set the length to be longer than the amount      /* If the reference is unset, there are two possibilities:
       of subject left; this ensures that every attempt at a match fails. We  
       can't just fail here, because of the possibility of quantifiers with zero  
       minima. */  
   
       length = (offset >= offset_top || md->offset_vector[offset] < 0)?  
         md->end_subject - eptr + 1 :  
         md->offset_vector[offset+1] - md->offset_vector[offset];  
2276    
2277        /* Set up for repetition, or handle the non-repeated case */      (a) In the default, Perl-compatible state, set the length negative;
2278        this ensures that every attempt at a match fails. We can't just fail
2279        here, because of the possibility of quantifiers with zero minima.
2280    
2281        switch (*ecode)      (b) If the JavaScript compatibility flag is set, set the length to zero
2282          {      so that the back reference matches an empty string.
         case OP_CRSTAR:  
         case OP_CRMINSTAR:  
         case OP_CRPLUS:  
         case OP_CRMINPLUS:  
         case OP_CRQUERY:  
         case OP_CRMINQUERY:  
         c = *ecode++ - OP_CRSTAR;  
         minimize = (c & 1) != 0;  
         min = rep_min[c];                 /* Pick up values from tables; */  
         max = rep_max[c];                 /* zero for max => infinity */  
         if (max == 0) max = INT_MAX;  
         break;  
2283    
2284          case OP_CRRANGE:      Otherwise, set the length to the length of what was matched by the
2285          case OP_CRMINRANGE:      referenced subpattern. */
         minimize = (*ecode == OP_CRMINRANGE);  
         min = GET2(ecode, 1);  
         max = GET2(ecode, 3);  
         if (max == 0) max = INT_MAX;  
         ecode += 5;  
         break;  
2286    
2287          default:               /* No repeat follows */      if (offset >= offset_top || md->offset_vector[offset] < 0)
2288          if (!match_ref(offset, eptr, length, md, ims)) RRETURN(MATCH_NOMATCH);        length = (md->jscript_compat)? 0 : -1;
2289          eptr += length;      else
2290          continue;              /* With the main loop */        length = md->offset_vector[offset+1] - md->offset_vector[offset];
2291    
2292        /* Set up for repetition, or handle the non-repeated case */
2293    
2294        switch (*ecode)
2295          {
2296          case OP_CRSTAR:
2297          case OP_CRMINSTAR:
2298          case OP_CRPLUS:
2299          case OP_CRMINPLUS:
2300          case OP_CRQUERY:
2301          case OP_CRMINQUERY:
2302          c = *ecode++ - OP_CRSTAR;
2303          minimize = (c & 1) != 0;
2304          min = rep_min[c];                 /* Pick up values from tables; */
2305          max = rep_max[c];                 /* zero for max => infinity */
2306          if (max == 0) max = INT_MAX;
2307          break;
2308    
2309          case OP_CRRANGE:
2310          case OP_CRMINRANGE:
2311          minimize = (*ecode == OP_CRMINRANGE);
2312          min = GET2(ecode, 1);
2313          max = GET2(ecode, 3);
2314          if (max == 0) max = INT_MAX;
2315          ecode += 5;
2316          break;
2317    
2318          default:               /* No repeat follows */
2319          if ((length = match_ref(offset, eptr, length, md, ims)) < 0)
2320            {
2321            CHECK_PARTIAL();
2322            MRRETURN(MATCH_NOMATCH);
2323          }          }
2324          eptr += length;
2325          continue;              /* With the main loop */
2326          }
2327    
2328        /* If the length of the reference is zero, just continue with the      /* Handle repeated back references. If the length of the reference is
2329        main loop. */      zero, just continue with the main loop. */
2330    
2331        if (length == 0) continue;      if (length == 0) continue;
2332    
2333        /* First, ensure the minimum number of matches are present. We get back      /* First, ensure the minimum number of matches are present. We get back
2334        the length of the reference string explicitly rather than passing the      the length of the reference string explicitly rather than passing the
2335        address of eptr, so that eptr can be a register variable. */      address of eptr, so that eptr can be a register variable. */
2336    
2337        for (i = 1; i <= min; i++)      for (i = 1; i <= min; i++)
2338          {
2339          int slength;
2340          if ((slength = match_ref(offset, eptr, length, md, ims)) < 0)
2341          {          {
2342          if (!match_ref(offset, eptr, length, md, ims)) RRETURN(MATCH_NOMATCH);          CHECK_PARTIAL();
2343          eptr += length;          MRRETURN(MATCH_NOMATCH);
2344          }          }
2345          eptr += slength;
2346          }
2347    
2348        /* If min = max, continue at the same level without recursion.      /* If min = max, continue at the same level without recursion.
2349        They are not both allowed to be zero. */      They are not both allowed to be zero. */
2350    
2351        if (min == max) continue;      if (min == max) continue;
2352    
2353        /* If minimizing, keep trying and advancing the pointer */      /* If minimizing, keep trying and advancing the pointer */
2354    
2355        if (minimize)      if (minimize)
2356          {
2357          for (fi = min;; fi++)
2358          {          {
2359          for (fi = min;; fi++)          int slength;
2360            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM14);
2361            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2362            if (fi >= max) MRRETURN(MATCH_NOMATCH);
2363            if ((slength = match_ref(offset, eptr, length, md, ims)) < 0)
2364            {            {
2365            RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);            CHECK_PARTIAL();
2366            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            MRRETURN(MATCH_NOMATCH);
           if (fi >= max || !match_ref(offset, eptr, length, md, ims))  
             RRETURN(MATCH_NOMATCH);  
           eptr += length;  
2367            }            }
2368          /* Control never gets here */          eptr += slength;
2369          }          }
2370          /* Control never gets here */
2371          }
2372    
2373        /* If maximizing, find the longest string and work backwards */      /* If maximizing, find the longest string and work backwards */
2374    
2375        else      else
2376          {
2377          pp = eptr;
2378          for (i = min; i < max; i++)
2379          {          {
2380          pp = eptr;          int slength;
2381          for (i = min; i < max; i++)          if ((slength = match_ref(offset, eptr, length, md, ims)) < 0)
           {  
           if (!match_ref(offset, eptr, length, md, ims)) break;  
           eptr += length;  
           }  
         while (eptr >= pp)  
2382            {            {
2383            RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);            CHECK_PARTIAL();
2384            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            break;
           eptr -= length;  
2385            }            }
2386          RRETURN(MATCH_NOMATCH);          eptr += slength;
2387            }
2388          while (eptr >= pp)
2389            {
2390            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM15);
2391            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2392            eptr -= length;
2393          }          }
2394          MRRETURN(MATCH_NOMATCH);
2395        }        }
2396      /* Control never gets here */      /* Control never gets here */
2397    
   
   
2398      /* Match a bit-mapped character class, possibly repeatedly. This op code is      /* Match a bit-mapped character class, possibly repeatedly. This op code is
2399      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,
2400      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 1683  for (;;) Line 2449  for (;;)
2449          {          {
2450          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
2451            {            {
2452            if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);            if (eptr >= md->end_subject)
2453                {
2454                SCHECK_PARTIAL();
2455                MRRETURN(MATCH_NOMATCH);
2456                }
2457            GETCHARINC(c, eptr);            GETCHARINC(c, eptr);
2458            if (c > 255)            if (c > 255)
2459              {              {
2460              if (op == OP_CLASS) RRETURN(MATCH_NOMATCH);              if (op == OP_CLASS) MRRETURN(MATCH_NOMATCH);
2461              }              }
2462            else            else
2463              {              {
2464              if ((data[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);              if ((data[c/8] & (1 << (c&7))) == 0) MRRETURN(MATCH_NOMATCH);
2465              }              }
2466            }            }
2467          }          }
# Line 1701  for (;;) Line 2471  for (;;)
2471          {          {
2472          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
2473            {            {
2474            if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);            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    
# Line 1723  for (;;) Line 2497  for (;;)
2497            {            {
2498            for (fi = min;; fi++)            for (fi = min;; fi++)
2499              {              {
2500              RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM16);
2501              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2502              if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);              if (fi >= max) MRRETURN(MATCH_NOMATCH);
2503                if (eptr >= md->end_subject)
2504                  {
2505                  SCHECK_PARTIAL();
2506                  MRRETURN(MATCH_NOMATCH);
2507                  }
2508              GETCHARINC(c, eptr);              GETCHARINC(c, eptr);
2509              if (c > 255)              if (c > 255)
2510                {                {
2511                if (op == OP_CLASS) RRETURN(MATCH_NOMATCH);                if (op == OP_CLASS) MRRETURN(MATCH_NOMATCH);
2512                }                }
2513              else              else
2514                {                {
2515                if ((data[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);                if ((data[c/8] & (1 << (c&7))) == 0) MRRETURN(MATCH_NOMATCH);
2516                }                }
2517              }              }
2518            }            }
# Line 1743  for (;;) Line 2522  for (;;)
2522            {            {
2523            for (fi = min;; fi++)            for (fi = min;; fi++)
2524              {              {
2525              RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM17);
2526              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2527              if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);              if (fi >= max) MRRETURN(MATCH_NOMATCH);
2528                if (eptr >= md->end_subject)
2529                  {
2530                  SCHECK_PARTIAL();
2531                  MRRETURN(MATCH_NOMATCH);
2532                  }
2533              c = *eptr++;              c = *eptr++;
2534              if ((data[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);              if ((data[c/8] & (1 << (c&7))) == 0) MRRETURN(MATCH_NOMATCH);
2535              }              }
2536            }            }
2537          /* Control never gets here */          /* Control never gets here */
# Line 1766  for (;;) Line 2550  for (;;)
2550            for (i = min; i < max; i++)            for (i = min; i < max; i++)
2551              {              {
2552              int len = 1;              int len = 1;
2553              if (eptr >= md->end_subject) break;              if (eptr >= md->end_subject)
2554                  {
2555                  SCHECK_PARTIAL();
2556                  break;
2557                  }
2558              GETCHARLEN(c, eptr, len);              GETCHARLEN(c, eptr, len);
2559              if (c > 255)              if (c > 255)
2560                {                {
# Line 1780  for (;;) Line 2568  for (;;)
2568              }              }
2569            for (;;)            for (;;)
2570              {              {
2571              RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM18);
2572              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2573              if (eptr-- == pp) break;        /* Stop if tried at original pos */              if (eptr-- == pp) break;        /* Stop if tried at original pos */
2574              BACKCHAR(eptr);              BACKCHAR(eptr);
# Line 1792  for (;;) Line 2580  for (;;)
2580            {            {
2581            for (i = min; i < max; i++)            for (i = min; i < max; i++)
2582              {              {
2583              if (eptr >= md->end_subject) break;              if (eptr >= md->end_subject)
2584                  {
2585                  SCHECK_PARTIAL();
2586                  break;
2587                  }
2588              c = *eptr;              c = *eptr;
2589              if ((data[c/8] & (1 << (c&7))) == 0) break;              if ((data[c/8] & (1 << (c&7))) == 0) break;
2590              eptr++;              eptr++;
2591              }              }
2592            while (eptr >= pp)            while (eptr >= pp)
2593              {              {
2594              RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM19);
2595              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2596              eptr--;              eptr--;
2597              }              }
2598            }            }
2599    
2600          RRETURN(MATCH_NOMATCH);          MRRETURN(MATCH_NOMATCH);
2601          }          }
2602        }        }
2603      /* Control never gets here */      /* Control never gets here */
2604    
2605    
2606      /* Match an extended character class. This opcode is encountered only      /* Match an extended character class. This opcode is encountered only
2607      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
2608        mode, because Unicode properties are supported in non-UTF-8 mode. */
2609    
2610  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
2611      case OP_XCLASS:      case OP_XCLASS:
# Line 1853  for (;;) Line 2646  for (;;)
2646    
2647        for (i = 1; i <= min; i++)        for (i = 1; i <= min; i++)
2648          {          {
2649          if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);          if (eptr >= md->end_subject)
2650          GETCHARINC(c, eptr);            {
2651          if (!_pcre_xclass(c, data)) RRETURN(MATCH_NOMATCH);            SCHECK_PARTIAL();
2652              MRRETURN(MATCH_NOMATCH);
2653              }
2654            GETCHARINCTEST(c, eptr);
2655            if (!_pcre_xclass(c, data)) MRRETURN(MATCH_NOMATCH);
2656          }          }
2657    
2658        /* 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 1870  for (;;) Line 2667  for (;;)
2667          {          {
2668          for (fi = min;; fi++)          for (fi = min;; fi++)
2669            {            {
2670            RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM20);
2671            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2672            if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);            if (fi >= max) MRRETURN(MATCH_NOMATCH);
2673            GETCHARINC(c, eptr);            if (eptr >= md->end_subject)
2674            if (!_pcre_xclass(c, data)) RRETURN(MATCH_NOMATCH);              {
2675                SCHECK_PARTIAL();
2676                MRRETURN(MATCH_NOMATCH);
2677                }
2678              GETCHARINCTEST(c, eptr);
2679              if (!_pcre_xclass(c, data)) MRRETURN(MATCH_NOMATCH);
2680            }            }
2681          /* Control never gets here */          /* Control never gets here */
2682          }          }
# Line 1887  for (;;) Line 2689  for (;;)
2689          for (i = min; i < max; i++)          for (i = min; i < max; i++)
2690            {            {
2691            int len = 1;            int len = 1;
2692            if (eptr >= md->end_subject) break;            if (eptr >= md->end_subject)
2693            GETCHARLEN(c, eptr, len);              {
2694                SCHECK_PARTIAL();
2695                break;
2696                }
2697              GETCHARLENTEST(c, eptr, len);
2698            if (!_pcre_xclass(c, data)) break;            if (!_pcre_xclass(c, data)) break;
2699            eptr += len;            eptr += len;
2700            }            }
2701          for(;;)          for(;;)
2702            {            {
2703            RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM21);
2704            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2705            if (eptr-- == pp) break;        /* Stop if tried at original pos */            if (eptr-- == pp) break;        /* Stop if tried at original pos */
2706            BACKCHAR(eptr)            if (utf8) BACKCHAR(eptr);
2707            }            }
2708          RRETURN(MATCH_NOMATCH);          MRRETURN(MATCH_NOMATCH);
2709          }          }
2710    
2711        /* Control never gets here */        /* Control never gets here */
# Line 1915  for (;;) Line 2721  for (;;)
2721        length = 1;        length = 1;
2722        ecode++;        ecode++;
2723        GETCHARLEN(fc, ecode, length);        GETCHARLEN(fc, ecode, length);
2724        if (length > md->end_subject - eptr) RRETURN(MATCH_NOMATCH);        if (length > md->end_subject - eptr)
2725        while (length-- > 0) if (*ecode++ != *eptr++) RRETURN(MATCH_NOMATCH);          {
2726            CHECK_PARTIAL();             /* Not SCHECK_PARTIAL() */
2727            MRRETURN(MATCH_NOMATCH);
2728            }
2729          while (length-- > 0) if (*ecode++ != *eptr++) MRRETURN(MATCH_NOMATCH);
2730        }        }
2731      else      else
2732  #endif  #endif
2733    
2734      /* Non-UTF-8 mode */      /* Non-UTF-8 mode */
2735        {        {
2736        if (md->end_subject - eptr < 1) RRETURN(MATCH_NOMATCH);        if (md->end_subject - eptr < 1)
2737        if (ecode[1] != *eptr++) RRETURN(MATCH_NOMATCH);          {
2738            SCHECK_PARTIAL();            /* This one can use SCHECK_PARTIAL() */
2739            MRRETURN(MATCH_NOMATCH);
2740            }
2741          if (ecode[1] != *eptr++) MRRETURN(MATCH_NOMATCH);
2742        ecode += 2;        ecode += 2;
2743        }        }
2744      break;      break;
# Line 1939  for (;;) Line 2753  for (;;)
2753        ecode++;        ecode++;
2754        GETCHARLEN(fc, ecode, length);        GETCHARLEN(fc, ecode, length);
2755    
2756        if (length > md->end_subject - eptr) RRETURN(MATCH_NOMATCH);        if (length > md->end_subject - eptr)
2757            {
2758            CHECK_PARTIAL();             /* Not SCHECK_PARTIAL() */
2759            MRRETURN(MATCH_NOMATCH);
2760            }
2761    
2762        /* 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
2763        can use the fast lookup table. */        can use the fast lookup table. */
2764    
2765        if (fc < 128)        if (fc < 128)
2766          {          {
2767          if (md->lcc[*ecode++] != md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH);          if (md->lcc[*ecode++] != md->lcc[*eptr++]) MRRETURN(MATCH_NOMATCH);
2768          }          }
2769    
2770        /* Otherwise we must pick up the subject character */        /* Otherwise we must pick up the subject character */
# Line 1963  for (;;) Line 2781  for (;;)
2781          if (fc != dc)          if (fc != dc)
2782            {            {
2783  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2784            if (dc != _pcre_ucp_othercase(fc))            if (dc != UCD_OTHERCASE(fc))
2785  #endif  #endif
2786              RRETURN(MATCH_NOMATCH);              MRRETURN(MATCH_NOMATCH);
2787            }            }
2788          }          }
2789        }        }
# Line 1974  for (;;) Line 2792  for (;;)
2792    
2793      /* Non-UTF-8 mode */      /* Non-UTF-8 mode */
2794        {        {
2795        if (md->end_subject - eptr < 1) RRETURN(MATCH_NOMATCH);        if (md->end_subject - eptr < 1)
2796        if (md->lcc[ecode[1]] != md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH);          {
2797            SCHECK_PARTIAL();            /* This one can use SCHECK_PARTIAL() */
2798            MRRETURN(MATCH_NOMATCH);
2799            }
2800          if (md->lcc[ecode[1]] != md->lcc[*eptr++]) MRRETURN(MATCH_NOMATCH);
2801        ecode += 2;        ecode += 2;
2802        }        }
2803      break;      break;
# Line 2028  for (;;) Line 2850  for (;;)
2850      case OP_MINQUERY:      case OP_MINQUERY:
2851      c = *ecode++ - OP_STAR;      c = *ecode++ - OP_STAR;
2852      minimize = (c & 1) != 0;      minimize = (c & 1) != 0;
2853    
2854      min = rep_min[c];                 /* Pick up values from tables; */      min = rep_min[c];                 /* Pick up values from tables; */
2855      max = rep_max[c];                 /* zero for max => infinity */      max = rep_max[c];                 /* zero for max => infinity */
2856      if (max == 0) max = INT_MAX;      if (max == 0) max = INT_MAX;
2857    
2858      /* 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. */  
2859    
2860      REPEATCHAR:      REPEATCHAR:
2861  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF8
# Line 2043  for (;;) Line 2864  for (;;)
2864        length = 1;        length = 1;
2865        charptr = ecode;        charptr = ecode;
2866        GETCHARLEN(fc, ecode, length);        GETCHARLEN(fc, ecode, length);
       if (min * length > md->end_subject - eptr) RRETURN(MATCH_NOMATCH);  
2867        ecode += length;        ecode += length;
2868    
2869        /* Handle multibyte character matching specially here. There is        /* Handle multibyte character matching specially here. There is
# Line 2054  for (;;) Line 2874  for (;;)
2874  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2875          unsigned int othercase;          unsigned int othercase;
2876          if ((ims & PCRE_CASELESS) != 0 &&          if ((ims & PCRE_CASELESS) != 0 &&
2877              (othercase = _pcre_ucp_othercase(fc)) != NOTACHAR)              (othercase = UCD_OTHERCASE(fc)) != fc)
2878            oclength = _pcre_ord2utf8(othercase, occhars);            oclength = _pcre_ord2utf8(othercase, occhars);
2879          else oclength = 0;          else oclength = 0;
2880  #endif  /* SUPPORT_UCP */  #endif  /* SUPPORT_UCP */
2881    
2882          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
2883            {            {
2884            if (memcmp(eptr, charptr, length) == 0) eptr += length;            if (eptr <= md->end_subject - length &&
2885                memcmp(eptr, charptr, length) == 0) eptr += length;
2886  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2887            /* Need braces because of following else */            else if (oclength > 0 &&
2888            else if (oclength == 0) { RRETURN(MATCH_NOMATCH); }                     eptr <= md->end_subject - oclength &&
2889                       memcmp(eptr, occhars, oclength) == 0) eptr += oclength;
2890    #endif  /* SUPPORT_UCP */
2891            else            else
2892              {              {
2893              if (memcmp(eptr, occhars, oclength) != 0) RRETURN(MATCH_NOMATCH);              CHECK_PARTIAL();
2894              eptr += oclength;              MRRETURN(MATCH_NOMATCH);
2895              }              }
 #else   /* without SUPPORT_UCP */  
           else { RRETURN(MATCH_NOMATCH); }  
 #endif  /* SUPPORT_UCP */  
2896            }            }
2897    
2898          if (min == max) continue;          if (min == max) continue;
# Line 2081  for (;;) Line 2901  for (;;)
2901            {            {
2902            for (fi = min;; fi++)            for (fi = min;; fi++)
2903              {              {
2904              RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM22);
2905              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2906              if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);              if (fi >= max) MRRETURN(MATCH_NOMATCH);
2907              if (memcmp(eptr, charptr, length) == 0) eptr += length;              if (eptr <= md->end_subject - length &&
2908                  memcmp(eptr, charptr, length) == 0) eptr += length;
2909  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2910              /* Need braces because of following else */              else if (oclength > 0 &&
2911              else if (oclength == 0) { RRETURN(MATCH_NOMATCH); }                       eptr <= md->end_subject - oclength &&
2912                         memcmp(eptr, occhars, oclength) == 0) eptr += oclength;
2913    #endif  /* SUPPORT_UCP */
2914              else              else
2915                {                {
2916                if (memcmp(eptr, occhars, oclength) != 0) RRETURN(MATCH_NOMATCH);                CHECK_PARTIAL();
2917                eptr += oclength;                MRRETURN(MATCH_NOMATCH);
2918                }                }
 #else   /* without SUPPORT_UCP */  
             else { RRETURN (MATCH_NOMATCH); }  
 #endif  /* SUPPORT_UCP */  
2919              }              }
2920            /* Control never gets here */            /* Control never gets here */
2921            }            }
# Line 2105  for (;;) Line 2925  for (;;)
2925            pp = eptr;            pp = eptr;
2926            for (i = min; i < max; i++)            for (i = min; i < max; i++)
2927              {              {
2928              if (eptr > md->end_subject - length) break;              if (eptr <= md->end_subject - length &&
2929              if (memcmp(eptr, charptr, length) == 0) eptr += length;                  memcmp(eptr, charptr, length) == 0) eptr += length;
2930  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2931              else if (oclength == 0) break;              else if (oclength > 0 &&
2932                         eptr <= md->end_subject - oclength &&
2933                         memcmp(eptr, occhars, oclength) == 0) eptr += oclength;
2934    #endif  /* SUPPORT_UCP */
2935              else              else
2936                {                {
2937                if (memcmp(eptr, occhars, oclength) != 0) break;                CHECK_PARTIAL();
2938                eptr += oclength;                break;
2939                }                }
 #else   /* without SUPPORT_UCP */  
             else break;  
 #endif  /* SUPPORT_UCP */  
2940              }              }
2941    
2942            if (possessive) continue;            if (possessive) continue;
2943    
2944            for(;;)            for(;;)
2945             {              {
2946             RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM23);
2947             if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
2948             if (eptr == pp) RRETURN(MATCH_NOMATCH);              if (eptr == pp) { MRRETURN(MATCH_NOMATCH); }
2949  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2950             eptr--;              eptr--;
2951             BACKCHAR(eptr);              BACKCHAR(eptr);
2952  #else   /* without SUPPORT_UCP */  #else   /* without SUPPORT_UCP */
2953             eptr -= length;              eptr -= length;
2954  #endif  /* SUPPORT_UCP */  #endif  /* SUPPORT_UCP */
2955             }              }
2956            }            }
2957          /* Control never gets here */          /* Control never gets here */
2958          }          }
# Line 2144  for (;;) Line 2965  for (;;)
2965  #endif  /* SUPPORT_UTF8 */  #endif  /* SUPPORT_UTF8 */
2966    
2967      /* When not in UTF-8 mode, load a single-byte character. */      /* When not in UTF-8 mode, load a single-byte character. */
2968        {  
2969        if (min > md->end_subject - eptr) RRETURN(MATCH_NOMATCH);      fc = *ecode++;
       fc = *ecode++;  
       }  
2970    
2971      /* 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
2972      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 2165  for (;;) Line 2984  for (;;)
2984        {        {
2985        fc = md->lcc[fc];        fc = md->lcc[fc];
2986        for (i = 1; i <= min; i++)        for (i = 1; i <= min; i++)
2987          if (fc != md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH);          {
2988            if (eptr >= md->end_subject)
2989              {
2990              SCHECK_PARTIAL();
2991              MRRETURN(MATCH_NOMATCH);
2992              }
2993            if (fc != md->lcc[*eptr++]) MRRETURN(MATCH_NOMATCH);
2994            }
2995        if (min == max) continue;        if (min == max) continue;
2996        if (minimize)        if (minimize)
2997          {          {
2998          for (fi = min;; fi++)          for (fi = min;; fi++)
2999            {            {
3000            RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM24);
3001            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3002            if (fi >= max || eptr >= md->end_subject ||            if (fi >= max) MRRETURN(MATCH_NOMATCH);
3003                fc != md->lcc[*eptr++])            if (eptr >= md->end_subject)
3004              RRETURN(MATCH_NOMATCH);              {
3005                SCHECK_PARTIAL();
3006                MRRETURN(MATCH_NOMATCH);
3007                }
3008              if (fc != md->lcc[*eptr++]) MRRETURN(MATCH_NOMATCH);
3009            }            }
3010          /* Control never gets here */          /* Control never gets here */
3011          }          }
# Line 2184  for (;;) Line 3014  for (;;)
3014          pp = eptr;          pp = eptr;
3015          for (i = min; i < max; i++)          for (i = min; i < max; i++)
3016            {            {
3017            if (eptr >= md->end_subject || fc != md->lcc[*eptr]) break;            if (eptr >= md->end_subject)
3018                {
3019                SCHECK_PARTIAL();
3020                break;
3021                }
3022              if (fc != md->lcc[*eptr]) break;
3023            eptr++;            eptr++;
3024            }            }
3025    
3026          if (possessive) continue;          if (possessive) continue;
3027    
3028          while (eptr >= pp)          while (eptr >= pp)
3029            {            {
3030            RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM25);
3031            eptr--;            eptr--;
3032            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3033            }            }
3034          RRETURN(MATCH_NOMATCH);          MRRETURN(MATCH_NOMATCH);
3035          }          }
3036        /* Control never gets here */        /* Control never gets here */
3037        }        }
# Line 2203  for (;;) Line 3040  for (;;)
3040    
3041      else      else
3042        {        {
3043        for (i = 1; i <= min; i++) if (fc != *eptr++) RRETURN(MATCH_NOMATCH);        for (i = 1; i <= min; i++)
3044            {
3045            if (eptr >= md->end_subject)
3046              {
3047              SCHECK_PARTIAL();
3048              MRRETURN(MATCH_NOMATCH);
3049              }
3050            if (fc != *eptr++) MRRETURN(MATCH_NOMATCH);
3051            }
3052    
3053        if (min == max) continue;        if (min == max) continue;
3054    
3055        if (minimize)        if (minimize)
3056          {          {
3057          for (fi = min;; fi++)          for (fi = min;; fi++)
3058            {            {
3059            RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM26);
3060            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3061            if (fi >= max || eptr >= md->end_subject || fc != *eptr++)            if (fi >= max) MRRETURN(MATCH_NOMATCH);
3062              RRETURN(MATCH_NOMATCH);            if (eptr >= md->end_subject)
3063                {
3064                SCHECK_PARTIAL();
3065                MRRETURN(MATCH_NOMATCH);
3066                }
3067              if (fc != *eptr++) MRRETURN(MATCH_NOMATCH);
3068            }            }
3069          /* Control never gets here */          /* Control never gets here */
3070          }          }
# Line 2221  for (;;) Line 3073  for (;;)
3073          pp = eptr;          pp = eptr;
3074          for (i = min; i < max; i++)          for (i = min; i < max; i++)
3075            {            {
3076            if (eptr >= md->end_subject || fc != *eptr) break;            if (eptr >= md->end_subject)
3077                {
3078                SCHECK_PARTIAL();
3079                break;
3080                }
3081              if (fc != *eptr) break;
3082            eptr++;            eptr++;
3083            }            }
3084          if (possessive) continue;          if (possessive) continue;
3085    
3086          while (eptr >= pp)          while (eptr >= pp)
3087            {            {
3088            RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM27);
3089            eptr--;            eptr--;
3090            if (rrc != MATCH_NOMATCH) RRETURN(rrc);            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3091            }            }
3092          RRETURN(MATCH_NOMATCH);          MRRETURN(MATCH_NOMATCH);
3093          }          }
3094        }        }
3095      /* Control never gets here */      /* Control never gets here */
# Line 2240  for (;;) Line 3098  for (;;)
3098      checking can be multibyte. */      checking can be multibyte. */
3099    
3100      case OP_NOT:      case OP_NOT:
3101      if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);      if (eptr >= md->end_subject)
3102          {
3103          SCHECK_PARTIAL();
3104          MRRETURN(MATCH_NOMATCH);
3105          }
3106      ecode++;      ecode++;
3107      GETCHARINCTEST(c, eptr);      GETCHARINCTEST(c, eptr);
3108      if ((ims & PCRE_CASELESS) != 0)      if ((ims & PCRE_CASELESS) != 0)
# Line 2249  for (;;) Line 3111  for (;;)
3111        if (c < 256)        if (c < 256)
3112  #endif  #endif
3113        c = md->lcc[c];        c = md->lcc[c];
3114        if (md->lcc[*ecode++] == c) RRETURN(MATCH_NOMATCH);        if (md->lcc[*ecode++] == c) MRRETURN(MATCH_NOMATCH);
3115        }        }
3116      else      else
3117        {        {
3118        if (*ecode++ == c) RRETURN(MATCH_NOMATCH);        if (*ecode++ == c) MRRETURN(MATCH_NOMATCH);
3119        }        }
3120      break;      break;
3121    
# Line 2317  for (;;) Line 3179  for (;;)
3179      max = rep_max[c];                 /* zero for max => infinity */      max = rep_max[c];                 /* zero for max => infinity */
3180      if (max == 0) max = INT_MAX;      if (max == 0) max = INT_MAX;
3181    
3182      /* 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. */  
3183    
3184      REPEATNOTCHAR:      REPEATNOTCHAR:
     if (min > md->end_subject - eptr) RRETURN(MATCH_NOMATCH);  
3185      fc = *ecode++;      fc = *ecode++;
3186    
3187      /* 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 2347  for (;;) Line 3206  for (;;)
3206          register unsigned int d;          register unsigned int d;
3207          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3208            {            {
3209              if (eptr >= md->end_subject)
3210                {
3211                SCHECK_PARTIAL();
3212                MRRETURN(MATCH_NOMATCH);
3213                }
3214            GETCHARINC(d, eptr);            GETCHARINC(d, eptr);
3215            if (d < 256) d = md->lcc[d];            if (d < 256) d = md->lcc[d];
3216            if (fc == d) RRETURN(MATCH_NOMATCH);            if (fc == d) MRRETURN(MATCH_NOMATCH);
3217            }            }
3218          }          }
3219        else        else
# Line 2358  for (;;) Line 3222  for (;;)
3222        /* Not UTF-8 mode */        /* Not UTF-8 mode */
3223          {          {
3224          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3225            if (fc == md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH);            {
3226              if (eptr >= md->end_subject)
3227                {
3228                SCHECK_PARTIAL();
3229                MRRETURN(MATCH_NOMATCH);
3230                }
3231              if (fc == md->lcc[*eptr++]) MRRETURN(MATCH_NOMATCH);
3232              }
3233          }          }
3234    
3235        if (min == max) continue;        if (min == max) continue;
# Line 2372  for (;;) Line 3243  for (;;)
3243            register unsigned int d;            register unsigned int d;
3244            for (fi = min;; fi++)            for (fi = min;; fi++)
3245              {              {
3246              RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM28);
3247              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3248                if (fi >= max) MRRETURN(MATCH_NOMATCH);
3249                if (eptr >= md->end_subject)
3250                  {
3251                  SCHECK_PARTIAL();
3252                  MRRETURN(MATCH_NOMATCH);
3253                  }
3254              GETCHARINC(d, eptr);              GETCHARINC(d, eptr);
3255              if (d < 256) d = md->lcc[d];              if (d < 256) d = md->lcc[d];
3256              if (fi >= max || eptr >= md->end_subject || fc == d)              if (fc == d) MRRETURN(MATCH_NOMATCH);
               RRETURN(MATCH_NOMATCH);  
3257              }              }
3258            }            }
3259          else          else
# Line 2386  for (;;) Line 3262  for (;;)
3262            {            {
3263            for (fi = min;; fi++)            for (fi = min;; fi++)
3264              {              {
3265              RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM29);
3266              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3267              if (fi >= max || eptr >= md->end_subject || fc == md->lcc[*eptr++])              if (fi >= max) MRRETURN(MATCH_NOMATCH);
3268                RRETURN(MATCH_NOMATCH);              if (eptr >= md->end_subject)
3269                  {
3270                  SCHECK_PARTIAL();
3271                  MRRETURN(MATCH_NOMATCH);
3272                  }
3273                if (fc == md->lcc[*eptr++]) MRRETURN(MATCH_NOMATCH);
3274              }              }
3275            }            }
3276          /* Control never gets here */          /* Control never gets here */
# Line 2409  for (;;) Line 3290  for (;;)
3290            for (i = min; i < max; i++)            for (i = min; i < max; i++)
3291              {              {
3292              int len = 1;              int len = 1;
3293              if (eptr >= md->end_subject) break;              if (eptr >= md->end_subject)
3294                  {
3295                  SCHECK_PARTIAL();
3296                  break;
3297                  }
3298              GETCHARLEN(d, eptr, len);              GETCHARLEN(d, eptr, len);
3299              if (d < 256) d = md->lcc[d];              if (d < 256) d = md->lcc[d];
3300              if (fc == d) break;              if (fc == d) break;
# Line 2418  for (;;) Line 3303  for (;;)
3303          if (possessive) continue;          if (possessive) continue;
3304          for(;;)          for(;;)
3305              {              {
3306              RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM30);
3307              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3308              if (eptr-- == pp) break;        /* Stop if tried at original pos */              if (eptr-- == pp) break;        /* Stop if tried at original pos */
3309              BACKCHAR(eptr);              BACKCHAR(eptr);
# Line 2430  for (;;) Line 3315  for (;;)
3315            {            {
3316            for (i = min; i < max; i++)            for (i = min; i < max; i++)
3317              {              {
3318              if (eptr >= md->end_subject || fc == md->lcc[*eptr]) break;              if (eptr >= md->end_subject)
3319                  {
3320                  SCHECK_PARTIAL();
3321                  break;
3322                  }
3323                if (fc == md->lcc[*eptr]) break;
3324              eptr++;              eptr++;
3325              }              }
3326            if (possessive) continue;            if (possessive) continue;
3327            while (eptr >= pp)            while (eptr >= pp)
3328              {              {
3329              RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM31);
3330              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3331              eptr--;              eptr--;
3332              }              }
3333            }            }
3334    
3335          RRETURN(MATCH_NOMATCH);          MRRETURN(MATCH_NOMATCH);
3336          }          }
3337        /* Control never gets here */        /* Control never gets here */
3338        }        }
# Line 2458  for (;;) Line 3348  for (;;)
3348          register unsigned int d;          register unsigned int d;
3349          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3350            {            {
3351              if (eptr >= md->end_subject)
3352                {
3353                SCHECK_PARTIAL();
3354                MRRETURN(MATCH_NOMATCH);
3355                }
3356            GETCHARINC(d, eptr);            GETCHARINC(d, eptr);
3357            if (fc == d) RRETURN(MATCH_NOMATCH);            if (fc == d) MRRETURN(MATCH_NOMATCH);
3358            }            }
3359          }          }
3360        else        else
# Line 2467  for (;;) Line 3362  for (;;)
3362        /* Not UTF-8 mode */        /* Not UTF-8 mode */
3363          {          {
3364          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3365            if (fc == *eptr++) RRETURN(MATCH_NOMATCH);            {
3366              if (eptr >= md->end_subject)
3367                {
3368                SCHECK_PARTIAL();
3369                MRRETURN(MATCH_NOMATCH);
3370                }
3371              if (fc == *eptr++) MRRETURN(MATCH_NOMATCH);
3372              }
3373          }          }
3374    
3375        if (min == max) continue;        if (min == max) continue;
# Line 2481  for (;;) Line 3383  for (;;)
3383            register unsigned int d;            register unsigned int d;
3384            for (fi = min;; fi++)            for (fi = min;; fi++)
3385              {              {
3386              RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM32);
3387              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3388                if (fi >= max) MRRETURN(MATCH_NOMATCH);
3389                if (eptr >= md->end_subject)
3390                  {
3391                  SCHECK_PARTIAL();
3392                  MRRETURN(MATCH_NOMATCH);
3393                  }
3394              GETCHARINC(d, eptr);              GETCHARINC(d, eptr);
3395              if (fi >= max || eptr >= md->end_subject || fc == d)              if (fc == d) MRRETURN(MATCH_NOMATCH);
               RRETURN(MATCH_NOMATCH);  
3396              }              }
3397            }            }
3398          else          else
# Line 2494  for (;;) Line 3401  for (;;)
3401            {            {
3402            for (fi = min;; fi++)            for (fi = min;; fi++)
3403              {              {
3404              RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM33);
3405              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3406              if (fi >= max || eptr >= md->end_subject || fc == *eptr++)              if (fi >= max) MRRETURN(MATCH_NOMATCH);
3407                RRETURN(MATCH_NOMATCH);              if (eptr >= md->end_subject)
3408                  {
3409                  SCHECK_PARTIAL();
3410                  MRRETURN(MATCH_NOMATCH);
3411                  }
3412                if (fc == *eptr++) MRRETURN(MATCH_NOMATCH);
3413              }              }
3414            }            }
3415          /* Control never gets here */          /* Control never gets here */
# Line 2517  for (;;) Line 3429  for (;;)
3429            for (i = min; i < max; i++)            for (i = min; i < max; i++)
3430              {              {
3431              int len = 1;              int len = 1;
3432              if (eptr >= md->end_subject) break;              if (eptr >= md->end_subject)
3433                  {
3434                  SCHECK_PARTIAL();
3435                  break;
3436                  }
3437              GETCHARLEN(d, eptr, len);              GETCHARLEN(d, eptr, len);
3438              if (fc == d) break;              if (fc == d) break;
3439              eptr += len;              eptr += len;
# Line 2525  for (;;) Line 3441  for (;;)
3441            if (possessive) continue;            if (possessive) continue;
3442            for(;;)            for(;;)
3443              {              {
3444              RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM34);
3445              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3446              if (eptr-- == pp) break;        /* Stop if tried at original pos */              if (eptr-- == pp) break;        /* Stop if tried at original pos */
3447              BACKCHAR(eptr);              BACKCHAR(eptr);
# Line 2537  for (;;) Line 3453  for (;;)
3453            {            {
3454            for (i = min; i < max; i++)            for (i = min; i < max; i++)
3455              {              {
3456              if (eptr >= md->end_subject || fc == *eptr) break;              if (eptr >= md->end_subject)
3457                  {
3458                  SCHECK_PARTIAL();
3459                  break;
3460                  }
3461                if (fc == *eptr) break;
3462              eptr++;              eptr++;
3463              }              }
3464            if (possessive) continue;            if (possessive) continue;
3465            while (eptr >= pp)            while (eptr >= pp)
3466              {              {
3467              RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0);              RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM35);
3468              if (rrc != MATCH_NOMATCH) RRETURN(rrc);              if (rrc != MATCH_NOMATCH) RRETURN(rrc);
3469              eptr--;              eptr--;
3470              }              }
3471            }            }
3472    
3473          RRETURN(MATCH_NOMATCH);          MRRETURN(MATCH_NOMATCH);
3474          }          }
3475        }        }
3476      /* Control never gets here */      /* Control never gets here */
# Line 2631  for (;;) Line 3552  for (;;)
3552    
3553      /* First, ensure the minimum number of matches are present. Use inline      /* First, ensure the minimum number of matches are present. Use inline
3554      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
3555      (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  
3556      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
3557      and single-bytes. */      and single-bytes. */
3558    
     if (min > md->end_subject - eptr) RRETURN(MATCH_NOMATCH);  
3559      if (min > 0)      if (min > 0)
3560        {        {
3561  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
# Line 2646  for (;;) Line 3564  for (;;)
3564          switch(prop_type)          switch(prop_type)
3565            {            {
3566            case PT_ANY:            case PT_ANY:
3567            if (prop_fail_result) RRETURN(MATCH_NOMATCH);            if (prop_fail_result) MRRETURN(MATCH_NOMATCH);
3568            for (i = 1; i <= min; i++)            for (i = 1; i <= min; i++)
3569              {              {
3570              if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);              if (eptr >= md->end_subject)
3571              GETCHARINC(c, eptr);                {
3572                  SCHECK_PARTIAL();
3573                  MRRETURN(MATCH_NOMATCH);
3574                  }
3575                GETCHARINCTEST(c, eptr);
3576              }              }
3577            break;            break;
3578    
3579            case PT_LAMP:            case PT_LAMP:
3580            for (i = 1; i <= min; i++)            for (i = 1; i <= min; i++)
3581              {              {
3582              if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);              if (eptr >= md->end_subject)
3583              GETCHARINC(c, eptr);                {
3584              prop_category = _pcre_ucp_findprop(c, &prop_chartype, &prop_script);                SCHECK_PARTIAL();
3585                  MRRETURN(MATCH_NOMATCH);
3586                  }
3587                GETCHARINCTEST(c, eptr);
3588                prop_chartype = UCD_CHARTYPE(c);
3589              if ((prop_chartype == ucp_Lu ||              if ((prop_chartype == ucp_Lu ||
3590                   prop_chartype == ucp_Ll ||                   prop_chartype == ucp_Ll ||
3591                   prop_chartype == ucp_Lt) == prop_fail_result)                   prop_chartype == ucp_Lt) == prop_fail_result)
3592                RRETURN(MATCH_NOMATCH);                MRRETURN(MATCH_NOMATCH);
3593              }              }
3594            break;            break;
3595    
3596            case PT_GC:            case PT_GC:
3597            for (i = 1; i <= min; i++)            for (i = 1; i <= min; i++)
3598              {              {
3599              if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);              if (eptr >= md->end_subject)
3600              GETCHARINC(c, eptr);                {
3601              prop_category = _pcre_ucp_findprop(c, &prop_chartype, &prop_script);                SCHECK_PARTIAL();
3602                  MRRETURN(MATCH_NOMATCH);
3603                  }
3604                GETCHARINCTEST(c, eptr);
3605                prop_category = UCD_CATEGORY(c);
3606              if ((prop_category == prop_value) == prop_fail_result)              if ((prop_category == prop_value) == prop_fail_result)
3607                RRETURN(MATCH_NOMATCH);                MRRETURN(MATCH_NOMATCH);
3608              }              }
3609            break;            break;
3610    
3611            case PT_PC:            case PT_PC:
3612            for (i = 1; i <= min; i++)            for (i = 1; i <= min; i++)
3613              {              {
3614              if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);              if (eptr >= md->end_subject)
3615              GETCHARINC(c, eptr);                {
3616              prop_category = _pcre_ucp_findprop(c, &prop_chartype, &prop_script);                SCHECK_PARTIAL();
3617                  MRRETURN(MATCH_NOMATCH);
3618                  }
3619                GETCHARINCTEST(c, eptr);
3620                prop_chartype = UCD_CHARTYPE(c);
3621              if ((prop_chartype == prop_value) == prop_fail_result)              if ((prop_chartype == prop_value) == prop_fail_result)
3622                RRETURN(MATCH_NOMATCH);                MRRETURN(MATCH_NOMATCH);
3623              }              }
3624            break;            break;
3625    
3626            case PT_SC:            case PT_SC:
3627            for (i = 1; i <= min; i++)            for (i = 1; i <= min; i++)
3628              {              {
3629              if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);              if (eptr >= md->end_subject)
3630              GETCHARINC(c, eptr);                {
3631              prop_category = _pcre_ucp_findprop(c, &prop_chartype, &prop_script);                SCHECK_PARTIAL();
3632                  MRRETURN(MATCH_NOMATCH);
3633                  }
3634                GETCHARINCTEST(c, eptr);
3635                prop_script = UCD_SCRIPT(c);
3636              if ((prop_script == prop_value) == prop_fail_result)              if ((prop_script == prop_value) == prop_fail_result)
3637                RRETURN(MATCH_NOMATCH);                MRRETURN(MATCH_NOMATCH);
3638              }              }
3639            break;            break;
3640    
3641            default:            case PT_ALNUM:
3642            RRETURN(PCRE_ERROR_INTERNAL);            for (i = 1; i <= min; i++)
3643            }              {
3644          }              if (eptr >= md->end_subject)
3645                  {
3646        /* Match extended Unicode sequences. We will get here only if the                SCHECK_PARTIAL();
3647                  MRRETURN(MATCH_NOMATCH);
3648                  }
3649                GETCHARINCTEST(c, eptr);
3650                prop_category = UCD_CATEGORY(c);
3651                if ((prop_category == ucp_L || prop_category == ucp_N)
3652                       == prop_fail_result)
3653                  MRRETURN(MATCH_NOMATCH);
3654                }
3655              break;
3656    
3657              case PT_SPACE:    /* Perl space */
3658              for (i = 1; i <= min; i++)
3659                {
3660                if (eptr >= md->end_subject)
3661                  {
3662                  SCHECK_PARTIAL();
3663                  MRRETURN(MATCH_NOMATCH);
3664                  }
3665                GETCHARINCTEST(c, eptr);
3666                prop_category = UCD_CATEGORY(c);
3667                if ((prop_category == ucp_Z || c == CHAR_HT || c == CHAR_NL ||
3668                     c == CHAR_FF || c == CHAR_CR)
3669                       == prop_fail_result)
3670                  MRRETURN(MATCH_NOMATCH);
3671                }
3672              break;
3673    
3674              case PT_PXSPACE:  /* POSIX space */
3675              for (i = 1; i <= min; i++)
3676                {
3677                if (eptr >= md->end_subject)
3678                  {
3679                  SCHECK_PARTIAL();
3680                  MRRETURN(MATCH_NOMATCH);
3681                  }
3682                GETCHARINCTEST(c, eptr);
3683                prop_category = UCD_CATEGORY(c);
3684                if ((prop_category == ucp_Z || c == CHAR_HT || c == CHAR_NL ||
3685                     c == CHAR_VT || c == CHAR_FF || c == CHAR_CR)
3686                       == prop_fail_result)
3687                  MRRETURN(MATCH_NOMATCH);
3688                }
3689              break;
3690    
3691              case PT_WORD:
3692              for (i = 1; i <= min; i++)
3693                {
3694                if (eptr >= md->end_subject)
3695                  {
3696                  SCHECK_PARTIAL();
3697                  MRRETURN(MATCH_NOMATCH);
3698                  }
3699                GETCHARINCTEST(c, eptr);
3700                prop_category = UCD_CATEGORY(c);
3701                if ((prop_category == ucp_L || prop_category == ucp_N ||
3702                     c == CHAR_UNDERSCORE)
3703                       == prop_fail_result)
3704                  MRRETURN(MATCH_NOMATCH);
3705                }
3706              break;
3707    
3708              /* This should not occur */
3709    
3710              default:
3711              RRETURN(PCRE_ERROR_INTERNAL);
3712              }
3713            }
3714    
3715          /* Match extended Unicode sequences. We will get here only if the
3716        support is in the binary; otherwise a compile-time error occurs. */        support is in the binary; otherwise a compile-time error occurs. */
3717    
3718        else if (ctype == OP_EXTUNI)        else if (ctype == OP_EXTUNI)
3719          {          {
3720          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3721            {            {
3722              if (eptr >= md->end_subject)
3723                {
3724                SCHECK_PARTIAL();
3725                MRRETURN(MATCH_NOMATCH);
3726                }
3727            GETCHARINCTEST(c, eptr);            GETCHARINCTEST(c, eptr);
3728            prop_category = _pcre_ucp_findprop(c, &prop_chartype, &prop_script);            prop_category = UCD_CATEGORY(c);
3729            if (prop_category == ucp_M) RRETURN(MATCH_NOMATCH);            if (prop_category == ucp_M) MRRETURN(MATCH_NOMATCH);
3730            while (eptr < md->end_subject)            while (eptr < md->end_subject)
3731              {              {
3732              int len = 1;              int len = 1;
3733              if (!utf8) c = *eptr; else              if (!utf8) c = *eptr;
3734                {                else { GETCHARLEN(c, eptr, len); }
3735                GETCHARLEN(c, eptr, len);              prop_category = UCD_CATEGORY(c);
               }  
             prop_category = _pcre_ucp_findprop(c, &prop_chartype, &prop_script);  
3736              if (prop_category != ucp_M) break;              if (prop_category != ucp_M) break;
3737              eptr += len;              eptr += len;
3738              }              }
# Line 2740  for (;;) Line 3750  for (;;)
3750          case OP_ANY:          case OP_ANY:
3751          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3752            {            {
3753            if (eptr >= md->end_subject ||            if (eptr >= md->end_subject)
3754                 ((ims & PCRE_DOTALL) == 0 && IS_NEWLINE(eptr)))              {
3755              RRETURN(MATCH_NOMATCH);              SCHECK_PARTIAL();
3756                MRRETURN(MATCH_NOMATCH);
3757                }
3758              if (IS_NEWLINE(eptr)) MRRETURN(MATCH_NOMATCH);
3759              eptr++;
3760              while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;
3761              }
3762            break;
3763    
3764            case OP_ALLANY:
3765            for (i = 1; i <= min; i++)
3766              {
3767              if (eptr >= md->end_subject)
3768                {
3769                SCHECK_PARTIAL();
3770                MRRETURN(MATCH_NOMATCH);
3771                }
3772            eptr++;            eptr++;
3773            while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;            while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;
3774            }            }
3775          break;          break;
3776    
3777          case OP_ANYBYTE:          case OP_ANYBYTE:
3778            if (eptr > md->end_subject - min) MRRETURN(MATCH_NOMATCH);
3779          eptr += min;          eptr += min;
3780          break;          break;
3781    
3782          case OP_ANYNL:          case OP_ANYNL:
3783          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3784            {            {
3785            if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);            if (eptr >= md->end_subject)
3786                {
3787                SCHECK_PARTIAL();
3788                MRRETURN(MATCH_NOMATCH);
3789                }
3790            GETCHARINC(c, eptr);            GETCHARINC(c, eptr);
3791            switch(c)            switch(c)
3792              {              {
3793              default: RRETURN(MATCH_NOMATCH);              default: MRRETURN(MATCH_NOMATCH);
3794              case 0x000d:              case 0x000d:
3795              if (eptr < md->end_subject && *eptr == 0x0a) eptr++;              if (eptr < md->end_subject && *eptr == 0x0a) eptr++;
3796              break;              break;
3797    
3798              case 0x000a:              case 0x000a:
3799                break;
3800    
3801              case 0x000b:              case 0x000b:
3802              case 0x000c:              case 0x000c:
3803              case 0x0085:              case 0x0085:
3804              case 0x2028:              case 0x2028:
3805              case 0x2029:              case 0x2029:
3806                if (md->bsr_anycrlf) MRRETURN(MATCH_NOMATCH);
3807                break;
3808                }
3809              }
3810            break;
3811    
3812            case OP_NOT_HSPACE:
3813            for (i = 1; i <= min; i++)
3814              {
3815              if (eptr >= md->end_subject)
3816                {
3817                SCHECK_PARTIAL();
3818                MRRETURN(MATCH_NOMATCH);
3819                }
3820              GETCHARINC(c, eptr);
3821              switch(c)
3822                {
3823                default: break;
3824                case 0x09:      /* HT */
3825                case 0x20:      /* SPACE */
3826                case 0xa0:      /* NBSP */
3827                case 0x1680:    /* OGHAM SPACE MARK */
3828                case 0x180e:    /* MONGOLIAN VOWEL SEPARATOR */
3829                case 0x2000:    /* EN QUAD */
3830                case 0x2001:    /* EM QUAD */
3831                case 0x2002:    /* EN SPACE */
3832                case 0x2003:    /* EM SPACE */
3833                case 0x2004:    /* THREE-PER-EM SPACE */
3834                case 0x2005:    /* FOUR-PER-EM SPACE */
3835                case 0x2006:    /* SIX-PER-EM SPACE */
3836                case 0x2007:    /* FIGURE SPACE */
3837                case 0x2008:    /* PUNCTUATION SPACE */
3838                case 0x2009:    /* THIN SPACE */
3839                case 0x200A:    /* HAIR SPACE */
3840                case 0x202f:    /* NARROW NO-BREAK SPACE */
3841                case 0x205f:    /* MEDIUM MATHEMATICAL SPACE */
3842                case 0x3000:    /* IDEOGRAPHIC SPACE */
3843                MRRETURN(MATCH_NOMATCH);
3844                }
3845              }
3846            break;
3847    
3848            case OP_HSPACE:
3849            for (i = 1; i <= min; i++)
3850              {
3851              if (eptr >= md->end_subject)
3852                {
3853                SCHECK_PARTIAL();
3854                MRRETURN(MATCH_NOMATCH);
3855                }
3856              GETCHARINC(c, eptr);
3857              switch(c)
3858                {
3859                default: MRRETURN(MATCH_NOMATCH);
3860                case 0x09:      /* HT */
3861                case 0x20:      /* SPACE */
3862                case 0xa0:      /* NBSP */
3863                case 0x1680:    /* OGHAM SPACE MARK */
3864                case 0x180e:    /* MONGOLIAN VOWEL SEPARATOR */
3865                case 0x2000:    /* EN QUAD */
3866                case 0x2001:    /* EM QUAD */
3867                case 0x2002:    /* EN SPACE */
3868                case 0x2003:    /* EM SPACE */
3869                case 0x2004:    /* THREE-PER-EM SPACE */
3870                case 0x2005:    /* FOUR-PER-EM SPACE */
3871                case 0x2006:    /* SIX-PER-EM SPACE */
3872                case 0x2007:    /* FIGURE SPACE */
3873                case 0x2008:    /* PUNCTUATION SPACE */
3874                case 0x2009:    /* THIN SPACE */
3875                case 0x200A:    /* HAIR SPACE */
3876                case 0x202f:    /* NARROW NO-BREAK SPACE */
3877                case 0x205f:    /* MEDIUM MATHEMATICAL SPACE */
3878                case 0x3000:    /* IDEOGRAPHIC SPACE */
3879                break;
3880                }
3881              }
3882            break;
3883    
3884            case OP_NOT_VSPACE:
3885            for (i = 1; i <= min; i++)
3886              {
3887              if (eptr >= md->end_subject)
3888                {
3889                SCHECK_PARTIAL();
3890                MRRETURN(MATCH_NOMATCH);
3891                }
3892              GETCHARINC(c, eptr);
3893              switch(c)
3894                {
3895                default: break;
3896                case 0x0a:      /* LF */
3897                case 0x0b:      /* VT */
3898                case 0x0c:      /* FF */
3899                case 0x0d:      /* CR */
3900                case 0x85:      /* NEL */
3901                case 0x2028:    /* LINE SEPARATOR */
3902                case 0x2029:    /* PARAGRAPH SEPARATOR */
3903                MRRETURN(MATCH_NOMATCH);
3904                }
3905              }
3906            break;
3907    
3908            case OP_VSPACE:
3909            for (i = 1; i <= min; i++)
3910              {
3911              if (eptr >= md->end_subject)
3912                {
3913                SCHECK_PARTIAL();
3914                MRRETURN(MATCH_NOMATCH);
3915                }
3916              GETCHARINC(c, eptr);
3917              switch(c)
3918                {
3919                default: MRRETURN(MATCH_NOMATCH);
3920                case 0x0a:      /* LF */
3921                case 0x0b:      /* VT */
3922                case 0x0c:      /* FF */
3923                case 0x0d:      /* CR */
3924                case 0x85:      /* NEL */
3925                case 0x2028:    /* LINE SEPARATOR */
3926                case 0x2029:    /* PARAGRAPH SEPARATOR */
3927              break;              break;
3928              }              }
3929            }            }
# Line 2777  for (;;) Line 3932  for (;;)
3932          case OP_NOT_DIGIT:          case OP_NOT_DIGIT:
3933          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3934            {            {
3935            if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH);            if (eptr >= md->end_subject)
3936                {
3937                SCHECK_PARTIAL();
3938                MRRETURN(MATCH_NOMATCH);
3939                }
3940            GETCHARINC(c, eptr);            GETCHARINC(c, eptr);
3941            if (c < 128 && (md->ctypes[c] & ctype_digit) != 0)            if (c < 128 && (md->ctypes[c] & ctype_digit) != 0)
3942              RRETURN(MATCH_NOMATCH);              MRRETURN(MATCH_NOMATCH);
3943            }            }
3944          break;          break;
3945    
3946          case OP_DIGIT:          case OP_DIGIT:
3947          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3948            {            {
3949            if (eptr >= md->end_subject ||            if (eptr >= md->end_subject)
3950               *eptr >= 128 || (md->ctypes[*eptr++] & ctype_digit) == 0)              {
3951              RRETURN(MATCH_NOMATCH);              SCHECK_PARTIAL();
3952                MRRETURN(MATCH_NOMATCH);
3953                }
3954              if (*eptr >= 128 || (md->ctypes[*eptr++] & ctype_digit) == 0)
3955                MRRETURN(MATCH_NOMATCH);
3956            /* 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 */
3957            }            }
3958          break;          break;
# Line 2797  for (;;) Line 3960  for (;;)
3960          case OP_NOT_WHITESPACE:          case OP_NOT_WHITESPACE:
3961          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3962            {            {
3963            if (eptr >= md->end_subject ||            if (eptr >= md->end_subject)
3964               (*eptr < 128 && (md->ctypes[*eptr++] & ctype_space) != 0))              {
3965              RRETURN(MATCH_NOMATCH);              SCHECK_PARTIAL();
3966            while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;              MRRETURN(MATCH_NOMATCH);
3967                }
3968              if (*eptr < 128 && (md->ctypes[*eptr] & ctype_space) != 0)
3969                MRRETURN(MATCH_NOMATCH);
3970              while (++eptr < md->end_subject && (*eptr & 0xc0) == 0x80);
3971            }            }
3972          break;          break;
3973    
3974          case OP_WHITESPACE:          case OP_WHITESPACE:
3975          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3976            {            {
3977            if (eptr >= md->end_subject ||            if (eptr >= md->end_subject)
3978               *eptr >= 128 || (md->ctypes[*eptr++] & ctype_space) == 0)              {
3979              RRETURN(MATCH_NOMATCH);              SCHECK_PARTIAL();
3980                MRRETURN(MATCH_NOMATCH);
3981                }
3982              if (*eptr >= 128 || (md->ctypes[*eptr++] & ctype_space) == 0)
3983                MRRETURN(MATCH_NOMATCH);
3984            /* 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 */
3985            }            }
3986          break;          break;
# Line 2817  for (;;) Line 3988  for (;;)
3988          case OP_NOT_WORDCHAR:          case OP_NOT_WORDCHAR:
3989          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
3990            {            {
3991            if (eptr >= md->end_subject ||            if (eptr >= md->end_subject)
3992               (*eptr < 128 && (md->ctypes[*eptr++] & ctype_word) != 0))              {
3993              RRETURN(MATCH_NOMATCH);              SCHECK_PARTIAL();
3994            while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;              MRRETURN(MATCH_NOMATCH);
3995                }
3996              if (*eptr < 128 && (md->ctypes[*eptr] & ctype_word) != 0)
3997                MRRETURN(MATCH_NOMATCH);
3998              while (++eptr < md->end_subject && (*eptr & 0xc0) == 0x80);
3999            }            }
4000          break;          break;
4001    
4002          case OP_WORDCHAR:          case OP_WORDCHAR:
4003          for (i = 1; i <= min; i++)          for (i = 1; i <= min; i++)
4004            {            {
4005            if (eptr >= md->end_subject ||            if (eptr >= md->end_subject)
4006               *eptr >= 128 || (md->ctypes[*eptr++] & ctype_word) == 0)              {
4007              RRETURN(MATCH_NOMATCH);              SCHECK_PARTIAL();
4008                MRRETURN(MATCH_NOMATCH);
4009                }
4010              if (*eptr >= 128 || (md->ctypes[*eptr++] & ctype_word) == 0)
4011                MRRETURN(MATCH_NOMATCH);
4012            /* 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 */
4013            }            }
4014          break;          break;
# Line 2842  for (;;) Line 4021  for (;;)
4021  #endif     /* SUPPORT_UTF8 */  #endif     /* SUPPORT_UTF8 */
4022    
4023        /* 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
4024        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. */  
4025    
4026        switch(ctype)        switch(ctype)
4027          {          {
4028          case OP_ANY:          case OP_ANY:
4029          if ((ims & PCRE_DOTALL) == 0)          for (i = 1; i <= min; i++)
4030            {            {
4031            for (i = 1; i <= min; i++)            if (eptr >= md->end_subject)
4032              {              {
4033              if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH);              SCHECK_PARTIAL();
4034              eptr++;              MRRETURN(MATCH_NOMATCH);
4035              }              }
4036              if (IS_NEWLINE(eptr)) MRRETURN(MATCH_NOMATCH);
4037              eptr++;
4038            }            }
         else eptr += min;  
4039          break;          break;
4040