This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Make tr/a/b/ croak on read-only null COWs
authorFather Chrysostomos <sprout@cpan.org>
Tue, 6 Aug 2013 20:05:20 +0000 (13:05 -0700)
committerFather Chrysostomos <sprout@cpan.org>
Sun, 11 Aug 2013 14:41:26 +0000 (07:41 -0700)
$ ./perl -Ilib -e 'use constant nullrocow => (keys%{{""=>undef}})[0]; for(nullrocow) { y/a/b/ }'
$ ./perl -Ilib -e 'use constant nullro => ""; for(nullro) { y/a/b/ }'
Modification of a read-only value attempted at -e line 1.

It should croak on COW scalars that are read-only, even if they are
zero-length, just as it does on non-COW scalars.

This logic is left over from when READONLY+FAKE meant COW.

doop.c
t/op/tr.t

diff --git a/doop.c b/doop.c
index faf74c5..5a819a7 100644 (file)
--- a/doop.c
+++ b/doop.c
@@ -632,7 +632,6 @@ Perl_do_trans(pTHX_ SV *sv)
     PERL_ARGS_ASSERT_DO_TRANS;
 
     if (SvREADONLY(sv) && !(PL_op->op_private & OPpTRANS_IDENTICAL)) {
-        if (!SvIsCOW(sv))
             Perl_croak_no_modify();
     }
     (void)SvPV_const(sv, len);
index 53530f2..55a3438 100644 (file)
--- a/t/op/tr.t
+++ b/t/op/tr.t
@@ -8,7 +8,7 @@ BEGIN {
     require './test.pl';
 }
 
-plan tests => 132;
+plan tests => 134;
 
 my $Is_EBCDIC = (ord('i') == 0x89 & ord('J') == 0xd1);
 
@@ -526,4 +526,12 @@ SKIP: {
     is($x, "PerlĪ²", "Only first of multiple transliterations is used");
 }
 
+# tr/a/b/ should fail even on zero-length read-only strings
+use constant nullrocow => (keys%{{""=>undef}})[0];
+for ("", nullrocow) {
+    eval { $_ =~ y/a/b/ };
+    like $@, qr/^Modification of a read-only value attempted at /,
+        'tr/a/b/ fails on zero-length ro string';
+}
+
 1;