From 2906d4d73a8afa654ab150ae44056a2b26bfd8b7 Mon Sep 17 00:00:00 2001 From: uwezkhan Date: Sun, 14 Jun 2026 02:51:20 +0530 Subject: [PATCH] reject nd-matrix dim count above CV_MAX_DIM in FileStorage read --- modules/core/src/persistence_types.cpp | 2 ++ modules/core/test/test_io.cpp | 29 ++++++++++++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/modules/core/src/persistence_types.cpp b/modules/core/src/persistence_types.cpp index 8aa929cc1d..6ea259d9bc 100644 --- a/modules/core/src/persistence_types.cpp +++ b/modules/core/src/persistence_types.cpp @@ -142,6 +142,7 @@ void read(const FileNode& node, Mat& m, const Mat& default_mat) CV_Assert( !sizes_node.empty() ); dims = (int)sizes_node.size(); + CV_Assert( dims > 0 && dims <= CV_MAX_DIM ); sizes_node.readRaw("i", sizes, dims*sizeof(sizes[0])); m.create(dims, sizes, elem_type); @@ -180,6 +181,7 @@ void read( const FileNode& node, SparseMat& m, const SparseMat& default_mat ) CV_Assert( !sizes_node.empty() ); int dims = (int)sizes_node.size(); + CV_Assert( dims > 0 && dims <= CV_MAX_DIM ); sizes_node.readRaw("i", sizes, dims*sizeof(sizes[0])); m.create(dims, sizes, elem_type); diff --git a/modules/core/test/test_io.cpp b/modules/core/test/test_io.cpp index 42e49c5b93..95f9b2e102 100644 --- a/modules/core/test/test_io.cpp +++ b/modules/core/test/test_io.cpp @@ -807,6 +807,35 @@ TEST(Core_InputOutput, filestorage_heap_overflow) EXPECT_EQ(0, remove(name.c_str())); } +TEST(Core_InputOutput, filestorage_nd_matrix_too_many_dims) +{ + // A declared dimension count above CV_MAX_DIM used to write the sizes list + // past the fixed-size sizes[CV_MAX_DIM] stack buffer in cv::read(). + std::string sizes; + for (int i = 0; i < CV_MAX_DIM + 8; i++) + sizes += "2, "; + sizes += "2"; + + const std::string content = + "%YAML:1.0\n---\n" + "m: !!opencv-nd-matrix\n" + " sizes: [ " + sizes + " ]\n" + " dt: f\n" + " data: [ 0., 0. ]\n" + "sm: !!opencv-sparse-matrix\n" + " sizes: [ " + sizes + " ]\n" + " dt: f\n" + " data: [ ]\n"; + + FileStorage fs(content, FileStorage::READ | FileStorage::MEMORY); + + Mat m; + EXPECT_ANY_THROW(fs["m"] >> m); + + SparseMat sm; + EXPECT_ANY_THROW(fs["sm"] >> sm); +} + TEST(Core_InputOutput, filestorage_base64_valid_call) { const ::testing::TestInfo* const test_info = ::testing::UnitTest::GetInstance()->current_test_info();