[gs-commits] ghostpdl branch, gs9.28, updated. ghostpdl-9.28rc4

[email protected] (Chris Liddell) Mon, 30 Sep 2019 07:33:59 +0000 (UTC)
Newsgroups gmane.comp.printing.ghostscript.cvs
Message-ID <[email protected]>
The ghostpdl branch, gs9.28 has been updated
       via  8f6060acadcbf365a67b1c48d5f1dd1228c2adab (commit)
       via  b0574cdb5b427690ac8d95679930c9f6cc1bdffb (commit)
       via  cce67ebf4c209ae3cbcc671e944596c64a3d7fc9 (commit)
       via  24c9f7f4a8d3e85e572094b4aedddbeeb02d5ef1 (commit)
       via  c40963eb024265ab28f4f897401ad7a050ca9425 (commit)
       via  7d70bd4338291c99234dd0078b5cdc85178c0540 (commit)
       via  2f713b99e1a626ba4b7b1be8cc715043bb4e0f0a (commit)
       via  31df729a821d1683381493b96c2ecced9da1e5e2 (commit)
       via  ca553d6d3ec0fa1455cf400629e08db90658aa85 (commit)
       via  205e2f529e6da569ec764ebb4aeddc41c66a8860 (commit)
       via  dd19ec5348723a5c70ff728911f856caa518166b (commit)
       via  da7486fc4b00eee956200d45fb340dc62c8e3bcb (commit)
       via  0222263e4fe03b29e9eb4141f7866fa8261d416a (commit)
       via  0e7039d7a83a7e35b8b41d59d7fb9a8b4fda7fb0 (commit)
       via  18316aba11fafc57ee77dbd7774b2c88b964a9d9 (commit)
      from  569a551f2a57f6e6c1e692f6b834c765dcbe7cfa (commit)

----------------------------------------------------------------------
commit 8f6060acadcbf365a67b1c48d5f1dd1228c2adab
Author: Chris Liddell <[email protected]>
Date:   Mon Sep 30 08:33:08 2019 +0100

    Dates and docs for 9.28 rc4

diff --git a/base/gscdefs.h b/base/gscdefs.h
index 95eb831..aea4514 100644
--- a/base/gscdefs.h
+++ b/base/gscdefs.h
@@ -37,7 +37,7 @@
 
 #ifndef GS_PRODUCT
 #  define GS_PRODUCT\
-        GS_PRODUCTFAMILY " RELEASE CANDIDATE 3"
+        GS_PRODUCTFAMILY " RELEASE CANDIDATE 4"
 #endif
 
 /* Prototypes for configuration definitions in gconfig.c. */
diff --git a/base/version.mak b/base/version.mak
index 54ce9be..f2d21a0 100644
--- a/base/version.mak
+++ b/base/version.mak
@@ -18,7 +18,7 @@ GS_VERSION_MAJOR=9
 GS_VERSION_MINOR=28
 GS_VERSION_MINOR0=28
 # Revision date: year x 10000 + month x 100 + day.
-GS_REVISIONDATE=20190918
+GS_REVISIONDATE=20190930
 # Derived values
 GS_VERSION=$(GS_VERSION_MAJOR)$(GS_VERSION_MINOR0)
 GS_DOT_VERSION=$(GS_VERSION_MAJOR).$(GS_VERSION_MINOR0)
diff --git a/doc/DLL.htm b/doc/DLL.htm
index 9465ad2..f1ee60b 100644
--- a/doc/DLL.htm
+++ b/doc/DLL.htm
@@ -776,7 +776,7 @@ or contact Artifex Software, Inc.,  1305 Grant Avenue - Suite 200,
 Novato, CA 94945, U.S.A., +1(415)492-9861, for further information.
 
 <p>
-<small>Ghostscript version 9.28, 18 September 2019
+<small>Ghostscript version 9.28, 30 September 2019
 
 <!-- [3.0 end visible trailer] ============================================= -->
 
diff --git a/doc/Deprecated.htm b/doc/Deprecated.htm
index cecb9d3..bcd1704 100644
--- a/doc/Deprecated.htm
+++ b/doc/Deprecated.htm
@@ -5773,7 +5773,7 @@ or contact Artifex Software, Inc.,  1305 Grant Avenue - Suite 200,
 Novato, CA 94945, U.S.A., +1(415)492-9861, for further information.
 
 <p>
-<small>Ghostscript version 9.28, 18 September 2019
+<small>Ghostscript version 9.28, 30 September 2019
 
 <!-- [3.0 end visible trailer] ============================================= -->
 
diff --git a/doc/Develop.htm b/doc/Develop.htm
index 425238c..2e39c3b 100644
--- a/doc/Develop.htm
+++ b/doc/Develop.htm
@@ -4773,7 +4773,7 @@ or contact Artifex Software, Inc.,  1305 Grant Avenue - Suite 200,
 Novato, CA 94945, U.S.A., +1(415)492-9861, for further information.
 
 <p>
-<small>Ghostscript version 9.28, 18 September 2019
+<small>Ghostscript version 9.28, 30 September 2019
 
 <!-- [3.0 end visible trailer] ============================================= -->
 
diff --git a/doc/Devices.htm b/doc/Devices.htm
index 8c97096..ba68079 100644
--- a/doc/Devices.htm
+++ b/doc/Devices.htm
@@ -2015,7 +2015,7 @@ or contact Artifex Software, Inc.,  1305 Grant Avenue - Suite 200,
 Novato, CA 94945, U.S.A., +1(415)492-9861, for further information.
 
 <p>
-<small>Ghostscript version 9.28, 18 September 2019
+<small>Ghostscript version 9.28, 30 September 2019
 
 <!-- [3.0 end visible trailer] ============================================= -->
 
diff --git a/doc/Drivers.htm b/doc/Drivers.htm
index 08cb3e4..c8df2ed 100644
--- a/doc/Drivers.htm
+++ b/doc/Drivers.htm
@@ -3678,7 +3678,7 @@ or contact Artifex Software, Inc.,  1305 Grant Avenue - Suite 200,
 Novato, CA 94945, U.S.A., +1(415)492-9861, for further information.
 
 <p>
-<small>Ghostscript version 9.28, 18 September 2019
+<small>Ghostscript version 9.28, 30 September 2019
 
 <!-- [3.0 end visible trailer] ============================================= -->
 
diff --git a/doc/Fonts.htm b/doc/Fonts.htm
index 946d60f..b37b6b7 100644
--- a/doc/Fonts.htm
+++ b/doc/Fonts.htm
@@ -357,7 +357,7 @@ or contact Artifex Software, Inc.,  1305 Grant Avenue - Suite 200,
 Novato, CA 94945, U.S.A., +1(415)492-9861, for further information.
 
 <p>
-<small>Ghostscript version 9.28, 18 September 2019
+<small>Ghostscript version 9.28, 30 September 2019
 
 <!-- [3.0 end visible trailer] ============================================= -->
 
diff --git a/doc/History9.htm b/doc/History9.htm
index 08369ed..a859a54 100644
--- a/doc/History9.htm
+++ b/doc/History9.htm
@@ -79,7 +79,7 @@ TOC to see how to edit it for visual conciseness.
 <h2>Table of contents</h2>
 
 <blockquote><ul>
-<li><a href="#Version9.28">Version 9.28 (2019-09-18)</a>
+<li><a href="#Version9.28">Version 9.28 (2019-09-30)</a>
 <li><a href="#Version9.27">Version 9.27 (2019-04-03)</a>
 <li><a href="#Version9.26">Version 9.26 (2018-11-20)</a>
 <li><a href="#Version9.25">Version 9.25 (2018-09-13)</a>
@@ -133,7 +133,7 @@ overview</a>.
 <!-- [1.0 end visible header] ============================================== -->
 
 <!-- [2.0 begin contents] ================================================== -->
-<h2><a name="Version9.28"></a>Version 9.28 (2019-09-18)</h2>
+<h2><a name="Version9.28"></a>Version 9.28 (2019-09-30)</h2>
 <p> Highlights in this release include:
 <ul>
 <li>
@@ -200,7 +200,254 @@ at <a href="https://www.mupdf.com">MuPDF</a>.
 </li>
 </ul>
 <h3><a name="9.28_changelog"></a>Changelog</h3>
