"Fossies" - the Fresh Open Source Software Archive  

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

About: Xpdf is a PDF viewer for X.

Parser.cc  (xpdf-4.03):Parser.cc  (xpdf-4.04)
skipping to change at line 155 skipping to change at line 155
buf1.copy(obj); buf1.copy(obj);
shift(); shift();
} }
return obj; return obj;
} }
Stream *Parser::makeStream(Object *dict, Guchar *fileKey, Stream *Parser::makeStream(Object *dict, Guchar *fileKey,
CryptAlgorithm encAlgorithm, int keyLength, CryptAlgorithm encAlgorithm, int keyLength,
int objNum, int objGen, int recursion) { int objNum, int objGen, int recursion) {
Object obj;
BaseStream *baseStr;
Stream *str, *str2;
GFileOffset pos, endPos, length;
char endstreamBuf[8];
GBool foundEndstream;
int c, i;
// get stream start position // get stream start position
lexer->skipToNextLine(); lexer->skipToNextLine();
if (!(str = lexer->getStream())) { Stream *curStr = lexer->getStream();
if (!curStr) {
return NULL; return NULL;
} }
pos = str->getPos(); GFileOffset pos = curStr->getPos();
GBool haveLength = gFalse;
GFileOffset length = 0;
GFileOffset endPos;
// check for length in damaged file // check for length in damaged file
if (xref && xref->getStreamEnd(pos, &endPos)) { if (xref && xref->getStreamEnd(pos, &endPos)) {
length = endPos - pos; length = endPos - pos;
haveLength = gTrue;
// get length from the stream object // get length from the stream object
} else { } else {
Object obj;
dict->dictLookup("Length", &obj, recursion); dict->dictLookup("Length", &obj, recursion);
if (obj.isInt()) { if (obj.isInt()) {
length = (GFileOffset)(Guint)obj.getInt(); length = (GFileOffset)(Guint)obj.getInt();
obj.free(); haveLength = gTrue;
} else { } else {
error(errSyntaxError, getPos(), "Bad 'Length' attribute in stream"); error(errSyntaxError, getPos(),
obj.free(); "Missing or invalid 'Length' attribute in stream");
return NULL;
} }
obj.free();
} }
// in badly damaged PDF files, we can run off the end of the input // in badly damaged PDF files, we can run off the end of the input
// stream immediately after the "stream" token // stream immediately after the "stream" token
if (!lexer->getStream()) { if (!lexer->getStream()) {
return NULL; return NULL;
} }
// copy the base stream (Lexer will free stream objects when it gets // copy the base stream (Lexer will free stream objects when it gets
// to end of stream -- which can happen in the shift() calls below) // to end of stream -- which can happen in the shift() calls below)
baseStr = (BaseStream *)lexer->getStream()->getBaseStream()->copy(); BaseStream *baseStr =
(BaseStream *)lexer->getStream()->getBaseStream()->copy();
// make new base stream // 'Length' attribute is missing -- search for 'endstream'
str = baseStr->makeSubStream(pos, gTrue, length, dict); if (!haveLength) {
GBool foundEndstream = gFalse;
char endstreamBuf[8];
if ((curStr = lexer->getStream())) {
int c;
while ((c = curStr->getChar()) != EOF) {
if (c == 'e' &&
curStr->getBlock(endstreamBuf, 8) == 8 &&
!memcmp(endstreamBuf, "ndstream", 8)) {
length = curStr->getPos() - 9 - pos;
foundEndstream = gTrue;
break;
}
}
}
if (!foundEndstream) {
error(errSyntaxError, getPos(), "Couldn't find 'endstream' for stream");
delete baseStr;
return NULL;
}
}
// skip over stream data // make new base stream
lexer->setPos(pos + length); Stream *str = baseStr->makeSubStream(pos, gTrue, length, dict);
// check for 'endstream' // look for the 'endstream' marker
// NB: we never reuse the Parser object to parse objects after a if (haveLength) {
// stream, and we could (if the PDF file is damaged) be in the // skip over stream data
// middle of binary data at this point, so we check the stream data lexer->setPos(pos + length);
// directly for 'endstream', rather than calling shift() to parse
// objects // check for 'endstream'
foundEndstream = gFalse; // NB: we never reuse the Parser object to parse objects after a
if ((str2 = lexer->getStream())) { // stream, and we could (if the PDF file is damaged) be in the
// skip up to 100 whitespace chars // middle of binary data at this point, so we check the stream
for (i = 0; i < 100; ++i) { // data directly for 'endstream', rather than calling shift() to
c = str2->getChar(); // parse objects
if (!Lexer::isSpace(c)) { GBool foundEndstream = gFalse;
break; char endstreamBuf[8];
if ((curStr = lexer->getStream())) {
// skip up to 100 whitespace chars
int c;
for (int i = 0; i < 100; ++i) {
c = curStr->getChar();
if (!Lexer::isSpace(c)) {
break;
}
} }
} if (c == 'e') {
if (c == 'e') { if (curStr->getBlock(endstreamBuf, 8) == 8 &&
if (str2->getBlock(endstreamBuf, 8) == 8 || !memcmp(endstreamBuf, "ndstream", 8)) {
!memcmp(endstreamBuf, "ndstream", 8)) { foundEndstream = gTrue;
foundEndstream = gTrue; }
} }
} }
} if (!foundEndstream) {
if (!foundEndstream) { error(errSyntaxError, getPos(), "Missing 'endstream'");
error(errSyntaxError, getPos(), "Missing 'endstream'"); // kludge for broken PDF files: just add 5k to the length, and
// kludge for broken PDF files: just add 5k to the length, and // hope it's enough
// hope it's enough // (dict is now owned by str, so we need to copy it before deleting str)
// (dict is now owned by str, so we need to copy it before deleting str) Object obj;
dict->copy(&obj); dict->copy(&obj);
delete str; delete str;
length += 5000; length += 5000;
str = baseStr->makeSubStream(pos, gTrue, length, &obj); str = baseStr->makeSubStream(pos, gTrue, length, &obj);
}
} }
// free the copied base stream // free the copied base stream
delete baseStr; delete baseStr;
// handle decryption // handle decryption
if (fileKey) { if (fileKey) {
str = new DecryptStream(str, fileKey, encAlgorithm, keyLength, // the 'Crypt' filter is used to mark unencrypted metadata streams
objNum, objGen); //~ this should also check for an empty DecodeParams entry
GBool encrypted = gTrue;
Object obj;
dict->dictLookup("Filter", &obj, recursion);
if (obj.isName("Crypt")) {
encrypted = gFalse;
} else if (obj.isArray() && obj.arrayGetLength() >= 1) {
Object obj2;
if (obj.arrayGet(0, &obj2)->isName("Crypt")) {
encrypted = gFalse;
}
obj2.free();
}
obj.free();
if (encrypted) {
str = new DecryptStream(str, fileKey, encAlgorithm, keyLength,
objNum, objGen);
}
} }
// get filters // get filters
str = str->addFilters(dict, recursion); str = str->addFilters(dict, recursion);
return str; return str;
} }
void Parser::shift() { void Parser::shift() {
if (inlineImg > 0) { if (inlineImg > 0) {
 End of changes. 16 change blocks. 
49 lines changed or deleted 96 lines changed or added

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