[poppler] poppler/poppler: XpdfPluginAPI.cc, NONE, 1.1 XpdfPluginAPI.h, NONE, 1.1 SecurityHandler.cc, NONE, 1.1 SecurityHandler.h, NONE, 1.1 DCTStream.h, 1.4, 1.5 Decrypt.cc, 1.2, 1.3 Decrypt.h, 1.1.1.1, 1.2 FlateStream.h, 1.1, 1.2 GlobalParams.cc, 1.8, 1.9 GlobalParams.h, 1.3, 1.4 Makefile.am, 1.11, 1.12 PDFDoc.cc, 1.5, 1.6 PDFDoc.h, 1.3, 1.4 Parser.cc, 1.1.1.1, 1.2 Parser.h, 1.1.1.1, 1.2 Stream.cc, 1.4, 1.5 Stream.h, 1.4, 1.5 XRef.cc, 1.4, 1.5 XRef.h, 1.2, 1.3 poppler-config.h.in, 1.2, 1.3

Marco Pesenti Gritti marco at freedesktop.org
Fri Sep 16 11:29:20 PDT 2005


Update of /cvs/poppler/poppler/poppler
In directory gabe:/tmp/cvs-serv4244/poppler

Modified Files:
	DCTStream.h Decrypt.cc Decrypt.h FlateStream.h GlobalParams.cc 
	GlobalParams.h Makefile.am PDFDoc.cc PDFDoc.h Parser.cc 
	Parser.h Stream.cc Stream.h XRef.cc XRef.h poppler-config.h.in 
Added Files:
	XpdfPluginAPI.cc XpdfPluginAPI.h SecurityHandler.cc 
	SecurityHandler.h 
Log Message:
2005-09-16  Marco Pesenti Gritti  <mpg at redhat.com>

        * goo/Makefile.am:
        * poppler/DCTStream.h:
        * poppler/Decrypt.cc:
        * poppler/Decrypt.h:
        * poppler/FlateStream.h:
        * poppler/GlobalParams.cc:
        * poppler/GlobalParams.h:
        * poppler/Makefile.am:
        * poppler/PDFDoc.cc:
        * poppler/PDFDoc.h:
        * poppler/Parser.cc:
        * poppler/Parser.h:
        * poppler/Stream.cc:
        * poppler/Stream.h:
        * poppler/XRef.cc:
        * poppler/XRef.h:
        * poppler/poppler-config.h.in:

        Merge security plugins support from xpdf 3.01



--- NEW FILE: XpdfPluginAPI.cc ---
//========================================================================
//
// XpdfPluginAPI.cc
//
// Copyright 2004 Glyph & Cog, LLC
//
//========================================================================

#include "aconf.h"

#ifdef ENABLE_PLUGINS

#include "gmem.h"
#include "GlobalParams.h"
#include "Object.h"
#include "PDFDoc.h"
#ifdef WIN32
#include "WinPDFCore.h"
#else
#include "XPDFCore.h"
#endif
#include "XpdfPluginAPI.h"

//------------------------------------------------------------------------

//~ This should use a pool of Objects; change xpdfFreeObj to match.
static Object *allocObj() {
  return (Object *)gmalloc(sizeof(Object));
}

//------------------------------------------------------------------------
// Document access functions
//------------------------------------------------------------------------

XpdfObject _xpdfGetInfoDict(XpdfDoc doc) {
  Object *obj;

  obj = allocObj();
  return (XpdfObject)((PDFDoc *)doc)->getDocInfo(obj);
}

XpdfObject _xpdfGetCatalog(XpdfDoc doc) {
  Object *obj;

  obj = allocObj();
  return (XpdfObject)((PDFDoc *)doc)->getXRef()->getCatalog(obj);
}

#ifdef _WIN32

HWND _xpdfWin32GetWindow(XpdfDoc doc) {
  WinPDFCore *core;

  if (!(core = (WinPDFCore *)((PDFDoc *)doc)->getGUIData())) {
    return NULL;
  }
  return core->getDrawFrame();
}

#else

Widget _xpdfXGetWindow(XpdfDoc doc) {
  XPDFCore *core;

  if (!(core = (XPDFCore *)((PDFDoc *)doc)->getGUIData())) {
    return NULL;
  }
  return core->getWidget();
}

#endif

//------------------------------------------------------------------------
// Object access functions.
//------------------------------------------------------------------------

XpdfBool _xpdfObjIsBool(XpdfObject obj) {
  return (XpdfBool)((Object *)obj)->isBool();
}

XpdfBool _xpdfObjIsInt(XpdfObject obj) {
  return (XpdfBool)((Object *)obj)->isInt();
}

XpdfBool _xpdfObjIsReal(XpdfObject obj) {
  return (XpdfBool)((Object *)obj)->isReal();
}

XpdfBool _xpdfObjIsNumber(XpdfObject obj) {
  return (XpdfBool)((Object *)obj)->isNum();
}

XpdfBool _xpdfObjIsString(XpdfObject obj) {
  return (XpdfBool)((Object *)obj)->isString();
}

XpdfBool _xpdfObjIsName(XpdfObject obj) {
  return (XpdfBool)((Object *)obj)->isName();
}

XpdfBool _xpdfObjIsNull(XpdfObject obj) {
  return (XpdfBool)((Object *)obj)->isNull();
}

XpdfBool _xpdfObjIsArray(XpdfObject obj) {
  return (XpdfBool)((Object *)obj)->isArray();
}

XpdfBool _xpdfObjIsDict(XpdfObject obj) {
  return (XpdfBool)((Object *)obj)->isDict();
}

XpdfBool _xpdfObjIsStream(XpdfObject obj) {
  return (XpdfBool)((Object *)obj)->isStream();
}

XpdfBool _xpdfObjIsRef(XpdfObject obj) {
  return (XpdfBool)((Object *)obj)->isRef();
}

XpdfBool _xpdfBoolValue(XpdfObject obj) {
  return (XpdfBool)((Object *)obj)->getBool();
}

int _xpdfIntValue(XpdfObject obj) {
  if (!((Object *)obj)->isInt()) {
    return 0;
  }
  return ((Object *)obj)->getInt();
}

double _xpdfRealValue(XpdfObject obj) {
  if (!((Object *)obj)->isReal()) {
    return 0;
  }
  return ((Object *)obj)->getReal();
}

double _xpdfNumberValue(XpdfObject obj) {
  if (!((Object *)obj)->isNum()) {
    return 0;
  }
  return ((Object *)obj)->getNum();
}

int _xpdfStringLength(XpdfObject obj) {
  if (!((Object *)obj)->isString()) {
    return 0;
  }
  return ((Object *)obj)->getString()->getLength();
}

char *_xpdfStringValue(XpdfObject obj) {
  if (!((Object *)obj)->isString()) {
    return 0;
  }
  return ((Object *)obj)->getString()->getCString();
}

char *_xpdfNameValue(XpdfObject obj) {
  if (!((Object *)obj)->isName()) {
    return NULL;
  }
  return ((Object *)obj)->getName();
}

int _xpdfArrayLength(XpdfObject obj) {
  if (!((Object *)obj)->isArray()) {
    return 0;
  }
  return ((Object *)obj)->arrayGetLength();
}

XpdfObject _xpdfArrayGet(XpdfObject obj, int idx) {
  Object *elem;

  elem = allocObj();
  if (!((Object *)obj)->isArray()) {
    return (XpdfObject)elem->initNull();
  }
  return (XpdfObject)((Object *)obj)->arrayGet(idx, elem);
}

XpdfObject _xpdfDictGet(XpdfObject obj, char *key) {
  Object *elem;

  elem = allocObj();
  if (!((Object *)obj)->isDict()) {
    return (XpdfObject)elem->initNull();
  }
  return (XpdfObject)((Object *)obj)->dictLookup(key, elem);
}

void _xpdfFreeObj(XpdfObject obj) {
  ((Object *)obj)->free();
  gfree(obj);
}

//------------------------------------------------------------------------
// Memory allocation functions
//------------------------------------------------------------------------

void *_xpdfMalloc(int size) {
  return gmalloc(size);
}

void *_xpdfRealloc(void *p, int size) {
  return grealloc(p, size);
}

void _xpdfFree(void *p) {
  gfree(p);
}

//------------------------------------------------------------------------
// Security handlers
//------------------------------------------------------------------------

void _xpdfRegisterSecurityHandler(XpdfSecurityHandler *handler) {
  if (handler->version <= xpdfPluginAPIVersion) {
    globalParams->addSecurityHandler(handler);
  }
}

//------------------------------------------------------------------------

XpdfPluginVecTable xpdfPluginVecTable = {
  xpdfPluginAPIVersion,
  &_xpdfGetInfoDict,
  &_xpdfGetCatalog,
#ifdef _WIN32
  &_xpdfWin32GetWindow,
#else
  &_xpdfXGetWindow,
#endif
  &_xpdfObjIsBool,
  &_xpdfObjIsInt,
  &_xpdfObjIsReal,
  &_xpdfObjIsString,
  &_xpdfObjIsName,
  &_xpdfObjIsNull,
  &_xpdfObjIsArray,
  &_xpdfObjIsDict,
  &_xpdfObjIsStream,
  &_xpdfObjIsRef,
  &_xpdfBoolValue,
  &_xpdfIntValue,
  &_xpdfRealValue,
  &_xpdfStringLength,
  &_xpdfStringValue,
  &_xpdfNameValue,
  &_xpdfArrayLength,
  &_xpdfArrayGet,
  &_xpdfDictGet,
  &_xpdfFreeObj,
  &_xpdfMalloc,
  &_xpdfRealloc,
  &_xpdfFree,
  &_xpdfRegisterSecurityHandler,
};

#endif // ENABLE_PLUGINS

--- NEW FILE: XpdfPluginAPI.h ---
/*
 * XpdfPluginAPI.h
 *
 * Copyright 2004 Glyph & Cog, LLC
 */

#ifndef XPDFPLUGINAPI_H
#define XPDFPLUGINAPI_H

#ifdef _WIN32
#include <windows.h>
#else
#define Object XtObject
#include <X11/Intrinsic.h>
#undef Object
#endif

#ifdef __cplusplus
extern "C" {
#endif

/*------------------------------------------------------------------------
 * Macros
 *------------------------------------------------------------------------*/

/*
 * The current API version.
 */
#define xpdfPluginAPIVersion 1

#ifdef _WIN32
#  ifdef __cplusplus
#    define PLUGINFUNC(retType) extern "C" __declspec(dllexport) retType
#  else
#    define PLUGINFUNC(retType) extern __declspec(dllexport) retType
#  endif
#else
#  ifdef __cplusplus
#    define PLUGINFUNC(retType) extern "C" retType
#  else
#    define PLUGINFUNC(retType) extern retType
#  endif
#endif

/*------------------------------------------------------------------------
 * Plugin setup/cleanup
 *------------------------------------------------------------------------*/

/*
 * All plugins are required to implement two functions:
 *
 * -- Initialize the plugin.  Returns non-zero if successful.
 * PLUGINFUNC(XpdfBool) xpdfInitPlugin(void);
 *
 * -- Free the plugin.
 * PLUGINFUNC(void) xpdfFreePlugin(void);
 */

/*------------------------------------------------------------------------
 * Types
 *------------------------------------------------------------------------*/

/*
 * Standard C boolean -- zero = false, non-zero = true.
 */
typedef int XpdfBool;
#define xpdfTrue  1
#define xpdfFalse 0

/*
 * PDF document handle.
 */
typedef struct _XpdfDoc *XpdfDoc;

/*
 * PDF object handle.
 */
typedef struct _XpdfObject *XpdfObject;

/*
 * Document access permissions.  Any of these can be bitwise 'or'ed
 * together.  If xpdfPermissionOpen is not included, the document
 * cannot be opened at all, and the other bits are ignored.
 */
typedef unsigned int XpdfPermission;
#define xpdfPermissionOpen     (1 << 0)
#define xpdfPermissionPrint    (1 << 2)
#define xpdfPermissionChange   (1 << 3)
#define xpdfPermissionCopy     (1 << 4)
#define xpdfPermissionNotes    (1 << 5)

/*------------------------------------------------------------------------
 * Security handler
 *------------------------------------------------------------------------*/

/*
 * XpdfSecurityHandler - a security handler plugin should create one
 * of these and pass it to xpdfRegisterSecurityHandler.
 */
#ifdef __cplusplus
struct XpdfSecurityHandler {
#else
typedef struct {
#endif

  /*
   * Version of the security handler spec (this document) -- use
   * xpdfPluginAPIVersion.
   */
  int version;

  /*
   * Security handler name.
   */
  char *name;

  /*
   * Any global data the security handler needs.  XpdfViewer will pass
   * this pointer to all handler functions as the <handlerData>
   * argument.
   */
  void *handlerData;

  /*
   * Allocate and initialize data for a new document.  XpdfViewer will
   * pass the returned pointer to all other handler functions as the
   * <docData> argument.  Returns non-zero if successful.
   */
  XpdfBool (*newDoc)(void *handlerData, XpdfDoc doc,
		     XpdfObject encryptDict, void **docData);

  /*
   * Free the data allocated by newDoc.
   */
  void (*freeDoc)(void *handlerData, void *docData);

  /*
   * Construct authorization data based on the supplied owner and user
   * passwords (either or both of which may be NULL).  This function
   * is called in "batch" mode, i.e., if the password was supplied on
   * the command line or via an Xpdf library API.  It should not
   * generate any user interaction (e.g., a password dialog).  It is
   * not required to support this function: the makeAuthData function
   * pointer can be set to NULL.  Returns non-zero if successful.
   */
  XpdfBool (*makeAuthData)(void *handlerData, void *docData,
			   char *ownerPassword, char *userPassword,
			   void **authData);

  /*
   * Request any needed information (e.g., a password) from the user,
   * and construct an authorization data object.  Returns non-zero if
   * successful.
   */
  XpdfBool (*getAuthData)(void *handlerData, void *docData,
			  void **authData);

  /*
   * Free the data allocated by getAuthData.
   */
  void (*freeAuthData)(void *handlerData, void *docData,
		       void *authData);

  /*
   * Request permission to access the document.  This returns all
   * permissions granted by authData.
   */
  XpdfPermission (*authorize)(void *handlerData, void *docData,
			      void *authData);

  /*
   * Get the decryption key and algorithm version associated with the
   * document.  Returns non-zero if successful.
   */
  XpdfBool (*getKey)(void *handlerData, void *docData,
		     char **key, int *keyLen, int *cryptVersion);

  /*
   * Free the data allocated by getKey.
   */
  void (*freeKey)(void *handlerData, void *docData,
		  char *key, int keyLen);

#ifdef __cplusplus
};
#else
} XpdfSecurityHandler;
#endif

/*------------------------------------------------------------------------*/

typedef struct {
  int version;

/*------------------------------------------------------------------------
 * Document access functions
 *------------------------------------------------------------------------*/

/*
 * Get a document's info dictionary.  (The returned object must be
 * freed with xpdfFreeObj.)
 */
XpdfObject (*_xpdfGetInfoDict)(XpdfDoc doc);

/*
 * Get a document's catalog ("root") dictionary.  (The returned object
 * must be freed with xpdfFreeObj.)
 */
XpdfObject (*_xpdfGetCatalog)(XpdfDoc doc);

#ifdef _WIN32

/*
 * Get the handle for the viewer window associated with the specified
 * document.  [Win32 only]
 */
HWND (*_xpdfWin32GetWindow)(XpdfDoc doc);

#else

/*
 * Get the Motif widget for the viewer window associated with the
 * specified document.  [X only]
 */
Widget (*_xpdfXGetWindow)(XpdfDoc doc);

#endif

/*------------------------------------------------------------------------
 * Object access functions
 *------------------------------------------------------------------------*/

/*
 * Check an object's type.
 */
XpdfBool (*_xpdfObjIsBool)(XpdfObject obj);
XpdfBool (*_xpdfObjIsInt)(XpdfObject obj);
XpdfBool (*_xpdfObjIsReal)(XpdfObject obj);
XpdfBool (*_xpdfObjIsString)(XpdfObject obj);
XpdfBool (*_xpdfObjIsName)(XpdfObject obj);
XpdfBool (*_xpdfObjIsNull)(XpdfObject obj);
XpdfBool (*_xpdfObjIsArray)(XpdfObject obj);
XpdfBool (*_xpdfObjIsDict)(XpdfObject obj);
XpdfBool (*_xpdfObjIsStream)(XpdfObject obj);
XpdfBool (*_xpdfObjIsRef)(XpdfObject obj);

/*
 * Value access.
 * (Objects returned by xpdfArrayGet and xpdfDictGet must be freed
 * with xpdfFreeObj.)
 */
XpdfBool (*_xpdfBoolValue)(XpdfObject obj);
int (*_xpdfIntValue)(XpdfObject obj);
double (*_xpdfRealValue)(XpdfObject obj);
int (*_xpdfStringLength)(XpdfObject obj);
char *(*_xpdfStringValue)(XpdfObject obj);
char *(*_xpdfNameValue)(XpdfObject obj);
int (*_xpdfArrayLength)(XpdfObject obj);
XpdfObject (*_xpdfArrayGet)(XpdfObject obj, int idx);
XpdfObject (*_xpdfDictGet)(XpdfObject obj, char *key);

/*
 * Object destruction.  NB: *all* objects must be freed after use.
 */
void (*_xpdfFreeObj)(XpdfObject obj);

/*------------------------------------------------------------------------
 * Memory allocation functions
 *------------------------------------------------------------------------*/

void *(*_xpdfMalloc)(int size);
void *(*_xpdfRealloc)(void *p, int size);
void (*_xpdfFree)(void *p);

/*------------------------------------------------------------------------
 * Security handler functions
 *------------------------------------------------------------------------*/

/*
 * Register a new security handler.
 */
void (*_xpdfRegisterSecurityHandler)(XpdfSecurityHandler *handler);

/*------------------------------------------------------------------------*/

} XpdfPluginVecTable;

#ifdef _WIN32

extern __declspec(dllexport) XpdfPluginVecTable xpdfPluginVecTable;

#define xpdfPluginSetup \
  extern __declspec(dllexport) \
  XpdfPluginVecTable xpdfPluginVecTable = {xpdfPluginAPIVersion};

#else

extern XpdfPluginVecTable xpdfPluginVecTable;

#define xpdfPluginSetup \
  XpdfPluginVecTable xpdfPluginVecTable = {xpdfPluginAPIVersion};

#endif

#define xpdfGetInfoDict (*xpdfPluginVecTable._xpdfGetInfoDict)
#define xpdfGetCatalog (*xpdfPluginVecTable._xpdfGetCatalog)
#ifdef _WIN32
#define xpdfWin32GetWindow (*xpdfPluginVecTable._xpdfWin32GetWindow)
#else
#define xpdfXGetWindow (*xpdfPluginVecTable._xpdfXGetWindow)
#endif
#define xpdfObjIsBool (*xpdfPluginVecTable._xpdfObjIsBool)
#define xpdfObjIsInt (*xpdfPluginVecTable._xpdfObjIsInt)
#define xpdfObjIsReal (*xpdfPluginVecTable._xpdfObjIsReal)
#define xpdfObjIsString (*xpdfPluginVecTable._xpdfObjIsString)
#define xpdfObjIsName (*xpdfPluginVecTable._xpdfObjIsName)
#define xpdfObjIsNull (*xpdfPluginVecTable._xpdfObjIsNull)
#define xpdfObjIsArray (*xpdfPluginVecTable._xpdfObjIsArray)
#define xpdfObjIsDict (*xpdfPluginVecTable._xpdfObjIsDict)
#define xpdfObjIsStream (*xpdfPluginVecTable._xpdfObjIsStream)
#define xpdfObjIsRef (*xpdfPluginVecTable._xpdfObjIsRef)
#define xpdfBoolValue (*xpdfPluginVecTable._xpdfBoolValue)
#define xpdfIntValue (*xpdfPluginVecTable._xpdfIntValue)
#define xpdfRealValue (*xpdfPluginVecTable._xpdfRealValue)
#define xpdfStringLength (*xpdfPluginVecTable._xpdfStringLength)
#define xpdfStringValue (*xpdfPluginVecTable._xpdfStringValue)
#define xpdfNameValue (*xpdfPluginVecTable._xpdfNameValue)
#define xpdfArrayLength (*xpdfPluginVecTable._xpdfArrayLength)
#define xpdfArrayGet (*xpdfPluginVecTable._xpdfArrayGet)
#define xpdfDictGet (*xpdfPluginVecTable._xpdfDictGet)
#define xpdfFreeObj (*xpdfPluginVecTable._xpdfFreeObj)
#define xpdfMalloc (*xpdfPluginVecTable._xpdfMalloc)
#define xpdfRealloc (*xpdfPluginVecTable._xpdfRealloc)
#define xpdfFree (*xpdfPluginVecTable._xpdfFree)
#define xpdfRegisterSecurityHandler (*xpdfPluginVecTable._xpdfRegisterSecurityHandler)

#ifdef __cplusplus
}
#endif

