41
41
* 28/12/18
42
42
* - remove warning messages from vips_icc_is_compatible_profile() since
43
43
* they can be triggered under normal circumstances
44
+ * 17/4/19 kleisauke
45
+ * - better rejection of broken embedded profiles
44
46
*/
45
47
46
48
/*
@@ -409,10 +411,6 @@ typedef struct _VipsIccImport {
409
411
gboolean embedded ;
410
412
char * input_profile_filename ;
411
413
412
- /* Set if we ended up using the fallback input profile.
413
- */
414
- gboolean used_fallback ;
415
-
416
414
} VipsIccImport ;
417
415
418
416
typedef VipsIccClass VipsIccImportClass ;
@@ -643,6 +641,27 @@ vips_icc_load_profile_blob( VipsBlob *blob, VipsImage *image )
643
641
return ( profile );
644
642
}
645
643
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
+
646
665
static int
647
666
vips_icc_import_build ( VipsObject * object )
648
667
{
@@ -652,6 +671,8 @@ vips_icc_import_build( VipsObject *object )
652
671
VipsIcc * icc = (VipsIcc * ) object ;
653
672
VipsIccImport * import = (VipsIccImport * ) object ;
654
673
674
+ gboolean used_fallback ;
675
+
655
676
/* We read the input profile like this:
656
677
*
657
678
* embedded filename action
@@ -661,23 +682,26 @@ vips_icc_import_build( VipsObject *object )
661
682
* 1 1 image, then fall back to file
662
683
*/
663
684
685
+ used_fallback = FALSE;
686
+
664
687
if ( code -> in &&
665
688
(import -> embedded ||
666
- !import -> input_profile_filename ) )
689
+ !import -> input_profile_filename ) ) {
667
690
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
+ }
668
694
669
- if ( !icc -> in_blob &&
695
+ if ( code -> in &&
696
+ !icc -> in_blob &&
670
697
import -> input_profile_filename ) {
671
698
if ( vips_profile_load ( import -> input_profile_filename ,
672
699
& icc -> in_blob , NULL ) )
673
700
return ( -1 );
674
- import -> used_fallback = TRUE;
675
- }
676
-
677
- if ( icc -> in_blob &&
678
- code -> in )
679
701
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
+ }
681
705
682
706
if ( !icc -> in_profile ) {
683
707
vips_error ( class -> nickname , "%s" , _ ( "no input profile" ) );
@@ -705,7 +729,7 @@ vips_icc_import_build( VipsObject *object )
705
729
* In the same way, we don't remove the embedded input profile on
706
730
* import.
707
731
*/
708
- if ( import -> used_fallback &&
732
+ if ( used_fallback &&
709
733
icc -> in_blob ) {
710
734
const void * data ;
711
735
size_t size ;
@@ -1066,19 +1090,26 @@ vips_icc_transform_build( VipsObject *object )
1066
1090
1067
1091
if ( code -> in &&
1068
1092
(transform -> embedded ||
1069
- !transform -> input_profile_filename ) )
1093
+ !transform -> input_profile_filename ) ) {
1070
1094
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
+ }
1071
1098
1072
- if ( !icc -> in_blob &&
1073
- transform -> input_profile_filename )
1099
+ if ( code -> in &&
1100
+ !icc -> in_blob &&
1101
+ transform -> input_profile_filename ) {
1074
1102
if ( vips_profile_load ( transform -> input_profile_filename ,
1075
1103
& icc -> in_blob , NULL ) )
1076
1104
return ( -1 );
1077
-
1078
- if ( icc -> in_blob &&
1079
- code -> in )
1080
1105
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
+ }
1082
1113
1083
1114
if ( !icc -> in_profile ) {
1084
1115
vips_error ( class -> nickname , "%s" , _ ( "no input profile" ) );
0 commit comments