//========================================================================
//
// Hints.cc
//
// This file is licensed under the GPLv2 or later
//
// Copyright 2010, 2012 Hib Eris <hib@hiberis.nl>
// Copyright 2010, 2011, 2013, 2014, 2016-2018 Albert Astals Cid <aacid@kde.org>
// Copyright 2010, 2013 Pino Toscano <pino@kde.org>
// Copyright 2013 Adrian Johnson <ajohnson@redneon.com>
// Copyright 2014 Fabio D'Urso <fabiodurso@hotmail.it>
// Copyright 2016 Jeffrey Morlan <jmmorlan@sonic.net>
//
//========================================================================

#include <config.h>

#include "Hints.h"

#include "Linearization.h"
#include "Object.h"
#include "Stream.h"
#include "XRef.h"
#include "Parser.h"
#include "Lexer.h"
#include "SecurityHandler.h"

#include <limits.h>

class StreamBitReader {
public:
  StreamBitReader(Stream *strA)
    : str(strA)
    , inputBits(0)
    , isAtEof(gFalse)
  {
  }

  void resetInputBits()
  {
    inputBits = 0;
  }

  GBool atEOF() const
  {
    return isAtEof;
  }

  Guint readBit()
  {
    Guint bit;
    int c;

    if (inputBits == 0) {
      if ((c = str->getChar()) == EOF) {
        isAtEof = gTrue;
        return (Guint) -1;
      }
      bitsBuffer = c;
      inputBits = 8;
    }
    bit = (bitsBuffer >> (inputBits - 1)) & 1;
    --inputBits;
    return bit;
  }

  Guint readBits(int n)
  {
    Guint bit, bits;

    if (n < 0) return -1;
    if (n == 0) return 0;

    if (n == 1)
      return readBit();

    bit = readBit();
    if (bit == (Guint) -1)
      return -1;

    bit = bit << (n-1);

    bits = readBits(n - 1);
    if (bits == (Guint) -1)
      return -1;

    return bit | bits;
  }

private:
  Stream *str;
  int inputBits;
  char bitsBuffer;
  GBool isAtEof;
};

//------------------------------------------------------------------------
// Hints
//------------------------------------------------------------------------

Hints::Hints(BaseStream *str, Linearization *linearization, XRef *xref, SecurityHandler *secHdlr)
{
  mainXRefEntriesOffset = linearization->getMainXRefEntriesOffset();
  nPages = linearization->getNumPages();
  pageFirst = linearization->getPageFirst();
  pageEndFirst = linearization->getEndFirst();
  pageObjectFirst = linearization->getObjectNumberFirst();
  if (pageObjectFirst < 0 || pageObjectFirst >= xref->getNumObjects()) {
    error(errSyntaxWarning, -1,
      "Invalid reference for first page object ({0:d}) in linearization table ",
      pageObjectFirst);
    pageObjectFirst = 0;
  }
  XRefEntry *pageObjectFirstXRefEntry = xref->getEntry(pageObjectFirst);
  if (!pageObjectFirstXRefEntry) {
      error(errSyntaxWarning, -1, "No XRef entry for first page object");
      pageOffsetFirst = 0;
  } else {
      pageOffsetFirst = pageObjectFirstXRefEntry->offset;
  }

  if (nPages >= INT_MAX / (int)sizeof(Guint)) {
     error(errSyntaxWarning, -1, "Invalid number of pages ({0:d}) for hints table", nPages);
     nPages = 0;
  }
  nObjects = (Guint *) gmallocn_checkoverflow(nPages, sizeof(Guint));
  pageObjectNum = (int *) gmallocn_checkoverflow(nPages, sizeof(int));
  xRefOffset = (Guint *) gmallocn_checkoverflow(nPages, sizeof(Guint));
  pageLength = (Guint *) gmallocn_checkoverflow(nPages, sizeof(Guint));
  pageOffset = (Goffset *) gmallocn_checkoverflow(nPages, sizeof(Goffset));
  numSharedObject = (Guint *) gmallocn_checkoverflow(nPages, sizeof(Guint));
  sharedObjectId = (Guint **) gmallocn_checkoverflow(nPages, sizeof(Guint*));
  if (!nObjects || !pageObjectNum || !xRefOffset || !pageLength || !pageOffset ||
      !numSharedObject || !sharedObjectId) {
    error(errSyntaxWarning, -1, "Failed to allocate memory for hints table");
    nPages = 0;
  }

  memset(pageLength, 0, nPages * sizeof(Guint));
  memset(pageOffset, 0, nPages * sizeof(Guint));
  memset(numSharedObject, 0, nPages * sizeof(Guint));
  memset(pageObjectNum, 0, nPages * sizeof(int));

  groupLength = nullptr;
  groupOffset = nullptr;
  groupHasSignature = nullptr;
  groupNumObjects = nullptr;
  groupXRefOffset = nullptr;

  ok = gTrue;
  readTables(str, linearization, xref, secHdlr);
}

