mirror of
https://github.com/syoyo/tinygltf.git
synced 2026-06-08 11:13:50 +00:00
Reject non-finite/out-of-range JSON numbers in int32/uint64 fields and array/attribute elements instead of silently truncating, initialize the model on parse-file failure, and free the partial JSON document when the root is not an object. Adds a pure-C libFuzzer harness (fuzz_gltf_v3_c) alongside the existing C++ one and tests covering the new failure modes. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
84 lines
2.6 KiB
Makefile
84 lines
2.6 KiB
Makefile
# tests/v3/fuzzer/Makefile — Build libFuzzer harnesses for tinygltf v3
|
|
#
|
|
# Requires: clang/clang++ with libFuzzer support
|
|
#
|
|
# Targets:
|
|
# make — build both harnesses with ASan + UBSan
|
|
# make run — run the dedicated pure-C v3 harness
|
|
# make run-cpp — run the legacy header-implementation harness
|
|
# make seed — generate seed corpus from test models
|
|
# make clean — remove binaries and corpus
|
|
|
|
CC = clang
|
|
CXX = clang++
|
|
CCFLAGS = -g -O1 -std=c11
|
|
CXXFLAGS = -g -O1 -std=c++17 -fno-rtti -fno-exceptions
|
|
SANITIZE = -fsanitize=fuzzer,address,undefined
|
|
INCLUDES = -I../../..
|
|
|
|
FUZZER = fuzz_gltf_v3
|
|
FUZZER_C = fuzz_gltf_v3_c
|
|
CORPUS = corpus
|
|
ARTIFACTS = artifacts
|
|
|
|
# Fuzzer runtime options
|
|
MAX_LEN ?= 65536
|
|
JOBS ?= $(shell nproc 2>/dev/null || echo 4)
|
|
MAX_TIME ?= 0
|
|
FUZZ_ENV ?= LSAN_OPTIONS=detect_leaks=0
|
|
|
|
.PHONY: all run run-cpp seed clean
|
|
|
|
all: $(FUZZER) $(FUZZER_C)
|
|
|
|
$(FUZZER): fuzz_gltf_v3.cc ../../../tiny_gltf_v3.h ../../../tiny_gltf_v3.c ../../../tinygltf_json_c.h
|
|
$(CXX) $(CXXFLAGS) $(SANITIZE) $(INCLUDES) -o $@ $<
|
|
|
|
$(FUZZER_C): fuzz_gltf_v3_c.c ../../../tiny_gltf_v3.h ../../../tiny_gltf_v3.c ../../../tinygltf_json_c.h
|
|
$(CC) $(CCFLAGS) $(SANITIZE) $(INCLUDES) -o $@ $< ../../../tiny_gltf_v3.c
|
|
|
|
run: $(FUZZER_C) | $(CORPUS) $(ARTIFACTS)
|
|
$(FUZZ_ENV) ./$(FUZZER_C) $(CORPUS) \
|
|
-artifact_prefix=$(ARTIFACTS)/ \
|
|
-max_len=$(MAX_LEN) \
|
|
-jobs=$(JOBS) \
|
|
-workers=$(JOBS) \
|
|
$(if $(filter-out 0,$(MAX_TIME)),-max_total_time=$(MAX_TIME))
|
|
|
|
run-cpp: $(FUZZER) | $(CORPUS) $(ARTIFACTS)
|
|
$(FUZZ_ENV) ./$(FUZZER) $(CORPUS) \
|
|
-artifact_prefix=$(ARTIFACTS)/ \
|
|
-max_len=$(MAX_LEN) \
|
|
-jobs=$(JOBS) \
|
|
-workers=$(JOBS) \
|
|
$(if $(filter-out 0,$(MAX_TIME)),-max_total_time=$(MAX_TIME))
|
|
|
|
# Generate seed corpus from existing test models
|
|
seed: | $(CORPUS)
|
|
@echo "Seeding corpus from test models..."
|
|
@for f in ../../../models/Cube/Cube.gltf \
|
|
../../../models/Cube/Cube.glb; do \
|
|
if [ -f "$$f" ]; then \
|
|
cp "$$f" $(CORPUS)/; \
|
|
echo " Added: $$f"; \
|
|
fi; \
|
|
done
|
|
@# Add a minimal valid glTF JSON
|
|
@echo '{"asset":{"version":"2.0"},"scene":0,"scenes":[{"nodes":[0]}],"nodes":[{"name":"n"}]}' > $(CORPUS)/minimal.gltf
|
|
@# Add a minimal valid GLB (header + empty JSON chunk)
|
|
@printf 'glTF\x02\x00\x00\x00\x1c\x00\x00\x00\x04\x00\x00\x00JSON{} ' > $(CORPUS)/minimal.glb
|
|
@# Add edge cases
|
|
@echo '{}' > $(CORPUS)/empty_object.gltf
|
|
@echo '{"asset":{"version":"2.0"}}' > $(CORPUS)/asset_only.gltf
|
|
@echo "Corpus: $$(ls $(CORPUS) | wc -l) files"
|
|
|
|
$(CORPUS):
|
|
mkdir -p $(CORPUS)
|
|
|
|
$(ARTIFACTS):
|
|
mkdir -p $(ARTIFACTS)
|
|
|
|
clean:
|
|
rm -f $(FUZZER) $(FUZZER_C)
|
|
rm -rf $(CORPUS) $(ARTIFACTS)
|