summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Tardon <dtardon@redhat.com>2017-09-16 10:21:47 +0200
committerDavid Tardon <dtardon@redhat.com>2017-09-16 10:23:03 +0200
commit44b4814516b60546a1268dbd5e4c23f5b85be116 (patch)
tree3e3544590d1e47544d87b73cf16ae102feb2de48
parentef2f52e891fd4c004f3a4491defe68e179a1a892 (diff)
cid#1219677 sanitize loop bound
Change-Id: Id1f3e84c21b31256e03da591d2f856818b084f1a
-rw-r--r--src/lib/FHParser.cpp2
-rw-r--r--src/lib/libfreehand_utils.cpp23
-rw-r--r--src/lib/libfreehand_utils.h2
3 files changed, 27 insertions, 0 deletions
diff --git a/src/lib/FHParser.cpp b/src/lib/FHParser.cpp
index 93488c7..0a39273 100644
--- a/src/lib/FHParser.cpp
+++ b/src/lib/FHParser.cpp
@@ -139,6 +139,8 @@ void libfreehand::FHParser::parseDictionary(librevenge::RVNGInputStream *input)
void libfreehand::FHParser::parseRecordList(librevenge::RVNGInputStream *input)
{
unsigned count = readU32(input);
+ if (count > getRemainingLength(input) / 2)
+ count = getRemainingLength(input) / 2;
for (unsigned i = 0; i < count; ++i)
{
unsigned id = readU16(input);
diff --git a/src/lib/libfreehand_utils.cpp b/src/lib/libfreehand_utils.cpp
index b12ff9e..439c457 100644
--- a/src/lib/libfreehand_utils.cpp
+++ b/src/lib/libfreehand_utils.cpp
@@ -127,6 +127,29 @@ int32_t libfreehand::readS32(librevenge::RVNGInputStream *input)
return (int32_t)readU32(input);
}
+unsigned long libfreehand::getRemainingLength(librevenge::RVNGInputStream *const input)
+{
+ if (!input || input->tell() < 0)
+ throw EndOfStreamException();
+
+ const long begin = input->tell();
+
+ if (input->seek(0, librevenge::RVNG_SEEK_END) != 0)
+ {
+ // librevenge::RVNG_SEEK_END does not work. Use the harder way.
+ while (!input->isEnd())
+ readU8(input);
+ }
+ const long end = input->tell();
+
+ if (input->seek(begin, librevenge::RVNG_SEEK_SET) != 0)
+ throw EndOfStreamException();
+
+ if (end < begin)
+ throw EndOfStreamException();
+ return static_cast<unsigned long>(end - begin);
+}
+
void libfreehand::_appendUTF16(librevenge::RVNGString &text, std::vector<unsigned short> &characters)
{
if (characters.empty())
diff --git a/src/lib/libfreehand_utils.h b/src/lib/libfreehand_utils.h
index ed57a00..ee975a7 100644
--- a/src/lib/libfreehand_utils.h
+++ b/src/lib/libfreehand_utils.h
@@ -61,6 +61,8 @@ int8_t readS8(librevenge::RVNGInputStream *input);
int16_t readS16(librevenge::RVNGInputStream *input);
int32_t readS32(librevenge::RVNGInputStream *input);
+unsigned long getRemainingLength(librevenge::RVNGInputStream *input);
+
void writeU16(librevenge::RVNGBinaryData &buffer, const int value);
void writeU32(librevenge::RVNGBinaryData &buffer, const int value);