Add intensive parser unit tester and LLVM fuzzer for tinygltf_json.h backend

Co-authored-by: syoyo <18676+syoyo@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot]
2026-03-19 00:42:53 +00:00
parent df3efc6453
commit 2c1a8be82d
25 changed files with 1184 additions and 1729 deletions

View File

@@ -4,3 +4,4 @@
all: ../tiny_gltf.h
clang++ -I../ $(EXTRA_CXXFLAGS) -std=c++11 -g -O0 -o tester tester.cc
clang++ -DTINYGLTF_NOEXCEPTION -I../ $(EXTRA_CXXFLAGS) -std=c++11 -g -O0 -o tester_noexcept tester.cc
clang++ -DTINYGLTF_USE_CUSTOM_JSON -I../ $(EXTRA_CXXFLAGS) -std=c++11 -g -O0 -o tester_intensive_customjson tester_intensive_customjson.cc

View File

@@ -7,6 +7,11 @@ Do fuzzing test for TinyGLTF API.
* [x] LoadASCIIFromMemory
* [ ] LoadBinaryFromMemory
### Custom JSON backend (`tinygltf_json.h`)
* [x] LoadASCIIFromMemory
* [x] LoadBinaryFromMemory
## Requirements
* meson
@@ -36,11 +41,17 @@ $ cd build
$ ninja
```
This builds two fuzzers:
* `fuzz_gltf` default nlohmann/json backend
* `fuzz_gltf_customjson` custom `tinygltf_json.h` backend (tests both ASCII and binary parsing paths)
## How to run
Increase memory limit. e.g. `-rss_limit_mb=50000`
```
$ ./fuzz_gltf -rss_limit_mb=20000 -jobs 4
$ ./fuzz_gltf_customjson -rss_limit_mb=20000 -jobs 4
```

View File

@@ -0,0 +1,76 @@
/*
* 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 <cstdint>
#include <cstring>
#include <memory>
#include <vector>
#include <iostream>
#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<const char *>(data);
bool ret =
ctx.LoadASCIIFromString(&model, &err, &warn, str,
static_cast<unsigned int>(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<unsigned int>(size),
/* base_dir */ "");
(void)ret;
}
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
if (size == 0) return 0;
/* Use the first byte to select the parse path, pass the rest as input. */
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;
}

View File

@@ -7,3 +7,9 @@ executable('fuzz_gltf',
cpp_args : '-fsanitize=address,fuzzer',
link_args : '-fsanitize=address,fuzzer' )
executable('fuzz_gltf_customjson',
'fuzz_gltf_customjson.cc',
include_directories : incdirs,
cpp_args : ['-fsanitize=address,fuzzer', '-DTINYGLTF_USE_CUSTOM_JSON'],
link_args : '-fsanitize=address,fuzzer' )

File diff suppressed because it is too large Load Diff