"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "xpdf/Stream.cc" between
xpdf-4.03.tar.gz and xpdf-4.04.tar.gz

About: Xpdf is a PDF viewer for X.

Stream.cc  (xpdf-4.03):Stream.cc  (xpdf-4.04)
skipping to change at line 55 skipping to change at line 55
#ifdef VMS #ifdef VMS
#ifdef __GNUC__ #ifdef __GNUC__
#define SEEK_SET 0 #define SEEK_SET 0
#define SEEK_CUR 1 #define SEEK_CUR 1
#define SEEK_END 2 #define SEEK_END 2
#endif #endif
#endif #endif
//------------------------------------------------------------------------ //------------------------------------------------------------------------
// An LZW/Flate decompression bomb is detected if the output size
// exceeds decompressionBombSizeThreshold and the decompression ratio
// exceeds decompressionBombRatioThreshold.
#define decompressionBombSizeThreshold 50000000
#define decompressionBombRatioThreshold 200
//------------------------------------------------------------------------
// Stream (base class) // Stream (base class)
//------------------------------------------------------------------------ //------------------------------------------------------------------------
Stream::Stream() { Stream::Stream() {
} }
Stream::~Stream() { Stream::~Stream() {
} }
void Stream::close() { void Stream::close() {
skipping to change at line 151 skipping to change at line 159
dict->dictLookup("DecodeParms", &params, recursion); dict->dictLookup("DecodeParms", &params, recursion);
if (params.isNull()) { if (params.isNull()) {
params.free(); params.free();
dict->dictLookup("DP", &params, recursion); dict->dictLookup("DP", &params, recursion);
} }
if (obj.isName()) { if (obj.isName()) {
str = makeFilter(obj.getName(), str, &params, recursion); str = makeFilter(obj.getName(), str, &params, recursion);
} else if (obj.isArray()) { } else if (obj.isArray()) {
for (i = 0; i < obj.arrayGetLength(); ++i) { for (i = 0; i < obj.arrayGetLength(); ++i) {
obj.arrayGet(i, &obj2, recursion); obj.arrayGet(i, &obj2, recursion);
if (params.isArray()) if (params.isArray() && i < params.arrayGetLength())
params.arrayGet(i, &params2, recursion); params.arrayGet(i, &params2, recursion);
else else
params2.initNull(); params2.initNull();
if (obj2.isName()) { if (obj2.isName()) {
str = makeFilter(obj2.getName(), str, &params2, recursion); str = makeFilter(obj2.getName(), str, &params2, recursion);
} else { } else {
error(errSyntaxError, getPos(), "Bad filter name"); error(errSyntaxError, getPos(), "Bad filter name");
str = new EOFStream(str); str = new EOFStream(str);
} }
obj2.free(); obj2.free();
skipping to change at line 308 skipping to change at line 316
} }
str = new FlateStream(str, pred, columns, colors, bits); str = new FlateStream(str, pred, columns, colors, bits);
} else if (!strcmp(name, "JBIG2Decode")) { } else if (!strcmp(name, "JBIG2Decode")) {
if (params->isDict()) { if (params->isDict()) {
params->dictLookup("JBIG2Globals", &globals, recursion); params->dictLookup("JBIG2Globals", &globals, recursion);
} }
str = new JBIG2Stream(str, &globals); str = new JBIG2Stream(str, &globals);
globals.free(); globals.free();
} else if (!strcmp(name, "JPXDecode")) { } else if (!strcmp(name, "JPXDecode")) {
str = new JPXStream(str); str = new JPXStream(str);
} else if (!strcmp(name, "Crypt")) {
// this is handled in Parser::makeStream()
} else { } else {
error(errSyntaxError, getPos(), "Unknown filter '{0:s}'", name); error(errSyntaxError, getPos(), "Unknown filter '{0:s}'", name);
str = new EOFStream(str); str = new EOFStream(str);
} }
return str; return str;
} }
//------------------------------------------------------------------------ //------------------------------------------------------------------------
// BaseStream // BaseStream
//------------------------------------------------------------------------ //------------------------------------------------------------------------
skipping to change at line 387 skipping to change at line 397
} }
ImageStream::~ImageStream() { ImageStream::~ImageStream() {
if (imgLine != (Guchar *)inputLine) { if (imgLine != (Guchar *)inputLine) {
gfree(imgLine); gfree(imgLine);
} }
gfree(inputLine); gfree(inputLine);
} }
void ImageStream::reset() { void ImageStream::reset() {
str->disableDecompressionBombChecking();
str->reset(); str->reset();
} }
void ImageStream::close() { void ImageStream::close() {
str->close(); str->close();
} }
GBool ImageStream::getPixel(Guchar *pix) { GBool ImageStream::getPixel(Guchar *pix) {
int i; int i;
skipping to change at line 937 skipping to change at line 948
bufPtr += n; bufPtr += n;
return n; return n;
} }
void MemStream::setPos(GFileOffset pos, int dir) { void MemStream::setPos(GFileOffset pos, int dir) {
Guint i; Guint i;
if (dir >= 0) { if (dir >= 0) {
i = (Guint)pos; i = (Guint)pos;
} else { } else {
i = (Guint)(start + length - pos); if (pos > start + length) {
i = 0;
} else {
i = (Guint)(start + length - pos);
}
} }
if (i < start) { if (i < start) {
i = start; i = start;
} else if (i > start + length) { } else if (i > start + length) {
i = start + length; i = start + length;
} }
bufPtr = buf + i; bufPtr = buf + i;
} }
void MemStream::moveStart(int delta) { void MemStream::moveStart(int delta) {
skipping to change at line 1223 skipping to change at line 1238
delete pred; delete pred;
pred = NULL; pred = NULL;
} }
} else { } else {
pred = NULL; pred = NULL;
} }
early = earlyA; early = earlyA;
eof = gFalse; eof = gFalse;
inputBits = 0; inputBits = 0;
clearTable(); clearTable();
checkForDecompressionBombs = gTrue;
} }
LZWStream::~LZWStream() { LZWStream::~LZWStream() {
if (pred) { if (pred) {
delete pred; delete pred;
} }
delete str; delete str;
} }
Stream *LZWStream::copy() { Stream *LZWStream::copy() {
if (pred) { if (pred) {
return new LZWStream(str->copy(), pred->getPredictor(), return new LZWStream(str->copy(), pred->getPredictor(),
pred->getWidth(), pred->getNComps(), pred->getWidth(), pred->getNComps(),
pred->getNBits(), early); pred->getNBits(), early);
} else { } else {
return new LZWStream(str->copy(), 1, 0, 0, 0, early); return new LZWStream(str->copy(), 1, 0, 0, 0, early);
} }
} }
void LZWStream::disableDecompressionBombChecking() {
checkForDecompressionBombs = gFalse;
FilterStream::disableDecompressionBombChecking();
}
int LZWStream::getChar() { int LZWStream::getChar() {
if (pred) { if (pred) {
return pred->getChar(); return pred->getChar();
} }
if (eof) { if (eof) {
return EOF; return EOF;
} }
if (seqIndex >= seqLength) { if (seqIndex >= seqLength) {
if (!processNextCode()) { if (!processNextCode()) {
return EOF; return EOF;
skipping to change at line 1388 skipping to change at line 1409
nextBits = 10; nextBits = 10;
else if (nextCode + early == 1024) else if (nextCode + early == 1024)
nextBits = 11; nextBits = 11;
else if (nextCode + early == 2048) else if (nextCode + early == 2048)
nextBits = 12; nextBits = 12;
} }
prevCode = code; prevCode = code;
totalOut += seqLength; totalOut += seqLength;
// check for a 'decompression bomb' // check for a 'decompression bomb'
if (totalOut > 50000000 && totalIn < totalOut / 250) { if (checkForDecompressionBombs &&
error(errSyntaxError, getPos(), "Decompression bomb in flate stream"); totalOut > decompressionBombSizeThreshold &&
totalIn < totalOut / decompressionBombRatioThreshold) {
error(errSyntaxError, getPos(), "Decompression bomb in LZW stream");
eof = gTrue; eof = gTrue;
return gFalse; return gFalse;
} }
// reset buffer // reset buffer
seqIndex = 0; seqIndex = 0;
return gTrue; return gTrue;
} }
skipping to change at line 2640 skipping to change at line 2663
39, 46, 53, 60, 39, 46, 53, 60,
61, 54, 47, 61, 54, 47,
55, 62, 55, 62,
63 63
}; };
DCTStream::DCTStream(Stream *strA, GBool colorXformA): DCTStream::DCTStream(Stream *strA, GBool colorXformA):
FilterStream(strA) { FilterStream(strA) {
int i; int i;
prepared = gFalse;
colorXform = colorXformA; colorXform = colorXformA;
progressive = interleaved = gFalse; progressive = interleaved = gFalse;
width = height = 0; width = height = 0;
mcuWidth = mcuHeight = 0; mcuWidth = mcuHeight = 0;
numComps = 0; numComps = 0;
comp = 0; comp = 0;
x = y = 0; x = y = 0;
for (i = 0; i < 4; ++i) { for (i = 0; i < 4; ++i) {
frameBuf[i] = NULL; frameBuf[i] = NULL;
} }
skipping to change at line 2685 skipping to change at line 2709
numDCHuffTables = 0; numDCHuffTables = 0;
numACHuffTables = 0; numACHuffTables = 0;
gotJFIFMarker = gFalse; gotJFIFMarker = gFalse;
gotAdobeMarker = gFalse; gotAdobeMarker = gFalse;
restartInterval = 0; restartInterval = 0;
if (!readHeader(gTrue)) { if (!readHeader(gTrue)) {
// force an EOF condition // force an EOF condition
progressive = gTrue; progressive = gTrue;
y = height; y = height;
prepared = gTrue;
return; return;
} }
// compute MCU size // compute MCU size
if (numComps == 1) { if (numComps == 1) {
compInfo[0].hSample = compInfo[0].vSample = 1; compInfo[0].hSample = compInfo[0].vSample = 1;
} }
mcuWidth = compInfo[0].hSample; mcuWidth = compInfo[0].hSample;
mcuHeight = compInfo[0].vSample; mcuHeight = compInfo[0].vSample;
for (i = 1; i < numComps; ++i) { for (i = 1; i < numComps; ++i) {
skipping to change at line 2721 skipping to change at line 2746
compInfo[2].id == 66) { // ASCII "RGB" compInfo[2].id == 66) { // ASCII "RGB"
colorXform = 0; colorXform = 0;
} else { } else {
colorXform = 1; colorXform = 1;
} }
} else { } else {
colorXform = 0; colorXform = 0;
} }
} }
if (progressive || !interleaved) { prepared = gFalse;
// 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(errSyntaxError, 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));
}
// read the image data
do {
restartMarker = 0xd0;
restart();
readScan();
} while (readHeader(gFalse));
// decode
decodeImage();
// initialize counters
comp = 0;
x = 0;
y = 0;
} else {
if (scanInfo.numComps != numComps) {
error(errSyntaxError, getPos(), "Invalid scan in sequential DCT stream");
y = height;
return;
}
// allocate a buffer for one row of MCUs
bufWidth = ((width + mcuWidth - 1) / mcuWidth) * mcuWidth;
rowBuf = (Guchar *)gmallocn(numComps * mcuHeight, bufWidth);
rowBufPtr = rowBufEnd = rowBuf;
// initialize counters
y = -mcuHeight;
restartMarker = 0xd0;
restart();
}
} }
GBool DCTStream::checkSequentialInterleaved() { GBool DCTStream::checkSequentialInterleaved() {
GBool headerOk; GBool headerOk;
str->reset(); str->reset();
progressive = interleaved = gFalse; progressive = interleaved = gFalse;
width = height = 0; width = height = 0;
numComps = 0; numComps = 0;
skipping to change at line 2810 skipping to change at line 2786
frameBuf[i] = NULL; frameBuf[i] = NULL;
} }
gfree(rowBuf); gfree(rowBuf);
rowBuf = NULL; rowBuf = NULL;
FilterStream::close(); FilterStream::close();
} }
int DCTStream::getChar() { int DCTStream::getChar() {
int c; int c;
if (!prepared) {
prepare();
}
if (progressive || !interleaved) { if (progressive || !interleaved) {
if (y >= height) { if (y >= height) {
return EOF; return EOF;
} }
c = frameBuf[comp][y * bufWidth + x]; c = frameBuf[comp][y * bufWidth + x];
if (++comp == numComps) { if (++comp == numComps) {
comp = 0; comp = 0;
if (++x == width) { if (++x == width) {
x = 0; x = 0;
++y; ++y;
skipping to change at line 2839 skipping to change at line 2818
y = height; y = height;
return EOF; return EOF;
} }
} }
c = *rowBufPtr++; c = *rowBufPtr++;
} }
return c; return c;
} }
int DCTStream::lookChar() { int DCTStream::lookChar() {
if (!prepared) {
prepare();
}
if (progressive || !interleaved) { if (progressive || !interleaved) {
if (y >= height) { if (y >= height) {
return EOF; return EOF;
} }
return frameBuf[comp][y * bufWidth + x]; return frameBuf[comp][y * bufWidth + x];
} else { } else {
if (rowBufPtr == rowBufEnd) { if (rowBufPtr == rowBufEnd) {
if (y + mcuHeight >= height) { if (y + mcuHeight >= height) {
return EOF; return EOF;
} }
skipping to change at line 2861 skipping to change at line 2843
return EOF; return EOF;
} }
} }
return *rowBufPtr; return *rowBufPtr;
} }
} }
int DCTStream::getBlock(char *blk, int size) { int DCTStream::getBlock(char *blk, int size) {
int nRead, nAvail, n; int nRead, nAvail, n;
if (!prepared) {
prepare();
}
if (progressive || !interleaved) { if (progressive || !interleaved) {
if (y >= height) { if (y >= height) {
return 0; return 0;
} }
for (nRead = 0; nRead < size; ++nRead) { for (nRead = 0; nRead < size; ++nRead) {
blk[nRead] = (char)frameBuf[comp][y * bufWidth + x]; blk[nRead] = (char)frameBuf[comp][y * bufWidth + x];
if (++comp == numComps) { if (++comp == numComps) {
comp = 0; comp = 0;
if (++x == width) { if (++x == width) {
x = 0; x = 0;
skipping to change at line 2902 skipping to change at line 2887
nAvail = (int)(rowBufEnd - rowBufPtr); nAvail = (int)(rowBufEnd - rowBufPtr);
n = (nAvail < size - nRead) ? nAvail : size - nRead; n = (nAvail < size - nRead) ? nAvail : size - nRead;
memcpy(blk + nRead, rowBufPtr, n); memcpy(blk + nRead, rowBufPtr, n);
rowBufPtr += n; rowBufPtr += n;
nRead += n; nRead += n;
} }
} }
return nRead; return nRead;
} }
void DCTStream::prepare() {
int i;
if (progressive || !interleaved) {
// 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(errSyntaxError, getPos(), "Invalid image size in DCT stream");
y = height;
prepared = gTrue;
return;
}
#if USE_EXCEPTIONS
try {
#endif
for (i = 0; i < numComps; ++i) {
frameBuf[i] = (int *)gmallocn(bufWidth * bufHeight, sizeof(int));
memset(frameBuf[i], 0, bufWidth * bufHeight * sizeof(int));
}
#if USE_EXCEPTIONS
} catch (GMemException) {
error(errSyntaxError, getPos(), "Out of memory in DCT stream");
y = height;
prepared = gTrue;
return;
}
#endif
// read the image data
do {
restartMarker = 0xd0;
restart();
readScan();
} while (readHeader(gFalse));
// decode
decodeImage();
// initialize counters
comp = 0;
x = 0;
y = 0;
} else {
if (scanInfo.numComps != numComps) {
error(errSyntaxError, getPos(), "Invalid scan in sequential DCT stream");
y = height;
prepared = gTrue;
return;
}
// allocate a buffer for one row of MCUs
bufWidth = ((width + mcuWidth - 1) / mcuWidth) * mcuWidth;
rowBuf = (Guchar *)gmallocn(numComps * mcuHeight, bufWidth);
rowBufPtr = rowBufEnd = rowBuf;
// initialize counters
y = -mcuHeight;
restartMarker = 0xd0;
restart();
}
prepared = gTrue;
}
void DCTStream::restart() { void DCTStream::restart() {
int i; int i;
inputBits = 0; inputBits = 0;
restartCtr = restartInterval; restartCtr = restartInterval;
for (i = 0; i < numComps; ++i) { for (i = 0; i < numComps; ++i) {
compInfo[i].prevDC = 0; compInfo[i].prevDC = 0;
} }
eobRun = 0; eobRun = 0;
} }
skipping to change at line 3843 skipping to change at line 3898
"Invalid DCT marker in scan <{0:02x}>", c); "Invalid DCT marker in scan <{0:02x}>", c);
return gFalse; return gFalse;
} }
break; break;
case 0xd9: // EOI case 0xd9: // EOI
return gFalse; return gFalse;
case 0xda: // SOS case 0xda: // SOS
if (!readScanInfo()) { if (!readScanInfo()) {
return gFalse; return gFalse;
} }
if (frame) {
interleaved = scanInfo.numComps == numComps;
}
doScan = gTrue; doScan = gTrue;
break; break;
case 0xdb: // DQT case 0xdb: // DQT
if (!readQuantTables()) { if (!readQuantTables()) {
return gFalse; return gFalse;
} }
break; break;
case 0xdd: // DRI case 0xdd: // DRI
if (!readRestartInterval()) { if (!readRestartInterval()) {
return gFalse; return gFalse;
skipping to change at line 4008 skipping to change at line 4066
if (scanInfo.numComps <= 0 || scanInfo.numComps > 4) { if (scanInfo.numComps <= 0 || scanInfo.numComps > 4) {
error(errSyntaxError, getPos(), "Bad number of components in DCT stream"); error(errSyntaxError, getPos(), "Bad number of components in DCT stream");
scanInfo.numComps = 0; scanInfo.numComps = 0;
return gFalse; return gFalse;
} }
--length; --length;
if (length != 2 * scanInfo.numComps + 3) { if (length != 2 * scanInfo.numComps + 3) {
error(errSyntaxError, getPos(), "Bad DCT scan info block"); error(errSyntaxError, getPos(), "Bad DCT scan info block");
return gFalse; return gFalse;
} }
interleaved = scanInfo.numComps == numComps;
for (j = 0; j < numComps; ++j) { for (j = 0; j < numComps; ++j) {
scanInfo.comp[j] = gFalse; scanInfo.comp[j] = gFalse;
} }
for (i = 0; i < scanInfo.numComps; ++i) { for (i = 0; i < scanInfo.numComps; ++i) {
id = str->getChar(); id = str->getChar();
// some (broken) DCT streams reuse ID numbers, but at least they // some (broken) DCT streams reuse ID numbers, but at least they
// keep the components in order, so we check compInfo[i] first to // keep the components in order, so we check compInfo[i] first to
// work around the problem // work around the problem
if (id == compInfo[i].id) { if (id == compInfo[i].id) {
j = i; j = i;
skipping to change at line 4913 skipping to change at line 4970
if (!pred->isOk()) { if (!pred->isOk()) {
delete pred; delete pred;
pred = NULL; pred = NULL;
} }
} else { } else {
pred = NULL; pred = NULL;
} }
litCodeTab.codes = NULL; litCodeTab.codes = NULL;
distCodeTab.codes = NULL; distCodeTab.codes = NULL;
memset(buf, 0, flateWindow); memset(buf, 0, flateWindow);
checkForDecompressionBombs = gTrue;
} }
FlateStream::~FlateStream() { FlateStream::~FlateStream() {
if (litCodeTab.codes != fixedLitCodeTab.codes) { if (litCodeTab.codes != fixedLitCodeTab.codes) {
gfree(litCodeTab.codes); gfree(litCodeTab.codes);
} }
if (distCodeTab.codes != fixedDistCodeTab.codes) { if (distCodeTab.codes != fixedDistCodeTab.codes) {
gfree(distCodeTab.codes); gfree(distCodeTab.codes);
} }
if (pred) { if (pred) {
skipping to change at line 4938 skipping to change at line 4996
Stream *FlateStream::copy() { Stream *FlateStream::copy() {
if (pred) { if (pred) {
return new FlateStream(str->copy(), pred->getPredictor(), return new FlateStream(str->copy(), pred->getPredictor(),
pred->getWidth(), pred->getNComps(), pred->getWidth(), pred->getNComps(),
pred->getNBits()); pred->getNBits());
} else { } else {
return new FlateStream(str->copy(), 1, 0, 0, 0); return new FlateStream(str->copy(), 1, 0, 0, 0);
} }
} }
void FlateStream::disableDecompressionBombChecking() {
checkForDecompressionBombs = gFalse;
FilterStream::disableDecompressionBombChecking();
}
void FlateStream::reset() { void FlateStream::reset() {
int cmf, flg; int cmf, flg;
index = 0; index = 0;
remain = 0; remain = 0;
codeBuf = 0; codeBuf = 0;
codeSize = 0; codeSize = 0;
compressedBlock = gFalse; compressedBlock = gFalse;
endOfBlock = gTrue; endOfBlock = gTrue;
eof = gTrue; eof = gTrue;
skipping to change at line 5200 skipping to change at line 5263
} }
remain = i; remain = i;
blockLen -= len; blockLen -= len;
if (blockLen == 0) if (blockLen == 0)
endOfBlock = gTrue; endOfBlock = gTrue;
totalIn += remain; totalIn += remain;
} }
totalOut += remain; totalOut += remain;
// check for a 'decompression bomb' // check for a 'decompression bomb'
if (totalOut > 50000000 && totalIn < totalOut / 250) { if (checkForDecompressionBombs &&
totalOut > decompressionBombSizeThreshold &&
totalIn < totalOut / decompressionBombRatioThreshold) {
error(errSyntaxError, getPos(), "Decompression bomb in flate stream"); error(errSyntaxError, getPos(), "Decompression bomb in flate stream");
endOfBlock = eof = gTrue; endOfBlock = eof = gTrue;
remain = 0; remain = 0;
} }
return; return;
err: err:
error(errSyntaxError, getPos(), "Unexpected end of file in flate stream"); error(errSyntaxError, getPos(), "Unexpected end of file in flate stream");
endOfBlock = eof = gTrue; endOfBlock = eof = gTrue;
skipping to change at line 5251 skipping to change at line 5316
if ((c = str->getChar()) == EOF) if ((c = str->getChar()) == EOF)
goto err; goto err;
blockLen |= (c & 0xff) << 8; blockLen |= (c & 0xff) << 8;
if ((c = str->getChar()) == EOF) if ((c = str->getChar()) == EOF)
goto err; goto err;
check = c & 0xff; check = c & 0xff;
if ((c = str->getChar()) == EOF) if ((c = str->getChar()) == EOF)
goto err; goto err;
check |= (c & 0xff) << 8; check |= (c & 0xff) << 8;
if (check != (~blockLen & 0xffff)) if (check != (~blockLen & 0xffff))
error(errSyntaxError, getPos(), goto err;
"Bad uncompressed block length in flate stream");
codeBuf = 0; codeBuf = 0;
codeSize = 0; codeSize = 0;
totalIn += 4; totalIn += 4;
// compressed block with fixed codes // compressed block with fixed codes
} else if (blockHdr == 1) { } else if (blockHdr == 1) {
compressedBlock = gTrue; compressedBlock = gTrue;
loadFixedCodes(); loadFixedCodes();
// compressed block with dynamic codes // compressed block with dynamic codes
 End of changes. 21 change blocks. 
58 lines changed or deleted 122 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)