1
0
mirror of https://github.com/opencv/opencv.git synced 2026-07-21 19:33:03 +04:00

bound marker string length in aruco readDictionary

This commit is contained in:
Uwez Khan
2026-07-16 19:44:15 +05:30
parent 2e778c52c1
commit b5fe8dfef3
2 changed files with 44 additions and 0 deletions
@@ -109,6 +109,8 @@ bool Dictionary::readDictionary(const cv::FileNode& fn) {
int nMarkers = 0, _markerSize = 0; int nMarkers = 0, _markerSize = 0;
if (fn.empty() || !readParameter("nmarkers", nMarkers, fn) || !readParameter("markersize", _markerSize, fn)) if (fn.empty() || !readParameter("nmarkers", nMarkers, fn) || !readParameter("markersize", _markerSize, fn))
return false; return false;
if (_markerSize <= 0)
return false;
Mat bytes(0, 0, CV_8UC1), marker(_markerSize, _markerSize, CV_8UC1); Mat bytes(0, 0, CV_8UC1), marker(_markerSize, _markerSize, CV_8UC1);
std::string markerString; std::string markerString;
for (int i = 0; i < nMarkers; i++) { for (int i = 0; i < nMarkers; i++) {
@@ -116,6 +118,8 @@ bool Dictionary::readDictionary(const cv::FileNode& fn) {
ostr << i; ostr << i;
if (!readParameter("marker_" + ostr.str(), markerString, fn)) if (!readParameter("marker_" + ostr.str(), markerString, fn))
return false; return false;
if (markerString.size() != (size_t)_markerSize * _markerSize)
return false;
for (int j = 0; j < (int) markerString.size(); j++) for (int j = 0; j < (int) markerString.size(); j++)
marker.at<unsigned char>(j) = (markerString[j] == '0') ? 0 : 1; marker.at<unsigned char>(j) = (markerString[j] == '0') ? 0 : 1;
bytes.push_back(Dictionary::getByteListFromBits(marker)); bytes.push_back(Dictionary::getByteListFromBits(marker));
@@ -1409,6 +1409,46 @@ TEST(CV_ArucoMultiDict, serialization)
} }
TEST(CV_ArucoDictionary, readDictionary_oversized_marker)
{
// A marker string longer than markersize*markersize must be rejected instead of
// being written past the markersize x markersize buffer in readDictionary.
std::string serialized;
{
FileStorage fs_out(".json", FileStorage::WRITE + FileStorage::MEMORY);
ASSERT_TRUE(fs_out.isOpened());
fs_out << "nmarkers" << 1;
fs_out << "markersize" << 5;
fs_out << "marker_0" << std::string(2000, '1');
serialized = fs_out.releaseAndGetString();
}
FileStorage fs_in(serialized, FileStorage::READ + FileStorage::MEMORY);
ASSERT_TRUE(fs_in.isOpened());
aruco::Dictionary dict;
bool ok = true;
ASSERT_NO_THROW(ok = dict.readDictionary(fs_in.root()));
EXPECT_FALSE(ok);
}
TEST(CV_ArucoDictionary, readDictionary_roundtrip)
{
aruco::Dictionary dict = aruco::getPredefinedDictionary(aruco::DICT_5X5_50);
std::string serialized;
{
FileStorage fs_out(".json", FileStorage::WRITE + FileStorage::MEMORY);
ASSERT_TRUE(fs_out.isOpened());
dict.writeDictionary(fs_out);
serialized = fs_out.releaseAndGetString();
}
FileStorage fs_in(serialized, FileStorage::READ + FileStorage::MEMORY);
ASSERT_TRUE(fs_in.isOpened());
aruco::Dictionary loaded;
ASSERT_TRUE(loaded.readDictionary(fs_in.root()));
EXPECT_EQ(dict, loaded);
}
struct ArucoThreading: public testing::TestWithParam<aruco::CornerRefineMethod> struct ArucoThreading: public testing::TestWithParam<aruco::CornerRefineMethod>
{ {
struct NumThreadsSetter { struct NumThreadsSetter {