Sophie

Sophie

distrib > Mageia > 9 > armv7hl > media > core-release-src > by-pkgid > d3fc76fe325ca661cb5adbf012153e1c > files > 12

ghostscript-10.00.0-6.mga9.src.rpm

From 8b72afb6e22a169be74e1e71331b1b661a72ea21 Mon Sep 17 00:00:00 2001
From: Ken Sharp <ken.sharp@artifex.com>
Date: Thu, 13 Oct 2022 14:54:23 +0100
Subject: [PATCH 148/155] GhostPDL + GS - do not make PS colour spaces into PDF
 ones

This was reported (out of Bugzilla) by Robin Watts, noticed in passing
while debugging a different problem. Using the bug file (bears.pdf)
from Bug #705975 and the following command line:

-r1500 -sDEVICE=tiffsep -o /temp/out.tif /temp/bears.pdf

if the output file out.tif cannot be written (read-only or held open by
another application) then this caused an error. On a Memento build on
Windows it causes a corrupted block on exit, on Linux it was giving a
warning about attempting to free an unknown PDF object type.

In all cases the error occurred during the PostScript end of job restore
when there should be no PDF objects and the PDF interpreter context had
been released.

The problem was due to colour spaces, when we create a colour space in
PDF we set a callback, called when a colour space is freed, which does
extra work specific to the PDF interpreter. However we were ending up
adding these callbacks to colour spaces allocated by the PostScript
interpreter.

This comes about because gs_setcolorspace() does not alter the current
colour space if we attempt to switch to the same space. So in this case
the current colour space in the PostScript interpreter was DeviceGray
and the PDF interpreter then set DeviceGray, which did not result in a
new colour space in the graphics state. But we went ahead and assigned
the colour callbacks assuming that it had. When we finally freed that
space we would then attempt to handle it as a PDF space, but the PDF
context had long gone, resulting in an error.

To fix this we now check the colour space after calling gs_setcolorspace
to see if it has changed. If it has not we do not assign the PDF colour
callbacks; either we have previously done so (if its a PDF space) or it
is a PostScript space and we absolutely do not want to set the callbacks.

Why does this not show up normally ? Because we do a showpage after
every page, which does an initgraphics, which resets the PostScript
colour space, and at this point the PDF context is still valid. In order
to get this problem we currently need 'showpage' to return an error.

But it is still wrong, much better to avoid the situation.
---
 pdf/pdf_colour.c | 49 ++++++++++++++++++++++++++++++++++++++++++------
 1 file changed, 43 insertions(+), 6 deletions(-)

diff --git a/pdf/pdf_colour.c b/pdf/pdf_colour.c
index 9c7e74910..a403d9bec 100644
--- a/pdf/pdf_colour.c
+++ b/pdf/pdf_colour.c
@@ -342,6 +342,7 @@ static void pdfi_cspace_free_callback(gs_memory_t * mem, void *cs)
 int pdfi_gs_setgray(pdf_context *ctx, double d)
 {
     int code = 0;
+    gs_color_space *pcs = ctx->pgs->color[0].color_space;
 
     /* PDF Reference 1.7 p423, any colour operators in a CharProc, following a d1, should be ignored */
     if (ctx->text.inside_CharProc && ctx->text.CharProc_d_type != pdf_type3_d0)
@@ -353,6 +354,11 @@ int pdfi_gs_setgray(pdf_context *ctx, double d)
         code = gs_setcolorspace(ctx->pgs, ctx->page.DefaultGray_cs);
         if (code < 0)
             return code;
+        /* If we didn't change the colour space in the graphics state, do not attempt to
+         * set the callbacks, the current space might be inherited from PostScript.
+         */
+        if (pcs != ctx->pgs->color[0].color_space)
+            pdfi_set_colour_callback(ctx->pgs->color[0].color_space, ctx, pdfi_cspace_free_callback);
         cc.paint.values[0] = d;
         cc.pattern = 0;
         return gs_setcolor(ctx->pgs, &cc);
@@ -361,13 +367,18 @@ int pdfi_gs_setgray(pdf_context *ctx, double d)
         if (code < 0)
             return code;
     }
