[libreoffice/f17] writer table crash & print fixes

Michael Stahl mstahl at fedoraproject.org
Fri Sep 28 17:16:23 UTC 2012


commit aa67036f8b4cf2ee441629f496464667edb5476c
Author: Michael Stahl <mstahl at redhat.com>
Date:   Fri Sep 28 19:15:19 2012 +0200

    writer table crash & print fixes
    
    - Resolves: rhbz#852128 Writer: avoid table undo crash
    - Resolves: rhbz#689053 Writer: fix crash following delete at last table cell
    - Resolves: rhbz#820283 Writer: fix crashes in DOCX table import
    - Resolves: rhbz#827695 Writer: prevent crashes after incomplete print

 0001-rhbz-852128-sw-avoid-table-undo-crash.patch   |   99 +++++++++++++
 ...-fix-crash-following-delete-at-last-table.patch |   68 +++++++++
 ...z-820283-fix-crashes-in-DOCX-table-import.patch |   47 ++++++
 ...-sw-prevent-crashes-after-incomplete-prin.patch |  152 ++++++++++++++++++++
 libreoffice.spec                                   |   12 ++
 5 files changed, 378 insertions(+), 0 deletions(-)
---
diff --git a/0001-rhbz-852128-sw-avoid-table-undo-crash.patch b/0001-rhbz-852128-sw-avoid-table-undo-crash.patch
new file mode 100644
index 0000000..163f802
--- /dev/null
+++ b/0001-rhbz-852128-sw-avoid-table-undo-crash.patch
@@ -0,0 +1,99 @@
+From c44c58be34ae09f4585689b44b04ebd5fc144252 Mon Sep 17 00:00:00 2001
+From: Michael Stahl <mst at openoffice.org>
+Date: Tue, 18 Sep 2012 14:19:50 +0200
+Subject: [PATCH 1/4] rhbz#852128: sw: avoid table undo crash:
+
+SwUndoTblNdsChg::UndoImpl: to prevent access of deleted table box start
+node, disconnect the SwTableBox from the start node before removing the
+table box nodes.
+This problem was probably introduced with CWS swnewtable
+db4de0817df6906db2743239d45f9f0834ab1e91, which changed the order of the
+removal operations for unknown reasons.
+
+(cherry picked from commit cf842d7c7f9559bfdbb3924cd05a3a50d1dff5e3)
+
+Conflicts:
+	sw/source/core/table/swtable.cxx
+
+Change-Id: Ic59823a84082cc6ff453b2b512cbb8253886ecf3
+Reviewed-on: https://gerrit.libreoffice.org/641
+Reviewed-by: Miklos Vajna <vmiklos at suse.cz>
+Tested-by: Miklos Vajna <vmiklos at suse.cz>
+---
+ sw/inc/swtable.hxx               |  1 +
+ sw/source/core/table/swtable.cxx | 14 +++++++++++---
+ sw/source/core/undo/untbl.cxx    |  5 +++++
+ 3 files changed, 17 insertions(+), 3 deletions(-)
+
+diff --git a/sw/inc/swtable.hxx b/sw/inc/swtable.hxx
+index 56cba82..27126c6 100644
+--- a/sw/inc/swtable.hxx
++++ b/sw/inc/swtable.hxx
+@@ -413,6 +413,7 @@ public:
+     SwFrmFmt* ClaimFrmFmt();
+     void ChgFrmFmt( SwTableBoxFmt *pNewFmt );
+ 
++    void RemoveFromTable();
+     const SwStartNode *GetSttNd() const { return pSttNd; }
+     sal_uLong GetSttIdx() const;
+ 
+diff --git a/sw/source/core/table/swtable.cxx b/sw/source/core/table/swtable.cxx
+index d961289..031899c 100644
+--- a/sw/source/core/table/swtable.cxx
++++ b/sw/source/core/table/swtable.cxx
+@@ -1748,10 +1748,9 @@ SwTableBox::SwTableBox( SwTableBoxFmt* pFmt, const SwStartNode& rSttNd, SwTableL
+     rSrtArr.Insert( p );        // eintragen
+ }
+ 
+-SwTableBox::~SwTableBox()
++void SwTableBox::RemoveFromTable()
+ {
+-    // Inhaltstragende Box ?
+-    if( !GetFrmFmt()->GetDoc()->IsInDtor() && pSttNd )
++    if (pSttNd) // box containing contents?
+     {
+         // an der Table austragen
+         const SwTableNode* pTblNd = pSttNd->FindTableNode();
+@@ -1760,6 +1759,15 @@ SwTableBox::~SwTableBox()
+                                     GetTabSortBoxes();
+         SwTableBox *p = this;   // error: &this
+         rSrtArr.Remove( p );        // austragen
++        pSttNd = 0; // clear it so this is only run once
++    }
++}
++
++SwTableBox::~SwTableBox()
++{
++    if (!GetFrmFmt()->GetDoc()->IsInDtor())
++    {
++        RemoveFromTable();
+     }
+ 
+     // ist die TabelleBox der letzte Client im FrameFormat, kann dieses
+diff --git a/sw/source/core/undo/untbl.cxx b/sw/source/core/undo/untbl.cxx
+index 641c000..ec85cfe 100644
+--- a/sw/source/core/undo/untbl.cxx
++++ b/sw/source/core/undo/untbl.cxx
+@@ -1818,7 +1818,11 @@ void SwUndoTblNdsChg::UndoImpl(::sw::UndoRedoContext & rContext)
+                 rDoc.GetNodes()._MoveNodes( aRg, rDoc.GetNodes(), aInsPos, sal_False );
+             }
+             else
++            {   // first disconnect box from node, otherwise ~SwTableBox would
++                // access pBox->pSttNd, deleted by DeleteSection
++                pBox->RemoveFromTable();
+                 rDoc.DeleteSection( rDoc.GetNodes()[ nIdx ] );
++            }
+             aDelBoxes.insert( aDelBoxes.end(), pBox );
+         }
+     }
+@@ -1834,6 +1838,7 @@ void SwUndoTblNdsChg::UndoImpl(::sw::UndoRedoContext & rContext)
+             // TL_CHART2: notify chart about box to be removed
+             if (pPCD)
+                 pPCD->DeleteBox( &pTblNd->GetTable(), *pBox );
++            pBox->RemoveFromTable(); // ~SwTableBox would access pBox->pSttNd
+             aDelBoxes.insert( aDelBoxes.end(), pBox );
+             rDoc.DeleteSection( rDoc.GetNodes()[ nIdx ] );
+         }
+-- 
+1.7.11.4
+
diff --git a/0002-rhbz-689053-fix-crash-following-delete-at-last-table.patch b/0002-rhbz-689053-fix-crash-following-delete-at-last-table.patch
new file mode 100644
index 0000000..61abdb6
--- /dev/null
+++ b/0002-rhbz-689053-fix-crash-following-delete-at-last-table.patch
@@ -0,0 +1,68 @@
+From d68cbde9a23d8ac68916b49d0cbcc5a4c2147b37 Mon Sep 17 00:00:00 2001
+From: Michael Stahl <mstahl at redhat.com>
+Date: Wed, 19 Sep 2012 20:47:48 +0200
+Subject: [PATCH 2/4] rhbz#689053: fix crash following delete at last table
+ cell:
+
+The IsSelOvr() in SwCrsrShell::Combine() detects that the PaM with mark
+in the last table cell and point ouside the table is invalid, but
+unfortunatley restores the wrong position, which does not actually
+correct the PaM; the deletion on the invalid PaM then removes the
+last SwTxtNode in the document, which leads to crash later.
+
+(cherry picked from commit af4b6c94c68b5f67b931cde8d0acda6ec8b288bb)
+
+Conflicts:
+	sw/source/core/crsr/crsrsh.cxx
+
+Change-Id: Ib2ae0b54e6c15dbe5b6811d8696531bf2022e1a4
+Reviewed-on: https://gerrit.libreoffice.org/652
+Reviewed-by: Miklos Vajna <vmiklos at suse.cz>
+Tested-by: Miklos Vajna <vmiklos at suse.cz>
+(cherry picked from commit 6bcbf68b29b609cf06dbea0e192533e11eb523c3)
+---
+ sw/source/core/crsr/crsrsh.cxx | 15 ++++++++-------
+ 1 file changed, 8 insertions(+), 7 deletions(-)
+
+diff --git a/sw/source/core/crsr/crsrsh.cxx b/sw/source/core/crsr/crsrsh.cxx
+index 36fe86d..626557c 100644
+--- a/sw/source/core/crsr/crsrsh.cxx
++++ b/sw/source/core/crsr/crsrsh.cxx
+@@ -1994,26 +1994,27 @@ void SwCrsrShell::Combine()
+         return;
+ 
+     SwCallLink aLk( *this );        // Crsr-Moves ueberwachen, evt. Link callen
+-    SwCrsrSaveState aSaveState( *pCurCrsr );
++    // rhbz#689053: IsSelOvr must restore the saved stack position, not the
++    // current one, because current point + stack mark may be invalid PaM
++    SwCrsrSaveState aSaveState(*pCrsrStk);
+     if( pCrsrStk->HasMark() )           // nur wenn GetMark gesetzt wurde
+     {
+         bool const bResult =
+         CheckNodesRange( pCrsrStk->GetMark()->nNode, pCurCrsr->GetPoint()->nNode, sal_True );
+         OSL_ENSURE(bResult, "StackCrsr & act. Crsr not in same Section.");
+         (void) bResult; // non-debug: unused
+-        // kopiere das GetMark
+-        if( !pCurCrsr->HasMark() )
+-            pCurCrsr->SetMark();
+-        *pCurCrsr->GetMark() = *pCrsrStk->GetMark();
+-        pCurCrsr->GetMkPos() = pCrsrStk->GetMkPos();
+     }
++    *pCrsrStk->GetPoint() = *pCurCrsr->GetPoint();
++    pCrsrStk->GetPtPos() = pCurCrsr->GetPtPos();
+ 
+     SwShellCrsr * pTmp = 0;
+     if( pCrsrStk->GetNext() != pCrsrStk )
+     {
+         pTmp = dynamic_cast<SwShellCrsr*>(pCrsrStk->GetNext());
+     }
+-    delete pCrsrStk;
++    delete pCurCrsr;
++    pCurCrsr = pCrsrStk;
++    pCrsrStk->MoveTo(0); // remove from ring
+     pCrsrStk = pTmp;
+     if( !pCurCrsr->IsInProtectTable( sal_True ) &&
+         !pCurCrsr->IsSelOvr( nsSwCursorSelOverFlags::SELOVER_TOGGLE |
+-- 
+1.7.11.4
+
diff --git a/0003-rhbz-820283-fix-crashes-in-DOCX-table-import.patch b/0003-rhbz-820283-fix-crashes-in-DOCX-table-import.patch
new file mode 100644
index 0000000..1a61873
--- /dev/null
+++ b/0003-rhbz-820283-fix-crashes-in-DOCX-table-import.patch
@@ -0,0 +1,47 @@
+From e1443019da5507fad8cc398bcf964cf3c72643ab Mon Sep 17 00:00:00 2001
+From: Michael Stahl <mstahl at redhat.com>
+Date: Mon, 24 Sep 2012 11:21:11 +0200
+Subject: [PATCH 3/4] rhbz#820283: fix crashes in DOCX table import:
+
+It is apparently possible that writerfilter creates a table with
+irregular structure, where the lines have varying numbers of boxes in
+them.  This may cause crashes on later editing operations, e.g.
+when SwTable::NewInsertCol() is unable to find boxes covering a
+particular column.  To prevent this, add missing boxes in
+SwNodes::TextToTable().
+
+(cherry picked from commit 6d2e09db4a677068095b0bebd08fbbb96620d60c)
+
+Change-Id: I423821645baeaf55595e4933e1ab8fb89b2099f3
+---
+ sw/source/core/docnode/ndtbl.cxx | 14 ++++++++++++++
+ 1 file changed, 14 insertions(+)
+
+diff --git a/sw/source/core/docnode/ndtbl.cxx b/sw/source/core/docnode/ndtbl.cxx
+index ca006bc..03409ce 100644
+--- a/sw/source/core/docnode/ndtbl.cxx
++++ b/sw/source/core/docnode/ndtbl.cxx
+@@ -1374,6 +1374,20 @@ SwTableNode* SwNodes::TextToTable( const SwNodes::TableRanges_t & rTableNodes,
+     // die Tabelle ausgleichen, leere Sections einfuegen
+     sal_uInt16 n;
+ 
++    for (n = 0; n < pTable->GetTabLines().Count(); ++n )
++    {
++        // rhbz#820283: balance the cells in table rows
++        SwTableLine *const pCurrLine = pTable->GetTabLines()[ n ];
++        nBoxes = pCurrLine->GetTabBoxes().Count();
++        SwTxtFmtColl *const pTxtColl(const_cast<SwTxtFmtColl*>(
++                GetDoc()->GetDfltTxtFmtColl()));
++        if (nMaxBoxes != nBoxes)
++        {
++            InsBoxen( pTblNd, pCurrLine, pBoxFmt, pTxtColl, 0,
++                        nBoxes, nMaxBoxes - nBoxes );
++        }
++    }
++
+     if( !aPosArr.empty() )
+     {
+         SwTableLines& rLns = pTable->GetTabLines();
+-- 
+1.7.11.4
+
diff --git a/0004-rhbz-827695-sw-prevent-crashes-after-incomplete-prin.patch b/0004-rhbz-827695-sw-prevent-crashes-after-incomplete-prin.patch
new file mode 100644
index 0000000..b7540b1
--- /dev/null
+++ b/0004-rhbz-827695-sw-prevent-crashes-after-incomplete-prin.patch
@@ -0,0 +1,152 @@
+From a2cb0319ea36bf068557643e9421a81a2aba1947 Mon Sep 17 00:00:00 2001
+From: Michael Stahl <mstahl at redhat.com>
+Date: Wed, 26 Sep 2012 12:43:29 +0200
+Subject: [PATCH 4/4] rhbz#827695: sw: prevent crashes after incomplete print:
+
+If the last page is not printed for whatever reason, then
+SwXTextDocument's destructor will delete a SwViewOptionAdjust_Impl,
+which accesses the document's ViewShell, which has already been
+deleted at that point.  Add a horrible kludge to not crash for now.
+
+Change-Id: I67fe37970d60782030b84f2badddd1e66ef3f9c6
+(cherry picked from commit d53e12c7a9c2d0a3b487303673c1fafd09f6593c)
+Reviewed-on: https://gerrit.libreoffice.org/699
+Reviewed-by: Noel Power <noel.power at suse.com>
+Tested-by: Noel Power <noel.power at suse.com>
+(cherry picked from commit 47014647eced4864e149b923b7eb024418e71782)
+---
+ sw/inc/printdata.hxx              |  2 +-
+ sw/inc/unotxdoc.hxx               |  5 +++--
+ sw/source/core/view/printdata.cxx |  5 +++++
+ sw/source/ui/uno/unotxdoc.cxx     | 26 ++++++++++++++++++--------
+ 4 files changed, 27 insertions(+), 11 deletions(-)
+
+diff --git a/sw/inc/printdata.hxx b/sw/inc/printdata.hxx
+index 02d56b8..a64ece9 100644
+--- a/sw/inc/printdata.hxx
++++ b/sw/inc/printdata.hxx
+@@ -42,7 +42,6 @@
+ 
+ class SwDoc;
+ class SwDocShell;
+-class ViewShell;
+ class _SetGetExpFlds;
+ class SwViewOption;
+ class OutputDevice;
+@@ -278,6 +277,7 @@ public:
+     void ViewOptionAdjustStart( ViewShell &rSh, const SwViewOption &rViewOptions);
+     void ViewOptionAdjust( SwPrintData const* const pPrtOptions );
+     void ViewOptionAdjustStop();
++    void ViewOptionAdjustCrashPreventionKludge();
+ 
+     bool HasSwPrtOptions() const    { return m_pPrtOptions != 0; }
+     SwPrintData const*  GetSwPrtOptions() const { return m_pPrtOptions.get(); }
+diff --git a/sw/inc/unotxdoc.hxx b/sw/inc/unotxdoc.hxx
+index 42d646f..a460565 100644
+--- a/sw/inc/unotxdoc.hxx
++++ b/sw/inc/unotxdoc.hxx
+@@ -587,7 +587,7 @@ public:
+   -----------------------------------------------------------------------*/
+ class SwViewOptionAdjust_Impl
+ {
+-    ViewShell &    m_rShell;
++    ViewShell *     m_pShell;
+     SwViewOption    m_aOldViewOptions;
+ 
+ public:
+@@ -595,7 +595,8 @@ public:
+     ~SwViewOptionAdjust_Impl();
+     void AdjustViewOptions( SwPrintData const* const pPrtOptions );
+     bool checkShell( const ViewShell& rCompare ) const
+-    { return &rCompare == &m_rShell; }
++    { return &rCompare == m_pShell; }
++    void DontTouchThatViewShellItSmellsFunny() { m_pShell = 0; }
+ };
+ 
+ 
+diff --git a/sw/source/core/view/printdata.cxx b/sw/source/core/view/printdata.cxx
+index 870ecbe..5c8e0ab 100644
+--- a/sw/source/core/view/printdata.cxx
++++ b/sw/source/core/view/printdata.cxx
+@@ -131,6 +131,11 @@ void SwRenderData::ViewOptionAdjustStop()
+     m_pViewOptionAdjust.reset();
+ }
+ 
++void SwRenderData::ViewOptionAdjustCrashPreventionKludge()
++{
++    m_pViewOptionAdjust->DontTouchThatViewShellItSmellsFunny();
++}
++
+ 
+ void SwRenderData::MakeSwPrtOptions(
+     SwDocShell const*const pDocShell,
+diff --git a/sw/source/ui/uno/unotxdoc.cxx b/sw/source/ui/uno/unotxdoc.cxx
+index 8711d4e..931d5ec 100644
+--- a/sw/source/ui/uno/unotxdoc.cxx
++++ b/sw/source/ui/uno/unotxdoc.cxx
+@@ -404,6 +404,13 @@ SwXTextDocument::~SwXTextDocument()
+         xNumFmtAgg = 0;
+     }
+     delete m_pPrintUIOptions;
++    if (m_pRenderData && m_pRenderData->IsViewOptionAdjust())
++    {   // rhbz#827695: this can happen if the last page is not printed
++        // the ViewShell has been deleted already by SwView::~SwView
++        // FIXME: replace this awful implementation of XRenderable with
++        // something less insane that has its own view
++        m_pRenderData->ViewOptionAdjustCrashPreventionKludge();
++    }
+     delete m_pRenderData;
+ }
+ 
+@@ -3861,14 +3868,17 @@ void SwXDocumentPropertyHelper::onChange()
+ 
+ SwViewOptionAdjust_Impl::SwViewOptionAdjust_Impl(
+             ViewShell& rSh, const SwViewOption &rViewOptions)
+-    : m_rShell( rSh )
++    : m_pShell(&rSh)
+     , m_aOldViewOptions( rViewOptions )
+ {
+ }
+ 
+ SwViewOptionAdjust_Impl::~SwViewOptionAdjust_Impl()
+ {
+-    m_rShell.ApplyViewOptions( m_aOldViewOptions );
++    if (m_pShell)
++    {
++        m_pShell->ApplyViewOptions( m_aOldViewOptions );
++    }
+ }
+ 
+ void
+@@ -3876,14 +3886,14 @@ SwViewOptionAdjust_Impl::AdjustViewOptions(SwPrintData const*const pPrtOptions)
+ {
+     // to avoid unnecessary reformatting the view options related to the content
+     // below should only change if necessary, that is if respective content is present
+-    const bool bContainsHiddenChars         = m_rShell.GetDoc()->ContainsHiddenChars();
+-    const SwFieldType* pFldType = m_rShell.GetDoc()->GetSysFldType( RES_HIDDENTXTFLD );
++    const bool bContainsHiddenChars         = m_pShell->GetDoc()->ContainsHiddenChars();
++    const SwFieldType* pFldType = m_pShell->GetDoc()->GetSysFldType( RES_HIDDENTXTFLD );
+     const bool bContainsHiddenFields        = pFldType && pFldType->GetDepends();
+-    pFldType = m_rShell.GetDoc()->GetSysFldType( RES_HIDDENPARAFLD );
++    pFldType = m_pShell->GetDoc()->GetSysFldType( RES_HIDDENPARAFLD );
+     const bool bContainsHiddenParagraphs    = pFldType && pFldType->GetDepends();
+-    pFldType = m_rShell.GetDoc()->GetSysFldType( RES_JUMPEDITFLD );
++    pFldType = m_pShell->GetDoc()->GetSysFldType( RES_JUMPEDITFLD );
+     const bool bContainsPlaceHolders        = pFldType && pFldType->GetDepends();
+-    const bool bContainsFields              = m_rShell.IsAnyFieldInDoc();
++    const bool bContainsFields              = m_pShell->IsAnyFieldInDoc();
+ 
+     SwViewOption aRenderViewOptions( m_aOldViewOptions );
+ 
+@@ -3923,7 +3933,7 @@ SwViewOptionAdjust_Impl::AdjustViewOptions(SwPrintData const*const pPrtOptions)
+     if (m_aOldViewOptions != aRenderViewOptions)  // check if reformatting is necessary
+     {
+         aRenderViewOptions.SetPrinting( pPrtOptions != NULL );
+-        m_rShell.ApplyViewOptions( aRenderViewOptions );
++        m_pShell->ApplyViewOptions( aRenderViewOptions );
+     }
+ }
+ 
+-- 
+1.7.11.4
+
diff --git a/libreoffice.spec b/libreoffice.spec
index fcf9868..ebf6cda 100644
--- a/libreoffice.spec
+++ b/libreoffice.spec
@@ -157,6 +157,10 @@ Patch39: 0001-Resolves-rhbz-855541-XIOError-handler-multithread-wo.patch
 Patch40: 0001-rhbz-836827-SQLFeatureNotSupportedException-only-in-.patch
 Patch41: 0001-n-744509-Alignment-of-text-is-wrong.patch
 Patch42: 0001-rhbz-826526-Inform-user-about-unsupported-PDF-encryp.patch
+Patch43: 0001-rhbz-852128-sw-avoid-table-undo-crash.patch
+Patch44: 0002-rhbz-689053-fix-crash-following-delete-at-last-table.patch
+Patch45: 0003-rhbz-820283-fix-crashes-in-DOCX-table-import.patch
+Patch46: 0004-rhbz-827695-sw-prevent-crashes-after-incomplete-prin.patch
 
 %{!?python_sitearch: %global python_sitearch %(%{__python} -c "from distutils.sysconfig import get_python_lib; print(get_python_lib(1))")}
 %define instdir %{_libdir}
@@ -1029,6 +1033,10 @@ mv -f redhat.soc extras/source/palettes/standard.soc
 %patch40 -p1 -b .rhbz-836827-SQLFeatureNotSupportedException-only-in-.patch
 %patch41 -p1 -b .n-744509-Alignment-of-text-is-wrong.patch
 %patch42 -p1 -b .rhbz-826526-Inform-user-about-unsupported-PDF-encryp.patch
+%patch43 -p1 -b .rhbz-852128-sw-avoid-table-undo-crash.patch
+%patch44 -p1 -b .rhbz-689053-fix-crash-following-delete-at-last-table.patch
+%patch45 -p1 -b .rhbz-820283-fix-crashes-in-DOCX-table-import.patch
+%patch46 -p1 -b .rhbz-827695-sw-prevent-crashes-after-incomplete-prin.patch
 
 # TODO: check this
 # these are horribly incomplete--empty translations and copied english
@@ -2317,6 +2325,10 @@ update-desktop-database %{_datadir}/applications &> /dev/null || :
 %changelog
 * Fri Sep 28 2012 Stephan Bergmann <sbergman at redhat.com> - 1:3.5.6.2-7-UNBUILT
 - Related: rhbz#826526 Inform user about unsupported PDF encryption formats
+- Resolves: rhbz#852128 Writer: avoid table undo crash
+- Resolves: rhbz#689053 Writer: fix crash following delete at last table cell
+- Resolves: rhbz#820283 Writer: fix crashes in DOCX table import
+- Resolves: rhbz#827695 Writer: prevent crashes after incomplete print
 
 * Fri Sep 28 2012 Caolán McNamara <caolanm at redhat.com> - 1:3.5.6.2-6
 - Resolves: fdo#54565 text misaligned in pptx


More information about the scm-commits mailing list