--- a/js/xpconnect/src/Sandbox.cpp
+++ b/js/xpconnect/src/Sandbox.cpp
@@ -21,17 +21,16 @@
#include "nsJSUtils.h"
#include "nsNetUtil.h"
#include "NullPrincipal.h"
#include "ExpandedPrincipal.h"
#include "WrapperFactory.h"
#include "xpcprivate.h"
#include "xpc_make_class.h"
#include "XPCWrapper.h"
-#include "XrayWrapper.h"
#include "Crypto.h"
#include "mozilla/dom/BindingUtils.h"
#include "mozilla/dom/BlobBinding.h"
#include "mozilla/dom/cache/CacheStorage.h"
#include "mozilla/dom/CSSBinding.h"
#include "mozilla/dom/CSSRuleBinding.h"
#include "mozilla/dom/DirectoryBinding.h"
#include "mozilla/dom/DOMParserBinding.h"
@@ -504,35 +503,91 @@ NS_IMPL_RELEASE(nsXPCComponents_utils_Sa
// We use the nsIXPScriptable macros to generate lots of stuff for us.
#define XPC_MAP_CLASSNAME nsXPCComponents_utils_Sandbox
#define XPC_MAP_QUOTED_CLASSNAME "nsXPCComponents_utils_Sandbox"
#define XPC_MAP_FLAGS (XPC_SCRIPTABLE_WANT_CALL | \
XPC_SCRIPTABLE_WANT_CONSTRUCT)
#include "xpc_map_end.h" /* This #undef's the above. */
-const xpc::SandboxProxyHandler xpc::sandboxProxyHandler;
+class SandboxProxyHandler : public js::Wrapper {
+public:
+ constexpr SandboxProxyHandler() : js::Wrapper(0)
+ {
+ }
+
+ virtual bool getOwnPropertyDescriptor(JSContext* cx, JS::Handle<JSObject*> proxy,
+ JS::Handle<jsid> id,
+ JS::MutableHandle<JS::PropertyDescriptor> desc) const override;
+
+ // We just forward the high-level methods to the BaseProxyHandler versions
+ // which implement them in terms of lower-level methods.
+ virtual bool has(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id,
+ bool* bp) const override;
+ virtual bool get(JSContext* cx, JS::Handle<JSObject*> proxy, JS::HandleValue receiver,
+ JS::Handle<jsid> id, JS::MutableHandle<JS::Value> vp) const override;
+ virtual bool set(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id,
+ JS::Handle<JS::Value> v, JS::Handle<JS::Value> receiver,
+ JS::ObjectOpResult& result) const override;
+
+ virtual bool getPropertyDescriptor(JSContext* cx, JS::Handle<JSObject*> proxy,
+ JS::Handle<jsid> id,
+ JS::MutableHandle<JS::PropertyDescriptor> desc) const override;
+ virtual bool hasOwn(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id,
+ bool* bp) const override;
+ virtual bool getOwnEnumerablePropertyKeys(JSContext* cx, JS::Handle<JSObject*> proxy,
+ JS::AutoIdVector& props) const override;
+ virtual JSObject* enumerate(JSContext* cx, JS::Handle<JSObject*> proxy) const override;
+};
+
+static const SandboxProxyHandler sandboxProxyHandler;
+
+namespace xpc {
bool
-xpc::IsSandboxPrototypeProxy(JSObject* obj)
+IsSandboxPrototypeProxy(JSObject* obj)
{
return js::IsProxy(obj) &&
- js::GetProxyHandler(obj) == &xpc::sandboxProxyHandler;
+ js::GetProxyHandler(obj) == &sandboxProxyHandler;
+}
+
}
+// A proxy handler that lets us wrap callables and invoke them with
+// the correct this object, while forwarding all other operations down
+// to them directly.
+class SandboxCallableProxyHandler : public js::Wrapper {
+public:
+ constexpr SandboxCallableProxyHandler() : js::Wrapper(0)
+ {
+ }
+
+ virtual bool call(JSContext* cx, JS::Handle<JSObject*> proxy,
+ const JS::CallArgs& args) const override;
+
+ static const size_t SandboxProxySlot = 0;
+
+ static inline JSObject* getSandboxProxy(JS::Handle<JSObject*> proxy)
+ {
+ return &js::GetProxyReservedSlot(proxy, SandboxProxySlot).toObject();
+ }
+};
+
+static const SandboxCallableProxyHandler sandboxCallableProxyHandler;
+
bool
-xpc::SandboxCallableProxyHandler::call(JSContext* cx, JS::Handle<JSObject*> proxy,
- const JS::CallArgs& args) const
+SandboxCallableProxyHandler::call(JSContext* cx, JS::Handle<JSObject*> proxy,
+ const JS::CallArgs& args) const
{
// We forward the call to our underlying callable.
// Get our SandboxProxyHandler proxy.
RootedObject sandboxProxy(cx, getSandboxProxy(proxy));
MOZ_ASSERT(js::IsProxy(sandboxProxy) &&
- js::GetProxyHandler(sandboxProxy) == &xpc::sandboxProxyHandler);
+ js::GetProxyHandler(sandboxProxy) == &sandboxProxyHandler);
// The global of the sandboxProxy is the sandbox global, and the
// target object is the original proto.
RootedObject sandboxGlobal(cx,
js::GetGlobalForObjectCrossCompartment(sandboxProxy));
MOZ_ASSERT(IsSandbox(sandboxGlobal));
// If our this object is the sandbox global, we call with this set to the
@@ -577,39 +632,36 @@ xpc::SandboxCallableProxyHandler::call(J
if (thisVal == ObjectValue(*sandboxGlobal)) {
thisVal = ObjectValue(*js::GetProxyTargetObject(sandboxProxy));
}
RootedValue func(cx, js::GetProxyPrivate(proxy));
return JS::Call(cx, thisVal, func, args, args.rval());
}
-const xpc::SandboxCallableProxyHandler xpc::sandboxCallableProxyHandler;
-
/*
* Wrap a callable such that if we're called with oldThisObj as the
* "this" we will instead call it with newThisObj as the this.
*/
static JSObject*
WrapCallable(JSContext* cx, HandleObject callable, HandleObject sandboxProtoProxy)
{
MOZ_ASSERT(JS::IsCallable(callable));
// Our proxy is wrapping the callable. So we need to use the
// callable as the private. We put the given sandboxProtoProxy in
// an extra slot, and our call() hook depends on that.
MOZ_ASSERT(js::IsProxy(sandboxProtoProxy) &&
- js::GetProxyHandler(sandboxProtoProxy) ==
- &xpc::sandboxProxyHandler);
+ js::GetProxyHandler(sandboxProtoProxy) == &sandboxProxyHandler);
RootedValue priv(cx, ObjectValue(*callable));
// We want to claim to have the same proto as our wrapped callable, so set
// ourselves up with a lazy proto.
js::ProxyOptions options;
options.setLazyProto(true);
- JSObject* obj = js::NewProxyObject(cx, &xpc::sandboxCallableProxyHandler,
+ JSObject* obj = js::NewProxyObject(cx, &sandboxCallableProxyHandler,
priv, nullptr, options);
if (obj) {
js::SetProxyReservedSlot(obj, SandboxCallableProxyHandler::SandboxProxySlot,
ObjectValue(*sandboxProtoProxy));
}
return obj;
}
@@ -644,20 +696,20 @@ IsMaybeWrappedDOMConstructor(JSObject* o
if (!obj) {
return false;
}
return dom::IsDOMConstructor(obj);
}
bool
-xpc::SandboxProxyHandler::getPropertyDescriptor(JSContext* cx,
- JS::Handle<JSObject*> proxy,
- JS::Handle<jsid> id,
- JS::MutableHandle<PropertyDescriptor> desc) const
+SandboxProxyHandler::getPropertyDescriptor(JSContext* cx,
+ JS::Handle<JSObject*> proxy,
+ JS::Handle<jsid> id,
+ JS::MutableHandle<PropertyDescriptor> desc) const
{
JS::RootedObject obj(cx, wrappedObject(proxy));
MOZ_ASSERT(js::GetObjectCompartment(obj) == js::GetObjectCompartment(proxy));
if (!JS_GetPropertyDescriptorById(cx, obj, id, desc))
return false;
if (!desc.object())
@@ -683,61 +735,60 @@ xpc::SandboxProxyHandler::getPropertyDes
desc.value().setObject(*val);
}
}
return true;
}
bool
-xpc::SandboxProxyHandler::getOwnPropertyDescriptor(JSContext* cx,
- JS::Handle<JSObject*> proxy,
- JS::Handle<jsid> id,
- JS::MutableHandle<PropertyDescriptor> desc)
- const
+SandboxProxyHandler::getOwnPropertyDescriptor(JSContext* cx,
+ JS::Handle<JSObject*> proxy,
+ JS::Handle<jsid> id,
+ JS::MutableHandle<PropertyDescriptor> desc) const
{
if (!getPropertyDescriptor(cx, proxy, id, desc))
return false;
if (desc.object() != wrappedObject(proxy))
desc.object().set(nullptr);
return true;
}
/*
* Reuse the BaseProxyHandler versions of the derived traps that are implemented
* in terms of the fundamental traps.
*/
bool
-xpc::SandboxProxyHandler::has(JSContext* cx, JS::Handle<JSObject*> proxy,
- JS::Handle<jsid> id, bool* bp) const
+SandboxProxyHandler::has(JSContext* cx, JS::Handle<JSObject*> proxy,
+ JS::Handle<jsid> id, bool* bp) const
{
// This uses getPropertyDescriptor for backward compatibility with
// the old BaseProxyHandler::has implementation.
Rooted<PropertyDescriptor> desc(cx);
if (!getPropertyDescriptor(cx, proxy, id, &desc))
return false;
*bp = !!desc.object();
return true;
}
bool
-xpc::SandboxProxyHandler::hasOwn(JSContext* cx, JS::Handle<JSObject*> proxy,
- JS::Handle<jsid> id, bool* bp) const
+SandboxProxyHandler::hasOwn(JSContext* cx, JS::Handle<JSObject*> proxy,
+ JS::Handle<jsid> id, bool* bp) const
{
return BaseProxyHandler::hasOwn(cx, proxy, id, bp);
}
bool
-xpc::SandboxProxyHandler::get(JSContext* cx, JS::Handle<JSObject*> proxy,
- JS::Handle<JS::Value> receiver,
- JS::Handle<jsid> id,
- JS::MutableHandle<Value> vp) const
+SandboxProxyHandler::get(JSContext* cx, JS::Handle<JSObject*> proxy,
+ JS::Handle<JS::Value> receiver,
+ JS::Handle<jsid> id,
+ JS::MutableHandle<Value> vp) const
{
// This uses getPropertyDescriptor for backward compatibility with
// the old BaseProxyHandler::get implementation.
Rooted<PropertyDescriptor> desc(cx);
if (!getPropertyDescriptor(cx, proxy, id, &desc))
return false;
desc.assertCompleteIfFound();
@@ -759,35 +810,35 @@ xpc::SandboxProxyHandler::get(JSContext*
vp.setUndefined();
return true;
}
return Call(cx, receiver, getter, HandleValueArray::empty(), vp);
}
bool
-xpc::SandboxProxyHandler::set(JSContext* cx, JS::Handle<JSObject*> proxy,
- JS::Handle<jsid> id,
- JS::Handle<Value> v,
- JS::Handle<Value> receiver,
- JS::ObjectOpResult& result) const
+SandboxProxyHandler::set(JSContext* cx, JS::Handle<JSObject*> proxy,
+ JS::Handle<jsid> id,
+ JS::Handle<Value> v,
+ JS::Handle<Value> receiver,
+ JS::ObjectOpResult& result) const
{
return BaseProxyHandler::set(cx, proxy, id, v, receiver, result);
}
bool
-xpc::SandboxProxyHandler::getOwnEnumerablePropertyKeys(JSContext* cx,
- JS::Handle<JSObject*> proxy,
- AutoIdVector& props) const
+SandboxProxyHandler::getOwnEnumerablePropertyKeys(JSContext* cx,
+ JS::Handle<JSObject*> proxy,
+ AutoIdVector& props) const
{
return BaseProxyHandler::getOwnEnumerablePropertyKeys(cx, proxy, props);
}
JSObject*
-xpc::SandboxProxyHandler::enumerate(JSContext* cx, JS::Handle<JSObject*> proxy) const
+SandboxProxyHandler::enumerate(JSContext* cx, JS::Handle<JSObject*> proxy) const
{
return BaseProxyHandler::enumerate(cx, proxy);
}
bool
xpc::GlobalProperties::Parse(JSContext* cx, JS::HandleObject obj)
{
uint32_t length;
@@ -1109,18 +1160,17 @@ xpc::CreateSandboxObject(JSContext* cx,
useSandboxProxy = IS_WN_CLASS(unwrappedClass) ||
mozilla::dom::IsDOMClass(Jsvalify(unwrappedClass));
}
if (useSandboxProxy) {
// Wrap it up in a proxy that will do the right thing in terms
// of this-binding for methods.
RootedValue priv(cx, ObjectValue(*options.proto));
- options.proto = js::NewProxyObject(cx, &xpc::sandboxProxyHandler,
- priv, nullptr);
+ options.proto = js::NewProxyObject(cx, &sandboxProxyHandler, priv, nullptr);
if (!options.proto)
return NS_ERROR_OUT_OF_MEMORY;
}
ok = JS_SplicePrototype(cx, sandbox, options.proto);
if (!ok)
return NS_ERROR_XPC_UNEXPECTED;
}
--- a/js/xpconnect/wrappers/XrayWrapper.h
+++ b/js/xpconnect/wrappers/XrayWrapper.h
@@ -460,70 +460,16 @@ class XrayWrapper : public Base {
#define PermissiveXrayJS xpc::XrayWrapper<js::CrossCompartmentWrapper, xpc::JSXrayTraits>
#define PermissiveXrayOpaque xpc::XrayWrapper<js::CrossCompartmentWrapper, xpc::OpaqueXrayTraits>
extern template class PermissiveXrayDOM;
extern template class SecurityXrayDOM;
extern template class PermissiveXrayJS;
extern template class PermissiveXrayOpaque;
-class SandboxProxyHandler : public js::Wrapper {
-public:
- constexpr SandboxProxyHandler() : js::Wrapper(0)
- {
- }
-
- virtual bool getOwnPropertyDescriptor(JSContext* cx, JS::Handle<JSObject*> proxy,
- JS::Handle<jsid> id,
- JS::MutableHandle<JS::PropertyDescriptor> desc) const override;
-
- // We just forward the high-level methods to the BaseProxyHandler versions
- // which implement them in terms of lower-level methods.
- virtual bool has(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id,
- bool* bp) const override;
- virtual bool get(JSContext* cx, JS::Handle<JSObject*> proxy, JS::HandleValue receiver,
- JS::Handle<jsid> id, JS::MutableHandle<JS::Value> vp) const override;
- virtual bool set(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id,
- JS::Handle<JS::Value> v, JS::Handle<JS::Value> receiver,
- JS::ObjectOpResult& result) const override;
-
- virtual bool getPropertyDescriptor(JSContext* cx, JS::Handle<JSObject*> proxy,
- JS::Handle<jsid> id,
- JS::MutableHandle<JS::PropertyDescriptor> desc) const override;
- virtual bool hasOwn(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id,
- bool* bp) const override;
- virtual bool getOwnEnumerablePropertyKeys(JSContext* cx, JS::Handle<JSObject*> proxy,
- JS::AutoIdVector& props) const override;
- virtual JSObject* enumerate(JSContext* cx, JS::Handle<JSObject*> proxy) const override;
-};
-
-extern const SandboxProxyHandler sandboxProxyHandler;
-
-// A proxy handler that lets us wrap callables and invoke them with
-// the correct this object, while forwarding all other operations down
-// to them directly.
-class SandboxCallableProxyHandler : public js::Wrapper {
-public:
- constexpr SandboxCallableProxyHandler() : js::Wrapper(0)
- {
- }
-
- virtual bool call(JSContext* cx, JS::Handle<JSObject*> proxy,
- const JS::CallArgs& args) const override;
-
- static const size_t SandboxProxySlot = 0;
-
- static inline JSObject* getSandboxProxy(JS::Handle<JSObject*> proxy)
- {
- return &js::GetProxyReservedSlot(proxy, SandboxProxySlot).toObject();
- }
-};
-
-extern const SandboxCallableProxyHandler sandboxCallableProxyHandler;
-
class AutoSetWrapperNotShadowing;
/*
* Slots for Xray expando objects. See comments in XrayWrapper.cpp for details
* of how these get used; we mostly want the value of JSSLOT_EXPANDO_COUNT here.
*/
enum ExpandoSlots {
JSSLOT_EXPANDO_NEXT = 0,