[gs-code-review] Fix for 24-05 and 24-06

Alex Cherepanov alexcher at quadnet.net
Thu Oct 26 11:02:26 PDT 2006


Attached is the fix for CET 24-05.PS and CET 24-06.PS .

Don't modify the destination string of cvs and cvrs operators on
failure and change the returned error codes to suit the test.

Adobe enterpreters have a bug
   1234556789 10 ( ) cvrs
restores the stack as
   123456789 ( ) ( )

This bug has not been transplanted to Ghostscript.

DIFFERENCES
None

-------------- next part --------------
Index: gs/src/iutil.c
===================================================================
--- gs/src/iutil.c	(revision 7121)
+++ gs/src/iutil.c	(working copy)
@@ -288,6 +288,11 @@
  * *prlen contains the amount of data returned.  start_pos is the starting
  * output position -- the first start_pos bytes of output are discarded.
  *
+ * When (restart = false) return e_rangecheck the when destination wasn't
+ * large enough without modifying the destination. This is needed for 
+ * compatibility with Adobe implementation of cvs and cvrs, which don't
+ * change the destination string on failure.
+ *
  * The mem argument is only used for getting the type of structures,
  * not for allocating; if it is NULL and full_print != 0, structures will
  * print as --(struct)--.
@@ -299,7 +304,7 @@
 private void ensure_dot(char *);
 int
 obj_cvp(const ref * op, byte * str, uint len, uint * prlen,
-	int full_print, uint start_pos, const gs_memory_t *mem)
+	int full_print, uint start_pos, const gs_memory_t *mem, bool restart)
 {
     char buf[50];  /* big enough for any float, double, or struct name */
     const byte *data = (const byte *)buf;
@@ -342,7 +347,7 @@
 	}
 	case t_operator:
 	case t_oparray:  
-	    code = obj_cvp(op, (byte *)buf + 2, sizeof(buf) - 4, &size, 0, 0, mem);
+	    code = obj_cvp(op, (byte *)buf + 2, sizeof(buf) - 4, &size, 0, 0, mem, restart);
 	    if (code < 0) 
 		return code;
 	    buf[0] = buf[1] = buf[size + 2] = buf[size + 3] = '-';
@@ -356,10 +361,10 @@
 		goto nl;
 	    }
 	    if (start_pos > 0)
-		return obj_cvp(op, str, len, prlen, 0, start_pos - 1, mem);
+		return obj_cvp(op, str, len, prlen, 0, start_pos - 1, mem, restart);
 	    if (len < 1)
 		return_error(e_rangecheck);
-	    code = obj_cvp(op, str + 1, len - 1, prlen, 0, 0, mem);
+	    code = obj_cvp(op, str + 1, len - 1, prlen, 0, 0, mem, restart);
 	    if (code < 0)
 		return code;
 	    str[0] = '/';
@@ -545,6 +550,8 @@
 rs: size = strlen((const char *)data);
 nl: if (size < start_pos)
 	return_error(e_rangecheck);
+    if (!restart && size > len)
+	return_error(e_rangecheck);
     size -= start_pos;
     *prlen = min(size, len);
     memmove(str, data + start_pos, *prlen);
@@ -584,7 +591,7 @@
 obj_cvs(const gs_memory_t *mem, const ref * op, byte * str, uint len, uint * prlen,
 	const byte ** pchars)
 {
-    int code = obj_cvp(op, str, len, prlen, 0, 0, mem);  /* NB: NULL memptr */
+    int code = obj_cvp(op, str, len, prlen, 0, 0, mem, false);  /* NB: NULL memptr */
 
     if (code != 1 && pchars) {
 	*pchars = str;
Index: gs/src/iutil.h
===================================================================
--- gs/src/iutil.h	(revision 7121)
+++ gs/src/iutil.h	(working copy)
@@ -62,7 +62,7 @@
  */
 #define CVP_MAX_STRING 200  /* strings are truncated here if full_print = 1 */
 int obj_cvp(const ref * op, byte *str, uint len, uint * prlen,
-	    int full_print, uint start_pos, const gs_memory_t *mem);
+	int full_print, uint start_pos, const gs_memory_t *mem, bool restart);
 
 /*
  * Create a printable representation of an object, a la cvs and =.  Return 0
Index: gs/src/zfileio.c
===================================================================
--- gs/src/zfileio.c	(revision 7121)
+++ gs/src/zfileio.c	(working copy)
@@ -757,7 +757,7 @@
     check_write_file(s, op - 2);
     check_type(*op, t_integer);
     code = obj_cvp(op - 1, str, sizeof(str), &len, (int)op->value.intval,
-		   start, imemory);
+		   start, imemory, true);
     if (code == e_rangecheck) {
         code = obj_string_data(imemory, op - 1, &data, &len);
 	if (len < start)
Index: gs/src/ztype.c
===================================================================
--- gs/src/ztype.c	(revision 7121)
+++ gs/src/ztype.c	(working copy)
@@ -345,8 +345,10 @@
 		    pop(2);
 		    return 0;
 		}
+            case t__invalid:
+                return_error(e_stackunderflow);
 	    default:
-		return_op_typecheck(op - 2);
+		return_error(e_rangecheck); /* CET 24-05 wants rangecheck */
 	}
     } else {
 	ulong ival;
@@ -366,8 +368,10 @@
 			return_error(e_rangecheck);
 		    ival = (ulong) (long)fval;
 		} break;
+            case t__invalid:
+                return_error(e_stackunderflow);
 	    default:
-		return_op_typecheck(op - 2);
+		return_error(e_rangecheck); /* CET 24-05 wants rangecheck */
 	}
 	do {
 	    int dit = ival % radix;
@@ -393,8 +397,8 @@
     os_ptr op = osp;
     int code;
 
+    check_write_type(*op, t_string);
     check_op(2);
-    check_write_type(*op, t_string);
     code = convert_to_string(imemory, op - 1, op);
     if (code >= 0)
 	pop(1);


More information about the gs-code-review mailing list