diff options
author | Manfred Blume <manfred.blume@cib.de> | 2018-01-25 15:46:57 +0100 |
---|---|---|
committer | Thorsten Behrens <Thorsten.Behrens@CIB.de> | 2018-01-27 23:33:40 +0100 |
commit | 26dc825d9fe7fe6a4188fc6ef68bc801fc8db064 (patch) | |
tree | 6390f07eb49e37e3d10a600d34a2c44609ea0cdc | |
parent | 960c96eabb15577b52f626cb0a3c8932757911b6 (diff) |
tdf#114306 fix crash caused by special document
Regression from 18765b9fa739337d2d891513f6e2fb7c3ce23b50
chnage signature of
static void lcl_RecalcRow( SwRowFrame& rRow, long nBottom )
to
static void lcl_RecalcRow( SwRowFrame* pRow, long nBottom )
Reviewed-on: https://gerrit.libreoffice.org/48613
Tested-by: Jenkins <ci@libreoffice.org>
Reviewed-by: Thorsten Behrens <Thorsten.Behrens@CIB.de>
(cherry picked from commit e4400f4c4e267f8528df3a7d5a09623c888bd10c)
Conflicts:
sw/qa/extras/uiwriter/uiwriter.cxx
Change-Id: Ie00435aa4bffa3d2e49896aea6894ae999a5536a
Reviewed-on: https://gerrit.libreoffice.org/48729
Tested-by: Jenkins <ci@libreoffice.org>
Reviewed-by: Thorsten Behrens <Thorsten.Behrens@CIB.de>
-rwxr-xr-x | sw/qa/extras/uiwriter/data/fdo114306_2.odt | bin | 0 -> 38424 bytes | |||
-rw-r--r-- | sw/qa/extras/uiwriter/uiwriter.cxx | 12 | ||||
-rw-r--r-- | sw/source/core/layout/tabfrm.cxx | 57 |
3 files changed, 53 insertions, 16 deletions
diff --git a/sw/qa/extras/uiwriter/data/fdo114306_2.odt b/sw/qa/extras/uiwriter/data/fdo114306_2.odt Binary files differnew file mode 100755 index 000000000000..b4bebc58add5 --- /dev/null +++ b/sw/qa/extras/uiwriter/data/fdo114306_2.odt diff --git a/sw/qa/extras/uiwriter/uiwriter.cxx b/sw/qa/extras/uiwriter/uiwriter.cxx index a81d236d8277..8f48295abe0c 100644 --- a/sw/qa/extras/uiwriter/uiwriter.cxx +++ b/sw/qa/extras/uiwriter/uiwriter.cxx @@ -288,6 +288,7 @@ public: void testTdf99689TableOfTables(); void testTdf113790(); void testTdf114306(); + void testTdf114306_2(); void testTdf114536(); CPPUNIT_TEST_SUITE(SwUiWriterTest); @@ -458,6 +459,7 @@ public: CPPUNIT_TEST(testTdf99689TableOfTables); CPPUNIT_TEST(testTdf113790); CPPUNIT_TEST(testTdf114306); + CPPUNIT_TEST(testTdf114306_2); CPPUNIT_TEST(testTdf114536); CPPUNIT_TEST_SUITE_END(); @@ -5257,6 +5259,16 @@ void SwUiWriterTest::testTdf114306() assertXPath(pXmlDoc, "/root/page[2]/body/tab[1]/row[1]/cell[1]/txt", 1); } +void SwUiWriterTest::testTdf114306_2() +{ + // tdf#114306 fix unexpected page break in row-spanned table + // load regression document without writer crash + load(DATA_DIRECTORY, "fdo114306_2.odt"); + + // correct number of pages + CPPUNIT_ASSERT_EQUAL(4, getPages()); +} + void SwUiWriterTest::testTdf108524() { createDoc("tdf108524.odt"); diff --git a/sw/source/core/layout/tabfrm.cxx b/sw/source/core/layout/tabfrm.cxx index 859c78b9c50d..ca245b65599d 100644 --- a/sw/source/core/layout/tabfrm.cxx +++ b/sw/source/core/layout/tabfrm.cxx @@ -173,7 +173,7 @@ void SwTabFrame::RegistFlys() } void SwInvalidateAll( SwFrame *pFrame, long nBottom ); -static void lcl_RecalcRow( SwRowFrame& rRow, long nBottom ); +static void lcl_RecalcRow( SwRowFrame* pRow, long nBottom ); static bool lcl_ArrangeLowers( SwLayoutFrame *pLay, long lYStart, bool bInva ); // #i26945# - add parameter <_bOnlyRowsAndCells> to control // that only row and cell frames are formatted. @@ -299,7 +299,7 @@ static void lcl_InvalidateLowerObjs( SwLayoutFrame& _rLayoutFrame, } } -// Local helper function to shrink all lowers of rRow to 0 height +// Local helper function to shrink all lowers of pRow to 0 height static void lcl_ShrinkCellsAndAllContent( SwRowFrame& rRow ) { SwCellFrame* pCurrMasterCell = static_cast<SwCellFrame*>(rRow.Lower()); @@ -691,7 +691,7 @@ static bool lcl_RecalcSplitLine( SwRowFrame& rLastLine, SwRowFrame& rFollowLine, rLastLine.SetInSplit(); // Do the recalculation - lcl_RecalcRow( rLastLine, LONG_MAX ); + lcl_RecalcRow( &rLastLine, LONG_MAX ); // #115759# - force a format of the last line in order to // get the correct height. rLastLine.InvalidateSize(); @@ -1565,7 +1565,7 @@ static bool lcl_InnerCalcLayout( SwFrame *pFrame, return bRet; } -static void lcl_RecalcRow( SwRowFrame& rRow, long nBottom ) +static void lcl_RecalcRow( SwRowFrame* pRow, long nBottom ) { // FME 2007-08-30 #i81146# new loop control int nLoopControlRuns_1 = 0; @@ -1579,14 +1579,14 @@ static void lcl_RecalcRow( SwRowFrame& rRow, long nBottom ) int nLoopControlRuns_2 = 0; sal_uInt16 nLoopControlStage_2 = 0; - while( lcl_InnerCalcLayout( &rRow, nBottom ) ) + while( lcl_InnerCalcLayout( pRow, nBottom ) ) { if ( ++nLoopControlRuns_2 > nLoopControlMax ) { SAL_WARN_IF(nLoopControlStage_2 == 0, "sw.layout", "LoopControl_2 in lcl_RecalcRow: Stage 1!"); SAL_WARN_IF(nLoopControlStage_2 == 1, "sw.layout", "LoopControl_2 in lcl_RecalcRow: Stage 2!!"); SAL_WARN_IF(nLoopControlStage_2 >= 2, "sw.layout", "LoopControl_2 in lcl_RecalcRow: Stage 3!!!"); - rRow.ValidateThisAndAllLowers( nLoopControlStage_2++ ); + pRow->ValidateThisAndAllLowers( nLoopControlStage_2++ ); nLoopControlRuns_2 = 0; if( nLoopControlStage_2 > 2 ) break; @@ -1599,14 +1599,39 @@ static void lcl_RecalcRow( SwRowFrame& rRow, long nBottom ) { // #115759# - force another format of the // lowers, if at least one of it was invalid. - bCheck = SwContentFrame::CalcLowers( &rRow, rRow.GetUpper(), nBottom, true ); + + // tdf#114306 writer may crash because pRow points to a deleted SwRowFrame + SwRowFrame* pOriginalRow = pRow; + OSL_ENSURE(pOriginalRow->GetUpper() && pOriginalRow->GetUpper()->IsTabFrame(), "No table"); + SwTabFrame* pOriginalTab = static_cast<SwTabFrame*>(pRow->GetUpper()); + + bCheck = SwContentFrame::CalcLowers( pRow, pRow->GetUpper(), nBottom, true ); + + bool bRowStillExists = false; + SwFrame* pTestRow = pOriginalTab->Lower(); + + while (pTestRow) + { + if (pTestRow == pRow) + { + bRowStillExists = true; + break; + } + pTestRow = pTestRow->GetNext(); + } + + if (!bRowStillExists) + { + SAL_WARN("sw.layout", "no row anymore at " << pRow); + return; + } // NEW TABLES // First we calculate the cells with row span of < 1, afterwards // all cells with row span of > 1: for ( int i = 0; i < 2; ++i ) { - SwCellFrame* pCellFrame = static_cast<SwCellFrame*>(rRow.Lower()); + SwCellFrame* pCellFrame = static_cast<SwCellFrame*>(pRow->Lower()); while ( pCellFrame ) { const bool bCalc = 0 == i ? @@ -1632,7 +1657,7 @@ static void lcl_RecalcRow( SwRowFrame& rRow, long nBottom ) SAL_WARN_IF(nLoopControlStage_1 == 0, "sw.layout", "LoopControl_1 in lcl_RecalcRow: Stage 1!"); SAL_WARN_IF(nLoopControlStage_1 == 1, "sw.layout", "LoopControl_1 in lcl_RecalcRow: Stage 2!!"); SAL_WARN_IF(nLoopControlStage_1 >= 2, "sw.layout", "LoopControl_1 in lcl_RecalcRow: Stage 3!!!"); - rRow.ValidateThisAndAllLowers( nLoopControlStage_1++ ); + pRow->ValidateThisAndAllLowers( nLoopControlStage_1++ ); nLoopControlRuns_1 = 0; if( nLoopControlStage_1 > 2 ) break; @@ -1657,7 +1682,7 @@ static void lcl_RecalcTable( SwTabFrame& rTab, rNotify.SetLowersComplete( true ); } ::SwInvalidatePositions( pFirstRow, LONG_MAX ); - lcl_RecalcRow( static_cast<SwRowFrame&>(*pFirstRow), LONG_MAX ); + lcl_RecalcRow( static_cast<SwRowFrame*>(pFirstRow), LONG_MAX ); } } @@ -2126,7 +2151,7 @@ void SwTabFrame::MakeAll(vcl::RenderContext* pRenderContext) { ::SwInvalidateAll( pLastLine, LONG_MAX ); SetRebuildLastLine( true ); - lcl_RecalcRow( static_cast<SwRowFrame&>(*pLastLine), LONG_MAX ); + lcl_RecalcRow( static_cast<SwRowFrame*>(pLastLine), LONG_MAX ); SetRebuildLastLine( false ); } @@ -2249,7 +2274,7 @@ void SwTabFrame::MakeAll(vcl::RenderContext* pRenderContext) } else if (m_bONECalcLowers) { - lcl_RecalcRow( static_cast<SwRowFrame&>(*Lower()), LONG_MAX ); + lcl_RecalcRow( static_cast<SwRowFrame*>(Lower()), LONG_MAX ); m_bONECalcLowers = false; } } @@ -2272,7 +2297,7 @@ void SwTabFrame::MakeAll(vcl::RenderContext* pRenderContext) } else if (m_bONECalcLowers) { - lcl_RecalcRow( static_cast<SwRowFrame&>(*Lower()), LONG_MAX ); + lcl_RecalcRow( static_cast<SwRowFrame*>(Lower()), LONG_MAX ); m_bONECalcLowers = false; } @@ -2338,7 +2363,7 @@ void SwTabFrame::MakeAll(vcl::RenderContext* pRenderContext) { SetInRecalcLowerRow( true ); - ::lcl_RecalcRow( static_cast<SwRowFrame&>(*Lower()), nDeadLine ); + ::lcl_RecalcRow( static_cast<SwRowFrame*>(Lower()), nDeadLine ); SetInRecalcLowerRow( false ); } m_bLowersFormatted = true; @@ -2438,7 +2463,7 @@ void SwTabFrame::MakeAll(vcl::RenderContext* pRenderContext) // to nDeadLine may not be enough. if ( bSplitError && bTryToSplit ) // no restart if we did not try to split: i72847, i79426 { - lcl_RecalcRow( static_cast<SwRowFrame&>(*Lower()), LONG_MAX ); + lcl_RecalcRow( static_cast<SwRowFrame*>(Lower()), LONG_MAX ); setFrameAreaPositionValid(false); bTryToSplit = false; continue; @@ -2479,7 +2504,7 @@ void SwTabFrame::MakeAll(vcl::RenderContext* pRenderContext) // its content. const bool bOldJoinLock = GetFollow()->IsJoinLocked(); GetFollow()->LockJoin(); - ::lcl_RecalcRow( static_cast<SwRowFrame&>(*GetFollow()->Lower()), + ::lcl_RecalcRow( static_cast<SwRowFrame*>(GetFollow()->Lower()), fnRectX.GetBottom(GetFollow()->GetUpper()->getFrameArea()) ); // #i43913# // #i63632# Do not unlock the |