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

David Tardon dtardon at redhat.com
Mon Jul 20 10:23:49 PDT 2015


 src/lib/Makefile.am          |    2 
 src/lib/VDXParser.cpp        |    1 
 src/lib/VSDXMLHelper.cpp     |  172 -----------------------------------
 src/lib/VSDXMLHelper.h       |   21 ----
 src/lib/VSDXMLParserBase.cpp |   41 ++++----
 src/lib/VSDXMLParserBase.h   |    3 
 src/lib/VSDXMetaData.cpp     |   10 +-
 src/lib/VSDXParser.cpp       |   99 ++++++++++++--------
 src/lib/VSDXTheme.cpp        |    1 
 src/lib/VisioDocument.cpp    |    1 
 src/lib/libvisio_xml.cpp     |  207 +++++++++++++++++++++++++++++++++++++++++++
 src/lib/libvisio_xml.h       |   65 +++++++++++++
 12 files changed, 368 insertions(+), 255 deletions(-)

New commits:
commit 23364514c7f5099b6bd687f4011f7aec9d645d7e
Author: David Tardon <dtardon at redhat.com>
Date:   Mon Jul 20 19:19:12 2015 +0200

    handle even more infinite loops in XML parser
    
    Change-Id: Ic16f373c6a143b10d4a53c7c84f3433ebb3c323d

diff --git a/src/lib/VSDXMLParserBase.cpp b/src/lib/VSDXMLParserBase.cpp
index 76d254e..03fa396 100644
--- a/src/lib/VSDXMLParserBase.cpp
+++ b/src/lib/VSDXMLParserBase.cpp
@@ -162,7 +162,7 @@ void libvisio::VSDXMLParserBase::readGeometry(xmlTextReaderPtr reader)
       break;
     }
   }
-  while (((XML_GEOM != tokenId && XML_SECTION != tokenId) || XML_READER_TYPE_END_ELEMENT != tokenType) && 1 == ret);
+  while (((XML_GEOM != tokenId && XML_SECTION != tokenId) || XML_READER_TYPE_END_ELEMENT != tokenType) && 1 == ret && !m_watcher->isError());
   if (ret == 1)
     m_currentGeometryList->addGeometry(0, level+1, noFill, noLine, noShow);
 }
@@ -212,7 +212,7 @@ void libvisio::VSDXMLParserBase::readMoveTo(xmlTextReaderPtr reader)
       break;
     }
   }
-  while (((XML_MOVETO != tokenId && XML_ROW != tokenId) || XML_READER_TYPE_END_ELEMENT != tokenType) && 1 == ret);
+  while (((XML_MOVETO != tokenId && XML_ROW != tokenId) || XML_READER_TYPE_END_ELEMENT != tokenType) && 1 == ret && !m_watcher->isError());
   if (ret == 1)
     m_currentGeometryList->addMoveTo(ix, level, x, y);
 }
@@ -262,7 +262,7 @@ void libvisio::VSDXMLParserBase::readLineTo(xmlTextReaderPtr reader)
       break;
     }
   }
-  while (((XML_LINETO != tokenId && XML_ROW != tokenId) || XML_READER_TYPE_END_ELEMENT != tokenType) && 1 == ret);
+  while (((XML_LINETO != tokenId && XML_ROW != tokenId) || XML_READER_TYPE_END_ELEMENT != tokenType) && 1 == ret && !m_watcher->isError());
   if (ret == 1)
     m_currentGeometryList->addLineTo(ix, level, x, y);
 }
@@ -316,7 +316,7 @@ void libvisio::VSDXMLParserBase::readArcTo(xmlTextReaderPtr reader)
       break;
     }
   }
-  while (((XML_ARCTO != tokenId && XML_ROW != tokenId) || XML_READER_TYPE_END_ELEMENT != tokenType) && 1 == ret);
+  while (((XML_ARCTO != tokenId && XML_ROW != tokenId) || XML_READER_TYPE_END_ELEMENT != tokenType) && 1 == ret && !m_watcher->isError());
   if (ret == 1)
     m_currentGeometryList->addArcTo(ix, level, x, y, a);
 }
@@ -382,7 +382,7 @@ void libvisio::VSDXMLParserBase::readEllipticalArcTo(xmlTextReaderPtr reader)
       break;
     }
   }
-  while (((XML_ELLIPTICALARCTO != tokenId && XML_ROW != tokenId) || XML_READER_TYPE_END_ELEMENT != tokenType) && 1 == ret);
+  while (((XML_ELLIPTICALARCTO != tokenId && XML_ROW != tokenId) || XML_READER_TYPE_END_ELEMENT != tokenType) && 1 == ret && !m_watcher->isError());
   if (ret == 1)
     m_currentGeometryList->addEllipticalArcTo(ix, level, x, y, a, b, c, d);
 }
@@ -448,7 +448,7 @@ void libvisio::VSDXMLParserBase::readEllipse(xmlTextReaderPtr reader)
       break;
     }
   }
-  while (((XML_ELLIPSE != tokenId && XML_ROW != tokenId) || XML_READER_TYPE_END_ELEMENT != tokenType) && 1 == ret);
+  while (((XML_ELLIPSE != tokenId && XML_ROW != tokenId) || XML_READER_TYPE_END_ELEMENT != tokenType) && 1 == ret && !m_watcher->isError());
   if (ret == 1)
     m_currentGeometryList->addEllipse(ix, level, x, y, a, b, c, d);
 }
@@ -518,7 +518,7 @@ void libvisio::VSDXMLParserBase::readNURBSTo(xmlTextReaderPtr reader)
       break;
     }
   }
-  while (((XML_NURBSTO != tokenId && XML_ROW != tokenId) || XML_READER_TYPE_END_ELEMENT != tokenType) && 1 == ret);
+  while (((XML_NURBSTO != tokenId && XML_ROW != tokenId) || XML_READER_TYPE_END_ELEMENT != tokenType) && 1 == ret && !m_watcher->isError());
 
   if (ret == 1)
     m_currentGeometryList->addNURBSTo(ix, level, x, y, knot, knotPrev, weight, weightPrev, nurbsData);
@@ -573,7 +573,7 @@ void libvisio::VSDXMLParserBase::readPolylineTo(xmlTextReaderPtr reader)
       break;
     }
   }
-  while (((XML_POLYLINETO != tokenId && XML_ROW != tokenId) || XML_READER_TYPE_END_ELEMENT != tokenType) && 1 == ret);
+  while (((XML_POLYLINETO != tokenId && XML_ROW != tokenId) || XML_READER_TYPE_END_ELEMENT != tokenType) && 1 == ret && !m_watcher->isError());
   if (ret == 1)
     m_currentGeometryList->addPolylineTo(ix, level, x, y, polyLineData);
 }
