/*
 * Copyright (C) 2010-2019 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 "Decoder.h"

#include "DataReference.h"
#include "MessageFlags.h"
#include <stdio.h>

#if PLATFORM(MAC)
#include "ImportanceAssertion.h"
#endif

namespace IPC {

static const uint8_t* copyBuffer(const uint8_t* buffer, size_t bufferSize)
{
    auto bufferCopy = static_cast<uint8_t*>(fastMalloc(bufferSize));
    memcpy(bufferCopy, buffer, bufferSize);

    return bufferCopy;
}

Decoder::Decoder(const uint8_t* buffer, size_t bufferSize, void (*bufferDeallocator)(const uint8_t*, size_t), Vector<Attachment>&& attachments)
    : m_buffer { bufferDeallocator ? buffer : copyBuffer(buffer, bufferSize) }
    , m_bufferPos { m_buffer }
    , m_bufferEnd { m_buffer + bufferSize }
    , m_bufferDeallocator { bufferDeallocator }
    , m_attachments { WTFMove(attachments) }
{
    ASSERT(!(reinterpret_cast<uintptr_t>(m_buffer) % alignof(uint64_t)));

    if (!decode(m_messageFlags))
        return;

    if (!decode(m_messageReceiverName))
        return;

    if (!decode(m_messageName))
        return;

    if (!decode(m_destinationID))
        return;
}

Decoder::~Decoder()
{
    ASSERT(m_buffer);

    if (m_bufferDeallocator)
        m_bufferDeallocator(m_buffer, m_bufferEnd - m_buffer);
    else
        fastFree(const_cast<uint8_t*>(m_buffer));

    // FIXME: We need to dispose of the mach ports in cases of failure.

#if HAVE(QOS_CLASSES)
    if (m_qosClassOverride)
        pthread_override_qos_class_end_np(m_qosClassOverride);
#endif
}

bool Decoder::isSyncMessage() const
{
    return m_messageFlags & SyncMessage;
}

ShouldDispatchWhenWaitingForSyncReply Decoder::shouldDispatchMessageWhenWaitingForSyncReply() const
{
    if (m_messageFlags & DispatchMessageWhenWaitingForSyncReply)
        return ShouldDispatchWhenWaitingForSyncReply::Yes;
    if (m_messageFlags & DispatchMessageWhenWaitingForUnboundedSyncReply)
        return ShouldDispatchWhenWaitingForSyncReply::YesDuringUnboundedIPC;
    return ShouldDispatchWhenWaitingForSyncReply::No;
}

bool Decoder::shouldUseFullySynchronousModeForTesting() const
{
    return m_messageFlags & UseFullySynchronousModeForTesting;
}

#if PLATFORM(MAC)
void Decoder::setImportanceAssertion(std::unique_ptr<ImportanceAssertion> assertion)
{
    m_importanceAssertion = WTFMove(assertion);
}
#endif

std::unique_ptr<Decoder> Decoder::unwrapForTesting(Decoder& decoder)
{
    ASSERT(decoder.isSyncMessage());

    Vector<Attachment> attachments;
    Attachment attachment;
    while (decoder.removeAttachment(attachment))
        attachments.append(WTFMove(attachment));
    attachments.reverse();

    DataReference wrappedMessage;
    if (!decoder.decode(wrappedMessage))
        return nullptr;

    return makeUnique<Decoder>(wrappedMessage.data(), wrappedMessage.size(), nullptr, WTFMove(attachments));
}

static inline const uint8_t* roundUpToAlignment(const uint8_t* ptr, unsigned alignment)
{
    // Assert that the alignment is a power of 2.
    ASSERT(alignment && !(alignment & (alignment - 1)));

    uintptr_t alignmentMask = alignment - 1;
    return reinterpret_cast<uint8_t*>((reinterpret_cast<uintptr_t>(ptr) + alignmentMask) & ~alignmentMask);
}

static inline bool alignedBufferIsLargeEnoughToContain(const uint8_t* alignedPosition, const uint8_t* bufferStart, const uint8_t* bufferEnd, size_t size)
{
    // When size == 0 for the last argument and it's a variable length byte arrray,
    // bufferStart == alignedPosition == bufferEnd, so checking (bufferEnd >= alignedPosition)
    // is not an off-by-one error since (static_cast<size_t>(bufferEnd - alignedPosition) >= size)
    // will catch issues when size != 0.
    return bufferEnd >= alignedPosition && bufferStart <= alignedPosition && static_cast<size_t>(bufferEnd - alignedPosition) >= size;
}

bool Decoder::alignBufferPosition(unsigned alignment, size_t size)
{
    const uint8_t* alignedPosition = roundUpToAlignment(m_bufferPos, alignment);
    if (!alignedBufferIsLargeEnoughToContain(alignedPosition, m_buffer, m_bufferEnd, size)) {
        // We've walked off the end of this buffer.
        markInvalid();
        return false;
    }
    
    m_bufferPos = alignedPosition;
    return true;
}

bool Decoder::bufferIsLargeEnoughToContain(unsigned alignment, size_t size) const
{
    return alignedBufferIsLargeEnoughToContain(roundUpToAlignment(m_bufferPos, alignment), m_buffer, m_bufferEnd, size);
}

bool Decoder::decodeFixedLengthData(uint8_t* data, size_t size, unsigned alignment)
{
    if (!alignBufferPosition(alignment, size))
        return false;

    memcpy(data, m_bufferPos, size);
    m_bufferPos += size;

    return true;
}

bool Decoder::decodeVariableLengthByteArray(DataReference& dataReference)
{
    uint64_t size;
    if (!decode(size))
        return false;
    
    if (!alignBufferPosition(1, size))
        return false;

    const uint8_t* data = m_bufferPos;
    m_bufferPos += size;

    dataReference = DataReference(data, size);
    return true;
}

template<typename Type>
static void decodeValueFromBuffer(Type& value, const uint8_t*& bufferPosition)
{
    memcpy(&value, bufferPosition, sizeof(value));
    bufferPosition += sizeof(Type);
}

template<typename Type>
Decoder& Decoder::getOptional(Optional<Type>& optional)
{
    Type result;
    if (!alignBufferPosition(sizeof(result), sizeof(result)))
        return *this;
    
    decodeValueFromBuffer(result, m_bufferPos);
    optional = result;
    return *this;
}

Decoder& Decoder::operator>>(Optional<bool>& optional)
{
    return getOptional(optional);
}

Decoder& Decoder::operator>>(Optional<uint8_t>& optional)
{
    return getOptional(optional);
}

Decoder& Decoder::operator>>(Optional<uint16_t>& optional)
{
    return getOptional(optional);
}

Decoder& Decoder::operator>>(Optional<uint32_t>& optional)
{
    return getOptional(optional);
}

Decoder& Decoder::operator>>(Optional<uint64_t>& optional)
{
    return getOptional(optional);
}

Decoder& Decoder::operator>>(Optional<int16_t>& optional)
{
    return getOptional(optional);
}

Decoder& Decoder::operator>>(Optional<int32_t>& optional)
{
    return getOptional(optional);
}

Decoder& Decoder::operator>>(Optional<int64_t>& optional)
{
    return getOptional(optional);
}

Decoder& Decoder::operator>>(Optional<float>& optional)
{
    return getOptional(optional);
}

Decoder& Decoder::operator>>(Optional<double>& optional)
{
    return getOptional(optional);
}

bool Decoder::decode(bool& result)
{
    if (!alignBufferPosition(sizeof(result), sizeof(result)))
        return false;
    
    decodeValueFromBuffer(result, m_bufferPos);
    return true;
}

bool Decoder::decode(uint8_t& result)
{
    if (!alignBufferPosition(sizeof(result), sizeof(result)))
        return false;

    decodeValueFromBuffer(result, m_bufferPos);
    return true;
}

bool Decoder::decode(uint16_t& result)
{
    if (!alignBufferPosition(sizeof(result), sizeof(result)))
        return false;

    decodeValueFromBuffer(result, m_bufferPos);
    return true;
}

bool Decoder::decode(uint32_t& result)
{
    if (!alignBufferPosition(sizeof(result), sizeof(result)))
        return false;

    decodeValueFromBuffer(result, m_bufferPos);
    return true;
}

bool Decoder::decode(uint64_t& result)
{
    if (!alignBufferPosition(sizeof(result), sizeof(result)))
        return false;
    
    decodeValueFromBuffer(result, m_bufferPos);
    return true;
}

bool Decoder::decode(int16_t& result)
{
    if (!alignBufferPosition(sizeof(result), sizeof(result)))
        return false;

    decodeValueFromBuffer(result, m_bufferPos);
    return true;
}

bool Decoder::decode(int32_t& result)
{
    if (!alignBufferPosition(sizeof(result), sizeof(result)))
        return false;
    
    decodeValueFromBuffer(result, m_bufferPos);
    return true;
}

bool Decoder::decode(int64_t& result)
{
    if (!alignBufferPosition(sizeof(result), sizeof(result)))
        return false;

    decodeValueFromBuffer(result, m_bufferPos);
    return true;
}

bool Decoder::decode(float& result)
{
    if (!alignBufferPosition(sizeof(result), sizeof(result)))
        return false;

    decodeValueFromBuffer(result, m_bufferPos);
    return true;
}

bool Decoder::decode(double& result)
{
    if (!alignBufferPosition(sizeof(result), sizeof(result)))
        return false;
    
    decodeValueFromBuffer(result, m_bufferPos);
    return true;
}

bool Decoder::removeAttachment(Attachment& attachment)
{
    if (m_attachments.isEmpty())
        return false;

    attachment = m_attachments.takeLast();
    return true;
}

} // namespace IPC
