From c66721be2e91519a66d3baf1d9558fbb88e2e861 Mon Sep 17 00:00:00 2001 From: Ms2ger Date: Thu, 10 Jul 2014 21:04:26 +0200 Subject: [PATCH] Backout changeset 69c0707a144a for crashes on a CLOSED TREE. --- js/xpconnect/src/XPCConvert.cpp | 96 +++++++++++++++++++++----- js/xpconnect/src/XPCWrappedJSClass.cpp | 11 +-- js/xpconnect/src/XPCWrappedNative.cpp | 4 +- js/xpconnect/src/xpcprivate.h | 2 +- 4 files changed, 88 insertions(+), 25 deletions(-) diff --git a/js/xpconnect/src/XPCConvert.cpp b/js/xpconnect/src/XPCConvert.cpp index a0b5eb7a1a5..d0b8b332034 100644 --- a/js/xpconnect/src/XPCConvert.cpp +++ b/js/xpconnect/src/XPCConvert.cpp @@ -376,7 +376,7 @@ bool ConvertToPrimitive(JSContext *cx, HandleValue v, T *retval) bool XPCConvert::JSData2Native(void* d, HandleValue s, const nsXPTType& type, - const nsID* iid, + bool useAllocator, const nsID* iid, nsresult* pErr) { NS_PRECONDITION(d, "bad param"); @@ -474,7 +474,10 @@ XPCConvert::JSData2Native(void* d, HandleValue s, case nsXPTType::T_ASTRING: { if (s.isUndefined()) { - (**((nsAString**)d)).SetIsVoid(true); + if (useAllocator) + *((const nsAString**)d) = &NullString(); + else + (**((nsAString**)d)).SetIsVoid(true); return true; } // Fall through to T_DOMSTRING case. @@ -482,7 +485,10 @@ XPCConvert::JSData2Native(void* d, HandleValue s, case nsXPTType::T_DOMSTRING: { if (s.isNull()) { - (**((nsAString**)d)).SetIsVoid(true); + if (useAllocator) + *((const nsAString**)d) = &NullString(); + else + (**((nsAString**)d)).SetIsVoid(true); return true; } size_t length = 0; @@ -493,17 +499,27 @@ XPCConvert::JSData2Native(void* d, HandleValue s, if (!str) return false; - chars = JS_GetStringCharsAndLength(cx, str, &length); + chars = useAllocator ? JS_GetStringCharsZAndLength(cx, str, &length) + : JS_GetStringCharsAndLength(cx, str, &length); if (!chars) return false; if (!length) { - (**((nsAString**)d)).Truncate(); + if (useAllocator) + *((const nsAString**)d) = &EmptyString(); + else + (**((nsAString**)d)).Truncate(); return true; } } - nsString* ws = *((nsString**)d); + nsString* ws; + if (useAllocator) { + ws = nsXPConnect::GetRuntimeInstance()->NewShortLivedString(); + *((const nsString**)d) = ws; + } else { + ws = *((nsString**)d); + } if (!str) { ws->AssignLiteral(MOZ_UTF16("undefined")); @@ -515,6 +531,10 @@ XPCConvert::JSData2Native(void* d, HandleValue s, // The characters represent a literal char16_t string constant // compiled into libxul, such as the string "undefined" above. ws->AssignLiteral(chars, length); + } else if (useAllocator && STRING_TO_JSVAL(str) == s) { + // The JS string will exist over the function call. + // We don't need to copy the characters in this case. + ws->Rebind(chars, length); } else { ws->Assign(chars, length); } @@ -595,8 +615,12 @@ XPCConvert::JSData2Native(void* d, HandleValue s, JSString* str; if (s.isNull() || s.isUndefined()) { - nsCString* rs = *((nsCString**)d); - rs->SetIsVoid(true); + if (useAllocator) { + *((const nsACString**)d) = &NullCString(); + } else { + nsCString* rs = *((nsCString**)d); + rs->SetIsVoid(true); + } return true; } @@ -608,12 +632,26 @@ XPCConvert::JSData2Native(void* d, HandleValue s, } if (!length) { - nsCString* rs = *((nsCString**)d); - rs->Truncate(); + if (useAllocator) { + *((const nsACString**)d) = &EmptyCString(); + } else { + nsCString* rs = *((nsCString**)d); + rs->Truncate(); + } return true; } - nsCString *rs = *((nsCString**)d); + nsCString *rs; + if (useAllocator) { + // Use nsCString to enable sharing + rs = new nsCString(); + if (!rs) + return false; + + *((const nsCString**)d) = rs; + } else { + rs = *((nsCString**)d); + } CopyUTF16toUTF8(Substring(chars, length), *rs); return true; } @@ -621,9 +659,18 @@ XPCConvert::JSData2Native(void* d, HandleValue s, case nsXPTType::T_CSTRING: { if (s.isNull() || s.isUndefined()) { - nsACString* rs = *((nsACString**)d); - rs->Truncate(); - rs->SetIsVoid(true); + if (useAllocator) { + nsACString *rs = new nsCString(); + if (!rs) + return false; + + rs->SetIsVoid(true); + *((nsACString**)d) = rs; + } else { + nsACString* rs = *((nsACString**)d); + rs->Truncate(); + rs->SetIsVoid(true); + } return true; } @@ -639,12 +686,25 @@ XPCConvert::JSData2Native(void* d, HandleValue s, } if (!length) { - nsCString* rs = *((nsCString**)d); - rs->Truncate(); + if (useAllocator) { + *((const nsACString**)d) = &EmptyCString(); + } else { + nsCString* rs = *((nsCString**)d); + rs->Truncate(); + } return true; } - nsACString *rs = *((nsACString**)d); + nsACString *rs; + if (useAllocator) { + rs = new nsCString(); + if (!rs) + return false; + *((const nsACString**)d) = rs; + } else { + rs = *((nsACString**)d); + } + rs->SetLength(uint32_t(length)); if (rs->Length() != uint32_t(length)) { return false; @@ -1548,7 +1608,7 @@ XPCConvert::JSArray2Native(void** d, HandleValue s, for (initedCount = 0; initedCount < count; initedCount++) { \ if (!JS_GetElement(cx, jsarray, initedCount, ¤t) || \ !JSData2Native(((_t*)array)+initedCount, current, type, \ - iid, pErr)) \ + true, iid, pErr)) \ goto failure; \ } \ PR_END_MACRO diff --git a/js/xpconnect/src/XPCWrappedJSClass.cpp b/js/xpconnect/src/XPCWrappedJSClass.cpp index 0078513345a..a5b6e1d5b47 100644 --- a/js/xpconnect/src/XPCWrappedJSClass.cpp +++ b/js/xpconnect/src/XPCWrappedJSClass.cpp @@ -283,7 +283,10 @@ GetNamedPropertyAsVariantRaw(XPCCallContext& ccx, RootedValue val(ccx); return JS_GetPropertyById(ccx, aJSObj, aName, &val) && - XPCConvert::JSData2Native(aResult, val, type, + // Note that this always takes the T_INTERFACE path through + // JSData2Native, so the value passed for useAllocator + // doesn't really matter. We pass true for consistency. + XPCConvert::JSData2Native(aResult, val, type, true, &NS_GET_IID(nsIVariant), pErr); } @@ -1347,13 +1350,13 @@ pre_call_clean_up: (defined(__powerpc__) && !defined (__powerpc64__))) if (type_tag == nsXPTType::T_JSVAL) { if (!XPCConvert::JSData2Native(*(void**)(&pv->val), val, type, - ¶m_iid, nullptr)) + !param.IsDipper(), ¶m_iid, nullptr)) break; } else #endif { if (!XPCConvert::JSData2Native(&pv->val, val, type, - ¶m_iid, nullptr)) + !param.IsDipper(), ¶m_iid, nullptr)) break; } } @@ -1426,7 +1429,7 @@ pre_call_clean_up: break; } else { if (!XPCConvert::JSData2Native(&pv->val, val, type, - ¶m_iid, + true, ¶m_iid, nullptr)) break; } diff --git a/js/xpconnect/src/XPCWrappedNative.cpp b/js/xpconnect/src/XPCWrappedNative.cpp index 959f89a5ba1..efd47c5e092 100644 --- a/js/xpconnect/src/XPCWrappedNative.cpp +++ b/js/xpconnect/src/XPCWrappedNative.cpp @@ -2156,7 +2156,7 @@ CallMethodHelper::ConvertIndependentParam(uint8_t i) } nsresult err; - if (!XPCConvert::JSData2Native(&dp->val, src, type, ¶m_iid, &err)) { + if (!XPCConvert::JSData2Native(&dp->val, src, type, true, ¶m_iid, &err)) { ThrowBadParam(err, i, mCallContext); return false; } @@ -2276,7 +2276,7 @@ CallMethodHelper::ConvertDependentParam(uint8_t i) } } } else { - if (!XPCConvert::JSData2Native(&dp->val, src, type, + if (!XPCConvert::JSData2Native(&dp->val, src, type, true, ¶m_iid, &err)) { ThrowBadParam(err, i, mCallContext); return false; diff --git a/js/xpconnect/src/xpcprivate.h b/js/xpconnect/src/xpcprivate.h index 43d5cdd7157..008d9c53062 100644 --- a/js/xpconnect/src/xpcprivate.h +++ b/js/xpconnect/src/xpcprivate.h @@ -2501,7 +2501,7 @@ public: static bool JSData2Native(void* d, JS::HandleValue s, const nsXPTType& type, - const nsID* iid, + bool useAllocator, const nsID* iid, nsresult* pErr); /**