Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(10)

Side by Side Diff: src/value-serializer.cc

Issue 2594793005: Disallow passing a SharedArrayBuffer in the transfer list. (Closed)
Patch Set: Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/value-serializer.h ('k') | test/unittests/value-serializer-unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 the V8 project authors. All rights reserved. 1 // Copyright 2016 the V8 project 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 "src/value-serializer.h" 5 #include "src/value-serializer.h"
6 6
7 #include <type_traits> 7 #include <type_traits>
8 8
9 #include "src/base/logging.h" 9 #include "src/base/logging.h"
10 #include "src/conversions.h" 10 #include "src/conversions.h"
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
103 // Array buffer (transferred). transferID:uint32_t 103 // Array buffer (transferred). transferID:uint32_t
104 kArrayBufferTransfer = 't', 104 kArrayBufferTransfer = 't',
105 // View into an array buffer. 105 // View into an array buffer.
106 // subtag:ArrayBufferViewTag, byteOffset:uint32_t, byteLength:uint32_t 106 // subtag:ArrayBufferViewTag, byteOffset:uint32_t, byteLength:uint32_t
107 // For typed arrays, byteOffset and byteLength must be divisible by the size 107 // For typed arrays, byteOffset and byteLength must be divisible by the size
108 // of the element. 108 // of the element.
109 // Note: kArrayBufferView is special, and should have an ArrayBuffer (or an 109 // Note: kArrayBufferView is special, and should have an ArrayBuffer (or an
110 // ObjectReference to one) serialized just before it. This is a quirk arising 110 // ObjectReference to one) serialized just before it. This is a quirk arising
111 // from the previous stack-based implementation. 111 // from the previous stack-based implementation.
112 kArrayBufferView = 'V', 112 kArrayBufferView = 'V',
113 // Shared array buffer (transferred). transferID:uint32_t 113 // Shared array buffer. transferID:uint32_t
114 kSharedArrayBufferTransfer = 'u', 114 kSharedArrayBuffer = 'u',
115 // Compiled WebAssembly module. encodingType:(one-byte tag). 115 // Compiled WebAssembly module. encodingType:(one-byte tag).
116 // If encodingType == 'y' (raw bytes): 116 // If encodingType == 'y' (raw bytes):
117 // wasmWireByteLength:uint32_t, then raw data 117 // wasmWireByteLength:uint32_t, then raw data
118 // compiledDataLength:uint32_t, then raw data 118 // compiledDataLength:uint32_t, then raw data
119 kWasmModule = 'W', 119 kWasmModule = 'W',
120 }; 120 };
121 121
122 namespace { 122 namespace {
123 123
124 enum class ArrayBufferViewTag : uint8_t { 124 enum class ArrayBufferViewTag : uint8_t {
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after
262 auto result = std::make_pair(buffer_, buffer_size_); 262 auto result = std::make_pair(buffer_, buffer_size_);
263 buffer_ = nullptr; 263 buffer_ = nullptr;
264 buffer_size_ = 0; 264 buffer_size_ = 0;
265 buffer_capacity_ = 0; 265 buffer_capacity_ = 0;
266 return result; 266 return result;
267 } 267 }
268 268
269 void ValueSerializer::TransferArrayBuffer(uint32_t transfer_id, 269 void ValueSerializer::TransferArrayBuffer(uint32_t transfer_id,
270 Handle<JSArrayBuffer> array_buffer) { 270 Handle<JSArrayBuffer> array_buffer) {
271 DCHECK(!array_buffer_transfer_map_.Find(array_buffer)); 271 DCHECK(!array_buffer_transfer_map_.Find(array_buffer));
272 DCHECK(!array_buffer->is_shared());
272 array_buffer_transfer_map_.Set(array_buffer, transfer_id); 273 array_buffer_transfer_map_.Set(array_buffer, transfer_id);
273 } 274 }
274 275
275 Maybe<bool> ValueSerializer::WriteObject(Handle<Object> object) { 276 Maybe<bool> ValueSerializer::WriteObject(Handle<Object> object) {
276 if (object->IsSmi()) { 277 if (object->IsSmi()) {
277 WriteSmi(Smi::cast(*object)); 278 WriteSmi(Smi::cast(*object));
278 return Just(true); 279 return Just(true);
279 } 280 }
280 281
281 DCHECK(object->IsHeapObject()); 282 DCHECK(object->IsHeapObject());
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
435 case JS_VALUE_TYPE: 436 case JS_VALUE_TYPE:
436 return WriteJSValue(Handle<JSValue>::cast(receiver)); 437 return WriteJSValue(Handle<JSValue>::cast(receiver));
437 case JS_REGEXP_TYPE: 438 case JS_REGEXP_TYPE:
438 WriteJSRegExp(JSRegExp::cast(*receiver)); 439 WriteJSRegExp(JSRegExp::cast(*receiver));
439 return Just(true); 440 return Just(true);
440 case JS_MAP_TYPE: 441 case JS_MAP_TYPE:
441 return WriteJSMap(Handle<JSMap>::cast(receiver)); 442 return WriteJSMap(Handle<JSMap>::cast(receiver));
442 case JS_SET_TYPE: 443 case JS_SET_TYPE:
443 return WriteJSSet(Handle<JSSet>::cast(receiver)); 444 return WriteJSSet(Handle<JSSet>::cast(receiver));
444 case JS_ARRAY_BUFFER_TYPE: 445 case JS_ARRAY_BUFFER_TYPE:
445 return WriteJSArrayBuffer(JSArrayBuffer::cast(*receiver)); 446 return WriteJSArrayBuffer(Handle<JSArrayBuffer>::cast(receiver));
446 case JS_TYPED_ARRAY_TYPE: 447 case JS_TYPED_ARRAY_TYPE:
447 case JS_DATA_VIEW_TYPE: 448 case JS_DATA_VIEW_TYPE:
448 return WriteJSArrayBufferView(JSArrayBufferView::cast(*receiver)); 449 return WriteJSArrayBufferView(JSArrayBufferView::cast(*receiver));
449 default: 450 default:
450 ThrowDataCloneError(MessageTemplate::kDataCloneError, receiver); 451 ThrowDataCloneError(MessageTemplate::kDataCloneError, receiver);
451 return Nothing<bool>(); 452 return Nothing<bool>();
452 } 453 }
453 return Nothing<bool>(); 454 return Nothing<bool>();
454 } 455 }
455 456
(...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after
717 for (int i = 0; i < length; i++) { 718 for (int i = 0; i < length; i++) {
718 if (!WriteObject(handle(entries->get(i), isolate_)).FromMaybe(false)) { 719 if (!WriteObject(handle(entries->get(i), isolate_)).FromMaybe(false)) {
719 return Nothing<bool>(); 720 return Nothing<bool>();
720 } 721 }
721 } 722 }
722 WriteTag(SerializationTag::kEndJSSet); 723 WriteTag(SerializationTag::kEndJSSet);
723 WriteVarint<uint32_t>(length); 724 WriteVarint<uint32_t>(length);
724 return Just(true); 725 return Just(true);
725 } 726 }
726 727
727 Maybe<bool> ValueSerializer::WriteJSArrayBuffer(JSArrayBuffer* array_buffer) { 728 Maybe<bool> ValueSerializer::WriteJSArrayBuffer(
728 uint32_t* transfer_entry = array_buffer_transfer_map_.Find(array_buffer); 729 Handle<JSArrayBuffer> array_buffer) {
729 if (transfer_entry) { 730 if (array_buffer->is_shared()) {
730 WriteTag(array_buffer->is_shared() 731 if (!delegate_) {
731 ? SerializationTag::kSharedArrayBufferTransfer 732 ThrowDataCloneError(MessageTemplate::kDataCloneError, array_buffer);
732 : SerializationTag::kArrayBufferTransfer); 733 return Nothing<bool>();
733 WriteVarint(*transfer_entry); 734 }
735
736 v8::Isolate* v8_isolate = reinterpret_cast<v8::Isolate*>(isolate_);
737 Maybe<uint32_t> index = delegate_->GetSharedArrayBufferId(
738 v8_isolate, Utils::ToLocalShared(array_buffer));
739 RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate_, Nothing<bool>());
740
741 WriteTag(SerializationTag::kSharedArrayBuffer);
742 WriteVarint(index.FromJust());
734 return Just(true); 743 return Just(true);
735 } 744 }
736 745
737 if (array_buffer->is_shared()) { 746 uint32_t* transfer_entry = array_buffer_transfer_map_.Find(array_buffer);
738 ThrowDataCloneError( 747 if (transfer_entry) {
739 MessageTemplate::kDataCloneErrorSharedArrayBufferNotTransferred); 748 WriteTag(SerializationTag::kArrayBufferTransfer);
740 return Nothing<bool>(); 749 WriteVarint(*transfer_entry);
750 return Just(true);
741 } 751 }
742 if (array_buffer->was_neutered()) { 752 if (array_buffer->was_neutered()) {
743 ThrowDataCloneError(MessageTemplate::kDataCloneErrorNeuteredArrayBuffer); 753 ThrowDataCloneError(MessageTemplate::kDataCloneErrorNeuteredArrayBuffer);
744 return Nothing<bool>(); 754 return Nothing<bool>();
745 } 755 }
746 double byte_length = array_buffer->byte_length()->Number(); 756 double byte_length = array_buffer->byte_length()->Number();
747 if (byte_length > std::numeric_limits<uint32_t>::max()) { 757 if (byte_length > std::numeric_limits<uint32_t>::max()) {
748 ThrowDataCloneError(MessageTemplate::kDataCloneError, handle(array_buffer)); 758 ThrowDataCloneError(MessageTemplate::kDataCloneError, array_buffer);
749 return Nothing<bool>(); 759 return Nothing<bool>();
750 } 760 }
751 WriteTag(SerializationTag::kArrayBuffer); 761 WriteTag(SerializationTag::kArrayBuffer);
752 WriteVarint<uint32_t>(byte_length); 762 WriteVarint<uint32_t>(byte_length);
753 WriteRawBytes(array_buffer->backing_store(), byte_length); 763 WriteRawBytes(array_buffer->backing_store(), byte_length);
754 return Just(true); 764 return Just(true);
755 } 765 }
756 766
757 Maybe<bool> ValueSerializer::WriteJSArrayBufferView(JSArrayBufferView* view) { 767 Maybe<bool> ValueSerializer::WriteJSArrayBufferView(JSArrayBufferView* view) {
758 WriteTag(SerializationTag::kArrayBufferView); 768 WriteTag(SerializationTag::kArrayBufferView);
(...skipping 339 matching lines...) Expand 10 before | Expand all | Expand 10 after
1098 case SerializationTag::kBeginJSMap: 1108 case SerializationTag::kBeginJSMap:
1099 return ReadJSMap(); 1109 return ReadJSMap();
1100 case SerializationTag::kBeginJSSet: 1110 case SerializationTag::kBeginJSSet:
1101 return ReadJSSet(); 1111 return ReadJSSet();
1102 case SerializationTag::kArrayBuffer: 1112 case SerializationTag::kArrayBuffer:
1103 return ReadJSArrayBuffer(); 1113 return ReadJSArrayBuffer();
1104 case SerializationTag::kArrayBufferTransfer: { 1114 case SerializationTag::kArrayBufferTransfer: {
1105 const bool is_shared = false; 1115 const bool is_shared = false;
1106 return ReadTransferredJSArrayBuffer(is_shared); 1116 return ReadTransferredJSArrayBuffer(is_shared);
1107 } 1117 }
1108 case SerializationTag::kSharedArrayBufferTransfer: { 1118 case SerializationTag::kSharedArrayBuffer: {
1109 const bool is_shared = true; 1119 const bool is_shared = true;
1110 return ReadTransferredJSArrayBuffer(is_shared); 1120 return ReadTransferredJSArrayBuffer(is_shared);
1111 } 1121 }
1112 case SerializationTag::kWasmModule: 1122 case SerializationTag::kWasmModule:
1113 return ReadWasmModule(); 1123 return ReadWasmModule();
1114 default: 1124 default:
1115 // TODO(jbroman): Introduce an explicit tag for host objects to avoid 1125 // TODO(jbroman): Introduce an explicit tag for host objects to avoid
1116 // having to treat every unknown tag as a potential host object. 1126 // having to treat every unknown tag as a potential host object.
1117 position_--; 1127 position_--;
1118 return ReadHostObject(); 1128 return ReadHostObject();
(...skipping 741 matching lines...) Expand 10 before | Expand all | Expand 10 after
1860 if (stack.size() != 1) { 1870 if (stack.size() != 1) {
1861 isolate_->Throw(*isolate_->factory()->NewError( 1871 isolate_->Throw(*isolate_->factory()->NewError(
1862 MessageTemplate::kDataCloneDeserializationError)); 1872 MessageTemplate::kDataCloneDeserializationError));
1863 return MaybeHandle<Object>(); 1873 return MaybeHandle<Object>();
1864 } 1874 }
1865 return scope.CloseAndEscape(stack[0]); 1875 return scope.CloseAndEscape(stack[0]);
1866 } 1876 }
1867 1877
1868 } // namespace internal 1878 } // namespace internal
1869 } // namespace v8 1879 } // namespace v8
OLDNEW
« no previous file with comments | « src/value-serializer.h ('k') | test/unittests/value-serializer-unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698