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

David Tardon dtardon at redhat.com
Sat May 11 23:45:43 PDT 2013


 src/lib/VSDContentCollector.cpp |   48 ++++++++++++++++++++-----------
 src/lib/VSDContentCollector.h   |    4 +-
 src/lib/VSDParser.cpp           |   61 ++++++++++++++++++++++++++--------------
 3 files changed, 74 insertions(+), 39 deletions(-)

New commits:
commit c5780bf9208736870ebfd0e1177b769a15f3f7e0
Author: David Tardon <dtardon at redhat.com>
Date:   Sun May 12 08:36:38 2013 +0200

    don't crash if there is no stencil

diff --git a/src/lib/VSDParser.cpp b/src/lib/VSDParser.cpp
index 4191b27..9fdb8be 100644
--- a/src/lib/VSDParser.cpp
+++ b/src/lib/VSDParser.cpp
@@ -369,7 +369,7 @@ void libvisio::VSDParser::handleStream(const Pointer &ptr, unsigned idx, unsigne
     _handleLevelChange(0);
     if (m_extractStencils)
       m_collector->endPage();
-    else
+    else if (m_currentStencil)
     {
       m_stencils.addStencil(idx, *m_currentStencil);
       m_currentStencil = 0;
@@ -382,7 +382,8 @@ void libvisio::VSDParser::handleStream(const Pointer &ptr, unsigned idx, unsigne
     if (m_isStencilStarted)
     {
       _handleLevelChange(0);
-      m_currentStencil->addStencilShape(m_shape.m_shapeId, m_shape);
+      if (m_currentStencil)
+        m_currentStencil->addStencilShape(m_shape.m_shapeId, m_shape);
     }
     break;
   default:
@@ -1079,7 +1080,7 @@ void libvisio::VSDParser::readPageProps(WPXInputStream *input)
   input->seek(1, WPX_SEEK_CUR);
   scale /= readDouble(input);
 
-  if (m_isStencilStarted)
+  if (m_isStencilStarted && m_currentStencil)
   {
     m_currentStencil->m_shadowOffsetX = m_shadowOffsetX;
     m_currentStencil->m_shadowOffsetY = m_shadowOffsetY;
commit 81663fbb1a705d329305ed7133b2df7a18e9747d
Author: David Tardon <dtardon at redhat.com>
Date:   Sun May 12 08:25:26 2013 +0200

    don't leave dangling pointer around

diff --git a/src/lib/VSDParser.cpp b/src/lib/VSDParser.cpp
index 3b41711..4191b27 100644
--- a/src/lib/VSDParser.cpp
+++ b/src/lib/VSDParser.cpp
@@ -670,6 +670,7 @@ void libvisio::VSDParser::_handleLevelChange(unsigned level)
     {
       _flushShape();
       m_shape.clear();
+      m_currentGeometryList = 0;
     }
     m_isShapeStarted = false;
     m_currentShapeLevel = 0;
@@ -1121,6 +1122,7 @@ void libvisio::VSDParser::readShape(WPXInputStream *input)
   }
 
   m_shape.clear();
+  m_currentGeometryList = 0;
   const VSDShape *tmpShape = m_stencils.getStencilShape(masterPage, masterShape);
   if (tmpShape)
   {
commit e89d34da0d9378f0a71d86cbe38c54575f02b73d
Author: David Tardon <dtardon at redhat.com>
Date:   Sun May 12 08:01:07 2013 +0200

    avoid crash if m_currentGeometryList is null

diff --git a/src/lib/VSDParser.cpp b/src/lib/VSDParser.cpp
index e9c9009..3b41711 100644
--- a/src/lib/VSDParser.cpp
+++ b/src/lib/VSDParser.cpp
@@ -694,7 +694,8 @@ void libvisio::VSDParser::readEllipticalArcTo(WPXInputStream *input)
   input->seek(1, WPX_SEEK_CUR);
   double ecc = readDouble(input); // Eccentricity
 
-  m_currentGeometryList->addEllipticalArcTo(m_header.id, m_header.level, x3, y3, x2, y2, angle, ecc);
+  if (m_currentGeometryList)
+    m_currentGeometryList->addEllipticalArcTo(m_header.id, m_header.level, x3, y3, x2, y2, angle, ecc);
 }
 
 
@@ -783,7 +784,8 @@ void libvisio::VSDParser::readEllipse(WPXInputStream *input)
   input->seek(1, WPX_SEEK_CUR);
   double ytop = readDouble(input);
 
-  m_currentGeometryList->addEllipse(m_header.id, m_header.level, cx, cy, xleft, yleft, xtop, ytop);
+  if (m_currentGeometryList)
+    m_currentGeometryList->addEllipse(m_header.id, m_header.level, cx, cy, xleft, yleft, xtop, ytop);
 }
 
 void libvisio::VSDParser::readLine(WPXInputStream *input)
@@ -854,7 +856,8 @@ void libvisio::VSDParser::readGeomList(WPXInputStream *input)
     for (unsigned i = 0; i < (childrenListLength / sizeof(uint32_t)); i++)
       geometryOrder.push_back(readU32(input));
 
-    m_currentGeometryList->setElementsOrder(geometryOrder);
+    if (m_currentGeometryList)
+      m_currentGeometryList->setElementsOrder(geometryOrder);
   }
 
   // We want the collectors to still get the level information
@@ -921,7 +924,8 @@ void libvisio::VSDParser::readGeometry(WPXInputStream *input)
   bool noLine = (!!(geomFlags & 2));
   bool noShow = (!!(geomFlags & 4));
 
-  m_currentGeometryList->addGeometry(m_header.id, m_header.level, noFill, noLine, noShow);
+  if (m_currentGeometryList)
+    m_currentGeometryList->addGeometry(m_header.id, m_header.level, noFill, noLine, noShow);
 }
 
 void libvisio::VSDParser::readMoveTo(WPXInputStream *input)
