Bug 1526615 - Part 2: Implement GenerateOriginKey2 which can be used on any thread; r=asuth

Differential Revision: https://phabricator.services.mozilla.com/D19283
This commit is contained in:
Jan Varga 2019-02-10 10:20:12 +01:00
Родитель aa63590c8e
Коммит 62cb092a89
6 изменённых файлов: 234 добавлений и 0 удалений

Просмотреть файл

@ -6,9 +6,13 @@
#include "LocalStorageCommon.h"
#include "mozilla/net/MozURL.h"
namespace mozilla {
namespace dom {
using namespace mozilla::net;
namespace {
Atomic<int32_t> gNextGenLocalStorageEnabled(-1);
@ -34,5 +38,87 @@ bool CachedNextGenLocalStorageEnabled() {
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

Просмотреть файл

@ -181,7 +181,17 @@
* interface.
*/
#include "mozilla/Attributes.h"
#include "nsString.h"
namespace mozilla {
namespace ipc {
class PrincipalInfo;
} // namespace ipc
namespace dom {
extern const char16_t* kLocalStorageType;
@ -220,6 +230,10 @@ bool NextGenLocalStorageEnabled();
*/
bool CachedNextGenLocalStorageEnabled();
nsresult GenerateOriginKey2(const mozilla::ipc::PrincipalInfo& aPrincipalInfo,
nsACString& aOriginAttrSuffix,
nsACString& aOriginKey);
} // namespace dom
} // namespace mozilla

Просмотреть файл

@ -12,6 +12,8 @@ TEST_HARNESS_FILES.xpcshell.dom.localstorage.test.unit += [
'test/unit/databaseShadowing-shared.js',
]
TEST_DIRS += ['test/gtest']
XPIDL_SOURCES += [
'nsILocalStorageManager.idl',
]

Просмотреть файл

@ -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);
}
}

Просмотреть файл

@ -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',
]

Просмотреть файл

@ -7,6 +7,8 @@
#ifndef mozilla_dom_StorageUtils_h
#define mozilla_dom_StorageUtils_h
#include "nsStringFwd.h"
class nsIPrincipal;
namespace mozilla {