/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- * vim: set ts=4 sw=4 et tw=99 ft=cpp: * * 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 "mozilla/Attributes.h" #include "mozilla/GuardObjects.h" #include "jsapi.h" #include "jswrapper.h" // Xray wrappers re-resolve the original native properties on the native // object and always directly access to those properties. // Because they work so differently from the rest of the wrapper hierarchy, // we pull them out of the Wrapper inheritance hierarchy and create a // little world around them. class XPCWrappedNative; namespace xpc { bool holder_get(JSContext *cx, JS::HandleObject holder, JS::HandleId id, JS::MutableHandleValue vp); bool holder_set(JSContext *cx, JS::HandleObject holder, JS::HandleId id, bool strict, JS::MutableHandleValue vp); namespace XrayUtils { extern JSClass HolderClass; bool CloneExpandoChain(JSContext *cx, JSObject *src, JSObject *dst); bool IsTransparent(JSContext *cx, JS::HandleObject wrapper, JS::HandleId id); JSObject * GetNativePropertiesObject(JSContext *cx, JSObject *wrapper); bool IsXrayResolving(JSContext *cx, JS::HandleObject wrapper, JS::HandleId id); bool HasNativeProperty(JSContext *cx, JS::HandleObject wrapper, JS::HandleId id, bool *hasProp); } class XrayTraits; class XPCWrappedNativeXrayTraits; class ProxyXrayTraits; class DOMXrayTraits; enum XrayType { XrayForDOMObject, XrayForWrappedNative, NotXray }; XrayType GetXrayType(JSObject *obj); XrayTraits* GetXrayTraits(JSObject *obj); // NB: Base *must* derive from JSProxyHandler template class XrayWrapper : public Base { public: XrayWrapper(unsigned flags); virtual ~XrayWrapper(); /* Fundamental proxy traps. */ virtual bool isExtensible(JSContext *cx, JS::Handle wrapper, bool *extensible) MOZ_OVERRIDE; virtual bool preventExtensions(JSContext *cx, JS::Handle wrapper) MOZ_OVERRIDE; virtual bool getPropertyDescriptor(JSContext *cx, JS::Handle wrapper, JS::Handle id, JS::MutableHandle desc, unsigned flags); virtual bool getOwnPropertyDescriptor(JSContext *cx, JS::Handle wrapper, JS::Handle id, JS::MutableHandle desc, unsigned flags); virtual bool defineProperty(JSContext *cx, JS::Handle wrapper, JS::Handle id, JS::MutableHandle desc); virtual bool getOwnPropertyNames(JSContext *cx, JS::Handle wrapper, js::AutoIdVector &props); virtual bool delete_(JSContext *cx, JS::Handle wrapper, JS::Handle id, bool *bp); virtual bool enumerate(JSContext *cx, JS::Handle wrapper, js::AutoIdVector &props); /* Derived proxy traps. */ virtual bool get(JSContext *cx, JS::Handle wrapper, JS::Handle receiver, JS::Handle id, JS::MutableHandle vp); virtual bool set(JSContext *cx, JS::Handle wrapper, JS::Handle receiver, JS::Handle id, bool strict, JS::MutableHandle vp); virtual bool has(JSContext *cx, JS::Handle wrapper, JS::Handle id, bool *bp); virtual bool hasOwn(JSContext *cx, JS::Handle wrapper, JS::Handle id, bool *bp); virtual bool keys(JSContext *cx, JS::Handle wrapper, js::AutoIdVector &props); virtual bool iterate(JSContext *cx, JS::Handle wrapper, unsigned flags, JS::MutableHandle vp); virtual bool call(JSContext *cx, JS::Handle wrapper, const JS::CallArgs &args) MOZ_OVERRIDE; virtual bool construct(JSContext *cx, JS::Handle wrapper, const JS::CallArgs &args) MOZ_OVERRIDE; virtual bool defaultValue(JSContext *cx, JS::HandleObject wrapper, JSType hint, JS::MutableHandleValue vp) MOZ_OVERRIDE; static XrayWrapper singleton; private: bool enumerate(JSContext *cx, JS::Handle wrapper, unsigned flags, JS::AutoIdVector &props); }; #define PermissiveXrayXPCWN xpc::XrayWrapper #define SecurityXrayXPCWN xpc::XrayWrapper #define PermissiveXrayDOM xpc::XrayWrapper #define SecurityXrayDOM xpc::XrayWrapper #define SCSecurityXrayXPCWN xpc::XrayWrapper #define SCPermissiveXrayXPCWN xpc::XrayWrapper #define SCPermissiveXrayDOM xpc::XrayWrapper class SandboxProxyHandler : public js::Wrapper { public: SandboxProxyHandler() : js::Wrapper(0) { } virtual bool getPropertyDescriptor(JSContext *cx, JS::Handle proxy, JS::Handle id, JS::MutableHandle desc, unsigned flags) MOZ_OVERRIDE; virtual bool getOwnPropertyDescriptor(JSContext *cx, JS::Handle proxy, JS::Handle id, JS::MutableHandle desc, unsigned flags) MOZ_OVERRIDE; // We just forward the derived traps to the BaseProxyHandler versions which // implement them in terms of the fundamental traps. virtual bool has(JSContext *cx, JS::Handle proxy, JS::Handle id, bool *bp) MOZ_OVERRIDE; virtual bool hasOwn(JSContext *cx, JS::Handle proxy, JS::Handle id, bool *bp) MOZ_OVERRIDE; virtual bool get(JSContext *cx, JS::Handle proxy, JS::Handle receiver, JS::Handle id, JS::MutableHandle vp) MOZ_OVERRIDE; virtual bool set(JSContext *cx, JS::Handle proxy, JS::Handle receiver, JS::Handle id, bool strict, JS::MutableHandle vp) MOZ_OVERRIDE; virtual bool keys(JSContext *cx, JS::Handle proxy, JS::AutoIdVector &props) MOZ_OVERRIDE; virtual bool iterate(JSContext *cx, JS::Handle proxy, unsigned flags, JS::MutableHandle vp) MOZ_OVERRIDE; }; extern 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: SandboxCallableProxyHandler() : js::Wrapper(0) { } virtual bool call(JSContext *cx, JS::Handle proxy, const JS::CallArgs &args) MOZ_OVERRIDE; }; extern SandboxCallableProxyHandler sandboxCallableProxyHandler; class AutoSetWrapperNotShadowing; class XPCWrappedNativeXrayTraits; class MOZ_STACK_CLASS ResolvingId { public: ResolvingId(JSContext *cx, JS::HandleObject wrapper, JS::HandleId id); ~ResolvingId(); bool isXrayShadowing(jsid id); bool isResolving(jsid id); static ResolvingId* getResolvingId(JSObject *holder); static JSObject* getHolderObject(JSObject *wrapper); static ResolvingId *getResolvingIdFromWrapper(JSObject *wrapper); private: friend class AutoSetWrapperNotShadowing; friend class XPCWrappedNativeXrayTraits; JS::HandleId mId; JS::RootedObject mHolder; ResolvingId *mPrev; bool mXrayShadowing; }; }