mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-01 19:39:13 +00:00
Bug 1254230 kinda-fix. Make sure to never send script errors with stacks attached to the console service if the associated windows have already had FreeInnerObjects called on them. r=bholley
This commit is contained in:
parent
2e2d6cac3d
commit
3e5ab54341
@ -548,7 +548,8 @@ AutoJSAPI::ReportException()
|
||||
if (inner && jsReport.report()->errorNumber != JSMSG_OUT_OF_MEMORY) {
|
||||
DispatchScriptErrorEvent(inner, JS_GetRuntime(cx()), xpcReport, exn);
|
||||
} else {
|
||||
JS::Rooted<JSObject*> stack(cx(), xpc::FindExceptionStack(cx(), exn));
|
||||
JS::Rooted<JSObject*> stack(cx(),
|
||||
xpc::FindExceptionStackForConsoleReport(cx(), inner, exn));
|
||||
xpcReport->LogToConsoleWithStack(stack);
|
||||
}
|
||||
} else {
|
||||
|
@ -612,6 +612,7 @@ nsPIDOMWindow<T>::nsPIDOMWindow(nsPIDOMWindowOuter *aOuterWindow)
|
||||
mMayHavePaintEventListener(false), mMayHaveTouchEventListener(false),
|
||||
mMayHaveMouseEnterLeaveEventListener(false),
|
||||
mMayHavePointerEnterLeaveEventListener(false),
|
||||
mInnerObjectsFreed(false),
|
||||
mIsModalContentWindow(false),
|
||||
mIsActive(false), mIsBackground(false),
|
||||
mAudioMuted(false), mAudioVolume(1.0), mAudioCaptured(false),
|
||||
@ -1171,7 +1172,6 @@ nsGlobalWindow::nsGlobalWindow(nsGlobalWindow *aOuterWindow)
|
||||
#endif
|
||||
mShowFocusRingForContent(false),
|
||||
mFocusByKeyOccurred(false),
|
||||
mInnerObjectsFreed(false),
|
||||
mHasGamepad(false),
|
||||
#ifdef MOZ_GAMEPAD
|
||||
mHasSeenGamepadInput(false),
|
||||
|
@ -1731,10 +1731,6 @@ protected:
|
||||
// should be displayed.
|
||||
bool mFocusByKeyOccurred : 1;
|
||||
|
||||
// Ensure that a call to ResumeTimeouts() after FreeInnerObjects() does nothing.
|
||||
// This member is only used by inner windows.
|
||||
bool mInnerObjectsFreed : 1;
|
||||
|
||||
// Inner windows only.
|
||||
// Indicates whether this window wants gamepad input events
|
||||
bool mHasGamepad : 1;
|
||||
|
@ -231,12 +231,20 @@ namespace xpc {
|
||||
//
|
||||
// Note that the returned object is _not_ wrapped into the compartment of cx.
|
||||
JSObject*
|
||||
FindExceptionStack(JSContext* cx, JS::HandleValue exceptionValue)
|
||||
FindExceptionStackForConsoleReport(JSContext* cx,
|
||||
nsPIDOMWindowInner* win,
|
||||
JS::HandleValue exceptionValue)
|
||||
{
|
||||
if (!exceptionValue.isObject()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (win && win->InnerObjectsFreed()) {
|
||||
// Pretend like we have no stack, so we don't end up keeping the global
|
||||
// alive via the stack.
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
JS::RootedObject exceptionObject(cx, &exceptionValue.toObject());
|
||||
JSAutoCompartment ac(cx, exceptionObject);
|
||||
JS::RootedObject stackObject(cx, ExceptionStackOrNull(cx, exceptionObject));
|
||||
@ -472,7 +480,8 @@ public:
|
||||
}
|
||||
JSContext* cx = jsapi.cx();
|
||||
JS::Rooted<JS::Value> exn(cx, mError);
|
||||
JS::RootedObject stack(cx, xpc::FindExceptionStack(cx, exn));
|
||||
JS::RootedObject stack(cx,
|
||||
xpc::FindExceptionStackForConsoleReport(cx, win, exn));
|
||||
mReport->LogToConsoleWithStack(stack);
|
||||
} else {
|
||||
mReport->LogToConsole();
|
||||
@ -555,7 +564,8 @@ SystemErrorReporter(JSContext *cx, const char *message, JSErrorReport *report)
|
||||
if (!win || JSREPORT_IS_WARNING(xpcReport->mFlags) ||
|
||||
report->errorNumber == JSMSG_OUT_OF_MEMORY)
|
||||
{
|
||||
JS::Rooted<JSObject*> stack(cx, xpc::FindExceptionStack(cx, exception));
|
||||
JS::Rooted<JSObject*> stack(cx,
|
||||
xpc::FindExceptionStackForConsoleReport(cx, win, exception));
|
||||
xpcReport->LogToConsoleWithStack(stack);
|
||||
return;
|
||||
}
|
||||
|
@ -630,6 +630,12 @@ protected:
|
||||
bool mMayHaveMouseEnterLeaveEventListener;
|
||||
bool mMayHavePointerEnterLeaveEventListener;
|
||||
|
||||
// Used to detect whether we have called FreeInnerObjects() (e.g. to ensure
|
||||
// that a call to ResumeTimeouts() after FreeInnerObjects() does nothing).
|
||||
// This member is only used by inner windows.
|
||||
bool mInnerObjectsFreed;
|
||||
|
||||
|
||||
// This variable is used on both inner and outer windows (and they
|
||||
// should match).
|
||||
bool mIsModalContentWindow;
|
||||
@ -779,6 +785,13 @@ public:
|
||||
mMayHavePointerEnterLeaveEventListener = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether this has had inner objects freed.
|
||||
*/
|
||||
bool InnerObjectsFreed() const
|
||||
{
|
||||
return mInnerObjectsFreed;
|
||||
}
|
||||
|
||||
protected:
|
||||
void CreatePerformanceObjectIfNeeded();
|
||||
|
@ -550,8 +550,16 @@ DispatchScriptErrorEvent(nsPIDOMWindowInner* win, JSRuntime* rt, xpc::ErrorRepor
|
||||
// passed-in value does NOT necessarily have to be in the same compartment as
|
||||
// the passed-in JSContext. The returned stack, if any, may also not be in the
|
||||
// same compartment as either cx or exceptionValue.
|
||||
//
|
||||
// The "win" argument passed in here should be the same as the window whose
|
||||
// WindowID() is used to initialize the xpc::ErrorReport. This may be null, of
|
||||
// course. If it's not null, this function may return a null stack object if
|
||||
// the window is far enough gone, because in those cases we don't want to have
|
||||
// the stack in the console message keeping the window alive.
|
||||
JSObject*
|
||||
FindExceptionStack(JSContext* cx, JS::HandleValue exceptionValue);
|
||||
FindExceptionStackForConsoleReport(JSContext* cx,
|
||||
nsPIDOMWindowInner* win,
|
||||
JS::HandleValue exceptionValue);
|
||||
|
||||
// Return a name for the compartment.
|
||||
// This function makes reasonable efforts to make this name both mostly human-readable
|
||||
|
Loading…
x
Reference in New Issue
Block a user