diff --git a/dom/base/WebSocket.cpp b/dom/base/WebSocket.cpp index fe06bc93a4..6c8154a35d 100644 --- a/dom/base/WebSocket.cpp +++ b/dom/base/WebSocket.cpp @@ -2548,16 +2548,22 @@ WebSocket::Close(const Optional& aCode, return; } - // If the webSocket is not closed we MUST have a mImpl. - MOZ_ASSERT(mImpl); + // If we don't have mImpl, we are in a shutting down worker where we are still + // in CONNECTING state, but already disconnected internally. + if (!mImpl) { + MOZ_ASSERT(readyState == CONNECTING); + SetReadyState(CLOSING); + return; + } + RefPtr impl = mImpl; if (readyState == CONNECTING) { - mImpl->FailConnection(closeCode, closeReason); + impl->FailConnection(closeCode, closeReason); return; } MOZ_ASSERT(readyState == OPEN); - mImpl->CloseConnection(closeCode, closeReason); + impl->CloseConnection(closeCode, closeReason); } //----------------------------------------------------------------------------- diff --git a/dom/security/nsCSPContext.cpp b/dom/security/nsCSPContext.cpp index b4818b5d0c..8cc83a6d97 100644 --- a/dom/security/nsCSPContext.cpp +++ b/dom/security/nsCSPContext.cpp @@ -827,6 +827,16 @@ nsCSPContext::SendReports(nsISupports* aBlockedContentSource, { NS_ENSURE_ARG_MAX(aViolatedPolicyIndex, mPolicies.Length() - 1); + if (!CSPService::sCSPReportingEnabled) { + // Reporting is pref-disabled. Don't do any actual work and return success. + nsContentUtils::ReportToConsoleNonLocalized( + NS_LITERAL_STRING("CSP violation report not sent: reports have been disabled contrary to spec."), + nsIScriptError::warningFlag, + NS_LITERAL_CSTRING("Content Security Policy"), + nullptr); + return NS_OK; + } + dom::CSPReport report; nsresult rv; diff --git a/dom/security/nsCSPService.cpp b/dom/security/nsCSPService.cpp index 5e5066b739..7ba531030d 100644 --- a/dom/security/nsCSPService.cpp +++ b/dom/security/nsCSPService.cpp @@ -25,12 +25,15 @@ using namespace mozilla; /* Keeps track of whether or not CSP is enabled */ bool CSPService::sCSPEnabled = true; +/* Keeps track of whether or not CSP reporting is enabled */ +bool CSPService::sCSPReportingEnabled = true; static LazyLogModule gCspPRLog("CSP"); CSPService::CSPService() { Preferences::AddBoolVarCache(&sCSPEnabled, "security.csp.enable"); + Preferences::AddBoolVarCache(&sCSPReportingEnabled, "security.csp.reporting.enabled"); } CSPService::~CSPService() diff --git a/dom/security/nsCSPService.h b/dom/security/nsCSPService.h index e9c82d438a..3c0883844f 100644 --- a/dom/security/nsCSPService.h +++ b/dom/security/nsCSPService.h @@ -14,8 +14,8 @@ #define CSPSERVICE_CONTRACTID "@mozilla.org/cspservice;1" #define CSPSERVICE_CID \ - { 0x8d2f40b2, 0x4875, 0x4c95, \ - { 0x97, 0xd9, 0x3f, 0x7d, 0xca, 0x2c, 0xb4, 0x60 } } + { 0x83d284d6, 0xf280, 0x48ae, \ + { 0xa5, 0x6b, 0x0f, 0x28, 0x11, 0x29, 0x83, 0x1b } } class CSPService : public nsIContentPolicy, public nsIChannelEventSink { @@ -26,6 +26,7 @@ public: CSPService(); static bool sCSPEnabled; + static bool sCSPReportingEnabled; protected: virtual ~CSPService(); diff --git a/layout/generic/nsTextFrame.cpp b/layout/generic/nsTextFrame.cpp index 1fccf48a18..7e73692c42 100644 --- a/layout/generic/nsTextFrame.cpp +++ b/layout/generic/nsTextFrame.cpp @@ -711,7 +711,11 @@ GlyphObserver::NotifyGlyphsChanged() int32_t nsTextFrame::GetContentEnd() const { nsTextFrame* next = static_cast(GetNextContinuation()); - return next ? next->GetContentOffset() : mContent->GetText()->GetLength(); + // In case of allocation failure when setting/modifying the textfragment, + // it's possible our text might be missing. So we check the fragment length, + // in addition to the offset of the next continuation (if any). + int32_t fragLen = mContent->GetText()->GetLength(); + return next ? std::min(fragLen, next->GetContentOffset()) : fragLen; } struct FlowLengthProperty { @@ -1078,8 +1082,8 @@ public: nsIFrame* mAncestorControllingInitialBreak; int32_t GetContentEnd() { - return mEndFrame ? mEndFrame->GetContentOffset() - : mStartFrame->GetContent()->GetText()->GetLength(); + int32_t fragLen = mStartFrame->GetContent()->GetText()->GetLength(); + return mEndFrame ? std::min(fragLen, mEndFrame->GetContentOffset()) : fragLen; } }; diff --git a/modules/libpref/init/all.js b/modules/libpref/init/all.js index 4c9de2d0d3..c902936115 100644 --- a/modules/libpref/init/all.js +++ b/modules/libpref/init/all.js @@ -2189,6 +2189,7 @@ pref("security.notification_enable_delay", 500); pref("security.csp.enable", true); pref("security.csp.experimentalEnabled", false); pref("security.csp.enableStrictDynamic", true); +pref("security.csp.reporting.enabled", true); // Default Content Security Policy to apply to signed contents. pref("security.signed_content.CSP.default", "script-src 'self'; style-src 'self'"); @@ -4570,6 +4571,8 @@ pref("full-screen-api.enabled", false); pref("full-screen-api.unprefix.enabled", true); pref("full-screen-api.allow-trusted-requests-only", true); pref("full-screen-api.pointer-lock.enabled", true); +// whether to prevent the top level widget from going fullscreen +pref("full-screen-api.ignore-widgets", false); // transition duration of fade-to-black and fade-from-black, unit: ms pref("full-screen-api.transition-duration.enter", "0 0"); diff --git a/netwerk/cache2/CacheIOThread.cpp b/netwerk/cache2/CacheIOThread.cpp index fe0a4ddb05..61fd6677c3 100644 --- a/netwerk/cache2/CacheIOThread.cpp +++ b/netwerk/cache2/CacheIOThread.cpp @@ -417,6 +417,7 @@ void CacheIOThread::ThreadFunc() threadInternal->SetObserver(this); mXPCOMThread = xpcomThread.forget().take(); + nsCOMPtr thread = NS_GetCurrentThread(); lock.NotifyAll(); @@ -437,7 +438,6 @@ loopStart: bool processedEvent; nsresult rv; do { - nsIThread *thread = mXPCOMThread; rv = thread->ProcessNextEvent(false, &processedEvent); MOZ_ASSERT(mBlockingIOWatcher); diff --git a/widget/GfxDriverInfo.cpp b/widget/GfxDriverInfo.cpp index 6f9a74a4f4..6d51c1587a 100644 --- a/widget/GfxDriverInfo.cpp +++ b/widget/GfxDriverInfo.cpp @@ -15,7 +15,7 @@ uint64_t GfxDriverInfo::allDriverVersions = ~(uint64_t(0)); GfxDeviceFamily* const GfxDriverInfo::allDevices = nullptr; GfxDeviceFamily* GfxDriverInfo::mDeviceFamilies[DeviceFamilyMax]; -nsAString* GfxDriverInfo::mDeviceVendors[DeviceVendorMax]; +nsString* GfxDriverInfo::mDeviceVendors[DeviceVendorMax]; GfxDriverInfo::GfxDriverInfo() : mOperatingSystem(OperatingSystem::Unknown), diff --git a/widget/GfxDriverInfo.h b/widget/GfxDriverInfo.h index 119976bcbc..27763db1c1 100644 --- a/widget/GfxDriverInfo.h +++ b/widget/GfxDriverInfo.h @@ -165,7 +165,7 @@ struct GfxDriverInfo static GfxDeviceFamily* mDeviceFamilies[DeviceFamilyMax]; static const nsAString& GetDeviceVendor(DeviceVendor id); - static nsAString* mDeviceVendors[DeviceVendorMax]; + static nsString* mDeviceVendors[DeviceVendorMax]; nsString mModel, mHardware, mProduct, mManufacturer; diff --git a/xpcom/io/nsLocalFileUnix.cpp b/xpcom/io/nsLocalFileUnix.cpp index 33c6b6bfaf..1f71c70566 100644 --- a/xpcom/io/nsLocalFileUnix.cpp +++ b/xpcom/io/nsLocalFileUnix.cpp @@ -1699,6 +1699,47 @@ nsLocalFile::Contains(nsIFile* aInFile, bool* aResult) return NS_OK; } +static nsresult ReadLinkSafe(const nsCString& aTarget, int32_t aExpectedSize, + nsACString& aOutBuffer) { + // If we call readlink with a buffer size S it returns S, then we cannot tell + // if the buffer was big enough to hold the entire path. We allocate an + // additional byte so we can check if the buffer was large enough. + const auto allocSize = CheckedInt(aExpectedSize) + 1; + if (!allocSize.isValid()) { + return NS_ERROR_OUT_OF_MEMORY; + } + + auto result = aOutBuffer.BulkWrite(allocSize.value(), 0, false); + if (result.isErr()) { + return result.unwrapErr(); + } + + auto handle = result.unwrap(); + + while (true) { + ssize_t bytesWritten = + readlink(aTarget.get(), handle.Elements(), handle.Length()); + if (bytesWritten < 0) { + return NSRESULT_FOR_ERRNO(); + } + + // written >= 0 so it is safe to cast to size_t. + if ((size_t)bytesWritten < handle.Length()) { + // Target might have changed since the lstat call, or lstat might lie, see + // bug 1791029. + handle.Finish(bytesWritten, false); + return NS_OK; + } + + // The buffer was not large enough, so double it and try again. + auto restartResult = handle.RestartBulkWrite(handle.Length() * 2, 0, false); + if (restartResult.isErr()) { + return restartResult.unwrapErr(); + } + } +} + + NS_IMETHODIMP nsLocalFile::GetNativeTarget(nsACString& aResult) { @@ -1714,21 +1755,12 @@ nsLocalFile::GetNativeTarget(nsACString& aResult) return NS_ERROR_FILE_INVALID_PATH; } - int32_t size = (int32_t)symStat.st_size; nsAutoCString target; - if (!target.SetLength(size, mozilla::fallible)) { - return NS_ERROR_OUT_OF_MEMORY; + nsresult rv = ReadLinkSafe(mPath, symStat.st_size, target); + if (NS_FAILED(rv)) { + return rv; } - ssize_t written = readlink(mPath.get(), target.BeginWriting(), size_t(size)); - if (written < 0) { - return NSRESULT_FOR_ERRNO(); - } - // Target might have changed since the lstat call, or lstat might lie, see bug - // 1791029. - target.Truncate(written); - - nsresult rv = NS_OK; nsCOMPtr self(this); int32_t maxLinks = 40; while (true) { @@ -1766,22 +1798,12 @@ nsLocalFile::GetNativeTarget(nsACString& aResult) break; } - int32_t newSize = (int32_t)symStat.st_size; - size = newSize; nsAutoCString newTarget; - if (!newTarget.SetLength(size, mozilla::fallible)) { - rv = NS_ERROR_OUT_OF_MEMORY; + rv = ReadLinkSafe(flatRetval, symStat.st_size, newTarget); + if (NS_FAILED(rv)) { break; } - ssize_t linkLen = readlink(flatRetval.get(), newTarget.BeginWriting(), size); - if (linkLen == -1) { - rv = NSRESULT_FOR_ERRNO(); - break; - } - // Target might have changed since the lstat call, or lstat might lie, see bug - // 1791029. - newTarget.Truncate(linkLen); target = newTarget; }