[rt #69242] don't leak memory when setscanline() is called with a bad palette index
authorTony Cook <tony@develop-help.com>
Mon, 15 Aug 2011 10:56:33 +0000 (20:56 +1000)
committerTony Cook <tony@develop-help.com>
Mon, 15 Aug 2011 10:56:33 +0000 (20:56 +1000)
Imager.xs
t/t023palette.t

index 5b919d1..e11fd03 100644 (file)
--- a/Imager.xs
+++ b/Imager.xs
@@ -28,6 +28,19 @@ extern "C" {
 
 #include "imperl.h"
 
+/*
+
+Allocate memory that will be discarded when mortals are discarded.
+
+*/
+
+static void *
+malloc_temp(pTHX_ size_t size) {
+  SV *sv = sv_2mortal(newSV(size));
+
+  return SvPVX(sv);
+}
+
 /* These functions are all shared - then comes platform dependant code */
 static int getstr(void *hv_t,char *key,char **store) {
   dTHX;
@@ -2883,16 +2896,15 @@ i_ppal(im, l, y, ...)
         i_img_dim     y
       PREINIT:
         i_palidx *work;
-        int i;
+        i_img_dim i;
       CODE:
         if (items > 3) {
-          work = mymalloc(sizeof(i_palidx) * (items-3));
+          work = malloc_temp(aTHX_ sizeof(i_palidx) * (items-3));
           for (i=0; i < items-3; ++i) {
             work[i] = SvIV(ST(i+3));
           }
           validate_i_ppal(im, work, items - 3);
           RETVAL = i_ppal(im, l, l+items-3, y, work);
-          myfree(work);
         }
         else {
           RETVAL = 0;
index c0ec8ca..38daec4 100644 (file)
@@ -1,7 +1,7 @@
 #!perl -w
 # some of this is tested in t01introvert.t too
 use strict;
-use Test::More tests => 128;
+use Test::More tests => 132;
 BEGIN { use_ok("Imager"); }
 
 use Imager::Test qw(image_bounds_checks test_image is_color3 isnt_image);
@@ -354,6 +354,39 @@ cmp_ok(Imager->errstr, '=~', qr/Channels must be positive and <= 4/,
   isnt_image($palim, $blank, "make sure paletted isn't all black");
 }
 
+{ # check validation of palette entries
+  my $im = Imager->new(xsize => 10, ysize => 10, type => 'paletted');
+  $im->addcolors(colors => [ $black, $red ]);
+  {
+    my $no_croak = eval {
+      $im->setscanline(y => 0, type => 'index', pixels => [ 0, 1 ]);
+      1;
+    };
+    ok($no_croak, "valid values don't croak");
+  }
+  {
+    my $no_croak = eval {
+      $im->setscanline(y => 0, type => 'index', pixels => pack("C*", 0, 1));
+      1;
+    };
+    ok($no_croak, "valid values don't croak (packed)");
+  }
+  {
+    my $no_croak = eval {
+      $im->setscanline(y => 0, type => 'index', pixels => [ 2, 255 ]);
+      1;
+    };
+    ok(!$no_croak, "invalid values do croak");
+  }
+  {
+    my $no_croak = eval {
+      $im->setscanline(y => 0, type => 'index', pixels => pack("C*", 2, 255));
+      1;
+    };
+    ok(!$no_croak, "invalid values do croak (packed)");
+  }
+}
+
 Imager->close_log;
 
 unless ($ENV{IMAGER_KEEP_FILES}) {