NEWS | 1 src/lib/CDRDocument.cpp | 104 ++++++++++++++++++++++-------------------------- src/lib/CMXParser.cpp | 66 ++++++++++++++++++++---------- src/lib/CMXParser.h | 5 +- src/lib/libcdr_utils.h | 5 ++ 5 files changed, 102 insertions(+), 79 deletions(-)
New commits: commit 20577bbcc4738de4e106503de36993f17295c79b Author: David Tardon <[email protected]> Date: Fri Sep 15 20:59:16 2017 +0200 mention coverity in news Change-Id: Id996a9d3aefb53332f7b0a4d0ccb8675180ce1dc diff --git a/NEWS b/NEWS index 6c5bb70..859b551 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,7 @@ libcdr 0.1.4 * Fix several issues found by oss-fuzz. * Require C++11 for build. +* Fix issues found by coverity. * Various code cleanups. libcdr 0.1.3 commit 934860e0ebf70b675d09d60d283d74cb092106d8 Author: David Tardon <[email protected]> Date: Fri Sep 15 20:50:55 2017 +0200 cid#1371578 sanitize loop bound Change-Id: I8b474571483c5ac248d88832a24857b041f25319 diff --git a/src/lib/CMXParser.cpp b/src/lib/CMXParser.cpp index fa3d494..625867d 100644 --- a/src/lib/CMXParser.cpp +++ b/src/lib/CMXParser.cpp @@ -1733,6 +1733,7 @@ void libcdr::CMXParser::readRdot(librevenge::RVNGInputStream *input) unsigned numRecords = readU16(input, m_bigEndian); CDR_DEBUG_MSG(("CMXParser::readRdot - numRecords %i\n", numRecords)); + sanitizeNumRecords(numRecords, m_precision, 2, 2, 1, getRemainingLength(input)); for (unsigned j = 1; j <= numRecords; ++j) { std::vector<unsigned> dots; @@ -1751,6 +1752,8 @@ void libcdr::CMXParser::readRdot(librevenge::RVNGInputStream *input) case CMX_Tag_DescrSection_Dash: { unsigned short dotCount = readU16(input, m_bigEndian); + if (dotCount > getRemainingLength(input) / 2) + dotCount = getRemainingLength(input) / 2; for (unsigned short i = 0; i < dotCount; ++i) dots.push_back(readU16(input, m_bigEndian)); break; @@ -1765,6 +1768,8 @@ void libcdr::CMXParser::readRdot(librevenge::RVNGInputStream *input) else if (m_precision == libcdr::PRECISION_16BIT) { unsigned short dotCount = readU16(input, m_bigEndian); + if (dotCount > getRemainingLength(input) / 2) + dotCount = getRemainingLength(input) / 2; for (unsigned short i = 0; i < dotCount; ++i) dots.push_back(readU16(input, m_bigEndian)); } commit af2b6648613d823efe299e35be386c05ceadf220 Author: David Tardon <[email protected]> Date: Fri Sep 15 20:46:16 2017 +0200 cid#1371577 sanitize loop bound Change-Id: I5c20f346fd92827a5c6aa923e2a6dfac15952f8e diff --git a/src/lib/CMXParser.cpp b/src/lib/CMXParser.cpp index 2fc72fe..fa3d494 100644 --- a/src/lib/CMXParser.cpp +++ b/src/lib/CMXParser.cpp @@ -1444,6 +1444,8 @@ bool libcdr::CMXParser::readFill(librevenge::RVNGInputStream *input) /* librevenge::RVNGString name = */ readString(input); /* librevenge::RVNGString stl = */ readString(input); unsigned short count = readU16(input, m_bigEndian); + if (count > getRemainingLength(input) / 8) + count = getRemainingLength(input) / 8; for (unsigned short i = 0; i < count; ++i) { readU16(input, m_bigEndian); commit ef10d79d0faed2a5d2578f52122449e78d3ffaf4 Author: David Tardon <[email protected]> Date: Fri Sep 15 20:42:47 2017 +0200 cid#1371576 sanitize loop bound Change-Id: I79a573b72be3894b596bff8979ff425727e0bdf9 diff --git a/src/lib/CMXParser.cpp b/src/lib/CMXParser.cpp index f4d89ad..2fc72fe 100644 --- a/src/lib/CMXParser.cpp +++ b/src/lib/CMXParser.cpp @@ -353,6 +353,8 @@ void libcdr::CMXParser::readIxmr(librevenge::RVNGInputStream *input) readU16(input, m_bigEndian); // Master ID readU16(input, m_bigEndian); // Size unsigned short recordCount = readU16(input, m_bigEndian); + if (recordCount > getRemainingLength(input) / 6) + recordCount = getRemainingLength(input) / 6; std::map<unsigned short, unsigned> offsets; for (unsigned short i = 1; i <= recordCount; ++i) { commit c6908fcfa1f421e5c2d99f945e33cb79ca896f13 Author: David Tardon <[email protected]> Date: Fri Sep 15 20:37:56 2017 +0200 cid#1371575 sanitize loop bound Change-Id: Ifbbc3ec2b68a5966401e4f7b499b1eefda06fac2 diff --git a/src/lib/CMXParser.cpp b/src/lib/CMXParser.cpp index 9ada58b..f4d89ad 100644 --- a/src/lib/CMXParser.cpp +++ b/src/lib/CMXParser.cpp @@ -1003,6 +1003,8 @@ libcdr::CDRBox libcdr::CMXParser::readBBox(librevenge::RVNGInputStream *input) librevenge::RVNGString libcdr::CMXParser::readString(librevenge::RVNGInputStream *input) { unsigned short count = readU16(input, m_bigEndian); + if (count > getRemainingLength(input)) + count = getRemainingLength(input); librevenge::RVNGString tmpString; for (unsigned short i = 0; i < count; ++i) tmpString.append((char)readU8(input, m_bigEndian)); commit 8d1ba8a93df9f103d53ad6fd77c0b45b885889c1 Author: David Tardon <[email protected]> Date: Fri Sep 15 20:35:34 2017 +0200 use smart pointers Change-Id: I62a8d1a30338d6750ec71fcbbb8c120bfac74081 diff --git a/src/lib/CDRDocument.cpp b/src/lib/CDRDocument.cpp index 9f56b63..d2fe9bf 100644 --- a/src/lib/CDRDocument.cpp +++ b/src/lib/CDRDocument.cpp @@ -60,42 +60,36 @@ Analyzes the content of an input stream to see if it can be parsed \return A value that indicates whether the content from the input stream is a Corel Draw Document that libcdr is able to parse */ -CDRAPI bool libcdr::CDRDocument::isSupported(librevenge::RVNGInputStream *input) +CDRAPI bool libcdr::CDRDocument::isSupported(librevenge::RVNGInputStream *input_) try { - if (!input) + if (!input_) return false; - librevenge::RVNGInputStream *tmpInput = input; - try + librevenge::RVNGInputStream *tmpInput = input_; + std::shared_ptr<librevenge::RVNGInputStream> input(input_, CDRDummyDeleter()); + + input->seek(0, librevenge::RVNG_SEEK_SET); + unsigned version = getCDRVersion(input.get()); + if (version) + return true; + if (tmpInput->isStructured()) { - input->seek(0, librevenge::RVNG_SEEK_SET); - unsigned version = getCDRVersion(input); - if (version) - return true; - if (tmpInput->isStructured()) - { - input = tmpInput->getSubStreamByName("content/riffData.cdr"); - if (!input) - input = tmpInput->getSubStreamByName("content/root.dat"); - } - tmpInput->seek(0, librevenge::RVNG_SEEK_SET); + input.reset(tmpInput->getSubStreamByName("content/riffData.cdr")); if (!input) - return false; - input->seek(0, librevenge::RVNG_SEEK_SET); - version = getCDRVersion(input); - if (input != tmpInput) - delete input; - input = tmpInput; - if (!version) - return false; - return true; + input.reset(tmpInput->getSubStreamByName("content/root.dat")); } - catch (...) - { - if (input != tmpInput) - delete input; + tmpInput->seek(0, librevenge::RVNG_SEEK_SET); + if (!input) return false; - } + input->seek(0, librevenge::RVNG_SEEK_SET); + version = getCDRVersion(input.get()); + if (!version) + return false; + return true; +} +catch (...) +{ + return false; } /** @@ -106,17 +100,19 @@ CDRPaintInterface class implementation when needed. This is often commonly calle \param painter A CDRPainterInterface implementation \return A value that indicates whether the parsing was successful */ -CDRAPI bool libcdr::CDRDocument::parse(librevenge::RVNGInputStream *input, librevenge::RVNGDrawingInterface *painter) +CDRAPI bool libcdr::CDRDocument::parse(librevenge::RVNGInputStream *input_, librevenge::RVNGDrawingInterface *painter) { - if (!input || !painter) + if (!input_ || !painter) return false; + std::shared_ptr<librevenge::RVNGInputStream> input(input_, CDRDummyDeleter()); + input->seek(0, librevenge::RVNG_SEEK_SET); bool retVal = false; unsigned version = 0; try { - version = getCDRVersion(input); + version = getCDRVersion(input.get()); if (version) { input->seek(0, librevenge::RVNG_SEEK_SET); @@ -124,9 +120,9 @@ CDRAPI bool libcdr::CDRDocument::parse(librevenge::RVNGInputStream *input, libre CDRStylesCollector stylesCollector(ps); CDRParser stylesParser(std::vector<librevenge::RVNGInputStream *>(), &stylesCollector); if (version >= 300) - retVal = stylesParser.parseRecords(input); + retVal = stylesParser.parseRecords(input.get()); else - retVal = stylesParser.parseWaldo(input); + retVal = stylesParser.parseWaldo(input.get()); if (ps.m_pages.empty()) retVal = false; if (retVal) @@ -135,9 +131,9 @@ CDRAPI bool libcdr::CDRDocument::parse(librevenge::RVNGInputStream *input, libre CDRContentCollector contentCollector(ps, painter); CDRParser contentParser(std::vector<librevenge::RVNGInputStream *>(), &contentCollector); if (version >= 300) - retVal = contentParser.parseRecords(input); + retVal = contentParser.parseRecords(input.get()); else - retVal = contentParser.parseWaldo(input); + retVal = contentParser.parseWaldo(input.get()); } return retVal; } @@ -148,7 +144,7 @@ CDRAPI bool libcdr::CDRDocument::parse(librevenge::RVNGInputStream *input, libre return false; } - librevenge::RVNGInputStream *tmpInput = input; + librevenge::RVNGInputStream *tmpInput = input_; std::vector<librevenge::RVNGInputStream *> dataStreams; try { @@ -156,11 +152,11 @@ CDRAPI bool libcdr::CDRDocument::parse(librevenge::RVNGInputStream *input, libre if (tmpInput->isStructured()) { tmpInput->seek(0, librevenge::RVNG_SEEK_SET); - input = tmpInput->getSubStreamByName("content/riffData.cdr"); + input.reset(tmpInput->getSubStreamByName("content/riffData.cdr")); if (!input) { tmpInput->seek(0, librevenge::RVNG_SEEK_SET); - input = tmpInput->getSubStreamByName("content/root.dat"); + input.reset(tmpInput->getSubStreamByName("content/root.dat")); if (input) { std::unique_ptr<librevenge::RVNGInputStream> tmpStream(tmpInput->getSubStreamByName("content/dataFileList.dat")); @@ -194,28 +190,26 @@ CDRAPI bool libcdr::CDRDocument::parse(librevenge::RVNGInputStream *input, libre dataStreams.push_back(tmpInput->getSubStreamByName(streamName.c_str())); } if (!input) - input = tmpInput; + input.reset(tmpInput, CDRDummyDeleter()); CDRParserState ps; - // libcdr extension to the getSubStreamByName. Will extract the first stream in the - // given directory - tmpInput->seek(0, librevenge::RVNG_SEEK_SET); - librevenge::RVNGInputStream *cmykProfile = tmpInput->getSubStreamByName("color/profiles/cmyk/"); - if (cmykProfile) { - ps.setColorTransform(cmykProfile); - delete cmykProfile; + // libcdr extension to the getSubStreamByName. Will extract the first stream in the + // given directory + tmpInput->seek(0, librevenge::RVNG_SEEK_SET); + std::unique_ptr<librevenge::RVNGInputStream> cmykProfile(tmpInput->getSubStreamByName("color/profiles/cmyk/")); + if (cmykProfile) + ps.setColorTransform(cmykProfile.get()); } - tmpInput->seek(0, librevenge::RVNG_SEEK_SET); - librevenge::RVNGInputStream *rgbProfile = tmpInput->getSubStreamByName("color/profiles/rgb/"); - if (rgbProfile) { - ps.setColorTransform(rgbProfile); - delete rgbProfile; + tmpInput->seek(0, librevenge::RVNG_SEEK_SET); + std::unique_ptr<librevenge::RVNGInputStream> rgbProfile(tmpInput->getSubStreamByName("color/profiles/rgb/")); + if (rgbProfile) + ps.setColorTransform(rgbProfile.get()); } CDRStylesCollector stylesCollector(ps); CDRParser stylesParser(dataStreams, &stylesCollector); input->seek(0, librevenge::RVNG_SEEK_SET); - retVal = stylesParser.parseRecords(input); + retVal = stylesParser.parseRecords(input.get()); if (ps.m_pages.empty()) retVal = false; if (retVal) @@ -223,15 +217,13 @@ CDRAPI bool libcdr::CDRDocument::parse(librevenge::RVNGInputStream *input, libre input->seek(0, librevenge::RVNG_SEEK_SET); CDRContentCollector contentCollector(ps, painter); CDRParser contentParser(dataStreams, &contentCollector); - retVal = contentParser.parseRecords(input); + retVal = contentParser.parseRecords(input.get()); } } catch (libcdr::EndOfStreamException const &) { retVal = false; } - if (input != tmpInput) - delete input; for (auto &dataStream : dataStreams) delete dataStream; return retVal; diff --git a/src/lib/libcdr_utils.h b/src/lib/libcdr_utils.h index b1d0b9f..4a69495 100644 --- a/src/lib/libcdr_utils.h +++ b/src/lib/libcdr_utils.h @@ -60,6 +60,11 @@ void debugPrint(const char *format, ...) CDR_ATTRIBUTE_PRINTF(1, 2); namespace libcdr { +struct CDRDummyDeleter +{ + void operator()(void *) const {} +}; + uint8_t readU8(librevenge::RVNGInputStream *input, bool bigEndian=false); uint16_t readU16(librevenge::RVNGInputStream *input, bool bigEndian=false); uint32_t readU32(librevenge::RVNGInputStream *input, bool bigEndian=false); commit a4716f518ed4d8d9e1deff8dba7988715ffb46dd Author: David Tardon <[email protected]> Date: Fri Sep 15 20:13:04 2017 +0200 use smart pointers Change-Id: I4420775d451cde8ccff88dffd25675dedd9d6df2 diff --git a/src/lib/CMXParser.cpp b/src/lib/CMXParser.cpp index 5c1ee24..9ada58b 100644 --- a/src/lib/CMXParser.cpp +++ b/src/lib/CMXParser.cpp @@ -72,14 +72,10 @@ libcdr::CMXParser::CMXParser(libcdr::CDRCollector *collector, CMXParserState &pa m_bigEndian(false), m_unit(0), m_scale(0.0), m_xmin(0.0), m_xmax(0.0), m_ymin(0.0), m_ymax(0.0), m_fillIndex(0), m_nextInstructionOffset(0), m_parserState(parserState), - m_currentImageInfo(), m_currentPattern(nullptr), m_currentBitmap(nullptr) {} + m_currentImageInfo(), m_currentPattern(), m_currentBitmap() {} libcdr::CMXParser::~CMXParser() { - if (m_currentPattern) - delete m_currentPattern; - if (m_currentBitmap) - delete m_currentBitmap; } bool libcdr::CMXParser::parseRecords(librevenge::RVNGInputStream *input, long size, unsigned level) @@ -1963,8 +1959,6 @@ void libcdr::CMXParser::readIxtl(librevenge::RVNGInputStream *input) input->seek(oldOffset, librevenge::RVNG_SEEK_SET); if (m_currentPattern && !m_currentPattern->pattern.empty()) m_collector->collectBmpf(j, m_currentPattern->width, m_currentPattern->height, m_currentPattern->pattern); - if (m_currentPattern) - delete m_currentPattern; m_currentPattern = nullptr; break; } @@ -2009,8 +2003,6 @@ void libcdr::CMXParser::readIxef(librevenge::RVNGInputStream *input) if (m_currentBitmap && !(m_currentBitmap->bitmap.empty())) m_collector->collectBmp(j, m_currentBitmap->colorModel, m_currentBitmap->width, m_currentBitmap->height, m_currentBitmap->bpp, m_currentBitmap->palette, m_currentBitmap->bitmap); - if (m_currentBitmap) - delete m_currentBitmap; m_currentBitmap = nullptr; } if (sizeInFile) @@ -2154,18 +2146,14 @@ void libcdr::CMXParser::readData(librevenge::RVNGInputStream *input) { unsigned fileSize = readU32(input, m_bigEndian); input->seek(8, librevenge::RVNG_SEEK_CUR); - if (m_currentPattern) - delete m_currentPattern; - m_currentPattern = new libcdr::CDRPattern(); + m_currentPattern.reset(new libcdr::CDRPattern()); readBmpPattern(m_currentPattern->width, m_currentPattern->height, m_currentPattern->pattern, fileSize - 14, input, m_bigEndian); } else if (0x52 == first && 0x49 == second) // RI { input->seek(12, librevenge::RVNG_SEEK_CUR); - if (m_currentBitmap) - delete m_currentBitmap; - m_currentBitmap = new libcdr::CDRBitmap(); + m_currentBitmap.reset(new libcdr::CDRBitmap()); readRImage(m_currentBitmap->colorModel, m_currentBitmap->width, m_currentBitmap->height, m_currentBitmap->bpp, m_currentBitmap->palette, m_currentBitmap->bitmap, input, m_bigEndian); @@ -2187,17 +2175,13 @@ void libcdr::CMXParser::readData(librevenge::RVNGInputStream *input) { unsigned fileSize = readU32(input, m_bigEndian); input->seek(8, librevenge::RVNG_SEEK_CUR); - if (m_currentPattern) - delete m_currentPattern; - m_currentPattern = new libcdr::CDRPattern(); + m_currentPattern.reset(new libcdr::CDRPattern()); readBmpPattern(m_currentPattern->width, m_currentPattern->height, m_currentPattern->pattern, fileSize - 14, input); } else if (0x52 == first && 0x49 == second) { input->seek(12, librevenge::RVNG_SEEK_CUR); // RI - if (m_currentBitmap) - delete m_currentBitmap; - m_currentBitmap = new libcdr::CDRBitmap(); + m_currentBitmap.reset(new libcdr::CDRBitmap()); readRImage(m_currentBitmap->colorModel, m_currentBitmap->width, m_currentBitmap->height, m_currentBitmap->bpp, m_currentBitmap->palette, m_currentBitmap->bitmap, input, m_bigEndian); diff --git a/src/lib/CMXParser.h b/src/lib/CMXParser.h index 47dc5ae..bdfc9fb 100644 --- a/src/lib/CMXParser.h +++ b/src/lib/CMXParser.h @@ -14,6 +14,7 @@ #include <iostream> #include <vector> #include <map> +#include <memory> #include <librevenge-stream/librevenge-stream.h> #include "CDRTypes.h" #include "CommonParser.h" @@ -168,8 +169,8 @@ private: unsigned m_nextInstructionOffset; CMXParserState &m_parserState; CMXImageInfo m_currentImageInfo; - CDRPattern *m_currentPattern; - CDRBitmap *m_currentBitmap; + std::unique_ptr<CDRPattern> m_currentPattern; + std::unique_ptr<CDRBitmap> m_currentBitmap; }; } // namespace libcdr commit f36fc7377df7ae9b07a85457e035dc122996d4c9 Author: David Tardon <[email protected]> Date: Fri Sep 15 20:09:23 2017 +0200 make this easier to use Change-Id: I3166bba6b137bce7a39c3d8a2648fa943654740a diff --git a/src/lib/CMXParser.cpp b/src/lib/CMXParser.cpp index 5d77181..5c1ee24 100644 --- a/src/lib/CMXParser.cpp +++ b/src/lib/CMXParser.cpp @@ -45,18 +45,26 @@ uint16_t readTagLength(librevenge::RVNGInputStream *const input, const bool bigE void sanitizeNumRecords( unsigned &numRecords, - const libcdr::CoordinatePrecision precision, const unsigned size16, const unsigned size32, const unsigned tags, + const libcdr::CoordinatePrecision precision, const unsigned size16, const unsigned size32, const unsigned long remainingLength) { unsigned recordSize = 1; if (precision == libcdr::PRECISION_16BIT) recordSize = size16; else if (precision == libcdr::PRECISION_32BIT) - recordSize = size32 + 3 * tags + 1; + recordSize = size32; if (numRecords > remainingLength / recordSize) numRecords = remainingLength / recordSize; } +void sanitizeNumRecords( + unsigned &numRecords, + const libcdr::CoordinatePrecision precision, const unsigned size16, const unsigned size32, const unsigned tags, + const unsigned long remainingLength) +{ + sanitizeNumRecords(numRecords, precision, size16, size32 + 3 * tags + 1, remainingLength); +} + } libcdr::CMXParser::CMXParser(libcdr::CDRCollector *collector, CMXParserState &parserState) @@ -1941,7 +1949,7 @@ void libcdr::CMXParser::readIxtl(librevenge::RVNGInputStream *input) return; } unsigned type = readU16(input, m_bigEndian); - sanitizeNumRecords(numRecords, m_precision, 4, 4 - 1, 0, getRemainingLength(input)); + sanitizeNumRecords(numRecords, m_precision, 4, 4, getRemainingLength(input)); for (unsigned j = 1; j <= numRecords; ++j) { switch (type) @@ -1980,7 +1988,7 @@ void libcdr::CMXParser::readIxef(librevenge::RVNGInputStream *input) unsigned numRecords = readU16(input, m_bigEndian); CDR_DEBUG_MSG(("CMXParser::readIxef - numRecords %i\n", numRecords)); - sanitizeNumRecords(numRecords, m_precision, 6, 8 - 1, 0, getRemainingLength(input)); + sanitizeNumRecords(numRecords, m_precision, 6, 8, getRemainingLength(input)); for (unsigned j = 1; j <= numRecords; ++j) { int sizeInFile(0); @@ -2019,7 +2027,7 @@ void libcdr::CMXParser::readIxpg(librevenge::RVNGInputStream *input) unsigned numRecords = readU16(input, m_bigEndian); CDR_DEBUG_MSG(("CMXParser::readIxpg - numRecords %i\n", numRecords)); - sanitizeNumRecords(numRecords, m_precision, 16, 18 - 1, 0, getRemainingLength(input)); + sanitizeNumRecords(numRecords, m_precision, 16, 18, getRemainingLength(input)); for (unsigned j = 1; j <= numRecords; ++j) { int sizeInFile(0); commit b51b2c3f55115ca61054fd8689c67939d4f3d999 Author: David Tardon <[email protected]> Date: Fri Sep 15 20:04:43 2017 +0200 cid#1371571 sanitize loop bound Change-Id: I4d943db17124508785044e0896f2ebe6e1258fb9 diff --git a/src/lib/CMXParser.cpp b/src/lib/CMXParser.cpp index 1f6c2d0..5d77181 100644 --- a/src/lib/CMXParser.cpp +++ b/src/lib/CMXParser.cpp @@ -1941,6 +1941,7 @@ void libcdr::CMXParser::readIxtl(librevenge::RVNGInputStream *input) return; } unsigned type = readU16(input, m_bigEndian); + sanitizeNumRecords(numRecords, m_precision, 4, 4 - 1, 0, getRemainingLength(input)); for (unsigned j = 1; j <= numRecords; ++j) { switch (type) commit e5301b388190e7562e4cb0984e94e55636029f7d Author: David Tardon <[email protected]> Date: Fri Sep 15 19:41:18 2017 +0200 cid#1371573 sanitize loop bound Change-Id: I590e6ef88f0489b8039e096e79b1c47a5edf3111 diff --git a/src/lib/CMXParser.cpp b/src/lib/CMXParser.cpp index 8188066..1f6c2d0 100644 --- a/src/lib/CMXParser.cpp +++ b/src/lib/CMXParser.cpp @@ -1979,6 +1979,7 @@ void libcdr::CMXParser::readIxef(librevenge::RVNGInputStream *input) unsigned numRecords = readU16(input, m_bigEndian); CDR_DEBUG_MSG(("CMXParser::readIxef - numRecords %i\n", numRecords)); + sanitizeNumRecords(numRecords, m_precision, 6, 8 - 1, 0, getRemainingLength(input)); for (unsigned j = 1; j <= numRecords; ++j) { int sizeInFile(0); commit 334cdf5093b093564bfc9f402ff46368b33ac091 Author: David Tardon <[email protected]> Date: Fri Sep 15 18:03:19 2017 +0200 cid#1371579 sanitize loop bound Change-Id: I1a34dcb7cd3de89e7ec484b759a9d81aefaf0dc6 diff --git a/src/lib/CMXParser.cpp b/src/lib/CMXParser.cpp index 202287d..8188066 100644 --- a/src/lib/CMXParser.cpp +++ b/src/lib/CMXParser.cpp @@ -2017,6 +2017,7 @@ void libcdr::CMXParser::readIxpg(librevenge::RVNGInputStream *input) unsigned numRecords = readU16(input, m_bigEndian); CDR_DEBUG_MSG(("CMXParser::readIxpg - numRecords %i\n", numRecords)); + sanitizeNumRecords(numRecords, m_precision, 16, 18 - 1, 0, getRemainingLength(input)); for (unsigned j = 1; j <= numRecords; ++j) { int sizeInFile(0); commit 0716f26b967a29dd8b4b843f092ede509c101d7e Author: David Tardon <[email protected]> Date: Fri Sep 15 18:00:21 2017 +0200 cid#1371574 sanitize loop bound Change-Id: I6cf6ee216bb4d722912164a7f4a7b4099017e887 diff --git a/src/lib/CMXParser.cpp b/src/lib/CMXParser.cpp index aa8666f..202287d 100644 --- a/src/lib/CMXParser.cpp +++ b/src/lib/CMXParser.cpp @@ -1672,6 +1672,7 @@ void libcdr::CMXParser::readRclr(librevenge::RVNGInputStream *input) unsigned numRecords = readU16(input, m_bigEndian); CDR_DEBUG_MSG(("CMXParser::readRclr - numRecords %i\n", numRecords)); + sanitizeNumRecords(numRecords, m_precision, 2, 2 + 0, 2, getRemainingLength(input)); for (unsigned j = 1; j <= numRecords; ++j) { CDR_DEBUG_MSG(("Color index %i\n", j)); commit fdfcdd5ec28ba5e500be0b44d86ac926d2d86213 Author: David Tardon <[email protected]> Date: Fri Sep 15 17:57:36 2017 +0200 cid#1371569 sanitize loop bound Change-Id: I7e8a16c14f3c83b5eb05931d282a7798231ed410 diff --git a/src/lib/CMXParser.cpp b/src/lib/CMXParser.cpp index ae2e23d..aa8666f 100644 --- a/src/lib/CMXParser.cpp +++ b/src/lib/CMXParser.cpp @@ -1878,6 +1878,7 @@ void libcdr::CMXParser::readRpen(librevenge::RVNGInputStream *input) unsigned numRecords = readU16(input, m_bigEndian); CDR_DEBUG_MSG(("CMXParser::readRpen - numRecords %i\n", numRecords)); + sanitizeNumRecords(numRecords, m_precision, 10, 12, 1, getRemainingLength(input)); for (unsigned j = 1; j <= numRecords; ++j) { CMXPen pen; commit ddeabcc6b0c4afe2629dc1f133adecac458ee2c8 Author: David Tardon <[email protected]> Date: Fri Sep 15 17:49:40 2017 +0200 cid#1371572 sanitize loop bound Change-Id: I5c4e36fac083f1e04301947cb52627c169fee719 diff --git a/src/lib/CMXParser.cpp b/src/lib/CMXParser.cpp index 3e957b7..ae2e23d 100644 --- a/src/lib/CMXParser.cpp +++ b/src/lib/CMXParser.cpp @@ -1772,6 +1772,7 @@ void libcdr::CMXParser::readRott(librevenge::RVNGInputStream *input) unsigned numRecords = readU16(input, m_bigEndian); CDR_DEBUG_MSG(("CMXParser::readRott - numRecords %i\n", numRecords)); + sanitizeNumRecords(numRecords, m_precision, 2, 2, 1, getRemainingLength(input)); for (unsigned j = 1; j <= numRecords; ++j) { CMXLineStyle lineStyle; commit 0778dd3ab809bcc2fce0dabafefcab32ed4caa65 Author: David Tardon <[email protected]> Date: Fri Sep 15 17:45:00 2017 +0200 cid#1371570 sanitize loop bound Change-Id: Icebb0e8844c37934c9f73b9064e0a2f95b986654 diff --git a/src/lib/CMXParser.cpp b/src/lib/CMXParser.cpp index 4d2e24f..3e957b7 100644 --- a/src/lib/CMXParser.cpp +++ b/src/lib/CMXParser.cpp @@ -43,6 +43,20 @@ uint16_t readTagLength(librevenge::RVNGInputStream *const input, const bool bigE return tagLength; } +void sanitizeNumRecords( + unsigned &numRecords, + const libcdr::CoordinatePrecision precision, const unsigned size16, const unsigned size32, const unsigned tags, + const unsigned long remainingLength) +{ + unsigned recordSize = 1; + if (precision == libcdr::PRECISION_16BIT) + recordSize = size16; + else if (precision == libcdr::PRECISION_32BIT) + recordSize = size32 + 3 * tags + 1; + if (numRecords > remainingLength / recordSize) + numRecords = remainingLength / recordSize; +} + } libcdr::CMXParser::CMXParser(libcdr::CDRCollector *collector, CMXParserState &parserState) @@ -1806,6 +1820,7 @@ void libcdr::CMXParser::readRotl(librevenge::RVNGInputStream *input) unsigned numRecords = readU16(input, m_bigEndian); CDR_DEBUG_MSG(("CMXParser::readRotl - numRecords %i\n", numRecords)); + sanitizeNumRecords(numRecords, m_precision, 12, 12, 1, getRemainingLength(input)); for (unsigned j = 1; j <= numRecords; ++j) { CMXOutline outline; _______________________________________________ Libreoffice-commits mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
