[perl #61520] Segfault in debugger with tr// and UTF8
authorDavid Mitchell <davem@iabyn.com>
Sat, 11 Jul 2009 16:56:06 +0000 (17:56 +0100)
committerDavid Mitchell <davem@iabyn.com>
Mon, 13 Jul 2009 14:39:43 +0000 (15:39 +0100)
commit 043e41b8 (29765), which made tr// threadsafe by moving the
swash into the pad, didn't mark the pad SV as read-only, so it was getting
removed from anon sub prototypes

(cherry picked from commit a5446a64ab75205e7ec7185a30ff6e9f7c532dd0)

op.c
t/op/tr.t

diff --git a/op.c b/op.c
index 5a7d95e..671eeb3 100644 (file)
--- a/op.c
+++ b/op.c
@@ -3339,6 +3339,7 @@ Perl_pmtrans(pTHX_ OP *o, OP *expr, OP *repl)
        SvREFCNT_dec(PAD_SVl(cPADOPo->op_padix));
        PAD_SETSV(cPADOPo->op_padix, swash);
        SvPADTMP_on(swash);
+       SvREADONLY_on(swash);
 #else
        cSVOPo->op_sv = swash;
 #endif
index 9273e09..3f85e43 100644 (file)
--- a/t/op/tr.t
+++ b/t/op/tr.t
@@ -6,7 +6,7 @@ BEGIN {
     require './test.pl';
 }
 
-plan tests => 118;
+plan tests => 119;
 
 my $Is_EBCDIC = (ord('i') == 0x89 & ord('J') == 0xd1);
 
@@ -468,3 +468,19 @@ my $wasro = Internals::SvREADONLY($s);
     $s =~ tr/i//;
     ok( Internals::SvREADONLY($s), "count-only tr doesn't deCOW COWs" );
 }
+
+# [ RT #61520 ]
+#
+# under threads, unicode tr within a cloned closure would SEGV or assert
+# fail, since the pointer in the pad to the swash was getting zeroed out
+# in the proto-CV
+
+{
+    my $x = "\x{142}";
+    sub {
+       $x =~ tr[\x{142}][\x{143}];
+    }->();
+    is($x,"\x{143}", "utf8 + closure");
+}
+
+