[poppler] 2 commits - CMakeLists.txt poppler/Annot.cc poppler/FileSpec.cc poppler/FileSpec.h poppler/Link.cc poppler/Link.h poppler/Makefile.am poppler/PSOutputDev.cc poppler/PSOutputDev.h poppler/Sound.cc

Carlos Garcia Campos carlosgc at kemper.freedesktop.org
Fri Sep 5 09:18:26 PDT 2008


 CMakeLists.txt         |    2 
 poppler/Annot.cc       |    8 +-
 poppler/FileSpec.cc    |  146 +++++++++++++++++++++++++++++++++++++++++++++++++
 poppler/FileSpec.h     |   24 ++++++++
 poppler/Link.cc        |  104 +++++-----------------------------
 poppler/Link.h         |    4 -
 poppler/Makefile.am    |    2 
 poppler/PSOutputDev.cc |   35 +----------
 poppler/PSOutputDev.h  |    1 
 poppler/Sound.cc       |    7 +-
 10 files changed, 202 insertions(+), 131 deletions(-)

New commits:
commit 49b3e4560f62a9a7db350d94d50e229f5e1208bf
Author: Carlos Garcia Campos <carlosgc at gnome.org>
Date:   Fri Sep 5 18:17:45 2008 +0200

    Movie filename is not a string, but a File Specification
    
    Fixes a crash when filename is a dictionary

diff --git a/poppler/Annot.cc b/poppler/Annot.cc
index e4c394a..158b689 100644
--- a/poppler/Annot.cc
+++ b/poppler/Annot.cc
@@ -54,6 +54,7 @@
 #include "Movie.h"
 #include "OptionalContent.h"
 #include "Sound.h"
+#include "FileSpec.h"
 #include <string.h>
 
 #define annotFlagHidden    0x0002
