/*1* *****************************************************************************2*3* SPDX-License-Identifier: BSD-2-Clause4*5* Copyright (c) 2018-2025 Gavin D. Howard and contributors.6*7* Redistribution and use in source and binary forms, with or without8* modification, are permitted provided that the following conditions are met:9*10* * Redistributions of source code must retain the above copyright notice, this11* list of conditions and the following disclaimer.12*13* * Redistributions in binary form must reproduce the above copyright notice,14* this list of conditions and the following disclaimer in the documentation15* and/or other materials provided with the distribution.16*17* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"18* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE19* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE20* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE21* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR22* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF23* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS24* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN25* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)26* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE27* POSSIBILITY OF SUCH DAMAGE.28*29* *****************************************************************************30*31* The entry point for libFuzzer when fuzzing dc.32*33*/3435#include <setjmp.h>36#include <string.h>3738#include <status.h>39#include <ossfuzz.h>40#include <vm.h>41#include <bc.h>42#include <dc.h>4344uint8_t* bc_fuzzer_data;4546/// A boolean about whether we should use -c (false) or -C (true).47static bool dc_C;4849int50LLVMFuzzerInitialize(int* argc, char*** argv)51{52BC_UNUSED(argc);5354if (argv == NULL || *argv == NULL)55{56dc_C = false;57}58else59{60char* name;6162// Get the basename63name = strrchr((*argv)[0], BC_FILE_SEP);64name = name == NULL ? (*argv)[0] : name + 1;6566// Figure out which to use.67dc_C = (strcmp(name, "dc_fuzzer_C") == 0);68}6970return 0;71}7273int74LLVMFuzzerTestOneInput(const uint8_t* Data, size_t Size)75{76BcStatus s;7778// I've already tested empty input, so just ignore.79if (Size == 0 || Data[0] == '\0') return 0;8081// Clear the global. This is to ensure a clean start.82memset(vm, 0, sizeof(BcVm));8384// Make sure to set the name.85vm->name = "dc";8687BC_SIG_LOCK;8889// We *must* do this here. Otherwise, other code could not jump out all of90// the way.91bc_vec_init(&vm->jmp_bufs, sizeof(sigjmp_buf), BC_DTOR_NONE);9293BC_SETJMP_LOCKED(vm, exit);9495// Create a string with the data.96bc_fuzzer_data = bc_vm_malloc(Size + 1);97memcpy(bc_fuzzer_data, Data, Size);98bc_fuzzer_data[Size] = '\0';99100s = dc_main((int) (bc_fuzzer_args_len - 1),101dc_C ? dc_fuzzer_args_C : dc_fuzzer_args_c);102103exit:104105BC_SIG_MAYLOCK;106107free(bc_fuzzer_data);108109return s == BC_STATUS_SUCCESS || s == BC_STATUS_QUIT ? 0 : -1;110}111112113