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-26 23:53:30 +0100 |
commit | e4400f4c4e267f8528df3a7d5a09623c888bd10c (patch) | |
tree | de0febdde661e8f00d6ae5f46df286adf8df0501 /sw | |
parent | ced60a5fa7824caff07846d7dd8abad3c0f31b55 (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 )
Change-Id: Ie00435aa4bffa3d2e49896aea6894ae999a5536a
Reviewed-on: https://gerrit.libreoffice.org/48613
Tested-by: Jenkins <ci@libreoffice.org>
Reviewed-by: Thorsten Behrens <Thorsten.Behrens@CIB.de>
Diffstat (limited to 'sw')
-rwxr-xr-x | sw/qa/extras/uiwriter/data/fdo114306_2.odt | bin | 0 -> 38424 bytes | |||
-rw-r--r-- | sw/qa/extras/uiwriter/uiwriter.cxx | 13 | ||||
-rw-r--r-- | sw/source/core/layout/tabfrm.cxx | 57 |
3 files changed, 54 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 6f4903f98d2f..4789d2d39829 100644 --- a/sw/qa/extras/uiwriter/uiwriter.cxx +++ b/sw/qa/extras/uiwriter/uiwriter.cxx @@ -294,6 +294,7 @@ public: void testTdf113790(); void testTdf108048(); void testTdf114306(); + void testTdf114306_2(); void testTdf113481(); void testTdf115013(); void testTdf114536(); @@ -471,6 +472,7 @@ public: CPPUNIT_TEST(testTdf113790); CPPUNIT_TEST(testTdf108048); CPPUNIT_TEST(testTdf114306); + CPPUNIT_TEST(testTdf114306_2); CPPUNIT_TEST(testTdf113481); CPPUNIT_TEST(testTdf115013); CPPUNIT_TEST(testTdf114536); @@ -5290,6 +5292,17 @@ 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()); +} + + // During insert of the document with list inside into the main document inside the list // we should merge both lists into one, when they have the same list properties void SwUiWriterTest::testTdf113877() diff --git a/sw/source/core/layout/tabfrm.cxx b/sw/source/core/layout/tabfrm.cxx index f1e2e2e56fff..d0f2ddddba26 100644 --- a/sw/source/core/layout/tabfrm.cxx +++ b/sw/source/core/layout/tabfrm.cxx @@ -163,7 +163,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. @@ -289,7 +289,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()); @@ -681,7 +681,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(); @@ -1555,7 +1555,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; @@ -1569,14 +1569,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; @@ -1589,14 +1589,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 ? @@ -1622,7 +1647,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; @@ -1647,7 +1672,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 ); } } @@ -2116,7 +2141,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 ); } @@ -2239,7 +2264,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; } } @@ -2262,7 +2287,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; } @@ -2328,7 +2353,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; @@ -2428,7 +2453,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; @@ -2469,7 +2494,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 |