Skip to content

Commit 691383c

Browse files
committed
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 #1286
1 parent c8ba6fc commit 691383c

File tree

1 file changed

+51
-20
lines changed

1 file changed

+51
-20
lines changed

libvips/colour/icc_transform.c

Lines changed: 51 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@
4141
* 28/12/18
4242
* - remove warning messages from vips_icc_is_compatible_profile() since
4343
* they can be triggered under normal circumstances
44+
* 17/4/19 kleisauke
45+
* - better rejection of broken embedded profiles
4446
*/
4547

4648
/*
@@ -409,10 +411,6 @@ typedef struct _VipsIccImport {
409411
gboolean embedded;
410412
char *input_profile_filename;
411413

412-
/* Set if we ended up using the fallback input profile.
413-
*/
414-
gboolean used_fallback;
415-
416414
} VipsIccImport;
417415

418416
typedef VipsIccClass VipsIccImportClass;
@@ -643,6 +641,27 @@ vips_icc_load_profile_blob( VipsBlob *blob, VipsImage *image )
643641
return( profile );
644642
}
645643

644+
/* Verify that a blob is not corrupt and is compatible with this image.
645+
*
646+
* unref the blob if it's useless.
647+
*/
648+
static cmsHPROFILE
649+
vips_icc_verify_blob( VipsBlob **blob, VipsImage *image )
650+
{
651+
if( *blob ) {
652+
cmsHPROFILE profile;
653+
654+
if( !(profile = vips_icc_load_profile_blob( *blob, image )) ) {
655+
vips_area_unref( (VipsArea *) *blob );
656+
*blob = NULL;
657+
}
658+
659+
return( profile );
660+
}
661+
662+
return( NULL );
663+
}
664+
646665
static int
647666
vips_icc_import_build( VipsObject *object )
648667
{
@@ -652,6 +671,8 @@ vips_icc_import_build( VipsObject *object )
652671
VipsIcc *icc = (VipsIcc *) object;
653672
VipsIccImport *import = (VipsIccImport *) object;
654673

674+
gboolean used_fallback;
675+
655676
/* We read the input profile like this:
656677
*
657678
* embedded filename action
@@ -661,23 +682,26 @@ vips_icc_import_build( VipsObject *object )
661682
* 1 1 image, then fall back to file
662683
*/
663684

685+
used_fallback = FALSE;
686+
664687
if( code->in &&
665688
(import->embedded ||
666-
!import->input_profile_filename) )
689+
!import->input_profile_filename) ) {
667690
icc->in_blob = vips_icc_get_profile_image( code->in );
691+
icc->in_profile =
692+
vips_icc_verify_blob( &icc->in_blob, code->in );
693+
}
668694

669-
if( !icc->in_blob &&
695+
if( code->in &&
696+
!icc->in_blob &&
670697
import->input_profile_filename ) {
671698
if( vips_profile_load( import->input_profile_filename,
672699
&icc->in_blob, NULL ) )
673700
return( -1 );
674-
import->used_fallback = TRUE;
675-
}
676-
677-
if( icc->in_blob &&
678-
code->in )
679701
icc->in_profile =
680-
vips_icc_load_profile_blob( icc->in_blob, code->in );
702+
vips_icc_verify_blob( &icc->in_blob, code->in );
703+
used_fallback = TRUE;
704+
}
681705

682706
if( !icc->in_profile ) {
683707
vips_error( class->nickname, "%s", _( "no input profile" ) );
@@ -705,7 +729,7 @@ vips_icc_import_build( VipsObject *object )
705729
* In the same way, we don't remove the embedded input profile on
706730
* import.
707731
*/
708-
if( import->used_fallback &&
732+
if( used_fallback &&
709733
icc->in_blob ) {
710734
const void *data;
711735
size_t size;
@@ -1066,19 +1090,26 @@ vips_icc_transform_build( VipsObject *object )
10661090

10671091
if( code->in &&
10681092
(transform->embedded ||
1069-
!transform->input_profile_filename) )
1093+
!transform->input_profile_filename) ) {
10701094
icc->in_blob = vips_icc_get_profile_image( code->in );
1095+
icc->in_profile =
1096+
vips_icc_verify_blob( &icc->in_blob, code->in );
1097+
}
10711098

1072-
if( !icc->in_blob &&
1073-
transform->input_profile_filename )
1099+
if( code->in &&
1100+
!icc->in_blob &&
1101+
transform->input_profile_filename ) {
10741102
if( vips_profile_load( transform->input_profile_filename,
10751103
&icc->in_blob, NULL ) )
10761104
return( -1 );
1077-
1078-
if( icc->in_blob &&
1079-
code->in )
10801105
icc->in_profile =
1081-
vips_icc_load_profile_blob( icc->in_blob, code->in );
1106+
vips_icc_verify_blob( &icc->in_blob, code->in );
1107+
}
1108+
1109+
if( !icc->in_profile ) {
1110+
vips_error( class->nickname, "%s", _( "no input profile" ) );
1111+
return( -1 );
1112+
}
10821113

10831114
if( !icc->in_profile ) {
10841115
vips_error( class->nickname, "%s", _( "no input profile" ) );

0 commit comments

Comments
 (0)