Make open(... "<&", $fileno) respect magic
authorFather Chrysostomos <sprout@cpan.org>
Fri, 25 May 2012 06:13:37 +0000 (23:13 -0700)
committerFather Chrysostomos <sprout@cpan.org>
Thu, 7 Jun 2012 15:18:52 +0000 (08:18 -0700)
A magical variable is never SvPOK, but only SvPOKp.  The code for
checking whether a duplicatee is a numeric file descriptor was only
checking SvPOK.  So a regular variable containing a fileno-as-a-string
would work, such as the $a below, as would a stringified magical vari-
able ("$1"), but not $1 itself.

$ echo foo | perl -le '$a = "0"; open a, "<&", $a; warn <a>'
foo
$ echo foo | perl -le '"0" =~ /(.)/; open a, "<&", $1; warn <a>'
Can't use an undefined value as filehandle reference at -e line 1.
$ echo foo | perl -le '"0" =~ /(.)/; open a, "<&", "$1"; warn <a>'
foo

SvPOK variables are also SvPOKp, so checking only the latter suffices.

doio.c
t/io/open.t

diff --git a/doio.c b/doio.c
index 69d091c..fed1a49 100644 (file)
--- a/doio.c
+++ b/doio.c
@@ -320,7 +320,10 @@ Perl_do_openn(pTHX_ GV *gv, register const char *oname, I32 len, int as_raw,
                    }
                    while (isSPACE(*type))
                        type++;
-                   if (num_svs && (SvIOK(*svp) || (SvPOK(*svp) && looks_like_number(*svp)))) {
+                   if (num_svs && (
+                            SvIOK(*svp)
+                         || (SvPOKp(*svp) && looks_like_number(*svp))
+                      )) {
                        fd = SvUV(*svp);
                        num_svs = 0;
                    }
index 696ba98..e06fc8e 100644 (file)
@@ -10,7 +10,7 @@ $|  = 1;
 use warnings;
 use Config;
 
-plan tests => 120;
+plan tests => 121;
 
 my $Perl = which_perl();
 
@@ -233,6 +233,10 @@ like( $@, qr/Bad filehandle:\s+$afile/,          '       right error' );
 
     # used to try to open a file [perl #17830]
     ok( open(my $stdin,  "<&", fileno STDIN),   'dup fileno(STDIN) into lexical fh') or _diag $!;
+
+    fileno(STDIN) =~ /(.)/;
+    ok open($stdin, "<&", $1), 'open ... "<&", $magical_fileno',
+       ||  _diag $!;
 }
 
 SKIP: {