From dc529e655355bff17b35ddec08d5bc5cbbdd206a Mon Sep 17 00:00:00 2001 From: Tony Cook Date: Mon, 7 Nov 2016 11:22:55 +1100 Subject: (perl #129995) avoid sv_catpvn() in do_vop() when unneeded This could call sv_catpvn() with the source string being within the destination SV, which caused a freed memory access if do_vop() and sv_catpvn_flags() had different ideas about the ideal size of the target SV's buffer. --- doop.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'doop.c') diff --git a/doop.c b/doop.c index 5525c470e8..bc23c9e872 100644 --- a/doop.c +++ b/doop.c @@ -1218,8 +1218,17 @@ Perl_do_vop(pTHX_ I32 optype, SV *sv, SV *left, SV *right) len = lensave; if (rightlen > len) sv_catpvn_nomg(sv, rsave + len, rightlen - len); - else if (leftlen > (STRLEN)len) - sv_catpvn_nomg(sv, lsave + len, leftlen - len); + else if (leftlen > (STRLEN)len) { + if (sv == left) { + /* sv_catpvn() might move the source from under us, + and the data is already in place, just adjust to + include it */ + SvCUR_set(sv, leftlen); + *SvEND(sv) = '\0'; + } + else + sv_catpvn_nomg(sv, lsave + len, leftlen - len); + } else *SvEND(sv) = '\0'; break; -- cgit v1.2.1