src/lib/VSDContentCollector.cpp | 11 ++ src/lib/VSDStyles.cpp | 153 ++++++++++++---------------------------- src/lib/VSDStylesCollector.cpp | 5 + 3 files changed, 61 insertions(+), 108 deletions(-)
New commits: commit 1c71f0a300b012cca709662823e9cbfa85fb7b36 Author: David Tardon <dtar...@redhat.com> Date: Thu Jul 16 18:59:23 2015 +0200 avoid endless loop when reading broken file Change-Id: I95ba48b926e51873786255e8933e94def4b04ace diff --git a/src/lib/VSDContentCollector.cpp b/src/lib/VSDContentCollector.cpp index 1d98798..8f2759a 100644 --- a/src/lib/VSDContentCollector.cpp +++ b/src/lib/VSDContentCollector.cpp @@ -8,6 +8,7 @@ */ #include <string.h> // for memcpy +#include <set> #include <stack> #include <boost/spirit/include/classic.hpp> #include <unicode/ucnv.h> @@ -1771,6 +1772,9 @@ void libvisio::VSDContentCollector::transformPoint(double &x, double &y, XForm * unsigned shapeId = m_currentShapeId; + std::set<unsigned> visitedShapes; // avoid mutually nested shapes in broken files + visitedShapes.insert(shapeId); + if (txtxform) applyXForm(x, y, *txtxform); @@ -1791,7 +1795,7 @@ void libvisio::VSDContentCollector::transformPoint(double &x, double &y, XForm * if (iter != m_groupMemberships->end() && shapeId != iter->second) { shapeId = iter->second; - shapeFound = true; + shapeFound = visitedShapes.insert(shapeId).second; } } if (!shapeFound) @@ -1828,6 +1832,9 @@ void libvisio::VSDContentCollector::transformFlips(bool &flipX, bool &flipY) unsigned shapeId = m_currentShapeId; + std::set<unsigned> visitedShapes; // avoid mutually nested shapes in broken files + visitedShapes.insert(shapeId); + while (true && m_groupXForms) { std::map<unsigned, XForm>::iterator iterX = m_groupXForms->find(shapeId); @@ -1848,7 +1855,7 @@ void libvisio::VSDContentCollector::transformFlips(bool &flipX, bool &flipY) if (iter != m_groupMemberships->end() && shapeId != iter->second) { shapeId = iter->second; - shapeFound = true; + shapeFound = visitedShapes.insert(shapeId).second; } } if (!shapeFound) commit 03eed259ce331998af623cf5da5320441ed55d1f Author: David Tardon <dtar...@redhat.com> Date: Thu Jul 16 18:43:34 2015 +0200 avoid endless loop when reading broken file Change-Id: I4956a3438d273a06a11d96031e2759062dce1e95 diff --git a/src/lib/VSDStyles.cpp b/src/lib/VSDStyles.cpp index ff29267..f8fd33d 100644 --- a/src/lib/VSDStyles.cpp +++ b/src/lib/VSDStyles.cpp @@ -7,6 +7,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#include <set> #include <stack> #include "VSDStyles.h" #include "VSDTypes.h" @@ -24,12 +25,18 @@ T getOptionalStyle(const std::map<unsigned, unsigned> &styleMasters, const std:: if (MINUS_ONE == styleIndex) return style; std::stack<unsigned> styleIdStack; + std::set<unsigned> foundStyles; styleIdStack.push(styleIndex); while (true) { std::map<unsigned, unsigned>::const_iterator iter = styleMasters.find(styleIdStack.top()); if (iter != styleMasters.end() && iter->second != MINUS_ONE) - styleIdStack.push(iter->second); + { + if (foundStyles.insert(iter->second).second) + styleIdStack.push(iter->second); + else // we already have this style -> stop incoming endless loop + break; + } else break; } commit 4a2e82ddca257374ab04c7bbbc1869e666a2d6b9 Author: David Tardon <dtar...@redhat.com> Date: Thu Jul 16 16:56:00 2015 +0200 avoid copypasta Change-Id: I5f7dc4912aebd763da27984fcd5644a9419901bf diff --git a/src/lib/VSDStyles.cpp b/src/lib/VSDStyles.cpp index 8280ae4..ff29267 100644 --- a/src/lib/VSDStyles.cpp +++ b/src/lib/VSDStyles.cpp @@ -11,6 +11,42 @@ #include "VSDStyles.h" #include "VSDTypes.h" +namespace libvisio +{ + +namespace +{ + +template<typename T> +T getOptionalStyle(const std::map<unsigned, unsigned> &styleMasters, const std::map<unsigned, T> &styles, const unsigned styleIndex) +{ + T style; + if (MINUS_ONE == styleIndex) + return style; + std::stack<unsigned> styleIdStack; + styleIdStack.push(styleIndex); + while (true) + { + std::map<unsigned, unsigned>::const_iterator iter = styleMasters.find(styleIdStack.top()); + if (iter != styleMasters.end() && iter->second != MINUS_ONE) + styleIdStack.push(iter->second); + else + break; + } + while (!styleIdStack.empty()) + { + typename std::map<unsigned, T>::const_iterator iter = styles.find(styleIdStack.top()); + if (iter != styles.end()) + style.override(iter->second); + styleIdStack.pop(); + } + return style; +} + +} + +} + libvisio::VSDStyles::VSDStyles() : m_lineStyles(), m_fillStyles(), m_textBlockStyles(), m_charStyles(), m_paraStyles(), m_themeRefs(), m_lineStyleMasters(), m_fillStyleMasters(), m_textStyleMasters() @@ -94,52 +130,12 @@ void libvisio::VSDStyles::addTextStyleMaster(unsigned textStyleIndex, unsigned t libvisio::VSDOptionalLineStyle libvisio::VSDStyles::getOptionalLineStyle(unsigned lineStyleIndex) const { - VSDOptionalLineStyle lineStyle; - if (MINUS_ONE == lineStyleIndex) - return lineStyle; - std::stack<unsigned> styleIdStack; - styleIdStack.push(lineStyleIndex); - while (true) - { - std::map<unsigned, unsigned>::const_iterator iter = m_lineStyleMasters.find(styleIdStack.top()); - if (iter != m_lineStyleMasters.end() && iter->second != MINUS_ONE) - styleIdStack.push(iter->second); - else - break; - } - while (!styleIdStack.empty()) - { - std::map<unsigned, VSDOptionalLineStyle>::const_iterator iter = m_lineStyles.find(styleIdStack.top()); - if (iter != m_lineStyles.end()) - lineStyle.override(iter->second); - styleIdStack.pop(); - } - return lineStyle; + return getOptionalStyle(m_lineStyleMasters, m_lineStyles, lineStyleIndex); } libvisio::VSDOptionalFillStyle libvisio::VSDStyles::getOptionalFillStyle(unsigned fillStyleIndex) const { - VSDOptionalFillStyle fillStyle; - if (MINUS_ONE == fillStyleIndex) - return fillStyle; - std::stack<unsigned> styleIdStack; - styleIdStack.push(fillStyleIndex); - while (true) - { - std::map<unsigned, unsigned>::const_iterator iter = m_fillStyleMasters.find(styleIdStack.top()); - if (iter != m_fillStyleMasters.end() && iter->second != MINUS_ONE) - styleIdStack.push(iter->second); - else - break; - } - while (!styleIdStack.empty()) - { - std::map<unsigned, VSDOptionalFillStyle>::const_iterator iter = m_fillStyles.find(styleIdStack.top()); - if (iter != m_fillStyles.end()) - fillStyle.override(iter->second); - styleIdStack.pop(); - } - return fillStyle; + return getOptionalStyle(m_fillStyleMasters, m_fillStyles, fillStyleIndex); } libvisio::VSDFillStyle libvisio::VSDStyles::getFillStyle(unsigned fillStyleIndex) const @@ -151,77 +147,17 @@ libvisio::VSDFillStyle libvisio::VSDStyles::getFillStyle(unsigned fillStyleIndex libvisio::VSDOptionalTextBlockStyle libvisio::VSDStyles::getOptionalTextBlockStyle(unsigned textStyleIndex) const { - VSDOptionalTextBlockStyle textBlockStyle; - if (MINUS_ONE == textStyleIndex) - return textBlockStyle; - std::stack<unsigned> styleIdStack; - styleIdStack.push(textStyleIndex); - while (true) - { - std::map<unsigned, unsigned>::const_iterator iter = m_textStyleMasters.find(styleIdStack.top()); - if (iter != m_textStyleMasters.end() && iter->second != MINUS_ONE) - styleIdStack.push(iter->second); - else - break; - } - while (!styleIdStack.empty()) - { - std::map<unsigned, VSDOptionalTextBlockStyle>::const_iterator iter = m_textBlockStyles.find(styleIdStack.top()); - if (iter != m_textBlockStyles.end()) - textBlockStyle.override(iter->second); - styleIdStack.pop(); - } - return textBlockStyle; + return getOptionalStyle(m_textStyleMasters, m_textBlockStyles, textStyleIndex); } libvisio::VSDOptionalCharStyle libvisio::VSDStyles::getOptionalCharStyle(unsigned textStyleIndex) const { - VSDOptionalCharStyle charStyle; - if (MINUS_ONE == textStyleIndex) - return charStyle; - std::stack<unsigned> styleIdStack; - styleIdStack.push(textStyleIndex); - while (true) - { - std::map<unsigned, unsigned>::const_iterator iter = m_textStyleMasters.find(styleIdStack.top()); - if (iter != m_textStyleMasters.end() && iter->second != MINUS_ONE) - styleIdStack.push(iter->second); - else - break; - } - while (!styleIdStack.empty()) - { - std::map<unsigned, VSDOptionalCharStyle>::const_iterator iter = m_charStyles.find(styleIdStack.top()); - if (iter != m_charStyles.end()) - charStyle.override(iter->second); - styleIdStack.pop(); - } - return charStyle; + return getOptionalStyle(m_textStyleMasters, m_charStyles, textStyleIndex); } libvisio::VSDOptionalParaStyle libvisio::VSDStyles::getOptionalParaStyle(unsigned textStyleIndex) const { - VSDOptionalParaStyle paraStyle; - if (MINUS_ONE == textStyleIndex) - return paraStyle; - std::stack<unsigned> styleIdStack; - styleIdStack.push(textStyleIndex); - while (true) - { - std::map<unsigned, unsigned>::const_iterator iter = m_textStyleMasters.find(styleIdStack.top()); - if (iter != m_textStyleMasters.end() && iter->second != MINUS_ONE) - styleIdStack.push(iter->second); - else - break; - } - while (!styleIdStack.empty()) - { - std::map<unsigned, VSDOptionalParaStyle>::const_iterator iter = m_paraStyles.find(styleIdStack.top()); - if (iter != m_paraStyles.end()) - paraStyle.override(iter->second); - styleIdStack.pop(); - } - return paraStyle; + return getOptionalStyle(m_textStyleMasters, m_paraStyles, textStyleIndex); } libvisio::VSDOptionalThemeReference libvisio::VSDStyles::getOptionalThemeReference(unsigned styleIndex) const commit 730f1e72686b9101c380d90bbbf521c1ec53c532 Author: David Tardon <dtar...@redhat.com> Date: Thu Jul 16 16:17:43 2015 +0200 avoid endless loop when reading broken file Change-Id: I512d48b5ea25d3784f5b63725d4ff3b8ad648ccc diff --git a/src/lib/VSDStylesCollector.cpp b/src/lib/VSDStylesCollector.cpp index 4fc82f6..12e3643 100644 --- a/src/lib/VSDStylesCollector.cpp +++ b/src/lib/VSDStylesCollector.cpp @@ -402,8 +402,10 @@ void libvisio::VSDStylesCollector::endPage() m_groupXFormsSequence.push_back(m_groupXForms); m_groupMembershipsSequence.push_back(m_groupMemberships); - while (!m_groupShapeOrder.empty()) + bool changed = true; + while (!m_groupShapeOrder.empty() && changed) { + changed = false; for (std::list<unsigned>::iterator j = m_pageShapeOrder.begin(); j != m_pageShapeOrder.end();) { std::map<unsigned, std::list<unsigned> >::iterator iter = m_groupShapeOrder.find(*j++); @@ -411,6 +413,7 @@ void libvisio::VSDStylesCollector::endPage() { m_pageShapeOrder.splice(j, iter->second, iter->second.begin(), iter->second.end()); m_groupShapeOrder.erase(iter); + changed = true; } } } _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits