[Libreoffice-commits] core.git: Branch 'libreoffice-5-3' - include/sal sw/source

Michael Stahl mstahl at redhat.com
Wed Apr 5 14:59:17 UTC 2017


 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 <mstahl at redhat.com>
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 <ci at libreoffice.org>
    Reviewed-by: Miklos Vajna <vmiklos at collabora.co.uk>

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
+ at 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 ]; }


More information about the Libreoffice-commits mailing list