This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
[perl #119043] Allow utf8 up/downgrade on ro COWs
authorFather Chrysostomos <sprout@cpan.org>
Sun, 4 Aug 2013 06:58:56 +0000 (23:58 -0700)
committerFather Chrysostomos <sprout@cpan.org>
Sun, 4 Aug 2013 07:04:32 +0000 (00:04 -0700)
commitc56ed9f6dbe3d89129c7f5a37b28d4fc398561e4
treefb3a242b29412fd38c7d32b000268ea928dff42f
parent9dbc968d1a9a9f1e73f1da3d0cd81229c81b27ab
[perl #119043] Allow utf8 up/downgrade on ro COWs

Commit 1913067 allowed COW constants to be read-only.  This broke
Glib, so I reverted it with ba36554e02.  That caused this bug to reë-
merge (I hadn’t realised that I had fixed it in 1913067):

perl -e 'for(1..10){for(__PACKAGE__){warn $_; $_++}}'
main at -e line 1.
maio at -e line 1.
maip at -e line 1.
maiq at -e line 1.
mair at -e line 1.

so I reverted the revert two commits ago.

Glib was triggering a read-only error because it called
sv_utf8_upgrade on a read-only COW scalar, and sv_utf8_upgrade does
sv_force_normal on COWs to de-COW them.  sv_force_normal croaks on
read-only scalars.

The real problem here is that sv_force_normal means ‘I am going to
modify this scalar’, yet sv_utf8_upgrade conceptually does not modify
the scalar, but only changes the internal representation.

Having to call sv_force_normal to get the *side effect* of de-COWing
without triggering the various other things it does is no good.

What we need is a separate sv_uncow function that sv_force_normal
uses.  This commit introduces such a function.
lib/utf8.t
sv.c