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

ken at ghostscript.com ken at ghostscript.com
Fri Dec 21 02:31:00 PST 2007


Author: ken
Date: 2007-12-21 02:31:00 -0800 (Fri, 21 Dec 2007)
New Revision: 8456

Modified:
   trunk/gs/src/sjbig2.c
   trunk/gs/src/sjbig2.h
   trunk/gs/src/sjbig2_luratech.c
   trunk/gs/src/sjbig2_luratech.h
   trunk/gs/src/zfjbig2.c
Log:
Fix (jbig2dec): The global data stream for a JBIG2 image in a PDF
file was being released, and the data freed by the garbage collector,
before the data was used.

Details: Bug #689568 and #689569. Uses the patch supplied by Alex
in thread for #689569, implements Ralph's comments about the structure 
naming. Does not attempt to change the memory allocator. This slightly
modified patch also works with the Luratech decoder.

sjbig2.h, sjbig2_luratech.h; make the global data structure 
s_jbig2_global_data_t public. Store the structure in the 
stream decoder state.

sjbig2.c, sjbig2_luratech.c; store a pointer to the global
data structure. 

sjbig2_luratech.c; don't reset the pointer during initialisation!

zfjbig2.c; Pass the global pointer to the stream decoder for
release in the finalize routine.

EXPECTED DIFFERENCES:
None.


Modified: trunk/gs/src/sjbig2.c
===================================================================
--- trunk/gs/src/sjbig2.c	2007-12-21 00:15:53 UTC (rev 8455)
+++ trunk/gs/src/sjbig2.c	2007-12-21 10:31:00 UTC (rev 8456)
@@ -132,10 +132,11 @@
 
 /* store a global ctx pointer in our state structure */
 int
-s_jbig2decode_set_global_data(stream_state *ss, void *data)
+s_jbig2decode_set_global_data(stream_state *ss, s_jbig2_global_data_t *gd)
 {
     stream_jbig2decode_state *state = (stream_jbig2decode_state*)ss;
-    state->global_ctx = (Jbig2GlobalCtx*)data;
+    state->global_struct = gd;
+    state->global_ctx = (Jbig2GlobalCtx*)(gd ? gd->data : 0);
     return 0;
 }
 
@@ -235,6 +236,7 @@
     stream_jbig2decode_state *const state = (stream_jbig2decode_state *) ss;
     
     /* state->global_ctx is not owned by us */
+    state->global_struct = NULL;
     state->global_ctx = NULL;
     state->decode_ctx = NULL;
     state->image = NULL;

Modified: trunk/gs/src/sjbig2.h
===================================================================
--- trunk/gs/src/sjbig2.h	2007-12-21 00:15:53 UTC (rev 8455)
+++ trunk/gs/src/sjbig2.h	2007-12-21 10:31:00 UTC (rev 8456)
@@ -22,10 +22,16 @@
 #include "scommon.h"
 #include <jbig2.h>
 
