include/svl/numformat.hxx                  |    2 +-
 sc/inc/interpretercontext.hxx              |    1 +
 sc/source/core/tool/interpretercontext.cxx |   29 ++++++++++++++---------------
 svl/source/numbers/zforlist.cxx            |   19 ++++++++++++++-----
 4 files changed, 30 insertions(+), 21 deletions(-)

New commits:
commit db040630d664fa20bc4f8995d2168fcce51a8bfd
Author:     Caolán McNamara <[email protected]>
AuthorDate: Mon Apr 1 21:17:26 2024 +0100
Commit:     Caolán McNamara <[email protected]>
CommitDate: Tue Apr 2 20:45:14 2024 +0200

    crashtesting: SvNFEngine::DefaultCurrencyRO assert
    
    seen with forum-mso-en4-207468.xls
    
    so we will have to ensure that nDefaultSystemCurrencyFormat
    is set before using the RO mode
    
    Change-Id: Ib1e755203917ddd751a1493c817cc8383bbbc043
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/165658
    Tested-by: Jenkins
    Reviewed-by: Caolán McNamara <[email protected]>

diff --git a/include/svl/numformat.hxx b/include/svl/numformat.hxx
index 92f93bb1562a..484a2a1bfdb7 100644
--- a/include/svl/numformat.hxx
+++ b/include/svl/numformat.hxx
@@ -552,7 +552,6 @@ private:
     OnDemandNativeNumberWrapper xNatNum; // Native number service loaded on 
demand
     Link<sal_uInt16, Color*> aColorLink; // User defined color table CallBack
 
-    SVL_DLLPRIVATE static volatile bool bCurrencyTableInitialized;
     SVL_DLLPRIVATE static sal_uInt16 nSystemCurrencyPosition;
     SVL_DLLPRIVATE static SvNumberFormatterRegistry_Impl* pFormatterRegistry;
 
@@ -651,6 +650,7 @@ public:
     // return the corresponding date separator
     const OUString& GetDateSep() const { return 
m_aCurrentLanguage.GetDateSep(); }
 
+    void PrepForRoMode();
     const SvNFFormatData& GetROFormatData() const { return m_aFormatData; }
     const SvNFLanguageData& GetROLanguageData() const { return 
m_aCurrentLanguage; }
 };
diff --git a/sc/inc/interpretercontext.hxx b/sc/inc/interpretercontext.hxx
index ead9b04c06c7..63d23bfe227a 100644
--- a/sc/inc/interpretercontext.hxx
+++ b/sc/inc/interpretercontext.hxx
@@ -121,6 +121,7 @@ private:
     void Cleanup();
     void ClearLookupCache(const ScDocument* pDoc);
     void initFormatTable();
+    void prepFormatterForRoMode(SvNumberFormatter* pFormatter);
 
     // During threaded calculation, where we don't need to add to the number
     // format data, we can access the numbering data with a RO unlocked view of
diff --git a/sc/source/core/tool/interpretercontext.cxx 
b/sc/source/core/tool/interpretercontext.cxx
index e1fc5fb24252..557a9c766db1 100644
--- a/sc/source/core/tool/interpretercontext.cxx
+++ b/sc/source/core/tool/interpretercontext.cxx
@@ -44,12 +44,7 @@ ScInterpreterContext::ScInterpreterContext(const ScDocument& 
rDoc, SvNumberForma
     if (!pFormatter)
         mpFormatData = nullptr;
     else
-    {
-        mxLanguageData.reset(new 
SvNFLanguageData(pFormatter->GetROLanguageData()));
-        mxAuxFormatKeyMap.reset(new SvNFFormatData::DefaultFormatKeysMap);
-        mpFormatData = &pFormatter->GetROFormatData();
-        maROPolicy = SvNFEngine::GetROPolicy(*mpFormatData, 
*mxAuxFormatKeyMap);
-    }
+        prepFormatterForRoMode(pFormatter);
 }
 
 ScInterpreterContext::~ScInterpreterContext() { ResetTokens(); }
@@ -73,28 +68,32 @@ void ScInterpreterContext::SetDocAndFormatter(const 
ScDocument& rDoc, SvNumberFo
     }
     if (mpFormatter != pFormatter)
     {
-        // formatter has changed
-        mxLanguageData.reset(new 
SvNFLanguageData(pFormatter->GetROLanguageData()));
-        mxAuxFormatKeyMap.reset(new SvNFFormatData::DefaultFormatKeysMap);
-        mpFormatData = &pFormatter->GetROFormatData();
-        maROPolicy = SvNFEngine::GetROPolicy(*mpFormatData, 
*mxAuxFormatKeyMap);
         mpFormatter = pFormatter;
 
+        // formatter has changed
+        prepFormatterForRoMode(pFormatter);
+
         // drop cache
         std::fill(maNFBuiltInCache.begin(), maNFBuiltInCache.end(), 
NFBuiltIn());
         std::fill(maNFTypeCache.begin(), maNFTypeCache.end(), NFType());
     }
 }
 
