develooper Front page | perl.perl5.changes | Postings from August 2022

[Perl/perl5] 2f6b24: Fix assorted bugs related to not having aUNIVERSA...

From:
Yves Orton via perl5-changes
Date:
August 1, 2022 12:38
Subject:
[Perl/perl5] 2f6b24: Fix assorted bugs related to not having aUNIVERSA...
Message ID:
Perl/perl5/push/refs/heads/yves/fix_universal_import_fragility/2f856a-2f6b24@github.com
  Branch: refs/heads/yves/fix_universal_import_fragility
  Home:   https://github.com/Perl/perl5
  Commit: 2f6b24b1db364577f75943ea003d98193c9b24c8
      https://github.com/Perl/perl5/commit/2f6b24b1db364577f75943ea003d98193c9b24c8
  Author: Yves Orton <demerphq@gmail.com>
  Date:   2022-08-01 (Mon, 01 Aug 2022)

  Changed paths:
    M gv.c
    M lib/UNIVERSAL.pm
    M t/op/universal.t
    M universal.c

  Log Message:
  -----------
  Fix assorted bugs related to not having a UNIVERSAL::import

Since perl 5.0 the methods "import" and "unimport" have been
special cased in gv.c (unimport was removed for a while) to
not produce errors if they are called. This is partly
because

    use Foo;

is defined to be

    BEGIN {
        require Foo;
        Foo->import();
    }

which would blow up if there is no import function defined in
Foo, for instance if it were defining a class and not a package
which exports modules.

This special case can be broken by simple code like

    \&UNIVERSAL::isa

which will create a stub function which then blows up when it is
used. Notably the module "autouse" which is shipped with perl will
trigger this behavior.

A related issue is that if you ask for a function to be exported
from a module that does not have support for exporting there is no
error, eg:

    use File::Spec qw(catfile);

will silently succeed without exporting a catfile function. This is
exacerbated on case insensitive file systems when the module name
is case-mismatched, the use succeeds but the export does not, leading
to confusion, eg:

    use LIst::Util qw(sum);

will load List::Util but will not export the sum function.

This patch defines UNIVERSAL::import() and UNIVERSAL::unimport()
functions. This prevents the "reference to \&UNIVERSAL::import" bug.
The function is defined to be a no-op unless arguments are passed into
the functions, in which case a warning is thrown indicating
that there is likely a problem. The error is modelled after the
error produced by calling a non-existent method or function:

    ./perl -Ilib -le'BEGIN{ my $import_sub= \&UNIVERSAL::import;}
        use File::Spec qw(catfile);'
    Attempt to call UNIVERSAL::import() with arguments via package File::Spec
        (Perhaps you forgot to load "File::Spec"?) at -e line 1.
    BEGIN failed--compilation aborted at -e line 1.

This fixes Issue #19416, Issue #19417, Issue #19418. See also Issue #19410 for
discussion, however this patch does not fix that case (it may not be
fixable.)





nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About