From 6153fd01748f2261f2fcfdfdbaa7ecc7d839ac9d Mon Sep 17 00:00:00 2001 From: David Mitchell Date: Sun, 3 Nov 2019 16:00:53 -0500 Subject: [PATCH] THX_ck_entersub_args_sereal_decoder(): set parent link correctly This patch was originally provided by Dave Mitchell inline as a response to a "Blead Breaks CPAN" report in the Perl 5 bug queue (originally rt.perl.org; now github.com/Perl/perl5/issues). Dave's comment in original ticket. THX_ck_entersub_args_sereal_decoder() in Decoder.xs wasn't setting the parent link correctly when munging an op tree. The following diff makes all tests pass on blead. I haven't tested against older perls. References: https://github.com/Perl/perl5/issues/17114 (originally https://rt-archive.perl.org/perl5/Ticket/Display.html?id=134320) https://github.com/Sereal/Sereal/issues/207 --- Perl/Decoder/Decoder.xs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/Perl/Decoder/Decoder.xs b/Perl/Decoder/Decoder.xs index 8e8a6946a..0296e3f30 100644 --- a/Perl/Decoder/Decoder.xs +++ b/Perl/Decoder/Decoder.xs @@ -223,13 +223,17 @@ THX_ck_entersub_args_sereal_decoder(pTHX_ OP *entersubop, GV *namegv, SV *ckobj) if (arity > min_arity) opopt |= OPOPT_OUTARG_HEADER; - OpMORESIB_set(pushop, cvop); - OpLASTSIB_set(lastargop, op_parent(lastargop)); + /* cut out all ops between the pushmark and the RV2CV */ + op_sibling_splice(NULL, pushop, arity, NULL); + /* then throw everything else out */ op_free(entersubop); - newop = newUNOP(OP_NULL, 0, firstargop); + newop = newUNOP(OP_NULL, 0, NULL); newop->op_type = OP_CUSTOM; newop->op_private = opopt; newop->op_ppaddr = opopt & OPOPT_LOOKS_LIKE ? THX_pp_looks_like_sereal : THX_pp_sereal_decode; + /* attach the spliced-out args as children of the custom op, while + * deleting the stub op created by newUNOP() */ + op_sibling_splice(newop, NULL, 1, firstargop); return newop; }