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

[Perl/perl5] 14ad5a: sv.c - add a _QUOTEDPREFIX version of SVf,UTF8f, ...

From:
Yves Orton via perl5-changes
Date:
August 2, 2022 13:39
Subject:
[Perl/perl5] 14ad5a: sv.c - add a _QUOTEDPREFIX version of SVf,UTF8f, ...
Message ID:
Perl/perl5/push/refs/heads/yves/fix_universal_import_fragility/086ea7-7a7f23@github.com
  Branch: refs/heads/yves/fix_universal_import_fragility
  Home:   https://github.com/Perl/perl5
  Commit: 14ad5a85ec0616f35ca0d0b72e3a9a50c5556e6c
      https://github.com/Perl/perl5/commit/14ad5a85ec0616f35ca0d0b72e3a9a50c5556e6c
  Author: Yves Orton <demerphq@gmail.com>
  Date:   2022-08-02 (Tue, 02 Aug 2022)

  Changed paths:
    M dump.c
    M gv.c
    M mg.c
    M perl.h
    M pod/perlguts.pod
    M pp_sys.c
    M sv.c
    M t/op/method.t
    M t/porting/diag.t
    M t/uni/method.t

  Log Message:
  -----------
  sv.c - add a _QUOTEDPREFIX version of SVf, UTF8f, and HEKf for use in error messages.

These new formats are intended to be used in error messages where
we want to show the contents of a string without any possible
hidden characters not rendering in the error message, and where
it would be unreasonable to show every character of the string
if it is very long.

A good example would be when we want to say that a class name is
illegal. Consider:

    "Foo\0"->thing()

should not throw an error message about "Foo" being missing, the fact
there is a null in there should be visible to the developer.
Similarly if we had

    ("x" x 1000_000)->thing()

we also wouldn't want to throw a 1MB error message.

Currently this patch restricts it to the first 256 characters, but the
docs are such that we can change that if we wish, I suspect something
like 100 would be more reasonable. You can override the define
PERL_QUOTEDPREFIX_LEN to a longer value in Configure if you wish.

Example usage:

    other= newSVpvs("Some\0::Thing\n");
    sv_catpvf(msg_sv,"%" SVfQUOTEDPREFIX, SVfARG(other));

Should append

    "Some\0::Thing\n"

to the msg_sv. If it were very long it would have elipses suffixed:

    "whatever"...

This patch changes the error messages related to method calls. I haven't
changed every place that this could happen yet, just the main ones.


  Commit: 7a7f23c3c46f01ef058749105ebddaedc47e39e6
      https://github.com/Perl/perl5/commit/7a7f23c3c46f01ef058749105ebddaedc47e39e6
  Author: Yves Orton <demerphq@gmail.com>
  Date:   2022-08-02 (Tue, 02 Aug 2022)

  Changed paths:
    M gv.c
    M lib/UNIVERSAL.pm
    M pod/perldiag.pod
    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); # note the typo!

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.)


Compare: https://github.com/Perl/perl5/compare/086ea7bbb9d8...7a7f23c3c46f



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