//========================================================================
//
// FoFiIdentifier.cc
//
// Copyright 2009 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) 2013 Christoph Duelli <duelli@melosgmbh.de>
// Copyright (C) 2018 Albert Astals Cid <aacid@kde.org>
// Copyright (C) 2019 Christian Persch <chpe@src.gnome.org>
// Copyright (C) 2019 LE GARREC Vincent <legarrec.vincent@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 <stdio.h>
#include <string.h>
#include <limits.h>
#include "goo/gfile.h"
#include "goo/GooCheckedOps.h"
#include "FoFiIdentifier.h"

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

namespace { // do not pollute global namespace

class Reader {
public:
  Reader() = default;
  Reader(const Reader &) = delete;
  Reader& operator=(const Reader &other) = delete;

  virtual ~Reader() {}

  // Read one byte.  Returns -1 if past EOF.
  virtual int getByte(int pos) = 0;

  // Read a big-endian unsigned 16-bit integer.  Fills in *val and
  // returns true if successful.
  virtual bool getU16BE(int pos, int *val) = 0;

  // Read a big-endian unsigned 32-bit integer.  Fills in *val and
  // returns true if successful.
  virtual bool getU32BE(int pos, unsigned int *val) = 0;

  // Read a little-endian unsigned 32-bit integer.  Fills in *val and
  // returns true if successful.
  virtual bool getU32LE(int pos, unsigned int *val) = 0;

  // Read a big-endian unsigned <size>-byte integer, where 1 <= size
  // <= 4.  Fills in *val and returns true if successful.
  virtual bool getUVarBE(int pos, int size, unsigned int *val) = 0;

  // Compare against a string.  Returns true if equal.
  virtual bool cmp(int pos, const char *s) = 0;

};

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

class MemReader: public Reader {
public:

  static MemReader *make(const char *bufA, int lenA);
  ~MemReader();
  int getByte(int pos) override;
  bool getU16BE(int pos, int *val) override;
  bool getU32BE(int pos, unsigned int *val) override;
  bool getU32LE(int pos, unsigned int *val) override;
  bool getUVarBE(int pos, int size, unsigned int *val) override;
  bool cmp(int pos, const char *s) override;

private:

  MemReader(const char *bufA, int lenA);

  const char *buf;
  int len;
};

MemReader *MemReader::make(const char *bufA, int lenA) {
  return new MemReader(bufA, lenA);
}

MemReader::MemReader(const char *bufA, int lenA) {
  buf = bufA;
  len = lenA;
}

MemReader::~MemReader() {
}

int MemReader::getByte(int pos) {
  if (pos < 0 || pos >= len) {
    return -1;
  }
  return buf[pos] & 0xff;
}

bool MemReader::getU16BE(int pos, int *val) {
  if (pos < 0 || pos > len - 2) {
    return false;
  }
  *val = ((buf[pos] & 0xff) << 8) +
         (buf[pos+1] & 0xff);
  return true;
}

bool MemReader::getU32BE(int pos, unsigned int *val) {
  if (pos < 0 || pos > len - 4) {
    return false;
  }
  *val = ((buf[pos] & 0xff) << 24) +
         ((buf[pos+1] & 0xff) << 16) +
         ((buf[pos+2] & 0xff) << 8) +
         (buf[pos+3] & 0xff);
  return true;
}

bool MemReader::getU32LE(int pos, unsigned int *val) {
  if (pos < 0 || pos > len - 4) {
    return false;
  }
  *val = (buf[pos] & 0xff) +
         ((buf[pos+1] & 0xff) << 8) +
         ((buf[pos+2] & 0xff) << 16) +
         ((buf[pos+3] & 0xff) << 24);
  return true;
}

bool MemReader::getUVarBE(int pos, int size, unsigned int *val) {
  int i;

  if (size < 1 || size > 4 || pos < 0 || pos > len - size) {
    return false;
  }
  *val = 0;
  for (i = 0; i < size; ++i) {
    *val = (*val << 8) + (buf[pos + i] & 0xff);
  }
  return true;
}

bool MemReader::cmp(int pos, const char *s) {
  int n;

  n = (int)strlen(s);
  if (pos < 0 || len < n || pos > len - n) {
    return false;
  }
  return !memcmp(buf + pos, s, n);
}

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

class FileReader: public Reader {
public:

  static FileReader *make(const char *fileName);
  ~FileReader();
  int getByte(int pos) override;
  bool getU16BE(int pos, int *val) override;
  bool getU32BE(int pos, unsigned int *val) override;
  bool getU32LE(int pos, unsigned int *val) override;
  bool getUVarBE(int pos, int size, unsigned int *val) override;
  bool cmp(int pos, const char *s) override;

private:

  FileReader(FILE *fA);
  bool fillBuf(int pos, int len);

  FILE *f;
  char buf[1024];
  int bufPos, bufLen;
};

FileReader *FileReader::make(const char *fileName) {
  FILE *fA;

  if (!(fA = openFile(fileName, "rb"))) {
    return nullptr;
  }
  return new FileReader(fA);
}

FileReader::FileReader(FILE *fA) {
  f = fA;
  bufPos = 0;
  bufLen = 0;
}

FileReader::~FileReader() {
  fclose(f);
}

int FileReader::getByte(int pos) {
  if (!fillBuf(pos, 1)) {
    return -1;
  }
  return buf[pos - bufPos] & 0xff;
}

bool FileReader::getU16BE(int pos, int *val) {
  if (!fillBuf(pos, 2)) {
    return false;
  }
  *val = ((buf[pos - bufPos] & 0xff) << 8) +
         (buf[pos - bufPos + 1] & 0xff);
  return true;
}

bool FileReader::getU32BE(int pos, unsigned int *val) {
  if (!fillBuf(pos, 4)) {
    return false;
  }
  *val = ((buf[pos - bufPos] & 0xff) << 24) +
         ((buf[pos - bufPos + 1] & 0xff) << 16) +
         ((buf[pos - bufPos + 2] & 0xff) << 8) +
         (buf[pos - bufPos + 3] & 0xff);
  return true;
}

bool FileReader::getU32LE(int pos, unsigned int *val) {
  if (!fillBuf(pos, 4)) {
    return false;
  }
  *val = (buf[pos - bufPos] & 0xff) +
         ((buf[pos - bufPos + 1] & 0xff) << 8) +
         ((buf[pos - bufPos + 2] & 0xff) << 16) +
         ((buf[pos - bufPos + 3] & 0xff) << 24);
  return true;
}

bool FileReader::getUVarBE(int pos, int size, unsigned int *val) {
  int i;

  if (size < 1 || size > 4 || !fillBuf(pos, size)) {
    return false;
  }
  *val = 0;
  for (i = 0; i < size; ++i) {
    *val = (*val << 8) + (buf[pos - bufPos + i] & 0xff);
  }
  return true;
}

bool FileReader::cmp(int pos, const char *s) {
  int n;

  n = (int)strlen(s);
  if (!fillBuf(pos, n)) {
    return false;
  }
  return !memcmp(buf - bufPos + pos, s, n);
}

bool FileReader::fillBuf(int pos, int len) {
  if (pos < 0 || len < 0 || len > (int)sizeof(buf) ||
      pos > INT_MAX - (int)sizeof(buf)) {
    return false;
  }
  if (pos >= bufPos && pos + len <= bufPos + bufLen) {
    return true;
  }
  if (fseek(f, pos, SEEK_SET)) {
    return false;
  }
  bufPos = pos;
  bufLen = (int)fread(buf, 1, sizeof(buf), f);
  if (bufLen < len) {
    return false;
  }
  return true;
}

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

class StreamReader: public Reader {
public:

  static StreamReader *make(int (*getCharA)(void *data), void *dataA);
  ~StreamReader();
  int getByte(int pos) override;
  bool getU16BE(int pos, int *val) override;
  bool getU32BE(int pos, unsigned int *val) override;
  bool getU32LE(int pos, unsigned int *val) override;
  bool getUVarBE(int pos, int size, unsigned int *val) override;
  bool cmp(int pos, const char *s) override;

private:

  StreamReader(int (*getCharA)(void *data), void *dataA);
  bool fillBuf(int pos, int len);

