From 7c20ef784dc65f437f526845ab23cc8c7735599a Mon Sep 17 00:00:00 2001 From: Peter Van der Beken Date: Mon, 9 Jan 2023 22:19:53 +0000 Subject: [PATCH] Bug 1806994 - Define @@toStringTag on Xrays for namespace objects. r=smaug Differential Revision: https://phabricator.services.mozilla.com/D165459 --- dom/bindings/BindingUtils.cpp | 16 ++++++++++++++-- dom/bindings/Codegen.py | 7 +++++-- dom/bindings/DOMJSClass.h | 5 +++-- dom/bindings/test/test_dom_xrays.html | 9 +++++++++ 4 files changed, 31 insertions(+), 6 deletions(-) diff --git a/dom/bindings/BindingUtils.cpp b/dom/bindings/BindingUtils.cpp index 25a7709def061..f76e7f30834bb 100644 --- a/dom/bindings/BindingUtils.cpp +++ b/dom/bindings/BindingUtils.cpp @@ -1632,7 +1632,7 @@ static bool XrayResolveProperty( switch (propertyInfo.type) { case eStaticMethod: case eStaticAttribute: - if (type != eInterface) { + if (type != eInterface && type != eNamespace) { return true; } break; @@ -1814,6 +1814,18 @@ static bool ResolvePrototypeOrConstructor( return true; } } + } else if (type == eNamespace) { + if (id.isWellKnownSymbol(JS::SymbolCode::toStringTag)) { + JS::Rooted nameStr( + cx, JS_AtomizeString(cx, JS::GetClass(obj)->name)); + if (!nameStr) { + return false; + } + + desc.set(Some(JS::PropertyDescriptor::Data( + JS::StringValue(nameStr), {JS::PropertyAttribute::Configurable}))); + return true; + } } else { MOZ_ASSERT(IsInterfacePrototype(type)); @@ -1954,7 +1966,7 @@ bool XrayOwnPropertyKeys(JSContext* cx, JS::Handle wrapper, } } else { MOZ_ASSERT(type != eGlobalInterfacePrototype); - if (type == eInterface) { + if (type == eInterface || type == eNamespace) { ADD_KEYS_IF_DEFINED(StaticMethod); ADD_KEYS_IF_DEFINED(StaticAttribute); } else { diff --git a/dom/bindings/Codegen.py b/dom/bindings/Codegen.py index 71ddaae0c4128..4afddb5346c04 100644 --- a/dom/bindings/Codegen.py +++ b/dom/bindings/Codegen.py @@ -973,7 +973,7 @@ def define(self): if self.descriptor.interface.isNamespace(): classString = self.descriptor.interface.getExtendedAttribute("ClassString") if classString is None: - classString = "Object" + classString = self.descriptor.interface.identifier.name else: classString = classString[0] funToString = "nullptr" @@ -999,7 +999,7 @@ def define(self): JS_NULL_CLASS_EXT, ${objectOps} }, - eInterface, + ${type}, ${needsHasInstance}, ${prototypeID}, ${depth}, @@ -1013,6 +1013,9 @@ def define(self): classOpsPtr=classOpsPtr, hooks=NativePropertyHooks(self.descriptor), objectOps=objectOps, + type="eNamespace" + if self.descriptor.interface.isNamespace() + else "eInterface", needsHasInstance=toStringBool(needsHasInstance), prototypeID=prototypeID, depth=depth, diff --git a/dom/bindings/DOMJSClass.h b/dom/bindings/DOMJSClass.h index 40b1796694a26..dd445792ef591 100644 --- a/dom/bindings/DOMJSClass.h +++ b/dom/bindings/DOMJSClass.h @@ -451,6 +451,7 @@ enum DOMObjectType : uint8_t { eInterface, eInterfacePrototype, eGlobalInterfacePrototype, + eNamespace, eNamedPropertiesObject }; @@ -549,8 +550,8 @@ struct DOMIfaceAndProtoJSClass { // initialization for aggregate/POD types. const JSClass mBase; - // Either eInterface, eInterfacePrototype, eGlobalInterfacePrototype or - // eNamedPropertiesObject. + // Either eInterface, eNamespace, eInterfacePrototype, + // eGlobalInterfacePrototype or eNamedPropertiesObject. DOMObjectType mType; // uint8_t // Boolean indicating whether this object wants a @@hasInstance property diff --git a/dom/bindings/test/test_dom_xrays.html b/dom/bindings/test/test_dom_xrays.html index b2614f03481e6..12d8d230db25d 100644 --- a/dom/bindings/test/test_dom_xrays.html +++ b/dom/bindings/test/test_dom_xrays.html @@ -318,6 +318,15 @@ checkXrayProperty(win.Image, Symbol.hasInstance, [undefined, win.Function.prototype[Symbol.hasInstance]]); + // toString/@@toStringTag + let imageConstructor = win.Image; + is(win.Function.prototype.toString.apply(imageConstructor), + Function.prototype.toString.apply(Image), + "Applying Function.prototype.toString through an Xray should give the same result as applying it directly"); + isDeeply(Object.getOwnPropertyDescriptor(win.CSS, Symbol.toStringTag), + Object.getOwnPropertyDescriptor(CSS, Symbol.toStringTag), + "Getting @@toStringTag on a namespace object through an Xray should give the same result as getting it directly"); + SimpleTest.finish(); }