Changeset 206948 in webkit
- Timestamp:
- Oct 7, 2016 8:20:53 PM (8 years ago)
- Location:
- trunk
- Files:
-
- 2 added
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JSTests/ChangeLog
r206846 r206948 1 2016-10-07 Mark Lam <mark.lam@apple.com> 2 3 Object.freeze() and seal() should throw if [[PreventExtensions]]() fails. 4 https://bugs.webkit.org/show_bug.cgi?id=163160 5 6 Reviewed by Saam Barati. 7 8 * stress/object-freeze-with-proxy-preventExtensions.js: Added. 9 * stress/object-seal-with-proxy-preventExtensions.js: Added. 10 1 11 2016-10-05 Yusuke Suzuki <utatane.tea@gmail.com> 2 12 -
trunk/Source/JavaScriptCore/ChangeLog
r206899 r206948 1 2016-10-07 Mark Lam <mark.lam@apple.com> 2 3 Object.freeze() and seal() should throw if [[PreventExtensions]]() fails. 4 https://bugs.webkit.org/show_bug.cgi?id=163160 5 6 Reviewed by Saam Barati. 7 8 See https://tc39.github.io/ecma262/#sec-object.freeze, 9 https://tc39.github.io/ecma262/#sec-object.seal, and 10 https://tc39.github.io/ecma262/#sec-setintegritylevel. We need to call 11 preventExtensions first before proceeding to freeze / seal the object. If 12 preventExtensions fails, we should throw a TypeError. 13 14 * runtime/ObjectConstructor.cpp: 15 (JSC::setIntegrityLevel): 16 (JSC::objectConstructorSeal): 17 (JSC::objectConstructorFreeze): 18 1 19 2016-10-06 Yusuke Suzuki <utatane.tea@gmail.com> 2 20 -
trunk/Source/JavaScriptCore/runtime/ObjectConstructor.cpp
r206778 r206948 472 472 } 473 473 474 enum class IntegrityLevel { 475 Sealed, 476 Frozen 477 }; 478 479 template<IntegrityLevel level> 480 bool setIntegrityLevel(ExecState* exec, VM& vm, JSObject* object) 481 { 482 // See https://tc39.github.io/ecma262/#sec-setintegritylevel. 483 auto scope = DECLARE_THROW_SCOPE(vm); 484 485 bool success = object->methodTable(vm)->preventExtensions(object, exec); 486 RETURN_IF_EXCEPTION(scope, false); 487 if (UNLIKELY(!success)) 488 return false; 489 490 PropertyNameArray properties(exec, PropertyNameMode::StringsAndSymbols); 491 object->methodTable(vm)->getOwnPropertyNames(object, exec, properties, EnumerationMode(DontEnumPropertiesMode::Include)); 492 RETURN_IF_EXCEPTION(scope, false); 493 494 PropertyNameArray::const_iterator end = properties.end(); 495 for (PropertyNameArray::const_iterator iter = properties.begin(); iter != end; ++iter) { 496 Identifier propertyName = *iter; 497 if (vm.propertyNames->isPrivateName(propertyName)) 498 continue; 499 500 PropertyDescriptor desc; 501 if (level == IntegrityLevel::Sealed) 502 desc.setConfigurable(false); 503 else { 504 if (!object->getOwnPropertyDescriptor(exec, propertyName, desc)) 505 continue; 506 507 if (desc.isDataDescriptor()) 508 desc.setWritable(false); 509 510 desc.setConfigurable(false); 511 } 512 513 object->methodTable(vm)->defineOwnProperty(object, exec, propertyName, desc, true); 514 RETURN_IF_EXCEPTION(scope, false); 515 } 516 return true; 517 } 518 474 519 EncodedJSValue JSC_HOST_CALL objectConstructorSeal(ExecState* exec) 475 520 { … … 488 533 } 489 534 490 // 2. For each named own property name P of O, 491 PropertyNameArray properties(exec, PropertyNameMode::StringsAndSymbols); 492 object->methodTable(vm)->getOwnPropertyNames(object, exec, properties, EnumerationMode(DontEnumPropertiesMode::Include)); 493 RETURN_IF_EXCEPTION(scope, encodedJSValue()); 494 PropertyNameArray::const_iterator end = properties.end(); 495 for (PropertyNameArray::const_iterator iter = properties.begin(); iter != end; ++iter) { 496 Identifier propertyName = *iter; 497 if (exec->propertyNames().isPrivateName(propertyName)) 498 continue; 499 // a. Let desc be the result of calling the [[GetOwnProperty]] internal method of O with P. 500 PropertyDescriptor desc; 501 if (!object->getOwnPropertyDescriptor(exec, propertyName, desc)) 502 continue; 503 // b. If desc.[[Configurable]] is true, set desc.[[Configurable]] to false. 504 desc.setConfigurable(false); 505 // c. Call the [[DefineOwnProperty]] internal method of O with P, desc, and true as arguments. 506 object->methodTable(vm)->defineOwnProperty(object, exec, propertyName, desc, true); 507 RETURN_IF_EXCEPTION(scope, encodedJSValue()); 508 } 509 510 // 3. Set the [[Extensible]] internal property of O to false. 511 object->methodTable(vm)->preventExtensions(object, exec); 512 RETURN_IF_EXCEPTION(scope, encodedJSValue()); 513 514 // 4. Return O. 535 bool success = setIntegrityLevel<IntegrityLevel::Sealed>(exec, vm, object); 536 RETURN_IF_EXCEPTION(scope, encodedJSValue()); 537 if (!success) { 538 throwTypeError(exec, scope, ASCIILiteral("Unable to prevent extension in Object.seal")); 539 return encodedJSValue(); 540 } 541 515 542 return JSValue::encode(obj); 516 543 } … … 526 553 } 527 554 528 // 2. For each named own property name P of O, 529 PropertyNameArray properties(exec, PropertyNameMode::StringsAndSymbols); 530 object->methodTable(vm)->getOwnPropertyNames(object, exec, properties, EnumerationMode(DontEnumPropertiesMode::Include)); 555 bool success = setIntegrityLevel<IntegrityLevel::Frozen>(exec, vm, object); 531 556 RETURN_IF_EXCEPTION(scope, nullptr); 532 PropertyNameArray::const_iterator end = properties.end(); 533 for (PropertyNameArray::const_iterator iter = properties.begin(); iter != end; ++iter) { 534 Identifier propertyName = *iter; 535 if (exec->propertyNames().isPrivateName(propertyName)) 536 continue; 537 // a. Let desc be the result of calling the [[GetOwnProperty]] internal method of O with P. 538 PropertyDescriptor desc; 539 if (!object->getOwnPropertyDescriptor(exec, propertyName, desc)) 540 continue; 541 // b. If IsDataDescriptor(desc) is true, then 542 // i. If desc.[[Writable]] is true, set desc.[[Writable]] to false. 543 if (desc.isDataDescriptor()) 544 desc.setWritable(false); 545 // c. If desc.[[Configurable]] is true, set desc.[[Configurable]] to false. 546 desc.setConfigurable(false); 547 // d. Call the [[DefineOwnProperty]] internal method of O with P, desc, and true as arguments. 548 object->methodTable(vm)->defineOwnProperty(object, exec, propertyName, desc, true); 549 RETURN_IF_EXCEPTION(scope, nullptr); 550 } 551 552 // 3. Set the [[Extensible]] internal property of O to false. 553 object->methodTable(vm)->preventExtensions(object, exec); 554 RETURN_IF_EXCEPTION(scope, nullptr); 555 556 // 4. Return O. 557 if (!success) 558 return throwTypeError(exec, scope, ASCIILiteral("Unable to prevent extension in Object.freeze")); 557 559 return object; 558 560 }
Note: See TracChangeset
for help on using the changeset viewer.