diff --git a/MANIFEST b/MANIFEST index 7def16c..e11f0ef 100644 --- a/MANIFEST +++ b/MANIFEST @@ -23,6 +23,7 @@ t/test_server_key.pub t/test_user_key t/test_user_key.pub t/known_hosts +t/module-loader.t t/quoting.t t/uri.t examples/expect.pl diff --git a/lib/Net/OpenSSH/ModuleLoader.pm b/lib/Net/OpenSSH/ModuleLoader.pm index 149a517..48a5580 100644 --- a/lib/Net/OpenSSH/ModuleLoader.pm +++ b/lib/Net/OpenSSH/ModuleLoader.pm @@ -11,23 +11,23 @@ our @EXPORT = qw(_load_module); sub _load_module { my ($module, $version) = @_; + defined $module or croak "bad Perl module name"; + $module =~ /\A[A-Za-z_]\w*(?:::\w+)*\z/ + or croak "bad Perl module name $module"; $loaded_module{$module} ||= do { my $err; do { local ($@, $SIG{__DIE__}); - my $ok = eval "require $module; 1"; + (my $path = "$module.pm") =~ s!::!/!g; + my $ok = eval { require $path; 1 }; $err = $@; $ok; } or croak "unable to load Perl module $module: $err"; }; if (defined $version) { - my $mv = do { - local ($@, $SIG{__DIE__}); - eval "\$${module}::VERSION"; - } || 0; - (my $mv1 = $mv) =~ s/_\d*$//; - croak "$module version $version required, $mv is available" - if $mv1 < $version; + local ($@, $SIG{__DIE__}); + eval { $module->VERSION($version); 1 } + or croak $@ || "$module version $version required"; } 1 } diff --git a/t/module-loader.t b/t/module-loader.t new file mode 100644 index 0000000..8e3db42 --- /dev/null +++ b/t/module-loader.t @@ -0,0 +1,34 @@ +#!/usr/bin/perl + +use strict; +use warnings; + +use Test::More tests => 6; + +use Net::OpenSSH::ModuleLoader; + +ok(_load_module('strict'), 'loads a valid module name'); + +eval { _load_module('strict; die "boom"') }; +like($@, qr/bad Perl module name/, 'rejects unsafe module names'); + +eval { _load_module(undef) }; +like($@, qr/bad Perl module name/, 'rejects undefined module names without warnings'); + +eval { _load_module('strict', 999_999) }; +like($@, qr/strict version 999999 required|strict version 999999 required--this is only version/, + 'uses standard VERSION checks for too-new requirements'); + +{ + package Test::Net::OpenSSH::ModuleLoader::Versioned; + our $VERSION = '1.02'; +} + +$INC{'Test/Net/OpenSSH/ModuleLoader/Versioned.pm'} = __FILE__; + +ok(_load_module('Test::Net::OpenSSH::ModuleLoader::Versioned', '1.01'), + 'accepts a sufficient version'); + +eval { _load_module('Test::Net::OpenSSH::ModuleLoader::Versioned', '1.03') }; +like($@, qr/Test::Net::OpenSSH::ModuleLoader::Versioned version 1.03 required/, + 'rejects an insufficient version');