/* * LLVM libFuzzer harness for tinygltf with the custom JSON backend * (tinygltf_json.h). * * Exercises: * 1. LoadASCIIFromString – glTF JSON parsing * 2. LoadBinaryFromMemory – GLB binary parsing * * Build (clang with libFuzzer): * clang++ -std=c++11 -fsanitize=address,fuzzer \ * -DTINYGLTF_USE_CUSTOM_JSON \ * -I../../ fuzz_gltf_customjson.cc \ * -o fuzz_gltf_customjson * * Run: * ./fuzz_gltf_customjson -rss_limit_mb=20000 -jobs 4 */ #include #include #define STB_IMAGE_IMPLEMENTATION #define STB_IMAGE_WRITE_IMPLEMENTATION #define TINYGLTF_IMPLEMENTATION #ifndef TINYGLTF_USE_CUSTOM_JSON #define TINYGLTF_USE_CUSTOM_JSON #endif #include "tiny_gltf.h" /* Fuzz the ASCII (JSON) parser path */ static void fuzz_ascii(const uint8_t *data, size_t size) { tinygltf::Model model; tinygltf::TinyGLTF ctx; std::string err; std::string warn; const char *str = reinterpret_cast(data); bool ret = ctx.LoadASCIIFromString(&model, &err, &warn, str, static_cast(size), /* base_dir */ ""); (void)ret; } /* Fuzz the binary (GLB) parser path */ static void fuzz_binary(const uint8_t *data, size_t size) { tinygltf::Model model; tinygltf::TinyGLTF ctx; std::string err; std::string warn; bool ret = ctx.LoadBinaryFromMemory(&model, &err, &warn, data, static_cast(size), /* base_dir */ ""); (void)ret; } extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { if (size == 0) return 0; /* Use the lowest bit of the first byte to select the parse path. * The remaining bits are left for the fuzzer engine to explore; * additional paths (e.g. LoadASCIIFromFile, check_sections flags) * can be added here in the future using more selector bits. */ uint8_t selector = data[0]; const uint8_t *payload = data + 1; size_t payload_size = size - 1; if (selector & 1) { fuzz_binary(payload, payload_size); } else { fuzz_ascii(payload, payload_size); } return 0; }