From 316c21f585dc633cbf9b337d9d56d1d8120375e3 Mon Sep 17 00:00:00 2001 From: Adrian Johnson Date: Sat, 22 Dec 2012 19:18:24 +1030 Subject: [PATCH 3/3] Large file support Create a Goffset type and use this type for all file offsets and file sizes. --- cpp/poppler-private.cpp | 2 +- cpp/poppler-private.h | 2 +- glib/poppler-input-stream.cc | 10 +- glib/poppler-input-stream.h | 16 +-- goo/gtypes.h | 15 +++ poppler/Decrypt.cc | 2 +- poppler/Decrypt.h | 2 +- poppler/Error.cc | 10 +- poppler/Error.h | 5 +- poppler/Hints.cc | 4 +- poppler/Hints.h | 6 +- poppler/JBIG2Stream.cc | 8 +- poppler/JBIG2Stream.h | 2 +- poppler/JPEG2000Stream.cc | 2 +- poppler/JPEG2000Stream.h | 2 +- poppler/Lexer.h | 8 +- poppler/Object.h | 8 +- poppler/PDFDoc.cc | 54 +++++----- poppler/PDFDoc.h | 14 +-- poppler/Parser.cc | 10 +- poppler/Parser.h | 2 +- poppler/Stream.cc | 88 ++++++++-------- poppler/Stream.h | 102 +++++++++---------- poppler/XRef.cc | 139 ++++++++++++++++---------- poppler/XRef.h | 34 +++---- poppler/poppler-config.h.in | 6 ++ qt4/src/poppler-private.cc | 2 +- qt4/src/poppler-qiodeviceoutstream-private.h | 2 +- qt4/src/poppler-qiodeviceoutstream.cc | 4 +- test/perf-test.cc | 6 +- utils/pdfunite.cc | 2 +- 31 files changed, 316 insertions(+), 253 deletions(-) diff --git a/cpp/poppler-private.cpp b/cpp/poppler-private.cpp index 2783bed..b2fa621 100644 --- a/cpp/poppler-private.cpp +++ b/cpp/poppler-private.cpp @@ -28,7 +28,7 @@ using namespace poppler; -void detail::error_function(void * /*data*/, ErrorCategory /*category*/, int pos, char *msg) +void detail::error_function(void * /*data*/, ErrorCategory /*category*/, Goffset pos, char *msg) { std::ostringstream oss; if (pos >= 0) { diff --git a/cpp/poppler-private.h b/cpp/poppler-private.h index a4b455c..cf2cc27 100644 --- a/cpp/poppler-private.h +++ b/cpp/poppler-private.h @@ -38,7 +38,7 @@ namespace poppler namespace detail { -void error_function(void *data, ErrorCategory category, int pos, char *msg); +void error_function(void *data, ErrorCategory category, Goffset pos, char *msg); rectf pdfrectangle_to_rectf(const PDFRectangle &pdfrect); diff --git a/glib/poppler-input-stream.cc b/glib/poppler-input-stream.cc index 99fcb6f..9b107b6 100644 --- a/glib/poppler-input-stream.cc +++ b/glib/poppler-input-stream.cc @@ -21,7 +21,7 @@ #include "poppler-input-stream.h" PopplerInputStream::PopplerInputStream(GInputStream *inputStreamA, GCancellable *cancellableA, - Guint startA, GBool limitedA, Guint lengthA, Object *dictA) + Goffset startA, GBool limitedA, Goffset lengthA, Object *dictA) : BaseStream(dictA, lengthA) { inputStream = (GInputStream *)g_object_ref(inputStreamA); @@ -41,8 +41,8 @@ PopplerInputStream::~PopplerInputStream() g_object_unref(cancellable); } -Stream *PopplerInputStream::makeSubStream(Guint startA, GBool limitedA, - Guint lengthA, Object *dictA) +Stream *PopplerInputStream::makeSubStream(Goffset startA, GBool limitedA, + Goffset lengthA, Object *dictA) { return new PopplerInputStream(inputStream, cancellable, startA, limitedA, lengthA, dictA); } @@ -66,7 +66,7 @@ void PopplerInputStream::close() saved = gFalse; } -void PopplerInputStream::setPos(Guint pos, int dir) +void PopplerInputStream::setPos(Goffset pos, int dir) { Guint size; GSeekable *seekable = G_SEEKABLE(inputStream); @@ -86,7 +86,7 @@ void PopplerInputStream::setPos(Guint pos, int dir) bufPtr = bufEnd = buf; } -void PopplerInputStream::moveStart(int delta) +void PopplerInputStream::moveStart(Goffset delta) { start += delta; bufPtr = bufEnd = buf; diff --git a/glib/poppler-input-stream.h b/glib/poppler-input-stream.h index 0d795f4..7a6972b 100644 --- a/glib/poppler-input-stream.h +++ b/glib/poppler-input-stream.h @@ -31,10 +31,10 @@ class PopplerInputStream: public BaseStream { public: PopplerInputStream(GInputStream *inputStream, GCancellable *cancellableA, - Guint startA, GBool limitedA, Guint lengthA, Object *dictA); + Goffset startA, GBool limitedA, Goffset lengthA, Object *dictA); virtual ~PopplerInputStream(); - virtual Stream *makeSubStream(Guint start, GBool limited, - Guint lengthA, Object *dictA); + virtual Stream *makeSubStream(Goffset start, GBool limited, + Goffset lengthA, Object *dictA); virtual StreamKind getKind() { return strWeird; } virtual void reset(); virtual void close(); @@ -42,10 +42,10 @@ public: { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); } virtual int lookChar() { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); } - virtual int getPos() { return bufPos + (bufPtr - buf); } - virtual void setPos(Guint pos, int dir = 0); - virtual Guint getStart() { return start; } - virtual void moveStart(int delta); + virtual Goffset getPos() { return bufPos + (bufPtr - buf); } + virtual void setPos(Goffset pos, int dir = 0); + virtual Goffset getStart() { return start; } + virtual void moveStart(Goffset delta); virtual int getUnfilteredChar() { return getChar(); } virtual void unfilteredReset() { reset(); } @@ -59,7 +59,7 @@ private: GInputStream *inputStream; GCancellable *cancellable; - Guint start; + Goffset start; GBool limited; char buf[inputStreamBufSize]; char *bufPtr; diff --git a/goo/gtypes.h b/goo/gtypes.h index b7a2dd2..5247041 100644 --- a/goo/gtypes.h +++ b/goo/gtypes.h @@ -24,6 +24,9 @@ #ifndef GTYPES_H #define GTYPES_H +#include "poppler-config.h" +#include // for off_t + /* * These have stupid names to avoid conflicts with some (but not all) * C++ compilers which define them. @@ -45,4 +48,16 @@ typedef unsigned short Gushort; typedef unsigned int Guint; typedef unsigned long Gulong; +/* Define Goffset to be the offset type used by the version of + * fseek we are using. + */ +#if HAVE_FSEEKO +typedef off_t Goffset; +#elif HAVE_FSEEK64 +typedef off64_t Goffset; +#else +typedef long Goffset; +#endif + + #endif diff --git a/poppler/Decrypt.cc b/poppler/Decrypt.cc index 44f6961..ad9a9eb 100644 --- a/poppler/Decrypt.cc +++ b/poppler/Decrypt.cc @@ -341,7 +341,7 @@ void BaseCryptStream::reset() { str->reset(); } -int BaseCryptStream::getPos() { +Goffset BaseCryptStream::getPos() { return charactersRead; } diff --git a/poppler/Decrypt.h b/poppler/Decrypt.h index c049f5c..c17cd38 100644 --- a/poppler/Decrypt.h +++ b/poppler/Decrypt.h @@ -107,7 +107,7 @@ public: virtual void reset(); virtual int getChar(); virtual int lookChar() = 0; - virtual int getPos(); + virtual Goffset getPos(); virtual GBool isBinary(GBool last); virtual Stream *getUndecodedStream() { return this; } void setAutoDelete(GBool val); diff --git a/poppler/Error.cc b/poppler/Error.cc index ce71820..9ff7b5d 100644 --- a/poppler/Error.cc +++ b/poppler/Error.cc @@ -48,17 +48,17 @@ static const char *errorCategoryNames[] = { }; static void (*errorCbk)(void *data, ErrorCategory category, - int pos, char *msg) = NULL; + Goffset pos, char *msg) = NULL; static void *errorCbkData = NULL; void setErrorCallback(void (*cbk)(void *data, ErrorCategory category, - int pos, char *msg), + Goffset pos, char *msg), void *data) { errorCbk = cbk; errorCbkData = data; } -void CDECL error(ErrorCategory category, int pos, const char *msg, ...) { +void CDECL error(ErrorCategory category, Goffset pos, const char *msg, ...) { va_list args; GooString *s, *sanitized; @@ -84,8 +84,8 @@ void CDECL error(ErrorCategory category, int pos, const char *msg, ...) { (*errorCbk)(errorCbkData, category, pos, sanitized->getCString()); } else { if (pos >= 0) { - fprintf(stderr, "%s (%d): %s\n", - errorCategoryNames[category], pos, sanitized->getCString()); + fprintf(stderr, "%s (%lld): %s\n", + errorCategoryNames[category], (long long)pos, sanitized->getCString()); } else { fprintf(stderr, "%s: %s\n", errorCategoryNames[category], sanitized->getCString()); diff --git a/poppler/Error.h b/poppler/Error.h index d7a0991..cf8874d 100644 --- a/poppler/Error.h +++ b/poppler/Error.h @@ -31,6 +31,7 @@ #include #include "poppler-config.h" +#include "goo/gtypes.h" enum ErrorCategory { errSyntaxWarning, // PDF syntax error which can be worked around; @@ -48,9 +49,9 @@ enum ErrorCategory { }; extern void setErrorCallback(void (*cbk)(void *data, ErrorCategory category, - int pos, char *msg), + Goffset pos, char *msg), void *data); -extern void CDECL error(ErrorCategory category, int pos, const char *msg, ...); +extern void CDECL error(ErrorCategory category, Goffset pos, const char *msg, ...); #endif diff --git a/poppler/Hints.cc b/poppler/Hints.cc index 13bcc90..5591535 100644 --- a/poppler/Hints.cc +++ b/poppler/Hints.cc @@ -51,7 +51,7 @@ Hints::Hints(BaseStream *str, Linearization *linearization, XRef *xref, Security pageObjectNum = (int *) gmallocn_checkoverflow(nPages, sizeof(int)); xRefOffset = (Guint *) gmallocn_checkoverflow(nPages, sizeof(Guint)); pageLength = (Guint *) gmallocn_checkoverflow(nPages, sizeof(Guint)); - pageOffset = (Guint *) gmallocn_checkoverflow(nPages, sizeof(Guint)); + pageOffset = (Goffset *) gmallocn_checkoverflow(nPages, sizeof(Goffset)); numSharedObject = (Guint *) gmallocn_checkoverflow(nPages, sizeof(Guint)); sharedObjectId = (Guint **) gmallocn_checkoverflow(nPages, sizeof(Guint*)); if (!nObjects || !pageObjectNum || !xRefOffset || !pageLength || !pageOffset || @@ -344,7 +344,7 @@ void Hints::readSharedObjectsTable(Stream *str) } } -Guint Hints::getPageOffset(int page) +Goffset Hints::getPageOffset(int page) { if ((page < 1) || (page > nPages)) return 0; diff --git a/poppler/Hints.h b/poppler/Hints.h index d598e79..69d8209 100644 --- a/poppler/Hints.h +++ b/poppler/Hints.h @@ -33,7 +33,7 @@ public: ~Hints(); int getPageObjectNum(int page); - Guint getPageOffset(int page); + Goffset getPageOffset(int page); std::vector* getPageRanges(int page); private: @@ -54,7 +54,7 @@ private: int nPages; int pageFirst; int pageObjectFirst; - Guint pageOffsetFirst; + Goffset pageOffsetFirst; Guint pageEndFirst; int objectNumberFirst; @@ -76,7 +76,7 @@ private: int *pageObjectNum; Guint *xRefOffset; Guint *pageLength; - Guint *pageOffset; + Goffset *pageOffset; Guint *numSharedObject; Guint **sharedObjectId; diff --git a/poppler/JBIG2Stream.cc b/poppler/JBIG2Stream.cc index afba8c6..7f5e0ec 100644 --- a/poppler/JBIG2Stream.cc +++ b/poppler/JBIG2Stream.cc @@ -1284,7 +1284,7 @@ int JBIG2Stream::lookChar() { return EOF; } -int JBIG2Stream::getPos() { +Goffset JBIG2Stream::getPos() { if (pageBitmap == NULL) { return 0; } @@ -1320,7 +1320,7 @@ void JBIG2Stream::readSegments() { Guint segNum, segFlags, segType, page, segLength; Guint refFlags, nRefSegs; Guint *refSegs; - int segDataPos; + Goffset segDataPos; int c1, c2, c3; Guint i; @@ -1483,7 +1483,7 @@ void JBIG2Stream::readSegments() { if (segLength != 0xffffffff) { - int segExtraBytes = segDataPos + segLength - curStr->getPos(); + Goffset segExtraBytes = segDataPos + segLength - curStr->getPos(); if (segExtraBytes > 0) { // If we didn't read all of the bytes in the segment data, @@ -1501,7 +1501,7 @@ void JBIG2Stream::readSegments() { // hopefully we're not doing this much int trash; - for (int i = segExtraBytes; i > 0; i--) { + for (Goffset i = segExtraBytes; i > 0; i--) { readByte(&trash); } diff --git a/poppler/JBIG2Stream.h b/poppler/JBIG2Stream.h index c518aa5..5c58c49 100644 --- a/poppler/JBIG2Stream.h +++ b/poppler/JBIG2Stream.h @@ -50,7 +50,7 @@ public: virtual StreamKind getKind() { return strJBIG2; } virtual void reset(); virtual void close(); - virtual int getPos(); + virtual Goffset getPos(); virtual int getChar(); virtual int lookChar(); virtual GooString *getPSFilter(int psLevel, const char *indent); diff --git a/poppler/JPEG2000Stream.cc b/poppler/JPEG2000Stream.cc index e2fd808..fcfdece 100644 --- a/poppler/JPEG2000Stream.cc +++ b/poppler/JPEG2000Stream.cc @@ -46,7 +46,7 @@ void JPXStream::close() { } } -int JPXStream::getPos() { +Goffset JPXStream::getPos() { return counter * ncomps + ccounter; } diff --git a/poppler/JPEG2000Stream.h b/poppler/JPEG2000Stream.h index 5aed32d..2b7afaf 100644 --- a/poppler/JPEG2000Stream.h +++ b/poppler/JPEG2000Stream.h @@ -29,7 +29,7 @@ public: virtual StreamKind getKind() { return strJPX; } virtual void reset(); virtual void close(); - virtual int getPos(); + virtual Goffset getPos(); virtual int getChar(); virtual int lookChar(); virtual GooString *getPSFilter(int psLevel, const char *indent); diff --git a/poppler/Lexer.h b/poppler/Lexer.h index 284479d..2a35e39 100644 --- a/poppler/Lexer.h +++ b/poppler/Lexer.h @@ -67,12 +67,12 @@ public: { return curStr.isStream() ? curStr.getStream() : (Stream *)NULL; } // Get current position in file. This is only used for error - // messages, so it returns an int instead of a Guint. - int getPos() - { return curStr.isStream() ? (int)curStr.streamGetPos() : -1; } + // messages. + Goffset getPos() + { return curStr.isStream() ? curStr.streamGetPos() : -1; } // Set position in file. - void setPos(Guint pos, int dir = 0) + void setPos(Goffset pos, int dir = 0) { if (curStr.isStream()) curStr.streamSetPos(pos, dir); } // Returns true if is a whitespace character. diff --git a/poppler/Object.h b/poppler/Object.h index 6f916fe..81c5328 100644 --- a/poppler/Object.h +++ b/poppler/Object.h @@ -230,8 +230,8 @@ public: int streamGetChars(int nChars, Guchar *buffer); int streamLookChar(); char *streamGetLine(char *buf, int size); - Guint streamGetPos(); - void streamSetPos(Guint pos, int dir = 0); + Goffset streamGetPos(); + void streamSetPos(Goffset pos, int dir = 0); Dict *streamGetDict(); // Output. @@ -351,10 +351,10 @@ inline int Object::streamLookChar() inline char *Object::streamGetLine(char *buf, int size) { OBJECT_TYPE_CHECK(objStream); return stream->getLine(buf, size); } -inline Guint Object::streamGetPos() +inline Goffset Object::streamGetPos() { OBJECT_TYPE_CHECK(objStream); return stream->getPos(); } -inline void Object::streamSetPos(Guint pos, int dir) +inline void Object::streamSetPos(Goffset pos, int dir) { OBJECT_TYPE_CHECK(objStream); stream->setPos(pos, dir); } inline Dict *Object::streamGetDict() diff --git a/poppler/PDFDoc.cc b/poppler/PDFDoc.cc index 48b1f5e..e7fbac6 100644 --- a/poppler/PDFDoc.cc +++ b/poppler/PDFDoc.cc @@ -106,7 +106,7 @@ void PDFDoc::init() #ifndef DISABLE_OUTLINE outline = NULL; #endif - startXRefPos = ~(Guint)0; + startXRefPos = -1; secHdlr = NULL; pageCache = NULL; } @@ -119,7 +119,7 @@ PDFDoc::PDFDoc() PDFDoc::PDFDoc(GooString *fileNameA, GooString *ownerPassword, GooString *userPassword, void *guiDataA) { Object obj; - int size = 0; + Goffset size = 0; #ifdef _WIN32 int n, i; #endif @@ -349,7 +349,7 @@ PDFDoc::~PDFDoc() { GBool PDFDoc::checkFooter() { // we look in the last 1024 chars because Adobe does the same char *eof = new char[1025]; - int pos = str->getPos(); + Goffset pos = str->getPos(); str->setPos(1024, -1); int i, ch; for (i = 0; i < 1024; i++) @@ -747,7 +747,7 @@ int PDFDoc::savePageAs(GooString *name, int pageNo) objectsCount++; page.free(); - Guint uxrefOffset = outStr->getPos(); + Goffset uxrefOffset = outStr->getPos(); Ref ref; ref.num = rootNum; ref.gen = 0; @@ -880,7 +880,7 @@ void PDFDoc::saveIncrementalUpdate (OutStream* outStr) return; } - Guint uxrefOffset = outStr->getPos(); + Goffset uxrefOffset = outStr->getPos(); int numobjects = xref->getNumObjects(); const char *fileNameA = fileName ? fileName->getCString() : NULL; Ref rootRef, uxrefStreamRef; @@ -963,7 +963,7 @@ void PDFDoc::saveCompleteRewrite (OutStream* outStr) obj1.free(); } } - Guint uxrefOffset = outStr->getPos(); + Goffset uxrefOffset = outStr->getPos(); writeXRefTableTrailer(uxrefOffset, uxref, gTrue /* write all entries */, uxref->getNumObjects(), outStr, gFalse /* complete rewrite */); delete uxref; @@ -999,17 +999,21 @@ void PDFDoc::writeRawStream (Stream* str, OutStream* outStr) { Object obj1; str->getDict()->lookup("Length", &obj1); - if (!obj1.isInt()) { + if (!obj1.isInt() && !obj1.isInt64()) { error (errSyntaxError, -1, "PDFDoc::writeRawStream, no Length in stream dict"); return; } - const int length = obj1.getInt(); + Goffset length; + if (obj1.isInt()) + length = obj1.getInt(); + else + length = obj1.getInt64(); obj1.free(); outStr->printf("stream\r\n"); str->unfilteredReset(); - for (int i=0; igetUnfilteredChar(); outStr->printf("%c", c); } @@ -1075,7 +1079,7 @@ void PDFDoc::writeString (GooString* s, OutStream* outStr, Guchar *fileKey, Guint PDFDoc::writeObjectHeader (Ref *ref, OutStream* outStr) { - Guint offset = outStr->getPos(); + Goffset offset = outStr->getPos(); outStr->printf("%i %i obj ", ref->num, ref->gen); return offset; } @@ -1085,7 +1089,7 @@ void PDFDoc::writeObject (Object* obj, OutStream* outStr, XRef *xRef, Guint numO { Array *array; Object obj1; - int tmp; + Goffset tmp; switch (obj->getType()) { case objBool: @@ -1152,7 +1156,7 @@ void PDFDoc::writeObject (Object* obj, OutStream* outStr, XRef *xRef, Guint numO for (int c=stream->getChar(); c!=EOF; c=stream->getChar()) { tmp++; } - obj1.initInt(tmp); + obj1.initInt64(tmp); stream->getDict()->set("Length", &obj1); //Remove Stream encoding @@ -1169,10 +1173,10 @@ void PDFDoc::writeObject (Object* obj, OutStream* outStr, XRef *xRef, Guint numO if (fs) { BaseStream *bs = fs->getBaseStream(); if (bs) { - Guint streamEnd; + Goffset streamEnd; if (xRef->getStreamEnd(bs->getStart(), &streamEnd)) { Object val; - val.initInt(streamEnd - bs->getStart()); + val.initInt64(streamEnd - bs->getStart()); stream->getDict()->set("Length", &val); } } @@ -1209,7 +1213,7 @@ void PDFDoc::writeObjectFooter (OutStream* outStr) } Dict *PDFDoc::createTrailerDict(int uxrefSize, GBool incrUpdate, Guint startxRef, - Ref *root, XRef *xRef, const char *fileName, Guint fileSize) + Ref *root, XRef *xRef, const char *fileName, Goffset fileSize) { Dict *trailerDict = new Dict(xRef); Object obj1; @@ -1230,7 +1234,7 @@ Dict *PDFDoc::createTrailerDict(int uxrefSize, GBool incrUpdate, Guint startxRef if (fileName) message.append(fileName); - sprintf(buffer, "%i", fileSize); + sprintf(buffer, "%lli", (long long)fileSize); message.append(buffer); //info dict -- only use text string @@ -1308,7 +1312,7 @@ Dict *PDFDoc::createTrailerDict(int uxrefSize, GBool incrUpdate, Guint startxRef return trailerDict; } -void PDFDoc::writeXRefTableTrailer(Dict *trailerDict, XRef *uxref, GBool writeAllEntries, Guint uxrefOffset, OutStream* outStr, XRef *xRef) +void PDFDoc::writeXRefTableTrailer(Dict *trailerDict, XRef *uxref, GBool writeAllEntries, Goffset uxrefOffset, OutStream* outStr, XRef *xRef) { uxref->writeTableToFile( outStr, writeAllEntries ); outStr->printf( "trailer\r\n"); @@ -1318,7 +1322,7 @@ void PDFDoc::writeXRefTableTrailer(Dict *trailerDict, XRef *uxref, GBool writeAl outStr->printf( "%%%%EOF\r\n"); } -void PDFDoc::writeXRefStreamTrailer (Dict *trailerDict, XRef *uxref, Ref *uxrefStreamRef, Guint uxrefOffset, OutStream* outStr, XRef *xRef) +void PDFDoc::writeXRefStreamTrailer (Dict *trailerDict, XRef *uxref, Ref *uxrefStreamRef, Goffset uxrefOffset, OutStream* outStr, XRef *xRef) { GooString stmData; @@ -1579,14 +1583,14 @@ PDFDoc *PDFDoc::ErrorPDFDoc(int errorCode, GooString *fileNameA) return doc; } -Guint PDFDoc::strToUnsigned(char *s) { - Guint x, d; +long long PDFDoc::strToLongLong(char *s) { + long long x, d; char *p; x = 0; for (p = s; *p && isdigit(*p & 0xff); ++p) { d = *p - '0'; - if (x > (UINT_MAX - d) / 10) { + if (x > (LLONG_MAX - d) / 10) { break; } x = 10 * x + d; @@ -1595,9 +1599,9 @@ Guint PDFDoc::strToUnsigned(char *s) { } // Read the 'startxref' position. -Guint PDFDoc::getStartXRef() +Goffset PDFDoc::getStartXRef() { - if (startXRefPos == ~(Guint)0) { + if (startXRefPos == -1) { if (isLinearized()) { char buf[linearizationSearchSize+1]; @@ -1648,7 +1652,7 @@ Guint PDFDoc::getStartXRef() startXRefPos = 0; } else { for (p = &buf[i+9]; isspace(*p); ++p) ; - startXRefPos = strToUnsigned(p); + startXRefPos = strToLongLong(p); } } @@ -1657,7 +1661,7 @@ Guint PDFDoc::getStartXRef() return startXRefPos; } -Guint PDFDoc::getMainXRefEntriesOffset() +Goffset PDFDoc::getMainXRefEntriesOffset() { Guint mainXRefEntriesOffset = 0; diff --git a/poppler/PDFDoc.h b/poppler/PDFDoc.h index 4562346..d3ece6b 100644 --- a/poppler/PDFDoc.h +++ b/poppler/PDFDoc.h @@ -250,11 +250,11 @@ public: // Ownership goes to the caller static Dict *createTrailerDict (int uxrefSize, GBool incrUpdate, Guint startxRef, - Ref *root, XRef *xRef, const char *fileName, Guint fileSize); + Ref *root, XRef *xRef, const char *fileName, Goffset fileSize); static void writeXRefTableTrailer (Dict *trailerDict, XRef *uxref, GBool writeAllEntries, - Guint uxrefOffset, OutStream* outStr, XRef *xRef); + Goffset uxrefOffset, OutStream* outStr, XRef *xRef); static void writeXRefStreamTrailer (Dict *trailerDict, XRef *uxref, Ref *uxrefStreamRef, - Guint uxrefOffset, OutStream* outStr, XRef *xRef); + Goffset uxrefOffset, OutStream* outStr, XRef *xRef); private: // insert referenced objects in XRef @@ -294,11 +294,11 @@ private: void checkHeader(); GBool checkEncryption(GooString *ownerPassword, GooString *userPassword); // Get the offset of the start xref table. - Guint getStartXRef(); + Goffset getStartXRef(); // Get the offset of the entries in the main XRef table of a // linearized document (0 for non linearized documents). - Guint getMainXRefEntriesOffset(); - Guint strToUnsigned(char *s); + Goffset getMainXRefEntriesOffset(); + long long strToLongLong(char *s); GooString *fileName; #ifdef _WIN32 @@ -325,7 +325,7 @@ private: //then the POSIX errno will be here. int fopenErrno; - Guint startXRefPos; // offset of last xref table + Goffset startXRefPos; // offset of last xref table }; #endif diff --git a/poppler/Parser.cc b/poppler/Parser.cc index 5b80293..1d808fd 100644 --- a/poppler/Parser.cc +++ b/poppler/Parser.cc @@ -193,7 +193,8 @@ Stream *Parser::makeStream(Object *dict, Guchar *fileKey, Object obj; BaseStream *baseStr; Stream *str; - Guint pos, endPos, length; + Goffset length; + Goffset pos, endPos; // get stream start position lexer->skipToNextLine(); @@ -205,7 +206,10 @@ Stream *Parser::makeStream(Object *dict, Guchar *fileKey, // get length dict->dictLookup("Length", &obj, recursion); if (obj.isInt()) { - length = (Guint)obj.getInt(); + length = obj.getInt(); + obj.free(); + } else if (obj.isInt64()) { + length = obj.getInt64(); obj.free(); } else { error(errSyntaxError, getPos(), "Bad 'Length' attribute in stream"); @@ -249,7 +253,7 @@ Stream *Parser::makeStream(Object *dict, Guchar *fileKey, } length = lexer->getPos() - pos; if (buf1.isCmd("endstream")) { - obj.initInt(length); + obj.initInt64(length); dict->dictSet("Length", &obj); obj.free(); } diff --git a/poppler/Parser.h b/poppler/Parser.h index 5ab4099..cb97caf 100644 --- a/poppler/Parser.h +++ b/poppler/Parser.h @@ -58,7 +58,7 @@ public: Stream *getStream() { return lexer->getStream(); } // Get current position in file. - int getPos() { return lexer->getPos(); } + Goffset getPos() { return lexer->getPos(); } private: diff --git a/poppler/Stream.cc b/poppler/Stream.cc index 414ff3f..7871fae 100644 --- a/poppler/Stream.cc +++ b/poppler/Stream.cc @@ -339,7 +339,7 @@ OutStream::~OutStream () //------------------------------------------------------------------------ // FileOutStream //------------------------------------------------------------------------ -FileOutStream::FileOutStream (FILE* fa, Guint startA) +FileOutStream::FileOutStream (FILE* fa, Goffset startA) { f = fa; start = startA; @@ -355,7 +355,7 @@ void FileOutStream::close () } -int FileOutStream::getPos () +Goffset FileOutStream::getPos () { return ftell(f); } @@ -378,7 +378,7 @@ void FileOutStream::printf(const char *format, ...) // BaseStream //------------------------------------------------------------------------ -BaseStream::BaseStream(Object *dictA, Guint lengthA) { +BaseStream::BaseStream(Object *dictA, Goffset lengthA) { dict = *dictA; length = lengthA; } @@ -402,7 +402,7 @@ void FilterStream::close() { str->close(); } -void FilterStream::setPos(Guint pos, int dir) { +void FilterStream::setPos(Goffset pos, int dir) { error(errInternal, -1, "Internal: called setPos() on FilterStream"); } @@ -729,8 +729,8 @@ GBool StreamPredictor::getNextLine() { // FileStream //------------------------------------------------------------------------ -FileStream::FileStream(FILE *fA, Guint startA, GBool limitedA, - Guint lengthA, Object *dictA): +FileStream::FileStream(FILE *fA, Goffset startA, GBool limitedA, + Goffset lengthA, Object *dictA): BaseStream(dictA, lengthA) { f = fA; start = startA; @@ -746,20 +746,20 @@ FileStream::~FileStream() { close(); } -Stream *FileStream::makeSubStream(Guint startA, GBool limitedA, - Guint lengthA, Object *dictA) { +Stream *FileStream::makeSubStream(Goffset startA, GBool limitedA, + Goffset lengthA, Object *dictA) { return new FileStream(f, startA, limitedA, lengthA, dictA); } void FileStream::reset() { #if HAVE_FSEEKO - savePos = (Guint)ftello(f); + savePos = ftello(f); fseeko(f, start, SEEK_SET); #elif HAVE_FSEEK64 - savePos = (Guint)ftell64(f); + savePos = ftell64(f); fseek64(f, start, SEEK_SET); #else - savePos = (Guint)ftell(f); + savePos = ftell(f); fseek(f, start, SEEK_SET); #endif saved = gTrue; @@ -801,8 +801,8 @@ GBool FileStream::fillBuf() { return gTrue; } -void FileStream::setPos(Guint pos, int dir) { - Guint size; +void FileStream::setPos(Goffset pos, int dir) { + Goffset size; if (dir >= 0) { #if HAVE_FSEEKO @@ -816,31 +816,31 @@ void FileStream::setPos(Guint pos, int dir) { } else { #if HAVE_FSEEKO fseeko(f, 0, SEEK_END); - size = (Guint)ftello(f); + size = ftello(f); #elif HAVE_FSEEK64 fseek64(f, 0, SEEK_END); - size = (Guint)ftell64(f); + size = ftell64(f); #else fseek(f, 0, SEEK_END); - size = (Guint)ftell(f); + size = ftell(f); #endif if (pos > size) - pos = (Guint)size; + pos = size; #if HAVE_FSEEKO - fseeko(f, -(int)pos, SEEK_END); - bufPos = (Guint)ftello(f); + fseeko(f, -pos, SEEK_END); + bufPos = ftello(f); #elif HAVE_FSEEK64 - fseek64(f, -(int)pos, SEEK_END); - bufPos = (Guint)ftell64(f); + fseek64(f, -pos, SEEK_END); + bufPos = ftell64(f); #else - fseek(f, -(int)pos, SEEK_END); - bufPos = (Guint)ftell(f); + fseek(f, -pos, SEEK_END); + bufPos = ftell(f); #endif } bufPtr = bufEnd = buf; } -void FileStream::moveStart(int delta) { +void FileStream::moveStart(Goffset delta) { start += delta; bufPtr = bufEnd = buf; bufPos = start; @@ -850,8 +850,8 @@ void FileStream::moveStart(int delta) { // CachedFileStream //------------------------------------------------------------------------ -CachedFileStream::CachedFileStream(CachedFile *ccA, Guint startA, - GBool limitedA, Guint lengthA, Object *dictA) +CachedFileStream::CachedFileStream(CachedFile *ccA, Goffset startA, + GBool limitedA, Goffset lengthA, Object *dictA) : BaseStream(dictA, lengthA) { cc = ccA; @@ -870,8 +870,8 @@ CachedFileStream::~CachedFileStream() cc->decRefCnt(); } -Stream *CachedFileStream::makeSubStream(Guint startA, GBool limitedA, - Guint lengthA, Object *dictA) +Stream *CachedFileStream::makeSubStream(Goffset startA, GBool limitedA, + Goffset lengthA, Object *dictA) { cc->incRefCnt(); return new CachedFileStream(cc, startA, limitedA, lengthA, dictA); @@ -917,7 +917,7 @@ GBool CachedFileStream::fillBuf() return gTrue; } -void CachedFileStream::setPos(Guint pos, int dir) +void CachedFileStream::setPos(Goffset pos, int dir) { Guint size; @@ -938,7 +938,7 @@ void CachedFileStream::setPos(Guint pos, int dir) bufPtr = bufEnd = buf; } -void CachedFileStream::moveStart(int delta) +void CachedFileStream::moveStart(Goffset delta) { start += delta; bufPtr = bufEnd = buf; @@ -949,7 +949,7 @@ void CachedFileStream::moveStart(int delta) // MemStream //------------------------------------------------------------------------ -MemStream::MemStream(char *bufA, Guint startA, Guint lengthA, Object *dictA): +MemStream::MemStream(char *bufA, Goffset startA, Guint lengthA, Object *dictA): BaseStream(dictA, lengthA) { buf = bufA; start = startA; @@ -965,10 +965,10 @@ MemStream::~MemStream() { } } -Stream *MemStream::makeSubStream(Guint startA, GBool limited, - Guint lengthA, Object *dictA) { +Stream *MemStream::makeSubStream(Goffset startA, GBool limited, + Goffset lengthA, Object *dictA) { MemStream *subStr; - Guint newLength; + Goffset newLength; if (!limited || startA + lengthA > start + length) { newLength = start + length - startA; @@ -1002,7 +1002,7 @@ int MemStream::getChars(int nChars, Guchar *buffer) { return n; } -void MemStream::setPos(Guint pos, int dir) { +void MemStream::setPos(Goffset pos, int dir) { Guint i; if (dir >= 0) { @@ -1018,7 +1018,7 @@ void MemStream::setPos(Guint pos, int dir) { bufPtr = buf + i; } -void MemStream::moveStart(int delta) { +void MemStream::moveStart(Goffset delta) { start += delta; length -= delta; bufPtr = buf + start; @@ -1029,7 +1029,7 @@ void MemStream::moveStart(int delta) { //------------------------------------------------------------------------ EmbedStream::EmbedStream(Stream *strA, Object *dictA, - GBool limitedA, Guint lengthA): + GBool limitedA, Goffset lengthA): BaseStream(dictA, lengthA) { str = strA; limited = limitedA; @@ -1039,8 +1039,8 @@ EmbedStream::EmbedStream(Stream *strA, Object *dictA, EmbedStream::~EmbedStream() { } -Stream *EmbedStream::makeSubStream(Guint start, GBool limitedA, - Guint lengthA, Object *dictA) { +Stream *EmbedStream::makeSubStream(Goffset start, GBool limitedA, + Goffset lengthA, Object *dictA) { error(errInternal, -1, "Called makeSubStream() on EmbedStream"); return NULL; } @@ -1064,22 +1064,22 @@ int EmbedStream::getChars(int nChars, Guchar *buffer) { if (nChars <= 0) { return 0; } - if (limited && length < (Guint)nChars) { - nChars = (int)length; + if (limited && length < nChars) { + nChars = length; } return str->doGetChars(nChars, buffer); } -void EmbedStream::setPos(Guint pos, int dir) { +void EmbedStream::setPos(Goffset pos, int dir) { error(errInternal, -1, "Internal: called setPos() on EmbedStream"); } -Guint EmbedStream::getStart() { +Goffset EmbedStream::getStart() { error(errInternal, -1, "Internal: called getStart() on EmbedStream"); return 0; } -void EmbedStream::moveStart(int delta) { +void EmbedStream::moveStart(Goffset delta) { error(errInternal, -1, "Internal: called moveStart() on EmbedStream"); } diff --git a/poppler/Stream.h b/poppler/Stream.h index 20b5fd6..6ab10f8 100644 --- a/poppler/Stream.h +++ b/poppler/Stream.h @@ -183,12 +183,12 @@ public: virtual char *getLine(char *buf, int size); // Get current position in file. - virtual int getPos() = 0; + virtual Goffset getPos() = 0; // Go to a position in the stream. If is negative, the // position is from the end of the file; otherwise the position is // from the start of the file. - virtual void setPos(Guint pos, int dir = 0) = 0; + virtual void setPos(Goffset pos, int dir = 0) = 0; // Get PostScript command for the filter(s). virtual GooString *getPSFilter(int psLevel, const char *indent); @@ -251,7 +251,7 @@ public: virtual void close() = 0; // Return position in stream - virtual int getPos() = 0; + virtual Goffset getPos() = 0; // Put a char in the stream virtual void put (char c) = 0; @@ -270,20 +270,20 @@ private: //------------------------------------------------------------------------ class FileOutStream : public OutStream { public: - FileOutStream (FILE* fa, Guint startA); + FileOutStream (FILE* fa, Goffset startA); virtual ~FileOutStream (); virtual void close(); - virtual int getPos(); + virtual Goffset getPos(); virtual void put (char c); virtual void printf (const char *format, ...); private: FILE *f; - Guint start; + Goffset start; }; @@ -297,25 +297,25 @@ private: class BaseStream: public Stream { public: - BaseStream(Object *dictA, Guint lengthA); + BaseStream(Object *dictA, Goffset lengthA); virtual ~BaseStream(); - virtual Stream *makeSubStream(Guint start, GBool limited, - Guint length, Object *dict) = 0; - virtual void setPos(Guint pos, int dir = 0) = 0; + virtual Stream *makeSubStream(Goffset start, GBool limited, + Goffset length, Object *dict) = 0; + virtual void setPos(Goffset pos, int dir = 0) = 0; virtual GBool isBinary(GBool last = gTrue) { return last; } virtual BaseStream *getBaseStream() { return this; } virtual Stream *getUndecodedStream() { return this; } virtual Dict *getDict() { return dict.getDict(); } virtual GooString *getFileName() { return NULL; } - virtual Guint getLength() { return length; } + virtual Goffset getLength() { return length; } // Get/set position of first byte of stream within the file. - virtual Guint getStart() = 0; - virtual void moveStart(int delta) = 0; + virtual Goffset getStart() = 0; + virtual void moveStart(Goffset delta) = 0; protected: - Guint length; + Goffset length; private: @@ -334,8 +334,8 @@ public: FilterStream(Stream *strA); virtual ~FilterStream(); virtual void close(); - virtual int getPos() { return str->getPos(); } - virtual void setPos(Guint pos, int dir = 0); + virtual Goffset getPos() { return str->getPos(); } + virtual void setPos(Goffset pos, int dir = 0); virtual BaseStream *getBaseStream() { return str->getBaseStream(); } virtual Stream *getUndecodedStream() { return str->getUndecodedStream(); } virtual Dict *getDict() { return str->getDict(); } @@ -439,11 +439,11 @@ private: class FileStream: public BaseStream { public: - FileStream(FILE *fA, Guint startA, GBool limitedA, - Guint lengthA, Object *dictA); + FileStream(FILE *fA, Goffset startA, GBool limitedA, + Goffset lengthA, Object *dictA); virtual ~FileStream(); - virtual Stream *makeSubStream(Guint startA, GBool limitedA, - Guint lengthA, Object *dictA); + virtual Stream *makeSubStream(Goffset startA, GBool limitedA, + Goffset lengthA, Object *dictA); virtual StreamKind getKind() { return strFile; } virtual void reset(); virtual void close(); @@ -451,10 +451,10 @@ public: { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); } virtual int lookChar() { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); } - virtual int getPos() { return bufPos + (bufPtr - buf); } - virtual void setPos(Guint pos, int dir = 0); - virtual Guint getStart() { return start; } - virtual void moveStart(int delta); + virtual Goffset getPos() { return bufPos + (bufPtr - buf); } + virtual void setPos(Goffset pos, int dir = 0); + virtual Goffset getStart() { return start; } + virtual void moveStart(Goffset delta); virtual int getUnfilteredChar () { return getChar(); } virtual void unfilteredReset () { reset(); } @@ -487,13 +487,13 @@ private: } FILE *f; - Guint start; + Goffset start; GBool limited; char buf[fileStreamBufSize]; char *bufPtr; char *bufEnd; - Guint bufPos; - int savePos; + Goffset bufPos; + Goffset savePos; GBool saved; }; @@ -506,11 +506,11 @@ private: class CachedFileStream: public BaseStream { public: - CachedFileStream(CachedFile *ccA, Guint startA, GBool limitedA, - Guint lengthA, Object *dictA); + CachedFileStream(CachedFile *ccA, Goffset startA, GBool limitedA, + Goffset lengthA, Object *dictA); virtual ~CachedFileStream(); - virtual Stream *makeSubStream(Guint startA, GBool limitedA, - Guint lengthA, Object *dictA); + virtual Stream *makeSubStream(Goffset startA, GBool limitedA, + Goffset lengthA, Object *dictA); virtual StreamKind getKind() { return strCachedFile; } virtual void reset(); virtual void close(); @@ -518,10 +518,10 @@ public: { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); } virtual int lookChar() { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); } - virtual int getPos() { return bufPos + (bufPtr - buf); } - virtual void setPos(Guint pos, int dir = 0); - virtual Guint getStart() { return start; } - virtual void moveStart(int delta); + virtual Goffset getPos() { return bufPos + (bufPtr - buf); } + virtual void setPos(Goffset pos, int dir = 0); + virtual Goffset getStart() { return start; } + virtual void moveStart(Goffset delta); virtual int getUnfilteredChar () { return getChar(); } virtual void unfilteredReset () { reset(); } @@ -531,7 +531,7 @@ private: GBool fillBuf(); CachedFile *cc; - Guint start; + Goffset start; GBool limited; char buf[cachedStreamBufSize]; char *bufPtr; @@ -549,10 +549,10 @@ private: class MemStream: public BaseStream { public: - MemStream(char *bufA, Guint startA, Guint lengthA, Object *dictA); + MemStream(char *bufA, Goffset startA, Guint lengthA, Object *dictA); virtual ~MemStream(); - virtual Stream *makeSubStream(Guint start, GBool limited, - Guint lengthA, Object *dictA); + virtual Stream *makeSubStream(Goffset start, GBool limited, + Goffset lengthA, Object *dictA); virtual StreamKind getKind() { return strWeird; } virtual void reset(); virtual void close(); @@ -560,10 +560,10 @@ public: { return (bufPtr < bufEnd) ? (*bufPtr++ & 0xff) : EOF; } virtual int lookChar() { return (bufPtr < bufEnd) ? (*bufPtr & 0xff) : EOF; } - virtual int getPos() { return (int)(bufPtr - buf); } - virtual void setPos(Guint pos, int dir = 0); - virtual Guint getStart() { return start; } - virtual void moveStart(int delta); + virtual Goffset getPos() { return (int)(bufPtr - buf); } + virtual void setPos(Goffset pos, int dir = 0); + virtual Goffset getStart() { return start; } + virtual void moveStart(Goffset delta); //if needFree = true, the stream will delete buf when it is destroyed //otherwise it will not touch it. Default value is false @@ -578,7 +578,7 @@ private: virtual int getChars(int nChars, Guchar *buffer); char *buf; - Guint start; + Goffset start; char *bufEnd; char *bufPtr; GBool needFree; @@ -597,18 +597,18 @@ private: class EmbedStream: public BaseStream { public: - EmbedStream(Stream *strA, Object *dictA, GBool limitedA, Guint lengthA); + EmbedStream(Stream *strA, Object *dictA, GBool limitedA, Goffset lengthA); virtual ~EmbedStream(); - virtual Stream *makeSubStream(Guint start, GBool limitedA, - Guint lengthA, Object *dictA); + virtual Stream *makeSubStream(Goffset start, GBool limitedA, + Goffset lengthA, Object *dictA); virtual StreamKind getKind() { return str->getKind(); } virtual void reset() {} virtual int getChar(); virtual int lookChar(); - virtual int getPos() { return str->getPos(); } - virtual void setPos(Guint pos, int dir = 0); - virtual Guint getStart(); - virtual void moveStart(int delta); + virtual Goffset getPos() { return str->getPos(); } + virtual void setPos(Goffset pos, int dir = 0); + virtual Goffset getStart(); + virtual void moveStart(Goffset delta); virtual int getUnfilteredChar () { return str->getUnfilteredChar(); } virtual void unfilteredReset () { str->unfilteredReset(); } diff --git a/poppler/XRef.cc b/poppler/XRef.cc index 81e939a..96ea24a 100644 --- a/poppler/XRef.cc +++ b/poppler/XRef.cc @@ -37,8 +37,10 @@ #include #include #include +#include #include #include +#include #include "goo/gmem.h" #include "Object.h" #include "Stream.h" @@ -130,9 +132,10 @@ class ObjectStreamItem : public PopplerCacheItem ObjectStream::ObjectStream(XRef *xref, int objStrNumA) { Stream *str; Parser *parser; - int *offsets; + Goffset *offsets; Object objStr, obj1, obj2; - int first, i; + Goffset first; + int i; objStrNum = objStrNumA; nObjects = 0; @@ -154,11 +157,15 @@ ObjectStream::ObjectStream(XRef *xref, int objStrNumA) { goto err1; } - if (!objStr.streamGetDict()->lookup("First", &obj1)->isInt()) { + objStr.streamGetDict()->lookup("First", &obj1); + if (!obj1.isInt() && !obj1.isInt64()) { obj1.free(); goto err1; } - first = obj1.getInt(); + if (obj1.isInt()) + first = obj1.getInt(); + else + first = obj1.getInt64(); obj1.free(); if (first < 0) { goto err1; @@ -173,7 +180,7 @@ ObjectStream::ObjectStream(XRef *xref, int objStrNumA) { } objs = new Object[nObjects]; objNums = (int *)gmallocn(nObjects, sizeof(int)); - offsets = (int *)gmallocn(nObjects, sizeof(int)); + offsets = (Goffset *)gmallocn(nObjects, sizeof(Goffset)); // parse the header: object numbers and offsets objStr.streamReset(); @@ -183,7 +190,7 @@ ObjectStream::ObjectStream(XRef *xref, int objStrNumA) { for (i = 0; i < nObjects; ++i) { parser->getObj(&obj1); parser->getObj(&obj2); - if (!obj1.isInt() || !obj2.isInt()) { + if (!obj1.isInt() || !(obj2.isInt() || obj2.isInt64())) { obj1.free(); obj2.free(); delete parser; @@ -191,7 +198,10 @@ ObjectStream::ObjectStream(XRef *xref, int objStrNumA) { goto err1; } objNums[i] = obj1.getInt(); - offsets[i] = obj2.getInt(); + if (obj2.isInt()) + offsets[i] = obj2.getInt(); + else + offsets[i] = obj2.getInt64(); obj1.free(); obj2.free(); if (objNums[i] < 0 || offsets[i] < 0 || @@ -207,7 +217,7 @@ ObjectStream::ObjectStream(XRef *xref, int objStrNumA) { // skip to the first object - this shouldn't be necessary because // the First key is supposed to be equal to offsets[0], but just in // case... - for (i = first; i < offsets[0]; ++i) { + for (Goffset pos = first; pos < offsets[0]; ++pos) { objStr.getStream()->getChar(); } @@ -285,7 +295,7 @@ XRef::XRef(Object *trailerDictA) { trailerDict.initDict(trailerDictA->getDict()); } -XRef::XRef(BaseStream *strA, Guint pos, Guint mainXRefEntriesOffsetA, GBool *wasReconstructed, GBool reconstruct) { +XRef::XRef(BaseStream *strA, Goffset pos, Goffset mainXRefEntriesOffsetA, GBool *wasReconstructed, GBool reconstruct) { Object obj; init(); @@ -313,7 +323,7 @@ XRef::XRef(BaseStream *strA, Guint pos, Guint mainXRefEntriesOffsetA, GBool *was // read the xref table } else { - std::vector followedXRefStm; + std::vector followedXRefStm; readXRef(&prevXRefOffset, &followedXRefStm, NULL); // if there was a problem with the xref table, @@ -410,7 +420,7 @@ int XRef::resize(int newSize) if (reserve(newSize) < newSize) return size; for (int i = size; i < newSize; ++i) { - entries[i].offset = 0xffffffff; + entries[i].offset = -1; entries[i].type = xrefEntryNone; entries[i].obj.initNull (); entries[i].flags = 0; @@ -430,7 +440,7 @@ int XRef::resize(int newSize) /* Read one xref table section. Also reads the associated trailer * dictionary, and returns the prev pointer (if any). * Arguments: - * pos Points to a Guint containing the offset of the XRef + * pos Points to a Goffset containing the offset of the XRef * section to be read. If a prev pointer is found, *pos is * updated with its value * followedXRefStm Used in case of nested readXRef calls to spot circular @@ -440,7 +450,7 @@ int XRef::resize(int newSize) * Return value: * gTrue if a prev pointer is found, otherwise gFalse */ -GBool XRef::readXRef(Guint *pos, std::vector *followedXRefStm, std::vector *xrefStreamObjsNum) { +GBool XRef::readXRef(Goffset *pos, std::vector *followedXRefStm, std::vector *xrefStreamObjsNum) { Parser *parser; Object obj; GBool more; @@ -496,11 +506,11 @@ GBool XRef::readXRef(Guint *pos, std::vector *followedXRefStm, std::vecto return gFalse; } -GBool XRef::readXRefTable(Parser *parser, Guint *pos, std::vector *followedXRefStm, std::vector *xrefStreamObjsNum) { +GBool XRef::readXRefTable(Parser *parser, Goffset *pos, std::vector *followedXRefStm, std::vector *xrefStreamObjsNum) { XRefEntry entry; GBool more; Object obj, obj2; - Guint pos2; + Goffset pos2; int first, n, i; while (1) { @@ -529,10 +539,14 @@ GBool XRef::readXRefTable(Parser *parser, Guint *pos, std::vector *follow } } for (i = first; i < first + n; ++i) { - if (!parser->getObj(&obj, gTrue)->isInt()) { + parser->getObj(&obj, gTrue); + if (obj.isInt()) { + entry.offset = obj.getInt(); + } else if (obj.isInt64()) { + entry.offset = obj.getInt64(); + } else { goto err1; } - entry.offset = (Guint)obj.getInt(); obj.free(); if (!parser->getObj(&obj, gTrue)->isInt()) { goto err1; @@ -550,7 +564,7 @@ GBool XRef::readXRefTable(Parser *parser, Guint *pos, std::vector *follow goto err1; } obj.free(); - if (entries[i].offset == 0xffffffff) { + if (entries[i].offset == -1) { entries[i] = entry; // PDF files of patents from the IBM Intellectual Property // Network have a bug: the xref table claims to start at 1 @@ -560,7 +574,7 @@ GBool XRef::readXRefTable(Parser *parser, Guint *pos, std::vector *follow entries[1].type == xrefEntryFree) { i = first = 0; entries[0] = entries[1]; - entries[1].offset = 0xffffffff; + entries[1].offset = -1; } } } @@ -573,8 +587,11 @@ GBool XRef::readXRefTable(Parser *parser, Guint *pos, std::vector *follow // get the 'Prev' pointer obj.getDict()->lookupNF("Prev", &obj2); - if (obj2.isInt()) { - pos2 = (Guint)obj2.getInt(); + if (obj2.isInt() || obj2.isInt64()) { + if (obj2.isInt()) + pos2 = obj2.getInt(); + else + pos2 = obj2.getInt64(); if (pos2 != *pos) { *pos = pos2; more = gTrue; @@ -604,8 +621,12 @@ GBool XRef::readXRefTable(Parser *parser, Guint *pos, std::vector *follow } // check for an 'XRefStm' key - if (obj.getDict()->lookup("XRefStm", &obj2)->isInt()) { - pos2 = (Guint)obj2.getInt(); + obj.getDict()->lookup("XRefStm", &obj2); + if (obj2.isInt() || obj2.isInt64()) { + if (obj2.isInt()) + pos2 = obj2.getInt(); + else + pos2 = obj2.getInt(); for (size_t i = 0; ok == gTrue && i < followedXRefStm->size(); ++i) { if (followedXRefStm->at(i) == pos2) { ok = gFalse; @@ -632,7 +653,7 @@ GBool XRef::readXRefTable(Parser *parser, Guint *pos, std::vector *follow return gFalse; } -GBool XRef::readXRefStream(Stream *xrefStr, Guint *pos) { +GBool XRef::readXRefStream(Stream *xrefStr, Goffset *pos) { Dict *dict; int w[3]; GBool more; @@ -667,11 +688,14 @@ GBool XRef::readXRefStream(Stream *xrefStr, Guint *pos) { } w[i] = obj2.getInt(); obj2.free(); - if (w[i] < 0 || w[i] > 4) { + if (w[i] < 0) { goto err1; } } obj.free(); + if (w[0] > (int)sizeof(int) || w[1] > (int)sizeof(Goffset) || w[2] > (int)sizeof(int)) { + goto err1; + } xrefStr->reset(); dict->lookupNF("Index", &idx); @@ -705,7 +729,10 @@ GBool XRef::readXRefStream(Stream *xrefStr, Guint *pos) { dict->lookupNF("Prev", &obj); if (obj.isInt()) { - *pos = (Guint)obj.getInt(); + *pos = obj.getInt(); + more = gTrue; + } else if (obj.isInt64()) { + *pos = obj.getInt64(); more = gTrue; } else { more = gFalse; @@ -725,7 +752,7 @@ GBool XRef::readXRefStream(Stream *xrefStr, Guint *pos) { } GBool XRef::readXRefStreamSection(Stream *xrefStr, int *w, int first, int n) { - Guint offset; + Goffset offset; int type, gen, c, i, j; if (first + n < 0) { @@ -764,7 +791,7 @@ GBool XRef::readXRefStreamSection(Stream *xrefStr, int *w, int first, int n) { } gen = (gen << 8) + c; } - if (entries[i].offset == 0xffffffff) { + if (entries[i].offset == -1) { switch (type) { case 0: entries[i].offset = offset; @@ -795,7 +822,7 @@ GBool XRef::constructXRef(GBool *wasReconstructed, GBool needCatalogDict) { Parser *parser; Object newTrailerDict, obj; char buf[256]; - Guint pos; + Goffset pos; int num, gen; int newSize; int streamEndsSize; @@ -916,8 +943,8 @@ GBool XRef::constructXRef(GBool *wasReconstructed, GBool needCatalogDict) { error(errSyntaxError, -1, "Invalid 'endstream' parameter."); return gFalse; } - streamEnds = (Guint *)greallocn(streamEnds, - streamEndsSize, sizeof(Guint)); + streamEnds = (Goffset *)greallocn(streamEnds, + streamEndsSize, sizeof(Goffset)); } streamEnds[streamEndsLen++] = pos; } @@ -1160,7 +1187,7 @@ Object *XRef::getDocInfoNF(Object *obj) { return trailerDict.dictLookupNF("Info", obj); } -GBool XRef::getStreamEnd(Guint streamStart, Guint *streamEnd) { +GBool XRef::getStreamEnd(Goffset streamStart, Goffset *streamEnd) { int a, b, m; if (streamEndsLen == 0 || @@ -1183,12 +1210,12 @@ GBool XRef::getStreamEnd(Guint streamStart, Guint *streamEnd) { return gTrue; } -int XRef::getNumEntry(Guint offset) +int XRef::getNumEntry(Goffset offset) { if (size > 0) { int res = 0; - Guint resOffset = getEntry(0)->offset; + Goffset resOffset = getEntry(0)->offset; XRefEntry *e; for (int i = 1; i < size; ++i) { @@ -1204,14 +1231,14 @@ int XRef::getNumEntry(Guint offset) else return -1; } -void XRef::add(int num, int gen, Guint offs, GBool used) { +void XRef::add(int num, int gen, Goffset offs, GBool used) { if (num >= size) { if (num >= capacity) { entries = (XRefEntry *)greallocn(entries, num + 1, sizeof(XRefEntry)); capacity = num + 1; } for (int i = size; i < num + 1; ++i) { - entries[i].offset = 0xffffffff; + entries[i].offset = -1; entries[i].type = xrefEntryFree; entries[i].obj.initNull (); entries[i].flags = 0; @@ -1339,8 +1366,8 @@ void XRef::XRefTableWriter::startSection(int first, int count) { outStr->printf("%i %i\r\n", first, count); } -void XRef::XRefTableWriter::writeEntry(Guint offset, int gen, XRefEntryType type) { - outStr->printf("%010i %05i %c\r\n", offset, gen, (type==xrefEntryFree)?'f':'n'); +void XRef::XRefTableWriter::writeEntry(Goffset offset, int gen, XRefEntryType type) { + outStr->printf("%010lli %05i %c\r\n", (long long)offset, gen, (type==xrefEntryFree)?'f':'n'); } void XRef::writeTableToFile(OutStream* outStr, GBool writeAllEntries) { @@ -1360,16 +1387,18 @@ void XRef::XRefStreamWriter::startSection(int first, int count) { index->arrayAdd( obj.initInt(count) ); } -void XRef::XRefStreamWriter::writeEntry(Guint offset, int gen, XRefEntryType type) { - char data[7]; +void XRef::XRefStreamWriter::writeEntry(Goffset offset, int gen, XRefEntryType type) { + char data[16]; + int i; data[0] = (type==xrefEntryFree) ? 0 : 1; - data[1] = (offset >> 24) & 0xff; - data[2] = (offset >> 16) & 0xff; - data[3] = (offset >> 8) & 0xff; - data[4] = offset & 0xff; - data[5] = (gen >> 8) & 0xff; - data[6] = gen & 0xff; - stmBuf->append(data, 7); + for (i = sizeof(Goffset); i > 0; i--) { + data[i] = offset & 0xff; + offset >>= 8; + } + i = sizeof(Goffset) + 1; + data[i] = (gen >> 8) & 0xff; + data[i+1] = gen & 0xff; + stmBuf->append(data, i+2); } void XRef::writeStreamToBuffer(GooString *stmBuf, Dict *xrefDict, XRef *xref) { @@ -1385,12 +1414,12 @@ void XRef::writeStreamToBuffer(GooString *stmBuf, Dict *xrefDict, XRef *xref) { xrefDict->set("Index", &index); obj2.initArray(xref); obj2.arrayAdd( obj1.initInt(1) ); - obj2.arrayAdd( obj1.initInt(4) ); + obj2.arrayAdd( obj1.initInt(sizeof(Goffset)) ); obj2.arrayAdd( obj1.initInt(2) ); xrefDict->set("W", &obj2); } -GBool XRef::parseEntry(Guint offset, XRefEntry *entry) +GBool XRef::parseEntry(Goffset offset, XRefEntry *entry) { GBool r; @@ -1400,10 +1429,14 @@ GBool XRef::parseEntry(Guint offset, XRefEntry *entry) str->makeSubStream(offset, gFalse, 20, &obj)), gTrue); Object obj1, obj2, obj3; - if ((parser.getObj(&obj1)->isInt()) && + if (((parser.getObj(&obj1)->isInt()) || + parser.getObj(&obj1)->isInt64()) && (parser.getObj(&obj2)->isInt()) && (parser.getObj(&obj3)->isCmd("n") || obj3.isCmd("f"))) { - entry->offset = (Guint) obj1.getInt(); + if (obj1.isInt64()) + entry->offset = obj1.getInt64(); + else + entry->offset = obj1.getInt(); entry->gen = obj2.getInt(); entry->type = obj3.isCmd("n") ? xrefEntryUncompressed : xrefEntryFree; entry->obj.initNull (); @@ -1426,7 +1459,7 @@ GBool XRef::parseEntry(Guint offset, XRefEntry *entry) * numbers of the XRef streams that have been traversed */ void XRef::readXRefUntil(int untilEntryNum, std::vector *xrefStreamObjsNum) { - std::vector followedPrev; + std::vector followedPrev; while (prevXRefOffset && (untilEntryNum == -1 || entries[untilEntryNum].type == xrefEntryNone)) { bool followed = false; for (size_t j = 0; j < followedPrev.size(); j++) { @@ -1445,7 +1478,7 @@ void XRef::readXRefUntil(int untilEntryNum, std::vector *xrefStreamObjsNum) followedPrev.push_back (prevXRefOffset); - std::vector followedXRefStm; + std::vector followedXRefStm; if (!readXRef(&prevXRefOffset, &followedXRefStm, xrefStreamObjsNum)) { prevXRefOffset = 0; } diff --git a/poppler/XRef.h b/poppler/XRef.h index 9af4a13..fde2b44 100644 --- a/poppler/XRef.h +++ b/poppler/XRef.h @@ -57,7 +57,7 @@ enum XRefEntryType { }; struct XRefEntry { - Guint offset; + Goffset offset; int gen; XRefEntryType type; int flags; @@ -95,7 +95,7 @@ public: // Constructor, create an empty XRef but with info dict, used for PDF writing XRef(Object *trailerDictA); // Constructor. Read xref table from stream. - XRef(BaseStream *strA, Guint pos, Guint mainXRefEntriesOffsetA = 0, GBool *wasReconstructed = NULL, GBool reconstruct = false); + XRef(BaseStream *strA, Goffset pos, Goffset mainXRefEntriesOffsetA = 0, GBool *wasReconstructed = NULL, GBool reconstruct = false); // Destructor. ~XRef(); @@ -152,10 +152,10 @@ public: // Get end position for a stream in a damaged file. // Returns false if unknown or file is not damaged. - GBool getStreamEnd(Guint streamStart, Guint *streamEnd); + GBool getStreamEnd(Goffset streamStart, Goffset *streamEnd); // Retuns the entry that belongs to the offset - int getNumEntry(Guint offset); + int getNumEntry(Goffset offset); // Scans the document and sets special flags in all xref entries. One of those // flags is Unencrypted, which affects how the object is fetched. Therefore, @@ -173,7 +173,7 @@ public: void setModifiedObject(Object* o, Ref r); Ref addIndirectObject (Object* o); void removeIndirectObject(Ref r); - void add(int num, int gen, Guint offs, GBool used); + void add(int num, int gen, Goffset offs, GBool used); // Output XRef table to stream void writeTableToFile(OutStream* outStr, GBool writeAllEntries); @@ -183,7 +183,7 @@ public: private: BaseStream *str; // input stream - Guint start; // offset in file (to allow for garbage + Goffset start; // offset in file (to allow for garbage // at beginning of file) XRefEntry *entries; // xref entries int capacity; // size of array @@ -192,7 +192,7 @@ private: GBool ok; // true if xref table is valid int errCode; // error code (if is false) Object trailerDict; // trailer dictionary - Guint *streamEnds; // 'endstream' positions - only used in + Goffset *streamEnds; // 'endstream' positions - only used in // damaged files int streamEndsLen; // number of valid entries in streamEnds PopplerCache *objStrs; // cached object streams @@ -204,28 +204,28 @@ private: int permFlags; // permission bits Guchar fileKey[32]; // file decryption key GBool ownerPasswordOk; // true if owner password is correct - Guint prevXRefOffset; // position of prev XRef section (= next to read) - Guint mainXRefEntriesOffset; // offset of entries in main XRef table + Goffset prevXRefOffset; // position of prev XRef section (= next to read) + Goffset mainXRefEntriesOffset; // offset of entries in main XRef table GBool xRefStream; // true if last XRef section is a stream - Guint mainXRefOffset; // position of the main XRef table/stream + Goffset mainXRefOffset; // position of the main XRef table/stream GBool scannedSpecialFlags; // true if scanSpecialFlags has been called void init(); int reserve(int newSize); int resize(int newSize); - GBool readXRef(Guint *pos, std::vector *followedXRefStm, std::vector *xrefStreamObjsNum); - GBool readXRefTable(Parser *parser, Guint *pos, std::vector *followedXRefStm, std::vector *xrefStreamObjsNum); + GBool readXRef(Goffset *pos, std::vector *followedXRefStm, std::vector *xrefStreamObjsNum); + GBool readXRefTable(Parser *parser, Goffset *pos, std::vector *followedXRefStm, std::vector *xrefStreamObjsNum); GBool readXRefStreamSection(Stream *xrefStr, int *w, int first, int n); - GBool readXRefStream(Stream *xrefStr, Guint *pos); + GBool readXRefStream(Stream *xrefStr, Goffset *pos); GBool constructXRef(GBool *wasReconstructed, GBool needCatalogDict = gFalse); - GBool parseEntry(Guint offset, XRefEntry *entry); + GBool parseEntry(Goffset offset, XRefEntry *entry); void readXRefUntil(int untilEntryNum, std::vector *xrefStreamObjsNum = NULL); void markUnencrypted(Object *obj); class XRefWriter { public: virtual void startSection(int first, int count) = 0; - virtual void writeEntry(Guint offset, int gen, XRefEntryType type) = 0; + virtual void writeEntry(Goffset offset, int gen, XRefEntryType type) = 0; virtual ~XRefWriter() {}; }; @@ -233,7 +233,7 @@ private: public: XRefTableWriter(OutStream* outStrA); void startSection(int first, int count); - void writeEntry(Guint offset, int gen, XRefEntryType type); + void writeEntry(Goffset offset, int gen, XRefEntryType type); private: OutStream* outStr; }; @@ -242,7 +242,7 @@ private: public: XRefStreamWriter(Object *index, GooString *stmBuf); void startSection(int first, int count); - void writeEntry(Guint offset, int gen, XRefEntryType type); + void writeEntry(Goffset offset, int gen, XRefEntryType type); private: Object *index; GooString *stmBuf; diff --git a/poppler/poppler-config.h.in b/poppler/poppler-config.h.in index 5c56ea4..8975f57 100644 --- a/poppler/poppler-config.h.in +++ b/poppler/poppler-config.h.in @@ -107,6 +107,12 @@ #undef USE_CMS #endif +/* Define to 1 if you have the `fseek64' function. */ +#undef HAVE_FSEEK64 + +/* Define to 1 if fseeko (and presumably ftello) exists and is declared. */ +#undef HAVE_FSEEKO + // Also, there are preprocessor symbols in the header files // that are used but never defined when building poppler using configure // or cmake: DISABLE_OUTLINE, DEBUG_MEM, SPLASH_CMYK, HAVE_T1LIB_H, diff --git a/qt4/src/poppler-private.cc b/qt4/src/poppler-private.cc index ffb5b92..a28e57b 100644 --- a/qt4/src/poppler-private.cc +++ b/qt4/src/poppler-private.cc @@ -53,7 +53,7 @@ namespace Debug { Debug::debugClosure = closure; } - void qt4ErrorFunction(void * /*data*/, ErrorCategory /*category*/, int pos, char *msg) + void qt4ErrorFunction(void * /*data*/, ErrorCategory /*category*/, Goffset pos, char *msg) { QString emsg; diff --git a/qt4/src/poppler-qiodeviceoutstream-private.h b/qt4/src/poppler-qiodeviceoutstream-private.h index e7faa29..84f7369 100644 --- a/qt4/src/poppler-qiodeviceoutstream-private.h +++ b/qt4/src/poppler-qiodeviceoutstream-private.h @@ -33,7 +33,7 @@ class QIODeviceOutStream : public OutStream virtual ~QIODeviceOutStream(); virtual void close(); - virtual int getPos(); + virtual Goffset getPos(); virtual void put(char c); virtual void printf(const char *format, ...); diff --git a/qt4/src/poppler-qiodeviceoutstream.cc b/qt4/src/poppler-qiodeviceoutstream.cc index b0054af..19e4f75 100644 --- a/qt4/src/poppler-qiodeviceoutstream.cc +++ b/qt4/src/poppler-qiodeviceoutstream.cc @@ -39,9 +39,9 @@ void QIODeviceOutStream::close() { } -int QIODeviceOutStream::getPos() +Goffset QIODeviceOutStream::getPos() { - return (int)m_device->pos(); + return m_device->pos(); } void QIODeviceOutStream::put(char c) diff --git a/test/perf-test.cc b/test/perf-test.cc index 21fbdee..84bbcda 100644 --- a/test/perf-test.cc +++ b/test/perf-test.cc @@ -742,7 +742,7 @@ void OutputDebugString(const char *txt) #define _vsnprintf vsnprintf #endif -void my_error(void *, ErrorCategory, int pos, char *msg) { +void my_error(void *, ErrorCategory, Goffset pos, char *msg) { #if 0 char buf[4096], *p = buf; @@ -752,7 +752,7 @@ void my_error(void *, ErrorCategory, int pos, char *msg) { } if (pos >= 0) { - p += _snprintf(p, sizeof(buf)-1, "Error (%d): ", pos); + p += _snprintf(p, sizeof(buf)-1, "Error (%lld): ", (long long)pos); *p = '\0'; OutputDebugString(p); } else { @@ -769,7 +769,7 @@ void my_error(void *, ErrorCategory, int pos, char *msg) { OutputDebugString(buf); if (pos >= 0) { - p += _snprintf(p, sizeof(buf)-1, "Error (%d): ", pos); + p += _snprintf(p, sizeof(buf)-1, "Error (%lld): ", (long long)pos); *p = '\0'; OutputDebugString(buf); if (gErrFile) diff --git a/utils/pdfunite.cc b/utils/pdfunite.cc index 79d05f0..f52f92b 100644 --- a/utils/pdfunite.cc +++ b/utils/pdfunite.cc @@ -163,7 +163,7 @@ int main (int argc, char *argv[]) outStr->printf(" >>\nendobj\n"); objectsCount++; } - Guint uxrefOffset = outStr->getPos(); + Goffset uxrefOffset = outStr->getPos(); Ref ref; ref.num = rootNum; ref.gen = 0; -- 1.7.10.4