mirror of
https://github.com/syoyo/tinygltf.git
synced 2026-06-08 03:03:50 +00:00
Fix fuzzer-found bugs, add libFuzzer harness for v3
Add tests/v3/fuzzer/ with libFuzzer harness covering all four parse paths (auto-detect, JSON, GLB, float32 mode) with ASan+UBSan. Fix two bugs found by 10+ hours of fuzzing (~23M iterations): 1. UB: (int64_t)inf in cj_parse_number when extreme exponents like 22222222e222222 produce infinity. Add cj_dbl_to_i64() that clamps inf/NaN/out-of-range values before casting. 2. Null deref in tg3__parse_string when glTF array elements are not JSON objects (e.g. "scenes": [[3]]). Add is_object() validation in TG3__PARSE_ARRAY_SIMPLE and TG3__PARSE_ARRAY_IDX macros. Verified clean: 5.8M additional runs with zero crashes after fixes. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -307,6 +307,14 @@ static const char *cj_scan_str(const char *p, const char *end) {
|
||||
* Breaks strict JSON/IEEE-754-double conformance.
|
||||
* ====================================================================== */
|
||||
|
||||
/* Safe double-to-int64 cast: clamp inf/NaN/out-of-range to 0. */
|
||||
static int64_t cj_dbl_to_i64(double d) {
|
||||
if (d != d) return 0; /* NaN */
|
||||
if (d >= (double)INT64_MAX) return INT64_MAX;
|
||||
if (d <= (double)INT64_MIN) return INT64_MIN;
|
||||
return (int64_t)d;
|
||||
}
|
||||
|
||||
/* Exact powers of 10 that are representable as IEEE 754 double.
|
||||
* 10^0 through 10^22 are all exactly representable. */
|
||||
static const double cj_exact_pow10[23] = {
|
||||
@@ -526,7 +534,7 @@ static const char *cj_parse_number(const char *p, const char *end,
|
||||
if (cj_fast_flt_convert(mantissa, exp10, neg, &f)) {
|
||||
*is_int = 0;
|
||||
*dval = (double)f;
|
||||
*ival = (int64_t)f;
|
||||
*ival = cj_dbl_to_i64((double)f);
|
||||
return p;
|
||||
}
|
||||
} else {
|
||||
@@ -534,7 +542,7 @@ static const char *cj_parse_number(const char *p, const char *end,
|
||||
if (cj_fast_dbl_convert(mantissa, exp10, neg, &d)) {
|
||||
*is_int = 0;
|
||||
*dval = d;
|
||||
*ival = (int64_t)d;
|
||||
*ival = cj_dbl_to_i64(d);
|
||||
return p;
|
||||
}
|
||||
}
|
||||
@@ -547,7 +555,7 @@ static const char *cj_parse_number(const char *p, const char *end,
|
||||
if (float32_mode) d = (double)(float)d;
|
||||
*is_int = 0;
|
||||
*dval = d;
|
||||
*ival = (int64_t)d;
|
||||
*ival = cj_dbl_to_i64(d);
|
||||
return eptr;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user