better rejection of broken embedded profiles
icc_import and _transform now test the embedded profile more carefully. It must now be a valid profile and must be compatible with the image. see https://github.com/libvips/libvips/issues/1286
This commit is contained in:
parent
c8ba6fcae5
commit
691383c2b8
@ -41,6 +41,8 @@
|
||||
* 28/12/18
|
||||
* - remove warning messages from vips_icc_is_compatible_profile() since
|
||||
* they can be triggered under normal circumstances
|
||||
* 17/4/19 kleisauke
|
||||
* - better rejection of broken embedded profiles
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -409,10 +411,6 @@ typedef struct _VipsIccImport {
|
||||
gboolean embedded;
|
||||
char *input_profile_filename;
|
||||
|
||||
/* Set if we ended up using the fallback input profile.
|
||||
*/
|
||||
gboolean used_fallback;
|
||||
|
||||
} VipsIccImport;
|
||||
|
||||
typedef VipsIccClass VipsIccImportClass;
|
||||
@ -643,6 +641,27 @@ vips_icc_load_profile_blob( VipsBlob *blob, VipsImage *image )
|
||||
return( profile );
|
||||
}
|
||||
|
||||
/* Verify that a blob is not corrupt and is compatible with this image.
|
||||
*
|
||||
* unref the blob if it's useless.
|
||||
*/
|
||||
static cmsHPROFILE
|
||||
vips_icc_verify_blob( VipsBlob **blob, VipsImage *image )
|
||||
{
|
||||
if( *blob ) {
|
||||
cmsHPROFILE profile;
|
||||
|
||||
if( !(profile = vips_icc_load_profile_blob( *blob, image )) ) {
|
||||
vips_area_unref( (VipsArea *) *blob );
|
||||
*blob = NULL;
|
||||
}
|
||||
|
||||
return( profile );
|
||||
}
|
||||
|
||||
return( NULL );
|
||||
}
|
||||
|
||||
static int
|
||||
vips_icc_import_build( VipsObject *object )
|
||||
{
|
||||
@ -652,6 +671,8 @@ vips_icc_import_build( VipsObject *object )
|
||||
VipsIcc *icc = (VipsIcc *) object;
|
||||
VipsIccImport *import = (VipsIccImport *) object;
|
||||
|
||||
gboolean used_fallback;
|
||||
|
||||
/* We read the input profile like this:
|
||||
*
|
||||
* embedded filename action
|
||||
@ -661,23 +682,26 @@ vips_icc_import_build( VipsObject *object )
|
||||
* 1 1 image, then fall back to file
|
||||
*/
|
||||
|
||||
used_fallback = FALSE;
|
||||
|
||||
if( code->in &&
|
||||
(import->embedded ||
|
||||
!import->input_profile_filename) )
|
||||
!import->input_profile_filename) ) {
|
||||
icc->in_blob = vips_icc_get_profile_image( code->in );
|
||||
icc->in_profile =
|
||||
vips_icc_verify_blob( &icc->in_blob, code->in );
|
||||
}
|
||||
|
||||
if( !icc->in_blob &&
|
||||
if( code->in &&
|
||||
!icc->in_blob &&
|
||||
import->input_profile_filename ) {
|
||||
if( vips_profile_load( import->input_profile_filename,
|
||||
&icc->in_blob, NULL ) )
|
||||
return( -1 );
|
||||
import->used_fallback = TRUE;
|
||||
}
|
||||
|
||||
if( icc->in_blob &&
|
||||
code->in )
|
||||
icc->in_profile =
|
||||
vips_icc_load_profile_blob( icc->in_blob, code->in );
|
||||
vips_icc_verify_blob( &icc->in_blob, code->in );
|
||||
used_fallback = TRUE;
|
||||
}
|
||||
|
||||
if( !icc->in_profile ) {
|
||||
vips_error( class->nickname, "%s", _( "no input profile" ) );
|
||||
@ -705,7 +729,7 @@ vips_icc_import_build( VipsObject *object )
|
||||
* In the same way, we don't remove the embedded input profile on
|
||||
* import.
|
||||
*/
|
||||
if( import->used_fallback &&
|
||||
if( used_fallback &&
|
||||
icc->in_blob ) {
|
||||
const void *data;
|
||||
size_t size;
|
||||
@ -1066,19 +1090,26 @@ vips_icc_transform_build( VipsObject *object )
|
||||
|
||||
if( code->in &&
|
||||
(transform->embedded ||
|
||||
!transform->input_profile_filename) )
|
||||
!transform->input_profile_filename) ) {
|
||||
icc->in_blob = vips_icc_get_profile_image( code->in );
|
||||
icc->in_profile =
|
||||
vips_icc_verify_blob( &icc->in_blob, code->in );
|
||||
}
|
||||
|
||||
if( !icc->in_blob &&
|
||||
transform->input_profile_filename )
|
||||
if( code->in &&
|
||||
!icc->in_blob &&
|
||||
transform->input_profile_filename ) {
|
||||
if( vips_profile_load( transform->input_profile_filename,
|
||||
&icc->in_blob, NULL ) )
|
||||
return( -1 );
|
||||
|
||||
if( icc->in_blob &&
|
||||
code->in )
|
||||
icc->in_profile =
|
||||
vips_icc_load_profile_blob( icc->in_blob, code->in );
|
||||
vips_icc_verify_blob( &icc->in_blob, code->in );
|
||||
}
|
||||
|
||||
if( !icc->in_profile ) {
|
||||
vips_error( class->nickname, "%s", _( "no input profile" ) );
|
||||
return( -1 );
|
||||
}
|
||||
|
||||
if( !icc->in_profile ) {
|
||||
vips_error( class->nickname, "%s", _( "no input profile" ) );
|
||||
|
Loading…
Reference in New Issue
Block a user