@@ -631,7 +631,7 @@ void libvisio::VSDXMLParserBase::readInfiniteLine(xmlTextReaderPtr reader)
       break;
     }
   }
-  while (((XML_INFINITELINE != tokenId && XML_ROW != tokenId) || XML_READER_TYPE_END_ELEMENT != tokenType) && 1 == ret);
+  while (((XML_INFINITELINE != tokenId && XML_ROW != tokenId) || XML_READER_TYPE_END_ELEMENT != tokenType) && 1 == ret && !m_watcher->isError());
   if (ret == 1)
     m_currentGeometryList->addInfiniteLine(ix, level, x, y, a, b);
 }
@@ -697,7 +697,7 @@ void libvisio::VSDXMLParserBase::readRelEllipticalArcTo(xmlTextReaderPtr reader)
       break;
     }
   }
-  while (((XML_RELELLIPTICALARCTO != tokenId && XML_ROW != tokenId) || XML_READER_TYPE_END_ELEMENT != tokenType) && 1 == ret);
+  while (((XML_RELELLIPTICALARCTO != tokenId && XML_ROW != tokenId) || XML_READER_TYPE_END_ELEMENT != tokenType) && 1 == ret && !m_watcher->isError());
   if (ret == 1)
     m_currentGeometryList->addRelEllipticalArcTo(ix, level, x, y, a, b, c, d);
 }
@@ -763,7 +763,7 @@ void libvisio::VSDXMLParserBase::readRelCubBezTo(xmlTextReaderPtr reader)
       break;
     }
   }
-  while (((XML_RELCUBBEZTO != tokenId && XML_ROW != tokenId) || XML_READER_TYPE_END_ELEMENT != tokenType) && 1 == ret);
+  while (((XML_RELCUBBEZTO != tokenId && XML_ROW != tokenId) || XML_READER_TYPE_END_ELEMENT != tokenType) && 1 == ret && !m_watcher->isError());
   if (ret == 1)
     m_currentGeometryList->addRelCubBezTo(ix, level, x, y, a, b, c, d);
 }
@@ -813,7 +813,7 @@ void libvisio::VSDXMLParserBase::readRelLineTo(xmlTextReaderPtr reader)
       break;
     }
   }
-  while (((XML_RELLINETO != tokenId && XML_ROW != tokenId) || XML_READER_TYPE_END_ELEMENT != tokenType) && 1 == ret);
+  while (((XML_RELLINETO != tokenId && XML_ROW != tokenId) || XML_READER_TYPE_END_ELEMENT != tokenType) && 1 == ret && !m_watcher->isError());
   if (ret == 1)
     m_currentGeometryList->addRelLineTo(ix, level, x, y);
 }
@@ -863,7 +863,7 @@ void libvisio::VSDXMLParserBase::readRelMoveTo(xmlTextReaderPtr reader)
       break;
     }
   }
-  while (((XML_RELMOVETO != tokenId && XML_ROW != tokenId) || XML_READER_TYPE_END_ELEMENT != tokenType) && 1 == ret);
+  while (((XML_RELMOVETO != tokenId && XML_ROW != tokenId) || XML_READER_TYPE_END_ELEMENT != tokenType) && 1 == ret && !m_watcher->isError());
   if (ret == 1)
     m_currentGeometryList->addRelMoveTo(ix, level, x, y);
 }
@@ -921,7 +921,7 @@ void libvisio::VSDXMLParserBase::readRelQuadBezTo(xmlTextReaderPtr reader)
       break;
     }
   }
-  while (((XML_RELQUADBEZTO != tokenId && XML_ROW != tokenId) || XML_READER_TYPE_END_ELEMENT != tokenType) && 1 == ret);
+  while (((XML_RELQUADBEZTO != tokenId && XML_ROW != tokenId) || XML_READER_TYPE_END_ELEMENT != tokenType) && 1 == ret && !m_watcher->isError());
   if (ret == 1)
     m_currentGeometryList->addRelQuadBezTo(ix, level, x, y, a, b);
 }
@@ -1051,7 +1051,7 @@ void libvisio::VSDXMLParserBase::readColours(xmlTextReaderPtr reader)
       }
     }
   }
-  while ((XML_COLORS != tokenId || XML_READER_TYPE_END_ELEMENT != tokenType) && 1 == ret);
+  while ((XML_COLORS != tokenId || XML_READER_TYPE_END_ELEMENT != tokenType) && 1 == ret && !m_watcher->isError());
 }
 
 void libvisio::VSDXMLParserBase::readPage(xmlTextReaderPtr reader)
@@ -1153,7 +1153,7 @@ void libvisio::VSDXMLParserBase::readText(xmlTextReaderPtr reader)
       break;
     }
   }
-  while ((XML_TEXT != tokenId || XML_READER_TYPE_END_ELEMENT != tokenType) && 1 == ret);
+  while ((XML_TEXT != tokenId || XML_READER_TYPE_END_ELEMENT != tokenType) && 1 == ret && !m_watcher->isError());
 }
 
 void libvisio::VSDXMLParserBase::readCharIX(xmlTextReaderPtr reader)
@@ -1316,7 +1316,7 @@ void libvisio::VSDXMLParserBase::readCharIX(xmlTextReaderPtr reader)
     }
 
   }
-  while (((XML_CHAR != tokenId && XML_ROW != tokenId) || XML_READER_TYPE_END_ELEMENT != tokenType) && 1 == ret);
+  while (((XML_CHAR != tokenId && XML_ROW != tokenId) || XML_READER_TYPE_END_ELEMENT != tokenType) && 1 == ret && !m_watcher->isError());
 
   if (m_isInStyles)
     m_collector->collectCharIXStyle(ix, level, charCount, font, fontColour, fontSize, bold, italic,
@@ -1405,7 +1405,7 @@ void libvisio::VSDXMLParserBase::readParaIX(xmlTextReaderPtr reader)
       break;
     }
   }
-  while (((XML_PARA != tokenId && XML_ROW != tokenId) || XML_READER_TYPE_END_ELEMENT != tokenType) && 1 == ret);
+  while (((XML_PARA != tokenId && XML_ROW != tokenId) || XML_READER_TYPE_END_ELEMENT != tokenType) && 1 == ret && !m_watcher->isError());
 
   if (m_isInStyles)
     m_collector->collectParaIXStyle(ix, level, charCount, indFirst, indLeft, indRight,
@@ -1504,7 +1504,7 @@ void libvisio::VSDXMLParserBase::readSplineStart(xmlTextReaderPtr reader)
       break;
     }
   }
