summaryrefslogtreecommitdiff
path: root/doop.c
diff options
context:
space:
mode:
authorJarkko Hietaniemi <jhi@iki.fi>2006-04-16 14:19:25 +0300
committerNicholas Clark <nick@ccl4.org>2006-04-17 10:24:58 +0000
commit2d78db9da3a2e0242b1652394b939dc5b5fab5e5 (patch)
tree88e0c83d60a5a85490235df80f82c31fe4092178 /doop.c
parent77cb431f8c908a31b286bd0ba26649cb6041bd72 (diff)
downloadperl-2d78db9da3a2e0242b1652394b939dc5b5fab5e5.tar.gz
The danger of piping an mbox to patch is that it contains more than
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
Diffstat (limited to 'doop.c')
-rw-r--r--doop.c19
1 files changed, 14 insertions, 5 deletions
diff --git a/doop.c b/doop.c
index 5972dbd2a6..3143467e3d 100644
--- 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;
+ bool needfree = FALSE;
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;
+ 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);
+ needfree = TRUE;
}
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() */
}
- SvCUR_set(sv, len);
- (void)SvPOK_only(sv);
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);
}
- 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:
@@ -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);
}
+ goto mop_up_utf; /* For consistency. */
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(). */
+ needfree = FALSE; /* sv_usepvn() moved dcorig. */
+ }
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;
}
+ if (needfree)
+ Safefree(dcorig);
SvUTF8_on(sv);
goto finish;
}