fix a tiff2vips crash on fractional samples

tiff2vips failed if samples_per_pixel was not a multiple of 8, ie.
byte-aligned, and the image was not palette-ised

thanks HongxuChen

see https://github.com/jcupitt/libvips/issues/1039
This commit is contained in:
John Cupitt 2018-07-21 17:06:01 +01:00
parent 3565808281
commit 0077017ad8
2 changed files with 24 additions and 6 deletions

View File

@ -179,6 +179,8 @@
* - page > 0 could break edge tiles or strips * - page > 0 could break edge tiles or strips
* 26/4/18 * 26/4/18
* - add n-pages metadata item * - add n-pages metadata item
* 21/7/18
* - check for non-byte-multiple bits_per_sample [HongxuChen]
*/ */
/* /*
@ -544,6 +546,21 @@ rtiff_check_min_samples( Rtiff *rtiff, int samples_per_pixel )
return( 0 ); return( 0 );
} }
/* Only allow samples which are whole bytes in size.
*/
static int
rtiff_non_fractional( Rtiff *rtiff )
{
if( rtiff->header.bits_per_sample % 8 != 0 ||
rtiff->header.bits_per_sample == 0 ) {
vips_error( "tiff2vips", "%s", _( "samples_per_pixel "
"not a whole number of bytes" ) );
return( -1 );
}
return( 0 );
}
static int static int
rtiff_check_interpretation( Rtiff *rtiff, int photometric_interpretation ) rtiff_check_interpretation( Rtiff *rtiff, int photometric_interpretation )
{ {
@ -811,7 +828,8 @@ rtiff_parse_onebit( Rtiff *rtiff, VipsImage *out )
/* Per-scanline process function for greyscale images. /* Per-scanline process function for greyscale images.
*/ */
static void static void
rtiff_greyscale_line( Rtiff *rtiff, VipsPel *q, VipsPel *p, int n, void *client ) rtiff_greyscale_line( Rtiff *rtiff,
VipsPel *q, VipsPel *p, int n, void *client )
{ {
int samples_per_pixel = rtiff->header.samples_per_pixel; int samples_per_pixel = rtiff->header.samples_per_pixel;
int photometric_interpretation = int photometric_interpretation =
@ -862,7 +880,8 @@ rtiff_greyscale_line( Rtiff *rtiff, VipsPel *q, VipsPel *p, int n, void *client
static int static int
rtiff_parse_greyscale( Rtiff *rtiff, VipsImage *out ) rtiff_parse_greyscale( Rtiff *rtiff, VipsImage *out )
{ {
if( rtiff_check_min_samples( rtiff, 1 ) ) if( rtiff_check_min_samples( rtiff, 1 ) ||
rtiff_non_fractional( rtiff ) )
return( -1 ); return( -1 );
out->Bands = rtiff->header.samples_per_pixel; out->Bands = rtiff->header.samples_per_pixel;
@ -1144,6 +1163,9 @@ rtiff_parse_copy( Rtiff *rtiff, VipsImage *out )
int photometric_interpretation = int photometric_interpretation =
rtiff->header.photometric_interpretation; rtiff->header.photometric_interpretation;
if( rtiff_non_fractional( rtiff ) )
return( -1 );
out->Bands = samples_per_pixel; out->Bands = samples_per_pixel;
out->BandFmt = rtiff_guess_format( rtiff ); out->BandFmt = rtiff_guess_format( rtiff );
if( out->BandFmt == VIPS_FORMAT_NOTSET ) if( out->BandFmt == VIPS_FORMAT_NOTSET )

View File

@ -840,10 +840,6 @@ build_xml_meta( VipsMeta *meta, VipsDbuf *dbuf )
g_value_unset( &save_value ); g_value_unset( &save_value );
} }
else {
printf( "unable to convert %s for save\n",
g_type_name( type ) );
}
return( NULL ); return( NULL );
} }