[gs-cvs] rev 8068 - trunk/gs/src

leonardo at ghostscript.com leonardo at ghostscript.com
Tue Jun 19 09:44:29 PDT 2007


Author: leonardo
Date: 2007-06-19 09:44:29 -0700 (Tue, 19 Jun 2007)
New Revision: 8068

Modified:
   trunk/gs/src/idict.c
Log:
Fix (PS interpreter) : "undef" data change was not properly saved.

DETAILS :

Bug 689284 "Abnormal dependence of 'known' on name hash indices".

The "undef" algorithm has an "optimization" branch for packed keys,
which replaces "deleted" elements with "empty" (i.e. unused).
However this data change was not tracked for "restore".
In some rare cases it causes a wrong result for "known", "get", "bind"
and others. Interesting that "dictforall" doesn't miss such keys
when "known" does, but it could enumerate same key several times
with older values.

The bug persists since the repository was created in March 2000.

This change simply saves the changed data for restore.

EXPECTED DIFFERENCES :

The test 311-03.ps may depend on this patch in some environments,
because the old behavior occasionally depends on hame hash indices.
For example, contributing new names into gs/Resource directory
could change the Postscript interpreter result.


Modified: trunk/gs/src/idict.c
===================================================================
--- trunk/gs/src/idict.c	2007-06-19 11:36:06 UTC (rev 8067)
+++ trunk/gs/src/idict.c	2007-06-19 16:44:29 UTC (rev 8068)
@@ -573,12 +573,13 @@
     mem = dict_memory(pdict);
     if (dict_is_packed(pdict)) {
 	ref_packed *pkp = pdict->keys.value.writable_packed + index;
+	bool must_save = ref_must_save_in(mem, &pdict->keys);
 
 	if_debug3('d', "[d]0x%lx: removing key at 0%lx: 0x%x\n",
 		  (ulong)pdict, (ulong)pkp, (uint)*pkp);
 	/* See the initial comment for why it is safe not to save */
 	/* the change if the keys array itself is new. */
-	if (ref_must_save_in(mem, &pdict->keys))
+	if (must_save)
 	    ref_do_save_in(mem, &pdict->keys, pkp, "dict_undef(key)");
 	/*
 	 * Accumulating deleted entries slows down lookup.
@@ -594,8 +595,15 @@
 	    uint end = nslots(pdict);
 
 	    *pkp = packed_key_empty;
-	    while (++index < end && *++pkp == packed_key_deleted)
-		*pkp = packed_key_empty;
+	    if (must_save) {
+		while (++index < end && *++pkp == packed_key_deleted) {
+		    ref_do_save_in(mem, &pdict->keys, pkp, "dict_undef(key)");
+		    *pkp = packed_key_empty;
+		}
+	    } else {
+		while (++index < end && *++pkp == packed_key_deleted)
+		    *pkp = packed_key_empty;
+	    }
 	} else
 	    *pkp = packed_key_deleted;
     } else {			/* not packed */



More information about the gs-cvs mailing list