Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "config.h" | 5 #include "config.h" |
| 6 #include "bindings/core/v8/ScriptValueSerializer.h" | 6 #include "bindings/core/v8/ScriptValueSerializer.h" |
| 7 | 7 |
| 8 #include "bindings/core/v8/V8ArrayBuffer.h" | 8 #include "bindings/core/v8/V8ArrayBuffer.h" |
| 9 #include "bindings/core/v8/V8ArrayBufferView.h" | 9 #include "bindings/core/v8/V8ArrayBufferView.h" |
| 10 #include "bindings/core/v8/V8Blob.h" | 10 #include "bindings/core/v8/V8Blob.h" |
| 11 #include "bindings/core/v8/V8File.h" | 11 #include "bindings/core/v8/V8File.h" |
| 12 #include "bindings/core/v8/V8FileList.h" | 12 #include "bindings/core/v8/V8FileList.h" |
| 13 #include "bindings/core/v8/V8ImageData.h" | 13 #include "bindings/core/v8/V8ImageData.h" |
| 14 #include "bindings/core/v8/V8MessagePort.h" | 14 #include "bindings/core/v8/V8MessagePort.h" |
| 15 #include "bindings/modules/v8/V8CryptoKey.h" | |
| 16 #include "bindings/modules/v8/V8DOMFileSystem.h" | |
| 17 #include "core/dom/DOMDataView.h" | 15 #include "core/dom/DOMDataView.h" |
| 18 #include "core/fileapi/Blob.h" | 16 #include "core/fileapi/Blob.h" |
| 19 #include "core/fileapi/File.h" | 17 #include "core/fileapi/File.h" |
| 20 #include "core/fileapi/FileList.h" | 18 #include "core/fileapi/FileList.h" |
| 21 #include "public/platform/Platform.h" | 19 #include "public/platform/Platform.h" |
| 22 #include "public/platform/WebBlobInfo.h" | 20 #include "public/platform/WebBlobInfo.h" |
| 23 #include "wtf/ArrayBuffer.h" | 21 #include "wtf/ArrayBuffer.h" |
| 24 #include "wtf/ArrayBufferContents.h" | 22 #include "wtf/ArrayBufferContents.h" |
| 25 #include "wtf/ArrayBufferView.h" | 23 #include "wtf/ArrayBufferView.h" |
| 26 #include "wtf/text/StringHash.h" | 24 #include "wtf/text/StringHash.h" |
| (...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 190 } | 188 } |
| 191 | 189 |
| 192 void Writer::writeBlob(const String& uuid, const String& type, unsigned long lon g size) | 190 void Writer::writeBlob(const String& uuid, const String& type, unsigned long lon g size) |
| 193 { | 191 { |
| 194 append(BlobTag); | 192 append(BlobTag); |
| 195 doWriteWebCoreString(uuid); | 193 doWriteWebCoreString(uuid); |
| 196 doWriteWebCoreString(type); | 194 doWriteWebCoreString(type); |
| 197 doWriteUint64(size); | 195 doWriteUint64(size); |
| 198 } | 196 } |
| 199 | 197 |
| 200 void Writer::writeDOMFileSystem(int type, const String& name, const String& url) | |
| 201 { | |
| 202 append(DOMFileSystemTag); | |
| 203 doWriteUint32(type); | |
| 204 doWriteWebCoreString(name); | |
| 205 doWriteWebCoreString(url); | |
| 206 } | |
| 207 | |
|
tasak
2014/11/14 08:07:39
Moved to ScriptValueSerializerForModules.cpp
| |
| 208 void Writer::writeBlobIndex(int blobIndex) | 198 void Writer::writeBlobIndex(int blobIndex) |
| 209 { | 199 { |
| 210 ASSERT(blobIndex >= 0); | 200 ASSERT(blobIndex >= 0); |
| 211 append(BlobIndexTag); | 201 append(BlobIndexTag); |
| 212 doWriteUint32(blobIndex); | 202 doWriteUint32(blobIndex); |
| 213 } | 203 } |
| 214 | 204 |
| 215 void Writer::writeFile(const File& file) | 205 void Writer::writeFile(const File& file) |
| 216 { | 206 { |
| 217 append(FileTag); | 207 append(FileTag); |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 235 | 225 |
| 236 void Writer::writeFileListIndex(const Vector<int>& blobIndices) | 226 void Writer::writeFileListIndex(const Vector<int>& blobIndices) |
| 237 { | 227 { |
| 238 append(FileListIndexTag); | 228 append(FileListIndexTag); |
| 239 uint32_t length = blobIndices.size(); | 229 uint32_t length = blobIndices.size(); |
| 240 doWriteUint32(length); | 230 doWriteUint32(length); |
| 241 for (unsigned i = 0; i < length; ++i) | 231 for (unsigned i = 0; i < length; ++i) |
| 242 doWriteUint32(blobIndices[i]); | 232 doWriteUint32(blobIndices[i]); |
| 243 } | 233 } |
| 244 | 234 |
| 245 bool Writer::writeCryptoKey(const WebCryptoKey& key) | |
| 246 { | |
| 247 append(static_cast<uint8_t>(CryptoKeyTag)); | |
| 248 | |
| 249 switch (key.algorithm().paramsType()) { | |
| 250 case WebCryptoKeyAlgorithmParamsTypeAes: | |
| 251 doWriteAesKey(key); | |
| 252 break; | |
| 253 case WebCryptoKeyAlgorithmParamsTypeHmac: | |
| 254 doWriteHmacKey(key); | |
| 255 break; | |
| 256 case WebCryptoKeyAlgorithmParamsTypeRsaHashed: | |
| 257 doWriteRsaHashedKey(key); | |
| 258 break; | |
| 259 case WebCryptoKeyAlgorithmParamsTypeEc: | |
| 260 doWriteEcKey(key); | |
| 261 break; | |
| 262 case WebCryptoKeyAlgorithmParamsTypeNone: | |
| 263 ASSERT_NOT_REACHED(); | |
| 264 return false; | |
| 265 } | |
| 266 | |
| 267 doWriteKeyUsages(key.usages(), key.extractable()); | |
| 268 | |
| 269 WebVector<uint8_t> keyData; | |
| 270 if (!Platform::current()->crypto()->serializeKeyForClone(key, keyData)) | |
| 271 return false; | |
| 272 | |
| 273 doWriteUint32(keyData.size()); | |
| 274 append(keyData.data(), keyData.size()); | |
| 275 return true; | |
| 276 } | |
| 277 | |
| 278 void Writer::writeArrayBuffer(const ArrayBuffer& arrayBuffer) | 235 void Writer::writeArrayBuffer(const ArrayBuffer& arrayBuffer) |
| 279 { | 236 { |
| 280 append(ArrayBufferTag); | 237 append(ArrayBufferTag); |
| 281 doWriteArrayBuffer(arrayBuffer); | 238 doWriteArrayBuffer(arrayBuffer); |
| 282 } | 239 } |
| 283 | 240 |
| 284 void Writer::writeArrayBufferView(const ArrayBufferView& arrayBufferView) | 241 void Writer::writeArrayBufferView(const ArrayBufferView& arrayBufferView) |
| 285 { | 242 { |
| 286 append(ArrayBufferViewTag); | 243 append(ArrayBufferViewTag); |
| 287 #if ENABLE(ASSERT) | 244 #if ENABLE(ASSERT) |
| (...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 440 doWriteUint32(static_cast<uint32_t>(length)); | 397 doWriteUint32(static_cast<uint32_t>(length)); |
| 441 append(reinterpret_cast<const uint8_t*>(data), length); | 398 append(reinterpret_cast<const uint8_t*>(data), length); |
| 442 } | 399 } |
| 443 | 400 |
| 444 void Writer::doWriteWebCoreString(const String& string) | 401 void Writer::doWriteWebCoreString(const String& string) |
| 445 { | 402 { |
| 446 StringUTF8Adaptor stringUTF8(string); | 403 StringUTF8Adaptor stringUTF8(string); |
| 447 doWriteString(stringUTF8.data(), stringUTF8.length()); | 404 doWriteString(stringUTF8.data(), stringUTF8.length()); |
| 448 } | 405 } |
| 449 | 406 |
| 450 void Writer::doWriteHmacKey(const WebCryptoKey& key) | |
| 451 { | |
| 452 ASSERT(key.algorithm().paramsType() == WebCryptoKeyAlgorithmParamsTypeHmac); | |
| 453 | |
| 454 append(static_cast<uint8_t>(HmacKeyTag)); | |
| 455 ASSERT(!(key.algorithm().hmacParams()->lengthBits() % 8)); | |
| 456 doWriteUint32(key.algorithm().hmacParams()->lengthBits() / 8); | |
| 457 doWriteAlgorithmId(key.algorithm().hmacParams()->hash().id()); | |
| 458 } | |
| 459 | |
| 460 void Writer::doWriteAesKey(const WebCryptoKey& key) | |
| 461 { | |
| 462 ASSERT(key.algorithm().paramsType() == WebCryptoKeyAlgorithmParamsTypeAes); | |
| 463 | |
| 464 append(static_cast<uint8_t>(AesKeyTag)); | |
| 465 doWriteAlgorithmId(key.algorithm().id()); | |
| 466 // Converting the key length from bits to bytes is lossless and makes | |
| 467 // it fit in 1 byte. | |
| 468 ASSERT(!(key.algorithm().aesParams()->lengthBits() % 8)); | |
| 469 doWriteUint32(key.algorithm().aesParams()->lengthBits() / 8); | |
| 470 } | |
| 471 | |
| 472 void Writer::doWriteRsaHashedKey(const WebCryptoKey& key) | |
| 473 { | |
| 474 ASSERT(key.algorithm().rsaHashedParams()); | |
| 475 append(static_cast<uint8_t>(RsaHashedKeyTag)); | |
| 476 | |
| 477 doWriteAlgorithmId(key.algorithm().id()); | |
| 478 doWriteAsymmetricKeyType(key.type()); | |
| 479 | |
| 480 const WebCryptoRsaHashedKeyAlgorithmParams* params = key.algorithm().rsaHash edParams(); | |
| 481 doWriteUint32(params->modulusLengthBits()); | |
| 482 doWriteUint32(params->publicExponent().size()); | |
| 483 append(params->publicExponent().data(), params->publicExponent().size()); | |
| 484 doWriteAlgorithmId(params->hash().id()); | |
| 485 } | |
| 486 | |
| 487 void Writer::doWriteEcKey(const WebCryptoKey& key) | |
| 488 { | |
| 489 ASSERT(key.algorithm().ecParams()); | |
| 490 append(static_cast<uint8_t>(EcKeyTag)); | |
| 491 | |
| 492 doWriteAlgorithmId(key.algorithm().id()); | |
| 493 doWriteAsymmetricKeyType(key.type()); | |
| 494 doWriteNamedCurve(key.algorithm().ecParams()->namedCurve()); | |
| 495 } | |
| 496 | |
| 497 void Writer::doWriteAlgorithmId(WebCryptoAlgorithmId id) | |
| 498 { | |
| 499 switch (id) { | |
| 500 case WebCryptoAlgorithmIdAesCbc: | |
| 501 return doWriteUint32(AesCbcTag); | |
| 502 case WebCryptoAlgorithmIdHmac: | |
| 503 return doWriteUint32(HmacTag); | |
| 504 case WebCryptoAlgorithmIdRsaSsaPkcs1v1_5: | |
| 505 return doWriteUint32(RsaSsaPkcs1v1_5Tag); | |
| 506 case WebCryptoAlgorithmIdSha1: | |
| 507 return doWriteUint32(Sha1Tag); | |
| 508 case WebCryptoAlgorithmIdSha256: | |
| 509 return doWriteUint32(Sha256Tag); | |
| 510 case WebCryptoAlgorithmIdSha384: | |
| 511 return doWriteUint32(Sha384Tag); | |
| 512 case WebCryptoAlgorithmIdSha512: | |
| 513 return doWriteUint32(Sha512Tag); | |
| 514 case WebCryptoAlgorithmIdAesGcm: | |
| 515 return doWriteUint32(AesGcmTag); | |
| 516 case WebCryptoAlgorithmIdRsaOaep: | |
| 517 return doWriteUint32(RsaOaepTag); | |
| 518 case WebCryptoAlgorithmIdAesCtr: | |
| 519 return doWriteUint32(AesCtrTag); | |
| 520 case WebCryptoAlgorithmIdAesKw: | |
| 521 return doWriteUint32(AesKwTag); | |
| 522 case WebCryptoAlgorithmIdRsaPss: | |
| 523 return doWriteUint32(RsaPssTag); | |
| 524 case WebCryptoAlgorithmIdEcdsa: | |
| 525 return doWriteUint32(EcdsaTag); | |
| 526 } | |
| 527 ASSERT_NOT_REACHED(); | |
| 528 } | |
| 529 | |
| 530 void Writer::doWriteAsymmetricKeyType(WebCryptoKeyType keyType) | |
| 531 { | |
| 532 switch (keyType) { | |
| 533 case WebCryptoKeyTypePublic: | |
| 534 doWriteUint32(PublicKeyType); | |
| 535 break; | |
| 536 case WebCryptoKeyTypePrivate: | |
| 537 doWriteUint32(PrivateKeyType); | |
| 538 break; | |
| 539 case WebCryptoKeyTypeSecret: | |
| 540 ASSERT_NOT_REACHED(); | |
| 541 } | |
| 542 } | |
| 543 | |
| 544 void Writer::doWriteNamedCurve(WebCryptoNamedCurve namedCurve) | |
| 545 { | |
| 546 switch (namedCurve) { | |
| 547 case WebCryptoNamedCurveP256: | |
| 548 return doWriteUint32(P256Tag); | |
| 549 case WebCryptoNamedCurveP384: | |
| 550 return doWriteUint32(P384Tag); | |
| 551 case WebCryptoNamedCurveP521: | |
| 552 return doWriteUint32(P521Tag); | |
| 553 } | |
| 554 ASSERT_NOT_REACHED(); | |
| 555 } | |
| 556 | |
| 557 void Writer::doWriteKeyUsages(const WebCryptoKeyUsageMask usages, bool extractab le) | |
| 558 { | |
| 559 // Reminder to update this when adding new key usages. | |
| 560 COMPILE_ASSERT(EndOfWebCryptoKeyUsage == (1 << 7) + 1, UpdateMe); | |
| 561 | |
| 562 uint32_t value = 0; | |
| 563 | |
| 564 if (extractable) | |
| 565 value |= ExtractableUsage; | |
| 566 | |
| 567 if (usages & WebCryptoKeyUsageEncrypt) | |
| 568 value |= EncryptUsage; | |
| 569 if (usages & WebCryptoKeyUsageDecrypt) | |
| 570 value |= DecryptUsage; | |
| 571 if (usages & WebCryptoKeyUsageSign) | |
| 572 value |= SignUsage; | |
| 573 if (usages & WebCryptoKeyUsageVerify) | |
| 574 value |= VerifyUsage; | |
| 575 if (usages & WebCryptoKeyUsageDeriveKey) | |
| 576 value |= DeriveKeyUsage; | |
| 577 if (usages & WebCryptoKeyUsageWrapKey) | |
| 578 value |= WrapKeyUsage; | |
| 579 if (usages & WebCryptoKeyUsageUnwrapKey) | |
| 580 value |= UnwrapKeyUsage; | |
| 581 if (usages & WebCryptoKeyUsageDeriveBits) | |
| 582 value |= DeriveBitsUsage; | |
| 583 | |
| 584 doWriteUint32(value); | |
| 585 } | |
| 586 | |
| 587 int Writer::bytesNeededToWireEncode(uint32_t value) | 407 int Writer::bytesNeededToWireEncode(uint32_t value) |
| 588 { | 408 { |
| 589 int bytes = 1; | 409 int bytes = 1; |
| 590 while (true) { | 410 while (true) { |
| 591 value >>= SerializedScriptValue::varIntShift; | 411 value >>= SerializedScriptValue::varIntShift; |
| 592 if (!value) | 412 if (!value) |
| 593 break; | 413 break; |
| 594 ++bytes; | 414 ++bytes; |
| 595 } | 415 } |
| 596 | 416 |
| (...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 861 } else if (value->IsNumberObject()) { | 681 } else if (value->IsNumberObject()) { |
| 862 writeNumberObject(value); | 682 writeNumberObject(value); |
| 863 } else if (value->IsBooleanObject()) { | 683 } else if (value->IsBooleanObject()) { |
| 864 writeBooleanObject(value); | 684 writeBooleanObject(value); |
| 865 } else if (value->IsArray()) { | 685 } else if (value->IsArray()) { |
| 866 return startArrayState(value.As<v8::Array>(), next); | 686 return startArrayState(value.As<v8::Array>(), next); |
| 867 } else if (V8File::hasInstance(value, isolate())) { | 687 } else if (V8File::hasInstance(value, isolate())) { |
| 868 return writeFile(value, next); | 688 return writeFile(value, next); |
| 869 } else if (V8Blob::hasInstance(value, isolate())) { | 689 } else if (V8Blob::hasInstance(value, isolate())) { |
| 870 return writeBlob(value, next); | 690 return writeBlob(value, next); |
| 871 } else if (V8DOMFileSystem::hasInstance(value, isolate())) { | |
| 872 return writeDOMFileSystem(value, next); | |
| 873 } else if (V8FileList::hasInstance(value, isolate())) { | 691 } else if (V8FileList::hasInstance(value, isolate())) { |
| 874 return writeFileList(value, next); | 692 return writeFileList(value, next); |
| 875 } else if (V8CryptoKey::hasInstance(value, isolate())) { | |
| 876 if (!writeCryptoKey(value)) | |
| 877 return handleError(DataCloneError, "Couldn't serialize key data" , next); | |
| 878 } else if (V8ImageData::hasInstance(value, isolate())) { | 693 } else if (V8ImageData::hasInstance(value, isolate())) { |
| 879 writeImageData(value); | 694 writeImageData(value); |
| 880 } else if (value->IsRegExp()) { | 695 } else if (value->IsRegExp()) { |
| 881 writeRegExp(value); | 696 writeRegExp(value); |
| 882 } else if (V8ArrayBuffer::hasInstance(value, isolate())) { | 697 } else if (V8ArrayBuffer::hasInstance(value, isolate())) { |
| 883 return writeArrayBuffer(value, next); | 698 return writeArrayBuffer(value, next); |
| 884 } else if (value->IsObject()) { | 699 } else if (value->IsObject()) { |
| 885 if (isHostObject(jsObject) || jsObject->IsCallable() || value->IsNat iveError()) | 700 if (isHostObject(jsObject) || jsObject->IsCallable() || value->IsNat iveError()) |
| 886 return handleError(DataCloneError, "An object could not be clone d.", next); | 701 return handleError(DataCloneError, "An object could not be clone d.", next); |
| 887 return startObjectState(jsObject, next); | 702 return startObjectState(jsObject, next); |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 985 return handleError(DataCloneError, "A Blob object has been closed, and c ould therefore not be cloned.", next); | 800 return handleError(DataCloneError, "A Blob object has been closed, and c ould therefore not be cloned.", next); |
| 986 int blobIndex = -1; | 801 int blobIndex = -1; |
| 987 m_blobDataHandles.set(blob->uuid(), blob->blobDataHandle()); | 802 m_blobDataHandles.set(blob->uuid(), blob->blobDataHandle()); |
| 988 if (appendBlobInfo(blob->uuid(), blob->type(), blob->size(), &blobIndex)) | 803 if (appendBlobInfo(blob->uuid(), blob->type(), blob->size(), &blobIndex)) |
| 989 m_writer.writeBlobIndex(blobIndex); | 804 m_writer.writeBlobIndex(blobIndex); |
| 990 else | 805 else |
| 991 m_writer.writeBlob(blob->uuid(), blob->type(), blob->size()); | 806 m_writer.writeBlob(blob->uuid(), blob->type(), blob->size()); |
| 992 return 0; | 807 return 0; |
| 993 } | 808 } |
| 994 | 809 |
| 995 Serializer::StateBase* Serializer::writeDOMFileSystem(v8::Handle<v8::Value> valu e, StateBase* next) | |
| 996 { | |
| 997 DOMFileSystem* fs = V8DOMFileSystem::toImpl(value.As<v8::Object>()); | |
| 998 if (!fs) | |
| 999 return 0; | |
| 1000 if (!fs->clonable()) | |
| 1001 return handleError(DataCloneError, "A FileSystem object could not be clo ned.", next); | |
| 1002 m_writer.writeDOMFileSystem(fs->type(), fs->name(), fs->rootURL().string()); | |
| 1003 return 0; | |
| 1004 } | |
| 1005 | |
| 1006 Serializer::StateBase* Serializer::writeFile(v8::Handle<v8::Value> value, Serial izer::StateBase* next) | 810 Serializer::StateBase* Serializer::writeFile(v8::Handle<v8::Value> value, Serial izer::StateBase* next) |
| 1007 { | 811 { |
| 1008 File* file = V8File::toImpl(value.As<v8::Object>()); | 812 File* file = V8File::toImpl(value.As<v8::Object>()); |
| 1009 if (!file) | 813 if (!file) |
| 1010 return 0; | 814 return 0; |
| 1011 if (file->hasBeenClosed()) | 815 if (file->hasBeenClosed()) |
| 1012 return handleError(DataCloneError, "A File object has been closed, and c ould therefore not be cloned.", next); | 816 return handleError(DataCloneError, "A File object has been closed, and c ould therefore not be cloned.", next); |
| 1013 int blobIndex = -1; | 817 int blobIndex = -1; |
| 1014 m_blobDataHandles.set(file->uuid(), file->blobDataHandle()); | 818 m_blobDataHandles.set(file->uuid(), file->blobDataHandle()); |
| 1015 if (appendFileInfo(file, &blobIndex)) { | 819 if (appendFileInfo(file, &blobIndex)) { |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 1040 blobIndices.append(blobIndex); | 844 blobIndices.append(blobIndex); |
| 1041 } | 845 } |
| 1042 } | 846 } |
| 1043 if (!blobIndices.isEmpty()) | 847 if (!blobIndices.isEmpty()) |
| 1044 m_writer.writeFileListIndex(blobIndices); | 848 m_writer.writeFileListIndex(blobIndices); |
| 1045 else | 849 else |
| 1046 m_writer.writeFileList(*fileList); | 850 m_writer.writeFileList(*fileList); |
| 1047 return 0; | 851 return 0; |
| 1048 } | 852 } |
| 1049 | 853 |
| 1050 bool Serializer::writeCryptoKey(v8::Handle<v8::Value> value) | |
| 1051 { | |
| 1052 CryptoKey* key = V8CryptoKey::toImpl(value.As<v8::Object>()); | |
| 1053 if (!key) | |
| 1054 return false; | |
| 1055 return m_writer.writeCryptoKey(key->key()); | |
| 1056 } | |
| 1057 | |
| 1058 void Serializer::writeImageData(v8::Handle<v8::Value> value) | 854 void Serializer::writeImageData(v8::Handle<v8::Value> value) |
| 1059 { | 855 { |
| 1060 ImageData* imageData = V8ImageData::toImpl(value.As<v8::Object>()); | 856 ImageData* imageData = V8ImageData::toImpl(value.As<v8::Object>()); |
| 1061 if (!imageData) | 857 if (!imageData) |
| 1062 return; | 858 return; |
| 1063 Uint8ClampedArray* pixelArray = imageData->data(); | 859 Uint8ClampedArray* pixelArray = imageData->data(); |
| 1064 m_writer.writeImageData(imageData->width(), imageData->height(), pixelArray- >data(), pixelArray->length()); | 860 m_writer.writeImageData(imageData->width(), imageData->height(), pixelArray- >data(), pixelArray->length()); |
| 1065 } | 861 } |
| 1066 | 862 |
| 1067 void Serializer::writeRegExp(v8::Handle<v8::Value> value) | 863 void Serializer::writeRegExp(v8::Handle<v8::Value> value) |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1183 *index = m_blobInfo->size(); | 979 *index = m_blobInfo->size(); |
| 1184 m_blobInfo->append(WebBlobInfo(file->uuid(), file->path(), file->name(), fil e->type(), lastModified, size)); | 980 m_blobInfo->append(WebBlobInfo(file->uuid(), file->path(), file->name(), fil e->type(), lastModified, size)); |
| 1185 return true; | 981 return true; |
| 1186 } | 982 } |
| 1187 | 983 |
| 1188 bool Reader::read(v8::Handle<v8::Value>* value, CompositeCreator& creator) | 984 bool Reader::read(v8::Handle<v8::Value>* value, CompositeCreator& creator) |
| 1189 { | 985 { |
| 1190 SerializationTag tag; | 986 SerializationTag tag; |
| 1191 if (!readTag(&tag)) | 987 if (!readTag(&tag)) |
| 1192 return false; | 988 return false; |
| 989 return readWithTag(tag, value, creator); | |
| 990 } | |
| 991 | |
| 992 bool Reader::readWithTag(SerializationTag tag, v8::Handle<v8::Value>* value, Com positeCreator& creator) | |
| 993 { | |
| 1193 switch (tag) { | 994 switch (tag) { |
| 1194 case ReferenceCountTag: { | 995 case ReferenceCountTag: { |
| 1195 if (!m_version) | 996 if (!m_version) |
| 1196 return false; | 997 return false; |
| 1197 uint32_t referenceTableSize; | 998 uint32_t referenceTableSize; |
| 1198 if (!doReadUint32(&referenceTableSize)) | 999 if (!doReadUint32(&referenceTableSize)) |
| 1199 return false; | 1000 return false; |
| 1200 // If this test fails, then the serializer and deserializer disagree abo ut the assignment | 1001 // If this test fails, then the serializer and deserializer disagree abo ut the assignment |
| 1201 // of object reference IDs. On the deserialization side, this means ther e are too many or too few | 1002 // of object reference IDs. On the deserialization side, this means ther e are too many or too few |
| 1202 // calls to pushObjectReference. | 1003 // calls to pushObjectReference. |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1268 if (!readBlob(value, tag == BlobIndexTag)) | 1069 if (!readBlob(value, tag == BlobIndexTag)) |
| 1269 return false; | 1070 return false; |
| 1270 creator.pushObjectReference(*value); | 1071 creator.pushObjectReference(*value); |
| 1271 break; | 1072 break; |
| 1272 case FileTag: | 1073 case FileTag: |
| 1273 case FileIndexTag: | 1074 case FileIndexTag: |
| 1274 if (!readFile(value, tag == FileIndexTag)) | 1075 if (!readFile(value, tag == FileIndexTag)) |
| 1275 return false; | 1076 return false; |
| 1276 creator.pushObjectReference(*value); | 1077 creator.pushObjectReference(*value); |
| 1277 break; | 1078 break; |
| 1278 case DOMFileSystemTag: | |
| 1279 if (!readDOMFileSystem(value)) | |
| 1280 return false; | |
| 1281 creator.pushObjectReference(*value); | |
| 1282 break; | |
| 1283 case FileListTag: | 1079 case FileListTag: |
| 1284 case FileListIndexTag: | 1080 case FileListIndexTag: |
| 1285 if (!readFileList(value, tag == FileListIndexTag)) | 1081 if (!readFileList(value, tag == FileListIndexTag)) |
| 1286 return false; | 1082 return false; |
| 1287 creator.pushObjectReference(*value); | 1083 creator.pushObjectReference(*value); |
| 1288 break; | 1084 break; |
| 1289 case CryptoKeyTag: | |
| 1290 if (!readCryptoKey(value)) | |
| 1291 return false; | |
| 1292 creator.pushObjectReference(*value); | |
| 1293 break; | |
| 1294 case ImageDataTag: | 1085 case ImageDataTag: |
| 1295 if (!readImageData(value)) | 1086 if (!readImageData(value)) |
| 1296 return false; | 1087 return false; |
| 1297 creator.pushObjectReference(*value); | 1088 creator.pushObjectReference(*value); |
| 1298 break; | 1089 break; |
| 1299 | 1090 |
| 1300 case RegExpTag: | 1091 case RegExpTag: |
| 1301 if (!readRegExp(value)) | 1092 if (!readRegExp(value)) |
| 1302 return false; | 1093 return false; |
| 1303 creator.pushObjectReference(*value); | 1094 creator.pushObjectReference(*value); |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1398 case ObjectReferenceTag: { | 1189 case ObjectReferenceTag: { |
| 1399 if (!m_version) | 1190 if (!m_version) |
| 1400 return false; | 1191 return false; |
| 1401 uint32_t reference; | 1192 uint32_t reference; |
| 1402 if (!doReadUint32(&reference)) | 1193 if (!doReadUint32(&reference)) |
| 1403 return false; | 1194 return false; |
| 1404 if (!creator.tryGetObjectFromObjectReference(reference, value)) | 1195 if (!creator.tryGetObjectFromObjectReference(reference, value)) |
| 1405 return false; | 1196 return false; |
| 1406 break; | 1197 break; |
| 1407 } | 1198 } |
| 1199 case DOMFileSystemTag: | |
| 1200 case CryptoKeyTag: | |
| 1201 ASSERT_NOT_REACHED(); | |
| 1408 default: | 1202 default: |
| 1409 return false; | 1203 return false; |
| 1410 } | 1204 } |
| 1411 return !value->IsEmpty(); | 1205 return !value->IsEmpty(); |
| 1412 } | 1206 } |
| 1413 | 1207 |
| 1414 bool Reader::readVersion(uint32_t& version) | 1208 bool Reader::readVersion(uint32_t& version) |
| 1415 { | 1209 { |
| 1416 SerializationTag tag; | 1210 SerializationTag tag; |
| 1417 if (!readTag(&tag)) { | 1211 if (!readTag(&tag)) { |
| (...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1715 if (!readWebCoreString(&type)) | 1509 if (!readWebCoreString(&type)) |
| 1716 return false; | 1510 return false; |
| 1717 if (!doReadUint64(&size)) | 1511 if (!doReadUint64(&size)) |
| 1718 return false; | 1512 return false; |
| 1719 blob = Blob::create(getOrCreateBlobDataHandle(uuid, type, size)); | 1513 blob = Blob::create(getOrCreateBlobDataHandle(uuid, type, size)); |
| 1720 } | 1514 } |
| 1721 *value = toV8(blob, m_scriptState->context()->Global(), isolate()); | 1515 *value = toV8(blob, m_scriptState->context()->Global(), isolate()); |
| 1722 return true; | 1516 return true; |
| 1723 } | 1517 } |
| 1724 | 1518 |
| 1725 bool Reader::readDOMFileSystem(v8::Handle<v8::Value>* value) | |
| 1726 { | |
| 1727 uint32_t type; | |
| 1728 String name; | |
| 1729 String url; | |
| 1730 if (!doReadUint32(&type)) | |
| 1731 return false; | |
| 1732 if (!readWebCoreString(&name)) | |
| 1733 return false; | |
| 1734 if (!readWebCoreString(&url)) | |
| 1735 return false; | |
| 1736 DOMFileSystem* fs = DOMFileSystem::create(m_scriptState->executionContext(), name, static_cast<FileSystemType>(type), KURL(ParsedURLString, url)); | |
| 1737 *value = toV8(fs, m_scriptState->context()->Global(), isolate()); | |
| 1738 return true; | |
| 1739 } | |
| 1740 | |
| 1741 bool Reader::readFile(v8::Handle<v8::Value>* value, bool isIndexed) | 1519 bool Reader::readFile(v8::Handle<v8::Value>* value, bool isIndexed) |
| 1742 { | 1520 { |
| 1743 File* file = nullptr; | 1521 File* file = nullptr; |
| 1744 if (isIndexed) { | 1522 if (isIndexed) { |
| 1745 if (m_version < 6) | 1523 if (m_version < 6) |
| 1746 return false; | 1524 return false; |
| 1747 file = readFileIndexHelper(); | 1525 file = readFileIndexHelper(); |
| 1748 } else { | 1526 } else { |
| 1749 file = readFileHelper(); | 1527 file = readFileHelper(); |
| 1750 } | 1528 } |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 1772 file = readFileHelper(); | 1550 file = readFileHelper(); |
| 1773 } | 1551 } |
| 1774 if (!file) | 1552 if (!file) |
| 1775 return false; | 1553 return false; |
| 1776 fileList->append(file); | 1554 fileList->append(file); |
| 1777 } | 1555 } |
| 1778 *value = toV8(fileList, m_scriptState->context()->Global(), isolate()); | 1556 *value = toV8(fileList, m_scriptState->context()->Global(), isolate()); |
| 1779 return true; | 1557 return true; |
| 1780 } | 1558 } |
| 1781 | 1559 |
| 1782 bool Reader::readCryptoKey(v8::Handle<v8::Value>* value) | |
| 1783 { | |
| 1784 uint32_t rawKeyType; | |
| 1785 if (!doReadUint32(&rawKeyType)) | |
| 1786 return false; | |
| 1787 | |
| 1788 WebCryptoKeyAlgorithm algorithm; | |
| 1789 WebCryptoKeyType type = WebCryptoKeyTypeSecret; | |
| 1790 | |
| 1791 switch (static_cast<CryptoKeySubTag>(rawKeyType)) { | |
| 1792 case AesKeyTag: | |
| 1793 if (!doReadAesKey(algorithm, type)) | |
| 1794 return false; | |
| 1795 break; | |
| 1796 case HmacKeyTag: | |
| 1797 if (!doReadHmacKey(algorithm, type)) | |
| 1798 return false; | |
| 1799 break; | |
| 1800 case RsaHashedKeyTag: | |
| 1801 if (!doReadRsaHashedKey(algorithm, type)) | |
| 1802 return false; | |
| 1803 break; | |
| 1804 case EcKeyTag: | |
| 1805 if (!doReadEcKey(algorithm, type)) | |
| 1806 return false; | |
| 1807 break; | |
| 1808 default: | |
| 1809 return false; | |
| 1810 } | |
| 1811 | |
| 1812 WebCryptoKeyUsageMask usages; | |
| 1813 bool extractable; | |
| 1814 if (!doReadKeyUsages(usages, extractable)) | |
| 1815 return false; | |
| 1816 | |
| 1817 uint32_t keyDataLength; | |
| 1818 if (!doReadUint32(&keyDataLength)) | |
| 1819 return false; | |
| 1820 | |
| 1821 if (m_position + keyDataLength > m_length) | |
| 1822 return false; | |
| 1823 | |
| 1824 const uint8_t* keyData = m_buffer + m_position; | |
| 1825 m_position += keyDataLength; | |
| 1826 | |
| 1827 WebCryptoKey key = WebCryptoKey::createNull(); | |
| 1828 if (!Platform::current()->crypto()->deserializeKeyForClone( | |
| 1829 algorithm, type, extractable, usages, keyData, keyDataLength, key)) { | |
| 1830 return false; | |
| 1831 } | |
| 1832 | |
| 1833 *value = toV8(CryptoKey::create(key), m_scriptState->context()->Global(), is olate()); | |
| 1834 return true; | |
| 1835 } | |
| 1836 | |
| 1837 File* Reader::readFileHelper() | 1560 File* Reader::readFileHelper() |
| 1838 { | 1561 { |
| 1839 if (m_version < 3) | 1562 if (m_version < 3) |
| 1840 return nullptr; | 1563 return nullptr; |
| 1841 ASSERT(!m_blobInfo); | 1564 ASSERT(!m_blobInfo); |
| 1842 String path; | 1565 String path; |
| 1843 String name; | 1566 String name; |
| 1844 String relativePath; | 1567 String relativePath; |
| 1845 String uuid; | 1568 String uuid; |
| 1846 String type; | 1569 String type; |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1917 // the blob in the src process happens to still exist at the time the dest p rocess is deserializing. | 1640 // the blob in the src process happens to still exist at the time the dest p rocess is deserializing. |
| 1918 // For example in sharedWorker.postMessage(...). | 1641 // For example in sharedWorker.postMessage(...). |
| 1919 BlobDataHandleMap::const_iterator it = m_blobDataHandles.find(uuid); | 1642 BlobDataHandleMap::const_iterator it = m_blobDataHandles.find(uuid); |
| 1920 if (it != m_blobDataHandles.end()) { | 1643 if (it != m_blobDataHandles.end()) { |
| 1921 // make assertions about type and size? | 1644 // make assertions about type and size? |
| 1922 return it->value; | 1645 return it->value; |
| 1923 } | 1646 } |
| 1924 return BlobDataHandle::create(uuid, type, size); | 1647 return BlobDataHandle::create(uuid, type, size); |
| 1925 } | 1648 } |
| 1926 | 1649 |
| 1927 bool Reader::doReadHmacKey(WebCryptoKeyAlgorithm& algorithm, WebCryptoKeyType& t ype) | |
| 1928 { | |
| 1929 uint32_t lengthBytes; | |
| 1930 if (!doReadUint32(&lengthBytes)) | |
| 1931 return false; | |
| 1932 WebCryptoAlgorithmId hash; | |
| 1933 if (!doReadAlgorithmId(hash)) | |
| 1934 return false; | |
| 1935 algorithm = WebCryptoKeyAlgorithm::createHmac(hash, lengthBytes * 8); | |
| 1936 type = WebCryptoKeyTypeSecret; | |
| 1937 return !algorithm.isNull(); | |
| 1938 } | |
| 1939 | |
| 1940 bool Reader::doReadAesKey(WebCryptoKeyAlgorithm& algorithm, WebCryptoKeyType& ty pe) | |
| 1941 { | |
| 1942 WebCryptoAlgorithmId id; | |
| 1943 if (!doReadAlgorithmId(id)) | |
| 1944 return false; | |
| 1945 uint32_t lengthBytes; | |
| 1946 if (!doReadUint32(&lengthBytes)) | |
| 1947 return false; | |
| 1948 algorithm = WebCryptoKeyAlgorithm::createAes(id, lengthBytes * 8); | |
| 1949 type = WebCryptoKeyTypeSecret; | |
| 1950 return !algorithm.isNull(); | |
| 1951 } | |
| 1952 | |
| 1953 bool Reader::doReadRsaHashedKey(WebCryptoKeyAlgorithm& algorithm, WebCryptoKeyTy pe& type) | |
| 1954 { | |
| 1955 WebCryptoAlgorithmId id; | |
| 1956 if (!doReadAlgorithmId(id)) | |
| 1957 return false; | |
| 1958 | |
| 1959 if (!doReadAsymmetricKeyType(type)) | |
| 1960 return false; | |
| 1961 | |
| 1962 uint32_t modulusLengthBits; | |
| 1963 if (!doReadUint32(&modulusLengthBits)) | |
| 1964 return false; | |
| 1965 | |
| 1966 uint32_t publicExponentSize; | |
| 1967 if (!doReadUint32(&publicExponentSize)) | |
| 1968 return false; | |
| 1969 | |
| 1970 if (m_position + publicExponentSize > m_length) | |
| 1971 return false; | |
| 1972 | |
| 1973 const uint8_t* publicExponent = m_buffer + m_position; | |
| 1974 m_position += publicExponentSize; | |
| 1975 | |
| 1976 WebCryptoAlgorithmId hash; | |
| 1977 if (!doReadAlgorithmId(hash)) | |
| 1978 return false; | |
| 1979 algorithm = WebCryptoKeyAlgorithm::createRsaHashed(id, modulusLengthBits, pu blicExponent, publicExponentSize, hash); | |
| 1980 | |
| 1981 return !algorithm.isNull(); | |
| 1982 } | |
| 1983 | |
| 1984 bool Reader::doReadEcKey(WebCryptoKeyAlgorithm& algorithm, WebCryptoKeyType& typ e) | |
| 1985 { | |
| 1986 WebCryptoAlgorithmId id; | |
| 1987 if (!doReadAlgorithmId(id)) | |
| 1988 return false; | |
| 1989 | |
| 1990 if (!doReadAsymmetricKeyType(type)) | |
| 1991 return false; | |
| 1992 | |
| 1993 WebCryptoNamedCurve namedCurve; | |
| 1994 if (!doReadNamedCurve(namedCurve)) | |
| 1995 return false; | |
| 1996 | |
| 1997 algorithm = WebCryptoKeyAlgorithm::createEc(id, namedCurve); | |
| 1998 return !algorithm.isNull(); | |
| 1999 } | |
| 2000 | |
| 2001 bool Reader::doReadAlgorithmId(WebCryptoAlgorithmId& id) | |
| 2002 { | |
| 2003 uint32_t rawId; | |
| 2004 if (!doReadUint32(&rawId)) | |
| 2005 return false; | |
| 2006 | |
| 2007 switch (static_cast<CryptoKeyAlgorithmTag>(rawId)) { | |
| 2008 case AesCbcTag: | |
| 2009 id = WebCryptoAlgorithmIdAesCbc; | |
| 2010 return true; | |
| 2011 case HmacTag: | |
| 2012 id = WebCryptoAlgorithmIdHmac; | |
| 2013 return true; | |
| 2014 case RsaSsaPkcs1v1_5Tag: | |
| 2015 id = WebCryptoAlgorithmIdRsaSsaPkcs1v1_5; | |
| 2016 return true; | |
| 2017 case Sha1Tag: | |
| 2018 id = WebCryptoAlgorithmIdSha1; | |
| 2019 return true; | |
| 2020 case Sha256Tag: | |
| 2021 id = WebCryptoAlgorithmIdSha256; | |
| 2022 return true; | |
| 2023 case Sha384Tag: | |
| 2024 id = WebCryptoAlgorithmIdSha384; | |
| 2025 return true; | |
| 2026 case Sha512Tag: | |
| 2027 id = WebCryptoAlgorithmIdSha512; | |
| 2028 return true; | |
| 2029 case AesGcmTag: | |
| 2030 id = WebCryptoAlgorithmIdAesGcm; | |
| 2031 return true; | |
| 2032 case RsaOaepTag: | |
| 2033 id = WebCryptoAlgorithmIdRsaOaep; | |
| 2034 return true; | |
| 2035 case AesCtrTag: | |
| 2036 id = WebCryptoAlgorithmIdAesCtr; | |
| 2037 return true; | |
| 2038 case AesKwTag: | |
| 2039 id = WebCryptoAlgorithmIdAesKw; | |
| 2040 return true; | |
| 2041 case RsaPssTag: | |
| 2042 id = WebCryptoAlgorithmIdRsaPss; | |
| 2043 return true; | |
| 2044 case EcdsaTag: | |
| 2045 id = WebCryptoAlgorithmIdEcdsa; | |
| 2046 return true; | |
| 2047 } | |
| 2048 | |
| 2049 return false; | |
| 2050 } | |
| 2051 | |
| 2052 bool Reader::doReadAsymmetricKeyType(WebCryptoKeyType& type) | |
| 2053 { | |
| 2054 uint32_t rawType; | |
| 2055 if (!doReadUint32(&rawType)) | |
| 2056 return false; | |
| 2057 | |
| 2058 switch (static_cast<AssymetricCryptoKeyType>(rawType)) { | |
| 2059 case PublicKeyType: | |
| 2060 type = WebCryptoKeyTypePublic; | |
| 2061 return true; | |
| 2062 case PrivateKeyType: | |
| 2063 type = WebCryptoKeyTypePrivate; | |
| 2064 return true; | |
| 2065 } | |
| 2066 | |
| 2067 return false; | |
| 2068 } | |
| 2069 | |
| 2070 bool Reader::doReadNamedCurve(WebCryptoNamedCurve& namedCurve) | |
| 2071 { | |
| 2072 uint32_t rawName; | |
| 2073 if (!doReadUint32(&rawName)) | |
| 2074 return false; | |
| 2075 | |
| 2076 switch (static_cast<NamedCurveTag>(rawName)) { | |
| 2077 case P256Tag: | |
| 2078 namedCurve = WebCryptoNamedCurveP256; | |
| 2079 return true; | |
| 2080 case P384Tag: | |
| 2081 namedCurve = WebCryptoNamedCurveP384; | |
| 2082 return true; | |
| 2083 case P521Tag: | |
| 2084 namedCurve = WebCryptoNamedCurveP521; | |
| 2085 return true; | |
| 2086 } | |
| 2087 | |
| 2088 return false; | |
| 2089 } | |
| 2090 | |
| 2091 bool Reader::doReadKeyUsages(WebCryptoKeyUsageMask& usages, bool& extractable) | |
| 2092 { | |
| 2093 // Reminder to update this when adding new key usages. | |
| 2094 COMPILE_ASSERT(EndOfWebCryptoKeyUsage == (1 << 7) + 1, UpdateMe); | |
| 2095 const uint32_t allPossibleUsages = ExtractableUsage | EncryptUsage | Decrypt Usage | SignUsage | VerifyUsage | DeriveKeyUsage | WrapKeyUsage | UnwrapKeyUsage | DeriveBitsUsage; | |
| 2096 | |
| 2097 uint32_t rawUsages; | |
| 2098 if (!doReadUint32(&rawUsages)) | |
| 2099 return false; | |
| 2100 | |
| 2101 // Make sure it doesn't contain an unrecognized usage value. | |
| 2102 if (rawUsages & ~allPossibleUsages) | |
| 2103 return false; | |
| 2104 | |
| 2105 usages = 0; | |
| 2106 | |
| 2107 extractable = rawUsages & ExtractableUsage; | |
| 2108 | |
| 2109 if (rawUsages & EncryptUsage) | |
| 2110 usages |= WebCryptoKeyUsageEncrypt; | |
| 2111 if (rawUsages & DecryptUsage) | |
| 2112 usages |= WebCryptoKeyUsageDecrypt; | |
| 2113 if (rawUsages & SignUsage) | |
| 2114 usages |= WebCryptoKeyUsageSign; | |
| 2115 if (rawUsages & VerifyUsage) | |
| 2116 usages |= WebCryptoKeyUsageVerify; | |
| 2117 if (rawUsages & DeriveKeyUsage) | |
| 2118 usages |= WebCryptoKeyUsageDeriveKey; | |
| 2119 if (rawUsages & WrapKeyUsage) | |
| 2120 usages |= WebCryptoKeyUsageWrapKey; | |
| 2121 if (rawUsages & UnwrapKeyUsage) | |
| 2122 usages |= WebCryptoKeyUsageUnwrapKey; | |
| 2123 if (rawUsages & DeriveBitsUsage) | |
| 2124 usages |= WebCryptoKeyUsageDeriveBits; | |
| 2125 | |
| 2126 return true; | |
| 2127 } | |
| 2128 | |
| 2129 v8::Handle<v8::Value> Deserializer::deserialize() | 1650 v8::Handle<v8::Value> Deserializer::deserialize() |
| 2130 { | 1651 { |
| 2131 v8::Isolate* isolate = m_reader.scriptState()->isolate(); | 1652 v8::Isolate* isolate = m_reader.scriptState()->isolate(); |
| 2132 if (!m_reader.readVersion(m_version) || m_version > SerializedScriptValue::w ireFormatVersion) | 1653 if (!m_reader.readVersion(m_version) || m_version > SerializedScriptValue::w ireFormatVersion) |
| 2133 return v8::Null(isolate); | 1654 return v8::Null(isolate); |
| 2134 m_reader.setVersion(m_version); | 1655 m_reader.setVersion(m_version); |
| 2135 v8::EscapableHandleScope scope(isolate); | 1656 v8::EscapableHandleScope scope(isolate); |
| 2136 while (!m_reader.isEof()) { | 1657 while (!m_reader.isEof()) { |
| 2137 if (!doDeserialize()) | 1658 if (!doDeserialize()) |
| 2138 return v8::Null(isolate); | 1659 return v8::Null(isolate); |
| (...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2329 m_openCompositeReferenceStack.shrink(m_openCompositeReferenceStack.size() - 1); | 1850 m_openCompositeReferenceStack.shrink(m_openCompositeReferenceStack.size() - 1); |
| 2330 if (objectReference >= m_objectPool.size()) | 1851 if (objectReference >= m_objectPool.size()) |
| 2331 return false; | 1852 return false; |
| 2332 *object = m_objectPool[objectReference]; | 1853 *object = m_objectPool[objectReference]; |
| 2333 return true; | 1854 return true; |
| 2334 } | 1855 } |
| 2335 | 1856 |
| 2336 } // SerializedScriptValueInternal | 1857 } // SerializedScriptValueInternal |
| 2337 | 1858 |
| 2338 } // namespace blink | 1859 } // namespace blink |
| OLD | NEW |