diff --git a/ChangeLog b/ChangeLog index ab1fdf55..82beb035 100644 --- a/ChangeLog +++ b/ChangeLog @@ -31,6 +31,10 @@ - added vips_perlin(), generate Perlin noise - gif loader can write 1, 2, 3, or 4 bands depending on file contents +30/7/16 started 8.3.3 +- fix performance regression in 8.3.2, thanks Lovell +- yet more robust vips file reading + 18/5/16 started 8.3.2 - more robust vips image reading - more robust tiff read [Matt Richards] diff --git a/configure.ac b/configure.ac index 0c4fed37..d7293543 100644 --- a/configure.ac +++ b/configure.ac @@ -38,7 +38,7 @@ VIPS_VERSION_STRING=$VIPS_VERSION-`date` # binary interface changes not backwards compatible?: reset age to 0 LIBRARY_CURRENT=46 -LIBRARY_REVISION=2 +LIBRARY_REVISION=3 LIBRARY_AGE=4 # patched into include/vips/version.h diff --git a/libvips/include/vips/header.h b/libvips/include/vips/header.h index 2530adf7..b60e1739 100644 --- a/libvips/include/vips/header.h +++ b/libvips/include/vips/header.h @@ -134,6 +134,7 @@ extern "C" { #define VIPS_META_ORIENTATION "orientation" guint64 vips_format_sizeof( VipsBandFormat format ); +guint64 vips_format_sizeof_unsafe( VipsBandFormat format ); int vips_image_get_width( const VipsImage *image ); int vips_image_get_height( const VipsImage *image ); diff --git a/libvips/include/vips/image.h b/libvips/include/vips/image.h index 3fedba71..60e8f59b 100644 --- a/libvips/include/vips/image.h +++ b/libvips/include/vips/image.h @@ -363,10 +363,11 @@ GType vips_image_get_type(void); /* Has to be guint64 and not size_t/off_t since we have to be able to address * huge images on platforms with 32-bit files. */ + /* Pixel address calculation macros. */ #define VIPS_IMAGE_SIZEOF_ELEMENT( I ) \ - (vips_format_sizeof((I)->BandFmt)) + (vips_format_sizeof_unsafe((I)->BandFmt)) #define VIPS_IMAGE_SIZEOF_PEL( I ) \ (VIPS_IMAGE_SIZEOF_ELEMENT( I ) * (I)->Bands) #define VIPS_IMAGE_SIZEOF_LINE( I ) \ diff --git a/libvips/iofuncs/header.c b/libvips/iofuncs/header.c index 2b5a6aa3..2ee3b7d8 100644 --- a/libvips/iofuncs/header.c +++ b/libvips/iofuncs/header.c @@ -201,6 +201,23 @@ vips_format_sizeof( VipsBandFormat format ) return( vips__image_sizeof_bandformat[format] ); } +/** + * vips_format_sizeof_unsafe: (skip) + * @format: format type + * + * A fast but dangerous version of vips_format_sizeof(). You must have + * previously range-checked @format or you'll crash. + * + * Returns: number of bytes for a band format. + */ +guint64 +vips_format_sizeof_unsafe( VipsBandFormat format ) +{ + g_assert( 0 <= format && format <= VIPS_FORMAT_DPCOMPLEX ); + + return( vips__image_sizeof_bandformat[format] ); +} + #ifdef DEBUG /* Check that this meta is on the hash table. */ diff --git a/libvips/iofuncs/vips.c b/libvips/iofuncs/vips.c index 9ed6b814..92dfb144 100644 --- a/libvips/iofuncs/vips.c +++ b/libvips/iofuncs/vips.c @@ -1,4 +1,4 @@ -/* Read and write a vips file +/* Read and write a vips file. * * 22/5/08 * - from im_open.c, im_openin.c, im_desc_hd.c, im_readhist.c, @@ -330,6 +330,18 @@ vips__read_header_bytes( VipsImage *im, unsigned char *from ) im->Xres = im->Xres_float; im->Yres = im->Yres_float; + /* Some protection against malicious files. We also check predicted + * (based on these values) against real file length, see below. + */ + im->Xsize = VIPS_CLIP( 1, im->Xsize, VIPS_MAX_COORD ); + im->Ysize = VIPS_CLIP( 1, im->Ysize, VIPS_MAX_COORD ); + im->Bands = VIPS_CLIP( 1, im->Bands, VIPS_MAX_COORD ); + im->BandFmt = VIPS_CLIP( 0, im->BandFmt, VIPS_FORMAT_LAST - 1 ); + + /* Type, Coding, Offset, Res, etc. don't affect vips file layout, just + * pixel interpretation, don't clip them. + */ + return( 0 ); }