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 <[email protected]> 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> °ree) : - 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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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; _______________________________________________ Libreoffice-commits mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
