src/lib/VSDContentCollector.cpp | 48 ++++++++++++++++++++----------- src/lib/VSDContentCollector.h | 4 +- src/lib/VSDParser.cpp | 61 ++++++++++++++++++++++++++-------------- 3 files changed, 74 insertions(+), 39 deletions(-)
New commits: commit c5780bf9208736870ebfd0e1177b769a15f3f7e0 Author: David Tardon <dtar...@redhat.com> Date: Sun May 12 08:36:38 2013 +0200 don't crash if there is no stencil diff --git a/src/lib/VSDParser.cpp b/src/lib/VSDParser.cpp index 4191b27..9fdb8be 100644 --- a/src/lib/VSDParser.cpp +++ b/src/lib/VSDParser.cpp @@ -369,7 +369,7 @@ void libvisio::VSDParser::handleStream(const Pointer &ptr, unsigned idx, unsigne _handleLevelChange(0); if (m_extractStencils) m_collector->endPage(); - else + else if (m_currentStencil) { m_stencils.addStencil(idx, *m_currentStencil); m_currentStencil = 0; @@ -382,7 +382,8 @@ void libvisio::VSDParser::handleStream(const Pointer &ptr, unsigned idx, unsigne if (m_isStencilStarted) { _handleLevelChange(0); - m_currentStencil->addStencilShape(m_shape.m_shapeId, m_shape); + if (m_currentStencil) + m_currentStencil->addStencilShape(m_shape.m_shapeId, m_shape); } break; default: @@ -1079,7 +1080,7 @@ void libvisio::VSDParser::readPageProps(WPXInputStream *input) input->seek(1, WPX_SEEK_CUR); scale /= readDouble(input); - if (m_isStencilStarted) + if (m_isStencilStarted && m_currentStencil) { m_currentStencil->m_shadowOffsetX = m_shadowOffsetX; m_currentStencil->m_shadowOffsetY = m_shadowOffsetY; commit 81663fbb1a705d329305ed7133b2df7a18e9747d Author: David Tardon <dtar...@redhat.com> Date: Sun May 12 08:25:26 2013 +0200 don't leave dangling pointer around diff --git a/src/lib/VSDParser.cpp b/src/lib/VSDParser.cpp index 3b41711..4191b27 100644 --- a/src/lib/VSDParser.cpp +++ b/src/lib/VSDParser.cpp @@ -670,6 +670,7 @@ void libvisio::VSDParser::_handleLevelChange(unsigned level) { _flushShape(); m_shape.clear(); + m_currentGeometryList = 0; } m_isShapeStarted = false; m_currentShapeLevel = 0; @@ -1121,6 +1122,7 @@ void libvisio::VSDParser::readShape(WPXInputStream *input) } m_shape.clear(); + m_currentGeometryList = 0; const VSDShape *tmpShape = m_stencils.getStencilShape(masterPage, masterShape); if (tmpShape) { commit e89d34da0d9378f0a71d86cbe38c54575f02b73d Author: David Tardon <dtar...@redhat.com> Date: Sun May 12 08:01:07 2013 +0200 avoid crash if m_currentGeometryList is null diff --git a/src/lib/VSDParser.cpp b/src/lib/VSDParser.cpp index e9c9009..3b41711 100644 --- a/src/lib/VSDParser.cpp +++ b/src/lib/VSDParser.cpp @@ -694,7 +694,8 @@ void libvisio::VSDParser::readEllipticalArcTo(WPXInputStream *input) input->seek(1, WPX_SEEK_CUR); double ecc = readDouble(input); // Eccentricity - m_currentGeometryList->addEllipticalArcTo(m_header.id, m_header.level, x3, y3, x2, y2, angle, ecc); + if (m_currentGeometryList) + m_currentGeometryList->addEllipticalArcTo(m_header.id, m_header.level, x3, y3, x2, y2, angle, ecc); } @@ -783,7 +784,8 @@ void libvisio::VSDParser::readEllipse(WPXInputStream *input) input->seek(1, WPX_SEEK_CUR); double ytop = readDouble(input); - m_currentGeometryList->addEllipse(m_header.id, m_header.level, cx, cy, xleft, yleft, xtop, ytop); + if (m_currentGeometryList) + m_currentGeometryList->addEllipse(m_header.id, m_header.level, cx, cy, xleft, yleft, xtop, ytop); } void libvisio::VSDParser::readLine(WPXInputStream *input) @@ -854,7 +856,8 @@ void libvisio::VSDParser::readGeomList(WPXInputStream *input) for (unsigned i = 0; i < (childrenListLength / sizeof(uint32_t)); i++) geometryOrder.push_back(readU32(input)); - m_currentGeometryList->setElementsOrder(geometryOrder); + if (m_currentGeometryList) + m_currentGeometryList->setElementsOrder(geometryOrder); } // We want the collectors to still get the level information @@ -921,7 +924,8 @@ void libvisio::VSDParser::readGeometry(WPXInputStream *input) bool noLine = (!!(geomFlags & 2)); bool noShow = (!!(geomFlags & 4)); - m_currentGeometryList->addGeometry(m_header.id, m_header.level, noFill, noLine, noShow); + if (m_currentGeometryList) + m_currentGeometryList->addGeometry(m_header.id, m_header.level, noFill, noLine, noShow); } void libvisio::VSDParser::readMoveTo(WPXInputStream *input) @@ -931,7 +935,8 @@ void libvisio::VSDParser::readMoveTo(WPXInputStream *input) input->seek(1, WPX_SEEK_CUR); double y = readDouble(input); - m_currentGeometryList->addMoveTo(m_header.id, m_header.level, x, y); + if (m_currentGeometryList) + m_currentGeometryList->addMoveTo(m_header.id, m_header.level, x, y); } void libvisio::VSDParser::readLineTo(WPXInputStream *input) @@ -941,7 +946,8 @@ void libvisio::VSDParser::readLineTo(WPXInputStream *input) input->seek(1, WPX_SEEK_CUR); double y = readDouble(input); - m_currentGeometryList->addLineTo(m_header.id, m_header.level, x, y); + if (m_currentGeometryList) + m_currentGeometryList->addLineTo(m_header.id, m_header.level, x, y); } void libvisio::VSDParser::readArcTo(WPXInputStream *input) @@ -953,7 +959,8 @@ void libvisio::VSDParser::readArcTo(WPXInputStream *input) input->seek(1, WPX_SEEK_CUR); double bow = readDouble(input); - m_currentGeometryList->addArcTo(m_header.id, m_header.level, x2, y2, bow); + if (m_currentGeometryList) + m_currentGeometryList->addArcTo(m_header.id, m_header.level, x2, y2, bow); } void libvisio::VSDParser::readXFormData(WPXInputStream *input) @@ -1153,7 +1160,8 @@ void libvisio::VSDParser::readNURBSTo(WPXInputStream *input) input->seek(3, WPX_SEEK_CUR); unsigned dataId = readU32(input); - m_currentGeometryList->addNURBSTo(m_header.id, m_header.level, x, y, knot, knotPrev, weight, weightPrev, dataId); + if (m_currentGeometryList) + m_currentGeometryList->addNURBSTo(m_header.id, m_header.level, x, y, knot, knotPrev, weight, weightPrev, dataId); return; } @@ -1281,12 +1289,14 @@ void libvisio::VSDParser::readNURBSTo(WPXInputStream *input) knotVector.push_back(lastKnot); weights.push_back(weight); - m_currentGeometryList->addNURBSTo(m_header.id, m_header.level, x, y, xType, - yType, degree, controlPoints, knotVector, weights); + if (m_currentGeometryList) + m_currentGeometryList->addNURBSTo(m_header.id, m_header.level, x, y, xType, + yType, degree, controlPoints, knotVector, weights); } else // No formula found, use line { - m_currentGeometryList->addLineTo(m_header.id, m_header.level, x, y); + if (m_currentGeometryList) + m_currentGeometryList->addLineTo(m_header.id, m_header.level, x, y); } } @@ -1305,7 +1315,8 @@ void libvisio::VSDParser::readPolylineTo(WPXInputStream *input) input->seek(3, WPX_SEEK_CUR); unsigned dataId = readU32(input); - m_currentGeometryList->addPolylineTo(m_header.id, m_header.level, x, y, dataId); + if (m_currentGeometryList) + m_currentGeometryList->addPolylineTo(m_header.id, m_header.level, x, y, dataId); return; } @@ -1377,12 +1388,14 @@ void libvisio::VSDParser::readPolylineTo(WPXInputStream *input) blockBytesRead += input->tell() - inputPos; } - m_currentGeometryList->addPolylineTo(m_header.id, m_header.level, x, y, xType, - yType, points); + if (m_currentGeometryList) + m_currentGeometryList->addPolylineTo(m_header.id, m_header.level, x, y, xType, + yType, points); } else { - m_currentGeometryList->addLineTo(m_header.id, m_header.level, x, y); + if (m_currentGeometryList) + m_currentGeometryList->addLineTo(m_header.id, m_header.level, x, y); } } @@ -1396,7 +1409,8 @@ void libvisio::VSDParser::readInfiniteLine(WPXInputStream *input) double x2 = readDouble(input); input->seek(1, WPX_SEEK_CUR); double y2 = readDouble(input); - m_currentGeometryList->addInfiniteLine(m_header.id, m_header.level, x1, y1, x2, y2); + if (m_currentGeometryList) + m_currentGeometryList->addInfiniteLine(m_header.id, m_header.level, x1, y1, x2, y2); } void libvisio::VSDParser::readShapeData(WPXInputStream *input) @@ -1475,7 +1489,8 @@ void libvisio::VSDParser::readSplineStart(WPXInputStream *input) double lastKnot = readDouble(input); unsigned degree = readU8(input); - m_currentGeometryList->addSplineStart(m_header.id, m_header.level, x, y, secondKnot, firstKnot, lastKnot, degree); + if (m_currentGeometryList) + m_currentGeometryList->addSplineStart(m_header.id, m_header.level, x, y, secondKnot, firstKnot, lastKnot, degree); } void libvisio::VSDParser::readSplineKnot(WPXInputStream *input) @@ -1486,7 +1501,8 @@ void libvisio::VSDParser::readSplineKnot(WPXInputStream *input) double y = readDouble(input); double knot = readDouble(input); - m_currentGeometryList->addSplineKnot(m_header.id, m_header.level, x, y, knot); + if (m_currentGeometryList) + m_currentGeometryList->addSplineKnot(m_header.id, m_header.level, x, y, knot); } void libvisio::VSDParser::readNameList(WPXInputStream * /* input */) commit 012166de9e82ced394138550d1c92e20df7cb504 Author: David Tardon <dtar...@redhat.com> Date: Sun May 12 07:39:17 2013 +0200 use iterator to point to the current style This avoids crash if one (or both) of groupMembershipsSequence and documentPageShapeOrders come in empty (when reading broken file. I do not know if it can happen legitimately. Probably not). Also, the old code actually overwrites the first elements of the two vectors on each change, because assignment to a reference changes the object the reference refers to. While it is probably harmless, as we do not need the old styles again, it does not "feel" right. diff --git a/src/lib/VSDContentCollector.cpp b/src/lib/VSDContentCollector.cpp index 0f80948..b1f83d7 100644 --- a/src/lib/VSDContentCollector.cpp +++ b/src/lib/VSDContentCollector.cpp @@ -89,11 +89,12 @@ libvisio::VSDContentCollector::VSDContentCollector( m_currentForeignData(), m_currentOLEData(), m_currentForeignProps(), m_currentShapeId(0), m_foreignType((unsigned)-1), m_foreignFormat(0), m_foreignOffsetX(0.0), m_foreignOffsetY(0.0), m_foreignWidth(0.0), m_foreignHeight(0.0), m_noLine(false), m_noFill(false), m_noShow(false), m_fonts(), - m_currentLevel(0), m_isShapeStarted(false), m_groupMemberships(groupMembershipsSequence[0]), + m_currentLevel(0), m_isShapeStarted(false), m_groupXFormsSequence(groupXFormsSequence), m_groupMembershipsSequence(groupMembershipsSequence), + m_groupMemberships(m_groupMembershipsSequence.begin()), m_currentPageNumber(0), m_shapeOutputDrawing(0), m_shapeOutputText(0), m_pageOutputDrawing(), m_pageOutputText(), m_documentPageShapeOrders(documentPageShapeOrders), - m_pageShapeOrder(documentPageShapeOrders[0]), m_isFirstGeometry(true), m_NURBSData(), m_polylineData(), + m_pageShapeOrder(m_documentPageShapeOrders.begin()), m_isFirstGeometry(true), m_NURBSData(), m_polylineData(), m_textStream(), m_names(), m_stencilNames(), m_fields(), m_stencilFields(), m_fieldIndex(0), m_textFormat(VSD_TEXT_ANSI), m_charFormats(), m_paraFormats(), m_lineStyle(), m_fillStyle(), m_textBlockStyle(), m_defaultCharStyle(), m_defaultParaStyle(), m_currentStyleSheet(0), m_styles(styles), @@ -713,13 +714,14 @@ void libvisio::VSDContentCollector::_flushCurrentForeignData() void libvisio::VSDContentCollector::_flushCurrentPage() { - if (!m_pageShapeOrder.empty()) + if (m_pageShapeOrder != m_documentPageShapeOrders.end() && !m_pageShapeOrder->empty() && + m_groupMemberships != m_groupMembershipsSequence.end()) { std::stack<std::pair<unsigned, VSDOutputElementList> > groupTextStack; - for (std::list<unsigned>::iterator iterList = m_pageShapeOrder.begin(); iterList != m_pageShapeOrder.end(); ++iterList) + for (std::list<unsigned>::iterator iterList = m_pageShapeOrder->begin(); iterList != m_pageShapeOrder->end(); ++iterList) { - std::map<unsigned, unsigned>::iterator iterGroup = m_groupMemberships.find(*iterList); - if (iterGroup == m_groupMemberships.end()) + std::map<unsigned, unsigned>::iterator iterGroup = m_groupMemberships->find(*iterList); + if (iterGroup == m_groupMemberships->end()) { while (!groupTextStack.empty()) { @@ -1620,10 +1622,17 @@ void libvisio::VSDContentCollector::transformPoint(double &x, double &y, XForm * } else break; - std::map<unsigned, unsigned>::iterator iter = m_groupMemberships.find(shapeId); - if (iter != m_groupMemberships.end() && shapeId != iter->second) - shapeId = iter->second; - else + bool shapeFound = false; + if (m_groupMemberships != m_groupMembershipsSequence.end()) + { + std::map<unsigned, unsigned>::iterator iter = m_groupMemberships->find(shapeId); + if (iter != m_groupMemberships->end() && shapeId != iter->second) + { + shapeId = iter->second; + shapeFound = true; + } + } + if (!shapeFound) break; } y = m_pageHeight - y; @@ -1670,10 +1679,17 @@ void libvisio::VSDContentCollector::transformFlips(bool &flipX, bool &flipY) } else break; - std::map<unsigned, unsigned>::iterator iter = m_groupMemberships.find(shapeId); - if (iter != m_groupMemberships.end() && shapeId != iter->second) - shapeId = iter->second; - else + bool shapeFound = false; + if (m_groupMemberships != m_groupMembershipsSequence.end()) + { + std::map<unsigned, unsigned>::iterator iter = m_groupMemberships->find(shapeId); + if (iter != m_groupMemberships->end() && shapeId != iter->second) + { + shapeId = iter->second; + shapeFound = true; + } + } + if (!shapeFound) break; } } @@ -2537,9 +2553,9 @@ void libvisio::VSDContentCollector::startPage(unsigned pageId) if (m_groupXFormsSequence.size() >= m_currentPageNumber) m_groupXForms = m_groupXFormsSequence.size() > m_currentPageNumber-1 ? &m_groupXFormsSequence[m_currentPageNumber-1] : 0; if (m_groupMembershipsSequence.size() >= m_currentPageNumber) - m_groupMemberships = m_groupMembershipsSequence[m_currentPageNumber-1]; + m_groupMemberships = m_groupMembershipsSequence.begin() + (m_currentPageNumber-1); if (m_documentPageShapeOrders.size() >= m_currentPageNumber) - m_pageShapeOrder = m_documentPageShapeOrders[m_currentPageNumber-1]; + m_pageShapeOrder = m_documentPageShapeOrders.begin() + (m_currentPageNumber-1); m_currentPage = libvisio::VSDPage(); m_currentPage.m_currentPageID = pageId; m_isPageStarted = true; diff --git a/src/lib/VSDContentCollector.h b/src/lib/VSDContentCollector.h index df4e475..d0667e6 100644 --- a/src/lib/VSDContentCollector.h +++ b/src/lib/VSDContentCollector.h @@ -252,15 +252,15 @@ private: std::map<unsigned short, VSDFont> m_fonts; unsigned m_currentLevel; bool m_isShapeStarted; - std::map<unsigned, unsigned> &m_groupMemberships; std::vector<std::map<unsigned, XForm> > &m_groupXFormsSequence; std::vector<std::map<unsigned, unsigned> > &m_groupMembershipsSequence; + std::vector<std::map<unsigned, unsigned> >::iterator m_groupMemberships; unsigned m_currentPageNumber; VSDOutputElementList *m_shapeOutputDrawing, *m_shapeOutputText; std::map<unsigned, VSDOutputElementList> m_pageOutputDrawing; std::map<unsigned, VSDOutputElementList> m_pageOutputText; std::vector<std::list<unsigned> > &m_documentPageShapeOrders; - std::list<unsigned> &m_pageShapeOrder; + std::vector<std::list<unsigned> >::iterator m_pageShapeOrder; bool m_isFirstGeometry; std::map<unsigned, NURBSData> m_NURBSData; _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits