sw/source/core/doc/docfmt.cxx | 38 ++++++++++++++++++++++++-------------- 1 file changed, 24 insertions(+), 14 deletions(-)
New commits: commit f6dc87fc730bc48a7c809d2ff460cc36024630b9 Author: Michael Stahl <michael.st...@allotropia.de> AuthorDate: Thu Sep 12 15:47:00 2024 +0200 Commit: Michael Stahl <michael.st...@allotropia.de> CommitDate: Fri Sep 13 10:35:02 2024 +0200 tdf#162911 sw: fix crash after autocorrect inserts hyperlinks The problem is that SwDoc::SetFormatItemByAutoFormat() inserts a static pool default item of SwFormatINetFormat as SwTextINetFormat into the document. SfxPoolItemHolder::SfxPoolItemHolder() does not clone a static pool default item, hence it will be deleted multiple times. The code that was added in SwDoc::SetFormatItemByAutoFormat() to fix tdf#62536 is for the RES_CHRATR_* items, it is not needed for any of the other items that autocorrect/autoformat may insert (RES_TXTATR_INETFMT or RES_PARATR_TABSTOP). (regression from commit fe444d1f74abe417962be0bcd3340f40f2446b58 and/or commit ca3c6d468f68af1506bf4e56b47655e5d56306a8) Change-Id: I8b0414995f9fd8f94d1903a8e66f0c25c7038ebd Reviewed-on: https://gerrit.libreoffice.org/c/core/+/173267 Tested-by: Jenkins Reviewed-by: Michael Stahl <michael.st...@allotropia.de> diff --git a/sw/source/core/doc/docfmt.cxx b/sw/source/core/doc/docfmt.cxx index 9f2331e89026..75ccf557810e 100644 --- a/sw/source/core/doc/docfmt.cxx +++ b/sw/source/core/doc/docfmt.cxx @@ -1884,27 +1884,37 @@ void SwDoc::SetFormatItemByAutoFormat( const SwPaM& rPam, const SfxItemSet& rSet SfxItemIter iter(rSet); for (SfxPoolItem const* pItem = iter.GetCurItem(); pItem; pItem = iter.NextItem()) { - whichIds.push_back({pItem->Which(), pItem->Which()}); + if (RES_CHRATR_BEGIN <= pItem->Which() && pItem->Which() < RES_CHRATR_END) + { // tdf#162911 don't add items with static default like INETFMT + whichIds.push_back({pItem->Which(), pItem->Which()}); + } } - // ITEM: Need to sort these due to ItemSet using unordered_set and - // WhichRangesContainer expect these sorted ascending - std::sort(whichIds.begin(), whichIds.end(), [](WhichPair& a, WhichPair& b) {return a.first < b.first;}); + ::std::optional<SfxItemSet> oCurrentSet; + if (!whichIds.empty()) + { + // ITEM: Need to sort these due to ItemSet using unordered_set and + // WhichRangesContainer expect these sorted ascending + std::sort(whichIds.begin(), whichIds.end(), [](WhichPair& a, WhichPair& b) {return a.first < b.first;}); - SfxItemSet currentSet(GetAttrPool(), WhichRangesContainer(whichIds.data(), whichIds.size())); - pTNd->GetParaAttr(currentSet, nEnd, nEnd); - for (const WhichPair& rPair : whichIds) - { // yuk - want to explicitly set the pool defaults too :-/ - currentSet.Put(currentSet.Get(rPair.first)); + oCurrentSet.emplace(GetAttrPool(), WhichRangesContainer(whichIds.data(), whichIds.size())); + pTNd->GetParaAttr(*oCurrentSet, nEnd, nEnd); + for (const WhichPair& rPair : whichIds) + { // yuk - want to explicitly set the pool defaults too :-/ + oCurrentSet->Put(oCurrentSet->Get(rPair.first)); + } } getIDocumentContentOperations().InsertItemSet( rPam, rSet, SetAttrMode::DONTEXPAND ); - // fdo#62536: DONTEXPAND does not work when there is already an AUTOFMT - // here, so insert the old attributes as an empty hint to stop expand - SwPaM endPam(*pTNd, nEnd); - endPam.SetMark(); - getIDocumentContentOperations().InsertItemSet(endPam, currentSet); + if (!whichIds.empty()) + { + // fdo#62536: DONTEXPAND does not work when there is already an AUTOFMT + // here, so insert the old attributes as an empty hint to stop expand + SwPaM endPam(*pTNd, nEnd); + endPam.SetMark(); + getIDocumentContentOperations().InsertItemSet(endPam, *oCurrentSet); + } getIDocumentRedlineAccess().SetRedlineFlags_intern( eOld ); }