]> www.fi.muni.cz Git - evince.git/blobdiff - pdf/xpdf/Parser.cc
change (disabled) font embedding code
[evince.git] / pdf / xpdf / Parser.cc
index 5568580742cbebf3629e888cb2a9a06531f7a1ff..4df53c986caae7dfc98811eed10290957259324d 100644 (file)
@@ -2,7 +2,7 @@
 //
 // Parser.cc
 //
-// Copyright 1996 Derek B. Noonburg
+// Copyright 1996-2002 Glyph & Cog, LLC
 //
 //========================================================================
 
 #pragma implementation
 #endif
 
+#include <aconf.h>
 #include <stddef.h>
 #include "Object.h"
 #include "Array.h"
 #include "Dict.h"
 #include "Parser.h"
+#include "XRef.h"
 #include "Error.h"
+#ifndef NO_DECRYPTION
+#include "Decrypt.h"
+#endif
 
-Parser::Parser(Lexer *lexer1) {
-  lexer = lexer1;
+Parser::Parser(XRef *xrefA, Lexer *lexerA) {
+  xref = xrefA;
+  lexer = lexerA;
   inlineImg = 0;
   lexer->getObj(&buf1);
   lexer->getObj(&buf2);
@@ -30,11 +36,23 @@ Parser::~Parser() {
   delete lexer;
 }
 
+#ifndef NO_DECRYPTION
+Object *Parser::getObj(Object *obj,
+                      Guchar *fileKey, int keyLength,
+                      int objNum, int objGen) {
+#else
 Object *Parser::getObj(Object *obj) {
+#endif
   char *key;
   Stream *str;
   Object obj2;
   int num;
+#ifndef NO_DECRYPTION
+  Decrypt *decrypt;
+  GString *s;
+  char *p;
+  int i;
+#endif
 
   // refill buffer after inline image data
   if (inlineImg == 2) {
@@ -48,9 +66,13 @@ Object *Parser::getObj(Object *obj) {
   // array
   if (buf1.isCmd("[")) {
     shift();
-    obj->initArray();
+    obj->initArray(xref);
     while (!buf1.isCmd("]") && !buf1.isEOF())
+#ifndef NO_DECRYPTION
+      obj->arrayAdd(getObj(&obj2, fileKey, keyLength, objNum, objGen));
+#else
       obj->arrayAdd(getObj(&obj2));
+#endif
     if (buf1.isEOF())
       error(getPos(), "End of file inside array");
     shift();
@@ -58,7 +80,7 @@ Object *Parser::getObj(Object *obj) {
   // dictionary or stream
   } else if (buf1.isCmd("<<")) {
     shift();
-    obj->initDict();
+    obj->initDict(xref);
     while (!buf1.isCmd(">>") && !buf1.isEOF()) {
       if (!buf1.isName()) {
        error(getPos(), "Dictionary key must be a name object");
@@ -68,7 +90,11 @@ Object *Parser::getObj(Object *obj) {
        shift();
        if (buf1.isEOF() || buf1.isError())
          break;
+#ifndef NO_DECRYPTION
+       obj->dictAdd(key, getObj(&obj2, fileKey, keyLength, objNum, objGen));
+#else
        obj->dictAdd(key, getObj(&obj2));
+#endif
       }
     }
     if (buf1.isEOF())
@@ -76,6 +102,12 @@ Object *Parser::getObj(Object *obj) {
     if (buf2.isCmd("stream")) {
       if ((str = makeStream(obj))) {
        obj->initStream(str);
+#ifndef NO_DECRYPTION
+       if (fileKey) {
+         str->getBaseStream()->doDecryption(fileKey, keyLength,
+                                            objNum, objGen);
+       }
+#endif
       } else {
        obj->free();
        obj->initError();
@@ -96,6 +128,21 @@ Object *Parser::getObj(Object *obj) {
       obj->initInt(num);
     }
 
+#ifndef NO_DECRYPTION
+  // string
+  } else if (buf1.isString() && fileKey) {
+    buf1.copy(obj);
+    s = obj->getString();
+    decrypt = new Decrypt(fileKey, keyLength, objNum, objGen);
+    for (i = 0, p = obj->getString()->getCString();
+        i < s->getLength();
+        ++i, ++p) {
+      *p = decrypt->decryptByte(*p);
+    }
+    delete decrypt;
+    shift();
+#endif
+
   // simple object
   } else {
     buf1.copy(obj);
@@ -108,7 +155,7 @@ Object *Parser::getObj(Object *obj) {
 Stream *Parser::makeStream(Object *dict) {
   Object obj;
   Stream *str;
-  int pos, length;
+  Guint pos, endPos, length;
 
   // get stream start position
   lexer->skipToNextLine();
@@ -117,7 +164,7 @@ Stream *Parser::makeStream(Object *dict) {
   // get length
   dict->dictLookup("Length", &obj);
   if (obj.isInt()) {
-    length = obj.getInt();
+    length = (Guint)obj.getInt();
     obj.free();
   } else {
     error(getPos(), "Bad 'Length' attribute in stream");
@@ -125,8 +172,14 @@ Stream *Parser::makeStream(Object *dict) {
     return NULL;
   }
 
+  // check for length in damaged file
+  if (xref->getStreamEnd(pos, &endPos)) {
+    length = endPos - pos;
+  }
+
   // make base stream
-  str = lexer->getStream()->getBaseStream()->makeSubStream(pos, length, dict);
+  str = lexer->getStream()->getBaseStream()->makeSubStream(pos, gTrue,
+                                                          length, dict);
 
   // get filters
   str = str->addFilters(dict);