[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