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