@@ -931,7 +935,8 @@ void libvisio::VSDParser::readMoveTo(WPXInputStream *input)
   input->seek(1, WPX_SEEK_CUR);
   double y = readDouble(input);
 
-  m_currentGeometryList->addMoveTo(m_header.id, m_header.level, x, y);
+  if (m_currentGeometryList)
+    m_currentGeometryList->addMoveTo(m_header.id, m_header.level, x, y);
 }
 
 void libvisio::VSDParser::readLineTo(WPXInputStream *input)
@@ -941,7 +946,8 @@ void libvisio::VSDParser::readLineTo(WPXInputStream *input)
   input->seek(1, WPX_SEEK_CUR);
   double y = readDouble(input);
 
-  m_currentGeometryList->addLineTo(m_header.id, m_header.level, x, y);
+  if (m_currentGeometryList)
+    m_currentGeometryList->addLineTo(m_header.id, m_header.level, x, y);
 }
 
 void libvisio::VSDParser::readArcTo(WPXInputStream *input)
@@ -953,7 +959,8 @@ void libvisio::VSDParser::readArcTo(WPXInputStream *input)
   input->seek(1, WPX_SEEK_CUR);
   double bow = readDouble(input);
 
-  m_currentGeometryList->addArcTo(m_header.id, m_header.level, x2, y2, bow);
+  if (m_currentGeometryList)
+    m_currentGeometryList->addArcTo(m_header.id, m_header.level, x2, y2, bow);
 }
 
 void libvisio::VSDParser::readXFormData(WPXInputStream *input)
@@ -1153,7 +1160,8 @@ void libvisio::VSDParser::readNURBSTo(WPXInputStream *input)
     input->seek(3, WPX_SEEK_CUR);
     unsigned dataId = readU32(input);
 
-    m_currentGeometryList->addNURBSTo(m_header.id, m_header.level, x, y, knot, knotPrev, weight, weightPrev, dataId);
+    if (m_currentGeometryList)
+      m_currentGeometryList->addNURBSTo(m_header.id, m_header.level, x, y, knot, knotPrev, weight, weightPrev, dataId);
     return;
   }
 
