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; }
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); }
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; }
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; }