Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(80)

Side by Side Diff: Source/bindings/core/v8/ScriptValueSerializer.cpp

Issue 721133002: bindings: preparation for fixing incorrect dependency of SerializedScriptValue. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Patch for landing Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "config.h"
6 #include "bindings/core/v8/ScriptValueSerializer.h"
7
8 #include "bindings/core/v8/V8ArrayBuffer.h"
9 #include "bindings/core/v8/V8ArrayBufferView.h"
10 #include "bindings/core/v8/V8Blob.h"
11 #include "bindings/core/v8/V8File.h"
12 #include "bindings/core/v8/V8FileList.h"
13 #include "bindings/core/v8/V8ImageData.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"
18 #include "core/fileapi/Blob.h"
19 #include "core/fileapi/File.h"
20 #include "core/fileapi/FileList.h"
21 #include "public/platform/Platform.h"
22 #include "public/platform/WebBlobInfo.h"
23 #include "wtf/ArrayBuffer.h"
24 #include "wtf/ArrayBufferContents.h"
25 #include "wtf/ArrayBufferView.h"
26 #include "wtf/text/StringHash.h"
27 #include "wtf/text/StringUTF8Adaptor.h"
28
29 // FIXME: consider crashing in debug mode on deserialization errors
30 // NOTE: be sure to change wireFormatVersion as necessary!
31
32 namespace blink {
33
34 namespace SerializedScriptValueInternal {
35
36 // 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
38
39 // ZigZag encoding helps VarInt encoding stay small for negative
40 // numbers with small absolute values.
41 class ZigZag {
42 public:
43 static uint32_t encode(uint32_t value)
44 {
45 if (value & (1U << 31))
46 value = ((~value) << 1) + 1;
47 else
48 value <<= 1;
49 return value;
50 }
51
52 static uint32_t decode(uint32_t value)
53 {
54 if (value & 1)
55 value = ~(value >> 1);
56 else
57 value >>= 1;
58 return value;
59 }
60
61 private:
62 ZigZag();
63 };
64
65 static const int maxDepth = 20000;
66
67 static bool shouldCheckForCycles(int depth)
68 {
69 ASSERT(depth >= 0);
70 // 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
72 // is a power of two.
73 return !(depth & (depth - 1));
74 }
75
76 void Writer::writeUndefined()
77 {
78 append(UndefinedTag);
79 }
80
81 void Writer::writeNull()
82 {
83 append(NullTag);
84 }
85
86 void Writer::writeTrue()
87 {
88 append(TrueTag);
89 }
90
91 void Writer::writeFalse()
92 {
93 append(FalseTag);
94 }
95
96 void Writer::writeBooleanObject(bool value)
97 {
98 append(value ? TrueObjectTag : FalseObjectTag);
99 }
100
101 void Writer::writeOneByteString(v8::Handle<v8::String>& string)
102 {
103 int stringLength = string->Length();
104 int utf8Length = string->Utf8Length();
105 ASSERT(stringLength >= 0 && utf8Length >= 0);
106
107 append(StringTag);
108 doWriteUint32(static_cast<uint32_t>(utf8Length));
109 ensureSpace(utf8Length);
110
111 // ASCII fast path.
112 if (stringLength == utf8Length) {
113 string->WriteOneByte(byteAt(m_position), 0, utf8Length, v8StringWriteOpt ions());
114 } else {
115 char* buffer = reinterpret_cast<char*>(byteAt(m_position));
116 string->WriteUtf8(buffer, utf8Length, 0, v8StringWriteOptions());
117 }
118 m_position += utf8Length;
119 }
120
121 void Writer::writeUCharString(v8::Handle<v8::String>& string)
122 {
123 int length = string->Length();
124 ASSERT(length >= 0);
125
126 int size = length * sizeof(UChar);
127 int bytes = bytesNeededToWireEncode(static_cast<uint32_t>(size));
128 if ((m_position + 1 + bytes) & 1)
129 append(PaddingTag);
130
131 append(StringUCharTag);
132 doWriteUint32(static_cast<uint32_t>(size));
133 ensureSpace(size);
134
135 ASSERT(!(m_position & 1));
136 uint16_t* buffer = reinterpret_cast<uint16_t*>(byteAt(m_position));
137 string->Write(buffer, 0, length, v8StringWriteOptions());
138 m_position += size;
139 }
140
141 void Writer::writeStringObject(const char* data, int length)
142 {
143 ASSERT(length >= 0);
144 append(StringObjectTag);
145 doWriteString(data, length);
146 }
147
148 void Writer::writeWebCoreString(const String& string)
149 {
150 // Uses UTF8 encoding so we can read it back as either V8 or
151 // WebCore string.
152 append(StringTag);
153 doWriteWebCoreString(string);
154 }
155
156 void Writer::writeVersion()
157 {
158 append(VersionTag);
159 doWriteUint32(SerializedScriptValue::wireFormatVersion);
160 }
161
162 void Writer::writeInt32(int32_t value)
163 {
164 append(Int32Tag);
165 doWriteUint32(ZigZag::encode(static_cast<uint32_t>(value)));
166 }
167
168 void Writer::writeUint32(uint32_t value)
169 {
170 append(Uint32Tag);
171 doWriteUint32(value);
172 }
173
174 void Writer::writeDate(double numberValue)
175 {
176 append(DateTag);
177 doWriteNumber(numberValue);
178 }
179
180 void Writer::writeNumber(double number)
181 {
182 append(NumberTag);
183 doWriteNumber(number);
184 }
185
186 void Writer::writeNumberObject(double number)
187 {
188 append(NumberObjectTag);
189 doWriteNumber(number);
190 }
191
192 void Writer::writeBlob(const String& uuid, const String& type, unsigned long lon g size)
193 {
194 append(BlobTag);
195 doWriteWebCoreString(uuid);
196 doWriteWebCoreString(type);
197 doWriteUint64(size);
198 }
199
200 void Writer::writeDOMFileSystem(int type, const String& name, const String& url)
201 {
202 append(DOMFileSystemTag);
203 doWriteUint32(type);
204 doWriteWebCoreString(name);
205 doWriteWebCoreString(url);
206 }
207
208 void Writer::writeBlobIndex(int blobIndex)
209 {
210 ASSERT(blobIndex >= 0);
211 append(BlobIndexTag);
212 doWriteUint32(blobIndex);
213 }
214
215 void Writer::writeFile(const File& file)
216 {
217 append(FileTag);
218 doWriteFile(file);
219 }
220
221 void Writer::writeFileIndex(int blobIndex)
222 {
223 append(FileIndexTag);
224 doWriteUint32(blobIndex);
225 }
226
227 void Writer::writeFileList(const FileList& fileList)
228 {
229 append(FileListTag);
230 uint32_t length = fileList.length();
231 doWriteUint32(length);
232 for (unsigned i = 0; i < length; ++i)
233 doWriteFile(*fileList.item(i));
234 }
235
236 void Writer::writeFileListIndex(const Vector<int>& blobIndices)
237 {
238 append(FileListIndexTag);
239 uint32_t length = blobIndices.size();
240 doWriteUint32(length);
241 for (unsigned i = 0; i < length; ++i)
242 doWriteUint32(blobIndices[i]);
243 }
244
245 bool Writer::writeCryptoKey(const WebCryptoKey& key)
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 {
280 append(ArrayBufferTag);
281 doWriteArrayBuffer(arrayBuffer);
282 }
283
284 void Writer::writeArrayBufferView(const ArrayBufferView& arrayBufferView)
285 {
286 append(ArrayBufferViewTag);
287 #if ENABLE(ASSERT)
288 const ArrayBuffer& arrayBuffer = *arrayBufferView.buffer();
289 ASSERT(static_cast<const uint8_t*>(arrayBuffer.data()) + arrayBufferView.byt eOffset() ==
290 static_cast<const uint8_t*>(arrayBufferView.baseAddress()));
291 #endif
292 ArrayBufferView::ViewType type = arrayBufferView.type();
293
294 if (type == ArrayBufferView::TypeInt8)
295 append(ByteArrayTag);
296 else if (type == ArrayBufferView::TypeUint8Clamped)
297 append(UnsignedByteClampedArrayTag);
298 else if (type == ArrayBufferView::TypeUint8)
299 append(UnsignedByteArrayTag);
300 else if (type == ArrayBufferView::TypeInt16)
301 append(ShortArrayTag);
302 else if (type == ArrayBufferView::TypeUint16)
303 append(UnsignedShortArrayTag);
304 else if (type == ArrayBufferView::TypeInt32)
305 append(IntArrayTag);
306 else if (type == ArrayBufferView::TypeUint32)
307 append(UnsignedIntArrayTag);
308 else if (type == ArrayBufferView::TypeFloat32)
309 append(FloatArrayTag);
310 else if (type == ArrayBufferView::TypeFloat64)
311 append(DoubleArrayTag);
312 else if (type == ArrayBufferView::TypeDataView)
313 append(DataViewTag);
314 else
315 ASSERT_NOT_REACHED();
316 doWriteUint32(arrayBufferView.byteOffset());
317 doWriteUint32(arrayBufferView.byteLength());
318 }
319
320 void Writer::writeImageData(uint32_t width, uint32_t height, const uint8_t* pixe lData, uint32_t pixelDataLength)
321 {
322 append(ImageDataTag);
323 doWriteUint32(width);
324 doWriteUint32(height);
325 doWriteUint32(pixelDataLength);
326 append(pixelData, pixelDataLength);
327 }
328
329 void Writer::writeRegExp(v8::Local<v8::String> pattern, v8::RegExp::Flags flags)
330 {
331 append(RegExpTag);
332 v8::String::Utf8Value patternUtf8Value(pattern);
333 doWriteString(*patternUtf8Value, patternUtf8Value.length());
334 doWriteUint32(static_cast<uint32_t>(flags));
335 }
336
337 void Writer::writeTransferredMessagePort(uint32_t index)
338 {
339 append(MessagePortTag);
340 doWriteUint32(index);
341 }
342
343 void Writer::writeTransferredArrayBuffer(uint32_t index)
344 {
345 append(ArrayBufferTransferTag);
346 doWriteUint32(index);
347 }
348
349 void Writer::writeObjectReference(uint32_t reference)
350 {
351 append(ObjectReferenceTag);
352 doWriteUint32(reference);
353 }
354
355 void Writer::writeObject(uint32_t numProperties)
356 {
357 append(ObjectTag);
358 doWriteUint32(numProperties);
359 }
360
361 void Writer::writeSparseArray(uint32_t numProperties, uint32_t length)
362 {
363 append(SparseArrayTag);
364 doWriteUint32(numProperties);
365 doWriteUint32(length);
366 }
367
368 void Writer::writeDenseArray(uint32_t numProperties, uint32_t length)
369 {
370 append(DenseArrayTag);
371 doWriteUint32(numProperties);
372 doWriteUint32(length);
373 }
374
375 String Writer::takeWireString()
376 {
377 COMPILE_ASSERT(sizeof(BufferValueType) == 2, BufferValueTypeIsTwoBytes);
378 fillHole();
379 String data = String(m_buffer.data(), m_buffer.size());
380 data.impl()->truncateAssumingIsolated((m_position + 1) / sizeof(BufferValueT ype));
381 return data;
382 }
383
384 void Writer::writeReferenceCount(uint32_t numberOfReferences)
385 {
386 append(ReferenceCountTag);
387 doWriteUint32(numberOfReferences);
388 }
389
390 void Writer::writeGenerateFreshObject()
391 {
392 append(GenerateFreshObjectTag);
393 }
394
395 void Writer::writeGenerateFreshSparseArray(uint32_t length)
396 {
397 append(GenerateFreshSparseArrayTag);
398 doWriteUint32(length);
399 }
400
401 void Writer::writeGenerateFreshDenseArray(uint32_t length)
402 {
403 append(GenerateFreshDenseArrayTag);
404 doWriteUint32(length);
405 }
406
407 void Writer::doWriteFile(const File& file)
408 {
409 doWriteWebCoreString(file.hasBackingFile() ? file.path() : "");
410 doWriteWebCoreString(file.name());
411 doWriteWebCoreString(file.webkitRelativePath());
412 doWriteWebCoreString(file.uuid());
413 doWriteWebCoreString(file.type());
414
415 // FIXME don't use 1 byte to encode a flag.
416 if (file.hasValidSnapshotMetadata()) {
417 doWriteUint32(static_cast<uint8_t>(1));
418
419 long long size;
420 double lastModified;
421 file.captureSnapshot(size, lastModified);
422 doWriteUint64(static_cast<uint64_t>(size));
423 doWriteNumber(lastModified);
424 } else {
425 doWriteUint32(static_cast<uint8_t>(0));
426 }
427
428 doWriteUint32(static_cast<uint8_t>((file.userVisibility() == File::IsUserVis ible) ? 1 : 0));
429 }
430
431 void Writer::doWriteArrayBuffer(const ArrayBuffer& arrayBuffer)
432 {
433 uint32_t byteLength = arrayBuffer.byteLength();
434 doWriteUint32(byteLength);
435 append(static_cast<const uint8_t*>(arrayBuffer.data()), byteLength);
436 }
437
438 void Writer::doWriteString(const char* data, int length)
439 {
440 doWriteUint32(static_cast<uint32_t>(length));
441 append(reinterpret_cast<const uint8_t*>(data), length);
442 }
443
444 void Writer::doWriteWebCoreString(const String& string)
445 {
446 StringUTF8Adaptor stringUTF8(string);
447 doWriteString(stringUTF8.data(), stringUTF8.length());
448 }
449
450 void Writer::doWriteHmacKey(const WebCryptoKey& key)
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 {
589 int bytes = 1;
590 while (true) {
591 value >>= SerializedScriptValue::varIntShift;
592 if (!value)
593 break;
594 ++bytes;
595 }
596
597 return bytes;
598 }
599
600 void Writer::doWriteUint32(uint32_t value)
601 {
602 doWriteUintHelper(value);
603 }
604
605 void Writer::doWriteUint64(uint64_t value)
606 {
607 doWriteUintHelper(value);
608 }
609
610 void Writer::doWriteNumber(double number)
611 {
612 append(reinterpret_cast<uint8_t*>(&number), sizeof(number));
613 }
614
615 void Writer::append(SerializationTag tag)
616 {
617 append(static_cast<uint8_t>(tag));
618 }
619
620 void Writer::append(uint8_t b)
621 {
622 ensureSpace(1);
623 *byteAt(m_position++) = b;
624 }
625
626 void Writer::append(const uint8_t* data, int length)
627 {
628 ensureSpace(length);
629 memcpy(byteAt(m_position), data, length);
630 m_position += length;
631 }
632
633 void Writer::ensureSpace(unsigned extra)
634 {
635 COMPILE_ASSERT(sizeof(BufferValueType) == 2, BufferValueTypeIsTwoBytes);
636 m_buffer.resize((m_position + extra + 1) / sizeof(BufferValueType)); // "+ 1 " to round up.
637 }
638
639 void Writer::fillHole()
640 {
641 COMPILE_ASSERT(sizeof(BufferValueType) == 2, BufferValueTypeIsTwoBytes);
642 // If the writer is at odd position in the buffer, then one of
643 // the bytes in the last UChar is not initialized.
644 if (m_position % 2)
645 *byteAt(m_position) = static_cast<uint8_t>(PaddingTag);
646 }
647
648 uint8_t* Writer::byteAt(int position)
649 {
650 return reinterpret_cast<uint8_t*>(m_buffer.data()) + position;
651 }
652
653 int Writer::v8StringWriteOptions()
654 {
655 return v8::String::NO_NULL_TERMINATION;
656 }
657
658 Serializer::StateBase* Serializer::AbstractObjectState::serializeProperties(bool ignoreIndexed, Serializer& serializer)
659 {
660 while (m_index < m_propertyNames->Length()) {
661 if (!m_nameDone) {
662 v8::Local<v8::Value> propertyName = m_propertyNames->Get(m_index);
663 if (StateBase* newState = serializer.checkException(this))
664 return newState;
665 if (propertyName.IsEmpty())
666 return serializer.handleError(InputError, "Empty property names cannot be cloned.", this);
667 bool hasStringProperty = propertyName->IsString() && composite()->Ha sRealNamedProperty(propertyName.As<v8::String>());
668 if (StateBase* newState = serializer.checkException(this))
669 return newState;
670 bool hasIndexedProperty = !hasStringProperty && propertyName->IsUint 32() && composite()->HasRealIndexedProperty(propertyName->Uint32Value());
671 if (StateBase* newState = serializer.checkException(this))
672 return newState;
673 if (hasStringProperty || (hasIndexedProperty && !ignoreIndexed)) {
674 m_propertyName = propertyName;
675 } else {
676 ++m_index;
677 continue;
678 }
679 }
680 ASSERT(!m_propertyName.IsEmpty());
681 if (!m_nameDone) {
682 m_nameDone = true;
683 if (StateBase* newState = serializer.doSerialize(m_propertyName, thi s))
684 return newState;
685 }
686 v8::Local<v8::Value> value = composite()->Get(m_propertyName);
687 if (StateBase* newState = serializer.checkException(this))
688 return newState;
689 m_nameDone = false;
690 m_propertyName.Clear();
691 ++m_index;
692 ++m_numSerializedProperties;
693 // 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
695 // we are unwinding the native stack).
696 if (StateBase* newState = serializer.doSerialize(value, this))
697 return newState;
698 }
699 return objectDone(m_numSerializedProperties, serializer);
700 }
701
702 Serializer::StateBase* Serializer::ObjectState::advance(Serializer& serializer)
703 {
704 if (m_propertyNames.IsEmpty()) {
705 m_propertyNames = composite()->GetPropertyNames();
706 if (StateBase* newState = serializer.checkException(this))
707 return newState;
708 if (m_propertyNames.IsEmpty())
709 return serializer.handleError(InputError, "Empty property names cann ot be cloned.", nextState());
710 }
711 return serializeProperties(false, serializer);
712 }
713
714 Serializer::StateBase* Serializer::ObjectState::objectDone(unsigned numPropertie s, Serializer& serializer)
715 {
716 return serializer.writeObject(numProperties, this);
717 }
718
719 Serializer::StateBase* Serializer::DenseArrayState::advance(Serializer& serializ er)
720 {
721 while (m_arrayIndex < m_arrayLength) {
722 v8::Handle<v8::Value> value = composite().As<v8::Array>()->Get(m_arrayIn dex);
723 m_arrayIndex++;
724 if (StateBase* newState = serializer.checkException(this))
725 return newState;
726 if (StateBase* newState = serializer.doSerialize(value, this))
727 return newState;
728 }
729 return serializeProperties(true, serializer);
730 }
731
732 Serializer::StateBase* Serializer::DenseArrayState::objectDone(unsigned numPrope rties, Serializer& serializer)
733 {
734 return serializer.writeDenseArray(numProperties, m_arrayLength, this);
735 }
736
737 Serializer::StateBase* Serializer::SparseArrayState::advance(Serializer& seriali zer)
738 {
739 return serializeProperties(false, serializer);
740 }
741
742 Serializer::StateBase* Serializer::SparseArrayState::objectDone(unsigned numProp erties, Serializer& serializer)
743 {
744 return serializer.writeSparseArray(numProperties, composite().As<v8::Array>( )->Length(), this);
745 }
746
747 static v8::Handle<v8::Object> toV8Object(MessagePort* impl, v8::Handle<v8::Objec t> creationContext, v8::Isolate* isolate)
748 {
749 if (!impl)
750 return v8::Handle<v8::Object>();
751 v8::Handle<v8::Value> wrapper = toV8(impl, creationContext, isolate);
752 ASSERT(wrapper->IsObject());
753 return wrapper.As<v8::Object>();
754 }
755
756 static v8::Handle<v8::ArrayBuffer> toV8Object(DOMArrayBuffer* impl, v8::Handle<v 8::Object> creationContext, v8::Isolate* isolate)
757 {
758 if (!impl)
759 return v8::Handle<v8::ArrayBuffer>();
760 v8::Handle<v8::Value> wrapper = toV8(impl, creationContext, isolate);
761 ASSERT(wrapper->IsArrayBuffer());
762 return wrapper.As<v8::ArrayBuffer>();
763 }
764
765 // Returns true if the provided object is to be considered a 'host object', as u sed in the
766 // HTML5 structured clone algorithm.
767 static bool isHostObject(v8::Handle<v8::Object> object)
768 {
769 // 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
771 // the mechanism for these relies on data stored in these fields. We should
772 // catch external array data as a special case.
773 return object->InternalFieldCount() || object->HasIndexedPropertiesInExterna lArrayData();
774 }
775
776 Serializer::Serializer(Writer& writer, MessagePortArray* messagePorts, ArrayBuff erArray* arrayBuffers, WebBlobInfoArray* blobInfo, BlobDataHandleMap& blobDataHa ndles, v8::TryCatch& tryCatch, ScriptState* scriptState)
777 : m_scriptState(scriptState)
778 , m_writer(writer)
779 , m_tryCatch(tryCatch)
780 , m_depth(0)
781 , m_status(Success)
782 , m_nextObjectReference(0)
783 , m_blobInfo(blobInfo)
784 , m_blobDataHandles(blobDataHandles)
785 {
786 ASSERT(!tryCatch.HasCaught());
787 v8::Handle<v8::Object> creationContext = m_scriptState->context()->Global();
788 if (messagePorts) {
789 for (size_t i = 0; i < messagePorts->size(); i++)
790 m_transferredMessagePorts.set(toV8Object(messagePorts->at(i).get(), creationContext, isolate()), i);
791 }
792 if (arrayBuffers) {
793 for (size_t i = 0; i < arrayBuffers->size(); i++) {
794 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.
796 if (!m_transferredArrayBuffers.contains(v8ArrayBuffer))
797 m_transferredArrayBuffers.set(v8ArrayBuffer, i);
798 }
799 }
800 }
801
802 Serializer::Status Serializer::serialize(v8::Handle<v8::Value> value)
803 {
804 v8::HandleScope scope(isolate());
805 m_writer.writeVersion();
806 StateBase* state = doSerialize(value, 0);
807 while (state)
808 state = state->advance(*this);
809 return m_status;
810 }
811
812 Serializer::StateBase* Serializer::doSerialize(v8::Handle<v8::Value> value, Seri alizer::StateBase* next)
813 {
814 m_writer.writeReferenceCount(m_nextObjectReference);
815 uint32_t objectReference;
816 uint32_t arrayBufferIndex;
817 if ((value->IsObject() || value->IsDate() || value->IsRegExp())
818 && m_objectPool.tryGet(value.As<v8::Object>(), &objectReference)) {
819 // Note that IsObject() also detects wrappers (eg, it will catch the thi ngs
820 // that we grey and write below).
821 ASSERT(!value->IsString());
822 m_writer.writeObjectReference(objectReference);
823 } else if (value.IsEmpty()) {
824 return handleError(InputError, "The empty property name cannot be cloned .", next);
825 } else if (value->IsUndefined()) {
826 m_writer.writeUndefined();
827 } else if (value->IsNull()) {
828 m_writer.writeNull();
829 } else if (value->IsTrue()) {
830 m_writer.writeTrue();
831 } else if (value->IsFalse()) {
832 m_writer.writeFalse();
833 } else if (value->IsInt32()) {
834 m_writer.writeInt32(value->Int32Value());
835 } else if (value->IsUint32()) {
836 m_writer.writeUint32(value->Uint32Value());
837 } else if (value->IsNumber()) {
838 m_writer.writeNumber(value.As<v8::Number>()->Value());
839 } else if (V8ArrayBufferView::hasInstance(value, isolate())) {
840 return writeAndGreyArrayBufferView(value.As<v8::Object>(), next);
841 } else if (value->IsString()) {
842 writeString(value);
843 } else if (V8MessagePort::hasInstance(value, isolate())) {
844 uint32_t messagePortIndex;
845 if (m_transferredMessagePorts.tryGet(value.As<v8::Object>(), &messagePor tIndex)) {
846 m_writer.writeTransferredMessagePort(messagePortIndex);
847 } else {
848 return handleError(DataCloneError, "A MessagePort could not be clone d.", next);
849 }
850 } else if (V8ArrayBuffer::hasInstance(value, isolate()) && m_transferredArra yBuffers.tryGet(value.As<v8::Object>(), &arrayBufferIndex)) {
851 return writeTransferredArrayBuffer(value, arrayBufferIndex, next);
852 } else {
853 v8::Handle<v8::Object> jsObject = value.As<v8::Object>();
854 if (jsObject.IsEmpty())
855 return handleError(DataCloneError, "An object could not be cloned.", next);
856 greyObject(jsObject);
857 if (value->IsDate()) {
858 m_writer.writeDate(value->NumberValue());
859 } else if (value->IsStringObject()) {
860 writeStringObject(value);
861 } else if (value->IsNumberObject()) {
862 writeNumberObject(value);
863 } else if (value->IsBooleanObject()) {
864 writeBooleanObject(value);
865 } else if (value->IsArray()) {
866 return startArrayState(value.As<v8::Array>(), next);
867 } else if (V8File::hasInstance(value, isolate())) {
868 return writeFile(value, next);
869 } else if (V8Blob::hasInstance(value, isolate())) {
870 return writeBlob(value, next);
871 } else if (V8DOMFileSystem::hasInstance(value, isolate())) {
872 return writeDOMFileSystem(value, next);
873 } else if (V8FileList::hasInstance(value, isolate())) {
874 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())) {
879 writeImageData(value);
880 } else if (value->IsRegExp()) {
881 writeRegExp(value);
882 } else if (V8ArrayBuffer::hasInstance(value, isolate())) {
883 return writeArrayBuffer(value, next);
884 } else if (value->IsObject()) {
885 if (isHostObject(jsObject) || jsObject->IsCallable() || value->IsNat iveError())
886 return handleError(DataCloneError, "An object could not be clone d.", next);
887 return startObjectState(jsObject, next);
888 } else {
889 return handleError(DataCloneError, "A value could not be cloned.", n ext);
890 }
891 }
892 return 0;
893 }
894
895 Serializer::StateBase* Serializer::doSerializeArrayBuffer(v8::Handle<v8::Value> arrayBuffer, Serializer::StateBase* next)
896 {
897 return doSerialize(arrayBuffer, next);
898 }
899
900 Serializer::StateBase* Serializer::checkException(Serializer::StateBase* state)
901 {
902 return m_tryCatch.HasCaught() ? handleError(JSException, "", state) : 0;
903 }
904
905 Serializer::StateBase* Serializer::writeObject(uint32_t numProperties, Serialize r::StateBase* state)
906 {
907 m_writer.writeObject(numProperties);
908 return pop(state);
909 }
910
911 Serializer::StateBase* Serializer::writeSparseArray(uint32_t numProperties, uint 32_t length, Serializer::StateBase* state)
912 {
913 m_writer.writeSparseArray(numProperties, length);
914 return pop(state);
915 }
916
917 Serializer::StateBase* Serializer::writeDenseArray(uint32_t numProperties, uint3 2_t length, Serializer::StateBase* state)
918 {
919 m_writer.writeDenseArray(numProperties, length);
920 return pop(state);
921 }
922
923 Serializer::StateBase* Serializer::handleError(Serializer::Status errorStatus, c onst String& message, Serializer::StateBase* state)
924 {
925 ASSERT(errorStatus != Success);
926 m_status = errorStatus;
927 m_errorMessage = message;
928 while (state) {
929 StateBase* tmp = state->nextState();
930 delete state;
931 state = tmp;
932 }
933 return new ErrorState;
934 }
935
936 bool Serializer::checkComposite(Serializer::StateBase* top)
937 {
938 ASSERT(top);
939 if (m_depth > maxDepth)
940 return false;
941 if (!shouldCheckForCycles(m_depth))
942 return true;
943 v8::Handle<v8::Value> composite = top->composite();
944 for (StateBase* state = top->nextState(); state; state = state->nextState()) {
945 if (state->composite() == composite)
946 return false;
947 }
948 return true;
949 }
950
951 void Serializer::writeString(v8::Handle<v8::Value> value)
952 {
953 v8::Handle<v8::String> string = value.As<v8::String>();
954 if (!string->Length() || string->IsOneByte())
955 m_writer.writeOneByteString(string);
956 else
957 m_writer.writeUCharString(string);
958 }
959
960 void Serializer::writeStringObject(v8::Handle<v8::Value> value)
961 {
962 v8::Handle<v8::StringObject> stringObject = value.As<v8::StringObject>();
963 v8::String::Utf8Value stringValue(stringObject->ValueOf());
964 m_writer.writeStringObject(*stringValue, stringValue.length());
965 }
966
967 void Serializer::writeNumberObject(v8::Handle<v8::Value> value)
968 {
969 v8::Handle<v8::NumberObject> numberObject = value.As<v8::NumberObject>();
970 m_writer.writeNumberObject(numberObject->ValueOf());
971 }
972
973 void Serializer::writeBooleanObject(v8::Handle<v8::Value> value)
974 {
975 v8::Handle<v8::BooleanObject> booleanObject = value.As<v8::BooleanObject>();
976 m_writer.writeBooleanObject(booleanObject->ValueOf());
977 }
978
979 Serializer::StateBase* Serializer::writeBlob(v8::Handle<v8::Value> value, Serial izer::StateBase* next)
980 {
981 Blob* blob = V8Blob::toImpl(value.As<v8::Object>());
982 if (!blob)
983 return 0;
984 if (blob->hasBeenClosed())
985 return handleError(DataCloneError, "A Blob object has been closed, and c ould therefore not be cloned.", next);
986 int blobIndex = -1;
987 m_blobDataHandles.set(blob->uuid(), blob->blobDataHandle());
988 if (appendBlobInfo(blob->uuid(), blob->type(), blob->size(), &blobIndex))
989 m_writer.writeBlobIndex(blobIndex);
990 else
991 m_writer.writeBlob(blob->uuid(), blob->type(), blob->size());
992 return 0;
993 }
994
995 Serializer::StateBase* Serializer::writeDOMFileSystem(v8::Handle<v8::Value> valu e, 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 {
1008 File* file = V8File::toImpl(value.As<v8::Object>());
1009 if (!file)
1010 return 0;
1011 if (file->hasBeenClosed())
1012 return handleError(DataCloneError, "A File object has been closed, and c ould therefore not be cloned.", next);
1013 int blobIndex = -1;
1014 m_blobDataHandles.set(file->uuid(), file->blobDataHandle());
1015 if (appendFileInfo(file, &blobIndex)) {
1016 ASSERT(blobIndex >= 0);
1017 m_writer.writeFileIndex(blobIndex);
1018 } else {
1019 m_writer.writeFile(*file);
1020 }
1021 return 0;
1022 }
1023
1024 Serializer::StateBase* Serializer::writeFileList(v8::Handle<v8::Value> value, Se rializer::StateBase* next)
1025 {
1026 FileList* fileList = V8FileList::toImpl(value.As<v8::Object>());
1027 if (!fileList)
1028 return 0;
1029 unsigned length = fileList->length();
1030 Vector<int> blobIndices;
1031 for (unsigned i = 0; i < length; ++i) {
1032 int blobIndex = -1;
1033 const File* file = fileList->item(i);
1034 if (file->hasBeenClosed())
1035 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());
1037 if (appendFileInfo(file, &blobIndex)) {
1038 ASSERT(!i || blobIndex > 0);
1039 ASSERT(blobIndex >= 0);
1040 blobIndices.append(blobIndex);
1041 }
1042 }
1043 if (!blobIndices.isEmpty())
1044 m_writer.writeFileListIndex(blobIndices);
1045 else
1046 m_writer.writeFileList(*fileList);
1047 return 0;
1048 }
1049
1050 bool Serializer::writeCryptoKey(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 {
1060 ImageData* imageData = V8ImageData::toImpl(value.As<v8::Object>());
1061 if (!imageData)
1062 return;
1063 Uint8ClampedArray* pixelArray = imageData->data();
1064 m_writer.writeImageData(imageData->width(), imageData->height(), pixelArray- >data(), pixelArray->length());
1065 }
1066
1067 void Serializer::writeRegExp(v8::Handle<v8::Value> value)
1068 {
1069 v8::Handle<v8::RegExp> regExp = value.As<v8::RegExp>();
1070 m_writer.writeRegExp(regExp->GetSource(), regExp->GetFlags());
1071 }
1072
1073 Serializer::StateBase* Serializer::writeAndGreyArrayBufferView(v8::Handle<v8::Ob ject> object, Serializer::StateBase* next)
1074 {
1075 ASSERT(!object.IsEmpty());
1076 DOMArrayBufferView* arrayBufferView = V8ArrayBufferView::toImpl(object);
1077 if (!arrayBufferView)
1078 return 0;
1079 if (!arrayBufferView->buffer())
1080 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());
1082 if (underlyingBuffer.IsEmpty())
1083 return handleError(DataCloneError, "An ArrayBuffer could not be cloned." , next);
1084 StateBase* stateOut = doSerializeArrayBuffer(underlyingBuffer, next);
1085 if (stateOut)
1086 return stateOut;
1087 m_writer.writeArrayBufferView(*arrayBufferView->view());
1088 // 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
1090 // cause the system stack to overflow nor should it have potential to reach
1091 // this ArrayBufferView again.
1092 //
1093 // 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
1095 // ArrayBufferView cannot be constructed without a corresponding ArrayBuffer
1096 // (or without an additional tag that would allow us to do two-stage constru ction
1097 // like we do for Objects and Arrays).
1098 greyObject(object);
1099 return 0;
1100 }
1101
1102 Serializer::StateBase* Serializer::writeArrayBuffer(v8::Handle<v8::Value> value, Serializer::StateBase* next)
1103 {
1104 DOMArrayBuffer* arrayBuffer = V8ArrayBuffer::toImpl(value.As<v8::Object>());
1105 if (!arrayBuffer)
1106 return 0;
1107 if (arrayBuffer->isNeutered())
1108 return handleError(DataCloneError, "An ArrayBuffer is neutered and could not be cloned.", next);
1109 ASSERT(!m_transferredArrayBuffers.contains(value.As<v8::Object>()));
1110 m_writer.writeArrayBuffer(*arrayBuffer->buffer());
1111 return 0;
1112 }
1113
1114 Serializer::StateBase* Serializer::writeTransferredArrayBuffer(v8::Handle<v8::Va lue> value, uint32_t index, Serializer::StateBase* next)
1115 {
1116 DOMArrayBuffer* arrayBuffer = V8ArrayBuffer::toImpl(value.As<v8::Object>());
1117 if (!arrayBuffer)
1118 return 0;
1119 if (arrayBuffer->isNeutered())
1120 return handleError(DataCloneError, "An ArrayBuffer is neutered and could not be cloned.", next);
1121 m_writer.writeTransferredArrayBuffer(index);
1122 return 0;
1123 }
1124
1125 bool Serializer::shouldSerializeDensely(uint32_t length, uint32_t propertyCount)
1126 {
1127 // 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)
1129 // 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
1131 return 6 * propertyCount >= length;
1132 }
1133
1134 Serializer::StateBase* Serializer::startArrayState(v8::Handle<v8::Array> array, Serializer::StateBase* next)
1135 {
1136 v8::Handle<v8::Array> propertyNames = array->GetPropertyNames();
1137 if (StateBase* newState = checkException(next))
1138 return newState;
1139 uint32_t length = array->Length();
1140
1141 if (shouldSerializeDensely(length, propertyNames->Length())) {
1142 m_writer.writeGenerateFreshDenseArray(length);
1143 return push(new DenseArrayState(array, propertyNames, next, isolate()));
1144 }
1145
1146 m_writer.writeGenerateFreshSparseArray(length);
1147 return push(new SparseArrayState(array, propertyNames, next, isolate()));
1148 }
1149
1150 Serializer::StateBase* Serializer::startObjectState(v8::Handle<v8::Object> objec t, Serializer::StateBase* next)
1151 {
1152 m_writer.writeGenerateFreshObject();
1153 // FIXME: check not a wrapper
1154 return push(new ObjectState(object, next));
1155 }
1156
1157 // 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.
1159 void Serializer::greyObject(const v8::Handle<v8::Object>& object)
1160 {
1161 ASSERT(!m_objectPool.contains(object));
1162 uint32_t objectReference = m_nextObjectReference++;
1163 m_objectPool.set(object, objectReference);
1164 }
1165
1166 bool Serializer::appendBlobInfo(const String& uuid, const String& type, unsigned long long size, int* index)
1167 {
1168 if (!m_blobInfo)
1169 return false;
1170 *index = m_blobInfo->size();
1171 m_blobInfo->append(WebBlobInfo(uuid, type, size));
1172 return true;
1173 }
1174
1175 bool Serializer::appendFileInfo(const File* file, int* index)
1176 {
1177 if (!m_blobInfo)
1178 return false;
1179
1180 long long size = -1;
1181 double lastModified = invalidFileTime();
1182 file->captureSnapshot(size, lastModified);
1183 *index = m_blobInfo->size();
1184 m_blobInfo->append(WebBlobInfo(file->uuid(), file->path(), file->name(), fil e->type(), lastModified, size));
1185 return true;
1186 }
1187
1188 bool Reader::read(v8::Handle<v8::Value>* value, CompositeCreator& creator)
1189 {
1190 SerializationTag tag;
1191 if (!readTag(&tag))
1192 return false;
1193 switch (tag) {
1194 case ReferenceCountTag: {
1195 if (!m_version)
1196 return false;
1197 uint32_t referenceTableSize;
1198 if (!doReadUint32(&referenceTableSize))
1199 return false;
1200 // 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
1202 // calls to pushObjectReference.
1203 if (referenceTableSize != creator.objectReferenceCount())
1204 return false;
1205 return true;
1206 }
1207 case InvalidTag:
1208 return false;
1209 case PaddingTag:
1210 return true;
1211 case UndefinedTag:
1212 *value = v8::Undefined(isolate());
1213 break;
1214 case NullTag:
1215 *value = v8::Null(isolate());
1216 break;
1217 case TrueTag:
1218 *value = v8Boolean(true, isolate());
1219 break;
1220 case FalseTag:
1221 *value = v8Boolean(false, isolate());
1222 break;
1223 case TrueObjectTag:
1224 *value = v8::BooleanObject::New(true);
1225 creator.pushObjectReference(*value);
1226 break;
1227 case FalseObjectTag:
1228 *value = v8::BooleanObject::New(false);
1229 creator.pushObjectReference(*value);
1230 break;
1231 case StringTag:
1232 if (!readString(value))
1233 return false;
1234 break;
1235 case StringUCharTag:
1236 if (!readUCharString(value))
1237 return false;
1238 break;
1239 case StringObjectTag:
1240 if (!readStringObject(value))
1241 return false;
1242 creator.pushObjectReference(*value);
1243 break;
1244 case Int32Tag:
1245 if (!readInt32(value))
1246 return false;
1247 break;
1248 case Uint32Tag:
1249 if (!readUint32(value))
1250 return false;
1251 break;
1252 case DateTag:
1253 if (!readDate(value))
1254 return false;
1255 creator.pushObjectReference(*value);
1256 break;
1257 case NumberTag:
1258 if (!readNumber(value))
1259 return false;
1260 break;
1261 case NumberObjectTag:
1262 if (!readNumberObject(value))
1263 return false;
1264 creator.pushObjectReference(*value);
1265 break;
1266 case BlobTag:
1267 case BlobIndexTag:
1268 if (!readBlob(value, tag == BlobIndexTag))
1269 return false;
1270 creator.pushObjectReference(*value);
1271 break;
1272 case FileTag:
1273 case FileIndexTag:
1274 if (!readFile(value, tag == FileIndexTag))
1275 return false;
1276 creator.pushObjectReference(*value);
1277 break;
1278 case DOMFileSystemTag:
1279 if (!readDOMFileSystem(value))
1280 return false;
1281 creator.pushObjectReference(*value);
1282 break;
1283 case FileListTag:
1284 case FileListIndexTag:
1285 if (!readFileList(value, tag == FileListIndexTag))
1286 return false;
1287 creator.pushObjectReference(*value);
1288 break;
1289 case CryptoKeyTag:
1290 if (!readCryptoKey(value))
1291 return false;
1292 creator.pushObjectReference(*value);
1293 break;
1294 case ImageDataTag:
1295 if (!readImageData(value))
1296 return false;
1297 creator.pushObjectReference(*value);
1298 break;
1299
1300 case RegExpTag:
1301 if (!readRegExp(value))
1302 return false;
1303 creator.pushObjectReference(*value);
1304 break;
1305 case ObjectTag: {
1306 uint32_t numProperties;
1307 if (!doReadUint32(&numProperties))
1308 return false;
1309 if (!creator.completeObject(numProperties, value))
1310 return false;
1311 break;
1312 }
1313 case SparseArrayTag: {
1314 uint32_t numProperties;
1315 uint32_t length;
1316 if (!doReadUint32(&numProperties))
1317 return false;
1318 if (!doReadUint32(&length))
1319 return false;
1320 if (!creator.completeSparseArray(numProperties, length, value))
1321 return false;
1322 break;
1323 }
1324 case DenseArrayTag: {
1325 uint32_t numProperties;
1326 uint32_t length;
1327 if (!doReadUint32(&numProperties))
1328 return false;
1329 if (!doReadUint32(&length))
1330 return false;
1331 if (!creator.completeDenseArray(numProperties, length, value))
1332 return false;
1333 break;
1334 }
1335 case ArrayBufferViewTag: {
1336 if (!m_version)
1337 return false;
1338 if (!readArrayBufferView(value, creator))
1339 return false;
1340 creator.pushObjectReference(*value);
1341 break;
1342 }
1343 case ArrayBufferTag: {
1344 if (!m_version)
1345 return false;
1346 if (!readArrayBuffer(value))
1347 return false;
1348 creator.pushObjectReference(*value);
1349 break;
1350 }
1351 case GenerateFreshObjectTag: {
1352 if (!m_version)
1353 return false;
1354 if (!creator.newObject())
1355 return false;
1356 return true;
1357 }
1358 case GenerateFreshSparseArrayTag: {
1359 if (!m_version)
1360 return false;
1361 uint32_t length;
1362 if (!doReadUint32(&length))
1363 return false;
1364 if (!creator.newSparseArray(length))
1365 return false;
1366 return true;
1367 }
1368 case GenerateFreshDenseArrayTag: {
1369 if (!m_version)
1370 return false;
1371 uint32_t length;
1372 if (!doReadUint32(&length))
1373 return false;
1374 if (!creator.newDenseArray(length))
1375 return false;
1376 return true;
1377 }
1378 case MessagePortTag: {
1379 if (!m_version)
1380 return false;
1381 uint32_t index;
1382 if (!doReadUint32(&index))
1383 return false;
1384 if (!creator.tryGetTransferredMessagePort(index, value))
1385 return false;
1386 break;
1387 }
1388 case ArrayBufferTransferTag: {
1389 if (!m_version)
1390 return false;
1391 uint32_t index;
1392 if (!doReadUint32(&index))
1393 return false;
1394 if (!creator.tryGetTransferredArrayBuffer(index, value))
1395 return false;
1396 break;
1397 }
1398 case ObjectReferenceTag: {
1399 if (!m_version)
1400 return false;
1401 uint32_t reference;
1402 if (!doReadUint32(&reference))
1403 return false;
1404 if (!creator.tryGetObjectFromObjectReference(reference, value))
1405 return false;
1406 break;
1407 }
1408 default:
1409 return false;
1410 }
1411 return !value->IsEmpty();
1412 }
1413
1414 bool Reader::readVersion(uint32_t& version)
1415 {
1416 SerializationTag tag;
1417 if (!readTag(&tag)) {
1418 // This is a nullary buffer. We're still version 0.
1419 version = 0;
1420 return true;
1421 }
1422 if (tag != VersionTag) {
1423 // Versions of the format past 0 start with the version tag.
1424 version = 0;
1425 // Put back the tag.
1426 undoReadTag();
1427 return true;
1428 }
1429 // Version-bearing messages are obligated to finish the version tag.
1430 return doReadUint32(&version);
1431 }
1432
1433 void Reader::setVersion(uint32_t version)
1434 {
1435 m_version = version;
1436 }
1437
1438 bool Reader::readTag(SerializationTag* tag)
1439 {
1440 if (m_position >= m_length)
1441 return false;
1442 *tag = static_cast<SerializationTag>(m_buffer[m_position++]);
1443 return true;
1444 }
1445
1446 void Reader::undoReadTag()
1447 {
1448 if (m_position > 0)
1449 --m_position;
1450 }
1451
1452 bool Reader::readArrayBufferViewSubTag(ArrayBufferViewSubTag* tag)
1453 {
1454 if (m_position >= m_length)
1455 return false;
1456 *tag = static_cast<ArrayBufferViewSubTag>(m_buffer[m_position++]);
1457 return true;
1458 }
1459
1460 bool Reader::readString(v8::Handle<v8::Value>* value)
1461 {
1462 uint32_t length;
1463 if (!doReadUint32(&length))
1464 return false;
1465 if (m_position + length > m_length)
1466 return false;
1467 *value = v8::String::NewFromUtf8(isolate(), reinterpret_cast<const char*>(m_ buffer + m_position), v8::String::kNormalString, length);
1468 m_position += length;
1469 return true;
1470 }
1471
1472 bool Reader::readUCharString(v8::Handle<v8::Value>* value)
1473 {
1474 uint32_t length;
1475 if (!doReadUint32(&length) || (length & 1))
1476 return false;
1477 if (m_position + length > m_length)
1478 return false;
1479 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));
1481 m_position += length;
1482 return true;
1483 }
1484
1485 bool Reader::readStringObject(v8::Handle<v8::Value>* value)
1486 {
1487 v8::Handle<v8::Value> stringValue;
1488 if (!readString(&stringValue) || !stringValue->IsString())
1489 return false;
1490 *value = v8::StringObject::New(stringValue.As<v8::String>());
1491 return true;
1492 }
1493
1494 bool Reader::readWebCoreString(String* string)
1495 {
1496 uint32_t length;
1497 if (!doReadUint32(&length))
1498 return false;
1499 if (m_position + length > m_length)
1500 return false;
1501 *string = String::fromUTF8(reinterpret_cast<const char*>(m_buffer + m_positi on), length);
1502 m_position += length;
1503 return true;
1504 }
1505
1506 bool Reader::readInt32(v8::Handle<v8::Value>* value)
1507 {
1508 uint32_t rawValue;
1509 if (!doReadUint32(&rawValue))
1510 return false;
1511 *value = v8::Integer::New(isolate(), static_cast<int32_t>(ZigZag::decode(raw Value)));
1512 return true;
1513 }
1514
1515 bool Reader::readUint32(v8::Handle<v8::Value>* value)
1516 {
1517 uint32_t rawValue;
1518 if (!doReadUint32(&rawValue))
1519 return false;
1520 *value = v8::Integer::NewFromUnsigned(isolate(), rawValue);
1521 return true;
1522 }
1523
1524 bool Reader::readDate(v8::Handle<v8::Value>* value)
1525 {
1526 double numberValue;
1527 if (!doReadNumber(&numberValue))
1528 return false;
1529 *value = v8DateOrNaN(numberValue, isolate());
1530 return true;
1531 }
1532
1533 bool Reader::readNumber(v8::Handle<v8::Value>* value)
1534 {
1535 double number;
1536 if (!doReadNumber(&number))
1537 return false;
1538 *value = v8::Number::New(isolate(), number);
1539 return true;
1540 }
1541
1542 bool Reader::readNumberObject(v8::Handle<v8::Value>* value)
1543 {
1544 double number;
1545 if (!doReadNumber(&number))
1546 return false;
1547 *value = v8::NumberObject::New(isolate(), number);
1548 return true;
1549 }
1550
1551 bool Reader::readImageData(v8::Handle<v8::Value>* value)
1552 {
1553 uint32_t width;
1554 uint32_t height;
1555 uint32_t pixelDataLength;
1556 if (!doReadUint32(&width))
1557 return false;
1558 if (!doReadUint32(&height))
1559 return false;
1560 if (!doReadUint32(&pixelDataLength))
1561 return false;
1562 if (m_position + pixelDataLength > m_length)
1563 return false;
1564 RefPtrWillBeRawPtr<ImageData> imageData = ImageData::create(IntSize(width, h eight));
1565 Uint8ClampedArray* pixelArray = imageData->data();
1566 ASSERT(pixelArray);
1567 ASSERT(pixelArray->length() >= pixelDataLength);
1568 memcpy(pixelArray->data(), m_buffer + m_position, pixelDataLength);
1569 m_position += pixelDataLength;
1570 *value = toV8(imageData.release(), m_scriptState->context()->Global(), isola te());
1571 return true;
1572 }
1573
1574 PassRefPtr<ArrayBuffer> Reader::doReadArrayBuffer()
1575 {
1576 uint32_t byteLength;
1577 if (!doReadUint32(&byteLength))
1578 return nullptr;
1579 if (m_position + byteLength > m_length)
1580 return nullptr;
1581 const void* bufferStart = m_buffer + m_position;
1582 m_position += byteLength;
1583 return ArrayBuffer::create(bufferStart, byteLength);
1584 }
1585
1586 bool Reader::readArrayBuffer(v8::Handle<v8::Value>* value)
1587 {
1588 RefPtr<ArrayBuffer> arrayBuffer = doReadArrayBuffer();
1589 if (!arrayBuffer)
1590 return false;
1591 *value = toV8(DOMArrayBuffer::create(arrayBuffer.release()), m_scriptState-> context()->Global(), isolate());
1592 return true;
1593 }
1594
1595 bool Reader::readArrayBufferView(v8::Handle<v8::Value>* value, CompositeCreator& creator)
1596 {
1597 ArrayBufferViewSubTag subTag;
1598 uint32_t byteOffset;
1599 uint32_t byteLength;
1600 RefPtr<DOMArrayBuffer> arrayBuffer;
1601 v8::Handle<v8::Value> arrayBufferV8Value;
1602 if (!readArrayBufferViewSubTag(&subTag))
1603 return false;
1604 if (!doReadUint32(&byteOffset))
1605 return false;
1606 if (!doReadUint32(&byteLength))
1607 return false;
1608 if (!creator.consumeTopOfStack(&arrayBufferV8Value))
1609 return false;
1610 if (arrayBufferV8Value.IsEmpty())
1611 return false;
1612 arrayBuffer = V8ArrayBuffer::toImpl(arrayBufferV8Value.As<v8::Object>());
1613 if (!arrayBuffer)
1614 return false;
1615
1616 v8::Handle<v8::Object> creationContext = m_scriptState->context()->Global();
1617 switch (subTag) {
1618 case ByteArrayTag:
1619 *value = toV8(DOMInt8Array::create(arrayBuffer.release(), byteOffset, by teLength), creationContext, isolate());
1620 break;
1621 case UnsignedByteArrayTag:
1622 *value = toV8(DOMUint8Array::create(arrayBuffer.release(), byteOffset, b yteLength), creationContext, isolate());
1623 break;
1624 case UnsignedByteClampedArrayTag:
1625 *value = toV8(DOMUint8ClampedArray::create(arrayBuffer.release(), byteOf fset, byteLength), creationContext, isolate());
1626 break;
1627 case ShortArrayTag: {
1628 uint32_t shortLength = byteLength / sizeof(int16_t);
1629 if (shortLength * sizeof(int16_t) != byteLength)
1630 return false;
1631 *value = toV8(DOMInt16Array::create(arrayBuffer.release(), byteOffset, s hortLength), creationContext, isolate());
1632 break;
1633 }
1634 case UnsignedShortArrayTag: {
1635 uint32_t shortLength = byteLength / sizeof(uint16_t);
1636 if (shortLength * sizeof(uint16_t) != byteLength)
1637 return false;
1638 *value = toV8(DOMUint16Array::create(arrayBuffer.release(), byteOffset, shortLength), creationContext, isolate());
1639 break;
1640 }
1641 case IntArrayTag: {
1642 uint32_t intLength = byteLength / sizeof(int32_t);
1643 if (intLength * sizeof(int32_t) != byteLength)
1644 return false;
1645 *value = toV8(DOMInt32Array::create(arrayBuffer.release(), byteOffset, i ntLength), creationContext, isolate());
1646 break;
1647 }
1648 case UnsignedIntArrayTag: {
1649 uint32_t intLength = byteLength / sizeof(uint32_t);
1650 if (intLength * sizeof(uint32_t) != byteLength)
1651 return false;
1652 *value = toV8(DOMUint32Array::create(arrayBuffer.release(), byteOffset, intLength), creationContext, isolate());
1653 break;
1654 }
1655 case FloatArrayTag: {
1656 uint32_t floatLength = byteLength / sizeof(float);
1657 if (floatLength * sizeof(float) != byteLength)
1658 return false;
1659 *value = toV8(DOMFloat32Array::create(arrayBuffer.release(), byteOffset, floatLength), creationContext, isolate());
1660 break;
1661 }
1662 case DoubleArrayTag: {
1663 uint32_t floatLength = byteLength / sizeof(double);
1664 if (floatLength * sizeof(double) != byteLength)
1665 return false;
1666 *value = toV8(DOMFloat64Array::create(arrayBuffer.release(), byteOffset, floatLength), creationContext, isolate());
1667 break;
1668 }
1669 case DataViewTag:
1670 *value = toV8(DOMDataView::create(arrayBuffer.release(), byteOffset, byt eLength), creationContext, isolate());
1671 break;
1672 default:
1673 return false;
1674 }
1675 // 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
1677 // to the size of the element type.
1678 return !value->IsEmpty();
1679 }
1680
1681 bool Reader::readRegExp(v8::Handle<v8::Value>* value)
1682 {
1683 v8::Handle<v8::Value> pattern;
1684 if (!readString(&pattern))
1685 return false;
1686 uint32_t flags;
1687 if (!doReadUint32(&flags))
1688 return false;
1689 *value = v8::RegExp::New(pattern.As<v8::String>(), static_cast<v8::RegExp::F lags>(flags));
1690 return true;
1691 }
1692
1693 bool Reader::readBlob(v8::Handle<v8::Value>* value, bool isIndexed)
1694 {
1695 if (m_version < 3)
1696 return false;
1697 Blob* blob = nullptr;
1698 if (isIndexed) {
1699 if (m_version < 6)
1700 return false;
1701 ASSERT(m_blobInfo);
1702 uint32_t index;
1703 if (!doReadUint32(&index) || index >= m_blobInfo->size())
1704 return false;
1705 const WebBlobInfo& info = (*m_blobInfo)[index];
1706 blob = Blob::create(getOrCreateBlobDataHandle(info.uuid(), info.type(), info.size()));
1707 } else {
1708 ASSERT(!m_blobInfo);
1709 String uuid;
1710 String type;
1711 uint64_t size;
1712 ASSERT(!m_blobInfo);
1713 if (!readWebCoreString(&uuid))
1714 return false;
1715 if (!readWebCoreString(&type))
1716 return false;
1717 if (!doReadUint64(&size))
1718 return false;
1719 blob = Blob::create(getOrCreateBlobDataHandle(uuid, type, size));
1720 }
1721 *value = toV8(blob, m_scriptState->context()->Global(), isolate());
1722 return true;
1723 }
1724
1725 bool Reader::readDOMFileSystem(v8::Handle<v8::Value>* value)
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 {
1743 File* file = nullptr;
1744 if (isIndexed) {
1745 if (m_version < 6)
1746 return false;
1747 file = readFileIndexHelper();
1748 } else {
1749 file = readFileHelper();
1750 }
1751 if (!file)
1752 return false;
1753 *value = toV8(file, m_scriptState->context()->Global(), isolate());
1754 return true;
1755 }
1756
1757 bool Reader::readFileList(v8::Handle<v8::Value>* value, bool isIndexed)
1758 {
1759 if (m_version < 3)
1760 return false;
1761 uint32_t length;
1762 if (!doReadUint32(&length))
1763 return false;
1764 FileList* fileList = FileList::create();
1765 for (unsigned i = 0; i < length; ++i) {
1766 File* file = nullptr;
1767 if (isIndexed) {
1768 if (m_version < 6)
1769 return false;
1770 file = readFileIndexHelper();
1771 } else {
1772 file = readFileHelper();
1773 }
1774 if (!file)
1775 return false;
1776 fileList->append(file);
1777 }
1778 *value = toV8(fileList, m_scriptState->context()->Global(), isolate());
1779 return true;
1780 }
1781
1782 bool Reader::readCryptoKey(v8::Handle<v8::Value>* value)
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 {
1839 if (m_version < 3)
1840 return nullptr;
1841 ASSERT(!m_blobInfo);
1842 String path;
1843 String name;
1844 String relativePath;
1845 String uuid;
1846 String type;
1847 uint32_t hasSnapshot = 0;
1848 uint64_t size = 0;
1849 double lastModified = 0;
1850 if (!readWebCoreString(&path))
1851 return nullptr;
1852 if (m_version >= 4 && !readWebCoreString(&name))
1853 return nullptr;
1854 if (m_version >= 4 && !readWebCoreString(&relativePath))
1855 return nullptr;
1856 if (!readWebCoreString(&uuid))
1857 return nullptr;
1858 if (!readWebCoreString(&type))
1859 return nullptr;
1860 if (m_version >= 4 && !doReadUint32(&hasSnapshot))
1861 return nullptr;
1862 if (hasSnapshot) {
1863 if (!doReadUint64(&size))
1864 return nullptr;
1865 if (!doReadNumber(&lastModified))
1866 return nullptr;
1867 }
1868 uint32_t isUserVisible = 1;
1869 if (m_version >= 7 && !doReadUint32(&isUserVisible))
1870 return nullptr;
1871 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));
1873 }
1874
1875 File* Reader::readFileIndexHelper()
1876 {
1877 if (m_version < 3)
1878 return nullptr;
1879 ASSERT(m_blobInfo);
1880 uint32_t index;
1881 if (!doReadUint32(&index) || index >= m_blobInfo->size())
1882 return nullptr;
1883 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()));
1885 }
1886
1887 bool Reader::doReadUint32(uint32_t* value)
1888 {
1889 return doReadUintHelper(value);
1890 }
1891
1892 bool Reader::doReadUint64(uint64_t* value)
1893 {
1894 return doReadUintHelper(value);
1895 }
1896
1897 bool Reader::doReadNumber(double* number)
1898 {
1899 if (m_position + sizeof(double) > m_length)
1900 return false;
1901 uint8_t* numberAsByteArray = reinterpret_cast<uint8_t*>(number);
1902 for (unsigned i = 0; i < sizeof(double); ++i)
1903 numberAsByteArray[i] = m_buffer[m_position++];
1904 return true;
1905 }
1906
1907 PassRefPtr<BlobDataHandle> Reader::getOrCreateBlobDataHandle(const String& uuid, const String& type, long long size)
1908 {
1909 // 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
1911 // the new blob instead of cons'ing up a new BDH.
1912 //
1913 // 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
1915 // 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
1917 // 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(...).
1919 BlobDataHandleMap::const_iterator it = m_blobDataHandles.find(uuid);
1920 if (it != m_blobDataHandles.end()) {
1921 // make assertions about type and size?
1922 return it->value;
1923 }
1924 return BlobDataHandle::create(uuid, type, size);
1925 }
1926
1927 bool Reader::doReadHmacKey(WebCryptoKeyAlgorithm& algorithm, WebCryptoKeyType& t ype)
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 {
2131 v8::Isolate* isolate = m_reader.scriptState()->isolate();
2132 if (!m_reader.readVersion(m_version) || m_version > SerializedScriptValue::w ireFormatVersion)
2133 return v8::Null(isolate);
2134 m_reader.setVersion(m_version);
2135 v8::EscapableHandleScope scope(isolate);
2136 while (!m_reader.isEof()) {
2137 if (!doDeserialize())
2138 return v8::Null(isolate);
2139 }
2140 if (stackDepth() != 1 || m_openCompositeReferenceStack.size())
2141 return v8::Null(isolate);
2142 v8::Handle<v8::Value> result = scope.Escape(element(0));
2143 return result;
2144 }
2145
2146 bool Deserializer::newSparseArray(uint32_t)
2147 {
2148 v8::Local<v8::Array> array = v8::Array::New(m_reader.scriptState()->isolate( ), 0);
2149 openComposite(array);
2150 return true;
2151 }
2152
2153 bool Deserializer::newDenseArray(uint32_t length)
2154 {
2155 v8::Local<v8::Array> array = v8::Array::New(m_reader.scriptState()->isolate( ), length);
2156 openComposite(array);
2157 return true;
2158 }
2159
2160 bool Deserializer::consumeTopOfStack(v8::Handle<v8::Value>* object)
2161 {
2162 if (stackDepth() < 1)
2163 return false;
2164 *object = element(stackDepth() - 1);
2165 pop(1);
2166 return true;
2167 }
2168
2169 bool Deserializer::newObject()
2170 {
2171 v8::Local<v8::Object> object = v8::Object::New(m_reader.scriptState()->isola te());
2172 if (object.IsEmpty())
2173 return false;
2174 openComposite(object);
2175 return true;
2176 }
2177
2178 bool Deserializer::completeObject(uint32_t numProperties, v8::Handle<v8::Value>* value)
2179 {
2180 v8::Local<v8::Object> object;
2181 if (m_version > 0) {
2182 v8::Local<v8::Value> composite;
2183 if (!closeComposite(&composite))
2184 return false;
2185 object = composite.As<v8::Object>();
2186 } else {
2187 object = v8::Object::New(m_reader.scriptState()->isolate());
2188 }
2189 if (object.IsEmpty())
2190 return false;
2191 return initializeObject(object, numProperties, value);
2192 }
2193
2194 bool Deserializer::completeSparseArray(uint32_t numProperties, uint32_t length, v8::Handle<v8::Value>* value)
2195 {
2196 v8::Local<v8::Array> array;
2197 if (m_version > 0) {
2198 v8::Local<v8::Value> composite;
2199 if (!closeComposite(&composite))
2200 return false;
2201 array = composite.As<v8::Array>();
2202 } else {
2203 array = v8::Array::New(m_reader.scriptState()->isolate());
2204 }
2205 if (array.IsEmpty())
2206 return false;
2207 return initializeObject(array, numProperties, value);
2208 }
2209
2210 bool Deserializer::completeDenseArray(uint32_t numProperties, uint32_t length, v 8::Handle<v8::Value>* value)
2211 {
2212 v8::Local<v8::Array> array;
2213 if (m_version > 0) {
2214 v8::Local<v8::Value> composite;
2215 if (!closeComposite(&composite))
2216 return false;
2217 array = composite.As<v8::Array>();
2218 }
2219 if (array.IsEmpty())
2220 return false;
2221 if (!initializeObject(array, numProperties, value))
2222 return false;
2223 if (length > stackDepth())
2224 return false;
2225 for (unsigned i = 0, stackPos = stackDepth() - length; i < length; i++, stac kPos++) {
2226 v8::Local<v8::Value> elem = element(stackPos);
2227 if (!elem->IsUndefined())
2228 array->Set(i, elem);
2229 }
2230 pop(length);
2231 return true;
2232 }
2233
2234 void Deserializer::pushObjectReference(const v8::Handle<v8::Value>& object)
2235 {
2236 m_objectPool.append(object);
2237 }
2238
2239 bool Deserializer::tryGetTransferredMessagePort(uint32_t index, v8::Handle<v8::V alue>* object)
2240 {
2241 if (!m_transferredMessagePorts)
2242 return false;
2243 if (index >= m_transferredMessagePorts->size())
2244 return false;
2245 v8::Handle<v8::Object> creationContext = m_reader.scriptState()->context()-> Global();
2246 *object = toV8(m_transferredMessagePorts->at(index).get(), creationContext, m_reader.scriptState()->isolate());
2247 return true;
2248 }
2249
2250 bool Deserializer::tryGetTransferredArrayBuffer(uint32_t index, v8::Handle<v8::V alue>* object)
2251 {
2252 if (!m_arrayBufferContents)
2253 return false;
2254 if (index >= m_arrayBuffers.size())
2255 return false;
2256 v8::Handle<v8::Object> result = m_arrayBuffers.at(index);
2257 if (result.IsEmpty()) {
2258 RefPtr<DOMArrayBuffer> buffer = DOMArrayBuffer::create(m_arrayBufferCont ents->at(index));
2259 v8::Isolate* isolate = m_reader.scriptState()->isolate();
2260 v8::Handle<v8::Object> creationContext = m_reader.scriptState()->context ()->Global();
2261 result = toV8Object(buffer.get(), creationContext, isolate);
2262 m_arrayBuffers[index] = result;
2263 }
2264 *object = result;
2265 return true;
2266 }
2267
2268 bool Deserializer::tryGetObjectFromObjectReference(uint32_t reference, v8::Handl e<v8::Value>* object)
2269 {
2270 if (reference >= m_objectPool.size())
2271 return false;
2272 *object = m_objectPool[reference];
2273 return object;
2274 }
2275
2276 uint32_t Deserializer::objectReferenceCount()
2277 {
2278 return m_objectPool.size();
2279 }
2280
2281 bool Deserializer::initializeObject(v8::Handle<v8::Object> object, uint32_t numP roperties, v8::Handle<v8::Value>* value)
2282 {
2283 unsigned length = 2 * numProperties;
2284 if (length > stackDepth())
2285 return false;
2286 for (unsigned i = stackDepth() - length; i < stackDepth(); i += 2) {
2287 v8::Local<v8::Value> propertyName = element(i);
2288 v8::Local<v8::Value> propertyValue = element(i + 1);
2289 object->Set(propertyName, propertyValue);
2290 }
2291 pop(length);
2292 *value = object;
2293 return true;
2294 }
2295
2296 bool Deserializer::read(v8::Local<v8::Value>* value)
2297 {
2298 return m_reader.read(value, *this);
2299 }
2300
2301 bool Deserializer::doDeserialize()
2302 {
2303 v8::Local<v8::Value> value;
2304 if (!read(&value))
2305 return false;
2306 if (!value.IsEmpty())
2307 push(value);
2308 return true;
2309 }
2310
2311 v8::Local<v8::Value> Deserializer::element(unsigned index)
2312 {
2313 ASSERT_WITH_SECURITY_IMPLICATION(index < m_stack.size());
2314 return m_stack[index];
2315 }
2316
2317 void Deserializer::openComposite(const v8::Local<v8::Value>& object)
2318 {
2319 uint32_t newObjectReference = m_objectPool.size();
2320 m_openCompositeReferenceStack.append(newObjectReference);
2321 m_objectPool.append(object);
2322 }
2323
2324 bool Deserializer::closeComposite(v8::Handle<v8::Value>* object)
2325 {
2326 if (!m_openCompositeReferenceStack.size())
2327 return false;
2328 uint32_t objectReference = m_openCompositeReferenceStack[m_openCompositeRefe renceStack.size() - 1];
2329 m_openCompositeReferenceStack.shrink(m_openCompositeReferenceStack.size() - 1);
2330 if (objectReference >= m_objectPool.size())
2331 return false;
2332 *object = m_objectPool[objectReference];
2333 return true;
2334 }
2335
2336 } // SerializedScriptValueInternal
2337
2338 } // namespace blink
OLDNEW
« no previous file with comments | « Source/bindings/core/v8/ScriptValueSerializer.h ('k') | Source/bindings/core/v8/SerializationTag.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698