1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 * vim: set ts=8 sts=4 et sw=4 tw=99:
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/. */
10 #include "mozilla/Attributes.h"
16 class DummyFrameGuard
;
19 * Helper for Wrapper::New default options.
21 * Callers of Wrapper::New() who wish to specify a prototype for the created
22 * Wrapper, *MUST* construct a WrapperOptions with a JSContext.
24 class MOZ_STACK_CLASS WrapperOptions
: public ProxyOptions
{
26 WrapperOptions() : ProxyOptions(false),
30 explicit WrapperOptions(JSContext
* cx
) : ProxyOptions(false),
36 inline JSObject
* proto() const;
37 WrapperOptions
& setProto(JSObject
* protoArg
) {
44 mozilla::Maybe
<JS::RootedObject
> proto_
;
48 * A wrapper is a proxy with a target object to which it generally forwards
49 * operations, but may restrict access to certain operations or instrument the
50 * methods in various ways. A wrapper is distinct from a Direct Proxy Handler
51 * in the sense that it can be "unwrapped" in C++, exposing the underlying
52 * object (Direct Proxy Handlers have an underlying target object, but don't
53 * expect to expose this object via any kind of unwrapping operation). Callers
54 * should be careful to avoid unwrapping security wrappers in the wrong
57 class JS_FRIEND_API(Wrapper
) : public DirectProxyHandler
62 using BaseProxyHandler::Action
;
65 CROSS_COMPARTMENT
= 1 << 0,
66 LAST_USED_FLAG
= CROSS_COMPARTMENT
69 virtual bool defaultValue(JSContext
* cx
, HandleObject obj
, JSType hint
,
70 MutableHandleValue vp
) const MOZ_OVERRIDE
;
72 static JSObject
* New(JSContext
* cx
, JSObject
* obj
, JSObject
* parent
, const Wrapper
* handler
,
73 const WrapperOptions
& options
= WrapperOptions());
75 static JSObject
* Renew(JSContext
* cx
, JSObject
* existing
, JSObject
* obj
, const Wrapper
* handler
);
77 static const Wrapper
* wrapperHandler(JSObject
* wrapper
);
79 static JSObject
* wrappedObject(JSObject
* wrapper
);
81 unsigned flags() const {
85 explicit MOZ_CONSTEXPR
Wrapper(unsigned aFlags
, bool aHasPrototype
= false,
86 bool aHasSecurityPolicy
= false)
87 : DirectProxyHandler(&family
, aHasPrototype
, aHasSecurityPolicy
),
91 virtual bool finalizeInBackground(Value priv
) const MOZ_OVERRIDE
;
92 virtual bool isConstructor(JSObject
* obj
) const MOZ_OVERRIDE
;
94 static const char family
;
95 static const Wrapper singleton
;
96 static const Wrapper singletonWithPrototype
;
98 static JSObject
* defaultProto
;
102 WrapperOptions::proto() const
104 return proto_
? *proto_
: Wrapper::defaultProto
;
107 /* Base class for all cross compartment wrapper handlers. */
108 class JS_FRIEND_API(CrossCompartmentWrapper
) : public Wrapper
111 explicit MOZ_CONSTEXPR
CrossCompartmentWrapper(unsigned aFlags
, bool aHasPrototype
= false,
112 bool aHasSecurityPolicy
= false)
113 : Wrapper(CROSS_COMPARTMENT
| aFlags
, aHasPrototype
, aHasSecurityPolicy
)
116 /* Standard internal methods. */
117 virtual bool getOwnPropertyDescriptor(JSContext
* cx
, HandleObject wrapper
, HandleId id
,
118 MutableHandle
<JSPropertyDescriptor
> desc
) const MOZ_OVERRIDE
;
119 virtual bool defineProperty(JSContext
* cx
, HandleObject wrapper
, HandleId id
,
120 MutableHandle
<JSPropertyDescriptor
> desc
) const MOZ_OVERRIDE
;
121 virtual bool ownPropertyKeys(JSContext
* cx
, HandleObject wrapper
,
122 AutoIdVector
& props
) const MOZ_OVERRIDE
;
123 virtual bool delete_(JSContext
* cx
, HandleObject wrapper
, HandleId id
, bool* bp
) const MOZ_OVERRIDE
;
124 virtual bool enumerate(JSContext
* cx
, HandleObject wrapper
, MutableHandleObject objp
) const MOZ_OVERRIDE
;
125 virtual bool getPrototypeOf(JSContext
* cx
, HandleObject proxy
,
126 MutableHandleObject protop
) const MOZ_OVERRIDE
;
127 virtual bool setPrototypeOf(JSContext
* cx
, HandleObject proxy
, HandleObject proto
,
128 bool* bp
) const MOZ_OVERRIDE
;
130 virtual bool setImmutablePrototype(JSContext
* cx
, HandleObject proxy
,
131 bool* succeeded
) const MOZ_OVERRIDE
;
132 virtual bool preventExtensions(JSContext
* cx
, HandleObject wrapper
, bool* succeeded
) const MOZ_OVERRIDE
;
133 virtual bool isExtensible(JSContext
* cx
, HandleObject wrapper
, bool* extensible
) const MOZ_OVERRIDE
;
134 virtual bool has(JSContext
* cx
, HandleObject wrapper
, HandleId id
, bool* bp
) const MOZ_OVERRIDE
;
135 virtual bool get(JSContext
* cx
, HandleObject wrapper
, HandleObject receiver
,
136 HandleId id
, MutableHandleValue vp
) const MOZ_OVERRIDE
;
137 virtual bool set(JSContext
* cx
, HandleObject wrapper
, HandleObject receiver
,
138 HandleId id
, bool strict
, MutableHandleValue vp
) const MOZ_OVERRIDE
;
139 virtual bool call(JSContext
* cx
, HandleObject wrapper
, const CallArgs
& args
) const MOZ_OVERRIDE
;
140 virtual bool construct(JSContext
* cx
, HandleObject wrapper
, const CallArgs
& args
) const MOZ_OVERRIDE
;
142 /* SpiderMonkey extensions. */
143 virtual bool getPropertyDescriptor(JSContext
* cx
, HandleObject wrapper
, HandleId id
,
144 MutableHandle
<JSPropertyDescriptor
> desc
) const MOZ_OVERRIDE
;
145 virtual bool hasOwn(JSContext
* cx
, HandleObject wrapper
, HandleId id
, bool* bp
) const MOZ_OVERRIDE
;
146 virtual bool getOwnEnumerablePropertyKeys(JSContext
* cx
, HandleObject wrapper
,
147 AutoIdVector
& props
) const MOZ_OVERRIDE
;
148 virtual bool nativeCall(JSContext
* cx
, IsAcceptableThis test
, NativeImpl impl
,
149 CallArgs args
) const MOZ_OVERRIDE
;
150 virtual bool hasInstance(JSContext
* cx
, HandleObject wrapper
, MutableHandleValue v
,
151 bool* bp
) const MOZ_OVERRIDE
;
152 virtual const char* className(JSContext
* cx
, HandleObject proxy
) const MOZ_OVERRIDE
;
153 virtual JSString
* fun_toString(JSContext
* cx
, HandleObject wrapper
,
154 unsigned indent
) const MOZ_OVERRIDE
;
155 virtual bool regexp_toShared(JSContext
* cx
, HandleObject proxy
, RegExpGuard
* g
) const MOZ_OVERRIDE
;
156 virtual bool boxedValue_unbox(JSContext
* cx
, HandleObject proxy
, MutableHandleValue vp
) const MOZ_OVERRIDE
;
157 virtual bool defaultValue(JSContext
* cx
, HandleObject wrapper
, JSType hint
,
158 MutableHandleValue vp
) const MOZ_OVERRIDE
;
160 static const CrossCompartmentWrapper singleton
;
161 static const CrossCompartmentWrapper singletonWithPrototype
;
165 * Base class for security wrappers. A security wrapper is potentially hiding
166 * all or part of some wrapped object thus SecurityWrapper defaults to denying
167 * access to the wrappee. This is the opposite of Wrapper which tries to be
168 * completely transparent.
170 * NB: Currently, only a few ProxyHandler operations are overridden to deny
171 * access, relying on derived SecurityWrapper to block access when necessary.
173 template <class Base
>
174 class JS_FRIEND_API(SecurityWrapper
) : public Base
177 explicit MOZ_CONSTEXPR
SecurityWrapper(unsigned flags
, bool hasPrototype
= false)
178 : Base(flags
, hasPrototype
, /* hasSecurityPolicy = */ true)
181 virtual bool enter(JSContext
* cx
, HandleObject wrapper
, HandleId id
, Wrapper::Action act
,
182 bool* bp
) const MOZ_OVERRIDE
;
184 virtual bool defineProperty(JSContext
* cx
, HandleObject wrapper
, HandleId id
,
185 MutableHandle
<JSPropertyDescriptor
> desc
) const MOZ_OVERRIDE
;
186 virtual bool isExtensible(JSContext
* cx
, HandleObject wrapper
, bool* extensible
) const MOZ_OVERRIDE
;
187 virtual bool preventExtensions(JSContext
* cx
, HandleObject wrapper
, bool* succeeded
) const MOZ_OVERRIDE
;
188 virtual bool setPrototypeOf(JSContext
* cx
, HandleObject proxy
, HandleObject proto
,
189 bool* bp
) const MOZ_OVERRIDE
;
190 virtual bool setImmutablePrototype(JSContext
* cx
, HandleObject proxy
, bool* succeeded
) const MOZ_OVERRIDE
;
192 virtual bool nativeCall(JSContext
* cx
, IsAcceptableThis test
, NativeImpl impl
,
193 CallArgs args
) const MOZ_OVERRIDE
;
194 virtual bool objectClassIs(HandleObject obj
, ESClassValue classValue
,
195 JSContext
* cx
) const MOZ_OVERRIDE
;
196 virtual bool regexp_toShared(JSContext
* cx
, HandleObject proxy
, RegExpGuard
* g
) const MOZ_OVERRIDE
;
197 virtual bool boxedValue_unbox(JSContext
* cx
, HandleObject proxy
, MutableHandleValue vp
) const MOZ_OVERRIDE
;
198 virtual bool defaultValue(JSContext
* cx
, HandleObject wrapper
, JSType hint
,
199 MutableHandleValue vp
) const MOZ_OVERRIDE
;
201 // Allow isCallable and isConstructor. They used to be class-level, and so could not be guarded
204 virtual bool watch(JSContext
* cx
, JS::HandleObject proxy
, JS::HandleId id
,
205 JS::HandleObject callable
) const MOZ_OVERRIDE
;
206 virtual bool unwatch(JSContext
* cx
, JS::HandleObject proxy
, JS::HandleId id
) const MOZ_OVERRIDE
;
209 * Allow our subclasses to select the superclass behavior they want without
210 * needing to specify an exact superclass.
212 typedef Base Permissive
;
213 typedef SecurityWrapper
<Base
> Restrictive
;
216 typedef SecurityWrapper
<Wrapper
> SameCompartmentSecurityWrapper
;
217 typedef SecurityWrapper
<CrossCompartmentWrapper
> CrossCompartmentSecurityWrapper
;
220 TransparentObjectWrapper(JSContext
* cx
, HandleObject existing
, HandleObject obj
,
221 HandleObject parent
);
224 IsWrapper(JSObject
* obj
)
226 return IsProxy(obj
) && GetProxyHandler(obj
)->family() == &Wrapper::family
;
229 // Given a JSObject, returns that object stripped of wrappers. If
230 // stopAtOuter is true, then this returns the outer window if it was
231 // previously wrapped. Otherwise, this returns the first object for
232 // which JSObject::isWrapper returns false.
233 JS_FRIEND_API(JSObject
*)
234 UncheckedUnwrap(JSObject
* obj
, bool stopAtOuter
= true, unsigned* flagsp
= nullptr);
236 // Given a JSObject, returns that object stripped of wrappers. At each stage,
237 // the security wrapper has the opportunity to veto the unwrap. Since checked
238 // code should never be unwrapping outer window wrappers, we always stop at
240 JS_FRIEND_API(JSObject
*)
241 CheckedUnwrap(JSObject
* obj
, bool stopAtOuter
= true);
243 // Unwrap only the outermost security wrapper, with the same semantics as
244 // above. This is the checked version of Wrapper::wrappedObject.
245 JS_FRIEND_API(JSObject
*)
246 UnwrapOneChecked(JSObject
* obj
, bool stopAtOuter
= true);
249 IsCrossCompartmentWrapper(JSObject
* obj
);
252 NukeCrossCompartmentWrapper(JSContext
* cx
, JSObject
* wrapper
);
255 RemapWrapper(JSContext
* cx
, JSObject
* wobj
, JSObject
* newTarget
);
258 RemapAllWrappersForObject(JSContext
* cx
, JSObject
* oldTarget
,
259 JSObject
* newTarget
);
261 // API to recompute all cross-compartment wrappers whose source and target
262 // match the given filters.
264 RecomputeWrappers(JSContext
* cx
, const CompartmentFilter
& sourceFilter
,
265 const CompartmentFilter
& targetFilter
);
269 #endif /* jswrapper_h */