From 81fde76643e6cd9114ae92d22704fbc405a02974 Mon Sep 17 00:00:00 2001 From: Hib Eris Date: Tue, 28 Feb 2012 10:53:56 +0100 Subject: [PATCH] Only use Hints table when there are no parse errors Fixes bug #46459. --- poppler/Hints.cc | 4 +++- poppler/Parser.cc | 29 +++++++++++++++++++++++------ poppler/Parser.h | 6 ++++-- 3 files changed, 30 insertions(+), 9 deletions(-) diff --git a/poppler/Hints.cc b/poppler/Hints.cc index 46bce80..99ab670 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)); @@ -138,7 +140,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, 0, gTrue)->isStream())) { Stream *hintsStream = obj.getStream(); Dict *hintsDict = obj.streamGetDict(); diff --git a/poppler/Parser.cc b/poppler/Parser.cc index 400d8d7..1563804 100644 --- a/poppler/Parser.cc +++ b/poppler/Parser.cc @@ -65,7 +65,8 @@ Object *Parser::getObj(Object *obj, int recursion) Object *Parser::getObj(Object *obj, GBool simpleOnly, Guchar *fileKey, CryptAlgorithm encAlgorithm, int keyLength, - int objNum, int objGen, int recursion) { + int objNum, int objGen, int recursion, + GBool strict) { char *key; Stream *str; Object obj2; @@ -90,8 +91,10 @@ Object *Parser::getObj(Object *obj, GBool simpleOnly, while (!buf1.isCmd("]") && !buf1.isEOF()) obj->arrayAdd(getObj(&obj2, gFalse, fileKey, encAlgorithm, keyLength, objNum, objGen, recursion + 1)); - if (buf1.isEOF()) + if (buf1.isEOF()) { error(errSyntaxError, getPos(), "End of file inside array"); + if (strict) goto err; + } shift(); // dictionary or stream @@ -101,6 +104,7 @@ Object *Parser::getObj(Object *obj, GBool simpleOnly, while (!buf1.isCmd(">>") && !buf1.isEOF()) { if (!buf1.isName()) { error(errSyntaxError, getPos(), "Dictionary key must be a name object"); + if (strict) goto err; shift(); } else { // buf1 might go away in shift(), so construct the key @@ -108,18 +112,22 @@ Object *Parser::getObj(Object *obj, GBool simpleOnly, shift(); if (buf1.isEOF() || buf1.isError()) { gfree(key); + if (strict && buf1.isError()) goto err; break; } obj->dictAdd(key, getObj(&obj2, gFalse, fileKey, encAlgorithm, keyLength, objNum, objGen, recursion + 1)); } } - if (buf1.isEOF()) + if (buf1.isEOF()) { error(errSyntaxError, 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, recursion + 1))) { + objNum, objGen, recursion + 1, + strict))) { obj->initStream(str); } else { obj->free(); @@ -169,11 +177,18 @@ Object *Parser::getObj(Object *obj, GBool simpleOnly, } return obj; + +err: + obj->free(); + obj->initError(); + return obj; + } Stream *Parser::makeStream(Object *dict, Guchar *fileKey, CryptAlgorithm encAlgorithm, int keyLength, - int objNum, int objGen, int recursion) { + int objNum, int objGen, int recursion, + GBool strict) { Object obj; BaseStream *baseStr; Stream *str; @@ -194,6 +209,7 @@ Stream *Parser::makeStream(Object *dict, Guchar *fileKey, } else { error(errSyntaxError, getPos(), "Bad 'Length' attribute in stream"); obj.free(); + if (strict) return NULL; length = 0; } @@ -223,7 +239,8 @@ Stream *Parser::makeStream(Object *dict, Guchar *fileKey, if (buf1.isCmd("endstream")) { shift(); } else { - error(errSyntaxError, getPos(), "Missing 'endstream'"); + error(errSyntaxError, 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 69cfc25..16365f8 100644 --- a/poppler/Parser.h +++ b/poppler/Parser.h @@ -48,7 +48,8 @@ public: Object *getObj(Object *obj, GBool simpleOnly = gFalse, Guchar *fileKey = NULL, CryptAlgorithm encAlgorithm = cryptRC4, int keyLength = 0, - int objNum = 0, int objGen = 0, int recursion = 0); + int objNum = 0, int objGen = 0, int recursion = 0, + GBool strict = gFalse); Object *getObj(Object *obj, int recursion); @@ -68,7 +69,8 @@ private: Stream *makeStream(Object *dict, Guchar *fileKey, CryptAlgorithm encAlgorithm, int keyLength, - int objNum, int objGen, int recursion); + int objNum, int objGen, int recursion, + GBool strict); void shift(int objNum = -1); }; -- 1.7.7