Change 27801 by [EMAIL PROTECTED] on 2006/04/14 16:11:19 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) From: [EMAIL PROTECTED] (Jarkko Hietaniemi) Date: Thu, 13 Apr 2006 19:20:46 +0300 (EEST) Message-Id: <[EMAIL PROTECTED]>
Affected files ... ... //depot/perl/doop.c#181 edit ... //depot/perl/pod/perlapi.pod#250 edit ... //depot/perl/sv.c#1241 edit ... //depot/perl/t/op/bop.t#28 edit Differences ... ==== //depot/perl/doop.c#181 (text) ==== Index: perl/doop.c --- perl/doop.c#180~27688~ 2006-04-02 13:58:59.000000000 -0700 +++ perl/doop.c 2006-04-14 09:11:19.000000000 -0700 @@ -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); ==== //depot/perl/pod/perlapi.pod#250 (text+w) ==== Index: perl/pod/perlapi.pod --- perl/pod/perlapi.pod#249~27626~ 2006-03-29 00:55:21.000000000 -0800 +++ perl/pod/perlapi.pod 2006-04-14 09:11:19.000000000 -0700 @@ -5725,12 +5725,14 @@ =item sv_usepvn X<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>. void sv_usepvn(SV* sv, char* ptr, STRLEN len) ==== //depot/perl/sv.c#1241 (text) ==== Index: perl/sv.c --- perl/sv.c#1240~27794~ 2006-04-13 11:31:54.000000000 -0700 +++ perl/sv.c 2006-04-14 09:11:19.000000000 -0700 @@ -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 ==== //depot/perl/t/op/bop.t#28 (xtext) ==== Index: perl/t/op/bop.t --- perl/t/op/bop.t#27~26136~ 2005-11-15 08:33:02.000000000 -0800 +++ perl/t/op/bop.t 2006-04-14 09:11:19.000000000 -0700 @@ -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); +} + End of Patch.