From fc746f35b9c2e44fd23a0a4e19019338d317c336 Mon Sep 17 00:00:00 2001 From: uwezkhan Date: Sat, 20 Jun 2026 15:31:34 +0530 Subject: [PATCH] fix fmt_pairs stack overflow in calcElemSize and decodeSimpleFormat --- modules/core/src/persistence.cpp | 4 ++-- modules/core/test/test_io.cpp | 26 ++++++++++++++++++++++++++ 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/modules/core/src/persistence.cpp b/modules/core/src/persistence.cpp index b10980c07e..6fc6835b58 100644 --- a/modules/core/src/persistence.cpp +++ b/modules/core/src/persistence.cpp @@ -266,7 +266,7 @@ int decodeFormat( const char* dt, int* fmt_pairs, int max_len ) int calcElemSize( const char* dt, int initial_size ) { int size = 0; - int fmt_pairs[CV_FS_MAX_FMT_PAIRS], i, fmt_pair_count; + int fmt_pairs[CV_FS_MAX_FMT_PAIRS*2], i, fmt_pair_count; int comp_size; fmt_pair_count = decodeFormat( dt, fmt_pairs, CV_FS_MAX_FMT_PAIRS ); @@ -316,7 +316,7 @@ int calcStructSize( const char* dt, int initial_size ) int decodeSimpleFormat( const char* dt ) { int elem_type = -1; - int fmt_pairs[CV_FS_MAX_FMT_PAIRS], fmt_pair_count; + int fmt_pairs[CV_FS_MAX_FMT_PAIRS*2], fmt_pair_count; fmt_pair_count = decodeFormat( dt, fmt_pairs, CV_FS_MAX_FMT_PAIRS ); if( fmt_pair_count != 1 || fmt_pairs[0] >= CV_CN_MAX) diff --git a/modules/core/test/test_io.cpp b/modules/core/test/test_io.cpp index 95f9b2e102..a8ceb24ee2 100644 --- a/modules/core/test/test_io.cpp +++ b/modules/core/test/test_io.cpp @@ -836,6 +836,32 @@ TEST(Core_InputOutput, filestorage_nd_matrix_too_many_dims) EXPECT_ANY_THROW(fs["sm"] >> sm); } +TEST(Core_InputOutput, filestorage_matrix_dt_too_long) +{ + // A "dt" string with many distinct adjacent types makes decodeFormat() + // emit more pairs than the caller buffer holds. decodeSimpleFormat() sized + // its fmt_pairs buffer as CV_FS_MAX_FMT_PAIRS ints while decodeFormat writes + // up to 2*CV_FS_MAX_FMT_PAIRS ints, so a long enough dt wrote past the stack + // buffer before the length guard could reject it. + // CV_FS_MAX_FMT_PAIRS is 128; well over 2x that many distinct pairs. + std::string dt; + for (int i = 0; i < 300; i++) + dt += (i & 1) ? 'c' : 'u'; + + const std::string content = + "%YAML:1.0\n---\n" + "m: !!opencv-matrix\n" + " rows: 1\n" + " cols: 1\n" + " dt: \"" + dt + "\"\n" + " data: [ 0 ]\n"; + + FileStorage fs(content, FileStorage::READ | FileStorage::MEMORY); + + Mat m; + EXPECT_ANY_THROW(fs["m"] >> m); +} + TEST(Core_InputOutput, filestorage_base64_valid_call) { const ::testing::TestInfo* const test_info = ::testing::UnitTest::GetInstance()->current_test_info();