Exemplo n.º 1
0
/**
 * Get the interface name and member name (for error messages).
 *
 * We could instead have each quick stub pass its name to the error-handling
 * functions, as that name is statically known.  But that would be redundant;
 * the information is handy at runtime anyway.  Also, this code often produces
 * a more specific error message, e.g. "[nsIDOMHTMLDocument.appendChild]"
 * rather than "[nsIDOMNode.appendChild]".
 */
static void
GetMemberInfo(JSObject *obj, jsid memberId, const char **ifaceName)
{
    *ifaceName = "Unknown";

    // Don't try to generate a useful name if there are security wrappers,
    // because it isn't worth the risk of something going wrong just to generate
    // an error message. Instead, only handle the simple case where we have the
    // reflector in hand.
    if (IS_WRAPPER_CLASS(js::GetObjectClass(obj))) {
        XPCWrappedNativeProto *proto;
        if (IS_SLIM_WRAPPER_OBJECT(obj)) {
            proto = GetSlimWrapperProto(obj);
        } else {
            MOZ_ASSERT(IS_WN_WRAPPER_OBJECT(obj));
            XPCWrappedNative *wrapper =
                static_cast<XPCWrappedNative *>(js::GetObjectPrivate(obj));
            proto = wrapper->GetProto();
        }
        if (proto) {
            XPCNativeSet *set = proto->GetSet();
            if (set) {
                XPCNativeMember *member;
                XPCNativeInterface *iface;

                if (set->FindMember(memberId, &member, &iface))
                    *ifaceName = iface->GetNameString();
            }
        }
    }
}
Exemplo n.º 2
0
/**
 * Get the interface name and member name (for error messages).
 *
 * We could instead have each quick stub pass its name to the error-handling
 * functions, as that name is statically known.  But that would be redundant;
 * the information is handy at runtime anyway.  Also, this code often produces
 * a more specific error message, e.g. "[nsIDOMHTMLDocument.appendChild]"
 * rather than "[nsIDOMNode.appendChild]".
 */
static void
GetMemberInfo(JSObject *obj,
              jsval memberId,
              const char **ifaceName,
              const char **memberName)
{
    // Get the interface name.  From DefinePropertyIfFound (in
    // xpcwrappednativejsops.cpp) and XPCThrower::Verbosify.
    //
    // We could instead make the quick stub could pass in its interface name,
    // but this code often produces a more specific error message, e.g.
    *ifaceName = "Unknown";

    NS_ASSERTION(IS_WRAPPER_CLASS(STOBJ_GET_CLASS(obj)) ||
                 STOBJ_GET_CLASS(obj) == &XPC_WN_Tearoff_JSClass ||
                 IS_SLIM_WRAPPER(obj),
                 "obj must be a wrapper");
    XPCWrappedNativeProto *proto;
    if(IS_SLIM_WRAPPER(obj))
    {
        proto = GetSlimWrapperProto(obj);
    }
    else
    {
        XPCWrappedNative *wrapper = (XPCWrappedNative *) obj->getPrivate();
        proto = wrapper->GetProto();
    }
    if(proto)
    {
        XPCNativeSet *set = proto->GetSet();
        if(set)
        {
            XPCNativeMember *member;
            XPCNativeInterface *iface;

            if(set->FindMember(memberId, &member, &iface))
                *ifaceName = iface->GetNameString();
        }
    }

    *memberName = (JSVAL_IS_STRING(memberId)
                   ? JS_GetStringBytes(JSVAL_TO_STRING(memberId))
                   : "unknown");
}
Exemplo n.º 3
0
/**
 * Get the interface name and member name (for error messages).
 *
 * We could instead have each quick stub pass its name to the error-handling
 * functions, as that name is statically known.  But that would be redundant;
 * the information is handy at runtime anyway.  Also, this code often produces
 * a more specific error message, e.g. "[nsIDOMHTMLDocument.appendChild]"
 * rather than "[nsIDOMNode.appendChild]".
 */
