haikuwebkit/LayoutTests/js/getOwnPropertyDescriptor-un...

64 lines
2.3 KiB
HTML
Raw Permalink Normal View History

Object.getOwnPropertyDescriptor() returns incomplete descriptor for instance properties https://bugs.webkit.org/show_bug.cgi?id=153817 Reviewed by Geoffrey Garen. LayoutTests/imported/w3c: Rebaseline W3C HTML test now that more checks are passing. Some checks are still failing because getter.call(undefined) / getter.call() currently throws an exception for Window properties but shouldn't. Global object property getters should not require an explicit |this|. * web-platform-tests/html/dom/interfaces-expected.txt: Source/JavaScriptCore: Extend support for Object.getOwnPropertyDescriptor() on native bindings to instance properties (e.g. Unforgeable properties or Global object properties) so that the returned descriptor has getter / setter functions, as expected. * runtime/JSObject.cpp: (JSC::JSObject::reifyAllStaticProperties): Add method that reifies all static properties, including the custom accessors. This is similar to what is done eagerly on the prototype objects in the bindings code. (JSC::JSObject::getOwnPropertyDescriptor): getOwnPropertyDescriptor() would previously fails for custom accessors that are on the instance because getDirect() does not check the static property table and those custom accessors were not reified (We only reified all properties eagerly - including custom accessors - on prototype objects. To address this issue, we now call reifyAllStaticProperties() if the call to getDirect() fails and then call getDirect() again. This fix is however insufficient for Window properties because |this| is a JSDOMWindowShell / JSProxy in this case and getDirect() / reifyAllStaticProperties() would fail as the proxy does not actually have the properties. This issue was addressed by checking if |this| is a JSProxy and then using JSProxy::target() instead of |this| for the calls to getDirect() and for the reification. * runtime/JSObject.h: * runtime/Lookup.h: (JSC::reifyStaticProperty): (JSC::reifyStaticProperties): Move most code in reifyStaticProperties() to a separate function so the code can be shared with JSObject::reifyAllStaticProperties(). reifyStaticProperties() is currently called by the bindings on the prototype objects. Source/WebCore: Update the bindings generator so that property getters / setters now make sure |this| has the right type and throw a TypeError if it does not, as per: - http://heycam.github.io/webidl/#dfn-attribute-getter (step 2.4.2) - http://heycam.github.io/webidl/#dfn-attribute-setter (step 3.5) This was an issue when doing something like: Object.getOwnPropertyDescriptor(window, "location").get.call(nonWindow) We would call toJSDOMWindow(thisValue), which would return null as thisValue is not a JSDOMWindow. We would then dereference this null pointer and crash. We now do a null check and throw a TypeError in this case, as per the Web IDL specification. The generated bindings still have some non-spec compliant behavior though: 1. The getters / setters of instance properties use slotBase instead of thisValue, which means that calling instanceA's getter on instanceB returns instanceA's property insteas of instanceB's. 2. Global object property getters should not require an explicit |this| so calling the following should work: - Object.getOwnPropertyDescriptor(window, "location").get.call() We currently throw in this case. These issues will be addressed in follow-up patches. Tests: js/getOwnPropertyDescriptor-unforgeable-attributes.html js/getOwnPropertyDescriptor-window-attributes.html js/instance-property-getter-other-instance.html * bindings/scripts/CodeGeneratorJS.pm: (GenerateImplementation): * bindings/scripts/test/JS/JSTestActiveDOMObject.cpp: (WebCore::jsTestActiveDOMObjectExcitingAttr): * bindings/scripts/test/JS/JSTestException.cpp: (WebCore::jsTestExceptionName): * bindings/scripts/test/JS/JSTestObj.cpp: (WebCore::jsTestObjConstructorTestSubObj): (WebCore::jsTestObjTestSubObjEnabledBySettingConstructor): (WebCore::jsTestObjConditionalAttr4Constructor): (WebCore::jsTestObjConditionalAttr5Constructor): (WebCore::jsTestObjConditionalAttr6Constructor): (WebCore::jsTestObjContentDocument): (WebCore::setJSTestObjTestSubObjEnabledBySettingConstructor): (WebCore::setJSTestObjConditionalAttr4Constructor): (WebCore::setJSTestObjConditionalAttr5Constructor): (WebCore::setJSTestObjConditionalAttr6Constructor): (WebCore::setJSTestObjConstructor): Deleted. (WebCore::setJSTestObjConstructorStaticStringAttr): Deleted. (WebCore::setJSTestObjConditionalAttr3): Deleted. * bindings/scripts/test/JS/JSTestTypedefs.cpp: (WebCore::jsTestTypedefsConstructorTestSubObj): LayoutTests: Add layout test coverage for calling Object.getOwnPropertyDescriptor() on instance properties (e.g. Unforgeable properties and Window properties). * http/tests/security/cross-origin-window-property-access-expected.txt: * http/tests/security/cross-origin-window-property-access.html: - Fix bug causing the onload function to not find the crossOriginWindow variable. - Update the case for accessing crossOriginWindow.location property as this is actually expected to work as per the specification: https://html.spec.whatwg.org/multipage/browsers.html#security-window * js/dom/dom-as-prototype-assignment-exception-expected.txt: * js/dom/getOwnPropertyDescriptor-expected.txt: * js/dom/script-tests/dom-as-prototype-assignment-exception.js: * js/getOwnPropertyDescriptor-unforgeable-attributes-expected.txt: Added. * js/getOwnPropertyDescriptor-unforgeable-attributes.html: Added. * js/getOwnPropertyDescriptor-window-attributes-expected.txt: Added. * js/getOwnPropertyDescriptor-window-attributes.html: Added. * js/instance-property-getter-other-instance-expected.txt: Added. * js/instance-property-getter-other-instance.html: Added. * js/resources/getOwnPropertyDescriptor.js: Canonical link: https://commits.webkit.org/171987@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@196145 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2016-02-04 21:36:04 +00:00
<!DOCTYPE html>
<script src="../resources/js-test-pre.js"></script>
<script>
description("Tests that Object.getOwnPropertyDescriptor() works correctly for [Unforgeable] IDL attributes.");
function checkUnforgeablePropertyDescriptor(descriptor, readOnly)
{
shouldBeType("descriptor.get", "Function");
if (readOnly)
shouldBeUndefined("descriptor.set");
else
shouldBeType("descriptor.set", "Function");
shouldBeTrue("descriptor.enumerable");
shouldBeFalse("descriptor.configurable");
invalidObject = { };
shouldThrow("descriptor.get.call(invalidObject)");
}
debug("* Document.location");
descriptor = Object.getOwnPropertyDescriptor(document, "location");
checkUnforgeablePropertyDescriptor(descriptor);
shouldBe("descriptor.get.call(document)", "document.location");
var locationProperties = Object.getOwnPropertyNames(document.location);
for (var i = 0; i < locationProperties.length; i++) {
var propertyName = locationProperties[i];
descriptor = Object.getOwnPropertyDescriptor(document.location, propertyName);
if (descriptor.value)
continue;
debug("");
debug("* Location." + propertyName);
var isReadOnly = propertyName == "origin" || propertyName == "ancestorOrigins";
checkUnforgeablePropertyDescriptor(descriptor, isReadOnly);
if (propertyName != "ancestorOrigins")
shouldBeTrue("descriptor.get.call(document.location) === document.location." + propertyName);
}
debug("");
debug("* Window.location");
descriptor = Object.getOwnPropertyDescriptor(window, "location");
checkUnforgeablePropertyDescriptor(descriptor);
shouldBeTrue("descriptor.get.call(window) === window.location");
debug("");
debug("* Window.window");
descriptor = Object.getOwnPropertyDescriptor(window, "window");
checkUnforgeablePropertyDescriptor(descriptor, true);
shouldBeTrue("descriptor.get.call(window) === window.window");
debug("");
debug("* Window.top");
descriptor = Object.getOwnPropertyDescriptor(window, "top");
checkUnforgeablePropertyDescriptor(descriptor, true);
shouldBeTrue("descriptor.get.call(window) === window.top");
debug("");
debug("* Window.document");
descriptor = Object.getOwnPropertyDescriptor(window, "document");
checkUnforgeablePropertyDescriptor(descriptor, true);
</script>
<script src="../resources/js-test-post.js"></script>