Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

perl -wle '%::=();//' crash #9326

Closed
p5pRT opened this issue May 12, 2008 · 42 comments
Closed

perl -wle '%::=();//' crash #9326

p5pRT opened this issue May 12, 2008 · 42 comments

Comments

@p5pRT
Copy link

p5pRT commented May 12, 2008

Migrated from rt.perl.org#54044 (status was 'resolved')

Searchable as RT54044$

@p5pRT
Copy link
Author

p5pRT commented May 12, 2008

From @rurban

perl -wle '%​::=();//' crashes in all perl versions.

In regexec.c PL_replgv is empty after the whole symboltable is cleared
and then used as GV.

regexec.c​: SV* const oreplsv = GvSV(PL_replgv);
The gp pointer is 0x0, the type is BIND.

I would check for the empty gp pointer in PL_replgv and create an empty
but valid stash.
The problem is the semantically an empty stash should be allowed in
simple regex's. At least perl should not crash.

--
Reini Urban
http​://phpwiki.org/ http​://murbreak.at/

@p5pRT
Copy link
Author

p5pRT commented May 12, 2008

From @rurban

Just for reference​:
assertion "SvTYPE(shplep) == SVt_PVGV || SvTYPE(shplep) == SVt_PVLV"
failed​: file "regexec.c", line 2768

But I haven't decided yet how to fix #54044.
Error out or create a new empty stash just for the match operator.
--
Reini Urban

@p5pRT
Copy link
Author

p5pRT commented May 12, 2008

From [Unknown Contact. See original ticket]

Just for reference​:
assertion "SvTYPE(shplep) == SVt_PVGV || SvTYPE(shplep) == SVt_PVLV"
failed​: file "regexec.c", line 2768

But I haven't decided yet how to fix #54044.
Error out or create a new empty stash just for the match operator.
--
Reini Urban

@p5pRT
Copy link
Author

p5pRT commented May 12, 2008

@rurban - Status changed from 'new' to 'open'

@p5pRT
Copy link
Author

p5pRT commented May 12, 2008

From jettero@cpan.org

This is a bug report for perl from jettero@​cpan.org,
generated with the help of perlbug 1.35 running under perl v5.8.8.


I think it's a little silly to report, but I was encouraged to do so.
Apparently Perl should never segmentation fault from perl code.

%​::();// # <-- seems to crash the system

I'm not really the person that figured that out. It seems to be
known. I'm not really surprised that it causes problems,
although segmentation faults do seem a little extreme.

-paul



Flags​:
  category=core
  severity=low


Site configuration information for perl v5.8.8​:

Configured by Debian Project at Tue Dec 4 09​:07​:29 UTC 2007.

Summary of my perl5 (revision 5 version 8 subversion 8) configuration​:
  Platform​:
  osname=linux, osvers=2.6.15.7, archname=i486-linux-gnu-thread-multi
  uname='linux terranova 2.6.15.7 #1 smp thu jul 12 14​:27​:56 utc 2007 i686 gnulinux '
  config_args='-Dusethreads -Duselargefiles -Dccflags=-DDEBIAN -Dcccdlflags=-fPIC -Darchname=i486-linux-gnu -Dprefix=/usr -Dprivlib=/usr/share/perl/5.8 -Darchlib=/usr/lib/perl/5.8 -Dvendorprefix=/usr -Dvendorlib=/usr/share/perl5 -Dvendorarch=/usr/lib/perl5 -Dsiteprefix=/usr/local -Dsitelib=/usr/local/share/perl/5.8.8 -Dsitearch=/usr/local/lib/perl/5.8.8 -Dman1dir=/usr/share/man/man1 -Dman3dir=/usr/share/man/man3 -Dsiteman1dir=/usr/local/man/man1 -Dsiteman3dir=/usr/local/man/man3 -Dman1ext=1 -Dman3ext=3perl -Dpager=/usr/bin/sensible-pager -Uafs -Ud_csh -Uusesfio -Uusenm -Duseshrplib -Dlibperl=libperl.so.5.8.8 -Dd_dosuid -des'
  hint=recommended, useposix=true, d_sigaction=define
  usethreads=define use5005threads=undef useithreads=define usemultiplicity=define
  useperlio=define d_sfio=undef uselargefiles=define usesocks=undef
  use64bitint=undef use64bitall=undef uselongdouble=undef
  usemymalloc=n, bincompat5005=undef
  Compiler​:
  cc='cc', ccflags ='-D_REENTRANT -D_GNU_SOURCE -DTHREADS_HAVE_PIDS -DDEBIAN -fno-strict-aliasing -pipe -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64',
  optimize='-O2',
  cppflags='-D_REENTRANT -D_GNU_SOURCE -DTHREADS_HAVE_PIDS -DDEBIAN -fno-strict-aliasing -pipe -I/usr/local/include'
  ccversion='', gccversion='4.1.3 20070929 (prerelease) (Ubuntu 4.1.2-16ubuntu2)', gccosandvers=''
  intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=1234
  d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=12
  ivtype='long', ivsize=4, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=8
  alignbytes=4, prototype=define
  Linker and Libraries​:
  ld='cc', ldflags =' -L/usr/local/lib'
  libpth=/usr/local/lib /lib /usr/lib
  libs=-lgdbm -lgdbm_compat -ldb -ldl -lm -lpthread -lc -lcrypt
  perllibs=-ldl -lm -lpthread -lc -lcrypt
  libc=/lib/libc-2.6.1.so, so=so, useshrplib=true, libperl=libperl.so.5.8.8
  gnulibc_version='2.6.1'
  Dynamic Linking​:
  dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-Wl,-E'
  cccdlflags='-fPIC', lddlflags='-shared -L/usr/local/lib'

Locally applied patches​:
 


@​INC for perl v5.8.8​:
  /etc/perl
  /usr/local/lib/perl/5.8.8
  /usr/local/share/perl/5.8.8
  /usr/lib/perl5
  /usr/share/perl5
  /usr/lib/perl/5.8
  /usr/share/perl/5.8
  /usr/local/lib/site_perl
  .


Environment for perl v5.8.8​:
  HOME=/home/jettero
  LANG=C
  LANGUAGE (unset)
  LD_LIBRARY_PATH=
  LOGDIR (unset)
  PATH=/home/jettero/bin​:/home/jettero/sbin​:/home/jettero/code/povray/bin​:/home/jettero/.jbash/jbin​:/home/jettero/bin​:/home/jettero/sbin​:/bin​:/usr/bin​:/usr/local/bin​:/sbin​:/usr/sbin​:/usr/games/bin​:/usr/X11R6/bin​:/home/jettero/code/povray/bin​:/usr/local/sbin​:/usr/games
  PERL_BADLANG (unset)
  SHELL=/bin/bash

@p5pRT
Copy link
Author

p5pRT commented May 12, 2008

From @Abigail

On Mon, May 12, 2008 at 07​:57​:55PM +0200, Reini Urban wrote​:

perl -wle '%​::=();//' crashes in all perl versions.

In 5.10.0, I get​:

  $ perl -wle '%​::=();//'
  Use of uninitialized value $_ in pattern match (m//) at -e line 1.
  Assertion ((svtype)((shplep)->sv_flags & 0xff)) == SVt_PVGV || ((svtype)((shplep)->sv_flags & 0xff)) == SVt_PVLV failed​: file "regexec.c", line 2741 at -e line 1.
  $

Anything else gives me a segmentation fault.

Abigail

@p5pRT
Copy link
Author

p5pRT commented May 16, 2008

From @smpeters

On Mon, May 12, 2008 at 2​:30 PM, via RT jettero @​ cpan. org
<perlbug-followup@​perl.org> wrote​:

# New Ticket Created by jettero@​cpan.org
# Please include the string​: [perl #54050]
# in the subject line of all future correspondence about this issue.
# <URL​: http​://rt.perl.org/rt3/Ticket/Display.html?id=54050 >

This is a bug report for perl from jettero@​cpan.org,
generated with the help of perlbug 1.35 running under perl v5.8.8.

-----------------------------------------------------------------

I think it's a little silly to report, but I was encouraged to do so.
Apparently Perl should never segmentation fault from perl code.

%​::();// # <-- seems to crash the system

I'm not really the person that figured that out. It seems to be
known. I'm not really surprised that it causes problems,
although segmentation faults do seem a little extreme.

-paul

Actually, thanks for reporting the segfault. You should actually
report your the segfaults you run into. Otherwise, we have the fiasco
of a thread elsewhere with describing favorite way to cause Perl to
core dump.

To your problem, though, I cannot even get the code above to parse.
Do you have a larger example?

Steve Peters
steve@​fisharerojo.org

@p5pRT
Copy link
Author

p5pRT commented May 16, 2008

From @demerphq

2008/5/16 Steve Peters <steve@​fisharerojo.org>​:

On Mon, May 12, 2008 at 2​:30 PM, via RT jettero @​ cpan. org
<perlbug-followup@​perl.org> wrote​:

# New Ticket Created by jettero@​cpan.org
# Please include the string​: [perl #54050]
# in the subject line of all future correspondence about this issue.
# <URL​: http​://rt.perl.org/rt3/Ticket/Display.html?id=54050 >

This is a bug report for perl from jettero@​cpan.org,
generated with the help of perlbug 1.35 running under perl v5.8.8.

-----------------------------------------------------------------

I think it's a little silly to report, but I was encouraged to do so.
Apparently Perl should never segmentation fault from perl code.

%​::();// # <-- seems to crash the system

I'm not really the person that figured that out. It seems to be
known. I'm not really surprised that it causes problems,
although segmentation faults do seem a little extreme.

-paul

Actually, thanks for reporting the segfault. You should actually
report your the segfaults you run into. Otherwise, we have the fiasco
of a thread elsewhere with describing favorite way to cause Perl to
core dump.

To your problem, though, I cannot even get the code above to parse.
Do you have a larger example?

At one point someone was randomly generating code snippets and was
able to come up with a surprising number that would segv. Maybe we
should try to do more of that and flush out things like this.

Yves

--
perl -Mre=debug -e "/just|another|perl|hacker/"

@p5pRT
Copy link
Author

p5pRT commented May 16, 2008

From @nwc10

On Fri, May 16, 2008 at 10​:23​:43PM +0200, demerphq wrote​:

At one point someone was randomly generating code snippets and was
able to come up with a surprising number that would segv. Maybe we
should try to do more of that and flush out things like this.

Such as revisiting this?

http​://www.xray.mpe.mpg.de/mailing-lists/perl5-porters/2001-05/msg01959.html

Nicholas Clark

@p5pRT
Copy link
Author

p5pRT commented May 16, 2008

From @demerphq

2008/5/16 Nicholas Clark <nick@​ccl4.org>​:

On Fri, May 16, 2008 at 10​:23​:43PM +0200, demerphq wrote​:

At one point someone was randomly generating code snippets and was
able to come up with a surprising number that would segv. Maybe we
should try to do more of that and flush out things like this.

Such as revisiting this?

http​://www.xray.mpe.mpg.de/mailing-lists/perl5-porters/2001-05/msg01959.html

Yep. Thats the one. Wow. Quick on the draw aintchya. :-)

