author | Jan Varga <jan.varga@gmail.com> |
Sun, 10 Feb 2019 10:20:12 +0100 | |
changeset 462930 | 84806a3e88b92aadc6570f59dbe12139f77d92c6 |
parent 462929 | 16bf9fd6ae4b46f20bd40e6aaa793729e0b271d5 |
child 462931 | 29f06968e80af7188d89768f48fe02daec45f5b4 |
push id | 35662 |
push user | aiakab@mozilla.com |
push date | Thu, 07 Mar 2019 21:58:58 +0000 |
treeherder | mozilla-central@af29567ecdba [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | asuth |
bugs | 1526615 |
milestone | 67.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/dom/localstorage/LocalStorageCommon.cpp +++ b/dom/localstorage/LocalStorageCommon.cpp @@ -1,19 +1,23 @@ /* -*- 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 "LocalStorageCommon.h" +#include "mozilla/net/MozURL.h" + namespace mozilla { namespace dom { +using namespace mozilla::net; + namespace { Atomic<int32_t> gNextGenLocalStorageEnabled(-1); } // namespace const char16_t* kLocalStorageType = u"localStorage"; @@ -29,10 +33,92 @@ bool NextGenLocalStorageEnabled() { } bool CachedNextGenLocalStorageEnabled() { MOZ_ASSERT(gNextGenLocalStorageEnabled != -1); return !!gNextGenLocalStorageEnabled; } +nsresult GenerateOriginKey2(const PrincipalInfo& aPrincipalInfo, + nsACString& aOriginAttrSuffix, + nsACString& aOriginKey) { + OriginAttributes attrs; + nsCString spec; + + switch (aPrincipalInfo.type()) { + case PrincipalInfo::TNullPrincipalInfo: { + const NullPrincipalInfo& info = aPrincipalInfo.get_NullPrincipalInfo(); + + attrs = info.attrs(); + spec = info.spec(); + + break; + } + + case PrincipalInfo::TContentPrincipalInfo: { + const ContentPrincipalInfo& info = + aPrincipalInfo.get_ContentPrincipalInfo(); + + attrs = info.attrs(); + spec = info.spec(); + + break; + } + + default: { + spec.SetIsVoid(true); + + break; + } + } + + if (spec.IsVoid()) { + return NS_ERROR_UNEXPECTED; + } + + attrs.CreateSuffix(aOriginAttrSuffix); + + RefPtr<MozURL> specURL; + nsresult rv = MozURL::Init(getter_AddRefs(specURL), spec); + if (NS_WARN_IF(NS_FAILED(rv))) { + return rv; + } + + nsCString host(specURL->Host()); + uint32_t length = host.Length(); + if (length > 0 && host.CharAt(0) == '[' && host.CharAt(length - 1) == ']') { + host = Substring(host, 1, length - 2); + } + + nsCString domainOrigin(host); + + if (domainOrigin.IsEmpty()) { + // For the file:/// protocol use the exact directory as domain. + if (specURL->Scheme().EqualsLiteral("file")) { + domainOrigin.Assign(specURL->Directory()); + } + } + + // Append reversed domain + nsAutoCString reverseDomain; + rv = CreateReversedDomain(domainOrigin, reverseDomain); + if (NS_FAILED(rv)) { + return rv; + } + + aOriginKey.Append(reverseDomain); + + // Append scheme + aOriginKey.Append(':'); + aOriginKey.Append(specURL->Scheme()); + + // Append port if any + int32_t port = specURL->RealPort(); + if (port != -1) { + aOriginKey.Append(nsPrintfCString(":%d", port)); + } + + return NS_OK; +} + } // namespace dom } // namespace mozilla
--- a/dom/localstorage/LocalStorageCommon.h +++ b/dom/localstorage/LocalStorageCommon.h @@ -176,17 +176,27 @@ * ~~~~~~~~~~~~~~~~~~~~~ * * The local storage manager exposes some of the features that need to be * available only in the chrome code or tests. The manager is represented by * the "LocalStorageManager2" class that implements the "nsIDOMStorageManager" * interface. */ +#include "mozilla/Attributes.h" +#include "nsString.h" + namespace mozilla { + +namespace ipc { + +class PrincipalInfo; + +} // namespace ipc + namespace dom { extern const char16_t* kLocalStorageType; /** * Convenience data-structure to make it easier to track whether a value has * changed and what its previous value was for notification purposes. Instances * are created on the stack by LSObject and passed to LSDatabase which in turn @@ -215,12 +225,16 @@ class MOZ_STACK_CLASS LSNotifyInfo { */ bool NextGenLocalStorageEnabled(); /** * Cached any-thread version of NextGenLocalStorageEnabled(). */ bool CachedNextGenLocalStorageEnabled(); +nsresult GenerateOriginKey2(const mozilla::ipc::PrincipalInfo& aPrincipalInfo, + nsACString& aOriginAttrSuffix, + nsACString& aOriginKey); + } // namespace dom } // namespace mozilla #endif // mozilla_dom_localstorage_LocalStorageCommon_h
--- a/dom/localstorage/moz.build +++ b/dom/localstorage/moz.build @@ -7,16 +7,18 @@ XPCSHELL_TESTS_MANIFESTS += [ 'test/unit/xpcshell.ini' ] TEST_HARNESS_FILES.xpcshell.dom.localstorage.test.unit += [ 'test/unit/databaseShadowing-shared.js', ] +TEST_DIRS += ['test/gtest'] + XPIDL_SOURCES += [ 'nsILocalStorageManager.idl', ] XPIDL_MODULE = 'dom_localstorage' EXPORTS.mozilla.dom.localstorage += [ 'ActorsParent.h',
new file mode 100644 --- /dev/null +++ b/dom/localstorage/test/gtest/TestLocalStorage.cpp @@ -0,0 +1,113 @@ +/* -*- 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 "gtest/gtest.h" +#include "mozilla/NullPrincipal.h" +#include "mozilla/dom/LocalStorageCommon.h" +#include "mozilla/dom/StorageUtils.h" +#include "mozilla/ipc/BackgroundUtils.h" +#include "mozilla/ipc/PBackgroundSharedTypes.h" +#include "nsCOMPtr.h" +#include "nsContentUtils.h" +#include "nsIURI.h" +#include "nsNetUtil.h" + +using namespace mozilla; +using namespace mozilla::dom; +using namespace mozilla::dom::StorageUtils; +using namespace mozilla::ipc; + +namespace { + +struct OriginKeyTest { + const char* mSpec; + const char* mOriginKey; +}; + +already_AddRefed<nsIPrincipal> GetCodebasePrincipal(const char* aSpec) { + nsCOMPtr<nsIURI> uri; + nsresult rv = NS_NewURI(getter_AddRefs(uri), nsDependentCString(aSpec)); + if (NS_WARN_IF(NS_FAILED(rv))) { + return nullptr; + } + + OriginAttributes attrs; + + nsCOMPtr<nsIPrincipal> principal = + BasePrincipal::CreateCodebasePrincipal(uri, attrs); + + return principal.forget(); +} + +void CheckGeneratedOriginKey(nsIPrincipal* aPrincipal, const char* aOriginKey) { + nsCString originAttrSuffix; + nsCString originKey; + nsresult rv = GenerateOriginKey(aPrincipal, originAttrSuffix, originKey); + if (aOriginKey) { + ASSERT_EQ(rv, NS_OK) << "GenerateOriginKey should not fail"; + EXPECT_TRUE(originKey == nsDependentCString(aOriginKey)); + } else { + ASSERT_NE(rv, NS_OK) << "GenerateOriginKey should fail"; + } + + PrincipalInfo principalInfo; + rv = PrincipalToPrincipalInfo(aPrincipal, &principalInfo); + ASSERT_EQ(rv, NS_OK) << "PrincipalToPrincipalInfo should not fail"; + + originKey.Truncate(); + rv = GenerateOriginKey2(principalInfo, originAttrSuffix, originKey); + if (aOriginKey) { + ASSERT_EQ(rv, NS_OK) << "GenerateOriginKey2 should not fail"; + EXPECT_TRUE(originKey == nsDependentCString(aOriginKey)); + } else { + ASSERT_NE(rv, NS_OK) << "GenerateOriginKey2 should fail"; + } +} + +} // namespace + +TEST(LocalStorage, OriginKey) { + // Check the system principal. + nsCOMPtr<nsIScriptSecurityManager> secMan = + nsContentUtils::GetSecurityManager(); + ASSERT_TRUE(secMan) << "GetSecurityManager() should not fail"; + + nsCOMPtr<nsIPrincipal> principal; + secMan->GetSystemPrincipal(getter_AddRefs(principal)); + ASSERT_TRUE(principal) << "GetSystemPrincipal() should not fail"; + + CheckGeneratedOriginKey(principal, nullptr); + + // Check the null principal. + principal = NullPrincipal::CreateWithoutOriginAttributes(); + ASSERT_TRUE(principal) << "CreateWithoutOriginAttributes() should not fail"; + + CheckGeneratedOriginKey(principal, nullptr); + + // Check content principals. + static const OriginKeyTest tests[] = { + {"http://www.mozilla.org", "gro.allizom.www.:http:80"}, + {"https://www.mozilla.org", "gro.allizom.www.:https:443"}, + {"http://www.mozilla.org:32400", "gro.allizom.www.:http:32400"}, + {"file:///Users/Joe/Sites/", "/setiS/eoJ/sresU/.:file"}, + {"file:///Users/Joe/Sites/#foo", "/setiS/eoJ/sresU/.:file"}, + {"file:///Users/Joe/Sites/?foo", "/setiS/eoJ/sresU/.:file"}, + {"file:///Users/Joe/Sites", "/eoJ/sresU/.:file"}, + {"file:///Users/Joe/Sites#foo", "/eoJ/sresU/.:file"}, + {"file:///Users/Joe/Sites?foo", "/eoJ/sresU/.:file"}, + {"moz-extension://53711a8f-65ed-e742-9671-1f02e267c0bc/" + "_generated_background_page.html", + "cb0c762e20f1-1769-247e-de56-f8a11735.:moz-extension"}, + {"http://[::1]:8/test.html", "1::.:http:8"}, + }; + + for (const auto& test : tests) { + principal = GetCodebasePrincipal(test.mSpec); + ASSERT_TRUE(principal) << "GetCodebasePrincipal() should not fail"; + + CheckGeneratedOriginKey(principal, test.mOriginKey); + } +}
new file mode 100644 --- /dev/null +++ b/dom/localstorage/test/gtest/moz.build @@ -0,0 +1,17 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# 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/. + +UNIFIED_SOURCES = [ + 'TestLocalStorage.cpp', +] + +include('/ipc/chromium/chromium-config.mozbuild') + +FINAL_LIBRARY = 'xul-gtest' + +LOCAL_INCLUDES += [ + '/dom/localstorage', +]
--- a/dom/storage/StorageUtils.h +++ b/dom/storage/StorageUtils.h @@ -2,16 +2,18 @@ /* 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_dom_StorageUtils_h #define mozilla_dom_StorageUtils_h +#include "nsStringFwd.h" + class nsIPrincipal; namespace mozilla { namespace dom { namespace StorageUtils { nsresult GenerateOriginKey(nsIPrincipal* aPrincipal, nsACString& aOriginAttrSuffix,