editeng/source/misc/svxacorr.cxx          |    4 +++
 sw/qa/extras/uiwriter/data/tdf83260-1.odt |binary
 sw/qa/extras/uiwriter/uiwriter.cxx        |   35 ++++++++++++++++++++++++++++++
 sw/source/filter/xml/swxml.cxx            |    5 ++++
 4 files changed, 44 insertions(+)

New commits:
commit e7c67eb093d1e099225eaccdaaf29eff1a4c9325
Author: Michael Stahl <mst...@redhat.com>
Date:   Wed Feb 14 12:57:49 2018 +0100

    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 <c...@libreoffice.org>
    Reviewed-by: Michael Stahl <mst...@redhat.com>
    (cherry picked from commit 1c8efde4daea648204e3ba19f8edc01ef3e548bd)
    Reviewed-on: https://gerrit.libreoffice.org/49805
    Reviewed-by: Miklos Vajna <vmik...@collabora.co.uk>

diff --git a/editeng/source/misc/svxacorr.cxx b/editeng/source/misc/svxacorr.cxx
index 658e6c619f33..9c8eeb9d2dac 100644
--- a/editeng/source/misc/svxacorr.cxx
+++ b/editeng/source/misc/svxacorr.cxx
@@ -1233,6 +1233,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 )
@@ -1343,6 +1344,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
Binary files /dev/null and b/sw/qa/extras/uiwriter/data/tdf83260-1.odt differ
diff --git a/sw/qa/extras/uiwriter/uiwriter.cxx 
b/sw/qa/extras/uiwriter/uiwriter.cxx
index ffd2d4bba18d..3c6e0a04afd7 100644
--- a/sw/qa/extras/uiwriter/uiwriter.cxx
+++ b/sw/qa/extras/uiwriter/uiwriter.cxx
@@ -155,6 +155,7 @@ public:
     void testChineseConversionSimplifiedToTraditional();
     void testFdo85554();
     void testAutoCorr();
+    void testTdf83260();
     void testMergeDoc();
     void testCreatePortions();
     void testBookmarkUndo();
@@ -328,6 +329,7 @@ public:
     CPPUNIT_TEST(testChineseConversionSimplifiedToTraditional);
     CPPUNIT_TEST(testFdo85554);
     CPPUNIT_TEST(testAutoCorr);
+    CPPUNIT_TEST(testTdf83260);
     CPPUNIT_TEST(testMergeDoc);
     CPPUNIT_TEST(testCreatePortions);
     CPPUNIT_TEST(testBookmarkUndo);
@@ -1407,6 +1409,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 652e84ef5ab8..dfedaa377a36 100644
--- a/sw/source/filter/xml/swxml.cxx
+++ b/sw/source/filter/xml/swxml.cxx
@@ -884,6 +884,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
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to