cheers,
yves

--
perl -Mre=debug -e "/just|another|perl|hacker/"

@p5pRT
Copy link
Author

p5pRT commented May 17, 2008

From p5p@perl.wizbit.be

Quoting Steve Peters <steve@​fisharerojo.org>​:

%​::();// # <-- seems to crash the system

To your problem, though, I cannot even get the code above to parse.
Do you have a larger example?

That's because the example is wrong.

It should be​: %​::=();//;

It got reported as​:

[perl #54044] perl -wle '%​::=();//' crash
http​://www.nntp.perl.org/group/perl.perl5.porters/2008/05/msg136747.html #
perl -wle '%​::=();//' crash (which was CC'ed to p5p - so the reply's
following on it aren't visible on RT)

[perl #54050] Segmentation Fault from ordinary, if unusual, perl code
[perl #54052] Re​: perl -wle '%​::=();//' crash

Kind regards,

Bram

@p5pRT
Copy link
Author

p5pRT commented May 18, 2008

From @rurban

jettero@​cpan.org (via RT) schrieb​:

# New Ticket Created by jettero@​cpan.org
# Please include the string​: [perl #54050]
# in the subject line of all future correspondence about this issue.
# <URL​: http​://rt.perl.org/rt3/Ticket/Display.html?id=54050 >

This is a bug report for perl from jettero@​cpan.org,
generated with the help of perlbug 1.35 running under perl v5.8.8.

-----------------------------------------------------------------

I think it's a little silly to report, but I was encouraged to do so.
Apparently Perl should never segmentation fault from perl code.

%​::();// # <-- seems to crash the system

I'm not really the person that figured that out. It seems to be
known. I'm not really surprised that it causes problems,
although segmentation faults do seem a little extreme.

That's a simple copy&paste error and a duplicate from
  [perl #54044] perl -wle '%​::=();//' crash,
which was reported by ton.iguana.be and discussed at #perl last week.

Please close this.

-paul

-----------------------------------------------------------------
---
Flags​:
category=core
severity=low
---
Site configuration information for perl v5.8.8​:

Configured by Debian Project at Tue Dec 4 09​:07​:29 UTC 2007.

Summary of my perl5 (revision 5 version 8 subversion 8) configuration​:
Platform​:
osname=linux, osvers=2.6.15.7, archname=i486-linux-gnu-thread-multi
uname='linux terranova 2.6.15.7 #1 smp thu jul 12 14​:27​:56 utc 2007 i686 gnulinux '
config_args='-Dusethreads -Duselargefiles -Dccflags=-DDEBIAN -Dcccdlflags=-fPIC -Darchname=i486-linux-gnu -Dprefix=/usr -Dprivlib=/usr/share/perl/5.8 -Darchlib=/usr/lib/perl/5.8 -Dvendorprefix=/usr -Dvendorlib=/usr/share/perl5 -Dvendorarch=/usr/lib/perl5 -Dsiteprefix=/usr/local -Dsitelib=/usr/local/share/perl/5.8.8 -Dsitearch=/usr/local/lib/perl/5.8.8 -Dman1dir=/usr/share/man/man1 -Dman3dir=/usr/share/man/man3 -Dsiteman1dir=/usr/local/man/man1 -Dsiteman3dir=/usr/local/man/man3 -Dman1ext=1 -Dman3ext=3perl -Dpager=/usr/bin/sensible-pager -Uafs -Ud_csh -Uusesfio -Uusenm -Duseshrplib -Dlibperl=libperl.so.5.8.8 -Dd_dosuid -des'
hint=recommended, useposix=true, d_sigaction=define
usethreads=define use5005threads=undef useithreads=define usemultiplicity=define
useperlio=define d_sfio=undef uselargefiles=define usesocks=undef
use64bitint=undef use64bitall=undef uselongdouble=undef
usemymalloc=n, bincompat5005=undef
Compiler​:
cc='cc', ccflags ='-D_REENTRANT -D_GNU_SOURCE -DTHREADS_HAVE_PIDS -DDEBIAN -fno-strict-aliasing -pipe -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64',
optimize='-O2',
cppflags='-D_REENTRANT -D_GNU_SOURCE -DTHREADS_HAVE_PIDS -DDEBIAN -fno-strict-aliasing -pipe -I/usr/local/include'
ccversion='', gccversion='4.1.3 20070929 (prerelease) (Ubuntu 4.1.2-16ubuntu2)', gccosandvers=''
intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=1234
d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=12
ivtype='long', ivsize=4, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=8
alignbytes=4, prototype=define
Linker and Libraries​:
ld='cc', ldflags =' -L/usr/local/lib'
libpth=/usr/local/lib /lib /usr/lib
libs=-lgdbm -lgdbm_compat -ldb -ldl -lm -lpthread -lc -lcrypt
perllibs=-ldl -lm -lpthread -lc -lcrypt
libc=/lib/libc-2.6.1.so, so=so, useshrplib=true, libperl=libperl.so.5.8.8
gnulibc_version='2.6.1'
Dynamic Linking​:
dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-Wl,-E'
cccdlflags='-fPIC', lddlflags='-shared -L/usr/local/lib'

Locally applied patches​:

---
@​INC for perl v5.8.8​:
/etc/perl
/usr/local/lib/perl/5.8.8
/usr/local/share/perl/5.8.8
/usr/lib/perl5
/usr/share/perl5
/usr/lib/perl/5.8
/usr/share/perl/5.8
/usr/local/lib/site_perl
.

---
Environment for perl v5.8.8​:
HOME=/home/jettero
LANG=C
LANGUAGE (unset)
LD_LIBRARY_PATH=
LOGDIR (unset)
PATH=/home/jettero/bin​:/home/jettero/sbin​:/home/jettero/code/povray/bin​:/home/jettero/.jbash/jbin​:/home/jettero/bin​:/home/jettero/sbin​:/bin​:/usr/bin​:/usr/local/bin​:/sbin​:/usr/sbin​:/usr/games/bin​:/usr/X11R6/bin​:/home/jettero/code/povray/bin​:/usr/local/sbin​:/usr/games
PERL_BADLANG (unset)
SHELL=/bin/bash

--
Reini Urban
http​://phpwiki.org/ http​://murbreak.at/

@p5pRT
Copy link
Author

p5pRT commented Mar 28, 2013

From @Hugmeir

Created by fraserb@gmail.com

perl -e 'undef %​::; chdir'

undef %​::; makes several functions[*] that use global variables
crash, e.g. eval due to PL_hintgv and chdir because of PL_envgv.

I haven't bisected it, but it starts crashing somewhere between
5.10.0 and 5.10.1.

This can be solved in a case by case basis by checking that
the variables are isGV() before using them, and recreating them
otherwise, but that is less than ideal.

* both evals, chdir, require, sort, .., stat, glob, print/say, warn,
plus a bunch of functions in sv.c. And there's several I missed.

Perl Info

Flags:
    category=core
    severity=medium

Site configuration information for perl 5.16.2:

Configured by hugmeir at Tue Nov 20 17:20:00 ART 2012.

Summary of my perl5 (revision 5 version 16 subversion 2) configuration:

  Platform:
    osname=linux, osvers=3.5.0-18-generic, archname=x86_64-linux-thread-multi
    uname='linux naw 3.5.0-18-generic #29-ubuntu smp fri oct 19
10:26:51 utc 2012 x86_64 x86_64 x86_64 gnulinux '
    config_args='-de
-Dprefix=/home/hugmeir/perl5/perlbrew/perls/perl-5.16.2 -DDEBUGGING
-Dusethreads -Doptimize=-g -O0 -ggdb3 -Uversiononly -Accflags=-Wall
-Wextra -Aeval:scriptdir=/home/hugmeir/perl5/perlbrew/perls/perl-5.16.2/bin'
    hint=recommended, useposix=true, d_sigaction=define
    useithreads=define, usemultiplicity=define
    useperlio=define, d_sfio=undef, uselargefiles=define, usesocks=undef
    use64bitint=define, use64bitall=define, uselongdouble=undef
    usemymalloc=n, bincompat5005=undef
  Compiler:
    cc='cc', ccflags ='-D_REENTRANT -D_GNU_SOURCE -Wall -Wextra
-DDEBUGGING -fno-strict-aliasing -pipe -fstack-protector
-I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64',
    optimize='-g -O0 -ggdb3',
    cppflags='-D_REENTRANT -D_GNU_SOURCE -Wall -Wextra -DDEBUGGING
-fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include'
    ccversion='', gccversion='4.7.2', gccosandvers=''
    intsize=4, longsize=8, ptrsize=8, doublesize=8, byteorder=12345678
    d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=16
    ivtype='long', ivsize=8, nvtype='double', nvsize=8, Off_t='off_t',
lseeksize=8
    alignbytes=8, prototype=define
  Linker and Libraries:
    ld='cc', ldflags =' -fstack-protector -L/usr/local/lib'
    libpth=/usr/local/lib /lib/x86_64-linux-gnu /lib/../lib
/usr/lib/x86_64-linux-gnu /usr/lib/../lib /lib /usr/lib
    libs=-lnsl -ldb -ldl -lm -lcrypt -lutil -lpthread -lc
    perllibs=-lnsl -ldl -lm -lcrypt -lutil -lpthread -lc
    libc=, so=so, useshrplib=false, libperl=libperl.a
    gnulibc_version='2.15'
  Dynamic Linking:
    dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-Wl,-E'
    cccdlflags='-fPIC', lddlflags='-shared -g -O0 -ggdb3
-L/usr/local/lib -fstack-protector'

Locally applied patches:



@INC for perl 5.16.2:
    /home/hugmeir/.perlbrew/libs/perl-5.16.2@all/lib/perl5/x86_64-linux-gnu-thread-multi
    /home/hugmeir/.perlbrew/libs/perl-5.16.2@all/lib/perl5/x86_64-linux-thread-multi
    /home/hugmeir/.perlbrew/libs/perl-5.16.2@all/lib/perl5
    /home/hugmeir/perl5/perlbrew/perls/perl-5.16.2/lib/site_perl/5.16.2/x86_64-linux-thread-multi
    /home/hugmeir/perl5/perlbrew/perls/perl-5.16.2/lib/site_perl/5.16.2
    /home/hugmeir/perl5/perlbrew/perls/perl-5.16.2/lib/5.16.2/x86_64-linux-thread-multi
    /home/hugmeir/perl5/perlbrew/perls/perl-5.16.2/lib/5.16.2
    .


Environment for perl 5.16.2:
    HOME=/home/hugmeir
    LANG=en_US.UTF-8
    LANGUAGE (unset)
    LD_LIBRARY_PATH (unset)
    LOGDIR (unset)
    PATH=/home/hugmeir/.rbenv/shims:/home/hugmeir/.rbenv/bin:/home/hugmeir/.perlbrew/libs/perl-5.16.2@all/bin:/home/hugmeir/perl5/perlbrew/bin:/home/hugmeir/perl5/perlbrew/perls/perl-5.16.2/bin:/home/hugmeir/.rbenv/shims:/home/hugmeir/.rbenv/bin:/usr/lib/lightdm/lightdm:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games
    PERL5LIB=/home/hugmeir/.perlbrew/libs/perl-5.16.2@all/lib/perl5/x86_64-linux-gnu-thread-multi:/home/hugmeir/.perlbrew/libs/perl-5.16.2@all/lib/perl5
    PERLBREW_BASHRC_VERSION=0.46
    PERLBREW_HOME=/home/hugmeir/.perlbrew
    PERLBREW_LIB=all
    PERLBREW_MANPATH=/home/hugmeir/.perlbrew/libs/perl-5.16.2@all/man:/home/hugmeir/perl5/perlbrew/perls/perl-5.16.2/man
    PERLBREW_PATH=/home/hugmeir/.perlbrew/libs/perl-5.16.2@all/bin:/home/hugmeir/perl5/perlbrew/bin:/home/hugmeir/perl5/perlbrew/perls/perl-5.16.2/bin
    PERLBREW_PERL=perl-5.16.2
    PERLBREW_ROOT=/home/hugmeir/perl5/perlbrew
    PERLBREW_VERSION=0.46
    PERL_BADLANG (unset)
    PERL_LOCAL_LIB_ROOT=/home/hugmeir/.perlbrew/libs/perl-5.16.2@all
    PERL_MB_OPT=--install_base /home/hugmeir/.perlbrew/libs/perl-5.16.2@all
    PERL_MM_OPT=INSTALL_BASE=/home/hugmeir/.perlbrew/libs/perl-5.16.2@all
    SHELL=/bin/bash

@p5pRT
Copy link
Author

p5pRT commented Mar 28, 2013

From @Hugmeir

On Thu, Mar 28, 2013 at 5​:34 PM, Brian Fraser <perlbug-followup@​perl.org> wrote​:

# New Ticket Created by Brian Fraser
# Please include the string​: [perl #117393]
# in the subject line of all future correspondence about this issue.
# <URL​: https://rt-archive.perl.org/perl5/Ticket/Display.html?id=117393 >

This is a bug report for perl from fraserb@​gmail.com,
generated with the help of perlbug 1.39 running under perl 5.16.2.

-----------------------------------------------------------------
[Please describe your issue here]

perl -e 'undef %​::; chdir'

undef %​::; makes several functions[*] that use global variables
crash, e.g. eval due to PL_hintgv and chdir because of PL_envgv.

I haven't bisected it, but it starts crashing somewhere between
5.10.0 and 5.10.1.

This can be solved in a case by case basis by checking that
the variables are isGV() before using them, and recreating them
otherwise, but that is less than ideal.

* both evals, chdir, require, sort, .., stat, glob, print/say, warn,
plus a bunch of functions in sv.c. And there's several I missed.

Actually, faulty test case. I was testing with 'perl -E "undef %​::"',
but that just automatically fails;
should've been using -e instead.
sort, warn, print & say seem to be working just fine, but the rest
still applies.

@p5pRT
Copy link
Author

p5pRT commented Mar 28, 2013

From @Hugmeir

On Thu, Mar 28, 2013 at 5​:42 PM, Brian Fraser <fraserbn@​gmail.com> wrote​:

On Thu, Mar 28, 2013 at 5​:34 PM, Brian Fraser <perlbug-followup@​perl.org> wrote​:

# New Ticket Created by Brian Fraser
# Please include the string​: [perl #117393]
# in the subject line of all future correspondence about this issue.
# <URL​: https://rt-archive.perl.org/perl5/Ticket/Display.html?id=117393 >

This is a bug report for perl from fraserb@​gmail.com,
generated with the help of perlbug 1.39 running under perl 5.16.2.

-----------------------------------------------------------------
[Please describe your issue here]

perl -e 'undef %​::; chdir'

undef %​::; makes several functions[*] that use global variables
crash, e.g. eval due to PL_hintgv and chdir because of PL_envgv.

I haven't bisected it, but it starts crashing somewhere between
5.10.0 and 5.10.1.

This can be solved in a case by case basis by checking that
the variables are isGV() before using them, and recreating them
otherwise, but that is less than ideal.

* both evals, chdir, require, sort, .., stat, glob, print/say, warn,
plus a bunch of functions in sv.c. And there's several I missed.

Actually, faulty test case. I was testing with 'perl -E "undef %​::"',
but that just automatically fails;
should've been using -e instead.
sort, warn, print & say seem to be working just fine, but the rest
still applies.

Attached file is just a handful of test cases for this.

@p5pRT
Copy link
Author

p5pRT commented Mar 28, 2013

From @Hugmeir

0001-Test-cases-for-117393.patch
From 2727b2614f0d89cc8cf837c32915f521b3a05865 Mon Sep 17 00:00:00 2001
From: Brian Fraser <fraserbn@gmail.com>
Date: Thu, 28 Mar 2013 18:37:38 -0300
Subject: [PATCH] Test cases for 117393

---
 t/op/undef.t |   13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/t/op/undef.t b/t/op/undef.t
index eafa6db..bfdb500 100644
--- a/t/op/undef.t
+++ b/t/op/undef.t
@@ -10,7 +10,7 @@ use strict;
 
 use vars qw(@ary %ary %hash);
 
-plan 85;
+plan 89;
 
 ok !defined($a);
 
@@ -176,3 +176,14 @@ sub PVBM () { 'foo' }
 my $pvbm = PVBM;
 undef $pvbm;
 ok !defined $pvbm;
+
+TODO: {
+   local $::TODO = '# [117393], undef %::; causes several crashes';
+   for my $op ( qw[ eval chdir() glob() require(strict) ] ) {
+      fresh_perl_like(
+         "my \$stdout = \\*STDOUT; undef \%::; $op; print { \$stdout } q{$op survived\n}",
+         qr/$op survived/,
+         "[117393] undef \%::; $op; doesn't crash"
+      );
+   }
+}
\ No newline at end of file
-- 
1.7.10.4

@p5pRT
Copy link
Author

p5pRT commented Mar 28, 2013

From @Hugmeir

On Thu, Mar 28, 2013 at 5​:34 PM, Brian Fraser <perlbug-followup@​perl.org> wrote​:

# New Ticket Created by Brian Fraser
# Please include the string​: [perl #117393]
# in the subject line of all future correspondence about this issue.
# <URL​: https://rt-archive.perl.org/perl5/Ticket/Display.html?id=117393 >

This is a bug report for perl from fraserb@​gmail.com,
generated with the help of perlbug 1.39 running under perl 5.16.2.

-----------------------------------------------------------------
[Please describe your issue here]

perl -e 'undef %​::; chdir'

undef %​::; makes several functions[*] that use global variables
crash, e.g. eval due to PL_hintgv and chdir because of PL_envgv.

I haven't bisected it, but it starts crashing somewhere between
5.10.0 and 5.10.1.

This can be solved in a case by case basis by checking that
the variables are isGV() before using them, and recreating them
otherwise, but that is less than ideal.

* both evals, chdir, require, sort, .., stat, glob, print/say, warn,
plus a bunch of functions in sv.c. And there's several I missed.

Pardons for the barrage of mails. Here's a related case, and how I
found all of this.
This crashes​:
  perl -e 'delete $​::{ENV}; chdir();'

But this does not​:
  perl -e 'BEGIN { delete $​::{ENV} }; chdir();'

This is because there's a call to gv_fetchpvs in toke.c that adds the
ENV gv if it doesn't exist​:
  case KEY_chdir​:
  /* may use HOME */
  (void)gv_fetchpvs("ENV", GV_ADD|GV_NOTQUAL, SVt_PVHV);
  UNI(OP_CHDIR);

That call has been there, some modifications in-between
notwithstanding, since 1993. I think that we should move it into
pp_chdir, or remove it entirely if the main issue in this ticket gets
resolved.

@p5pRT
Copy link
Author

p5pRT commented Apr 4, 2013

From @wolfsage

Hmm, is this https://rt-archive.perl.org/perl5/Ticket/Display.html?id=54044 again?

-- Matthew Horsfall (alh)

@p5pRT
Copy link
Author

p5pRT commented Apr 4, 2013

The RT System itself - Status changed from 'new' to 'open'

@p5pRT
Copy link
Author

p5pRT commented Apr 6, 2013

From @Hugmeir

On Thu, Apr 4, 2013 at 7​:07 PM, Matthew Horsfall via RT <
perlbug-followup@​perl.org> wrote​:

Hmm, is this https://rt-archive.perl.org/perl5/Ticket/Display.html?id=54044 again?

Looks like it, I think this ticket can be merged.

@p5pRT
Copy link
Author

p5pRT commented Apr 8, 2013

From @rurban

This is a bug report for perl from rurban@​cpanel.net,
generated with the help of perlbug 1.39 running under perl 5.14.2.

From 40bb0e6fc1252879ea0cd48a0267e4db5a2d6bc7 Mon Sep 17 00​:00​:00 2001
From​: Reini Urban <rurban@​x-ray.at>
Date​: Mon, 8 Apr 2013 12​:02​:17 -0500
Subject​: [PATCH] Error "Attempt to clear the %main​:: symbol table" [perl
#54044]
MIME-Version​: 1.0
Content-Type​: multipart/mixed; boundary="------------1.7.10.4"

This is a multi-part message in MIME format.
--------------1.7.10.4
Content-Type​: text/plain; charset=UTF-8; format=fixed
Content-Transfer-Encoding​: 8bit

Perl used to crash when the %main​:: stash is undef'ed or cleared and some
magic to be expected symbol is accessed, such as perl -wle '%​::=();//'
with PL_replgv.
Check both cases​: undef and assignment in hv_clear()/sv_clear().


hv.c | 4 ++++
pod/perldiag.pod | 9 +++++++++
sv.c | 2 ++
t/op/stash.t | 16 ++++++++++++----
t/op/undef.t | 16 +++++++++++++++-
5 files changed, 42 insertions(+), 5 deletions(-)

--------------1.7.10.4
Content-Type​: text/x-patch; name="0001-Error-Attempt-to-clear-the-main-symbol-table-perl-54.patch"
Content-Transfer-Encoding​: 8bit
Content-Disposition​: attachment; filename="0001-Error-Attempt-to-clear-the-main-symbol-table-perl-54.patch"

Inline Patch
diff --git a/hv.c b/hv.c
index ec1bfe8..4e93315 100644
--- a/hv.c
+++ b/hv.c
@@ -1469,6 +1469,8 @@ Perl_hv_clear(pTHX_ HV *hv)
     xhv = (XPVHV*)SvANY(hv);
 
     ENTER;
+    if ( hv == PL_defstash && PL_phase != PERL_PHASE_DESTRUCT )
+        croak("Attempt to clear the %main:: symbol table");
     SAVEFREESV(SvREFCNT_inc_simple_NN(hv));
     if (SvREADONLY(hv) && HvARRAY(hv) != NULL) {
 	/* restricted hash: convert all keys to placeholders */
@@ -1706,6 +1708,8 @@ Perl_hv_undef_flags(pTHX_ HV *hv, U32 flags)
     /* note that the code following prior to hfreeentries is duplicated
      * in sv_clear(), and changes here should be done there too */
     if (PL_phase != PERL_PHASE_DESTRUCT && (name = HvNAME(hv))) {
+        if (hv == PL_defstash)
+            croak("Attempt to clear the %main:: symbol table");
         if (PL_stashcache) {
             DEBUG_o(Perl_deb(aTHX_ "hv_undef_flags clearing PL_stashcache for '%"
                              HEKf"'\n", HvNAME_HEK(hv)));
diff --git a/pod/perldiag.pod b/pod/perldiag.pod
index f7eb662..f3fb28b 100644
--- a/pod/perldiag.pod
+++ b/pod/perldiag.pod
@@ -277,6 +277,15 @@ example by:
 
     bless $self, "$proto";
 
+=item Attempt to clear the %main:: symbol table
+
+(F) The failing code attempted to delete or set the C<%main::>
+symboltable, with something like C<%::=()> or C<undef %::>.  If you
+want to really clear all entries from the C<%main::> symboltable you
+need to do it manually, element by element.  But beware that a lot of
+magic main symbols entries are required, e.g.  for the regex engine,
+and all namespaces will be gone also, as they are keys of C<%main::>.
+
 =item Attempt to clear deleted array
 
 (S debugging) An array was assigned to when it was being freed.
diff --git a/sv.c b/sv.c
index 3736ba8..b095591 100644
--- a/sv.c
+++ b/sv.c
@@ -6120,6 +6120,8 @@ Perl_sv_clear(pTHX_ SV *const orig_sv)
 	    /* Free back-references before magic, in case the magic calls
 	     * Perl code that has weak references to sv. */
 	    if (type == SVt_PVHV) {
+                if (PL_phase != PERL_PHASE_DESTRUCT && hv == PL_defstash)
+                    croak("Attempt to clear the %main:: symbol table");
 		Perl_hv_kill_backrefs(aTHX_ MUTABLE_HV(sv));
 		if (SvMAGIC(sv))
 		    mg_free(sv);
diff --git a/t/op/stash.t b/t/op/stash.t
index fd5450e..fd9392c 100644
--- a/t/op/stash.t
+++ b/t/op/stash.t
@@ -7,12 +7,12 @@ BEGIN {
 
 BEGIN { require "./test.pl"; }
 
-plan( tests => 58 );
+plan( tests => 59 );
 
-# Used to segfault (bug #15479)
+# Used to segfault (bug #15479 and #54044)
 fresh_perl_like(
     '%:: = ""',
-    qr/Odd number of elements in hash assignment at - line 1\./,
+    qr/^Attempt to clear the %main:: symbol table at - line 1\./,
     { switches => [ '-w' ] },
     'delete $::{STDERR} and print a warning',
 );
@@ -60,7 +60,7 @@ package main;
     local $ENV{PERL_DESTRUCT_LEVEL} = 2;
     fresh_perl_is(
 		  'package A; sub a { // }; %::=""',
-		  '',
+		  'Attempt to clear the current symbol table at - line 1.',
 		  '',
 		  );
     # Variant of the above which creates an object that persists until global
@@ -336,3 +336,11 @@ ok eval '
      sub foo{};
      1
   ', 'no crashing or errors when clobbering the current package';
+
+{
+    # [perl #54004] disallow setting i.e. clearing %main::
+    eval '%::=()';
+    like $@, qr/^Attempt to clear the %main:: symbol table/;
+    eval '%main:: = ($_ = "")';
+    like $@, qr/^Attempt to clear the %main:: symbol table/;
+}
diff --git a/t/op/undef.t b/t/op/undef.t
index eafa6db..fa4cdfc 100644
--- a/t/op/undef.t
+++ b/t/op/undef.t
@@ -10,7 +10,7 @@ use strict;
 
 use vars qw(@ary %ary %hash);
 
-plan 85;
+plan 90;
 
 ok !defined($a);
 
@@ -176,3 +176,17 @@ sub PVBM () { 'foo' }
 my $pvbm = PVBM;
 undef $pvbm;
 ok !defined $pvbm;
+
+{
+    # [perl #54004] disallow undef %main::
+    eval 'undef %::';
+    like $@, qr/^Attempt to clear the %main:: symbol table/;
+    eval 'undef %main::';
+    like $@, qr/^Attempt to clear the %main:: symbol table/;
+    eval 'undef %main::main::';
+    like $@, qr/^Attempt to clear the %main:: symbol table/;
+    eval 'package A; undef %main::';
+    like $@, qr/^Attempt to clear the %main:: symbol table/;
+    eval 'package A; undef %::';
+    like $@, qr/^Attempt to clear the %main:: symbol table/;
+}

--------------1.7.10.4--


---
Flags:   category=core   severity=medium

This perlbug was built using Perl 5.17.3 - Mon Jul 30 16​:28​:27 CDT 2012
It is being executed now by Perl 5.14.2 - Wed Oct 26 17​:33​:43 CDT 2011.

Site configuration information for perl 5.14.2​:

Configured by rurban at Wed Oct 26 17​:33​:43 CDT 2011.

Summary of my perl5 (revision 5 version 14 subversion 2) configuration​:
 
  Platform​:
  osname=linux, osvers=3.0.0-1-amd64, archname=x86_64-linux
  uname='linux reini 3.0.0-1-amd64 #1 smp sun jul 24 02​:24​:44 utc 2011 x86_64 gnulinux '
  config_args='-de -Dmksymlinks -Duseshrplib -Dusedevel -Doptimize=-Os -Accflags=-msse4.2 -Accflags=-march=corei7 -Dcf_email=rurban@​cpanel.net -Dperladmin=rurban@​cpanel.net -Dstartperl=#!/usr/local/bin/perl5.14.2-nt -Dperlpath=/usr/local/bin/perl5.14.2-nt'
  hint=recommended, useposix=true, d_sigaction=define
  useithreads=undef, usemultiplicity=undef
  useperlio=define, d_sfio=undef, uselargefiles=define, usesocks=undef
  use64bitint=define, use64bitall=define, uselongdouble=undef
  usemymalloc=n, bincompat5005=undef
  Compiler​:
  cc='ccache cc', ccflags ='-msse4.2 -march=corei7 -fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64',
  optimize='-Os',
  cppflags='-msse4.2 -march=corei7 -fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include'
  ccversion='', gccversion='4.6.1', gccosandvers=''
  intsize=4, longsize=8, ptrsize=8, doublesize=8, byteorder=12345678
  d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=16
  ivtype='long', ivsize=8, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=8
  alignbytes=8, prototype=define
  Linker and Libraries​:
  ld='cc', ldflags ='-fstack-protector -L/usr/local/lib'
  libpth=/usr/local/lib /lib /usr/lib /usr/lib/x86_64-linux-gnu /lib64 /usr/lib64
  libs=-lnsl -ldl -lm -lcrypt -lutil -lc
  perllibs=-lnsl -ldl -lm -lcrypt -lutil -lc
  libc=, so=so, useshrplib=true, libperl=libperl.so
  gnulibc_version='2.13'
  Dynamic Linking​:
  dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-Wl,-E -Wl,-rpath,/usr/local/lib/perl5/5.14.2/x86_64-linux/CORE'
  cccdlflags='-fPIC', lddlflags='-shared -L/usr/local/lib -fstack-protector'

Locally applied patches​:
 


@​INC for perl 5.14.2​:
  /usr/local/lib/perl5/site_perl/5.14.2/x86_64-linux
  /usr/local/lib/perl5/site_perl/5.14.2
  /usr/local/lib/perl5/5.14.2/x86_64-linux
  /usr/local/lib/perl5/5.14.2
  .


Environment for perl 5.14.2​:
  HOME=/home/rurban
  LANG=en_US.UTF-8
  LANGUAGE (unset)
  LD_LIBRARY_PATH=/usr/src/perl/blead/perl-git
  LOGDIR (unset)
  PATH=/home/rurban/bin​:/usr/local/bin​:/usr/bin​:/bin​:/usr/local/games​:/usr/games
  PERL_BADLANG (unset)
  SHELL=/bin/bash

@p5pRT
Copy link
Author

p5pRT commented Apr 8, 2013

From @rurban

---------- Forwarded message ----------
From​: rurban@​cpanel.net via RT <perlbug-followup@​perl.org>
Date​: Mon, Apr 8, 2013 at 12​:07 PM
Subject​: [PATCH] 40bb0e6 Error "Attempt to clear the %main​:: symbol
table" [perl #54044]
To​: abigail@​abigail.be, fraserbn@​gmail.com, jettero@​cpan.org, rurban@​x-ray.at

This is a bug report for perl from rurban@​cpanel.net,
generated with the help of perlbug 1.39 running under perl 5.14.2.

From 40bb0e6fc1252879ea0cd48a0267e4db5a2d6bc7 Mon Sep 17 00​:00​:00 2001
From​: Reini Urban <rurban@​x-ray.at>
Date​: Mon, 8 Apr 2013 12​:02​:17 -0500
Subject​: [PATCH] Error "Attempt to clear the %main​:: symbol table" [perl
#54044]
MIME-Version​: 1.0
Content-Type​: multipart/mixed; boundary="------------1.7.10.4"

This is a multi-part message in MIME format.
--------------1.7.10.4
Content-Type​: text/plain; charset=UTF-8; format=fixed
Content-Transfer-Encoding​: 8bit

Perl used to crash when the %main​:: stash is undef'ed or cleared and some
magic to be expected symbol is accessed, such as perl -wle '%​::=();//'
with PL_replgv.
Check both cases​: undef and assignment in hv_clear()/sv_clear().


hv.c | 4 ++++
pod/perldiag.pod | 9 +++++++++
sv.c | 2 ++
t/op/stash.t | 16 ++++++++++++----
t/op/undef.t | 16 +++++++++++++++-
5 files changed, 42 insertions(+), 5 deletions(-)

--------------1.7.10.4
Content-Type​: text/x-patch;
name="0001-Error-Attempt-to-clear-the-main-symbol-table-perl-54.patch"
Content-Transfer-Encoding​: 8bit
Content-Disposition​: attachment;
filename="0001-Error-Attempt-to-clear-the-main-symbol-table-perl-54.patch"

Inline Patch
diff --git a/hv.c b/hv.c
index ec1bfe8..4e93315 100644
--- a/hv.c
+++ b/hv.c
@@ -1469,6 +1469,8 @@ Perl_hv_clear(pTHX_ HV *hv)
     xhv = (XPVHV*)SvANY(hv);

     ENTER;
+    if ( hv == PL_defstash && PL_phase != PERL_PHASE_DESTRUCT )
+        croak("Attempt to clear the %main:: symbol table");
     SAVEFREESV(SvREFCNT_inc_simple_NN(hv));
     if (SvREADONLY(hv) && HvARRAY(hv) != NULL) {
        /* restricted hash: convert all keys to placeholders */
@@ -1706,6 +1708,8 @@ Perl_hv_undef_flags(pTHX_ HV *hv, U32 flags)
     /* note that the code following prior to hfreeentries is duplicated
      * in sv_clear(), and changes here should be done there too */
     if (PL_phase != PERL_PHASE_DESTRUCT && (name = HvNAME(hv))) {
+        if (hv == PL_defstash)
+            croak("Attempt to clear the %main:: symbol table");
         if (PL_stashcache) {
             DEBUG_o(Perl_deb(aTHX_ "hv_undef_flags clearing
PL_stashcache for '%"   HEKf"'\\n"\, HvNAME\_HEK\(hv\)\)\);
Inline Patch
diff --git a/pod/perldiag.pod b/pod/perldiag.pod
index f7eb662..f3fb28b 100644
--- a/pod/perldiag.pod
+++ b/pod/perldiag.pod
@@ -277,6 +277,15 @@ example by:

     bless $self, "$proto";

+=item Attempt to clear the %main:: symbol table
+
+(F) The failing code attempted to delete or set the C<%main::>
+symboltable, with something like C<%::=()> or C<undef %::>.  If you
+want to really clear all entries from the C<%main::> symboltable you
+need to do it manually, element by element.  But beware that a lot of
+magic main symbols entries are required, e.g.  for the regex engine,
+and all namespaces will be gone also, as they are keys of C<%main::>.
+
 =item Attempt to clear deleted array

 (S debugging) An array was assigned to when it was being freed.
diff --git a/sv.c b/sv.c
index 3736ba8..b095591 100644
--- a/sv.c
+++ b/sv.c
@@ -6120,6 +6120,8 @@ Perl_sv_clear(pTHX_ SV *const orig_sv)
            /* Free back-references before magic, in case the magic calls
             * Perl code that has weak references to sv. */
            if (type == SVt_PVHV) {
+                if (PL_phase != PERL_PHASE_DESTRUCT && hv == PL_defstash)
+                    croak("Attempt to clear the %main:: symbol table");
                Perl_hv_kill_backrefs(aTHX_ MUTABLE_HV(sv));
                if (SvMAGIC(sv))
                    mg_free(sv);
diff --git a/t/op/stash.t b/t/op/stash.t
index fd5450e..fd9392c 100644
--- a/t/op/stash.t
+++ b/t/op/stash.t
@@ -7,12 +7,12 @@ BEGIN {

 BEGIN { require "./test.pl"; }

-plan( tests => 58 );
+plan( tests => 59 );

-# Used to segfault (bug #15479)
+# Used to segfault (bug #15479 and #54044)
 fresh_perl_like(
     '%:: = ""',
-    qr/Odd number of elements in hash assignment at - line 1\./,
+    qr/^Attempt to clear the %main:: symbol table at - line 1\./,
     { switches => [ '-w' ] },
     'delete $::{STDERR} and print a warning',
 );
@@ -60,7 +60,7 @@ package main;
     local $ENV{PERL_DESTRUCT_LEVEL} = 2;
     fresh_perl_is(
                  'package A; sub a { // }; %::=""',
-                 '',
+                 'Attempt to clear the current symbol table at - line 1.',
                  '',
                  );
     # Variant of the above which creates an object that persists until global
@@ -336,3 +336,11 @@ ok eval '
      sub foo{};
      1
   ', 'no crashing or errors when clobbering the current package';
+
+{
+    # [perl #54004] disallow setting i.e. clearing %main::
+    eval '%::=()';
+    like $@, qr/^Attempt to clear the %main:: symbol table/;
+    eval '%main:: = ($_ = "")';
+    like $@, qr/^Attempt to clear the %main:: symbol table/;
+}
diff --git a/t/op/undef.t b/t/op/undef.t
index eafa6db..fa4cdfc 100644
--- a/t/op/undef.t
+++ b/t/op/undef.t
@@ -10,7 +10,7 @@ use strict;

 use vars qw(@ary %ary %hash);

-plan 85;
+plan 90;

 ok !defined($a);

@@ -176,3 +176,17 @@ sub PVBM () { 'foo' }
 my $pvbm = PVBM;
 undef $pvbm;
 ok !defined $pvbm;
+
+{
+    # [perl #54004] disallow undef %main::
+    eval 'undef %::';
+    like $@, qr/^Attempt to clear the %main:: symbol table/;
+    eval 'undef %main::';
+    like $@, qr/^Attempt to clear the %main:: symbol table/;
+    eval 'undef %main::main::';
+    like $@, qr/^Attempt to clear the %main:: symbol table/;
+    eval 'package A; undef %main::';
+    like $@, qr/^Attempt to clear the %main:: symbol table/;
+    eval 'package A; undef %::';
+    like $@, qr/^Attempt to clear the %main:: symbol table/;
+}

--------------1.7.10.4--


---
Flags:   category=core   severity=medium

This perlbug was built using Perl 5.17.3 - Mon Jul 30 16​:28​:27 CDT 2012
It is being executed now by Perl 5.14.2 - Wed Oct 26 17​:33​:43 CDT 2011.

Site configuration information for perl 5.14.2​:

Configured by rurban at Wed Oct 26 17​:33​:43 CDT 2011.

Summary of my perl5 (revision 5 version 14 subversion 2) configuration​:

  Platform​:
  osname=linux, osvers=3.0.0-1-amd64, archname=x86_64-linux
  uname='linux reini 3.0.0-1-amd64 #1 smp sun jul 24 02​:24​:44 utc
2011 x86_64 gnulinux '
  config_args='-de -Dmksymlinks -Duseshrplib -Dusedevel
-Doptimize=-Os -Accflags=-msse4.2 -Accflags=-march=corei7
-Dcf_email=rurban@​cpanel.net -Dperladmin=rurban@​cpanel.net
-Dstartperl=#!/usr/local/bin/perl5.14.2-nt
-Dperlpath=/usr/local/bin/perl5.14.2-nt'
  hint=recommended, useposix=true, d_sigaction=define
  useithreads=undef, usemultiplicity=undef
  useperlio=define, d_sfio=undef, uselargefiles=define, usesocks=undef
  use64bitint=define, use64bitall=define, uselongdouble=undef
  usemymalloc=n, bincompat5005=undef
  Compiler​:
  cc='ccache cc', ccflags ='-msse4.2 -march=corei7
-fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include
-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64',
  optimize='-Os',
  cppflags='-msse4.2 -march=corei7 -fno-strict-aliasing -pipe
-fstack-protector -I/usr/local/include'
  ccversion='', gccversion='4.6.1', gccosandvers=''
  intsize=4, longsize=8, ptrsize=8, doublesize=8, byteorder=12345678
  d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=16
  ivtype='long', ivsize=8, nvtype='double', nvsize=8, Off_t='off_t',
lseeksize=8
  alignbytes=8, prototype=define
  Linker and Libraries​:
  ld='cc', ldflags ='-fstack-protector -L/usr/local/lib'
  libpth=/usr/local/lib /lib /usr/lib /usr/lib/x86_64-linux-gnu
/lib64 /usr/lib64
  libs=-lnsl -ldl -lm -lcrypt -lutil -lc
  perllibs=-lnsl -ldl -lm -lcrypt -lutil -lc
  libc=, so=so, useshrplib=true, libperl=libperl.so
  gnulibc_version='2.13'
  Dynamic Linking​:
  dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-Wl,-E
-Wl,-rpath,/usr/local/lib/perl5/5.14.2/x86_64-linux/CORE'
  cccdlflags='-fPIC', lddlflags='-shared -L/usr/local/lib -fstack-protector'

Locally applied patches​:


@​INC for perl 5.14.2​:
  /usr/local/lib/perl5/site_perl/5.14.2/x86_64-linux
  /usr/local/lib/perl5/site_perl/5.14.2
  /usr/local/lib/perl5/5.14.2/x86_64-linux
  /usr/local/lib/perl5/5.14.2
  .


Environment for perl 5.14.2​:
  HOME=/home/rurban
  LANG=en_US.UTF-8
  LANGUAGE (unset)
  LD_LIBRARY_PATH=/usr/src/perl/blead/perl-git
  LOGDIR (unset)
  PATH=/home/rurban/bin​:/usr/local/bin​:/usr/bin​:/bin​:/usr/local/games​:/usr/games
  PERL_BADLANG (unset)
  SHELL=/bin/bash

--
Reini Urban
http​://cpanel.net/ http​://www.perl-compiler.org/

@p5pRT
Copy link
Author

p5pRT commented Apr 8, 2013

From @rurban

Oops, previous patch had a last minute typo in it (sv vs hv)

Use this one instead.
I'm smoking it now with my cpan subset to catch possible
%{"$pkg\​::"}=... cases with empty $pkg.

On Mon Apr 08 10​:22​:20 2013, rurban wrote​:

---------- Forwarded message ----------
From​: rurban@​cpanel.net via RT <perlbug-followup@​perl.org>
Date​: Mon, Apr 8, 2013 at 12​:07 PM
Subject​: [PATCH] 40bb0e6 Error "Attempt to clear the %main​:: symbol
table" [perl #54044]
To​: abigail@​abigail.be, fraserbn@​gmail.com, jettero@​cpan.org,
rurban@​x-ray.at
Subject​: [PATCH] Error "Attempt to clear the %main​:: symbol table"
[perl #54044]

--
Reini Urban

@p5pRT
Copy link
Author

p5pRT commented Apr 8, 2013

From @rurban

0001-Error-Attempt-to-clear-the-main-symbol-table-perl-54.patch
From 54fb05a34547efb1a4c76db0f77d5d154be13cde Mon Sep 17 00:00:00 2001
From: Reini Urban <rurban@x-ray.at>
Date: Mon, 8 Apr 2013 12:02:17 -0500
Subject: [PATCH] Error "Attempt to clear the %main:: symbol table" [perl
 #54044]
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="------------1.7.10.4"

This is a multi-part message in MIME format.
--------------1.7.10.4
Content-Type: text/plain; charset=UTF-8; format=fixed
Content-Transfer-Encoding: 8bit


Perl used to crash when the %main:: stash is undef'ed or cleared and some
magic to be expected symbol is accessed, such as perl -wle '%::=();//'
with PL_replgv.
Check both cases: undef and assignment in hv_clear()/sv_clear().
---
 hv.c             |    4 ++++
 pod/perldiag.pod |    9 +++++++++
 sv.c             |    2 ++
 t/op/stash.t     |   16 ++++++++++++----
 t/op/undef.t     |   16 +++++++++++++++-
 5 files changed, 42 insertions(+), 5 deletions(-)


--------------1.7.10.4
Content-Type: text/x-patch; name="0001-Error-Attempt-to-clear-the-main-symbol-table-perl-54.patch"
Content-Transfer-Encoding: 8bit
Content-Disposition: attachment; filename="0001-Error-Attempt-to-clear-the-main-symbol-table-perl-54.patch"

diff --git a/hv.c b/hv.c
index ec1bfe8..4e93315 100644
--- a/hv.c
+++ b/hv.c
@@ -1469,6 +1469,8 @@ Perl_hv_clear(pTHX_ HV *hv)
     xhv = (XPVHV*)SvANY(hv);
 
     ENTER;
+    if ( hv == PL_defstash && PL_phase != PERL_PHASE_DESTRUCT )
+        croak("Attempt to clear the %main:: symbol table");
     SAVEFREESV(SvREFCNT_inc_simple_NN(hv));
     if (SvREADONLY(hv) && HvARRAY(hv) != NULL) {
 	/* restricted hash: convert all keys to placeholders */
@@ -1706,6 +1708,8 @@ Perl_hv_undef_flags(pTHX_ HV *hv, U32 flags)
     /* note that the code following prior to hfreeentries is duplicated
      * in sv_clear(), and changes here should be done there too */
     if (PL_phase != PERL_PHASE_DESTRUCT && (name = HvNAME(hv))) {
+        if (hv == PL_defstash)
+            croak("Attempt to clear the %main:: symbol table");
         if (PL_stashcache) {
             DEBUG_o(Perl_deb(aTHX_ "hv_undef_flags clearing PL_stashcache for '%"
                              HEKf"'\n", HvNAME_HEK(hv)));
diff --git a/pod/perldiag.pod b/pod/perldiag.pod
index f7eb662..f3fb28b 100644
--- a/pod/perldiag.pod
+++ b/pod/perldiag.pod
@@ -277,6 +277,15 @@ example by:
 
     bless $self, "$proto";
 
+=item Attempt to clear the %main:: symbol table
+
+(F) The failing code attempted to delete or set the C<%main::>
+symboltable, with something like C<%::=()> or C<undef %::>.  If you
+want to really clear all entries from the C<%main::> symboltable you
+need to do it manually, element by element.  But beware that a lot of
+magic main symbols entries are required, e.g.  for the regex engine,
+and all namespaces will be gone also, as they are keys of C<%main::>.
+
 =item Attempt to clear deleted array
 
 (S debugging) An array was assigned to when it was being freed.
diff --git a/sv.c b/sv.c
index 3736ba8..ffdb48d 100644
--- a/sv.c
+++ b/sv.c
@@ -6120,6 +6120,8 @@ Perl_sv_clear(pTHX_ SV *const orig_sv)
 	    /* Free back-references before magic, in case the magic calls
 	     * Perl code that has weak references to sv. */
 	    if (type == SVt_PVHV) {
+                if (PL_phase != PERL_PHASE_DESTRUCT && MUTABLE_HV(sv) == PL_defstash)
+                    croak("Attempt to clear the %main:: symbol table");
 		Perl_hv_kill_backrefs(aTHX_ MUTABLE_HV(sv));
 		if (SvMAGIC(sv))
 		    mg_free(sv);
diff --git a/t/op/stash.t b/t/op/stash.t
index fd5450e..fd9392c 100644
--- a/t/op/stash.t
+++ b/t/op/stash.t
@@ -7,12 +7,12 @@ BEGIN {
 
 BEGIN { require "./test.pl"; }
 
-plan( tests => 58 );
+plan( tests => 59 );
 
-# Used to segfault (bug #15479)
+# Used to segfault (bug #15479 and #54044)
 fresh_perl_like(
     '%:: = ""',
-    qr/Odd number of elements in hash assignment at - line 1\./,
+    qr/^Attempt to clear the %main:: symbol table at - line 1\./,
     { switches => [ '-w' ] },
     'delete $::{STDERR} and print a warning',
 );
@@ -60,7 +60,7 @@ package main;
     local $ENV{PERL_DESTRUCT_LEVEL} = 2;
     fresh_perl_is(
 		  'package A; sub a { // }; %::=""',
-		  '',
+		  'Attempt to clear the current symbol table at - line 1.',
 		  '',
 		  );
     # Variant of the above which creates an object that persists until global
@@ -336,3 +336,11 @@ ok eval '
      sub foo{};
      1
   ', 'no crashing or errors when clobbering the current package';
+
+{
+    # [perl #54004] disallow setting i.e. clearing %main::
+    eval '%::=()';
+    like $@, qr/^Attempt to clear the %main:: symbol table/;
+    eval '%main:: = ($_ = "")';
+    like $@, qr/^Attempt to clear the %main:: symbol table/;
+}
diff --git a/t/op/undef.t b/t/op/undef.t
index eafa6db..fa4cdfc 100644
--- a/t/op/undef.t
+++ b/t/op/undef.t
@@ -10,7 +10,7 @@ use strict;
 
 use vars qw(@ary %ary %hash);
 
-plan 85;
+plan 90;
 
 ok !defined($a);
 
@@ -176,3 +176,17 @@ sub PVBM () { 'foo' }
 my $pvbm = PVBM;
 undef $pvbm;
 ok !defined $pvbm;
+
+{
+    # [perl #54004] disallow undef %main::
+    eval 'undef %::';
+    like $@, qr/^Attempt to clear the %main:: symbol table/;
+    eval 'undef %main::';
+    like $@, qr/^Attempt to clear the %main:: symbol table/;
+    eval 'undef %main::main::';
+    like $@, qr/^Attempt to clear the %main:: symbol table/;
+    eval 'package A; undef %main::';
+    like $@, qr/^Attempt to clear the %main:: symbol table/;
+    eval 'package A; undef %::';
+    like $@, qr/^Attempt to clear the %main:: symbol table/;
+}

--------------1.7.10.4--


@p5pRT
Copy link
Author

p5pRT commented Apr 8, 2013

From @rurban

On Mon Apr 08 11​:36​:23 2013, rurban wrote​:

Oops, previous patch had a last minute typo in it (sv vs hv)

Use this one instead.
I'm smoking it now with my cpan subset to catch possible
%{"$pkg\​::"}=... cases with empty $pkg.

Smoked my cpan successfully with this revised patch.

--
Reini Urban

@p5pRT
Copy link
Author

p5pRT commented Apr 8, 2013

From @rurban

0001-Error-Attempt-to-clear-the-main-symbol-table-perl-54.patch
From 7ae6b9039b8f7d695148312ef46e4cc841e45d57 Mon Sep 17 00:00:00 2001
From: Reini Urban <rurban@x-ray.at>
Date: Mon, 8 Apr 2013 12:02:17 -0500
Subject: [PATCH] Error "Attempt to clear the %main:: symbol table" [perl
 #54044]
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="------------1.7.10.4"

This is a multi-part message in MIME format.
--------------1.7.10.4
Content-Type: text/plain; charset=UTF-8; format=fixed
Content-Transfer-Encoding: 8bit


Perl used to crash when the %main:: stash is undef'ed or cleared and some
magic to be expected symbol is accessed, such as perl -wle '%::=();//'
with PL_replgv.
Check both cases: undef and assignment in hv_clear()/sv_clear().
---
 hv.c             |    4 ++++
 pod/perldiag.pod |    9 +++++++++
 sv.c             |    2 ++
 t/op/stash.t     |   18 +++++++++++++-----
 t/op/undef.t     |   16 +++++++++++++++-
 5 files changed, 43 insertions(+), 6 deletions(-)


--------------1.7.10.4
Content-Type: text/x-patch; name="0001-Error-Attempt-to-clear-the-main-symbol-table-perl-54.patch"
Content-Transfer-Encoding: 8bit
Content-Disposition: attachment; filename="0001-Error-Attempt-to-clear-the-main-symbol-table-perl-54.patch"

diff --git a/hv.c b/hv.c
index ec1bfe8..4e93315 100644
--- a/hv.c
+++ b/hv.c
@@ -1469,6 +1469,8 @@ Perl_hv_clear(pTHX_ HV *hv)
     xhv = (XPVHV*)SvANY(hv);
 
     ENTER;
+    if ( hv == PL_defstash && PL_phase != PERL_PHASE_DESTRUCT )
+        croak("Attempt to clear the %main:: symbol table");
     SAVEFREESV(SvREFCNT_inc_simple_NN(hv));
     if (SvREADONLY(hv) && HvARRAY(hv) != NULL) {
 	/* restricted hash: convert all keys to placeholders */
@@ -1706,6 +1708,8 @@ Perl_hv_undef_flags(pTHX_ HV *hv, U32 flags)
     /* note that the code following prior to hfreeentries is duplicated
      * in sv_clear(), and changes here should be done there too */
     if (PL_phase != PERL_PHASE_DESTRUCT && (name = HvNAME(hv))) {
+        if (hv == PL_defstash)
+            croak("Attempt to clear the %main:: symbol table");
         if (PL_stashcache) {
             DEBUG_o(Perl_deb(aTHX_ "hv_undef_flags clearing PL_stashcache for '%"
                              HEKf"'\n", HvNAME_HEK(hv)));
diff --git a/pod/perldiag.pod b/pod/perldiag.pod
index f7eb662..f3fb28b 100644
--- a/pod/perldiag.pod
+++ b/pod/perldiag.pod
@@ -277,6 +277,15 @@ example by:
 
     bless $self, "$proto";
 
+=item Attempt to clear the %main:: symbol table
+
+(F) The failing code attempted to delete or set the C<%main::>
+symboltable, with something like C<%::=()> or C<undef %::>.  If you
+want to really clear all entries from the C<%main::> symboltable you
+need to do it manually, element by element.  But beware that a lot of
+magic main symbols entries are required, e.g.  for the regex engine,
+and all namespaces will be gone also, as they are keys of C<%main::>.
+
 =item Attempt to clear deleted array
 
 (S debugging) An array was assigned to when it was being freed.
diff --git a/sv.c b/sv.c
index 3736ba8..ffdb48d 100644
--- a/sv.c
+++ b/sv.c
@@ -6120,6 +6120,8 @@ Perl_sv_clear(pTHX_ SV *const orig_sv)
 	    /* Free back-references before magic, in case the magic calls
 	     * Perl code that has weak references to sv. */
 	    if (type == SVt_PVHV) {
+                if (PL_phase != PERL_PHASE_DESTRUCT && MUTABLE_HV(sv) == PL_defstash)
+                    croak("Attempt to clear the %main:: symbol table");
 		Perl_hv_kill_backrefs(aTHX_ MUTABLE_HV(sv));
 		if (SvMAGIC(sv))
 		    mg_free(sv);
diff --git a/t/op/stash.t b/t/op/stash.t
index fd5450e..a5bea3e 100644
--- a/t/op/stash.t
+++ b/t/op/stash.t
@@ -7,12 +7,12 @@ BEGIN {
 
 BEGIN { require "./test.pl"; }
 
-plan( tests => 58 );
+plan( tests => 60 );
 
-# Used to segfault (bug #15479)
+# Used to segfault (bug #15479 and #54044)
 fresh_perl_like(
     '%:: = ""',
-    qr/Odd number of elements in hash assignment at - line 1\./,
+    qr/^Attempt to clear the %main:: symbol table at - line 1\./m,
     { switches => [ '-w' ] },
     'delete $::{STDERR} and print a warning',
 );
@@ -60,14 +60,14 @@ package main;
     local $ENV{PERL_DESTRUCT_LEVEL} = 2;
     fresh_perl_is(
 		  'package A; sub a { // }; %::=""',
-		  '',
+		  'Attempt to clear the %main:: symbol table at - line 1.',
 		  '',
 		  );
     # Variant of the above which creates an object that persists until global
     # destruction.
     fresh_perl_is(
 		  'use Exporter; package A; sub a { // }; %::=""',
-		  '',
+		  'Attempt to clear the %main:: symbol table at - line 1.',
 		  '',
 		  );
 }
@@ -336,3 +336,11 @@ ok eval '
      sub foo{};
      1
   ', 'no crashing or errors when clobbering the current package';
+
+{
+    # [perl #54004] disallow setting i.e. clearing %main::
+    eval '%::=()';
+    like $@, qr/^Attempt to clear the %main:: symbol table/;
+    eval '%main:: = ($_ = "")';
+    like $@, qr/^Attempt to clear the %main:: symbol table/;
+}
diff --git a/t/op/undef.t b/t/op/undef.t
index eafa6db..fa4cdfc 100644
--- a/t/op/undef.t
+++ b/t/op/undef.t
@@ -10,7 +10,7 @@ use strict;
 
 use vars qw(@ary %ary %hash);
 
-plan 85;
+plan 90;
 
 ok !defined($a);
 
@@ -176,3 +176,17 @@ sub PVBM () { 'foo' }
 my $pvbm = PVBM;
 undef $pvbm;
 ok !defined $pvbm;
+
+{
+    # [perl #54004] disallow undef %main::
+    eval 'undef %::';
+    like $@, qr/^Attempt to clear the %main:: symbol table/;
+    eval 'undef %main::';
+    like $@, qr/^Attempt to clear the %main:: symbol table/;
+    eval 'undef %main::main::';
+    like $@, qr/^Attempt to clear the %main:: symbol table/;
+    eval 'package A; undef %main::';
+    like $@, qr/^Attempt to clear the %main:: symbol table/;
+    eval 'package A; undef %::';
+    like $@, qr/^Attempt to clear the %main:: symbol table/;
+}

--------------1.7.10.4--


@p5pRT
Copy link
Author

p5pRT commented Apr 9, 2013

From @tsee

On 04/08/2013 11​:27 PM, Reini Urban via RT wrote​:

On Mon Apr 08 11​:36​:23 2013, rurban wrote​:

Oops, previous patch had a last minute typo in it (sv vs hv)

Use this one instead.
I'm smoking it now with my cpan subset to catch possible
%{"$pkg\​::"}=... cases with empty $pkg.

Smoked my cpan successfully with this revised patch.

FWIW if nobody beats me to it or strongly objects I'll try to remember
to apply this after 5.18. Feel free to remind me then as well.

--Steffen

@p5pRT
Copy link
Author

p5pRT commented Apr 9, 2013

From @Hugmeir

On Tue, Apr 9, 2013 at 2​:03 AM, Steffen Mueller <smueller@​cpan.org> wrote​:

On 04/08/2013 11​:27 PM, Reini Urban via RT wrote​:

On Mon Apr 08 11​:36​:23 2013, rurban wrote​:

Oops, previous patch had a last minute typo in it (sv vs hv)

Use this one instead.
I'm smoking it now with my cpan subset to catch possible
%{"$pkg\​::"}=... cases with empty $pkg.

Smoked my cpan successfully with this revised patch.

FWIW if nobody beats me to it or strongly objects I'll try to remember to
apply this after 5.18. Feel free to remind me then as well.

--Steffen

My soft objection is that it doesn't really solve the underlaying issue, it
just hides it; perl -e 'delete $​::{ENV}; chdir' will still fail. But that's
a reason to keep the ticket open, not one not to merge the patch.

@p5pRT
Copy link
Author

p5pRT commented Apr 10, 2013

From @Hugmeir

Another objection, I don't think either of these should fail​:

$ ./perl -e '%​:: = %​::'
Attempt to clear the %main​:: symbol table at -e line 1.

$ ./perl -e '%​:: = map { $_ =&gt; $​::{$_} } grep !/foo|bar/, keys %​::;'
Attempt to clear the %main​:: symbol table at -e line 1.

On Tue, Apr 9, 2013 at 2​:09 AM, Brian Fraser <fraserbn@​gmail.com> wrote​:

On Tue, Apr 9, 2013 at 2​:03 AM, Steffen Mueller <smueller@​cpan.org> wrote​:

On 04/08/2013 11​:27 PM, Reini Urban via RT wrote​:

On Mon Apr 08 11​:36​:23 2013, rurban wrote​:

Oops, previous patch had a last minute typo in it (sv vs hv)

Use this one instead.
I'm smoking it now with my cpan subset to catch possible
%{"$pkg\​::"}=... cases with empty $pkg.

Smoked my cpan successfully with this revised patch.

FWIW if nobody beats me to it or strongly objects I'll try to remember to
apply this after 5.18. Feel free to remind me then as well.

--Steffen

My soft objection is that it doesn't really solve the underlaying issue,
it just hides it; perl -e 'delete $​::{ENV}; chdir' will still fail. But
that's a reason to keep the ticket open, not one not to merge the patch.

@p5pRT
Copy link
Author

p5pRT commented Apr 10, 2013

From @nwc10

On Wed, Apr 10, 2013 at 06​:48​:23AM -0300, Brian Fraser wrote​:

Another objection, I don't think either of these should fail​:

$ ./perl -e '%​:: = %​::'
Attempt to clear the %main​:: symbol table at -e line 1.

$ ./perl -e '%​:: = map { $_ =&gt; $​::{$_} } grep !/foo|bar/, keys %​::;'
Attempt to clear the %main​:: symbol table at -e line 1.

Given how hash list assignment is implemented, it's hard to see how to
permit those to keep working whilst also adding a way to prevent
clearing %​::

I can see that they are reduced test cases, but what's the real world
use case that they represent?

Nicholas Clark

@p5pRT
Copy link
Author

p5pRT commented Apr 10, 2013

From @Hugmeir

On Wed, Apr 10, 2013 at 7​:04 AM, Nicholas Clark <nick@​ccl4.org> wrote​:

On Wed, Apr 10, 2013 at 06​:48​:23AM -0300, Brian Fraser wrote​:

Another objection, I don't think either of these should fail​:

$ ./perl -e '%​:: = %​::'
Attempt to clear the %main​:: symbol table at -e line 1.

$ ./perl -e '%​:: = map { $_ =&gt; $​::{$_} } grep !/foo|bar/, keys %​::;'
Attempt to clear the %main​:: symbol table at -e line 1.

Given how hash list assignment is implemented, it's hard to see how to
permit those to keep working whilst also adding a way to prevent
clearing %​::

I can see that they are reduced test cases, but what's the real world
use case that they represent?

Ah. Good question; None productive from me. I've only used them in joke
modules and when trying to make Perl crash. So that's a strike against that
objection.

@p5pRT
Copy link
Author

p5pRT commented Apr 10, 2013

From @nwc10

On Mon, Apr 08, 2013 at 02​:27​:04PM -0700, Reini Urban via RT wrote​:

On Mon Apr 08 11​:36​:23 2013, rurban wrote​:

Oops, previous patch had a last minute typo in it (sv vs hv)

Use this one instead.
I'm smoking it now with my cpan subset to catch possible
%{"$pkg\​::"}=... cases with empty $pkg.

Smoked my cpan successfully with this revised patch.

Mmm, that's an interesting failure case that I'd not thought of.

+++ b/t/op/stash.t
@​@​ -7,12 +7,12 @​@​ BEGIN {

BEGIN { require "./test.pl"; }

-plan( tests => 58 );
+plan( tests => 60 );

-# Used to segfault (bug #15479)
+# Used to segfault (bug #15479 and #54044)
fresh_perl_like(
'%​:: = ""',
- qr/Odd number of elements in hash assignment at - line 1\./,
+ qr/^Attempt to clear the %main​:: symbol table at - line 1\./m,
{ switches => [ '-w' ] },
'delete $​::{STDERR} and print a warning',
);
@​@​ -60,14 +60,14 @​@​ package main;
local $ENV{PERL_DESTRUCT_LEVEL} = 2;
fresh_perl_is(
'package A; sub a { // }; %​::=""',
- '',
+ 'Attempt to clear the %main​:: symbol table at - line 1.',
'',
);
# Variant of the above which creates an object that persists until global
# destruction.
fresh_perl_is(
'use Exporter; package A; sub a { // }; %​::=""',
- '',
+ 'Attempt to clear the %main​:: symbol table at - line 1.',
'',
);
}

I don't think that these three should be changed like that. Clearing %​::
was the intent of the tests. Triggering an error or SEGV as the side effect
of something no longer being in %​:: was the intent. I think that a better
change would be this​:

Inline Patch
diff --git a/t/op/stash.t b/t/op/stash.t
index fd5450e..2681d47 100644
--- a/t/op/stash.t
+++ b/t/op/stash.t
@@ -11,7 +11,7 @@ plan( tests => 58 );
 
 # Used to segfault (bug #15479)
 fresh_perl_like(
-    '%:: = ""',
+    'delete $::{STDERR}; my %a = ""',
     qr/Odd number of elements in hash assignment at - line 1\./,
     { switches => [ '-w' ] },
     'delete $::{STDERR} and print a warning',
@@ -59,14 +59,15 @@ package main;
 {
     local $ENV{PERL_DESTRUCT_LEVEL} = 2;
     fresh_perl_is(
-		  'package A; sub a { // }; %::=""',
+		  'package A::B; sub a { // }; %A::=""',
 		  '',
 		  '',
 		  );
     # Variant of the above which creates an object that persists until global
-    # destruction.
+    # destruction, and triggers an assertion failure prior to change
+    # a420522db95b7762
     fresh_perl_is(
-		  'use Exporter; package A; sub a { // }; %::=""',
+		  'use Exporter; package A; sub a { // }; delete $::{$_} for keys %::',
 		  '',
 		  '',
 		  );


as those all maintain the original intent of the tests.

Verified. In that I built the 3 revisions where those 3 were added and
checked that my suggested revised test case also triggers the bug that each
was testing. Also, as those 3 don't change behaviour with Reini's patch
added, I'd be tempted to apply them as a commit before Reini's patch, so that
it's clear that the revised versions pass independently of his change.

I sort of assume that "code freeze" applies equally to the code that is tests,
so I'm not doing it now.

Nicholas Clark

@p5pRT
Copy link
Author

p5pRT commented May 22, 2013

From @nwc10

On Wed, Apr 10, 2013 at 12​:13​:37PM +0100, Nicholas Clark wrote​:

was the intent of the tests. Triggering an error or SEGV as the side effect
of something no longer being in %​:: was the intent. I think that a better
change would be this​:

diff --git a/t/op/stash.t b/t/op/stash.t
index fd5450e..2681d47 100644
--- a/t/op/stash.t
+++ b/t/op/stash.t
@​@​ -11,7 +11,7 @​@​ plan( tests => 58 );

# Used to segfault (bug #15479)
fresh_perl_like(
- '%​:: = ""',
+ 'delete $​::{STDERR}; my %a = ""',
qr/Odd number of elements in hash assignment at - line 1\./,
{ switches => [ '-w' ] },
'delete $​::{STDERR} and print a warning',
@​@​ -59,14 +59,15 @​@​ package main;
{
local $ENV{PERL_DESTRUCT_LEVEL} = 2;
fresh_perl_is(
- 'package A; sub a { // }; %​::=""',
+ 'package A​::B; sub a { // }; %A​::=""',
'',
'',
);
# Variant of the above which creates an object that persists until global
- # destruction.
+ # destruction, and triggers an assertion failure prior to change
+ # a420522
fresh_perl_is(
- 'use Exporter; package A; sub a { // }; %​::=""',
+ 'use Exporter; package A; sub a { // }; delete $​::{$_} for keys %​::',
'',
'',
);

as those all maintain the original intent of the tests.

Verified. In that I built the 3 revisions where those 3 were added and
checked that my suggested revised test case also triggers the bug that each
was testing. Also, as those 3 don't change behaviour with Reini's patch
added, I'd be tempted to apply them as a commit before Reini's patch, so that
it's clear that the revised versions pass independently of his change.

I sort of assume that "code freeze" applies equally to the code that is tests,
so I'm not doing it now.

*That* change is now in blead, but the rest of this ticket is not yet done.

Nicholas Clark

@p5pRT
Copy link
Author

p5pRT commented Oct 27, 2013

From @cpansprout

On Wed Apr 10 03​:51​:04 2013, Hugmeir wrote​:

On Wed, Apr 10, 2013 at 7​:04 AM, Nicholas Clark <nick@​ccl4.org> wrote​:

On Wed, Apr 10, 2013 at 06​:48​:23AM -0300, Brian Fraser wrote​:

Another objection, I don't think either of these should fail​:

$ ./perl -e '%​:: = %​::'
Attempt to clear the %main​:: symbol table at -e line 1.

$ ./perl -e '%​:: = map { $_ =&gt; $​::{$_} } grep !/foo|bar/, keys %​::;'
Attempt to clear the %main​:: symbol table at -e line 1.

Given how hash list assignment is implemented, it's hard to see how to
permit those to keep working whilst also adding a way to prevent
clearing %​::

I can see that they are reduced test cases, but what's the real world
use case that they represent?

Ah. Good question; None productive from me. I've only used them in joke
modules and when trying to make Perl crash. So that's a strike against that
objection.

Another objection​: It doesn’t fix the underlying issue, and it just adds a special case to prevent something that nobody does anyway (and the extra check will make every %hash=() marginally slower).

I think the real fix here is to make certain shortcut pointers (like PL_replgv) reference-counted as necessary.

I have already begun this. I started for a different purpose; namely, to prevent gv_try_downgrade from trying to delete these (yes, it can do that!).

Once that’s done, I think this ticket can be closed.

--

Father Chrysostomos

@p5pRT
Copy link
Author

p5pRT commented Oct 27, 2013

From @cpansprout

On Sun Oct 27 16​:23​:04 2013, sprout wrote​:

On Wed Apr 10 03​:51​:04 2013, Hugmeir wrote​:

On Wed, Apr 10, 2013 at 7​:04 AM, Nicholas Clark <nick@​ccl4.org>
wrote​:

On Wed, Apr 10, 2013 at 06​:48​:23AM -0300, Brian Fraser wrote​:

Another objection, I don't think either of these should fail​:

$ ./perl -e '%​:: = %​::'
Attempt to clear the %main​:: symbol table at -e line 1.

$ ./perl -e '%​:: = map { $_ =&gt; $​::{$_} } grep !/foo|bar/, keys
%​::;'
Attempt to clear the %main​:: symbol table at -e line 1.

Given how hash list assignment is implemented, it's hard to see how
to
permit those to keep working whilst also adding a way to prevent
clearing %​::

I can see that they are reduced test cases, but what's the real
world
use case that they represent?

Ah. Good question; None productive from me. I've only used them in
joke
modules and when trying to make Perl crash. So that's a strike
against that
objection.

Another objection​: It doesn’t fix the underlying issue, and it just
adds a special case to prevent something that nobody does anyway (and
the extra check will make every %hash=() marginally slower).

I think the real fix here is to make certain shortcut pointers (like
PL_replgv) reference-counted as necessary.

I forgot to mention​: If someone removes, say, $​::{ENV} and expects *{"ENV"} to work thereafter, that’s not our problem. That counts as podotoxoboly (with apologies to Damian Conway).

--

Father Chrysostomos

@p5pRT
Copy link
Author

p5pRT commented Oct 28, 2013

From jettero@cpan.org

Apologies if this is a stupid question, but I can't figure why I'm copied
on this -- fascinating though the discussion is. Did I report this bug? I
highly doubt it, and I can't see where I commented on it.

Is this the best place to find the full history?

http​://www.nntp.perl.org/group/perl.perl5.porters/2013/04/msg200892.html

On Sun, Oct 27, 2013 at 7​:23 PM, Father Chrysostomos via RT <
perlbug-followup@​perl.org> wrote​:

On Wed Apr 10 03​:51​:04 2013, Hugmeir wrote​:

On Wed, Apr 10, 2013 at 7​:04 AM, Nicholas Clark <nick@​ccl4.org> wrote​:

On Wed, Apr 10, 2013 at 06​:48​:23AM -0300, Brian Fraser wrote​:

Another objection, I don't think either of these should fail​:

$ ./perl -e '%​:: = %​::'
Attempt to clear the %main​:: symbol table at -e line 1.

$ ./perl -e '%​:: = map { $_ =&gt; $​::{$_} } grep !/foo|bar/, keys %​::;'
Attempt to clear the %main​:: symbol table at -e line 1.

Given how hash list assignment is implemented, it's hard to see how to
permit those to keep working whilst also adding a way to prevent
clearing %​::

I can see that they are reduced test cases, but what's the real world
use case that they represent?

Ah. Good question; None productive from me. I've only used them in joke
modules and when trying to make Perl crash. So that's a strike against
that
objection.

Another objection​: It doesn’t fix the underlying issue, and it just adds
a special case to prevent something that nobody does anyway (and the extra
check will make every %hash=() marginally slower).

I think the real fix here is to make certain shortcut pointers (like
PL_replgv) reference-counted as necessary.

I have already begun this. I started for a different purpose; namely, to
prevent gv_try_downgrade from trying to delete these (yes, it can do that!).

Once that’s done, I think this ticket can be closed.

--

Father Chrysostomos

--
If riding in an airplane is flying, then riding in a boat is swimming.
116 jumps, 48.6 minutes of freefall, 92.9 freefall miles.

@p5pRT
Copy link
Author

p5pRT commented Oct 28, 2013

From @ap

* Father Chrysostomos via RT <perlbug-followup@​perl.org> [2013-10-28 00​:45]​:

I forgot to mention​: If someone removes, say, $​::{ENV} and expects
*{"ENV"} to work thereafter, that’s not our problem. That counts as
podotoxoboly (with apologies to Damian Conway).

Quoth `man bash` describing `unset`​:

  If any of RANDOM, SECONDS, LINENO, HISTCMD, FUNCNAME, GROUPS, or
  DIRSTACK are unset, they lose their special properties, even if they
  are subsequently reset.

So assuming that I am making the right connection here, the sentiment
seems common and to have precedent.

--
Aristotle Pagaltzis // <http​://plasmasturm.org/>

@p5pRT
Copy link
Author

p5pRT commented Oct 28, 2013

From @Smylers

Paul Miller writes​:

Apologies if this is a stupid question, but I can't figure why I'm copied
on this -- fascinating though the discussion is. Did I report this bug? I
highly doubt it, and I can't see where I commented on it.

Is this the best place to find the full history?

Hi Paul. At the very bottom of Father Chrysostomos's message that you
replied to is this link, which has the full bug details​:
https://rt-archive.perl.org/perl5/Ticket/Display.html?id=54044

Reading down it seems you first reported Bug 54050, which was then
merged into this one​:
https://rt.perl.org/Public/Bug/Display.html?id=54044#txn-403224

Smylers
--
Stop drug companies hiding negative research results.
Sign the AllTrials petition to get all clinical research results published.
Read more​: http​://www.alltrials.net/blog/the-alltrials-campaign/

@p5pRT
Copy link
Author

p5pRT commented Oct 28, 2013

From jettero@cpan.org

On Mon Oct 28 00​:23​:37 2013, smylers@​stripey.com wrote​:

Hi Paul. At the very bottom of Father Chrysostomos's message that you

It's actually not on his. I looked at that first thing (then checked the raw copy after you said to see if gmail hid it somehow), as I expected it would be if it was from RT. I think he replied in another way.

But all I had to do was put 54044 into the regular old rt.perl.org? I feel silly regardless.

Looks like I did report this at one point. I wonder how I found that.

@p5pRT
Copy link
Author

p5pRT commented Oct 28, 2013

From @Smylers

jettero@​cpan.org via RT writes​:

On Mon Oct 28 00​:23​:37 2013, smylers@​stripey.com wrote​:

Hi Paul. At the very bottom of Father Chrysostomos's message that you

It's actually not on his.

In which case, my apologies for suggesting otherwise.

I looked at that first thing (then checked the raw copy after you said
to see if gmail hid it somehow), as I expected it would be if it was
from RT. I think he replied in another way.

It was via RT, but possibly RT sends different messages to ‘internal’
and ‘external’ recipients. Here's the copy which RT sent to the P5P
mailing list, with the RT footer​:
http​://www.nntp.perl.org/group/perl.perl5.porters/2013/10/msg208991.html

But all I had to do was put 54044 into the regular old rt.perl.org? I
feel silly regardless.

Please don't feel silly​: I don't see why it would be obvious to somebody
who's reported a bug using the perlbug command that it would have a
public web interface available at a particular URL, especially not when
several years have gone by since reporting it.

Cheers

Smylers
--
Stop drug companies hiding negative research results.
Sign the AllTrials petition to get all clinical research results published.
Read more​: http​://www.alltrials.net/blog/the-alltrials-campaign/

@p5pRT
Copy link
Author

p5pRT commented Oct 29, 2013

From @cpansprout

On Sun Oct 27 16​:23​:04 2013, sprout wrote​:

On Wed Apr 10 03​:51​:04 2013, Hugmeir wrote​:

On Wed, Apr 10, 2013 at 7​:04 AM, Nicholas Clark <nick@​ccl4.org>
wrote​:

On Wed, Apr 10, 2013 at 06​:48​:23AM -0300, Brian Fraser wrote​:

Another objection, I don't think either of these should fail​:

$ ./perl -e '%​:: = %​::'
Attempt to clear the %main​:: symbol table at -e line 1.

$ ./perl -e '%​:: = map { $_ =&gt; $​::{$_} } grep !/foo|bar/, keys
%​::;'
Attempt to clear the %main​:: symbol table at -e line 1.

Given how hash list assignment is implemented, it's hard to see how
to
permit those to keep working whilst also adding a way to prevent
clearing %​::

I can see that they are reduced test cases, but what's the real
world
use case that they represent?

Ah. Good question; None productive from me. I've only used them in
joke
modules and when trying to make Perl crash. So that's a strike
against that
objection.

Another objection​: It doesn’t fix the underlying issue, and it just
adds a special case to prevent something that nobody does anyway (and
the extra check will make every %hash=() marginally slower).

I think the real fix here is to make certain shortcut pointers (like
PL_replgv) reference-counted as necessary.

I have already begun this. I started for a different purpose; namely,
to prevent gv_try_downgrade from trying to delete these (yes, it can
do that!).

Once that’s done, I think this ticket can be closed.

This is now fixed in commit 475b1e9 and some of the commits leading up to it.

--

Father Chrysostomos

@p5pRT
Copy link
Author

p5pRT commented Oct 29, 2013

@cpansprout - Status changed from 'open' to 'resolved'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant