//========================================================================
//
// 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, 2021 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 <cstdio>
#include <cstring>
#include <climits>
#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() override;
    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() override;
    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:
    explicit 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() override;
    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;
    }
}