  int (*getChar)(void *data);
  void *data;
  int streamPos;
  char buf[1024];
  int bufPos, bufLen;
};

StreamReader *StreamReader::make(int (*getCharA)(void *data), void *dataA) {
  return new StreamReader(getCharA, dataA);
}

StreamReader::StreamReader(int (*getCharA)(void *data), void *dataA) {
  getChar = getCharA;
  data = dataA;
  streamPos = 0;
  bufPos = 0;
  bufLen = 0;
}

StreamReader::~StreamReader() {
}

int StreamReader::getByte(int pos) {
  if (!fillBuf(pos, 1)) {
    return -1;
  }
  return buf[pos - bufPos] & 0xff;
}

bool StreamReader::getU16BE(int pos, int *val) {
  if (!fillBuf(pos, 2)) {
    return false;
  }
  *val = ((buf[pos - bufPos] & 0xff) << 8) +
         (buf[pos - bufPos + 1] & 0xff);
  return true;
}

bool StreamReader::getU32BE(int pos, unsigned int *val) {
  if (!fillBuf(pos, 4)) {
    return false;
  }
  *val = ((buf[pos - bufPos] & 0xff) << 24) +
         ((buf[pos - bufPos + 1] & 0xff) << 16) +
         ((buf[pos - bufPos + 2] & 0xff) << 8) +
         (buf[pos - bufPos + 3] & 0xff);
  return true;
}

bool StreamReader::getU32LE(int pos, unsigned int *val) {
  if (!fillBuf(pos, 4)) {
    return false;
  }
  *val = (buf[pos - bufPos] & 0xff) +
         ((buf[pos - bufPos + 1] & 0xff) << 8) +
         ((buf[pos - bufPos + 2] & 0xff) << 16) +
         ((buf[pos - bufPos + 3] & 0xff) << 24);
  return true;
}

bool StreamReader::getUVarBE(int pos, int size, unsigned int *val) {
  int i;

  if (size < 1 || size > 4 || !fillBuf(pos, size)) {
    return false;
  }
  *val = 0;
  for (i = 0; i < size; ++i) {
    *val = (*val << 8) + (buf[pos - bufPos + i] & 0xff);
  }
  return true;
}

bool StreamReader::cmp(int pos, const char *s) {
  const int n = (int)strlen(s);
  if (!fillBuf(pos, n)) {
    return false;
  }
  const int posDiff = pos - bufPos;
  return !memcmp(buf + posDiff, s, n);
}

bool StreamReader::fillBuf(int pos, int len) {
  int c;

  if (pos < 0 || len < 0 || len > (int)sizeof(buf) ||
      pos > INT_MAX - (int)sizeof(buf)) {
    return false;
  }
  if (pos < bufPos) {
    return false;
  }

  // if requested region will not fit in the current buffer...
  if (pos + len > bufPos + (int)sizeof(buf)) {

    // if the start of the requested data is already in the buffer, move
    // it to the start of the buffer
    if (pos < bufPos + bufLen) {
      bufLen -= pos - bufPos;
      memmove(buf, buf + (pos - bufPos), bufLen);
      bufPos = pos;

    // otherwise discard data from the
    // stream until we get to the requested position
    } else {
      bufPos += bufLen;
      bufLen = 0;
      while (bufPos < pos) {
	if ((c = (*getChar)(data)) < 0) {
	  return false;
	}
	++bufPos;
      }
    }
  }

  // read the rest of the requested data
  while (bufPos + bufLen < pos + len) {
    if ((c = (*getChar)(data)) < 0) {
      return false;
    }
    buf[bufLen++] = (char)c;
  }

  return true;
}

}

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

static FoFiIdentifierType identify(Reader *reader);
static FoFiIdentifierType identifyOpenType(Reader *reader);
static FoFiIdentifierType identifyCFF(Reader *reader, int start);

FoFiIdentifierType FoFiIdentifier::identifyMem(const char *file, int len) {
  MemReader *reader;
  FoFiIdentifierType type;

  if (!(reader = MemReader::make(file, len))) {
    return fofiIdError;
  }
  type = identify(reader);
  delete reader;
  return type;
}

FoFiIdentifierType FoFiIdentifier::identifyFile(const char *fileName) {
  FileReader *reader;
  FoFiIdentifierType type;

  if (!(reader = FileReader::make(fileName))) {
    return fofiIdError;
  }
  type = identify(reader);
  delete reader;
  return type;
}

FoFiIdentifierType FoFiIdentifier::identifyStream(int (*getChar)(void *data),
						  void *data) {
  StreamReader *reader;
  FoFiIdentifierType type;

  if (!(reader = StreamReader::make(getChar, data))) {
    return fofiIdError;
  }
  type = identify(reader);
  delete reader;
  return type;
}

static FoFiIdentifierType identify(Reader *reader) {
  unsigned int n;

  //----- PFA
  if (reader->cmp(0, "%!PS-AdobeFont-1") ||
      reader->cmp(0, "%!FontType1")) {
    return fofiIdType1PFA;
  }

  //----- PFB
  if (reader->getByte(0) == 0x80 &&
      reader->getByte(1) == 0x01 &&
      reader->getU32LE(2, &n)) {
    if ((n >= 16 && reader->cmp(6, "%!PS-AdobeFont-1")) ||
	(n >= 11 && reader->cmp(6, "%!FontType1"))) {
      return fofiIdType1PFB;
    }
  }

  //----- TrueType
  if ((reader->getByte(0) == 0x00 &&
       reader->getByte(1) == 0x01 &&
       reader->getByte(2) == 0x00 &&
       reader->getByte(3) == 0x00) ||
      (reader->getByte(0) == 0x74 &&	// 'true'
       reader->getByte(1) == 0x72 &&
       reader->getByte(2) == 0x75 &&
       reader->getByte(3) == 0x65)) {
    return fofiIdTrueType;
  }
  if (reader->getByte(0) == 0x74 &&	// 'ttcf'
      reader->getByte(1) == 0x74 &&
      reader->getByte(2) == 0x63 &&
      reader->getByte(3) == 0x66) {
    return fofiIdTrueTypeCollection;
  }

  //----- OpenType
  if (reader->getByte(0) == 0x4f &&	// 'OTTO
      reader->getByte(1) == 0x54 &&
      reader->getByte(2) == 0x54 &&
      reader->getByte(3) == 0x4f) {
    return identifyOpenType(reader);
  }

  //----- CFF
  if (reader->getByte(0) == 0x01 &&
      reader->getByte(1) == 0x00) {
    return identifyCFF(reader, 0);
  }
  // some tools embed CFF fonts with an extra whitespace char at the
  // beginning
  if (reader->getByte(1) == 0x01 &&
      reader->getByte(2) == 0x00) {
    return identifyCFF(reader, 1);
  }

  return fofiIdUnknown;
}

