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