Diff
Modified: trunk/LayoutTests/ChangeLog (158582 => 158583)
--- trunk/LayoutTests/ChangeLog 2013-11-04 18:45:03 UTC (rev 158582)
+++ trunk/LayoutTests/ChangeLog 2013-11-04 19:52:04 UTC (rev 158583)
@@ -1,3 +1,17 @@
+2013-11-04 Mark Hahnenberg <[email protected]>
+
+ JSArrayBufferViews of length 0 allocate 0 CopiedSpace bytes, which is invalid
+ https://bugs.webkit.org/show_bug.cgi?id=123746
+
+ Reviewed by Geoffrey Garen.
+
+ Added a test to make sure that we don't crash when allocating a typed array with 0 length.
+
+ * js/script-tests/typedarray-zero-size.js: Added.
+ (foo):
+ * js/typedarray-zero-size-expected.txt: Added.
+ * js/typedarray-zero-size.html: Added.
+
2013-11-04 Alexey Proskuryakov <[email protected]>
Implement generateKey for HMAC and AES-CBC
Added: trunk/LayoutTests/js/script-tests/typedarray-zero-size.js (0 => 158583)
--- trunk/LayoutTests/js/script-tests/typedarray-zero-size.js (rev 0)
+++ trunk/LayoutTests/js/script-tests/typedarray-zero-size.js 2013-11-04 19:52:04 UTC (rev 158583)
@@ -0,0 +1,22 @@
+description(
+"Tests that creating TypedArrays of length 0 doesn't cause us to crash."
+);
+
+var array = new Uint8Array(0);
+
+function foo() {
+ return new Uint16Array(0);
+}
+
+var result = 0;
+
+for (var i = 1; i < 10001; i++) {
+ var newArray = foo();
+ var otherArray = new Array(i);
+ for (var j = 0; j < i; ++j)
+ otherArray[j] = j;
+ result += otherArray[i - 1];
+}
+
+if (result != (10000 * 9999) / 2)
+ throw "Bad result: " + result;
Added: trunk/LayoutTests/js/typedarray-zero-size-expected.txt (0 => 158583)
--- trunk/LayoutTests/js/typedarray-zero-size-expected.txt (rev 0)
+++ trunk/LayoutTests/js/typedarray-zero-size-expected.txt 2013-11-04 19:52:04 UTC (rev 158583)
@@ -0,0 +1,9 @@
+Tests that creating TypedArrays of length 0 doesn't cause us to crash.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Added: trunk/LayoutTests/js/typedarray-zero-size.html (0 => 158583)
--- trunk/LayoutTests/js/typedarray-zero-size.html (rev 0)
+++ trunk/LayoutTests/js/typedarray-zero-size.html 2013-11-04 19:52:04 UTC (rev 158583)
@@ -0,0 +1,10 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<script src=""
+</head>
+<body>
+<script src=""
+<script src=""
+</body>
+</html>
Modified: trunk/Source/_javascript_Core/ChangeLog (158582 => 158583)
--- trunk/Source/_javascript_Core/ChangeLog 2013-11-04 18:45:03 UTC (rev 158582)
+++ trunk/Source/_javascript_Core/ChangeLog 2013-11-04 19:52:04 UTC (rev 158583)
@@ -1,3 +1,36 @@
+2013-11-04 Mark Hahnenberg <[email protected]>
+
+ JSArrayBufferViews of length 0 allocate 0 CopiedSpace bytes, which is invalid
+ https://bugs.webkit.org/show_bug.cgi?id=123746
+
+ Reviewed by Geoffrey Garen.
+
+ This patch disallows clients from allocating 0 bytes in CopiedSpace. We enforce this invariant
+ with an ASSERT in C++ code and a breakpoint in JIT code. Clients who care about 0-byte
+ allocations (like JSArrayBufferViews) must handle that case themselves, but we don't punish
+ anybody else for the rare case that somebody decides to allocate a 0-length typed array.
+ It also makes the allocation and copying cases consistent for CopiedSpace: no 0-byte allocations,
+ no 0-byte copying.
+
+ Also added a check so that JSArrayBufferViews don't try to copy their m_vector backing store when
+ their length is 0. Also sprinkled several ASSERTs throughout the JSArrayBufferView code to make sure that
+ when length is 0 m_vector is null.
+
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::compileNewTypedArray):
+ * dfg/DFGSpeculativeJIT.h:
+ (JSC::DFG::SpeculativeJIT::emitAllocateBasicStorage):
+ * heap/CopiedSpaceInlines.h:
+ (JSC::CopiedSpace::tryAllocate):
+ * runtime/ArrayBuffer.h:
+ (JSC::ArrayBuffer::create):
+ * runtime/JSArrayBufferView.cpp:
+ (JSC::JSArrayBufferView::ConstructionContext::ConstructionContext):
+ * runtime/JSGenericTypedArrayViewInlines.h:
+ (JSC::::visitChildren):
+ (JSC::::copyBackingStore):
+ (JSC::::slowDownAndWasteMemory):
+
2013-11-04 Julien Brianceau <[email protected]>
[sh4] Refactor jumps in baseline JIT to return label after the jump.
Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp (158582 => 158583)
--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp 2013-11-04 18:45:03 UTC (rev 158582)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp 2013-11-04 19:52:04 UTC (rev 158583)
@@ -4709,6 +4709,7 @@
slowCases.append(m_jit.branch32(
MacroAssembler::Above, sizeGPR, TrustedImm32(JSArrayBufferView::fastSizeLimit)));
+ slowCases.append(m_jit.branchTest32(MacroAssembler::Zero, sizeGPR));
m_jit.move(sizeGPR, scratchGPR);
m_jit.lshift32(TrustedImm32(logElementSize(type)), scratchGPR);
Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h (158582 => 158583)
--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h 2013-11-04 18:45:03 UTC (rev 158582)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h 2013-11-04 19:52:04 UTC (rev 158583)
@@ -2052,7 +2052,15 @@
MacroAssembler::Jump emitAllocateBasicStorage(SizeType size, GPRReg resultGPR)
{
CopiedAllocator* copiedAllocator = &m_jit.vm()->heap.storageAllocator();
-
+
+ // It's invalid to allocate zero bytes in CopiedSpace.
+#ifndef NDEBUG
+ m_jit.move(size, resultGPR);
+ MacroAssembler::Jump nonZeroSize = m_jit.branchTest32(MacroAssembler::NonZero, resultGPR);
+ m_jit.breakpoint();
+ nonZeroSize.link(&m_jit);
+#endif
+
m_jit.loadPtr(&copiedAllocator->m_currentRemaining, resultGPR);
MacroAssembler::Jump slowPath = m_jit.branchSubPtr(JITCompiler::Signed, size, resultGPR);
m_jit.storePtr(resultGPR, &copiedAllocator->m_currentRemaining);
Modified: trunk/Source/_javascript_Core/heap/CopiedSpaceInlines.h (158582 => 158583)
--- trunk/Source/_javascript_Core/heap/CopiedSpaceInlines.h 2013-11-04 18:45:03 UTC (rev 158582)
+++ trunk/Source/_javascript_Core/heap/CopiedSpaceInlines.h 2013-11-04 19:52:04 UTC (rev 158583)
@@ -150,6 +150,7 @@
inline CheckedBoolean CopiedSpace::tryAllocate(size_t bytes, void** outPtr)
{
ASSERT(!m_heap->vm()->isInitializingObject());
+ ASSERT(bytes);
if (!m_allocator.tryAllocate(bytes, outPtr))
return tryAllocateSlowCase(bytes, outPtr);
Modified: trunk/Source/_javascript_Core/runtime/ArrayBuffer.h (158582 => 158583)
--- trunk/Source/_javascript_Core/runtime/ArrayBuffer.h 2013-11-04 18:45:03 UTC (rev 158582)
+++ trunk/Source/_javascript_Core/runtime/ArrayBuffer.h 2013-11-04 19:52:04 UTC (rev 158583)
@@ -160,6 +160,7 @@
if (!contents.m_data)
return 0;
RefPtr<ArrayBuffer> buffer = adoptRef(new ArrayBuffer(contents));
+ ASSERT(!byteLength || source);
memcpy(buffer->data(), source, byteLength);
return buffer.release();
}
Modified: trunk/Source/_javascript_Core/runtime/JSArrayBufferView.cpp (158582 => 158583)
--- trunk/Source/_javascript_Core/runtime/JSArrayBufferView.cpp 2013-11-04 18:45:03 UTC (rev 158582)
+++ trunk/Source/_javascript_Core/runtime/JSArrayBufferView.cpp 2013-11-04 19:52:04 UTC (rev 158583)
@@ -45,9 +45,10 @@
{
if (length <= fastSizeLimit) {
// Attempt GC allocation.
- void* temp;
+ void* temp = 0;
size_t size = sizeOf(length, elementSize);
- if (!vm.heap.tryAllocateStorage(0, size, &temp))
+ // CopiedSpace only allows non-zero size allocations.
+ if (size && !vm.heap.tryAllocateStorage(0, size, &temp))
return;
m_structure = structure;
Modified: trunk/Source/_javascript_Core/runtime/JSGenericTypedArrayViewInlines.h (158582 => 158583)
--- trunk/Source/_javascript_Core/runtime/JSGenericTypedArrayViewInlines.h 2013-11-04 18:45:03 UTC (rev 158582)
+++ trunk/Source/_javascript_Core/runtime/JSGenericTypedArrayViewInlines.h 2013-11-04 19:52:04 UTC (rev 158583)
@@ -441,7 +441,8 @@
switch (thisObject->m_mode) {
case FastTypedArray: {
- visitor.copyLater(thisObject, TypedArrayVectorCopyToken, thisObject->m_vector, thisObject->byteSize());
+ if (thisObject->m_vector)
+ visitor.copyLater(thisObject, TypedArrayVectorCopyToken, thisObject->m_vector, thisObject->byteSize());
break;
}
@@ -469,6 +470,7 @@
if (token == TypedArrayVectorCopyToken
&& visitor.checkIfShouldCopy(thisObject->m_vector)) {
+ ASSERT(thisObject->m_vector);
void* oldVector = thisObject->m_vector;
void* newVector = visitor.allocateNewSpace(thisObject->byteSize());
memcpy(newVector, oldVector, thisObject->byteSize());
@@ -505,6 +507,7 @@
if (thisObject->m_mode == FastTypedArray
&& !thisObject->m_butterfly && size >= sizeof(IndexingHeader)) {
+ ASSERT(thisObject->m_vector);
// Reuse already allocated memory if at all possible.
thisObject->m_butterfly =
static_cast<IndexingHeader*>(thisObject->m_vector)->butterfly();