-
+<p><strong>2019-09-27 13:26:01 +0100
+</strong>
+<br>Chris Liddell &lt;[email protected]&gt;<br>
+<a href="http://git.ghostscript.com/?p=ghostpdl.git;a=commitdiff;h=b0574cdb5b427690ac8d95679930c9f6cc1bdffb">b0574cdb5b427690ac8d95679930c9f6cc1bdffb</a>
+<blockquote>
+<p>
+    Bug 701634: Correctly handle file name of &quot;\0&quot;<br>
+<br>
+    Attempting to open a file with a filename string starting with a NULL<br>
+    character should be treated the same as if the string was zero length.<br>
+<br>
+    Not doing so created a broken file object leading to several operations<br>
+    resulting in a segfault.<br>
+<br>
+    Also, add cleanup in the event of such an error, freeing memory allocated in<br>
+    preparing the gs stream object.<br>
+<br>
+base/sfxcommon.c<br>
+psi/zfile.c<br>
+<p>
+</blockquote>
+<hr>
+<p><strong>2019-09-26 10:47:01 +0100
+</strong>
+<br>Chris Liddell &lt;[email protected]&gt;<br>
+<a href="http://git.ghostscript.com/?p=ghostpdl.git;a=commitdiff;h=cce67ebf4c209ae3cbcc671e944596c64a3d7fc9">cce67ebf4c209ae3cbcc671e944596c64a3d7fc9</a>
+<blockquote>
+<p>
+    Revised comment for 8992f00edfd1c39154c013489de2a01d2e9a92ee<br>
+<br>
+    Make it clearer why the revised behaviour is required.<br>
+<br>
+base/gstiffio.c<br>
+<p>
+</blockquote>
+<hr>
+<p><strong>2019-09-26 09:34:02 +0100
+</strong>
+<br>Chris Liddell &lt;[email protected]&gt;<br>
+<a href="http://git.ghostscript.com/?p=ghostpdl.git;a=commitdiff;h=24c9f7f4a8d3e85e572094b4aedddbeeb02d5ef1">24c9f7f4a8d3e85e572094b4aedddbeeb02d5ef1</a>
+<blockquote>
+<p>
+    Bug 701313: Disable libtiff callbacks when libtiff is shared<br>
+<br>
+    It seems that libtiff uses global variables to store the error/warning callbacks<br>
+    so if two callers in the exe are using the libtiff shared lib, very bad things<br>
+    happen (usually a segfault).<br>
+<br>
+    So, if that's how we're linked, set the callbacks to NULL.<br>
+<br>
+base/gstiffio.c<br>
+<p>
+</blockquote>
+<hr>
+<p><strong>2019-09-24 15:48:54 +0100
+</strong>
+<br>Chris Liddell &lt;[email protected]&gt;<br>
+<a href="http://git.ghostscript.com/?p=ghostpdl.git;a=commitdiff;h=c40963eb024265ab28f4f897401ad7a050ca9425">c40963eb024265ab28f4f897401ad7a050ca9425</a>
+<blockquote>
+<p>
+    Cope with .setsafe(global) being called when already 'SAFER'<br>
+<br>
+    As we default to SAFER file controls now, we want to cope with .setsafe and<br>
+    .setsafeglobal being called either when already SAFER, or called multiple times.<br>
+<br>
+    This means adding a .currentpathcontrolstate operator so we don't try to<br>
+    influence the path control lists after control is activated.<br>
+<br>
+Resource/Init/gs_init.ps<br>
+psi/zfile.c<br>
+<p>
+</blockquote>
+<hr>
+<p><strong>2019-09-24 09:18:47 +0100
+</strong>
+<br>Chris Liddell &lt;[email protected]&gt;<br>
+<a href="http://git.ghostscript.com/?p=ghostpdl.git;a=commitdiff;h=7d70bd4338291c99234dd0078b5cdc85178c0540">7d70bd4338291c99234dd0078b5cdc85178c0540</a>
+<blockquote>
+<p>
+    tiffsep(1): Cope with .tiff ending as well as .tif<br>
+<br>
+devices/gdevtsep.c<br>
+<p>
+</blockquote>
+<hr>
+<p><strong>2019-09-23 20:04:49 +0100
+</strong>
+<br>Robin Watts &lt;[email protected]&gt;<br>
+<a href="http://git.ghostscript.com/?p=ghostpdl.git;a=commitdiff;h=2f713b99e1a626ba4b7b1be8cc715043bb4e0f0a">2f713b99e1a626ba4b7b1be8cc715043bb4e0f0a</a>
+<blockquote>
+<p>
+    Recast validate to use gs_file_name_check_separator.<br>
+<br>
+    Avoid using gp_file_name_directory_separator, as windows can<br>
+    have 2 different directory separators.<br>
+<br>
+base/gpmisc.c<br>
+<p>
+</blockquote>
+<hr>
+<p><strong>2019-09-23 18:05:00 +0100
+</strong>
+<br>Chris Liddell &lt;[email protected]&gt;<br>
+<a href="http://git.ghostscript.com/?p=ghostpdl.git;a=commitdiff;h=31df729a821d1683381493b96c2ecced9da1e5e2">31df729a821d1683381493b96c2ecced9da1e5e2</a>
+<blockquote>
+<p>
+    Remove spurious call to gp_validate_path_len()...<br>
+<br>
+    ...in gx_device_open_output_file()<br>
+<br>
+    There is no need to validate the path in gx_device_open_output_file() as it will<br>
+    be done at a lower level (gp_fopen) for paths that require it (we only validate<br>
+    *after* the Postscript style %device% paths have been expanded into 'real'<br>
+    paths).<br>
+<br>
+    This also interacts badly with the revised handling of formatted string<br>
+    file names, hence remove it.<br>
+<br>
+base/gsdevice.c<br>
+<p>
+</blockquote>
+<hr>
+<p><strong>2019-09-23 17:56:34 +0100
+</strong>
+<br>Chris Liddell &lt;[email protected]&gt;<br>
+<a href="http://git.ghostscript.com/?p=ghostpdl.git;a=commitdiff;h=ca553d6d3ec0fa1455cf400629e08db90658aa85">ca553d6d3ec0fa1455cf400629e08db90658aa85</a>
+<blockquote>
+<p>
+    Fix tiffsep(1) interaction with file permissions lists<br>
+<br>
+    The previous solution didn't quite work, when using formatted strings for<br>
+    output file names (i.e. output-%d.tif).<br>
+<br>
+    This adds a dedicated gs_remove_outputfile_control_path() to mirror<br>
+    gs_add_outputfile_control_path() and uses those for the dynamic adding and<br>
+    removing of separation output file names.<br>
+<br>
+base/gslibctx.c<br>
+base/gslibctx.h<br>
+devices/gdevtsep.c<br>
+<p>
+</blockquote>
+<hr>
+<p><strong>2019-09-23 17:11:47 +0100
+</strong>
+<br>Robin Watts &lt;[email protected]&gt;<br>
+<a href="http://git.ghostscript.com/?p=ghostpdl.git;a=commitdiff;h=205e2f529e6da569ec764ebb4aeddc41c66a8860">205e2f529e6da569ec764ebb4aeddc41c66a8860</a>
+<blockquote>
+<p>
+    Update path validation to accept multiple *'s as special case.<br>
+<br>
+    Previously we interpretted multiple *'s as meaning the same as<br>
+    single *'s. Now we use them to mean &quot;just those chars that<br>
+    might be created by the use of a %...{d,x,u,i,o,X} format<br>
+    specifier&quot;.<br>
+<br>
+base/gpmisc.c<br>
+doc/Use.htm<br>
+<p>
+</blockquote>
+<hr>
+<p><strong>2019-09-23 16:41:09 +0100
+</strong>
+<br>Robin Watts &lt;[email protected]&gt;<br>
+<a href="http://git.ghostscript.com/?p=ghostpdl.git;a=commitdiff;h=dd19ec5348723a5c70ff728911f856caa518166b">dd19ec5348723a5c70ff728911f856caa518166b</a>
+<blockquote>
+<p>
+    Improve OutputFile handling of %d etc.<br>
+<br>
+    Only accept %d (and friends) (as opposed to anything starting with %).<br>
+    Only accept legal combinations of flags/widths/precision etc.<br>
+    Generate a more conservative wildcard.<br>
+<br>
+base/gslibctx.c<br>
+<p>
+</blockquote>
+<hr>
+<p><strong>2019-09-20 12:38:02 -0700
+</strong>
+<br>Ray Johnston &lt;[email protected]&gt;<br>
+<a href="http://git.ghostscript.com/?p=ghostpdl.git;a=commitdiff;h=da7486fc4b00eee956200d45fb340dc62c8e3bcb">da7486fc4b00eee956200d45fb340dc62c8e3bcb</a>
+<blockquote>
+<p>
+    Slight improvement to &quot;permit-file-***&quot; parameter documentation.<br>
+<br>
+doc/Use.htm<br>
+<p>
+</blockquote>
+<hr>
+<p><strong>2019-09-20 11:17:53 -0700
+</strong>
+<br>Ray Johnston &lt;[email protected]&gt;<br>
+<a href="http://git.ghostscript.com/?p=ghostpdl.git;a=commitdiff;h=0222263e4fe03b29e9eb4141f7866fa8261d416a">0222263e4fe03b29e9eb4141f7866fa8261d416a</a>
+<blockquote>
+<p>
+    Fix tiffsep and tiffsep1 with new file access control and SAFER mode<br>
+<br>
+    The tiffsep and tiffsep1 synthesize output file names with the outputfile<br>
+    and the separation color name, but the 'open' of these filenames would<br>
+    fail since they were not included on the permit_file_writing list.<br>
+    Add the full filename before opening, and remove the names after closing.<br>
+<br>
+devices/gdevtsep.c<br>
+<p>
+</blockquote>
+<hr>
+<p><strong>2019-09-20 17:49:57 +0100
+</strong>
+<br>Robin Watts &lt;[email protected]&gt;<br>
+<a href="http://git.ghostscript.com/?p=ghostpdl.git;a=commitdiff;h=0e7039d7a83a7e35b8b41d59d7fb9a8b4fda7fb0">0e7039d7a83a7e35b8b41d59d7fb9a8b4fda7fb0</a>
+<blockquote>
+<p>
+    Fix &quot;permit-file-xxxx&quot; handling.<br>
+<br>
+    Ray spotted that gs_add_explicit_control_path was adding 17<br>
+    to arg before using it. 17 happens to be the right amount<br>
+    to add for &quot;--permit-file-read=&quot;, but the wrong amount for<br>
+    write/control/all.<br>
+<br>
+    Update the code to call it with the correct arg pointer<br>
+    to start with.<br>
+<br>
+    Also, update a couple of routines to cope with being called<br>
+    with NULL strings.<br>
+<br>
+    Also use enum values in switch rather than 0, 1, 2.<br>
+<br>
+base/gslibctx.c<br>
+pcl/pl/plmain.c<br>
+psi/imainarg.c<br>
+<p>
+</blockquote>
+<hr>
+<p><strong>2019-09-19 11:02:48 +0100
+</strong>
+<br>Chris Liddell &lt;[email protected]&gt;<br>
+<a href="http://git.ghostscript.com/?p=ghostpdl.git;a=commitdiff;h=18316aba11fafc57ee77dbd7774b2c88b964a9d9">18316aba11fafc57ee77dbd7774b2c88b964a9d9</a>
+<blockquote>
+<p>
+    Make missing jbig2 decoder fatal error.<br>
+<br>
+    If we have neither Luratech nor jbig2dec, have configure fail, unless<br>
+    explicitly run with --without-jbig2dec<br>
+<br>
+configure.ac<br>
+<p>
+</blockquote>
+<hr>
 <p><strong>2019-09-18 09:24:25 +0100
 </strong>
 <br>Chris Liddell &lt;[email protected]&gt;<br>
@@ -211960,7 +212207,7 @@ or contact Artifex Software, Inc.,  1305 Grant Avenue - Suite 200,
 Novato, CA 94945, U.S.A., +1(415)492-9861, for further information.
 
 <p>
-<small>Ghostscript version 9.28, 18 September 2019
+<small>Ghostscript version 9.28, 30 September 2019
 
 <!-- [3.0 end visible trailer] ============================================= -->
 
diff --git a/doc/Install.htm b/doc/Install.htm
index c5f287f..2e64fb2 100644
--- a/doc/Install.htm
+++ b/doc/Install.htm
@@ -440,7 +440,7 @@ or contact Artifex Software, Inc.,  1305 Grant Avenue - Suite 200,
 Novato, CA 94945, U.S.A., +1(415)492-9861, for further information.
 
 <p>
-<small>Ghostscript version 9.28, 18 September 2019
+<small>Ghostscript version 9.28, 30 September 2019
 
 <!-- [3.0 end visible trailer] ============================================= -->
 
diff --git a/doc/Internal.htm b/doc/Internal.htm
index dd25e65..78be2c4 100644
--- a/doc/Internal.htm
+++ b/doc/Internal.htm
@@ -118,7 +118,7 @@ or contact Artifex Software, Inc.,  1305 Grant Avenue - Suite 200,
 Novato, CA 94945, U.S.A., +1(415)492-9861, for further information.
 
 <p>
-<small>Ghostscript version 9.28, 18 September 2019
+<small>Ghostscript version 9.28, 30 September 2019
 
 <!-- [3.0 end visible trailer] ============================================= -->
 
diff --git a/doc/Language.htm b/doc/Language.htm
index e21be74..ba4f210 100644
--- a/doc/Language.htm
+++ b/doc/Language.htm
@@ -1965,7 +1965,7 @@ or contact Artifex Software, Inc.,  1305 Grant Avenue - Suite 200,
 Novato, CA 94945, U.S.A., +1(415)492-9861, for further information.
 
 <p>
-<small>Ghostscript version 9.28, 18 September 2019
+<small>Ghostscript version 9.28, 30 September 2019
 
 <!-- [3.0 end visible trailer] ============================================= -->
 
diff --git a/doc/Lib.htm b/doc/Lib.htm
index db311ab..585ee9f 100644
--- a/doc/Lib.htm
+++ b/doc/Lib.htm
@@ -1047,7 +1047,7 @@ or contact Artifex Software, Inc.,  1305 Grant Avenue - Suite 200,
 Novato, CA 94945, U.S.A., +1(415)492-9861, for further information.
 
 <p>
-<small>Ghostscript version 9.28, 18 September 2019
+<small>Ghostscript version 9.28, 30 September 2019
 
 <!-- [3.0 end visible trailer] ============================================= -->
 
