[Libreoffice-commits] libcdr.git: 9 commits - src/lib
David Tardon
dtardon at redhat.com
Mon Aug 17 12:24:06 PDT 2015
src/lib/CDRContentCollector.cpp | 39 ++++++++++++++++++++++++++++-------
src/lib/CDRParser.cpp | 44 +++++++++++++++++++++++++++++++++-------
src/lib/libcdr_utils.cpp | 5 ++++
src/lib/libcdr_utils.h | 1
4 files changed, 74 insertions(+), 15 deletions(-)
New commits:
commit 518a4c52ff5bb841f74339ead214f544ec9f1dde
Author: David Tardon <dtardon at redhat.com>
Date: Mon Aug 17 20:49:45 2015 +0200
afl: avoid infinite loop with big numbers
... for which x - 1.0 == x due to rounding.
Change-Id: I98930077a5b47dc9e49ae6ac78e6b19177c7b56c
diff --git a/src/lib/CDRContentCollector.cpp b/src/lib/CDRContentCollector.cpp
index c3d1c22..ae51b44 100644
--- a/src/lib/CDRContentCollector.cpp
+++ b/src/lib/CDRContentCollector.cpp
@@ -27,6 +27,35 @@
#define DUMP_VECT 0
#endif
+namespace libcdr
+{
+namespace
+{
+
+/// Move the number into [0;1] range.
+void normalize(double &d)
+{
+ if (d < 0.0)
+ {
+ const double n = d + static_cast<unsigned long>(-d) + 1.0;
+ if ((n < 0.0) || (n > 1.0))
+ d = 0.0; // The number was too big, thus rounded. Just pick a value.
+ else
+ d = n;
+ }
+ if (d > 1.0)
+ {
+ const double n = d - static_cast<unsigned long>(d);
+ if ((n < 0.0) || (n > 1.0))
+ d = 0.0; // The number was too big, thus rounded. Just pick a value.
+ else
+ d = n;
+ }
+}
+
+}
+}
+
libcdr::CDRContentCollector::CDRContentCollector(libcdr::CDRParserState &ps, librevenge::RVNGDrawingInterface *painter) :
m_painter(painter), m_isDocumentStarted(false),
m_isPageProperties(false), m_isPageStarted(false), m_ignorePage(false),
@@ -773,19 +802,13 @@ void libcdr::CDRContentCollector::_fillProperties(librevenge::RVNGPropertyList &
if (m_fillTransforms.getTranslateX() != 0.0)
{
double xOffset = m_fillTransforms.getTranslateX() / m_currentFillStyle.imageFill.width;
- while (xOffset < 0.0)
- xOffset += 1.0;
- while (xOffset > 1.0)
- xOffset -= 1.0;
+ normalize(xOffset);
propList.insert("draw:fill-image-ref-point-x", xOffset, librevenge::RVNG_PERCENT);
}
if (m_fillTransforms.getTranslateY() != 0.0)
{
double yOffset = m_fillTransforms.getTranslateY() / m_currentFillStyle.imageFill.width;
- while (yOffset < 0.0)
- yOffset += 1.0;
- while (yOffset > 1.0)
- yOffset -= 1.0;
+ normalize(yOffset);
propList.insert("draw:fill-image-ref-point-y", 1.0 - yOffset, librevenge::RVNG_PERCENT);
}
}
commit e13f0f01b29d4487525998f9f0ff0dc895155f4b
Author: David Tardon <dtardon at redhat.com>
Date: Mon Aug 17 20:13:06 2015 +0200
afl: postpone alloc. till we get the data
Change-Id: Ic54f3b1e7e4f08d23a44ad65e855286ebf659fb2
diff --git a/src/lib/CDRParser.cpp b/src/lib/CDRParser.cpp
index 5decfdb..36fbe01 100644
--- a/src/lib/CDRParser.cpp
+++ b/src/lib/CDRParser.cpp
@@ -2360,12 +2360,12 @@ void libcdr::CDRParser::readWaldoBmpf(librevenge::RVNGInputStream *input, unsign
return;
input->seek(4, librevenge::RVNG_SEEK_CUR);
unsigned dataSize = readU32(input);
- std::vector<unsigned char> pattern(dataSize);
unsigned long tmpNumBytesRead = 0;
input->seek(24, librevenge::RVNG_SEEK_CUR); // TODO: is this empirical experience universal???
const unsigned char *tmpBuffer = input->read(dataSize, tmpNumBytesRead);
if (dataSize != tmpNumBytesRead)
return;
+ std::vector<unsigned char> pattern(dataSize);
memcpy(&pattern[0], tmpBuffer, dataSize);
m_collector->collectBmpf(id, width, height, pattern);
}
commit 334a6c12f3466828a3acb384d9b8bcac664b555f
Author: David Tardon <dtardon at redhat.com>
Date: Mon Aug 17 20:12:11 2015 +0200
afl: postpone alloc. till we get the data
Change-Id: I10412cb64fea97a7271abc8d1cd721c09cfad423
diff --git a/src/lib/CDRParser.cpp b/src/lib/CDRParser.cpp
index 4274165..5decfdb 100644
--- a/src/lib/CDRParser.cpp
+++ b/src/lib/CDRParser.cpp
@@ -2300,11 +2300,11 @@ void libcdr::CDRParser::readBmp(librevenge::RVNGInputStream *input, unsigned len
}
if (bmpsize == 0)
return;
- std::vector<unsigned char> bitmap(bmpsize);
unsigned long tmpNumBytesRead = 0;
const unsigned char *tmpBuffer = input->read(bmpsize, tmpNumBytesRead);
if (bmpsize != tmpNumBytesRead)
return;
+ std::vector<unsigned char> bitmap(bmpsize);
memcpy(&bitmap[0], tmpBuffer, bmpsize);
m_collector->collectBmp(imageId, colorModel, width, height, bpp, palette, bitmap);
}
commit 47d2e94deb1e633a15e31ffd3345895bcb80cdb6
Author: David Tardon <dtardon at redhat.com>
Date: Mon Aug 17 20:07:15 2015 +0200
afl: sanitize size before using it to alloc. a vector
Change-Id: I83086ec45babe6fc908b1aa658cdae06e8e241dc
diff --git a/src/lib/CDRParser.cpp b/src/lib/CDRParser.cpp
index 0b3d0f2..4274165 100644
--- a/src/lib/CDRParser.cpp
+++ b/src/lib/CDRParser.cpp
@@ -3066,6 +3066,8 @@ void libcdr::CDRParser::readTxsm16(librevenge::RVNGInputStream *input)
}
unsigned numChars = readU32(input);
+ if (numChars > getRemainingLength(input) / 8)
+ numChars = getRemainingLength(input) / 8;
std::vector<unsigned char> charDescriptions(numChars);
for (i=0; i<numChars; ++i)
{
commit 0fa9c7c9678a3d3ca797217db013e6290de7bcdb
Author: David Tardon <dtardon at redhat.com>
Date: Mon Aug 17 20:03:59 2015 +0200
afl: postpone alloc. till we get the data
Change-Id: I8b4471f3b8846a92f6b0e71e4e9372471fc2cb35
diff --git a/src/lib/CDRParser.cpp b/src/lib/CDRParser.cpp
index fbceb75..0b3d0f2 100644
--- a/src/lib/CDRParser.cpp
+++ b/src/lib/CDRParser.cpp
@@ -2338,11 +2338,11 @@ void libcdr::CDRParser::readBmpf(librevenge::RVNGInputStream *input, unsigned le
if (dataSize == 0)
return;
input->seek(length - dataSize - 28, librevenge::RVNG_SEEK_CUR);
- std::vector<unsigned char> pattern(dataSize);
unsigned long tmpNumBytesRead = 0;
const unsigned char *tmpBuffer = input->read(dataSize, tmpNumBytesRead);
if (dataSize != tmpNumBytesRead)
return;
+ std::vector<unsigned char> pattern(dataSize);
memcpy(&pattern[0], tmpBuffer, dataSize);
m_collector->collectBmpf(patternId, width, height, pattern);
}
commit 11a9e1bf12237d983f606826c444973e54bf879e
Author: David Tardon <dtardon at redhat.com>
Date: Mon Aug 17 19:37:30 2015 +0200
afl: sanitize size before using it to alloc. a vector
Change-Id: Ie4eac6f2c72f192716d48c2f593666b5d65a7cab
diff --git a/src/lib/CDRParser.cpp b/src/lib/CDRParser.cpp
index f438ed0..fbceb75 100644
--- a/src/lib/CDRParser.cpp
+++ b/src/lib/CDRParser.cpp
@@ -2951,6 +2951,9 @@ void libcdr::CDRParser::readTxsm(librevenge::RVNGInputStream *input, unsigned le
charStyles[2*i] = charStyle;
}
unsigned numChars = readU32(input);
+ const unsigned charSize = m_version >= 1200 ? 8 : 4;
+ if (numChars > getRemainingLength(input) / charSize)
+ numChars = getRemainingLength(input) / charSize;
std::vector<unsigned char> charDescriptions(numChars);
for (i=0; i<numChars; ++i)
{
commit 6775c795d1930ef8c585ed972c96b862aa8d31bc
Author: David Tardon <dtardon at redhat.com>
Date: Mon Aug 17 19:29:32 2015 +0200
afl: sanitize length before reading string
This avoids potential creation and manipulation of large buffers.
Change-Id: Iac2fa879a65bc2ec2a91c191398e4181f0aa9fd1
diff --git a/src/lib/CDRParser.cpp b/src/lib/CDRParser.cpp
index ef449fc..f438ed0 100644
--- a/src/lib/CDRParser.cpp
+++ b/src/lib/CDRParser.cpp
@@ -3368,6 +3368,13 @@ void libcdr::CDRParser::readParagraphText(librevenge::RVNGInputStream *input)
void libcdr::CDRParser::_readX6StyleString(librevenge::RVNGInputStream *input, unsigned length, libcdr::CDRCharacterStyle &style)
{
+ if (length > getRemainingLength(input))
+ {
+ length = getRemainingLength(input);
+ if ((m_version < 1700) && (length & 1))
+ --length; // the length must be even
+ }
+
std::vector<unsigned char> styleBuffer(length);
unsigned long numBytesRead = 0;
const unsigned char *tmpBuffer = input->read(length, numBytesRead);
diff --git a/src/lib/libcdr_utils.cpp b/src/lib/libcdr_utils.cpp
index d4b8116..e4f2fcc 100644
--- a/src/lib/libcdr_utils.cpp
+++ b/src/lib/libcdr_utils.cpp
@@ -295,6 +295,11 @@ unsigned long libcdr::getLength(librevenge::RVNGInputStream *const input)
return static_cast<unsigned long>(end);
}
+unsigned long libcdr::getRemainingLength(librevenge::RVNGInputStream *const input)
+{
+ return getLength(input) - static_cast<unsigned long>(input->tell());
+}
+
int libcdr::cdr_round(double d)
{
return (d>0) ? int(d+0.5) : int(d-0.5);
diff --git a/src/lib/libcdr_utils.h b/src/lib/libcdr_utils.h
index d26f06a..273b0e9 100644
--- a/src/lib/libcdr_utils.h
+++ b/src/lib/libcdr_utils.h
@@ -90,6 +90,7 @@ double readDouble(librevenge::RVNGInputStream *input, bool bigEndian=false);
double readFixedPoint(librevenge::RVNGInputStream *input, bool bigEndian=false);
unsigned long getLength(librevenge::RVNGInputStream *input);
+unsigned long getRemainingLength(librevenge::RVNGInputStream *input);
int cdr_round(double d);
commit bf32c68489887f2a1c10a93630bd3b6409ae9d8d
Author: David Tardon <dtardon at redhat.com>
Date: Mon Aug 17 19:16:47 2015 +0200
use stricter checks in Styd parser too
Change-Id: Ib28e586f8569d85264d3c64d2de661a527f97a8b
diff --git a/src/lib/CDRParser.cpp b/src/lib/CDRParser.cpp
index a501591..ef449fc 100644
--- a/src/lib/CDRParser.cpp
+++ b/src/lib/CDRParser.cpp
@@ -3256,12 +3256,21 @@ void libcdr::CDRParser::readStyd(librevenge::RVNGInputStream *input)
}
unsigned styleId = readU16(input);
long startPosition = input->tell();
+ const unsigned long maxLength = getLength(input);
+ if (startPosition >= long(maxLength))
+ return;
unsigned chunkLength = readUnsigned(input);
+ if ((chunkLength > maxLength) || (long(maxLength - chunkLength) < startPosition))
+ chunkLength = unsigned(maxLength - static_cast<unsigned long>(startPosition)); // sanitize length
unsigned numOfArgs = readUnsigned(input);
- if (numOfArgs > chunkLength / 4) // avoid extra big allocation in case of a broken file
- numOfArgs = chunkLength / 4;
unsigned startOfArgs = readUnsigned(input);
+ if (startOfArgs >= chunkLength)
+ return;
unsigned startOfArgTypes = readUnsigned(input);
+ if (startOfArgTypes >= chunkLength)
+ return;
+ if (numOfArgs > (chunkLength - startOfArgs) / 4) // avoid extra big allocation in case of a broken file
+ numOfArgs = (chunkLength - startOfArgs) / 4;
CDRCharacterStyle charStyle;
charStyle.m_parentId = readUnsigned(input);
std::vector<unsigned> argOffsets(numOfArgs, 0);
commit 5d204827bbcb4466d3845bb7655d74531094b901
Author: David Tardon <dtardon at redhat.com>
Date: Mon Aug 17 19:14:03 2015 +0200
use stricter checks in Loda parser too
Change-Id: I73f566ea7fab30d04510a0eb41bd6c314feff4b9
diff --git a/src/lib/CDRParser.cpp b/src/lib/CDRParser.cpp
index 101d9bf..a501591 100644
--- a/src/lib/CDRParser.cpp
+++ b/src/lib/CDRParser.cpp
@@ -2052,12 +2052,21 @@ void libcdr::CDRParser::readLoda(librevenge::RVNGInputStream *input, unsigned le
if (!_redirectX6Chunk(&input, length))
throw GenericException();
long startPosition = input->tell();
+ const unsigned long maxLength = getLength(input);
+ if (startPosition >= long(maxLength))
+ return;
+ if ((length > maxLength) || (long(maxLength - length) < startPosition))
+ length = unsigned(maxLength - static_cast<unsigned long>(startPosition)); // sanitize length
unsigned chunkLength = readUnsigned(input);
unsigned numOfArgs = readUnsigned(input);
- if (numOfArgs > length / 4) // avoid extra big allocation in case of a broken file
- numOfArgs = length / 4;
unsigned startOfArgs = readUnsigned(input);
+ if (startOfArgs >= length)
+ return;
unsigned startOfArgTypes = readUnsigned(input);
+ if (startOfArgTypes >= length)
+ return;
+ if (numOfArgs > (length - startOfArgs) / 4) // avoid extra big allocation in case of a broken file
+ numOfArgs = (length - startOfArgs) / 4;
unsigned chunkType = readUnsigned(input);
if (chunkType == 0x26)
m_collector->collectSpline();
More information about the Libreoffice-commits
mailing list