include/sal/log-areas.dox | 1 sw/source/core/layout/laycache.cxx | 61 ++++++++++++++++++++++++++++++++----- sw/source/core/layout/layhelp.hxx | 4 +- 3 files changed, 56 insertions(+), 10 deletions(-)
New commits: commit 137ad218db262fb3531215adbc88b7093b4999c7 Author: Michael Stahl <[email protected]> Date: Mon Apr 3 14:28:56 2017 +0200 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 <[email protected]> Reviewed-by: Miklos Vajna <[email protected]> diff --git a/include/sal/log-areas.dox b/include/sal/log-areas.dox index c5cdc3c188db..2ce662a6cca5 100644 --- a/include/sal/log-areas.dox +++ b/include/sal/log-areas.dox @@ -464,6 +464,7 @@ certain functionality. @li @c sw @li @c sw.a11y - accessibility @li @c sw.core - Writer core +@li @c sw.layout - Writer core view: document layout @li @c sw.createcopy @li @c sw.doc @li @c sw.docappend 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 ]; } _______________________________________________ Libreoffice-commits mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
