summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHugo van der Sanden <hv@crypt.org>2015-02-17 03:27:33 +0000
committerHugo van der Sanden <hv@crypt.org>2015-02-18 01:40:44 +0000
commite92b41c6ac6bcd8786b0448c8337c4151e4f9a63 (patch)
tree6c7b0e81f99418fd7d027fed6e3379a897abc169
parent04ffdf6a81289d4734cb56d4feeba6e14d1c7f8e (diff)
downloadperl-e92b41c6ac6bcd8786b0448c8337c4151e4f9a63.tar.gz
[perl #123852] avoid capture side-effects under noncapture flag
//n was implemented by avoiding the primary side-effects of compiling a capture when the flag was turned on; however some secondary effects still occurred later in the same function, by using the value of the 'paren' variable - even as far as causing coredumps. Setting paren to ':' when NOCAPTURE is enabled makes the rest of the function act just as if it had parsed (?:...) instead of (...).
-rw-r--r--regcomp.c2
-rw-r--r--t/re/pat.t12
2 files changed, 13 insertions, 1 deletions
diff --git a/regcomp.c b/regcomp.c
index 51c778d044..68f6bfdc43 100644
--- a/regcomp.c
+++ b/regcomp.c
@@ -10450,6 +10450,8 @@ S_reg(pTHX_ RExC_state_t *pRExC_state, I32 paren, I32 *flagp,U32 depth)
Set_Node_Offset(ret, RExC_parse); /* MJD */
is_open = 1;
} else {
+ /* with RXf_PMf_NOCAPTURE treat (...) as (?:...) */
+ paren = ':';
ret = NULL;
}
}
diff --git a/t/re/pat.t b/t/re/pat.t
index 137a049489..5dad5ef470 100644
--- a/t/re/pat.t
+++ b/t/re/pat.t
@@ -22,7 +22,7 @@ BEGIN {
skip_all_without_unicode_tables();
}
-plan tests => 772; # Update this when adding/deleting tests.
+plan tests => 774; # Update this when adding/deleting tests.
run_tests() unless caller;
@@ -1684,6 +1684,16 @@ EOP
ok(1, "compiled GOSUB in CURLYM ok");
is($match, 'xxyxxyx', "matched GOSUB in CURLYM");
}
+
+ {
+ # [perl #123852] doesn't avoid all the capture-related work with
+ # //n, leading to possible memory corruption
+ eval q{ qr{()(?1)}n };
+ my $error = $@;
+ ok(1, "qr{()(?1)}n didn't crash");
+ like($error, qr{Reference to nonexistent group},
+ 'gave appropriate error for qr{()(?1)}n');
+ }
} # End of sub run_tests
1;