diff options
author | Michael Stahl <mstahl@redhat.com> | 2017-04-03 14:28:56 +0200 |
---|---|---|
committer | Andras Timar <andras.timar@collabora.com> | 2017-04-07 07:53:08 +0200 |
commit | 5ec306f3fb4b8965c4aa0aa14ec09a135471571e (patch) | |
tree | 175983f8713362175ec2413c5690b45a6fd7f49e /sw | |
parent | ef7a181168e7f4e6a65d39f70dd16fb5ed11c5f2 (diff) |
tdf#106237 sw: do some basic sanity checking on layout-cache
The bugdoc, with claimed generator AOO4.1.1 on Windows, contains
a bogus layout-cache:
debug:26706:1: nType P nIndex 29 2147483647
debug:26706:1: nType P nIndex 66 2147483647
debug:26706:1: nType P nIndex 105 2147483647
debug:26706:1: nType P nIndex 142 2147483647
debug:26706:1: nType P nIndex 178 2147483647
debug:26706:1: nType P nIndex 205 2147483647
debug:26706:1: nType P nIndex 229 2147483647
debug:26706:1: nType T nIndex 314 65535
Due to a loop-control this causes incorrect pagination if CalcLayout()
is called only once.
It should look like this:
debug:26765:1: nType T nIndex 382 65535
debug:26765:1: nType T nIndex 790 65535
In this case we can easily detect that the indexes and types in
the layout-cache are bogus by checking against the node types, so
do that in SwLayHelper::SwLayHelper().
(cherry picked from commit 8a5374f2fdbd1e15c107133f55930cbc431edbd5)
sw: [loplugin:sallogareas]
(cherry picked from commit 282b3e8c4d45aacae57e3542b872cdbfebcc7195)
loplugin:loopvartoosmall
(cherry picked from commit dbaab58c1442e7f62ef0732376fe5a49840e9fd6)
Change-Id: I7091af49a8c29bf0a11ceff0be9ba84b1f710fdb
Reviewed-on: https://gerrit.libreoffice.org/36046
Tested-by: Jenkins <ci@libreoffice.org>
Reviewed-by: Miklos Vajna <vmiklos@collabora.co.uk>
(cherry picked from commit 137ad218db262fb3531215adbc88b7093b4999c7)
Diffstat (limited to 'sw')
-rw-r--r-- | sw/source/core/layout/laycache.cxx | 61 | ||||
-rw-r--r-- | sw/source/core/layout/layhelp.hxx | 4 |
2 files changed, 55 insertions, 10 deletions
diff --git a/sw/source/core/layout/laycache.cxx b/sw/source/core/layout/laycache.cxx index 8a5beb52f327..5d3cbafb0d35 100644 --- a/sw/source/core/layout/laycache.cxx +++ b/sw/source/core/layout/laycache.cxx @@ -454,6 +454,51 @@ SwActualSection::SwActualSection( SwActualSection *pUp, } } +namespace { + +bool sanityCheckLayoutCache(SwLayCacheImpl const& rCache, + SwNodes const& rNodes, sal_uLong nNodeIndex) +{ + auto const nStartOfContent(rNodes.GetEndOfContent().StartOfSectionNode()->GetIndex()); + nNodeIndex -= nStartOfContent; + auto const nMaxIndex(rNodes.GetEndOfContent().GetIndex() - nStartOfContent); + for (size_t nIndex = 0; nIndex < rCache.size(); ++nIndex) + { + auto const nBreakIndex(rCache.GetBreakIndex(nIndex)); + if (nBreakIndex < nNodeIndex || nMaxIndex <= nBreakIndex) + { + SAL_WARN("sw.layout", + "invalid node index in layout-cache: " << nBreakIndex); + return false; + } + auto const nBreakType(rCache.GetBreakType(nIndex)); + switch (nBreakType) + { + case SW_LAYCACHE_IO_REC_PARA: + if (!rNodes[nBreakIndex + nStartOfContent]->IsTextNode()) + { + SAL_WARN("sw.layout", + "invalid node of type 'P' in layout-cache"); + return false; + } + break; + case SW_LAYCACHE_IO_REC_TABLE: + if (!rNodes[nBreakIndex + nStartOfContent]->IsTableNode()) + { + SAL_WARN("sw.layout", + "invalid node of type 'T' in layout-cache"); + return false; + } + break; + default: + assert(false); // Read shouldn't have inserted that + } + } + return true; +} + +} // namespace + /** helper class, which utilizes the layout cache information * to distribute the document content to the right pages. * It's used by the InsertCnt_(..)-function. @@ -478,19 +523,19 @@ SwLayHelper::SwLayHelper( SwDoc *pD, SwFrame* &rpF, SwFrame* &rpP, SwPageFrame* pImpl = pDoc->GetLayoutCache() ? pDoc->GetLayoutCache()->LockImpl() : nullptr; if( pImpl ) { - nMaxParaPerPage = 1000; - nStartOfContent = pDoc->GetNodes().GetEndOfContent().StartOfSectionNode() - ->GetIndex(); - nNodeIndex -= nStartOfContent; - nIndex = 0; - while( nIndex < pImpl->size() && pImpl->GetBreakIndex( nIndex ) < nNodeIndex ) + SwNodes const& rNodes(pDoc->GetNodes()); + if (sanityCheckLayoutCache(*pImpl, rNodes, nNodeIndex)) { - ++nIndex; + nIndex = 0; + nStartOfContent = rNodes.GetEndOfContent().StartOfSectionNode()->GetIndex(); + nMaxParaPerPage = 1000; } - if( nIndex >= pImpl->size() ) + else { pDoc->GetLayoutCache()->UnlockImpl(); pImpl = nullptr; + nIndex = USHRT_MAX; + nStartOfContent = USHRT_MAX; } } else diff --git a/sw/source/core/layout/layhelp.hxx b/sw/source/core/layout/layhelp.hxx index 57c747b4c0d1..3da3a10bce10 100644 --- a/sw/source/core/layout/layhelp.hxx +++ b/sw/source/core/layout/layhelp.hxx @@ -66,9 +66,9 @@ public: bool Read( SvStream& rStream ); - sal_uLong GetBreakIndex( sal_uInt16 nIdx ) const { return mIndices[ nIdx ]; } + sal_uLong GetBreakIndex( size_t nIdx ) const { return mIndices[ nIdx ]; } sal_Int32 GetBreakOfst( size_t nIdx ) const { return aOffset[ nIdx ]; } - sal_uInt16 GetBreakType( sal_uInt16 nIdx ) const { return aType[ nIdx ]; } + sal_uInt16 GetBreakType( size_t nIdx ) const { return aType[ nIdx ]; } size_t GetFlyCount() const { return m_FlyCache.size(); } SwFlyCache& GetFlyCache( size_t nIdx ) { return m_FlyCache[ nIdx ]; } |