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

tim at ghostscript.com tim at ghostscript.com
Sat Apr 14 07:08:05 PDT 2007


Author: tim
Date: 2007-04-14 07:08:04 -0700 (Sat, 14 Apr 2007)
New Revision: 7847

Modified:
   trunk/gs/src/gdevprn.c
   trunk/gs/src/gxcldev.h
   trunk/gs/src/gxclist.c
   trunk/gs/src/gxclist.h
   trunk/gs/src/gxclread.c
   trunk/gs/src/lib.mak
Log:
Fix for the band_complexity_array overflow issue. First reported in bug
report #689165. Also encountered by me when running the test file for bug
report #688830.

DETAILS:
The band_complexity_array array of a clist reader device was being statically
allocated with 100 elements. As the requirement is 1 element per band,
jobs requiring more than 100 bands could cause an abnormal termination
of ghostscript or some other failure. The array is now allocated dynamically
with 1 element per band.

EXPECTED DIFFERENCES:
Since the CET and comparefiles does not apparently have any jobs which
require than 100 bands, no differences are expected.



Modified: trunk/gs/src/gdevprn.c
===================================================================
--- trunk/gs/src/gdevprn.c	2007-04-12 21:23:35 UTC (rev 7846)
+++ trunk/gs/src/gdevprn.c	2007-04-14 14:08:04 UTC (rev 7847)
@@ -198,6 +198,13 @@
 	ppdev->buf = 0;
 	ppdev->buffer_space = 0;
 	is_command_list = true;
+	
+	/* If the clist is a reader clist, free any band_complexity_array
+	 * memory used by same.
+	 */
+	if (!CLIST_IS_WRITER(pclist_dev))
+	    gx_clist_reader_free_band_complexity_array(pclist_dev);
+	
     } else {
 	/* point at the device bitmap, no need to close mem dev */
 	*the_memory = pmemdev->base;

Modified: trunk/gs/src/gxcldev.h
===================================================================
--- trunk/gs/src/gxcldev.h	2007-04-12 21:23:35 UTC (rev 7846)
+++ trunk/gs/src/gxcldev.h	2007-04-14 14:08:04 UTC (rev 7847)
@@ -266,7 +266,7 @@
 	0, gx_no_bitmap_id,\
 	 { 0, 0 }, { gx_no_color_index, gx_no_color_index },\
 	 { 0, 0, 0, 0 }, lop_default, 0, 0, 0, initial_known,\
-	{ 0, 0 }, 0, { 0 }
+	{ 0, 0 }, { 0, 0 }, { 0, 0 }
 
 /* Define the size of the command buffer used for reading. */
 /* This is needed to split up operations with a large amount of data, */

Modified: trunk/gs/src/gxclist.c
===================================================================
--- trunk/gs/src/gxclist.c	2007-04-12 21:23:35 UTC (rev 7846)
+++ trunk/gs/src/gxclist.c	2007-04-14 14:08:04 UTC (rev 7847)
@@ -27,7 +27,6 @@
 #include "gxdcolor.h"
 
 /* GC information */
-#define CLIST_IS_WRITER(cdev) ((cdev)->common.ymin < 0)
 extern_st(st_imager_state);
 private
 ENUM_PTRS_WITH(device_clist_enum_ptrs, gx_device_clist *cdev)
@@ -36,31 +35,49 @@
 
 	return (ret ? ret : ENUM_OBJ(0));
     }
-    if (!CLIST_IS_WRITER(cdev))
-	return 0;
     index -= st_device_forward_max_ptrs;
-    switch (index) {
-    case 0: return ENUM_OBJ((cdev->writer.image_enum_id != gs_no_id ?
-			     cdev->writer.clip_path : 0));
-    case 1: return ENUM_OBJ((cdev->writer.image_enum_id != gs_no_id ?
-			     cdev->writer.color_space.space : 0));
-    default:
-	return ENUM_USING(st_imager_state, &cdev->writer.imager_state,
-			  sizeof(gs_imager_state), index - 2);
+    if (CLIST_IS_WRITER(cdev)) {
+        switch (index) {
+        case 0: return ENUM_OBJ((cdev->writer.image_enum_id != gs_no_id ?
+                     cdev->writer.clip_path : 0));
+        case 1: return ENUM_OBJ((cdev->writer.image_enum_id != gs_no_id ?
+                     cdev->writer.color_space.space : 0));
+        default:
+        return ENUM_USING(st_imager_state, &cdev->writer.imager_state,
+                  sizeof(gs_imager_state), index - 2);
+        }
     }
+    else {
+        /* 041207
+         * clist is reader.
+         * We don't expect this code to be exercised at this time as the reader
+         * runs under gdev_prn_output_page which is an atomic function of the
+         * interpreter. We do this as this situation may change in the future.
+         */
+        if (index == 0)
+            return ENUM_OBJ(cdev->reader.band_complexity_array);
+        else
+            return 0;
+    }
 ENUM_PTRS_END
 private
 RELOC_PTRS_WITH(device_clist_reloc_ptrs, gx_device_clist *cdev)
 {
     RELOC_PREFIX(st_device_forward);
-    if (!CLIST_IS_WRITER(cdev))
-	return;
-    if (cdev->writer.image_enum_id != gs_no_id) {
-	RELOC_VAR(cdev->writer.clip_path);
-	RELOC_VAR(cdev->writer.color_space.space);
+    if (CLIST_IS_WRITER(cdev)) {
+        if (cdev->writer.image_enum_id != gs_no_id) {
+        RELOC_VAR(cdev->writer.clip_path);
+        RELOC_VAR(cdev->writer.color_space.space);
+        }
+        RELOC_USING(st_imager_state, &cdev->writer.imager_state,
+            sizeof(gs_imager_state));
     }
-    RELOC_USING(st_imager_state, &cdev->writer.imager_state,
-		sizeof(gs_imager_state));
+    else
+        /* 041207
+         * clist is reader.
+         * See note above in ENUM_PTRS_WITH section.
+         */
+        RELOC_VAR(cdev->reader.band_complexity_array);
 } RELOC_PTRS_END
 public_st_device_clist();
 
@@ -615,10 +632,15 @@
 int
 clist_finish_page(gx_device *dev, bool flush)
 {
-    gx_device_clist_writer * const cdev =
-	&((gx_device_clist *)dev)->writer;
+    gx_device_clist_writer * const cdev =	&((gx_device_clist *)dev)->writer;
     int code;
 
+    /* If this is a reader clist, which is about to be reset to a writer,
+     * free any band_complexity_array memory used by same.
+     */
+    if (!CLIST_IS_WRITER((gx_device_clist *)dev))
+       	gx_clist_reader_free_band_complexity_array( (gx_device_clist *)dev );
+
     if (flush) {
 	if (cdev->page_cfile != 0)
 	    cdev->page_info.io_procs->rewind(cdev->page_cfile, true, cdev->page_cfname);

Modified: trunk/gs/src/gxclist.h
===================================================================
--- trunk/gs/src/gxclist.h	2007-04-12 21:23:35 UTC (rev 7846)
+++ trunk/gs/src/gxclist.h	2007-04-14 14:08:04 UTC (rev 7847)
@@ -261,7 +261,7 @@
 					/* means all planes */
     const gx_placed_page *pages;
     int num_pages;
-    gx_band_complexity_t band_complexity_array[100];  /* NB: should be: num_bands elements */
+    gx_band_complexity_t *band_complexity_array;  /* num_bands elements */
 } gx_device_clist_reader;
 
 typedef union gx_device_clist_s {
@@ -270,6 +270,8 @@
     gx_device_clist_writer writer;
 } gx_device_clist;
 
+#define CLIST_IS_WRITER(cdev) ((cdev)->common.ymin < 0)
+
 extern_st(st_device_clist);
 #define public_st_device_clist()	/* in gxclist.c */\
   gs_public_st_complex_only(st_device_clist, gx_device_clist,\
@@ -355,6 +357,10 @@
 gx_band_complexity_t *
 clist_get_band_complexity(gx_device *dev, int y);
 
+/* Free any band_complexity_array memory used by the clist reader device */
+void
+gx_clist_reader_free_band_complexity_array(gx_device_clist *cldev);
+
 /* deep copy constructor if from != NULL
  * default constructor if from == NULL
  */

Modified: trunk/gs/src/gxclread.c
===================================================================
--- trunk/gs/src/gxclread.c	2007-04-12 21:23:35 UTC (rev 7846)
+++ trunk/gs/src/gxclread.c	2007-04-14 14:08:04 UTC (rev 7847)
@@ -26,6 +26,7 @@
 #include "gxgetbit.h"
 #include "gxhttile.h"
 #include "gdevplnx.h"
+#include "gsmemory.h"
 /*
  * We really don't like the fact that gdevprn.h is included here, since
  * command lists are supposed to be usable for purposes other than printer
@@ -234,6 +235,7 @@
     /* For normal rasterizing, pages and num_pages are zero. */
     crdev->pages = 0;
     crdev->num_pages = 0;
+    crdev->band_complexity_array = NULL;
 
     return gx_clist_reader_read_band_complexity(dev);
 }
@@ -561,9 +563,22 @@
 
 	return &crdev->band_complexity_array[band_number];
     }
-    return NULL;   
+    return NULL;
 }
 
+/* Free any band_complexity_array memory used by the clist reader device */
+void gx_clist_reader_free_band_complexity_array( gx_device_clist *cldev )
+{
+	if (cldev != NULL) {
+	    gx_device_clist_reader * const crdev = &cldev->reader;
+	    
+	    if ( crdev->band_complexity_array ) {
+	    	gs_free_object( crdev->memory, crdev->band_complexity_array,
+	    	  "gx_clist_reader_free_band_complexity_array" );
+	    	crdev->band_complexity_array = NULL;
+	    }
+	}
+}
 
 /* call once per read page to read the band complexity from clist file 
  */
@@ -590,6 +605,14 @@
 	save_pos = crdev->page_info.io_procs->ftell(rs.page_bfile);
 	crdev->page_info.io_procs->fseek(rs.page_bfile, pos, SEEK_SET, rs.page_bfname);
 
+	if ( crdev->band_complexity_array == NULL )
+		crdev->band_complexity_array = (gx_band_complexity_t*)
+		  gs_alloc_byte_array( crdev->memory, crdev->nbands,
+		  sizeof( gx_band_complexity_t ), "gx_clist_reader_read_band_complexity" );
+
+	if ( crdev->band_complexity_array == NULL )
+		return_error(gs_error_VMerror);
+
 	for (i=0; i < crdev->nbands; i++) {
 	    crdev->page_info.io_procs->fread_chars(&cb, sizeof(cb), rs.page_bfile);
 	    crdev->band_complexity_array[i] = cb.band_complexity;

Modified: trunk/gs/src/lib.mak
===================================================================
--- trunk/gs/src/lib.mak	2007-04-12 21:23:35 UTC (rev 7846)
+++ trunk/gs/src/lib.mak	2007-04-14 14:08:04 UTC (rev 7847)
@@ -1679,6 +1679,7 @@
  $(gdevplnx_h) $(gdevprn_h)\
  $(gscoord_h) $(gsdevice_h)\
  $(gxcldev_h) $(gxdevice_h) $(gxdevmem_h) $(gxgetbit_h) $(gxhttile_h)\
+ $(gsmemory_h) \
  $(stream_h) $(strimpl_h)
 	$(GLCC) $(GLO_)gxclread.$(OBJ) $(C_) $(GLSRC)gxclread.c
 



More information about the gs-cvs mailing list