db2a8b
From 3d35d209c19c1d3b09b794a0c863ba5de44a9c0a Mon Sep 17 00:00:00 2001
db2a8b
From: Marek Kasik <mkasik@redhat.com>
db2a8b
Date: Mon, 29 Oct 2018 17:44:47 +0100
db2a8b
Subject: [PATCH] Avoid cycles in PDF parsing
db2a8b
db2a8b
Mark objects being processed in Parser::makeStream() as being processed
db2a8b
and check the mark when entering this method to avoid processing
db2a8b
of the same object recursively.
db2a8b
---
db2a8b
 poppler/Parser.cc | 15 +++++++++++++++
db2a8b
 poppler/XRef.h    |  1 +
db2a8b
 2 files changed, 16 insertions(+)
db2a8b
db2a8b
diff --git a/poppler/Parser.cc b/poppler/Parser.cc
db2a8b
index bd4845ab..8f48efbe 100644
db2a8b
--- a/poppler/Parser.cc
db2a8b
+++ b/poppler/Parser.cc
db2a8b
@@ -197,6 +197,18 @@ Stream *Parser::makeStream(Object &&dict, Guchar *fileKey,
db2a8b
   Stream *str;
db2a8b
   Goffset length;
db2a8b
   Goffset pos, endPos;
db2a8b
+  XRefEntry *entry = nullptr;
db2a8b
+
db2a8b
+  if (xref && (entry = xref->getEntry(objNum, false))) {
db2a8b
+    if (!entry->getFlag(XRefEntry::Parsing) ||
db2a8b
+        (objNum == 0 && objGen == 0)) {
db2a8b
+      entry->setFlag(XRefEntry::Parsing, true);
db2a8b
+    } else {
db2a8b
+      error(errSyntaxError, getPos(),
db2a8b
+            "Object '{0:d} {1:d} obj' is being already parsed", objNum, objGen);
db2a8b
+      return nullptr;
db2a8b
+    }
db2a8b
+  }
db2a8b
 
db2a8b
   // get stream start position
db2a8b
   lexer->skipToNextLine();
db2a8b
@@ -278,6 +290,9 @@ Stream *Parser::makeStream(Object &&dict, Guchar *fileKey,
db2a8b
   // get filters
db2a8b
   str = str->addFilters(str->getDict(), recursion);
db2a8b
 
db2a8b
+  if (entry)
db2a8b
+    entry->setFlag(XRefEntry::Parsing, false);
db2a8b
+
db2a8b
   return str;
db2a8b
 }
db2a8b
 
db2a8b
diff --git a/poppler/XRef.h b/poppler/XRef.h
db2a8b
index 11ee5e03..2eb2f9fd 100644
db2a8b
--- a/poppler/XRef.h
db2a8b
+++ b/poppler/XRef.h
db2a8b
@@ -65,6 +65,7 @@ struct XRefEntry {
db2a8b
   enum Flag {
db2a8b
     // Regular flags
db2a8b
     Updated,     // Entry was modified
db2a8b
+    Parsing,     // Entry is currently being parsed
db2a8b
 
db2a8b
     // Special flags -- available only after xref->scanSpecialFlags() is run
db2a8b
     Unencrypted, // Entry is stored in unencrypted form (meaningless in unencrypted documents)
db2a8b
-- 
db2a8b
2.19.1
db2a8b