Diff
Modified: branches/safari-600.3-branch/LayoutTests/ChangeLog (177092 => 177093)
--- branches/safari-600.3-branch/LayoutTests/ChangeLog 2014-12-10 21:20:23 UTC (rev 177092)
+++ branches/safari-600.3-branch/LayoutTests/ChangeLog 2014-12-10 21:50:53 UTC (rev 177093)
@@ -1,3 +1,36 @@
+2014-12-10 Matthew Hanson <matthew_han...@apple.com>
+
+ Merge r175243. <rdar://problem/19196762>
+
+ 2014-10-27 Mark Lam <mark....@apple.com>
+
+ Crash when attempting to perform array iteration on a non-array with numeric keys not initialized.
+ <https://webkit.org/b/137814>
+
+ Reviewed by Geoffrey Garen.
+
+ * js/array-length-shortening-expected.txt: Added.
+ * js/array-length-shortening.html: Added.
+ * js/for-of-crash-expected.txt: Added.
+ * js/for-of-crash.html: Added.
+ * js/script-tests/array-length-shortening.js: Added.
+ (testLengthShortening):
+ (denseInt32Elements):
+ (denseDoubleElements):
+ (denseObjectElements):
+ (holeyInt32Elements):
+ (holeyDoubleElements):
+ (holeyObjectElements):
+ (arrayStorageInt32Elements):
+ (arrayStorageDoubleElements):
+ (arrayStorageObjectElements):
+ (sparseInt32Elements):
+ (sparseDoubleElements):
+ (sparseObjectElements):
+ * js/script-tests/for-of-crash.js: Added.
+ (foo):
+
+
2014-12-03 Dana Burkart <dburk...@apple.com>
Merge r176295. <rdar://problem/19122588>
Added: branches/safari-600.3-branch/LayoutTests/js/array-length-shortening-expected.txt (0 => 177093)
--- branches/safari-600.3-branch/LayoutTests/js/array-length-shortening-expected.txt (rev 0)
+++ branches/safari-600.3-branch/LayoutTests/js/array-length-shortening-expected.txt 2014-12-10 21:50:53 UTC (rev 177093)
@@ -0,0 +1,33 @@
+Tests array length shortening.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS count is 1
+PASS count is 1
+PASS count is 1
+PASS count is 1
+PASS count is 1
+PASS count is 1
+PASS count is 1
+PASS count is 1
+PASS count is 1
+PASS count is 1
+PASS count is 1
+PASS count is 1
+PASS count is 1
+PASS count is 1
+PASS count is 1
+PASS count is 1
+PASS count is 1
+PASS count is 1
+PASS count is 1
+PASS count is 1
+PASS count is 1
+PASS count is 1
+PASS count is 1
+PASS count is 1
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Added: branches/safari-600.3-branch/LayoutTests/js/array-length-shortening.html (0 => 177093)
--- branches/safari-600.3-branch/LayoutTests/js/array-length-shortening.html (rev 0)
+++ branches/safari-600.3-branch/LayoutTests/js/array-length-shortening.html 2014-12-10 21:50:53 UTC (rev 177093)
@@ -0,0 +1,10 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<script src=""
+</head>
+<body>
+<script src=""
+<script src=""
+</body>
+</html>
Added: branches/safari-600.3-branch/LayoutTests/js/for-of-crash-expected.txt (0 => 177093)
--- branches/safari-600.3-branch/LayoutTests/js/for-of-crash-expected.txt (rev 0)
+++ branches/safari-600.3-branch/LayoutTests/js/for-of-crash-expected.txt 2014-12-10 21:50:53 UTC (rev 177093)
@@ -0,0 +1,9 @@
+Tests that for-of iteration does not crashes.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Added: branches/safari-600.3-branch/LayoutTests/js/for-of-crash.html (0 => 177093)
--- branches/safari-600.3-branch/LayoutTests/js/for-of-crash.html (rev 0)
+++ branches/safari-600.3-branch/LayoutTests/js/for-of-crash.html 2014-12-10 21:50:53 UTC (rev 177093)
@@ -0,0 +1,10 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<script src=""
+</head>
+<body>
+<script src=""
+<script src=""
+</body>
+</html>
Added: branches/safari-600.3-branch/LayoutTests/js/script-tests/array-length-shortening.js (0 => 177093)
--- branches/safari-600.3-branch/LayoutTests/js/script-tests/array-length-shortening.js (rev 0)
+++ branches/safari-600.3-branch/LayoutTests/js/script-tests/array-length-shortening.js 2014-12-10 21:50:53 UTC (rev 177093)
@@ -0,0 +1,126 @@
+description(
+"Tests array length shortening."
+);
+
+var count;
+
+function testLengthShortening(array) {
+ array.length = 1;
+ count = 0;
+ for (var x of array) {
+ count++;
+ }
+
+ shouldBe("count", "1");
+}
+
+var arr;
+
+// Test Objects with densely packed indexed properties:
+function denseInt32Elements(arr) {
+ arr[0] = 1;
+ arr[1] = 2;
+ return arr;
+}
+testLengthShortening(denseInt32Elements(Object.create(Array.prototype)));
+testLengthShortening(denseInt32Elements([]));
+
+function denseDoubleElements(arr) {
+ arr[0] = 1.5;
+ arr[1] = 2.5;
+ return arr;
+}
+testLengthShortening(denseDoubleElements(Object.create(Array.prototype)));
+testLengthShortening(denseDoubleElements([]));
+
+function denseObjectElements(arr) {
+ arr[0] = {};
+ arr[1] = {};
+ return arr;
+}
+testLengthShortening(denseObjectElements(Object.create(Array.prototype)));
+testLengthShortening(denseObjectElements([]));
+
+// Test Objects with hole-y indexed properties:
+function holeyInt32Elements(arr) {
+ arr[0] = 1;
+ arr[1] = 2;
+ arr[4] = 4;
+ return arr;
+}
+testLengthShortening(holeyInt32Elements(Object.create(Array.prototype)));
+testLengthShortening(holeyInt32Elements([]));
+
+function holeyDoubleElements(arr) {
+ arr[0] = 1.5;
+ arr[1] = 2.5;
+ arr[4] = 4.5;
+ return arr;
+}
+testLengthShortening(holeyDoubleElements(Object.create(Array.prototype)));
+testLengthShortening(holeyDoubleElements([]));
+
+function holeyObjectElements(arr) {
+ arr[0] = {};
+ arr[1] = {};
+ arr[4] = {};
+ return arr;
+}
+testLengthShortening(holeyObjectElements(Object.create(Array.prototype)));
+testLengthShortening(holeyObjectElements([]));
+
+// Test Objects with ArrayStorage indexed properties:
+function arrayStorageInt32Elements(arr) {
+ arr[0] = 1;
+ arr[1] = 2;
+ arr.unshift(100); // Force conversion to using ArrayStorage.
+ return arr;
+}
+testLengthShortening(arrayStorageInt32Elements(Object.create(Array.prototype)));
+testLengthShortening(arrayStorageInt32Elements([]));
+
+function arrayStorageDoubleElements(arr) {
+ arr[0] = 1.5;
+ arr[1] = 2.5;
+ arr.unshift(100.5); // Force conversion to using ArrayStorage.
+ return arr;
+}
+testLengthShortening(arrayStorageDoubleElements(Object.create(Array.prototype)));
+testLengthShortening(arrayStorageDoubleElements([]));
+
+function arrayStorageObjectElements(arr) {
+ arr[0] = {};
+ arr[1] = {};
+ arr.unshift({}); // Force conversion to using ArrayStorage.
+ return arr;
+}
+testLengthShortening(arrayStorageObjectElements(Object.create(Array.prototype)));
+testLengthShortening(arrayStorageObjectElements([]));
+
+// Test Objects with sparse indexed properties:
+function sparseInt32Elements(arr) {
+ arr[0] = 1;
+ arr[1] = 2;
+ arr[100000] = 100;
+ return arr;
+}
+testLengthShortening(sparseInt32Elements(Object.create(Array.prototype)));
+testLengthShortening(sparseInt32Elements([]));
+
+function sparseDoubleElements(arr) {
+ arr[0] = 1.5;
+ arr[1] = 2.5;
+ arr[100000] = 100.5;
+ return arr;
+}
+testLengthShortening(sparseDoubleElements(Object.create(Array.prototype)));
+testLengthShortening(sparseDoubleElements([]));
+
+function sparseObjectElements(arr) {
+ arr[0] = {};
+ arr[1] = {};
+ arr[100000] = {};
+ return arr;
+}
+testLengthShortening(sparseObjectElements(Object.create(Array.prototype)));
+testLengthShortening(sparseObjectElements([]));
Added: branches/safari-600.3-branch/LayoutTests/js/script-tests/for-of-crash.js (0 => 177093)
--- branches/safari-600.3-branch/LayoutTests/js/script-tests/for-of-crash.js (rev 0)
+++ branches/safari-600.3-branch/LayoutTests/js/script-tests/for-of-crash.js 2014-12-10 21:50:53 UTC (rev 177093)
@@ -0,0 +1,10 @@
+description(
+"Tests that for-of iteration does not crashes."
+);
+
+function foo() {
+ var o = Object.create(Array.prototype);
+ for (var x of o) {
+ }
+}
+foo();
Modified: branches/safari-600.3-branch/Source/_javascript_Core/ChangeLog (177092 => 177093)
--- branches/safari-600.3-branch/Source/_javascript_Core/ChangeLog 2014-12-10 21:20:23 UTC (rev 177092)
+++ branches/safari-600.3-branch/Source/_javascript_Core/ChangeLog 2014-12-10 21:50:53 UTC (rev 177093)
@@ -1,3 +1,29 @@
+2014-12-10 Matthew Hanson <matthew_han...@apple.com>
+
+ Merge r175243. <rdar://problem/19196762>
+
+ 2014-10-27 Mark Lam <mark....@apple.com>
+
+ Crash when attempting to perform array iteration on a non-array with numeric keys not initialized.
+ <https://webkit.org/b/137814>
+
+ Reviewed by Geoffrey Garen.
+
+ The arrayIteratorNextThunkGenerator() thunk was not checking for the case where
+ the butterfly may be NULL. This was the source of the crash, and is now fixed.
+
+ In addition, it is also not checking for the case where a property named "length"
+ may have been set on the iterated object. The thunk only checks the butterfly's
+ publicLength for its iteration operation. Array objects will work fine with this
+ because it always updates its butterfly's publicLength when its length changes.
+ In the case of iterable non-Array objects, the "length" property will require a
+ look up outside of the scope of this thunk. The fix is simply to limit the fast
+ case checks in this thunk to Array objects.
+
+ * jit/ThunkGenerators.cpp:
+ (JSC::arrayIteratorNextThunkGenerator):
+
+
2014-12-04 Dana Burkart <dburk...@apple.com>
Merge r176803. <rdar://problem/19034499>
Modified: branches/safari-600.3-branch/Source/_javascript_Core/jit/ThunkGenerators.cpp (177092 => 177093)
--- branches/safari-600.3-branch/Source/_javascript_Core/jit/ThunkGenerators.cpp 2014-12-10 21:20:23 UTC (rev 177092)
+++ branches/safari-600.3-branch/Source/_javascript_Core/jit/ThunkGenerators.cpp 2014-12-10 21:50:53 UTC (rev 177093)
@@ -972,10 +972,12 @@
// Pull out the butterfly from iteratedObject
jit.load8(Address(SpecializedThunkJIT::regT0, JSCell::indexingTypeOffset()), SpecializedThunkJIT::regT3);
jit.loadPtr(Address(SpecializedThunkJIT::regT0, JSObject::butterflyOffset()), SpecializedThunkJIT::regT2);
+ Jump nullButterfly = jit.branchTestPtr(SpecializedThunkJIT::Zero, SpecializedThunkJIT::regT2);
- jit.and32(TrustedImm32(IndexingShapeMask), SpecializedThunkJIT::regT3);
+ Jump notDone = jit.branch32(SpecializedThunkJIT::Below, SpecializedThunkJIT::regT1, Address(SpecializedThunkJIT::regT2, Butterfly::offsetOfPublicLength()));
- Jump notDone = jit.branch32(SpecializedThunkJIT::Below, SpecializedThunkJIT::regT1, Address(SpecializedThunkJIT::regT2, Butterfly::offsetOfPublicLength()));
+ nullButterfly.link(&jit);
+
// Return the termination signal to indicate that we've finished
jit.move(TrustedImmPtr(vm->iterationTerminator.get()), SpecializedThunkJIT::regT0);
jit.returnJSCell(SpecializedThunkJIT::regT0);
@@ -994,8 +996,8 @@
jit.appendFailure(jit.branch32(SpecializedThunkJIT::AboveOrEqual, SpecializedThunkJIT::regT1, Address(SpecializedThunkJIT::regT2, Butterfly::offsetOfVectorLength())));
// So now we perform inline loads for int32, value/undecided, and double storage
- Jump undecidedStorage = jit.branch32(SpecializedThunkJIT::Equal, SpecializedThunkJIT::regT3, TrustedImm32(UndecidedShape));
- Jump notContiguousStorage = jit.branch32(SpecializedThunkJIT::NotEqual, SpecializedThunkJIT::regT3, TrustedImm32(ContiguousShape));
+ Jump undecidedStorage = jit.branch32(SpecializedThunkJIT::Equal, SpecializedThunkJIT::regT3, TrustedImm32(ArrayWithUndecided));
+ Jump notContiguousStorage = jit.branch32(SpecializedThunkJIT::NotEqual, SpecializedThunkJIT::regT3, TrustedImm32(ArrayWithContiguous));
undecidedStorage.link(&jit);
@@ -1023,14 +1025,14 @@
#endif
notContiguousStorage.link(&jit);
- Jump notInt32Storage = jit.branch32(SpecializedThunkJIT::NotEqual, SpecializedThunkJIT::regT3, TrustedImm32(Int32Shape));
+ Jump notInt32Storage = jit.branch32(SpecializedThunkJIT::NotEqual, SpecializedThunkJIT::regT3, TrustedImm32(ArrayWithInt32));
jit.loadPtr(Address(SpecializedThunkJIT::regT0, JSObject::butterflyOffset()), SpecializedThunkJIT::regT2);
jit.load32(BaseIndex(SpecializedThunkJIT::regT2, SpecializedThunkJIT::regT1, SpecializedThunkJIT::TimesEight, JSValue::offsetOfPayload()), SpecializedThunkJIT::regT0);
jit.add32(TrustedImm32(1), Address(SpecializedThunkJIT::regT4, JSArrayIterator::offsetOfNextIndex()));
jit.returnInt32(SpecializedThunkJIT::regT0);
notInt32Storage.link(&jit);
- jit.appendFailure(jit.branch32(SpecializedThunkJIT::NotEqual, SpecializedThunkJIT::regT3, TrustedImm32(DoubleShape)));
+ jit.appendFailure(jit.branch32(SpecializedThunkJIT::NotEqual, SpecializedThunkJIT::regT3, TrustedImm32(ArrayWithDouble)));
jit.loadPtr(Address(SpecializedThunkJIT::regT0, JSObject::butterflyOffset()), SpecializedThunkJIT::regT2);
jit.loadDouble(BaseIndex(SpecializedThunkJIT::regT2, SpecializedThunkJIT::regT1, SpecializedThunkJIT::TimesEight), SpecializedThunkJIT::fpRegT0);
jit.add32(TrustedImm32(1), Address(SpecializedThunkJIT::regT4, JSArrayIterator::offsetOfNextIndex()));