This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
RT#131000: splice doesn't honour read-only flag
authorAaron Crane <arc@cpan.org>
Thu, 16 Mar 2017 12:33:59 +0000 (12:33 +0000)
committerAaron Crane <arc@cpan.org>
Sun, 15 Oct 2017 09:13:58 +0000 (11:13 +0200)
commit3275d25a1e4129bdf23c447f60be4348af4dfe19
tree307c6a77e0701309ad89d1c51dd2618db496a661
parenta55c21fc5cb5464e6c8e268297570cb845eb2142
RT#131000: splice doesn't honour read-only flag

The push and unshift builtins were correctly throwing a "Modification of a
read-only value attempted" exception when modifying a read-only array, but
splice was silently modifying the array. This commit adds tests that all
three builtins throw such an exception.

One discrepancy between the three remains: push has long silently accepted
a push of no elements onto an array, whereas unshift throws an exception in
that situation. This seems to have been originally a coincidence. The
pp_unshift implementation first makes space for the elements it unshifts
(which croaks for a read-only array), then copies the new values into the
space thus created. The pp_push implementation, on the other hand, calls
av_push() individually on each element; that implicitly croaks, but only one
there's at least one element being pushed.

The pp_push implementation has subsequently been changed: read-only checking
is now done first, but that was done to fix a memory leak. (If the av_push()
itself failed, then the new SV that had been allocated for pushing onto the
array would get leaked.) That leak fix specifically grandfathered in the
acceptance of empty-push-to-readonly-array, to avoid changing behaviour.

I'm not fond of the inconsistency betwen push on the one hand and unshift &
splice on the other, but I'm disinclined to make empty-push-to-readonly
suddenly start throwing an exception after all these years, and it seems
best not to extend that exemption-from-exception to the other builtins.
pp.c
t/op/push.t
t/op/splice.t
t/op/unshift.t