sw/inc/dbfld.hxx                             |    1 +
 sw/inc/ddefld.hxx                            |    1 +
 sw/inc/expfld.hxx                            |    1 +
 sw/inc/fldbas.hxx                            |    1 +
 sw/inc/usrfld.hxx                            |    1 +
 sw/source/core/doc/DocumentFieldsManager.cxx |    2 +-
 sw/source/core/fields/dbfld.cxx              |    2 ++
 sw/source/core/fields/ddefld.cxx             |    2 ++
 sw/source/core/fields/expfld.cxx             |    2 ++
 sw/source/core/fields/fldbas.cxx             |    2 ++
 sw/source/core/fields/usrfld.cxx             |    2 ++
 11 files changed, 16 insertions(+), 1 deletion(-)

New commits:
commit 56f60453e788984627085ce65924a45e97a42ec2
Author:     Mike Kaganski <[email protected]>
AuthorDate: Fri Oct 24 11:33:55 2025 +0500
Commit:     Mike Kaganski <[email protected]>
CommitDate: Fri Oct 24 10:58:17 2025 +0200

    Fix renaming field type in InsDeletedFieldType
    
    The function has this comment:
    
      // - If the same type is found, the deleted one has to be renamed.
    
    And obviously, the loop in it intends to do that. It searches the name;
    when it finds one, it uses a counter to add a suffix to find an unused
    name; and finally, it assigns the found unused new name.
    
    The problem was, that it assigned it to a local variable, not to the
    field type.
    
    This happened in commit 263153842741d7ce21cc0bf1c5296a55a1138024
    (String to OUString, 2013-07-16). Before that, SwFieldType::GetName
    returned a const reference to a string; and that string was the field
    actually representing name in the relevant field types. The function
    InsDeletedFieldType took the name by const reference, and const_casted
    it when renaming. The mentioned commit changed SwFieldType::GetName to
    return by value, meaning that InsDeletedFieldType operated on a local
    variable since then.
    
    Later commits changed the local variable in InsDeletedFieldType to be
    non-reference, and later the name in SwFieldType became a UIName.
    
    This change introduces a normal setter for the field type name, to
    avoid the hackish rename method, that led to this problem in the first
    place.
    
    This is a problem found by code reading. I don't know a user-visible
    problem caused by this, so no unit test.
    
    Change-Id: Ibe6fb1e0a11c5193cc253efe7241592d7ce9ca77
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/192931
    Tested-by: Jenkins
    Reviewed-by: Mike Kaganski <[email protected]>

diff --git a/sw/inc/dbfld.hxx b/sw/inc/dbfld.hxx
index 132a5de5241c..9eab816b64ff 100644
--- a/sw/inc/dbfld.hxx
+++ b/sw/inc/dbfld.hxx
@@ -38,6 +38,7 @@ public:
     virtual ~SwDBFieldType() override;
 
     virtual UIName GetName() const override;
+    virtual void SetName(const UIName& newName) override;
     virtual std::unique_ptr<SwFieldType> Copy() const override;
 
     void     AddRef() { m_nRefCnt++; }
diff --git a/sw/inc/ddefld.hxx b/sw/inc/ddefld.hxx
index 278542e744db..18c8985a207f 100644
--- a/sw/inc/ddefld.hxx
+++ b/sw/inc/ddefld.hxx
@@ -72,6 +72,7 @@ public:
 
     virtual std::unique_ptr<SwFieldType> Copy() const override;
     virtual UIName GetName() const override;
+    virtual void SetName(const UIName& newName) override;
 
     virtual void QueryValue( css::uno::Any& rVal, sal_uInt16 nWhich ) const 
override;
     virtual void PutValue( const css::uno::Any& rVal, sal_uInt16 nWhich ) 
override;
diff --git a/sw/inc/expfld.hxx b/sw/inc/expfld.hxx
index cdc738d775c9..de48331d0702 100644
--- a/sw/inc/expfld.hxx
+++ b/sw/inc/expfld.hxx
@@ -160,6 +160,7 @@ public:
                         SwGetSetExpType nType = SwGetSetExpType::Expr );
     virtual std::unique_ptr<SwFieldType> Copy() const override;
     virtual UIName          GetName() const override;
+    virtual void SetName(const UIName& newName) override;
 
     inline void             SetType(SwGetSetExpType nTyp);
     inline SwGetSetExpType  GetType() const;
diff --git a/sw/inc/fldbas.hxx b/sw/inc/fldbas.hxx
index f91ccf30f99f..0f60a85a0e00 100644
--- a/sw/inc/fldbas.hxx
+++ b/sw/inc/fldbas.hxx
@@ -257,6 +257,7 @@ public:
 
     /// Only in derived classes.
     virtual UIName        GetName() const;
