summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Stahl <mstahl@redhat.com>2018-02-14 12:57:49 +0100
committerMichael Stahl <mstahl@redhat.com>2018-02-15 09:56:55 +0100
commit1c8efde4daea648204e3ba19f8edc01ef3e548bd (patch)
treed46e889b698005a142a08bfe873162fd6e877cce
parentaac475436271ddeabf6d9a4c3984ba77accf56ce (diff)
tdf#83260 sw: call CompressRedlines() in ODF import
It's possible that an ODF document contains redlines that will be deduplicated by CompressRedlines(). If that happens during some editing operation, then a SwRedline will be deleted and the nodes array becomes smaller by at least 3 nodes; any Undo actions that were created prior to the operation that called CompressRedlines() will store invalid node indexes now and Undo will crash. So presumably it's a precondition of editing operations that CompressRedlines() is a no-op. Interestingly CompressRedlines() is also called from SwEditShell::Undo()/Redo(). Ensure it's a no-op later by calling CompressRedlines() immediately after load. (Hopefully this should also work for the Insert File case.) Add a test too. Change-Id: Iec8135cc60260ed5cfff05a196b5c92cc03265f9 Reviewed-on: https://gerrit.libreoffice.org/49721 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Michael Stahl <mstahl@redhat.com>
-rw-r--r--editeng/source/misc/svxacorr.cxx4
-rw-r--r--sw/qa/extras/uiwriter/data/tdf83260-1.odtbin0 -> 9422 bytes
-rw-r--r--sw/qa/extras/uiwriter/uiwriter.cxx35
-rw-r--r--sw/source/filter/xml/swxml.cxx5
4 files changed, 44 insertions, 0 deletions
diff --git a/editeng/source/misc/svxacorr.cxx b/editeng/source/misc/svxacorr.cxx
index 1119879f178c..302c941b06b7 100644
--- a/editeng/source/misc/svxacorr.cxx
+++ b/editeng/source/misc/svxacorr.cxx
@@ -1228,6 +1228,7 @@ OUString SvxAutoCorrect::GetQuote( SvxAutoCorrDoc const & rDoc, sal_Int32 nInsPo
return sRet;
}
+// WARNING: rText may become invalid, see comment below
void SvxAutoCorrect::DoAutoCorrect( SvxAutoCorrDoc& rDoc, const OUString& rTxt,
sal_Int32 nInsPos, sal_Unicode cChar,
bool bInsert, bool& io_bNbspRunNext, vcl::Window const * pFrameWin )
@@ -1338,6 +1339,9 @@ void SvxAutoCorrect::DoAutoCorrect( SvxAutoCorrDoc& rDoc, const OUString& rTxt,
if( IsAutoCorrFlag( Autocorrect ) )
{
+ // WARNING ATTENTION: rTxt is an alias of the text node's OUString
+ // and becomes INVALID if ChgAutoCorrWord returns true!
+ // => use aPara/pPara to create a valid copy of the string!
OUString aPara;
OUString* pPara = IsAutoCorrFlag(CapitalStartSentence) ? &aPara : nullptr;
diff --git a/sw/qa/extras/uiwriter/data/tdf83260-1.odt b/sw/qa/extras/uiwriter/data/tdf83260-1.odt
new file mode 100644
index 000000000000..b6e144b57751
--- /dev/null
+++ b/sw/qa/extras/uiwriter/data/tdf83260-1.odt
Binary files differ
diff --git a/sw/qa/extras/uiwriter/uiwriter.cxx b/sw/qa/extras/uiwriter/uiwriter.cxx
index 8dee21388fbe..0a16a201ad1a 100644
--- a/sw/qa/extras/uiwriter/uiwriter.cxx
+++ b/sw/qa/extras/uiwriter/uiwriter.cxx
@@ -156,6 +156,7 @@ public:
void testChineseConversionSimplifiedToTraditional();
void testFdo85554();
void testAutoCorr();
+ void testTdf83260();
void testMergeDoc();
void testCreatePortions();
void testBookmarkUndo();
@@ -337,6 +338,7 @@ public:
CPPUNIT_TEST(testChineseConversionSimplifiedToTraditional);
CPPUNIT_TEST(testFdo85554);
CPPUNIT_TEST(testAutoCorr);
+ CPPUNIT_TEST(testTdf83260);
CPPUNIT_TEST(testMergeDoc);
CPPUNIT_TEST(testCreatePortions);
CPPUNIT_TEST(testBookmarkUndo);
@@ -1424,6 +1426,39 @@ void SwUiWriterTest::testAutoCorr()
CPPUNIT_ASSERT_EQUAL(sal_Int32(3), xTable->getColumns()->getCount());
}
+void SwUiWriterTest::testTdf83260()
+{
+ SwDoc* const pDoc(createDoc("tdf83260-1.odt"));
+ SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
+ SwAutoCorrect corr(*SvxAutoCorrCfg::Get().GetAutoCorrect());
+
+ // enabled but not shown
+ CPPUNIT_ASSERT(IDocumentRedlineAccess::IsHideChanges(
+ pDoc->getIDocumentRedlineAccess().GetRedlineFlags()));
+ CPPUNIT_ASSERT(IDocumentRedlineAccess::IsRedlineOn(
+ pDoc->getIDocumentRedlineAccess().GetRedlineFlags()));
+ CPPUNIT_ASSERT(!pDoc->getIDocumentRedlineAccess().GetRedlineTable().empty());
+
+ // the document contains redlines that are combined with CompressRedlines()
+ // if that happens during AutoCorrect then indexes in Undo are off -> crash
+ pWrtShell->Insert("tset");
+ pWrtShell->AutoCorrect(corr, u' ');
+ sw::UndoManager& rUndoManager = pDoc->GetUndoManager();
+ auto const nActions(rUndoManager.GetUndoActionCount());
+ for (auto i = nActions; 0 < i; --i)
+ {
+ rUndoManager.Undo();
+ }
+ for (auto i = nActions; 0 < i; --i)
+ {
+ rUndoManager.Redo();
+ }
+ for (auto i = nActions; 0 < i; --i)
+ {
+ rUndoManager.Undo();
+ }
+}
+
void SwUiWriterTest::testMergeDoc()
{
SwDoc* const pDoc1(createDoc("merge-change1.odt"));
diff --git a/sw/source/filter/xml/swxml.cxx b/sw/source/filter/xml/swxml.cxx
index 700bad46ba96..a96433fa042e 100644
--- a/sw/source/filter/xml/swxml.cxx
+++ b/sw/source/filter/xml/swxml.cxx
@@ -885,6 +885,11 @@ ErrCode XMLReader::Read( SwDoc &rDoc, const OUString& rBaseURL, SwPaM &rPaM, con
// (First set bogus mode to make sure the mode in getIDocumentRedlineAccess().SetRedlineFlags()
// is different from its previous mode.)
rDoc.getIDocumentRedlineAccess().SetRedlineFlags_intern( ~nRedlineFlags );
+ // must set flags to show delete so that CompressRedlines works
+ rDoc.getIDocumentRedlineAccess().SetRedlineFlags(nRedlineFlags|RedlineFlags::ShowDelete);
+ // tdf#83260 ensure that the first call of CompressRedlines after loading
+ // the document is a no-op by calling it now
+ rDoc.getIDocumentRedlineAccess().CompressRedlines();
rDoc.getIDocumentRedlineAccess().SetRedlineFlags( nRedlineFlags );
lcl_EnsureValidPam( rPaM ); // move Pam into valid content