summaryrefslogtreecommitdiffstats
path: root/meta/recipes-extended/ghostscript/ghostscript/CVE-2019-14817-0001.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta/recipes-extended/ghostscript/ghostscript/CVE-2019-14817-0001.patch')
-rw-r--r--meta/recipes-extended/ghostscript/ghostscript/CVE-2019-14817-0001.patch270
1 files changed, 270 insertions, 0 deletions
diff --git a/meta/recipes-extended/ghostscript/ghostscript/CVE-2019-14817-0001.patch b/meta/recipes-extended/ghostscript/ghostscript/CVE-2019-14817-0001.patch
new file mode 100644
index 0000000000..c76e21caa6
--- /dev/null
+++ b/meta/recipes-extended/ghostscript/ghostscript/CVE-2019-14817-0001.patch
@@ -0,0 +1,270 @@
+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 1/2] 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.
+
+CVE: CVE-2019-14817
+Upstream-Status: Backport [git://git.ghostscript.com/ghostpdl.git]
+
+Signed-off-by: Stefan Ghinea <stefan.ghinea@windriver.com>
+---
+ 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 9fb85f6..2df3303 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.20.1
+