summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFather Chrysostomos <sprout@cpan.org>2014-01-04 06:05:41 -0800
committerFather Chrysostomos <sprout@cpan.org>2014-01-04 06:06:03 -0800
commit901ee108fe1f8070e4722d8313bf202d0eb843b0 (patch)
tree01871bec19b77e5310c10592d7a76fc35895a84e
parenta76c354d5bbd0beffab91da21869cc5a9ef5ee30 (diff)
downloadperl-901ee108fe1f8070e4722d8313bf202d0eb843b0.tar.gz
[perl #120657] Fix require PADTMP when @INC=(sub{},sub{})
It was passing a freed scalar to subsequent subs, breaking Test::Without::Module: sub fake_module { my (undef,$module_file) = @_; !1 } unshift @INC, (\&fake_module)x2; require "${\'whatever'}"; __END__ panic: attempt to copy freed scalar 7fe8d0829820 to 7fe8d082a0f0 at - line 3. Obviously, doing: SAVETMPS; ... nsv = sv_newmortal(); ... FREETMPS; # free all tmps created since SAVETMPS inside a loop that only assigns to nsv the first time through will cause nsv to point to a freed scalar on subsequent iterations. It was stupid of me to make that mistake in commit 9ffd39a to begin with. The extra file name SV here will simply have to last until the require call finishes, something I was trying to avoid by putting it after SAVETMPS.
-rw-r--r--pp_ctl.c5
-rw-r--r--t/op/inccode.t16
2 files changed, 18 insertions, 3 deletions
diff --git a/pp_ctl.c b/pp_ctl.c
index c8c67736b0..7236921455 100644
--- a/pp_ctl.c
+++ b/pp_ctl.c
@@ -3833,12 +3833,13 @@ PP(pp_require)
tryname = SvPVX_const(namesv);
tryrsfp = NULL;
- ENTER_with_name("call_INC");
- SAVETMPS;
if (SvPADTMP(nsv)) {
nsv = sv_newmortal();
SvSetSV_nosteal(nsv,sv);
}
+
+ ENTER_with_name("call_INC");
+ SAVETMPS;
EXTEND(SP, 2);
PUSHMARK(SP);
diff --git a/t/op/inccode.t b/t/op/inccode.t
index b00959c67c..0712956f3e 100644
--- a/t/op/inccode.t
+++ b/t/op/inccode.t
@@ -21,7 +21,7 @@ unless (is_miniperl()) {
use strict;
-plan(tests => 61 + !is_miniperl() * (3 + 14 * $can_fork));
+plan(tests => 62 + !is_miniperl() * (3 + 14 * $can_fork));
sub get_temp_fh {
my $f = tempfile();
@@ -267,6 +267,20 @@ is $_||$@, "are temps freed prematurely?",
"are temps freed prematurely when returned from inc filters?";
shift @INC;
+# [perl #120657]
+sub fake_module {
+ my (undef,$module_file) = @_;
+ !1
+}
+{
+ local @INC = @INC;
+ unshift @INC, (\&fake_module)x2;
+ eval { require "${\'bralbalhablah'}" };
+ like $@, qr/^Can't locate/,
+ 'require PADTMP passing freed var when @INC has multiple subs';
+}
+
+
exit if is_miniperl();
SKIP: {