From b0fe66b30e62ac5981df2baba3b5a2f73d4d83c5 Mon Sep 17 00:00:00 2001 From: Shuvam Pandey Date: Wed, 22 Jul 2026 12:52:27 +0545 Subject: [PATCH] [hist] Fix TFormula Hessian result sizing HessianPar writes fNpar * fNpar entries, but its CladStorage overload only resized results smaller than fNpar. For two or more parameters, a partially sized result could pass the check and leave Clad writing past the vector's size. Check for the full flattened Hessian size and cover the missed case in ResultUpsize. --- hist/hist/src/TFormula.cxx | 2 +- hist/hist/test/TFormulaHessianTests.cxx | 17 ++++++++--------- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/hist/hist/src/TFormula.cxx b/hist/hist/src/TFormula.cxx index 376c4ae49c276..2888bf66c7c75 100644 --- a/hist/hist/src/TFormula.cxx +++ b/hist/hist/src/TFormula.cxx @@ -3419,7 +3419,7 @@ void TFormula::HessianPar(const Double_t *x, TFormula::CladStorage& result) return; } - if ((int)result.size() < fNpar) { + if ((int)result.size() < fNpar * fNpar) { Warning("HessianPar", "The size of hessian result is %zu but %d is required. Resizing.", result.size(), fNpar * fNpar); diff --git a/hist/hist/test/TFormulaHessianTests.cxx b/hist/hist/test/TFormulaHessianTests.cxx index 2a4c4bd401d87..5e8dc792bc400 100644 --- a/hist/hist/test/TFormulaHessianTests.cxx +++ b/hist/hist/test/TFormulaHessianTests.cxx @@ -43,20 +43,19 @@ TEST(TFormulaHessianPar, ResultUpsize) TFormula f("f", "std::sin([1]) - std::cos([0])"); double p[] = {60, 30}; f.SetParameters(p); - TFormula::CladStorage result; + // Two elements passed the old check, but a 2x2 Hessian needs four. + TFormula::CladStorage result(2); double x[] = {2, 1}; - ASSERT_TRUE(result.empty()); - ROOT_EXPECT_WARNING(f.HessianPar(x, result), - "TFormula::HessianPar", - "The size of hessian result is 0 but 4 is required. Resizing." - ); + ASSERT_TRUE(2 == result.size()); + ROOT_EXPECT_WARNING(f.HessianPar(x, result), "TFormula::HessianPar", + "The size of hessian result is 2 but 4 is required. Resizing."); + ASSERT_TRUE(4 == result.size()); ASSERT_FLOAT_EQ(std::cos(p[0]), result[0]); ASSERT_FLOAT_EQ(0, result[1]); ASSERT_FLOAT_EQ(0, result[2]); - ASSERT_FLOAT_EQ(- std::sin(p[1]), result[3]); - ASSERT_TRUE(4 == result.size()); + ASSERT_FLOAT_EQ(-std::sin(p[1]), result[3]); } TEST(TFormulaHessianPar, ResultDownsize) @@ -86,4 +85,4 @@ TEST(TFormulaHessianPar, GetHessFormula) #ifndef R__WIN32 ASSERT_THAT(s, testing::ContainsRegex("void TFormula____id[0-9]*_hessian_1")); #endif // R__WIN32 -} \ No newline at end of file +}