@@ -56,15 +56,11 @@ public function getPages(bool $deep = false): array
5656 return [];
5757 }
5858
59+ /** @var ElementArray $kidsElement */
5960 $ kidsElement = $ this ->get ('Kids ' );
60- if ($ kidsElement instanceof ElementArray) {
61- $ kids = $ kidsElement ->getContent ();
62- } else {
63- $ kids = [$ kidsElement ];
64- }
6561
6662 if (!$ deep ) {
67- return $ kids ;
63+ return $ kidsElement -> getContent () ;
6864 }
6965
7066 // Prepare to apply the Pages' object's fonts to each page
@@ -73,6 +69,10 @@ public function getPages(bool $deep = false): array
7369 }
7470 $ fontsAvailable = 0 < \count ($ this ->fonts );
7571
72+ $ kids = $ kidsElement ->getContent ();
73+ if (!\is_array ($ kids )) {
74+ $ kids = [];
75+ }
7676 $ pages = [];
7777
7878 foreach ($ kids as $ kid ) {
@@ -83,12 +83,70 @@ public function getPages(bool $deep = false): array
8383 $ kid ->setFonts ($ this ->fonts );
8484 }
8585 $ pages [] = $ kid ;
86+ } elseif ($ kid instanceof PDFObject && $ this ->isRecoverablePageObject ($ kid )) {
87+ $ recoveredPage = new Page ($ kid ->getDocument (), $ kid ->getHeader (), $ kid ->getContent (), $ kid ->getConfig ());
88+ if ($ fontsAvailable ) {
89+ $ recoveredPage ->setFonts ($ this ->fonts );
90+ }
91+ $ pages [] = $ recoveredPage ;
92+ }
93+ }
94+
95+ if ([] === $ pages ) {
96+ $ pages = $ this ->recoverPagesByParentReference ($ fontsAvailable );
97+ }
98+
99+ return $ pages ;
100+ }
101+
102+ /**
103+ * Recover page objects when Kids is malformed but child objects still point
104+ * to this node via Parent.
105+ *
106+ * @return array<Page>
107+ */
108+ protected function recoverPagesByParentReference (bool $ fontsAvailable ): array
109+ {
110+ $ pages = [];
111+
112+ foreach ($ this ->getDocument ()->getObjects () as $ object ) {
113+ if ($ object instanceof Page && $ object ->has ('Parent ' ) && $ object ->get ('Parent ' ) === $ this ) {
114+ if ($ fontsAvailable ) {
115+ $ object ->setFonts ($ this ->fonts );
116+ }
117+ $ pages [] = $ object ;
118+ continue ;
119+ }
120+
121+ if (!$ object instanceof PDFObject || !$ this ->isRecoverablePageObject ($ object )) {
122+ continue ;
123+ }
124+
125+ if ($ object ->get ('Parent ' ) !== $ this ) {
126+ continue ;
127+ }
128+
129+ $ recoveredPage = new Page ($ object ->getDocument (), $ object ->getHeader (), $ object ->getContent (), $ object ->getConfig ());
130+ if ($ fontsAvailable ) {
131+ $ recoveredPage ->setFonts ($ this ->fonts );
86132 }
133+ $ pages [] = $ recoveredPage ;
87134 }
88135
89136 return $ pages ;
90137 }
91138
139+ protected function isRecoverablePageObject (PDFObject $ object ): bool
140+ {
141+ // Some malformed files corrupt the key name for /Type and objects are not
142+ // instantiated as Page. Recover only when page-specific keys are present.
143+ if (!$ object ->has ('Parent ' )) {
144+ return false ;
145+ }
146+
147+ return $ object ->has ('MediaBox ' ) || $ object ->has ('Contents ' );
148+ }
149+
92150 /**
93151 * Gathers information about fonts and collects them in a list.
94152 *
0 commit comments