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

Side by Side Diff: third_party/WebKit/Source/bindings/core/v8/ScriptValueSerializer.cpp

Issue 1414553002: Fix out-of-memory crashes related to ArrayBuffer allocation Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: applied review comments Created 5 years, 2 months 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
OLDNEW
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 958 matching lines...) Expand 10 before | Expand all | Expand 10 after
969 { 969 {
970 v8::Local<v8::RegExp> regExp = value.As<v8::RegExp>(); 970 v8::Local<v8::RegExp> regExp = value.As<v8::RegExp>();
971 m_writer.writeRegExp(regExp->GetSource(), regExp->GetFlags()); 971 m_writer.writeRegExp(regExp->GetSource(), regExp->GetFlags());
972 } 972 }
973 973
974 ScriptValueSerializer::StateBase* ScriptValueSerializer::writeAndGreyArrayBuffer View(v8::Local<v8::Object> object, ScriptValueSerializer::StateBase* next) 974 ScriptValueSerializer::StateBase* ScriptValueSerializer::writeAndGreyArrayBuffer View(v8::Local<v8::Object> object, ScriptValueSerializer::StateBase* next)
975 { 975 {
976 ASSERT(!object.IsEmpty()); 976 ASSERT(!object.IsEmpty());
977 DOMArrayBufferView* arrayBufferView = V8ArrayBufferView::toImpl(object); 977 DOMArrayBufferView* arrayBufferView = V8ArrayBufferView::toImpl(object);
978 if (!arrayBufferView) 978 if (!arrayBufferView)
979 return 0; 979 return nullptr;
980 if (!arrayBufferView->bufferBase()) 980 if (!arrayBufferView->bufferBaseOrNull())
981 return handleError(DataCloneError, "An ArrayBuffer could not be cloned." , next); 981 return handleError(DataCloneError, "An ArrayBuffer could not be cloned." , next);
982 v8::Local<v8::Value> underlyingBuffer = toV8(arrayBufferView->bufferBase(), m_scriptState->context()->Global(), isolate()); 982 v8::Local<v8::Value> underlyingBuffer = toV8(arrayBufferView->bufferBaseOrNu ll(), m_scriptState->context()->Global(), isolate());
983 if (underlyingBuffer.IsEmpty()) 983 if (underlyingBuffer.IsEmpty())
984 return handleError(DataCloneError, "An ArrayBuffer could not be cloned." , next); 984 return handleError(DataCloneError, "An ArrayBuffer could not be cloned." , next);
985 StateBase* stateOut = doSerializeArrayBuffer(underlyingBuffer, next); 985 StateBase* stateOut = doSerializeArrayBuffer(underlyingBuffer, next);
986 if (stateOut) 986 if (stateOut)
987 return stateOut; 987 return stateOut;
988 m_writer.writeArrayBufferView(*arrayBufferView); 988 m_writer.writeArrayBufferView(*arrayBufferView);
989 // This should be safe: we serialize something that we know to be a wrapper (see 989 // This should be safe: we serialize something that we know to be a wrapper (see
990 // the toV8 call above), so the call to doSerializeArrayBuffer should neithe r 990 // the toV8 call above), so the call to doSerializeArrayBuffer should neithe r
991 // cause the system stack to overflow nor should it have potential to reach 991 // cause the system stack to overflow nor should it have potential to reach
992 // this ArrayBufferView again. 992 // this ArrayBufferView again.
(...skipping 532 matching lines...) Expand 10 before | Expand all | Expand 10 after
1525 uint32_t height; 1525 uint32_t height;
1526 uint32_t pixelDataLength; 1526 uint32_t pixelDataLength;
1527 if (!doReadUint32(&width)) 1527 if (!doReadUint32(&width))
1528 return false; 1528 return false;
1529 if (!doReadUint32(&height)) 1529 if (!doReadUint32(&height))
1530 return false; 1530 return false;
1531 if (!doReadUint32(&pixelDataLength)) 1531 if (!doReadUint32(&pixelDataLength))
1532 return false; 1532 return false;
1533 if (m_position + pixelDataLength > m_length) 1533 if (m_position + pixelDataLength > m_length)
1534 return false; 1534 return false;
1535 ImageData* imageData = ImageData::create(IntSize(width, height)); 1535 NonThrowableExceptionState exceptionState;
1536 ImageData* imageData = ImageData::create(IntSize(width, height), exceptionSt ate);
1537 if (exceptionState.hadException())
1538 return false;
1536 DOMUint8ClampedArray* pixelArray = imageData->data(); 1539 DOMUint8ClampedArray* pixelArray = imageData->data();
1537 ASSERT(pixelArray); 1540 ASSERT(pixelArray);
1538 ASSERT(pixelArray->length() >= pixelDataLength); 1541 ASSERT(pixelArray->length() >= pixelDataLength);
1539 memcpy(pixelArray->data(), m_buffer + m_position, pixelDataLength); 1542 memcpy(pixelArray->data(), m_buffer + m_position, pixelDataLength);
1540 m_position += pixelDataLength; 1543 m_position += pixelDataLength;
1541 *value = toV8(imageData, m_scriptState->context()->Global(), isolate()); 1544 *value = toV8(imageData, m_scriptState->context()->Global(), isolate());
1542 return !value->IsEmpty(); 1545 return !value->IsEmpty();
1543 } 1546 }
1544 1547
1545 bool SerializedScriptValueReader::readCompositorProxy(v8::Local<v8::Value>* valu e) 1548 bool SerializedScriptValueReader::readCompositorProxy(v8::Local<v8::Value>* valu e)
1546 { 1549 {
1547 uint32_t attributes; 1550 uint32_t attributes;
1548 uint64_t element; 1551 uint64_t element;
1549 if (!doReadUint64(&element)) 1552 if (!doReadUint64(&element))
1550 return false; 1553 return false;
1551 if (!doReadUint32(&attributes)) 1554 if (!doReadUint32(&attributes))
1552 return false; 1555 return false;
1553 1556
1554 CompositorProxy* compositorProxy = CompositorProxy::create(element, attribut es); 1557 CompositorProxy* compositorProxy = CompositorProxy::create(element, attribut es);
1555 *value = toV8(compositorProxy, m_scriptState->context()->Global(), isolate() ); 1558 *value = toV8(compositorProxy, m_scriptState->context()->Global(), isolate() );
1556 return !value->IsEmpty(); 1559 return !value->IsEmpty();
1557 } 1560 }
1558 1561
1559 PassRefPtr<DOMArrayBuffer> SerializedScriptValueReader::doReadArrayBuffer() 1562 PassRefPtr<DOMArrayBuffer> SerializedScriptValueReader::doReadArrayBufferOrNull( )
jsbell 2015/10/20 22:25:50 Since this already returned nullptr in some cases,
1560 { 1563 {
1561 uint32_t byteLength; 1564 uint32_t byteLength;
1562 if (!doReadUint32(&byteLength)) 1565 if (!doReadUint32(&byteLength))
1563 return nullptr; 1566 return nullptr;
1564 if (m_position + byteLength > m_length) 1567 if (m_position + byteLength > m_length)
1565 return nullptr; 1568 return nullptr;
1566 const void* bufferStart = m_buffer + m_position; 1569 const void* bufferStart = m_buffer + m_position;
1567 m_position += byteLength; 1570 m_position += byteLength;
1568 return DOMArrayBuffer::create(bufferStart, byteLength); 1571 return DOMArrayBuffer::createOrNull(bufferStart, byteLength);
1569 } 1572 }
1570 1573
1571 bool SerializedScriptValueReader::readArrayBuffer(v8::Local<v8::Value>* value) 1574 bool SerializedScriptValueReader::readArrayBuffer(v8::Local<v8::Value>* value)
1572 { 1575 {
1573 RefPtr<DOMArrayBuffer> arrayBuffer = doReadArrayBuffer(); 1576 RefPtr<DOMArrayBuffer> arrayBuffer = doReadArrayBufferOrNull();
1574 if (!arrayBuffer) 1577 if (!arrayBuffer)
1575 return false; 1578 return false;
jsbell 2015/10/20 22:25:50 I'm embarrassed to say I don't know how we handle
1576 *value = toV8(arrayBuffer.release(), m_scriptState->context()->Global(), iso late()); 1579 *value = toV8(arrayBuffer.release(), m_scriptState->context()->Global(), iso late());
1577 return !value->IsEmpty(); 1580 return !value->IsEmpty();
1578 } 1581 }
1579 1582
1580 bool SerializedScriptValueReader::readArrayBufferView(v8::Local<v8::Value>* valu e, ScriptValueCompositeCreator& creator) 1583 bool SerializedScriptValueReader::readArrayBufferView(v8::Local<v8::Value>* valu e, ScriptValueCompositeCreator& creator)
1581 { 1584 {
1582 ArrayBufferViewSubTag subTag; 1585 ArrayBufferViewSubTag subTag;
1583 uint32_t byteOffset; 1586 uint32_t byteOffset;
1584 uint32_t byteLength; 1587 uint32_t byteLength;
1585 RefPtr<DOMArrayBufferBase> arrayBuffer; 1588 RefPtr<DOMArrayBufferBase> arrayBuffer;
(...skipping 571 matching lines...) Expand 10 before | Expand all | Expand 10 after
2157 return false; 2160 return false;
2158 uint32_t objectReference = m_openCompositeReferenceStack[m_openCompositeRefe renceStack.size() - 1]; 2161 uint32_t objectReference = m_openCompositeReferenceStack[m_openCompositeRefe renceStack.size() - 1];
2159 m_openCompositeReferenceStack.shrink(m_openCompositeReferenceStack.size() - 1); 2162 m_openCompositeReferenceStack.shrink(m_openCompositeReferenceStack.size() - 1);
2160 if (objectReference >= m_objectPool.size()) 2163 if (objectReference >= m_objectPool.size())
2161 return false; 2164 return false;
2162 *object = m_objectPool[objectReference]; 2165 *object = m_objectPool[objectReference];
2163 return true; 2166 return true;
2164 } 2167 }
2165 2168
2166 } // namespace blink 2169 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698