develooper Front page | perl.perl5.porters | Postings from September 2019

[perl #134459] Safe: wrap_code_ref hides all exceptions from thewrapped code

From:
Mathias Kende
Date:
September 28, 2019 20:29
Subject:
[perl #134459] Safe: wrap_code_ref hides all exceptions from thewrapped code
Message ID:
rt-4.0.24-7803-1569670596-1213.134459-75-0@perl.org
# New Ticket Created by  Mathias Kende 
# Please include the string:  [perl #134459]
# in the subject line of all future correspondence about this issue. 
# <URL: https://rt.perl.org/Ticket/Display.html?id=134459 >


This is a bug report for perl from mathias@cpan.org,
generated with the help of perlbug 1.41 running under perl 5.30.0.

Here is a small instroductory example:

$ perl -MSafe -e 'Safe->new()->reval("sub { die 1 }")->(); print "Should 
not be here ($@)\n"'

Which prints: Should not be here ()

What we see is that code refs returned by Safe::reval (which have been 
wrapped
by wrap_code_ref) will hide exceptions when they run (and $@ is not set 
either).

Reading the code of wrap_code_ref I think that the intent was for the 
exception
to be propagated. However this does not happen because the call to 
_safe_call_sv
hides the exceptions (and there is no actual eval call so $@ is not 
set).

The fix is, inside wrap_code_ref, to wrap the call to $sub->(@args) 
inside an
eval when building the $sub_with_args variable.

However there are two possible ways to handle this: either keep the 
current code
which will trigger an exception, or remove the die call. I think that 
the second
approach is safest as currently the errors are silently ignored so 
starting to
die could break existing code (while setting $@ is less disrupting 
because the
caller has to explicitly check its value for something to happen).

The second approach (setting $@ but not raising an exception), also has 
the
advantage that wrapped code will behave as the code run through reval, 
which is
more consistent with the documentation (the part that says that code 
references
returned by reval are wrapped to be executed as in the compartiment). 
Ideally
the wrapping should be propagated also to code reference returned 
recursivelly
from code reference returned by reval.

The proposed patch applies these fixes:
  - wrap the wrapped_code in an eval to catch exception;
  - do not raise these exceptions, let the user read them in $@;
  - recursively wrap code returned by wrapped code;
  - bump the version to 2.41;
  - document this behavior.
---
Flags:
     category=library
     severity=medium
     Type=Patch
     PatchStatus=HasPatch
     module=Safe
---
Site configuration information for perl 5.30.0:

Configured by Mathias at Sat Sep 28 12:50:24 CEST 2019.

Summary of my perl5 (revision 5 version 30 subversion 0) configuration:

   Platform:
     osname=cygwin
     osvers=3.0.7(0.33853)
     archname=cygwin-thread-multi
     uname='cygwin_nt-10.0 mathias-2013 3.0.7(0.33853) 2019-04-30 18:08 
x86_64 cygwin '
     config_args='-de 
-Dprefix=/cygdrive/d/Mathias/Cygwin/perl5/perlbrew/perls/perl-5.30.0 
-Aeval:scriptdir=/cygdrive/d/Mathias/Cygwin/perl5/perlbrew/perls/perl-5.30.0/bin'
     hint=recommended
     useposix=true
     d_sigaction=define
     useithreads=define
     usemultiplicity=define
     use64bitint=define
     use64bitall=define
     uselongdouble=undef
     usemymalloc=n
     default_inc_excludes_dot=define
     bincompat5005=undef
   Compiler:
     cc='gcc'
     ccflags ='-DPERL_USE_SAFE_PUTENV -U__STRICT_ANSI__ -D_GNU_SOURCE 
-fwrapv -fno-strict-aliasing -pipe -fstack-protector-strong 
-I/usr/local/include -D_FORTIFY_SOURCE=2'
     optimize='-O3'
     cppflags='-DPERL_USE_SAFE_PUTENV -U__STRICT_ANSI__ -D_GNU_SOURCE 
-fwrapv -fno-strict-aliasing -pipe -fstack-protector-strong 
-I/usr/local/include'
     ccversion=''
     gccversion='7.4.0'
     gccosandvers=''
     intsize=4
     longsize=8
     ptrsize=8
     doublesize=8
     byteorder=12345678
     doublekind=3
     d_longlong=define
     longlongsize=8
     d_longdbl=define
     longdblsize=16
     longdblkind=3
     ivtype='long'
     ivsize=8
     nvtype='double'
     nvsize=8
     Off_t='off_t'
     lseeksize=8
     alignbytes=8
     prototype=define
   Linker and Libraries:
     ld='g++'
     ldflags =' -Wl,--enable-auto-import -Wl,--export-all-symbols 
-Wl,--enable-auto-image-base -fstack-protector-strong -L/usr/local/lib'
     libpth=/usr/local/lib /usr/lib /lib
     libs=-lpthread -ldl
     perllibs=-lpthread -ldl
     libc=/usr/lib/libc.a
     so=dll
     useshrplib=true
     libperl=cygperl5_30_0.dll
     gnulibc_version=''
   Dynamic Linking:
     dlsrc=dl_dlopen.xs
     dlext=dll
     d_dlsymun=undef
     ccdlflags=' '
     cccdlflags=' '
     lddlflags=' --shared  -Wl,--enable-auto-import 
-Wl,--export-all-symbols -Wl,--enable-auto-image-base -L/usr/local/lib 
-fstack-protector-strong'


---
@INC for perl 5.30.0:
     
/cygdrive/d/Mathias/Cygwin/perl5/perlbrew/perls/perl-5.30.0/lib/site_perl/5.30.0/cygwin-thread-multi
     
/cygdrive/d/Mathias/Cygwin/perl5/perlbrew/perls/perl-5.30.0/lib/site_perl/5.30.0
     
/cygdrive/d/Mathias/Cygwin/perl5/perlbrew/perls/perl-5.30.0/lib/5.30.0/cygwin-thread-multi
     
/cygdrive/d/Mathias/Cygwin/perl5/perlbrew/perls/perl-5.30.0/lib/5.30.0

---
Environment for perl 5.30.0:
     HOME=/cygdrive/d/Mathias/Cygwin
     LANG=fr_FR.UTF-8
     LANGUAGE (unset)
     LD_LIBRARY_PATH (unset)
     LOGDIR (unset)
     
PATH=/cygdrive/d/Mathias/Cygwin/perl5/perlbrew/bin:/cygdrive/d/Mathias/Cygwin/perl5/perlbrew/perls/5.30/bin:/cygdrive/d/Mathias/Cygwin/gitbin:/usr/local/bin:/usr/bin:/cygdrive/c/Program 
Files (x86)/Common 
Files/Oracle/Java/javapath:/cygdrive/c/Python27:/cygdrive/c/Python27/Scripts:/cygdrive/c/Windows/system32:/cygdrive/c/Windows:/cygdrive/c/Windows/System32/Wbem:/cygdrive/c/Windows/System32/WindowsPowerShell/v1.0:/cygdrive/c/Program 
Files (x86)/NVIDIA 
Corporation/PhysX/Common:/cygdrive/c/WINDOWS/system32:/cygdrive/c/WINDOWS:/cygdrive/c/WINDOWS/System32/Wbem:/cygdrive/c/WINDOWS/System32/WindowsPowerShell/v1.0:/cygdrive/d/Programmes/Calibre2:/cygdrive/c/Program 
Files/Git/cmd:/cygdrive/d/Programmes/LLVM/bin:/cygdrive/d/Programmes/Heroku/bin:/cygdrive/c/Program 
Files 
(x86)/git/cmd:/cygdrive/d/Programmes/Skype/Phone:/cygdrive/c/WINDOWS/System32/OpenSSH:/cygdrive/c/Program 
Files/NVIDIA
Corporation/NVIDIA 
NvDLISR:/cygdrive/d/Programmes/VisiCut:/cygdrive/c/Program 
Files/Pandoc:/cygdrive/c/Users/Mathias/AppData/Local/Microsoft/WindowsApps:/usr/lib/lapack
     PERL5LIB=
     PERLBREW_LIB=
     
PERLBREW_MANPATH=/cygdrive/d/Mathias/Cygwin/perl5/perlbrew/perls/5.30/man
     
PERLBREW_PATH=/cygdrive/d/Mathias/Cygwin/perl5/perlbrew/bin:/cygdrive/d/Mathias/Cygwin/perl5/perlbrew/perls/5.30/bin
     PERLBREW_PERL=5.30
     PERLBREW_ROOT=/cygdrive/d/Mathias/Cygwin/perl5/perlbrew
     PERLBREW_SKIP_INIT=1
     PERLBREW_VERSION=0.86
     PERL_BADLANG (unset)
     PERL_LOCAL_LIB_ROOT=
     SHELL=/bin/bash


---
Attachment(s):
     safe.patch



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