better behaviour for truncated PNG files

truncated PNG files failed with an error, even if --fail was not set ...
instead, just warn, and only error out if fail is on

see https://github.com/jcupitt/libvips/issues/629
This commit is contained in:
John Cupitt 2017-03-30 17:13:25 +01:00
parent 6fffc3f47f
commit d5a706e47e
6 changed files with 41 additions and 27 deletions

View File

@ -1,3 +1,6 @@
25/3/17 started 8.5.2
- better behaviour for truncated PNG files, thanks Yury
25/3/17 started 8.5.1
- init more classes earlier, thanks David

View File

@ -2,7 +2,7 @@
# also update the version number in the m4 macros below
AC_INIT([vips], [8.5.1], [vipsip@jiscmail.ac.uk])
AC_INIT([vips], [8.5.2], [vipsip@jiscmail.ac.uk])
# required for gobject-introspection
AC_PREREQ(2.62)
@ -18,7 +18,7 @@ AC_CONFIG_MACRO_DIR([m4])
# user-visible library versioning
m4_define([vips_major_version], [8])
m4_define([vips_minor_version], [5])
m4_define([vips_micro_version], [1])
m4_define([vips_micro_version], [2])
m4_define([vips_version],
[vips_major_version.vips_minor_version.vips_micro_version])
@ -38,7 +38,7 @@ VIPS_VERSION_STRING=$VIPS_VERSION-`date`
# binary interface changes not backwards compatible?: reset age to 0
LIBRARY_CURRENT=49
LIBRARY_REVISION=1
LIBRARY_REVISION=2
LIBRARY_AGE=7
# patched into include/vips/version.h

View File

@ -87,7 +87,7 @@ png2vips( const char *name, IMAGE *out, gboolean header_only )
return( -1 );
}
else {
if( vips__png_read( filename, out ) )
if( vips__png_read( filename, out, TRUE ) )
return( -1 );
}
#else

View File

@ -177,15 +177,15 @@ int vips__jpeg_read_buffer( const void *buf, size_t len, VipsImage *out,
gboolean header_only, int shrink, int fail, gboolean autorotate );
int vips__png_header( const char *name, VipsImage *out );
int vips__png_read( const char *name, VipsImage *out );
int vips__png_read( const char *name, VipsImage *out, gboolean fail );
gboolean vips__png_ispng_buffer( const void *buf, size_t len );
int vips__png_ispng( const char *filename );
gboolean vips__png_isinterlaced( const char *filename );
gboolean vips__png_isinterlaced_buffer( const void *buffer, size_t length );
extern const char *vips__png_suffs[];
int vips__png_read_buffer( const void *buffer, size_t length, VipsImage *out );
int vips__png_header_buffer( const void *buffer, size_t length,
VipsImage *out );
int vips__png_read_buffer( const void *buffer, size_t length, VipsImage *out,
gboolean fail );
int vips__png_header_buffer( const void *buffer, size_t length, VipsImage *out );
int vips__png_write( VipsImage *in, const char *filename,
int compress, int interlace, const char *profile,

View File

@ -106,7 +106,7 @@ vips_foreign_load_png_load( VipsForeignLoad *load )
{
VipsForeignLoadPng *png = (VipsForeignLoadPng *) load;
if( vips__png_read( png->filename, load->real ) )
if( vips__png_read( png->filename, load->real, load->fail ) )
return( -1 );
return( 0 );
@ -201,7 +201,7 @@ vips_foreign_load_png_buffer_load( VipsForeignLoad *load )
VipsForeignLoadPngBuffer *buffer = (VipsForeignLoadPngBuffer *) load;
if( vips__png_read_buffer( buffer->buf->data, buffer->buf->length,
load->real ) )
load->real, load->fail ) )
return( -1 );
return( 0 );

View File

