OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "bindings/core/v8/serialization/V8ScriptValueDeserializer.h" | 5 #include "bindings/core/v8/serialization/V8ScriptValueDeserializer.h" |
6 | 6 |
7 #include "bindings/core/v8/ToV8.h" | 7 #include "bindings/core/v8/ToV8.h" |
8 #include "core/dom/DOMArrayBuffer.h" | 8 #include "core/dom/DOMArrayBuffer.h" |
9 #include "core/dom/DOMSharedArrayBuffer.h" | 9 #include "core/dom/DOMSharedArrayBuffer.h" |
10 #include "core/dom/MessagePort.h" | 10 #include "core/dom/MessagePort.h" |
| 11 #include "core/fileapi/Blob.h" |
11 #include "core/frame/ImageBitmap.h" | 12 #include "core/frame/ImageBitmap.h" |
12 #include "core/html/ImageData.h" | 13 #include "core/html/ImageData.h" |
13 #include "core/offscreencanvas/OffscreenCanvas.h" | 14 #include "core/offscreencanvas/OffscreenCanvas.h" |
14 #include "platform/RuntimeEnabledFeatures.h" | 15 #include "platform/RuntimeEnabledFeatures.h" |
| 16 #include "public/platform/WebBlobInfo.h" |
15 #include "wtf/CheckedNumeric.h" | 17 #include "wtf/CheckedNumeric.h" |
16 | 18 |
17 namespace blink { | 19 namespace blink { |
18 | 20 |
19 V8ScriptValueDeserializer::V8ScriptValueDeserializer(RefPtr<ScriptState> scriptS
tate, RefPtr<SerializedScriptValue> serializedScriptValue) | 21 V8ScriptValueDeserializer::V8ScriptValueDeserializer(RefPtr<ScriptState> scriptS
tate, RefPtr<SerializedScriptValue> serializedScriptValue) |
20 : m_scriptState(std::move(scriptState)) | 22 : m_scriptState(std::move(scriptState)) |
21 , m_serializedScriptValue(std::move(serializedScriptValue)) | 23 , m_serializedScriptValue(std::move(serializedScriptValue)) |
22 , m_deserializer( | 24 , m_deserializer( |
23 m_scriptState->isolate(), | 25 m_scriptState->isolate(), |
24 reinterpret_cast<const uint8_t*>( | 26 reinterpret_cast<const uint8_t*>( |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
97 const void* utf8Data = nullptr; | 99 const void* utf8Data = nullptr; |
98 if (!readUint32(&utf8Length) || !readRawBytes(utf8Length, &utf8Data)) | 100 if (!readUint32(&utf8Length) || !readRawBytes(utf8Length, &utf8Data)) |
99 return false; | 101 return false; |
100 *string = String::fromUTF8(reinterpret_cast<const LChar*>(utf8Data), utf8Len
gth); | 102 *string = String::fromUTF8(reinterpret_cast<const LChar*>(utf8Data), utf8Len
gth); |
101 return true; | 103 return true; |
102 } | 104 } |
103 | 105 |
104 ScriptWrappable* V8ScriptValueDeserializer::readDOMObject(SerializationTag tag) | 106 ScriptWrappable* V8ScriptValueDeserializer::readDOMObject(SerializationTag tag) |
105 { | 107 { |
106 switch (tag) { | 108 switch (tag) { |
| 109 case BlobTag: { |
| 110 if (version() < 3) |
| 111 return nullptr; |
| 112 String uuid, type; |
| 113 uint64_t size; |
| 114 if (!readUTF8String(&uuid) || !readUTF8String(&type) || !readUint64(&siz
e)) |
| 115 return nullptr; |
| 116 return Blob::create(getOrCreateBlobDataHandle(uuid, type, size)); |
| 117 } |
| 118 case BlobIndexTag: { |
| 119 if (version() < 6 || !m_blobInfoArray) |
| 120 return nullptr; |
| 121 uint32_t index = 0; |
| 122 if (!readUint32(&index) || index >= m_blobInfoArray->size()) |
| 123 return nullptr; |
| 124 const WebBlobInfo& info = (*m_blobInfoArray)[index]; |
| 125 return Blob::create(getOrCreateBlobDataHandle(info.uuid(), info.type(),
info.size())); |
| 126 } |
107 case ImageBitmapTag: { | 127 case ImageBitmapTag: { |
108 uint32_t originClean = 0, isPremultiplied = 0, width = 0, height = 0, pi
xelLength = 0; | 128 uint32_t originClean = 0, isPremultiplied = 0, width = 0, height = 0, pi
xelLength = 0; |
109 const void* pixels = nullptr; | 129 const void* pixels = nullptr; |
110 if (!readUint32(&originClean) || originClean > 1 | 130 if (!readUint32(&originClean) || originClean > 1 |
111 || !readUint32(&isPremultiplied) || isPremultiplied > 1 | 131 || !readUint32(&isPremultiplied) || isPremultiplied > 1 |
112 || !readUint32(&width) | 132 || !readUint32(&width) |
113 || !readUint32(&height) | 133 || !readUint32(&height) |
114 || !readUint32(&pixelLength) | 134 || !readUint32(&pixelLength) |
115 || !readRawBytes(pixelLength, &pixels)) | 135 || !readRawBytes(pixelLength, &pixels)) |
116 return nullptr; | 136 return nullptr; |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
164 canvas->setAssociatedCanvasId(canvasId); | 184 canvas->setAssociatedCanvasId(canvasId); |
165 canvas->setSurfaceId(clientId, localId, nonce); | 185 canvas->setSurfaceId(clientId, localId, nonce); |
166 return canvas; | 186 return canvas; |
167 } | 187 } |
168 default: | 188 default: |
169 break; | 189 break; |
170 } | 190 } |
171 return nullptr; | 191 return nullptr; |
172 } | 192 } |
173 | 193 |
| 194 RefPtr<BlobDataHandle> V8ScriptValueDeserializer::getOrCreateBlobDataHandle(cons
t String& uuid, const String& type, uint64_t size) |
| 195 { |
| 196 // The containing ssv may have a BDH for this uuid if this ssv is just being |
| 197 // passed from main to worker thread (for example). We use those values when
creating |
| 198 // the new blob instead of cons'ing up a new BDH. |
| 199 // |
| 200 // FIXME: Maybe we should require that it work that way where the ssv must h
ave a BDH for any |
| 201 // blobs it comes across during deserialization. Would require callers to ex
plicitly populate |
| 202 // the collection of BDH's for blobs to work, which would encourage lifetime
s to be considered |
| 203 // when passing ssv's around cross process. At present, we get 'lucky' in so
me cases because |
| 204 // the blob in the src process happens to still exist at the time the dest p
rocess is deserializing. |
| 205 // For example in sharedWorker.postMessage(...). |
| 206 BlobDataHandleMap& handles = m_serializedScriptValue->blobDataHandles(); |
| 207 BlobDataHandleMap::const_iterator it = handles.find(uuid); |
| 208 if (it != handles.end()) { |
| 209 RefPtr<BlobDataHandle> handle = it->value; |
| 210 DCHECK_EQ(handle->type(), type); |
| 211 DCHECK_EQ(handle->size(), size); |
| 212 return handle; |
| 213 } |
| 214 return BlobDataHandle::create(uuid, type, size); |
| 215 } |
| 216 |
174 v8::MaybeLocal<v8::Object> V8ScriptValueDeserializer::ReadHostObject(v8::Isolate
* isolate) | 217 v8::MaybeLocal<v8::Object> V8ScriptValueDeserializer::ReadHostObject(v8::Isolate
* isolate) |
175 { | 218 { |
176 DCHECK_EQ(isolate, m_scriptState->isolate()); | 219 DCHECK_EQ(isolate, m_scriptState->isolate()); |
177 ExceptionState exceptionState(isolate, ExceptionState::UnknownContext, nullp
tr, nullptr); | 220 ExceptionState exceptionState(isolate, ExceptionState::UnknownContext, nullp
tr, nullptr); |
178 ScriptWrappable* wrappable = nullptr; | 221 ScriptWrappable* wrappable = nullptr; |
179 SerializationTag tag = PaddingTag; | 222 SerializationTag tag = PaddingTag; |
180 if (readTag(&tag)) | 223 if (readTag(&tag)) |
181 wrappable = readDOMObject(tag); | 224 wrappable = readDOMObject(tag); |
182 if (!wrappable) { | 225 if (!wrappable) { |
183 exceptionState.throwDOMException(DataCloneError, "Unable to deserialize
cloned data."); | 226 exceptionState.throwDOMException(DataCloneError, "Unable to deserialize
cloned data."); |
184 return v8::MaybeLocal<v8::Object>(); | 227 return v8::MaybeLocal<v8::Object>(); |
185 } | 228 } |
186 v8::Local<v8::Object> creationContext = m_scriptState->context()->Global(); | 229 v8::Local<v8::Object> creationContext = m_scriptState->context()->Global(); |
187 v8::Local<v8::Value> wrapper = toV8(wrappable, creationContext, isolate); | 230 v8::Local<v8::Value> wrapper = toV8(wrappable, creationContext, isolate); |
188 DCHECK(wrapper->IsObject()); | 231 DCHECK(wrapper->IsObject()); |
189 return wrapper.As<v8::Object>(); | 232 return wrapper.As<v8::Object>(); |
190 } | 233 } |
191 | 234 |
192 } // namespace blink | 235 } // namespace blink |
OLD | NEW |