diff options
author | Robin Watts <robin.watts@artifex.com> | 2011-12-06 19:20:28 +0000 |
---|---|---|
committer | Robin Watts <robin.watts@artifex.com> | 2011-12-06 19:20:28 +0000 |
commit | 9335aeee4aab3e7454c827fc3a327437dec85637 (patch) | |
tree | 9fa671323ab651afd6b1d8618c9ab96e56b7533d /gs/base/gxpath.h | |
parent | a7b85f9823b1a1dea1530716a3e2fb3dd2f75c9c (diff) | |
download | ghostpdl-9335aeee4aab3e7454c827fc3a327437dec85637.tar.gz |
Bug 692526: Partial fix (clipping path initialisation)
Ghostscript paths have a 'local_segments' structure inside them
enabling them to be allocated entirely on the stack. Clipping
paths contain paths, so have the same structure. When a new
clipping path is initialised on the stack, it can share the
segments from an existing clipping path.
If this existing clipping path is on the stack, and 'goes away'
(due to garbage collection etc) the new clipping path can be left
holding pointers to invalid data. As such there is code in the gs
lib to detect that a clipping path is being asked to share
segments from another stack allocated clipping path, and to refuse.
The file referenced in the bug runs into exactly this situation.
It is however entirely safe, as the lifespan of the second clipping
path is 'nested' safely within the lifespan of the original.
I have therefore introduced another function that allows the
initialisation to be done as long as the caller guarantees that it
is safely nested.
This is sufficient to avoid the warning messages, and the file now
runs to completion successfully.
So why is this only a partial fix?
The original code refuses to initialise the clip path, and returns
a (negative) error code. This is caught by the calling code and
various things are not done. Later, a compositor comes to be shut
down, and pdf14_compose_group is called.
This finds that maskbuf != NULL, but maskbuf->transfer_fn == NULL.
This leads to a SEGV.
Something (presumably in the cleanup code that should be handling
the error) is leaving the compositor in an unexpected state however.
The code change here stops the error return code, so the cleanup code
is not called, and the regression is fixed. It leaves the broken
cleanup code in there though - I'll leave the bug open until this is
fixed.
Diffstat (limited to 'gs/base/gxpath.h')
-rw-r--r-- | gs/base/gxpath.h | 9 |
1 files changed, 9 insertions, 0 deletions
diff --git a/gs/base/gxpath.h b/gs/base/gxpath.h index e4985611d..b8dedafd7 100644 --- a/gs/base/gxpath.h +++ b/gs/base/gxpath.h @@ -317,6 +317,15 @@ int gx_cpath_init_contained_shared(gx_clip_path * pcpath, int gx_cpath_init_local_shared(gx_clip_path * pcpath, const gx_clip_path * shared, gs_memory_t * mem); +/* Function that informs us that the usage of this cpath will be + * safely nested within the existence of the 'shared' one. i.e. + * we don't need to worry that the shared one may go away while + * we contain pointers to it. + */ +int gx_cpath_init_local_shared_nested(gx_clip_path * pcpath, + const gx_clip_path * shared, + gs_memory_t * mem, + bool safely_nested); #define gx_cpath_init_local(pcpath, mem)\ (void)gx_cpath_init_local_shared(pcpath, NULL, mem) /* can't fail */ |