diff options
author | David Tardon <dtardon@redhat.com> | 2015-07-21 17:35:13 +0200 |
---|---|---|
committer | David Tardon <dtardon@redhat.com> | 2015-07-21 17:59:43 +0200 |
commit | 77a88f128700e434c093eb53590be63022edbdea (patch) | |
tree | 4dbbaae1f35e081ac85aa109e90fe09c3be1381c | |
parent | 2bdd7a9bfd1ed1606b7348602196f0a2baf0c099 (diff) |
avoid overflows when reading chunk records
Change-Id: Iea13e63e977348a449b68eca329146ae6f097197
-rw-r--r-- | src/lib/VSD5Parser.cpp | 16 |
1 files changed, 12 insertions, 4 deletions
diff --git a/src/lib/VSD5Parser.cpp b/src/lib/VSD5Parser.cpp index 00cbf06..79b638b 100644 --- a/src/lib/VSD5Parser.cpp +++ b/src/lib/VSD5Parser.cpp @@ -102,7 +102,12 @@ void libvisio::VSD5Parser::handleChunkRecords(librevenge::RVNGInputStream *input long endPosition = input->tell() + m_header.dataLength; input->seek(endPosition - 4, librevenge::RVNG_SEEK_SET); unsigned numRecords = readU16(input); + const long headerPosition = endPosition - 4 * (numRecords + 1); + if (headerPosition <= startPosition) // no records to read + return; unsigned endOffset = readU16(input); + if (long(endOffset) > (headerPosition - startPosition)) + endOffset = unsigned(headerPosition - startPosition); // try to read something anyway std::map<unsigned, ChunkHeader> records; input->seek(endPosition-4*(numRecords+1), librevenge::RVNG_SEEK_SET); unsigned i = 0; @@ -114,10 +119,13 @@ void libvisio::VSD5Parser::handleChunkRecords(librevenge::RVNGInputStream *input unsigned tmpStart = offset; while (tmpStart % 4) tmpStart++; - header.dataLength = endOffset - tmpStart; - header.level = m_header.level + 1; - records[tmpStart] = header; - endOffset = offset; + if (tmpStart < endOffset) + { + header.dataLength = endOffset - tmpStart; + header.level = m_header.level + 1; + records[tmpStart] = header; + endOffset = offset; + } } i = 0; for (std::map<unsigned, ChunkHeader>::iterator iter = records.begin(); iter != records.end(); ++iter) |