1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/js/xpconnect/wrappers/XrayWrapper.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,221 @@ 1.4 +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 1.5 +/* vim: set ts=8 sts=4 et sw=4 tw=99: */ 1.6 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.8 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.9 + 1.10 +#ifndef XrayWrapper_h 1.11 +#define XrayWrapper_h 1.12 + 1.13 +#include "mozilla/Attributes.h" 1.14 + 1.15 +#include "jswrapper.h" 1.16 + 1.17 +// Xray wrappers re-resolve the original native properties on the native 1.18 +// object and always directly access to those properties. 1.19 +// Because they work so differently from the rest of the wrapper hierarchy, 1.20 +// we pull them out of the Wrapper inheritance hierarchy and create a 1.21 +// little world around them. 1.22 + 1.23 +namespace xpc { 1.24 + 1.25 +bool 1.26 +holder_get(JSContext *cx, JS::HandleObject holder, JS::HandleId id, JS::MutableHandleValue vp); 1.27 +bool 1.28 +holder_set(JSContext *cx, JS::HandleObject holder, JS::HandleId id, bool strict, 1.29 + JS::MutableHandleValue vp); 1.30 + 1.31 +namespace XrayUtils { 1.32 + 1.33 +bool IsXPCWNHolderClass(const JSClass *clasp); 1.34 + 1.35 +bool CloneExpandoChain(JSContext *cx, JSObject *src, JSObject *dst); 1.36 + 1.37 +bool 1.38 +IsTransparent(JSContext *cx, JS::HandleObject wrapper, JS::HandleId id); 1.39 + 1.40 +JSObject * 1.41 +GetNativePropertiesObject(JSContext *cx, JSObject *wrapper); 1.42 + 1.43 +bool 1.44 +IsXrayResolving(JSContext *cx, JS::HandleObject wrapper, JS::HandleId id); 1.45 + 1.46 +bool 1.47 +HasNativeProperty(JSContext *cx, JS::HandleObject wrapper, JS::HandleId id, 1.48 + bool *hasProp); 1.49 +} 1.50 + 1.51 +class XrayTraits; 1.52 +class XPCWrappedNativeXrayTraits; 1.53 +class DOMXrayTraits; 1.54 +class JSXrayTraits; 1.55 + 1.56 + 1.57 +enum XrayType { 1.58 + XrayForDOMObject, 1.59 + XrayForWrappedNative, 1.60 + XrayForJSObject, 1.61 + NotXray 1.62 +}; 1.63 + 1.64 +XrayType GetXrayType(JSObject *obj); 1.65 +XrayTraits* GetXrayTraits(JSObject *obj); 1.66 + 1.67 +// NB: Base *must* derive from JSProxyHandler 1.68 +template <typename Base, typename Traits = XPCWrappedNativeXrayTraits > 1.69 +class XrayWrapper : public Base { 1.70 + public: 1.71 + XrayWrapper(unsigned flags); 1.72 + virtual ~XrayWrapper(); 1.73 + 1.74 + /* Fundamental proxy traps. */ 1.75 + virtual bool isExtensible(JSContext *cx, JS::Handle<JSObject*> wrapper, bool *extensible) MOZ_OVERRIDE; 1.76 + virtual bool preventExtensions(JSContext *cx, JS::Handle<JSObject*> wrapper) MOZ_OVERRIDE; 1.77 + virtual bool getPropertyDescriptor(JSContext *cx, JS::Handle<JSObject*> wrapper, JS::Handle<jsid> id, 1.78 + JS::MutableHandle<JSPropertyDescriptor> desc); 1.79 + virtual bool getOwnPropertyDescriptor(JSContext *cx, JS::Handle<JSObject*> wrapper, JS::Handle<jsid> id, 1.80 + JS::MutableHandle<JSPropertyDescriptor> desc); 1.81 + virtual bool defineProperty(JSContext *cx, JS::Handle<JSObject*> wrapper, JS::Handle<jsid> id, 1.82 + JS::MutableHandle<JSPropertyDescriptor> desc); 1.83 + virtual bool getOwnPropertyNames(JSContext *cx, JS::Handle<JSObject*> wrapper, 1.84 + JS::AutoIdVector &props); 1.85 + virtual bool delete_(JSContext *cx, JS::Handle<JSObject*> wrapper, 1.86 + JS::Handle<jsid> id, bool *bp); 1.87 + virtual bool enumerate(JSContext *cx, JS::Handle<JSObject*> wrapper, JS::AutoIdVector &props); 1.88 + 1.89 + /* Derived proxy traps. */ 1.90 + virtual bool get(JSContext *cx, JS::Handle<JSObject*> wrapper, JS::Handle<JSObject*> receiver, 1.91 + JS::Handle<jsid> id, JS::MutableHandle<JS::Value> vp); 1.92 + virtual bool set(JSContext *cx, JS::Handle<JSObject*> wrapper, JS::Handle<JSObject*> receiver, 1.93 + JS::Handle<jsid> id, bool strict, JS::MutableHandle<JS::Value> vp); 1.94 + virtual bool has(JSContext *cx, JS::Handle<JSObject*> wrapper, JS::Handle<jsid> id, 1.95 + bool *bp); 1.96 + virtual bool hasOwn(JSContext *cx, JS::Handle<JSObject*> wrapper, JS::Handle<jsid> id, 1.97 + bool *bp); 1.98 + virtual bool keys(JSContext *cx, JS::Handle<JSObject*> wrapper, 1.99 + JS::AutoIdVector &props); 1.100 + virtual bool iterate(JSContext *cx, JS::Handle<JSObject*> wrapper, unsigned flags, 1.101 + JS::MutableHandle<JS::Value> vp); 1.102 + 1.103 + virtual bool call(JSContext *cx, JS::Handle<JSObject*> wrapper, 1.104 + const JS::CallArgs &args) MOZ_OVERRIDE; 1.105 + virtual bool construct(JSContext *cx, JS::Handle<JSObject*> wrapper, 1.106 + const JS::CallArgs &args) MOZ_OVERRIDE; 1.107 + 1.108 + virtual bool defaultValue(JSContext *cx, JS::HandleObject wrapper, 1.109 + JSType hint, JS::MutableHandleValue vp) 1.110 + MOZ_OVERRIDE; 1.111 + 1.112 + virtual bool getPrototypeOf(JSContext *cx, JS::HandleObject wrapper, 1.113 + JS::MutableHandleObject protop) MOZ_OVERRIDE; 1.114 + virtual bool setPrototypeOf(JSContext *cx, JS::HandleObject wrapper, 1.115 + JS::HandleObject proto, bool *bp) MOZ_OVERRIDE; 1.116 + 1.117 + static XrayWrapper singleton; 1.118 + 1.119 + private: 1.120 + template <bool HasPrototype> 1.121 + typename mozilla::EnableIf<HasPrototype, bool>::Type 1.122 + getPrototypeOfHelper(JSContext *cx, JS::HandleObject wrapper, 1.123 + JS::HandleObject target, JS::MutableHandleObject protop) 1.124 + { 1.125 + return Traits::singleton.getPrototypeOf(cx, wrapper, target, protop); 1.126 + } 1.127 + template <bool HasPrototype> 1.128 + typename mozilla::EnableIf<!HasPrototype, bool>::Type 1.129 + getPrototypeOfHelper(JSContext *cx, JS::HandleObject wrapper, 1.130 + JS::HandleObject target, JS::MutableHandleObject protop) 1.131 + { 1.132 + return Base::getPrototypeOf(cx, wrapper, protop); 1.133 + } 1.134 + bool getPrototypeOfHelper(JSContext *cx, JS::HandleObject wrapper, 1.135 + JS::HandleObject target, JS::MutableHandleObject protop) 1.136 + { 1.137 + return getPrototypeOfHelper<Traits::HasPrototype>(cx, wrapper, target, 1.138 + protop); 1.139 + } 1.140 + 1.141 + bool enumerate(JSContext *cx, JS::Handle<JSObject*> wrapper, unsigned flags, 1.142 + JS::AutoIdVector &props); 1.143 +}; 1.144 + 1.145 +#define PermissiveXrayXPCWN xpc::XrayWrapper<js::CrossCompartmentWrapper, xpc::XPCWrappedNativeXrayTraits> 1.146 +#define SecurityXrayXPCWN xpc::XrayWrapper<js::CrossCompartmentSecurityWrapper, xpc::XPCWrappedNativeXrayTraits> 1.147 +#define PermissiveXrayDOM xpc::XrayWrapper<js::CrossCompartmentWrapper, xpc::DOMXrayTraits> 1.148 +#define SecurityXrayDOM xpc::XrayWrapper<js::CrossCompartmentSecurityWrapper, xpc::DOMXrayTraits> 1.149 +#define PermissiveXrayJS xpc::XrayWrapper<js::CrossCompartmentWrapper, xpc::JSXrayTraits> 1.150 +#define SCSecurityXrayXPCWN xpc::XrayWrapper<js::SameCompartmentSecurityWrapper, xpc::XPCWrappedNativeXrayTraits> 1.151 + 1.152 +class SandboxProxyHandler : public js::Wrapper { 1.153 +public: 1.154 + SandboxProxyHandler() : js::Wrapper(0) 1.155 + { 1.156 + } 1.157 + 1.158 + virtual bool getPropertyDescriptor(JSContext *cx, JS::Handle<JSObject*> proxy, 1.159 + JS::Handle<jsid> id, 1.160 + JS::MutableHandle<JSPropertyDescriptor> desc) MOZ_OVERRIDE; 1.161 + virtual bool getOwnPropertyDescriptor(JSContext *cx, JS::Handle<JSObject*> proxy, 1.162 + JS::Handle<jsid> id, 1.163 + JS::MutableHandle<JSPropertyDescriptor> desc) MOZ_OVERRIDE; 1.164 + 1.165 + // We just forward the derived traps to the BaseProxyHandler versions which 1.166 + // implement them in terms of the fundamental traps. 1.167 + virtual bool has(JSContext *cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id, 1.168 + bool *bp) MOZ_OVERRIDE; 1.169 + virtual bool hasOwn(JSContext *cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id, 1.170 + bool *bp) MOZ_OVERRIDE; 1.171 + virtual bool get(JSContext *cx, JS::Handle<JSObject*> proxy, JS::Handle<JSObject*> receiver, 1.172 + JS::Handle<jsid> id, JS::MutableHandle<JS::Value> vp) MOZ_OVERRIDE; 1.173 + virtual bool set(JSContext *cx, JS::Handle<JSObject*> proxy, JS::Handle<JSObject*> receiver, 1.174 + JS::Handle<jsid> id, bool strict, JS::MutableHandle<JS::Value> vp) MOZ_OVERRIDE; 1.175 + virtual bool keys(JSContext *cx, JS::Handle<JSObject*> proxy, 1.176 + JS::AutoIdVector &props) MOZ_OVERRIDE; 1.177 + virtual bool iterate(JSContext *cx, JS::Handle<JSObject*> proxy, unsigned flags, 1.178 + JS::MutableHandle<JS::Value> vp) MOZ_OVERRIDE; 1.179 +}; 1.180 + 1.181 +extern SandboxProxyHandler sandboxProxyHandler; 1.182 + 1.183 +// A proxy handler that lets us wrap callables and invoke them with 1.184 +// the correct this object, while forwarding all other operations down 1.185 +// to them directly. 1.186 +class SandboxCallableProxyHandler : public js::Wrapper { 1.187 +public: 1.188 + SandboxCallableProxyHandler() : js::Wrapper(0) 1.189 + { 1.190 + } 1.191 + 1.192 + virtual bool call(JSContext *cx, JS::Handle<JSObject*> proxy, 1.193 + const JS::CallArgs &args) MOZ_OVERRIDE; 1.194 +}; 1.195 + 1.196 +extern SandboxCallableProxyHandler sandboxCallableProxyHandler; 1.197 + 1.198 +class AutoSetWrapperNotShadowing; 1.199 +class XPCWrappedNativeXrayTraits; 1.200 + 1.201 +class MOZ_STACK_CLASS ResolvingId { 1.202 +public: 1.203 + ResolvingId(JSContext *cx, JS::HandleObject wrapper, JS::HandleId id); 1.204 + ~ResolvingId(); 1.205 + 1.206 + bool isXrayShadowing(jsid id); 1.207 + bool isResolving(jsid id); 1.208 + static ResolvingId* getResolvingId(JSObject *holder); 1.209 + static JSObject* getHolderObject(JSObject *wrapper); 1.210 + static ResolvingId *getResolvingIdFromWrapper(JSObject *wrapper); 1.211 + 1.212 +private: 1.213 + friend class AutoSetWrapperNotShadowing; 1.214 + friend class XPCWrappedNativeXrayTraits; 1.215 + 1.216 + JS::HandleId mId; 1.217 + JS::RootedObject mHolder; 1.218 + ResolvingId *mPrev; 1.219 + bool mXrayShadowing; 1.220 +}; 1.221 + 1.222 +} 1.223 + 1.224 +#endif