+/* See zfjbig2.c for details. */
+typedef struct s_jbig2_global_data_s {
+	void *data;
+} s_jbig2_global_data_t;
+
 /* JBIG2Decode internal stream state */
 typedef struct stream_jbig2decode_state_s
 {
-    stream_state_common;	/* a define from scommon.h */
+    stream_state_common; /* a define from scommon.h */
+    s_jbig2_global_data_t *global_struct; /* to protect it from freeing by GC */
     Jbig2GlobalCtx *global_ctx;
     Jbig2Ctx *decode_ctx;
     Jbig2Image *image;
@@ -35,15 +41,16 @@
 stream_jbig2decode_state;
 
 #define private_st_jbig2decode_state()	\
-  gs_private_st_simple(st_jbig2decode_state, stream_jbig2decode_state,\
-    "jbig2decode filter state")
+  gs_private_st_ptrs1(st_jbig2decode_state, stream_jbig2decode_state,\
+    "jbig2decode filter state", jbig2decode_state_enum_ptrs,\
+     jbig2decode_state_reloc_ptrs, global_struct)
 extern const stream_template s_jbig2decode_template;
 
 /* call ins to process the JBIG2Globals parameter */
 int
 s_jbig2decode_make_global_data(byte *data, uint length, void **result);
 int
-s_jbig2decode_set_global_data(stream_state *ss, void *data);
+s_jbig2decode_set_global_data(stream_state *ss, s_jbig2_global_data_t *gd);
 void
 s_jbig2decode_free_global_data(void *data);
 	

Modified: trunk/gs/src/sjbig2_luratech.c
===================================================================
--- trunk/gs/src/sjbig2_luratech.c	2007-12-21 00:15:53 UTC (rev 8455)
+++ trunk/gs/src/sjbig2_luratech.c	2007-12-21 10:31:00 UTC (rev 8456)
@@ -94,23 +94,22 @@
 
 /* store a global ctx pointer in our state structure */
 int
-s_jbig2decode_set_global_data(stream_state *ss, void *data)
+s_jbig2decode_set_global_data(stream_state *ss, s_jbig2_global_data_t *gs)
 {
     stream_jbig2decode_state *state = (stream_jbig2decode_state*)ss;
-    s_jbig2decode_global_data *global = (s_jbig2decode_global_data*)data;
+    if (state == NULL)
+        return gs_error_VMerror;
+    
+    state->global_struct = gs;
+    if (gs != NULL) {
+        s_jbig2decode_global_data *global = (s_jbig2decode_global_data*)(gs->data);
 
-    if (state != NULL) {
-      if (global != NULL) {
         state->global_data = global->data;
         state->global_size = global->size;
-        return 0;
-      } else {
-	state->global_data = NULL;
-	state->global_size = 0;
-	return 0;
-      }
+    } else {
+        state->global_data = NULL;
+        state->global_size = 0;
     }
-    
     return gs_error_VMerror;
 }
 

Modified: trunk/gs/src/sjbig2_luratech.h
===================================================================
--- trunk/gs/src/sjbig2_luratech.h	2007-12-21 00:15:53 UTC (rev 8455)
+++ trunk/gs/src/sjbig2_luratech.h	2007-12-21 10:31:00 UTC (rev 8456)
@@ -21,11 +21,17 @@
 #include "scommon.h"
 #include <ldf_jb2.h>
 
+/* See zfjbig2.c for details. */
+typedef struct s_jbig2_global_data_s {
+	void *data;
+} s_jbig2_global_data_t;
+
 /* JBIG2Decode internal stream state */
 typedef struct stream_jbig2decode_state_s
 {
     stream_state_common;	/* inherit base object from scommon.h */
     JB2_Handle_Document doc;	/* Luratech JBIG2 codec context */
+    s_jbig2_global_data_t *global_struct; /* to protect it from freeing by GC */
     unsigned char *global_data;
     unsigned long global_size;
     unsigned char *inbuf;  /* compressed image data */
@@ -39,15 +45,16 @@
 stream_jbig2decode_state;
 
 #define private_st_jbig2decode_state()	\
-  gs_private_st_simple(st_jbig2decode_state, stream_jbig2decode_state,\
-    "jbig2decode filter state")
+  gs_private_st_ptrs1(st_jbig2decode_state, stream_jbig2decode_state,\
+    "jbig2decode filter state", jbig2decode_state_enum_ptrs,\
+     jbig2decode_state_reloc_ptrs, global_struct)
 extern const stream_template s_jbig2decode_template;
 
 /* call in to process the JBIG2Globals parameter */
 int
 s_jbig2decode_make_global_data(byte *data, uint size, void **result);
 int
-s_jbig2decode_set_global_data(stream_state *ss, void *data);
+s_jbig2decode_set_global_data(stream_state *ss, s_jbig2_global_data_t *gs);
 void
 s_jbig2decode_free_global_data(void *data);
 

Modified: trunk/gs/src/zfjbig2.c
===================================================================
--- trunk/gs/src/zfjbig2.c	2007-12-21 00:15:53 UTC (rev 8455)
+++ trunk/gs/src/zfjbig2.c	2007-12-21 10:31:00 UTC (rev 8456)
@@ -35,7 +35,8 @@
 #include "sjbig2.h"
 #endif
 
-/* We define a structure, allocated in the postscript
+/* We define a structure, s_jbig2_global_data_t, 
+   allocated in the postscript
    memory space, to hold a pointer to the global decoder
    context (which is allocated by libjbig2). This allows
    us to pass the reference through postscript code to
@@ -44,12 +45,8 @@
    a finalize method to deallocate it when the reference
    is no longer in use. */
    
-typedef struct jbig2_global_data_s {
-	void *data;
-} jbig2_global_data_t;
-
 static void jbig2_global_data_finalize(void *vptr);
-gs_private_st_simple_final(st_jbig2_global_data_t, jbig2_global_data_t,
+gs_private_st_simple_final(st_jbig2_global_data_t, s_jbig2_global_data_t,
 	"jbig2globaldata", jbig2_global_data_finalize);
 
 
@@ -60,7 +57,7 @@
 {
     os_ptr op = osp;
     ref *sop = NULL;
-    jbig2_global_data_t *gref;
+    s_jbig2_global_data_t *gref;
     stream_jbig2decode_state state;
 
     /* Extract the global context reference, if any, from the parameter
@@ -74,8 +71,8 @@
     if (r_has_type(op, t_dictionary)) {
         check_dict_read(*op);
         if ( dict_find_string(op, ".jbig2globalctx", &sop) > 0) {
-	    gref = r_ptr(sop, jbig2_global_data_t);
-	    s_jbig2decode_set_global_data((stream_state*)&state, gref->data);
+	    gref = r_ptr(sop, s_jbig2_global_data_t);
+	    s_jbig2decode_set_global_data((stream_state*)&state, gref);
         }
     }
     	
@@ -98,7 +95,7 @@
 z_jbig2makeglobalctx(i_ctx_t * i_ctx_p)
 {
 	void *global = NULL;
-	jbig2_global_data_t *st;
+	s_jbig2_global_data_t *st;
 	os_ptr op = osp;
 	byte *data;
 	int size;
@@ -115,7 +112,7 @@
 	    return_error(e_unknownerror);
 	}
 	
-	st = ialloc_struct(jbig2_global_data_t, 
+	st = ialloc_struct(s_jbig2_global_data_t, 
 		&st_jbig2_global_data_t,
 		"jbig2decode parsed global context");
 	if (st == NULL) return_error(e_VMerror);
@@ -129,7 +126,7 @@
 /* free our referenced global context data */
 static void jbig2_global_data_finalize(void *vptr)
 {
-	jbig2_global_data_t *st = vptr;
+	s_jbig2_global_data_t *st = vptr;
 	
 	if (st->data) s_jbig2decode_free_global_data(st->data);
 	st->data = NULL;



More information about the gs-cvs mailing list