-  while (((XML_SPLINESTART != tokenId && XML_ROW != tokenId) || XML_READER_TYPE_END_ELEMENT != tokenType) && 1 == ret);
+  while (((XML_SPLINESTART != tokenId && XML_ROW != tokenId) || XML_READER_TYPE_END_ELEMENT != tokenType) && 1 == ret && !m_watcher->isError());
   if (ret == 1)
     m_currentGeometryList->addSplineStart(ix, level, x, y, a, b, c, d);
 }
@@ -1558,7 +1558,7 @@ void libvisio::VSDXMLParserBase::readSplineKnot(xmlTextReaderPtr reader)
       break;
     }
   }
-  while (((XML_SPLINEKNOT != tokenId && XML_ROW != tokenId) || XML_READER_TYPE_END_ELEMENT != tokenType) && 1 == ret);
+  while (((XML_SPLINEKNOT != tokenId && XML_ROW != tokenId) || XML_READER_TYPE_END_ELEMENT != tokenType) && 1 == ret && !m_watcher->isError());
   if (ret == 1)
     m_currentGeometryList->addSplineKnot(ix, level, x, y, a);
 }
diff --git a/src/lib/VSDXMLParserBase.h b/src/lib/VSDXMLParserBase.h
index ff65233..6698a9d 100644
--- a/src/lib/VSDXMLParserBase.h
+++ b/src/lib/VSDXMLParserBase.h
@@ -24,6 +24,7 @@ namespace libvisio
 {
 
 class VSDCollector;
+class XMLErrorWatcher;
 
 class VSDXMLParserBase
 {
@@ -59,6 +60,8 @@ protected:
 
   std::map<unsigned, VSDName> m_fonts;
 
+  XMLErrorWatcher *m_watcher;
+
   // Helper functions
 
   int readByteData(unsigned char &value, xmlTextReaderPtr reader);
diff --git a/src/lib/VSDXParser.h b/src/lib/VSDXParser.h
index 419e53a..9eef41e 100644
--- a/src/lib/VSDXParser.h
+++ b/src/lib/VSDXParser.h
@@ -18,7 +18,6 @@ namespace libvisio
 {
 
 class VSDCollector;
-class XMLErrorWatcher;
 
 class VSDXParser : public VSDXMLParserBase
 {
@@ -82,7 +81,6 @@ private:
   int m_currentDepth;
   VSDXRelationships *m_rels;
   VSDXTheme m_currentTheme;
-  XMLErrorWatcher *m_watcher;
 };
 
 } // namespace libvisio
commit 781201586a451393c62dde1c43dfb481c8dbaf24
Author: David Tardon <dtardon at redhat.com>
Date:   Mon Jul 20 19:01:20 2015 +0200

    handle more infinite loops in XML parser
    
    Change-Id: Ia39b230bd9ec76ba9bfa49820ea64f72ca1f35a6

diff --git a/src/lib/VSDXParser.cpp b/src/lib/VSDXParser.cpp
index e5cee1e..33f5695 100644
--- a/src/lib/VSDXParser.cpp
+++ b/src/lib/VSDXParser.cpp
@@ -302,55 +302,69 @@ void libvisio::VSDXParser::processXmlDocument(librevenge::RVNGInputStream *input
   XMLErrorWatcher watcher;
 
   const boost::shared_ptr<xmlTextReader> reader(
-      xmlReaderForStream(input, 0, 0, XML_PARSE_NOBLANKS|XML_PARSE_NOENT|XML_PARSE_NONET, &watcher),
-      xmlFreeTextReader);
+    xmlReaderForStream(input, 0, 0, XML_PARSE_NOBLANKS|XML_PARSE_NOENT|XML_PARSE_NONET, &watcher),
+    xmlFreeTextReader);
   if (!reader)
     return;
-  int ret = xmlTextReaderRead(reader.get());
-  while (1 == ret && !watcher.isError())
+
+  XMLErrorWatcher *oldWatcher = m_watcher;
+  try
   {
-    int tokenId = VSDXMLTokenMap::getTokenId(xmlTextReaderConstName(reader.get()));
-    int tokenType = xmlTextReaderNodeType(reader.get());
+    m_watcher = &watcher;
 
-    switch (tokenId)
+    int ret = xmlTextReaderRead(reader.get());
+    while (1 == ret && !watcher.isError())
     {
-    case XML_REL:
-      if (XML_READER_TYPE_ELEMENT == tokenType)
+      int tokenId = VSDXMLTokenMap::getTokenId(xmlTextReaderConstName(reader.get()));
+      int tokenType = xmlTextReaderNodeType(reader.get());
+
+      switch (tokenId)
       {
-        boost::shared_ptr<xmlChar> id(xmlTextReaderGetAttribute(reader.get(), BAD_CAST("r:id")), xmlFree);
-        if (id)
+      case XML_REL:
+        if (XML_READER_TYPE_ELEMENT == tokenType)
         {
-          const VSDXRelationship *rel = rels.getRelationshipById((char *)id.get());
-          if (rel)
+          boost::shared_ptr<xmlChar> id(xmlTextReaderGetAttribute(reader.get(), BAD_CAST("r:id")), xmlFree);
+          if (id)
           {
-            std::string type = rel->getType();
-            if (type == "http://schemas.microsoft.com/visio/2010/relationships/master")
-            {
-              m_currentDepth += xmlTextReaderDepth(reader.get());
-              parseMaster(m_input, rel->getTarget().c_str());
-              m_currentDepth -= xmlTextReaderDepth(reader.get());
-            }
-            else if (type == "http://schemas.microsoft.com/visio/2010/relationships/page")
-            {
-              m_currentDepth += xmlTextReaderDepth(reader.get());
-              parsePage(m_input, rel->getTarget().c_str());
-              m_currentDepth -= xmlTextReaderDepth(reader.get());
-            }
-            else if (type == "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image")
+            const VSDXRelationship *rel = rels.getRelationshipById((char *)id.get());
+            if (rel)
             {
-              extractBinaryData(m_input, rel->getTarget().c_str());
+              std::string type = rel->getType();
+              if (type == "http://schemas.microsoft.com/visio/2010/relationships/master")
+              {
+                m_currentDepth += xmlTextReaderDepth(reader.get());
+                parseMaster(m_input, rel->getTarget().c_str());
+                m_currentDepth -= xmlTextReaderDepth(reader.get());
+              }
+              else if (type == "http://schemas.microsoft.com/visio/2010/relationships/page")
+              {
+                m_currentDepth += xmlTextReaderDepth(reader.get());
+                parsePage(m_input, rel->getTarget().c_str());
+                m_currentDepth -= xmlTextReaderDepth(reader.get());
+              }
+              else if (type == "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image")
+              {
+                extractBinaryData(m_input, rel->getTarget().c_str());
+              }
+              else
+                processXmlNode(reader.get());
             }
-            else
-              processXmlNode(reader.get());
           }
         }
+        break;
+      default:
+        processXmlNode(reader.get());
+        break;
       }
-      break;
-    default:
-      processXmlNode(reader.get());
-      break;
+      ret = xmlTextReaderRead(reader.get());
     }
-    ret = xmlTextReaderRead(reader.get());
+
+    m_watcher = oldWatcher;
+  }
+  catch (...)
+  {
+    m_watcher = oldWatcher;
+    throw;
   }
 }
 
@@ -639,7 +653,7 @@ void libvisio::VSDXParser::readPageSheetProperties(xmlTextReaderPtr reader)
       break;
     }
   }
