- Revision
- 198676
- Author
- [email protected]
- Date
- 2016-03-25 11:07:35 -0700 (Fri, 25 Mar 2016)
Log Message
putByIndexBeyondVectorLengthWithoutAttributes should not crash if it can't ensureLength
https://bugs.webkit.org/show_bug.cgi?id=155730
Reviewed by Saam Barati.
This patch makes ensureLength return a boolean indicating if it was able to set the length.
ensureLength also no longer sets the butterfly to null if the allocation of the butterfly
fails. All of ensureLengths callers including putByIndexBeyondVectorLengthWithoutAttributes
have been adapted to throw an out of memory error if ensureLength fails.
* runtime/JSArray.cpp:
(JSC::JSArray::setLength):
(JSC::JSArray::unshiftCountWithAnyIndexingType):
* runtime/JSObject.cpp:
(JSC::JSObject::putByIndexBeyondVectorLengthWithoutAttributes):
(JSC::JSObject::ensureLengthSlow):
* runtime/JSObject.h:
(JSC::JSObject::ensureLength):
Modified Paths
Diff
Modified: trunk/Source/_javascript_Core/ChangeLog (198675 => 198676)
--- trunk/Source/_javascript_Core/ChangeLog 2016-03-25 18:07:31 UTC (rev 198675)
+++ trunk/Source/_javascript_Core/ChangeLog 2016-03-25 18:07:35 UTC (rev 198676)
@@ -1,3 +1,24 @@
+2016-03-25 Keith Miller <[email protected]>
+
+ putByIndexBeyondVectorLengthWithoutAttributes should not crash if it can't ensureLength
+ https://bugs.webkit.org/show_bug.cgi?id=155730
+
+ Reviewed by Saam Barati.
+
+ This patch makes ensureLength return a boolean indicating if it was able to set the length.
+ ensureLength also no longer sets the butterfly to null if the allocation of the butterfly
+ fails. All of ensureLengths callers including putByIndexBeyondVectorLengthWithoutAttributes
+ have been adapted to throw an out of memory error if ensureLength fails.
+
+ * runtime/JSArray.cpp:
+ (JSC::JSArray::setLength):
+ (JSC::JSArray::unshiftCountWithAnyIndexingType):
+ * runtime/JSObject.cpp:
+ (JSC::JSObject::putByIndexBeyondVectorLengthWithoutAttributes):
+ (JSC::JSObject::ensureLengthSlow):
+ * runtime/JSObject.h:
+ (JSC::JSObject::ensureLength):
+
2016-03-25 Caitlin Potter <[email protected]>
[JSC] implement String.prototype.padStart() and String.prototype.padEnd() proposal
Modified: trunk/Source/_javascript_Core/runtime/JSArray.cpp (198675 => 198676)
--- trunk/Source/_javascript_Core/runtime/JSArray.cpp 2016-03-25 18:07:31 UTC (rev 198675)
+++ trunk/Source/_javascript_Core/runtime/JSArray.cpp 2016-03-25 18:07:35 UTC (rev 198676)
@@ -421,7 +421,10 @@
ensureArrayStorage(exec->vm()));
}
if (newLength > butterfly->publicLength()) {
- ensureLength(exec->vm(), newLength);
+ if (!ensureLength(exec->vm(), newLength)) {
+ throwOutOfMemoryError(exec);
+ return false;
+ }
return true;
}
@@ -1014,7 +1017,10 @@
if (oldLength - startIndex >= MIN_SPARSE_ARRAY_INDEX)
return unshiftCountWithArrayStorage(exec, startIndex, count, ensureArrayStorage(exec->vm()));
- ensureLength(exec->vm(), oldLength + count);
+ if (!ensureLength(exec->vm(), oldLength + count)) {
+ throwOutOfMemoryError(exec);
+ return false;
+ }
butterfly = m_butterfly.get();
// We have to check for holes before we start moving things around so that we don't get halfway
@@ -1047,7 +1053,10 @@
if (oldLength - startIndex >= MIN_SPARSE_ARRAY_INDEX)
return unshiftCountWithArrayStorage(exec, startIndex, count, ensureArrayStorage(exec->vm()));
- ensureLength(exec->vm(), oldLength + count);
+ if (!ensureLength(exec->vm(), oldLength + count)) {
+ throwOutOfMemoryError(exec);
+ return false;
+ }
butterfly = m_butterfly.get();
// We have to check for holes before we start moving things around so that we don't get halfway
Modified: trunk/Source/_javascript_Core/runtime/JSObject.cpp (198675 => 198676)
--- trunk/Source/_javascript_Core/runtime/JSObject.cpp 2016-03-25 18:07:31 UTC (rev 198675)
+++ trunk/Source/_javascript_Core/runtime/JSObject.cpp 2016-03-25 18:07:35 UTC (rev 198676)
@@ -2235,7 +2235,10 @@
return result;
}
- ensureLength(vm, i + 1);
+ if (!ensureLength(vm, i + 1)) {
+ throwOutOfMemoryError(exec);
+ return false;
+ }
butterfly = m_butterfly.get();
RELEASE_ASSERT(i < butterfly->vectorLength());
@@ -2753,7 +2756,7 @@
return true;
}
-void JSObject::ensureLengthSlow(VM& vm, unsigned length)
+bool JSObject::ensureLengthSlow(VM& vm, unsigned length)
{
Butterfly* butterfly = m_butterfly.get();
@@ -2770,6 +2773,8 @@
vm, this, structure(), structure()->outOfLineCapacity(), true,
oldVectorLength * sizeof(EncodedJSValue),
newVectorLength * sizeof(EncodedJSValue));
+ if (!butterfly)
+ return false;
m_butterfly.set(vm, this, butterfly);
butterfly->setVectorLength(newVectorLength);
@@ -2778,6 +2783,7 @@
for (unsigned i = oldVectorLength; i < newVectorLength; ++i)
butterfly->contiguousDouble().data()[i] = PNaN;
}
+ return true;
}
void JSObject::reallocateAndShrinkButterfly(VM& vm, unsigned length)
Modified: trunk/Source/_javascript_Core/runtime/JSObject.h (198675 => 198676)
--- trunk/Source/_javascript_Core/runtime/JSObject.h 2016-03-25 18:07:31 UTC (rev 198675)
+++ trunk/Source/_javascript_Core/runtime/JSObject.h 2016-03-25 18:07:35 UTC (rev 198676)
@@ -868,16 +868,18 @@
// Call this if you want setIndexQuickly to succeed and you're sure that
// the array is contiguous.
- void ensureLength(VM& vm, unsigned length)
+ bool WARN_UNUSED_RETURN ensureLength(VM& vm, unsigned length)
{
ASSERT(length < MAX_ARRAY_INDEX);
ASSERT(hasContiguous(indexingType()) || hasInt32(indexingType()) || hasDouble(indexingType()) || hasUndecided(indexingType()));
+ bool result = true;
if (m_butterfly.get()->vectorLength() < length)
- ensureLengthSlow(vm, length);
+ result = ensureLengthSlow(vm, length);
if (m_butterfly.get()->publicLength() < length)
m_butterfly.get()->setPublicLength(length);
+ return result;
}
// Call this if you want to shrink the butterfly backing store, and you're
@@ -933,7 +935,7 @@
JS_EXPORT_PRIVATE void convertInt32ToDoubleOrContiguousWhilePerformingSetIndex(VM&, unsigned index, JSValue);
JS_EXPORT_PRIVATE void convertDoubleToContiguousWhilePerformingSetIndex(VM&, unsigned index, JSValue);
- void ensureLengthSlow(VM&, unsigned length);
+ bool ensureLengthSlow(VM&, unsigned length);
ContiguousJSValues ensureInt32Slow(VM&);
ContiguousDoubles ensureDoubleSlow(VM&);