Do not crash if passed garbage like array.
authorJohn Peacock <jpeacock@cpan.org>
Sun, 29 Dec 2013 19:33:48 +0000 (14:33 -0500)
committerFather Chrysostomos <sprout@cpan.org>
Sat, 4 Jan 2014 13:10:04 +0000 (05:10 -0800)
Somehow we lost the test that caught getting passed an arrayref
instead of a simple scalar.  Also integrate fix from perl rt#120872.

cpan/version/lib/version/vpp.pm
cpan/version/t/coretests.pm
vutil.c

index f6153a6..c879c39 100644 (file)
@@ -674,6 +674,11 @@ sub new
            $qv = TRUE;
        }
 
+       if (ref($value) =~ m/ARRAY|HASH/) {
+           require Carp;
+           Carp::croak("Invalid version format (non-numeric data)");
+       }
+
        $value = _un_vstring($value);
 
        # exponential notation
index b7b690a..17bf9ec 100644 (file)
@@ -30,6 +30,10 @@ sub BaseTests {
     $version = $CLASS->$method(1.23);
     is ( "$version" , "1.23" , '1.23 eq "1.23"' );
 
+    # Test explicit integer
+    $version = $CLASS->$method(23);
+    is ( "$version" , 23 , '23 eq "23"' );
+
     # Test quoted number processing
     $version = $CLASS->$method("5.005_03");
     is ( "$version" , "5.005_03" , '"5.005_03" eq "5.005_03"' );
@@ -582,6 +586,13 @@ SKIP: {
        is ref(ver->qv("1.2.3")), 'ver', 'ver can inherit from version';
     }
 
+    { # discovered while integrating with bleadperl
+       eval {my $v = $CLASS->new([1,2,3]) };
+       like $@, qr/Invalid version format/, 'Do not crash for garbage';
+       eval {my $v = $CLASS->new({1 => 2}) };
+       like $@, qr/Invalid version format/, 'Do not crash for garbage';
+    }
+
 }
 
 1;
diff --git a/vutil.c b/vutil.c
index 8eafd75..06680dd 100644 (file)
--- a/vutil.c
+++ b/vutil.c
@@ -572,8 +572,9 @@ Perl_upg_version(pTHX_ SV *ver, bool qv)
        }
 #endif
        if (sv) {
-           Perl_sv_setpvf(aTHX_ sv, "%.9"NVff, SvNVX(ver));
-           buf = SvPV(sv, len);
+           Perl_sv_catpvf(aTHX_ sv, "%.9"NVff, SvNVX(ver));
+           len = SvCUR(sv);
+           buf = SvPVX(sv);
        }
        else {
            len = my_snprintf(tbuf, sizeof(tbuf), "%.9"NVff, SvNVX(ver));
@@ -609,7 +610,7 @@ Perl_upg_version(pTHX_ SV *ver, bool qv)
     else if ( SvUOK(ver) || SvIOK(ver) ) {
        version = savesvpv(ver);
     }
-    else /* must be a string or something like a string */
+    else if ( SvPOK(ver) )/* must be a string or something like a string */
     {
        STRLEN len;
        version = savepvn(SvPV(ver,len), SvCUR(ver));
@@ -650,6 +651,11 @@ Perl_upg_version(pTHX_ SV *ver, bool qv)
 #  endif
 #endif
     }
+    else
+    {
+       /* no idea what this is */
+       Perl_croak(aTHX_ "Invalid version format (non-numeric data)");
+    }
 
     s = SCAN_VERSION(version, ver, qv);
     if ( *s != '\0' )