//
// Copyright 2016 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//

// translator_fuzzer.cpp: A libfuzzer fuzzer for the shader translator.

#include <cstddef>
#include <cstdint>
#include <iostream>
#include <memory>
#include <unordered_map>
#include "common/unsafe_buffers.h"

#include "angle_gl.h"
#include "anglebase/no_destructor.h"
#include "common/hash_containers.h"
#include "compiler/translator/Compiler.h"
#include "compiler/translator/util.h"

using namespace sh;

namespace
{
struct TranslatorCacheKey
{
    bool operator==(const TranslatorCacheKey &other) const
    {
        return type == other.type && spec == other.spec && output == other.output;
    }

    uint32_t type   = 0;
    uint32_t spec   = 0;
    uint32_t output = 0;
};
}  // anonymous namespace

namespace std
{

template <>
struct hash<TranslatorCacheKey>
{
    std::size_t operator()(const TranslatorCacheKey &k) const
    {
        return (hash<uint32_t>()(k.type) << 1) ^ (hash<uint32_t>()(k.spec) >> 1) ^
               hash<uint32_t>()(k.output);
    }
};
}  // namespace std

struct TCompilerDeleter
{
    void operator()(TCompiler *compiler) const { DeleteCompiler(compiler); }
};

extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
{
    ShaderDumpHeader header{};
    if (size <= sizeof(header))
    {
        return 0;
    }

    // Make sure the rest of data will be a valid C string so that we don't have to copy it.
    if (ANGLE_UNSAFE_TODO(data[size - 1]) != 0)
    {
        return 0;
    }

    ANGLE_UNSAFE_TODO(memcpy(&header, data, sizeof(header)));
    ShCompileOptions options{};
    ANGLE_UNSAFE_TODO(
        memcpy(&options, &header.basicCompileOptions, offsetof(ShCompileOptions, metal)));
    ANGLE_UNSAFE_TODO(memcpy(&options.metal, &header.metalCompileOptions, sizeof(options.metal)));
    ANGLE_UNSAFE_TODO(memcpy(&options.pls, &header.plsCompileOptions, sizeof(options.pls)));
    size -= sizeof(header);
    ANGLE_UNSAFE_TODO(data += sizeof(header));
    uint32_t type = header.type;
    uint32_t spec = header.spec;

    if (type != GL_FRAGMENT_SHADER && type != GL_VERTEX_SHADER)
    {
        return 0;
    }

    if (spec != SH_GLES2_SPEC && spec != SH_WEBGL_SPEC && spec != SH_GLES3_SPEC &&
        spec != SH_WEBGL2_SPEC)
    {
        return 0;
    }

    ShShaderOutput shaderOutput = static_cast<ShShaderOutput>(header.output);

    bool hasUnsupportedOptions = false;

    const bool hasMacGLSLOptions = options.addAndTrueToLoopCondition ||
                                   options.unfoldShortCircuit || options.rewriteRowMajorMatrices;

    if (!IsOutputGLSL(shaderOutput) && !IsOutputESSL(shaderOutput))
    {
        hasUnsupportedOptions = hasUnsupportedOptions || options.emulateAtan2FloatFunction ||
                                options.clampFragDepth || options.rewriteRepeatedAssignToSwizzled ||
                                options.useUnusedStandardSharedBlocks ||
                                options.selectViewInNvGLSLVertexShader;

        hasUnsupportedOptions = hasUnsupportedOptions || hasMacGLSLOptions;
    }
    else
    {
#if !defined(ANGLE_PLATFORM_APPLE)
        hasUnsupportedOptions = hasUnsupportedOptions || hasMacGLSLOptions;
#endif
    }
    if (!IsOutputSPIRV(shaderOutput))
    {
        hasUnsupportedOptions = hasUnsupportedOptions || options.addVulkanXfbEmulationSupportCode ||
                                options.addAdvancedBlendEquationsEmulation;
    }
    if (!IsOutputHLSL(shaderOutput))
    {
        hasUnsupportedOptions = hasUnsupportedOptions ||
                                options.expandSelectHLSLIntegerPowExpressions ||
                                options.allowTranslateUniformBlockToStructuredBuffer ||
                                options.rewriteIntegerUnaryMinusOperator;
    }
    if (!IsOutputMSL(shaderOutput))
    {
        hasUnsupportedOptions = hasUnsupportedOptions || options.ensureLoopForwardProgress;
    }

    // If there are any options not supported with this output, don't attempt to run the translator.
    if (hasUnsupportedOptions)
    {
        return 0;
    }

    // Make sure the rest of the options are in a valid range.
    options.pls.fragmentSyncType = static_cast<ShFragmentSynchronizationType>(
        static_cast<uint32_t>(options.pls.fragmentSyncType) %
        static_cast<uint32_t>(ShFragmentSynchronizationType::InvalidEnum));

    // Force enable options that are required by the output generators.
    if (IsOutputSPIRV(shaderOutput))
    {
        options.removeInactiveVariables = true;
        options.retainInactiveFragmentOutputs = false;
    }
    if (IsOutputMSL(shaderOutput) || IsOutputHLSL(shaderOutput) || IsOutputWGSL(shaderOutput))
    {
        options.removeInactiveVariables = true;
        options.retainInactiveFragmentOutputs = true;
    }

    std::vector<uint32_t> validOutputs;
    validOutputs.push_back(SH_ESSL_OUTPUT);
    validOutputs.push_back(SH_GLSL_150_CORE_OUTPUT);
    validOutputs.push_back(SH_GLSL_330_CORE_OUTPUT);
    validOutputs.push_back(SH_GLSL_400_CORE_OUTPUT);
    validOutputs.push_back(SH_GLSL_410_CORE_OUTPUT);
    validOutputs.push_back(SH_GLSL_420_CORE_OUTPUT);
    validOutputs.push_back(SH_GLSL_430_CORE_OUTPUT);
    validOutputs.push_back(SH_GLSL_440_CORE_OUTPUT);
    validOutputs.push_back(SH_GLSL_450_CORE_OUTPUT);
    validOutputs.push_back(SH_SPIRV_VULKAN_OUTPUT);
    validOutputs.push_back(SH_HLSL_4_1_OUTPUT);
    bool found = false;
    for (auto valid : validOutputs)
    {
        found = found || (valid == shaderOutput);
    }
    if (!found)
    {
        return 0;
    }

    if (!sh::Initialize())
    {
        return 0;
    }

    TranslatorCacheKey key;
    key.type   = type;
    key.spec   = spec;
    key.output = shaderOutput;

    using UniqueTCompiler = std::unique_ptr<TCompiler, TCompilerDeleter>;
    static angle::base::NoDestructor<angle::HashMap<TranslatorCacheKey, UniqueTCompiler>>
        translators;

    if (translators->find(key) == translators->end())
    {
        UniqueTCompiler translator(
            ConstructCompiler(type, static_cast<ShShaderSpec>(spec), shaderOutput));

        if (translator == nullptr)
        {
            return 0;
        }

        ShBuiltInResources resources;
        sh::InitBuiltInResources(&resources);

        // Enable all the extensions to have more coverage
        resources.OES_standard_derivatives        = 1;
        resources.OES_EGL_image_external          = 1;
        resources.OES_EGL_image_external_essl3    = 1;
        resources.NV_EGL_stream_consumer_external = 1;
        resources.ARB_texture_rectangle           = 1;
        resources.EXT_blend_func_extended         = 1;
        resources.EXT_conservative_depth          = 1;
        resources.EXT_shader_framebuffer_fetch    = 1;
        resources.ARM_shader_framebuffer_fetch    = 1;
        resources.ARM_shader_framebuffer_fetch_depth_stencil = 1;
        resources.EXT_YUV_target                  = 1;
        resources.APPLE_clip_distance             = 1;
        resources.MaxDualSourceDrawBuffers        = 1;
        resources.EXT_gpu_shader5                 = 1;
        resources.MaxClipDistances                = 1;
        resources.EXT_shadow_samplers             = 1;
        resources.EXT_clip_cull_distance          = 1;
        resources.ANGLE_clip_cull_distance        = 1;
        resources.EXT_primitive_bounding_box      = 1;
        resources.OES_primitive_bounding_box      = 1;

        // Some extensions are not allowed in WebGL2
        if (spec == SH_WEBGL2_SPEC)
        {
            resources.EXT_frag_depth         = 0;
            resources.EXT_shader_texture_lod = 0;
            resources.EXT_draw_buffers       = 0;
        }
        else
        {
            resources.EXT_frag_depth         = 1;
            resources.EXT_shader_texture_lod = 1;
            resources.EXT_draw_buffers       = 1;
        }

        if (!translator->Init(resources))
        {
            return 0;
        }

        (*translators)[key] = std::move(translator);
    }

    auto &translator = (*translators)[key];

    // Enable options that any security-sensitive application should enable, otherwise it's easy to
    // trigger various inactionable errors.
    options.limitExpressionComplexity = true;
    options.limitCallStackDepth                     = true;
    options.rejectWebglShadersWithLargeVariables    = true;
    options.rejectWebglShadersWithUndefinedBehavior = true;
    const char *shaderStrings[]       = {reinterpret_cast<const char *>(data)};

    // Dump the string being passed to the compiler to ease debugging.
    // The string is written char-by-char and unwanted characters are replaced with whitespace.
    // This is because characters such as \r can hide the shader contents.
    std::cerr << "\nCompile input with unprintable characters turned to whitespace:\n";
    for (const char *c = shaderStrings[0]; *c; ANGLE_UNSAFE_TODO(++c))
    {
        if (*c < ' ' && *c != '\n')
        {
            std::cerr << ' ';
        }
        else
        {
            std::cerr << *c;
        }
    }
    std::cerr << "\nEnd of compile input.\n\n";

    translator->compile(shaderStrings, options);

    return 0;
}
