diff options
author | Michael Stahl <mstahl@redhat.com> | 2017-06-21 15:26:01 +0200 |
---|---|---|
committer | Michael Stahl <mstahl@redhat.com> | 2017-06-22 09:53:06 +0200 |
commit | c83a443eb106e426901d0ba8a809eedcd24c42c5 (patch) | |
tree | 1e9727430d63607f2797a3aeb9b3ccaf1b405445 /sw | |
parent | 9dcb767c5bdccdf6606240afd6aa2c6bd3dcc9f4 (diff) |
tdf#101821 sw: fix another layout footnote use-after-free
In SwContentFrame::MakeAll() the pPre (previous frame) is deleted in a
call to MoveFwd(). This SwTextFrame is inside of a footnote, and
the SwFlowFrame::CutTree() for whatever reason wants to format all
of the SwTextFrames inside the same SwFootnoteFrame, which causes
the pPre to be joined with another one.
Let's try to avoid that by checking that it's still in the layout after
the call to MoveFwd(); on the one hand it's not obvious that this frame
is important enough that it should be kept alive with ForbidDelete(),
on the other hand i have no idea if simply removing the ValidateSz()
call would introduce new loops or whatever.
Invalid read of size 4
at 0x414E8D14: SwFrame::IsSctFrame() const (frame.hxx:1018)
by 0x41A85A29: SwContentFrame::MakeAll(OutputDevice*) (calcmove.cxx:1713)
by 0x41A7F499: SwFrame::OptPrepareMake() (calcmove.cxx:368)
by 0x41ADF0CF: SwFrame::OptCalc() const (frame.hxx:892)
by 0x41ADCC07: SwLayAction::FormatContent_(SwContentFrame const*, SwPageFrame const*) (layact.cxx:1789)
by 0x41ADC195: SwLayAction::FormatContent(SwPageFrame const*) (layact.cxx:1620)
by 0x41AD88DE: SwLayAction::InternalAction(OutputDevice*) (layact.cxx:760)
by 0x41AD7080: SwLayAction::Action(OutputDevice*) (layact.cxx:351)
by 0x41ADE32E: SwLayIdle::SwLayIdle(SwRootFrame*, SwViewShellImp*) (layact.cxx:2133)
by 0x41FFC97E: SwViewShell::LayoutIdle() (viewsh.cxx:711)
Address 0x530ccf80 is 160 bytes inside a block of size 264 free'd
at 0x4C2ED4A: free (vg_replace_malloc.c:530)
by 0x4E5BCD0: rtl_freeMemory_SYSTEM(void*) (alloc_global.cxx:271)
by 0x4E5C00A: rtl_freeMemory (alloc_global.cxx:341)
by 0x4E5AAA0: rtl_cache_free (alloc_cache.cxx:1231)
by 0xEFC9A6F: FixedMemPool::Free(void*) (mempool.cxx:49)
by 0x41CA7DFA: SwTextFrame::operator delete(void*, unsigned long) (txtfrm.hxx:377)
by 0x41C9F7B6: SwTextFrame::~SwTextFrame() (txtfrm.cxx:415)
by 0x41B5B74C: SwFrame::DestroyFrame(SwFrame*) (ssfrm.cxx:391)
by 0x41C1589A: SwTextFrame::JoinFrame() (frmform.cxx:656)
by 0x41C153B1: SwTextFrame::AdjustFollow_(SwTextFormatter&, int, int, unsigned char) (frmform.cxx:555)
by 0x41C172E1: SwTextFrame::FormatAdjust(SwTextFormatter&, WidowsAndOrphans&, int, bool) (frmform.cxx:1108)
by 0x41C18D5E: SwTextFrame::Format_(SwTextFormatter&, SwTextFormatInfo&, bool) (frmform.cxx:1550)
by 0x41C19340: SwTextFrame::Format_(OutputDevice*, SwParaPortion*) (frmform.cxx:1660)
by 0x41C19CD8: SwTextFrame::Format(OutputDevice*, SwBorderAttrs const*) (frmform.cxx:1807)
by 0x41A847A1: SwContentFrame::MakeAll(OutputDevice*) (calcmove.cxx:1393)
by 0x41A7F211: SwFrame::PrepareMake(OutputDevice*) (calcmove.cxx:346)
by 0x41B75758: SwFrame::Calc(OutputDevice*) const (trvlfrm.cxx:1761)
by 0x41A973E7: SwFlowFrame::CutTree(SwFrame*) (flowfrm.cxx:424)
by 0x41A979AE: SwFlowFrame::MoveSubTree(SwLayoutFrame*, SwFrame*) (flowfrm.cxx:592)
by 0x41ACFB69: SwContentFrame::MoveFootnoteCntFwd(bool, SwFootnoteBossFrame*) (ftnfrm.cxx:2756)
by 0x41A9B78E: SwFlowFrame::MoveFwd(bool, bool, bool) (flowfrm.cxx:1813)
by 0x41A85864: SwContentFrame::MakeAll(OutputDevice*) (calcmove.cxx:1681)
by 0x41A7F499: SwFrame::OptPrepareMake() (calcmove.cxx:368)
by 0x41ADF0CF: SwFrame::OptCalc() const (frame.hxx:892)
by 0x41ADCC07: SwLayAction::FormatContent_(SwContentFrame const*, SwPageFrame const*) (layact.cxx:1789)
by 0x41ADC195: SwLayAction::FormatContent(SwPageFrame const*) (layact.cxx:1620)
by 0x41AD88DE: SwLayAction::InternalAction(OutputDevice*) (layact.cxx:760)
by 0x41AD7080: SwLayAction::Action(OutputDevice*) (layact.cxx:351)
by 0x41ADE32E: SwLayIdle::SwLayIdle(SwRootFrame*, SwViewShellImp*) (layact.cxx:2133)
by 0x41FFC97E: SwViewShell::LayoutIdle() (viewsh.cxx:711)
Change-Id: I35b27a32608d4dcf98e0933cce76ce5ddb1c09d9
Diffstat (limited to 'sw')
-rw-r--r-- | sw/source/core/layout/calcmove.cxx | 20 |
1 files changed, 20 insertions, 0 deletions
diff --git a/sw/source/core/layout/calcmove.cxx b/sw/source/core/layout/calcmove.cxx index 56886e4a95c7..2fdbb6b4f62f 100644 --- a/sw/source/core/layout/calcmove.cxx +++ b/sw/source/core/layout/calcmove.cxx @@ -1681,6 +1681,26 @@ void SwContentFrame::MakeAll(vcl::RenderContext* /*pRenderContext*/) if ( !bMovedFwd && !MoveFwd( bMakePage, false ) ) bMakePage = false; aRectFnSet.Refresh(this); + if (!bMovedFwd && bFootnote && GetIndPrev() != pPre) + { // SwFlowFrame::CutTree() could have formatted and deleted pPre + auto const pPrevFootnoteFrame(static_cast<SwFootnoteFrame const*>(GetUpper())->GetMaster()); + bool bReset = true; + if (pPrevFootnoteFrame) + { // use GetIndNext() in case there are sections + for (auto p = pPrevFootnoteFrame->Lower(); p; p = p->GetIndNext()) + { + if (p == pPre) + { + bReset = false; + break; + } + } + } + if (bReset) + { + pPre = nullptr; + } + } // If MoveFwd moves the paragraph to the next page, a following // paragraph, which contains footnotes can cause the old upper |