diff options
author | ph10 <ph10@2f5784b3-3f2a-0410-8824-cb99058d5e15> | 2013-07-26 10:03:38 +0000 |
---|---|---|
committer | ph10 <ph10@2f5784b3-3f2a-0410-8824-cb99058d5e15> | 2013-07-26 10:03:38 +0000 |
commit | b4cde2376078d389f45388c5f974b6777838940b (patch) | |
tree | f0e57c8142fa8d926a18929967792e321fca7e7f /pcre_exec.c | |
parent | e83f730e5000d138a5763db37fbde6fd128db2e2 (diff) | |
download | pcre-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.c | 36 |
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; } } } |