haikuwebkit/JSTests/stress/put-to-primitive-non-reifie...

65 lines
2.3 KiB
JavaScript
Raw Permalink Normal View History

Unreviewed, reland r276592 with a fix for put() override in prototype chain of a JSProxy https://bugs.webkit.org/show_bug.cgi?id=226185 JSTests: * microbenchmarks/put-slow-no-cache-array.js: Added. * microbenchmarks/put-slow-no-cache-function.js: Added. * microbenchmarks/put-slow-no-cache-js-proxy.js: Added. * microbenchmarks/put-slow-no-cache-long-prototype-chain.js: Added. * microbenchmarks/put-slow-no-cache.js: Added. * microbenchmarks/reflect-set-with-receiver.js: Added. * stress/custom-get-set-proto-chain-put.js: * stress/module-namespace-access-set-fails.js: Added. * stress/put-non-reified-static-accessor-or-custom.js: Added. * stress/put-non-reified-static-function-or-custom.js: Added. * stress/put-to-primitive-non-reified-static-custom.js: Added. * stress/put-to-primitive.js: Added. * stress/put-to-proto-chain-overrides-put.js: Rework to always test new objects, add JSProxy coverage, and assert that receiver has own property. * stress/typed-array-canonical-numeric-index-string-set.js: Added. LayoutTests/imported/w3c: * web-platform-tests/WebIDL/ecmascript-binding/global-object-implicit-this-value.any-expected.txt: * web-platform-tests/WebIDL/ecmascript-binding/interface-object-set-receiver-expected.txt: Added. * web-platform-tests/WebIDL/ecmascript-binding/interface-object-set-receiver.html: Added. * web-platform-tests/WebIDL/ecmascript-binding/interface-prototype-constructor-set-receiver-expected.txt: * web-platform-tests/WebIDL/ecmascript-binding/interface-prototype-constructor-set-receiver.html: Source/JavaScriptCore: The API test added in r278366 revealed a flaw in JSObject::definePropertyOnReceiver() that caused putDirectInternal() to be performed on a JSProxy instead of it's target. Remedies that via a type check, ensuring the test and iOS apps are functional. The issue was originally missed because the prototype chain of a global object is immutable and none of the global object's prototypes override put(). OpaqueJSClass::prototype() sets the [[Prototype]] directly, ignoring the IsImmutablePrototypeExoticObject type info flag. Also, excludes an invariant from the original patch that required put() to be overriden when implementing custom [[DefineOwnProperty]]. It is now broken by WindowProperties object. * API/JSCallbackObject.h: * API/JSCallbackObjectFunctions.h: (JSC::JSCallbackObject<Parent>::put): * API/tests/testapiScripts/testapi.js: * debugger/DebuggerScope.h: * runtime/ClassInfo.h: * runtime/ClonedArguments.h: * runtime/CustomGetterSetter.cpp: (JSC::callCustomSetter): Deleted. * runtime/CustomGetterSetter.h: * runtime/ErrorConstructor.h: * runtime/ErrorInstance.h: * runtime/GenericArguments.h: * runtime/GenericArgumentsInlines.h: (JSC::GenericArguments<Type>::put): * runtime/GetterSetter.h: * runtime/JSArray.cpp: (JSC::JSArray::put): * runtime/JSArray.h: * runtime/JSArrayBufferView.cpp: (JSC::JSArrayBufferView::put): Deleted. * runtime/JSArrayBufferView.h: * runtime/JSCJSValue.cpp: (JSC::JSValue::putToPrimitive): * runtime/JSCell.cpp: (JSC::JSCell::doPutPropertySecurityCheck): Deleted. * runtime/JSCell.h: * runtime/JSFunction.cpp: (JSC::JSFunction::put): * runtime/JSFunction.h: * runtime/JSGenericTypedArrayView.h: * runtime/JSGlobalLexicalEnvironment.h: * runtime/JSGlobalObject.cpp: (JSC::JSGlobalObject::put): * runtime/JSGlobalObject.h: * runtime/JSLexicalEnvironment.h: * runtime/JSModuleEnvironment.h: * runtime/JSModuleNamespaceObject.h: * runtime/JSObject.cpp: (JSC::JSObject::getOwnPropertySlot): (JSC::JSObject::putInlineSlow): (JSC::definePropertyOnReceiverSlow): (JSC::JSObject::definePropertyOnReceiver): (JSC::JSObject::putInlineFastReplacingStaticPropertyIfNeeded): (JSC::JSObject::doPutPropertySecurityCheck): Deleted. (JSC::JSObject::prototypeChainMayInterceptStoreTo): Deleted. * runtime/JSObject.h: (JSC::JSObject::putByIndexInline): (JSC::JSObject::hasNonReifiedStaticProperties): (JSC::JSObject::getOwnPropertySlot): (JSC::JSObject::putDirect): (JSC::JSObject::doPutPropertySecurityCheck): Deleted. * runtime/JSObjectInlines.h: (JSC::JSObject::canPerformFastPutInlineExcludingProto): (JSC::JSObject::putInlineForJSObject): (JSC::JSObject::putInlineFast): (JSC::JSObject::putDirectInternal): * runtime/JSProxy.h: * runtime/JSTypeInfo.h: (JSC::TypeInfo::hasStaticPropertyTable const): (JSC::TypeInfo::overridesPut const): (JSC::TypeInfo::getOwnPropertySlotMayBeWrongAboutDontEnum const): (JSC::TypeInfo::hasPutPropertySecurityCheck const): Deleted. * runtime/Lookup.h: (JSC::putEntry): Deleted. (JSC::lookupPut): Deleted. * runtime/PropertySlot.h: * runtime/ProxyObject.cpp: (JSC::ProxyObject::put): * runtime/ProxyObject.h: * runtime/PutPropertySlot.h: (JSC::PutPropertySlot::PutPropertySlot): (JSC::PutPropertySlot::context const): (JSC::PutPropertySlot::isTaintedByOpaqueObject const): (JSC::PutPropertySlot::setIsTaintedByOpaqueObject): * runtime/ReflectObject.cpp: (JSC::JSC_DEFINE_HOST_FUNCTION): * runtime/RegExpObject.cpp: (JSC::RegExpObject::put): * runtime/RegExpObject.h: * runtime/StringObject.cpp: (JSC::StringObject::put): * runtime/StringObject.h: * runtime/StringPrototype.cpp: (JSC::StringPrototype::finishCreation): (JSC::StringPrototype::create): * runtime/StringPrototype.h: * runtime/Structure.cpp: (JSC::Structure::validateFlags): * runtime/Structure.h: (JSC::Structure::hasNonReifiedStaticProperties const): * tools/JSDollarVM.cpp: Source/WebCore: Tests: js/dom/script-tests/reflect-set-onto-dom.js imported/w3c/web-platform-tests/WebIDL/ecmascript-binding/interface-object-set-receiver.html http/tests/security/cross-frame-access-object-getPrototypeOf-in-put.html * bindings/js/JSDOMWindowCustom.cpp: (WebCore::JSDOMWindow::put): (WebCore::JSDOMWindow::doPutPropertySecurityCheck): Deleted. * bindings/js/JSLocationCustom.cpp: (WebCore::JSLocation::doPutPropertySecurityCheck): Deleted. * bindings/js/JSRemoteDOMWindowCustom.cpp: (WebCore::JSRemoteDOMWindow::put): * bindings/scripts/CodeGeneratorJS.pm: (GeneratePut): (GenerateHeader): * bindings/scripts/test/JS/*: Updated. * bridge/objc/objc_runtime.h: * bridge/runtime_array.h: * bridge/runtime_object.h: Source/WebKit: * WebProcess/Plugins/Netscape/JSNPObject.h: LayoutTests: * http/tests/security/cross-frame-access-object-getPrototypeOf-in-put-expected.txt: * http/tests/security/cross-frame-access-object-getPrototypeOf-in-put.html: * js/dom/reflect-set-onto-dom-expected.txt: * js/dom/script-tests/reflect-set-onto-dom.js: Canonical link: https://commits.webkit.org/238579@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@278589 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2021-06-08 01:53:46 +00:00
"use strict";
function shouldBe(actual, expected) {
if (actual !== expected)
throw new Error(`Bad value: ${actual}!`);
}
function shouldThrow(func, errorMessage) {
let errorThrown = false;
try {
func();
} catch (error) {
errorThrown = true;
if (String(error) !== errorMessage)
throw new Error(`Bad error: ${error}`);
}
if (!errorThrown)
throw new Error("Didn't throw!");
}
const poisonedSetter = { set() { throw new Error("Object.prototype setter should be unreachable!"); } };
const primitives = [true, 1, "", Symbol(), 0n];
(function testStaticCustomValue() {
Object.defineProperties(Object.prototype, {
testStaticValue: poisonedSetter,
testStaticValueNoSetter: poisonedSetter,
testStaticValueReadOnly: poisonedSetter,
});
for (const primitive of primitives) {
const primitivePrototype = Object.getPrototypeOf(primitive);
const staticCustomValue = $vm.createStaticCustomValue();
Object.setPrototypeOf(primitivePrototype, staticCustomValue);
primitive.testStaticValue = 1;
shouldBe(staticCustomValue.testStaticValue, 1);
shouldThrow(() => { primitive.testStaticValue = 1; }, "TypeError: Attempted to assign to readonly property.");
shouldThrow(() => { primitive.testStaticValueNoSetter = 1; }, "TypeError: Attempted to assign to readonly property.");
shouldThrow(() => { primitive.testStaticValueReadOnly = 1; }, "TypeError: Attempted to assign to readonly property.");
Object.setPrototypeOf(primitivePrototype, Object.prototype);
}
})();
(function testStaticCustomAccessor() {
Object.defineProperties(Object.prototype, {
testStaticAccessor: poisonedSetter,
testStaticAccessorReadOnly: poisonedSetter,
});
for (const primitive of primitives) {
const primitivePrototype = Object.getPrototypeOf(primitive);
Object.setPrototypeOf(primitivePrototype, $vm.createStaticCustomAccessor());
for (let i = 0; i < 1000; i++) {
primitive.testStaticAccessor = i;
shouldBe(primitivePrototype.testField, i);
}
shouldThrow(() => { primitive.testStaticAccessorReadOnly = 1; }, "TypeError: Attempted to assign to readonly property.");
Object.setPrototypeOf(primitivePrototype, Object.prototype);
}
})();