If $s in
open my $fh, "<", \$s
or similar is a ref, then
stringify that ref: i.e. convert it from a ref into the string
"SCALAR(0x....)" or whatever.
This fixes
RT #119529 Filehandle opened from ref to ref hangs on reading
which in this case was looping forever, since it kept thinking that
the var was a string ("SCALAR.."), but whose length was 0.
I haven't gone for a complete "always force var into a string" approach,
since PerlIO::scalar has quite a tolerance for "bad" vars; e.g.
it won't warn if $var is undef or a read-only constant number etc;
and it already normalises under some circumstances and not others.
So I've just increased the cases somewhat where it normalises.
Also, I didn't look to closely at the code that was looping (or to put it
another way, I looked at it but didn't understand it), so it could
conceivably still behave badly on some other strange type of variable that
manages to avoid getting normalised.
package PerlIO::scalar;
-our $VERSION = '0.16';
+our $VERSION = '0.17';
require XSLoader;
XSLoader::load();
1;
else {
s->var = newSVpvn("", 0);
}
- SvUPGRADE(s->var, SVt_PV);
+ if (SvROK(s->var))
+ /* force refs, overload etc to be plain strings */
+ (void)SvPV_force_nomg_nolen(s->var);
+ else
+ SvUPGRADE(s->var, SVt_PV);
+
code = PerlIOBase_pushed(aTHX_ f, mode, Nullsv, tab);
if (!SvOK(s->var) || (PerlIOBase(f)->flags) & PERLIO_F_TRUNCATE)
{
$| = 1;
-use Test::More tests => 108;
+use Test::More tests => 109;
my $fh;
my $var = "aaa\n";
ok(!(print $fh "B"), "write to an non-downgradable SV (and warn)");
is_deeply(\@warnings, [ $byte_warning ], "check warning");
}
+
+# RT #119529: non-string should be forced into a string
+
+{
+ my $x = \42;
+ open my $fh, "<", \$x;
+ my $got = <$fh>; # this used to loop
+ like($got, qr/^SCALAR\(0x[0-9a-f]+\)$/, "ref to a ref");
+}