mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-17 23:35:34 +00:00
Merge mozilla-central to autoland. a=merge CLOSED TREE
This commit is contained in:
commit
eae80bd903
@ -182,8 +182,8 @@
|
||||
<key id="key_delete" keycode="VK_DELETE" command="cmd_delete"/>
|
||||
<key id="key_selectAll" key="&selectAllCmd.key;" modifiers="accel"/>
|
||||
|
||||
<key keycode="VK_BACK" command="cmd_handleBackspace"/>
|
||||
<key keycode="VK_BACK" command="cmd_handleShiftBackspace" modifiers="shift"/>
|
||||
<key keycode="VK_BACK" command="cmd_handleBackspace" reserved="false"/>
|
||||
<key keycode="VK_BACK" command="cmd_handleShiftBackspace" modifiers="shift" reserved="false"/>
|
||||
#ifndef XP_MACOSX
|
||||
<key id="goBackKb" keycode="VK_LEFT" command="Browser:Back" modifiers="alt"/>
|
||||
<key id="goForwardKb" keycode="VK_RIGHT" command="Browser:Forward" modifiers="alt"/>
|
||||
|
@ -117,3 +117,43 @@ if (!navigator.platform.includes("Mac")) {
|
||||
BrowserTestUtils.removeTab(tab1);
|
||||
});
|
||||
}
|
||||
|
||||
// There is a <key> element for Backspace with reserved="false", so make sure that it is not
|
||||
// treated as a blocked shortcut key.
|
||||
add_task(async function test_backspace() {
|
||||
await new Promise(resolve => {
|
||||
SpecialPowers.pushPrefEnv({"set": [["permissions.default.shortcuts", 2]]}, resolve);
|
||||
});
|
||||
|
||||
// The input field is autofocused. If this test fails, backspace can go back
|
||||
// in history so cancel the beforeunload event and adjust the field to make the test fail.
|
||||
const uri = "data:text/html,<body onbeforeunload='document.getElementById(\"field\").value = \"failed\";'>" +
|
||||
"<input id='field' value='something'></body>";
|
||||
let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, uri);
|
||||
|
||||
await ContentTask.spawn(tab.linkedBrowser, { }, async function() {
|
||||
content.document.getElementById("field").focus();
|
||||
|
||||
// Add a promise that resolves when the backspace key gets received
|
||||
// so we can ensure the key gets received before checking the result.
|
||||
content.keysPromise = new Promise(resolve => {
|
||||
content.addEventListener("keyup", event => {
|
||||
if (event.code == "Backspace") {
|
||||
resolve(content.document.getElementById("field").value);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// Move the caret so backspace will delete the first character.
|
||||
EventUtils.synthesizeKey("KEY_ArrowRight", {});
|
||||
EventUtils.synthesizeKey("KEY_Backspace", {});
|
||||
|
||||
let fieldValue = await ContentTask.spawn(tab.linkedBrowser, { }, async function() {
|
||||
return content.keysPromise;
|
||||
});
|
||||
is(fieldValue, "omething", "backspace not prevented");
|
||||
|
||||
BrowserTestUtils.removeTab(tab);
|
||||
});
|
||||
|
||||
|
@ -339,7 +339,7 @@ function openLinkIn(url, where, params) {
|
||||
userContextId: aUserContextId,
|
||||
privateBrowsingId: aIsPrivate || (w && PrivateBrowsingUtils.isWindowPrivate(w)),
|
||||
};
|
||||
return Services.scriptSecurityManager.createCodebasePrincipal(principal.URI, attrs);
|
||||
return Services.scriptSecurityManager.principalWithOA(principal, attrs);
|
||||
}
|
||||
return principal;
|
||||
}
|
||||
|
@ -1,15 +1,15 @@
|
||||
{
|
||||
"llvm_revision": "349247",
|
||||
"llvm_revision": "342383",
|
||||
"stages": "2",
|
||||
"build_libcxx": true,
|
||||
"build_type": "Release",
|
||||
"assertions": false,
|
||||
"llvm_repo": "https://llvm.org/svn/llvm-project/llvm/tags/RELEASE_701/final",
|
||||
"clang_repo": "https://llvm.org/svn/llvm-project/cfe/tags/RELEASE_701/final",
|
||||
"lld_repo": "https://llvm.org/svn/llvm-project/lld/tags/RELEASE_701/final",
|
||||
"compiler_repo": "https://llvm.org/svn/llvm-project/compiler-rt/tags/RELEASE_701/final",
|
||||
"libcxx_repo": "https://llvm.org/svn/llvm-project/libcxx/tags/RELEASE_701/final",
|
||||
"libcxxabi_repo": "https://llvm.org/svn/llvm-project/libcxxabi/tags/RELEASE_701/final",
|
||||
"llvm_repo": "https://llvm.org/svn/llvm-project/llvm/tags/RELEASE_700/final",
|
||||
"clang_repo": "https://llvm.org/svn/llvm-project/cfe/tags/RELEASE_700/final",
|
||||
"lld_repo": "https://llvm.org/svn/llvm-project/lld/tags/RELEASE_700/final",
|
||||
"compiler_repo": "https://llvm.org/svn/llvm-project/compiler-rt/tags/RELEASE_700/final",
|
||||
"libcxx_repo": "https://llvm.org/svn/llvm-project/libcxx/tags/RELEASE_700/final",
|
||||
"libcxxabi_repo": "https://llvm.org/svn/llvm-project/libcxxabi/tags/RELEASE_700/final",
|
||||
"python_path": "/usr/bin/python2.7",
|
||||
"gcc_dir": "/builds/worker/workspace/build/src/gcc",
|
||||
"cc": "/builds/worker/workspace/build/src/gcc/bin/gcc",
|
||||
|
@ -1,15 +1,15 @@
|
||||
{
|
||||
"llvm_revision": "349247",
|
||||
"llvm_revision": "342383",
|
||||
"stages": "3",
|
||||
"build_libcxx": true,
|
||||
"build_type": "Release",
|
||||
"assertions": false,
|
||||
"llvm_repo": "https://llvm.org/svn/llvm-project/llvm/tags/RELEASE_701/final",
|
||||
"clang_repo": "https://llvm.org/svn/llvm-project/cfe/tags/RELEASE_701/final",
|
||||
"lld_repo": "https://llvm.org/svn/llvm-project/lld/tags/RELEASE_701/final",
|
||||
"compiler_repo": "https://llvm.org/svn/llvm-project/compiler-rt/tags/RELEASE_701/final",
|
||||
"libcxx_repo": "https://llvm.org/svn/llvm-project/libcxx/tags/RELEASE_701/final",
|
||||
"libcxxabi_repo": "https://llvm.org/svn/llvm-project/libcxxabi/tags/RELEASE_701/final",
|
||||
"llvm_repo": "https://llvm.org/svn/llvm-project/llvm/tags/RELEASE_700/final",
|
||||
"clang_repo": "https://llvm.org/svn/llvm-project/cfe/tags/RELEASE_700/final",
|
||||
"lld_repo": "https://llvm.org/svn/llvm-project/lld/tags/RELEASE_700/final",
|
||||
"compiler_repo": "https://llvm.org/svn/llvm-project/compiler-rt/tags/RELEASE_700/final",
|
||||
"libcxx_repo": "https://llvm.org/svn/llvm-project/libcxx/tags/RELEASE_700/final",
|
||||
"libcxxabi_repo": "https://llvm.org/svn/llvm-project/libcxxabi/tags/RELEASE_700/final",
|
||||
"python_path": "/usr/bin/python2.7",
|
||||
"gcc_dir": "/builds/worker/workspace/build/src/gcc",
|
||||
"cc": "/builds/worker/workspace/build/src/gcc/bin/gcc",
|
||||
|
@ -1,16 +1,16 @@
|
||||
{
|
||||
"llvm_revision": "349247",
|
||||
"llvm_revision": "342383",
|
||||
"stages": "1",
|
||||
"build_libcxx": true,
|
||||
"build_type": "Release",
|
||||
"assertions": false,
|
||||
"osx_cross_compile": true,
|
||||
"llvm_repo": "https://llvm.org/svn/llvm-project/llvm/tags/RELEASE_701/final",
|
||||
"clang_repo": "https://llvm.org/svn/llvm-project/cfe/tags/RELEASE_701/final",
|
||||
"lld_repo": "https://llvm.org/svn/llvm-project/lld/tags/RELEASE_701/final",
|
||||
"compiler_repo": "https://llvm.org/svn/llvm-project/compiler-rt/tags/RELEASE_701/final",
|
||||
"libcxx_repo": "https://llvm.org/svn/llvm-project/libcxx/tags/RELEASE_701/final",
|
||||
"libcxxabi_repo": "https://llvm.org/svn/llvm-project/libcxxabi/tags/RELEASE_701/final",
|
||||
"llvm_repo": "https://llvm.org/svn/llvm-project/llvm/tags/RELEASE_700/final",
|
||||
"clang_repo": "https://llvm.org/svn/llvm-project/cfe/tags/RELEASE_700/final",
|
||||
"lld_repo": "https://llvm.org/svn/llvm-project/lld/tags/RELEASE_700/final",
|
||||
"compiler_repo": "https://llvm.org/svn/llvm-project/compiler-rt/tags/RELEASE_700/final",
|
||||
"libcxx_repo": "https://llvm.org/svn/llvm-project/libcxx/tags/RELEASE_700/final",
|
||||
"libcxxabi_repo": "https://llvm.org/svn/llvm-project/libcxxabi/tags/RELEASE_700/final",
|
||||
"python_path": "/usr/bin/python2.7",
|
||||
"gcc_dir": "/builds/worker/workspace/build/src/gcc",
|
||||
"cc": "/builds/worker/workspace/build/src/clang/bin/clang",
|
||||
|
@ -1,15 +1,15 @@
|
||||
{
|
||||
"llvm_revision": "349247",
|
||||
"llvm_revision": "342383",
|
||||
"stages": "1",
|
||||
"build_libcxx": true,
|
||||
"build_type": "Release",
|
||||
"assertions": false,
|
||||
"build_clang_tidy": true,
|
||||
"llvm_repo": "https://llvm.org/svn/llvm-project/llvm/tags/RELEASE_701/final/",
|
||||
"clang_repo": "https://llvm.org/svn/llvm-project/cfe/tags/RELEASE_701/final/",
|
||||
"extra_repo": "https://llvm.org/svn/llvm-project/clang-tools-extra/tags/RELEASE_701/final/",
|
||||
"libcxx_repo": "https://llvm.org/svn/llvm-project/libcxx/tags/RELEASE_701/final/",
|
||||
"libcxxabi_repo": "https://llvm.org/svn/llvm-project/libcxxabi/tags/RELEASE_701/final/",
|
||||
"llvm_repo": "https://llvm.org/svn/llvm-project/llvm/tags/RELEASE_700/final/",
|
||||
"clang_repo": "https://llvm.org/svn/llvm-project/cfe/tags/RELEASE_700/final/",
|
||||
"extra_repo": "https://llvm.org/svn/llvm-project/clang-tools-extra/tags/RELEASE_700/final/",
|
||||
"libcxx_repo": "https://llvm.org/svn/llvm-project/libcxx/tags/RELEASE_700/final/",
|
||||
"libcxxabi_repo": "https://llvm.org/svn/llvm-project/libcxxabi/tags/RELEASE_700/final/",
|
||||
"python_path": "/usr/bin/python2.7",
|
||||
"gcc_dir": "/builds/worker/workspace/build/src/gcc",
|
||||
"cc": "/builds/worker/workspace/build/src/gcc/bin/gcc",
|
||||
|
@ -1,16 +1,16 @@
|
||||
{
|
||||
"llvm_revision": "349247",
|
||||
"llvm_revision": "342383",
|
||||
"stages": "1",
|
||||
"build_libcxx": true,
|
||||
"build_type": "Release",
|
||||
"assertions": false,
|
||||
"build_clang_tidy": true,
|
||||
"osx_cross_compile": true,
|
||||
"llvm_repo": "https://llvm.org/svn/llvm-project/llvm/tags/RELEASE_701/final",
|
||||
"clang_repo": "https://llvm.org/svn/llvm-project/cfe/tags/RELEASE_701/final",
|
||||
"extra_repo": "https://llvm.org/svn/llvm-project/clang-tools-extra/tags/RELEASE_701/final",
|
||||
"libcxx_repo": "https://llvm.org/svn/llvm-project/libcxx/tags/RELEASE_701/final",
|
||||
"libcxxabi_repo": "https://llvm.org/svn/llvm-project/libcxxabi/tags/RELEASE_701/final",
|
||||
"llvm_repo": "https://llvm.org/svn/llvm-project/llvm/tags/RELEASE_700/final",
|
||||
"clang_repo": "https://llvm.org/svn/llvm-project/cfe/tags/RELEASE_700/final",
|
||||
"extra_repo": "https://llvm.org/svn/llvm-project/clang-tools-extra/tags/RELEASE_700/final",
|
||||
"libcxx_repo": "https://llvm.org/svn/llvm-project/libcxx/tags/RELEASE_700/final",
|
||||
"libcxxabi_repo": "https://llvm.org/svn/llvm-project/libcxxabi/tags/RELEASE_700/final",
|
||||
"python_path": "/usr/bin/python2.7",
|
||||
"gcc_dir": "/builds/worker/workspace/build/src/gcc",
|
||||
"cc": "/builds/worker/workspace/build/src/clang/bin/clang",
|
||||
|
@ -1,15 +1,15 @@
|
||||
{
|
||||
"llvm_revision": "349247",
|
||||
"llvm_revision": "342383",
|
||||
"stages": "1",
|
||||
"build_libcxx": false,
|
||||
"build_type": "Release",
|
||||
"assertions": false,
|
||||
"build_clang_tidy": true,
|
||||
"llvm_repo": "https://llvm.org/svn/llvm-project/llvm/tags/RELEASE_701/final",
|
||||
"clang_repo": "https://llvm.org/svn/llvm-project/cfe/tags/RELEASE_701/final",
|
||||
"extra_repo": "https://llvm.org/svn/llvm-project/clang-tools-extra/tags/RELEASE_701/final",
|
||||
"compiler_repo": "https://llvm.org/svn/llvm-project/compiler-rt/tags/RELEASE_701/final",
|
||||
"libcxx_repo": "https://llvm.org/svn/llvm-project/libcxx/tags/RELEASE_701/final",
|
||||
"llvm_repo": "https://llvm.org/svn/llvm-project/llvm/tags/RELEASE_700/final",
|
||||
"clang_repo": "https://llvm.org/svn/llvm-project/cfe/tags/RELEASE_700/final",
|
||||
"extra_repo": "https://llvm.org/svn/llvm-project/clang-tools-extra/tags/RELEASE_700/final",
|
||||
"compiler_repo": "https://llvm.org/svn/llvm-project/compiler-rt/tags/RELEASE_700/final",
|
||||
"libcxx_repo": "https://llvm.org/svn/llvm-project/libcxx/tags/RELEASE_700/final",
|
||||
"python_path": "c:/mozilla-build/python/python.exe",
|
||||
"cc": "cl.exe",
|
||||
"cxx": "cl.exe",
|
||||
|
@ -1,15 +1,15 @@
|
||||
{
|
||||
"llvm_revision": "349247",
|
||||
"llvm_revision": "342383",
|
||||
"stages": "1",
|
||||
"build_libcxx": false,
|
||||
"build_type": "Release",
|
||||
"assertions": false,
|
||||
"build_clang_tidy": true,
|
||||
"llvm_repo": "https://llvm.org/svn/llvm-project/llvm/tags/RELEASE_701/final",
|
||||
"clang_repo": "https://llvm.org/svn/llvm-project/cfe/tags/RELEASE_701/final",
|
||||
"extra_repo": "https://llvm.org/svn/llvm-project/clang-tools-extra/tags/RELEASE_701/final",
|
||||
"compiler_repo": "https://llvm.org/svn/llvm-project/compiler-rt/tags/RELEASE_701/final",
|
||||
"libcxx_repo": "https://llvm.org/svn/llvm-project/libcxx/tags/RELEASE_701/final",
|
||||
"llvm_repo": "https://llvm.org/svn/llvm-project/llvm/tags/RELEASE_700/final",
|
||||
"clang_repo": "https://llvm.org/svn/llvm-project/cfe/tags/RELEASE_700/final",
|
||||
"extra_repo": "https://llvm.org/svn/llvm-project/clang-tools-extra/tags/RELEASE_700/final",
|
||||
"compiler_repo": "https://llvm.org/svn/llvm-project/compiler-rt/tags/RELEASE_700/final",
|
||||
"libcxx_repo": "https://llvm.org/svn/llvm-project/libcxx/tags/RELEASE_700/final",
|
||||
"python_path": "c:/mozilla-build/python/python.exe",
|
||||
"cc": "cl.exe",
|
||||
"cxx": "cl.exe",
|
||||
|
@ -1,14 +1,14 @@
|
||||
{
|
||||
"llvm_revision": "349247",
|
||||
"llvm_revision": "342383",
|
||||
"stages": "3",
|
||||
"build_libcxx": false,
|
||||
"build_type": "Release",
|
||||
"assertions": false,
|
||||
"llvm_repo": "https://llvm.org/svn/llvm-project/llvm/tags/RELEASE_701/final",
|
||||
"clang_repo": "https://llvm.org/svn/llvm-project/cfe/tags/RELEASE_701/final",
|
||||
"lld_repo": "https://llvm.org/svn/llvm-project/lld/tags/RELEASE_701/final",
|
||||
"compiler_repo": "https://llvm.org/svn/llvm-project/compiler-rt/tags/RELEASE_701/final",
|
||||
"libcxx_repo": "https://llvm.org/svn/llvm-project/libcxx/tags/RELEASE_701/final",
|
||||
"llvm_repo": "https://llvm.org/svn/llvm-project/llvm/tags/RELEASE_700/final",
|
||||
"clang_repo": "https://llvm.org/svn/llvm-project/cfe/tags/RELEASE_700/final",
|
||||
"lld_repo": "https://llvm.org/svn/llvm-project/lld/tags/RELEASE_700/final",
|
||||
"compiler_repo": "https://llvm.org/svn/llvm-project/compiler-rt/tags/RELEASE_700/final",
|
||||
"libcxx_repo": "https://llvm.org/svn/llvm-project/libcxx/tags/RELEASE_700/final",
|
||||
"python_path": "c:/mozilla-build/python/python.exe",
|
||||
"cc": "cl.exe",
|
||||
"cxx": "cl.exe",
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include "mozilla/dom/BlobURLProtocolHandler.h"
|
||||
#include "mozilla/dom/ChromeUtils.h"
|
||||
#include "mozilla/dom/CSPDictionariesBinding.h"
|
||||
#include "mozilla/dom/nsCSPContext.h"
|
||||
#include "mozilla/dom/ToJSValue.h"
|
||||
|
||||
namespace mozilla {
|
||||
@ -494,6 +495,34 @@ void BasePrincipal::FinishInit(const nsACString& aOriginNoSuffix,
|
||||
mOriginNoSuffix = NS_Atomize(aOriginNoSuffix);
|
||||
}
|
||||
|
||||
void BasePrincipal::FinishInit(BasePrincipal* aOther,
|
||||
const OriginAttributes& aOriginAttributes) {
|
||||
mInitialized = true;
|
||||
mOriginAttributes = aOriginAttributes;
|
||||
|
||||
// First compute the origin suffix since it's infallible.
|
||||
nsAutoCString originSuffix;
|
||||
mOriginAttributes.CreateSuffix(originSuffix);
|
||||
mOriginSuffix = NS_Atomize(originSuffix);
|
||||
|
||||
mOriginNoSuffix = aOther->mOriginNoSuffix;
|
||||
mHasExplicitDomain = aOther->mHasExplicitDomain;
|
||||
|
||||
if (aOther->mPreloadCSP) {
|
||||
mPreloadCSP = do_CreateInstance("@mozilla.org/cspcontext;1");
|
||||
nsCSPContext* preloadCSP = static_cast<nsCSPContext*>(mPreloadCSP.get());
|
||||
preloadCSP->InitFromOther(
|
||||
static_cast<nsCSPContext*>(aOther->mPreloadCSP.get()), nullptr, this);
|
||||
}
|
||||
|
||||
if (aOther->mCSP) {
|
||||
mCSP = do_CreateInstance("@mozilla.org/cspcontext;1");
|
||||
nsCSPContext* csp = static_cast<nsCSPContext*>(mCSP.get());
|
||||
csp->InitFromOther(static_cast<nsCSPContext*>(aOther->mCSP.get()), nullptr,
|
||||
this);
|
||||
}
|
||||
}
|
||||
|
||||
bool SiteIdentifier::Equals(const SiteIdentifier& aOther) const {
|
||||
MOZ_ASSERT(IsInitialized());
|
||||
MOZ_ASSERT(aOther.IsInitialized());
|
||||
|
@ -241,11 +241,13 @@ class BasePrincipal : public nsJSPrincipals {
|
||||
|
||||
void SetHasExplicitDomain() { mHasExplicitDomain = true; }
|
||||
|
||||
// This function should be called as the last step of the initialization of
|
||||
// the principal objects. It's typically called as the last step from the
|
||||
// Init() method of the child classes.
|
||||
// Either of these functions should be called as the last step of the
|
||||
// initialization of the principal objects. It's typically called as the
|
||||
// last step from the Init() method of the child classes.
|
||||
void FinishInit(const nsACString& aOriginNoSuffix,
|
||||
const OriginAttributes& aOriginAttributes);
|
||||
void FinishInit(BasePrincipal* aOther,
|
||||
const OriginAttributes& aOriginAttributes);
|
||||
|
||||
nsCOMPtr<nsIContentSecurityPolicy> mCSP;
|
||||
nsCOMPtr<nsIContentSecurityPolicy> mPreloadCSP;
|
||||
|
@ -81,6 +81,18 @@ nsresult ContentPrincipal::Init(nsIURI* aCodebase,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult ContentPrincipal::Init(ContentPrincipal* aOther,
|
||||
const OriginAttributes& aOriginAttributes) {
|
||||
NS_ENSURE_ARG(aOther);
|
||||
|
||||
mCodebase = aOther->mCodebase;
|
||||
FinishInit(aOther, aOriginAttributes);
|
||||
|
||||
mDomain = aOther->mDomain;
|
||||
mAddon = aOther->mAddon;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult ContentPrincipal::GetScriptLocation(nsACString& aStr) {
|
||||
return mCodebase->GetSpec(aStr);
|
||||
}
|
||||
|
@ -38,6 +38,8 @@ class ContentPrincipal final : public BasePrincipal {
|
||||
// Init() must be called before the principal is in a usable state.
|
||||
nsresult Init(nsIURI* aCodebase, const OriginAttributes& aOriginAttributes,
|
||||
const nsACString& aOriginNoSuffix);
|
||||
nsresult Init(ContentPrincipal* aOther,
|
||||
const OriginAttributes& aOriginAttributes);
|
||||
|
||||
virtual nsresult GetScriptLocation(nsACString& aStr) override;
|
||||
|
||||
|
@ -154,6 +154,14 @@ interface nsIScriptSecurityManager : nsISupports
|
||||
nsIPrincipal getDocShellCodebasePrincipal(in nsIURI uri,
|
||||
in nsIDocShell docShell);
|
||||
|
||||
/**
|
||||
* If this is a codebase principal, return a copy with different
|
||||
* origin attributes.
|
||||
*/
|
||||
[implicit_jscontext]
|
||||
nsIPrincipal principalWithOA(in nsIPrincipal principal,
|
||||
in jsval originAttributes);
|
||||
|
||||
/**
|
||||
* Returns a principal whose origin is composed of |uri| and |originAttributes|.
|
||||
* See nsIPrincipal.idl for a description of origin attributes, and
|
||||
|
@ -120,9 +120,10 @@ JS_PUBLIC_API void JSPrincipals::dump() {
|
||||
return ReadKnownPrincipalType(aCx, aReader, tag, aOutPrincipals);
|
||||
}
|
||||
|
||||
static bool ReadPrincipalInfo(JSStructuredCloneReader* aReader,
|
||||
OriginAttributes& aAttrs, nsACString& aSpec,
|
||||
nsACString& aOriginNoSuffix) {
|
||||
static bool ReadPrincipalInfo(
|
||||
JSStructuredCloneReader* aReader, OriginAttributes& aAttrs,
|
||||
nsACString& aSpec, nsACString& aOriginNoSuffix,
|
||||
nsTArray<ContentSecurityPolicy>* aPolicies = nullptr) {
|
||||
uint32_t suffixLength, specLength;
|
||||
if (!JS_ReadUint32Pair(aReader, &suffixLength, &specLength)) {
|
||||
return false;
|
||||
@ -149,12 +150,14 @@ static bool ReadPrincipalInfo(JSStructuredCloneReader* aReader,
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t originNoSuffixLength, dummy;
|
||||
if (!JS_ReadUint32Pair(aReader, &originNoSuffixLength, &dummy)) {
|
||||
uint32_t originNoSuffixLength, policyCount;
|
||||
if (!JS_ReadUint32Pair(aReader, &originNoSuffixLength, &policyCount)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(dummy == 0);
|
||||
if (!aPolicies) {
|
||||
MOZ_ASSERT(policyCount == 0);
|
||||
}
|
||||
|
||||
if (!aOriginNoSuffix.SetLength(originNoSuffixLength, fallible)) {
|
||||
return false;
|
||||
@ -165,6 +168,29 @@ static bool ReadPrincipalInfo(JSStructuredCloneReader* aReader,
|
||||
return false;
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < policyCount; i++) {
|
||||
uint32_t policyLength, reportAndMeta;
|
||||
if (!JS_ReadUint32Pair(aReader, &policyLength, &reportAndMeta)) {
|
||||
return false;
|
||||
}
|
||||
bool reportOnly = reportAndMeta & 1;
|
||||
bool deliveredViaMetaTag = reportAndMeta & 2;
|
||||
|
||||
nsAutoCString policyStr;
|
||||
if (!policyStr.SetLength(policyLength, fallible)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!JS_ReadBytes(aReader, policyStr.BeginWriting(), policyLength)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (aPolicies) {
|
||||
aPolicies->AppendElement(ContentSecurityPolicy(
|
||||
NS_ConvertUTF8toUTF16(policyStr), reportOnly, deliveredViaMetaTag));
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -206,7 +232,8 @@ static bool ReadPrincipalInfo(JSStructuredCloneReader* aReader, uint32_t aTag,
|
||||
OriginAttributes attrs;
|
||||
nsAutoCString spec;
|
||||
nsAutoCString originNoSuffix;
|
||||
if (!ReadPrincipalInfo(aReader, attrs, spec, originNoSuffix)) {
|
||||
nsTArray<ContentSecurityPolicy> policies;
|
||||
if (!ReadPrincipalInfo(aReader, attrs, spec, originNoSuffix, &policies)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -218,7 +245,8 @@ static bool ReadPrincipalInfo(JSStructuredCloneReader* aReader, uint32_t aTag,
|
||||
|
||||
MOZ_DIAGNOSTIC_ASSERT(!originNoSuffix.IsEmpty());
|
||||
|
||||
aInfo = ContentPrincipalInfo(attrs, originNoSuffix, spec);
|
||||
aInfo =
|
||||
ContentPrincipalInfo(attrs, originNoSuffix, spec, std::move(policies));
|
||||
} else {
|
||||
#ifdef FUZZING
|
||||
return false;
|
||||
@ -259,19 +287,37 @@ static bool ReadPrincipalInfo(JSStructuredCloneReader* aReader, uint32_t aTag,
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool WritePrincipalInfo(JSStructuredCloneWriter* aWriter,
|
||||
const OriginAttributes& aAttrs,
|
||||
const nsCString& aSpec,
|
||||
const nsCString& aOriginNoSuffix) {
|
||||
static bool WritePrincipalInfo(
|
||||
JSStructuredCloneWriter* aWriter, const OriginAttributes& aAttrs,
|
||||
const nsCString& aSpec, const nsCString& aOriginNoSuffix,
|
||||
const nsTArray<ContentSecurityPolicy>* aPolicies = nullptr) {
|
||||
nsAutoCString suffix;
|
||||
aAttrs.CreateSuffix(suffix);
|
||||
size_t policyCount = aPolicies ? aPolicies->Length() : 0;
|
||||
|
||||
return JS_WriteUint32Pair(aWriter, suffix.Length(), aSpec.Length()) &&
|
||||
JS_WriteBytes(aWriter, suffix.get(), suffix.Length()) &&
|
||||
JS_WriteBytes(aWriter, aSpec.get(), aSpec.Length()) &&
|
||||
JS_WriteUint32Pair(aWriter, aOriginNoSuffix.Length(), 0) &&
|
||||
JS_WriteBytes(aWriter, aOriginNoSuffix.get(),
|
||||
aOriginNoSuffix.Length());
|
||||
if (!(JS_WriteUint32Pair(aWriter, suffix.Length(), aSpec.Length()) &&
|
||||
JS_WriteBytes(aWriter, suffix.get(), suffix.Length()) &&
|
||||
JS_WriteBytes(aWriter, aSpec.get(), aSpec.Length()) &&
|
||||
JS_WriteUint32Pair(aWriter, aOriginNoSuffix.Length(), policyCount) &&
|
||||
JS_WriteBytes(aWriter, aOriginNoSuffix.get(),
|
||||
aOriginNoSuffix.Length()))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < policyCount; i++) {
|
||||
nsCString policy;
|
||||
CopyUTF16toUTF8((*aPolicies)[i].policy(), policy);
|
||||
uint32_t reportAndMeta =
|
||||
((*aPolicies)[i].reportOnlyFlag() ? 1 : 0) |
|
||||
((*aPolicies)[i].deliveredViaMetaTagFlag() ? 2 : 0);
|
||||
if (!(JS_WriteUint32Pair(aWriter, policy.Length(), reportAndMeta) &&
|
||||
JS_WriteBytes(aWriter, PromiseFlatCString(policy).get(),
|
||||
policy.Length()))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool WritePrincipalInfo(JSStructuredCloneWriter* aWriter,
|
||||
@ -304,7 +350,8 @@ static bool WritePrincipalInfo(JSStructuredCloneWriter* aWriter,
|
||||
const ContentPrincipalInfo& cInfo = aInfo;
|
||||
return JS_WriteUint32Pair(aWriter, SCTAG_DOM_CONTENT_PRINCIPAL, 0) &&
|
||||
WritePrincipalInfo(aWriter, cInfo.attrs(), cInfo.spec(),
|
||||
cInfo.originNoSuffix());
|
||||
cInfo.originNoSuffix(),
|
||||
&(cInfo.securityPolicies()));
|
||||
}
|
||||
|
||||
bool nsJSPrincipals::write(JSContext* aCx, JSStructuredCloneWriter* aWriter) {
|
||||
|
@ -1257,6 +1257,35 @@ nsScriptSecurityManager::GetDocShellCodebasePrincipal(
|
||||
return *aPrincipal ? NS_OK : NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsScriptSecurityManager::PrincipalWithOA(
|
||||
nsIPrincipal* aPrincipal, JS::Handle<JS::Value> aOriginAttributes,
|
||||
JSContext* aCx, nsIPrincipal** aReturnPrincipal) {
|
||||
if (!aPrincipal) {
|
||||
return NS_OK;
|
||||
}
|
||||
if (aPrincipal->GetIsCodebasePrincipal()) {
|
||||
OriginAttributes attrs;
|
||||
if (!aOriginAttributes.isObject() || !attrs.Init(aCx, aOriginAttributes)) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
RefPtr<ContentPrincipal> copy = new ContentPrincipal();
|
||||
ContentPrincipal* contentPrincipal =
|
||||
static_cast<ContentPrincipal*>(aPrincipal);
|
||||
nsresult rv = copy->Init(contentPrincipal, attrs);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
copy.forget(aReturnPrincipal);
|
||||
} else {
|
||||
// We do this for null principals, system principals (both fine)
|
||||
// ... and expanded principals, where we should probably do something
|
||||
// cleverer, but I also don't think we care too much.
|
||||
nsCOMPtr<nsIPrincipal> prin = aPrincipal;
|
||||
prin.forget(aReturnPrincipal);
|
||||
}
|
||||
|
||||
return *aReturnPrincipal ? NS_OK : NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsScriptSecurityManager::CanCreateWrapper(JSContext* cx, const nsIID& aIID,
|
||||
nsISupports* aObj,
|
||||
|
BIN
config/external/icu/data/icudt63l.dat
vendored
BIN
config/external/icu/data/icudt63l.dat
vendored
Binary file not shown.
@ -704,6 +704,7 @@ skip-if = (os == "win" && ccov) # Bug 1424154
|
||||
[browser_dbg-expressions-error.js]
|
||||
[browser_dbg-iframes.js]
|
||||
[browser_dbg-inline-cache.js]
|
||||
skip-if = ccov && os == 'win' # Bug 1443132
|
||||
[browser_dbg-inspector-integration.js]
|
||||
[browser_dbg-keyboard-navigation.js]
|
||||
[browser_dbg-keyboard-shortcuts.js]
|
||||
|
@ -54,6 +54,7 @@ support-files =
|
||||
browser_timelineMarkers-frame-05.js
|
||||
head.js
|
||||
frame-head.js
|
||||
file_data_load_inherit_csp.html
|
||||
file_click_link_within_view_source.html
|
||||
onload_message.html
|
||||
onpageshow_message.html
|
||||
@ -92,6 +93,7 @@ skip-if = verify
|
||||
[browser_bug852909.js]
|
||||
skip-if = (verify && debug && (os == 'win'))
|
||||
[browser_bug92473.js]
|
||||
[browser_data_load_inherit_csp.js]
|
||||
[browser_dataURI_unique_opaque_origin.js]
|
||||
[browser_uriFixupIntegration.js]
|
||||
[browser_uriFixupAlternateRedirects.js]
|
||||
|
82
docshell/test/browser/browser_data_load_inherit_csp.js
Normal file
82
docshell/test/browser/browser_data_load_inherit_csp.js
Normal file
@ -0,0 +1,82 @@
|
||||
"use strict";
|
||||
|
||||
const TEST_PATH = getRootDirectory(gTestPath).replace("chrome://mochitests/content", "http://example.com");
|
||||
const HTML_URI = TEST_PATH + "file_data_load_inherit_csp.html";
|
||||
const DATA_URI = "data:text/html;html,<html><body>foo</body></html>";
|
||||
|
||||
function setDataHrefOnLink(aBrowser, aDataURI) {
|
||||
return ContentTask.spawn(aBrowser, aDataURI, function(uri) {
|
||||
let link = content.document.getElementById("testlink");
|
||||
link.href = uri;
|
||||
});
|
||||
};
|
||||
|
||||
function verifyCSP(aTestName, aBrowser, aDataURI) {
|
||||
return ContentTask.spawn(aBrowser, {aTestName, aDataURI}, async function ({aTestName, aDataURI}) {
|
||||
let channel = content.docShell.currentDocumentChannel;
|
||||
is(channel.URI.spec, aDataURI, "testing CSP for " + aTestName);
|
||||
let principal = channel.loadInfo.triggeringPrincipal;
|
||||
let cspJSON = principal.cspJSON;
|
||||
let cspOBJ = JSON.parse(cspJSON);
|
||||
let policies = cspOBJ["csp-policies"];
|
||||
is(policies.length, 1, "should be one policy");
|
||||
let policy = policies[0];
|
||||
is(policy['script-src'], "'unsafe-inline'", "script-src directive matches");
|
||||
});
|
||||
};
|
||||
|
||||
add_task(async function setup() {
|
||||
// allow top level data: URI navigations, otherwise clicking data: link fails
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
"set": [["security.data_uri.block_toplevel_data_uri_navigations", false]],
|
||||
});
|
||||
});
|
||||
|
||||
add_task(async function test_data_csp_inheritance_regular_click() {
|
||||
await BrowserTestUtils.withNewTab(HTML_URI, async function(browser) {
|
||||
let loadPromise = BrowserTestUtils.browserLoaded(browser, false, DATA_URI);
|
||||
// set the data href + simulate click
|
||||
await setDataHrefOnLink(gBrowser.selectedBrowser, DATA_URI);
|
||||
BrowserTestUtils.synthesizeMouseAtCenter("#testlink", {},
|
||||
gBrowser.selectedBrowser);
|
||||
await loadPromise;
|
||||
await verifyCSP("click()", gBrowser.selectedBrowser, DATA_URI);
|
||||
});
|
||||
});
|
||||
|
||||
add_task(async function test_data_csp_inheritance_ctrl_click() {
|
||||
await BrowserTestUtils.withNewTab(HTML_URI, async function(browser) {
|
||||
let loadPromise = BrowserTestUtils.waitForNewTab(gBrowser, DATA_URI);
|
||||
// set the data href + simulate ctrl+click
|
||||
await setDataHrefOnLink(gBrowser.selectedBrowser, DATA_URI);
|
||||
BrowserTestUtils.synthesizeMouseAtCenter("#testlink",
|
||||
{ ctrlKey: true, metaKey: true },
|
||||
gBrowser.selectedBrowser);
|
||||
let tab = await loadPromise;
|
||||
gBrowser.selectTabAtIndex(2);
|
||||
await verifyCSP("ctrl-click()", gBrowser.selectedBrowser, DATA_URI);
|
||||
await BrowserTestUtils.removeTab(tab);
|
||||
});
|
||||
});
|
||||
|
||||
add_task(async function test_data_csp_inheritance_right_click_open_link_in_new_tab() {
|
||||
await BrowserTestUtils.withNewTab(HTML_URI, async function(browser) {
|
||||
let loadPromise = BrowserTestUtils.waitForNewTab(gBrowser, DATA_URI);
|
||||
// set the data href + simulate right-click open link in tab
|
||||
await setDataHrefOnLink(gBrowser.selectedBrowser, DATA_URI);
|
||||
BrowserTestUtils.waitForEvent(document, "popupshown", false, event => {
|
||||
// These are operations that must be executed synchronously with the event.
|
||||
document.getElementById("context-openlinkintab").doCommand();
|
||||
event.target.hidePopup();
|
||||
return true;
|
||||
});
|
||||
BrowserTestUtils.synthesizeMouseAtCenter("#testlink",
|
||||
{ type: "contextmenu", button: 2 },
|
||||
gBrowser.selectedBrowser);
|
||||
|
||||
let tab = await loadPromise;
|
||||
gBrowser.selectTabAtIndex(2);
|
||||
await verifyCSP("right-click-open-in-new-tab()", gBrowser.selectedBrowser, DATA_URI);
|
||||
await BrowserTestUtils.removeTab(tab);
|
||||
});
|
||||
});
|
11
docshell/test/browser/file_data_load_inherit_csp.html
Normal file
11
docshell/test/browser/file_data_load_inherit_csp.html
Normal file
@ -0,0 +1,11 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Bug 1358009 - Inherit CSP into data URI</title>
|
||||
<meta http-equiv="Content-Security-Policy" content="script-src 'unsafe-inline'">
|
||||
</head>
|
||||
<body>
|
||||
<a id="testlink">testlink</a>
|
||||
</body>
|
||||
</html>
|
5
dom/cache/DBSchema.cpp
vendored
5
dom/cache/DBSchema.cpp
vendored
@ -2490,8 +2490,11 @@ nsresult ReadResponse(mozIStorageConnection* aConn, EntryId aEntryId,
|
||||
nsCString origin;
|
||||
url->Origin(origin);
|
||||
|
||||
// CSP is recovered from the headers, no need to initialise it here.
|
||||
nsTArray<mozilla::ipc::ContentSecurityPolicy> policies;
|
||||
aSavedResponseOut->mValue.principalInfo() =
|
||||
mozilla::ipc::ContentPrincipalInfo(attrs, origin, specNoSuffix);
|
||||
mozilla::ipc::ContentPrincipalInfo(attrs, origin, specNoSuffix,
|
||||
std::move(policies));
|
||||
}
|
||||
|
||||
bool nullPadding = false;
|
||||
|
@ -64,7 +64,7 @@ ReverbConvolver::ReverbConvolver(const float* impulseResponseData,
|
||||
m_accumulationBuffer(impulseResponseLength + WEBAUDIO_BLOCK_SIZE),
|
||||
m_inputBuffer(InputBufferSize),
|
||||
m_backgroundThread("ConvolverWorker"),
|
||||
m_backgroundThreadCondition(&m_backgroundThreadLock),
|
||||
m_backgroundThreadMonitor("ConvolverMonitor"),
|
||||
m_useBackgroundThreads(useBackgroundThreads),
|
||||
m_wantsToExit(false),
|
||||
m_moreInputBuffered(false) {
|
||||
@ -166,9 +166,9 @@ ReverbConvolver::~ReverbConvolver() {
|
||||
|
||||
// Wake up thread so it can return
|
||||
{
|
||||
AutoLock locker(m_backgroundThreadLock);
|
||||
MonitorAutoLock locker(m_backgroundThreadMonitor);
|
||||
m_moreInputBuffered = true;
|
||||
m_backgroundThreadCondition.Signal();
|
||||
m_backgroundThreadMonitor.Notify();
|
||||
}
|
||||
|
||||
m_backgroundThread.Stop();
|
||||
@ -199,8 +199,7 @@ size_t ReverbConvolver::sizeOfIncludingThis(
|
||||
|
||||
// Possible future measurements:
|
||||
// - m_backgroundThread
|
||||
// - m_backgroundThreadLock
|
||||
// - m_backgroundThreadCondition
|
||||
// - m_backgroundThreadMonitor
|
||||
return amount;
|
||||
}
|
||||
|
||||
@ -209,9 +208,9 @@ void ReverbConvolver::backgroundThreadEntry() {
|
||||
// Wait for realtime thread to give us more input
|
||||
m_moreInputBuffered = false;
|
||||
{
|
||||
AutoLock locker(m_backgroundThreadLock);
|
||||
MonitorAutoLock locker(m_backgroundThreadMonitor);
|
||||
while (!m_moreInputBuffered && !m_wantsToExit)
|
||||
m_backgroundThreadCondition.Wait();
|
||||
m_backgroundThreadMonitor.Wait();
|
||||
}
|
||||
|
||||
// Process all of the stages until their read indices reach the input
|
||||
@ -251,17 +250,17 @@ void ReverbConvolver::process(const float* sourceChannelData,
|
||||
|
||||
// Now that we've buffered more input, wake up our background thread.
|
||||
|
||||
// Not using a MutexLocker looks strange, but we use a tryLock() instead
|
||||
// Not using a MonitorAutoLock looks strange, but we use a TryLock() instead
|
||||
// because this is run on the real-time thread where it is a disaster for the
|
||||
// lock to be contended (causes audio glitching). It's OK if we fail to
|
||||
// signal from time to time, since we'll get to it the next time we're called.
|
||||
// We're called repeatedly and frequently (around every 3ms). The background
|
||||
// thread is processing well into the future and has a considerable amount of
|
||||
// leeway here...
|
||||
if (m_backgroundThreadLock.Try()) {
|
||||
if (m_backgroundThreadMonitor.TryLock()) {
|
||||
m_moreInputBuffered = true;
|
||||
m_backgroundThreadCondition.Signal();
|
||||
m_backgroundThreadLock.Release();
|
||||
m_backgroundThreadMonitor.Notify();
|
||||
m_backgroundThreadMonitor.Unlock();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -33,11 +33,10 @@
|
||||
#include "ReverbInputBuffer.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "mozilla/MemoryReporting.h"
|
||||
#include "mozilla/Monitor.h"
|
||||
#ifdef LOG
|
||||
#undef LOG
|
||||
#endif
|
||||
#include "base/condition_variable.h"
|
||||
#include "base/lock.h"
|
||||
#include "base/thread.h"
|
||||
|
||||
namespace WebCore {
|
||||
@ -80,8 +79,7 @@ class ReverbConvolver {
|
||||
|
||||
// Background thread and synchronization
|
||||
base::Thread m_backgroundThread;
|
||||
Lock m_backgroundThreadLock;
|
||||
ConditionVariable m_backgroundThreadCondition;
|
||||
mozilla::Monitor m_backgroundThreadMonitor;
|
||||
bool m_useBackgroundThreads;
|
||||
bool m_wantsToExit;
|
||||
bool m_moreInputBuffered;
|
||||
|
@ -261,6 +261,22 @@ nsCSPContext::~nsCSPContext() {
|
||||
}
|
||||
}
|
||||
|
||||
nsresult nsCSPContext::InitFromOther(nsCSPContext* aOtherContext,
|
||||
Document* aDoc, nsIPrincipal* aPrincipal) {
|
||||
NS_ENSURE_ARG(aOtherContext);
|
||||
|
||||
nsresult rv = SetRequestContext(aDoc, aPrincipal);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
for (auto policy : aOtherContext->mPolicies) {
|
||||
nsAutoString policyStr;
|
||||
policy->toString(policyStr);
|
||||
AppendPolicy(policyStr, policy->getReportOnlyFlag(),
|
||||
policy->getDeliveredViaMetaTagFlag());
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCSPContext::GetPolicyString(uint32_t aIndex, nsAString& outStr) {
|
||||
outStr.Truncate();
|
||||
|
@ -51,6 +51,10 @@ class nsCSPContext : public nsIContentSecurityPolicy {
|
||||
public:
|
||||
nsCSPContext();
|
||||
|
||||
nsresult InitFromOther(nsCSPContext* otherContext,
|
||||
mozilla::dom::Document* aDoc,
|
||||
nsIPrincipal* aPrincipal);
|
||||
|
||||
/**
|
||||
* SetRequestContext() needs to be called before the innerWindowID
|
||||
* is initialized on the document. Use this function to call back to
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "nsIScriptError.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsContentPolicyUtils.h"
|
||||
#include "nsNetUtil.h"
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
@ -250,6 +251,17 @@ CSPService::AsyncOnChannelRedirect(nsIChannel *oldChannel,
|
||||
nsIAsyncVerifyRedirectCallback *callback) {
|
||||
net::nsAsyncRedirectAutoCallback autoCallback(callback);
|
||||
|
||||
if (XRE_IsE10sParentProcess()) {
|
||||
nsCOMPtr<nsIParentChannel> parentChannel;
|
||||
NS_QueryNotificationCallbacks(oldChannel, parentChannel);
|
||||
if (parentChannel) {
|
||||
// This is an IPC'd channel. Don't check it here, because we won't have
|
||||
// access to the request context; we'll check them in the content
|
||||
// process instead. Bug 1509738 covers fixing this.
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIURI> newUri;
|
||||
nsresult rv = newChannel->GetURI(getter_AddRefs(newUri));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
@ -10,4 +10,7 @@ support-files =
|
||||
!/dom/security/test/csp/file_web_manifest_remote.html
|
||||
[browser_test_web_manifest.js]
|
||||
[browser_test_web_manifest_mixed_content.js]
|
||||
[browser_test_uir_optional_clicks.js]
|
||||
support-files =
|
||||
file_csp_meta_uir.html
|
||||
[browser_manifest-src-override-default-src.js]
|
||||
|
14
dom/security/test/csp/browser_test_uir_optional_clicks.js
Normal file
14
dom/security/test/csp/browser_test_uir_optional_clicks.js
Normal file
@ -0,0 +1,14 @@
|
||||
"use strict"
|
||||
|
||||
const TEST_PATH_HTTP = getRootDirectory(gTestPath).replace("chrome://mochitests/content", "http://example.com");
|
||||
const TEST_PATH_HTTPS = getRootDirectory(gTestPath).replace("chrome://mochitests/content", "https://example.com");
|
||||
|
||||
add_task(async function() {
|
||||
await BrowserTestUtils.withNewTab(TEST_PATH_HTTPS + "file_csp_meta_uir.html", async function(browser) {
|
||||
let newTabPromise = BrowserTestUtils.waitForNewTab(gBrowser, null, true);
|
||||
BrowserTestUtils.synthesizeMouse("#mylink", 2, 2, {accelKey: true}, browser);
|
||||
let tab = await newTabPromise;
|
||||
is(tab.linkedBrowser.currentURI.scheme, "https", "Should have opened https page.");
|
||||
BrowserTestUtils.removeTab(tab);
|
||||
});
|
||||
});
|
13
dom/security/test/csp/file_csp_meta_uir.html
Normal file
13
dom/security/test/csp/file_csp_meta_uir.html
Normal file
@ -0,0 +1,13 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Hello World</title>
|
||||
<meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests">
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
document.write("<a href='" + document.location.href.replace(/^https/, "http") + "' id='mylink'>Click me</a>");
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -111,8 +111,10 @@ nsresult CreatePrincipalInfo(nsILineInputStream* aStream,
|
||||
return rv;
|
||||
}
|
||||
|
||||
aEntry->principal() =
|
||||
mozilla::ipc::ContentPrincipalInfo(attrs, origin, aEntry->scope());
|
||||
// CSP will be applied during the script load.
|
||||
nsTArray<mozilla::ipc::ContentSecurityPolicy> policies;
|
||||
aEntry->principal() = mozilla::ipc::ContentPrincipalInfo(
|
||||
attrs, origin, aEntry->scope(), std::move(policies));
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -271,8 +271,10 @@ TEST(ServiceWorkerRegistrar, TestWriteData) {
|
||||
|
||||
nsAutoCString spec;
|
||||
spec.AppendPrintf("spec write %d", i);
|
||||
|
||||
nsTArray<mozilla::ipc::ContentSecurityPolicy> policies;
|
||||
reg.principal() = mozilla::ipc::ContentPrincipalInfo(
|
||||
mozilla::OriginAttributes(i, i % 2), spec, spec);
|
||||
mozilla::OriginAttributes(i, i % 2), spec, spec, std::move(policies));
|
||||
|
||||
swr->TestRegisterServiceWorker(reg);
|
||||
}
|
||||
@ -858,8 +860,10 @@ TEST(ServiceWorkerRegistrar, TestDedupeWrite) {
|
||||
|
||||
nsAutoCString spec;
|
||||
spec.AppendPrintf("spec write dedupe/%d", i);
|
||||
|
||||
nsTArray<mozilla::ipc::ContentSecurityPolicy> policies;
|
||||
reg.principal() = mozilla::ipc::ContentPrincipalInfo(
|
||||
mozilla::OriginAttributes(0, false), spec, spec);
|
||||
mozilla::OriginAttributes(0, false), spec, spec, std::move(policies));
|
||||
|
||||
swr->TestRegisterServiceWorker(reg);
|
||||
}
|
||||
|
@ -11,13 +11,6 @@ using struct mozilla::void_t from "ipc/IPCMessageUtils.h";
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
struct ContentSecurityPolicy
|
||||
{
|
||||
nsString policy;
|
||||
bool reportOnlyFlag;
|
||||
bool deliveredViaMetaTagFlag;
|
||||
};
|
||||
|
||||
struct RemoteWorkerData
|
||||
{
|
||||
// This should only be used for devtools.
|
||||
|
@ -38,34 +38,6 @@ using namespace mozilla::ipc;
|
||||
|
||||
namespace {
|
||||
|
||||
nsresult PopulateContentSecurityPolicies(
|
||||
nsIContentSecurityPolicy* aCSP,
|
||||
nsTArray<ContentSecurityPolicy>& aPolicies) {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(aCSP);
|
||||
MOZ_ASSERT(aPolicies.IsEmpty());
|
||||
|
||||
uint32_t count = 0;
|
||||
nsresult rv = aCSP->GetPolicyCount(&count);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < count; ++i) {
|
||||
const nsCSPPolicy* policy = aCSP->GetPolicy(i);
|
||||
MOZ_ASSERT(policy);
|
||||
|
||||
nsAutoString policyString;
|
||||
policy->toString(policyString);
|
||||
|
||||
aPolicies.AppendElement(
|
||||
ContentSecurityPolicy(policyString, policy->getReportOnlyFlag(),
|
||||
policy->getDeliveredViaMetaTagFlag()));
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult PopulateContentSecurityPolicyArray(
|
||||
nsIPrincipal* aPrincipal, nsTArray<ContentSecurityPolicy>& policies,
|
||||
nsTArray<ContentSecurityPolicy>& preloadPolicies) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
commit 6e82c7c389888603f0de84ffe5c60f43f11ee844
|
||||
commit 26eea4948c743417c8aa9d1e7fd900d1fb57fbdc
|
||||
Author: Yoshito Umaoka <yoshito_umaoka@us.ibm.com>
|
||||
Date: Wed Nov 7 19:23:35 2018 -0500
|
||||
Date: Wed Jan 2 17:39:20 2019 -0500
|
||||
|
||||
ICU-20260 Fix CR/LF issue
|
||||
ICU time zone data updates for tzdata 2018i (including 2018h changes)
|
||||
|
@ -1 +1 @@
|
||||
2018g
|
||||
2018i
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -813,12 +813,7 @@ metaZones:table(nofallback){
|
||||
{
|
||||
"Europe_Western",
|
||||
"1985-12-31 23:00",
|
||||
"2018-10-26 23:00",
|
||||
}
|
||||
{
|
||||
"Europe_Central",
|
||||
"2018-10-26 23:00",
|
||||
"9999-12-31 23:59",
|
||||
"2018-10-28 02:00",
|
||||
}
|
||||
}
|
||||
"Africa:Ceuta"{
|
||||
@ -867,12 +862,7 @@ metaZones:table(nofallback){
|
||||
{
|
||||
"Europe_Western",
|
||||
"1976-04-14 01:00",
|
||||
"2018-10-26 23:00",
|
||||
}
|
||||
{
|
||||
"Europe_Central",
|
||||
"2018-10-26 23:00",
|
||||
"9999-12-31 23:59",
|
||||
"2018-10-28 02:00",
|
||||
}
|
||||
}
|
||||
"Africa:Freetown"{
|
||||
@ -1045,6 +1035,11 @@ metaZones:table(nofallback){
|
||||
{
|
||||
"Africa_Western",
|
||||
"2018-01-01 01:00",
|
||||
"2019-01-01 01:00",
|
||||
}
|
||||
{
|
||||
"GMT",
|
||||
"2019-01-01 01:00",
|
||||
"9999-12-31 23:59",
|
||||
}
|
||||
}
|
||||
@ -2086,6 +2081,16 @@ metaZones:table(nofallback){
|
||||
{
|
||||
"Alaska",
|
||||
"2015-11-01 10:00",
|
||||
"2018-11-04 10:00",
|
||||
}
|
||||
{
|
||||
"America_Pacific",
|
||||
"2018-11-04 10:00",
|
||||
"2019-03-10 11:00",
|
||||
}
|
||||
{
|
||||
"Alaska",
|
||||
"2019-03-10 11:00",
|
||||
"9999-12-31 23:59",
|
||||
}
|
||||
}
|
||||
@ -3162,6 +3167,13 @@ metaZones:table(nofallback){
|
||||
"9999-12-31 23:59",
|
||||
}
|
||||
}
|
||||
"Asia:Qostanay"{
|
||||
{
|
||||
"Kazakhstan_Eastern",
|
||||
"2004-10-30 21:00",
|
||||
"9999-12-31 23:59",
|
||||
}
|
||||
}
|
||||
"Asia:Qyzylorda"{
|
||||
{
|
||||
"Kizilorda",
|
||||
@ -3176,6 +3188,11 @@ metaZones:table(nofallback){
|
||||
{
|
||||
"Kazakhstan_Eastern",
|
||||
"2004-10-30 21:00",
|
||||
"2018-12-20 18:00",
|
||||
}
|
||||
{
|
||||
"Kazakhstan_Western",
|
||||
"2018-12-20 18:00",
|
||||
"9999-12-31 23:59",
|
||||
}
|
||||
}
|
||||
@ -4226,11 +4243,11 @@ metaZones:table(nofallback){
|
||||
{
|
||||
"Kwajalein",
|
||||
"1970-01-01 00:00",
|
||||
"1993-08-20 12:00",
|
||||
"1993-08-21 12:00",
|
||||
}
|
||||
{
|
||||
"Marshall_Islands",
|
||||
"1993-08-20 12:00",
|
||||
"1993-08-21 12:00",
|
||||
"9999-12-31 23:59",
|
||||
}
|
||||
}
|
||||
|
@ -416,6 +416,7 @@ timezoneTypes:table(nofallback){
|
||||
"Asia:Pontianak"{"idpnk"}
|
||||
"Asia:Pyongyang"{"kpfnj"}
|
||||
"Asia:Qatar"{"qadoh"}
|
||||
"Asia:Qostanay"{"kzksn"}
|
||||
"Asia:Qyzylorda"{"kzkzo"}
|
||||
"Asia:Rangoon"{"mmrgn"}
|
||||
"Asia:Riyadh"{"saruh"}
|
||||
|
@ -17,8 +17,8 @@ windowsZones:table(nofallback){
|
||||
"Alaskan Standard Time"{
|
||||
001{"America/Anchorage"}
|
||||
US{
|
||||
"America/Anchorage America/Juneau America/Metlakatla America/Nome Ame"
|
||||
"rica/Sitka America/Yakutat"
|
||||
"America/Anchorage America/Juneau America/Nome America/Sitka America/"
|
||||
"Yakutat"
|
||||
}
|
||||
}
|
||||
"Aleutian Standard Time"{
|
||||
@ -130,7 +130,7 @@ windowsZones:table(nofallback){
|
||||
CN{"Asia/Urumqi"}
|
||||
IO{"Indian/Chagos"}
|
||||
KG{"Asia/Bishkek"}
|
||||
KZ{"Asia/Almaty Asia/Qyzylorda"}
|
||||
KZ{"Asia/Almaty Asia/Qostanay"}
|
||||
ZZ{"Etc/GMT-6"}
|
||||
}
|
||||
"Central Brazilian Standard Time"{
|
||||
@ -468,7 +468,7 @@ windowsZones:table(nofallback){
|
||||
"Pacific Standard Time"{
|
||||
001{"America/Los_Angeles"}
|
||||
CA{"America/Vancouver America/Dawson America/Whitehorse"}
|
||||
US{"America/Los_Angeles"}
|
||||
US{"America/Los_Angeles America/Metlakatla"}
|
||||
ZZ{"PST8PDT"}
|
||||
}
|
||||
"Pakistan Standard Time"{
|
||||
@ -779,7 +779,7 @@ windowsZones:table(nofallback){
|
||||
"West Asia Standard Time"{
|
||||
001{"Asia/Tashkent"}
|
||||
AQ{"Antarctica/Mawson"}
|
||||
KZ{"Asia/Oral Asia/Aqtau Asia/Aqtobe Asia/Atyrau"}
|
||||
KZ{"Asia/Oral Asia/Aqtau Asia/Aqtobe Asia/Atyrau Asia/Qyzylorda"}
|
||||
MV{"Indian/Maldives"}
|
||||
TF{"Indian/Kerguelen"}
|
||||
TJ{"Asia/Dushanbe"}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -15,12 +15,15 @@ namespace base {
|
||||
// thread-safe access, since it will only be modified in testing.
|
||||
static AtExitManager* g_top_manager = NULL;
|
||||
|
||||
AtExitManager::AtExitManager() : next_manager_(NULL) {
|
||||
AtExitManager::AtExitManager() : lock_("AtExitManager"),
|
||||
next_manager_(NULL) {
|
||||
DCHECK(!g_top_manager);
|
||||
g_top_manager = this;
|
||||
}
|
||||
|
||||
AtExitManager::AtExitManager(bool shadow) : next_manager_(g_top_manager) {
|
||||
AtExitManager::AtExitManager(bool shadow) : lock_("AtExitManager"),
|
||||
next_manager_(g_top_manager)
|
||||
{
|
||||
DCHECK(shadow || !g_top_manager);
|
||||
g_top_manager = this;
|
||||
}
|
||||
@ -45,7 +48,7 @@ void AtExitManager::RegisterCallback(AtExitCallbackType func, void* param) {
|
||||
|
||||
DCHECK(func);
|
||||
|
||||
AutoLock lock(g_top_manager->lock_);
|
||||
mozilla::MutexAutoLock lock(g_top_manager->lock_);
|
||||
g_top_manager->stack_.push(CallbackAndParam(func, param));
|
||||
}
|
||||
|
||||
@ -56,7 +59,7 @@ void AtExitManager::ProcessCallbacksNow() {
|
||||
return;
|
||||
}
|
||||
|
||||
AutoLock lock(g_top_manager->lock_);
|
||||
mozilla::MutexAutoLock lock(g_top_manager->lock_);
|
||||
|
||||
while (!g_top_manager->stack_.empty()) {
|
||||
CallbackAndParam callback_and_param = g_top_manager->stack_.top();
|
||||
|
@ -10,7 +10,8 @@
|
||||
#include <stack>
|
||||
|
||||
#include "base/basictypes.h"
|
||||
#include "base/lock.h"
|
||||
|
||||
#include "mozilla/Mutex.h"
|
||||
|
||||
namespace base {
|
||||
|
||||
@ -63,7 +64,7 @@ class AtExitManager {
|
||||
void* param_;
|
||||
};
|
||||
|
||||
Lock lock_;
|
||||
mozilla::Mutex lock_;
|
||||
std::stack<CallbackAndParam> stack_;
|
||||
AtExitManager* next_manager_; // Stack of managers to allow shadowing.
|
||||
|
||||
|
@ -26,8 +26,6 @@ namespace base {
|
||||
#define DVLOG(x) CHROMIUM_LOG(ERROR)
|
||||
#define CHECK_GT DCHECK_GT
|
||||
#define CHECK_LT DCHECK_LT
|
||||
typedef ::Lock Lock;
|
||||
typedef ::AutoLock AutoLock;
|
||||
|
||||
// Static table of checksums for all possible 8 bit bytes.
|
||||
const uint32_t Histogram::kCrcTable[256] = {
|
||||
|
@ -50,7 +50,6 @@
|
||||
#include <string>
|
||||
|
||||
#include "base/time.h"
|
||||
#include "base/lock.h"
|
||||
|
||||
#include "nsTArray.h"
|
||||
|
||||
|
@ -171,6 +171,7 @@ MessageLoop::MessageLoop(Type type, nsIEventTarget* aEventTarget)
|
||||
id_(++message_loop_id_seq),
|
||||
nestable_tasks_allowed_(true),
|
||||
exception_restoration_(false),
|
||||
incoming_queue_lock_("MessageLoop Incoming Queue Lock"),
|
||||
state_(NULL),
|
||||
run_depth_base_(1),
|
||||
shutting_down_(false),
|
||||
@ -400,7 +401,7 @@ void MessageLoop::PostTask_Helper(already_AddRefed<nsIRunnable> task,
|
||||
|
||||
RefPtr<base::MessagePump> pump;
|
||||
{
|
||||
AutoLock locked(incoming_queue_lock_);
|
||||
mozilla::MutexAutoLock locked(incoming_queue_lock_);
|
||||
incoming_queue_.push(std::move(pending_task));
|
||||
pump = pump_;
|
||||
}
|
||||
@ -478,7 +479,7 @@ void MessageLoop::ReloadWorkQueue() {
|
||||
|
||||
// Acquire all we can from the inter-thread queue with one lock acquisition.
|
||||
{
|
||||
AutoLock lock(incoming_queue_lock_);
|
||||
mozilla::MutexAutoLock lock(incoming_queue_lock_);
|
||||
if (incoming_queue_.empty()) return;
|
||||
std::swap(incoming_queue_, work_queue_);
|
||||
DCHECK(incoming_queue_.empty());
|
||||
|
@ -13,10 +13,11 @@
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
#include "base/lock.h"
|
||||
#include "base/message_pump.h"
|
||||
#include "base/observer_list.h"
|
||||
|
||||
#include "mozilla/Mutex.h"
|
||||
|
||||
#if defined(OS_WIN)
|
||||
// We need this to declare base::MessagePumpWin::Dispatcher, which we should
|
||||
// really just eliminate.
|
||||
@ -423,7 +424,7 @@ class MessageLoop : public base::MessagePump::Delegate {
|
||||
// will be handled by the TimerManager.
|
||||
TaskQueue incoming_queue_;
|
||||
// Protect access to incoming_queue_.
|
||||
Lock incoming_queue_lock_;
|
||||
mozilla::Mutex incoming_queue_lock_;
|
||||
|
||||
RunState* state_;
|
||||
int run_depth_base_;
|
||||
|
@ -11,7 +11,6 @@
|
||||
|
||||
#include <list>
|
||||
|
||||
#include "base/lock.h"
|
||||
#include "base/message_pump.h"
|
||||
#include "base/observer_list.h"
|
||||
#include "base/scoped_handle.h"
|
||||
|
@ -44,9 +44,9 @@
|
||||
#include <mmsystem.h>
|
||||
|
||||
#include "base/basictypes.h"
|
||||
#include "base/lock.h"
|
||||
#include "base/logging.h"
|
||||
#include "mozilla/Casting.h"
|
||||
#include "mozilla/StaticMutex.h"
|
||||
|
||||
using base::Time;
|
||||
using base::TimeDelta;
|
||||
@ -216,10 +216,8 @@ DWORD (*tick_function)(void) = &timeGetTimeWrapper;
|
||||
// 49 days.
|
||||
class NowSingleton {
|
||||
public:
|
||||
NowSingleton() : rollover_(TimeDelta::FromMilliseconds(0)), last_seen_(0) {}
|
||||
|
||||
TimeDelta Now() {
|
||||
AutoLock locked(lock_);
|
||||
mozilla::StaticMutexAutoLock locked(lock_);
|
||||
// We should hold the lock while calling tick_function to make sure that
|
||||
// we keep our last_seen_ stay correctly in sync.
|
||||
DWORD now = tick_function();
|
||||
@ -231,12 +229,28 @@ class NowSingleton {
|
||||
}
|
||||
|
||||
static NowSingleton& instance() {
|
||||
static NowSingleton now;
|
||||
// This setup is a little gross: the `now` instance lives until libxul is
|
||||
// unloaded, but leak checking runs prior to that, and would see a Mutex
|
||||
// instance contained in NowSingleton as still live. Said instance would
|
||||
// be reported as a leak...but it's not, really. To avoid that, we need
|
||||
// to use StaticMutex (which is not leak-checked), but StaticMutex can't
|
||||
// be a member variable. So we have to have this separate variable and
|
||||
// pass it into the NowSingleton constructor.
|
||||
static mozilla::StaticMutex mutex;
|
||||
static NowSingleton now(mutex);
|
||||
return now;
|
||||
}
|
||||
|
||||
private:
|
||||
Lock lock_; // To protected last_seen_ and rollover_.
|
||||
explicit NowSingleton(mozilla::StaticMutex& aMutex)
|
||||
: lock_(aMutex)
|
||||
, rollover_(TimeDelta::FromMilliseconds(0))
|
||||
, last_seen_(0)
|
||||
{
|
||||
}
|
||||
~NowSingleton() = default;
|
||||
|
||||
mozilla::StaticMutex& lock_; // To protected last_seen_ and rollover_.
|
||||
TimeDelta rollover_; // Accumulation of time lost due to rollover.
|
||||
DWORD last_seen_; // The last timeGetTime value we saw, to detect rollover.
|
||||
|
||||
|
@ -25,7 +25,6 @@
|
||||
|
||||
#include "base/command_line.h"
|
||||
#include "base/eintr_wrapper.h"
|
||||
#include "base/lock.h"
|
||||
#include "base/logging.h"
|
||||
#include "base/process_util.h"
|
||||
#include "base/string_util.h"
|
||||
@ -33,6 +32,7 @@
|
||||
#include "chrome/common/file_descriptor_set_posix.h"
|
||||
#include "chrome/common/ipc_message_utils.h"
|
||||
#include "mozilla/ipc/ProtocolUtils.h"
|
||||
#include "mozilla/StaticMutex.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
|
||||
#ifdef FUZZING
|
||||
@ -108,7 +108,7 @@ class PipeMap {
|
||||
public:
|
||||
// Lookup a given channel id. Return -1 if not found.
|
||||
int Lookup(const std::string& channel_id) {
|
||||
AutoLock locked(lock_);
|
||||
mozilla::StaticMutexAutoLock locked(lock_);
|
||||
|
||||
ChannelToFDMap::const_iterator i = map_.find(channel_id);
|
||||
if (i == map_.end()) return -1;
|
||||
@ -118,7 +118,7 @@ class PipeMap {
|
||||
// Remove the mapping for the given channel id. No error is signaled if the
|
||||
// channel_id doesn't exist
|
||||
void Remove(const std::string& channel_id) {
|
||||
AutoLock locked(lock_);
|
||||
mozilla::StaticMutexAutoLock locked(lock_);
|
||||
|
||||
ChannelToFDMap::iterator i = map_.find(channel_id);
|
||||
if (i != map_.end()) map_.erase(i);
|
||||
@ -127,7 +127,7 @@ class PipeMap {
|
||||
// Insert a mapping from @channel_id to @fd. It's a fatal error to insert a
|
||||
// mapping if one already exists for the given channel_id
|
||||
void Insert(const std::string& channel_id, int fd) {
|
||||
AutoLock locked(lock_);
|
||||
mozilla::StaticMutexAutoLock locked(lock_);
|
||||
DCHECK(fd != -1);
|
||||
|
||||
ChannelToFDMap::const_iterator i = map_.find(channel_id);
|
||||
@ -137,15 +137,25 @@ class PipeMap {
|
||||
}
|
||||
|
||||
static PipeMap& instance() {
|
||||
static PipeMap map;
|
||||
// This setup is a little gross: the `map` instance lives until libxul is
|
||||
// unloaded, but leak checking runs prior to that, and would see a Mutex
|
||||
// instance contained in PipeMap as still live. Said instance would be
|
||||
// reported as a leak...but it's not, really. To avoid that, we need to
|
||||
// use StaticMutex (which is not leak-checked), but StaticMutex can't be
|
||||
// a member variable. So we have to have this separate variable and pass
|
||||
// it into the PipeMap constructor.
|
||||
static mozilla::StaticMutex mutex;
|
||||
static PipeMap map(mutex);
|
||||
return map;
|
||||
}
|
||||
|
||||
private:
|
||||
PipeMap() = default;
|
||||
explicit PipeMap(mozilla::StaticMutex& aMutex)
|
||||
: lock_(aMutex)
|
||||
{}
|
||||
~PipeMap() = default;
|
||||
|
||||
Lock lock_;
|
||||
mozilla::StaticMutex& lock_;
|
||||
typedef std::map<std::string, int> ChannelToFDMap;
|
||||
ChannelToFDMap map_;
|
||||
};
|
||||
|
@ -8,7 +8,6 @@
|
||||
|
||||
#include "MainThreadUtils.h"
|
||||
#include "mozilla/Assertions.h"
|
||||
#include "mozilla/BasePrincipal.h"
|
||||
#include "mozilla/ContentPrincipal.h"
|
||||
#include "mozilla/NullPrincipal.h"
|
||||
#include "mozilla/ipc/PBackgroundSharedTypes.h"
|
||||
@ -24,6 +23,8 @@
|
||||
#include "nsTArray.h"
|
||||
#include "mozilla/nsRedirectHistoryEntry.h"
|
||||
#include "URIUtils.h"
|
||||
#include "mozilla/dom/nsCSPUtils.h"
|
||||
#include "mozilla/dom/nsCSPContext.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace net {
|
||||
@ -103,6 +104,29 @@ already_AddRefed<nsIPrincipal> PrincipalInfoToPrincipal(
|
||||
MOZ_CRASH("Origin must be available when deserialized");
|
||||
}
|
||||
|
||||
if (info.securityPolicies().Length() > 0) {
|
||||
nsCOMPtr<nsIContentSecurityPolicy> csp =
|
||||
do_CreateInstance(NS_CSPCONTEXT_CONTRACTID, &rv);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
rv = csp->SetRequestContext(nullptr, principal);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
for (auto policy : info.securityPolicies()) {
|
||||
rv = csp->AppendPolicy(policy.policy(), policy.reportOnlyFlag(),
|
||||
policy.deliveredViaMetaTagFlag());
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
principal->SetCsp(csp);
|
||||
}
|
||||
|
||||
return principal.forget();
|
||||
}
|
||||
|
||||
@ -140,6 +164,34 @@ already_AddRefed<nsIPrincipal> PrincipalInfoToPrincipal(
|
||||
MOZ_CRASH("Should never get here!");
|
||||
}
|
||||
|
||||
nsresult PopulateContentSecurityPolicies(
|
||||
nsIContentSecurityPolicy* aCSP,
|
||||
nsTArray<ContentSecurityPolicy>& aPolicies) {
|
||||
MOZ_ASSERT(aCSP);
|
||||
MOZ_ASSERT(aPolicies.IsEmpty());
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
uint32_t count = 0;
|
||||
nsresult rv = aCSP->GetPolicyCount(&count);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < count; ++i) {
|
||||
const nsCSPPolicy* policy = aCSP->GetPolicy(i);
|
||||
MOZ_ASSERT(policy);
|
||||
|
||||
nsAutoString policyString;
|
||||
policy->toString(policyString);
|
||||
|
||||
aPolicies.AppendElement(
|
||||
ContentSecurityPolicy(policyString, policy->getReportOnlyFlag(),
|
||||
policy->getDeliveredViaMetaTagFlag()));
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult PrincipalToPrincipalInfo(nsIPrincipal* aPrincipal,
|
||||
PrincipalInfo* aPrincipalInfo) {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
@ -231,8 +283,20 @@ nsresult PrincipalToPrincipalInfo(nsIPrincipal* aPrincipal,
|
||||
return rv;
|
||||
}
|
||||
|
||||
*aPrincipalInfo = ContentPrincipalInfo(aPrincipal->OriginAttributesRef(),
|
||||
originNoSuffix, spec);
|
||||
nsCOMPtr<nsIContentSecurityPolicy> csp;
|
||||
rv = aPrincipal->GetCsp(getter_AddRefs(csp));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsTArray<ContentSecurityPolicy> policies;
|
||||
if (csp) {
|
||||
PopulateContentSecurityPolicies(csp, policies);
|
||||
}
|
||||
|
||||
*aPrincipalInfo =
|
||||
ContentPrincipalInfo(aPrincipal->OriginAttributesRef(), originNoSuffix,
|
||||
spec, std::move(policies));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -55,6 +55,7 @@ class RedirectHistoryEntryInfo;
|
||||
|
||||
namespace ipc {
|
||||
|
||||
class ContentSecurityPolicy;
|
||||
class PrincipalInfo;
|
||||
|
||||
/**
|
||||
@ -65,6 +66,14 @@ class PrincipalInfo;
|
||||
already_AddRefed<nsIPrincipal> PrincipalInfoToPrincipal(
|
||||
const PrincipalInfo& aPrincipalInfo, nsresult* aOptionalResult = nullptr);
|
||||
|
||||
/**
|
||||
* Populate an array of ContentSecurityPolicy objects from a CSP object.
|
||||
*
|
||||
* MUST be called on the main thread only.
|
||||
*/
|
||||
nsresult PopulateContentSecurityPolicies(
|
||||
nsIContentSecurityPolicy* aCSP, nsTArray<ContentSecurityPolicy>& aPolicies);
|
||||
|
||||
/**
|
||||
* Convert an nsIPrincipal to a PrincipalInfo.
|
||||
*
|
||||
|
@ -8,6 +8,13 @@ using struct mozilla::void_t from "ipc/IPCMessageUtils.h";
|
||||
namespace mozilla {
|
||||
namespace ipc {
|
||||
|
||||
struct ContentSecurityPolicy
|
||||
{
|
||||
nsString policy;
|
||||
bool reportOnlyFlag;
|
||||
bool deliveredViaMetaTagFlag;
|
||||
};
|
||||
|
||||
struct ContentPrincipalInfo
|
||||
{
|
||||
OriginAttributes attrs;
|
||||
@ -22,6 +29,8 @@ struct ContentPrincipalInfo
|
||||
nsCString originNoSuffix;
|
||||
|
||||
nsCString spec;
|
||||
|
||||
ContentSecurityPolicy[] securityPolicies;
|
||||
};
|
||||
|
||||
struct SystemPrincipalInfo
|
||||
|
@ -106,11 +106,9 @@ struct JSPropertySpec {
|
||||
|
||||
private:
|
||||
void checkAccessorsAreNative() const {
|
||||
MOZ_ASSERT(accessors.getter.native.op);
|
||||
// We may not have a setter at all. So all we can assert here, for the
|
||||
// native case is that if we have a jitinfo for the setter then we have
|
||||
// a setter op too. This is good enough to make sure we don't have a
|
||||
// SelfHostedWrapper for the setter.
|
||||
// We may have a getter or a setter or both. And whichever ones we have
|
||||
// should not have a SelfHostedWrapper for the accessor.
|
||||
MOZ_ASSERT_IF(accessors.getter.native.info, accessors.getter.native.op);
|
||||
MOZ_ASSERT_IF(accessors.setter.native.info, accessors.setter.native.op);
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Generated by make_intl_data.py. DO NOT EDIT.
|
||||
// tzdata version = 2018g
|
||||
// tzdata version = 2018i
|
||||
|
||||
#ifndef builtin_intl_TimeZoneDataGenerated_h
|
||||
#define builtin_intl_TimeZoneDataGenerated_h
|
||||
|
@ -256,6 +256,33 @@ void LIRGenerator::visitWasmUnsignedToFloat32(MWasmUnsignedToFloat32* ins) {
|
||||
define(lir, ins);
|
||||
}
|
||||
|
||||
// If the base is a constant, and it is zero or its offset is zero, then
|
||||
// code generation will fold the values into the access. Allocate the
|
||||
// pointer to a register only if that can't happen.
|
||||
|
||||
static bool OptimizableConstantAccess(MDefinition* base,
|
||||
const wasm::MemoryAccessDesc& access) {
|
||||
MOZ_ASSERT(base->isConstant());
|
||||
MOZ_ASSERT(base->type() == MIRType::Int32);
|
||||
|
||||
if (!(base->toConstant()->isInt32(0) || access.offset() == 0)) {
|
||||
return false;
|
||||
}
|
||||
if (access.type() == Scalar::Int64) {
|
||||
// For int64 accesses on 32-bit systems we will need to add another offset
|
||||
// of 4 to access the high part of the value; make sure this does not
|
||||
// overflow the value.
|
||||
int32_t v;
|
||||
if (base->toConstant()->isInt32(0)) {
|
||||
v = access.offset();
|
||||
} else {
|
||||
v = base->toConstant()->toInt32();
|
||||
}
|
||||
return v <= int32_t(INT32_MAX - INT64HIGH_OFFSET);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void LIRGenerator::visitWasmLoad(MWasmLoad* ins) {
|
||||
MDefinition* base = ins->base();
|
||||
MOZ_ASSERT(base->type() == MIRType::Int32);
|
||||
@ -273,13 +300,8 @@ void LIRGenerator::visitWasmLoad(MWasmLoad* ins) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If the base is a constant, and it is zero or its offset is zero, then
|
||||
// code generation will fold the values into the access. Allocate the
|
||||
// pointer to a register only if that can't happen.
|
||||
|
||||
LAllocation baseAlloc;
|
||||
if (!base->isConstant() ||
|
||||
!(base->toConstant()->isInt32(0) || ins->access().offset() == 0)) {
|
||||
if (!base->isConstant() || !OptimizableConstantAccess(base, ins->access())) {
|
||||
baseAlloc = ins->type() == MIRType::Int64 ? useRegister(base)
|
||||
: useRegisterAtStart(base);
|
||||
}
|
||||
@ -326,13 +348,8 @@ void LIRGenerator::visitWasmStore(MWasmStore* ins) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If the base is a constant, and it is zero or its offset is zero, then
|
||||
// code generation will fold the values into the access. Allocate the
|
||||
// pointer to a register only if that can't happen.
|
||||
|
||||
LAllocation baseAlloc;
|
||||
if (!base->isConstant() ||
|
||||
!(base->toConstant()->isInt32(0) || ins->access().offset() == 0)) {
|
||||
if (!base->isConstant() || !OptimizableConstantAccess(base, ins->access())) {
|
||||
baseAlloc = useRegisterAtStart(base);
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
// |reftest| skip-if(!this.hasOwnProperty("Intl"))
|
||||
|
||||
// Generated by make_intl_data.py. DO NOT EDIT.
|
||||
// tzdata version = 2018g
|
||||
// tzdata version = 2018i
|
||||
|
||||
const tzMapper = [
|
||||
x => x,
|
||||
|
@ -1,7 +1,7 @@
|
||||
// |reftest| skip-if(!this.hasOwnProperty("Intl"))
|
||||
|
||||
// Generated by make_intl_data.py. DO NOT EDIT.
|
||||
// tzdata version = 2018g
|
||||
// tzdata version = 2018i
|
||||
|
||||
const tzMapper = [
|
||||
x => x,
|
||||
|
@ -1,7 +1,7 @@
|
||||
// |reftest| skip-if(!this.hasOwnProperty("Intl"))
|
||||
|
||||
// Generated by make_intl_data.py. DO NOT EDIT.
|
||||
// tzdata version = 2018g
|
||||
// tzdata version = 2018i
|
||||
|
||||
const tzMapper = [
|
||||
x => x,
|
||||
|
@ -1,7 +1,7 @@
|
||||
// |reftest| skip-if(!this.hasOwnProperty("Intl"))
|
||||
|
||||
// Generated by make_intl_data.py. DO NOT EDIT.
|
||||
// tzdata version = 2018g
|
||||
// tzdata version = 2018i
|
||||
|
||||
const tzMapper = [
|
||||
x => x,
|
||||
|
@ -164,8 +164,8 @@ struct JSContext : public JS::RootingContext,
|
||||
return thing->compartment() == compartment();
|
||||
}
|
||||
|
||||
void* onOutOfMemory(js::AllocFunction allocFunc, size_t nbytes,
|
||||
arena_id_t arena, void* reallocPtr = nullptr) {
|
||||
void* onOutOfMemory(js::AllocFunction allocFunc, arena_id_t arena,
|
||||
size_t nbytes, void* reallocPtr = nullptr) {
|
||||
if (helperThread()) {
|
||||
addPendingOutOfMemory();
|
||||
return nullptr;
|
||||
|
@ -162,7 +162,10 @@ static SystemClass ClassifySystem() {
|
||||
}
|
||||
|
||||
// Code sizes in machine code bytes per bytecode byte, again empirical except
|
||||
// where marked as "Guess".
|
||||
// where marked.
|
||||
//
|
||||
// The Ion estimate for ARM64 is the measured Baseline value scaled by a
|
||||
// plausible factor for optimized code.
|
||||
|
||||
static const double x64Tox86Inflation = 1.25;
|
||||
|
||||
@ -170,15 +173,14 @@ static const double x64IonBytesPerBytecode = 2.45;
|
||||
static const double x86IonBytesPerBytecode =
|
||||
x64IonBytesPerBytecode * x64Tox86Inflation;
|
||||
static const double arm32IonBytesPerBytecode = 3.3;
|
||||
static const double arm64IonBytesPerBytecode = 3.0; // Guess
|
||||
static const double arm64IonBytesPerBytecode = 3.0 / 1.4; // Estimate
|
||||
|
||||
static const double x64BaselineBytesPerBytecode = x64IonBytesPerBytecode * 1.43;
|
||||
static const double x86BaselineBytesPerBytecode =
|
||||
x64BaselineBytesPerBytecode * x64Tox86Inflation;
|
||||
static const double arm32BaselineBytesPerBytecode =
|
||||
arm32IonBytesPerBytecode * 1.39;
|
||||
static const double arm64BaselineBytesPerBytecode =
|
||||
arm64IonBytesPerBytecode * 1.39; // Guess
|
||||
static const double arm64BaselineBytesPerBytecode = 3.0;
|
||||
|
||||
static double OptimizedBytesPerBytecode(SystemClass cls) {
|
||||
switch (cls) {
|
||||
@ -239,25 +241,32 @@ static const double tierCutoffMs = 250;
|
||||
// Compilation rate values are empirical except when noted, the reference
|
||||
// systems are:
|
||||
//
|
||||
// Late-2013 MacBook Pro (2.6GHz quad hyperthreaded Haswell)
|
||||
// Late-2015 Nexus 5X (1.4GHz quad Cortex-A53 + 1.8GHz dual Cortex-A57)
|
||||
// Late-2013 MacBook Pro (2.6GHz 4 x hyperthreaded Haswell, Mac OS X)
|
||||
// Late-2015 Nexus 5X (1.4GHz 4 x Cortex-A53 + 1.8GHz 2 x Cortex-A57, Android)
|
||||
// Ca-2016 SoftIron Overdrive 1000 (1.7GHz 4 x Cortex-A57, Fedora)
|
||||
//
|
||||
// The rates are always per core.
|
||||
//
|
||||
// The estimate for ARM64 is the Baseline compilation rate on the SoftIron
|
||||
// (because we have no Ion yet), divided by 5 to estimate Ion compile rate and
|
||||
// then divided by 2 to make it more reasonable for consumer ARM64 systems.
|
||||
|
||||
static const double x64BytecodesPerMs = 2100;
|
||||
static const double x86BytecodesPerMs = 1500;
|
||||
static const double arm32BytecodesPerMs = 450;
|
||||
static const double arm64BytecodesPerMs = 650; // Guess
|
||||
static const double x64IonBytecodesPerMs = 2100;
|
||||
static const double x86IonBytecodesPerMs = 1500;
|
||||
static const double arm32IonBytecodesPerMs = 450;
|
||||
static const double arm64IonBytecodesPerMs = 750; // Estimate
|
||||
|
||||
// Tiering cutoff values: if code section sizes are below these values (when
|
||||
// divided by the effective number of cores) we do not tier, because we guess
|
||||
// that parallel Ion compilation will be fast enough.
|
||||
|
||||
static const double x64DesktopTierCutoff = x64BytecodesPerMs * tierCutoffMs;
|
||||
static const double x86DesktopTierCutoff = x86BytecodesPerMs * tierCutoffMs;
|
||||
static const double x64DesktopTierCutoff = x64IonBytecodesPerMs * tierCutoffMs;
|
||||
static const double x86DesktopTierCutoff = x86IonBytecodesPerMs * tierCutoffMs;
|
||||
static const double x86MobileTierCutoff = x86DesktopTierCutoff / 2; // Guess
|
||||
static const double arm32MobileTierCutoff = arm32BytecodesPerMs * tierCutoffMs;
|
||||
static const double arm64MobileTierCutoff = arm64BytecodesPerMs * tierCutoffMs;
|
||||
static const double arm32MobileTierCutoff = arm32IonBytecodesPerMs * tierCutoffMs;
|
||||
static const double arm64MobileTierCutoff = arm64IonBytecodesPerMs * tierCutoffMs;
|
||||
|
||||
static double CodesizeCutoff(SystemClass cls, uint32_t codeSize) {
|
||||
static double CodesizeCutoff(SystemClass cls) {
|
||||
switch (cls) {
|
||||
case SystemClass::DesktopX86:
|
||||
case SystemClass::DesktopUnknown32:
|
||||
@ -335,7 +344,7 @@ static bool TieringBeneficial(uint32_t codeSize) {
|
||||
// Ion compilation on available cores must take long enough to be worth the
|
||||
// bother.
|
||||
|
||||
double cutoffSize = CodesizeCutoff(cls, codeSize);
|
||||
double cutoffSize = CodesizeCutoff(cls);
|
||||
double effectiveCores = EffectiveCores(cls, cores);
|
||||
|
||||
if ((codeSize / effectiveCores) < cutoffSize) {
|
||||
|
@ -7814,7 +7814,10 @@ static bool IsAcceptableCaretPosition(const gfxSkipCharsIterator& aIter,
|
||||
(NS_IS_LOW_SURROGATE(ch) && offs > 0 &&
|
||||
NS_IS_HIGH_SURROGATE(frag->CharAt(offs - 1))) ||
|
||||
(!aTextRun->IsLigatureGroupStart(index) &&
|
||||
unicode::GetEmojiPresentation(ch) == unicode::EmojiDefault)) {
|
||||
(unicode::GetEmojiPresentation(ch) == unicode::EmojiDefault ||
|
||||
(unicode::GetEmojiPresentation(ch) == unicode::TextDefault &&
|
||||
offs + 1 < frag->GetLength() &&
|
||||
frag->CharAt(offs + 1) == gfxFontUtils::kUnicodeVS16)))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -111,6 +111,10 @@ class FakeSocketTransportProvider : public nsISocketTransport {
|
||||
MOZ_ASSERT(false);
|
||||
return NS_OK;
|
||||
}
|
||||
NS_IMETHOD SetLinger(bool aPolarity, int16_t aTimeout) override {
|
||||
MOZ_ASSERT(false);
|
||||
return NS_OK;
|
||||
}
|
||||
NS_IMETHOD SetReuseAddrPort(bool reuseAddrPort) override {
|
||||
MOZ_ASSERT(false);
|
||||
return NS_OK;
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include <vector>
|
||||
|
||||
#include "CSFLog.h"
|
||||
#include "base/histogram.h"
|
||||
#include "timecard.h"
|
||||
|
||||
#include "jsapi.h"
|
||||
|
@ -42,7 +42,9 @@ DeviceInfoIos::DeviceInfoIos() {
|
||||
this->Init();
|
||||
}
|
||||
|
||||
DeviceInfoIos::~DeviceInfoIos() {}
|
||||
DeviceInfoIos::~DeviceInfoIos() {
|
||||
[_captureInfo registerOwner:nil];
|
||||
}
|
||||
|
||||
int32_t DeviceInfoIos::Init() {
|
||||
_captureInfo = [[DeviceInfoIosObjC alloc] init];
|
||||
|
@ -1784,6 +1784,20 @@ VARCACHE_PREF(
|
||||
bool, true
|
||||
)
|
||||
|
||||
// Block 3rd party fingerprinting resources.
|
||||
VARCACHE_PREF(
|
||||
"privacy.trackingprotection.fingerprinting.enabled",
|
||||
privacy_trackingprotection_fingerprinting_enabled,
|
||||
bool, true
|
||||
)
|
||||
|
||||
// Block 3rd party cryptomining resources.
|
||||
VARCACHE_PREF(
|
||||
"privacy.trackingprotection.cryptomining.enabled",
|
||||
privacy_trackingprotection_cryptomining_enabled,
|
||||
bool, true
|
||||
)
|
||||
|
||||
// Lower the priority of network loads for resources on the tracking protection
|
||||
// list. Note that this requires the
|
||||
// privacy.trackingprotection.annotate_channels pref to be on in order to have
|
||||
|
@ -127,8 +127,9 @@ inline void mozilla::detail::MutexImpl::mutexLock() {
|
||||
"mozilla::detail::MutexImpl::mutexLock: pthread_mutex_lock failed");
|
||||
}
|
||||
|
||||
#ifdef XP_DARWIN
|
||||
inline bool mozilla::detail::MutexImpl::mutexTryLock() {
|
||||
bool mozilla::detail::MutexImpl::tryLock() { return mutexTryLock(); }
|
||||
|
||||
bool mozilla::detail::MutexImpl::mutexTryLock() {
|
||||
int result = pthread_mutex_trylock(&platformData()->ptMutex);
|
||||
if (result == 0) {
|
||||
return true;
|
||||
@ -142,7 +143,6 @@ inline bool mozilla::detail::MutexImpl::mutexTryLock() {
|
||||
result,
|
||||
"mozilla::detail::MutexImpl::mutexTryLock: pthread_mutex_trylock failed");
|
||||
}
|
||||
#endif
|
||||
|
||||
void mozilla::detail::MutexImpl::lock() {
|
||||
#ifndef XP_DARWIN
|
||||
|
@ -22,6 +22,12 @@ void mozilla::detail::MutexImpl::lock() {
|
||||
AcquireSRWLockExclusive(&platformData()->lock);
|
||||
}
|
||||
|
||||
bool mozilla::detail::MutexImpl::tryLock() { return mutexTryLock(); }
|
||||
|
||||
bool mozilla::detail::MutexImpl::mutexTryLock() {
|
||||
return !!TryAcquireSRWLockExclusive(&platformData()->lock);
|
||||
}
|
||||
|
||||
void mozilla::detail::MutexImpl::unlock() {
|
||||
ReleaseSRWLockExclusive(&platformData()->lock);
|
||||
}
|
||||
|
@ -33,6 +33,9 @@ class MutexImpl {
|
||||
protected:
|
||||
MFBT_API void lock();
|
||||
MFBT_API void unlock();
|
||||
// We have a separate, forwarding API so internal uses don't have to go
|
||||
// through the PLT.
|
||||
MFBT_API bool tryLock();
|
||||
|
||||
private:
|
||||
MutexImpl(const MutexImpl&) = delete;
|
||||
@ -42,9 +45,7 @@ class MutexImpl {
|
||||
bool operator==(const MutexImpl& rhs) = delete;
|
||||
|
||||
void mutexLock();
|
||||
#ifdef XP_DARWIN
|
||||
bool mutexTryLock();
|
||||
#endif
|
||||
|
||||
PlatformData* platformData();
|
||||
|
||||
|
@ -124,6 +124,13 @@ interface nsISocketTransport : nsITransport
|
||||
unsigned long getTimeout(in unsigned long aType);
|
||||
void setTimeout(in unsigned long aType, in unsigned long aValue);
|
||||
|
||||
/**
|
||||
* Sets the SO_LINGER option with the specified values for the l_onoff and
|
||||
* l_linger parameters. This applies PR_SockOpt_Linger before PR_Close and
|
||||
* can be used with a timeout of zero to send an RST packet when closing.
|
||||
*/
|
||||
void setLinger(in boolean aPolarity, in short aTimeout);
|
||||
|
||||
/**
|
||||
* True to set addr and port reuse socket options.
|
||||
*/
|
||||
|
@ -717,6 +717,8 @@ nsSocketTransport::nsSocketTransport()
|
||||
mSocketTransportService(gSocketTransportService),
|
||||
mInput(this),
|
||||
mOutput(this),
|
||||
mLingerPolarity(false),
|
||||
mLingerTimeout(0),
|
||||
mQoSBits(0x00),
|
||||
mKeepaliveEnabled(false),
|
||||
mKeepaliveIdleTimeS(-1),
|
||||
@ -1978,7 +1980,8 @@ class ThunkPRClose : public Runnable {
|
||||
PRFileDesc *mFD;
|
||||
};
|
||||
|
||||
void STS_PRCloseOnSocketTransport(PRFileDesc *fd) {
|
||||
void STS_PRCloseOnSocketTransport(PRFileDesc *fd, bool lingerPolarity,
|
||||
int16_t lingerTimeout) {
|
||||
if (gSocketTransportService) {
|
||||
// Can't PR_Close() a socket off STS thread. Thunk it to STS to die
|
||||
gSocketTransportService->Dispatch(new ThunkPRClose(fd), NS_DISPATCH_NORMAL);
|
||||
@ -1999,13 +2002,22 @@ void nsSocketTransport::ReleaseFD_Locked(PRFileDesc *fd) {
|
||||
gSocketTransportService->MaxTimeForPrClosePref())) {
|
||||
// If shutdown last to long, let the socket leak and do not close it.
|
||||
SOCKET_LOG(("Intentional leak"));
|
||||
} else if (OnSocketThread()) {
|
||||
SOCKET_LOG(("nsSocketTransport: calling PR_Close [this=%p]\n", this));
|
||||
CloseSocket(
|
||||
mFD, mSocketTransportService->IsTelemetryEnabledAndNotSleepPhase());
|
||||
} else {
|
||||
// Can't PR_Close() a socket off STS thread. Thunk it to STS to die
|
||||
STS_PRCloseOnSocketTransport(mFD);
|
||||
if (mLingerPolarity || mLingerTimeout) {
|
||||
PRSocketOptionData socket_linger;
|
||||
socket_linger.option = PR_SockOpt_Linger;
|
||||
socket_linger.value.linger.polarity = mLingerPolarity;
|
||||
socket_linger.value.linger.linger = mLingerTimeout;
|
||||
PR_SetSocketOption(mFD, &socket_linger);
|
||||
}
|
||||
if (OnSocketThread()) {
|
||||
SOCKET_LOG(("nsSocketTransport: calling PR_Close [this=%p]\n", this));
|
||||
CloseSocket(
|
||||
mFD, mSocketTransportService->IsTelemetryEnabledAndNotSleepPhase());
|
||||
} else {
|
||||
// Can't PR_Close() a socket off STS thread. Thunk it to STS to die
|
||||
STS_PRCloseOnSocketTransport(mFD, mLingerPolarity, mLingerTimeout);
|
||||
}
|
||||
}
|
||||
mFD = nullptr;
|
||||
}
|
||||
@ -2756,6 +2768,16 @@ nsSocketTransport::SetReuseAddrPort(bool reuseAddrPort) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSocketTransport::SetLinger(bool aPolarity, int16_t aTimeout) {
|
||||
MutexAutoLock lock(mLock);
|
||||
|
||||
mLingerPolarity = aPolarity;
|
||||
mLingerTimeout = aTimeout;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSocketTransport::SetQoSBits(uint8_t aQoSBits) {
|
||||
// Don't do any checking here of bits. Why? Because as of RFC-4594
|
||||
|
@ -398,6 +398,10 @@ class nsSocketTransport final : public nsASocketHandler,
|
||||
// socket timeouts are not protected by any lock.
|
||||
uint16_t mTimeouts[2];
|
||||
|
||||
// linger options to use when closing
|
||||
bool mLingerPolarity;
|
||||
int16_t mLingerTimeout;
|
||||
|
||||
// QoS setting for socket
|
||||
uint8_t mQoSBits;
|
||||
|
||||
|
@ -596,7 +596,6 @@ size_t CacheIOThread::SizeOfExcludingThis(
|
||||
MonitorAutoLock lock(const_cast<CacheIOThread*>(this)->mMonitor);
|
||||
|
||||
size_t n = 0;
|
||||
n += mallocSizeOf(mThread);
|
||||
for (const auto& event : mEventQueue) {
|
||||
n += event.ShallowSizeOfExcludingThis(mallocSizeOf);
|
||||
// Events referenced by the queues are arbitrary objects we cannot be sure
|
||||
|
@ -1889,6 +1889,11 @@ SocketTransportShim::SetReuseAddrPort(bool aReuseAddrPort) {
|
||||
return mWrapped->SetReuseAddrPort(aReuseAddrPort);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
SocketTransportShim::SetLinger(bool aPolarity, int16_t aTimeout) {
|
||||
return mWrapped->SetLinger(aPolarity, aTimeout);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
SocketTransportShim::GetQoSBits(uint8_t *aQoSBits) {
|
||||
return mWrapped->GetQoSBits(aQoSBits);
|
||||
|
@ -398,7 +398,7 @@ nsHttpServer.prototype =
|
||||
|
||||
try {
|
||||
var conn = new Connection(input, output, this, socket.port, trans.port,
|
||||
connectionNumber);
|
||||
connectionNumber, trans);
|
||||
var reader = new RequestReader(conn);
|
||||
|
||||
// XXX add request timeout functionality here!
|
||||
@ -1067,7 +1067,8 @@ ServerIdentity.prototype =
|
||||
* @param number : uint
|
||||
* a serial number used to uniquely identify this connection
|
||||
*/
|
||||
function Connection(input, output, server, port, outgoingPort, number) {
|
||||
function Connection(input, output, server, port, outgoingPort, number,
|
||||
transport) {
|
||||
dumpn("*** opening new connection " + number + " on port " + outgoingPort);
|
||||
|
||||
/** Stream of incoming data. */
|
||||
@ -1088,6 +1089,9 @@ function Connection(input, output, server, port, outgoingPort, number) {
|
||||
/** The serial number of this connection. */
|
||||
this.number = number;
|
||||
|
||||
/** Reference to the underlying transport. */
|
||||
this.transport = transport;
|
||||
|
||||
/**
|
||||
* The request for which a response is being generated, null if the
|
||||
* incoming request has not been fully received or if it had errors.
|
||||
@ -3559,10 +3563,19 @@ Response.prototype =
|
||||
* @param e : Error
|
||||
* the exception which precipitated this abort, or null if no such exception
|
||||
* was generated
|
||||
* @param truncateConnection : Boolean
|
||||
* ensures that we truncate the connection using an RST packet, so the
|
||||
* client testing code is aware that an error occurred, otherwise it may
|
||||
* consider the response as valid.
|
||||
*/
|
||||
abort(e) {
|
||||
abort(e, truncateConnection = false) {
|
||||
dumpn("*** abort(<" + e + ">)");
|
||||
|
||||
if (truncateConnection) {
|
||||
dumpn("*** truncate connection");
|
||||
this._connection.transport.setLinger(true, 0);
|
||||
}
|
||||
|
||||
// This response will be ended by the processor if one was created.
|
||||
var copier = this._asyncCopier;
|
||||
if (copier) {
|
||||
|
@ -87,13 +87,14 @@ LazyLogModule UrlClassifierCommon::sLog("nsChannelClassifier");
|
||||
pwin->NotifyContentBlockingState(aBlockedReason, aChannel, true, uri);
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
UrlClassifierCommon::ShouldEnableTrackingProtectionOrAnnotation(
|
||||
/* static */ bool UrlClassifierCommon::ShouldEnableClassifier(
|
||||
nsIChannel* aChannel,
|
||||
AntiTrackingCommon::ContentBlockingAllowListPurpose aBlockingPurpose) {
|
||||
MOZ_ASSERT(aChannel);
|
||||
MOZ_ASSERT(aBlockingPurpose == AntiTrackingCommon::eTrackingProtection ||
|
||||
aBlockingPurpose == AntiTrackingCommon::eTrackingAnnotations);
|
||||
aBlockingPurpose == AntiTrackingCommon::eTrackingAnnotations ||
|
||||
aBlockingPurpose == AntiTrackingCommon::eFingerprinting ||
|
||||
aBlockingPurpose == AntiTrackingCommon::eCryptomining);
|
||||
|
||||
nsCOMPtr<nsIHttpChannelInternal> channel = do_QueryInterface(aChannel);
|
||||
if (!channel) {
|
||||
|
@ -33,7 +33,7 @@ class UrlClassifierCommon final {
|
||||
static void NotifyChannelBlocked(nsIChannel* aChannel,
|
||||
unsigned aBlockedReason);
|
||||
|
||||
static bool ShouldEnableTrackingProtectionOrAnnotation(
|
||||
static bool ShouldEnableClassifier(
|
||||
nsIChannel* aChannel,
|
||||
AntiTrackingCommon::ContentBlockingAllowListPurpose aBlockingPurpose);
|
||||
|
||||
|
175
netwerk/url-classifier/UrlClassifierFeatureCryptomining.cpp
Normal file
175
netwerk/url-classifier/UrlClassifierFeatureCryptomining.cpp
Normal file
@ -0,0 +1,175 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "UrlClassifierFeatureCryptomining.h"
|
||||
|
||||
#include "mozilla/AntiTrackingCommon.h"
|
||||
#include "mozilla/net/UrlClassifierCommon.h"
|
||||
#include "mozilla/StaticPrefs.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsNetUtil.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace net {
|
||||
|
||||
namespace {
|
||||
|
||||
#define CRYPTOMINING_FEATURE_NAME "cryptomining"
|
||||
|
||||
#define URLCLASSIFIER_CRYPTOMINING_BLACKLIST \
|
||||
"urlclassifier.features.cryptomining.blacklistTables"
|
||||
#define URLCLASSIFIER_CRYPTOMINING_BLACKLIST_TEST_ENTRIES \
|
||||
"urlclassifier.features.cryptomining.blacklistHosts"
|
||||
#define URLCLASSIFIER_CRYPTOMINING_WHITELIST \
|
||||
"urlclassifier.features.cryptomining.whitelistTables"
|
||||
#define URLCLASSIFIER_CRYPTOMINING_WHITELIST_TEST_ENTRIES \
|
||||
"urlclassifier.features.cryptomining.whitelistHosts"
|
||||
#define TABLE_CRYPTOMINING_BLACKLIST_PREF "cryptomining-blacklist-pref"
|
||||
#define TABLE_CRYPTOMINING_WHITELIST_PREF "cryptomining-whitelist-pref"
|
||||
|
||||
StaticRefPtr<UrlClassifierFeatureCryptomining> gFeatureCryptomining;
|
||||
|
||||
} // namespace
|
||||
|
||||
UrlClassifierFeatureCryptomining::UrlClassifierFeatureCryptomining()
|
||||
: UrlClassifierFeatureBase(
|
||||
NS_LITERAL_CSTRING(CRYPTOMINING_FEATURE_NAME),
|
||||
NS_LITERAL_CSTRING(URLCLASSIFIER_CRYPTOMINING_BLACKLIST),
|
||||
NS_LITERAL_CSTRING(URLCLASSIFIER_CRYPTOMINING_WHITELIST),
|
||||
NS_LITERAL_CSTRING(URLCLASSIFIER_CRYPTOMINING_BLACKLIST_TEST_ENTRIES),
|
||||
NS_LITERAL_CSTRING(URLCLASSIFIER_CRYPTOMINING_WHITELIST_TEST_ENTRIES),
|
||||
NS_LITERAL_CSTRING(TABLE_CRYPTOMINING_BLACKLIST_PREF),
|
||||
NS_LITERAL_CSTRING(TABLE_CRYPTOMINING_WHITELIST_PREF),
|
||||
EmptyCString()) {}
|
||||
|
||||
/* static */ const char* UrlClassifierFeatureCryptomining::Name() {
|
||||
return CRYPTOMINING_FEATURE_NAME;
|
||||
}
|
||||
|
||||
/* static */ void UrlClassifierFeatureCryptomining::MaybeInitialize() {
|
||||
UC_LOG(("UrlClassifierFeatureCryptomining: MaybeInitialize"));
|
||||
|
||||
if (!gFeatureCryptomining) {
|
||||
gFeatureCryptomining = new UrlClassifierFeatureCryptomining();
|
||||
gFeatureCryptomining->InitializePreferences();
|
||||
}
|
||||
}
|
||||
|
||||
/* static */ void UrlClassifierFeatureCryptomining::MaybeShutdown() {
|
||||
UC_LOG(("UrlClassifierFeatureCryptomining: MaybeShutdown"));
|
||||
|
||||
if (gFeatureCryptomining) {
|
||||
gFeatureCryptomining->ShutdownPreferences();
|
||||
gFeatureCryptomining = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
/* static */ already_AddRefed<UrlClassifierFeatureCryptomining>
|
||||
UrlClassifierFeatureCryptomining::MaybeCreate(nsIChannel* aChannel) {
|
||||
MOZ_ASSERT(aChannel);
|
||||
|
||||
UC_LOG(("UrlClassifierFeatureCryptomining: MaybeCreate for channel %p",
|
||||
aChannel));
|
||||
|
||||
if (!StaticPrefs::privacy_trackingprotection_cryptomining_enabled()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIURI> chanURI;
|
||||
nsresult rv = aChannel->GetURI(getter_AddRefs(chanURI));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool isThirdParty =
|
||||
nsContentUtils::IsThirdPartyWindowOrChannel(nullptr, aChannel, chanURI);
|
||||
if (!isThirdParty) {
|
||||
if (UC_LOG_ENABLED()) {
|
||||
nsCString spec = chanURI->GetSpecOrDefault();
|
||||
spec.Truncate(
|
||||
std::min(spec.Length(), UrlClassifierCommon::sMaxSpecLength));
|
||||
UC_LOG(
|
||||
("UrlClassifierFeatureCryptomining: Skipping cryptomining checks "
|
||||
"for first party or top-level load channel[%p] "
|
||||
"with uri %s",
|
||||
aChannel, spec.get()));
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!UrlClassifierCommon::ShouldEnableClassifier(
|
||||
aChannel, AntiTrackingCommon::eCryptomining)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
MaybeInitialize();
|
||||
MOZ_ASSERT(gFeatureCryptomining);
|
||||
|
||||
RefPtr<UrlClassifierFeatureCryptomining> self = gFeatureCryptomining;
|
||||
return self.forget();
|
||||
}
|
||||
|
||||
/* static */ already_AddRefed<nsIUrlClassifierFeature>
|
||||
UrlClassifierFeatureCryptomining::GetIfNameMatches(const nsACString& aName) {
|
||||
if (!aName.EqualsLiteral(CRYPTOMINING_FEATURE_NAME)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
MaybeInitialize();
|
||||
MOZ_ASSERT(gFeatureCryptomining);
|
||||
|
||||
RefPtr<UrlClassifierFeatureCryptomining> self = gFeatureCryptomining;
|
||||
return self.forget();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
UrlClassifierFeatureCryptomining::ProcessChannel(nsIChannel* aChannel,
|
||||
const nsACString& aList,
|
||||
bool* aShouldContinue) {
|
||||
NS_ENSURE_ARG_POINTER(aChannel);
|
||||
NS_ENSURE_ARG_POINTER(aShouldContinue);
|
||||
|
||||
// This is a blocking feature.
|
||||
*aShouldContinue = false;
|
||||
|
||||
UrlClassifierCommon::SetBlockedContent(aChannel, NS_ERROR_TRACKING_URI, aList,
|
||||
EmptyCString(), EmptyCString());
|
||||
|
||||
UC_LOG(
|
||||
("UrlClassifierFeatureCryptomining::ProcessChannel, cancelling "
|
||||
"channel[%p]",
|
||||
aChannel));
|
||||
nsCOMPtr<nsIHttpChannelInternal> httpChannel = do_QueryInterface(aChannel);
|
||||
|
||||
// FIXME: the way we cancel the channel depends on what the UI wants to show.
|
||||
// This needs to change, at some point.
|
||||
if (httpChannel) {
|
||||
Unused << httpChannel->CancelForTrackingProtection();
|
||||
} else {
|
||||
Unused << aChannel->Cancel(NS_ERROR_TRACKING_URI);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
UrlClassifierFeatureCryptomining::GetURIByListType(
|
||||
nsIChannel* aChannel, nsIUrlClassifierFeature::listType aListType,
|
||||
nsIURI** aURI) {
|
||||
NS_ENSURE_ARG_POINTER(aChannel);
|
||||
NS_ENSURE_ARG_POINTER(aURI);
|
||||
|
||||
if (aListType == nsIUrlClassifierFeature::blacklist) {
|
||||
return aChannel->GetURI(aURI);
|
||||
}
|
||||
|
||||
MOZ_ASSERT(aListType == nsIUrlClassifierFeature::whitelist);
|
||||
return UrlClassifierCommon::CreatePairwiseWhiteListURI(aChannel, aURI);
|
||||
}
|
||||
|
||||
} // namespace net
|
||||
} // namespace mozilla
|
45
netwerk/url-classifier/UrlClassifierFeatureCryptomining.h
Normal file
45
netwerk/url-classifier/UrlClassifierFeatureCryptomining.h
Normal file
@ -0,0 +1,45 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef mozilla_net_UrlClassifierFeatureCryptomining_h
|
||||
#define mozilla_net_UrlClassifierFeatureCryptomining_h
|
||||
|
||||
#include "UrlClassifierFeatureBase.h"
|
||||
|
||||
class nsIChannel;
|
||||
|
||||
namespace mozilla {
|
||||
namespace net {
|
||||
|
||||
class UrlClassifierFeatureCryptomining final : public UrlClassifierFeatureBase {
|
||||
public:
|
||||
static const char* Name();
|
||||
|
||||
static void MaybeShutdown();
|
||||
|
||||
static already_AddRefed<UrlClassifierFeatureCryptomining> MaybeCreate(
|
||||
nsIChannel* aChannel);
|
||||
|
||||
static already_AddRefed<nsIUrlClassifierFeature> GetIfNameMatches(
|
||||
const nsACString& aName);
|
||||
|
||||
NS_IMETHOD ProcessChannel(nsIChannel* aChannel, const nsACString& aList,
|
||||
bool* aShouldContinue) override;
|
||||
|
||||
NS_IMETHOD GetURIByListType(nsIChannel* aChannel,
|
||||
nsIUrlClassifierFeature::listType aListType,
|
||||
nsIURI** aURI) override;
|
||||
|
||||
private:
|
||||
UrlClassifierFeatureCryptomining();
|
||||
|
||||
static void MaybeInitialize();
|
||||
};
|
||||
|
||||
} // namespace net
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_net_UrlClassifierFeatureCryptomining_h
|
@ -7,6 +7,8 @@
|
||||
#include "mozilla/net/UrlClassifierFeatureFactory.h"
|
||||
|
||||
// List of Features
|
||||
#include "UrlClassifierFeatureCryptomining.h"
|
||||
#include "UrlClassifierFeatureFingerprinting.h"
|
||||
#include "UrlClassifierFeatureFlash.h"
|
||||
#include "UrlClassifierFeatureLoginReputation.h"
|
||||
#include "UrlClassifierFeatureTrackingProtection.h"
|
||||
@ -24,6 +26,8 @@ namespace net {
|
||||
return;
|
||||
}
|
||||
|
||||
UrlClassifierFeatureCryptomining::MaybeShutdown();
|
||||
UrlClassifierFeatureFingerprinting::MaybeShutdown();
|
||||
UrlClassifierFeatureFlash::MaybeShutdown();
|
||||
UrlClassifierFeatureLoginReputation::MaybeShutdown();
|
||||
UrlClassifierFeatureTrackingAnnotation::MaybeShutdown();
|
||||
@ -43,6 +47,18 @@ namespace net {
|
||||
// feature order, and this could produce different results with a different
|
||||
// feature ordering.
|
||||
|
||||
// Cryptomining
|
||||
feature = UrlClassifierFeatureCryptomining::MaybeCreate(aChannel);
|
||||
if (feature) {
|
||||
aFeatures.AppendElement(feature);
|
||||
}
|
||||
|
||||
// Fingerprinting
|
||||
feature = UrlClassifierFeatureFingerprinting::MaybeCreate(aChannel);
|
||||
if (feature) {
|
||||
aFeatures.AppendElement(feature);
|
||||
}
|
||||
|
||||
// Tracking Protection
|
||||
feature = UrlClassifierFeatureTrackingProtection::MaybeCreate(aChannel);
|
||||
if (feature) {
|
||||
@ -75,6 +91,18 @@ UrlClassifierFeatureFactory::GetFeatureByName(const nsACString& aName) {
|
||||
|
||||
nsCOMPtr<nsIUrlClassifierFeature> feature;
|
||||
|
||||
// Cryptomining
|
||||
feature = UrlClassifierFeatureCryptomining::GetIfNameMatches(aName);
|
||||
if (feature) {
|
||||
return feature.forget();
|
||||
}
|
||||
|
||||
// Fingerprinting
|
||||
feature = UrlClassifierFeatureFingerprinting::GetIfNameMatches(aName);
|
||||
if (feature) {
|
||||
return feature.forget();
|
||||
}
|
||||
|
||||
// Tracking Protection
|
||||
feature = UrlClassifierFeatureTrackingProtection::GetIfNameMatches(aName);
|
||||
if (feature) {
|
||||
@ -102,6 +130,49 @@ UrlClassifierFeatureFactory::GetFeatureByName(const nsACString& aName) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/* static */ void UrlClassifierFeatureFactory::GetFeatureNames(
|
||||
nsTArray<nsCString>& aArray) {
|
||||
if (!XRE_IsParentProcess()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Cryptomining
|
||||
nsAutoCString name;
|
||||
name.Assign(UrlClassifierFeatureCryptomining::Name());
|
||||
if (!name.IsEmpty()) {
|
||||
aArray.AppendElement(name);
|
||||
}
|
||||
|
||||
// Fingerprinting
|
||||
name.Assign(UrlClassifierFeatureFingerprinting::Name());
|
||||
if (!name.IsEmpty()) {
|
||||
aArray.AppendElement(name);
|
||||
}
|
||||
|
||||
// Tracking Protection
|
||||
name.Assign(UrlClassifierFeatureTrackingProtection::Name());
|
||||
if (!name.IsEmpty()) {
|
||||
aArray.AppendElement(name);
|
||||
}
|
||||
|
||||
// Tracking Annotation
|
||||
name.Assign(UrlClassifierFeatureTrackingAnnotation::Name());
|
||||
if (!name.IsEmpty()) {
|
||||
aArray.AppendElement(name);
|
||||
}
|
||||
|
||||
// Login reputation
|
||||
name.Assign(UrlClassifierFeatureLoginReputation::Name());
|
||||
if (!name.IsEmpty()) {
|
||||
aArray.AppendElement(name);
|
||||
}
|
||||
|
||||
// Flash features
|
||||
nsTArray<nsCString> features;
|
||||
UrlClassifierFeatureFlash::GetFeatureNames(features);
|
||||
aArray.AppendElements(features);
|
||||
}
|
||||
|
||||
/* static */ already_AddRefed<nsIUrlClassifierFeature>
|
||||
UrlClassifierFeatureFactory::CreateFeatureWithTables(
|
||||
const nsACString& aName, const nsTArray<nsCString>& aBlacklistTables,
|
||||
|
@ -29,6 +29,8 @@ class UrlClassifierFeatureFactory final {
|
||||
static already_AddRefed<nsIUrlClassifierFeature> GetFeatureByName(
|
||||
const nsACString& aFeatureName);
|
||||
|
||||
static void GetFeatureNames(nsTArray<nsCString>& aArray);
|
||||
|
||||
static already_AddRefed<nsIUrlClassifierFeature> CreateFeatureWithTables(
|
||||
const nsACString& aName, const nsTArray<nsCString>& aBlacklistTables,
|
||||
const nsTArray<nsCString>& aWhitelistTables);
|
||||
|
177
netwerk/url-classifier/UrlClassifierFeatureFingerprinting.cpp
Normal file
177
netwerk/url-classifier/UrlClassifierFeatureFingerprinting.cpp
Normal file
@ -0,0 +1,177 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "UrlClassifierFeatureFingerprinting.h"
|
||||
|
||||
#include "mozilla/AntiTrackingCommon.h"
|
||||
#include "mozilla/net/UrlClassifierCommon.h"
|
||||
#include "mozilla/StaticPrefs.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsNetUtil.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace net {
|
||||
|
||||
namespace {
|
||||
|
||||
#define FINGERPRINTING_FEATURE_NAME "fingerprinting"
|
||||
|
||||
#define URLCLASSIFIER_FINGERPRINTING_BLACKLIST \
|
||||
"urlclassifier.features.fingerprinting.blacklistTables"
|
||||
#define URLCLASSIFIER_FINGERPRINTING_BLACKLIST_TEST_ENTRIES \
|
||||
"urlclassifier.features.fingerprinting.blacklistHosts"
|
||||
#define URLCLASSIFIER_FINGERPRINTING_WHITELIST \
|
||||
"urlclassifier.features.fingerprinting.whitelistTables"
|
||||
#define URLCLASSIFIER_FINGERPRINTING_WHITELIST_TEST_ENTRIES \
|
||||
"urlclassifier.features.fingerprinting.whitelistHosts"
|
||||
#define TABLE_FINGERPRINTING_BLACKLIST_PREF "fingerprinting-blacklist-pref"
|
||||
#define TABLE_FINGERPRINTING_WHITELIST_PREF "fingerprinting-whitelist-pref"
|
||||
|
||||
StaticRefPtr<UrlClassifierFeatureFingerprinting> gFeatureFingerprinting;
|
||||
|
||||
} // namespace
|
||||
|
||||
UrlClassifierFeatureFingerprinting::UrlClassifierFeatureFingerprinting()
|
||||
: UrlClassifierFeatureBase(
|
||||
NS_LITERAL_CSTRING(FINGERPRINTING_FEATURE_NAME),
|
||||
NS_LITERAL_CSTRING(URLCLASSIFIER_FINGERPRINTING_BLACKLIST),
|
||||
NS_LITERAL_CSTRING(URLCLASSIFIER_FINGERPRINTING_WHITELIST),
|
||||
NS_LITERAL_CSTRING(
|
||||
URLCLASSIFIER_FINGERPRINTING_BLACKLIST_TEST_ENTRIES),
|
||||
NS_LITERAL_CSTRING(
|
||||
URLCLASSIFIER_FINGERPRINTING_WHITELIST_TEST_ENTRIES),
|
||||
NS_LITERAL_CSTRING(TABLE_FINGERPRINTING_BLACKLIST_PREF),
|
||||
NS_LITERAL_CSTRING(TABLE_FINGERPRINTING_WHITELIST_PREF),
|
||||
EmptyCString()) {}
|
||||
|
||||
/* static */ const char* UrlClassifierFeatureFingerprinting::Name() {
|
||||
return FINGERPRINTING_FEATURE_NAME;
|
||||
}
|
||||
|
||||
/* static */ void UrlClassifierFeatureFingerprinting::MaybeInitialize() {
|
||||
UC_LOG(("UrlClassifierFeatureFingerprinting: MaybeInitialize"));
|
||||
|
||||
if (!gFeatureFingerprinting) {
|
||||
gFeatureFingerprinting = new UrlClassifierFeatureFingerprinting();
|
||||
gFeatureFingerprinting->InitializePreferences();
|
||||
}
|
||||
}
|
||||
|
||||
/* static */ void UrlClassifierFeatureFingerprinting::MaybeShutdown() {
|
||||
UC_LOG(("UrlClassifierFeatureFingerprinting: MaybeShutdown"));
|
||||
|
||||
if (gFeatureFingerprinting) {
|
||||
gFeatureFingerprinting->ShutdownPreferences();
|
||||
gFeatureFingerprinting = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
/* static */ already_AddRefed<UrlClassifierFeatureFingerprinting>
|
||||
UrlClassifierFeatureFingerprinting::MaybeCreate(nsIChannel* aChannel) {
|
||||
MOZ_ASSERT(aChannel);
|
||||
|
||||
UC_LOG(("UrlClassifierFeatureFingerprinting: MaybeCreate for channel %p",
|
||||
aChannel));
|
||||
|
||||
if (!StaticPrefs::privacy_trackingprotection_fingerprinting_enabled()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIURI> chanURI;
|
||||
nsresult rv = aChannel->GetURI(getter_AddRefs(chanURI));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool isThirdParty =
|
||||
nsContentUtils::IsThirdPartyWindowOrChannel(nullptr, aChannel, chanURI);
|
||||
if (!isThirdParty) {
|
||||
if (UC_LOG_ENABLED()) {
|
||||
nsCString spec = chanURI->GetSpecOrDefault();
|
||||
spec.Truncate(
|
||||
std::min(spec.Length(), UrlClassifierCommon::sMaxSpecLength));
|
||||
UC_LOG(
|
||||
("UrlClassifierFeatureFingerprinting: Skipping fingerprinting checks "
|
||||
"for first party or top-level load channel[%p] "
|
||||
"with uri %s",
|
||||
aChannel, spec.get()));
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!UrlClassifierCommon::ShouldEnableClassifier(
|
||||
aChannel, AntiTrackingCommon::eFingerprinting)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
MaybeInitialize();
|
||||
MOZ_ASSERT(gFeatureFingerprinting);
|
||||
|
||||
RefPtr<UrlClassifierFeatureFingerprinting> self = gFeatureFingerprinting;
|
||||
return self.forget();
|
||||
}
|
||||
|
||||
/* static */ already_AddRefed<nsIUrlClassifierFeature>
|
||||
UrlClassifierFeatureFingerprinting::GetIfNameMatches(const nsACString& aName) {
|
||||
if (!aName.EqualsLiteral(FINGERPRINTING_FEATURE_NAME)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
MaybeInitialize();
|
||||
MOZ_ASSERT(gFeatureFingerprinting);
|
||||
|
||||
RefPtr<UrlClassifierFeatureFingerprinting> self = gFeatureFingerprinting;
|
||||
return self.forget();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
UrlClassifierFeatureFingerprinting::ProcessChannel(nsIChannel* aChannel,
|
||||
const nsACString& aList,
|
||||
bool* aShouldContinue) {
|
||||
NS_ENSURE_ARG_POINTER(aChannel);
|
||||
NS_ENSURE_ARG_POINTER(aShouldContinue);
|
||||
|
||||
// This is a blocking feature.
|
||||
*aShouldContinue = false;
|
||||
|
||||
UrlClassifierCommon::SetBlockedContent(aChannel, NS_ERROR_TRACKING_URI, aList,
|
||||
EmptyCString(), EmptyCString());
|
||||
|
||||
UC_LOG(
|
||||
("UrlClassifierFeatureFingerprinting::ProcessChannel, cancelling "
|
||||
"channel[%p]",
|
||||
aChannel));
|
||||
nsCOMPtr<nsIHttpChannelInternal> httpChannel = do_QueryInterface(aChannel);
|
||||
|
||||
// FIXME: the way we cancel the channel depends on what the UI wants to show.
|
||||
// This needs to change, at some point.
|
||||
if (httpChannel) {
|
||||
Unused << httpChannel->CancelForTrackingProtection();
|
||||
} else {
|
||||
Unused << aChannel->Cancel(NS_ERROR_TRACKING_URI);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
UrlClassifierFeatureFingerprinting::GetURIByListType(
|
||||
nsIChannel* aChannel, nsIUrlClassifierFeature::listType aListType,
|
||||
nsIURI** aURI) {
|
||||
NS_ENSURE_ARG_POINTER(aChannel);
|
||||
NS_ENSURE_ARG_POINTER(aURI);
|
||||
|
||||
if (aListType == nsIUrlClassifierFeature::blacklist) {
|
||||
return aChannel->GetURI(aURI);
|
||||
}
|
||||
|
||||
MOZ_ASSERT(aListType == nsIUrlClassifierFeature::whitelist);
|
||||
return UrlClassifierCommon::CreatePairwiseWhiteListURI(aChannel, aURI);
|
||||
}
|
||||
|
||||
} // namespace net
|
||||
} // namespace mozilla
|
46
netwerk/url-classifier/UrlClassifierFeatureFingerprinting.h
Normal file
46
netwerk/url-classifier/UrlClassifierFeatureFingerprinting.h
Normal file
@ -0,0 +1,46 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef mozilla_net_UrlClassifierFeatureFingerprinting_h
|
||||
#define mozilla_net_UrlClassifierFeatureFingerprinting_h
|
||||
|
||||
#include "UrlClassifierFeatureBase.h"
|
||||
|
||||
class nsIChannel;
|
||||
|
||||
namespace mozilla {
|
||||
namespace net {
|
||||
|
||||
class UrlClassifierFeatureFingerprinting final
|
||||
: public UrlClassifierFeatureBase {
|
||||
public:
|
||||
static const char* Name();
|
||||
|
||||
static void MaybeShutdown();
|
||||
|
||||
static already_AddRefed<UrlClassifierFeatureFingerprinting> MaybeCreate(
|
||||
nsIChannel* aChannel);
|
||||
|
||||
static already_AddRefed<nsIUrlClassifierFeature> GetIfNameMatches(
|
||||
const nsACString& aName);
|
||||
|
||||
NS_IMETHOD ProcessChannel(nsIChannel* aChannel, const nsACString& aList,
|
||||
bool* aShouldContinue) override;
|
||||
|
||||
NS_IMETHOD GetURIByListType(nsIChannel* aChannel,
|
||||
nsIUrlClassifierFeature::listType aListType,
|
||||
nsIURI** aURI) override;
|
||||
|
||||
private:
|
||||
UrlClassifierFeatureFingerprinting();
|
||||
|
||||
static void MaybeInitialize();
|
||||
};
|
||||
|
||||
} // namespace net
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_net_UrlClassifierFeatureFingerprinting_h
|
@ -55,6 +55,15 @@ UrlClassifierFeatureFlash::UrlClassifierFeatureFlash(uint32_t aId)
|
||||
"nsIHttpChannel::FlashPluginLastValue is out-of-sync!");
|
||||
}
|
||||
|
||||
/* static */ void UrlClassifierFeatureFlash::GetFeatureNames(
|
||||
nsTArray<nsCString>& aArray) {
|
||||
uint32_t numFeatures =
|
||||
(sizeof(sFlashFeaturesMap) / sizeof(sFlashFeaturesMap[0]));
|
||||
for (uint32_t i = 0; i < numFeatures; ++i) {
|
||||
aArray.AppendElement(nsDependentCString(sFlashFeaturesMap[i].mName));
|
||||
}
|
||||
}
|
||||
|
||||
/* static */ void UrlClassifierFeatureFlash::MaybeInitialize() {
|
||||
MOZ_ASSERT(XRE_IsParentProcess());
|
||||
|
||||
|
@ -14,6 +14,8 @@ namespace net {
|
||||
|
||||
class UrlClassifierFeatureFlash final : public UrlClassifierFeatureBase {
|
||||
public:
|
||||
static void GetFeatureNames(nsTArray<nsCString>& aNames);
|
||||
|
||||
static void MaybeShutdown();
|
||||
|
||||
static void MaybeCreate(
|
||||
|
@ -33,6 +33,12 @@ UrlClassifierFeatureLoginReputation::UrlClassifierFeatureLoginReputation()
|
||||
EmptyCString()) // skip host pref
|
||||
{}
|
||||
|
||||
/* static */ const char* UrlClassifierFeatureLoginReputation::Name() {
|
||||
return StaticPrefs::browser_safebrowsing_passwords_enabled()
|
||||
? LOGIN_REPUTATION_FEATURE_NAME
|
||||
: "";
|
||||
}
|
||||
|
||||
/* static */ void UrlClassifierFeatureLoginReputation::MaybeShutdown() {
|
||||
UC_LOG(("UrlClassifierFeatureLoginReputation: MaybeShutdown"));
|
||||
|
||||
@ -76,36 +82,6 @@ UrlClassifierFeatureLoginReputation::ProcessChannel(nsIChannel* aChannel,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
UrlClassifierFeatureLoginReputation::GetTables(
|
||||
nsIUrlClassifierFeature::listType aListType, nsTArray<nsCString>& aTables) {
|
||||
MOZ_ASSERT(aListType == nsIUrlClassifierFeature::whitelist,
|
||||
"UrlClassifierFeatureLoginReputation is meant to be used just to "
|
||||
"whitelist URLs");
|
||||
return UrlClassifierFeatureBase::GetTables(aListType, aTables);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
UrlClassifierFeatureLoginReputation::HasTable(
|
||||
const nsACString& aTable, nsIUrlClassifierFeature::listType aListType,
|
||||
bool* aResult) {
|
||||
MOZ_ASSERT(aListType == nsIUrlClassifierFeature::whitelist,
|
||||
"UrlClassifierFeatureLoginReputation is meant to be used just to "
|
||||
"whitelist URLs");
|
||||
return UrlClassifierFeatureBase::HasTable(aTable, aListType, aResult);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
UrlClassifierFeatureLoginReputation::HasHostInPreferences(
|
||||
const nsACString& aHost, nsIUrlClassifierFeature::listType aListType,
|
||||
nsACString& aPrefTableName, bool* aResult) {
|
||||
MOZ_ASSERT(aListType == nsIUrlClassifierFeature::whitelist,
|
||||
"UrlClassifierFeatureLoginReputation is meant to be used just to "
|
||||
"whitelist URLs");
|
||||
return UrlClassifierFeatureBase::HasHostInPreferences(
|
||||
aHost, aListType, aPrefTableName, aResult);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
UrlClassifierFeatureLoginReputation::GetURIByListType(
|
||||
nsIChannel* aChannel, nsIUrlClassifierFeature::listType aListType,
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user