office-gobmx/xpdf/xpdf-3.02.patch
Tor Lillqvist 97d8b88221 Revert "fdo#38878 upgrade xpdf to poppler"
Also revert my two minor follow-up popper commits.

Poppler doesn't build on Mac OS X. It uses fontconfig, and we don't
depend on that on the Mac.

There is a patch from 2009
http://lists.freedesktop.org/archives/poppler/2009-July/004932.html
(actual patch at
http://lists.freedesktop.org/archives/poppler/attachments/20090712/f3b154d0/attachment-0001.obj
) that makes poppler not use fontconfig on the Mac, but it was never
upstreamed.

And that patch uses the obsolete ATSUI API, which we want to stop
using in LO code, not introduce new uses of.

This reverts commit 39f9eb0d85.
This reverts commit 0941c21185.
This reverts commit a6e9bb4c7b.
2012-11-13 10:28:15 +02:00

1901 lines
54 KiB
Diff

--- misc/xpdf-3.02/goo/gmem.cc 2007-02-27 23:05:51.000000000 +0100
+++ misc/build/xpdf-3.02/goo/gmem.cc 2009-11-10 11:43:10.374175496 +0100
@@ -55,7 +55,15 @@
void *data;
unsigned long *trl, *p;
- if (size <= 0) {
+ if (size < 0) {
+#if USE_EXCEPTIONS
+ throw GMemException();
+#else
+ fprintf(stderr, "Invalid memory allocation size\n");
+ exit(1);
+#endif
+ }
+ if (size == 0) {
return NULL;
}
size1 = gMemDataSize(size);
@@ -91,7 +99,15 @@
#else
void *p;
- if (size <= 0) {
+ if (size < 0) {
+#if USE_EXCEPTIONS
+ throw GMemException();
+#else
+ fprintf(stderr, "Invalid memory allocation size\n");
+ exit(1);
+#endif
+ }
+ if (size == 0) {
return NULL;
}
if (!(p = malloc(size))) {
@@ -112,7 +128,15 @@
void *q;
int oldSize;
- if (size <= 0) {
+ if (size < 0) {
+#if USE_EXCEPTIONS
+ throw GMemException();
+#else
+ fprintf(stderr, "Invalid memory allocation size\n");
+ exit(1);
+#endif
+ }
+ if (size == 0) {
if (p) {
gfree(p);
}
@@ -131,7 +155,15 @@
#else
void *q;
- if (size <= 0) {
+ if (size < 0) {
+#if USE_EXCEPTIONS
+ throw GMemException();
+#else
+ fprintf(stderr, "Invalid memory allocation size\n");
+ exit(1);
+#endif
+ }
+ if (size == 0) {
if (p) {
free(p);
}
--- misc/xpdf-3.02/goo/GString.cc 2007-02-27 23:05:51.000000000 +0100
+++ misc/build/xpdf-3.02/goo/GString.cc 2009-11-10 11:43:10.368006116 +0100
@@ -528,7 +528,7 @@
if ((neg = x < 0)) {
x = -x;
}
- x = floor(x * pow(10, prec) + 0.5);
+ x = floor(x * pow(10.0, prec) + 0.5);
i = bufSize;
started = !trim;
for (j = 0; j < prec && i > 1; ++j) {
--- misc/xpdf-3.02/ms_make.bat 2007-02-27 23:05:51.000000000 +0100
+++ misc/build/xpdf-3.02/ms_make.bat 2009-11-10 11:43:10.450112062 +0100
@@ -1,5 +1,5 @@
set CC=cl
-set CFLAGS=/DWIN32 /I.. /I..\goo /I..\fofi /O2 /nologo
+set CFLAGS=/DWIN32 /D_MT /I.. /I..\goo /I..\fofi /O2 /nologo
set CXX=cl
set CXXFLAGS=%CFLAGS% /TP
set LIBPROG=lib
@@ -70,6 +70,8 @@
%CXX% %CXXFLAGS% /c pdffonts.cc
%CXX% %CXXFLAGS% /c pdfimages.cc
+%LIBPROG% /nologo /out:xpdf.lib Annot.obj Array.obj BuiltinFont.obj BuiltinFontTables.obj Catalog.obj CharCodeToUnicode.obj CMap.obj Decrypt.obj Dict.obj Error.obj FontEncodingTables.obj Function.obj Gfx.obj GfxFont.obj GfxState.obj GlobalParams.obj JArithmeticDecoder.obj JBIG2Stream.obj JPXStream.obj Lexer.obj Link.obj NameToCharCode.obj Object.obj Outline.obj OutputDev.obj Page.obj Parser.obj PDFDoc.obj PDFDocEncoding.obj PSTokenizer.obj SecurityHandler.obj Stream.obj UnicodeMap.obj XRef.obj
+
%CXX% %LINKFLAGS% /Fepdftops.exe Annot.obj Array.obj BuiltinFont.obj BuiltinFontTables.obj Catalog.obj CharCodeToUnicode.obj CMap.obj Decrypt.obj Dict.obj Error.obj FontEncodingTables.obj Function.obj Gfx.obj GfxFont.obj GfxState.obj GlobalParams.obj JArithmeticDecoder.obj JBIG2Stream.obj JPXStream.obj Lexer.obj Link.obj NameToCharCode.obj Object.obj Outline.obj OutputDev.obj Page.obj Parser.obj PDFDoc.obj PDFDocEncoding.obj PSOutputDev.obj PSTokenizer.obj SecurityHandler.obj Stream.obj UnicodeMap.obj XRef.obj pdftops.obj ..\fofi\fofi.lib ..\goo\Goo.lib shell32.lib user32.lib gdi32.lib advapi32.lib
%CXX% %LINKFLAGS% /Fepdftotext.exe Annot.obj Array.obj BuiltinFont.obj BuiltinFontTables.obj Catalog.obj CharCodeToUnicode.obj CMap.obj Decrypt.obj Dict.obj Error.obj FontEncodingTables.obj Function.obj Gfx.obj GfxFont.obj GfxState.obj GlobalParams.obj JArithmeticDecoder.obj JBIG2Stream.obj JPXStream.obj Lexer.obj Link.obj NameToCharCode.obj Object.obj Outline.obj OutputDev.obj Page.obj Parser.obj PDFDoc.obj PDFDocEncoding.obj PSTokenizer.obj SecurityHandler.obj Stream.obj TextOutputDev.obj UnicodeMap.obj UnicodeTypeTable.obj XRef.obj pdftotext.obj ..\fofi\fofi.lib ..\goo\Goo.lib shell32.lib user32.lib gdi32.lib advapi32.lib
@@ -82,37 +84,3 @@
cd ..
-rem --- This part will only work if you have FreeType installed ---
-
-set FT2DIR=..\freetype-2.3.1
-set CXXFLAGS=%CXXFLAGS% /I..\splash /I%FT2DIR%\include
-
-cd splash
-%CXX% %CXXFLAGS% /c Splash.cc
-%CXX% %CXXFLAGS% /c SplashBitmap.cc
-%CXX% %CXXFLAGS% /c SplashClip.cc
-%CXX% %CXXFLAGS% /c SplashFTFont.cc
-%CXX% %CXXFLAGS% /c SplashFTFontEngine.cc
-%CXX% %CXXFLAGS% /c SplashFTFontFile.cc
-%CXX% %CXXFLAGS% /c SplashFont.cc
-%CXX% %CXXFLAGS% /c SplashFontEngine.cc
-%CXX% %CXXFLAGS% /c SplashFontFile.cc
-%CXX% %CXXFLAGS% /c SplashFontFileID.cc
-%CXX% %CXXFLAGS% /c SplashPath.cc
-%CXX% %CXXFLAGS% /c SplashPattern.cc
-%CXX% %CXXFLAGS% /c SplashScreen.cc
-%CXX% %CXXFLAGS% /c SplashState.cc
-%CXX% %CXXFLAGS% /c SplashT1Font.cc
-%CXX% %CXXFLAGS% /c SplashT1FontEngine.cc
-%CXX% %CXXFLAGS% /c SplashT1FontFile.cc
-%CXX% %CXXFLAGS% /c SplashXPath.cc
-%CXX% %CXXFLAGS% /c SplashXPathScanner.cc
-%LIBPROG% /nologo /out:splash.lib Splash.obj SplashBitmap.obj SplashClip.obj SplashFTFont.obj SplashFTFontEngine.obj SplashFTFontFile.obj SplashFont.obj SplashFontEngine.obj SplashFontFile.obj SplashFontFileID.obj SplashPath.obj SplashPattern.obj SplashScreen.obj SplashState.obj SplashT1Font.obj SplashT1FontEngine.obj SplashT1FontFile.obj SplashXPath.obj SplashXPathScanner.obj
-
-cd ..\xpdf
-%CXX% %CXXFLAGS% /c SplashOutputDev.cc
-%CXX% %CXXFLAGS% /c pdftoppm.cc
-
-%CXX% %LINKFLAGS% /Fepdftoppm.exe Annot.obj Array.obj BuiltinFont.obj BuiltinFontTables.obj Catalog.obj CharCodeToUnicode.obj CMap.obj Decrypt.obj Dict.obj Error.obj FontEncodingTables.obj Function.obj Gfx.obj GfxFont.obj GfxState.obj GlobalParams.obj JArithmeticDecoder.obj JBIG2Stream.obj JPXStream.obj Lexer.obj Link.obj NameToCharCode.obj Object.obj Outline.obj OutputDev.obj Page.obj Parser.obj PDFDoc.obj PDFDocEncoding.obj PSTokenizer.obj SecurityHandler.obj SplashOutputDev.obj Stream.obj UnicodeMap.obj UnicodeTypeTable.obj XRef.obj pdftoppm.obj ..\splash\splash.lib ..\fofi\fofi.lib ..\goo\Goo.lib %FT2DIR%\freetype2.lib shell32.lib user32.lib gdi32.lib advapi32.lib
-
-cd ..
--- misc/xpdf-3.02/splash/SplashBitmap.cc 2007-02-27 23:05:52.000000000 +0100
+++ misc/build/xpdf-3.02/splash/SplashBitmap.cc 2009-11-10 11:43:54.912615507 +0100
@@ -11,6 +11,7 @@
#endif
#include <stdio.h>
+#include <limits.h>
#include "gmem.h"
#include "SplashErrorCodes.h"
#include "SplashBitmap.h"
@@ -27,30 +28,48 @@
mode = modeA;
switch (mode) {
case splashModeMono1:
- rowSize = (width + 7) >> 3;
+ if (width > 0) {
+ rowSize = (width + 7) >> 3;
+ } else {
+ rowSize = -1;
+ }
break;
case splashModeMono8:
- rowSize = width;
+ if (width > 0) {
+ rowSize = width;
+ } else {
+ rowSize = -1;
+ }
break;
case splashModeRGB8:
case splashModeBGR8:
- rowSize = width * 3;
+ if (width > 0 && width <= INT_MAX / 3) {
+ rowSize = width * 3;
+ } else {
+ rowSize = -1;
+ }
break;
#if SPLASH_CMYK
case splashModeCMYK8:
- rowSize = width * 4;
+ if (width > 0 && width <= INT_MAX / 4) {
+ rowSize = width * 4;
+ } else {
+ rowSize = -1;
+ }
break;
#endif
}
- rowSize += rowPad - 1;
- rowSize -= rowSize % rowPad;
- data = (SplashColorPtr)gmalloc(rowSize * height);
+ if (rowSize > 0) {
+ rowSize += rowPad - 1;
+ rowSize -= rowSize % rowPad;
+ }
+ data = (SplashColorPtr)gmallocn(height, rowSize);
if (!topDown) {
data += (height - 1) * rowSize;
rowSize = -rowSize;
}
if (alphaA) {
- alpha = (Guchar *)gmalloc(width * height);
+ alpha = (Guchar *)gmallocn(width, height);
} else {
alpha = NULL;
}
--- misc/xpdf-3.02/splash/Splash.cc 2007-02-27 23:05:52.000000000 +0100
+++ misc/build/xpdf-3.02/splash/Splash.cc 2009-11-10 11:43:54.894089400 +0100
@@ -12,6 +12,7 @@
#include <stdlib.h>
#include <string.h>
+#include <limits.h>
#include "gmem.h"
#include "SplashErrorCodes.h"
#include "SplashMath.h"
@@ -1912,7 +1913,10 @@
xq = w % scaledWidth;
// allocate pixel buffer
- pixBuf = (SplashColorPtr)gmalloc((yp + 1) * w);
+ if (yp < 0 || yp > INT_MAX - 1) {
+ return splashErrBadArg;
+ }
+ pixBuf = (SplashColorPtr)gmallocn(yp + 1, w);
// initialize the pixel pipe
pipeInit(&pipe, 0, 0, state->fillPattern, NULL, state->fillAlpha,
@@ -2208,9 +2212,12 @@
xq = w % scaledWidth;
// allocate pixel buffers
- colorBuf = (SplashColorPtr)gmalloc((yp + 1) * w * nComps);
+ if (yp < 0 || yp > INT_MAX - 1 || w > INT_MAX / nComps) {
+ return splashErrBadArg;
+ }
+ colorBuf = (SplashColorPtr)gmallocn(yp + 1, w * nComps);
if (srcAlpha) {
- alphaBuf = (Guchar *)gmalloc((yp + 1) * w);
+ alphaBuf = (Guchar *)gmallocn(yp + 1, w);
} else {
alphaBuf = NULL;
}
--- misc/xpdf-3.02/splash/SplashErrorCodes.h 2007-02-27 23:05:52.000000000 +0100
+++ misc/build/xpdf-3.02/splash/SplashErrorCodes.h 2009-11-10 11:43:54.903536237 +0100
@@ -29,4 +29,6 @@
#define splashErrSingularMatrix 8 // matrix is singular
+#define splashErrBadArg 9 // bad argument
+
#endif
--- misc/xpdf-3.02/xpdf/JBIG2Stream.cc 2007-02-27 23:05:52.000000000 +0100
+++ misc/build/xpdf-3.02/xpdf/JBIG2Stream.cc 2009-11-10 11:43:10.393213949 +0100
@@ -422,12 +422,14 @@
table[i] = table[len];
// assign prefixes
- i = 0;
- prefix = 0;
- table[i++].prefix = prefix++;
- for (; table[i].rangeLen != jbig2HuffmanEOT; ++i) {
- prefix <<= table[i].prefixLen - table[i-1].prefixLen;
- table[i].prefix = prefix++;
+ if (table[0].rangeLen != jbig2HuffmanEOT) {
+ i = 0;
+ prefix = 0;
+ table[i++].prefix = prefix++;
+ for (; table[i].rangeLen != jbig2HuffmanEOT; ++i) {
+ prefix <<= table[i].prefixLen - table[i-1].prefixLen;
+ table[i].prefix = prefix++;
+ }
}
}
@@ -491,7 +493,7 @@
}
if (p->bits < 0) {
error(str->getPos(), "Bad two dim code in JBIG2 MMR stream");
- return 0;
+ return EOF;
}
bufLen -= p->bits;
return p->n;
@@ -507,7 +509,7 @@
++nBytesRead;
}
while (1) {
- if (bufLen >= 7 && ((buf >> (bufLen - 7)) & 0x7f) == 0) {
+ if (bufLen >= 11 && ((buf >> (bufLen - 7)) & 0x7f) == 0) {
if (bufLen <= 12) {
code = buf << (12 - bufLen);
} else {
@@ -550,14 +552,15 @@
++nBytesRead;
}
while (1) {
- if (bufLen >= 6 && ((buf >> (bufLen - 6)) & 0x3f) == 0) {
+ if (bufLen >= 10 && ((buf >> (bufLen - 6)) & 0x3f) == 0) {
if (bufLen <= 13) {
code = buf << (13 - bufLen);
} else {
code = buf >> (bufLen - 13);
}
p = &blackTab1[code & 0x7f];
- } else if (bufLen >= 4 && ((buf >> (bufLen - 4)) & 0x0f) == 0) {
+ } else if (bufLen >= 7 && ((buf >> (bufLen - 4)) & 0x0f) == 0 &&
+ ((buf >> (bufLen - 6)) & 0x03) != 0) {
if (bufLen <= 12) {
code = buf << (12 - bufLen);
} else {
@@ -683,8 +686,9 @@
h = hA;
line = (wA + 7) >> 3;
if (w <= 0 || h <= 0 || line <= 0 || h >= (INT_MAX - 1) / line) {
- data = NULL;
- return;
+ // force a call to gmalloc(-1), which will throw an exception
+ h = -1;
+ line = 2;
}
// need to allocate one extra guard byte for use in combine()
data = (Guchar *)gmalloc(h * line + 1);
@@ -698,8 +702,9 @@
h = bitmap->h;
line = bitmap->line;
if (w <= 0 || h <= 0 || line <= 0 || h >= (INT_MAX - 1) / line) {
- data = NULL;
- return;
+ // force a call to gmalloc(-1), which will throw an exception
+ h = -1;
+ line = 2;
}
// need to allocate one extra guard byte for use in combine()
data = (Guchar *)gmalloc(h * line + 1);
@@ -754,6 +759,8 @@
inline void JBIG2Bitmap::getPixelPtr(int x, int y, JBIG2BitmapPtr *ptr) {
if (y < 0 || y >= h || x >= w) {
ptr->p = NULL;
+ ptr->shift = 0; // make gcc happy
+ ptr->x = 0; // make gcc happy
} else if (x < 0) {
ptr->p = &data[y * line];
ptr->shift = 7;
@@ -798,6 +805,10 @@
Guint src0, src1, src, dest, s1, s2, m1, m2, m3;
GBool oneByte;
+ // check for the pathological case where y = -2^31
+ if (y < -0x7fffffff) {
+ return;
+ }
if (y < 0) {
y0 = -y;
} else {
@@ -1011,8 +1022,13 @@
JBIG2SymbolDict::JBIG2SymbolDict(Guint segNumA, Guint sizeA):
JBIG2Segment(segNumA)
{
+ Guint i;
+
size = sizeA;
bitmaps = (JBIG2Bitmap **)gmallocn(size, sizeof(JBIG2Bitmap *));
+ for (i = 0; i < size; ++i) {
+ bitmaps[i] = NULL;
+ }
genericRegionStats = NULL;
refinementRegionStats = NULL;
}
@@ -1021,7 +1037,9 @@
Guint i;
for (i = 0; i < size; ++i) {
- delete bitmaps[i];
+ if (bitmaps[i]) {
+ delete bitmaps[i];
+ }
}
gfree(bitmaps);
if (genericRegionStats) {
@@ -1296,6 +1314,13 @@
goto eofError2;
}
+ // check for missing page information segment
+ if (!pageBitmap && ((segType >= 4 && segType <= 7) ||
+ (segType >= 20 && segType <= 43))) {
+ error(getPos(), "First JBIG2 segment associated with a page must be a page information segment");
+ goto syntaxError;
+ }
+
// read the segment data
switch (segType) {
case 0:
@@ -1411,6 +1436,8 @@
Guint i, j, k;
Guchar *p;
+ symWidths = NULL;
+
// symbol dictionary flags
if (!readUWord(&flags)) {
goto eofError;
@@ -1466,20 +1493,32 @@
codeTables = new GList();
numInputSyms = 0;
for (i = 0; i < nRefSegs; ++i) {
- seg = findSegment(refSegs[i]);
- if (seg->getType() == jbig2SegSymbolDict) {
- numInputSyms += ((JBIG2SymbolDict *)seg)->getSize();
- } else if (seg->getType() == jbig2SegCodeTable) {
- codeTables->append(seg);
+ if ((seg = findSegment(refSegs[i]))) {
+ if (seg->getType() == jbig2SegSymbolDict) {
+ j = ((JBIG2SymbolDict *)seg)->getSize();
+ if (numInputSyms > UINT_MAX - j) {
+ error(getPos(), "Too many input symbols in JBIG2 symbol dictionary");
+ delete codeTables;
+ goto eofError;
+ }
+ numInputSyms += j;
+ } else if (seg->getType() == jbig2SegCodeTable) {
+ codeTables->append(seg);
+ }
}
}
+ if (numInputSyms > UINT_MAX - numNewSyms) {
+ error(getPos(), "Too many input symbols in JBIG2 symbol dictionary");
+ delete codeTables;
+ goto eofError;
+ }
// compute symbol code length
- symCodeLen = 0;
- i = 1;
- while (i < numInputSyms + numNewSyms) {
+ symCodeLen = 1;
+ i = (numInputSyms + numNewSyms) >> 1;
+ while (i) {
++symCodeLen;
- i <<= 1;
+ i >>= 1;
}
// get the input symbol bitmaps
@@ -1491,11 +1530,12 @@
k = 0;
inputSymbolDict = NULL;
for (i = 0; i < nRefSegs; ++i) {
- seg = findSegment(refSegs[i]);
- if (seg->getType() == jbig2SegSymbolDict) {
- inputSymbolDict = (JBIG2SymbolDict *)seg;
- for (j = 0; j < inputSymbolDict->getSize(); ++j) {
- bitmaps[k++] = inputSymbolDict->getBitmap(j);
+ if ((seg = findSegment(refSegs[i]))) {
+ if (seg->getType() == jbig2SegSymbolDict) {
+ inputSymbolDict = (JBIG2SymbolDict *)seg;
+ for (j = 0; j < inputSymbolDict->getSize(); ++j) {
+ bitmaps[k++] = inputSymbolDict->getBitmap(j);
+ }
}
}
}
@@ -1510,6 +1550,9 @@
} else if (huffDH == 1) {
huffDHTable = huffTableE;
} else {
+ if (i >= (Guint)codeTables->getLength()) {
+ goto codeTableError;
+ }
huffDHTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
}
if (huffDW == 0) {
@@ -1517,17 +1560,26 @@
} else if (huffDW == 1) {
huffDWTable = huffTableC;
} else {
+ if (i >= (Guint)codeTables->getLength()) {
+ goto codeTableError;
+ }
huffDWTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
}
if (huffBMSize == 0) {
huffBMSizeTable = huffTableA;
} else {
+ if (i >= (Guint)codeTables->getLength()) {
+ goto codeTableError;
+ }
huffBMSizeTable =
((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
}
if (huffAggInst == 0) {
huffAggInstTable = huffTableA;
} else {
+ if (i >= (Guint)codeTables->getLength()) {
+ goto codeTableError;
+ }
huffAggInstTable =
((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
}
@@ -1560,7 +1612,6 @@
}
// allocate symbol widths storage
- symWidths = NULL;
if (huff && !refAgg) {
symWidths = (Guint *)gmallocn(numNewSyms, sizeof(Guint));
}
@@ -1602,6 +1653,10 @@
goto syntaxError;
}
symWidth += dw;
+ if (i >= numNewSyms) {
+ error(getPos(), "Too many symbols in JBIG2 symbol dictionary");
+ goto syntaxError;
+ }
// using a collective bitmap, so don't read a bitmap here
if (huff && !refAgg) {
@@ -1638,6 +1693,10 @@
arithDecoder->decodeInt(&refDX, iardxStats);
arithDecoder->decodeInt(&refDY, iardyStats);
}
+ if (symID >= numInputSyms + i) {
+ error(getPos(), "Invalid symbol ID in JBIG2 symbol dictionary");
+ goto syntaxError;
+ }
refBitmap = bitmaps[symID];
bitmaps[numInputSyms + i] =
readGenericRefinementRegion(symWidth, symHeight,
@@ -1704,6 +1763,12 @@
} else {
arithDecoder->decodeInt(&run, iaexStats);
}
+ if (i + run > numInputSyms + numNewSyms ||
+ (ex && j + run > numExSyms)) {
+ error(getPos(), "Too many exported symbols in JBIG2 symbol dictionary");
+ delete symbolDict;
+ goto syntaxError;
+ }
if (ex) {
for (cnt = 0; cnt < run; ++cnt) {
symbolDict->setBitmap(j++, bitmaps[i++]->copy());
@@ -1713,6 +1778,11 @@
}
ex = !ex;
}
+ if (j != numExSyms) {
+ error(getPos(), "Too few symbols in JBIG2 symbol dictionary");
+ delete symbolDict;
+ goto syntaxError;
+ }
for (i = 0; i < numNewSyms; ++i) {
delete bitmaps[numInputSyms + i];
@@ -1735,6 +1805,10 @@
return gTrue;
+ codeTableError:
+ error(getPos(), "Missing code table in JBIG2 symbol dictionary");
+ delete codeTables;
+
syntaxError:
for (i = 0; i < numNewSyms; ++i) {
if (bitmaps[numInputSyms + i]) {
@@ -1837,6 +1911,8 @@
}
} else {
error(getPos(), "Invalid segment reference in JBIG2 text region");
+ delete codeTables;
+ return;
}
}
symCodeLen = 0;
@@ -1871,6 +1947,9 @@
} else if (huffFS == 1) {
huffFSTable = huffTableG;
} else {
+ if (i >= (Guint)codeTables->getLength()) {
+ goto codeTableError;
+ }
huffFSTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
}
if (huffDS == 0) {
@@ -1880,6 +1959,9 @@
} else if (huffDS == 2) {
huffDSTable = huffTableJ;
} else {
+ if (i >= (Guint)codeTables->getLength()) {
+ goto codeTableError;
+ }
huffDSTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
}
if (huffDT == 0) {
@@ -1889,6 +1971,9 @@
} else if (huffDT == 2) {
huffDTTable = huffTableM;
} else {
+ if (i >= (Guint)codeTables->getLength()) {
+ goto codeTableError;
+ }
huffDTTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
}
if (huffRDW == 0) {
@@ -1896,6 +1981,9 @@
} else if (huffRDW == 1) {
huffRDWTable = huffTableO;
} else {
+ if (i >= (Guint)codeTables->getLength()) {
+ goto codeTableError;
+ }
huffRDWTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
}
if (huffRDH == 0) {
@@ -1903,6 +1991,9 @@
} else if (huffRDH == 1) {
huffRDHTable = huffTableO;
} else {
+ if (i >= (Guint)codeTables->getLength()) {
+ goto codeTableError;
+ }
huffRDHTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
}
if (huffRDX == 0) {
@@ -1910,6 +2001,9 @@
} else if (huffRDX == 1) {
huffRDXTable = huffTableO;
} else {
+ if (i >= (Guint)codeTables->getLength()) {
+ goto codeTableError;
+ }
huffRDXTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
}
if (huffRDY == 0) {
@@ -1917,11 +2011,17 @@
} else if (huffRDY == 1) {
huffRDYTable = huffTableO;
} else {
+ if (i >= (Guint)codeTables->getLength()) {
+ goto codeTableError;
+ }
huffRDYTable = ((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
}
if (huffRSize == 0) {
huffRSizeTable = huffTableA;
} else {
+ if (i >= (Guint)codeTables->getLength()) {
+ goto codeTableError;
+ }
huffRSizeTable =
((JBIG2CodeTable *)codeTables->get(i++))->getHuffTable();
}
@@ -2016,8 +2116,15 @@
return;
+ codeTableError:
+ error(getPos(), "Missing code table in JBIG2 text region");
+ gfree(codeTables);
+ delete syms;
+ return;
+
eofError:
error(getPos(), "Unexpected EOF in JBIG2 stream");
+ return;
}
JBIG2Bitmap *JBIG2Stream::readTextRegion(GBool huff, GBool refine,
@@ -2324,8 +2431,8 @@
error(getPos(), "Bad symbol dictionary reference in JBIG2 halftone segment");
return;
}
- seg = findSegment(refSegs[0]);
- if (seg->getType() != jbig2SegPatternDict) {
+ if (!(seg = findSegment(refSegs[0])) ||
+ seg->getType() != jbig2SegPatternDict) {
error(getPos(), "Bad symbol dictionary reference in JBIG2 halftone segment");
return;
}
@@ -2483,7 +2590,7 @@
// read the bitmap
bitmap = readGenericBitmap(mmr, w, h, templ, tpgdOn, gFalse,
- NULL, atx, aty, mmr ? 0 : length - 18);
+ NULL, atx, aty, mmr ? length - 18 : 0);
// combine the region bitmap into the page bitmap
if (imm) {
@@ -2505,6 +2612,43 @@
error(getPos(), "Unexpected EOF in JBIG2 stream");
}
+inline void JBIG2Stream::mmrAddPixels(int a1, int blackPixels,
+ int *codingLine, int *a0i, int w) {
+ if (a1 > codingLine[*a0i]) {
+ if (a1 > w) {
+ error(getPos(), "JBIG2 MMR row is wrong length ({0:d})", a1);
+ a1 = w;
+ }
+ if ((*a0i & 1) ^ blackPixels) {
+ ++*a0i;
+ }
+ codingLine[*a0i] = a1;
+ }
+}
+
+inline void JBIG2Stream::mmrAddPixelsNeg(int a1, int blackPixels,
+ int *codingLine, int *a0i, int w) {
+ if (a1 > codingLine[*a0i]) {
+ if (a1 > w) {
+ error(getPos(), "JBIG2 MMR row is wrong length ({0:d})", a1);
+ a1 = w;
+ }
+ if ((*a0i & 1) ^ blackPixels) {
+ ++*a0i;
+ }
+ codingLine[*a0i] = a1;
+ } else if (a1 < codingLine[*a0i]) {
+ if (a1 < 0) {
+ error(getPos(), "Invalid JBIG2 MMR code");
+ a1 = 0;
+ }
+ while (*a0i > 0 && a1 <= codingLine[*a0i - 1]) {
+ --*a0i;
+ }
+ codingLine[*a0i] = a1;
+ }
+}
+
JBIG2Bitmap *JBIG2Stream::readGenericBitmap(GBool mmr, int w, int h,
int templ, GBool tpgdOn,
GBool useSkip, JBIG2Bitmap *skip,
@@ -2517,7 +2661,7 @@
JBIG2BitmapPtr atPtr0, atPtr1, atPtr2, atPtr3;
int *refLine, *codingLine;
int code1, code2, code3;
- int x, y, a0, pix, i, refI, codingI;
+ int x, y, a0i, b1i, blackPixels, pix, i;
bitmap = new JBIG2Bitmap(0, w, h);
bitmap->clearToZero();
@@ -2527,9 +2671,18 @@
if (mmr) {
mmrDecoder->reset();
+ if (w > INT_MAX - 2) {
+ error(getPos(), "Bad width in JBIG2 generic bitmap");
+ // force a call to gmalloc(-1), which will throw an exception
+ w = -3;
+ }
+ // 0 <= codingLine[0] < codingLine[1] < ... < codingLine[n] = w
+ // ---> max codingLine size = w + 1
+ // refLine has one extra guard entry at the end
+ // ---> max refLine size = w + 2
+ codingLine = (int *)gmallocn(w + 1, sizeof(int));
refLine = (int *)gmallocn(w + 2, sizeof(int));
- codingLine = (int *)gmallocn(w + 2, sizeof(int));
- codingLine[0] = codingLine[1] = w;
+ codingLine[0] = w;
for (y = 0; y < h; ++y) {
@@ -2537,128 +2690,157 @@
for (i = 0; codingLine[i] < w; ++i) {
refLine[i] = codingLine[i];
}
- refLine[i] = refLine[i + 1] = w;
+ refLine[i++] = w;
+ refLine[i] = w;
// decode a line
- refI = 0; // b1 = refLine[refI]
- codingI = 0; // a1 = codingLine[codingI]
- a0 = 0;
- do {
+ codingLine[0] = 0;
+ a0i = 0;
+ b1i = 0;
+ blackPixels = 0;
+ // invariant:
+ // refLine[b1i-1] <= codingLine[a0i] < refLine[b1i] < refLine[b1i+1] <= w
+ // exception at left edge:
+ // codingLine[a0i = 0] = refLine[b1i = 0] = 0 is possible
+ // exception at right edge:
+ // refLine[b1i] = refLine[b1i+1] = w is possible
+ while (codingLine[a0i] < w) {
code1 = mmrDecoder->get2DCode();
switch (code1) {
case twoDimPass:
- if (refLine[refI] < w) {
- a0 = refLine[refI + 1];
- refI += 2;
- }
- break;
+ mmrAddPixels(refLine[b1i + 1], blackPixels, codingLine, &a0i, w);
+ if (refLine[b1i + 1] < w) {
+ b1i += 2;
+ }
+ break;
case twoDimHoriz:
- if (codingI & 1) {
- code1 = 0;
- do {
- code1 += code3 = mmrDecoder->getBlackCode();
- } while (code3 >= 64);
- code2 = 0;
- do {
- code2 += code3 = mmrDecoder->getWhiteCode();
- } while (code3 >= 64);
- } else {
- code1 = 0;
- do {
- code1 += code3 = mmrDecoder->getWhiteCode();
- } while (code3 >= 64);
- code2 = 0;
- do {
- code2 += code3 = mmrDecoder->getBlackCode();
- } while (code3 >= 64);
- }
- if (code1 > 0 || code2 > 0) {
- a0 = codingLine[codingI++] = a0 + code1;
- a0 = codingLine[codingI++] = a0 + code2;
- while (refLine[refI] <= a0 && refLine[refI] < w) {
- refI += 2;
- }
- }
- break;
- case twoDimVert0:
- a0 = codingLine[codingI++] = refLine[refI];
- if (refLine[refI] < w) {
- ++refI;
- }
- break;
- case twoDimVertR1:
- a0 = codingLine[codingI++] = refLine[refI] + 1;
- if (refLine[refI] < w) {
- ++refI;
- while (refLine[refI] <= a0 && refLine[refI] < w) {
- refI += 2;
- }
- }
- break;
- case twoDimVertR2:
- a0 = codingLine[codingI++] = refLine[refI] + 2;
- if (refLine[refI] < w) {
- ++refI;
- while (refLine[refI] <= a0 && refLine[refI] < w) {
- refI += 2;
- }
- }
- break;
+ code1 = code2 = 0;
+ if (blackPixels) {
+ do {
+ code1 += code3 = mmrDecoder->getBlackCode();
+ } while (code3 >= 64);
+ do {
+ code2 += code3 = mmrDecoder->getWhiteCode();
+ } while (code3 >= 64);
+ } else {
+ do {
+ code1 += code3 = mmrDecoder->getWhiteCode();
+ } while (code3 >= 64);
+ do {
+ code2 += code3 = mmrDecoder->getBlackCode();
+ } while (code3 >= 64);
+ }
+ mmrAddPixels(codingLine[a0i] + code1, blackPixels,
+ codingLine, &a0i, w);
+ if (codingLine[a0i] < w) {
+ mmrAddPixels(codingLine[a0i] + code2, blackPixels ^ 1,
+ codingLine, &a0i, w);
+ }
+ while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < w) {
+ b1i += 2;
+ }
+ break;
case twoDimVertR3:
- a0 = codingLine[codingI++] = refLine[refI] + 3;
- if (refLine[refI] < w) {
- ++refI;
- while (refLine[refI] <= a0 && refLine[refI] < w) {
- refI += 2;
- }
- }
- break;
- case twoDimVertL1:
- a0 = codingLine[codingI++] = refLine[refI] - 1;
- if (refI > 0) {
- --refI;
- } else {
- ++refI;
- }
- while (refLine[refI] <= a0 && refLine[refI] < w) {
- refI += 2;
- }
- break;
- case twoDimVertL2:
- a0 = codingLine[codingI++] = refLine[refI] - 2;
- if (refI > 0) {
- --refI;
- } else {
- ++refI;
- }
- while (refLine[refI] <= a0 && refLine[refI] < w) {
- refI += 2;
- }
- break;
+ mmrAddPixels(refLine[b1i] + 3, blackPixels, codingLine, &a0i, w);
+ blackPixels ^= 1;
+ if (codingLine[a0i] < w) {
+ ++b1i;
+ while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < w) {
+ b1i += 2;
+ }
+ }
+ break;
+ case twoDimVertR2:
+ mmrAddPixels(refLine[b1i] + 2, blackPixels, codingLine, &a0i, w);
+ blackPixels ^= 1;
+ if (codingLine[a0i] < w) {
+ ++b1i;
+ while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < w) {
+ b1i += 2;
+ }
+ }
+ break;
+ case twoDimVertR1:
+ mmrAddPixels(refLine[b1i] + 1, blackPixels, codingLine, &a0i, w);
+ blackPixels ^= 1;
+ if (codingLine[a0i] < w) {
+ ++b1i;
+ while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < w) {
+ b1i += 2;
+ }
+ }
+ break;
+ case twoDimVert0:
+ mmrAddPixels(refLine[b1i], blackPixels, codingLine, &a0i, w);
+ blackPixels ^= 1;
+ if (codingLine[a0i] < w) {
+ ++b1i;
+ while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < w) {
+ b1i += 2;
+ }
+ }
+ break;
case twoDimVertL3:
- a0 = codingLine[codingI++] = refLine[refI] - 3;
- if (refI > 0) {
- --refI;
- } else {
- ++refI;
- }
- while (refLine[refI] <= a0 && refLine[refI] < w) {
- refI += 2;
- }
- break;
+ mmrAddPixelsNeg(refLine[b1i] - 3, blackPixels, codingLine, &a0i, w);
+ blackPixels ^= 1;
+ if (codingLine[a0i] < w) {
+ if (b1i > 0) {
+ --b1i;
+ } else {
+ ++b1i;
+ }
+ while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < w) {
+ b1i += 2;
+ }
+ }
+ break;
+ case twoDimVertL2:
+ mmrAddPixelsNeg(refLine[b1i] - 2, blackPixels, codingLine, &a0i, w);
+ blackPixels ^= 1;
+ if (codingLine[a0i] < w) {
+ if (b1i > 0) {
+ --b1i;
+ } else {
+ ++b1i;
+ }
+ while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < w) {
+ b1i += 2;
+ }
+ }
+ break;
+ case twoDimVertL1:
+ mmrAddPixelsNeg(refLine[b1i] - 1, blackPixels, codingLine, &a0i, w);
+ blackPixels ^= 1;
+ if (codingLine[a0i] < w) {
+ if (b1i > 0) {
+ --b1i;
+ } else {
+ ++b1i;
+ }
+ while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < w) {
+ b1i += 2;
+ }
+ }
+ break;
+ case EOF:
+ mmrAddPixels(w, 0, codingLine, &a0i, w);
+ break;
default:
error(getPos(), "Illegal code in JBIG2 MMR bitmap data");
+ mmrAddPixels(w, 0, codingLine, &a0i, w);
break;
}
- } while (a0 < w);
- codingLine[codingI++] = w;
+ }
// convert the run lengths to a bitmap line
i = 0;
- while (codingLine[i] < w) {
+ while (1) {
for (x = codingLine[i]; x < codingLine[i+1]; ++x) {
bitmap->setPixel(x, y);
}
+ if (codingLine[i+1] >= w || codingLine[i+2] >= w) {
+ break;
+ }
i += 2;
}
}
@@ -2706,7 +2888,9 @@
ltp = !ltp;
}
if (ltp) {
- bitmap->duplicateRow(y, y-1);
+ if (y > 0) {
+ bitmap->duplicateRow(y, y-1);
+ }
continue;
}
}
@@ -2909,8 +3093,8 @@
return;
}
if (nRefSegs == 1) {
- seg = findSegment(refSegs[0]);
- if (seg->getType() != jbig2SegBitmap) {
+ if (!(seg = findSegment(refSegs[0])) ||
+ seg->getType() != jbig2SegBitmap) {
error(getPos(), "Bad bitmap reference in JBIG2 generic refinement segment");
return;
}
@@ -3004,6 +3188,10 @@
tpgrCX2 = refBitmap->nextPixel(&tpgrCXPtr2);
tpgrCX2 = (tpgrCX2 << 1) | refBitmap->nextPixel(&tpgrCXPtr2);
tpgrCX2 = (tpgrCX2 << 1) | refBitmap->nextPixel(&tpgrCXPtr2);
+ } else {
+ tpgrCXPtr0.p = tpgrCXPtr1.p = tpgrCXPtr2.p = NULL; // make gcc happy
+ tpgrCXPtr0.shift = tpgrCXPtr1.shift = tpgrCXPtr2.shift = 0;
+ tpgrCXPtr0.x = tpgrCXPtr1.x = tpgrCXPtr2.x = 0;
}
for (x = 0; x < w; ++x) {
@@ -3075,6 +3263,10 @@
tpgrCX2 = refBitmap->nextPixel(&tpgrCXPtr2);
tpgrCX2 = (tpgrCX2 << 1) | refBitmap->nextPixel(&tpgrCXPtr2);
tpgrCX2 = (tpgrCX2 << 1) | refBitmap->nextPixel(&tpgrCXPtr2);
+ } else {
+ tpgrCXPtr0.p = tpgrCXPtr1.p = tpgrCXPtr2.p = NULL; // make gcc happy
+ tpgrCXPtr0.shift = tpgrCXPtr1.shift = tpgrCXPtr2.shift = 0;
+ tpgrCXPtr0.x = tpgrCXPtr1.x = tpgrCXPtr2.x = 0;
}
for (x = 0; x < w; ++x) {
--- misc/xpdf-3.02/xpdf/JBIG2Stream.h 2007-02-27 23:05:52.000000000 +0100
+++ misc/build/xpdf-3.02/xpdf/JBIG2Stream.h 2009-11-10 11:43:10.400610529 +0100
@@ -78,6 +78,10 @@
Guint *refSegs, Guint nRefSegs);
void readGenericRegionSeg(Guint segNum, GBool imm,
GBool lossless, Guint length);
+ void mmrAddPixels(int a1, int blackPixels,
+ int *codingLine, int *a0i, int w);
+ void mmrAddPixelsNeg(int a1, int blackPixels,
+ int *codingLine, int *a0i, int w);
JBIG2Bitmap *readGenericBitmap(GBool mmr, int w, int h,
int templ, GBool tpgdOn,
GBool useSkip, JBIG2Bitmap *skip,
--- misc/xpdf-3.02/xpdf/Makefile.in 2007-02-27 23:05:52.000000000 +0100
+++ misc/build/xpdf-3.02/xpdf/Makefile.in 2009-11-10 11:43:10.407182402 +0100
@@ -20,6 +20,8 @@
SPLASHLIBDIR = ../splash
CXXFLAGS = @CXXFLAGS@ @DEFS@ -I.. -I$(GOOSRCDIR) -I$(FOFISRCDIR) -I$(SPLASHSRCDIR) -I$(srcdir) @freetype2_CFLAGS@ @Sgm_CFLAGS@ @Xm_CFLAGS@ @Xt_CFLAGS@ @Xp_CFLAGS@ @Xext_CFLAGS@ @Xpm_CFLAGS@ @t1_CFLAGS@ @libpaper_CFLAGS@ @X_CFLAGS@
+AR = @AR@
+RANLIB = @RANLIB@
LDFLAGS = @LDFLAGS@
@@ -107,10 +109,27 @@
#------------------------------------------------------------------------
all: xpdf$(EXE) pdftops$(EXE) pdftotext$(EXE) pdfinfo$(EXE) \
- pdffonts$(EXE) pdftoppm$(EXE) pdfimages$(EXE)
+ pdffonts$(EXE) pdftoppm$(EXE) pdfimages$(EXE) $(LIBPREFIX)xpdf.a
all-no-x: pdftops$(EXE) pdftotext$(EXE) pdfinfo$(EXE) pdffonts$(EXE) \
- pdfimages$(EXE)
+ pdfimages$(EXE) $(LIBPREFIX)xpdf.a
+
+#------------------------------------------------------------------------
+
+XPDFLIB_OBJS = Annot.o Array.o BuiltinFont.o BuiltinFontTables.o Catalog.o \
+ CharCodeToUnicode.o CMap.o Decrypt.o Dict.o \
+ Error.o FontEncodingTables.o Function.o Gfx.o GfxFont.o \
+ GfxState.o GlobalParams.o JArithmeticDecoder.o JBIG2Stream.o \
+ JPXStream.o Lexer.o Link.o NameToCharCode.o Object.o Outline.o \
+ OutputDev.o Page.o Parser.o PDFCore.o PDFDoc.o PDFDocEncoding.o \
+ PSTokenizer.o SecurityHandler.o \
+ Stream.o UnicodeMap.o \
+ UnicodeTypeTable.o XRef.o
+
+$(LIBPREFIX)xpdf.a: $(XPDFLIB_OBJS)
+ rm -f $(LIBPREFIX)xpdf.a
+ $(AR) $(LIBPREFIX)xpdf.a $(XPDFLIB_OBJS)
+ $(RANLIB) $(LIBPREFIX)xpdf.a
#------------------------------------------------------------------------
--- misc/xpdf-3.02/xpdf/PSOutputDev.cc 2007-02-27 23:05:52.000000000 +0100
+++ misc/build/xpdf-3.02/xpdf/PSOutputDev.cc 2009-11-10 11:43:54.879574544 +0100
@@ -4301,7 +4301,7 @@
width, -height, height);
// allocate a line buffer
- lineBuf = (Guchar *)gmalloc(4 * width);
+ lineBuf = (Guchar *)gmallocn(width, 4);
// set up to process the data stream
imgStr = new ImageStream(str, width, colorMap->getNumPixelComps(),
--- misc/xpdf-3.02/xpdf/Stream.cc 2007-02-27 23:05:52.000000000 +0100
+++ misc/build/xpdf-3.02/xpdf/Stream.cc 2009-11-10 11:43:54.863071127 +0100
@@ -323,6 +323,10 @@
} else {
imgLineSize = nVals;
}
+ if (width > INT_MAX / nComps) {
+ // force a call to gmallocn(-1,...), which will throw an exception
+ imgLineSize = -1;
+ }
imgLine = (Guchar *)gmallocn(imgLineSize, sizeof(Guchar));
imgIdx = nVals;
}
@@ -410,15 +414,13 @@
ok = gFalse;
nVals = width * nComps;
- if (width <= 0 || nComps <= 0 || nBits <= 0 ||
- nComps >= INT_MAX / nBits ||
- width >= INT_MAX / nComps / nBits ||
- nVals * nBits + 7 < 0) {
- return;
- }
pixBytes = (nComps * nBits + 7) >> 3;
rowBytes = ((nVals * nBits + 7) >> 3) + pixBytes;
- if (rowBytes <= 0) {
+ if (width <= 0 || nComps <= 0 || nBits <= 0 ||
+ nComps > gfxColorMaxComps ||
+ nBits > 16 ||
+ width >= INT_MAX / nComps || // check for overflow in nVals
+ nVals >= (INT_MAX - 7) / nBits) { // check for overflow in rowBytes
return;
}
predLine = (Guchar *)gmalloc(rowBytes);
@@ -1245,23 +1247,26 @@
columns = columnsA;
if (columns < 1) {
columns = 1;
- }
- if (columns + 4 <= 0) {
- columns = INT_MAX - 4;
+ } else if (columns > INT_MAX - 2) {
+ columns = INT_MAX - 2;
}
rows = rowsA;
endOfBlock = endOfBlockA;
black = blackA;
- refLine = (short *)gmallocn(columns + 3, sizeof(short));
- codingLine = (short *)gmallocn(columns + 2, sizeof(short));
+ // 0 <= codingLine[0] < codingLine[1] < ... < codingLine[n] = columns
+ // ---> max codingLine size = columns + 1
+ // refLine has one extra guard entry at the end
+ // ---> max refLine size = columns + 2
+ codingLine = (int *)gmallocn(columns + 1, sizeof(int));
+ refLine = (int *)gmallocn(columns + 2, sizeof(int));
eof = gFalse;
row = 0;
nextLine2D = encoding < 0;
inputBits = 0;
- codingLine[0] = 0;
- codingLine[1] = refLine[2] = columns;
- a0 = 1;
+ codingLine[0] = columns;
+ a0i = 0;
+ outputBits = 0;
buf = EOF;
}
@@ -1280,9 +1285,9 @@
row = 0;
nextLine2D = encoding < 0;
inputBits = 0;
- codingLine[0] = 0;
- codingLine[1] = columns;
- a0 = 1;
+ codingLine[0] = columns;
+ a0i = 0;
+ outputBits = 0;
buf = EOF;
// skip any initial zero bits and end-of-line marker, and get the 2D
@@ -1299,211 +1304,230 @@
}
}
+inline void CCITTFaxStream::addPixels(int a1, int blackPixels) {
+ if (a1 > codingLine[a0i]) {
+ if (a1 > columns) {
+ error(getPos(), "CCITTFax row is wrong length (%d)", a1);
+ err = gTrue;
+ a1 = columns;
+ }
+ if ((a0i & 1) ^ blackPixels) {
+ ++a0i;
+ }
+ codingLine[a0i] = a1;
+ }
+}
+
+inline void CCITTFaxStream::addPixelsNeg(int a1, int blackPixels) {
+ if (a1 > codingLine[a0i]) {
+ if (a1 > columns) {
+ error(getPos(), "CCITTFax row is wrong length (%d)", a1);
+ err = gTrue;
+ a1 = columns;
+ }
+ if ((a0i & 1) ^ blackPixels) {
+ ++a0i;
+ }
+ codingLine[a0i] = a1;
+ } else if (a1 < codingLine[a0i]) {
+ if (a1 < 0) {
+ error(getPos(), "Invalid CCITTFax code");
+ err = gTrue;
+ a1 = 0;
+ }
+ while (a0i > 0 && a1 <= codingLine[a0i - 1]) {
+ --a0i;
+ }
+ codingLine[a0i] = a1;
+ }
+}
+
int CCITTFaxStream::lookChar() {
short code1, code2, code3;
- int a0New;
- GBool err, gotEOL;
- int ret;
- int bits, i;
+ int b1i, blackPixels, i, bits;
+ GBool gotEOL;
- // if at eof just return EOF
- if (eof && codingLine[a0] >= columns) {
- return EOF;
+ if (buf != EOF) {
+ return buf;
}
// read the next row
- err = gFalse;
- if (codingLine[a0] >= columns) {
+ if (outputBits == 0) {
+
+ // if at eof just return EOF
+ if (eof) {
+ return EOF;
+ }
+
+ err = gFalse;
// 2-D encoding
if (nextLine2D) {
- // state:
- // a0New = current position in coding line (0 <= a0New <= columns)
- // codingLine[a0] = last change in coding line
- // (black-to-white if a0 is even,
- // white-to-black if a0 is odd)
- // refLine[b1] = next change in reference line of opposite color
- // to a0
- // invariants:
- // 0 <= codingLine[a0] <= a0New
- // <= refLine[b1] <= refLine[b1+1] <= columns
- // 0 <= a0 <= columns+1
- // refLine[0] = 0
- // refLine[n] = refLine[n+1] = columns
- // -- for some 1 <= n <= columns+1
- // end condition:
- // 0 = codingLine[0] <= codingLine[1] < codingLine[2] < ...
- // < codingLine[n-1] < codingLine[n] = columns
- // -- where 1 <= n <= columns+1
for (i = 0; codingLine[i] < columns; ++i) {
refLine[i] = codingLine[i];
}
- refLine[i] = refLine[i + 1] = columns;
- b1 = 1;
- a0New = codingLine[a0 = 0] = 0;
- do {
+ refLine[i++] = columns;
+ refLine[i] = columns;
+ codingLine[0] = 0;
+ a0i = 0;
+ b1i = 0;
+ blackPixels = 0;
+ // invariant:
+ // refLine[b1i-1] <= codingLine[a0i] < refLine[b1i] < refLine[b1i+1]
+ // <= columns
+ // exception at left edge:
+ // codingLine[a0i = 0] = refLine[b1i = 0] = 0 is possible
+ // exception at right edge:
+ // refLine[b1i] = refLine[b1i+1] = columns is possible
+ while (codingLine[a0i] < columns) {
code1 = getTwoDimCode();
switch (code1) {
case twoDimPass:
- if (refLine[b1] < columns) {
- a0New = refLine[b1 + 1];
- b1 += 2;
+ addPixels(refLine[b1i + 1], blackPixels);
+ if (refLine[b1i + 1] < columns) {
+ b1i += 2;
}
break;
case twoDimHoriz:
- if ((a0 & 1) == 0) {
- code1 = code2 = 0;
+ code1 = code2 = 0;
+ if (blackPixels) {
do {
- code1 += code3 = getWhiteCode();
+ code1 += code3 = getBlackCode();
} while (code3 >= 64);
do {
- code2 += code3 = getBlackCode();
+ code2 += code3 = getWhiteCode();
} while (code3 >= 64);
} else {
- code1 = code2 = 0;
do {
- code1 += code3 = getBlackCode();
+ code1 += code3 = getWhiteCode();
} while (code3 >= 64);
do {
- code2 += code3 = getWhiteCode();
+ code2 += code3 = getBlackCode();
} while (code3 >= 64);
}
- if (code1 > 0 || code2 > 0) {
- if (a0New + code1 <= columns) {
- codingLine[a0 + 1] = a0New + code1;
- } else {
- codingLine[a0 + 1] = columns;
- }
- ++a0;
- if (codingLine[a0] + code2 <= columns) {
- codingLine[a0 + 1] = codingLine[a0] + code2;
- } else {
- codingLine[a0 + 1] = columns;
- }
- ++a0;
- a0New = codingLine[a0];
- while (refLine[b1] <= a0New && refLine[b1] < columns) {
- b1 += 2;
+ addPixels(codingLine[a0i] + code1, blackPixels);
+ if (codingLine[a0i] < columns) {
+ addPixels(codingLine[a0i] + code2, blackPixels ^ 1);
+ }
+ while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < columns) {
+ b1i += 2;
+ }
+ break;
+ case twoDimVertR3:
+ addPixels(refLine[b1i] + 3, blackPixels);
+ blackPixels ^= 1;
+ if (codingLine[a0i] < columns) {
+ ++b1i;
+ while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < columns) {
+ b1i += 2;
}
}
break;
- case twoDimVert0:
- if (refLine[b1] < columns) {
- a0New = codingLine[++a0] = refLine[b1];
- ++b1;
- while (refLine[b1] <= a0New && refLine[b1] < columns) {
- b1 += 2;
+ case twoDimVertR2:
+ addPixels(refLine[b1i] + 2, blackPixels);
+ blackPixels ^= 1;
+ if (codingLine[a0i] < columns) {
+ ++b1i;
+ while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < columns) {
+ b1i += 2;
}
- } else {
- a0New = codingLine[++a0] = columns;
}
break;
case twoDimVertR1:
- if (refLine[b1] + 1 < columns) {
- a0New = codingLine[++a0] = refLine[b1] + 1;
- ++b1;
- while (refLine[b1] <= a0New && refLine[b1] < columns) {
- b1 += 2;
+ addPixels(refLine[b1i] + 1, blackPixels);
+ blackPixels ^= 1;
+ if (codingLine[a0i] < columns) {
+ ++b1i;
+ while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < columns) {
+ b1i += 2;
}
- } else {
- a0New = codingLine[++a0] = columns;
}
break;
- case twoDimVertL1:
- if (refLine[b1] - 1 > a0New || (a0 == 0 && refLine[b1] == 1)) {
- a0New = codingLine[++a0] = refLine[b1] - 1;
- --b1;
- while (refLine[b1] <= a0New && refLine[b1] < columns) {
- b1 += 2;
+ case twoDimVert0:
+ addPixels(refLine[b1i], blackPixels);
+ blackPixels ^= 1;
+ if (codingLine[a0i] < columns) {
+ ++b1i;
+ while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < columns) {
+ b1i += 2;
}
}
break;
- case twoDimVertR2:
- if (refLine[b1] + 2 < columns) {
- a0New = codingLine[++a0] = refLine[b1] + 2;
- ++b1;
- while (refLine[b1] <= a0New && refLine[b1] < columns) {
- b1 += 2;
+ case twoDimVertL3:
+ addPixelsNeg(refLine[b1i] - 3, blackPixels);
+ blackPixels ^= 1;
+ if (codingLine[a0i] < columns) {
+ if (b1i > 0) {
+ --b1i;
+ } else {
+ ++b1i;
+ }
+ while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < columns) {
+ b1i += 2;
}
- } else {
- a0New = codingLine[++a0] = columns;
}
break;
case twoDimVertL2:
- if (refLine[b1] - 2 > a0New || (a0 == 0 && refLine[b1] == 2)) {
- a0New = codingLine[++a0] = refLine[b1] - 2;
- --b1;
- while (refLine[b1] <= a0New && refLine[b1] < columns) {
- b1 += 2;
+ addPixelsNeg(refLine[b1i] - 2, blackPixels);
+ blackPixels ^= 1;
+ if (codingLine[a0i] < columns) {
+ if (b1i > 0) {
+ --b1i;
+ } else {
+ ++b1i;
}
- }
- break;
- case twoDimVertR3:
- if (refLine[b1] + 3 < columns) {
- a0New = codingLine[++a0] = refLine[b1] + 3;
- ++b1;
- while (refLine[b1] <= a0New && refLine[b1] < columns) {
- b1 += 2;
+ while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < columns) {
+ b1i += 2;
}
- } else {
- a0New = codingLine[++a0] = columns;
}
break;
- case twoDimVertL3:
- if (refLine[b1] - 3 > a0New || (a0 == 0 && refLine[b1] == 3)) {
- a0New = codingLine[++a0] = refLine[b1] - 3;
- --b1;
- while (refLine[b1] <= a0New && refLine[b1] < columns) {
- b1 += 2;
+ case twoDimVertL1:
+ addPixelsNeg(refLine[b1i] - 1, blackPixels);
+ blackPixels ^= 1;
+ if (codingLine[a0i] < columns) {
+ if (b1i > 0) {
+ --b1i;
+ } else {
+ ++b1i;
+ }
+ while (refLine[b1i] <= codingLine[a0i] && refLine[b1i] < columns) {
+ b1i += 2;
}
}
break;
case EOF:
+ addPixels(columns, 0);
eof = gTrue;
- codingLine[a0 = 0] = columns;
- return EOF;
+ break;
default:
error(getPos(), "Bad 2D code %04x in CCITTFax stream", code1);
+ addPixels(columns, 0);
err = gTrue;
break;
}
- } while (codingLine[a0] < columns);
+ }
// 1-D encoding
} else {
- codingLine[a0 = 0] = 0;
- while (1) {
+ codingLine[0] = 0;
+ a0i = 0;
+ blackPixels = 0;
+ while (codingLine[a0i] < columns) {
code1 = 0;
- do {
- code1 += code3 = getWhiteCode();
- } while (code3 >= 64);
- codingLine[a0+1] = codingLine[a0] + code1;
- ++a0;
- if (codingLine[a0] >= columns) {
- break;
- }
- code2 = 0;
- do {
- code2 += code3 = getBlackCode();
- } while (code3 >= 64);
- codingLine[a0+1] = codingLine[a0] + code2;
- ++a0;
- if (codingLine[a0] >= columns) {
- break;
+ if (blackPixels) {
+ do {
+ code1 += code3 = getBlackCode();
+ } while (code3 >= 64);
+ } else {
+ do {
+ code1 += code3 = getWhiteCode();
+ } while (code3 >= 64);
}
+ addPixels(codingLine[a0i] + code1, blackPixels);
+ blackPixels ^= 1;
}
}
- if (codingLine[a0] != columns) {
- error(getPos(), "CCITTFax row is wrong length (%d)", codingLine[a0]);
- // force the row to be the correct length
- while (codingLine[a0] > columns) {
- --a0;
- }
- codingLine[++a0] = columns;
- err = gTrue;
- }
-
// byte-align the row
if (byteAlign) {
inputBits &= ~7;
@@ -1562,14 +1586,17 @@
// this if we know the stream contains end-of-line markers because
// the "just plow on" technique tends to work better otherwise
} else if (err && endOfLine) {
- do {
+ while (1) {
+ code1 = lookBits(13);
if (code1 == EOF) {
eof = gTrue;
return EOF;
}
+ if ((code1 >> 1) == 0x001) {
+ break;
+ }
eatBits(1);
- code1 = lookBits(13);
- } while ((code1 >> 1) != 0x001);
+ }
eatBits(12);
if (encoding > 0) {
eatBits(1);
@@ -1577,11 +1604,11 @@
}
}
- a0 = 0;
- outputBits = codingLine[1] - codingLine[0];
- if (outputBits == 0) {
- a0 = 1;
- outputBits = codingLine[2] - codingLine[1];
+ // set up for output
+ if (codingLine[0] > 0) {
+ outputBits = codingLine[a0i = 0];
+ } else {
+ outputBits = codingLine[a0i = 1];
}
++row;
@@ -1589,39 +1616,43 @@
// get a byte
if (outputBits >= 8) {
- ret = ((a0 & 1) == 0) ? 0xff : 0x00;
- if ((outputBits -= 8) == 0) {
- ++a0;
- if (codingLine[a0] < columns) {
- outputBits = codingLine[a0 + 1] - codingLine[a0];
- }
+ buf = (a0i & 1) ? 0x00 : 0xff;
+ outputBits -= 8;
+ if (outputBits == 0 && codingLine[a0i] < columns) {
+ ++a0i;
+ outputBits = codingLine[a0i] - codingLine[a0i - 1];
}
} else {
bits = 8;
- ret = 0;
+ buf = 0;
do {
if (outputBits > bits) {
- i = bits;
- bits = 0;
- if ((a0 & 1) == 0) {
- ret |= 0xff >> (8 - i);
+ buf <<= bits;
+ if (!(a0i & 1)) {
+ buf |= 0xff >> (8 - bits);
}
- outputBits -= i;
+ outputBits -= bits;
+ bits = 0;
} else {
- i = outputBits;
- bits -= outputBits;
- if ((a0 & 1) == 0) {
- ret |= (0xff >> (8 - i)) << bits;
+ buf <<= outputBits;
+ if (!(a0i & 1)) {
+ buf |= 0xff >> (8 - outputBits);
}
+ bits -= outputBits;
outputBits = 0;
- ++a0;
- if (codingLine[a0] < columns) {
- outputBits = codingLine[a0 + 1] - codingLine[a0];
+ if (codingLine[a0i] < columns) {
+ ++a0i;
+ outputBits = codingLine[a0i] - codingLine[a0i - 1];
+ } else if (bits > 0) {
+ buf <<= bits;
+ bits = 0;
}
}
- } while (bits > 0 && codingLine[a0] < columns);
+ } while (bits);
+ }
+ if (black) {
+ buf ^= 0xff;
}
- buf = black ? (ret ^ 0xff) : ret;
return buf;
}
@@ -1663,6 +1694,9 @@
code = 0; // make gcc happy
if (endOfBlock) {
code = lookBits(12);
+ if (code == EOF) {
+ return 1;
+ }
if ((code >> 5) == 0) {
p = &whiteTab1[code];
} else {
@@ -1675,6 +1709,9 @@
} else {
for (n = 1; n <= 9; ++n) {
code = lookBits(n);
+ if (code == EOF) {
+ return 1;
+ }
if (n < 9) {
code <<= 9 - n;
}
@@ -1686,6 +1723,9 @@
}
for (n = 11; n <= 12; ++n) {
code = lookBits(n);
+ if (code == EOF) {
+ return 1;
+ }
if (n < 12) {
code <<= 12 - n;
}
@@ -1711,9 +1751,12 @@
code = 0; // make gcc happy
if (endOfBlock) {
code = lookBits(13);
+ if (code == EOF) {
+ return 1;
+ }
if ((code >> 7) == 0) {
p = &blackTab1[code];
- } else if ((code >> 9) == 0) {
+ } else if ((code >> 9) == 0 && (code >> 7) != 0) {
p = &blackTab2[(code >> 1) - 64];
} else {
p = &blackTab3[code >> 7];
@@ -1725,6 +1768,9 @@
} else {
for (n = 2; n <= 6; ++n) {
code = lookBits(n);
+ if (code == EOF) {
+ return 1;
+ }
if (n < 6) {
code <<= 6 - n;
}
@@ -1736,6 +1782,9 @@
}
for (n = 7; n <= 12; ++n) {
code = lookBits(n);
+ if (code == EOF) {
+ return 1;
+ }
if (n < 12) {
code <<= 12 - n;
}
@@ -1749,6 +1798,9 @@
}
for (n = 10; n <= 13; ++n) {
code = lookBits(n);
+ if (code == EOF) {
+ return 1;
+ }
if (n < 13) {
code <<= 13 - n;
}
@@ -1963,6 +2015,12 @@
// allocate a buffer for the whole image
bufWidth = ((width + mcuWidth - 1) / mcuWidth) * mcuWidth;
bufHeight = ((height + mcuHeight - 1) / mcuHeight) * mcuHeight;
+ if (bufWidth <= 0 || bufHeight <= 0 ||
+ bufWidth > INT_MAX / bufWidth / (int)sizeof(int)) {
+ error(getPos(), "Invalid image size in DCT stream");
+ y = height;
+ return;
+ }
for (i = 0; i < numComps; ++i) {
frameBuf[i] = (int *)gmallocn(bufWidth * bufHeight, sizeof(int));
memset(frameBuf[i], 0, bufWidth * bufHeight * sizeof(int));
@@ -3038,6 +3096,11 @@
}
scanInfo.firstCoeff = str->getChar();
scanInfo.lastCoeff = str->getChar();
+ if (scanInfo.firstCoeff < 0 || scanInfo.lastCoeff > 63 ||
+ scanInfo.firstCoeff > scanInfo.lastCoeff) {
+ error(getPos(), "Bad DCT coefficient numbers in scan info block");
+ return gFalse;
+ }
c = str->getChar();
scanInfo.ah = (c >> 4) & 0x0f;
scanInfo.al = c & 0x0f;
--- misc/xpdf-3.02/xpdf/Stream.h 2007-02-27 23:05:52.000000000 +0100
+++ misc/build/xpdf-3.02/xpdf/Stream.h 2009-11-10 11:43:10.426813566 +0100
@@ -528,13 +528,15 @@
int row; // current row
int inputBuf; // input buffer
int inputBits; // number of bits in input buffer
- short *refLine; // reference line changing elements
- int b1; // index into refLine
- short *codingLine; // coding line changing elements
- int a0; // index into codingLine
+ int *codingLine; // coding line changing elements
+ int *refLine; // reference line changing elements
+ int a0i; // index into codingLine
+ GBool err; // error on current line
int outputBits; // remaining ouput bits
int buf; // character buffer
+ void addPixels(int a1, int black);
+ void addPixelsNeg(int a1, int black);
short getTwoDimCode();
short getWhiteCode();
short getBlackCode();
--- misc/xpdf-3.02/xpdf/XRef.cc 2007-02-27 23:05:52.000000000 +0100
+++ misc/build/xpdf-3.02/xpdf/XRef.cc 2009-11-10 11:43:54.923556696 +0100
@@ -52,6 +52,8 @@
// generation 0.
ObjectStream(XRef *xref, int objStrNumA);
+ GBool isOk() { return ok; }
+
~ObjectStream();
// Return the object number of this object stream.
@@ -67,6 +69,7 @@
int nObjects; // number of objects in the stream
Object *objs; // the objects (length = nObjects)
int *objNums; // the object numbers (length = nObjects)
+ GBool ok;
};
ObjectStream::ObjectStream(XRef *xref, int objStrNumA) {
@@ -80,6 +83,7 @@
nObjects = 0;
objs = NULL;
objNums = NULL;
+ ok = gFalse;
if (!xref->fetch(objStrNum, 0, &objStr)->isStream()) {
goto err1;
@@ -105,6 +109,13 @@
goto err1;
}
+ // this is an arbitrary limit to avoid integer overflow problems
+ // in the 'new Object[nObjects]' call (Acrobat apparently limits
+ // object streams to 100-200 objects)
+ if (nObjects > 1000000) {
+ error(-1, "Too many objects in an object stream");
+ goto err1;
+ }
objs = new Object[nObjects];
objNums = (int *)gmallocn(nObjects, sizeof(int));
offsets = (int *)gmallocn(nObjects, sizeof(int));
@@ -161,10 +172,10 @@
}
gfree(offsets);
+ ok = gTrue;
err1:
objStr.free();
- return;
}
ObjectStream::~ObjectStream() {
@@ -837,6 +848,11 @@
delete objStr;
}
objStr = new ObjectStream(this, e->offset);
+ if (!objStr->isOk()) {
+ delete objStr;
+ objStr = NULL;
+ goto err;
+ }
}
objStr->getObject(e->gen, num, obj);
break;
--- misc/xpdf-3.02/fofi/FoFiType1.cc 2007-02-27 23:05:51.000000000 +0100
+++ misc/build/xpdf-3.02/fofi/FoFiType1.cc 2011-01-04 13:41:06.871136746 +0100
@@ -224,7 +224,7 @@
code = code * 8 + (*p2 - '0');
}
}
- if (code < 256) {
+ if (code < 256 && code >= 0) {
for (p = p2; *p == ' ' || *p == '\t'; ++p) ;
if (*p == '/') {
++p;
--- misc/xpdf-3.02/xpdf/Gfx.cc 2007-02-27 23:05:52.000000000 +0100
+++ misc/build/xpdf-3.02/xpdf/Gfx.cc 2011-01-04 13:41:19.847501431 +0100
@@ -441,6 +441,7 @@
void *abortCheckCbkDataA) {
int i;
+ parser = NULL;
xref = xrefA;
subPage = gFalse;
printCommands = globalParams->getPrintCommands();
@@ -483,6 +484,7 @@
void *abortCheckCbkDataA) {
int i;
+ parser = NULL;
xref = xrefA;
subPage = gTrue;
printCommands = globalParams->getPrintCommands();