From 6bf0a5cb5034a7e684dcc3500e841785237ce2dd Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 19:32:43 +0200 Subject: Adding upstream version 1:115.7.0. Signed-off-by: Daniel Baumann --- dom/bindings/RemoteObjectProxy.h | 204 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 204 insertions(+) create mode 100644 dom/bindings/RemoteObjectProxy.h (limited to 'dom/bindings/RemoteObjectProxy.h') diff --git a/dom/bindings/RemoteObjectProxy.h b/dom/bindings/RemoteObjectProxy.h new file mode 100644 index 0000000000..8a8ef7270c --- /dev/null +++ b/dom/bindings/RemoteObjectProxy.h @@ -0,0 +1,204 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef mozilla_dom_RemoteObjectProxy_h +#define mozilla_dom_RemoteObjectProxy_h + +#include "js/Proxy.h" +#include "mozilla/Maybe.h" +#include "mozilla/dom/MaybeCrossOriginObject.h" +#include "mozilla/dom/PrototypeList.h" +#include "xpcpublic.h" + +namespace mozilla::dom { + +class BrowsingContext; + +/** + * Base class for RemoteObjectProxy. Implements the pieces of the handler that + * don't depend on properties/methods of the specific WebIDL interface that this + * proxy implements. + */ +class RemoteObjectProxyBase : public js::BaseProxyHandler, + public MaybeCrossOriginObjectMixins { + protected: + explicit constexpr RemoteObjectProxyBase(prototypes::ID aPrototypeID) + : BaseProxyHandler(&sCrossOriginProxyFamily, false), + mPrototypeID(aPrototypeID) {} + + public: + bool finalizeInBackground(const JS::Value& priv) const final { return false; } + + // Standard internal methods + bool getOwnPropertyDescriptor( + JSContext* aCx, JS::Handle aProxy, JS::Handle aId, + JS::MutableHandle> aDesc) const override; + bool ownPropertyKeys(JSContext* aCx, JS::Handle aProxy, + JS::MutableHandleVector aProps) const override; + bool defineProperty(JSContext* aCx, JS::Handle aProxy, + JS::Handle aId, + JS::Handle aDesc, + JS::ObjectOpResult& result) const final; + bool delete_(JSContext* aCx, JS::Handle aProxy, + JS::Handle aId, JS::ObjectOpResult& aResult) const final; + + bool getPrototypeIfOrdinary(JSContext* aCx, JS::Handle aProxy, + bool* aIsOrdinary, + JS::MutableHandle aProtop) const final; + + bool preventExtensions(JSContext* aCx, JS::Handle aProxy, + JS::ObjectOpResult& aResult) const final; + bool isExtensible(JSContext* aCx, JS::Handle aProxy, + bool* aExtensible) const final; + + bool get(JSContext* cx, JS::Handle aProxy, + JS::Handle aReceiver, JS::Handle aId, + JS::MutableHandle aVp) const final; + bool set(JSContext* cx, JS::Handle aProxy, JS::Handle aId, + JS::Handle aValue, JS::Handle aReceiver, + JS::ObjectOpResult& aResult) const final; + + // SpiderMonkey extensions + bool getOwnEnumerablePropertyKeys( + JSContext* aCx, JS::Handle aProxy, + JS::MutableHandleVector aProps) const override; + const char* className(JSContext* aCx, + JS::Handle aProxy) const final; + + // Cross origin objects like RemoteWindowProxy should not participate in + // private fields. + virtual bool throwOnPrivateField() const override { return true; } + + bool isCallable(JSObject* aObj) const final { return false; } + bool isConstructor(JSObject* aObj) const final { return false; } + + virtual void NoteChildren(JSObject* aProxy, + nsCycleCollectionTraversalCallback& aCb) const = 0; + + static void* GetNative(JSObject* aProxy) { + return js::GetProxyPrivate(aProxy).toPrivate(); + } + + /** + * Returns true if aProxy is a cross-process proxy that represents + * an object implementing the WebIDL interface for aProtoID. aProxy + * should be a proxy object. + */ + static inline bool IsRemoteObjectProxy(JSObject* aProxy, + prototypes::ID aProtoID) { + const js::BaseProxyHandler* handler = js::GetProxyHandler(aProxy); + return handler->family() == &sCrossOriginProxyFamily && + static_cast(handler)->mPrototypeID == + aProtoID; + } + + /** + * Returns true if aProxy is a cross-process proxy, no matter which + * interface it represents. aProxy should be a proxy object. + */ + static inline bool IsRemoteObjectProxy(JSObject* aProxy) { + const js::BaseProxyHandler* handler = js::GetProxyHandler(aProxy); + return handler->family() == &sCrossOriginProxyFamily; + } + + protected: + /** + * Gets an existing cached proxy object, or creates a new one and caches it. + * aProxy will be null on failure. aNewObjectCreated is set to true if a new + * object was created, callers probably need to addref the native in that + * case. aNewObjectCreated can be true even if aProxy is null, if something + * failed after creating the object. + */ + void GetOrCreateProxyObject(JSContext* aCx, void* aNative, + const JSClass* aClasp, + JS::Handle aTransplantTo, + JS::MutableHandle aProxy, + bool& aNewObjectCreated) const; + + const prototypes::ID mPrototypeID; + + friend struct SetDOMProxyInformation; + static const char sCrossOriginProxyFamily; +}; + +/** + * Proxy handler for proxy objects that represent an object implementing a + * WebIDL interface that has cross-origin accessible properties/methods, and + * which lives in a different process. The WebIDL code generator will create + * arrays of cross-origin accessible properties/methods that can be used as + * arguments to this template. + * + * The properties and methods can be cached on a holder JSObject, stored in a + * reserved slot on the proxy object. + * + * The proxy objects that use a handler derived from this one are stored in a + * hash map in the JS compartment's private (@see + * xpc::CompartmentPrivate::GetRemoteProxyMap). + */ +template +class RemoteObjectProxy : public RemoteObjectProxyBase { + public: + void finalize(JS::GCContext* aGcx, JSObject* aProxy) const final { + auto native = static_cast(GetNative(aProxy)); + RefPtr self(dont_AddRef(native)); + } + + void GetProxyObject(JSContext* aCx, Native* aNative, + JS::Handle aTransplantTo, + JS::MutableHandle aProxy) const { + bool objectCreated = false; + GetOrCreateProxyObject(aCx, aNative, &sClass, aTransplantTo, aProxy, + objectCreated); + if (objectCreated) { + NS_ADDREF(aNative); + } + } + + protected: + using RemoteObjectProxyBase::RemoteObjectProxyBase; + + private: + bool EnsureHolder(JSContext* aCx, JS::Handle aProxy, + JS::MutableHandle aHolder) const final { + return MaybeCrossOriginObjectMixins::EnsureHolder( + aCx, aProxy, /* slot = */ 0, P, aHolder); + } + + static const JSClass sClass; +}; + +/** + * Returns true if aObj is a cross-process proxy object that + * represents an object implementing the WebIDL interface for + * aProtoID. + */ +inline bool IsRemoteObjectProxy(JSObject* aObj, prototypes::ID aProtoID) { + if (!js::IsProxy(aObj)) { + return false; + } + return RemoteObjectProxyBase::IsRemoteObjectProxy(aObj, aProtoID); +} + +/** + * Returns true if aObj is a cross-process proxy object, no matter + * which WebIDL interface it corresponds to. + */ +inline bool IsRemoteObjectProxy(JSObject* aObj) { + if (!js::IsProxy(aObj)) { + return false; + } + return RemoteObjectProxyBase::IsRemoteObjectProxy(aObj); +} + +/** + * Return the browsing context for this remote outer window proxy. + * Only call this function on remote outer window proxies. + */ +BrowsingContext* GetBrowsingContext(JSObject* aProxy); + +} // namespace mozilla::dom + +#endif /* mozilla_dom_RemoteObjectProxy_h */ -- cgit v1.2.3