Commit 15b0869d authored by jbroman's avatar jbroman Committed by Commit bot

Implement v8::ValueSerializer::Delegate to throw DOMException for DataCloneError.

This allows V8 to indirectly throw a DOMException, as is required to handle
certain kinds of errors encountered during serialization.

BUG=chromium:148757

Review-Url: https://codereview.chromium.org/2316763002
Cr-Commit-Position: refs/heads/master@{#417184}
parent 09d8cdfc
......@@ -130,6 +130,8 @@ public:
const char* propertyName() const { return m_propertyName; }
const char* interfaceName() const { return m_interfaceName; }
String addExceptionContext(const String&) const;
protected:
// An ExceptionCode for the case that an exception is rethrown. In that
// case, we cannot determine an exception code.
......@@ -138,8 +140,6 @@ protected:
void setException(ExceptionCode, const String&, v8::Local<v8::Value>);
private:
String addExceptionContext(const String&) const;
ExceptionCode m_code;
ContextType m_context;
String m_message;
......
......@@ -7,13 +7,14 @@
#include "bindings/core/v8/ToV8.h"
#include "core/dom/DOMArrayBufferBase.h"
#include "platform/RuntimeEnabledFeatures.h"
#include "wtf/AutoReset.h"
namespace blink {
V8ScriptValueSerializer::V8ScriptValueSerializer(RefPtr<ScriptState> scriptState)
: m_scriptState(std::move(scriptState))
, m_serializedScriptValue(SerializedScriptValue::create())
, m_serializer(m_scriptState->isolate())
, m_serializer(m_scriptState->isolate(), this)
{
DCHECK(RuntimeEnabledFeatures::v8BasedStructuredCloneEnabled());
}
......@@ -25,6 +26,7 @@ RefPtr<SerializedScriptValue> V8ScriptValueSerializer::serialize(v8::Local<v8::V
m_serializeInvoked = true;
#endif
DCHECK(m_serializedScriptValue);
AutoReset<const ExceptionState*> reset(&m_exceptionState, &exceptionState);
ScriptState::Scope scope(m_scriptState.get());
// Prepare to transfer the provided transferables.
......@@ -42,11 +44,7 @@ RefPtr<SerializedScriptValue> V8ScriptValueSerializer::serialize(v8::Local<v8::V
exceptionState.rethrowV8Exception(tryCatch.Exception());
return nullptr;
}
if (!wroteValue) {
DCHECK(!tryCatch.HasCaught());
exceptionState.throwDOMException(DataCloneError, "An object could not be cloned.");
return nullptr;
}
DCHECK(wroteValue);
// Finalize the results.
std::vector<uint8_t> buffer = m_serializer.ReleaseBuffer();
......@@ -85,4 +83,14 @@ void V8ScriptValueSerializer::transfer(Transferables* transferables, ExceptionSt
}
}
void V8ScriptValueSerializer::ThrowDataCloneError(v8::Local<v8::String> v8Message)
{
DCHECK(m_exceptionState);
String message = m_exceptionState->addExceptionContext(
v8StringToWebCoreString<String>(v8Message, DoNotExternalize));
v8::Local<v8::Value> exception = V8ThrowException::createDOMException(
m_scriptState->isolate(), DataCloneError, message);
V8ThrowException::throwException(m_scriptState->isolate(), exception);
}
} // namespace blink
......@@ -25,7 +25,7 @@ class Transferables;
//
// A serializer cannot be used multiple times; it is expected that its serialize
// method will be invoked exactly once.
class V8ScriptValueSerializer {
class GC_PLUGIN_IGNORE("https://crbug.com/644725") V8ScriptValueSerializer : public v8::ValueSerializer::Delegate {
STACK_ALLOCATED();
WTF_MAKE_NONCOPYABLE(V8ScriptValueSerializer);
public:
......@@ -35,9 +35,13 @@ public:
private:
void transfer(Transferables*, ExceptionState&);
// v8::ValueSerializer::Delegate
void ThrowDataCloneError(v8::Local<v8::String> message) override;
RefPtr<ScriptState> m_scriptState;
RefPtr<SerializedScriptValue> m_serializedScriptValue;
v8::ValueSerializer m_serializer;
const ExceptionState* m_exceptionState = nullptr;
#if DCHECK_IS_ON()
bool m_serializeInvoked = false;
#endif
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment