Beispiel #1
0
JSBool
xpc_qsUnwrapThisFromCcxImpl(XPCCallContext &ccx,
                            const nsIID &iid,
                            void **ppThis,
                            nsISupports **pThisRef,
                            jsval *vp)
{
    nsISupports *native = ccx.GetIdentityObject();
    if(!native)
        return xpc_qsThrow(ccx.GetJSContext(), NS_ERROR_XPC_HAS_BEEN_SHUTDOWN);

    nsresult rv = getNative(native, GetOffsets(native, ccx.GetProto()),
                            ccx.GetFlattenedJSObject(), iid, ppThis, pThisRef,
                            vp);
    if(NS_FAILED(rv))
        return xpc_qsThrow(ccx.GetJSContext(), rv);
    return JS_TRUE;
}
Beispiel #2
0
JSBool
xpc_qsUnwrapThisImpl(JSContext *cx,
                     JSObject *obj,
                     JSObject *callee,
                     const nsIID &iid,
                     void **ppThis,
                     nsISupports **pThisRef,
                     jsval *vp,
                     XPCLazyCallContext *lccx)
{
    JSObject *cur = obj;
    XPCWrappedNativeTearOff *tearoff;
    XPCWrappedNative *wrapper =
        XPCWrappedNative::GetWrappedNativeOfJSObject(cx, obj, callee, &cur,
                                                     &tearoff);
    if(wrapper)
    {
        nsresult rv = getNativeFromWrapper(wrapper, iid, ppThis, pThisRef, vp);
        if(NS_SUCCEEDED(rv))
        {
            if(lccx)
                lccx->SetWrapper(cur, wrapper, tearoff);
            
            return JS_TRUE;
        }
        if(rv != NS_ERROR_NO_INTERFACE)
            return xpc_qsThrow(cx, rv);
    }
    else if(cur)
    {
        nsISupports *native = static_cast<nsISupports*>(xpc_GetJSPrivate(cur));
        if(NS_SUCCEEDED(getNative(native, GetOffsetsFromSlimWrapper(cur),
                                  cur, iid, ppThis, pThisRef, vp)))
        {
            if(lccx)
                lccx->SetWrapper(cur, nsnull, nsnull);

            return JS_TRUE;
        }
    }

    *pThisRef = nsnull;
    return xpc_qsThrow(cx, NS_ERROR_XPC_BAD_OP_ON_WN_PROTO);
}
Beispiel #3
0
JSBool
xpc_qsXPCOMObjectToJsval(XPCLazyCallContext &lccx, nsISupports *p,
                         nsWrapperCache *cache, const nsIID *iid,
                         XPCNativeInterface **iface, jsval *rval)
{
    // From the T_INTERFACE case in XPCConvert::NativeData2JS.
    // This is one of the slowest things quick stubs do.

    JSContext *cx = lccx.GetJSContext();
    if(!iface)
        return xpc_qsThrow(cx, NS_ERROR_XPC_BAD_CONVERT_NATIVE);

    // XXX The OBJ_IS_NOT_GLOBAL here is not really right. In
    // fact, this code is depending on the fact that the
    // global object will not have been collected, and
    // therefore this NativeInterface2JSObject will not end up
    // creating a new XPCNativeScriptableShared.

    nsresult rv;
    if(!XPCConvert::NativeInterface2JSObject(lccx, rval, nsnull, p,
                                             iid, iface, cache,
                                             lccx.GetCurrentJSObject(), PR_TRUE,
                                             OBJ_IS_NOT_GLOBAL, &rv))
    {
        // I can't tell if NativeInterface2JSObject throws JS exceptions
        // or not.  This is a sloppy stab at the right semantics; the
        // method really ought to be fixed to behave consistently.
        if(!JS_IsExceptionPending(cx))
            xpc_qsThrow(cx, NS_FAILED(rv) ? rv : NS_ERROR_UNEXPECTED);
        return JS_FALSE;
    }

#ifdef DEBUG
    JSObject* jsobj = JSVAL_TO_OBJECT(*rval);
    if(jsobj && !STOBJ_GET_PARENT(jsobj))
        NS_ASSERTION(STOBJ_GET_CLASS(jsobj)->flags & JSCLASS_IS_GLOBAL,
                     "Why did we recreate this wrapper?");
#endif

    return JS_TRUE;
}
Beispiel #4
0
JSBool
xpc_qsVariantToJsval(XPCLazyCallContext &lccx,
                     nsIVariant *p,
                     jsval *rval)
{
    // From the T_INTERFACE case in XPCConvert::NativeData2JS.
    // Error handling is in XPCWrappedNative::CallMethod.
    if(p)
    {
        nsresult rv;
        JSBool ok = XPCVariant::VariantDataToJS(lccx, p,
                                                lccx.GetCurrentJSObject(),
                                                &rv, rval);
        if (!ok)
            xpc_qsThrow(lccx.GetJSContext(), rv);
        return ok;
    }
    *rval = JSVAL_NULL;
    return JS_TRUE;
}
static JSBool
CVE_2012_0478_firefox4_0_1_nsIDOMWebGLRenderingContext_TexImage2D(JSContext *cx, uintN argc, jsval *vp)
{
    XPC_QS_ASSERT_CONTEXT_OK(cx);
    JSObject *obj = JS_THIS_OBJECT(cx, vp);
    if (!obj)
        return JS_FALSE;

    nsresult rv;

    nsIDOMWebGLRenderingContext *self;
    xpc_qsSelfRef selfref;
    js::AutoValueRooter tvr(cx);
    if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, tvr.jsval_addr(), nsnull))
        return JS_FALSE;

    if (argc < 6 || argc == 7 || argc == 8)
        return xpc_qsThrow(cx, NS_ERROR_XPC_NOT_ENOUGH_ARGS);

    jsval *argv = JS_ARGV(cx, vp);

    // arguments common to all cases
    GET_UINT32_ARG(argv0, 0);
    GET_INT32_ARG(argv1, 1);

    if (argc > 5 &&
        !JSVAL_IS_PRIMITIVE(argv[5]))
    {
        // implement the variants taking a DOMElement as argv[5]
        GET_UINT32_ARG(argv2, 2);
        GET_UINT32_ARG(argv3, 3);
        GET_UINT32_ARG(argv4, 4);

        nsIDOMElement *elt;
        xpc_qsSelfRef eltRef;
        rv = xpc_qsUnwrapArg<nsIDOMElement>(cx, argv[5], &elt, &eltRef.ptr, &argv[5]);
        if (NS_FAILED(rv)) return JS_FALSE;

        rv = self->TexImage2D_dom(argv0, argv1, argv2, argv3, argv4, elt);

        if (NS_FAILED(rv)) {
            // failed to interprete argv[5] as a DOMElement, now try to interprete it as ImageData
            JSObject *argv5 = JSVAL_TO_OBJECT(argv[5]);

            jsval js_width, js_height, js_data;
            JS_GetProperty(cx, argv5, "width", &js_width);
            JS_GetProperty(cx, argv5, "height", &js_height);
            JS_GetProperty(cx, argv5, "data", &js_data);
            if (js_width  == JSVAL_VOID ||
                js_height == JSVAL_VOID ||
                js_data   == JSVAL_VOID)
            {
                xpc_qsThrowBadArg(cx, NS_ERROR_FAILURE, vp, 5);
                return JS_FALSE;
            }
            int32 int_width, int_height;
            JSObject *obj_data = JSVAL_TO_OBJECT(js_data);
            if (!JS_ValueToECMAInt32(cx, js_width, &int_width) ||
                !JS_ValueToECMAInt32(cx, js_height, &int_height))
            {
                return JS_FALSE;
            }
            if (!js_IsTypedArray(obj_data))
            {
                xpc_qsThrowBadArg(cx, NS_ERROR_FAILURE, vp, 5);
                return JS_FALSE;
            }
            rv = self->TexImage2D_imageData(argv0, argv1, argv2,
                                            int_width, int_height, 0,
                                            argv3, argv4, js::TypedArray::fromJSObject(obj_data));
        }
    } else if (argc > 8 &&
               JSVAL_IS_OBJECT(argv[8])) // here, we allow null !
    {
        // implement the variants taking a buffer/array as argv[8]
        GET_UINT32_ARG(argv2, 2);
        GET_INT32_ARG(argv3, 3);
        GET_INT32_ARG(argv4, 4);
        GET_INT32_ARG(argv5, 5);
        GET_UINT32_ARG(argv6, 6);
        GET_UINT32_ARG(argv7, 7);

        JSObject *argv8 = JSVAL_TO_OBJECT(argv[8]);

        // then try to grab either a js::ArrayBuffer, js::TypedArray, or null
        if (argv8 == nsnull) {
            rv = self->TexImage2D_buf(argv0, argv1, argv2, argv3,
                                      argv4, argv5, argv6, argv7,
                                      nsnull);
        } else if (js_IsArrayBuffer(argv8)) {
            rv = self->TexImage2D_buf(argv0, argv1, argv2, argv3,
                                      argv4, argv5, argv6, argv7,
                                      js::ArrayBuffer::fromJSObject(argv8));
        } else if (js_IsTypedArray(argv8)) {
            rv = self->TexImage2D_array(argv0, argv1, argv2, argv3,
                                        argv4, argv5, argv6, argv7,
                                        js::TypedArray::fromJSObject(argv8));
        } else {
            xpc_qsThrowBadArg(cx, NS_ERROR_FAILURE, vp, 8);
            return JS_FALSE;
        }
    } else {
        xpc_qsThrow(cx, NS_ERROR_XPC_NOT_ENOUGH_ARGS);
        return JS_FALSE;
    }

    if (NS_FAILED(rv))
        return xpc_qsThrowMethodFailed(cx, rv, vp);

    *vp = JSVAL_VOID;
    return JS_TRUE;
}