summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Stahl <Michael.Stahl@cib.de>2020-11-16 13:08:48 +0100
committerMiklos Vajna <vmiklos@collabora.com>2021-10-08 15:03:02 +0200
commita543433c730eac8f91b49c6a7993ae26e67d309b (patch)
treeda38c47b7a93c7a676f9ecabfc635bb63b2f4d24
parentf6405603547435442ad4b11a37c8cdc68b063f3e (diff)
(related tdf#134298) sw: layout: avoid infinite loop in InternalAction()
The condition IsInterrupt() && pPage && (m_nCheckPageNum != USHRT_MAX) isn't handled properly and the while loop will never terminate with the fix for tdf#134298 in several UITest_writer_tests*. If m_nCheckPageNum is set, then it must result in a call to CheckPageDescs() here; it's a member of SwLayAction so won't survive until the next idle layout invocation. There is a funny history of these loop conditions with commit 9eff9e699e17cc5a8a25895bd28dc8e4ceb8071e and cee296066ab780217395201ab84c2150c8840d25 so we can only hope this time we got it right... (cherry picked from commit 094ee3955ee81e1bc631d50cc216cbb17a777839) Change-Id: I91b63540bf4280296d747cb8e841594f8dd3b140
-rw-r--r--sw/source/core/layout/layact.cxx20
1 files changed, 12 insertions, 8 deletions
diff --git a/sw/source/core/layout/layact.cxx b/sw/source/core/layout/layact.cxx
index 7f913c8a02ff..d3dd8b62027d 100644
--- a/sw/source/core/layout/layact.cxx
+++ b/sw/source/core/layout/layact.cxx
@@ -447,15 +447,19 @@ void SwLayAction::InternalAction(OutputDevice* pRenderContext)
sal_uInt16 nPercentPageNum = 0;
while ((!IsInterrupt() && pPage) || (m_nCheckPageNum != USHRT_MAX))
{
- if (!pPage && m_nCheckPageNum != USHRT_MAX)
+ // note: this is the only place that consumes and resets m_nCheckPageNum
+ if ((IsInterrupt() || !pPage) && m_nCheckPageNum != USHRT_MAX)
{
- SwPageFrame *pPg = static_cast<SwPageFrame*>(m_pRoot->Lower());
- while (pPg && pPg->GetPhyPageNum() < m_nCheckPageNum)
- pPg = static_cast<SwPageFrame*>(pPg->GetNext());
- if (pPg)
- pPage = pPg;
- if (!pPage)
- break;
+ if (!pPage || m_nCheckPageNum < pPage->GetPhyPageNum())
+ {
+ SwPageFrame *pPg = static_cast<SwPageFrame*>(m_pRoot->Lower());
+ while (pPg && pPg->GetPhyPageNum() < m_nCheckPageNum)
+ pPg = static_cast<SwPageFrame*>(pPg->GetNext());
+ if (pPg)
+ pPage = pPg;
+ if (!pPage)
+ break;
+ }
SwPageFrame *pTmp = pPage->GetPrev() ?
static_cast<SwPageFrame*>(pPage->GetPrev()) : pPage;