//========================================================================
//
// XRef.cc
//
// Copyright 1996-2003 Glyph & Cog, LLC
//
//========================================================================

//========================================================================
//
// Modified under the Poppler project - http://poppler.freedesktop.org
//
// All changes made under the Poppler project to this file are licensed
// under GPL version 2 or later
//
// Copyright (C) 2005 Dan Sheridan <dan.sheridan@postman.org.uk>
// Copyright (C) 2005 Brad Hards <bradh@frogmouth.net>
// Copyright (C) 2006, 2008, 2010, 2012-2014 Albert Astals Cid <aacid@kde.org>
// Copyright (C) 2007-2008 Julien Rebetez <julienr@svn.gnome.org>
// Copyright (C) 2007 Carlos Garcia Campos <carlosgc@gnome.org>
// Copyright (C) 2009, 2010 Ilya Gorenbein <igorenbein@finjan.com>
// Copyright (C) 2010 Hib Eris <hib@hiberis.nl>
// Copyright (C) 2012, 2013, 2016 Thomas Freitag <Thomas.Freitag@kabelmail.de>
// Copyright (C) 2012, 2013 Fabio D'Urso <fabiodurso@hotmail.it>
// Copyright (C) 2013, 2014 Adrian Johnson <ajohnson@redneon.com>
// Copyright (C) 2013 Pino Toscano <pino@kde.org>
// Copyright (C) 2016 Jakub Kucharski <jakubkucharski97@gmail.com>
//
// 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
//
//========================================================================

#include <config.h>

#ifdef USE_GCC_PRAGMAS
#pragma implementation
#endif

#include <stdlib.h>
#include <stddef.h>
#include <string.h>
#include <math.h>
#include <ctype.h>
#include <limits.h>
#include <float.h>
#include "goo/gfile.h"
#include "goo/gmem.h"
#include "Object.h"
#include "Stream.h"
#include "Lexer.h"
#include "Parser.h"
#include "Dict.h"
#include "Error.h"
#include "ErrorCodes.h"
#include "XRef.h"
#include "PopplerCache.h"

//------------------------------------------------------------------------
// Permission bits
// Note that the PDF spec uses 1 base (eg bit 3 is 1<<2)
//------------------------------------------------------------------------

#define permPrint         (1<<2)  // bit 3
#define permChange        (1<<3)  // bit 4
#define permCopy          (1<<4)  // bit 5
#define permNotes         (1<<5)  // bit 6
#define permFillForm      (1<<8)  // bit 9
#define permAccessibility (1<<9)  // bit 10
#define permAssemble      (1<<10) // bit 11
#define permHighResPrint  (1<<11) // bit 12
#define defPermFlags 0xfffc

#if MULTITHREADED
#  define xrefLocker()   MutexLocker locker(&mutex)
#  define xrefCondLocker(X)  MutexLocker locker(&mutex, (X))
#else
#  define xrefLocker()
#  define xrefCondLocker(X)
#endif

//------------------------------------------------------------------------
// ObjectStream
//------------------------------------------------------------------------

class ObjectStream {
public:

  // Create an object stream, using object number <objStrNum>,
  // generation 0.
  ObjectStream(XRef *xref, int objStrNumA, int recursion = 0);

  GBool isOk() { return ok; }

  ~ObjectStream();

  // Return the object number of this object stream.
  int getObjStrNum() { return objStrNum; }

  // Get the <objIdx>th object from this stream, which should be
  // object number <objNum>, generation 0.
  Object *getObject(int objIdx, int objNum, Object *obj);

private:

  int objStrNum;		// object number of the object stream
  int nObjects;			// number of objects in the stream
  Object *objs;			// the objects (length = nObjects)
  int *objNums;			// the object numbers (length = nObjects)
  GBool ok;
};

class ObjectStreamKey : public PopplerCacheKey
{
  public:
    ObjectStreamKey(int num) : objStrNum(num)
    {
    }

    bool operator==(const PopplerCacheKey &key) const
    {
      const ObjectStreamKey *k = static_cast<const ObjectStreamKey*>(&key);
      return objStrNum == k->objStrNum;
    }

    const int objStrNum;
};

class ObjectStreamItem : public PopplerCacheItem
{
  public:
    ObjectStreamItem(ObjectStream *objStr) : objStream(objStr)
    {
    }

    ~ObjectStreamItem()
    {
      delete objStream;
    }

    ObjectStream *objStream;
};

ObjectStream::ObjectStream(XRef *xref, int objStrNumA, int recursion) {
  Stream *str;
  Parser *parser;
  Goffset *offsets;
  Object objStr, obj1, obj2;
  Goffset first;
  int i;

  objStrNum = objStrNumA;
  nObjects = 0;
  objs = NULL;
  objNums = NULL;
  ok = gFalse;

  if (!xref->fetch(objStrNum, 0, &objStr, recursion)->isStream()) {
    goto err1;
  }

  if (!objStr.streamGetDict()->lookup("N", &obj1, recursion)->isInt()) {
    obj1.free();
    goto err1;
  }
  nObjects = obj1.getInt();
  obj1.free();
  if (nObjects <= 0) {
    goto err1;
  }

  objStr.streamGetDict()->lookup("First", &obj1, recursion);
  if (!obj1.isInt() && !obj1.isInt64()) {
    obj1.free();
    goto err1;
  }
  if (obj1.isInt())
    first = obj1.getInt();
  else
    first = obj1.getInt64();
  obj1.free();
  if (first < 0) {
    goto err1;
  }

  // this is an arbitrary limit to avoid integer overflow problems
  // in the 'new Object[nObjects]' call (Acrobat apparently limits
  // object streams to 100-200 objects)
  if (nObjects > 1000000) {
    error(errSyntaxError, -1, "Too many objects in an object stream");
    goto err1;
  }
  objs = new Object[nObjects];
  objNums = (int *)gmallocn(nObjects, sizeof(int));
  offsets = (Goffset *)gmallocn(nObjects, sizeof(Goffset));

  // parse the header: object numbers and offsets
  objStr.streamReset();
  obj1.initNull();
  str = new EmbedStream(objStr.getStream(), &obj1, gTrue, first);
  parser = new Parser(xref, new Lexer(xref, str), gFalse);
  for (i = 0; i < nObjects; ++i) {
    parser->getObj(&obj1);
    parser->getObj(&obj2);
    if (!obj1.isInt() || !(obj2.isInt() || obj2.isInt64())) {
      obj1.free();
      obj2.free();
      delete parser;
      gfree(offsets);
      goto err1;
    }
    objNums[i] = obj1.getInt();
    if (obj2.isInt())
      offsets[i] = obj2.getInt();
    else
      offsets[i] = obj2.getInt64();
    obj1.free();
    obj2.free();
    if (objNums[i] < 0 || offsets[i] < 0 ||
	(i > 0 && offsets[i] < offsets[i-1])) {
      delete parser;
      gfree(offsets);
      goto err1;
    }
  }
  while (str->getChar() != EOF) ;
  delete parser;

  // skip to the first object - this shouldn't be necessary because
  // the First key is supposed to be equal to offsets[0], but just in
  // case...
  for (Goffset pos = first; pos < offsets[0]; ++pos) {
    objStr.getStream()->getChar();
  }

  // parse the objects
  for (i = 0; i < nObjects; ++i) {
    obj1.initNull();
    if (i == nObjects - 1) {
      str = new EmbedStream(objStr.getStream(), &obj1, gFalse, 0);
    } else {
      str = new EmbedStream(objStr.getStream(), &obj1, gTrue,
			    offsets[i+1] - offsets[i]);
    }
    parser = new Parser(xref, new Lexer(xref, str), gFalse);
    parser->getObj(&objs[i]);
    while (str->getChar() != EOF) ;
    delete parser;
  }

  gfree(offsets);
  ok = gTrue;

 err1:
  objStr.free();
}

