From d701ccf82e2fee36170c2c75c305aefbf151aa83 Mon Sep 17 00:00:00 2001 From: Bill McCloskey Date: Wed, 20 Aug 2014 15:16:07 -0700 Subject: [PATCH] Bug 1053999 - Be more conservative in recursion checks before brain transplants (r=bholley) --- dom/base/nsGlobalWindow.cpp | 5 +++-- dom/bindings/BindingUtils.cpp | 5 +++-- js/src/jsfriendapi.h | 13 +++++++++++++ js/xpconnect/src/XPCWrappedNative.cpp | 5 +++-- 4 files changed, 22 insertions(+), 6 deletions(-) diff --git a/dom/base/nsGlobalWindow.cpp b/dom/base/nsGlobalWindow.cpp index fbc09794e82e..50bdc41897ce 100644 --- a/dom/base/nsGlobalWindow.cpp +++ b/dom/base/nsGlobalWindow.cpp @@ -2424,8 +2424,9 @@ nsGlobalWindow::SetNewDocument(nsIDocument* aDocument, bool thisChrome = IsChromeWindow(); // Check if we're near the stack limit before we get anywhere near the - // transplanting code. - JS_CHECK_RECURSION(cx, return NS_ERROR_FAILURE); + // transplanting code. We use a conservative check since we'll use a little + // more space before we actually hit the critical "can't fail" path. + JS_CHECK_RECURSION_CONSERVATIVE(cx, return NS_ERROR_FAILURE); nsCOMPtr wsh = do_QueryInterface(aState); NS_ASSERTION(!aState || wsh, "What kind of weird state are you giving me here?"); diff --git a/dom/bindings/BindingUtils.cpp b/dom/bindings/BindingUtils.cpp index 06e44cace64b..afa2c69cae95 100644 --- a/dom/bindings/BindingUtils.cpp +++ b/dom/bindings/BindingUtils.cpp @@ -1741,8 +1741,9 @@ ReparentWrapper(JSContext* aCx, JS::Handle aObjArg) js::AssertSameCompartment(aCx, aObjArg); // Check if we're near the stack limit before we get anywhere near the - // transplanting code. - JS_CHECK_RECURSION(aCx, return NS_ERROR_FAILURE); + // transplanting code. We use a conservative check since we'll use a little + // more space before we actually hit the critical "can't fail" path. + JS_CHECK_RECURSION_CONSERVATIVE(aCx, return NS_ERROR_FAILURE); JS::Rooted aObj(aCx, aObjArg); const DOMJSClass* domClass = GetDOMClass(aObj); diff --git a/js/src/jsfriendapi.h b/js/src/jsfriendapi.h index 3344839dd297..bdeb4645c5a7 100644 --- a/js/src/jsfriendapi.h +++ b/js/src/jsfriendapi.h @@ -995,6 +995,7 @@ GetNativeStackLimit(JSContext *cx) * These macros report a stack overflow and run |onerror| if we are close to * using up the C stack. The JS_CHECK_CHROME_RECURSION variant gives us a little * extra space so that we can ensure that crucial code is able to run. + * JS_CHECK_RECURSION_CONSERVATIVE gives us a little less space. */ #define JS_CHECK_RECURSION(cx, onerror) \ @@ -1041,6 +1042,18 @@ GetNativeStackLimit(JSContext *cx) } \ JS_END_MACRO +#define JS_CHECK_RECURSION_CONSERVATIVE(cx, onerror) \ + JS_BEGIN_MACRO \ + int stackDummy_; \ + if (!JS_CHECK_STACK_SIZE_WITH_TOLERANCE(js::GetNativeStackLimit(cx), \ + &stackDummy_, \ + -1024 * sizeof(size_t))) \ + { \ + js_ReportOverRecursed(cx); \ + onerror; \ + } \ + JS_END_MACRO + JS_FRIEND_API(void) StartPCCountProfiling(JSContext *cx); diff --git a/js/xpconnect/src/XPCWrappedNative.cpp b/js/xpconnect/src/XPCWrappedNative.cpp index e77f13cf55d7..91d671e504d3 100644 --- a/js/xpconnect/src/XPCWrappedNative.cpp +++ b/js/xpconnect/src/XPCWrappedNative.cpp @@ -1073,9 +1073,10 @@ XPCWrappedNative::ReparentWrapperIfFound(XPCWrappedNativeScope* aOldScope, nsISupports* aCOMObj) { // Check if we're near the stack limit before we get anywhere near the - // transplanting code. + // transplanting code. We use a conservative check since we'll use a little + // more space before we actually hit the critical "can't fail" path. AutoJSContext cx; - JS_CHECK_RECURSION(cx, return NS_ERROR_FAILURE); + JS_CHECK_RECURSION_CONSERVATIVE(cx, return NS_ERROR_FAILURE); XPCNativeInterface* iface = XPCNativeInterface::GetISupports(); if (!iface)