From 588aa082d364ac67b55d97c28674e1d445fdd0fc Mon Sep 17 00:00:00 2001 From: John Cupitt Date: Thu, 19 Mar 2009 23:29:12 +0000 Subject: [PATCH] allow open of truncated images, but block data access --- ChangeLog | 3 ++- TODO | 5 +++++ include/vips/vips.h | 5 +++++ libsrc/iofuncs/im_init.c | 4 ++++ libsrc/iofuncs/im_open_vips.c | 10 ++++++---- libsrc/iofuncs/window.c | 11 +++++++++++ 6 files changed, 33 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index ba8b4e76..c7e0be7d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -4,7 +4,8 @@ - configure spots support for "restrict" - reset dcm:display-range on magick read to help DICOM - saner im_buildlut() behaviour -- added im_gauss_imask_sep() +- added im_gauss_imask_sep() +- allow open of truncated images, but block pixel access 3/3/09 started 7.17.2 - im_magick2vips.c: allow funky bit depths, like 14 (thanks Mikkel) diff --git a/TODO b/TODO index 2fb18497..682d8e7a 100644 --- a/TODO +++ b/TODO @@ -49,6 +49,11 @@ WONTFIX for 7.18 ================ +- bilateral filtering, see: + + http://en.wikipedia.org/wiki/Bilateral_filter + http://www.shellandslate.com/fastmedian.html + - try making vips_add(), an operator as a class - need to write interpolate docs ... manpages and tutorial diff --git a/include/vips/vips.h b/include/vips/vips.h index 08601396..7ebbd624 100644 --- a/include/vips/vips.h +++ b/include/vips/vips.h @@ -359,6 +359,11 @@ typedef struct im__IMAGE { GSList *evalstartfns; /* list of start eval callbacks */ GSList *preclosefns; /* list of pre-close callbacks */ GSList *invalidatefns; /* list of invalidate callbacks */ + + /* Set this to indicate a truncated file. We've been able to read the + * header, but don't try mapping any of it or you'll crash. + */ + int nodata; } IMAGE; /* Only define if IM_ENABLE_DEPRECATED is set. diff --git a/libsrc/iofuncs/im_init.c b/libsrc/iofuncs/im_init.c index d41fddab..75e92951 100644 --- a/libsrc/iofuncs/im_init.c +++ b/libsrc/iofuncs/im_init.c @@ -31,6 +31,8 @@ * - added preclose and evalstart * 9/8/08 * - lock global image list (thanks lee) + * 19/3/09 + * - add nodata */ /* @@ -168,6 +170,8 @@ im_init( const char *filename ) im->preclosefns = NULL; im->invalidatefns = NULL; + im->nodata = 0; + if( !(im->filename = im_strdup( NULL, filename )) ) { im_close( im ); return( NULL ); diff --git a/libsrc/iofuncs/im_open_vips.c b/libsrc/iofuncs/im_open_vips.c index a33123d2..8ff551a5 100644 --- a/libsrc/iofuncs/im_open_vips.c +++ b/libsrc/iofuncs/im_open_vips.c @@ -3,6 +3,8 @@ * 22/5/08 * - from im_open.c, im_openin.c, im_desc_hd.c, im_readhist.c, * im_openout.c + * 19/3/09 + * - block mmaps of nodata images */ /* @@ -914,9 +916,9 @@ im__read_header( IMAGE *image ) if( (length = im_file_length( image->fd )) == -1 ) return( -1 ); if( psize > length ) { - im_error( "im_openin", _( "unable to open \"%s\", %s" ), + im_warn( "im_openin", _( "unable to read data for \"%s\", %s" ), image->filename, _( "file has been truncated" ) ); - return( -1 ); + image->nodata = 1; } /* Set demand style. Allow the most permissive sort. @@ -960,7 +962,7 @@ im_openin( IMAGE *image ) size = (gint64) IM_IMAGE_SIZEOF_LINE( image ) * image->Ysize + image->sizeof_header; - if( size < im__mmap_limit ) { + if( size < im__mmap_limit && !image->nodata ) { if( im_mapfile( image ) ) return( -1 ); image->data = image->baseaddr + image->sizeof_header; @@ -981,7 +983,7 @@ im_openin( IMAGE *image ) return( 0 ); } -/* Open, then mmap() read/write. This is old and deprecated API, uuse +/* Open, then mmap() read/write. This is old and deprecated API, use * im_vips_open() in preference. */ int diff --git a/libsrc/iofuncs/window.c b/libsrc/iofuncs/window.c index 6539ea44..f7eac7b0 100644 --- a/libsrc/iofuncs/window.c +++ b/libsrc/iofuncs/window.c @@ -2,6 +2,8 @@ * * 30/10/06 * - from region.c + * 19/3/09 + * - block mmaps of nodata images */ /* @@ -217,6 +219,15 @@ im_window_set( im_window_t *window, int top, int height ) gint64 start, end, pagestart; size_t length, pagelength; + /* Make sure this image has data. + */ + if( window->im->nodata ) { + im_error( "im_window_set", + _( "unable to read data for \"%s\", %s" ), + window->im->filename, _( "file has been truncated" ) ); + return( -1 ); + } + /* Calculate start and length for our window. */ start = window->im->sizeof_header +