Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium 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 "config.h" | 5 #include "config.h" |
| 6 #include "bindings/core/v8/ScriptValueSerializer.h" | 6 #include "bindings/core/v8/ScriptValueSerializer.h" |
| 7 | 7 |
| 8 #include "bindings/core/v8/V8ArrayBuffer.h" | 8 #include "bindings/core/v8/V8ArrayBuffer.h" |
| 9 #include "bindings/core/v8/V8ArrayBufferView.h" | 9 #include "bindings/core/v8/V8ArrayBufferView.h" |
| 10 #include "bindings/core/v8/V8Blob.h" | 10 #include "bindings/core/v8/V8Blob.h" |
| (...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 245 void SerializedScriptValueWriter::writeArrayBuffer(const DOMArrayBuffer& arrayBu ffer) | 245 void SerializedScriptValueWriter::writeArrayBuffer(const DOMArrayBuffer& arrayBu ffer) |
| 246 { | 246 { |
| 247 append(ArrayBufferTag); | 247 append(ArrayBufferTag); |
| 248 doWriteArrayBuffer(arrayBuffer); | 248 doWriteArrayBuffer(arrayBuffer); |
| 249 } | 249 } |
| 250 | 250 |
| 251 void SerializedScriptValueWriter::writeArrayBufferView(const DOMArrayBufferView& arrayBufferView) | 251 void SerializedScriptValueWriter::writeArrayBufferView(const DOMArrayBufferView& arrayBufferView) |
| 252 { | 252 { |
| 253 append(ArrayBufferViewTag); | 253 append(ArrayBufferViewTag); |
| 254 #if ENABLE(ASSERT) | 254 #if ENABLE(ASSERT) |
| 255 ASSERT(static_cast<const uint8_t*>(arrayBufferView.bufferBase()->data()) + a rrayBufferView.byteOffset() == | 255 ASSERT(static_cast<const uint8_t*>(arrayBufferView.bufferBaseOrNull()->data( )) + arrayBufferView.byteOffset() == |
| 256 static_cast<const uint8_t*>(arrayBufferView.baseAddress())); | 256 static_cast<const uint8_t*>(arrayBufferView.baseAddress())); |
| 257 #endif | 257 #endif |
| 258 DOMArrayBufferView::ViewType type = arrayBufferView.type(); | 258 DOMArrayBufferView::ViewType type = arrayBufferView.type(); |
| 259 | 259 |
| 260 switch (type) { | 260 switch (type) { |
| 261 case DOMArrayBufferView::TypeInt8: | 261 case DOMArrayBufferView::TypeInt8: |
| 262 append(ByteArrayTag); | 262 append(ByteArrayTag); |
| 263 break; | 263 break; |
| 264 case DOMArrayBufferView::TypeUint8Clamped: | 264 case DOMArrayBufferView::TypeUint8Clamped: |
| 265 append(UnsignedByteClampedArrayTag); | 265 append(UnsignedByteClampedArrayTag); |
| (...skipping 730 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 996 { | 996 { |
| 997 v8::Local<v8::RegExp> regExp = value.As<v8::RegExp>(); | 997 v8::Local<v8::RegExp> regExp = value.As<v8::RegExp>(); |
| 998 m_writer.writeRegExp(regExp->GetSource(), regExp->GetFlags()); | 998 m_writer.writeRegExp(regExp->GetSource(), regExp->GetFlags()); |
| 999 } | 999 } |
| 1000 | 1000 |
| 1001 ScriptValueSerializer::StateBase* ScriptValueSerializer::writeAndGreyArrayBuffer View(v8::Local<v8::Object> object, ScriptValueSerializer::StateBase* next) | 1001 ScriptValueSerializer::StateBase* ScriptValueSerializer::writeAndGreyArrayBuffer View(v8::Local<v8::Object> object, ScriptValueSerializer::StateBase* next) |
| 1002 { | 1002 { |
| 1003 ASSERT(!object.IsEmpty()); | 1003 ASSERT(!object.IsEmpty()); |
| 1004 DOMArrayBufferView* arrayBufferView = V8ArrayBufferView::toImpl(object); | 1004 DOMArrayBufferView* arrayBufferView = V8ArrayBufferView::toImpl(object); |
| 1005 if (!arrayBufferView) | 1005 if (!arrayBufferView) |
| 1006 return 0; | 1006 return nullptr; |
| 1007 if (!arrayBufferView->bufferBase()) | 1007 if (!arrayBufferView->bufferBaseOrNull()) |
| 1008 return handleError(DataCloneError, "An ArrayBuffer could not be cloned." , next); | 1008 return handleError(DataCloneError, "An ArrayBuffer could not be cloned." , next); |
| 1009 v8::Local<v8::Value> underlyingBuffer = toV8(arrayBufferView->bufferBase(), m_scriptState->context()->Global(), isolate()); | 1009 v8::Local<v8::Value> underlyingBuffer = toV8(arrayBufferView->bufferBaseOrNu ll(), m_scriptState->context()->Global(), isolate()); |
| 1010 if (underlyingBuffer.IsEmpty()) | 1010 if (underlyingBuffer.IsEmpty()) |
| 1011 return handleError(DataCloneError, "An ArrayBuffer could not be cloned." , next); | 1011 return handleError(DataCloneError, "An ArrayBuffer could not be cloned." , next); |
| 1012 StateBase* stateOut = doSerializeArrayBuffer(underlyingBuffer, next); | 1012 StateBase* stateOut = doSerializeArrayBuffer(underlyingBuffer, next); |
| 1013 if (stateOut) | 1013 if (stateOut) |
| 1014 return stateOut; | 1014 return stateOut; |
| 1015 m_writer.writeArrayBufferView(*arrayBufferView); | 1015 m_writer.writeArrayBufferView(*arrayBufferView); |
| 1016 // This should be safe: we serialize something that we know to be a wrapper (see | 1016 // This should be safe: we serialize something that we know to be a wrapper (see |
| 1017 // the toV8 call above), so the call to doSerializeArrayBuffer should neithe r | 1017 // the toV8 call above), so the call to doSerializeArrayBuffer should neithe r |
| 1018 // cause the system stack to overflow nor should it have potential to reach | 1018 // cause the system stack to overflow nor should it have potential to reach |
| 1019 // this ArrayBufferView again. | 1019 // this ArrayBufferView again. |
| (...skipping 553 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1573 uint32_t height; | 1573 uint32_t height; |
| 1574 uint32_t pixelDataLength; | 1574 uint32_t pixelDataLength; |
| 1575 if (!doReadUint32(&width)) | 1575 if (!doReadUint32(&width)) |
| 1576 return false; | 1576 return false; |
| 1577 if (!doReadUint32(&height)) | 1577 if (!doReadUint32(&height)) |
| 1578 return false; | 1578 return false; |
| 1579 if (!doReadUint32(&pixelDataLength)) | 1579 if (!doReadUint32(&pixelDataLength)) |
| 1580 return false; | 1580 return false; |
| 1581 if (m_position + pixelDataLength > m_length) | 1581 if (m_position + pixelDataLength > m_length) |
| 1582 return false; | 1582 return false; |
| 1583 ImageData* imageData = ImageData::create(IntSize(width, height)); | 1583 NonThrowableExceptionState exceptionState; |
|
haraken
2015/10/29 16:24:34
Why can't we use a normal ExecptionState?
Justin Novosad
2015/10/29 18:26:02
Added an explanatory comment.
| |
| 1584 ImageData* imageData = ImageData::create(IntSize(width, height), exceptionSt ate); | |
| 1585 if (exceptionState.hadException()) | |
| 1586 return false; | |
| 1584 DOMUint8ClampedArray* pixelArray = imageData->data(); | 1587 DOMUint8ClampedArray* pixelArray = imageData->data(); |
| 1585 ASSERT(pixelArray); | 1588 ASSERT(pixelArray); |
| 1586 ASSERT(pixelArray->length() >= pixelDataLength); | 1589 ASSERT(pixelArray->length() >= pixelDataLength); |
| 1587 memcpy(pixelArray->data(), m_buffer + m_position, pixelDataLength); | 1590 memcpy(pixelArray->data(), m_buffer + m_position, pixelDataLength); |
| 1588 m_position += pixelDataLength; | 1591 m_position += pixelDataLength; |
| 1589 *value = toV8(imageData, m_scriptState->context()->Global(), isolate()); | 1592 *value = toV8(imageData, m_scriptState->context()->Global(), isolate()); |
| 1590 return !value->IsEmpty(); | 1593 return !value->IsEmpty(); |
| 1591 } | 1594 } |
| 1592 | 1595 |
| 1593 bool SerializedScriptValueReader::readCompositorProxy(v8::Local<v8::Value>* valu e) | 1596 bool SerializedScriptValueReader::readCompositorProxy(v8::Local<v8::Value>* valu e) |
| 1594 { | 1597 { |
| 1595 uint32_t attributes; | 1598 uint32_t attributes; |
| 1596 uint64_t element; | 1599 uint64_t element; |
| 1597 if (!doReadUint64(&element)) | 1600 if (!doReadUint64(&element)) |
| 1598 return false; | 1601 return false; |
| 1599 if (!doReadUint32(&attributes)) | 1602 if (!doReadUint32(&attributes)) |
| 1600 return false; | 1603 return false; |
| 1601 | 1604 |
| 1602 CompositorProxy* compositorProxy = CompositorProxy::create(element, attribut es); | 1605 CompositorProxy* compositorProxy = CompositorProxy::create(element, attribut es); |
| 1603 *value = toV8(compositorProxy, m_scriptState->context()->Global(), isolate() ); | 1606 *value = toV8(compositorProxy, m_scriptState->context()->Global(), isolate() ); |
| 1604 return !value->IsEmpty(); | 1607 return !value->IsEmpty(); |
| 1605 } | 1608 } |
| 1606 | 1609 |
| 1607 PassRefPtr<DOMArrayBuffer> SerializedScriptValueReader::doReadArrayBuffer() | 1610 PassRefPtr<DOMArrayBuffer> SerializedScriptValueReader::doReadArrayBufferOrNull( ) |
| 1608 { | 1611 { |
| 1609 uint32_t byteLength; | 1612 uint32_t byteLength; |
| 1610 if (!doReadUint32(&byteLength)) | 1613 if (!doReadUint32(&byteLength)) |
| 1611 return nullptr; | 1614 return nullptr; |
| 1612 if (m_position + byteLength > m_length) | 1615 if (m_position + byteLength > m_length) |
| 1613 return nullptr; | 1616 return nullptr; |
| 1614 const void* bufferStart = m_buffer + m_position; | 1617 const void* bufferStart = m_buffer + m_position; |
| 1615 m_position += byteLength; | 1618 m_position += byteLength; |
| 1616 return DOMArrayBuffer::create(bufferStart, byteLength); | 1619 return DOMArrayBuffer::createOrNull(bufferStart, byteLength); |
| 1617 } | 1620 } |
| 1618 | 1621 |
| 1619 bool SerializedScriptValueReader::readArrayBuffer(v8::Local<v8::Value>* value) | 1622 bool SerializedScriptValueReader::readArrayBuffer(v8::Local<v8::Value>* value) |
| 1620 { | 1623 { |
| 1621 RefPtr<DOMArrayBuffer> arrayBuffer = doReadArrayBuffer(); | 1624 RefPtr<DOMArrayBuffer> arrayBuffer = doReadArrayBufferOrNull(); |
| 1622 if (!arrayBuffer) | 1625 // FIXME(crbug.com/536816): Instead of the following assert, we should consi der doing: |
|
haraken
2015/10/29 16:24:34
FIXME => TODO(junov)
| |
| 1623 return false; | 1626 // if (!arrayBuffer) |
| 1627 // return false; | |
| 1628 // To do that, we need to make sure that call sites would react correctly | |
| 1629 // in this case, with the value not having been set. | |
| 1630 RELEASE_ASSERT(arrayBuffer); // This is essentially an out of memory crash | |
| 1624 *value = toV8(arrayBuffer.release(), m_scriptState->context()->Global(), iso late()); | 1631 *value = toV8(arrayBuffer.release(), m_scriptState->context()->Global(), iso late()); |
| 1625 return !value->IsEmpty(); | 1632 return !value->IsEmpty(); |
| 1626 } | 1633 } |
| 1627 | 1634 |
| 1628 bool SerializedScriptValueReader::readArrayBufferView(v8::Local<v8::Value>* valu e, ScriptValueCompositeCreator& creator) | 1635 bool SerializedScriptValueReader::readArrayBufferView(v8::Local<v8::Value>* valu e, ScriptValueCompositeCreator& creator) |
| 1629 { | 1636 { |
| 1630 ArrayBufferViewSubTag subTag; | 1637 ArrayBufferViewSubTag subTag; |
| 1631 uint32_t byteOffset; | 1638 uint32_t byteOffset; |
| 1632 uint32_t byteLength; | 1639 uint32_t byteLength; |
| 1633 RefPtr<DOMArrayBufferBase> arrayBuffer; | 1640 RefPtr<DOMArrayBufferBase> arrayBuffer; |
| (...skipping 582 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2216 return false; | 2223 return false; |
| 2217 uint32_t objectReference = m_openCompositeReferenceStack[m_openCompositeRefe renceStack.size() - 1]; | 2224 uint32_t objectReference = m_openCompositeReferenceStack[m_openCompositeRefe renceStack.size() - 1]; |
| 2218 m_openCompositeReferenceStack.shrink(m_openCompositeReferenceStack.size() - 1); | 2225 m_openCompositeReferenceStack.shrink(m_openCompositeReferenceStack.size() - 1); |
| 2219 if (objectReference >= m_objectPool.size()) | 2226 if (objectReference >= m_objectPool.size()) |
| 2220 return false; | 2227 return false; |
| 2221 *object = m_objectPool[objectReference]; | 2228 *object = m_objectPool[objectReference]; |
| 2222 return true; | 2229 return true; |
| 2223 } | 2230 } |
| 2224 | 2231 |
| 2225 } // namespace blink | 2232 } // namespace blink |
| OLD | NEW |