зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
fe0de4c0ef
Коммит
931e7dd36c
|
@ -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 {
|
||||
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
*
|
||||
*/
|
||||
|
||||
[Func="IsChromeOrUAWidget", Exposed=Window]
|
||||
[Func="mozilla::intl::Localization::IsAPIEnabled", Exposed=Window]
|
||||
interface DOMLocalization : Localization {
|
||||
/**
|
||||
* Constructor arguments:
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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,12 @@ Localization::Localization(nsIGlobalObject* aGlobal, bool aIsSync,
|
|||
RegisterObservers();
|
||||
}
|
||||
|
||||
/* static */
|
||||
bool Localization::IsAPIEnabled(JSContext* aCx, JSObject* aObject) {
|
||||
return Document::DocumentSupportsL10n(aCx, aObject) ||
|
||||
IsChromeOrUAWidget(aCx, aObject);
|
||||
}
|
||||
|
||||
already_AddRefed<Localization> Localization::Constructor(
|
||||
const GlobalObject& aGlobal,
|
||||
const Sequence<OwningUTF8StringOrResourceId>& aResourceIds, bool aIsSync,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче