diff options
Diffstat (limited to 'js/xpconnect')
-rw-r--r-- | js/xpconnect/idl/moz.build | 1 | ||||
-rw-r--r-- | js/xpconnect/idl/nsIScriptError.idl | 122 | ||||
-rw-r--r-- | js/xpconnect/src/XPCComponents.cpp | 2 | ||||
-rw-r--r-- | js/xpconnect/src/XPCConvert.cpp | 2 | ||||
-rw-r--r-- | js/xpconnect/src/XPCModule.h | 4 | ||||
-rw-r--r-- | js/xpconnect/src/XPCWrappedJSClass.cpp | 1 | ||||
-rw-r--r-- | js/xpconnect/src/XPCWrappedNativeInfo.cpp | 1 | ||||
-rw-r--r-- | js/xpconnect/src/moz.build | 3 | ||||
-rw-r--r-- | js/xpconnect/src/nsScriptError.cpp | 345 | ||||
-rw-r--r-- | js/xpconnect/src/nsScriptErrorWithStack.cpp | 118 | ||||
-rw-r--r-- | js/xpconnect/src/nsXPConnect.cpp | 142 | ||||
-rw-r--r-- | js/xpconnect/src/xpcprivate.h | 72 | ||||
-rw-r--r-- | js/xpconnect/src/xpcpublic.h | 58 | ||||
-rw-r--r-- | js/xpconnect/tests/chrome/test_bug1041626.xul | 3 | ||||
-rw-r--r-- | js/xpconnect/wrappers/WrapperFactory.cpp | 2 |
15 files changed, 164 insertions, 712 deletions
diff --git a/js/xpconnect/idl/moz.build b/js/xpconnect/idl/moz.build index 2438b1a5a..0808d3450 100644 --- a/js/xpconnect/idl/moz.build +++ b/js/xpconnect/idl/moz.build @@ -7,7 +7,6 @@ XPIDL_SOURCES += [ 'mozIJSSubScriptLoader.idl', 'nsIAddonInterposition.idl', - 'nsIScriptError.idl', 'nsIXPConnect.idl', 'nsIXPCScriptable.idl', 'xpccomponents.idl', diff --git a/js/xpconnect/idl/nsIScriptError.idl b/js/xpconnect/idl/nsIScriptError.idl deleted file mode 100644 index 468ca682f..000000000 --- a/js/xpconnect/idl/nsIScriptError.idl +++ /dev/null @@ -1,122 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* - * nsIConsoleMessage subclass for representing JavaScript errors and warnings. - */ - - -#include "nsISupports.idl" -#include "nsIConsoleMessage.idl" - -%{C++ -#include "nsStringGlue.h" // for nsDependentCString -%} - -[scriptable, uuid(361be358-76f0-47aa-b37b-6ad833599e8d)] -interface nsIScriptError : nsIConsoleMessage -{ - /** pseudo-flag for default case */ - const unsigned long errorFlag = 0x0; - - /** message is warning */ - const unsigned long warningFlag = 0x1; - - /** exception was thrown for this case - exception-aware hosts can ignore */ - const unsigned long exceptionFlag = 0x2; - - // XXX check how strict is implemented these days. - /** error or warning is due to strict option */ - const unsigned long strictFlag = 0x4; - - /** just a log message */ - const unsigned long infoFlag = 0x8; - - /** - * The error message without any context/line number information. - * - * @note nsIConsoleMessage.message will return the error formatted - * with file/line information. - */ - readonly attribute AString errorMessage; - - readonly attribute AString sourceName; - readonly attribute AString sourceLine; - readonly attribute uint32_t lineNumber; - readonly attribute uint32_t columnNumber; - readonly attribute uint32_t flags; - - /** - * Categories I know about - - * XUL javascript - * content javascript (both of these from nsDocShell, currently) - * system javascript (errors in JS components and other system JS) - */ - readonly attribute string category; - - /* Get the window id this was initialized with. Zero will be - returned if init() was used instead of initWithWindowID(). */ - readonly attribute unsigned long long outerWindowID; - - /* Get the inner window id this was initialized with. Zero will be - returned if init() was used instead of initWithWindowID(). */ - readonly attribute unsigned long long innerWindowID; - - readonly attribute boolean isFromPrivateWindow; - - attribute jsval stack; - - /** - * The name of a template string, as found in js.msg, associated with the - * error message. - */ - attribute AString errorMessageName; - - - void init(in AString message, - in AString sourceName, - in AString sourceLine, - in uint32_t lineNumber, - in uint32_t columnNumber, - in uint32_t flags, - in string category); - - /* This should be called instead of nsIScriptError.init to - initialize with a window id. The window id should be for the - inner window associated with this error. */ - void initWithWindowID(in AString message, - in AString sourceName, - in AString sourceLine, - in uint32_t lineNumber, - in uint32_t columnNumber, - in uint32_t flags, - in ACString category, - in unsigned long long innerWindowID); -%{C++ - // This overload allows passing a literal string for category. - template<uint32_t N> - nsresult InitWithWindowID(const nsAString& message, - const nsAString& sourceName, - const nsAString& sourceLine, - uint32_t lineNumber, - uint32_t columnNumber, - uint32_t flags, - const char (&c)[N], - uint64_t aInnerWindowID) - { - nsDependentCString category(c, N - 1); - return InitWithWindowID(message, sourceName, sourceLine, lineNumber, - columnNumber, flags, category, aInnerWindowID); - } -%} - -}; - -%{ C++ -#define NS_SCRIPTERROR_CID \ -{ 0x1950539a, 0x90f0, 0x4d22, { 0xb5, 0xaf, 0x71, 0x32, 0x9c, 0x68, 0xfa, 0x35 }} - -#define NS_SCRIPTERROR_CONTRACTID "@mozilla.org/scripterror;1" -%} diff --git a/js/xpconnect/src/XPCComponents.cpp b/js/xpconnect/src/XPCComponents.cpp index dbb63092e..07ce7460b 100644 --- a/js/xpconnect/src/XPCComponents.cpp +++ b/js/xpconnect/src/XPCComponents.cpp @@ -34,9 +34,11 @@ #include "nsDOMClassInfo.h" #include "ShimInterfaceInfo.h" #include "nsIAddonInterposition.h" +#include "nsIScriptError.h" #include "nsISimpleEnumerator.h" #include "nsPIDOMWindow.h" #include "nsGlobalWindow.h" +#include "nsScriptError.h" using namespace mozilla; using namespace JS; diff --git a/js/xpconnect/src/XPCConvert.cpp b/js/xpconnect/src/XPCConvert.cpp index 37932b452..77f09f4a5 100644 --- a/js/xpconnect/src/XPCConvert.cpp +++ b/js/xpconnect/src/XPCConvert.cpp @@ -11,9 +11,11 @@ #include "xpcprivate.h" #include "nsIAtom.h" +#include "nsIScriptError.h" #include "nsWrapperCache.h" #include "nsJSUtils.h" #include "nsQueryObject.h" +#include "nsScriptError.h" #include "WrapperFactory.h" #include "nsWrapperCacheInlines.h" diff --git a/js/xpconnect/src/XPCModule.h b/js/xpconnect/src/XPCModule.h index d62764625..506e8945a 100644 --- a/js/xpconnect/src/XPCModule.h +++ b/js/xpconnect/src/XPCModule.h @@ -23,7 +23,6 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(nsJSID) NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsIXPConnect, nsXPConnect::GetSingleton) -NS_GENERIC_FACTORY_CONSTRUCTOR(nsScriptError) NS_GENERIC_FACTORY_CONSTRUCTOR(mozJSComponentLoader) NS_GENERIC_FACTORY_CONSTRUCTOR(mozJSSubScriptLoader) @@ -31,14 +30,12 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(mozJSSubScriptLoader) NS_DEFINE_NAMED_CID(NS_JS_ID_CID); NS_DEFINE_NAMED_CID(NS_XPCONNECT_CID); NS_DEFINE_NAMED_CID(NS_XPCEXCEPTION_CID); -NS_DEFINE_NAMED_CID(NS_SCRIPTERROR_CID); NS_DEFINE_NAMED_CID(MOZJSCOMPONENTLOADER_CID); NS_DEFINE_NAMED_CID(MOZ_JSSUBSCRIPTLOADER_CID); #define XPCONNECT_CIDENTRIES \ { &kNS_JS_ID_CID, false, nullptr, nsJSIDConstructor }, \ { &kNS_XPCONNECT_CID, false, nullptr, nsIXPConnectConstructor }, \ - { &kNS_SCRIPTERROR_CID, false, nullptr, nsScriptErrorConstructor }, \ { &kMOZJSCOMPONENTLOADER_CID, false, nullptr, mozJSComponentLoaderConstructor },\ { &kMOZ_JSSUBSCRIPTLOADER_CID, false, nullptr, mozJSSubScriptLoaderConstructor }, @@ -46,7 +43,6 @@ NS_DEFINE_NAMED_CID(MOZ_JSSUBSCRIPTLOADER_CID); { XPC_ID_CONTRACTID, &kNS_JS_ID_CID }, \ { XPC_XPCONNECT_CONTRACTID, &kNS_XPCONNECT_CID }, \ { XPC_CONTEXT_STACK_CONTRACTID, &kNS_XPCONNECT_CID }, \ - { NS_SCRIPTERROR_CONTRACTID, &kNS_SCRIPTERROR_CID }, \ { MOZJSCOMPONENTLOADER_CONTRACTID, &kMOZJSCOMPONENTLOADER_CID }, \ { MOZJSSUBSCRIPTLOADER_CONTRACTID, &kMOZ_JSSUBSCRIPTLOADER_CID }, diff --git a/js/xpconnect/src/XPCWrappedJSClass.cpp b/js/xpconnect/src/XPCWrappedJSClass.cpp index 2c9fd66bc..e90373e3d 100644 --- a/js/xpconnect/src/XPCWrappedJSClass.cpp +++ b/js/xpconnect/src/XPCWrappedJSClass.cpp @@ -10,6 +10,7 @@ #include "jsprf.h" #include "nsArrayEnumerator.h" #include "nsContentUtils.h" +#include "nsIScriptError.h" #include "nsWrapperCache.h" #include "AccessCheck.h" #include "nsJSUtils.h" diff --git a/js/xpconnect/src/XPCWrappedNativeInfo.cpp b/js/xpconnect/src/XPCWrappedNativeInfo.cpp index 302454fb5..4b0330af6 100644 --- a/js/xpconnect/src/XPCWrappedNativeInfo.cpp +++ b/js/xpconnect/src/XPCWrappedNativeInfo.cpp @@ -11,6 +11,7 @@ #include "mozilla/MemoryReporting.h" #include "mozilla/XPTInterfaceInfoManager.h" +#include "nsIScriptError.h" #include "nsPrintfCString.h" using namespace JS; diff --git a/js/xpconnect/src/moz.build b/js/xpconnect/src/moz.build index 7e787bb56..7d9cd5b37 100644 --- a/js/xpconnect/src/moz.build +++ b/js/xpconnect/src/moz.build @@ -14,8 +14,6 @@ EXPORTS += [ UNIFIED_SOURCES += [ 'ExportHelpers.cpp', - 'nsScriptError.cpp', - 'nsScriptErrorWithStack.cpp', 'nsXPConnect.cpp', 'Sandbox.cpp', 'XPCCallContext.cpp', @@ -58,6 +56,7 @@ LOCAL_INCLUDES += [ '../wrappers', '/caps', '/dom/base', + '/dom/bindings', '/dom/html', '/dom/svg', '/dom/workers', diff --git a/js/xpconnect/src/nsScriptError.cpp b/js/xpconnect/src/nsScriptError.cpp deleted file mode 100644 index ff687bc44..000000000 --- a/js/xpconnect/src/nsScriptError.cpp +++ /dev/null @@ -1,345 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* vim: set ts=8 sts=4 et sw=4 tw=99: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* - * nsIScriptError implementation. Defined here, lacking a JS-specific - * place to put XPCOM things. - */ - -#include "xpcprivate.h" -#include "jsprf.h" -#include "MainThreadUtils.h" -#include "mozilla/Assertions.h" -#include "nsGlobalWindow.h" -#include "nsPIDOMWindow.h" -#include "nsILoadContext.h" -#include "nsIDocShell.h" -#include "nsIScriptError.h" -#include "nsISensitiveInfoHiddenURI.h" - -static_assert(nsIScriptError::errorFlag == JSREPORT_ERROR && - nsIScriptError::warningFlag == JSREPORT_WARNING && - nsIScriptError::exceptionFlag == JSREPORT_EXCEPTION && - nsIScriptError::strictFlag == JSREPORT_STRICT && - nsIScriptError::infoFlag == JSREPORT_USER_1, - "flags should be consistent"); - -nsScriptErrorBase::nsScriptErrorBase() - : mMessage(), - mMessageName(), - mSourceName(), - mLineNumber(0), - mSourceLine(), - mColumnNumber(0), - mFlags(0), - mCategory(), - mOuterWindowID(0), - mInnerWindowID(0), - mTimeStamp(0), - mInitializedOnMainThread(false), - mIsFromPrivateWindow(false) -{ -} - -nsScriptErrorBase::~nsScriptErrorBase() {} - -void -nsScriptErrorBase::InitializeOnMainThread() -{ - MOZ_ASSERT(NS_IsMainThread()); - MOZ_ASSERT(!mInitializedOnMainThread); - - if (mInnerWindowID) { - nsGlobalWindow* window = - nsGlobalWindow::GetInnerWindowWithId(mInnerWindowID); - if (window) { - nsPIDOMWindowOuter* outer = window->GetOuterWindow(); - if (outer) - mOuterWindowID = outer->WindowID(); - - nsIDocShell* docShell = window->GetDocShell(); - nsCOMPtr<nsILoadContext> loadContext = do_QueryInterface(docShell); - - if (loadContext) { - // Never mark exceptions from chrome windows as having come from - // private windows, since we always want them to be reported. - nsIPrincipal* winPrincipal = window->GetPrincipal(); - mIsFromPrivateWindow = loadContext->UsePrivateBrowsing() && - !nsContentUtils::IsSystemPrincipal(winPrincipal); - } - } - } - - mInitializedOnMainThread = true; -} - -// nsIConsoleMessage methods -NS_IMETHODIMP -nsScriptErrorBase::GetMessageMoz(char16_t** result) { - nsresult rv; - - nsAutoCString message; - rv = ToString(message); - if (NS_FAILED(rv)) - return rv; - - *result = UTF8ToNewUnicode(message); - if (!*result) - return NS_ERROR_OUT_OF_MEMORY; - - return NS_OK; -} - - -NS_IMETHODIMP -nsScriptErrorBase::GetLogLevel(uint32_t* aLogLevel) -{ - if (mFlags & (uint32_t)nsIScriptError::infoFlag) { - *aLogLevel = nsIConsoleMessage::info; - } else if (mFlags & (uint32_t)nsIScriptError::warningFlag) { - *aLogLevel = nsIConsoleMessage::warn; - } else { - *aLogLevel = nsIConsoleMessage::error; - } - return NS_OK; -} - -// nsIScriptError methods -NS_IMETHODIMP -nsScriptErrorBase::GetErrorMessage(nsAString& aResult) { - aResult.Assign(mMessage); - return NS_OK; -} - -NS_IMETHODIMP -nsScriptErrorBase::GetSourceName(nsAString& aResult) { - aResult.Assign(mSourceName); - return NS_OK; -} - -NS_IMETHODIMP -nsScriptErrorBase::GetSourceLine(nsAString& aResult) { - aResult.Assign(mSourceLine); - return NS_OK; -} - -NS_IMETHODIMP -nsScriptErrorBase::GetLineNumber(uint32_t* result) { - *result = mLineNumber; - return NS_OK; -} - -NS_IMETHODIMP -nsScriptErrorBase::GetColumnNumber(uint32_t* result) { - *result = mColumnNumber; - return NS_OK; -} - -NS_IMETHODIMP -nsScriptErrorBase::GetFlags(uint32_t* result) { - *result = mFlags; - return NS_OK; -} - -NS_IMETHODIMP -nsScriptErrorBase::GetCategory(char** result) { - *result = ToNewCString(mCategory); - return NS_OK; -} - -NS_IMETHODIMP -nsScriptErrorBase::GetStack(JS::MutableHandleValue aStack) { - aStack.setUndefined(); - return NS_OK; -} - -NS_IMETHODIMP -nsScriptErrorBase::SetStack(JS::HandleValue aStack) { - return NS_OK; -} - -NS_IMETHODIMP -nsScriptErrorBase::GetErrorMessageName(nsAString& aErrorMessageName) { - aErrorMessageName = mMessageName; - return NS_OK; -} - -NS_IMETHODIMP -nsScriptErrorBase::SetErrorMessageName(const nsAString& aErrorMessageName) { - mMessageName = aErrorMessageName; - return NS_OK; -} - -NS_IMETHODIMP -nsScriptErrorBase::Init(const nsAString& message, - const nsAString& sourceName, - const nsAString& sourceLine, - uint32_t lineNumber, - uint32_t columnNumber, - uint32_t flags, - const char* category) -{ - return InitWithWindowID(message, sourceName, sourceLine, lineNumber, - columnNumber, flags, - category ? nsDependentCString(category) - : EmptyCString(), - 0); -} - -NS_IMETHODIMP -nsScriptErrorBase::InitWithWindowID(const nsAString& message, - const nsAString& sourceName, - const nsAString& sourceLine, - uint32_t lineNumber, - uint32_t columnNumber, - uint32_t flags, - const nsACString& category, - uint64_t aInnerWindowID) -{ - mMessage.Assign(message); - - if (!sourceName.IsEmpty()) { - mSourceName.Assign(sourceName); - - nsCOMPtr<nsIURI> uri; - nsAutoCString pass; - if (NS_SUCCEEDED(NS_NewURI(getter_AddRefs(uri), sourceName)) && - NS_SUCCEEDED(uri->GetPassword(pass)) && - !pass.IsEmpty()) { - nsCOMPtr<nsISensitiveInfoHiddenURI> safeUri = - do_QueryInterface(uri); - - nsAutoCString loc; - if (safeUri && - NS_SUCCEEDED(safeUri->GetSensitiveInfoHiddenSpec(loc))) { - mSourceName.Assign(NS_ConvertUTF8toUTF16(loc)); - } - } - } - - mLineNumber = lineNumber; - mSourceLine.Assign(sourceLine); - mColumnNumber = columnNumber; - mFlags = flags; - mCategory = category; - mTimeStamp = JS_Now() / 1000; - mInnerWindowID = aInnerWindowID; - - if (aInnerWindowID && NS_IsMainThread()) { - InitializeOnMainThread(); - } - - return NS_OK; -} - -NS_IMETHODIMP -nsScriptErrorBase::ToString(nsACString& /*UTF8*/ aResult) -{ - static const char format0[] = - "[%s: \"%s\" {file: \"%s\" line: %d column: %d source: \"%s\"}]"; - static const char format1[] = - "[%s: \"%s\" {file: \"%s\" line: %d}]"; - static const char format2[] = - "[%s: \"%s\"]"; - - static const char error[] = "JavaScript Error"; - static const char warning[] = "JavaScript Warning"; - - const char* severity = !(mFlags & JSREPORT_WARNING) ? error : warning; - - char* temp; - char* tempMessage = nullptr; - char* tempSourceName = nullptr; - char* tempSourceLine = nullptr; - - if (!mMessage.IsEmpty()) - tempMessage = ToNewUTF8String(mMessage); - if (!mSourceName.IsEmpty()) - // Use at most 512 characters from mSourceName. - tempSourceName = ToNewUTF8String(StringHead(mSourceName, 512)); - if (!mSourceLine.IsEmpty()) - // Use at most 512 characters from mSourceLine. - tempSourceLine = ToNewUTF8String(StringHead(mSourceLine, 512)); - - if (nullptr != tempSourceName && nullptr != tempSourceLine) - temp = JS_smprintf(format0, - severity, - tempMessage, - tempSourceName, - mLineNumber, - mColumnNumber, - tempSourceLine); - else if (!mSourceName.IsEmpty()) - temp = JS_smprintf(format1, - severity, - tempMessage, - tempSourceName, - mLineNumber); - else - temp = JS_smprintf(format2, - severity, - tempMessage); - - if (nullptr != tempMessage) - free(tempMessage); - if (nullptr != tempSourceName) - free(tempSourceName); - if (nullptr != tempSourceLine) - free(tempSourceLine); - - if (!temp) - return NS_ERROR_OUT_OF_MEMORY; - - aResult.Assign(temp); - JS_smprintf_free(temp); - return NS_OK; -} - -NS_IMETHODIMP -nsScriptErrorBase::GetOuterWindowID(uint64_t* aOuterWindowID) -{ - NS_WARNING_ASSERTION(NS_IsMainThread() || mInitializedOnMainThread, - "This can't be safely determined off the main thread, " - "returning an inaccurate value!"); - - if (!mInitializedOnMainThread && NS_IsMainThread()) { - InitializeOnMainThread(); - } - - *aOuterWindowID = mOuterWindowID; - return NS_OK; -} - -NS_IMETHODIMP -nsScriptErrorBase::GetInnerWindowID(uint64_t* aInnerWindowID) -{ - *aInnerWindowID = mInnerWindowID; - return NS_OK; -} - -NS_IMETHODIMP -nsScriptErrorBase::GetTimeStamp(int64_t* aTimeStamp) -{ - *aTimeStamp = mTimeStamp; - return NS_OK; -} - -NS_IMETHODIMP -nsScriptErrorBase::GetIsFromPrivateWindow(bool* aIsFromPrivateWindow) -{ - NS_WARNING_ASSERTION(NS_IsMainThread() || mInitializedOnMainThread, - "This can't be safely determined off the main thread, " - "returning an inaccurate value!"); - - if (!mInitializedOnMainThread && NS_IsMainThread()) { - InitializeOnMainThread(); - } - - *aIsFromPrivateWindow = mIsFromPrivateWindow; - return NS_OK; -} - -NS_IMPL_ISUPPORTS(nsScriptError, nsIConsoleMessage, nsIScriptError) diff --git a/js/xpconnect/src/nsScriptErrorWithStack.cpp b/js/xpconnect/src/nsScriptErrorWithStack.cpp deleted file mode 100644 index 50407da23..000000000 --- a/js/xpconnect/src/nsScriptErrorWithStack.cpp +++ /dev/null @@ -1,118 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* vim: set ts=8 sts=4 et sw=4 tw=99: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* - * nsScriptErrorWithStack implementation. - * a main-thread-only, cycle-collected subclass of nsScriptErrorBase - * that can store a SavedFrame stack trace object. - */ - -#include "xpcprivate.h" -#include "MainThreadUtils.h" -#include "mozilla/Assertions.h" -#include "nsGlobalWindow.h" -#include "nsCycleCollectionParticipant.h" - - -namespace { - -static nsCString -FormatStackString(JSContext* cx, HandleObject aStack) { - JS::RootedString formattedStack(cx); - - if (!JS::BuildStackString(cx, aStack, &formattedStack)) { - return nsCString(); - } - - nsAutoJSString stackJSString; - if (!stackJSString.init(cx, formattedStack)) { - return nsCString(); - } - - return NS_ConvertUTF16toUTF8(stackJSString.get()); -} - -} - - -NS_IMPL_CYCLE_COLLECTION_CLASS(nsScriptErrorWithStack) - -NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsScriptErrorWithStack) - tmp->mStack = nullptr; -NS_IMPL_CYCLE_COLLECTION_UNLINK_END - -NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsScriptErrorWithStack) -NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END - -NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(nsScriptErrorWithStack) - NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mStack) -NS_IMPL_CYCLE_COLLECTION_TRACE_END - -NS_IMPL_CYCLE_COLLECTING_ADDREF(nsScriptErrorWithStack) -NS_IMPL_CYCLE_COLLECTING_RELEASE(nsScriptErrorWithStack) - -NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsScriptErrorWithStack) - NS_INTERFACE_MAP_ENTRY(nsISupports) - NS_INTERFACE_MAP_ENTRY(nsIConsoleMessage) - NS_INTERFACE_MAP_ENTRY(nsIScriptError) -NS_INTERFACE_MAP_END - -nsScriptErrorWithStack::nsScriptErrorWithStack(JS::HandleObject aStack) - : mStack(aStack) -{ - MOZ_ASSERT(NS_IsMainThread(), "You can't use this class on workers."); - mozilla::HoldJSObjects(this); -} - -nsScriptErrorWithStack::~nsScriptErrorWithStack() { - mozilla::DropJSObjects(this); -} - -NS_IMETHODIMP -nsScriptErrorWithStack::Init(const nsAString& message, - const nsAString& sourceName, - const nsAString& sourceLine, - uint32_t lineNumber, - uint32_t columnNumber, - uint32_t flags, - const char* category) -{ - MOZ_CRASH("nsScriptErrorWithStack requires to be initialized with a document, by using InitWithWindowID"); -} - -NS_IMETHODIMP -nsScriptErrorWithStack::GetStack(JS::MutableHandleValue aStack) { - aStack.setObjectOrNull(mStack); - return NS_OK; -} - -NS_IMETHODIMP -nsScriptErrorWithStack::ToString(nsACString& /*UTF8*/ aResult) -{ - MOZ_ASSERT(NS_IsMainThread()); - - nsCString message; - nsresult rv = nsScriptErrorBase::ToString(message); - NS_ENSURE_SUCCESS(rv, rv); - - if (!mStack) { - aResult.Assign(message); - return NS_OK; - } - - AutoJSAPI jsapi; - if (!jsapi.Init(mStack)) { - return NS_ERROR_FAILURE; - } - - JSContext* cx = jsapi.cx(); - RootedObject stack(cx, mStack); - nsCString stackString = FormatStackString(cx, stack); - nsCString combined = message + NS_LITERAL_CSTRING("\n") + stackString; - aResult.Assign(combined); - - return NS_OK; -} diff --git a/js/xpconnect/src/nsXPConnect.cpp b/js/xpconnect/src/nsXPConnect.cpp index 0466175b1..0d1a6be0a 100644 --- a/js/xpconnect/src/nsXPConnect.cpp +++ b/js/xpconnect/src/nsXPConnect.cpp @@ -33,7 +33,9 @@ #include "nsIObjectOutputStream.h" #include "nsScriptSecurityManager.h" #include "nsIPermissionManager.h" +#include "nsIScriptError.h" #include "nsContentUtils.h" +#include "nsScriptError.h" #include "jsfriendapi.h" using namespace mozilla; @@ -170,9 +172,31 @@ nsXPConnect::IsISupportsDescendant(nsIInterfaceInfo* info) } void +xpc::ErrorBase::Init(JSErrorBase* aReport) +{ + if (!aReport->filename) { + mFileName.SetIsVoid(true); + } else { + mFileName.AssignWithConversion(aReport->filename); + } + + mLineNumber = aReport->lineno; + mColumn = aReport->column; +} + +void +xpc::ErrorNote::Init(JSErrorNotes::Note* aNote) +{ + xpc::ErrorBase::Init(aNote); + + ErrorNoteToMessageString(aNote, mErrorMsg); +} + +void xpc::ErrorReport::Init(JSErrorReport* aReport, const char* aToStringResult, bool aIsChrome, uint64_t aWindowID) { + xpc::ErrorBase::Init(aReport); mCategory = aIsChrome ? NS_LITERAL_CSTRING("chrome javascript") : NS_LITERAL_CSTRING("content javascript"); mWindowID = aWindowID; @@ -182,12 +206,6 @@ xpc::ErrorReport::Init(JSErrorReport* aReport, const char* aToStringResult, AppendUTF8toUTF16(aToStringResult, mErrorMsg); } - if (!aReport->filename) { - mFileName.SetIsVoid(true); - } else { - mFileName.AssignWithConversion(aReport->filename); - } - mSourceLine.Assign(aReport->linebuf(), aReport->linebufLength()); const JSErrorFormatString* efs = js::GetErrorMessage(nullptr, aReport->errorNumber); @@ -197,10 +215,20 @@ xpc::ErrorReport::Init(JSErrorReport* aReport, const char* aToStringResult, mErrorMsgName.AssignASCII(efs->name); } - mLineNumber = aReport->lineno; - mColumn = aReport->column; mFlags = aReport->flags; mIsMuted = aReport->isMuted; + + if (aReport->notes) { + if (!mNotes.SetLength(aReport->notes->length(), fallible)) { + return; + } + + size_t i = 0; + for (auto&& note : *aReport->notes) { + mNotes.ElementAt(i).Init(note.get()); + i++; + } + } } void @@ -226,6 +254,59 @@ xpc::ErrorReport::Init(JSContext* aCx, mozilla::dom::Exception* aException, static LazyLogModule gJSDiagnostics("JSDiagnostics"); void +xpc::ErrorBase::AppendErrorDetailsTo(nsCString& error) +{ + error.Append(NS_LossyConvertUTF16toASCII(mFileName)); + error.AppendLiteral(", line "); + error.AppendInt(mLineNumber, 10); + error.AppendLiteral(": "); + error.Append(NS_LossyConvertUTF16toASCII(mErrorMsg)); +} + +void +xpc::ErrorNote::LogToStderr() +{ + if (!nsContentUtils::DOMWindowDumpEnabled()) { + return; + } + + nsAutoCString error; + error.AssignLiteral("JavaScript note: "); + AppendErrorDetailsTo(error); + + fprintf(stderr, "%s\n", error.get()); + fflush(stderr); +} + +void +xpc::ErrorReport::LogToStderr() +{ + if (!nsContentUtils::DOMWindowDumpEnabled()) { + return; + } + + nsAutoCString error; + error.AssignLiteral("JavaScript "); + if (JSREPORT_IS_STRICT(mFlags)) { + error.AppendLiteral("strict "); + } + if (JSREPORT_IS_WARNING(mFlags)) { + error.AppendLiteral("warning: "); + } else { + error.AppendLiteral("error: "); + } + AppendErrorDetailsTo(error); + + fprintf(stderr, "%s\n", error.get()); + fflush(stderr); + + for (size_t i = 0, len = mNotes.Length(); i < len; i++) { + ErrorNote& note = mNotes[i]; + note.LogToStderr(); + } +} + +void xpc::ErrorReport::LogToConsole() { LogToConsoleWithStack(nullptr); @@ -233,25 +314,7 @@ xpc::ErrorReport::LogToConsole() void xpc::ErrorReport::LogToConsoleWithStack(JS::HandleObject aStack) { - // Log to stdout. - if (nsContentUtils::DOMWindowDumpEnabled()) { - nsAutoCString error; - error.AssignLiteral("JavaScript "); - if (JSREPORT_IS_STRICT(mFlags)) - error.AppendLiteral("strict "); - if (JSREPORT_IS_WARNING(mFlags)) - error.AppendLiteral("warning: "); - else - error.AppendLiteral("error: "); - error.Append(NS_LossyConvertUTF16toASCII(mFileName)); - error.AppendLiteral(", line "); - error.AppendInt(mLineNumber, 10); - error.AppendLiteral(": "); - error.Append(NS_LossyConvertUTF16toASCII(mErrorMsg)); - - fprintf(stderr, "%s\n", error.get()); - fflush(stderr); - } + LogToStderr(); MOZ_LOG(gJSDiagnostics, JSREPORT_IS_WARNING(mFlags) ? LogLevel::Warning : LogLevel::Error, @@ -263,8 +326,9 @@ xpc::ErrorReport::LogToConsoleWithStack(JS::HandleObject aStack) // mechanisms. nsCOMPtr<nsIConsoleService> consoleService = do_GetService(NS_CONSOLESERVICE_CONTRACTID); + NS_ENSURE_TRUE_VOID(consoleService); - nsCOMPtr<nsIScriptError> errorObject; + RefPtr<nsScriptErrorBase> errorObject; if (mWindowID && aStack) { // Only set stack on messages related to a document // As we cache messages in the console service, @@ -275,18 +339,38 @@ xpc::ErrorReport::LogToConsoleWithStack(JS::HandleObject aStack) errorObject = new nsScriptError(); } errorObject->SetErrorMessageName(mErrorMsgName); - NS_ENSURE_TRUE_VOID(consoleService); nsresult rv = errorObject->InitWithWindowID(mErrorMsg, mFileName, mSourceLine, mLineNumber, mColumn, mFlags, mCategory, mWindowID); NS_ENSURE_SUCCESS_VOID(rv); + + for (size_t i = 0, len = mNotes.Length(); i < len; i++) { + ErrorNote& note = mNotes[i]; + + nsScriptErrorNote* noteObject = new nsScriptErrorNote(); + noteObject->Init(note.mErrorMsg, note.mFileName, + note.mLineNumber, note.mColumn); + errorObject->AddNote(noteObject); + } + consoleService->LogMessage(errorObject); } /* static */ void +xpc::ErrorNote::ErrorNoteToMessageString(JSErrorNotes::Note* aNote, + nsAString& aString) +{ + aString.Truncate(); + if (aNote->message()) { + aString.Append(NS_ConvertUTF8toUTF16(aNote->message().c_str())); + } +} + +/* static */ +void xpc::ErrorReport::ErrorReportToMessageString(JSErrorReport* aReport, nsAString& aString) { diff --git a/js/xpconnect/src/xpcprivate.h b/js/xpconnect/src/xpcprivate.h index 347b406eb..e55cc06e0 100644 --- a/js/xpconnect/src/xpcprivate.h +++ b/js/xpconnect/src/xpcprivate.h @@ -128,7 +128,6 @@ #include "MainThreadUtils.h" #include "nsIConsoleService.h" -#include "nsIScriptError.h" #include "nsIException.h" #include "nsVariant.h" @@ -2552,77 +2551,6 @@ extern char* xpc_PrintJSStack(JSContext* cx, bool showArgs, bool showLocals, bool showThisProps); -/***************************************************************************/ - -// Definition of nsScriptError, defined here because we lack a place to put -// XPCOM objects associated with the JavaScript engine. -class nsScriptErrorBase : public nsIScriptError { -public: - nsScriptErrorBase(); - - // TODO - do something reasonable on getting null from these babies. - - NS_DECL_NSICONSOLEMESSAGE - NS_DECL_NSISCRIPTERROR - -protected: - virtual ~nsScriptErrorBase(); - - void - InitializeOnMainThread(); - - nsString mMessage; - nsString mMessageName; - nsString mSourceName; - uint32_t mLineNumber; - nsString mSourceLine; - uint32_t mColumnNumber; - uint32_t mFlags; - nsCString mCategory; - // mOuterWindowID is set on the main thread from InitializeOnMainThread(). - uint64_t mOuterWindowID; - uint64_t mInnerWindowID; - int64_t mTimeStamp; - // mInitializedOnMainThread and mIsFromPrivateWindow are set on the main - // thread from InitializeOnMainThread(). - mozilla::Atomic<bool> mInitializedOnMainThread; - bool mIsFromPrivateWindow; -}; - -class nsScriptError final : public nsScriptErrorBase { -public: - nsScriptError() {} - NS_DECL_THREADSAFE_ISUPPORTS - -private: - virtual ~nsScriptError() {} -}; - -class nsScriptErrorWithStack : public nsScriptErrorBase { -public: - explicit nsScriptErrorWithStack(JS::HandleObject); - - NS_DECL_CYCLE_COLLECTING_ISUPPORTS - NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(nsScriptErrorWithStack) - - NS_IMETHOD Init(const nsAString& message, - const nsAString& sourceName, - const nsAString& sourceLine, - uint32_t lineNumber, - uint32_t columnNumber, - uint32_t flags, - const char* category) override; - - NS_IMETHOD GetStack(JS::MutableHandleValue) override; - NS_IMETHOD ToString(nsACString& aResult) override; - -private: - virtual ~nsScriptErrorWithStack(); - // Complete stackframe where the error happened. - // Must be SavedFrame object. - JS::Heap<JSObject*> mStack; -}; - /****************************************************************************** * Handles pre/post script processing. */ diff --git a/js/xpconnect/src/xpcpublic.h b/js/xpconnect/src/xpcpublic.h index fc8670d46..399cd2181 100644 --- a/js/xpconnect/src/xpcpublic.h +++ b/js/xpconnect/src/xpcpublic.h @@ -515,13 +515,50 @@ AllowCPOWsInAddon(const nsACString& addonId, bool allow); bool ExtraWarningsForSystemJS(); -class ErrorReport { +class ErrorBase { + public: + nsString mErrorMsg; + nsString mFileName; + uint32_t mLineNumber; + uint32_t mColumn; + + ErrorBase() : mLineNumber(0) + , mColumn(0) + {} + + void Init(JSErrorBase* aReport); + + void AppendErrorDetailsTo(nsCString& error); +}; + +class ErrorNote : public ErrorBase { + public: + void Init(JSErrorNotes::Note* aNote); + + // Produce an error event message string from the given JSErrorNotes::Note. + // This may produce an empty string if aNote doesn't have a message + // attached. + static void ErrorNoteToMessageString(JSErrorNotes::Note* aNote, + nsAString& aString); + + // Log the error note to the stderr. + void LogToStderr(); +}; + +class ErrorReport : public ErrorBase { public: NS_INLINE_DECL_THREADSAFE_REFCOUNTING(ErrorReport); + nsTArray<ErrorNote> mNotes; + + nsCString mCategory; + nsString mSourceLine; + nsString mErrorMsgName; + uint64_t mWindowID; + uint32_t mFlags; + bool mIsMuted; + ErrorReport() : mWindowID(0) - , mLineNumber(0) - , mColumn(0) , mFlags(0) , mIsMuted(false) {} @@ -530,6 +567,7 @@ class ErrorReport { bool aIsChrome, uint64_t aWindowID); void Init(JSContext* aCx, mozilla::dom::Exception* aException, bool aIsChrome, uint64_t aWindowID); + // Log the error report to the console. Which console will depend on the // window id it was initialized with. void LogToConsole(); @@ -544,18 +582,8 @@ class ErrorReport { static void ErrorReportToMessageString(JSErrorReport* aReport, nsAString& aString); - public: - - nsCString mCategory; - nsString mErrorMsgName; - nsString mErrorMsg; - nsString mFileName; - nsString mSourceLine; - uint64_t mWindowID; - uint32_t mLineNumber; - uint32_t mColumn; - uint32_t mFlags; - bool mIsMuted; + // Log the error report to the stderr. + void LogToStderr(); private: ~ErrorReport() {} diff --git a/js/xpconnect/tests/chrome/test_bug1041626.xul b/js/xpconnect/tests/chrome/test_bug1041626.xul index c7c7b7024..11529fbe4 100644 --- a/js/xpconnect/tests/chrome/test_bug1041626.xul +++ b/js/xpconnect/tests/chrome/test_bug1041626.xul @@ -28,9 +28,6 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1041626 ok(Cu.isXrayWrapper(window[0].location), "Location is Xrayed"); let xrayOwnProperties = Object.getOwnPropertyNames(window[0].location); - todo(xrayOwnProperties.indexOf('toJSON') != -1, - "dummy toJSON on Location should show up in Xrayable properties"); - xrayOwnProperties.push('toJSON'); let realOwnProperties = Object.getOwnPropertyNames(window[0].wrappedJSObject.location); ok(realOwnProperties.length > 2); diff --git a/js/xpconnect/wrappers/WrapperFactory.cpp b/js/xpconnect/wrappers/WrapperFactory.cpp index 0031fb127..8c9d38788 100644 --- a/js/xpconnect/wrappers/WrapperFactory.cpp +++ b/js/xpconnect/wrappers/WrapperFactory.cpp @@ -536,7 +536,7 @@ WrapperFactory::Rewrap(JSContext* cx, HandleObject existing, HandleObject obj) DEBUG_CheckUnwrapSafety(obj, wrapper, origin, target); if (existing) - return Wrapper::Renew(cx, existing, obj, wrapper); + return Wrapper::Renew(existing, obj, wrapper); return Wrapper::New(cx, obj, wrapper); } |