summaryrefslogtreecommitdiffstats
path: root/js/xpconnect/src/XPCWrapper.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--js/xpconnect/src/XPCWrapper.cpp90
1 files changed, 90 insertions, 0 deletions
diff --git a/js/xpconnect/src/XPCWrapper.cpp b/js/xpconnect/src/XPCWrapper.cpp
new file mode 100644
index 0000000000..7a4f689471
--- /dev/null
+++ b/js/xpconnect/src/XPCWrapper.cpp
@@ -0,0 +1,90 @@
+/* -*- 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/. */
+
+#include "xpcprivate.h"
+#include "XPCWrapper.h"
+#include "WrapperFactory.h"
+#include "AccessCheck.h"
+
+#include "js/PropertyAndElement.h" // JS_DefineFunction
+
+using namespace xpc;
+using namespace mozilla;
+using namespace JS;
+
+namespace XPCNativeWrapper {
+
+static inline bool ThrowException(nsresult ex, JSContext* cx) {
+ XPCThrower::Throw(ex, cx);
+
+ return false;
+}
+
+static bool UnwrapNW(JSContext* cx, unsigned argc, Value* vp) {
+ JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
+ if (args.length() != 1) {
+ return ThrowException(NS_ERROR_XPC_NOT_ENOUGH_ARGS, cx);
+ }
+
+ JS::RootedValue v(cx, args[0]);
+ if (!v.isObject() || !js::IsCrossCompartmentWrapper(&v.toObject()) ||
+ !WrapperFactory::AllowWaiver(&v.toObject())) {
+ args.rval().set(v);
+ return true;
+ }
+
+ bool ok = xpc::WrapperFactory::WaiveXrayAndWrap(cx, &v);
+ NS_ENSURE_TRUE(ok, false);
+ args.rval().set(v);
+ return true;
+}
+
+static bool XrayWrapperConstructor(JSContext* cx, unsigned argc, Value* vp) {
+ JS::CallArgs args = CallArgsFromVp(argc, vp);
+ if (args.length() == 0) {
+ return ThrowException(NS_ERROR_XPC_NOT_ENOUGH_ARGS, cx);
+ }
+
+ if (!args[0].isObject()) {
+ if (args.isConstructing()) {
+ return ThrowException(NS_ERROR_XPC_BAD_CONVERT_JS, cx);
+ }
+
+ args.rval().set(args[0]);
+ return true;
+ }
+
+ args.rval().setObject(*js::UncheckedUnwrap(&args[0].toObject()));
+ return JS_WrapValue(cx, args.rval());
+}
+// static
+bool AttachNewConstructorObject(JSContext* aCx,
+ JS::HandleObject aGlobalObject) {
+ JSAutoRealm ar(aCx, aGlobalObject);
+ JSFunction* xpcnativewrapper = JS_DefineFunction(
+ aCx, aGlobalObject, "XPCNativeWrapper", XrayWrapperConstructor, 1,
+ JSPROP_READONLY | JSPROP_PERMANENT | JSFUN_CONSTRUCTOR);
+ if (!xpcnativewrapper) {
+ return false;
+ }
+ JS::RootedObject obj(aCx, JS_GetFunctionObject(xpcnativewrapper));
+ return JS_DefineFunction(aCx, obj, "unwrap", UnwrapNW, 1,
+ JSPROP_READONLY | JSPROP_PERMANENT) != nullptr;
+}
+
+} // namespace XPCNativeWrapper
+
+namespace XPCWrapper {
+
+JSObject* UnsafeUnwrapSecurityWrapper(JSObject* obj) {
+ if (js::IsProxy(obj)) {
+ return js::UncheckedUnwrap(obj);
+ }
+
+ return obj;
+}
+
+} // namespace XPCWrapper