diff options
author | Michael Vrhel <michael.vrhel@artifex.com> | 2016-01-26 08:47:30 -0800 |
---|---|---|
committer | Michael Vrhel <michael.vrhel@artifex.com> | 2016-01-26 09:20:31 -0800 |
commit | 3bbced3ab549bef42f47fb28c10287b32826d1b4 (patch) | |
tree | 5bfedc935af9debb0a071d18c5066ecac98815e7 | |
parent | 5e270fffe76164b07b29dec2358ef01003866674 (diff) | |
download | ghostpdl-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.c | 16 | ||||
-rw-r--r-- | base/gsicc_create.c | 5 | ||||
-rw-r--r-- | base/gsicc_manage.c | 18 | ||||
-rw-r--r-- | base/gsicc_manage.h | 2 | ||||
-rw-r--r-- | devices/gdevrinkj.c | 15 | ||||
-rw-r--r-- | xps/xpscolor.c | 5 | ||||
-rw-r--r-- | xps/xpsimage.c | 5 |
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"); |