#endif

--- NEW FILE: SecurityHandler.cc ---
//========================================================================
//
// SecurityHandler.cc
//
// Copyright 2004 Glyph & Cog, LLC
//
//========================================================================

#include <config.h>

#ifdef USE_GCC_PRAGMAS
#pragma implementation
#endif

#include "GooString.h"
#include "PDFDoc.h"
#include "Decrypt.h"
#include "Error.h"
#include "GlobalParams.h"
#if HAVE_XPDFCORE
#  include "XPDFCore.h"
#elif HAVE_WINPDFCORE
#  include "WinPDFCore.h"
#endif
#ifdef ENABLE_PLUGINS
#  include "XpdfPluginAPI.h"
#endif
#include "SecurityHandler.h"

//------------------------------------------------------------------------
// SecurityHandler
//------------------------------------------------------------------------

SecurityHandler *SecurityHandler::make(PDFDoc *docA, Object *encryptDictA) {
  Object filterObj;
  SecurityHandler *secHdlr;
  XpdfSecurityHandler *xsh;

  encryptDictA->dictLookup("Filter", &filterObj);
  if (filterObj.isName("Standard")) {
    secHdlr = new StandardSecurityHandler(docA, encryptDictA);
  } else if (filterObj.isName()) {
#ifdef ENABLE_PLUGINS
    if ((xsh = globalParams->getSecurityHandler(filterObj.getName()))) {
      secHdlr = new ExternalSecurityHandler(docA, encryptDictA, xsh);
    } else {
#endif
      error(-1, "Couldn't find the '%s' security handler",
	    filterObj.getName());
      secHdlr = NULL;
#ifdef ENABLE_PLUGINS
    }
#endif
  } else {
    error(-1, "Missing or invalid 'Filter' entry in encryption dictionary");
    secHdlr = NULL;
  }
  filterObj.free();
  return secHdlr;
}

SecurityHandler::SecurityHandler(PDFDoc *docA) {
  doc = docA;
}

SecurityHandler::~SecurityHandler() {
}

GBool SecurityHandler::checkEncryption(GooString *ownerPassword,
				       GooString *userPassword) {
  void *authData;
  GBool ok;
  int i;

  if (ownerPassword || userPassword) {
    authData = makeAuthData(ownerPassword, userPassword);
  } else {
    authData = NULL;
  }
  ok = authorize(authData);
  if (authData) {
    freeAuthData(authData);
  }
  for (i = 0; !ok && i < 3; ++i) {
    if (!(authData = getAuthData())) {
      break;
    }
    ok = authorize(authData);
    if (authData) {
      freeAuthData(authData);
    }
  }
  if (!ok) {
    error(-1, "Incorrect password");
  }
  return ok;
}

//------------------------------------------------------------------------
// StandardSecurityHandler
//------------------------------------------------------------------------

class StandardAuthData {
public:

  StandardAuthData(GooString *ownerPasswordA, GooString *userPasswordA) {
    ownerPassword = ownerPasswordA;
    userPassword = userPasswordA;
  }

  ~StandardAuthData() {
    if (ownerPassword) {
      delete ownerPassword;
    }
    if (userPassword) {
      delete userPassword;
    }
  }

  GooString *ownerPassword;
  GooString *userPassword;
};

StandardSecurityHandler::StandardSecurityHandler(PDFDoc *docA,
						 Object *encryptDictA):
  SecurityHandler(docA)
{
  Object versionObj, revisionObj, lengthObj;
  Object ownerKeyObj, userKeyObj, permObj, fileIDObj;
  Object fileIDObj1;
  Object cryptFiltersObj, streamFilterObj, stringFilterObj;
  Object cryptFilterObj, cfmObj, cfLengthObj;
  Object encryptMetadataObj;

  ok = gFalse;
  fileID = NULL;
  ownerKey = NULL;
  userKey = NULL;

  encryptDictA->dictLookup("V", &versionObj);
  encryptDictA->dictLookup("R", &revisionObj);
  encryptDictA->dictLookup("Length", &lengthObj);
  encryptDictA->dictLookup("O", &ownerKeyObj);
  encryptDictA->dictLookup("U", &userKeyObj);
  encryptDictA->dictLookup("P", &permObj);
  doc->getXRef()->getTrailerDict()->dictLookup("ID", &fileIDObj);
  if (versionObj.isInt() &&
      revisionObj.isInt() &&
      ownerKeyObj.isString() && ownerKeyObj.getString()->getLength() == 32 &&
      userKeyObj.isString() && userKeyObj.getString()->getLength() == 32 &&
      permObj.isInt()) {
    encVersion = versionObj.getInt();
    encRevision = revisionObj.getInt();
    // revision 2 forces a 40-bit key - some buggy PDF generators
    // set the Length value incorrectly
    if (encRevision == 2 || !lengthObj.isInt()) {
      fileKeyLength = 5;
    } else {
      fileKeyLength = lengthObj.getInt() / 8;
    }
    encryptMetadata = gTrue;
    //~ this currently only handles a subset of crypt filter functionality
    if (encVersion == 4 && encRevision == 4) {
      encryptDictA->dictLookup("CF", &cryptFiltersObj);
      encryptDictA->dictLookup("StmF", &streamFilterObj);
      encryptDictA->dictLookup("StrF", &stringFilterObj);
      if (cryptFiltersObj.isDict() &&
	  streamFilterObj.isName() &&
	  stringFilterObj.isName() &&
	  !strcmp(streamFilterObj.getName(), stringFilterObj.getName())) {
	if (cryptFiltersObj.dictLookup(streamFilterObj.getName(),
				       &cryptFilterObj)->isDict()) {
	  if (cryptFilterObj.dictLookup("CFM", &cfmObj)->isName("V2")) {
	    encVersion = 2;
	    encRevision = 3;
	    if (cryptFilterObj.dictLookup("Length", &cfLengthObj)->isInt()) {
	      //~ according to the spec, this should be cfLengthObj / 8
	      fileKeyLength = cfLengthObj.getInt();
	    }
	    cfLengthObj.free();
	  }
	  cfmObj.free();
	}
	cryptFilterObj.free();
      }
      stringFilterObj.free();
      streamFilterObj.free();
      cryptFiltersObj.free();
      if (encryptDictA->dictLookup("EncryptMetadata",
				   &encryptMetadataObj)->isBool()) {
	encryptMetadata = encryptMetadataObj.getBool();
      }
      encryptMetadataObj.free();
    }
    permFlags = permObj.getInt();
    ownerKey = ownerKeyObj.getString()->copy();
    userKey = userKeyObj.getString()->copy();
    if (encVersion >= 1 && encVersion <= 2 &&
	encRevision >= 2 && encRevision <= 3) {
      if (fileIDObj.isArray()) {
	if (fileIDObj.arrayGet(0, &fileIDObj1)->isString()) {
	  fileID = fileIDObj1.getString()->copy();
	} else {
	  fileID = new GooString();
	}
	fileIDObj1.free();
      } else {
	fileID = new GooString();
      }
      ok = gTrue;
    } else {
      error(-1, "Unsupported version/revision (%d/%d) of Standard security handler",
	    encVersion, encRevision);
    }
  } else {
    error(-1, "Weird encryption info");
  }
  if (fileKeyLength > 16) {
    fileKeyLength = 16;
  }
  fileIDObj.free();
  permObj.free();
  userKeyObj.free();
  ownerKeyObj.free();
  lengthObj.free();
  revisionObj.free();
  versionObj.free();
}

