1/* 2 * Copyright (C) 2012 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 "ShareableResource.h" 28 29#if ENABLE(SHAREABLE_RESOURCE) 30 31#include "ArgumentCoders.h" 32#include <WebCore/SharedBuffer.h> 33 34using namespace WebCore; 35 36namespace WebKit { 37 38ShareableResource::Handle::Handle() 39{ 40} 41 42void ShareableResource::Handle::encode(IPC::ArgumentEncoder& encoder) const 43{ 44 encoder << m_handle; 45 encoder << m_offset; 46 encoder << m_size; 47} 48 49bool ShareableResource::Handle::decode(IPC::ArgumentDecoder& decoder, Handle& handle) 50{ 51 if (!decoder.decode(handle.m_handle)) 52 return false; 53 if (!decoder.decode(handle.m_offset)) 54 return false; 55 if (!decoder.decode(handle.m_size)) 56 return false; 57 return true; 58} 59 60static void shareableResourceDeallocate(void *ptr, void *info) 61{ 62 (static_cast<ShareableResource*>(info))->deref(); // Balanced by ref() in createShareableResourceDeallocator() 63} 64 65static CFAllocatorRef createShareableResourceDeallocator(ShareableResource* resource) 66{ 67 resource->ref(); // Balanced by deref in shareableResourceDeallocate() 68 69 CFAllocatorContext context = { 0, 70 resource, 71 NULL, // retain 72 NULL, // release 73 NULL, // copyDescription 74 NULL, // allocate 75 NULL, // reallocate 76 shareableResourceDeallocate, 77 NULL, // preferredSize 78 }; 79 80 return CFAllocatorCreate(kCFAllocatorDefault, &context); 81} 82 83RetainPtr<CFDataRef> ShareableResource::Handle::tryWrapInCFData() const 84{ 85 RefPtr<ShareableResource> resource = ShareableResource::create(*this); 86 if (!resource) { 87 LOG_ERROR("Failed to recreate ShareableResource from handle."); 88 return 0; 89 } 90 91 RetainPtr<CFAllocatorRef> deallocator = adoptCF(createShareableResourceDeallocator(resource.get())); 92 return adoptCF(CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, reinterpret_cast<const UInt8*>(resource->data()), static_cast<CFIndex>(resource->size()), deallocator.get())); 93} 94 95PassRefPtr<SharedBuffer> ShareableResource::Handle::tryWrapInSharedBuffer() const 96{ 97 return SharedBuffer::wrapCFData(tryWrapInCFData().get()); 98} 99 100PassRefPtr<ShareableResource> ShareableResource::create(PassRefPtr<SharedMemory> sharedMemory, unsigned offset, unsigned size) 101{ 102 return adoptRef(new ShareableResource(sharedMemory, offset, size)); 103} 104 105PassRefPtr<ShareableResource> ShareableResource::create(const Handle& handle) 106{ 107 RefPtr<SharedMemory> sharedMemory = SharedMemory::create(handle.m_handle, SharedMemory::ReadOnly); 108 if (!sharedMemory) 109 return 0; 110 111 return create(sharedMemory.release(), handle.m_offset, handle.m_size); 112} 113 114ShareableResource::ShareableResource(PassRefPtr<SharedMemory> sharedMemory, unsigned offset, unsigned size) 115 : m_sharedMemory(sharedMemory) 116 , m_offset(offset) 117 , m_size(size) 118{ 119 ASSERT(m_sharedMemory); 120 ASSERT(m_offset + m_size <= m_sharedMemory->size()); 121 122 // FIXME (NetworkProcess): This data was received from another process. If it is bogus, should we assume that process is compromised and we should kill it? 123} 124 125ShareableResource::~ShareableResource() 126{ 127} 128 129bool ShareableResource::createHandle(Handle& handle) 130{ 131 if (!m_sharedMemory->createHandle(handle.m_handle, SharedMemory::ReadOnly)) 132 return false; 133 134 handle.m_offset = m_offset; 135 handle.m_size = m_size; 136 137 return true; 138} 139 140const char* ShareableResource::data() const 141{ 142 return static_cast<const char*>(m_sharedMemory->data()) + m_offset; 143} 144 145unsigned ShareableResource::size() const 146{ 147 return m_size; 148} 149 150} // namespace WebKit 151 152#endif // ENABLE(SHAREABLE_RESOURCE) 153