diff --git a/doc/Make.htm b/doc/Make.htm
index d6be720..77220a1 100644
--- a/doc/Make.htm
+++ b/doc/Make.htm
@@ -1517,7 +1517,7 @@ or contact Artifex Software, Inc.,  1305 Grant Avenue - Suite 200,
 Novato, CA 94945, U.S.A., +1(415)492-9861, for further information.
 
 <p>
-<small>Ghostscript version 9.28, 18 September 2019
+<small>Ghostscript version 9.28, 30 September 2019
 
 <!-- [3.0 end visible trailer] ============================================= -->
 
diff --git a/doc/News.htm b/doc/News.htm
index 20a8abe..bd2ac4b 100644
--- a/doc/News.htm
+++ b/doc/News.htm
@@ -96,7 +96,7 @@ overview</a>.
 
 <!-- [2.0 begin contents] ================================================== -->
 
-<h2><a name="Version9.28"></a>Version 9.28 (2019-09-18)</h2>
+<h2><a name="Version9.28"></a>Version 9.28 (2019-09-30)</h2>
 <p> Highlights in this release include:
 <ul>
 <li>
@@ -187,7 +187,7 @@ or contact Artifex Software, Inc.,  1305 Grant Avenue - Suite 200,
 Novato, CA 94945, U.S.A., +1(415)492-9861, for further information.
 
 <p>
-<small>Ghostscript version 9.28, 18 September 2019
+<small>Ghostscript version 9.28, 30 September 2019
 
 <!-- [3.0 end visible trailer] ============================================= -->
 
diff --git a/doc/Ps-style.htm b/doc/Ps-style.htm
index 64f72dd..6051f15 100644
--- a/doc/Ps-style.htm
+++ b/doc/Ps-style.htm
@@ -549,7 +549,7 @@ or contact Artifex Software, Inc.,  1305 Grant Avenue - Suite 200,
 Novato, CA 94945, U.S.A., +1(415)492-9861, for further information.
 
 <p>
-<small>Ghostscript version 9.28, 18 September 2019
+<small>Ghostscript version 9.28, 30 September 2019
 
 <!-- [3.0 end visible trailer] ============================================= -->
 
diff --git a/doc/Ps2epsi.htm b/doc/Ps2epsi.htm
index 133d860..66176ef 100644
--- a/doc/Ps2epsi.htm
+++ b/doc/Ps2epsi.htm
@@ -229,7 +229,7 @@ or contact Artifex Software, Inc.,  1305 Grant Avenue - Suite 200,
 Novato, CA 94945, U.S.A., +1(415)492-9861, for further information.
 
 <p>
-<small>Ghostscript version 9.28, 18 September 2019
+<small>Ghostscript version 9.28, 30 September 2019
 
 <!-- [3.0 end visible trailer] ============================================= -->
 
diff --git a/doc/Psfiles.htm b/doc/Psfiles.htm
index ab716bc..a465723 100644
--- a/doc/Psfiles.htm
+++ b/doc/Psfiles.htm
@@ -894,7 +894,7 @@ or contact Artifex Software, Inc.,  1305 Grant Avenue - Suite 200,
 Novato, CA 94945, U.S.A., +1(415)492-9861, for further information.
 
 <p>
-<small>Ghostscript version 9.28, 18 September 2019
+<small>Ghostscript version 9.28, 30 September 2019
 
 <!-- [3.0 end visible trailer] ============================================= -->
 
diff --git a/doc/Readme.htm b/doc/Readme.htm
index 8f52ace..eb1376a 100644
--- a/doc/Readme.htm
+++ b/doc/Readme.htm
@@ -578,7 +578,7 @@ or contact Artifex Software, Inc.,  1305 Grant Avenue - Suite 200,
 Novato, CA 94945, U.S.A., +1(415)492-9861, for further information.
 
 <p>
-<small>Ghostscript version 9.28, 18 September 2019
+<small>Ghostscript version 9.28, 30 September 2019
 
 <!-- [3.0 end visible trailer] ============================================= -->
 
diff --git a/doc/Release.htm b/doc/Release.htm
index 2f2c1c9..bfc58c1 100644
--- a/doc/Release.htm
+++ b/doc/Release.htm
@@ -845,7 +845,7 @@ or contact Artifex Software, Inc.,  1305 Grant Avenue - Suite 200,
 Novato, CA 94945, U.S.A., +1(415)492-9861, for further information.
 
 <p>
-<small>Ghostscript version 9.28, 18 September 2019
+<small>Ghostscript version 9.28, 30 September 2019
 
 <!-- [3.0 end visible trailer] ============================================= -->
 
diff --git a/doc/SavedPages.htm b/doc/SavedPages.htm
index d070cd7..6e775dc 100644
--- a/doc/SavedPages.htm
+++ b/doc/SavedPages.htm
@@ -317,7 +317,7 @@ or contact Artifex Software, Inc., 1305 Grant Avenue - Suite 200,
 Novato, CA 94945, U.S.A., +1(415)492-9861.
 
 <p>
-<small>Ghostscript version 9.28, 18 September 2019
+<small>Ghostscript version 9.28, 30 September 2019
 
 <!-- [3.0 end visible trailer] ============================================= -->
 
diff --git a/doc/Source.htm b/doc/Source.htm
index 5bb5c2f..079d8f4 100644
--- a/doc/Source.htm
+++ b/doc/Source.htm
@@ -465,7 +465,7 @@ or contact Artifex Software, Inc.,  1305 Grant Avenue - Suite 200,
 Novato, CA 94945, U.S.A., +1(415)492-9861, for further information.
 
 <p>
-<small>Ghostscript version 9.28, 18 September 2019
+<small>Ghostscript version 9.28, 30 September 2019
 
 <!-- [3.0 end visible trailer] ============================================= -->
 
diff --git a/doc/Unix-lpr.htm b/doc/Unix-lpr.htm
index 2edbe7b..96cf2ad 100644
--- a/doc/Unix-lpr.htm
+++ b/doc/Unix-lpr.htm
@@ -304,7 +304,7 @@ or contact Artifex Software, Inc.,  1305 Grant Avenue - Suite 200,
 Novato, CA 94945, U.S.A., +1(415)492-9861, for further information.
 
 <p>
-<small>Ghostscript version 9.28, 18 September 2019
+<small>Ghostscript version 9.28, 30 September 2019
 
 <!-- [3.0 end visible trailer] ============================================= -->
 
diff --git a/doc/Use.htm b/doc/Use.htm
index 1f7ecd8..9a7a5cd 100644
--- a/doc/Use.htm
+++ b/doc/Use.htm
@@ -5250,7 +5250,7 @@ or contact Artifex Software, Inc.,  1305 Grant Avenue - Suite 200,
 Novato, CA 94945, U.S.A., +1(415)492-9861, for further information.
 
 <p>
-<small>Ghostscript version 9.28, 18 September 2019
+<small>Ghostscript version 9.28, 30 September 2019
 
 <!-- [3.0 end visible trailer] ============================================= -->
 
diff --git a/doc/VectorDevices.htm b/doc/VectorDevices.htm
index df0cbb4..31145a4 100644
--- a/doc/VectorDevices.htm
+++ b/doc/VectorDevices.htm
@@ -1396,7 +1396,7 @@ or contact Artifex Software, Inc.,  1305 Grant Avenue - Suite 200,
 Novato, CA 94945, U.S.A., +1(415)492-9861, for further information.
 
 <p>
-<small>Ghostscript version 9.28, 18 September 2019
+<small>Ghostscript version 9.28, 30 September 2019
 
 <!-- [3.0 end visible trailer] ============================================= -->
 
diff --git a/doc/WhatIsGS.htm b/doc/WhatIsGS.htm
index deada28..838fcba 100644
--- a/doc/WhatIsGS.htm
+++ b/doc/WhatIsGS.htm
@@ -189,7 +189,7 @@ or contact Artifex Software, Inc.,  1305 Grant Avenue - Suite 200,
 Novato, CA 94945, U.S.A., +1(415)492-9861, for further information.
 
 <p>
-<small>Ghostscript version 9.28, 18 September 2019
+<small>Ghostscript version 9.28, 30 September 2019
 
 <!-- [3.0 end visible trailer] ============================================= -->
 
diff --git a/doc/gs-vms.hlp b/doc/gs-vms.hlp
index f16cc06..3f168c9 100644
--- a/doc/gs-vms.hlp
+++ b/doc/gs-vms.hlp
@@ -1,6 +1,6 @@
 1 gs
  gs - GPL Ghostscript interpreter/previewer
-! Ghostscript version 9.28, 18 September 2019
+! Ghostscript version 9.28, 30 September 2019
   Usage:
    $ gs [options] [file ...]
 
diff --git a/doc/sample_downscale_device.htm b/doc/sample_downscale_device.htm
index 77d07ad..9fe23f5 100644
--- a/doc/sample_downscale_device.htm
+++ b/doc/sample_downscale_device.htm
@@ -263,7 +263,7 @@ or contact Artifex Software, Inc.,  1305 Grant Avenue - Suite 200,
 Novato, CA 94945, U.S.A., +1(415)492-9861, for further information.
 
 <p>
-<small>Ghostscript version 9.28, 18 September 2019
+<small>Ghostscript version 9.28, 30 September 2019
 
 <!-- [3.0 end visible trailer] ============================================= -->
 <!--FINISH EDITING HERE-->
diff --git a/doc/subclass.htm b/doc/subclass.htm
index 7b8f8d3..db6c9cf 100644
--- a/doc/subclass.htm
+++ b/doc/subclass.htm
@@ -812,7 +812,7 @@ or contact Artifex Software, Inc., 1305 Grant Avenue - Suite 200,
 Novato, CA 94945, U.S.A., +1(415)492-9861.
 
 <p>
-<small>Ghostscript version 9.28, 18 September 2019
+<small>Ghostscript version 9.28, 30 September 2019
 
 <!-- [3.0 end visible trailer] ============================================= -->
 
diff --git a/doc/thirdparty.htm b/doc/thirdparty.htm
index 541fa71..0857097 100644
--- a/doc/thirdparty.htm
+++ b/doc/thirdparty.htm
@@ -268,7 +268,7 @@ or contact Artifex Software, Inc.,  1305 Grant Avenue - Suite 200,
 Novato, CA 94945, U.S.A., +1(415)492-9861, for further information.
 
 <p>
-<small>Ghostscript version 9.28, 18 September 2019
+<small>Ghostscript version 9.28, 30 September 2019
 
 <!-- [3.0 end visible trailer] ============================================= -->
 
diff --git a/man/dvipdf.1 b/man/dvipdf.1
index 4bbf82e..4cda10b 100644
--- a/man/dvipdf.1
+++ b/man/dvipdf.1
@@ -1,4 +1,4 @@
-.TH DVIPDF 1 "18 September 2019" 9.28 Ghostscript \" -*- nroff -*-
+.TH DVIPDF 1 "30 September 2019" 9.28 Ghostscript \" -*- nroff -*-
 .SH NAME
 dvipdf \- Convert TeX DVI file to PDF using ghostscript and dvips
 .SH SYNOPSIS
diff --git a/man/gs.1 b/man/gs.1
index 4b0015e..94acb7d 100644
--- a/man/gs.1
+++ b/man/gs.1
@@ -1,4 +1,4 @@
-.TH GS 1 "18 September 2019" 9.28 Ghostscript \" -*- nroff -*-
+.TH GS 1 "30 September 2019" 9.28 Ghostscript \" -*- nroff -*-
 .SH NAME
 gs \- Ghostscript (PostScript and PDF language interpreter and previewer)
 .SH SYNOPSIS