StandardSecurityHandler::~StandardSecurityHandler() {
  if (fileID) {
    delete fileID;
  }
  if (ownerKey) {
    delete ownerKey;
  }
  if (userKey) {
    delete userKey;
  }
}

void *StandardSecurityHandler::makeAuthData(GooString *ownerPassword,
					    GooString *userPassword) {
  return new StandardAuthData(ownerPassword ? ownerPassword->copy()
			                    : (GooString *)NULL,
			      userPassword ? userPassword->copy()
			                   : (GooString *)NULL);
}

void *StandardSecurityHandler::getAuthData() {
#if HAVE_XPDFCORE
  XPDFCore *core;
  GooString *password;

  if (!(core = (XPDFCore *)doc->getGUIData()) ||
      !(password = core->getPassword())) {
    return NULL;
  }
  return new StandardAuthData(password, password->copy());
#elif HAVE_WINPDFCORE
  WinPDFCore *core;
  GooString *password;

  if (!(core = (WinPDFCore *)doc->getGUIData()) ||
      !(password = core->getPassword())) {
    return NULL;
  }
  return new StandardAuthData(password, password->copy());
#else
  return NULL;
#endif
}

void StandardSecurityHandler::freeAuthData(void *authData) {
  delete (StandardAuthData *)authData;
}

GBool StandardSecurityHandler::authorize(void *authData) {
  GooString *ownerPassword, *userPassword;

  if (!ok) {
    return gFalse;
  }
  if (authData) {
    ownerPassword = ((StandardAuthData *)authData)->ownerPassword;
    userPassword = ((StandardAuthData *)authData)->userPassword;
  } else {
    ownerPassword = NULL;
    userPassword = NULL;
  }
  if (!Decrypt::makeFileKey(encVersion, encRevision, fileKeyLength,
			    ownerKey, userKey, permFlags, fileID,
			    ownerPassword, userPassword, fileKey,
			    encryptMetadata, &ownerPasswordOk)) {
    return gFalse;
  }
  return gTrue;
}

#ifdef ENABLE_PLUGINS

//------------------------------------------------------------------------
// ExternalSecurityHandler
//------------------------------------------------------------------------

ExternalSecurityHandler::ExternalSecurityHandler(PDFDoc *docA,
						 Object *encryptDictA,
						 XpdfSecurityHandler *xshA):
  SecurityHandler(docA)
{
  encryptDictA->copy(&encryptDict);
  xsh = xshA;
  ok = gFalse;

  if (!(*xsh->newDoc)(xsh->handlerData, (XpdfDoc)docA,
		      (XpdfObject)encryptDictA, &docData)) {
    return;
  }

  ok = gTrue;
}

ExternalSecurityHandler::~ExternalSecurityHandler() {
  (*xsh->freeDoc)(xsh->handlerData, docData);
  encryptDict.free();
}

void *ExternalSecurityHandler::makeAuthData(GooString *ownerPassword,
					    GooString *userPassword) {
  char *opw, *upw;
  void *authData;

  opw = ownerPassword ? ownerPassword->getCString() : (char *)NULL;
  upw = userPassword ? userPassword->getCString() : (char *)NULL;
  if (!(*xsh->makeAuthData)(xsh->handlerData, docData, opw, upw, &authData)) {
    return NULL;
  }
  return authData;
}

void *ExternalSecurityHandler::getAuthData() {
  void *authData;

  if (!(*xsh->getAuthData)(xsh->handlerData, docData, &authData)) {
    return NULL;
  }
  return authData;
}

void ExternalSecurityHandler::freeAuthData(void *authData) {
  (*xsh->freeAuthData)(xsh->handlerData, docData, authData);
}

GBool ExternalSecurityHandler::authorize(void *authData) {
  char *key;
  int length;

  if (!ok) {
    return gFalse;
  }
  permFlags = (*xsh->authorize)(xsh->handlerData, docData, authData);
  if (!(permFlags & xpdfPermissionOpen)) {
    return gFalse;
  }
  if (!(*xsh->getKey)(xsh->handlerData, docData, &key, &length, &encVersion)) {
    return gFalse;
  }
  if ((fileKeyLength = length) > 16) {
    fileKeyLength = 16;
  }
  memcpy(fileKey, key, fileKeyLength);
  (*xsh->freeKey)(xsh->handlerData, docData, key, length);
  return gTrue;
}

#endif // ENABLE_PLUGINS

--- NEW FILE: SecurityHandler.h ---
//========================================================================
//
// SecurityHandler.h
//
// Copyright 2004 Glyph & Cog, LLC
//
//========================================================================

#ifndef SECURITYHANDLER_H
#define SECURITYHANDLER_H

#include <config.h>

#ifdef USE_GCC_PRAGMAS
#pragma interface
#endif

#include "gtypes.h"
#include "Object.h"

class GooString;
class PDFDoc;
struct XpdfSecurityHandler;

//------------------------------------------------------------------------
// SecurityHandler
//------------------------------------------------------------------------

class SecurityHandler {
public:

  static SecurityHandler *make(PDFDoc *docA, Object *encryptDictA);

  SecurityHandler(PDFDoc *docA);
  virtual ~SecurityHandler();

  // Check the document's encryption.  If the document is encrypted,
  // this will first try <ownerPassword> and <userPassword> (in
  // "batch" mode), and if those fail, it will attempt to request a
  // password from the user.  This is the high-level function that
  // calls the lower level functions for the specific security handler
  // (requesting a password three times, etc.).  Returns true if the
  // document can be opened (if it's unencrypted, or if a correct
  // password is obtained); false otherwise (encrypted and no correct
  // password).
  GBool checkEncryption(GooString *ownerPassword,
			GooString *userPassword);

  // Create authorization data for the specified owner and user
  // passwords.  If the security handler doesn't support "batch" mode,
  // this function should return NULL.
  virtual void *makeAuthData(GooString *ownerPassword,
			     GooString *userPassword) = 0;

  // Construct authorization data, typically by prompting the user for
  // a password.  Returns an authorization data object, or NULL to
  // cancel.
  virtual void *getAuthData() = 0;

  // Free the authorization data returned by makeAuthData or
  // getAuthData.
  virtual void freeAuthData(void *authData) = 0;

  // Attempt to authorize the document, using the supplied
  // authorization data (which may be NULL).  Returns true if
  // successful (i.e., if at least the right to open the document was
  // granted).
  virtual GBool authorize(void *authData) = 0;

  // Return the various authorization parameters.  These are only
  // valid after authorize has returned true.
  virtual int getPermissionFlags() = 0;
  virtual GBool getOwnerPasswordOk() = 0;
  virtual Guchar *getFileKey() = 0;
  virtual int getFileKeyLength() = 0;
  virtual int getEncVersion() = 0;
  virtual int getEncRevision() = 0;

protected:

  PDFDoc *doc;
};

//------------------------------------------------------------------------
// StandardSecurityHandler
//------------------------------------------------------------------------

class StandardSecurityHandler: public SecurityHandler {
public:

  StandardSecurityHandler(PDFDoc *docA, Object *encryptDictA);
  virtual ~StandardSecurityHandler();

  virtual void *makeAuthData(GooString *ownerPassword,
			     GooString *userPassword);
  virtual void *getAuthData();
  virtual void freeAuthData(void *authData);
  virtual GBool authorize(void *authData);
  virtual int getPermissionFlags() { return permFlags; }
  virtual GBool getOwnerPasswordOk() { return ownerPasswordOk; }
  virtual Guchar *getFileKey() { return fileKey; }
  virtual int getFileKeyLength() { return fileKeyLength; }
  virtual int getEncVersion() { return encVersion; }
  virtual int getEncRevision() { return encRevision; }

private:

  int permFlags;
  GBool ownerPasswordOk;
  Guchar fileKey[16];
  int fileKeyLength;
  int encVersion;
  int encRevision;
  GBool encryptMetadata;

  GooString *ownerKey, *userKey;
  GooString *fileID;
  GBool ok;
};

#ifdef ENABLE_PLUGINS
//------------------------------------------------------------------------
// ExternalSecurityHandler
//------------------------------------------------------------------------

class ExternalSecurityHandler: public SecurityHandler {
public:

  ExternalSecurityHandler(PDFDoc *docA, Object *encryptDictA,
			  XpdfSecurityHandler *xshA);
  virtual ~ExternalSecurityHandler();

  virtual void *makeAuthData(GooString *ownerPassword,
			     GooString *userPassword);
  virtual void *getAuthData();
  virtual void freeAuthData(void *authData);
  virtual GBool authorize(void *authData);
  virtual int getPermissionFlags() { return permFlags; }
  virtual GBool getOwnerPasswordOk() { return gFalse; }
  virtual Guchar *getFileKey() { return fileKey; }
  virtual int getFileKeyLength() { return fileKeyLength; }
  virtual int getEncVersion() { return encVersion; }

private:

