715684
From d77d726d206f16232df6edd80739720bb7011aea Mon Sep 17 00:00:00 2001
715684
From: Pali <pali@cpan.org>
715684
Date: Thu, 7 Oct 2021 22:35:51 +0200
715684
Subject: [PATCH] Fix memory leak in function encode_method()
715684
715684
Pull request https://github.com/dankogai/p5-encode/pull/72 fixed memory
715684
corruption but introduced a new memory leak as dst scalar is not mortal
715684
anymore and not every possible exit from every XS function properly release
715684
scalar's memory.
715684
715684
Fix this memory leak by making dst scalar mortal again. To not re-introduce
715684
that memory corruption, first store dst scalar into temporary variable and
715684
then save it into stack via ST(0) macro.
715684
---
715684
 Encode.xs | 23 ++++++++++++-----------
715684
 1 file changed, 12 insertions(+), 11 deletions(-)
715684
715684
diff --git a/Encode.xs b/Encode.xs
715684
index 4baf296..d173c96 100644
715684
--- a/Encode.xs
715684
+++ b/Encode.xs
715684
@@ -154,7 +154,7 @@ encode_method(pTHX_ const encode_t * enc, const encpage_t * dir, SV * src, U8 *
715684
     STRLEN sdone = 0;
715684
     /* We allocate slen+1.
715684
        PerlIO dumps core if this value is smaller than this. */
715684
-    SV *dst = newSV(slen+1);
715684
+    SV *dst = sv_2mortal(newSV(slen+1));
715684
     U8 *d = (U8 *)SvPVX(dst);
715684
     STRLEN dlen = SvLEN(dst)-1;
715684
     int code = 0;
715684
@@ -810,13 +810,12 @@ CODE:
715684
     tmp = encode_method(aTHX_ enc, enc->t_utf8, src, s, slen, check,
715684
                 &offset, term, &code, fallback_cb);
715684
     sv_catsv(dst, tmp);
715684
-    SvREFCNT_dec(tmp);
715684
     SvIV_set(off, (IV)offset);
715684
     RETVAL = (code == ENCODE_FOUND_TERM);
715684
 OUTPUT:
715684
     RETVAL
715684
 
715684
-SV *
715684
+void
715684
 Method_decode(obj,src,check_sv = &PL_sv_no)
715684
 SV *	obj
715684
 SV *	src
715684
@@ -828,6 +827,7 @@ PREINIT:
715684
     encode_t *enc;
715684
     U8 *s;
715684
     STRLEN slen;
715684
+    SV *ret;
715684
 INIT:
715684
     SvGETMAGIC(src);
715684
     SvGETMAGIC(check_sv);
715684
@@ -841,13 +841,13 @@ CODE:
715684
     s = modify ? (U8 *)SvPV_force_nomg(src, slen) : (U8 *)SvPV_nomg(src, slen);
715684
     if (SvUTF8(src))
715684
         utf8_safe_downgrade(aTHX_ &src, &s, &slen, modify);
715684
-    RETVAL = encode_method(aTHX_ enc, enc->t_utf8, src, s, slen, check,
715684
+    ret = encode_method(aTHX_ enc, enc->t_utf8, src, s, slen, check,
715684
               NULL, Nullsv, NULL, fallback_cb);
715684
-    SvUTF8_on(RETVAL);
715684
-OUTPUT:
715684
-    RETVAL
715684
+    SvUTF8_on(ret);
715684
+    ST(0) = ret;
715684
+    XSRETURN(1);
715684
 
715684
-SV *
715684
+void
715684
 Method_encode(obj,src,check_sv = &PL_sv_no)
715684
 SV *	obj
715684
 SV *	src
715684
@@ -859,6 +859,7 @@ PREINIT:
715684
     encode_t *enc;
715684
     U8 *s;
715684
     STRLEN slen;
715684
+    SV *ret;
715684
 INIT:
715684
     SvGETMAGIC(src);
715684
     SvGETMAGIC(check_sv);
715684
@@ -872,10 +873,10 @@ CODE:
715684
     s = modify ? (U8 *)SvPV_force_nomg(src, slen) : (U8 *)SvPV_nomg(src, slen);
715684
     if (!SvUTF8(src))
715684
         utf8_safe_upgrade(aTHX_ &src, &s, &slen, modify);
715684
-    RETVAL = encode_method(aTHX_ enc, enc->f_utf8, src, s, slen, check,
715684
+    ret = encode_method(aTHX_ enc, enc->f_utf8, src, s, slen, check,
715684
               NULL, Nullsv, NULL, fallback_cb);
715684
-OUTPUT:
715684
-    RETVAL
715684
+    ST(0) = ret;
715684
+    XSRETURN(1);
715684
 
715684
 bool
715684
 Method_needs_lines(obj)
715684
-- 
715684
2.31.1
715684