Merge pull request #29866 from lazerg:fix/issue-29865-ply-parseheader-bounds

ptcloud: bounds-check split() results in PLY header parsing
This commit is contained in:
Alexander Smorkalov
2026-09-04 16:37:47 +03:00
committed by GitHub
2 changed files with 53 additions and 2 deletions

View File

@@ -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;

View File

@@ -5,6 +5,7 @@
#include <opencv2/core.hpp>
#include <vector>
#include <cstdio>
#include <fstream>
#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<cv::Point3f> 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<cv::Point3f> 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<cv::Point3f> points, normals, rgb;
cv::loadPointCloud(path, points, normals, rgb);
EXPECT_TRUE(points.empty());
std::remove(path.c_str());
}
}} /* namespace opencv_test */