summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--op.c10
-rw-r--r--pad.c5
-rw-r--r--t/op/tr.t11
-rw-r--r--toke.c4
4 files changed, 19 insertions, 11 deletions
diff --git a/op.c b/op.c
index 7695cada23..cf3fec00da 100644
--- a/op.c
+++ b/op.c
@@ -3956,9 +3956,6 @@ S_pmtrans(pTHX_ OP *o, OP *expr, OP *repl)
else
bits = 8;
- PerlMemShared_free(cPVOPo->op_pv);
- cPVOPo->op_pv = NULL;
-
swash = MUTABLE_SV(swash_init("utf8", "", listsv, bits, none));
#ifdef USE_ITHREADS
cPADOPo->op_padix = pad_alloc(OP_TRANS, SVs_PADTMP);
@@ -3992,9 +3989,12 @@ S_pmtrans(pTHX_ OP *o, OP *expr, OP *repl)
return o;
}
- tbl = (short*)cPVOPo->op_pv;
+ tbl = (short*)PerlMemShared_calloc(
+ (o->op_private & OPpTRANS_COMPLEMENT) &&
+ !(o->op_private & OPpTRANS_DELETE) ? 258 : 256,
+ sizeof(short));
+ cPVOPo->op_pv = (char*)tbl;
if (complement) {
- Zero(tbl, 256, short);
for (i = 0; i < (I32)tlen; i++)
tbl[t[i]] = -1;
for (i = 0, j = 0; i < 256; i++) {
diff --git a/pad.c b/pad.c
index 779e6d6708..c4362af0d4 100644
--- a/pad.c
+++ b/pad.c
@@ -1516,8 +1516,9 @@ Perl_pad_swipe(pTHX_ PADOFFSET po, bool refadjust)
if (AvARRAY(PL_comppad) != PL_curpad)
Perl_croak(aTHX_ "panic: pad_swipe curpad, %p!=%p",
AvARRAY(PL_comppad), PL_curpad);
- if (!po)
- Perl_croak(aTHX_ "panic: pad_swipe po");
+ if (!po || ((SSize_t)po) > AvFILLp(PL_comppad))
+ Perl_croak(aTHX_ "panic: pad_swipe po=%ld, fill=%ld",
+ (long)po, (long)AvFILLp(PL_comppad));
DEBUG_X(PerlIO_printf(Perl_debug_log,
"Pad 0x%"UVxf"[0x%"UVxf"] swipe: %ld\n",
diff --git a/t/op/tr.t b/t/op/tr.t
index 0f2ae97be6..5baa43178f 100644
--- a/t/op/tr.t
+++ b/t/op/tr.t
@@ -6,7 +6,7 @@ BEGIN {
require './test.pl';
}
-plan tests => 128;
+plan tests => 130;
my $Is_EBCDIC = (ord('i') == 0x89 & ord('J') == 0xd1);
@@ -506,4 +506,13 @@ SKIP: {
is($x,"\x{143}", "utf8 + closure");
}
+# Freeing of trans ops prior to pmtrans() [perl #102858].
+eval q{ $a ~= tr/a/b/; };
+ok 1;
+SKIP: {
+ skip "no encoding", 1 unless eval { require encoding; 1 };
+ eval q{ use encoding "utf8"; $a ~= tr/a/b/; };
+ ok 1;
+}
+1;
diff --git a/toke.c b/toke.c
index bec4b211cf..c7194df993 100644
--- a/toke.c
+++ b/toke.c
@@ -9272,7 +9272,6 @@ S_scan_trans(pTHX_ char *start)
dVAR;
register char* s;
OP *o;
- short *tbl;
U8 squash;
U8 del;
U8 complement;
@@ -9340,8 +9339,7 @@ S_scan_trans(pTHX_ char *start)
}
no_more:
- tbl = (short *)PerlMemShared_calloc(complement&&!del?258:256, sizeof(short));
- o = newPVOP(nondestruct ? OP_TRANSR : OP_TRANS, 0, (char*)tbl);
+ o = newPVOP(nondestruct ? OP_TRANSR : OP_TRANS, 0, (char*)NULL);
o->op_private &= ~OPpTRANS_ALL;
o->op_private |= del|squash|complement|
(DO_UTF8(PL_lex_stuff)? OPpTRANS_FROM_UTF : 0)|