ObjectStream::~ObjectStream() {
  int i;

  if (objs) {
    for (i = 0; i < nObjects; ++i) {
      objs[i].free();
    }
    delete[] objs;
  }
  gfree(objNums);
}

Object *ObjectStream::getObject(int objIdx, int objNum, Object *obj) {
  if (objIdx < 0 || objIdx >= nObjects || objNum != objNums[objIdx]) {
    return obj->initNull();
  }
  return objs[objIdx].copy(obj);
}

//------------------------------------------------------------------------
// XRef
//------------------------------------------------------------------------

void XRef::init() {
#if MULTITHREADED
  gInitMutex(&mutex);
#endif
  ok = gTrue;
  errCode = errNone;
  entries = NULL;
  capacity = 0;
  size = 0;
  modified = gFalse;
  streamEnds = NULL;
  streamEndsLen = 0;
  objStrs = new PopplerCache(5);
  mainXRefEntriesOffset = 0;
  xRefStream = gFalse;
  scannedSpecialFlags = gFalse;
  encrypted = gFalse;
  permFlags = defPermFlags;
  ownerPasswordOk = gFalse;
  rootNum = -1;
  strOwner = gFalse;
  xrefReconstructed = gFalse;
}

XRef::XRef() {
  init();
}

XRef::XRef(Object *trailerDictA) {
  init();

  if (trailerDictA->isDict())
    trailerDict.initDict(trailerDictA->getDict());
}

XRef::XRef(BaseStream *strA, Goffset pos, Goffset mainXRefEntriesOffsetA, GBool *wasReconstructed, GBool reconstruct) {
  Object obj;

  init();
  mainXRefEntriesOffset = mainXRefEntriesOffsetA;

  // read the trailer
  str = strA;
  start = str->getStart();
  prevXRefOffset = mainXRefOffset = pos;

  if (reconstruct && !(ok = constructXRef(wasReconstructed)))
  {
    errCode = errDamaged;
    return;
  }
  else
  {
    // if there was a problem with the 'startxref' position, try to
    // reconstruct the xref table
    if (prevXRefOffset == 0) {
      if (!(ok = constructXRef(wasReconstructed))) {
        errCode = errDamaged;
        return;
      }

    // read the xref table
    } else {
      std::vector<Goffset> followedXRefStm;
      readXRef(&prevXRefOffset, &followedXRefStm, NULL);

      // if there was a problem with the xref table,
      // try to reconstruct it
      if (!ok) {
        if (!(ok = constructXRef(wasReconstructed))) {
          errCode = errDamaged;
          return;
        }
      }
    }

    // set size to (at least) the size specified in trailer dict
    trailerDict.dictLookupNF("Size", &obj);
    if (!obj.isInt()) {
        error(errSyntaxWarning, -1, "No valid XRef size in trailer");
    } else {
      if (obj.getInt() > size) {
         if (resize(obj.getInt()) != obj.getInt()) {
            if (!(ok = constructXRef(wasReconstructed))) {
               obj.free();
               errCode = errDamaged;
               return;
            }
         }
      }
    }
    obj.free();

    // get the root dictionary (catalog) object
    trailerDict.dictLookupNF("Root", &obj);
    if (obj.isRef()) {
      rootNum = obj.getRefNum();
      rootGen = obj.getRefGen();
      obj.free();
    } else {
      obj.free();
      if (!(ok = constructXRef(wasReconstructed))) {
        errCode = errDamaged;
        return;
      }
    }
  }
  // now set the trailer dictionary's xref pointer so we can fetch
  // indirect objects from it
  trailerDict.getDict()->setXRef(this);
}

XRef::~XRef() {
  for(int i=0; i<size; i++) {
      entries[i].obj.free ();
  }
  gfree(entries);

  trailerDict.free();
  if (streamEnds) {
    gfree(streamEnds);
  }
  if (objStrs) {
    delete objStrs;
  }
  if (strOwner) {
    delete str;
  }
#if MULTITHREADED
  gDestroyMutex(&mutex);
#endif
}

XRef *XRef::copy() {
  XRef *xref = new XRef();
  xref->str = str->copy();
  xref->strOwner = gTrue;
  xref->encrypted = encrypted;
  xref->permFlags = permFlags;
  xref->ownerPasswordOk = ownerPasswordOk;
  xref->rootGen = rootGen;
  xref->rootNum = rootNum;

  xref->start = start;
  xref->prevXRefOffset = prevXRefOffset;
  xref->mainXRefEntriesOffset = mainXRefEntriesOffset;
  xref->xRefStream = xRefStream;
  trailerDict.copy(&xref->trailerDict);
  xref->encAlgorithm = encAlgorithm;
  xref->encRevision = encRevision;
  xref->encVersion = encVersion;
  xref->permFlags = permFlags;
  xref->keyLength = keyLength;
  xref->permFlags = permFlags;
  for (int i = 0; i < 32; i++) {
    xref->fileKey[i] = fileKey[i];
  }

  if (xref->reserve(size) == 0) {
    error(errSyntaxError, -1, "unable to allocate {0:d} entries", size);
    delete xref;
    return NULL;
  }
  xref->size = size;
  for (int i = 0; i < size; ++i) {
    xref->entries[i].offset = entries[i].offset;
    xref->entries[i].type = entries[i].type;
    xref->entries[i].obj.initNull ();
    xref->entries[i].flags = entries[i].flags;
    xref->entries[i].gen = entries[i].gen;
  }
  xref->streamEndsLen = streamEndsLen;
  if (streamEndsLen  != 0) {
    xref->streamEnds = (Goffset *)gmalloc(streamEndsLen * sizeof(Goffset));
    for (int i = 0; i < streamEndsLen; i++) {
      xref->streamEnds[i] = streamEnds[i];
    }
  }
  return xref;
}

