Skip to content

Commit 99fc7ec

Browse files
author
Father Chrysostomos
committed
Make rv2gv return autovivified magic GVs
There is special code in pp_rv2gv to deal with the case of built-in variables that are created on the fly. It basically pretends that they have always existed, even in rvalue context. Normally, defined(*{"foo"}) will not actually create the *foo glob, but will simply return false. defined(*{">"}), however is supposed to return true because of the $> variable; its popping into existing when looked at being an implementation detail. That is the whole pur- pose of is_gv_magical_sv in gv.c. Prior to this commit, however, defined(*{">"}) would autovivify the GV, but then return *false*! It was simply a matter of faulty logic in this part of pp_rv2gv: SV * const temp = MUTABLE_SV(gv_fetchsv(sv, 0, SVt_PVGV)); if (!temp && (!is_gv_magical_sv(sv,0) || !(sv = MUTABLE_SV(gv_fetchsv(sv, GV_ADD, SVt_PVGV))))) { RETSETUNDEF; } sv = temp; The autovivification happens in the second gv_fetchsv call. But after the new GV is assigned to sv and the condition proves false, we reach the sv = temp assignment which clobbers it.
1 parent f8326b3 commit 99fc7ec

File tree

2 files changed

+6
-2
lines changed

2 files changed

+6
-2
lines changed

pp.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,7 @@ PP(pp_rv2gv)
207207
SVt_PVGV))))) {
208208
RETSETUNDEF;
209209
}
210-
sv = temp;
210+
if (temp) sv = temp;
211211
}
212212
else {
213213
if (PL_op->op_private & HINT_STRICT_REFS)

t/op/readdir.t

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,12 @@ isnt("$fh", "$fh{abc}");
5959

6060
# See that perl does not segfault upon readdir($x=".");
6161
# http://rt.perl.org/rt3/Ticket/Display.html?id=68182
62+
# This test has subsequently changed to use "x", because *. now always
63+
# returns a glob (because of the $. variable), even in the non-vivifying
64+
# context supplied by readdir (which implies *{}). "x" triggers the same
65+
# conditions under which the segfault originally occurred.
6266
fresh_perl_like(<<'EOP', qr/^Bad symbol for dirhandle at -/, {}, 'RT #68182');
63-
my $x = ".";
67+
my $x = "x";
6468
my @files = readdir($x);
6569
EOP
6670

0 commit comments

Comments
 (0)