123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438 |
- /* -*- Mode: C++; tab-width: 8; 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/. */
- /*
- * nsIScriptError implementation.
- */
- #include "nsScriptError.h"
- #include "jsprf.h"
- #include "MainThreadUtils.h"
- #include "mozilla/Assertions.h"
- #include "nsGlobalWindow.h"
- #include "nsNetUtil.h"
- #include "nsPIDOMWindow.h"
- #include "nsILoadContext.h"
- #include "nsIDocShell.h"
- #include "nsIMutableArray.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::AddNote(nsIScriptErrorNote* note)
- {
- mNotes.AppendObject(note);
- }
- 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);
- }
- static void
- AssignSourceNameHelper(nsString& aSourceNameDest, const nsAString& aSourceNameSrc)
- {
- if (aSourceNameSrc.IsEmpty())
- return;
- aSourceNameDest.Assign(aSourceNameSrc);
- nsCOMPtr<nsIURI> uri;
- nsAutoCString pass;
- if (NS_SUCCEEDED(NS_NewURI(getter_AddRefs(uri), aSourceNameSrc)) &&
- NS_SUCCEEDED(uri->GetPassword(pass)) &&
- !pass.IsEmpty())
- {
- nsCOMPtr<nsISensitiveInfoHiddenURI> safeUri = do_QueryInterface(uri);
- nsAutoCString loc;
- if (safeUri && NS_SUCCEEDED(safeUri->GetSensitiveInfoHiddenSpec(loc)))
- aSourceNameDest.Assign(NS_ConvertUTF8toUTF16(loc));
- }
- }
- 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);
- AssignSourceNameHelper(mSourceName, sourceName);
- 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;
- }
- static nsresult
- ToStringHelper(const char* aSeverity, const nsString& aMessage,
- const nsString& aSourceName, const nsString* aSourceLine,
- uint32_t aLineNumber, uint32_t aColumnNumber,
- 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\"]";
- char* temp;
- char* tempMessage = nullptr;
- char* tempSourceName = nullptr;
- char* tempSourceLine = nullptr;
- if (!aMessage.IsEmpty())
- tempMessage = ToNewUTF8String(aMessage);
- if (!aSourceName.IsEmpty())
- // Use at most 512 characters from mSourceName.
- tempSourceName = ToNewUTF8String(StringHead(aSourceName, 512));
- if (aSourceLine && !aSourceLine->IsEmpty())
- // Use at most 512 characters from mSourceLine.
- tempSourceLine = ToNewUTF8String(StringHead(*aSourceLine, 512));
- if (nullptr != tempSourceName && nullptr != tempSourceLine) {
- temp = JS_smprintf(format0,
- aSeverity,
- tempMessage,
- tempSourceName,
- aLineNumber,
- aColumnNumber,
- tempSourceLine);
- } else if (!aSourceName.IsEmpty()) {
- temp = JS_smprintf(format1,
- aSeverity,
- tempMessage,
- tempSourceName,
- aLineNumber);
- } else {
- temp = JS_smprintf(format2,
- aSeverity,
- 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::ToString(nsACString& /*UTF8*/ aResult)
- {
- static const char error[] = "JavaScript Error";
- static const char warning[] = "JavaScript Warning";
- const char* severity = !(mFlags & JSREPORT_WARNING) ? error : warning;
- return ToStringHelper(severity, mMessage, mSourceName, &mSourceLine,
- mLineNumber, mColumnNumber, aResult);
- }
- 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_IMETHODIMP
- nsScriptErrorBase::GetNotes(nsIArray** aNotes)
- {
- nsresult rv = NS_OK;
- nsCOMPtr<nsIMutableArray> array =
- do_CreateInstance(NS_ARRAY_CONTRACTID, &rv);
- NS_ENSURE_SUCCESS(rv, rv);
- uint32_t len = mNotes.Length();
- for (uint32_t i = 0; i < len; i++)
- array->AppendElement(mNotes[i], false);
- array.forget(aNotes);
- return NS_OK;
- }
- NS_IMPL_ISUPPORTS(nsScriptError, nsIConsoleMessage, nsIScriptError)
- nsScriptErrorNote::nsScriptErrorNote()
- : mMessage(),
- mSourceName(),
- mLineNumber(0),
- mColumnNumber(0)
- {
- }
- nsScriptErrorNote::~nsScriptErrorNote() {}
- void
- nsScriptErrorNote::Init(const nsAString& message,
- const nsAString& sourceName,
- uint32_t lineNumber,
- uint32_t columnNumber)
- {
- mMessage.Assign(message);
- AssignSourceNameHelper(mSourceName, sourceName);
- mLineNumber = lineNumber;
- mColumnNumber = columnNumber;
- }
- // nsIScriptErrorNote methods
- NS_IMETHODIMP
- nsScriptErrorNote::GetErrorMessage(nsAString& aResult) {
- aResult.Assign(mMessage);
- return NS_OK;
- }
- NS_IMETHODIMP
- nsScriptErrorNote::GetSourceName(nsAString& aResult) {
- aResult.Assign(mSourceName);
- return NS_OK;
- }
- NS_IMETHODIMP
- nsScriptErrorNote::GetLineNumber(uint32_t* result) {
- *result = mLineNumber;
- return NS_OK;
- }
- NS_IMETHODIMP
- nsScriptErrorNote::GetColumnNumber(uint32_t* result) {
- *result = mColumnNumber;
- return NS_OK;
- }
- NS_IMETHODIMP
- nsScriptErrorNote::ToString(nsACString& /*UTF8*/ aResult)
- {
- return ToStringHelper("JavaScript Note", mMessage, mSourceName, nullptr,
- mLineNumber, mColumnNumber, aResult);
- }
- NS_IMPL_ISUPPORTS(nsScriptErrorNote, nsIScriptErrorNote)
|