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

Powered by Google App Engine
This is Rietveld 408576698