OLD | NEW |
---|---|
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "config.h" | 5 #include "config.h" |
6 #include "bindings/core/v8/ScriptValueSerializer.h" | 6 #include "bindings/core/v8/ScriptValueSerializer.h" |
7 | 7 |
8 #include "bindings/core/v8/V8ArrayBuffer.h" | 8 #include "bindings/core/v8/V8ArrayBuffer.h" |
9 #include "bindings/core/v8/V8ArrayBufferView.h" | 9 #include "bindings/core/v8/V8ArrayBufferView.h" |
10 #include "bindings/core/v8/V8Blob.h" | 10 #include "bindings/core/v8/V8Blob.h" |
11 #include "bindings/core/v8/V8File.h" | 11 #include "bindings/core/v8/V8File.h" |
12 #include "bindings/core/v8/V8FileList.h" | 12 #include "bindings/core/v8/V8FileList.h" |
13 #include "bindings/core/v8/V8ImageData.h" | 13 #include "bindings/core/v8/V8ImageData.h" |
14 #include "bindings/core/v8/V8MessagePort.h" | 14 #include "bindings/core/v8/V8MessagePort.h" |
15 #include "bindings/modules/v8/V8CryptoKey.h" | |
16 #include "bindings/modules/v8/V8DOMFileSystem.h" | |
17 #include "core/dom/DOMDataView.h" | 15 #include "core/dom/DOMDataView.h" |
18 #include "core/fileapi/Blob.h" | 16 #include "core/fileapi/Blob.h" |
19 #include "core/fileapi/File.h" | 17 #include "core/fileapi/File.h" |
20 #include "core/fileapi/FileList.h" | 18 #include "core/fileapi/FileList.h" |
21 #include "public/platform/Platform.h" | 19 #include "public/platform/Platform.h" |
22 #include "public/platform/WebBlobInfo.h" | 20 #include "public/platform/WebBlobInfo.h" |
23 #include "wtf/ArrayBuffer.h" | 21 #include "wtf/ArrayBuffer.h" |
24 #include "wtf/ArrayBufferContents.h" | 22 #include "wtf/ArrayBufferContents.h" |
25 #include "wtf/ArrayBufferView.h" | 23 #include "wtf/ArrayBufferView.h" |
26 #include "wtf/text/StringHash.h" | 24 #include "wtf/text/StringHash.h" |
27 #include "wtf/text/StringUTF8Adaptor.h" | 25 #include "wtf/text/StringUTF8Adaptor.h" |
28 | 26 |
29 // FIXME: consider crashing in debug mode on deserialization errors | 27 // FIXME: consider crashing in debug mode on deserialization errors |
30 // NOTE: be sure to change wireFormatVersion as necessary! | 28 // NOTE: be sure to change wireFormatVersion as necessary! |
31 | 29 |
32 namespace blink { | 30 namespace blink { |
33 | 31 |
34 namespace SerializedScriptValueInternal { | |
35 | |
36 // This code implements the HTML5 Structured Clone algorithm: | 32 // This code implements the HTML5 Structured Clone algorithm: |
37 // http://www.whatwg.org/specs/web-apps/current-work/multipage/urls.html#safe-pa ssing-of-structured-data | 33 // http://www.whatwg.org/specs/web-apps/current-work/multipage/urls.html#safe-pa ssing-of-structured-data |
38 | 34 |
39 // ZigZag encoding helps VarInt encoding stay small for negative | 35 // ZigZag encoding helps VarInt encoding stay small for negative |
40 // numbers with small absolute values. | 36 // numbers with small absolute values. |
41 class ZigZag { | 37 class ZigZag { |
42 public: | 38 public: |
43 static uint32_t encode(uint32_t value) | 39 static uint32_t encode(uint32_t value) |
44 { | 40 { |
45 if (value & (1U << 31)) | 41 if (value & (1U << 31)) |
(...skipping 20 matching lines...) Expand all Loading... | |
66 | 62 |
67 static bool shouldCheckForCycles(int depth) | 63 static bool shouldCheckForCycles(int depth) |
68 { | 64 { |
69 ASSERT(depth >= 0); | 65 ASSERT(depth >= 0); |
70 // Since we are not required to spot the cycle as soon as it | 66 // Since we are not required to spot the cycle as soon as it |
71 // happens we can check for cycles only when the current depth | 67 // happens we can check for cycles only when the current depth |
72 // is a power of two. | 68 // is a power of two. |
73 return !(depth & (depth - 1)); | 69 return !(depth & (depth - 1)); |
74 } | 70 } |
75 | 71 |
76 void Writer::writeUndefined() | 72 void SerializedScriptValueWriter::writeUndefined() |
77 { | 73 { |
78 append(UndefinedTag); | 74 append(UndefinedTag); |
79 } | 75 } |
80 | 76 |
81 void Writer::writeNull() | 77 void SerializedScriptValueWriter::writeNull() |
82 { | 78 { |
83 append(NullTag); | 79 append(NullTag); |
84 } | 80 } |
85 | 81 |
86 void Writer::writeTrue() | 82 void SerializedScriptValueWriter::writeTrue() |
87 { | 83 { |
88 append(TrueTag); | 84 append(TrueTag); |
89 } | 85 } |
90 | 86 |
91 void Writer::writeFalse() | 87 void SerializedScriptValueWriter::writeFalse() |
92 { | 88 { |
93 append(FalseTag); | 89 append(FalseTag); |
94 } | 90 } |
95 | 91 |
96 void Writer::writeBooleanObject(bool value) | 92 void SerializedScriptValueWriter::writeBooleanObject(bool value) |
97 { | 93 { |
98 append(value ? TrueObjectTag : FalseObjectTag); | 94 append(value ? TrueObjectTag : FalseObjectTag); |
99 } | 95 } |
100 | 96 |
101 void Writer::writeOneByteString(v8::Handle<v8::String>& string) | 97 void SerializedScriptValueWriter::writeOneByteString(v8::Handle<v8::String>& str ing) |
102 { | 98 { |
103 int stringLength = string->Length(); | 99 int stringLength = string->Length(); |
104 int utf8Length = string->Utf8Length(); | 100 int utf8Length = string->Utf8Length(); |
105 ASSERT(stringLength >= 0 && utf8Length >= 0); | 101 ASSERT(stringLength >= 0 && utf8Length >= 0); |
106 | 102 |
107 append(StringTag); | 103 append(StringTag); |
108 doWriteUint32(static_cast<uint32_t>(utf8Length)); | 104 doWriteUint32(static_cast<uint32_t>(utf8Length)); |
109 ensureSpace(utf8Length); | 105 ensureSpace(utf8Length); |
110 | 106 |
111 // ASCII fast path. | 107 // ASCII fast path. |
112 if (stringLength == utf8Length) { | 108 if (stringLength == utf8Length) { |
113 string->WriteOneByte(byteAt(m_position), 0, utf8Length, v8StringWriteOpt ions()); | 109 string->WriteOneByte(byteAt(m_position), 0, utf8Length, v8StringWriteOpt ions()); |
114 } else { | 110 } else { |
115 char* buffer = reinterpret_cast<char*>(byteAt(m_position)); | 111 char* buffer = reinterpret_cast<char*>(byteAt(m_position)); |
116 string->WriteUtf8(buffer, utf8Length, 0, v8StringWriteOptions()); | 112 string->WriteUtf8(buffer, utf8Length, 0, v8StringWriteOptions()); |
117 } | 113 } |
118 m_position += utf8Length; | 114 m_position += utf8Length; |
119 } | 115 } |
120 | 116 |
121 void Writer::writeUCharString(v8::Handle<v8::String>& string) | 117 void SerializedScriptValueWriter::writeUCharString(v8::Handle<v8::String>& strin g) |
122 { | 118 { |
123 int length = string->Length(); | 119 int length = string->Length(); |
124 ASSERT(length >= 0); | 120 ASSERT(length >= 0); |
125 | 121 |
126 int size = length * sizeof(UChar); | 122 int size = length * sizeof(UChar); |
127 int bytes = bytesNeededToWireEncode(static_cast<uint32_t>(size)); | 123 int bytes = bytesNeededToWireEncode(static_cast<uint32_t>(size)); |
128 if ((m_position + 1 + bytes) & 1) | 124 if ((m_position + 1 + bytes) & 1) |
129 append(PaddingTag); | 125 append(PaddingTag); |
130 | 126 |
131 append(StringUCharTag); | 127 append(StringUCharTag); |
132 doWriteUint32(static_cast<uint32_t>(size)); | 128 doWriteUint32(static_cast<uint32_t>(size)); |
133 ensureSpace(size); | 129 ensureSpace(size); |
134 | 130 |
135 ASSERT(!(m_position & 1)); | 131 ASSERT(!(m_position & 1)); |
136 uint16_t* buffer = reinterpret_cast<uint16_t*>(byteAt(m_position)); | 132 uint16_t* buffer = reinterpret_cast<uint16_t*>(byteAt(m_position)); |
137 string->Write(buffer, 0, length, v8StringWriteOptions()); | 133 string->Write(buffer, 0, length, v8StringWriteOptions()); |
138 m_position += size; | 134 m_position += size; |
139 } | 135 } |
140 | 136 |
141 void Writer::writeStringObject(const char* data, int length) | 137 void SerializedScriptValueWriter::writeStringObject(const char* data, int length ) |
142 { | 138 { |
143 ASSERT(length >= 0); | 139 ASSERT(length >= 0); |
144 append(StringObjectTag); | 140 append(StringObjectTag); |
145 doWriteString(data, length); | 141 doWriteString(data, length); |
146 } | 142 } |
147 | 143 |
148 void Writer::writeWebCoreString(const String& string) | 144 void SerializedScriptValueWriter::writeWebCoreString(const String& string) |
149 { | 145 { |
150 // Uses UTF8 encoding so we can read it back as either V8 or | 146 // Uses UTF8 encoding so we can read it back as either V8 or |
151 // WebCore string. | 147 // WebCore string. |
152 append(StringTag); | 148 append(StringTag); |
153 doWriteWebCoreString(string); | 149 doWriteWebCoreString(string); |
154 } | 150 } |
155 | 151 |
156 void Writer::writeVersion() | 152 void SerializedScriptValueWriter::writeVersion() |
157 { | 153 { |
158 append(VersionTag); | 154 append(VersionTag); |
159 doWriteUint32(SerializedScriptValue::wireFormatVersion); | 155 doWriteUint32(SerializedScriptValue::wireFormatVersion); |
160 } | 156 } |
161 | 157 |
162 void Writer::writeInt32(int32_t value) | 158 void SerializedScriptValueWriter::writeInt32(int32_t value) |
163 { | 159 { |
164 append(Int32Tag); | 160 append(Int32Tag); |
165 doWriteUint32(ZigZag::encode(static_cast<uint32_t>(value))); | 161 doWriteUint32(ZigZag::encode(static_cast<uint32_t>(value))); |
166 } | 162 } |
167 | 163 |
168 void Writer::writeUint32(uint32_t value) | 164 void SerializedScriptValueWriter::writeUint32(uint32_t value) |
169 { | 165 { |
170 append(Uint32Tag); | 166 append(Uint32Tag); |
171 doWriteUint32(value); | 167 doWriteUint32(value); |
172 } | 168 } |
173 | 169 |
174 void Writer::writeDate(double numberValue) | 170 void SerializedScriptValueWriter::writeDate(double numberValue) |
175 { | 171 { |
176 append(DateTag); | 172 append(DateTag); |
177 doWriteNumber(numberValue); | 173 doWriteNumber(numberValue); |
178 } | 174 } |
179 | 175 |
180 void Writer::writeNumber(double number) | 176 void SerializedScriptValueWriter::writeNumber(double number) |
181 { | 177 { |
182 append(NumberTag); | 178 append(NumberTag); |
183 doWriteNumber(number); | 179 doWriteNumber(number); |
184 } | 180 } |
185 | 181 |
186 void Writer::writeNumberObject(double number) | 182 void SerializedScriptValueWriter::writeNumberObject(double number) |
187 { | 183 { |
188 append(NumberObjectTag); | 184 append(NumberObjectTag); |
189 doWriteNumber(number); | 185 doWriteNumber(number); |
190 } | 186 } |
191 | 187 |
192 void Writer::writeBlob(const String& uuid, const String& type, unsigned long lon g size) | 188 void SerializedScriptValueWriter::writeBlob(const String& uuid, const String& ty pe, unsigned long long size) |
193 { | 189 { |
194 append(BlobTag); | 190 append(BlobTag); |
195 doWriteWebCoreString(uuid); | 191 doWriteWebCoreString(uuid); |
196 doWriteWebCoreString(type); | 192 doWriteWebCoreString(type); |
197 doWriteUint64(size); | 193 doWriteUint64(size); |
198 } | 194 } |
199 | 195 |
200 void Writer::writeDOMFileSystem(int type, const String& name, const String& url) | 196 void SerializedScriptValueWriter::writeBlobIndex(int blobIndex) |
201 { | |
202 append(DOMFileSystemTag); | |
203 doWriteUint32(type); | |
204 doWriteWebCoreString(name); | |
205 doWriteWebCoreString(url); | |
206 } | |
207 | |
208 void Writer::writeBlobIndex(int blobIndex) | |
209 { | 197 { |
210 ASSERT(blobIndex >= 0); | 198 ASSERT(blobIndex >= 0); |
211 append(BlobIndexTag); | 199 append(BlobIndexTag); |
212 doWriteUint32(blobIndex); | 200 doWriteUint32(blobIndex); |
213 } | 201 } |
214 | 202 |
215 void Writer::writeFile(const File& file) | 203 void SerializedScriptValueWriter::writeFile(const File& file) |
216 { | 204 { |
217 append(FileTag); | 205 append(FileTag); |
218 doWriteFile(file); | 206 doWriteFile(file); |
219 } | 207 } |
220 | 208 |
221 void Writer::writeFileIndex(int blobIndex) | 209 void SerializedScriptValueWriter::writeFileIndex(int blobIndex) |
222 { | 210 { |
223 append(FileIndexTag); | 211 append(FileIndexTag); |
224 doWriteUint32(blobIndex); | 212 doWriteUint32(blobIndex); |
225 } | 213 } |
226 | 214 |
227 void Writer::writeFileList(const FileList& fileList) | 215 void SerializedScriptValueWriter::writeFileList(const FileList& fileList) |
228 { | 216 { |
229 append(FileListTag); | 217 append(FileListTag); |
230 uint32_t length = fileList.length(); | 218 uint32_t length = fileList.length(); |
231 doWriteUint32(length); | 219 doWriteUint32(length); |
232 for (unsigned i = 0; i < length; ++i) | 220 for (unsigned i = 0; i < length; ++i) |
233 doWriteFile(*fileList.item(i)); | 221 doWriteFile(*fileList.item(i)); |
234 } | 222 } |
235 | 223 |
236 void Writer::writeFileListIndex(const Vector<int>& blobIndices) | 224 void SerializedScriptValueWriter::writeFileListIndex(const Vector<int>& blobIndi ces) |
237 { | 225 { |
238 append(FileListIndexTag); | 226 append(FileListIndexTag); |
239 uint32_t length = blobIndices.size(); | 227 uint32_t length = blobIndices.size(); |
240 doWriteUint32(length); | 228 doWriteUint32(length); |
241 for (unsigned i = 0; i < length; ++i) | 229 for (unsigned i = 0; i < length; ++i) |
242 doWriteUint32(blobIndices[i]); | 230 doWriteUint32(blobIndices[i]); |
243 } | 231 } |
244 | 232 |
245 bool Writer::writeCryptoKey(const WebCryptoKey& key) | 233 void SerializedScriptValueWriter::writeArrayBuffer(const ArrayBuffer& arrayBuffe r) |
246 { | |
247 append(static_cast<uint8_t>(CryptoKeyTag)); | |
248 | |
249 switch (key.algorithm().paramsType()) { | |
250 case WebCryptoKeyAlgorithmParamsTypeAes: | |
251 doWriteAesKey(key); | |
252 break; | |
253 case WebCryptoKeyAlgorithmParamsTypeHmac: | |
254 doWriteHmacKey(key); | |
255 break; | |
256 case WebCryptoKeyAlgorithmParamsTypeRsaHashed: | |
257 doWriteRsaHashedKey(key); | |
258 break; | |
259 case WebCryptoKeyAlgorithmParamsTypeEc: | |
260 doWriteEcKey(key); | |
261 break; | |
262 case WebCryptoKeyAlgorithmParamsTypeNone: | |
263 ASSERT_NOT_REACHED(); | |
264 return false; | |
265 } | |
266 | |
267 doWriteKeyUsages(key.usages(), key.extractable()); | |
268 | |
269 WebVector<uint8_t> keyData; | |
270 if (!Platform::current()->crypto()->serializeKeyForClone(key, keyData)) | |
271 return false; | |
272 | |
273 doWriteUint32(keyData.size()); | |
274 append(keyData.data(), keyData.size()); | |
275 return true; | |
276 } | |
277 | |
278 void Writer::writeArrayBuffer(const ArrayBuffer& arrayBuffer) | |
279 { | 234 { |
280 append(ArrayBufferTag); | 235 append(ArrayBufferTag); |
281 doWriteArrayBuffer(arrayBuffer); | 236 doWriteArrayBuffer(arrayBuffer); |
282 } | 237 } |
283 | 238 |
284 void Writer::writeArrayBufferView(const ArrayBufferView& arrayBufferView) | 239 void SerializedScriptValueWriter::writeArrayBufferView(const ArrayBufferView& ar rayBufferView) |
285 { | 240 { |
286 append(ArrayBufferViewTag); | 241 append(ArrayBufferViewTag); |
287 #if ENABLE(ASSERT) | 242 #if ENABLE(ASSERT) |
288 const ArrayBuffer& arrayBuffer = *arrayBufferView.buffer(); | 243 const ArrayBuffer& arrayBuffer = *arrayBufferView.buffer(); |
289 ASSERT(static_cast<const uint8_t*>(arrayBuffer.data()) + arrayBufferView.byt eOffset() == | 244 ASSERT(static_cast<const uint8_t*>(arrayBuffer.data()) + arrayBufferView.byt eOffset() == |
290 static_cast<const uint8_t*>(arrayBufferView.baseAddress())); | 245 static_cast<const uint8_t*>(arrayBufferView.baseAddress())); |
291 #endif | 246 #endif |
292 ArrayBufferView::ViewType type = arrayBufferView.type(); | 247 ArrayBufferView::ViewType type = arrayBufferView.type(); |
293 | 248 |
294 if (type == ArrayBufferView::TypeInt8) | 249 if (type == ArrayBufferView::TypeInt8) |
(...skipping 15 matching lines...) Expand all Loading... | |
310 else if (type == ArrayBufferView::TypeFloat64) | 265 else if (type == ArrayBufferView::TypeFloat64) |
311 append(DoubleArrayTag); | 266 append(DoubleArrayTag); |
312 else if (type == ArrayBufferView::TypeDataView) | 267 else if (type == ArrayBufferView::TypeDataView) |
313 append(DataViewTag); | 268 append(DataViewTag); |
314 else | 269 else |
315 ASSERT_NOT_REACHED(); | 270 ASSERT_NOT_REACHED(); |
316 doWriteUint32(arrayBufferView.byteOffset()); | 271 doWriteUint32(arrayBufferView.byteOffset()); |
317 doWriteUint32(arrayBufferView.byteLength()); | 272 doWriteUint32(arrayBufferView.byteLength()); |
318 } | 273 } |
319 | 274 |
320 void Writer::writeImageData(uint32_t width, uint32_t height, const uint8_t* pixe lData, uint32_t pixelDataLength) | 275 void SerializedScriptValueWriter::writeImageData(uint32_t width, uint32_t height , const uint8_t* pixelData, uint32_t pixelDataLength) |
321 { | 276 { |
322 append(ImageDataTag); | 277 append(ImageDataTag); |
323 doWriteUint32(width); | 278 doWriteUint32(width); |
324 doWriteUint32(height); | 279 doWriteUint32(height); |
325 doWriteUint32(pixelDataLength); | 280 doWriteUint32(pixelDataLength); |
326 append(pixelData, pixelDataLength); | 281 append(pixelData, pixelDataLength); |
327 } | 282 } |
328 | 283 |
329 void Writer::writeRegExp(v8::Local<v8::String> pattern, v8::RegExp::Flags flags) | 284 void SerializedScriptValueWriter::writeRegExp(v8::Local<v8::String> pattern, v8: :RegExp::Flags flags) |
330 { | 285 { |
331 append(RegExpTag); | 286 append(RegExpTag); |
332 v8::String::Utf8Value patternUtf8Value(pattern); | 287 v8::String::Utf8Value patternUtf8Value(pattern); |
333 doWriteString(*patternUtf8Value, patternUtf8Value.length()); | 288 doWriteString(*patternUtf8Value, patternUtf8Value.length()); |
334 doWriteUint32(static_cast<uint32_t>(flags)); | 289 doWriteUint32(static_cast<uint32_t>(flags)); |
335 } | 290 } |
336 | 291 |
337 void Writer::writeTransferredMessagePort(uint32_t index) | 292 void SerializedScriptValueWriter::writeTransferredMessagePort(uint32_t index) |
338 { | 293 { |
339 append(MessagePortTag); | 294 append(MessagePortTag); |
340 doWriteUint32(index); | 295 doWriteUint32(index); |
341 } | 296 } |
342 | 297 |
343 void Writer::writeTransferredArrayBuffer(uint32_t index) | 298 void SerializedScriptValueWriter::writeTransferredArrayBuffer(uint32_t index) |
344 { | 299 { |
345 append(ArrayBufferTransferTag); | 300 append(ArrayBufferTransferTag); |
346 doWriteUint32(index); | 301 doWriteUint32(index); |
347 } | 302 } |
348 | 303 |
349 void Writer::writeObjectReference(uint32_t reference) | 304 void SerializedScriptValueWriter::writeObjectReference(uint32_t reference) |
350 { | 305 { |
351 append(ObjectReferenceTag); | 306 append(ObjectReferenceTag); |
352 doWriteUint32(reference); | 307 doWriteUint32(reference); |
353 } | 308 } |
354 | 309 |
355 void Writer::writeObject(uint32_t numProperties) | 310 void SerializedScriptValueWriter::writeObject(uint32_t numProperties) |
356 { | 311 { |
357 append(ObjectTag); | 312 append(ObjectTag); |
358 doWriteUint32(numProperties); | 313 doWriteUint32(numProperties); |
359 } | 314 } |
360 | 315 |
361 void Writer::writeSparseArray(uint32_t numProperties, uint32_t length) | 316 void SerializedScriptValueWriter::writeSparseArray(uint32_t numProperties, uint3 2_t length) |
362 { | 317 { |
363 append(SparseArrayTag); | 318 append(SparseArrayTag); |
364 doWriteUint32(numProperties); | 319 doWriteUint32(numProperties); |
365 doWriteUint32(length); | 320 doWriteUint32(length); |
366 } | 321 } |
367 | 322 |
368 void Writer::writeDenseArray(uint32_t numProperties, uint32_t length) | 323 void SerializedScriptValueWriter::writeDenseArray(uint32_t numProperties, uint32 _t length) |
369 { | 324 { |
370 append(DenseArrayTag); | 325 append(DenseArrayTag); |
371 doWriteUint32(numProperties); | 326 doWriteUint32(numProperties); |
372 doWriteUint32(length); | 327 doWriteUint32(length); |
373 } | 328 } |
374 | 329 |
375 String Writer::takeWireString() | 330 String SerializedScriptValueWriter::takeWireString() |
376 { | 331 { |
377 COMPILE_ASSERT(sizeof(BufferValueType) == 2, BufferValueTypeIsTwoBytes); | 332 COMPILE_ASSERT(sizeof(BufferValueType) == 2, BufferValueTypeIsTwoBytes); |
378 fillHole(); | 333 fillHole(); |
379 String data = String(m_buffer.data(), m_buffer.size()); | 334 String data = String(m_buffer.data(), m_buffer.size()); |
380 data.impl()->truncateAssumingIsolated((m_position + 1) / sizeof(BufferValueT ype)); | 335 data.impl()->truncateAssumingIsolated((m_position + 1) / sizeof(BufferValueT ype)); |
381 return data; | 336 return data; |
382 } | 337 } |
383 | 338 |
384 void Writer::writeReferenceCount(uint32_t numberOfReferences) | 339 void SerializedScriptValueWriter::writeReferenceCount(uint32_t numberOfReference s) |
385 { | 340 { |
386 append(ReferenceCountTag); | 341 append(ReferenceCountTag); |
387 doWriteUint32(numberOfReferences); | 342 doWriteUint32(numberOfReferences); |
388 } | 343 } |
389 | 344 |
390 void Writer::writeGenerateFreshObject() | 345 void SerializedScriptValueWriter::writeGenerateFreshObject() |
391 { | 346 { |
392 append(GenerateFreshObjectTag); | 347 append(GenerateFreshObjectTag); |
393 } | 348 } |
394 | 349 |
395 void Writer::writeGenerateFreshSparseArray(uint32_t length) | 350 void SerializedScriptValueWriter::writeGenerateFreshSparseArray(uint32_t length) |
396 { | 351 { |
397 append(GenerateFreshSparseArrayTag); | 352 append(GenerateFreshSparseArrayTag); |
398 doWriteUint32(length); | 353 doWriteUint32(length); |
399 } | 354 } |
400 | 355 |
401 void Writer::writeGenerateFreshDenseArray(uint32_t length) | 356 void SerializedScriptValueWriter::writeGenerateFreshDenseArray(uint32_t length) |
402 { | 357 { |
403 append(GenerateFreshDenseArrayTag); | 358 append(GenerateFreshDenseArrayTag); |
404 doWriteUint32(length); | 359 doWriteUint32(length); |
405 } | 360 } |
406 | 361 |
407 void Writer::doWriteFile(const File& file) | 362 void SerializedScriptValueWriter::doWriteFile(const File& file) |
408 { | 363 { |
409 doWriteWebCoreString(file.hasBackingFile() ? file.path() : ""); | 364 doWriteWebCoreString(file.hasBackingFile() ? file.path() : ""); |
410 doWriteWebCoreString(file.name()); | 365 doWriteWebCoreString(file.name()); |
411 doWriteWebCoreString(file.webkitRelativePath()); | 366 doWriteWebCoreString(file.webkitRelativePath()); |
412 doWriteWebCoreString(file.uuid()); | 367 doWriteWebCoreString(file.uuid()); |
413 doWriteWebCoreString(file.type()); | 368 doWriteWebCoreString(file.type()); |
414 | 369 |
415 // FIXME don't use 1 byte to encode a flag. | 370 // FIXME don't use 1 byte to encode a flag. |
416 if (file.hasValidSnapshotMetadata()) { | 371 if (file.hasValidSnapshotMetadata()) { |
417 doWriteUint32(static_cast<uint8_t>(1)); | 372 doWriteUint32(static_cast<uint8_t>(1)); |
418 | 373 |
419 long long size; | 374 long long size; |
420 double lastModified; | 375 double lastModified; |
421 file.captureSnapshot(size, lastModified); | 376 file.captureSnapshot(size, lastModified); |
422 doWriteUint64(static_cast<uint64_t>(size)); | 377 doWriteUint64(static_cast<uint64_t>(size)); |
423 doWriteNumber(lastModified); | 378 doWriteNumber(lastModified); |
424 } else { | 379 } else { |
425 doWriteUint32(static_cast<uint8_t>(0)); | 380 doWriteUint32(static_cast<uint8_t>(0)); |
426 } | 381 } |
427 | 382 |
428 doWriteUint32(static_cast<uint8_t>((file.userVisibility() == File::IsUserVis ible) ? 1 : 0)); | 383 doWriteUint32(static_cast<uint8_t>((file.userVisibility() == File::IsUserVis ible) ? 1 : 0)); |
429 } | 384 } |
430 | 385 |
431 void Writer::doWriteArrayBuffer(const ArrayBuffer& arrayBuffer) | 386 void SerializedScriptValueWriter::doWriteArrayBuffer(const ArrayBuffer& arrayBuf fer) |
432 { | 387 { |
433 uint32_t byteLength = arrayBuffer.byteLength(); | 388 uint32_t byteLength = arrayBuffer.byteLength(); |
434 doWriteUint32(byteLength); | 389 doWriteUint32(byteLength); |
435 append(static_cast<const uint8_t*>(arrayBuffer.data()), byteLength); | 390 append(static_cast<const uint8_t*>(arrayBuffer.data()), byteLength); |
436 } | 391 } |
437 | 392 |
438 void Writer::doWriteString(const char* data, int length) | 393 void SerializedScriptValueWriter::doWriteString(const char* data, int length) |
439 { | 394 { |
440 doWriteUint32(static_cast<uint32_t>(length)); | 395 doWriteUint32(static_cast<uint32_t>(length)); |
441 append(reinterpret_cast<const uint8_t*>(data), length); | 396 append(reinterpret_cast<const uint8_t*>(data), length); |
442 } | 397 } |
443 | 398 |
444 void Writer::doWriteWebCoreString(const String& string) | 399 void SerializedScriptValueWriter::doWriteWebCoreString(const String& string) |
445 { | 400 { |
446 StringUTF8Adaptor stringUTF8(string); | 401 StringUTF8Adaptor stringUTF8(string); |
447 doWriteString(stringUTF8.data(), stringUTF8.length()); | 402 doWriteString(stringUTF8.data(), stringUTF8.length()); |
448 } | 403 } |
449 | 404 |
450 void Writer::doWriteHmacKey(const WebCryptoKey& key) | 405 int SerializedScriptValueWriter::bytesNeededToWireEncode(uint32_t value) |
451 { | |
452 ASSERT(key.algorithm().paramsType() == WebCryptoKeyAlgorithmParamsTypeHmac); | |
453 | |
454 append(static_cast<uint8_t>(HmacKeyTag)); | |
455 ASSERT(!(key.algorithm().hmacParams()->lengthBits() % 8)); | |
456 doWriteUint32(key.algorithm().hmacParams()->lengthBits() / 8); | |
457 doWriteAlgorithmId(key.algorithm().hmacParams()->hash().id()); | |
458 } | |
459 | |
460 void Writer::doWriteAesKey(const WebCryptoKey& key) | |
461 { | |
462 ASSERT(key.algorithm().paramsType() == WebCryptoKeyAlgorithmParamsTypeAes); | |
463 | |
464 append(static_cast<uint8_t>(AesKeyTag)); | |
465 doWriteAlgorithmId(key.algorithm().id()); | |
466 // Converting the key length from bits to bytes is lossless and makes | |
467 // it fit in 1 byte. | |
468 ASSERT(!(key.algorithm().aesParams()->lengthBits() % 8)); | |
469 doWriteUint32(key.algorithm().aesParams()->lengthBits() / 8); | |
470 } | |
471 | |
472 void Writer::doWriteRsaHashedKey(const WebCryptoKey& key) | |
473 { | |
474 ASSERT(key.algorithm().rsaHashedParams()); | |
475 append(static_cast<uint8_t>(RsaHashedKeyTag)); | |
476 | |
477 doWriteAlgorithmId(key.algorithm().id()); | |
478 doWriteAsymmetricKeyType(key.type()); | |
479 | |
480 const WebCryptoRsaHashedKeyAlgorithmParams* params = key.algorithm().rsaHash edParams(); | |
481 doWriteUint32(params->modulusLengthBits()); | |
482 doWriteUint32(params->publicExponent().size()); | |
483 append(params->publicExponent().data(), params->publicExponent().size()); | |
484 doWriteAlgorithmId(params->hash().id()); | |
485 } | |
486 | |
487 void Writer::doWriteEcKey(const WebCryptoKey& key) | |
488 { | |
489 ASSERT(key.algorithm().ecParams()); | |
490 append(static_cast<uint8_t>(EcKeyTag)); | |
491 | |
492 doWriteAlgorithmId(key.algorithm().id()); | |
493 doWriteAsymmetricKeyType(key.type()); | |
494 doWriteNamedCurve(key.algorithm().ecParams()->namedCurve()); | |
495 } | |
496 | |
497 void Writer::doWriteAlgorithmId(WebCryptoAlgorithmId id) | |
498 { | |
499 switch (id) { | |
500 case WebCryptoAlgorithmIdAesCbc: | |
501 return doWriteUint32(AesCbcTag); | |
502 case WebCryptoAlgorithmIdHmac: | |
503 return doWriteUint32(HmacTag); | |
504 case WebCryptoAlgorithmIdRsaSsaPkcs1v1_5: | |
505 return doWriteUint32(RsaSsaPkcs1v1_5Tag); | |
506 case WebCryptoAlgorithmIdSha1: | |
507 return doWriteUint32(Sha1Tag); | |
508 case WebCryptoAlgorithmIdSha256: | |
509 return doWriteUint32(Sha256Tag); | |
510 case WebCryptoAlgorithmIdSha384: | |
511 return doWriteUint32(Sha384Tag); | |
512 case WebCryptoAlgorithmIdSha512: | |
513 return doWriteUint32(Sha512Tag); | |
514 case WebCryptoAlgorithmIdAesGcm: | |
515 return doWriteUint32(AesGcmTag); | |
516 case WebCryptoAlgorithmIdRsaOaep: | |
517 return doWriteUint32(RsaOaepTag); | |
518 case WebCryptoAlgorithmIdAesCtr: | |
519 return doWriteUint32(AesCtrTag); | |
520 case WebCryptoAlgorithmIdAesKw: | |
521 return doWriteUint32(AesKwTag); | |
522 case WebCryptoAlgorithmIdRsaPss: | |
523 return doWriteUint32(RsaPssTag); | |
524 case WebCryptoAlgorithmIdEcdsa: | |
525 return doWriteUint32(EcdsaTag); | |
526 } | |
527 ASSERT_NOT_REACHED(); | |
528 } | |
529 | |
530 void Writer::doWriteAsymmetricKeyType(WebCryptoKeyType keyType) | |
531 { | |
532 switch (keyType) { | |
533 case WebCryptoKeyTypePublic: | |
534 doWriteUint32(PublicKeyType); | |
535 break; | |
536 case WebCryptoKeyTypePrivate: | |
537 doWriteUint32(PrivateKeyType); | |
538 break; | |
539 case WebCryptoKeyTypeSecret: | |
540 ASSERT_NOT_REACHED(); | |
541 } | |
542 } | |
543 | |
544 void Writer::doWriteNamedCurve(WebCryptoNamedCurve namedCurve) | |
545 { | |
546 switch (namedCurve) { | |
547 case WebCryptoNamedCurveP256: | |
548 return doWriteUint32(P256Tag); | |
549 case WebCryptoNamedCurveP384: | |
550 return doWriteUint32(P384Tag); | |
551 case WebCryptoNamedCurveP521: | |
552 return doWriteUint32(P521Tag); | |
553 } | |
554 ASSERT_NOT_REACHED(); | |
555 } | |
556 | |
557 void Writer::doWriteKeyUsages(const WebCryptoKeyUsageMask usages, bool extractab le) | |
558 { | |
559 // Reminder to update this when adding new key usages. | |
560 COMPILE_ASSERT(EndOfWebCryptoKeyUsage == (1 << 7) + 1, UpdateMe); | |
561 | |
562 uint32_t value = 0; | |
563 | |
564 if (extractable) | |
565 value |= ExtractableUsage; | |
566 | |
567 if (usages & WebCryptoKeyUsageEncrypt) | |
568 value |= EncryptUsage; | |
569 if (usages & WebCryptoKeyUsageDecrypt) | |
570 value |= DecryptUsage; | |
571 if (usages & WebCryptoKeyUsageSign) | |
572 value |= SignUsage; | |
573 if (usages & WebCryptoKeyUsageVerify) | |
574 value |= VerifyUsage; | |
575 if (usages & WebCryptoKeyUsageDeriveKey) | |
576 value |= DeriveKeyUsage; | |
577 if (usages & WebCryptoKeyUsageWrapKey) | |
578 value |= WrapKeyUsage; | |
579 if (usages & WebCryptoKeyUsageUnwrapKey) | |
580 value |= UnwrapKeyUsage; | |
581 if (usages & WebCryptoKeyUsageDeriveBits) | |
582 value |= DeriveBitsUsage; | |
583 | |
584 doWriteUint32(value); | |
585 } | |
586 | |
587 int Writer::bytesNeededToWireEncode(uint32_t value) | |
588 { | 406 { |
589 int bytes = 1; | 407 int bytes = 1; |
590 while (true) { | 408 while (true) { |
591 value >>= SerializedScriptValue::varIntShift; | 409 value >>= SerializedScriptValue::varIntShift; |
592 if (!value) | 410 if (!value) |
593 break; | 411 break; |
594 ++bytes; | 412 ++bytes; |
595 } | 413 } |
596 | 414 |
597 return bytes; | 415 return bytes; |
598 } | 416 } |
599 | 417 |
600 void Writer::doWriteUint32(uint32_t value) | 418 void SerializedScriptValueWriter::doWriteUint32(uint32_t value) |
601 { | 419 { |
602 doWriteUintHelper(value); | 420 doWriteUintHelper(value); |
603 } | 421 } |
604 | 422 |
605 void Writer::doWriteUint64(uint64_t value) | 423 void SerializedScriptValueWriter::doWriteUint64(uint64_t value) |
606 { | 424 { |
607 doWriteUintHelper(value); | 425 doWriteUintHelper(value); |
608 } | 426 } |
609 | 427 |
610 void Writer::doWriteNumber(double number) | 428 void SerializedScriptValueWriter::doWriteNumber(double number) |
611 { | 429 { |
612 append(reinterpret_cast<uint8_t*>(&number), sizeof(number)); | 430 append(reinterpret_cast<uint8_t*>(&number), sizeof(number)); |
613 } | 431 } |
614 | 432 |
615 void Writer::append(SerializationTag tag) | 433 void SerializedScriptValueWriter::append(SerializationTag tag) |
616 { | 434 { |
617 append(static_cast<uint8_t>(tag)); | 435 append(static_cast<uint8_t>(tag)); |
618 } | 436 } |
619 | 437 |
620 void Writer::append(uint8_t b) | 438 void SerializedScriptValueWriter::append(uint8_t b) |
621 { | 439 { |
622 ensureSpace(1); | 440 ensureSpace(1); |
623 *byteAt(m_position++) = b; | 441 *byteAt(m_position++) = b; |
624 } | 442 } |
625 | 443 |
626 void Writer::append(const uint8_t* data, int length) | 444 void SerializedScriptValueWriter::append(const uint8_t* data, int length) |
627 { | 445 { |
628 ensureSpace(length); | 446 ensureSpace(length); |
629 memcpy(byteAt(m_position), data, length); | 447 memcpy(byteAt(m_position), data, length); |
630 m_position += length; | 448 m_position += length; |
631 } | 449 } |
632 | 450 |
633 void Writer::ensureSpace(unsigned extra) | 451 void SerializedScriptValueWriter::ensureSpace(unsigned extra) |
634 { | 452 { |
635 COMPILE_ASSERT(sizeof(BufferValueType) == 2, BufferValueTypeIsTwoBytes); | 453 COMPILE_ASSERT(sizeof(BufferValueType) == 2, BufferValueTypeIsTwoBytes); |
636 m_buffer.resize((m_position + extra + 1) / sizeof(BufferValueType)); // "+ 1 " to round up. | 454 m_buffer.resize((m_position + extra + 1) / sizeof(BufferValueType)); // "+ 1 " to round up. |
637 } | 455 } |
638 | 456 |
639 void Writer::fillHole() | 457 void SerializedScriptValueWriter::fillHole() |
640 { | 458 { |
641 COMPILE_ASSERT(sizeof(BufferValueType) == 2, BufferValueTypeIsTwoBytes); | 459 COMPILE_ASSERT(sizeof(BufferValueType) == 2, BufferValueTypeIsTwoBytes); |
642 // If the writer is at odd position in the buffer, then one of | 460 // If the writer is at odd position in the buffer, then one of |
643 // the bytes in the last UChar is not initialized. | 461 // the bytes in the last UChar is not initialized. |
644 if (m_position % 2) | 462 if (m_position % 2) |
645 *byteAt(m_position) = static_cast<uint8_t>(PaddingTag); | 463 *byteAt(m_position) = static_cast<uint8_t>(PaddingTag); |
646 } | 464 } |
647 | 465 |
648 uint8_t* Writer::byteAt(int position) | 466 uint8_t* SerializedScriptValueWriter::byteAt(int position) |
649 { | 467 { |
650 return reinterpret_cast<uint8_t*>(m_buffer.data()) + position; | 468 return reinterpret_cast<uint8_t*>(m_buffer.data()) + position; |
651 } | 469 } |
652 | 470 |
653 int Writer::v8StringWriteOptions() | 471 int SerializedScriptValueWriter::v8StringWriteOptions() |
654 { | 472 { |
655 return v8::String::NO_NULL_TERMINATION; | 473 return v8::String::NO_NULL_TERMINATION; |
656 } | 474 } |
657 | 475 |
658 Serializer::StateBase* Serializer::AbstractObjectState::serializeProperties(bool ignoreIndexed, Serializer& serializer) | 476 ScriptValueSerializer::StateBase* ScriptValueSerializer::AbstractObjectState::se rializeProperties(bool ignoreIndexed, ScriptValueSerializer& serializer) |
659 { | 477 { |
660 while (m_index < m_propertyNames->Length()) { | 478 while (m_index < m_propertyNames->Length()) { |
661 if (!m_nameDone) { | 479 if (!m_nameDone) { |
662 v8::Local<v8::Value> propertyName = m_propertyNames->Get(m_index); | 480 v8::Local<v8::Value> propertyName = m_propertyNames->Get(m_index); |
663 if (StateBase* newState = serializer.checkException(this)) | 481 if (StateBase* newState = serializer.checkException(this)) |
664 return newState; | 482 return newState; |
665 if (propertyName.IsEmpty()) | 483 if (propertyName.IsEmpty()) |
666 return serializer.handleError(InputError, "Empty property names cannot be cloned.", this); | 484 return serializer.handleError(InputError, "Empty property names cannot be cloned.", this); |
667 bool hasStringProperty = propertyName->IsString() && composite()->Ha sRealNamedProperty(propertyName.As<v8::String>()); | 485 bool hasStringProperty = propertyName->IsString() && composite()->Ha sRealNamedProperty(propertyName.As<v8::String>()); |
668 if (StateBase* newState = serializer.checkException(this)) | 486 if (StateBase* newState = serializer.checkException(this)) |
(...skipping 23 matching lines...) Expand all Loading... | |
692 ++m_numSerializedProperties; | 510 ++m_numSerializedProperties; |
693 // If we return early here, it's either because we have pushed a new sta te onto the | 511 // If we return early here, it's either because we have pushed a new sta te onto the |
694 // serialization state stack or because we have encountered an error (an d in both cases | 512 // serialization state stack or because we have encountered an error (an d in both cases |
695 // we are unwinding the native stack). | 513 // we are unwinding the native stack). |
696 if (StateBase* newState = serializer.doSerialize(value, this)) | 514 if (StateBase* newState = serializer.doSerialize(value, this)) |
697 return newState; | 515 return newState; |
698 } | 516 } |
699 return objectDone(m_numSerializedProperties, serializer); | 517 return objectDone(m_numSerializedProperties, serializer); |
700 } | 518 } |
701 | 519 |
702 Serializer::StateBase* Serializer::ObjectState::advance(Serializer& serializer) | 520 ScriptValueSerializer::StateBase* ScriptValueSerializer::ObjectState::advance(Sc riptValueSerializer& serializer) |
703 { | 521 { |
704 if (m_propertyNames.IsEmpty()) { | 522 if (m_propertyNames.IsEmpty()) { |
705 m_propertyNames = composite()->GetPropertyNames(); | 523 m_propertyNames = composite()->GetPropertyNames(); |
706 if (StateBase* newState = serializer.checkException(this)) | 524 if (StateBase* newState = serializer.checkException(this)) |
707 return newState; | 525 return newState; |
708 if (m_propertyNames.IsEmpty()) | 526 if (m_propertyNames.IsEmpty()) |
709 return serializer.handleError(InputError, "Empty property names cann ot be cloned.", nextState()); | 527 return serializer.handleError(InputError, "Empty property names cann ot be cloned.", nextState()); |
710 } | 528 } |
711 return serializeProperties(false, serializer); | 529 return serializeProperties(false, serializer); |
712 } | 530 } |
713 | 531 |
714 Serializer::StateBase* Serializer::ObjectState::objectDone(unsigned numPropertie s, Serializer& serializer) | 532 ScriptValueSerializer::StateBase* ScriptValueSerializer::ObjectState::objectDone (unsigned numProperties, ScriptValueSerializer& serializer) |
715 { | 533 { |
716 return serializer.writeObject(numProperties, this); | 534 return serializer.writeObject(numProperties, this); |
717 } | 535 } |
718 | 536 |
719 Serializer::StateBase* Serializer::DenseArrayState::advance(Serializer& serializ er) | 537 ScriptValueSerializer::StateBase* ScriptValueSerializer::DenseArrayState::advanc e(ScriptValueSerializer& serializer) |
720 { | 538 { |
721 while (m_arrayIndex < m_arrayLength) { | 539 while (m_arrayIndex < m_arrayLength) { |
722 v8::Handle<v8::Value> value = composite().As<v8::Array>()->Get(m_arrayIn dex); | 540 v8::Handle<v8::Value> value = composite().As<v8::Array>()->Get(m_arrayIn dex); |
723 m_arrayIndex++; | 541 m_arrayIndex++; |
724 if (StateBase* newState = serializer.checkException(this)) | 542 if (StateBase* newState = serializer.checkException(this)) |
725 return newState; | 543 return newState; |
726 if (StateBase* newState = serializer.doSerialize(value, this)) | 544 if (StateBase* newState = serializer.doSerialize(value, this)) |
727 return newState; | 545 return newState; |
728 } | 546 } |
729 return serializeProperties(true, serializer); | 547 return serializeProperties(true, serializer); |
730 } | 548 } |
731 | 549 |
732 Serializer::StateBase* Serializer::DenseArrayState::objectDone(unsigned numPrope rties, Serializer& serializer) | 550 ScriptValueSerializer::StateBase* ScriptValueSerializer::DenseArrayState::object Done(unsigned numProperties, ScriptValueSerializer& serializer) |
733 { | 551 { |
734 return serializer.writeDenseArray(numProperties, m_arrayLength, this); | 552 return serializer.writeDenseArray(numProperties, m_arrayLength, this); |
735 } | 553 } |
736 | 554 |
737 Serializer::StateBase* Serializer::SparseArrayState::advance(Serializer& seriali zer) | 555 ScriptValueSerializer::StateBase* ScriptValueSerializer::SparseArrayState::advan ce(ScriptValueSerializer& serializer) |
738 { | 556 { |
739 return serializeProperties(false, serializer); | 557 return serializeProperties(false, serializer); |
740 } | 558 } |
741 | 559 |
742 Serializer::StateBase* Serializer::SparseArrayState::objectDone(unsigned numProp erties, Serializer& serializer) | 560 ScriptValueSerializer::StateBase* ScriptValueSerializer::SparseArrayState::objec tDone(unsigned numProperties, ScriptValueSerializer& serializer) |
743 { | 561 { |
744 return serializer.writeSparseArray(numProperties, composite().As<v8::Array>( )->Length(), this); | 562 return serializer.writeSparseArray(numProperties, composite().As<v8::Array>( )->Length(), this); |
745 } | 563 } |
746 | 564 |
747 static v8::Handle<v8::Object> toV8Object(MessagePort* impl, v8::Handle<v8::Objec t> creationContext, v8::Isolate* isolate) | 565 static v8::Handle<v8::Object> toV8Object(MessagePort* impl, v8::Handle<v8::Objec t> creationContext, v8::Isolate* isolate) |
748 { | 566 { |
749 if (!impl) | 567 if (!impl) |
750 return v8::Handle<v8::Object>(); | 568 return v8::Handle<v8::Object>(); |
751 v8::Handle<v8::Value> wrapper = toV8(impl, creationContext, isolate); | 569 v8::Handle<v8::Value> wrapper = toV8(impl, creationContext, isolate); |
752 ASSERT(wrapper->IsObject()); | 570 ASSERT(wrapper->IsObject()); |
(...skipping 13 matching lines...) Expand all Loading... | |
766 // HTML5 structured clone algorithm. | 584 // HTML5 structured clone algorithm. |
767 static bool isHostObject(v8::Handle<v8::Object> object) | 585 static bool isHostObject(v8::Handle<v8::Object> object) |
768 { | 586 { |
769 // If the object has any internal fields, then we won't be able to serialize or deserialize | 587 // If the object has any internal fields, then we won't be able to serialize or deserialize |
770 // them; conveniently, this is also a quick way to detect DOM wrapper object s, because | 588 // them; conveniently, this is also a quick way to detect DOM wrapper object s, because |
771 // the mechanism for these relies on data stored in these fields. We should | 589 // the mechanism for these relies on data stored in these fields. We should |
772 // catch external array data as a special case. | 590 // catch external array data as a special case. |
773 return object->InternalFieldCount() || object->HasIndexedPropertiesInExterna lArrayData(); | 591 return object->InternalFieldCount() || object->HasIndexedPropertiesInExterna lArrayData(); |
774 } | 592 } |
775 | 593 |
776 Serializer::Serializer(Writer& writer, MessagePortArray* messagePorts, ArrayBuff erArray* arrayBuffers, WebBlobInfoArray* blobInfo, BlobDataHandleMap& blobDataHa ndles, v8::TryCatch& tryCatch, ScriptState* scriptState) | 594 ScriptValueSerializer::ScriptValueSerializer(SerializedScriptValueWriter& writer , MessagePortArray* messagePorts, ArrayBufferArray* arrayBuffers, WebBlobInfoArr ay* blobInfo, BlobDataHandleMap& blobDataHandles, v8::TryCatch& tryCatch, Script State* scriptState) |
777 : m_scriptState(scriptState) | 595 : m_scriptState(scriptState) |
778 , m_writer(writer) | 596 , m_writer(writer) |
779 , m_tryCatch(tryCatch) | 597 , m_tryCatch(tryCatch) |
780 , m_depth(0) | 598 , m_depth(0) |
781 , m_status(Success) | 599 , m_status(Success) |
782 , m_nextObjectReference(0) | 600 , m_nextObjectReference(0) |
783 , m_blobInfo(blobInfo) | 601 , m_blobInfo(blobInfo) |
784 , m_blobDataHandles(blobDataHandles) | 602 , m_blobDataHandles(blobDataHandles) |
785 { | 603 { |
786 ASSERT(!tryCatch.HasCaught()); | 604 ASSERT(!tryCatch.HasCaught()); |
787 v8::Handle<v8::Object> creationContext = m_scriptState->context()->Global(); | 605 v8::Handle<v8::Object> creationContext = m_scriptState->context()->Global(); |
788 if (messagePorts) { | 606 if (messagePorts) { |
789 for (size_t i = 0; i < messagePorts->size(); i++) | 607 for (size_t i = 0; i < messagePorts->size(); i++) |
790 m_transferredMessagePorts.set(toV8Object(messagePorts->at(i).get(), creationContext, isolate()), i); | 608 m_transferredMessagePorts.set(toV8Object(messagePorts->at(i).get(), creationContext, isolate()), i); |
791 } | 609 } |
792 if (arrayBuffers) { | 610 if (arrayBuffers) { |
793 for (size_t i = 0; i < arrayBuffers->size(); i++) { | 611 for (size_t i = 0; i < arrayBuffers->size(); i++) { |
794 v8::Handle<v8::Object> v8ArrayBuffer = toV8Object(arrayBuffers->at(i ).get(), creationContext, isolate()); | 612 v8::Handle<v8::Object> v8ArrayBuffer = toV8Object(arrayBuffers->at(i ).get(), creationContext, isolate()); |
795 // Coalesce multiple occurences of the same buffer to the first inde x. | 613 // Coalesce multiple occurences of the same buffer to the first inde x. |
796 if (!m_transferredArrayBuffers.contains(v8ArrayBuffer)) | 614 if (!m_transferredArrayBuffers.contains(v8ArrayBuffer)) |
797 m_transferredArrayBuffers.set(v8ArrayBuffer, i); | 615 m_transferredArrayBuffers.set(v8ArrayBuffer, i); |
798 } | 616 } |
799 } | 617 } |
800 } | 618 } |
801 | 619 |
802 Serializer::Status Serializer::serialize(v8::Handle<v8::Value> value) | 620 ScriptValueSerializer::Status ScriptValueSerializer::serialize(v8::Handle<v8::Va lue> value) |
803 { | 621 { |
804 v8::HandleScope scope(isolate()); | 622 v8::HandleScope scope(isolate()); |
805 m_writer.writeVersion(); | 623 m_writer.writeVersion(); |
806 StateBase* state = doSerialize(value, 0); | 624 StateBase* state = doSerialize(value, 0); |
807 while (state) | 625 while (state) |
808 state = state->advance(*this); | 626 state = state->advance(*this); |
809 return m_status; | 627 return m_status; |
810 } | 628 } |
811 | 629 |
812 Serializer::StateBase* Serializer::doSerialize(v8::Handle<v8::Value> value, Seri alizer::StateBase* next) | 630 ScriptValueSerializer::StateBase* ScriptValueSerializer::doSerialize(v8::Handle< v8::Value> value, ScriptValueSerializer::StateBase* next) |
813 { | 631 { |
814 m_writer.writeReferenceCount(m_nextObjectReference); | 632 m_writer.writeReferenceCount(m_nextObjectReference); |
815 uint32_t objectReference; | 633 uint32_t objectReference; |
816 uint32_t arrayBufferIndex; | 634 uint32_t arrayBufferIndex; |
817 if ((value->IsObject() || value->IsDate() || value->IsRegExp()) | 635 if ((value->IsObject() || value->IsDate() || value->IsRegExp()) |
818 && m_objectPool.tryGet(value.As<v8::Object>(), &objectReference)) { | 636 && m_objectPool.tryGet(value.As<v8::Object>(), &objectReference)) { |
jsbell
2014/11/17 23:46:02
Won't the object pool be bypassed completely by th
jsbell
2014/11/18 19:30:47
Actually... I think it would be a script-visible c
tasak
2014/11/19 05:12:16
I see. The previous patch causes this regression.
| |
819 // Note that IsObject() also detects wrappers (eg, it will catch the thi ngs | 637 // Note that IsObject() also detects wrappers (eg, it will catch the thi ngs |
820 // that we grey and write below). | 638 // that we grey and write below). |
821 ASSERT(!value->IsString()); | 639 ASSERT(!value->IsString()); |
822 m_writer.writeObjectReference(objectReference); | 640 m_writer.writeObjectReference(objectReference); |
823 } else if (value.IsEmpty()) { | 641 } else if (value.IsEmpty()) { |
824 return handleError(InputError, "The empty property name cannot be cloned .", next); | 642 return handleError(InputError, "The empty property name cannot be cloned .", next); |
825 } else if (value->IsUndefined()) { | 643 } else if (value->IsUndefined()) { |
826 m_writer.writeUndefined(); | 644 m_writer.writeUndefined(); |
827 } else if (value->IsNull()) { | 645 } else if (value->IsNull()) { |
828 m_writer.writeNull(); | 646 m_writer.writeNull(); |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
861 } else if (value->IsNumberObject()) { | 679 } else if (value->IsNumberObject()) { |
862 writeNumberObject(value); | 680 writeNumberObject(value); |
863 } else if (value->IsBooleanObject()) { | 681 } else if (value->IsBooleanObject()) { |
864 writeBooleanObject(value); | 682 writeBooleanObject(value); |
865 } else if (value->IsArray()) { | 683 } else if (value->IsArray()) { |
866 return startArrayState(value.As<v8::Array>(), next); | 684 return startArrayState(value.As<v8::Array>(), next); |
867 } else if (V8File::hasInstance(value, isolate())) { | 685 } else if (V8File::hasInstance(value, isolate())) { |
868 return writeFile(value, next); | 686 return writeFile(value, next); |
869 } else if (V8Blob::hasInstance(value, isolate())) { | 687 } else if (V8Blob::hasInstance(value, isolate())) { |
870 return writeBlob(value, next); | 688 return writeBlob(value, next); |
871 } else if (V8DOMFileSystem::hasInstance(value, isolate())) { | |
872 return writeDOMFileSystem(value, next); | |
873 } else if (V8FileList::hasInstance(value, isolate())) { | 689 } else if (V8FileList::hasInstance(value, isolate())) { |
874 return writeFileList(value, next); | 690 return writeFileList(value, next); |
875 } else if (V8CryptoKey::hasInstance(value, isolate())) { | |
876 if (!writeCryptoKey(value)) | |
877 return handleError(DataCloneError, "Couldn't serialize key data" , next); | |
878 } else if (V8ImageData::hasInstance(value, isolate())) { | 691 } else if (V8ImageData::hasInstance(value, isolate())) { |
879 writeImageData(value); | 692 writeImageData(value); |
880 } else if (value->IsRegExp()) { | 693 } else if (value->IsRegExp()) { |
881 writeRegExp(value); | 694 writeRegExp(value); |
882 } else if (V8ArrayBuffer::hasInstance(value, isolate())) { | 695 } else if (V8ArrayBuffer::hasInstance(value, isolate())) { |
883 return writeArrayBuffer(value, next); | 696 return writeArrayBuffer(value, next); |
884 } else if (value->IsObject()) { | 697 } else if (value->IsObject()) { |
885 if (isHostObject(jsObject) || jsObject->IsCallable() || value->IsNat iveError()) | 698 if (isHostObject(jsObject) || jsObject->IsCallable() || value->IsNat iveError()) |
886 return handleError(DataCloneError, "An object could not be clone d.", next); | 699 return handleError(DataCloneError, "An object could not be clone d.", next); |
887 return startObjectState(jsObject, next); | 700 return startObjectState(jsObject, next); |
888 } else { | 701 } else { |
889 return handleError(DataCloneError, "A value could not be cloned.", n ext); | 702 return handleError(DataCloneError, "A value could not be cloned.", n ext); |
890 } | 703 } |
891 } | 704 } |
892 return 0; | 705 return 0; |
893 } | 706 } |
894 | 707 |
895 Serializer::StateBase* Serializer::doSerializeArrayBuffer(v8::Handle<v8::Value> arrayBuffer, Serializer::StateBase* next) | 708 ScriptValueSerializer::StateBase* ScriptValueSerializer::doSerializeArrayBuffer( v8::Handle<v8::Value> arrayBuffer, ScriptValueSerializer::StateBase* next) |
896 { | 709 { |
897 return doSerialize(arrayBuffer, next); | 710 return doSerialize(arrayBuffer, next); |
898 } | 711 } |
899 | 712 |
900 Serializer::StateBase* Serializer::checkException(Serializer::StateBase* state) | 713 ScriptValueSerializer::StateBase* ScriptValueSerializer::checkException(ScriptVa lueSerializer::StateBase* state) |
901 { | 714 { |
902 return m_tryCatch.HasCaught() ? handleError(JSException, "", state) : 0; | 715 return m_tryCatch.HasCaught() ? handleError(JSException, "", state) : 0; |
903 } | 716 } |
904 | 717 |
905 Serializer::StateBase* Serializer::writeObject(uint32_t numProperties, Serialize r::StateBase* state) | 718 ScriptValueSerializer::StateBase* ScriptValueSerializer::writeObject(uint32_t nu mProperties, ScriptValueSerializer::StateBase* state) |
906 { | 719 { |
907 m_writer.writeObject(numProperties); | 720 m_writer.writeObject(numProperties); |
908 return pop(state); | 721 return pop(state); |
909 } | 722 } |
910 | 723 |
911 Serializer::StateBase* Serializer::writeSparseArray(uint32_t numProperties, uint 32_t length, Serializer::StateBase* state) | 724 ScriptValueSerializer::StateBase* ScriptValueSerializer::writeSparseArray(uint32 _t numProperties, uint32_t length, ScriptValueSerializer::StateBase* state) |
912 { | 725 { |
913 m_writer.writeSparseArray(numProperties, length); | 726 m_writer.writeSparseArray(numProperties, length); |
914 return pop(state); | 727 return pop(state); |
915 } | 728 } |
916 | 729 |
917 Serializer::StateBase* Serializer::writeDenseArray(uint32_t numProperties, uint3 2_t length, Serializer::StateBase* state) | 730 ScriptValueSerializer::StateBase* ScriptValueSerializer::writeDenseArray(uint32_ t numProperties, uint32_t length, ScriptValueSerializer::StateBase* state) |
918 { | 731 { |
919 m_writer.writeDenseArray(numProperties, length); | 732 m_writer.writeDenseArray(numProperties, length); |
920 return pop(state); | 733 return pop(state); |
921 } | 734 } |
922 | 735 |
923 Serializer::StateBase* Serializer::handleError(Serializer::Status errorStatus, c onst String& message, Serializer::StateBase* state) | 736 ScriptValueSerializer::StateBase* ScriptValueSerializer::handleError(ScriptValue Serializer::Status errorStatus, const String& message, ScriptValueSerializer::St ateBase* state) |
924 { | 737 { |
925 ASSERT(errorStatus != Success); | 738 ASSERT(errorStatus != Success); |
926 m_status = errorStatus; | 739 m_status = errorStatus; |
927 m_errorMessage = message; | 740 m_errorMessage = message; |
928 while (state) { | 741 while (state) { |
929 StateBase* tmp = state->nextState(); | 742 StateBase* tmp = state->nextState(); |
930 delete state; | 743 delete state; |
931 state = tmp; | 744 state = tmp; |
932 } | 745 } |
933 return new ErrorState; | 746 return new ErrorState; |
934 } | 747 } |
935 | 748 |
936 bool Serializer::checkComposite(Serializer::StateBase* top) | 749 bool ScriptValueSerializer::checkComposite(ScriptValueSerializer::StateBase* top ) |
937 { | 750 { |
938 ASSERT(top); | 751 ASSERT(top); |
939 if (m_depth > maxDepth) | 752 if (m_depth > maxDepth) |
940 return false; | 753 return false; |
941 if (!shouldCheckForCycles(m_depth)) | 754 if (!shouldCheckForCycles(m_depth)) |
942 return true; | 755 return true; |
943 v8::Handle<v8::Value> composite = top->composite(); | 756 v8::Handle<v8::Value> composite = top->composite(); |
944 for (StateBase* state = top->nextState(); state; state = state->nextState()) { | 757 for (StateBase* state = top->nextState(); state; state = state->nextState()) { |
945 if (state->composite() == composite) | 758 if (state->composite() == composite) |
946 return false; | 759 return false; |
947 } | 760 } |
948 return true; | 761 return true; |
949 } | 762 } |
950 | 763 |
951 void Serializer::writeString(v8::Handle<v8::Value> value) | 764 void ScriptValueSerializer::writeString(v8::Handle<v8::Value> value) |
952 { | 765 { |
953 v8::Handle<v8::String> string = value.As<v8::String>(); | 766 v8::Handle<v8::String> string = value.As<v8::String>(); |
954 if (!string->Length() || string->IsOneByte()) | 767 if (!string->Length() || string->IsOneByte()) |
955 m_writer.writeOneByteString(string); | 768 m_writer.writeOneByteString(string); |
956 else | 769 else |
957 m_writer.writeUCharString(string); | 770 m_writer.writeUCharString(string); |
958 } | 771 } |
959 | 772 |
960 void Serializer::writeStringObject(v8::Handle<v8::Value> value) | 773 void ScriptValueSerializer::writeStringObject(v8::Handle<v8::Value> value) |
961 { | 774 { |
962 v8::Handle<v8::StringObject> stringObject = value.As<v8::StringObject>(); | 775 v8::Handle<v8::StringObject> stringObject = value.As<v8::StringObject>(); |
963 v8::String::Utf8Value stringValue(stringObject->ValueOf()); | 776 v8::String::Utf8Value stringValue(stringObject->ValueOf()); |
964 m_writer.writeStringObject(*stringValue, stringValue.length()); | 777 m_writer.writeStringObject(*stringValue, stringValue.length()); |
965 } | 778 } |
966 | 779 |
967 void Serializer::writeNumberObject(v8::Handle<v8::Value> value) | 780 void ScriptValueSerializer::writeNumberObject(v8::Handle<v8::Value> value) |
968 { | 781 { |
969 v8::Handle<v8::NumberObject> numberObject = value.As<v8::NumberObject>(); | 782 v8::Handle<v8::NumberObject> numberObject = value.As<v8::NumberObject>(); |
970 m_writer.writeNumberObject(numberObject->ValueOf()); | 783 m_writer.writeNumberObject(numberObject->ValueOf()); |
971 } | 784 } |
972 | 785 |
973 void Serializer::writeBooleanObject(v8::Handle<v8::Value> value) | 786 void ScriptValueSerializer::writeBooleanObject(v8::Handle<v8::Value> value) |
974 { | 787 { |
975 v8::Handle<v8::BooleanObject> booleanObject = value.As<v8::BooleanObject>(); | 788 v8::Handle<v8::BooleanObject> booleanObject = value.As<v8::BooleanObject>(); |
976 m_writer.writeBooleanObject(booleanObject->ValueOf()); | 789 m_writer.writeBooleanObject(booleanObject->ValueOf()); |
977 } | 790 } |
978 | 791 |
979 Serializer::StateBase* Serializer::writeBlob(v8::Handle<v8::Value> value, Serial izer::StateBase* next) | 792 ScriptValueSerializer::StateBase* ScriptValueSerializer::writeBlob(v8::Handle<v8 ::Value> value, ScriptValueSerializer::StateBase* next) |
980 { | 793 { |
981 Blob* blob = V8Blob::toImpl(value.As<v8::Object>()); | 794 Blob* blob = V8Blob::toImpl(value.As<v8::Object>()); |
982 if (!blob) | 795 if (!blob) |
983 return 0; | 796 return 0; |
984 if (blob->hasBeenClosed()) | 797 if (blob->hasBeenClosed()) |
985 return handleError(DataCloneError, "A Blob object has been closed, and c ould therefore not be cloned.", next); | 798 return handleError(DataCloneError, "A Blob object has been closed, and c ould therefore not be cloned.", next); |
986 int blobIndex = -1; | 799 int blobIndex = -1; |
987 m_blobDataHandles.set(blob->uuid(), blob->blobDataHandle()); | 800 m_blobDataHandles.set(blob->uuid(), blob->blobDataHandle()); |
988 if (appendBlobInfo(blob->uuid(), blob->type(), blob->size(), &blobIndex)) | 801 if (appendBlobInfo(blob->uuid(), blob->type(), blob->size(), &blobIndex)) |
989 m_writer.writeBlobIndex(blobIndex); | 802 m_writer.writeBlobIndex(blobIndex); |
990 else | 803 else |
991 m_writer.writeBlob(blob->uuid(), blob->type(), blob->size()); | 804 m_writer.writeBlob(blob->uuid(), blob->type(), blob->size()); |
992 return 0; | 805 return 0; |
993 } | 806 } |
994 | 807 |
995 Serializer::StateBase* Serializer::writeDOMFileSystem(v8::Handle<v8::Value> valu e, StateBase* next) | 808 ScriptValueSerializer::StateBase* ScriptValueSerializer::writeFile(v8::Handle<v8 ::Value> value, ScriptValueSerializer::StateBase* next) |
996 { | |
997 DOMFileSystem* fs = V8DOMFileSystem::toImpl(value.As<v8::Object>()); | |
998 if (!fs) | |
999 return 0; | |
1000 if (!fs->clonable()) | |
1001 return handleError(DataCloneError, "A FileSystem object could not be clo ned.", next); | |
1002 m_writer.writeDOMFileSystem(fs->type(), fs->name(), fs->rootURL().string()); | |
1003 return 0; | |
1004 } | |
1005 | |
1006 Serializer::StateBase* Serializer::writeFile(v8::Handle<v8::Value> value, Serial izer::StateBase* next) | |
1007 { | 809 { |
1008 File* file = V8File::toImpl(value.As<v8::Object>()); | 810 File* file = V8File::toImpl(value.As<v8::Object>()); |
1009 if (!file) | 811 if (!file) |
1010 return 0; | 812 return 0; |
1011 if (file->hasBeenClosed()) | 813 if (file->hasBeenClosed()) |
1012 return handleError(DataCloneError, "A File object has been closed, and c ould therefore not be cloned.", next); | 814 return handleError(DataCloneError, "A File object has been closed, and c ould therefore not be cloned.", next); |
1013 int blobIndex = -1; | 815 int blobIndex = -1; |
1014 m_blobDataHandles.set(file->uuid(), file->blobDataHandle()); | 816 m_blobDataHandles.set(file->uuid(), file->blobDataHandle()); |
1015 if (appendFileInfo(file, &blobIndex)) { | 817 if (appendFileInfo(file, &blobIndex)) { |
1016 ASSERT(blobIndex >= 0); | 818 ASSERT(blobIndex >= 0); |
1017 m_writer.writeFileIndex(blobIndex); | 819 m_writer.writeFileIndex(blobIndex); |
1018 } else { | 820 } else { |
1019 m_writer.writeFile(*file); | 821 m_writer.writeFile(*file); |
1020 } | 822 } |
1021 return 0; | 823 return 0; |
1022 } | 824 } |
1023 | 825 |
1024 Serializer::StateBase* Serializer::writeFileList(v8::Handle<v8::Value> value, Se rializer::StateBase* next) | 826 ScriptValueSerializer::StateBase* ScriptValueSerializer::writeFileList(v8::Handl e<v8::Value> value, ScriptValueSerializer::StateBase* next) |
1025 { | 827 { |
1026 FileList* fileList = V8FileList::toImpl(value.As<v8::Object>()); | 828 FileList* fileList = V8FileList::toImpl(value.As<v8::Object>()); |
1027 if (!fileList) | 829 if (!fileList) |
1028 return 0; | 830 return 0; |
1029 unsigned length = fileList->length(); | 831 unsigned length = fileList->length(); |
1030 Vector<int> blobIndices; | 832 Vector<int> blobIndices; |
1031 for (unsigned i = 0; i < length; ++i) { | 833 for (unsigned i = 0; i < length; ++i) { |
1032 int blobIndex = -1; | 834 int blobIndex = -1; |
1033 const File* file = fileList->item(i); | 835 const File* file = fileList->item(i); |
1034 if (file->hasBeenClosed()) | 836 if (file->hasBeenClosed()) |
1035 return handleError(DataCloneError, "A File object has been closed, a nd could therefore not be cloned.", next); | 837 return handleError(DataCloneError, "A File object has been closed, a nd could therefore not be cloned.", next); |
1036 m_blobDataHandles.set(file->uuid(), file->blobDataHandle()); | 838 m_blobDataHandles.set(file->uuid(), file->blobDataHandle()); |
1037 if (appendFileInfo(file, &blobIndex)) { | 839 if (appendFileInfo(file, &blobIndex)) { |
1038 ASSERT(!i || blobIndex > 0); | 840 ASSERT(!i || blobIndex > 0); |
1039 ASSERT(blobIndex >= 0); | 841 ASSERT(blobIndex >= 0); |
1040 blobIndices.append(blobIndex); | 842 blobIndices.append(blobIndex); |
1041 } | 843 } |
1042 } | 844 } |
1043 if (!blobIndices.isEmpty()) | 845 if (!blobIndices.isEmpty()) |
1044 m_writer.writeFileListIndex(blobIndices); | 846 m_writer.writeFileListIndex(blobIndices); |
1045 else | 847 else |
1046 m_writer.writeFileList(*fileList); | 848 m_writer.writeFileList(*fileList); |
1047 return 0; | 849 return 0; |
1048 } | 850 } |
1049 | 851 |
1050 bool Serializer::writeCryptoKey(v8::Handle<v8::Value> value) | 852 void ScriptValueSerializer::writeImageData(v8::Handle<v8::Value> value) |
1051 { | |
1052 CryptoKey* key = V8CryptoKey::toImpl(value.As<v8::Object>()); | |
1053 if (!key) | |
1054 return false; | |
1055 return m_writer.writeCryptoKey(key->key()); | |
1056 } | |
1057 | |
1058 void Serializer::writeImageData(v8::Handle<v8::Value> value) | |
1059 { | 853 { |
1060 ImageData* imageData = V8ImageData::toImpl(value.As<v8::Object>()); | 854 ImageData* imageData = V8ImageData::toImpl(value.As<v8::Object>()); |
1061 if (!imageData) | 855 if (!imageData) |
1062 return; | 856 return; |
1063 Uint8ClampedArray* pixelArray = imageData->data(); | 857 Uint8ClampedArray* pixelArray = imageData->data(); |
1064 m_writer.writeImageData(imageData->width(), imageData->height(), pixelArray- >data(), pixelArray->length()); | 858 m_writer.writeImageData(imageData->width(), imageData->height(), pixelArray- >data(), pixelArray->length()); |
1065 } | 859 } |
1066 | 860 |
1067 void Serializer::writeRegExp(v8::Handle<v8::Value> value) | 861 void ScriptValueSerializer::writeRegExp(v8::Handle<v8::Value> value) |
1068 { | 862 { |
1069 v8::Handle<v8::RegExp> regExp = value.As<v8::RegExp>(); | 863 v8::Handle<v8::RegExp> regExp = value.As<v8::RegExp>(); |
1070 m_writer.writeRegExp(regExp->GetSource(), regExp->GetFlags()); | 864 m_writer.writeRegExp(regExp->GetSource(), regExp->GetFlags()); |
1071 } | 865 } |
1072 | 866 |
1073 Serializer::StateBase* Serializer::writeAndGreyArrayBufferView(v8::Handle<v8::Ob ject> object, Serializer::StateBase* next) | 867 ScriptValueSerializer::StateBase* ScriptValueSerializer::writeAndGreyArrayBuffer View(v8::Handle<v8::Object> object, ScriptValueSerializer::StateBase* next) |
1074 { | 868 { |
1075 ASSERT(!object.IsEmpty()); | 869 ASSERT(!object.IsEmpty()); |
1076 DOMArrayBufferView* arrayBufferView = V8ArrayBufferView::toImpl(object); | 870 DOMArrayBufferView* arrayBufferView = V8ArrayBufferView::toImpl(object); |
1077 if (!arrayBufferView) | 871 if (!arrayBufferView) |
1078 return 0; | 872 return 0; |
1079 if (!arrayBufferView->buffer()) | 873 if (!arrayBufferView->buffer()) |
1080 return handleError(DataCloneError, "An ArrayBuffer could not be cloned." , next); | 874 return handleError(DataCloneError, "An ArrayBuffer could not be cloned." , next); |
1081 v8::Handle<v8::Value> underlyingBuffer = toV8(arrayBufferView->buffer(), m_s criptState->context()->Global(), isolate()); | 875 v8::Handle<v8::Value> underlyingBuffer = toV8(arrayBufferView->buffer(), m_s criptState->context()->Global(), isolate()); |
1082 if (underlyingBuffer.IsEmpty()) | 876 if (underlyingBuffer.IsEmpty()) |
1083 return handleError(DataCloneError, "An ArrayBuffer could not be cloned." , next); | 877 return handleError(DataCloneError, "An ArrayBuffer could not be cloned." , next); |
1084 StateBase* stateOut = doSerializeArrayBuffer(underlyingBuffer, next); | 878 StateBase* stateOut = doSerializeArrayBuffer(underlyingBuffer, next); |
1085 if (stateOut) | 879 if (stateOut) |
1086 return stateOut; | 880 return stateOut; |
1087 m_writer.writeArrayBufferView(*arrayBufferView->view()); | 881 m_writer.writeArrayBufferView(*arrayBufferView->view()); |
1088 // This should be safe: we serialize something that we know to be a wrapper (see | 882 // This should be safe: we serialize something that we know to be a wrapper (see |
1089 // the toV8 call above), so the call to doSerializeArrayBuffer should neithe r | 883 // the toV8 call above), so the call to doSerializeArrayBuffer should neithe r |
1090 // cause the system stack to overflow nor should it have potential to reach | 884 // cause the system stack to overflow nor should it have potential to reach |
1091 // this ArrayBufferView again. | 885 // this ArrayBufferView again. |
1092 // | 886 // |
1093 // We do need to grey the underlying buffer before we grey its view, however ; | 887 // We do need to grey the underlying buffer before we grey its view, however ; |
1094 // ArrayBuffers may be shared, so they need to be given reference IDs, and a n | 888 // ArrayBuffers may be shared, so they need to be given reference IDs, and a n |
1095 // ArrayBufferView cannot be constructed without a corresponding ArrayBuffer | 889 // ArrayBufferView cannot be constructed without a corresponding ArrayBuffer |
1096 // (or without an additional tag that would allow us to do two-stage constru ction | 890 // (or without an additional tag that would allow us to do two-stage constru ction |
1097 // like we do for Objects and Arrays). | 891 // like we do for Objects and Arrays). |
1098 greyObject(object); | 892 greyObject(object); |
1099 return 0; | 893 return 0; |
1100 } | 894 } |
1101 | 895 |
1102 Serializer::StateBase* Serializer::writeArrayBuffer(v8::Handle<v8::Value> value, Serializer::StateBase* next) | 896 ScriptValueSerializer::StateBase* ScriptValueSerializer::writeArrayBuffer(v8::Ha ndle<v8::Value> value, ScriptValueSerializer::StateBase* next) |
1103 { | 897 { |
1104 DOMArrayBuffer* arrayBuffer = V8ArrayBuffer::toImpl(value.As<v8::Object>()); | 898 DOMArrayBuffer* arrayBuffer = V8ArrayBuffer::toImpl(value.As<v8::Object>()); |
1105 if (!arrayBuffer) | 899 if (!arrayBuffer) |
1106 return 0; | 900 return 0; |
1107 if (arrayBuffer->isNeutered()) | 901 if (arrayBuffer->isNeutered()) |
1108 return handleError(DataCloneError, "An ArrayBuffer is neutered and could not be cloned.", next); | 902 return handleError(DataCloneError, "An ArrayBuffer is neutered and could not be cloned.", next); |
1109 ASSERT(!m_transferredArrayBuffers.contains(value.As<v8::Object>())); | 903 ASSERT(!m_transferredArrayBuffers.contains(value.As<v8::Object>())); |
1110 m_writer.writeArrayBuffer(*arrayBuffer->buffer()); | 904 m_writer.writeArrayBuffer(*arrayBuffer->buffer()); |
1111 return 0; | 905 return 0; |
1112 } | 906 } |
1113 | 907 |
1114 Serializer::StateBase* Serializer::writeTransferredArrayBuffer(v8::Handle<v8::Va lue> value, uint32_t index, Serializer::StateBase* next) | 908 ScriptValueSerializer::StateBase* ScriptValueSerializer::writeTransferredArrayBu ffer(v8::Handle<v8::Value> value, uint32_t index, ScriptValueSerializer::StateBa se* next) |
1115 { | 909 { |
1116 DOMArrayBuffer* arrayBuffer = V8ArrayBuffer::toImpl(value.As<v8::Object>()); | 910 DOMArrayBuffer* arrayBuffer = V8ArrayBuffer::toImpl(value.As<v8::Object>()); |
1117 if (!arrayBuffer) | 911 if (!arrayBuffer) |
1118 return 0; | 912 return 0; |
1119 if (arrayBuffer->isNeutered()) | 913 if (arrayBuffer->isNeutered()) |
1120 return handleError(DataCloneError, "An ArrayBuffer is neutered and could not be cloned.", next); | 914 return handleError(DataCloneError, "An ArrayBuffer is neutered and could not be cloned.", next); |
1121 m_writer.writeTransferredArrayBuffer(index); | 915 m_writer.writeTransferredArrayBuffer(index); |
1122 return 0; | 916 return 0; |
1123 } | 917 } |
1124 | 918 |
1125 bool Serializer::shouldSerializeDensely(uint32_t length, uint32_t propertyCount) | 919 bool ScriptValueSerializer::shouldSerializeDensely(uint32_t length, uint32_t pro pertyCount) |
1126 { | 920 { |
1127 // Let K be the cost of serializing all property values that are there | 921 // Let K be the cost of serializing all property values that are there |
1128 // Cost of serializing sparsely: 5*propertyCount + K (5 bytes per uint32_t k ey) | 922 // Cost of serializing sparsely: 5*propertyCount + K (5 bytes per uint32_t k ey) |
1129 // Cost of serializing densely: K + 1*(length - propertyCount) (1 byte for a ll properties that are not there) | 923 // Cost of serializing densely: K + 1*(length - propertyCount) (1 byte for a ll properties that are not there) |
1130 // so densely is better than sparsly whenever 6*propertyCount > length | 924 // so densely is better than sparsly whenever 6*propertyCount > length |
1131 return 6 * propertyCount >= length; | 925 return 6 * propertyCount >= length; |
1132 } | 926 } |
1133 | 927 |
1134 Serializer::StateBase* Serializer::startArrayState(v8::Handle<v8::Array> array, Serializer::StateBase* next) | 928 ScriptValueSerializer::StateBase* ScriptValueSerializer::startArrayState(v8::Han dle<v8::Array> array, ScriptValueSerializer::StateBase* next) |
1135 { | 929 { |
1136 v8::Handle<v8::Array> propertyNames = array->GetPropertyNames(); | 930 v8::Handle<v8::Array> propertyNames = array->GetPropertyNames(); |
1137 if (StateBase* newState = checkException(next)) | 931 if (StateBase* newState = checkException(next)) |
1138 return newState; | 932 return newState; |
1139 uint32_t length = array->Length(); | 933 uint32_t length = array->Length(); |
1140 | 934 |
1141 if (shouldSerializeDensely(length, propertyNames->Length())) { | 935 if (shouldSerializeDensely(length, propertyNames->Length())) { |
1142 m_writer.writeGenerateFreshDenseArray(length); | 936 m_writer.writeGenerateFreshDenseArray(length); |
1143 return push(new DenseArrayState(array, propertyNames, next, isolate())); | 937 return push(new DenseArrayState(array, propertyNames, next, isolate())); |
1144 } | 938 } |
1145 | 939 |
1146 m_writer.writeGenerateFreshSparseArray(length); | 940 m_writer.writeGenerateFreshSparseArray(length); |
1147 return push(new SparseArrayState(array, propertyNames, next, isolate())); | 941 return push(new SparseArrayState(array, propertyNames, next, isolate())); |
1148 } | 942 } |
1149 | 943 |
1150 Serializer::StateBase* Serializer::startObjectState(v8::Handle<v8::Object> objec t, Serializer::StateBase* next) | 944 ScriptValueSerializer::StateBase* ScriptValueSerializer::startObjectState(v8::Ha ndle<v8::Object> object, ScriptValueSerializer::StateBase* next) |
1151 { | 945 { |
1152 m_writer.writeGenerateFreshObject(); | 946 m_writer.writeGenerateFreshObject(); |
1153 // FIXME: check not a wrapper | 947 // FIXME: check not a wrapper |
1154 return push(new ObjectState(object, next)); | 948 return push(new ObjectState(object, next)); |
1155 } | 949 } |
1156 | 950 |
1157 // Marks object as having been visited by the serializer and assigns it a unique object reference ID. | 951 // Marks object as having been visited by the serializer and assigns it a unique object reference ID. |
1158 // An object may only be greyed once. | 952 // An object may only be greyed once. |
1159 void Serializer::greyObject(const v8::Handle<v8::Object>& object) | 953 void ScriptValueSerializer::greyObject(const v8::Handle<v8::Object>& object) |
1160 { | 954 { |
1161 ASSERT(!m_objectPool.contains(object)); | 955 ASSERT(!m_objectPool.contains(object)); |
1162 uint32_t objectReference = m_nextObjectReference++; | 956 uint32_t objectReference = m_nextObjectReference++; |
1163 m_objectPool.set(object, objectReference); | 957 m_objectPool.set(object, objectReference); |
1164 } | 958 } |
1165 | 959 |
1166 bool Serializer::appendBlobInfo(const String& uuid, const String& type, unsigned long long size, int* index) | 960 bool ScriptValueSerializer::appendBlobInfo(const String& uuid, const String& typ e, unsigned long long size, int* index) |
1167 { | 961 { |
1168 if (!m_blobInfo) | 962 if (!m_blobInfo) |
1169 return false; | 963 return false; |
1170 *index = m_blobInfo->size(); | 964 *index = m_blobInfo->size(); |
1171 m_blobInfo->append(WebBlobInfo(uuid, type, size)); | 965 m_blobInfo->append(WebBlobInfo(uuid, type, size)); |
1172 return true; | 966 return true; |
1173 } | 967 } |
1174 | 968 |
1175 bool Serializer::appendFileInfo(const File* file, int* index) | 969 bool ScriptValueSerializer::appendFileInfo(const File* file, int* index) |
1176 { | 970 { |
1177 if (!m_blobInfo) | 971 if (!m_blobInfo) |
1178 return false; | 972 return false; |
1179 | 973 |
1180 long long size = -1; | 974 long long size = -1; |
1181 double lastModified = invalidFileTime(); | 975 double lastModified = invalidFileTime(); |
1182 file->captureSnapshot(size, lastModified); | 976 file->captureSnapshot(size, lastModified); |
1183 *index = m_blobInfo->size(); | 977 *index = m_blobInfo->size(); |
1184 m_blobInfo->append(WebBlobInfo(file->uuid(), file->path(), file->name(), fil e->type(), lastModified, size)); | 978 m_blobInfo->append(WebBlobInfo(file->uuid(), file->path(), file->name(), fil e->type(), lastModified, size)); |
1185 return true; | 979 return true; |
1186 } | 980 } |
1187 | 981 |
1188 bool Reader::read(v8::Handle<v8::Value>* value, CompositeCreator& creator) | 982 bool SerializedScriptValueReader::read(v8::Handle<v8::Value>* value, ScriptValue CompositeCreator& creator) |
1189 { | 983 { |
1190 SerializationTag tag; | 984 SerializationTag tag; |
1191 if (!readTag(&tag)) | 985 if (!readTag(&tag)) |
1192 return false; | 986 return false; |
987 return readWithTag(tag, value, creator); | |
988 } | |
989 | |
990 bool SerializedScriptValueReader::readWithTag(SerializationTag tag, v8::Handle<v 8::Value>* value, ScriptValueCompositeCreator& creator) | |
991 { | |
1193 switch (tag) { | 992 switch (tag) { |
1194 case ReferenceCountTag: { | 993 case ReferenceCountTag: { |
1195 if (!m_version) | 994 if (!m_version) |
1196 return false; | 995 return false; |
1197 uint32_t referenceTableSize; | 996 uint32_t referenceTableSize; |
1198 if (!doReadUint32(&referenceTableSize)) | 997 if (!doReadUint32(&referenceTableSize)) |
1199 return false; | 998 return false; |
1200 // If this test fails, then the serializer and deserializer disagree abo ut the assignment | 999 // If this test fails, then the serializer and deserializer disagree abo ut the assignment |
1201 // of object reference IDs. On the deserialization side, this means ther e are too many or too few | 1000 // of object reference IDs. On the deserialization side, this means ther e are too many or too few |
1202 // calls to pushObjectReference. | 1001 // calls to pushObjectReference. |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1268 if (!readBlob(value, tag == BlobIndexTag)) | 1067 if (!readBlob(value, tag == BlobIndexTag)) |
1269 return false; | 1068 return false; |
1270 creator.pushObjectReference(*value); | 1069 creator.pushObjectReference(*value); |
1271 break; | 1070 break; |
1272 case FileTag: | 1071 case FileTag: |
1273 case FileIndexTag: | 1072 case FileIndexTag: |
1274 if (!readFile(value, tag == FileIndexTag)) | 1073 if (!readFile(value, tag == FileIndexTag)) |
1275 return false; | 1074 return false; |
1276 creator.pushObjectReference(*value); | 1075 creator.pushObjectReference(*value); |
1277 break; | 1076 break; |
1278 case DOMFileSystemTag: | |
1279 if (!readDOMFileSystem(value)) | |
1280 return false; | |
1281 creator.pushObjectReference(*value); | |
1282 break; | |
1283 case FileListTag: | 1077 case FileListTag: |
1284 case FileListIndexTag: | 1078 case FileListIndexTag: |
1285 if (!readFileList(value, tag == FileListIndexTag)) | 1079 if (!readFileList(value, tag == FileListIndexTag)) |
1286 return false; | 1080 return false; |
1287 creator.pushObjectReference(*value); | 1081 creator.pushObjectReference(*value); |
1288 break; | 1082 break; |
1289 case CryptoKeyTag: | |
1290 if (!readCryptoKey(value)) | |
1291 return false; | |
1292 creator.pushObjectReference(*value); | |
1293 break; | |
1294 case ImageDataTag: | 1083 case ImageDataTag: |
1295 if (!readImageData(value)) | 1084 if (!readImageData(value)) |
1296 return false; | 1085 return false; |
1297 creator.pushObjectReference(*value); | 1086 creator.pushObjectReference(*value); |
1298 break; | 1087 break; |
1299 | 1088 |
1300 case RegExpTag: | 1089 case RegExpTag: |
1301 if (!readRegExp(value)) | 1090 if (!readRegExp(value)) |
1302 return false; | 1091 return false; |
1303 creator.pushObjectReference(*value); | 1092 creator.pushObjectReference(*value); |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1398 case ObjectReferenceTag: { | 1187 case ObjectReferenceTag: { |
1399 if (!m_version) | 1188 if (!m_version) |
1400 return false; | 1189 return false; |
1401 uint32_t reference; | 1190 uint32_t reference; |
1402 if (!doReadUint32(&reference)) | 1191 if (!doReadUint32(&reference)) |
1403 return false; | 1192 return false; |
1404 if (!creator.tryGetObjectFromObjectReference(reference, value)) | 1193 if (!creator.tryGetObjectFromObjectReference(reference, value)) |
1405 return false; | 1194 return false; |
1406 break; | 1195 break; |
1407 } | 1196 } |
1197 case DOMFileSystemTag: | |
1198 case CryptoKeyTag: | |
1199 ASSERT_NOT_REACHED(); | |
1408 default: | 1200 default: |
1409 return false; | 1201 return false; |
1410 } | 1202 } |
1411 return !value->IsEmpty(); | 1203 return !value->IsEmpty(); |
1412 } | 1204 } |
1413 | 1205 |
1414 bool Reader::readVersion(uint32_t& version) | 1206 bool SerializedScriptValueReader::readVersion(uint32_t& version) |
1415 { | 1207 { |
1416 SerializationTag tag; | 1208 SerializationTag tag; |
1417 if (!readTag(&tag)) { | 1209 if (!readTag(&tag)) { |
1418 // This is a nullary buffer. We're still version 0. | 1210 // This is a nullary buffer. We're still version 0. |
1419 version = 0; | 1211 version = 0; |
1420 return true; | 1212 return true; |
1421 } | 1213 } |
1422 if (tag != VersionTag) { | 1214 if (tag != VersionTag) { |
1423 // Versions of the format past 0 start with the version tag. | 1215 // Versions of the format past 0 start with the version tag. |
1424 version = 0; | 1216 version = 0; |
1425 // Put back the tag. | 1217 // Put back the tag. |
1426 undoReadTag(); | 1218 undoReadTag(); |
1427 return true; | 1219 return true; |
1428 } | 1220 } |
1429 // Version-bearing messages are obligated to finish the version tag. | 1221 // Version-bearing messages are obligated to finish the version tag. |
1430 return doReadUint32(&version); | 1222 return doReadUint32(&version); |
1431 } | 1223 } |
1432 | 1224 |
1433 void Reader::setVersion(uint32_t version) | 1225 void SerializedScriptValueReader::setVersion(uint32_t version) |
1434 { | 1226 { |
1435 m_version = version; | 1227 m_version = version; |
1436 } | 1228 } |
1437 | 1229 |
1438 bool Reader::readTag(SerializationTag* tag) | 1230 bool SerializedScriptValueReader::readTag(SerializationTag* tag) |
1439 { | 1231 { |
1440 if (m_position >= m_length) | 1232 if (m_position >= m_length) |
1441 return false; | 1233 return false; |
1442 *tag = static_cast<SerializationTag>(m_buffer[m_position++]); | 1234 *tag = static_cast<SerializationTag>(m_buffer[m_position++]); |
1443 return true; | 1235 return true; |
1444 } | 1236 } |
1445 | 1237 |
1446 void Reader::undoReadTag() | 1238 void SerializedScriptValueReader::undoReadTag() |
1447 { | 1239 { |
1448 if (m_position > 0) | 1240 if (m_position > 0) |
1449 --m_position; | 1241 --m_position; |
1450 } | 1242 } |
1451 | 1243 |
1452 bool Reader::readArrayBufferViewSubTag(ArrayBufferViewSubTag* tag) | 1244 bool SerializedScriptValueReader::readArrayBufferViewSubTag(ArrayBufferViewSubTa g* tag) |
1453 { | 1245 { |
1454 if (m_position >= m_length) | 1246 if (m_position >= m_length) |
1455 return false; | 1247 return false; |
1456 *tag = static_cast<ArrayBufferViewSubTag>(m_buffer[m_position++]); | 1248 *tag = static_cast<ArrayBufferViewSubTag>(m_buffer[m_position++]); |
1457 return true; | 1249 return true; |
1458 } | 1250 } |
1459 | 1251 |
1460 bool Reader::readString(v8::Handle<v8::Value>* value) | 1252 bool SerializedScriptValueReader::readString(v8::Handle<v8::Value>* value) |
1461 { | 1253 { |
1462 uint32_t length; | 1254 uint32_t length; |
1463 if (!doReadUint32(&length)) | 1255 if (!doReadUint32(&length)) |
1464 return false; | 1256 return false; |
1465 if (m_position + length > m_length) | 1257 if (m_position + length > m_length) |
1466 return false; | 1258 return false; |
1467 *value = v8::String::NewFromUtf8(isolate(), reinterpret_cast<const char*>(m_ buffer + m_position), v8::String::kNormalString, length); | 1259 *value = v8::String::NewFromUtf8(isolate(), reinterpret_cast<const char*>(m_ buffer + m_position), v8::String::kNormalString, length); |
1468 m_position += length; | 1260 m_position += length; |
1469 return true; | 1261 return true; |
1470 } | 1262 } |
1471 | 1263 |
1472 bool Reader::readUCharString(v8::Handle<v8::Value>* value) | 1264 bool SerializedScriptValueReader::readUCharString(v8::Handle<v8::Value>* value) |
1473 { | 1265 { |
1474 uint32_t length; | 1266 uint32_t length; |
1475 if (!doReadUint32(&length) || (length & 1)) | 1267 if (!doReadUint32(&length) || (length & 1)) |
1476 return false; | 1268 return false; |
1477 if (m_position + length > m_length) | 1269 if (m_position + length > m_length) |
1478 return false; | 1270 return false; |
1479 ASSERT(!(m_position & 1)); | 1271 ASSERT(!(m_position & 1)); |
1480 *value = v8::String::NewFromTwoByte(isolate(), reinterpret_cast<const uint16 _t*>(m_buffer + m_position), v8::String::kNormalString, length / sizeof(UChar)); | 1272 *value = v8::String::NewFromTwoByte(isolate(), reinterpret_cast<const uint16 _t*>(m_buffer + m_position), v8::String::kNormalString, length / sizeof(UChar)); |
1481 m_position += length; | 1273 m_position += length; |
1482 return true; | 1274 return true; |
1483 } | 1275 } |
1484 | 1276 |
1485 bool Reader::readStringObject(v8::Handle<v8::Value>* value) | 1277 bool SerializedScriptValueReader::readStringObject(v8::Handle<v8::Value>* value) |
1486 { | 1278 { |
1487 v8::Handle<v8::Value> stringValue; | 1279 v8::Handle<v8::Value> stringValue; |
1488 if (!readString(&stringValue) || !stringValue->IsString()) | 1280 if (!readString(&stringValue) || !stringValue->IsString()) |
1489 return false; | 1281 return false; |
1490 *value = v8::StringObject::New(stringValue.As<v8::String>()); | 1282 *value = v8::StringObject::New(stringValue.As<v8::String>()); |
1491 return true; | 1283 return true; |
1492 } | 1284 } |
1493 | 1285 |
1494 bool Reader::readWebCoreString(String* string) | 1286 bool SerializedScriptValueReader::readWebCoreString(String* string) |
1495 { | 1287 { |
1496 uint32_t length; | 1288 uint32_t length; |
1497 if (!doReadUint32(&length)) | 1289 if (!doReadUint32(&length)) |
1498 return false; | 1290 return false; |
1499 if (m_position + length > m_length) | 1291 if (m_position + length > m_length) |
1500 return false; | 1292 return false; |
1501 *string = String::fromUTF8(reinterpret_cast<const char*>(m_buffer + m_positi on), length); | 1293 *string = String::fromUTF8(reinterpret_cast<const char*>(m_buffer + m_positi on), length); |
1502 m_position += length; | 1294 m_position += length; |
1503 return true; | 1295 return true; |
1504 } | 1296 } |
1505 | 1297 |
1506 bool Reader::readInt32(v8::Handle<v8::Value>* value) | 1298 bool SerializedScriptValueReader::readInt32(v8::Handle<v8::Value>* value) |
1507 { | 1299 { |
1508 uint32_t rawValue; | 1300 uint32_t rawValue; |
1509 if (!doReadUint32(&rawValue)) | 1301 if (!doReadUint32(&rawValue)) |
1510 return false; | 1302 return false; |
1511 *value = v8::Integer::New(isolate(), static_cast<int32_t>(ZigZag::decode(raw Value))); | 1303 *value = v8::Integer::New(isolate(), static_cast<int32_t>(ZigZag::decode(raw Value))); |
1512 return true; | 1304 return true; |
1513 } | 1305 } |
1514 | 1306 |
1515 bool Reader::readUint32(v8::Handle<v8::Value>* value) | 1307 bool SerializedScriptValueReader::readUint32(v8::Handle<v8::Value>* value) |
1516 { | 1308 { |
1517 uint32_t rawValue; | 1309 uint32_t rawValue; |
1518 if (!doReadUint32(&rawValue)) | 1310 if (!doReadUint32(&rawValue)) |
1519 return false; | 1311 return false; |
1520 *value = v8::Integer::NewFromUnsigned(isolate(), rawValue); | 1312 *value = v8::Integer::NewFromUnsigned(isolate(), rawValue); |
1521 return true; | 1313 return true; |
1522 } | 1314 } |
1523 | 1315 |
1524 bool Reader::readDate(v8::Handle<v8::Value>* value) | 1316 bool SerializedScriptValueReader::readDate(v8::Handle<v8::Value>* value) |
1525 { | 1317 { |
1526 double numberValue; | 1318 double numberValue; |
1527 if (!doReadNumber(&numberValue)) | 1319 if (!doReadNumber(&numberValue)) |
1528 return false; | 1320 return false; |
1529 *value = v8DateOrNaN(numberValue, isolate()); | 1321 *value = v8DateOrNaN(numberValue, isolate()); |
1530 return true; | 1322 return true; |
1531 } | 1323 } |
1532 | 1324 |
1533 bool Reader::readNumber(v8::Handle<v8::Value>* value) | 1325 bool SerializedScriptValueReader::readNumber(v8::Handle<v8::Value>* value) |
1534 { | 1326 { |
1535 double number; | 1327 double number; |
1536 if (!doReadNumber(&number)) | 1328 if (!doReadNumber(&number)) |
1537 return false; | 1329 return false; |
1538 *value = v8::Number::New(isolate(), number); | 1330 *value = v8::Number::New(isolate(), number); |
1539 return true; | 1331 return true; |
1540 } | 1332 } |
1541 | 1333 |
1542 bool Reader::readNumberObject(v8::Handle<v8::Value>* value) | 1334 bool SerializedScriptValueReader::readNumberObject(v8::Handle<v8::Value>* value) |
1543 { | 1335 { |
1544 double number; | 1336 double number; |
1545 if (!doReadNumber(&number)) | 1337 if (!doReadNumber(&number)) |
1546 return false; | 1338 return false; |
1547 *value = v8::NumberObject::New(isolate(), number); | 1339 *value = v8::NumberObject::New(isolate(), number); |
1548 return true; | 1340 return true; |
1549 } | 1341 } |
1550 | 1342 |
1551 bool Reader::readImageData(v8::Handle<v8::Value>* value) | 1343 bool SerializedScriptValueReader::readImageData(v8::Handle<v8::Value>* value) |
1552 { | 1344 { |
1553 uint32_t width; | 1345 uint32_t width; |
1554 uint32_t height; | 1346 uint32_t height; |
1555 uint32_t pixelDataLength; | 1347 uint32_t pixelDataLength; |
1556 if (!doReadUint32(&width)) | 1348 if (!doReadUint32(&width)) |
1557 return false; | 1349 return false; |
1558 if (!doReadUint32(&height)) | 1350 if (!doReadUint32(&height)) |
1559 return false; | 1351 return false; |
1560 if (!doReadUint32(&pixelDataLength)) | 1352 if (!doReadUint32(&pixelDataLength)) |
1561 return false; | 1353 return false; |
1562 if (m_position + pixelDataLength > m_length) | 1354 if (m_position + pixelDataLength > m_length) |
1563 return false; | 1355 return false; |
1564 RefPtrWillBeRawPtr<ImageData> imageData = ImageData::create(IntSize(width, h eight)); | 1356 RefPtrWillBeRawPtr<ImageData> imageData = ImageData::create(IntSize(width, h eight)); |
1565 Uint8ClampedArray* pixelArray = imageData->data(); | 1357 Uint8ClampedArray* pixelArray = imageData->data(); |
1566 ASSERT(pixelArray); | 1358 ASSERT(pixelArray); |
1567 ASSERT(pixelArray->length() >= pixelDataLength); | 1359 ASSERT(pixelArray->length() >= pixelDataLength); |
1568 memcpy(pixelArray->data(), m_buffer + m_position, pixelDataLength); | 1360 memcpy(pixelArray->data(), m_buffer + m_position, pixelDataLength); |
1569 m_position += pixelDataLength; | 1361 m_position += pixelDataLength; |
1570 *value = toV8(imageData.release(), m_scriptState->context()->Global(), isola te()); | 1362 *value = toV8(imageData.release(), m_scriptState->context()->Global(), isola te()); |
1571 return true; | 1363 return true; |
1572 } | 1364 } |
1573 | 1365 |
1574 PassRefPtr<ArrayBuffer> Reader::doReadArrayBuffer() | 1366 PassRefPtr<ArrayBuffer> SerializedScriptValueReader::doReadArrayBuffer() |
1575 { | 1367 { |
1576 uint32_t byteLength; | 1368 uint32_t byteLength; |
1577 if (!doReadUint32(&byteLength)) | 1369 if (!doReadUint32(&byteLength)) |
1578 return nullptr; | 1370 return nullptr; |
1579 if (m_position + byteLength > m_length) | 1371 if (m_position + byteLength > m_length) |
1580 return nullptr; | 1372 return nullptr; |
1581 const void* bufferStart = m_buffer + m_position; | 1373 const void* bufferStart = m_buffer + m_position; |
1582 m_position += byteLength; | 1374 m_position += byteLength; |
1583 return ArrayBuffer::create(bufferStart, byteLength); | 1375 return ArrayBuffer::create(bufferStart, byteLength); |
1584 } | 1376 } |
1585 | 1377 |
1586 bool Reader::readArrayBuffer(v8::Handle<v8::Value>* value) | 1378 bool SerializedScriptValueReader::readArrayBuffer(v8::Handle<v8::Value>* value) |
1587 { | 1379 { |
1588 RefPtr<ArrayBuffer> arrayBuffer = doReadArrayBuffer(); | 1380 RefPtr<ArrayBuffer> arrayBuffer = doReadArrayBuffer(); |
1589 if (!arrayBuffer) | 1381 if (!arrayBuffer) |
1590 return false; | 1382 return false; |
1591 *value = toV8(DOMArrayBuffer::create(arrayBuffer.release()), m_scriptState-> context()->Global(), isolate()); | 1383 *value = toV8(DOMArrayBuffer::create(arrayBuffer.release()), m_scriptState-> context()->Global(), isolate()); |
1592 return true; | 1384 return true; |
1593 } | 1385 } |
1594 | 1386 |
1595 bool Reader::readArrayBufferView(v8::Handle<v8::Value>* value, CompositeCreator& creator) | 1387 bool SerializedScriptValueReader::readArrayBufferView(v8::Handle<v8::Value>* val ue, ScriptValueCompositeCreator& creator) |
1596 { | 1388 { |
1597 ArrayBufferViewSubTag subTag; | 1389 ArrayBufferViewSubTag subTag; |
1598 uint32_t byteOffset; | 1390 uint32_t byteOffset; |
1599 uint32_t byteLength; | 1391 uint32_t byteLength; |
1600 RefPtr<DOMArrayBuffer> arrayBuffer; | 1392 RefPtr<DOMArrayBuffer> arrayBuffer; |
1601 v8::Handle<v8::Value> arrayBufferV8Value; | 1393 v8::Handle<v8::Value> arrayBufferV8Value; |
1602 if (!readArrayBufferViewSubTag(&subTag)) | 1394 if (!readArrayBufferViewSubTag(&subTag)) |
1603 return false; | 1395 return false; |
1604 if (!doReadUint32(&byteOffset)) | 1396 if (!doReadUint32(&byteOffset)) |
1605 return false; | 1397 return false; |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1671 break; | 1463 break; |
1672 default: | 1464 default: |
1673 return false; | 1465 return false; |
1674 } | 1466 } |
1675 // The various *Array::create() methods will return null if the range the vi ew expects is | 1467 // The various *Array::create() methods will return null if the range the vi ew expects is |
1676 // mismatched with the range the buffer can provide or if the byte offset is not aligned | 1468 // mismatched with the range the buffer can provide or if the byte offset is not aligned |
1677 // to the size of the element type. | 1469 // to the size of the element type. |
1678 return !value->IsEmpty(); | 1470 return !value->IsEmpty(); |
1679 } | 1471 } |
1680 | 1472 |
1681 bool Reader::readRegExp(v8::Handle<v8::Value>* value) | 1473 bool SerializedScriptValueReader::readRegExp(v8::Handle<v8::Value>* value) |
1682 { | 1474 { |
1683 v8::Handle<v8::Value> pattern; | 1475 v8::Handle<v8::Value> pattern; |
1684 if (!readString(&pattern)) | 1476 if (!readString(&pattern)) |
1685 return false; | 1477 return false; |
1686 uint32_t flags; | 1478 uint32_t flags; |
1687 if (!doReadUint32(&flags)) | 1479 if (!doReadUint32(&flags)) |
1688 return false; | 1480 return false; |
1689 *value = v8::RegExp::New(pattern.As<v8::String>(), static_cast<v8::RegExp::F lags>(flags)); | 1481 *value = v8::RegExp::New(pattern.As<v8::String>(), static_cast<v8::RegExp::F lags>(flags)); |
1690 return true; | 1482 return true; |
1691 } | 1483 } |
1692 | 1484 |
1693 bool Reader::readBlob(v8::Handle<v8::Value>* value, bool isIndexed) | 1485 bool SerializedScriptValueReader::readBlob(v8::Handle<v8::Value>* value, bool is Indexed) |
1694 { | 1486 { |
1695 if (m_version < 3) | 1487 if (m_version < 3) |
1696 return false; | 1488 return false; |
1697 Blob* blob = nullptr; | 1489 Blob* blob = nullptr; |
1698 if (isIndexed) { | 1490 if (isIndexed) { |
1699 if (m_version < 6) | 1491 if (m_version < 6) |
1700 return false; | 1492 return false; |
1701 ASSERT(m_blobInfo); | 1493 ASSERT(m_blobInfo); |
1702 uint32_t index; | 1494 uint32_t index; |
1703 if (!doReadUint32(&index) || index >= m_blobInfo->size()) | 1495 if (!doReadUint32(&index) || index >= m_blobInfo->size()) |
(...skipping 11 matching lines...) Expand all Loading... | |
1715 if (!readWebCoreString(&type)) | 1507 if (!readWebCoreString(&type)) |
1716 return false; | 1508 return false; |
1717 if (!doReadUint64(&size)) | 1509 if (!doReadUint64(&size)) |
1718 return false; | 1510 return false; |
1719 blob = Blob::create(getOrCreateBlobDataHandle(uuid, type, size)); | 1511 blob = Blob::create(getOrCreateBlobDataHandle(uuid, type, size)); |
1720 } | 1512 } |
1721 *value = toV8(blob, m_scriptState->context()->Global(), isolate()); | 1513 *value = toV8(blob, m_scriptState->context()->Global(), isolate()); |
1722 return true; | 1514 return true; |
1723 } | 1515 } |
1724 | 1516 |
1725 bool Reader::readDOMFileSystem(v8::Handle<v8::Value>* value) | 1517 bool SerializedScriptValueReader::readFile(v8::Handle<v8::Value>* value, bool is Indexed) |
1726 { | |
1727 uint32_t type; | |
1728 String name; | |
1729 String url; | |
1730 if (!doReadUint32(&type)) | |
1731 return false; | |
1732 if (!readWebCoreString(&name)) | |
1733 return false; | |
1734 if (!readWebCoreString(&url)) | |
1735 return false; | |
1736 DOMFileSystem* fs = DOMFileSystem::create(m_scriptState->executionContext(), name, static_cast<FileSystemType>(type), KURL(ParsedURLString, url)); | |
1737 *value = toV8(fs, m_scriptState->context()->Global(), isolate()); | |
1738 return true; | |
1739 } | |
1740 | |
1741 bool Reader::readFile(v8::Handle<v8::Value>* value, bool isIndexed) | |
1742 { | 1518 { |
1743 File* file = nullptr; | 1519 File* file = nullptr; |
1744 if (isIndexed) { | 1520 if (isIndexed) { |
1745 if (m_version < 6) | 1521 if (m_version < 6) |
1746 return false; | 1522 return false; |
1747 file = readFileIndexHelper(); | 1523 file = readFileIndexHelper(); |
1748 } else { | 1524 } else { |
1749 file = readFileHelper(); | 1525 file = readFileHelper(); |
1750 } | 1526 } |
1751 if (!file) | 1527 if (!file) |
1752 return false; | 1528 return false; |
1753 *value = toV8(file, m_scriptState->context()->Global(), isolate()); | 1529 *value = toV8(file, m_scriptState->context()->Global(), isolate()); |
1754 return true; | 1530 return true; |
1755 } | 1531 } |
1756 | 1532 |
1757 bool Reader::readFileList(v8::Handle<v8::Value>* value, bool isIndexed) | 1533 bool SerializedScriptValueReader::readFileList(v8::Handle<v8::Value>* value, boo l isIndexed) |
1758 { | 1534 { |
1759 if (m_version < 3) | 1535 if (m_version < 3) |
1760 return false; | 1536 return false; |
1761 uint32_t length; | 1537 uint32_t length; |
1762 if (!doReadUint32(&length)) | 1538 if (!doReadUint32(&length)) |
1763 return false; | 1539 return false; |
1764 FileList* fileList = FileList::create(); | 1540 FileList* fileList = FileList::create(); |
1765 for (unsigned i = 0; i < length; ++i) { | 1541 for (unsigned i = 0; i < length; ++i) { |
1766 File* file = nullptr; | 1542 File* file = nullptr; |
1767 if (isIndexed) { | 1543 if (isIndexed) { |
1768 if (m_version < 6) | 1544 if (m_version < 6) |
1769 return false; | 1545 return false; |
1770 file = readFileIndexHelper(); | 1546 file = readFileIndexHelper(); |
1771 } else { | 1547 } else { |
1772 file = readFileHelper(); | 1548 file = readFileHelper(); |
1773 } | 1549 } |
1774 if (!file) | 1550 if (!file) |
1775 return false; | 1551 return false; |
1776 fileList->append(file); | 1552 fileList->append(file); |
1777 } | 1553 } |
1778 *value = toV8(fileList, m_scriptState->context()->Global(), isolate()); | 1554 *value = toV8(fileList, m_scriptState->context()->Global(), isolate()); |
1779 return true; | 1555 return true; |
1780 } | 1556 } |
1781 | 1557 |
1782 bool Reader::readCryptoKey(v8::Handle<v8::Value>* value) | 1558 File* SerializedScriptValueReader::readFileHelper() |
1783 { | |
1784 uint32_t rawKeyType; | |
1785 if (!doReadUint32(&rawKeyType)) | |
1786 return false; | |
1787 | |
1788 WebCryptoKeyAlgorithm algorithm; | |
1789 WebCryptoKeyType type = WebCryptoKeyTypeSecret; | |
1790 | |
1791 switch (static_cast<CryptoKeySubTag>(rawKeyType)) { | |
1792 case AesKeyTag: | |
1793 if (!doReadAesKey(algorithm, type)) | |
1794 return false; | |
1795 break; | |
1796 case HmacKeyTag: | |
1797 if (!doReadHmacKey(algorithm, type)) | |
1798 return false; | |
1799 break; | |
1800 case RsaHashedKeyTag: | |
1801 if (!doReadRsaHashedKey(algorithm, type)) | |
1802 return false; | |
1803 break; | |
1804 case EcKeyTag: | |
1805 if (!doReadEcKey(algorithm, type)) | |
1806 return false; | |
1807 break; | |
1808 default: | |
1809 return false; | |
1810 } | |
1811 | |
1812 WebCryptoKeyUsageMask usages; | |
1813 bool extractable; | |
1814 if (!doReadKeyUsages(usages, extractable)) | |
1815 return false; | |
1816 | |
1817 uint32_t keyDataLength; | |
1818 if (!doReadUint32(&keyDataLength)) | |
1819 return false; | |
1820 | |
1821 if (m_position + keyDataLength > m_length) | |
1822 return false; | |
1823 | |
1824 const uint8_t* keyData = m_buffer + m_position; | |
1825 m_position += keyDataLength; | |
1826 | |
1827 WebCryptoKey key = WebCryptoKey::createNull(); | |
1828 if (!Platform::current()->crypto()->deserializeKeyForClone( | |
1829 algorithm, type, extractable, usages, keyData, keyDataLength, key)) { | |
1830 return false; | |
1831 } | |
1832 | |
1833 *value = toV8(CryptoKey::create(key), m_scriptState->context()->Global(), is olate()); | |
1834 return true; | |
1835 } | |
1836 | |
1837 File* Reader::readFileHelper() | |
1838 { | 1559 { |
1839 if (m_version < 3) | 1560 if (m_version < 3) |
1840 return nullptr; | 1561 return nullptr; |
1841 ASSERT(!m_blobInfo); | 1562 ASSERT(!m_blobInfo); |
1842 String path; | 1563 String path; |
1843 String name; | 1564 String name; |
1844 String relativePath; | 1565 String relativePath; |
1845 String uuid; | 1566 String uuid; |
1846 String type; | 1567 String type; |
1847 uint32_t hasSnapshot = 0; | 1568 uint32_t hasSnapshot = 0; |
(...skipping 17 matching lines...) Expand all Loading... | |
1865 if (!doReadNumber(&lastModified)) | 1586 if (!doReadNumber(&lastModified)) |
1866 return nullptr; | 1587 return nullptr; |
1867 } | 1588 } |
1868 uint32_t isUserVisible = 1; | 1589 uint32_t isUserVisible = 1; |
1869 if (m_version >= 7 && !doReadUint32(&isUserVisible)) | 1590 if (m_version >= 7 && !doReadUint32(&isUserVisible)) |
1870 return nullptr; | 1591 return nullptr; |
1871 const File::UserVisibility userVisibility = (isUserVisible > 0) ? File::IsUs erVisible : File::IsNotUserVisible; | 1592 const File::UserVisibility userVisibility = (isUserVisible > 0) ? File::IsUs erVisible : File::IsNotUserVisible; |
1872 return File::createFromSerialization(path, name, relativePath, userVisibilit y, hasSnapshot > 0, size, lastModified, getOrCreateBlobDataHandle(uuid, type)); | 1593 return File::createFromSerialization(path, name, relativePath, userVisibilit y, hasSnapshot > 0, size, lastModified, getOrCreateBlobDataHandle(uuid, type)); |
1873 } | 1594 } |
1874 | 1595 |
1875 File* Reader::readFileIndexHelper() | 1596 File* SerializedScriptValueReader::readFileIndexHelper() |
1876 { | 1597 { |
1877 if (m_version < 3) | 1598 if (m_version < 3) |
1878 return nullptr; | 1599 return nullptr; |
1879 ASSERT(m_blobInfo); | 1600 ASSERT(m_blobInfo); |
1880 uint32_t index; | 1601 uint32_t index; |
1881 if (!doReadUint32(&index) || index >= m_blobInfo->size()) | 1602 if (!doReadUint32(&index) || index >= m_blobInfo->size()) |
1882 return nullptr; | 1603 return nullptr; |
1883 const WebBlobInfo& info = (*m_blobInfo)[index]; | 1604 const WebBlobInfo& info = (*m_blobInfo)[index]; |
1884 return File::createFromIndexedSerialization(info.filePath(), info.fileName() , info.size(), info.lastModified(), getOrCreateBlobDataHandle(info.uuid(), info. type(), info.size())); | 1605 return File::createFromIndexedSerialization(info.filePath(), info.fileName() , info.size(), info.lastModified(), getOrCreateBlobDataHandle(info.uuid(), info. type(), info.size())); |
1885 } | 1606 } |
1886 | 1607 |
1887 bool Reader::doReadUint32(uint32_t* value) | 1608 bool SerializedScriptValueReader::doReadUint32(uint32_t* value) |
1888 { | 1609 { |
1889 return doReadUintHelper(value); | 1610 return doReadUintHelper(value); |
1890 } | 1611 } |
1891 | 1612 |
1892 bool Reader::doReadUint64(uint64_t* value) | 1613 bool SerializedScriptValueReader::doReadUint64(uint64_t* value) |
1893 { | 1614 { |
1894 return doReadUintHelper(value); | 1615 return doReadUintHelper(value); |
1895 } | 1616 } |
1896 | 1617 |
1897 bool Reader::doReadNumber(double* number) | 1618 bool SerializedScriptValueReader::doReadNumber(double* number) |
1898 { | 1619 { |
1899 if (m_position + sizeof(double) > m_length) | 1620 if (m_position + sizeof(double) > m_length) |
1900 return false; | 1621 return false; |
1901 uint8_t* numberAsByteArray = reinterpret_cast<uint8_t*>(number); | 1622 uint8_t* numberAsByteArray = reinterpret_cast<uint8_t*>(number); |
1902 for (unsigned i = 0; i < sizeof(double); ++i) | 1623 for (unsigned i = 0; i < sizeof(double); ++i) |
1903 numberAsByteArray[i] = m_buffer[m_position++]; | 1624 numberAsByteArray[i] = m_buffer[m_position++]; |
1904 return true; | 1625 return true; |
1905 } | 1626 } |
1906 | 1627 |
1907 PassRefPtr<BlobDataHandle> Reader::getOrCreateBlobDataHandle(const String& uuid, const String& type, long long size) | 1628 PassRefPtr<BlobDataHandle> SerializedScriptValueReader::getOrCreateBlobDataHandl e(const String& uuid, const String& type, long long size) |
1908 { | 1629 { |
1909 // The containing ssv may have a BDH for this uuid if this ssv is just being | 1630 // The containing ssv may have a BDH for this uuid if this ssv is just being |
1910 // passed from main to worker thread (for example). We use those values when creating | 1631 // passed from main to worker thread (for example). We use those values when creating |
1911 // the new blob instead of cons'ing up a new BDH. | 1632 // the new blob instead of cons'ing up a new BDH. |
1912 // | 1633 // |
1913 // FIXME: Maybe we should require that it work that way where the ssv must h ave a BDH for any | 1634 // FIXME: Maybe we should require that it work that way where the ssv must h ave a BDH for any |
1914 // blobs it comes across during deserialization. Would require callers to ex plicitly populate | 1635 // blobs it comes across during deserialization. Would require callers to ex plicitly populate |
1915 // the collection of BDH's for blobs to work, which would encourage lifetime s to be considered | 1636 // the collection of BDH's for blobs to work, which would encourage lifetime s to be considered |
1916 // when passing ssv's around cross process. At present, we get 'lucky' in so me cases because | 1637 // when passing ssv's around cross process. At present, we get 'lucky' in so me cases because |
1917 // the blob in the src process happens to still exist at the time the dest p rocess is deserializing. | 1638 // the blob in the src process happens to still exist at the time the dest p rocess is deserializing. |
1918 // For example in sharedWorker.postMessage(...). | 1639 // For example in sharedWorker.postMessage(...). |
1919 BlobDataHandleMap::const_iterator it = m_blobDataHandles.find(uuid); | 1640 BlobDataHandleMap::const_iterator it = m_blobDataHandles.find(uuid); |
1920 if (it != m_blobDataHandles.end()) { | 1641 if (it != m_blobDataHandles.end()) { |
1921 // make assertions about type and size? | 1642 // make assertions about type and size? |
1922 return it->value; | 1643 return it->value; |
1923 } | 1644 } |
1924 return BlobDataHandle::create(uuid, type, size); | 1645 return BlobDataHandle::create(uuid, type, size); |
1925 } | 1646 } |
1926 | 1647 |
1927 bool Reader::doReadHmacKey(WebCryptoKeyAlgorithm& algorithm, WebCryptoKeyType& t ype) | 1648 v8::Handle<v8::Value> ScriptValueDeserializer::deserialize() |
1928 { | |
1929 uint32_t lengthBytes; | |
1930 if (!doReadUint32(&lengthBytes)) | |
1931 return false; | |
1932 WebCryptoAlgorithmId hash; | |
1933 if (!doReadAlgorithmId(hash)) | |
1934 return false; | |
1935 algorithm = WebCryptoKeyAlgorithm::createHmac(hash, lengthBytes * 8); | |
1936 type = WebCryptoKeyTypeSecret; | |
1937 return !algorithm.isNull(); | |
1938 } | |
1939 | |
1940 bool Reader::doReadAesKey(WebCryptoKeyAlgorithm& algorithm, WebCryptoKeyType& ty pe) | |
1941 { | |
1942 WebCryptoAlgorithmId id; | |
1943 if (!doReadAlgorithmId(id)) | |
1944 return false; | |
1945 uint32_t lengthBytes; | |
1946 if (!doReadUint32(&lengthBytes)) | |
1947 return false; | |
1948 algorithm = WebCryptoKeyAlgorithm::createAes(id, lengthBytes * 8); | |
1949 type = WebCryptoKeyTypeSecret; | |
1950 return !algorithm.isNull(); | |
1951 } | |
1952 | |
1953 bool Reader::doReadRsaHashedKey(WebCryptoKeyAlgorithm& algorithm, WebCryptoKeyTy pe& type) | |
1954 { | |
1955 WebCryptoAlgorithmId id; | |
1956 if (!doReadAlgorithmId(id)) | |
1957 return false; | |
1958 | |
1959 if (!doReadAsymmetricKeyType(type)) | |
1960 return false; | |
1961 | |
1962 uint32_t modulusLengthBits; | |
1963 if (!doReadUint32(&modulusLengthBits)) | |
1964 return false; | |
1965 | |
1966 uint32_t publicExponentSize; | |
1967 if (!doReadUint32(&publicExponentSize)) | |
1968 return false; | |
1969 | |
1970 if (m_position + publicExponentSize > m_length) | |
1971 return false; | |
1972 | |
1973 const uint8_t* publicExponent = m_buffer + m_position; | |
1974 m_position += publicExponentSize; | |
1975 | |
1976 WebCryptoAlgorithmId hash; | |
1977 if (!doReadAlgorithmId(hash)) | |
1978 return false; | |
1979 algorithm = WebCryptoKeyAlgorithm::createRsaHashed(id, modulusLengthBits, pu blicExponent, publicExponentSize, hash); | |
1980 | |
1981 return !algorithm.isNull(); | |
1982 } | |
1983 | |
1984 bool Reader::doReadEcKey(WebCryptoKeyAlgorithm& algorithm, WebCryptoKeyType& typ e) | |
1985 { | |
1986 WebCryptoAlgorithmId id; | |
1987 if (!doReadAlgorithmId(id)) | |
1988 return false; | |
1989 | |
1990 if (!doReadAsymmetricKeyType(type)) | |
1991 return false; | |
1992 | |
1993 WebCryptoNamedCurve namedCurve; | |
1994 if (!doReadNamedCurve(namedCurve)) | |
1995 return false; | |
1996 | |
1997 algorithm = WebCryptoKeyAlgorithm::createEc(id, namedCurve); | |
1998 return !algorithm.isNull(); | |
1999 } | |
2000 | |
2001 bool Reader::doReadAlgorithmId(WebCryptoAlgorithmId& id) | |
2002 { | |
2003 uint32_t rawId; | |
2004 if (!doReadUint32(&rawId)) | |
2005 return false; | |
2006 | |
2007 switch (static_cast<CryptoKeyAlgorithmTag>(rawId)) { | |
2008 case AesCbcTag: | |
2009 id = WebCryptoAlgorithmIdAesCbc; | |
2010 return true; | |
2011 case HmacTag: | |
2012 id = WebCryptoAlgorithmIdHmac; | |
2013 return true; | |
2014 case RsaSsaPkcs1v1_5Tag: | |
2015 id = WebCryptoAlgorithmIdRsaSsaPkcs1v1_5; | |
2016 return true; | |
2017 case Sha1Tag: | |
2018 id = WebCryptoAlgorithmIdSha1; | |
2019 return true; | |
2020 case Sha256Tag: | |
2021 id = WebCryptoAlgorithmIdSha256; | |
2022 return true; | |
2023 case Sha384Tag: | |
2024 id = WebCryptoAlgorithmIdSha384; | |
2025 return true; | |
2026 case Sha512Tag: | |
2027 id = WebCryptoAlgorithmIdSha512; | |
2028 return true; | |
2029 case AesGcmTag: | |
2030 id = WebCryptoAlgorithmIdAesGcm; | |
2031 return true; | |
2032 case RsaOaepTag: | |
2033 id = WebCryptoAlgorithmIdRsaOaep; | |
2034 return true; | |
2035 case AesCtrTag: | |
2036 id = WebCryptoAlgorithmIdAesCtr; | |
2037 return true; | |
2038 case AesKwTag: | |
2039 id = WebCryptoAlgorithmIdAesKw; | |
2040 return true; | |
2041 case RsaPssTag: | |
2042 id = WebCryptoAlgorithmIdRsaPss; | |
2043 return true; | |
2044 case EcdsaTag: | |
2045 id = WebCryptoAlgorithmIdEcdsa; | |
2046 return true; | |
2047 } | |
2048 | |
2049 return false; | |
2050 } | |
2051 | |
2052 bool Reader::doReadAsymmetricKeyType(WebCryptoKeyType& type) | |
2053 { | |
2054 uint32_t rawType; | |
2055 if (!doReadUint32(&rawType)) | |
2056 return false; | |
2057 | |
2058 switch (static_cast<AssymetricCryptoKeyType>(rawType)) { | |
2059 case PublicKeyType: | |
2060 type = WebCryptoKeyTypePublic; | |
2061 return true; | |
2062 case PrivateKeyType: | |
2063 type = WebCryptoKeyTypePrivate; | |
2064 return true; | |
2065 } | |
2066 | |
2067 return false; | |
2068 } | |
2069 | |
2070 bool Reader::doReadNamedCurve(WebCryptoNamedCurve& namedCurve) | |
2071 { | |
2072 uint32_t rawName; | |
2073 if (!doReadUint32(&rawName)) | |
2074 return false; | |
2075 | |
2076 switch (static_cast<NamedCurveTag>(rawName)) { | |
2077 case P256Tag: | |
2078 namedCurve = WebCryptoNamedCurveP256; | |
2079 return true; | |
2080 case P384Tag: | |
2081 namedCurve = WebCryptoNamedCurveP384; | |
2082 return true; | |
2083 case P521Tag: | |
2084 namedCurve = WebCryptoNamedCurveP521; | |
2085 return true; | |
2086 } | |
2087 | |
2088 return false; | |
2089 } | |
2090 | |
2091 bool Reader::doReadKeyUsages(WebCryptoKeyUsageMask& usages, bool& extractable) | |
2092 { | |
2093 // Reminder to update this when adding new key usages. | |
2094 COMPILE_ASSERT(EndOfWebCryptoKeyUsage == (1 << 7) + 1, UpdateMe); | |
2095 const uint32_t allPossibleUsages = ExtractableUsage | EncryptUsage | Decrypt Usage | SignUsage | VerifyUsage | DeriveKeyUsage | WrapKeyUsage | UnwrapKeyUsage | DeriveBitsUsage; | |
2096 | |
2097 uint32_t rawUsages; | |
2098 if (!doReadUint32(&rawUsages)) | |
2099 return false; | |
2100 | |
2101 // Make sure it doesn't contain an unrecognized usage value. | |
2102 if (rawUsages & ~allPossibleUsages) | |
2103 return false; | |
2104 | |
2105 usages = 0; | |
2106 | |
2107 extractable = rawUsages & ExtractableUsage; | |
2108 | |
2109 if (rawUsages & EncryptUsage) | |
2110 usages |= WebCryptoKeyUsageEncrypt; | |
2111 if (rawUsages & DecryptUsage) | |
2112 usages |= WebCryptoKeyUsageDecrypt; | |
2113 if (rawUsages & SignUsage) | |
2114 usages |= WebCryptoKeyUsageSign; | |
2115 if (rawUsages & VerifyUsage) | |
2116 usages |= WebCryptoKeyUsageVerify; | |
2117 if (rawUsages & DeriveKeyUsage) | |
2118 usages |= WebCryptoKeyUsageDeriveKey; | |
2119 if (rawUsages & WrapKeyUsage) | |
2120 usages |= WebCryptoKeyUsageWrapKey; | |
2121 if (rawUsages & UnwrapKeyUsage) | |
2122 usages |= WebCryptoKeyUsageUnwrapKey; | |
2123 if (rawUsages & DeriveBitsUsage) | |
2124 usages |= WebCryptoKeyUsageDeriveBits; | |
2125 | |
2126 return true; | |
2127 } | |
2128 | |
2129 v8::Handle<v8::Value> Deserializer::deserialize() | |
2130 { | 1649 { |
2131 v8::Isolate* isolate = m_reader.scriptState()->isolate(); | 1650 v8::Isolate* isolate = m_reader.scriptState()->isolate(); |
2132 if (!m_reader.readVersion(m_version) || m_version > SerializedScriptValue::w ireFormatVersion) | 1651 if (!m_reader.readVersion(m_version) || m_version > SerializedScriptValue::w ireFormatVersion) |
2133 return v8::Null(isolate); | 1652 return v8::Null(isolate); |
2134 m_reader.setVersion(m_version); | 1653 m_reader.setVersion(m_version); |
2135 v8::EscapableHandleScope scope(isolate); | 1654 v8::EscapableHandleScope scope(isolate); |
2136 while (!m_reader.isEof()) { | 1655 while (!m_reader.isEof()) { |
2137 if (!doDeserialize()) | 1656 if (!doDeserialize()) |
2138 return v8::Null(isolate); | 1657 return v8::Null(isolate); |
2139 } | 1658 } |
2140 if (stackDepth() != 1 || m_openCompositeReferenceStack.size()) | 1659 if (stackDepth() != 1 || m_openCompositeReferenceStack.size()) |
2141 return v8::Null(isolate); | 1660 return v8::Null(isolate); |
2142 v8::Handle<v8::Value> result = scope.Escape(element(0)); | 1661 v8::Handle<v8::Value> result = scope.Escape(element(0)); |
2143 return result; | 1662 return result; |
2144 } | 1663 } |
2145 | 1664 |
2146 bool Deserializer::newSparseArray(uint32_t) | 1665 bool ScriptValueDeserializer::newSparseArray(uint32_t) |
2147 { | 1666 { |
2148 v8::Local<v8::Array> array = v8::Array::New(m_reader.scriptState()->isolate( ), 0); | 1667 v8::Local<v8::Array> array = v8::Array::New(m_reader.scriptState()->isolate( ), 0); |
2149 openComposite(array); | 1668 openComposite(array); |
2150 return true; | 1669 return true; |
2151 } | 1670 } |
2152 | 1671 |
2153 bool Deserializer::newDenseArray(uint32_t length) | 1672 bool ScriptValueDeserializer::newDenseArray(uint32_t length) |
2154 { | 1673 { |
2155 v8::Local<v8::Array> array = v8::Array::New(m_reader.scriptState()->isolate( ), length); | 1674 v8::Local<v8::Array> array = v8::Array::New(m_reader.scriptState()->isolate( ), length); |
2156 openComposite(array); | 1675 openComposite(array); |
2157 return true; | 1676 return true; |
2158 } | 1677 } |
2159 | 1678 |
2160 bool Deserializer::consumeTopOfStack(v8::Handle<v8::Value>* object) | 1679 bool ScriptValueDeserializer::consumeTopOfStack(v8::Handle<v8::Value>* object) |
2161 { | 1680 { |
2162 if (stackDepth() < 1) | 1681 if (stackDepth() < 1) |
2163 return false; | 1682 return false; |
2164 *object = element(stackDepth() - 1); | 1683 *object = element(stackDepth() - 1); |
2165 pop(1); | 1684 pop(1); |
2166 return true; | 1685 return true; |
2167 } | 1686 } |
2168 | 1687 |
2169 bool Deserializer::newObject() | 1688 bool ScriptValueDeserializer::newObject() |
2170 { | 1689 { |
2171 v8::Local<v8::Object> object = v8::Object::New(m_reader.scriptState()->isola te()); | 1690 v8::Local<v8::Object> object = v8::Object::New(m_reader.scriptState()->isola te()); |
2172 if (object.IsEmpty()) | 1691 if (object.IsEmpty()) |
2173 return false; | 1692 return false; |
2174 openComposite(object); | 1693 openComposite(object); |
2175 return true; | 1694 return true; |
2176 } | 1695 } |
2177 | 1696 |
2178 bool Deserializer::completeObject(uint32_t numProperties, v8::Handle<v8::Value>* value) | 1697 bool ScriptValueDeserializer::completeObject(uint32_t numProperties, v8::Handle< v8::Value>* value) |
2179 { | 1698 { |
2180 v8::Local<v8::Object> object; | 1699 v8::Local<v8::Object> object; |
2181 if (m_version > 0) { | 1700 if (m_version > 0) { |
2182 v8::Local<v8::Value> composite; | 1701 v8::Local<v8::Value> composite; |
2183 if (!closeComposite(&composite)) | 1702 if (!closeComposite(&composite)) |
2184 return false; | 1703 return false; |
2185 object = composite.As<v8::Object>(); | 1704 object = composite.As<v8::Object>(); |
2186 } else { | 1705 } else { |
2187 object = v8::Object::New(m_reader.scriptState()->isolate()); | 1706 object = v8::Object::New(m_reader.scriptState()->isolate()); |
2188 } | 1707 } |
2189 if (object.IsEmpty()) | 1708 if (object.IsEmpty()) |
2190 return false; | 1709 return false; |
2191 return initializeObject(object, numProperties, value); | 1710 return initializeObject(object, numProperties, value); |
2192 } | 1711 } |
2193 | 1712 |
2194 bool Deserializer::completeSparseArray(uint32_t numProperties, uint32_t length, v8::Handle<v8::Value>* value) | 1713 bool ScriptValueDeserializer::completeSparseArray(uint32_t numProperties, uint32 _t length, v8::Handle<v8::Value>* value) |
2195 { | 1714 { |
2196 v8::Local<v8::Array> array; | 1715 v8::Local<v8::Array> array; |
2197 if (m_version > 0) { | 1716 if (m_version > 0) { |
2198 v8::Local<v8::Value> composite; | 1717 v8::Local<v8::Value> composite; |
2199 if (!closeComposite(&composite)) | 1718 if (!closeComposite(&composite)) |
2200 return false; | 1719 return false; |
2201 array = composite.As<v8::Array>(); | 1720 array = composite.As<v8::Array>(); |
2202 } else { | 1721 } else { |
2203 array = v8::Array::New(m_reader.scriptState()->isolate()); | 1722 array = v8::Array::New(m_reader.scriptState()->isolate()); |
2204 } | 1723 } |
2205 if (array.IsEmpty()) | 1724 if (array.IsEmpty()) |
2206 return false; | 1725 return false; |
2207 return initializeObject(array, numProperties, value); | 1726 return initializeObject(array, numProperties, value); |
2208 } | 1727 } |
2209 | 1728 |
2210 bool Deserializer::completeDenseArray(uint32_t numProperties, uint32_t length, v 8::Handle<v8::Value>* value) | 1729 bool ScriptValueDeserializer::completeDenseArray(uint32_t numProperties, uint32_ t length, v8::Handle<v8::Value>* value) |
2211 { | 1730 { |
2212 v8::Local<v8::Array> array; | 1731 v8::Local<v8::Array> array; |
2213 if (m_version > 0) { | 1732 if (m_version > 0) { |
2214 v8::Local<v8::Value> composite; | 1733 v8::Local<v8::Value> composite; |
2215 if (!closeComposite(&composite)) | 1734 if (!closeComposite(&composite)) |
2216 return false; | 1735 return false; |
2217 array = composite.As<v8::Array>(); | 1736 array = composite.As<v8::Array>(); |
2218 } | 1737 } |
2219 if (array.IsEmpty()) | 1738 if (array.IsEmpty()) |
2220 return false; | 1739 return false; |
2221 if (!initializeObject(array, numProperties, value)) | 1740 if (!initializeObject(array, numProperties, value)) |
2222 return false; | 1741 return false; |
2223 if (length > stackDepth()) | 1742 if (length > stackDepth()) |
2224 return false; | 1743 return false; |
2225 for (unsigned i = 0, stackPos = stackDepth() - length; i < length; i++, stac kPos++) { | 1744 for (unsigned i = 0, stackPos = stackDepth() - length; i < length; i++, stac kPos++) { |
2226 v8::Local<v8::Value> elem = element(stackPos); | 1745 v8::Local<v8::Value> elem = element(stackPos); |
2227 if (!elem->IsUndefined()) | 1746 if (!elem->IsUndefined()) |
2228 array->Set(i, elem); | 1747 array->Set(i, elem); |
2229 } | 1748 } |
2230 pop(length); | 1749 pop(length); |
2231 return true; | 1750 return true; |
2232 } | 1751 } |
2233 | 1752 |
2234 void Deserializer::pushObjectReference(const v8::Handle<v8::Value>& object) | 1753 void ScriptValueDeserializer::pushObjectReference(const v8::Handle<v8::Value>& o bject) |
2235 { | 1754 { |
2236 m_objectPool.append(object); | 1755 m_objectPool.append(object); |
2237 } | 1756 } |
2238 | 1757 |
2239 bool Deserializer::tryGetTransferredMessagePort(uint32_t index, v8::Handle<v8::V alue>* object) | 1758 bool ScriptValueDeserializer::tryGetTransferredMessagePort(uint32_t index, v8::H andle<v8::Value>* object) |
2240 { | 1759 { |
2241 if (!m_transferredMessagePorts) | 1760 if (!m_transferredMessagePorts) |
2242 return false; | 1761 return false; |
2243 if (index >= m_transferredMessagePorts->size()) | 1762 if (index >= m_transferredMessagePorts->size()) |
2244 return false; | 1763 return false; |
2245 v8::Handle<v8::Object> creationContext = m_reader.scriptState()->context()-> Global(); | 1764 v8::Handle<v8::Object> creationContext = m_reader.scriptState()->context()-> Global(); |
2246 *object = toV8(m_transferredMessagePorts->at(index).get(), creationContext, m_reader.scriptState()->isolate()); | 1765 *object = toV8(m_transferredMessagePorts->at(index).get(), creationContext, m_reader.scriptState()->isolate()); |
2247 return true; | 1766 return true; |
2248 } | 1767 } |
2249 | 1768 |
2250 bool Deserializer::tryGetTransferredArrayBuffer(uint32_t index, v8::Handle<v8::V alue>* object) | 1769 bool ScriptValueDeserializer::tryGetTransferredArrayBuffer(uint32_t index, v8::H andle<v8::Value>* object) |
2251 { | 1770 { |
2252 if (!m_arrayBufferContents) | 1771 if (!m_arrayBufferContents) |
2253 return false; | 1772 return false; |
2254 if (index >= m_arrayBuffers.size()) | 1773 if (index >= m_arrayBuffers.size()) |
2255 return false; | 1774 return false; |
2256 v8::Handle<v8::Object> result = m_arrayBuffers.at(index); | 1775 v8::Handle<v8::Object> result = m_arrayBuffers.at(index); |
2257 if (result.IsEmpty()) { | 1776 if (result.IsEmpty()) { |
2258 RefPtr<DOMArrayBuffer> buffer = DOMArrayBuffer::create(m_arrayBufferCont ents->at(index)); | 1777 RefPtr<DOMArrayBuffer> buffer = DOMArrayBuffer::create(m_arrayBufferCont ents->at(index)); |
2259 v8::Isolate* isolate = m_reader.scriptState()->isolate(); | 1778 v8::Isolate* isolate = m_reader.scriptState()->isolate(); |
2260 v8::Handle<v8::Object> creationContext = m_reader.scriptState()->context ()->Global(); | 1779 v8::Handle<v8::Object> creationContext = m_reader.scriptState()->context ()->Global(); |
2261 result = toV8Object(buffer.get(), creationContext, isolate); | 1780 result = toV8Object(buffer.get(), creationContext, isolate); |
2262 m_arrayBuffers[index] = result; | 1781 m_arrayBuffers[index] = result; |
2263 } | 1782 } |
2264 *object = result; | 1783 *object = result; |
2265 return true; | 1784 return true; |
2266 } | 1785 } |
2267 | 1786 |
2268 bool Deserializer::tryGetObjectFromObjectReference(uint32_t reference, v8::Handl e<v8::Value>* object) | 1787 bool ScriptValueDeserializer::tryGetObjectFromObjectReference(uint32_t reference , v8::Handle<v8::Value>* object) |
2269 { | 1788 { |
2270 if (reference >= m_objectPool.size()) | 1789 if (reference >= m_objectPool.size()) |
2271 return false; | 1790 return false; |
2272 *object = m_objectPool[reference]; | 1791 *object = m_objectPool[reference]; |
2273 return object; | 1792 return object; |
2274 } | 1793 } |
2275 | 1794 |
2276 uint32_t Deserializer::objectReferenceCount() | 1795 uint32_t ScriptValueDeserializer::objectReferenceCount() |
2277 { | 1796 { |
2278 return m_objectPool.size(); | 1797 return m_objectPool.size(); |
2279 } | 1798 } |
2280 | 1799 |
2281 bool Deserializer::initializeObject(v8::Handle<v8::Object> object, uint32_t numP roperties, v8::Handle<v8::Value>* value) | 1800 bool ScriptValueDeserializer::initializeObject(v8::Handle<v8::Object> object, ui nt32_t numProperties, v8::Handle<v8::Value>* value) |
2282 { | 1801 { |
2283 unsigned length = 2 * numProperties; | 1802 unsigned length = 2 * numProperties; |
2284 if (length > stackDepth()) | 1803 if (length > stackDepth()) |
2285 return false; | 1804 return false; |
2286 for (unsigned i = stackDepth() - length; i < stackDepth(); i += 2) { | 1805 for (unsigned i = stackDepth() - length; i < stackDepth(); i += 2) { |
2287 v8::Local<v8::Value> propertyName = element(i); | 1806 v8::Local<v8::Value> propertyName = element(i); |
2288 v8::Local<v8::Value> propertyValue = element(i + 1); | 1807 v8::Local<v8::Value> propertyValue = element(i + 1); |
2289 object->Set(propertyName, propertyValue); | 1808 object->Set(propertyName, propertyValue); |
2290 } | 1809 } |
2291 pop(length); | 1810 pop(length); |
2292 *value = object; | 1811 *value = object; |
2293 return true; | 1812 return true; |
2294 } | 1813 } |
2295 | 1814 |
2296 bool Deserializer::read(v8::Local<v8::Value>* value) | 1815 bool ScriptValueDeserializer::read(v8::Local<v8::Value>* value) |
2297 { | 1816 { |
2298 return m_reader.read(value, *this); | 1817 return m_reader.read(value, *this); |
2299 } | 1818 } |
2300 | 1819 |
2301 bool Deserializer::doDeserialize() | 1820 bool ScriptValueDeserializer::doDeserialize() |
2302 { | 1821 { |
2303 v8::Local<v8::Value> value; | 1822 v8::Local<v8::Value> value; |
2304 if (!read(&value)) | 1823 if (!read(&value)) |
2305 return false; | 1824 return false; |
2306 if (!value.IsEmpty()) | 1825 if (!value.IsEmpty()) |
2307 push(value); | 1826 push(value); |
2308 return true; | 1827 return true; |
2309 } | 1828 } |
2310 | 1829 |
2311 v8::Local<v8::Value> Deserializer::element(unsigned index) | 1830 v8::Local<v8::Value> ScriptValueDeserializer::element(unsigned index) |
2312 { | 1831 { |
2313 ASSERT_WITH_SECURITY_IMPLICATION(index < m_stack.size()); | 1832 ASSERT_WITH_SECURITY_IMPLICATION(index < m_stack.size()); |
2314 return m_stack[index]; | 1833 return m_stack[index]; |
2315 } | 1834 } |
2316 | 1835 |
2317 void Deserializer::openComposite(const v8::Local<v8::Value>& object) | 1836 void ScriptValueDeserializer::openComposite(const v8::Local<v8::Value>& object) |
2318 { | 1837 { |
2319 uint32_t newObjectReference = m_objectPool.size(); | 1838 uint32_t newObjectReference = m_objectPool.size(); |
2320 m_openCompositeReferenceStack.append(newObjectReference); | 1839 m_openCompositeReferenceStack.append(newObjectReference); |
2321 m_objectPool.append(object); | 1840 m_objectPool.append(object); |
2322 } | 1841 } |
2323 | 1842 |
2324 bool Deserializer::closeComposite(v8::Handle<v8::Value>* object) | 1843 bool ScriptValueDeserializer::closeComposite(v8::Handle<v8::Value>* object) |
2325 { | 1844 { |
2326 if (!m_openCompositeReferenceStack.size()) | 1845 if (!m_openCompositeReferenceStack.size()) |
2327 return false; | 1846 return false; |
2328 uint32_t objectReference = m_openCompositeReferenceStack[m_openCompositeRefe renceStack.size() - 1]; | 1847 uint32_t objectReference = m_openCompositeReferenceStack[m_openCompositeRefe renceStack.size() - 1]; |
2329 m_openCompositeReferenceStack.shrink(m_openCompositeReferenceStack.size() - 1); | 1848 m_openCompositeReferenceStack.shrink(m_openCompositeReferenceStack.size() - 1); |
2330 if (objectReference >= m_objectPool.size()) | 1849 if (objectReference >= m_objectPool.size()) |
2331 return false; | 1850 return false; |
2332 *object = m_objectPool[objectReference]; | 1851 *object = m_objectPool[objectReference]; |
2333 return true; | 1852 return true; |
2334 } | 1853 } |
2335 | 1854 |
2336 } // SerializedScriptValueInternal | |
2337 | |
2338 } // namespace blink | 1855 } // namespace blink |
OLD | NEW |