Bug 1070842 - Remove ambiguous globals from xpc::ErrorReporter and make meanings explicit. r=bz

This commit is contained in:
Bobby Holley 2014-09-29 15:34:20 +02:00
parent e514b2b327
commit b0d5796cba
4 changed files with 27 additions and 62 deletions

View File

@ -351,17 +351,19 @@ NS_HandleScriptError(nsIScriptGlobalObject *aScriptGlobal,
class ScriptErrorEvent : public nsRunnable
{
public:
ScriptErrorEvent(JSRuntime* aRuntime,
ScriptErrorEvent(nsPIDOMWindow* aWindow,
JSRuntime* aRuntime,
xpc::ErrorReport* aReport,
JS::Handle<JS::Value> aError)
: mReport(aReport)
: mWindow(aWindow)
, mReport(aReport)
, mError(aRuntime, aError)
{}
NS_IMETHOD Run()
{
nsEventStatus status = nsEventStatus_eIgnore;
nsPIDOMWindow* win = mReport->mWindow;
nsPIDOMWindow* win = mWindow;
MOZ_ASSERT(win);
// First, notify the DOM that we have a script error, but only if
// our window is still the current inner.
@ -407,6 +409,7 @@ public:
}
private:
nsCOMPtr<nsPIDOMWindow> mWindow;
nsRefPtr<xpc::ErrorReport> mReport;
JS::PersistentRootedValue mError;
@ -467,12 +470,14 @@ SystemErrorReporter(JSContext *cx, const char *message, JSErrorReport *report)
if (globalObject) {
nsRefPtr<xpc::ErrorReport> xpcReport = new xpc::ErrorReport();
xpcReport->Init(report, message, globalObject);
bool isChrome = nsContentUtils::IsSystemPrincipal(globalObject->PrincipalOrNull());
nsCOMPtr<nsPIDOMWindow> win = do_QueryInterface(globalObject);
xpcReport->Init(report, message, isChrome, win ? win->WindowID() : 0);
// If we can't dispatch an event to a window, report it to the console
// directly. This includes the case where the error was an OOM, because
// triggering a scripted event handler is likely to generate further OOMs.
if (!xpcReport->mWindow || JSREPORT_IS_WARNING(xpcReport->mFlags) ||
if (!win || JSREPORT_IS_WARNING(xpcReport->mFlags) ||
report->errorNumber == JSMSG_OUT_OF_MEMORY)
{
xpcReport->LogToConsole();
@ -481,7 +486,7 @@ SystemErrorReporter(JSContext *cx, const char *message, JSErrorReport *report)
// Otherwise, we need to asynchronously invoke onerror before we can decide
// whether or not to report the error to the console.
nsContentUtils::AddScriptRunner(new ScriptErrorEvent(JS_GetRuntime(cx), xpcReport, exception));
nsContentUtils::AddScriptRunner(new ScriptErrorEvent(win, JS_GetRuntime(cx), xpcReport, exception));
}
}

View File

@ -1023,13 +1023,11 @@ Promise::MaybeReportRejected()
}
nsRefPtr<xpc::ErrorReport> xpcReport = new xpc::ErrorReport();
if (MOZ_LIKELY(NS_IsMainThread())) {
nsIGlobalObject* global = xpc::NativeGlobal(js::GetGlobalForObjectCrossCompartment(obj));
xpcReport->Init(report.report(), report.message(), global);
} else {
xpcReport->InitOnWorkerThread(report.report(), report.message(),
GetCurrentThreadWorkerPrivate()->IsChromeWorker());
}
bool isMainThread = MOZ_LIKELY(NS_IsMainThread());
bool isChrome = isMainThread ? nsContentUtils::IsSystemPrincipal(nsContentUtils::ObjectPrincipal(obj))
: GetCurrentThreadWorkerPrivate()->IsChromeWorker();
nsPIDOMWindow* win = isMainThread ? xpc::WindowGlobalOrNull(obj) : nullptr;
xpcReport->Init(report.report(), report.message(), isChrome, win ? win->WindowID() : 0);
// Now post an event to do the real reporting async
// Since Promises preserve their wrapper, it is essential to nsRefPtr<> the

View File

@ -187,38 +187,13 @@ nsXPConnect::IsISupportsDescendant(nsIInterfaceInfo* info)
}
void
xpc::ErrorReport::Init(JSErrorReport *aReport,
const char *aFallbackMessage,
nsIGlobalObject *aGlobal)
xpc::ErrorReport::Init(JSErrorReport *aReport, const char *aFallbackMessage,
bool aIsChrome, uint64_t aWindowID)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aGlobal);
mCategory = aIsChrome ? NS_LITERAL_CSTRING("chrome javascript")
: NS_LITERAL_CSTRING("content javascript");
mWindowID = aWindowID;
mGlobal = aGlobal;
mWindow = do_QueryInterface(mGlobal);
MOZ_ASSERT_IF(mWindow, mWindow->IsInnerWindow());
nsIPrincipal *prin = mGlobal->PrincipalOrNull();
mIsChrome = nsContentUtils::IsSystemPrincipal(prin);
InitInternal(aReport, aFallbackMessage);
}
void
xpc::ErrorReport::InitOnWorkerThread(JSErrorReport *aReport,
const char *aFallbackMessage,
bool aIsChrome)
{
MOZ_ASSERT(!NS_IsMainThread());
mIsChrome = aIsChrome;
InitInternal(aReport, aFallbackMessage);
}
void
xpc::ErrorReport::InitInternal(JSErrorReport *aReport,
const char *aFallbackMessage)
{
const char16_t* m = static_cast<const char16_t*>(aReport->ucmessage);
if (m) {
JSFlatString* name = js::GetErrorTypeName(CycleCollectedJSRuntime::Get()->Runtime(), aReport->exnType);
@ -296,8 +271,8 @@ xpc::ErrorReport::LogToConsole()
NS_ENSURE_TRUE_VOID(consoleService && errorObject);
nsresult rv = errorObject->InitWithWindowID(mErrorMsg, mFileName, mSourceLine,
mLineNumber, mColumn, mFlags, Category(),
mWindow ? mWindow->WindowID() : 0);
mLineNumber, mColumn, mFlags,
mCategory, mWindowID);
NS_ENSURE_SUCCESS_VOID(rv);
consoleService->LogMessage(errorObject);

View File

@ -505,7 +505,7 @@ class ErrorReport {
public:
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(ErrorReport);
ErrorReport() : mIsChrome(false)
ErrorReport() : mWindowID(0)
, mLineNumber(0)
, mColumn(0)
, mFlags(0)
@ -513,34 +513,21 @@ class ErrorReport {
{}
void Init(JSErrorReport *aReport, const char *aFallbackMessage,
nsIGlobalObject *aGlobal);
void InitOnWorkerThread(JSErrorReport *aReport, const char *aFallbackMessage,
bool aIsChrome);
bool aIsChrome, uint64_t aWindowID);
void LogToConsole();
private:
void InitInternal(JSErrorReport *aReport, const char *aFallbackMessage);
bool mIsChrome;
public:
const nsCString Category() {
return mIsChrome ? NS_LITERAL_CSTRING("chrome javascript")
: NS_LITERAL_CSTRING("content javascript");
}
nsCString mCategory;
nsString mErrorMsg;
nsString mFileName;
nsString mSourceLine;
uint64_t mWindowID;
uint32_t mLineNumber;
uint32_t mColumn;
uint32_t mFlags;
bool mIsMuted;
// These are both null for ErrorReports initialized on a worker thread.
nsCOMPtr<nsIGlobalObject> mGlobal;
nsCOMPtr<nsPIDOMWindow> mWindow;
private:
~ErrorReport() {}
};