diff options
author | Carsten Lohrke <carlo@gentoo.org> | 2004-11-04 14:07:46 +0000 |
---|---|---|
committer | Carsten Lohrke <carlo@gentoo.org> | 2004-11-04 14:07:46 +0000 |
commit | c169f9d22bda243453a2d9dd3b545db0d6d27b2f (patch) | |
tree | 69bb39905e6eb18c3e0e59af90bdde9c4e60cc89 /kde-base | |
parent | Stable on sparc wrt security bug #69936. (diff) | |
download | historical-c169f9d22bda243453a2d9dd3b545db0d6d27b2f.tar.gz historical-c169f9d22bda243453a2d9dd3b545db0d6d27b2f.tar.bz2 historical-c169f9d22bda243453a2d9dd3b545db0d6d27b2f.zip |
fixed patch
Diffstat (limited to 'kde-base')
-rw-r--r-- | kde-base/kdegraphics/ChangeLog | 6 | ||||
-rw-r--r-- | kde-base/kdegraphics/Manifest | 44 | ||||
-rw-r--r-- | kde-base/kdegraphics/files/post-3.3.0-kdegraphics_2.diff | 1028 |
3 files changed, 58 insertions, 1020 deletions
diff --git a/kde-base/kdegraphics/ChangeLog b/kde-base/kdegraphics/ChangeLog index 54db3fa16f23..7735597f8aa2 100644 --- a/kde-base/kdegraphics/ChangeLog +++ b/kde-base/kdegraphics/ChangeLog @@ -1,6 +1,10 @@ # ChangeLog for kde-base/kdegraphics # Copyright 2002-2004 Gentoo Foundation; Distributed under the GPL v2 -# $Header: /var/cvsroot/gentoo-x86/kde-base/kdegraphics/ChangeLog,v 1.122 2004/11/04 13:45:22 weeve Exp $ +# $Header: /var/cvsroot/gentoo-x86/kde-base/kdegraphics/ChangeLog,v 1.123 2004/11/04 14:07:46 carlo Exp $ + + 04 Nov 2004; Carsten Lohrke <carlo@gentoo.org> + files/post-3.3.0-kdegraphics_2.diff: + fixed patch 04 Nov 2004; Jason Wever <weeve@gentoo.org> kdegraphics-3.3.1-r2.ebuild: Stable on sparc wrt security bug #69936. diff --git a/kde-base/kdegraphics/Manifest b/kde-base/kdegraphics/Manifest index f5696974458a..ce9d94cf039c 100644 --- a/kde-base/kdegraphics/Manifest +++ b/kde-base/kdegraphics/Manifest @@ -1,34 +1,34 @@ -MD5 276380838d371e4d28627acbc5d92c21 ChangeLog 16974 -MD5 feb2b4270d15a98a32173a5ae04a19fb kdegraphics-3.1.5.ebuild 1048 -MD5 d34737e0c554fe641ce3a353c8b7fe8d kdegraphics-3.2.0.ebuild 1330 -MD5 6b3fabad5f11df10503b136be549dc16 kdegraphics-3.3.1.ebuild 1434 -MD5 14889ab75f97d76e58b0c1154e7683a9 metadata.xml 161 MD5 0c557af25ca14e9133483d1ff8414c74 kdegraphics-3.2.2.ebuild 1224 +MD5 e720f7455cef7015497f5ad795a6108b kdegraphics-3.2.3-r2.ebuild 1280 MD5 5a60aa7288a3e688931b84fce55c4b6a kdegraphics-3.3.0.ebuild 1430 -MD5 8e48bc60a542000e2ca8ca2173a21113 kdegraphics-3.2.3.ebuild 1226 +MD5 fbd70cd93878a0622071cf149368b28e kdegraphics-3.3.0-r2.ebuild 1486 +MD5 0dcbff375e401ca8c354637670a32c43 kdegraphics-3.3.1-r1.ebuild 1485 MD5 749ee0be0aab8c1f4ee11978a8d16ae2 kdegraphics-3.2.3-r1.ebuild 1278 MD5 f8ea687ae1a7ff4a4771f5cf4050a125 kdegraphics-3.3.0-r1.ebuild 1499 -MD5 0dcbff375e401ca8c354637670a32c43 kdegraphics-3.3.1-r1.ebuild 1485 -MD5 e720f7455cef7015497f5ad795a6108b kdegraphics-3.2.3-r2.ebuild 1280 -MD5 fbd70cd93878a0622071cf149368b28e kdegraphics-3.3.0-r2.ebuild 1486 +MD5 feb2b4270d15a98a32173a5ae04a19fb kdegraphics-3.1.5.ebuild 1048 +MD5 8e48bc60a542000e2ca8ca2173a21113 kdegraphics-3.2.3.ebuild 1226 +MD5 6b3fabad5f11df10503b136be549dc16 kdegraphics-3.3.1.ebuild 1434 +MD5 624fb5601e9a7f7643cce71f96ee5d2c ChangeLog 17077 MD5 0075d981be237e5f3f8e887e94140f9a kdegraphics-3.3.1-r2.ebuild 1493 -MD5 e43eeb201ab38aa05917d4de1573ff59 files/digest-kdegraphics-3.2.3 71 +MD5 d34737e0c554fe641ce3a353c8b7fe8d kdegraphics-3.2.0.ebuild 1330 +MD5 14889ab75f97d76e58b0c1154e7683a9 metadata.xml 161 +MD5 33d7a652f3ae6f9e66d79fb818b684f6 files/digest-kdegraphics-3.3.0-r1 71 +MD5 33d7a652f3ae6f9e66d79fb818b684f6 files/digest-kdegraphics-3.3.0-r2 71 +MD5 fecf5cb3209323e56be3368df325411a files/digest-kdegraphics-3.3.1-r1 71 +MD5 fecf5cb3209323e56be3368df325411a files/digest-kdegraphics-3.3.1-r2 71 +MD5 eb03ab721af71700a0b445f1c50b55f8 files/kdegraphics-3.2.2-gcc34-compile.patch 7723 MD5 78ab0a172f24863df0ba35300e95a890 files/digest-kdegraphics-3.1.5 71 MD5 8c9db7f8d52169b544da66be07e9979a files/digest-kdegraphics-3.2.0 71 -MD5 fecf5cb3209323e56be3368df325411a files/digest-kdegraphics-3.3.1 71 -MD5 e43eeb201ab38aa05917d4de1573ff59 files/digest-kdegraphics-3.2.3-r1 71 MD5 80f49f2fcc0bb31559666e47fc28b047 files/digest-kdegraphics-3.2.2 71 -MD5 eb03ab721af71700a0b445f1c50b55f8 files/kdegraphics-3.2.2-gcc34-compile.patch 7723 -MD5 d97c962408abd235435f6857fc405ebf files/kdegraphics-3.2.3-gcc34-compile.patch 7162 -MD5 33d7a652f3ae6f9e66d79fb818b684f6 files/digest-kdegraphics-3.3.0-r1 71 +MD5 e43eeb201ab38aa05917d4de1573ff59 files/digest-kdegraphics-3.2.3 71 MD5 33d7a652f3ae6f9e66d79fb818b684f6 files/digest-kdegraphics-3.3.0 71 -MD5 fecf5cb3209323e56be3368df325411a files/digest-kdegraphics-3.3.1-r1 71 -MD5 4f854adb507f4d04e997702e44ffc2ea files/post-3.2.3-kdegraphics.diff 3853 -MD5 651fba579516ea947fbefee373f40a6c files/post-3.3.1-kdegraphics.diff 1533 +MD5 fecf5cb3209323e56be3368df325411a files/digest-kdegraphics-3.3.1 71 MD5 8d995a343d5083ba8ac84f1d4136d359 files/xpdf-3.3.0-kdegraphics.diff 1630 -MD5 e43eeb201ab38aa05917d4de1573ff59 files/digest-kdegraphics-3.2.3-r2 71 -MD5 33d7a652f3ae6f9e66d79fb818b684f6 files/digest-kdegraphics-3.3.0-r2 71 -MD5 fecf5cb3209323e56be3368df325411a files/digest-kdegraphics-3.3.1-r2 71 +MD5 4f854adb507f4d04e997702e44ffc2ea files/post-3.2.3-kdegraphics.diff 3853 +MD5 d97c962408abd235435f6857fc405ebf files/kdegraphics-3.2.3-gcc34-compile.patch 7162 +MD5 06573d3829a3009c879f870746607056 files/post-3.3.0-kdegraphics_2.diff 3586 MD5 870d90051bb236753070fb553890f95d files/post-3.2.3-kdegraphics_2.diff 3205 -MD5 a93abae30c47739bd9247d230d1769d2 files/post-3.3.0-kdegraphics_2.diff 26941 +MD5 651fba579516ea947fbefee373f40a6c files/post-3.3.1-kdegraphics.diff 1533 MD5 6c3f55477c5f566c711563caa3c51296 files/post-3.3.1-kdegraphics_2.diff 3887 +MD5 e43eeb201ab38aa05917d4de1573ff59 files/digest-kdegraphics-3.2.3-r1 71 +MD5 e43eeb201ab38aa05917d4de1573ff59 files/digest-kdegraphics-3.2.3-r2 71 diff --git a/kde-base/kdegraphics/files/post-3.3.0-kdegraphics_2.diff b/kde-base/kdegraphics/files/post-3.3.0-kdegraphics_2.diff index 23ddb97bdba6..65ff45832586 100644 --- a/kde-base/kdegraphics/files/post-3.3.0-kdegraphics_2.diff +++ b/kde-base/kdegraphics/files/post-3.3.0-kdegraphics_2.diff @@ -1,5 +1,5 @@ ---- kdegraphics/kpdf/xpdf/Catalog.cc 2003/08/20 21:25:12 1.3 -+++ kdegraphics/kpdf/xpdf/Catalog.cc 2004/10/28 09:42:53 1.3.4.4 +--- kpdf/xpdf/Catalog.cc 2003/08/20 21:25:12 1.3 ++++ kpdf/xpdf/Catalog.cc 2004/10/28 09:42:53 1.3.4.4 @@ -12,6 +12,7 @@ #pragma implementation #endif @@ -55,8 +55,9 @@ } names.free(); if (!found) ---- kdegraphics/kpdf/xpdf/XRef.cc 2003/08/20 21:25:12 1.3 -+++ kdegraphics/kpdf/xpdf/XRef.cc 2004/10/28 09:42:53 1.3.4.5 + +--- kpdf/xpdf/XRef.cc.orig 2004-11-04 13:08:50.000000000 +0100 ++++ kpdf/xpdf/XRef.cc 2004-11-04 13:14:50.000000000 +0100 @@ -12,6 +12,7 @@ #pragma implementation #endif @@ -65,874 +66,42 @@ #include <stdlib.h> #include <stddef.h> #include <string.h> -@@ -47,12 +48,162 @@ - #endif - - //------------------------------------------------------------------------ -+// ObjectStream -+//------------------------------------------------------------------------ -+ -+class ObjectStream { -+public: -+ -+ // Create an object stream, using object number <objStrNum>, -+ // generation 0. -+ ObjectStream(XRef *xref, int objStrNumA); -+ -+ ~ObjectStream(); -+ -+ // Return the object number of this object stream. -+ int getObjStrNum() { return objStrNum; } -+ -+ // Get the <objIdx>th object from this stream, which should be -+ // object number <objNum>, generation 0. -+ Object *getObject(int objIdx, int objNum, Object *obj); -+ -+private: -+ -+ int objStrNum; // object number of the object stream -+ int nObjects; // number of objects in the stream -+ Object *objs; // the objects (length = nObjects) -+ int *objNums; // the object numbers (length = nObjects) -+}; -+ -+ObjectStream::ObjectStream(XRef *xref, int objStrNumA) { -+ Stream *str; -+ Parser *parser; -+ int *offsets; -+ Object objStr, obj1, obj2; -+ int first, i; -+ -+ objStrNum = objStrNumA; -+ nObjects = 0; -+ objs = NULL; -+ objNums = NULL; -+ -+ if (!xref->fetch(objStrNum, 0, &objStr)->isStream()) { -+ goto err1; -+ } -+ -+ if (!objStr.streamGetDict()->lookup("N", &obj1)->isInt()) { -+ obj1.free(); -+ goto err1; -+ } -+ nObjects = obj1.getInt(); -+ obj1.free(); -+ if (nObjects <= 0) { -+ goto err1; -+ } -+ -+ if (!objStr.streamGetDict()->lookup("First", &obj1)->isInt()) { -+ obj1.free(); -+ goto err1; -+ } -+ first = obj1.getInt(); -+ obj1.free(); -+ if (first < 0) { -+ goto err1; -+ } -+ -+ if ((unsigned) nObjects >= INT_MAX / sizeof(int)) { -+ error(-1, "Invalid 'nObjects'"); -+ goto err1; -+ } -+ -+ objs = new Object[nObjects]; -+ objNums = (int *)gmalloc(nObjects * sizeof(int)); -+ offsets = (int *)gmalloc(nObjects * sizeof(int)); -+ -+ // parse the header: object numbers and offsets -+ objStr.streamReset(); -+ obj1.initNull(); -+ str = new EmbedStream(objStr.getStream(), &obj1, gTrue, first); -+ parser = new Parser(xref, new Lexer(xref, str)); -+ for (i = 0; i < nObjects; ++i) { -+ parser->getObj(&obj1); -+ parser->getObj(&obj2); -+ if (!obj1.isInt() || !obj2.isInt()) { -+ obj1.free(); -+ obj2.free(); -+ delete parser; -+ gfree(offsets); -+ goto err1; -+ } -+ objNums[i] = obj1.getInt(); -+ offsets[i] = obj2.getInt(); -+ obj1.free(); -+ obj2.free(); -+ if (objNums[i] < 0 || offsets[i] < 0 || -+ (i > 0 && offsets[i] < offsets[i-1])) { -+ delete parser; -+ gfree(offsets); -+ goto err1; -+ } -+ } -+ while (str->getChar() != EOF) ; -+ delete parser; -+ -+ // 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) { -+ objStr.getStream()->getChar(); -+ } -+ -+ // parse the objects -+ for (i = 0; i < nObjects; ++i) { -+ obj1.initNull(); -+ if (i == nObjects - 1) { -+ str = new EmbedStream(objStr.getStream(), &obj1, gFalse, 0); -+ } else { -+ str = new EmbedStream(objStr.getStream(), &obj1, gTrue, -+ offsets[i+1] - offsets[i]); -+ } -+ parser = new Parser(xref, new Lexer(xref, str)); -+ parser->getObj(&objs[i]); -+ while (str->getChar() != EOF) ; -+ delete parser; -+ } -+ -+ gfree(offsets); -+ -+ err1: -+ objStr.free(); -+ return; -+} -+ -+ObjectStream::~ObjectStream() { -+ int i; -+ -+ if (objs) { -+ for (i = 0; i < nObjects; ++i) { -+ objs[i].free(); -+ } -+ delete[] objs; -+ } -+ gfree(objNums); -+} -+ -+Object *ObjectStream::getObject(int objIdx, int objNum, Object *obj) { -+ if (objIdx < 0 || objIdx >= nObjects || objNum != objNums[objIdx]) { -+ return obj->initNull(); -+ } -+ return objs[objIdx].copy(obj); -+} -+ -+//------------------------------------------------------------------------ - // XRef - //------------------------------------------------------------------------ - - XRef::XRef(BaseStream *strA, GString *ownerPassword, GString *userPassword) { - Guint pos; -- int i; -+ Object obj; - - ok = gTrue; - errCode = errNone; -@@ -60,35 +211,28 @@ XRef::XRef(BaseStream *strA, GString *ow - entries = NULL; - streamEnds = NULL; - streamEndsLen = 0; -+ objStr = NULL; - - // read the trailer - str = strA; - start = str->getStart(); -- pos = readTrailer(); -+ pos = getStartXref(); - -- // if there was a problem with the trailer, -- // try to reconstruct the xref table -+ // if there was a problem with the 'startxref' position, try to -+ // reconstruct the xref table - if (pos == 0) { - if (!(ok = constructXRef())) { - errCode = errDamaged; - return; - } +@@ -76,6 +77,12 @@ -- // trailer is ok - read the xref table -+ // read the xref table + // trailer is ok - read the xref table } else { -- entries = (XRefEntry *)gmalloc(size * sizeof(XRefEntry)); -- for (i = 0; i < size; ++i) { -- entries[i].offset = 0xffffffff; -- entries[i].used = gFalse; -- } - while (readXRef(&pos)) ; - - // if there was a problem with the xref table, - // try to reconstruct it - if (!ok) { -- gfree(entries); -- size = 0; -- entries = NULL; - if (!(ok = constructXRef())) { - errCode = errDamaged; - return; -@@ -96,6 +240,20 @@ XRef::XRef(BaseStream *strA, GString *ow - } - } - -+ // get the root dictionary (catalog) object -+ trailerDict.dictLookupNF("Root", &obj); -+ if (obj.isRef()) { -+ rootNum = obj.getRefNum(); -+ rootGen = obj.getRefGen(); -+ obj.free(); -+ } else { -+ obj.free(); -+ if (!(ok = constructXRef())) { ++ if ((unsigned) size >= INT_MAX / sizeof(XRefEntry)) { ++ error(-1, "Invalid 'size' inside xref table."); ++ ok = gFalse; + errCode = errDamaged; + return; + } -+ } -+ - // now set the trailer dictionary's xref pointer so we can fetch - // indirect objects from it - trailerDict.getDict()->setXRef(this); -@@ -117,188 +275,165 @@ XRef::~XRef() { - if (streamEnds) { - gfree(streamEnds); - } -+ if (objStr) { -+ delete objStr; -+ } - } - --// Read startxref position, xref table size, and root. Returns --// first xref position. --Guint XRef::readTrailer() { -- Parser *parser; -- Object obj; -+// Read the 'startxref' position. -+Guint XRef::getStartXref() { - char buf[xrefSearchSize+1]; -- int n; -- Guint pos, pos1; - char *p; -- int c; -- int i; -+ int c, n, i; - - // read last xrefSearchSize bytes - str->setPos(xrefSearchSize, -1); - for (n = 0; n < xrefSearchSize; ++n) { -- if ((c = str->getChar()) == EOF) -+ if ((c = str->getChar()) == EOF) { - break; -+ } - buf[n] = c; - } - buf[n] = '\0'; - - // find startxref - for (i = n - 9; i >= 0; --i) { -- if (!strncmp(&buf[i], "startxref", 9)) -+ if (!strncmp(&buf[i], "startxref", 9)) { - break; -+ } - } -- if (i < 0) -+ if (i < 0) { - return 0; -+ } - for (p = &buf[i+9]; isspace(*p); ++p) ; -- pos = lastXRefPos = strToUnsigned(p); -+ lastXRefPos = strToUnsigned(p); - -- // find trailer dict by looking after first xref table -- // (NB: we can't just use the trailer dict at the end of the file -- -- // this won't work for linearized files.) -- str->setPos(start + pos); -- for (i = 0; i < 4; ++i) -- buf[i] = str->getChar(); -- if (strncmp(buf, "xref", 4)) -- return 0; -- pos1 = pos + 4; -- while (1) { -- str->setPos(start + pos1); -- for (i = 0; i < 35; ++i) { -- if ((c = str->getChar()) == EOF) -- return 0; -- buf[i] = c; -- } -- if (!strncmp(buf, "trailer", 7)) -- break; -- p = buf; -- while (isspace(*p)) ++p; -- while ('0' <= *p && *p <= '9') ++p; -- while (isspace(*p)) ++p; -- n = atoi(p); -- while ('0' <= *p && *p <= '9') ++p; -- while (isspace(*p)) ++p; -- if (p == buf) -- return 0; -- pos1 += (p - buf) + n * 20; -- } -- pos1 += 7; -+ return lastXRefPos; -+} - -- // read trailer dict -+// Read one xref table section. Also reads the associated trailer -+// dictionary, and returns the prev pointer (if any). -+GBool XRef::readXRef(Guint *pos) { -+ Parser *parser; -+ Object obj; -+ GBool more; -+ -+ // start up a parser, parse one token - obj.initNull(); - parser = new Parser(NULL, - new Lexer(NULL, -- str->makeSubStream(start + pos1, gFalse, 0, &obj))); -- parser->getObj(&trailerDict); -- if (trailerDict.isDict()) { -- trailerDict.dictLookupNF("Size", &obj); -- if (obj.isInt()) -- size = obj.getInt(); -- else -- pos = 0; -+ str->makeSubStream(start + *pos, gFalse, 0, &obj))); -+ parser->getObj(&obj); -+ -+ // parse an old-style xref table -+ if (obj.isCmd("xref")) { - obj.free(); -- trailerDict.dictLookupNF("Root", &obj); -- if (obj.isRef()) { -- rootNum = obj.getRefNum(); -- rootGen = obj.getRefGen(); -- } else { -- pos = 0; -+ more = readXRefTable(parser, pos); -+ -+ // parse an xref stream -+ } else if (obj.isInt()) { -+ obj.free(); -+ if (!parser->getObj(&obj)->isInt()) { -+ goto err1; -+ } -+ obj.free(); -+ if (!parser->getObj(&obj)->isCmd("obj")) { -+ goto err1; - } - obj.free(); -+ if (!parser->getObj(&obj)->isStream()) { -+ goto err1; -+ } -+ more = readXRefStream(obj.getStream(), pos); -+ obj.free(); -+ - } else { -- pos = 0; -+ goto err1; - } -+ - delete parser; -+ return more; - -- // return first xref position -- return pos; -+ err1: -+ obj.free(); -+ delete parser; -+ ok = gFalse; -+ return gFalse; - } - --// Read an xref table and the prev pointer from the trailer. --GBool XRef::readXRef(Guint *pos) { -- Parser *parser; -- Object obj, obj2; -- char s[20]; -+GBool XRef::readXRefTable(Parser *parser, Guint *pos) { -+ XRefEntry entry; - GBool more; -- int first, newSize, n, i, j; -- int c; -- -- // seek to xref in stream -- str->setPos(start + *pos); -- -- // make sure it's an xref table -- while ((c = str->getChar()) != EOF && isspace(c)) ; -- s[0] = (char)c; -- s[1] = (char)str->getChar(); -- s[2] = (char)str->getChar(); -- s[3] = (char)str->getChar(); -- if (!(s[0] == 'x' && s[1] == 'r' && s[2] == 'e' && s[3] == 'f')) { -- goto err2; -- } -+ Object obj, obj2; -+ Guint pos2; -+ int first, n, newSize, i; - -- // read xref - while (1) { -- while ((c = str->lookChar()) != EOF && isspace(c)) { -- str->getChar(); -- } -- if (c == 't') { -+ parser->getObj(&obj); -+ if (obj.isCmd("trailer")) { -+ obj.free(); - break; - } -- for (i = 0; (c = str->getChar()) != EOF && isdigit(c) && i < 20; ++i) { -- s[i] = (char)c; -+ if (!obj.isInt()) { -+ goto err1; - } -- if (i == 0) { -- goto err2; -+ first = obj.getInt(); -+ obj.free(); -+ if (!parser->getObj(&obj)->isInt()) { -+ goto err1; - } -- s[i] = '\0'; -- first = atoi(s); -- while ((c = str->lookChar()) != EOF && isspace(c)) { -- str->getChar(); -- } -- for (i = 0; (c = str->getChar()) != EOF && isdigit(c) && i < 20; ++i) { -- s[i] = (char)c; -- } -- if (i == 0) { -- goto err2; -- } -- s[i] = '\0'; -- n = atoi(s); -- while ((c = str->lookChar()) != EOF && isspace(c)) { -- str->getChar(); -+ n = obj.getInt(); -+ obj.free(); -+ if (first < 0 || n < 0 || first + n < 0) { -+ goto err1; - } -- // check for buggy PDF files with an incorrect (too small) xref -- // table size + entries = (XRefEntry *)gmalloc(size * sizeof(XRefEntry)); + for (i = 0; i < size; ++i) { + entries[i].offset = 0xffffffff; +@@ -267,6 +274,10 @@ + // table size if (first + n > size) { -- newSize = size + 256; -+ for (newSize = size ? 2 * size : 1024; -+ first + n > newSize && newSize > 0; -+ newSize <<= 1) ; -+ if (newSize < 0) { -+ goto err1; -+ } + newSize = size + 256; + if ((unsigned) newSize >= INT_MAX / sizeof(XRefEntry)) { -+ error(-1, "Invalid 'obj' parameters'"); -+ goto err1; ++ error(-1, "Invalid 'newSize'"); ++ goto err2; + } -+ entries = (XRefEntry *)grealloc(entries, newSize * sizeof(XRefEntry)); for (i = size; i < newSize; ++i) { entries[i].offset = 0xffffffff; -- entries[i].used = gFalse; -+ entries[i].type = xrefEntryFree; - } - size = newSize; - } - for (i = first; i < first + n; ++i) { -- for (j = 0; j < 20; ++j) { -- if ((c = str->getChar()) == EOF) { -- goto err2; -- } -- s[j] = (char)c; -+ if (!parser->getObj(&obj)->isInt()) { -+ goto err1; - } -+ entry.offset = (Guint)obj.getInt(); -+ obj.free(); -+ if (!parser->getObj(&obj)->isInt()) { -+ goto err1; -+ } -+ entry.gen = obj.getInt(); -+ obj.free(); -+ parser->getObj(&obj); -+ if (obj.isCmd("n")) { -+ entry.type = xrefEntryUncompressed; -+ } else if (obj.isCmd("f")) { -+ entry.type = xrefEntryFree; -+ } else { -+ goto err1; -+ } -+ obj.free(); - if (entries[i].offset == 0xffffffff) { -- s[10] = '\0'; -- entries[i].offset = strToUnsigned(s); -- s[16] = '\0'; -- entries[i].gen = atoi(&s[11]); -- if (s[17] == 'n') { -- entries[i].used = gTrue; -- } else if (s[17] == 'f') { -- entries[i].used = gFalse; -- } else { -- goto err2; -- } -+ entries[i] = entry; - // PDF files of patents from the IBM Intellectual Property - // Network have a bug: the xref table claims to start at 1 - // instead of 0. - if (i == 1 && first == 1 && - entries[1].offset == 0 && entries[1].gen == 65535 && -- !entries[1].used) { -+ entries[1].type == xrefEntryFree) { - i = first = 0; - entries[0] = entries[1]; - entries[1].offset = 0xffffffff; -@@ -307,20 +442,12 @@ GBool XRef::readXRef(Guint *pos) { - } - } - -- // read prev pointer from trailer dictionary -- obj.initNull(); -- parser = new Parser(NULL, -- new Lexer(NULL, -- str->makeSubStream(str->getPos(), gFalse, 0, &obj))); -- parser->getObj(&obj); -- if (!obj.isCmd("trailer")) { -- goto err1; -- } -- obj.free(); -- parser->getObj(&obj); -- if (!obj.isDict()) { -+ // read the trailer dictionary -+ if (!parser->getObj(&obj)->isDict()) { - goto err1; - } -+ -+ // get the 'Prev' pointer - obj.getDict()->lookupNF("Prev", &obj2); - if (obj2.isInt()) { - *pos = (Guint)obj2.getInt(); -@@ -333,23 +460,208 @@ GBool XRef::readXRef(Guint *pos) { - } else { - more = gFalse; - } -- obj.free(); - obj2.free(); - -- delete parser; -+ // save the first trailer dictionary -+ if (trailerDict.isNone()) { -+ obj.copy(&trailerDict); -+ } -+ -+ // check for an 'XRefStm' key -+ if (obj.getDict()->lookup("XRefStm", &obj2)->isInt()) { -+ pos2 = (Guint)obj2.getInt(); -+ readXRef(&pos2); -+ if (!ok) { -+ goto err1; -+ } -+ } -+ obj2.free(); -+ -+ obj.free(); -+ return more; -+ -+ err1: -+ obj.free(); -+ ok = gFalse; -+ return gFalse; -+} -+ -+GBool XRef::readXRefStream(Stream *xrefStr, Guint *pos) { -+ Dict *dict; -+ int w[3]; -+ GBool more; -+ Object obj, obj2, idx; -+ int newSize, first, n, i; -+ -+ dict = xrefStr->getDict(); -+ -+ if (!dict->lookupNF("Size", &obj)->isInt()) { -+ goto err1; -+ } -+ newSize = obj.getInt(); -+ obj.free(); -+ if (newSize < 0) { -+ goto err1; -+ } -+ if (newSize > size) { -+ if ((unsigned) newSize >= INT_MAX / sizeof(XRefEntry)) { -+ error(-1, "Invalid 'size' parameter."); -+ return gFalse; -+ } -+ entries = (XRefEntry *)grealloc(entries, newSize * sizeof(XRefEntry)); -+ for (i = size; i < newSize; ++i) { -+ entries[i].offset = 0xffffffff; -+ entries[i].type = xrefEntryFree; -+ } -+ size = newSize; -+ } -+ -+ if (!dict->lookupNF("W", &obj)->isArray() || -+ obj.arrayGetLength() < 3) { -+ goto err1; -+ } -+ for (i = 0; i < 3; ++i) { -+ if (!obj.arrayGet(i, &obj2)->isInt()) { -+ obj2.free(); -+ goto err1; -+ } -+ w[i] = obj2.getInt(); -+ obj2.free(); -+ if (w[i] < 0 || w[i] > 4) { -+ goto err1; -+ } -+ } -+ obj.free(); -+ -+ xrefStr->reset(); -+ dict->lookupNF("Index", &idx); -+ if (idx.isArray()) { -+ for (i = 0; i+1 < idx.arrayGetLength(); i += 2) { -+ if (!idx.arrayGet(i, &obj)->isInt()) { -+ idx.free(); -+ goto err1; -+ } -+ first = obj.getInt(); -+ obj.free(); -+ if (!idx.arrayGet(i+1, &obj)->isInt()) { -+ idx.free(); -+ goto err1; -+ } -+ n = obj.getInt(); -+ obj.free(); -+ if (first < 0 || n < 0 || -+ !readXRefStreamSection(xrefStr, w, first, n)) { -+ idx.free(); -+ goto err0; -+ } -+ } -+ } else { -+ if (!readXRefStreamSection(xrefStr, w, 0, newSize)) { -+ idx.free(); -+ goto err0; -+ } -+ } -+ idx.free(); -+ -+ dict->lookupNF("Prev", &obj); -+ if (obj.isInt()) { -+ *pos = (Guint)obj.getInt(); -+ more = gTrue; -+ } else { -+ more = gFalse; -+ } -+ obj.free(); -+ if (trailerDict.isNone()) { -+ trailerDict.initDict(dict); -+ } -+ - return more; - - err1: - obj.free(); -- err2: -+ err0: - ok = gFalse; - return gFalse; - } - -+GBool XRef::readXRefStreamSection(Stream *xrefStr, int *w, int first, int n) { -+ Guint offset; -+ int type, gen, c, newSize, i, j; -+ -+ if (first + n < 0) { -+ return gFalse; -+ } -+ if (first + n > size) { -+ for (newSize = size ? 2 * size : 1024; -+ first + n > newSize && newSize > 0; -+ newSize <<= 1) ; -+ if (newSize < 0) { -+ return gFalse; -+ } -+ if ((unsigned) newSize >= INT_MAX / sizeof(XRefEntry)) { -+ error(-1, "Invalid 'size' inside xref table."); -+ return gFalse; -+ } -+ entries = (XRefEntry *)grealloc(entries, newSize * sizeof(XRefEntry)); -+ for (i = size; i < newSize; ++i) { -+ entries[i].offset = 0xffffffff; -+ entries[i].type = xrefEntryFree; -+ } -+ size = newSize; -+ } -+ for (i = first; i < first + n; ++i) { -+ if (w[0] == 0) { -+ type = 1; -+ } else { -+ for (type = 0, j = 0; j < w[0]; ++j) { -+ if ((c = xrefStr->getChar()) == EOF) { -+ return gFalse; -+ } -+ type = (type << 8) + c; -+ } -+ } -+ for (offset = 0, j = 0; j < w[1]; ++j) { -+ if ((c = xrefStr->getChar()) == EOF) { -+ return gFalse; -+ } -+ offset = (offset << 8) + c; -+ } -+ for (gen = 0, j = 0; j < w[2]; ++j) { -+ if ((c = xrefStr->getChar()) == EOF) { -+ return gFalse; -+ } -+ gen = (gen << 8) + c; -+ } -+ if (entries[i].offset == 0xffffffff) { -+ switch (type) { -+ case 0: -+ entries[i].offset = offset; -+ entries[i].gen = gen; -+ entries[i].type = xrefEntryFree; -+ break; -+ case 1: -+ entries[i].offset = offset; -+ entries[i].gen = gen; -+ entries[i].type = xrefEntryUncompressed; -+ break; -+ case 2: -+ entries[i].offset = offset; -+ entries[i].gen = gen; -+ entries[i].type = xrefEntryCompressed; -+ break; -+ default: -+ return gFalse; -+ } -+ } -+ } -+ -+ return gTrue; -+} -+ - // Attempt to construct an xref table for a damaged file. - GBool XRef::constructXRef() { - Parser *parser; -- Object obj; -+ Object newTrailerDict, obj; - char buf[256]; - Guint pos; - int num, gen; -@@ -359,6 +671,10 @@ GBool XRef::constructXRef() { - int i; - GBool gotRoot; - -+ gfree(entries); -+ size = 0; -+ entries = NULL; -+ - error(0, "PDF file is damaged - attempting to reconstruct xref table..."); - gotRoot = gFalse; - streamEndsLen = streamEndsSize = 0; -@@ -377,56 +693,68 @@ GBool XRef::constructXRef() { - parser = new Parser(NULL, - new Lexer(NULL, - str->makeSubStream(start + pos + 7, gFalse, 0, &obj))); -- if (!trailerDict.isNone()) -- trailerDict.free(); -- parser->getObj(&trailerDict); -- if (trailerDict.isDict()) { -- trailerDict.dictLookupNF("Root", &obj); -+ parser->getObj(&newTrailerDict); -+ if (newTrailerDict.isDict()) { -+ newTrailerDict.dictLookupNF("Root", &obj); - if (obj.isRef()) { - rootNum = obj.getRefNum(); - rootGen = obj.getRefGen(); -+ if (!trailerDict.isNone()) { -+ trailerDict.free(); -+ } -+ newTrailerDict.copy(&trailerDict); - gotRoot = gTrue; - } - obj.free(); -- } else { -- pos = 0; - } -+ newTrailerDict.free(); - delete parser; - - // look for object - } else if (isdigit(*p)) { - num = atoi(p); -- do { -- ++p; -- } while (*p && isdigit(*p)); -- if (isspace(*p)) { -+ if (num > 0) { - do { - ++p; -- } while (*p && isspace(*p)); -- if (isdigit(*p)) { -- gen = atoi(p); -+ } while (*p && isdigit(*p)); -+ if (isspace(*p)) { - do { - ++p; -- } while (*p && isdigit(*p)); -- if (isspace(*p)) { -+ } while (*p && isspace(*p)); -+ if (isdigit(*p)) { -+ gen = atoi(p); - do { - ++p; -- } while (*p && isspace(*p)); -- if (!strncmp(p, "obj", 3)) { -- if (num >= size) { -- newSize = (num + 1 + 255) & ~255; -- entries = (XRefEntry *) -- grealloc(entries, newSize * sizeof(XRefEntry)); -- for (i = size; i < newSize; ++i) { -- entries[i].offset = 0xffffffff; -- entries[i].used = gFalse; -+ } while (*p && isdigit(*p)); -+ if (isspace(*p)) { -+ do { -+ ++p; -+ } while (*p && isspace(*p)); -+ if (!strncmp(p, "obj", 3)) { -+ if (num >= size) { -+ newSize = (num + 1 + 255) & ~255; -+ if (newSize < 0) { -+ error(-1, "Bad object number"); -+ return gFalse; -+ } -+ if ((unsigned) newSize >= INT_MAX / sizeof(XRefEntry)) { -+ error(-1, "Invalid 'obj' parameters."); -+ return gFalse; -+ } -+ entries = (XRefEntry *) -+ grealloc(entries, newSize * sizeof(XRefEntry)); -+ for (i = size; i < newSize; ++i) { -+ entries[i].offset = 0xffffffff; -+ entries[i].type = xrefEntryFree; -+ } -+ size = newSize; -+ } -+ if (entries[num].type == xrefEntryFree || -+ gen >= entries[num].gen) { -+ entries[num].offset = pos - start; -+ entries[num].gen = gen; -+ entries[num].type = xrefEntryUncompressed; - } -- size = newSize; -- } -- if (!entries[num].used || gen >= entries[num].gen) { -- entries[num].offset = pos - start; -- entries[num].gen = gen; -- entries[num].used = gTrue; - } - } - } -@@ -436,6 +764,10 @@ GBool XRef::constructXRef() { +@@ -415,6 +426,10 @@ + if (!strncmp(p, "obj", 3)) { + if (num >= size) { + newSize = (num + 1 + 255) & ~255; ++ if ((unsigned) newSize >= INT_MAX / sizeof(XRefEntry)) { ++ error(-1, "Invalid 'obj' parameters."); ++ return gFalse; ++ } + entries = (XRefEntry *) + grealloc(entries, newSize * sizeof(XRefEntry)); + for (i = size; i < newSize; ++i) { +@@ -436,6 +451,11 @@ } else if (!strncmp(p, "endstream", 9)) { if (streamEndsLen == streamEndsSize) { streamEndsSize += 64; @@ -940,142 +109,7 @@ + error(-1, "Invalid 'endstream' parameter."); + return gFalse; + } ++ streamEnds = (Guint *)grealloc(streamEnds, streamEndsSize * sizeof(int)); } -@@ -457,6 +789,8 @@ GBool XRef::checkEncrypted(GString *owne - GBool encrypted1; - GBool ret; - -+ keyLength = 0; -+ encVersion = encRevision = 0; - ret = gFalse; - - permFlags = defPermFlags; -@@ -551,38 +885,34 @@ GBool XRef::checkEncrypted(GString *owne - - GBool XRef::okToPrint(GBool ignoreOwnerPW) { - #ifndef NO_DECRYPTION -- if ((ignoreOwnerPW || !ownerPasswordOk) && !(permFlags & permPrint)) { -- return gFalse; -- } --#endif -+ return (!ignoreOwnerPW && ownerPasswordOk) || (permFlags & permPrint); -+#else - return gTrue; -+#endif - } - - GBool XRef::okToChange(GBool ignoreOwnerPW) { - #ifndef NO_DECRYPTION -- if ((ignoreOwnerPW || !ownerPasswordOk) && !(permFlags & permChange)) { -- return gFalse; -- } --#endif -+ return (!ignoreOwnerPW && ownerPasswordOk) || (permFlags & permChange); -+#else - return gTrue; -+#endif - } - - GBool XRef::okToCopy(GBool ignoreOwnerPW) { - #ifndef NO_DECRYPTION -- if ((ignoreOwnerPW || !ownerPasswordOk) && !(permFlags & permCopy)) { -- return gFalse; -- } --#endif -+ return (!ignoreOwnerPW && ownerPasswordOk) || (permFlags & permCopy); -+#else - return gTrue; -+#endif - } - - GBool XRef::okToAddNotes(GBool ignoreOwnerPW) { - #ifndef NO_DECRYPTION -- if ((ignoreOwnerPW || !ownerPasswordOk) && !(permFlags & permNotes)) { -- return gFalse; -- } --#endif -+ return (!ignoreOwnerPW && ownerPasswordOk) || (permFlags & permNotes); -+#else - return gTrue; -+#endif - } - - Object *XRef::fetch(int num, int gen, Object *obj) { -@@ -592,12 +922,16 @@ Object *XRef::fetch(int num, int gen, Ob - - // check for bogus ref - this can happen in corrupted PDF files - if (num < 0 || num >= size) { -- obj->initNull(); -- return obj; -+ goto err; - } - - e = &entries[num]; -- if (e->gen == gen && e->offset != 0xffffffff) { -+ switch (e->type) { -+ -+ case xrefEntryUncompressed: -+ if (e->gen != gen) { -+ goto err; -+ } - obj1.initNull(); - parser = new Parser(this, - new Lexer(this, -@@ -605,26 +939,44 @@ Object *XRef::fetch(int num, int gen, Ob - parser->getObj(&obj1); - parser->getObj(&obj2); - parser->getObj(&obj3); -- if (obj1.isInt() && obj1.getInt() == num && -- obj2.isInt() && obj2.getInt() == gen && -- obj3.isCmd("obj")) { -+ if (!obj1.isInt() || obj1.getInt() != num || -+ !obj2.isInt() || obj2.getInt() != gen || -+ !obj3.isCmd("obj")) { -+ goto err; -+ } - #ifndef NO_DECRYPTION -- parser->getObj(obj, encrypted ? fileKey : (Guchar *)NULL, keyLength, -- num, gen); -+ parser->getObj(obj, encrypted ? fileKey : (Guchar *)NULL, keyLength, -+ num, gen); - #else -- parser->getObj(obj); -+ parser->getObj(obj); - #endif -- } else { -- obj->initNull(); -- } - obj1.free(); - obj2.free(); - obj3.free(); - delete parser; -- } else { -- obj->initNull(); -+ break; -+ -+ case xrefEntryCompressed: -+ if (gen != 0) { -+ goto err; -+ } -+ if (!objStr || objStr->getObjStrNum() != (int)e->offset) { -+ if (objStr) { -+ delete objStr; -+ } -+ objStr = new ObjectStream(this, e->offset); -+ } -+ objStr->getObject(e->gen, num, obj); -+ break; -+ -+ default: -+ goto err; - } -+ - return obj; -+ -+ err: -+ return obj->initNull(); - } - - Object *XRef::getDocInfo(Object *obj) { |