Files
palemoon27/layout/style/ErrorReporter.cpp
T
roytam1 be2de91b7f import changes from `dev' branch of rmottola/Arctic-Fox:
- Bug 1211479 - Errors when parsing substituting variables should include the generated string to help diagnose the issue. r=bz (41d8876fa8)
- Bug 1219150 - EventStateManager::{LatestUserInputStart, UserInputCount};r=smaug (2420aab91f)
- Bug 1171970. Handle super-long lines in CSS files a bit more gracefully if they cause OOM when creating CSS error messages. r=heycam (c1a3ec3869)
- Bug 1226400 - null-check GetParentObject(). r=m_kato (445e4cd17b)
- Bug 1226400 - throw an error in addition to returning null. r=bz (ac11a79851)
- Bug 1222662 - In the content process, detect when the mouse exists a plugin frame and update the content cursor accordingly. r=enn (7dfa70eeaa)
- Bug 1186780: Replace EnumerateRead with new iterators in ImageLoader. r=dbaron (939ae5322c)
- Bug 1186780: ifdef DEBUG fixes on a CLOSED TREE. r=me (1d8d5cfaa1)
- Bug 1219474 - Replace PRLogModuleInfo w/ LazyLogModule in the 'image/' directory. r=seth (abd4f22cfb)
- Bug 1217571 - fix the imagelib cache to work in e10s; r=seth (25fd01a8f5)
- Bug 1187149 - Replace nsBaseHashtable::Enumerate() calls in image/ with iterators r=njn (b1f310e9cc)
- Bug 1114526 - Make sure that CSS image invalidation also notifies rendering observers even if the image isn't visible (because the rendering observers might be visible). r=mattwoodrow (1dd0d5d0f7)
- Bug 1215361 (part 1) - Don't set mBPP twice in nsICODecoder.cpp. r=seth. (8250b4e5b6)
- Bug 1215361 (part 2) - Streamline nsBMPDecoder's getters. r=seth. (dd8b3a9d61)
- Bug 1215361 (part 3) - Deconvolute nsICODecoder's handling of endianness. r=seth. (a8c0841b1b)
- Bug 1204393 (part 1) - Use StreamingLexer in the ICON decoder. r=seth. (c68d1aafe3)
- Bug 1204393 (part 2) - Add more testing of the ICON decoder. r=seth. (d964ba2aee)
- Bug 1210291 - Streamline StreamingLexer's handling of terminal states. r=seth. (92ba68ff6d)
- Bug 1223319 (part 1) - Remove unused function nsICODecoder::CalcAlphaRowSize(). r=seth. (35ddc1d85d)
- Bug 1223465 - Clamp GIF frame rects to their screen rects - r=seth (d7fbc3f591)
- Bug 1217465 - Fill in missing pixels caused by truncated BMP files. r=seth. (b18f045a48)
- Bug 1173214, r=seth,bz (fbf1b74263)
- shadow warnings in decoders (fa930afb03)
- Bug 962243 - Implement PINCH to TOUCHING transition in APZC. r=botond (937b537084)
- Add page scroll support for APZ wheel events. (bug 1228028, r=kats) (6dab10516f)
- warnings (675c4e9921)
- Bug 1153392 - Use the current timestamp if the software vsync thread is late. r=kats (4c56f24c21)
- Bug 884594 - Part 1: ACEService and nsIAccessControlEnforcer.idl. r=allstars.chh (e96c5e0bc3)
- Bug 884594 - Part 2.1: GPAccessRulesManager and nsIAccessRulesManager.idl. Add utils to SEUtils.jsm. r=allstars.chh (e299f898e9)
- Bug 884594 - Part 2.2: New SEUtils.js tests. r=allstars.chh (07a2fd9334)
- Bug 884594 - Part 3 - Build support for ACE components. r=allstars.chh (16c2cec2a6)
- Bug 884594 - Part 4: Initial integration with ACE. r=allstars.chh (38cac02a26)
- Bug 1118102 - Fix error handling by rejecting the promise request with specific SE errors instead of 'Generic Error'. r=allstars.chh r=khuey a=kwierso (a5aa5cd88b)
- var-let (9cdc34a4e3)
- Bug 1136211 - SMS cannot be sent to a 15-digit phone number (such as an iNum) which doesn't have a territory id. r=mhenretty (709e060b9e)
- Bug 1138571 - Update PhonenumberJS Metadata. r=fabrice (077024cd5a)
- Bug 1179379 - PhonenumberJS: Update Metadata. r=bent (e72bad1476)
- Bug 1136211 - SMS cannot be sent to a 15-digit phone number (such as an iNum) which doesn't have a territory id. Tests. r=mhenretty (19d12d1628)
- Bug 1188117: Do not allow IDBCursor.delete while cursor update is in progress. r=baku (86016e968f)
2023-05-16 11:09:54 +08:00

380 lines
10 KiB
C++

/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* 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/. */
/* diagnostic reporting for CSS style sheet parser */
#include "mozilla/css/ErrorReporter.h"
#include "mozilla/CSSStyleSheet.h"
#include "mozilla/css/Loader.h"
#include "mozilla/Preferences.h"
#include "mozilla/Services.h"
#include "nsCSSScanner.h"
#include "nsIConsoleService.h"
#include "nsIDocument.h"
#include "nsIFactory.h"
#include "nsIScriptError.h"
#include "nsIStringBundle.h"
#include "nsServiceManagerUtils.h"
#include "nsStyleUtil.h"
#include "nsThreadUtils.h"
#ifdef CSS_REPORT_PARSE_ERRORS
using namespace mozilla;
namespace {
class ShortTermURISpecCache : public nsRunnable {
public:
ShortTermURISpecCache() : mPending(false) {}
nsString const& GetSpec(nsIURI* aURI) {
if (mURI != aURI) {
mURI = aURI;
nsAutoCString cSpec;
mURI->GetSpec(cSpec);
CopyUTF8toUTF16(cSpec, mSpec);
}
return mSpec;
}
bool IsInUse() const { return mURI != nullptr; }
bool IsPending() const { return mPending; }
void SetPending() { mPending = true; }
// When invoked as a runnable, zap the cache.
NS_IMETHOD Run() {
mURI = nullptr;
mSpec.Truncate();
mPending = false;
return NS_OK;
}
private:
nsCOMPtr<nsIURI> mURI;
nsString mSpec;
bool mPending;
};
} // namespace
static bool sReportErrors;
static nsIConsoleService *sConsoleService;
static nsIFactory *sScriptErrorFactory;
static nsIStringBundle *sStringBundle;
static ShortTermURISpecCache *sSpecCache;
#define CSS_ERRORS_PREF "layout.css.report_errors"
static bool
InitGlobals()
{
MOZ_ASSERT(!sConsoleService && !sScriptErrorFactory && !sStringBundle,
"should not have been called");
if (NS_FAILED(Preferences::AddBoolVarCache(&sReportErrors, CSS_ERRORS_PREF,
true))) {
return false;
}
nsCOMPtr<nsIConsoleService> cs = do_GetService(NS_CONSOLESERVICE_CONTRACTID);
if (!cs) {
return false;
}
nsCOMPtr<nsIFactory> sf = do_GetClassObject(NS_SCRIPTERROR_CONTRACTID);
if (!sf) {
return false;
}
nsCOMPtr<nsIStringBundleService> sbs = services::GetStringBundleService();
if (!sbs) {
return false;
}
nsCOMPtr<nsIStringBundle> sb;
nsresult rv = sbs->CreateBundle("chrome://global/locale/css.properties",
getter_AddRefs(sb));
if (NS_FAILED(rv) || !sb) {
return false;
}
cs.forget(&sConsoleService);
sf.forget(&sScriptErrorFactory);
sb.forget(&sStringBundle);
return true;
}
static inline bool
ShouldReportErrors()
{
if (!sConsoleService) {
if (!InitGlobals()) {
return false;
}
}
return sReportErrors;
}
namespace mozilla {
namespace css {
/* static */ void
ErrorReporter::ReleaseGlobals()
{
NS_IF_RELEASE(sConsoleService);
NS_IF_RELEASE(sScriptErrorFactory);
NS_IF_RELEASE(sStringBundle);
NS_IF_RELEASE(sSpecCache);
}
ErrorReporter::ErrorReporter(const nsCSSScanner& aScanner,
const CSSStyleSheet* aSheet,
const Loader* aLoader,
nsIURI* aURI)
: mScanner(&aScanner), mSheet(aSheet), mLoader(aLoader), mURI(aURI),
mInnerWindowID(0), mErrorLineNumber(0), mPrevErrorLineNumber(0),
mErrorColNumber(0)
{
}
ErrorReporter::~ErrorReporter()
{
// Schedule deferred cleanup for cached data. We want to strike a
// balance between performance and memory usage, so we only allow
// short-term caching.
if (sSpecCache && sSpecCache->IsInUse() && !sSpecCache->IsPending()) {
if (NS_FAILED(NS_DispatchToCurrentThread(sSpecCache))) {
// Peform the "deferred" cleanup immediately if the dispatch fails.
sSpecCache->Run();
} else {
sSpecCache->SetPending();
}
}
}
void
ErrorReporter::OutputError()
{
if (mError.IsEmpty()) {
return;
}
if (!ShouldReportErrors()) {
ClearError();
return;
}
if (mInnerWindowID == 0 && (mSheet || mLoader)) {
if (mSheet) {
mInnerWindowID = mSheet->FindOwningWindowInnerID();
}
if (mInnerWindowID == 0 && mLoader) {
nsIDocument* doc = mLoader->GetDocument();
if (doc) {
mInnerWindowID = doc->InnerWindowID();
}
}
// don't attempt this again, even if we failed
mSheet = nullptr;
mLoader = nullptr;
}
if (mFileName.IsEmpty()) {
if (mURI) {
if (!sSpecCache) {
sSpecCache = new ShortTermURISpecCache;
NS_ADDREF(sSpecCache);
}
mFileName = sSpecCache->GetSpec(mURI);
mURI = nullptr;
} else {
mFileName.AssignLiteral("from DOM");
}
}
nsresult rv;
nsCOMPtr<nsIScriptError> errorObject =
do_CreateInstance(sScriptErrorFactory, &rv);
if (NS_SUCCEEDED(rv)) {
rv = errorObject->InitWithWindowID(mError,
mFileName,
mErrorLine,
mErrorLineNumber,
mErrorColNumber,
nsIScriptError::warningFlag,
"CSS Parser",
mInnerWindowID);
if (NS_SUCCEEDED(rv)) {
sConsoleService->LogMessage(errorObject);
}
}
ClearError();
}
void
ErrorReporter::OutputError(uint32_t aLineNumber, uint32_t aLineOffset)
{
mErrorLineNumber = aLineNumber;
mErrorColNumber = aLineOffset;
OutputError();
}
void
ErrorReporter::ClearError()
{
mError.Truncate();
}
void
ErrorReporter::AddToError(const nsString &aErrorText)
{
if (!ShouldReportErrors()) return;
if (mError.IsEmpty()) {
mError = aErrorText;
mErrorLineNumber = mScanner->GetLineNumber();
mErrorColNumber = mScanner->GetColumnNumber();
// Retrieve the error line once per line, and reuse the same nsString
// for all errors on that line. That causes the text of the line to
// be shared among all the nsIScriptError objects.
if (mErrorLine.IsEmpty() || mErrorLineNumber != mPrevErrorLineNumber) {
// Be careful here: the error line might be really long and OOM
// when we try to make a copy here. If so, just leave it empty.
if (!mErrorLine.Assign(mScanner->GetCurrentLine(), fallible)) {
mErrorLine.Truncate();
}
mPrevErrorLineNumber = mErrorLineNumber;
}
} else {
mError.AppendLiteral(" ");
mError.Append(aErrorText);
}
}
void
ErrorReporter::ReportUnexpected(const char *aMessage)
{
if (!ShouldReportErrors()) return;
nsAutoString str;
sStringBundle->GetStringFromName(NS_ConvertASCIItoUTF16(aMessage).get(),
getter_Copies(str));
AddToError(str);
}
void
ErrorReporter::ReportUnexpected(const char *aMessage,
const nsString &aParam)
{
if (!ShouldReportErrors()) return;
nsAutoString qparam;
nsStyleUtil::AppendEscapedCSSIdent(aParam, qparam);
const char16_t *params[1] = { qparam.get() };
nsAutoString str;
sStringBundle->FormatStringFromName(NS_ConvertASCIItoUTF16(aMessage).get(),
params, ArrayLength(params),
getter_Copies(str));
AddToError(str);
}
void
ErrorReporter::ReportUnexpected(const char *aMessage,
const nsCSSToken &aToken)
{
if (!ShouldReportErrors()) return;
nsAutoString tokenString;
aToken.AppendToString(tokenString);
const char16_t *params[1] = { tokenString.get() };
nsAutoString str;
sStringBundle->FormatStringFromName(NS_ConvertASCIItoUTF16(aMessage).get(),
params, ArrayLength(params),
getter_Copies(str));
AddToError(str);
}
void
ErrorReporter::ReportUnexpected(const char *aMessage,
const nsCSSToken &aToken,
char16_t aChar)
{
if (!ShouldReportErrors()) return;
nsAutoString tokenString;
aToken.AppendToString(tokenString);
const char16_t charStr[2] = { aChar, 0 };
const char16_t *params[2] = { tokenString.get(), charStr };
nsAutoString str;
sStringBundle->FormatStringFromName(NS_ConvertASCIItoUTF16(aMessage).get(),
params, ArrayLength(params),
getter_Copies(str));
AddToError(str);
}
void
ErrorReporter::ReportUnexpected(const char *aMessage,
const nsString &aParam,
const nsString &aValue)
{
if (!ShouldReportErrors()) return;
nsAutoString qparam;
nsStyleUtil::AppendEscapedCSSIdent(aParam, qparam);
const char16_t *params[2] = { qparam.get(), aValue.get() };
nsAutoString str;
sStringBundle->FormatStringFromName(NS_ConvertASCIItoUTF16(aMessage).get(),
params, ArrayLength(params),
getter_Copies(str));
AddToError(str);
}
void
ErrorReporter::ReportUnexpectedEOF(const char *aMessage)
{
if (!ShouldReportErrors()) return;
nsAutoString innerStr;
sStringBundle->GetStringFromName(NS_ConvertASCIItoUTF16(aMessage).get(),
getter_Copies(innerStr));
const char16_t *params[1] = { innerStr.get() };
nsAutoString str;
sStringBundle->FormatStringFromName(MOZ_UTF16("PEUnexpEOF2"),
params, ArrayLength(params),
getter_Copies(str));
AddToError(str);
}
void
ErrorReporter::ReportUnexpectedEOF(char16_t aExpected)
{
if (!ShouldReportErrors()) return;
const char16_t expectedStr[] = {
char16_t('\''), aExpected, char16_t('\''), char16_t(0)
};
const char16_t *params[1] = { expectedStr };
nsAutoString str;
sStringBundle->FormatStringFromName(MOZ_UTF16("PEUnexpEOF2"),
params, ArrayLength(params),
getter_Copies(str));
AddToError(str);
}
} // namespace css
} // namespace mozilla
#endif