[Libreoffice-commits] core.git: Branch 'distro/collabora/cp-6.0' - sw/source
Libreoffice Gerrit user
logerrit at kemper.freedesktop.org
Mon Aug 20 07:46:21 UTC 2018
sw/source/core/doc/doc.cxx | 49 +++++++++++++++++++++++++++++----------------
1 file changed, 32 insertions(+), 17 deletions(-)
New commits:
commit 53dfffb5ca85afa3c74b8e7a8f05cb4f2840c477
Author: Mike Kaganski <mike.kaganski at collabora.com>
AuthorDate: Thu Aug 16 13:56:07 2018 +0300
Commit: Andras Timar <andras.timar at collabora.com>
CommitDate: Mon Aug 20 09:46:01 2018 +0200
tdf#119294: reimplement fix for tdf#118859
When removing paragraphs with mail mere fields, both field type reference
and node reference could get invalid, because field type will be destroyed
when its last field is gone; and node will be destroyed if it is in a fly
with anchor in another node which gets destroyed.
To avoid use-after-delete, we will use an SwClient on field types, thus
detecting if a collected field type got destroyed; iterating over fields
using SwIterator is safe, because removing a node with fields would update
the iterator.
Change-Id: Id8b555ef7015b13ab70ebb41845d34c477ac6b31
Reviewed-on: https://gerrit.libreoffice.org/59164
Tested-by: Jenkins
Reviewed-by: Mike Kaganski <mike.kaganski at collabora.com>
(cherry picked from commit c883d5e073d2ac5b2d55126c929d7bf3e6d295e8)
Reviewed-on: https://gerrit.libreoffice.org/59178
Reviewed-by: Andras Timar <andras.timar at collabora.com>
Tested-by: Andras Timar <andras.timar at collabora.com>
diff --git a/sw/source/core/doc/doc.cxx b/sw/source/core/doc/doc.cxx
index 8d29d7872467..a594fe3d1a2c 100644
--- a/sw/source/core/doc/doc.cxx
+++ b/sw/source/core/doc/doc.cxx
@@ -45,6 +45,7 @@
#include <comphelper/string.hxx>
#include <comphelper/random.hxx>
+#include <o3tl/make_unique.hxx>
#include <tools/urlobj.hxx>
#include <tools/poly.hxx>
#include <tools/multisel.hxx>
@@ -124,7 +125,6 @@
#include <vector>
#include <map>
-#include <set>
#include <osl/diagnose.h>
#include <osl/interlck.h>
#include <vbahelper/vbaaccesshelper.hxx>
@@ -1341,8 +1341,9 @@ void RemoveOrDeleteContents(SwTextNode* pTextNd, IDocumentContentOperations& xOp
xOperations.DelFullPara(aPam);
}
}
-// Returns the node pointer which needs to hide, or nullptr if this field does not hide a node
-SwTextNode* HandleHidingField(SwFormatField& rFormatField, const SwNodes& rNodes)
+// Returns if the data was actually modified
+bool HandleHidingField(SwFormatField& rFormatField, const SwNodes& rNodes,
+ IDocumentContentOperations& xOperations)
{
SwTextNode* pTextNd;
if (rFormatField.GetTextField()
@@ -1350,9 +1351,10 @@ SwTextNode* HandleHidingField(SwFormatField& rFormatField, const SwNodes& rNodes
&& pTextNd->GetpSwpHints() && pTextNd->IsHiddenByParaField()
&& &pTextNd->GetNodes() == &rNodes)
{
- return pTextNd;
+ RemoveOrDeleteContents(pTextNd, xOperations);
+ return true;
}
- return nullptr;
+ return false;
}
}
@@ -1391,25 +1393,38 @@ bool SwDoc::RemoveInvisibleContent()
GetIDocumentUndoRedo().StartUndo( SwUndoId::UI_DELETE_INVISIBLECNTNT, nullptr );
{
+ class FieldTypeGuard : public SwClient
+ {
+ public:
+ explicit FieldTypeGuard(SwFieldType* pType)
+ : SwClient(pType)
+ {
+ }
+ const SwFieldType* get() const
+ {
+ return static_cast<const SwFieldType*>(GetRegisteredIn());
+ }
+ };
// Removing some nodes for one SwFieldIds::Database type might remove the type from
- // document's field types, or try to remove already removed nodes, invalidating iterators.
- // So, we need to create own list of nodes prior to removing them.
- std::set<SwTextNode*> aHiddenNodes;
- for (const auto* pType : *getIDocumentFieldsAccess().GetFieldTypes())
+ // document's field types, invalidating iterators. So, we need to create own list of
+ // matching types prior to processing them.
+ std::vector<std::unique_ptr<FieldTypeGuard>> aHidingFieldTypes;
+ for (SwFieldType* pType : *getIDocumentFieldsAccess().GetFieldTypes())
{
if (FieldCanHidePara(pType->Which()))
+ aHidingFieldTypes.push_back(o3tl::make_unique<FieldTypeGuard>(pType));
+ }
+ for (const auto& pTypeGuard : aHidingFieldTypes)
+ {
+ if (const SwFieldType* pType = pTypeGuard->get())
{
SwIterator<SwFormatField, SwFieldType> aIter(*pType);
- for (auto* pField = aIter.First(); pField; pField = aIter.Next())
- if (SwTextNode* pHiddenNode = HandleHidingField(*pField, GetNodes()))
- aHiddenNodes.insert(pHiddenNode);
+ for (SwFormatField* pFormatField = aIter.First(); pFormatField;
+ pFormatField = aIter.Next())
+ bRet |= HandleHidingField(*pFormatField, GetNodes(),
+ getIDocumentContentOperations());
}
}
- for (SwTextNode* pHiddenNode : aHiddenNodes)
- {
- bRet = true;
- RemoveOrDeleteContents(pHiddenNode, getIDocumentContentOperations());
- }
}
// Remove any hidden paragraph (hidden text attribute)
More information about the Libreoffice-commits
mailing list