[Libreoffice-commits] core.git: sw/source
Caolán McNamara
caolanm at redhat.com
Fri May 29 07:28:31 PDT 2015
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 f703201d35f6e77940f68a21b339f67335b99441
Author: Caolán McNamara <caolanm at 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
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 034b2be..7bfa692 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 477053a..c2f63c1 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 bebe456..07e45f9 100644
--- a/sw/source/core/text/txtfrm.cxx
+++ b/sw/source/core/text/txtfrm.cxx
@@ -1441,9 +1441,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
@@ -1459,7 +1461,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 :
{
@@ -1491,7 +1493,7 @@ void SwTextFrm::Prepare( const PrepareHint ePrep, const void* pVoid,
if ( GetDrawObjs() )
break;
- return;
+ return bParaPossiblyInvalid;
}
default:
break;
@@ -1506,7 +1508,7 @@ void SwTextFrm::Prepare( const PrepareHint ePrep, const void* pVoid,
InvalidateSize();
else
_InvalidateSize();
- return;
+ return bParaPossiblyInvalid;
}
// Get object from cache while locking
@@ -1537,7 +1539,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;
@@ -1703,17 +1705,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;
}
@@ -1724,7 +1732,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;
@@ -1750,7 +1760,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:
@@ -1767,7 +1777,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
}
@@ -1796,11 +1806,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;
}
/**
More information about the Libreoffice-commits
mailing list