@@ -3160,9 +3161,10 @@ void AnnotMovie::initialize(XRef *xrefA, Catalog *catalog, Dict* dict) {
   FWPosY = 0.5;
 
   if (dict->lookup("Movie", &movieDict)->isDict()) {
-    if (movieDict.dictLookup("F", &obj1)->isString()) {
-      fileName = obj1.getString()->copy();
-    }
+    Object obj2;
+    getFileSpecNameForPlatform(movieDict.dictLookup("F", &obj1), &obj2);
+    fileName = obj2.getString()->copy();
+    obj2.free();
     obj1.free();
 
     if (movieDict.dictLookup("Aspect", &obj1)->isArray()) {
commit 996d2e176057e22acbc374cff7a712ce6fd92d93
Author: Carlos Garcia Campos <carlosgc at gnome.org>
Date:   Fri Sep 5 18:17:25 2008 +0200

    Unify multiple File Specification parsers

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 63ec8bd..63f28b7 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -143,6 +143,7 @@ set(poppler_SRCS
   poppler/Decrypt.cc
   poppler/Dict.cc
   poppler/Error.cc
+  poppler/FileSpec.cc
   poppler/FontEncodingTables.cc
   poppler/Form.cc
   poppler/FontInfo.cc
@@ -272,6 +273,7 @@ if(ENABLE_XPDF_HEADERS)
     poppler/Decrypt.h
     poppler/Dict.h
     poppler/Error.h
+    poppler/FileSpec.h
     poppler/FontEncodingTables.h
     poppler/FontInfo.h
     poppler/Form.h
diff --git a/poppler/FileSpec.cc b/poppler/FileSpec.cc
new file mode 100644
index 0000000..7ef759e
--- /dev/null
+++ b/poppler/FileSpec.cc
@@ -0,0 +1,146 @@
+//========================================================================
+//
+// FileSpec.cc
+//
+// All changes made under the Poppler project to this file are licensed
+// under GPL version 2 or later
+//
+// Copyright (C) 2008 Carlos Garcia Campos <carlosgc at gnome.org>
+//
+// To see a description of the changes please see the Changelog file that
+// came with your tarball or type make ChangeLog if you are building from git
+//
+//========================================================================
+
+//========================================================================
+//
+// Most of the code from Link.cc and PSOutputDev.cc
+//
+// Copyright 1996-2003 Glyph & Cog, LLC 
+//
+//========================================================================
+
+#include <config.h>
+
+#include "FileSpec.h"
+
+GBool getFileSpecName (Object *fileSpec, Object *fileName)
+{
+  if (fileSpec->isString()) {
+    fileSpec->copy(fileName);
+    return gTrue;
+  }
+  
+  if (fileSpec->isDict()) {
+    fileSpec->dictLookup("DOS", fileName);
+    if (fileName->isString()) {
+      return gTrue;
+    }
+    fileName->free();
+    fileSpec->dictLookup("Mac", fileName);
+    if (fileName->isString()) {
+      return gTrue;
+    }
+    fileName->free();
+    fileSpec->dictLookup("Unix", fileName);
+    if (fileName->isString()) {
+      return gTrue;
+    }
+    fileName->free();
+    fileSpec->dictLookup("F", fileName);
+    if (fileName->isString()) {
+      return gTrue;
+    }
+    fileName->free();
+  }
+  return gFalse;
+}
+
+GBool getFileSpecNameForPlatform (Object *fileSpec, Object *fileName)
+{
+  if (fileSpec->isString()) {
+    fileSpec->copy(fileName);
+    return gTrue;
+  }
+
+  Object obj1;
+  GooString *name;
+
+  name = NULL;
+  
+  if (fileSpec->isDict()) {
+#ifdef WIN32
+    if (!fileSpec->dictLookup("DOS", &obj1)->isString()) {
+#else
+    if (!fileSpec->dictLookup("Unix", &obj1)->isString()) {
+#endif
+      obj1.free();
+      fileSpec->dictLookup("F", &obj1);
+    }
+    
+    if (obj1.isString()) {
+       name = obj1.getString()->copy();
+    } else {
+      error(-1, "Illegal file spec in link");
+    }
+    obj1.free();
+
+  // error
+  } else {
+    error(-1, "Illegal file spec in link");
+  }
+
+  // system-dependent path manipulation
+  if (name) {
+#ifdef WIN32
+    int i, j;
+
+    // "//...."             --> "\...."
+    // "/x/...."            --> "x:\...."
+    // "/server/share/...." --> "\\server\share\...."
+    // convert escaped slashes to slashes and unescaped slashes to backslashes
+    i = 0;
+    if (name->getChar(0) == '/') {
+      if (name->getLength() >= 2 && name->getChar(1) == '/') {
+	name->del(0);
+	i = 0;
+      } else if (name->getLength() >= 2 &&
+		 ((name->getChar(1) >= 'a' && name->getChar(1) <= 'z') ||
+		  (name->getChar(1) >= 'A' && name->getChar(1) <= 'Z')) &&
+		 (name->getLength() == 2 || name->getChar(2) == '/')) {
+	name->setChar(0, name->getChar(1));
+	name->setChar(1, ':');
+	i = 2;
+      } else {
+	for (j = 2; j < name->getLength(); ++j) {
+	  if (name->getChar(j-1) != '\\' &&
+	      name->getChar(j) == '/') {
+	    break;
+	  }
+	}
+	if (j < name->getLength()) {
+	  name->setChar(0, '\\');
+	  name->insert(0, '\\');
+	  i = 2;
+	}
+      }
+    }
+    for (; i < name->getLength(); ++i) {
+      if (name->getChar(i) == '/') {
+	name->setChar(i, '\\');
+      } else if (name->getChar(i) == '\\' &&
+		 i+1 < name->getLength() &&
+		 name->getChar(i+1) == '/') {
+	name->del(i);
+      }
+    }
+#else
+    // no manipulation needed for Unix
+#endif
+  } else {
+    return gFalse;
+  }
+
+  fileName->initString (name);
+  return gTrue;
+}
diff --git a/poppler/FileSpec.h b/poppler/FileSpec.h
new file mode 100644
index 0000000..ec35f3f
--- /dev/null
+++ b/poppler/FileSpec.h
@@ -0,0 +1,24 @@
+//========================================================================
+//
+// FileSpec.h
+//
+// All changes made under the Poppler project to this file are licensed
+// under GPL version 2 or later
+//
+// Copyright (C) 2008 Carlos Garcia Campos <carlosgc at gnome.org>
+//
+// To see a description of the changes please see the Changelog file that
+// came with your tarball or type make ChangeLog if you are building from git
+//
+//========================================================================
+
+#ifndef FILE_SPEC_H
+#define FILE_SPEC_H
+
+#include "goo/gtypes.h"
+#include "Object.h"
+
+GBool getFileSpecName (Object *fileSpec, Object *fileName);
+GBool getFileSpecNameForPlatform (Object *fileSpec, Object *fileName);
+
+#endif /* FILE_SPEC_H */
diff --git a/poppler/Link.cc b/poppler/Link.cc
index 795ad40..61f05b7 100644
--- a/poppler/Link.cc
+++ b/poppler/Link.cc
@@ -40,6 +40,7 @@
 #include "Link.h"
 #include "Sound.h"
 #include "Movie.h"
+#include "FileSpec.h"
 
 //------------------------------------------------------------------------
 // LinkAction
@@ -136,90 +137,6 @@ LinkAction *LinkAction::parseAction(Object *obj, GooString *baseURI) {
   return action;
 }
 
-GooString *LinkAction::getFileSpecName(Object *fileSpecObj) {
-  GooString *name;
-  Object obj1;
-
-  name = NULL;
-
-  // string
-  if (fileSpecObj->isString()) {
-    name = fileSpecObj->getString()->copy();
-
-  // dictionary
-  } else if (fileSpecObj->isDict()) {
-#ifdef WIN32
-    if (!fileSpecObj->dictLookup("DOS", &obj1)->isString()) {
-#else
-    if (!fileSpecObj->dictLookup("Unix", &obj1)->isString()) {
-#endif
-      obj1.free();
-      fileSpecObj->dictLookup("F", &obj1);
-    }
-    if (obj1.isString()) {
-      name = obj1.getString()->copy();
-    } else {
-      error(-1, "Illegal file spec in link");
-    }
-    obj1.free();
-
-  // error
-  } else {
-    error(-1, "Illegal file spec in link");
-  }
-
-  // system-dependent path manipulation
-  if (name) {
-#ifdef WIN32
-    int i, j;
-
-    // "//...."             --> "\...."
-    // "/x/...."            --> "x:\...."
-    // "/server/share/...." --> "\\server\share\...."
-    // convert escaped slashes to slashes and unescaped slashes to backslashes
-    i = 0;
-    if (name->getChar(0) == '/') {
-      if (name->getLength() >= 2 && name->getChar(1) == '/') {
-	name->del(0);
-	i = 0;
-      } else if (name->getLength() >= 2 &&
-		 ((name->getChar(1) >= 'a' && name->getChar(1) <= 'z') ||
-		  (name->getChar(1) >= 'A' && name->getChar(1) <= 'Z')) &&
-		 (name->getLength() == 2 || name->getChar(2) == '/')) {
-	name->setChar(0, name->getChar(1));
-	name->setChar(1, ':');
-	i = 2;
-      } else {
-	for (j = 2; j < name->getLength(); ++j) {
-	  if (name->getChar(j-1) != '\\' &&
-	      name->getChar(j) == '/') {
-	    break;
-	  }
-	}
-	if (j < name->getLength()) {
-	  name->setChar(0, '\\');
-	  name->insert(0, '\\');
-	  i = 2;
-	}
-      }
-    }
-    for (; i < name->getLength(); ++i) {
-      if (name->getChar(i) == '/') {
-	name->setChar(i, '\\');
-      } else if (name->getChar(i) == '\\' &&
-		 i+1 < name->getLength() &&
-		 name->getChar(i+1) == '/') {
-	name->del(i);
-      }
-    }
-#else
-    // no manipulation needed for Unix
-#endif
-  }
-
-  return name;
-}
-
 //------------------------------------------------------------------------
 // LinkDest
 //------------------------------------------------------------------------
@@ -505,7 +422,10 @@ LinkGoToR::LinkGoToR(Object *fileSpecObj, Object *destObj) {
   namedDest = NULL;
 
   // get file name
-  fileName = getFileSpecName(fileSpecObj);
+  Object obj1;
+  getFileSpecNameForPlatform (fileSpecObj, &obj1);
+  fileName = obj1.getString()->copy();
+  obj1.free();
 
   // named destination
   if (destObj->isName()) {
@@ -542,20 +462,24 @@ LinkGoToR::~LinkGoToR() {
 //------------------------------------------------------------------------
 
 LinkLaunch::LinkLaunch(Object *actionObj) {
-  Object obj1, obj2;
+  Object obj1, obj2, obj3;
 
   fileName = NULL;
   params = NULL;
 
   if (actionObj->isDict()) {
     if (!actionObj->dictLookup("F", &obj1)->isNull()) {
-      fileName = getFileSpecName(&obj1);
+      getFileSpecNameForPlatform (&obj1, &obj3);
+      fileName = obj3.getString()->copy();
+      obj3.free();
     } else {
       obj1.free();
 #ifdef WIN32
       if (actionObj->dictLookup("Win", &obj1)->isDict()) {
 	obj1.dictLookup("F", &obj2);
-	fileName = getFileSpecName(&obj2);
+	getFileSpecNameForPlatform (&obj2, &obj3);
+	fileName = obj3.getString()->copy();
+	obj3.free();
 	obj2.free();
 	if (obj1.dictLookup("P", &obj2)->isString()) {
 	  params = obj2.getString()->copy();
@@ -569,7 +493,9 @@ LinkLaunch::LinkLaunch(Object *actionObj) {
       //~ just like the Win dictionary until they say otherwise.
       if (actionObj->dictLookup("Unix", &obj1)->isDict()) {
 	obj1.dictLookup("F", &obj2);
-	fileName = getFileSpecName(&obj2);
+	getFileSpecNameForPlatform (&obj2, &obj3);
+	fileName = obj3.getString()->copy();
+	obj3.free();
 	obj2.free();
 	if (obj1.dictLookup("P", &obj2)->isString()) {
 	  params = obj2.getString()->copy();
diff --git a/poppler/Link.h b/poppler/Link.h
index 12d5231..af42923 100644
--- a/poppler/Link.h
+++ b/poppler/Link.h
@@ -70,10 +70,6 @@ public:
 
   // Parse an action dictionary.
   static LinkAction *parseAction(Object *obj, GooString *baseURI = NULL);
-
-  // Extract a file name from a file specification (string or
-  // dictionary).
-  static GooString *getFileSpecName(Object *fileSpecObj);
 };
 
 //------------------------------------------------------------------------
diff --git a/poppler/Makefile.am b/poppler/Makefile.am
index f19b31e..6d163f7 100644
--- a/poppler/Makefile.am
+++ b/poppler/Makefile.am
@@ -155,6 +155,7 @@ poppler_include_HEADERS =	\
 	Decrypt.h		\
 	Dict.h			\
 	Error.h			\
+	FileSpec.h		\
 	FontEncodingTables.h	\
 	FontInfo.h		\
 	Form.h 			\
@@ -224,6 +225,7 @@ libpoppler_la_SOURCES =		\
 	Decrypt.cc		\
 	Dict.cc 		\
 	Error.cc 		\
+	FileSpec.cc		\
 	FontEncodingTables.cc	\
 	Form.cc 		\
 	FontInfo.cc		\
diff --git a/poppler/PSOutputDev.cc b/poppler/PSOutputDev.cc
index fecc2a3..b80654a 100644
--- a/poppler/PSOutputDev.cc
+++ b/poppler/PSOutputDev.cc
@@ -54,6 +54,7 @@
 #include "Annot.h"
 #include "XRef.h"
 #include "PreScanOutputDev.h"
+#include "FileSpec.h"
 #if HAVE_SPLASH
 #  include "splash/Splash.h"
 #  include "splash/SplashBitmap.h"
@@ -5647,7 +5648,7 @@ void PSOutputDev::opiBegin20(GfxState *state, Dict *dict) {
   writePS("%%Distilled\n");
 
   dict->lookup("F", &obj1);
-  if (getFileSpec(&obj1, &obj2)) {
+  if (getFileSpecName(&obj1, &obj2)) {
     writePSFmt("%%ImageFileName: {0:t}\n", obj2.getString());
     obj2.free();
   }
@@ -5763,7 +5764,7 @@ void PSOutputDev::opiBegin13(GfxState *state, Dict *dict) {
   writePS("opiMatrix setmatrix\n");
 
   dict->lookup("F", &obj1);
-  if (getFileSpec(&obj1, &obj2)) {
+  if (getFileSpecName(&obj1, &obj2)) {
     writePSFmt("%ALDImageFileName: {0:t}\n", obj2.getString());
     obj2.free();
   }
@@ -6014,36 +6015,6 @@ void PSOutputDev::opiEnd(GfxState *state, Dict *opiDict) {
     }
   }
 }
-
-GBool PSOutputDev::getFileSpec(Object *fileSpec, Object *fileName) {
-  if (fileSpec->isString()) {
-    fileSpec->copy(fileName);
-    return gTrue;
-  }
-  if (fileSpec->isDict()) {
-    fileSpec->dictLookup("DOS", fileName);
-    if (fileName->isString()) {
-      return gTrue;
-    }
-    fileName->free();
-    fileSpec->dictLookup("Mac", fileName);
-    if (fileName->isString()) {
-      return gTrue;
-    }
-    fileName->free();
-    fileSpec->dictLookup("Unix", fileName);
-    if (fileName->isString()) {
-      return gTrue;
-    }
-    fileName->free();
-    fileSpec->dictLookup("F", fileName);
-    if (fileName->isString()) {
-      return gTrue;
-    }
-    fileName->free();
-  }
-  return gFalse;
-}
 #endif // OPI_SUPPORT
 
 void PSOutputDev::type3D0(GfxState *state, double wx, double wy) {
diff --git a/poppler/PSOutputDev.h b/poppler/PSOutputDev.h
index 2c6a103..ddc2041 100644
--- a/poppler/PSOutputDev.h
+++ b/poppler/PSOutputDev.h
@@ -319,7 +319,6 @@ private:
   void opiBegin13(GfxState *state, Dict *dict);
   void opiTransform(GfxState *state, double x0, double y0,
 		    double *x1, double *y1);
-  GBool getFileSpec(Object *fileSpec, Object *fileName);
 #endif
   void cvtFunction(Function *func);
   void writePSChar(char c);
diff --git a/poppler/Sound.cc b/poppler/Sound.cc
index 8f8eadd..0dec645 100644
--- a/poppler/Sound.cc
+++ b/poppler/Sound.cc
@@ -20,7 +20,7 @@
 #include "Object.h"
 #include "Sound.h"
 #include "Stream.h"
-#include "Link.h"
+#include "FileSpec.h"
 
 Sound *Sound::parseSound(Object *obj)
 {
@@ -65,9 +65,12 @@ Sound::Sound(Object *obj, bool readAttrs)
     Dict *dict = streamObj->getStream()->getDict();
     dict->lookup("F", &tmp);
     if (!tmp.isNull()) {
+      Object obj1;
       // valid 'F' key -> external file
       kind = soundExternal;
-      fileName = LinkAction::getFileSpecName(&tmp);
+      getFileSpecNameForPlatform (&tmp, &obj1);
+      fileName = obj1.getString()->copy();
+      obj1.free();
     } else {
       // no file specification, then the sound data have to be
       // extracted from the stream


More information about the poppler mailing list