/* SPDX-License-Identifier: LGPL-2.1-or-later */

#include <string.h>

#include "bootspec.h"
#include "env-util.h"
#include "escape.h"
#include "fuzz.h"
#include "fd-util.h"
#include "json.h"

static int json_dispatch_config(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata) {
        BootConfig *config = ASSERT_PTR(userdata);

        const char *s = json_variant_string(variant);
        if (!s)
                return -EINVAL;

        _cleanup_fclose_ FILE *f = NULL;
        assert_se(f = data_to_file((const uint8_t*) s, strlen(s)));

        (void) boot_loader_read_conf(config, f, "memstream");
        return 0;
}

static int json_dispatch_entries(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata) {
        BootConfig *config = ASSERT_PTR(userdata);
        JsonVariant *entry;

        JSON_VARIANT_ARRAY_FOREACH(entry, variant) {
                if (!json_variant_is_array(entry) ||
                    json_variant_elements(entry) < 1)
                        return -EINVAL;

                JsonVariant *v;
                const char *id = NULL, *raw = NULL;
                _cleanup_free_ char *data = NULL;
                ssize_t len = -ENODATA;

                v = json_variant_by_index(entry, 0);
                if (v)
                        id = json_variant_string(v);
                if (!id)
                        continue;

                v = json_variant_by_index(entry, 1);
                if (v)
                        raw = json_variant_string(v);
                if (raw)
                        len = cunescape(raw, UNESCAPE_RELAX | UNESCAPE_ACCEPT_NUL, &data);
                if (len >= 0) {
                        _cleanup_fclose_ FILE *f = NULL;
                        assert_se(f = data_to_file((const uint8_t*) data, len));

                        assert_se(boot_config_load_type1(config, f, "/", "/entries", id) != -ENOMEM);
                }
        }

        return 0;
}

static int json_dispatch_loader(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata) {
        BootConfig *config = ASSERT_PTR(userdata);
        _cleanup_strv_free_ char **entries = NULL;
        int r;

        r = json_dispatch_strv(name, variant, flags, &entries);
        if (r < 0)
                return r;

        (void) boot_config_augment_from_loader(config, entries, false);
        return 0;
}

static const JsonDispatch data_dispatch[] = {
        { "config",  JSON_VARIANT_STRING, json_dispatch_config,  0, 0 },
        { "entries", JSON_VARIANT_ARRAY,  json_dispatch_entries, 0, 0 },
        { "loader",  JSON_VARIANT_ARRAY,  json_dispatch_loader,  0, 0 },
        {}
};

int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
        _cleanup_free_ const char *datadup = NULL;
        _cleanup_(boot_config_free) BootConfig config = BOOT_CONFIG_NULL;
        int r;

        if (outside_size_range(size, 0, 65536))
                return 0;

        /* Disable most logging if not running standalone */
        if (!getenv("SYSTEMD_LOG_LEVEL"))
                log_set_max_level(LOG_CRIT);

        assert_se(datadup = memdup_suffix0(data, size));

        _cleanup_(json_variant_unrefp) JsonVariant *v = NULL;
        r = json_parse(datadup, 0, &v, NULL, NULL);
        if (r < 0)
                return 0;

        r = json_dispatch(v, data_dispatch, NULL, 0, &config);
        if (r < 0)
                return 0;

        assert_se(boot_config_finalize(&config) >= 0);

        (void) boot_config_select_special_entries(&config, /* skip_efivars= */ false);

        _cleanup_close_ int orig_stdout_fd = -EBADF;
        if (getenv_bool("SYSTEMD_FUZZ_OUTPUT") <= 0) {
                orig_stdout_fd = fcntl(fileno(stdout), F_DUPFD_CLOEXEC, 3);
                if (orig_stdout_fd < 0)
                        log_warning_errno(orig_stdout_fd, "Failed to duplicate fd 1: %m");
                else
                        assert_se(freopen("/dev/null", "w", stdout));
        }

        (void) show_boot_entries(&config, JSON_FORMAT_OFF);
        (void) show_boot_entries(&config, JSON_FORMAT_PRETTY);

        if (orig_stdout_fd >= 0)
                assert_se(freopen(FORMAT_PROC_FD_PATH(orig_stdout_fd), "w", stdout));

        return 0;
}
