summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTibby Lickle <tibbylickle@gmail.com>2011-07-06 23:28:38 +0100
committerTibby Lickle <tibbylickle@gmail.com>2011-07-06 23:28:38 +0100
commit423ec413425e0c388de58681294a27d834e3eb93 (patch)
tree5ec244baa7f054a54c531d94b134533ed2d75865
parent73cbda5638cf5010817dc5242de746f61e5311a9 (diff)
Fix hangs if formula block is not present within NURBSTo/PolylineTo chunks
-rw-r--r--src/lib/VSDXParser.cpp27
1 files changed, 17 insertions, 10 deletions
diff --git a/src/lib/VSDXParser.cpp b/src/lib/VSDXParser.cpp
index a09e462..46d2c94 100644
--- a/src/lib/VSDXParser.cpp
+++ b/src/lib/VSDXParser.cpp
@@ -490,22 +490,25 @@ void libvisio::VSDXParser::readNURBSTo(WPXInputStream *input)
weights.push_back(d);
input->seek(11, WPX_SEEK_CUR); // Seek to blocks at offset 0x50 (80)
+ unsigned long chunkBytesRead = 0x50;
// Find formula block referring to cell E (cell 6)
unsigned cellRef = 0;
unsigned length = 0;
unsigned long inputPos = input->tell();
unsigned long bytesRead = 0;
- while (cellRef != 6 && !input->atEOS())
+ while (cellRef != 6 && !input->atEOS() && m_header.dataLength - chunkBytesRead > 4)
{
length = readU32(input);
input->seek(1, WPX_SEEK_CUR);
cellRef = readU8(input);
if (cellRef < 6)
input->seek(length - 6, WPX_SEEK_CUR);
+ chunkBytesRead += input->tell() - inputPos;
+ inputPos = input->tell();
}
- if (input->atEOS())
+ if (input->atEOS() || cellRef != 6)
return;
// Indicates whether it's a "simple" NURBS block with a static format
@@ -614,25 +617,29 @@ void libvisio::VSDXParser::readPolylineTo(WPXInputStream *input)
// Blocks start at 0x30
input->seek(0xb, WPX_SEEK_CUR);
+ unsigned long chunkBytesRead = 0x30;
// Find formula block referring to cell A (cell 2)
unsigned cellRef = 0;
unsigned length = 0;
- unsigned long bytesRead = 0;
- while (cellRef != 2 && !input->atEOS())
+ unsigned long inputPos = input->tell();
+ unsigned long blockBytesRead = 0;
+ while (cellRef != 2 && !input->atEOS() && m_header.dataLength - chunkBytesRead > 4)
{
length = readU32(input);
input->seek(1, WPX_SEEK_CUR);
cellRef = readU8(input);
if (cellRef < 2)
input->seek(length - 6, WPX_SEEK_CUR);
+ chunkBytesRead += input->tell() - inputPos;
+ inputPos = input->tell();
}
- if (input->atEOS())
+ if (input->atEOS() || cellRef != 2)
return;
- unsigned long inputPos = input->tell();
- bytesRead += 6;
+ inputPos = input->tell();
+ blockBytesRead += 6;
// Parse static first two parameters to function
unsigned xType = 0; unsigned yType = 0;
@@ -645,8 +652,8 @@ void libvisio::VSDXParser::readPolylineTo(WPXInputStream *input)
std::vector<std::pair<double, double> > points;
unsigned flag = readU8(input);
unsigned valueType = 0; // Holds parameter type indicator
- bytesRead += input->tell() - inputPos;
- while (flag != 0x81 && bytesRead < length)
+ blockBytesRead += input->tell() - inputPos;
+ while (flag != 0x81 && blockBytesRead < length)
{
inputPos = input->tell();
double x2 = 0; double y2 = 0;
@@ -665,7 +672,7 @@ void libvisio::VSDXParser::readPolylineTo(WPXInputStream *input)
points.push_back(std::pair<double, double>(x2, y2));
flag = readU8(input);
- bytesRead += input->tell() - inputPos;
+ blockBytesRead += input->tell() - inputPos;
}
m_geomList.addPolylineTo(m_header.id, m_header.level, x, y, xType, yType, points);