Title: [89599] trunk/Source/WebCore
Revision
89599
Author
jcive...@chromium.org
Date
2011-06-23 12:29:36 -0700 (Thu, 23 Jun 2011)

Log Message

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):

Modified Paths

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') {
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to