  Object encryptDict;
  XpdfSecurityHandler *xsh;
  void *docData;
  int permFlags;
  Guchar fileKey[16];
  int fileKeyLength;
  int encVersion;
  GBool ok;
};
#endif // ENABLE_PLUGINS

#endif

Index: DCTStream.h
===================================================================
RCS file: /cvs/poppler/poppler/poppler/DCTStream.h,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- DCTStream.h	1 Aug 2005 19:15:40 -0000	1.4
+++ DCTStream.h	16 Sep 2005 18:29:18 -0000	1.5
@@ -32,9 +32,7 @@
 #include "poppler-config.h"
 #include "Error.h"
 #include "Object.h"
-#ifndef NO_DECRYPTION
 #include "Decrypt.h"
-#endif
 #include "Stream.h"
 
 extern "C" {

Index: Decrypt.cc
===================================================================
RCS file: /cvs/poppler/poppler/poppler/Decrypt.cc,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- Decrypt.cc	28 Aug 2005 09:43:18 -0000	1.2
+++ Decrypt.cc	16 Sep 2005 18:29:18 -0000	1.3
@@ -66,7 +66,8 @@
 			   GooString *ownerKey, GooString *userKey,
 			   int permissions, GooString *fileID,
 			   GooString *ownerPassword, GooString *userPassword,
-			   Guchar *fileKey, GBool *ownerPasswordOk) {
+			   Guchar *fileKey, GBool encryptMetadata,
+			   GBool *ownerPasswordOk) {
   Guchar test[32], test2[32];
   GooString *userPassword2;
   Guchar fState[256];
@@ -111,7 +112,8 @@
     }
     userPassword2 = new GooString((char *)test2, 32);
     if (makeFileKey2(encVersion, encRevision, keyLength, ownerKey, userKey,
-		     permissions, fileID, userPassword2, fileKey)) {
+		     permissions, fileID, userPassword2, fileKey,
+		     encryptMetadata)) {
       *ownerPasswordOk = gTrue;
       delete userPassword2;
       return gTrue;
@@ -121,13 +123,15 @@
 
   // try using the supplied user password
   return makeFileKey2(encVersion, encRevision, keyLength, ownerKey, userKey,
-		      permissions, fileID, userPassword, fileKey);
+		      permissions, fileID, userPassword, fileKey,
+		      encryptMetadata);
 }
 
 GBool Decrypt::makeFileKey2(int encVersion, int encRevision, int keyLength,
 			    GooString *ownerKey, GooString *userKey,
 			    int permissions, GooString *fileID,
-			    GooString *userPassword, Guchar *fileKey) {
+			    GooString *userPassword, Guchar *fileKey,
+			    GBool encryptMetadata) {
   Guchar *buf;
   Guchar test[32];
   Guchar fState[256];
@@ -137,7 +141,7 @@
   GBool ok;
 
   // generate file key
-  buf = (Guchar *)gmalloc(68 + fileID->getLength());
+  buf = (Guchar *)gmalloc(72 + fileID->getLength());
   if (userPassword) {
     len = userPassword->getLength();
     if (len < 32) {
@@ -155,7 +159,14 @@
   buf[66] = (permissions >> 16) & 0xff;
   buf[67] = (permissions >> 24) & 0xff;
   memcpy(buf + 68, fileID->getCString(), fileID->getLength());
-  md5(buf, 68 + fileID->getLength(), fileKey);
+  len = 68 + fileID->getLength();
+  if (!encryptMetadata) {
+    buf[len++] = 0xff;
+    buf[len++] = 0xff;
+    buf[len++] = 0xff;
+    buf[len++] = 0xff;
+  }
+  md5(buf, len, fileKey);
   if (encRevision == 3) {
     for (i = 0; i < 50; ++i) {
       md5(fileKey, keyLength, fileKey);

Index: Decrypt.h
===================================================================
RCS file: /cvs/poppler/poppler/poppler/Decrypt.h,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -u -d -r1.1.1.1 -r1.2
--- Decrypt.h	3 Mar 2005 19:46:00 -0000	1.1.1.1
+++ Decrypt.h	16 Sep 2005 18:29:18 -0000	1.2
@@ -41,14 +41,16 @@
 			   GooString *ownerKey, GooString *userKey,
 			   int permissions, GooString *fileID,
 			   GooString *ownerPassword, GooString *userPassword,
-			   Guchar *fileKey, GBool *ownerPasswordOk);
+			   Guchar *fileKey, GBool encryptMetadata,
+			   GBool *ownerPasswordOk);
 
 private:
 
   static GBool makeFileKey2(int encVersion, int encRevision, int keyLength,
 			    GooString *ownerKey, GooString *userKey,
 			    int permissions, GooString *fileID,
-			    GooString *userPassword, Guchar *fileKey);
+			    GooString *userPassword, Guchar *fileKey,
+			    GBool encryptMetadata);
 
   int objKeyLength;
   Guchar objKey[21];

Index: FlateStream.h
===================================================================
RCS file: /cvs/poppler/poppler/poppler/FlateStream.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- FlateStream.h	27 Apr 2005 20:56:18 -0000	1.1
+++ FlateStream.h	16 Sep 2005 18:29:18 -0000	1.2
@@ -32,9 +32,7 @@
 #include "poppler-config.h"
 #include "Error.h"
 #include "Object.h"
-#ifndef NO_DECRYPTION
 #include "Decrypt.h"
-#endif
 #include "Stream.h"
 
 extern "C" {

Index: GlobalParams.cc
===================================================================
RCS file: /cvs/poppler/poppler/poppler/GlobalParams.cc,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -d -r1.8 -r1.9
--- GlobalParams.cc	23 Aug 2005 18:20:45 -0000	1.8
+++ GlobalParams.cc	16 Sep 2005 18:29:18 -0000	1.9
@@ -15,6 +15,14 @@
 #include <string.h>
 #include <stdio.h>
 #include <ctype.h>
+#ifdef ENABLE_PLUGINS
+#  ifndef WIN32
+#    include <dlfcn.h>
+#  endif
+#endif
+#ifdef WIN32
+#  include <shlobj.h>
+#endif
 #if HAVE_PAPER_H
 #include <paper.h>
 #endif
@@ -31,6 +39,9 @@
 #include "CMap.h"
 #include "BuiltinFontTables.h"
 #include "FontEncodingTables.h"
+#ifdef ENABLE_PLUGINS
+#  include "XpdfPluginAPI.h"
+#endif
 #include "GlobalParams.h"
 #include "GfxFont.h"
 
@@ -58,6 +69,12 @@
 #include "UnicodeMapTables.h"
 #include "UTF8.h"
 
+#ifdef ENABLE_PLUGINS
+#  ifdef WIN32
+extern XpdfPluginVecTable xpdfPluginVecTable;
+#  endif
+#endif
+
 //------------------------------------------------------------------------
 
 #define cidToUnicodeCacheSize     4
@@ -121,6 +138,148 @@
   }
 }
 
+#ifdef ENABLE_PLUGINS
+//------------------------------------------------------------------------
+// Plugin
+//------------------------------------------------------------------------
+
+class Plugin {
+public:
+
+  static Plugin *load(char *type, char *name);
+  ~Plugin();
+
+private:
+
+#ifdef WIN32
+  Plugin(HMODULE libA);
+  HMODULE lib;
+#else
+  Plugin(void *dlA);
+  void *dl;
+#endif
+};
+
+Plugin *Plugin::load(char *type, char *name) {
+  GString *path;
+  Plugin *plugin;
+  XpdfPluginVecTable *vt;
+  XpdfBool (*xpdfInitPlugin)(void);
+#ifdef WIN32
+  HMODULE libA;
+#else
+  void *dlA;
+#endif
+
+  path = globalParams->getBaseDir();
+  appendToPath(path, "plugins");
+  appendToPath(path, type);
+  appendToPath(path, name);
+
+#ifdef WIN32
+  path->append(".dll");
+  if (!(libA = LoadLibrary(path->getCString()))) {
+    error(-1, "Failed to load plugin '%s'",
+	  path->getCString());
+    goto err1;
+  }
+  if (!(vt = (XpdfPluginVecTable *)
+	         GetProcAddress(libA, "xpdfPluginVecTable"))) {
+    error(-1, "Failed to find xpdfPluginVecTable in plugin '%s'",
+	  path->getCString());
+    goto err2;
+  }
+#else
+  //~ need to deal with other extensions here
+  path->append(".so");
+  if (!(dlA = dlopen(path->getCString(), RTLD_NOW))) {
+    error(-1, "Failed to load plugin '%s': %s",
+	  path->getCString(), dlerror());
+    goto err1;
+  }
+  if (!(vt = (XpdfPluginVecTable *)dlsym(dlA, "xpdfPluginVecTable"))) {
+    error(-1, "Failed to find xpdfPluginVecTable in plugin '%s'",
+	  path->getCString());
+    goto err2;
+  }
+#endif
+
+  if (vt->version != xpdfPluginVecTable.version) {
+    error(-1, "Plugin '%s' is wrong version", path->getCString());
+    goto err2;
+  }
+  memcpy(vt, &xpdfPluginVecTable, sizeof(xpdfPluginVecTable));
+
+#ifdef WIN32
+  if (!(xpdfInitPlugin = (XpdfBool (*)(void))
+	                     GetProcAddress(libA, "xpdfInitPlugin"))) {
+    error(-1, "Failed to find xpdfInitPlugin in plugin '%s'",
+	  path->getCString());
+    goto err2;
+  }
+#else
+  if (!(xpdfInitPlugin = (XpdfBool (*)(void))dlsym(dlA, "xpdfInitPlugin"))) {
+    error(-1, "Failed to find xpdfInitPlugin in plugin '%s'",
+	  path->getCString());
+    goto err2;
+  }
+#endif
+
+  if (!(*xpdfInitPlugin)()) {
+    error(-1, "Initialization of plugin '%s' failed",
+	  path->getCString());
+    goto err2;
+  }
+
+#ifdef WIN32
+  plugin = new Plugin(libA);
+#else
+  plugin = new Plugin(dlA);
+#endif
+
+  delete path;
+  return plugin;
+
+ err2:
+#ifdef WIN32
+  FreeLibrary(libA);
+#else
+  dlclose(dlA);
+#endif
+ err1:
+  delete path;
+  return NULL;
+}
+
+#ifdef WIN32
+Plugin::Plugin(HMODULE libA) {
+  lib = libA;
+}
+#else
+Plugin::Plugin(void *dlA) {
+  dl = dlA;
+}
+#endif
+
+Plugin::~Plugin() {
+  void (*xpdfFreePlugin)(void);
+
+#ifdef WIN32
+  if ((xpdfFreePlugin = (void (*)(void))
+                            GetProcAddress(lib, "xpdfFreePlugin"))) {
+    (*xpdfFreePlugin)();
+  }
+  FreeLibrary(lib);
+#else
+  if ((xpdfFreePlugin = (void (*)(void))dlsym(dl, "xpdfFreePlugin"))) {
+    (*xpdfFreePlugin)();
+  }
+  dlclose(dl);
+#endif
+}
+
+#endif // ENABLE_PLUGINS
+
 //------------------------------------------------------------------------
 // parsing
 //------------------------------------------------------------------------
@@ -224,6 +383,11 @@
   unicodeMapCache = new UnicodeMapCache();
   cMapCache = new CMapCache();
 
+#ifdef ENABLE_PLUGINS
+  plugins = new GList();
+  securityHandlers = new GList();
+#endif
+
   // set up the initial nameToUnicode table
   for (i = 0; nameToUnicodeTab[i].name; ++i) {
     nameToUnicode->add(nameToUnicodeTab[i].name, nameToUnicodeTab[i].u);
@@ -816,6 +980,11 @@
   delete unicodeMapCache;
   delete cMapCache;
 
+#ifdef ENABLE_PLUGINS
+  delete securityHandlers;
+  deleteGList(plugins, Plugin);
+#endif
+
 #if MULTITHREADED
   gDestroyMutex(&mutex);
   gDestroyMutex(&unicodeMapCacheMutex);
@@ -1741,3 +1910,63 @@
   errQuiet = errQuietA;
   unlockGlobalParams;
 }
+
+void GlobalParams::addSecurityHandler(XpdfSecurityHandler *handler) {
+#ifdef ENABLE_PLUGINS
+  lockGlobalParams;
+  securityHandlers->append(handler);
+  unlockGlobalParams;
+#endif
+}
+
+XpdfSecurityHandler *GlobalParams::getSecurityHandler(char *name) {
+#ifdef ENABLE_PLUGINS
+  XpdfSecurityHandler *hdlr;
+  int i;
+
+  lockGlobalParams;
+  for (i = 0; i < securityHandlers->getLength(); ++i) {
+    hdlr = (XpdfSecurityHandler *)securityHandlers->get(i);
+    if (!stricmp(hdlr->name, name)) {
+      unlockGlobalParams;
+      return hdlr;
+    }
+  }
+  unlockGlobalParams;
+
+  if (!loadPlugin("security", name)) {
+    return NULL;
+  }
+
+  lockGlobalParams;
+  for (i = 0; i < securityHandlers->getLength(); ++i) {
+    hdlr = (XpdfSecurityHandler *)securityHandlers->get(i);
+    if (!strcmp(hdlr->name, name)) {
+      unlockGlobalParams;
+      return hdlr;
+    }
+  }
+  unlockGlobalParams;
+#endif
+
+  return NULL;
+}
+
+#ifdef ENABLE_PLUGINS
+//------------------------------------------------------------------------
+// plugins
+//------------------------------------------------------------------------
+
+GBool GlobalParams::loadPlugin(char *type, char *name) {
+  Plugin *plugin;
+
+  if (!(plugin = Plugin::load(type, name))) {
+    return gFalse;
+  }
+  lockGlobalParams;
+  plugins->append(plugin);
+  unlockGlobalParams;
+  return gTrue;
+}
+
+#endif // ENABLE_PLUGINS

Index: GlobalParams.h
===================================================================
RCS file: /cvs/poppler/poppler/poppler/GlobalParams.h,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- GlobalParams.h	23 Aug 2005 18:20:45 -0000	1.3
+++ GlobalParams.h	16 Sep 2005 18:29:18 -0000	1.4
@@ -33,6 +33,7 @@
 class UnicodeMapCache;
 class CMap;
 class CMapCache;
+struct XpdfSecurityHandler;
 class GlobalParams;
 class GfxFont;
 
@@ -165,6 +166,9 @@
   UnicodeMap *getUnicodeMap(GooString *encodingName);
   CMap *getCMap(GooString *collection, GooString *cMapName);
   UnicodeMap *getTextEncoding();
+#ifdef ENABLE_PLUGINS
+  GBool loadPlugin(char *type, char *name);
+#endif
 
   //----- functions to set parameters
 
@@ -198,6 +202,11 @@
   void setProfileCommands(GBool profileCommandsA);
   void setErrQuiet(GBool errQuietA);
 
+  //----- security handlers
+
+  void addSecurityHandler(XpdfSecurityHandler *handler);
+  XpdfSecurityHandler *getSecurityHandler(char *name);
+
 private:
 
   void parseFile(GooString *fileName, FILE *f);
@@ -232,6 +241,7 @@
 
   //----- user-modifiable settings
 
+  GooString *baseDir;		// base directory - for plugins, etc.
   NameToCharCode *		// mapping from char name to Unicode
     nameToUnicode;
   GooHash *cidToUnicodes;		// files for mappings from char collections
@@ -296,6 +306,12 @@
   
   FcConfig *FCcfg;
 
+#ifdef ENABLE_PLUGINS
+  GList *plugins;		// list of plugins [Plugin]
+  GList *securityHandlers;	// list of loaded security handlers
+				//   [XpdfSecurityHandler]
+#endif
+
 #if MULTITHREADED
   GooMutex mutex;
   GooMutex unicodeMapCacheMutex;

Index: Makefile.am
===================================================================
RCS file: /cvs/poppler/poppler/poppler/Makefile.am,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -d -r1.11 -r1.12
--- Makefile.am	23 Aug 2005 18:20:45 -0000	1.11
+++ Makefile.am	16 Sep 2005 18:29:18 -0000	1.12
@@ -74,6 +74,7 @@
 
 INCLUDES =					\
 	-I$(top_srcdir)				\
+	-I$(top_srcdir)/goo			\
 	$(splash_includes)			\
 	$(cairo_includes)			\
 	$(arthur_includes)			\
@@ -142,6 +143,7 @@
 	NameToUnicodeTable.h	\
 	PSOutputDev.h		\
 	TextOutputDev.h		\
+	SecurityHandler.h	\
 	UTF8.h			\
 	poppler-config.h
 
@@ -190,4 +192,5 @@
 	PSOutputDev.cc		\
 	TextOutputDev.cc	\
 	PageLabelInfo.h		\
-	PageLabelInfo.cc	
+	PageLabelInfo.cc	\
+	SecurityHandler.cc

Index: PDFDoc.cc
===================================================================
RCS file: /cvs/poppler/poppler/poppler/PDFDoc.cc,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -d -r1.5 -r1.6
--- PDFDoc.cc	7 Aug 2005 23:58:12 -0000	1.5
+++ PDFDoc.cc	16 Sep 2005 18:29:18 -0000	1.6
@@ -30,6 +30,7 @@
 #include "ErrorCodes.h"
 #include "Lexer.h"
 #include "Parser.h"
+#include "SecurityHandler.h"
 #ifndef DISABLE_OUTLINE
 #include "Outline.h"
 #endif
@@ -244,6 +245,41 @@
   }
 }
 
