michael@0: /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ michael@0: /* vim: set ts=8 sts=4 et sw=4 tw=99: */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #ifndef XrayWrapper_h michael@0: #define XrayWrapper_h michael@0: michael@0: #include "mozilla/Attributes.h" michael@0: michael@0: #include "jswrapper.h" michael@0: michael@0: // Xray wrappers re-resolve the original native properties on the native michael@0: // object and always directly access to those properties. michael@0: // Because they work so differently from the rest of the wrapper hierarchy, michael@0: // we pull them out of the Wrapper inheritance hierarchy and create a michael@0: // little world around them. michael@0: michael@0: namespace xpc { michael@0: michael@0: bool michael@0: holder_get(JSContext *cx, JS::HandleObject holder, JS::HandleId id, JS::MutableHandleValue vp); michael@0: bool michael@0: holder_set(JSContext *cx, JS::HandleObject holder, JS::HandleId id, bool strict, michael@0: JS::MutableHandleValue vp); michael@0: michael@0: namespace XrayUtils { michael@0: michael@0: bool IsXPCWNHolderClass(const JSClass *clasp); michael@0: michael@0: bool CloneExpandoChain(JSContext *cx, JSObject *src, JSObject *dst); michael@0: michael@0: bool michael@0: IsTransparent(JSContext *cx, JS::HandleObject wrapper, JS::HandleId id); michael@0: michael@0: JSObject * michael@0: GetNativePropertiesObject(JSContext *cx, JSObject *wrapper); michael@0: michael@0: bool michael@0: IsXrayResolving(JSContext *cx, JS::HandleObject wrapper, JS::HandleId id); michael@0: michael@0: bool michael@0: HasNativeProperty(JSContext *cx, JS::HandleObject wrapper, JS::HandleId id, michael@0: bool *hasProp); michael@0: } michael@0: michael@0: class XrayTraits; michael@0: class XPCWrappedNativeXrayTraits; michael@0: class DOMXrayTraits; michael@0: class JSXrayTraits; michael@0: michael@0: michael@0: enum XrayType { michael@0: XrayForDOMObject, michael@0: XrayForWrappedNative, michael@0: XrayForJSObject, michael@0: NotXray michael@0: }; michael@0: michael@0: XrayType GetXrayType(JSObject *obj); michael@0: XrayTraits* GetXrayTraits(JSObject *obj); michael@0: michael@0: // NB: Base *must* derive from JSProxyHandler michael@0: template michael@0: class XrayWrapper : public Base { michael@0: public: michael@0: XrayWrapper(unsigned flags); michael@0: virtual ~XrayWrapper(); michael@0: michael@0: /* Fundamental proxy traps. */ michael@0: virtual bool isExtensible(JSContext *cx, JS::Handle wrapper, bool *extensible) MOZ_OVERRIDE; michael@0: virtual bool preventExtensions(JSContext *cx, JS::Handle wrapper) MOZ_OVERRIDE; michael@0: virtual bool getPropertyDescriptor(JSContext *cx, JS::Handle wrapper, JS::Handle id, michael@0: JS::MutableHandle desc); michael@0: virtual bool getOwnPropertyDescriptor(JSContext *cx, JS::Handle wrapper, JS::Handle id, michael@0: JS::MutableHandle desc); michael@0: virtual bool defineProperty(JSContext *cx, JS::Handle wrapper, JS::Handle id, michael@0: JS::MutableHandle desc); michael@0: virtual bool getOwnPropertyNames(JSContext *cx, JS::Handle wrapper, michael@0: JS::AutoIdVector &props); michael@0: virtual bool delete_(JSContext *cx, JS::Handle wrapper, michael@0: JS::Handle id, bool *bp); michael@0: virtual bool enumerate(JSContext *cx, JS::Handle wrapper, JS::AutoIdVector &props); michael@0: michael@0: /* Derived proxy traps. */ michael@0: virtual bool get(JSContext *cx, JS::Handle wrapper, JS::Handle receiver, michael@0: JS::Handle id, JS::MutableHandle vp); michael@0: virtual bool set(JSContext *cx, JS::Handle wrapper, JS::Handle receiver, michael@0: JS::Handle id, bool strict, JS::MutableHandle vp); michael@0: virtual bool has(JSContext *cx, JS::Handle wrapper, JS::Handle id, michael@0: bool *bp); michael@0: virtual bool hasOwn(JSContext *cx, JS::Handle wrapper, JS::Handle id, michael@0: bool *bp); michael@0: virtual bool keys(JSContext *cx, JS::Handle wrapper, michael@0: JS::AutoIdVector &props); michael@0: virtual bool iterate(JSContext *cx, JS::Handle wrapper, unsigned flags, michael@0: JS::MutableHandle vp); michael@0: michael@0: virtual bool call(JSContext *cx, JS::Handle wrapper, michael@0: const JS::CallArgs &args) MOZ_OVERRIDE; michael@0: virtual bool construct(JSContext *cx, JS::Handle wrapper, michael@0: const JS::CallArgs &args) MOZ_OVERRIDE; michael@0: michael@0: virtual bool defaultValue(JSContext *cx, JS::HandleObject wrapper, michael@0: JSType hint, JS::MutableHandleValue vp) michael@0: MOZ_OVERRIDE; michael@0: michael@0: virtual bool getPrototypeOf(JSContext *cx, JS::HandleObject wrapper, michael@0: JS::MutableHandleObject protop) MOZ_OVERRIDE; michael@0: virtual bool setPrototypeOf(JSContext *cx, JS::HandleObject wrapper, michael@0: JS::HandleObject proto, bool *bp) MOZ_OVERRIDE; michael@0: michael@0: static XrayWrapper singleton; michael@0: michael@0: private: michael@0: template michael@0: typename mozilla::EnableIf::Type michael@0: getPrototypeOfHelper(JSContext *cx, JS::HandleObject wrapper, michael@0: JS::HandleObject target, JS::MutableHandleObject protop) michael@0: { michael@0: return Traits::singleton.getPrototypeOf(cx, wrapper, target, protop); michael@0: } michael@0: template michael@0: typename mozilla::EnableIf::Type michael@0: getPrototypeOfHelper(JSContext *cx, JS::HandleObject wrapper, michael@0: JS::HandleObject target, JS::MutableHandleObject protop) michael@0: { michael@0: return Base::getPrototypeOf(cx, wrapper, protop); michael@0: } michael@0: bool getPrototypeOfHelper(JSContext *cx, JS::HandleObject wrapper, michael@0: JS::HandleObject target, JS::MutableHandleObject protop) michael@0: { michael@0: return getPrototypeOfHelper(cx, wrapper, target, michael@0: protop); michael@0: } michael@0: michael@0: bool enumerate(JSContext *cx, JS::Handle wrapper, unsigned flags, michael@0: JS::AutoIdVector &props); michael@0: }; michael@0: michael@0: #define PermissiveXrayXPCWN xpc::XrayWrapper michael@0: #define SecurityXrayXPCWN xpc::XrayWrapper michael@0: #define PermissiveXrayDOM xpc::XrayWrapper michael@0: #define SecurityXrayDOM xpc::XrayWrapper michael@0: #define PermissiveXrayJS xpc::XrayWrapper michael@0: #define SCSecurityXrayXPCWN xpc::XrayWrapper michael@0: michael@0: class SandboxProxyHandler : public js::Wrapper { michael@0: public: michael@0: SandboxProxyHandler() : js::Wrapper(0) michael@0: { michael@0: } michael@0: michael@0: virtual bool getPropertyDescriptor(JSContext *cx, JS::Handle proxy, michael@0: JS::Handle id, michael@0: JS::MutableHandle desc) MOZ_OVERRIDE; michael@0: virtual bool getOwnPropertyDescriptor(JSContext *cx, JS::Handle proxy, michael@0: JS::Handle id, michael@0: JS::MutableHandle desc) MOZ_OVERRIDE; michael@0: michael@0: // We just forward the derived traps to the BaseProxyHandler versions which michael@0: // implement them in terms of the fundamental traps. michael@0: virtual bool has(JSContext *cx, JS::Handle proxy, JS::Handle id, michael@0: bool *bp) MOZ_OVERRIDE; michael@0: virtual bool hasOwn(JSContext *cx, JS::Handle proxy, JS::Handle id, michael@0: bool *bp) MOZ_OVERRIDE; michael@0: virtual bool get(JSContext *cx, JS::Handle proxy, JS::Handle receiver, michael@0: JS::Handle id, JS::MutableHandle vp) MOZ_OVERRIDE; michael@0: virtual bool set(JSContext *cx, JS::Handle proxy, JS::Handle receiver, michael@0: JS::Handle id, bool strict, JS::MutableHandle vp) MOZ_OVERRIDE; michael@0: virtual bool keys(JSContext *cx, JS::Handle proxy, michael@0: JS::AutoIdVector &props) MOZ_OVERRIDE; michael@0: virtual bool iterate(JSContext *cx, JS::Handle proxy, unsigned flags, michael@0: JS::MutableHandle vp) MOZ_OVERRIDE; michael@0: }; michael@0: michael@0: extern SandboxProxyHandler sandboxProxyHandler; michael@0: michael@0: // A proxy handler that lets us wrap callables and invoke them with michael@0: // the correct this object, while forwarding all other operations down michael@0: // to them directly. michael@0: class SandboxCallableProxyHandler : public js::Wrapper { michael@0: public: michael@0: SandboxCallableProxyHandler() : js::Wrapper(0) michael@0: { michael@0: } michael@0: michael@0: virtual bool call(JSContext *cx, JS::Handle proxy, michael@0: const JS::CallArgs &args) MOZ_OVERRIDE; michael@0: }; michael@0: michael@0: extern SandboxCallableProxyHandler sandboxCallableProxyHandler; michael@0: michael@0: class AutoSetWrapperNotShadowing; michael@0: class XPCWrappedNativeXrayTraits; michael@0: michael@0: class MOZ_STACK_CLASS ResolvingId { michael@0: public: michael@0: ResolvingId(JSContext *cx, JS::HandleObject wrapper, JS::HandleId id); michael@0: ~ResolvingId(); michael@0: michael@0: bool isXrayShadowing(jsid id); michael@0: bool isResolving(jsid id); michael@0: static ResolvingId* getResolvingId(JSObject *holder); michael@0: static JSObject* getHolderObject(JSObject *wrapper); michael@0: static ResolvingId *getResolvingIdFromWrapper(JSObject *wrapper); michael@0: michael@0: private: michael@0: friend class AutoSetWrapperNotShadowing; michael@0: friend class XPCWrappedNativeXrayTraits; michael@0: michael@0: JS::HandleId mId; michael@0: JS::RootedObject mHolder; michael@0: ResolvingId *mPrev; michael@0: bool mXrayShadowing; michael@0: }; michael@0: michael@0: } michael@0: michael@0: #endif