File poppler-broken-hints-table.patch of Package poppler.470

From c9780f867ee62c388483829c4e16804045567c87 Mon Sep 17 00:00:00 2001
From: Hib Eris <hib@hiberis.nl>
Date: Tue, 28 Feb 2012 11:38:07 +0100
Subject: [PATCH] [Backported to 0.18.4] Only use Hints table when there are
 no parse errors

Fixes bug #46459.

Backported to 0.18.4 from: 81fde76643e6cd9114ae92d22704fbc405a02974
---
 poppler/Hints.cc  |    5 ++++-
 poppler/Parser.cc |   29 +++++++++++++++++++++++------
 poppler/Parser.h  |    6 ++++--
 3 files changed, 31 insertions(+), 9 deletions(-)

diff --git a/poppler/Hints.cc b/poppler/Hints.cc
index 4f0c959..e76ffca 100644
--- a/poppler/Hints.cc
+++ b/poppler/Hints.cc
@@ -60,6 +60,8 @@ Hints::Hints(BaseStream *str, Linearization *linearization, XRef *xref, Security
     nPages = 0;
   }
 
+  memset(pageLength, 0, nPages * sizeof(Guint));
+  memset(pageOffset, 0, nPages * sizeof(Guint));
   memset(numSharedObject, 0, nPages * sizeof(Guint));
   memset(pageObjectNum, 0, nPages * sizeof(int));
 