+GBool PDFDoc::checkEncryption(GooString *ownerPassword, GooString *userPassword) {
+  Object encrypt;
+  GBool encrypted;
+  SecurityHandler *secHdlr;
+  GBool ret;
+
+  xref->getTrailerDict()->dictLookup("Encrypt", &encrypt);
+  if ((encrypted = encrypt.isDict())) {
+    if ((secHdlr = SecurityHandler::make(this, &encrypt))) {
+      if (secHdlr->checkEncryption(ownerPassword, userPassword)) {
+	// authorization succeeded
+       	xref->setEncryption(secHdlr->getPermissionFlags(),
+			    secHdlr->getOwnerPasswordOk(),
+			    secHdlr->getFileKey(),
+			    secHdlr->getFileKeyLength(),
+			    secHdlr->getEncVersion(),
+			    secHdlr->getEncRevision());
+	ret = gTrue;
+      } else {
+	// authorization failed
+	ret = gFalse;
+      }
+      delete secHdlr;
+    } else {
+      // couldn't find the matching security handler
+      ret = gFalse;
+    }
+  } else {
+    // document is not encrypted
+    ret = gTrue;
+  }
+  encrypt.free();
+  return ret;
+}
+
 void PDFDoc::displayPage(OutputDev *out, int page, double hDPI, double vDPI,
 			 int rotate, GBool crop, GBool doLinks,
 			 GBool (*abortCheckCbk)(void *data),

Index: PDFDoc.h
===================================================================
RCS file: /cvs/poppler/poppler/poppler/PDFDoc.h,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- PDFDoc.h	6 Jul 2005 13:29:00 -0000	1.3
+++ PDFDoc.h	16 Sep 2005 18:29:18 -0000	1.4
@@ -166,6 +166,7 @@
   GBool setup(GooString *ownerPassword, GooString *userPassword);
   GBool checkFooter();
   void checkHeader();
+  GBool checkEncryption(GooString *ownerPassword, GooString *userPassword);
   void getLinks(Page *page);
 
   GooString *fileName;

Index: Parser.cc
===================================================================
RCS file: /cvs/poppler/poppler/poppler/Parser.cc,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -u -d -r1.1.1.1 -r1.2
--- Parser.cc	3 Mar 2005 19:46:03 -0000	1.1.1.1
+++ Parser.cc	16 Sep 2005 18:29:18 -0000	1.2
@@ -19,9 +19,7 @@
 #include "Parser.h"
 #include "XRef.h"
 #include "Error.h"
-#ifndef NO_DECRYPTION
 #include "Decrypt.h"
-#endif
 
 Parser::Parser(XRef *xrefA, Lexer *lexerA) {
   xref = xrefA;
@@ -37,23 +35,17 @@
   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;
   GooString *s;
   char *p;
   int i;
-#endif
 
   // refill buffer after inline image data
   if (inlineImg == 2) {
@@ -69,11 +61,7 @@
     shift();
     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();
@@ -93,11 +81,7 @@
 	  gfree(key);
 	  break;
 	}
-#ifndef NO_DECRYPTION
 	obj->dictAdd(key, getObj(&obj2, fileKey, keyLength, objNum, objGen));
-#else
-	obj->dictAdd(key, getObj(&obj2));
-#endif
       }
     }
     if (buf1.isEOF())