@@ -1281,12 +1289,14 @@ void libvisio::VSDParser::readNURBSTo(WPXInputStream *input)
     knotVector.push_back(lastKnot);
     weights.push_back(weight);
 
-    m_currentGeometryList->addNURBSTo(m_header.id, m_header.level, x, y, xType,
-                                      yType, degree, controlPoints, knotVector, weights);
+    if (m_currentGeometryList)
+      m_currentGeometryList->addNURBSTo(m_header.id, m_header.level, x, y, xType,
+                                        yType, degree, controlPoints, knotVector, weights);
   }
   else // No formula found, use line
   {
-    m_currentGeometryList->addLineTo(m_header.id, m_header.level, x,  y);
+    if (m_currentGeometryList)
+      m_currentGeometryList->addLineTo(m_header.id, m_header.level, x,  y);
   }
 }
 
@@ -1305,7 +1315,8 @@ void libvisio::VSDParser::readPolylineTo(WPXInputStream *input)
     input->seek(3, WPX_SEEK_CUR);
     unsigned dataId = readU32(input);
 
-    m_currentGeometryList->addPolylineTo(m_header.id, m_header.level, x, y, dataId);
+    if (m_currentGeometryList)
+      m_currentGeometryList->addPolylineTo(m_header.id, m_header.level, x, y, dataId);
     return;
   }
 
@@ -1377,12 +1388,14 @@ void libvisio::VSDParser::readPolylineTo(WPXInputStream *input)
       blockBytesRead += input->tell() - inputPos;
     }
 
-    m_currentGeometryList->addPolylineTo(m_header.id, m_header.level, x, y, xType,
-                                         yType, points);
+    if (m_currentGeometryList)
+      m_currentGeometryList->addPolylineTo(m_header.id, m_header.level, x, y, xType,
+                                           yType, points);
   }
   else
   {
-    m_currentGeometryList->addLineTo(m_header.id, m_header.level, x, y);
+    if (m_currentGeometryList)
+      m_currentGeometryList->addLineTo(m_header.id, m_header.level, x, y);
   }
 }
 
@@ -1396,7 +1409,8 @@ void libvisio::VSDParser::readInfiniteLine(WPXInputStream *input)
   double x2 = readDouble(input);
   input->seek(1, WPX_SEEK_CUR);
   double y2 = readDouble(input);
-  m_currentGeometryList->addInfiniteLine(m_header.id, m_header.level, x1, y1, x2, y2);
+  if (m_currentGeometryList)
+    m_currentGeometryList->addInfiniteLine(m_header.id, m_header.level, x1, y1, x2, y2);
 }
 
 void libvisio::VSDParser::readShapeData(WPXInputStream *input)
@@ -1475,7 +1489,8 @@ void libvisio::VSDParser::readSplineStart(WPXInputStream *input)
   double lastKnot = readDouble(input);
   unsigned degree = readU8(input);
 
-  m_currentGeometryList->addSplineStart(m_header.id, m_header.level, x, y, secondKnot, firstKnot, lastKnot, degree);
+  if (m_currentGeometryList)
+    m_currentGeometryList->addSplineStart(m_header.id, m_header.level, x, y, secondKnot, firstKnot, lastKnot, degree);
 }
 
 void libvisio::VSDParser::readSplineKnot(WPXInputStream *input)
@@ -1486,7 +1501,8 @@ void libvisio::VSDParser::readSplineKnot(WPXInputStream *input)
   double y = readDouble(input);
   double knot = readDouble(input);
 
-  m_currentGeometryList->addSplineKnot(m_header.id, m_header.level, x, y, knot);
+  if (m_currentGeometryList)
+    m_currentGeometryList->addSplineKnot(m_header.id, m_header.level, x, y, knot);
 }
 
 void libvisio::VSDParser::readNameList(WPXInputStream * /* input */)
