From 484403500e2573fc28d221ebdd48d6449bd143dd Mon Sep 17 00:00:00 2001 From: ztzat089-ctrl Date: Fri, 7 Aug 2026 13:03:21 +0000 Subject: [PATCH] Fix heap overflow in CopyDataAsFloatImpl by validating accessor bounds --- src/draco/io/tiny_gltf_utils.h | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/draco/io/tiny_gltf_utils.h b/src/draco/io/tiny_gltf_utils.h index a536a70fb..c0a85adaa 100644 --- a/src/draco/io/tiny_gltf_utils.h +++ b/src/draco/io/tiny_gltf_utils.h @@ -104,6 +104,26 @@ class TinyGltfUtils { const unsigned char *const data_start = buffer.data.data() + buffer_view.byteOffset + accessor.byteOffset; const int byte_stride = accessor.ByteStride(buffer_view); + + // Validate that reading |accessor.count| elements with |byte_stride| + // does not read past the end of the buffer. + if (accessor.count < 0 || byte_stride <= 0) { + return Status(Status::DRACO_ERROR, + "Error CopyDataAsFloat() invalid accessor."); + } + const size_t start_offset = + buffer_view.byteOffset + accessor.byteOffset; + if (start_offset > buffer.data.size()) { + return Status(Status::DRACO_ERROR, + "Error CopyDataAsFloat() accessor offset out of bounds."); + } + const size_t available_bytes = buffer.data.size() - start_offset; + const size_t required_bytes = + static_cast(byte_stride) * static_cast(accessor.count); + if (required_bytes > available_bytes) { + return Status(Status::DRACO_ERROR, + "Error CopyDataAsFloat() accessor data out of bounds."); + } const int component_size = tinygltf::GetComponentSizeInBytes(accessor.componentType);