1 //========================================================================
5 // Copyright 1996-2003 Glyph & Cog, LLC
7 //========================================================================
11 #ifdef USE_GCC_PRAGMAS
12 #pragma implementation
24 Parser::Parser(XRef *xrefA, Lexer *lexerA) {
38 Object *Parser::getObj(Object *obj,
39 Guchar *fileKey, int keyLength,
40 int objNum, int objGen) {
50 // refill buffer after inline image data
60 if (buf1.isCmd("[")) {
63 while (!buf1.isCmd("]") && !buf1.isEOF())
64 obj->arrayAdd(getObj(&obj2, fileKey, keyLength, objNum, objGen));
66 error(getPos(), "End of file inside array");
69 // dictionary or stream
70 } else if (buf1.isCmd("<<")) {
73 while (!buf1.isCmd(">>") && !buf1.isEOF()) {
75 error(getPos(), "Dictionary key must be a name object");
78 key = copyString(buf1.getName());
80 if (buf1.isEOF() || buf1.isError()) {
84 obj->dictAdd(key, getObj(&obj2, fileKey, keyLength, objNum, objGen));
88 error(getPos(), "End of file inside dictionary");
89 if (buf2.isCmd("stream")) {
90 if ((str = makeStream(obj))) {
93 str->getBaseStream()->doDecryption(fileKey, keyLength,
104 // indirect reference or integer
105 } else if (buf1.isInt()) {
108 if (buf1.isInt() && buf2.isCmd("R")) {
109 obj->initRef(num, buf1.getInt());
117 } else if (buf1.isString() && fileKey) {
119 s = obj->getString();
120 decrypt = new Decrypt(fileKey, keyLength, objNum, objGen);
121 for (i = 0, p = obj->getString()->getCString();
124 *p = decrypt->decryptByte(*p);
138 Stream *Parser::makeStream(Object *dict) {
142 Guint pos, endPos, length;
144 // get stream start position
145 lexer->skipToNextLine();
146 pos = lexer->getPos();
149 dict->dictLookup("Length", &obj);
151 length = (Guint)obj.getInt();
154 error(getPos(), "Bad 'Length' attribute in stream");
159 // check for length in damaged file
160 if (xref && xref->getStreamEnd(pos, &endPos)) {
161 length = endPos - pos;
164 // in badly damaged PDF files, we can run off the end of the input
165 // stream immediately after the "stream" token
166 if (!lexer->getStream()) {
169 baseStr = lexer->getStream()->getBaseStream();
171 // skip over stream data
172 lexer->setPos(pos + length);
174 // refill token buffers and check for 'endstream'
175 shift(); // kill '>>'
176 shift(); // kill 'stream'
177 if (buf1.isCmd("endstream")) {
180 error(getPos(), "Missing 'endstream'");
181 // kludge for broken PDF files: just add 5k to the length, and
187 str = baseStr->makeSubStream(pos, gTrue, length, dict);
190 str = str->addFilters(dict);
195 void Parser::shift() {
200 // in a damaged content stream, if 'ID' shows up in the middle
201 // of a dictionary, we need to reset
204 } else if (buf2.isCmd("ID")) {
205 lexer->skipChar(); // skip char after 'ID' command
210 if (inlineImg > 0) // don't buffer inline image data
213 lexer->getObj(&buf2);