-  while ((XML_PAGESHEET != tokenId || XML_READER_TYPE_END_ELEMENT != tokenType) && 1 == ret);
+  while ((XML_PAGESHEET != tokenId || XML_READER_TYPE_END_ELEMENT != tokenType) && 1 == ret && !m_watcher->isError());
 
   if (m_isStencilStarted && m_currentStencil)
   {
@@ -682,7 +696,7 @@ void libvisio::VSDXParser::readFonts(xmlTextReaderPtr reader)
       ++idx;
     }
   }
-  while ((XML_FACENAMES != tokenId || XML_READER_TYPE_END_ELEMENT != tokenType) && 1 == ret);
+  while ((XML_FACENAMES != tokenId || XML_READER_TYPE_END_ELEMENT != tokenType) && 1 == ret && !m_watcher->isError());
 }
 
 void libvisio::VSDXParser::readStyleProperties(xmlTextReaderPtr reader)
@@ -874,7 +888,7 @@ void libvisio::VSDXParser::readStyleProperties(xmlTextReaderPtr reader)
       break;
     }
   }
-  while ((XML_STYLESHEET != tokenId || XML_READER_TYPE_END_ELEMENT != tokenType) && 1 == ret);
+  while ((XML_STYLESHEET != tokenId || XML_READER_TYPE_END_ELEMENT != tokenType) && 1 == ret && !m_watcher->isError());
 
 #if 0
   if (bgClrId < 0)
@@ -1255,7 +1269,7 @@ void libvisio::VSDXParser::readShapeProperties(xmlTextReaderPtr reader)
       break;
     }
   }
-  while ((XML_SHAPES != tokenId) && (XML_SHAPE != tokenId || XML_READER_TYPE_END_ELEMENT != tokenType) && 1 == ret);
+  while ((XML_SHAPES != tokenId) && (XML_SHAPE != tokenId || XML_READER_TYPE_END_ELEMENT != tokenType) && 1 == ret && !m_watcher->isError());
 
   if (1 == ret)
     processXmlNode(reader);
@@ -1279,7 +1293,7 @@ void libvisio::VSDXParser::readParagraph(xmlTextReaderPtr reader)
     if (XML_ROW == tokenId && XML_READER_TYPE_ELEMENT == tokenType)
       readParaIX(reader);
   }
-  while ((XML_SECTION != tokenId || XML_READER_TYPE_END_ELEMENT != tokenType) && 1 == ret);
+  while ((XML_SECTION != tokenId || XML_READER_TYPE_END_ELEMENT != tokenType) && 1 == ret && !m_watcher->isError());
 }
 
 void libvisio::VSDXParser::readCharacter(xmlTextReaderPtr reader)
@@ -1300,7 +1314,7 @@ void libvisio::VSDXParser::readCharacter(xmlTextReaderPtr reader)
     if (XML_ROW == tokenId && XML_READER_TYPE_ELEMENT == tokenType)
       readCharIX(reader);
   }
-  while ((XML_SECTION != tokenId || XML_READER_TYPE_END_ELEMENT != tokenType) && 1 == ret);
+  while ((XML_SECTION != tokenId || XML_READER_TYPE_END_ELEMENT != tokenType) && 1 == ret && !m_watcher->isError());
 }
 
 void libvisio::VSDXParser::getBinaryData(xmlTextReaderPtr reader)
diff --git a/src/lib/VSDXParser.h b/src/lib/VSDXParser.h
index 9eef41e..419e53a 100644
--- a/src/lib/VSDXParser.h
+++ b/src/lib/VSDXParser.h
@@ -18,6 +18,7 @@ namespace libvisio
 {
 
 class VSDCollector;
+class XMLErrorWatcher;
 
 class VSDXParser : public VSDXMLParserBase
 {
@@ -81,6 +82,7 @@ private:
   int m_currentDepth;
   VSDXRelationships *m_rels;
   VSDXTheme m_currentTheme;
+  XMLErrorWatcher *m_watcher;
 };
 
 } // namespace libvisio
commit c19e87440ef2d79ba199881c983f2be94fbef907
Author: David Tardon <dtardon at redhat.com>
Date:   Mon Jul 20 18:47:38 2015 +0200

    use const
    
    Change-Id: Idb34c470628f98aabfdcb75313705ce225a65bd7