static void
GetMemberInfo(JSObject *obj, jsid memberId, const char **ifaceName)
{
    *ifaceName = "Unknown";

    // Don't try to generate a useful name if there are security wrappers,
    // because it isn't worth the risk of something going wrong just to generate
    // an error message. Instead, only handle the simple case where we have the
    // reflector in hand.
    if (IS_WN_REFLECTOR(obj)) {
        XPCWrappedNative *wrapper = XPCWrappedNative::Get(obj);
        XPCWrappedNativeProto *proto = wrapper->GetProto();
        if (proto) {
            XPCNativeSet *set = proto->GetSet();
            if (set) {
                XPCNativeMember *member;
                XPCNativeInterface *iface;

                if (set->FindMember(memberId, &member, &iface))
                    *ifaceName = iface->GetNameString();
            }
        }
    }
}
bool
XPC_WN_Shared_Enumerate(JSContext* cx, HandleObject obj)
{
    XPCCallContext ccx(cx, obj);
    XPCWrappedNative* wrapper = ccx.GetWrapper();
    THROW_AND_RETURN_IF_BAD_WRAPPER(cx, wrapper);

    // Since we aren't going to enumerate tearoff names and the prototype
    // handles non-mutated members, we can do this potential short-circuit.
    if (!wrapper->HasMutatedSet())
        return true;

    XPCNativeSet* set = wrapper->GetSet();
    XPCNativeSet* protoSet = wrapper->HasProto() ?
                                wrapper->GetProto()->GetSet() : nullptr;

    uint16_t interface_count = set->GetInterfaceCount();
    XPCNativeInterface** interfaceArray = set->GetInterfaceArray();
    for (uint16_t i = 0; i < interface_count; i++) {
        XPCNativeInterface* iface = interfaceArray[i];
        uint16_t member_count = iface->GetMemberCount();
        for (uint16_t k = 0; k < member_count; k++) {
            XPCNativeMember* member = iface->GetMemberAt(k);
            jsid name = member->GetName();

            // Skip if this member is going to come from the proto.
            uint16_t index;
            if (protoSet &&
                protoSet->FindMember(name, nullptr, &index) && index == i)
                continue;
            if (!xpc_ForcePropertyResolve(cx, obj, name))
                return false;
        }
    }
    return true;
}
bool
XPC_WN_Helper_Resolve(JSContext* cx, HandleObject obj, HandleId id, bool* resolvedp)
{
    nsresult rv = NS_OK;
    bool retval = true;
    bool resolved = false;
    XPCCallContext ccx(cx, obj);
    XPCWrappedNative* wrapper = ccx.GetWrapper();
    THROW_AND_RETURN_IF_BAD_WRAPPER(cx, wrapper);

    RootedId old(cx, ccx.SetResolveName(id));

    XPCNativeScriptableInfo* si = wrapper->GetScriptableInfo();
    if (si && si->GetFlags().WantResolve()) {
        XPCWrappedNative* oldResolvingWrapper;
        bool allowPropMods = si->GetFlags().AllowPropModsDuringResolve();

        if (allowPropMods)
            oldResolvingWrapper = ccx.SetResolvingWrapper(wrapper);

        rv = si->GetCallback()->Resolve(wrapper, cx, obj, id, &resolved, &retval);

        if (allowPropMods)
            (void)ccx.SetResolvingWrapper(oldResolvingWrapper);
    }

    old = ccx.SetResolveName(old);
    MOZ_ASSERT(old == id, "bad nest");

    if (NS_FAILED(rv)) {
        return Throw(rv, cx);
    }

    if (resolved) {
        *resolvedp = true;
    } else if (wrapper->HasMutatedSet()) {
        // We are here if scriptable did not resolve this property and
        // it *might* be in the instance set but not the proto set.

        XPCNativeSet* set = wrapper->GetSet();
        XPCNativeSet* protoSet = wrapper->HasProto() ?
                                    wrapper->GetProto()->GetSet() : nullptr;
        XPCNativeMember* member = nullptr;
        RefPtr<XPCNativeInterface> iface;
        bool IsLocal = false;

        if (set->FindMember(id, &member, &iface, protoSet, &IsLocal) &&
            IsLocal) {
            XPCWrappedNative* oldResolvingWrapper;

            XPCNativeScriptableFlags siFlags(0);
            if (si)
                siFlags = si->GetFlags();

            XPCWrappedNative* wrapperForInterfaceNames =
                siFlags.DontReflectInterfaceNames() ? nullptr : wrapper;

            oldResolvingWrapper = ccx.SetResolvingWrapper(wrapper);
            retval = DefinePropertyIfFound(ccx, obj, id,
                                           set, iface, member,
                                           wrapper->GetScope(),
                                           false,
                                           wrapperForInterfaceNames,
                                           nullptr, si,
                                           JSPROP_ENUMERATE, resolvedp);
            (void)ccx.SetResolvingWrapper(oldResolvingWrapper);
        }
    }

    return retval;
}