Commit 4e8964c6 authored by darin@apple.com's avatar darin@apple.com

2009-04-11 Darin Adler <darin@apple.com>

        Reviewed by Dan Bernstein.

        Fix problem when encoding history files with duplicate integer arrays near the end of the file.
        This results in an assertion failure, and if assertions are turned off, corrupted output.

        When writing an integer array it's important not to add an object reference to the
        aggregate buffer. The writing of the array does not depend on the aggregate buffer. But,
        more importantly, it's possible this instance integer array is a duplicate and won't be
        written out. If so, there's no guarantee there's enough space in the aggregate buffer to
        store the object references (the references will be ignored). In some cases the aggregate
        buffer can then overrun the data being written; normally this is prevented by the fact that
        the data being written will include a copy of the aggregate buffer.

        Also removed a bit of unneeded dead code to handle the integer -1.

        * platform/cf/BinaryPropertyList.cpp:
        (WebCore::BinaryPropertyListPlan::BinaryPropertyListPlan): Removed unneeded
        m_integerNegativeOneObjectReference, since property lists support only non-negative integers.
        (WebCore::BinaryPropertyListPlan::writeInteger): Removed support for
        m_integerNegativeOneObjectReference.
        (WebCore::BinaryPropertyListPlan::integerObjectReference): Ditto.
        (WebCore::BinaryPropertyListSerializer::writeIntegerWithoutAddingAggregateObjectReference):
        Added. Factored out most of writeInteger, for use in writeIntegerArray, without calling
        addAggregateObjectReference.
        (WebCore::BinaryPropertyListSerializer::writeInteger): Changed to call the new
        writeIntegerWithoutAddingAggregateObjectReference function.
        (WebCore::BinaryPropertyListSerializer::writeIntegerArray): Call the new
        writeIntegerWithoutAddingAggregateObjectReference function and therefore remove the
        code to save and restore m_currentAggregateBufferByte, which is no longer needed.



