Bug 1850713: remove duplicated setting of early hint preloader id in `ScriptLoader...
[gecko.git] / dom / base / MaybeCrossOriginObject.h
blob5a75e70dcedf4668163436db7497e81c6bb8b8b2
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef mozilla_dom_MaybeCrossOriginObject_h
8 #define mozilla_dom_MaybeCrossOriginObject_h
10 /**
11 * Shared infrastructure for WindowProxy and Location objects. These
12 * are the objects that can be accessed cross-origin in the HTML
13 * specification.
15 * This class can be inherited from by the relevant proxy handlers to
16 * help implement spec algorithms.
18 * The algorithms this class implements come from
19 * <https://html.spec.whatwg.org/multipage/browsers.html#shared-abstract-operations>,
20 * <https://html.spec.whatwg.org/multipage/window-object.html#the-windowproxy-exotic-object>,
21 * and
22 * <https://html.spec.whatwg.org/multipage/history.html#the-location-interface>.
24 * The class is templated on its base so we can directly implement the things
25 * that should have identical implementations for WindowProxy and Location. The
26 * templating is needed because WindowProxy needs to be a wrapper and Location
27 * shouldn't be one.
30 #include "js/Class.h"
31 #include "js/TypeDecls.h"
32 #include "nsStringFwd.h"
33 #include "mozilla/Maybe.h"
35 namespace mozilla::dom {
37 /**
38 * "mAttributes" and "mMethods" are the cross-origin attributes and methods we
39 * care about, which should get defined on holders.
41 * "mChromeOnlyAttributes" and "mChromeOnlyMethods" are the cross-origin
42 * attributes and methods we care about, which should get defined on holders
43 * for the chrome realm, in addition to the properties that are in
44 * "mAttributes" and "mMethods".
46 struct CrossOriginProperties {
47 const JSPropertySpec* mAttributes;
48 const JSFunctionSpec* mMethods;
49 const JSPropertySpec* mChromeOnlyAttributes;
50 const JSFunctionSpec* mChromeOnlyMethods;
53 // Methods that MaybeCrossOriginObject wants that do not depend on the "Base"
54 // template parameter. We can avoid having multiple instantiations of them by
55 // pulling them out into this helper class.
56 class MaybeCrossOriginObjectMixins {
57 public:
58 /**
59 * Implementation of
60 * <https://html.spec.whatwg.org/multipage/browsers.html#isplatformobjectsameorigin-(-o-)>.
61 * "cx" and "obj" may or may not be same-compartment and even when
62 * same-compartment may not be same-Realm. "obj" can be a WindowProxy, a
63 * Window, or a Location.
65 static bool IsPlatformObjectSameOrigin(JSContext* cx, JSObject* obj);
67 protected:
68 /**
69 * Implementation of
70 * <https://html.spec.whatwg.org/multipage/browsers.html#crossorigingetownpropertyhelper-(-o,-p-)>.
72 * "cx" and "obj" are expected to be different-Realm here, and may be
73 * different-compartment. "obj" can be a "WindowProxy" or a "Location" or a
74 * cross-process proxy for one of those.
76 bool CrossOriginGetOwnPropertyHelper(
77 JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id,
78 JS::MutableHandle<Maybe<JS::PropertyDescriptor>> desc) const;
80 /**
81 * Implementation of
82 * <https://html.spec.whatwg.org/multipage/browsers.html#crossoriginpropertyfallback-(-p-)>.
84 * This should be called at the end of getOwnPropertyDescriptor
85 * methods in the cross-origin case.
87 * "cx" and "obj" are expected to be different-Realm here, and may
88 * be different-compartment. "obj" can be a "WindowProxy" or a
89 * "Location" or a cross-process proxy for one of those.
91 static bool CrossOriginPropertyFallback(
92 JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id,
93 JS::MutableHandle<Maybe<JS::PropertyDescriptor>> desc);
95 /**
96 * Implementation of
97 * <https://html.spec.whatwg.org/multipage/browsers.html#crossoriginget-(-o,-p,-receiver-)>.
99 * "cx" and "obj" are expected to be different-Realm here and may be
100 * different-compartment. "obj" can be a "WindowProxy" or a
101 * "Location" or a cross-process proxy for one of those.
103 * "receiver" will be in the compartment of "cx". The return value will
104 * be in the compartment of "cx".
106 static bool CrossOriginGet(JSContext* cx, JS::Handle<JSObject*> obj,
107 JS::Handle<JS::Value> receiver,
108 JS::Handle<jsid> id,
109 JS::MutableHandle<JS::Value> vp);
112 * Implementation of
113 * <https://html.spec.whatwg.org/multipage/browsers.html#crossoriginset-(-o,-p,-v,-receiver-)>.
115 * "cx" and "obj" are expected to be different-Realm here and may be
116 * different-compartment. "obj" can be a "WindowProxy" or a
117 * "Location" or a cross-process proxy for one of those.
119 * "receiver" and "v" will be in the compartment of "cx".
121 static bool CrossOriginSet(JSContext* cx, JS::Handle<JSObject*> obj,
122 JS::Handle<jsid> id, JS::Handle<JS::Value> v,
123 JS::Handle<JS::Value> receiver,
124 JS::ObjectOpResult& result);
127 * Utility method to ensure a holder for cross-origin properties for the
128 * current global of the JSContext.
130 * When this is called, "cx" and "obj" are _always_ different-Realm, because
131 * this is only used in cross-origin situations. The "holder" return value is
132 * always in the Realm of "cx".
134 * "obj" is the object which has space to store the collection of holders in
135 * the given slot.
137 * "properties" are the cross-origin attributes and methods we care about,
138 * which should get defined on holders.
140 static bool EnsureHolder(JSContext* cx, JS::Handle<JSObject*> obj,
141 size_t slot, const CrossOriginProperties& properties,
142 JS::MutableHandle<JSObject*> holder);
145 * Ensures we have a holder object for the current Realm. When this is
146 * called, "obj" is guaranteed to not be same-Realm with "cx", because this
147 * is only used for cross-origin cases.
149 * Subclasses are expected to implement this by calling our static
150 * EnsureHolder with the appropriate arguments.
152 virtual bool EnsureHolder(JSContext* cx, JS::Handle<JSObject*> proxy,
153 JS::MutableHandle<JSObject*> holder) const = 0;
156 * Report a cross-origin denial for a property named by aId. Always
157 * returns false, so it can be used as "return
158 * ReportCrossOriginDenial(...);".
160 static bool ReportCrossOriginDenial(JSContext* aCx, JS::Handle<jsid> aId,
161 const nsACString& aAccessType);
164 // A proxy handler for objects that may be cross-origin objects. Whether they
165 // actually _are_ cross-origin objects can change dynamically if document.domain
166 // is set.
167 template <typename Base>
168 class MaybeCrossOriginObject : public Base,
169 public MaybeCrossOriginObjectMixins {
170 protected:
171 template <typename... Args>
172 constexpr MaybeCrossOriginObject(Args&&... aArgs)
173 : Base(std::forward<Args>(aArgs)...) {}
176 * Implementation of [[GetPrototypeOf]] as defined in
177 * <https://html.spec.whatwg.org/multipage/window-object.html#windowproxy-getprototypeof>
178 * and
179 * <https://html.spec.whatwg.org/multipage/history.html#location-getprototypeof>.
181 * Our prototype-storage model looks quite different from the spec's, so we
182 * need to implement some hooks that don't directly map to the spec.
184 * "proxy" is the WindowProxy or Location involved. It may or may not be
185 * same-compartment with cx.
187 * "protop" is the prototype value (possibly null). It is guaranteed to be
188 * same-compartment with cx after this function returns successfully.
190 bool getPrototype(JSContext* cx, JS::Handle<JSObject*> proxy,
191 JS::MutableHandle<JSObject*> protop) const final;
194 * Hook for doing the OrdinaryGetPrototypeOf bits that [[GetPrototypeOf]] does
195 * in the spec. Location and WindowProxy store that information somewhat
196 * differently.
198 * The prototype should come from the Realm of "cx".
200 virtual JSObject* getSameOriginPrototype(JSContext* cx) const = 0;
203 * Implementation of [[SetPrototypeOf]] as defined in
204 * <https://html.spec.whatwg.org/multipage/window-object.html#windowproxy-setprototypeof>
205 * and
206 * <https://html.spec.whatwg.org/multipage/history.html#location-setprototypeof>.
208 * "proxy" is the WindowProxy or Location object involved. It may or may not
209 * be same-compartment with "cx".
211 * "proto" is the new prototype object (possibly null). It must be
212 * same-compartment with "cx".
214 bool setPrototype(JSContext* cx, JS::Handle<JSObject*> proxy,
215 JS::Handle<JSObject*> proto,
216 JS::ObjectOpResult& result) const final;
219 * Our non-standard getPrototypeIfOrdinary hook.
221 bool getPrototypeIfOrdinary(JSContext* cx, JS::Handle<JSObject*> proxy,
222 bool* isOrdinary,
223 JS::MutableHandle<JSObject*> protop) const final;
226 * Our non-standard setImmutablePrototype hook.
228 bool setImmutablePrototype(JSContext* cx, JS::Handle<JSObject*> proxy,
229 bool* succeeded) const final;
232 * Implementation of [[IsExtensible]] as defined in
233 * <https://html.spec.whatwg.org/multipage/window-object.html#windowproxy-isextensible>
234 * and
235 * <https://html.spec.whatwg.org/multipage/history.html#location-isextensible>.
237 bool isExtensible(JSContext* cx, JS::Handle<JSObject*> proxy,
238 bool* extensible) const final;
241 * Implementation of [[PreventExtensions]] as defined in
242 * <https://html.spec.whatwg.org/multipage/window-object.html#windowproxy-preventextensions>
243 * and
244 * <https://html.spec.whatwg.org/multipage/history.html#location-preventextensions>.
246 bool preventExtensions(JSContext* cx, JS::Handle<JSObject*> proxy,
247 JS::ObjectOpResult& result) const final;
250 * Implementation of [[GetOwnProperty]] is completely delegated to subclasses.
252 * "proxy" is the WindowProxy or Location object involved. It may or may not
253 * be same-compartment with cx.
255 bool getOwnPropertyDescriptor(
256 JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id,
257 JS::MutableHandle<Maybe<JS::PropertyDescriptor>> desc) const override = 0;
260 * Implementation of [[DefineOwnProperty]] as defined in
261 * <https://html.spec.whatwg.org/multipage/window-object.html#windowproxy-defineownproperty>
262 * and
263 * <https://html.spec.whatwg.org/multipage/history.html#location-defineownproperty>.
264 * "proxy" is the WindowProxy or Location object involved. It may or may not
265 * be same-compartment with cx.
268 bool defineProperty(JSContext* cx, JS::Handle<JSObject*> proxy,
269 JS::Handle<jsid> id,
270 JS::Handle<JS::PropertyDescriptor> desc,
271 JS::ObjectOpResult& result) const final;
274 * Some of our base classes define _another_ virtual defineProperty, and we
275 * get overloaded-virtual warnings as a result due to us hiding it, if we
276 * don't pull it in here.
278 using Base::defineProperty;
281 * Hook for handling the same-origin case in defineProperty.
283 * "proxy" is the WindowProxy or Location object involved. It will be
284 * same-compartment with cx.
286 * "desc" is a the descriptor being defined. It will be same-compartment with
287 * cx.
289 virtual bool definePropertySameOrigin(JSContext* cx,
290 JS::Handle<JSObject*> proxy,
291 JS::Handle<jsid> id,
292 JS::Handle<JS::PropertyDescriptor> desc,
293 JS::ObjectOpResult& result) const = 0;
296 * Implementation of [[Get]] is completely delegated to subclasses.
298 * "proxy" is the WindowProxy or Location object involved. It may or may not
299 * be same-compartment with "cx".
301 * "receiver" is the receiver ("this") for the get. It will be
302 * same-compartment with "cx"
304 * "vp" is the return value. It will be same-compartment with "cx".
306 bool get(JSContext* cx, JS::Handle<JSObject*> proxy,
307 JS::Handle<JS::Value> receiver, JS::Handle<jsid> id,
308 JS::MutableHandle<JS::Value> vp) const override = 0;
311 * Implementation of [[Set]] is completely delegated to subclasses.
313 * "proxy" is the WindowProxy or Location object involved. It may or may not
314 * be same-compartment with "cx".
316 * "v" is the value being set. It will be same-compartment with "cx".
318 * "receiver" is the receiver ("this") for the set. It will be
319 * same-compartment with "cx".
321 bool set(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id,
322 JS::Handle<JS::Value> v, JS::Handle<JS::Value> receiver,
323 JS::ObjectOpResult& result) const override = 0;
326 * Implementation of [[Delete]] is completely delegated to subclasses.
328 * "proxy" is the WindowProxy or Location object involved. It may or may not
329 * be same-compartment with "cx".
331 bool delete_(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id,
332 JS::ObjectOpResult& result) const override = 0;
335 * Spidermonkey-internal hook for enumerating objects.
337 bool enumerate(JSContext* cx, JS::Handle<JSObject*> proxy,
338 JS::MutableHandleVector<jsid> props) const final;
340 // Cross origin objects should not participate in private fields.
341 virtual bool throwOnPrivateField() const override { return true; }
344 * Spidermonkey-internal hook used by Object.prototype.toString. Subclasses
345 * need to implement this, because we don't know what className they want.
346 * Except in the cross-origin case, when we could maybe handle it...
348 const char* className(JSContext* cx,
349 JS::Handle<JSObject*> proxy) const override = 0;
352 } // namespace mozilla::dom
354 #endif /* mozilla_dom_MaybeCrossOriginObject_h */