summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Vrhel <michael.vrhel@artifex.com>2016-01-26 08:47:30 -0800
committerMichael Vrhel <michael.vrhel@artifex.com>2016-01-26 09:20:31 -0800
commit3bbced3ab549bef42f47fb28c10287b32826d1b4 (patch)
tree5bfedc935af9debb0a071d18c5066ecac98815e7
parent5e270fffe76164b07b29dec2358ef01003866674 (diff)
downloadghostpdl-3bbced3ab549bef42f47fb28c10287b32826d1b4.tar.gz
Fix for Bug 696514. rinkj device
The rinkj device was dereferencing a NULL pointer related to the ICC device link profile that it can be set up to use. Fixing this issued and playing around with a various command line options revealed a problem in error trapping in the icc code where you could cause a crash by having a bogus device link profile specified on the command line. This fixes that crash also.
-rw-r--r--base/gsciemap.c16
-rw-r--r--base/gsicc_create.c5
-rw-r--r--base/gsicc_manage.c18
-rw-r--r--base/gsicc_manage.h2
-rw-r--r--devices/gdevrinkj.c15
-rw-r--r--xps/xpscolor.c5
-rw-r--r--xps/xpsimage.c5
7 files changed, 44 insertions, 22 deletions
diff --git a/base/gsciemap.c b/base/gsciemap.c
index fdd2f8e94..6c711f3c2 100644
--- a/base/gsciemap.c
+++ b/base/gsciemap.c
@@ -254,7 +254,9 @@ gx_ciedefg_to_icc(gs_color_space **ppcs_icc, gs_color_space *pcs, gs_memory_t *m
abc_caches, lmn_caches, defg_caches);
if (code < 0)
return gs_rethrow(code, "Failed to create ICC profile from CIEDEFG");
- gsicc_init_profile_info((*ppcs_icc)->cmm_icc_profile_data);
+ code = gsicc_init_profile_info((*ppcs_icc)->cmm_icc_profile_data);
+ if (code < 0)
+ return gs_rethrow(code, "Failed to create ICC profile from CIEDEFG");
(*ppcs_icc)->cmm_icc_profile_data->default_match = CIE_DEFG;
pcs->icc_equivalent = *ppcs_icc;
pcs->icc_equivalent->cmm_icc_profile_data->data_cs = gsCMYK;
@@ -535,7 +537,9 @@ gx_ciedef_to_icc(gs_color_space **ppcs_icc, gs_color_space *pcs, gs_memory_t *me
abc_caches, lmn_caches, def_caches);
if (code < 0)
return gs_rethrow(code, "Failed to build ICC profile from CIEDEF");
- gsicc_init_profile_info((*ppcs_icc)->cmm_icc_profile_data);
+ code = gsicc_init_profile_info((*ppcs_icc)->cmm_icc_profile_data);
+ if (code < 0)
+ return gs_rethrow(code, "Failed to build ICC profile from CIEDEF");
(*ppcs_icc)->cmm_icc_profile_data->default_match = CIE_DEF;
/* Assign to the icc_equivalent member variable */
pcs->icc_equivalent = *ppcs_icc;
@@ -643,7 +647,9 @@ gx_cieabc_to_icc(gs_color_space **ppcs_icc, gs_color_space *pcs, bool *islab,
abc_caches, lmn_caches, islab);
if (code < 0)
return gs_rethrow(code, "Failed to build ICC profile from CIEABC");
- gsicc_init_profile_info((*ppcs_icc)->cmm_icc_profile_data);
+ code = gsicc_init_profile_info((*ppcs_icc)->cmm_icc_profile_data);
+ if (code < 0)
+ return gs_rethrow(code, "Failed to build ICC profile from CIEDEF");
(*ppcs_icc)->cmm_icc_profile_data->default_match = CIE_ABC;
/* Assign to the icc_equivalent member variable */
pcs->icc_equivalent = *ppcs_icc;
@@ -755,7 +761,9 @@ gx_ciea_to_icc(gs_color_space **ppcs_icc, gs_color_space *pcs, gs_memory_t *memo
a_cache, lmn_caches);
if (code < 0)
return gs_rethrow(code, "Failed to create ICC profile from CIEA");
- gsicc_init_profile_info((*ppcs_icc)->cmm_icc_profile_data);
+ code = gsicc_init_profile_info((*ppcs_icc)->cmm_icc_profile_data);
+ if (code < 0)
+ return gs_rethrow(code, "Failed to build ICC profile from CIEDEF");
(*ppcs_icc)->cmm_icc_profile_data->default_match = CIE_A;
/* Assign to the icc_equivalent member variable */
pcs->icc_equivalent = *ppcs_icc;
diff --git a/base/gsicc_create.c b/base/gsicc_create.c
index fdc638cd4..36b2d1916 100644
--- a/base/gsicc_create.c
+++ b/base/gsicc_create.c
@@ -3124,6 +3124,7 @@ get_xyzprofile(cmm_profile_t *xyz_profile)
byte mediawhitept[12];
icS15Fixed16Number one, zero;
int k, j;
+ int code;
/* Fill in the common stuff */
setheader_common(header, 2);
@@ -3212,12 +3213,12 @@ get_xyzprofile(cmm_profile_t *xyz_profile)
gs_free_object(memory, tag_list, "get_xyzprofile");
xyz_profile->buffer = buffer;
xyz_profile->buffer_size = profile_size;
- gsicc_init_profile_info(xyz_profile);
+ code = gsicc_init_profile_info(xyz_profile);
#if SAVEICCPROFILE
/* Dump the buffer to a file for testing if its a valid ICC profile */
save_profile(buffer, "XYZProfile", profile_size);
#endif
- return 0;
+ return code;
}
static bool
diff --git a/base/gsicc_manage.c b/base/gsicc_manage.c
index 78d465c6a..16e8d98d0 100644
--- a/base/gsicc_manage.c
+++ b/base/gsicc_manage.c
@@ -651,7 +651,9 @@ gsicc_set_srcgtag_struct(gsicc_manager_t *icc_manager, const char* pname,
return code;
}
if (str != NULL && icc_profile != NULL) {
- gsicc_init_profile_info(icc_profile);
+ code = gsicc_init_profile_info(icc_profile);
+ if (code < 0)
+ return code;
cmm = gsCMM_DEFAULT;
/* Check if this object is a devicelink profile.
If it is then the intent, blackpoint etc. are not
@@ -912,7 +914,8 @@ gsicc_set_profile(gsicc_manager_t *icc_manager, const char* pname, int namelen,
index in the table is the first name */
gsicc_get_devicen_names(icc_profile, icc_manager->memory);
/* Init this profile now */
- gsicc_init_profile_info(icc_profile);
+ code = gsicc_init_profile_info(icc_profile);
+ if (code < 0) return gs_throw1(-1, "problems with profile %s", pname);
} else {
/* Delay the loading of the handle buffer until we need the profile.
But set some basic stuff that we need. Take care of DeviceN
@@ -1027,13 +1030,17 @@ gsicc_get_profile_handle_file(const char* pname, int namelen, gs_memory_t *mem)
gs_throw(gs_error_VMerror, "Creation of ICC profile failed");
return NULL;
}
- gsicc_init_profile_info(result);
+ code = gsicc_init_profile_info(result);
+ if (code < 0) {
+ gs_throw(gs_error_VMerror, "Creation of ICC profile failed");
+ return NULL;
+ }
return result;
}
/* Given that we already have a profile in a buffer (e.g. generated from a PS object)
this gets the handle and initializes the various member variables that we need */
-void
+int
gsicc_init_profile_info(cmm_profile_t *profile)
{
int k;
@@ -1043,6 +1050,8 @@ gsicc_init_profile_info(cmm_profile_t *profile)
gsicc_get_profile_handle_buffer(profile->buffer,
profile->buffer_size,
profile->memory);
+ if (profile->profile_handle == NULL)
+ return -1;
/* Compute the hash code of the profile. */
gsicc_get_icc_buff_hash(profile->buffer, &(profile->hashcode),
@@ -1058,6 +1067,7 @@ gsicc_init_profile_info(cmm_profile_t *profile)
profile->Range.ranges[k].rmin = 0.0;
profile->Range.ranges[k].rmax = 1.0;
}
+ return 0;
}
/* This is used to try to find the specified or default ICC profiles */
diff --git a/base/gsicc_manage.h b/base/gsicc_manage.h
index 8c2b6d737..2da149745 100644
--- a/base/gsicc_manage.h
+++ b/base/gsicc_manage.h
@@ -99,7 +99,7 @@ int gsicc_set_srcgtag_struct(gsicc_manager_t *icc_manager, const char* pname,
int namelen);
cmm_profile_t* gsicc_get_profile_handle_file(const char* pname, int namelen,
gs_memory_t *mem);
-void gsicc_init_profile_info(cmm_profile_t *profile);
+int gsicc_init_profile_info(cmm_profile_t *profile);
int gsicc_initialize_default_profile(cmm_profile_t *icc_profile);
gsicc_manager_t* gsicc_manager_new(gs_memory_t *memory);
cmm_profile_t* gsicc_profile_new(stream *s, gs_memory_t *memory,
diff --git a/devices/gdevrinkj.c b/devices/gdevrinkj.c
index b638e5747..e7b140c7b 100644
--- a/devices/gdevrinkj.c
+++ b/devices/gdevrinkj.c
@@ -127,19 +127,17 @@ typedef struct rinkj_device_s {
*/
gs_separation_names separation_order;
- /* ICC color profile objects, for color conversion. */
- char profile_out_fn[256];
-
/* This device can use a device link ICC profile to map
the colors to the appropriate color space. Not
as flexible as having source and destination profiles
and creating the link on the fly, but I am doing
the minimal changes on this device to make it work
with the new ICC architecture. No optimizations yet. */
-
gcmmhlink_t icc_link;
cmm_profile_t *link_profile;
+ /* ICC color profile objects, for color conversion. */
+ char profile_out_fn[256];
char setup_fn[256];
} rinkj_device;
@@ -245,7 +243,9 @@ const rinkj_device gs_rinkj_device =
(&DeviceCMYKComponents), /* Names of color model colorants */
4, /* Number colorants for CMYK */
{0}, /* SeparationNames */
- {0} /* SeparationOrder names */
+ {0}, /* SeparationOrder names */
+ 0, /* icc_link (link handle) */
+ 0 /* link_profile (device link profile) */
};
/*
@@ -480,7 +480,6 @@ rinkj_open_profile(rinkj_device *rdev)
if (rdev->icc_link == NULL)
return gs_throw(-1, "Could not create link handle for rinkj device");
-
}
return(0);
}
@@ -774,7 +773,9 @@ rinkj_close_device(gx_device *dev)
{
rinkj_device * const rdev = (rinkj_device *) dev;
- gscms_release_link(rdev->icc_link);
+ /* ICC link profile only used (and set) if specified on command line */
+ if (rdev->icc_link != NULL)
+ gscms_release_link(rdev->icc_link);
rc_decrement(rdev->link_profile, "rinkj_close_device");
return gdev_prn_close(dev);
diff --git a/xps/xpscolor.c b/xps/xpscolor.c
index 5f82b62e6..d0e7e732f 100644
--- a/xps/xpscolor.c
+++ b/xps/xpscolor.c
@@ -177,6 +177,7 @@ xps_read_icc_colorspace(xps_context_t *ctx, char *base_uri, char *profilename)
cmm_profile_t *profile;
xps_part_t *part;
char partname[1024];
+ int code;
/* Find ICC colorspace part */
xps_absolute_path(partname, base_uri, profilename, sizeof partname);
@@ -203,10 +204,10 @@ xps_read_icc_colorspace(xps_context_t *ctx, char *base_uri, char *profilename)
profile->buffer_size = part->size;
/* Parse */
- gsicc_init_profile_info(profile);
+ code = gsicc_init_profile_info(profile);
/* Problem with profile. Don't fail, just use the default */
- if (profile->profile_handle == NULL)
+ if (code < 0)
{
gsicc_profile_reference(profile, -1);
gs_warn1("there was a problem with the profile: %s", partname);
diff --git a/xps/xpsimage.c b/xps/xpsimage.c
index 265ab503d..3cd8336c9 100644
--- a/xps/xpsimage.c
+++ b/xps/xpsimage.c
@@ -122,6 +122,7 @@ xps_decode_image(xps_context_t *ctx, xps_part_t *part, xps_image_t *image)
int len = part->size;
cmm_profile_t *profile;
int error;
+ int code;
if (len < 8)
return gs_throw(-1, "unknown image file format");
@@ -178,9 +179,9 @@ xps_decode_image(xps_context_t *ctx, xps_part_t *part, xps_image_t *image)
profile->buffer_size = image->profilesize;
/* Parse */
- gsicc_init_profile_info(profile);
+ code = gsicc_init_profile_info(profile);
- if (profile->profile_handle == NULL)
+ if (code < 0)
{
/* Problem with profile. Just ignore it */
gs_warn("ignoring problem with icc profile embedded in an image");