This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
The danger of piping an mbox to patch is that it contains more than
authorJarkko Hietaniemi <jhi@iki.fi>
Sun, 16 Apr 2006 11:19:25 +0000 (14:19 +0300)
committerNicholas Clark <nick@ccl4.org>
Mon, 17 Apr 2006 10:24:58 +0000 (10:24 +0000)
one message. So both:

Subject: [PATCH] doop.c: one more code path where memory could leak (Coverity)
Message-Id: <20060416081925.680336CF2D@aprikoosi.hut.fi>
Date: Sun, 16 Apr 2006 11:19:25 +0300 (EEST)

and

Subject: [PATCH] doop.c: one more code path where memory could leak (Coverity)
From: jhi@cc.hut.fi (Jarkko Hietaniemi)
Message-Id: <20060416081925.680336CF2D@aprikoosi.hut.fi>
Date: Sun, 16 Apr 2006 11:19:25 +0300 (EEST)

p4raw-id: //depot/perl@27856

doop.c

diff --git a/doop.c b/doop.c
index 5972dbd..3143467 100644 (file)
--- a/doop.c
+++ b/doop.c
@@ -1185,6 +1185,7 @@ Perl_do_vop(pTHX_ I32 optype, SV *sv, SV *left, SV *right)
     const bool left_utf = DO_UTF8(left);
     const bool right_utf = DO_UTF8(right);
     I32 needlen = 0;
     const bool left_utf = DO_UTF8(left);
     const bool right_utf = DO_UTF8(right);
     I32 needlen = 0;
+    bool needfree = FALSE;
 
     if (left_utf && !right_utf)
        sv_utf8_upgrade(right);
 
     if (left_utf && !right_utf)
        sv_utf8_upgrade(right);
@@ -1197,9 +1198,12 @@ Perl_do_vop(pTHX_ I32 optype, SV *sv, SV *left, SV *right)
     rsave = rc = SvPV_nomg_const(right, rightlen);
     len = leftlen < rightlen ? leftlen : rightlen;
     lensave = len;
     rsave = rc = SvPV_nomg_const(right, rightlen);
     len = leftlen < rightlen ? leftlen : rightlen;
     lensave = len;
+    SvCUR_set(sv, len);
+    (void)SvPOK_only(sv);
     if ((left_utf || right_utf) && (sv == left || sv == right)) {
        needlen = optype == OP_BIT_AND ? len : leftlen + rightlen;
        Newxz(dc, needlen + 1, char);
     if ((left_utf || right_utf) && (sv == left || sv == right)) {
        needlen = optype == OP_BIT_AND ? len : leftlen + rightlen;
        Newxz(dc, needlen + 1, char);
+       needfree = TRUE;
     }
     else if (SvOK(sv) || SvTYPE(sv) > SVt_PVMG) {
        dc = SvPV_force_nomg_nolen(sv);
     }
     else if (SvOK(sv) || SvTYPE(sv) > SVt_PVMG) {
        dc = SvPV_force_nomg_nolen(sv);
@@ -1217,8 +1221,6 @@ Perl_do_vop(pTHX_ I32 optype, SV *sv, SV *left, SV *right)
        sv_usepvn_flags(sv, dc, needlen, SV_HAS_TRAILING_NUL);
        dc = SvPVX(sv);         /* sv_usepvn() calls Renew() */
     }
        sv_usepvn_flags(sv, dc, needlen, SV_HAS_TRAILING_NUL);
        dc = SvPVX(sv);         /* sv_usepvn() calls Renew() */
     }
-    SvCUR_set(sv, len);
-    (void)SvPOK_only(sv);
     if (left_utf || right_utf) {
        UV duc, luc, ruc;
        char *dcorig = dc;
     if (left_utf || right_utf) {
        UV duc, luc, ruc;
        char *dcorig = dc;
@@ -1239,8 +1241,10 @@ Perl_do_vop(pTHX_ I32 optype, SV *sv, SV *left, SV *right)
                duc = luc & ruc;
                dc = (char*)uvchr_to_utf8((U8*)dc, duc);
            }
                duc = luc & ruc;
                dc = (char*)uvchr_to_utf8((U8*)dc, duc);
            }
-           if (sv == left || sv == right)
-               (void)sv_usepvn(sv, dcorig, needlen);
+           if (sv == left || sv == right) {
+               (void)sv_usepvn(sv, dcorig, needlen); /* Uses Renew(). */
+               needfree = FALSE; /* sv_usepvn() moved dcorig. */
+           }
            SvCUR_set(sv, dc - dcorig);
            break;
        case OP_BIT_XOR:
            SvCUR_set(sv, dc - dcorig);
            break;
        case OP_BIT_XOR:
@@ -1266,13 +1270,16 @@ Perl_do_vop(pTHX_ I32 optype, SV *sv, SV *left, SV *right)
                duc = luc | ruc;
                dc = (char*)uvchr_to_utf8((U8*)dc, duc);
            }
                duc = luc | ruc;
                dc = (char*)uvchr_to_utf8((U8*)dc, duc);
            }
+           goto mop_up_utf; /* For consistency. */
          mop_up_utf:
            if (rulen)
                dcsave = savepvn(rc, rulen);
            else if (lulen)
                dcsave = savepvn(lc, lulen);
          mop_up_utf:
            if (rulen)
                dcsave = savepvn(rc, rulen);
            else if (lulen)
                dcsave = savepvn(lc, lulen);
-           if (sv == left || sv == right)
+           if (sv == left || sv == right) {
                (void)sv_usepvn(sv, dcorig, needlen); /* Uses Renew(). */
                (void)sv_usepvn(sv, dcorig, needlen); /* Uses Renew(). */
+               needfree = FALSE; /* sv_usepvn() moved dcorig. */
+           }
            SvCUR_set(sv, dc - dcorig);
            if (rulen)
                sv_catpvn(sv, dcsave, rulen);
            SvCUR_set(sv, dc - dcorig);
            if (rulen)
                sv_catpvn(sv, dcsave, rulen);
@@ -1283,6 +1290,8 @@ Perl_do_vop(pTHX_ I32 optype, SV *sv, SV *left, SV *right)
            Safefree(dcsave);
            break;
        }
            Safefree(dcsave);
            break;
        }
+       if (needfree)
+           Safefree(dcorig);
        SvUTF8_on(sv);
        goto finish;
     }
        SvUTF8_on(sv);
        goto finish;
     }