diff --git a/man/gslp.1 b/man/gslp.1
index 543ec65..390182f 100644
--- a/man/gslp.1
+++ b/man/gslp.1
@@ -1,4 +1,4 @@
-.TH GSLP 1 "18 September 2019" 9.28 Ghostscript \" -*- nroff -*-
+.TH GSLP 1 "30 September 2019" 9.28 Ghostscript \" -*- nroff -*-
 .SH NAME
 gslp \- Format and print text using ghostscript
 .br
diff --git a/man/gsnd.1 b/man/gsnd.1
index aee58d4..33b9c56 100644
--- a/man/gsnd.1
+++ b/man/gsnd.1
@@ -1,4 +1,4 @@
-.TH GSND 1 "18 September 2019" 9.28 Ghostscript \" -*- nroff -*-
+.TH GSND 1 "30 September 2019" 9.28 Ghostscript \" -*- nroff -*-
 .SH NAME
 gsnd \- Run ghostscript (PostScript and PDF engine) without display
 .SH SYNOPSIS
diff --git a/man/pdf2dsc.1 b/man/pdf2dsc.1
index dd833c0..21d3924 100644
--- a/man/pdf2dsc.1
+++ b/man/pdf2dsc.1
@@ -1,4 +1,4 @@
-.TH PDF2DSC 1 "18 September 2019" 9.28 "Ghostscript Tools" \" -*- nroff -*-
+.TH PDF2DSC 1 "30 September 2019" 9.28 "Ghostscript Tools" \" -*- nroff -*-
 .SH NAME
 pdf2dsc \- generate a PostScript page list of a PDF document
 .SH SYNOPSIS
diff --git a/man/pdf2ps.1 b/man/pdf2ps.1
index 0671351..45f9465 100644
--- a/man/pdf2ps.1
+++ b/man/pdf2ps.1
@@ -1,4 +1,4 @@
-.TH PDF2PS 1 "18 September 2019" 9.28 "Ghostscript Tools" \" -*- nroff -*-
+.TH PDF2PS 1 "30 September 2019" 9.28 "Ghostscript Tools" \" -*- nroff -*-
 .SH NAME
 pdf2ps \- Ghostscript PDF to PostScript translator
 .SH SYNOPSIS
diff --git a/man/pf2afm.1 b/man/pf2afm.1
index 7940c98..9e9c1d2 100644
--- a/man/pf2afm.1
+++ b/man/pf2afm.1
@@ -1,4 +1,4 @@
-.TH PF2AFM 1 "18 September 2019" 9.28 Ghostscript \" -*- nroff -*-
+.TH PF2AFM 1 "30 September 2019" 9.28 Ghostscript \" -*- nroff -*-
 .SH NAME
 pf2afm \- Make an AFM file from Postscript (PFB/PFA/PFM) font files using ghostscript
 .SH SYNOPSIS
diff --git a/man/pfbtopfa.1 b/man/pfbtopfa.1
index 4137b22..311af7b 100644
--- a/man/pfbtopfa.1
+++ b/man/pfbtopfa.1
@@ -1,4 +1,4 @@
-.TH PFBTOPFA 1 "18 September 2019" 9.28 Ghostscript \" -*- nroff -*-
+.TH PFBTOPFA 1 "30 September 2019" 9.28 Ghostscript \" -*- nroff -*-
 .SH NAME
 pfbtopfa \- Convert Postscript .pfb fonts to .pfa format using ghostscript
 .SH SYNOPSIS
diff --git a/man/printafm.1 b/man/printafm.1
index d5dc88c..192f8e0 100644
--- a/man/printafm.1
+++ b/man/printafm.1
@@ -1,4 +1,4 @@
-.TH PRINTAFM 1 "18 September 2019" 9.28 Ghostscript \" -*- nroff -*-
+.TH PRINTAFM 1 "30 September 2019" 9.28 Ghostscript \" -*- nroff -*-
 .SH NAME
 printafm \- Print the metrics from a Postscript font in AFM format using ghostscript
 .SH SYNOPSIS
diff --git a/man/ps2ascii.1 b/man/ps2ascii.1
index 2f55cf8..de592d2 100644
--- a/man/ps2ascii.1
+++ b/man/ps2ascii.1
@@ -1,4 +1,4 @@
-.TH PS2ASCII 1 "18 September 2019" 9.28 "Ghostscript Tools" \" -*- nroff -*-
+.TH PS2ASCII 1 "30 September 2019" 9.28 "Ghostscript Tools" \" -*- nroff -*-
 .SH NAME
 ps2ascii \- Ghostscript translator from PostScript or PDF to ASCII
 .SH SYNOPSIS
diff --git a/man/ps2epsi.1 b/man/ps2epsi.1
index 0f52591..9fa77e7 100644
--- a/man/ps2epsi.1
+++ b/man/ps2epsi.1
@@ -1,4 +1,4 @@
-.TH PS2EPSI 1 "18 September 2019" 9.28 "Ghostscript Tools" \" -*- nroff -*-
+.TH PS2EPSI 1 "30 September 2019" 9.28 "Ghostscript Tools" \" -*- nroff -*-
 .SH NAME
 ps2epsi \- generate conforming Encapsulated PostScript
 .SH SYNOPSIS
diff --git a/man/ps2pdf.1 b/man/ps2pdf.1
index 2f134a5..18dd0ca 100644
--- a/man/ps2pdf.1
+++ b/man/ps2pdf.1
@@ -1,4 +1,4 @@
-.TH PS2PDF 1 "18 September 2019" 9.28 Ghostscript \" -*- nroff -*-
+.TH PS2PDF 1 "30 September 2019" 9.28 Ghostscript \" -*- nroff -*-
 .SH NAME
 ps2pdf \- Convert PostScript to PDF using ghostscript
 .br
diff --git a/man/ps2pdfwr.1 b/man/ps2pdfwr.1
index 4a4503b..977467c 100644
--- a/man/ps2pdfwr.1
+++ b/man/ps2pdfwr.1
@@ -1,4 +1,4 @@
-.TH PS2PDFWR 1 "18 September 2019" 9.28 Ghostscript \" -*- nroff -*-
+.TH PS2PDFWR 1 "30 September 2019" 9.28 Ghostscript \" -*- nroff -*-
 .SH NAME
 ps2pdfwr \- Convert PostScript to PDF without specifying CompatibilityLevel, using ghostscript
 .SH SYNOPSIS
diff --git a/man/ps2ps.1 b/man/ps2ps.1
index 80c5751..34b25ef 100644
--- a/man/ps2ps.1
+++ b/man/ps2ps.1
@@ -1,4 +1,4 @@
-.TH PS2PS 1 "18 September 2019" 9.28 "Ghostscript Tools" \" -*- nroff -*-
+.TH PS2PS 1 "30 September 2019" 9.28 "Ghostscript Tools" \" -*- nroff -*-
 .SH NAME
 ps2ps, eps2eps \- Ghostscript PostScript "distiller"
 .SH SYNOPSIS

----------------------------------------------------------------------
commit b0574cdb5b427690ac8d95679930c9f6cc1bdffb
Author: Chris Liddell <[email protected]>
Date:   Fri Sep 27 13:26:01 2019 +0100

    Bug 701634: Correctly handle file name of "\0"
    
    Attempting to open a file with a filename string starting with a NULL
    character should be treated the same as if the string was zero length.
    
    Not doing so created a broken file object leading to several operations
    resulting in a segfault.
    
    Also, add cleanup in the event of such an error, freeing memory allocated in
    preparing the gs stream object.