diff --git a/src/lib/VSDXParser.cpp b/src/lib/VSDXParser.cpp
index 6ce9aaf..e5cee1e 100644
--- a/src/lib/VSDXParser.cpp
+++ b/src/lib/VSDXParser.cpp
@@ -301,7 +301,7 @@ void libvisio::VSDXParser::processXmlDocument(librevenge::RVNGInputStream *input
 
   XMLErrorWatcher watcher;
 
-  boost::shared_ptr<xmlTextReader> reader(
+  const boost::shared_ptr<xmlTextReader> reader(
       xmlReaderForStream(input, 0, 0, XML_PARSE_NOBLANKS|XML_PARSE_NOENT|XML_PARSE_NONET, &watcher),
       xmlFreeTextReader);
   if (!reader)
commit 8c59a6a236ec23558ac6645cdce4b58fdb002368
Author: David Tardon <dtardon at redhat.com>
Date:   Mon Jul 20 18:47:25 2015 +0200

    avoid another infinite loop in XML parser
    
    Change-Id: I73b3d064c8931f706e0df1e3bd837f0801491a51

diff --git a/src/lib/VSDXParser.cpp b/src/lib/VSDXParser.cpp
index dfaca93..6ce9aaf 100644
--- a/src/lib/VSDXParser.cpp
+++ b/src/lib/VSDXParser.cpp
@@ -299,11 +299,15 @@ void libvisio::VSDXParser::processXmlDocument(librevenge::RVNGInputStream *input
 
   m_rels = &rels;
 
-  boost::shared_ptr<xmlTextReader> reader(xmlReaderForStream(input, 0, 0, XML_PARSE_NOBLANKS|XML_PARSE_NOENT|XML_PARSE_NONET), xmlFreeTextReader);
+  XMLErrorWatcher watcher;
+
+  boost::shared_ptr<xmlTextReader> reader(
+      xmlReaderForStream(input, 0, 0, XML_PARSE_NOBLANKS|XML_PARSE_NOENT|XML_PARSE_NONET, &watcher),
+      xmlFreeTextReader);
   if (!reader)
     return;
   int ret = xmlTextReaderRead(reader.get());
-  while (1 == ret)
+  while (1 == ret && !watcher.isError())
   {
     int tokenId = VSDXMLTokenMap::getTokenId(xmlTextReaderConstName(reader.get()));
     int tokenType = xmlTextReaderNodeType(reader.get());
commit c2031ad6125b4fcd8202778e74b58235cd419f69
Author: David Tardon <dtardon at redhat.com>
Date:   Mon Jul 20 18:35:56 2015 +0200

    stop parsing if XML error is encountered
    
    xmlTextReader either does not continue processing the document if it
    encounters an error or it can get into an infinite loop in some cases.
    XML_PARSE_RECOVER does not help. So we just give up in case of error.
    
    Change-Id: I29615b656fc9b1dcd39aefbecc67da10c75fe0b6

diff --git a/src/lib/VSDXMetaData.cpp b/src/lib/VSDXMetaData.cpp
index 3724dc9..2d9a45c 100644
--- a/src/lib/VSDXMetaData.cpp
+++ b/src/lib/VSDXMetaData.cpp
@@ -117,8 +117,10 @@ bool libvisio::VSDXMetaData::parse(librevenge::RVNGInputStream *input)
   if (!input)
     return false;
 
+  XMLErrorWatcher watcher;
+
   const boost::shared_ptr<xmlTextReader> reader(
-    xmlReaderForStream(input, 0, 0, XML_PARSE_NOBLANKS|XML_PARSE_NOENT|XML_PARSE_NONET),
+    xmlReaderForStream(input, 0, 0, XML_PARSE_NOBLANKS|XML_PARSE_NOENT|XML_PARSE_NONET, &watcher),
     xmlFreeTextReader);
   if (!reader)
     return false;
@@ -126,7 +128,7 @@ bool libvisio::VSDXMetaData::parse(librevenge::RVNGInputStream *input)
   try
   {
     int ret = xmlTextReaderRead(reader.get());
-    while (1 == ret)
+    while (1 == ret && !watcher.isError())
     {
       int tokenId = getElementToken(reader.get());
       switch (tokenId)
@@ -146,7 +148,8 @@ bool libvisio::VSDXMetaData::parse(librevenge::RVNGInputStream *input)
   {
     return false;
   }
-  return true;
+
+  return !watcher.isError();
 }
 
 int libvisio::VSDXMetaData::getElementToken(xmlTextReaderPtr reader)
diff --git a/src/lib/libvisio_xml.cpp b/src/lib/libvisio_xml.cpp
index 09ad165..9941ee9 100644
--- a/src/lib/libvisio_xml.cpp
+++ b/src/lib/libvisio_xml.cpp
@@ -47,11 +47,12 @@ extern "C"
   }
 
 #ifdef DEBUG
-  static void vsdxReaderErrorFunc(void *, const char *message, xmlParserSeverities severity, xmlTextReaderLocatorPtr)
+  static void vsdxReaderErrorFunc(void *arg, const char *message, xmlParserSeverities severity, xmlTextReaderLocatorPtr)
 #else
-  static void vsdxReaderErrorFunc(void *, const char *, xmlParserSeverities severity, xmlTextReaderLocatorPtr)
+  static void vsdxReaderErrorFunc(void *arg, const char *, xmlParserSeverities severity, xmlTextReaderLocatorPtr)
 #endif
   {
+    XMLErrorWatcher *const watcher = reinterpret_cast<XMLErrorWatcher *>(arg);
     switch (severity)
     {
     case XML_PARSER_SEVERITY_VALIDITY_WARNING:
@@ -65,6 +66,8 @@ extern "C"
       break;
     case XML_PARSER_SEVERITY_ERROR:
       VSD_DEBUG_MSG(("Found xml parser severity error %s\n", message));
+      if (watcher)
+        watcher->setError();
       break;
     default:
       break;
@@ -75,10 +78,25 @@ extern "C"
 
 } // anonymous namespace
 
-xmlTextReaderPtr xmlReaderForStream(librevenge::RVNGInputStream *input, const char *URL, const char *encoding, int options)
+XMLErrorWatcher::XMLErrorWatcher()
+  : m_error(false)
+{
+}
+
+bool XMLErrorWatcher::isError() const
+{
+  return m_error;
+}
+
+void XMLErrorWatcher::setError()
+{
+  m_error = true;
+}
+
+xmlTextReaderPtr xmlReaderForStream(librevenge::RVNGInputStream *input, const char *URL, const char *encoding, int options, XMLErrorWatcher *const watcher)
 {
   xmlTextReaderPtr reader = xmlReaderForIO(vsdxInputReadFunc, vsdxInputCloseFunc, (void *)input, URL, encoding, options);
-  xmlTextReaderSetErrorHandler(reader, vsdxReaderErrorFunc, 0);
+  xmlTextReaderSetErrorHandler(reader, vsdxReaderErrorFunc, watcher);
   return reader;
 }
 
diff --git a/src/lib/libvisio_xml.h b/src/lib/libvisio_xml.h
index 3ec7524..298b739 100644
--- a/src/lib/libvisio_xml.h
+++ b/src/lib/libvisio_xml.h
@@ -21,13 +21,30 @@ namespace libvisio
 
 struct Colour;
 
+class XMLErrorWatcher
+{
+  // disable copying
+  XMLErrorWatcher(const XMLErrorWatcher &);
+  XMLErrorWatcher &operator=(const XMLErrorWatcher &);
+
+public:
+  XMLErrorWatcher();
+
+  bool isError() const;
+  void setError();
+
+private:
+  bool m_error;
+};
+
 // create an xmlTextReader pointer from a librevenge::RVNGInputStream pointer
 // needs to be freed using xmlTextReaderFree function.
 
 xmlTextReaderPtr xmlReaderForStream(librevenge::RVNGInputStream *input,
                                     const char *URL,
                                     const char *encoding,
-                                    int options);
+                                    int options,
+                                    XMLErrorWatcher *watcher = 0);
 
 Colour xmlStringToColour(const xmlChar *s);
 Colour xmlStringToColour(const boost::shared_ptr<xmlChar> &s);
commit 5b75213bedc88d6df1d95611521a913ad97a4bdc
Author: David Tardon <dtardon at redhat.com>
Date:   Mon Jul 20 18:23:46 2015 +0200

    move libxml2-related functions to a separate file
    
    Change-Id: I41a37b02f72e5c8d42e636b54627716add60e70f

diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am
index f07c5ac..f5968fd 100644
--- a/src/lib/Makefile.am
+++ b/src/lib/Makefile.am
@@ -27,6 +27,7 @@ libvisio_ at VSD_MAJOR_VERSION@_ at VSD_MINOR_VERSION@_la_DEPENDENCIES = @LIBVISIO_WIN
 libvisio_ at VSD_MAJOR_VERSION@_ at VSD_MINOR_VERSION@_la_LDFLAGS = $(version_info) -export-dynamic -no-undefined
 libvisio_ at VSD_MAJOR_VERSION@_ at VSD_MINOR_VERSION@_la_SOURCES = \
 	libvisio_utils.cpp \
+	libvisio_xml.cpp \
 	VisioDocument.cpp \
 	VSD5Parser.cpp \
 	VSD6Parser.cpp \
@@ -46,6 +47,7 @@ libvisio_ at VSD_MAJOR_VERSION@_ at VSD_MINOR_VERSION@_la_SOURCES = \
 	VSDStylesCollector.cpp \
 	VSDXMLHelper.cpp \
 	libvisio_utils.h \
+	libvisio_xml.h \
 	VSD5Parser.h \
 	VSD6Parser.h \
 	VSDInternalStream.h \
diff --git a/src/lib/VDXParser.cpp b/src/lib/VDXParser.cpp
index 1776de2..a64c5fc 100644
--- a/src/lib/VDXParser.cpp
+++ b/src/lib/VDXParser.cpp
@@ -15,6 +15,7 @@
 #include <boost/shared_ptr.hpp>
 #include "VDXParser.h"
 #include "libvisio_utils.h"
+#include "libvisio_xml.h"
 #include "VSDContentCollector.h"
 #include "VSDStylesCollector.h"
 #include "VSDXMLHelper.h"
diff --git a/src/lib/VSDXMLHelper.cpp b/src/lib/VSDXMLHelper.cpp
index b42b093..5bd40f0 100644
--- a/src/lib/VSDXMLHelper.cpp
+++ b/src/lib/VSDXMLHelper.cpp
@@ -17,180 +17,10 @@
 #include <boost/algorithm/string.hpp>
 #include <boost/lexical_cast.hpp>
 #include <boost/shared_ptr.hpp>
-#include <libxml/xmlIO.h>
-#include <libxml/xmlstring.h>
 #include <librevenge-stream/librevenge-stream.h>
 #include "VSDXMLHelper.h"
 #include "libvisio_utils.h"
-
-
-namespace
-{
-
-extern "C" {
-
-  static int vsdxInputCloseFunc(void *)
-  {
-    return 0;
-  }
-
-  static int vsdxInputReadFunc(void *context, char *buffer, int len)
-  {
-    librevenge::RVNGInputStream *input = (librevenge::RVNGInputStream *)context;
-
-    if ((!input) || (!buffer) || (len < 0))
-      return -1;
-
-    if (input->isEnd())
-      return 0;
-
-    unsigned long tmpNumBytesRead = 0;
-    const unsigned char *tmpBuffer = input->read(len, tmpNumBytesRead);
-
-    if (tmpBuffer && tmpNumBytesRead)
-      memcpy(buffer, tmpBuffer, tmpNumBytesRead);
-    return tmpNumBytesRead;
-  }
-
-#ifdef DEBUG
-  static void vsdxReaderErrorFunc(void *, const char *message, xmlParserSeverities severity, xmlTextReaderLocatorPtr)
-#else
-  static void vsdxReaderErrorFunc(void *, const char *, xmlParserSeverities severity, xmlTextReaderLocatorPtr)
-#endif
-  {
-    switch (severity)
-    {
-    case XML_PARSER_SEVERITY_VALIDITY_WARNING:
-      VSD_DEBUG_MSG(("Found xml parser severity validity warning %s\n", message));
-      break;
-    case XML_PARSER_SEVERITY_VALIDITY_ERROR:
-      VSD_DEBUG_MSG(("Found xml parser severity validity error %s\n", message));
-      break;
-    case XML_PARSER_SEVERITY_WARNING:
-      VSD_DEBUG_MSG(("Found xml parser severity warning %s\n", message));
-      break;
-    case XML_PARSER_SEVERITY_ERROR:
-      VSD_DEBUG_MSG(("Found xml parser severity error %s\n", message));
-      break;
-    default:
-      break;
-    }
-  }
-
-} // extern "C"
-
-} // anonymous namespace
-
-// xmlTextReader helper function
-
-xmlTextReaderPtr libvisio::xmlReaderForStream(librevenge::RVNGInputStream *input, const char *URL, const char *encoding, int options)
-{
-  xmlTextReaderPtr reader = xmlReaderForIO(vsdxInputReadFunc, vsdxInputCloseFunc, (void *)input, URL, encoding, options);
-  xmlTextReaderSetErrorHandler(reader, vsdxReaderErrorFunc, 0);
-  return reader;
-}
-
-libvisio::Colour libvisio::xmlStringToColour(const xmlChar *s)
-{
-  if (xmlStrEqual(s, BAD_CAST("Themed")))
-    return libvisio::Colour();
-  std::string str((const char *)s);
-  if (str[0] == '#')
-  {
-    if (str.length() != 7)
-    {
-      VSD_DEBUG_MSG(("Throwing XmlParserException\n"));
-      throw XmlParserException();
-    }
-    else
-      str.erase(str.begin());
-  }
-  else
-  {
-    if (str.length() != 6)
-    {
-      VSD_DEBUG_MSG(("Throwing XmlParserException\n"));
-      throw XmlParserException();
-    }
-  }
-
-  std::istringstream istr(str);
-  unsigned val = 0;
-  istr >> std::hex >> val;
-
-  return Colour((val & 0xff0000) >> 16, (val & 0xff00) >> 8, val & 0xff, 0);
-}
-
-libvisio::Colour libvisio::xmlStringToColour(const boost::shared_ptr<xmlChar> &s)
-{
-  return xmlStringToColour(s.get());
-}
-
-long libvisio::xmlStringToLong(const xmlChar *s)
-{
-  using boost::lexical_cast;
-  using boost::bad_lexical_cast;
-  if (xmlStrEqual(s, BAD_CAST("Themed")))
-    return 0;
-
-  try
-  {
-    return boost::lexical_cast<long, const char *>((const char *)s);
-  }
-  catch (const boost::bad_lexical_cast &)
-  {
-    VSD_DEBUG_MSG(("Throwing XmlParserException\n"));
-    throw XmlParserException();
-  }
-  return 0;
-}
-
-long libvisio::xmlStringToLong(const boost::shared_ptr<xmlChar> &s)
-{
-  return xmlStringToLong(s.get());
-}
-
-double libvisio::xmlStringToDouble(const xmlChar *s) try
-{
-  if (xmlStrEqual(s, BAD_CAST("Themed")))
-    return 0.0;
-
-  return boost::lexical_cast<double, const char *>((const char *)s);
-}
-catch (const boost::bad_lexical_cast &)
-{
-  VSD_DEBUG_MSG(("Throwing XmlParserException\n"));
-  throw XmlParserException();
-}
-
-double libvisio::xmlStringToDouble(const boost::shared_ptr<xmlChar> &s)
-{
-  return xmlStringToDouble(s.get());
-}
-
-bool libvisio::xmlStringToBool(const xmlChar *s)
-{
-  if (xmlStrEqual(s, BAD_CAST("Themed")))
-    return 0;
-
-  bool value = false;
-  if (xmlStrEqual(s, BAD_CAST("true")) || xmlStrEqual(s, BAD_CAST("1")))
-    value = true;
-  else if (xmlStrEqual(s, BAD_CAST("false")) || xmlStrEqual(s, BAD_CAST("0")))
-    value = false;
-  else
-  {
-    VSD_DEBUG_MSG(("Throwing XmlParserException\n"));
-    throw XmlParserException();
-  }
-  return value;
-
-}
-
-bool libvisio::xmlStringToBool(const boost::shared_ptr<xmlChar> &s)
-{
-  return xmlStringToBool(s.get());
-}
+#include "libvisio_xml.h"
 
 // VSDXRelationship
 
diff --git a/src/lib/VSDXMLHelper.h b/src/lib/VSDXMLHelper.h
index 588ca50..0a46a6a 100644
--- a/src/lib/VSDXMLHelper.h
+++ b/src/lib/VSDXMLHelper.h
@@ -20,27 +20,6 @@
 namespace libvisio
 {
 
-// create an xmlTextReader pointer from a librevenge::RVNGInputStream pointer
-// needs to be freed using xmlTextReaderFree function.
-
-xmlTextReaderPtr xmlReaderForStream(librevenge::RVNGInputStream *input,
-                                    const char *URL,
-                                    const char *encoding,
-                                    int options);
-
-Colour xmlStringToColour(const xmlChar *s);
-Colour xmlStringToColour(const boost::shared_ptr<xmlChar> &s);
-
-long xmlStringToLong(const xmlChar *s);
-long xmlStringToLong(const boost::shared_ptr<xmlChar> &s);
-
-double xmlStringToDouble(const xmlChar *s);
-double xmlStringToDouble(const boost::shared_ptr<xmlChar> &s);
-
-bool xmlStringToBool(const xmlChar *s);
-bool xmlStringToBool(const boost::shared_ptr<xmlChar> &s);
-
-
 class VSDCollector;
 
 // Helper classes to properly handle OPC relationships
diff --git a/src/lib/VSDXMLParserBase.cpp b/src/lib/VSDXMLParserBase.cpp
index 33afca9..76d254e 100644
--- a/src/lib/VSDXMLParserBase.cpp
+++ b/src/lib/VSDXMLParserBase.cpp
@@ -16,6 +16,7 @@
 #include <boost/spirit/include/classic.hpp>
 #include "VSDXMLParserBase.h"
 #include "libvisio_utils.h"
+#include "libvisio_xml.h"
 #include "VSDContentCollector.h"
 #include "VSDStylesCollector.h"
 #include "VSDXMLHelper.h"
diff --git a/src/lib/VSDXMetaData.cpp b/src/lib/VSDXMetaData.cpp
index ffcad6e..3724dc9 100644
--- a/src/lib/VSDXMetaData.cpp
+++ b/src/lib/VSDXMetaData.cpp
@@ -10,6 +10,7 @@
 #include "VSDXMetaData.h"
 #include "VSDXMLTokenMap.h"
 #include "libvisio_utils.h"
+#include "libvisio_xml.h"
 #include <string>
 #include <boost/shared_ptr.hpp>
 
diff --git a/src/lib/VSDXParser.cpp b/src/lib/VSDXParser.cpp
index 9cb62e6..dfaca93 100644
--- a/src/lib/VSDXParser.cpp
+++ b/src/lib/VSDXParser.cpp
@@ -15,6 +15,7 @@
 #include <boost/shared_ptr.hpp>
 #include "VSDXParser.h"
 #include "libvisio_utils.h"
+#include "libvisio_xml.h"
 #include "VSDContentCollector.h"
 #include "VSDStylesCollector.h"
 #include "VSDXMLHelper.h"
diff --git a/src/lib/VSDXTheme.cpp b/src/lib/VSDXTheme.cpp
index 142623f..edf395c 100644
--- a/src/lib/VSDXTheme.cpp
+++ b/src/lib/VSDXTheme.cpp
@@ -13,6 +13,7 @@
 
 #include "VSDXMLTokenMap.h"
 #include "libvisio_utils.h"
+#include "libvisio_xml.h"
 
 using boost::shared_ptr;
 
diff --git a/src/lib/VisioDocument.cpp b/src/lib/VisioDocument.cpp
index ee7c758..6304391 100644
--- a/src/lib/VisioDocument.cpp
+++ b/src/lib/VisioDocument.cpp
@@ -12,6 +12,7 @@
 #include <librevenge/librevenge.h>
 #include <libvisio/libvisio.h>
 #include "libvisio_utils.h"
+#include "libvisio_xml.h"
 #include "VDXParser.h"
 #include "VSDParser.h"
 #include "VSDXParser.h"
diff --git a/src/lib/libvisio_xml.cpp b/src/lib/libvisio_xml.cpp
new file mode 100644
index 0000000..09ad165
--- /dev/null
+++ b/src/lib/libvisio_xml.cpp
@@ -0,0 +1,189 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/*
+ * This file is part of the libvisio project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include "libvisio_xml.h"
+
+#include <boost/lexical_cast.hpp>
+
+#include "VSDTypes.h"
+#include "libvisio_utils.h"
+
+namespace libvisio
+{
+
+namespace
+{
+
+extern "C"
+{
+
+  static int vsdxInputCloseFunc(void *)
+  {
+    return 0;
+  }
+
+  static int vsdxInputReadFunc(void *context, char *buffer, int len)
+  {
+    librevenge::RVNGInputStream *input = (librevenge::RVNGInputStream *)context;
+
+    if ((!input) || (!buffer) || (len < 0))
+      return -1;
+
+    if (input->isEnd())
+      return 0;
+
+    unsigned long tmpNumBytesRead = 0;
+    const unsigned char *tmpBuffer = input->read(len, tmpNumBytesRead);
+
+    if (tmpBuffer && tmpNumBytesRead)
+      memcpy(buffer, tmpBuffer, tmpNumBytesRead);
+    return tmpNumBytesRead;
+  }
+
+#ifdef DEBUG
+  static void vsdxReaderErrorFunc(void *, const char *message, xmlParserSeverities severity, xmlTextReaderLocatorPtr)
+#else
+  static void vsdxReaderErrorFunc(void *, const char *, xmlParserSeverities severity, xmlTextReaderLocatorPtr)
+#endif
+  {
+    switch (severity)
+    {
+    case XML_PARSER_SEVERITY_VALIDITY_WARNING:
+      VSD_DEBUG_MSG(("Found xml parser severity validity warning %s\n", message));
+      break;
+    case XML_PARSER_SEVERITY_VALIDITY_ERROR:
+      VSD_DEBUG_MSG(("Found xml parser severity validity error %s\n", message));
+      break;
+    case XML_PARSER_SEVERITY_WARNING:
+      VSD_DEBUG_MSG(("Found xml parser severity warning %s\n", message));
+      break;
+    case XML_PARSER_SEVERITY_ERROR:
+      VSD_DEBUG_MSG(("Found xml parser severity error %s\n", message));
+      break;
+    default:
+      break;
+    }
+  }
+
+} // extern "C"
+
+} // anonymous namespace
+
+xmlTextReaderPtr xmlReaderForStream(librevenge::RVNGInputStream *input, const char *URL, const char *encoding, int options)
+{
+  xmlTextReaderPtr reader = xmlReaderForIO(vsdxInputReadFunc, vsdxInputCloseFunc, (void *)input, URL, encoding, options);
+  xmlTextReaderSetErrorHandler(reader, vsdxReaderErrorFunc, 0);
+  return reader;
+}
+
+Colour xmlStringToColour(const xmlChar *s)
+{
+  if (xmlStrEqual(s, BAD_CAST("Themed")))
+    return Colour();
+  std::string str((const char *)s);
+  if (str[0] == '#')
+  {
+    if (str.length() != 7)
+    {
+      VSD_DEBUG_MSG(("Throwing XmlParserException\n"));
+      throw XmlParserException();
+    }
+    else
+      str.erase(str.begin());
+  }
+  else
+  {
+    if (str.length() != 6)
+    {
+      VSD_DEBUG_MSG(("Throwing XmlParserException\n"));
+      throw XmlParserException();
+    }
+  }
+
+  std::istringstream istr(str);
+  unsigned val = 0;
+  istr >> std::hex >> val;
+
+  return Colour((val & 0xff0000) >> 16, (val & 0xff00) >> 8, val & 0xff, 0);
+}
+
+Colour xmlStringToColour(const boost::shared_ptr<xmlChar> &s)
+{
+  return xmlStringToColour(s.get());
+}
+
+long xmlStringToLong(const xmlChar *s)
+{
+  using boost::lexical_cast;
+  using boost::bad_lexical_cast;
+  if (xmlStrEqual(s, BAD_CAST("Themed")))
+    return 0;
+
+  try
+  {
+    return boost::lexical_cast<long, const char *>((const char *)s);
+  }
+  catch (const boost::bad_lexical_cast &)
+  {
+    VSD_DEBUG_MSG(("Throwing XmlParserException\n"));
+    throw XmlParserException();
+  }
+  return 0;
+}
+
+long xmlStringToLong(const boost::shared_ptr<xmlChar> &s)
+{
+  return xmlStringToLong(s.get());
+}
+
+double xmlStringToDouble(const xmlChar *s) try
+{
+  if (xmlStrEqual(s, BAD_CAST("Themed")))
+    return 0.0;
+
+  return boost::lexical_cast<double, const char *>((const char *)s);
+}
+catch (const boost::bad_lexical_cast &)
+{
+  VSD_DEBUG_MSG(("Throwing XmlParserException\n"));
+  throw XmlParserException();
+}
+
+double xmlStringToDouble(const boost::shared_ptr<xmlChar> &s)
+{
+  return xmlStringToDouble(s.get());
+}
+
+bool xmlStringToBool(const xmlChar *s)
+{
+  if (xmlStrEqual(s, BAD_CAST("Themed")))
+    return 0;
+
+  bool value = false;
+  if (xmlStrEqual(s, BAD_CAST("true")) || xmlStrEqual(s, BAD_CAST("1")))
+    value = true;
+  else if (xmlStrEqual(s, BAD_CAST("false")) || xmlStrEqual(s, BAD_CAST("0")))
+    value = false;
+  else
+  {
+    VSD_DEBUG_MSG(("Throwing XmlParserException\n"));
+    throw XmlParserException();
+  }
+  return value;
+
+}
+
+bool xmlStringToBool(const boost::shared_ptr<xmlChar> &s)
+{
+  return xmlStringToBool(s.get());
+}
+
+} // namespace libvisio
+
+/* vim:set shiftwidth=2 softtabstop=2 expandtab: */
diff --git a/src/lib/libvisio_xml.h b/src/lib/libvisio_xml.h
new file mode 100644
index 0000000..3ec7524
--- /dev/null
+++ b/src/lib/libvisio_xml.h
@@ -0,0 +1,48 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/*
+ * This file is part of the libvisio project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef __LIBVISIO_XML_H__
+#define __LIBVISIO_XML_H__
+
+#include <boost/shared_ptr.hpp>
+
+#include <librevenge-stream/librevenge-stream.h>
+
+#include <libxml/xmlreader.h>
+
+namespace libvisio
+{
+
+struct Colour;
+
+// create an xmlTextReader pointer from a librevenge::RVNGInputStream pointer
+// needs to be freed using xmlTextReaderFree function.
+
+xmlTextReaderPtr xmlReaderForStream(librevenge::RVNGInputStream *input,
+                                    const char *URL,
+                                    const char *encoding,
+                                    int options);
+
+Colour xmlStringToColour(const xmlChar *s);
+Colour xmlStringToColour(const boost::shared_ptr<xmlChar> &s);
+
+long xmlStringToLong(const xmlChar *s);
+long xmlStringToLong(const boost::shared_ptr<xmlChar> &s);
+
+double xmlStringToDouble(const xmlChar *s);
+double xmlStringToDouble(const boost::shared_ptr<xmlChar> &s);
+
+bool xmlStringToBool(const xmlChar *s);
+bool xmlStringToBool(const boost::shared_ptr<xmlChar> &s);
+
+} // namespace libvisio
+
+#endif // __LIBVISIO_XML_H__
+
+/* vim:set shiftwidth=2 softtabstop=2 expandtab: */


More information about the Libreoffice-commits mailing list