mirror of
https://github.com/classilla/tenfourfox.git
synced 2025-02-18 21:30:42 +00:00
closes #391: M1342721 with some ideas from M1342439
This commit is contained in:
parent
cb70bd9e50
commit
faa6eb4c0c
@ -2396,9 +2396,7 @@ nsGlobalWindow::SetNewDocument(nsIDocument* aDocument,
|
||||
// transplanting code, since it has no good way to handle errors. This uses
|
||||
// the untrusted script limit, which is not strictly necessary since no
|
||||
// actual script should run.
|
||||
bool overrecursed = false;
|
||||
JS_CHECK_RECURSION_CONSERVATIVE_DONT_REPORT(cx, overrecursed = true);
|
||||
if (overrecursed) {
|
||||
if (MOZ_UNLIKELY(!js::CheckRecursionConservativeDontReport(cx))) {
|
||||
NS_WARNING("Overrecursion in SetNewDocument");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
@ -1891,7 +1891,9 @@ ReparentWrapper(JSContext* aCx, JS::Handle<JSObject*> aObjArg)
|
||||
// transplanting code, since it has no good way to handle errors. This uses
|
||||
// the untrusted script limit, which is not strictly necessary since no
|
||||
// actual script should run.
|
||||
JS_CHECK_RECURSION_CONSERVATIVE(aCx, return NS_ERROR_FAILURE);
|
||||
if (MOZ_UNLIKELY(!js::CheckRecursionConservative(aCx))) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
JS::Rooted<JSObject*> aObj(aCx, aObjArg);
|
||||
const DOMJSClass* domClass = GetDOMClass(aObj);
|
||||
|
@ -28,6 +28,8 @@
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#include "jscntxtinlines.h"
|
||||
|
||||
#include "irregexp/RegExpEngine.h"
|
||||
|
||||
#include "irregexp/NativeRegExpMacroAssembler.h"
|
||||
|
@ -149,6 +149,8 @@ class ExclusiveContext : public ContextFriendFields,
|
||||
return isJSContext();
|
||||
}
|
||||
|
||||
JSRuntime* ecRuntime() const { return runtime_; } // TenFourFox issue 391
|
||||
|
||||
bool runtimeMatches(JSRuntime* rt) const {
|
||||
return runtime_ == rt;
|
||||
}
|
||||
|
@ -19,8 +19,130 @@
|
||||
#include "vm/ProxyObject.h"
|
||||
#include "vm/Symbol.h"
|
||||
|
||||
MOZ_ALWAYS_INLINE bool
|
||||
JSContext::runningWithTrustedPrincipals() const
|
||||
{
|
||||
return !compartment() || compartment()->principals() == runtime()->trustedPrincipals();
|
||||
}
|
||||
|
||||
namespace js {
|
||||
|
||||
MOZ_ALWAYS_INLINE uintptr_t
|
||||
GetNativeStackLimit(JSContext* cx, StackKind kind, int extraAllowance = 0)
|
||||
{
|
||||
PerThreadDataFriendFields* mainThread =
|
||||
PerThreadDataFriendFields::getMainThread(GetRuntime(cx));
|
||||
uintptr_t limit = mainThread->nativeStackLimit[kind];
|
||||
#if JS_STACK_GROWTH_DIRECTION > 0
|
||||
limit += extraAllowance;
|
||||
#else
|
||||
limit -= extraAllowance;
|
||||
#endif
|
||||
return limit;
|
||||
}
|
||||
|
||||
// Needed for issue 391 -- see below
|
||||
MOZ_ALWAYS_INLINE uintptr_t
|
||||
GetNativeStackLimit(ExclusiveContext* cx, StackKind kind, int extraAllowance = 0)
|
||||
{
|
||||
PerThreadDataFriendFields* mainThread =
|
||||
PerThreadDataFriendFields::getMainThread(cx->ecRuntime());
|
||||
uintptr_t limit = mainThread->nativeStackLimit[kind];
|
||||
#if JS_STACK_GROWTH_DIRECTION > 0
|
||||
limit += extraAllowance;
|
||||
#else
|
||||
limit -= extraAllowance;
|
||||
#endif
|
||||
return limit;
|
||||
}
|
||||
|
||||
MOZ_ALWAYS_INLINE uintptr_t
|
||||
GetNativeStackLimit(JSContext* cx, int extraAllowance = 0)
|
||||
{
|
||||
StackKind kind = cx->runningWithTrustedPrincipals() ? StackForTrustedScript
|
||||
: StackForUntrustedScript;
|
||||
return GetNativeStackLimit(cx, kind, extraAllowance);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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 allows less space than any other check,
|
||||
* including a safety buffer (as in, it uses the untrusted limit and subtracts
|
||||
* a little more from it).
|
||||
*/
|
||||
|
||||
// Implement a fast path a la bug 1342439, but without all that churn.
|
||||
// Leave the old limit versions here just in case.
|
||||
// TenFourFox issue 391
|
||||
|
||||
#define JS_CHECK_RECURSION_LIMIT(cx, limit, onerror) \
|
||||
JS_BEGIN_MACRO \
|
||||
int stackDummy_; \
|
||||
if (MOZ_UNLIKELY(!JS_CHECK_STACK_SIZE(limit, &stackDummy_))) { \
|
||||
js::ReportOverRecursed(cx); \
|
||||
onerror; \
|
||||
} \
|
||||
JS_END_MACRO
|
||||
|
||||
#define JS_CHECK_RECURSION(cx, onerror) \
|
||||
JS_BEGIN_MACRO \
|
||||
int stackDummy_; \
|
||||
if (MOZ_UNLIKELY(!JS_CHECK_STACK_SIZE(js::GetNativeStackLimit(cx, js::StackForUntrustedScript), &stackDummy_))) { \
|
||||
if (MOZ_UNLIKELY(!JS_CHECK_STACK_SIZE(js::GetNativeStackLimit(cx), &stackDummy_))) {\
|
||||
js::ReportOverRecursed(cx); \
|
||||
onerror; \
|
||||
} \
|
||||
} \
|
||||
JS_END_MACRO
|
||||
|
||||
#define JS_CHECK_RECURSION_LIMIT_DONT_REPORT(cx, limit, onerror) \
|
||||
JS_BEGIN_MACRO \
|
||||
int stackDummy_; \
|
||||
if (MOZ_UNLIKELY(!JS_CHECK_STACK_SIZE(limit, &stackDummy_))) { \
|
||||
onerror; \
|
||||
} \
|
||||
JS_END_MACRO
|
||||
|
||||
#define JS_CHECK_RECURSION_DONT_REPORT(cx, onerror) \
|
||||
JS_BEGIN_MACRO \
|
||||
int stackDummy_; \
|
||||
if (MOZ_UNLIKELY(!JS_CHECK_STACK_SIZE(js::GetNativeStackLimit(cx, js::StackForUntrustedScript), &stackDummy_))) { \
|
||||
if (MOZ_UNLIKELY(!JS_CHECK_STACK_SIZE(js::GetNativeStackLimit(cx), &stackDummy_))) {\
|
||||
onerror; \
|
||||
} \
|
||||
} \
|
||||
JS_END_MACRO
|
||||
|
||||
#define JS_CHECK_RECURSION_WITH_SP_DONT_REPORT(cx, sp, onerror) \
|
||||
JS_BEGIN_MACRO \
|
||||
if (MOZ_UNLIKELY(!JS_CHECK_STACK_SIZE(js::GetNativeStackLimit(cx), sp))) { \
|
||||
onerror; \
|
||||
} \
|
||||
JS_END_MACRO
|
||||
|
||||
#define JS_CHECK_RECURSION_WITH_SP(cx, sp, onerror) \
|
||||
JS_BEGIN_MACRO \
|
||||
if (MOZ_UNLIKELY(!JS_CHECK_STACK_SIZE(js::GetNativeStackLimit(cx), sp))) { \
|
||||
js::ReportOverRecursed(cx); \
|
||||
onerror; \
|
||||
} \
|
||||
JS_END_MACRO
|
||||
|
||||
#define JS_CHECK_SYSTEM_RECURSION(cx, onerror) \
|
||||
JS_CHECK_RECURSION_LIMIT(cx, js::GetNativeStackLimit(cx, js::StackForSystemCode), onerror)
|
||||
|
||||
#define JS_CHECK_RECURSION_CONSERVATIVE(cx, onerror) \
|
||||
JS_CHECK_RECURSION_LIMIT(cx, \
|
||||
js::GetNativeStackLimit(cx, js::StackForUntrustedScript, -1024 * int(sizeof(size_t))), \
|
||||
onerror)
|
||||
|
||||
#define JS_CHECK_RECURSION_CONSERVATIVE_DONT_REPORT(cx, onerror) \
|
||||
JS_CHECK_RECURSION_LIMIT_DONT_REPORT(cx, \
|
||||
js::GetNativeStackLimit(cx, js::StackForUntrustedScript, -1024 * int(sizeof(size_t))), \
|
||||
onerror)
|
||||
|
||||
class CompartmentChecker
|
||||
{
|
||||
JSCompartment* compartment;
|
||||
@ -382,12 +504,6 @@ JSContext::setPendingException(js::Value v)
|
||||
MOZ_ASSERT_IF(v.isObject(), v.toObject().compartment() == compartment());
|
||||
}
|
||||
|
||||
inline bool
|
||||
JSContext::runningWithTrustedPrincipals() const
|
||||
{
|
||||
return !compartment() || compartment()->principals() == runtime()->trustedPrincipals();
|
||||
}
|
||||
|
||||
inline void
|
||||
js::ExclusiveContext::enterCompartment(JSCompartment* c)
|
||||
{
|
||||
|
@ -385,9 +385,24 @@ js::IsObjectInContextCompartment(JSObject* obj, const JSContext* cx)
|
||||
}
|
||||
|
||||
JS_FRIEND_API(bool)
|
||||
js::RunningWithTrustedPrincipals(JSContext* cx)
|
||||
js::CheckRecursion(JSContext* cx)
|
||||
{
|
||||
return cx->runningWithTrustedPrincipals();
|
||||
JS_CHECK_RECURSION(cx, return false);
|
||||
return true;
|
||||
}
|
||||
|
||||
JS_FRIEND_API(bool)
|
||||
js::CheckRecursionConservative(JSContext* cx)
|
||||
{
|
||||
JS_CHECK_RECURSION_CONSERVATIVE(cx, return false);
|
||||
return true;
|
||||
}
|
||||
|
||||
JS_FRIEND_API(bool)
|
||||
js::CheckRecursionConservativeDontReport(JSContext* cx)
|
||||
{
|
||||
JS_CHECK_RECURSION_CONSERVATIVE_DONT_REPORT(cx, return false);
|
||||
return true;
|
||||
}
|
||||
|
||||
JS_FRIEND_API(JSFunction*)
|
||||
|
@ -967,89 +967,13 @@ IsObjectInContextCompartment(JSObject* obj, const JSContext* cx);
|
||||
#define JSITER_SYMBOLSONLY 0x40 /* exclude string property keys */
|
||||
|
||||
JS_FRIEND_API(bool)
|
||||
RunningWithTrustedPrincipals(JSContext* cx);
|
||||
CheckRecursion(JSContext* cx);
|
||||
|
||||
MOZ_ALWAYS_INLINE uintptr_t
|
||||
GetNativeStackLimit(JSContext* cx, StackKind kind, int extraAllowance = 0)
|
||||
{
|
||||
PerThreadDataFriendFields* mainThread =
|
||||
PerThreadDataFriendFields::getMainThread(GetRuntime(cx));
|
||||
uintptr_t limit = mainThread->nativeStackLimit[kind];
|
||||
#if JS_STACK_GROWTH_DIRECTION > 0
|
||||
limit += extraAllowance;
|
||||
#else
|
||||
limit -= extraAllowance;
|
||||
#endif
|
||||
return limit;
|
||||
}
|
||||
JS_FRIEND_API(bool)
|
||||
CheckRecursionConservative(JSContext* cx);
|
||||
|
||||
MOZ_ALWAYS_INLINE uintptr_t
|
||||
GetNativeStackLimit(JSContext* cx, int extraAllowance = 0)
|
||||
{
|
||||
StackKind kind = RunningWithTrustedPrincipals(cx) ? StackForTrustedScript
|
||||
: StackForUntrustedScript;
|
||||
return GetNativeStackLimit(cx, kind, extraAllowance);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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 allows less space than any other check,
|
||||
* including a safety buffer (as in, it uses the untrusted limit and subtracts
|
||||
* a little more from it).
|
||||
*/
|
||||
|
||||
#define JS_CHECK_RECURSION_LIMIT(cx, limit, onerror) \
|
||||
JS_BEGIN_MACRO \
|
||||
int stackDummy_; \
|
||||
if (MOZ_UNLIKELY(!JS_CHECK_STACK_SIZE(limit, &stackDummy_))) { \
|
||||
js::ReportOverRecursed(cx); \
|
||||
onerror; \
|
||||
} \
|
||||
JS_END_MACRO
|
||||
|
||||
#define JS_CHECK_RECURSION(cx, onerror) \
|
||||
JS_CHECK_RECURSION_LIMIT(cx, js::GetNativeStackLimit(cx), onerror)
|
||||
|
||||
#define JS_CHECK_RECURSION_LIMIT_DONT_REPORT(cx, limit, onerror) \
|
||||
JS_BEGIN_MACRO \
|
||||
int stackDummy_; \
|
||||
if (MOZ_UNLIKELY(!JS_CHECK_STACK_SIZE(limit, &stackDummy_))) { \
|
||||
onerror; \
|
||||
} \
|
||||
JS_END_MACRO
|
||||
|
||||
#define JS_CHECK_RECURSION_DONT_REPORT(cx, onerror) \
|
||||
JS_CHECK_RECURSION_LIMIT_DONT_REPORT(cx, js::GetNativeStackLimit(cx), onerror)
|
||||
|
||||
#define JS_CHECK_RECURSION_WITH_SP_DONT_REPORT(cx, sp, onerror) \
|
||||
JS_BEGIN_MACRO \
|
||||
if (MOZ_UNLIKELY(!JS_CHECK_STACK_SIZE(js::GetNativeStackLimit(cx), sp))) { \
|
||||
onerror; \
|
||||
} \
|
||||
JS_END_MACRO
|
||||
|
||||
#define JS_CHECK_RECURSION_WITH_SP(cx, sp, onerror) \
|
||||
JS_BEGIN_MACRO \
|
||||
if (MOZ_UNLIKELY(!JS_CHECK_STACK_SIZE(js::GetNativeStackLimit(cx), sp))) { \
|
||||
js::ReportOverRecursed(cx); \
|
||||
onerror; \
|
||||
} \
|
||||
JS_END_MACRO
|
||||
|
||||
#define JS_CHECK_SYSTEM_RECURSION(cx, onerror) \
|
||||
JS_CHECK_RECURSION_LIMIT(cx, js::GetNativeStackLimit(cx, js::StackForSystemCode), onerror)
|
||||
|
||||
#define JS_CHECK_RECURSION_CONSERVATIVE(cx, onerror) \
|
||||
JS_CHECK_RECURSION_LIMIT(cx, \
|
||||
js::GetNativeStackLimit(cx, js::StackForUntrustedScript, -1024 * int(sizeof(size_t))), \
|
||||
onerror)
|
||||
|
||||
#define JS_CHECK_RECURSION_CONSERVATIVE_DONT_REPORT(cx, onerror) \
|
||||
JS_CHECK_RECURSION_LIMIT_DONT_REPORT(cx, \
|
||||
js::GetNativeStackLimit(cx, js::StackForUntrustedScript, -1024 * int(sizeof(size_t))), \
|
||||
onerror)
|
||||
JS_FRIEND_API(bool)
|
||||
CheckRecursionConservativeDontReport(JSContext* cx);
|
||||
|
||||
JS_FRIEND_API(void)
|
||||
StartPCCountProfiling(JSContext* cx);
|
||||
|
@ -258,7 +258,9 @@ XPCArrayHomogenizer::GetTypeForArray(JSContext* cx, HandleObject array,
|
||||
|
||||
bool XPCVariant::InitializeData(JSContext* cx)
|
||||
{
|
||||
JS_CHECK_RECURSION(cx, return false);
|
||||
if (MOZ_UNLIKELY(!js::CheckRecursion(cx))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
RootedValue val(cx, GetJSVal());
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user