/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
 * Copyright (C) 2023 Google, Inc.
 */

#include <config.h>
#include <string.h>
#include <stdint.h>
#include <glib.h>

/* Include the whole fuzzer test file */
int LLVMFuzzerTestOneInput (const uint8_t *data,
                            size_t         size);
#include "test-message-fuzzer.c"

static void
test_fuzzer_sample_basic (void)
{
    const guint8 data[] = { 0x3 };

    g_assert_cmpuint (LLVMFuzzerTestOneInput (data, G_N_ELEMENTS (data)), ==, 0);
}

static void
test_fuzzer_sample_invalid_array_size (void)
{
    const guint8 data[] = {
        0x3,0x0,0x0,0x80,0x46,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,
        0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x68,0x22,0x3d,0x4,0x9f,
        0x6c,0x4e,0xf,0x82,0x2d,0x28,0x44,0x1f,0xb7,0x23,0x40,
        0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x5,0x0,0x0,0x0,0x0,
        0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2e,0xb7,0x23,
        0x40,0x59,0x67,0xbd,0xcc,0x7f,0xd2,0x49,0xa2,0x9f,0x5c,
        0xb2,0xe7,0xe,0x52,0x7d,0xb3,0x1,0x0,0x0,0x0,0x23,0x40,
        0x1,0x0,0x0,0x0,0x0,0x3,0x0,0x0,0x9 };

    g_assert_cmpuint (LLVMFuzzerTestOneInput (data, G_N_ELEMENTS (data)), ==, 0);
}

static void
test_fuzzer_sample_invalid_offset_unbound_bytearray (void)
{
    const guint8 data[] = {
        0x3,0x0,0x0,0x80,0x31,0x0,0x0,0x0,0x0,0x4c,0x0,0x0,0x1,
        0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xc2,0xf6,0x58,0x8e,0xf0,0x37,
        0x4b,0xc9,0x86,0x65,0xf4,0xd4,0x4b,0xd0,0x93,0x67,0x5,0x0,
        0x0,0x0,0x4c,0x0,0x5d,0x0,0x1,0x0,0x0,0x0,0x0,0x4,0x0,0x0,
        0x80,0x0,0x0,0x0,0xa0,0x0,0x0,0x1,0x0,0x80,0x32 };

    g_assert_cmpuint (LLVMFuzzerTestOneInput (data, G_N_ELEMENTS (data)), ==, 0);
}

static void
test_fuzzer_sample_ms_struct_array_with_string (void)
{
    const guint8 data[] = {
        0x3,0x0,0x0,0x80,0x54,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x0,
        0x0,0x0,0x0,0x0,0x0,0x0,0x3d,0x1,0xdc,0xc5,0xfe,0xf5,0x4d,
        0x5,0xd,0x3a,0xbe,0xf7,0x5,0x8e,0x9a,0xaf,0xb,0x0,0x0,0x0,
        0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x0,0x40,0x0,0x7a,0x1d,0x0,
        0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
        0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x12,0x0,
        0x0,0x0,0x0,0x0,0x0,0x7a,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
        0x3b,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,
        0x0,0x0,0x0,0x0,0x0,0xa2,0x89,0xcc,0x33,0xbc,0xbb,0x8b,0x4f,
        0xb6,0xb0,0x13,0x3e,0xc2,0xaa,0xe6,0xdf,0x1,0x0,0x0,0x0,0x0,
        0x0,0x2,0x0,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xa4,0xa4,0x3,
        0x0,0x0,0x0,0x24,0x0,0x0,0xfe,0xf5,0x4d,0x5,0xd,0x3a,0xbe,
        0xf7,0x5,0x8e,0x9a,0xaf,0xb,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,
        0x0,0x0,0x0,0x0,0x40,0x0,0x7a,0x1d,0x0,0x0,0x0,0x0,0x0,0x0,
        0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
        0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x12,0x0,0x0,0x0,0x0,0x0,0x0,
        0x0,0x0,0x15,0x0,0x0,0x0,0x80,0xad,0xa4,0x9b,0x9b,0x9b,0xbd,
        0xbd
    };

    g_assert_cmpuint (LLVMFuzzerTestOneInput (data, G_N_ELEMENTS (data)), ==, 0);
}

static void
test_fuzzer_sample_ref_struct_array_with_unsized_bytearrays (void)
{
    const guint8 data[] = {
        0x3,0x0,0x0,0x80,0x33,0x0,0x0,0x0,0x0,0x0,0x55,0x8,0x1,0x0,0x0,
        0x0,0x0,0x0,0x0,0x0,0xc2,0xf6,0x58,0x8e,0xf0,0x37,0x4b,0xc9,0x86,
        0x65,0xf4,0xd4,0x4b,0xd0,0x93,0x67,0x5,0x0,0x0,0x0,0x32,0x0,0x0,
        0x0,0x1,0x0,0x0,0x0,0x0,0x1,0x0,0xff,0xff,0xff,0xff,0xff,0xff,
        0xff,0xff,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
        0x0,0xb0,0x13,0x12,0x0,0xca,0xca,0xca,0x0,0x0,0xe8
    };

    g_assert_cmpuint (LLVMFuzzerTestOneInput (data, G_N_ELEMENTS (data)), ==, 0);
}

int main (int argc, char **argv)
{
    g_test_init (&argc, &argv, NULL);

#define PREFIX "/libmbim-glib/message/fuzzer-samples/"
    g_test_add_func (PREFIX "basic", test_fuzzer_sample_basic);
    g_test_add_func (PREFIX "invalid-arraysize", test_fuzzer_sample_invalid_array_size);
    g_test_add_func (PREFIX "invalid-offset-unbound-bytearray", test_fuzzer_sample_invalid_offset_unbound_bytearray);
    g_test_add_func (PREFIX "ms-struct-array-with-string", test_fuzzer_sample_ms_struct_array_with_string);
    g_test_add_func (PREFIX "ref-struct-array-with-unsized-bytearrays", test_fuzzer_sample_ref_struct_array_with_unsized_bytearrays);
#undef PREFIX
    return g_test_run ();
}
