summaryrefslogtreecommitdiff
path: root/base/gsicc_profilecache.c
diff options
context:
space:
mode:
authorChris Liddell <chris.liddell@artifex.com>2021-04-08 15:30:56 +0100
committerChris Liddell <chris.liddell@artifex.com>2021-04-09 07:54:56 +0100
commitca567f59767d633eda63e418e4eac680e16c5331 (patch)
treee55a9fc8952f03c089a9562211dd9cdf7051a44b /base/gsicc_profilecache.c
parent7a708a373809849e2379121218ef3114cdff002d (diff)
downloadghostpdl-ca567f59767d633eda63e418e4eac680e16c5331.tar.gz
Harden the use of the ICC cs cache for Cal spaces
Originally, the cache key used was the "saveid" entry in the ref "value" union. Since the ref object in question was a dictionary, this meant an unsigned long interpretation of the pointer value from "dictval" in the same union. This was unsafe for a couple of reasons: Postscript allows dictionary objects to be reused, so it was feasible for the same dictionary object to be used to define two different color spaces, this meaning the cache would retrieve the wrong ICC color space. Secondly, garbage collection results in objects (like dictval instances) moving address. So, the same dictionary need not be at the same address, but a different dictionary could be. Since the other CIE based spaces use an MD5 hash of the contents of the color spaces to create the cache key, this implements the same things, bringing the Cal color spaces in-line with their CIE bretherin. In addition, where we retrieve color spaces from the ICC cs cache, add in a simple validation of the number components before going ahead and using the cached color space. This came out of investigating a *long* standing indeterimate cluster test file tests_private/comparefiles/p2b-100.pdf and we fervently hope that this will fix that indeterminacy.
Diffstat (limited to 'base/gsicc_profilecache.c')
-rw-r--r--base/gsicc_profilecache.c6
1 files changed, 6 insertions, 0 deletions
diff --git a/base/gsicc_profilecache.c b/base/gsicc_profilecache.c
index db2e8ae4a..900a3440b 100644
--- a/base/gsicc_profilecache.c
+++ b/base/gsicc_profilecache.c
@@ -95,6 +95,9 @@ gsicc_add_cs(gs_gstate * pgs, gs_color_space * colorspace, uint64_t dictkey)
gsicc_profile_cache_t *profile_cache = pgs->icc_profile_cache;
gs_memory_t *memory = pgs->memory;
+ if (dictkey == 0)
+ return;
+
/* The entry has to be added in stable memory. We want them
to be maintained across the gsave and grestore process */
result = gs_alloc_struct(memory->stable_memory, gsicc_profile_entry_t,
@@ -125,6 +128,9 @@ gsicc_find_cs(uint64_t key_test, gs_gstate * pgs)
gsicc_profile_cache_t *profile_cache = pgs->icc_profile_cache;
gsicc_profile_entry_t *prev = NULL, *curr = profile_cache->head;
+ if (key_test == 0)
+ return NULL;
+
/* Look through the cache for the key. If found, move to MRU */
while (curr != NULL ){
if (curr->key == key_test){