Skip to content

Commit d8c211b

Browse files
Fixed infinite loop in case of a recursive pages dictionary
1 parent 4fc6d6e commit d8c211b

File tree

1 file changed

+16
-2
lines changed

1 file changed

+16
-2
lines changed

src/PdfReader/PdfReader.php

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -139,12 +139,19 @@ public function getPage($pageNumber)
139139
$page = $this->pages[$pageNumber - 1];
140140

141141
if ($page instanceof PdfIndirectObjectReference) {
142-
$readPages = function ($kids) use (&$readPages) {
142+
$alreadyReadKids = [];
143+
$readPages = function ($kids) use (&$readPages, &$alreadyReadKids) {
143144
$kids = PdfArray::ensure($kids);
144145

145146
/** @noinspection LoopWhichDoesNotLoopInspection */
146147
foreach ($kids->value as $reference) {
147148
$reference = PdfIndirectObjectReference::ensure($reference);
149+
150+
if (\in_array($reference->value, $alreadyReadKids)) {
151+
throw new PdfReaderException('Recursive pages dictionary detected.');
152+
}
153+
$alreadyReadKids[] = $reference->value;
154+
148155
$object = $this->parser->getIndirectObject($reference->value);
149156
$type = PdfDictionary::get($object->value, 'Type');
150157

@@ -168,6 +175,7 @@ public function getPage($pageNumber)
168175
if ($type->value === 'Pages') {
169176
$kids = PdfType::resolve(PdfDictionary::get($dict, 'Kids'), $this->parser);
170177
try {
178+
$alreadyReadKids[] = $page->objectNumber;
171179
$page = $this->pages[$pageNumber - 1] = $readPages($kids);
172180
} catch (PdfReaderException $e) {
173181
if ($e->getCode() !== PdfReaderException::KIDS_EMPTY) {
@@ -203,7 +211,8 @@ protected function readPages($readAll = false)
203211
}
204212

205213
$expectedPageCount = $this->getPageCount();
206-
$readPages = function ($kids, $count) use (&$readPages, $readAll, $expectedPageCount) {
214+
$alreadyReadKids = [];
215+
$readPages = function ($kids, $count) use (&$readPages, &$alreadyReadKids, $readAll, $expectedPageCount) {
207216
$kids = PdfArray::ensure($kids);
208217
$isLeaf = ($count->value === \count($kids->value));
209218

@@ -215,6 +224,11 @@ protected function readPages($readAll = false)
215224
continue;
216225
}
217226

227+
if (\in_array($reference->value, $alreadyReadKids)) {
228+
throw new PdfReaderException('Recursive pages dictionary detected.');
229+
}
230+
$alreadyReadKids[] = $reference->value;
231+
218232
$object = $this->parser->getIndirectObject($reference->value);
219233
$type = PdfDictionary::get($object->value, 'Type');
220234

0 commit comments

Comments
 (0)