+    virtual void SetName(const UIName& newName);
     virtual std::unique_ptr<SwFieldType> Copy() const = 0;
     virtual void QueryValue( css::uno::Any& rVal, sal_uInt16 nWhich ) const;
     virtual void PutValue( const css::uno::Any& rVal, sal_uInt16 nWhich );
diff --git a/sw/inc/usrfld.hxx b/sw/inc/usrfld.hxx
index 718fd449b335..8b71f15cf355 100644
--- a/sw/inc/usrfld.hxx
+++ b/sw/inc/usrfld.hxx
@@ -47,6 +47,7 @@ public:
     SwUserFieldType( SwDoc* pDocPtr, const UIName& );
 
     virtual UIName          GetName() const override;
+    virtual void SetName(const UIName& newName) override;
     virtual std::unique_ptr<SwFieldType> Copy() const override;
 
     OUString                Expand(sal_uInt32 nFormat, SwUserType nSubType, 
LanguageType nLng);
diff --git a/sw/source/core/doc/DocumentFieldsManager.cxx 
b/sw/source/core/doc/DocumentFieldsManager.cxx
index 4367a90458eb..621aa7d3cb69 100644
--- a/sw/source/core/doc/DocumentFieldsManager.cxx
+++ b/sw/source/core/doc/DocumentFieldsManager.cxx
@@ -453,7 +453,7 @@ void DocumentFieldsManager::InsDeletedFieldType( 
SwFieldType& rFieldTyp )
                 }
                 if( i >= nSize )        // not found
                 {
-                    const_cast<OUString&>(aFieldNm) = sSrch;
+                    rFieldTyp.SetName(UIName(sSrch));
                     break;      // exit while loop
                 }
                 ++nNum;
diff --git a/sw/source/core/fields/dbfld.cxx b/sw/source/core/fields/dbfld.cxx
index 119f34273e57..344ab81673f7 100644
--- a/sw/source/core/fields/dbfld.cxx
+++ b/sw/source/core/fields/dbfld.cxx
@@ -77,6 +77,8 @@ UIName SwDBFieldType::GetName() const
     return m_sName;
 }
 
+void SwDBFieldType::SetName(const UIName& newName) { m_sName = newName; }
+
 void SwDBFieldType::ReleaseRef()
 {
     OSL_ENSURE(m_nRefCnt > 0, "RefCount < 0!");
diff --git a/sw/source/core/fields/ddefld.cxx b/sw/source/core/fields/ddefld.cxx
index 3fc078afac4e..22219baebb63 100644
--- a/sw/source/core/fields/ddefld.cxx
+++ b/sw/source/core/fields/ddefld.cxx
@@ -180,6 +180,8 @@ UIName SwDDEFieldType::GetName() const
     return m_aName;
 }
 
+void SwDDEFieldType::SetName(const UIName& newName) { m_aName = newName; }
+
 void SwDDEFieldType::SetCmd( const OUString& _aStr )
 {
     OUString aStr = _aStr;
diff --git a/sw/source/core/fields/expfld.cxx b/sw/source/core/fields/expfld.cxx
index 456bf436c46f..ab1321c14369 100644
--- a/sw/source/core/fields/expfld.cxx
+++ b/sw/source/core/fields/expfld.cxx
@@ -529,6 +529,8 @@ UIName SwSetExpFieldType::GetName() const
     return m_sName;
 }
 
+void SwSetExpFieldType::SetName(const UIName& newName) { m_sName = newName; }
+
 const OUString& SwSetExpField::GetExpStr(SwRootFrame const*const pLayout) const
 {
     return (pLayout && pLayout->IsHideRedlines()) ? msExpandRLHidden : 
msExpand;
diff --git a/sw/source/core/fields/fldbas.cxx b/sw/source/core/fields/fldbas.cxx
index 60292ce717f6..c8e18513e046 100644
--- a/sw/source/core/fields/fldbas.cxx
+++ b/sw/source/core/fields/fldbas.cxx
@@ -143,6 +143,8 @@ UIName SwFieldType::GetName() const
     return UIName();
 }
 
+void SwFieldType::SetName(const UIName& /*newName*/) { assert(!"Wrong field 
type"); }
+
 void SwFieldType::QueryValue( uno::Any&, sal_uInt16 ) const
 {
 }
diff --git a/sw/source/core/fields/usrfld.cxx b/sw/source/core/fields/usrfld.cxx
index fbba5f0f8169..b1624b4a8c18 100644
--- a/sw/source/core/fields/usrfld.cxx
+++ b/sw/source/core/fields/usrfld.cxx
@@ -215,6 +215,8 @@ UIName SwUserFieldType::GetName() const
     return m_aName;
 }
 
+void SwUserFieldType::SetName(const UIName& newName) { m_aName = newName; }
+
 void SwUserFieldType::SwClientNotify(const SwModify&, const SfxHint& rHint)
 {
     if (rHint.GetId() == SfxHintId::SwLegacyModify)

Reply via email to