diff --git a/SOURCES/ghostscript-check-icc-profile-errors.patch b/SOURCES/ghostscript-check-icc-profile-errors.patch new file mode 100644 index 0000000..e4f54ee --- /dev/null +++ b/SOURCES/ghostscript-check-icc-profile-errors.patch @@ -0,0 +1,103 @@ +From 8d65c0854c049e4c0c8e08006b595ad40a59e696 Mon Sep 17 00:00:00 2001 +From: Robin Watts +Date: Thu, 28 Mar 2013 21:12:18 +0000 +Subject: [PATCH] Another memory squeeze fix. + +Avoid SEGV in gsicc_alloc_link_entry and callers. +--- + base/gsicc_cache.c | 17 +++++++++++------ + base/gsicc_manage.c | 6 ++++-- + base/gsicc_nocm.c | 3 +++ + base/gsicc_replacecm.c | 3 +++ + 4 files changed, 21 insertions(+), 8 deletions(-) + +diff --git a/base/gsicc_cache.c b/base/gsicc_cache.c +index 616db4c..65b2dd0 100644 +--- a/base/gsicc_cache.c ++++ b/base/gsicc_cache.c +@@ -659,12 +659,14 @@ gsicc_alloc_link_entry(gsicc_link_cache_t *icc_link_cache, + /* insert an empty link that we will reserve so we */ + /* can unlock while building the link contents */ + (*ret_link) = gsicc_alloc_link(cache_mem->stable_memory, hash); +- (*ret_link)->icc_link_cache = icc_link_cache; +- (*ret_link)->next = icc_link_cache->head; +- icc_link_cache->head = *ret_link; +- icc_link_cache->num_links++; +- /* now that we own this link we can release +- the lock since it is not valid */ ++ if (*ret_link) { ++ (*ret_link)->icc_link_cache = icc_link_cache; ++ (*ret_link)->next = icc_link_cache->head; ++ icc_link_cache->head = *ret_link; ++ icc_link_cache->num_links++; ++ /* now that we own this link we can release ++ the lock since it is not valid */ ++ } + gx_monitor_leave(icc_link_cache->lock); + return false; + } +@@ -794,6 +796,9 @@ gsicc_get_link_profile(const gs_imager_state *pis, gx_device *dev, + if (gsicc_alloc_link_entry(icc_link_cache, &link, hash, include_softproof, + include_devicelink)) + return link; ++ if (link == NULL) ++ return NULL; ++ + /* Now compute the link contents */ + cms_input_profile = gs_input_profile->profile_handle; + if (cms_input_profile == NULL) { +diff --git a/base/gsicc_manage.c b/base/gsicc_manage.c +index e0e7d93..210be59 100644 +--- a/base/gsicc_manage.c ++++ b/base/gsicc_manage.c +@@ -1521,8 +1521,8 @@ gsicc_set_device_profile(gx_device * pdev, gs_memory_t * mem, + icc_profile = + gsicc_profile_new(str, mem, file_name, strlen(file_name)); + code = sfclose(str); +- } +- if (str != NULL && icc_profile != NULL) { ++ if (icc_profile == NULL) ++ return_error(gs_error_VMerror); + if (pro_enum < gsPROOFPROFILE) { + if_debug1m(gs_debug_flag_icc, mem, + "[icc] Setting device profile %d\n", pro_enum); +@@ -1542,6 +1542,8 @@ gsicc_set_device_profile(gx_device * pdev, gs_memory_t * mem, + gsicc_get_profile_handle_buffer(icc_profile->buffer, + icc_profile->buffer_size, + mem); ++ if (icc_profile->profile_handle == NULL) ++ return_error(gs_error_unknownerror); + /* Compute the hash code of the profile. Everything in the + ICC manager will have it's hash code precomputed */ + gsicc_get_icc_buff_hash(icc_profile->buffer, +diff --git a/base/gsicc_nocm.c b/base/gsicc_nocm.c +index 8b2a353..bcc3138 100644 +--- a/base/gsicc_nocm.c ++++ b/base/gsicc_nocm.c +@@ -372,6 +372,9 @@ gsicc_nocm_get_link(const gs_imager_state *pis, gx_device *dev, + if (gsicc_alloc_link_entry(pis->icc_link_cache, &result, hash, false, false)) + return result; + ++ if (result == NULL) ++ return NULL; ++ + /* Now compute the link contents */ + result->procs.map_buffer = gsicc_nocm_transform_color_buffer; + result->procs.map_color = gsicc_nocm_transform_color; +diff --git a/base/gsicc_replacecm.c b/base/gsicc_replacecm.c +index 1a7c9e6..d1ab5ea 100644 +--- a/base/gsicc_replacecm.c ++++ b/base/gsicc_replacecm.c +@@ -330,6 +330,9 @@ gsicc_rcm_get_link(const gs_imager_state *pis, gx_device *dev, + if (gsicc_alloc_link_entry(pis->icc_link_cache, &result, hash, false, false)) + return result; + ++ if (result == NULL) ++ return result; ++ + /* Now compute the link contents */ + result->procs.map_buffer = gsicc_rcm_transform_color_buffer; + result->procs.map_color = gsicc_rcm_transform_color; +-- +2.5.5 + diff --git a/SOURCES/ghostscript-cups-icc-profile.patch b/SOURCES/ghostscript-cups-icc-profile.patch new file mode 100644 index 0000000..5db5e38 --- /dev/null +++ b/SOURCES/ghostscript-cups-icc-profile.patch @@ -0,0 +1,25 @@ +From 9e45d4a26eea12be326c5f515b44c7474a33f6c5 Mon Sep 17 00:00:00 2001 +From: Tim Waugh +Date: Tue, 12 Jul 2016 17:29:49 +0200 +Subject: [PATCH] Do not set device output ICC profile if the string is empty + +--- + cups/gstoraster.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/cups/gstoraster.c b/cups/gstoraster.c +index 3ddc21f..8fe77a2 100644 +--- a/cups/gstoraster.c ++++ b/cups/gstoraster.c +@@ -665,7 +665,7 @@ main (int argc, char **argv, char *envp[]) + cupsArrayAdd(gs_args, strdup(tmpstr)); + + /* set the device output ICC profile */ +- if(icc_profile != NULL) { ++ if(icc_profile != NULL && icc_profile[0] != '\0') { + snprintf(tmpstr, sizeof(tmpstr), "-sOutputICCProfile=%s", icc_profile); + cupsArrayAdd(gs_args, strdup(tmpstr)); + } +-- +2.5.5 + diff --git a/SOURCES/ghostscript-hanging-in-convert.patch b/SOURCES/ghostscript-hanging-in-convert.patch new file mode 100644 index 0000000..5563d1f --- /dev/null +++ b/SOURCES/ghostscript-hanging-in-convert.patch @@ -0,0 +1,784 @@ +From 85cebb9760339a7853f6eef6be03812f24492f40 Mon Sep 17 00:00:00 2001 +From: Michael Vrhel +Date: Sat, 8 Jun 2013 09:12:30 -0700 +Subject: [PATCH 1/5] Change in behavior for overprint. Fixes bugs 694295 + 694296 and 694067 + +With this change we now do simulated overprinting of cmyk AND spot colorants +for contone cmyk devices by default. If -dSimulateOverprint=false is specified we +will not simulate overprinting of any colors. + +Also, cmyk simulation of spot colors with separation devices is not handled. +i.e. if you specify -dSimulateOverprint=true -dMaxSpots=0 -sDEVICE=tiffsep1 +you will see the spot colors blended in CMYK space if overprint has been +specified in the document. + +Note that not all overprint situations can be simulated accurately with this +approach. For example, if I have a spot color that resulted in a CMYK value +of 0 0 100 0 after the alternate tint transform and then I did an overprint with +a CMYK value of 0 0 1 0, the color should still be a bright yellow but will actually +be almost no color. The issue is that we can not distinguish this case from one +where we had first laid down a CMYK of 0 0 100 0 followed by the overprint of 0 0 1 0 +which should be a light yellow. The documentation has been updated to point this out. + +I reviewed all the diffs that came up in the bmpcmp and reviewed the Ghent overprint +files. +--- + base/gscdevn.c | 10 +++++++--- + base/gscsepr.c | 8 ++++++-- + base/gsdparam.c | 4 ++-- + base/gsicc.c | 7 +++++-- + base/gsicc_manage.c | 2 +- + base/gsovrc.c | 43 ++++++++++++++++++++++++------------------- + base/gsstate.c | 13 ++++++++++++- + base/lib.mak | 4 ++-- + doc/Use.htm | 11 +++++++++-- + 9 files changed, 68 insertions(+), 34 deletions(-) + +diff --git a/base/gscdevn.c b/base/gscdevn.c +index 4963d14..348d543 100644 +--- a/base/gscdevn.c ++++ b/base/gscdevn.c +@@ -40,6 +40,7 @@ + #include "gsicc_manage.h" + #include "gsicc.h" + #include "gsicc_cache.h" ++#include "gxdevice.h" + + /* ---------------- Color space ---------------- */ + +@@ -688,14 +689,16 @@ gx_set_overprint_DeviceN(const gs_color_space * pcs, gs_state * pgs) + if (pcmap->use_alt_cspace) { + const gs_color_space_type* base_type = pcs->base_space->type; + +- if (dev_profile->sim_overprint) ++ if (dev_profile->sim_overprint && ++ dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE && ++ !gx_device_must_halftone(dev)) + return gx_simulated_set_overprint(pcs->base_space, pgs); + else { + /* If the base space is DeviceCMYK, handle overprint as DeviceCMYK */ + if ( base_type->index == gs_color_space_index_DeviceCMYK ) +- return base_type->set_overprint( pcs->base_space, pgs ); ++ return base_type->set_overprint( pcs->base_space, pgs ); + else +- return gx_spot_colors_set_overprint( pcs->base_space, pgs); ++ return gx_spot_colors_set_overprint( pcs->base_space, pgs); + } + } + else { +@@ -707,6 +710,7 @@ gx_set_overprint_DeviceN(const gs_color_space * pcs, gs_state * pgs) + params.retain_spot_comps = false; + params.drawn_comps = 0; + params.k_value = 0; ++ /* We should not have to blend if we don't need the alternate tint transform */ + params.blendspot = false; + for (i = 0; i < ncomps; i++) { + int mcomp = pcmap->color_map[i]; +diff --git a/base/gscsepr.c b/base/gscsepr.c +index 4f477f7..c9b20c5 100644 +--- a/base/gscsepr.c ++++ b/base/gscsepr.c +@@ -33,6 +33,7 @@ + #include "gsovrc.h" + #include "stream.h" + #include "gsicc_cache.h" ++#include "gxdevice.h" + + /* ---------------- Color space ---------------- */ + +@@ -149,20 +150,23 @@ gx_set_overprint_Separation(const gs_color_space * pcs, gs_state * pgs) + + dev_proc(dev, get_profile)(dev, &(dev_profile)); + if (pcmap->use_alt_cspace) +- if (dev_profile->sim_overprint) ++ if (dev_profile->sim_overprint && ++ dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE && ++ !gx_device_must_halftone(dev)) + return gx_simulated_set_overprint(pcs->base_space, pgs); + else + return gx_spot_colors_set_overprint(pcs->base_space, pgs); + else { + gs_overprint_params_t params; + ++ /* We should not have to blend if we don't need the alternate tint transform */ ++ params.blendspot = false; + params.retain_any_comps = pgs->overprint && + pcs->params.separation.sep_type != SEP_ALL; + if (params.retain_any_comps) { + params.retain_spot_comps = false; + params.drawn_comps = 0; + params.k_value = 0; +- params.blendspot = false; + if (pcs->params.separation.sep_type != SEP_NONE) { + int mcomp = pcmap->color_map[0]; + +diff --git a/base/gsdparam.c b/base/gsdparam.c +index 030daec..e2a3e54 100644 +--- a/base/gsdparam.c ++++ b/base/gsdparam.c +@@ -80,7 +80,7 @@ gx_default_get_params(gx_device * dev, gs_param_list * plist) + gsicc_blackpreserve_t blackpreserve[NUM_DEVICE_PROFILES]; + bool devicegraytok = true; /* Default if device profile stuct not set */ + bool usefastcolor = false; /* set for unmanaged color */ +- bool sim_overprint = false; ++ bool sim_overprint = true; /* By default simulate overprinting */ + bool prebandthreshold = true; + int k; + gs_param_float_array msa, ibba, hwra, ma; +@@ -803,7 +803,7 @@ gx_default_put_params(gx_device * dev, gs_param_list * plist) + int k; + bool devicegraytok = true; + bool usefastcolor = false; +- bool sim_overprint = false; ++ bool sim_overprint = true; + bool prebandthreshold = false; + int profile_types[NUM_DEVICE_PROFILES] = {gsDEFAULTPROFILE, + gsGRAPHICPROFILE, +diff --git a/base/gsicc.c b/base/gsicc.c +index 80380b7..e7093c5 100644 +--- a/base/gsicc.c ++++ b/base/gsicc.c +@@ -608,14 +608,17 @@ gx_set_overprint_ICC(const gs_color_space * pcs, gs_state * pgs) + { + gx_device * dev = pgs->device; + gx_device_color_info * pcinfo = (dev == 0 ? 0 : &dev->color_info); ++ cmm_dev_profile_t *dev_profile; ++ int code = dev_proc(dev, get_profile)(dev, &dev_profile); + + /* check if we require special handling */ + if ( !pgs->overprint || + pgs->overprint_mode != 1 || + pcinfo == 0 || + pcs->cmm_icc_profile_data->data_cs != gsCMYK || +- pcinfo->opmode == GX_CINFO_OPMODE_NOT ) +- return gx_spot_colors_set_overprint(pcs, pgs); ++ pcinfo->opmode == GX_CINFO_OPMODE_NOT ) { ++ return gx_spot_colors_set_overprint(pcs, pgs); ++ } + + if (pcinfo->opmode == GX_CINFO_OPMODE_RGB || + pcinfo->opmode == GC_CINFO_OPMODE_RGB_SET) { +diff --git a/base/gsicc_manage.c b/base/gsicc_manage.c +index 05e618b..03cc29c 100644 +--- a/base/gsicc_manage.c ++++ b/base/gsicc_manage.c +@@ -1179,7 +1179,7 @@ gsicc_new_device_profile_array(gs_memory_t *memory) + result->usefastcolor = false; /* Default is to not use fast color */ + result->prebandthreshold = true; + result->supports_devn = false; +- result->sim_overprint = false; ++ result->sim_overprint = true; + rc_init_free(result, memory->non_gc_memory, 1, rc_free_profile_array); + return(result); + } +diff --git a/base/gsovrc.c b/base/gsovrc.c +index 890b2f7..3b741b9 100644 +--- a/base/gsovrc.c ++++ b/base/gsovrc.c +@@ -125,6 +125,7 @@ c_overprint_equal(const gs_composite_t * pct0, const gs_composite_t * pct1) + */ + #define OVERPRINT_ANY_COMPS 1 + #define OVERPRINT_SPOT_COMPS 2 ++#define OVERPRINT_BLEND 4 + + /* + * Convert an overprint compositor to string form for use by the command +@@ -140,15 +141,15 @@ c_overprint_write(const gs_composite_t * pct, byte * data, uint * psize, gx_devi + /* encoded the booleans in a single byte */ + if (pparams->retain_any_comps) { + flags |= OVERPRINT_ANY_COMPS; +- +- /* write out the component bits only if necessary (and possible) */ +- if (pparams->retain_spot_comps && !pparams->blendspot) ++ if (pparams->blendspot) ++ flags |= OVERPRINT_BLEND; ++ if (pparams->retain_spot_comps) + flags |= OVERPRINT_SPOT_COMPS; +- else { +- uint tmp_size = (avail > 0 ? avail - 1 : 0); +- int code = write_color_index( pparams->drawn_comps, +- data + 1, +- &tmp_size ); ++ /* write out the component bits only if necessary (and possible) */ ++ if (!pparams->retain_spot_comps || pparams->blendspot) { ++ uint tmp_size = (avail > 0 ? avail - 1 : 0); ++ int code = write_color_index(pparams->drawn_comps, data + 1, ++ &tmp_size); + /* It would be nice to do have an If RGB OP case, then write out + K value, but on the reader side, there is no way to find this + out so we will always write it out if we are writing the +@@ -199,11 +200,11 @@ c_overprint_read( + params.retain_any_comps = (flags & OVERPRINT_ANY_COMPS) != 0; + params.retain_spot_comps = (flags & OVERPRINT_SPOT_COMPS) != 0; + params.idle = 0; +- params.blendspot = false; ++ params.blendspot = (flags & OVERPRINT_BLEND) != 0; + params.k_value = 0; + + /* check if the drawn_comps array is present */ +- if (params.retain_any_comps && !params.retain_spot_comps) { ++ if (params.retain_any_comps && (!params.retain_spot_comps || params.blendspot)) { + code = read_color_index(¶ms.drawn_comps, data + 1, size - 1); + if (code < 0) + return code; +@@ -1181,21 +1182,25 @@ overprint_fill_rectangle_hl_color(gx_device *dev, + return code; + } + if (blendspot) { +- /* Skip the plane if this component is not to be drawn. We have +- to do a get bits for each plane due to the fact that we have +- to do a copy_planes at the end. If we had a copy_plane +- operation we would just get the ones need and set those. */ +- if ((comps & 0x01) == 1) { +- /* Not sure if a loop or a memset is better here */ +- memset(gb_params.data[k], +- ((pdcolor->colors.devn.values[k]) >> shift & mask), w); ++ /* We need to blend the CMYK colorants as we are simulating ++ the overprint of a spot colorant with its equivalent CMYK ++ colorants */ ++ if ((comps & 0x01) == 1) { ++ int kk; ++ byte *cp = gb_params.data[k]; ++ byte new_val = ((pdcolor->colors.devn.values[k]) >> shift & mask); ++ for (kk = 0; kk < w; kk++, cp++) { ++ int temp = (255 - *cp) * (255 - new_val); ++ temp = temp >> 8; ++ *cp = (255-temp); ++ } + } + comps >>= 1; + } else { + /* Skip the plane if this component is not to be drawn. We have + to do a get bits for each plane due to the fact that we have + to do a copy_planes at the end. If we had a copy_plane +- operation we would just get the ones need and set those. */ ++ operation we would just get the ones needed and set those. */ + if ((comps & 0x01) == 1) { + /* Not sure if a loop or a memset is better here */ + memset(gb_params.data[k], +diff --git a/base/gsstate.c b/base/gsstate.c +index 516fc70..e3e5b70 100644 +--- a/base/gsstate.c ++++ b/base/gsstate.c +@@ -675,7 +675,18 @@ void + gs_setoverprint(gs_state * pgs, bool ovp) + { + bool prior_ovp = pgs->overprint; +- ++ cmm_dev_profile_t *profile_struct; ++ gx_device *dev = pgs->device; ++ ++ /* Check if overprint is disabled */ ++ if (dev != NULL) { ++ if (dev->procs.get_profile == NULL) { ++ profile_struct = dev->icc_struct; ++ } else { ++ dev_proc(dev, get_profile)(dev, &profile_struct); ++ } ++ if (profile_struct->sim_overprint == false) return; ++ } + pgs->overprint = ovp; + if (prior_ovp != ovp) + (void)gs_do_set_overprint(pgs); +diff --git a/base/lib.mak b/base/lib.mak +index 10d0d0d..59e0f5c 100644 +--- a/base/lib.mak ++++ b/base/lib.mak +@@ -2898,7 +2898,7 @@ $(GLD)seprlib.dev : $(LIB_MAK) $(ECHOGS_XE) $(seprlib_) + $(GLOBJ)gscsepr.$(OBJ) : $(GLSRC)gscsepr.c $(AK) $(gx_h) $(gserrors_h)\ + $(memory__h) $(gsfunc_h) $(gsrefct_h) $(gsmatrix_h) $(gscsepr_h) $(gxcspace_h)\ + $(gxfixed_h) $(gxcolor2_h) $(gzstate_h) $(gscdevn_h) $(gxcdevn_h)\ +- $(gxcmap_h) $(gxdevcli_h) $(gsovrc_h) $(stream_h) $(gsicc_cache_h)\ ++ $(gxcmap_h) $(gxdevcli_h) $(gsovrc_h) $(stream_h) $(gsicc_cache_h) $(gxdevice_h)\ + $(MAKEDIRS) + $(GLCC) $(GLO_)gscsepr.$(OBJ) $(C_) $(GLSRC)gscsepr.c + +@@ -2972,7 +2972,7 @@ $(GLOBJ)gscdevn.$(OBJ) : $(GLSRC)gscdevn.c $(AK) $(gx_h) $(gserrors_h)\ + $(gscdevn_h) $(gsfunc_h) $(gsmatrix_h) $(gsrefct_h) $(gsstruct_h)\ + $(gxcspace_h) $(gxcdevn_h) $(gxfarith_h) $(gxfrac_h) $(gsnamecl_h) $(gxcmap_h)\ + $(gxistate_h) $(gscoord_h) $(gzstate_h) $(gxdevcli_h) $(gsovrc_h) $(stream_h)\ +- $(gsicc_manage_h) $(gsicc_cache_h) $(MAKEDIRS) ++ $(gsicc_manage_h) $(gsicc_cache_h) $(gxdevice_h) $(MAKEDIRS) + $(GLCC) $(GLO_)gscdevn.$(OBJ) $(C_) $(GLSRC)gscdevn.c + + $(GLOBJ)gxdevndi.$(OBJ) : $(GLSRC)gxdevndi.c $(AK) $(gx_h)\ +diff --git a/doc/Use.htm b/doc/Use.htm +index 2bbc2f0..133b2ec 100644 +--- a/doc/Use.htm ++++ b/doc/Use.htm +@@ -3057,8 +3057,15 @@ removal mappings. +
+
-dSimulateOverprint=true/false +
+-This option enables CMYK devices (e.g. tiff32nc) to provide an simulation of +-overprinting. ++This option enables continous tone CMYK devices (e.g. tiff32nc) the capability to ++provide a simulation of spot color overprinting. The default setting is true. ++Note that not all spot color overprint cases can be accurately simulated with a CMYK ++only device. For example, a case where you have a spot color overprinted with CMYK ++colors will be indistiguishable from a case where you have spot color equivalent ++CMYK colorants overprinted with CMYK colors, even though they may need to show ++significantly different overprint simulations. To obtain a full overprint simulation, ++use the psdcmyk or tiffsep device, where the spot colors are kept in their own ++individual planes. +
+ +
+-- +2.5.5 + + +From 27c1c6e80b0d4c62d9ced7bf986a7bdb7b444d67 Mon Sep 17 00:00:00 2001 +From: Robin Watts +Date: Tue, 26 Mar 2013 13:09:49 -0700 +Subject: [PATCH 2/5] Fix various memory squeezing errors. + +Mostly these are unchecked allocations, but some are errors in the +cleanup paths. +--- + base/gslibctx.c | 14 +++++++++----- + base/gsmalloc.c | 8 ++++++-- + psi/gs.c | 3 ++- + psi/imain.c | 10 ++++++++-- + psi/interp.c | 19 ++++++++++++++----- + psi/zgstate.c | 4 ++++ + 6 files changed, 43 insertions(+), 15 deletions(-) + +diff --git a/base/gslibctx.c b/base/gslibctx.c +index e0bf259..e3f1b06 100644 +--- a/base/gslibctx.c ++++ b/base/gslibctx.c +@@ -192,13 +192,17 @@ int errwrite_nomem(const char *str, int len) + int errwrite(const gs_memory_t *mem, const char *str, int len) + { + int code; ++ gs_lib_ctx_t *ctx; + if (len == 0) + return 0; +- if (mem->gs_lib_ctx->stderr_fn) +- return (*mem->gs_lib_ctx->stderr_fn)(mem->gs_lib_ctx->caller_handle, str, len); +- +- code = fwrite(str, 1, len, mem->gs_lib_ctx->fstderr); +- fflush(mem->gs_lib_ctx->fstderr); ++ ctx = mem->gs_lib_ctx; ++ if (ctx == NULL) ++ return 0; ++ if (ctx->stderr_fn) ++ return (*ctx->stderr_fn)(ctx->caller_handle, str, len); ++ ++ code = fwrite(str, 1, len, ctx->fstderr); ++ fflush(ctx->fstderr); + return code; + } + +diff --git a/base/gsmalloc.c b/base/gsmalloc.c +index 76f5d40..6b3d4b5 100644 +--- a/base/gsmalloc.c ++++ b/base/gsmalloc.c +@@ -581,10 +581,14 @@ gs_malloc_init(void) + void + gs_malloc_release(gs_memory_t *mem) + { ++ gs_malloc_memory_t * malloc_memory_default; ++ ++ if (mem == NULL) ++ return; + #ifdef USE_RETRY_MEMORY_WRAPPER +- gs_malloc_memory_t * malloc_memory_default = gs_malloc_unwrap(mem); ++ malloc_memory_default = gs_malloc_unwrap(mem); + #else +- gs_malloc_memory_t * malloc_memory_default = (gs_malloc_memory_t *)mem; ++ malloc_memory_default = (gs_malloc_memory_t *)mem; + #endif + gs_lib_ctx_fin((gs_memory_t *)malloc_memory_default); + +diff --git a/psi/gs.c b/psi/gs.c +index 530303b..dc5bb31 100644 +--- a/psi/gs.c ++++ b/psi/gs.c +@@ -135,7 +135,8 @@ main(int argc, char *argv[]) + exit_status = 255; + } + +- gs_to_exit_with_code(minst->heap, exit_status, code); ++ if (minst) ++ gs_to_exit_with_code(minst->heap, exit_status, code); + gs_malloc_release(mem); + + switch (exit_status) { +diff --git a/psi/imain.c b/psi/imain.c +index aee66f8..91b0fbe 100644 +--- a/psi/imain.c ++++ b/psi/imain.c +@@ -131,6 +131,7 @@ gs_main_init0(gs_main_instance * minst, FILE * in, FILE * out, FILE * err, + int max_lib_paths) + { + ref *paths; ++ ref *array; + + /* Do platform-dependent initialization. */ + /* We have to do this as the very first thing, */ +@@ -158,9 +159,14 @@ gs_main_init0(gs_main_instance * minst, FILE * in, FILE * out, FILE * err, + gs_lib_finit(1, e_VMerror, minst->heap); + return_error(e_VMerror); + } ++ array = (ref *) gs_alloc_byte_array(minst->heap, max_lib_paths, sizeof(ref), ++ "lib_path array"); ++ if (array == 0) { ++ gs_lib_finit(1, e_VMerror, minst->heap); ++ return_error(e_VMerror); ++ } + make_array(&minst->lib_path.container, avm_foreign, max_lib_paths, +- (ref *) gs_alloc_byte_array(minst->heap, max_lib_paths, sizeof(ref), +- "lib_path array")); ++ array); + make_array(&minst->lib_path.list, avm_foreign | a_readonly, 0, + minst->lib_path.container.value.refs); + minst->lib_path.env = 0; +diff --git a/psi/interp.c b/psi/interp.c +index bc8b49a..3e3aaaa 100644 +--- a/psi/interp.c ++++ b/psi/interp.c +@@ -311,6 +311,7 @@ gs_interp_init(i_ctx_t **pi_ctx_p, const ref *psystem_dict, + int + gs_interp_alloc_stacks(gs_ref_memory_t *mem, gs_context_state_t * pcst) + { ++ int code; + gs_ref_memory_t *smem = + (gs_ref_memory_t *)gs_memory_stable((gs_memory_t *)mem); + ref stk; +@@ -318,16 +319,20 @@ gs_interp_alloc_stacks(gs_ref_memory_t *mem, gs_context_state_t * pcst) + #define REFS_SIZE_OSTACK OS_REFS_SIZE(MAX_OSTACK) + #define REFS_SIZE_ESTACK ES_REFS_SIZE(MAX_ESTACK) + #define REFS_SIZE_DSTACK DS_REFS_SIZE(MAX_DSTACK) +- gs_alloc_ref_array(smem, &stk, 0, ++ code = gs_alloc_ref_array(smem, &stk, 0, + REFS_SIZE_OSTACK + REFS_SIZE_ESTACK + + REFS_SIZE_DSTACK, "gs_interp_alloc_stacks"); ++ if (code < 0) ++ return code; + + { + ref_stack_t *pos = &pcst->op_stack.stack; + + r_set_size(&stk, REFS_SIZE_OSTACK); +- ref_stack_init(pos, &stk, OS_GUARD_UNDER, OS_GUARD_OVER, NULL, +- smem, NULL); ++ code = ref_stack_init(pos, &stk, OS_GUARD_UNDER, OS_GUARD_OVER, NULL, ++ smem, NULL); ++ if (code < 0) ++ return code; + ref_stack_set_error_codes(pos, e_stackunderflow, e_stackoverflow); + ref_stack_set_max_count(pos, MAX_OSTACK); + stk.value.refs += REFS_SIZE_OSTACK; +@@ -339,8 +344,10 @@ gs_interp_alloc_stacks(gs_ref_memory_t *mem, gs_context_state_t * pcst) + + r_set_size(&stk, REFS_SIZE_ESTACK); + make_oper(&euop, 0, estack_underflow); +- ref_stack_init(pes, &stk, ES_GUARD_UNDER, ES_GUARD_OVER, &euop, ++ code = ref_stack_init(pes, &stk, ES_GUARD_UNDER, ES_GUARD_OVER, &euop, + smem, NULL); ++ if (code < 0) ++ return code; + ref_stack_set_error_codes(pes, e_ExecStackUnderflow, + e_execstackoverflow); + /**************** E-STACK EXPANSION IS NYI. ****************/ +@@ -353,7 +360,9 @@ gs_interp_alloc_stacks(gs_ref_memory_t *mem, gs_context_state_t * pcst) + ref_stack_t *pds = &pcst->dict_stack.stack; + + r_set_size(&stk, REFS_SIZE_DSTACK); +- ref_stack_init(pds, &stk, 0, 0, NULL, smem, NULL); ++ code = ref_stack_init(pds, &stk, 0, 0, NULL, smem, NULL); ++ if (code < 0) ++ return code; + ref_stack_set_error_codes(pds, e_dictstackunderflow, + e_dictstackoverflow); + ref_stack_set_max_count(pds, MAX_DSTACK); +diff --git a/psi/zgstate.c b/psi/zgstate.c +index 8529d04..524f8ff 100644 +--- a/psi/zgstate.c ++++ b/psi/zgstate.c +@@ -117,6 +117,8 @@ int_gstate_alloc(const gs_dual_memory_t * dmem) + + iigs = gs_alloc_struct((gs_memory_t *)lmem, int_gstate, &st_int_gstate, + "int_gstate_alloc(int_gstate)"); ++ if (iigs == NULL) ++ return NULL; + int_gstate_map_refs(iigs, make_null); + make_empty_array(&iigs->dash_pattern_array, a_all); + gs_alloc_ref_array(lmem, &proc0, a_readonly + a_executable, 2, +@@ -134,6 +136,8 @@ int_gstate_alloc(const gs_dual_memory_t * dmem) + prci = gs_alloc_struct((gs_memory_t *)gmem, int_remap_color_info_t, + &st_int_remap_color_info, + "int_gstate_alloc(remap color info)"); ++ if (prci == NULL) ++ return NULL; + make_struct(&iigs->remap_color_info, imemory_space(gmem), prci); + clear_pagedevice(iigs); + gs_state_set_client(pgs, iigs, &istate_procs, true); +-- +2.5.5 + + +From 7bacac2668e96e14b7a988cfdc10c34405bfe585 Mon Sep 17 00:00:00 2001 +From: Robin Watts +Date: Tue, 26 Mar 2013 14:48:04 -0700 +Subject: [PATCH 3/5] More memory squeezing fixes. + +Mostly unchecked allocation failures when setting up the gstate. +--- + base/gscolor.c | 6 ++++-- + base/gsptype1.c | 4 +++- + base/gsstate.c | 35 +++++++++++++++++++++++++++++------ + base/gxchar.c | 8 ++++++-- + base/gxdcolor.h | 2 +- + 5 files changed, 43 insertions(+), 12 deletions(-) + +diff --git a/base/gscolor.c b/base/gscolor.c +index 62a687b..81f738d 100644 +--- a/base/gscolor.c ++++ b/base/gscolor.c +@@ -210,7 +210,7 @@ gs_currenttransfer(const gs_state * pgs) + /* ------ Non-operator routines ------ */ + + /* Set device color = 1 for writing into the character cache. */ +-void ++int + gx_set_device_color_1(gs_state * pgs) + { + gs_color_space *pcs; +@@ -222,7 +222,8 @@ gx_set_device_color_1(gs_state * pgs) + gs_setcolorspace(pgs, pcs); + rc_decrement_only_cs(pcs, "gx_set_device_color_1"); + } else { +- /* {csrc} really need to signal an error here */ ++ /* signal an error here */ ++ return_error(gs_error_VMerror); + } + set_nonclient_dev_color(gs_currentdevicecolor_inline(pgs), 1); + pgs->log_op = lop_default; +@@ -233,6 +234,7 @@ gx_set_device_color_1(gs_state * pgs) + if (pgs->effective_overprint_mode == 1) + (void)gs_do_set_overprint(pgs); + ++ return 0; + } + + /* ------ Internal routines ------ */ +diff --git a/base/gsptype1.c b/base/gsptype1.c +index 171025d..0959bea 100644 +--- a/base/gsptype1.c ++++ b/base/gsptype1.c +@@ -158,7 +158,9 @@ gs_pattern1_make_pattern(gs_client_color * pcc, + gs_set_logical_op(saved, lop_default); + break; + case 2: /* uncolored */ +- gx_set_device_color_1(saved); ++ code = gx_set_device_color_1(saved); ++ if (code < 0) ++ goto fsaved; + break; + default: + code = gs_note_error(gs_error_rangecheck); +diff --git a/base/gsstate.c b/base/gsstate.c +index e3e5b70..a0419ff 100644 +--- a/base/gsstate.c ++++ b/base/gsstate.c +@@ -223,8 +223,19 @@ gs_state_alloc(gs_memory_t * mem) + + if (pgs == 0) + return 0; +- pgs->saved = 0; + *(gs_imager_state *)pgs = gstate_initial; /* this sets is_gstate == true */ ++ /* Need to set up at least enough to make gs_state_free happy */ ++ pgs->saved = 0; ++ pgs->path = NULL; ++ pgs->clip_path = NULL; ++ pgs->clip_stack = NULL; ++ pgs->view_clip = NULL; ++ pgs->effective_clip_path = NULL; ++ pgs->font = NULL; ++ pgs->root_font = NULL; ++ pgs->show_gstate = NULL; ++ pgs->device = NULL; ++ pgs->dfilter_stack = NULL; + + /* + * Just enough of the state is initialized at this point +@@ -247,6 +258,8 @@ gs_state_alloc(gs_memory_t * mem) + pgs->clip_path = gx_cpath_alloc(mem, "gs_state_alloc(clip_path)"); + pgs->clip_stack = 0; + pgs->view_clip = gx_cpath_alloc(mem, "gs_state_alloc(view_clip)"); ++ if (pgs->view_clip == NULL) ++ goto fail; + pgs->view_clip->rule = 0; /* no clipping */ + pgs->effective_clip_id = pgs->clip_path->id; + pgs->effective_view_clip_id = gs_no_id; +@@ -254,14 +267,24 @@ gs_state_alloc(gs_memory_t * mem) + pgs->effective_clip_shared = true; + /* Initialize things so that gx_remap_color won't crash. */ + pgs->color[0].color_space = gs_cspace_new_DeviceGray(pgs->memory); ++ if (pgs->color[0].color_space == NULL) ++ goto fail; + pgs->color[1].color_space = gs_cspace_new_DeviceGray(pgs->memory); ++ if (pgs->color[1].color_space == NULL) ++ goto fail; + pgs->in_cachedevice = 0; + gs_swapcolors_quick(pgs); /* To color 1 */ +- gx_set_device_color_1(pgs); /* sets colorspace and client color */ ++ code = gx_set_device_color_1(pgs); /* sets colorspace and client color */ ++ if (code < 0) ++ goto fail; + gs_swapcolors_quick(pgs); /* To color 0 */ +- gx_set_device_color_1(pgs); /* sets colorspace and client color */ ++ code = gx_set_device_color_1(pgs); /* sets colorspace and client color */ ++ if (code < 0) ++ goto fail; + pgs->device = 0; /* setting device adjusts refcts */ +- gs_nulldevice(pgs); ++ code = gs_nulldevice(pgs); ++ if (code < 0) ++ goto fail; + gs_setalpha(pgs, 1.0); + gs_settransfer(pgs, gs_identity_transfer); + gs_setflat(pgs, 1.0); +@@ -886,7 +909,7 @@ gstate_free_parts(const gs_state * parts, gs_memory_t * mem, client_name_t cname + gx_cpath_free(parts->effective_clip_path, cname); + gx_cpath_free(parts->clip_path, cname); + if (parts->path) +- gx_path_free(parts->path, cname); ++ gx_path_free(parts->path, cname); + } + + /* Allocate the privately allocated parts of a gstate. */ +@@ -1223,4 +1246,4 @@ int gs_swapcolors(gs_state *pgs) + return gs_do_set_overprint(pgs); + } + return 0; +-} +\ No newline at end of file ++} +diff --git a/base/gxchar.c b/base/gxchar.c +index 40c42f1..e2e8692 100644 +--- a/base/gxchar.c ++++ b/base/gxchar.c +@@ -689,9 +689,13 @@ set_cache_device(gs_show_enum * penum, gs_state * pgs, floatp llx, floatp lly, + clip_box.q.y = int2fixed(iheight); + if ((code = gx_clip_to_rectangle(pgs, &clip_box)) < 0) + return code; +- gx_set_device_color_1(pgs); /* write 1's */ ++ code = gx_set_device_color_1(pgs); /* write 1's */ ++ if (code < 0) ++ return code; + gs_swapcolors_quick(pgs); +- gx_set_device_color_1(pgs); /* write 1's */ ++ code = gx_set_device_color_1(pgs); /* write 1's */ ++ if (code < 0) ++ return code; + gs_swapcolors_quick(pgs); + pgs->in_cachedevice = CACHE_DEVICE_CACHING; + } +diff --git a/base/gxdcolor.h b/base/gxdcolor.h +index 476f59e..70b1291 100644 +--- a/base/gxdcolor.h ++++ b/base/gxdcolor.h +@@ -300,7 +300,7 @@ extern dev_color_proc_get_phase(gx_dc_ht_get_phase); + + /* Set up device color 1 for writing into a mask cache */ + /* (e.g., the character cache). */ +-void gx_set_device_color_1(gs_state * pgs); ++int gx_set_device_color_1(gs_state * pgs); + + /* Remap the color if necessary. */ + int gx_remap_color(gs_state *); +-- +2.5.5 + + +From 0a2b1cddf39ddbe263c61b15af283aaf0f1d8d00 Mon Sep 17 00:00:00 2001 +From: Robin Watts +Date: Thu, 28 Mar 2013 19:42:34 +0000 +Subject: [PATCH 4/5] Another memory squeezing fix. + +Check allocations for failures. Free objects in the cleanup path. +--- + base/gsicc_manage.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/base/gsicc_manage.c b/base/gsicc_manage.c +index 03cc29c..e0e7d93 100644 +--- a/base/gsicc_manage.c ++++ b/base/gsicc_manage.c +@@ -1628,7 +1628,7 @@ gsicc_profile_new(stream *s, gs_memory_t *memory, const char* pname, + { + cmm_profile_t *result; + int code; +- char *nameptr; ++ char *nameptr = NULL; + gs_memory_t *mem_nongc = memory->non_gc_memory; + + result = (cmm_profile_t*) gs_alloc_bytes(mem_nongc, sizeof(cmm_profile_t), +@@ -1639,6 +1639,10 @@ gsicc_profile_new(stream *s, gs_memory_t *memory, const char* pname, + if (namelen > 0) { + nameptr = (char*) gs_alloc_bytes(mem_nongc, namelen+1, + "gsicc_profile_new"); ++ if (nameptr == NULL) { ++ gs_free_object(mem_nongc, result, "gsicc_profile_new"); ++ return NULL; ++ } + memcpy(nameptr, pname, namelen); + nameptr[namelen] = '\0'; + result->name = nameptr; +@@ -1654,6 +1658,7 @@ gsicc_profile_new(stream *s, gs_memory_t *memory, const char* pname, + code = gsicc_load_profile_buffer(result, s, mem_nongc); + if (code < 0) { + gs_free_object(mem_nongc, result, "gsicc_profile_new"); ++ gs_free_object(mem_nongc, nameptr, "gsicc_profile_new"); + return NULL; + } + } else { +@@ -1670,6 +1675,7 @@ gsicc_profile_new(stream *s, gs_memory_t *memory, const char* pname, + result->lock = gx_monitor_alloc(mem_nongc); + if (result->lock == NULL ) { + gs_free_object(mem_nongc, result, "gsicc_profile_new"); ++ gs_free_object(mem_nongc, nameptr, "gsicc_profile_new"); + return(NULL); + } + if_debug1m(gs_debug_flag_icc, mem_nongc, +-- +2.5.5 + + +From e6997f1f7f436eb7ca2ebbc88a7463b880427b69 Mon Sep 17 00:00:00 2001 +From: Michael Vrhel +Date: Fri, 22 Apr 2016 09:24:52 -0700 +Subject: [PATCH 5/5] Coverity ID 94568 Dereference after null check + +The device profile is not even used in this function. +Likely left over by mistake. Dereference of NULL no +longer possible here. +--- + base/gsicc.c | 6 ++---- + 1 file changed, 2 insertions(+), 4 deletions(-) + +diff --git a/base/gsicc.c b/base/gsicc.c +index e7093c5..f74f55b 100644 +--- a/base/gsicc.c ++++ b/base/gsicc.c +@@ -606,10 +606,8 @@ gx_serialize_ICC(const gs_color_space * pcs, stream * s) + static int + gx_set_overprint_ICC(const gs_color_space * pcs, gs_state * pgs) + { +- gx_device * dev = pgs->device; +- gx_device_color_info * pcinfo = (dev == 0 ? 0 : &dev->color_info); +- cmm_dev_profile_t *dev_profile; +- int code = dev_proc(dev, get_profile)(dev, &dev_profile); ++ gx_device *dev = pgs->device; ++ gx_device_color_info *pcinfo = (dev == 0 ? 0 : &dev->color_info); + + /* check if we require special handling */ + if ( !pgs->overprint || +-- +2.5.5 + diff --git a/SOURCES/ghostscript-import-lcms2-2.6-changes.patch b/SOURCES/ghostscript-import-lcms2-2.6-changes.patch new file mode 100644 index 0000000..34a53f9 --- /dev/null +++ b/SOURCES/ghostscript-import-lcms2-2.6-changes.patch @@ -0,0 +1,261 @@ +From ccd21419317edb7709b95f95bb7cc742ba8dea32 Mon Sep 17 00:00:00 2001 +From: Robin Watts +Date: Tue, 31 Dec 2013 15:19:54 +0000 +Subject: [PATCH] Import LCMS 2.6 Release version + +Update gs calling code to cope, including simple mutex +handlers. Also incorporates our optimisations etc. +--- + base/gsicc_lcms2.c | 109 ++++++++++++++++++++++++++++++++++++++++++----------- + base/lib.mak | 3 +- + 2 files changed, 90 insertions(+), 22 deletions(-) + +diff --git a/base/gsicc_lcms2.c b/base/gsicc_lcms2.c +index 9a013be..ff6097c 100644 +--- a/base/gsicc_lcms2.c ++++ b/base/gsicc_lcms2.c +@@ -22,6 +22,12 @@ + #include "gslibctx.h" + #include "gserrors.h" + ++#define USE_LCMS2_LOCKING ++ ++#ifdef USE_LCMS2_LOCKING ++#include "gxsync.h" ++#endif ++ + #define DUMP_CMS_BUFFER 0 + #define DEBUG_LCMS_MEM 0 + #define LCMS_BYTES_MASK 0x7 +@@ -43,7 +49,7 @@ static + void *gs_lcms2_malloc(cmsContext id, unsigned int size) + { + void *ptr; +- gs_memory_t *mem = (gs_memory_t *)id; ++ gs_memory_t *mem = (gs_memory_t *)cmsGetContextUserData(id); + + ptr = gs_alloc_bytes(mem, size, "lcms"); + #if DEBUG_LCMS_MEM +@@ -55,7 +61,7 @@ void *gs_lcms2_malloc(cmsContext id, unsigned int size) + static + void gs_lcms2_free(cmsContext id, void *ptr) + { +- gs_memory_t *mem = (gs_memory_t *)id; ++ gs_memory_t *mem = (gs_memory_t *)cmsGetContextUserData(id); + if (ptr != NULL) { + #if DEBUG_LCMS_MEM + gs_warn1("lcms free at 0x%x",ptr); +@@ -67,7 +73,7 @@ void gs_lcms2_free(cmsContext id, void *ptr) + static + void *gs_lcms2_realloc(cmsContext id, void *ptr, unsigned int size) + { +- gs_memory_t *mem = (gs_memory_t *)id; ++ gs_memory_t *mem = (gs_memory_t *)cmsGetContextUserData(id); + void *ptr2; + + if (ptr == 0) +@@ -97,9 +103,53 @@ static cmsPluginMemHandler gs_cms_memhandler = + gs_lcms2_realloc, + NULL, + NULL, +- NULL ++ NULL, + }; + ++#ifdef USE_LCMS2_LOCKING ++ ++static ++void *gs_lcms2_createMutex(cmsContext id) ++{ ++ gs_memory_t *mem = (gs_memory_t *)cmsGetContextUserData(id); ++ ++ return gx_monitor_alloc(mem); ++} ++ ++static ++void gs_lcms2_destroyMutex(cmsContext id, void* mtx) ++{ ++ gx_monitor_free((gx_monitor_t *)mtx); ++} ++ ++static ++cmsBool gs_lcms2_lockMutex(cmsContext id, void* mtx) ++{ ++ return !gx_monitor_enter((gx_monitor_t *)mtx); ++} ++ ++static ++void gs_lcms2_unlockMutex(cmsContext id, void* mtx) ++{ ++ gx_monitor_leave((gx_monitor_t *)mtx); ++} ++ ++static cmsPluginMutex gs_cms_mutexhandler = ++{ ++ { ++ cmsPluginMagicNumber, ++ 2060, ++ cmsPluginMutexSig, ++ NULL ++ }, ++ gs_lcms2_createMutex, ++ gs_lcms2_destroyMutex, ++ gs_lcms2_lockMutex, ++ gs_lcms2_unlockMutex ++}; ++ ++#endif ++ + /* Get the number of channels for the profile. + Input count */ + int +@@ -194,15 +244,19 @@ gcmmhprofile_t + gscms_get_profile_handle_mem(gs_memory_t *mem, unsigned char *buffer, + unsigned int input_size) + { +- cmsSetLogErrorHandler(gscms_error); +- return(cmsOpenProfileFromMemTHR((cmsContext)mem,buffer,input_size)); ++ cmsContext ctx = gs_lib_ctx_get_cms_context(mem); ++ ++ cmsSetLogErrorHandlerTHR(ctx, gscms_error); ++ return(cmsOpenProfileFromMemTHR(ctx,buffer,input_size)); + } + + /* Get ICC Profile handle from file ptr */ + gcmmhprofile_t + gscms_get_profile_handle_file(gs_memory_t *mem,const char *filename) + { +- return(cmsOpenProfileFromFileTHR((cmsContext)mem, filename, "r")); ++ cmsContext ctx = gs_lib_ctx_get_cms_context(mem); ++ ++ return(cmsOpenProfileFromFileTHR(ctx, filename, "r")); + } + + /* Transform an entire buffer */ +@@ -347,6 +401,7 @@ gscms_get_link(gcmmhprofile_t lcms_srchandle, + int src_nChannels,des_nChannels; + int lcms_src_color_space, lcms_des_color_space; + unsigned int flag; ++ cmsContext ctx = gs_lib_ctx_get_cms_context(memory); + + /* Check for case of request for a transfrom from a device link profile + in that case, the destination profile is NULL */ +@@ -416,7 +471,7 @@ gscms_get_link(gcmmhprofile_t lcms_srchandle, + } + } + /* Create the link */ +- return cmsCreateTransformTHR((cmsContext)memory, ++ return cmsCreateTransformTHR(ctx, + lcms_srchandle, src_data_type, + lcms_deshandle, des_data_type, + rendering_params->rendering_intent,flag); +@@ -443,6 +498,7 @@ gscms_get_link_proof_devlink(gcmmhprofile_t lcms_srchandle, + cmsHPROFILE hProfiles[5]; + int nProfiles = 0; + unsigned int flag; ++ cmsContext ctx = gs_lib_ctx_get_cms_context(memory); + + /* Check if the rendering intent is something other than relative colorimetric + and if we have a proofing profile. In this case we need to create the +@@ -505,7 +561,7 @@ gscms_get_link_proof_devlink(gcmmhprofile_t lcms_srchandle, + flag = (flag | cmsFLAGS_BLACKPOINTCOMPENSATION); + } + /* Use relative colorimetric here */ +- temptransform = cmsCreateMultiprofileTransformTHR((cmsContext)memory, ++ temptransform = cmsCreateMultiprofileTransformTHR(ctx, + hProfiles, nProfiles, src_data_type, + des_data_type, gsRELATIVECOLORIMETRIC, flag); + cmsCloseProfile(src_to_proof); +@@ -558,7 +614,7 @@ gscms_get_link_proof_devlink(gcmmhprofile_t lcms_srchandle, + || rendering_params->black_point_comp == gsBLACKPTCOMP_ON_OR) { + flag = (flag | cmsFLAGS_BLACKPOINTCOMPENSATION); + } +- return cmsCreateMultiprofileTransformTHR((cmsContext)memory, ++ return cmsCreateMultiprofileTransformTHR(ctx, + hProfiles, nProfiles, src_data_type, + des_data_type, rendering_params->rendering_intent, flag); + } +@@ -568,15 +624,20 @@ gscms_get_link_proof_devlink(gcmmhprofile_t lcms_srchandle, + int + gscms_create(gs_memory_t *memory) + { ++ cmsContext ctx; ++ + /* Set our own error handling function */ +- cmsSetLogErrorHandler(gscms_error); +- cmsPluginTHR(memory, &gs_cms_memhandler); +- /* If we had created any persitent state that we needed access to in the +- * other functions, we should store that by calling: +- * gs_lib_ctx_set_cms_context(memory, state); +- * We can then retrieve it anywhere else by calling: +- * gs_lib_ctx_get_cms_context(memory); +- * LCMS currently uses no such state. */ ++ ctx = cmsCreateContext((void *)&gs_cms_memhandler, memory); ++ if (ctx == NULL) ++ return gs_error_VMerror; ++ ++#ifdef USE_LCMS2_LOCKING ++ cmsPluginTHR(ctx, (void *)&gs_cms_mutexhandler); ++#endif ++ ++ cmsSetLogErrorHandlerTHR(ctx, gscms_error); ++ gs_lib_ctx_set_cms_context(memory, ctx); ++ + return 0; + } + +@@ -584,7 +645,12 @@ gscms_create(gs_memory_t *memory) + void + gscms_destroy(gs_memory_t *memory) + { +- /* Nothing to do here for lcms */ ++ cmsContext ctx = gs_lib_ctx_get_cms_context(memory); ++ if (ctx == NULL) ++ return; ++ ++ cmsDeleteContext(ctx); ++ gs_lib_ctx_set_cms_context(memory, NULL); + } + + /* Have the CMS release the link */ +@@ -662,6 +728,7 @@ gscms_get_name2device_link(gsicc_link_t *icclink, + cmsUInt32Number dwOutputFormat; + cmsUInt32Number lcms_proof_flag; + int number_colors; ++ cmsContext ctx = gs_lib_ctx_get_cms_context(memory); + + /* NOTE: We need to add a test here to check that we even HAVE + device values in here and NOT just CIELAB values */ +@@ -672,7 +739,7 @@ gscms_get_name2device_link(gsicc_link_t *icclink, + } + /* Create the transform */ + /* ToDo: Adjust rendering intent */ +- hTransform = cmsCreateProofingTransformTHR(memory, ++ hTransform = cmsCreateProofingTransformTHR(ctx, + lcms_srchandle, TYPE_NAMED_COLOR_INDEX, + lcms_deshandle, TYPE_CMYK_8, + lcms_proofhandle,INTENT_PERCEPTUAL, +@@ -692,4 +759,4 @@ gscms_get_name2device_link(gsicc_link_t *icclink, + if(lcms_deshandle) cmsCloseProfile(lcms_deshandle); + if(lcms_proofhandle) cmsCloseProfile(lcms_proofhandle); + return; +-} +\ No newline at end of file ++} +diff --git a/base/lib.mak b/base/lib.mak +index e9cb290..10d0d0d 100644 +--- a/base/lib.mak ++++ b/base/lib.mak +@@ -2862,7 +2862,8 @@ $(GLOBJ)gsicc_lcms2_0.$(OBJ) : $(GLSRC)gsicc_lcms2.c\ + $(gsicc_cms_h) $(lcms2_h) $(gslibctx_h) $(lcms2_plugin_h) $(gserrors_h) + $(GLLCMS2CC) $(GLO_)gsicc_lcms2_0.$(OBJ) $(C_) $(GLSRC)gsicc_lcms2.c + +-$(GLOBJ)gsicc_lcms2.$(OBJ) : $(GLOBJ)gsicc_lcms2_$(SHARE_LCMS).$(OBJ) ++$(GLOBJ)gsicc_lcms2.$(OBJ) : $(GLOBJ)gsicc_lcms2_$(SHARE_LCMS).$(OBJ) $(gp_h) \ ++ $(gxsync_h) + $(CP_) $(GLOBJ)gsicc_lcms2_$(SHARE_LCMS).$(OBJ) $(GLOBJ)gsicc_lcms2.$(OBJ) + + # Note that gsicc_create requires compile with lcms to obtain icc34.h +-- +2.5.5 + diff --git a/SPECS/ghostscript.spec b/SPECS/ghostscript.spec index 18d4bdd..727df65 100644 --- a/SPECS/ghostscript.spec +++ b/SPECS/ghostscript.spec @@ -5,7 +5,7 @@ Summary: A PostScript interpreter and renderer Name: ghostscript Version: %{gs_ver} -Release: 18%{?dist} +Release: 20%{?dist} # Included CMap data is Redistributable, no modification permitted, # see http://bugzilla.redhat.com/487510 @@ -39,6 +39,10 @@ Patch15: ghostscript-zfapi-crash.patch Patch16: ghostscript-gstoraster-costs.patch Patch17: ghostscript-trio-g.patch Patch18: ghostscript-crash.patch +Patch19: ghostscript-import-lcms2-2.6-changes.patch +Patch20: ghostscript-hanging-in-convert.patch +Patch21: ghostscript-check-icc-profile-errors.patch +Patch22: ghostscript-cups-icc-profile.patch Requires: urw-fonts >= 1.1, ghostscript-fonts Requires: poppler-data @@ -175,6 +179,18 @@ rm -rf expat freetype icclib jasper jpeg lcms lcms2 libpng openjpeg zlib cups/li # Prevent memory handling crash (bug #1105519). %patch18 -p1 -b .crash +# Prevent crashing when opening a .ps file followed by another (bug #959351) +%patch19 -p1 -b .import-lcms2-2.6-changes + +# Fix ghostscript hanging indefinitely when converting PDF -> PNG (bug #1302121) +%patch20 -p1 + +# Do not SIGSEGV after icc_profile error, report error instead (bug #1243784) +%patch21 -p1 + +# Fix the color printing on HP InkJet printers (bug #1225858) +%patch22 -p1 + # Remove pdfopt man pages which were mistakenly left in (bug #963882). rm man/{de/,}pdfopt.1 @@ -374,6 +390,15 @@ rm -rf $RPM_BUILD_ROOT %{_libdir}/libgs.so %changelog +* Wed Jul 13 2016 David Kaspar [Dee'Kej] - 9.07-20 +- Fixed some complains of CovScan in ghostscript-hanging-in-convert.patch + +* Thu Jun 2 2016 David Kaspar [Dee'Kej] - 9.07-19 +- Import LCMS2 2.6 rebase changes into ghostscript (bug #959351) +- Fix hanging of ghostscript when converting PDF -> PNG (bug #1302121) +- Do not SIGSEGV after icc_profile error, report error instead (bug #1243784) +- Fix the color printing on HP InkJet printers (bug #1225858) + * Wed Sep 24 2014 Tim Waugh 9.07-18 - Applied patch from upstream to fix memory handling issue that could lead to crashes (bug #1105519).