@@ -105,12 +89,10 @@
     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();
@@ -131,7 +113,6 @@
       obj->initInt(num);
     }
 
-#ifndef NO_DECRYPTION
   // string
   } else if (buf1.isString() && fileKey) {
     buf1.copy(obj);
@@ -144,7 +125,6 @@
     }
     delete decrypt;
     shift();
-#endif
 
   // simple object
   } else {

Index: Parser.h
===================================================================
RCS file: /cvs/poppler/poppler/poppler/Parser.h,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -u -d -r1.1.1.1 -r1.2
--- Parser.h	3 Mar 2005 19:46:01 -0000	1.1.1.1
+++ Parser.h	16 Sep 2005 18:29:18 -0000	1.2
@@ -29,13 +29,9 @@
   ~Parser();
 
   // Get the next object from the input stream.
-#ifndef NO_DECRYPTION
   Object *getObj(Object *obj,
 		 Guchar *fileKey = NULL, int keyLength = 0,
 		 int objNum = 0, int objGen = 0);
-#else
-  Object *getObj(Object *obj);
-#endif
 
   // Get stream.
   Stream *getStream() { return lexer->getStream(); }

Index: Stream.cc
===================================================================
RCS file: /cvs/poppler/poppler/poppler/Stream.cc,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- Stream.cc	27 Aug 2005 08:43:43 -0000	1.4
+++ Stream.cc	16 Sep 2005 18:29:18 -0000	1.5
@@ -25,9 +25,7 @@
 #include "poppler-config.h"
 #include "Error.h"
 #include "Object.h"
-#ifndef NO_DECRYPTION
 #include "Decrypt.h"
-#endif
 #include "Stream.h"
 #include "JBIG2Stream.h"
 #include "JPXStream.h"
@@ -280,25 +278,19 @@
 
 BaseStream::BaseStream(Object *dictA) {
   dict = *dictA;
-#ifndef NO_DECRYPTION
   decrypt = NULL;
-#endif
 }
 
 BaseStream::~BaseStream() {
   dict.free();
-#ifndef NO_DECRYPTION
   if (decrypt)
     delete decrypt;
-#endif
 }
 
-#ifndef NO_DECRYPTION
 void BaseStream::doDecryption(Guchar *fileKey, int keyLength,
 			      int objNum, int objGen) {
   decrypt = new Decrypt(fileKey, keyLength, objNum, objGen);
 }
-#endif
 
 //------------------------------------------------------------------------
 // FilterStream
@@ -604,10 +596,8 @@
   saved = gTrue;
   bufPtr = bufEnd = buf;
   bufPos = start;
-#ifndef NO_DECRYPTION
   if (decrypt)
     decrypt->reset();
-#endif
 }
 
 void FileStream::close() {
@@ -625,9 +615,7 @@
 
 GBool FileStream::fillBuf() {
   int n;
-#ifndef NO_DECRYPTION
   char *p;
-#endif
 
   bufPos += bufEnd - buf;
   bufPtr = bufEnd = buf;
@@ -644,13 +632,11 @@
   if (bufPtr >= bufEnd) {
     return gFalse;
   }
-#ifndef NO_DECRYPTION
   if (decrypt) {
     for (p = buf; p < bufEnd; ++p) {
       *p = (char)decrypt->decryptByte((Guchar)*p);
     }
   }
-#endif
   return gTrue;
 }
 
@@ -739,11 +725,9 @@
 
 void MemStream::reset() {
   bufPtr = buf + start;
-#ifndef NO_DECRYPTION
   if (decrypt) {
     decrypt->reset();
   }
-#endif
 }
 
 void MemStream::close() {
@@ -770,7 +754,6 @@
   bufPtr = buf + start;
 }
 
-#ifndef NO_DECRYPTION
 void MemStream::doDecryption(Guchar *fileKey, int keyLength,
 			     int objNum, int objGen) {
   char *newBuf;
@@ -789,7 +772,6 @@
     needFree = gTrue;
   }
 }
-#endif
 
 //------------------------------------------------------------------------
 // EmbedStream

Index: Stream.h
===================================================================
RCS file: /cvs/poppler/poppler/poppler/Stream.h,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- Stream.h	31 Aug 2005 15:28:46 -0000	1.4
+++ Stream.h	16 Sep 2005 18:29:18 -0000	1.5
@@ -17,9 +17,7 @@
 #include "goo/gtypes.h"
 #include "Object.h"
 
-#ifndef NO_DECRYPTION
 class Decrypt;
-#endif
 class BaseStream;
 
 //------------------------------------------------------------------------
@@ -145,17 +143,13 @@
   virtual Guint getStart() = 0;
   virtual void moveStart(int delta) = 0;
 
-#ifndef NO_DECRYPTION
   // Set decryption for this stream.
   virtual void doDecryption(Guchar *fileKey, int keyLength,
 			    int objNum, int objGen);
-#endif
 
-#ifndef NO_DECRYPTION
 protected:
 
   Decrypt *decrypt;
-#endif
 
 private:
 
@@ -322,10 +316,8 @@
   virtual void setPos(Guint pos, int dir = 0);
   virtual Guint getStart() { return start; }
   virtual void moveStart(int delta);
-#ifndef NO_DECRYPTION
   virtual void doDecryption(Guchar *fileKey, int keyLength,
 			    int objNum, int objGen);
-#endif
 
 private:
 

Index: XRef.cc
===================================================================
RCS file: /cvs/poppler/poppler/poppler/XRef.cc,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- XRef.cc	27 Aug 2005 08:43:43 -0000	1.4
+++ XRef.cc	16 Sep 2005 18:29:18 -0000	1.5
@@ -22,9 +22,7 @@
 #include "Lexer.h"
 #include "Parser.h"
 #include "Dict.h"
-#ifndef NO_DECRYPTION
 #include "Decrypt.h"
-#endif
 #include "Error.h"
 #include "ErrorCodes.h"
 #include "XRef.h"
@@ -34,7 +32,6 @@
 #define xrefSearchSize 1024	// read this many bytes at end of file
 				//   to look for 'startxref'
 
-#ifndef NO_DECRYPTION
 //------------------------------------------------------------------------
 // Permission bits
 // Note that the PDF spec uses 1 base (eg bit 3 is 1<<2)
@@ -49,7 +46,6 @@
 #define permAssemble      (1<<10) // bit 11
 #define permHighResPrint  (1<<11) // bit 12
 #define defPermFlags 0xfffc
-#endif
 
 //------------------------------------------------------------------------
 // ObjectStream
@@ -263,9 +259,7 @@
   trailerDict.getDict()->setXRef(this);
 
   // check for encryption
-#ifndef NO_DECRYPTION
   encrypted = gFalse;
-#endif
   if (checkEncrypted(ownerPassword, userPassword)) {
     ok = gFalse;
     errCode = errEncrypted;
@@ -786,129 +780,34 @@
   return gFalse;
 }
 
