blob: 24939a9649c30309911f860166653aa954f260b8 [file] [log] [blame]
/*
* Copyright (C) 2013 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#include "BlobRegistrationData.h"
#if ENABLE(BLOB) && ENABLE(NETWORK_PROCESS)
#include "ArgumentCoders.h"
#include "DataReference.h"
#include "WebCoreArgumentCoders.h"
#include <WebCore/BlobData.h>
using namespace WebCore;
namespace WebKit {
BlobRegistrationData::BlobRegistrationData()
{
}
BlobRegistrationData::BlobRegistrationData(std::unique_ptr<BlobData> data)
: m_data(std::move(data))
{
const BlobDataItemList& items = m_data->items();
size_t fileCount = 0;
for (size_t i = 0, count = items.size(); i < count; ++i) {
// File path can be empty when submitting a form file input without a file, see bug 111778.
if (items[i].type == BlobDataItem::File && !items[i].path.isEmpty())
++fileCount;
}
m_sandboxExtensions.allocate(fileCount);
size_t extensionIndex = 0;
for (size_t i = 0, count = items.size(); i < count; ++i) {
const BlobDataItem& item = items[i];
if (item.type == BlobDataItem::File && !items[i].path.isEmpty())
SandboxExtension::createHandle(item.path, SandboxExtension::ReadOnly, m_sandboxExtensions[extensionIndex++]);
}
}
BlobRegistrationData::~BlobRegistrationData()
{
}
std::unique_ptr<BlobData> BlobRegistrationData::releaseData() const
{
return std::move(m_data);
}
void BlobRegistrationData::encode(IPC::ArgumentEncoder& encoder) const
{
encoder << m_data->contentType();
encoder << m_data->contentDisposition();
const BlobDataItemList& items = m_data->items();
encoder << static_cast<uint64_t>(items.size());
for (size_t i = 0, count = items.size(); i < count; ++i) {
const BlobDataItem& item = items[i];
encoder << static_cast<uint32_t>(item.type);
switch (item.type) {
case BlobDataItem::Data:
// There is no way to create a partial data item.
ASSERT(!item.offset);
ASSERT(item.length == BlobDataItem::toEndOfFile);
encoder << IPC::DataReference(reinterpret_cast<const uint8_t*>(item.data->data()), item.data->length());
break;
case BlobDataItem::File:
encoder << static_cast<int64_t>(item.offset);
encoder << static_cast<int64_t>(item.length);
encoder << item.expectedModificationTime;
encoder << item.path;
break;
case BlobDataItem::Blob:
encoder << static_cast<int64_t>(item.offset);
encoder << static_cast<int64_t>(item.length);
encoder << item.url;
break;
}
}
encoder << m_sandboxExtensions;
}
bool BlobRegistrationData::decode(IPC::ArgumentDecoder& decoder, BlobRegistrationData& result)
{
ASSERT(!result.m_data);
result.m_data = std::make_unique<BlobData>();
String contentType;
if (!decoder.decode(contentType))
return false;
result.m_data->setContentType(contentType);
String contentDisposition;
if (!decoder.decode(contentDisposition))
return false;
result.m_data->setContentDisposition(contentDisposition);
uint64_t itemCount;
if (!decoder.decode(itemCount))
return false;
for (uint64_t i = 0; i < itemCount; ++i) {
uint32_t type;
if (!decoder.decode(type))
return false;
switch (type) {
case BlobDataItem::Data: {
IPC::DataReference data;
if (!decoder.decode(data))
return false;
RefPtr<RawData> rawData = RawData::create();
rawData->mutableData()->append(data.data(), data.size());
result.m_data->appendData(rawData.release(), 0, BlobDataItem::toEndOfFile);
break;
}
case BlobDataItem::File: {
int64_t offset;
if (!decoder.decode(offset))
return false;
int64_t length;
if (!decoder.decode(length))
return false;
double expectedModificationTime;
if (!decoder.decode(expectedModificationTime))
return false;
String path;
if (!decoder.decode(path))
return false;
result.m_data->appendFile(path, offset, length, expectedModificationTime);
break;
}
case BlobDataItem::Blob: {
int64_t offset;
if (!decoder.decode(offset))
return false;
int64_t length;
if (!decoder.decode(length))
return false;
String url;
if (!decoder.decode(url))
return false;
result.m_data->appendBlob(URL(URL(), url), offset, length);
break;
}
default:
return false;
}
}
if (!decoder.decode(result.m_sandboxExtensions))
return false;
return true;
}
}
#endif // ENABLE(BLOB) && ENABLE(NETWORK_PROCESS)