| Index: third_party/WebKit/Source/platform/mhtml/MHTMLArchive.cpp
|
| diff --git a/third_party/WebKit/Source/platform/mhtml/MHTMLArchive.cpp b/third_party/WebKit/Source/platform/mhtml/MHTMLArchive.cpp
|
| index 09d61918d13cea2522f5b5893fedf9f19981290f..334f671a805c26baf968f19df69ce82a39d94c95 100644
|
| --- a/third_party/WebKit/Source/platform/mhtml/MHTMLArchive.cpp
|
| +++ b/third_party/WebKit/Source/platform/mhtml/MHTMLArchive.cpp
|
| @@ -45,12 +45,21 @@
|
| #include "wtf/text/Base64.h"
|
| #include "wtf/text/StringBuilder.h"
|
|
|
| -namespace blink {
|
| +namespace {
|
|
|
| const char* const quotedPrintable = "quoted-printable";
|
| const char* const base64 = "base64";
|
| const char* const binary = "binary";
|
|
|
| +enum class Encoding {
|
| + QuotedPrintable,
|
| + Base64,
|
| + Binary,
|
| +};
|
| +}
|
| +
|
| +namespace blink {
|
| +
|
| static String replaceNonPrintableCharacters(const String& text) {
|
| StringBuilder stringBuilder;
|
| for (size_t i = 0; i < text.length(); ++i) {
|
| @@ -110,7 +119,7 @@ bool MHTMLArchive::canLoadArchive(const KURL& url) {
|
| void MHTMLArchive::generateMHTMLHeader(const String& boundary,
|
| const String& title,
|
| const String& mimeType,
|
| - SharedBuffer& outputBuffer) {
|
| + std::vector<char>& outputBuffer) {
|
| ASSERT(!boundary.isEmpty());
|
| ASSERT(!mimeType.isEmpty());
|
|
|
| @@ -142,14 +151,16 @@ void MHTMLArchive::generateMHTMLHeader(const String& boundary,
|
| ASSERT(stringBuilder.toString().containsOnlyASCII());
|
| CString asciiString = stringBuilder.toString().utf8();
|
|
|
| - outputBuffer.append(asciiString.data(), asciiString.length());
|
| + outputBuffer.reserve(outputBuffer.size() + asciiString.length());
|
| + outputBuffer.insert(outputBuffer.end(), asciiString.data(),
|
| + asciiString.data() + asciiString.length());
|
| }
|
|
|
| void MHTMLArchive::generateMHTMLPart(const String& boundary,
|
| const String& contentID,
|
| EncodingPolicy encodingPolicy,
|
| const SerializedResource& resource,
|
| - SharedBuffer& outputBuffer) {
|
| + std::vector<char>& outputBuffer) {
|
| ASSERT(!boundary.isEmpty());
|
| ASSERT(contentID.isEmpty() || contentID[0] == '<');
|
|
|
| @@ -168,17 +179,22 @@ void MHTMLArchive::generateMHTMLPart(const String& boundary,
|
| stringBuilder.append("\r\n");
|
| }
|
|
|
| - const char* contentEncoding = 0;
|
| - if (encodingPolicy == UseBinaryEncoding)
|
| - contentEncoding = binary;
|
| - else if (MIMETypeRegistry::isSupportedJavaScriptMIMEType(resource.mimeType) ||
|
| - MIMETypeRegistry::isSupportedNonImageMIMEType(resource.mimeType))
|
| - contentEncoding = quotedPrintable;
|
| - else
|
| - contentEncoding = base64;
|
| + const char* contentEncodingText = 0;
|
| + Encoding encoding = Encoding::Base64;
|
| + if (encodingPolicy == UseBinaryEncoding) {
|
| + contentEncodingText = binary;
|
| + encoding = Encoding::Binary;
|
| + } else if (MIMETypeRegistry::isSupportedJavaScriptMIMEType(
|
| + resource.mimeType) ||
|
| + MIMETypeRegistry::isSupportedNonImageMIMEType(resource.mimeType)) {
|
| + contentEncodingText = quotedPrintable;
|
| + encoding = Encoding::QuotedPrintable;
|
| + } else {
|
| + contentEncodingText = base64;
|
| + }
|
|
|
| stringBuilder.append("Content-Transfer-Encoding: ");
|
| - stringBuilder.append(contentEncoding);
|
| + stringBuilder.append(contentEncodingText);
|
| stringBuilder.append("\r\n");
|
|
|
| if (!resource.url.protocolIsAbout()) {
|
| @@ -190,13 +206,25 @@ void MHTMLArchive::generateMHTMLPart(const String& boundary,
|
| stringBuilder.append("\r\n");
|
|
|
| CString asciiString = stringBuilder.toString().utf8();
|
| - outputBuffer.append(asciiString.data(), asciiString.length());
|
|
|
| - if (!strcmp(contentEncoding, binary)) {
|
| + // Best guess for a reserved size. It should work well for binary and base64
|
| + // (see https://en.wikipedia.org/wiki/Base64#MIME); not so much for
|
| + // quoted-printable which is harder to estimate.
|
| + std::size_t expectedFinalSize = outputBuffer.size() + asciiString.length();
|
| + if (encoding == Encoding::Base64)
|
| + expectedFinalSize += static_cast<std::size_t>(resource.data->size() * 1.37);
|
| + else
|
| + expectedFinalSize += resource.data->size();
|
| + outputBuffer.reserve(expectedFinalSize);
|
| +
|
| + outputBuffer.insert(outputBuffer.end(), asciiString.data(),
|
| + asciiString.data() + asciiString.length());
|
| +
|
| + if (encoding == Encoding::Binary) {
|
| const char* data;
|
| size_t position = 0;
|
| while (size_t length = resource.data->getSomeData(data, position)) {
|
| - outputBuffer.append(data, length);
|
| + outputBuffer.insert(outputBuffer.end(), data, data + length);
|
| position += length;
|
| }
|
| } else {
|
| @@ -205,12 +233,14 @@ void MHTMLArchive::generateMHTMLPart(const String& boundary,
|
| const char* data = resource.data->data();
|
| size_t dataLength = resource.data->size();
|
| Vector<char> encodedData;
|
| - if (!strcmp(contentEncoding, quotedPrintable)) {
|
| + if (encoding == Encoding::QuotedPrintable) {
|
| quotedPrintableEncode(data, dataLength, encodedData);
|
| - outputBuffer.append(encodedData.data(), encodedData.size());
|
| - outputBuffer.append("\r\n", 2u);
|
| + outputBuffer.insert(outputBuffer.end(), encodedData.data(),
|
| + encodedData.data() + encodedData.size());
|
| + outputBuffer.push_back('\r');
|
| + outputBuffer.push_back('\n');
|
| } else {
|
| - ASSERT(!strcmp(contentEncoding, base64));
|
| + DCHECK(encoding == Encoding::Base64);
|
| // We are not specifying insertLFs = true below as it would cut the lines
|
| // with LFs and MHTML requires CRLFs.
|
| base64Encode(data, dataLength, encodedData);
|
| @@ -220,8 +250,10 @@ void MHTMLArchive::generateMHTMLPart(const String& boundary,
|
| do {
|
| size_t lineLength =
|
| std::min(encodedDataLength - index, maximumLineLength);
|
| - outputBuffer.append(encodedData.data() + index, lineLength);
|
| - outputBuffer.append("\r\n", 2u);
|
| + outputBuffer.insert(outputBuffer.end(), encodedData.data() + index,
|
| + encodedData.data() + index + lineLength);
|
| + outputBuffer.push_back('\r');
|
| + outputBuffer.push_back('\n');
|
| index += maximumLineLength;
|
| } while (index < encodedDataLength);
|
| }
|
| @@ -229,10 +261,12 @@ void MHTMLArchive::generateMHTMLPart(const String& boundary,
|
| }
|
|
|
| void MHTMLArchive::generateMHTMLFooter(const String& boundary,
|
| - SharedBuffer& outputBuffer) {
|
| + std::vector<char>& outputBuffer) {
|
| ASSERT(!boundary.isEmpty());
|
| CString asciiString = String("--" + boundary + "--\r\n").utf8();
|
| - outputBuffer.append(asciiString.data(), asciiString.length());
|
| + outputBuffer.reserve(outputBuffer.size() + asciiString.length());
|
| + outputBuffer.insert(outputBuffer.end(), asciiString.data(),
|
| + asciiString.data() + asciiString.length());
|
| }
|
|
|
| void MHTMLArchive::setMainResource(ArchiveResource* mainResource) {
|
|
|