Hints::~Hints()
{
  gfree(nObjects);
  gfree(pageObjectNum);
  gfree(xRefOffset);
  gfree(pageLength);
  gfree(pageOffset);
  for (int i=0; i< nPages; i++) {
    if (numSharedObject[i]) {
       gfree(sharedObjectId[i]);
    }
  }
  gfree(sharedObjectId);
  gfree(numSharedObject);

  gfree(groupLength);
  gfree(groupOffset);
  gfree(groupHasSignature);
  gfree(groupNumObjects);
  gfree(groupXRefOffset);
}

void Hints::readTables(BaseStream *str, Linearization *linearization, XRef *xref, SecurityHandler *secHdlr)
{
  hintsOffset = linearization->getHintsOffset();
  hintsLength = linearization->getHintsLength();
  hintsOffset2 = linearization->getHintsOffset2();
  hintsLength2 = linearization->getHintsLength2();

  Parser *parser;

  int bufLength = hintsLength + hintsLength2;

  std::vector<char> buf(bufLength);
  char *p = &buf[0];

  Stream *s = str->makeSubStream(hintsOffset, gFalse, hintsLength, Object(objNull));
  s->reset();
  for (Guint i=0; i < hintsLength; i++) { *p++ = s->getChar(); }
  delete s;

  if (hintsOffset2 && hintsLength2) {
    s = str->makeSubStream(hintsOffset2, gFalse, hintsLength2, Object(objNull));
    s->reset();
    for (Guint i=0; i < hintsLength2; i++) { *p++ = s->getChar(); }
    delete s;
  }

  MemStream *memStream = new MemStream (&buf[0], 0, bufLength, Object(objNull));

  parser = new Parser(xref, new Lexer(xref, memStream), gTrue);

  int num, gen;
  Object obj;
  if ((obj = parser->getObj(), obj.isInt()) &&
     (num = obj.getInt(), obj = parser->getObj(), obj.isInt()) &&
     (gen = obj.getInt(), obj = parser->getObj(), obj.isCmd("obj")) &&
     (obj = parser->getObj(gFalse,
         secHdlr ? secHdlr->getFileKey() : (Guchar *)nullptr,
         secHdlr ? secHdlr->getEncAlgorithm() : cryptRC4,
         secHdlr ? secHdlr->getFileKeyLength() : 0,
         num, gen, 0, gTrue), obj.isStream())) {
    Stream *hintsStream = obj.getStream();
    Dict *hintsDict = obj.streamGetDict();

    int sharedStreamOffset = 0;
    if (hintsDict->lookupInt("S", nullptr, &sharedStreamOffset) &&
        sharedStreamOffset > 0) {

        hintsStream->reset();
        ok = readPageOffsetTable(hintsStream);

        if (ok) {
          hintsStream->reset();
          for (int i=0; i<sharedStreamOffset; i++) hintsStream->getChar();
          ok = readSharedObjectsTable(hintsStream);
        }
    } else {
      error(errSyntaxWarning, -1, "Invalid shared object hint table offset");
    }
  } else {
    error(errSyntaxWarning, -1, "Failed parsing hints table object");
  }

  delete parser;
}

