diff --git a/ChangeLog b/ChangeLog index 1f660da9..1d347468 100644 --- a/ChangeLog +++ b/ChangeLog @@ -19,7 +19,7 @@ - hide info messages you could get with some older glibs [kleisauke] - fix --no-strip on dzsave with icc-profiles [altert] - better GraphicsMagick image write [bfriesen] -- Add missing read loops to spng, heif and ppm load [kleisauke] +- Add missing read loops to spng, heif, giflib and ppm load [kleisauke] 6/9/20 started 8.10.2 - update magicksave/load profile handling [kelilevi] diff --git a/libvips/foreign/gifload.c b/libvips/foreign/gifload.c index 34acd212..52fd843b 100644 --- a/libvips/foreign/gifload.c +++ b/libvips/foreign/gifload.c @@ -351,20 +351,34 @@ vips_foreign_load_gif_close_giflib( VipsForeignLoadGif *gif ) /* Callback from the gif loader. * - * Read up to len bytes into buffer, return number of bytes read, 0 for EOF. + * Read up to len bytes into buffer, return number of bytes read. This is + * called by giflib exactly as fread, so it does not distinguish between EOF + * and read error. */ static int vips_giflib_read( GifFileType *file, GifByteType *buf, int n ) { VipsForeignLoadGif *gif = (VipsForeignLoadGif *) file->UserData; - gint64 read; + int to_read; - read = vips_source_read( gif->source, buf, n ); - if( read == 0 ) - gif->eof = TRUE; + to_read = n; + while( to_read > 0 ) { + gint64 bytes_read; - return( (int) read ); + bytes_read = vips_source_read( gif->source, buf, n ); + if( bytes_read == 0 ) + gif->eof = TRUE; + if( bytes_read <= 0 ) + return( -1 ); + if( bytes_read > INT_MAX ) + return( -1 ); + + to_read -= bytes_read; + buf += bytes_read; + } + + return( (int) n ); } /* Open any underlying file resource, then giflib. diff --git a/libvips/foreign/heifload.c b/libvips/foreign/heifload.c index 9b3232db..1a701cf4 100644 --- a/libvips/foreign/heifload.c +++ b/libvips/foreign/heifload.c @@ -988,13 +988,14 @@ vips_foreign_load_heif_read( void *data, size_t size, void *userdata ) VipsForeignLoadHeif *heif = (VipsForeignLoadHeif *) userdata; while( size > 0 ) { - gint64 result; + gint64 bytes_read; - result = vips_source_read( heif->source, data, size ); - if( result <= 0 ) + bytes_read = vips_source_read( heif->source, data, size ); + if( bytes_read <= 0 ) return( -1 ); - size -= result; + size -= bytes_read; + data += bytes_read; } return( 0 ); diff --git a/libvips/foreign/ppmload.c b/libvips/foreign/ppmload.c index 77dfbb60..430a5572 100644 --- a/libvips/foreign/ppmload.c +++ b/libvips/foreign/ppmload.c @@ -462,10 +462,12 @@ vips_foreign_load_ppm_generate_binary( VipsRegion *or, n_bytes = sizeof_line; while( n_bytes > 0 ) { - size_t bytes_read; + gint64 bytes_read; bytes_read = vips_source_read( ppm->source, q, sizeof_line ); + if( bytes_read < 0 ) + return( -1 ); if( bytes_read == 0 ) { vips_error( class->nickname, "%s", _( "file truncated" ) ); @@ -473,6 +475,7 @@ vips_foreign_load_ppm_generate_binary( VipsRegion *or, } n_bytes -= bytes_read; + q += bytes_read; } }