/*
 * Copyright (C) 2010 Apple Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "config.h"
#include "WOFFFileFormat.h"
#include <zlib.h>

#include "SharedBuffer.h"
#include <wtf/ByteOrder.h>

#if USE(WOFF2)
#include <woff2/decode.h>
static const uint32_t kWoff2Signature = 0x774f4632; // "wOF2"
#endif

namespace WebCore {

static bool readUInt32(SharedBuffer& buffer, size_t& offset, uint32_t& value)
{
    ASSERT_ARG(offset, offset <= buffer.size());
    if (buffer.size() - offset < sizeof(value))
        return false;

    value = ntohl(*reinterpret_cast_ptr<const uint32_t*>(buffer.data() + offset));
    offset += sizeof(value);

    return true;
}

static bool readUInt16(SharedBuffer& buffer, size_t& offset, uint16_t& value)
{
    ASSERT_ARG(offset, offset <= buffer.size());
    if (buffer.size() - offset < sizeof(value))
        return false;

    value = ntohs(*reinterpret_cast_ptr<const uint16_t*>(buffer.data() + offset));
    offset += sizeof(value);

    return true;
}

static bool writeUInt32(Vector<uint8_t>& vector, uint32_t value)
{
    uint32_t bigEndianValue = htonl(value);
    return vector.tryAppend(reinterpret_cast_ptr<uint8_t*>(&bigEndianValue), sizeof(bigEndianValue));
}

static bool writeUInt16(Vector<uint8_t>& vector, uint16_t value)
{
    uint16_t bigEndianValue = htons(value);
    return vector.tryAppend(reinterpret_cast_ptr<uint8_t*>(&bigEndianValue), sizeof(bigEndianValue));
}

static const uint32_t woffSignature = 0x774f4646; /* 'wOFF' */

bool isWOFF(SharedBuffer& buffer)
{
    size_t offset = 0;
    uint32_t signature;

    if (!readUInt32(buffer, offset, signature))
        return false;

#if USE(WOFF2)
    return signature == woffSignature || signature == kWoff2Signature;
#else
    return signature == woffSignature;
#endif
}

#if USE(WOFF2)
class WOFF2VectorOut : public woff2::WOFF2Out {
public:
    WOFF2VectorOut(Vector<uint8_t>& vector)
        : m_vector(vector)
    { }

    bool Write(const void* data, size_t n) override
    {
        if (!m_vector.tryReserveCapacity(m_vector.size() + n))
            return false;
        m_vector.append(static_cast<const uint8_t*>(data), n);
        return true;
    }

    bool Write(const void* data, size_t offset, size_t n) override
    {
        if (!m_vector.tryReserveCapacity(offset + n))
            return false;
        if (offset + n > m_vector.size())
            m_vector.grow(offset + n);
        m_vector.remove(offset, n);
        m_vector.insert(offset, static_cast<const uint8_t*>(data), n);
        return true;
    }

    size_t Size() override
    {
        return m_vector.size();
    }

private:
    Vector<uint8_t>& m_vector;
};
#endif