@@ -131,6 +133,7 @@ void Hints::readTables(BaseStream *str, Linearization *linearization, XRef *xref
   parser = new Parser(xref, new Lexer(xref, memStream), gTrue);
 
   int num, gen;
+  std::set<int> fetchOriginatorNums;
   if (parser->getObj(&obj)->isInt() &&
      (num = obj.getInt(), obj.free(), parser->getObj(&obj)->isInt()) &&
      (gen = obj.getInt(), obj.free(), parser->getObj(&obj)->isCmd("obj")) &&
@@ -138,7 +141,7 @@ void Hints::readTables(BaseStream *str, Linearization *linearization, XRef *xref
          secHdlr ? secHdlr->getFileKey() : (Guchar *)NULL,
          secHdlr ? secHdlr->getEncAlgorithm() : cryptRC4,
          secHdlr ? secHdlr->getFileKeyLength() : 0,
-         num, gen)->isStream())) {
+         num, gen, &fetchOriginatorNums, gTrue)->isStream())) {
     Stream *hintsStream = obj.getStream();
     Dict *hintsDict = obj.streamGetDict();
 
diff --git a/poppler/Parser.cc b/poppler/Parser.cc
index 34a8286..8bf820b 100644
--- a/poppler/Parser.cc
+++ b/poppler/Parser.cc
@@ -66,7 +66,8 @@ Object *Parser::getObj(Object *obj, std::set<int> *fetchOriginatorNums)
 
 Object *Parser::getObj(Object *obj, Guchar *fileKey,
 		       CryptAlgorithm encAlgorithm, int keyLength,
-		       int objNum, int objGen, std::set<int> *fetchOriginatorNums) {
+		       int objNum, int objGen, std::set<int> *fetchOriginatorNums,
+		       GBool strict) {
   char *key;
   Stream *str;
   Object obj2;
@@ -91,8 +92,10 @@ Object *Parser::getObj(Object *obj, Guchar *fileKey,
     while (!buf1.isCmd("]") && !buf1.isEOF())
       obj->arrayAdd(getObj(&obj2, fileKey, encAlgorithm, keyLength,
 			   objNum, objGen, fetchOriginatorNums));
-    if (buf1.isEOF())
+    if (buf1.isEOF()) {
       error(getPos(), "End of file inside array");
+      if (strict) goto err;
+    }
     shift();
 
   // dictionary or stream
@@ -102,6 +105,7 @@ Object *Parser::getObj(Object *obj, Guchar *fileKey,
     while (!buf1.isCmd(">>") && !buf1.isEOF()) {
       if (!buf1.isName()) {
 	error(getPos(), "Dictionary key must be a name object");
+	if (strict) goto err;
 	shift();
       } else {
 	// buf1 might go away in shift(), so construct the key
@@ -109,18 +113,22 @@ Object *Parser::getObj(Object *obj, Guchar *fileKey,
 	shift();
 	if (buf1.isEOF() || buf1.isError()) {
 	  gfree(key);
+	  if (strict && buf1.isError()) goto err;
 	  break;
 	}
 	obj->dictAdd(key, getObj(&obj2, fileKey, encAlgorithm, keyLength, objNum, objGen, fetchOriginatorNums));
       }
     }
-    if (buf1.isEOF())
+    if (buf1.isEOF()) {
       error(getPos(), "End of file inside dictionary");
+      if (strict) goto err;
+    }
     // stream objects are not allowed inside content streams or
     // object streams
     if (allowStreams && buf2.isCmd("stream")) {
       if ((str = makeStream(obj, fileKey, encAlgorithm, keyLength,
-			    objNum, objGen, fetchOriginatorNums))) {
+			    objNum, objGen, fetchOriginatorNums,
+			    strict))) {
 	obj->initStream(str);
       } else {
 	obj->free();
@@ -170,11 +178,18 @@ Object *Parser::getObj(Object *obj, Guchar *fileKey,
   }
 
   return obj;
+
+err:
+  obj->free();
+  obj->initError();
+  return obj;
+
 }
 
 Stream *Parser::makeStream(Object *dict, Guchar *fileKey,
 			   CryptAlgorithm encAlgorithm, int keyLength,
-			   int objNum, int objGen, std::set<int> *fetchOriginatorNums) {
+			   int objNum, int objGen, std::set<int> *fetchOriginatorNums,
+			   GBool strict) {
   Object obj;
   BaseStream *baseStr;
   Stream *str;
@@ -192,6 +207,7 @@ Stream *Parser::makeStream(Object *dict, Guchar *fileKey,
   } else {
     error(getPos(), "Bad 'Length' attribute in stream");
     obj.free();
+    if (strict) return NULL;
     length = 0;
   }
 
@@ -221,7 +237,8 @@ Stream *Parser::makeStream(Object *dict, Guchar *fileKey,
   if (buf1.isCmd("endstream")) {
     shift();
   } else {
-    error(getPos(), "Missing 'endstream'");
+    error(getPos(), "Missing 'endstream' or incorrect stream length");
+    if (strict) return NULL;
     if (xref) {
       // shift until we find the proper endstream or we change to another object or reach eof
       while (!buf1.isCmd("endstream") && xref->getNumEntry(lexer->getPos()) == objNum && !buf1.isEOF()) {
diff --git a/poppler/Parser.h b/poppler/Parser.h
index 3d8a831..4fb3330 100644
--- a/poppler/Parser.h
+++ b/poppler/Parser.h
@@ -49,7 +49,8 @@ public:
   
   Object *getObj(Object *obj, Guchar *fileKey,
      CryptAlgorithm encAlgorithm, int keyLength,
-     int objNum, int objGen, std::set<int> *fetchOriginatorNums);
+     int objNum, int objGen, std::set<int> *fetchOriginatorNums,
+     GBool strict = gFalse);
 
   Object *getObj(Object *obj, std::set<int> *fetchOriginatorNums);
 
@@ -69,7 +70,8 @@ private:
 
   Stream *makeStream(Object *dict, Guchar *fileKey,
 		     CryptAlgorithm encAlgorithm, int keyLength,
-		     int objNum, int objGen, std::set<int> *fetchOriginatorNums);
+		     int objNum, int objGen, std::set<int> *fetchOriginatorNums,
+		     GBool strict);
   void shift(int objNum = -1);
 };
 
-- 
1.7.7

openSUSE Build Service is sponsored by