diff --git a/modules/ptcloud/src/io_ply.cpp b/modules/ptcloud/src/io_ply.cpp index 9652bda8aa..5d9b025e46 100644 --- a/modules/ptcloud/src/io_ply.cpp +++ b/modules/ptcloud/src/io_ply.cpp @@ -50,11 +50,16 @@ bool PlyDecoder::parseHeader(std::ifstream &file, int& nTexCoords) { e = trimSpaces(e); } - if (splitArr[0] != "format") + if (splitArr.empty() || splitArr[0] != "format") { CV_LOG_ERROR(NULL, "Provided file doesn't have format"); return false; } + if (splitArr.size() < 2) + { + CV_LOG_ERROR(NULL, "Provided PLY file format is not supported"); + return false; + } if (splitArr[1] == "ascii") { m_inputDataFormat = DataFormat::ASCII; @@ -104,7 +109,13 @@ bool PlyDecoder::parseHeader(std::ifstream &file, int& nTexCoords) { e = trimSpaces(e); } - std::string elemName = splitArrElem.at(1); + if (splitArrElem.size() < 2) + { + CV_LOG_ERROR(NULL, "Element description has " << splitArrElem.size() + << " words instead of at least 2"); + return false; + } + std::string elemName = splitArrElem[1]; if (elemName == "vertex") { elemRead = READ_VERTEX; diff --git a/modules/ptcloud/test/test_pointcloud_io.cpp b/modules/ptcloud/test/test_pointcloud_io.cpp index e18c54d66e..4dbf2e3eb2 100644 --- a/modules/ptcloud/test/test_pointcloud_io.cpp +++ b/modules/ptcloud/test/test_pointcloud_io.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include "test_precomp.hpp" #include "opencv2/ts.hpp" @@ -296,4 +297,43 @@ TEST(PointCloud, SaveBadExtension) cv::savePointCloud(folder + "pointcloudio/fake.fake", points, normals); } +TEST(PointCloud, LoadPlyEmptyFormatLine) +{ + std::string path = tempfile("empty_format.ply"); + std::ofstream file(path, std::ios::binary); + file << "ply\n\n"; + file.close(); + + std::vector points, normals, rgb; + cv::loadPointCloud(path, points, normals, rgb); + EXPECT_TRUE(points.empty()); + std::remove(path.c_str()); +} + +TEST(PointCloud, LoadPlyFormatLineNoSeparator) +{ + std::string path = tempfile("no_separator_format.ply"); + std::ofstream file(path, std::ios::binary); + file << "ply\nformat\r\r\r\r\r\r\r\r\r\r\r\r\n"; + file.close(); + + std::vector points, normals, rgb; + cv::loadPointCloud(path, points, normals, rgb); + EXPECT_TRUE(points.empty()); + std::remove(path.c_str()); +} + +TEST(PointCloud, LoadPlyMalformedElementLine) +{ + std::string path = tempfile("malformed_element.ply"); + std::ofstream file(path, std::ios::binary); + file << "ply\nformat ascii 1.0\nelement\nend_header\n"; + file.close(); + + std::vector points, normals, rgb; + cv::loadPointCloud(path, points, normals, rgb); + EXPECT_TRUE(points.empty()); + std::remove(path.c_str()); +} + }} /* namespace opencv_test */