This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
[perl #77094] Stop printf +() from reading past SP
authorFather Chrysostomos <sprout@cpan.org>
Mon, 24 Sep 2012 23:08:07 +0000 (16:08 -0700)
committerFather Chrysostomos <sprout@cpan.org>
Mon, 24 Sep 2012 23:08:07 +0000 (16:08 -0700)
printf with an empty list was reading past the end of the stack and
using whatever it found as its format.  If given an empty list, it
should treat the format as "".

pp_sys.c
t/io/print.t

index a41c6d1..68510f8 100644 (file)
--- a/pp_sys.c
+++ b/pp_sys.c
@@ -1521,6 +1521,9 @@ PP(pp_prtf)
        = (PL_op->op_flags & OPf_STACKED) ? MUTABLE_GV(*++MARK) : PL_defoutgv;
     IO *const io = GvIO(gv);
 
        = (PL_op->op_flags & OPf_STACKED) ? MUTABLE_GV(*++MARK) : PL_defoutgv;
     IO *const io = GvIO(gv);
 
+    /* Treat empty list as "" */
+    if (MARK == SP) XPUSHs(&PL_sv_no);
+
     if (io) {
        const MAGIC * const mg = SvTIED_mg((const SV *)io, PERL_MAGIC_tiedscalar);
        if (mg) {
     if (io) {
        const MAGIC * const mg = SvTIED_mg((const SV *)io, PERL_MAGIC_tiedscalar);
        if (mg) {
index 00ee7fb..4336090 100644 (file)
@@ -10,7 +10,7 @@ BEGIN {
 
 use strict 'vars';
 
 
 use strict 'vars';
 
-print "1..23\n";
+print "1..24\n";
 
 my $foo = 'STDOUT';
 print $foo "ok 1\n";
 
 my $foo = 'STDOUT';
 print $foo "ok 1\n";
@@ -71,3 +71,8 @@ if (!exists &Errno::EBADF) {
 my $n = "abc";
 printf "ok 22%n - not really a test; just printing\n", substr $n,1,1;
 print "not " x ($n ne "a5c") . "ok 23 - printf with %n (got $n)\n";
 my $n = "abc";
 printf "ok 22%n - not really a test; just printing\n", substr $n,1,1;
 print "not " x ($n ne "a5c") . "ok 23 - printf with %n (got $n)\n";
+
+# [perl #77094] printf with empty list
+() = ("not ");
+printf +();
+print "ok 24 - printf +() does not steal stack items\n";