int XRef::reserve(int newSize)
{
  if (newSize > capacity) {

    int realNewSize;
    for (realNewSize = capacity ? 2 * capacity : 1024;
          newSize > realNewSize && realNewSize > 0;
          realNewSize <<= 1) ;
    if ((realNewSize < 0) ||
        (realNewSize >= INT_MAX / (int)sizeof(XRefEntry))) {
      return 0;
    }

    void *p = greallocn_checkoverflow(entries, realNewSize, sizeof(XRefEntry));
    if (p == NULL) {
      return 0;
    }

    entries = (XRefEntry *) p;
    capacity = realNewSize;

  }

  return capacity;
}

int XRef::resize(int newSize)
{
  if (newSize > size) {

    if (reserve(newSize) < newSize) return size;

    for (int i = size; i < newSize; ++i) {
      entries[i].offset = -1;
      entries[i].type = xrefEntryNone;
      entries[i].obj.initNull ();
      entries[i].flags = 0;
      entries[i].gen = 0;
    }
  } else {
    for (int i = newSize; i < size; i++) {
      entries[i].obj.free ();
    }
  }

  size = newSize;

  return size;
}

/* Read one xref table section.  Also reads the associated trailer
 * dictionary, and returns the prev pointer (if any).
 * Arguments:
 *   pos                Points to a Goffset containing the offset of the XRef
 *                      section to be read. If a prev pointer is found, *pos is
 *                      updated with its value
 *   followedXRefStm    Used in case of nested readXRef calls to spot circular
 *                      references in XRefStm pointers
 *   xrefStreamObjsNum  If not NULL, every time a XRef stream is encountered,
 *                      its object number is appended
 * Return value:
 *   gTrue if a prev pointer is found, otherwise gFalse
 */
GBool XRef::readXRef(Goffset *pos, std::vector<Goffset> *followedXRefStm, std::vector<int> *xrefStreamObjsNum) {
  Parser *parser;
  Object obj;
  GBool more;

  // start up a parser, parse one token
  obj.initNull();
  parser = new Parser(NULL,
	     new Lexer(NULL,
	       str->makeSubStream(start + *pos, gFalse, 0, &obj)),
	     gTrue);
  parser->getObj(&obj, gTrue);

  // parse an old-style xref table
  if (obj.isCmd("xref")) {
    obj.free();
    more = readXRefTable(parser, pos, followedXRefStm, xrefStreamObjsNum);

  // parse an xref stream
  } else if (obj.isInt()) {
    const int objNum = obj.getInt();
    obj.free();
    if (!parser->getObj(&obj, gTrue)->isInt()) {
      goto err1;
    }
    obj.free();
    if (!parser->getObj(&obj, gTrue)->isCmd("obj")) {
      goto err1;
    }
    obj.free();
    if (!parser->getObj(&obj)->isStream()) {
      goto err1;
    }
    if (trailerDict.isNone()) {
      xRefStream = gTrue;
    }
    if (xrefStreamObjsNum) {
      xrefStreamObjsNum->push_back(objNum);
    }
    more = readXRefStream(obj.getStream(), pos);
    obj.free();

  } else {
    goto err1;
  }

  delete parser;
  return more;

 err1:
  obj.free();
  delete parser;
  ok = gFalse;
  return gFalse;
}

GBool XRef::readXRefTable(Parser *parser, Goffset *pos, std::vector<Goffset> *followedXRefStm, std::vector<int> *xrefStreamObjsNum) {
  XRefEntry entry;
  GBool more;
  Object obj, obj2;
  Goffset pos2;
  int first, n, i;

  while (1) {
    parser->getObj(&obj, gTrue);
    if (obj.isCmd("trailer")) {
      obj.free();
      break;
    }
    if (!obj.isInt()) {
      goto err1;
    }
    first = obj.getInt();
    obj.free();
    if (!parser->getObj(&obj, gTrue)->isInt()) {
      goto err1;
    }
    n = obj.getInt();
    obj.free();
    if (first < 0 || n < 0 || first + n < 0) {
      goto err0;
    }
    if (first + n > size) {
      if (resize(first + n) != first + n) {
        error(errSyntaxError, -1, "Invalid 'obj' parameters'");
        goto err0;
      }
    }
    for (i = first; i < first + n; ++i) {
      parser->getObj(&obj, gTrue);
      if (obj.isInt()) {
	entry.offset = obj.getInt();
      } else if (obj.isInt64()) {
	entry.offset = obj.getInt64();
      } else {
	goto err1;
      }
      obj.free();
      if (!parser->getObj(&obj, gTrue)->isInt()) {
	goto err1;
      }
      entry.gen = obj.getInt();
      entry.obj.initNull ();
      entry.flags = 0;
      obj.free();
      parser->getObj(&obj, gTrue);
      if (obj.isCmd("n")) {
	entry.type = xrefEntryUncompressed;
      } else if (obj.isCmd("f")) {
	entry.type = xrefEntryFree;
      } else {
	goto err1;
      }
      obj.free();
      if (entries[i].offset == -1) {
	entries[i] = entry;
	// PDF files of patents from the IBM Intellectual Property
	// Network have a bug: the xref table claims to start at 1
	// instead of 0.
	if (i == 1 && first == 1 &&
	    entries[1].offset == 0 && entries[1].gen == 65535 &&
	    entries[1].type == xrefEntryFree) {
	  i = first = 0;
	  entries[0] = entries[1];
	  entries[1].offset = -1;
	}
      }
    }
  }

  // read the trailer dictionary
  if (!parser->getObj(&obj)->isDict()) {
    goto err1;
  }

  // get the 'Prev' pointer
  obj.getDict()->lookupNF("Prev", &obj2);
  if (obj2.isInt() || obj2.isInt64()) {
    if (obj2.isInt())
      pos2 = obj2.getInt();
    else
      pos2 = obj2.getInt64();
    if (pos2 != *pos) {
      *pos = pos2;
      more = gTrue;
    } else {
      error(errSyntaxWarning, -1, "Infinite loop in xref table");
      more = gFalse;
    }
  } else if (obj2.isRef()) {
    // certain buggy PDF generators generate "/Prev NNN 0 R" instead
    // of "/Prev NNN"
    pos2 = (Guint)obj2.getRefNum();
    if (pos2 != *pos) {
      *pos = pos2;
      more = gTrue;
    } else {
      error(errSyntaxWarning, -1, "Infinite loop in xref table");
      more = gFalse;
    }
  } else {
    more = gFalse;
  }
  obj2.free();

  // save the first trailer dictionary
  if (trailerDict.isNone()) {
    obj.copy(&trailerDict);
  }

  // check for an 'XRefStm' key
  obj.getDict()->lookup("XRefStm", &obj2);
  if (obj2.isInt() || obj2.isInt64()) {
    if (obj2.isInt())
      pos2 = obj2.getInt();
    else
      pos2 = obj2.getInt64();
    for (size_t i = 0; ok == gTrue && i < followedXRefStm->size(); ++i) {
      if (followedXRefStm->at(i) == pos2) {
        ok = gFalse;
      }
    }
    if (ok) {
      followedXRefStm->push_back(pos2);
      readXRef(&pos2, followedXRefStm, xrefStreamObjsNum);
    }
    if (!ok) {
      obj2.free();
      goto err1;
    }
  }
  obj2.free();

  obj.free();
  return more;

 err1:
  obj.free();
 err0:
  ok = gFalse;
  return gFalse;
}

GBool XRef::readXRefStream(Stream *xrefStr, Goffset *pos) {
  Dict *dict;
  int w[3];
  GBool more;
  Object obj, obj2, idx;
  int newSize, first, n, i;

  dict = xrefStr->getDict();

  if (!dict->lookupNF("Size", &obj)->isInt()) {
    goto err1;
  }
  newSize = obj.getInt();
  obj.free();
  if (newSize < 0) {
    goto err1;
  }
  if (newSize > size) {
    if (resize(newSize) != newSize) {
      error(errSyntaxError, -1, "Invalid 'size' parameter");
      goto err0;
    }
  }

  if (!dict->lookupNF("W", &obj)->isArray() ||
      obj.arrayGetLength() < 3) {
    goto err1;
  }
  for (i = 0; i < 3; ++i) {
    if (!obj.arrayGet(i, &obj2)->isInt()) {
      obj2.free();
      goto err1;
    }
    w[i] = obj2.getInt();
    obj2.free();
    if (w[i] < 0) {
      goto err1;
    }
  }
  obj.free();
  if (w[0] > (int)sizeof(int) || w[1] > (int)sizeof(long long) || w[2] > (int)sizeof(int)) {
    goto err1;
  }

  xrefStr->reset();
  dict->lookupNF("Index", &idx);
  if (idx.isArray()) {
    for (i = 0; i+1 < idx.arrayGetLength(); i += 2) {
      if (!idx.arrayGet(i, &obj)->isInt()) {
	idx.free();
	goto err1;
      }
      first = obj.getInt();
      obj.free();
      if (!idx.arrayGet(i+1, &obj)->isInt()) {
	idx.free();
	goto err1;
      }
      n = obj.getInt();
      obj.free();
      if (first < 0 || n < 0 ||
	  !readXRefStreamSection(xrefStr, w, first, n)) {
	idx.free();
	goto err0;
      }
    }
  } else {
    if (!readXRefStreamSection(xrefStr, w, 0, newSize)) {
      idx.free();
      goto err0;
    }
  }
  idx.free();

  dict->lookupNF("Prev", &obj);
  if (obj.isInt()) {
    *pos = obj.getInt();
    more = gTrue;
  } else if (obj.isInt64()) {
    *pos = obj.getInt64();
    more = gTrue;
  } else {
    more = gFalse;
  }
  obj.free();
  if (trailerDict.isNone()) {
    trailerDict.initDict(dict);
  }

  return more;

 err1:
  obj.free();
 err0:
  ok = gFalse;
  return gFalse;
}

GBool XRef::readXRefStreamSection(Stream *xrefStr, int *w, int first, int n) {
  unsigned long long offset;
  int type, gen, c, i, j;

  if (first + n < 0) {
    return gFalse;
  }
  if (first + n > size) {
    if (resize(first + n) != size) {
      error(errSyntaxError, -1, "Invalid 'size' inside xref table");
      return gFalse;
    }
    if (first + n > size) {
      error(errSyntaxError, -1, "Invalid 'first' or 'n' inside xref table");
      return gFalse;
    }
  }
  for (i = first; i < first + n; ++i) {
    if (w[0] == 0) {
      type = 1;
    } else {
      for (type = 0, j = 0; j < w[0]; ++j) {
	if ((c = xrefStr->getChar()) == EOF) {
	  return gFalse;
	}
	type = (type << 8) + c;
      }
    }
    for (offset = 0, j = 0; j < w[1]; ++j) {
      if ((c = xrefStr->getChar()) == EOF) {
	return gFalse;
      }
      offset = (offset << 8) + c;
    }
    if (offset > (unsigned long long)GoffsetMax()) {
      error(errSyntaxError, -1, "Offset inside xref table too large for fseek");
      return gFalse;
    }
    for (gen = 0, j = 0; j < w[2]; ++j) {
      if ((c = xrefStr->getChar()) == EOF) {
	return gFalse;
      }
      gen = (gen << 8) + c;
    }
    if (entries[i].offset == -1) {
      switch (type) {
      case 0:
	entries[i].offset = offset;
	entries[i].gen = gen;
	entries[i].type = xrefEntryFree;
	break;
      case 1:
	entries[i].offset = offset;
	entries[i].gen = gen;
	entries[i].type = xrefEntryUncompressed;
	break;
      case 2:
	entries[i].offset = offset;
	entries[i].gen = gen;
	entries[i].type = xrefEntryCompressed;
	break;
      default:
	return gFalse;
      }
    }
  }

  return gTrue;
}

// Attempt to construct an xref table for a damaged file.
GBool XRef::constructXRef(GBool *wasReconstructed, GBool needCatalogDict) {
  Parser *parser;
  Object newTrailerDict, obj;
  char buf[256];
  Goffset pos;
  int num, gen;
  int newSize;
  int streamEndsSize;
  char *p;
  GBool gotRoot;
  char* token = NULL;
  bool oneCycle = true;
  int offset = 0;

  gfree(entries);
  capacity = 0;
  size = 0;
  entries = NULL;

  gotRoot = gFalse;
  streamEndsLen = streamEndsSize = 0;

  if (wasReconstructed)
  {
    *wasReconstructed = true;
  }

  str->reset();
  while (1) {
    pos = str->getPos();
    if (!str->getLine(buf, 256)) {
      break;
    }
    p = buf;

    // skip whitespace
    while (*p && Lexer::isSpace(*p & 0xff)) ++p;

    oneCycle = true;
    offset = 0;

    while( ( token = strstr( p, "endobj" ) ) || oneCycle ) {
      oneCycle = false;

      if( token ) {
        oneCycle = true;
        token[0] = '\0'; 
        offset = token - p;
      }

      // got trailer dictionary
      if (!strncmp(p, "trailer", 7)) {
        obj.initNull();
        parser = new Parser(NULL,
		 new Lexer(NULL,
		   str->makeSubStream(pos + 7, gFalse, 0, &obj)),
		 gFalse);
        parser->getObj(&newTrailerDict);
        if (newTrailerDict.isDict()) {
	  newTrailerDict.dictLookupNF("Root", &obj);
	  if (obj.isRef() && (!gotRoot || !needCatalogDict) && rootNum != obj.getRefNum()) {
	    rootNum = obj.getRefNum();
	    rootGen = obj.getRefGen();
	    if (!trailerDict.isNone()) {
	      trailerDict.free();
	    }
	    newTrailerDict.copy(&trailerDict);
	    gotRoot = gTrue;
	  }
	  obj.free();
        }
        newTrailerDict.free();
        delete parser;

      // look for object
    } else if (isdigit(*p & 0xff)) {
      num = atoi(p);
      if (num > 0) {
	do {
	  ++p;
	} while (*p && isdigit(*p & 0xff));
	if ((*p & 0xff) == 0 || isspace(*p & 0xff)) {
          if ((*p & 0xff) == 0) {
            //new line, continue with next line!
            str->getLine(buf, 256);
            p = buf - 1;
          }
	  do {
	    ++p;
	  } while (*p && isspace(*p & 0xff));
	  if (isdigit(*p & 0xff)) {
	    gen = atoi(p);
	    do {
	      ++p;
	    } while (*p && isdigit(*p & 0xff));
	    if ((*p & 0xff) == 0 || isspace(*p & 0xff)) {
              if ((*p & 0xff) == 0) {
                //new line, continue with next line!
                str->getLine(buf, 256);
                p = buf - 1;
              }
	      do {
		++p;
	      } while (*p && isspace(*p & 0xff));
	      if (!strncmp(p, "obj", 3)) {
		if (num >= size) {
		  newSize = (num + 1 + 255) & ~255;
		  if (newSize < 0) {
		    error(errSyntaxError, -1, "Bad object number");
		    return gFalse;
		  }
		    if (resize(newSize) != newSize) {
		      error(errSyntaxError, -1, "Invalid 'obj' parameters");
		      return gFalse;
		    }
		  }
		  if (entries[num].type == xrefEntryFree ||
		      gen >= entries[num].gen) {
		    entries[num].offset = pos - start;
		    entries[num].gen = gen;
		    entries[num].type = xrefEntryUncompressed;
		}
	        }
	      }
	    }
	  }
        }

      } else if (!strncmp(p, "endstream", 9)) {
        if (streamEndsLen == streamEndsSize) {
	  streamEndsSize += 64;
          if (streamEndsSize >= INT_MAX / (int)sizeof(int)) {
            error(errSyntaxError, -1, "Invalid 'endstream' parameter.");
            return gFalse;
          }
	  streamEnds = (Goffset *)greallocn(streamEnds,
					streamEndsSize, sizeof(Goffset));
        }
        streamEnds[streamEndsLen++] = pos;
      }
      if( token ) {
        p = token + 6;// strlen( "endobj" ) = 6
        pos += offset + 6;// strlen( "endobj" ) = 6
        while (*p && Lexer::isSpace(*p & 0xff)) {
          ++p;
          ++pos;
        }
      }
    }
  }

  if (gotRoot)
    return gTrue;

  error(errSyntaxError, -1, "Couldn't find trailer dictionary");
  return gFalse;
}

void XRef::setEncryption(int permFlagsA, GBool ownerPasswordOkA,
			 Guchar *fileKeyA, int keyLengthA,
			 int encVersionA, int encRevisionA,
			 CryptAlgorithm encAlgorithmA) {
  int i;

  encrypted = gTrue;
  permFlags = permFlagsA;
  ownerPasswordOk = ownerPasswordOkA;
  if (keyLengthA <= 32) {
    keyLength = keyLengthA;
  } else {
    keyLength = 32;
  }
  for (i = 0; i < keyLength; ++i) {
    fileKey[i] = fileKeyA[i];
  }
  encVersion = encVersionA;
  encRevision = encRevisionA;
  encAlgorithm = encAlgorithmA;
}

void XRef::getEncryptionParameters(Guchar **fileKeyA, CryptAlgorithm *encAlgorithmA,
                              int *keyLengthA) {
  if (encrypted) {
    *fileKeyA = fileKey;
    *encAlgorithmA = encAlgorithm;
    *keyLengthA = keyLength;
  } else {
    // null encryption parameters
    *fileKeyA = NULL;
    *encAlgorithmA = cryptRC4;
    *keyLengthA = 0;
  }
}

GBool XRef::okToPrint(GBool ignoreOwnerPW) {
  return (!ignoreOwnerPW && ownerPasswordOk) || (permFlags & permPrint);
}

// 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) {
  if (encrypted) {
    if (2 == encRevision) {
      return (okToPrint(ignoreOwnerPW));
    } else if (encRevision >= 3) {
      return (okToPrint(ignoreOwnerPW) && (permFlags & permHighResPrint));
    } else {
      // something weird - unknown security handler version
      return gFalse;
    }
  } else {
    return gTrue;
  }
}

GBool XRef::okToChange(GBool ignoreOwnerPW) {
  return (!ignoreOwnerPW && ownerPasswordOk) || (permFlags & permChange);
}

GBool XRef::okToCopy(GBool ignoreOwnerPW) {
  return (!ignoreOwnerPW && ownerPasswordOk) || (permFlags & permCopy);
}

GBool XRef::okToAddNotes(GBool ignoreOwnerPW) {
  return (!ignoreOwnerPW && ownerPasswordOk) || (permFlags & permNotes);
}

GBool XRef::okToFillForm(GBool ignoreOwnerPW) {
  return (!ignoreOwnerPW && ownerPasswordOk) || (permFlags & permFillForm);
}

GBool XRef::okToAccessibility(GBool ignoreOwnerPW) {
  return (!ignoreOwnerPW && ownerPasswordOk) || (permFlags & permAccessibility);
}

GBool XRef::okToAssemble(GBool ignoreOwnerPW) {
  return (!ignoreOwnerPW && ownerPasswordOk) || (permFlags & permAssemble);
}

Object *XRef::getCatalog(Object *catalog) {
  Object *obj = fetch(rootNum, rootGen, catalog);
  if (obj->isDict()) {
    return obj;
  }
  GBool wasReconstructed = false;
  GBool ok = constructXRef(&wasReconstructed, gTrue);
  return (ok) ? fetch(rootNum, rootGen, catalog) : obj;
}

Object *XRef::fetch(int num, int gen, Object *obj, int recursion) {
  XRefEntry *e;
  Parser *parser;
  Object obj1, obj2, obj3;

  xrefLocker();
  // check for bogus ref - this can happen in corrupted PDF files
  if (num < 0 || num >= size) {
    goto err;
  }

  e = getEntry(num);
  if(!e->obj.isNull ()) { //check for updated object
    obj = e->obj.copy(obj);
    return obj;
  }

  switch (e->type) {

  case xrefEntryUncompressed:
    if (e->gen != gen) {
      goto err;
    }
    obj1.initNull();
    parser = new Parser(this,
	       new Lexer(this,
		 str->makeSubStream(start + e->offset, gFalse, 0, &obj1)),
	       gTrue);
    parser->getObj(&obj1, recursion);
    parser->getObj(&obj2, recursion);
    parser->getObj(&obj3, recursion);
    if (!obj1.isInt() || obj1.getInt() != num ||
	!obj2.isInt() || obj2.getInt() != gen ||
	!obj3.isCmd("obj")) {
      // some buggy pdf have obj1234 for ints that represent 1234
      // try to recover here
      if (obj1.isInt() && obj1.getInt() == num &&
	  obj2.isInt() && obj2.getInt() == gen &&
	  obj3.isCmd()) {
	char *cmd = obj3.getCmd();
	if (strlen(cmd) > 3 &&
	    cmd[0] == 'o' &&
	    cmd[1] == 'b' &&
	    cmd[2] == 'j') {
	  char *end_ptr;
	  long longNumber = strtol(cmd + 3, &end_ptr, 0);
	  if (longNumber <= INT_MAX && longNumber >= INT_MIN && *end_ptr == '\0') {
	    int number = longNumber;
	    error(errSyntaxWarning, -1, "Cmd was not obj but {0:s}, assuming the creator meant obj {1:d}", cmd, number);
	    obj->initInt(number);
	    obj1.free();
	    obj2.free();
	    obj3.free();
	    delete parser;
	    break;
	  }
	}
      }
      obj1.free();
      obj2.free();
      obj3.free();
      delete parser;
      goto err;
    }
    parser->getObj(obj, gFalse, (encrypted && !e->getFlag(XRefEntry::Unencrypted)) ? fileKey : NULL,
		   encAlgorithm, keyLength, num, gen, recursion);
    obj1.free();
    obj2.free();
    obj3.free();
    delete parser;
    break;

  case xrefEntryCompressed:
  {
#if 0 // Adobe apparently ignores the generation number on compressed objects
    if (gen != 0) {
      goto err;
    }
#endif
    if (e->offset >= (Guint)size ||
	entries[e->offset].type != xrefEntryUncompressed) {
      error(errSyntaxError, -1, "Invalid object stream");
      goto err;
    }

    ObjectStream *objStr = NULL;
    ObjectStreamKey key(e->offset);
    PopplerCacheItem *item = objStrs->lookup(key);
    if (item) {
      ObjectStreamItem *it = static_cast<ObjectStreamItem *>(item);
      objStr = it->objStream;
    }

    if (!objStr) {
      objStr = new ObjectStream(this, e->offset, recursion + 1);
      if (!objStr->isOk()) {
	delete objStr;
	objStr = NULL;
	goto err;
      } else {
	// XRef could be reconstructed in constructor of ObjectStream:
	e = getEntry(num);
	ObjectStreamKey *newkey = new ObjectStreamKey(e->offset);
	ObjectStreamItem *newitem = new ObjectStreamItem(objStr);
	objStrs->put(newkey, newitem);
      }
    }
    objStr->getObject(e->gen, num, obj);
  }
  break;

  default:
    goto err;
  }
  
  return obj;

 err:
  if (!xRefStream && !xrefReconstructed) {
    error(errInternal, -1, "xref num {0:d} not found but needed, try to reconstruct\n", num);
    rootNum = -1;
    constructXRef(&xrefReconstructed);
    return fetch(num, gen, obj, ++recursion);
  }
  return obj->initNull();
}

void XRef::lock() {
#if MULTITHREADED
  gLockMutex(&mutex);
#endif
}

void XRef::unlock() {
#if MULTITHREADED
  gUnlockMutex(&mutex);
#endif
}

Object *XRef::getDocInfo(Object *obj) {
  return trailerDict.dictLookup("Info", obj);
}

// Added for the pdftex project.
Object *XRef::getDocInfoNF(Object *obj) {
  return trailerDict.dictLookupNF("Info", obj);
}

Object *XRef::createDocInfoIfNoneExists(Object *obj) {
  getDocInfo(obj);

  if (obj->isDict()) {
    return obj;
  } else if (!obj->isNull()) {
    // DocInfo exists, but isn't a dictionary (doesn't comply with the PDF reference)
    obj->free();
    removeDocInfo();
  }

  obj->initDict(this);

  Ref ref = addIndirectObject(obj);

  Object objRef;
  objRef.initRef(ref.num, ref.gen);

  trailerDict.dictSet("Info", &objRef);

  objRef.free();

  return obj;
}

void XRef::removeDocInfo() {
  Object infoObjRef;
  getDocInfoNF(&infoObjRef);
  if (infoObjRef.isNull()) {
    return;
  }

  trailerDict.dictRemove("Info");

  removeIndirectObject(infoObjRef.getRef());
  infoObjRef.free();
}

GBool XRef::getStreamEnd(Goffset streamStart, Goffset *streamEnd) {
  int a, b, m;

  if (streamEndsLen == 0 ||
      streamStart > streamEnds[streamEndsLen - 1]) {
    return gFalse;
  }

  a = -1;
  b = streamEndsLen - 1;
  // invariant: streamEnds[a] < streamStart <= streamEnds[b]
  while (b - a > 1) {
    m = (a + b) / 2;
    if (streamStart <= streamEnds[m]) {
      b = m;
    } else {
      a = m;
    }
  }
  *streamEnd = streamEnds[b];
  return gTrue;
}

int XRef::getNumEntry(Goffset offset)
{
  if (size > 0)
  {
    int res = 0;
    Goffset resOffset = getEntry(0)->offset;
    XRefEntry *e;
    for (int i = 1; i < size; ++i)
    {
      e = getEntry(i, gFalse);
      if (e->type != xrefEntryFree && e->offset < offset && e->offset >= resOffset)
      {
        res = i;
        resOffset = e->offset;
      }
    }
    return res;
  }
  else return -1;
}

void XRef::add(int num, int gen, Goffset offs, GBool used) {
  xrefLocker();
  if (num >= size) {
    if (num >= capacity) {
      entries = (XRefEntry *)greallocn(entries, num + 1, sizeof(XRefEntry));
      capacity = num + 1;
    }
    for (int i = size; i < num + 1; ++i) {
      entries[i].offset = -1;
      entries[i].type = xrefEntryFree;
      entries[i].obj.initNull ();
      entries[i].flags = 0;
      entries[i].gen = 0;
    }
    size = num + 1;
  }
  XRefEntry *e = getEntry(num);
  e->gen = gen;
  e->obj.initNull ();
  e->flags = 0;
  if (used) {
    e->type = xrefEntryUncompressed;
    e->offset = offs;
  } else {
    e->type = xrefEntryFree;
    e->offset = 0;
  }
}

void XRef::setModifiedObject (Object* o, Ref r) {
  xrefLocker();
  if (r.num < 0 || r.num >= size) {
    error(errInternal, -1,"XRef::setModifiedObject on unknown ref: {0:d}, {1:d}\n", r.num, r.gen);
    return;
  }
  XRefEntry *e = getEntry(r.num);
  e->obj.free();
  o->copy(&(e->obj));
  e->setFlag(XRefEntry::Updated, gTrue);
  setModified();
}

Ref XRef::addIndirectObject (Object* o) {
  int entryIndexToUse = -1;
  for (int i = 1; entryIndexToUse == -1 && i < size; ++i) {
    XRefEntry *e = getEntry(i, false /* complainIfMissing */);
    if (e->type == xrefEntryFree && e->gen != 65535) {
      entryIndexToUse = i;
    }
  }

  XRefEntry *e;
  if (entryIndexToUse == -1) {
    entryIndexToUse = size;
    add(entryIndexToUse, 0, 0, gFalse);
    e = getEntry(entryIndexToUse);
  } else {
    //reuse a free entry
    e = getEntry(entryIndexToUse);
    //we don't touch gen number, because it should have been 
    //incremented when the object was deleted
  }
  e->type = xrefEntryUncompressed;
  o->copy(&e->obj);
  e->setFlag(XRefEntry::Updated, gTrue);
  setModified();

  Ref r;
  r.num = entryIndexToUse;
  r.gen = e->gen;
  return r;
}

void XRef::removeIndirectObject(Ref r) {
  xrefLocker();
  if (r.num < 0 || r.num >= size) {
    error(errInternal, -1,"XRef::removeIndirectObject on unknown ref: {0:d}, {1:d}\n", r.num, r.gen);
    return;
  }
  XRefEntry *e = getEntry(r.num);
  if (e->type == xrefEntryFree) {
    return;
  }
  e->obj.free();
  e->type = xrefEntryFree;
  e->gen++;
  e->setFlag(XRefEntry::Updated, gTrue);
  setModified();
}

void XRef::writeXRef(XRef::XRefWriter *writer, GBool writeAllEntries) {
  //create free entries linked-list
  if (getEntry(0)->gen != 65535) {
    error(errInternal, -1, "XRef::writeXRef, entry 0 of the XRef is invalid (gen != 65535)\n");
  }
  int lastFreeEntry = 0;
  for (int i=0; i<size; i++) {
    if (getEntry(i)->type == xrefEntryFree) {
      getEntry(lastFreeEntry)->offset = i;
      lastFreeEntry = i;
    }
  }
  getEntry(lastFreeEntry)->offset = 0;

  if (writeAllEntries) {
    writer->startSection(0, size);
    for (int i=0; i<size; i++) {
      XRefEntry *e = getEntry(i);
      if(e->gen > 65535) e->gen = 65535; //cap generation number to 65535 (required by PDFReference)
      writer->writeEntry(e->offset, e->gen, e->type);
    }
  } else {
    int i = 0;
    while (i < size) {
      int j;
      for(j=i; j<size; j++) { //look for consecutive entries
        if ((getEntry(j)->type == xrefEntryFree) && (getEntry(j)->gen == 0))
          break;
      }
      if (j-i != 0)
      {
        writer->startSection(i, j-i);
        for (int k=i; k<j; k++) {
          XRefEntry *e = getEntry(k);
          if(e->gen > 65535) e->gen = 65535; //cap generation number to 65535 (required by PDFReference)
          writer->writeEntry(e->offset, e->gen, e->type);
        }
        i = j;
      }
      else ++i;
    }
  }
}

XRef::XRefTableWriter::XRefTableWriter(OutStream* outStrA) {
  outStr = outStrA;
}

void XRef::XRefTableWriter::startSection(int first, int count) {
  outStr->printf("%i %i\r\n", first, count);
}

void XRef::XRefTableWriter::writeEntry(Goffset offset, int gen, XRefEntryType type) {
  outStr->printf("%010lli %05i %c\r\n", (long long)offset, gen, (type==xrefEntryFree)?'f':'n');
}

void XRef::writeTableToFile(OutStream* outStr, GBool writeAllEntries) {
  XRefTableWriter writer(outStr);
  outStr->printf("xref\r\n");
  writeXRef(&writer, writeAllEntries);
}

XRef::XRefStreamWriter::XRefStreamWriter(Object *indexA, GooString *stmBufA, int offsetSizeA) {
  index = indexA;
  stmBuf = stmBufA;
  offsetSize = offsetSizeA;
}

void XRef::XRefStreamWriter::startSection(int first, int count) {
  Object obj;
  index->arrayAdd( obj.initInt(first) );
  index->arrayAdd( obj.initInt(count) );
}

void XRef::XRefStreamWriter::writeEntry(Goffset offset, int gen, XRefEntryType type) {
  const int entryTotalSize = 1 + offsetSize + 2; /* type + offset + gen */
  char data[16];
  data[0] = (type==xrefEntryFree) ? 0 : 1;
  for (int i = offsetSize; i > 0; i--) {
    data[i] = offset & 0xff;
    offset >>= 8;
  }
  data[offsetSize + 1] = (gen >> 8) & 0xff;
  data[offsetSize + 2] = gen & 0xff;
  stmBuf->append(data, entryTotalSize);
}

XRef::XRefPreScanWriter::XRefPreScanWriter() {
  hasOffsetsBeyond4GB = gFalse;
}

void XRef::XRefPreScanWriter::startSection(int first, int count) {
}

void XRef::XRefPreScanWriter::writeEntry(Goffset offset, int gen, XRefEntryType type) {
  if (offset >= 0x100000000ll)
    hasOffsetsBeyond4GB = gTrue;
}

void XRef::writeStreamToBuffer(GooString *stmBuf, Dict *xrefDict, XRef *xref) {
  Object index;
  index.initArray(xref);
  stmBuf->clear();

  // First pass: determine whether all offsets fit in 4 bytes or not
  XRefPreScanWriter prescan;
  writeXRef(&prescan, gFalse);
  const int offsetSize = prescan.hasOffsetsBeyond4GB ? sizeof(Goffset) : 4;

  // Second pass: actually write the xref stream
  XRefStreamWriter writer(&index, stmBuf, offsetSize);
  writeXRef(&writer, gFalse);

  Object obj1, obj2;
  xrefDict->set("Type", obj1.initName("XRef"));
  xrefDict->set("Index", &index);
  obj2.initArray(xref);
  obj2.arrayAdd( obj1.initInt(1) );
  obj2.arrayAdd( obj1.initInt(offsetSize) );
  obj2.arrayAdd( obj1.initInt(2) );
  xrefDict->set("W", &obj2);
}

