mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-15 14:25:52 +00:00
Implement new chrome wrappers (574539, r=mrbkap).
This commit is contained in:
parent
11099189c8
commit
6f976ada12
@ -149,6 +149,22 @@ NewKeyValuePair(JSContext *cx, jsid key, jsval val, jsval *rval)
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
IdToIteratorValue(JSContext *cx, JSObject *obj, jsid id, uintN flags, jsval *vp)
|
||||
{
|
||||
if (!(flags & JSITER_FOREACH)) {
|
||||
*vp = ID_TO_VALUE(id);
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Do the lookup on the original object instead of the prototype. */
|
||||
if (!obj->getProperty(cx, id, vp))
|
||||
return false;
|
||||
if ((flags & JSITER_KEYVALUE) && !NewKeyValuePair(cx, id, *vp, vp))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
Enumerate(JSContext *cx, JSObject *obj, JSObject *pobj, jsid id,
|
||||
bool enumerable, uintN flags, HashSet<jsid>& ht,
|
||||
@ -166,17 +182,10 @@ Enumerate(JSContext *cx, JSObject *obj, JSObject *pobj, jsid id,
|
||||
return false;
|
||||
}
|
||||
if (enumerable || (flags & JSITER_HIDDEN)) {
|
||||
if (!vec.append(ID_TO_VALUE(id)))
|
||||
if (!vec.append(JSVAL_VOID))
|
||||
return false;
|
||||
if (!IdToIteratorValue(cx, obj, id, flags, vec.end() - 1))
|
||||
return false;
|
||||
if (flags & JSITER_FOREACH) {
|
||||
jsval *vp = vec.end() - 1;
|
||||
|
||||
/* Do the lookup on the original object instead of the prototype. */
|
||||
if (!obj->getProperty(cx, id, vp))
|
||||
return false;
|
||||
if ((flags & JSITER_KEYVALUE) && !NewKeyValuePair(cx, id, *vp, vp))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@ -434,6 +443,16 @@ IdVectorToIterator(JSContext *cx, JSObject *obj, uintN flags, AutoValueVector &p
|
||||
if (!ni)
|
||||
return false;
|
||||
|
||||
/* If this is a for-each iteration, fetch the values or key/value pairs. */
|
||||
if (flags & JSITER_FOREACH) {
|
||||
size_t length = props.length();
|
||||
for (size_t n = 0; n < length; ++n) {
|
||||
jsval *vp = &ni->begin()[n];
|
||||
if (!IdToIteratorValue(cx, obj, *vp, flags, vp))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
iterobj->setNativeIterator(ni);
|
||||
|
||||
RegisterEnumerator(cx, iterobj, ni);
|
||||
|
@ -472,14 +472,14 @@ JSCrossCompartmentWrapper::~JSCrossCompartmentWrapper()
|
||||
{
|
||||
}
|
||||
|
||||
#define PIERCE(cx, proxy, pre, op, post) \
|
||||
JS_BEGIN_MACRO \
|
||||
AutoCompartment call(cx, wrappedObject(proxy)); \
|
||||
if (!call.enter() || !(pre) || !enter(cx, proxy, id) || !(op)) \
|
||||
return false; \
|
||||
leave(cx, proxy); \
|
||||
call.leave(); \
|
||||
return (post); \
|
||||
#define PIERCE(cx, proxy, mode, pre, op, post) \
|
||||
JS_BEGIN_MACRO \
|
||||
AutoCompartment call(cx, wrappedObject(proxy)); \
|
||||
if (!call.enter() || !(pre) || !enter(cx, proxy, id, mode) || !(op)) \
|
||||
return false; \
|
||||
leave(cx, proxy); \
|
||||
call.leave(); \
|
||||
return (post); \
|
||||
JS_END_MACRO
|
||||
|
||||
#define NOTHING (true)
|
||||
@ -487,7 +487,7 @@ JSCrossCompartmentWrapper::~JSCrossCompartmentWrapper()
|
||||
bool
|
||||
JSCrossCompartmentWrapper::getPropertyDescriptor(JSContext *cx, JSObject *proxy, jsid id, JSPropertyDescriptor *desc)
|
||||
{
|
||||
PIERCE(cx, proxy,
|
||||
PIERCE(cx, proxy, GET,
|
||||
call.destination->wrapId(cx, &id),
|
||||
JSWrapper::getPropertyDescriptor(cx, proxy, id, desc),
|
||||
call.origin->wrap(cx, desc));
|
||||
@ -496,7 +496,7 @@ JSCrossCompartmentWrapper::getPropertyDescriptor(JSContext *cx, JSObject *proxy,
|
||||
bool
|
||||
JSCrossCompartmentWrapper::getOwnPropertyDescriptor(JSContext *cx, JSObject *proxy, jsid id, JSPropertyDescriptor *desc)
|
||||
{
|
||||
PIERCE(cx, proxy,
|
||||
PIERCE(cx, proxy, GET,
|
||||
call.destination->wrapId(cx, &id),
|
||||
JSWrapper::getOwnPropertyDescriptor(cx, proxy, id, desc),
|
||||
call.origin->wrap(cx, desc));
|
||||
@ -506,7 +506,7 @@ bool
|
||||
JSCrossCompartmentWrapper::defineProperty(JSContext *cx, JSObject *proxy, jsid id, JSPropertyDescriptor *desc)
|
||||
{
|
||||
AutoDescriptor desc2(cx, desc);
|
||||
PIERCE(cx, proxy,
|
||||
PIERCE(cx, proxy, SET,
|
||||
call.destination->wrapId(cx, &id) && call.destination->wrap(cx, &desc2),
|
||||
JSWrapper::getOwnPropertyDescriptor(cx, proxy, id, &desc2),
|
||||
NOTHING);
|
||||
@ -515,16 +515,16 @@ JSCrossCompartmentWrapper::defineProperty(JSContext *cx, JSObject *proxy, jsid i
|
||||
bool
|
||||
JSCrossCompartmentWrapper::getOwnPropertyNames(JSContext *cx, JSObject *proxy, AutoValueVector &props)
|
||||
{
|
||||
PIERCE(cx, proxy,
|
||||
PIERCE(cx, proxy, GET,
|
||||
NOTHING,
|
||||
JSWrapper::getOwnPropertyNames(cx, proxy, props),
|
||||
filter(cx, proxy, props) && call.origin->wrap(cx, props));
|
||||
call.origin->wrap(cx, props));
|
||||
}
|
||||
|
||||
bool
|
||||
JSCrossCompartmentWrapper::delete_(JSContext *cx, JSObject *proxy, jsid id, bool *bp)
|
||||
{
|
||||
PIERCE(cx, proxy,
|
||||
PIERCE(cx, proxy, SET,
|
||||
call.destination->wrapId(cx, &id),
|
||||
JSWrapper::delete_(cx, proxy, id, bp),
|
||||
NOTHING);
|
||||
@ -533,16 +533,16 @@ JSCrossCompartmentWrapper::delete_(JSContext *cx, JSObject *proxy, jsid id, bool
|
||||
bool
|
||||
JSCrossCompartmentWrapper::enumerate(JSContext *cx, JSObject *proxy, AutoValueVector &props)
|
||||
{
|
||||
PIERCE(cx, proxy,
|
||||
PIERCE(cx, proxy, GET,
|
||||
NOTHING,
|
||||
JSWrapper::enumerate(cx, proxy, props),
|
||||
filter(cx, proxy, props) && call.origin->wrap(cx, props));
|
||||
call.origin->wrap(cx, props));
|
||||
}
|
||||
|
||||
bool
|
||||
JSCrossCompartmentWrapper::has(JSContext *cx, JSObject *proxy, jsid id, bool *bp)
|
||||
{
|
||||
PIERCE(cx, proxy,
|
||||
PIERCE(cx, proxy, GET,
|
||||
call.destination->wrapId(cx, &id),
|
||||
JSWrapper::has(cx, proxy, id, bp),
|
||||
NOTHING);
|
||||
@ -551,7 +551,7 @@ JSCrossCompartmentWrapper::has(JSContext *cx, JSObject *proxy, jsid id, bool *bp
|
||||
bool
|
||||
JSCrossCompartmentWrapper::hasOwn(JSContext *cx, JSObject *proxy, jsid id, bool *bp)
|
||||
{
|
||||
PIERCE(cx, proxy,
|
||||
PIERCE(cx, proxy, GET,
|
||||
call.destination->wrapId(cx, &id),
|
||||
JSWrapper::hasOwn(cx, proxy, id, bp),
|
||||
NOTHING);
|
||||
@ -560,7 +560,7 @@ JSCrossCompartmentWrapper::hasOwn(JSContext *cx, JSObject *proxy, jsid id, bool
|
||||
bool
|
||||
JSCrossCompartmentWrapper::get(JSContext *cx, JSObject *proxy, JSObject *receiver, jsid id, jsval *vp)
|
||||
{
|
||||
PIERCE(cx, proxy,
|
||||
PIERCE(cx, proxy, GET,
|
||||
call.destination->wrap(cx, &receiver) && call.destination->wrapId(cx, &id),
|
||||
JSWrapper::get(cx, proxy, receiver, id, vp),
|
||||
call.origin->wrap(cx, vp));
|
||||
@ -570,7 +570,7 @@ bool
|
||||
JSCrossCompartmentWrapper::set(JSContext *cx, JSObject *proxy, JSObject *receiver, jsid id, jsval *vp)
|
||||
{
|
||||
AutoValueRooter tvr(cx, *vp);
|
||||
PIERCE(cx, proxy,
|
||||
PIERCE(cx, proxy, SET,
|
||||
call.destination->wrap(cx, &receiver) && call.destination->wrapId(cx, &id) && call.destination->wrap(cx, tvr.addr()),
|
||||
JSWrapper::set(cx, proxy, receiver, id, tvr.addr()),
|
||||
NOTHING);
|
||||
@ -579,19 +579,49 @@ JSCrossCompartmentWrapper::set(JSContext *cx, JSObject *proxy, JSObject *receive
|
||||
bool
|
||||
JSCrossCompartmentWrapper::enumerateOwn(JSContext *cx, JSObject *proxy, AutoValueVector &props)
|
||||
{
|
||||
PIERCE(cx, proxy,
|
||||
PIERCE(cx, proxy, GET,
|
||||
NOTHING,
|
||||
JSWrapper::enumerateOwn(cx, proxy, props),
|
||||
filter(cx, proxy, props) && call.origin->wrap(cx, props));
|
||||
call.origin->wrap(cx, props));
|
||||
}
|
||||
|
||||
/*
|
||||
* We can reify non-escaping iterator objects instead of having to wrap them. This
|
||||
* allows fast iteration over objects across a compartment boundary.
|
||||
*/
|
||||
static bool
|
||||
CanReify(jsval *vp)
|
||||
{
|
||||
return !JSVAL_IS_PRIMITIVE(*vp) &&
|
||||
JSVAL_TO_OBJECT(*vp)->getClass() == &js_IteratorClass.base &&
|
||||
!!(JSVAL_TO_OBJECT(*vp)->getNativeIterator()->flags & JSITER_ENUMERATE);
|
||||
}
|
||||
|
||||
static bool
|
||||
Reify(JSContext *cx, JSCompartment *origin, jsval *vp)
|
||||
{
|
||||
JSObject *iterObj = JSVAL_TO_OBJECT(*vp);
|
||||
NativeIterator *ni = iterObj->getNativeIterator();
|
||||
AutoValueVector props(cx);
|
||||
size_t length = ni->length();
|
||||
if (length > 0) {
|
||||
props.resize(length);
|
||||
for (size_t n = 0; n < length; ++n)
|
||||
props[n] = origin->wrap(cx, &ni->begin()[n]);
|
||||
}
|
||||
|
||||
JSObject *obj = ni->obj;
|
||||
return origin->wrap(cx, &obj) &&
|
||||
IdVectorToIterator(cx, obj, ni->flags, props, vp);
|
||||
}
|
||||
|
||||
bool
|
||||
JSCrossCompartmentWrapper::iterate(JSContext *cx, JSObject *proxy, uintN flags, jsval *vp)
|
||||
{
|
||||
PIERCE(cx, proxy,
|
||||
PIERCE(cx, proxy, GET,
|
||||
NOTHING,
|
||||
JSWrapper::iterate(cx, proxy, flags, vp),
|
||||
filter(cx, proxy, vp) && call.origin->wrap(cx, vp));
|
||||
CanReify(vp) ? Reify(cx, call.origin, vp) : call.origin->wrap(cx, vp));
|
||||
}
|
||||
|
||||
bool
|
||||
@ -612,7 +642,7 @@ JSCrossCompartmentWrapper::call(JSContext *cx, JSObject *proxy, uintN argc, jsva
|
||||
jsval *fakevp = call.getvp();
|
||||
fakevp[0] = vp[0];
|
||||
fakevp[1] = vp[1];
|
||||
if (!enter(cx, proxy, JSVAL_VOID) || !JSWrapper::call(cx, proxy, argc, vp))
|
||||
if (!enter(cx, proxy, JSVAL_VOID, GET) || !JSWrapper::call(cx, proxy, argc, vp))
|
||||
return false;
|
||||
|
||||
leave(cx, proxy);
|
||||
@ -635,7 +665,7 @@ JSCrossCompartmentWrapper::construct(JSContext *cx, JSObject *proxy, JSObject *r
|
||||
jsval *vp = call.getvp();
|
||||
vp[0] = OBJECT_TO_JSVAL(call.target);
|
||||
if (!call.destination->wrap(cx, &receiver) ||
|
||||
!enter(cx, proxy, JSVAL_VOID) ||
|
||||
!enter(cx, proxy, JSVAL_VOID, GET) ||
|
||||
!JSWrapper::construct(cx, proxy, receiver, argc, argv, rval)) {
|
||||
return false;
|
||||
}
|
||||
@ -653,7 +683,7 @@ JSCrossCompartmentWrapper::obj_toString(JSContext *cx, JSObject *proxy)
|
||||
if (!call.enter())
|
||||
return NULL;
|
||||
|
||||
if (!enter(cx, proxy, JSVAL_VOID))
|
||||
if (!enter(cx, proxy, JSVAL_VOID, GET))
|
||||
return NULL;
|
||||
JSString *str = JSWrapper::obj_toString(cx, proxy);
|
||||
if (!str)
|
||||
@ -674,7 +704,7 @@ JSCrossCompartmentWrapper::fun_toString(JSContext *cx, JSObject *proxy, uintN in
|
||||
if (!call.enter())
|
||||
return NULL;
|
||||
|
||||
if (!enter(cx, proxy, JSVAL_VOID))
|
||||
if (!enter(cx, proxy, JSVAL_VOID, GET))
|
||||
return NULL;
|
||||
JSString *str = JSWrapper::fun_toString(cx, proxy, indent);
|
||||
if (!str)
|
||||
@ -689,7 +719,7 @@ JSCrossCompartmentWrapper::fun_toString(JSContext *cx, JSObject *proxy, uintN in
|
||||
}
|
||||
|
||||
bool
|
||||
JSCrossCompartmentWrapper::enter(JSContext *cx, JSObject *proxy, jsval id)
|
||||
JSCrossCompartmentWrapper::enter(JSContext *cx, JSObject *proxy, jsval id, Mode mode)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@ -699,16 +729,4 @@ JSCrossCompartmentWrapper::leave(JSContext *cx, JSObject *proxy)
|
||||
{
|
||||
}
|
||||
|
||||
bool
|
||||
JSCrossCompartmentWrapper::filter(JSContext *cx, JSObject *proxy, AutoValueVector &props)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
JSCrossCompartmentWrapper::filter(JSContext *cx, JSObject *proxy, jsval *vp)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
JSCrossCompartmentWrapper JSCrossCompartmentWrapper::singleton;
|
||||
|
@ -101,6 +101,8 @@ class JSCrossCompartmentWrapper : public JSWrapper {
|
||||
JS_FRIEND_API(JSCrossCompartmentWrapper());
|
||||
|
||||
public:
|
||||
typedef enum { GET, SET } Mode;
|
||||
|
||||
virtual JS_FRIEND_API(~JSCrossCompartmentWrapper());
|
||||
|
||||
/* ES5 Harmony fundamental proxy traps. */
|
||||
@ -130,10 +132,8 @@ class JSCrossCompartmentWrapper : public JSWrapper {
|
||||
virtual JSString *fun_toString(JSContext *cx, JSObject *proxy, uintN indent);
|
||||
|
||||
/* Policy enforcement traps. */
|
||||
virtual bool enter(JSContext *cx, JSObject *proxy, jsid id);
|
||||
virtual bool enter(JSContext *cx, JSObject *proxy, jsid id, Mode mode);
|
||||
virtual void leave(JSContext *cx, JSObject *proxy);
|
||||
virtual bool filter(JSContext *cx, JSObject *proxy, js::AutoValueVector &props);
|
||||
virtual bool filter(JSContext *cx, JSObject *proxy, jsval *vp);
|
||||
|
||||
static JSCrossCompartmentWrapper singleton;
|
||||
|
||||
|
115
js/src/xpconnect/src/wrappers/AccessCheck.cpp
Normal file
115
js/src/xpconnect/src/wrappers/AccessCheck.cpp
Normal file
@ -0,0 +1,115 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* vim: set ts=4 sw=4 et tw=99 ft=cpp:
|
||||
*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code, released
|
||||
* June 24, 2010.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* The Mozilla Foundation
|
||||
*
|
||||
* Contributor(s):
|
||||
* Andreas Gal <gal@mozilla.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "jsapi.h"
|
||||
#include "jswrapper.h"
|
||||
|
||||
#include "XPCWrapper.h"
|
||||
|
||||
#include "nsJSPrincipals.h"
|
||||
|
||||
#include "AccessCheck.h"
|
||||
|
||||
namespace xpc {
|
||||
|
||||
nsIPrincipal *
|
||||
GetCompartmentPrincipal(JSCompartment *compartment)
|
||||
{
|
||||
return static_cast<nsJSPrincipals *>(compartment->principals)->nsIPrincipalPtr;
|
||||
}
|
||||
|
||||
bool
|
||||
AccessCheck::isPrivileged(JSCompartment *compartment)
|
||||
{
|
||||
nsIScriptSecurityManager *ssm = XPCWrapper::GetSecurityManager();
|
||||
if(!ssm) {
|
||||
return true;
|
||||
}
|
||||
|
||||
PRBool privileged;
|
||||
if(NS_SUCCEEDED(ssm->IsSystemPrincipal(GetCompartmentPrincipal(compartment), &privileged))
|
||||
&& privileged) {
|
||||
return true;
|
||||
}
|
||||
if(NS_SUCCEEDED(ssm->IsCapabilityEnabled("UniversalXPConnect", &privileged)) && privileged) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
AccessCheck::deny(JSContext *cx, jsid id)
|
||||
{
|
||||
if(id == JSVAL_VOID) {
|
||||
JS_ReportError(cx, "Permission denied to access object");
|
||||
} else {
|
||||
JSString *str = JS_ValueToString(cx, id);
|
||||
JS_ReportError(cx, "Permission denied to access property '%hs'", str);
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
AccessCheck::enter(JSContext *cx, JSObject *wrapper, JSObject *wrappedObject, jsid id,
|
||||
JSCrossCompartmentWrapper::Mode mode)
|
||||
{
|
||||
nsIScriptSecurityManager *ssm = XPCWrapper::GetSecurityManager();
|
||||
if(!ssm) {
|
||||
return true;
|
||||
}
|
||||
JSStackFrame *fp = NULL;
|
||||
nsresult rv = ssm->PushContextPrincipal(cx, JS_FrameIterator(cx, &fp),
|
||||
GetCompartmentPrincipal(wrappedObject->getCompartment(cx)));
|
||||
if(NS_FAILED(rv)) {
|
||||
NS_WARNING("Not allowing call because we're out of memory");
|
||||
JS_ReportOutOfMemory(cx);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
AccessCheck::leave(JSContext *cx, JSObject *wrapper, JSObject *wrappedObject)
|
||||
{
|
||||
nsIScriptSecurityManager *ssm = XPCWrapper::GetSecurityManager();
|
||||
if(ssm) {
|
||||
ssm->PopContextPrincipal(cx);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
57
js/src/xpconnect/src/wrappers/AccessCheck.h
Normal file
57
js/src/xpconnect/src/wrappers/AccessCheck.h
Normal file
@ -0,0 +1,57 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* vim: set ts=4 sw=4 et tw=99 ft=cpp:
|
||||
*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code, released
|
||||
* June 24, 2010.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* The Mozilla Foundation
|
||||
*
|
||||
* Contributor(s):
|
||||
* Andreas Gal <gal@mozilla.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "jsapi.h"
|
||||
#include "jswrapper.h"
|
||||
|
||||
namespace xpc {
|
||||
|
||||
class AccessCheck {
|
||||
public:
|
||||
static bool subsumes(JSCompartment *subject, JSCompartment *object, bool *yesno);
|
||||
static bool isPrivileged(JSCompartment *compartment);
|
||||
|
||||
static void deny(JSContext *cx, jsid id);
|
||||
|
||||
static bool enter(JSContext *cx, JSObject *wrapper, JSObject *wrappedObject, jsid id,
|
||||
JSCrossCompartmentWrapper::Mode mode);
|
||||
static void leave(JSContext *cx, JSObject *wrapper, JSObject *wrappedObject);
|
||||
};
|
||||
|
||||
}
|
244
js/src/xpconnect/src/wrappers/ChromeWrapper.cpp
Normal file
244
js/src/xpconnect/src/wrappers/ChromeWrapper.cpp
Normal file
@ -0,0 +1,244 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* vim: set ts=4 sw=4 et tw=99 ft=cpp:
|
||||
*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code, released
|
||||
* June 24, 2010.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* The Mozilla Foundation
|
||||
*
|
||||
* Contributor(s):
|
||||
* Andreas Gal <gal@mozilla.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "ChromeWrapper.h"
|
||||
#include "AccessCheck.h"
|
||||
|
||||
#include "XPCWrapper.h"
|
||||
|
||||
using namespace js;
|
||||
|
||||
namespace xpc {
|
||||
|
||||
ChromeWrapper ChromeWrapper::singleton;
|
||||
|
||||
ChromeWrapper::ChromeWrapper() : JSCrossCompartmentWrapper()
|
||||
{
|
||||
}
|
||||
|
||||
ChromeWrapper::~ChromeWrapper()
|
||||
{
|
||||
}
|
||||
|
||||
typedef enum { READ = (1<<0), WRITE = (1<<1), DENIED=0 } Permission;
|
||||
|
||||
static bool
|
||||
Allow(JSContext *cx, bool *yesno)
|
||||
{
|
||||
if(yesno) {
|
||||
*yesno = true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
Deny(JSContext *cx, bool *yesno, const char *error)
|
||||
{
|
||||
if(yesno) {
|
||||
*yesno = false;
|
||||
return true;
|
||||
}
|
||||
JS_ReportError(cx, error);
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool
|
||||
CheckAccess(JSContext *cx, JSObject *hallpass, jsid id, JSCrossCompartmentWrapper::Mode mode,
|
||||
bool *yesno = NULL)
|
||||
{
|
||||
if(!hallpass) {
|
||||
return Allow(cx, yesno);
|
||||
}
|
||||
|
||||
Permission perm = DENIED;
|
||||
|
||||
jsval v;
|
||||
if(!JS_LookupPropertyById(cx, hallpass, id, &v)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!JSVAL_IS_STRING(v)) {
|
||||
return Deny(cx, yesno, "property permission must be a string");
|
||||
}
|
||||
|
||||
JSString *str = JSVAL_TO_STRING(v);
|
||||
const jschar *chars = JS_GetStringChars(str);
|
||||
size_t length = JS_GetStringLength(str);
|
||||
for (size_t i = 0; i < length; ++i) {
|
||||
switch (chars[i]) {
|
||||
case 'r':
|
||||
if(perm & READ) {
|
||||
return Deny(cx, yesno, "duplicate 'readable' property flag");
|
||||
}
|
||||
perm = Permission(perm | READ);
|
||||
break;
|
||||
|
||||
case 'w':
|
||||
if(perm & WRITE) {
|
||||
return Deny(cx, yesno, "duplicate 'writable' property flag");
|
||||
}
|
||||
perm = Permission(perm | WRITE);
|
||||
break;
|
||||
|
||||
default:
|
||||
return Deny(cx, yesno, "property permission can only be readable or read and writable");
|
||||
}
|
||||
}
|
||||
|
||||
if(perm == DENIED) {
|
||||
return Deny(cx, yesno, "invalid property permission");
|
||||
}
|
||||
|
||||
if((mode == JSCrossCompartmentWrapper::GET && !(perm & READ)) ||
|
||||
(mode == JSCrossCompartmentWrapper::SET && !(perm & WRITE))) {
|
||||
if(yesno) {
|
||||
*yesno = false;
|
||||
return true;
|
||||
}
|
||||
AccessCheck::deny(cx, id);
|
||||
return false;
|
||||
}
|
||||
|
||||
return Allow(cx, yesno);
|
||||
}
|
||||
|
||||
static bool
|
||||
GetHallPass(JSContext *cx, JSObject *wrappedObject, jsid id, JSObject **hallpassp)
|
||||
{
|
||||
jsid exposedPropsId = GetRTIdByIndex(cx, XPCJSRuntime::IDX_EXPOSEDPROPS);
|
||||
|
||||
JSBool found = JS_FALSE;
|
||||
if(!JS_HasPropertyById(cx, wrappedObject, exposedPropsId, &found))
|
||||
return false;
|
||||
if(!found) {
|
||||
*hallpassp = NULL;
|
||||
return true;
|
||||
}
|
||||
|
||||
jsval exposedProps;
|
||||
if(!JS_LookupPropertyById(cx, wrappedObject, exposedPropsId, &exposedProps))
|
||||
return false;
|
||||
|
||||
if(JSVAL_IS_VOID(exposedProps) || JSVAL_IS_NULL(exposedProps)) {
|
||||
AccessCheck::deny(cx, id);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!JSVAL_IS_OBJECT(exposedProps)) {
|
||||
JS_ReportError(cx,
|
||||
"__exposedProps__ must be undefined, null, or an object");
|
||||
return false;
|
||||
}
|
||||
|
||||
*hallpassp = JSVAL_TO_OBJECT(exposedProps);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
Filter(JSContext *cx, JSObject *wrappedObject, AutoValueVector &props)
|
||||
{
|
||||
JSObject *hallpass;
|
||||
if(!GetHallPass(cx, wrappedObject, JSVAL_VOID, &hallpass))
|
||||
return false;
|
||||
if(!hallpass)
|
||||
return true;
|
||||
size_t w = 0;
|
||||
for (size_t n = 0; n < props.length(); ++n) {
|
||||
bool yes;
|
||||
jsid id = props[n];
|
||||
if(!CheckAccess(cx, hallpass, id, JSCrossCompartmentWrapper::GET, &yes))
|
||||
return false;
|
||||
if(yes) {
|
||||
props[w++] = id;
|
||||
}
|
||||
}
|
||||
props.resize(w);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
ChromeWrapper::getOwnPropertyNames(JSContext *cx, JSObject *wrapper, AutoValueVector &props)
|
||||
{
|
||||
return JSCrossCompartmentWrapper::getOwnPropertyNames(cx, wrapper, props) &&
|
||||
Filter(cx, wrappedObject(wrapper), props);
|
||||
}
|
||||
|
||||
bool
|
||||
ChromeWrapper::enumerate(JSContext *cx, JSObject *wrapper, AutoValueVector &props)
|
||||
{
|
||||
return JSCrossCompartmentWrapper::enumerate(cx, wrapper, props) &&
|
||||
Filter(cx, wrappedObject(wrapper), props);
|
||||
}
|
||||
|
||||
bool
|
||||
ChromeWrapper::enumerateOwn(JSContext *cx, JSObject *wrapper, AutoValueVector &props)
|
||||
{
|
||||
return JSCrossCompartmentWrapper::enumerateOwn(cx, wrapper, props) &&
|
||||
Filter(cx, wrappedObject(wrapper), props);
|
||||
}
|
||||
|
||||
bool
|
||||
ChromeWrapper::iterate(JSContext *cx, JSObject *wrapper, uintN flags, jsval *vp)
|
||||
{
|
||||
// We refuse to trigger the iterator hook across chrome wrappers because
|
||||
// we don't know how to censor custom iterator objects. Instead we trigger
|
||||
// the default proxy iterate trap, which will ask ChromeWrapper::enumerate()
|
||||
// for the list of (consored) ids.
|
||||
return JSProxyHandler::iterate(cx, wrapper, flags, vp);
|
||||
}
|
||||
|
||||
bool
|
||||
ChromeWrapper::enter(JSContext *cx, JSObject *wrapper, jsid id, Mode mode)
|
||||
{
|
||||
JSObject *hallpass;
|
||||
return GetHallPass(cx, wrappedObject(wrapper), id, &hallpass) &&
|
||||
CheckAccess(cx, hallpass, id, mode);
|
||||
}
|
||||
|
||||
JSString *
|
||||
ChromeWrapper::fun_toString(JSContext *cx, JSObject *wrapper, uintN indent)
|
||||
{
|
||||
// Censor Function.prototype.toString.call(wrapper) and decompile Function instead.
|
||||
JSObject *ctor;
|
||||
if(!JS_GetClassObject(cx, wrapper->getGlobal(), JSProto_Function, &ctor))
|
||||
return false;
|
||||
return JS_DecompileFunction(cx, JS_ValueToConstructor(cx, OBJECT_TO_JSVAL(ctor)), indent);
|
||||
}
|
||||
|
||||
}
|
62
js/src/xpconnect/src/wrappers/ChromeWrapper.h
Normal file
62
js/src/xpconnect/src/wrappers/ChromeWrapper.h
Normal file
@ -0,0 +1,62 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* vim: set ts=4 sw=4 et tw=99 ft=cpp:
|
||||
*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code, released
|
||||
* June 24, 2010.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* The Mozilla Foundation
|
||||
*
|
||||
* Contributor(s):
|
||||
* Andreas Gal <gal@mozilla.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "jsapi.h"
|
||||
#include "jswrapper.h"
|
||||
|
||||
namespace xpc {
|
||||
|
||||
class ChromeWrapper : public JSCrossCompartmentWrapper {
|
||||
public:
|
||||
ChromeWrapper();
|
||||
virtual ~ChromeWrapper();
|
||||
|
||||
virtual bool getOwnPropertyNames(JSContext *cx, JSObject *wrapper, js::AutoValueVector &props);
|
||||
virtual bool enumerate(JSContext *cx, JSObject *wrapper, js::AutoValueVector &props);
|
||||
virtual bool enumerateOwn(JSContext *cx, JSObject *wrapper, js::AutoValueVector &props);
|
||||
virtual bool iterate(JSContext *cx, JSObject *proxy, uintN flags, jsval *vp);
|
||||
|
||||
virtual bool enter(JSContext *cx, JSObject *wrapper, jsid id, Mode mode);
|
||||
|
||||
virtual JSString *fun_toString(JSContext *cx, JSObject *wrapper, uintN indent);
|
||||
|
||||
static ChromeWrapper singleton;
|
||||
};
|
||||
|
||||
}
|
@ -14,8 +14,8 @@
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla SpiderMonkey JavaScript 1.9.1 code, released
|
||||
* June 30, 2009.
|
||||
* The Original Code is mozilla.org code, released
|
||||
* June 24, 2010.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* The Mozilla Foundation
|
||||
@ -37,25 +37,12 @@
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "jsapi.h"
|
||||
#include "jswrapper.h"
|
||||
|
||||
#include "XPCWrapper.h"
|
||||
|
||||
#include "nsJSPrincipals.h"
|
||||
#include "ContentWrapper.h"
|
||||
#include "AccessCheck.h"
|
||||
|
||||
namespace xpc {
|
||||
|
||||
class ContentWrapper : public JSCrossCompartmentWrapper {
|
||||
public:
|
||||
ContentWrapper();
|
||||
virtual ~ContentWrapper();
|
||||
|
||||
virtual bool enter(JSContext *cx, JSObject *proxy, jsid id);
|
||||
virtual void leave(JSContext *cx, JSObject *proxy);
|
||||
|
||||
static ContentWrapper singleton;
|
||||
};
|
||||
ContentWrapper ContentWrapper::singleton;
|
||||
|
||||
ContentWrapper::ContentWrapper() : JSCrossCompartmentWrapper()
|
||||
{
|
||||
@ -66,41 +53,15 @@ ContentWrapper::~ContentWrapper()
|
||||
}
|
||||
|
||||
bool
|
||||
ContentWrapper::enter(JSContext *cx, JSObject *wrapper, jsid id)
|
||||
ContentWrapper::enter(JSContext *cx, JSObject *wrapper, jsid id, Mode mode)
|
||||
{
|
||||
nsIScriptSecurityManager *ssm = XPCWrapper::GetSecurityManager();
|
||||
if(!ssm) {
|
||||
return true;
|
||||
}
|
||||
JSPrincipals *subjectPrincipals = wrapper->getCompartment(cx)->principals;
|
||||
JSPrincipals *objectPrincipals = wrappedObject(wrapper)->getCompartment(cx)->principals;
|
||||
if(!subjectPrincipals->subsume(subjectPrincipals, objectPrincipals)) {
|
||||
if(id == JSVAL_VOID) {
|
||||
JS_ReportError(cx, "Permission denied to access object");
|
||||
} else {
|
||||
JSString *str = JS_ValueToString(cx, id);
|
||||
JS_ReportError(cx, "Permission denied to access property '%hs'", str);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
JSStackFrame *fp = nsnull;
|
||||
nsIPrincipal *principal = static_cast<nsJSPrincipals *>(objectPrincipals)->nsIPrincipalPtr;
|
||||
nsresult rv = ssm->PushContextPrincipal(cx, JS_FrameIterator(cx, &fp), principal);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("Not allowing call because we're out of memory");
|
||||
JS_ReportOutOfMemory(cx);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
return AccessCheck::enter(cx, wrapper, wrappedObject(wrapper), id, mode);
|
||||
}
|
||||
|
||||
void
|
||||
ContentWrapper::leave(JSContext *cx, JSObject *proxy)
|
||||
ContentWrapper::leave(JSContext *cx, JSObject *wrapper)
|
||||
{
|
||||
nsIScriptSecurityManager *ssm = XPCWrapper::GetSecurityManager();
|
||||
if (ssm) {
|
||||
ssm->PopContextPrincipal(cx);
|
||||
}
|
||||
return AccessCheck::leave(cx, wrapper, wrappedObject(wrapper));
|
||||
}
|
||||
|
||||
}
|
||||
|
64
js/src/xpconnect/src/wrappers/ContentWrapper.h
Normal file
64
js/src/xpconnect/src/wrappers/ContentWrapper.h
Normal file
@ -0,0 +1,64 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* vim: set ts=4 sw=4 et tw=99 ft=cpp:
|
||||
*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code, released
|
||||
* June 24, 2010.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* The Mozilla Foundation
|
||||
*
|
||||
* Contributor(s):
|
||||
* Andreas Gal <gal@mozilla.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "jsapi.h"
|
||||
#include "jswrapper.h"
|
||||
|
||||
// Content wrappers allow unmitigated access and are only used if the
|
||||
// origin (subject) compartment's principals subsume the target (object)
|
||||
// compartment's principals.
|
||||
//
|
||||
// The main responsibility of the content wrapper is to push and pop the
|
||||
// target (object) compartment's principals when entering and leaving
|
||||
// that compartment.
|
||||
|
||||
namespace xpc {
|
||||
|
||||
class ContentWrapper : public JSCrossCompartmentWrapper {
|
||||
public:
|
||||
ContentWrapper();
|
||||
virtual ~ContentWrapper();
|
||||
|
||||
virtual bool enter(JSContext *cx, JSObject *wrapper, jsid id, Mode mode);
|
||||
virtual void leave(JSContext *cx, JSObject *wrapper);
|
||||
|
||||
static ContentWrapper singleton;
|
||||
};
|
||||
|
||||
}
|
@ -47,7 +47,10 @@ LIBRARY_NAME = xpcwrappers_s
|
||||
FORCE_STATIC_LIB = 1
|
||||
LIBXUL_LIBRARY = 1
|
||||
|
||||
CPPSRCS = ContentWrapper.cpp
|
||||
CPPSRCS = ContentWrapper.cpp \
|
||||
ChromeWrapper.cpp \
|
||||
AccessCheck.cpp \
|
||||
WrapperFactory.cpp
|
||||
|
||||
LOCAL_INCLUDES = \
|
||||
-I$(srcdir)/.. \
|
||||
|
56
js/src/xpconnect/src/wrappers/WrapperFactory.cpp
Normal file
56
js/src/xpconnect/src/wrappers/WrapperFactory.cpp
Normal file
@ -0,0 +1,56 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* vim: set ts=4 sw=4 et tw=99 ft=cpp:
|
||||
*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code, released
|
||||
* June 24, 2010.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* The Mozilla Foundation
|
||||
*
|
||||
* Contributor(s):
|
||||
* Andreas Gal <gal@mozilla.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "WrapperFactory.h"
|
||||
#include "ContentWrapper.h"
|
||||
#include "ChromeWrapper.h"
|
||||
#include "AccessCheck.h"
|
||||
|
||||
namespace xpc {
|
||||
|
||||
JSCrossCompartmentWrapper *
|
||||
WrapperFactory::select(JSContext *cx, JSCompartment *subject, JSCompartment *object)
|
||||
{
|
||||
if(AccessCheck::isPrivileged(object)) {
|
||||
return &ChromeWrapper::singleton;
|
||||
}
|
||||
return &ContentWrapper::singleton;
|
||||
}
|
||||
|
||||
}
|
52
js/src/xpconnect/src/wrappers/WrapperFactory.h
Normal file
52
js/src/xpconnect/src/wrappers/WrapperFactory.h
Normal file
@ -0,0 +1,52 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* vim: set ts=4 sw=4 et tw=99 ft=cpp:
|
||||
*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code, released
|
||||
* June 24, 2010.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* The Mozilla Foundation
|
||||
*
|
||||
* Contributor(s):
|
||||
* Andreas Gal <gal@mozilla.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "jsapi.h"
|
||||
#include "jswrapper.h"
|
||||
|
||||
namespace xpc {
|
||||
|
||||
class WrapperFactory {
|
||||
// Return the wrapper handler to use, or NULL in case of error.
|
||||
static JSCrossCompartmentWrapper *select(JSContext *cx,
|
||||
JSCompartment *subject,
|
||||
JSCompartment *object);
|
||||
};
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user