This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
[perl #128182] Fix crash with require $nonstring
authorFather Chrysostomos <sprout@cpan.org>
Thu, 19 May 2016 01:07:37 +0000 (18:07 -0700)
committerFather Chrysostomos <sprout@cpan.org>
Thu, 19 May 2016 03:13:57 +0000 (20:13 -0700)
If something other than a plain string (e.g. a reference or typeglob)
whose stringified form contains a null character is passed to require()
or do(), it crashes, as of v5.19.3-130-gc8028aa, because the code in
question that handles the error tries to read fields of the scalar
that are only valid if it is a string internally.

pp_ctl.c
t/op/require_errors.t

index 423691c..1e5b684 100644 (file)
--- a/pp_ctl.c
+++ b/pp_ctl.c
@@ -3686,8 +3686,8 @@ S_require_file(pTHX_ SV *const sv)
 
     if (!IS_SAFE_PATHNAME(name, len, "require")) {
         DIE(aTHX_ "Can't locate %s:   %s",
-            pv_escape(newSVpvs_flags("",SVs_TEMP),SvPVX(sv),SvCUR(sv),
-                      SvCUR(sv)*2,NULL, SvUTF8(sv)?PERL_PV_ESCAPE_UNI:0),
+            pv_escape(newSVpvs_flags("",SVs_TEMP),name,len,len*2,
+                      NULL, SvUTF8(sv)?PERL_PV_ESCAPE_UNI:0),
             Strerror(ENOENT));
     }
     TAINT_PROPER("require");
index 3744f14..2215b40 100644 (file)
@@ -8,7 +8,7 @@ BEGIN {
 use strict;
 use warnings;
 
-plan(tests => 18);
+plan(tests => 20);
 
 my $nonfile = tempfile();
 
@@ -139,3 +139,11 @@ like $@, qr/^Can't locate strict\.pm\\0invalid: /, 'do nul check';
 eval "require strict\0::invalid;";
 like $@, qr/^syntax error at \(eval \d+\) line 1/, 'parse error with \0 in barewords module names';
 
+# Refs and globs that stringify with embedded nulls
+# These crashed from 5.20 to 5.24 [perl #128182].
+eval { no warnings 'syscalls'; require eval "qr/\0/" };
+like $@, qr/^Can't locate \(\?\^:\\0\):/,
+    'require ref that stringifies with embedded null';
+eval { no strict; no warnings 'syscalls'; require *{"\0a"} };
+like $@, qr/^Can't locate \*main::\\0a:/,
+    'require ref that stringifies with embedded null';