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