Bug 1145854 - Don't leak WrapperOwner::className's string. r=billm

This commit is contained in:
Blake Kaplan 2015-03-27 13:12:37 -07:00
parent d16f449019
commit 0ef2e0f8d2
7 changed files with 24 additions and 13 deletions

View File

@ -232,6 +232,12 @@
todo_is(savedElement.toString, savedElement.toString, "toString identity works");
todo_is(savedElement.QueryInterface, savedElement.QueryInterface, "toString identity works");
is(Object.prototype.toString.call(savedElement), "[object HTMLDivElement]",
"prove that this works (and doesn't leak)");
is(Object.prototype.toString.call(savedElement), "[object HTMLDivElement]",
"prove that this works twice (since we cache it and doesn't leak)");
// This does work because we create a CPOW for isEqualNode that stays
// alive as long as we have a reference to the first CPOW (so as long
// as it's detectable).

View File

@ -92,7 +92,7 @@ class JavaScriptBase : public WrapperOwner, public WrapperAnswer, public Base
bool *result) {
return Answer::RecvObjectClassIs(ObjectId::deserialize(objId), classValue, result);
}
bool RecvClassName(const uint64_t &objId, nsString *result) {
bool RecvClassName(const uint64_t &objId, nsCString *result) {
return Answer::RecvClassName(ObjectId::deserialize(objId), result);
}
bool RecvGetPrototype(const uint64_t &objId, ReturnStatus *rs, ObjectOrNullVariant *result) {
@ -181,7 +181,7 @@ class JavaScriptBase : public WrapperOwner, public WrapperAnswer, public Base
bool *result) {
return Base::SendObjectClassIs(objId.serialize(), classValue, result);
}
bool SendClassName(const ObjectId &objId, nsString *result) {
bool SendClassName(const ObjectId &objId, nsCString *result) {
return Base::SendClassName(objId.serialize(), result);
}
bool SendGetPrototype(const ObjectId &objId, ReturnStatus *rs, ObjectOrNullVariant *result) {

View File

@ -39,7 +39,7 @@ both:
prio(high) sync CallOrConstruct(uint64_t objId, JSParam[] argv, bool construct) returns (ReturnStatus rs, JSVariant result, JSParam[] outparams);
prio(high) sync HasInstance(uint64_t objId, JSVariant v) returns (ReturnStatus rs, bool has);
prio(high) sync ObjectClassIs(uint64_t objId, uint32_t classValue) returns (bool result);
prio(high) sync ClassName(uint64_t objId) returns (nsString name);
prio(high) sync ClassName(uint64_t objId) returns (nsCString name);
prio(high) sync GetPrototype(uint64_t objId) returns (ReturnStatus rs, ObjectOrNullVariant result);
prio(high) sync RegExpToShared(uint64_t objId) returns (ReturnStatus rs, nsString source, uint32_t flags);

View File

@ -513,7 +513,7 @@ WrapperAnswer::RecvObjectClassIs(const ObjectId &objId, const uint32_t &classVal
}
bool
WrapperAnswer::RecvClassName(const ObjectId &objId, nsString *name)
WrapperAnswer::RecvClassName(const ObjectId &objId, nsCString *name)
{
AutoJSAPI jsapi;
if (NS_WARN_IF(!jsapi.Init(scopeForTargetObjects())))
@ -528,7 +528,7 @@ WrapperAnswer::RecvClassName(const ObjectId &objId, nsString *name)
LOG("%s.className()", ReceiverObj(objId));
*name = NS_ConvertASCIItoUTF16(js::ObjectClassName(cx, obj));
*name = js::ObjectClassName(cx, obj);
return true;
}

View File

@ -48,7 +48,7 @@ class WrapperAnswer : public virtual JavaScriptShared
bool RecvHasInstance(const ObjectId &objId, const JSVariant &v, ReturnStatus *rs, bool *bp);
bool RecvObjectClassIs(const ObjectId &objId, const uint32_t &classValue,
bool *result);
bool RecvClassName(const ObjectId &objId, nsString *result);
bool RecvClassName(const ObjectId &objId, nsCString *result);
bool RecvGetPrototype(const ObjectId &objId, ReturnStatus *rs, ObjectOrNullVariant *result);
bool RecvRegExpToShared(const ObjectId &objId, ReturnStatus *rs, nsString *source, uint32_t *flags);

View File

@ -33,6 +33,9 @@ struct AuxCPOWData
// however they see fit.
nsCString objectTag;
// The class name for WrapperOwner::className, below.
nsCString className;
AuxCPOWData(ObjectId id,
bool isCallable,
bool isConstructor,
@ -750,15 +753,17 @@ CPOWProxyHandler::className(JSContext *cx, HandleObject proxy) const
const char *
WrapperOwner::className(JSContext *cx, HandleObject proxy)
{
ObjectId objId = idOf(proxy);
AuxCPOWData *data = AuxCPOWDataOf(proxy);
if (data->className.IsEmpty()) {
ObjectId objId = idOf(proxy);
nsString name;
if (!SendClassName(objId, &name))
return "<error>";
if (!SendClassName(objId, &data->className))
return "<error>";
LOG_STACK();
LOG_STACK();
}
return ToNewCString(name);
return data->className.get();
}
bool

View File

@ -140,7 +140,7 @@ class WrapperOwner : public virtual JavaScriptShared
ReturnStatus *rs, bool *bp) = 0;
virtual bool SendObjectClassIs(const ObjectId &objId, const uint32_t &classValue,
bool *result) = 0;
virtual bool SendClassName(const ObjectId &objId, nsString *result) = 0;
virtual bool SendClassName(const ObjectId &objId, nsCString *result) = 0;
virtual bool SendGetPrototype(const ObjectId &objId, ReturnStatus *rs, ObjectOrNullVariant *result) = 0;
virtual bool SendRegExpToShared(const ObjectId &objId, ReturnStatus *rs, nsString *source,
uint32_t *flags) = 0;