Commit e48e96ca authored by J0WI's avatar J0WI Committed by Kevin Daudt
Browse files

main/ghostscript: upgrade to 9.50

Closes GH-11934
parent 8f1b5873
From 0bafbd9c1273fab0dc79fd20db0ffc4443683f96 Mon Sep 17 00:00:00 2001
From: Ken Sharp <ken.sharp@artifex.com>
Date: Mon, 29 Apr 2019 11:14:06 +0100
Subject: [PATCH] PDF interpreter - Decode ToUnicode entries of the form
/Identity-H/V
Bug #701003 "Text searchability broken due to omission of /ToUnicode /Identity-H"
The PDF references from 1.2 too 2.0 all state that the value associated
with a ToUnicode key in a FontDescriptor must be a stream object. However
this file (and one case seen previously, bug 687351) have FontDescriptor
dictionaries where the value associated with a /ToUnicode key is a
name object, in both cases /Identity-H.
Although this is clearly not legal, Acrobat not only tolerates it, it
actually uses it for search/copy/paste (see bug 701003 for details).
Without the key Acrobat is unable to successfully search the output file.
We can't simply preserve the name object as a ToUnicode value; when
handling ToUnicode we actually decode the CMap and build a
GlyphNames2Unicode map (an internal representation of the G2U data
produced by the Microsoft PostScript printer driver). When writing the
output file we use that information to get a Unicode value for each
character we write, and build a new ToUnicode CMap using that.
This commit tackles the problem by pre-scanning for a name object and
then checking to see if its Identity-H or Identity-V (although we have
not seen an Identity-V, there seems no reason why it wouldn't be
equally valid). If we find either of these then we construct a
GlyphNames2Unicode table for all possible values (0 - 65535) and store
that with the font as normal. When we write the output file we only
write the required entries for the subset font, so we write a now
completely legal ToUnicode CMap, and Acrobat is equally happy with that
as the original name.
If the ToUnicode value isn't a name object, or isn't one of the
identities then we proceed as before. This means we will print a
warning for non conforming ToUnicode entries and ignore them.
---
Resource/Init/pdf_font.ps | 200 ++++++++++++++++++++++++--------------
1 file changed, 129 insertions(+), 71 deletions(-)
diff --git a/Resource/Init/pdf_font.ps b/Resource/Init/pdf_font.ps
index 0e802d393..964d54c1e 100644
--- a/Resource/Init/pdf_font.ps
+++ b/Resource/Init/pdf_font.ps
@@ -621,86 +621,144 @@ currentdict end readonly def
PDFDEBUG {
(.processToUnicode beg) =
} if
- 2 index /ToUnicode knownoget {
- dup type /dicttype eq { dup /File known not } { //true } ifelse {
- % We undefine wrong /Length and define /File in stream dictionaries.
- % Bug687351.pdf defines /ToUnicode /Identity-H, what is incorrect.
- ( **** Warning: Ignoring bad ToUnicode CMap.\n) pdfformatwarning
- pop
+
+ 2 index /ToUnicode knownoget
+ {
+ dup type /nametype eq {
+ % This is contrary to the specification but it seems that Acrobat at least will accept
+ % a ToUnicode with a value of Identity-H *and* will use that for search, copy/paste.
+ % We can't pass through a name, so the best we can do is build a GlyphNames2Unicode
+ % map matching that which would have been generated by a full 16-bit Identity CMap
+ %
+ % See bug numbers 701003 and 687351
+ %
+ dup /Identity-H eq 1 index /Identity-V eq or{
+ pop
+ 1 index /FontInfo .knownget not {
+ currentglobal 2 index dup gcheck setglobal
+ /FontInfo 5 dict dup 5 1 roll .forceput
+ setglobal
+ } if
+ dup /GlyphNames2Unicode .knownget not {
+ //true % No existing G2U, make one
+ } {
+ dup wcheck {
+ //false % Existing, writeable G2U, don't make new one
+ } {
+ pop //true % Existing read only G2U, make new one
+ } ifelse
+ } ifelse
+ {
+ currentglobal exch dup gcheck setglobal
+ dup /GlyphNames2Unicode 100 dict dup 4 1 roll .forceput
+ 3 2 roll setglobal
+ } if % font-res font-dict encoding|null font-info g2u
+
+ 0 1 65535{
+ % g2u index
+ dup dup 256 mod exch 256 idiv % g2u index lo-byte hi-byte
+ 2 string dup 0 4 -1 roll % g2u index lo-byte () () 0 hi-byte
+ put % g2u index lo-byte (x)
+ dup 1 % g2u index lo-byte (x) (x) 1
+ 4 -1 roll put % g2u index (x) (x) 1 lo-byte -> dict index (xx)
+ 2 index % g2u index (xx) dict
+ 3 1 roll % g2u g2u index (xx)
+ put % g2u
+ } for
+ pop % font-res font-dict encoding|null font-info
+ pop % font-res font-dict encoding|null
+ //false % We built a GlyphNames2Unicode table, don't need to process further
+ }{
+ //true % name is not Identity-V or H, fail by falling through
+ }ifelse
} {
- /PDFScanRules .getuserparam dup //null eq {
- pop //PDFScanRules_null
- } {
- 1 dict dup /PDFScanRules 4 -1 roll put
- } ifelse
- //PDFScanRules_true setuserparams
- PDFfile fileposition
- 3 -1 roll
- count 1 sub
- countdictstack
- { //false resolvestream
- % Following Acrobat we ignore everything outside
- % begincodespacerange .. endcmap.
- dup 0 (begincodespacerange) /SubFileDecode filter flushfile
- /CIDInit /ProcSet findresource begin
- //ToUnicodeCMapReader begin
- 12 dict begin
- /CMapType 2 def
- mark exch % emulate 'begincodespacerange'
- 0 (endcmap) /SubFileDecode filter cvx /begincmap cvx exch 2 .execn
- endcmap
- userdict /.lastToUnicode currentdict put
- end end end
- }
+ //true
+ } ifelse % not a name, try as a dictionary (as specified)
- PDFSTOPONERROR {
- { exec } 0 get
- //false
- 5 -2 roll
- 5
+ % If the ToUnicode isn't a name, or the name isn't Identity-V or -H then follow the specification
+ % If its not a dictionary type throw an error, otherwise decode it and build a GlyphNames2Unicode
+ %
+ {
+ dup type /dicttype eq { dup /File known not } { //true } ifelse {
+ % We undefine wrong /Length and define /File in stream dictionaries.
+ % Bug687351.pdf defines /ToUnicode /Identity-H, what is incorrect.
+ ( **** Warning: Ignoring bad ToUnicode CMap.\n) pdfformatwarning
+ pop
} {
- { stopped } 0 get
- 4 2 roll
- 4
- } ifelse
- array astore cvx exec
+ /PDFScanRules .getuserparam dup //null eq {
+ pop //PDFScanRules_null
+ } {
+ 1 dict dup /PDFScanRules 4 -1 roll put
+ } ifelse
+ //PDFScanRules_true setuserparams
+ PDFfile fileposition
+ 3 -1 roll
+ count 1 sub
+ countdictstack
+ { //false resolvestream
+ % Following Acrobat we ignore everything outside
+ % begincodespacerange .. endcmap.
+ dup 0 (begincodespacerange) /SubFileDecode filter flushfile
+ /CIDInit /ProcSet findresource begin
+ //ToUnicodeCMapReader begin
+ 12 dict begin
+ /CMapType 2 def
+ mark exch % emulate 'begincodespacerange'
+ 0 (endcmap) /SubFileDecode filter cvx /begincmap cvx exch 2 .execn
+ endcmap
+ userdict /.lastToUnicode currentdict put
+ end end end
+ }
- countdictstack exch sub 0 .max { end } repeat
- count exch sub 2 sub 0 .max { exch pop } repeat
- 3 1 roll % Stach the stop flag.
- PDFfile exch setfileposition
- setuserparams
- {
- ( **** Warning: Failed to read ToUnicode CMap.\n) pdfformatwarning
- } {
- 1 index /FontInfo .knownget not {
- currentglobal 2 index dup gcheck setglobal
- /FontInfo 5 dict dup 5 1 roll .forceput
- setglobal
- } if
- dup /GlyphNames2Unicode .knownget not {
- //true % No existing G2U, make one
+ PDFSTOPONERROR {
+ { exec } 0 get
+ //false
+ 5 -2 roll
+ 5
+ } {
+ { stopped } 0 get
+ 4 2 roll
+ 4
+ } ifelse
+ array astore cvx exec
+
+ countdictstack exch sub 0 .max { end } repeat
+ count exch sub 2 sub 0 .max { exch pop } repeat
+ 3 1 roll % Stach the stop flag.
+ PDFfile exch setfileposition
+ setuserparams
+ {
+ ( **** Warning: Failed to read ToUnicode CMap.\n) pdfformatwarning
} {
- dup wcheck {
- //false % Existing, writeable G2U, don't make new one
+ 1 index /FontInfo .knownget not {
+ currentglobal 2 index dup gcheck setglobal
+ /FontInfo 5 dict dup 5 1 roll .forceput
+ setglobal
+ } if
+ dup /GlyphNames2Unicode .knownget not {
+ //true % No existing G2U, make one
} {
- pop //true % Existing read only G2U, make new one
+ dup wcheck {
+ //false % Existing, writeable G2U, don't make new one
+ } {
+ pop //true % Existing read only G2U, make new one
+ } ifelse
} ifelse
+ {
+ currentglobal exch dup gcheck setglobal
+ dup /GlyphNames2Unicode 100 dict dup 4 1 roll .forceput
+ 3 2 roll setglobal
+ } if % font-res font-dict encoding|null font-info g2u
+ exch pop exch % font-res font-dict g2u encoding|null
+ userdict /.lastToUnicode get % font-res font-dict g2u Encoding|null CMap
+ .convert_ToUnicode-into-g2u % font-res font-dict
+ //null % font-res font-dict //null
} ifelse
- {
- currentglobal exch dup gcheck setglobal
- dup /GlyphNames2Unicode 100 dict dup 4 1 roll .forceput
- 3 2 roll setglobal
- } if % font-res font-dict encoding|null font-info g2u
- exch pop exch % font-res font-dict g2u encoding|null
- userdict /.lastToUnicode get % font-res font-dict g2u Encoding|null CMap
- .convert_ToUnicode-into-g2u % font-res font-dict
- //null % font-res font-dict //null
} ifelse
- } ifelse
- } if
- PDFDEBUG {
- (.processToUnicode end) =
+ } if
+ PDFDEBUG {
+ (.processToUnicode end) =
+ } if
} if
} if
} stopped
--
2.23.0
# Contributor: Cameron Banta <cbanta@gmail.com>
# Maintainer: Cameron Banta <cbanta@gmail.com>
pkgname=ghostscript
pkgver=9.27
pkgrel=4
pkgver=9.50
pkgrel=0
pkgdesc="An interpreter for the PostScript language and for PDF"
url="https://ghostscript.com/"
arch="all"
......@@ -13,13 +13,8 @@ makedepends="autoconf automake libjpeg-turbo-dev libpng-dev expat-dev
cups-dev libtool jbig2dec-dev openjpeg-dev"
subpackages="$pkgname-dbg $pkgname-doc $pkgname-dev $pkgname-gtk"
source="https://github.com/ArtifexSoftware/ghostpdl-downloads/releases/download/gs${pkgver/./}/ghostscript-$pkgver.tar.gz
https://github.com/ArtifexSoftware/ghostpdl-downloads/releases/download/gs926/0001-Bug700317-Address-.force-operators-exposure.tgz
ghostscript-system-zlib.patch
fix-sprintf.patch
CVE-2019-10216.patch
forceput-inaccessible.patch
0001-PDF-interpreter-Decode-ToUnicode-entries-of-the-form.patch
CVE-2019-14817.patch
"
# secfixes:
......@@ -135,11 +130,6 @@ gtk() {
mv "$pkgdir"/usr/bin/gsx "$subpkgdir"/usr/bin/
}
sha512sums="9ad7bd24b6d9b7d258e943783817be036a2e0234517baffa1016804ef9b6f3062fb5da20a890a0bfc9e58203ddcf25dc4465f5b3bf5e4a61db87bef0606a0884 ghostscript-9.27.tar.gz
289d916a0b0da410e6f721e42bc44659c91c66ca0f7b96b1a6b010ae1c25e47788e282edc3578b4e4b120a2c684c7b1fd4cc574084bdc9cbbf6e431a01fbae0e 0001-Bug700317-Address-.force-operators-exposure.tgz
sha512sums="acee64fae78771bffa19b0b2bfaba3c345b420f93ceb4fc9df5fb705f785c8ed720fde2aef53546fac6aca2f7366c64c68a6e373a71999a42dc71aadc9aa782f ghostscript-9.50.tar.gz
70721e3a335afa5e21d4e6cf919119010bd4544a03ab8f53f5325c173902221ad9b88c118b4bfeee80b3e1956bcdbaf4c53f64ae7fb81f5ba57dbc956750c482 ghostscript-system-zlib.patch
beefcf395f7f828e1b81c088022c08a506e218f27535b9de01e0f0edf7979b435316c318fa676771630f6ad16ff1ab059cd68aa128ed97e5a9f2f3fa840200c4 fix-sprintf.patch
f89744b17922b7d9c04c6de69ce35fa621732e4373eccc158b7ff6a9e56d2cf0bbea30c28119f4808864ca584e94342e5125d7bcc6195252455b5f223f379e3f CVE-2019-10216.patch
d7045aa5a02a3fc882552da0b9a60ea565a36d5d038cdf576dc7188158dc05a470ce9fa40bdf1e1003a48995f6707431980910372da549918caf789eb3a2f81f forceput-inaccessible.patch
0ec65d29eb7ade7a8c02190fc5358faf257f63dc50b30d222b231aed496c8ac1fb7c0710e78117e10a16886dfcaccab610afb434efbbd557f63396c12ccd5d64 0001-PDF-interpreter-Decode-ToUnicode-entries-of-the-form.patch
deed829b14223b2f99d49aea5575c9ad855f6815d238502d3109849acac239eb312fd89e802e12a85fe7e92375694c42422240a6e1759ecfd094762eccaed826 CVE-2019-14817.patch"
beefcf395f7f828e1b81c088022c08a506e218f27535b9de01e0f0edf7979b435316c318fa676771630f6ad16ff1ab059cd68aa128ed97e5a9f2f3fa840200c4 fix-sprintf.patch"
From 5b85ddd19a8420a1bd2d5529325be35d78e94234 Mon Sep 17 00:00:00 2001
From: Chris Liddell <chris.liddell@artifex.com>
Date: Fri, 2 Aug 2019 15:18:26 +0100
Subject: [PATCH] Bug 701394: protect use of .forceput with executeonly
---
Resource/Init/gs_type1.ps | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/Resource/Init/gs_type1.ps b/Resource/Init/gs_type1.ps
index 6c7735b..a039cce 100644
--- a/Resource/Init/gs_type1.ps
+++ b/Resource/Init/gs_type1.ps
@@ -118,25 +118,25 @@
( to be the same as glyph: ) print 1 index //== exec } if
3 index exch 3 index .forceput
% scratch(string) RAGL(dict) AGL(dict) CharStrings(dict) cstring gname
- }
+ }executeonly
{pop} ifelse
- } forall
+ } executeonly forall
pop pop
- }
+ } executeonly
{
pop pop pop
} ifelse
- }
+ } executeonly
{
% scratch(string) RAGL(dict) AGL(dict) CharStrings(dict) cstring gname
pop pop
} ifelse
- } forall
+ } executeonly forall
3 1 roll pop pop
- } if
+ } executeonly if
pop
dup /.AGLprocessed~GS //true .forceput
- } if
+ } executeonly if
%% We need to excute the C .buildfont1 in a stopped context so that, if there
%% are errors we can put the stack back sanely and exit. Otherwise callers won't
--
2.9.1
From cd1b1cacadac2479e291efe611979bdc1b3bdb19 Mon Sep 17 00:00:00 2001
From: Ken Sharp <ken.sharp@artifex.com>
Date: Wed, 21 Aug 2019 10:10:51 +0100
Subject: [PATCH] PDF interpreter - review .forceput security
Bug #701450 "Safer Mode Bypass by .forceput Exposure in .pdfexectoken"
By abusing the error handler it was possible to get the PDFDEBUG portion
of .pdfexectoken, which uses .forceput left readable.
Add an executeonly appropriately to make sure that clause isn't readable
no mstter what.
Review all the uses of .forceput searching for similar cases, add
executeonly as required to secure those. All cases in the PostScript
support files seem to be covered already.
---
Resource/Init/pdf_base.ps | 2 +-
Resource/Init/pdf_draw.ps | 14 +++++++-------
Resource/Init/pdf_font.ps | 29 ++++++++++++++++-------------
Resource/Init/pdf_main.ps | 6 +++---
Resource/Init/pdf_ops.ps | 11 ++++++-----
5 files changed, 33 insertions(+), 29 deletions(-)
diff --git a/Resource/Init/pdf_base.ps b/Resource/Init/pdf_base.ps
index 2e28cdd..02503ee 100644
--- a/Resource/Init/pdf_base.ps
+++ b/Resource/Init/pdf_base.ps
@@ -157,7 +157,7 @@ currentdict /num-chars-dict .undef
{
dup ==only () = flush
} ifelse % PDFSTEP
- } if % PDFDEBUG
+ } executeonly if % PDFDEBUG
2 copy .knownget {
exch pop exch pop exch pop exec
} {
diff --git a/Resource/Init/pdf_draw.ps b/Resource/Init/pdf_draw.ps
index 11eb485..fe3fc56 100644
--- a/Resource/Init/pdf_draw.ps
+++ b/Resource/Init/pdf_draw.ps
@@ -501,8 +501,8 @@ end
( Output may be incorrect.\n) pdfformaterror
//pdfdict /.gs_warning_issued //true .forceput
PDFSTOPONERROR { /gs /undefined signalerror } if
- } if
- }
+ } executeonly if
+ } executeonly
ifelse
} bind executeonly def
@@ -1152,7 +1152,7 @@ currentdict end readonly def
.setglobal
pdfformaterror
} executeonly ifelse
- }
+ } executeonly
{
currentglobal //pdfdict gcheck .setglobal
//pdfdict /.Qqwarning_issued //true .forceput
@@ -1160,8 +1160,8 @@ currentdict end readonly def
pdfformaterror
} executeonly ifelse
end
- } ifelse
- } loop
+ } executeonly ifelse
+ } executeonly loop
{
(\n **** Error: File has unbalanced q/Q operators \(too many q's\)\n Output may be incorrect.\n)
//pdfdict /.Qqwarning_issued .knownget
@@ -1175,14 +1175,14 @@ currentdict end readonly def
.setglobal
pdfformaterror
} executeonly ifelse
- }
+ } executeonly
{
currentglobal //pdfdict gcheck .setglobal
//pdfdict /.Qqwarning_issued //true .forceput
.setglobal
pdfformaterror
} executeonly ifelse
- } if
+ } executeonly if
pop
% restore pdfemptycount
diff --git a/Resource/Init/pdf_font.ps b/Resource/Init/pdf_font.ps
index da07da5..81b7af1 100644
--- a/Resource/Init/pdf_font.ps
+++ b/Resource/Init/pdf_font.ps
@@ -638,7 +638,7 @@ currentdict end readonly def
currentglobal 2 index dup gcheck setglobal
/FontInfo 5 dict dup 5 1 roll .forceput
setglobal
- } if
+ } executeonly if
dup /GlyphNames2Unicode .knownget not {
//true % No existing G2U, make one
} {
@@ -668,10 +668,12 @@ currentdict end readonly def
pop % font-res font-dict encoding|null font-info
pop % font-res font-dict encoding|null
//false % We built a GlyphNames2Unicode table, don't need to process further
- }{
+ } executeonly
+ {
//true % name is not Identity-V or H, fail by falling through
}ifelse
- } {
+ } executeonly
+ {
//true
} ifelse % not a name, try as a dictionary (as specified)
@@ -759,9 +761,9 @@ currentdict end readonly def
PDFDEBUG {
(.processToUnicode end) =
} if
- } if
- } if
- } stopped
+ } executeonly if
+ } executeonly if
+ } executeonly stopped
{
.dstackdepth 1 countdictstack 1 sub
{pop end} for
@@ -1298,19 +1300,20 @@ currentdict /eexec_pdf_param_dict .undef
//pdfdict /.Qqwarning_issued //true .forceput
} executeonly if
Q
- } repeat
+ } executeonly repeat
Q
- } PDFfile fileposition 2 .execn % Keep pdfcount valid.
+ } executeonly PDFfile fileposition 2 .execn % Keep pdfcount valid.
PDFfile exch setfileposition
- } ifelse
- } {
+ } executeonly ifelse
+ } executeonly
+ {
% PDF Type 3 fonts don't use .notdef
% d1 implementation adjusts the width as needed
0 0 0 0 0 0
pdfopdict /d1 get exec
} ifelse
end end
- } bdef
+ } executeonly bdef
dup currentdict Encoding .processToUnicode
currentdict end .completefont exch pop
} bind executeonly odef
@@ -2124,9 +2127,9 @@ currentdict /CMap_read_dict undef
(Will continue, but content may be missing.) = flush
} ifelse
} if
- } if
+ } executeonly if
/findresource cvx /undefined signalerror
- } loop
+ } executeonly loop
} bind executeonly odef
/buildCIDType0 { % <CIDFontType0-font-resource> buildCIDType0 <font>
diff --git a/Resource/Init/pdf_main.ps b/Resource/Init/pdf_main.ps
index 00d7e36..7690bae 100644
--- a/Resource/Init/pdf_main.ps
+++ b/Resource/Init/pdf_main.ps
@@ -2771,15 +2771,15 @@ currentdict /PDF2PS_matrix_key undef
.setglobal
pdfformaterror
} executeonly ifelse
- }
+ } executeonly
{
currentglobal //pdfdict gcheck .setglobal
//pdfdict /.Qqwarning_issued //true .forceput
.setglobal
pdfformaterror
} executeonly ifelse
- } if
- } if
+ } executeonly if
+ } executeonly if
pop
count PDFexecstackcount sub { pop } repeat
(after exec) VMDEBUG
diff --git a/Resource/Init/pdf_ops.ps b/Resource/Init/pdf_ops.ps
index a15c8c6..d594035 100644
--- a/Resource/Init/pdf_ops.ps
+++ b/Resource/Init/pdf_ops.ps
@@ -192,14 +192,14 @@ currentdict /gput_always_allow .undef
.setglobal
pdfformaterror
} executeonly ifelse
- }
+ } executeonly
{
currentglobal //pdfdict gcheck .setglobal
//pdfdict /.Qqwarning_issued //true .forceput
.setglobal
pdfformaterror
} executeonly ifelse
- } if
+ } executeonly if
} bind executeonly odef
% Save PDF gstate
@@ -446,11 +446,12 @@ currentdict /gput_always_allow .undef
dup type /booleantype eq {
.currentSMask type /dicttype eq {
.currentSMask /Processed 2 index .forceput
+ } executeonly
+ {
+ .setSMask
+ }ifelse
} executeonly
{
- .setSMask
- }ifelse
- }{
.setSMask
}ifelse
--
2.9.1
From 885444fcbe10dc42787ecb76686c8ee4dd33bf33 Mon Sep 17 00:00:00 2001
From: Ken Sharp <ken.sharp@artifex.com>
Date: Tue, 20 Aug 2019 10:10:28 +0100
Subject: [PATCH] make .forceput inaccessible
Bug #701343, #701344, #701345
More defensive programming. We don't want people to access .forecput
even though it is no longer sufficient to bypass SAFER. The exploit
in #701343 didn't work anyway because of earlier work to stop the error
handler being used, but nevertheless, prevent access to .forceput from
.setuserparams2.
---
Resource/Init/gs_lev2.ps | 6 +++---
Resource/Init/gs_pdfwr.ps | 4 ++--
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/Resource/Init/gs_lev2.ps b/Resource/Init/gs_lev2.ps
index 4cc7f82..0fd4164 100644
--- a/Resource/Init/gs_lev2.ps
+++ b/Resource/Init/gs_lev2.ps
@@ -158,7 +158,7 @@ end
{
pop pop
} ifelse
- } forall
+ } executeonly forall
% A context switch might have occurred during the above loop,
% causing the interpreter-level parameters to be reset.
% Set them again to the new values. From here on, we are safe,
@@ -229,9 +229,9 @@ end
{ pop pop
}
ifelse
- }
+ } executeonly