fix a crash with delayed load
If a delayed load failed, it could leave the pipeline only half-set up. Sebsequent threads could then segv. Set a load-has-failed flag and test before generate. See https://github.com/jcupitt/libvips/issues/893
This commit is contained in:
parent
eefb2dad98
commit
20d840e6da
@ -4,6 +4,7 @@
|
|||||||
writing twice to memory
|
writing twice to memory
|
||||||
- better rounding behaviour in convolution means we hit the vector path more
|
- better rounding behaviour in convolution means we hit the vector path more
|
||||||
often
|
often
|
||||||
|
- fix a crash if a delayed load failed [gsharpsh00ter]
|
||||||
|
|
||||||
5/1/18 started 8.6.2
|
5/1/18 started 8.6.2
|
||||||
- vips_sink_screen() keeps a ref to the input image ... stops a rare race
|
- vips_sink_screen() keeps a ref to the input image ... stops a rare race
|
||||||
|
@ -18,6 +18,8 @@
|
|||||||
* - transform cmyk->rgb if there's an embedded profile
|
* - transform cmyk->rgb if there's an embedded profile
|
||||||
* 16/6/17
|
* 16/6/17
|
||||||
* - add page_height
|
* - add page_height
|
||||||
|
* 5/3/18
|
||||||
|
* - block _start if one start fails, see #893
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -796,6 +798,11 @@ vips_foreign_load_start( VipsImage *out, void *a, void *b )
|
|||||||
VipsForeignLoad *load = VIPS_FOREIGN_LOAD( b );
|
VipsForeignLoad *load = VIPS_FOREIGN_LOAD( b );
|
||||||
VipsForeignLoadClass *class = VIPS_FOREIGN_LOAD_GET_CLASS( load );
|
VipsForeignLoadClass *class = VIPS_FOREIGN_LOAD_GET_CLASS( load );
|
||||||
|
|
||||||
|
/* If this start has failed before in another thread, we can fail now.
|
||||||
|
*/
|
||||||
|
if( load->error )
|
||||||
|
return( NULL );
|
||||||
|
|
||||||
if( !load->real ) {
|
if( !load->real ) {
|
||||||
if( !(load->real = vips_foreign_load_temp( load )) )
|
if( !(load->real = vips_foreign_load_temp( load )) )
|
||||||
return( NULL );
|
return( NULL );
|
||||||
@ -819,19 +826,25 @@ vips_foreign_load_start( VipsImage *out, void *a, void *b )
|
|||||||
g_object_set_qdata( G_OBJECT( load->real ),
|
g_object_set_qdata( G_OBJECT( load->real ),
|
||||||
vips__foreign_load_operation, load );
|
vips__foreign_load_operation, load );
|
||||||
|
|
||||||
if( class->load( load ) ||
|
/* Load the image and check the result.
|
||||||
vips_image_pio_input( load->real ) )
|
*
|
||||||
return( NULL );
|
* ->header() read the header into @out, load has read the
|
||||||
|
|
||||||
/* ->header() read the header into @out, load has read the
|
|
||||||
* image into @real. They must match exactly in size, bands,
|
* image into @real. They must match exactly in size, bands,
|
||||||
* format and coding for the copy to work.
|
* format and coding for the copy to work.
|
||||||
*
|
*
|
||||||
* Some versions of ImageMagick give different results between
|
* Some versions of ImageMagick give different results between
|
||||||
* Ping and Load for some formats, for example.
|
* Ping and Load for some formats, for example.
|
||||||
|
*
|
||||||
|
* If the load fails, we need to stop
|
||||||
*/
|
*/
|
||||||
if( !vips_foreign_load_iscompat( load->real, out ) )
|
if( class->load( load ) ||
|
||||||
|
vips_image_pio_input( load->real ) ||
|
||||||
|
vips_foreign_load_iscompat( load->real, out ) ) {
|
||||||
|
vips_operation_invalidate( VIPS_OPERATION( load ) );
|
||||||
|
load->error = TRUE;
|
||||||
|
|
||||||
return( NULL );
|
return( NULL );
|
||||||
|
}
|
||||||
|
|
||||||
/* We have to tell vips that out depends on real. We've set
|
/* We have to tell vips that out depends on real. We've set
|
||||||
* the demand hint below, but not given an input there.
|
* the demand hint below, but not given an input there.
|
||||||
|
@ -158,6 +158,11 @@ typedef struct _VipsForeignLoad {
|
|||||||
* TRUE.
|
* TRUE.
|
||||||
*/
|
*/
|
||||||
gboolean disc;
|
gboolean disc;
|
||||||
|
|
||||||
|
/* Set if a start function fails. We want to prevent the other starts
|
||||||
|
* from also triggering the load.
|
||||||
|
*/
|
||||||
|
gboolean error;
|
||||||
} VipsForeignLoad;
|
} VipsForeignLoad;
|
||||||
|
|
||||||
typedef struct _VipsForeignLoadClass {
|
typedef struct _VipsForeignLoadClass {
|
||||||
|
Loading…
Reference in New Issue
Block a user