/*
 * Copyright (C) 2015-2021 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 "DFABytecodeInterpreter.h"

#include "ContentExtensionsDebugging.h"
#include <wtf/text/CString.h>

#if ENABLE(CONTENT_EXTENSIONS)

namespace WebCore::ContentExtensions {

template <typename IntType>
static IntType getBits(Span<const uint8_t> bytecode, uint32_t index)
{
    ASSERT(index + sizeof(IntType) <= bytecode.size());
    return *reinterpret_cast<const IntType*>(bytecode.data() + index);
}

static uint32_t get24BitsUnsigned(Span<const uint8_t> bytecode, uint32_t index)
{
    ASSERT(index + UInt24Size <= bytecode.size());
    uint32_t highBits = getBits<uint8_t>(bytecode, index + sizeof(uint16_t));
    uint32_t lowBits = getBits<uint16_t>(bytecode, index);
    return (highBits << 16) | lowBits;
}

static DFABytecodeInstruction getInstruction(Span<const uint8_t> bytecode, uint32_t index)
{
    return static_cast<DFABytecodeInstruction>(getBits<uint8_t>(bytecode, index) & DFABytecodeInstructionMask);
}

static size_t jumpSizeInBytes(DFABytecodeJumpSize jumpSize)
{
    switch (jumpSize) {
    case DFABytecodeJumpSize::Int8:
        return sizeof(int8_t);
    case DFABytecodeJumpSize::Int16:
        return sizeof(int16_t);
    case DFABytecodeJumpSize::Int24:
        return Int24Size;
    case DFABytecodeJumpSize::Int32:
        return sizeof(int32_t);
    }
    RELEASE_ASSERT_NOT_REACHED();
}

template<typename T> uint32_t consumeInteger(Span<const uint8_t> bytecode, uint32_t& programCounter)
{
    programCounter += sizeof(T);
    return getBits<T>(bytecode, programCounter - sizeof(T));
}
static uint32_t consume24BitUnsignedInteger(Span<const uint8_t> bytecode, uint32_t& programCounter)
{
    programCounter += UInt24Size;
    return get24BitsUnsigned(bytecode, programCounter - UInt24Size);
}

static constexpr bool hasFlags(DFABytecodeInstruction instruction)
{
    switch (instruction) {
    case DFABytecodeInstruction::TestFlagsAndAppendAction:
        return true;
    case DFABytecodeInstruction::CheckValueCaseSensitive:
    case DFABytecodeInstruction::CheckValueCaseInsensitive:
    case DFABytecodeInstruction::JumpTableCaseInsensitive:
    case DFABytecodeInstruction::JumpTableCaseSensitive:
    case DFABytecodeInstruction::CheckValueRangeCaseSensitive:
    case DFABytecodeInstruction::CheckValueRangeCaseInsensitive:
    case DFABytecodeInstruction::Jump:
    case DFABytecodeInstruction::AppendAction:
    case DFABytecodeInstruction::Terminate:
        break;
    }
    return false;
}

static constexpr bool hasAction(DFABytecodeInstruction instruction)
{
    switch (instruction) {
    case DFABytecodeInstruction::TestFlagsAndAppendAction:
    case DFABytecodeInstruction::AppendAction:
        return true;
    case DFABytecodeInstruction::CheckValueCaseSensitive:
    case DFABytecodeInstruction::CheckValueCaseInsensitive:
    case DFABytecodeInstruction::JumpTableCaseInsensitive:
    case DFABytecodeInstruction::JumpTableCaseSensitive:
    case DFABytecodeInstruction::CheckValueRangeCaseSensitive:
    case DFABytecodeInstruction::CheckValueRangeCaseInsensitive:
    case DFABytecodeInstruction::Jump:
    case DFABytecodeInstruction::Terminate:
        break;
    }
    return false;
}

static ResourceFlags consumeResourceFlagsAndInstruction(Span<const uint8_t> bytecode, uint32_t& programCounter)
{
    ASSERT_UNUSED(hasFlags, hasFlags(getInstruction(bytecode, programCounter)));
    switch (static_cast<DFABytecodeFlagsSize>(bytecode[programCounter++] & DFABytecodeFlagsSizeMask)) {
    case DFABytecodeFlagsSize::UInt8:
        return consumeInteger<uint8_t>(bytecode, programCounter);
    case DFABytecodeFlagsSize::UInt16:
        return consumeInteger<uint16_t>(bytecode, programCounter);
    case DFABytecodeFlagsSize::UInt24:
        return consume24BitUnsignedInteger(bytecode, programCounter);
    }
    ASSERT_NOT_REACHED();
    return 0;
}

static uint32_t consumeAction(Span<const uint8_t> bytecode, uint32_t& programCounter, uint32_t instructionLocation)
{
    ASSERT_UNUSED(hasAction, hasAction(getInstruction(bytecode, instructionLocation)));
    ASSERT(programCounter > instructionLocation);
    switch (static_cast<DFABytecodeActionSize>(bytecode[instructionLocation] & DFABytecodeActionSizeMask)) {
    case DFABytecodeActionSize::UInt8:
        return consumeInteger<uint8_t>(bytecode, programCounter);
    case DFABytecodeActionSize::UInt16:
        return consumeInteger<uint16_t>(bytecode, programCounter);
    case DFABytecodeActionSize::UInt24:
        return consume24BitUnsignedInteger(bytecode, programCounter);
    case DFABytecodeActionSize::UInt32:
        return consumeInteger<uint32_t>(bytecode, programCounter);
    }
    ASSERT_NOT_REACHED();
    return 0;
}

static DFABytecodeJumpSize getJumpSize(Span<const uint8_t> bytecode, uint32_t index)
{
    auto jumpSize = static_cast<DFABytecodeJumpSize>(getBits<uint8_t>(bytecode, index) & DFABytecodeJumpSizeMask);
    ASSERT(jumpSize == DFABytecodeJumpSize::Int32
        || jumpSize == DFABytecodeJumpSize::Int24
        || jumpSize == DFABytecodeJumpSize::Int16
        || jumpSize == DFABytecodeJumpSize::Int8);
    return jumpSize;
}

static int32_t getJumpDistance(Span<const uint8_t> bytecode, uint32_t index, DFABytecodeJumpSize jumpSize)
{
    switch (jumpSize) {
    case DFABytecodeJumpSize::Int8:
        return getBits<int8_t>(bytecode, index);
    case DFABytecodeJumpSize::Int16:
        return getBits<int16_t>(bytecode, index);
    case DFABytecodeJumpSize::Int24:
        return getBits<uint16_t>(bytecode, index) | (static_cast<int32_t>(getBits<int8_t>(bytecode, index + sizeof(uint16_t))) << 16);
    case DFABytecodeJumpSize::Int32:
        return getBits<int32_t>(bytecode, index);
    }
    RELEASE_ASSERT_NOT_REACHED();
}

void DFABytecodeInterpreter::interpretAppendAction(uint32_t& programCounter, Actions& actions)
{
    ASSERT(getInstruction(m_bytecode, programCounter) == DFABytecodeInstruction::AppendAction);
    auto instructionLocation = programCounter++;
    actions.add(consumeAction(m_bytecode, programCounter, instructionLocation));
}

void DFABytecodeInterpreter::interpretTestFlagsAndAppendAction(uint32_t& programCounter, ResourceFlags flags, Actions& actions)
{
    auto instructionLocation = programCounter;
    auto flagsToCheck = consumeResourceFlagsAndInstruction(m_bytecode, programCounter);

    ResourceFlags loadTypeFlags = flagsToCheck & LoadTypeMask;
    ResourceFlags loadContextFlags = flagsToCheck & LoadContextMask;
    ResourceFlags resourceTypeFlags = flagsToCheck & ResourceTypeMask;

    bool loadTypeMatches = loadTypeFlags ? (loadTypeFlags & flags) : true;
    bool loadContextMatches = loadContextFlags ? (loadContextFlags & flags) : true;
    bool resourceTypeMatches = resourceTypeFlags ? (resourceTypeFlags & flags) : true;
    
    auto actionWithoutFlags = consumeAction(m_bytecode, programCounter, instructionLocation);
    if (loadTypeMatches && loadContextMatches && resourceTypeMatches) {
        uint64_t actionAndFlags = (static_cast<uint64_t>(flagsToCheck) << 32) | static_cast<uint64_t>(actionWithoutFlags);
        actions.add(actionAndFlags);
    }
}

template<bool caseSensitive>
inline void DFABytecodeInterpreter::interpetJumpTable(Span<const char> url, uint32_t& urlIndex, uint32_t& programCounter)
{
    DFABytecodeJumpSize jumpSize = getJumpSize(m_bytecode, programCounter);

    char c = urlIndex < url.size() ? url[urlIndex] : 0;
    char character = caseSensitive ? c : toASCIILower(c);
    uint8_t firstCharacter = getBits<uint8_t>(m_bytecode, programCounter + sizeof(DFABytecodeInstruction));
    uint8_t lastCharacter = getBits<uint8_t>(m_bytecode, programCounter + sizeof(DFABytecodeInstruction) + sizeof(uint8_t));
    if (character >= firstCharacter && character <= lastCharacter) {
        uint32_t startOffset = programCounter + sizeof(DFABytecodeInstruction) + 2 * sizeof(uint8_t);
        uint32_t jumpLocation = startOffset + (character - firstCharacter) * jumpSizeInBytes(jumpSize);
        programCounter += getJumpDistance(m_bytecode, jumpLocation, jumpSize);
        urlIndex++; // This represents an edge in the DFA.
    } else
        programCounter += sizeof(DFABytecodeInstruction) + 2 * sizeof(uint8_t) + jumpSizeInBytes(jumpSize) * (lastCharacter - firstCharacter + 1);
}

auto DFABytecodeInterpreter::actionsMatchingEverything() -> Actions
{
    Actions actions;

    // DFA header.
    uint32_t dfaBytecodeLength = getBits<uint32_t>(m_bytecode, 0);
    uint32_t programCounter = sizeof(DFAHeader);

    while (programCounter < dfaBytecodeLength) {
        DFABytecodeInstruction instruction = getInstruction(m_bytecode, programCounter);
        if (instruction == DFABytecodeInstruction::AppendAction)
            interpretAppendAction(programCounter, actions);
        else if (instruction == DFABytecodeInstruction::TestFlagsAndAppendAction) {
            auto programCounterAtInstruction = programCounter;
            consumeResourceFlagsAndInstruction(m_bytecode, programCounter);
            consumeAction(m_bytecode, programCounter, programCounterAtInstruction);
        } else
            break;
    }
    return actions;
}

auto DFABytecodeInterpreter::interpret(const String& urlString, ResourceFlags flags) -> Actions
{
    CString urlCString;
    Span<const char> url;
    if (LIKELY(urlString.is8Bit()))
        url = { reinterpret_cast<const char*>(urlString.characters8()), urlString.length() };
    else {
        urlCString = urlString.utf8();
        url = { urlCString.data(), urlCString.length() };
    }
    ASSERT(url.data());
    
    Actions actions;
    
    uint32_t programCounter = 0;
    while (programCounter < m_bytecode.size()) {

        // DFA header.
        uint32_t dfaStart = programCounter;
        uint32_t dfaBytecodeLength = getBits<uint32_t>(m_bytecode, programCounter);
        programCounter += sizeof(uint32_t);

        // Skip the actions without flags on the DFA root. These are accessed via actionsMatchingEverything.
        if (!dfaStart) {
            while (programCounter < dfaBytecodeLength) {
                DFABytecodeInstruction instruction = getInstruction(m_bytecode, programCounter);
                if (instruction == DFABytecodeInstruction::AppendAction) {
                    auto instructionLocation = programCounter++;
                    consumeAction(m_bytecode, programCounter, instructionLocation);
                } else if (instruction == DFABytecodeInstruction::TestFlagsAndAppendAction)
                    interpretTestFlagsAndAppendAction(programCounter, flags, actions);
                else
                    break;
            }
            if (programCounter >= m_bytecode.size())
                return actions;
        } else {
            ASSERT_WITH_MESSAGE(getInstruction(m_bytecode, programCounter) != DFABytecodeInstruction::AppendAction
                && getInstruction(m_bytecode, programCounter) != DFABytecodeInstruction::TestFlagsAndAppendAction,
                "Triggers that match everything should only be in the first DFA.");
        }
        
        // Interpret the bytecode from this DFA.
        // This should always terminate if interpreting correctly compiled bytecode.
        uint32_t urlIndex = 0;
        while (true) {
            ASSERT(programCounter <= m_bytecode.size());
            switch (getInstruction(m_bytecode, programCounter)) {

            case DFABytecodeInstruction::Terminate:
                goto nextDFA;
                    
            case DFABytecodeInstruction::CheckValueCaseSensitive: {
                if (urlIndex > url.size())
                    goto nextDFA;

                // Check to see if the next character in the url is the value stored with the bytecode.
                char character = urlIndex < url.size() ? url[urlIndex] : 0;
                DFABytecodeJumpSize jumpSize = getJumpSize(m_bytecode, programCounter);
                if (character == getBits<uint8_t>(m_bytecode, programCounter + sizeof(DFABytecodeInstruction))) {
                    uint32_t jumpLocation = programCounter + sizeof(DFABytecodeInstruction) + sizeof(uint8_t);
                    programCounter += getJumpDistance(m_bytecode, jumpLocation, jumpSize);
                    urlIndex++; // This represents an edge in the DFA.
                } else
                    programCounter += sizeof(DFABytecodeInstruction) + sizeof(uint8_t) + jumpSizeInBytes(jumpSize);
                break;
            }

            case DFABytecodeInstruction::CheckValueCaseInsensitive: {
                if (urlIndex > url.size())
                    goto nextDFA;

                // Check to see if the next character in the url is the value stored with the bytecode.
                char character = urlIndex < url.size() ? toASCIILower(url[urlIndex]) : 0;
                DFABytecodeJumpSize jumpSize = getJumpSize(m_bytecode, programCounter);
                if (character == getBits<uint8_t>(m_bytecode, programCounter + sizeof(DFABytecodeInstruction))) {
                    uint32_t jumpLocation = programCounter + sizeof(DFABytecodeInstruction) + sizeof(uint8_t);
                    programCounter += getJumpDistance(m_bytecode, jumpLocation, jumpSize);
                    urlIndex++; // This represents an edge in the DFA.
                } else
                    programCounter += sizeof(DFABytecodeInstruction) + sizeof(uint8_t) + jumpSizeInBytes(jumpSize);
                break;
            }

            case DFABytecodeInstruction::JumpTableCaseInsensitive:
                if (urlIndex > url.size())
                    goto nextDFA;

                interpetJumpTable<false>(url, urlIndex, programCounter);
                break;
            case DFABytecodeInstruction::JumpTableCaseSensitive:
                if (urlIndex > url.size())
                    goto nextDFA;

                interpetJumpTable<true>(url, urlIndex, programCounter);
                break;
                    
            case DFABytecodeInstruction::CheckValueRangeCaseSensitive: {
                if (urlIndex > url.size())
                    goto nextDFA;
                
                char character = urlIndex < url.size() ? url[urlIndex] : 0;
                DFABytecodeJumpSize jumpSize = getJumpSize(m_bytecode, programCounter);
                if (character >= getBits<uint8_t>(m_bytecode, programCounter + sizeof(DFABytecodeInstruction))
                    && character <= getBits<uint8_t>(m_bytecode, programCounter + sizeof(DFABytecodeInstruction) + sizeof(uint8_t))) {
                    uint32_t jumpLocation = programCounter + sizeof(DFABytecodeInstruction) + 2 * sizeof(uint8_t);
                    programCounter += getJumpDistance(m_bytecode, jumpLocation, jumpSize);
                    urlIndex++; // This represents an edge in the DFA.
                } else
                    programCounter += sizeof(DFABytecodeInstruction) + 2 * sizeof(uint8_t) + jumpSizeInBytes(jumpSize);
                break;
            }

            case DFABytecodeInstruction::CheckValueRangeCaseInsensitive: {
                if (urlIndex > url.size())
                    goto nextDFA;
                
                char character = urlIndex < url.size() ? toASCIILower(url[urlIndex]) : 0;
                DFABytecodeJumpSize jumpSize = getJumpSize(m_bytecode, programCounter);
                if (character >= getBits<uint8_t>(m_bytecode, programCounter + sizeof(DFABytecodeInstruction))
                    && character <= getBits<uint8_t>(m_bytecode, programCounter + sizeof(DFABytecodeInstruction) + sizeof(uint8_t))) {
                    uint32_t jumpLocation = programCounter + sizeof(DFABytecodeInstruction) + 2 * sizeof(uint8_t);
                    programCounter += getJumpDistance(m_bytecode, jumpLocation, jumpSize);
                    urlIndex++; // This represents an edge in the DFA.
                } else
                    programCounter += sizeof(DFABytecodeInstruction) + 2 * sizeof(uint8_t) + jumpSizeInBytes(jumpSize);
                break;
            }

            case DFABytecodeInstruction::Jump: {
                if (urlIndex >= url.size())
                    goto nextDFA;
                
                uint32_t jumpLocation = programCounter + sizeof(DFABytecodeInstruction);
                DFABytecodeJumpSize jumpSize = getJumpSize(m_bytecode, programCounter);
                programCounter += getJumpDistance(m_bytecode, jumpLocation, jumpSize);
                urlIndex++; // This represents an edge in the DFA.
                break;
            }
                    
            case DFABytecodeInstruction::AppendAction:
                interpretAppendAction(programCounter, actions);
                break;
                    
            case DFABytecodeInstruction::TestFlagsAndAppendAction:
                interpretTestFlagsAndAppendAction(programCounter, flags, actions);
                break;
                    
            default:
                RELEASE_ASSERT_NOT_REACHED(); // Invalid bytecode.
            }
            // We should always terminate before or at an imaginary null character at the end of a String.
            ASSERT(urlIndex <= url.size() + 1);
        }
        RELEASE_ASSERT_NOT_REACHED(); // The while loop can only be exited using goto nextDFA.
        nextDFA:
        ASSERT(dfaBytecodeLength);
        programCounter = dfaStart + dfaBytecodeLength;
    }
    return actions;
}

} // namespace WebCore::ContentExtensions

#endif // ENABLE(CONTENT_EXTENSIONS)
