From be64298218969ed243fd1184ea62dc7dcf7571e7 Mon Sep 17 00:00:00 2001 From: Kelsi Date: Wed, 6 May 2026 06:19:01 -0700 Subject: [PATCH] fix(dbc): cap JSON DBC string sizes (4KB/string, 64MB total) + NaN floats MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit JSON DBC values are mostly small integers, but a malicious file could stuff 100MB strings into every cell to OOM the stringBlock (which has no per-string or total cap). Added 4KB per-string + 64MB total caps — fields exceeding either are zeroed. Float fields also get NaN scrub (same pattern as the earlier vertex/keyframe guards). --- src/pipeline/dbc_loader.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/pipeline/dbc_loader.cpp b/src/pipeline/dbc_loader.cpp index 8bc784a4..7b3fdc50 100644 --- a/src/pipeline/dbc_loader.cpp +++ b/src/pipeline/dbc_loader.cpp @@ -2,6 +2,7 @@ #include "core/logger.hpp" #include #include +#include #include #include #include @@ -430,8 +431,14 @@ bool DBCFile::loadJSON(const std::vector& jsonData) { const auto& val = row[col]; if (val.is_string()) { const std::string& str = val.get_ref(); + // Cap individual string at 4KB and total stringBlock at + // 64MB to prevent OOM from a malicious JSON DBC stuffing + // huge strings into every field. if (str.empty()) { fields[col] = 0; + } else if (str.size() > 4096 || + stringBlock.size() + str.size() > 64ull * 1024 * 1024) { + fields[col] = 0; } else { fields[col] = static_cast(stringBlock.size()); stringBlock.insert(stringBlock.end(), str.begin(), str.end()); @@ -439,6 +446,7 @@ bool DBCFile::loadJSON(const std::vector& jsonData) { } } else if (val.is_number_float()) { float f = val.get(); + if (!std::isfinite(f)) f = 0.0f; std::memcpy(&fields[col], &f, 4); } else if (val.is_number_integer()) { fields[col] = val.get();