Login | Register For Free | Help
Search for: (Advanced)

Mailing List Archive: Perl: porters

Readonly bug in 5.10.0

 

 

Perl porters RSS feed   Index | Next | Previous | View Threaded


jdhedden at cpan

Nov 28, 2007, 6:54 AM

Post #1 of 9 (235 views)
Permalink
Readonly bug in 5.10.0

The following (attached):

#!/usr/bin/perl

use strict;
use warnings;

# Create a object from an anonymous scalar
my $obj1 = \do{ my $scalar = 1; }; # Object ID = 1
bless($obj1, 'Foo');

# Put the object's ID into a hash
my %ids;
$ids{$$obj1} = undef;


# Create a 2nd object
my $obj2 = \do{ my $scalar; };

# Set the 2nd object IDs from the hash
($$obj2) = keys(%ids);
delete($ids{$$obj2});

# Bless the 2nd object
bless($obj2, 'Foo'); # Causes "Modification of a read-only value..." error

# EOF

Produces:

Modification of a read-only value attempted at ./readonly_bug.pl line 23.

Can this be fixed before 5.10.0 goes out?
Attachments: readonly_bug.pl (0.49 KB)


jdhedden at cpan

Nov 28, 2007, 6:58 AM

Post #2 of 9 (227 views)
Permalink
Re: Readonly bug in 5.10.0 [In reply to]

Jerry D. Hedden wrote:
> The following (attached):
[SNIP]
>
> Produces:
>
> Modification of a read-only value attempted at ./readonly_bug.pl line 23.
>
> Can this be fixed before 5.10.0 goes out?

This bug does not occur in maint - just blead.


jdhedden at cpan

Nov 28, 2007, 7:18 AM

Post #3 of 9 (227 views)
Permalink
Re: Readonly bug in 5.10.0 [In reply to]

> Modification of a read-only value attempted ...

Here's an even simpler example:

# Create an anonymous scalar ref
my $obj = \do{ my $scalar; };

# Set the ref's value from a key in the hash
my %ids = ( 1 => undef );
($$obj) = keys(%ids);

# Bless into an object
bless($obj, 'Foo'); # Causes "Modification of a read-only value..." error


rgarciasuarez at gmail

Nov 28, 2007, 8:23 AM

Post #4 of 9 (223 views)
Permalink
Re: Readonly bug in 5.10.0 [In reply to]

On 28/11/2007, Jerry D. Hedden <jdhedden [at] cpan> wrote:
> > Modification of a read-only value attempted ...
>
> Here's an even simpler example:
>
> # Create an anonymous scalar ref
> my $obj = \do{ my $scalar; };
>
> # Set the ref's value from a key in the hash
> my %ids = ( 1 => undef );
> ($$obj) = keys(%ids);
>
> # Bless into an object
> bless($obj, 'Foo'); # Causes "Modification of a read-only value..." error

That comes from sv_bless, this line precisely:

if (SvREADONLY(tmpRef))
Perl_croak(aTHX_ PL_no_modify);

It forbids blessing a ref to something which is read only. This code
is old. I don't know why it isn't exercised in 5.8, but the meaning is
clear...

Here's a simpler test case:

$ bleadperl -e '%h=1..2;($k)=keys%h;$x=\$k;bless$x'
Modification of a read-only value attempted at -e line 1.

A workaround is to un-read-only $k:

$ bleadperl -e '%h=1..2;($k)=keys%h;$k.="";$x=\$k;bless$x'


nick at ccl4

Nov 28, 2007, 8:26 AM

Post #5 of 9 (227 views)
Permalink
Re: Readonly bug in 5.10.0 [In reply to]

On Wed, Nov 28, 2007 at 05:23:04PM +0100, Rafael Garcia-Suarez wrote:

> That comes from sv_bless, this line precisely:
>
> if (SvREADONLY(tmpRef))
> Perl_croak(aTHX_ PL_no_modify);
>
> It forbids blessing a ref to something which is read only. This code
> is old. I don't know why it isn't exercised in 5.8, but the meaning is
> clear...

Probably because the core in 5.10 internally copies shared hash key scalars
as shared hash key scalars. 5.8.x doesn't.

A fix is likely to be about 2 lines. I've just got back in from a walk, and
don't have any tea yet, so haven't looked.

Nicholas Clark


nick at ccl4

Nov 28, 2007, 9:10 AM

Post #6 of 9 (222 views)
Permalink
Re: Readonly bug in 5.10.0 [In reply to]

On Wed, Nov 28, 2007 at 04:26:02PM +0000, Nicholas Clark wrote:
> On Wed, Nov 28, 2007 at 05:23:04PM +0100, Rafael Garcia-Suarez wrote:
>
> > That comes from sv_bless, this line precisely:
> >
> > if (SvREADONLY(tmpRef))
> > Perl_croak(aTHX_ PL_no_modify);
> >
> > It forbids blessing a ref to something which is read only. This code
> > is old. I don't know why it isn't exercised in 5.8, but the meaning is
> > clear...
>
> Probably because the core in 5.10 internally copies shared hash key scalars
> as shared hash key scalars. 5.8.x doesn't.

