Title: [203087] trunk/Source/_javascript_Core
- Revision
- 203087
- Author
- sbar...@apple.com
- Date
- 2016-07-11 15:08:40 -0700 (Mon, 11 Jul 2016)
Log Message
some paths in Array.prototype.splice don't account for the array not having certain indexed properties
https://bugs.webkit.org/show_bug.cgi?id=159641
<rdar://problem/27171999>
Reviewed by Filip Pizlo and Keith Miller.
Array.prototype.splice was incorrectly putting properties on
the result array even if the |this| array didn't have those
properties. This is not the behavior of the spec. However, this
could also cause a crash because we can construct a program where
we would putByIndex on a typed array where the value we are
putting is JSValue(). This is bad because the typed array will
try to convert JSValue() into an integer.
* runtime/ArrayPrototype.cpp:
(JSC::arrayProtoFuncSplice):
* tests/stress/array-prototype-splice-making-typed-array.js: Added.
(assert):
(test):
Modified Paths
Added Paths
Diff
Modified: trunk/Source/_javascript_Core/ChangeLog (203086 => 203087)
--- trunk/Source/_javascript_Core/ChangeLog 2016-07-11 22:02:38 UTC (rev 203086)
+++ trunk/Source/_javascript_Core/ChangeLog 2016-07-11 22:08:40 UTC (rev 203087)
@@ -1,3 +1,25 @@
+2016-07-11 Saam Barati <sbar...@apple.com>
+
+ some paths in Array.prototype.splice don't account for the array not having certain indexed properties
+ https://bugs.webkit.org/show_bug.cgi?id=159641
+ <rdar://problem/27171999>
+
+ Reviewed by Filip Pizlo and Keith Miller.
+
+ Array.prototype.splice was incorrectly putting properties on
+ the result array even if the |this| array didn't have those
+ properties. This is not the behavior of the spec. However, this
+ could also cause a crash because we can construct a program where
+ we would putByIndex on a typed array where the value we are
+ putting is JSValue(). This is bad because the typed array will
+ try to convert JSValue() into an integer.
+
+ * runtime/ArrayPrototype.cpp:
+ (JSC::arrayProtoFuncSplice):
+ * tests/stress/array-prototype-splice-making-typed-array.js: Added.
+ (assert):
+ (test):
+
2016-07-11 Mark Lam <mark....@apple.com>
Refactor JSStack to only be the stack data structure for the C Loop.
Modified: trunk/Source/_javascript_Core/runtime/ArrayPrototype.cpp (203086 => 203087)
--- trunk/Source/_javascript_Core/runtime/ArrayPrototype.cpp 2016-07-11 22:02:38 UTC (rev 203086)
+++ trunk/Source/_javascript_Core/runtime/ArrayPrototype.cpp 2016-07-11 22:08:40 UTC (rev 203087)
@@ -885,6 +885,8 @@
JSValue v = getProperty(exec, thisObj, k + begin);
if (UNLIKELY(vm.exception()))
return JSValue::encode(jsUndefined());
+ if (UNLIKELY(!v))
+ continue;
result->putByIndexInline(exec, k, v, true);
if (UNLIKELY(vm.exception()))
return JSValue::encode(jsUndefined());
@@ -898,6 +900,8 @@
JSValue v = getProperty(exec, thisObj, k + begin);
if (UNLIKELY(vm.exception()))
return JSValue::encode(jsUndefined());
+ if (UNLIKELY(!v))
+ continue;
result->initializeIndex(vm, k, v);
}
}
Added: trunk/Source/_javascript_Core/tests/stress/array-prototype-splice-making-typed-array.js (0 => 203087)
--- trunk/Source/_javascript_Core/tests/stress/array-prototype-splice-making-typed-array.js (rev 0)
+++ trunk/Source/_javascript_Core/tests/stress/array-prototype-splice-making-typed-array.js 2016-07-11 22:08:40 UTC (rev 203087)
@@ -0,0 +1,60 @@
+function assert(b) {
+ if (!b)
+ throw new Error("Bad assertion!")
+}
+
+function test(f, n = 4) {
+ for (let i = 0; i < n; i++)
+ f();
+}
+
+test(function() {
+ // This should not crash.
+
+ // FIXME: this might need to be updated as we make our splice implementation
+ // more ES6 compliant: https://bugs.webkit.org/show_bug.cgi?id=159645
+ let x = [1,2,3,4,5];
+ x.constructor = Uint8Array;
+ delete x[2];
+ assert(!(2 in x));
+ let removed = x.splice(1,3);
+ assert(removed instanceof Uint8Array);
+ assert(removed.length === 3);
+ assert(removed[0] === 2);
+ assert(removed[1] === 0);
+ assert(removed[2] === 4);
+
+ assert(x instanceof Array);
+ assert(x.length === 2);
+ assert(x[0] === 1);
+ assert(x[1] === 5);
+});
+
+test(function() {
+ let x = [1,2,3,4,5];
+ x.constructor = Uint8Array;
+ delete x[2];
+ assert(!(2 in x));
+ Object.defineProperty(Uint8Array, Symbol.species, {value: null});
+ assert(Uint8Array[Symbol.species] === null);
+ x = new Proxy(x, {
+ get(target, property, receiver) {
+ if (parseInt(property, 10))
+ assert(property !== "2");
+ return Reflect.get(target, property, receiver);
+ }
+ });
+
+ let removed = x.splice(1,3);
+ assert(removed instanceof Array); // We shouldn't make a TypedArray here because Symbol.species is null.
+ assert(removed.length === 3);
+ assert(removed[0] === 2);
+ assert(removed[1] === undefined);
+ assert(!(1 in removed));
+ assert(removed[2] === 4);
+
+ assert(x instanceof Array);
+ assert(x.length === 2);
+ assert(x[0] === 1);
+ assert(x[1] === 5);
+});
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes