From 4cf39b95800e248f65fa008b15eebcaa77bf353b Mon Sep 17 00:00:00 2001 From: Adrian Johnson Date: Sat, 22 Dec 2012 19:18:24 +1030 Subject: [PATCH 3/4] 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 | 141 ++++++++++++++++---------- 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/pdfinfo.cc | 6 +- utils/pdfunite.cc | 2 +- 32 files changed, 320 insertions(+), 257 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 4ac3149..041cc2e 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); @@ -45,8 +45,8 @@ BaseStream *PopplerInputStream::copy() { return new PopplerInputStream(inputStream, cancellable, start, limited, length, &dict); } -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); } @@ -70,7 +70,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); @@ -90,7 +90,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 639ea04..251a61b 100644 --- a/glib/poppler-input-stream.h +++ b/glib/poppler-input-stream.h @@ -31,11 +31,11 @@ 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 BaseStream *copy(); - 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(); @@ -43,10 +43,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(); } @@ -60,7 +60,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 86da9b0..7ff05a4 100644 --- a/poppler/Object.h +++ b/poppler/Object.h @@ -231,8 +231,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. @@ -352,10 +352,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 df11a16..ecc2af5 100644 --- a/poppler/PDFDoc.cc +++ b/poppler/PDFDoc.cc @@ -117,7 +117,7 @@ void PDFDoc::init() #ifndef DISABLE_OUTLINE outline = NULL; #endif - startXRefPos = ~(Guint)0; + startXRefPos = -1; secHdlr = NULL; pageCache = NULL; } @@ -130,7 +130,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 @@ -369,7 +369,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++) @@ -767,7 +767,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; @@ -906,7 +906,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; @@ -991,7 +991,7 @@ void PDFDoc::saveCompleteRewrite (OutStream* outStr) } } xref->unlock(); - Guint uxrefOffset = outStr->getPos(); + Goffset uxrefOffset = outStr->getPos(); writeXRefTableTrailer(uxrefOffset, uxref, gTrue /* write all entries */, uxref->getNumObjects(), outStr, gFalse /* complete rewrite */); delete uxref; @@ -1027,17 +1027,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); } @@ -1103,7 +1107,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; } @@ -1113,7 +1117,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: @@ -1180,7 +1184,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 @@ -1197,10 +1201,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); } } @@ -1237,7 +1241,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; @@ -1258,7 +1262,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 @@ -1336,7 +1340,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"); @@ -1346,7 +1350,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; @@ -1609,14 +1613,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; @@ -1625,9 +1629,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]; @@ -1678,7 +1682,7 @@ Guint PDFDoc::getStartXRef() startXRefPos = 0; } else { for (p = &buf[i+9]; isspace(*p); ++p) ; - startXRefPos = strToUnsigned(p); + startXRefPos = strToLongLong(p); } } @@ -1687,7 +1691,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 75d0c40..6fc30f5 100644 --- a/poppler/PDFDoc.h +++ b/poppler/PDFDoc.h @@ -252,11 +252,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 @@ -296,11 +296,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 @@ -327,7 +327,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 #if MULTITHREADED GooMutex mutex; #endif diff --git a/poppler/Parser.cc b/poppler/Parser.cc index 41c611d..f31b94f 100644 --- a/poppler/Parser.cc +++ b/poppler/Parser.cc @@ -194,7 +194,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(); @@ -206,7 +207,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"); @@ -250,7 +254,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 482bcbf..f13603c 100644 --- a/poppler/Stream.cc +++ b/poppler/Stream.cc @@ -366,7 +366,7 @@ OutStream::~OutStream () //------------------------------------------------------------------------ // FileOutStream //------------------------------------------------------------------------ -FileOutStream::FileOutStream (FILE* fa, Guint startA) +FileOutStream::FileOutStream (FILE* fa, Goffset startA) { f = fa; start = startA; @@ -382,7 +382,7 @@ void FileOutStream::close () } -int FileOutStream::getPos () +Goffset FileOutStream::getPos () { return ftell(f); } @@ -405,7 +405,7 @@ void FileOutStream::printf(const char *format, ...) // BaseStream //------------------------------------------------------------------------ -BaseStream::BaseStream(Object *dictA, Guint lengthA) { +BaseStream::BaseStream(Object *dictA, Goffset lengthA) { dict = *dictA; length = lengthA; } @@ -429,7 +429,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"); } @@ -771,8 +771,8 @@ UniqueFileStream::~UniqueFileStream() { // FileStream //------------------------------------------------------------------------ -FileStream::FileStream(FILE *fA, char *fileNameA, Guint startA, GBool limitedA, - Guint lengthA, Object *dictA): +FileStream::FileStream(FILE *fA, char *fileNameA, Goffset startA, GBool limitedA, + Goffset lengthA, Object *dictA): BaseStream(dictA, lengthA) { f = fA; fileName = fileNameA; @@ -793,20 +793,20 @@ BaseStream *FileStream::copy() { return new UniqueFileStream(f, fileName, start, limited, length, &dict); } -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, fileName, 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; @@ -848,8 +848,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 @@ -863,31 +863,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; @@ -897,8 +897,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; @@ -922,8 +922,8 @@ BaseStream *CachedFileStream::copy() { return new CachedFileStream(cc, start, limited, length, &dict); } -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); @@ -969,7 +969,7 @@ GBool CachedFileStream::fillBuf() return gTrue; } -void CachedFileStream::setPos(Guint pos, int dir) +void CachedFileStream::setPos(Goffset pos, int dir) { Guint size; @@ -990,7 +990,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; @@ -1001,7 +1001,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; @@ -1021,10 +1021,10 @@ BaseStream *MemStream::copy() { return new MemStream(buf, start, length, &dict); } -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; @@ -1058,7 +1058,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) { @@ -1074,7 +1074,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; @@ -1085,7 +1085,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; @@ -1100,8 +1100,8 @@ BaseStream *EmbedStream::copy() { return NULL; } -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; } @@ -1125,22 +1125,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 9dd5459..e662706 100644 --- a/poppler/Stream.h +++ b/poppler/Stream.h @@ -184,12 +184,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); @@ -255,7 +255,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; @@ -274,20 +274,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; }; @@ -301,26 +301,26 @@ private: class BaseStream: public Stream { public: - BaseStream(Object *dictA, Guint lengthA); + BaseStream(Object *dictA, Goffset lengthA); virtual ~BaseStream(); virtual BaseStream *copy() = 0; - 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; Object dict; }; @@ -336,8 +336,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(); } @@ -441,12 +441,12 @@ private: class FileStream: public BaseStream { public: - FileStream(FILE *fA, char *fileName, Guint startA, GBool limitedA, - Guint lengthA, Object *dictA); + FileStream(FILE *fA, char *fileName, Goffset startA, GBool limitedA, + Goffset lengthA, Object *dictA); virtual ~FileStream(); virtual BaseStream *copy(); - 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(); @@ -454,10 +454,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(); } @@ -493,13 +493,13 @@ protected: FILE *f; char *fileName; private: - Guint start; + Goffset start; GBool limited; char buf[fileStreamBufSize]; char *bufPtr; char *bufEnd; - Guint bufPos; - int savePos; + Goffset bufPos; + Goffset savePos; GBool saved; }; @@ -520,12 +520,12 @@ public: 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 BaseStream *copy(); - 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(); @@ -533,10 +533,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(); } @@ -546,7 +546,7 @@ private: GBool fillBuf(); CachedFile *cc; - Guint start; + Goffset start; GBool limited; char buf[cachedStreamBufSize]; char *bufPtr; @@ -564,11 +564,11 @@ 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 BaseStream *copy(); - 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(); @@ -576,10 +576,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 @@ -594,7 +594,7 @@ private: virtual int getChars(int nChars, Guchar *buffer); char *buf; - Guint start; + Goffset start; char *bufEnd; char *bufPtr; GBool needFree; @@ -613,19 +613,19 @@ 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 BaseStream *copy(); - 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 0ff17f0..1ea0ded 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" @@ -138,9 +140,10 @@ class ObjectStreamItem : public PopplerCacheItem ObjectStream::ObjectStream(XRef *xref, int objStrNumA, int recursion) { Stream *str; Parser *parser; - int *offsets; + Goffset *offsets; Object objStr, obj1, obj2; - int first, i; + Goffset first; + int i; objStrNum = objStrNumA; nObjects = 0; @@ -162,11 +165,15 @@ ObjectStream::ObjectStream(XRef *xref, int objStrNumA, int recursion) { goto err1; } - if (!objStr.streamGetDict()->lookup("First", &obj1, recursion)->isInt()) { + objStr.streamGetDict()->lookup("First", &obj1, recursion); + 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; @@ -181,7 +188,7 @@ ObjectStream::ObjectStream(XRef *xref, int objStrNumA, int recursion) { } 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(); @@ -191,7 +198,7 @@ ObjectStream::ObjectStream(XRef *xref, int objStrNumA, int recursion) { 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; @@ -199,7 +206,10 @@ ObjectStream::ObjectStream(XRef *xref, int objStrNumA, int recursion) { 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 || @@ -215,7 +225,7 @@ ObjectStream::ObjectStream(XRef *xref, int objStrNumA, int recursion) { // 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(); } @@ -297,7 +307,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(); @@ -325,7 +335,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, @@ -434,7 +444,7 @@ XRef *XRef::copy() { } xref->streamEndsLen = streamEndsLen; if (streamEndsLen != 0) { - xref->streamEnds = (Guint *)gmalloc(streamEndsLen * sizeof(Guint)); + xref->streamEnds = (Goffset *)gmalloc(streamEndsLen * sizeof(Goffset)); for (int i = 0; i < streamEndsLen; i++) { xref->streamEnds[i] = streamEnds[i]; } @@ -475,7 +485,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; @@ -495,7 +505,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 @@ -505,7 +515,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; @@ -561,11 +571,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) { @@ -594,10 +604,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; @@ -615,7 +629,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 @@ -625,7 +639,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; } } } @@ -638,8 +652,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; @@ -669,8 +686,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; @@ -697,7 +718,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; @@ -732,11 +753,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); @@ -770,7 +794,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; @@ -790,7 +817,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) { @@ -829,7 +856,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; @@ -860,7 +887,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; @@ -981,8 +1008,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; } @@ -1237,7 +1264,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 || @@ -1260,12 +1287,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) { @@ -1281,7 +1308,7 @@ 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) { lockXRef; if (num >= size) { if (num >= capacity) { @@ -1289,7 +1316,7 @@ void XRef::add(int num, int gen, Guint offs, GBool used) { 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; @@ -1424,8 +1451,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) { @@ -1445,16 +1472,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) { @@ -1470,12 +1499,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; @@ -1485,10 +1514,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 (); @@ -1511,7 +1544,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++) { @@ -1530,7 +1563,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 8cb587c..850a523 100644 --- a/poppler/XRef.h +++ b/poppler/XRef.h @@ -59,7 +59,7 @@ enum XRefEntryType { }; struct XRefEntry { - Guint offset; + Goffset offset; int gen; XRefEntryType type; int flags; @@ -97,7 +97,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(); @@ -157,10 +157,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, @@ -178,7 +178,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); @@ -192,7 +192,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 @@ -201,7 +201,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 @@ -213,10 +213,10 @@ 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 GBool strOwner; // true if str is owned by the instance #if MULTITHREADED @@ -226,19 +226,19 @@ private: 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() {}; }; @@ -246,7 +246,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; }; @@ -255,7 +255,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 7022147..8a6dc0d 100644 --- a/qt4/src/poppler-private.cc +++ b/qt4/src/poppler-private.cc @@ -54,7 +54,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/pdfinfo.cc b/utils/pdfinfo.cc index 10a6c31..734c2b9 100644 --- a/utils/pdfinfo.cc +++ b/utils/pdfinfo.cc @@ -353,13 +353,13 @@ int main(int argc, char *argv[]) { if (f) { #if HAVE_FSEEKO fseeko(f, 0, SEEK_END); - printf("File size: %u bytes\n", (Guint)ftello(f)); + printf("File size: %lld bytes\n", (long long)ftello(f)); #elif HAVE_FSEEK64 fseek64(f, 0, SEEK_END); - printf("File size: %u bytes\n", (Guint)ftell64(f)); + printf("File size: %lld bytes\n", (long long)ftell64(f)); #else fseek(f, 0, SEEK_END); - printf("File size: %d bytes\n", (int)ftell(f)); + printf("File size: %lld bytes\n", (long long)ftell(f)); #endif fclose(f); } 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