Bug 1053271 - Remove XPCWN Xrays. r=bz.

--HG--
extra : rebase_source : 4da59c56ffc6eab4af0bf59d3d3861bbc18a33ba
This commit is contained in:
Peter Van der Beken 2018-06-04 12:56:38 +02:00
parent a0cb50c811
commit c02d68395d
4 changed files with 6 additions and 349 deletions

View File

@ -164,7 +164,6 @@ IdentifyCrossOriginObject(JSObject* obj)
{
obj = js::UncheckedUnwrap(obj, /* stopAtWindowProxy = */ false);
const js::Class* clasp = js::GetObjectClass(obj);
MOZ_ASSERT(!XrayUtils::IsXPCWNHolderClass(Jsvalify(clasp)), "shouldn't have a holder here");
if (clasp->name[0] == 'L' && !strcmp(clasp->name, "Location"))
return CrossOriginLocation;

View File

@ -400,9 +400,7 @@ SelectWrapper(bool securityWrapper, XrayType xrayType, bool waiveXrays, JSObject
// Ok, we're using Xray. If this isn't a security wrapper, use the permissive
// version and skip the filter.
if (!securityWrapper) {
if (xrayType == XrayForWrappedNative)
return &PermissiveXrayXPCWN::singleton;
else if (xrayType == XrayForDOMObject)
if (xrayType == XrayForDOMObject)
return &PermissiveXrayDOM::singleton;
else if (xrayType == XrayForJSObject)
return &PermissiveXrayJS::singleton;
@ -435,7 +433,6 @@ WrapperFactory::Rewrap(JSContext* cx, HandleObject existing, HandleObject obj)
GetProxyHandler(obj) == &XrayWaiver ||
js::IsWindowProxy(obj),
"wrapped object passed to rewrap");
MOZ_ASSERT(!XrayUtils::IsXPCWNHolderClass(JS_GetClass(obj)), "trying to wrap a holder");
MOZ_ASSERT(!js::IsWindow(obj));
MOZ_ASSERT(dom::IsJSAPIActive());

View File

@ -104,9 +104,7 @@ GetXrayType(JSObject* obj)
if (mozilla::dom::UseDOMXray(obj))
return XrayForDOMObject;
const js::Class* clasp = js::GetObjectClass(obj);
if (IS_WN_CLASS(clasp) || js::IsWindowProxy(obj))
return XrayForWrappedNative;
MOZ_ASSERT(!js::IsWindowProxy(obj));
JSProtoKey standardProto = IdentifyStandardInstanceOrPrototype(obj);
if (IsJSXraySupported(standardProto))
@ -198,17 +196,6 @@ XrayTraits::setExpandoChain(JSContext* cx, HandleObject obj, HandleObject chain)
return ObjectScope(obj)->SetExpandoChain(cx, obj, chain);
}
// static
XPCWrappedNative*
XPCWrappedNativeXrayTraits::getWN(JSObject* wrapper)
{
return XPCWrappedNative::Get(getTargetObject(wrapper));
}
const JSClass XPCWrappedNativeXrayTraits::HolderClass = {
"NativePropertyHolder", JSCLASS_HAS_RESERVED_SLOTS(HOLDER_SHARED_SLOT_COUNT)
};
const JSClass XrayTraits::HolderClass = {
"XrayHolder", JSCLASS_HAS_RESERVED_SLOTS(HOLDER_SHARED_SLOT_COUNT)
};
@ -1029,7 +1016,6 @@ JSXrayTraits::createHolder(JSContext* cx, JSObject* wrapper)
return holder;
}
XPCWrappedNativeXrayTraits XPCWrappedNativeXrayTraits::singleton;
DOMXrayTraits DOMXrayTraits::singleton;
JSXrayTraits JSXrayTraits::singleton;
OpaqueXrayTraits OpaqueXrayTraits::singleton;
@ -1040,8 +1026,6 @@ GetXrayTraits(JSObject* obj)
switch (GetXrayType(obj)) {
case XrayForDOMObject:
return &DOMXrayTraits::singleton;
case XrayForWrappedNative:
return &XPCWrappedNativeXrayTraits::singleton;
case XrayForJSObject:
return &JSXrayTraits::singleton;
case XrayForOpaqueObject:
@ -1423,16 +1407,6 @@ SetCachedXrayExpando(JSObject* holder, JSObject* expandoWrapper)
JS_SetReservedSlot(holder, XrayTraits::HOLDER_SLOT_EXPANDO, ObjectValue(*expandoWrapper));
}
namespace XrayUtils {
bool
IsXPCWNHolderClass(const JSClass* clasp)
{
return clasp == &XPCWrappedNativeXrayTraits::HolderClass;
}
} // namespace XrayUtils
static nsGlobalWindowInner*
AsWindow(JSContext* cx, JSObject* wrapper)
{
@ -1448,106 +1422,6 @@ IsWindow(JSContext* cx, JSObject* wrapper)
return !!AsWindow(cx, wrapper);
}
void
XPCWrappedNativeXrayTraits::preserveWrapper(JSObject* target)
{
}
static bool
XrayToString(JSContext* cx, unsigned argc, JS::Value* vp);
bool
XPCWrappedNativeXrayTraits::resolveNativeProperty(JSContext* cx, HandleObject wrapper,
HandleObject holder, HandleId id,
MutableHandle<PropertyDescriptor> desc)
{
MOZ_ASSERT(js::GetObjectJSClass(holder) == &HolderClass);
desc.object().set(nullptr);
// This will do verification and the method lookup for us.
RootedObject target(cx, getTargetObject(wrapper));
XPCCallContext ccx(cx, target, nullptr, id);
// There are no native numeric (or symbol-keyed) properties, so we can
// shortcut here. We will not find the property.
if (!JSID_IS_STRING(id))
return true;
XPCNativeInterface* iface;
XPCNativeMember* member;
XPCWrappedNative* wn = getWN(wrapper);
if (ccx.GetWrapper() != wn || !wn->IsValid()) {
return true;
}
if (!(iface = ccx.GetInterface()) || !(member = ccx.GetMember())) {
if (id != XPCJSRuntime::Get()->GetStringID(XPCJSContext::IDX_TO_STRING))
return true;
JSFunction* toString = JS_NewFunction(cx, XrayToString, 0, 0, "toString");
if (!toString)
return false;
FillPropertyDescriptor(desc, wrapper, 0,
ObjectValue(*JS_GetFunctionObject(toString)));
return JS_DefinePropertyById(cx, holder, id, desc) &&
JS_GetOwnPropertyDescriptorById(cx, holder, id, desc);
}
desc.object().set(holder);
desc.setAttributes(JSPROP_ENUMERATE);
desc.setGetter(nullptr);
desc.setSetter(nullptr);
desc.value().setUndefined();
RootedValue fval(cx, JS::UndefinedValue());
if (member->IsConstant()) {
if (!member->GetConstantValue(ccx, iface, desc.value().address())) {
JS_ReportErrorASCII(cx, "Failed to convert constant native property to JS value");
return false;
}
} else if (member->IsAttribute()) {
// This is a getter/setter. Clone a function for it.
if (!member->NewFunctionObject(ccx, iface, wrapper, fval.address())) {
JS_ReportErrorASCII(cx, "Failed to clone function object for native getter/setter");
return false;
}
unsigned attrs = desc.attributes();
attrs |= JSPROP_GETTER;
if (member->IsWritableAttribute())
attrs |= JSPROP_SETTER;
desc.setAttributes(attrs);
} else {
// This is a method. Clone a function for it.
if (!member->NewFunctionObject(ccx, iface, wrapper, desc.value().address())) {
JS_ReportErrorASCII(cx, "Failed to clone function object for native function");
return false;
}
// Without a wrapper the function would live on the prototype. Since we
// don't have one, we have to avoid calling the scriptable helper's
// GetProperty method for this property, so null out the getter and
// setter here explicitly.
desc.setGetter(nullptr);
desc.setSetter(nullptr);
}
if (!JS_WrapValue(cx, desc.value()) || !JS_WrapValue(cx, &fval))
return false;
if (desc.hasGetterObject())
desc.setGetterObject(&fval.toObject());
if (desc.hasSetterObject())
desc.setSetterObject(&fval.toObject());
return JS_DefinePropertyById(cx, holder, id, desc);
}
static bool
wrappedJSObject_getter(JSContext* cx, unsigned argc, Value* vp)
{
@ -1638,112 +1512,6 @@ XrayTraits::resolveOwnProperty(JSContext* cx, HandleObject wrapper, HandleObject
return true;
}
bool
XPCWrappedNativeXrayTraits::resolveOwnProperty(JSContext* cx, HandleObject wrapper,
HandleObject target, HandleObject holder,
HandleId id,
MutableHandle<PropertyDescriptor> desc)
{
// Call the common code.
bool ok = XrayTraits::resolveOwnProperty(cx, wrapper, target, holder,
id, desc);
if (!ok || desc.object())
return ok;
// Xray wrappers don't use the regular wrapper hierarchy, so we should be
// in the wrapper's compartment here, not the wrappee.
MOZ_ASSERT(js::IsObjectInContextCompartment(wrapper, cx));
return JS_GetOwnPropertyDescriptorById(cx, holder, id, desc);
}
bool
XPCWrappedNativeXrayTraits::enumerateNames(JSContext* cx, HandleObject wrapper, unsigned flags,
AutoIdVector& props)
{
// Force all native properties to be materialized onto the wrapped native.
AutoIdVector wnProps(cx);
{
RootedObject target(cx, getTargetObject(wrapper));
JSAutoRealm ar(cx, target);
if (!js::GetPropertyKeys(cx, target, flags, &wnProps))
return false;
}
// Go through the properties we found on the underlying object and see if
// they appear on the XrayWrapper. If it throws (which may happen if the
// wrapper is a SecurityWrapper), just clear the exception and move on.
MOZ_ASSERT(!JS_IsExceptionPending(cx));
if (!props.reserve(wnProps.length()))
return false;
for (size_t n = 0; n < wnProps.length(); ++n) {
RootedId id(cx, wnProps[n]);
JS_MarkCrossZoneId(cx, id);
bool hasProp;
if (JS_HasPropertyById(cx, wrapper, id, &hasProp) && hasProp)
props.infallibleAppend(id);
JS_ClearPendingException(cx);
}
return true;
}
JSObject*
XPCWrappedNativeXrayTraits::createHolder(JSContext* cx, JSObject* wrapper)
{
return JS_NewObjectWithGivenProto(cx, &HolderClass, nullptr);
}
bool
XPCWrappedNativeXrayTraits::call(JSContext* cx, HandleObject wrapper,
const JS::CallArgs& args,
const js::Wrapper& baseInstance)
{
// Run the call hook of the wrapped native.
XPCWrappedNative* wn = getWN(wrapper);
if (wn->GetScriptable() && wn->GetScriptable()->WantCall()) {
XPCCallContext ccx(cx, wrapper, nullptr, JSID_VOIDHANDLE, args.length(),
args.array(), args.rval().address());
if (!ccx.IsValid())
return false;
bool ok = true;
nsresult rv = wn->GetScriptable()->Call(wn, cx, wrapper, args, &ok);
if (NS_FAILED(rv)) {
if (ok)
XPCThrower::Throw(rv, cx);
return false;
}
}
return true;
}
bool
XPCWrappedNativeXrayTraits::construct(JSContext* cx, HandleObject wrapper,
const JS::CallArgs& args,
const js::Wrapper& baseInstance)
{
// Run the construct hook of the wrapped native.
XPCWrappedNative* wn = getWN(wrapper);
if (wn->GetScriptable() && wn->GetScriptable()->WantConstruct()) {
XPCCallContext ccx(cx, wrapper, nullptr, JSID_VOIDHANDLE, args.length(),
args.array(), args.rval().address());
if (!ccx.IsValid())
return false;
bool ok = true;
nsresult rv =
wn->GetScriptable()->Construct(wn, cx, wrapper, args, &ok);
if (NS_FAILED(rv)) {
if (ok)
XPCThrower::Throw(rv, cx);
return false;
}
}
return true;
}
bool
DOMXrayTraits::resolveOwnProperty(JSContext* cx, HandleObject wrapper, HandleObject target,
HandleObject holder, HandleId id,
@ -1988,58 +1756,6 @@ HasNativeProperty(JSContext* cx, HandleObject wrapper, HandleId id, bool* hasPro
} // namespace XrayUtils
static bool
XrayToString(JSContext* cx, unsigned argc, Value* vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
if (!args.thisv().isObject()) {
JS_ReportErrorASCII(cx, "XrayToString called on an incompatible object");
return false;
}
RootedObject wrapper(cx, &args.thisv().toObject());
if (!wrapper)
return false;
if (IsWrapper(wrapper) &&
GetProxyHandler(wrapper) == &sandboxCallableProxyHandler) {
wrapper = xpc::SandboxCallableProxyHandler::wrappedObject(wrapper);
}
if (!IsWrapper(wrapper) || !WrapperFactory::IsXrayWrapper(wrapper)) {
JS_ReportErrorASCII(cx, "XrayToString called on an incompatible object");
return false;
}
RootedObject obj(cx, XrayTraits::getTargetObject(wrapper));
if (GetXrayType(obj) != XrayForWrappedNative) {
JS_ReportErrorASCII(cx, "XrayToString called on an incompatible object");
return false;
}
static const char start[] = "[object XrayWrapper ";
static const char end[] = "]";
nsAutoString result;
result.AppendASCII(start);
XPCCallContext ccx(cx, obj);
XPCWrappedNative* wn = XPCWrappedNativeXrayTraits::getWN(wrapper);
char* wrapperStr = wn->ToString();
if (!wrapperStr) {
JS_ReportOutOfMemory(cx);
return false;
}
result.AppendASCII(wrapperStr);
js_free(wrapperStr);
result.AppendASCII(end);
JSString* str = JS_NewUCStringCopyN(cx, result.get(), result.Length());
if (!str)
return false;
args.rval().setString(str);
return true;
}
template <typename Base, typename Traits>
bool
@ -2091,12 +1807,9 @@ XrayWrapper<Base, Traits>::getPropertyDescriptor(JSContext* cx, HandleObject wra
// which are |own| value props.
//
// resolveOwnProperty may or may not cache what it finds on the holder,
// depending on how ephemeral it decides the property is. XPCWN |own|
// properties generally end up on the holder via Resolve, whereas
// NodeList |own| properties don't get defined on the holder, since they're
// supposed to be dynamic. This means that we have to first check the result
// of resolveOwnProperty, and _then_, if that comes up blank, check the
// holder for any cached native properties.
// depending on how ephemeral it decides the property is. This means that we have to
// first check the result of resolveOwnProperty, and _then_, if that comes up blank,
// check the holder for any cached native properties.
//
// Finally, we call resolveNativeProperty, which checks non-own properties,
// and unconditionally caches what it finds on the holder.
@ -2612,8 +2325,6 @@ template<typename Base, typename Traits>
const xpc::XrayWrapper<Base, Traits>
xpc::XrayWrapper<Base, Traits>::singleton(0);
template class PermissiveXrayXPCWN;
template class SecurityXrayXPCWN;
template class PermissiveXrayDOM;
template class SecurityXrayDOM;
template class PermissiveXrayJS;

View File

@ -29,15 +29,11 @@
// little world around them.
class nsIPrincipal;
class XPCWrappedNative;
namespace xpc {
namespace XrayUtils {
bool
IsXPCWNHolderClass(const JSClass* clasp);
bool
IsTransparent(JSContext* cx, JS::HandleObject wrapper, JS::HandleId id);
@ -51,7 +47,6 @@ HasNativeProperty(JSContext* cx, JS::HandleObject wrapper, JS::HandleId id,
enum XrayType {
XrayForDOMObject,
XrayForWrappedNative,
XrayForJSObject,
XrayForOpaqueObject,
NotXray
@ -146,46 +141,6 @@ private:
const XrayTraits& operator=(XrayTraits&) = delete;
};
class XPCWrappedNativeXrayTraits : public XrayTraits
{
public:
enum {
HasPrototype = 0
};
static const XrayType Type = XrayForWrappedNative;
virtual bool resolveNativeProperty(JSContext* cx, JS::HandleObject wrapper,
JS::HandleObject holder, JS::HandleId id,
JS::MutableHandle<JS::PropertyDescriptor> desc) override;
virtual bool resolveOwnProperty(JSContext* cx, JS::HandleObject wrapper, JS::HandleObject target,
JS::HandleObject holder, JS::HandleId id,
JS::MutableHandle<JS::PropertyDescriptor> desc) override;
bool defineProperty(JSContext* cx, JS::HandleObject wrapper, JS::HandleId id,
JS::Handle<JS::PropertyDescriptor> desc,
JS::Handle<JS::PropertyDescriptor> existingDesc,
JS::ObjectOpResult& result, bool* defined)
{
*defined = false;
return true;
}
virtual bool enumerateNames(JSContext* cx, JS::HandleObject wrapper, unsigned flags,
JS::AutoIdVector& props);
static bool call(JSContext* cx, JS::HandleObject wrapper,
const JS::CallArgs& args, const js::Wrapper& baseInstance);
static bool construct(JSContext* cx, JS::HandleObject wrapper,
const JS::CallArgs& args, const js::Wrapper& baseInstance);
static XPCWrappedNative* getWN(JSObject* wrapper);
virtual void preserveWrapper(JSObject* target) override;
virtual JSObject* createHolder(JSContext* cx, JSObject* wrapper) override;
static const JSClass HolderClass;
static XPCWrappedNativeXrayTraits singleton;
};
class DOMXrayTraits : public XrayTraits
{
public:
@ -450,7 +405,7 @@ XrayType GetXrayType(JSObject* obj);
XrayTraits* GetXrayTraits(JSObject* obj);
// NB: Base *must* derive from JSProxyHandler
template <typename Base, typename Traits = XPCWrappedNativeXrayTraits >
template <typename Base, typename Traits>
class XrayWrapper : public Base {
public:
constexpr explicit XrayWrapper(unsigned flags)
@ -531,20 +486,15 @@ class XrayWrapper : public Base {
JS::AutoIdVector& props) const;
};
#define PermissiveXrayXPCWN xpc::XrayWrapper<js::CrossCompartmentWrapper, xpc::XPCWrappedNativeXrayTraits>
#define SecurityXrayXPCWN xpc::XrayWrapper<js::CrossCompartmentSecurityWrapper, xpc::XPCWrappedNativeXrayTraits>
#define PermissiveXrayDOM xpc::XrayWrapper<js::CrossCompartmentWrapper, xpc::DOMXrayTraits>
#define SecurityXrayDOM xpc::XrayWrapper<js::CrossCompartmentSecurityWrapper, xpc::DOMXrayTraits>
#define PermissiveXrayJS xpc::XrayWrapper<js::CrossCompartmentWrapper, xpc::JSXrayTraits>
#define PermissiveXrayOpaque xpc::XrayWrapper<js::CrossCompartmentWrapper, xpc::OpaqueXrayTraits>
extern template class PermissiveXrayXPCWN;
extern template class SecurityXrayXPCWN;
extern template class PermissiveXrayDOM;
extern template class SecurityXrayDOM;
extern template class PermissiveXrayJS;
extern template class PermissiveXrayOpaque;
extern template class PermissiveXrayXPCWN;
class SandboxProxyHandler : public js::Wrapper {
public: