fix a crash with heavy use of draw

we were leaving a few bits of the original image around after
vips_image_copy_memory(), including the progress signal ... if earlier images
were freed, perhaps by a GC in a language binding, we could get a dangling
pointer

thanks Nakilon, see https://github.com/jcupitt/ruby-vips/issues/140
This commit is contained in:
John Cupitt 2017-10-09 22:27:36 +01:00
parent 653e99ea82
commit 6f16a9df71
2 changed files with 34 additions and 4 deletions

View File

@ -1,6 +1,8 @@
29/8/17 started 8.5.9
- make --fail stop jpeg read on any libjpeg warning, thanks @mceachen
- don't build enumtypes so often, removing perl as a compile dependancy
- fix a crash with havy use of draw operations from language bindings,
thanks @Nakilon
2/8/17 started 8.5.8
- fix transparency detection in merge, thanks Haida

View File

@ -2458,6 +2458,8 @@ vips_image_write( VipsImage *image, VipsImage *out )
g_object_ref( image );
vips_object_local( out, image );
}
else {
}
return( 0 );
}
@ -3010,6 +3012,9 @@ VipsImage *
vips_image_copy_memory( VipsImage *image )
{
VipsImage *new;
VipsImage *image_array[2];
size_t length;
void *data;
switch( image->dtype ) {
case VIPS_IMAGE_SETBUF:
@ -3025,13 +3030,36 @@ vips_image_copy_memory( VipsImage *image )
case VIPS_IMAGE_OPENOUT:
case VIPS_IMAGE_OPENIN:
case VIPS_IMAGE_PARTIAL:
/* Copy to a new memory image.
/* We don't use vips_image_new_memory() and vips_image_write()
* since we want to make a break in the pipeline and we want
* to avoid all the machinery around reordering and dependancy
* links.
*
* We especially want to be able to unref input and have output
* survive. Things like the progress signal must be cleared,
* for example.
*/
new = vips_image_new_memory();
if( vips_image_write( image, new ) ) {
g_object_unref( new );
/* Write to a new memory image.
*/
if( !(data = vips_image_write_to_memory( image, &length )) )
return( NULL );
if( !(new = vips_image_new_from_memory( data, length,
image->Xsize, image->Ysize, image->Bands,
image->BandFmt )) ) {
g_free( data );
return( NULL );
}
/* Copy over other fields and the metadata.
*/
image_array[0] = image;
image_array[1] = NULL;
if( vips__image_copy_fields_array( new, image_array ) ) {
VIPS_UNREF( new );
return( NULL );
}
break;
default: