//========================================================================
//
// 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, 2016-2018 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, 2017 Adrian Johnson <ajohnson@redneon.com>
// Copyright (C) 2013 Pino Toscano <pino@kde.org>
// Copyright (C) 2016 Jakub Alba <jakubalba@gmail.com>
// Copyright (C) 2018 Adam Reichold <adam.reichold@t-online.de>
// Copyright (C) 2018 Tobias Deiminger <haxtibal@posteo.de>
//
// 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>
#include "poppler-config.h"

#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"

//------------------------------------------------------------------------
// 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

//------------------------------------------------------------------------
// 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();

  ObjectStream(const ObjectStream &) = delete;
  ObjectStream& operator=(const ObjectStream &) = delete;

  // 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);

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;
};

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

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

  objStr = xref->fetch(objStrNum, 0, recursion);
  if (!objStr.isStream()) {
    return;
  }

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

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

  // 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");
    return;
  }
  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();
  str = new EmbedStream(objStr.getStream(), Object(objNull), gTrue, first);
  parser = new Parser(xref, new Lexer(xref, str), gFalse);
  for (i = 0; i < nObjects; ++i) {
    obj1 = parser->getObj();
    Object obj2 = parser->getObj();
    if (!obj1.isInt() || !(obj2.isInt() || obj2.isInt64())) {
      delete parser;
      gfree(offsets);
      return;
    }
    objNums[i] = obj1.getInt();
    if (obj2.isInt())
      offsets[i] = obj2.getInt();
    else
      offsets[i] = obj2.getInt64();
    if (objNums[i] < 0 || offsets[i] < 0 ||
	(i > 0 && offsets[i] < offsets[i-1])) {
      delete parser;
      gfree(offsets);
      return;
    }
  }
  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) {
    if (i == nObjects - 1) {
      str = new EmbedStream(objStr.getStream(), Object(objNull), gFalse, 0);
    } else {
      str = new EmbedStream(objStr.getStream(), Object(objNull), gTrue,
			    offsets[i+1] - offsets[i]);
    }
    parser = new Parser(xref, new Lexer(xref, str), gFalse);
    objs[i] = parser->getObj();
    while (str->getChar() != EOF) ;
    delete parser;
  }

  gfree(offsets);
  ok = gTrue;
}

ObjectStream::~ObjectStream() {
  delete[] objs;
  gfree(objNums);
}

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

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

#define xrefLocker()   std::unique_lock<std::recursive_mutex> locker(mutex)

XRef::XRef() : objStrs{5} {
  ok = gTrue;
  errCode = errNone;
  entries = nullptr;
  capacity = 0;
  size = 0;
  modified = gFalse;
  streamEnds = nullptr;
  streamEndsLen = 0;
  mainXRefEntriesOffset = 0;
  xRefStream = gFalse;
  scannedSpecialFlags = gFalse;
  encrypted = gFalse;
  permFlags = defPermFlags;
  ownerPasswordOk = gFalse;
  rootNum = -1;
  strOwner = gFalse;
  xrefReconstructed = gFalse;
  encAlgorithm = cryptNone;
}

XRef::XRef(const Object *trailerDictA) : XRef{} {
  if (trailerDictA->isDict())
    trailerDict = trailerDictA->copy();
}

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

  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, nullptr);

      // 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
    obj = trailerDict.dictLookupNF("Size");
    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))) {
               errCode = errDamaged;
               return;
            }
         }
      }
    }

    // get the root dictionary (catalog) object
    obj = trailerDict.dictLookupNF("Root");
    if (obj.isRef()) {
      rootNum = obj.getRefNum();
      rootGen = obj.getRefGen();
    } else {
      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.~Object();
  }
  gfree(entries);

  if (streamEnds) {
    gfree(streamEnds);
  }
  if (strOwner) {
    delete str;
  }
}

XRef *XRef::copy() const {
  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;
  xref->trailerDict = trailerDict.copy();
  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 nullptr;
  }
  xref->size = size;
  for (int i = 0; i < size; ++i) {
    xref->entries[i].offset = entries[i].offset;
    xref->entries[i].type = entries[i].type;
    new (&xref->entries[i].obj) Object(objNull);
    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 == nullptr) {
      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;
      new (&entries[i].obj) Object(objNull);
      entries[i].flags = 0;
      entries[i].gen = 0;
    }
  } else {
    for (int i = newSize; i < size; i++) {
      entries[i].obj.~Object();
    }
  }

  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;

  if (unlikely(start > (LLONG_MAX - *pos))) {
    ok = gFalse;
    return gFalse;
  }

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

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

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

  } else {
    goto err1;
  }

  delete parser;
  return more;

 err1:
  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;

  while (1) {
    obj = parser->getObj(gTrue);
    if (obj.isCmd("trailer")) {
      break;
    }
    if (!obj.isInt()) {
      goto err0;
    }
    first = obj.getInt();
    obj = parser->getObj(gTrue);
    if (!obj.isInt()) {
      goto err0;
    }
    n = obj.getInt();
    if (first < 0 || n < 0 || first > INT_MAX - n) {
      goto err0;
    }
    if (first + n > size) {
      if (resize(first + n) != first + n) {
        error(errSyntaxError, -1, "Invalid 'obj' parameters'");
        goto err0;
      }
    }
    for (int i = first; i < first + n; ++i) {
      obj = parser->getObj(gTrue);
      if (obj.isInt()) {
	entry.offset = obj.getInt();
      } else if (obj.isInt64()) {
	entry.offset = obj.getInt64();
      } else {
	goto err0;
      }
      obj = parser->getObj(gTrue);
      if (!obj.isInt()) {
	goto err0;
      }
      entry.gen = obj.getInt();
      entry.flags = 0;
      obj = parser->getObj(gTrue);
      if (obj.isCmd("n")) {
	entry.type = xrefEntryUncompressed;
      } else if (obj.isCmd("f")) {
	entry.type = xrefEntryFree;
      } else {
	goto err0;
      }
      if (entries[i].offset == -1) {
	entries[i].offset = entry.offset;
	entries[i].gen = entry.gen;
	entries[i].type = entry.type;
	entries[i].flags = entry.flags;
	entries[i].obj.setToNull();

	// 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].offset = 0;
	  entries[0].gen = 65535;
	  entries[0].type = xrefEntryFree;
	  entries[0].flags = entries[1].flags;
	  entries[0].obj = std::move(entries[1].obj);

	  entries[1].offset = -1;
	  entries[1].obj.setToNull();
	}
      }
    }
  }

  // read the trailer dictionary
  obj = parser->getObj();
  if (!obj.isDict()) {
    goto err0;
  }

  // get the 'Prev' pointer
  obj2 = obj.getDict()->lookupNF("Prev");
  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;
  }

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

  // check for an 'XRefStm' key
  obj2 = obj.getDict()->lookup("XRefStm");
  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) {
      goto err0;
    }
  }

  return more;

 err0:
  ok = gFalse;
  return gFalse;
}

GBool XRef::readXRefStream(Stream *xrefStr, Goffset *pos) {
  int w[3];
  GBool more;
  Object obj;

  ok = gFalse;

  Dict *dict = xrefStr->getDict();
  obj = dict->lookupNF("Size");
  if (!obj.isInt()) {
    return gFalse;
  }
  int newSize = obj.getInt();
  if (newSize < 0) {
    return gFalse;
  }
  if (newSize > size) {
    if (resize(newSize) != newSize) {
      error(errSyntaxError, -1, "Invalid 'size' parameter");
      return gFalse;
    }
  }

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

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

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

  ok = gTrue;
  return more;
}

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

  if (first > INT_MAX - n) {
    return gFalse;
  }
  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 (gen > INT_MAX) {
      error(errSyntaxError, -1, "Gen inside xref table too large (bigger than INT_MAX)");
      return gFalse;
    }
    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.
// Warning: Reconstruction of files where last XRef section is a stream
//          or where some objects are defined inside an object stream is not yet supported.
//          Existing data in XRef::entries may get corrupted if applied anyway.
GBool XRef::constructXRef(GBool *wasReconstructed, GBool needCatalogDict) {
  Parser *parser;
  Object obj;
  char buf[256];
  Goffset pos;
  int num, gen;
  int streamEndsSize;
  char *p;
  GBool gotRoot;
  char* token = nullptr;
  bool oneCycle = true;
  int offset = 0;

  resize(0); // free entries properly
  gfree(entries);
  capacity = 0;
  size = 0;
  entries = nullptr;

  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)) {
        parser = new Parser(nullptr,
		 new Lexer(nullptr,
		   str->makeSubStream(pos + 7, gFalse, 0, Object(objNull))),
		 gFalse);
        Object newTrailerDict = parser->getObj();
        if (newTrailerDict.isDict()) {
	  obj = newTrailerDict.dictLookupNF("Root");
	  if (obj.isRef() && (!gotRoot || !needCatalogDict) && rootNum != obj.getRefNum()) {
	    rootNum = obj.getRefNum();
	    rootGen = obj.getRefGen();
	    trailerDict = newTrailerDict.copy();
	    gotRoot = gTrue;
	  }
        }
        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;
          } else {
	    ++p;
	  }
	  while (*p && isspace(*p & 0xff)) ++p;
	  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;
              } else {
		++p;
	      }
	      while (*p && isspace(*p & 0xff)) ++p;
	      if (!strncmp(p, "obj", 3)) {
		if (num >= size) {
		  if (unlikely(num >= INT_MAX - 1 - 255)) {
		    error(errSyntaxError, -1, "Bad object number");
		    return gFalse;
		  }
		  const int 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 {
	char *endstream = strstr( p, "endstream" );
	if (endstream) {
	  int endstreamPos = endstream - p;
	  if ((endstreamPos == 0 || Lexer::isSpace(p[endstreamPos-1] & 0xff)) // endstream is either at beginning or preceeded by space
	    && (endstreamPos + 9 >= 256 || Lexer::isSpace(p[endstreamPos+9] & 0xff))) // endstream is either at end or followed by space
	  {
	    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 + endstreamPos;
	  }
	}
      }
      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,
			 const 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 = nullptr;
    *encAlgorithmA = cryptRC4;
    *keyLengthA = 0;
  }
}

