1/* 2 * Copyright (C) 2013 Apple Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' 14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS 17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 23 * THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26#include "config.h" 27#include "BlobRegistrationData.h" 28 29#if ENABLE(BLOB) && ENABLE(NETWORK_PROCESS) 30 31#include "ArgumentCoders.h" 32#include "DataReference.h" 33#include "WebCoreArgumentCoders.h" 34#include <WebCore/BlobData.h> 35 36using namespace WebCore; 37 38namespace WebKit { 39 40BlobRegistrationData::BlobRegistrationData() 41{ 42} 43 44BlobRegistrationData::BlobRegistrationData(PassOwnPtr<BlobData> data) 45 : m_data(data) 46{ 47 const BlobDataItemList& items = m_data->items(); 48 size_t fileCount = 0; 49 for (size_t i = 0, count = items.size(); i < count; ++i) { 50 // File path can be empty when submitting a form file input without a file, see bug 111778. 51 if (items[i].type == BlobDataItem::File && !items[i].path.isEmpty()) 52 ++fileCount; 53 } 54 55 m_sandboxExtensions.allocate(fileCount); 56 size_t extensionIndex = 0; 57 for (size_t i = 0, count = items.size(); i < count; ++i) { 58 const BlobDataItem& item = items[i]; 59 if (item.type == BlobDataItem::File && !items[i].path.isEmpty()) 60 SandboxExtension::createHandle(item.path, SandboxExtension::ReadOnly, m_sandboxExtensions[extensionIndex++]); 61 } 62} 63 64BlobRegistrationData::~BlobRegistrationData() 65{ 66} 67 68PassOwnPtr<BlobData> BlobRegistrationData::releaseData() const 69{ 70 return m_data.release(); 71} 72 73void BlobRegistrationData::encode(CoreIPC::ArgumentEncoder& encoder) const 74{ 75 encoder << m_data->contentType(); 76 encoder << m_data->contentDisposition(); 77 78 const BlobDataItemList& items = m_data->items(); 79 encoder << static_cast<uint64_t>(items.size()); 80 for (size_t i = 0, count = items.size(); i < count; ++i) { 81 const BlobDataItem& item = items[i]; 82 encoder << static_cast<uint32_t>(item.type); 83 switch (item.type) { 84 case BlobDataItem::Data: 85 // There is no way to create a partial data item. 86 ASSERT(!item.offset); 87 ASSERT(item.length == BlobDataItem::toEndOfFile); 88 encoder << CoreIPC::DataReference(reinterpret_cast<const uint8_t*>(item.data->data()), item.data->length()); 89 break; 90 case BlobDataItem::File: 91 encoder << item.offset; 92 encoder << item.length; 93 encoder << item.expectedModificationTime; 94 encoder << item.path; 95 break; 96 case BlobDataItem::Blob: 97 encoder << item.offset; 98 encoder << item.length; 99 encoder << item.url; 100 break; 101 } 102 } 103 104 encoder << m_sandboxExtensions; 105} 106 107bool BlobRegistrationData::decode(CoreIPC::ArgumentDecoder& decoder, BlobRegistrationData& result) 108{ 109 ASSERT(!result.m_data); 110 result.m_data = BlobData::create(); 111 112 String contentType; 113 if (!decoder.decode(contentType)) 114 return false; 115 result.m_data->setContentType(contentType); 116 117 String contentDisposition; 118 if (!decoder.decode(contentDisposition)) 119 return false; 120 result.m_data->setContentDisposition(contentDisposition); 121 122 uint64_t itemCount; 123 if (!decoder.decode(itemCount)) 124 return false; 125 126 for (uint64_t i = 0; i < itemCount; ++i) { 127 uint32_t type; 128 if (!decoder.decode(type)) 129 return false; 130 switch (type) { 131 case BlobDataItem::Data: { 132 CoreIPC::DataReference data; 133 if (!decoder.decode(data)) 134 return false; 135 RefPtr<RawData> rawData = RawData::create(); 136 rawData->mutableData()->append(data.data(), data.size()); 137 result.m_data->appendData(rawData.release(), 0, BlobDataItem::toEndOfFile); 138 break; 139 } 140 case BlobDataItem::File: { 141 long long offset; 142 if (!decoder.decode(offset)) 143 return false; 144 long long length; 145 if (!decoder.decode(length)) 146 return false; 147 double expectedModificationTime; 148 if (!decoder.decode(expectedModificationTime)) 149 return false; 150 String path; 151 if (!decoder.decode(path)) 152 return false; 153 result.m_data->appendFile(path, offset, length, expectedModificationTime); 154 break; 155 } 156 case BlobDataItem::Blob: { 157 long long offset; 158 if (!decoder.decode(offset)) 159 return false; 160 long long length; 161 if (!decoder.decode(length)) 162 return false; 163 String url; 164 if (!decoder.decode(url)) 165 return false; 166 result.m_data->appendBlob(KURL(KURL(), url), offset, length); 167 break; 168 } 169 default: 170 return false; 171 } 172 } 173 174 if (!decoder.decode(result.m_sandboxExtensions)) 175 return false; 176 177 return true; 178} 179 180} 181 182#endif // ENABLE(BLOB) && ENABLE(NETWORK_PROCESS) 183