summaryrefslogtreecommitdiff
path: root/sw
diff options
context:
space:
mode:
authorCaolán McNamara <caolanm@redhat.com>2015-05-29 15:25:27 +0100
committerCaolán McNamara <caolanm@redhat.com>2015-05-29 15:41:59 +0100
commit48495a7135d74dbf7ef19f868d6b76a725f36a96 (patch)
tree4520fac48057831907139fee4f0c3217669257a1 /sw
parenta44e8241d65866373ae43dbcf0bbea2eebf12163 (diff)
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)
Diffstat (limited to 'sw')
-rw-r--r--sw/source/core/inc/frame.hxx2
-rw-r--r--sw/source/core/inc/tabfrm.hxx2
-rw-r--r--sw/source/core/inc/txtfrm.hxx5
-rw-r--r--sw/source/core/layout/tabfrm.cxx3
-rw-r--r--sw/source/core/layout/wsfrm.cxx3
-rw-r--r--sw/source/core/text/txtfrm.cxx38
6 files changed, 36 insertions, 17 deletions
diff --git a/sw/source/core/inc/frame.hxx b/sw/source/core/inc/frame.hxx
index 0a23c88acc24..8d283f59e23a 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 3b418cf7f18b..c78872bc553a 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 2d1418c49966..63ce3b938303 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 879bdff06afd..1fd119c59bab 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 6ab254e6b9aa..73ca1dd29ed8 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 4ce9409198d7..bc3e656bb4cd 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;
}
/**