develooper Front page | perl.perl5.porters | Postings from April 2006

[PATCH] doop.c: (Coverity) found a bug but not quite what Coverity thought it did (try valgrind on the new bop.t without the doop.c patch)

Thread Next
From:
jhi
Date:
April 13, 2006 09:21
Subject:
[PATCH] doop.c: (Coverity) found a bug but not quite what Coverity thought it did (try valgrind on the new bop.t without the doop.c patch)
Message ID:
20060413162046.5F9636D08C@ugli.hut.fi
--- doop.c.dist	2006-04-13 18:44:51.000000000 +0300
+++ doop.c	2006-04-13 19:17:55.000000000 +0300
@@ -1221,7 +1221,8 @@
     (void)SvPOK_only(sv);
     if (left_utf || right_utf) {
 	UV duc, luc, ruc;
-	char * const dcsave = dc;
+	char *dcorig = dc;
+	char *dcsave = NULL;
 	STRLEN lulen = leftlen;
 	STRLEN rulen = rightlen;
 	STRLEN ulen;
@@ -1239,8 +1240,8 @@
 		dc = (char*)uvchr_to_utf8((U8*)dc, duc);
 	    }
 	    if (sv == left || sv == right)
-		(void)sv_usepvn(sv, dcsave, needlen);
-	    SvCUR_set(sv, dc - dcsave);
+		(void)sv_usepvn(sv, dcorig, needlen);
+	    SvCUR_set(sv, dc - dcorig);
 	    break;
 	case OP_BIT_XOR:
 	    while (lulen && rulen) {
@@ -1266,15 +1267,20 @@
 		dc = (char*)uvchr_to_utf8((U8*)dc, duc);
 	    }
 	  mop_up_utf:
+	    if (rulen)
+		dcsave = savepvn(rc, rulen);
+	    else if (lulen)
+		dcsave = savepvn(lc, lulen);
 	    if (sv == left || sv == right)
-		(void)sv_usepvn(sv, dcsave, needlen);
-	    SvCUR_set(sv, dc - dcsave);
+		(void)sv_usepvn(sv, dcorig, needlen); /* Uses Renew(). */
+	    SvCUR_set(sv, dc - dcorig);
 	    if (rulen)
-		sv_catpvn(sv, rc, rulen);
+		sv_catpvn(sv, dcsave, rulen);
 	    else if (lulen)
-		sv_catpvn(sv, lc, lulen);
+		sv_catpvn(sv, dcsave, lulen);
 	    else
 		*SvEND(sv) = '\0';
+	    Safefree(dcsave);
 	    break;
 	}
 	SvUTF8_on(sv);
--- sv.c.dist	2006-04-13 18:55:22.000000000 +0300
+++ sv.c	2006-04-13 18:56:51.000000000 +0300
@@ -3883,12 +3883,14 @@
 /*
 =for apidoc sv_usepvn
 
-Tells an SV to use C<ptr> to find its string value.  Normally the string is
-stored inside the SV but sv_usepvn allows the SV to use an outside string.
-The C<ptr> should point to memory that was allocated by C<malloc>.  The
-string length, C<len>, must be supplied.  This function will realloc the
-memory pointed to by C<ptr>, so that pointer should not be freed or used by
-the programmer after giving it to sv_usepvn.  Does not handle 'set' magic.
+Tells an SV to use C<ptr> to find its string value.  Normally the
+string is stored inside the SV but sv_usepvn allows the SV to use an
+outside string.  The C<ptr> should point to memory that was allocated
+by C<malloc>.  The string length, C<len>, must be supplied.  This
+function will realloc (i.e. move) the memory pointed to by C<ptr>,
+so that pointer should not be freed or used by the programmer after
+giving it to sv_usepvn, and neither should any pointers from "behind"
+that pointer (e.g. ptr + 1) be used.  Does not handle 'set' magic.
 See C<sv_usepvn_mg>.
 
 =cut
--- t/op/bop.t.dist	2006-04-13 18:51:00.000000000 +0300
+++ t/op/bop.t	2006-04-13 19:16:12.000000000 +0300
@@ -15,7 +15,7 @@
 # If you find tests are failing, please try adding names to tests to track
 # down where the failure is, and supply your new names as a patch.
 # (Just-in-time test naming)
-plan tests => 148;
+plan tests => 160;
 
 # numerics
 ok ((0xdead & 0xbeef) == 0x9ead);
@@ -340,3 +340,75 @@
     $b &= "b";
     ok($b =~ /b+$/, 'Unicode "b" is NUL-terminated');
 }
+
+{
+    $a = chr(0x101) x 0x101;
+    $b = chr(0x0FF) x 0x0FF;
+
+    $c = $a | $b;
+    is($c, chr(0x1FF) x 0xFF . chr(0x101) x 2);
+
+    $c = $b | $a;
+    is($c, chr(0x1FF) x 0xFF . chr(0x101) x 2);
+
+    $c = $a & $b;
+    is($c, chr(0x001) x 0x0FF);
+
+    $c = $b & $a;
+    is($c, chr(0x001) x 0x0FF);
+
+    $c = $a ^ $b;
+    is($c, chr(0x1FE) x 0x0FF . chr(0x101) x 2);
+
+    $c = $b ^ $a;
+    is($c, chr(0x1FE) x 0x0FF . chr(0x101) x 2);
+}
+
+{
+    $a = chr(0x101) x 0x101;
+    $b = chr(0x0FF) x 0x0FF;
+
+    $a |= $b;
+    is($a, chr(0x1FF) x 0xFF . chr(0x101) x 2);
+}
+
+{
+    $a = chr(0x101) x 0x101;
+    $b = chr(0x0FF) x 0x0FF;
+
+    $b |= $a;
+    is($b, chr(0x1FF) x 0xFF . chr(0x101) x 2);
+}
+
+{
+    $a = chr(0x101) x 0x101;
+    $b = chr(0x0FF) x 0x0FF;
+
+    $a &= $b;
+    is($a, chr(0x001) x 0x0FF);
+}
+
+{
+    $a = chr(0x101) x 0x101;
+    $b = chr(0x0FF) x 0x0FF;
+
+    $b &= $a;
+    is($b, chr(0x001) x 0x0FF);
+}
+
+{
+    $a = chr(0x101) x 0x101;
+    $b = chr(0x0FF) x 0x0FF;
+
+    $a ^= $b;
+    is($a, chr(0x1FE) x 0x0FF . chr(0x101) x 2);
+}
+
+{
+    $a = chr(0x101) x 0x101;
+    $b = chr(0x0FF) x 0x0FF;
+
+    $b ^= $a;
+    is($b, chr(0x1FE) x 0x0FF . chr(0x101) x 2);
+}
+

Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About