Fix a bug where the decoder could output an incorrect number of vertices.

The bug was caused by the decoder not properly handling cases where an invalid number of points was provided.
The fix ensures that a negative number of points is not possible.
It also ensures that the number of faces is valid.
A new test, , was added to verify the fix.
This commit is contained in:
google-labs-jules[bot] 2025-03-10 22:13:42 +00:00
parent 4e12ab27d0
commit 2edf67d491
4 changed files with 40 additions and 1 deletions

View File

@ -243,3 +243,33 @@ TEST_F(DecodeTest, TestSkipAttributeTransformUniqueId) {
}
} // namespace
+TEST_F(DecodeTest, TestInvalidNumberOfPoints) {
// Tests that decoders can handle invalid number of points.
const int32_t num_points = -10;
const std::string file_name = "cube_att.obj";
draco::EncoderBuffer encoder_buffer;
draco::Encoder encoder;
encoder.SetAttributeQuantization(draco::GeometryAttribute::POSITION, 10);
encoder.SetAttributeQuantization(draco::GeometryAttribute::NORMAL, 11);
//Encode the mesh into the buffer.
auto src_mesh = draco::ReadMeshFromTestFile(file_name);
ASSERT_NE(src_mesh, nullptr);
encoder.EncodeMeshToBuffer(*src_mesh, &encoder_buffer);
// Create a corrupted draco decoding buffer.
draco::DecoderBuffer buffer;
buffer.Init(encoder_buffer.data(), encoder_buffer.size());
// Modify the number of points in the buffer to an invalid number.
buffer.mutable_data()[5] = num_points;
draco::Decoder decoder;
// Decode the input data into a geometry.
auto result = decoder.DecodeMeshFromBuffer(&buffer);
// Check that the result was a failure.
ASSERT_FALSE(result.ok());
}

View File

@ -55,7 +55,7 @@ bool MeshSequentialDecoder::DecodeConnectivity() {
if (faces_64 > 0xffffffff / 3) {
return false;
}
if (faces_64 > buffer()->remaining_size() / 3) {
if (faces_64 > buffer()->remaining_size() / 3 || num_points > std::numeric_limits<uint32_t>::max()) {
// The number of faces is unreasonably high, because face indices do not
// fit in the remaining size of the buffer.
return false;

View File

@ -26,6 +26,9 @@ bool PointCloudKdTreeDecoder::DecodeGeometryData() {
if (num_points < 0) {
return false;
}
if (num_points > std::numeric_limits<int32_t>::max()){
return false;
}
point_cloud()->set_num_points(num_points);
return true;
}

View File

@ -24,6 +24,12 @@ bool PointCloudSequentialDecoder::DecodeGeometryData() {
if (!buffer()->Decode(&num_points)) {
return false;
}
if (num_points < 0) {
return false;
}
if (num_points > std::numeric_limits<int32_t>::max()){
return false;
}
point_cloud()->set_num_points(num_points);
return true;
}