summaryrefslogtreecommitdiff
path: root/pcre_exec.c
diff options
context:
space:
mode:
authorph10 <ph10@2f5784b3-3f2a-0410-8824-cb99058d5e15>2013-07-26 10:03:38 +0000
committerph10 <ph10@2f5784b3-3f2a-0410-8824-cb99058d5e15>2013-07-26 10:03:38 +0000
commitb4cde2376078d389f45388c5f974b6777838940b (patch)
treef0e57c8142fa8d926a18929967792e321fca7e7f /pcre_exec.c
parente83f730e5000d138a5763db37fbde6fd128db2e2 (diff)
downloadpcre-b4cde2376078d389f45388c5f974b6777838940b.tar.gz
Fix backup bugs with \X repeat matches.
git-svn-id: svn://vcs.exim.org/pcre/code/trunk@1350 2f5784b3-3f2a-0410-8824-cb99058d5e15
Diffstat (limited to 'pcre_exec.c')
-rw-r--r--pcre_exec.c36
1 files changed, 28 insertions, 8 deletions
diff --git a/pcre_exec.c b/pcre_exec.c
index cf4d466..c5d0566 100644
--- a/pcre_exec.c
+++ b/pcre_exec.c
@@ -5637,7 +5637,7 @@ for (;;)
}
}
- /* Match extended Unicode sequences. We will get here only if the
+ /* Match extended Unicode grapheme clusters. We will get here only if the
support is in the binary; otherwise a compile-time error occurs. */
else if (ctype == OP_EXTUNI)
@@ -5670,21 +5670,41 @@ for (;;)
/* eptr is now past the end of the maximum run */
if (possessive) continue; /* No backtracking */
+
for(;;)
{
- if (eptr == pp) goto TAIL_RECURSE;
+ int lgb, rgb;
+ PCRE_PUCHAR fptr;
+
+ if (eptr == pp) goto TAIL_RECURSE; /* At start of char run */
RMATCH(eptr, ecode, offset_top, md, eptrb, RM45);
if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+
+ /* Backtracking over an extended grapheme cluster involves inspecting
+ the previous two characters (if present) to see if a break is
+ permitted between them. */
+
eptr--;
- for (;;) /* Move back over one extended */
+ if (!utf) c = *eptr; else
{
- if (!utf) c = *eptr; else
+ BACKCHAR(eptr);
+ GETCHAR(c, eptr);
+ }
+ rgb = UCD_GRAPHBREAK(c);
+
+ for (;;)
+ {
+ if (eptr == pp) goto TAIL_RECURSE; /* At start of char run */
+ fptr = eptr - 1;
+ if (!utf) c = *fptr; else
{
- BACKCHAR(eptr);
- GETCHAR(c, eptr);
+ BACKCHAR(fptr);
+ GETCHAR(c, fptr);
}
- if (UCD_CATEGORY(c) != ucp_M) break;
- eptr--;
+ lgb = UCD_GRAPHBREAK(c);
+ if ((PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0) break;
+ eptr = fptr;
+ rgb = lgb;
}
}
}