1/* 2 * Copyright (C) 2009, 2013 Apple Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 * 25 */ 26 27#include "config.h" 28#include "SerializedScriptValue.h" 29 30#include "Blob.h" 31#include "CryptoKeyAES.h" 32#include "CryptoKeyDataOctetSequence.h" 33#include "CryptoKeyDataRSAComponents.h" 34#include "CryptoKeyHMAC.h" 35#include "CryptoKeyRSA.h" 36#include "ExceptionCode.h" 37#include "File.h" 38#include "FileList.h" 39#include "ImageData.h" 40#include "JSBlob.h" 41#include "JSCryptoKey.h" 42#include "JSDOMBinding.h" 43#include "JSDOMGlobalObject.h" 44#include "JSFile.h" 45#include "JSFileList.h" 46#include "JSImageData.h" 47#include "JSMessagePort.h" 48#include "JSNavigator.h" 49#include "ScriptExecutionContext.h" 50#include "SharedBuffer.h" 51#include "WebCoreJSClientData.h" 52#include <limits> 53#include <JavaScriptCore/APICast.h> 54#include <runtime/ArrayBuffer.h> 55#include <runtime/BooleanObject.h> 56#include <runtime/DateInstance.h> 57#include <runtime/Error.h> 58#include <runtime/ExceptionHelpers.h> 59#include <runtime/JSArrayBuffer.h> 60#include <runtime/JSArrayBufferView.h> 61#include <runtime/JSCInlines.h> 62#include <runtime/JSDataView.h> 63#include <runtime/JSMap.h> 64#include <runtime/JSSet.h> 65#include <runtime/JSTypedArrays.h> 66#include <runtime/MapData.h> 67#include <runtime/ObjectConstructor.h> 68#include <runtime/PropertyNameArray.h> 69#include <runtime/RegExp.h> 70#include <runtime/RegExpObject.h> 71#include <runtime/TypedArrayInlines.h> 72#include <runtime/TypedArrays.h> 73#include <wtf/HashTraits.h> 74#include <wtf/Vector.h> 75 76using namespace JSC; 77 78#if CPU(BIG_ENDIAN) || CPU(MIDDLE_ENDIAN) || CPU(NEEDS_ALIGNED_ACCESS) 79#define ASSUME_LITTLE_ENDIAN 0 80#else 81#define ASSUME_LITTLE_ENDIAN 1 82#endif 83 84namespace WebCore { 85 86static const unsigned maximumFilterRecursion = 40000; 87 88enum WalkerState { StateUnknown, ArrayStartState, ArrayStartVisitMember, ArrayEndVisitMember, 89 ObjectStartState, ObjectStartVisitMember, ObjectEndVisitMember, 90 MapDataStartVisitEntry, MapDataEndVisitKey, MapDataEndVisitValue }; 91 92// These can't be reordered, and any new types must be added to the end of the list 93enum SerializationTag { 94 ArrayTag = 1, 95 ObjectTag = 2, 96 UndefinedTag = 3, 97 NullTag = 4, 98 IntTag = 5, 99 ZeroTag = 6, 100 OneTag = 7, 101 FalseTag = 8, 102 TrueTag = 9, 103 DoubleTag = 10, 104 DateTag = 11, 105 FileTag = 12, 106 FileListTag = 13, 107 ImageDataTag = 14, 108 BlobTag = 15, 109 StringTag = 16, 110 EmptyStringTag = 17, 111 RegExpTag = 18, 112 ObjectReferenceTag = 19, 113 MessagePortReferenceTag = 20, 114 ArrayBufferTag = 21, 115 ArrayBufferViewTag = 22, 116 ArrayBufferTransferTag = 23, 117 TrueObjectTag = 24, 118 FalseObjectTag = 25, 119 StringObjectTag = 26, 120 EmptyStringObjectTag = 27, 121 NumberObjectTag = 28, 122 SetObjectTag = 29, 123 MapObjectTag = 30, 124 NonMapPropertiesTag = 31, 125#if ENABLE(SUBTLE_CRYPTO) 126 CryptoKeyTag = 32, 127#endif 128 ErrorTag = 255 129}; 130 131enum ArrayBufferViewSubtag { 132 DataViewTag = 0, 133 Int8ArrayTag = 1, 134 Uint8ArrayTag = 2, 135 Uint8ClampedArrayTag = 3, 136 Int16ArrayTag = 4, 137 Uint16ArrayTag = 5, 138 Int32ArrayTag = 6, 139 Uint32ArrayTag = 7, 140 Float32ArrayTag = 8, 141 Float64ArrayTag = 9 142}; 143 144static unsigned typedArrayElementSize(ArrayBufferViewSubtag tag) 145{ 146 switch (tag) { 147 case DataViewTag: 148 case Int8ArrayTag: 149 case Uint8ArrayTag: 150 case Uint8ClampedArrayTag: 151 return 1; 152 case Int16ArrayTag: 153 case Uint16ArrayTag: 154 return 2; 155 case Int32ArrayTag: 156 case Uint32ArrayTag: 157 case Float32ArrayTag: 158 return 4; 159 case Float64ArrayTag: 160 return 8; 161 default: 162 return 0; 163 } 164 165} 166 167#if ENABLE(SUBTLE_CRYPTO) 168 169const uint32_t currentKeyFormatVersion = 1; 170 171enum class CryptoKeyClassSubtag { 172 HMAC = 0, 173 AES = 1, 174 RSA = 2 175}; 176const uint8_t cryptoKeyClassSubtagMaximumValue = 2; 177 178enum class CryptoKeyAsymmetricTypeSubtag { 179 Public = 0, 180 Private = 1 181}; 182const uint8_t cryptoKeyAsymmetricTypeSubtagMaximumValue = 1; 183 184enum class CryptoKeyUsageTag { 185 Encrypt = 0, 186 Decrypt = 1, 187 Sign = 2, 188 Verify = 3, 189 DeriveKey = 4, 190 DeriveBits = 5, 191 WrapKey = 6, 192 UnwrapKey = 7 193}; 194const uint8_t cryptoKeyUsageTagMaximumValue = 7; 195 196enum class CryptoAlgorithmIdentifierTag { 197 RSAES_PKCS1_v1_5 = 0, 198 RSASSA_PKCS1_v1_5 = 1, 199 RSA_PSS = 2, 200 RSA_OAEP = 3, 201 ECDSA = 4, 202 ECDH = 5, 203 AES_CTR = 6, 204 AES_CBC = 7, 205 AES_CMAC = 8, 206 AES_GCM = 9, 207 AES_CFB = 10, 208 AES_KW = 11, 209 HMAC = 12, 210 DH = 13, 211 SHA_1 = 14, 212 SHA_224 = 15, 213 SHA_256 = 16, 214 SHA_384 = 17, 215 SHA_512 = 18, 216 CONCAT = 19, 217 HKDF_CTR = 20, 218 PBKDF2 = 21, 219}; 220const uint8_t cryptoAlgorithmIdentifierTagMaximumValue = 21; 221 222static unsigned countUsages(CryptoKeyUsage usages) 223{ 224 // Fast bit count algorithm for sparse bit maps. 225 unsigned count = 0; 226 while (usages) { 227 usages = usages & (usages - 1); 228 ++count; 229 } 230 return count; 231} 232 233#endif 234 235/* CurrentVersion tracks the serialization version so that persistent stores 236 * are able to correctly bail out in the case of encountering newer formats. 237 * 238 * Initial version was 1. 239 * Version 2. added the ObjectReferenceTag and support for serialization of cyclic graphs. 240 * Version 3. added the FalseObjectTag, TrueObjectTag, NumberObjectTag, StringObjectTag 241 * and EmptyStringObjectTag for serialization of Boolean, Number and String objects. 242 * Version 4. added support for serializing non-index properties of arrays. 243 * Version 5. added support for Map and Set types. 244 */ 245static const unsigned CurrentVersion = 5; 246static const unsigned TerminatorTag = 0xFFFFFFFF; 247static const unsigned StringPoolTag = 0xFFFFFFFE; 248static const unsigned NonIndexPropertiesTag = 0xFFFFFFFD; 249 250/* 251 * Object serialization is performed according to the following grammar, all tags 252 * are recorded as a single uint8_t. 253 * 254 * IndexType (used for the object pool and StringData's constant pool) is the 255 * minimum sized unsigned integer type required to represent the maximum index 256 * in the constant pool. 257 * 258 * SerializedValue :- <CurrentVersion:uint32_t> Value 259 * Value :- Array | Object | Map | Set | Terminal 260 * 261 * Array :- 262 * ArrayTag <length:uint32_t>(<index:uint32_t><value:Value>)* TerminatorTag 263 * 264 * Object :- 265 * ObjectTag (<name:StringData><value:Value>)* TerminatorTag 266 * 267 * Map :- MapObjectTag MapData 268 * 269 * Set :- SetObjectTag MapData 270 * 271 * MapData :- (<key:Value><value:Value>) NonMapPropertiesTag (<name:StringData><value:Value>)* TerminatorTag 272 * 273 * Terminal :- 274 * UndefinedTag 275 * | NullTag 276 * | IntTag <value:int32_t> 277 * | ZeroTag 278 * | OneTag 279 * | FalseTag 280 * | TrueTag 281 * | FalseObjectTag 282 * | TrueObjectTag 283 * | DoubleTag <value:double> 284 * | NumberObjectTag <value:double> 285 * | DateTag <value:double> 286 * | String 287 * | EmptyStringTag 288 * | EmptyStringObjectTag 289 * | File 290 * | FileList 291 * | ImageData 292 * | Blob 293 * | ObjectReference 294 * | MessagePortReferenceTag <value:uint32_t> 295 * | ArrayBuffer 296 * | ArrayBufferViewTag ArrayBufferViewSubtag <byteOffset:uint32_t> <byteLength:uint32_t> (ArrayBuffer | ObjectReference) 297 * | ArrayBufferTransferTag <value:uint32_t> 298 * | CryptoKeyTag <wrappedKeyLength:uint32_t> <factor:byte{wrappedKeyLength}> 299 * 300 * Inside wrapped crypto key, data is serialized in this format: 301 * 302 * <keyFormatVersion:uint32_t> <extractable:int32_t> <usagesCount:uint32_t> <usages:byte{usagesCount}> CryptoKeyClassSubtag (CryptoKeyHMAC | CryptoKeyAES | CryptoKeyRSA) 303 * 304 * String :- 305 * EmptyStringTag 306 * StringTag StringData 307 * 308 * StringObject: 309 * EmptyStringObjectTag 310 * StringObjectTag StringData 311 * 312 * StringData :- 313 * StringPoolTag <cpIndex:IndexType> 314 * (not (TerminatorTag | StringPoolTag))<length:uint32_t><characters:UChar{length}> // Added to constant pool when seen, string length 0xFFFFFFFF is disallowed 315 * 316 * File :- 317 * FileTag FileData 318 * 319 * FileData :- 320 * <path:StringData> <url:StringData> <type:StringData> <name:StringData> 321 * 322 * FileList :- 323 * FileListTag <length:uint32_t>(<file:FileData>){length} 324 * 325 * ImageData :- 326 * ImageDataTag <width:int32_t><height:int32_t><length:uint32_t><data:uint8_t{length}> 327 * 328 * Blob :- 329 * BlobTag <url:StringData><type:StringData><size:long long> 330 * 331 * RegExp :- 332 * RegExpTag <pattern:StringData><flags:StringData> 333 * 334 * ObjectReference :- 335 * ObjectReferenceTag <opIndex:IndexType> 336 * 337 * ArrayBuffer :- 338 * ArrayBufferTag <length:uint32_t> <contents:byte{length}> 339 * 340 * CryptoKeyHMAC :- 341 * <keySize:uint32_t> <keyData:byte{keySize}> CryptoAlgorithmIdentifierTag // Algorithm tag inner hash function. 342 * 343 * CryptoKeyAES :- 344 * CryptoAlgorithmIdentifierTag <keySize:uint32_t> <keyData:byte{keySize}> 345 * 346 * CryptoKeyRSA :- 347 * CryptoAlgorithmIdentifierTag <isRestrictedToHash:int32_t> CryptoAlgorithmIdentifierTag? CryptoKeyAsymmetricTypeSubtag CryptoKeyRSAPublicComponents CryptoKeyRSAPrivateComponents? 348 * 349 * CryptoKeyRSAPublicComponents :- 350 * <modulusSize:uint32_t> <modulus:byte{modulusSize}> <exponentSize:uint32_t> <exponent:byte{exponentSize}> 351 * 352 * CryptoKeyRSAPrivateComponents :- 353 * <privateExponentSize:uint32_t> <privateExponent:byte{privateExponentSize}> <primeCount:uint32_t> FirstPrimeInfo? PrimeInfo{primeCount - 1} 354 * 355 * // CRT data could be computed from prime factors. It is only serialized to reuse a code path that's needed for JWK. 356 * FirstPrimeInfo :- 357 * <factorSize:uint32_t> <factor:byte{factorSize}> <crtExponentSize:uint32_t> <crtExponent:byte{crtExponentSize}> 358 * 359 * PrimeInfo :- 360 * <factorSize:uint32_t> <factor:byte{factorSize}> <crtExponentSize:uint32_t> <crtExponent:byte{crtExponentSize}> <crtCoefficientSize:uint32_t> <crtCoefficient:byte{crtCoefficientSize}> 361 */ 362 363typedef std::pair<JSC::JSValue, SerializationReturnCode> DeserializationResult; 364 365class CloneBase { 366protected: 367 CloneBase(ExecState* exec) 368 : m_exec(exec) 369 , m_failed(false) 370 { 371 } 372 373 bool shouldTerminate() 374 { 375 return m_exec->hadException(); 376 } 377 378 void throwStackOverflow() 379 { 380 m_exec->vm().throwException(m_exec, createStackOverflowError(m_exec)); 381 } 382 383 void fail() 384 { 385 m_failed = true; 386 } 387 388 ExecState* m_exec; 389 bool m_failed; 390 MarkedArgumentBuffer m_gcBuffer; 391}; 392 393#if ENABLE(SUBTLE_CRYPTO) 394static bool wrapCryptoKey(ExecState* exec, const Vector<uint8_t>& key, Vector<uint8_t>& wrappedKey) 395{ 396 ScriptExecutionContext* scriptExecutionContext = scriptExecutionContextFromExecState(exec); 397 if (!scriptExecutionContext) 398 return false; 399 return scriptExecutionContext->wrapCryptoKey(key, wrappedKey); 400} 401 402static bool unwrapCryptoKey(ExecState* exec, const Vector<uint8_t>& wrappedKey, Vector<uint8_t>& key) 403{ 404 ScriptExecutionContext* scriptExecutionContext = scriptExecutionContextFromExecState(exec); 405 if (!scriptExecutionContext) 406 return false; 407 return scriptExecutionContext->unwrapCryptoKey(wrappedKey, key); 408} 409#endif 410 411#if ASSUME_LITTLE_ENDIAN 412template <typename T> static void writeLittleEndian(Vector<uint8_t>& buffer, T value) 413{ 414 buffer.append(reinterpret_cast<uint8_t*>(&value), sizeof(value)); 415} 416#else 417template <typename T> static void writeLittleEndian(Vector<uint8_t>& buffer, T value) 418{ 419 for (unsigned i = 0; i < sizeof(T); i++) { 420 buffer.append(value & 0xFF); 421 value >>= 8; 422 } 423} 424#endif 425 426template <> void writeLittleEndian<uint8_t>(Vector<uint8_t>& buffer, uint8_t value) 427{ 428 buffer.append(value); 429} 430 431template <typename T> static bool writeLittleEndian(Vector<uint8_t>& buffer, const T* values, uint32_t length) 432{ 433 if (length > std::numeric_limits<uint32_t>::max() / sizeof(T)) 434 return false; 435 436#if ASSUME_LITTLE_ENDIAN 437 buffer.append(reinterpret_cast<const uint8_t*>(values), length * sizeof(T)); 438#else 439 for (unsigned i = 0; i < length; i++) { 440 T value = values[i]; 441 for (unsigned j = 0; j < sizeof(T); j++) { 442 buffer.append(static_cast<uint8_t>(value & 0xFF)); 443 value >>= 8; 444 } 445 } 446#endif 447 return true; 448} 449 450static bool writeLittleEndianUInt16(Vector<uint8_t>& buffer, const LChar* values, uint32_t length) 451{ 452 if (length > std::numeric_limits<uint32_t>::max() / 2) 453 return false; 454 455 for (unsigned i = 0; i < length; ++i) { 456 buffer.append(values[i]); 457 buffer.append(0); 458 } 459 460 return true; 461} 462 463template <> bool writeLittleEndian<uint8_t>(Vector<uint8_t>& buffer, const uint8_t* values, uint32_t length) 464{ 465 buffer.append(values, length); 466 return true; 467} 468 469class CloneSerializer : CloneBase { 470public: 471 static SerializationReturnCode serialize(ExecState* exec, JSValue value, 472 MessagePortArray* messagePorts, ArrayBufferArray* arrayBuffers, 473 Vector<String>& blobURLs, Vector<uint8_t>& out) 474 { 475 CloneSerializer serializer(exec, messagePorts, arrayBuffers, blobURLs, out); 476 return serializer.serialize(value); 477 } 478 479 static bool serialize(const String& s, Vector<uint8_t>& out) 480 { 481 writeLittleEndian(out, CurrentVersion); 482 if (s.isEmpty()) { 483 writeLittleEndian<uint8_t>(out, EmptyStringTag); 484 return true; 485 } 486 writeLittleEndian<uint8_t>(out, StringTag); 487 writeLittleEndian(out, s.length()); 488 if (s.is8Bit()) 489 return writeLittleEndianUInt16(out, s.characters8(), s.length()); 490 return writeLittleEndian(out, s.characters16(), s.length()); 491 } 492 493 static void serializeUndefined(Vector<uint8_t>& out) 494 { 495 writeLittleEndian(out, CurrentVersion); 496 writeLittleEndian<uint8_t>(out, UndefinedTag); 497 } 498 499 static void serializeBoolean(bool value, Vector<uint8_t>& out) 500 { 501 writeLittleEndian(out, CurrentVersion); 502 writeLittleEndian<uint8_t>(out, value ? TrueTag : FalseTag); 503 } 504 505 static void serializeNumber(double value, Vector<uint8_t>& out) 506 { 507 writeLittleEndian(out, CurrentVersion); 508 writeLittleEndian<uint8_t>(out, DoubleTag); 509 union { 510 double d; 511 int64_t i; 512 } u; 513 u.d = value; 514 writeLittleEndian(out, u.i); 515 } 516 517private: 518 typedef HashMap<JSObject*, uint32_t> ObjectPool; 519 520 CloneSerializer(ExecState* exec, MessagePortArray* messagePorts, ArrayBufferArray* arrayBuffers, Vector<String>& blobURLs, Vector<uint8_t>& out) 521 : CloneBase(exec) 522 , m_buffer(out) 523 , m_blobURLs(blobURLs) 524 , m_emptyIdentifier(exec, emptyString()) 525 { 526 write(CurrentVersion); 527 fillTransferMap(messagePorts, m_transferredMessagePorts); 528 fillTransferMap(arrayBuffers, m_transferredArrayBuffers); 529 } 530 531 template <class T> 532 void fillTransferMap(Vector<RefPtr<T>, 1>* input, ObjectPool& result) 533 { 534 if (!input) 535 return; 536 JSDOMGlobalObject* globalObject = jsCast<JSDOMGlobalObject*>(m_exec->lexicalGlobalObject()); 537 for (size_t i = 0; i < input->size(); i++) { 538 JSC::JSValue value = toJS(m_exec, globalObject, input->at(i).get()); 539 JSC::JSObject* obj = value.getObject(); 540 if (obj && !result.contains(obj)) 541 result.add(obj, i); 542 } 543 } 544 545 SerializationReturnCode serialize(JSValue in); 546 547 bool isArray(JSValue value) 548 { 549 if (!value.isObject()) 550 return false; 551 JSObject* object = asObject(value); 552 return isJSArray(object) || object->inherits(JSArray::info()); 553 } 554 555 bool isMap(JSValue value) 556 { 557 if (!value.isObject()) 558 return false; 559 JSObject* object = asObject(value); 560 return object->inherits(JSMap::info()); 561 } 562 bool isSet(JSValue value) 563 { 564 if (!value.isObject()) 565 return false; 566 JSObject* object = asObject(value); 567 return object->inherits(JSSet::info()); 568 } 569 570 bool checkForDuplicate(JSObject* object) 571 { 572 // Record object for graph reconstruction 573 ObjectPool::const_iterator found = m_objectPool.find(object); 574 575 // Handle duplicate references 576 if (found != m_objectPool.end()) { 577 write(ObjectReferenceTag); 578 ASSERT(static_cast<int32_t>(found->value) < m_objectPool.size()); 579 writeObjectIndex(found->value); 580 return true; 581 } 582 583 return false; 584 } 585 586 void recordObject(JSObject* object) 587 { 588 m_objectPool.add(object, m_objectPool.size()); 589 m_gcBuffer.append(object); 590 } 591 592 bool startObjectInternal(JSObject* object) 593 { 594 if (checkForDuplicate(object)) 595 return false; 596 recordObject(object); 597 return true; 598 } 599 600 bool startObject(JSObject* object) 601 { 602 if (!startObjectInternal(object)) 603 return false; 604 write(ObjectTag); 605 return true; 606 } 607 608 bool startArray(JSArray* array) 609 { 610 if (!startObjectInternal(array)) 611 return false; 612 613 unsigned length = array->length(); 614 write(ArrayTag); 615 write(length); 616 return true; 617 } 618 619 bool startSet(JSSet* set) 620 { 621 if (!startObjectInternal(set)) 622 return false; 623 624 write(SetObjectTag); 625 return true; 626 } 627 628 bool startMap(JSMap* map) 629 { 630 if (!startObjectInternal(map)) 631 return false; 632 633 write(MapObjectTag); 634 return true; 635 } 636 637 void endObject() 638 { 639 write(TerminatorTag); 640 } 641 642 JSValue getProperty(JSObject* object, const Identifier& propertyName) 643 { 644 PropertySlot slot(object); 645 if (object->methodTable()->getOwnPropertySlot(object, m_exec, propertyName, slot)) 646 return slot.getValue(m_exec, propertyName); 647 return JSValue(); 648 } 649 650 void dumpImmediate(JSValue value) 651 { 652 if (value.isNull()) 653 write(NullTag); 654 else if (value.isUndefined()) 655 write(UndefinedTag); 656 else if (value.isNumber()) { 657 if (value.isInt32()) { 658 if (!value.asInt32()) 659 write(ZeroTag); 660 else if (value.asInt32() == 1) 661 write(OneTag); 662 else { 663 write(IntTag); 664 write(static_cast<uint32_t>(value.asInt32())); 665 } 666 } else { 667 write(DoubleTag); 668 write(value.asDouble()); 669 } 670 } else if (value.isBoolean()) { 671 if (value.isTrue()) 672 write(TrueTag); 673 else 674 write(FalseTag); 675 } 676 } 677 678 void dumpString(String str) 679 { 680 if (str.isEmpty()) 681 write(EmptyStringTag); 682 else { 683 write(StringTag); 684 write(str); 685 } 686 } 687 688 void dumpStringObject(String str) 689 { 690 if (str.isEmpty()) 691 write(EmptyStringObjectTag); 692 else { 693 write(StringObjectTag); 694 write(str); 695 } 696 } 697 698 bool dumpArrayBufferView(JSObject* obj, SerializationReturnCode& code) 699 { 700 write(ArrayBufferViewTag); 701 if (obj->inherits(JSDataView::info())) 702 write(DataViewTag); 703 else if (obj->inherits(JSUint8ClampedArray::info())) 704 write(Uint8ClampedArrayTag); 705 else if (obj->inherits(JSInt8Array::info())) 706 write(Int8ArrayTag); 707 else if (obj->inherits(JSUint8Array::info())) 708 write(Uint8ArrayTag); 709 else if (obj->inherits(JSInt16Array::info())) 710 write(Int16ArrayTag); 711 else if (obj->inherits(JSUint16Array::info())) 712 write(Uint16ArrayTag); 713 else if (obj->inherits(JSInt32Array::info())) 714 write(Int32ArrayTag); 715 else if (obj->inherits(JSUint32Array::info())) 716 write(Uint32ArrayTag); 717 else if (obj->inherits(JSFloat32Array::info())) 718 write(Float32ArrayTag); 719 else if (obj->inherits(JSFloat64Array::info())) 720 write(Float64ArrayTag); 721 else 722 return false; 723 724 RefPtr<ArrayBufferView> arrayBufferView = toArrayBufferView(obj); 725 write(static_cast<uint32_t>(arrayBufferView->byteOffset())); 726 write(static_cast<uint32_t>(arrayBufferView->byteLength())); 727 RefPtr<ArrayBuffer> arrayBuffer = arrayBufferView->buffer(); 728 if (!arrayBuffer) { 729 code = ValidationError; 730 return true; 731 } 732 JSValue bufferObj = toJS(m_exec, jsCast<JSDOMGlobalObject*>(m_exec->lexicalGlobalObject()), arrayBuffer.get()); 733 return dumpIfTerminal(bufferObj, code); 734 } 735 736 bool dumpIfTerminal(JSValue value, SerializationReturnCode& code) 737 { 738 if (!value.isCell()) { 739 dumpImmediate(value); 740 return true; 741 } 742 743 if (value.isString()) { 744 String str = asString(value)->value(m_exec); 745 dumpString(str); 746 return true; 747 } 748 749 if (value.isNumber()) { 750 write(DoubleTag); 751 write(value.asNumber()); 752 return true; 753 } 754 755 if (value.isObject() && asObject(value)->inherits(DateInstance::info())) { 756 write(DateTag); 757 write(asDateInstance(value)->internalNumber()); 758 return true; 759 } 760 761 if (isArray(value)) 762 return false; 763 764 if (value.isObject()) { 765 JSObject* obj = asObject(value); 766 if (obj->inherits(BooleanObject::info())) { 767 if (!startObjectInternal(obj)) // handle duplicates 768 return true; 769 write(asBooleanObject(value)->internalValue().toBoolean(m_exec) ? TrueObjectTag : FalseObjectTag); 770 return true; 771 } 772 if (obj->inherits(StringObject::info())) { 773 if (!startObjectInternal(obj)) // handle duplicates 774 return true; 775 String str = asString(asStringObject(value)->internalValue())->value(m_exec); 776 dumpStringObject(str); 777 return true; 778 } 779 if (obj->inherits(NumberObject::info())) { 780 if (!startObjectInternal(obj)) // handle duplicates 781 return true; 782 write(NumberObjectTag); 783 NumberObject* obj = static_cast<NumberObject*>(asObject(value)); 784 write(obj->internalValue().asNumber()); 785 return true; 786 } 787 if (File* file = toFile(obj)) { 788 write(FileTag); 789 write(file); 790 return true; 791 } 792 if (FileList* list = toFileList(obj)) { 793 write(FileListTag); 794 unsigned length = list->length(); 795 write(length); 796 for (unsigned i = 0; i < length; i++) 797 write(list->item(i)); 798 return true; 799 } 800 if (Blob* blob = toBlob(obj)) { 801 write(BlobTag); 802 m_blobURLs.append(blob->url()); 803 write(blob->url()); 804 write(blob->type()); 805 write(blob->size()); 806 return true; 807 } 808 if (ImageData* data = toImageData(obj)) { 809 write(ImageDataTag); 810 write(data->width()); 811 write(data->height()); 812 write(data->data()->length()); 813 write(data->data()->data(), data->data()->length()); 814 return true; 815 } 816 if (obj->inherits(RegExpObject::info())) { 817 RegExpObject* regExp = asRegExpObject(obj); 818 char flags[3]; 819 int flagCount = 0; 820 if (regExp->regExp()->global()) 821 flags[flagCount++] = 'g'; 822 if (regExp->regExp()->ignoreCase()) 823 flags[flagCount++] = 'i'; 824 if (regExp->regExp()->multiline()) 825 flags[flagCount++] = 'm'; 826 write(RegExpTag); 827 write(regExp->regExp()->pattern()); 828 write(String(flags, flagCount)); 829 return true; 830 } 831 if (obj->inherits(JSMessagePort::info())) { 832 ObjectPool::iterator index = m_transferredMessagePorts.find(obj); 833 if (index != m_transferredMessagePorts.end()) { 834 write(MessagePortReferenceTag); 835 write(index->value); 836 return true; 837 } 838 // MessagePort object could not be found in transferred message ports 839 code = ValidationError; 840 return true; 841 } 842 if (ArrayBuffer* arrayBuffer = toArrayBuffer(obj)) { 843 if (arrayBuffer->isNeutered()) { 844 code = ValidationError; 845 return true; 846 } 847 ObjectPool::iterator index = m_transferredArrayBuffers.find(obj); 848 if (index != m_transferredArrayBuffers.end()) { 849 write(ArrayBufferTransferTag); 850 write(index->value); 851 return true; 852 } 853 if (!startObjectInternal(obj)) // handle duplicates 854 return true; 855 write(ArrayBufferTag); 856 write(arrayBuffer->byteLength()); 857 write(static_cast<const uint8_t*>(arrayBuffer->data()), arrayBuffer->byteLength()); 858 return true; 859 } 860 if (obj->inherits(JSArrayBufferView::info())) { 861 if (checkForDuplicate(obj)) 862 return true; 863 bool success = dumpArrayBufferView(obj, code); 864 recordObject(obj); 865 return success; 866 } 867#if ENABLE(SUBTLE_CRYPTO) 868 if (CryptoKey* key = toCryptoKey(obj)) { 869 write(CryptoKeyTag); 870 Vector<uint8_t> serializedKey; 871 Vector<String> dummyBlobURLs; 872 CloneSerializer rawKeySerializer(m_exec, nullptr, nullptr, dummyBlobURLs, serializedKey); 873 rawKeySerializer.write(key); 874 Vector<uint8_t> wrappedKey; 875 if (!wrapCryptoKey(m_exec, serializedKey, wrappedKey)) 876 return false; 877 write(wrappedKey); 878 return true; 879 } 880#endif 881 882 return false; 883 } 884 // Any other types are expected to serialize as null. 885 write(NullTag); 886 return true; 887 } 888 889 void write(SerializationTag tag) 890 { 891 writeLittleEndian<uint8_t>(m_buffer, static_cast<uint8_t>(tag)); 892 } 893 894 void write(ArrayBufferViewSubtag tag) 895 { 896 writeLittleEndian<uint8_t>(m_buffer, static_cast<uint8_t>(tag)); 897 } 898 899#if ENABLE(SUBTLE_CRYPTO) 900 void write(CryptoKeyClassSubtag tag) 901 { 902 writeLittleEndian<uint8_t>(m_buffer, static_cast<uint8_t>(tag)); 903 } 904 905 void write(CryptoKeyAsymmetricTypeSubtag tag) 906 { 907 writeLittleEndian<uint8_t>(m_buffer, static_cast<uint8_t>(tag)); 908 } 909 910 void write(CryptoKeyUsageTag tag) 911 { 912 writeLittleEndian<uint8_t>(m_buffer, static_cast<uint8_t>(tag)); 913 } 914 915 void write(CryptoAlgorithmIdentifierTag tag) 916 { 917 writeLittleEndian<uint8_t>(m_buffer, static_cast<uint8_t>(tag)); 918 } 919#endif 920 921 void write(uint8_t c) 922 { 923 writeLittleEndian(m_buffer, c); 924 } 925 926 void write(uint32_t i) 927 { 928 writeLittleEndian(m_buffer, i); 929 } 930 931 void write(double d) 932 { 933 union { 934 double d; 935 int64_t i; 936 } u; 937 u.d = d; 938 writeLittleEndian(m_buffer, u.i); 939 } 940 941 void write(int32_t i) 942 { 943 writeLittleEndian(m_buffer, i); 944 } 945 946 void write(unsigned long long i) 947 { 948 writeLittleEndian(m_buffer, i); 949 } 950 951 void write(uint16_t ch) 952 { 953 writeLittleEndian(m_buffer, ch); 954 } 955 956 void writeStringIndex(unsigned i) 957 { 958 writeConstantPoolIndex(m_constantPool, i); 959 } 960 961 void writeObjectIndex(unsigned i) 962 { 963 writeConstantPoolIndex(m_objectPool, i); 964 } 965 966 template <class T> void writeConstantPoolIndex(const T& constantPool, unsigned i) 967 { 968 ASSERT(static_cast<int32_t>(i) < constantPool.size()); 969 if (constantPool.size() <= 0xFF) 970 write(static_cast<uint8_t>(i)); 971 else if (constantPool.size() <= 0xFFFF) 972 write(static_cast<uint16_t>(i)); 973 else 974 write(static_cast<uint32_t>(i)); 975 } 976 977 void write(const Identifier& ident) 978 { 979 const String& str = ident.string(); 980 StringConstantPool::AddResult addResult = m_constantPool.add(str.impl(), m_constantPool.size()); 981 if (!addResult.isNewEntry) { 982 write(StringPoolTag); 983 writeStringIndex(addResult.iterator->value); 984 return; 985 } 986 987 unsigned length = str.length(); 988 989 // This condition is unlikely to happen as they would imply an ~8gb 990 // string but we should guard against it anyway 991 if (length >= StringPoolTag) { 992 fail(); 993 return; 994 } 995 996 // Guard against overflow 997 if (length > (std::numeric_limits<uint32_t>::max() - sizeof(uint32_t)) / sizeof(UChar)) { 998 fail(); 999 return; 1000 } 1001 1002 writeLittleEndian<uint32_t>(m_buffer, length); 1003 if (!length || str.is8Bit()) { 1004 if (!writeLittleEndianUInt16(m_buffer, str.characters8(), length)) 1005 fail(); 1006 return; 1007 } 1008 if (!writeLittleEndian(m_buffer, str.characters16(), length)) 1009 fail(); 1010 } 1011 1012 void write(const String& str) 1013 { 1014 if (str.isNull()) 1015 write(m_emptyIdentifier); 1016 else 1017 write(Identifier(m_exec, str)); 1018 } 1019 1020 void write(const Vector<uint8_t>& vector) 1021 { 1022 uint32_t size = vector.size(); 1023 write(size); 1024 writeLittleEndian(m_buffer, vector.data(), size); 1025 } 1026 1027 void write(const File* file) 1028 { 1029 m_blobURLs.append(file->url()); 1030 write(file->path()); 1031 write(file->url()); 1032 write(file->type()); 1033 write(file->name()); 1034 } 1035 1036#if ENABLE(SUBTLE_CRYPTO) 1037 void write(CryptoAlgorithmIdentifier algorithm) 1038 { 1039 switch (algorithm) { 1040 case CryptoAlgorithmIdentifier::RSAES_PKCS1_v1_5: 1041 write(CryptoAlgorithmIdentifierTag::RSAES_PKCS1_v1_5); 1042 break; 1043 case CryptoAlgorithmIdentifier::RSASSA_PKCS1_v1_5: 1044 write(CryptoAlgorithmIdentifierTag::RSASSA_PKCS1_v1_5); 1045 break; 1046 case CryptoAlgorithmIdentifier::RSA_PSS: 1047 write(CryptoAlgorithmIdentifierTag::RSA_PSS); 1048 break; 1049 case CryptoAlgorithmIdentifier::RSA_OAEP: 1050 write(CryptoAlgorithmIdentifierTag::RSA_OAEP); 1051 break; 1052 case CryptoAlgorithmIdentifier::ECDSA: 1053 write(CryptoAlgorithmIdentifierTag::ECDSA); 1054 break; 1055 case CryptoAlgorithmIdentifier::ECDH: 1056 write(CryptoAlgorithmIdentifierTag::ECDH); 1057 break; 1058 case CryptoAlgorithmIdentifier::AES_CTR: 1059 write(CryptoAlgorithmIdentifierTag::AES_CTR); 1060 break; 1061 case CryptoAlgorithmIdentifier::AES_CBC: 1062 write(CryptoAlgorithmIdentifierTag::AES_CBC); 1063 break; 1064 case CryptoAlgorithmIdentifier::AES_CMAC: 1065 write(CryptoAlgorithmIdentifierTag::AES_CMAC); 1066 break; 1067 case CryptoAlgorithmIdentifier::AES_GCM: 1068 write(CryptoAlgorithmIdentifierTag::AES_GCM); 1069 break; 1070 case CryptoAlgorithmIdentifier::AES_CFB: 1071 write(CryptoAlgorithmIdentifierTag::AES_CFB); 1072 break; 1073 case CryptoAlgorithmIdentifier::AES_KW: 1074 write(CryptoAlgorithmIdentifierTag::AES_KW); 1075 break; 1076 case CryptoAlgorithmIdentifier::HMAC: 1077 write(CryptoAlgorithmIdentifierTag::HMAC); 1078 break; 1079 case CryptoAlgorithmIdentifier::DH: 1080 write(CryptoAlgorithmIdentifierTag::DH); 1081 break; 1082 case CryptoAlgorithmIdentifier::SHA_1: 1083 write(CryptoAlgorithmIdentifierTag::SHA_1); 1084 break; 1085 case CryptoAlgorithmIdentifier::SHA_224: 1086 write(CryptoAlgorithmIdentifierTag::SHA_224); 1087 break; 1088 case CryptoAlgorithmIdentifier::SHA_256: 1089 write(CryptoAlgorithmIdentifierTag::SHA_256); 1090 break; 1091 case CryptoAlgorithmIdentifier::SHA_384: 1092 write(CryptoAlgorithmIdentifierTag::SHA_384); 1093 break; 1094 case CryptoAlgorithmIdentifier::SHA_512: 1095 write(CryptoAlgorithmIdentifierTag::SHA_512); 1096 break; 1097 case CryptoAlgorithmIdentifier::CONCAT: 1098 write(CryptoAlgorithmIdentifierTag::CONCAT); 1099 break; 1100 case CryptoAlgorithmIdentifier::HKDF_CTR: 1101 write(CryptoAlgorithmIdentifierTag::HKDF_CTR); 1102 break; 1103 case CryptoAlgorithmIdentifier::PBKDF2: 1104 write(CryptoAlgorithmIdentifierTag::PBKDF2); 1105 break; 1106 } 1107 } 1108 1109 void write(CryptoKeyDataRSAComponents::Type type) 1110 { 1111 switch (type) { 1112 case CryptoKeyDataRSAComponents::Type::Public: 1113 write(CryptoKeyAsymmetricTypeSubtag::Public); 1114 return; 1115 case CryptoKeyDataRSAComponents::Type::Private: 1116 write(CryptoKeyAsymmetricTypeSubtag::Private); 1117 return; 1118 } 1119 } 1120 1121 void write(const CryptoKeyDataRSAComponents& key) 1122 { 1123 write(key.type()); 1124 write(key.modulus()); 1125 write(key.exponent()); 1126 if (key.type() == CryptoKeyDataRSAComponents::Type::Public) 1127 return; 1128 1129 write(key.privateExponent()); 1130 1131 unsigned primeCount = key.hasAdditionalPrivateKeyParameters() ? key.otherPrimeInfos().size() + 2 : 0; 1132 write(primeCount); 1133 if (!primeCount) 1134 return; 1135 1136 write(key.firstPrimeInfo().primeFactor); 1137 write(key.firstPrimeInfo().factorCRTExponent); 1138 write(key.secondPrimeInfo().primeFactor); 1139 write(key.secondPrimeInfo().factorCRTExponent); 1140 write(key.secondPrimeInfo().factorCRTCoefficient); 1141 for (unsigned i = 2; i < primeCount; ++i) { 1142 write(key.otherPrimeInfos()[i].primeFactor); 1143 write(key.otherPrimeInfos()[i].factorCRTExponent); 1144 write(key.otherPrimeInfos()[i].factorCRTCoefficient); 1145 } 1146 } 1147 1148 void write(const CryptoKey* key) 1149 { 1150 write(currentKeyFormatVersion); 1151 1152 write(key->extractable()); 1153 1154 CryptoKeyUsage usages = key->usagesBitmap(); 1155 write(countUsages(usages)); 1156 if (usages & CryptoKeyUsageEncrypt) 1157 write(CryptoKeyUsageTag::Encrypt); 1158 if (usages & CryptoKeyUsageDecrypt) 1159 write(CryptoKeyUsageTag::Decrypt); 1160 if (usages & CryptoKeyUsageSign) 1161 write(CryptoKeyUsageTag::Sign); 1162 if (usages & CryptoKeyUsageVerify) 1163 write(CryptoKeyUsageTag::Verify); 1164 if (usages & CryptoKeyUsageDeriveKey) 1165 write(CryptoKeyUsageTag::DeriveKey); 1166 if (usages & CryptoKeyUsageDeriveBits) 1167 write(CryptoKeyUsageTag::DeriveBits); 1168 if (usages & CryptoKeyUsageWrapKey) 1169 write(CryptoKeyUsageTag::WrapKey); 1170 if (usages & CryptoKeyUsageUnwrapKey) 1171 write(CryptoKeyUsageTag::UnwrapKey); 1172 1173 switch (key->keyClass()) { 1174 case CryptoKeyClass::HMAC: 1175 write(CryptoKeyClassSubtag::HMAC); 1176 write(toCryptoKeyHMAC(key)->key()); 1177 write(toCryptoKeyHMAC(key)->hashAlgorithmIdentifier()); 1178 break; 1179 case CryptoKeyClass::AES: 1180 write(CryptoKeyClassSubtag::AES); 1181 write(key->algorithmIdentifier()); 1182 write(toCryptoKeyAES(key)->key()); 1183 break; 1184 case CryptoKeyClass::RSA: 1185 write(CryptoKeyClassSubtag::RSA); 1186 write(key->algorithmIdentifier()); 1187 CryptoAlgorithmIdentifier hash; 1188 bool isRestrictedToHash = toCryptoKeyRSA(key)->isRestrictedToHash(hash); 1189 write(isRestrictedToHash); 1190 if (isRestrictedToHash) 1191 write(hash); 1192 write(toCryptoKeyDataRSAComponents(*key->exportData())); 1193 break; 1194 } 1195 } 1196#endif 1197 1198 void write(const uint8_t* data, unsigned length) 1199 { 1200 m_buffer.append(data, length); 1201 } 1202 1203 Vector<uint8_t>& m_buffer; 1204 Vector<String>& m_blobURLs; 1205 ObjectPool m_objectPool; 1206 ObjectPool m_transferredMessagePorts; 1207 ObjectPool m_transferredArrayBuffers; 1208 typedef HashMap<RefPtr<StringImpl>, uint32_t, IdentifierRepHash> StringConstantPool; 1209 StringConstantPool m_constantPool; 1210 Identifier m_emptyIdentifier; 1211}; 1212 1213SerializationReturnCode CloneSerializer::serialize(JSValue in) 1214{ 1215 Vector<uint32_t, 16> indexStack; 1216 Vector<uint32_t, 16> lengthStack; 1217 Vector<PropertyNameArray, 16> propertyStack; 1218 Vector<JSObject*, 32> inputObjectStack; 1219 Vector<MapData*, 4> mapDataStack; 1220 Vector<MapData::const_iterator, 4> iteratorStack; 1221 Vector<WalkerState, 16> stateStack; 1222 WalkerState state = StateUnknown; 1223 JSValue inValue = in; 1224 while (1) { 1225 switch (state) { 1226 arrayStartState: 1227 case ArrayStartState: { 1228 ASSERT(isArray(inValue)); 1229 if (inputObjectStack.size() > maximumFilterRecursion) 1230 return StackOverflowError; 1231 1232 JSArray* inArray = asArray(inValue); 1233 unsigned length = inArray->length(); 1234 if (!startArray(inArray)) 1235 break; 1236 inputObjectStack.append(inArray); 1237 indexStack.append(0); 1238 lengthStack.append(length); 1239 } 1240 arrayStartVisitMember: 1241 FALLTHROUGH; 1242 case ArrayStartVisitMember: { 1243 JSObject* array = inputObjectStack.last(); 1244 uint32_t index = indexStack.last(); 1245 if (index == lengthStack.last()) { 1246 indexStack.removeLast(); 1247 lengthStack.removeLast(); 1248 1249 propertyStack.append(PropertyNameArray(m_exec)); 1250 array->methodTable()->getOwnNonIndexPropertyNames(array, m_exec, propertyStack.last(), ExcludeDontEnumProperties); 1251 if (propertyStack.last().size()) { 1252 write(NonIndexPropertiesTag); 1253 indexStack.append(0); 1254 goto objectStartVisitMember; 1255 } 1256 propertyStack.removeLast(); 1257 1258 endObject(); 1259 inputObjectStack.removeLast(); 1260 break; 1261 } 1262 inValue = array->getDirectIndex(m_exec, index); 1263 if (!inValue) { 1264 indexStack.last()++; 1265 goto arrayStartVisitMember; 1266 } 1267 1268 write(index); 1269 SerializationReturnCode terminalCode = SuccessfullyCompleted; 1270 if (dumpIfTerminal(inValue, terminalCode)) { 1271 if (terminalCode != SuccessfullyCompleted) 1272 return terminalCode; 1273 indexStack.last()++; 1274 goto arrayStartVisitMember; 1275 } 1276 stateStack.append(ArrayEndVisitMember); 1277 goto stateUnknown; 1278 } 1279 case ArrayEndVisitMember: { 1280 indexStack.last()++; 1281 goto arrayStartVisitMember; 1282 } 1283 objectStartState: 1284 case ObjectStartState: { 1285 ASSERT(inValue.isObject()); 1286 if (inputObjectStack.size() > maximumFilterRecursion) 1287 return StackOverflowError; 1288 JSObject* inObject = asObject(inValue); 1289 if (!startObject(inObject)) 1290 break; 1291 // At this point, all supported objects other than Object 1292 // objects have been handled. If we reach this point and 1293 // the input is not an Object object then we should throw 1294 // a DataCloneError. 1295 if (inObject->classInfo() != JSFinalObject::info()) 1296 return DataCloneError; 1297 inputObjectStack.append(inObject); 1298 indexStack.append(0); 1299 propertyStack.append(PropertyNameArray(m_exec)); 1300 inObject->methodTable()->getOwnPropertyNames(inObject, m_exec, propertyStack.last(), ExcludeDontEnumProperties); 1301 } 1302 objectStartVisitMember: 1303 FALLTHROUGH; 1304 case ObjectStartVisitMember: { 1305 JSObject* object = inputObjectStack.last(); 1306 uint32_t index = indexStack.last(); 1307 PropertyNameArray& properties = propertyStack.last(); 1308 if (index == properties.size()) { 1309 endObject(); 1310 inputObjectStack.removeLast(); 1311 indexStack.removeLast(); 1312 propertyStack.removeLast(); 1313 break; 1314 } 1315 inValue = getProperty(object, properties[index]); 1316 if (shouldTerminate()) 1317 return ExistingExceptionError; 1318 1319 if (!inValue) { 1320 // Property was removed during serialisation 1321 indexStack.last()++; 1322 goto objectStartVisitMember; 1323 } 1324 write(properties[index]); 1325 1326 if (shouldTerminate()) 1327 return ExistingExceptionError; 1328 1329 SerializationReturnCode terminalCode = SuccessfullyCompleted; 1330 if (!dumpIfTerminal(inValue, terminalCode)) { 1331 stateStack.append(ObjectEndVisitMember); 1332 goto stateUnknown; 1333 } 1334 if (terminalCode != SuccessfullyCompleted) 1335 return terminalCode; 1336 FALLTHROUGH; 1337 } 1338 case ObjectEndVisitMember: { 1339 if (shouldTerminate()) 1340 return ExistingExceptionError; 1341 1342 indexStack.last()++; 1343 goto objectStartVisitMember; 1344 } 1345 mapStartState: { 1346 ASSERT(inValue.isObject()); 1347 if (inputObjectStack.size() > maximumFilterRecursion) 1348 return StackOverflowError; 1349 JSMap* inMap = jsCast<JSMap*>(inValue); 1350 if (!startMap(inMap)) 1351 break; 1352 MapData* mapData = inMap->mapData(); 1353 m_gcBuffer.append(mapData); 1354 mapDataStack.append(mapData); 1355 iteratorStack.append(mapData->begin()); 1356 inputObjectStack.append(inMap); 1357 goto mapDataStartVisitEntry; 1358 } 1359 setStartState: { 1360 ASSERT(inValue.isObject()); 1361 if (inputObjectStack.size() > maximumFilterRecursion) 1362 return StackOverflowError; 1363 JSSet* inSet = jsCast<JSSet*>(inValue); 1364 if (!startSet(inSet)) 1365 break; 1366 MapData* mapData = inSet->mapData(); 1367 m_gcBuffer.append(mapData); 1368 mapDataStack.append(mapData); 1369 iteratorStack.append(mapData->begin()); 1370 inputObjectStack.append(inSet); 1371 goto mapDataStartVisitEntry; 1372 } 1373 mapDataStartVisitEntry: 1374 case MapDataStartVisitEntry: { 1375 MapData::const_iterator& ptr = iteratorStack.last(); 1376 MapData* mapData = mapDataStack.last(); 1377 if (ptr == mapData->end()) { 1378 iteratorStack.removeLast(); 1379 mapDataStack.removeLast(); 1380 JSObject* object = inputObjectStack.last(); 1381 ASSERT(jsDynamicCast<JSSet*>(object) || jsDynamicCast<JSMap*>(object)); 1382 propertyStack.append(PropertyNameArray(m_exec)); 1383 object->methodTable()->getOwnPropertyNames(object, m_exec, propertyStack.last(), ExcludeDontEnumProperties); 1384 write(NonMapPropertiesTag); 1385 indexStack.append(0); 1386 goto objectStartVisitMember; 1387 } 1388 inValue = ptr.key(); 1389 stateStack.append(MapDataEndVisitKey); 1390 goto stateUnknown; 1391 } 1392 case MapDataEndVisitKey: { 1393 inValue = iteratorStack.last().value(); 1394 stateStack.append(MapDataEndVisitValue); 1395 goto stateUnknown; 1396 } 1397 case MapDataEndVisitValue: { 1398 ++iteratorStack.last(); 1399 goto mapDataStartVisitEntry; 1400 } 1401 1402 stateUnknown: 1403 case StateUnknown: { 1404 SerializationReturnCode terminalCode = SuccessfullyCompleted; 1405 if (dumpIfTerminal(inValue, terminalCode)) { 1406 if (terminalCode != SuccessfullyCompleted) 1407 return terminalCode; 1408 break; 1409 } 1410 1411 if (isArray(inValue)) 1412 goto arrayStartState; 1413 if (isMap(inValue)) 1414 goto mapStartState; 1415 if (isSet(inValue)) 1416 goto setStartState; 1417 goto objectStartState; 1418 } 1419 } 1420 if (stateStack.isEmpty()) 1421 break; 1422 1423 state = stateStack.last(); 1424 stateStack.removeLast(); 1425 } 1426 if (m_failed) 1427 return UnspecifiedError; 1428 1429 return SuccessfullyCompleted; 1430} 1431 1432typedef Vector<JSC::ArrayBufferContents> ArrayBufferContentsArray; 1433 1434class CloneDeserializer : CloneBase { 1435public: 1436 static String deserializeString(const Vector<uint8_t>& buffer) 1437 { 1438 if (buffer.isEmpty()) 1439 return String(); 1440 const uint8_t* ptr = buffer.begin(); 1441 const uint8_t* end = buffer.end(); 1442 uint32_t version; 1443 if (!readLittleEndian(ptr, end, version) || version > CurrentVersion) 1444 return String(); 1445 uint8_t tag; 1446 if (!readLittleEndian(ptr, end, tag) || tag != StringTag) 1447 return String(); 1448 uint32_t length; 1449 if (!readLittleEndian(ptr, end, length) || length >= StringPoolTag) 1450 return String(); 1451 String str; 1452 if (!readString(ptr, end, str, length)) 1453 return String(); 1454 return String(str.impl()); 1455 } 1456 1457 static DeserializationResult deserialize(ExecState* exec, JSGlobalObject* globalObject, 1458 MessagePortArray* messagePorts, ArrayBufferContentsArray* arrayBufferContentsArray, 1459 const Vector<uint8_t>& buffer) 1460 { 1461 if (!buffer.size()) 1462 return std::make_pair(jsNull(), UnspecifiedError); 1463 CloneDeserializer deserializer(exec, globalObject, messagePorts, arrayBufferContentsArray, buffer); 1464 if (!deserializer.isValid()) 1465 return std::make_pair(JSValue(), ValidationError); 1466 return deserializer.deserialize(); 1467 } 1468 1469private: 1470 struct CachedString { 1471 CachedString(const String& string) 1472 : m_string(string) 1473 { 1474 } 1475 1476 JSValue jsString(ExecState* exec) 1477 { 1478 if (!m_jsString) 1479 m_jsString = JSC::jsString(exec, m_string); 1480 return m_jsString; 1481 } 1482 const String& string() { return m_string; } 1483 1484 private: 1485 String m_string; 1486 JSValue m_jsString; 1487 }; 1488 1489 struct CachedStringRef { 1490 CachedStringRef() 1491 : m_base(0) 1492 , m_index(0) 1493 { 1494 } 1495 CachedStringRef(Vector<CachedString>* base, size_t index) 1496 : m_base(base) 1497 , m_index(index) 1498 { 1499 } 1500 1501 CachedString* operator->() { ASSERT(m_base); return &m_base->at(m_index); } 1502 1503 private: 1504 Vector<CachedString>* m_base; 1505 size_t m_index; 1506 }; 1507 1508 CloneDeserializer(ExecState* exec, JSGlobalObject* globalObject, 1509 MessagePortArray* messagePorts, ArrayBufferContentsArray* arrayBufferContents, 1510 const Vector<uint8_t>& buffer) 1511 : CloneBase(exec) 1512 , m_globalObject(globalObject) 1513 , m_isDOMGlobalObject(globalObject->inherits(JSDOMGlobalObject::info())) 1514 , m_ptr(buffer.data()) 1515 , m_end(buffer.data() + buffer.size()) 1516 , m_version(0xFFFFFFFF) 1517 , m_messagePorts(messagePorts) 1518 , m_arrayBufferContents(arrayBufferContents) 1519 , m_arrayBuffers(arrayBufferContents ? arrayBufferContents->size() : 0) 1520 { 1521 if (!read(m_version)) 1522 m_version = 0xFFFFFFFF; 1523 } 1524 1525 DeserializationResult deserialize(); 1526 1527 void throwValidationError() 1528 { 1529 m_exec->vm().throwException(m_exec, createTypeError(m_exec, "Unable to deserialize data.")); 1530 } 1531 1532 bool isValid() const { return m_version <= CurrentVersion; } 1533 1534 template <typename T> bool readLittleEndian(T& value) 1535 { 1536 if (m_failed || !readLittleEndian(m_ptr, m_end, value)) { 1537 fail(); 1538 return false; 1539 } 1540 return true; 1541 } 1542#if ASSUME_LITTLE_ENDIAN 1543 template <typename T> static bool readLittleEndian(const uint8_t*& ptr, const uint8_t* end, T& value) 1544 { 1545 if (ptr > end - sizeof(value)) 1546 return false; 1547 1548 if (sizeof(T) == 1) 1549 value = *ptr++; 1550 else { 1551 value = *reinterpret_cast<const T*>(ptr); 1552 ptr += sizeof(T); 1553 } 1554 return true; 1555 } 1556#else 1557 template <typename T> static bool readLittleEndian(const uint8_t*& ptr, const uint8_t* end, T& value) 1558 { 1559 if (ptr > end - sizeof(value)) 1560 return false; 1561 1562 if (sizeof(T) == 1) 1563 value = *ptr++; 1564 else { 1565 value = 0; 1566 for (unsigned i = 0; i < sizeof(T); i++) 1567 value += ((T)*ptr++) << (i * 8); 1568 } 1569 return true; 1570 } 1571#endif 1572 1573 bool read(uint32_t& i) 1574 { 1575 return readLittleEndian(i); 1576 } 1577 1578 bool read(int32_t& i) 1579 { 1580 return readLittleEndian(*reinterpret_cast<uint32_t*>(&i)); 1581 } 1582 1583 bool read(uint16_t& i) 1584 { 1585 return readLittleEndian(i); 1586 } 1587 1588 bool read(uint8_t& i) 1589 { 1590 return readLittleEndian(i); 1591 } 1592 1593 bool read(double& d) 1594 { 1595 union { 1596 double d; 1597 uint64_t i64; 1598 } u; 1599 if (!readLittleEndian(u.i64)) 1600 return false; 1601 d = u.d; 1602 return true; 1603 } 1604 1605 bool read(unsigned long long& i) 1606 { 1607 return readLittleEndian(i); 1608 } 1609 1610 bool readStringIndex(uint32_t& i) 1611 { 1612 return readConstantPoolIndex(m_constantPool, i); 1613 } 1614 1615 template <class T> bool readConstantPoolIndex(const T& constantPool, uint32_t& i) 1616 { 1617 if (constantPool.size() <= 0xFF) { 1618 uint8_t i8; 1619 if (!read(i8)) 1620 return false; 1621 i = i8; 1622 return true; 1623 } 1624 if (constantPool.size() <= 0xFFFF) { 1625 uint16_t i16; 1626 if (!read(i16)) 1627 return false; 1628 i = i16; 1629 return true; 1630 } 1631 return read(i); 1632 } 1633 1634 static bool readString(const uint8_t*& ptr, const uint8_t* end, String& str, unsigned length) 1635 { 1636 if (length >= std::numeric_limits<int32_t>::max() / sizeof(UChar)) 1637 return false; 1638 1639 unsigned size = length * sizeof(UChar); 1640 if ((end - ptr) < static_cast<int>(size)) 1641 return false; 1642 1643#if ASSUME_LITTLE_ENDIAN 1644 str = String(reinterpret_cast<const UChar*>(ptr), length); 1645 ptr += length * sizeof(UChar); 1646#else 1647 Vector<UChar> buffer; 1648 buffer.reserveCapacity(length); 1649 for (unsigned i = 0; i < length; i++) { 1650 uint16_t ch; 1651 readLittleEndian(ptr, end, ch); 1652 buffer.append(ch); 1653 } 1654 str = String::adopt(buffer); 1655#endif 1656 return true; 1657 } 1658 1659 bool readStringData(CachedStringRef& cachedString) 1660 { 1661 bool scratch; 1662 return readStringData(cachedString, scratch); 1663 } 1664 1665 bool readStringData(CachedStringRef& cachedString, bool& wasTerminator) 1666 { 1667 if (m_failed) 1668 return false; 1669 uint32_t length = 0; 1670 if (!read(length)) 1671 return false; 1672 if (length == TerminatorTag) { 1673 wasTerminator = true; 1674 return false; 1675 } 1676 if (length == StringPoolTag) { 1677 unsigned index = 0; 1678 if (!readStringIndex(index)) { 1679 fail(); 1680 return false; 1681 } 1682 if (index >= m_constantPool.size()) { 1683 fail(); 1684 return false; 1685 } 1686 cachedString = CachedStringRef(&m_constantPool, index); 1687 return true; 1688 } 1689 String str; 1690 if (!readString(m_ptr, m_end, str, length)) { 1691 fail(); 1692 return false; 1693 } 1694 m_constantPool.append(str); 1695 cachedString = CachedStringRef(&m_constantPool, m_constantPool.size() - 1); 1696 return true; 1697 } 1698 1699 SerializationTag readTag() 1700 { 1701 if (m_ptr >= m_end) 1702 return ErrorTag; 1703 return static_cast<SerializationTag>(*m_ptr++); 1704 } 1705 1706 bool readArrayBufferViewSubtag(ArrayBufferViewSubtag& tag) 1707 { 1708 if (m_ptr >= m_end) 1709 return false; 1710 tag = static_cast<ArrayBufferViewSubtag>(*m_ptr++); 1711 return true; 1712 } 1713 1714 void putProperty(JSObject* object, unsigned index, JSValue value) 1715 { 1716 object->putDirectIndex(m_exec, index, value); 1717 } 1718 1719 void putProperty(JSObject* object, const Identifier& property, JSValue value) 1720 { 1721 object->putDirectMayBeIndex(m_exec, property, value); 1722 } 1723 1724 bool readFile(RefPtr<File>& file) 1725 { 1726 CachedStringRef path; 1727 if (!readStringData(path)) 1728 return 0; 1729 CachedStringRef url; 1730 if (!readStringData(url)) 1731 return 0; 1732 CachedStringRef type; 1733 if (!readStringData(type)) 1734 return 0; 1735 CachedStringRef name; 1736 if (!readStringData(name)) 1737 return 0; 1738 if (m_isDOMGlobalObject) 1739 file = File::deserialize(path->string(), URL(URL(), url->string()), type->string(), name->string()); 1740 return true; 1741 } 1742 1743 bool readArrayBuffer(RefPtr<ArrayBuffer>& arrayBuffer) 1744 { 1745 uint32_t length; 1746 if (!read(length)) 1747 return false; 1748 if (m_ptr + length > m_end) 1749 return false; 1750 arrayBuffer = ArrayBuffer::create(m_ptr, length); 1751 m_ptr += length; 1752 return true; 1753 } 1754 1755 bool readArrayBufferView(JSValue& arrayBufferView) 1756 { 1757 ArrayBufferViewSubtag arrayBufferViewSubtag; 1758 if (!readArrayBufferViewSubtag(arrayBufferViewSubtag)) 1759 return false; 1760 uint32_t byteOffset; 1761 if (!read(byteOffset)) 1762 return false; 1763 uint32_t byteLength; 1764 if (!read(byteLength)) 1765 return false; 1766 JSObject* arrayBufferObj = asObject(readTerminal()); 1767 if (!arrayBufferObj || !arrayBufferObj->inherits(JSArrayBuffer::info())) 1768 return false; 1769 1770 unsigned elementSize = typedArrayElementSize(arrayBufferViewSubtag); 1771 if (!elementSize) 1772 return false; 1773 unsigned length = byteLength / elementSize; 1774 if (length * elementSize != byteLength) 1775 return false; 1776 1777 RefPtr<ArrayBuffer> arrayBuffer = toArrayBuffer(arrayBufferObj); 1778 switch (arrayBufferViewSubtag) { 1779 case DataViewTag: 1780 arrayBufferView = getJSValue(DataView::create(arrayBuffer, byteOffset, length).get()); 1781 return true; 1782 case Int8ArrayTag: 1783 arrayBufferView = getJSValue(Int8Array::create(arrayBuffer, byteOffset, length).get()); 1784 return true; 1785 case Uint8ArrayTag: 1786 arrayBufferView = getJSValue(Uint8Array::create(arrayBuffer, byteOffset, length).get()); 1787 return true; 1788 case Uint8ClampedArrayTag: 1789 arrayBufferView = getJSValue(Uint8ClampedArray::create(arrayBuffer, byteOffset, length).get()); 1790 return true; 1791 case Int16ArrayTag: 1792 arrayBufferView = getJSValue(Int16Array::create(arrayBuffer, byteOffset, length).get()); 1793 return true; 1794 case Uint16ArrayTag: 1795 arrayBufferView = getJSValue(Uint16Array::create(arrayBuffer, byteOffset, length).get()); 1796 return true; 1797 case Int32ArrayTag: 1798 arrayBufferView = getJSValue(Int32Array::create(arrayBuffer, byteOffset, length).get()); 1799 return true; 1800 case Uint32ArrayTag: 1801 arrayBufferView = getJSValue(Uint32Array::create(arrayBuffer, byteOffset, length).get()); 1802 return true; 1803 case Float32ArrayTag: 1804 arrayBufferView = getJSValue(Float32Array::create(arrayBuffer, byteOffset, length).get()); 1805 return true; 1806 case Float64ArrayTag: 1807 arrayBufferView = getJSValue(Float64Array::create(arrayBuffer, byteOffset, length).get()); 1808 return true; 1809 default: 1810 return false; 1811 } 1812 } 1813 1814 bool read(Vector<uint8_t>& result) 1815 { 1816 ASSERT(result.isEmpty()); 1817 uint32_t size; 1818 if (!read(size)) 1819 return false; 1820 if (m_ptr + size > m_end) 1821 return false; 1822 result.append(m_ptr, size); 1823 m_ptr += size; 1824 return true; 1825 } 1826 1827#if ENABLE(SUBTLE_CRYPTO) 1828 bool read(CryptoAlgorithmIdentifier& result) 1829 { 1830 uint8_t algorithmTag; 1831 if (!read(algorithmTag)) 1832 return false; 1833 if (algorithmTag > cryptoAlgorithmIdentifierTagMaximumValue) 1834 return false; 1835 switch (static_cast<CryptoAlgorithmIdentifierTag>(algorithmTag)) { 1836 case CryptoAlgorithmIdentifierTag::RSAES_PKCS1_v1_5: 1837 result = CryptoAlgorithmIdentifier::RSAES_PKCS1_v1_5; 1838 break; 1839 case CryptoAlgorithmIdentifierTag::RSASSA_PKCS1_v1_5: 1840 result = CryptoAlgorithmIdentifier::RSASSA_PKCS1_v1_5; 1841 break; 1842 case CryptoAlgorithmIdentifierTag::RSA_PSS: 1843 result = CryptoAlgorithmIdentifier::RSA_PSS; 1844 break; 1845 case CryptoAlgorithmIdentifierTag::RSA_OAEP: 1846 result = CryptoAlgorithmIdentifier::RSA_OAEP; 1847 break; 1848 case CryptoAlgorithmIdentifierTag::ECDSA: 1849 result = CryptoAlgorithmIdentifier::ECDSA; 1850 break; 1851 case CryptoAlgorithmIdentifierTag::ECDH: 1852 result = CryptoAlgorithmIdentifier::ECDH; 1853 break; 1854 case CryptoAlgorithmIdentifierTag::AES_CTR: 1855 result = CryptoAlgorithmIdentifier::AES_CTR; 1856 break; 1857 case CryptoAlgorithmIdentifierTag::AES_CBC: 1858 result = CryptoAlgorithmIdentifier::AES_CBC; 1859 break; 1860 case CryptoAlgorithmIdentifierTag::AES_CMAC: 1861 result = CryptoAlgorithmIdentifier::AES_CMAC; 1862 break; 1863 case CryptoAlgorithmIdentifierTag::AES_GCM: 1864 result = CryptoAlgorithmIdentifier::AES_GCM; 1865 break; 1866 case CryptoAlgorithmIdentifierTag::AES_CFB: 1867 result = CryptoAlgorithmIdentifier::AES_CFB; 1868 break; 1869 case CryptoAlgorithmIdentifierTag::AES_KW: 1870 result = CryptoAlgorithmIdentifier::AES_KW; 1871 break; 1872 case CryptoAlgorithmIdentifierTag::HMAC: 1873 result = CryptoAlgorithmIdentifier::HMAC; 1874 break; 1875 case CryptoAlgorithmIdentifierTag::DH: 1876 result = CryptoAlgorithmIdentifier::DH; 1877 break; 1878 case CryptoAlgorithmIdentifierTag::SHA_1: 1879 result = CryptoAlgorithmIdentifier::SHA_1; 1880 break; 1881 case CryptoAlgorithmIdentifierTag::SHA_224: 1882 result = CryptoAlgorithmIdentifier::SHA_224; 1883 break; 1884 case CryptoAlgorithmIdentifierTag::SHA_256: 1885 result = CryptoAlgorithmIdentifier::SHA_256; 1886 break; 1887 case CryptoAlgorithmIdentifierTag::SHA_384: 1888 result = CryptoAlgorithmIdentifier::SHA_384; 1889 break; 1890 case CryptoAlgorithmIdentifierTag::SHA_512: 1891 result = CryptoAlgorithmIdentifier::SHA_512; 1892 break; 1893 case CryptoAlgorithmIdentifierTag::CONCAT: 1894 result = CryptoAlgorithmIdentifier::CONCAT; 1895 break; 1896 case CryptoAlgorithmIdentifierTag::HKDF_CTR: 1897 result = CryptoAlgorithmIdentifier::HKDF_CTR; 1898 break; 1899 case CryptoAlgorithmIdentifierTag::PBKDF2: 1900 result = CryptoAlgorithmIdentifier::PBKDF2; 1901 break; 1902 } 1903 return true; 1904 } 1905 1906 bool read(CryptoKeyClassSubtag& result) 1907 { 1908 uint8_t tag; 1909 if (!read(tag)) 1910 return false; 1911 if (tag > cryptoKeyClassSubtagMaximumValue) 1912 return false; 1913 result = static_cast<CryptoKeyClassSubtag>(tag); 1914 return true; 1915 } 1916 1917 bool read(CryptoKeyUsageTag& result) 1918 { 1919 uint8_t tag; 1920 if (!read(tag)) 1921 return false; 1922 if (tag > cryptoKeyUsageTagMaximumValue) 1923 return false; 1924 result = static_cast<CryptoKeyUsageTag>(tag); 1925 return true; 1926 } 1927 1928 bool read(CryptoKeyAsymmetricTypeSubtag& result) 1929 { 1930 uint8_t tag; 1931 if (!read(tag)) 1932 return false; 1933 if (tag > cryptoKeyAsymmetricTypeSubtagMaximumValue) 1934 return false; 1935 result = static_cast<CryptoKeyAsymmetricTypeSubtag>(tag); 1936 return true; 1937 } 1938 1939 bool readHMACKey(bool extractable, CryptoKeyUsage usages, RefPtr<CryptoKey>& result) 1940 { 1941 Vector<uint8_t> keyData; 1942 if (!read(keyData)) 1943 return false; 1944 CryptoAlgorithmIdentifier hash; 1945 if (!read(hash)) 1946 return false; 1947 result = CryptoKeyHMAC::create(keyData, hash, extractable, usages); 1948 return true; 1949 } 1950 1951 bool readAESKey(bool extractable, CryptoKeyUsage usages, RefPtr<CryptoKey>& result) 1952 { 1953 CryptoAlgorithmIdentifier algorithm; 1954 if (!read(algorithm)) 1955 return false; 1956 if (!CryptoKeyAES::isValidAESAlgorithm(algorithm)) 1957 return false; 1958 Vector<uint8_t> keyData; 1959 if (!read(keyData)) 1960 return false; 1961 result = CryptoKeyAES::create(algorithm, keyData, extractable, usages); 1962 return true; 1963 } 1964 1965 bool readRSAKey(bool extractable, CryptoKeyUsage usages, RefPtr<CryptoKey>& result) 1966 { 1967 CryptoAlgorithmIdentifier algorithm; 1968 if (!read(algorithm)) 1969 return false; 1970 1971 int32_t isRestrictedToHash; 1972 CryptoAlgorithmIdentifier hash; 1973 if (!read(isRestrictedToHash)) 1974 return false; 1975 if (isRestrictedToHash && !read(hash)) 1976 return false; 1977 1978 CryptoKeyAsymmetricTypeSubtag type; 1979 if (!read(type)) 1980 return false; 1981 1982 Vector<uint8_t> modulus; 1983 if (!read(modulus)) 1984 return false; 1985 Vector<uint8_t> exponent; 1986 if (!read(exponent)) 1987 return false; 1988 1989 if (type == CryptoKeyAsymmetricTypeSubtag::Public) { 1990 auto keyData = CryptoKeyDataRSAComponents::createPublic(modulus, exponent); 1991 auto key = CryptoKeyRSA::create(algorithm, *keyData, extractable, usages); 1992 if (isRestrictedToHash) 1993 key->restrictToHash(hash); 1994 result = WTF::move(key); 1995 return true; 1996 } 1997 1998 Vector<uint8_t> privateExponent; 1999 if (!read(privateExponent)) 2000 return false; 2001 2002 uint32_t primeCount; 2003 if (!read(primeCount)) 2004 return false; 2005 2006 if (!primeCount) { 2007 auto keyData = CryptoKeyDataRSAComponents::createPrivate(modulus, exponent, privateExponent); 2008 auto key = CryptoKeyRSA::create(algorithm, *keyData, extractable, usages); 2009 if (isRestrictedToHash) 2010 key->restrictToHash(hash); 2011 result = WTF::move(key); 2012 return true; 2013 } 2014 2015 if (primeCount < 2) 2016 return false; 2017 2018 CryptoKeyDataRSAComponents::PrimeInfo firstPrimeInfo; 2019 CryptoKeyDataRSAComponents::PrimeInfo secondPrimeInfo; 2020 Vector<CryptoKeyDataRSAComponents::PrimeInfo> otherPrimeInfos(primeCount - 2); 2021 2022 if (!read(firstPrimeInfo.primeFactor)) 2023 return false; 2024 if (!read(firstPrimeInfo.factorCRTExponent)) 2025 return false; 2026 if (!read(secondPrimeInfo.primeFactor)) 2027 return false; 2028 if (!read(secondPrimeInfo.factorCRTExponent)) 2029 return false; 2030 if (!read(secondPrimeInfo.factorCRTCoefficient)) 2031 return false; 2032 for (unsigned i = 2; i < primeCount; ++i) { 2033 if (!read(otherPrimeInfos[i].primeFactor)) 2034 return false; 2035 if (!read(otherPrimeInfos[i].factorCRTExponent)) 2036 return false; 2037 if (!read(otherPrimeInfos[i].factorCRTCoefficient)) 2038 return false; 2039 } 2040 2041 auto keyData = CryptoKeyDataRSAComponents::createPrivateWithAdditionalData(modulus, exponent, privateExponent, firstPrimeInfo, secondPrimeInfo, otherPrimeInfos); 2042 auto key = CryptoKeyRSA::create(algorithm, *keyData, extractable, usages); 2043 if (isRestrictedToHash) 2044 key->restrictToHash(hash); 2045 result = WTF::move(key); 2046 return true; 2047 } 2048 2049 bool readCryptoKey(JSValue& cryptoKey) 2050 { 2051 uint32_t keyFormatVersion; 2052 if (!read(keyFormatVersion) || keyFormatVersion > currentKeyFormatVersion) 2053 return false; 2054 2055 int32_t extractable; 2056 if (!read(extractable)) 2057 return false; 2058 2059 uint32_t usagesCount; 2060 if (!read(usagesCount)) 2061 return false; 2062 2063 CryptoKeyUsage usages = 0; 2064 for (uint32_t i = 0; i < usagesCount; ++i) { 2065 CryptoKeyUsageTag usage; 2066 if (!read(usage)) 2067 return false; 2068 switch (usage) { 2069 case CryptoKeyUsageTag::Encrypt: 2070 usages |= CryptoKeyUsageEncrypt; 2071 break; 2072 case CryptoKeyUsageTag::Decrypt: 2073 usages |= CryptoKeyUsageDecrypt; 2074 break; 2075 case CryptoKeyUsageTag::Sign: 2076 usages |= CryptoKeyUsageSign; 2077 break; 2078 case CryptoKeyUsageTag::Verify: 2079 usages |= CryptoKeyUsageVerify; 2080 break; 2081 case CryptoKeyUsageTag::DeriveKey: 2082 usages |= CryptoKeyUsageDeriveKey; 2083 break; 2084 case CryptoKeyUsageTag::DeriveBits: 2085 usages |= CryptoKeyUsageDeriveBits; 2086 break; 2087 case CryptoKeyUsageTag::WrapKey: 2088 usages |= CryptoKeyUsageWrapKey; 2089 break; 2090 case CryptoKeyUsageTag::UnwrapKey: 2091 usages |= CryptoKeyUsageUnwrapKey; 2092 break; 2093 } 2094 } 2095 2096 CryptoKeyClassSubtag cryptoKeyClass; 2097 if (!read(cryptoKeyClass)) 2098 return false; 2099 RefPtr<CryptoKey> result; 2100 switch (cryptoKeyClass) { 2101 case CryptoKeyClassSubtag::HMAC: 2102 if (!readHMACKey(extractable, usages, result)) 2103 return false; 2104 break; 2105 case CryptoKeyClassSubtag::AES: 2106 if (!readAESKey(extractable, usages, result)) 2107 return false; 2108 break; 2109 case CryptoKeyClassSubtag::RSA: 2110 if (!readRSAKey(extractable, usages, result)) 2111 return false; 2112 break; 2113 } 2114 cryptoKey = getJSValue(result.get()); 2115 return true; 2116 } 2117#endif 2118 2119 template<class T> 2120 JSValue getJSValue(T* nativeObj) 2121 { 2122 return toJS(m_exec, jsCast<JSDOMGlobalObject*>(m_globalObject), nativeObj); 2123 } 2124 2125 JSValue readTerminal() 2126 { 2127 SerializationTag tag = readTag(); 2128 switch (tag) { 2129 case UndefinedTag: 2130 return jsUndefined(); 2131 case NullTag: 2132 return jsNull(); 2133 case IntTag: { 2134 int32_t i; 2135 if (!read(i)) 2136 return JSValue(); 2137 return jsNumber(i); 2138 } 2139 case ZeroTag: 2140 return jsNumber(0); 2141 case OneTag: 2142 return jsNumber(1); 2143 case FalseTag: 2144 return jsBoolean(false); 2145 case TrueTag: 2146 return jsBoolean(true); 2147 case FalseObjectTag: { 2148 BooleanObject* obj = BooleanObject::create(m_exec->vm(), m_globalObject->booleanObjectStructure()); 2149 obj->setInternalValue(m_exec->vm(), jsBoolean(false)); 2150 m_gcBuffer.append(obj); 2151 return obj; 2152 } 2153 case TrueObjectTag: { 2154 BooleanObject* obj = BooleanObject::create(m_exec->vm(), m_globalObject->booleanObjectStructure()); 2155 obj->setInternalValue(m_exec->vm(), jsBoolean(true)); 2156 m_gcBuffer.append(obj); 2157 return obj; 2158 } 2159 case DoubleTag: { 2160 double d; 2161 if (!read(d)) 2162 return JSValue(); 2163 return jsNumber(d); 2164 } 2165 case NumberObjectTag: { 2166 double d; 2167 if (!read(d)) 2168 return JSValue(); 2169 NumberObject* obj = constructNumber(m_exec, m_globalObject, jsNumber(d)); 2170 m_gcBuffer.append(obj); 2171 return obj; 2172 } 2173 case DateTag: { 2174 double d; 2175 if (!read(d)) 2176 return JSValue(); 2177 return DateInstance::create(m_exec->vm(), m_globalObject->dateStructure(), d); 2178 } 2179 case FileTag: { 2180 RefPtr<File> file; 2181 if (!readFile(file)) 2182 return JSValue(); 2183 if (!m_isDOMGlobalObject) 2184 return jsNull(); 2185 return toJS(m_exec, jsCast<JSDOMGlobalObject*>(m_globalObject), file.get()); 2186 } 2187 case FileListTag: { 2188 unsigned length = 0; 2189 if (!read(length)) 2190 return JSValue(); 2191 Vector<RefPtr<File>> files; 2192 for (unsigned i = 0; i < length; i++) { 2193 RefPtr<File> file; 2194 if (!readFile(file)) 2195 return JSValue(); 2196 if (m_isDOMGlobalObject) 2197 files.append(WTF::move(file)); 2198 } 2199 if (!m_isDOMGlobalObject) 2200 return jsNull(); 2201 return getJSValue(FileList::create(WTF::move(files)).get()); 2202 } 2203 case ImageDataTag: { 2204 int32_t width; 2205 if (!read(width)) 2206 return JSValue(); 2207 int32_t height; 2208 if (!read(height)) 2209 return JSValue(); 2210 uint32_t length; 2211 if (!read(length)) 2212 return JSValue(); 2213 if (m_end < ((uint8_t*)0) + length || m_ptr > m_end - length) { 2214 fail(); 2215 return JSValue(); 2216 } 2217 if (!m_isDOMGlobalObject) { 2218 m_ptr += length; 2219 return jsNull(); 2220 } 2221 RefPtr<ImageData> result = ImageData::create(IntSize(width, height)); 2222 memcpy(result->data()->data(), m_ptr, length); 2223 m_ptr += length; 2224 return getJSValue(result.get()); 2225 } 2226 case BlobTag: { 2227 CachedStringRef url; 2228 if (!readStringData(url)) 2229 return JSValue(); 2230 CachedStringRef type; 2231 if (!readStringData(type)) 2232 return JSValue(); 2233 unsigned long long size = 0; 2234 if (!read(size)) 2235 return JSValue(); 2236 if (!m_isDOMGlobalObject) 2237 return jsNull(); 2238 return getJSValue(Blob::deserialize(URL(URL(), url->string()), type->string(), size).get()); 2239 } 2240 case StringTag: { 2241 CachedStringRef cachedString; 2242 if (!readStringData(cachedString)) 2243 return JSValue(); 2244 return cachedString->jsString(m_exec); 2245 } 2246 case EmptyStringTag: 2247 return jsEmptyString(&m_exec->vm()); 2248 case StringObjectTag: { 2249 CachedStringRef cachedString; 2250 if (!readStringData(cachedString)) 2251 return JSValue(); 2252 StringObject* obj = constructString(m_exec->vm(), m_globalObject, cachedString->jsString(m_exec)); 2253 m_gcBuffer.append(obj); 2254 return obj; 2255 } 2256 case EmptyStringObjectTag: { 2257 VM& vm = m_exec->vm(); 2258 StringObject* obj = constructString(vm, m_globalObject, jsEmptyString(&vm)); 2259 m_gcBuffer.append(obj); 2260 return obj; 2261 } 2262 case RegExpTag: { 2263 CachedStringRef pattern; 2264 if (!readStringData(pattern)) 2265 return JSValue(); 2266 CachedStringRef flags; 2267 if (!readStringData(flags)) 2268 return JSValue(); 2269 RegExpFlags reFlags = regExpFlags(flags->string()); 2270 ASSERT(reFlags != InvalidFlags); 2271 VM& vm = m_exec->vm(); 2272 RegExp* regExp = RegExp::create(vm, pattern->string(), reFlags); 2273 return RegExpObject::create(vm, m_globalObject->regExpStructure(), regExp); 2274 } 2275 case ObjectReferenceTag: { 2276 unsigned index = 0; 2277 if (!readConstantPoolIndex(m_gcBuffer, index)) { 2278 fail(); 2279 return JSValue(); 2280 } 2281 return m_gcBuffer.at(index); 2282 } 2283 case MessagePortReferenceTag: { 2284 uint32_t index; 2285 bool indexSuccessfullyRead = read(index); 2286 if (!indexSuccessfullyRead || !m_messagePorts || index >= m_messagePorts->size()) { 2287 fail(); 2288 return JSValue(); 2289 } 2290 return getJSValue(m_messagePorts->at(index).get()); 2291 } 2292 case ArrayBufferTag: { 2293 RefPtr<ArrayBuffer> arrayBuffer; 2294 if (!readArrayBuffer(arrayBuffer)) { 2295 fail(); 2296 return JSValue(); 2297 } 2298 JSValue result = getJSValue(arrayBuffer.get()); 2299 m_gcBuffer.append(result); 2300 return result; 2301 } 2302 case ArrayBufferTransferTag: { 2303 uint32_t index; 2304 bool indexSuccessfullyRead = read(index); 2305 if (!indexSuccessfullyRead || index >= m_arrayBuffers.size()) { 2306 fail(); 2307 return JSValue(); 2308 } 2309 2310 if (!m_arrayBuffers[index]) 2311 m_arrayBuffers[index] = ArrayBuffer::create(m_arrayBufferContents->at(index)); 2312 2313 return getJSValue(m_arrayBuffers[index].get()); 2314 } 2315 case ArrayBufferViewTag: { 2316 JSValue arrayBufferView; 2317 if (!readArrayBufferView(arrayBufferView)) { 2318 fail(); 2319 return JSValue(); 2320 } 2321 m_gcBuffer.append(arrayBufferView); 2322 return arrayBufferView; 2323 } 2324#if ENABLE(SUBTLE_CRYPTO) 2325 case CryptoKeyTag: { 2326 Vector<uint8_t> wrappedKey; 2327 if (!read(wrappedKey)) { 2328 fail(); 2329 return JSValue(); 2330 } 2331 Vector<uint8_t> serializedKey; 2332 if (!unwrapCryptoKey(m_exec, wrappedKey, serializedKey)) { 2333 fail(); 2334 return JSValue(); 2335 } 2336 JSValue cryptoKey; 2337 CloneDeserializer rawKeyDeserializer(m_exec, m_globalObject, nullptr, nullptr, serializedKey); 2338 if (!rawKeyDeserializer.readCryptoKey(cryptoKey)) { 2339 fail(); 2340 return JSValue(); 2341 } 2342 m_gcBuffer.append(cryptoKey); 2343 return cryptoKey; 2344 } 2345#endif 2346 default: 2347 m_ptr--; // Push the tag back 2348 return JSValue(); 2349 } 2350 } 2351 2352 bool consumeMapDataTerminationIfPossible() 2353 { 2354 if (readTag() == NonMapPropertiesTag) 2355 return true; 2356 m_ptr--; 2357 return false; 2358 } 2359 2360 JSGlobalObject* m_globalObject; 2361 bool m_isDOMGlobalObject; 2362 const uint8_t* m_ptr; 2363 const uint8_t* m_end; 2364 unsigned m_version; 2365 Vector<CachedString> m_constantPool; 2366 MessagePortArray* m_messagePorts; 2367 ArrayBufferContentsArray* m_arrayBufferContents; 2368 ArrayBufferArray m_arrayBuffers; 2369}; 2370 2371DeserializationResult CloneDeserializer::deserialize() 2372{ 2373 Vector<uint32_t, 16> indexStack; 2374 Vector<Identifier, 16> propertyNameStack; 2375 Vector<JSObject*, 32> outputObjectStack; 2376 Vector<JSValue, 4> keyStack; 2377 Vector<MapData*, 4> mapDataStack; 2378 Vector<WalkerState, 16> stateStack; 2379 WalkerState state = StateUnknown; 2380 JSValue outValue; 2381 2382 while (1) { 2383 switch (state) { 2384 arrayStartState: 2385 case ArrayStartState: { 2386 uint32_t length; 2387 if (!read(length)) { 2388 fail(); 2389 goto error; 2390 } 2391 JSArray* outArray = constructEmptyArray(m_exec, 0, m_globalObject, length); 2392 m_gcBuffer.append(outArray); 2393 outputObjectStack.append(outArray); 2394 } 2395 arrayStartVisitMember: 2396 FALLTHROUGH; 2397 case ArrayStartVisitMember: { 2398 uint32_t index; 2399 if (!read(index)) { 2400 fail(); 2401 goto error; 2402 } 2403 if (index == TerminatorTag) { 2404 JSObject* outArray = outputObjectStack.last(); 2405 outValue = outArray; 2406 outputObjectStack.removeLast(); 2407 break; 2408 } else if (index == NonIndexPropertiesTag) { 2409 goto objectStartVisitMember; 2410 } 2411 2412 if (JSValue terminal = readTerminal()) { 2413 putProperty(outputObjectStack.last(), index, terminal); 2414 goto arrayStartVisitMember; 2415 } 2416 if (m_failed) 2417 goto error; 2418 indexStack.append(index); 2419 stateStack.append(ArrayEndVisitMember); 2420 goto stateUnknown; 2421 } 2422 case ArrayEndVisitMember: { 2423 JSObject* outArray = outputObjectStack.last(); 2424 putProperty(outArray, indexStack.last(), outValue); 2425 indexStack.removeLast(); 2426 goto arrayStartVisitMember; 2427 } 2428 objectStartState: 2429 case ObjectStartState: { 2430 if (outputObjectStack.size() > maximumFilterRecursion) 2431 return std::make_pair(JSValue(), StackOverflowError); 2432 JSObject* outObject = constructEmptyObject(m_exec, m_globalObject->objectPrototype()); 2433 m_gcBuffer.append(outObject); 2434 outputObjectStack.append(outObject); 2435 } 2436 objectStartVisitMember: 2437 FALLTHROUGH; 2438 case ObjectStartVisitMember: { 2439 CachedStringRef cachedString; 2440 bool wasTerminator = false; 2441 if (!readStringData(cachedString, wasTerminator)) { 2442 if (!wasTerminator) 2443 goto error; 2444 2445 JSObject* outObject = outputObjectStack.last(); 2446 outValue = outObject; 2447 outputObjectStack.removeLast(); 2448 break; 2449 } 2450 2451 if (JSValue terminal = readTerminal()) { 2452 putProperty(outputObjectStack.last(), Identifier(m_exec, cachedString->string()), terminal); 2453 goto objectStartVisitMember; 2454 } 2455 stateStack.append(ObjectEndVisitMember); 2456 propertyNameStack.append(Identifier(m_exec, cachedString->string())); 2457 goto stateUnknown; 2458 } 2459 case ObjectEndVisitMember: { 2460 putProperty(outputObjectStack.last(), propertyNameStack.last(), outValue); 2461 propertyNameStack.removeLast(); 2462 goto objectStartVisitMember; 2463 } 2464 mapObjectStartState: { 2465 if (outputObjectStack.size() > maximumFilterRecursion) 2466 return std::make_pair(JSValue(), StackOverflowError); 2467 JSMap* map = JSMap::create(m_exec->vm(), m_globalObject->mapStructure()); 2468 m_gcBuffer.append(map); 2469 outputObjectStack.append(map); 2470 MapData* mapData = map->mapData(); 2471 mapDataStack.append(mapData); 2472 goto mapDataStartVisitEntry; 2473 } 2474 setObjectStartState: { 2475 if (outputObjectStack.size() > maximumFilterRecursion) 2476 return std::make_pair(JSValue(), StackOverflowError); 2477 JSSet* set = JSSet::create(m_exec->vm(), m_globalObject->setStructure()); 2478 m_gcBuffer.append(set); 2479 outputObjectStack.append(set); 2480 MapData* mapData = set->mapData(); 2481 mapDataStack.append(mapData); 2482 goto mapDataStartVisitEntry; 2483 } 2484 mapDataStartVisitEntry: 2485 case MapDataStartVisitEntry: { 2486 if (consumeMapDataTerminationIfPossible()) { 2487 mapDataStack.removeLast(); 2488 goto objectStartVisitMember; 2489 } 2490 stateStack.append(MapDataEndVisitKey); 2491 goto stateUnknown; 2492 } 2493 2494 case MapDataEndVisitKey: { 2495 keyStack.append(outValue); 2496 stateStack.append(MapDataEndVisitValue); 2497 goto stateUnknown; 2498 } 2499 2500 case MapDataEndVisitValue: { 2501 mapDataStack.last()->set(m_exec, keyStack.last(), outValue); 2502 keyStack.removeLast(); 2503 goto mapDataStartVisitEntry; 2504 } 2505 stateUnknown: 2506 case StateUnknown: 2507 if (JSValue terminal = readTerminal()) { 2508 outValue = terminal; 2509 break; 2510 } 2511 SerializationTag tag = readTag(); 2512 if (tag == ArrayTag) 2513 goto arrayStartState; 2514 if (tag == ObjectTag) 2515 goto objectStartState; 2516 if (tag == MapObjectTag) 2517 goto mapObjectStartState; 2518 if (tag == SetObjectTag) 2519 goto setObjectStartState; 2520 goto error; 2521 } 2522 if (stateStack.isEmpty()) 2523 break; 2524 2525 state = stateStack.last(); 2526 stateStack.removeLast(); 2527 } 2528 ASSERT(outValue); 2529 ASSERT(!m_failed); 2530 return std::make_pair(outValue, SuccessfullyCompleted); 2531error: 2532 fail(); 2533 return std::make_pair(JSValue(), ValidationError); 2534} 2535 2536void SerializedScriptValue::addBlobURL(const String& string) 2537{ 2538 m_blobURLs.append(Vector<uint16_t>()); 2539 m_blobURLs.last().reserveCapacity(string.length()); 2540 for (size_t i = 0; i < string.length(); i++) 2541 m_blobURLs.last().append(string.characterAt(i)); 2542 m_blobURLs.last().resize(m_blobURLs.last().size()); 2543} 2544 2545SerializedScriptValue::~SerializedScriptValue() 2546{ 2547} 2548 2549SerializedScriptValue::SerializedScriptValue(const Vector<uint8_t>& buffer) 2550 : m_data(buffer) 2551{ 2552} 2553 2554SerializedScriptValue::SerializedScriptValue(Vector<uint8_t>& buffer) 2555{ 2556 m_data.swap(buffer); 2557} 2558 2559SerializedScriptValue::SerializedScriptValue(Vector<uint8_t>& buffer, Vector<String>& blobURLs) 2560{ 2561 m_data.swap(buffer); 2562 for (auto& string : blobURLs) 2563 addBlobURL(string); 2564} 2565 2566SerializedScriptValue::SerializedScriptValue(Vector<uint8_t>& buffer, Vector<String>& blobURLs, PassOwnPtr<ArrayBufferContentsArray> arrayBufferContentsArray) 2567 : m_arrayBufferContentsArray(arrayBufferContentsArray) 2568{ 2569 m_data.swap(buffer); 2570 for (auto& string : blobURLs) 2571 addBlobURL(string); 2572} 2573 2574PassOwnPtr<SerializedScriptValue::ArrayBufferContentsArray> SerializedScriptValue::transferArrayBuffers( 2575 ExecState* exec, ArrayBufferArray& arrayBuffers, SerializationReturnCode& code) 2576{ 2577 for (size_t i = 0; i < arrayBuffers.size(); i++) { 2578 if (arrayBuffers[i]->isNeutered()) { 2579 code = ValidationError; 2580 return nullptr; 2581 } 2582 } 2583 2584 OwnPtr<ArrayBufferContentsArray> contents = adoptPtr(new ArrayBufferContentsArray(arrayBuffers.size())); 2585 Vector<Ref<DOMWrapperWorld>> worlds; 2586 static_cast<WebCoreJSClientData*>(exec->vm().clientData)->getAllWorlds(worlds); 2587 2588 HashSet<JSC::ArrayBuffer*> visited; 2589 for (size_t arrayBufferIndex = 0; arrayBufferIndex < arrayBuffers.size(); arrayBufferIndex++) { 2590 if (visited.contains(arrayBuffers[arrayBufferIndex].get())) 2591 continue; 2592 visited.add(arrayBuffers[arrayBufferIndex].get()); 2593 2594 bool result = arrayBuffers[arrayBufferIndex]->transfer(contents->at(arrayBufferIndex)); 2595 if (!result) { 2596 code = ValidationError; 2597 return nullptr; 2598 } 2599 } 2600 return contents.release(); 2601} 2602 2603 2604PassRefPtr<SerializedScriptValue> SerializedScriptValue::create(ExecState* exec, JSValue value, 2605 MessagePortArray* messagePorts, ArrayBufferArray* arrayBuffers, 2606 SerializationErrorMode throwExceptions) 2607{ 2608 Vector<uint8_t> buffer; 2609 Vector<String> blobURLs; 2610 SerializationReturnCode code = CloneSerializer::serialize(exec, value, messagePorts, arrayBuffers, blobURLs, buffer); 2611 2612 OwnPtr<ArrayBufferContentsArray> arrayBufferContentsArray; 2613 2614 if (arrayBuffers && serializationDidCompleteSuccessfully(code)) 2615 arrayBufferContentsArray = transferArrayBuffers(exec, *arrayBuffers, code); 2616 2617 if (throwExceptions == Throwing) 2618 maybeThrowExceptionIfSerializationFailed(exec, code); 2619 2620 if (!serializationDidCompleteSuccessfully(code)) 2621 return 0; 2622 2623 return adoptRef(new SerializedScriptValue(buffer, blobURLs, arrayBufferContentsArray.release())); 2624} 2625 2626PassRefPtr<SerializedScriptValue> SerializedScriptValue::create(const String& string) 2627{ 2628 Vector<uint8_t> buffer; 2629 if (!CloneSerializer::serialize(string, buffer)) 2630 return 0; 2631 return adoptRef(new SerializedScriptValue(buffer)); 2632} 2633 2634#if ENABLE(INDEXED_DATABASE) 2635PassRefPtr<SerializedScriptValue> SerializedScriptValue::numberValue(double value) 2636{ 2637 Vector<uint8_t> buffer; 2638 CloneSerializer::serializeNumber(value, buffer); 2639 return adoptRef(new SerializedScriptValue(buffer)); 2640} 2641 2642PassRefPtr<SerializedScriptValue> SerializedScriptValue::undefinedValue() 2643{ 2644 Vector<uint8_t> buffer; 2645 CloneSerializer::serializeUndefined(buffer); 2646 return adoptRef(new SerializedScriptValue(buffer)); 2647} 2648#endif 2649 2650PassRefPtr<SerializedScriptValue> SerializedScriptValue::create(JSContextRef originContext, JSValueRef apiValue, JSValueRef* exception) 2651{ 2652 ExecState* exec = toJS(originContext); 2653 JSLockHolder locker(exec); 2654 JSValue value = toJS(exec, apiValue); 2655 RefPtr<SerializedScriptValue> serializedValue = SerializedScriptValue::create(exec, value, nullptr, nullptr); 2656 if (exec->hadException()) { 2657 if (exception) 2658 *exception = toRef(exec, exec->exception()); 2659 exec->clearException(); 2660 return 0; 2661 } 2662 ASSERT(serializedValue); 2663 return serializedValue.release(); 2664} 2665 2666String SerializedScriptValue::toString() 2667{ 2668 return CloneDeserializer::deserializeString(m_data); 2669} 2670 2671JSValue SerializedScriptValue::deserialize(ExecState* exec, JSGlobalObject* globalObject, 2672 MessagePortArray* messagePorts, SerializationErrorMode throwExceptions) 2673{ 2674 DeserializationResult result = CloneDeserializer::deserialize(exec, globalObject, messagePorts, 2675 m_arrayBufferContentsArray.get(), m_data); 2676 if (throwExceptions == Throwing) 2677 maybeThrowExceptionIfSerializationFailed(exec, result.second); 2678 return result.first ? result.first : jsNull(); 2679} 2680 2681JSValueRef SerializedScriptValue::deserialize(JSContextRef destinationContext, JSValueRef* exception) 2682{ 2683 ExecState* exec = toJS(destinationContext); 2684 JSLockHolder locker(exec); 2685 JSValue value = deserialize(exec, exec->lexicalGlobalObject(), nullptr); 2686 if (exec->hadException()) { 2687 if (exception) 2688 *exception = toRef(exec, exec->exception()); 2689 exec->clearException(); 2690 return nullptr; 2691 } 2692 ASSERT(value); 2693 return toRef(exec, value); 2694} 2695 2696PassRefPtr<SerializedScriptValue> SerializedScriptValue::nullValue() 2697{ 2698 Vector<uint8_t> buffer; 2699 return adoptRef(new SerializedScriptValue(buffer)); 2700} 2701 2702void SerializedScriptValue::maybeThrowExceptionIfSerializationFailed(ExecState* exec, SerializationReturnCode code) 2703{ 2704 if (code == SuccessfullyCompleted) 2705 return; 2706 2707 switch (code) { 2708 case StackOverflowError: 2709 exec->vm().throwException(exec, createStackOverflowError(exec)); 2710 break; 2711 case ValidationError: 2712 exec->vm().throwException(exec, createTypeError(exec, "Unable to deserialize data.")); 2713 break; 2714 case DataCloneError: 2715 setDOMException(exec, DATA_CLONE_ERR); 2716 break; 2717 case ExistingExceptionError: 2718 break; 2719 case UnspecifiedError: 2720 break; 2721 default: 2722 ASSERT_NOT_REACHED(); 2723 } 2724} 2725 2726bool SerializedScriptValue::serializationDidCompleteSuccessfully(SerializationReturnCode code) 2727{ 2728 return (code == SuccessfullyCompleted); 2729} 2730 2731uint32_t SerializedScriptValue::wireFormatVersion() 2732{ 2733 return CurrentVersion; 2734} 2735 2736} 2737