Nullary reverse needs to extend the stack to push its result scalar.
It was actually extending the stack, but doing so invalidated MARK,
which it relied upon to place the stack pointer afterwards. Upon stack
reallocation it was therefore leaving the stack pointer pointing to the
freed stack memory. Reformulate stack manipulation to not rely on MARK
after extending. Fixes [perl #132544].
STRLEN len;
SvUTF8_off(TARG); /* decontaminate */
- if (SP - MARK > 1)
+ if (SP - MARK > 1) {
do_join(TARG, &PL_sv_no, MARK, SP);
- else if (SP > MARK)
+ SP = MARK + 1;
+ SETs(TARG);
+ } else if (SP > MARK) {
sv_setsv(TARG, *SP);
- else {
+ SETs(TARG);
+ } else {
sv_setsv(TARG, DEFSV);
- EXTEND(SP, 1);
+ XPUSHs(TARG);
}
up = SvPV_force(TARG, len);
}
(void)SvPOK_only_UTF8(TARG);
}
- SP = MARK + 1;
- SETTARG;
}
RETURN;
}
set_up_inc('../lib');
}
-plan tests => 25;
+plan tests => 26;
is(reverse("abc"), "cba", 'simple reverse');
ok defined $a[-1] && ${$a[-1]} eq '1', "in-place reverse strengthens weak reference";
ok defined $a[2] && ${$a[2]} eq '3', "in-place reverse strengthens weak reference in the middle";
}
+
+# [perl #132544] stack pointer used to go wild when nullary reverse
+# required extending the stack
+for(0..1000){()=(0..$_,scalar reverse )}
+pass "extending the stack without crashing";