XPCWrapper.cpp (2584B)
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/. */ 6 7 #include "xpcprivate.h" 8 #include "XPCWrapper.h" 9 #include "WrapperFactory.h" 10 #include "AccessCheck.h" 11 12 #include "js/PropertyAndElement.h" // JS_DefineFunction 13 14 using namespace xpc; 15 using namespace mozilla; 16 using namespace JS; 17 18 namespace XPCNativeWrapper { 19 20 static inline bool ThrowException(nsresult ex, JSContext* cx) { 21 XPCThrower::Throw(ex, cx); 22 23 return false; 24 } 25 26 static bool UnwrapNW(JSContext* cx, unsigned argc, Value* vp) { 27 JS::CallArgs args = JS::CallArgsFromVp(argc, vp); 28 if (args.length() != 1) { 29 return ThrowException(NS_ERROR_XPC_NOT_ENOUGH_ARGS, cx); 30 } 31 32 JS::RootedValue v(cx, args[0]); 33 if (!v.isObject() || !js::IsCrossCompartmentWrapper(&v.toObject()) || 34 !WrapperFactory::AllowWaiver(&v.toObject())) { 35 args.rval().set(v); 36 return true; 37 } 38 39 bool ok = xpc::WrapperFactory::WaiveXrayAndWrap(cx, &v); 40 NS_ENSURE_TRUE(ok, false); 41 args.rval().set(v); 42 return true; 43 } 44 45 static bool XrayWrapperConstructor(JSContext* cx, unsigned argc, Value* vp) { 46 JS::CallArgs args = CallArgsFromVp(argc, vp); 47 if (args.length() == 0) { 48 return ThrowException(NS_ERROR_XPC_NOT_ENOUGH_ARGS, cx); 49 } 50 51 if (!args[0].isObject()) { 52 if (args.isConstructing()) { 53 return ThrowException(NS_ERROR_XPC_BAD_CONVERT_JS, cx); 54 } 55 56 args.rval().set(args[0]); 57 return true; 58 } 59 60 args.rval().setObject(*js::UncheckedUnwrap(&args[0].toObject())); 61 return JS_WrapValue(cx, args.rval()); 62 } 63 // static 64 bool AttachNewConstructorObject(JSContext* aCx, 65 JS::HandleObject aGlobalObject) { 66 JSAutoRealm ar(aCx, aGlobalObject); 67 JSFunction* xpcnativewrapper = JS_DefineFunction( 68 aCx, aGlobalObject, "XPCNativeWrapper", XrayWrapperConstructor, 1, 69 JSPROP_READONLY | JSPROP_PERMANENT | JSFUN_CONSTRUCTOR); 70 if (!xpcnativewrapper) { 71 return false; 72 } 73 JS::RootedObject obj(aCx, JS_GetFunctionObject(xpcnativewrapper)); 74 return JS_DefineFunction(aCx, obj, "unwrap", UnwrapNW, 1, 75 JSPROP_READONLY | JSPROP_PERMANENT) != nullptr; 76 } 77 78 } // namespace XPCNativeWrapper 79 80 namespace XPCWrapper { 81 82 JSObject* UnsafeUnwrapSecurityWrapper(JSObject* obj) { 83 if (js::IsProxy(obj)) { 84 return js::UncheckedUnwrap(obj); 85 } 86 87 return obj; 88 } 89 90 } // namespace XPCWrapper