diff --git a/caps/src/nsSecurityManagerFactory.cpp b/caps/src/nsSecurityManagerFactory.cpp index 424911c0a71..d3ec46a036b 100644 --- a/caps/src/nsSecurityManagerFactory.cpp +++ b/caps/src/nsSecurityManagerFactory.cpp @@ -83,8 +83,12 @@ nsSecurityNameSet::InitializeNameSet(nsIScriptContext* aScriptContext) JSObject *obj = global; JSObject *proto; JSAutoRequest ar(cx); - while ((proto = JS_GetPrototype(obj)) != nullptr) + for (;;) { + MOZ_ALWAYS_TRUE(JS_GetPrototype(cx, obj, &proto)); + if (!proto) + break; obj = proto; + } JSClass *objectClass = JS_GetClass(obj); JS::Value v; diff --git a/content/xbl/src/nsXBLBinding.cpp b/content/xbl/src/nsXBLBinding.cpp index 9ed505b04a2..ed4f3e3d90b 100644 --- a/content/xbl/src/nsXBLBinding.cpp +++ b/content/xbl/src/nsXBLBinding.cpp @@ -1217,7 +1217,9 @@ nsXBLBinding::ChangeDocument(nsIDocument* aOldDocument, nsIDocument* aNewDocumen JSAutoCompartment ac(cx, scriptObject); for ( ; true; base = proto) { // Will break out on null proto - proto = ::JS_GetPrototype(base); + if (!JS_GetPrototype(cx, base, &proto)) { + return; + } if (!proto) { break; } @@ -1249,7 +1251,10 @@ nsXBLBinding::ChangeDocument(nsIDocument* aOldDocument, nsIDocument* aNewDocumen // Alright! This is the right prototype. Pull it out of the // proto chain. - JSObject* grandProto = ::JS_GetPrototype(proto); + JSObject* grandProto; + if (!JS_GetPrototype(cx, proto, &grandProto)) { + return; + } ::JS_SetPrototype(cx, base, grandProto); break; } @@ -1346,7 +1351,9 @@ nsXBLBinding::DoInitJSClass(JSContext *cx, JSObject *global, JSObject *obj, if (obj) { // Retrieve the current prototype of obj. - parent_proto = ::JS_GetPrototype(obj); + if (!JS_GetPrototype(cx, obj, &parent_proto)) { + return NS_ERROR_FAILURE; + } if (parent_proto) { // We need to create a unique classname based on aClassName and // parent_proto. Append a space (an invalid URI character) to ensure that diff --git a/content/xbl/src/nsXBLDocumentInfo.cpp b/content/xbl/src/nsXBLDocumentInfo.cpp index 87d4c730380..ee0f5386434 100644 --- a/content/xbl/src/nsXBLDocumentInfo.cpp +++ b/content/xbl/src/nsXBLDocumentInfo.cpp @@ -98,7 +98,9 @@ nsXBLDocGlobalObject::doCheckAccess(JSContext *cx, JSObject *obj, jsid id, uint3 // Make sure to actually operate on our object, and not some object further // down on the proto chain. while (JS_GetClass(obj) != &nsXBLDocGlobalObject::gSharedGlobalClass) { - obj = ::JS_GetPrototype(obj); + if (!::JS_GetPrototype(cx, obj, &obj)) { + return JS_FALSE; + } if (!obj) { ::JS_ReportError(cx, "Invalid access to a global object property."); return JS_FALSE; diff --git a/dom/base/nsDOMClassInfo.cpp b/dom/base/nsDOMClassInfo.cpp index 24d025de2c8..fc11438b232 100644 --- a/dom/base/nsDOMClassInfo.cpp +++ b/dom/base/nsDOMClassInfo.cpp @@ -5131,9 +5131,12 @@ nsDOMClassInfo::PostCreatePrototype(JSContext * cx, JSObject * proto) "Incorrect object class!"); } - NS_ASSERTION(::JS_GetPrototype(proto) && - JS_GetClass(::JS_GetPrototype(proto)) == sObjectClass, - "Hmm, somebody did something evil?"); +#ifdef DEBUG + JSObject *proto2; + JS_GetPrototype(cx, proto, &proto2); + NS_ASSERTION(proto2 && JS_GetClass(proto2) == sObjectClass, + "Hmm, somebody did something evil?"); +#endif #ifdef DEBUG if (mData->mHasClassInterface && mData->mProtoChainInterface && @@ -5462,7 +5465,10 @@ nsWindowSH::GlobalScopePolluterNewResolve(JSContext *cx, JSHandleObject obj, return JS_TRUE; } - JSObject *proto = ::JS_GetPrototype(obj); + JSObject *proto; + if (!::JS_GetPrototype(cx, obj, &proto)) { + return JS_FALSE; + } JSBool hasProp; if (!proto || !::JS_HasPropertyById(cx, proto, id, &hasProp) || @@ -5505,14 +5511,21 @@ nsWindowSH::GlobalScopePolluterNewResolve(JSContext *cx, JSHandleObject obj, } // static -void +JSBool nsWindowSH::InvalidateGlobalScopePolluter(JSContext *cx, JSObject *obj) { JSObject *proto; JSAutoRequest ar(cx); - while ((proto = ::JS_GetPrototype(obj))) { + for (;;) { + if (!::JS_GetPrototype(cx, obj, &proto)) { + return JS_FALSE; + } + if (!proto) { + break; + } + if (JS_GetClass(proto) == &sGlobalScopePolluterClass) { nsIHTMLDocument *doc = (nsIHTMLDocument *)::JS_GetPrivate(proto); @@ -5520,15 +5533,22 @@ nsWindowSH::InvalidateGlobalScopePolluter(JSContext *cx, JSObject *obj) ::JS_SetPrivate(proto, nullptr); + JSObject *proto_proto; + if (!::JS_GetPrototype(cx, proto, &proto_proto)) { + return JS_FALSE; + } + // Pull the global scope polluter out of the prototype chain so // that it can be freed. - ::JS_SplicePrototype(cx, obj, ::JS_GetPrototype(proto)); + ::JS_SplicePrototype(cx, obj, proto_proto); break; } obj = proto; } + + return JS_TRUE; } // static @@ -5554,7 +5574,13 @@ nsWindowSH::InstallGlobalScopePolluter(JSContext *cx, JSObject *obj, // Find the place in the prototype chain where we want this global // scope polluter (right before Object.prototype). - while ((proto = ::JS_GetPrototype(o))) { + for (;;) { + if (!::JS_GetPrototype(cx, o, &proto)) { + return NS_ERROR_OUT_OF_MEMORY; + } + if (!proto) { + break; + } if (JS_GetClass(proto) == sObjectClass) { // Set the global scope polluters prototype to Object.prototype ::JS_SplicePrototype(cx, gsp, proto); @@ -6322,8 +6348,14 @@ nsDOMConstructor::HasInstance(nsIXPConnectWrappedNative *wrapper, JSObject *dot_prototype = JSVAL_TO_OBJECT(val); - JSObject *proto = JS_GetPrototype(dom_obj); - for ( ; proto; proto = JS_GetPrototype(proto)) { + JSObject *proto = dom_obj; + for (;;) { + if (!JS_GetPrototype(cx, proto, &proto)) { + return NS_ERROR_UNEXPECTED; + } + if (!proto) { + break; + } if (proto == dot_prototype) { *bp = true; break; @@ -6682,7 +6714,10 @@ ResolvePrototype(nsIXPConnect *aXPConnect, nsGlobalWindow *aWin, JSContext *cx, if (dot_prototype) { JSAutoCompartment ac(cx, dot_prototype); - JSObject *xpc_proto_proto = ::JS_GetPrototype(dot_prototype); + JSObject *xpc_proto_proto; + if (!::JS_GetPrototype(cx, dot_prototype, &xpc_proto_proto)) { + return NS_ERROR_UNEXPECTED; + } if (proto && (!xpc_proto_proto || @@ -8428,7 +8463,10 @@ nsNamedArraySH::NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx, } JSAutoCompartment ac(cx, realObj); - JSObject *proto = ::JS_GetPrototype(realObj); + JSObject *proto; + if (!::JS_GetPrototype(cx, realObj, &proto)) { + return NS_ERROR_FAILURE; + } if (proto) { JSBool hasProp; @@ -9144,14 +9182,17 @@ nsHTMLDocumentSH::CallToGetPropMapper(JSContext *cx, unsigned argc, jsval *vp) } -static inline JSObject * -GetDocumentAllHelper(JSObject *obj) +static inline bool +GetDocumentAllHelper(JSContext *cx, JSObject *obj, JSObject **result) { while (obj && JS_GetClass(obj) != &sHTMLDocumentAllHelperClass) { - obj = ::JS_GetPrototype(obj); + if (!::JS_GetPrototype(cx, obj, &obj)) { + return false; + } } - return obj; + *result = obj; + return true; } static inline void * @@ -9177,7 +9218,10 @@ nsHTMLDocumentSH::DocumentAllHelperGetProperty(JSContext *cx, JSHandleObject obj return JS_TRUE; } - JSObject *helper = GetDocumentAllHelper(obj); + JSObject *helper; + if (!GetDocumentAllHelper(cx, obj, &helper)) { + return JS_FALSE; + } if (!helper) { NS_ERROR("Uh, how'd we get here?"); @@ -9235,7 +9279,10 @@ nsHTMLDocumentSH::DocumentAllHelperNewResolve(JSContext *cx, JSHandleObject obj, { if (nsDOMClassInfo::sAll_id == id) { // document.all is resolved for the first time. Define it. - JSObject *helper = GetDocumentAllHelper(obj); + JSObject *helper; + if (!GetDocumentAllHelper(cx, obj, &helper)) { + return JS_FALSE; + } if (helper) { if (!::JS_DefineProperty(cx, helper, "all", JSVAL_VOID, nullptr, nullptr, @@ -9259,7 +9306,10 @@ nsHTMLDocumentSH::DocumentAllTagsNewResolve(JSContext *cx, JSHandleObject obj, if (JSID_IS_STRING(id)) { nsDocument *doc = GetDocument(obj); - JSObject *proto = ::JS_GetPrototype(obj); + JSObject *proto; + if (!::JS_GetPrototype(cx, obj, &proto)) { + return JS_FALSE; + } if (NS_UNLIKELY(!proto)) { return JS_TRUE; } @@ -9338,9 +9388,19 @@ nsHTMLDocumentSH::NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx, nsIDocument *doc = static_cast(wrapper->Native()); if (doc->GetCompatibilityMode() == eCompatibility_NavQuirks) { - JSObject *helper = GetDocumentAllHelper(::JS_GetPrototype(obj)); + JSObject *proto; + if (!::JS_GetPrototype(cx, obj, &proto)) { + return NS_ERROR_FAILURE; + } - JSObject *proto = ::JS_GetPrototype(helper ? helper : obj); + JSObject *helper; + if (!GetDocumentAllHelper(cx, proto, &helper)) { + return NS_ERROR_FAILURE; + } + + if (!::JS_GetPrototype(cx, helper ? helper : obj, &proto)) { + return NS_ERROR_FAILURE; + } // Check if the property all is defined on obj's (or helper's // if obj doesn't exist) prototype, if it is, don't expose our @@ -9355,11 +9415,14 @@ nsHTMLDocumentSH::NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx, // Our helper's prototype now has an "all" property, remove // the helper out of the prototype chain to prevent // shadowing of the now defined "all" property. - JSObject *tmp = obj, *tmpProto; + JSObject *tmp = obj, *tmpProto = tmp; - while ((tmpProto = ::JS_GetPrototype(tmp)) != helper) { + do { tmp = tmpProto; - } + if (!::JS_GetPrototype(cx, tmp, &tmpProto)) { + return NS_ERROR_UNEXPECTED; + } + } while (tmpProto != helper); ::JS_SetPrototype(cx, tmp, proto); } @@ -9373,8 +9436,11 @@ nsHTMLDocumentSH::NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx, // Print a warning so developers can stop using document.all PrintWarningOnConsole(cx, "DocumentAllUsed"); + if (!::JS_GetPrototype(cx, obj, &proto)) { + return NS_ERROR_UNEXPECTED; + } helper = ::JS_NewObject(cx, &sHTMLDocumentAllHelperClass, - ::JS_GetPrototype(obj), + proto, ::JS_GetGlobalForObject(cx, obj)); if (!helper) { @@ -9944,7 +10010,10 @@ nsHTMLPluginObjElementSH::GetProperty(nsIXPConnectWrappedNative *wrapper, { JSAutoRequest ar(cx); - JSObject *pi_obj = ::JS_GetPrototype(obj); + JSObject *pi_obj; + if (!::JS_GetPrototype(cx, obj, &pi_obj)) { + return NS_ERROR_UNEXPECTED; + } if (NS_UNLIKELY(!pi_obj)) { return NS_OK; } @@ -9973,7 +10042,10 @@ nsHTMLPluginObjElementSH::SetProperty(nsIXPConnectWrappedNative *wrapper, { JSAutoRequest ar(cx); - JSObject *pi_obj = ::JS_GetPrototype(obj); + JSObject *pi_obj; + if (!::JS_GetPrototype(cx, obj, &pi_obj)) { + return NS_ERROR_UNEXPECTED; + } if (NS_UNLIKELY(!pi_obj)) { return NS_OK; } @@ -10049,7 +10121,9 @@ nsHTMLPluginObjElementSH::GetPluginJSObject(JSContext *cx, JSObject *obj, if (plugin_inst) { plugin_inst->GetJSObject(cx, plugin_obj); if (*plugin_obj) { - *plugin_proto = ::JS_GetPrototype(*plugin_obj); + if (!::JS_GetPrototype(cx, *plugin_obj, plugin_proto)) { + return NS_ERROR_UNEXPECTED; + } } } @@ -10394,7 +10468,10 @@ nsStorage2SH::NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx, return NS_OK; } - JSObject *proto = ::JS_GetPrototype(realObj); + JSObject *proto; + if (!::JS_GetPrototype(cx, realObj, &proto)) { + return NS_ERROR_FAILURE; + } JSBool hasProp; if (proto && diff --git a/dom/base/nsDOMClassInfo.h b/dom/base/nsDOMClassInfo.h index 568ebd796cc..6215c994b8a 100644 --- a/dom/base/nsDOMClassInfo.h +++ b/dom/base/nsDOMClassInfo.h @@ -420,7 +420,7 @@ public: JSMutableHandleValue vp); static JSBool SecurityCheckOnSetProp(JSContext *cx, JSHandleObject obj, JSHandleId id, JSBool strict, JSMutableHandleValue vp); - static void InvalidateGlobalScopePolluter(JSContext *cx, JSObject *obj); + static JSBool InvalidateGlobalScopePolluter(JSContext *cx, JSObject *obj); static nsresult InstallGlobalScopePolluter(JSContext *cx, JSObject *obj, nsIHTMLDocument *doc); static nsIClassInfo *doCreate(nsDOMClassInfoData* aData) diff --git a/dom/base/nsGlobalWindow.cpp b/dom/base/nsGlobalWindow.cpp index 40066fab07c..caccf6d10a8 100644 --- a/dom/base/nsGlobalWindow.cpp +++ b/dom/base/nsGlobalWindow.cpp @@ -1687,7 +1687,11 @@ nsGlobalWindow::SetOuterObject(JSContext* aCx, JSObject* aOuterObject) // Set up the prototype for the outer object. JSObject* inner = JS_GetParent(aOuterObject); - JS_SetPrototype(aCx, aOuterObject, JS_GetPrototype(inner)); + JSObject* proto; + if (!JS_GetPrototype(aCx, inner, &proto)) { + return NS_ERROR_FAILURE; + } + JS_SetPrototype(aCx, aOuterObject, proto); return NS_OK; } @@ -1856,7 +1860,9 @@ nsGlobalWindow::SetNewDocument(nsIDocument* aDocument, if (aDocument != oldDoc) { xpc_UnmarkGrayObject(currentInner->mJSObject); - nsWindowSH::InvalidateGlobalScopePolluter(cx, currentInner->mJSObject); + if (!nsWindowSH::InvalidateGlobalScopePolluter(cx, currentInner->mJSObject)) { + return NS_ERROR_FAILURE; + } } // We're reusing the inner window, but this still counts as a navigation, @@ -1992,7 +1998,8 @@ nsGlobalWindow::SetNewDocument(nsIDocument* aDocument, JS_SetParent(cx, mJSObject, newInnerWindow->mJSObject); - SetOuterObject(cx, mJSObject); + rv = SetOuterObject(cx, mJSObject); + NS_ENSURE_SUCCESS(rv, rv); JSCompartment *compartment = js::GetObjectCompartment(mJSObject); xpc::CompartmentPrivate *priv = @@ -2049,9 +2056,13 @@ nsGlobalWindow::SetNewDocument(nsIDocument* aDocument, // the global object's compartment as its default compartment, // so update that now since it might have changed. JS_SetGlobalObject(cx, mJSObject); - NS_ASSERTION(JS_GetPrototype(mJSObject) == - JS_GetPrototype(newInnerJSObject), +#ifdef DEBUG + JSObject *proto1, *proto2; + JS_GetPrototype(cx, mJSObject, &proto1); + JS_GetPrototype(cx, newInnerJSObject, &proto2); + NS_ASSERTION(proto1 == proto2, "outer and inner globals should have the same prototype"); +#endif nsCOMPtr frame = do_QueryInterface(GetFrameElementInternal()); if (frame) { diff --git a/dom/bindings/Codegen.py b/dom/bindings/Codegen.py index 54c74c9df03..719110779d6 100644 --- a/dom/bindings/Codegen.py +++ b/dom/bindings/Codegen.py @@ -759,13 +759,16 @@ class CGClassHasInstanceHook(CGAbstractStaticMethod): JSObject *objProto = &protov.toObject(); JSObject* instance = &vp.toObject(); - JSObject* proto = JS_GetPrototype(instance); + JSObject* proto; + if (!JS_GetPrototype(cx, instance, &proto)) + return false; while (proto) { if (proto == objProto) { *bp = true; return true; } - proto = JS_GetPrototype(proto); + if (!JS_GetPrototype(cx, proto, &proto)) + return false; } nsISupports* native = diff --git a/dom/plugins/base/nsJSNPRuntime.cpp b/dom/plugins/base/nsJSNPRuntime.cpp index 1e7d0186547..262c4644751 100644 --- a/dom/plugins/base/nsJSNPRuntime.cpp +++ b/dom/plugins/base/nsJSNPRuntime.cpp @@ -1142,7 +1142,9 @@ GetNPObjectWrapper(JSContext *cx, JSObject *obj, bool wrapResult = true) } return obj; } - obj = ::JS_GetPrototype(obj); + if (!::JS_GetPrototype(cx, obj, &obj)) { + return NULL; + } } return NULL; } @@ -2054,12 +2056,20 @@ nsJSNPRuntime::OnPluginDestroy(NPP npp) // be only one, but remove all instances found in case the page put // more than one of the plugin's scriptable objects on the prototype // chain). - while (obj && (proto = ::JS_GetPrototype(obj))) { + while (obj) { + if (!::JS_GetPrototype(cx, obj, &proto)) { + return; + } + if (!proto) { + break; + } // Unwrap while checking the jsclass - if the prototype is a wrapper for // an NP object, that counts too. if (JS_GetClass(js::UnwrapObject(proto)) == &sNPObjectJSWrapperClass) { // We found an NPObject on the proto chain, get its prototype... - proto = ::JS_GetPrototype(proto); + if (!::JS_GetPrototype(cx, proto, &proto)) { + return; + } // ... and pull it out of the chain. ::JS_SetPrototype(cx, obj, proto); diff --git a/js/ipc/ObjectWrapperChild.cpp b/js/ipc/ObjectWrapperChild.cpp index d7f618475c2..7cf75ef1514 100644 --- a/js/ipc/ObjectWrapperChild.cpp +++ b/js/ipc/ObjectWrapperChild.cpp @@ -422,14 +422,14 @@ ObjectWrapperChild::AnswerNewEnumerateInit(/* no in-parameters */ return false; AutoObjectRooter tvr(cx, state); - for (JSObject* proto = mObj; - proto; - proto = JS_GetPrototype(proto)) - { + for (JSObject* proto = mObj; proto; ) { AutoIdArray ids(cx, JS_Enumerate(cx, proto)); for (size_t i = 0; i < ids.length(); ++i) JS_DefinePropertyById(cx, state, ids[i], JSVAL_VOID, NULL, NULL, JSPROP_ENUMERATE | JSPROP_SHARED); + + if (!JS_GetPrototype(cx, proto, &proto)) + return false; } InfallibleTArray* strIds; diff --git a/js/jsd/jsd_val.cpp b/js/jsd/jsd_val.cpp index ba924ce3bb2..20249cc2cbd 100644 --- a/js/jsd/jsd_val.cpp +++ b/js/jsd/jsd_val.cpp @@ -614,6 +614,7 @@ jsd_GetValueFunction(JSDContext* jsdc, JSDValue* jsdval) JSDValue* jsd_GetValuePrototype(JSDContext* jsdc, JSDValue* jsdval) { + JSContext* cx = jsdc->dumbContext; if(!(CHECK_BIT_FLAG(jsdval->flags, GOT_PROTO))) { JSObject* obj; @@ -623,7 +624,8 @@ jsd_GetValuePrototype(JSDContext* jsdc, JSDValue* jsdval) if(JSVAL_IS_PRIMITIVE(jsdval->val)) return NULL; obj = JSVAL_TO_OBJECT(jsdval->val); - proto = JS_GetPrototype(obj); + if(!JS_GetPrototype(cx, obj, &proto)) + return NULL; if(!proto) return NULL; jsdval->proto = jsd_NewValue(jsdc, OBJECT_TO_JSVAL(proto)); @@ -665,6 +667,7 @@ JSDValue* jsd_GetValueConstructor(JSDContext* jsdc, JSDValue* jsdval) { JSCompartment* oldCompartment = NULL; + JSContext* cx = jsdc->dumbContext; if(!(CHECK_BIT_FLAG(jsdval->flags, GOT_CTOR))) { @@ -676,7 +679,8 @@ jsd_GetValueConstructor(JSDContext* jsdc, JSDValue* jsdval) if(JSVAL_IS_PRIMITIVE(jsdval->val)) return NULL; obj = JSVAL_TO_OBJECT(jsdval->val); - proto = JS_GetPrototype(obj); + if(!JS_GetPrototype(cx, obj, &proto)) + return NULL; if(!proto) return NULL; JS_BeginRequest(jsdc->dumbContext); diff --git a/js/src/ctypes/CTypes.cpp b/js/src/ctypes/CTypes.cpp index d7d5804d7c3..18c11c5e744 100644 --- a/js/src/ctypes/CTypes.cpp +++ b/js/src/ctypes/CTypes.cpp @@ -717,7 +717,9 @@ InitCTypeClass(JSContext* cx, HandleObject parent) return NULL; RootedObject ctor(cx, JS_GetFunctionObject(fun)); - RootedObject fnproto(cx, JS_GetPrototype(ctor)); + RootedObject fnproto(cx); + if (!JS_GetPrototype(cx, ctor, fnproto.address())) + return NULL; JS_ASSERT(ctor); JS_ASSERT(fnproto); @@ -1928,11 +1930,15 @@ ConvertToJS(JSContext* cx, if (!numeric_limits::is_signed) { \ value = *static_cast(data); \ /* Get ctypes.UInt64.prototype from ctypes.CType.prototype. */ \ - proto = CType::GetProtoFromType(typeObj, SLOT_UINT64PROTO); \ + proto = CType::GetProtoFromType(cx, typeObj, SLOT_UINT64PROTO); \ + if (!proto) \ + return false; \ } else { \ value = int64_t(*static_cast(data)); \ /* Get ctypes.Int64.prototype from ctypes.CType.prototype. */ \ - proto = CType::GetProtoFromType(typeObj, SLOT_INT64PROTO); \ + proto = CType::GetProtoFromType(cx, typeObj, SLOT_INT64PROTO); \ + if (!proto) \ + return false; \ } \ \ JSObject* obj = Int64Base::Construct(cx, proto, value, \ @@ -3357,17 +3363,20 @@ CType::GetProtoFromCtor(JSObject* obj, CTypeProtoSlot slot) } JSObject* -CType::GetProtoFromType(JSObject* obj, CTypeProtoSlot slot) +CType::GetProtoFromType(JSContext* cx, JSObject* obj, CTypeProtoSlot slot) { JS_ASSERT(IsCType(obj)); // Get the prototype of the type object. - JSObject* proto = JS_GetPrototype(obj); + JSObject* proto; + if (!JS_GetPrototype(cx, obj, &proto)) + return NULL; JS_ASSERT(proto); JS_ASSERT(CType::IsCTypeProto(proto)); // Get the requested ctypes.{Pointer,Array,Struct,Function}Type.prototype. jsval result = JS_GetReservedSlot(proto, slot); + JS_ASSERT(!JSVAL_IS_PRIMITIVE(result)); return JSVAL_TO_OBJECT(result); } @@ -3538,7 +3547,11 @@ CType::HasInstance(JSContext* cx, JSHandleObject obj, JSMutableHandleValue v, JS return JS_TRUE; JSObject* proto = JSVAL_TO_OBJECT(v); - while ((proto = JS_GetPrototype(proto))) { + for (;;) { + if (!JS_GetPrototype(cx, proto, &proto)) + return JS_FALSE; + if (!proto) + break; if (proto == prototype) { *bp = JS_TRUE; break; @@ -3552,15 +3565,16 @@ CType::GetGlobalCTypes(JSContext* cx, JSObject* obj) { JS_ASSERT(CType::IsCType(obj)); - JSObject *objTypeProto = JS_GetPrototype(obj); - if (!objTypeProto) { - } + JSObject *objTypeProto; + if (!JS_GetPrototype(cx, obj, &objTypeProto)) + return NULL; JS_ASSERT(objTypeProto); JS_ASSERT(CType::IsCTypeProto(objTypeProto)); jsval valCTypes = JS_GetReservedSlot(objTypeProto, SLOT_CTYPES); JS_ASSERT(!JSVAL_IS_PRIMITIVE(valCTypes)); + JS_ASSERT(!JSVAL_IS_PRIMITIVE(valCTypes)); return JSVAL_TO_OBJECT(valCTypes); } @@ -3653,8 +3667,12 @@ PointerType::CreateInternal(JSContext* cx, HandleObject baseType) // of this type, or ctypes.FunctionType.prototype for function pointers. CTypeProtoSlot slotId = CType::GetTypeCode(baseType) == TYPE_function ? SLOT_FUNCTIONDATAPROTO : SLOT_POINTERDATAPROTO; - RootedObject dataProto(cx, CType::GetProtoFromType(baseType, slotId)); - RootedObject typeProto(cx, CType::GetProtoFromType(baseType, SLOT_POINTERPROTO)); + RootedObject dataProto(cx, CType::GetProtoFromType(cx, baseType, slotId)); + if (!dataProto) + return NULL; + RootedObject typeProto(cx, CType::GetProtoFromType(cx, baseType, SLOT_POINTERPROTO)); + if (!typeProto) + return NULL; // Create a new CType object with the common properties and slots. JSObject* typeObj = CType::Create(cx, typeProto, dataProto, TYPE_pointer, @@ -3971,8 +3989,12 @@ ArrayType::CreateInternal(JSContext* cx, { // Get ctypes.ArrayType.prototype and the common prototype for CData objects // of this type, from ctypes.CType.prototype. - RootedObject typeProto(cx, CType::GetProtoFromType(baseType, SLOT_ARRAYPROTO)); - RootedObject dataProto(cx, CType::GetProtoFromType(baseType, SLOT_ARRAYDATAPROTO)); + RootedObject typeProto(cx, CType::GetProtoFromType(cx, baseType, SLOT_ARRAYPROTO)); + if (!typeProto) + return NULL; + RootedObject dataProto(cx, CType::GetProtoFromType(cx, baseType, SLOT_ARRAYDATAPROTO)); + if (!dataProto) + return NULL; // Determine the size of the array from the base type, if possible. // The size of the base type must be defined. @@ -4515,7 +4537,9 @@ StructType::DefineInternal(JSContext* cx, JSObject* typeObj_, JSObject* fieldsOb // Get the common prototype for CData objects of this type from // ctypes.CType.prototype. - RootedObject dataProto(cx, CType::GetProtoFromType(typeObj, SLOT_STRUCTDATAPROTO)); + RootedObject dataProto(cx, CType::GetProtoFromType(cx, typeObj, SLOT_STRUCTDATAPROTO)); + if (!dataProto) + return JS_FALSE; // Set up the 'prototype' and 'prototype.constructor' properties. // The prototype will reflect the struct fields as properties on CData objects @@ -5372,10 +5396,14 @@ FunctionType::CreateInternal(JSContext* cx, // Get ctypes.FunctionType.prototype and the common prototype for CData objects // of this type, from ctypes.CType.prototype. - RootedObject typeProto(cx, CType::GetProtoFromType(fninfo->mReturnType, + RootedObject typeProto(cx, CType::GetProtoFromType(cx, fninfo->mReturnType, SLOT_FUNCTIONPROTO)); - RootedObject dataProto(cx, CType::GetProtoFromType(fninfo->mReturnType, + if (!typeProto) + return NULL; + RootedObject dataProto(cx, CType::GetProtoFromType(cx, fninfo->mReturnType, SLOT_FUNCTIONDATAPROTO)); + if (!dataProto) + return NULL; // Create a new CType object with the common properties and slots. JSObject* typeObj = CType::Create(cx, typeProto, dataProto, TYPE_function, @@ -5590,6 +5618,8 @@ FunctionType::Call(JSContext* cx, // Store the error value for later consultation with |ctypes.getStatus| JSObject *objCTypes = CType::GetGlobalCTypes(cx, typeObj); + if (!objCTypes) + return false; JS_SetReservedSlot(objCTypes, SLOT_ERRNO, INT_TO_JSVAL(errnoStatus)); #if defined(XP_WIN) @@ -5740,7 +5770,9 @@ CClosure::Create(JSContext* cx, // Get the prototype of the FunctionType object, of class CTypeProto, // which stores our JSContext for use with the closure. - JSObject* proto = JS_GetPrototype(typeObj); + JSObject* proto; + if (!JS_GetPrototype(cx, typeObj, &proto)) + return NULL; JS_ASSERT(proto); JS_ASSERT(CType::IsCTypeProto(proto)); @@ -6906,6 +6938,8 @@ CDataFinalizer::Methods::Dispose(JSContext* cx, unsigned argc, jsval *vp) JS_ASSERT(!JSVAL_IS_PRIMITIVE(valType)); JSObject *objCTypes = CType::GetGlobalCTypes(cx, JSVAL_TO_OBJECT(valType)); + if (!objCTypes) + return JS_FALSE; jsval valCodePtrType = JS_GetReservedSlot(obj, SLOT_DATAFINALIZER_CODETYPE); JS_ASSERT(!JSVAL_IS_PRIMITIVE(valCodePtrType)); diff --git a/js/src/ctypes/CTypes.h b/js/src/ctypes/CTypes.h index 3c541230d33..10227ee5398 100644 --- a/js/src/ctypes/CTypes.h +++ b/js/src/ctypes/CTypes.h @@ -428,7 +428,7 @@ namespace CType { ffi_type* GetFFIType(JSContext* cx, JSObject* obj); JSString* GetName(JSContext* cx, JSHandleObject obj); JSObject* GetProtoFromCtor(JSObject* obj, CTypeProtoSlot slot); - JSObject* GetProtoFromType(JSObject* obj, CTypeProtoSlot slot); + JSObject* GetProtoFromType(JSContext* cx, JSObject* obj, CTypeProtoSlot slot); JSCTypesCallbacks* GetCallbacksFromType(JSObject* obj); } diff --git a/js/src/jsapi-tests/testTypedArrays.cpp b/js/src/jsapi-tests/testTypedArrays.cpp index 6efbcc4a4ea..8c26712142d 100644 --- a/js/src/jsapi-tests/testTypedArrays.cpp +++ b/js/src/jsapi-tests/testTypedArrays.cpp @@ -30,7 +30,8 @@ BEGIN_TEST(testTypedArrays) RootedObject buffer(cx, JS_NewArrayBuffer(cx, nbytes)); CHECK(JS_IsArrayBufferObject(buffer, cx)); - RootedObject proto(cx, JS_GetPrototype(buffer)); + RootedObject proto(cx); + JS_GetPrototype(cx, buffer, proto.address()); CHECK(!JS_IsArrayBufferObject(proto, cx)); RootedObject dummy(cx, JS_GetParent(proto)); CHECK(!JS_IsArrayBufferObject(dummy, cx)); @@ -60,7 +61,8 @@ TestPlainTypedArray(JSContext *cx) { RootedObject array(cx, Create(cx, 7)); CHECK(JS_IsTypedArrayObject(array, cx)); - RootedObject proto(cx, JS_GetPrototype(array)); + RootedObject proto(cx); + JS_GetPrototype(cx, array, proto.address()); CHECK(!JS_IsTypedArrayObject(proto, cx)); RootedObject dummy(cx, JS_GetParent(proto)); CHECK(!JS_IsTypedArrayObject(dummy, cx)); diff --git a/js/src/jsapi.cpp b/js/src/jsapi.cpp index 117ea788896..5c8c8f09516 100644 --- a/js/src/jsapi.cpp +++ b/js/src/jsapi.cpp @@ -3268,11 +3268,14 @@ JS_GetInstancePrivate(JSContext *cx, JSObject *objArg, JSClass *clasp, jsval *ar return obj->getPrivate(); } -JS_PUBLIC_API(JSObject *) -JS_GetPrototype(RawObject obj) +JS_PUBLIC_API(JSBool) +JS_GetPrototype(JSContext *cx, JSObject *objArg, JSObject **protop) { - /* FIXME! */ - return obj->getProto(); + RootedObject obj(cx, objArg); + RootedObject proto(cx); + bool rv = JSObject::getProto(cx, obj, &proto); + *protop = proto; + return rv; } JS_PUBLIC_API(JSBool) diff --git a/js/src/jsapi.h b/js/src/jsapi.h index 89d586a43cf..c89c5fd65ac 100644 --- a/js/src/jsapi.h +++ b/js/src/jsapi.h @@ -4334,8 +4334,8 @@ extern JS_PUBLIC_API(void *) JS_GetInstancePrivate(JSContext *cx, JSObject *obj, JSClass *clasp, jsval *argv); -extern JS_PUBLIC_API(JSObject *) -JS_GetPrototype(JSRawObject obj); +extern JS_PUBLIC_API(JSBool) +JS_GetPrototype(JSContext *cx, JSObject *obj, JSObject **protop); extern JS_PUBLIC_API(JSBool) JS_SetPrototype(JSContext *cx, JSObject *obj, JSObject *proto); diff --git a/js/src/jsfriendapi.h b/js/src/jsfriendapi.h index a517d317018..9b43e073517 100644 --- a/js/src/jsfriendapi.h +++ b/js/src/jsfriendapi.h @@ -405,11 +405,10 @@ GetObjectProto(JSContext *cx, JSObject *obj, JSObject **proto) clasp == &js::OuterWindowProxyClass || clasp == &js::FunctionProxyClass) { - /* FIXME */ - *proto = reinterpret_cast(obj)->type->proto; - } else { - *proto = reinterpret_cast(obj)->type->proto; + return JS_GetPrototype(cx, obj, proto); } + + *proto = reinterpret_cast(obj)->type->proto; return true; } diff --git a/js/xpconnect/src/dombindings.cpp b/js/xpconnect/src/dombindings.cpp index bbdd7c1d03d..530f52181ad 100644 --- a/js/xpconnect/src/dombindings.cpp +++ b/js/xpconnect/src/dombindings.cpp @@ -288,7 +288,11 @@ interface_hasInstance(JSContext *cx, JSHandleObject obj, JSMutableHandleValue vp } else { JSObject *protoObj = JSVAL_TO_OBJECT(prototype); JSObject *proto = other; - while ((proto = JS_GetPrototype(proto))) { + for (;;) { + if (!JS_GetPrototype(cx, proto, &proto)) + return false; + if (!proto) + break; if (proto == protoObj) { *bp = true; return true; @@ -697,8 +701,9 @@ template bool ListBase::enumerate(JSContext *cx, JSObject *proxy, AutoIdVector &props) { - JSObject *proto = JS_GetPrototype(proxy); - return getOwnPropertyNames(cx, proxy, props) && + JSObject *proto; + return JS_GetPrototype(cx, proxy, &proto) && + getOwnPropertyNames(cx, proxy, props) && (!proto || js::GetPropertyNames(cx, proto, 0, &props)); } diff --git a/js/xpconnect/wrappers/ChromeObjectWrapper.cpp b/js/xpconnect/wrappers/ChromeObjectWrapper.cpp index 76aa115846b..00101be7463 100644 --- a/js/xpconnect/wrappers/ChromeObjectWrapper.cpp +++ b/js/xpconnect/wrappers/ChromeObjectWrapper.cpp @@ -44,7 +44,9 @@ ChromeObjectWrapper::getPropertyDescriptor(JSContext *cx, JSObject *wrapper, desc->obj = NULL; // If we found something, were doing a set, or have no proto, we're done. - JSObject *wrapperProto = JS_GetPrototype(wrapper); + JSObject *wrapperProto; + if (!JS_GetPrototype(cx, wrapper, &wrapperProto)) + return false; if (desc->obj || set || !wrapperProto) return true; @@ -61,7 +63,9 @@ ChromeObjectWrapper::has(JSContext *cx, JSObject *wrapper, jsid id, bool *bp) return false; // If we found something or have no prototype, we're done. - JSObject *wrapperProto = JS_GetPrototype(wrapper); + JSObject *wrapperProto; + if (!JS_GetPrototype(cx, wrapper, &wrapperProto)) + return false; if (*bp || !wrapperProto) return true; @@ -102,7 +106,9 @@ ChromeObjectWrapper::get(JSContext *cx, JSObject *wrapper, JSObject *receiver, } // If we have no proto, we're done. - JSObject *wrapperProto = JS_GetPrototype(wrapper); + JSObject *wrapperProto; + if (!JS_GetPrototype(cx, wrapper, &wrapperProto)) + return false; if (!wrapperProto) return true; diff --git a/js/xpconnect/wrappers/WrapperFactory.cpp b/js/xpconnect/wrappers/WrapperFactory.cpp index 8ea054793e2..e7ae541f745 100644 --- a/js/xpconnect/wrappers/WrapperFactory.cpp +++ b/js/xpconnect/wrappers/WrapperFactory.cpp @@ -569,8 +569,11 @@ WrapperFactory::WaiveXrayAndWrap(JSContext *cx, jsval *vp) JSObject * WrapperFactory::WrapSOWObject(JSContext *cx, JSObject *obj) { + JSObject *proto; + if (!JS_GetPrototype(cx, obj, &proto)) + return NULL; JSObject *wrapperObj = - Wrapper::New(cx, obj, JS_GetPrototype(obj), JS_GetGlobalForObject(cx, obj), + Wrapper::New(cx, obj, proto, JS_GetGlobalForObject(cx, obj), &FilteringWrapper::singleton); return wrapperObj; @@ -586,8 +589,11 @@ WrapperFactory::IsComponentsObject(JSObject *obj) JSObject * WrapperFactory::WrapComponentsObject(JSContext *cx, JSObject *obj) { + JSObject *proto; + if (!JS_GetPrototype(cx, obj, &proto)) + return NULL; JSObject *wrapperObj = - Wrapper::New(cx, obj, JS_GetPrototype(obj), JS_GetGlobalForObject(cx, obj), + Wrapper::New(cx, obj, proto, JS_GetGlobalForObject(cx, obj), &FilteringWrapper::singleton); return wrapperObj; diff --git a/js/xpconnect/wrappers/XrayWrapper.cpp b/js/xpconnect/wrappers/XrayWrapper.cpp index 18233117260..8427cbda8a0 100644 --- a/js/xpconnect/wrappers/XrayWrapper.cpp +++ b/js/xpconnect/wrappers/XrayWrapper.cpp @@ -719,8 +719,11 @@ XPCWrappedNativeXrayTraits::resolveNativeProperty(JSContext *cx, JSObject *wrapp // this problem for mozMatchesSelector. See: bug 763897. desc->obj = wrapper; desc->attrs = JSPROP_ENUMERATE; + JSObject *proto; + if (!JS_GetPrototype(cx, wrapper, &proto)) + return false; JSFunction *fun = JS_NewFunction(cx, mozMatchesSelectorStub, - 1, 0, JS_GetPrototype(wrapper), + 1, 0, proto, "mozMatchesSelector"); NS_ENSURE_TRUE(fun, false); desc->value = OBJECT_TO_JSVAL(JS_GetFunctionObject(fun));