Fix for 686994 (dangling pdf14 pointers)
Raph Levien <[email protected]>
| Newsgroups | gmane.comp.printing.ghostscript.patches |
|---|---|
| Message-ID | <[email protected]> |
Fixes two pointers to freed objects that were left dangling
in the PDF 1.4 transparency logic. Fixes bug #686994.
DETAILS:
With some test files, saved graphics states had held on to pointers to
the device filter stack that had already been freed by a
gs_pop_device_filter() call. These dangling pointers can cause garbage
collection corruption. This patch introduces reference counting
discipline to these pointers so that the dfilter_stack objects are not
actually freed until the last reference is dropped.
A similar but simpler argument applies to the pdf14_ctx object in the
pdf14_device. This patch simply sets the pointer to NULL when freeing
the context.
---
I am committing this patch now so that we can see the results of
tonight's regression run. Test file ai2.pdf now runs correctly.
Raph
Index: src/gdevp14.c
===================================================================
RCS file: /cvs/ghostscript/gs/src/gdevp14.c,v
retrieving revision 1.18
diff -C2 -r1.18 gdevp14.c
*** src/gdevp14.c 23 Jul 2003 21:27:48 -0000 1.18
--- src/gdevp14.c 15 Aug 2003 22:13:29 -0000
***************
*** 933,938 ****
pdf14_device *pdev = (pdf14_device *)dev;
! if (pdev->ctx)
pdf14_ctx_free(pdev->ctx);
return 0;
}
--- 933,940 ----
pdf14_device *pdev = (pdf14_device *)dev;
! if (pdev->ctx) {
pdf14_ctx_free(pdev->ctx);
+ pdev->ctx = NULL;
+ }
return 0;
}
Index: src/gsstate.c
===================================================================
RCS file: /cvs/ghostscript/gs/src/gsstate.c,v
retrieving revision 1.20
diff -C2 -r1.20 gsstate.c
*** src/gsstate.c 17 Jun 2003 09:42:19 -0000 1.20
--- src/gsstate.c 15 Aug 2003 22:20:34 -0000
***************
*** 322,325 ****
--- 322,326 ----
*/
pnew->clip_stack = 0;
+ rc_increment(pnew->dfilter_stack);
pgs->saved = pnew;
if (pgs->show_gstate == pgs)
***************
*** 479,482 ****
--- 480,484 ----
pnew = gstate_clone(pgs, mem, "gs_gstate", copy_for_gstate);
rc_increment(pnew->clip_stack);
+ rc_increment(pnew->dfilter_stack);
pgs->view_clip = view_clip;
if (pnew == 0)
***************
*** 926,929 ****
--- 928,932 ----
rc_decrement(pgs->device, cname);
rc_decrement(pgs->clip_stack, cname);
+ rc_decrement(pgs->dfilter_stack, cname);
cs_adjust_counts(pgs, -1);
if (pgs->client_data != 0)
***************
*** 982,985 ****
--- 985,989 ----
RCCOPY(device);
RCCOPY(clip_stack);
+ RCCOPY(dfilter_stack);
{
struct gx_pattern_cache_s *pcache = pto->pattern_cache;
Index: src/gsdfilt.c
===================================================================
RCS file: /cvs/ghostscript/gs/src/gsdfilt.c,v
retrieving revision 1.7
diff -C2 -r1.7 gsdfilt.c
*** src/gsdfilt.c 7 Oct 2002 08:28:56 -0000 1.7
--- src/gsdfilt.c 15 Aug 2003 22:20:34 -0000
***************
*** 41,50 ****
#include "gsdfilt.h"
- struct gs_device_filter_stack_s {
- gs_device_filter_stack_t *next;
- gs_device_filter_t *df;
- gx_device *next_device;
- };
-
gs_private_st_ptrs3(st_gs_device_filter_stack, gs_device_filter_stack_t,
"gs_device_filter_stack",
--- 41,44 ----
***************
*** 77,80 ****
--- 71,75 ----
pgs->dfilter_stack = dfs;
dfs->df = df;
+ rc_init(dfs, mem, 1);
gs_setdevice_no_init(pgs, new_dev);
rc_decrement_only(new_dev, "gs_push_device_filter");
***************
*** 98,102 ****
gs_setdevice_no_init(pgs, dfs_tos->next_device);
rc_decrement_only(dfs_tos->next_device, "gs_pop_device_filter");
! gs_free_object(mem, dfs_tos, "gs_pop_device_filter");
code = df->postpop(df, mem, pgs, tos_device);
rc_decrement_only(tos_device, "gs_pop_device_filter");
--- 93,98 ----
gs_setdevice_no_init(pgs, dfs_tos->next_device);
rc_decrement_only(dfs_tos->next_device, "gs_pop_device_filter");
! dfs_tos->df = NULL;
! rc_decrement_only(dfs_tos, "gs_pop_device_filter");
code = df->postpop(df, mem, pgs, tos_device);
rc_decrement_only(tos_device, "gs_pop_device_filter");
Index: src/gsdfilt.h
===================================================================
RCS file: /cvs/ghostscript/gs/src/gsdfilt.h,v
retrieving revision 1.8
diff -C2 -r1.8 gsdfilt.h
*** src/gsdfilt.h 8 Oct 2002 23:02:31 -0000 1.8
--- src/gsdfilt.h 15 Aug 2003 22:20:34 -0000
***************
*** 37,42 ****
#endif
! /* This is the base structure from which device filters are derived. */
typedef struct gs_device_filter_s gs_device_filter_t;
struct gs_device_filter_s {
--- 37,44 ----
#endif
! #ifndef gs_device_filter_DEFINED
! # define gs_device_filter_DEFINED
typedef struct gs_device_filter_s gs_device_filter_t;
+ #endif
struct gs_device_filter_s {
Index: src/gzstate.h
===================================================================
RCS file: /cvs/ghostscript/gs/src/gzstate.h,v
retrieving revision 1.8
diff -C2 -r1.8 gzstate.h
*** src/gzstate.h 22 Aug 2002 07:12:29 -0000 1.8
--- src/gzstate.h 15 Aug 2003 22:20:34 -0000
***************
*** 63,66 ****
--- 63,84 ----
#endif
+ /* Device filter stack structure is defined here so that gstate
+ lifecycle operations can access reference count; implementation is
+ in gsdfilt.c.
+ */
+
+ #ifndef gs_device_filter_DEFINED
+ # define gs_device_filter_DEFINED
+ typedef struct gs_device_filter_s gs_device_filter_t;
+ #endif
+
+ /* This is the base structure from which device filters are derived. */
+ struct gs_device_filter_stack_s {
+ gs_device_filter_stack_t *next;
+ gs_device_filter_t *df;
+ gx_device *next_device;
+ rc_header rc;
+ };
+
/* Graphics state structure. */