@ -61,6 +61,8 @@
* - invalidate operation on read error
* 27/2/17
* - use dbuf for buffer output
* 30/3/17
* - better behaviour for truncated png files, thanks Yury
*/
/*
@ -125,8 +127,8 @@ user_error_function( png_structp png_ptr, png_const_charp error_msg )
/* This function must not return or the default error handler will be
* invoked.
*/
longjmp( png_jmpbuf( png_ptr ), -1 );
*/
}
static void
@ -140,6 +142,7 @@ user_warning_function( png_structp png_ptr, png_const_charp warning_msg )
typedef struct {
char *name;
VipsImage *out;
gboolean fail;
int y_pos;
png_structp pPng;
@ -176,7 +179,7 @@ read_close_cb( VipsImage *out, Read *read )
}
static Read *
read_new( VipsImage *out )
read_new( VipsImage *out, gboolean fail )
{
Read *read;
@ -184,6 +187,7 @@ read_new( VipsImage *out )
return( NULL );
read->name = NULL;
read->fail = fail;
read->out = out;
read->y_pos = 0;
read->pPng = NULL;
@ -221,11 +225,11 @@ read_new( VipsImage *out )
}
static Read *
read_new_filename( VipsImage *out, const char *name )
read_new_filename( VipsImage *out, const char *name, gboolean fail )
{
Read *read;
if( !(read = read_new( out )) )
if( !(read = read_new( out, fail )) )
return( NULL );
read->name = vips_strdup( VIPS_OBJECT( out ), name );
@ -437,7 +441,7 @@ vips__png_header( const char *name, VipsImage *out )
{
Read *read;
if( !(read = read_new_filename( out, name )) ||
if( !(read = read_new_filename( out, name, TRUE )) ||
png2vips_header( read, out ) )
return( -1 );
@ -539,10 +543,15 @@ png2vips_generate( VipsRegion *or,
read->y_pos += 1;
}
/* Turn errors back on. png_read_end() can trigger them too.
/* Turn errors back on. png_read_end() can trigger them too, for
* example for a truncated file.
*/
if( setjmp( png_jmpbuf( read->pPng ) ) )
return( -1 );
if( setjmp( png_jmpbuf( read->pPng ) ) ) {
if( read->fail )
return( -1 );
return( 0 );
}
/* We need to shut down the reader immediately at the end of read or
* we won't detach ready for the next image.
@ -566,7 +575,7 @@ vips__png_isinterlaced( const char *filename )
int interlace_type;
image = vips_image_new();
if( !(read = read_new_filename( image, filename )) ) {
if( !(read = read_new_filename( image, filename, TRUE )) ) {
g_object_unref( image );
return( -1 );
}
@ -610,7 +619,7 @@ png2vips_image( Read *read, VipsImage *out )
}
int
vips__png_read( const char *filename, VipsImage *out )
vips__png_read( const char *filename, VipsImage *out, gboolean fail )
{
Read *read;
@ -618,7 +627,7 @@ vips__png_read( const char *filename, VipsImage *out )
printf( "vips__png_read: reading \"%s\"\n", filename );
#endif /*DEBUG*/
if( !(read = read_new_filename( out, filename )) ||
if( !(read = read_new_filename( out, filename, fail )) ||
png2vips_image( read, out ) )
return( -1 );
@ -665,11 +674,12 @@ vips_png_read_buffer( png_structp pPng, png_bytep data, png_size_t length )
}
static Read *
read_new_buffer( VipsImage *out, const void *buffer, size_t length )
read_new_buffer( VipsImage *out, const void *buffer, size_t length,
gboolean fail )
{
Read *read;
if( !(read = read_new( out )) )
if( !(read = read_new( out, fail )) )
return( NULL );
read->length = length;
@ -695,7 +705,7 @@ vips__png_header_buffer( const void *buffer, size_t length, VipsImage *out )
{
Read *read;
if( !(read = read_new_buffer( out, buffer, length )) ||
if( !(read = read_new_buffer( out, buffer, length, TRUE )) ||
png2vips_header( read, out ) )
return( -1 );
@ -703,11 +713,12 @@ vips__png_header_buffer( const void *buffer, size_t length, VipsImage *out )
}
int
vips__png_read_buffer( const void *buffer, size_t length, VipsImage *out )
vips__png_read_buffer( const void *buffer, size_t length, VipsImage *out,
gboolean fail )
{
Read *read;
if( !(read = read_new_buffer( out, buffer, length )) ||
if( !(read = read_new_buffer( out, buffer, length, fail )) ||
png2vips_image( read, out ) )
return( -1 );
@ -726,7 +737,7 @@ vips__png_isinterlaced_buffer( const void *buffer, size_t length )
image = vips_image_new();
if( !(read = read_new_buffer( image, buffer, length )) ) {
if( !(read = read_new_buffer( image, buffer, length, TRUE )) ) {
g_object_unref( image );
return( -1 );
}