GBool Hints::readPageOffsetTable(Stream *str)
{
  if (nPages < 1) {
    error(errSyntaxWarning, -1, "Invalid number of pages reading page offset hints table");
    return gFalse;
  }

  StreamBitReader sbr(str);

  nObjectLeast = sbr.readBits(32);
  if (nObjectLeast < 1) {
    error(errSyntaxWarning, -1, "Invalid least number of objects reading page offset hints table");
    nPages = 0;
    return gFalse;
  }

  objectOffsetFirst = sbr.readBits(32);
  if (objectOffsetFirst >= hintsOffset) objectOffsetFirst += hintsLength;

  nBitsDiffObjects = sbr.readBits(16);
  if (nBitsDiffObjects > 32) {
    error(errSyntaxWarning, -1, "Invalid number of bits needed to represent the difference between the greatest and least number of objects in a page");
    nPages = 0;
    return gFalse;
  }

  pageLengthLeast = sbr.readBits(32);

  nBitsDiffPageLength = sbr.readBits(16);

  OffsetStreamLeast = sbr.readBits(32);

  nBitsOffsetStream = sbr.readBits(16);

  lengthStreamLeast = sbr.readBits(32);

  nBitsLengthStream = sbr.readBits(16);

  nBitsNumShared = sbr.readBits(16);

  nBitsShared = sbr.readBits(16);

  nBitsNumerator = sbr.readBits(16);

  denominator = sbr.readBits(16);

  for (int i = 0; i < nPages && !sbr.atEOF(); i++) {
    nObjects[i] = nObjectLeast + sbr.readBits(nBitsDiffObjects);
  }
  if (sbr.atEOF())
    return gFalse;

  nObjects[0] = 0;
  xRefOffset[0] = mainXRefEntriesOffset + 20;
  for (int i=1; i<nPages; i++) {
    xRefOffset[i] = xRefOffset[i-1] + 20*nObjects[i-1];
  }

  pageObjectNum[0] = 1;
  for (int i=1; i<nPages; i++) {
    pageObjectNum[i] = pageObjectNum[i-1] + nObjects[i-1];
  }
  pageObjectNum[0] = pageObjectFirst;

  sbr.resetInputBits(); // reset on byte boundary. Not in specs!
  for (int i = 0; i < nPages && !sbr.atEOF(); i++) {
    pageLength[i] = pageLengthLeast + sbr.readBits(nBitsDiffPageLength);
  }
  if (sbr.atEOF())
    return gFalse;

  sbr.resetInputBits(); // reset on byte boundary. Not in specs!
  numSharedObject[0] = sbr.readBits(nBitsNumShared);
  numSharedObject[0] = 0; // Do not trust the read value to be 0.
  sharedObjectId[0] = nullptr;
  for (int i = 1; i < nPages && !sbr.atEOF(); i++) {
    numSharedObject[i] = sbr.readBits(nBitsNumShared);
    if (numSharedObject[i] >= INT_MAX / (int)sizeof(Guint)) {
       error(errSyntaxWarning, -1, "Invalid number of shared objects");
       numSharedObject[i] = 0;
       return gFalse;
    }
    sharedObjectId[i] = (Guint *) gmallocn_checkoverflow(numSharedObject[i], sizeof(Guint));
    if (numSharedObject[i] && !sharedObjectId[i]) {
       error(errSyntaxWarning, -1, "Failed to allocate memory for shared object IDs");
       numSharedObject[i] = 0;
       return gFalse;
    }
  }
  if (sbr.atEOF())
    return gFalse;

  sbr.resetInputBits(); // reset on byte boundary. Not in specs!
  for (int i=1; i<nPages; i++) {
    for (Guint j = 0; j < numSharedObject[i] && !sbr.atEOF(); j++) {
      sharedObjectId[i][j] = sbr.readBits(nBitsShared);
    }
  }

  pageOffset[0] = pageOffsetFirst;
  // find pageOffsets.
  for (int i=1; i<nPages; i++) {
    pageOffset[i] = pageOffset[i-1] + pageLength[i-1];
  }

  return !sbr.atEOF();
}

