diff --git a/perlio.c b/perlio.c index 8d0ee5c23a45..5df638b058cd 100644 --- a/perlio.c +++ b/perlio.c @@ -1265,14 +1265,14 @@ PerlIOScalar_write(pTHX_ PerlIO * f, const void *vbuf, Size_t count) SETERRNO(EINVAL, SS_IVCHAN); return 0; } + /* Avoid calling SvCUR() on undef'ed SVs */ + STRLEN const cur = SvOK(sv) ? SvCUR(sv) : 0; if ((PerlIOBase(f)->flags) & PERLIO_F_APPEND) { - dst = SvGROW(sv, SvCUR(sv) + count + 1); + dst = SvGROW(sv, cur + count + 1); offset = SvCUR(sv); s->posn = offset + count; } else { - STRLEN const cur = SvCUR(sv); - /* ensure we don't try to create ridiculously large * SVs on small platforms */ diff --git a/pod/perldelta.pod b/pod/perldelta.pod index 412acc5b0134..fb62a2613447 100644 --- a/pod/perldelta.pod +++ b/pod/perldelta.pod @@ -374,6 +374,12 @@ used to be parsed incorrectly. =item * +When a scalar variable used as the target of a filehandle is C'ed +while being output, garbage bytes would be left in that scalar. +[L] + +=item * + XXX =back diff --git a/t/io/scalar.t b/t/io/scalar.t index ca854b44c245..01fe7595b034 100644 --- a/t/io/scalar.t +++ b/t/io/scalar.t @@ -12,7 +12,7 @@ use strict; use Fcntl qw(SEEK_SET SEEK_CUR SEEK_END); # Not 0, 1, 2 everywhere. use Errno qw(EACCES); -plan(128); +plan(129); my $fh; my $var = "aaa\n"; @@ -528,3 +528,11 @@ SKIP: select((select($fh), ++$|)[0]); ok(!(print $fh "x"), "write to a large offset"); } + +{ # GH #24008 + open my $fh, '>', \my $str or die $!; + print $fh "xxxxx"; + undef $str; + print $fh "y"; + is($str, "\0\0\0\0\0y", "write to undef'ed variable"); +}