From 9ef24def649528850ae4e3f33c05d1b82e0390aa Mon Sep 17 00:00:00 2001 From: mohammadmseet Date: Sun, 29 Mar 2026 14:03:10 +0200 Subject: [PATCH] Fix integer overflow in computeBindingSize for glTF accessors Add overflow validation to computeBindingSize(), consistent with the existing overflow check already present in decodeMeshoptCompression() in the same file (lines 100-104). The multiplication accessor->stride * (accessor->count - 1) can overflow when both stride and count are large values from a glTF file. The result is truncated to uint32_t, producing an undersized value that is used for buffer allocation in ResourceLoader. Uses postcondition checks as requested in review. --- libs/gltfio/src/Utility.cpp | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/libs/gltfio/src/Utility.cpp b/libs/gltfio/src/Utility.cpp index b7a771d0cac4..45934c8aee03 100644 --- a/libs/gltfio/src/Utility.cpp +++ b/libs/gltfio/src/Utility.cpp @@ -168,7 +168,20 @@ bool primitiveHasVertexColor(cgltf_primitive* inPrim) { // private but its implementation file is available in this cpp file. uint32_t computeBindingSize(cgltf_accessor const* accessor) { cgltf_size element_size = cgltf_calc_size(accessor->type, accessor->component_type); - return uint32_t(accessor->stride * (accessor->count - 1) + element_size); + // Validate against overflow, consistent with the check in decodeMeshoptCompression above. + FILAMENT_CHECK_POSTCONDITION(accessor->count > 0) + << "gltfio: accessor count must be > 0"; + cgltf_size const countMinus1 = accessor->count - 1; + if (accessor->stride > 0) { + cgltf_size const maxCount = std::numeric_limits::max() / accessor->stride; + FILAMENT_CHECK_POSTCONDITION(countMinus1 <= maxCount) + << "gltfio: binding size overflow (stride=" << accessor->stride + << ", count=" << accessor->count << ")"; + } + cgltf_size const result = accessor->stride * countMinus1 + element_size; + FILAMENT_CHECK_POSTCONDITION(result <= std::numeric_limits::max()) + << "gltfio: binding size exceeds uint32_t max"; + return uint32_t(result); } void convertBytesToShorts(uint16_t* dst, uint8_t const* src, size_t count) {