GBool Hints::readSharedObjectsTable(Stream *str)
{
  StreamBitReader sbr(str);

  const Guint firstSharedObjectNumber = sbr.readBits(32);

  const Guint firstSharedObjectOffset = sbr.readBits(32) + hintsLength;

  const Guint nSharedGroupsFirst = sbr.readBits(32);

  const Guint nSharedGroups = sbr.readBits(32);

  const Guint nBitsNumObjects = sbr.readBits(16);

  const Guint groupLengthLeast = sbr.readBits(32);

  const Guint nBitsDiffGroupLength = sbr.readBits(16);

  if ((!nSharedGroups) || (nSharedGroups >= INT_MAX / (int)sizeof(Guint))) {
     error(errSyntaxWarning, -1, "Invalid number of shared object groups");
     return gFalse;
  }
  if ((!nSharedGroupsFirst) || (nSharedGroupsFirst > nSharedGroups)) {
     error(errSyntaxWarning, -1, "Invalid number of first page shared object groups");
     return gFalse;
  }
  if (nBitsNumObjects > 32 || nBitsDiffGroupLength > 32) {
     error(errSyntaxWarning, -1, "Invalid shared object groups bit length");
     return gFalse;
  }

  groupLength = (Guint *) gmallocn_checkoverflow(nSharedGroups, sizeof(Guint));
  groupOffset = (Guint *) gmallocn_checkoverflow(nSharedGroups, sizeof(Guint));
  groupHasSignature = (Guint *) gmallocn_checkoverflow(nSharedGroups, sizeof(Guint));
  groupNumObjects = (Guint *) gmallocn_checkoverflow(nSharedGroups, sizeof(Guint));
  groupXRefOffset = (Guint *) gmallocn_checkoverflow(nSharedGroups, sizeof(Guint));
  if (!groupLength || !groupOffset || !groupHasSignature ||
      !groupNumObjects || !groupXRefOffset) {
     error(errSyntaxWarning, -1, "Failed to allocate memory for shared object groups");
     return gFalse;
  }

  sbr.resetInputBits(); // reset on byte boundary. Not in specs!
  for (Guint i = 0; i < nSharedGroups && !sbr.atEOF(); i++) {
    groupLength[i] = groupLengthLeast + sbr.readBits(nBitsDiffGroupLength);
  }
  if (sbr.atEOF())
    return gFalse;

  groupOffset[0] = objectOffsetFirst;
  for (Guint i=1; i<nSharedGroupsFirst; i++) {
    groupOffset[i] = groupOffset[i-1] + groupLength[i-1];
  }
  if (nSharedGroups > nSharedGroupsFirst ) {
    groupOffset[nSharedGroupsFirst] = firstSharedObjectOffset;
    for (Guint i=nSharedGroupsFirst+1; i<nSharedGroups; i++) {
      groupOffset[i] = groupOffset[i-1] + groupLength[i-1];
    }
  }

  sbr.resetInputBits(); // reset on byte boundary. Not in specs!
  for (Guint i = 0; i < nSharedGroups && !sbr.atEOF(); i++) {
    groupHasSignature[i] = sbr.readBits(1);
  }
  if (sbr.atEOF())
    return gFalse;

  sbr.resetInputBits(); // reset on byte boundary. Not in specs!
  for (Guint i = 0; i < nSharedGroups && !sbr.atEOF(); i++) {
    if (groupHasSignature[i]) {
       sbr.readBits(128);
    }
  }
  if (sbr.atEOF())
    return gFalse;

  sbr.resetInputBits(); // reset on byte boundary. Not in specs!
  for (Guint i = 0; i < nSharedGroups && !sbr.atEOF(); i++) {
    groupNumObjects[i] =
       nBitsNumObjects ? 1 + sbr.readBits(nBitsNumObjects) : 1;
  }

  for (Guint i=0; i<nSharedGroupsFirst; i++) {
    groupNumObjects[i] = 0;
    groupXRefOffset[i] = 0;
  }
  if (nSharedGroups > nSharedGroupsFirst ) {
    groupXRefOffset[nSharedGroupsFirst] =
        mainXRefEntriesOffset + 20*firstSharedObjectNumber;
    for (Guint i=nSharedGroupsFirst+1; i<nSharedGroups; i++) {
      groupXRefOffset[i] = groupXRefOffset[i-1] + 20*groupNumObjects[i-1];
    }
  }

  return !sbr.atEOF();
}

GBool Hints::isOk() const
{
  return ok;
}

Goffset Hints::getPageOffset(int page)
{
  if ((page < 1) || (page > nPages)) return 0;

  if (page-1 > pageFirst)
    return pageOffset[page-1];
  else if (page-1 < pageFirst)
    return pageOffset[page];
  else
    return pageOffset[0];
}

std::vector<ByteRange>* Hints::getPageRanges(int page)
{
  if ((page < 1) || (page > nPages)) return nullptr;

  int idx;
  if (page-1 > pageFirst)
     idx = page-1;
  else if (page-1 < pageFirst)
     idx = page;
  else
     idx = 0;

  ByteRange pageRange;
  std::vector<ByteRange> *v = new std::vector<ByteRange>;

  pageRange.offset = pageOffset[idx];
  pageRange.length = pageLength[idx];
  v->push_back(pageRange);

  pageRange.offset = xRefOffset[idx];
  pageRange.length = 20*nObjects[idx];
  v->push_back(pageRange);

  for (Guint j=0; j<numSharedObject[idx]; j++) {
     Guint k = sharedObjectId[idx][j];

     pageRange.offset = groupOffset[k];
     pageRange.length = groupLength[k];
     v->push_back(pageRange);

     pageRange.offset = groupXRefOffset[k];
     pageRange.length = 20*groupNumObjects[k];
     v->push_back(pageRange);
  }

  return v;
}

int Hints::getPageObjectNum(int page) {
  if ((page < 1) || (page > nPages)) return 0;

  if (page-1 > pageFirst)
    return pageObjectNum[page-1];
  else if (page-1 < pageFirst)
    return pageObjectNum[page];
  else
    return pageObjectNum[0];
}