GBool XRef::okToPrint(GBool ignoreOwnerPW) const {
  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) const {
  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) const {
  return (!ignoreOwnerPW && ownerPasswordOk) || (permFlags & permChange);
}

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

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

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

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

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

Object XRef::getCatalog() {
  Object catalog = fetch(rootNum, rootGen);
  if (catalog.isDict()) {
    return catalog;
  }
  GBool wasReconstructed = false;
  if (constructXRef(&wasReconstructed, gTrue)) {
    catalog = fetch(rootNum, rootGen);
  }
  return catalog;
}

Object XRef::fetch(int num, int gen, 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
    return e->obj.copy();
  }

  switch (e->type) {

  case xrefEntryUncompressed:
  {
    if (e->gen != gen || e->offset < 0) {
      goto err;
    }
    parser = new Parser(this,
	       new Lexer(this,
		 str->makeSubStream(start + e->offset, gFalse, 0, Object(objNull))),
	       gTrue);
    obj1 = parser->getObj(recursion);
    obj2 = parser->getObj(recursion);
    obj3 = parser->getObj(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()) {
	const 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);
	    delete parser;
	    return Object(number);
	  }
	}
      }
      delete parser;
      goto err;
    }
    Object obj = parser->getObj(gFalse, (encrypted && !e->getFlag(XRefEntry::Unencrypted)) ? fileKey : nullptr,
		   encAlgorithm, keyLength, num, gen, recursion);
    delete parser;
    return obj;
  }

  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 = objStrs.lookup(e->offset);
    if (!objStr) {
      objStr = new ObjectStream(this, e->offset, recursion + 1);
      if (!objStr->isOk()) {
	delete objStr;
	objStr = nullptr;
	goto err;
      } else {
	// XRef could be reconstructed in constructor of ObjectStream:
	e = getEntry(num);
	objStrs.put(e->offset, objStr);
      }
    }
    return objStr->getObject(e->gen, num);
  }

  default:
    goto err;
  }
  
 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, ++recursion);
  }
  return Object(objNull);
}

void XRef::lock() {
  mutex.lock();
}

void XRef::unlock() {
  mutex.unlock();
}

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

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

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

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

  obj = Object(new Dict(this));
  const Ref ref = addIndirectObject(&obj);
  trailerDict.dictSet("Info", Object(ref.num, ref.gen));

  return obj;
}

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

  trailerDict.dictRemove("Info");

  removeIndirectObject(infoObjRef.getRef());
}

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;
      new (&entries[i].obj) Object(objNull);
      entries[i].flags = 0;
      entries[i].gen = 0;
    }
    size = num + 1;
  }
  XRefEntry *e = getEntry(num);
  e->gen = gen;
  e->obj.setToNull();
  e->flags = 0;
  if (used) {
    e->type = xrefEntryUncompressed;
    e->offset = offs;
  } else {
    e->type = xrefEntryFree;
    e->offset = 0;
  }
}

void XRef::setModifiedObject (const 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 = o->copy();
  e->setFlag(XRefEntry::Updated, gTrue);
  setModified();
}

Ref XRef::addIndirectObject (const 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;
  e->obj = o->copy();
  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.~Object();
  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(Array *indexA, GooString *stmBufA, int offsetSizeA) {
  index = indexA;
  stmBuf = stmBufA;
  offsetSize = offsetSizeA;
}

void XRef::XRefStreamWriter::startSection(int first, int count) {
  index->add( Object(first) );
  index->add( Object(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) {
  Array *index = new Array(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);

  xrefDict->set("Type", Object(objName, "XRef"));
  xrefDict->set("Index", Object(index));
  Array *wArray = new Array(xref);
  wArray->add( Object(1) );
  wArray->add( Object(offsetSize) );
  wArray->add( Object(2) );
  xrefDict->set("W", Object(wArray));
}

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

  if (unlikely(entry == nullptr))
    return gFalse;

  Parser parser(nullptr, new Lexer(nullptr,
     str->makeSubStream(offset, gFalse, 20, Object(objNull))), gTrue);

  Object obj1, obj2, obj3;
  if (((obj1 = parser.getObj(), obj1.isInt()) || obj1.isInt64()) &&
      (obj2 = parser.getObj(), obj2.isInt()) &&
      (obj3 = 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.setToNull();
    entry->flags = 0;
    r = gTrue;
  } else {
    r = gFalse;
  }

  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 (!xRefStream && !(ok = constructXRef(nullptr))) {
        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)) {
        if (!xRefStream && !(ok = constructXRef(nullptr))) {
            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 {0:d}", i);
        }
        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++) {
	obj1 = array->getNF(i);
        markUnencrypted(&obj1);
      }
      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++) {
	obj1 = dict->getValNF(i);
        markUnencrypted(&obj1);
      }
      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);
      obj1 = fetch(ref.num, ref.gen);
      markUnencrypted(&obj1);
      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
  markUnencrypted();
}

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