commit 012166de9e82ced394138550d1c92e20df7cb504
Author: David Tardon <dtardon at redhat.com>
Date:   Sun May 12 07:39:17 2013 +0200

    use iterator to point to the current style
    
    This avoids crash if one (or both) of groupMembershipsSequence and
    documentPageShapeOrders come in empty (when reading broken file. I do
    not know if it can happen legitimately. Probably not).
    
    Also, the old code actually overwrites the first elements of the two
    vectors on each change, because assignment to a reference changes the
    object the reference refers to. While it is probably harmless, as we do
    not need the old styles again, it does not "feel" right.

diff --git a/src/lib/VSDContentCollector.cpp b/src/lib/VSDContentCollector.cpp
index 0f80948..b1f83d7 100644
--- a/src/lib/VSDContentCollector.cpp
+++ b/src/lib/VSDContentCollector.cpp
@@ -89,11 +89,12 @@ libvisio::VSDContentCollector::VSDContentCollector(
   m_currentForeignData(), m_currentOLEData(), m_currentForeignProps(), m_currentShapeId(0), m_foreignType((unsigned)-1),
   m_foreignFormat(0), m_foreignOffsetX(0.0), m_foreignOffsetY(0.0), m_foreignWidth(0.0), m_foreignHeight(0.0),
   m_noLine(false), m_noFill(false), m_noShow(false), m_fonts(),
-  m_currentLevel(0), m_isShapeStarted(false), m_groupMemberships(groupMembershipsSequence[0]),
+  m_currentLevel(0), m_isShapeStarted(false),
   m_groupXFormsSequence(groupXFormsSequence), m_groupMembershipsSequence(groupMembershipsSequence),
+  m_groupMemberships(m_groupMembershipsSequence.begin()),
   m_currentPageNumber(0), m_shapeOutputDrawing(0), m_shapeOutputText(0),
   m_pageOutputDrawing(), m_pageOutputText(), m_documentPageShapeOrders(documentPageShapeOrders),
-  m_pageShapeOrder(documentPageShapeOrders[0]), m_isFirstGeometry(true), m_NURBSData(), m_polylineData(),
+  m_pageShapeOrder(m_documentPageShapeOrders.begin()), m_isFirstGeometry(true), m_NURBSData(), m_polylineData(),
   m_textStream(), m_names(), m_stencilNames(), m_fields(), m_stencilFields(), m_fieldIndex(0),
   m_textFormat(VSD_TEXT_ANSI), m_charFormats(), m_paraFormats(), m_lineStyle(), m_fillStyle(),
   m_textBlockStyle(), m_defaultCharStyle(), m_defaultParaStyle(), m_currentStyleSheet(0), m_styles(styles),
@@ -713,13 +714,14 @@ void libvisio::VSDContentCollector::_flushCurrentForeignData()
 
 void libvisio::VSDContentCollector::_flushCurrentPage()
 {
-  if (!m_pageShapeOrder.empty())
+  if (m_pageShapeOrder != m_documentPageShapeOrders.end() && !m_pageShapeOrder->empty() &&
+      m_groupMemberships != m_groupMembershipsSequence.end())
   {
     std::stack<std::pair<unsigned, VSDOutputElementList> > groupTextStack;
-    for (std::list<unsigned>::iterator iterList = m_pageShapeOrder.begin(); iterList != m_pageShapeOrder.end(); ++iterList)
+    for (std::list<unsigned>::iterator iterList = m_pageShapeOrder->begin(); iterList != m_pageShapeOrder->end(); ++iterList)
     {
-      std::map<unsigned, unsigned>::iterator iterGroup = m_groupMemberships.find(*iterList);
-      if (iterGroup == m_groupMemberships.end())
+      std::map<unsigned, unsigned>::iterator iterGroup = m_groupMemberships->find(*iterList);
+      if (iterGroup == m_groupMemberships->end())
       {
         while (!groupTextStack.empty())
         {
@@ -1620,10 +1622,17 @@ void libvisio::VSDContentCollector::transformPoint(double &x, double &y, XForm *
     }
     else
       break;
-    std::map<unsigned, unsigned>::iterator iter = m_groupMemberships.find(shapeId);
-    if (iter != m_groupMemberships.end() && shapeId != iter->second)
-      shapeId = iter->second;
-    else
+    bool shapeFound = false;
+    if (m_groupMemberships != m_groupMembershipsSequence.end())
+    {
+      std::map<unsigned, unsigned>::iterator iter = m_groupMemberships->find(shapeId);
+      if (iter != m_groupMemberships->end() && shapeId != iter->second)
+      {
+        shapeId = iter->second;
+        shapeFound = true;
+      }
+    }
+    if (!shapeFound)
       break;
   }
   y = m_pageHeight - y;
@@ -1670,10 +1679,17 @@ void libvisio::VSDContentCollector::transformFlips(bool &flipX, bool &flipY)
     }
     else
       break;
-    std::map<unsigned, unsigned>::iterator iter = m_groupMemberships.find(shapeId);
-    if (iter != m_groupMemberships.end() && shapeId != iter->second)
-      shapeId = iter->second;
-    else
+    bool shapeFound = false;
+    if (m_groupMemberships != m_groupMembershipsSequence.end())
+    {
+      std::map<unsigned, unsigned>::iterator iter = m_groupMemberships->find(shapeId);
+      if (iter != m_groupMemberships->end() && shapeId != iter->second)
+      {
+        shapeId = iter->second;
+        shapeFound = true;
+      }
+    }
+    if (!shapeFound)
       break;
   }
 }
@@ -2537,9 +2553,9 @@ void libvisio::VSDContentCollector::startPage(unsigned pageId)
   if (m_groupXFormsSequence.size() >= m_currentPageNumber)
     m_groupXForms = m_groupXFormsSequence.size() > m_currentPageNumber-1 ? &m_groupXFormsSequence[m_currentPageNumber-1] : 0;
   if (m_groupMembershipsSequence.size() >= m_currentPageNumber)
-    m_groupMemberships = m_groupMembershipsSequence[m_currentPageNumber-1];
+    m_groupMemberships = m_groupMembershipsSequence.begin() + (m_currentPageNumber-1);
   if (m_documentPageShapeOrders.size() >= m_currentPageNumber)
-    m_pageShapeOrder = m_documentPageShapeOrders[m_currentPageNumber-1];
+    m_pageShapeOrder = m_documentPageShapeOrders.begin() + (m_currentPageNumber-1);
   m_currentPage = libvisio::VSDPage();
   m_currentPage.m_currentPageID = pageId;
   m_isPageStarted = true;
diff --git a/src/lib/VSDContentCollector.h b/src/lib/VSDContentCollector.h
index df4e475..d0667e6 100644
--- a/src/lib/VSDContentCollector.h
+++ b/src/lib/VSDContentCollector.h
@@ -252,15 +252,15 @@ private:
   std::map<unsigned short, VSDFont> m_fonts;
   unsigned m_currentLevel;
   bool m_isShapeStarted;
-  std::map<unsigned, unsigned> &m_groupMemberships;
   std::vector<std::map<unsigned, XForm> > &m_groupXFormsSequence;
   std::vector<std::map<unsigned, unsigned> > &m_groupMembershipsSequence;
+  std::vector<std::map<unsigned, unsigned> >::iterator m_groupMemberships;
   unsigned m_currentPageNumber;
   VSDOutputElementList *m_shapeOutputDrawing, *m_shapeOutputText;
   std::map<unsigned, VSDOutputElementList> m_pageOutputDrawing;
   std::map<unsigned, VSDOutputElementList> m_pageOutputText;
   std::vector<std::list<unsigned> > &m_documentPageShapeOrders;
-  std::list<unsigned> &m_pageShapeOrder;
+  std::vector<std::list<unsigned> >::iterator m_pageShapeOrder;
   bool m_isFirstGeometry;
 
   std::map<unsigned, NURBSData> m_NURBSData;


More information about the Libreoffice-commits mailing list