The appended patch would fix it.

Nicholas Clark

==== //depot/perl/sv.c#1442 - /home/nick/p4perl/perl/sv.c ====
--- /tmp/tmp.16261.0 Wed Nov 28 17:06:14 2007
+++ /home/nick/p4perl/perl/sv.c Wed Nov 28 16:45:09 2007
@@ -7979,6 +7979,8 @@ Perl_sv_bless(pTHX_ SV *sv, HV *stash)
Perl_croak(aTHX_ "Can't bless non-reference value");
tmpRef = SvRV(sv);
if (SvFLAGS(tmpRef) & (SVs_OBJECT|SVf_READONLY)) {
+ if (SvIsCOW(tmpRef))
+ sv_force_normal_flags(tmpRef, 0);
if (SvREADONLY(tmpRef))
Perl_croak(aTHX_ PL_no_modify);
if (SvOBJECT(tmpRef)) {
==== //depot/perl/t/op/bless.t#8 - /home/nick/p4perl/perl/t/op/bless.t ====
--- /tmp/tmp.16261.1 Wed Nov 28 17:06:14 2007
+++ /home/nick/p4perl/perl/t/op/bless.t Wed Nov 28 16:39:04 2007
@@ -6,7 +6,7 @@ BEGIN {
require './test.pl';
}

-plan (106);
+plan (107);

sub expected {
my($object, $package, $type) = @_;
@@ -128,3 +128,11 @@ $h1 = bless {}, "H4";
$c4 = eval { bless \$test, $h1 };
is ($@, '', "class is an overloaded ref");
expected($c4, 'C4', "SCALAR");
+
+{
+ my %h = 1..2;
+ my($k) = keys %h;
+ my $x=\$k;
+ bless $x, 'pam';
+ is(ref $x, 'pam');
+}


jdhedden at cpan

Nov 28, 2007, 9:21 AM

Post #7 of 9 (225 views)
Permalink
Re: Readonly bug in 5.10.0 [In reply to]

> Probably because the core in 5.10 internally copies
> shared hash key scalars as shared hash key scalars.
> 5.8.x doesn't.

That begs the question: If the coping of shared hash key
scalars is different between 5.8.x and 5.10.0, what else
will break? Should the shared hash key scalars be copied as
regular scalars? Or was this entirely intentional?


nick at ccl4

Nov 28, 2007, 9:54 AM

Post #8 of 9 (220 views)
Permalink
Re: Readonly bug in 5.10.0 [In reply to]

On Wed, Nov 28, 2007 at 12:21:26PM -0500, Jerry D. Hedden wrote:
> > Probably because the core in 5.10 internally copies
> > shared hash key scalars as shared hash key scalars.
> > 5.8.x doesn't.
>
> That begs the question: If the coping of shared hash key
> scalars is different between 5.8.x and 5.10.0, what else
> will break? Should the shared hash key scalars be copied as
> regular scalars? Or was this entirely intentional?

It was intentional. The copy itself is faster and more memory efficient,
and the shared hash key scalars allow a faster path through the hash
implementation if they are used as keys in hash lookups.

IIRC this is the first bug related to it spotted in over a year.
Most of the code needed to remove the COW aspects of the shared hash key
scalars needs to exist in 5.8.x anyway, because if you try hard enough
you can make them reach quite a few functions. For example, on 5.8.8:

$ perl -wle '%h = (a=>3); $b = bless \(keys %h); print $b; print $$b'
Modification of a read-only value attempted at -e line 1.

I'd argue that the above is a bug, and the (new) blead behaviour is
correct:

$ ./perl -wle '%h = (a=>3); $b = bless \(keys %h); print $b; print $$b'
main=SCALAR(0x831331c)
a


Nicholas Clark


nick at ccl4

Nov 28, 2007, 9:55 AM

Post #9 of 9 (225 views)
Permalink
Re: Readonly bug in 5.10.0 [In reply to]

On Wed, Nov 28, 2007 at 05:10:36PM +0000, Nicholas Clark wrote:
> On Wed, Nov 28, 2007 at 04:26:02PM +0000, Nicholas Clark wrote:
> > On Wed, Nov 28, 2007 at 05:23:04PM +0100, Rafael Garcia-Suarez wrote:
> >
> > > That comes from sv_bless, this line precisely:
> > >
> > > if (SvREADONLY(tmpRef))
> > > Perl_croak(aTHX_ PL_no_modify);
> > >
> > > It forbids blessing a ref to something which is read only. This code
> > > is old. I don't know why it isn't exercised in 5.8, but the meaning is
> > > clear...
> >
> > Probably because the core in 5.10 internally copies shared hash key scalars
> > as shared hash key scalars. 5.8.x doesn't.
>
> The appended patch would fix it.

Applied with a second regression test as change 32533

Nicholas Clark

Perl porters RSS feed   Index | Next | Previous | View Threaded
 
 


Interested in having your list archived? Contact Gossamer Threads
 
  Web Applications & Managed Hosting Powered by Gossamer Threads Inc.