summaryrefslogtreecommitdiff
path: root/sw
diff options
context:
space:
mode:
authorMichael Stahl <mstahl@redhat.com>2017-04-03 14:28:56 +0200
committerAndras Timar <andras.timar@collabora.com>2017-04-07 07:53:08 +0200
commit5ec306f3fb4b8965c4aa0aa14ec09a135471571e (patch)
tree175983f8713362175ec2413c5690b45a6fd7f49e /sw
parentef7a181168e7f4e6a65d39f70dd16fb5ed11c5f2 (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.cxx61
-rw-r--r--sw/source/core/layout/layhelp.hxx4
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 ]; }