poppler/Gfx.cc | 2 - poppler/GlobalParamsWin.cc | 3 -- poppler/Hints.cc | 2 - poppler/Lexer.h | 3 ++ poppler/Linearization.cc | 2 - poppler/Parser.cc | 61 +++++++++++++++++++++++---------------------- poppler/Parser.h | 10 +++---- poppler/XRef.cc | 33 +++++++++--------------- 8 files changed, 57 insertions(+), 59 deletions(-)
New commits: commit eb40274320381deca89898fb78b57091d2b804cc Author: Adam Reichold <adam.reich...@t-online.de> Date: Wed Nov 21 18:08:13 2018 +0100 Since a Parser cannot be used without a Lexer, make the Parser own the Lexer by value and construct it in place. diff --git a/poppler/Gfx.cc b/poppler/Gfx.cc index 9244b044..eaeede53 100644 --- a/poppler/Gfx.cc +++ b/poppler/Gfx.cc @@ -709,7 +709,7 @@ void Gfx::display(Object *obj, bool topLevel) { error(errSyntaxError, -1, "Weird page contents"); return; } - parser = new Parser(xref, new Lexer(xref, obj), false); + parser = new Parser(xref, obj, false); go(topLevel); delete parser; parser = nullptr; diff --git a/poppler/GlobalParamsWin.cc b/poppler/GlobalParamsWin.cc index e4fa6731..82f97e48 100644 --- a/poppler/GlobalParamsWin.cc +++ b/poppler/GlobalParamsWin.cc @@ -447,8 +447,7 @@ void GlobalParams::setupBaseFonts(char * dir) if (file != nullptr) { Parser *parser; parser = new Parser(nullptr, - new Lexer(nullptr, - new FileStream(file, 0, false, file->size(), Object(objNull))), + new FileStream(file, 0, false, file->size(), Object(objNull)), true); Object obj1 = parser->getObj(); while (!obj1.isEOF()) { diff --git a/poppler/Hints.cc b/poppler/Hints.cc index e6039f4d..6adf10a0 100644 --- a/poppler/Hints.cc +++ b/poppler/Hints.cc @@ -202,7 +202,7 @@ void Hints::readTables(BaseStream *str, Linearization *linearization, XRef *xref MemStream *memStream = new MemStream (&buf[0], 0, bufLength, Object(objNull)); - parser = new Parser(xref, new Lexer(xref, memStream), true); + parser = new Parser(xref, memStream, true); int num, gen; Object obj; diff --git a/poppler/Lexer.h b/poppler/Lexer.h index bbc05a10..2666715d 100644 --- a/poppler/Lexer.h +++ b/poppler/Lexer.h @@ -91,6 +91,9 @@ public: static const int LOOK_VALUE_NOT_CACHED = -3; int lookCharLastValueCached; + XRef *getXRef() const { return xref; } + bool hasXRef() const { return xref != nullptr; } + private: int getChar(bool comesFromLook = false); diff --git a/poppler/Linearization.cc b/poppler/Linearization.cc index 0e2d3aa7..550b9bff 100644 --- a/poppler/Linearization.cc +++ b/poppler/Linearization.cc @@ -24,7 +24,7 @@ Linearization::Linearization (BaseStream *str) str->reset(); parser = new Parser(nullptr, - new Lexer(nullptr, str->makeSubStream(str->getStart(), false, 0, Object(objNull))), + str->makeSubStream(str->getStart(), false, 0, Object(objNull)), false); Object obj1 = parser->getObj(); Object obj2 = parser->getObj(); diff --git a/poppler/Parser.cc b/poppler/Parser.cc index 2c2f8718..cb9ebf93 100644 --- a/poppler/Parser.cc +++ b/poppler/Parser.cc @@ -44,19 +44,22 @@ // lots of nested arrays that made us consume all the stack #define recursionLimit 500 -Parser::Parser(XRef *xrefA, Lexer *lexerA, bool allowStreamsA) { - xref = xrefA; - lexer = lexerA; - inlineImg = 0; +Parser::Parser(XRef *xrefA, Stream *streamA, bool allowStreamsA) : lexer{xrefA, streamA} { allowStreams = allowStreamsA; - buf1 = lexer->getObj(); - buf2 = lexer->getObj(); + buf1 = lexer.getObj(); + buf2 = lexer.getObj(); + inlineImg = 0; } -Parser::~Parser() { - delete lexer; +Parser::Parser(XRef *xrefA, Object *objectA, bool allowStreamsA) : lexer{xrefA, objectA} { + allowStreams = allowStreamsA; + buf1 = lexer.getObj(); + buf2 = lexer.getObj(); + inlineImg = 0; } +Parser::~Parser() = default; + Object Parser::getObj(int recursion) { return getObj(false, nullptr, cryptRC4, 0, 0, 0, recursion); @@ -76,8 +79,8 @@ Object Parser::getObj(bool simpleOnly, // refill buffer after inline image data if (inlineImg == 2) { - buf1 = lexer->getObj(); - buf2 = lexer->getObj(); + buf1 = lexer.getObj(); + buf2 = lexer.getObj(); inlineImg = 0; } @@ -88,7 +91,7 @@ Object Parser::getObj(bool simpleOnly, // array if (!simpleOnly && buf1.isCmd("[")) { shift(); - obj = Object(new Array(xref)); + obj = Object(new Array(lexer.getXRef())); while (!buf1.isCmd("]") && !buf1.isEOF() && recursion + 1 < recursionLimit) { Object obj2 = getObj(false, fileKey, encAlgorithm, keyLength, objNum, objGen, recursion + 1); obj.arrayAdd(std::move(obj2)); @@ -103,7 +106,7 @@ Object Parser::getObj(bool simpleOnly, // dictionary or stream } else if (!simpleOnly && buf1.isCmd("<<")) { shift(objNum); - obj = Object(new Dict(xref)); + obj = Object(new Dict(lexer.getXRef())); while (!buf1.isCmd(">>") && !buf1.isEOF()) { if (!buf1.isName()) { error(errSyntaxError, getPos(), "Dictionary key must be a name object"); @@ -203,7 +206,7 @@ Stream *Parser::makeStream(Object &&dict, unsigned char *fileKey, Goffset pos, endPos; - if (xref) { + if (XRef *xref = lexer.getXRef()) { XRefEntry *entry = xref->getEntry(objNum, false); if (entry) { if (!entry->getFlag(XRefEntry::Parsing) || @@ -218,8 +221,8 @@ Stream *Parser::makeStream(Object &&dict, unsigned char *fileKey, } // get stream start position - lexer->skipToNextLine(); - if (!(str = lexer->getStream())) { + lexer.skipToNextLine(); + if (!(str = lexer.getStream())) { return nullptr; } pos = str->getPos(); @@ -237,22 +240,22 @@ Stream *Parser::makeStream(Object &&dict, unsigned char *fileKey, } // check for length in damaged file - if (xref && xref->getStreamEnd(pos, &endPos)) { + if (lexer.hasXRef() && lexer.getXRef()->getStreamEnd(pos, &endPos)) { length = endPos - pos; } // in badly damaged PDF files, we can run off the end of the input // stream immediately after the "stream" token - if (!lexer->getStream()) { + if (!lexer.getStream()) { return nullptr; } - baseStr = lexer->getStream()->getBaseStream(); + baseStr = lexer.getStream()->getBaseStream(); // skip over stream data - if (Lexer::LOOK_VALUE_NOT_CACHED != lexer->lookCharLastValueCached) { + if (Lexer::LOOK_VALUE_NOT_CACHED != lexer.lookCharLastValueCached) { // take into account the fact that we've cached one value pos = pos - 1; - lexer->lookCharLastValueCached = Lexer::LOOK_VALUE_NOT_CACHED; + lexer.lookCharLastValueCached = Lexer::LOOK_VALUE_NOT_CACHED; } if (unlikely(length < 0)) { return nullptr; @@ -260,7 +263,7 @@ Stream *Parser::makeStream(Object &&dict, unsigned char *fileKey, if (unlikely(pos > LLONG_MAX - length)) { return nullptr; } - lexer->setPos(pos + length); + lexer.setPos(pos + length); // refill token buffers and check for 'endstream' shift(); // kill '>>' @@ -270,9 +273,9 @@ Stream *Parser::makeStream(Object &&dict, unsigned char *fileKey, } else { error(errSyntaxError, getPos(), "Missing 'endstream' or incorrect stream length"); if (strict) return nullptr; - if (xref && lexer->getStream()) { + if (lexer.hasXRef() && lexer.getStream()) { // shift until we find the proper endstream or we change to another object or reach eof - length = lexer->getPos() - pos; + length = lexer.getPos() - pos; if (buf1.isCmd("endstream")) { dict.dictSet("Length", Object(length)); } @@ -297,7 +300,7 @@ Stream *Parser::makeStream(Object &&dict, unsigned char *fileKey, // get filters str = str->addFilters(str->getDict(), recursion); - if (xref) { + if (XRef *xref = lexer.getXRef()) { // Don't try to reuse the entry from the block at the start // of the function, xref can change in the middle because of // reconstruction @@ -320,14 +323,14 @@ void Parser::shift(int objNum) { inlineImg = 0; } } else if (buf2.isCmd("ID")) { - lexer->skipChar(); // skip char after 'ID' command + lexer.skipChar(); // skip char after 'ID' command inlineImg = 1; } buf1 = std::move(buf2); if (inlineImg > 0) // don't buffer inline image data buf2.setToNull(); else { - buf2 = lexer->getObj(objNum); + buf2 = lexer.getObj(objNum); } } @@ -341,15 +344,15 @@ void Parser::shift(const char *cmdA, int objNum) { inlineImg = 0; } } else if (buf2.isCmd("ID")) { - lexer->skipChar(); // skip char after 'ID' command + lexer.skipChar(); // skip char after 'ID' command inlineImg = 1; } buf1 = std::move(buf2); if (inlineImg > 0) { buf2.setToNull(); } else if (buf1.isCmd(cmdA)) { - buf2 = lexer->getObj(objNum); + buf2 = lexer.getObj(objNum); } else { - buf2 = lexer->getObj(cmdA, objNum); + buf2 = lexer.getObj(cmdA, objNum); } } diff --git a/poppler/Parser.h b/poppler/Parser.h index 2d2ed36f..fc92adea 100644 --- a/poppler/Parser.h +++ b/poppler/Parser.h @@ -36,7 +36,8 @@ class Parser { public: // Constructor. - Parser(XRef *xrefA, Lexer *lexerA, bool allowStreamsA); + Parser(XRef *xrefA, Stream *streamA, bool allowStreamsA); + Parser(XRef *xrefA, Object *objectA, bool allowStreamsA); // Destructor. ~Parser(); @@ -57,15 +58,14 @@ public: template<typename T> Object getObj(T) = delete; // Get stream. - Stream *getStream() { return lexer->getStream(); } + Stream *getStream() { return lexer.getStream(); } // Get current position in file. - Goffset getPos() { return lexer->getPos(); } + Goffset getPos() { return lexer.getPos(); } private: - XRef *xref; // the xref table for this PDF file - Lexer *lexer; // input stream + Lexer lexer; // input stream bool allowStreams; // parse stream objects? Object buf1, buf2; // next two tokens int inlineImg; // set when inline image data is encountered diff --git a/poppler/XRef.cc b/poppler/XRef.cc index d9b7a33b..68f92d05 100644 --- a/poppler/XRef.cc +++ b/poppler/XRef.cc @@ -157,7 +157,7 @@ ObjectStream::ObjectStream(XRef *xref, int objStrNumA, int recursion) { // parse the header: object numbers and offsets objStr.streamReset(); str = new EmbedStream(objStr.getStream(), Object(objNull), true, first); - parser = new Parser(xref, new Lexer(xref, str), false); + parser = new Parser(xref, str, false); for (i = 0; i < nObjects; ++i) { obj1 = parser->getObj(); Object obj2 = parser->getObj(); @@ -196,7 +196,7 @@ ObjectStream::ObjectStream(XRef *xref, int objStrNumA, int recursion) { str = new EmbedStream(objStr.getStream(), Object(objNull), true, offsets[i+1] - offsets[i]); } - parser = new Parser(xref, new Lexer(xref, str), false); + parser = new Parser(xref, str, false); objs[i] = parser->getObj(); while (str->getChar() != EOF) ; delete parser; @@ -459,8 +459,7 @@ bool XRef::readXRef(Goffset *pos, std::vector<Goffset> *followedXRefStm, std::ve // start up a parser, parse one token parser = new Parser(nullptr, - new Lexer(nullptr, - str->makeSubStream(start + *pos, false, 0, Object(objNull))), + str->makeSubStream(start + *pos, false, 0, Object(objNull)), true); obj = parser->getObj(true); @@ -866,8 +865,7 @@ bool XRef::constructXRef(bool *wasReconstructed, bool needCatalogDict) { // got trailer dictionary if (!strncmp(p, "trailer", 7)) { parser = new Parser(nullptr, - new Lexer(nullptr, - str->makeSubStream(pos + 7, false, 0, Object(objNull))), + str->makeSubStream(pos + 7, false, 0, Object(objNull)), false); Object newTrailerDict = parser->getObj(); if (newTrailerDict.isDict()) { @@ -1078,7 +1076,6 @@ Object XRef::fetch(const Ref ref, int recursion) Object XRef::fetch(int num, int gen, int recursion) { XRefEntry *e; - Parser *parser; Object obj1, obj2, obj3; xrefLocker(); @@ -1099,13 +1096,12 @@ Object XRef::fetch(int num, int gen, int recursion) { if (e->gen != gen || e->offset < 0) { goto err; } - parser = new Parser(this, - new Lexer(this, - str->makeSubStream(start + e->offset, false, 0, Object(objNull))), - true); - obj1 = parser->getObj(recursion); - obj2 = parser->getObj(recursion); - obj3 = parser->getObj(recursion); + Parser parser{this, + str->makeSubStream(start + e->offset, false, 0, Object(objNull)), + true}; + obj1 = parser.getObj(recursion); + obj2 = parser.getObj(recursion); + obj3 = parser.getObj(recursion); if (!obj1.isInt() || obj1.getInt() != num || !obj2.isInt() || obj2.getInt() != gen || !obj3.isCmd("obj")) { @@ -1124,17 +1120,14 @@ Object XRef::fetch(int num, int gen, int recursion) { if (longNumber <= INT_MAX && longNumber >= INT_MIN && *end_ptr == '\0') { int number = longNumber; error(errSyntaxWarning, -1, "Cmd was not obj but {0:s}, assuming the creator meant obj {1:d}", cmd, number); - delete parser; return Object(number); } } } - delete parser; goto err; } - Object obj = parser->getObj(false, (encrypted && !e->getFlag(XRefEntry::Unencrypted)) ? fileKey : nullptr, + Object obj = parser.getObj(false, (encrypted && !e->getFlag(XRefEntry::Unencrypted)) ? fileKey : nullptr, encAlgorithm, keyLength, num, gen, recursion); - delete parser; return obj; } @@ -1486,8 +1479,8 @@ bool XRef::parseEntry(Goffset offset, XRefEntry *entry) if (unlikely(entry == nullptr)) return false; - Parser parser(nullptr, new Lexer(nullptr, - str->makeSubStream(offset, false, 20, Object(objNull))), true); + Parser parser(nullptr, + str->makeSubStream(offset, false, 20, Object(objNull)), true); Object obj1, obj2, obj3; if (((obj1 = parser.getObj(), obj1.isInt()) || obj1.isInt64()) && _______________________________________________ poppler mailing list poppler@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/poppler