$ ./perl -Ilib -e 'for(\1){ vec($_,0,1)=1 }'
Can't coerce readonly REF to string in sassign at -e line 1.
Why not ‘Modification of a read-only value’ as elsewhere?
The code in question, in sv_pvn_force_flags, allows references to
bypass the initial read-only check. (This has been the case since
perl-5.005_02-1047-g6fc9266. I think it was a mistake.) Then there
is a check further down that croaks with this error, unless called as
SvPV_force_mutable (i.e., with the SV_MUTABLE_RETURN flag).
So that means read-only references can silently be flattened, regard-
less of the read-only flag, if the caller uses SvPV_force_mutable.
Fortunately, the only use of that macro in the core is in fbm_compile,
which I recently modified so that it wouldn’t touch references at all.
I don’t understand the logic that allows read-only thingies to be mod-
ified in the presence of the SV_MUTABLE_RETURN flag, but not other-
wise. As of the previous commit, which removed the exception for
read-only scalars at compile time, nothing can reach that code except
read-only references.
This commit restores the logic inadvertently changed by 6fc9266 and
removes the code that becomes unreachable as a result.
PERL_ARGS_ASSERT_SV_PVN_FORCE_FLAGS;
if (flags & SV_GMAGIC) SvGETMAGIC(sv);
- if (SvTHINKFIRST(sv) && !SvROK(sv))
+ if (SvTHINKFIRST(sv) && (!SvROK(sv) || SvREADONLY(sv)))
sv_force_normal_flags(sv, 0);
if (SvPOK(sv)) {
char *s;
STRLEN len;
- if (SvREADONLY(sv) && !(flags & SV_MUTABLE_RETURN)) {
- const char * const ref = sv_reftype(sv,0);
- if (PL_op)
- Perl_croak(aTHX_ "Can't coerce readonly %s to string in %s",
- ref, OP_DESC(PL_op));
- else
- Perl_croak(aTHX_ "Can't coerce readonly %s to string", ref);
- }
if (SvTYPE(sv) > SVt_PVLV
|| isGV_with_GP(sv))
/* diag_listed_as: Can't coerce %s to %s in %s */
}
require "test.pl";
-plan( tests => 32 );
+plan( tests => 33 );
my $Is_EBCDIC = (ord('A') == 193) ? 1 : 0;
$x = bless({}, 'Class');
}
is($destroyed, 1, 'Timely scalar destruction with lvalue vec');
+
+eval { for (\1) { vec($_,0,1) = 1 } };
+like($@, qr/^Modification of a read-only value attempted at /,
+ 'err msg when modifying read-only refs');
Malformed UTF-8 character (unexpected non-continuation byte 0x%x, immediately after start byte 0x%x)
Cannot apply "%s" in non-PerlIO perl
-Can't coerce readonly %s to string
-Can't coerce readonly %s to string in %s
Can't find string terminator %c%s%c anywhere before EOF
Can't fix broken locale name "%s"
Can't get short module name from a handle