Index: src/api.cc |
diff --git a/src/api.cc b/src/api.cc |
index 283a9117c60ced7e6c322e6892e58e44d9bb7f6c..074065574534b0e3d1300448a8e5aa60f0e67c62 100644 |
--- a/src/api.cc |
+++ b/src/api.cc |
@@ -2858,10 +2858,8 @@ Maybe<bool> ValueSerializer::WriteValue(Local<Context> context, |
PREPARE_FOR_EXECUTION_PRIMITIVE(context, ValueSerializer, WriteValue, bool); |
i::Handle<i::Object> object = Utils::OpenHandle(*value); |
Maybe<bool> result = private_->serializer.WriteObject(object); |
- if (result.IsNothing()) { |
- has_pending_exception = private_->isolate->has_pending_exception(); |
- RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool); |
- } |
+ has_pending_exception = result.IsNothing(); |
+ RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool); |
return result; |
} |
@@ -2886,6 +2884,7 @@ struct ValueDeserializer::PrivateData { |
: isolate(i), deserializer(i, data) {} |
i::Isolate* isolate; |
i::ValueDeserializer deserializer; |
+ bool has_aborted = false; |
bool supports_legacy_wire_format = false; |
}; |
@@ -2896,38 +2895,61 @@ ValueDeserializer::ValueDeserializer(Isolate* isolate, const uint8_t* data, |
new PrivateData(reinterpret_cast<i::Isolate*>(isolate), |
i::Vector<const uint8_t>(data, static_cast<int>(size))); |
} else { |
- private_ = nullptr; |
+ private_ = new PrivateData(reinterpret_cast<i::Isolate*>(isolate), |
+ i::Vector<const uint8_t>(nullptr, 0)); |
+ private_->has_aborted = true; |
} |
} |
ValueDeserializer::~ValueDeserializer() { delete private_; } |
-Maybe<bool> ValueDeserializer::ReadHeader() { |
+Maybe<bool> ValueDeserializer::ReadHeader(Local<Context> context) { |
+ PREPARE_FOR_EXECUTION_PRIMITIVE(context, ValueDeserializer, ReadHeader, bool); |
+ |
+ // We could have aborted during the constructor. |
+ // If so, ReadHeader is where we report it. |
+ if (private_->has_aborted) { |
+ isolate->Throw(*isolate->factory()->NewError( |
+ i::MessageTemplate::kDataCloneDeserializationError)); |
+ has_pending_exception = true; |
+ RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool); |
+ } |
+ |
+ bool read_header = false; |
+ has_pending_exception = !private_->deserializer.ReadHeader().To(&read_header); |
+ RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool); |
+ DCHECK(read_header); |
+ |
// TODO(jbroman): Today, all wire formats are "legacy". When a more supported |
// format is added, compare the version of the internal serializer to the |
// minimum non-legacy version number. |
- if (!private_ || !private_->deserializer.ReadHeader().FromMaybe(false) || |
- !private_->supports_legacy_wire_format) { |
- delete private_; |
- private_ = nullptr; |
- return Nothing<bool>(); |
+ if (!private_->supports_legacy_wire_format) { |
+ isolate->Throw(*isolate->factory()->NewError( |
+ i::MessageTemplate::kDataCloneDeserializationVersionError)); |
+ has_pending_exception = true; |
+ RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool); |
} |
+ |
return Just(true); |
} |
+Maybe<bool> ValueDeserializer::ReadHeader() { |
+ Isolate* isolate = reinterpret_cast<Isolate*>(private_->isolate); |
+ return ReadHeader(isolate->GetEnteredContext()); |
+} |
+ |
void ValueDeserializer::SetSupportsLegacyWireFormat( |
bool supports_legacy_wire_format) { |
- if (!private_) return; |
private_->supports_legacy_wire_format = supports_legacy_wire_format; |
} |
uint32_t ValueDeserializer::GetWireFormatVersion() const { |
- CHECK(private_); |
+ CHECK(!private_->has_aborted); |
return private_->deserializer.GetWireFormatVersion(); |
} |
MaybeLocal<Value> ValueDeserializer::ReadValue(Local<Context> context) { |
- CHECK(private_); |
+ CHECK(!private_->has_aborted); |
PREPARE_FOR_EXECUTION(context, ValueDeserializer, ReadValue, Value); |
i::MaybeHandle<i::Object> result; |
if (GetWireFormatVersion() > 0) { |
@@ -2937,22 +2959,21 @@ MaybeLocal<Value> ValueDeserializer::ReadValue(Local<Context> context) { |
private_->deserializer.ReadObjectUsingEntireBufferForLegacyFormat(); |
} |
Local<Value> value; |
- if (!ToLocal(result, &value)) { |
- has_pending_exception = private_->isolate->has_pending_exception(); |
- RETURN_ON_FAILED_EXECUTION(Value); |
- return MaybeLocal<Value>(); |
- } |
+ has_pending_exception = !ToLocal(result, &value); |
+ RETURN_ON_FAILED_EXECUTION(Value); |
RETURN_ESCAPED(value); |
} |
void ValueDeserializer::TransferArrayBuffer(uint32_t transfer_id, |
Local<ArrayBuffer> array_buffer) { |
+ CHECK(!private_->has_aborted); |
private_->deserializer.TransferArrayBuffer(transfer_id, |
Utils::OpenHandle(*array_buffer)); |
} |
void ValueDeserializer::TransferSharedArrayBuffer( |
uint32_t transfer_id, Local<SharedArrayBuffer> shared_array_buffer) { |
+ CHECK(!private_->has_aborted); |
private_->deserializer.TransferArrayBuffer( |
transfer_id, Utils::OpenHandle(*shared_array_buffer)); |
} |