diff --git a/base/sfxcommon.c b/base/sfxcommon.c
index e5d5e88..002651b 100644
--- a/base/sfxcommon.c
+++ b/base/sfxcommon.c
@@ -82,8 +82,15 @@ file_open_stream(const char *fname, uint len, const char *file_access,
         return code;
     if (fname == 0)
         return 0;
-    if (fname[0] == 0)		/* fopen_proc gets NUL terminated string, not len */
-        return 0;		/* so this is the same as len == 0, so return NULL */
+    if (fname[0] == 0) {        /* fopen_proc gets NUL terminated string, not len */
+                                /* so this is the same as len == 0, so return NULL */
+        /* discard the stuff we allocated to keep from accumulating stuff needing GC */
+        gs_free_object(mem, (*ps)->cbuf, "file_close(buffer)");
+        gs_free_object(mem, *ps, "file_prepare_stream(stream)");
+        *ps = NULL;
+
+        return 0;
+    }
     code = (*fopen_proc)(iodev, (char *)(*ps)->cbuf, fmode, &file,
                          (char *)(*ps)->cbuf, (*ps)->bsize, mem);
     if (code < 0) {
diff --git a/psi/zfile.c b/psi/zfile.c
index 2b7d168..2f13992 100644
--- a/psi/zfile.c
+++ b/psi/zfile.c
@@ -282,6 +282,8 @@ zfile(i_ctx_t *i_ctx_p)
     }
     if (code < 0)
         return code;
+    if (s == NULL)
+        return_error(gs_error_undefinedfilename);
     code = ssetfilename(s, op[-1].value.const_bytes, r_size(op - 1));
     if (code < 0) {
         sclose(s);
@@ -667,6 +669,7 @@ zlibfile(i_ctx_t *i_ctx_p)
         pname.iodev = iodev_dflt;
     if (pname.iodev != iodev_dflt) { /* Non-OS devices don't have search paths (yet). */
         code = zopen_file(i_ctx_p, &pname, "r", &s, imemory);
+        if (s == NULL) code = gs_note_error(gs_error_undefinedfilename);
         if (code >= 0) {
             code = ssetfilename(s, op->value.const_bytes, r_size(op));
             if (code < 0) {

----------------------------------------------------------------------
commit cce67ebf4c209ae3cbcc671e944596c64a3d7fc9
Author: Chris Liddell <[email protected]>
Date:   Thu Sep 26 10:47:01 2019 +0100

    Revised comment for 8992f00edfd1c39154c013489de2a01d2e9a92ee
    
    Make it clearer why the revised behaviour is required.

diff --git a/base/gstiffio.c b/base/gstiffio.c
index a99e5e7..6828a61 100644
--- a/base/gstiffio.c
+++ b/base/gstiffio.c
@@ -212,9 +212,11 @@ gs_tifsErrorHandlerEx(thandle_t client_data, const char* module, const char* fmt
 
 void tiff_set_handlers (void)
 {
-    /* Bad things happen if multiple callers are using libtiff
-     * with custom error/warning callbacks, so set them to NULL
-     * if we're using a libtiff shared lib
+    /* Bad things happen if we set custom error/warning
+     * handlers, and multiple callers are using the shared
+     * libtiff - our handlers may be triggered in the
+     * context of the other caller(s) meaning it's not
+     * our client_data being passed in.
      */
     (void)TIFFSetErrorHandler(NULL);
     (void)TIFFSetWarningHandler(NULL);

----------------------------------------------------------------------
commit 24c9f7f4a8d3e85e572094b4aedddbeeb02d5ef1
Author: Chris Liddell <[email protected]>
Date:   Thu Sep 26 09:34:02 2019 +0100

    Bug 701313: Disable libtiff callbacks when libtiff is shared
    
    It seems that libtiff uses global variables to store the error/warning callbacks
    so if two callers in the exe are using the libtiff shared lib, very bad things
    happen (usually a segfault).
    
    So, if that's how we're linked, set the callbacks to NULL.

diff --git a/base/gstiffio.c b/base/gstiffio.c
index e69ad14..a99e5e7 100644
--- a/base/gstiffio.c
+++ b/base/gstiffio.c
@@ -212,10 +212,16 @@ gs_tifsErrorHandlerEx(thandle_t client_data, const char* module, const char* fmt
 
 void tiff_set_handlers (void)
 {
+    /* Bad things happen if multiple callers are using libtiff
+     * with custom error/warning callbacks, so set them to NULL
+     * if we're using a libtiff shared lib
+     */
     (void)TIFFSetErrorHandler(NULL);
     (void)TIFFSetWarningHandler(NULL);
+#if SHARE_LIBTIFF == 0
     (void)TIFFSetErrorHandlerExt(gs_tifsErrorHandlerEx);
     (void)TIFFSetWarningHandlerExt(gs_tifsWarningHandlerEx);
+#endif
 }
 
 #if SHARE_LIBTIFF == 0

----------------------------------------------------------------------
commit c40963eb024265ab28f4f897401ad7a050ca9425
Author: Chris Liddell <[email protected]>
Date:   Tue Sep 24 15:48:54 2019 +0100

    Cope with .setsafe(global) being called when already 'SAFER'
    
    As we default to SAFER file controls now, we want to cope with .setsafe and
    .setsafeglobal being called either when already SAFER, or called multiple times.
    
    This means adding a .currentpathcontrolstate operator so we don't try to
    influence the path control lists after control is activated.

diff --git a/Resource/Init/gs_init.ps b/Resource/Init/gs_init.ps
index 2e37db0..f46f653 100644
--- a/Resource/Init/gs_init.ps
+++ b/Resource/Init/gs_init.ps
@@ -2216,30 +2216,37 @@ readonly def
 ] def
 
 /.lockfileaccess {
-  [
-    //tempfilepaths (*) .generate_dir_list_templates
-    /FONTPATH .systemvar (*) .generate_dir_list_templates
-    /level2dict where {
-        pop
-        % Default resources :
-      [ currentsystemparams /GenericResourceDir get] (*) .generate_dir_list_templates
-    } if
-    /LIBPATH  .systemvar (*) .generate_dir_list_templates
-    currentuserparams /ICCProfilesDir known {
-      [currentuserparams /ICCProfilesDir get] (*)
-      .generate_dir_list_templates
-    } if
-  ] {/PermitFileReading exch .addcontrolpath} forall
+  .currentpathcontrolstate
+  {
+    (\n **** WARNING: .lockfileaccess or .setsafe called ****\n) print
+    ( **** when file access controls are already active ****\n) print flush
+  }
+  {
+    [
+      //tempfilepaths (*) .generate_dir_list_templates
+      /FONTPATH .systemvar (*) .generate_dir_list_templates
+      /level2dict where {
+          pop
+          % Default resources :
+        [ currentsystemparams /GenericResourceDir get] (*) .generate_dir_list_templates
+      } if
+      /LIBPATH  .systemvar (*) .generate_dir_list_templates
+      currentuserparams /ICCProfilesDir known {
+        [currentuserparams /ICCProfilesDir get] (*)
+        .generate_dir_list_templates
+      } if
+    ] {/PermitFileReading exch .addcontrolpath} forall
 
-  [
-    //tempfilepaths (*) .generate_dir_list_templates
-  ] {/PermitFileWriting exch .addcontrolpath} forall
+    [
+      //tempfilepaths (*) .generate_dir_list_templates
+    ] {/PermitFileWriting exch .addcontrolpath} forall
 
-  [
-    //tempfilepaths (*) .generate_dir_list_templates
-  ] {/PermitFileControl exch .addcontrolpath} forall
+    [
+      //tempfilepaths (*) .generate_dir_list_templates
+    ] {/PermitFileControl exch .addcontrolpath} forall
 
-  .activatepathcontrol
+    .activatepathcontrol
+  } ifelse
 } bind def
 
 /.locksafe_userparams {
@@ -2310,7 +2317,12 @@ currentdict /tempfilepaths undef
     if
     .locksafe
   }
-  {//.lockfileaccess exec}
+  {
+    //.lockfileaccess exec
+    DELAYBIND not {
+        //systemdict /SAFERUndefinePostScriptOperators .knownget {exec} if
+    } if
+  }
   ifelse
 } .bind executeonly odef
 %% --- End documented extensions ---
@@ -2351,9 +2363,14 @@ currentdict /tempfilepaths undef
     if
     //.locksafeglobal exec
   }
-  {//.lockfileaccess exec}
+  {
+    //.lockfileaccess exec
+    DELAYBIND not {
+        //systemdict /SAFERUndefinePostScriptOperators .knownget {exec} if
+    } if
+  }
   ifelse
-} .bind def
+} .bind executeonly odef
 
 % If we are running in SAFER mode, lock things down
 SAFER { .setsafeglobal } if
diff --git a/psi/zfile.c b/psi/zfile.c
index 9d87f45..2b7d168 100644
--- a/psi/zfile.c
+++ b/psi/zfile.c
@@ -918,6 +918,18 @@ static int zactivatepathcontrol(i_ctx_t *i_ctx_p)
     gs_activate_path_control(imemory, 1);
     return 0;
 }
+static int zcurrentpathcontrolstate(i_ctx_t *i_ctx_p)
+{
+    os_ptr op = osp;
+    push(1);
+    if (gs_is_path_control_active(imemory)) {
+        make_true(op);
+    }
+    else {
+        make_false(op);
+    }
+    return 0;
+}
 
 /* ------ Initialization procedure ------ */
 
@@ -940,6 +952,7 @@ const op_def zfile_op_defs[] =
     /* Control path operators */
     {"2.addcontrolpath", zaddcontrolpath},
     {"0.activatepathcontrol", zactivatepathcontrol},
+    {"0.currentpathcontrolstate", zcurrentpathcontrolstate},
     op_def_end(0)
 };
 

----------------------------------------------------------------------
commit 7d70bd4338291c99234dd0078b5cdc85178c0540
Author: Chris Liddell <[email protected]>
Date:   Tue Sep 24 09:18:47 2019 +0100

    tiffsep(1): Cope with .tiff ending as well as .tif

diff --git a/devices/gdevtsep.c b/devices/gdevtsep.c
index 7650c2b..5fb1025 100644
--- a/devices/gdevtsep.c
+++ b/devices/gdevtsep.c
@@ -1507,7 +1507,7 @@ copy_separation_name(tiffsep_device * pdev,
  * name.
  */
 static int
-length_base_file_name(tiffsep_device * pdev)
+length_base_file_name(tiffsep_device * pdev, bool *double_f)
 {
     int base_filename_length = strlen(pdev->fname);
 
@@ -1517,8 +1517,19 @@ length_base_file_name(tiffsep_device * pdev)
         pdev->fname[base_filename_length - 4] == '.'  &&
         toupper(pdev->fname[base_filename_length - 3]) == 'T'  &&
         toupper(pdev->fname[base_filename_length - 2]) == 'I'  &&
-        toupper(pdev->fname[base_filename_length - 1]) == 'F')
+        toupper(pdev->fname[base_filename_length - 1]) == 'F') {
         base_filename_length -= 4;
+        *double_f = false;
+    }
+    else if (base_filename_length > 5 &&
+        pdev->fname[base_filename_length - 5] == '.'  &&
+        toupper(pdev->fname[base_filename_length - 4]) == 'T'  &&
+        toupper(pdev->fname[base_filename_length - 3]) == 'I'  &&
+        toupper(pdev->fname[base_filename_length - 2]) == 'F'  &&
+        toupper(pdev->fname[base_filename_length - 1]) == 'F') {
+        base_filename_length -= 5;
+        *double_f = true;
+    }
 #endif
 #undef REMOVE_TIF_FROM_BASENAME
 
@@ -1532,7 +1543,8 @@ static int
 create_separation_file_name(tiffsep_device * pdev, char * buffer,
                                 uint max_size, int sep_num, bool use_sep_name)
 {
-    uint base_filename_length = length_base_file_name(pdev);
+    bool double_f = false;
+    uint base_filename_length = length_base_file_name(pdev, &double_f);
 
     /*
      * In most cases it is more convenient if we append '.tif' to the end
@@ -1566,9 +1578,16 @@ create_separation_file_name(tiffsep_device * pdev, char * buffer,
         strcat(buffer, ")");
 
 #if APPEND_TIF_TO_NAME
-    if (max_size < strlen(buffer) + SUFFIX_SIZE)
-        return_error(gs_error_rangecheck);
-    strcat(buffer, ".tif");
+    if (double_f) {
+        if (max_size < strlen(buffer) + SUFFIX_SIZE + 1)
+            return_error(gs_error_rangecheck);
+        strcat(buffer, ".tiff");
+    }
+    else {
+        if (max_size < strlen(buffer) + SUFFIX_SIZE)
+            return_error(gs_error_rangecheck);
+        strcat(buffer, ".tif");
+    }
 #endif
     return 0;
 }
@@ -2304,7 +2323,8 @@ tiffsep_print_page(gx_device_printer * pdev, gp_file * file)
     int num_comp, comp_num, sep_num, code = 0, code1 = 0;
     cmyk_composite_map cmyk_map[GX_DEVICE_COLOR_MAX_COMPONENTS];
     char *name = NULL;
-    int base_filename_length = length_base_file_name(tfdev);
+    bool double_f = false;
+    int base_filename_length = length_base_file_name(tfdev, &double_f);
     int save_depth = pdev->color_info.depth;
     int save_numcomps = pdev->color_info.num_components;
     const char *fmt;

----------------------------------------------------------------------
commit 2f713b99e1a626ba4b7b1be8cc715043bb4e0f0a
Author: Robin Watts <[email protected]>
Date:   Mon Sep 23 20:04:49 2019 +0100

    Recast validate to use gs_file_name_check_separator.
    
    Avoid using gp_file_name_directory_separator, as windows can
    have 2 different directory separators.

diff --git a/base/gpmisc.c b/base/gpmisc.c
index 4ffd6d5..9cca5d5 100644
--- a/base/gpmisc.c
+++ b/base/gpmisc.c
@@ -896,19 +896,6 @@ gp_enumerate_files_close(gs_memory_t *mem, file_enum * pfen)
  */
 
 static int
-ends_in(const char *first, const char *last, const char *ds, size_t len)
-{
-    while (len) {
-        if (last < first)
-            return 0; /* No match */
-        if (*last != ds[--len])
-            return 0; /* No match */
-        last--;
-    }
-    return 1;
-}
-
-static int
 validate(const gs_memory_t *mem,
          const char        *path,
          gs_path_control_t  type)
@@ -916,8 +903,6 @@ validate(const gs_memory_t *mem,
     gs_lib_ctx_core_t *core = mem->gs_lib_ctx->core;
     const gs_path_control_set_t *control;
     unsigned int i, n;
-    const char *ds = gp_file_name_directory_separator();
-    size_t dslen = strlen(ds);
 
     switch (type) {
         case gs_permit_file_reading:
@@ -970,20 +955,21 @@ validate(const gs_memory_t *mem,
                         goto found;
                     /* Skip over anything except NUL, directory
                      * separator, and the next char to match. */
-                    while (*a && *a != ds[0] && *a != b[1])
+                    while (*a && !gs_file_name_check_separator(a, 1, a) && *a != b[1])
                         a++;
-                    if (*a == 0 || *a == ds[0])
+                    if (*a == 0 || *a == gs_file_name_check_separator(a, 1, a))
                         break; /* No match */
                 }
                 /* Continue matching */
                 a--; /* Subtract 1 as the loop will increment it again later */
             } else if (*b == 0) {
-                if (ends_in(control->paths[i], b - 1, ds, dslen)) {
+                if (b != control->paths[i] &&
+                    gs_file_name_check_separator(b, -1, b)) {
                     const char *a2 = a;
                     const char *aend = path + strlen(path);
-                    while (aend - a2 >= dslen && memcmp(a2, ds, dslen))
+                    while (aend != a2 && !gs_file_name_check_separator(a2, 1, a2))
                       a2++;
-                    if (aend - a2 < dslen)
+                    if (aend != a2)
                       /* PATH=abc/? pattern=abc/ */
                       goto found; /* Bingo! */
                  }

----------------------------------------------------------------------
commit 31df729a821d1683381493b96c2ecced9da1e5e2
Author: Chris Liddell <[email protected]>
Date:   Mon Sep 23 18:05:00 2019 +0100

    Remove spurious call to gp_validate_path_len()...
    
    ...in gx_device_open_output_file()
    
    There is no need to validate the path in gx_device_open_output_file() as it will
    be done at a lower level (gp_fopen) for paths that require it (we only validate
    *after* the Postscript style %device% paths have been expanded into 'real'
    paths).
    
    This also interacts badly with the revised handling of formatted string
    file names, hence remove it.

diff --git a/base/gsdevice.c b/base/gsdevice.c
index 16b0752..69fb174 100644
--- a/base/gsdevice.c
+++ b/base/gsdevice.c
@@ -1207,13 +1207,10 @@ gx_device_open_output_file(const gx_device * dev, char *fname,
     char *pfname = (char *)gs_alloc_bytes(dev->memory, gp_file_name_sizeof, "gx_device_open_output_file(pfname)");
     int code;
 
-    if (gp_validate_path(dev->memory, fname, binary ? "wb" : "w") != 0)
-        return gs_error_invalidfileaccess;
-
     if (pfname == NULL) {
         code = gs_note_error(gs_error_VMerror);
 	goto done;
-     }
+    }
 
     if (strlen(fname) == 0) {
         code = gs_note_error(gs_error_undefinedfilename);

----------------------------------------------------------------------
commit ca553d6d3ec0fa1455cf400629e08db90658aa85
Author: Chris Liddell <[email protected]>
Date:   Mon Sep 23 17:56:34 2019 +0100

    Fix tiffsep(1) interaction with file permissions lists
    
    The previous solution didn't quite work, when using formatted strings for
    output file names (i.e. output-%d.tif).
    
    This adds a dedicated gs_remove_outputfile_control_path() to mirror
    gs_add_outputfile_control_path() and uses those for the dynamic adding and
    removing of separation output file names.

diff --git a/base/gslibctx.c b/base/gslibctx.c
index 8895ff2..9bb5d19 100644
--- a/base/gslibctx.c
+++ b/base/gslibctx.c
@@ -683,6 +683,46 @@ gs_add_outputfile_control_path(gs_memory_t *mem, const char *fname)
 }
 
 int
+gs_remove_outputfile_control_path(gs_memory_t *mem, const char *fname)
+{
+    char *fp, f[gp_file_name_sizeof];
+    const int pipe = 124; /* ASCII code for '|' */
+    const int len = strlen(fname);
+
+    /* Be sure the string copy will fit */
+    if (len >= gp_file_name_sizeof)
+        return gs_error_rangecheck;
+    strcpy(f, fname);
+    fp = f;
+    /* Try to rewrite any %d (or similar) in the string */
+    if (!rewrite_percent_specifiers(f)) {
+        /* No %d found, so check for pipes */
+        int i;
+        fp = f;
+        for (i = 0; i < len; i++) {
+            if (f[i] == pipe) {
+               int code;
+
+               fp = &f[i + 1];
+               /* Because we potentially have to check file permissions at two levels
+                  for the output file (gx_device_open_output_file and the low level
+                  fopen API, if we're using a pipe, we have to add both the full string,
+                  (including the '|', and just the command to which we pipe - since at
+                  the pipe_fopen(), the leading '|' has been stripped.
+                */
+               code = gs_remove_control_path(mem, gs_permit_file_writing, f);
+               if (code < 0)
+                   return code;
+               break;
+            }
+            if (!IS_WHITESPACE(f[i]))
+                break;
+        }
+    }
+    return gs_remove_control_path(mem, gs_permit_file_writing, fp);
+}
+
+int
 gs_add_explicit_control_path(gs_memory_t *mem, const char *arg, gs_path_control_t control)
 {
     char *p2, *p1 = (char *)arg;
diff --git a/base/gslibctx.h b/base/gslibctx.h
index 1425014..79bc9da 100644
--- a/base/gslibctx.h
+++ b/base/gslibctx.h
@@ -243,6 +243,9 @@ int
 gs_add_outputfile_control_path(gs_memory_t *mem, const char *fname);
 
 int
+gs_remove_outputfile_control_path(gs_memory_t *mem, const char *fname);
+
+int
 gs_add_explicit_control_path(gs_memory_t *mem, const char *arg, gs_path_control_t control);
 
 int
diff --git a/devices/gdevtsep.c b/devices/gdevtsep.c
index ec01fb3..7650c2b 100644
--- a/devices/gdevtsep.c
+++ b/devices/gdevtsep.c
@@ -1361,7 +1361,7 @@ tiffsep1_prn_close(gx_device * pdev)
             }
             code = gx_device_close_output_file(pdev, name, tfdev->sep_file[comp_num]);
             if (code >= 0)
-                code = gs_remove_control_path(pdev->memory, gs_permit_file_writing, name);
+                code = gs_remove_outputfile_control_path(pdev->memory, name);
             if (code < 0) {
                 goto done;
             }
@@ -1871,7 +1871,7 @@ tiffsep_prn_close(gx_device * pdev)
             }
             code = tiffsep_close_sep_file(pdevn, name, comp_num);
             if (code >= 0)
-                code = gs_remove_control_path(pdevn->memory, gs_permit_file_writing, name);
+                code = gs_remove_outputfile_control_path(pdevn->memory, name);
             if (code < 0) {
                 goto done;
             }
@@ -2407,13 +2407,13 @@ tiffsep_print_page(gx_device_printer * pdev, gp_file * file)
             if (tfdev->sep_file[comp_num] != NULL && fmt != NULL) {
                 code = tiffsep_close_sep_file(tfdev, name, comp_num);
                 if (code >= 0)
-                    code = gs_remove_control_path(tfdev->memory, gs_permit_file_writing, name);
+                    code = gs_remove_outputfile_control_path(tfdev->memory, name);
                 if (code < 0)
                     return code;
             }
             /* Open the separation file, if not already open */
             if (tfdev->sep_file[comp_num] == NULL) {
-                code = gs_add_control_path(tfdev->memory, gs_permit_file_writing, name);
+                code = gs_add_outputfile_control_path(tfdev->memory, name);
                 if (code < 0) {
                     goto done;
                 }
@@ -2637,7 +2637,7 @@ cleanup:
                     }
                     code = tiffsep_close_sep_file(tfdev, name, comp_num);
                     if (code >= 0)
-                        code = gs_remove_control_path(tfdev->memory, gs_permit_file_writing, name);
+                        code = gs_remove_outputfile_control_path(tfdev->memory, name);
                     if (code < 0) {
                         code1 = code;
                     }
@@ -2750,7 +2750,7 @@ tiffsep1_print_page(gx_device_printer * pdev, gp_file * file)
 
         /* Open the separation file, if not already open */
         if (tfdev->sep_file[comp_num] == NULL) {
-            code = gs_add_control_path(tfdev->memory, gs_permit_file_writing, name);
+            code = gs_add_outputfile_control_path(tfdev->memory, name);
             if (code < 0) {
                 goto done;
             }
@@ -2913,7 +2913,7 @@ tiffsep1_print_page(gx_device_printer * pdev, gp_file * file)
                 }
                 code = tiffsep_close_sep_file((tiffsep_device *)tfdev, name, comp_num);
                 if (code >= 0)
-                    code = gs_remove_control_path(tfdev->memory, gs_permit_file_writing, name);
+                    code = gs_remove_outputfile_control_path(tfdev->memory, name);
                 if (code < 0) {
                     code1 = code;
                 }

----------------------------------------------------------------------
commit 205e2f529e6da569ec764ebb4aeddc41c66a8860
Author: Robin Watts <[email protected]>
Date:   Mon Sep 23 17:11:47 2019 +0100

    Update path validation to accept multiple *'s as special case.
    
    Previously we interpretted multiple *'s as meaning the same as
    single *'s. Now we use them to mean "just those chars that
    might be created by the use of a %...{d,x,u,i,o,X} format
    specifier".

diff --git a/base/gpmisc.c b/base/gpmisc.c
index 88a09c6..4ffd6d5 100644
--- a/base/gpmisc.c
+++ b/base/gpmisc.c
@@ -946,22 +946,37 @@ validate(const gs_memory_t *mem,
                     /* PATH=abc pattern=abcd */
                     break; /* No match */
             } else if (*b == '*') {
-                /* Skip over multiple '*'s - this is intended to
-                 * make life easier for the code constructing
-                 * patterns from OutputFile definitions. */
-                while (b[1] == '*')
+                if (b[1] == '*') {
+                    /* Multiple '*'s are taken to mean the
+                     * output from a printf. */
                     b++;
-                if (b[1] == 0)
-                    /* PATH=abc???? pattern=abc* */
-                    goto found;
-                /* Skip over anything except NUL, directory
-                 * separator, and the next char to match. */
-                while (*a && *a != ds[0] && *a != b[1])
-                    a++;
-                if (*a == 0 || *a == ds[0])
-                    break; /* No match */
+                    while (b[1] == '*')
+                        b++;
+                    /* Skip over the permissible matching chars */
+                    while (*a &&
+                           ((*a == ' ' || *a == '-' || *a == '+' ||
+                             (*a >= '0' && *a <= '9') ||
+                             (*a >= 'a' && *a <= 'f') ||
+                             (*a >= 'A' && *a <= 'F'))))
+                            a++;
+                    if (b[1] == 0 && *a == 0)
+                        /* PATH=abc<%d> pattern=abc** */
+                        goto found;
+                    if (*a == 0)
+                        break; /* No match */
+                } else {
+                    if (b[1] == 0)
+                        /* PATH=abc???? pattern=abc* */
+                        goto found;
+                    /* Skip over anything except NUL, directory
+                     * separator, and the next char to match. */
+                    while (*a && *a != ds[0] && *a != b[1])
+                        a++;
+                    if (*a == 0 || *a == ds[0])
+                        break; /* No match */
+                }
                 /* Continue matching */
-                a--;
+                a--; /* Subtract 1 as the loop will increment it again later */
             } else if (*b == 0) {
                 if (ends_in(control->paths[i], b - 1, ds, dslen)) {
                     const char *a2 = a;
diff --git a/doc/Use.htm b/doc/Use.htm
index 1c5b259..1f7ecd8 100644
--- a/doc/Use.htm
+++ b/doc/Use.htm
@@ -3551,6 +3551,10 @@ and on MS Windows it is &quot;;&quot;).
 </li>
 </ul>
 <p>
+'*' may be used as a wildcard in the above paths to mean "any
+character other than the directory separator. Do not use two
+or more *'s without intervening characters.
+<p>
 Finally, paths supplied on the command line (such as those in <code>-I</code>,
 <code>-sFONTPATH</code> parameters) are added to the permitted reading list.
 Similarly, paths read during initialisation from <code>Fontmap</code>, <code>cidfmap</code>,

----------------------------------------------------------------------
commit dd19ec5348723a5c70ff728911f856caa518166b
Author: Robin Watts <[email protected]>
Date:   Mon Sep 23 16:41:09 2019 +0100

    Improve OutputFile handling of %d etc.
    
    Only accept %d (and friends) (as opposed to anything starting with %).
    Only accept legal combinations of flags/widths/precision etc.
    Generate a more conservative wildcard.

diff --git a/base/gslibctx.c b/base/gslibctx.c
index e7af870..8895ff2 100644
--- a/base/gslibctx.c
+++ b/base/gslibctx.c
@@ -577,6 +577,64 @@ gs_check_file_permission (gs_memory_t *mem, const char *fname, const int len, co
     return code;
 }
 
+static int
+rewrite_percent_specifiers(char *s)
+{
+    char *match_start;
+
+    while (*s)
+    {
+        int flags;
+        /* Find a % */
+        while (*s && *s != '%')
+            s++;
+        if (*s == 0)
+            return 0;
+        match_start = s;
+        s++;
+        /* Skip over flags (just one instance of any given flag, in any order) */
+        flags = 0;
+        while (*s) {
+            if (*s == '-' && (flags & 1) == 0)
+                flags |= 1;
+            else if (*s == '+' && (flags & 2) == 0)
+                flags |= 2;
+            else if (*s == ' ' && (flags & 4) == 0)
+                flags |= 4;
+            else if (*s == '0' && (flags & 8) == 0)
+                flags |= 8;
+            else if (*s == '#' && (flags & 16) == 0)
+                flags |= 16;
+            else
+                break;
+            s++;
+        }
+        /* Skip over width */
+        while (*s >= '0' && *s <= '9')
+            s++;
+        /* Skip over .precision */
+        if (*s == '.' && s[1] >= '0' && s[1] <= '9') {
+            s++;
+            while (*s >= '0' && *s <= '9')
+                s++;
+        }
+        /* Skip over 'l' */
+        if (*s == 'l')
+            s++;
+        if (*s == 'd' ||
+            *s == 'i' ||
+            *s == 'u' ||
+            *s == 'o' ||
+            *s == 'x' ||
+            *s == 'X') {
+            /* Success! */
+            memset(match_start, '*', s - match_start + 1);
+            return 1;
+        }
+    }
+    return 0;
+}
+
 /* For the OutputFile permission we have to deal with formattable strings
    i.e. ones that have "%d" or similar in them. For these we want to replace
    everything after the %d with a wildcard "*".
@@ -587,18 +645,18 @@ gs_check_file_permission (gs_memory_t *mem, const char *fname, const int len, co
 int
 gs_add_outputfile_control_path(gs_memory_t *mem, const char *fname)
 {
-    char *fp, f[gp_file_name_sizeof] = {0};
-    const int percent = 37; /* ASCII code for '%' */
+    char *fp, f[gp_file_name_sizeof];
     const int pipe = 124; /* ASCII code for '|' */
     const int len = strlen(fname);
 
-    strncpy(f, fname, len);
-    fp = strchr(f, percent);
-    if (fp != NULL) {
-        fp[0] = '*';
-        fp[1] = '\0';
-        fp = f;
-    } else {
+    /* Be sure the string copy will fit */
+    if (len >= gp_file_name_sizeof)
+        return gs_error_rangecheck;
+    strcpy(f, fname);
+    fp = f;
+    /* Try to rewrite any %d (or similar) in the string */
+    if (!rewrite_percent_specifiers(f)) {
+        /* No %d found, so check for pipes */
         int i;
         fp = f;
         for (i = 0; i < len; i++) {

----------------------------------------------------------------------
commit da7486fc4b00eee956200d45fb340dc62c8e3bcb
Author: Ray Johnston <[email protected]>
Date:   Fri Sep 20 12:38:02 2019 -0700

    Slight improvement to "permit-file-***" parameter documentation.

diff --git a/doc/Use.htm b/doc/Use.htm
index d4639ad..1c5b259 100644
--- a/doc/Use.htm
+++ b/doc/Use.htm
@@ -3525,25 +3525,25 @@ in that it now supports (although does not enforce) case sensitivity.
 Four command line parameters permit explicit control of the paths included in
 the access control lists:
 <ul>
-<li><dt><code>--permit-file-read<code></dt>
+<li><dt><code>--permit-file-read=<code><em>pathlist</em></dt>
 <p> Adds a path, or list of paths, to the "permit read" list. A list
 of paths is a series of paths separated by the appropriate path list separator
 for your platform (for example, on Unix-like systems it is &quot;&colon;&quot;
 and on MS Windows it is &quot;;&quot;).
 </li>
-<li><dt><code>--permit-file-write<code></dt>
+<li><dt><code>--permit-file-write=<code><em>pathlist</em></dt>
 <p> Adds a path, or list of paths, to the "permit write" list. A list
 of paths is a series of paths separated by the appropriate path list separator
 for your platform (for example, on Unix-like systems it is &quot;&colon;&quot;
 and on MS Windows it is &quot;;&quot;).
 </li>
-<li><dt><code>--permit-file-control<code></dt>
+<li><dt><code>--permit-file-control=<code><em>pathlist</em></dt>
 <p> Adds a path, or list of paths, to the "permit control" list. A list
 of paths is a series of paths separated by the appropriate path list separator
 for your platform (for example, on Unix-like systems it is &quot;&colon;&quot;
 and on MS Windows it is &quot;;&quot;).
 </li>
-<li><dt><code>--permit-file-all<code></dt>
+<li><dt><code>--permit-file-all=<code><em>pathlist</em></dt>
 <p> Adds a path, or list of paths, to the all the above lists. A list
 of paths is a series of paths separated by the appropriate path list separator
 for your platform (for example, on Unix-like systems it is &quot;&colon;&quot;

----------------------------------------------------------------------
commit 0222263e4fe03b29e9eb4141f7866fa8261d416a
Author: Ray Johnston <[email protected]>
Date:   Fri Sep 20 11:17:53 2019 -0700

    Fix tiffsep and tiffsep1 with new file access control and SAFER mode
    
    The tiffsep and tiffsep1 synthesize output file names with the outputfile
    and the separation color name, but the 'open' of these filenames would
    fail since they were not included on the permit_file_writing list.
    Add the full filename before opening, and remove the names after closing.

diff --git a/devices/gdevtsep.c b/devices/gdevtsep.c
index d40f074..ec01fb3 100644
--- a/devices/gdevtsep.c
+++ b/devices/gdevtsep.c
@@ -1360,6 +1360,8 @@ tiffsep1_prn_close(gx_device * pdev)
                 goto done;
             }
             code = gx_device_close_output_file(pdev, name, tfdev->sep_file[comp_num]);
+            if (code >= 0)
+                code = gs_remove_control_path(pdev->memory, gs_permit_file_writing, name);
             if (code < 0) {
                 goto done;
             }
@@ -1868,6 +1870,8 @@ tiffsep_prn_close(gx_device * pdev)
                 goto done;
             }
             code = tiffsep_close_sep_file(pdevn, name, comp_num);
+            if (code >= 0)
+                code = gs_remove_control_path(pdevn->memory, gs_permit_file_writing, name);
             if (code < 0) {
                 goto done;
             }
@@ -2402,11 +2406,17 @@ tiffsep_print_page(gx_device_printer * pdev, gp_file * file)
              */
             if (tfdev->sep_file[comp_num] != NULL && fmt != NULL) {
                 code = tiffsep_close_sep_file(tfdev, name, comp_num);
+                if (code >= 0)
+                    code = gs_remove_control_path(tfdev->memory, gs_permit_file_writing, name);
                 if (code < 0)
                     return code;
             }
             /* Open the separation file, if not already open */
             if (tfdev->sep_file[comp_num] == NULL) {
+                code = gs_add_control_path(tfdev->memory, gs_permit_file_writing, name);
+                if (code < 0) {
+                    goto done;
+                }
                 code = gx_device_open_output_file((gx_device *)pdev, name,
                     true, true, &(tfdev->sep_file[comp_num]));
                 if (code < 0) {
@@ -2626,6 +2636,8 @@ cleanup:
                         continue;
                     }
                     code = tiffsep_close_sep_file(tfdev, name, comp_num);
+                    if (code >= 0)
+                        code = gs_remove_control_path(tfdev->memory, gs_permit_file_writing, name);
                     if (code < 0) {
                         code1 = code;
                     }
@@ -2738,6 +2750,10 @@ tiffsep1_print_page(gx_device_printer * pdev, gp_file * file)
 
         /* Open the separation file, if not already open */
         if (tfdev->sep_file[comp_num] == NULL) {
+            code = gs_add_control_path(tfdev->memory, gs_permit_file_writing, name);
+            if (code < 0) {
+                goto done;
+            }
             code = gx_device_open_output_file((gx_device *)pdev, name,
                     true, true, &(tfdev->sep_file[comp_num]));
             if (code < 0) {
@@ -2896,6 +2912,8 @@ tiffsep1_print_page(gx_device_printer * pdev, gp_file * file)
                     continue;
                 }
                 code = tiffsep_close_sep_file((tiffsep_device *)tfdev, name, comp_num);
+                if (code >= 0)
+                    code = gs_remove_control_path(tfdev->memory, gs_permit_file_writing, name);
                 if (code < 0) {
                     code1 = code;
                 }

----------------------------------------------------------------------
commit 0e7039d7a83a7e35b8b41d59d7fb9a8b4fda7fb0
Author: Robin Watts <[email protected]>
Date:   Fri Sep 20 17:49:57 2019 +0100

    Fix "permit-file-xxxx" handling.
    
    Ray spotted that gs_add_explicit_control_path was adding 17
    to arg before using it. 17 happens to be the right amount
    to add for "--permit-file-read=", but the wrong amount for
    write/control/all.
    
    Update the code to call it with the correct arg pointer
    to start with.
    
    Also, update a couple of routines to cope with being called
    with NULL strings.
    
    Also use enum values in switch rather than 0, 1, 2.

diff --git a/base/gslibctx.c b/base/gslibctx.c
index a72a81d..e7af870 100644
--- a/base/gslibctx.c
+++ b/base/gslibctx.c
@@ -627,10 +627,13 @@ gs_add_outputfile_control_path(gs_memory_t *mem, const char *fname)
 int
 gs_add_explicit_control_path(gs_memory_t *mem, const char *arg, gs_path_control_t control)
 {
-    char *p2, *p1 = (char *)arg + 17;
-    const char *lim = arg + strlen(arg);
+    char *p2, *p1 = (char *)arg;
+    const char *lim;
     int code = 0;
 
+    if (arg == NULL)
+        return 0;
+    lim = arg + strlen(arg);
     while (code >= 0 && p1 < lim && (p2 = strchr(p1, (int)gp_file_name_list_separator)) != NULL) {
         code = gs_add_control_path_len(mem, control, p1, (int)(p2 - p1));
         p1 = p2 + 1;
@@ -649,18 +652,21 @@ gs_add_control_path_len(const gs_memory_t *mem, gs_path_control_t type, const ch
     char *buffer;
     uint rlen;
 
+    if (path == NULL || len == 0)
+        return 0;
+
     if (mem == NULL || mem->gs_lib_ctx == NULL ||
         (core = mem->gs_lib_ctx->core) == NULL)
         return gs_error_unknownerror;
 
     switch(type) {
-        case 0:
+        case gs_permit_file_reading:
             control = &core->permit_reading;
             break;
-        case 1:
+        case gs_permit_file_writing:
             control = &core->permit_writing;
             break;
-        case 2:
+        case gs_permit_file_control:
             control = &core->permit_control;
             break;
         default:
@@ -714,6 +720,9 @@ gs_add_control_path_len(const gs_memory_t *mem, gs_path_control_t type, const ch
 int
 gs_add_control_path(const gs_memory_t *mem, gs_path_control_t type, const char *path)
 {
+    if (path == NULL)
+        return 0;
+
     return gs_add_control_path_len(mem, type, path, strlen(path));
 }
 
@@ -726,6 +735,9 @@ gs_remove_control_path_len(const gs_memory_t *mem, gs_path_control_t type, const
     char *buffer;
     uint rlen;
 
+    if (path == NULL || len == 0)
+        return 0;
+
     if (mem == NULL || mem->gs_lib_ctx == NULL ||
         (core = mem->gs_lib_ctx->core) == NULL)
         return gs_error_unknownerror;
@@ -774,6 +786,9 @@ gs_remove_control_path_len(const gs_memory_t *mem, gs_path_control_t type, const
 int
 gs_remove_control_path(const gs_memory_t *mem, gs_path_control_t type, const char *path)
 {
+    if (path == NULL)
+        return 0;
+
     return gs_remove_control_path_len(mem, type, path, strlen(path));
 }
 
diff --git a/pcl/pl/plmain.c b/pcl/pl/plmain.c
index 73f45fe..ff89da2 100644
--- a/pcl/pl/plmain.c
+++ b/pcl/pl/plmain.c
@@ -1323,6 +1323,24 @@ pl_main_set_string_param(pl_main_instance_t * pmi, const char *arg)
 }
 
 static int
+do_arg_match(const char **arg, const char *match, size_t match_len)
+{
+    const char *s = *arg;
+    if (strncmp(s, match, match_len) != 0)
+        return 0;
+    s += match_len;
+    if (*s == '=')
+        *arg = ++s;
+    else if (*s != 0)
+        return 0;
+    else
+        *arg = NULL;
+    return 1;
+}
+
+#define arg_match(A, B) do_arg_match(A, B, sizeof(B)-1)
+
+static int
 pl_main_process_options(pl_main_instance_t * pmi, arg_list * pal,
                         pl_interp_implementation_t * pjli)
 {
@@ -1422,19 +1440,19 @@ pl_main_process_options(pl_main_instance_t * pmi, arg_list * pal,
                     break;
                 }
                 /* Now handle the explicitly added paths to the file control lists */
-                else if (strncmp(arg, "permit-file-read", 16) == 0) {
+                else if (arg_match(&arg, "permit-file-read")) {
                     code = gs_add_explicit_control_path(pmi->memory, arg, gs_permit_file_reading);
                     if (code < 0) return code;
                     break;
-                } else if (strncmp(arg, "permit-file-write", 17) == 0) {
+                } else if (arg_match(&arg, "permit-file-write")) {
                     code = gs_add_explicit_control_path(pmi->memory, arg, gs_permit_file_writing);
                     if (code < 0) return code;
                     break;
-                } else if (strncmp(arg, "permit-file-control", 19) == 0) {
+                } else if (arg_match(&arg, "permit-file-control")) {
                     code = gs_add_explicit_control_path(pmi->memory, arg, gs_permit_file_control);
                     if (code < 0) return code;
                     break;
-                } else if (strncmp(arg, "permit-file-all", 15) == 0) {
+                } else if (arg_match(&arg, "permit-file-all")) {
                     code = gs_add_explicit_control_path(pmi->memory, arg, gs_permit_file_reading);
                     if (code < 0) return code;
                     code = gs_add_explicit_control_path(pmi->memory, arg, gs_permit_file_writing);
diff --git a/psi/imainarg.c b/psi/imainarg.c
index d22d3ca..76653f3 100644
--- a/psi/imainarg.c
+++ b/psi/imainarg.c
@@ -315,6 +315,23 @@ gs_main_run_start(gs_main_instance * minst)
     return run_string(minst, "systemdict /start get exec", runFlush, minst->user_errors, NULL, NULL);
 }
 
+static int
+do_arg_match(const char **arg, const char *match, size_t match_len)
+{
+    const char *s = *arg;
+    if (strncmp(s, match, match_len) != 0)
+        return 0;
+    s += match_len;
+    if (*s == '=')
+        *arg = ++s;
+    else if (*s != 0)
+        return 0;
+    else
+        *arg = NULL;
+    return 1;
+}
+
+#define arg_match(A, B) do_arg_match(A, B, sizeof(B)-1)
 
 /* Process switches.  Return 0 if processed, 1 for unknown switch, */
 /* <0 if error. */
@@ -436,19 +453,19 @@ run_stdin:
                 minst->saved_pages_test_mode = true;
                 break;
             /* Now handle the explicitly added paths to the file control lists */
-            } else if (strncmp(arg, "permit-file-read", 16) == 0) {
+            } else if (arg_match(&arg, "permit-file-read")) {
                 code = gs_add_explicit_control_path(minst->heap, arg, gs_permit_file_reading);
                 if (code < 0) return code;
                 break;
-            } else if (strncmp(arg, "permit-file-write", 17) == 0) {
+            } else if (arg_match(&arg, "permit-file-write")) {
                 code = gs_add_explicit_control_path(minst->heap, arg, gs_permit_file_writing);
                 if (code < 0) return code;
                 break;
-            } else if (strncmp(arg, "permit-file-control", 19) == 0) {
+            } else if (arg_match(&arg, "permit-file-control")) {
                 code = gs_add_explicit_control_path(minst->heap, arg, gs_permit_file_control);
                 if (code < 0) return code;
                 break;
-            } else if (strncmp(arg, "permit-file-all", 15) == 0) {
+            } else if (arg_match(&arg, "permit-file-all")) {
                 code = gs_add_explicit_control_path(minst->heap, arg, gs_permit_file_reading);
                 if (code < 0) return code;
                 code = gs_add_explicit_control_path(minst->heap, arg, gs_permit_file_writing);

----------------------------------------------------------------------
commit 18316aba11fafc57ee77dbd7774b2c88b964a9d9
Author: Chris Liddell <[email protected]>
Date:   Thu Sep 19 11:02:48 2019 +0100

    Make missing jbig2 decoder fatal error.
    
    If we have neither Luratech nor jbig2dec, have configure fail, unless
    explicitly run with --without-jbig2dec

diff --git a/configure.ac b/configure.ac
index c5ddefe..3b72367 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1621,6 +1621,7 @@ if test x$with_luratech != xno; then
 fi
 
 JB2_STDINT_TYPES_IN=
+JBIG2DEC_REQ=0.16
 
 if test "x$JBIG2_DECODER" = x; then
   dnl look for jbig2dec
@@ -1680,7 +1681,6 @@ if test "x$JBIG2_DECODER" = x; then
       # autoconf macro and b) requires pkg-config on the system, which is
       # NOT standard on ANY OS, including Linux!
       if test "x$PKGCONFIG" != x; then
-        JBIG2DEC_REQ=0.16
         AC_MSG_CHECKING(for jbig2dec $JBIG2DEC_REQ with pkg-config)
         if $PKGCONFIG --atleast-version=$JBIG2DEC_REQ jbig2dec; then
           AC_MSG_RESULT(yes)
@@ -1688,17 +1688,14 @@ if test "x$JBIG2_DECODER" = x; then
           JBIG2DEC_LIBS="`$PKGCONFIG --libs jbig2dec`"
           SHARE_JBIG2=1
         else
-          AC_MSG_RESULT(no)
-          AC_MSG_WARN([disabling support for JBIG2 files])
-          with_jbig2dec=no
+          AC_MSG_ERROR([jbig2 decoder not found, or too old])
         fi
       else
         AC_MSG_CHECKING(for jbig2dec library)
         AC_CHECK_LIB([jbig2dec], [jbig2_page_out], [
             SHARE_JBIG2=1
         ], [
-            AC_MSG_WARN([disabling support for JBIG2 files])
-            with_jbig2dec=no
+            AC_MSG_ERROR([jbig2 decoder not found, or too old])
         ])
       fi
       if test x$with_jbig2dec != xno; then


Summary of changes:
 Resource/Init/gs_init.ps        |  65 ++++++----
 base/gpmisc.c                   |  65 +++++-----
 base/gscdefs.h                  |   2 +-
 base/gsdevice.c                 |   5 +-
 base/gslibctx.c                 | 141 +++++++++++++++++++---
 base/gslibctx.h                 |   3 +
 base/gstiffio.c                 |   8 ++
 base/sfxcommon.c                |  11 +-
 base/version.mak                |   2 +-
 configure.ac                    |   9 +-
 devices/gdevtsep.c              |  52 ++++++--
 doc/DLL.htm                     |   2 +-
 doc/Deprecated.htm              |   2 +-
 doc/Develop.htm                 |   2 +-
 doc/Devices.htm                 |   2 +-
 doc/Drivers.htm                 |   2 +-
 doc/Fonts.htm                   |   2 +-
 doc/History9.htm                | 255 +++++++++++++++++++++++++++++++++++++++-
 doc/Install.htm                 |   2 +-
 doc/Internal.htm                |   2 +-
 doc/Language.htm                |   2 +-
 doc/Lib.htm                     |   2 +-
 doc/Make.htm                    |   2 +-
 doc/News.htm                    |   4 +-
 doc/Ps-style.htm                |   2 +-
 doc/Ps2epsi.htm                 |   2 +-
 doc/Psfiles.htm                 |   2 +-
 doc/Readme.htm                  |   2 +-
 doc/Release.htm                 |   2 +-
 doc/SavedPages.htm              |   2 +-
 doc/Source.htm                  |   2 +-
 doc/Unix-lpr.htm                |   2 +-
 doc/Use.htm                     |  14 ++-
 doc/VectorDevices.htm           |   2 +-
 doc/WhatIsGS.htm                |   2 +-
 doc/gs-vms.hlp                  |   2 +-
 doc/sample_downscale_device.htm |   2 +-
 doc/subclass.htm                |   2 +-
 doc/thirdparty.htm              |   2 +-
 man/dvipdf.1                    |   2 +-
 man/gs.1                        |   2 +-
 man/gslp.1                      |   2 +-
 man/gsnd.1                      |   2 +-
 man/pdf2dsc.1                   |   2 +-
 man/pdf2ps.1                    |   2 +-
 man/pf2afm.1                    |   2 +-
 man/pfbtopfa.1                  |   2 +-
 man/printafm.1                  |   2 +-
 man/ps2ascii.1                  |   2 +-
 man/ps2epsi.1                   |   2 +-
 man/ps2pdf.1                    |   2 +-
 man/ps2pdfwr.1                  |   2 +-
 man/ps2ps.1                     |   2 +-
 pcl/pl/plmain.c                 |  26 +++-
 psi/imainarg.c                  |  25 +++-
 psi/zfile.c                     |  16 +++
 56 files changed, 632 insertions(+), 149 deletions(-)