From: Tony Cook Date: Mon, 29 Oct 2007 11:11:10 +0000 (+0000) Subject: - the SGI RLE compression code could overflow its compression buffer X-Git-Tag: Imager-0.61~11 X-Git-Url: http://git.imager.perl.org/imager.git/commitdiff_plain/ed1074389cab8cd55af1ab2c2814f888216a8383 - the SGI RLE compression code could overflow its compression buffer http://rt.cpan.org/Ticket/Display.html?id=30334 - the 32-bit output function used by the SGI code only handled values under 0x10000. This was most noticable when writing large RLE images. http://rt.cpan.org/Ticket/Display.html?id=30335 --- diff --git a/Changes b/Changes index b7735d7f..9427270b 100644 --- a/Changes +++ b/Changes @@ -33,6 +33,13 @@ Bug fixes: Added tests for better code coverage of the ops. http://rt.cpan.org/Ticket/Display.html?id=29296 + - the SGI RLE compression code could overflow its compression buffer + http://rt.cpan.org/Ticket/Display.html?id=30334 + + - the 32-bit output function used by the SGI code only handled values + under 0x10000. This was most noticable when writing large RLE images. + http://rt.cpan.org/Ticket/Display.html?id=30335 + Imager 0.60 - 30 August 2007 =========== diff --git a/SGI/imsgi.c b/SGI/imsgi.c index 54a2d494..547badcf 100644 --- a/SGI/imsgi.c +++ b/SGI/imsgi.c @@ -121,7 +121,7 @@ store_16(unsigned char *buf, unsigned short value) { } static void -store_32(unsigned char *buf, unsigned short value) { +store_32(unsigned char *buf, unsigned long value) { buf[0] = value >> 24; buf[1] = (value >> 16) & 0xFF; buf[2] = (value >> 8) & 0xFF; @@ -987,9 +987,8 @@ write_sgi_8_rle(i_img *img, io_glue *ig) { /* fill out the run if 2 or less samples left and there's space */ if (in_left - run_length <= 2 - && run_length + in_left - run_length <= 127) { - run_length += in_left; - in_left = 0; + && in_left <= 127) { + run_length = in_left; } in_left -= run_length; *outp++ = run_length | 0x80; @@ -1145,9 +1144,8 @@ write_sgi_16_rle(i_img *img, io_glue *ig) { /* fill out the run if 2 or less samples left and there's space */ if (in_left - run_length <= 2 - && run_length + in_left - run_length <= 127) { - run_length += in_left; - in_left = 0; + && in_left <= 127) { + run_length = in_left; } in_left -= run_length; store_16(outp, run_length | 0x80); diff --git a/SGI/t/20write.t b/SGI/t/20write.t index 1ca6aef0..879412b6 100644 --- a/SGI/t/20write.t +++ b/SGI/t/20write.t @@ -1,7 +1,7 @@ #!perl -w use strict; use Imager; -use Test::More tests => 51; +use Test::More tests => 55; use Imager::Test qw(test_image test_image_16 is_image); use IO::Seekable; @@ -11,6 +11,7 @@ Imager::init_log('testout/20write.log', 2); { my $im = test_image(); + $im->line(x1 => 0, y1 => 0, x2 => 150, y2 => 150, color => 'FF0000'); ok($im->write(file => 'testout/20verb.rgb'), "write 8-bit verbatim") or print "# ", $im->errstr, "\n"; my $im2 = Imager->new; @@ -36,6 +37,7 @@ Imager::init_log('testout/20write.log', 2); { my $im = test_image_16(); + $im->line(x1 => 0, y1 => 0, x2 => 150, y2 => 150, color => 'FF0000'); ok($im->write(file => 'testout/20verb16.rgb'), "write 16-bit verbatim") or print "# ", $im->errstr, "\n"; my $im2 = Imager->new; @@ -57,6 +59,24 @@ Imager::init_log('testout/20write.log', 2); is($im3->tags(name => 'sgi_rle'), 1, "check not rle"); is($im3->tags(name => 'sgi_bpc'), 2, "check bpc"); is($im3->tags(name => 'i_comment'), 'test', "check i_comment set"); + + my $imbig = Imager->new(xsize => 300, ysize => 300, bits => 16); + $imbig->paste(src => $im, tx => 0, ty => 0); + $imbig->paste(src => $im, tx => 150, ty => 0); + $imbig->paste(src => $im, tx => 0, ty => 150); + $imbig->paste(src => $im, tx => 150, ty => 150); + for my $t (0 .. 74) { + $imbig->line(x1 => $t*4, y1 => 0, x2 => 3+$t*4, y2 => 299, + color => [ 255 - $t, 0, 0 ]); + } + my $data; + ok($imbig->write(data => \$data, type => 'sgi', sgi_rle => 1), + "write larger image"); + cmp_ok(length($data), '>', 0x10000, "check output large enough for test"); + print "# ", length $data, "\n"; + my $imbigcmp = Imager->new; + ok($imbigcmp->read(data => $data), "read larger image"); + is_image($imbig, $imbigcmp, "check large image matches"); } { diff --git a/TODO b/TODO index 256fba2a..fe2350b4 100644 --- a/TODO +++ b/TODO @@ -26,7 +26,7 @@ TIFF improvements (to be detailed) (#20329) both contig and non-contiguous - possible extra code for handling 8-bit CMYK (#29353) -regmach.c fixes/tests (#29296) +regmach.c fixes/tests (#29296) (done) sample: scaling an animated gif (#27591) (done)