sw/source/core/inc/frame.hxx | 2 +- sw/source/core/inc/tabfrm.hxx | 2 +- sw/source/core/inc/txtfrm.hxx | 5 ++++- sw/source/core/layout/tabfrm.cxx | 3 ++- sw/source/core/layout/wsfrm.cxx | 3 ++- sw/source/core/text/txtfrm.cxx | 38 ++++++++++++++++++++++++++------------ 6 files changed, 36 insertions(+), 17 deletions(-)
New commits: commit 48495a7135d74dbf7ef19f868d6b76a725f36a96 Author: Caolán McNamara <caol...@redhat.com> Date: Fri May 29 15:25:27 2015 +0100 fix Invalid Read on conversion of ooo95991-1.odt to pdf "Prepare" can delete the Portion belonging to the SwTxtFrm and replace it. Prepare knows this and re-fetches it if that happens. But Prepare can call itself and the outermost Prepare doesn't know that the innermost Prepare replaced the SwTxtFrm (and re-fetched it for the remainer of the innermost Prepare). So bubble out that it was re-fetched so the outer most one re-fetches too Invalid read of size 1 SwParaPortion::SetPrep(bool) (porlay.hxx:299) SwTextFrm::Prepare(PrepareHint, void const*, bool) (txtfrm.cxx:1805) SwContentFrm::MakeAll() (calcmove.cxx:1317) SwFrm::PrepareMake() (calcmove.cxx:340) SwFrm::Calc() const (frame.hxx:1004) CalcContent(SwLayoutFrm*, bool, bool) (fly.cxx:1465) SwLayoutFrm::FormatWidthCols(SwBorderAttrs const&, long, long) (wsfrm.cxx:3306) Address 0x2137c850 is 832 bytes inside a block of size 840 free'd free (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so) rtl_freeMemory_SYSTEM(void*) (alloc_global.cxx:277) rtl_freeMemory (alloc_global.cxx:347) rtl_cache_free (alloc_cache.cxx:1222) FixedMemPool::Free(void*) (mempool.cxx:48) SwParaPortion::operator delete(void*, unsigned long) (in /home/caolan/LibreOffice/core/instdir/program/libswlo.so) SwParaPortion::~SwParaPortion() (porlay.cxx:1967) SwTextFrm::ClearPara() (txtcache.cxx:106) SwTextFrm::Init() (txtfrm.cxx:339) SwTextFrm::CalcLineSpace() (txtfrm.cxx:792) SwTextFrm::Prepare(PrepareHint, void const*, bool) (txtfrm.cxx:1724) SwTextFrm::Prepare(PrepareHint, void const*, bool) (txtfrm.cxx:1706) SwContentFrm::MakeAll() (calcmove.cxx:1317) SwFrm::PrepareMake() (calcmove.cxx:340) SwFrm::Calc() const (frame.hxx:1004) CalcContent(SwLayoutFrm*, bool, bool) (fly.cxx:1465) SwLayoutFrm::FormatWidthCols(SwBorderAttrs const&, long, long) (wsfrm.cxx:3306) Change-Id: I1fdade2846e3cbd2e73be1f58d2597e9358fa0ea (cherry picked from commit f703201d35f6e77940f68a21b339f67335b99441) diff --git a/sw/source/core/inc/frame.hxx b/sw/source/core/inc/frame.hxx index 0a23c88..8d283f5 100644 --- a/sw/source/core/inc/frame.hxx +++ b/sw/source/core/inc/frame.hxx @@ -770,7 +770,7 @@ public: // HACK: shortcut between frame and formatting // It's your own fault if you cast void* incorrectly! In any case check // the void* for 0. - virtual void Prepare( const PrepareHint ePrep = PREP_CLEAR, + virtual bool Prepare( const PrepareHint ePrep = PREP_CLEAR, const void *pVoid = 0, bool bNotify = true ); // true if it is the correct class, false otherwise diff --git a/sw/source/core/inc/tabfrm.hxx b/sw/source/core/inc/tabfrm.hxx index 3b418cf..c78872b 100644 --- a/sw/source/core/inc/tabfrm.hxx +++ b/sw/source/core/inc/tabfrm.hxx @@ -133,7 +133,7 @@ public: virtual void Cut() SAL_OVERRIDE; virtual void Paste( SwFrm* pParent, SwFrm* pSibling = 0 ) SAL_OVERRIDE; - virtual void Prepare( const PrepareHint ePrep = PREP_CLEAR, + virtual bool Prepare( const PrepareHint ePrep = PREP_CLEAR, const void *pVoid = 0, bool bNotify = true ) SAL_OVERRIDE; SwContentFrm *FindLastContent(); diff --git a/sw/source/core/inc/txtfrm.hxx b/sw/source/core/inc/txtfrm.hxx index 2d1418c..63ce3b9 100644 --- a/sw/source/core/inc/txtfrm.hxx +++ b/sw/source/core/inc/txtfrm.hxx @@ -342,8 +342,11 @@ public: * SwContentFrm: the shortcut for the Frames * If the void* casts wrongly, it's its own fault! * The void* must be checked for 0 in any case! + * + * return true if the Portion associated with this SwTxtFrm was + * potentially destroyed and replaced by Prepare */ - virtual void Prepare( const PrepareHint ePrep = PREP_CLEAR, + virtual bool Prepare( const PrepareHint ePrep = PREP_CLEAR, const void *pVoid = 0, bool bNotify = true ) SAL_OVERRIDE; /** diff --git a/sw/source/core/layout/tabfrm.cxx b/sw/source/core/layout/tabfrm.cxx index 879bdff..1fd119c 100644 --- a/sw/source/core/layout/tabfrm.cxx +++ b/sw/source/core/layout/tabfrm.cxx @@ -3490,10 +3490,11 @@ void SwTabFrm::Paste( SwFrm* pParent, SwFrm* pSibling ) } } -void SwTabFrm::Prepare( const PrepareHint eHint, const void *, bool ) +bool SwTabFrm::Prepare( const PrepareHint eHint, const void *, bool ) { if( PREP_BOSS_CHGD == eHint ) CheckDirChange(); + return false; } SwRowFrm::SwRowFrm(const SwTableLine &rLine, SwFrm* pSib, bool bInsertContent) diff --git a/sw/source/core/layout/wsfrm.cxx b/sw/source/core/layout/wsfrm.cxx index 6ab254e..73ca1dd 100644 --- a/sw/source/core/layout/wsfrm.cxx +++ b/sw/source/core/layout/wsfrm.cxx @@ -332,9 +332,10 @@ void SwFrm::_UpdateAttrFrm( const SfxPoolItem *pOld, const SfxPoolItem *pNew, } } -void SwFrm::Prepare( const PrepareHint, const void *, bool ) +bool SwFrm::Prepare( const PrepareHint, const void *, bool ) { /* Do nothing */ + return false; } /** diff --git a/sw/source/core/text/txtfrm.cxx b/sw/source/core/text/txtfrm.cxx index 4ce9409..bc3e656 100644 --- a/sw/source/core/text/txtfrm.cxx +++ b/sw/source/core/text/txtfrm.cxx @@ -1447,9 +1447,11 @@ static bool lcl_ErgoVadis( SwTextFrm* pFrm, sal_Int32 &rPos, const PrepareHint e return true; } -void SwTextFrm::Prepare( const PrepareHint ePrep, const void* pVoid, +bool SwTextFrm::Prepare( const PrepareHint ePrep, const void* pVoid, bool bNotify ) { + bool bParaPossiblyInvalid = false; + SwFrmSwapper aSwapper( this, false ); #if OSL_DEBUG_LEVEL > 1 @@ -1465,7 +1467,7 @@ void SwTextFrm::Prepare( const PrepareHint ePrep, const void* pVoid, SetInvalidVert( true ); // Test case PREP_WIDOWS_ORPHANS: case PREP_WIDOWS: - case PREP_FTN_GONE : return; + case PREP_FTN_GONE : return bParaPossiblyInvalid; case PREP_POS_CHGD : { @@ -1497,7 +1499,7 @@ void SwTextFrm::Prepare( const PrepareHint ePrep, const void* pVoid, if ( GetDrawObjs() ) break; - return; + return bParaPossiblyInvalid; } default: break; @@ -1512,7 +1514,7 @@ void SwTextFrm::Prepare( const PrepareHint ePrep, const void* pVoid, InvalidateSize(); else _InvalidateSize(); - return; + return bParaPossiblyInvalid; } // Get object from cache while locking @@ -1543,7 +1545,7 @@ void SwTextFrm::Prepare( const PrepareHint ePrep, const void* pVoid, case PREP_WIDOWS : // MustFit is stronger than anything else if( pPara->IsPrepMustFit() ) - return; + return bParaPossiblyInvalid; // see comment in WidowsAndOrphans::FindOrphans and CalcPreps() PrepWidows( *static_cast<const sal_uInt16 *>(pVoid), bNotify ); break; @@ -1709,17 +1711,23 @@ void SwTextFrm::Prepare( const PrepareHint ePrep, const void* pVoid, else { if( GetTextNode()->GetSwAttrSet().GetRegister().GetValue() ) - Prepare( PREP_REGISTER, 0, bNotify ); - + bParaPossiblyInvalid = Prepare( PREP_REGISTER, 0, bNotify ); // The Frames need to be readjusted, which caused by changes // in position else if( HasFootnote() ) { - Prepare( PREP_ADJUST_FRM, 0, bNotify ); + bParaPossiblyInvalid = Prepare( PREP_ADJUST_FRM, 0, bNotify ); _InvalidateSize(); } else - return; // So that there's no SetPrep() + return bParaPossiblyInvalid; // So that there's no SetPrep() + + if (bParaPossiblyInvalid) + { + // It's possible that pPara was deleted above; retrieve it again + pPara = aAccess.GetPara(); + } + } break; } @@ -1730,7 +1738,9 @@ void SwTextFrm::Prepare( const PrepareHint ePrep, const void* pVoid, CalcLineSpace(); // It's possible that pPara was deleted above; retrieve it again + bParaPossiblyInvalid = true; pPara = aAccess.GetPara(); + InvalidateSize(); _InvalidatePrt(); SwFrm* pNxt; @@ -1756,7 +1766,7 @@ void SwTextFrm::Prepare( const PrepareHint ePrep, const void* pVoid, if( nPos ) --nPos; // The char preceding our Follow InvalidateRange( SwCharRange( nPos, 1 ), 0 ); - return; + return bParaPossiblyInvalid; } case PREP_ERGOSUM: case PREP_QUOVADIS: @@ -1773,7 +1783,7 @@ void SwTextFrm::Prepare( const PrepareHint ePrep, const void* pVoid, sal_Int32 nWhere = CalcFlyPos( const_cast<SwFrameFormat *>(static_cast<SwFrameFormat const *>(pVoid)) ); OSL_ENSURE( COMPLETE_STRING != nWhere, "Prepare: Why me?" ); InvalidateRange( SwCharRange( nWhere, 1 ) ); - return; + return bParaPossiblyInvalid; } // else: continue with default case block } @@ -1802,11 +1812,15 @@ void SwTextFrm::Prepare( const PrepareHint ePrep, const void* pVoid, else _InvalidateSize(); } - return; // no SetPrep() happened + return bParaPossiblyInvalid; // no SetPrep() happened } } if( pPara ) + { pPara->SetPrep(); + } + + return bParaPossiblyInvalid; } /**
_______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits