Bug 1906744 - Check if constructor is enabled before installing named property. r=mccr8,dom-storage-reviewers,janv,asuth,eemeli

Differential Revision: https://phabricator.services.mozilla.com/D216671
This commit is contained in:
Peter Van der Beken 2024-08-08 16:35:19 +00:00
parent 360950121a
commit 834db6cfe8
15 changed files with 225 additions and 248 deletions

View File

@ -548,14 +548,33 @@ class SystemCallerGuarantee {
operator CallerType() const { return CallerType::System; }
};
enum class DefineInterfaceProperty {
No,
CheckExposure,
Always,
};
class ProtoAndIfaceCache;
typedef void (*CreateInterfaceObjectsMethod)(JSContext* aCx,
JS::Handle<JSObject*> aGlobal,
ProtoAndIfaceCache& aCache,
bool aDefineOnGlobal);
using CreateInterfaceObjectsMethod =
void (*)(JSContext*, JS::Handle<JSObject*>, ProtoAndIfaceCache&,
DefineInterfaceProperty aDefineOnGlobal);
// GetPerInterfaceObjectHandle has 3 possible behaviours for defining the named
// properties on the global for an interface or namespace when it creates an
// interface or namespace object. aDefineOnGlobal can be used to pick the
// behaviour. GetPerInterfaceObjectHandle either:
//
// * does not define any properties on the global object
// (for DefineInterfaceProperty::No),
// * checks whether the interface is exposed in the global object before
// defining properties (for DefineInterfaceProperty::CheckExposure),
// * always defines properties (for DefineInterfaceProperty::Always).
//
// Callers should be careful when passing DefineInterfaceProperty::Always and
// make sure to check exposure themselves if needed.
JS::Handle<JSObject*> GetPerInterfaceObjectHandle(
JSContext* aCx, size_t aSlotId, CreateInterfaceObjectsMethod aCreator,
bool aDefineOnGlobal);
DefineInterfaceProperty aDefineOnGlobal);
namespace binding_detail {

View File

@ -3665,8 +3665,8 @@ bool GetDesiredProto(JSContext* aCx, const JS::CallArgs& aCallArgs,
// JS::GetRealmGlobalOrNull should not be returning null here, because we
// have live objects in the Realm.
JSAutoRealm ar(aCx, JS::GetRealmGlobalOrNull(realm));
aDesiredProto.set(
GetPerInterfaceObjectHandle(aCx, aProtoId, aCreator, true));
aDesiredProto.set(GetPerInterfaceObjectHandle(
aCx, aProtoId, aCreator, DefineInterfaceProperty::CheckExposure));
if (!aDesiredProto) {
return false;
}
@ -3797,8 +3797,8 @@ bool HTMLConstructor(JSContext* aCx, unsigned aArgc, JS::Value* aVp,
// makes sense to start with: https://github.com/whatwg/html/issues/3575
{
JSAutoRealm ar(aCx, newTarget);
JS::Handle<JSObject*> constructor =
GetPerInterfaceObjectHandle(aCx, aConstructorId, aCreator, true);
JS::Handle<JSObject*> constructor = GetPerInterfaceObjectHandle(
aCx, aConstructorId, aCreator, DefineInterfaceProperty::CheckExposure);
if (!constructor) {
return false;
}
@ -4202,7 +4202,7 @@ JSObject* UnprivilegedJunkScopeOrWorkerGlobal(const fallible_t&) {
JS::Handle<JSObject*> GetPerInterfaceObjectHandle(
JSContext* aCx, size_t aSlotId, CreateInterfaceObjectsMethod aCreator,
bool aDefineOnGlobal) {
DefineInterfaceProperty aDefineOnGlobal) {
/* Make sure our global is sane. Hopefully we can remove this sometime */
JSObject* global = JS::CurrentGlobalOrNull(aCx);
if (!(JS::GetClass(global)->flags & JSCLASS_DOM_GLOBAL)) {

View File

@ -3369,6 +3369,14 @@ class StringIdChars {
already_AddRefed<Promise> CreateRejectedPromiseFromThrownException(
JSContext* aCx, ErrorResult& aError);
template <auto ConstructorEnabled>
inline bool ShouldExpose(JSContext* aCx, JS::Handle<JSObject*> aGlobal,
DefineInterfaceProperty aDefine) {
return aDefine == DefineInterfaceProperty::Always ||
(aDefine == DefineInterfaceProperty::CheckExposure &&
ConstructorEnabled(aCx, aGlobal));
}
} // namespace binding_detail
} // namespace dom

View File

@ -3494,7 +3494,7 @@ class CGCreateInterfaceObjectsMethod(CGAbstractMethod):
Argument("JSContext*", "aCx"),
Argument("JS::Handle<JSObject*>", "aGlobal"),
Argument("ProtoAndIfaceCache&", "aProtoAndIfaceCache"),
Argument("bool", "aDefineOnGlobal"),
Argument("DefineInterfaceProperty", "aDefineOnGlobal"),
]
CGAbstractMethod.__init__(
self, descriptor, "CreateInterfaceObjects", "void", args, static=static
@ -3505,6 +3505,19 @@ class CGCreateInterfaceObjectsMethod(CGAbstractMethod):
def definition_body(self):
needInterfaceObject = self.descriptor.interface.hasInterfaceObject()
if needInterfaceObject and self.descriptor.isExposedConditionally():
# This code might be called when we're trying to create an object
# in a non-system compartment, for example when system code is
# calling a constructor through Xrays. In that case we do want to
# create an interface object in the non-system compartment, but we
# don't want to expose the name on the non-system global if the
# interface itself is marked as ChromeOnly.
defineOnGlobal = (
"ShouldExpose<%s::ConstructorEnabled>(aCx, aGlobal, aDefineOnGlobal)"
% toBindingNamespace(self.descriptor.name)
)
else:
defineOnGlobal = "aDefineOnGlobal != DefineInterfaceProperty::No"
if needInterfaceObject:
(protoGetter, protoHandleGetter) = InterfaceObjectProtoGetter(
self.descriptor
@ -3572,13 +3585,15 @@ class CGCreateInterfaceObjectsMethod(CGAbstractMethod):
interfaceCache,
${properties},
${chromeProperties},
"${name}", aDefineOnGlobal);
"${name}",
${defineOnGlobal});
""",
interfaceCache=interfaceCache,
constructorProto=constructorProto,
properties=properties,
chromeProperties=chromeProperties,
name=name,
defineOnGlobal=defineOnGlobal,
)
return CGList(
[
@ -3659,7 +3674,8 @@ class CGCreateInterfaceObjectsMethod(CGAbstractMethod):
interfaceCache,
${properties},
${chromeProperties},
"${name}", aDefineOnGlobal,
"${name}",
${defineOnGlobal},
${unscopableNames},
${isGlobal},
${legacyWindowAliases});
@ -3674,6 +3690,7 @@ class CGCreateInterfaceObjectsMethod(CGAbstractMethod):
properties=properties,
chromeProperties=chromeProperties,
name=name,
defineOnGlobal=defineOnGlobal,
unscopableNames="unscopableNames" if self.haveUnscopables else "nullptr",
isGlobal=toStringBool(isGlobal),
legacyWindowAliases="legacyWindowAliases"
@ -3913,6 +3930,40 @@ class CGCreateInterfaceObjectsMethod(CGAbstractMethod):
).define()
class CGCreateAndDefineOnGlobalMethod(CGAbstractMethod):
"""
A method for creating the interface or namespace object and defining
properties for it on the global.
"""
def __init__(self, descriptor):
CGAbstractMethod.__init__(
self,
descriptor,
"CreateAndDefineOnGlobal",
"bool",
[
Argument("JSContext*", "aCx"),
],
inline=True,
)
def definition_body(self):
return fill(
"""
// Get the interface or namespace object for this class. This will
// create the object as needed and always define the properties for
// it on the global. The caller should make sure the interface or
// namespace is exposed on the global before calling this.
return GetPerInterfaceObjectHandle(aCx, constructors::id::${name},
&CreateInterfaceObjects,
DefineInterfaceProperty::Always);
""",
name=self.descriptor.name,
)
class CGGetProtoObjectHandleMethod(CGAbstractMethod):
"""
A method for getting the interface prototype object.
@ -3937,7 +3988,7 @@ class CGGetProtoObjectHandleMethod(CGAbstractMethod):
object as needed. */
return GetPerInterfaceObjectHandle(aCx, prototypes::id::${name},
&CreateInterfaceObjects,
/* aDefineOnGlobal = */ true);
DefineInterfaceProperty::CheckExposure);
""",
name=self.descriptor.name,
@ -3975,7 +4026,6 @@ class CGGetConstructorObjectHandleMethod(CGAbstractMethod):
"JS::Handle<JSObject*>",
[
Argument("JSContext*", "aCx"),
Argument("bool", "aDefineOnGlobal", "true"),
],
inline=True,
)
@ -3988,7 +4038,7 @@ class CGGetConstructorObjectHandleMethod(CGAbstractMethod):
return GetPerInterfaceObjectHandle(aCx, constructors::id::${name},
&CreateInterfaceObjects,
aDefineOnGlobal);
DefineInterfaceProperty::CheckExposure);
""",
name=self.descriptor.name,
)
@ -17172,6 +17222,11 @@ class CGDescriptor(CGThing):
if descriptor.interface.hasInterfaceObject():
cgThings.append(CGGetConstructorObjectHandleMethod(descriptor))
cgThings.append(CGGetConstructorObjectMethod(descriptor))
cgThings.append(
CGCreateAndDefineOnGlobalMethod(
descriptor,
)
)
# See whether we need to generate cross-origin property arrays.
if needCrossOriginPropertyArrays:
@ -18355,6 +18410,21 @@ class CGDictionary(CGThing):
return all(CGDictionary.typeSafeToJSONify(m.type) for m in dictionary.members)
def RegisterNonWindowBindings(descriptors):
conditions = []
for desc in descriptors:
bindingNS = toBindingNamespace(desc.name)
condition = "!%s::CreateAndDefineOnGlobal(aCx)" % bindingNS
if desc.isExposedConditionally():
condition = "%s::ConstructorEnabled(aCx, aObj) && " % bindingNS + condition
conditions.append(condition)
lines = [
CGIfWrapper(CGGeneric("return false;\n"), condition) for condition in conditions
]
lines.append(CGGeneric("return true;\n"))
return CGList(lines, "\n").define()
class CGRegisterWorkerBindings(CGAbstractMethod):
def __init__(self, config):
CGAbstractMethod.__init__(
@ -18367,24 +18437,11 @@ class CGRegisterWorkerBindings(CGAbstractMethod):
self.config = config
def definition_body(self):
descriptors = self.config.getDescriptors(
hasInterfaceObject=True, isExposedInAnyWorker=True, register=True
return RegisterNonWindowBindings(
self.config.getDescriptors(
hasInterfaceObject=True, isExposedInAnyWorker=True, register=True
)
)
conditions = []
for desc in descriptors:
bindingNS = toBindingNamespace(desc.name)
condition = "!%s::GetConstructorObject(aCx)" % bindingNS
if desc.isExposedConditionally():
condition = (
"%s::ConstructorEnabled(aCx, aObj) && " % bindingNS + condition
)
conditions.append(condition)
lines = [
CGIfWrapper(CGGeneric("return false;\n"), condition)
for condition in conditions
]
lines.append(CGGeneric("return true;\n"))
return CGList(lines, "\n").define()
class CGRegisterWorkerDebuggerBindings(CGAbstractMethod):
@ -18399,24 +18456,11 @@ class CGRegisterWorkerDebuggerBindings(CGAbstractMethod):
self.config = config
def definition_body(self):
descriptors = self.config.getDescriptors(
hasInterfaceObject=True, isExposedInWorkerDebugger=True, register=True
return RegisterNonWindowBindings(
self.config.getDescriptors(
hasInterfaceObject=True, isExposedInWorkerDebugger=True, register=True
)
)
conditions = []
for desc in descriptors:
bindingNS = toBindingNamespace(desc.name)
condition = "!%s::GetConstructorObject(aCx)" % bindingNS
if desc.isExposedConditionally():
condition = (
"%s::ConstructorEnabled(aCx, aObj) && " % bindingNS + condition
)
conditions.append(condition)
lines = [
CGIfWrapper(CGGeneric("return false;\n"), condition)
for condition in conditions
]
lines.append(CGGeneric("return true;\n"))
return CGList(lines, "\n").define()
class CGRegisterWorkletBindings(CGAbstractMethod):
@ -18431,24 +18475,11 @@ class CGRegisterWorkletBindings(CGAbstractMethod):
self.config = config
def definition_body(self):
descriptors = self.config.getDescriptors(
hasInterfaceObject=True, isExposedInAnyWorklet=True, register=True
return RegisterNonWindowBindings(
self.config.getDescriptors(
hasInterfaceObject=True, isExposedInAnyWorklet=True, register=True
)
)
conditions = []
for desc in descriptors:
bindingNS = toBindingNamespace(desc.name)
condition = "!%s::GetConstructorObject(aCx)" % bindingNS
if desc.isExposedConditionally():
condition = (
"%s::ConstructorEnabled(aCx, aObj) && " % bindingNS + condition
)
conditions.append(condition)
lines = [
CGIfWrapper(CGGeneric("return false;\n"), condition)
for condition in conditions
]
lines.append(CGGeneric("return true;\n"))
return CGList(lines, "\n").define()
class CGRegisterShadowRealmBindings(CGAbstractMethod):
@ -18463,24 +18494,11 @@ class CGRegisterShadowRealmBindings(CGAbstractMethod):
self.config = config
def definition_body(self):
descriptors = self.config.getDescriptors(
hasInterfaceObject=True, isExposedInShadowRealms=True, register=True
return RegisterNonWindowBindings(
self.config.getDescriptors(
hasInterfaceObject=True, isExposedInShadowRealms=True, register=True
)
)
conditions = []
for desc in descriptors:
bindingNS = toBindingNamespace(desc.name)
condition = "!%s::GetConstructorObject(aCx)" % bindingNS
if desc.isExposedConditionally():
condition = (
"%s::ConstructorEnabled(aCx, aObj) && " % bindingNS + condition
)
conditions.append(condition)
lines = [
CGIfWrapper(CGGeneric("return false;\n"), condition)
for condition in conditions
]
lines.append(CGGeneric("return true;\n"))
return CGList(lines, "\n").define()
def BindingNamesOffsetEnum(name):

View File

@ -33,7 +33,7 @@ static JSObject* FindNamedConstructorForXray(
JSContext* aCx, JS::Handle<jsid> aId, const WebIDLNameTableEntry* aEntry) {
JSObject* interfaceObject =
GetPerInterfaceObjectHandle(aCx, aEntry->mConstructorId, aEntry->mCreate,
/* aDefineOnGlobal = */ false);
DefineInterfaceProperty::No);
if (!interfaceObject) {
return nullptr;
}
@ -161,10 +161,13 @@ bool WebIDLGlobalNameHash::DefineIfEnabled(
return true;
}
// We've already checked whether the interface is enabled (see
// checkEnabledForScope above), so it's fine to pass
// DefineInterfaceProperty::Always here.
JS::Rooted<JSObject*> interfaceObject(
aCx,
GetPerInterfaceObjectHandle(aCx, entry->mConstructorId, entry->mCreate,
/* aDefineOnGlobal = */ true));
DefineInterfaceProperty::Always));
if (NS_WARN_IF(!interfaceObject)) {
return Throw(aCx, NS_ERROR_FAILURE);
}
@ -235,9 +238,12 @@ bool WebIDLGlobalNameHash::ResolveForSystemGlobal(JSContext* aCx,
// Look up the corresponding entry in the name table, and resolve if enabled.
const WebIDLNameTableEntry* entry = GetEntry(aId.toLinearString());
if (entry && (!entry->mEnabled || entry->mEnabled(aCx, aObj))) {
// We've already checked whether the interface is enabled (see
// entry->mEnabled above), so it's fine to pass
// DefineInterfaceProperty::Always here.
if (NS_WARN_IF(!GetPerInterfaceObjectHandle(
aCx, entry->mConstructorId, entry->mCreate,
/* aDefineOnGlobal = */ true))) {
DefineInterfaceProperty::Always))) {
return Throw(aCx, NS_ERROR_FAILURE);
}

View File

@ -226,14 +226,15 @@ already_AddRefed<CacheStorage> CacheStorage::CreateOnWorker(
}
// static
bool CacheStorage::DefineCaches(JSContext* aCx, JS::Handle<JSObject*> aGlobal) {
bool CacheStorage::DefineCachesForSandbox(JSContext* aCx,
JS::Handle<JSObject*> aGlobal) {
MOZ_ASSERT(NS_IsMainThread());
MOZ_DIAGNOSTIC_ASSERT(JS::GetClass(aGlobal)->flags & JSCLASS_DOM_GLOBAL,
"Passed object is not a global object!");
js::AssertSameCompartment(aCx, aGlobal);
if (NS_WARN_IF(!CacheStorage_Binding::GetConstructorObject(aCx) ||
!Cache_Binding::GetConstructorObject(aCx))) {
if (NS_WARN_IF(!CacheStorage_Binding::CreateAndDefineOnGlobal(aCx) ||
!Cache_Binding::CreateAndDefineOnGlobal(aCx))) {
return false;
}

View File

@ -52,7 +52,8 @@ class CacheStorage final : public nsISupports,
Namespace aNamespace, nsIGlobalObject* aGlobal,
WorkerPrivate* aWorkerPrivate, ErrorResult& aRv);
static bool DefineCaches(JSContext* aCx, JS::Handle<JSObject*> aGlobal);
static bool DefineCachesForSandbox(JSContext* aCx,
JS::Handle<JSObject*> aGlobal);
// webidl interface methods
already_AddRefed<Promise> Match(JSContext* aCx,

View File

@ -390,17 +390,17 @@ bool IndexedDatabaseManager::ResolveSandboxBinding(JSContext* aCx) {
return false;
}
if (!IDBCursor_Binding::GetConstructorObject(aCx) ||
!IDBCursorWithValue_Binding::GetConstructorObject(aCx) ||
!IDBDatabase_Binding::GetConstructorObject(aCx) ||
!IDBFactory_Binding::GetConstructorObject(aCx) ||
!IDBIndex_Binding::GetConstructorObject(aCx) ||
!IDBKeyRange_Binding::GetConstructorObject(aCx) ||
!IDBObjectStore_Binding::GetConstructorObject(aCx) ||
!IDBOpenDBRequest_Binding::GetConstructorObject(aCx) ||
!IDBRequest_Binding::GetConstructorObject(aCx) ||
!IDBTransaction_Binding::GetConstructorObject(aCx) ||
!IDBVersionChangeEvent_Binding::GetConstructorObject(aCx)) {
if (!IDBCursor_Binding::CreateAndDefineOnGlobal(aCx) ||
!IDBCursorWithValue_Binding::CreateAndDefineOnGlobal(aCx) ||
!IDBDatabase_Binding::CreateAndDefineOnGlobal(aCx) ||
!IDBFactory_Binding::CreateAndDefineOnGlobal(aCx) ||
!IDBIndex_Binding::CreateAndDefineOnGlobal(aCx) ||
!IDBKeyRange_Binding::CreateAndDefineOnGlobal(aCx) ||
!IDBObjectStore_Binding::CreateAndDefineOnGlobal(aCx) ||
!IDBOpenDBRequest_Binding::CreateAndDefineOnGlobal(aCx) ||
!IDBRequest_Binding::CreateAndDefineOnGlobal(aCx) ||
!IDBTransaction_Binding::CreateAndDefineOnGlobal(aCx) ||
!IDBVersionChangeEvent_Binding::CreateAndDefineOnGlobal(aCx)) {
return false;
}

View File

@ -24,7 +24,7 @@
*
*/
[Func="IsChromeOrUAWidget", Exposed=Window]
[Func="mozilla::intl::Localization::IsAPIEnabled", Exposed=Window]
interface DOMLocalization : Localization {
/**
* Constructor arguments:

View File

@ -59,7 +59,7 @@ dictionary L10nMessage {
* - formatMessages - format multiple compound messages
*
*/
[Func="IsChromeOrUAWidget", Exposed=Window]
[Func="mozilla::intl::Localization::IsAPIEnabled", Exposed=Window]
interface Localization {
/**
* Constructor arguments:

View File

@ -37,11 +37,8 @@ bool WorkerPrivate::RegisterDebuggerBindings(JSContext* aCx,
return false;
}
if (!ChromeUtils_Binding::GetConstructorObject(aCx)) {
return false;
}
if (!DebuggerNotificationObserver_Binding::GetConstructorObject(aCx)) {
if (!ChromeUtils_Binding::CreateAndDefineOnGlobal(aCx) ||
!DebuggerNotificationObserver_Binding::CreateAndDefineOnGlobal(aCx)) {
return false;
}

View File

@ -77,7 +77,7 @@ nsresult CentralizedAdminPrefManagerInit(bool aSandboxEnabled) {
}
// Define ChromeUtils for ChromeUtils.import.
if (!mozilla::dom::ChromeUtils_Binding::GetConstructorObject(cx)) {
if (!mozilla::dom::ChromeUtils_Binding::CreateAndDefineOnGlobal(cx)) {
return NS_ERROR_FAILURE;
}

View File

@ -6,9 +6,11 @@
#include "Localization.h"
#include "nsIObserverService.h"
#include "xpcpublic.h"
#include "mozilla/BasePrincipal.h"
#include "mozilla/Preferences.h"
#include "mozilla/Services.h"
#include "mozilla/dom/Document.h"
#include "mozilla/dom/PromiseNativeHandler.h"
#define INTL_APP_LOCALES_CHANGED "intl:app-locales-changed"
@ -148,6 +150,13 @@ Localization::Localization(nsIGlobalObject* aGlobal, bool aIsSync,
RegisterObservers();
}
/* static */
bool Localization::IsAPIEnabled(JSContext* aCx, JSObject* aObject) {
JS::Rooted<JSObject*> obj(aCx, aObject);
return Document::DocumentSupportsL10n(aCx, obj) ||
IsChromeOrUAWidget(aCx, obj);
}
already_AddRefed<Localization> Localization::Constructor(
const GlobalObject& aGlobal,
const Sequence<OwningUTF8StringOrResourceId>& aResourceIds, bool aIsSync,

View File

@ -84,6 +84,8 @@ class Localization : public nsIObserver,
nsIObserver)
NS_DECL_NSIOBSERVER
static bool IsAPIEnabled(JSContext* aCx, JSObject* aObject);
static already_AddRefed<Localization> Constructor(
const dom::GlobalObject& aGlobal,
const dom::Sequence<dom::OwningUTF8StringOrResourceId>& aResourceIds,

View File

@ -83,6 +83,7 @@
#include "mozilla/dom/ScriptSettings.h"
#include "mozilla/dom/SelectionBinding.h"
#include "mozilla/dom/StorageManager.h"
#include "mozilla/dom/StorageManagerBinding.h"
#include "mozilla/dom/TextDecoderBinding.h"
#include "mozilla/dom/TextEncoderBinding.h"
#include "mozilla/dom/URLBinding.h"
@ -352,9 +353,9 @@ bool xpc::SandboxCreateFetch(JSContext* cx, JS::Handle<JSObject*> obj) {
MOZ_ASSERT(JS_IsGlobalObject(obj));
return JS_DefineFunction(cx, obj, "fetch", SandboxFetchPromise, 2, 0) &&
dom::Request_Binding::GetConstructorObject(cx) &&
dom::Response_Binding::GetConstructorObject(cx) &&
dom::Headers_Binding::GetConstructorObject(cx);
Request_Binding::CreateAndDefineOnGlobal(cx) &&
Response_Binding::CreateAndDefineOnGlobal(cx) &&
Headers_Binding::CreateAndDefineOnGlobal(cx);
}
static bool SandboxCreateStorage(JSContext* cx, JS::HandleObject obj) {
@ -363,6 +364,10 @@ static bool SandboxCreateStorage(JSContext* cx, JS::HandleObject obj) {
nsIGlobalObject* native = xpc::NativeGlobal(obj);
MOZ_ASSERT(native);
if (!StorageManager_Binding::CreateAndDefineOnGlobal(cx)) {
return false;
}
dom::StorageManager* storageManager = new dom::StorageManager(native);
JS::RootedObject wrapped(cx, storageManager->WrapObject(cx, nullptr));
return JS_DefineProperty(cx, obj, "storage", wrapped, JSPROP_ENUMERATE);
@ -1027,151 +1032,62 @@ bool xpc::GlobalProperties::Define(JSContext* cx, JS::HandleObject obj) {
// This function holds common properties not exposed automatically but able
// to be requested either in |Cu.importGlobalProperties| or
// |wantGlobalProperties| of a sandbox.
if (AbortController &&
!dom::AbortController_Binding::GetConstructorObject(cx)) {
return false;
#define DEFINE_WEBIDL_INTERFACE_OR_NAMESPACE(_iface) \
if ((_iface) && !dom::_iface##_Binding::CreateAndDefineOnGlobal(cx)) { \
return false; \
}
if (Blob && !dom::Blob_Binding::GetConstructorObject(cx)) return false;
if (ChromeUtils && !dom::ChromeUtils_Binding::GetConstructorObject(cx)) {
DEFINE_WEBIDL_INTERFACE_OR_NAMESPACE(AbortController)
DEFINE_WEBIDL_INTERFACE_OR_NAMESPACE(ChromeUtils)
DEFINE_WEBIDL_INTERFACE_OR_NAMESPACE(Blob)
DEFINE_WEBIDL_INTERFACE_OR_NAMESPACE(CSS)
DEFINE_WEBIDL_INTERFACE_OR_NAMESPACE(CSSRule)
DEFINE_WEBIDL_INTERFACE_OR_NAMESPACE(CustomStateSet)
DEFINE_WEBIDL_INTERFACE_OR_NAMESPACE(Directory)
DEFINE_WEBIDL_INTERFACE_OR_NAMESPACE(Document)
DEFINE_WEBIDL_INTERFACE_OR_NAMESPACE(DOMException)
DEFINE_WEBIDL_INTERFACE_OR_NAMESPACE(DOMParser)
DEFINE_WEBIDL_INTERFACE_OR_NAMESPACE(DOMTokenList)
DEFINE_WEBIDL_INTERFACE_OR_NAMESPACE(Element)
DEFINE_WEBIDL_INTERFACE_OR_NAMESPACE(Event)
DEFINE_WEBIDL_INTERFACE_OR_NAMESPACE(File)
DEFINE_WEBIDL_INTERFACE_OR_NAMESPACE(FileReader)
DEFINE_WEBIDL_INTERFACE_OR_NAMESPACE(FormData)
DEFINE_WEBIDL_INTERFACE_OR_NAMESPACE(Headers)
DEFINE_WEBIDL_INTERFACE_OR_NAMESPACE(IOUtils)
DEFINE_WEBIDL_INTERFACE_OR_NAMESPACE(InspectorCSSParser)
DEFINE_WEBIDL_INTERFACE_OR_NAMESPACE(InspectorUtils)
DEFINE_WEBIDL_INTERFACE_OR_NAMESPACE(MessageChannel)
if (MessageChannel && !MessagePort_Binding::CreateAndDefineOnGlobal(cx)) {
return false;
}
DEFINE_WEBIDL_INTERFACE_OR_NAMESPACE(MIDIInputMap)
DEFINE_WEBIDL_INTERFACE_OR_NAMESPACE(MIDIOutputMap)
DEFINE_WEBIDL_INTERFACE_OR_NAMESPACE(Node)
DEFINE_WEBIDL_INTERFACE_OR_NAMESPACE(NodeFilter)
DEFINE_WEBIDL_INTERFACE_OR_NAMESPACE(PathUtils)
DEFINE_WEBIDL_INTERFACE_OR_NAMESPACE(Performance)
DEFINE_WEBIDL_INTERFACE_OR_NAMESPACE(PromiseDebugging)
DEFINE_WEBIDL_INTERFACE_OR_NAMESPACE(Range)
DEFINE_WEBIDL_INTERFACE_OR_NAMESPACE(ReadableStream)
DEFINE_WEBIDL_INTERFACE_OR_NAMESPACE(Selection)
DEFINE_WEBIDL_INTERFACE_OR_NAMESPACE(TextDecoder)
DEFINE_WEBIDL_INTERFACE_OR_NAMESPACE(TextEncoder)
DEFINE_WEBIDL_INTERFACE_OR_NAMESPACE(URL)
DEFINE_WEBIDL_INTERFACE_OR_NAMESPACE(URLSearchParams)
DEFINE_WEBIDL_INTERFACE_OR_NAMESPACE(WebSocket)
DEFINE_WEBIDL_INTERFACE_OR_NAMESPACE(Window)
DEFINE_WEBIDL_INTERFACE_OR_NAMESPACE(XMLHttpRequest)
DEFINE_WEBIDL_INTERFACE_OR_NAMESPACE(XMLSerializer)
if (CSS && !dom::CSS_Binding::GetConstructorObject(cx)) {
return false;
}
if (CSSRule && !dom::CSSRule_Binding::GetConstructorObject(cx)) {
return false;
}
if (CustomStateSet &&
!dom::CustomStateSet_Binding::GetConstructorObject(cx)) {
return false;
}
if (Directory && !dom::Directory_Binding::GetConstructorObject(cx))
return false;
if (Document && !dom::Document_Binding::GetConstructorObject(cx)) {
return false;
}
if (DOMException && !dom::DOMException_Binding::GetConstructorObject(cx)) {
return false;
}
if (DOMParser && !dom::DOMParser_Binding::GetConstructorObject(cx)) {
return false;
}
if (DOMTokenList && !dom::DOMTokenList_Binding::GetConstructorObject(cx)) {
return false;
}
if (Element && !dom::Element_Binding::GetConstructorObject(cx)) return false;
if (Event && !dom::Event_Binding::GetConstructorObject(cx)) return false;
if (File && !dom::File_Binding::GetConstructorObject(cx)) return false;
if (FileReader && !dom::FileReader_Binding::GetConstructorObject(cx)) {
return false;
}
if (FormData && !dom::FormData_Binding::GetConstructorObject(cx))
return false;
if (Headers && !dom::Headers_Binding::GetConstructorObject(cx)) {
return false;
}
if (IOUtils && !dom::IOUtils_Binding::GetConstructorObject(cx)) {
return false;
}
if (InspectorCSSParser &&
!dom::InspectorCSSParser_Binding::GetConstructorObject(cx)) {
return false;
}
if (InspectorUtils && !dom::InspectorUtils_Binding::GetConstructorObject(cx))
return false;
if (MessageChannel &&
(!dom::MessageChannel_Binding::GetConstructorObject(cx) ||
!dom::MessagePort_Binding::GetConstructorObject(cx)))
return false;
if (MIDIInputMap && !dom::MIDIInputMap_Binding::GetConstructorObject(cx)) {
return false;
}
if (MIDIOutputMap && !dom::MIDIOutputMap_Binding::GetConstructorObject(cx)) {
return false;
}
if (Node && !dom::Node_Binding::GetConstructorObject(cx)) {
return false;
}
if (NodeFilter && !dom::NodeFilter_Binding::GetConstructorObject(cx)) {
return false;
}
if (PathUtils && !dom::PathUtils_Binding::GetConstructorObject(cx)) {
return false;
}
if (Performance && !dom::Performance_Binding::GetConstructorObject(cx)) {
return false;
}
if (PromiseDebugging &&
!dom::PromiseDebugging_Binding::GetConstructorObject(cx)) {
return false;
}
if (Range && !dom::Range_Binding::GetConstructorObject(cx)) {
return false;
}
if (Selection && !dom::Selection_Binding::GetConstructorObject(cx)) {
return false;
}
if (TextDecoder && !dom::TextDecoder_Binding::GetConstructorObject(cx))
return false;
if (TextEncoder && !dom::TextEncoder_Binding::GetConstructorObject(cx))
return false;
if (URL && !dom::URL_Binding::GetConstructorObject(cx)) return false;
if (URLSearchParams &&
!dom::URLSearchParams_Binding::GetConstructorObject(cx))
return false;
if (XMLHttpRequest && !dom::XMLHttpRequest_Binding::GetConstructorObject(cx))
return false;
if (WebSocket && !dom::WebSocket_Binding::GetConstructorObject(cx))
return false;
if (Window && !dom::Window_Binding::GetConstructorObject(cx)) return false;
if (XMLSerializer && !dom::XMLSerializer_Binding::GetConstructorObject(cx))
return false;
if (ReadableStream && !dom::ReadableStream_Binding::GetConstructorObject(cx))
return false;
#undef DEFINE_WEBIDL_INTERFACE_OR_NAMESPACE
if (atob && !JS_DefineFunction(cx, obj, "atob", Atob, 1, 0)) return false;
if (btoa && !JS_DefineFunction(cx, obj, "btoa", Btoa, 1, 0)) return false;
if (caches && !dom::cache::CacheStorage::DefineCaches(cx, obj)) {
if (caches && !dom::cache::CacheStorage::DefineCachesForSandbox(cx, obj)) {
return false;
}