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