summaryrefslogtreecommitdiff
path: root/regexp.h
diff options
context:
space:
mode:
authorDavid Mitchell <davem@iabyn.com>2013-07-16 16:31:04 +0100
committerDavid Mitchell <davem@iabyn.com>2013-07-28 10:33:39 +0100
commitd5e7783a3e8dcf16e8d64aae0d77eed33dc12a5c (patch)
tree90eae92d4e416b5f4abf9a1e7bcd9e4f2ddf2db1 /regexp.h
parentfeb38e3b9dba8f9f75fe6c737d7c4d99ff1aca46 (diff)
downloadperl-d5e7783a3e8dcf16e8d64aae0d77eed33dc12a5c.tar.gz
s/.(?=.\G)/X/g: refuse to go backwards
On something like: $_ = "123456789"; pos = 6; s/.(?=.\G)/X/g; each iteration could in theory start with pos one character to the left of the previous position, and with the substitution replacing bits that it has already replaced. Since that way madness lies, ban any attempt by s/// to substitute to the left of a previous position. To implement this, add a new flag to regexec(), REXEC_FAIL_ON_UNDERFLOW. This tells regexec() to return failure even if the match itself succeeded, but where the start of $& is before the passed stringarg point. This change caused one existing test to fail (which was added about a year ago): $_="abcdef"; s/bc|(.)\G(.)/$1 ? "[$1-$2]" : "XX"/ge; print; # used to print "aXX[c-d][d-e][e-f]"; now prints "aXXdef" I think that that test relies on ambiguous behaviour, and that my change makes things saner. Note that s/// with \G is generally very under-tested.
Diffstat (limited to 'regexp.h')
-rw-r--r--regexp.h3
1 files changed, 3 insertions, 0 deletions
diff --git a/regexp.h b/regexp.h
index 5fb85ec684..65c2d38517 100644
--- a/regexp.h
+++ b/regexp.h
@@ -547,6 +547,9 @@ get_regex_charset_name(const U32 flags, STRLEN* const lenp)
* to skip copying ... */
#define REXEC_COPY_SKIP_PRE 0x20 /* ...the $` part of the string, or */
#define REXEC_COPY_SKIP_POST 0x40 /* ...the $' part of the string */
+#define REXEC_FAIL_ON_UNDERFLOW 0x80 /* fail the match if $& would start before
+ the start pos (so s/.\G// would fail
+ on second iteration */
#if defined(__GNUC__) && !defined(PERL_GCC_BRACE_GROUPS_FORBIDDEN)
# define ReREFCNT_inc(re) \