Diff
Modified: trunk/Source/WebCore/ChangeLog (89598 => 89599)
--- trunk/Source/WebCore/ChangeLog 2011-06-23 19:13:13 UTC (rev 89598)
+++ trunk/Source/WebCore/ChangeLog 2011-06-23 19:29:36 UTC (rev 89599)
@@ -1,3 +1,27 @@
+2011-06-23 Jay Civelli <jcive...@chromium.org>
+
+ Reviewed by Adam Barth.
+
+ Fixing the SharedBufferChunkReader API so it works correctly with
+ binary data (non printable characters).
+ Also adding a method to peek at the data (this is needed for MHTML
+ with binary parts).
+ https://bugs.webkit.org/show_bug.cgi?id=63231
+
+ * loader/archive/mhtml/MHTMLParser.cpp:
+ (WebCore::skipLinesUntilBoundaryFound):
+ (WebCore::MHTMLParser::parseNextPart):
+ * loader/archive/mhtml/MHTMLParser.h:
+ * platform/SharedBufferChunkReader.cpp:
+ (WebCore::SharedBufferChunkReader::SharedBufferChunkReader):
+ (WebCore::SharedBufferChunkReader::setSeparator):
+ (WebCore::SharedBufferChunkReader::nextChunk):
+ (WebCore::SharedBufferChunkReader::nextChunkAsUTF8StringWithLatin1Fallback):
+ (WebCore::SharedBufferChunkReader::peek):
+ * platform/SharedBufferChunkReader.h:
+ * platform/network/MIMEHeader.cpp:
+ (WebCore::retrieveKeyValuePairs):
+
2011-06-23 Nate Chapin <jap...@chromium.org>
Unreviewed.
Modified: trunk/Source/WebCore/loader/archive/mhtml/MHTMLParser.cpp (89598 => 89599)
--- trunk/Source/WebCore/loader/archive/mhtml/MHTMLParser.cpp 2011-06-23 19:13:13 UTC (rev 89598)
+++ trunk/Source/WebCore/loader/archive/mhtml/MHTMLParser.cpp 2011-06-23 19:29:36 UTC (rev 89599)
@@ -46,7 +46,7 @@
static bool skipLinesUntilBoundaryFound(SharedBufferChunkReader& lineReader, const String& boundary)
{
String line;
- while (!(line = lineReader.nextChunk()).isNull()) {
+ while (!(line = lineReader.nextChunkAsUTF8StringWithLatin1Fallback()).isNull()) {
if (line == boundary)
return true;
}
@@ -147,7 +147,7 @@
const bool checkBoundary = !endOfPartBoundary.isEmpty();
bool endOfPartReached = false;
String line;
- while (!(line = m_lineReader.nextChunk()).isNull()) {
+ while (!(line = m_lineReader.nextChunkAsUTF8StringWithLatin1Fallback()).isNull()) {
if (checkBoundary && (line == endOfPartBoundary || line == endOfDocumentBoundary)) {
endOfArchiveReached = (line == endOfDocumentBoundary);
endOfPartReached = true;
Modified: trunk/Source/WebCore/loader/archive/mhtml/MHTMLParser.h (89598 => 89599)
--- trunk/Source/WebCore/loader/archive/mhtml/MHTMLParser.h 2011-06-23 19:13:13 UTC (rev 89598)
+++ trunk/Source/WebCore/loader/archive/mhtml/MHTMLParser.h 2011-06-23 19:29:36 UTC (rev 89599)
@@ -34,6 +34,7 @@
#if ENABLE(MHTML)
#include "SharedBufferChunkReader.h"
#include <wtf/RefPtr.h>
+#include <wtf/text/WTFString.h>
#include <wtf/Vector.h>
namespace WebCore {
Modified: trunk/Source/WebCore/platform/SharedBufferChunkReader.cpp (89598 => 89599)
--- trunk/Source/WebCore/platform/SharedBufferChunkReader.cpp 2011-06-23 19:13:13 UTC (rev 89598)
+++ trunk/Source/WebCore/platform/SharedBufferChunkReader.cpp 2011-06-23 19:29:36 UTC (rev 89599)
@@ -32,11 +32,10 @@
#include "SharedBufferChunkReader.h"
#include "SharedBuffer.h"
-#include <wtf/text/StringBuilder.h>
namespace WebCore {
-SharedBufferChunkReader::SharedBufferChunkReader(SharedBuffer* buffer, const String& separator)
+SharedBufferChunkReader::SharedBufferChunkReader(SharedBuffer* buffer, const Vector<char>& separator)
: m_buffer(buffer)
, m_bufferPosition(0)
, m_segment(0)
@@ -48,34 +47,53 @@
{
}
-void SharedBufferChunkReader::setSeparator(const String& separator)
+SharedBufferChunkReader::SharedBufferChunkReader(SharedBuffer* buffer, const char* separator)
+ : m_buffer(buffer)
+ , m_bufferPosition(0)
+ , m_segment(0)
+ , m_segmentLength(0)
+ , m_segmentIndex(0)
+ , m_reachedEndOfFile(false)
+ , m_separatorIndex(0)
{
+ setSeparator(separator);
+}
+
+void SharedBufferChunkReader::setSeparator(const Vector<char>& separator)
+{
m_separator = separator;
}
-String SharedBufferChunkReader::nextChunk(bool includeSeparator)
+void SharedBufferChunkReader::setSeparator(const char* separator)
{
+ m_separator.clear();
+ m_separator.append(separator, strlen(separator));
+}
+
+bool SharedBufferChunkReader::nextChunk(Vector<char>& chunk, bool includeSeparator)
+{
if (m_reachedEndOfFile)
- return String();
+ return false;
- StringBuilder stringBuilder;
+ chunk.clear();
while (true) {
while (m_segmentIndex < m_segmentLength) {
char currentCharacter = m_segment[m_segmentIndex++];
if (currentCharacter != m_separator[m_separatorIndex]) {
- if (m_separatorIndex > 0) {
- stringBuilder.append(m_separator.substring(0, m_separatorIndex));
- m_separatorIndex = 0;
- }
- stringBuilder.append(currentCharacter);
- continue;
+ if (m_separatorIndex > 0) {
+ ASSERT(m_separatorIndex <= m_separator.size());
+ chunk.append(m_separator.data(), m_separatorIndex);
+ m_separatorIndex = 0;
+ }
+ chunk.append(currentCharacter);
+ continue;
}
m_separatorIndex++;
- if (m_separatorIndex == m_separator.length()) {
- if (includeSeparator)
- stringBuilder.append(m_separator);
- m_separatorIndex = 0;
- return stringBuilder.toString();
+ if (m_separatorIndex == m_separator.size()) {
+ if (includeSeparator)
+ chunk.append(m_separator);
+ m_separatorIndex = 0;
+ return true;
}
}
@@ -86,11 +104,47 @@
if (!m_segmentLength) {
m_reachedEndOfFile = true;
if (m_separatorIndex > 0)
- stringBuilder.append(m_separator.substring(0, m_separatorIndex));
- return stringBuilder.length() > 0 ? stringBuilder.toString() : String();
+ chunk.append(m_separator.data(), m_separatorIndex);
+ return !chunk.isEmpty();
}
}
- return String(); // Compiler is unhappy without this.
+ ASSERT_NOT_REACHED();
+ return false;
}
+String SharedBufferChunkReader::nextChunkAsUTF8StringWithLatin1Fallback(bool includeSeparator)
+{
+ Vector<char> data;
+ if (!nextChunk(data, includeSeparator))
+ return String();
+
+ return data.size() ? String::fromUTF8WithLatin1Fallback(data.data(), data.size()) : String("");
}
+
+size_t SharedBufferChunkReader::peek(Vector<char>& data, size_t requestedSize)
+{
+ data.clear();
+ if (requestedSize <= m_segmentLength - m_segmentIndex) {
+ data.append(m_segment + m_segmentIndex, requestedSize);
+ return requestedSize;
+ }
+
+ size_t readBytesCount = m_segmentLength - m_segmentIndex;
+ data.append(m_segment + m_segmentIndex, readBytesCount);
+
+ size_t bufferPosition = m_bufferPosition + m_segmentLength;
+ const char* segment = 0;
+ while (size_t segmentLength = m_buffer->getSomeData(segment, bufferPosition)) {
+ if (requestedSize <= readBytesCount + segmentLength) {
+ data.append(segment, requestedSize - readBytesCount);
+ readBytesCount += (requestedSize - readBytesCount);
+ break;
+ }
+ data.append(segment, segmentLength);
+ readBytesCount += segmentLength;
+ bufferPosition += segmentLength;
+ }
+ return readBytesCount;
+}
+
+}
Modified: trunk/Source/WebCore/platform/SharedBufferChunkReader.h (89598 => 89599)
--- trunk/Source/WebCore/platform/SharedBufferChunkReader.h 2011-06-23 19:13:13 UTC (rev 89598)
+++ trunk/Source/WebCore/platform/SharedBufferChunkReader.h 2011-06-23 19:29:36 UTC (rev 89599)
@@ -31,25 +31,31 @@
#ifndef SharedBufferChunkReader_h
#define SharedBufferChunkReader_h
+#include <wtf/Vector.h>
#include <wtf/text/WTFString.h>
-namespace WTF {
-class StringBuilder;
-}
-
namespace WebCore {
class SharedBuffer;
class SharedBufferChunkReader {
public:
- SharedBufferChunkReader(SharedBuffer*, const String& separator);
+ SharedBufferChunkReader(SharedBuffer*, const Vector<char>& separator);
+ SharedBufferChunkReader(SharedBuffer*, const char* separator);
- void setSeparator(const String&);
+ void setSeparator(const Vector<char>&);
+ void setSeparator(const char*);
+ // Returns false when the end of the buffer was reached.
+ bool nextChunk(Vector<char>& data, bool includeSeparator = false);
+
// Returns a null string when the end of the buffer has been reached.
- String nextChunk(bool includeSeparator = false);
+ String nextChunkAsUTF8StringWithLatin1Fallback(bool includeSeparator = false);
+ // Reads size bytes at the current location in the buffer, without changing the buffer position.
+ // Returns the number of bytes read. That number might be less than the specified size if the end of the buffer was reached.
+ size_t peek(Vector<char>&, size_t);
+
private:
SharedBuffer* m_buffer;
size_t m_bufferPosition;
@@ -57,7 +63,7 @@
size_t m_segmentLength;
size_t m_segmentIndex;
bool m_reachedEndOfFile;
- String m_separator;
+ Vector<char> m_separator;
size_t m_separatorIndex;
};
Modified: trunk/Source/WebCore/platform/network/MIMEHeader.cpp (89598 => 89599)
--- trunk/Source/WebCore/platform/network/MIMEHeader.cpp 2011-06-23 19:13:13 UTC (rev 89598)
+++ trunk/Source/WebCore/platform/network/MIMEHeader.cpp 2011-06-23 19:29:36 UTC (rev 89599)
@@ -49,7 +49,7 @@
String line;
String key;
StringBuilder value;
- while (!(line = buffer->nextChunk()).isNull()) {
+ while (!(line = buffer->nextChunkAsUTF8StringWithLatin1Fallback()).isNull()) {
if (line.isEmpty())
break; // Empty line means end of key/value section.
if (line[0] == '\t') {