Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright 2017 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "modules/indexeddb/IDBValueWrapper.h" | |
| 6 | |
| 7 #include <utility> | |
| 8 | |
| 9 #include "bindings/core/v8/ScriptValue.h" | |
| 10 #include "bindings/core/v8/SerializationTag.h" | |
| 11 #include "bindings/core/v8/SerializedScriptValue.h" | |
| 12 #include "bindings/modules/v8/V8BindingForModules.h" | |
| 13 #include "core/fileapi/Blob.h" | |
| 14 #include "modules/indexeddb/IDBRequest.h" | |
| 15 #include "platform/wtf/text/WTFString.h" | |
| 16 | |
| 17 namespace blink { | |
| 18 | |
| 19 IDBValueWrapper::IDBValueWrapper(v8::Isolate* isolate, | |
| 20 v8::Local<v8::Value> value, | |
| 21 bool write_wasm_to_stream, | |
| 22 ExceptionState& exception_state) { | |
| 23 SerializedScriptValue::SerializeOptions options; | |
| 24 options.blob_info = &blob_info_; | |
| 25 options.for_storage = true; | |
| 26 options.write_wasm_to_stream = write_wasm_to_stream; | |
| 27 | |
| 28 serialized_value_ = SerializedScriptValue::Serialize(isolate, value, options, | |
| 29 exception_state); | |
| 30 | |
| 31 #if DCHECK_IS_ON() | |
| 32 if (exception_state.HadException()) | |
| 33 had_exception_ = true; | |
| 34 #endif // DCHECK_IS_ON() | |
| 35 } | |
| 36 | |
| 37 void IDBValueWrapper::Clone(ScriptState* script_state, ScriptValue* clone) { | |
| 38 #if DCHECK_IS_ON() | |
| 39 DCHECK(!had_exception_) | |
| 40 << "Clone() called on wrapper with serialization exception"; | |
| 41 DCHECK(!wrap_called_) << "Clone() called after WrapIfBiggerThan()"; | |
| 42 #endif // DCHECK_IS_ON() | |
| 43 *clone = DeserializeScriptValue(script_state, serialized_value_.Get(), | |
| 44 &blob_info_); | |
| 45 } | |
| 46 | |
| 47 void IDBValueWrapper::WriteVarint(unsigned value, Vector<char>& output) { | |
| 48 // Writes an unsigned integer as a base-128 varint. | |
| 49 // The number is written, 7 bits at a time, from the least significant to | |
| 50 // the most significant 7 bits. Each byte, except the last, has the MSB set. | |
| 51 // See also https://developers.google.com/protocol-buffers/docs/encoding | |
| 52 do { | |
| 53 output.push_back((value & 0x7F) | 0x80); | |
| 54 value >>= 7; | |
| 55 } while (value); | |
| 56 output.back() &= 0x7F; | |
| 57 } | |
| 58 | |
| 59 void IDBValueWrapper::WriteAsciiString(const String& value, | |
| 60 Vector<char>& output) { | |
| 61 DCHECK(value.Is8Bit() && value.ContainsOnlyASCII()); | |
| 62 | |
| 63 IDBValueWrapper::WriteVarint(value.length(), output); | |
| 64 output.Append(value.Characters8(), value.length()); | |
| 65 } | |
| 66 | |
| 67 bool IDBValueWrapper::WrapIfBiggerThan(unsigned max_bytes) { | |
| 68 #if DCHECK_IS_ON() | |
| 69 DCHECK(!had_exception_) | |
| 70 << "WrapIfBiggerThan() called on wrapper with serialization exception"; | |
| 71 DCHECK(!wrap_called_) | |
| 72 << "WrapIfBiggerThan() called twice on the same wrapper"; | |
| 73 wrap_called_ = true; | |
| 74 #endif // DCHECK_IS_ON() | |
| 75 | |
| 76 serialized_value_->ToWireBytes(wire_bytes_); | |
| 77 if (wire_bytes_.size() <= max_bytes) | |
|
dmurph
2017/05/04 22:27:07
Check the accessible buffer instead of wire bytes,
pwnall
2017/05/11 23:54:24
I still need to serialize, even if no wrapping hap
| |
| 78 return false; | |
| 79 | |
| 80 // TODO(pwnall): The MIME type should probably be an atomic string. | |
| 81 String mime_type(kWrapMimeType); | |
| 82 Blob* wrapper = | |
|
dmurph
2017/05/04 22:27:07
Add a TODO & bug to use CreateBuilder in WebBlobRe
pwnall
2017/05/11 23:54:24
Done.
| |
| 83 Blob::Create(reinterpret_cast<unsigned char*>(wire_bytes_.data()), | |
| 84 wire_bytes_.size(), mime_type); | |
| 85 | |
| 86 wrapper_handle_ = std::move(wrapper->GetBlobDataHandle()); | |
|
dmurph
2017/05/04 22:27:07
Do we need this to be a separate handle? Can we ju
pwnall
2017/05/11 23:54:24
IIUC, WebBlobInfo is a struct that wraps the field
| |
| 87 blob_info_.emplace_back(wrapper_handle_->Uuid(), wrapper_handle_->GetType(), | |
| 88 wrapper->size()); | |
| 89 | |
| 90 wire_bytes_.clear(); | |
| 91 | |
| 92 // Version 17 of SSV always writes a V8 envelope after the Blink envelope, so | |
| 93 // its output starts with 0xFF 0x11 0xFF. Therefore, we can use 0xFF 0x11 0xvv | |
| 94 // as an escape prefix, for 0x00 <= 0xvv < 0xFF. | |
| 95 wire_bytes_.push_back(kVersionTag); | |
| 96 wire_bytes_.push_back(17); | |
| 97 wire_bytes_.push_back(1); | |
| 98 IDBValueWrapper::WriteVarint(wrapper->size(), wire_bytes_); | |
| 99 IDBValueWrapper::WriteAsciiString(wrapper->Uuid(), wire_bytes_); | |
| 100 return true; | |
| 101 } | |
| 102 | |
| 103 void IDBValueWrapper::ExtractBlobDataHandles( | |
| 104 Vector<RefPtr<BlobDataHandle>>* blob_data_handles) { | |
| 105 for (const auto& kvp : serialized_value_->BlobDataHandles()) | |
| 106 blob_data_handles->push_back(kvp.value); | |
| 107 if (wrapper_handle_) | |
| 108 blob_data_handles->push_back(std::move(wrapper_handle_)); | |
| 109 } | |
| 110 | |
| 111 PassRefPtr<SharedBuffer> IDBValueWrapper::ExtractWireBytes() { | |
| 112 #if DCHECK_IS_ON() | |
| 113 DCHECK(!had_exception_) | |
| 114 << "ExtractWireBytes() called on wrapper with serialization exception"; | |
| 115 #endif // DCHECK_IS_ON() | |
| 116 | |
| 117 return SharedBuffer::AdoptVector(wire_bytes_); | |
| 118 } | |
| 119 | |
| 120 } // namespace blink | |
| OLD | NEW |