static FoFiIdentifierType identifyOpenType(Reader *reader) {
  FoFiIdentifierType type;
  unsigned int offset;
  int nTables, i;

  if (!reader->getU16BE(4, &nTables)) {
    return fofiIdUnknown;
  }
  for (i = 0; i < nTables; ++i) {
    if (reader->cmp(12 + i*16, "CFF ")) {
      if (reader->getU32BE(12 + i*16 + 8, &offset) &&
	  offset < (unsigned int)INT_MAX) {
	type = identifyCFF(reader, (int)offset);
	if (type == fofiIdCFF8Bit) {
	  type = fofiIdOpenTypeCFF8Bit;
	} else if (type == fofiIdCFFCID) {
	  type = fofiIdOpenTypeCFFCID;
	}
	return type;
      }
      return fofiIdUnknown;
    }
  }
  return fofiIdUnknown;
}

static FoFiIdentifierType identifyCFF(Reader *reader, int start) {
  unsigned int offset0, offset1;
  int hdrSize, offSize0, offSize1, pos, endPos, b0, n, i;

  //----- read the header
  if (reader->getByte(start) != 0x01 ||
      reader->getByte(start + 1) != 0x00) {
    return fofiIdUnknown;
  }
  if ((hdrSize = reader->getByte(start + 2)) < 0) {
    return fofiIdUnknown;
  }
  if ((offSize0 = reader->getByte(start + 3)) < 1 || offSize0 > 4) {
    return fofiIdUnknown;
  }
  pos = start + hdrSize;
  if (pos < 0) {
    return fofiIdUnknown;
  }

  //----- skip the name index
  if (!reader->getU16BE(pos, &n)) {
    return fofiIdUnknown;
  }
  if (n == 0) {
    pos += 2;
  } else {
    if ((offSize1 = reader->getByte(pos + 2)) < 1 || offSize1 > 4) {
      return fofiIdUnknown;
    }
    if (!reader->getUVarBE(pos + 3 + n * offSize1, offSize1, &offset1) ||
	offset1 > (unsigned int)INT_MAX) {
      return fofiIdUnknown;
    }
    pos += 3 + (n + 1) * offSize1 + (int)offset1 - 1;
  }
  if (pos < 0) {
    return fofiIdUnknown;
  }

  //----- parse the top dict index
  if (!reader->getU16BE(pos, &n) || n < 1) {
    return fofiIdUnknown;
  }
  if ((offSize1 = reader->getByte(pos + 2)) < 1 || offSize1 > 4) {
    return fofiIdUnknown;
  }
  if (!reader->getUVarBE(pos + 3, offSize1, &offset0) ||
      offset0 > (unsigned int)INT_MAX ||
      !reader->getUVarBE(pos + 3 + offSize1, offSize1, &offset1) ||
      offset1 > (unsigned int)INT_MAX ||
      offset0 > offset1) {
    return fofiIdUnknown;
  }
  if (checkedAdd(pos + 3 + (n + 1) * offSize1, (int)offset0 - 1, &pos) ||
    checkedAdd(pos + 3 + (n + 1) * offSize1, (int)offset1 - 1, &endPos) ||
    pos < 0 || endPos < 0 || pos > endPos) {
    return fofiIdUnknown;
  }
  
  //----- parse the top dict, look for ROS as first entry
  // for a CID font, the top dict starts with:
  //     <int> <int> <int> ROS
  for (i = 0; i < 3; ++i) {
    b0 = reader->getByte(pos++);
    if (b0 == 0x1c) {
      pos += 2;
    } else if (b0 == 0x1d) {
      pos += 4;
    } else if (b0 >= 0xf7 && b0 <= 0xfe) {
      pos += 1;
    } else if (b0 < 0x20 || b0 > 0xf6) {
      return fofiIdCFF8Bit;
    }
    if (pos >= endPos || pos < 0) {
      return fofiIdCFF8Bit;
    }
  }
  if (pos + 1 < endPos &&
      reader->getByte(pos) == 12 &&
      reader->getByte(pos + 1) == 30) {
    return fofiIdCFFCID;
  } else {
    return fofiIdCFF8Bit;
  }
}
