summaryrefslogtreecommitdiffstats
path: root/dom
diff options
context:
space:
mode:
Diffstat (limited to 'dom')
-rw-r--r--dom/asmjscache/AsmJSCache.cpp348
-rw-r--r--dom/asmjscache/test/test_cachingBasic.html2
-rw-r--r--dom/asmjscache/test/test_cachingMulti.html2
-rw-r--r--dom/asmjscache/test/test_workers.html2
-rw-r--r--dom/base/FileReader.cpp4
-rw-r--r--dom/base/Navigator.cpp10
-rw-r--r--dom/base/moz.build2
-rw-r--r--dom/base/nsContentSink.cpp5
-rw-r--r--dom/base/nsContentUtils.cpp10
-rw-r--r--dom/base/nsContentUtils.h10
-rw-r--r--dom/base/nsDocument.cpp10
-rw-r--r--dom/base/nsDocument.h1
-rw-r--r--dom/base/nsGkAtomList.h4
-rw-r--r--dom/base/nsGlobalWindow.cpp12
-rw-r--r--dom/base/nsGlobalWindow.h14
-rw-r--r--dom/base/nsIDocument.h28
-rw-r--r--dom/base/nsPluginArray.cpp18
-rw-r--r--dom/base/nsTreeSanitizer.cpp2
-rw-r--r--dom/base/test/test_viewport_scroll.html4
-rw-r--r--dom/bindings/moz.build2
-rw-r--r--dom/browser-element/mochitest/browserElement_ScrollEvent.js4
-rw-r--r--dom/crypto/WebCryptoTask.cpp5
-rw-r--r--dom/html/HTMLMediaElement.cpp5
-rw-r--r--dom/html/nsHTMLDocument.cpp10
-rw-r--r--dom/indexedDB/ActorsParent.cpp108
-rw-r--r--dom/interfaces/security/nsIContentSecurityPolicy.idl5
-rw-r--r--dom/ipc/ContentProcess.cpp9
-rw-r--r--dom/locales/en-US/chrome/security/csp.properties4
-rw-r--r--dom/media/Benchmark.cpp2
-rw-r--r--dom/media/DecoderDoctorDiagnostics.cpp13
-rw-r--r--dom/media/MediaManager.cpp36
-rw-r--r--dom/media/eme/MediaKeySystemAccess.cpp14
-rw-r--r--dom/media/fmp4/MP4Decoder.cpp8
-rw-r--r--dom/media/gtest/TestGMPCrossOrigin.cpp5
-rw-r--r--dom/media/platforms/PDMFactory.cpp15
-rw-r--r--dom/media/platforms/wmf/WMF.h18
-rw-r--r--dom/media/platforms/wmf/WMFUtils.cpp16
-rw-r--r--dom/media/systemservices/MediaParent.cpp34
-rw-r--r--dom/media/webrtc/MediaEngineWebRTC.cpp4
-rw-r--r--dom/plugins/base/nsPluginHost.cpp68
-rw-r--r--dom/plugins/ipc/hangui/plugin-hang-ui.exe.manifest1
-rw-r--r--dom/plugins/test/unit/xpcshell.ini2
-rw-r--r--dom/security/nsCSPContext.cpp25
-rw-r--r--dom/security/nsCSPParser.cpp7
-rw-r--r--dom/security/nsCSPParser.h4
-rw-r--r--dom/security/nsCSPUtils.cpp44
-rw-r--r--dom/security/nsCSPUtils.h10
-rw-r--r--dom/security/nsMixedContentBlocker.cpp7
-rw-r--r--dom/security/test/csp/file_ignore_xfo.html10
-rw-r--r--dom/security/test/csp/file_ignore_xfo.html^headers^3
-rw-r--r--dom/security/test/csp/file_image_nonce.html39
-rw-r--r--dom/security/test/csp/file_image_nonce.html^headers^2
-rw-r--r--dom/security/test/csp/file_punycode_host_src.js2
-rw-r--r--dom/security/test/csp/file_punycode_host_src.sjs45
-rw-r--r--dom/security/test/csp/file_ro_ignore_xfo.html10
-rw-r--r--dom/security/test/csp/file_ro_ignore_xfo.html^headers^3
-rw-r--r--dom/security/test/csp/file_upgrade_insecure_navigation.sjs79
-rw-r--r--dom/security/test/csp/file_websocket_explicit.html31
-rw-r--r--dom/security/test/csp/file_websocket_self.html31
-rw-r--r--dom/security/test/csp/file_websocket_self_wsh.py7
-rw-r--r--dom/security/test/csp/mochitest.ini18
-rw-r--r--dom/security/test/csp/test_ignore_xfo.html59
-rw-r--r--dom/security/test/csp/test_image_nonce.html60
-rw-r--r--dom/security/test/csp/test_punycode_host_src.html81
-rw-r--r--dom/security/test/csp/test_upgrade_insecure_navigation.html103
-rw-r--r--dom/security/test/csp/test_websocket_self.html61
-rw-r--r--dom/security/test/gtest/TestCSPParser.cpp2
-rw-r--r--dom/tests/mochitest/general/test_domWindowUtils_scrollXY.html12
-rw-r--r--dom/url/URL.h6
-rw-r--r--dom/url/tests/test_url.html6
-rw-r--r--dom/webidl/URL.webidl5
-rw-r--r--dom/webidl/Window.webidl12
-rw-r--r--dom/webidl/moz.build12
73 files changed, 1269 insertions, 403 deletions
diff --git a/dom/asmjscache/AsmJSCache.cpp b/dom/asmjscache/AsmJSCache.cpp
index 4afcc6d6b..be54987a1 100644
--- a/dom/asmjscache/AsmJSCache.cpp
+++ b/dom/asmjscache/AsmJSCache.cpp
@@ -69,13 +69,19 @@ namespace asmjscache {
namespace {
+class ParentRunnable;
+
// Anything smaller should compile fast enough that caching will just add
// overhead.
-// static const size_t sMinCachedModuleLength = 10000;
+static const size_t sMinCachedModuleLength = 10000;
// The number of characters to hash into the Metadata::Entry::mFastHash.
static const unsigned sNumFastHashChars = 4096;
+// Track all live parent actors.
+typedef nsTArray<const ParentRunnable*> ParentActorArray;
+StaticAutoPtr<ParentActorArray> sLiveParentActors;
+
nsresult
WriteMetadataFile(nsIFile* aMetadataFile, const Metadata& aMetadata)
{
@@ -236,6 +242,94 @@ EvictEntries(nsIFile* aDirectory, const nsACString& aGroup,
}
}
+/*******************************************************************************
+ * Client
+ ******************************************************************************/
+
+class Client
+ : public quota::Client
+{
+ static Client* sInstance;
+
+ bool mShutdownRequested;
+
+public:
+ Client();
+
+ static bool
+ IsShuttingDownOnBackgroundThread()
+ {
+ AssertIsOnBackgroundThread();
+
+ if (sInstance) {
+ return sInstance->IsShuttingDown();
+ }
+
+ return QuotaManager::IsShuttingDown();
+ }
+
+ static bool
+ IsShuttingDownOnNonBackgroundThread()
+ {
+ MOZ_ASSERT(!IsOnBackgroundThread());
+
+ return QuotaManager::IsShuttingDown();
+ }
+
+ bool
+ IsShuttingDown() const
+ {
+ AssertIsOnBackgroundThread();
+
+ return mShutdownRequested;
+ }
+
+ NS_INLINE_DECL_REFCOUNTING(Client, override)
+
+ virtual Type
+ GetType() override;
+
+ virtual nsresult
+ InitOrigin(PersistenceType aPersistenceType,
+ const nsACString& aGroup,
+ const nsACString& aOrigin,
+ const AtomicBool& aCanceled,
+ UsageInfo* aUsageInfo) override;
+
+ virtual nsresult
+ GetUsageForOrigin(PersistenceType aPersistenceType,
+ const nsACString& aGroup,
+ const nsACString& aOrigin,
+ const AtomicBool& aCanceled,
+ UsageInfo* aUsageInfo) override;
+
+ virtual void
+ OnOriginClearCompleted(PersistenceType aPersistenceType,
+ const nsACString& aOrigin)
+ override;
+
+ virtual void
+ ReleaseIOThreadObjects() override;
+
+ virtual void
+ AbortOperations(const nsACString& aOrigin) override;
+
+ virtual void
+ AbortOperationsForProcess(ContentParentId aContentParentId) override;
+
+ virtual void
+ StartIdleMaintenance() override;
+
+ virtual void
+ StopIdleMaintenance() override;
+
+ virtual void
+ ShutdownWorkThreads() override;
+
+private:
+ ~Client();
+};
+
// FileDescriptorHolder owns a file descriptor and its memory mapping.
// FileDescriptorHolder is derived by two runnable classes (that is,
// (Parent|Child)Runnable.
@@ -897,6 +991,13 @@ ParentRunnable::FinishOnOwningThread()
FileDescriptorHolder::Finish();
mDirectoryLock = nullptr;
+
+ MOZ_ASSERT(sLiveParentActors);
+ sLiveParentActors->RemoveElement(this);
+
+ if (sLiveParentActors->IsEmpty()) {
+ sLiveParentActors = nullptr;
+ }
}
NS_IMETHODIMP
@@ -1140,6 +1241,10 @@ AllocEntryParent(OpenMode aOpenMode,
{
AssertIsOnBackgroundThread();
+ if (NS_WARN_IF(Client::IsShuttingDownOnBackgroundThread())) {
+ return nullptr;
+ }
+
if (NS_WARN_IF(aPrincipalInfo.type() == PrincipalInfo::TNullPrincipalInfo)) {
MOZ_ASSERT(false);
return nullptr;
@@ -1148,6 +1253,12 @@ AllocEntryParent(OpenMode aOpenMode,
RefPtr<ParentRunnable> runnable =
new ParentRunnable(aPrincipalInfo, aOpenMode, aWriteParams);
+ if (!sLiveParentActors) {
+ sLiveParentActors = new ParentActorArray();
+ }
+
+ sLiveParentActors->AppendElement(runnable);
+
nsresult rv = NS_DispatchToMainThread(runnable);
NS_ENSURE_SUCCESS(rv, nullptr);
@@ -1520,7 +1631,6 @@ DeallocEntryChild(PAsmJSCacheEntryChild* aActor)
static_cast<ChildRunnable*>(aActor)->Release();
}
-/*
namespace {
JS::AsmJSCacheResult
@@ -1583,7 +1693,6 @@ OpenFile(nsIPrincipal* aPrincipal,
}
} // namespace
-*/
typedef uint32_t AsmJSCookieType;
static const uint32_t sAsmJSCookie = 0x600d600d;
@@ -1596,9 +1705,6 @@ OpenEntryForRead(nsIPrincipal* aPrincipal,
const uint8_t** aMemory,
intptr_t* aHandle)
{
- return false;
-
-/*
if (size_t(aLimit - aBegin) < sMinCachedModuleLength) {
return false;
}
@@ -1638,7 +1744,6 @@ OpenEntryForRead(nsIPrincipal* aPrincipal,
// failure) at which point the file will be closed.
childRunnable.Forget(reinterpret_cast<ChildRunnable**>(aHandle));
return true;
-*/
}
void
@@ -1663,9 +1768,6 @@ OpenEntryForWrite(nsIPrincipal* aPrincipal,
uint8_t** aMemory,
intptr_t* aHandle)
{
- return JS::AsmJSCache_ESR52;
-
-/*
if (size_t(aEnd - aBegin) < sMinCachedModuleLength) {
return JS::AsmJSCache_ModuleTooSmall;
}
@@ -1699,7 +1801,6 @@ OpenEntryForWrite(nsIPrincipal* aPrincipal,
// failure) at which point the file will be closed
childRunnable.Forget(reinterpret_cast<ChildRunnable**>(aHandle));
return JS::AsmJSCache_Success;
-*/
}
void
@@ -1722,128 +1823,163 @@ CloseEntryForWrite(size_t aSize,
}
}
-class Client : public quota::Client
+/*******************************************************************************
+ * Client
+ ******************************************************************************/
+
+Client* Client::sInstance = nullptr;
+
+Client::Client()
+ : mShutdownRequested(false)
{
- ~Client() {}
+ AssertIsOnBackgroundThread();
+ MOZ_ASSERT(!sInstance, "We expect this to be a singleton!");
-public:
- NS_IMETHOD_(MozExternalRefCountType)
- AddRef() override;
+ sInstance = this;
+}
- NS_IMETHOD_(MozExternalRefCountType)
- Release() override;
+Client::~Client()
+{
+ AssertIsOnBackgroundThread();
+ MOZ_ASSERT(sInstance == this, "We expect this to be a singleton!");
- virtual Type
- GetType() override
- {
- return ASMJS;
- }
+ sInstance = nullptr;
+}
- virtual nsresult
- InitOrigin(PersistenceType aPersistenceType,
- const nsACString& aGroup,
- const nsACString& aOrigin,
- const AtomicBool& aCanceled,
- UsageInfo* aUsageInfo) override
- {
- if (!aUsageInfo) {
- return NS_OK;
- }
- return GetUsageForOrigin(aPersistenceType,
- aGroup,
- aOrigin,
- aCanceled,
- aUsageInfo);
- }
+Client::Type
+Client::GetType()
+{
+ return ASMJS;
+}
- virtual nsresult
- GetUsageForOrigin(PersistenceType aPersistenceType,
- const nsACString& aGroup,
- const nsACString& aOrigin,
- const AtomicBool& aCanceled,
- UsageInfo* aUsageInfo) override
- {
- QuotaManager* qm = QuotaManager::Get();
- MOZ_ASSERT(qm, "We were being called by the QuotaManager");
+nsresult
+Client::InitOrigin(PersistenceType aPersistenceType,
+ const nsACString& aGroup,
+ const nsACString& aOrigin,
+ const AtomicBool& aCanceled,
+ UsageInfo* aUsageInfo)
+{
+ if (!aUsageInfo) {
+ return NS_OK;
+ }
+ return GetUsageForOrigin(aPersistenceType,
+ aGroup,
+ aOrigin,
+ aCanceled,
+ aUsageInfo);
+}
- nsCOMPtr<nsIFile> directory;
- nsresult rv = qm->GetDirectoryForOrigin(aPersistenceType, aOrigin,
- getter_AddRefs(directory));
- NS_ENSURE_SUCCESS(rv, rv);
- MOZ_ASSERT(directory, "We're here because the origin directory exists");
+nsresult
+Client::GetUsageForOrigin(PersistenceType aPersistenceType,
+ const nsACString& aGroup,
+ const nsACString& aOrigin,
+ const AtomicBool& aCanceled,
+ UsageInfo* aUsageInfo)
+{
+ QuotaManager* qm = QuotaManager::Get();
+ MOZ_ASSERT(qm, "We were being called by the QuotaManager");
- rv = directory->Append(NS_LITERAL_STRING(ASMJSCACHE_DIRECTORY_NAME));
- NS_ENSURE_SUCCESS(rv, rv);
+ nsCOMPtr<nsIFile> directory;
+ nsresult rv = qm->GetDirectoryForOrigin(aPersistenceType, aOrigin,
+ getter_AddRefs(directory));
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
- DebugOnly<bool> exists;
- MOZ_ASSERT(NS_SUCCEEDED(directory->Exists(&exists)) && exists);
+ MOZ_ASSERT(directory, "We're here because the origin directory exists");
- nsCOMPtr<nsISimpleEnumerator> entries;
- rv = directory->GetDirectoryEntries(getter_AddRefs(entries));
- NS_ENSURE_SUCCESS(rv, rv);
+ rv = directory->Append(NS_LITERAL_STRING(ASMJSCACHE_DIRECTORY_NAME));
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
- bool hasMore;
- while (NS_SUCCEEDED((rv = entries->HasMoreElements(&hasMore))) &&
- hasMore && !aCanceled) {
- nsCOMPtr<nsISupports> entry;
- rv = entries->GetNext(getter_AddRefs(entry));
- NS_ENSURE_SUCCESS(rv, rv);
+ DebugOnly<bool> exists;
+ MOZ_ASSERT(NS_SUCCEEDED(directory->Exists(&exists)) && exists);
- nsCOMPtr<nsIFile> file = do_QueryInterface(entry);
- NS_ENSURE_TRUE(file, NS_NOINTERFACE);
+ nsCOMPtr<nsISimpleEnumerator> entries;
+ rv = directory->GetDirectoryEntries(getter_AddRefs(entries));
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
- int64_t fileSize;
- rv = file->GetFileSize(&fileSize);
- NS_ENSURE_SUCCESS(rv, rv);
+ bool hasMore;
+ while (NS_SUCCEEDED((rv = entries->HasMoreElements(&hasMore))) &&
+ hasMore && !aCanceled) {
+ nsCOMPtr<nsISupports> entry;
+ rv = entries->GetNext(getter_AddRefs(entry));
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
- MOZ_ASSERT(fileSize >= 0, "Negative size?!");
+ nsCOMPtr<nsIFile> file = do_QueryInterface(entry);
+ if (NS_WARN_IF(!file)) {
+ return NS_NOINTERFACE;
+ }
- // Since the client is not explicitly storing files, append to database
- // usage which represents implicit storage allocation.
- aUsageInfo->AppendToDatabaseUsage(uint64_t(fileSize));
+ int64_t fileSize;
+ rv = file->GetFileSize(&fileSize);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
}
- NS_ENSURE_SUCCESS(rv, rv);
- return NS_OK;
+ MOZ_ASSERT(fileSize >= 0, "Negative size?!");
+
+ // Since the client is not explicitly storing files, append to database
+ // usage which represents implicit storage allocation.
+ aUsageInfo->AppendToDatabaseUsage(uint64_t(fileSize));
+ }
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
}
- virtual void
- OnOriginClearCompleted(PersistenceType aPersistenceType,
- const nsACString& aOrigin)
- override
- { }
+ return NS_OK;
+}
- virtual void
- ReleaseIOThreadObjects() override
- { }
+void
+Client::OnOriginClearCompleted(PersistenceType aPersistenceType,
+ const nsACString& aOrigin)
+{
+}
- virtual void
- AbortOperations(const nsACString& aOrigin) override
- { }
+void
+Client::ReleaseIOThreadObjects()
+{
+}
- virtual void
- AbortOperationsForProcess(ContentParentId aContentParentId) override
- { }
+void
+Client::AbortOperations(const nsACString& aOrigin)
+{
+}
- virtual void
- StartIdleMaintenance() override
- { }
+void
+Client::AbortOperationsForProcess(ContentParentId aContentParentId)
+{
+}
- virtual void
- StopIdleMaintenance() override
- { }
+void
+Client::StartIdleMaintenance()
+{
+}
- virtual void
- ShutdownWorkThreads() override
- { }
+void
+Client::StopIdleMaintenance()
+{
+}
-private:
- nsAutoRefCnt mRefCnt;
- NS_DECL_OWNINGTHREAD
-};
+void
+Client::ShutdownWorkThreads()
+{
+ AssertIsOnBackgroundThread();
+
+ if (sLiveParentActors) {
+ nsIThread* currentThread = NS_GetCurrentThread();
+ MOZ_ASSERT(currentThread);
-NS_IMPL_ADDREF(asmjscache::Client)
-NS_IMPL_RELEASE(asmjscache::Client)
+ do {
+ MOZ_ALWAYS_TRUE(NS_ProcessNextEvent(currentThread));
+ } while (!sLiveParentActors);
+ }
+}
quota::Client*
CreateClient()
diff --git a/dom/asmjscache/test/test_cachingBasic.html b/dom/asmjscache/test/test_cachingBasic.html
index e84fdba8b..f491fe9fa 100644
--- a/dom/asmjscache/test/test_cachingBasic.html
+++ b/dom/asmjscache/test/test_cachingBasic.html
@@ -44,7 +44,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=929236
evalAsync(code);
break;
case 1:
- ok(!jsFuns.isAsmJSModuleLoadedFromCache(module), 'module not loaded from cache');
+ ok(jsFuns.isAsmJSModuleLoadedFromCache(module), 'module loaded from cache');
SimpleTest.finish();
break;
default:
diff --git a/dom/asmjscache/test/test_cachingMulti.html b/dom/asmjscache/test/test_cachingMulti.html
index ca092fda0..ceaf75812 100644
--- a/dom/asmjscache/test/test_cachingMulti.html
+++ b/dom/asmjscache/test/test_cachingMulti.html
@@ -36,7 +36,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=944821
code2 += "return g" + i + ";\n";
code2 += "}\n";
code2 += "ok(jsFuns.isAsmJSModule(f), 'f is an asm.js module')\n";
- code2 += "if (assertCacheHit) ok(!jsFuns.isAsmJSModuleLoadedFromCache(f), 'cache disabled');\n";
+ code2 += "if (assertCacheHit) ok(jsFuns.isAsmJSModuleLoadedFromCache(f), 'cache hit');\n";
code2 += "var gX = f();\n";
code2 += "ok(jsFuns.isAsmJSFunction(gX), 'gX is an asm.js function')\n";
code2 += "ok(gX() === " + i + ", 'gX returns the correct result')\n";
diff --git a/dom/asmjscache/test/test_workers.html b/dom/asmjscache/test/test_workers.html
index 992ed785b..6704459f6 100644
--- a/dom/asmjscache/test/test_workers.html
+++ b/dom/asmjscache/test/test_workers.html
@@ -31,7 +31,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=941830
var workerBlob = new Blob([workerCode], {type:"application/javascript"});
var mainCode = asmjsCode;
- mainCode += "ok(!jsFuns.isAsmJSModuleLoadedFromCache(f), 'f is not a cache hit')\n";
+ mainCode += "ok(jsFuns.isAsmJSModuleLoadedFromCache(f), 'f is a cache hit')\n";
mainCode += "var g42 = f();\n";
mainCode += "ok(jsFuns.isAsmJSFunction(g42), 'g42 is an asm.js function');\n";
mainCode += "ok(g42() === 42, 'g42 returns the correct result');\n";
diff --git a/dom/base/FileReader.cpp b/dom/base/FileReader.cpp
index 003edc61f..63a0ef2ee 100644
--- a/dom/base/FileReader.cpp
+++ b/dom/base/FileReader.cpp
@@ -452,8 +452,8 @@ FileReader::GetAsText(Blob *aBlob,
}
}
- nsDependentCSubstring data(aFileData, aDataLen);
- return nsContentUtils::ConvertStringFromEncoding(encoding, data, aResult);
+ return nsContentUtils::ConvertStringFromEncoding(
+ encoding, aFileData, aDataLen, aResult);
}
nsresult
diff --git a/dom/base/Navigator.cpp b/dom/base/Navigator.cpp
index 290af152b..8b20d0196 100644
--- a/dom/base/Navigator.cpp
+++ b/dom/base/Navigator.cpp
@@ -1854,16 +1854,6 @@ Navigator::GetUserAgent(nsPIDOMWindowInner* aWindow, nsIURI* aURI,
{
MOZ_ASSERT(NS_IsMainThread());
- if (!aIsCallerChrome) {
- const nsAdoptingString& override =
- mozilla::Preferences::GetString("general.useragent.override");
-
- if (override) {
- aUserAgent = override;
- return NS_OK;
- }
- }
-
nsresult rv;
nsCOMPtr<nsIHttpProtocolHandler>
service(do_GetService(NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "http", &rv));
diff --git a/dom/base/moz.build b/dom/base/moz.build
index d237acb03..0bc9902e4 100644
--- a/dom/base/moz.build
+++ b/dom/base/moz.build
@@ -472,7 +472,7 @@ include('/ipc/chromium/chromium-config.mozbuild')
FINAL_LIBRARY = 'xul'
-if CONFIG['MOZ_BUILD_APP'] in ['browser', 'mobile/android', 'xulrunner']:
+if CONFIG['MOZ_BUILD_APP'] in ['mobile/android', 'xulrunner'] or CONFIG['MOZ_PHOENIX']:
DEFINES['HAVE_SIDEBAR'] = True
if CONFIG['MOZ_X11']:
diff --git a/dom/base/nsContentSink.cpp b/dom/base/nsContentSink.cpp
index 3d6f069d2..85b3d07bf 100644
--- a/dom/base/nsContentSink.cpp
+++ b/dom/base/nsContentSink.cpp
@@ -305,6 +305,11 @@ nsContentSink::ProcessHeaderData(nsIAtom* aHeader, const nsAString& aValue,
mDocument->SetHeaderData(aHeader, aValue);
if (aHeader == nsGkAtoms::setcookie) {
+ // Don't allow setting cookies in cookie-averse documents.
+ if (mDocument->IsCookieAverse()) {
+ return NS_OK;
+ }
+
// Note: Necko already handles cookies set via the channel. We can't just
// call SetCookie on the channel because we want to do some security checks
// here.
diff --git a/dom/base/nsContentUtils.cpp b/dom/base/nsContentUtils.cpp
index 29d28f8ce..1cc352685 100644
--- a/dom/base/nsContentUtils.cpp
+++ b/dom/base/nsContentUtils.cpp
@@ -4128,9 +4128,15 @@ nsContentUtils::GetSubdocumentWithOuterWindowId(nsIDocument *aDocument,
/* static */
nsresult
nsContentUtils::ConvertStringFromEncoding(const nsACString& aEncoding,
- const nsACString& aInput,
+ const char* aInput,
+ uint32_t aInputLen,
nsAString& aOutput)
{
+ CheckedInt32 len = aInputLen;
+ if (!len.isValid()) {
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+
nsAutoCString encoding;
if (aEncoding.IsEmpty()) {
encoding.AssignLiteral("UTF-8");
@@ -4142,7 +4148,7 @@ nsContentUtils::ConvertStringFromEncoding(const nsACString& aEncoding,
nsAutoPtr<TextDecoder> decoder(new TextDecoder());
decoder->InitWithEncoding(encoding, false);
- decoder->Decode(aInput.BeginReading(), aInput.Length(), false,
+ decoder->Decode(aInput, len.value(), false,
aOutput, rv);
return rv.StealNSResult();
}
diff --git a/dom/base/nsContentUtils.h b/dom/base/nsContentUtils.h
index 278fbd008..f688eeecf 100644
--- a/dom/base/nsContentUtils.h
+++ b/dom/base/nsContentUtils.h
@@ -554,9 +554,17 @@ public:
* string (meaning UTF-8)
*/
static nsresult ConvertStringFromEncoding(const nsACString& aEncoding,
- const nsACString& aInput,
+ const char* aInput,
+ uint32_t aInputLen,
nsAString& aOutput);
+ static nsresult ConvertStringFromEncoding(const nsACString& aEncoding,
+ const nsACString& aInput,
+ nsAString& aOutput) {
+ return ConvertStringFromEncoding(
+ aEncoding, aInput.BeginReading(), aInput.Length(), aOutput);
+ }
+
/**
* Determine whether a buffer begins with a BOM for UTF-8, UTF-16LE,
* UTF-16BE
diff --git a/dom/base/nsDocument.cpp b/dom/base/nsDocument.cpp
index 8e6920a0e..4926b6c0a 100644
--- a/dom/base/nsDocument.cpp
+++ b/dom/base/nsDocument.cpp
@@ -61,6 +61,7 @@
#include "nsGenericHTMLElement.h"
#include "mozilla/dom/CDATASection.h"
#include "mozilla/dom/ProcessingInstruction.h"
+#include "nsDSURIContentListener.h"
#include "nsDOMString.h"
#include "nsNodeUtils.h"
#include "nsLayoutUtils.h" // for GetFrameForPoint
@@ -2456,6 +2457,15 @@ nsDocument::StartDocumentLoad(const char* aCommand, nsIChannel* aChannel,
NS_ENSURE_SUCCESS(rv, rv);
}
+ // XFO needs to be checked after CSP because it is ignored if
+ // the CSP defines frame-ancestors.
+ if (!nsDSURIContentListener::CheckFrameOptions(aChannel, docShell, NodePrincipal())) {
+ MOZ_LOG(gCspPRLog, LogLevel::Debug,
+ ("XFO doesn't like frame's ancestry, not loading."));
+ // stop! ERROR page!
+ aChannel->Cancel(NS_ERROR_CSP_FRAME_ANCESTOR_VIOLATION);
+ }
+
return NS_OK;
}
diff --git a/dom/base/nsDocument.h b/dom/base/nsDocument.h
index 17d936055..fc6749c9f 100644
--- a/dom/base/nsDocument.h
+++ b/dom/base/nsDocument.h
@@ -1491,7 +1491,6 @@ private:
void PostUnblockOnloadEvent();
void DoUnblockOnload();
- nsresult CheckFrameOptions();
nsresult InitCSP(nsIChannel* aChannel);
/**
diff --git a/dom/base/nsGkAtomList.h b/dom/base/nsGkAtomList.h
index 7827ad66b..0b76b2bea 100644
--- a/dom/base/nsGkAtomList.h
+++ b/dom/base/nsGkAtomList.h
@@ -2230,6 +2230,8 @@ GK_ATOM(scrollbar_end_backward, "scrollbar-end-backward")
GK_ATOM(scrollbar_end_forward, "scrollbar-end-forward")
GK_ATOM(scrollbar_thumb_proportional, "scrollbar-thumb-proportional")
GK_ATOM(overlay_scrollbars, "overlay-scrollbars")
+GK_ATOM(windows_accent_color_applies, "windows-accent-color-applies")
+GK_ATOM(windows_accent_color_is_dark, "windows-accent-color-is-dark")
GK_ATOM(windows_default_theme, "windows-default-theme")
GK_ATOM(mac_graphite_theme, "mac-graphite-theme")
GK_ATOM(mac_yosemite_theme, "mac-yosemite-theme")
@@ -2259,6 +2261,8 @@ GK_ATOM(_moz_scrollbar_end_backward, "-moz-scrollbar-end-backward")
GK_ATOM(_moz_scrollbar_end_forward, "-moz-scrollbar-end-forward")
GK_ATOM(_moz_scrollbar_thumb_proportional, "-moz-scrollbar-thumb-proportional")
GK_ATOM(_moz_overlay_scrollbars, "-moz-overlay-scrollbars")
+GK_ATOM(_moz_windows_accent_color_applies, "-moz-windows-accent-color-applies")
+GK_ATOM(_moz_windows_accent_color_is_dark, "-moz-windows-accent-color-is-dark")
GK_ATOM(_moz_windows_default_theme, "-moz-windows-default-theme")
GK_ATOM(_moz_mac_graphite_theme, "-moz-mac-graphite-theme")
GK_ATOM(_moz_mac_yosemite_theme, "-moz-mac-yosemite-theme")
diff --git a/dom/base/nsGlobalWindow.cpp b/dom/base/nsGlobalWindow.cpp
index 8ff4b84ce..f784031f6 100644
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -6187,7 +6187,7 @@ nsGlobalWindow::GetScrollMaxY(ErrorResult& aError)
FORWARD_TO_OUTER_OR_THROW(GetScrollBoundaryOuter, (eSideBottom), aError, 0);
}
-CSSIntPoint
+CSSPoint
nsGlobalWindow::GetScrollXY(bool aDoFlush)
{
MOZ_ASSERT(IsOuterWindow());
@@ -6211,30 +6211,30 @@ nsGlobalWindow::GetScrollXY(bool aDoFlush)
return GetScrollXY(true);
}
- return sf->GetScrollPositionCSSPixels();
+ return CSSPoint::FromAppUnits(scrollPos);
}
-int32_t
+double
nsGlobalWindow::GetScrollXOuter()
{
MOZ_RELEASE_ASSERT(IsOuterWindow());
return GetScrollXY(false).x;
}
-int32_t
+double
nsGlobalWindow::GetScrollX(ErrorResult& aError)
{
FORWARD_TO_OUTER_OR_THROW(GetScrollXOuter, (), aError, 0);
}
-int32_t
+double
nsGlobalWindow::GetScrollYOuter()
{
MOZ_RELEASE_ASSERT(IsOuterWindow());
return GetScrollXY(false).y;
}
-int32_t
+double
nsGlobalWindow::GetScrollY(ErrorResult& aError)
{
FORWARD_TO_OUTER_OR_THROW(GetScrollYOuter, (), aError, 0);
diff --git a/dom/base/nsGlobalWindow.h b/dom/base/nsGlobalWindow.h
index eab91c2e4..dbceeab74 100644
--- a/dom/base/nsGlobalWindow.h
+++ b/dom/base/nsGlobalWindow.h
@@ -1050,15 +1050,15 @@ public:
void SetInnerHeight(JSContext* aCx, JS::Handle<JS::Value> aValue,
mozilla::dom::CallerType aCallerType,
mozilla::ErrorResult& aError);
- int32_t GetScrollXOuter();
- int32_t GetScrollX(mozilla::ErrorResult& aError);
- int32_t GetPageXOffset(mozilla::ErrorResult& aError)
+ double GetScrollXOuter();
+ double GetScrollX(mozilla::ErrorResult& aError);
+ double GetPageXOffset(mozilla::ErrorResult& aError)
{
return GetScrollX(aError);
}
- int32_t GetScrollYOuter();
- int32_t GetScrollY(mozilla::ErrorResult& aError);
- int32_t GetPageYOffset(mozilla::ErrorResult& aError)
+ double GetScrollYOuter();
+ double GetScrollY(mozilla::ErrorResult& aError);
+ double GetPageYOffset(mozilla::ErrorResult& aError)
{
return GetScrollY(aError);
}
@@ -1579,7 +1579,7 @@ public:
// If aDoFlush is true, we'll flush our own layout; otherwise we'll try to
// just flush our parent and only flush ourselves if we think we need to.
// Outer windows only.
- mozilla::CSSIntPoint GetScrollXY(bool aDoFlush);
+ mozilla::CSSPoint GetScrollXY(bool aDoFlush);
int32_t GetScrollBoundaryOuter(mozilla::Side aSide);
diff --git a/dom/base/nsIDocument.h b/dom/base/nsIDocument.h
index 5b10c9914..8f35e9ba5 100644
--- a/dom/base/nsIDocument.h
+++ b/dom/base/nsIDocument.h
@@ -1923,6 +1923,34 @@ public:
return mMarkedCCGeneration;
}
+ /**
+ * Returns whether this document is cookie-averse. See
+ * https://html.spec.whatwg.org/multipage/dom.html#cookie-averse-document-object
+ */
+ bool IsCookieAverse() const
+ {
+ // If we are a document that "has no browsing context."
+ if (!GetInnerWindow()) {
+ return true;
+ }
+
+ // If we are a document "whose URL's scheme is not a network scheme."
+ // NB: Explicitly allow file: URIs to store cookies.
+ nsCOMPtr<nsIURI> codebaseURI;
+ NodePrincipal()->GetURI(getter_AddRefs(codebaseURI));
+
+ if (!codebaseURI) {
+ return true;
+ }
+
+ nsAutoCString scheme;
+ codebaseURI->GetScheme(scheme);
+ return !scheme.EqualsLiteral("http") &&
+ !scheme.EqualsLiteral("https") &&
+ !scheme.EqualsLiteral("ftp") &&
+ !scheme.EqualsLiteral("file");
+ }
+
bool IsLoadedAsData()
{
return mLoadedAsData;
diff --git a/dom/base/nsPluginArray.cpp b/dom/base/nsPluginArray.cpp
index b9c946ca3..5b9378ae0 100644
--- a/dom/base/nsPluginArray.cpp
+++ b/dom/base/nsPluginArray.cpp
@@ -372,9 +372,21 @@ nsPluginArray::EnsurePlugins()
nsCString permString;
nsresult rv = pluginHost->GetPermissionStringForTag(pluginTag, 0, permString);
if (rv == NS_OK) {
- nsIPrincipal* principal = mWindow->GetExtantDoc()->NodePrincipal();
- nsCOMPtr<nsIPermissionManager> permMgr = services::GetPermissionManager();
- permMgr->TestPermissionFromPrincipal(principal, permString.get(), &permission);
+ nsCOMPtr<nsIDocument> currentDoc = mWindow->GetExtantDoc();
+
+ // The top-level content document gets the final say on whether or not
+ // a plugin is going to be hidden or not, regardless of the origin
+ // that a subframe is hosted at. This is to avoid spamming the user
+ // with the hidden plugin notification bar when third-party iframes
+ // attempt to access navigator.plugins after the user has already
+ // expressed that the top-level document has this permission.
+ nsCOMPtr<nsIDocument> topDoc = currentDoc->GetTopLevelContentDocument();
+
+ if (topDoc) {
+ nsIPrincipal* principal = topDoc->NodePrincipal();
+ nsCOMPtr<nsIPermissionManager> permMgr = services::GetPermissionManager();
+ permMgr->TestPermissionFromPrincipal(principal, permString.get(), &permission);
+ }
}
}
}
diff --git a/dom/base/nsTreeSanitizer.cpp b/dom/base/nsTreeSanitizer.cpp
index dc53ea5fa..323c851c1 100644
--- a/dom/base/nsTreeSanitizer.cpp
+++ b/dom/base/nsTreeSanitizer.cpp
@@ -169,6 +169,7 @@ nsIAtom** const kAttributesHTML[] = {
&nsGkAtoms::contextmenu,
&nsGkAtoms::controls,
&nsGkAtoms::coords,
+ &nsGkAtoms::crossorigin,
&nsGkAtoms::datetime,
&nsGkAtoms::dir,
&nsGkAtoms::disabled,
@@ -185,6 +186,7 @@ nsIAtom** const kAttributesHTML[] = {
&nsGkAtoms::hreflang,
&nsGkAtoms::icon,
&nsGkAtoms::id,
+ &nsGkAtoms::integrity,
&nsGkAtoms::ismap,
&nsGkAtoms::itemid,
&nsGkAtoms::itemprop,
diff --git a/dom/base/test/test_viewport_scroll.html b/dom/base/test/test_viewport_scroll.html
index 9b812360b..7db02b781 100644
--- a/dom/base/test/test_viewport_scroll.html
+++ b/dom/base/test/test_viewport_scroll.html
@@ -28,10 +28,10 @@ function subtest(winProp, elemProp, win, correctElement, elemToSet, otherElem1,
win.scrollTo(50, 50);
elemToSet[elemProp] = 100;
if (elemToSet == correctElement) {
- is(win[winProp], 100, "Setting " + elemToSet.name + "." + elemProp + " should scroll");
+ is(Math.round(win[winProp]), 100, "Setting " + elemToSet.name + "." + elemProp + " should scroll");
is(elemToSet[elemProp], 100, "Reading back " + elemToSet.name + "." + elemProp + " after scrolling");
} else {
- is(win[winProp], 50, "Setting " + elemToSet.name + "." + elemProp + " should not scroll");
+ is(Math.round(win[winProp]), 50, "Setting " + elemToSet.name + "." + elemProp + " should not scroll");
is(elemToSet[elemProp], 0, "Reading back " + elemToSet.name + "." + elemProp + " after not scrolling");
}
if (otherElem1 == correctElement) {
diff --git a/dom/bindings/moz.build b/dom/bindings/moz.build
index fadaac69b..eb00482c6 100644
--- a/dom/bindings/moz.build
+++ b/dom/bindings/moz.build
@@ -139,7 +139,7 @@ FINAL_LIBRARY = 'xul'
SPHINX_TREES['webidl'] = 'docs'
SPHINX_PYTHON_PACKAGE_DIRS += ['mozwebidlcodegen']
-if CONFIG['MOZ_BUILD_APP'] in ['browser', 'mobile/android', 'xulrunner']:
+if CONFIG['MOZ_BUILD_APP'] in ['mobile/android', 'xulrunner'] or CONFIG['MOZ_PHOENIX']:
# This is needed for Window.webidl
DEFINES['HAVE_SIDEBAR'] = True
diff --git a/dom/browser-element/mochitest/browserElement_ScrollEvent.js b/dom/browser-element/mochitest/browserElement_ScrollEvent.js
index 5c4b4dcf9..06dc91b86 100644
--- a/dom/browser-element/mochitest/browserElement_ScrollEvent.js
+++ b/dom/browser-element/mochitest/browserElement_ScrollEvent.js
@@ -16,8 +16,8 @@ function runTest() {
iframe.addEventListener("mozbrowserscroll", function(e) {
ok(true, "got mozbrowserscroll event.");
ok(e.detail, "event.detail is not null.");
- ok(e.detail.top === 4000, "top position is correct.");
- ok(e.detail.left === 4000, "left position is correct.");
+ ok(Math.round(e.detail.top) == 4000, "top position is correct.");
+ ok(Math.round(e.detail.left) == 4000, "left position is correct.");
SimpleTest.finish();
});
diff --git a/dom/crypto/WebCryptoTask.cpp b/dom/crypto/WebCryptoTask.cpp
index 57a7da186..f5fc7b5bc 100644
--- a/dom/crypto/WebCryptoTask.cpp
+++ b/dom/crypto/WebCryptoTask.cpp
@@ -716,6 +716,11 @@ private:
return NS_ERROR_DOM_INVALID_ACCESS_ERR;
}
+ // Check whether the integer addition would overflow.
+ if (std::numeric_limits<CryptoBuffer::size_type>::max() - 16 < mData.Length()) {
+ return NS_ERROR_DOM_DATA_ERR;
+ }
+
// Initialize the output buffer (enough space for padding / a full tag)
uint32_t dataLen = mData.Length();
uint32_t maxLen = dataLen + 16;
diff --git a/dom/html/HTMLMediaElement.cpp b/dom/html/HTMLMediaElement.cpp
index b64761270..e81cd20bc 100644
--- a/dom/html/HTMLMediaElement.cpp
+++ b/dom/html/HTMLMediaElement.cpp
@@ -4550,6 +4550,11 @@ void HTMLMediaElement::FirstFrameLoaded()
ChangeDelayLoadStatus(false);
+ // FIXME: This is a workaround for DoneCreatingElement() not being called
+ // at the appropriate time when cloning elements, to preserve the "muted"
+ // status. See bug 1424871.
+ if (HasAttr(kNameSpaceID_None, nsGkAtoms::muted)) SetMuted(true);
+
if (mDecoder && mAllowSuspendAfterFirstFrame && mPaused &&
!HasAttr(kNameSpaceID_None, nsGkAtoms::autoplay) &&
mPreloadAction == HTMLMediaElement::PRELOAD_METADATA) {
diff --git a/dom/html/nsHTMLDocument.cpp b/dom/html/nsHTMLDocument.cpp
index 5e6302941..7d66aab04 100644
--- a/dom/html/nsHTMLDocument.cpp
+++ b/dom/html/nsHTMLDocument.cpp
@@ -1255,6 +1255,11 @@ nsHTMLDocument::GetCookie(nsAString& aCookie, ErrorResult& rv)
rv.Throw(NS_ERROR_DOM_SECURITY_ERR);
return;
}
+
+ // If the document is a cookie-averse document, return an empty string.
+ if (IsCookieAverse()) {
+ return;
+ }
// not having a cookie service isn't an error
nsCOMPtr<nsICookieService> service = do_GetService(NS_COOKIESERVICE_CONTRACTID);
@@ -1310,6 +1315,11 @@ nsHTMLDocument::SetCookie(const nsAString& aCookie, ErrorResult& rv)
return;
}
+ // If the document is a cookie-averse document, do nothing.
+ if (IsCookieAverse()) {
+ return;
+ }
+
// not having a cookie service isn't an error
nsCOMPtr<nsICookieService> service = do_GetService(NS_COOKIESERVICE_CONTRACTID);
if (service && mDocumentURI) {
diff --git a/dom/indexedDB/ActorsParent.cpp b/dom/indexedDB/ActorsParent.cpp
index 702d5c985..9d4e72f2f 100644
--- a/dom/indexedDB/ActorsParent.cpp
+++ b/dom/indexedDB/ActorsParent.cpp
@@ -7,6 +7,7 @@
#include "ActorsParent.h"
#include <algorithm>
+#include <stdint.h> // UINTPTR_MAX, uintptr_t
#include "FileInfo.h"
#include "FileManager.h"
#include "IDBObjectStore.h"
@@ -859,6 +860,11 @@ ReadCompressedIndexDataValuesFromBlob(const uint8_t* aBlobData,
"ReadCompressedIndexDataValuesFromBlob",
js::ProfileEntry::Category::STORAGE);
+ if (uintptr_t(aBlobData) > UINTPTR_MAX - aBlobDataLength) {
+ IDB_REPORT_INTERNAL_ERR();
+ return NS_ERROR_FILE_CORRUPTED;
+ }
+
const uint8_t* blobDataIter = aBlobData;
const uint8_t* blobDataEnd = aBlobData + aBlobDataLength;
@@ -878,7 +884,8 @@ ReadCompressedIndexDataValuesFromBlob(const uint8_t* aBlobData,
if (NS_WARN_IF(blobDataIter == blobDataEnd) ||
NS_WARN_IF(keyBufferLength > uint64_t(UINT32_MAX)) ||
- NS_WARN_IF(blobDataIter + keyBufferLength > blobDataEnd)) {
+ NS_WARN_IF(keyBufferLength > uintptr_t(blobDataEnd)) ||
+ NS_WARN_IF(blobDataIter > blobDataEnd - keyBufferLength)) {
IDB_REPORT_INTERNAL_ERR();
return NS_ERROR_FILE_CORRUPTED;
}
@@ -896,7 +903,8 @@ ReadCompressedIndexDataValuesFromBlob(const uint8_t* aBlobData,
if (sortKeyBufferLength > 0) {
if (NS_WARN_IF(blobDataIter == blobDataEnd) ||
NS_WARN_IF(sortKeyBufferLength > uint64_t(UINT32_MAX)) ||
- NS_WARN_IF(blobDataIter + sortKeyBufferLength > blobDataEnd)) {
+ NS_WARN_IF(sortKeyBufferLength > uintptr_t(blobDataEnd)) ||
+ NS_WARN_IF(blobDataIter > blobDataEnd - sortKeyBufferLength)) {
IDB_REPORT_INTERNAL_ERR();
return NS_ERROR_FILE_CORRUPTED;
}
@@ -18177,11 +18185,25 @@ QuotaClient::ShutdownWorkThreads()
mShutdownRequested = true;
+ // Shutdown maintenance thread pool (this spins the event loop until all
+ // threads are gone). This should release any maintenance related quota
+ // objects.
if (mMaintenanceThreadPool) {
mMaintenanceThreadPool->Shutdown();
mMaintenanceThreadPool = nullptr;
}
+ // Let any runnables dispatched from dying maintenance threads to be
+ // processed. This should release any maintenance related directory locks.
+ if (mCurrentMaintenance) {
+ nsIThread* currentThread = NS_GetCurrentThread();
+ MOZ_ASSERT(currentThread);
+
+ do {
+ MOZ_ALWAYS_TRUE(NS_ProcessNextEvent(currentThread));
+ } while (!mCurrentMaintenance);
+ }
+
RefPtr<ConnectionPool> connectionPool = gConnectionPool.get();
if (connectionPool) {
connectionPool->Shutdown();
@@ -18401,7 +18423,8 @@ Maintenance::Start()
AssertIsOnBackgroundThread();
MOZ_ASSERT(mState == State::Initial);
- if (IsAborted()) {
+ if (NS_WARN_IF(QuotaClient::IsShuttingDownOnBackgroundThread()) ||
+ IsAborted()) {
return NS_ERROR_ABORT;
}
@@ -18425,7 +18448,8 @@ Maintenance::CreateIndexedDatabaseManager()
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(mState == State::CreateIndexedDatabaseManager);
- if (IsAborted()) {
+ if (NS_WARN_IF(QuotaClient::IsShuttingDownOnNonBackgroundThread()) ||
+ IsAborted()) {
return NS_ERROR_ABORT;
}
@@ -18450,7 +18474,8 @@ Maintenance::OpenDirectory()
MOZ_ASSERT(!mDirectoryLock);
MOZ_ASSERT(QuotaManager::Get());
- if (IsAborted()) {
+ if (NS_WARN_IF(QuotaClient::IsShuttingDownOnBackgroundThread()) ||
+ IsAborted()) {
return NS_ERROR_ABORT;
}
@@ -18474,7 +18499,8 @@ Maintenance::DirectoryOpen()
MOZ_ASSERT(mState == State::DirectoryOpenPending);
MOZ_ASSERT(mDirectoryLock);
- if (IsAborted()) {
+ if (NS_WARN_IF(QuotaClient::IsShuttingDownOnBackgroundThread()) ||
+ IsAborted()) {
return NS_ERROR_ABORT;
}
@@ -18504,7 +18530,8 @@ Maintenance::DirectoryWork()
// We have to find all database files that match any persistence type and any
// origin. We ignore anything out of the ordinary for now.
- if (IsAborted()) {
+ if (NS_WARN_IF(QuotaClient::IsShuttingDownOnNonBackgroundThread()) ||
+ IsAborted()) {
return NS_ERROR_ABORT;
}
@@ -18691,8 +18718,10 @@ Maintenance::DirectoryWork()
continue;
}
+ nsCString suffix;
nsCString group;
nsCString origin;
+ bool isApp;
nsTArray<nsString> databasePaths;
while (true) {
@@ -18748,19 +18777,18 @@ Maintenance::DirectoryWork()
// Found a database.
if (databasePaths.IsEmpty()) {
+ MOZ_ASSERT(suffix.IsEmpty());
MOZ_ASSERT(group.IsEmpty());
MOZ_ASSERT(origin.IsEmpty());
int64_t dummyTimeStamp;
- nsCString dummySuffix;
- bool dummyIsApp;
if (NS_WARN_IF(NS_FAILED(
quotaManager->GetDirectoryMetadata2(originDir,
&dummyTimeStamp,
- dummySuffix,
+ suffix,
group,
origin,
- &dummyIsApp)))) {
+ &isApp)))) {
// Not much we can do here...
continue;
}
@@ -18776,6 +18804,22 @@ Maintenance::DirectoryWork()
group,
origin,
Move(databasePaths)));
+
+ nsCOMPtr<nsIFile> directory;
+
+ // Idle maintenance may occur before origin is initailized.
+ // Ensure origin is initialized first. It will initialize all origins
+ // for temporary storage including IDB origins.
+ rv = quotaManager->EnsureOriginIsInitialized(persistenceType,
+ suffix,
+ group,
+ origin,
+ isApp,
+ getter_AddRefs(directory));
+
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
}
}
}
@@ -18827,6 +18871,11 @@ Maintenance::BeginDatabaseMaintenance()
}
};
+ if (NS_WARN_IF(QuotaClient::IsShuttingDownOnBackgroundThread()) ||
+ IsAborted()) {
+ return NS_ERROR_ABORT;
+ }
+
RefPtr<nsThreadPool> threadPool;
for (DirectoryInfo& directoryInfo : mDirectoryInfos) {
@@ -19013,6 +19062,11 @@ DatabaseMaintenance::PerformMaintenanceOnDatabase()
}
};
+ if (NS_WARN_IF(QuotaClient::IsShuttingDownOnNonBackgroundThread()) ||
+ mMaintenance->IsAborted()) {
+ return;
+ }
+
nsCOMPtr<nsIFile> databaseFile = GetFileForPath(mDatabasePath);
MOZ_ASSERT(databaseFile);
@@ -19029,10 +19083,6 @@ DatabaseMaintenance::PerformMaintenanceOnDatabase()
AutoClose autoClose(connection);
- if (mMaintenance->IsAborted()) {
- return;
- }
-
AutoProgressHandler progressHandler(mMaintenance);
if (NS_WARN_IF(NS_FAILED(progressHandler.Register(connection)))) {
return;
@@ -19051,20 +19101,12 @@ DatabaseMaintenance::PerformMaintenanceOnDatabase()
return;
}
- if (mMaintenance->IsAborted()) {
- return;
- }
-
MaintenanceAction maintenanceAction;
rv = DetermineMaintenanceAction(connection, databaseFile, &maintenanceAction);
if (NS_WARN_IF(NS_FAILED(rv))) {
return;
}
- if (mMaintenance->IsAborted()) {
- return;
- }
-
switch (maintenanceAction) {
case MaintenanceAction::Nothing:
break;
@@ -19091,6 +19133,11 @@ DatabaseMaintenance::CheckIntegrity(mozIStorageConnection* aConnection,
MOZ_ASSERT(aConnection);
MOZ_ASSERT(aOk);
+ if (NS_WARN_IF(QuotaClient::IsShuttingDownOnNonBackgroundThread()) ||
+ mMaintenance->IsAborted()) {
+ return NS_ERROR_ABORT;
+ }
+
nsresult rv;
// First do a full integrity_check. Scope statements tightly here because
@@ -19208,6 +19255,11 @@ DatabaseMaintenance::DetermineMaintenanceAction(
MOZ_ASSERT(aDatabaseFile);
MOZ_ASSERT(aMaintenanceAction);
+ if (NS_WARN_IF(QuotaClient::IsShuttingDownOnNonBackgroundThread()) ||
+ mMaintenance->IsAborted()) {
+ return NS_ERROR_ABORT;
+ }
+
int32_t schemaVersion;
nsresult rv = aConnection->GetSchemaVersion(&schemaVersion);
if (NS_WARN_IF(NS_FAILED(rv))) {
@@ -19417,6 +19469,11 @@ DatabaseMaintenance::IncrementalVacuum(mozIStorageConnection* aConnection)
MOZ_ASSERT(!IsOnBackgroundThread());
MOZ_ASSERT(aConnection);
+ if (NS_WARN_IF(QuotaClient::IsShuttingDownOnNonBackgroundThread()) ||
+ mMaintenance->IsAborted()) {
+ return;
+ }
+
nsresult rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
"PRAGMA incremental_vacuum;"
));
@@ -19434,6 +19491,11 @@ DatabaseMaintenance::FullVacuum(mozIStorageConnection* aConnection,
MOZ_ASSERT(aConnection);
MOZ_ASSERT(aDatabaseFile);
+ if (NS_WARN_IF(QuotaClient::IsShuttingDownOnNonBackgroundThread()) ||
+ mMaintenance->IsAborted()) {
+ return;
+ }
+
nsresult rv = aConnection->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
"VACUUM;"
));
diff --git a/dom/interfaces/security/nsIContentSecurityPolicy.idl b/dom/interfaces/security/nsIContentSecurityPolicy.idl
index ade5b1243..51ca46f2a 100644
--- a/dom/interfaces/security/nsIContentSecurityPolicy.idl
+++ b/dom/interfaces/security/nsIContentSecurityPolicy.idl
@@ -98,6 +98,11 @@ interface nsIContentSecurityPolicy : nsISerializable
readonly attribute bool blockAllMixedContent;
/**
+ * Returns whether this policy enforces the frame-ancestors directive.
+ */
+ readonly attribute bool enforcesFrameAncestors;
+
+ /**
* Obtains the referrer policy (as integer) for this browsing context as
* specified in CSP. If there are multiple policies and...
* - only one sets a referrer policy: that policy is returned
diff --git a/dom/ipc/ContentProcess.cpp b/dom/ipc/ContentProcess.cpp
index 66125f332..2413d8808 100644
--- a/dom/ipc/ContentProcess.cpp
+++ b/dom/ipc/ContentProcess.cpp
@@ -8,10 +8,6 @@
#include "ContentProcess.h"
-#if defined(XP_WIN) && defined(MOZ_CONTENT_SANDBOX)
-#include "mozilla/WindowsVersion.h"
-#endif
-
#if defined(XP_MACOSX) && defined(MOZ_CONTENT_SANDBOX)
#include <stdlib.h>
#endif
@@ -33,9 +29,8 @@ static bool
IsSandboxTempDirRequired()
{
// On Windows, a sandbox-writable temp directory is only used
- // for Vista or later with sandbox pref level >= 1.
- return (IsVistaOrLater() &&
- (Preferences::GetInt("security.sandbox.content.level") >= 1));
+ // when sandbox pref level >= 1.
+ return Preferences::GetInt("security.sandbox.content.level") >= 1;
}
static void
diff --git a/dom/locales/en-US/chrome/security/csp.properties b/dom/locales/en-US/chrome/security/csp.properties
index fc7fc04ba..4124ef8aa 100644
--- a/dom/locales/en-US/chrome/security/csp.properties
+++ b/dom/locales/en-US/chrome/security/csp.properties
@@ -91,6 +91,10 @@ ignoringReportOnlyDirective = Ignoring sandbox directive when delivered in a rep
# LOCALIZATION NOTE (deprecatedReferrerDirective):
# %1$S is the value of the deprecated Referrer Directive.
deprecatedReferrerDirective = Referrer Directive ‘%1$S’ has been deprecated. Please use the Referrer-Policy header instead.
+# LOCALIZATION NOTE (IgnoringSrcBecauseOfDirective):
+# %1$S is the name of the src that is ignored.
+# %2$S is the name of the directive that causes the src to be ignored.
+IgnoringSrcBecauseOfDirective=Ignoring ‘%1$S’ because of ‘%2$S’ directive.
# CSP Errors:
# LOCALIZATION NOTE (couldntParseInvalidSource):
diff --git a/dom/media/Benchmark.cpp b/dom/media/Benchmark.cpp
index a4761f1b1..1ba6e561c 100644
--- a/dom/media/Benchmark.cpp
+++ b/dom/media/Benchmark.cpp
@@ -22,7 +22,7 @@ namespace mozilla {
// Update this version number to force re-running the benchmark. Such as when
// an improvement to FFVP9 or LIBVPX is deemed worthwhile.
-const uint32_t VP9Benchmark::sBenchmarkVersionID = 1;
+const uint32_t VP9Benchmark::sBenchmarkVersionID = 2;
const char* VP9Benchmark::sBenchmarkFpsPref = "media.benchmark.vp9.fps";
const char* VP9Benchmark::sBenchmarkFpsVersionCheck = "media.benchmark.vp9.versioncheck";
diff --git a/dom/media/DecoderDoctorDiagnostics.cpp b/dom/media/DecoderDoctorDiagnostics.cpp
index 91c2d8dfb..778e8c4c5 100644
--- a/dom/media/DecoderDoctorDiagnostics.cpp
+++ b/dom/media/DecoderDoctorDiagnostics.cpp
@@ -576,16 +576,9 @@ DecoderDoctorDocumentWatcher::SynthesizeAnalysis()
// going through expected decoders from most to least desirable.
#if defined(XP_WIN)
if (!formatsRequiringWMF.IsEmpty()) {
- if (IsVistaOrLater()) {
- DD_INFO("DecoderDoctorDocumentWatcher[%p, doc=%p]::SynthesizeAnalysis() - unplayable formats: %s -> Cannot play media because WMF was not found",
- this, mDocument, NS_ConvertUTF16toUTF8(formatsRequiringWMF).get());
- ReportAnalysis(mDocument, sMediaWMFNeeded, false, formatsRequiringWMF);
- } else {
- DD_INFO("DecoderDoctorDocumentWatcher[%p, doc=%p]::SynthesizeAnalysis() - unplayable formats: %s -> Cannot play media before Windows Vista",
- this, mDocument, NS_ConvertUTF16toUTF8(formatsRequiringWMF).get());
- ReportAnalysis(mDocument, sMediaUnsupportedBeforeWindowsVista,
- false, formatsRequiringWMF);
- }
+ DD_INFO("DecoderDoctorDocumentWatcher[%p, doc=%p]::SynthesizeAnalysis() - unplayable formats: %s -> Cannot play media because WMF was not found",
+ this, mDocument, NS_ConvertUTF16toUTF8(formatsRequiringWMF).get());
+ ReportAnalysis(mDocument, sMediaWMFNeeded, false, formatsRequiringWMF);
return;
}
#endif
diff --git a/dom/media/MediaManager.cpp b/dom/media/MediaManager.cpp
index 96e2c23e0..97a6855d9 100644
--- a/dom/media/MediaManager.cpp
+++ b/dom/media/MediaManager.cpp
@@ -1853,20 +1853,18 @@ MediaManager::GetNonE10sParent()
MediaManager::StartupInit()
{
#ifdef WIN32
- if (IsVistaOrLater() && !IsWin8OrLater()) {
- // Bug 1107702 - Older Windows fail in GetAdaptersInfo (and others) if the
- // first(?) call occurs after the process size is over 2GB (kb/2588507).
- // Attempt to 'prime' the pump by making a call at startup.
- unsigned long out_buf_len = sizeof(IP_ADAPTER_INFO);
- PIP_ADAPTER_INFO pAdapterInfo = (IP_ADAPTER_INFO *) moz_xmalloc(out_buf_len);
- if (GetAdaptersInfo(pAdapterInfo, &out_buf_len) == ERROR_BUFFER_OVERFLOW) {
- free(pAdapterInfo);
- pAdapterInfo = (IP_ADAPTER_INFO *) moz_xmalloc(out_buf_len);
- GetAdaptersInfo(pAdapterInfo, &out_buf_len);
- }
- if (pAdapterInfo) {
- free(pAdapterInfo);
- }
+ // Bug 1107702 - Some Windows versions fail in GetAdaptersInfo (and others)
+ // if the first(?) call occurs after the process size is over 2GB (kb/2588507).
+ // Attempt to 'prime' the pump by making a call at startup.
+ unsigned long out_buf_len = sizeof(IP_ADAPTER_INFO);
+ PIP_ADAPTER_INFO pAdapterInfo = (IP_ADAPTER_INFO *) moz_xmalloc(out_buf_len);
+ if (GetAdaptersInfo(pAdapterInfo, &out_buf_len) == ERROR_BUFFER_OVERFLOW) {
+ free(pAdapterInfo);
+ pAdapterInfo = (IP_ADAPTER_INFO *) moz_xmalloc(out_buf_len);
+ GetAdaptersInfo(pAdapterInfo, &out_buf_len);
+ }
+ if (pAdapterInfo) {
+ free(pAdapterInfo);
}
#endif
}
@@ -2130,19 +2128,11 @@ if (privileged) {
case MediaSourceEnum::Application:
case MediaSourceEnum::Window:
// Deny screensharing request if support is disabled, or
- // the requesting document is not from a host on the whitelist, or
- // we're on WinXP until proved that it works
+ // the requesting document is not from a host on the whitelist
if (!Preferences::GetBool(((videoType == MediaSourceEnum::Browser)?
"media.getusermedia.browser.enabled" :
"media.getusermedia.screensharing.enabled"),
false) ||
-#if defined(XP_WIN)
- (
- // Allow tab sharing for all platforms including XP
- (videoType != MediaSourceEnum::Browser) &&
- !Preferences::GetBool("media.getusermedia.screensharing.allow_on_old_platforms",
- false) && !IsVistaOrLater()) ||
-#endif
(!privileged && !HostIsHttps(*docURI))) {
RefPtr<MediaStreamError> error =
new MediaStreamError(aWindow,
diff --git a/dom/media/eme/MediaKeySystemAccess.cpp b/dom/media/eme/MediaKeySystemAccess.cpp
index 7007d3a03..4cff464e7 100644
--- a/dom/media/eme/MediaKeySystemAccess.cpp
+++ b/dom/media/eme/MediaKeySystemAccess.cpp
@@ -140,26 +140,12 @@ MediaKeySystemAccess::GetKeySystemStatus(const nsAString& aKeySystem,
aOutMessage = NS_LITERAL_CSTRING("Adobe EME disabled");
return MediaKeySystemStatus::Cdm_disabled;
}
-#ifdef XP_WIN
- // Win Vista and later only.
- if (!IsVistaOrLater()) {
- aOutMessage = NS_LITERAL_CSTRING("Minimum Windows version (Vista) not met for Adobe EME");
- return MediaKeySystemStatus::Cdm_not_supported;
- }
-#endif
return EnsureCDMInstalled(aKeySystem, aOutMessage);
}
}
if (IsWidevineKeySystem(aKeySystem)) {
if (Preferences::GetBool("media.gmp-widevinecdm.visible", false)) {
-#ifdef XP_WIN
- // Win Vista and later only.
- if (!IsVistaOrLater()) {
- aOutMessage = NS_LITERAL_CSTRING("Minimum Windows version (Vista) not met for Widevine EME");
- return MediaKeySystemStatus::Cdm_not_supported;
- }
-#endif
if (!Preferences::GetBool("media.gmp-widevinecdm.enabled", false)) {
aOutMessage = NS_LITERAL_CSTRING("Widevine EME disabled");
return MediaKeySystemStatus::Cdm_disabled;
diff --git a/dom/media/fmp4/MP4Decoder.cpp b/dom/media/fmp4/MP4Decoder.cpp
index 4cf07ddbd..fdd6f2c7e 100644
--- a/dom/media/fmp4/MP4Decoder.cpp
+++ b/dom/media/fmp4/MP4Decoder.cpp
@@ -52,14 +52,6 @@ IsWhitelistedH264Codec(const nsAString& aCodec)
return false;
}
-#ifdef XP_WIN
- // Disable 4k video on windows vista since it performs poorly.
- if (!IsWin7OrLater() &&
- level >= H264_LEVEL_5) {
- return false;
- }
-#endif
-
// Just assume what we can play on all platforms the codecs/formats that
// WMF can play, since we don't have documentation about what other
// platforms can play... According to the WMF documentation:
diff --git a/dom/media/gtest/TestGMPCrossOrigin.cpp b/dom/media/gtest/TestGMPCrossOrigin.cpp
index 036282153..33ac98388 100644
--- a/dom/media/gtest/TestGMPCrossOrigin.cpp
+++ b/dom/media/gtest/TestGMPCrossOrigin.cpp
@@ -1521,11 +1521,6 @@ TEST(GeckoMediaPlugins, GMPPluginVoucher) {
#if defined(XP_WIN)
TEST(GeckoMediaPlugins, GMPOutputProtection) {
- // Output Protection is not available pre-Vista.
- if (!IsVistaOrLater()) {
- return;
- }
-
RefPtr<GMPStorageTest> runner = new GMPStorageTest();
runner->DoTest(&GMPStorageTest::TestOutputProtection);
}
diff --git a/dom/media/platforms/PDMFactory.cpp b/dom/media/platforms/PDMFactory.cpp
index a72d910f5..c1e58fdc2 100644
--- a/dom/media/platforms/PDMFactory.cpp
+++ b/dom/media/platforms/PDMFactory.cpp
@@ -47,10 +47,6 @@
#include "MP4Decoder.h"
#include "mozilla/dom/RemoteVideoDecoder.h"
-#ifdef XP_WIN
-#include "mozilla/WindowsVersion.h"
-#endif
-
#include "mp4_demuxer/H264.h"
namespace mozilla {
@@ -367,16 +363,7 @@ PDMFactory::CreatePDMs()
}
#endif
#ifdef XP_WIN
- if (MediaPrefs::PDMWMFEnabled() && IsVistaOrLater() && !IsWin7AndPre2000Compatible()) {
- // *Only* use WMF on Vista and later, as if Firefox is run in Windows 95
- // compatibility mode on Windows 7 (it does happen!) we may crash trying
- // to startup WMF. So we need to detect the OS version here, as in
- // compatibility mode IsVistaOrLater() and friends behave as if we're on
- // the emulated version of Windows. See bug 1279171.
- // Additionally, we don't want to start the RemoteDecoderModule if we
- // expect it's not going to work (i.e. on Windows older than Vista).
- // IsWin7AndPre2000Compatible() uses GetVersionEx as the user specified OS version can
- // be reflected when compatibility mode is in effect.
+ if (MediaPrefs::PDMWMFEnabled()) {
m = new WMFDecoderModule();
RefPtr<PlatformDecoderModule> remote = new dom::RemoteDecoderModule(m);
StartupPDM(remote);
diff --git a/dom/media/platforms/wmf/WMF.h b/dom/media/platforms/wmf/WMF.h
index 5ede0d361..6988ef083 100644
--- a/dom/media/platforms/wmf/WMF.h
+++ b/dom/media/platforms/wmf/WMF.h
@@ -7,18 +7,6 @@
#ifndef WMF_H_
#define WMF_H_
-#if WINVER < _WIN32_WINNT_WIN7
-#error \
-You must include WMF.h before including mozilla headers, \
-otherwise mozconfig.h will be included \
-and that sets WINVER to WinXP, \
-which makes Windows Media Foundation unavailable.
-#endif
-
-#pragma push_macro("WINVER")
-#undef WINVER
-#define WINVER _WIN32_WINNT_WIN7
-
#include <windows.h>
#include <mfapi.h>
#include <mfidl.h>
@@ -35,7 +23,7 @@ which makes Windows Media Foundation unavailable.
#include <codecapi.h>
// The Windows headers helpfully declare min and max macros, which don't
-// compile in the prescence of std::min and std::max and unified builds.
+// compile in the presence of std::min and std::max and unified builds.
// So undef them here.
#ifdef min
#undef min
@@ -97,8 +85,4 @@ HRESULT MFCreateDXGISurfaceBuffer(REFIID riid,
} // end namespace wmf
} // end namespace mozilla
-
-
-#pragma pop_macro("WINVER")
-
#endif
diff --git a/dom/media/platforms/wmf/WMFUtils.cpp b/dom/media/platforms/wmf/WMFUtils.cpp
index 8aec8a8af..055012d0f 100644
--- a/dom/media/platforms/wmf/WMFUtils.cpp
+++ b/dom/media/platforms/wmf/WMFUtils.cpp
@@ -205,31 +205,17 @@ LoadDLLs()
HRESULT
MFStartup()
{
- if (!IsVistaOrLater() || IsWin7AndPre2000Compatible()) {
- // *Only* use WMF on Vista and later, as if Firefox is run in Windows 95
- // compatibility mode on Windows 7 (it does happen!) we may crash trying
- // to startup WMF. So we need to detect the OS version here, as in
- // compatibility mode IsVistaOrLater() and friends behave as if we're on
- // the emulated version of Windows. See bug 1279171.
- // Using GetVersionEx API which takes compatibility mode into account.
- return E_FAIL;
- }
-
HRESULT hr = LoadDLLs();
if (FAILED(hr)) {
return hr;
}
- const int MF_VISTA_VERSION = (0x0001 << 16 | MF_API_VERSION);
const int MF_WIN7_VERSION = (0x0002 << 16 | MF_API_VERSION);
// decltype is unusable for functions having default parameters
DECL_FUNCTION_PTR(MFStartup, ULONG, DWORD);
ENSURE_FUNCTION_PTR_(MFStartup, Mfplat.dll)
- if (!IsWin7OrLater())
- return MFStartupPtr(MF_VISTA_VERSION, MFSTARTUP_FULL);
- else
- return MFStartupPtr(MF_WIN7_VERSION, MFSTARTUP_FULL);
+ return MFStartupPtr(MF_WIN7_VERSION, MFSTARTUP_FULL);
}
HRESULT
diff --git a/dom/media/systemservices/MediaParent.cpp b/dom/media/systemservices/MediaParent.cpp
index 109a44a28..89a495f6a 100644
--- a/dom/media/systemservices/MediaParent.cpp
+++ b/dom/media/systemservices/MediaParent.cpp
@@ -37,6 +37,7 @@ mozilla::LazyLogModule gMediaParentLog("MediaParent");
namespace mozilla {
namespace media {
+StaticMutex sOriginKeyStoreMutex;
static OriginKeyStore* sOriginKeyStore = nullptr;
class OriginKeyStore : public nsISupports
@@ -332,6 +333,7 @@ class OriginKeyStore : public nsISupports
private:
virtual ~OriginKeyStore()
{
+ StaticMutexAutoLock lock(sOriginKeyStoreMutex);
sOriginKeyStore = nullptr;
LOG((__FUNCTION__));
}
@@ -340,6 +342,7 @@ public:
static OriginKeyStore* Get()
{
MOZ_ASSERT(NS_IsMainThread());
+ StaticMutexAutoLock lock(sOriginKeyStoreMutex);
if (!sOriginKeyStore) {
sOriginKeyStore = new OriginKeyStore();
}
@@ -384,8 +387,8 @@ Parent<Super>::RecvGetOriginKey(const uint32_t& aRequestId,
return false;
}
- // Then over to stream-transport thread to do the actual file io.
- // Stash a pledge to hold the answer and get an id for this request.
+ // Then over to stream-transport thread (a thread pool) to do the actual
+ // file io. Stash a pledge to hold the answer and get an id for this request.
RefPtr<Pledge<nsCString>> p = new Pledge<nsCString>();
uint32_t id = mOutstandingPledges.Append(*p);
@@ -397,12 +400,17 @@ Parent<Super>::RecvGetOriginKey(const uint32_t& aRequestId,
rv = sts->Dispatch(NewRunnableFrom([this, that, id, profileDir, aOrigin,
aPrivateBrowsing, aPersist]() -> nsresult {
MOZ_ASSERT(!NS_IsMainThread());
- mOriginKeyStore->mOriginKeys.SetProfileDir(profileDir);
+ StaticMutexAutoLock lock(sOriginKeyStoreMutex);
+ if (!sOriginKeyStore) {
+ return NS_ERROR_FAILURE;
+ }
+ sOriginKeyStore->mOriginKeys.SetProfileDir(profileDir);
+
nsCString result;
if (aPrivateBrowsing) {
- mOriginKeyStore->mPrivateBrowsingOriginKeys.GetOriginKey(aOrigin, result);
+ sOriginKeyStore->mPrivateBrowsingOriginKeys.GetOriginKey(aOrigin, result);
} else {
- mOriginKeyStore->mOriginKeys.GetOriginKey(aOrigin, result, aPersist);
+ sOriginKeyStore->mOriginKeys.GetOriginKey(aOrigin, result, aPersist);
}
// Pass result back to main thread.
@@ -450,19 +458,21 @@ Parent<Super>::RecvSanitizeOriginKeys(const uint64_t& aSinceWhen,
if (NS_WARN_IF(NS_FAILED(rv))) {
return false;
}
- // Over to stream-transport thread to do the file io.
+ // Over to stream-transport thread (a thread pool) to do the file io.
nsCOMPtr<nsIEventTarget> sts = do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID);
MOZ_ASSERT(sts);
- RefPtr<OriginKeyStore> store(mOriginKeyStore);
-
- rv = sts->Dispatch(NewRunnableFrom([profileDir, store, aSinceWhen,
+ rv = sts->Dispatch(NewRunnableFrom([profileDir, aSinceWhen,
aOnlyPrivateBrowsing]() -> nsresult {
MOZ_ASSERT(!NS_IsMainThread());
- store->mPrivateBrowsingOriginKeys.Clear(aSinceWhen);
+ StaticMutexAutoLock lock(sOriginKeyStoreMutex);
+ if (!sOriginKeyStore) {
+ return NS_ERROR_FAILURE;
+ }
+ sOriginKeyStore->mPrivateBrowsingOriginKeys.Clear(aSinceWhen);
if (!aOnlyPrivateBrowsing) {
- store->mOriginKeys.SetProfileDir(profileDir);
- store->mOriginKeys.Clear(aSinceWhen);
+ sOriginKeyStore->mOriginKeys.SetProfileDir(profileDir);
+ sOriginKeyStore->mOriginKeys.Clear(aSinceWhen);
}
return NS_OK;
}), NS_DISPATCH_NORMAL);
diff --git a/dom/media/webrtc/MediaEngineWebRTC.cpp b/dom/media/webrtc/MediaEngineWebRTC.cpp
index 522f23f61..1a2dc9a04 100644
--- a/dom/media/webrtc/MediaEngineWebRTC.cpp
+++ b/dom/media/webrtc/MediaEngineWebRTC.cpp
@@ -268,11 +268,7 @@ MediaEngineWebRTC::EnumerateVideoDevices(dom::MediaSourceEnum aMediaSource,
bool
MediaEngineWebRTC::SupportsDuplex()
{
-#ifndef XP_WIN
return mFullDuplex;
-#else
- return IsVistaOrLater() && mFullDuplex;
-#endif
}
void
diff --git a/dom/plugins/base/nsPluginHost.cpp b/dom/plugins/base/nsPluginHost.cpp
index 6ee23f38b..bd71d6f65 100644
--- a/dom/plugins/base/nsPluginHost.cpp
+++ b/dom/plugins/base/nsPluginHost.cpp
@@ -2024,45 +2024,9 @@ struct CompareFilesByTime
} // namespace
-bool
-nsPluginHost::ShouldAddPlugin(nsPluginTag* aPluginTag)
-{
-#if defined(XP_WIN) && (defined(__x86_64__) || defined(_M_X64))
- // On 64-bit windows, the only plugins we should load are flash and
- // silverlight. Use library filename and MIME type to check.
- if (StringBeginsWith(aPluginTag->FileName(), NS_LITERAL_CSTRING("NPSWF"), nsCaseInsensitiveCStringComparator()) &&
- (aPluginTag->HasMimeType(NS_LITERAL_CSTRING("application/x-shockwave-flash")) ||
- aPluginTag->HasMimeType(NS_LITERAL_CSTRING("application/x-shockwave-flash-test")))) {
- return true;
- }
- if (StringBeginsWith(aPluginTag->FileName(), NS_LITERAL_CSTRING("npctrl"), nsCaseInsensitiveCStringComparator()) &&
- (aPluginTag->HasMimeType(NS_LITERAL_CSTRING("application/x-silverlight-test")) ||
- aPluginTag->HasMimeType(NS_LITERAL_CSTRING("application/x-silverlight-2")) ||
- aPluginTag->HasMimeType(NS_LITERAL_CSTRING("application/x-silverlight")))) {
- return true;
- }
- // Accept the test plugin MIME types, so mochitests still work.
- if (aPluginTag->HasMimeType(NS_LITERAL_CSTRING("application/x-test")) ||
- aPluginTag->HasMimeType(NS_LITERAL_CSTRING("application/x-Second-Test")) ||
- aPluginTag->HasMimeType(NS_LITERAL_CSTRING("application/x-java-test"))) {
- return true;
- }
-#ifdef PLUGIN_LOGGING
- PLUGIN_LOG(PLUGIN_LOG_NORMAL,
- ("ShouldAddPlugin : Ignoring non-flash plugin library %s\n", aPluginTag->FileName().get()));
-#endif // PLUGIN_LOGGING
- return false;
-#else
- return true;
-#endif // defined(XP_WIN) && (defined(__x86_64__) || defined(_M_X64))
-}
-
void
nsPluginHost::AddPluginTag(nsPluginTag* aPluginTag)
{
- if (!ShouldAddPlugin(aPluginTag)) {
- return;
- }
aPluginTag->mNext = mPlugins;
mPlugins = aPluginTag;
@@ -2078,22 +2042,6 @@ nsPluginHost::AddPluginTag(nsPluginTag* aPluginTag)
}
}
-static bool
-PluginInfoIsFlash(const nsPluginInfo& info)
-{
- if (!info.fName || strcmp(info.fName, "Shockwave Flash") != 0) {
- return false;
- }
- for (uint32_t i = 0; i < info.fVariantCount; ++i) {
- if (info.fMimeTypeArray[i] &&
- (!strcmp(info.fMimeTypeArray[i], "application/x-shockwave-flash") ||
- !strcmp(info.fMimeTypeArray[i], "application/x-shockwave-flash-test"))) {
- return true;
- }
- }
- return false;
-}
-
typedef NS_NPAPIPLUGIN_CALLBACK(char *, NP_GETMIMEDESCRIPTION)(void);
nsresult nsPluginHost::ScanPluginsDirectory(nsIFile *pluginsDir,
@@ -2114,8 +2062,6 @@ nsresult nsPluginHost::ScanPluginsDirectory(nsIFile *pluginsDir,
("nsPluginHost::ScanPluginsDirectory dir=%s\n", dirPath.get()));
#endif
- bool flashOnly = Preferences::GetBool("plugin.load_flash_only", true);
-
nsCOMPtr<nsISimpleEnumerator> iter;
rv = pluginsDir->GetDirectoryEntries(getter_AddRefs(iter));
if (NS_FAILED(rv))
@@ -2218,8 +2164,7 @@ nsresult nsPluginHost::ScanPluginsDirectory(nsIFile *pluginsDir,
res = pluginFile.GetPluginInfo(info, &library);
}
// if we don't have mime type don't proceed, this is not a plugin
- if (NS_FAILED(res) || !info.fMimeTypeArray ||
- (flashOnly && !PluginInfoIsFlash(info))) {
+ if (NS_FAILED(res) || !info.fMimeTypeArray) {
RefPtr<nsInvalidPluginTag> invalidTag = new nsInvalidPluginTag(filePath.get(),
fileModTime);
pluginFile.FreePluginInfo(info);
@@ -2867,14 +2812,12 @@ nsPluginHost::WritePluginInfo()
return rv;
}
- bool flashOnly = Preferences::GetBool("plugin.load_flash_only", true);
-
PR_fprintf(fd, "Generated File. Do not edit.\n");
PR_fprintf(fd, "\n[HEADER]\nVersion%c%s%c%c%c\nArch%c%s%c%c\n",
PLUGIN_REGISTRY_FIELD_DELIMITER,
kPluginRegistryVersion,
- flashOnly ? 't' : 'f',
+ 'f', //flashOnly
PLUGIN_REGISTRY_FIELD_DELIMITER,
PLUGIN_REGISTRY_END_OF_LINE_MARKER,
PLUGIN_REGISTRY_FIELD_DELIMITER,
@@ -3071,9 +3014,8 @@ nsPluginHost::ReadPluginInfo()
// If we're reading an old registry, ignore it
// If we flipped the flash-only pref, ignore it
- bool flashOnly = Preferences::GetBool("plugin.load_flash_only", true);
nsAutoCString expectedVersion(kPluginRegistryVersion);
- expectedVersion.Append(flashOnly ? 't' : 'f');
+ expectedVersion.Append('f'); //flashOnly
if (!expectedVersion.Equals(values[1])) {
return rv;
@@ -3214,10 +3156,6 @@ nsPluginHost::ReadPluginInfo()
MOZ_LOG(nsPluginLogging::gPluginLog, PLUGIN_LOG_BASIC,
("LoadCachedPluginsInfo : Loading Cached plugininfo for %s\n", tag->FileName().get()));
- if (!ShouldAddPlugin(tag)) {
- continue;
- }
-
tag->mNext = mCachedPlugins;
mCachedPlugins = tag;
}
diff --git a/dom/plugins/ipc/hangui/plugin-hang-ui.exe.manifest b/dom/plugins/ipc/hangui/plugin-hang-ui.exe.manifest
index 8d6149c58..f5b7345f9 100644
--- a/dom/plugins/ipc/hangui/plugin-hang-ui.exe.manifest
+++ b/dom/plugins/ipc/hangui/plugin-hang-ui.exe.manifest
@@ -32,7 +32,6 @@
<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
- <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/>
</application>
</compatibility>
</assembly>
diff --git a/dom/plugins/test/unit/xpcshell.ini b/dom/plugins/test/unit/xpcshell.ini
index 8dae66b20..69b6731b2 100644
--- a/dom/plugins/test/unit/xpcshell.ini
+++ b/dom/plugins/test/unit/xpcshell.ini
@@ -5,7 +5,7 @@ tail =
tags = addons
firefox-appdir = browser
support-files =
- !/toolkit/mozapps/extensions/test/xpcshell/head_addons.js
+ !/toolkit/mozapps/webextensions/test/xpcshell/head_addons.js
[test_allowed_types.js]
skip-if = appname == "thunderbird"
diff --git a/dom/security/nsCSPContext.cpp b/dom/security/nsCSPContext.cpp
index 815c7734d..5e435d4ca 100644
--- a/dom/security/nsCSPContext.cpp
+++ b/dom/security/nsCSPContext.cpp
@@ -156,10 +156,13 @@ nsCSPContext::ShouldLoad(nsContentPolicyType aContentType,
nsAutoString nonce;
bool parserCreated = false;
if (!isPreload) {
- nsCOMPtr<nsIDOMHTMLElement> htmlElement = do_QueryInterface(aRequestContext);
- if (htmlElement) {
- rv = htmlElement->GetAttribute(NS_LITERAL_STRING("nonce"), nonce);
- NS_ENSURE_SUCCESS(rv, rv);
+ if (aContentType == nsIContentPolicy::TYPE_SCRIPT ||
+ aContentType == nsIContentPolicy::TYPE_STYLESHEET) {
+ nsCOMPtr<nsIDOMHTMLElement> htmlElement = do_QueryInterface(aRequestContext);
+ if (htmlElement) {
+ rv = htmlElement->GetAttribute(NS_LITERAL_STRING("nonce"), nonce);
+ NS_ENSURE_SUCCESS(rv, rv);
+ }
}
nsCOMPtr<nsIScriptElement> script = do_QueryInterface(aRequestContext);
@@ -343,6 +346,20 @@ nsCSPContext::GetBlockAllMixedContent(bool *outBlockAllMixedContent)
}
NS_IMETHODIMP
+nsCSPContext::GetEnforcesFrameAncestors(bool *outEnforcesFrameAncestors)
+{
+ *outEnforcesFrameAncestors = false;
+ for (uint32_t i = 0; i < mPolicies.Length(); i++) {
+ if (!mPolicies[i]->getReportOnlyFlag() &&
+ mPolicies[i]->hasDirective(nsIContentSecurityPolicy::FRAME_ANCESTORS_DIRECTIVE)) {
+ *outEnforcesFrameAncestors = true;
+ return NS_OK;
+ }
+ }
+ return NS_OK;
+}
+
+NS_IMETHODIMP
nsCSPContext::GetReferrerPolicy(uint32_t* outPolicy, bool* outIsSet)
{
*outIsSet = false;
diff --git a/dom/security/nsCSPParser.cpp b/dom/security/nsCSPParser.cpp
index a662c9cd1..86aa4e001 100644
--- a/dom/security/nsCSPParser.cpp
+++ b/dom/security/nsCSPParser.cpp
@@ -136,6 +136,7 @@ nsCSPParser::nsCSPParser(cspTokens& aTokens,
, mUnsafeInlineKeywordSrc(nullptr)
, mChildSrc(nullptr)
, mFrameSrc(nullptr)
+ , mParsingFrameAncestorsDir(false)
, mTokens(aTokens)
, mSelfURI(aSelfURI)
, mPolicy(nullptr)
@@ -531,7 +532,7 @@ nsCSPParser::keywordSource()
// Special case handling for 'self' which is not stored internally as a keyword,
// but rather creates a nsCSPHostSrc using the selfURI
if (CSP_IsKeyword(mCurToken, CSP_SELF)) {
- return CSP_CreateHostSrcFromURI(mSelfURI);
+ return CSP_CreateHostSrcFromSelfURI(mSelfURI);
}
if (CSP_IsKeyword(mCurToken, CSP_STRICT_DYNAMIC)) {
@@ -807,6 +808,7 @@ nsCSPParser::sourceExpression()
if (nsCSPHostSrc *cspHost = hostSource()) {
// Do not forget to set the parsed scheme.
cspHost->setScheme(parsedScheme);
+ cspHost->setWithinFrameAncestorsDir(mParsingFrameAncestorsDir);
return cspHost;
}
// Error was reported in hostSource()
@@ -1209,6 +1211,9 @@ nsCSPParser::directive()
mStrictDynamic = false;
mUnsafeInlineKeywordSrc = nullptr;
+ mParsingFrameAncestorsDir =
+ CSP_IsDirective(mCurDir[0], nsIContentSecurityPolicy::FRAME_ANCESTORS_DIRECTIVE);
+
// Try to parse all the srcs by handing the array off to directiveValue
nsTArray<nsCSPBaseSrc*> srcs;
directiveValue(srcs);
diff --git a/dom/security/nsCSPParser.h b/dom/security/nsCSPParser.h
index 30954b10f..1bfc56c65 100644
--- a/dom/security/nsCSPParser.h
+++ b/dom/security/nsCSPParser.h
@@ -252,6 +252,10 @@ class nsCSPParser {
nsCSPChildSrcDirective* mChildSrc;
nsCSPDirective* mFrameSrc;
+ // cache variable to let nsCSPHostSrc know that it's within
+ // the frame-ancestors directive.
+ bool mParsingFrameAncestorsDir;
+
cspTokens mTokens;
nsIURI* mSelfURI;
nsCSPPolicy* mPolicy;
diff --git a/dom/security/nsCSPUtils.cpp b/dom/security/nsCSPUtils.cpp
index 63b4aae2c..a5f683b01 100644
--- a/dom/security/nsCSPUtils.cpp
+++ b/dom/security/nsCSPUtils.cpp
@@ -266,20 +266,21 @@ CSP_ContentTypeToDirective(nsContentPolicyType aType)
}
nsCSPHostSrc*
-CSP_CreateHostSrcFromURI(nsIURI* aURI)
+CSP_CreateHostSrcFromSelfURI(nsIURI* aSelfURI)
{
// Create the host first
nsCString host;
- aURI->GetHost(host);
+ aSelfURI->GetAsciiHost(host);
nsCSPHostSrc *hostsrc = new nsCSPHostSrc(NS_ConvertUTF8toUTF16(host));
+ hostsrc->setGeneratedFromSelfKeyword();
// Add the scheme.
nsCString scheme;
- aURI->GetScheme(scheme);
+ aSelfURI->GetScheme(scheme);
hostsrc->setScheme(NS_ConvertUTF8toUTF16(scheme));
int32_t port;
- aURI->GetPort(&port);
+ aSelfURI->GetPort(&port);
// Only add port if it's not default port.
if (port > 0) {
nsAutoString portStr;
@@ -348,13 +349,17 @@ CSP_IsQuotelessKeyword(const nsAString& aKey)
* @param aUpgradeInsecure
* Whether the policy makes use of the directive
* 'upgrade-insecure-requests'.
+ * @param aFromSelfURI
+ * Whether a scheme was generated from the keyword 'self'
+ * which then allows schemeless sources to match ws and wss.
*/
bool
permitsScheme(const nsAString& aEnforcementScheme,
nsIURI* aUri,
bool aReportOnly,
- bool aUpgradeInsecure)
+ bool aUpgradeInsecure,
+ bool aFromSelfURI)
{
nsAutoCString scheme;
nsresult rv = aUri->GetScheme(scheme);
@@ -373,8 +378,20 @@ permitsScheme(const nsAString& aEnforcementScheme,
// allow scheme-less sources where the protected resource is http
// and the load is https, see:
// http://www.w3.org/TR/CSP2/#match-source-expression
- if (aEnforcementScheme.EqualsASCII("http") &&
- scheme.EqualsASCII("https")) {
+ if (aEnforcementScheme.EqualsASCII("http")) {
+ if (scheme.EqualsASCII("https")) {
+ return true;
+ }
+ if ((scheme.EqualsASCII("ws") || scheme.EqualsASCII("wss")) && aFromSelfURI) {
+ return true;
+ }
+ }
+ if (aEnforcementScheme.EqualsASCII("https")) {
+ if (scheme.EqualsLiteral("wss") && aFromSelfURI) {
+ return true;
+ }
+ }
+ if (aEnforcementScheme.EqualsASCII("ws") && scheme.EqualsASCII("wss")) {
return true;
}
@@ -483,7 +500,7 @@ nsCSPSchemeSrc::permits(nsIURI* aUri, const nsAString& aNonce, bool aWasRedirect
if (mInvalidated) {
return false;
}
- return permitsScheme(mScheme, aUri, aReportOnly, aUpgradeInsecure);
+ return permitsScheme(mScheme, aUri, aReportOnly, aUpgradeInsecure, false);
}
bool
@@ -503,6 +520,8 @@ nsCSPSchemeSrc::toString(nsAString& outStr) const
nsCSPHostSrc::nsCSPHostSrc(const nsAString& aHost)
: mHost(aHost)
+ , mGeneratedFromSelfKeyword(false)
+ , mWithinFrameAncstorsDir(false)
{
ToLowerCase(mHost);
}
@@ -611,7 +630,7 @@ nsCSPHostSrc::permits(nsIURI* aUri, const nsAString& aNonce, bool aWasRedirected
// http://www.w3.org/TR/CSP11/#match-source-expression
// 4.3) scheme matching: Check if the scheme matches.
- if (!permitsScheme(mScheme, aUri, aReportOnly, aUpgradeInsecure)) {
+ if (!permitsScheme(mScheme, aUri, aReportOnly, aUpgradeInsecure, mGeneratedFromSelfKeyword)) {
return false;
}
@@ -642,7 +661,7 @@ nsCSPHostSrc::permits(nsIURI* aUri, const nsAString& aNonce, bool aWasRedirected
// Before we can check if the host matches, we have to
// extract the host part from aUri.
nsAutoCString uriHost;
- nsresult rv = aUri->GetHost(uriHost);
+ nsresult rv = aUri->GetAsciiHost(uriHost);
NS_ENSURE_SUCCESS(rv, false);
nsString decodedUriHost;
@@ -686,6 +705,11 @@ nsCSPHostSrc::permits(nsIURI* aUri, const nsAString& aNonce, bool aWasRedirected
rv = url->GetFilePath(uriPath);
NS_ENSURE_SUCCESS(rv, false);
+ if (mWithinFrameAncstorsDir) {
+ // no path matching for frame-ancestors to not leak any path information.
+ return true;
+ }
+
nsString decodedUriPath;
CSP_PercentDecodeStr(NS_ConvertUTF8toUTF16(uriPath), decodedUriPath);
diff --git a/dom/security/nsCSPUtils.h b/dom/security/nsCSPUtils.h
index b33c8932a..cfbe83256 100644
--- a/dom/security/nsCSPUtils.h
+++ b/dom/security/nsCSPUtils.h
@@ -186,7 +186,7 @@ nsresult CSP_AppendCSPFromHeader(nsIContentSecurityPolicy* aCsp,
class nsCSPHostSrc;
-nsCSPHostSrc* CSP_CreateHostSrcFromURI(nsIURI* aURI);
+nsCSPHostSrc* CSP_CreateHostSrcFromSelfURI(nsIURI* aSelfURI);
bool CSP_IsValidDirective(const nsAString& aDir);
bool CSP_IsDirective(const nsAString& aValue, CSPDirective aDir);
bool CSP_IsKeyword(const nsAString& aValue, enum CSPKeyword aKey);
@@ -256,6 +256,12 @@ class nsCSPHostSrc : public nsCSPBaseSrc {
void setPort(const nsAString& aPort);
void appendPath(const nsAString &aPath);
+ inline void setGeneratedFromSelfKeyword() const
+ { mGeneratedFromSelfKeyword = true;}
+
+ inline void setWithinFrameAncestorsDir(bool aValue) const
+ { mWithinFrameAncstorsDir = aValue; }
+
inline void getScheme(nsAString& outStr) const
{ outStr.Assign(mScheme); };
@@ -273,6 +279,8 @@ class nsCSPHostSrc : public nsCSPBaseSrc {
nsString mHost;
nsString mPort;
nsString mPath;
+ mutable bool mGeneratedFromSelfKeyword;
+ mutable bool mWithinFrameAncstorsDir;
};
/* =============== nsCSPKeywordSrc ============ */
diff --git a/dom/security/nsMixedContentBlocker.cpp b/dom/security/nsMixedContentBlocker.cpp
index a9aca5333..4e80dce3f 100644
--- a/dom/security/nsMixedContentBlocker.cpp
+++ b/dom/security/nsMixedContentBlocker.cpp
@@ -337,7 +337,11 @@ nsMixedContentBlocker::AsyncOnChannelRedirect(nsIChannel* aOldChannel,
nullptr, // aExtra
requestingPrincipal,
&decision);
- NS_ENSURE_SUCCESS(rv, rv);
+ if (NS_FAILED(rv)) {
+ autoCallback.DontCallback();
+ aOldChannel->Cancel(NS_ERROR_DOM_BAD_URI);
+ return NS_BINDING_FAILED;
+ }
if (nsMixedContentBlocker::sSendHSTSPriming) {
// The LoadInfo passed in is for the original channel, HSTS priming needs to
@@ -358,6 +362,7 @@ nsMixedContentBlocker::AsyncOnChannelRedirect(nsIChannel* aOldChannel,
// If the channel is about to load mixed content, abort the channel
if (!NS_CP_ACCEPTED(decision)) {
autoCallback.DontCallback();
+ aOldChannel->Cancel(NS_ERROR_DOM_BAD_URI);
return NS_BINDING_FAILED;
}
diff --git a/dom/security/test/csp/file_ignore_xfo.html b/dom/security/test/csp/file_ignore_xfo.html
new file mode 100644
index 000000000..6746a3adb
--- /dev/null
+++ b/dom/security/test/csp/file_ignore_xfo.html
@@ -0,0 +1,10 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>Bug 1024557: Ignore x-frame-options if CSP with frame-ancestors exists</title>
+</head>
+<body>
+<div id="cspmessage">Ignoring XFO because of CSP</div>
+</body>
+</html>
diff --git a/dom/security/test/csp/file_ignore_xfo.html^headers^ b/dom/security/test/csp/file_ignore_xfo.html^headers^
new file mode 100644
index 000000000..e93f9e3ec
--- /dev/null
+++ b/dom/security/test/csp/file_ignore_xfo.html^headers^
@@ -0,0 +1,3 @@
+Content-Security-Policy: frame-ancestors http://mochi.test:8888
+X-Frame-Options: deny
+Cache-Control: no-cache
diff --git a/dom/security/test/csp/file_image_nonce.html b/dom/security/test/csp/file_image_nonce.html
new file mode 100644
index 000000000..5d57bb837
--- /dev/null
+++ b/dom/security/test/csp/file_image_nonce.html
@@ -0,0 +1,39 @@
+<!DOCTYPE HTML>
+<html>
+ <head>
+ <meta charset='utf-8'>
+ <title>Bug 1355801: Nonce should not apply to images</title>
+ </head>
+<body>
+
+<img id='matchingNonce' src='http://mochi.test:8888/tests/image/test/mochitest/blue.png?a' nonce='abc'></img>
+<img id='nonMatchingNonce' src='http://mochi.test:8888/tests/image/test/mochitest/blue.png?b' nonce='bca'></img>
+<img id='noNonce' src='http://mochi.test:8888/tests/image/test/mochitest/blue.png?c'></img>
+
+<script type='application/javascript'>
+ var matchingNonce = document.getElementById('matchingNonce');
+ matchingNonce.onload = function(e) {
+ window.parent.postMessage({result: 'img-with-matching-nonce-loaded'}, '*');
+ };
+ matchingNonce.onerror = function(e) {
+ window.parent.postMessage({result: 'img-with-matching-nonce-blocked'}, '*');
+ }
+
+ var nonMatchingNonce = document.getElementById('nonMatchingNonce');
+ nonMatchingNonce.onload = function(e) {
+ window.parent.postMessage({result: 'img-with_non-matching-nonce-loaded'}, '*');
+ };
+ nonMatchingNonce.onerror = function(e) {
+ window.parent.postMessage({result: 'img-with_non-matching-nonce-blocked'}, '*');
+ }
+
+ var noNonce = document.getElementById('noNonce');
+ noNonce.onload = function(e) {
+ window.parent.postMessage({result: 'img-without-nonce-loaded'}, '*');
+ };
+ noNonce.onerror = function(e) {
+ window.parent.postMessage({result: 'img-without-nonce-blocked'}, '*');
+ }
+</script>
+</body>
+</html>
diff --git a/dom/security/test/csp/file_image_nonce.html^headers^ b/dom/security/test/csp/file_image_nonce.html^headers^
new file mode 100644
index 000000000..0d63558c4
--- /dev/null
+++ b/dom/security/test/csp/file_image_nonce.html^headers^
@@ -0,0 +1,2 @@
+Content-Security-Policy: img-src 'nonce-abc';
+Cache-Control: no-cache
diff --git a/dom/security/test/csp/file_punycode_host_src.js b/dom/security/test/csp/file_punycode_host_src.js
new file mode 100644
index 000000000..3505faf70
--- /dev/null
+++ b/dom/security/test/csp/file_punycode_host_src.js
@@ -0,0 +1,2 @@
+const LOADED = true;
+parent.postMessage({result: 'script-allowed'}, "*"); \ No newline at end of file
diff --git a/dom/security/test/csp/file_punycode_host_src.sjs b/dom/security/test/csp/file_punycode_host_src.sjs
new file mode 100644
index 000000000..3189cc063
--- /dev/null
+++ b/dom/security/test/csp/file_punycode_host_src.sjs
@@ -0,0 +1,45 @@
+// custom *.sjs for Bug 1224225
+// Punycode in CSP host sources
+
+const HTML_PART1 =
+ "<!DOCTYPE HTML>" +
+ "<html><head><meta charset=\"utf-8\">" +
+ "<title>Bug 1224225 - CSP source matching should work for punycoded domain names</title>" +
+ "</head>" +
+ "<body>" +
+ "<script id='script' src='";
+
+const TESTCASE1 = "http://sub2.ält.example.org/";
+const TESTCASE2 = "http://sub2.xn--lt-uia.example.org/"
+
+const HTML_PART2 = "tests/dom/security/test/csp/file_punycode_host_src.js'></script>" +
+ "</body>" +
+ "</html>";
+
+function handleRequest(request, response)
+{
+ // avoid confusing cache behaviors
+ response.setHeader("Cache-Control", "no-cache", false);
+ response.setHeader("Content-Type", "text/html", false);
+
+ Components.utils.importGlobalProperties(["URLSearchParams"]);
+ const query = new URLSearchParams(request.queryString);
+
+
+ if (query.get("csp")) {
+ response.setHeader("Content-Security-Policy", query.get("csp"), false);
+ }
+ if (query.get("action") == "script-unicode-csp-punycode") {
+ response.write(HTML_PART1 + TESTCASE1 + HTML_PART2);
+ return
+ }
+ if (query.get("action") == "script-punycode-csp-punycode") {
+ response.write(HTML_PART1 + TESTCASE2 + HTML_PART2);
+ return
+ }
+
+
+ // we should never get here, but just in case
+ // return something unexpected
+ response.write("do'h");
+}
diff --git a/dom/security/test/csp/file_ro_ignore_xfo.html b/dom/security/test/csp/file_ro_ignore_xfo.html
new file mode 100644
index 000000000..85e7f0092
--- /dev/null
+++ b/dom/security/test/csp/file_ro_ignore_xfo.html
@@ -0,0 +1,10 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>Bug 1024557: Ignore x-frame-options if CSP with frame-ancestors exists</title>
+</head>
+<body>
+<div id="cspmessage">Ignoring XFO because of CSP_RO</div>
+</body>
+</html> \ No newline at end of file
diff --git a/dom/security/test/csp/file_ro_ignore_xfo.html^headers^ b/dom/security/test/csp/file_ro_ignore_xfo.html^headers^
new file mode 100644
index 000000000..ab8366f06
--- /dev/null
+++ b/dom/security/test/csp/file_ro_ignore_xfo.html^headers^
@@ -0,0 +1,3 @@
+Content-Security-Policy-Report-Only: frame-ancestors http://mochi.test:8888
+X-Frame-Options: deny
+Cache-Control: no-cache
diff --git a/dom/security/test/csp/file_upgrade_insecure_navigation.sjs b/dom/security/test/csp/file_upgrade_insecure_navigation.sjs
new file mode 100644
index 000000000..51afa39bf
--- /dev/null
+++ b/dom/security/test/csp/file_upgrade_insecure_navigation.sjs
@@ -0,0 +1,79 @@
+// Custom *.sjs file specifically for the needs of
+// https://bugzilla.mozilla.org/show_bug.cgi?id=1271173
+
+"use strict";
+Components.utils.importGlobalProperties(["URLSearchParams"]);
+
+const TEST_NAVIGATIONAL_UPGRADE = `
+ <!DOCTYPE html>
+ <html>
+ <head><meta charset="utf-8"></head>
+ <body>
+ <a href="http://example.com/tests/dom/security/test/csp/file_upgrade_insecure_navigation.sjs?action=framenav" id="testlink">clickme</a>
+ <script type="text/javascript">
+ // before navigating the current frame we open the window and check that uir applies
+ var myWin = window.open("http://example.com/tests/dom/security/test/csp/file_upgrade_insecure_navigation.sjs?action=docnav");
+
+ window.addEventListener("message", receiveMessage, false);
+ function receiveMessage(event) {
+ myWin.close();
+ var link = document.getElementById('testlink');
+ link.click();
+ }
+ </script>
+ </body>
+ </html>`;
+
+const FRAME_NAV = `
+ <!DOCTYPE html>
+ <html>
+ <head><meta charset="utf-8"></head>
+ <body>
+ <script type="text/javascript">
+ parent.postMessage({result: document.documentURI}, "*");
+ </script>
+ </body>
+ </html>`;
+
+const DOC_NAV = `
+ <!DOCTYPE html>
+ <html>
+ <head><meta charset="utf-8"></head>
+ <body>
+ <script type="text/javascript">
+ // call back to the main testpage signaling whether the upgraded succeeded
+ window.opener.parent.postMessage({result: document.documentURI}, "*");
+ // let the opener (iframe) now that we can now close the window and move on with the test.
+ window.opener.postMessage({result: "readyToMoveOn"}, "*");
+ </script>
+ </body>
+ </html>`;
+
+function handleRequest(request, response) {
+ const query = new URLSearchParams(request.queryString);
+
+ response.setHeader("Cache-Control", "no-cache", false);
+ response.setHeader("Content-Type", "text/html", false);
+ if (query.get("csp")) {
+ response.setHeader("Content-Security-Policy", query.get("csp"), false);
+ }
+
+ if (query.get("action") === "perform_navigation") {
+ response.write(TEST_NAVIGATIONAL_UPGRADE);
+ return;
+ }
+
+ if (query.get("action") === "framenav") {
+ response.write(FRAME_NAV);
+ return;
+ }
+
+ if (query.get("action") === "docnav") {
+ response.write(DOC_NAV);
+ return;
+ }
+
+ // we should never get here, but just in case
+ // return something unexpected
+ response.write("do'h");
+}
diff --git a/dom/security/test/csp/file_websocket_explicit.html b/dom/security/test/csp/file_websocket_explicit.html
new file mode 100644
index 000000000..51462ab74
--- /dev/null
+++ b/dom/security/test/csp/file_websocket_explicit.html
@@ -0,0 +1,31 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>Bug 1345615: Allow websocket schemes when using 'self' in CSP</title>
+ <meta http-equiv="Content-Security-Policy" content="connect-src ws:">
+</head>
+<body>
+ <script type="application/javascript">
+ /* load socket using ws */
+ var wsSocket = new WebSocket("ws://example.com/tests/dom/security/test/csp/file_websocket_self");
+ wsSocket.onopen = function(e) {
+ window.parent.postMessage({result: "explicit-ws-loaded"}, "*");
+ wsSocket.close();
+ };
+ wsSocket.onerror = function(e) {
+ window.parent.postMessage({result: "explicit-ws-blocked"}, "*");
+ };
+
+ /* load socket using wss */
+ var wssSocket = new WebSocket("wss://example.com/tests/dom/security/test/csp/file_websocket_self");
+ wssSocket.onopen = function(e) {
+ window.parent.postMessage({result: "explicit-wss-loaded"}, "*");
+ wssSocket.close();
+ };
+ wssSocket.onerror = function(e) {
+ window.parent.postMessage({result: "explicit-wss-blocked"}, "*");
+ };
+ </script>
+</body>
+</html>
diff --git a/dom/security/test/csp/file_websocket_self.html b/dom/security/test/csp/file_websocket_self.html
new file mode 100644
index 000000000..3ff5f0558
--- /dev/null
+++ b/dom/security/test/csp/file_websocket_self.html
@@ -0,0 +1,31 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>Bug 1345615: Allow websocket schemes when using 'self' in CSP</title>
+ <meta http-equiv="Content-Security-Policy" content="connect-src 'self'">
+</head>
+<body>
+ <script type="application/javascript">
+ /* load socket using ws */
+ var wsSocket = new WebSocket("ws://example.com/tests/dom/security/test/csp/file_websocket_self");
+ wsSocket.onopen = function(e) {
+ window.parent.postMessage({result: "self-ws-loaded"}, "*");
+ wsSocket.close();
+ };
+ wsSocket.onerror = function(e) {
+ window.parent.postMessage({result: "self-ws-blocked"}, "*");
+ };
+
+ /* load socket using wss */
+ var wssSocket = new WebSocket("wss://example.com/tests/dom/security/test/csp/file_websocket_self");
+ wssSocket.onopen = function(e) {
+ window.parent.postMessage({result: "self-wss-loaded"}, "*");
+ wssSocket.close();
+ };
+ wssSocket.onerror = function(e) {
+ window.parent.postMessage({result: "self-wss-blocked"}, "*");
+ };
+ </script>
+</body>
+</html>
diff --git a/dom/security/test/csp/file_websocket_self_wsh.py b/dom/security/test/csp/file_websocket_self_wsh.py
new file mode 100644
index 000000000..5fe508a91
--- /dev/null
+++ b/dom/security/test/csp/file_websocket_self_wsh.py
@@ -0,0 +1,7 @@
+from mod_pywebsocket import msgutil
+
+def web_socket_do_extra_handshake(request):
+ pass
+
+def web_socket_transfer_data(request):
+ pass
diff --git a/dom/security/test/csp/mochitest.ini b/dom/security/test/csp/mochitest.ini
index 8add999c3..2102cbe70 100644
--- a/dom/security/test/csp/mochitest.ini
+++ b/dom/security/test/csp/mochitest.ini
@@ -206,6 +206,18 @@ support-files =
file_iframe_srcdoc.sjs
file_iframe_sandbox_srcdoc.html
file_iframe_sandbox_srcdoc.html^headers^
+ file_ignore_xfo.html
+ file_ignore_xfo.html^headers^
+ file_ro_ignore_xfo.html
+ file_ro_ignore_xfo.html^headers^
+ file_upgrade_insecure_navigation.sjs
+ file_image_nonce.html
+ file_image_nonce.html^headers^
+ file_punycode_host_src.sjs
+ file_punycode_host_src.js
+ file_websocket_self.html
+ file_websocket_explicit.html
+ file_websocket_self_wsh.py
[test_base-uri.html]
[test_blob_data_schemes.html]
@@ -292,9 +304,15 @@ tags = mcb
[test_strict_dynamic.html]
[test_strict_dynamic_parser_inserted.html]
[test_strict_dynamic_default_src.html]
+[test_upgrade_insecure_navigation.html]
[test_iframe_sandbox_srcdoc.html]
[test_iframe_srcdoc.html]
[test_sandbox_allow_scripts.html]
support-files =
file_sandbox_allow_scripts.html
file_sandbox_allow_scripts.html^headers^
+[test_ignore_xfo.html]
+[test_image_nonce.html]
+[test_punycode_host_src.html]
+[test_websocket_self.html]
+skip-if = toolkit == 'android'
diff --git a/dom/security/test/csp/test_ignore_xfo.html b/dom/security/test/csp/test_ignore_xfo.html
new file mode 100644
index 000000000..fb3aadc6c
--- /dev/null
+++ b/dom/security/test/csp/test_ignore_xfo.html
@@ -0,0 +1,59 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>Bug 1024557: Ignore x-frame-options if CSP with frame-ancestors exists</title>
+ <!-- Including SimpleTest.js so we can use waitForExplicitFinish !-->
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<iframe style="width:100%;" id="csp_testframe"></iframe>
+<iframe style="width:100%;" id="csp_ro_testframe"></iframe>
+
+<script class="testbody" type="text/javascript">
+
+/*
+ * We load two frames using:
+ * x-frame-options: deny
+ * where the first frame uses a csp and the second a csp_ro including frame-ancestors.
+ * We make sure that xfo is ignored for regular csp but not for csp_ro.
+ */
+
+SimpleTest.waitForExplicitFinish();
+
+var testcounter = 0;
+function checkFinished() {
+ testcounter++;
+ if (testcounter < 2) {
+ return;
+ }
+ SimpleTest.finish();
+}
+
+// 1) test XFO with CSP
+var csp_testframe = document.getElementById("csp_testframe");
+csp_testframe.onload = function() {
+ var msg = csp_testframe.contentWindow.document.getElementById("cspmessage");
+ is(msg.innerHTML, "Ignoring XFO because of CSP", "Loading frame with with XFO and CSP");
+ checkFinished();
+}
+csp_testframe.onerror = function() {
+ ok(false, "sanity: should not fire onerror for csp_testframe");
+}
+csp_testframe.src = "file_ignore_xfo.html";
+
+// 2) test XFO with CSP_RO
+var csp_ro_testframe = document.getElementById("csp_ro_testframe");
+csp_ro_testframe.onload = function() {
+ var msg = csp_ro_testframe.contentWindow.document.getElementById("cspmessage");
+ is(msg, null, "Blocking frame with with XFO and CSP_RO");
+ checkFinished();
+}
+csp_ro_testframe.onerror = function() {
+ ok(false, "sanity: should not fire onerror for csp_ro_testframe");
+}
+csp_ro_testframe.src = "file_ro_ignore_xfo.html";
+
+</script>
+</body>
+</html>
diff --git a/dom/security/test/csp/test_image_nonce.html b/dom/security/test/csp/test_image_nonce.html
new file mode 100644
index 000000000..ff6d636b6
--- /dev/null
+++ b/dom/security/test/csp/test_image_nonce.html
@@ -0,0 +1,60 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>Bug 1139297 - Implement CSP upgrade-insecure-requests directive</title>
+ <!-- Including SimpleTest.js so we can use waitForExplicitFinish !-->
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<iframe style="width:100%;" id="testframe"></iframe>
+
+<script class="testbody" type="text/javascript">
+
+/* Description of the test:
+ * We load three images: (a) with a matching nonce,
+ (b) with a non matching nonce,
+ * (c) with no nonce
+ * and make sure that all three images get blocked because
+ * "img-src nonce-bla" should not allow an image load, not
+ * even if the nonce matches*.
+ */
+
+SimpleTest.waitForExplicitFinish();
+
+var counter = 0;
+
+function finishTest() {
+ window.removeEventListener("message", receiveMessage);
+ SimpleTest.finish();
+}
+
+function checkResults(aResult) {
+ counter++;
+ if (aResult === "img-with-matching-nonce-blocked" ||
+ aResult === "img-with_non-matching-nonce-blocked" ||
+ aResult === "img-without-nonce-blocked") {
+ ok (true, "correct result for: " + aResult);
+ }
+ else {
+ ok(false, "unexpected result: " + aResult + "\n\n");
+ }
+ if (counter < 3) {
+ return;
+ }
+ finishTest();
+}
+
+// a postMessage handler that is used by sandboxed iframes without
+// 'allow-same-origin' to bubble up results back to this main page.
+window.addEventListener("message", receiveMessage);
+function receiveMessage(event) {
+ checkResults(event.data.result);
+}
+
+document.getElementById("testframe").src = "file_image_nonce.html";
+
+</script>
+</body>
+</html>
diff --git a/dom/security/test/csp/test_punycode_host_src.html b/dom/security/test/csp/test_punycode_host_src.html
new file mode 100644
index 000000000..8d891725c
--- /dev/null
+++ b/dom/security/test/csp/test_punycode_host_src.html
@@ -0,0 +1,81 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>Bug 1224225 - CSP source matching should work for punycoded domain names</title>
+ <!-- Including SimpleTest.js so we can use waitForExplicitFinish !-->
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<iframe style="width:100%;" id="testframe"></iframe>
+
+<script class="testbody" type="text/javascript">
+
+/* Description of the test:
+ * We load scripts within an iframe and make sure that the
+ * CSP matching is same for punycode domain names as well as IDNA.
+ */
+
+SimpleTest.waitForExplicitFinish();
+
+
+var curTest;
+var counter = -1;
+
+const tests = [
+ { // test 1
+ description: "loads script as sub2.ält.example.org, but whitelist in CSP as sub2.xn--lt-uia.example.org",
+ action: "script-unicode-csp-punycode",
+ csp: "script-src http://sub2.xn--lt-uia.example.org;",
+ expected: "script-allowed",
+
+ },
+ { // test 2
+ description: "loads script as sub2.xn--lt-uia.example.org, and whitelist in CSP as sub2.xn--lt-uia.example.org",
+ action: "script-punycode-csp-punycode",
+ csp: "script-src http://sub2.xn--lt-uia.example.org;",
+ expected: "script-allowed",
+
+ },
+ { // test 3
+ description: "loads script as sub2.xn--lt-uia.example.org, and whitelist in CSP as sub2.xn--lt-uia.example.org",
+ action: "script-punycode-csp-punycode",
+ csp: "script-src *.xn--lt-uia.example.org;",
+ expected: "script-allowed",
+
+ },
+
+];
+
+function finishTest() {
+ window.removeEventListener("message", receiveMessage);
+ SimpleTest.finish();
+}
+
+function checkResults(result) {
+ is(result, curTest.expected, curTest.description);
+ loadNextTest();
+}
+
+window.addEventListener("message", receiveMessage);
+function receiveMessage(event) {
+ checkResults(event.data.result);
+}
+
+function loadNextTest() {
+ counter++;
+ if (counter == tests.length) {
+ finishTest();
+ return;
+ }
+ curTest = tests[counter];
+ var testframe = document.getElementById("testframe");
+ testframe.src = `file_punycode_host_src.sjs?action=${curTest.action}&csp=${curTest.csp}`;
+}
+
+loadNextTest();
+
+</script>
+</body>
+</html>
diff --git a/dom/security/test/csp/test_upgrade_insecure_navigation.html b/dom/security/test/csp/test_upgrade_insecure_navigation.html
new file mode 100644
index 000000000..db6a6a1be
--- /dev/null
+++ b/dom/security/test/csp/test_upgrade_insecure_navigation.html
@@ -0,0 +1,103 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>Bug 1271173 - Missing spec on Upgrade Insecure Requests(Navigational Upgrades) </title>
+ <!-- Including SimpleTest.js so we can use waitForExplicitFinish !-->
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<iframe style="width:100%;" id="testframe"></iframe>
+<iframe style="width:100%;" id="sandboxedtestframe"
+ sandbox="allow-scripts allow-top-navigation allow-same-origin allow-pointer-lock allow-popups"></iframe>
+
+<script class="testbody" type="text/javascript">
+/*
+ * Description of the test:
+ * We load a page into an iframe that performs a navigational request.
+ * We make sure that upgrade-insecure-requests applies and the page
+ * gets upgraded to https if same origin.
+ * Please note that uir only applies to sandboxed iframes if
+ * the value 'allow-same-origin' is specified.
+ */
+
+SimpleTest.waitForExplicitFinish();
+
+var tests = [
+ {
+ csp: "upgrade-insecure-requests;",
+ result: "https",
+ origin: "http://example.com",
+ desc: "upgrade-insecure-requests same origin should upgrade"
+ },
+ {
+ csp: "",
+ result: "http",
+ origin: "http://example.com",
+ desc: "No upgrade-insecure-requests same origin should not upgrade"
+ },
+ {
+ csp: "upgrade-insecure-requests;",
+ result: "http",
+ origin: "http://mochi.test:8888",
+ desc: "upgrade-insecure-requests cross origin should not upgrade"
+ },
+ {
+ csp: "",
+ result: "http",
+ origin: "http://mochi.test:8888",
+ desc: "No upgrade-insecure-requests cross origin should not upgrade"
+ },
+];
+
+// initializing to -1 so we start at index 0 when we start the test
+var counter = -1;
+
+function finishTest() {
+ window.removeEventListener("message", receiveMessage, false);
+ SimpleTest.finish();
+}
+
+var subtests = 0;
+
+window.addEventListener("message", receiveMessage, false);
+function receiveMessage(event) {
+ var result = event.data.result;
+ // query the scheme from the URL before comparing the result
+ var scheme = result.substring(0, result.indexOf(":"));
+ is(scheme, tests[counter].result, tests[counter].desc);
+
+ // @hardcoded 4:
+ // each test run contains of two subtests (frame and top-level)
+ // and we load each test into a regular iframe and into a
+ // sandboxed iframe. only move on to the next test once all
+ // four results from the subtests have bubbled up.
+ subtests++;
+ if (subtests != 4) {
+ return;
+ }
+ subtests = 0;
+ loadNextTest();
+}
+
+function loadNextTest() {
+ counter++;
+ if (counter == tests.length) {
+ finishTest();
+ return;
+ }
+
+ var src = tests[counter].origin;
+ src += "/tests/dom/security/test/csp/file_upgrade_insecure_navigation.sjs";
+ src += "?csp=" + escape(tests[counter].csp);
+ src += "&action=perform_navigation";
+ document.getElementById("testframe").src = src;
+ document.getElementById("sandboxedtestframe").src = src;
+}
+
+// start running the tests
+loadNextTest();
+
+</script>
+</body>
+</html>
diff --git a/dom/security/test/csp/test_websocket_self.html b/dom/security/test/csp/test_websocket_self.html
new file mode 100644
index 000000000..a03c32704
--- /dev/null
+++ b/dom/security/test/csp/test_websocket_self.html
@@ -0,0 +1,61 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>Bug 1345615: Allow websocket schemes when using 'self' in CSP</title>
+ <!-- Including SimpleTest.js so we can use waitForExplicitFinish !-->
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<iframe style="width:100%;" id="test_ws_self_frame"></iframe>
+<iframe style="width:100%;" id="test_ws_explicit_frame"></iframe>
+
+<script class="testbody" type="text/javascript">
+
+/* Description of the test:
+ * We load an iframe using connect-src 'self' and one
+ * iframe using connect-src ws: and make
+ * sure that in both cases ws: as well as wss: is allowed to load.
+ */
+
+SimpleTest.waitForExplicitFinish();
+
+function finishTest() {
+ window.removeEventListener("message", receiveMessage);
+ SimpleTest.finish();
+}
+
+const TOTAL_TESTS = 4;
+var counter = 0;
+
+function checkResults(result) {
+ counter++;
+ if (result === "self-ws-loaded" || result === "self-wss-loaded" ||
+ result === "explicit-ws-loaded" || result === "explicit-wss-loaded") {
+ ok(true, "Evaluating: " + result);
+ }
+ else {
+ ok(false, "Evaluating: " + result);
+ }
+ if (counter < TOTAL_TESTS) {
+ return;
+ }
+ finishTest();
+}
+
+window.addEventListener("message", receiveMessage);
+function receiveMessage(event) {
+ checkResults(event.data.result);
+}
+
+const HOST = "http://example.com/tests/dom/security/test/csp/";
+var test_ws_self_frame = document.getElementById("test_ws_self_frame");
+test_ws_self_frame.src = HOST + "file_websocket_self.html";
+
+var test_ws_explicit_frame = document.getElementById("test_ws_explicit_frame");
+test_ws_explicit_frame.src = HOST + "file_websocket_explicit.html";
+
+</script>
+</body>
+</html>
diff --git a/dom/security/test/gtest/TestCSPParser.cpp b/dom/security/test/gtest/TestCSPParser.cpp
index fafa7b5d9..8d168d81c 100644
--- a/dom/security/test/gtest/TestCSPParser.cpp
+++ b/dom/security/test/gtest/TestCSPParser.cpp
@@ -204,6 +204,8 @@ TEST(CSPParser, Directives)
{
static const PolicyTest policies[] =
{
+ { "connect-src xn--mnchen-3ya.de",
+ "connect-src http://xn--mnchen-3ya.de"},
{ "default-src http://www.example.com",
"default-src http://www.example.com" },
{ "script-src http://www.example.com",
diff --git a/dom/tests/mochitest/general/test_domWindowUtils_scrollXY.html b/dom/tests/mochitest/general/test_domWindowUtils_scrollXY.html
index c6ee89ee3..cf27e5d87 100644
--- a/dom/tests/mochitest/general/test_domWindowUtils_scrollXY.html
+++ b/dom/tests/mochitest/general/test_domWindowUtils_scrollXY.html
@@ -31,13 +31,13 @@
function checkGetScrollXYState(flush, vals, testName) {
let scrollX = {}, scrollY = {};
domWindowUtils.getScrollXY(flush, scrollX, scrollY);
- is(scrollX.value, vals[0], "getScrollXY x for test: " + testName);
- is(scrollY.value, vals[1], "getScrollXY y for test: " + testName);
+ is(Math.round(scrollX.value), vals[0], "getScrollXY x for test: " + testName);
+ is(Math.round(scrollY.value), vals[1], "getScrollXY y for test: " + testName);
}
function checkWindowScrollState(vals, testName) {
- is(cwindow.scrollX, vals[0], "scrollX for test: " + testName);
- is(cwindow.scrollY, vals[1], "scrollY for test: " + testName);
+ is(Math.round(cwindow.scrollX), vals[0], "scrollX for test: " + testName);
+ is(Math.round(cwindow.scrollY), vals[1], "scrollY for test: " + testName);
}
// Check initial state (0, 0)
@@ -67,8 +67,8 @@
let scrollX = {}, scrollY = {};
domWindowUtils.getScrollXY(false, scrollX, scrollY);
- is(scrollX.value, 0, "scrollX is zero for display:none iframe");
- is(scrollY.value, 0, "scrollY is zero for display:none iframe");
+ is(Math.round(scrollX.value), 0, "scrollX is zero for display:none iframe");
+ is(Math.round(scrollY.value), 0, "scrollY is zero for display:none iframe");
}
SimpleTest.waitForExplicitFinish();
diff --git a/dom/url/URL.h b/dom/url/URL.h
index 16b4678ba..45e4dd289 100644
--- a/dom/url/URL.h
+++ b/dom/url/URL.h
@@ -155,6 +155,12 @@ public:
GetHref(aRetval, aRv);
}
+ void
+ ToJSON(nsAString& aResult, ErrorResult& aRv) const
+ {
+ GetHref(aResult, aRv);
+ }
+
// URLSearchParamsObserver
void
URLSearchParamsUpdated(URLSearchParams* aSearchParams) override;
diff --git a/dom/url/tests/test_url.html b/dom/url/tests/test_url.html
index 3f3f727d6..d07a752bb 100644
--- a/dom/url/tests/test_url.html
+++ b/dom/url/tests/test_url.html
@@ -438,5 +438,11 @@
url = new URL("data:text/html,<a href=\"http://example.org/?q\">Link</a>");
is(url.href, "data:text/html,<a%20href=\"http://example.org/?q\">Link</a>");
</script>
+
+ <script>
+ var u = new URL('http://www.example.org');
+ ok(u.toJSON(), 'http://www.example.org', "URL.toJSON()");
+ is(JSON.stringify(u), "\"http://www.example.org/\"", "JSON.stringify(u) works");
+ </script>
</body>
</html>
diff --git a/dom/webidl/URL.webidl b/dom/webidl/URL.webidl
index 0baa9913c..4d491e1b3 100644
--- a/dom/webidl/URL.webidl
+++ b/dom/webidl/URL.webidl
@@ -44,9 +44,12 @@ interface URL {
attribute USVString pathname;
[Throws]
attribute USVString search;
- readonly attribute URLSearchParams searchParams;
+ [SameObject] readonly attribute URLSearchParams searchParams;
[Throws]
attribute USVString hash;
+
+ [Throws]
+ USVString toJSON();
};
partial interface URL {
diff --git a/dom/webidl/Window.webidl b/dom/webidl/Window.webidl
index 055a274cc..36b1f0313 100644
--- a/dom/webidl/Window.webidl
+++ b/dom/webidl/Window.webidl
@@ -182,14 +182,10 @@ partial interface Window {
[ChromeOnly] void mozScrollSnap();
// The four properties below are double per spec at the moment, but whether
// that will continue is unclear.
- //[Replaceable, Throws] readonly attribute double scrollX;
- //[Replaceable, Throws] readonly attribute double pageXOffset;
- //[Replaceable, Throws] readonly attribute double scrollY;
- //[Replaceable, Throws] readonly attribute double pageYOffset;
- [Replaceable, Throws] readonly attribute long scrollX;
- [Replaceable, Throws] readonly attribute long pageXOffset;
- [Replaceable, Throws] readonly attribute long scrollY;
- [Replaceable, Throws] readonly attribute long pageYOffset;
+ [Replaceable, Throws] readonly attribute double scrollX;
+ [Throws] readonly attribute double pageXOffset;
+ [Replaceable, Throws] readonly attribute double scrollY;
+ [Throws] readonly attribute double pageYOffset;
// client
// These are writable because we allow chrome to write them. And they need
diff --git a/dom/webidl/moz.build b/dom/webidl/moz.build
index efa90230d..f24c366e8 100644
--- a/dom/webidl/moz.build
+++ b/dom/webidl/moz.build
@@ -18,7 +18,6 @@ PREPROCESSED_WEBIDL_FILES = [
WEBIDL_FILES = [
'AbstractWorker.webidl',
- 'AddonManager.webidl',
'AnalyserNode.webidl',
'Animatable.webidl',
'Animation.webidl',
@@ -592,6 +591,9 @@ WEBIDL_FILES = [
'XULElement.webidl',
]
+if CONFIG['MOZ_WEBEXTENSIONS']:
+ WEBIDL_FILES += ['AddonManager.webidl']
+
if CONFIG['MOZ_AUDIO_CHANNEL_MANAGER']:
WEBIDL_FILES += [
'AudioChannelManager.webidl',
@@ -692,7 +694,6 @@ else:
]
GENERATED_EVENTS_WEBIDL_FILES = [
- 'AddonEvent.webidl',
'AnimationPlaybackEvent.webidl',
'AutocompleteErrorEvent.webidl',
'BlobEvent.webidl',
@@ -734,6 +735,9 @@ GENERATED_EVENTS_WEBIDL_FILES = [
'WebGLContextEvent.webidl',
]
+if CONFIG['MOZ_WEBEXTENSIONS']:
+ GENERATED_EVENTS_WEBIDL_FILES += ['AddonEvent.webidl']
+
if CONFIG['MOZ_WEBRTC']:
GENERATED_EVENTS_WEBIDL_FILES += [
'RTCDataChannelEvent.webidl',
@@ -764,12 +768,12 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk':
'MozWifiStatusChangeEvent.webidl',
]
-if CONFIG['MOZ_BUILD_APP'] in ['browser', 'xulrunner'] or CONFIG['MOZ_SUITE']:
+if CONFIG['MOZ_BUILD_APP'] in ['xulrunner'] or CONFIG['MOZ_PHOENIX'] or CONFIG['MOZ_SUITE']:
WEBIDL_FILES += [
'BrowserFeedWriter.webidl',
]
-if CONFIG['MOZ_BUILD_APP'] in ['browser', 'mobile/android', 'xulrunner']:
+if CONFIG['MOZ_BUILD_APP'] in ['mobile/android', 'xulrunner'] or CONFIG['MOZ_PHOENIX']:
WEBIDL_FILES += [
'External.webidl',
]