Bug 689577 - Problem with some files with so build and stdin redirection -- Error: /undefined in eartomark
Problem with some files with so build and stdin redirection -- Error: /undefi...
Product: Ghostscript
Classification: Unclassified
Component: Client API
PC Linux
: P2 critical
Assigned To: Alex Cherepanov
Bug traffic
Depends on:
  Show dependency treegraph
Reported: 2007-11-27 12:45 PST by Marcos H. Woehrmann
Modified: 2014-02-17 04:40 PST (History)
2 users (show)

See Also:
Word Size: ---

d01785-001 (236.56 KB, application/octet-stream)
2007-11-27 12:45 PST, Marcos H. Woehrmann
simplified.ps (773 bytes, application/octet-stream)
2007-11-29 16:54 PST, Marcos H. Woehrmann
pdfteste-hack.ps (60.63 KB, application/postscript)
2009-05-07 04:46 PDT, Alex Cherepanov

Note You need to log in before you can comment on or make changes to this bug.
Description Marcos H. Woehrmann 2007-11-27 12:45:24 PST
This problem comes from the Ubuntu Ghostscript bug list:

I've done some work to isolate the problem and it appears that it only occurs
when all of the following are true:
1.  The input file is a Postscript file generated by Acrobat from an encrypted
PDF file (see attached for an example).
2.  Ghostscript is built as a library (i.e. "make so").
3.  The input file is sent to Ghostcript via "- <filename".

From my testing it appears that the current head (r8406) continues to have this

Here's how to duplicate the problem (on my Ubuntu 7.10 AMD64 box under tcsh, ymmv):

  make XCFLAGS="-fPIC" XLDFLAGS="-fPIC" so
  setenv LD_LIBRARY_PATH sobin
  sobin/gsc -sDEVICE=ppmraw -sOutputFile=test.ppm - <./d01785-001
Comment 1 Marcos H. Woehrmann 2007-11-27 12:45:49 PST
Created attachment 3583 [details]
Comment 2 Marcos H. Woehrmann 2007-11-27 12:55:58 PST
Bumping the priority since this bug effects a large number of users and has high
Comment 3 Till Kamppeter 2007-11-27 13:52:19 PST
Especially note that distros tend to the library version of Ghostscript, due to
my packaging work Ubuntu, Debian, and Mandriva use the library version already.
Some programs like GSView require the library. For printing the input files are
usually piped into Ghostscript (in most cases by foomatic-rip or pstoraster) and
acroread 8.1.1 ships also with most current distros. So the occurrence of the
problem is ievitable.
Comment 4 Till Kamppeter 2007-11-27 13:53:29 PST
A fix by a small patch is appreciated, as it can more easily be applied as an
update for a released Linux distribution than a new release of Ghostscript.
Comment 5 Ray Johnston 2007-11-27 17:12:33 PST
The problem happens after the code:

%ADOBeginClientInjection: DocumentSetup Start "No Re-Distill"
%% Removing the following eleven lines is illegal, subject to the Digital
Copyright Act of 1998.
mark currentfile eexec
%ADOEndClientInjection: DocumentSetup Start "No Re-Distill"

Apparently the 'cl' is getting swallowed by the eexec filter resulting in the
Error: /undefined in eartomark

Note that I was able to duplicate the problem on Windows with HEAD using:

cat bug_689577.ps | gswin32c -

Also on Windows, this works:   gswin32c bug_589577.ps

Comment 6 Ray Johnston 2007-11-27 17:26:18 PST
The encoded sequence converts to:


which displays as:

/currentdistillerparams where { pop /pdfmark where
{pop (This PostScript file was created from an encrypted PDF file.\n) print
(Redistilling encrypted PDF is not permitted.\n) print
userdict /quit get exec }if} if
currentfile closefile
&#9644;&#9830;ΗK&#9484;&#9600;&#8962;Jμηκ&&#8993;m t§Gλ     &#8804;&#9580;&#931;ϊξ«O

Comment 7 Marcos H. Woehrmann 2007-11-29 16:54:07 PST
Created attachment 3587 [details]

A much simplified test case that fails in the same way.,
Comment 8 Marcos H. Woehrmann 2007-11-30 06:59:41 PST
The problem appears to be the mem->gs_lib_ctx->stdin_is_interactive flag being
set incorrectly.  The following hack allows the file to be read, however this
likely breaks other things:

