- Revision
- 210457
- Author
- [email protected]
- Date
- 2017-01-06 15:30:57 -0800 (Fri, 06 Jan 2017)
Log Message
@putByValDirect in Array.of and Array.from overwrites non-writable/configurable properties
https://bugs.webkit.org/show_bug.cgi?id=153486
Reviewed by Saam Barati.
JSTests:
New regression test.
* stress/regress-153486.js: Added.
(shouldEqual):
(makeUnwriteableUnconfigurableObject):
(testArrayOf):
(testArrayFrom):
(runTest):
Source/_javascript_Core:
Moved read only check in putDirect() to all paths.
* runtime/SparseArrayValueMap.cpp:
(JSC::SparseArrayValueMap::putDirect):
Modified Paths
Added Paths
Diff
Modified: trunk/JSTests/ChangeLog (210456 => 210457)
--- trunk/JSTests/ChangeLog 2017-01-06 23:29:09 UTC (rev 210456)
+++ trunk/JSTests/ChangeLog 2017-01-06 23:30:57 UTC (rev 210457)
@@ -1,3 +1,19 @@
+2017-01-06 Michael Saboff <[email protected]>
+
+ @putByValDirect in Array.of and Array.from overwrites non-writable/configurable properties
+ https://bugs.webkit.org/show_bug.cgi?id=153486
+
+ Reviewed by Saam Barati.
+
+ New regression test.
+
+ * stress/regress-153486.js: Added.
+ (shouldEqual):
+ (makeUnwriteableUnconfigurableObject):
+ (testArrayOf):
+ (testArrayFrom):
+ (runTest):
+
2016-12-30 Filip Pizlo <[email protected]>
DeferGC::~DeferGC should be super cheap
Added: trunk/JSTests/stress/regress-153486.js (0 => 210457)
--- trunk/JSTests/stress/regress-153486.js (rev 0)
+++ trunk/JSTests/stress/regress-153486.js 2017-01-06 23:30:57 UTC (rev 210457)
@@ -0,0 +1,48 @@
+// Check frozen Array.of and Array.from don't modify unwritable/unconfigurable entries.
+
+let totalFailed = 0;
+
+function shouldEqual(testId, iteration, actual, expected) {
+ if (actual != expected) {
+ throw "Test #" + testId + ", iteration " + iteration + ", ERROR: expected \"" + expected + "\", got \"" + actual + "\"";
+ }
+}
+
+function makeUnwriteableUnconfigurableObject()
+{
+ return Object.defineProperty([], 0, {value: "frozen", writable: false, configurable: false});
+}
+
+function testArrayOf(obj)
+{
+ Array.of.call(function() { return obj; }, "no longer frozen");
+}
+
+noInline(testArrayOf);
+
+function testArrayFrom(obj)
+{
+ Array.from.call(function() { return obj; }, ["no longer frozen"]);
+}
+
+noInline(testArrayFrom);
+
+let numIterations = 10000;
+
+function runTest(testId, test, sourceMaker, expectedException) {
+ for (var i = 0; i < numIterations; i++) {
+ var exception = "No exception";
+ var obj = sourceMaker();
+
+ try {
+ test(obj);
+ } catch (e) {
+ exception = "" + e;
+ exception = exception.substr(0, 10); // Search for "TypeError:".
+ }
+ shouldEqual(testId, i, exception, expectedException);
+ }
+}
+
+runTest(1, testArrayOf, makeUnwriteableUnconfigurableObject, "TypeError:");
+runTest(2, testArrayFrom, makeUnwriteableUnconfigurableObject, "TypeError:");
Modified: trunk/Source/_javascript_Core/ChangeLog (210456 => 210457)
--- trunk/Source/_javascript_Core/ChangeLog 2017-01-06 23:29:09 UTC (rev 210456)
+++ trunk/Source/_javascript_Core/ChangeLog 2017-01-06 23:30:57 UTC (rev 210457)
@@ -1,3 +1,15 @@
+2017-01-06 Michael Saboff <[email protected]>
+
+ @putByValDirect in Array.of and Array.from overwrites non-writable/configurable properties
+ https://bugs.webkit.org/show_bug.cgi?id=153486
+
+ Reviewed by Saam Barati.
+
+ Moved read only check in putDirect() to all paths.
+
+ * runtime/SparseArrayValueMap.cpp:
+ (JSC::SparseArrayValueMap::putDirect):
+
2016-12-30 Filip Pizlo <[email protected]>
DeferGC::~DeferGC should be super cheap
Modified: trunk/Source/_javascript_Core/runtime/SparseArrayValueMap.cpp (210456 => 210457)
--- trunk/Source/_javascript_Core/runtime/SparseArrayValueMap.cpp 2017-01-06 23:29:09 UTC (rev 210456)
+++ trunk/Source/_javascript_Core/runtime/SparseArrayValueMap.cpp 2017-01-06 23:30:57 UTC (rev 210457)
@@ -137,17 +137,17 @@
AddResult result = add(array, i);
SparseArrayEntry& entry = result.iterator->value;
- if (mode != PutDirectIndexLikePutDirect && !array->isStructureExtensible()) {
- // To save a separate find & add, we first always add to the sparse map.
- // In the uncommon case that this is a new property, and the array is not
- // extensible, this is not the right thing to have done - so remove again.
- if (result.isNewEntry) {
- remove(result.iterator);
- return typeError(exec, scope, shouldThrow, ASCIILiteral(NonExtensibleObjectPropertyDefineError));
- }
- if (entry.attributes & ReadOnly)
- return typeError(exec, scope, shouldThrow, ASCIILiteral(ReadonlyPropertyWriteError));
+ // To save a separate find & add, we first always add to the sparse map.
+ // In the uncommon case that this is a new property, and the array is not
+ // extensible, this is not the right thing to have done - so remove again.
+ if (mode != PutDirectIndexLikePutDirect && result.isNewEntry && !array->isStructureExtensible()) {
+ remove(result.iterator);
+ return typeError(exec, scope, shouldThrow, ASCIILiteral(NonExtensibleObjectPropertyDefineError));
}
+
+ if (entry.attributes & ReadOnly)
+ return typeError(exec, scope, shouldThrow, ASCIILiteral(ReadonlyPropertyWriteError));
+
entry.attributes = attributes;
entry.set(vm, this, value);
return true;