git-svn-id: svn://svn.chromium.org/blink/trunk@42432 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent 3cb1e207
2009-04-11 Darin Adler <darin@apple.com>
Reviewed by Dan Bernstein.
Fix problem when encoding history files with duplicate integer arrays near the end of the file.
This results in an assertion failure, and if assertions are turned off, corrupted output.
When writing an integer array it's important not to add an object reference to the
aggregate buffer. The writing of the array does not depend on the aggregate buffer. But,
more importantly, it's possible this instance integer array is a duplicate and won't be
written out. If so, there's no guarantee there's enough space in the aggregate buffer to
store the object references (the references will be ignored). In some cases the aggregate
buffer can then overrun the data being written; normally this is prevented by the fact that
the data being written will include a copy of the aggregate buffer.
Also removed a bit of unneeded dead code to handle the integer -1.
* platform/cf/BinaryPropertyList.cpp:
(WebCore::BinaryPropertyListPlan::BinaryPropertyListPlan): Removed unneeded
m_integerNegativeOneObjectReference, since property lists support only non-negative integers.
(WebCore::BinaryPropertyListPlan::writeInteger): Removed support for
m_integerNegativeOneObjectReference.
(WebCore::BinaryPropertyListPlan::integerObjectReference): Ditto.
(WebCore::BinaryPropertyListSerializer::writeIntegerWithoutAddingAggregateObjectReference):
Added. Factored out most of writeInteger, for use in writeIntegerArray, without calling
addAggregateObjectReference.
(WebCore::BinaryPropertyListSerializer::writeInteger): Changed to call the new
writeIntegerWithoutAddingAggregateObjectReference function.
(WebCore::BinaryPropertyListSerializer::writeIntegerArray): Call the new
writeIntegerWithoutAddingAggregateObjectReference function and therefore remove the
code to save and restore m_currentAggregateBufferByte, which is no longer needed.
2009-04-13 Holger Hans Peter Freyther <zecke@selfish.org>
Unreviewed Qt build fix.
......@@ -145,7 +145,6 @@ private:
typedef HashMap<IntegerArray, ObjectReference, IntegerArrayHash, IntegerArrayHashTraits> IntegerArrayMap;
ObjectReference m_booleanTrueObjectReference;
ObjectReference m_integerNegativeOneObjectReference;
ObjectReference m_integerZeroObjectReference;
HashMap<int, ObjectReference> m_integers;
HashMap<String, ObjectReference> m_strings;
......@@ -161,7 +160,6 @@ private:
BinaryPropertyListPlan::BinaryPropertyListPlan(BinaryPropertyListWriter& client)
: m_booleanTrueObjectReference(invalidObjectReference())
, m_integerNegativeOneObjectReference(invalidObjectReference())
, m_integerZeroObjectReference(invalidObjectReference())
, m_currentObjectReference(0)
, m_currentAggregateSize(0)
......@@ -200,21 +198,13 @@ void BinaryPropertyListPlan::writeInteger(int integer)
{
ASSERT(integer >= 0);
++m_currentAggregateSize;
switch (integer) {
case -1:
if (m_integerNegativeOneObjectReference != invalidObjectReference())
return;
m_integerNegativeOneObjectReference = m_currentObjectReference;
break;
case 0:
if (m_integerZeroObjectReference != invalidObjectReference())
return;
m_integerZeroObjectReference = m_currentObjectReference;
break;
default:
if (!m_integers.add(integer, m_currentObjectReference).second)
return;
break;
if (!integer) {
if (m_integerZeroObjectReference != invalidObjectReference())
return;
m_integerZeroObjectReference = m_currentObjectReference;
} else {
if (!m_integers.add(integer, m_currentObjectReference).second)
return;
}
++m_currentObjectReference;
m_byteCount += integerByteCount(integer);
......@@ -330,17 +320,13 @@ ObjectReference BinaryPropertyListPlan::booleanTrueObjectReference() const
ObjectReference BinaryPropertyListPlan::integerObjectReference(int integer) const
{
switch (integer) {
case -1:
ASSERT(m_integerNegativeOneObjectReference != invalidObjectReference());
return m_integerNegativeOneObjectReference;
case 0:
ASSERT(m_integerZeroObjectReference != invalidObjectReference());
return m_integerZeroObjectReference;
default:
ASSERT(m_integers.contains(integer));
return m_integers.get(integer);
ASSERT(integer >= 0);
if (!integer) {
ASSERT(m_integerZeroObjectReference != invalidObjectReference());
return m_integerZeroObjectReference;
}
ASSERT(m_integers.contains(integer));
return m_integers.get(integer);
}
ObjectReference BinaryPropertyListPlan::stringObjectReference(const String& string) const
......@@ -371,6 +357,8 @@ private:
virtual size_t writeDictionaryStart();
virtual void writeDictionaryEnd(size_t);
ObjectReference writeIntegerWithoutAddingAggregateObjectReference(int);
void appendIntegerObject(int);
void appendStringObject(const String&);
void appendStringObject(const char*);
......@@ -520,14 +508,19 @@ void BinaryPropertyListSerializer::writeBooleanTrue()
addAggregateObjectReference(reference);
}
void BinaryPropertyListSerializer::writeInteger(int integer)
inline ObjectReference BinaryPropertyListSerializer::writeIntegerWithoutAddingAggregateObjectReference(int integer)
{
ObjectReference reference = m_plan.integerObjectReference(integer);
if (m_currentObjectReference != reference)
ASSERT(reference < m_currentObjectReference);
else
appendIntegerObject(integer);
addAggregateObjectReference(reference);
return reference;
}
void BinaryPropertyListSerializer::writeInteger(int integer)
{
addAggregateObjectReference(writeIntegerWithoutAddingAggregateObjectReference(integer));
}
void BinaryPropertyListSerializer::writeString(const String& string)
......@@ -543,11 +536,8 @@ void BinaryPropertyListSerializer::writeString(const String& string)
void BinaryPropertyListSerializer::writeIntegerArray(const int* integers, size_t size)
{
ObjectReference reference = m_plan.integerArrayObjectReference(integers, size);
UInt8* savedAggregateBufferByte = m_currentAggregateBufferByte;
for (size_t i = 0; i < size; ++i)
writeInteger(integers[i]);
m_currentAggregateBufferByte = savedAggregateBufferByte;
ASSERT(m_currentByte <= m_currentAggregateBufferByte);
writeIntegerWithoutAddingAggregateObjectReference(integers[i]);
if (m_currentObjectReference != reference)
ASSERT(reference < m_currentObjectReference);
else
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment