[gs-cvs] rev 8901 - trunk/gs/src
alexcher at ghostscript.com
alexcher at ghostscript.com
Tue Jul 29 12:11:31 PDT 2008
Author: alexcher
Date: 2008-07-29 12:11:31 -0700 (Tue, 29 Jul 2008)
New Revision: 8901
Modified:
trunk/gs/src/zcontrol.c
Log:
Add support to NULL pointers in t_structs or t_astructs objects to execstack
operator. Thanks to Ken for the analysis. Bug 689535.
DETAILS:
The issue is to do with devices handling patterns as high-level objects, which
is why it affects pdfwrite (which can handle patterns itself) but not regular
rendering. In zpcolor.c, pattern_paint_prepare(), there are two control paths,
one for devices which handle patterns as high-level objects, and one for
devices which don't. If the device can't handle high level objects, we install
a pattern accumulation device.
In this case, the flag internal_accum is set, we create the pattern accumulator
device and open it:
if (internal_accum) {
gs_memory_t *storage_memory = gstate_pattern_cache(pgs)->memory;
pdev = gx_pattern_accum_alloc(imemory, storage_memory, pinst,
"pattern_paint_prepare");
if (pdev == 0)
return_error(e_VMerror);
code = (*dev_proc(pdev, open_device)) ((gx_device *) pdev);
...
...
}
Later the two control paths rejoin and we put some objects on the execution
stack:
push_mark_estack(es_other, pattern_paint_cleanup);
++esp;
make_istruct(esp, 0, pdev);
Now notice that we construct the structure on esp using pdev, but we *don't*
create pdev if we can handle patterns, so its left as NULL and we end up
pushing an empty t_struct.
Leo's question in comment 10 is whether this is legal, the answer appears to be
yes, but its debatable.
In pattern_paint_finish we do this:
gx_device_forward *pdev = r_ptr(esp - 1, gx_device_forward);
if (pdev != NULL) {
gx_color_tile *ctile;
int code = gx_pattern_cache_add_entry((gs_imager_state *)igs,
pdev, &ctile);
That is, if the structure *isn't* NULL we do something with it, we ignore it if
it is NULL. Either way we then do this:
esp -= 3;
Removing all the objects from the execution stack that we added. Notice that
the structure we pushed onto the execution stack isn't actually 'executed', its
just data used by the pattern handler.
Now, all this works just fine in normal practice, however the job here uses a
CIEBased colour space, and being from an Adobe application it tries to set the
ColorRendering. Since we don't implement a ColorRendering resource category,
this causes an error (handled in a stopped context).
The default error handler uses execstack, and this is where the actual error
finally occurs, because execstack can't handle the empty structure.
DIFFERENCES:
None
Modified: trunk/gs/src/zcontrol.c
===================================================================
--- trunk/gs/src/zcontrol.c 2008-07-29 18:42:29 UTC (rev 8900)
+++ trunk/gs/src/zcontrol.c 2008-07-29 19:11:31 UTC (rev 8901)
@@ -816,9 +816,10 @@
}
case t_struct:
case t_astruct: {
- const char *tname =
+ const char *tname = rq->value.pstruct ?
gs_struct_type_name_string(
- gs_object_type(imemory, rq->value.pstruct));
+ gs_object_type(imemory, rq->value.pstruct))
+ : "NULL";
make_const_string(rq, a_readonly | avm_foreign,
strlen(tname), (const byte *)tname);
More information about the gs-cvs
mailing list