author | Bill McCloskey <wmccloskey@mozilla.com> |
Mon, 03 Sep 2012 16:42:17 -0700 | |
changeset 108155 | fd398d69d052954dc376c64f1e17dbbc05579037 |
parent 108154 | c372439f0aad42d3dd73306c59035f2450d2e1b7 |
child 108156 | 7228effb2e5b55055f7d8597a86d42857a270beb |
push id | 23539 |
push user | ryanvm@gmail.com |
push date | Wed, 26 Sep 2012 22:55:55 +0000 |
treeherder | autoland@ec079fd92224 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | bhackett |
bugs | 787856 |
milestone | 18.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/caps/src/nsSecurityManagerFactory.cpp +++ b/caps/src/nsSecurityManagerFactory.cpp @@ -78,18 +78,22 @@ nsSecurityNameSet::InitializeNameSet(nsI /* * Find Object.prototype's class by walking up the global object's * prototype chain. */ 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; if (!JS_GetProperty(cx, global, "netscape", &v)) return NS_ERROR_FAILURE; JSObject *securityObj; if (v.isObject()) {
--- a/content/xbl/src/nsXBLBinding.cpp +++ b/content/xbl/src/nsXBLBinding.cpp @@ -1212,17 +1212,19 @@ nsXBLBinding::ChangeDocument(nsIDocument // Find the right prototype. JSObject* base = scriptObject; JSObject* proto; JSAutoRequest ar(cx); 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; } JSClass* clazz = ::JS_GetClass(proto); if (!clazz || (~clazz->flags & (JSCLASS_HAS_PRIVATE | JSCLASS_PRIVATE_IS_NSISUPPORTS)) || @@ -1244,17 +1246,20 @@ nsXBLBinding::ChangeDocument(nsIDocument if (JSVAL_TO_PRIVATE(protoBinding) != mPrototypeBinding) { // Not the right binding continue; } // 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; } mPrototypeBinding->UndefineFields(cx, scriptObject); // Don't remove the reference from the document to the // wrapper here since it'll be removed by the element @@ -1341,17 +1346,19 @@ nsXBLBinding::DoInitJSClass(JSContext *c nsAutoCString className(aClassName); JSObject* parent_proto = nullptr; // If we have an "obj" we can set this JSAutoRequest ar(cx); JSAutoCompartment ac(cx, global); 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 // we don't have accidental collisions with the case when parent_proto is // null and aClassName ends in some bizarre numbers (yeah, it's unlikely). jsid parent_proto_id; if (!::JS_GetObjectId(cx, parent_proto, &parent_proto_id)) { // Probably OOM
--- a/content/xbl/src/nsXBLDocumentInfo.cpp +++ b/content/xbl/src/nsXBLDocumentInfo.cpp @@ -93,17 +93,19 @@ nsXBLDocGlobalObject::doCheckAccess(JSCo if (!ssm) { ::JS_ReportError(cx, "Unable to verify access to a global object property."); return JS_FALSE; } // 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; } } nsresult rv = ssm->CheckPropertyAccess(cx, obj, JS_GetClass(obj)->name, id, accessType);
--- a/dom/base/nsDOMClassInfo.cpp +++ b/dom/base/nsDOMClassInfo.cpp @@ -5126,19 +5126,22 @@ nsDOMClassInfo::PostCreatePrototype(JSCo // sObjectClass, so compute it here. We assume that nobody has had a // chance to monkey around with proto's prototype chain before this. if (!sObjectClass) { FindObjectClass(cx, proto); NS_ASSERTION(sObjectClass && !strcmp(sObjectClass->name, "Object"), "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 && mData->mProtoChainInterface != &NS_GET_IID(nsISupports)) { nsCOMPtr<nsIInterfaceInfoManager> iim(do_GetService(NS_INTERFACEINFOMANAGER_SERVICE_CONTRACTID)); if (iim) { @@ -5457,17 +5460,20 @@ nsWindowSH::GlobalScopePolluterNewResolv nsHTMLDocument *document = GetDocument(obj); if (!document) { // If we don't have a document, return early. 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) || hasProp) { // No prototype, or the property exists on the prototype. Do // nothing. return JS_TRUE; @@ -5500,40 +5506,54 @@ nsWindowSH::GlobalScopePolluterNewResolv objp.set(obj); } return JS_TRUE; } // 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); NS_IF_RELEASE(doc); ::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 nsresult nsWindowSH::InstallGlobalScopePolluter(JSContext *cx, JSObject *obj, nsIHTMLDocument *doc) { // If global scope pollution is disabled, or if our document is not @@ -5549,17 +5569,23 @@ nsWindowSH::InstallGlobalScopePolluter(J return NS_ERROR_OUT_OF_MEMORY; } JSObject *o = obj, *proto; // 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); break; } o = proto; @@ -6317,18 +6343,24 @@ nsDOMConstructor::HasInstance(nsIXPConne } if (JSVAL_IS_PRIMITIVE(val)) { return NS_OK; } 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; } } return NS_OK; } @@ -6677,17 +6709,20 @@ ResolvePrototype(nsIXPConnect *aXPConnec if (val.isObject()) { proto = &val.toObject(); } } } 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 || JS_GetClass(xpc_proto_proto) == sObjectClass)) { if (!JS_WrapObject(cx, &proto) || !JS_SetPrototype(cx, dot_prototype, proto)) { return NS_ERROR_UNEXPECTED; } @@ -8423,17 +8458,20 @@ nsNamedArraySH::NewResolve(nsIXPConnectW if (wrapper) { wrapper->GetJSObject(&realObj); } else { realObj = obj; } 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; if (!::JS_HasPropertyById(cx, proto, id, &hasProp)) { *_retval = false; return NS_ERROR_FAILURE; } @@ -9139,24 +9177,27 @@ nsHTMLDocumentSH::CallToGetPropMapper(JS if (!chars) { return JS_FALSE; } return ::JS_GetUCProperty(cx, self, chars, length, 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); - } - - return obj; + if (!::JS_GetPrototype(cx, obj, &obj)) { + return false; + } + } + + *result = obj; + return true; } static inline void * FlagsToPrivate(uint32_t flags) { MOZ_ASSERT((flags & (1 << 31)) == 0); return reinterpret_cast<void*>(static_cast<uintptr_t>(flags << 1)); } @@ -9172,17 +9213,20 @@ PrivateToFlags(void *priv) JSBool nsHTMLDocumentSH::DocumentAllHelperGetProperty(JSContext *cx, JSHandleObject obj, JSHandleId id, JSMutableHandleValue vp) { if (nsDOMClassInfo::sAll_id != id) { 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?"); // Let scripts continue, if we somehow did get here... return JS_TRUE; } @@ -9230,17 +9274,20 @@ nsHTMLDocumentSH::DocumentAllHelperGetPr JSBool nsHTMLDocumentSH::DocumentAllHelperNewResolve(JSContext *cx, JSHandleObject obj, JSHandleId id, unsigned flags, JSMutableHandleObject objp) { 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, JSPROP_ENUMERATE)) { return JS_FALSE; } objp.set(helper); @@ -9254,17 +9301,20 @@ nsHTMLDocumentSH::DocumentAllHelperNewRe JSBool nsHTMLDocumentSH::DocumentAllTagsNewResolve(JSContext *cx, JSHandleObject obj, JSHandleId id, unsigned flags, JSMutableHandleObject objp) { 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; } JSBool found; if (!::JS_HasPropertyById(cx, proto, id, &found)) { return JS_FALSE; } @@ -9333,53 +9383,69 @@ nsHTMLDocumentSH::NewResolve(nsIXPConnec } } if (id == sAll_id && !sDisableDocumentAllSupport && !ObjectIsNativeWrapper(cx, obj)) { nsIDocument *doc = static_cast<nsIDocument*>(wrapper->Native()); if (doc->GetCompatibilityMode() == eCompatibility_NavQuirks) { - JSObject *helper = GetDocumentAllHelper(::JS_GetPrototype(obj)); - - JSObject *proto = ::JS_GetPrototype(helper ? helper : obj); + JSObject *proto; + if (!::JS_GetPrototype(cx, obj, &proto)) { + return NS_ERROR_FAILURE; + } + + 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 // document.all helper. JSBool hasAll = JS_FALSE; if (proto && !JS_HasProperty(cx, proto, "all", &hasAll)) { return NS_ERROR_UNEXPECTED; } if (hasAll && helper) { // 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; - - while ((tmpProto = ::JS_GetPrototype(tmp)) != helper) { + JSObject *tmp = obj, *tmpProto = tmp; + + do { tmp = tmpProto; - } + if (!::JS_GetPrototype(cx, tmp, &tmpProto)) { + return NS_ERROR_UNEXPECTED; + } + } while (tmpProto != helper); ::JS_SetPrototype(cx, tmp, proto); } // If we don't already have a helper, and we're resolving // document.all qualified, and we're *not* detecting // document.all, e.g. if (document.all), and "all" isn't // already defined on our prototype, create a helper. if (!helper && flags & JSRESOLVE_QUALIFIED && !(flags & JSRESOLVE_DETECTING) && !hasAll) { // 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) { return NS_ERROR_OUT_OF_MEMORY; } // Insert the helper into our prototype chain. helper's prototype // is already obj's current prototype. @@ -9939,17 +10005,20 @@ nsHTMLPluginObjElementSH::PostTransplant NS_IMETHODIMP nsHTMLPluginObjElementSH::GetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx, JSObject *obj, jsid id, jsval *vp, bool *_retval) { 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; } JSBool found = false; if (!ObjectIsNativeWrapper(cx, obj)) { *_retval = ::JS_HasPropertyById(cx, pi_obj, id, &found); @@ -9968,17 +10037,20 @@ nsHTMLPluginObjElementSH::GetProperty(ns NS_IMETHODIMP nsHTMLPluginObjElementSH::SetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx, JSObject *obj, jsid id, jsval *vp, bool *_retval) { 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; } JSBool found = false; if (!ObjectIsNativeWrapper(cx, obj)) { *_retval = ::JS_HasPropertyById(cx, pi_obj, id, &found); @@ -10044,17 +10116,19 @@ nsHTMLPluginObjElementSH::GetPluginJSObj // NB: We need an AutoEnterCompartment because we can be called from // nsObjectFrame when the plugin loads after the JS object for our content // node has been created. JSAutoCompartment ac(cx, 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; + } } } return NS_OK; } NS_IMETHODIMP nsHTMLPluginObjElementSH::NewResolve(nsIXPConnectWrappedNative *wrapper, @@ -10389,17 +10463,20 @@ nsStorage2SH::NewResolve(nsIXPConnectWra // First check to see if the property is defined on our prototype, // after converting id to a string if it's an integer. JSString *jsstr = IdToString(cx, id); if (!jsstr) { return NS_OK; } - JSObject *proto = ::JS_GetPrototype(realObj); + JSObject *proto; + if (!::JS_GetPrototype(cx, realObj, &proto)) { + return NS_ERROR_FAILURE; + } JSBool hasProp; if (proto && (::JS_HasPropertyById(cx, proto, id, &hasProp) && hasProp)) { // We found the property we're resolving on the prototype, // nothing left to do here then.
--- a/dom/base/nsDOMClassInfo.h +++ b/dom/base/nsDOMClassInfo.h @@ -415,17 +415,17 @@ public: JSHandleId id, unsigned flags, JSMutableHandleObject objp); static JSBool GlobalScopePolluterGetProperty(JSContext *cx, JSHandleObject obj, JSHandleId id, JSMutableHandleValue vp); static JSBool SecurityCheckOnAddDelProp(JSContext *cx, JSHandleObject obj, JSHandleId id, 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) { return new nsWindowSH(aData); } };
--- a/dom/base/nsGlobalWindow.cpp +++ b/dom/base/nsGlobalWindow.cpp @@ -1682,17 +1682,21 @@ nsresult nsGlobalWindow::SetOuterObject(JSContext* aCx, JSObject* aOuterObject) { // Force our context's global object to be the outer. // NB: JS_SetGlobalObject sets aCx->compartment. JS_SetGlobalObject(aCx, 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; } /** * Create a new global object that will be used for an inner window. * Return the native global and an nsISupports 'holder' that can be used * to manage the lifetime of it. @@ -1851,17 +1855,19 @@ nsGlobalWindow::SetNewDocument(nsIDocume if (reUseInnerWindow) { // We're reusing the current inner window. NS_ASSERTION(!currentInner->IsFrozen(), "We should never be reusing a shared inner window"); newInnerWindow = currentInner; 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, // so all expandos and such defined on the outer window should go away. Force // all Xray wrappers to be recomputed. xpc_UnmarkGrayObject(mJSObject); if (!JS_RefreshCrossCompartmentWrappers(cx, mJSObject)) { return NS_ERROR_FAILURE; @@ -1987,17 +1993,18 @@ nsGlobalWindow::SetNewDocument(nsIDocume mJSObject = outerObject; SetWrapper(mJSObject); { JSAutoCompartment ac(cx, mJSObject); 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 = static_cast<xpc::CompartmentPrivate*>(JS_GetCompartmentPrivate(compartment)); if (priv && priv->waiverWrapperMap) { NS_ASSERTION(!JS_IsExceptionPending(cx), "We might overwrite a pending exception!"); priv->waiverWrapperMap->Reparent(cx, newInnerWindow->mJSObject); @@ -2044,19 +2051,23 @@ nsGlobalWindow::SetNewDocument(nsIDocume JSObject* newInnerJSObject = newInnerWindow->FastGetGlobalJSObject(); #endif // Now that we're connecting the outer global to the inner one, // we must have transplanted it. The JS engine tries to maintain // 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<nsIContent> frame = do_QueryInterface(GetFrameElementInternal()); if (frame) { nsPIDOMWindow* parentWindow = frame->OwnerDoc()->GetWindow(); if (parentWindow && parentWindow->TimeoutSuspendCount()) { SuspendTimeouts(parentWindow->TimeoutSuspendCount()); } }
--- a/dom/bindings/Codegen.py +++ b/dom/bindings/Codegen.py @@ -754,23 +754,26 @@ class CGClassHasInstanceHook(CGAbstractS if (!protov.isObject()) { JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_BAD_PROTOTYPE, "%s"); return false; } 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 = nsContentUtils::XPConnect()->GetNativeOfWrapper(cx, instance); nsCOMPtr<%s> qiResult = do_QueryInterface(native); *bp = !!qiResult; return true; """ % (self.descriptor.name, self.descriptor.hasInstanceInterface)
--- a/dom/plugins/base/nsJSNPRuntime.cpp +++ b/dom/plugins/base/nsJSNPRuntime.cpp @@ -1137,17 +1137,19 @@ GetNPObjectWrapper(JSContext *cx, JSObje { while (obj && (obj = js::UnwrapObjectChecked(cx, obj))) { if (JS_GetClass(obj) == &sNPObjectJSWrapperClass) { if (wrapResult && !JS_WrapObject(cx, &obj)) { return NULL; } return obj; } - obj = ::JS_GetPrototype(obj); + if (!::JS_GetPrototype(cx, obj, &obj)) { + return NULL; + } } return NULL; } static NPObject * GetNPObject(JSContext *cx, JSObject *obj) { obj = GetNPObjectWrapper(cx, obj, /* wrapResult = */ false); @@ -2049,22 +2051,30 @@ nsJSNPRuntime::OnPluginDestroy(NPP npp) ac.construct(cx, obj); } // Loop over the DOM element's JS object prototype chain and remove // all JS objects of the class sNPObjectJSWrapperClass (there should // 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); } obj = proto; } }
--- a/js/ipc/ObjectWrapperChild.cpp +++ b/js/ipc/ObjectWrapperChild.cpp @@ -417,24 +417,24 @@ ObjectWrapperChild::AnswerNewEnumerateIn AutoCheckOperation aco(this, status); JSClass* clasp = const_cast<JSClass*>(&sCPOW_NewEnumerateState_JSClass); JSObject* state = JS_NewObjectWithGivenProto(cx, clasp, NULL, NULL); if (!state) 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<nsString>* strIds; { AutoIdArray ids(cx, JS_Enumerate(cx, state)); if (!ids) return false; strIds = new InfallibleTArray<nsString>(ids.length());
--- a/js/jsd/jsd_val.cpp +++ b/js/jsd/jsd_val.cpp @@ -609,26 +609,28 @@ jsd_GetValueFunction(JSDContext* jsdc, J JS_LeaveCompartment(jsdc->dumbContext, oldCompartment); return fun; } JSDValue* jsd_GetValuePrototype(JSDContext* jsdc, JSDValue* jsdval) { + JSContext* cx = jsdc->dumbContext; if(!(CHECK_BIT_FLAG(jsdval->flags, GOT_PROTO))) { JSObject* obj; JSObject* proto; JS_ASSERT(!jsdval->proto); SET_BIT_FLAG(jsdval->flags, GOT_PROTO); 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)); } if(jsdval->proto) jsdval->proto->nref++; return jsdval->proto; } @@ -660,28 +662,30 @@ jsd_GetValueParent(JSDContext* jsdc, JSD jsdval->parent->nref++; return jsdval->parent; } JSDValue* jsd_GetValueConstructor(JSDContext* jsdc, JSDValue* jsdval) { JSCompartment* oldCompartment = NULL; + JSContext* cx = jsdc->dumbContext; if(!(CHECK_BIT_FLAG(jsdval->flags, GOT_CTOR))) { JSObject* obj; JSObject* proto; JSObject* ctor; JS_ASSERT(!jsdval->ctor); SET_BIT_FLAG(jsdval->flags, GOT_CTOR); 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); oldCompartment = JS_EnterCompartment(jsdc->dumbContext, obj); ctor = JS_GetConstructor(jsdc->dumbContext,proto); JS_LeaveCompartment(jsdc->dumbContext, oldCompartment); JS_EndRequest(jsdc->dumbContext); if(!ctor)
--- a/js/src/ctypes/CTypes.cpp +++ b/js/src/ctypes/CTypes.cpp @@ -712,17 +712,19 @@ static JSObject* InitCTypeClass(JSContext* cx, HandleObject parent) { JSFunction *fun = JS_DefineFunction(cx, parent, "CType", ConstructAbstract, 0, CTYPESCTOR_FLAGS); if (!fun) 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); // Set up ctypes.CType.prototype. RootedObject prototype(cx, JS_NewObject(cx, &sCTypeProtoClass, fnproto, parent)); if (!prototype) return NULL; @@ -1923,21 +1925,25 @@ ConvertToJS(JSContext* cx, #define DEFINE_WRAPPED_INT_TYPE(name, type, ffiType) \ case TYPE_##name: { \ /* Return an Int64 or UInt64 object - do not convert to a JS number. */ \ uint64_t value; \ RootedObject proto(cx); \ if (!numeric_limits<type>::is_signed) { \ value = *static_cast<type*>(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<type*>(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, \ !numeric_limits<type>::is_signed); \ if (!obj) \ return false; \ *result = OBJECT_TO_JSVAL(obj); \ break; \ @@ -3352,27 +3358,30 @@ CType::GetProtoFromCtor(JSObject* obj, C JS_ASSERT(CType::IsCTypeProto(proto)); // Get the desired prototype. jsval result = JS_GetReservedSlot(proto, slot); return JSVAL_TO_OBJECT(result); } 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); } JSBool CType::PrototypeGetter(JSContext* cx, JSHandleObject obj, JSHandleId idval, MutableHandleValue vp) { if (!(CType::IsCType(obj) || CType::IsCTypeProto(obj))) { JS_ReportError(cx, "not a CType or CTypeProto"); @@ -3533,39 +3542,44 @@ CType::HasInstance(JSContext* cx, JSHand JS_ASSERT(prototype); JS_ASSERT(CData::IsCDataProto(prototype)); *bp = JS_FALSE; if (JSVAL_IS_PRIMITIVE(v)) 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; } } return JS_TRUE; } static JSObject* 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); } /******************************************************************************* ** ABI implementation *******************************************************************************/ bool @@ -3648,18 +3662,22 @@ PointerType::CreateInternal(JSContext* c jsval slot = JS_GetReservedSlot(baseType, SLOT_PTR); if (!JSVAL_IS_VOID(slot)) return JSVAL_TO_OBJECT(slot); // Get ctypes.PointerType.prototype and the common prototype for CData objects // 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, NULL, INT_TO_JSVAL(sizeof(void*)), INT_TO_JSVAL(ffi_type_pointer.alignment), &ffi_type_pointer); if (!typeObj) return NULL; @@ -3966,18 +3984,22 @@ ArrayType::Create(JSContext* cx, unsigne JSObject* ArrayType::CreateInternal(JSContext* cx, HandleObject baseType, size_t length, bool lengthDefined) { // 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. // If our length is undefined, both our size and length will be undefined. size_t baseSize; if (!CType::GetSafeSize(baseType, &baseSize)) { JS_ReportError(cx, "base size must be defined"); return NULL; @@ -4510,17 +4532,19 @@ StructType::DefineInternal(JSContext* cx RootedObject typeObj(cx, typeObj_); RootedObject fieldsObj(cx, fieldsObj_); uint32_t len; ASSERT_OK(JS_GetArrayLength(cx, fieldsObj, &len)); // 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 // created from this type. RootedObject prototype(cx, JS_NewObject(cx, &sCDataProtoClass, dataProto, NULL)); if (!prototype) return JS_FALSE; @@ -5367,20 +5391,24 @@ FunctionType::CreateInternal(JSContext* { // Determine and check the types, and prepare the function CIF. AutoPtr<FunctionInfo> fninfo(NewFunctionInfo(cx, abi, rtype, argtypes, arglen)); if (!fninfo) return NULL; // 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, NULL, JSVAL_VOID, JSVAL_VOID, NULL); if (!typeObj) return NULL; js::AutoObjectRooter root(cx, typeObj); @@ -5585,16 +5613,18 @@ FunctionType::Call(JSContext* cx, lastErrorStatus = GetLastError(); SetLastError(savedLastError); #endif // defined(XP_WIN) errno = savedErrno; // 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) JS_SetReservedSlot(objCTypes, SLOT_LASTERROR, INT_TO_JSVAL(lastErrorStatus)); #endif // defined(XP_WIN) // Small integer types get returned as a word-sized ffi_arg. Coerce it back // into the correct size for ConvertToJS. @@ -5735,17 +5765,19 @@ CClosure::Create(JSContext* cx, AutoPtr<ClosureInfo> cinfo(cx->new_<ClosureInfo>(JS_GetRuntime(cx))); if (!cinfo) { JS_ReportOutOfMemory(cx); return NULL; } // 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)); // Get a JSContext for use with the closure. jsval slot = JS_GetReservedSlot(proto, SLOT_CLOSURECX); if (!JSVAL_IS_VOID(slot)) { // Use the existing JSContext. cinfo->cx = static_cast<JSContext*>(JSVAL_TO_PRIVATE(slot)); @@ -6901,16 +6933,18 @@ CDataFinalizer::Methods::Dispose(JSConte JS_ReportError(cx, "dispose called on an empty CDataFinalizer."); return JS_FALSE; } jsval valType = JS_GetReservedSlot(obj, SLOT_DATAFINALIZER_VALTYPE); 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)); JSObject *objCodePtrType = JSVAL_TO_OBJECT(valCodePtrType); JSObject *objCodeType = PointerType::GetBaseType(objCodePtrType); JS_ASSERT(objCodeType); JS_ASSERT(CType::GetTypeCode(objCodeType) == TYPE_function);
--- a/js/src/ctypes/CTypes.h +++ b/js/src/ctypes/CTypes.h @@ -423,17 +423,17 @@ namespace CType { bool TypesEqual(JSObject* t1, JSObject* t2); size_t GetSize(JSObject* obj); bool GetSafeSize(JSObject* obj, size_t* result); bool IsSizeDefined(JSObject* obj); size_t GetAlignment(JSObject* obj); 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); } namespace PointerType { JSObject* CreateInternal(JSContext* cx, JSHandleObject baseType); JSObject* GetBaseType(JSObject* obj); }
--- a/js/src/jsapi-tests/testTypedArrays.cpp +++ b/js/src/jsapi-tests/testTypedArrays.cpp @@ -25,17 +25,18 @@ BEGIN_TEST(testTypedArrays) TestPlainTypedArray<JS_NewUint32Array, uint32_t, JS_GetUint32ArrayData>(cx) && TestPlainTypedArray<JS_NewFloat32Array, float, JS_GetFloat32ArrayData>(cx) && TestPlainTypedArray<JS_NewFloat64Array, double, JS_GetFloat64ArrayData>(cx); size_t nbytes = sizeof(double) * 8; 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)); CHECK_EQUAL(JS_GetArrayBufferByteLength(buffer, cx), nbytes); memset(JS_GetArrayBufferData(buffer, cx), 1, nbytes); ok = ok && @@ -55,17 +56,18 @@ BEGIN_TEST(testTypedArrays) template<JSObject *Create(JSContext *, uint32_t), typename Element, Element *GetData(JSObject *, JSContext *)> bool 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)); CHECK_EQUAL(JS_GetTypedArrayLength(array, cx), 7); CHECK_EQUAL(JS_GetTypedArrayByteOffset(array, cx), 0); CHECK_EQUAL(JS_GetTypedArrayByteLength(array, cx), sizeof(Element) * 7);
--- a/js/src/jsapi.cpp +++ b/js/src/jsapi.cpp @@ -3263,21 +3263,24 @@ JS_PUBLIC_API(void *) JS_GetInstancePrivate(JSContext *cx, JSObject *objArg, JSClass *clasp, jsval *argv) { RootedObject obj(cx, objArg); if (!JS_InstanceOf(cx, obj, clasp, argv)) return NULL; return obj->getPrivate(); } -JS_PUBLIC_API(JSObject *) -JS_GetPrototype(RawObject obj) -{ - /* FIXME! */ - return obj->getProto(); +JS_PUBLIC_API(JSBool) +JS_GetPrototype(JSContext *cx, JSObject *objArg, JSObject **protop) +{ + RootedObject obj(cx, objArg); + RootedObject proto(cx); + bool rv = JSObject::getProto(cx, obj, &proto); + *protop = proto; + return rv; } JS_PUBLIC_API(JSBool) JS_SetPrototype(JSContext *cx, JSObject *objArg, JSObject *protoArg) { RootedObject obj(cx, objArg); RootedObject proto(cx, protoArg); AssertHeapIsIdle(cx);
--- a/js/src/jsapi.h +++ b/js/src/jsapi.h @@ -4329,18 +4329,18 @@ JS_GetPrivate(JSRawObject obj); extern JS_PUBLIC_API(void) JS_SetPrivate(JSRawObject obj, void *data); 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); extern JS_PUBLIC_API(JSObject *) JS_GetParent(JSRawObject obj); extern JS_PUBLIC_API(JSBool)
--- a/js/src/jsfriendapi.h +++ b/js/src/jsfriendapi.h @@ -400,21 +400,20 @@ SetFunctionNativeReserved(RawObject fun, inline bool GetObjectProto(JSContext *cx, JSObject *obj, JSObject **proto) { js::Class *clasp = GetObjectClass(obj); if (clasp == &js::ObjectProxyClass || clasp == &js::OuterWindowProxyClass || clasp == &js::FunctionProxyClass) { - /* FIXME */ - *proto = reinterpret_cast<const shadow::Object*>(obj)->type->proto; - } else { - *proto = reinterpret_cast<const shadow::Object*>(obj)->type->proto; + return JS_GetPrototype(cx, obj, proto); } + + *proto = reinterpret_cast<const shadow::Object*>(obj)->type->proto; return true; } inline void * GetObjectPrivate(RawObject obj) { const shadow::Object *nobj = reinterpret_cast<const shadow::Object*>(obj); void **addr = reinterpret_cast<void**>(&nobj->fixedSlots()[nobj->numFixedSlots()]);
--- a/js/xpconnect/src/dombindings.cpp +++ b/js/xpconnect/src/dombindings.cpp @@ -283,17 +283,21 @@ interface_hasInstance(JSContext *cx, JSH JSObject *other = &vp.toObject(); if (instanceIsProxy(other)) { ProxyHandler *handler = static_cast<ProxyHandler*>(js::GetProxyHandler(other)); if (handler->isInstanceOf(JSVAL_TO_OBJECT(prototype))) { *bp = true; } 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; } } *bp = false; } @@ -692,18 +696,19 @@ ListBase<LC>::delete_(JSContext *cx, JSO *bp = !!b; return true; } template<class LC> bool ListBase<LC>::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)); } template<class LC> bool ListBase<LC>::hasOwn(JSContext *cx, JSObject *proxy, jsid id, bool *bp) { if (hasIndexGetter) {
--- a/js/xpconnect/wrappers/ChromeObjectWrapper.cpp +++ b/js/xpconnect/wrappers/ChromeObjectWrapper.cpp @@ -39,34 +39,38 @@ ChromeObjectWrapper::getPropertyDescript // If the property is something that can be found on a standard prototype, // prefer the one we'll get via the prototype chain in the content // compartment. if (desc->obj && PropIsFromStandardPrototype(cx, desc)) 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; // If not, try doing the lookup on the prototype. MOZ_ASSERT(js::IsObjectInContextCompartment(wrapper, cx)); return JS_GetPropertyDescriptorById(cx, wrapperProto, id, 0, desc); } bool ChromeObjectWrapper::has(JSContext *cx, JSObject *wrapper, jsid id, bool *bp) { // Try the lookup on the base wrapper. if (!ChromeObjectWrapperBase::has(cx, wrapper, id, 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; // Try the prototype if that failed. MOZ_ASSERT(js::IsObjectInContextCompartment(wrapper, cx)); JSPropertyDescriptor desc; memset(&desc, 0, sizeof(desc)); if (!JS_GetPropertyDescriptorById(cx, wrapperProto, id, 0, &desc)) @@ -97,17 +101,19 @@ ChromeObjectWrapper::get(JSContext *cx, if (!ChromeObjectWrapperBase::get(cx, wrapper, receiver, id, vp)) return false; // If we found something, we're done. if (!vp->isUndefined()) return true; } // 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; // Try the prototype. MOZ_ASSERT(js::IsObjectInContextCompartment(wrapper, cx)); return js::GetGeneric(cx, wrapperProto, receiver, id, vp); }
--- a/js/xpconnect/wrappers/WrapperFactory.cpp +++ b/js/xpconnect/wrappers/WrapperFactory.cpp @@ -564,35 +564,41 @@ WrapperFactory::WaiveXrayAndWrap(JSConte *vp = OBJECT_TO_JSVAL(obj); return JS_WrapValue(cx, 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<SameCompartmentSecurityWrapper, OnlyIfSubjectIsSystem>::singleton); return wrapperObj; } bool WrapperFactory::IsComponentsObject(JSObject *obj) { const char *name = js::GetObjectClass(obj)->name; return name[0] == 'n' && !strcmp(name, "nsXPCComponents"); } 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<SameCompartmentSecurityWrapper, ComponentsObjectPolicy>::singleton); return wrapperObj; } JSObject * WrapperFactory::WrapForSameCompartmentXray(JSContext *cx, JSObject *obj) {
--- a/js/xpconnect/wrappers/XrayWrapper.cpp +++ b/js/xpconnect/wrappers/XrayWrapper.cpp @@ -714,18 +714,21 @@ XPCWrappedNativeXrayTraits::resolveNativ id == rt->GetStringID(XPCJSRuntime::IDX_MOZMATCHESSELECTOR) && Is<nsIDOMElement>(wrapper)) { // XPC calling mechanism cannot handle call/bind properly in some cases // especially through xray wrappers. This is a temoorary work around for // 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)); desc->getter = NULL; desc->setter = NULL; desc->shortid = 0; return true; }