-#ifndef NO_DECRYPTION
-GBool XRef::checkEncrypted(GooString *ownerPassword, GooString *userPassword) {
-  Object encrypt, filterObj, versionObj, revisionObj, lengthObj;
-  Object ownerKey, userKey, permissions, fileID, fileID1;
-  GBool encrypted1;
-  GBool ret;
-
-  keyLength = 0;
-  encVersion = encRevision = 0;
-  ret = gFalse;
-
-  permFlags = defPermFlags;
-  ownerPasswordOk = gFalse;
-  trailerDict.dictLookup("Encrypt", &encrypt);
-  if ((encrypted1 = encrypt.isDict())) {
-    ret = gTrue;
-    encrypt.dictLookup("Filter", &filterObj);
-    if (filterObj.isName("Standard")) {
-      encrypt.dictLookup("V", &versionObj);
-      encrypt.dictLookup("R", &revisionObj);
-      encrypt.dictLookup("Length", &lengthObj);
-      encrypt.dictLookup("O", &ownerKey);
-      encrypt.dictLookup("U", &userKey);
-      encrypt.dictLookup("P", &permissions);
-      trailerDict.dictLookup("ID", &fileID);
-      if (versionObj.isInt() &&
-	  revisionObj.isInt() &&
-	  ownerKey.isString() && ownerKey.getString()->getLength() == 32 &&
-	  userKey.isString() && userKey.getString()->getLength() == 32 &&
-	  permissions.isInt() &&
-	  fileID.isArray()) {
-	encVersion = versionObj.getInt();
-	encRevision = revisionObj.getInt();
-	if (lengthObj.isInt()) {
-	  keyLength = lengthObj.getInt() / 8;
-	} else {
-	  keyLength = 5;
-	}
-	if (keyLength > 16) {
-	  keyLength = 16;
-	}
-	/* special case for revision 2. 
-	 * See Algorithm 3.2 step 9 from PDF Reference, fifth edition.*/
-	if (encRevision == 2) {
-	  keyLength = 5;
-	}
+void XRef::setEncryption(int permFlagsA, GBool ownerPasswordOkA,
+			 Guchar *fileKeyA, int keyLengthA,
+			 int encVersionA, int encRevisionA) {
+  int i;
 
-	permFlags = permissions.getInt();
-	if (encVersion >= 1 && encVersion <= 2 &&
-	    encRevision >= 2 && encRevision <= 3) {
-	  fileID.arrayGet(0, &fileID1);
-	  if (fileID1.isString()) {
-	    if (Decrypt::makeFileKey(encVersion, encRevision, keyLength,
-				     ownerKey.getString(), userKey.getString(),
-				     permFlags, fileID1.getString(),
-				     ownerPassword, userPassword, fileKey,
-				     &ownerPasswordOk)) {
-	      if (ownerPassword && !ownerPasswordOk) {
-		error(-1, "Incorrect owner password");
-	      }
-	      ret = gFalse;
-	    } else {
-	      error(-1, "Incorrect password");
-	    }
-	  } else {
-	    error(-1, "Weird encryption info");
-	  }
-	  fileID1.free();
-	} else {
-	  error(-1, "Unsupported version/revision (%d/%d) of Standard security handler",
-		encVersion, encRevision);
-	}
-      } else {
-	error(-1, "Weird encryption info");
-      }
-      fileID.free();
-      permissions.free();
-      userKey.free();
-      ownerKey.free();
-      lengthObj.free();
-      revisionObj.free();
-      versionObj.free();
-    } else {
-      error(-1, "Unknown security handler '%s'",
-	    filterObj.isName() ? filterObj.getName() : "???");
-    }
-    filterObj.free();
+  encrypted = gTrue;
+  permFlags = permFlagsA;
+  ownerPasswordOk = ownerPasswordOkA;
+  if (keyLengthA <= 16) {
+    keyLength = keyLengthA;
+  } else {
+    keyLength = 16;
   }
-  encrypt.free();
-
-  // this flag has to be set *after* we read the O/U/P strings
-  encrypted = encrypted1;
-
-  return ret;
-}
-#else
-GBool XRef::checkEncrypted(GooString *ownerPassword, GooString *userPassword) {
-  Object obj;
-  GBool encrypted;
-
-  trailerDict.dictLookup("Encrypt", &obj);
-  if ((encrypted = !obj.isNull())) {
-    error(-1, "PDF file is encrypted and this version of the Xpdf tools");
-    error(-1, "was built without decryption support.");
+  for (i = 0; i < keyLength; ++i) {
+    fileKey[i] = fileKeyA[i];
   }
-  obj.free();
-  return encrypted;
+  encVersion = encVersionA;
+  encRevision = encRevisionA;
 }
-#endif
 
 GBool XRef::okToPrint(GBool ignoreOwnerPW) {
-#ifndef NO_DECRYPTION
   return (!ignoreOwnerPW && ownerPasswordOk) || (permFlags & permPrint);
-#else
-  return gTrue;
-#endif
 }
 
 // we can print at high res if we are only doing security handler revision
 // 2 (and we are allowed to print at all), or with security handler rev
 // 3 and we are allowed to print, and bit 12 is set.
 GBool XRef::okToPrintHighRes(GBool ignoreOwnerPW) {
-#ifndef NO_DECRYPTION
   if (2 == encRevision) {
     return (okToPrint(ignoreOwnerPW));
   } else if (encRevision >= 3) {
@@ -917,57 +816,30 @@
     // something weird - unknown security handler version
     return gFalse;
   }
-#else
-  return gTrue;
-#endif
 }
 
 GBool XRef::okToChange(GBool ignoreOwnerPW) {
-#ifndef NO_DECRYPTION
   return (!ignoreOwnerPW && ownerPasswordOk) || (permFlags & permChange);
-#else
-  return gTrue;
-#endif
 }
 
 GBool XRef::okToCopy(GBool ignoreOwnerPW) {
-#ifndef NO_DECRYPTION
   return (!ignoreOwnerPW && ownerPasswordOk) || (permFlags & permCopy);
-#else
-  return gTrue;
-#endif
 }
 
 GBool XRef::okToAddNotes(GBool ignoreOwnerPW) {
-#ifndef NO_DECRYPTION
   return (!ignoreOwnerPW && ownerPasswordOk) || (permFlags & permNotes);
-#else
-  return gTrue;
-#endif
 }
 
 GBool XRef::okToFillForm(GBool ignoreOwnerPW) {
-#ifndef NO_DECRYPTION
   return (!ignoreOwnerPW && ownerPasswordOk) || (permFlags & permFillForm);
-#else
-  return gTrue;
-#endif
 }
 
 GBool XRef::okToAccessibility(GBool ignoreOwnerPW) {
-#ifndef NO_DECRYPTION
   return (!ignoreOwnerPW && ownerPasswordOk) || (permFlags & permAccessibility);
-#else
-  return gTrue;
-#endif
 }
 
 GBool XRef::okToAssemble(GBool ignoreOwnerPW) {
-#ifndef NO_DECRYPTION
   return (!ignoreOwnerPW && ownerPasswordOk) || (permFlags & permAssemble);
-#else
-  return gTrue;
-#endif
 }
 
 Object *XRef::fetch(int num, int gen, Object *obj) {
@@ -999,12 +871,8 @@
 	!obj3.isCmd("obj")) {
       goto err;
     }
-#ifndef NO_DECRYPTION
     parser->getObj(obj, encrypted ? fileKey : (Guchar *)NULL, keyLength,
 		   num, gen);
-#else
-    parser->getObj(obj);
-#endif
     obj1.free();
     obj2.free();
     obj3.free();

Index: XRef.h
===================================================================
RCS file: /cvs/poppler/poppler/poppler/XRef.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- XRef.h	5 Jul 2005 12:15:04 -0000	1.2
+++ XRef.h	16 Sep 2005 18:29:18 -0000	1.3
@@ -52,12 +52,13 @@
   // Get the error code (if isOk() returns false).
   int getErrorCode() { return errCode; }
 
+  // Set the encryption parameters.
+  void setEncryption(int permFlagsA, GBool ownerPasswordOkA,
+		     Guchar *fileKeyA, int keyLengthA,
+		     int encVersionA, int encRevisionA);
+
   // Is the file encrypted?
-#ifndef NO_DECRYPTION
   GBool isEncrypted() { return encrypted; }
-#else
-  GBool isEncrypted() { return gFalse; }
-#endif
 
   // Check various permissions.
   GBool okToPrint(GBool ignoreOwnerPW = gFalse);
@@ -114,15 +115,13 @@
 				//   damaged files
   int streamEndsLen;		// number of valid entries in streamEnds
   ObjectStream *objStr;		// cached object stream
-#ifndef NO_DECRYPTION
   GBool encrypted;		// true if file is encrypted
+  int encRevision;		
   int encVersion;		// encryption algorithm
-  int encRevision;		// security handler revision
   int keyLength;		// length of key, in bytes
   int permFlags;		// permission bits
   Guchar fileKey[16];		// file decryption key
   GBool ownerPasswordOk;	// true if owner password is correct
-#endif
 
   Guint getStartXref();
   GBool readXRef(Guint *pos);

Index: poppler-config.h.in
===================================================================
RCS file: /cvs/poppler/poppler/poppler/poppler-config.h.in,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- poppler-config.h.in	28 Jul 2005 06:31:57 -0000	1.2
+++ poppler-config.h.in	16 Sep 2005 18:29:18 -0000	1.3
@@ -41,8 +41,6 @@
 
 // Also, there's a couple of preprocessor symbols in the header files
 // that are used but never defined: DISABLE_OUTLINE, DEBUG_MEM and
-// NO_DECRYPTION.  We might want to explicitly #undef these to make
-// sure we don't get spurious API or ABI incompatibilities.
 
 //------------------------------------------------------------------------
 // version



More information about the poppler mailing list