-void ScInterpreterContext::initFormatTable()
+void ScInterpreterContext::prepFormatterForRoMode(SvNumberFormatter* 
pFormatter)
 {
-    mpFormatter = mpDoc->GetFormatTable(); // will assert if not main thread
-    mpFormatData = &mpFormatter->GetROFormatData();
-    mxLanguageData.reset(new 
SvNFLanguageData(mpFormatter->GetROLanguageData()));
+    pFormatter->PrepForRoMode();
+    mpFormatData = &pFormatter->GetROFormatData();
+    mxLanguageData.reset(new 
SvNFLanguageData(pFormatter->GetROLanguageData()));
     mxAuxFormatKeyMap.reset(new SvNFFormatData::DefaultFormatKeysMap);
     maROPolicy = SvNFEngine::GetROPolicy(*mpFormatData, *mxAuxFormatKeyMap);
 }
 
+void ScInterpreterContext::initFormatTable()
+{
+    mpFormatter = mpDoc->GetFormatTable(); // will assert if not main thread
+    prepFormatterForRoMode(mpFormatter);
+}
+
 void ScInterpreterContext::MergeDefaultFormatKeys(SvNumberFormatter& 
rFormatter) const
 {
     rFormatter.MergeDefaultFormatKeys(*mxAuxFormatKeyMap);
diff --git a/svl/source/numbers/zforlist.cxx b/svl/source/numbers/zforlist.cxx
index 02e48b8468cc..a7a36cd6fdb2 100644
--- a/svl/source/numbers/zforlist.cxx
+++ b/svl/source/numbers/zforlist.cxx
@@ -242,8 +242,9 @@ void SvNumberFormatterRegistry_Impl::ConfigurationChanged( 
utl::ConfigurationBro
     }
 }
 
+static volatile bool bCurrencyTableInitialized = false;
+
 SvNumberFormatterRegistry_Impl* SvNumberFormatter::pFormatterRegistry = 
nullptr;
-volatile bool SvNumberFormatter::bCurrencyTableInitialized = false;
 namespace
 {
     NfCurrencyTable& theCurrencyTable()
@@ -3986,9 +3987,20 @@ SvNFEngine::Accessor 
SvNFEngine::GetRWPolicy(SvNFFormatData& rFormatData)
     };
 }
 
-SvNFEngine::Accessor SvNFEngine::GetROPolicy(const SvNFFormatData& 
rFormatData, SvNFFormatData::DefaultFormatKeysMap& rFormatCache)
+void SvNumberFormatter::PrepForRoMode()
 {
     SvNumberFormatter::GetTheCurrencyTable(); // create this now so threads 
don't attempt to create it simultaneously
+    if (m_aFormatData.nDefaultSystemCurrencyFormat == 
NUMBERFORMAT_ENTRY_NOT_FOUND)
+    {
+        m_aFormatData.ImpGetDefaultSystemCurrencyFormat(m_aCurrentLanguage, 
GetNatNum());
+        assert(m_aFormatData.nDefaultSystemCurrencyFormat != 
NUMBERFORMAT_ENTRY_NOT_FOUND);
+    }
+}
+
+SvNFEngine::Accessor SvNFEngine::GetROPolicy(const SvNFFormatData& 
rFormatData, SvNFFormatData::DefaultFormatKeysMap& rFormatCache)
+{
+    assert(rFormatData.nDefaultSystemCurrencyFormat != 
NUMBERFORMAT_ENTRY_NOT_FOUND && "ensure PrepForRoMode is called");
+    assert(bCurrencyTableInitialized && "ensure PrepForRoMode is called");
     return
     {
         std::bind(SvNFEngine::GetCLOffsetRO, std::ref(rFormatData), 
std::placeholders::_1, std::placeholders::_2, std::placeholders::_3),
@@ -4129,7 +4141,6 @@ const NfCurrencyTable& 
SvNumberFormatter::GetTheCurrencyTable()
     return theCurrencyTable();
 }
 
-
 // static
 const NfCurrencyEntry* SvNumberFormatter::MatchSystemCurrency()
 {
@@ -4138,7 +4149,6 @@ const NfCurrencyEntry* 
SvNumberFormatter::MatchSystemCurrency()
     return nSystemCurrencyPosition ? &rTable[nSystemCurrencyPosition] : 
nullptr;
 }
 
-
 // static
 const NfCurrencyEntry& SvNumberFormatter::GetCurrencyEntry( LanguageType eLang 
)
 {
@@ -4801,7 +4811,6 @@ void SvNumberFormatter::ImpInitCurrencyTable()
     bCurrencyTableInitialized = true;
 }
 
-
 static std::ptrdiff_t addToCurrencyFormatsList( NfWSStringsDtor& rStrArr, 
const OUString& rFormat )
 {
     // Prevent duplicates even over subsequent calls of

Reply via email to