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

David Tardon dtardon at redhat.com
Mon May 15 18:42:41 UTC 2017


 configure.ac                    |    4 -
 src/lib/VSDContentCollector.cpp |   52 +++++------------
 src/lib/VSDGeometryList.cpp     |   54 ++++++++---------
 src/lib/VSDInternalStream.cpp   |    2 
 src/lib/VSDParser.cpp           |   37 +++++++++---
 src/lib/VSDParser.h             |    5 -
 src/lib/VSDTypes.h              |    1 
 src/lib/VSDXMLParserBase.cpp    |  122 +++++++++++++++++++++++-----------------
 8 files changed, 150 insertions(+), 127 deletions(-)

New commits:
commit 6a71379ad6a70b2b0e24400bb668d0accb3c9ab2
Author: David Tardon <dtardon at redhat.com>
Date:   Mon May 15 20:41:22 2017 +0200

    drop unneeded macro
    
    Change-Id: I352f2938e57ac93f8c787732cdd4757743fed901

diff --git a/src/lib/VSDGeometryList.cpp b/src/lib/VSDGeometryList.cpp
index 1e83f49..8bb6f61 100644
--- a/src/lib/VSDGeometryList.cpp
+++ b/src/lib/VSDGeometryList.cpp
@@ -20,8 +20,8 @@ class VSDGeometry : public VSDGeometryListElement
 public:
   VSDGeometry(unsigned id, unsigned level, const boost::optional<bool> &noFill,
               const boost::optional<bool> &noLine, const boost::optional<bool> &noShow) :
-    VSDGeometryListElement(id, level), m_noFill(FROM_OPTIONAL(noFill, false)),
-    m_noLine(FROM_OPTIONAL(noLine, false)), m_noShow(FROM_OPTIONAL(noShow, false)) {}
+    VSDGeometryListElement(id, level), m_noFill(get_optional_value_or(noFill, false)),
+    m_noLine(get_optional_value_or(noLine, false)), m_noShow(get_optional_value_or(noShow, false)) {}
   virtual ~VSDGeometry() {}
   void handle(VSDCollector *collector) const;
   VSDGeometryListElement *clone();
