[Libreoffice-commits] libvisio.git: 4 commits - src/lib

David Tardon dtardon at redhat.com
Thu Jul 16 10:34:01 PDT 2015


 src/lib/VSDContentCollector.cpp |   11 ++
 src/lib/VSDStyles.cpp           |  153 ++++++++++++----------------------------
 src/lib/VSDStylesCollector.cpp  |    5 +
 3 files changed, 61 insertions(+), 108 deletions(-)

New commits:
commit 1c71f0a300b012cca709662823e9cbfa85fb7b36
Author: David Tardon <dtardon at redhat.com>
Date:   Thu Jul 16 18:59:23 2015 +0200

    avoid endless loop when reading broken file
    
    Change-Id: I95ba48b926e51873786255e8933e94def4b04ace

diff --git a/src/lib/VSDContentCollector.cpp b/src/lib/VSDContentCollector.cpp
index 1d98798..8f2759a 100644
--- a/src/lib/VSDContentCollector.cpp
+++ b/src/lib/VSDContentCollector.cpp
@@ -8,6 +8,7 @@
  */
 
 #include <string.h> // for memcpy
+#include <set>
 #include <stack>
 #include <boost/spirit/include/classic.hpp>
 #include <unicode/ucnv.h>
@@ -1771,6 +1772,9 @@ void libvisio::VSDContentCollector::transformPoint(double &x, double &y, XForm *
 
   unsigned shapeId = m_currentShapeId;
 
+  std::set<unsigned> visitedShapes; // avoid mutually nested shapes in broken files
+  visitedShapes.insert(shapeId);
+
   if (txtxform)
     applyXForm(x, y, *txtxform);
 
@@ -1791,7 +1795,7 @@ void libvisio::VSDContentCollector::transformPoint(double &x, double &y, XForm *
       if (iter != m_groupMemberships->end() && shapeId != iter->second)
       {
         shapeId = iter->second;
-        shapeFound = true;
+        shapeFound = visitedShapes.insert(shapeId).second;
       }
     }
     if (!shapeFound)
@@ -1828,6 +1832,9 @@ void libvisio::VSDContentCollector::transformFlips(bool &flipX, bool &flipY)
 
   unsigned shapeId = m_currentShapeId;
 
+  std::set<unsigned> visitedShapes; // avoid mutually nested shapes in broken files
+  visitedShapes.insert(shapeId);
+
   while (true && m_groupXForms)
   {
     std::map<unsigned, XForm>::iterator iterX = m_groupXForms->find(shapeId);
@@ -1848,7 +1855,7 @@ void libvisio::VSDContentCollector::transformFlips(bool &flipX, bool &flipY)
       if (iter != m_groupMemberships->end() && shapeId != iter->second)
       {
         shapeId = iter->second;
-        shapeFound = true;
+        shapeFound = visitedShapes.insert(shapeId).second;
       }
     }
     if (!shapeFound)
commit 03eed259ce331998af623cf5da5320441ed55d1f
Author: David Tardon <dtardon at redhat.com>
Date:   Thu Jul 16 18:43:34 2015 +0200

    avoid endless loop when reading broken file
    
    Change-Id: I4956a3438d273a06a11d96031e2759062dce1e95

diff --git a/src/lib/VSDStyles.cpp b/src/lib/VSDStyles.cpp
index ff29267..f8fd33d 100644
--- a/src/lib/VSDStyles.cpp
+++ b/src/lib/VSDStyles.cpp
@@ -7,6 +7,7 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  */
 
+#include <set>
 #include <stack>
 #include "VSDStyles.h"
 #include "VSDTypes.h"
@@ -24,12 +25,18 @@ T getOptionalStyle(const std::map<unsigned, unsigned> &styleMasters, const std::
   if (MINUS_ONE == styleIndex)
     return style;
   std::stack<unsigned> styleIdStack;
+  std::set<unsigned> foundStyles;
   styleIdStack.push(styleIndex);
   while (true)
   {
     std::map<unsigned, unsigned>::const_iterator iter = styleMasters.find(styleIdStack.top());
     if (iter != styleMasters.end() && iter->second != MINUS_ONE)
-      styleIdStack.push(iter->second);
+    {
+      if (foundStyles.insert(iter->second).second)
+        styleIdStack.push(iter->second);
+      else // we already have this style -> stop incoming endless loop
+        break;
+    }
     else
       break;
   }
commit 4a2e82ddca257374ab04c7bbbc1869e666a2d6b9
Author: David Tardon <dtardon at redhat.com>
Date:   Thu Jul 16 16:56:00 2015 +0200

    avoid copypasta
    
    Change-Id: I5f7dc4912aebd763da27984fcd5644a9419901bf

diff --git a/src/lib/VSDStyles.cpp b/src/lib/VSDStyles.cpp
index 8280ae4..ff29267 100644
--- a/src/lib/VSDStyles.cpp
+++ b/src/lib/VSDStyles.cpp
@@ -11,6 +11,42 @@
 #include "VSDStyles.h"
 #include "VSDTypes.h"
 
+namespace libvisio
+{
+
+namespace
+{
+
+template<typename T>
+T getOptionalStyle(const std::map<unsigned, unsigned> &styleMasters, const std::map<unsigned, T> &styles, const unsigned styleIndex)
+{
+  T style;
+  if (MINUS_ONE == styleIndex)
+    return style;
+  std::stack<unsigned> styleIdStack;
+  styleIdStack.push(styleIndex);
+  while (true)
+  {
+    std::map<unsigned, unsigned>::const_iterator iter = styleMasters.find(styleIdStack.top());
+    if (iter != styleMasters.end() && iter->second != MINUS_ONE)
+      styleIdStack.push(iter->second);
+    else
+      break;
+  }
+  while (!styleIdStack.empty())
+  {
+    typename std::map<unsigned, T>::const_iterator iter = styles.find(styleIdStack.top());
+    if (iter != styles.end())
+      style.override(iter->second);
+    styleIdStack.pop();
+  }
+  return style;
+}
+
+}
+
+}
+
 libvisio::VSDStyles::VSDStyles() :
   m_lineStyles(), m_fillStyles(), m_textBlockStyles(), m_charStyles(), m_paraStyles(),
   m_themeRefs(), m_lineStyleMasters(), m_fillStyleMasters(), m_textStyleMasters()
@@ -94,52 +130,12 @@ void libvisio::VSDStyles::addTextStyleMaster(unsigned textStyleIndex, unsigned t
 
 libvisio::VSDOptionalLineStyle libvisio::VSDStyles::getOptionalLineStyle(unsigned lineStyleIndex) const
 {
-  VSDOptionalLineStyle lineStyle;
-  if (MINUS_ONE == lineStyleIndex)
-    return lineStyle;
-  std::stack<unsigned> styleIdStack;
-  styleIdStack.push(lineStyleIndex);
-  while (true)
-  {
-    std::map<unsigned, unsigned>::const_iterator iter = m_lineStyleMasters.find(styleIdStack.top());
-    if (iter != m_lineStyleMasters.end() && iter->second != MINUS_ONE)
-      styleIdStack.push(iter->second);
-    else
-      break;
-  }
-  while (!styleIdStack.empty())
-  {
-    std::map<unsigned, VSDOptionalLineStyle>::const_iterator iter = m_lineStyles.find(styleIdStack.top());
-    if (iter != m_lineStyles.end())
-      lineStyle.override(iter->second);
-    styleIdStack.pop();
-  }
-  return lineStyle;
+  return getOptionalStyle(m_lineStyleMasters, m_lineStyles, lineStyleIndex);
 }
 
 libvisio::VSDOptionalFillStyle libvisio::VSDStyles::getOptionalFillStyle(unsigned fillStyleIndex) const
 {
-  VSDOptionalFillStyle fillStyle;
-  if (MINUS_ONE == fillStyleIndex)
-    return fillStyle;
-  std::stack<unsigned> styleIdStack;
-  styleIdStack.push(fillStyleIndex);
-  while (true)
-  {
-    std::map<unsigned, unsigned>::const_iterator iter = m_fillStyleMasters.find(styleIdStack.top());
-    if (iter != m_fillStyleMasters.end() && iter->second != MINUS_ONE)
-      styleIdStack.push(iter->second);
-    else
-      break;
-  }
-  while (!styleIdStack.empty())
-  {
-    std::map<unsigned, VSDOptionalFillStyle>::const_iterator iter = m_fillStyles.find(styleIdStack.top());
-    if (iter != m_fillStyles.end())
-      fillStyle.override(iter->second);
-    styleIdStack.pop();
-  }
-  return fillStyle;
+  return getOptionalStyle(m_fillStyleMasters, m_fillStyles, fillStyleIndex);
 }
 
 libvisio::VSDFillStyle libvisio::VSDStyles::getFillStyle(unsigned fillStyleIndex) const
@@ -151,77 +147,17 @@ libvisio::VSDFillStyle libvisio::VSDStyles::getFillStyle(unsigned fillStyleIndex
 
 libvisio::VSDOptionalTextBlockStyle libvisio::VSDStyles::getOptionalTextBlockStyle(unsigned textStyleIndex) const
 {
-  VSDOptionalTextBlockStyle textBlockStyle;
-  if (MINUS_ONE == textStyleIndex)
-    return textBlockStyle;
-  std::stack<unsigned> styleIdStack;
-  styleIdStack.push(textStyleIndex);
-  while (true)
-  {
-    std::map<unsigned, unsigned>::const_iterator iter = m_textStyleMasters.find(styleIdStack.top());
-    if (iter != m_textStyleMasters.end() && iter->second != MINUS_ONE)
-      styleIdStack.push(iter->second);
-    else
-      break;
-  }
-  while (!styleIdStack.empty())
-  {
-    std::map<unsigned, VSDOptionalTextBlockStyle>::const_iterator iter = m_textBlockStyles.find(styleIdStack.top());
-    if (iter != m_textBlockStyles.end())
-      textBlockStyle.override(iter->second);
-    styleIdStack.pop();
-  }
-  return textBlockStyle;
+  return getOptionalStyle(m_textStyleMasters, m_textBlockStyles, textStyleIndex);
 }
 
 libvisio::VSDOptionalCharStyle libvisio::VSDStyles::getOptionalCharStyle(unsigned textStyleIndex) const
 {
-  VSDOptionalCharStyle charStyle;
-  if (MINUS_ONE == textStyleIndex)
-    return charStyle;
-  std::stack<unsigned> styleIdStack;
-  styleIdStack.push(textStyleIndex);
-  while (true)
-  {
-    std::map<unsigned, unsigned>::const_iterator iter = m_textStyleMasters.find(styleIdStack.top());
-    if (iter != m_textStyleMasters.end() && iter->second != MINUS_ONE)
-      styleIdStack.push(iter->second);
-    else
-      break;
-  }
-  while (!styleIdStack.empty())
-  {
-    std::map<unsigned, VSDOptionalCharStyle>::const_iterator iter = m_charStyles.find(styleIdStack.top());
-    if (iter != m_charStyles.end())
-      charStyle.override(iter->second);
-    styleIdStack.pop();
-  }
-  return charStyle;
+  return getOptionalStyle(m_textStyleMasters, m_charStyles, textStyleIndex);
 }
 
 libvisio::VSDOptionalParaStyle libvisio::VSDStyles::getOptionalParaStyle(unsigned textStyleIndex) const
 {
-  VSDOptionalParaStyle paraStyle;
-  if (MINUS_ONE == textStyleIndex)
-    return paraStyle;
-  std::stack<unsigned> styleIdStack;
-  styleIdStack.push(textStyleIndex);
-  while (true)
-  {
-    std::map<unsigned, unsigned>::const_iterator iter = m_textStyleMasters.find(styleIdStack.top());
-    if (iter != m_textStyleMasters.end() && iter->second != MINUS_ONE)
-      styleIdStack.push(iter->second);
-    else
-      break;
-  }
-  while (!styleIdStack.empty())
-  {
-    std::map<unsigned, VSDOptionalParaStyle>::const_iterator iter = m_paraStyles.find(styleIdStack.top());
-    if (iter != m_paraStyles.end())
-      paraStyle.override(iter->second);
-    styleIdStack.pop();
-  }
-  return paraStyle;
+  return getOptionalStyle(m_textStyleMasters, m_paraStyles, textStyleIndex);
 }
 
 libvisio::VSDOptionalThemeReference libvisio::VSDStyles::getOptionalThemeReference(unsigned styleIndex) const
commit 730f1e72686b9101c380d90bbbf521c1ec53c532
Author: David Tardon <dtardon at redhat.com>
Date:   Thu Jul 16 16:17:43 2015 +0200

    avoid endless loop when reading broken file
    
    Change-Id: I512d48b5ea25d3784f5b63725d4ff3b8ad648ccc

diff --git a/src/lib/VSDStylesCollector.cpp b/src/lib/VSDStylesCollector.cpp
index 4fc82f6..12e3643 100644
--- a/src/lib/VSDStylesCollector.cpp
+++ b/src/lib/VSDStylesCollector.cpp
@@ -402,8 +402,10 @@ void libvisio::VSDStylesCollector::endPage()
   m_groupXFormsSequence.push_back(m_groupXForms);
   m_groupMembershipsSequence.push_back(m_groupMemberships);
 
-  while (!m_groupShapeOrder.empty())
+  bool changed = true;
+  while (!m_groupShapeOrder.empty() && changed)
   {
+    changed = false;
     for (std::list<unsigned>::iterator j = m_pageShapeOrder.begin(); j != m_pageShapeOrder.end();)
     {
       std::map<unsigned, std::list<unsigned> >::iterator iter = m_groupShapeOrder.find(*j++);
@@ -411,6 +413,7 @@ void libvisio::VSDStylesCollector::endPage()
       {
         m_pageShapeOrder.splice(j, iter->second, iter->second.begin(), iter->second.end());
         m_groupShapeOrder.erase(iter);
+        changed = true;
       }
     }
   }


More information about the Libreoffice-commits mailing list