This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Re: [PATCH] update to pp_complement() via Coverity
authorSADAHIRO Tomoyuki <BQW10602@nifty.com>
Sun, 16 Apr 2006 18:45:37 +0000 (03:45 +0900)
committerNicholas Clark <nick@ccl4.org>
Mon, 17 Apr 2006 15:11:03 +0000 (15:11 +0000)
Message-Id: <20060416184044.4ADB.BQW10602@nifty.com>
Date: Sun, 16 Apr 2006 18:45:37 +0900

Subject: Re: [PATCH] update to pp_complement() via Coverity
From: SADAHIRO Tomoyuki <bqw10602@nifty.com>
Message-Id: <20060417230614.20A5.BQW10602@nifty.com>
Date: Mon, 17 Apr 2006 23:06:21 +0900

p4raw-id: //depot/perl@27871

pp.c
t/op/bop.t

diff --git a/pp.c b/pp.c
index 8914545..7a70e15 100644 (file)
--- a/pp.c
+++ b/pp.c
@@ -2433,10 +2433,12 @@ PP(pp_complement)
          UV nchar = 0;
          UV nwide = 0;
          U8 * const send = tmps + len;
+         U8 * const origtmps = tmps;
+         const UV utf8flags = UTF8_ALLOW_ANYUV;
 
          while (tmps < send) {
-           const UV c = utf8n_to_uvchr(tmps, send-tmps, &l, UTF8_ALLOW_ANYUV);
-           tmps += UTF8SKIP(tmps);
+           const UV c = utf8n_to_uvchr(tmps, send-tmps, &l, utf8flags);
+           tmps += l;
            targlen += UNISKIP(~c);
            nchar++;
            if (c > 0xff)
@@ -2444,17 +2446,17 @@ PP(pp_complement)
          }
 
          /* Now rewind strings and write them. */
-         tmps -= len;
+         tmps = origtmps;
 
          if (nwide) {
              U8 *result;
              U8 *p;
 
-             Newxz(result, targlen + 1, U8);
+             Newx(result, targlen + 1, U8);
              p = result;
              while (tmps < send) {
-                 const UV c = utf8n_to_uvchr(tmps, send-tmps, &l, UTF8_ALLOW_ANYUV);
-                 tmps += UTF8SKIP(tmps);
+                 const UV c = utf8n_to_uvchr(tmps, send-tmps, &l, utf8flags);
+                 tmps += l;
                  p = uvchr_to_utf8_flags(p, ~c, UNICODE_ALLOW_ANY);
              }
              *p = '\0';
@@ -2466,11 +2468,11 @@ PP(pp_complement)
              U8 *result;
              U8 *p;
 
-             Newxz(result, nchar + 1, U8);
+             Newx(result, nchar + 1, U8);
              p = result;
              while (tmps < send) {
-                 const U8 c = (U8)utf8n_to_uvchr(tmps, 0, &l, UTF8_ALLOW_ANY);
-                 tmps += UTF8SKIP(tmps);
+                 const U8 c = (U8)utf8n_to_uvchr(tmps, send-tmps, &l, utf8flags);
+                 tmps += l;
                  *p++ = ~c;
              }
              *p = '\0';
index 28ac60e..7e8a0c7 100755 (executable)
@@ -15,7 +15,7 @@ BEGIN {
 # 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 => 160;
+plan tests => 161;
 
 # numerics
 ok ((0xdead & 0xbeef) == 0x9ead);
@@ -412,3 +412,19 @@ SKIP: {
     is($b, chr(0x1FE) x 0x0FF . chr(0x101) x 2);
 }
 
+# update to pp_complement() via Coverity
+SKIP: {
+  # UTF-EBCDIC is limited to 0x7fffffff and can't encode ~0.
+  skip "EBCDIC" if $Is_EBCDIC;
+
+  my $str = "\x{10000}\x{800}";
+  # U+10000 is four bytes in UTF-8/UTF-EBCDIC.
+  # U+0800 is three bytes in UTF-8/UTF-EBCDIC.
+
+  no warnings "utf8";
+  { use bytes; $str =~ s/\C\C\z//; }
+
+  # it's really bogus that (~~malformed) is \0.
+  my $ref = "\x{10000}\0";
+  is(~~$str, $ref);
+}