diff options
Diffstat (limited to 'Source/WebCore/fileapi/FileReaderLoader.cpp')
-rw-r--r-- | Source/WebCore/fileapi/FileReaderLoader.cpp | 108 |
1 files changed, 56 insertions, 52 deletions
diff --git a/Source/WebCore/fileapi/FileReaderLoader.cpp b/Source/WebCore/fileapi/FileReaderLoader.cpp index 007ff70a9..7fd08fea1 100644 --- a/Source/WebCore/fileapi/FileReaderLoader.cpp +++ b/Source/WebCore/fileapi/FileReaderLoader.cpp @@ -30,13 +30,13 @@ #include "config.h" -#if ENABLE(BLOB) - #include "FileReaderLoader.h" #include "Blob.h" #include "BlobURL.h" #include "FileReaderLoaderClient.h" +#include "HTTPHeaderNames.h" +#include "ResourceError.h" #include "ResourceRequest.h" #include "ResourceResponse.h" #include "ScriptExecutionContext.h" @@ -44,7 +44,6 @@ #include "ThreadableBlobRegistry.h" #include "ThreadableLoader.h" #include <runtime/ArrayBuffer.h> -#include <wtf/PassRefPtr.h> #include <wtf/RefPtr.h> #include <wtf/Vector.h> #include <wtf/text/Base64.h> @@ -58,13 +57,10 @@ FileReaderLoader::FileReaderLoader(ReadType readType, FileReaderLoaderClient* cl : m_readType(readType) , m_client(client) , m_isRawDataConverted(false) - , m_stringResult("") + , m_stringResult(emptyString()) , m_variableLength(false) , m_bytesLoaded(0) , m_totalBytes(0) - , m_hasRange(false) - , m_rangeStart(0) - , m_rangeEnd(0) , m_errorCode(0) { } @@ -76,33 +72,33 @@ FileReaderLoader::~FileReaderLoader() ThreadableBlobRegistry::unregisterBlobURL(m_urlForReading); } -void FileReaderLoader::start(ScriptExecutionContext* scriptExecutionContext, Blob* blob) +void FileReaderLoader::start(ScriptExecutionContext* scriptExecutionContext, Blob& blob) { + ASSERT(scriptExecutionContext); + // The blob is read by routing through the request handling layer given a temporary public url. m_urlForReading = BlobURL::createPublicURL(scriptExecutionContext->securityOrigin()); if (m_urlForReading.isEmpty()) { failed(FileError::SECURITY_ERR); return; } - ThreadableBlobRegistry::registerBlobURL(scriptExecutionContext->securityOrigin(), m_urlForReading, blob->url()); + ThreadableBlobRegistry::registerBlobURL(scriptExecutionContext->securityOrigin(), m_urlForReading, blob.url()); // Construct and load the request. ResourceRequest request(m_urlForReading); request.setHTTPMethod("GET"); - if (m_hasRange) - request.setHTTPHeaderField("Range", String::format("bytes=%d-%d", m_rangeStart, m_rangeEnd)); ThreadableLoaderOptions options; options.sendLoadCallbacks = SendCallbacks; - options.sniffContent = DoNotSniffContent; - options.preflightPolicy = ConsiderPreflight; - options.allowCredentials = AllowStoredCredentials; - options.crossOriginRequestPolicy = DenyCrossOriginRequests; + options.dataBufferingPolicy = DoNotBufferData; + options.credentials = FetchOptions::Credentials::Include; + options.mode = FetchOptions::Mode::SameOrigin; + options.contentSecurityPolicyEnforcement = ContentSecurityPolicyEnforcement::DoNotEnforce; if (m_client) - m_loader = ThreadableLoader::create(scriptExecutionContext, this, request, options); + m_loader = ThreadableLoader::create(*scriptExecutionContext, *this, WTFMove(request), options); else - ThreadableLoader::loadResourceSynchronously(scriptExecutionContext, request, *this, options); + ThreadableLoader::loadResourceSynchronously(*scriptExecutionContext, WTFMove(request), *this, options); } void FileReaderLoader::cancel() @@ -121,12 +117,12 @@ void FileReaderLoader::terminate() void FileReaderLoader::cleanup() { - m_loader = 0; + m_loader = nullptr; // If we get any error, we do not need to keep a buffer around. if (m_errorCode) { - m_rawData = 0; - m_stringResult = ""; + m_rawData = nullptr; + m_stringResult = emptyString(); } } @@ -137,16 +133,12 @@ void FileReaderLoader::didReceiveResponse(unsigned long, const ResourceResponse& return; } - unsigned long long length = response.expectedContentLength(); + long long length = response.expectedContentLength(); - // A value larger than INT_MAX means that the content length wasn't - // specified, so the buffer will need to be dynamically grown. - if (length > INT_MAX) { + // A negative value means that the content length wasn't specified, so the buffer will need to be dynamically grown. + if (length < 0) { m_variableLength = true; - if (m_hasRange) - length = 1 + m_rangeEnd - m_rangeStart; - else - length = defaultBufferLength; + length = defaultBufferLength; } // Check that we can cast to unsigned since we have to do @@ -158,7 +150,7 @@ void FileReaderLoader::didReceiveResponse(unsigned long, const ResourceResponse& } ASSERT(!m_rawData); - m_rawData = ArrayBuffer::create(static_cast<unsigned>(length), 1); + m_rawData = ArrayBuffer::tryCreate(static_cast<unsigned>(length), 1); if (!m_rawData) { failed(FileError::NOT_READABLE_ERR); @@ -189,17 +181,26 @@ void FileReaderLoader::didReceiveData(const char* data, int dataLength) return; } if (m_variableLength) { - unsigned long long newLength = m_totalBytes * 2; - if (newLength > std::numeric_limits<unsigned>::max()) - newLength = std::numeric_limits<unsigned>::max(); - RefPtr<ArrayBuffer> newData = - ArrayBuffer::create(static_cast<unsigned>(newLength), 1); + unsigned newLength = m_totalBytes + static_cast<unsigned>(dataLength); + if (newLength < m_totalBytes) { + failed(FileError::NOT_READABLE_ERR); + return; + } + newLength = std::max(newLength, m_totalBytes + m_totalBytes / 4 + 1); + auto newData = ArrayBuffer::tryCreate(newLength, 1); + if (!newData) { + // Not enough memory. + failed(FileError::NOT_READABLE_ERR); + return; + } memcpy(static_cast<char*>(newData->data()), static_cast<char*>(m_rawData->data()), m_bytesLoaded); m_rawData = newData; m_totalBytes = static_cast<unsigned>(newLength); - } else + } else { + // This can only happen if we get more data than indicated in expected content length (i.e. never, unless the networking layer is buggy). length = remainingBufferSpace; + } } if (length <= 0) @@ -227,13 +228,13 @@ void FileReaderLoader::didFinishLoading(unsigned long, double) m_client->didFinishLoading(); } -void FileReaderLoader::didFail(const ResourceError&) +void FileReaderLoader::didFail(const ResourceError& error) { // If we're aborting, do not proceed with normal error handling since it is covered in aborting code. if (m_errorCode == FileError::ABORT_ERR) return; - failed(FileError::NOT_READABLE_ERR); + failed(toErrorCode(static_cast<BlobResourceHandle::Error>(error.errorCode()))); } void FileReaderLoader::failed(int errorCode) @@ -244,32 +245,40 @@ void FileReaderLoader::failed(int errorCode) m_client->didFail(m_errorCode); } +FileError::ErrorCode FileReaderLoader::toErrorCode(BlobResourceHandle::Error error) +{ + switch (error) { + case BlobResourceHandle::Error::NotFoundError: + return FileError::NOT_FOUND_ERR; + default: + return FileError::NOT_READABLE_ERR; + } +} + FileError::ErrorCode FileReaderLoader::httpStatusCodeToErrorCode(int httpStatusCode) { switch (httpStatusCode) { case 403: return FileError::SECURITY_ERR; - case 404: - return FileError::NOT_FOUND_ERR; default: return FileError::NOT_READABLE_ERR; } } -PassRefPtr<ArrayBuffer> FileReaderLoader::arrayBufferResult() const +RefPtr<ArrayBuffer> FileReaderLoader::arrayBufferResult() const { ASSERT(m_readType == ReadAsArrayBuffer); // If the loading is not started or an error occurs, return an empty result. if (!m_rawData || m_errorCode) - return 0; + return nullptr; // If completed, we can simply return our buffer. if (isCompleted()) return m_rawData; // Otherwise, return a copy. - return ArrayBuffer::create(m_rawData.get()); + return ArrayBuffer::create(*m_rawData); } String FileReaderLoader::stringResult() @@ -316,21 +325,18 @@ void FileReaderLoader::convertToText() // requirement in order to be consistent with how WebKit decodes the web content: always has the BOM override the // provided encoding. // FIXME: consider supporting incremental decoding to improve the perf. - StringBuilder builder; if (!m_decoder) m_decoder = TextResourceDecoder::create("text/plain", m_encoding.isValid() ? m_encoding : UTF8Encoding()); - builder.append(m_decoder->decode(static_cast<const char*>(m_rawData->data()), m_bytesLoaded)); - if (isCompleted()) - builder.append(m_decoder->flush()); - - m_stringResult = builder.toString(); + m_stringResult = m_decoder->decodeAndFlush(static_cast<const char*>(m_rawData->data()), m_bytesLoaded); + else + m_stringResult = m_decoder->decode(static_cast<const char*>(m_rawData->data()), m_bytesLoaded); } void FileReaderLoader::convertToDataURL() { StringBuilder builder; - builder.append("data:"); + builder.appendLiteral("data:"); if (!m_bytesLoaded) { m_stringResult = builder.toString(); @@ -338,7 +344,7 @@ void FileReaderLoader::convertToDataURL() } builder.append(m_dataType); - builder.append(";base64,"); + builder.appendLiteral(";base64,"); Vector<char> out; base64Encode(m_rawData->data(), m_bytesLoaded, out); @@ -360,5 +366,3 @@ void FileReaderLoader::setEncoding(const String& encoding) } } // namespace WebCore - -#endif // ENABLE(BLOB) |