coverity complained minset could be -1
authorTony Cook <tony@develop-help.com>
Tue, 1 Jan 2019 00:07:10 +0000 (11:07 +1100)
committerTony Cook <tony@develop-help.com>
Tue, 1 Jan 2019 00:07:10 +0000 (11:07 +1100)
but no callers call i_map() in such a way that it can happen.

Add a belt-and-suspenders check.

Changes
map.c
t/300-transform/060-map.t

diff --git a/Changes b/Changes
index e115b31..2554022 100644 (file)
--- a/Changes
+++ b/Changes
@@ -31,6 +31,12 @@ Coverity finally finished a build, fix a few problems:
    only for the old API.)  Coverity complained that this leaked, but
    this could only occur with an invalid (NULL pointer) color object.
 
+ - the underlying implementation of the map() method could read before
+   the beginning on an allocated array if supplied with inconsistent
+   parameters, which Coverity complained about.  No Imager code calls
+   that function with inconsistent parameters, but a
+   belt-and-suspenders check was added.
+
 Imager 1.008 - 31 Dec 2018
 ============
 
diff --git a/map.c b/map.c
index 0431367..aedd0df 100644 (file)
--- a/map.c
+++ b/map.c
@@ -45,14 +45,18 @@ i_map(i_img *im, unsigned char (*maps)[256], unsigned int mask) {
 
   if (!mask) return; /* nothing to do here */
 
-  for(i=0; i<im->channels; i++)
+  for(i=0; i<im->channels; i++) {
     if (mask & (1<<i)) {
       if (minset == -1) minset = i;
       maxset = i;
     }
+  }
 
   mm_log((1, "minset=%d maxset=%d\n", minset, maxset));
 
+  if (minset == -1)
+    return;
+
   vals = mymalloc(sizeof(i_color) * im->xsize);
 
   for (y = 0; y < im->ysize; ++y) {
index ace9521..d8d8a18 100644 (file)
@@ -1,7 +1,7 @@
 #!perl -w
 use strict;
-use Test::More tests => 10;
-use Imager::Test qw(is_image);
+use Test::More;
+use Imager::Test qw(is_image test_image);
 
 -d "testout" or mkdir "testout";
 
@@ -61,3 +61,16 @@ SKIP: {
   ok($out, "map()");
   is_image($out, $cmp, "test map output");
 }
+
+{
+  # test with zero mask: coverity detected a bad channel index problem
+  # that only applies in this case
+  my $im = test_image();
+  $im->setmask(mask => 0x80);
+  is($im->getmask, 0x80, "check we set mask");
+  my @map = ( map int $_ / 2, 0 .. 255 );
+  my $out = $im->map(maps => [ (undef) x 3 ]);
+  ok($out, "map done");
+}
+
+done_testing();