Hello community,
here is the log from the commit of package perl-Module-Runtime for openSUSE:Factory checked in at 2012-02-16 16:22:04
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/perl-Module-Runtime (Old)
and /work/SRC/openSUSE:Factory/.perl-Module-Runtime.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "perl-Module-Runtime", Maintainer is ""
Changes:
--------
--- /work/SRC/openSUSE:Factory/perl-Module-Runtime/perl-Module-Runtime.changes 2011-11-16 17:21:39.000000000 +0100
+++ /work/SRC/openSUSE:Factory/.perl-Module-Runtime.new/perl-Module-Runtime.changes 2012-02-16 16:22:06.000000000 +0100
@@ -1,0 +2,33 @@
+Mon Feb 13 09:03:02 UTC 2012 - coolo@suse.com
+
+- updated to 0.012
+ * work around Perl core bug [RT#68590] regarding leakage of %^H
+ into modules being loaded
+
+ * work around Perl core bug that made a failed module loading appear
+ successful when re-requiring the same module
+
+ * duplicate is_string() from Params::Classify, rather than importing it,
+ to avoid circular dependency problems (affecting both installation
+ and runtime)
+
+ * duplicate minimal exporting behaviour from Exporter, and avoid using
+ the "feature", "warnings", "strict", and "parent" pragmata, to allow
+ for possible future use of this module by any infrastructure module
+
+ * document core bug workarounds
+
+ * document module name syntax more prominently, and discuss the state
+ of Unicode handling
+
+ * tweak documentation of use_package_optimistically()
+
+ * test behaviour with tainted module name
+
+ * test lack of unwanted eval frame around require
+
+ * give test modules more meaningful names
+
+ * convert .cvsignore to .gitignore
+
+-------------------------------------------------------------------
Old:
----
Module-Runtime-0.011.tar.gz
New:
----
Module-Runtime-0.012.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ perl-Module-Runtime.spec ++++++
--- /var/tmp/diff_new_pack.dPwlrJ/_old 2012-02-16 16:22:07.000000000 +0100
+++ /var/tmp/diff_new_pack.dPwlrJ/_new 2012-02-16 16:22:07.000000000 +0100
@@ -1,7 +1,7 @@
#
# spec file for package perl-Module-Runtime
#
-# Copyright (c) 2011 SUSE LINUX Products GmbH, Nuernberg, Germany.
+# Copyright (c) 2012 SUSE LINUX Products GmbH, Nuernberg, Germany.
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
@@ -16,41 +16,40 @@
#
-
Name: perl-Module-Runtime
-Version: 0.011
-Release: 1
-License: GPL-1.0+ or Artistic-1.0
+Version: 0.012
+Release: 0
%define cpan_name Module-Runtime
Summary: runtime module handling
-Url: http://search.cpan.org/dist/Module-Runtime/
+License: Artistic-1.0 or GPL-1.0+
Group: Development/Libraries/Perl
+Url: http://search.cpan.org/dist/Module-Runtime/
Source: http://www.cpan.org/authors/id/Z/ZE/ZEFRAM/%{cpan_name}-%{version}.tar.gz
BuildArch: noarch
BuildRoot: %{_tmppath}/%{name}-%{version}-build
BuildRequires: perl
BuildRequires: perl-macros
-BuildRequires: perl(Exporter)
BuildRequires: perl(Module::Build)
-BuildRequires: perl(Params::Classify)
-BuildRequires: perl(parent)
-BuildRequires: perl(strict)
-BuildRequires: perl(Test::More)
-BuildRequires: perl(warnings)
-#BuildRequires: perl(CPAN)
-#BuildRequires: perl(Cwd)
-#BuildRequires: perl(ExtUtils::MakeMaker)
-#BuildRequires: perl(File::Spec)
-Requires: perl(Exporter)
-Requires: perl(Params::Classify)
-Requires: perl(parent)
-Requires: perl(strict)
-Requires: perl(warnings)
+#BuildRequires: perl(Module::Runtime)
%{perl_requires}
%description
The functions exported by this module deal with runtime handling of Perl
-modules, which are normally handled at compile time.
+modules, which are normally handled at compile time. This module avoids
+using any other modules, so that it can be used in low-level
+infrastructure.
+
+The parts of this module that work with module names apply the same syntax
+that is used for barewords in Perl source. In principle this syntax can
+vary between versions of Perl, and this module applies the syntax of the
+Perl on which it is running. In practice the usable syntax hasn't changed
+yet, but there's a good chance of it changing in Perl 5.18.
+
+The functions of this module whose purpose is to load modules include
+workarounds for three old Perl core bugs regarding 'require'. These
+workarounds are applied on any Perl version where the bugs exist, except
+for a case where one of the bugs cannot be adequately worked around in pure
+Perl.
%prep
%setup -q -n %{cpan_name}-%{version}
++++++ Module-Runtime-0.011.tar.gz -> Module-Runtime-0.012.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Module-Runtime-0.011/.gitignore new/Module-Runtime-0.012/.gitignore
--- old/Module-Runtime-0.011/.gitignore 1970-01-01 01:00:00.000000000 +0100
+++ new/Module-Runtime-0.012/.gitignore 2012-02-12 12:54:02.000000000 +0100
@@ -0,0 +1,11 @@
+/Build
+/Makefile
+/_build
+/blib
+/META.json
+/META.yml
+/MYMETA.json
+/MYMETA.yml
+/Makefile.PL
+/SIGNATURE
+/Module-Runtime-*
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Module-Runtime-0.011/Build.PL new/Module-Runtime-0.012/Build.PL
--- old/Module-Runtime-0.011/Build.PL 2011-10-25 00:15:17.000000000 +0200
+++ new/Module-Runtime-0.012/Build.PL 2012-02-12 12:54:02.000000000 +0100
@@ -21,12 +21,7 @@
"warnings" => 0,
},
requires => {
- "Exporter" => 0,
- "Params::Classify" => 0,
- "parent" => 0,
"perl" => "5.006",
- "strict" => 0,
- "warnings" => 0,
},
dynamic_config => 0,
meta_add => { distribution_type => "module" },
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Module-Runtime-0.011/Changes new/Module-Runtime-0.012/Changes
--- old/Module-Runtime-0.011/Changes 2011-10-25 00:15:17.000000000 +0200
+++ new/Module-Runtime-0.012/Changes 2012-02-12 12:54:02.000000000 +0100
@@ -1,3 +1,34 @@
+version 0.012; 2012-02-12
+
+ * work around Perl core bug [perl #68590] regarding leakage of %^H
+ into modules being loaded
+
+ * work around Perl core bug that made a failed module loading appear
+ successful when re-requiring the same module
+
+ * duplicate is_string() from Params::Classify, rather than importing it,
+ to avoid circular dependency problems (affecting both installation
+ and runtime)
+
+ * duplicate minimal exporting behaviour from Exporter, and avoid using
+ the "feature", "warnings", "strict", and "parent" pragmata, to allow
+ for possible future use of this module by any infrastructure module
+
+ * document core bug workarounds
+
+ * document module name syntax more prominently, and discuss the state
+ of Unicode handling
+
+ * tweak documentation of use_package_optimistically()
+
+ * test behaviour with tainted module name
+
+ * test lack of unwanted eval frame around require
+
+ * give test modules more meaningful names
+
+ * convert .cvsignore to .gitignore
+
version 0.011; 2011-10-24
* bugfix: in require_module() and use_module(), work around a Perl
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Module-Runtime-0.011/MANIFEST new/Module-Runtime-0.012/MANIFEST
--- old/Module-Runtime-0.011/MANIFEST 2011-10-25 00:15:17.000000000 +0200
+++ new/Module-Runtime-0.012/MANIFEST 2012-02-12 12:54:02.000000000 +0100
@@ -1,4 +1,4 @@
-.cvsignore
+.gitignore
Build.PL
Changes
MANIFEST
@@ -7,15 +7,21 @@
Makefile.PL
README
lib/Module/Runtime.pm
-t/Mod0.pm
-t/Mod1.pm
+t/Break.pm
+t/Context.pm
+t/Eval.pm
+t/Hints.pm
+t/Simple.pm
t/cmn.t
+t/dependency.t
+t/import_error.t
t/ivmn.t
t/ivms.t
t/mnf.t
t/pod_cvg.t
t/pod_syn.t
t/rm.t
+t/taint.t
t/um.t
t/upo.t
SIGNATURE Added here by Module::Build
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Module-Runtime-0.011/META.json new/Module-Runtime-0.012/META.json
--- old/Module-Runtime-0.011/META.json 2011-10-25 00:15:17.000000000 +0200
+++ new/Module-Runtime-0.012/META.json 2012-02-12 12:54:02.000000000 +0100
@@ -33,19 +33,14 @@
},
"runtime" : {
"requires" : {
- "Exporter" : 0,
- "Params::Classify" : 0,
- "parent" : 0,
- "perl" : "5.006",
- "strict" : 0,
- "warnings" : 0
+ "perl" : "5.006"
}
}
},
"provides" : {
"Module::Runtime" : {
"file" : "lib/Module/Runtime.pm",
- "version" : "0.011"
+ "version" : "0.012"
}
},
"release_status" : "stable",
@@ -54,5 +49,5 @@
"http://dev.perl.org/licenses/"
]
},
- "version" : "0.011"
+ "version" : "0.012"
}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Module-Runtime-0.011/META.yml new/Module-Runtime-0.012/META.yml
--- old/Module-Runtime-0.011/META.yml 2011-10-25 00:15:17.000000000 +0200
+++ new/Module-Runtime-0.012/META.yml 2012-02-12 12:54:02.000000000 +0100
@@ -23,14 +23,9 @@
provides:
Module::Runtime:
file: lib/Module/Runtime.pm
- version: 0.011
+ version: 0.012
requires:
- Exporter: 0
- Params::Classify: 0
- parent: 0
perl: 5.006
- strict: 0
- warnings: 0
resources:
license: http://dev.perl.org/licenses/
-version: 0.011
+version: 0.012
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Module-Runtime-0.011/README new/Module-Runtime-0.012/README
--- old/Module-Runtime-0.011/README 2011-10-25 00:15:17.000000000 +0200
+++ new/Module-Runtime-0.012/README 2012-02-12 12:54:02.000000000 +0100
@@ -4,8 +4,22 @@
DESCRIPTION
-The functions exported by this module deal with runtime handling of Perl
-modules, which are normally handled at compile time.
+The functions exported by this module deal with runtime handling of
+Perl modules, which are normally handled at compile time. This module
+avoids using any other modules, so that it can be used in low-level
+infrastructure.
+
+The parts of this module that work with module names apply the same
+syntax that is used for barewords in Perl source. In principle this
+syntax can vary between versions of Perl, and this module applies the
+syntax of the Perl on which it is running. In practice the usable syntax
+hasn't changed yet, but there's a good chance of it changing in Perl 5.18.
+
+The functions of this module whose purpose is to load modules include
+workarounds for three old Perl core bugs regarding "require". These
+workarounds are applied on any Perl version where the bugs exist, except
+for a case where one of the bugs cannot be adequately worked around in
+pure Perl.
INSTALLATION
@@ -20,7 +34,7 @@
COPYRIGHT
-Copyright (C) 2004, 2006, 2007, 2009, 2010, 2011
+Copyright (C) 2004, 2006, 2007, 2009, 2010, 2011, 2012
Andrew Main (Zefram)
LICENSE
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Module-Runtime-0.011/SIGNATURE new/Module-Runtime-0.012/SIGNATURE
--- old/Module-Runtime-0.011/SIGNATURE 2011-10-25 00:15:27.000000000 +0200
+++ new/Module-Runtime-0.012/SIGNATURE 2012-02-12 12:54:07.000000000 +0100
@@ -14,30 +14,36 @@
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
-SHA1 ebdaab906c62ff40b3e35b320d0724e2e38cd959 .cvsignore
-SHA1 de6c2fdf1247bfd8b7eecfba4fd403d615fe5102 Build.PL
-SHA1 347dc1d11d4ac43933d6fd8d1438aa0b82ae9248 Changes
-SHA1 0824ada5d908f7df2d10648c20aa14a454053cd3 MANIFEST
-SHA1 0f7940cb32c667fc022a3ed5c89df48592515ae8 META.json
-SHA1 cf12caa191857cc293f6e1d095a2f04b41a515d4 META.yml
+SHA1 846abd52ddad1c3141b395933fd10f14cb3cd7bc .gitignore
+SHA1 dd0ddabd6469a1b8c7f9dd0e7eb63a59d9b763db Build.PL
+SHA1 ba7b415c1638b6f8056b0fafec88acab3f9a2a3a Changes
+SHA1 7761501f07e9045a073537d0cce2e4214d417abd MANIFEST
+SHA1 f483967b1e2121537599d2ca1c9f10083ca6d2b3 META.json
+SHA1 bf9146284bf2f6a1dd595bb6b677ff6820a6f444 META.yml
SHA1 a4df8e97ccd390a42212af5a9f4d0986c85e7a5f Makefile.PL
-SHA1 51e1825521428873eb7ffb3dbba5503fd71fa23d README
-SHA1 5cd392a8733b918f3699beec0e89beb753861069 lib/Module/Runtime.pm
-SHA1 15f83d769adddc47c9b7f41bfd1c8d109af030f5 t/Mod0.pm
-SHA1 e13ce4d6f9946cc4e9f59d4c24dd0dd208992663 t/Mod1.pm
+SHA1 5601c747fdb2c85a790ebfe21303f693f9e38574 README
+SHA1 0863044a64b2b6f22d548db4a2be56684b7fd1a1 lib/Module/Runtime.pm
+SHA1 e80e49f06f99a5b5bb0faf54988df29a7aff89c5 t/Break.pm
+SHA1 c3c7b101e683f9f3d7f915763aa6d1850421bcb4 t/Context.pm
+SHA1 fbe32c46e3fe2cac40e4ab173764aec7db9b2a00 t/Eval.pm
+SHA1 d7f5ca01199b601b1a1a86127270d9ab7d1ca50b t/Hints.pm
+SHA1 f8988828e7cab17800a0b5f25547f09431933480 t/Simple.pm
SHA1 a0f9c0dfbe6472e81222a196a2f17554697d0d48 t/cmn.t
+SHA1 c0cdbe18b2c347ebabda457af0b73a1c14866535 t/dependency.t
+SHA1 9331d0076c868209e9d3f0572d80f3e81df456df t/import_error.t
SHA1 fa24ea0033e10712a16c71466d488cd3e69e3697 t/ivmn.t
SHA1 84e207008efae1ed0ad21601d77205c2a8739fa5 t/ivms.t
SHA1 8adfb7863317a2d0962a2538800cb5ad3bda1690 t/mnf.t
SHA1 904d9a4f76525e2303e4b0c168c68230f223c8de t/pod_cvg.t
SHA1 65c75abdef6f01a5d1588a307f2ddfe2333dc961 t/pod_syn.t
-SHA1 e288041e245f8915789efefd2e97d3f14ff394ef t/rm.t
-SHA1 7f12b2d9db3fbf8dc444c24a2cf3ee682fd722dd t/um.t
-SHA1 33de70ab8e0c415ab87e2120edefddc9516632ad t/upo.t
+SHA1 2e9638c32424e2e58100d64cb74ac50a0b964d1b t/rm.t
+SHA1 5a0ef5f7a982fbaff5d501165ae2720f465c7560 t/taint.t
+SHA1 75d8504e7dc405bc5b7296b509bcfad5230477c0 t/um.t
+SHA1 4aed128da5418fa7b5f3ff21d89fc3134bc5a111 t/upo.t
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.10 (GNU/Linux)
-iEYEARECAAYFAk6l43UACgkQOV9mt2VyAVEzYgCeJVbJUMNFU2ekn71CsMRORDam
-ctsAnR6Kk9RbpdbJiEywsdwd1Z+VhySd
-=zdZP
+iEYEARECAAYFAk83qFoACgkQOV9mt2VyAVHCiACggpTkwm7VqCcQHjRXMUIlRrQd
+vdgAoJ2f0k6rm+zI63O9RMutiaRB5hBY
+=KypS
-----END PGP SIGNATURE-----
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Module-Runtime-0.011/lib/Module/Runtime.pm new/Module-Runtime-0.012/lib/Module/Runtime.pm
--- old/Module-Runtime-0.011/lib/Module/Runtime.pm 2011-10-25 00:15:17.000000000 +0200
+++ new/Module-Runtime-0.012/lib/Module/Runtime.pm 2012-02-12 12:54:02.000000000 +0100
@@ -37,22 +37,92 @@
=head1 DESCRIPTION
-The functions exported by this module deal with runtime handling of Perl
-modules, which are normally handled at compile time.
+The functions exported by this module deal with runtime handling of
+Perl modules, which are normally handled at compile time. This module
+avoids using any other modules, so that it can be used in low-level
+infrastructure.
+
+The parts of this module that work with module names apply the same
+syntax that is used for barewords in Perl source. In principle this
+syntax can vary between versions of Perl, and this module applies the
+syntax of the Perl on which it is running. In practice the usable syntax
+hasn't changed yet, but there's a good chance of it changing in Perl 5.18.
+
+The functions of this module whose purpose is to load modules include
+workarounds for three old Perl core bugs regarding C<require>. These
+workarounds are applied on any Perl version where the bugs exist, except
+for a case where one of the bugs cannot be adequately worked around in
+pure Perl.
+
+=head2 Module name syntax
+
+The usable module name syntax has not changed from Perl 5.000 up to
+Perl 5.15.7. The syntax is composed entirely of ASCII characters.
+From Perl 5.6 onwards there has been some attempt to allow the use of
+non-ASCII Unicode characters in Perl source, but it was fundamentally
+broken (like the entirety of Perl 5.6's Unicode handling) and remained
+pretty much entirely unusable until it got some attention in the Perl
+5.15 series. Although Unicode is now consistently accepted by the
+parser in some places, it remains broken for module names. Furthermore,
+there has not yet been any work on how to map Unicode module names into
+filenames, so in that respect also Unicode module names are unusable.
+This may finally be addressed in the Perl 5.17 series.
+
+The module name syntax is, precisely: the string must consist of one or
+more segments separated by C<::>; each segment must consist of one or more
+identifier characters (ASCII alphanumerics plus "_"); the first character
+of the string must not be a digit. Thus "CIO::File", "C<warnings>",
+and "Cfoo::123::x_0" are all valid module names, whereas "CIO::"
+and "C<1foo::bar>" are not. C<'> separators are not permitted by this
+module, though they remain usable in Perl source, being translated to
+C<::> in the parser.
+
+=head2 Core bugs worked around
+
+The first bug worked around is core bug [perl #68590], which causes
+lexical state in one file to leak into another that is C<require>d/C<use>d
+from it. This bug is present from Perl 5.6 up to Perl 5.10, and is
+fixed in Perl 5.11.0. From Perl 5.9.4 up to Perl 5.10.0 no satisfactory
+workaround is possible in pure Perl. The workaround means that modules
+loaded via this module don't suffer this pollution of their lexical
+state. Modules loaded in other ways, or via this module on the Perl
+versions where the pure Perl workaround is impossible, remain vulnerable.
+The module LLexical::SealRequireHints provides a complete workaround
+for this bug.
+
+The second bug worked around causes some kinds of failure in module
+loading, principally compilation errors in the loaded module, to be
+recorded in C<%INC> as if they were successful, so later attempts to load
+the same module immediately indicate success. This bug is present up
+to Perl 5.8.9, and is fixed in Perl 5.9.0. The workaround means that a
+compilation error in a module loaded via this module won't be cached as
+a success. Modules loaded in other ways remain liable to produce bogus
+C<%INC> entries, and if a bogus entry exists then it will mislead this
+module if it is used to re-attempt loading.
+
+The third bug worked around causes the wrong context to be seen at
+file scope of a loaded module, if C<require> is invoked in a location
+that inherits context from a higher scope. This bug is present up to
+Perl 5.11.2, and is fixed in Perl 5.11.3. The workaround means that
+a module loaded via this module will always see the correct context.
+Modules loaded in other ways remain vulnerable.
=cut
package Module::Runtime;
-{ use 5.006; }
-use warnings;
-use strict;
+# Don't "use 5.006" here, because Perl 5.15.6 will load feature.pm if
+# the version check is done that way.
+BEGIN { require 5.006; }
+# Don't "use warnings" here, to avoid dependencies. Do standardise the
+# warning status by lexical override; unfortunately the only safe bitset
+# to build in is the empty set, equivalent to "no warnings".
+BEGIN { ${^WARNING_BITS} = ""; }
+# Don't "use strict" here, to avoid dependencies.
-use Params::Classify 0.000 qw(is_string);
+our $VERSION = "0.012";
-our $VERSION = "0.011";
-
-use parent "Exporter";
+# Don't use Exporter here, to avoid dependencies.
our @EXPORT_OK = qw(
$module_name_rx is_module_name is_valid_module_name check_module_name
module_notional_filename require_module
@@ -61,6 +131,36 @@
is_module_spec is_valid_module_spec check_module_spec
compose_module_name
);
+my %export_ok = map { ($_ => undef) } @EXPORT_OK;
+sub import {
+ my $me = shift;
+ my $callpkg = caller(0);
+ my $errs = "";
+ foreach(@_) {
+ if(exists $export_ok{$_}) {
+ # We would need to do "no strict 'refs'" here
+ # if we had enabled strict at file scope.
+ if(/\A\$(.*)\z/s) {
+ *{$callpkg."::".$1} = \$$1;
+ } else {
+ *{$callpkg."::".$_} = \&$_;
+ }
+ } else {
+ $errs .= "\"$_\" is not exported by the $me module\n";
+ }
+ }
+ if($errs ne "") {
+ die "${errs}Can't continue after import errors ".
+ "at @{[(caller(0))[1]]} line @{[(caller(0))[2]]}.\n";
+ }
+}
+
+# Logic duplicated from Params::Classify. Duplicating it here avoids
+# an extensive and potentially circular dependency graph.
+sub _is_string($) {
+ my($arg) = @_;
+ return defined($arg) && ref(\$arg) eq "SCALAR";
+}
=head1 REGULAR EXPRESSIONS
@@ -73,15 +173,6 @@
=item $module_name_rx
Matches a valid Perl module name in bareword syntax.
-The rule for this, precisely, is: the string must
-consist of one or more segments separated by C<::>; each segment must
-consist of one or more identifier characters (alphanumerics plus "_");
-the first character of the string must not be a digit. Thus "CIO::File",
-"C<warnings>", and "Cfoo::123::x_0" are all valid module names, whereas
-"CIO::" and "C<1foo::bar>" are not.
-Only ASCII characters are permitted; Perl's handling of non-ASCII
-characters in source code is inconsistent.
-C<'> separators are not permitted.
=cut
@@ -128,7 +219,7 @@
=cut
-sub is_module_name($) { is_string($_[0]) && $_[0] =~ /\A$module_name_rx\z/o }
+sub is_module_name($) { _is_string($_[0]) && $_[0] =~ /\A$module_name_rx\z/o }
=item is_valid_module_name(ARG)
@@ -148,7 +239,7 @@
sub check_module_name($) {
unless(&is_module_name) {
- die +(is_string($_[0]) ? "`$_[0]'" : "argument").
+ die +(_is_string($_[0]) ? "`$_[0]'" : "argument").
" is not a module name\n";
}
}
@@ -194,15 +285,37 @@
=cut
+# Don't "use constant" here, to avoid dependencies.
+BEGIN {
+ *_WORK_AROUND_HINT_LEAKAGE =
+ "$]" < 5.011 && !("$]" >= 5.009004 && "$]" < 5.010001)
+ ? sub(){1} : sub(){0};
+ *_WORK_AROUND_BROKEN_MODULE_STATE = "$]" < 5.009 ? sub(){1} : sub(){0};
+}
+
+BEGIN { if(_WORK_AROUND_BROKEN_MODULE_STATE) { eval q{
+ sub Module::Runtime::__GUARD__::DESTROY {
+ delete $INC{$_[0]->[0]} if @{$_[0]};
+ }
+ 1;
+}; die $@ if $@ ne ""; } }
+
sub require_module($) {
- # Explicit scalar() here works around a Perl core bug, present
- # in Perl 5.8 and 5.10, which allowed a require() in return
- # position to pass a non-scalar context through to file scope
- # of the required file. This breaks some modules. require()
- # in any other position, where its op flags determine context
- # statically, doesn't have this problem, because the op flags
- # are forced to scalar.
- return scalar(require(&module_notional_filename));
+ # Localise %^H to work around [perl #68590], where the bug exists
+ # and this is a satisfactory workaround. The bug consists of
+ # %^H state leaking into each required module, polluting the
+ # module's lexical state.
+ local %^H if _WORK_AROUND_HINT_LEAKAGE;
+ if(_WORK_AROUND_BROKEN_MODULE_STATE) {
+ my $notional_filename = &module_notional_filename;
+ my $guard = bless([ $notional_filename ],
+ "Module::Runtime::__GUARD__");
+ my $result = require($notional_filename);
+ pop @$guard;
+ return $result;
+ } else {
+ return scalar(require(&module_notional_filename));
+ }
}
=back
@@ -248,8 +361,8 @@
An attempt is made to load the named module (as if by the bareword form
of C<require>). If the module cannot be found then it is assumed that
-the package was actually already loaded but wasn't detected correctly,
-and no error is signalled. That's the optimistic bit.
+the package was actually already loaded by other means, and no error
+is signalled. That's the optimistic bit.
This is mostly the same operation that is performed by the L<base> pragma
to ensure that the specified base classes are available. The behaviour
@@ -267,11 +380,9 @@
sub use_package_optimistically($;$) {
my($name, $version) = @_;
check_module_name($name);
- eval { local $SIG{__DIE__}; require(module_notional_filename($name)); };
- die $@ if $@ ne "" && $@ !~ /\A
- Can't\ locate\ .+\ at
- \ \Q@{[__FILE__]}\E\ line\ \Q@{[__LINE__-1]}\E
- /xs;
+ eval { local $SIG{__DIE__}; require_module($name); };
+ die $@ if $@ ne "" &&
+ $@ !~ /\ACan't locate .+ at \Q@{[__FILE__]}\E line/s;
$name->VERSION($version) if defined $version;
return $name;
}
@@ -294,7 +405,7 @@
sub is_module_spec($$) {
my($prefix, $spec) = @_;
- return is_string($spec) &&
+ return _is_string($spec) &&
$spec =~ ($prefix ? qr/\A$sub_module_spec_rx\z/o :
qr/\A$top_module_spec_rx\z/o);
}
@@ -316,7 +427,7 @@
sub check_module_spec($$) {
unless(&is_module_spec) {
- die +(is_string($_[1]) ? "`$_[1]'" : "argument").
+ die +(_is_string($_[1]) ? "`$_[1]'" : "argument").
" is not a module specification\n";
}
}
@@ -359,6 +470,7 @@
=head1 SEE ALSO
+LLexical::SealRequireHints,
L<base>,
L,
L
@@ -369,7 +481,7 @@
=head1 COPYRIGHT
-Copyright (C) 2004, 2006, 2007, 2009, 2010, 2011
+Copyright (C) 2004, 2006, 2007, 2009, 2010, 2011, 2012
Andrew Main (Zefram)
=head1 LICENSE
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Module-Runtime-0.011/t/Break.pm new/Module-Runtime-0.012/t/Break.pm
--- old/Module-Runtime-0.011/t/Break.pm 1970-01-01 01:00:00.000000000 +0100
+++ new/Module-Runtime-0.012/t/Break.pm 2012-02-12 12:54:02.000000000 +0100
@@ -0,0 +1,7 @@
+package t::Break;
+
+{ use 5.006; }
+use warnings;
+use strict;
+
+die "broken";
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Module-Runtime-0.011/t/Context.pm new/Module-Runtime-0.012/t/Context.pm
--- old/Module-Runtime-0.011/t/Context.pm 1970-01-01 01:00:00.000000000 +0100
+++ new/Module-Runtime-0.012/t/Context.pm 2012-02-12 12:54:02.000000000 +0100
@@ -0,0 +1,12 @@
+package t::Context;
+
+{ use 5.006; }
+use warnings;
+use strict;
+
+our $VERSION = 1;
+
+die "t::Context sees array context at file scope" if wantarray;
+die "t::Context sees void context at file scope" unless defined wantarray;
+
+"t::Context return";
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Module-Runtime-0.011/t/Eval.pm new/Module-Runtime-0.012/t/Eval.pm
--- old/Module-Runtime-0.011/t/Eval.pm 1970-01-01 01:00:00.000000000 +0100
+++ new/Module-Runtime-0.012/t/Eval.pm 2012-02-12 12:54:02.000000000 +0100
@@ -0,0 +1,41 @@
+package t::Eval;
+
+use warnings;
+use strict;
+
+use Test::More;
+
+sub _ok_no_eval() {
+ my $lastsub = "";
+ my $i = 0;
+ while(1) {
+ my @c = caller($i);
+ unless(@c) {
+ ok 0;
+ diag "failed to find main program in stack trace";
+ return;
+ }
+ my $sub = $c[3];
+ if($sub eq "main::eval_test") {
+ ok 1;
+ return;
+ }
+ my $type = $sub ne "(eval)" ? "subroutine" :
+ $c[7] ? "require" :
+ defined($c[6]) ? "string eval" : "block eval";
+ if($type =~ /eval/ && !($lastsub eq "t::Eval::BEGIN" &&
+ $type eq "block eval")) {
+ ok 0;
+ diag "have $type between module and main program";
+ return;
+ }
+ $lastsub = $sub;
+ $i++;
+ }
+}
+
+BEGIN { _ok_no_eval(); }
+_ok_no_eval();
+sub import { _ok_no_eval(); }
+
+1;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Module-Runtime-0.011/t/Hints.pm new/Module-Runtime-0.012/t/Hints.pm
--- old/Module-Runtime-0.011/t/Hints.pm 1970-01-01 01:00:00.000000000 +0100
+++ new/Module-Runtime-0.012/t/Hints.pm 2012-02-12 12:54:02.000000000 +0100
@@ -0,0 +1,17 @@
+package t::Hints;
+
+use warnings;
+use strict;
+
+use Test::More;
+
+BEGIN { is $^H{"Module::Runtime/test_a"}, undef; }
+main::test_runtime_hint_hash "Module::Runtime/test_a", undef;
+
+sub import {
+ is $^H{"Module::Runtime/test_a"}, 1;
+ $^H |= 0x20000 if "$]" < 5.009004;
+ $^H{"Module::Runtime/test_b"} = 1;
+}
+
+1;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Module-Runtime-0.011/t/Mod0.pm new/Module-Runtime-0.012/t/Mod0.pm
--- old/Module-Runtime-0.011/t/Mod0.pm 2011-10-25 00:15:17.000000000 +0200
+++ new/Module-Runtime-0.012/t/Mod0.pm 1970-01-01 01:00:00.000000000 +0100
@@ -1,9 +0,0 @@
-package t::Mod0;
-
-{ use 5.006; }
-use warnings;
-use strict;
-
-our $VERSION = 1;
-
-"t::Mod0 return";
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Module-Runtime-0.011/t/Mod1.pm new/Module-Runtime-0.012/t/Mod1.pm
--- old/Module-Runtime-0.011/t/Mod1.pm 2011-10-25 00:15:17.000000000 +0200
+++ new/Module-Runtime-0.012/t/Mod1.pm 1970-01-01 01:00:00.000000000 +0100
@@ -1,12 +0,0 @@
-package t::Mod1;
-
-{ use 5.006; }
-use warnings;
-use strict;
-
-our $VERSION = 1;
-
-die "t::Mod1 sees array context at file scope" if wantarray;
-die "t::Mod1 sees void context at file scope" unless defined wantarray;
-
-"t::Mod1 return";
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Module-Runtime-0.011/t/Simple.pm new/Module-Runtime-0.012/t/Simple.pm
--- old/Module-Runtime-0.011/t/Simple.pm 1970-01-01 01:00:00.000000000 +0100
+++ new/Module-Runtime-0.012/t/Simple.pm 2012-02-12 12:54:02.000000000 +0100
@@ -0,0 +1,9 @@
+package t::Simple;
+
+{ use 5.006; }
+use warnings;
+use strict;
+
+our $VERSION = 1;
+
+"t::Simple return";
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Module-Runtime-0.011/t/dependency.t new/Module-Runtime-0.012/t/dependency.t
--- old/Module-Runtime-0.011/t/dependency.t 1970-01-01 01:00:00.000000000 +0100
+++ new/Module-Runtime-0.012/t/dependency.t 2012-02-12 12:54:02.000000000 +0100
@@ -0,0 +1,8 @@
+# This test checks that M:R doesn't load any other modules. Hence this
+# script cannot itself use warnings, Test::More, or any other module.
+
+BEGIN { print "1..1\n"; }
+use Module::Runtime qw(require_module);
+print join(" ", sort keys %INC) eq "Module/Runtime.pm" ? "" : "not ", "ok 1\n";
+
+1;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Module-Runtime-0.011/t/import_error.t new/Module-Runtime-0.012/t/import_error.t
--- old/Module-Runtime-0.011/t/import_error.t 1970-01-01 01:00:00.000000000 +0100
+++ new/Module-Runtime-0.012/t/import_error.t 2012-02-12 12:54:02.000000000 +0100
@@ -0,0 +1,35 @@
+use warnings;
+use strict;
+
+use Test::More tests => 3;
+
+eval q{#line 11 "test_eval"
+ use Module::Runtime qw(foo);
+};
+$@ =~ s/\(eval [0-9]+\) line 2/test_eval line 11/ if "$]" < 5.006001;
+like $@, qr/\A
+ \"foo\"\ is\ not\ exported\ by\ the\ Module::Runtime\ module\n
+ Can't\ continue\ after\ import\ errors\ at\ test_eval\ line\ 11.\n
+/x;
+
+eval q{#line 22 "test_eval"
+ use Module::Runtime qw(require_module.1);
+};
+$@ =~ s/\(eval [0-9]+\) line 2/test_eval line 22/ if "$]" < 5.006001;
+like $@, qr/\A
+ \"require_module.1\"\ is\ not\ exported
+ \ by\ the\ Module::Runtime\ module\n
+ Can't\ continue\ after\ import\ errors\ at\ test_eval\ line\ 22.\n
+/x;
+
+eval q{#line 33 "test_eval"
+ use Module::Runtime qw(foo require_module bar);
+};
+$@ =~ s/\(eval [0-9]+\) line 2/test_eval line 33/ if "$]" < 5.006001;
+like $@, qr/\A
+ \"foo\"\ is\ not\ exported\ by\ the\ Module::Runtime\ module\n
+ \"bar\"\ is\ not\ exported\ by\ the\ Module::Runtime\ module\n
+ Can't\ continue\ after\ import\ errors\ at\ test_eval\ line\ 33.\n
+/x;
+
+1;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Module-Runtime-0.011/t/rm.t new/Module-Runtime-0.012/t/rm.t
--- old/Module-Runtime-0.011/t/rm.t 2011-10-25 00:15:17.000000000 +0200
+++ new/Module-Runtime-0.012/t/rm.t 2012-02-12 12:54:02.000000000 +0100
@@ -1,7 +1,7 @@
use warnings;
use strict;
-use Test::More tests => 9;
+use Test::More tests => 26;
BEGIN { use_ok "Module::Runtime", qw(require_module); }
@@ -23,17 +23,64 @@
is($result, 1);
# a module that we'll load now
-test_require_module("t::Mod0");
+test_require_module("t::Simple");
is($err, "");
-is($result, "t::Mod0 return");
+is($result, "t::Simple return");
# re-requiring the module that we just loaded
-test_require_module("t::Mod0");
+test_require_module("t::Simple");
is($err, "");
is($result, 1);
# module file scope sees scalar context regardless of calling context
-eval { require_module("t::Mod1"); 1 };
+eval { require_module("t::Context"); 1 };
is $@, "";
+# lexical hints don't leak through
+my $have_runtime_hint_hash = "$]" >= 5.009004;
+sub test_runtime_hint_hash($$) {
+ SKIP: {
+ skip "no runtime hint hash", 1 unless $have_runtime_hint_hash;
+ is +((caller(0))[10] || {})->{$_[0]}, $_[1];
+ }
+}
+SKIP: {
+ skip "core bug makes this test crash", 13
+ if "$]" >= 5.008 && "$]" < 5.008004;
+ skip "can't work around hint leakage in pure Perl", 13
+ if "$]" >= 5.009004 && "$]" < 5.010001;
+ $^H |= 0x20000 if "$]" < 5.009004;
+ $^H{"Module::Runtime/test_a"} = 1;
+ is $^H{"Module::Runtime/test_a"}, 1;
+ is $^H{"Module::Runtime/test_b"}, undef;
+ require_module("t::Hints");
+ is $^H{"Module::Runtime/test_a"}, 1;
+ is $^H{"Module::Runtime/test_b"}, undef;
+ t::Hints->import;
+ is $^H{"Module::Runtime/test_a"}, 1;
+ is $^H{"Module::Runtime/test_b"}, 1;
+ eval q{
+ BEGIN { $^H |= 0x20000; $^H{foo} = 1; }
+ BEGIN { is $^H{foo}, 1; }
+ main::test_runtime_hint_hash("foo", 1);
+ BEGIN { require_module("Math::BigInt"); }
+ BEGIN { is $^H{foo}, 1; }
+ main::test_runtime_hint_hash("foo", 1);
+ 1;
+ }; die $@ unless $@ eq "";
+}
+
+# broken module is visibly broken when re-required
+eval { require_module("t::Break") };
+like $@, qr/\A(?:broken |Attempt to reload )/;
+eval { require_module("t::Break") };
+like $@, qr/\A(?:broken |Attempt to reload )/;
+
+# no extra eval frame
+SKIP: {
+ skip "core bug makes this test crash", 2 if "$]" < 5.006001;
+ sub eval_test () { require_module("t::Eval") }
+ eval_test();
+}
+
1;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Module-Runtime-0.011/t/taint.t new/Module-Runtime-0.012/t/taint.t
--- old/Module-Runtime-0.011/t/taint.t 1970-01-01 01:00:00.000000000 +0100
+++ new/Module-Runtime-0.012/t/taint.t 2012-02-12 12:54:02.000000000 +0100
@@ -0,0 +1,24 @@
+#!perl -T
+# above line is required to enable taint mode
+
+use warnings;
+use strict;
+
+use Test::More tests => 5;
+
+BEGIN {
+ use_ok "Module::Runtime",
+ qw(require_module use_module use_package_optimistically);
+}
+
+my $tainted_modname = substr($ENV{PATH}, 0, 0) . "Module::Runtime";
+eval { require_module($tainted_modname) };
+like $@, qr/\AInsecure dependency /;
+eval { use_module($tainted_modname) };
+like $@, qr/\AInsecure dependency /;
+eval { use_package_optimistically($tainted_modname) };
+like $@, qr/\AInsecure dependency /;
+eval { require_module("Module::Runtime") };
+is $@, "";
+
+1;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Module-Runtime-0.011/t/um.t new/Module-Runtime-0.012/t/um.t
--- old/Module-Runtime-0.011/t/um.t 2011-10-25 00:15:17.000000000 +0200
+++ new/Module-Runtime-0.012/t/um.t 2012-02-12 12:54:02.000000000 +0100
@@ -1,7 +1,7 @@
use warnings;
use strict;
-use Test::More tests => 12;
+use Test::More tests => 29;
BEGIN { use_ok "Module::Runtime", qw(use_module); }
@@ -23,19 +23,66 @@
is($result, "Test::More");
# a module that we'll load now
-test_use_module("t::Mod0");
+test_use_module("t::Simple");
is($err, "");
-is($result, "t::Mod0");
+is($result, "t::Simple");
# re-requiring the module that we just loaded
-test_use_module("t::Mod0");
+test_use_module("t::Simple");
is($err, "");
-is($result, "t::Mod0");
+is($result, "t::Simple");
# module file scope sees scalar context regardless of calling context
-eval { use_module("t::Mod1"); 1 };
+eval { use_module("t::Context"); 1 };
is $@, "";
+# lexical hints don't leak through
+my $have_runtime_hint_hash = "$]" >= 5.009004;
+sub test_runtime_hint_hash($$) {
+ SKIP: {
+ skip "no runtime hint hash", 1 unless $have_runtime_hint_hash;
+ is +((caller(0))[10] || {})->{$_[0]}, $_[1];
+ }
+}
+SKIP: {
+ skip "core bug makes this test crash", 13
+ if "$]" >= 5.008 && "$]" < 5.008004;
+ skip "can't work around hint leakage in pure Perl", 13
+ if "$]" >= 5.009004 && "$]" < 5.010001;
+ $^H |= 0x20000 if "$]" < 5.009004;
+ $^H{"Module::Runtime/test_a"} = 1;
+ is $^H{"Module::Runtime/test_a"}, 1;
+ is $^H{"Module::Runtime/test_b"}, undef;
+ use_module("t::Hints");
+ is $^H{"Module::Runtime/test_a"}, 1;
+ is $^H{"Module::Runtime/test_b"}, undef;
+ t::Hints->import;
+ is $^H{"Module::Runtime/test_a"}, 1;
+ is $^H{"Module::Runtime/test_b"}, 1;
+ eval q{
+ BEGIN { $^H |= 0x20000; $^H{foo} = 1; }
+ BEGIN { is $^H{foo}, 1; }
+ main::test_runtime_hint_hash("foo", 1);
+ BEGIN { use_module("Math::BigInt"); }
+ BEGIN { is $^H{foo}, 1; }
+ main::test_runtime_hint_hash("foo", 1);
+ 1;
+ }; die $@ unless $@ eq "";
+}
+
+# broken module is visibly broken when re-required
+eval { use_module("t::Break") };
+like $@, qr/\A(?:broken |Attempt to reload )/;
+eval { use_module("t::Break") };
+like $@, qr/\A(?:broken |Attempt to reload )/;
+
+# no extra eval frame
+SKIP: {
+ skip "core bug makes this test crash", 2 if "$]" < 5.006001;
+ sub eval_test () { use_module("t::Eval") }
+ eval_test();
+}
+
# successful version check
test_use_module("Module::Runtime", 0.001);
is($err, "");
@@ -46,5 +93,3 @@
like($err, qr/^Module::Runtime version /);
1;
-
-1;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Module-Runtime-0.011/t/upo.t new/Module-Runtime-0.012/t/upo.t
--- old/Module-Runtime-0.011/t/upo.t 2011-10-25 00:15:17.000000000 +0200
+++ new/Module-Runtime-0.012/t/upo.t 2012-02-12 12:54:02.000000000 +0100
@@ -1,7 +1,7 @@
use warnings;
use strict;
-use Test::More tests => 15;
+use Test::More tests => 30;
BEGIN { use_ok "Module::Runtime", qw(use_package_optimistically); }
@@ -24,11 +24,51 @@
is $result, "Test::More";
# a module that we'll load now
-test_use_package_optimistically("t::Mod0");
+test_use_package_optimistically("t::Simple");
is $err, "";
-is $result, "t::Mod0";
+is $result, "t::Simple";
no strict "refs";
-ok defined(${"t::Mod0::VERSION"});
+ok defined(${"t::Simple::VERSION"});
+
+# lexical hints don't leak through
+my $have_runtime_hint_hash = "$]" >= 5.009004;
+sub test_runtime_hint_hash($$) {
+ SKIP: {
+ skip "no runtime hint hash", 1 unless $have_runtime_hint_hash;
+ is +((caller(0))[10] || {})->{$_[0]}, $_[1];
+ }
+}
+SKIP: {
+ skip "core bug makes this test crash", 13
+ if "$]" >= 5.008 && "$]" < 5.008004;
+ skip "can't work around hint leakage in pure Perl", 13
+ if "$]" >= 5.009004 && "$]" < 5.010001;
+ $^H |= 0x20000 if "$]" < 5.009004;
+ $^H{"Module::Runtime/test_a"} = 1;
+ is $^H{"Module::Runtime/test_a"}, 1;
+ is $^H{"Module::Runtime/test_b"}, undef;
+ use_package_optimistically("t::Hints");
+ is $^H{"Module::Runtime/test_a"}, 1;
+ is $^H{"Module::Runtime/test_b"}, undef;
+ t::Hints->import;
+ is $^H{"Module::Runtime/test_a"}, 1;
+ is $^H{"Module::Runtime/test_b"}, 1;
+ eval q{
+ BEGIN { $^H |= 0x20000; $^H{foo} = 1; }
+ BEGIN { is $^H{foo}, 1; }
+ main::test_runtime_hint_hash("foo", 1);
+ BEGIN { use_package_optimistically("Math::BigInt"); }
+ BEGIN { is $^H{foo}, 1; }
+ main::test_runtime_hint_hash("foo", 1);
+ 1;
+ }; die $@ unless $@ eq "";
+}
+
+# broken module is visibly broken when re-required
+eval { use_package_optimistically("t::Break") };
+like $@, qr/\A(?:broken |Attempt to reload )/;
+eval { use_package_optimistically("t::Break") };
+like $@, qr/\A(?:broken |Attempt to reload )/;
# successful version check
test_use_package_optimistically("Module::Runtime", 0.001);
@@ -40,11 +80,11 @@
like $err, qr/^Module::Runtime version /;
# even load module if $VERSION already set, unlike older behaviour
-$t::Mod1::VERSION = undef;
-test_use_package_optimistically("t::Mod1");
+$t::Context::VERSION = undef;
+test_use_package_optimistically("t::Context");
is $err, "";
-is $result, "t::Mod1";
-ok defined($t::Mod1::VERSION);
-ok $INC{"t/Mod1.pm"};
+is $result, "t::Context";
+ok defined($t::Context::VERSION);
+ok $INC{"t/Context.pm"};
1;
--
To unsubscribe, e-mail: opensuse-commit+unsubscribe@opensuse.org
For additional commands, e-mail: opensuse-commit+help@opensuse.org