bool convertWOFFToSfnt(SharedBuffer& woff, Vector<uint8_t>& sfnt)
{
    ASSERT_ARG(sfnt, sfnt.isEmpty());

    size_t offset = 0;

    // Read the WOFF header.
    uint32_t signature;
    if (!readUInt32(woff, offset, signature)) {
        ASSERT_NOT_REACHED();
        return false;
    }

#if USE(WOFF2)
    if (signature == kWoff2Signature) {
        auto* woffData = woff.data();
        const size_t woffSize = woff.size();
        const size_t sfntSize = woff2::ComputeWOFF2FinalSize(woffData, woffSize);

        if (!sfnt.tryReserveCapacity(sfntSize))
            return false;

        WOFF2VectorOut out(sfnt);
        return woff2::ConvertWOFF2ToTTF(woffData, woffSize, &out);
    }
#endif

    if (signature != woffSignature) {
        ASSERT_NOT_REACHED();
        return false;
    }

    uint32_t flavor;
    if (!readUInt32(woff, offset, flavor))
        return false;

    uint32_t length;
    if (!readUInt32(woff, offset, length) || length != woff.size())
        return false;

    uint16_t numTables;
    if (!readUInt16(woff, offset, numTables))
        return false;

    if (!numTables || numTables > 0x0fff)
        return false;

    uint16_t reserved;
    if (!readUInt16(woff, offset, reserved) || reserved)
        return false;

    uint32_t totalSfntSize;
    if (!readUInt32(woff, offset, totalSfntSize))
        return false;

    if (woff.size() - offset < sizeof(uint16_t) + sizeof(uint16_t) + sizeof(uint32_t) + sizeof(uint32_t) + sizeof(uint32_t) + sizeof(uint32_t) + sizeof(uint32_t))
        return false;

    offset += sizeof(uint16_t); // majorVersion
    offset += sizeof(uint16_t); // minorVersion
    offset += sizeof(uint32_t); // metaOffset
    offset += sizeof(uint32_t); // metaLength
    offset += sizeof(uint32_t); // metaOrigLength
    offset += sizeof(uint32_t); // privOffset
    offset += sizeof(uint32_t); // privLength

    // Check if the WOFF can supply as many tables as it claims it has.
    if (woff.size() - offset < numTables * 5 * sizeof(uint32_t))
        return false;

    // Write the sfnt offset subtable.
    uint16_t entrySelector = 0;
    uint16_t searchRange = 1;
    while (searchRange < numTables >> 1) {
        entrySelector++;
        searchRange <<= 1;
    }
    searchRange <<= 4;
    uint16_t rangeShift = (numTables << 4) - searchRange;

    if (!writeUInt32(sfnt, flavor)
        || !writeUInt16(sfnt, numTables)
        || !writeUInt16(sfnt, searchRange)
        || !writeUInt16(sfnt, entrySelector)
        || !writeUInt16(sfnt, rangeShift))
        return false;

    if (sfnt.size() > totalSfntSize)
        return false;

    if (totalSfntSize - sfnt.size() < numTables * 4 * sizeof(uint32_t))
        return false;

    size_t sfntTableDirectoryCursor = sfnt.size();
    sfnt.grow(sfnt.size() + numTables * 4 * sizeof(uint32_t));

    // Process tables.
    for (uint16_t i = 0; i < numTables; ++i) {
        // Read a WOFF table directory entry.
        uint32_t tableTag;
        if (!readUInt32(woff, offset, tableTag))
            return false;

        uint32_t tableOffset;
        if (!readUInt32(woff, offset, tableOffset))
            return false;

        uint32_t tableCompLength;
        if (!readUInt32(woff, offset, tableCompLength))
            return false;

        if (tableOffset > woff.size() || tableCompLength > woff.size() - tableOffset)
            return false;

        uint32_t tableOrigLength;
        if (!readUInt32(woff, offset, tableOrigLength) || tableCompLength > tableOrigLength)
            return false;

        if (tableOrigLength > totalSfntSize || sfnt.size() > totalSfntSize - tableOrigLength)
            return false;

        uint32_t tableOrigChecksum;
        if (!readUInt32(woff, offset, tableOrigChecksum))
            return false;

        // Write an sfnt table directory entry.
        uint32_t* sfntTableDirectoryPtr = reinterpret_cast_ptr<uint32_t*>(sfnt.data() + sfntTableDirectoryCursor);
        *sfntTableDirectoryPtr++ = htonl(tableTag);
        *sfntTableDirectoryPtr++ = htonl(tableOrigChecksum);
        *sfntTableDirectoryPtr++ = htonl(sfnt.size());
        *sfntTableDirectoryPtr++ = htonl(tableOrigLength);
        sfntTableDirectoryCursor += 4 * sizeof(uint32_t);

        if (tableCompLength == tableOrigLength) {
            // The table is not compressed.
            if (!sfnt.tryAppend(woff.data() + tableOffset, tableCompLength))
                return false;
        } else {
            uLongf destLen = tableOrigLength;
            if (!sfnt.tryReserveCapacity(sfnt.size() + tableOrigLength))
                return false;
            Bytef* dest = reinterpret_cast<Bytef*>(sfnt.end());
            sfnt.grow(sfnt.size() + tableOrigLength);
            if (uncompress(dest, &destLen, reinterpret_cast<const Bytef*>(woff.data() + tableOffset), tableCompLength) != Z_OK)
                return false;
            if (destLen != tableOrigLength)
                return false;
        }

        // Pad to a multiple of 4 bytes.
        while (sfnt.size() % 4)
            sfnt.append(0);
    }

    return sfnt.size() == totalSfntSize;
}

bool convertWOFFToSfntIfNecessary(RefPtr<SharedBuffer>& buffer)
{
#if PLATFORM(COCOA)
    UNUSED_PARAM(buffer);
    return false;
#else
    if (!buffer || !isWOFF(*buffer))
        return false;

    Vector<uint8_t> convertedFont;
    if (convertWOFFToSfnt(*buffer, convertedFont))
        buffer = SharedBuffer::create(WTFMove(convertedFont));
    else
        buffer = nullptr;

    return true;
#endif
}

} // namespace WebCore
