---------- Forwarded message ----------
From:
rur...@cpanel.net via RT <
perlbug-...@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:
abi...@abigail.be,
fras...@gmail.com,
jet...@cpan.org,
rur...@x-ray.at
This is a bug report for perl from
rur...@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 <
rur...@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..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=
rur...@cpanel.net -Dperladmin=
rur...@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/