Ejemplo n.º 1
0
bool
InterposeProperty(JSContext* cx, HandleObject target, const nsIID* iid, HandleId id,
                  MutableHandle<JSPropertyDescriptor> descriptor)
{
    // We only want to do interpostion on DOM instances and
    // wrapped natives.
    RootedObject unwrapped(cx, UncheckedUnwrap(target));
    const js::Class* clasp = js::GetObjectClass(unwrapped);
    if (!mozilla::dom::IsDOMClass(clasp) &&
        !IS_WN_CLASS(clasp) &&
        !IS_PROTO_CLASS(clasp) &&
        clasp != &OuterWindowProxyClass) {
        return true;
    }

    XPCWrappedNativeScope* scope = ObjectScope(CurrentGlobalOrNull(cx));
    MOZ_ASSERT(scope->HasInterposition());

    nsCOMPtr<nsIAddonInterposition> interp = scope->GetInterposition();
    JSAddonId* addonId = AddonIdOfObject(target);
    RootedValue addonIdValue(cx, StringValue(StringOfAddonId(addonId)));
    RootedValue prop(cx, IdToValue(id));
    RootedValue targetValue(cx, ObjectValue(*target));
    RootedValue descriptorVal(cx);
    nsresult rv = interp->InterposeProperty(addonIdValue, targetValue,
                                            iid, prop, &descriptorVal);
    if (NS_FAILED(rv)) {
        xpc::Throw(cx, rv);
        return false;
    }

    if (!descriptorVal.isObject())
        return true;

    // We need to be careful parsing descriptorVal. |cx| is in the compartment
    // of the add-on and the descriptor is in the compartment of the
    // interposition. We could wrap the descriptor in the add-on's compartment
    // and then parse it. However, parsing the descriptor fetches properties
    // from it, and we would try to interpose on those property accesses. So
    // instead we parse in the interposition's compartment and then wrap the
    // descriptor.

    {
        JSAutoCompartment ac(cx, &descriptorVal.toObject());
        if (!JS::ObjectToCompletePropertyDescriptor(cx, target, descriptorVal, descriptor))
            return false;
    }

    // Always make the property non-configurable regardless of what the
    // interposition wants.
    descriptor.setAttributes(descriptor.attributes() | JSPROP_PERMANENT);

    if (!JS_WrapPropertyDescriptor(cx, descriptor))
        return false;

    return true;
}
Ejemplo n.º 2
0
bool
InterposeCall(JSContext* cx, JS::HandleObject target, const JS::CallArgs& args, bool* done)
{
    *done = false;
    XPCWrappedNativeScope* scope = ObjectScope(CurrentGlobalOrNull(cx));
    MOZ_ASSERT(scope->HasInterposition());

    nsCOMPtr<nsIAddonInterposition> interp = scope->GetInterposition();

    RootedObject unwrappedTarget(cx, UncheckedUnwrap(target));
    XPCWrappedNativeScope* targetScope = ObjectScope(unwrappedTarget);
    bool hasInterpostion = targetScope->HasCallInterposition();

    if (!hasInterpostion)
        return true;

    // If there is a call interpostion, we don't want to propogate the
    // call to Base:
    *done = true; 

    JSAddonId* addonId = AddonIdOfObject(target);
    RootedValue addonIdValue(cx, StringValue(StringOfAddonId(addonId)));
    RootedValue targetValue(cx, ObjectValue(*target));
    RootedValue thisValue(cx, args.thisv());
    RootedObject argsArray(cx, ConvertArgsToArray(cx, args));
    if (!argsArray)
        return false;

    RootedValue argsVal(cx, ObjectValue(*argsArray));
    RootedValue returnVal(cx);

    nsresult rv = interp->InterposeCall(addonIdValue, targetValue,
                                        thisValue, argsVal, args.rval());
    if (NS_FAILED(rv)) {
        xpc::Throw(cx, rv);
        return false;
    }

    return true;
}