GBool XRef::parseEntry(Goffset offset, XRefEntry *entry)
{
  GBool r;

  Object obj;
  obj.initNull();
  Parser parser = Parser(NULL, new Lexer(NULL,
     str->makeSubStream(offset, gFalse, 20, &obj)), gTrue);

  Object obj1, obj2, obj3;
  if (((parser.getObj(&obj1)->isInt()) ||
       parser.getObj(&obj1)->isInt64()) &&
      (parser.getObj(&obj2)->isInt()) &&
      (parser.getObj(&obj3)->isCmd("n") || obj3.isCmd("f"))) {
    if (obj1.isInt64())
      entry->offset = obj1.getInt64();
    else
      entry->offset = obj1.getInt();
    entry->gen = obj2.getInt();
    entry->type = obj3.isCmd("n") ? xrefEntryUncompressed : xrefEntryFree;
    entry->obj.initNull ();
    entry->flags = 0;
    r = gTrue;
  } else {
    r = gFalse;
  }
  obj1.free();
  obj2.free();
  obj3.free();

  return r;
}

/* Traverse all XRef tables and, if untilEntryNum != -1, stop as soon as
 * untilEntryNum is found, or try to reconstruct the xref table if it's not
 * present in any xref.
 * If xrefStreamObjsNum is not NULL, it is filled with the list of the object
 * numbers of the XRef streams that have been traversed */
void XRef::readXRefUntil(int untilEntryNum, std::vector<int> *xrefStreamObjsNum)
{
  std::vector<Goffset> followedPrev;
  while (prevXRefOffset && (untilEntryNum == -1 || (untilEntryNum < size && entries[untilEntryNum].type == xrefEntryNone))) {
    bool followed = false;
    for (size_t j = 0; j < followedPrev.size(); j++) {
      if (followedPrev.at(j) == prevXRefOffset) {
        followed = true;
        break;
      }
    }
    if (followed) {
      error(errSyntaxError, -1, "Circular XRef");
      if (!(ok = constructXRef(NULL))) {
        errCode = errDamaged;
      }
      break;
    }

    followedPrev.push_back (prevXRefOffset);

    std::vector<Goffset> followedXRefStm;
    if (!readXRef(&prevXRefOffset, &followedXRefStm, xrefStreamObjsNum)) {
        prevXRefOffset = 0;
    }

    // if there was a problem with the xref table, or we haven't found the entry
    // we were looking for, try to reconstruct the xref
    if (!ok || (!prevXRefOffset && untilEntryNum != -1 && entries[untilEntryNum].type == xrefEntryNone)) {
        GBool wasReconstructed = false;
        if (!(ok = constructXRef(&wasReconstructed))) {
            errCode = errDamaged;
            break;
        }
        break;
    }
  }
}

XRefEntry *XRef::getEntry(int i, GBool complainIfMissing)
{
  if (i >= size || entries[i].type == xrefEntryNone) {

    if ((!xRefStream) && mainXRefEntriesOffset) {
      if (!parseEntry(mainXRefEntriesOffset + 20*i, &entries[i])) {
        error(errSyntaxError, -1, "Failed to parse XRef entry [{0:d}].", i);
      }
    } else {
      // Read XRef tables until the entry we're looking for is found
      readXRefUntil(i);
      
      // We might have reconstructed the xref
      // Check again i is in bounds
      if (unlikely(i >= size)) {
        static XRefEntry dummy;
        dummy.offset = 0;
        dummy.gen = -1;
        dummy.type = xrefEntryNone;
        dummy.flags = 0;
        return &dummy;
      }

      if (entries[i].type == xrefEntryNone) {
        if (complainIfMissing) {
          error(errSyntaxError, -1, "Invalid XRef entry");
        }
        entries[i].type = xrefEntryFree;
      }
    }
  }

  return &entries[i];
}

// Recursively sets the Unencrypted flag in all referenced xref entries
void XRef::markUnencrypted(Object *obj) {
  Object obj1;

  switch (obj->getType()) {
    case objArray:
    {
      Array *array = obj->getArray();
      for (int i = 0; i < array->getLength(); i++) {
        markUnencrypted(array->getNF(i, &obj1));
        obj1.free();
      }
      break;
    }
    case objStream:
    case objDict:
    {
      Dict *dict;
      if (obj->getType() == objStream) {
        Stream *stream = obj->getStream();
        dict = stream->getDict();
      } else {
        dict = obj->getDict();
      }
      for (int i = 0; i < dict->getLength(); i++) {
        markUnencrypted(dict->getValNF(i, &obj1));
        obj1.free();
      }
      break;
    }
    case objRef:
    {
      Ref ref = obj->getRef();
      XRefEntry *e = getEntry(ref.num);
      if (e->getFlag(XRefEntry::Unencrypted))
        return; // We've already been here: prevent infinite recursion
      e->setFlag(XRefEntry::Unencrypted, gTrue);
      fetch(ref.num, ref.gen, &obj1);
      markUnencrypted(&obj1);
      obj1.free();
      break;
    }
    default:
      break;
  }
}

void XRef::scanSpecialFlags() {
  if (scannedSpecialFlags) {
    return;
  }
  scannedSpecialFlags = gTrue;

  // "Rewind" the XRef linked list, so that readXRefUntil re-reads all XRef
  // tables/streams, even those that had already been parsed
  prevXRefOffset = mainXRefOffset;

  std::vector<int> xrefStreamObjNums;
  if (!streamEndsLen) { // don't do it for already reconstructed xref
    readXRefUntil(-1 /* read all xref sections */, &xrefStreamObjNums);
  }

  // Mark object streams as DontRewrite, because we write each object
  // individually in full rewrite mode.
  for (int i = 0; i < size; ++i) {
    if (entries[i].type == xrefEntryCompressed) {
      const int objStmNum = entries[i].offset;
      if (unlikely(objStmNum < 0 || objStmNum >= size)) {
        error(errSyntaxError, -1, "Compressed object offset out of xref bounds");
      } else {
        getEntry(objStmNum)->setFlag(XRefEntry::DontRewrite, gTrue);
      }
    }
  }

  // Mark XRef streams objects as Unencrypted and DontRewrite
  for (size_t i = 0; i < xrefStreamObjNums.size(); ++i) {
    const int objNum = xrefStreamObjNums.at(i);
    getEntry(objNum)->setFlag(XRefEntry::Unencrypted, gTrue);
    getEntry(objNum)->setFlag(XRefEntry::DontRewrite, gTrue);
  }

  // Mark objects referred from the Encrypt dict as Unencrypted
  Object obj;
  markUnencrypted(trailerDict.dictLookupNF("Encrypt", &obj));
  obj.free();
}

void XRef::markUnencrypted() {
  // Mark objects referred from the Encrypt dict as Unencrypted
  Object obj;
  trailerDict.dictLookupNF("Encrypt", &obj);
  if (obj.isRef()) {
    XRefEntry *e = getEntry(obj.getRefNum());
    e->setFlag(XRefEntry::Unencrypted, gTrue);
  }
  obj.free();
}

