[Libreoffice-commits] libcdr.git: 15 commits - NEWS src/lib

David Tardon dtardon at redhat.com
Fri Sep 15 19:00:30 UTC 2017


 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 <dtardon at redhat.com>
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 <dtardon at redhat.com>
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 <dtardon at redhat.com>
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 <dtardon at redhat.com>
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 <dtardon at redhat.com>
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 <dtardon at redhat.com>
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 <dtardon at redhat.com>
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 <dtardon at redhat.com>
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 <dtardon at redhat.com>
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 <dtardon at redhat.com>
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 <dtardon at redhat.com>
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 <dtardon at redhat.com>
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 <dtardon at redhat.com>
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 <dtardon at redhat.com>
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 <dtardon at redhat.com>
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;


More information about the Libreoffice-commits mailing list