From b09cbe8e577fb14504932dc8d9096187ec4e0840 Mon Sep 17 00:00:00 2001
From: Ray Johnston <ray.johnston@artifex.com>
Date: Sun, 29 Mar 2020 15:32:36 -0700
Subject: [PATCH] Fix infinite loop in PDF interpreter 'pagespotcolors'
 procedure

The file tests_private/pdf/uploads/poc1_pdf_gs.pdf has the single page
Parent object as itself. This only showed up with "DeviceN" devices that
search the PDF for the number of spot colorants on the page.

Note that this file is broken in other respects since it has a /Count
of 9 pages, but only a single page. This change also adds handling for
the //null object returned when a page isn't found since there isn't
actually a second page, and adds an error message when this is the case.
---
 Resource/Init/pdf_main.ps | 27 +++++++++++++++++++--------
 1 file changed, 19 insertions(+), 8 deletions(-)

diff --git a/Resource/Init/pdf_main.ps b/Resource/Init/pdf_main.ps
index 2d896b2..7a3b91f 100644
--- a/Resource/Init/pdf_main.ps
+++ b/Resource/Init/pdf_main.ps
@@ -513,7 +513,12 @@ currentdict /runpdfstring .undef
       {
         dup /Page# exch store
         QUIET not { (Page ) print dup //== exec flush } if
-        pdfgetpage pdfshowpage
+        pdfgetpage
+        dup //null ne { pdfshowpage } {
+          (   **** Error: Page #) pdfformaterror Page# 10 string cvs pdfformaterror
+          ( not found.\n) pdfformaterror
+          /dopdfpages cvx /syntaxerror signalerror
+        } ifelse
       }{
         pop
       }ifelse
@@ -2076,14 +2081,19 @@ currentdict /xref-char-dict undef
 /pdffindpageref {		% <int> pdffindpage <objref>
   dup pdffindpage?
                 % Stack: index countleft noderef
-   1 index 1 ne { pop pop /pdffindpage cvx /rangecheck signalerror } if
-   exch pop
-   PageIndex 2 index 1 sub 65533 .min 2 index oforce put
-   PageNumbers 1 index oforce 3 index dup 65534 le
-    { put }
-    { pop pop pop }	% don't store more than 65534 pagenumbers
+   dup //null ne {
+     1 index 1 ne { pop pop /pdffindpage cvx /rangecheck signalerror } if
+     exch pop
+     PageIndex 2 index 1 sub 65533 .min 2 index oforce put
+     PageNumbers 1 index oforce 3 index dup 65534 le
+      { put }
+      { pop pop pop }	% don't store more than 65534 pagenumbers
+     ifelse
+   } {
+     exch pop			% return the //null
+   }
    ifelse
-   exch pop
+   exch pop			% pop the page number, return the object or null
 } bind executeonly def
 /pdffindpage {		% <int> pdffindpage <pagedict>
   pdffindpageref oforce
@@ -3311,6 +3321,7 @@ currentdict /PDF2PS_matrix_key undef
   {
     /Parent knownoget
     {
+      dup /Pages known not { pop exit } if	% not a valid Page Tree ancestor
       dup 4 1 roll
       resourcespotcolors
       3 -1 roll
-- 
1.8.3.1