-    pdfi_set_colour_callback(ctx->pgs->color[0].color_space, ctx, pdfi_cspace_free_callback);
+    /* If we didn't change the colour space in the graphics state, do not attempt to
+     * set the callbacks, the current space might be inherited from PostScript.
+     */
+    if (pcs != ctx->pgs->color[0].color_space)
+        pdfi_set_colour_callback(ctx->pgs->color[0].color_space, ctx, pdfi_cspace_free_callback);
     return 0;
 }
 
 int pdfi_gs_setrgbcolor(pdf_context *ctx, double r, double g, double b)
 {
     int code = 0;
+    gs_color_space *pcs = ctx->pgs->color[0].color_space;
 
     /* PDF Reference 1.7 p423, any colour operators in a CharProc, following a d1, should be ignored */
     if (ctx->text.inside_CharProc && ctx->text.CharProc_d_type != pdf_type3_d0)
@@ -379,7 +390,11 @@ int pdfi_gs_setrgbcolor(pdf_context *ctx, double r, double g, double b)
         code = gs_setcolorspace(ctx->pgs, ctx->page.DefaultRGB_cs);
         if (code < 0)
             return code;
-        pdfi_set_colour_callback(ctx->pgs->color[0].color_space, ctx, NULL);
+        /* If we didn't change the colour space in the graphics state, do not attempt to
+         * set the callbacks, the current space might be inherited from PostScript.
+         */
+        if (pcs != ctx->pgs->color[0].color_space)
+            pdfi_set_colour_callback(ctx->pgs->color[0].color_space, ctx, pdfi_cspace_free_callback);
         cc.paint.values[0] = r;
         cc.paint.values[1] = g;
         cc.paint.values[2] = b;
@@ -389,7 +404,11 @@ int pdfi_gs_setrgbcolor(pdf_context *ctx, double r, double g, double b)
         code = gs_setrgbcolor(ctx->pgs, r, g, b);
         if (code < 0)
             return code;
-        pdfi_set_colour_callback(ctx->pgs->color[0].color_space, ctx, pdfi_cspace_free_callback);
+        /* If we didn't change the colour space in the graphics state, do not attempt to
+         * set the callbacks, the current space might be inherited from PostScript.
+         */
+        if (pcs != ctx->pgs->color[0].color_space)
+            pdfi_set_colour_callback(ctx->pgs->color[0].color_space, ctx, pdfi_cspace_free_callback);
     }
     return 0;
 }
@@ -397,6 +416,7 @@ int pdfi_gs_setrgbcolor(pdf_context *ctx, double r, double g, double b)
 static int pdfi_gs_setcmykcolor(pdf_context *ctx, double c, double m, double y, double k)
 {
     int code = 0;
+    gs_color_space *pcs = ctx->pgs->color[0].color_space;
 
     /* PDF Reference 1.7 p423, any colour operators in a CharProc, following a d1, should be ignored */
     if (ctx->text.inside_CharProc && ctx->text.CharProc_d_type != pdf_type3_d0)
@@ -408,6 +428,11 @@ static int pdfi_gs_setcmykcolor(pdf_context *ctx, double c, double m, double y,
         code = gs_setcolorspace(ctx->pgs, ctx->page.DefaultCMYK_cs);
         if (code < 0)
             return code;
+        /* If we didn't change the colour space in the graphics state, do not attempt to
+         * set the callbacks, the current space might be inherited from PostScript.
+         */
+        if (pcs != ctx->pgs->color[0].color_space)
+            pdfi_set_colour_callback(ctx->pgs->color[0].color_space, ctx, pdfi_cspace_free_callback);
         cc.paint.values[0] = c;
         cc.paint.values[1] = m;
         cc.paint.values[2] = y;
@@ -418,13 +443,19 @@ static int pdfi_gs_setcmykcolor(pdf_context *ctx, double c, double m, double y,
         code = gs_setcmykcolor(ctx->pgs, c, m, y, k);
         if (code < 0)
             return code;
+        /* If we didn't change the colour space in the graphics state, do not attempt to
+         * set the callbacks, the current space might be inherited from PostScript.
+         */
+        if (pcs != ctx->pgs->color[0].color_space)
+            pdfi_set_colour_callback(ctx->pgs->color[0].color_space, ctx, pdfi_cspace_free_callback);
     }
-    pdfi_set_colour_callback(ctx->pgs->color[0].color_space, ctx, pdfi_cspace_free_callback);
     return 0;
 }
 
 int pdfi_gs_setcolorspace(pdf_context *ctx, gs_color_space *pcs)
 {
+    gs_color_space *old_pcs = ctx->pgs->color[0].color_space;
+    int code = 0;
     /* If the target colour space is already the current colour space, don't
      * bother to do anything.
      */
@@ -433,8 +464,14 @@ int pdfi_gs_setcolorspace(pdf_context *ctx, gs_color_space *pcs)
         if (ctx->text.inside_CharProc && ctx->text.CharProc_d_type != pdf_type3_d0)
             return 0;
 
-        pdfi_set_colour_callback(pcs, ctx, pdfi_cspace_free_callback);
-        return gs_setcolorspace(ctx->pgs, pcs);
+        code = gs_setcolorspace(ctx->pgs, pcs);
+        if (code < 0)
+            return code;
+        /* If we didn't change the colour space in the graphics state, do not attempt to
+         * set the callbacks, the current space might be inherited from PostScript.
+         */
+        if (old_pcs != ctx->pgs->color[0].color_space)
+            pdfi_set_colour_callback(ctx->pgs->color[0].color_space, ctx, pdfi_cspace_free_callback);
     }
     return 0;
 }
-- 
2.30.4