Chromium Code Reviews| Index: third_party/WebKit/Source/bindings/core/v8/ScriptValueSerializer.cpp |
| diff --git a/third_party/WebKit/Source/bindings/core/v8/ScriptValueSerializer.cpp b/third_party/WebKit/Source/bindings/core/v8/ScriptValueSerializer.cpp |
| index 3bd0390146d9043f971387b6fb751005509455e8..516ee495c8eb90ba956de9f45136e80208a645c9 100644 |
| --- a/third_party/WebKit/Source/bindings/core/v8/ScriptValueSerializer.cpp |
| +++ b/third_party/WebKit/Source/bindings/core/v8/ScriptValueSerializer.cpp |
| @@ -251,7 +251,7 @@ void SerializedScriptValueWriter::writeArrayBufferView(const DOMArrayBufferView& |
| { |
| append(ArrayBufferViewTag); |
| #if ENABLE(ASSERT) |
| - ASSERT(static_cast<const uint8_t*>(arrayBufferView.bufferBase()->data()) + arrayBufferView.byteOffset() == |
| + ASSERT(static_cast<const uint8_t*>(arrayBufferView.bufferBaseOrNull()->data()) + arrayBufferView.byteOffset() == |
|
haraken
2015/10/29 18:58:37
arrayBufferView.bufferBaseOrNull() can return null
Justin Novosad
2015/11/05 00:17:51
Done.
|
| static_cast<const uint8_t*>(arrayBufferView.baseAddress())); |
| #endif |
| DOMArrayBufferView::ViewType type = arrayBufferView.type(); |
| @@ -976,10 +976,10 @@ ScriptValueSerializer::StateBase* ScriptValueSerializer::writeAndGreyArrayBuffer |
| ASSERT(!object.IsEmpty()); |
| DOMArrayBufferView* arrayBufferView = V8ArrayBufferView::toImpl(object); |
| if (!arrayBufferView) |
| - return 0; |
| - if (!arrayBufferView->bufferBase()) |
| + return nullptr; |
| + if (!arrayBufferView->bufferBaseOrNull()) |
| return handleError(DataCloneError, "An ArrayBuffer could not be cloned.", next); |
| - v8::Local<v8::Value> underlyingBuffer = toV8(arrayBufferView->bufferBase(), m_scriptState->context()->Global(), isolate()); |
| + v8::Local<v8::Value> underlyingBuffer = toV8(arrayBufferView->bufferBaseOrNull(), m_scriptState->context()->Global(), isolate()); |
| if (underlyingBuffer.IsEmpty()) |
| return handleError(DataCloneError, "An ArrayBuffer could not be cloned.", next); |
| StateBase* stateOut = doSerializeArrayBuffer(underlyingBuffer, next); |
| @@ -1532,7 +1532,22 @@ bool SerializedScriptValueReader::readImageData(v8::Local<v8::Value>* value) |
| return false; |
| if (m_position + pixelDataLength > m_length) |
| return false; |
| - ImageData* imageData = ImageData::create(IntSize(width, height)); |
| + // TODO(junov): crbug.com/536816 |
| + // Here we use a NonThorwableExceptionState in order to fail silently |
| + // when ImageData allocation fails. It needs to be ascertained whether |
| + // the call sites that depend on value deserialization agree with |
| + // re-throwing a RangeError exception from here, which is what happens |
| + // when the ArrayBuffer encapsulated in the ImageData fails to be |
| + // allocated, as per the ECMAScript spec: |
| + // http://ecma-international.org/ecma-262/6.0/#sec-createbytedatablock |
| + // Before we decide to propagate the exception down to the script |
| + // execution context, all the APIs that depend on this routine would |
| + // need to have specifications stating that exceptions thrown by sub |
| + // routines involved in the deserialization process are re-thrown. |
| + NonThrowableExceptionState exceptionState; |
| + ImageData* imageData = ImageData::create(IntSize(width, height), exceptionState); |
| + if (exceptionState.hadException()) |
| + return false; |
| DOMUint8ClampedArray* pixelArray = imageData->data(); |
| ASSERT(pixelArray); |
| ASSERT(pixelArray->length() >= pixelDataLength); |
| @@ -1556,7 +1571,7 @@ bool SerializedScriptValueReader::readCompositorProxy(v8::Local<v8::Value>* valu |
| return !value->IsEmpty(); |
| } |
| -PassRefPtr<DOMArrayBuffer> SerializedScriptValueReader::doReadArrayBuffer() |
| +PassRefPtr<DOMArrayBuffer> SerializedScriptValueReader::doReadArrayBufferOrNull() |
| { |
| uint32_t byteLength; |
| if (!doReadUint32(&byteLength)) |
| @@ -1565,14 +1580,18 @@ PassRefPtr<DOMArrayBuffer> SerializedScriptValueReader::doReadArrayBuffer() |
| return nullptr; |
| const void* bufferStart = m_buffer + m_position; |
| m_position += byteLength; |
| - return DOMArrayBuffer::create(bufferStart, byteLength); |
| + return DOMArrayBuffer::createOrNull(bufferStart, byteLength); |
| } |
| bool SerializedScriptValueReader::readArrayBuffer(v8::Local<v8::Value>* value) |
| { |
| - RefPtr<DOMArrayBuffer> arrayBuffer = doReadArrayBuffer(); |
| - if (!arrayBuffer) |
| - return false; |
| + RefPtr<DOMArrayBuffer> arrayBuffer = doReadArrayBufferOrNull(); |
| + // TODO(junov): crbug.com/536816 Instead of the following assert, we should consider doing: |
| + // if (!arrayBuffer) |
| + // return false; |
| + // To do that, we need to make sure that call sites would react correctly |
| + // in this case, with the value not having been set. |
| + RELEASE_ASSERT(arrayBuffer); // This is essentially an out of memory crash |
|
haraken
2015/10/29 18:58:37
You've added a bunch of RELEASE_ASSERT(arrayBuffer
Justin Novosad
2015/11/05 00:17:51
Done. Turns out that I made a mistake about this c
|
| *value = toV8(arrayBuffer.release(), m_scriptState->context()->Global(), isolate()); |
| return !value->IsEmpty(); |
| } |