@@ -44,7 +44,7 @@ class VSDMoveTo : public VSDGeometryListElement
 {
 public:
   VSDMoveTo(unsigned id, unsigned level, const boost::optional<double> &x, const boost::optional<double> &y) :
-    VSDGeometryListElement(id, level), m_x(FROM_OPTIONAL(x, 0.0)), m_y(FROM_OPTIONAL(y, 0.0)) {}
+    VSDGeometryListElement(id, level), m_x(get_optional_value_or(x, 0.0)), m_y(get_optional_value_or(y, 0.0)) {}
   virtual ~VSDMoveTo() {}
   void handle(VSDCollector *collector) const;
   VSDGeometryListElement *clone();
@@ -55,7 +55,7 @@ class VSDLineTo : public VSDGeometryListElement
 {
 public:
   VSDLineTo(unsigned id, unsigned level, const boost::optional<double> &x, const boost::optional<double> &y) :
-    VSDGeometryListElement(id, level), m_x(FROM_OPTIONAL(x, 0.0)), m_y(FROM_OPTIONAL(y, 0.0)) {}
+    VSDGeometryListElement(id, level), m_x(get_optional_value_or(x, 0.0)), m_y(get_optional_value_or(y, 0.0)) {}
   virtual ~VSDLineTo() {}
   void handle(VSDCollector *collector) const;
   VSDGeometryListElement *clone();
@@ -66,7 +66,7 @@ class VSDArcTo : public VSDGeometryListElement
 {
 public:
   VSDArcTo(unsigned id, unsigned level, const boost::optional<double> &x2, const boost::optional<double> &y2, const boost::optional<double> &bow) :
-    VSDGeometryListElement(id, level), m_x2(FROM_OPTIONAL(x2, 0.0)), m_y2(FROM_OPTIONAL(y2, 0.0)), m_bow(FROM_OPTIONAL(bow, 0.0)) {}
+    VSDGeometryListElement(id, level), m_x2(get_optional_value_or(x2, 0.0)), m_y2(get_optional_value_or(y2, 0.0)), m_bow(get_optional_value_or(bow, 0.0)) {}
   virtual ~VSDArcTo() {}
   void handle(VSDCollector *collector) const;
   VSDGeometryListElement *clone();
@@ -79,9 +79,9 @@ public:
   VSDEllipse(unsigned id, unsigned level, const boost::optional<double> &cx, const boost::optional<double> &cy,
              const boost::optional<double> &xleft, const boost::optional<double> &yleft,
              const boost::optional<double> &xtop, const boost::optional<double> &ytop) :
-    VSDGeometryListElement(id, level), m_cx(FROM_OPTIONAL(cx, 0.0)), m_cy(FROM_OPTIONAL(cy, 0.0)),
-    m_xleft(FROM_OPTIONAL(xleft, 0.0)), m_yleft(FROM_OPTIONAL(yleft, 0.0)), m_xtop(FROM_OPTIONAL(xtop, 0.0)),
-    m_ytop(FROM_OPTIONAL(ytop, 0.0)) {}
+    VSDGeometryListElement(id, level), m_cx(get_optional_value_or(cx, 0.0)), m_cy(get_optional_value_or(cy, 0.0)),
+    m_xleft(get_optional_value_or(xleft, 0.0)), m_yleft(get_optional_value_or(yleft, 0.0)), m_xtop(get_optional_value_or(xtop, 0.0)),
+    m_ytop(get_optional_value_or(ytop, 0.0)) {}
   virtual ~VSDEllipse() {}
   void handle(VSDCollector *collector) const;
   VSDGeometryListElement *clone();
@@ -94,8 +94,8 @@ public:
   VSDEllipticalArcTo(unsigned id, unsigned level, const boost::optional<double> &x3, const boost::optional<double> &y3,
                      const boost::optional<double> &x2, const boost::optional<double> &y2,
                      const boost::optional<double> &angle, const boost::optional<double> &ecc) :
-    VSDGeometryListElement(id, level), m_x3(FROM_OPTIONAL(x3, 0.0)), m_y3(FROM_OPTIONAL(y3, 0.0)), m_x2(FROM_OPTIONAL(x2, 0.0)),
-    m_y2(FROM_OPTIONAL(y2, 0.0)), m_angle(FROM_OPTIONAL(angle, 0.0)), m_ecc(FROM_OPTIONAL(ecc, 1.0)) {}
+    VSDGeometryListElement(id, level), m_x3(get_optional_value_or(x3, 0.0)), m_y3(get_optional_value_or(y3, 0.0)), m_x2(get_optional_value_or(x2, 0.0)),
+    m_y2(get_optional_value_or(y2, 0.0)), m_angle(get_optional_value_or(angle, 0.0)), m_ecc(get_optional_value_or(ecc, 1.0)) {}
   virtual ~VSDEllipticalArcTo() {}
   void handle(VSDCollector *collector) const;
   VSDGeometryListElement *clone();
@@ -141,8 +141,8 @@ public:
   VSDNURBSTo3(unsigned id, unsigned level, const boost::optional<double> &x2, const boost::optional<double> &y2, const boost::optional<double> &knot,
               const boost::optional<double> &knotPrev, const boost::optional<double> &weight, const boost::optional<double> &weightPrev,
               const boost::optional<NURBSData> &data) :
-    VSDGeometryListElement(id, level), m_data(FROM_OPTIONAL(data, NURBSData())), m_x2(FROM_OPTIONAL(x2, 0.0)), m_y2(FROM_OPTIONAL(y2, 0.0)),
-    m_knot(FROM_OPTIONAL(knot, 0.0)), m_knotPrev(FROM_OPTIONAL(knotPrev, 0.0)), m_weight(FROM_OPTIONAL(weight, 0.0)), m_weightPrev(FROM_OPTIONAL(weightPrev, 0.0)) {}
+    VSDGeometryListElement(id, level), m_data(get_optional_value_or(data, NURBSData())), m_x2(get_optional_value_or(x2, 0.0)), m_y2(get_optional_value_or(y2, 0.0)),
+    m_knot(get_optional_value_or(knot, 0.0)), m_knotPrev(get_optional_value_or(knotPrev, 0.0)), m_weight(get_optional_value_or(weight, 0.0)), m_weightPrev(get_optional_value_or(weightPrev, 0.0)) {}
   virtual ~VSDNURBSTo3() {}
   void handle(VSDCollector *collector) const;
   VSDGeometryListElement *clone();
@@ -186,7 +186,7 @@ class VSDPolylineTo3 : public VSDGeometryListElement
 public:
   VSDPolylineTo3(unsigned id, unsigned level, const boost::optional<double> &x, const boost::optional<double> &y,
                  const boost::optional<PolylineData> &data) :
-    VSDGeometryListElement(id, level), m_data(FROM_OPTIONAL(data, PolylineData())), m_x(FROM_OPTIONAL(x, 0.0)), m_y(FROM_OPTIONAL(y, 0.0)) {}
+    VSDGeometryListElement(id, level), m_data(get_optional_value_or(data, PolylineData())), m_x(get_optional_value_or(x, 0.0)), m_y(get_optional_value_or(y, 0.0)) {}
   virtual ~VSDPolylineTo3() {}
   void handle(VSDCollector *collector) const;
   VSDGeometryListElement *clone();
@@ -201,8 +201,8 @@ public:
   VSDSplineStart(unsigned id, unsigned level, const boost::optional<double> &x, const boost::optional<double> &y,
                  const boost::optional<double> &secondKnot, const boost::optional<double> &firstKnot,
                  const boost::optional<double> &lastKnot, const boost::optional<unsigned> &degree) :
-    VSDGeometryListElement(id, level), m_x(FROM_OPTIONAL(x, 0.0)), m_y(FROM_OPTIONAL(y, 0.0)), m_secondKnot(FROM_OPTIONAL(secondKnot, 0.0)),
-    m_firstKnot(FROM_OPTIONAL(firstKnot, 0.0)), m_lastKnot(FROM_OPTIONAL(lastKnot, 0.0)), m_degree(FROM_OPTIONAL(degree, 0)) {}
+    VSDGeometryListElement(id, level), m_x(get_optional_value_or(x, 0.0)), m_y(get_optional_value_or(y, 0.0)), m_secondKnot(get_optional_value_or(secondKnot, 0.0)),
+    m_firstKnot(get_optional_value_or(firstKnot, 0.0)), m_lastKnot(get_optional_value_or(lastKnot, 0.0)), m_degree(get_optional_value_or(degree, 0)) {}
   virtual ~VSDSplineStart() {}
   void handle(VSDCollector *collector) const;
   VSDGeometryListElement *clone();
@@ -217,7 +217,7 @@ class VSDSplineKnot : public VSDGeometryListElement
 public:
   VSDSplineKnot(unsigned id, unsigned level, const boost::optional<double> &x, const boost::optional<double> &y,
                 const boost::optional<double> &knot) :
-    VSDGeometryListElement(id, level), m_x(FROM_OPTIONAL(x, 0.0)), m_y(FROM_OPTIONAL(y, 0.0)), m_knot(FROM_OPTIONAL(knot, 0.0)) {}
+    VSDGeometryListElement(id, level), m_x(get_optional_value_or(x, 0.0)), m_y(get_optional_value_or(y, 0.0)), m_knot(get_optional_value_or(knot, 0.0)) {}
   virtual ~VSDSplineKnot() {}
   void handle(VSDCollector *collector) const;
   VSDGeometryListElement *clone();
@@ -230,8 +230,8 @@ class VSDInfiniteLine : public VSDGeometryListElement
 public:
   VSDInfiniteLine(unsigned id, unsigned level, const boost::optional<double> &x1, const boost::optional<double> &y1,
                   const boost::optional<double> &x2, const boost::optional<double> &y2) :
-    VSDGeometryListElement(id, level), m_x1(FROM_OPTIONAL(x1, 0.0)), m_y1(FROM_OPTIONAL(y1, 0.0)),
-    m_x2(FROM_OPTIONAL(x2, 0.0)), m_y2(FROM_OPTIONAL(y2, 0.0)) {}
+    VSDGeometryListElement(id, level), m_x1(get_optional_value_or(x1, 0.0)), m_y1(get_optional_value_or(y1, 0.0)),
+    m_x2(get_optional_value_or(x2, 0.0)), m_y2(get_optional_value_or(y2, 0.0)) {}
   virtual ~VSDInfiniteLine() {}
   void handle(VSDCollector *collector) const;
   VSDGeometryListElement *clone();
@@ -243,8 +243,8 @@ class VSDRelCubBezTo : public VSDGeometryListElement
 public:
   VSDRelCubBezTo(unsigned id, unsigned level, const boost::optional<double> &x, const boost::optional<double> &y, const boost::optional<double> &a,
                  const boost::optional<double> &b, const boost::optional<double> &c, const boost::optional<double> &d) :
-    VSDGeometryListElement(id, level), m_x(FROM_OPTIONAL(x, 0.0)), m_y(FROM_OPTIONAL(y, 0.0)),
-    m_a(FROM_OPTIONAL(a, 0.0)), m_b(FROM_OPTIONAL(b, 0.0)), m_c(FROM_OPTIONAL(c, 0.0)), m_d(FROM_OPTIONAL(d, 0.0)) {}
+    VSDGeometryListElement(id, level), m_x(get_optional_value_or(x, 0.0)), m_y(get_optional_value_or(y, 0.0)),
+    m_a(get_optional_value_or(a, 0.0)), m_b(get_optional_value_or(b, 0.0)), m_c(get_optional_value_or(c, 0.0)), m_d(get_optional_value_or(d, 0.0)) {}
   virtual ~VSDRelCubBezTo() {}
   void handle(VSDCollector *collector) const;
   VSDGeometryListElement *clone();
@@ -257,9 +257,9 @@ public:
   VSDRelEllipticalArcTo(unsigned id, unsigned level, const boost::optional<double> &x3, const boost::optional<double> &y3,
                         const boost::optional<double> &x2, const boost::optional<double> &y2, const boost::optional<double> &angle,
                         const boost::optional<double> &ecc) :
-    VSDGeometryListElement(id, level), m_x3(FROM_OPTIONAL(x3, 0.0)), m_y3(FROM_OPTIONAL(y3, 0.0)),
-    m_x2(FROM_OPTIONAL(x2, 0.0)), m_y2(FROM_OPTIONAL(y2, 0.0)), m_angle(FROM_OPTIONAL(angle, 0.0)),
-    m_ecc(FROM_OPTIONAL(ecc, 1.0)) {}
+    VSDGeometryListElement(id, level), m_x3(get_optional_value_or(x3, 0.0)), m_y3(get_optional_value_or(y3, 0.0)),
+    m_x2(get_optional_value_or(x2, 0.0)), m_y2(get_optional_value_or(y2, 0.0)), m_angle(get_optional_value_or(angle, 0.0)),
+    m_ecc(get_optional_value_or(ecc, 1.0)) {}
   virtual ~VSDRelEllipticalArcTo() {}
   void handle(VSDCollector *collector) const;
   VSDGeometryListElement *clone();
@@ -270,7 +270,7 @@ class VSDRelMoveTo : public VSDGeometryListElement
 {
 public:
   VSDRelMoveTo(unsigned id, unsigned level, const boost::optional<double> &x, const boost::optional<double> &y) :
-    VSDGeometryListElement(id, level), m_x(FROM_OPTIONAL(x, 0.0)), m_y(FROM_OPTIONAL(y, 0.0)) {}
+    VSDGeometryListElement(id, level), m_x(get_optional_value_or(x, 0.0)), m_y(get_optional_value_or(y, 0.0)) {}
   virtual ~VSDRelMoveTo() {}
   void handle(VSDCollector *collector) const;
   VSDGeometryListElement *clone();
@@ -281,7 +281,7 @@ class VSDRelLineTo : public VSDGeometryListElement
 {
 public:
   VSDRelLineTo(unsigned id, unsigned level, const boost::optional<double> &x, const boost::optional<double> &y) :
-    VSDGeometryListElement(id, level), m_x(FROM_OPTIONAL(x, 0.0)), m_y(FROM_OPTIONAL(y, 0.0)) {}
+    VSDGeometryListElement(id, level), m_x(get_optional_value_or(x, 0.0)), m_y(get_optional_value_or(y, 0.0)) {}
   virtual ~VSDRelLineTo() {}
   void handle(VSDCollector *collector) const;
   VSDGeometryListElement *clone();
@@ -293,8 +293,8 @@ class VSDRelQuadBezTo : public VSDGeometryListElement
 public:
   VSDRelQuadBezTo(unsigned id, unsigned level, const boost::optional<double> &x, const boost::optional<double> &y,
                   const boost::optional<double> &a, const boost::optional<double> &b) :
-    VSDGeometryListElement(id, level), m_x(FROM_OPTIONAL(x, 0.0)),
-    m_y(FROM_OPTIONAL(y, 0.0)), m_a(FROM_OPTIONAL(a, 0.0)), m_b(FROM_OPTIONAL(b, 0.0)) {}
+    VSDGeometryListElement(id, level), m_x(get_optional_value_or(x, 0.0)),
+    m_y(get_optional_value_or(y, 0.0)), m_a(get_optional_value_or(a, 0.0)), m_b(get_optional_value_or(b, 0.0)) {}
   virtual ~VSDRelQuadBezTo() {}
   void handle(VSDCollector *collector) const;
   VSDGeometryListElement *clone();
diff --git a/src/lib/VSDTypes.h b/src/lib/VSDTypes.h
index a2e6e40..fbcb65d 100644
--- a/src/lib/VSDTypes.h
+++ b/src/lib/VSDTypes.h
@@ -14,7 +14,6 @@
 #include <map>
 #include <librevenge/librevenge.h>
 
-#define FROM_OPTIONAL(t, u) !!t ? t.get() : u
 #define ASSIGN_OPTIONAL(t, u) if(!!t) u = t.get()
 #define MINUS_ONE (unsigned)-1
 
commit f5f362797c76285216e46649970d0928135eeb81
Author: David Tardon <dtardon at redhat.com>
Date:   Mon May 15 17:04:05 2017 +0200

    move from Spirit.Classic to Qi
    
    Change-Id: I75e25d7b3430a9fc40cb8f8e79f53c12b6754c4e

diff --git a/configure.ac b/configure.ac
index 26c50e2..8b7167b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -88,7 +88,9 @@ AC_CHECK_HEADERS(
 	boost/cstdint.hpp \
 	boost/lexical_cast.hpp \
 	boost/optional.hpp \
-	boost/spirit/include/classic.hpp,
+	boost/phoenix.hpp \
+	boost/spirit/include/qi.hpp \
+        ,
 	[],
 	[AC_MSG_ERROR(Required boost headers not found. install boost >= 1.36)],
 	[]
diff --git a/src/lib/VSDContentCollector.cpp b/src/lib/VSDContentCollector.cpp
index 92898a5..acb2a30 100644
--- a/src/lib/VSDContentCollector.cpp
+++ b/src/lib/VSDContentCollector.cpp
@@ -12,7 +12,7 @@
 #include <string.h> // for memcpy
 #include <set>
 #include <stack>
-#include <boost/spirit/include/classic.hpp>
+#include <boost/spirit/include/qi.hpp>
 #include <unicode/ucnv.h>
 #include <unicode/utf8.h>
 
@@ -3551,30 +3551,21 @@ void libvisio::VSDContentCollector::endPages()
 
 bool libvisio::VSDContentCollector::parseFormatId(const char *formatString, unsigned short &result)
 {
-  using namespace ::boost::spirit::classic;
+  using namespace ::boost::spirit::qi;
 
   result = 0xffff;
 
-  uint_parser<unsigned short,10,1,5> ushort_p;
-  if (parse(formatString,
-            // Begin grammar
-            (
-              (
-                str_p("{<") >>
-                ushort_p[assign_a(result)]
-                >> str_p(">}")
-              )
-              |
-              (
-                str_p("esc(") >>
-                ushort_p[assign_a(result)]
-                >> ')'
-              )
-            )>> end_p,
-            // End grammar
-            space_p).full)
+  uint_parser<unsigned short,10,1,5> ushort_;
+  auto first = formatString;
+  const auto last = first + strlen(formatString);
+  if (phrase_parse(first, last,
+                   (
+                     "{<" >> ushort_ >> ">}"
+                     | "esc(" >> ushort_ >> ')'
+                   ),
+                   space, result))
   {
-    return true;
+    return first == last;
   }
   return false;
 }
@@ -3757,21 +3748,10 @@ void libvisio::VSDContentCollector::collectLayerMem(unsigned level, const VSDNam
   memcpy(&tmpData[0], layerMem.m_data.getDataBuffer(), layerMem.m_data.size());
   appendCharacters(text, tmpData, layerMem.m_format);
 
-  using namespace ::boost::spirit::classic;
-  bool bRes = parse(text.cstr(),
-                    //  Begin grammar
-                    (
-                      // parse comma-delimited list of doubles (have to use the
-                      // 'direct' variant, as otherwise spirit refactors our
-                      // parser to push both real num and comma to push_back_a)
-                      list_p.direct
-                      (
-                        int_p[push_back_a(m_currentLayerMem)],
-                        ';'
-                      )
-                    ) >> end_p,
-                    //  End grammar
-                    space_p).full;
+  using namespace ::boost::spirit::qi;
+  auto first = text.cstr();
+  const auto last = first + strlen(first);
+  bool bRes = phrase_parse(first, last, int_ % ';', space, m_currentLayerMem) && first == last;
 
   if (!bRes)
     m_currentLayerMem.clear();
diff --git a/src/lib/VSDXMLParserBase.cpp b/src/lib/VSDXMLParserBase.cpp
index 76fa5b3..5eb6481 100644
--- a/src/lib/VSDXMLParserBase.cpp
+++ b/src/lib/VSDXMLParserBase.cpp
@@ -11,7 +11,10 @@
 #include <libxml/xmlIO.h>
 #include <libxml/xmlstring.h>
 #include <librevenge-stream/librevenge-stream.h>
-#include <boost/spirit/include/classic.hpp>
+
+#include <boost/phoenix.hpp>
+#include <boost/spirit/include/qi.hpp>
+
 #include "VSDXMLParserBase.h"
 #include "libvisio_utils.h"
 #include "libvisio_xml.h"
@@ -1959,8 +1962,6 @@ void libvisio::VSDXMLParserBase::skipPages(xmlTextReaderPtr reader)
 
 int libvisio::VSDXMLParserBase::readNURBSData(boost::optional<NURBSData> &data, xmlTextReaderPtr reader)
 {
-  using namespace ::boost::spirit::classic;
-
   NURBSData tmpData;
 
   bool bRes = false;
@@ -1970,26 +1971,39 @@ int libvisio::VSDXMLParserBase::readNURBSData(boost::optional<NURBSData> &data,
   {
     std::pair<double, double> point;
 
-    bRes = parse((const char *)formula.get(),
-                 //  Begin grammar
-                 (
-                   str_p("NURBS")
-                   >> '('
-                   >> real_p[assign_a(tmpData.lastKnot)] >> (',' | eps_p)
-                   >> int_p[assign_a(tmpData.degree)] >> (',' | eps_p)
-                   >> int_p[assign_a(tmpData.xType)] >> (',' | eps_p)
-                   >> int_p[assign_a(tmpData.yType)] >> (',' | eps_p) >>
-                   // array of points, weights and knots
-                   (list_p(
-                      (
-                        (real_p[assign_a(point.first)] >> (',' | eps_p) >>
-                         real_p[assign_a(point.second)])[push_back_a(tmpData.points,point)]
-                        >> (',' | eps_p) >>
-                        real_p[push_back_a(tmpData.knots)] >> (',' | eps_p) >>
-                        real_p[push_back_a(tmpData.weights)]), ',' | eps_p))
-                 ) >> ')' >> end_p,
-                 //  End grammar
-                 space_p).full;
+    using namespace ::boost::spirit::qi;
+    namespace phx = boost::phoenix;
+    using phx::push_back;
+    using phx::ref;
+
+    auto first = reinterpret_cast<const char *>(formula.get());
+    const auto last = first + strlen(first);
+    bRes = phrase_parse(first, last,
+                        //  Begin grammar
+                        (
+                          lit("NURBS")
+                          >> '('
+                          >> double_[ref(tmpData.lastKnot) = _1] >> -char_(',')
+                          >> int_[ref(tmpData.degree) = _1] >> -char_(',')
+                          >> int_[ref(tmpData.xType) = _1] >> -char_(',')
+                          >> int_[ref(tmpData.yType) = _1] >> -char_(',')
+                          >> // array of points, weights and knots
+                          (
+                            (
+                              (double_[ref(point.first) = _1] >> -char_(',') >>
+                               double_[ref(point.second) = _1]
+                              )[push_back(phx::ref(tmpData.points), phx::cref(point))]
+                              >> -char_(',') >>
+                              double_[push_back(phx::ref(tmpData.knots), _1)] >> -char_(',') >>
+                              double_[push_back(phx::ref(tmpData.weights), _1)]
+                            )
+                            % -char_(',')
+                          )
+                          >> ')'
+                        ),
+                        //  End grammar
+                        space)
+           && first == last;
   }
 
   if (!bRes)
@@ -2000,8 +2014,6 @@ int libvisio::VSDXMLParserBase::readNURBSData(boost::optional<NURBSData> &data,
 
 int libvisio::VSDXMLParserBase::readPolylineData(boost::optional<PolylineData> &data, xmlTextReaderPtr reader)
 {
-  using namespace ::boost::spirit::classic;
-
   PolylineData tmpData;
 
   bool bRes = false;
@@ -2011,21 +2023,30 @@ int libvisio::VSDXMLParserBase::readPolylineData(boost::optional<PolylineData> &
   {
     std::pair<double, double> point;
 
-    bRes = parse((const char *)formula.get(),
-                 //  Begin grammar
-                 (
-                   str_p("POLYLINE")
-                   >> '('
-                   >> int_p[assign_a(tmpData.xType)] >> (',' | eps_p)
-                   >> int_p[assign_a(tmpData.yType)] >> (',' | eps_p) >>
-                   // array of points
-                   (list_p(
-                      (
-                        (real_p[assign_a(point.first)] >> (',' | eps_p) >>
-                         real_p[assign_a(point.second)])[push_back_a(tmpData.points,point)]), ',' | eps_p))
-                 ) >> ')' >> end_p,
-                 //  End grammar
-                 space_p).full;
+    using namespace ::boost::spirit::qi;
+    namespace phx = boost::phoenix;
+    using phx::push_back;
+    using phx::ref;
+
+    auto first = reinterpret_cast<const char *>(formula.get());
+    const auto last = first + strlen(first);
+    bRes = phrase_parse(first, last,
+                        (
+                          lit("POLYLINE")
+                          >> '('
+                          >> int_[ref(tmpData.xType) = _1] >> -char_(',')
+                          >> int_[ref(tmpData.yType) = _1] >> -char_(',')
+                          >> // array of points
+                          (
+                            (
+                              double_[ref(point.first) = _1] >> -char_(',')
+                              >> double_[ref(point.second) = _1]
+                            )[push_back(phx::ref(tmpData.points), phx::cref(point))] % -char_(',')
+                          )
+                          >> ')'
+                        ),
+                        space)
+           && first == last;
   }
 
   if (!bRes)
@@ -2215,21 +2236,22 @@ unsigned libvisio::VSDXMLParserBase::getIX(xmlTextReaderPtr reader)
 
 void libvisio::VSDXMLParserBase::readTriggerId(unsigned &id, xmlTextReaderPtr reader)
 {
-  using namespace ::boost::spirit::classic;
+  using namespace ::boost::spirit::qi;
 
   unsigned triggerId = MINUS_ONE;
   const std::shared_ptr<xmlChar> triggerString(xmlTextReaderGetAttribute(reader, BAD_CAST("F")), xmlFree);
   if (triggerString)
   {
-    if (parse((const char *)triggerString.get(),
-              //  Begin grammar
-              (
-                str_p("_XFTRIGGER")
-                >> '(' >> (+(alnum_p|space_p)) >> '.'
-                >> int_p[assign_a(triggerId)] >> '!' >> str_p("EventXFMod")
-              ) >> ')' >> end_p,
-              //  End grammar
-              space_p).full)
+    auto first = reinterpret_cast<const char *>(triggerString.get());
+    const auto last = first + strlen(first);
+    if (phrase_parse(first, last,
+                     (
+                       lit("_XFTRIGGER")
+                       >> '(' >> omit[+alnum] >> '.'
+                       >> int_ >> '!' >> lit("EventXFMod")
+                       >> ')'
+                     ),
+                     space, triggerId) && first == last)
       id = triggerId;
   }
 }
commit d095eb768180f86df4f939d86f3debf3a7078872
Author: David Tardon <dtardon at redhat.com>
Date:   Mon May 15 16:39:58 2017 +0200

    ofz#1000 avoid stack overflow
    
    Change-Id: Ie570417aa0c6c8a3eefcaf954fd572f4a82308f2

diff --git a/src/lib/VSDParser.cpp b/src/lib/VSDParser.cpp
index 07733b5..3827313 100644
--- a/src/lib/VSDParser.cpp
+++ b/src/lib/VSDParser.cpp
@@ -9,6 +9,7 @@
 
 #include <librevenge-stream/librevenge-stream.h>
 #include <locale.h>
+#include <cassert>
 #include <sstream>
 #include <string>
 #include <cmath>
@@ -189,11 +190,14 @@ bool libvisio::VSDParser::parseDocument(librevenge::RVNGInputStream *input, unsi
 {
   try
   {
-    handleStreams(input, VSD_TRAILER_STREAM, shift, 0);
+    std::set<unsigned> visited;
+    handleStreams(input, VSD_TRAILER_STREAM, shift, 0, visited);
+    assert(visited.empty());
     return true;
   }
   catch (...)
   {
+    assert(visited.empty());
     return false;
   }
 }
@@ -224,7 +228,7 @@ void libvisio::VSDParser::readPointerInfo(librevenge::RVNGInputStream *input, un
   input->seek(4, librevenge::RVNG_SEEK_CUR);
 }
 
-void libvisio::VSDParser::handleStreams(librevenge::RVNGInputStream *input, unsigned ptrType, unsigned shift, unsigned level)
+void libvisio::VSDParser::handleStreams(librevenge::RVNGInputStream *input, unsigned ptrType, unsigned shift, unsigned level, std::set<unsigned> &visited)
 {
   VSD_DEBUG_MSG(("VSDParser::HandleStreams\n"));
   std::vector<unsigned> pointerOrder;
@@ -270,13 +274,13 @@ void libvisio::VSDParser::handleStreams(librevenge::RVNGInputStream *input, unsi
 
   std::map<unsigned, libvisio::Pointer>::iterator iter;
   for (iter = NameList.begin(); iter != NameList.end(); ++iter)
-    handleStream(iter->second, iter->first, level+1);
+    handleStream(iter->second, iter->first, level+1, visited);
 
   for (iter = NameIDX.begin(); iter != NameIDX.end(); ++iter)
-    handleStream(iter->second, iter->first, level+1);
+    handleStream(iter->second, iter->first, level+1, visited);
 
   for (iter = FontFaces.begin(); iter != FontFaces.end(); ++iter)
-    handleStream(iter->second, iter->first, level+1);
+    handleStream(iter->second, iter->first, level+1, visited);
 
   if (!pointerOrder.empty())
   {
@@ -285,17 +289,17 @@ void libvisio::VSDParser::handleStreams(librevenge::RVNGInputStream *input, unsi
       iter = PtrList.find(pointerOrder[j]);
       if (iter != PtrList.end())
       {
-        handleStream(iter->second, iter->first, level+1);
+        handleStream(iter->second, iter->first, level+1, visited);
         PtrList.erase(iter);
       }
     }
   }
   for (iter = PtrList.begin(); iter != PtrList.end(); ++iter)
-    handleStream(iter->second, iter->first, level+1);
+    handleStream(iter->second, iter->first, level+1, visited);
 
 }
 
-void libvisio::VSDParser::handleStream(const Pointer &ptr, unsigned idx, unsigned level)
+void libvisio::VSDParser::handleStream(const Pointer &ptr, unsigned idx, unsigned level, std::set<unsigned> &visited)
 {
   VSD_DEBUG_MSG(("VSDParser::HandleStream %u type 0x%x\n", idx, ptr.Type));
   m_header.level = level;
@@ -362,7 +366,22 @@ void libvisio::VSDParser::handleStream(const Pointer &ptr, unsigned idx, unsigne
   {
     handleBlob(&tmpInput, shift, level+1);
     if ((ptr.Format >> 4) == 0x5 && ptr.Type != VSD_COLORS)
-      handleStreams(&tmpInput, ptr.Type, shift, level+1);
+    {
+      const auto it = visited.insert(ptr.Offset);
+      if (it.second)
+      {
+        try
+        {
+          handleStreams(&tmpInput, ptr.Type, shift, level+1, visited);
+        }
+        catch (...)
+        {
+          visited.erase(it.first);
+          throw;
+        }
+        visited.erase(it.first);
+      }
+    }
   }
   else if ((ptr.Format >> 4) == 0xd || (ptr.Format >> 4) == 0xc || (ptr.Format >> 4) == 0x8)
     handleChunks(&tmpInput, level+1);
diff --git a/src/lib/VSDParser.h b/src/lib/VSDParser.h
index bdd8b37..e275a97 100644
--- a/src/lib/VSDParser.h
+++ b/src/lib/VSDParser.h
@@ -15,6 +15,7 @@
 #include <vector>
 #include <stack>
 #include <map>
+#include <set>
 #include <librevenge/librevenge.h>
 #include "VSDTypes.h"
 #include "VSDGeometryList.h"
@@ -124,8 +125,8 @@ protected:
   void parseMetaData();
 
   // Stream handlers
-  void handleStreams(librevenge::RVNGInputStream *input, unsigned ptrType, unsigned shift, unsigned level);
-  void handleStream(const Pointer &ptr, unsigned idx, unsigned level);
+  void handleStreams(librevenge::RVNGInputStream *input, unsigned ptrType, unsigned shift, unsigned level, std::set<unsigned> &visited);
+  void handleStream(const Pointer &ptr, unsigned idx, unsigned level, std::set<unsigned> &visited);
   void handleChunks(librevenge::RVNGInputStream *input, unsigned level);
   void handleChunk(librevenge::RVNGInputStream *input);
   void handleBlob(librevenge::RVNGInputStream *input, unsigned shift, unsigned level);
commit 214b5930a63e1f1652dd7a7e27a62627385bc6d9
Author: David Tardon <dtardon at redhat.com>
Date:   Fri May 5 12:33:55 2017 +0200

    avoid possible overflow
    
    Change-Id: I30d60ba7964fc731be1706edc864afa22882b9a2

diff --git a/src/lib/VSDInternalStream.cpp b/src/lib/VSDInternalStream.cpp
index 9d69c39..1873eac 100644
--- a/src/lib/VSDInternalStream.cpp
+++ b/src/lib/VSDInternalStream.cpp
@@ -84,7 +84,7 @@ const unsigned char *VSDInternalStream::read(unsigned long numBytes, unsigned lo
 
   int numBytesToRead;
 
-  if ((m_offset+numBytes) < m_buffer.size())
+  if (numBytes < m_buffer.size() - m_offset)
     numBytesToRead = numBytes;
   else
     numBytesToRead = m_buffer.size() - m_offset;


More information about the Libreoffice-commits mailing list