Index: ziodevsc.c
--- ziodevsc.c  (revision 8416)
+++ ziodevsc.c  (working copy)
@@ -99,7 +99,7 @@
     if (mem->gs_lib_ctx->stdin_fn)
        count = (*mem->gs_lib_ctx->stdin_fn)
            (mem->gs_lib_ctx->caller_handle, (char *)pw->ptr + 1,
-            mem->gs_lib_ctx->stdin_is_interactive ? 1 : wcount);
+            mem->gs_lib_ctx->stdin_is_interactive ? wcount : wcount);  /* mhw */
        count = gp_stdin_read((char *)pw->ptr + 1, wcount,

Comment 9 Marcos H. Woehrmann 2007-11-30 08:02:51 PST
More details:

The significant routine appears to be s_stdin_read_process() in ziodevsc.c:

/* Read from stdin into the buffer. */
/* If interactive, only read one character. */
static int
s_stdin_read_process(stream_state * st, stream_cursor_read * ignore_pr,
                     stream_cursor_write * pw, bool last)
    int wcount = (int)(pw->limit - pw->ptr);
    int count;
    gs_memory_t *mem = st->memory;

    if (wcount <= 0)
        return 0;

    /* do the callout */
    if (mem->gs_lib_ctx->stdin_fn)
        count = (*mem->gs_lib_ctx->stdin_fn)
            (mem->gs_lib_ctx->caller_handle, (char *)pw->ptr + 1,
             mem->gs_lib_ctx->stdin_is_interactive ? 1 : wcount);
        count = gp_stdin_read((char *)pw->ptr + 1, wcount,

    pw->ptr += (count < 0) ? 0 : count;
    return ((count < 0) ? ERRC : (count == 0) ? EOFC : count);

The difference between Ghostscript running as a shared library and as a
standalone problem when using "- <filename" is that when running as a program
the gp_stdin_read() routine is called to read stdin and it is passed
mem->gs_lib_ctx->stdin_is_interactive which it ignores:

/* Read bytes from stdin, unbuffered if possible. */
int gp_stdin_read(char *buf, int len, int interactive, FILE *f)
    return read(fileno(f), buf, len);

Whereas when Ghostscript is a library the call to read stdin is to gsdll_stdin()
(which is what *mem->gs_lib_ctx->stdin_fn is set to) and it doesn't take
mem->gs_lib_ctx->stdin_is_interactive as a parameter but instead is called with
wcount set to 1.

So my comment #8 is partially correct, mem->gs_lib_ctx->stdin_is_interactive
isn't set incorrectly, it's just ignored in the standalone case.

So the question is why does the shared library need to pay attention to the
stdin_is_interactive flag when the standalone program ignores it?  Does this
comment explain why (from imainarg.c):

        case 0:         /* read stdin as a file char-by-char */
            /* This is a ******HACK****** for Ghostview. */
            minst->heap->gs_lib_ctx->stdin_is_interactive = true;
            goto run_stdin;

Comment 10 Marcos H. Woehrmann 2007-12-04 10:00:35 PST
Based on Ray's suggestion I tested -_ instead of - to enable buffered reading
and it works.  This is a workaround, so I'll suggest this to Till but leave the
bug open.
Comment 11 Marcos H. Woehrmann 2007-12-04 21:34:14 PST
Here's a diff -c example of the hack from comment #10:

*** LaserJet-6MP-foomatic.ppd.old       Tue Dec  4 11:04:07 2007
--- LaserJet-6MP-foomatic.ppd   Tue Dec  4 11:13:52 2007
*** 95,101 ****
 *FoomaticIDs: HP-LaserJet_6MP hpijs
 *FoomaticRIPCommandLine: "gs -q -dBATCH -dPARANOIDSAFER -dQUIET -dNOPA&&
 USE -sDEVICE=ijs -sIjsServer=hpijs%A%B%C -dIjsUseOutputFD%Z -sOutputFi&&
! le=- -"

 *FoomaticRIPOption Model: enum CmdLine A 100
--- 95,101 ----
 *FoomaticIDs: HP-LaserJet_6MP hpijs
 *FoomaticRIPCommandLine: "gs -q -dBATCH -dPARANOIDSAFER -dQUIET -dNOPA&&
 USE -sDEVICE=ijs -sIjsServer=hpijs%A%B%C -dIjsUseOutputFD%Z -sOutputFi&&
! le=- -_"

 *FoomaticRIPOption Model: enum CmdLine A 100
Comment 12 Till Kamppeter 2007-12-06 04:29:31 PST
To not need to change all entries in the Foomatic database one by one, I have
simply modified the foomatic-gswrapper (the general Ghostscript problem
workaround layer of Foomatic) to replace any expression for stdin as the input
file for Ghostscript ny '-_'. Get the new version of the foomatic-gswrapper from


and replace your foomatic-gswrapper with it (usually in /usr/bin)

This makes all print queues with Foomatic-based PPDs (for example HP inkjets and
PCL lasers) printing correctly again.

If your printer uses a CUPS raster driver, the /usr/lib/cups/filter/pstoraster
needs to be patched. Replace the line




(line 54 in current version). I have done this in the Ghostscript SVN repository
as rev 8423.

If you are using a driver of Rick Richardson's foo2zjs suite
(http://foo2zjs.rkkda.com/, HP LaserJet 10xx, P10xx, M1005 MFP, Color LaserJet
1500, 1600, 2600n, Konica Minolta magicolor DL/MF series, Samsung CLP-300/600,
Xerox Phaser 6110, Lexmark C500n) run the following command as root to patch all
the Ghostscript wrapper scripts of foo2zjs:

perl -p -i -e 's/(GAMMAFILE )- /\1-_ /' /usr/bin/foo2*wrapper

I have applied all this in Ubuntu Hardy now.
Comment 13 Till Kamppeter 2007-12-07 10:56:16 PST
For foo2zjs the workaround was now applied upstream, too.
Comment 14 Till Kamppeter 2007-12-08 14:52:51 PST
A fix of this bug is really needed, as workarounds cannot be applied everywhere.
Especially the closed-source drivers from Samsung call Ghostscript (with "-" as
input) out of a closed-source executable. Here one cannot do quick workarounds
as I have shown in my previous comments. See also the complaint of the user
"lunomad" in the Ubuntu bug report.
Comment 15 Sammy Umar 2007-12-08 16:41:19 PST
Can we get a nod whether a fix for this in ghostscript is coming or not?
Many applications like kghostview and evince are failing as well. I made
a small fix for kghostview (replacing - with -_ in one location) but if
ghostscript is going to be fixed we will have to take all these out again.
It would be nice to know. Thanks.
Comment 16 Ray Johnston 2007-12-08 16:44:59 PST
Till wrote in the previous comment:
"A fix of this bug is really needed, as workarounds cannot be applied everywhere.
Especially the closed-source drivers from Samsung call Ghostscript (with "-" as
input) out of a closed-source executable."

Since GPL doesn't allow closed source (isn't being able to fix it yourself part
of the point of GPL), this looks like a violation of GPL and thus a violation
of Artifex's license of Ghostscript under GPL. I'm not a lawyer, but I will
forward this to the appropriate people at Artifex Software.


As far as fixing the bug, it's still open and will get fixed.
Comment 17 Ray Johnston 2007-12-08 16:50:38 PST
A comment on needing to take out the '-_' ...

The '-' assumes that the input needs to be interactive and shouldn't be
buffered (needs to read 1 character at a time). The '-_' uses larger buffers from
stdin and so it generally is more efficient anyway.
Comment 18 Marcos H. Woehrmann 2007-12-08 19:25:36 PST
I have a couple of suggestions as to how we can fix this without having to delve
into the atream code:

1.  Replace /usr/bin/gs with the standalone gs instead of the stub that calls
the library.

2.  Have the /usr/bin/gs stub scan the command line and replace '-' with '-_'
before calling the library Ghostscript.  

Both to these shouldn't break any existing code.  Since the standalone
Ghostscript has always had '-' mean buffered input anyone calling /usr/bin/gs
shouldn't be expecting anything else.
Comment 19 Alex Cherepanov 2007-12-08 22:40:52 PST
A patch that reduces the buffer in eexecDecode filter has been committed
as a rev. 8428. See:

Regression testing shows no differences.

The sample file is incorrect. It has to few 0's than specified in
PLRM. The affected fragment is inserted into PS files generated by
Adobe Acrobat from PDF files with usage restrictions. So the fragment
doesn't change between files and the proposed solution should be
robust enough.

The buffer size of 132 has been selected from a middle of small window that
fixes the bug but doesn't cause regression in comparefiles/fonttest.pdf.
Detection of EOF after seeing a run of 0's is worth to note as an alternative.

Comment 20 Sammy Umar 2007-12-09 08:45:59 PST
Should one keep the previous changes to cups etc. that replace - with -_ ?
Comment 21 Till Kamppeter 2007-12-09 09:27:53 PST
An addition to my comment #14: A possible workaround is to replace Samsung's
closed-source driver ny the open-source driver SpliX, which supports most not
too old Samsung printers. From Samsung's driver use only the scanner driver if
you have an MF device. The SpliX driver (see http://www.openprinting.org/) is a
pure CUPS Raster driver which does not call Ghostscript by itself, my
workarounds from comment #12 are sufficient.

About comment #16: There is no GPL violation. Samsung's drivers are not
published under the GPL.

About comment #17: I will keep all my workarounds in place, not only because it
takes time until everyone will have a fixed Ghostscript but also as buffered
input is better for the performance.

About comment #18: The suggestion (2) can be implemented easily: Replace your
/usr/bin/foomatic-gswrapper by the newest one from


Rename /usr/bin/gs to /usr/bin/gs.orig and rename /usr/bin/foomatic-gswrapper to
/usr/bin/gs. Then edit /usr/bin/gs replacing 'my $gspath = "gs";' by 'my $gspath
= "gs.orig";'. Now every call of "gs", including calls by pstoraster and by
closed-source drivers, has all workarounds and fixes from foomatic-gswrapper
applied, especially the "-_" as input file.

About comment #19: As the fix is a really simple patch, I recommend to every
distro package maintainer to apply this patch without waiting for the next
official release of Ghostscript, and even apply this patch as an update for
already released versions of the distros.

Here is the patch:

Modified: trunk/gs/src/seexec.c
--- trunk/gs/src/seexec.c 2007-12-08 13:57:53 UTC (rev 8427)
+++ trunk/gs/src/seexec.c 2007-12-09 06:33:00 UTC (rev 8428)
@@ -215,8 +215,10 @@
  * so that it will stay under the limit even after adding min_in_size
  * for a subsequent filter in a pipeline. Note that we have to specify
  * a size of at least 128 so that filter_read won't round it up.
+ * The value of 132 is small enough for the sample file of the bug 689577 but
+ * still sufficient for comparefiles/fonttest.pdf .
 const stream_template s_exD_template = {
- &st_exD_state, s_exD_init, s_exD_process, 8, 200,
+ &st_exD_state, s_exD_init, s_exD_process, 8, 132,
     NULL, s_exD_set_defaults

Comment 22 Till Kamppeter 2007-12-09 09:30:01 PST
Sammy, I recommend to keep the workarounds in place as buffered input improves
the performance.
Comment 23 Gustavo Homem 2009-05-06 15:38:46 PDT
Although the 200 -> 132 patch solves the problem for simplified.ps I have a PDF
for which the problem is not solved.

We get

"Error: /undefined in ec"

I can send the file privately.
Comment 24 Gustavo Homem 2009-05-06 15:39:56 PDT
This bug did not exist in ghostscript 8.15-22.
Comment 25 Alex Cherepanov 2009-05-07 04:46:56 PDT
Created attachment 5002 [details]

Reduced PS file that has Adobe startup code only. The file displays blank page.

The bug can be reproduced by:
  gswin32c - <pdfteste-hack.ps
Comment 26 Gustavo Homem 2009-07-02 07:52:52 PDT
Seems that this problem applies to all PDFs with "security restrictions" (even
if printed is not restricted).

The bug is present on ghostscript 8.60-55 but not on (for example) 8.15-22 and

Is this expected to be fixed inside ghostscript?
Comment 27 Masaki Ushizaka 2009-08-11 01:10:52 PDT
Reproduced pdfteste-hack.ps from #25 with r9948 on both Windows XP Pro SP3 + VS2008 Express and 
Windows 2000 Pro SP4 + VS6 SP6.  Did not reproduce on Mac OS X.  Looks like windows only problem.
Replacing '-' with '-_' removes error, this can be used as a workaround.
Comment 28 Masaki Ushizaka 2009-08-11 04:44:09 PDT
My mistake.  Please forget 'Did not reproduce on Mac OS X.  Looks like windows only problem.' part in 
above my comment.  I didn't try it using shared object.
Comment 29 Alex Cherepanov 2009-08-13 12:08:58 PDT
In hex form of eexec stream, break out of reading loop and try to interpret
the accumulated data when a whitespace character is encountered. Skip whitespace
characters when the control returns to /eexecDecode filter.

Normally, eexec stream is followed by a large number of 0's to compensate
for read-ahead effects. The code fragment that Adobe Acrobat uses to prevent
re-distilling of the file has no trailing 0's at all. This patch tries to guess
the end of eexec stream after every whitespace character.

The following patch has been committed as a rev. 9989.
Regression testing shows no differences.