[gs-bugs] [Bug 691995] Command line works, DLL does not

bugzilla-daemon at ghostscript.com bugzilla-daemon at ghostscript.com
Mon Feb 28 15:33:13 UTC 2011


Ken Sharp <ken.sharp at artifex.com> changed:

           What    |Removed                     |Added
             Status|NEW                         |RESOLVED
         Resolution|                            |INVALID

--- Comment #8 from Ken Sharp <ken.sharp at artifex.com> 2011-02-28 15:33:09 UTC ---
If we remove the exception handling (as I suggested) then we can see that GP
fault occurs in memmove called thus:

zflushfile             - flushing the warning message from the PDF interpreter

The buffer pointers are incorrect, resulting in a small negative read, which
ends up as a large positive read (unsigned longs). Not surprisingly this
quickly attempts to read from unassigned memory and causes a GPF.

So why do we get a small negative number ? In rfgsw.cpp there is a callback to
handle stderr and stdout:

int gsdll_callback(int message, char *str, unsigned long count)
   switch (message) {
      case GSDLL_STDIN:
         // We don't allow reading from stdin when running PostScript from
within the WorkServer,
         // so always return a 0 indicating EOF

      case GSDLL_STDOUT:
            if (str != (char *) NULL)
               fwrite(str, 1, count, stdout);

          //8/25/2010 KLS: add these two lines to fix RF-4608:
         if( (strstr(str, "Warning") != (char *) NULL) )


The culprit is the code with the comment '//8/25/2010 KLS: add these two lines
to fix RF-4608:'

The stream writing code expects to be told how much of the data has been
consumed, which is why the return value is normally 'count' (consumed all of
it). Returning 'GSDLL_INIT_QUIT' tells the stream code that 'GSDLL_INIT_QUIT'
(decimal 101, 0x65) bytes have been processed, which is not true. In this case
there were only 62 bytes (0x3e) available.

The problem is that this tells the stream code that more bytes were processed
than were actually available. In this particular case this causes the buffer
pointer to be moved past the end of the buffer. Later when we calculate how
much space remains in the buffer we subtract the pointer from the limit,
resulting in a negative number, and causing the crash.

I have no idea what 'RF-4608' is, but it seems to me that this code is clearly
incorrect, you can't tell the stream code that you read more bytes than it gave
you :-) I suppose we could have the stream code check the return value and
clamp it to the maximum of the supplied data. I'll leave that up to Ray if he
wants to do it. I assume the intention was to have this error code returned up
to the calling application, but I'm afraid there is no actual way to do that
from here.

Anyway, if I remove the two lines of code after the comment then the file runs
to completion and produces an apparently correct TIFF file.

I would recommend removing the _try and _except code around the initialisation
of Ghostscript, at least for development. This has been added (from the
comment) because initialisation was causing GPFs. While I understand a desire
to shield end users from crash dialogs, this only hides real problems when
developing and debugging. Also the message is somewhat misleading, it states
that an exception occurred during initialisation but in fact this call not only
initialises Ghostscript it runs the PostScript file too.

I would also, once again, draw attention to the Windows API call
'FormatMessage' which allows for a developer to print a meaningful error
message, rather than a cryptic number.

I believe this fixes the problem, so I'm going to close this as INVALID,
because Ghostscript is working as expected. Obviously if it doesn't fix the
problem in the customer's code then we'll need to reopen and think again.

Configure bugmail: http://bugs.ghostscript.com/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are the QA contact for the bug.

More information about the gs-bugs mailing list