src/lib/MSPUBCollector.cpp | 323 ++++++++++++++++++++++----------------------- src/lib/MSPUBDocument.cpp | 55 ++++--- src/lib/MSPUBParser.cpp | 9 - src/lib/libmspub_utils.cpp | 12 + 4 files changed, 212 insertions(+), 187 deletions(-)
New commits: commit f797896cd97ea73a234d41aad2c44466e9f86f72 Author: David Tardon <dtar...@redhat.com> Date: Sat May 11 14:58:36 2013 +0200 avoid out-of-bounds access into vector diff --git a/src/lib/MSPUBCollector.cpp b/src/lib/MSPUBCollector.cpp index b8a96a9..c51af2e 100644 --- a/src/lib/MSPUBCollector.cpp +++ b/src/lib/MSPUBCollector.cpp @@ -563,176 +563,179 @@ boost::function<void(void)> libmspub::MSPUBCollector::paintShape(const ShapeInfo } double borderVertPadding = borderVertTotalPadding / (numImagesVert - 1); double borderHorizPadding = borderHorizTotalPadding / (numImagesHoriz - 1); - const BorderArtInfo &ba = m_borderImages[maybeBorderImg.get()]; - if (!ba.m_offsets.empty()) + if (maybeBorderImg.get() < m_borderImages.size()) { - WPXPropertyList baProps; - baProps.insert("draw:stroke", "none"); - baProps.insert("draw:fill", "solid"); - baProps.insert("draw:fill-color", "#ffffff"); - m_painter->setStyle(baProps, WPXPropertyListVector()); - WPXPropertyList topRectProps; - topRectProps.insert("svg:x", x); - topRectProps.insert("svg:y", y); - topRectProps.insert("svg:height", borderImgWidth); - topRectProps.insert("svg:width", width); - m_painter->drawRectangle(topRectProps); - WPXPropertyList rightRectProps; - rightRectProps.insert("svg:x", x + width - borderImgWidth); - rightRectProps.insert("svg:y", y); - rightRectProps.insert("svg:height", height); - rightRectProps.insert("svg:width", borderImgWidth); - m_painter->drawRectangle(rightRectProps); - WPXPropertyList botRectProps; - botRectProps.insert("svg:x", x); - botRectProps.insert("svg:y", y + height - borderImgWidth); - botRectProps.insert("svg:height", borderImgWidth); - botRectProps.insert("svg:width", width); - m_painter->drawRectangle(botRectProps); - WPXPropertyList leftRectProps; - leftRectProps.insert("svg:x", x); - leftRectProps.insert("svg:y", y); - leftRectProps.insert("svg:height", height); - leftRectProps.insert("svg:width", borderImgWidth); - m_painter->drawRectangle(leftRectProps); - std::vector<unsigned>::const_iterator iOffset = ba.m_offsets.begin(); - boost::optional<Color> oneBitColor; - if (!!info.m_lineBackColor) + const BorderArtInfo &ba = m_borderImages[maybeBorderImg.get()]; + if (!ba.m_offsets.empty()) { - oneBitColor = info.m_lineBackColor.get().getFinalColor(m_paletteColors); - } - // top left - unsigned iOrdOff = find(ba.m_offsetsOrdered.begin(), - ba.m_offsetsOrdered.end(), *iOffset) - ba.m_offsetsOrdered.begin(); - if (iOrdOff < ba.m_images.size()) - { - const BorderImgInfo &bi = ba.m_images[iOrdOff]; - writeImage(x, y, borderImgWidth, borderImgWidth, - bi.m_type, bi.m_imgBlob, oneBitColor); - } - if (iOffset + 1 != ba.m_offsets.end()) - { - ++iOffset; - } - // top - iOrdOff = find(ba.m_offsetsOrdered.begin(), - ba.m_offsetsOrdered.end(), *iOffset) - ba.m_offsetsOrdered.begin(); - if (iOrdOff < ba.m_images.size()) - { - const BorderImgInfo &bi = ba.m_images[iOrdOff]; - for (unsigned iTop = 1; iTop < numImagesHoriz - 1; ++iTop) + WPXPropertyList baProps; + baProps.insert("draw:stroke", "none"); + baProps.insert("draw:fill", "solid"); + baProps.insert("draw:fill-color", "#ffffff"); + m_painter->setStyle(baProps, WPXPropertyListVector()); + WPXPropertyList topRectProps; + topRectProps.insert("svg:x", x); + topRectProps.insert("svg:y", y); + topRectProps.insert("svg:height", borderImgWidth); + topRectProps.insert("svg:width", width); + m_painter->drawRectangle(topRectProps); + WPXPropertyList rightRectProps; + rightRectProps.insert("svg:x", x + width - borderImgWidth); + rightRectProps.insert("svg:y", y); + rightRectProps.insert("svg:height", height); + rightRectProps.insert("svg:width", borderImgWidth); + m_painter->drawRectangle(rightRectProps); + WPXPropertyList botRectProps; + botRectProps.insert("svg:x", x); + botRectProps.insert("svg:y", y + height - borderImgWidth); + botRectProps.insert("svg:height", borderImgWidth); + botRectProps.insert("svg:width", width); + m_painter->drawRectangle(botRectProps); + WPXPropertyList leftRectProps; + leftRectProps.insert("svg:x", x); + leftRectProps.insert("svg:y", y); + leftRectProps.insert("svg:height", height); + leftRectProps.insert("svg:width", borderImgWidth); + m_painter->drawRectangle(leftRectProps); + std::vector<unsigned>::const_iterator iOffset = ba.m_offsets.begin(); + boost::optional<Color> oneBitColor; + if (!!info.m_lineBackColor) { - double imgX = stretch ? - x + borderImgWidth + (iTop - 1) * stretchedImgWidth : - x + iTop * (borderImgWidth + borderHorizPadding); - writeImage(imgX, y, - borderImgWidth, stretchedImgWidth, - bi.m_type, bi.m_imgBlob, oneBitColor); + oneBitColor = info.m_lineBackColor.get().getFinalColor(m_paletteColors); } - } - if (iOffset + 1 != ba.m_offsets.end()) - { - ++iOffset; - } - // top right - iOrdOff = find(ba.m_offsetsOrdered.begin(), - ba.m_offsetsOrdered.end(), *iOffset) - ba.m_offsetsOrdered.begin(); - if (iOrdOff < ba.m_images.size()) - { - const BorderImgInfo &bi = ba.m_images[iOrdOff]; - writeImage(x + width - borderImgWidth, y, - borderImgWidth, borderImgWidth, - bi.m_type, bi.m_imgBlob, oneBitColor); - } - if (iOffset + 1 != ba.m_offsets.end()) - { - ++iOffset; - } - // right - iOrdOff = find(ba.m_offsetsOrdered.begin(), - ba.m_offsetsOrdered.end(), *iOffset) - ba.m_offsetsOrdered.begin(); - if (iOrdOff < ba.m_images.size()) - { - const BorderImgInfo &bi = ba.m_images[iOrdOff]; - for (unsigned iRight = 1; iRight < numImagesVert - 1; ++iRight) + // top left + unsigned iOrdOff = find(ba.m_offsetsOrdered.begin(), + ba.m_offsetsOrdered.end(), *iOffset) - ba.m_offsetsOrdered.begin(); + if (iOrdOff < ba.m_images.size()) + { + const BorderImgInfo &bi = ba.m_images[iOrdOff]; + writeImage(x, y, borderImgWidth, borderImgWidth, + bi.m_type, bi.m_imgBlob, oneBitColor); + } + if (iOffset + 1 != ba.m_offsets.end()) + { + ++iOffset; + } + // top + iOrdOff = find(ba.m_offsetsOrdered.begin(), + ba.m_offsetsOrdered.end(), *iOffset) - ba.m_offsetsOrdered.begin(); + if (iOrdOff < ba.m_images.size()) + { + const BorderImgInfo &bi = ba.m_images[iOrdOff]; + for (unsigned iTop = 1; iTop < numImagesHoriz - 1; ++iTop) + { + double imgX = stretch ? + x + borderImgWidth + (iTop - 1) * stretchedImgWidth : + x + iTop * (borderImgWidth + borderHorizPadding); + writeImage(imgX, y, + borderImgWidth, stretchedImgWidth, + bi.m_type, bi.m_imgBlob, oneBitColor); + } + } + if (iOffset + 1 != ba.m_offsets.end()) + { + ++iOffset; + } + // top right + iOrdOff = find(ba.m_offsetsOrdered.begin(), + ba.m_offsetsOrdered.end(), *iOffset) - ba.m_offsetsOrdered.begin(); + if (iOrdOff < ba.m_images.size()) + { + const BorderImgInfo &bi = ba.m_images[iOrdOff]; + writeImage(x + width - borderImgWidth, y, + borderImgWidth, borderImgWidth, + bi.m_type, bi.m_imgBlob, oneBitColor); + } + if (iOffset + 1 != ba.m_offsets.end()) + { + ++iOffset; + } + // right + iOrdOff = find(ba.m_offsetsOrdered.begin(), + ba.m_offsetsOrdered.end(), *iOffset) - ba.m_offsetsOrdered.begin(); + if (iOrdOff < ba.m_images.size()) + { + const BorderImgInfo &bi = ba.m_images[iOrdOff]; + for (unsigned iRight = 1; iRight < numImagesVert - 1; ++iRight) + { + double imgY = stretch ? + y + borderImgWidth + (iRight - 1) * stretchedImgHeight : + y + iRight * (borderImgWidth + borderVertPadding); + writeImage(x + width - borderImgWidth, + imgY, + stretchedImgHeight, borderImgWidth, + bi.m_type, bi.m_imgBlob, oneBitColor); + } + } + if (iOffset + 1 != ba.m_offsets.end()) + { + ++iOffset; + } + // bottom right + iOrdOff = find(ba.m_offsetsOrdered.begin(), + ba.m_offsetsOrdered.end(), *iOffset) - ba.m_offsetsOrdered.begin(); + if (iOrdOff < ba.m_images.size()) { - double imgY = stretch ? - y + borderImgWidth + (iRight - 1) * stretchedImgHeight : - y + iRight * (borderImgWidth + borderVertPadding); + const BorderImgInfo &bi = ba.m_images[iOrdOff]; writeImage(x + width - borderImgWidth, - imgY, - stretchedImgHeight, borderImgWidth, - bi.m_type, bi.m_imgBlob, oneBitColor); + y + height - borderImgWidth, + borderImgWidth, borderImgWidth, + bi.m_type, bi.m_imgBlob, oneBitColor); } - } - if (iOffset + 1 != ba.m_offsets.end()) - { - ++iOffset; - } - // bottom right - iOrdOff = find(ba.m_offsetsOrdered.begin(), - ba.m_offsetsOrdered.end(), *iOffset) - ba.m_offsetsOrdered.begin(); - if (iOrdOff < ba.m_images.size()) - { - const BorderImgInfo &bi = ba.m_images[iOrdOff]; - writeImage(x + width - borderImgWidth, - y + height - borderImgWidth, - borderImgWidth, borderImgWidth, - bi.m_type, bi.m_imgBlob, oneBitColor); - } - if (iOffset + 1 != ba.m_offsets.end()) - { - ++iOffset; - } - // bottom - iOrdOff = find(ba.m_offsetsOrdered.begin(), - ba.m_offsetsOrdered.end(), *iOffset) - ba.m_offsetsOrdered.begin(); - if (iOrdOff < ba.m_images.size()) - { - const BorderImgInfo &bi = ba.m_images[iOrdOff]; - for (unsigned iBot = 1; iBot < numImagesHoriz - 1; ++iBot) + if (iOffset + 1 != ba.m_offsets.end()) { - double imgX = stretch ? - x + width - borderImgWidth - iBot * stretchedImgWidth : - x + width - borderImgWidth - iBot * (borderImgWidth + borderHorizPadding); - writeImage( - imgX, y + height - borderImgWidth, - borderImgWidth, stretchedImgWidth, - bi.m_type, bi.m_imgBlob, oneBitColor); + ++iOffset; } - } - if (iOffset + 1 != ba.m_offsets.end()) - { - ++iOffset; - } - // bottom left - iOrdOff = find(ba.m_offsetsOrdered.begin(), - ba.m_offsetsOrdered.end(), *iOffset) - ba.m_offsetsOrdered.begin(); - if (iOrdOff < ba.m_images.size()) - { - const BorderImgInfo &bi = ba.m_images[iOrdOff]; - writeImage(x, y + height - borderImgWidth, - borderImgWidth, borderImgWidth, - bi.m_type, bi.m_imgBlob, oneBitColor); - } - if (iOffset + 1 != ba.m_offsets.end()) - { - ++iOffset; - } - // left - iOrdOff = find(ba.m_offsetsOrdered.begin(), - ba.m_offsetsOrdered.end(), *iOffset) - ba.m_offsetsOrdered.begin(); - if (iOrdOff < ba.m_images.size()) - { - const BorderImgInfo &bi = ba.m_images[iOrdOff]; - for (unsigned iLeft = 1; iLeft < numImagesVert - 1; ++iLeft) + // bottom + iOrdOff = find(ba.m_offsetsOrdered.begin(), + ba.m_offsetsOrdered.end(), *iOffset) - ba.m_offsetsOrdered.begin(); + if (iOrdOff < ba.m_images.size()) + { + const BorderImgInfo &bi = ba.m_images[iOrdOff]; + for (unsigned iBot = 1; iBot < numImagesHoriz - 1; ++iBot) + { + double imgX = stretch ? + x + width - borderImgWidth - iBot * stretchedImgWidth : + x + width - borderImgWidth - iBot * (borderImgWidth + borderHorizPadding); + writeImage( + imgX, y + height - borderImgWidth, + borderImgWidth, stretchedImgWidth, + bi.m_type, bi.m_imgBlob, oneBitColor); + } + } + if (iOffset + 1 != ba.m_offsets.end()) + { + ++iOffset; + } + // bottom left + iOrdOff = find(ba.m_offsetsOrdered.begin(), + ba.m_offsetsOrdered.end(), *iOffset) - ba.m_offsetsOrdered.begin(); + if (iOrdOff < ba.m_images.size()) + { + const BorderImgInfo &bi = ba.m_images[iOrdOff]; + writeImage(x, y + height - borderImgWidth, + borderImgWidth, borderImgWidth, + bi.m_type, bi.m_imgBlob, oneBitColor); + } + if (iOffset + 1 != ba.m_offsets.end()) + { + ++iOffset; + } + // left + iOrdOff = find(ba.m_offsetsOrdered.begin(), + ba.m_offsetsOrdered.end(), *iOffset) - ba.m_offsetsOrdered.begin(); + if (iOrdOff < ba.m_images.size()) { - double imgY = stretch ? - y + height - borderImgWidth - iLeft * stretchedImgHeight : - y + height - borderImgWidth - - iLeft * (borderImgWidth + borderVertPadding); - writeImage(x, imgY, stretchedImgHeight, borderImgWidth, - bi.m_type, bi.m_imgBlob, oneBitColor); + const BorderImgInfo &bi = ba.m_images[iOrdOff]; + for (unsigned iLeft = 1; iLeft < numImagesVert - 1; ++iLeft) + { + double imgY = stretch ? + y + height - borderImgWidth - iLeft * stretchedImgHeight : + y + height - borderImgWidth - + iLeft * (borderImgWidth + borderVertPadding); + writeImage(x, imgY, stretchedImgHeight, borderImgWidth, + bi.m_type, bi.m_imgBlob, oneBitColor); + } } } } commit 77f677c9d37adff32e7049adab545c09d6c38bbd Author: David Tardon <dtar...@redhat.com> Date: Sat May 11 14:43:17 2013 +0200 return early if there are no chars to append diff --git a/src/lib/libmspub_utils.cpp b/src/lib/libmspub_utils.cpp index 8f94578..e222341 100644 --- a/src/lib/libmspub_utils.cpp +++ b/src/lib/libmspub_utils.cpp @@ -358,6 +358,12 @@ void libmspub::readNBytes(WPXInputStream *input, unsigned long length, std::vect void libmspub::appendCharacters(WPXString &text, const std::vector<unsigned char> characters, const char *encoding) { + if (characters.empty()) + { + MSPUB_DEBUG_MSG(("Attempt to append 0 characters!")); + return; + } + UErrorCode status = U_ZERO_ERROR; UConverter *conv = NULL; conv = ucnv_open(encoding, &status); commit 7a334723b99797c3732e58d9e8c3b0f8cb5e97b6 Author: David Tardon <dtar...@redhat.com> Date: Sat May 11 14:37:13 2013 +0200 return immediately if there's nothing to read diff --git a/src/lib/libmspub_utils.cpp b/src/lib/libmspub_utils.cpp index d217139..8f94578 100644 --- a/src/lib/libmspub_utils.cpp +++ b/src/lib/libmspub_utils.cpp @@ -334,6 +334,12 @@ uint64_t libmspub::readU64(WPXInputStream *input) void libmspub::readNBytes(WPXInputStream *input, unsigned long length, std::vector<unsigned char> &out) { + if (length == 0) + { + MSPUB_DEBUG_MSG(("Attempt to read 0 bytes!")); + return; + } + unsigned long numBytesRead = 0; const unsigned char *tmpBuffer = input->read(length, numBytesRead); if (numBytesRead != length) commit 662925201db2b66a8ce96cadd693acd35c27d87d Author: David Tardon <dtar...@redhat.com> Date: Sat May 11 14:34:42 2013 +0200 ignore fonts with 0-length name diff --git a/src/lib/MSPUBParser.cpp b/src/lib/MSPUBParser.cpp index 3e49127..e59d059 100644 --- a/src/lib/MSPUBParser.cpp +++ b/src/lib/MSPUBParser.cpp @@ -1048,9 +1048,12 @@ void libmspub::MSPUBParser::parseFonts(WPXInputStream *input, const QuillChunkRe for (unsigned i = 0; i < numElements; ++i) { unsigned short nameLength = readU16(input); - std::vector<unsigned char> name; - readNBytes(input, nameLength * 2, name); - m_collector->addFont(name); + if (nameLength > 0) + { + std::vector<unsigned char> name; + readNBytes(input, nameLength * 2, name); + m_collector->addFont(name); + } readU32(input); } } commit 624622b0ab650fa8a7381de305730f31edbb3cf8 Author: David Tardon <dtar...@redhat.com> Date: Sat May 11 14:16:52 2013 +0200 do not let MSPUBDocument::parse throw diff --git a/src/lib/MSPUBDocument.cpp b/src/lib/MSPUBDocument.cpp index 8ac3545..f2f8668 100644 --- a/src/lib/MSPUBDocument.cpp +++ b/src/lib/MSPUBDocument.cpp @@ -134,40 +134,47 @@ WPGPaintInterface class implementation when needed. This is often commonly calle */ bool libmspub::MSPUBDocument::parse(::WPXInputStream *input, libwpg::WPGPaintInterface *painter) { - MSPUBCollector collector(painter); - input->seek(0, WPX_SEEK_SET); - boost::scoped_ptr<MSPUBParser> parser; - switch (getVersion(input)) - { - case MSPUB_2K: + try { - boost::scoped_ptr<WPXInputStream> quillStream(input->getDocumentOLEStream("Quill/QuillSub/CONTENTS")); - if (!quillStream) + MSPUBCollector collector(painter); + input->seek(0, WPX_SEEK_SET); + boost::scoped_ptr<MSPUBParser> parser; + switch (getVersion(input)) { - boost::scoped_ptr<MSPUBParser> tmp(new MSPUBParser97(input, &collector)); - parser.swap(tmp); + case MSPUB_2K: + { + boost::scoped_ptr<WPXInputStream> quillStream(input->getDocumentOLEStream("Quill/QuillSub/CONTENTS")); + if (!quillStream) + { + boost::scoped_ptr<MSPUBParser> tmp(new MSPUBParser97(input, &collector)); + parser.swap(tmp); + } + else + { + boost::scoped_ptr<MSPUBParser> tmp(new MSPUBParser2k(input, &collector)); + parser.swap(tmp); + } + break; } - else + case MSPUB_2K2: { - boost::scoped_ptr<MSPUBParser> tmp(new MSPUBParser2k(input, &collector)); + boost::scoped_ptr<MSPUBParser> tmp(new MSPUBParser(input, &collector)); parser.swap(tmp); + break; + } + default: + return false; + } + if (parser) + { + return parser->parse(); } - break; - } - case MSPUB_2K2: - { - boost::scoped_ptr<MSPUBParser> tmp(new MSPUBParser(input, &collector)); - parser.swap(tmp); - break; - } - default: return false; } - if (parser) + catch (...) { - return parser->parse(); + return false; } - return false; } /** _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits