зеркало из https://github.com/mozilla/gecko-dev.git
Merge inbound to central, a=merge
MozReview-Commit-ID: EQ7w1Gld1K2
This commit is contained in:
Коммит
b31e9e6a39
|
@ -18,10 +18,6 @@
|
|||
#include "mozilla/AppUnits.h"
|
||||
#include "mozilla/gfx/2D.h"
|
||||
|
||||
#if defined(MOZ_WIDGET_GTK)
|
||||
#include "gfxPlatformGtk.h" // xxx - for UseFcFontList
|
||||
#endif
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::a11y;
|
||||
|
||||
|
@ -652,28 +648,14 @@ TextAttrsMgr::FontWeightTextAttr::
|
|||
if (font->IsSyntheticBold())
|
||||
return 700;
|
||||
|
||||
bool useFontEntryWeight = true;
|
||||
|
||||
// Under Linux, when gfxPangoFontGroup code is used,
|
||||
// font->GetStyle()->weight will give the absolute weight requested of the
|
||||
// font face. The gfxPangoFontGroup code uses the gfxFontEntry constructor
|
||||
// which doesn't initialize the weight field.
|
||||
#if defined(MOZ_WIDGET_GTK)
|
||||
useFontEntryWeight = gfxPlatformGtk::UseFcFontList();
|
||||
#endif
|
||||
|
||||
if (useFontEntryWeight) {
|
||||
// On Windows, font->GetStyle()->weight will give the same weight as
|
||||
// fontEntry->Weight(), the weight of the first font in the font group,
|
||||
// which may not be the weight of the font face used to render the
|
||||
// characters. On Mac, font->GetStyle()->weight will just give the same
|
||||
// number as getComputedStyle(). fontEntry->Weight() will give the weight
|
||||
// of the font face used.
|
||||
gfxFontEntry *fontEntry = font->GetFontEntry();
|
||||
return fontEntry->Weight();
|
||||
} else {
|
||||
return font->GetStyle()->weight;
|
||||
}
|
||||
// On Windows, font->GetStyle()->weight will give the same weight as
|
||||
// fontEntry->Weight(), the weight of the first font in the font group,
|
||||
// which may not be the weight of the font face used to render the
|
||||
// characters. On Mac, font->GetStyle()->weight will just give the same
|
||||
// number as getComputedStyle(). fontEntry->Weight() will give the weight
|
||||
// of the font face used.
|
||||
gfxFontEntry *fontEntry = font->GetFontEntry();
|
||||
return fontEntry->Weight();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -218,7 +218,8 @@ function onIndexedDBUsageCallback(request) {
|
|||
throw new Error("Callback received for bad URI: " + uri);
|
||||
}
|
||||
|
||||
if (request.usage) {
|
||||
let usage = request.result.usage;
|
||||
if (usage) {
|
||||
if (!("DownloadUtils" in window)) {
|
||||
Components.utils.import("resource://gre/modules/DownloadUtils.jsm");
|
||||
}
|
||||
|
@ -228,7 +229,7 @@ function onIndexedDBUsageCallback(request) {
|
|||
|
||||
status.value =
|
||||
gBundle.getFormattedString("indexedDBUsage",
|
||||
DownloadUtils.convertByteUnits(request.usage));
|
||||
DownloadUtils.convertByteUnits(usage));
|
||||
status.removeAttribute("hidden");
|
||||
button.removeAttribute("hidden");
|
||||
}
|
||||
|
|
|
@ -68,9 +68,6 @@
|
|||
Components.classes["@mozilla.org/autocomplete/search;1?name=unifiedcomplete"]
|
||||
.getService(Components.interfaces.mozIPlacesAutoComplete);
|
||||
</field>
|
||||
<field name="AppConstants" readonly="true">
|
||||
(Components.utils.import("resource://gre/modules/AppConstants.jsm", {})).AppConstants;
|
||||
</field>
|
||||
<field name="mTabBox" readonly="true">
|
||||
document.getAnonymousElementByAttribute(this, "anonid", "tabbox");
|
||||
</field>
|
||||
|
@ -108,7 +105,7 @@
|
|||
new Map();
|
||||
</field>
|
||||
<field name="arrowKeysShouldWrap" readonly="true">
|
||||
this.AppConstants.platform == "macosx";
|
||||
AppConstants == "macosx";
|
||||
</field>
|
||||
|
||||
<field name="_autoScrollPopup">
|
||||
|
@ -2655,7 +2652,10 @@
|
|||
|
||||
var browser = this.getBrowserForTab(aTab);
|
||||
|
||||
if (!aTab._pendingPermitUnload && !aAdoptedByTab && !aSkipPermitUnload) {
|
||||
if (!aTab._pendingPermitUnload &&
|
||||
!aSkipPermitUnload &&
|
||||
aTab.linkedPanel &&
|
||||
!aAdoptedByTab) {
|
||||
// We need to block while calling permitUnload() because it
|
||||
// processes the event queue and may lead to another removeTab()
|
||||
// call before permitUnload() returns.
|
||||
|
@ -2663,8 +2663,7 @@
|
|||
TelemetryStopwatch.start("FX_TAB_CLOSE_PERMIT_UNLOAD_TIME_MS", aTab);
|
||||
|
||||
aTab._pendingPermitUnload = true;
|
||||
let {permitUnload, timedOut} = aTab.linkedPanel ?
|
||||
browser.permitUnload() : {permitUnload: true, timedOut: false};
|
||||
let {permitUnload, timedOut} = browser.permitUnload();
|
||||
delete aTab._pendingPermitUnload;
|
||||
|
||||
TelemetryStopwatch.finish("FX_TAB_CLOSE_PERMIT_UNLOAD_TIME_MS", aTab);
|
||||
|
@ -3425,7 +3424,7 @@
|
|||
<parameter name="aTab"/>
|
||||
<body>
|
||||
<![CDATA[
|
||||
if (!this.AppConstants.E10S_TESTING_ONLY) {
|
||||
if (!AppConstants.E10S_TESTING_ONLY) {
|
||||
throw "This method is intended only for e10s testing!";
|
||||
}
|
||||
let url = aTab.linkedBrowser.currentURI.spec;
|
||||
|
@ -4037,7 +4036,7 @@
|
|||
dump("Assertion failure\n" + Error().stack);
|
||||
|
||||
// Don't break a user's browser if an assertion fails.
|
||||
if (this.tabbrowser.AppConstants.DEBUG) {
|
||||
if (AppConstants.DEBUG) {
|
||||
throw new Error("Assertion failure");
|
||||
}
|
||||
}
|
||||
|
@ -4813,7 +4812,7 @@
|
|||
}
|
||||
}
|
||||
|
||||
if (this.AppConstants.platform != "macosx") {
|
||||
if (AppConstants.platform != "macosx") {
|
||||
if (aEvent.ctrlKey && !aEvent.shiftKey && !aEvent.metaKey &&
|
||||
aEvent.keyCode == KeyEvent.DOM_VK_F4 &&
|
||||
!this.mCurrentTab.pinned) {
|
||||
|
@ -4835,7 +4834,7 @@
|
|||
if (aEvent.altKey)
|
||||
return;
|
||||
|
||||
if (this.AppConstants.platform == "macosx") {
|
||||
if (AppConstants.platform == "macosx") {
|
||||
if (!aEvent.metaKey)
|
||||
return;
|
||||
|
||||
|
@ -4898,7 +4897,7 @@
|
|||
}
|
||||
} else {
|
||||
label = tab.getAttribute("label");
|
||||
if (this.AppConstants.E10S_TESTING_ONLY &&
|
||||
if (AppConstants.E10S_TESTING_ONLY &&
|
||||
tab.linkedBrowser &&
|
||||
tab.linkedBrowser.isRemoteBrowser) {
|
||||
label += " - e10s";
|
||||
|
@ -5181,7 +5180,7 @@
|
|||
let els = Components.classes["@mozilla.org/eventlistenerservice;1"]
|
||||
.getService(nsIEventListenerService);
|
||||
els.addSystemEventListener(document, "keydown", this, false);
|
||||
if (this.AppConstants.platform == "macosx") {
|
||||
if (AppConstants.platform == "macosx") {
|
||||
els.addSystemEventListener(document, "keypress", this, false);
|
||||
}
|
||||
window.addEventListener("sizemodechange", this);
|
||||
|
@ -5298,7 +5297,7 @@
|
|||
let els = Components.classes["@mozilla.org/eventlistenerservice;1"]
|
||||
.getService(nsIEventListenerService);
|
||||
els.removeSystemEventListener(document, "keydown", this, false);
|
||||
if (this.AppConstants.platform == "macosx") {
|
||||
if (AppConstants.platform == "macosx") {
|
||||
els.removeSystemEventListener(document, "keypress", this, false);
|
||||
}
|
||||
window.removeEventListener("sizemodechange", this);
|
||||
|
@ -6658,7 +6657,7 @@
|
|||
return;
|
||||
|
||||
let wrongModifiers;
|
||||
if (this.tabbrowser.AppConstants.platform == "macosx") {
|
||||
if (AppConstants.platform == "macosx") {
|
||||
wrongModifiers = !event.metaKey;
|
||||
} else {
|
||||
wrongModifiers = !event.ctrlKey || event.metaKey;
|
||||
|
@ -6741,7 +6740,7 @@
|
|||
context.fillRect(0, 0, canvas.width, canvas.height);
|
||||
|
||||
let captureListener;
|
||||
let platform = this.tabbrowser.AppConstants.platform;
|
||||
let platform = AppConstants.platform;
|
||||
// On Windows and Mac we can update the drag image during a drag
|
||||
// using updateDragImage. On Linux, we can use a panel.
|
||||
if (platform == "win" || platform == "macosx") {
|
||||
|
@ -7026,7 +7025,7 @@
|
|||
window.focus();
|
||||
} else {
|
||||
let props = { screenX: left, screenY: top };
|
||||
if (this.tabbrowser.AppConstants.platform != "win") {
|
||||
if (AppConstants.platform != "win") {
|
||||
props.outerWidth = winWidth;
|
||||
props.outerHeight = winHeight;
|
||||
}
|
||||
|
|
|
@ -83,7 +83,7 @@ this.SiteDataManager = {
|
|||
promises.push(new Promise(resolve => {
|
||||
let callback = {
|
||||
onUsageResult(request) {
|
||||
site.quotaUsage = request.usage;
|
||||
site.quotaUsage = request.result.usage;
|
||||
resolve();
|
||||
}
|
||||
};
|
||||
|
|
|
@ -132,7 +132,7 @@ function getQuotaUsage(origin) {
|
|||
return new Promise(resolve => {
|
||||
let uri = NetUtil.newURI(origin);
|
||||
let principal = Services.scriptSecurityManager.createCodebasePrincipal(uri, {});
|
||||
Services.qms.getUsageForPrincipal(principal, request => resolve(request.usage));
|
||||
Services.qms.getUsageForPrincipal(principal, request => resolve(request.result.usage));
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -18,16 +18,6 @@
|
|||
obj:/lib/libdbus-1.so.3.4.0
|
||||
...
|
||||
}
|
||||
{
|
||||
Bug 793600
|
||||
Memcheck:Leak
|
||||
fun:realloc
|
||||
obj:/usr/lib/libfontconfig.so.1.4.4
|
||||
...
|
||||
fun:FcDefaultSubstitute
|
||||
fun:_ZN17gfxPangoFontGroup11MakeFontSetEP14_PangoLanguagedP9nsAutoRefI10_FcPatternE
|
||||
...
|
||||
}
|
||||
{
|
||||
Bug 794366
|
||||
Memcheck:Leak
|
||||
|
|
|
@ -18,16 +18,6 @@
|
|||
obj:/lib64/libdbus-1.so.3.4.0
|
||||
...
|
||||
}
|
||||
{
|
||||
Bug 793600
|
||||
Memcheck:Leak
|
||||
fun:realloc
|
||||
obj:/usr/lib64/libfontconfig.so.1.4.4
|
||||
...
|
||||
fun:FcDefaultSubstitute
|
||||
fun:_ZN17gfxPangoFontGroup11MakeFontSetEP14_PangoLanguagedP9nsAutoRefI10_FcPatternE
|
||||
...
|
||||
}
|
||||
# Fontconfig is going fancy with its cache structure and that confuses valgrind.
|
||||
# https://bugs.freedesktop.org/show_bug.cgi?id=8215
|
||||
# https://bugs.freedesktop.org/show_bug.cgi?id=8428
|
||||
|
|
|
@ -12,292 +12,22 @@
|
|||
#endif
|
||||
#include "nsIAddonPolicyService.h"
|
||||
#include "nsIContentSecurityPolicy.h"
|
||||
#include "nsIEffectiveTLDService.h"
|
||||
#include "nsIObjectInputStream.h"
|
||||
#include "nsIObjectOutputStream.h"
|
||||
|
||||
#include "nsPrincipal.h"
|
||||
#include "ContentPrincipal.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsIURIWithPrincipal.h"
|
||||
#include "nsNullPrincipal.h"
|
||||
#include "NullPrincipal.h"
|
||||
#include "nsScriptSecurityManager.h"
|
||||
#include "nsServiceManagerUtils.h"
|
||||
|
||||
#include "mozilla/dom/ChromeUtils.h"
|
||||
#include "mozilla/dom/CSPDictionariesBinding.h"
|
||||
#include "mozilla/dom/quota/QuotaManager.h"
|
||||
#include "mozilla/dom/ToJSValue.h"
|
||||
#include "mozilla/dom/URLSearchParams.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
using dom::URLParams;
|
||||
|
||||
bool OriginAttributes::sFirstPartyIsolation = false;
|
||||
bool OriginAttributes::sRestrictedOpenerAccess = false;
|
||||
|
||||
void
|
||||
OriginAttributes::InitPrefs()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
static bool sInited = false;
|
||||
if (!sInited) {
|
||||
sInited = true;
|
||||
Preferences::AddBoolVarCache(&sFirstPartyIsolation,
|
||||
"privacy.firstparty.isolate");
|
||||
Preferences::AddBoolVarCache(&sRestrictedOpenerAccess,
|
||||
"privacy.firstparty.isolate.restrict_opener_access");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
OriginAttributes::SetFirstPartyDomain(const bool aIsTopLevelDocument,
|
||||
nsIURI* aURI)
|
||||
{
|
||||
bool isFirstPartyEnabled = IsFirstPartyEnabled();
|
||||
|
||||
// If the pref is off or this is not a top level load, bail out.
|
||||
if (!isFirstPartyEnabled || !aIsTopLevelDocument) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIEffectiveTLDService> tldService =
|
||||
do_GetService(NS_EFFECTIVETLDSERVICE_CONTRACTID);
|
||||
MOZ_ASSERT(tldService);
|
||||
if (!tldService) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsAutoCString baseDomain;
|
||||
nsresult rv = tldService->GetBaseDomain(aURI, 0, baseDomain);
|
||||
if (NS_FAILED(rv)) {
|
||||
nsAutoCString scheme;
|
||||
rv = aURI->GetScheme(scheme);
|
||||
NS_ENSURE_SUCCESS_VOID(rv);
|
||||
if (scheme.EqualsLiteral("about")) {
|
||||
baseDomain.AssignLiteral(ABOUT_URI_FIRST_PARTY_DOMAIN);
|
||||
}
|
||||
}
|
||||
|
||||
mFirstPartyDomain = NS_ConvertUTF8toUTF16(baseDomain);
|
||||
}
|
||||
|
||||
void
|
||||
OriginAttributes::SetFirstPartyDomain(const bool aIsTopLevelDocument,
|
||||
const nsACString& aDomain)
|
||||
{
|
||||
bool isFirstPartyEnabled = IsFirstPartyEnabled();
|
||||
|
||||
// If the pref is off or this is not a top level load, bail out.
|
||||
if (!isFirstPartyEnabled || !aIsTopLevelDocument) {
|
||||
return;
|
||||
}
|
||||
|
||||
mFirstPartyDomain = NS_ConvertUTF8toUTF16(aDomain);
|
||||
}
|
||||
|
||||
void
|
||||
OriginAttributes::CreateSuffix(nsACString& aStr) const
|
||||
{
|
||||
URLParams params;
|
||||
nsAutoString value;
|
||||
|
||||
//
|
||||
// Important: While serializing any string-valued attributes, perform a
|
||||
// release-mode assertion to make sure that they don't contain characters that
|
||||
// will break the quota manager when it uses the serialization for file
|
||||
// naming.
|
||||
//
|
||||
|
||||
if (mAppId != nsIScriptSecurityManager::NO_APP_ID) {
|
||||
value.AppendInt(mAppId);
|
||||
params.Set(NS_LITERAL_STRING("appId"), value);
|
||||
}
|
||||
|
||||
if (mInIsolatedMozBrowser) {
|
||||
params.Set(NS_LITERAL_STRING("inBrowser"), NS_LITERAL_STRING("1"));
|
||||
}
|
||||
|
||||
if (mUserContextId != nsIScriptSecurityManager::DEFAULT_USER_CONTEXT_ID) {
|
||||
value.Truncate();
|
||||
value.AppendInt(mUserContextId);
|
||||
params.Set(NS_LITERAL_STRING("userContextId"), value);
|
||||
}
|
||||
|
||||
|
||||
if (mPrivateBrowsingId) {
|
||||
value.Truncate();
|
||||
value.AppendInt(mPrivateBrowsingId);
|
||||
params.Set(NS_LITERAL_STRING("privateBrowsingId"), value);
|
||||
}
|
||||
|
||||
if (!mFirstPartyDomain.IsEmpty()) {
|
||||
MOZ_RELEASE_ASSERT(mFirstPartyDomain.FindCharInSet(dom::quota::QuotaManager::kReplaceChars) == kNotFound);
|
||||
params.Set(NS_LITERAL_STRING("firstPartyDomain"), mFirstPartyDomain);
|
||||
}
|
||||
|
||||
aStr.Truncate();
|
||||
|
||||
params.Serialize(value);
|
||||
if (!value.IsEmpty()) {
|
||||
aStr.AppendLiteral("^");
|
||||
aStr.Append(NS_ConvertUTF16toUTF8(value));
|
||||
}
|
||||
|
||||
// In debug builds, check the whole string for illegal characters too (just in case).
|
||||
#ifdef DEBUG
|
||||
nsAutoCString str;
|
||||
str.Assign(aStr);
|
||||
MOZ_ASSERT(str.FindCharInSet(dom::quota::QuotaManager::kReplaceChars) == kNotFound);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
OriginAttributes::CreateAnonymizedSuffix(nsACString& aStr) const
|
||||
{
|
||||
OriginAttributes attrs = *this;
|
||||
|
||||
if (!attrs.mFirstPartyDomain.IsEmpty()) {
|
||||
attrs.mFirstPartyDomain.AssignLiteral("_anonymizedFirstPartyDomain_");
|
||||
}
|
||||
|
||||
attrs.CreateSuffix(aStr);
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
class MOZ_STACK_CLASS PopulateFromSuffixIterator final
|
||||
: public URLParams::ForEachIterator
|
||||
{
|
||||
public:
|
||||
explicit PopulateFromSuffixIterator(OriginAttributes* aOriginAttributes)
|
||||
: mOriginAttributes(aOriginAttributes)
|
||||
{
|
||||
MOZ_ASSERT(aOriginAttributes);
|
||||
// If mPrivateBrowsingId is passed in as >0 and is not present in the suffix,
|
||||
// then it will remain >0 when it should be 0 according to the suffix. Set to 0 before
|
||||
// iterating to fix this.
|
||||
mOriginAttributes->mPrivateBrowsingId = 0;
|
||||
}
|
||||
|
||||
bool URLParamsIterator(const nsString& aName,
|
||||
const nsString& aValue) override
|
||||
{
|
||||
if (aName.EqualsLiteral("appId")) {
|
||||
nsresult rv;
|
||||
int64_t val = aValue.ToInteger64(&rv);
|
||||
NS_ENSURE_SUCCESS(rv, false);
|
||||
NS_ENSURE_TRUE(val <= UINT32_MAX, false);
|
||||
mOriginAttributes->mAppId = static_cast<uint32_t>(val);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if (aName.EqualsLiteral("inBrowser")) {
|
||||
if (!aValue.EqualsLiteral("1")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
mOriginAttributes->mInIsolatedMozBrowser = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (aName.EqualsLiteral("addonId")) {
|
||||
// No longer supported. Silently ignore so that legacy origin strings
|
||||
// don't cause failures.
|
||||
return true;
|
||||
}
|
||||
|
||||
if (aName.EqualsLiteral("userContextId")) {
|
||||
nsresult rv;
|
||||
int64_t val = aValue.ToInteger64(&rv);
|
||||
NS_ENSURE_SUCCESS(rv, false);
|
||||
NS_ENSURE_TRUE(val <= UINT32_MAX, false);
|
||||
mOriginAttributes->mUserContextId = static_cast<uint32_t>(val);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if (aName.EqualsLiteral("privateBrowsingId")) {
|
||||
nsresult rv;
|
||||
int64_t val = aValue.ToInteger64(&rv);
|
||||
NS_ENSURE_SUCCESS(rv, false);
|
||||
NS_ENSURE_TRUE(val >= 0 && val <= UINT32_MAX, false);
|
||||
mOriginAttributes->mPrivateBrowsingId = static_cast<uint32_t>(val);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if (aName.EqualsLiteral("firstPartyDomain")) {
|
||||
MOZ_RELEASE_ASSERT(mOriginAttributes->mFirstPartyDomain.IsEmpty());
|
||||
mOriginAttributes->mFirstPartyDomain.Assign(aValue);
|
||||
return true;
|
||||
}
|
||||
|
||||
// No other attributes are supported.
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
OriginAttributes* mOriginAttributes;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
bool
|
||||
OriginAttributes::PopulateFromSuffix(const nsACString& aStr)
|
||||
{
|
||||
if (aStr.IsEmpty()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (aStr[0] != '^') {
|
||||
return false;
|
||||
}
|
||||
|
||||
URLParams params;
|
||||
params.ParseInput(Substring(aStr, 1, aStr.Length() - 1));
|
||||
|
||||
PopulateFromSuffixIterator iterator(this);
|
||||
return params.ForEach(iterator);
|
||||
}
|
||||
|
||||
bool
|
||||
OriginAttributes::PopulateFromOrigin(const nsACString& aOrigin,
|
||||
nsACString& aOriginNoSuffix)
|
||||
{
|
||||
// RFindChar is only available on nsCString.
|
||||
nsCString origin(aOrigin);
|
||||
int32_t pos = origin.RFindChar('^');
|
||||
|
||||
if (pos == kNotFound) {
|
||||
aOriginNoSuffix = origin;
|
||||
return true;
|
||||
}
|
||||
|
||||
aOriginNoSuffix = Substring(origin, 0, pos);
|
||||
return PopulateFromSuffix(Substring(origin, pos));
|
||||
}
|
||||
|
||||
void
|
||||
OriginAttributes::SyncAttributesWithPrivateBrowsing(bool aInPrivateBrowsing)
|
||||
{
|
||||
mPrivateBrowsingId = aInPrivateBrowsing ? 1 : 0;
|
||||
}
|
||||
|
||||
/* static */
|
||||
bool
|
||||
OriginAttributes::IsPrivateBrowsing(const nsACString& aOrigin)
|
||||
{
|
||||
nsAutoCString dummy;
|
||||
OriginAttributes attrs;
|
||||
if (NS_WARN_IF(!attrs.PopulateFromOrigin(aOrigin, dummy))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return !!attrs.mPrivateBrowsingId;
|
||||
}
|
||||
|
||||
BasePrincipal::BasePrincipal(PrincipalKind aKind)
|
||||
: mKind(aKind)
|
||||
, mDomainSet(false)
|
||||
|
@ -645,7 +375,7 @@ BasePrincipal::CreateCodebasePrincipal(nsIURI* aURI, const OriginAttributes& aAt
|
|||
nsresult rv = NS_URIChainHasFlags(aURI, nsIProtocolHandler::URI_INHERITS_SECURITY_CONTEXT,
|
||||
&inheritsPrincipal);
|
||||
if (NS_FAILED(rv) || inheritsPrincipal) {
|
||||
return nsNullPrincipal::Create(aAttrs);
|
||||
return NullPrincipal::Create(aAttrs);
|
||||
}
|
||||
|
||||
// Check whether the URI knows what its principal is supposed to be.
|
||||
|
@ -654,14 +384,14 @@ BasePrincipal::CreateCodebasePrincipal(nsIURI* aURI, const OriginAttributes& aAt
|
|||
nsCOMPtr<nsIPrincipal> principal;
|
||||
uriPrinc->GetPrincipal(getter_AddRefs(principal));
|
||||
if (!principal) {
|
||||
return nsNullPrincipal::Create(aAttrs);
|
||||
return NullPrincipal::Create(aAttrs);
|
||||
}
|
||||
RefPtr<BasePrincipal> concrete = Cast(principal);
|
||||
return concrete.forget();
|
||||
}
|
||||
|
||||
// Mint a codebase principal.
|
||||
RefPtr<nsPrincipal> codebase = new nsPrincipal();
|
||||
RefPtr<ContentPrincipal> codebase = new ContentPrincipal();
|
||||
rv = codebase->Init(aURI, aAttrs);
|
||||
NS_ENSURE_SUCCESS(rv, nullptr);
|
||||
return codebase.forget();
|
||||
|
@ -674,7 +404,7 @@ BasePrincipal::CreateCodebasePrincipal(const nsACString& aOrigin)
|
|||
"CreateCodebasePrincipal does not support System and Expanded principals");
|
||||
|
||||
MOZ_ASSERT(!StringBeginsWith(aOrigin, NS_LITERAL_CSTRING(NS_NULLPRINCIPAL_SCHEME ":")),
|
||||
"CreateCodebasePrincipal does not support nsNullPrincipal");
|
||||
"CreateCodebasePrincipal does not support NullPrincipal");
|
||||
|
||||
nsAutoCString originNoSuffix;
|
||||
mozilla::OriginAttributes attrs;
|
||||
|
|
|
@ -10,187 +10,17 @@
|
|||
#include "nsJSPrincipals.h"
|
||||
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/dom/ChromeUtils.h"
|
||||
#include "mozilla/dom/ChromeUtilsBinding.h"
|
||||
#include "nsIScriptSecurityManager.h"
|
||||
#include "mozilla/OriginAttributes.h"
|
||||
|
||||
class nsIContentSecurityPolicy;
|
||||
class nsIObjectOutputStream;
|
||||
class nsIObjectInputStream;
|
||||
class nsIURI;
|
||||
|
||||
class nsExpandedPrincipal;
|
||||
class ExpandedPrincipal;
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
// Base OriginAttributes class. This has several subclass flavors, and is not
|
||||
// directly constructable itself.
|
||||
class OriginAttributes : public dom::OriginAttributesDictionary
|
||||
{
|
||||
public:
|
||||
OriginAttributes() {}
|
||||
|
||||
OriginAttributes(uint32_t aAppId, bool aInIsolatedMozBrowser)
|
||||
{
|
||||
mAppId = aAppId;
|
||||
mInIsolatedMozBrowser = aInIsolatedMozBrowser;
|
||||
}
|
||||
|
||||
explicit OriginAttributes(const OriginAttributesDictionary& aOther)
|
||||
: OriginAttributesDictionary(aOther)
|
||||
{}
|
||||
|
||||
void SetFirstPartyDomain(const bool aIsTopLevelDocument, nsIURI* aURI);
|
||||
void SetFirstPartyDomain(const bool aIsTopLevelDocument, const nsACString& aDomain);
|
||||
|
||||
enum {
|
||||
STRIP_FIRST_PARTY_DOMAIN = 0x01,
|
||||
STRIP_USER_CONTEXT_ID = 0x02,
|
||||
};
|
||||
|
||||
inline void StripAttributes(uint32_t aFlags)
|
||||
{
|
||||
if (aFlags & STRIP_FIRST_PARTY_DOMAIN) {
|
||||
mFirstPartyDomain.Truncate();
|
||||
}
|
||||
|
||||
if (aFlags & STRIP_USER_CONTEXT_ID) {
|
||||
mUserContextId = nsIScriptSecurityManager::DEFAULT_USER_CONTEXT_ID;
|
||||
}
|
||||
}
|
||||
|
||||
bool operator==(const OriginAttributes& aOther) const
|
||||
{
|
||||
return mAppId == aOther.mAppId &&
|
||||
mInIsolatedMozBrowser == aOther.mInIsolatedMozBrowser &&
|
||||
mUserContextId == aOther.mUserContextId &&
|
||||
mPrivateBrowsingId == aOther.mPrivateBrowsingId &&
|
||||
mFirstPartyDomain == aOther.mFirstPartyDomain;
|
||||
}
|
||||
|
||||
bool operator!=(const OriginAttributes& aOther) const
|
||||
{
|
||||
return !(*this == aOther);
|
||||
}
|
||||
|
||||
// Serializes/Deserializes non-default values into the suffix format, i.e.
|
||||
// |!key1=value1&key2=value2|. If there are no non-default attributes, this
|
||||
// returns an empty string.
|
||||
void CreateSuffix(nsACString& aStr) const;
|
||||
|
||||
// Don't use this method for anything else than debugging!
|
||||
void CreateAnonymizedSuffix(nsACString& aStr) const;
|
||||
|
||||
MOZ_MUST_USE bool PopulateFromSuffix(const nsACString& aStr);
|
||||
|
||||
// Populates the attributes from a string like
|
||||
// |uri!key1=value1&key2=value2| and returns the uri without the suffix.
|
||||
MOZ_MUST_USE bool PopulateFromOrigin(const nsACString& aOrigin,
|
||||
nsACString& aOriginNoSuffix);
|
||||
|
||||
// Helper function to match mIsPrivateBrowsing to existing private browsing
|
||||
// flags. Once all other flags are removed, this can be removed too.
|
||||
void SyncAttributesWithPrivateBrowsing(bool aInPrivateBrowsing);
|
||||
|
||||
// check if "privacy.firstparty.isolate" is enabled.
|
||||
static inline bool IsFirstPartyEnabled()
|
||||
{
|
||||
return sFirstPartyIsolation;
|
||||
}
|
||||
|
||||
// check if the access of window.opener across different FPDs is restricted.
|
||||
// We only restrict the access of window.opener when first party isolation
|
||||
// is enabled and "privacy.firstparty.isolate.restrict_opener_access" is on.
|
||||
static inline bool IsRestrictOpenerAccessForFPI()
|
||||
{
|
||||
// We always want to restrict window.opener if first party isolation is
|
||||
// disabled.
|
||||
return !sFirstPartyIsolation || sRestrictedOpenerAccess;
|
||||
}
|
||||
|
||||
// returns true if the originAttributes suffix has mPrivateBrowsingId value
|
||||
// different than 0.
|
||||
static bool IsPrivateBrowsing(const nsACString& aOrigin);
|
||||
|
||||
static void InitPrefs();
|
||||
|
||||
private:
|
||||
static bool sFirstPartyIsolation;
|
||||
static bool sRestrictedOpenerAccess;
|
||||
};
|
||||
|
||||
class OriginAttributesPattern : public dom::OriginAttributesPatternDictionary
|
||||
{
|
||||
public:
|
||||
// To convert a JSON string to an OriginAttributesPattern, do the following:
|
||||
//
|
||||
// OriginAttributesPattern pattern;
|
||||
// if (!pattern.Init(aJSONString)) {
|
||||
// ... // handle failure.
|
||||
// }
|
||||
OriginAttributesPattern() {}
|
||||
|
||||
explicit OriginAttributesPattern(const OriginAttributesPatternDictionary& aOther)
|
||||
: OriginAttributesPatternDictionary(aOther) {}
|
||||
|
||||
// Performs a match of |aAttrs| against this pattern.
|
||||
bool Matches(const OriginAttributes& aAttrs) const
|
||||
{
|
||||
if (mAppId.WasPassed() && mAppId.Value() != aAttrs.mAppId) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mInIsolatedMozBrowser.WasPassed() && mInIsolatedMozBrowser.Value() != aAttrs.mInIsolatedMozBrowser) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mUserContextId.WasPassed() && mUserContextId.Value() != aAttrs.mUserContextId) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mPrivateBrowsingId.WasPassed() && mPrivateBrowsingId.Value() != aAttrs.mPrivateBrowsingId) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mFirstPartyDomain.WasPassed() && mFirstPartyDomain.Value() != aAttrs.mFirstPartyDomain) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Overlaps(const OriginAttributesPattern& aOther) const
|
||||
{
|
||||
if (mAppId.WasPassed() && aOther.mAppId.WasPassed() &&
|
||||
mAppId.Value() != aOther.mAppId.Value()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mInIsolatedMozBrowser.WasPassed() &&
|
||||
aOther.mInIsolatedMozBrowser.WasPassed() &&
|
||||
mInIsolatedMozBrowser.Value() != aOther.mInIsolatedMozBrowser.Value()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mUserContextId.WasPassed() && aOther.mUserContextId.WasPassed() &&
|
||||
mUserContextId.Value() != aOther.mUserContextId.Value()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mPrivateBrowsingId.WasPassed() && aOther.mPrivateBrowsingId.WasPassed() &&
|
||||
mPrivateBrowsingId.Value() != aOther.mPrivateBrowsingId.Value()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mFirstPartyDomain.WasPassed() && aOther.mFirstPartyDomain.WasPassed() &&
|
||||
mFirstPartyDomain.Value() != aOther.mFirstPartyDomain.Value()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* Base class from which all nsIPrincipal implementations inherit. Use this for
|
||||
* default implementations and other commonalities between principal
|
||||
|
@ -283,7 +113,7 @@ protected:
|
|||
// principal would allow the load ignoring any common behavior implemented in
|
||||
// BasePrincipal::CheckMayLoad.
|
||||
virtual bool MayLoadInternal(nsIURI* aURI) = 0;
|
||||
friend class ::nsExpandedPrincipal;
|
||||
friend class ::ExpandedPrincipal;
|
||||
|
||||
// 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()
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
* 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 "nsPrincipal.h"
|
||||
#include "ContentPrincipal.h"
|
||||
|
||||
#include "mozIThirdPartyUtil.h"
|
||||
#include "nscore.h"
|
||||
|
@ -19,6 +19,8 @@
|
|||
#include "nsJSPrincipals.h"
|
||||
#include "nsIEffectiveTLDService.h"
|
||||
#include "nsIClassInfoImpl.h"
|
||||
#include "nsIObjectInputStream.h"
|
||||
#include "nsIObjectOutputStream.h"
|
||||
#include "nsIProtocolHandler.h"
|
||||
#include "nsError.h"
|
||||
#include "nsIContentSecurityPolicy.h"
|
||||
|
@ -58,25 +60,25 @@ GetAddonPolicyService(nsresult* aRv)
|
|||
return addonPolicyService;
|
||||
}
|
||||
|
||||
NS_IMPL_CLASSINFO(nsPrincipal, nullptr, nsIClassInfo::MAIN_THREAD_ONLY,
|
||||
NS_IMPL_CLASSINFO(ContentPrincipal, nullptr, nsIClassInfo::MAIN_THREAD_ONLY,
|
||||
NS_PRINCIPAL_CID)
|
||||
NS_IMPL_QUERY_INTERFACE_CI(nsPrincipal,
|
||||
NS_IMPL_QUERY_INTERFACE_CI(ContentPrincipal,
|
||||
nsIPrincipal,
|
||||
nsISerializable)
|
||||
NS_IMPL_CI_INTERFACE_GETTER(nsPrincipal,
|
||||
NS_IMPL_CI_INTERFACE_GETTER(ContentPrincipal,
|
||||
nsIPrincipal,
|
||||
nsISerializable)
|
||||
|
||||
// Called at startup:
|
||||
/* static */ void
|
||||
nsPrincipal::InitializeStatics()
|
||||
ContentPrincipal::InitializeStatics()
|
||||
{
|
||||
Preferences::AddBoolVarCache(&gCodeBasePrincipalSupport,
|
||||
"signed.applets.codebase_principal_support",
|
||||
false);
|
||||
}
|
||||
|
||||
nsPrincipal::nsPrincipal()
|
||||
ContentPrincipal::ContentPrincipal()
|
||||
: BasePrincipal(eCodebasePrincipal)
|
||||
, mCodebaseImmutable(false)
|
||||
, mDomainImmutable(false)
|
||||
|
@ -84,7 +86,7 @@ nsPrincipal::nsPrincipal()
|
|||
{
|
||||
}
|
||||
|
||||
nsPrincipal::~nsPrincipal()
|
||||
ContentPrincipal::~ContentPrincipal()
|
||||
{
|
||||
// let's clear the principal within the csp to avoid a tangling pointer
|
||||
if (mCSP) {
|
||||
|
@ -93,7 +95,8 @@ nsPrincipal::~nsPrincipal()
|
|||
}
|
||||
|
||||
nsresult
|
||||
nsPrincipal::Init(nsIURI *aCodebase, const OriginAttributes& aOriginAttributes)
|
||||
ContentPrincipal::Init(nsIURI *aCodebase,
|
||||
const OriginAttributes& aOriginAttributes)
|
||||
{
|
||||
NS_ENSURE_STATE(!mInitialized);
|
||||
NS_ENSURE_ARG(aCodebase);
|
||||
|
@ -123,13 +126,13 @@ nsPrincipal::Init(nsIURI *aCodebase, const OriginAttributes& aOriginAttributes)
|
|||
}
|
||||
|
||||
nsresult
|
||||
nsPrincipal::GetScriptLocation(nsACString &aStr)
|
||||
ContentPrincipal::GetScriptLocation(nsACString &aStr)
|
||||
{
|
||||
return mCodebase->GetSpec(aStr);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsPrincipal::GetOriginInternal(nsACString& aOrigin)
|
||||
ContentPrincipal::GetOriginInternal(nsACString& aOrigin)
|
||||
{
|
||||
if (!mCodebase) {
|
||||
return NS_ERROR_FAILURE;
|
||||
|
@ -249,12 +252,12 @@ nsPrincipal::GetOriginInternal(nsACString& aOrigin)
|
|||
}
|
||||
|
||||
bool
|
||||
nsPrincipal::SubsumesInternal(nsIPrincipal* aOther,
|
||||
BasePrincipal::DocumentDomainConsideration aConsideration)
|
||||
ContentPrincipal::SubsumesInternal(nsIPrincipal* aOther,
|
||||
BasePrincipal::DocumentDomainConsideration aConsideration)
|
||||
{
|
||||
MOZ_ASSERT(aOther);
|
||||
|
||||
// For nsPrincipal, Subsumes is equivalent to Equals.
|
||||
// For ContentPrincipal, Subsumes is equivalent to Equals.
|
||||
if (aOther == this) {
|
||||
return true;
|
||||
}
|
||||
|
@ -286,7 +289,7 @@ nsPrincipal::SubsumesInternal(nsIPrincipal* aOther,
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPrincipal::GetURI(nsIURI** aURI)
|
||||
ContentPrincipal::GetURI(nsIURI** aURI)
|
||||
{
|
||||
if (mCodebaseImmutable) {
|
||||
NS_ADDREF(*aURI = mCodebase);
|
||||
|
@ -302,7 +305,7 @@ nsPrincipal::GetURI(nsIURI** aURI)
|
|||
}
|
||||
|
||||
bool
|
||||
nsPrincipal::MayLoadInternal(nsIURI* aURI)
|
||||
ContentPrincipal::MayLoadInternal(nsIURI* aURI)
|
||||
{
|
||||
// See if aURI is something like a Blob URI that is actually associated with
|
||||
// a principal.
|
||||
|
@ -338,7 +341,7 @@ nsPrincipal::MayLoadInternal(nsIURI* aURI)
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPrincipal::GetHashValue(uint32_t* aValue)
|
||||
ContentPrincipal::GetHashValue(uint32_t* aValue)
|
||||
{
|
||||
NS_PRECONDITION(mCodebase, "Need a codebase");
|
||||
|
||||
|
@ -347,7 +350,7 @@ nsPrincipal::GetHashValue(uint32_t* aValue)
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPrincipal::GetDomain(nsIURI** aDomain)
|
||||
ContentPrincipal::GetDomain(nsIURI** aDomain)
|
||||
{
|
||||
if (!mDomain) {
|
||||
*aDomain = nullptr;
|
||||
|
@ -363,7 +366,7 @@ nsPrincipal::GetDomain(nsIURI** aDomain)
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPrincipal::SetDomain(nsIURI* aDomain)
|
||||
ContentPrincipal::SetDomain(nsIURI* aDomain)
|
||||
{
|
||||
mDomain = NS_TryToMakeImmutable(aDomain);
|
||||
mDomainImmutable = URIIsImmutable(mDomain);
|
||||
|
@ -384,7 +387,7 @@ nsPrincipal::SetDomain(nsIURI* aDomain)
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPrincipal::GetBaseDomain(nsACString& aBaseDomain)
|
||||
ContentPrincipal::GetBaseDomain(nsACString& aBaseDomain)
|
||||
{
|
||||
// For a file URI, we return the file path.
|
||||
if (NS_URIIsLocalFile(mCodebase)) {
|
||||
|
@ -419,7 +422,7 @@ nsPrincipal::GetBaseDomain(nsACString& aBaseDomain)
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPrincipal::GetAddonId(nsAString& aAddonId)
|
||||
ContentPrincipal::GetAddonId(nsAString& aAddonId)
|
||||
{
|
||||
if (mAddonIdCache.isSome()) {
|
||||
aAddonId.Assign(mAddonIdCache.ref());
|
||||
|
@ -448,7 +451,7 @@ nsPrincipal::GetAddonId(nsAString& aAddonId)
|
|||
};
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPrincipal::Read(nsIObjectInputStream* aStream)
|
||||
ContentPrincipal::Read(nsIObjectInputStream* aStream)
|
||||
{
|
||||
nsCOMPtr<nsISupports> supports;
|
||||
nsCOMPtr<nsIURI> codebase;
|
||||
|
@ -494,7 +497,7 @@ nsPrincipal::Read(nsIObjectInputStream* aStream)
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPrincipal::Write(nsIObjectOutputStream* aStream)
|
||||
ContentPrincipal::Write(nsIObjectOutputStream* aStream)
|
||||
{
|
||||
NS_ENSURE_STATE(mCodebase);
|
||||
nsresult rv = NS_WriteOptionalCompoundObject(aStream, mCodebase, NS_GET_IID(nsIURI),
|
|
@ -3,8 +3,8 @@
|
|||
* 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 nsPrincipal_h__
|
||||
#define nsPrincipal_h__
|
||||
#ifndef ContentPrincipal_h
|
||||
#define ContentPrincipal_h
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsJSPrincipals.h"
|
||||
|
@ -15,7 +15,7 @@
|
|||
#include "nsScriptSecurityManager.h"
|
||||
#include "mozilla/BasePrincipal.h"
|
||||
|
||||
class nsPrincipal final : public mozilla::BasePrincipal
|
||||
class ContentPrincipal final : public mozilla::BasePrincipal
|
||||
{
|
||||
public:
|
||||
NS_DECL_NSISERIALIZABLE
|
||||
|
@ -29,7 +29,7 @@ public:
|
|||
bool IsCodebasePrincipal() const override { return true; }
|
||||
nsresult GetOriginInternal(nsACString& aOrigin) override;
|
||||
|
||||
nsPrincipal();
|
||||
ContentPrincipal();
|
||||
|
||||
// Init() must be called before the principal is in a usable state.
|
||||
nsresult Init(nsIURI* aCodebase,
|
||||
|
@ -50,9 +50,10 @@ public:
|
|||
bool mInitialized;
|
||||
|
||||
protected:
|
||||
virtual ~nsPrincipal();
|
||||
virtual ~ContentPrincipal();
|
||||
|
||||
bool SubsumesInternal(nsIPrincipal* aOther, DocumentDomainConsideration aConsideration) override;
|
||||
bool SubsumesInternal(nsIPrincipal* aOther,
|
||||
DocumentDomainConsideration aConsideration) override;
|
||||
bool MayLoadInternal(nsIURI* aURI) override;
|
||||
|
||||
private:
|
||||
|
@ -64,4 +65,4 @@ private:
|
|||
{ 0x653e0e4d, 0x3ee4, 0x45fa, \
|
||||
{ 0xb2, 0x72, 0x97, 0xc2, 0x0b, 0xc0, 0x1e, 0xb8 } }
|
||||
|
||||
#endif // nsPrincipal_h__
|
||||
#endif // ContentPrincipal_h
|
|
@ -4,19 +4,19 @@
|
|||
* 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 "nsExpandedPrincipal.h"
|
||||
#include "ExpandedPrincipal.h"
|
||||
#include "nsIClassInfoImpl.h"
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
NS_IMPL_CLASSINFO(nsExpandedPrincipal, nullptr, nsIClassInfo::MAIN_THREAD_ONLY,
|
||||
NS_IMPL_CLASSINFO(ExpandedPrincipal, nullptr, nsIClassInfo::MAIN_THREAD_ONLY,
|
||||
NS_EXPANDEDPRINCIPAL_CID)
|
||||
NS_IMPL_QUERY_INTERFACE_CI(nsExpandedPrincipal,
|
||||
NS_IMPL_QUERY_INTERFACE_CI(ExpandedPrincipal,
|
||||
nsIPrincipal,
|
||||
nsIExpandedPrincipal)
|
||||
NS_IMPL_CI_INTERFACE_GETTER(nsExpandedPrincipal,
|
||||
nsIPrincipal,
|
||||
nsIExpandedPrincipal)
|
||||
NS_IMPL_CI_INTERFACE_GETTER(ExpandedPrincipal,
|
||||
nsIPrincipal,
|
||||
nsIExpandedPrincipal)
|
||||
|
||||
struct OriginComparator
|
||||
{
|
||||
|
@ -43,11 +43,11 @@ struct OriginComparator
|
|||
}
|
||||
};
|
||||
|
||||
nsExpandedPrincipal::nsExpandedPrincipal(nsTArray<nsCOMPtr<nsIPrincipal>> &aWhiteList,
|
||||
const OriginAttributes& aAttrs)
|
||||
ExpandedPrincipal::ExpandedPrincipal(nsTArray<nsCOMPtr<nsIPrincipal>> &aWhiteList,
|
||||
const OriginAttributes& aAttrs)
|
||||
: BasePrincipal(eExpandedPrincipal)
|
||||
{
|
||||
// We force the principals to be sorted by origin so that nsExpandedPrincipal
|
||||
// We force the principals to be sorted by origin so that ExpandedPrincipal
|
||||
// origins can have a canonical form.
|
||||
OriginComparator c;
|
||||
for (size_t i = 0; i < aWhiteList.Length(); ++i) {
|
||||
|
@ -56,33 +56,33 @@ nsExpandedPrincipal::nsExpandedPrincipal(nsTArray<nsCOMPtr<nsIPrincipal>> &aWhit
|
|||
mOriginAttributes = aAttrs;
|
||||
}
|
||||
|
||||
nsExpandedPrincipal::~nsExpandedPrincipal()
|
||||
ExpandedPrincipal::~ExpandedPrincipal()
|
||||
{ }
|
||||
|
||||
already_AddRefed<nsExpandedPrincipal>
|
||||
nsExpandedPrincipal::Create(nsTArray<nsCOMPtr<nsIPrincipal>>& aWhiteList,
|
||||
const OriginAttributes& aAttrs)
|
||||
already_AddRefed<ExpandedPrincipal>
|
||||
ExpandedPrincipal::Create(nsTArray<nsCOMPtr<nsIPrincipal>>& aWhiteList,
|
||||
const OriginAttributes& aAttrs)
|
||||
{
|
||||
RefPtr<nsExpandedPrincipal> ep = new nsExpandedPrincipal(aWhiteList, aAttrs);
|
||||
RefPtr<ExpandedPrincipal> ep = new ExpandedPrincipal(aWhiteList, aAttrs);
|
||||
ep->FinishInit();
|
||||
return ep.forget();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsExpandedPrincipal::GetDomain(nsIURI** aDomain)
|
||||
ExpandedPrincipal::GetDomain(nsIURI** aDomain)
|
||||
{
|
||||
*aDomain = nullptr;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsExpandedPrincipal::SetDomain(nsIURI* aDomain)
|
||||
ExpandedPrincipal::SetDomain(nsIURI* aDomain)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsExpandedPrincipal::GetOriginInternal(nsACString& aOrigin)
|
||||
ExpandedPrincipal::GetOriginInternal(nsACString& aOrigin)
|
||||
{
|
||||
aOrigin.AssignLiteral("[Expanded Principal [");
|
||||
for (size_t i = 0; i < mPrincipals.Length(); ++i) {
|
||||
|
@ -101,8 +101,8 @@ nsExpandedPrincipal::GetOriginInternal(nsACString& aOrigin)
|
|||
}
|
||||
|
||||
bool
|
||||
nsExpandedPrincipal::SubsumesInternal(nsIPrincipal* aOther,
|
||||
BasePrincipal::DocumentDomainConsideration aConsideration)
|
||||
ExpandedPrincipal::SubsumesInternal(nsIPrincipal* aOther,
|
||||
BasePrincipal::DocumentDomainConsideration aConsideration)
|
||||
{
|
||||
// If aOther is an ExpandedPrincipal too, we break it down into its component
|
||||
// nsIPrincipals, and check subsumes on each one.
|
||||
|
@ -133,7 +133,7 @@ nsExpandedPrincipal::SubsumesInternal(nsIPrincipal* aOther,
|
|||
}
|
||||
|
||||
bool
|
||||
nsExpandedPrincipal::MayLoadInternal(nsIURI* uri)
|
||||
ExpandedPrincipal::MayLoadInternal(nsIURI* uri)
|
||||
{
|
||||
for (uint32_t i = 0; i < mPrincipals.Length(); ++i){
|
||||
if (BasePrincipal::Cast(mPrincipals[i])->MayLoadInternal(uri)) {
|
||||
|
@ -145,40 +145,40 @@ nsExpandedPrincipal::MayLoadInternal(nsIURI* uri)
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsExpandedPrincipal::GetHashValue(uint32_t* result)
|
||||
ExpandedPrincipal::GetHashValue(uint32_t* result)
|
||||
{
|
||||
MOZ_CRASH("extended principal should never be used as key in a hash map");
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsExpandedPrincipal::GetURI(nsIURI** aURI)
|
||||
ExpandedPrincipal::GetURI(nsIURI** aURI)
|
||||
{
|
||||
*aURI = nullptr;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsExpandedPrincipal::GetWhiteList(nsTArray<nsCOMPtr<nsIPrincipal> >** aWhiteList)
|
||||
ExpandedPrincipal::GetWhiteList(nsTArray<nsCOMPtr<nsIPrincipal> >** aWhiteList)
|
||||
{
|
||||
*aWhiteList = &mPrincipals;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsExpandedPrincipal::GetBaseDomain(nsACString& aBaseDomain)
|
||||
ExpandedPrincipal::GetBaseDomain(nsACString& aBaseDomain)
|
||||
{
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsExpandedPrincipal::GetAddonId(nsAString& aAddonId)
|
||||
ExpandedPrincipal::GetAddonId(nsAString& aAddonId)
|
||||
{
|
||||
aAddonId.Truncate();
|
||||
return NS_OK;
|
||||
};
|
||||
|
||||
bool
|
||||
nsExpandedPrincipal::AddonHasPermission(const nsAString& aPerm)
|
||||
ExpandedPrincipal::AddonHasPermission(const nsAString& aPerm)
|
||||
{
|
||||
for (size_t i = 0; i < mPrincipals.Length(); ++i) {
|
||||
if (BasePrincipal::Cast(mPrincipals[i])->AddonHasPermission(aPerm)) {
|
||||
|
@ -189,7 +189,7 @@ nsExpandedPrincipal::AddonHasPermission(const nsAString& aPerm)
|
|||
}
|
||||
|
||||
nsresult
|
||||
nsExpandedPrincipal::GetScriptLocation(nsACString& aStr)
|
||||
ExpandedPrincipal::GetScriptLocation(nsACString& aStr)
|
||||
{
|
||||
aStr.Assign("[Expanded Principal [");
|
||||
for (size_t i = 0; i < mPrincipals.Length(); ++i) {
|
||||
|
@ -213,13 +213,13 @@ nsExpandedPrincipal::GetScriptLocation(nsACString& aStr)
|
|||
//////////////////////////////////////////
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsExpandedPrincipal::Read(nsIObjectInputStream* aStream)
|
||||
ExpandedPrincipal::Read(nsIObjectInputStream* aStream)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsExpandedPrincipal::Write(nsIObjectOutputStream* aStream)
|
||||
ExpandedPrincipal::Write(nsIObjectOutputStream* aStream)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
|
@ -3,8 +3,8 @@
|
|||
* 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 nsExpandedPrincipal_h
|
||||
#define nsExpandedPrincipal_h
|
||||
#ifndef ExpandedPrincipal_h
|
||||
#define ExpandedPrincipal_h
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsJSPrincipals.h"
|
||||
|
@ -12,19 +12,20 @@
|
|||
#include "nsNetUtil.h"
|
||||
#include "mozilla/BasePrincipal.h"
|
||||
|
||||
class nsExpandedPrincipal : public nsIExpandedPrincipal
|
||||
, public mozilla::BasePrincipal
|
||||
class ExpandedPrincipal : public nsIExpandedPrincipal
|
||||
, public mozilla::BasePrincipal
|
||||
{
|
||||
nsExpandedPrincipal(nsTArray<nsCOMPtr<nsIPrincipal>> &aWhiteList,
|
||||
const mozilla::OriginAttributes& aAttrs);
|
||||
ExpandedPrincipal(nsTArray<nsCOMPtr<nsIPrincipal>> &aWhiteList,
|
||||
const mozilla::OriginAttributes& aAttrs);
|
||||
|
||||
public:
|
||||
static already_AddRefed<nsExpandedPrincipal>
|
||||
static already_AddRefed<ExpandedPrincipal>
|
||||
Create(nsTArray<nsCOMPtr<nsIPrincipal>>& aWhiteList,
|
||||
const mozilla::OriginAttributes& aAttrs);
|
||||
|
||||
NS_DECL_NSIEXPANDEDPRINCIPAL
|
||||
NS_DECL_NSISERIALIZABLE
|
||||
|
||||
NS_IMETHOD_(MozExternalRefCountType) AddRef() override { return nsJSPrincipals::AddRef(); };
|
||||
NS_IMETHOD_(MozExternalRefCountType) Release() override { return nsJSPrincipals::Release(); };
|
||||
NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr) override;
|
||||
|
@ -39,9 +40,11 @@ public:
|
|||
nsresult GetOriginInternal(nsACString& aOrigin) override;
|
||||
|
||||
protected:
|
||||
virtual ~nsExpandedPrincipal();
|
||||
virtual ~ExpandedPrincipal();
|
||||
|
||||
bool SubsumesInternal(nsIPrincipal* aOther,
|
||||
DocumentDomainConsideration aConsideration) override;
|
||||
|
||||
bool SubsumesInternal(nsIPrincipal* aOther, DocumentDomainConsideration aConsideration) override;
|
||||
bool MayLoadInternal(nsIURI* aURI) override;
|
||||
|
||||
private:
|
||||
|
@ -53,4 +56,4 @@ private:
|
|||
{ 0xe8ee88b0, 0x5571, 0x4086, \
|
||||
{ 0xa4, 0x5b, 0x39, 0xa7, 0x16, 0x90, 0x6b, 0xdb } }
|
||||
|
||||
#endif // nsExpandedPrincipal_h
|
||||
#endif // ExpandedPrincipal_h
|
|
@ -13,54 +13,54 @@
|
|||
#include "mozilla/ArrayUtils.h"
|
||||
|
||||
#include "nsDocShell.h"
|
||||
#include "nsNullPrincipal.h"
|
||||
#include "nsNullPrincipalURI.h"
|
||||
#include "NullPrincipal.h"
|
||||
#include "NullPrincipalURI.h"
|
||||
#include "nsMemory.h"
|
||||
#include "nsIURIWithPrincipal.h"
|
||||
#include "nsIClassInfoImpl.h"
|
||||
#include "nsNetCID.h"
|
||||
#include "nsError.h"
|
||||
#include "nsIScriptSecurityManager.h"
|
||||
#include "nsPrincipal.h"
|
||||
#include "ContentPrincipal.h"
|
||||
#include "nsScriptSecurityManager.h"
|
||||
#include "pratom.h"
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
NS_IMPL_CLASSINFO(nsNullPrincipal, nullptr, nsIClassInfo::MAIN_THREAD_ONLY,
|
||||
NS_IMPL_CLASSINFO(NullPrincipal, nullptr, nsIClassInfo::MAIN_THREAD_ONLY,
|
||||
NS_NULLPRINCIPAL_CID)
|
||||
NS_IMPL_QUERY_INTERFACE_CI(nsNullPrincipal,
|
||||
NS_IMPL_QUERY_INTERFACE_CI(NullPrincipal,
|
||||
nsIPrincipal,
|
||||
nsISerializable)
|
||||
NS_IMPL_CI_INTERFACE_GETTER(nsNullPrincipal,
|
||||
NS_IMPL_CI_INTERFACE_GETTER(NullPrincipal,
|
||||
nsIPrincipal,
|
||||
nsISerializable)
|
||||
|
||||
/* static */ already_AddRefed<nsNullPrincipal>
|
||||
nsNullPrincipal::CreateWithInheritedAttributes(nsIPrincipal* aInheritFrom)
|
||||
/* static */ already_AddRefed<NullPrincipal>
|
||||
NullPrincipal::CreateWithInheritedAttributes(nsIPrincipal* aInheritFrom)
|
||||
{
|
||||
RefPtr<nsNullPrincipal> nullPrin = new nsNullPrincipal();
|
||||
RefPtr<NullPrincipal> nullPrin = new NullPrincipal();
|
||||
nsresult rv = nullPrin->Init(Cast(aInheritFrom)->OriginAttributesRef());
|
||||
MOZ_RELEASE_ASSERT(NS_SUCCEEDED(rv));
|
||||
return nullPrin.forget();
|
||||
}
|
||||
|
||||
/* static */ already_AddRefed<nsNullPrincipal>
|
||||
nsNullPrincipal::CreateWithInheritedAttributes(nsIDocShell* aDocShell, bool aIsFirstParty)
|
||||
/* static */ already_AddRefed<NullPrincipal>
|
||||
NullPrincipal::CreateWithInheritedAttributes(nsIDocShell* aDocShell, bool aIsFirstParty)
|
||||
{
|
||||
OriginAttributes attrs = nsDocShell::Cast(aDocShell)->GetOriginAttributes();
|
||||
attrs.SetFirstPartyDomain(aIsFirstParty, NS_LITERAL_CSTRING(NULL_PRINCIPAL_FIRST_PARTY_DOMAIN));
|
||||
|
||||
RefPtr<nsNullPrincipal> nullPrin = new nsNullPrincipal();
|
||||
RefPtr<NullPrincipal> nullPrin = new NullPrincipal();
|
||||
nsresult rv = nullPrin->Init(attrs);
|
||||
MOZ_RELEASE_ASSERT(NS_SUCCEEDED(rv));
|
||||
return nullPrin.forget();
|
||||
}
|
||||
|
||||
/* static */ already_AddRefed<nsNullPrincipal>
|
||||
nsNullPrincipal::Create(const OriginAttributes& aOriginAttributes, nsIURI* aURI)
|
||||
/* static */ already_AddRefed<NullPrincipal>
|
||||
NullPrincipal::Create(const OriginAttributes& aOriginAttributes, nsIURI* aURI)
|
||||
{
|
||||
RefPtr<nsNullPrincipal> nullPrin = new nsNullPrincipal();
|
||||
RefPtr<NullPrincipal> nullPrin = new NullPrincipal();
|
||||
nsresult rv = nullPrin->Init(aOriginAttributes, aURI);
|
||||
MOZ_RELEASE_ASSERT(NS_SUCCEEDED(rv));
|
||||
|
||||
|
@ -68,7 +68,7 @@ nsNullPrincipal::Create(const OriginAttributes& aOriginAttributes, nsIURI* aURI)
|
|||
}
|
||||
|
||||
nsresult
|
||||
nsNullPrincipal::Init(const OriginAttributes& aOriginAttributes, nsIURI* aURI)
|
||||
NullPrincipal::Init(const OriginAttributes& aOriginAttributes, nsIURI* aURI)
|
||||
{
|
||||
mOriginAttributes = aOriginAttributes;
|
||||
|
||||
|
@ -82,7 +82,7 @@ nsNullPrincipal::Init(const OriginAttributes& aOriginAttributes, nsIURI* aURI)
|
|||
|
||||
mURI = aURI;
|
||||
} else {
|
||||
mURI = nsNullPrincipalURI::Create();
|
||||
mURI = NullPrincipalURI::Create();
|
||||
NS_ENSURE_TRUE(mURI, NS_ERROR_NOT_AVAILABLE);
|
||||
}
|
||||
|
||||
|
@ -92,7 +92,7 @@ nsNullPrincipal::Init(const OriginAttributes& aOriginAttributes, nsIURI* aURI)
|
|||
}
|
||||
|
||||
nsresult
|
||||
nsNullPrincipal::GetScriptLocation(nsACString &aStr)
|
||||
NullPrincipal::GetScriptLocation(nsACString &aStr)
|
||||
{
|
||||
return mURI->GetSpec(aStr);
|
||||
}
|
||||
|
@ -102,14 +102,15 @@ nsNullPrincipal::GetScriptLocation(nsACString &aStr)
|
|||
*/
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNullPrincipal::GetHashValue(uint32_t *aResult)
|
||||
NullPrincipal::GetHashValue(uint32_t *aResult)
|
||||
{
|
||||
*aResult = (NS_PTR_TO_INT32(this) >> 2);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNullPrincipal::SetCsp(nsIContentSecurityPolicy* aCsp) {
|
||||
NullPrincipal::SetCsp(nsIContentSecurityPolicy* aCsp)
|
||||
{
|
||||
// Never destroy an existing CSP on the principal.
|
||||
// This method should only be called in rare cases.
|
||||
|
||||
|
@ -123,19 +124,19 @@ nsNullPrincipal::SetCsp(nsIContentSecurityPolicy* aCsp) {
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNullPrincipal::GetURI(nsIURI** aURI)
|
||||
NullPrincipal::GetURI(nsIURI** aURI)
|
||||
{
|
||||
return NS_EnsureSafeToReturn(mURI, aURI);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNullPrincipal::GetDomain(nsIURI** aDomain)
|
||||
NullPrincipal::GetDomain(nsIURI** aDomain)
|
||||
{
|
||||
return NS_EnsureSafeToReturn(mURI, aDomain);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNullPrincipal::SetDomain(nsIURI* aDomain)
|
||||
NullPrincipal::SetDomain(nsIURI* aDomain)
|
||||
{
|
||||
// I think the right thing to do here is to just throw... Silently failing
|
||||
// seems counterproductive.
|
||||
|
@ -143,13 +144,13 @@ nsNullPrincipal::SetDomain(nsIURI* aDomain)
|
|||
}
|
||||
|
||||
nsresult
|
||||
nsNullPrincipal::GetOriginInternal(nsACString& aOrigin)
|
||||
NullPrincipal::GetOriginInternal(nsACString& aOrigin)
|
||||
{
|
||||
return mURI->GetSpec(aOrigin);
|
||||
}
|
||||
|
||||
bool
|
||||
nsNullPrincipal::MayLoadInternal(nsIURI* aURI)
|
||||
NullPrincipal::MayLoadInternal(nsIURI* aURI)
|
||||
{
|
||||
// Also allow the load if we are the principal of the URI being checked.
|
||||
nsCOMPtr<nsIURIWithPrincipal> uriPrinc = do_QueryInterface(aURI);
|
||||
|
@ -166,14 +167,14 @@ nsNullPrincipal::MayLoadInternal(nsIURI* aURI)
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNullPrincipal::GetBaseDomain(nsACString& aBaseDomain)
|
||||
NullPrincipal::GetBaseDomain(nsACString& aBaseDomain)
|
||||
{
|
||||
// For a null principal, we use our unique uuid as the base domain.
|
||||
return mURI->GetPath(aBaseDomain);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNullPrincipal::GetAddonId(nsAString& aAddonId)
|
||||
NullPrincipal::GetAddonId(nsAString& aAddonId)
|
||||
{
|
||||
aAddonId.Truncate();
|
||||
return NS_OK;
|
||||
|
@ -183,11 +184,11 @@ nsNullPrincipal::GetAddonId(nsAString& aAddonId)
|
|||
* nsISerializable implementation
|
||||
*/
|
||||
NS_IMETHODIMP
|
||||
nsNullPrincipal::Read(nsIObjectInputStream* aStream)
|
||||
NullPrincipal::Read(nsIObjectInputStream* aStream)
|
||||
{
|
||||
// Note - nsNullPrincipal use NS_GENERIC_FACTORY_CONSTRUCTOR_INIT, which means
|
||||
// Note - NullPrincipal use NS_GENERIC_FACTORY_CONSTRUCTOR_INIT, which means
|
||||
// that the Init() method has already been invoked by the time we deserialize.
|
||||
// This is in contrast to nsPrincipal, which uses NS_GENERIC_FACTORY_CONSTRUCTOR,
|
||||
// This is in contrast to ContentPrincipal, which uses NS_GENERIC_FACTORY_CONSTRUCTOR,
|
||||
// in which case ::Read needs to invoke Init().
|
||||
|
||||
nsAutoCString spec;
|
||||
|
@ -210,7 +211,7 @@ nsNullPrincipal::Read(nsIObjectInputStream* aStream)
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNullPrincipal::Write(nsIObjectOutputStream* aStream)
|
||||
NullPrincipal::Write(nsIObjectOutputStream* aStream)
|
||||
{
|
||||
NS_ENSURE_STATE(mURI);
|
||||
|
|
@ -9,8 +9,8 @@
|
|||
* same-origin with anything but themselves.
|
||||
*/
|
||||
|
||||
#ifndef nsNullPrincipal_h__
|
||||
#define nsNullPrincipal_h__
|
||||
#ifndef NullPrincipal_h
|
||||
#define NullPrincipal_h
|
||||
|
||||
#include "nsIPrincipal.h"
|
||||
#include "nsJSPrincipals.h"
|
||||
|
@ -30,13 +30,13 @@ class nsIURI;
|
|||
|
||||
#define NS_NULLPRINCIPAL_SCHEME "moz-nullprincipal"
|
||||
|
||||
class nsNullPrincipal final : public mozilla::BasePrincipal
|
||||
class NullPrincipal final : public mozilla::BasePrincipal
|
||||
{
|
||||
public:
|
||||
// This should only be used by deserialization, and the factory constructor.
|
||||
// Other consumers should use the Create and CreateWithInheritedAttributes
|
||||
// methods.
|
||||
nsNullPrincipal()
|
||||
NullPrincipal()
|
||||
: BasePrincipal(eNullPrincipal)
|
||||
{
|
||||
}
|
||||
|
@ -53,15 +53,16 @@ public:
|
|||
NS_IMETHOD GetAddonId(nsAString& aAddonId) override;
|
||||
nsresult GetOriginInternal(nsACString& aOrigin) override;
|
||||
|
||||
static already_AddRefed<nsNullPrincipal> CreateWithInheritedAttributes(nsIPrincipal* aInheritFrom);
|
||||
static already_AddRefed<NullPrincipal> CreateWithInheritedAttributes(nsIPrincipal* aInheritFrom);
|
||||
|
||||
// Create NullPrincipal with origin attributes from docshell.
|
||||
// If aIsFirstParty is true, and the pref 'privacy.firstparty.isolate' is also
|
||||
// enabled, the mFirstPartyDomain value of the origin attributes will be set
|
||||
// to NULL_PRINCIPAL_FIRST_PARTY_DOMAIN.
|
||||
static already_AddRefed<nsNullPrincipal> CreateWithInheritedAttributes(nsIDocShell* aDocShell, bool aIsFirstParty = false);
|
||||
static already_AddRefed<NullPrincipal>
|
||||
CreateWithInheritedAttributes(nsIDocShell* aDocShell, bool aIsFirstParty = false);
|
||||
|
||||
static already_AddRefed<nsNullPrincipal>
|
||||
static already_AddRefed<NullPrincipal>
|
||||
Create(const mozilla::OriginAttributes& aOriginAttributes = mozilla::OriginAttributes(),
|
||||
nsIURI* aURI = nullptr);
|
||||
|
||||
|
@ -71,7 +72,7 @@ public:
|
|||
virtual nsresult GetScriptLocation(nsACString &aStr) override;
|
||||
|
||||
protected:
|
||||
virtual ~nsNullPrincipal() {}
|
||||
virtual ~NullPrincipal() = default;
|
||||
|
||||
bool SubsumesInternal(nsIPrincipal* aOther, DocumentDomainConsideration aConsideration) override
|
||||
{
|
||||
|
@ -83,4 +84,4 @@ public:
|
|||
nsCOMPtr<nsIURI> mURI;
|
||||
};
|
||||
|
||||
#endif // nsNullPrincipal_h__
|
||||
#endif // NullPrincipal_h__
|
|
@ -4,7 +4,7 @@
|
|||
* 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 "nsNullPrincipalURI.h"
|
||||
#include "NullPrincipalURI.h"
|
||||
|
||||
#include "mozilla/DebugOnly.h"
|
||||
#include "mozilla/MemoryReporting.h"
|
||||
|
@ -16,21 +16,21 @@
|
|||
#include "nsIUUIDGenerator.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//// nsNullPrincipalURI
|
||||
//// NullPrincipalURI
|
||||
|
||||
nsNullPrincipalURI::nsNullPrincipalURI()
|
||||
NullPrincipalURI::NullPrincipalURI()
|
||||
: mPath(mPathBytes, ArrayLength(mPathBytes), ArrayLength(mPathBytes) - 1)
|
||||
{
|
||||
}
|
||||
|
||||
nsNullPrincipalURI::nsNullPrincipalURI(const nsNullPrincipalURI& aOther)
|
||||
NullPrincipalURI::NullPrincipalURI(const NullPrincipalURI& aOther)
|
||||
: mPath(mPathBytes, ArrayLength(mPathBytes), ArrayLength(mPathBytes) - 1)
|
||||
{
|
||||
mPath.Assign(aOther.mPath);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsNullPrincipalURI::Init()
|
||||
NullPrincipalURI::Init()
|
||||
{
|
||||
// FIXME: bug 327161 -- make sure the uuid generator is reseeding-resistant.
|
||||
nsCOMPtr<nsIUUIDGenerator> uuidgen = services::GetUUIDGenerator();
|
||||
|
@ -51,10 +51,10 @@ nsNullPrincipalURI::Init()
|
|||
}
|
||||
|
||||
/* static */
|
||||
already_AddRefed<nsNullPrincipalURI>
|
||||
nsNullPrincipalURI::Create()
|
||||
already_AddRefed<NullPrincipalURI>
|
||||
NullPrincipalURI::Create()
|
||||
{
|
||||
RefPtr<nsNullPrincipalURI> uri = new nsNullPrincipalURI();
|
||||
RefPtr<NullPrincipalURI> uri = new NullPrincipalURI();
|
||||
nsresult rv = uri->Init();
|
||||
NS_ENSURE_SUCCESS(rv, nullptr);
|
||||
return uri.forget();
|
||||
|
@ -63,13 +63,13 @@ nsNullPrincipalURI::Create()
|
|||
static NS_DEFINE_CID(kNullPrincipalURIImplementationCID,
|
||||
NS_NULLPRINCIPALURI_IMPLEMENTATION_CID);
|
||||
|
||||
NS_IMPL_ADDREF(nsNullPrincipalURI)
|
||||
NS_IMPL_RELEASE(nsNullPrincipalURI)
|
||||
NS_IMPL_ADDREF(NullPrincipalURI)
|
||||
NS_IMPL_RELEASE(NullPrincipalURI)
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN(nsNullPrincipalURI)
|
||||
NS_INTERFACE_MAP_BEGIN(NullPrincipalURI)
|
||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIURI)
|
||||
if (aIID.Equals(kNullPrincipalURIImplementationCID))
|
||||
foundInterface = static_cast<nsIURI *>(this);
|
||||
foundInterface = static_cast<nsIURI*>(this);
|
||||
else
|
||||
NS_INTERFACE_MAP_ENTRY(nsIURI)
|
||||
NS_INTERFACE_MAP_ENTRY(nsISizeOf)
|
||||
|
@ -80,23 +80,23 @@ NS_INTERFACE_MAP_END
|
|||
//// nsIURI
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNullPrincipalURI::GetAsciiHost(nsACString &_host)
|
||||
NullPrincipalURI::GetAsciiHost(nsACString& _host)
|
||||
{
|
||||
_host.Truncate();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNullPrincipalURI::GetAsciiHostPort(nsACString &_hostport)
|
||||
NullPrincipalURI::GetAsciiHostPort(nsACString& _hostport)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNullPrincipalURI::GetAsciiSpec(nsACString &_spec)
|
||||
NullPrincipalURI::GetAsciiSpec(nsACString& _spec)
|
||||
{
|
||||
nsAutoCString buffer;
|
||||
// Ignore the return value -- nsNullPrincipalURI::GetSpec() is infallible.
|
||||
// Ignore the return value -- NullPrincipalURI::GetSpec() is infallible.
|
||||
Unused << GetSpec(buffer);
|
||||
// This uses the infallible version of |NS_EscapeURL| as |GetSpec| is
|
||||
// already infallible.
|
||||
|
@ -105,141 +105,141 @@ nsNullPrincipalURI::GetAsciiSpec(nsACString &_spec)
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNullPrincipalURI::GetHost(nsACString &_host)
|
||||
NullPrincipalURI::GetHost(nsACString& _host)
|
||||
{
|
||||
_host.Truncate();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNullPrincipalURI::SetHost(const nsACString &aHost)
|
||||
NullPrincipalURI::SetHost(const nsACString& aHost)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNullPrincipalURI::GetHostPort(nsACString &_host)
|
||||
NullPrincipalURI::GetHostPort(nsACString& _host)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNullPrincipalURI::SetHostPort(const nsACString &aHost)
|
||||
NullPrincipalURI::SetHostPort(const nsACString& aHost)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNullPrincipalURI::SetHostAndPort(const nsACString &aHost)
|
||||
NullPrincipalURI::SetHostAndPort(const nsACString& aHost)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNullPrincipalURI::GetOriginCharset(nsACString &_charset)
|
||||
NullPrincipalURI::GetOriginCharset(nsACString& _charset)
|
||||
{
|
||||
_charset.Truncate();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNullPrincipalURI::GetPassword(nsACString &_password)
|
||||
NullPrincipalURI::GetPassword(nsACString& _password)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNullPrincipalURI::SetPassword(const nsACString &aPassword)
|
||||
NullPrincipalURI::SetPassword(const nsACString& aPassword)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNullPrincipalURI::GetPath(nsACString &_path)
|
||||
NullPrincipalURI::GetPath(nsACString& _path)
|
||||
{
|
||||
_path = mPath;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNullPrincipalURI::SetPath(const nsACString &aPath)
|
||||
NullPrincipalURI::SetPath(const nsACString& aPath)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNullPrincipalURI::GetFilePath(nsACString &aFilePath)
|
||||
NullPrincipalURI::GetFilePath(nsACString& aFilePath)
|
||||
{
|
||||
aFilePath.Truncate();
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNullPrincipalURI::SetFilePath(const nsACString &aFilePath)
|
||||
NullPrincipalURI::SetFilePath(const nsACString& aFilePath)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNullPrincipalURI::GetQuery(nsACString &aQuery)
|
||||
NullPrincipalURI::GetQuery(nsACString& aQuery)
|
||||
{
|
||||
aQuery.Truncate();
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNullPrincipalURI::SetQuery(const nsACString &aQuery)
|
||||
NullPrincipalURI::SetQuery(const nsACString& aQuery)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNullPrincipalURI::GetRef(nsACString &_ref)
|
||||
NullPrincipalURI::GetRef(nsACString& _ref)
|
||||
{
|
||||
_ref.Truncate();
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNullPrincipalURI::SetRef(const nsACString &aRef)
|
||||
NullPrincipalURI::SetRef(const nsACString& aRef)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNullPrincipalURI::GetPrePath(nsACString &_prePath)
|
||||
NullPrincipalURI::GetPrePath(nsACString& _prePath)
|
||||
{
|
||||
_prePath = NS_LITERAL_CSTRING(NS_NULLPRINCIPAL_SCHEME ":");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNullPrincipalURI::GetPort(int32_t *_port)
|
||||
NullPrincipalURI::GetPort(int32_t* _port)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNullPrincipalURI::SetPort(int32_t aPort)
|
||||
NullPrincipalURI::SetPort(int32_t aPort)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNullPrincipalURI::GetScheme(nsACString &_scheme)
|
||||
NullPrincipalURI::GetScheme(nsACString& _scheme)
|
||||
{
|
||||
_scheme = NS_LITERAL_CSTRING(NS_NULLPRINCIPAL_SCHEME);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNullPrincipalURI::SetScheme(const nsACString &aScheme)
|
||||
NullPrincipalURI::SetScheme(const nsACString& aScheme)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNullPrincipalURI::GetSpec(nsACString &_spec)
|
||||
NullPrincipalURI::GetSpec(nsACString& _spec)
|
||||
{
|
||||
_spec = NS_LITERAL_CSTRING(NS_NULLPRINCIPAL_SCHEME ":") + mPath;
|
||||
return NS_OK;
|
||||
|
@ -247,77 +247,77 @@ nsNullPrincipalURI::GetSpec(nsACString &_spec)
|
|||
|
||||
// result may contain unescaped UTF-8 characters
|
||||
NS_IMETHODIMP
|
||||
nsNullPrincipalURI::GetSpecIgnoringRef(nsACString &result)
|
||||
NullPrincipalURI::GetSpecIgnoringRef(nsACString& _result)
|
||||
{
|
||||
return GetSpec(result);
|
||||
return GetSpec(_result);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNullPrincipalURI::GetHasRef(bool *result)
|
||||
NullPrincipalURI::GetHasRef(bool* _result)
|
||||
{
|
||||
*result = false;
|
||||
*_result = false;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNullPrincipalURI::SetSpec(const nsACString &aSpec)
|
||||
NullPrincipalURI::SetSpec(const nsACString& aSpec)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNullPrincipalURI::GetUsername(nsACString &_username)
|
||||
NullPrincipalURI::GetUsername(nsACString& _username)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNullPrincipalURI::SetUsername(const nsACString &aUsername)
|
||||
NullPrincipalURI::SetUsername(const nsACString& aUsername)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNullPrincipalURI::GetUserPass(nsACString &_userPass)
|
||||
NullPrincipalURI::GetUserPass(nsACString& _userPass)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNullPrincipalURI::SetUserPass(const nsACString &aUserPass)
|
||||
NullPrincipalURI::SetUserPass(const nsACString& aUserPass)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNullPrincipalURI::Clone(nsIURI **_newURI)
|
||||
NullPrincipalURI::Clone(nsIURI** _newURI)
|
||||
{
|
||||
nsCOMPtr<nsIURI> uri = new nsNullPrincipalURI(*this);
|
||||
nsCOMPtr<nsIURI> uri = new NullPrincipalURI(*this);
|
||||
uri.forget(_newURI);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNullPrincipalURI::CloneIgnoringRef(nsIURI **_newURI)
|
||||
NullPrincipalURI::CloneIgnoringRef(nsIURI** _newURI)
|
||||
{
|
||||
// GetRef/SetRef not supported by nsNullPrincipalURI, so
|
||||
// GetRef/SetRef not supported by NullPrincipalURI, so
|
||||
// CloneIgnoringRef() is the same as Clone().
|
||||
return Clone(_newURI);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNullPrincipalURI::CloneWithNewRef(const nsACString& newRef, nsIURI **_newURI)
|
||||
NullPrincipalURI::CloneWithNewRef(const nsACString& newRef, nsIURI** _newURI)
|
||||
{
|
||||
// GetRef/SetRef not supported by nsNullPrincipalURI, so
|
||||
// GetRef/SetRef not supported by NullPrincipalURI, so
|
||||
// CloneWithNewRef() is the same as Clone().
|
||||
return Clone(_newURI);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNullPrincipalURI::Equals(nsIURI *aOther, bool *_equals)
|
||||
NullPrincipalURI::Equals(nsIURI* aOther, bool* _equals)
|
||||
{
|
||||
*_equals = false;
|
||||
RefPtr<nsNullPrincipalURI> otherURI;
|
||||
RefPtr<NullPrincipalURI> otherURI;
|
||||
nsresult rv = aOther->QueryInterface(kNullPrincipalURIImplementationCID,
|
||||
getter_AddRefs(otherURI));
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
|
@ -327,23 +327,23 @@ nsNullPrincipalURI::Equals(nsIURI *aOther, bool *_equals)
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNullPrincipalURI::EqualsExceptRef(nsIURI *aOther, bool *_equals)
|
||||
NullPrincipalURI::EqualsExceptRef(nsIURI* aOther, bool* _equals)
|
||||
{
|
||||
// GetRef/SetRef not supported by nsNullPrincipalURI, so
|
||||
// GetRef/SetRef not supported by NullPrincipalURI, so
|
||||
// EqualsExceptRef() is the same as Equals().
|
||||
return Equals(aOther, _equals);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNullPrincipalURI::Resolve(const nsACString &aRelativePath,
|
||||
nsACString &_resolvedURI)
|
||||
NullPrincipalURI::Resolve(const nsACString& aRelativePath,
|
||||
nsACString& _resolvedURI)
|
||||
{
|
||||
_resolvedURI = aRelativePath;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNullPrincipalURI::SchemeIs(const char *aScheme, bool *_schemeIs)
|
||||
NullPrincipalURI::SchemeIs(const char* aScheme, bool* _schemeIs)
|
||||
{
|
||||
*_schemeIs = (0 == nsCRT::strcasecmp(NS_NULLPRINCIPAL_SCHEME, aScheme));
|
||||
return NS_OK;
|
||||
|
@ -353,13 +353,13 @@ nsNullPrincipalURI::SchemeIs(const char *aScheme, bool *_schemeIs)
|
|||
//// nsIIPCSerializableURI
|
||||
|
||||
void
|
||||
nsNullPrincipalURI::Serialize(mozilla::ipc::URIParams &aParams)
|
||||
NullPrincipalURI::Serialize(mozilla::ipc::URIParams& aParams)
|
||||
{
|
||||
aParams = mozilla::ipc::NullPrincipalURIParams();
|
||||
}
|
||||
|
||||
bool
|
||||
nsNullPrincipalURI::Deserialize(const mozilla::ipc::URIParams &aParams)
|
||||
NullPrincipalURI::Deserialize(const mozilla::ipc::URIParams& aParams)
|
||||
{
|
||||
if (aParams.type() != mozilla::ipc::URIParams::TNullPrincipalURIParams) {
|
||||
MOZ_ASSERT_UNREACHABLE("unexpected URIParams type");
|
||||
|
@ -376,13 +376,13 @@ nsNullPrincipalURI::Deserialize(const mozilla::ipc::URIParams &aParams)
|
|||
//// nsISizeOf
|
||||
|
||||
size_t
|
||||
nsNullPrincipalURI::SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
|
||||
NullPrincipalURI::SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
|
||||
{
|
||||
return mPath.SizeOfExcludingThisIfUnshared(aMallocSizeOf);
|
||||
}
|
||||
|
||||
size_t
|
||||
nsNullPrincipalURI::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const {
|
||||
NullPrincipalURI::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
|
||||
{
|
||||
return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf);
|
||||
}
|
||||
|
|
@ -8,8 +8,8 @@
|
|||
* This wraps nsSimpleURI so that all calls to it are done on the main thread.
|
||||
*/
|
||||
|
||||
#ifndef __nsNullPrincipalURI_h__
|
||||
#define __nsNullPrincipalURI_h__
|
||||
#ifndef __NullPrincipalURI_h__
|
||||
#define __NullPrincipalURI_h__
|
||||
|
||||
#include "nsIURI.h"
|
||||
#include "nsISizeOf.h"
|
||||
|
@ -17,7 +17,7 @@
|
|||
#include "mozilla/Attributes.h"
|
||||
#include "nsIIPCSerializableURI.h"
|
||||
#include "mozilla/MemoryReporting.h"
|
||||
#include "nsNullPrincipal.h"
|
||||
#include "NullPrincipal.h"
|
||||
#include "nsID.h"
|
||||
|
||||
// {51fcd543-3b52-41f7-b91b-6b54102236e6}
|
||||
|
@ -25,9 +25,9 @@
|
|||
{0x51fcd543, 0x3b52, 0x41f7, \
|
||||
{0xb9, 0x1b, 0x6b, 0x54, 0x10, 0x22, 0x36, 0xe6} }
|
||||
|
||||
class nsNullPrincipalURI final : public nsIURI
|
||||
, public nsISizeOf
|
||||
, public nsIIPCSerializableURI
|
||||
class NullPrincipalURI final : public nsIURI
|
||||
, public nsISizeOf
|
||||
, public nsIIPCSerializableURI
|
||||
{
|
||||
public:
|
||||
NS_DECL_THREADSAFE_ISUPPORTS
|
||||
|
@ -40,15 +40,15 @@ public:
|
|||
|
||||
// NB: This constructor exists only for deserialization. Everyone
|
||||
// else should call Create.
|
||||
nsNullPrincipalURI();
|
||||
NullPrincipalURI();
|
||||
|
||||
// Returns null on failure.
|
||||
static already_AddRefed<nsNullPrincipalURI> Create();
|
||||
static already_AddRefed<NullPrincipalURI> Create();
|
||||
|
||||
private:
|
||||
nsNullPrincipalURI(const nsNullPrincipalURI& aOther);
|
||||
NullPrincipalURI(const NullPrincipalURI& aOther);
|
||||
|
||||
~nsNullPrincipalURI() {}
|
||||
~NullPrincipalURI() {}
|
||||
|
||||
nsresult Init();
|
||||
|
||||
|
@ -56,4 +56,4 @@ private:
|
|||
nsFixedCString mPath;
|
||||
};
|
||||
|
||||
#endif // __nsNullPrincipalURI_h__
|
||||
#endif // __NullPrincipalURI_h__
|
|
@ -0,0 +1,283 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=2 sw=2 et 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 "mozilla/OriginAttributes.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/dom/URLSearchParams.h"
|
||||
#include "mozilla/dom/quota/QuotaManager.h"
|
||||
#include "nsIEffectiveTLDService.h"
|
||||
#include "nsIURI.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
using dom::URLParams;
|
||||
|
||||
bool OriginAttributes::sFirstPartyIsolation = false;
|
||||
bool OriginAttributes::sRestrictedOpenerAccess = false;
|
||||
|
||||
void
|
||||
OriginAttributes::InitPrefs()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
static bool sInited = false;
|
||||
if (!sInited) {
|
||||
sInited = true;
|
||||
Preferences::AddBoolVarCache(&sFirstPartyIsolation,
|
||||
"privacy.firstparty.isolate");
|
||||
Preferences::AddBoolVarCache(&sRestrictedOpenerAccess,
|
||||
"privacy.firstparty.isolate.restrict_opener_access");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
OriginAttributes::SetFirstPartyDomain(const bool aIsTopLevelDocument,
|
||||
nsIURI* aURI)
|
||||
{
|
||||
bool isFirstPartyEnabled = IsFirstPartyEnabled();
|
||||
|
||||
// If the pref is off or this is not a top level load, bail out.
|
||||
if (!isFirstPartyEnabled || !aIsTopLevelDocument) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIEffectiveTLDService> tldService =
|
||||
do_GetService(NS_EFFECTIVETLDSERVICE_CONTRACTID);
|
||||
MOZ_ASSERT(tldService);
|
||||
if (!tldService) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsAutoCString baseDomain;
|
||||
nsresult rv = tldService->GetBaseDomain(aURI, 0, baseDomain);
|
||||
if (NS_FAILED(rv)) {
|
||||
nsAutoCString scheme;
|
||||
rv = aURI->GetScheme(scheme);
|
||||
NS_ENSURE_SUCCESS_VOID(rv);
|
||||
if (scheme.EqualsLiteral("about")) {
|
||||
baseDomain.AssignLiteral(ABOUT_URI_FIRST_PARTY_DOMAIN);
|
||||
}
|
||||
}
|
||||
|
||||
mFirstPartyDomain = NS_ConvertUTF8toUTF16(baseDomain);
|
||||
}
|
||||
|
||||
void
|
||||
OriginAttributes::SetFirstPartyDomain(const bool aIsTopLevelDocument,
|
||||
const nsACString& aDomain)
|
||||
{
|
||||
bool isFirstPartyEnabled = IsFirstPartyEnabled();
|
||||
|
||||
// If the pref is off or this is not a top level load, bail out.
|
||||
if (!isFirstPartyEnabled || !aIsTopLevelDocument) {
|
||||
return;
|
||||
}
|
||||
|
||||
mFirstPartyDomain = NS_ConvertUTF8toUTF16(aDomain);
|
||||
}
|
||||
|
||||
void
|
||||
OriginAttributes::CreateSuffix(nsACString& aStr) const
|
||||
{
|
||||
URLParams params;
|
||||
nsAutoString value;
|
||||
|
||||
//
|
||||
// Important: While serializing any string-valued attributes, perform a
|
||||
// release-mode assertion to make sure that they don't contain characters that
|
||||
// will break the quota manager when it uses the serialization for file
|
||||
// naming.
|
||||
//
|
||||
|
||||
if (mAppId != nsIScriptSecurityManager::NO_APP_ID) {
|
||||
value.AppendInt(mAppId);
|
||||
params.Set(NS_LITERAL_STRING("appId"), value);
|
||||
}
|
||||
|
||||
if (mInIsolatedMozBrowser) {
|
||||
params.Set(NS_LITERAL_STRING("inBrowser"), NS_LITERAL_STRING("1"));
|
||||
}
|
||||
|
||||
if (mUserContextId != nsIScriptSecurityManager::DEFAULT_USER_CONTEXT_ID) {
|
||||
value.Truncate();
|
||||
value.AppendInt(mUserContextId);
|
||||
params.Set(NS_LITERAL_STRING("userContextId"), value);
|
||||
}
|
||||
|
||||
|
||||
if (mPrivateBrowsingId) {
|
||||
value.Truncate();
|
||||
value.AppendInt(mPrivateBrowsingId);
|
||||
params.Set(NS_LITERAL_STRING("privateBrowsingId"), value);
|
||||
}
|
||||
|
||||
if (!mFirstPartyDomain.IsEmpty()) {
|
||||
MOZ_RELEASE_ASSERT(mFirstPartyDomain.FindCharInSet(dom::quota::QuotaManager::kReplaceChars) == kNotFound);
|
||||
params.Set(NS_LITERAL_STRING("firstPartyDomain"), mFirstPartyDomain);
|
||||
}
|
||||
|
||||
aStr.Truncate();
|
||||
|
||||
params.Serialize(value);
|
||||
if (!value.IsEmpty()) {
|
||||
aStr.AppendLiteral("^");
|
||||
aStr.Append(NS_ConvertUTF16toUTF8(value));
|
||||
}
|
||||
|
||||
// In debug builds, check the whole string for illegal characters too (just in case).
|
||||
#ifdef DEBUG
|
||||
nsAutoCString str;
|
||||
str.Assign(aStr);
|
||||
MOZ_ASSERT(str.FindCharInSet(dom::quota::QuotaManager::kReplaceChars) == kNotFound);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
OriginAttributes::CreateAnonymizedSuffix(nsACString& aStr) const
|
||||
{
|
||||
OriginAttributes attrs = *this;
|
||||
|
||||
if (!attrs.mFirstPartyDomain.IsEmpty()) {
|
||||
attrs.mFirstPartyDomain.AssignLiteral("_anonymizedFirstPartyDomain_");
|
||||
}
|
||||
|
||||
attrs.CreateSuffix(aStr);
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
class MOZ_STACK_CLASS PopulateFromSuffixIterator final
|
||||
: public URLParams::ForEachIterator
|
||||
{
|
||||
public:
|
||||
explicit PopulateFromSuffixIterator(OriginAttributes* aOriginAttributes)
|
||||
: mOriginAttributes(aOriginAttributes)
|
||||
{
|
||||
MOZ_ASSERT(aOriginAttributes);
|
||||
// If mPrivateBrowsingId is passed in as >0 and is not present in the suffix,
|
||||
// then it will remain >0 when it should be 0 according to the suffix. Set to 0 before
|
||||
// iterating to fix this.
|
||||
mOriginAttributes->mPrivateBrowsingId = 0;
|
||||
}
|
||||
|
||||
bool URLParamsIterator(const nsString& aName,
|
||||
const nsString& aValue) override
|
||||
{
|
||||
if (aName.EqualsLiteral("appId")) {
|
||||
nsresult rv;
|
||||
int64_t val = aValue.ToInteger64(&rv);
|
||||
NS_ENSURE_SUCCESS(rv, false);
|
||||
NS_ENSURE_TRUE(val <= UINT32_MAX, false);
|
||||
mOriginAttributes->mAppId = static_cast<uint32_t>(val);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if (aName.EqualsLiteral("inBrowser")) {
|
||||
if (!aValue.EqualsLiteral("1")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
mOriginAttributes->mInIsolatedMozBrowser = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (aName.EqualsLiteral("addonId")) {
|
||||
// No longer supported. Silently ignore so that legacy origin strings
|
||||
// don't cause failures.
|
||||
return true;
|
||||
}
|
||||
|
||||
if (aName.EqualsLiteral("userContextId")) {
|
||||
nsresult rv;
|
||||
int64_t val = aValue.ToInteger64(&rv);
|
||||
NS_ENSURE_SUCCESS(rv, false);
|
||||
NS_ENSURE_TRUE(val <= UINT32_MAX, false);
|
||||
mOriginAttributes->mUserContextId = static_cast<uint32_t>(val);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if (aName.EqualsLiteral("privateBrowsingId")) {
|
||||
nsresult rv;
|
||||
int64_t val = aValue.ToInteger64(&rv);
|
||||
NS_ENSURE_SUCCESS(rv, false);
|
||||
NS_ENSURE_TRUE(val >= 0 && val <= UINT32_MAX, false);
|
||||
mOriginAttributes->mPrivateBrowsingId = static_cast<uint32_t>(val);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if (aName.EqualsLiteral("firstPartyDomain")) {
|
||||
MOZ_RELEASE_ASSERT(mOriginAttributes->mFirstPartyDomain.IsEmpty());
|
||||
mOriginAttributes->mFirstPartyDomain.Assign(aValue);
|
||||
return true;
|
||||
}
|
||||
|
||||
// No other attributes are supported.
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
OriginAttributes* mOriginAttributes;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
bool
|
||||
OriginAttributes::PopulateFromSuffix(const nsACString& aStr)
|
||||
{
|
||||
if (aStr.IsEmpty()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (aStr[0] != '^') {
|
||||
return false;
|
||||
}
|
||||
|
||||
URLParams params;
|
||||
params.ParseInput(Substring(aStr, 1, aStr.Length() - 1));
|
||||
|
||||
PopulateFromSuffixIterator iterator(this);
|
||||
return params.ForEach(iterator);
|
||||
}
|
||||
|
||||
bool
|
||||
OriginAttributes::PopulateFromOrigin(const nsACString& aOrigin,
|
||||
nsACString& aOriginNoSuffix)
|
||||
{
|
||||
// RFindChar is only available on nsCString.
|
||||
nsCString origin(aOrigin);
|
||||
int32_t pos = origin.RFindChar('^');
|
||||
|
||||
if (pos == kNotFound) {
|
||||
aOriginNoSuffix = origin;
|
||||
return true;
|
||||
}
|
||||
|
||||
aOriginNoSuffix = Substring(origin, 0, pos);
|
||||
return PopulateFromSuffix(Substring(origin, pos));
|
||||
}
|
||||
|
||||
void
|
||||
OriginAttributes::SyncAttributesWithPrivateBrowsing(bool aInPrivateBrowsing)
|
||||
{
|
||||
mPrivateBrowsingId = aInPrivateBrowsing ? 1 : 0;
|
||||
}
|
||||
|
||||
/* static */
|
||||
bool
|
||||
OriginAttributes::IsPrivateBrowsing(const nsACString& aOrigin)
|
||||
{
|
||||
nsAutoCString dummy;
|
||||
OriginAttributes attrs;
|
||||
if (NS_WARN_IF(!attrs.PopulateFromOrigin(aOrigin, dummy))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return !!attrs.mPrivateBrowsingId;
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
|
@ -0,0 +1,184 @@
|
|||
/* -*- 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_OriginAttributes_h
|
||||
#define mozilla_OriginAttributes_h
|
||||
|
||||
#include "mozilla/dom/ChromeUtils.h"
|
||||
#include "mozilla/dom/ChromeUtilsBinding.h"
|
||||
#include "nsIScriptSecurityManager.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
class OriginAttributes : public dom::OriginAttributesDictionary
|
||||
{
|
||||
public:
|
||||
OriginAttributes() {}
|
||||
|
||||
OriginAttributes(uint32_t aAppId, bool aInIsolatedMozBrowser)
|
||||
{
|
||||
mAppId = aAppId;
|
||||
mInIsolatedMozBrowser = aInIsolatedMozBrowser;
|
||||
}
|
||||
|
||||
explicit OriginAttributes(const OriginAttributesDictionary& aOther)
|
||||
: OriginAttributesDictionary(aOther)
|
||||
{}
|
||||
|
||||
void SetFirstPartyDomain(const bool aIsTopLevelDocument, nsIURI* aURI);
|
||||
void SetFirstPartyDomain(const bool aIsTopLevelDocument, const nsACString& aDomain);
|
||||
|
||||
enum {
|
||||
STRIP_FIRST_PARTY_DOMAIN = 0x01,
|
||||
STRIP_USER_CONTEXT_ID = 0x02,
|
||||
};
|
||||
|
||||
inline void StripAttributes(uint32_t aFlags)
|
||||
{
|
||||
if (aFlags & STRIP_FIRST_PARTY_DOMAIN) {
|
||||
mFirstPartyDomain.Truncate();
|
||||
}
|
||||
|
||||
if (aFlags & STRIP_USER_CONTEXT_ID) {
|
||||
mUserContextId = nsIScriptSecurityManager::DEFAULT_USER_CONTEXT_ID;
|
||||
}
|
||||
}
|
||||
|
||||
bool operator==(const OriginAttributes& aOther) const
|
||||
{
|
||||
return mAppId == aOther.mAppId &&
|
||||
mInIsolatedMozBrowser == aOther.mInIsolatedMozBrowser &&
|
||||
mUserContextId == aOther.mUserContextId &&
|
||||
mPrivateBrowsingId == aOther.mPrivateBrowsingId &&
|
||||
mFirstPartyDomain == aOther.mFirstPartyDomain;
|
||||
}
|
||||
|
||||
bool operator!=(const OriginAttributes& aOther) const
|
||||
{
|
||||
return !(*this == aOther);
|
||||
}
|
||||
|
||||
// Serializes/Deserializes non-default values into the suffix format, i.e.
|
||||
// |!key1=value1&key2=value2|. If there are no non-default attributes, this
|
||||
// returns an empty string.
|
||||
void CreateSuffix(nsACString& aStr) const;
|
||||
|
||||
// Don't use this method for anything else than debugging!
|
||||
void CreateAnonymizedSuffix(nsACString& aStr) const;
|
||||
|
||||
MOZ_MUST_USE bool PopulateFromSuffix(const nsACString& aStr);
|
||||
|
||||
// Populates the attributes from a string like
|
||||
// |uri!key1=value1&key2=value2| and returns the uri without the suffix.
|
||||
MOZ_MUST_USE bool PopulateFromOrigin(const nsACString& aOrigin,
|
||||
nsACString& aOriginNoSuffix);
|
||||
|
||||
// Helper function to match mIsPrivateBrowsing to existing private browsing
|
||||
// flags. Once all other flags are removed, this can be removed too.
|
||||
void SyncAttributesWithPrivateBrowsing(bool aInPrivateBrowsing);
|
||||
|
||||
// check if "privacy.firstparty.isolate" is enabled.
|
||||
static inline bool IsFirstPartyEnabled()
|
||||
{
|
||||
return sFirstPartyIsolation;
|
||||
}
|
||||
|
||||
// check if the access of window.opener across different FPDs is restricted.
|
||||
// We only restrict the access of window.opener when first party isolation
|
||||
// is enabled and "privacy.firstparty.isolate.restrict_opener_access" is on.
|
||||
static inline bool IsRestrictOpenerAccessForFPI()
|
||||
{
|
||||
// We always want to restrict window.opener if first party isolation is
|
||||
// disabled.
|
||||
return !sFirstPartyIsolation || sRestrictedOpenerAccess;
|
||||
}
|
||||
|
||||
// returns true if the originAttributes suffix has mPrivateBrowsingId value
|
||||
// different than 0.
|
||||
static bool IsPrivateBrowsing(const nsACString& aOrigin);
|
||||
|
||||
static void InitPrefs();
|
||||
|
||||
private:
|
||||
static bool sFirstPartyIsolation;
|
||||
static bool sRestrictedOpenerAccess;
|
||||
};
|
||||
|
||||
class OriginAttributesPattern : public dom::OriginAttributesPatternDictionary
|
||||
{
|
||||
public:
|
||||
// To convert a JSON string to an OriginAttributesPattern, do the following:
|
||||
//
|
||||
// OriginAttributesPattern pattern;
|
||||
// if (!pattern.Init(aJSONString)) {
|
||||
// ... // handle failure.
|
||||
// }
|
||||
OriginAttributesPattern() {}
|
||||
|
||||
explicit OriginAttributesPattern(const OriginAttributesPatternDictionary& aOther)
|
||||
: OriginAttributesPatternDictionary(aOther) {}
|
||||
|
||||
// Performs a match of |aAttrs| against this pattern.
|
||||
bool Matches(const OriginAttributes& aAttrs) const
|
||||
{
|
||||
if (mAppId.WasPassed() && mAppId.Value() != aAttrs.mAppId) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mInIsolatedMozBrowser.WasPassed() && mInIsolatedMozBrowser.Value() != aAttrs.mInIsolatedMozBrowser) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mUserContextId.WasPassed() && mUserContextId.Value() != aAttrs.mUserContextId) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mPrivateBrowsingId.WasPassed() && mPrivateBrowsingId.Value() != aAttrs.mPrivateBrowsingId) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mFirstPartyDomain.WasPassed() && mFirstPartyDomain.Value() != aAttrs.mFirstPartyDomain) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Overlaps(const OriginAttributesPattern& aOther) const
|
||||
{
|
||||
if (mAppId.WasPassed() && aOther.mAppId.WasPassed() &&
|
||||
mAppId.Value() != aOther.mAppId.Value()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mInIsolatedMozBrowser.WasPassed() &&
|
||||
aOther.mInIsolatedMozBrowser.WasPassed() &&
|
||||
mInIsolatedMozBrowser.Value() != aOther.mInIsolatedMozBrowser.Value()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mUserContextId.WasPassed() && aOther.mUserContextId.WasPassed() &&
|
||||
mUserContextId.Value() != aOther.mUserContextId.Value()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mPrivateBrowsingId.WasPassed() && aOther.mPrivateBrowsingId.WasPassed() &&
|
||||
mPrivateBrowsingId.Value() != aOther.mPrivateBrowsingId.Value()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mFirstPartyDomain.WasPassed() && aOther.mFirstPartyDomain.WasPassed() &&
|
||||
mFirstPartyDomain.Value() != aOther.mFirstPartyDomain.Value()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
#endif /* mozilla_OriginAttributes_h */
|
|
@ -6,7 +6,7 @@
|
|||
/* The privileged system principal. */
|
||||
|
||||
#include "nscore.h"
|
||||
#include "nsSystemPrincipal.h"
|
||||
#include "SystemPrincipal.h"
|
||||
#include "nsIComponentManager.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsIURL.h"
|
||||
|
@ -19,28 +19,28 @@
|
|||
#include "nsIScriptSecurityManager.h"
|
||||
#include "pratom.h"
|
||||
|
||||
NS_IMPL_CLASSINFO(nsSystemPrincipal, nullptr,
|
||||
NS_IMPL_CLASSINFO(SystemPrincipal, nullptr,
|
||||
nsIClassInfo::SINGLETON | nsIClassInfo::MAIN_THREAD_ONLY,
|
||||
NS_SYSTEMPRINCIPAL_CID)
|
||||
NS_IMPL_QUERY_INTERFACE_CI(nsSystemPrincipal,
|
||||
NS_IMPL_QUERY_INTERFACE_CI(SystemPrincipal,
|
||||
nsIPrincipal,
|
||||
nsISerializable)
|
||||
NS_IMPL_CI_INTERFACE_GETTER(nsSystemPrincipal,
|
||||
NS_IMPL_CI_INTERFACE_GETTER(SystemPrincipal,
|
||||
nsIPrincipal,
|
||||
nsISerializable)
|
||||
|
||||
#define SYSTEM_PRINCIPAL_SPEC "[System Principal]"
|
||||
|
||||
already_AddRefed<nsSystemPrincipal>
|
||||
nsSystemPrincipal::Create()
|
||||
already_AddRefed<SystemPrincipal>
|
||||
SystemPrincipal::Create()
|
||||
{
|
||||
RefPtr<nsSystemPrincipal> sp = new nsSystemPrincipal();
|
||||
RefPtr<SystemPrincipal> sp = new SystemPrincipal();
|
||||
sp->FinishInit();
|
||||
return sp.forget();
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsSystemPrincipal::GetScriptLocation(nsACString &aStr)
|
||||
SystemPrincipal::GetScriptLocation(nsACString &aStr)
|
||||
{
|
||||
aStr.AssignLiteral(SYSTEM_PRINCIPAL_SPEC);
|
||||
return NS_OK;
|
||||
|
@ -51,35 +51,35 @@ nsSystemPrincipal::GetScriptLocation(nsACString &aStr)
|
|||
///////////////////////////////////////
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSystemPrincipal::GetHashValue(uint32_t *result)
|
||||
SystemPrincipal::GetHashValue(uint32_t *result)
|
||||
{
|
||||
*result = NS_PTR_TO_INT32(this);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSystemPrincipal::GetURI(nsIURI** aURI)
|
||||
SystemPrincipal::GetURI(nsIURI** aURI)
|
||||
{
|
||||
*aURI = nullptr;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsSystemPrincipal::GetOriginInternal(nsACString& aOrigin)
|
||||
SystemPrincipal::GetOriginInternal(nsACString& aOrigin)
|
||||
{
|
||||
aOrigin.AssignLiteral(SYSTEM_PRINCIPAL_SPEC);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSystemPrincipal::GetCsp(nsIContentSecurityPolicy** aCsp)
|
||||
SystemPrincipal::GetCsp(nsIContentSecurityPolicy** aCsp)
|
||||
{
|
||||
*aCsp = nullptr;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSystemPrincipal::SetCsp(nsIContentSecurityPolicy* aCsp)
|
||||
SystemPrincipal::SetCsp(nsIContentSecurityPolicy* aCsp)
|
||||
{
|
||||
// Never destroy an existing CSP on the principal.
|
||||
// This method should only be called in rare cases.
|
||||
|
@ -88,50 +88,50 @@ nsSystemPrincipal::SetCsp(nsIContentSecurityPolicy* aCsp)
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSystemPrincipal::EnsureCSP(nsIDOMDocument* aDocument,
|
||||
nsIContentSecurityPolicy** aCSP)
|
||||
SystemPrincipal::EnsureCSP(nsIDOMDocument* aDocument,
|
||||
nsIContentSecurityPolicy** aCSP)
|
||||
{
|
||||
// CSP on a system principal makes no sense
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSystemPrincipal::GetPreloadCsp(nsIContentSecurityPolicy** aPreloadCSP)
|
||||
SystemPrincipal::GetPreloadCsp(nsIContentSecurityPolicy** aPreloadCSP)
|
||||
{
|
||||
*aPreloadCSP = nullptr;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSystemPrincipal::EnsurePreloadCSP(nsIDOMDocument* aDocument,
|
||||
nsIContentSecurityPolicy** aPreloadCSP)
|
||||
SystemPrincipal::EnsurePreloadCSP(nsIDOMDocument* aDocument,
|
||||
nsIContentSecurityPolicy** aPreloadCSP)
|
||||
{
|
||||
// CSP on a system principal makes no sense
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSystemPrincipal::GetDomain(nsIURI** aDomain)
|
||||
SystemPrincipal::GetDomain(nsIURI** aDomain)
|
||||
{
|
||||
*aDomain = nullptr;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSystemPrincipal::SetDomain(nsIURI* aDomain)
|
||||
SystemPrincipal::SetDomain(nsIURI* aDomain)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSystemPrincipal::GetBaseDomain(nsACString& aBaseDomain)
|
||||
SystemPrincipal::GetBaseDomain(nsACString& aBaseDomain)
|
||||
{
|
||||
// No base domain for chrome.
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSystemPrincipal::GetAddonId(nsAString& aAddonId)
|
||||
SystemPrincipal::GetAddonId(nsAString& aAddonId)
|
||||
{
|
||||
aAddonId.Truncate();
|
||||
return NS_OK;
|
||||
|
@ -142,14 +142,14 @@ nsSystemPrincipal::GetAddonId(nsAString& aAddonId)
|
|||
//////////////////////////////////////////
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSystemPrincipal::Read(nsIObjectInputStream* aStream)
|
||||
SystemPrincipal::Read(nsIObjectInputStream* aStream)
|
||||
{
|
||||
// no-op: CID is sufficient to identify the mSystemPrincipal singleton
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSystemPrincipal::Write(nsIObjectOutputStream* aStream)
|
||||
SystemPrincipal::Write(nsIObjectOutputStream* aStream)
|
||||
{
|
||||
// no-op: CID is sufficient to identify the mSystemPrincipal singleton
|
||||
return NS_OK;
|
|
@ -6,8 +6,8 @@
|
|||
|
||||
/* The privileged system principal. */
|
||||
|
||||
#ifndef nsSystemPrincipal_h__
|
||||
#define nsSystemPrincipal_h__
|
||||
#ifndef SystemPrincipal_h
|
||||
#define SystemPrincipal_h
|
||||
|
||||
#include "nsIPrincipal.h"
|
||||
#include "nsJSPrincipals.h"
|
||||
|
@ -20,15 +20,15 @@
|
|||
#define NS_SYSTEMPRINCIPAL_CONTRACTID "@mozilla.org/systemprincipal;1"
|
||||
|
||||
|
||||
class nsSystemPrincipal final : public mozilla::BasePrincipal
|
||||
class SystemPrincipal final : public mozilla::BasePrincipal
|
||||
{
|
||||
nsSystemPrincipal()
|
||||
SystemPrincipal()
|
||||
: BasePrincipal(eSystemPrincipal)
|
||||
{
|
||||
}
|
||||
|
||||
public:
|
||||
static already_AddRefed<nsSystemPrincipal> Create();
|
||||
static already_AddRefed<SystemPrincipal> Create();
|
||||
|
||||
NS_DECL_NSISERIALIZABLE
|
||||
NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr) override;
|
||||
|
@ -48,9 +48,10 @@ public:
|
|||
virtual nsresult GetScriptLocation(nsACString &aStr) override;
|
||||
|
||||
protected:
|
||||
virtual ~nsSystemPrincipal(void) {}
|
||||
virtual ~SystemPrincipal(void) {}
|
||||
|
||||
bool SubsumesInternal(nsIPrincipal *aOther, DocumentDomainConsideration aConsideration) override
|
||||
bool SubsumesInternal(nsIPrincipal *aOther,
|
||||
DocumentDomainConsideration aConsideration) override
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
@ -61,4 +62,4 @@ protected:
|
|||
}
|
||||
};
|
||||
|
||||
#endif // nsSystemPrincipal_h__
|
||||
#endif // SystemPrincipal_h
|
|
@ -25,29 +25,31 @@ XPIDL_MODULE = 'caps'
|
|||
|
||||
EXPORTS += [
|
||||
'nsJSPrincipals.h',
|
||||
'nsNullPrincipal.h',
|
||||
'nsNullPrincipalURI.h',
|
||||
'NullPrincipal.h',
|
||||
'NullPrincipalURI.h',
|
||||
]
|
||||
|
||||
EXPORTS.mozilla = [
|
||||
'BasePrincipal.h'
|
||||
'BasePrincipal.h',
|
||||
'OriginAttributes.h',
|
||||
]
|
||||
|
||||
SOURCES += [
|
||||
# Compile this separately since nsExceptionHandler.h conflicts
|
||||
# with something from nsNullPrincipal.cpp.
|
||||
# with something from NullPrincipal.cpp.
|
||||
'BasePrincipal.cpp',
|
||||
]
|
||||
|
||||
UNIFIED_SOURCES += [
|
||||
'ContentPrincipal.cpp',
|
||||
'DomainPolicy.cpp',
|
||||
'nsExpandedPrincipal.cpp',
|
||||
'ExpandedPrincipal.cpp',
|
||||
'nsJSPrincipals.cpp',
|
||||
'nsNullPrincipal.cpp',
|
||||
'nsNullPrincipalURI.cpp',
|
||||
'nsPrincipal.cpp',
|
||||
'nsScriptSecurityManager.cpp',
|
||||
'nsSystemPrincipal.cpp',
|
||||
'NullPrincipal.cpp',
|
||||
'NullPrincipalURI.cpp',
|
||||
'OriginAttributes.cpp',
|
||||
'SystemPrincipal.cpp',
|
||||
]
|
||||
|
||||
LOCAL_INCLUDES += [
|
||||
|
|
|
@ -357,12 +357,12 @@ interface nsIPrincipal : nsISerializable
|
|||
};
|
||||
|
||||
/**
|
||||
* If nsSystemPrincipal is too risky to use, but we want a principal to access
|
||||
* more than one origin, nsExpandedPrincipals letting us define an array of
|
||||
* principals it subsumes. So script with an nsExpandedPrincipals will gain
|
||||
* If SystemPrincipal is too risky to use, but we want a principal to access
|
||||
* more than one origin, ExpandedPrincipals letting us define an array of
|
||||
* principals it subsumes. So script with an ExpandedPrincipals will gain
|
||||
* same origin access when at least one of its principals it contains gained
|
||||
* sameorigin acccess. An nsExpandedPrincipal will be subsumed by the system
|
||||
* principal, and by another nsExpandedPrincipal that has all its principals.
|
||||
* sameorigin acccess. An ExpandedPrincipal will be subsumed by the system
|
||||
* principal, and by another ExpandedPrincipal that has all its principals.
|
||||
* It is added for jetpack content-scripts to let them interact with the
|
||||
* content and a well defined set of other domains, without the risk of
|
||||
* leaking out a system principal to the content. See: Bug 734891
|
||||
|
|
|
@ -20,9 +20,8 @@
|
|||
#include "nspr.h"
|
||||
#include "nsJSPrincipals.h"
|
||||
#include "mozilla/BasePrincipal.h"
|
||||
#include "nsSystemPrincipal.h"
|
||||
#include "nsPrincipal.h"
|
||||
#include "nsNullPrincipal.h"
|
||||
#include "SystemPrincipal.h"
|
||||
#include "NullPrincipal.h"
|
||||
#include "DomainPolicy.h"
|
||||
#include "nsXPIDLString.h"
|
||||
#include "nsCRT.h"
|
||||
|
@ -1141,7 +1140,7 @@ nsScriptSecurityManager::CreateNullPrincipal(JS::Handle<JS::Value> aOriginAttrib
|
|||
if (!aOriginAttributes.isObject() || !attrs.Init(aCx, aOriginAttributes)) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
nsCOMPtr<nsIPrincipal> prin = nsNullPrincipal::Create(attrs);
|
||||
nsCOMPtr<nsIPrincipal> prin = NullPrincipal::Create(attrs);
|
||||
prin.forget(aPrincipal);
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -1335,7 +1334,7 @@ nsresult nsScriptSecurityManager::Init()
|
|||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Create our system principal singleton
|
||||
RefPtr<nsSystemPrincipal> system = nsSystemPrincipal::Create();
|
||||
RefPtr<SystemPrincipal> system = SystemPrincipal::Create();
|
||||
|
||||
mSystemPrincipal = system;
|
||||
|
||||
|
@ -1407,13 +1406,13 @@ nsScriptSecurityManager::InitStatics()
|
|||
// Currently this nsGenericFactory constructor is used only from FastLoad
|
||||
// (XPCOM object deserialization) code, when "creating" the system principal
|
||||
// singleton.
|
||||
nsSystemPrincipal *
|
||||
SystemPrincipal *
|
||||
nsScriptSecurityManager::SystemPrincipalSingletonConstructor()
|
||||
{
|
||||
nsIPrincipal *sysprin = nullptr;
|
||||
if (gScriptSecMan)
|
||||
NS_ADDREF(sysprin = gScriptSecMan->mSystemPrincipal);
|
||||
return static_cast<nsSystemPrincipal*>(sysprin);
|
||||
return static_cast<SystemPrincipal*>(sysprin);
|
||||
}
|
||||
|
||||
struct IsWhitespace {
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
class nsCString;
|
||||
class nsIIOService;
|
||||
class nsIStringBundle;
|
||||
class nsSystemPrincipal;
|
||||
class SystemPrincipal;
|
||||
|
||||
namespace mozilla {
|
||||
class OriginAttributes;
|
||||
|
@ -55,7 +55,7 @@ public:
|
|||
// Invoked exactly once, by XPConnect.
|
||||
static void InitStatics();
|
||||
|
||||
static nsSystemPrincipal*
|
||||
static SystemPrincipal*
|
||||
SystemPrincipalSingletonConstructor();
|
||||
|
||||
/**
|
||||
|
|
|
@ -50,7 +50,7 @@ var JsonView = {
|
|||
* in the parent process.
|
||||
*/
|
||||
onSave: function (message) {
|
||||
JsonViewUtils.getTargetFile(file => {
|
||||
JsonViewUtils.getTargetFile().then(file => {
|
||||
if (file) {
|
||||
JsonViewUtils.saveToFile(file, message.data);
|
||||
}
|
||||
|
|
|
@ -120,7 +120,7 @@
|
|||
#include "nsITimer.h"
|
||||
#include "nsISHistoryInternal.h"
|
||||
#include "nsIPrincipal.h"
|
||||
#include "nsNullPrincipal.h"
|
||||
#include "NullPrincipal.h"
|
||||
#include "nsISHEntry.h"
|
||||
#include "nsIWindowWatcher.h"
|
||||
#include "nsIPromptFactory.h"
|
||||
|
@ -1501,7 +1501,7 @@ nsDocShell::LoadURI(nsIURI* aURI,
|
|||
//
|
||||
// We didn't inherit OriginAttributes here as ExpandedPrincipal doesn't
|
||||
// have origin attributes.
|
||||
principalToInherit = nsNullPrincipal::CreateWithInheritedAttributes(this);
|
||||
principalToInherit = NullPrincipal::CreateWithInheritedAttributes(this);
|
||||
inheritPrincipal = false;
|
||||
}
|
||||
}
|
||||
|
@ -1514,7 +1514,7 @@ nsDocShell::LoadURI(nsIURI* aURI,
|
|||
inheritPrincipal = false;
|
||||
// If aFirstParty is true and the pref 'privacy.firstparty.isolate' is
|
||||
// enabled, we will set firstPartyDomain on the origin attributes.
|
||||
principalToInherit = nsNullPrincipal::CreateWithInheritedAttributes(this, aFirstParty);
|
||||
principalToInherit = NullPrincipal::CreateWithInheritedAttributes(this, aFirstParty);
|
||||
}
|
||||
|
||||
// If the triggeringPrincipal is not passed explicitly, we first try to create
|
||||
|
@ -8127,9 +8127,9 @@ nsDocShell::CreateAboutBlankContentViewer(nsIPrincipal* aPrincipal,
|
|||
nsCOMPtr<nsIPrincipal> principal;
|
||||
if (mSandboxFlags & SANDBOXED_ORIGIN) {
|
||||
if (aPrincipal) {
|
||||
principal = nsNullPrincipal::CreateWithInheritedAttributes(aPrincipal);
|
||||
principal = NullPrincipal::CreateWithInheritedAttributes(aPrincipal);
|
||||
} else {
|
||||
principal = nsNullPrincipal::CreateWithInheritedAttributes(this);
|
||||
principal = NullPrincipal::CreateWithInheritedAttributes(this);
|
||||
}
|
||||
} else {
|
||||
principal = aPrincipal;
|
||||
|
@ -12409,13 +12409,13 @@ nsDocShell::AddToSessionHistory(nsIURI* aURI, nsIChannel* aChannel,
|
|||
if (!principalToInherit) {
|
||||
if (loadInfo->GetLoadingSandboxed()) {
|
||||
if (loadInfo->LoadingPrincipal()) {
|
||||
principalToInherit = nsNullPrincipal::CreateWithInheritedAttributes(
|
||||
principalToInherit = NullPrincipal::CreateWithInheritedAttributes(
|
||||
loadInfo->LoadingPrincipal());
|
||||
} else {
|
||||
// get the OriginAttributes
|
||||
OriginAttributes attrs;
|
||||
loadInfo->GetOriginAttributes(&attrs);
|
||||
principalToInherit = nsNullPrincipal::Create(attrs);
|
||||
principalToInherit = NullPrincipal::Create(attrs);
|
||||
}
|
||||
} else {
|
||||
principalToInherit = loadInfo->PrincipalToInherit();
|
||||
|
@ -12606,7 +12606,7 @@ nsDocShell::LoadHistoryEntry(nsISHEntry* aEntry, uint32_t aLoadType)
|
|||
// Ensure that we have a triggeringPrincipal. Otherwise javascript:
|
||||
// URIs will pick it up from the about:blank page we just loaded,
|
||||
// and we don't really want even that in this case.
|
||||
triggeringPrincipal = nsNullPrincipal::CreateWithInheritedAttributes(this);
|
||||
triggeringPrincipal = NullPrincipal::CreateWithInheritedAttributes(this);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -14378,7 +14378,7 @@ nsDocShell::GetPrintPreview(nsIWebBrowserPrint** aPrintPreview)
|
|||
// we QI the mContentViewer if the current URI is either about:blank
|
||||
// or about:printpreview.
|
||||
Stop(nsIWebNavigation::STOP_ALL);
|
||||
nsCOMPtr<nsIPrincipal> principal = nsNullPrincipal::CreateWithInheritedAttributes(this);
|
||||
nsCOMPtr<nsIPrincipal> principal = NullPrincipal::CreateWithInheritedAttributes(this);
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
NS_NewURI(getter_AddRefs(uri), NS_LITERAL_CSTRING("about:printpreview"));
|
||||
nsresult rv = CreateAboutBlankContentViewer(principal, uri);
|
||||
|
|
|
@ -1623,18 +1623,24 @@ public:
|
|||
InitOrigin(PersistenceType aPersistenceType,
|
||||
const nsACString& aGroup,
|
||||
const nsACString& aOrigin,
|
||||
const AtomicBool& aCanceled,
|
||||
UsageInfo* aUsageInfo) override
|
||||
{
|
||||
if (!aUsageInfo) {
|
||||
return NS_OK;
|
||||
}
|
||||
return GetUsageForOrigin(aPersistenceType, aGroup, aOrigin, aUsageInfo);
|
||||
return GetUsageForOrigin(aPersistenceType,
|
||||
aGroup,
|
||||
aOrigin,
|
||||
aCanceled,
|
||||
aUsageInfo);
|
||||
}
|
||||
|
||||
nsresult
|
||||
GetUsageForOrigin(PersistenceType aPersistenceType,
|
||||
const nsACString& aGroup,
|
||||
const nsACString& aOrigin,
|
||||
const AtomicBool& aCanceled,
|
||||
UsageInfo* aUsageInfo) override
|
||||
{
|
||||
QuotaManager* qm = QuotaManager::Get();
|
||||
|
@ -1658,7 +1664,7 @@ public:
|
|||
|
||||
bool hasMore;
|
||||
while (NS_SUCCEEDED((rv = entries->HasMoreElements(&hasMore))) &&
|
||||
hasMore && !aUsageInfo->Canceled()) {
|
||||
hasMore && !aCanceled) {
|
||||
nsCOMPtr<nsISupports> entry;
|
||||
rv = entries->GetNext(getter_AddRefs(entry));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
#include "nsDOMJSUtils.h"
|
||||
#include "nsError.h"
|
||||
#include "nsPIDOMWindow.h"
|
||||
#include "nsNullPrincipal.h"
|
||||
#include "NullPrincipal.h"
|
||||
#include "mozilla/LoadInfo.h"
|
||||
#include "mozilla/dom/BindingUtils.h"
|
||||
#include "mozilla/dom/ScriptSettings.h"
|
||||
|
@ -345,7 +345,7 @@ DOMParser::Init(nsIPrincipal* principal, nsIURI* documentURI,
|
|||
// Don't give DOMParsers the system principal. Use a null
|
||||
// principal instead.
|
||||
mOriginalPrincipalWasSystem = true;
|
||||
mPrincipal = nsNullPrincipal::Create();
|
||||
mPrincipal = NullPrincipal::Create();
|
||||
|
||||
if (!mDocumentURI) {
|
||||
rv = mPrincipal->GetURI(getter_AddRefs(mDocumentURI));
|
||||
|
@ -456,7 +456,7 @@ DOMParser::SetUpDocument(DocumentFlavor aFlavor, nsIDOMDocument** aResult)
|
|||
NS_ENSURE_TRUE(!mAttemptedInit, NS_ERROR_NOT_INITIALIZED);
|
||||
AttemptedInitMarker marker(&mAttemptedInit);
|
||||
|
||||
nsCOMPtr<nsIPrincipal> prin = nsNullPrincipal::Create();
|
||||
nsCOMPtr<nsIPrincipal> prin = NullPrincipal::Create();
|
||||
rv = Init(prin, nullptr, nullptr, scriptHandlingObject);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
#include "nsGlobalWindow.h"
|
||||
#include "mozilla/Likely.h"
|
||||
#include "nsCycleCollectionParticipant.h"
|
||||
#include "nsNullPrincipal.h"
|
||||
#include "NullPrincipal.h"
|
||||
#include "ScriptSettings.h"
|
||||
#include "mozilla/Unused.h"
|
||||
#include "mozilla/dom/LocationBinding.h"
|
||||
|
@ -164,7 +164,7 @@ Location::CheckURL(nsIURI* aURI, nsIDocShellLoadInfo** aLoadInfo)
|
|||
sourceURI = docCurrentURI;
|
||||
}
|
||||
else {
|
||||
// Use principalURI as long as it is not an nsNullPrincipalURI. We
|
||||
// Use principalURI as long as it is not an NullPrincipalURI. We
|
||||
// could add a method such as GetReferrerURI to principals to make this
|
||||
// cleaner, but given that we need to start using Source Browsing
|
||||
// Context for referrer (see Bug 960639) this may be wasted effort at
|
||||
|
|
|
@ -164,7 +164,7 @@ ScriptSettingsStackEntry::~ScriptSettingsStackEntry()
|
|||
// If the entry or incumbent global ends up being something that the subject
|
||||
// principal doesn't subsume, we don't want to use it. This never happens on
|
||||
// the web, but can happen with asymmetric privilege relationships (i.e.
|
||||
// nsExpandedPrincipal and System Principal).
|
||||
// ExpandedPrincipal and System Principal).
|
||||
//
|
||||
// The most correct thing to use instead would be the topmost global on the
|
||||
// callstack whose principal is subsumed by the subject principal. But that's
|
||||
|
|
|
@ -182,7 +182,7 @@
|
|||
#include "nsNetCID.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsNodeInfoManager.h"
|
||||
#include "nsNullPrincipal.h"
|
||||
#include "NullPrincipal.h"
|
||||
#include "nsParserCIID.h"
|
||||
#include "nsParserConstants.h"
|
||||
#include "nsPIDOMWindow.h"
|
||||
|
@ -514,7 +514,7 @@ nsContentUtils::Init()
|
|||
sSecurityManager->GetSystemPrincipal(&sSystemPrincipal);
|
||||
MOZ_ASSERT(sSystemPrincipal);
|
||||
|
||||
RefPtr<nsNullPrincipal> nullPrincipal = nsNullPrincipal::Create();
|
||||
RefPtr<NullPrincipal> nullPrincipal = NullPrincipal::Create();
|
||||
if (!nullPrincipal) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
@ -4790,7 +4790,7 @@ nsContentUtils::ConvertToPlainText(const nsAString& aSourceBuffer,
|
|||
{
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
NS_NewURI(getter_AddRefs(uri), "about:blank");
|
||||
nsCOMPtr<nsIPrincipal> principal = nsNullPrincipal::Create();
|
||||
nsCOMPtr<nsIPrincipal> principal = NullPrincipal::Create();
|
||||
nsCOMPtr<nsIDOMDocument> domDocument;
|
||||
nsresult rv = NS_NewDOMDocument(getter_AddRefs(domDocument),
|
||||
EmptyString(),
|
||||
|
|
|
@ -1578,12 +1578,12 @@ public:
|
|||
static bool IsSystemPrincipal(nsIPrincipal* aPrincipal);
|
||||
|
||||
/**
|
||||
* Returns true if aPrincipal is an nsExpandedPrincipal.
|
||||
* Returns true if aPrincipal is an ExpandedPrincipal.
|
||||
*/
|
||||
static bool IsExpandedPrincipal(nsIPrincipal* aPrincipal);
|
||||
|
||||
/**
|
||||
* Returns true if aPrincipal is the system or an nsExpandedPrincipal.
|
||||
* Returns true if aPrincipal is the system or an ExpandedPrincipal.
|
||||
*/
|
||||
static bool IsSystemOrExpandedPrincipal(nsIPrincipal* aPrincipal)
|
||||
{
|
||||
|
|
|
@ -106,7 +106,7 @@
|
|||
#include "nsIScriptSecurityManager.h"
|
||||
#include "nsIPermissionManager.h"
|
||||
#include "nsIPrincipal.h"
|
||||
#include "nsNullPrincipal.h"
|
||||
#include "NullPrincipal.h"
|
||||
|
||||
#include "nsIDOMWindow.h"
|
||||
#include "nsPIDOMWindow.h"
|
||||
|
@ -2723,7 +2723,7 @@ nsDocument::InitCSP(nsIChannel* aChannel)
|
|||
if (cspSandboxFlags & SANDBOXED_ORIGIN) {
|
||||
// If the new CSP sandbox flags do not have the allow-same-origin flag
|
||||
// reset the document principal to a null principal
|
||||
principal = nsNullPrincipal::Create();
|
||||
principal = NullPrincipal::Create();
|
||||
SetPrincipal(principal);
|
||||
}
|
||||
|
||||
|
|
|
@ -50,7 +50,7 @@
|
|||
#include "nsIEditor.h"
|
||||
#include "nsIMozBrowserFrame.h"
|
||||
#include "nsISHistory.h"
|
||||
#include "nsNullPrincipal.h"
|
||||
#include "NullPrincipal.h"
|
||||
#include "nsIScriptError.h"
|
||||
#include "nsGlobalWindow.h"
|
||||
#include "nsPIWindowRoot.h"
|
||||
|
@ -98,7 +98,7 @@
|
|||
#include "mozilla/dom/Promise.h"
|
||||
#include "mozilla/dom/PromiseNativeHandler.h"
|
||||
|
||||
#include "nsPrincipal.h"
|
||||
#include "ContentPrincipal.h"
|
||||
|
||||
#ifdef XP_WIN
|
||||
#include "mozilla/plugins/PPluginWidgetParent.h"
|
||||
|
@ -831,7 +831,7 @@ nsFrameLoader::ReallyStartLoadingInternal()
|
|||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
// Use referrer as long as it is not an nsNullPrincipalURI.
|
||||
// Use referrer as long as it is not an NullPrincipalURI.
|
||||
// We could add a method such as GetReferrerURI to principals to make this
|
||||
// cleaner, but given that we need to start using Source Browsing Context for
|
||||
// referrer (see Bug 960639) this may be wasted effort at this stage.
|
||||
|
|
|
@ -13077,9 +13077,14 @@ nsGlobalWindow::RunTimeoutHandler(Timeout* aTimeout,
|
|||
AutoEntryScript aes(this, reason, true);
|
||||
JS::CompileOptions options(aes.cx());
|
||||
options.setFileAndLine(filename, lineNo).setVersion(JSVERSION_DEFAULT);
|
||||
options.setNoScriptRval(true);
|
||||
JS::Rooted<JSObject*> global(aes.cx(), FastGetGlobalJSObject());
|
||||
nsresult rv =
|
||||
nsJSUtils::EvaluateString(aes.cx(), script, global, options);
|
||||
nsresult rv = NS_OK;
|
||||
{
|
||||
nsJSUtils::ExecutionContext exec(aes.cx(), global);
|
||||
rv = exec.CompileAndExec(options, script);
|
||||
}
|
||||
|
||||
if (rv == NS_SUCCESS_DOM_SCRIPT_EVALUATION_THREW_UNCATCHABLE) {
|
||||
abortIntervalHandler = true;
|
||||
}
|
||||
|
|
|
@ -123,156 +123,162 @@ nsJSUtils::CompileFunction(AutoJSAPI& jsapi,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsJSUtils::EvaluateString(JSContext* aCx,
|
||||
const nsAString& aScript,
|
||||
JS::Handle<JSObject*> aEvaluationGlobal,
|
||||
JS::CompileOptions& aCompileOptions,
|
||||
const EvaluateOptions& aEvaluateOptions,
|
||||
JS::MutableHandle<JS::Value> aRetValue)
|
||||
static nsresult
|
||||
EvaluationExceptionToNSResult(JSContext* aCx)
|
||||
{
|
||||
const nsPromiseFlatString& flatScript = PromiseFlatString(aScript);
|
||||
JS::SourceBufferHolder srcBuf(flatScript.get(), aScript.Length(),
|
||||
JS::SourceBufferHolder::NoOwnership);
|
||||
return EvaluateString(aCx, srcBuf, aEvaluationGlobal, aCompileOptions,
|
||||
aEvaluateOptions, aRetValue, nullptr);
|
||||
if (JS_IsExceptionPending(aCx)) {
|
||||
return NS_SUCCESS_DOM_SCRIPT_EVALUATION_THREW;
|
||||
}
|
||||
return NS_SUCCESS_DOM_SCRIPT_EVALUATION_THREW_UNCATCHABLE;
|
||||
}
|
||||
|
||||
nsJSUtils::ExecutionContext::ExecutionContext(JSContext* aCx,
|
||||
JS::Handle<JSObject*> aGlobal)
|
||||
: mSamplerRAII("nsJSUtils::ExecutionContext", /* PROFILER_LABEL */
|
||||
js::ProfileEntry::Category::JS, __LINE__)
|
||||
, mCx(aCx)
|
||||
, mCompartment(aCx, aGlobal)
|
||||
, mRetValue(aCx)
|
||||
, mScopeChain(aCx)
|
||||
, mRv(NS_OK)
|
||||
, mSkip(false)
|
||||
, mCoerceToString(false)
|
||||
#ifdef DEBUG
|
||||
, mWantsReturnValue(false)
|
||||
, mExpectScopeChain(false)
|
||||
#endif
|
||||
{
|
||||
MOZ_ASSERT(aCx == nsContentUtils::GetCurrentJSContext());
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(nsContentUtils::IsInMicroTask());
|
||||
MOZ_ASSERT(mRetValue.isUndefined());
|
||||
|
||||
MOZ_ASSERT(js::GetGlobalForObjectCrossCompartment(aGlobal) == aGlobal);
|
||||
if (MOZ_UNLIKELY(!xpc::Scriptability::Get(aGlobal).Allowed())) {
|
||||
mSkip = true;
|
||||
mRv = NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsJSUtils::ExecutionContext::SetScopeChain(
|
||||
const JS::AutoObjectVector& aScopeChain)
|
||||
{
|
||||
if (mSkip) {
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
mExpectScopeChain = true;
|
||||
#endif
|
||||
// Now make sure to wrap the scope chain into the right compartment.
|
||||
if (!mScopeChain.reserve(aScopeChain.length())) {
|
||||
mSkip = true;
|
||||
mRv = NS_ERROR_OUT_OF_MEMORY;
|
||||
return;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < aScopeChain.length(); ++i) {
|
||||
JS::ExposeObjectToActiveJS(aScopeChain[i]);
|
||||
mScopeChain.infallibleAppend(aScopeChain[i]);
|
||||
if (!JS_WrapObject(mCx, mScopeChain[i])) {
|
||||
mSkip = true;
|
||||
mRv = NS_ERROR_OUT_OF_MEMORY;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsJSUtils::EvaluateString(JSContext* aCx,
|
||||
JS::SourceBufferHolder& aSrcBuf,
|
||||
JS::Handle<JSObject*> aEvaluationGlobal,
|
||||
JS::CompileOptions& aCompileOptions,
|
||||
const EvaluateOptions& aEvaluateOptions,
|
||||
JS::MutableHandle<JS::Value> aRetValue,
|
||||
void **aOffThreadToken)
|
||||
nsJSUtils::ExecutionContext::SyncAndExec(void **aOffThreadToken,
|
||||
JS::MutableHandle<JSScript*> aScript)
|
||||
{
|
||||
PROFILER_LABEL("nsJSUtils", "EvaluateString",
|
||||
js::ProfileEntry::Category::JS);
|
||||
if (mSkip) {
|
||||
return mRv;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(!mWantsReturnValue);
|
||||
MOZ_ASSERT(!mExpectScopeChain);
|
||||
aScript.set(JS::FinishOffThreadScript(mCx, *aOffThreadToken));
|
||||
*aOffThreadToken = nullptr; // Mark the token as having been finished.
|
||||
if (!aScript || !JS_ExecuteScript(mCx, mScopeChain, aScript)) {
|
||||
mSkip = true;
|
||||
mRv = EvaluationExceptionToNSResult(mCx);
|
||||
return mRv;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsJSUtils::ExecutionContext::CompileAndExec(JS::CompileOptions& aCompileOptions,
|
||||
JS::SourceBufferHolder& aSrcBuf)
|
||||
{
|
||||
if (mSkip) {
|
||||
return mRv;
|
||||
}
|
||||
|
||||
MOZ_ASSERT_IF(aCompileOptions.versionSet,
|
||||
aCompileOptions.version != JSVERSION_UNKNOWN);
|
||||
MOZ_ASSERT_IF(aEvaluateOptions.coerceToString, !aCompileOptions.noScriptRval);
|
||||
MOZ_ASSERT(aCx == nsContentUtils::GetCurrentJSContext());
|
||||
MOZ_ASSERT(aSrcBuf.get());
|
||||
MOZ_ASSERT(js::GetGlobalForObjectCrossCompartment(aEvaluationGlobal) ==
|
||||
aEvaluationGlobal);
|
||||
MOZ_ASSERT_IF(aOffThreadToken, aCompileOptions.noScriptRval);
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(nsContentUtils::IsInMicroTask());
|
||||
|
||||
// Unfortunately, the JS engine actually compiles scripts with a return value
|
||||
// in a different, less efficient way. Furthermore, it can't JIT them in many
|
||||
// cases. So we need to be explicitly told whether the caller cares about the
|
||||
// return value. Callers can do this by calling the other overload of
|
||||
// EvaluateString() which calls this function with
|
||||
// aCompileOptions.noScriptRval set to true.
|
||||
aRetValue.setUndefined();
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
NS_ENSURE_TRUE(xpc::Scriptability::Get(aEvaluationGlobal).Allowed(), NS_OK);
|
||||
|
||||
bool ok = true;
|
||||
// Scope the JSAutoCompartment so that we can later wrap the return value
|
||||
// into the caller's cx.
|
||||
{
|
||||
JSAutoCompartment ac(aCx, aEvaluationGlobal);
|
||||
|
||||
// Now make sure to wrap the scope chain into the right compartment.
|
||||
JS::AutoObjectVector scopeChain(aCx);
|
||||
if (!scopeChain.reserve(aEvaluateOptions.scopeChain.length())) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < aEvaluateOptions.scopeChain.length(); ++i) {
|
||||
JS::ExposeObjectToActiveJS(aEvaluateOptions.scopeChain[i]);
|
||||
scopeChain.infallibleAppend(aEvaluateOptions.scopeChain[i]);
|
||||
if (!JS_WrapObject(aCx, scopeChain[i])) {
|
||||
ok = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ok && aOffThreadToken) {
|
||||
JS::Rooted<JSScript*>
|
||||
script(aCx, JS::FinishOffThreadScript(aCx, *aOffThreadToken));
|
||||
*aOffThreadToken = nullptr; // Mark the token as having been finished.
|
||||
if (script) {
|
||||
ok = JS_ExecuteScript(aCx, scopeChain, script);
|
||||
} else {
|
||||
ok = false;
|
||||
}
|
||||
} else if (ok) {
|
||||
ok = JS::Evaluate(aCx, scopeChain, aCompileOptions, aSrcBuf, aRetValue);
|
||||
}
|
||||
|
||||
if (ok && aEvaluateOptions.coerceToString && !aRetValue.isUndefined()) {
|
||||
JS::Rooted<JS::Value> value(aCx, aRetValue);
|
||||
JSString* str = JS::ToString(aCx, value);
|
||||
ok = !!str;
|
||||
aRetValue.set(ok ? JS::StringValue(str) : JS::UndefinedValue());
|
||||
}
|
||||
MOZ_ASSERT(mRetValue.isUndefined());
|
||||
#ifdef DEBUG
|
||||
mWantsReturnValue = !aCompileOptions.noScriptRval;
|
||||
#endif
|
||||
MOZ_ASSERT(!mCoerceToString || mWantsReturnValue);
|
||||
if (!JS::Evaluate(mCx, mScopeChain, aCompileOptions, aSrcBuf, &mRetValue)) {
|
||||
mSkip = true;
|
||||
mRv = EvaluationExceptionToNSResult(mCx);
|
||||
return mRv;
|
||||
}
|
||||
|
||||
if (!ok) {
|
||||
if (JS_IsExceptionPending(aCx)) {
|
||||
rv = NS_SUCCESS_DOM_SCRIPT_EVALUATION_THREW;
|
||||
} else {
|
||||
rv = NS_SUCCESS_DOM_SCRIPT_EVALUATION_THREW_UNCATCHABLE;
|
||||
}
|
||||
|
||||
if (!aCompileOptions.noScriptRval) {
|
||||
aRetValue.setUndefined();
|
||||
}
|
||||
}
|
||||
|
||||
// Wrap the return value into whatever compartment aCx was in.
|
||||
if (ok && !aCompileOptions.noScriptRval) {
|
||||
if (!JS_WrapValue(aCx, aRetValue)) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsJSUtils::EvaluateString(JSContext* aCx,
|
||||
JS::SourceBufferHolder& aSrcBuf,
|
||||
JS::Handle<JSObject*> aEvaluationGlobal,
|
||||
JS::CompileOptions& aCompileOptions,
|
||||
const EvaluateOptions& aEvaluateOptions,
|
||||
JS::MutableHandle<JS::Value> aRetValue)
|
||||
nsJSUtils::ExecutionContext::CompileAndExec(JS::CompileOptions& aCompileOptions,
|
||||
const nsAString& aScript)
|
||||
{
|
||||
return EvaluateString(aCx, aSrcBuf, aEvaluationGlobal, aCompileOptions,
|
||||
aEvaluateOptions, aRetValue, nullptr);
|
||||
if (mSkip) {
|
||||
return mRv;
|
||||
}
|
||||
|
||||
const nsPromiseFlatString& flatScript = PromiseFlatString(aScript);
|
||||
JS::SourceBufferHolder srcBuf(flatScript.get(), aScript.Length(),
|
||||
JS::SourceBufferHolder::NoOwnership);
|
||||
return CompileAndExec(aCompileOptions, srcBuf);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsJSUtils::EvaluateString(JSContext* aCx,
|
||||
const nsAString& aScript,
|
||||
JS::Handle<JSObject*> aEvaluationGlobal,
|
||||
JS::CompileOptions& aCompileOptions)
|
||||
nsJSUtils::ExecutionContext::ExtractReturnValue(JS::MutableHandle<JS::Value> aRetValue)
|
||||
{
|
||||
EvaluateOptions options(aCx);
|
||||
aCompileOptions.setNoScriptRval(true);
|
||||
JS::RootedValue unused(aCx);
|
||||
return EvaluateString(aCx, aScript, aEvaluationGlobal, aCompileOptions,
|
||||
options, &unused);
|
||||
}
|
||||
MOZ_ASSERT(aRetValue.isUndefined());
|
||||
if (mSkip) {
|
||||
// Repeat earlier result, as NS_SUCCESS_DOM_SCRIPT_EVALUATION_THREW are not
|
||||
// failures cases.
|
||||
#ifdef DEBUG
|
||||
mWantsReturnValue = false;
|
||||
#endif
|
||||
return mRv;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsJSUtils::EvaluateString(JSContext* aCx,
|
||||
JS::SourceBufferHolder& aSrcBuf,
|
||||
JS::Handle<JSObject*> aEvaluationGlobal,
|
||||
JS::CompileOptions& aCompileOptions,
|
||||
void **aOffThreadToken)
|
||||
{
|
||||
EvaluateOptions options(aCx);
|
||||
aCompileOptions.setNoScriptRval(true);
|
||||
JS::RootedValue unused(aCx);
|
||||
return EvaluateString(aCx, aSrcBuf, aEvaluationGlobal, aCompileOptions,
|
||||
options, &unused, aOffThreadToken);
|
||||
MOZ_ASSERT(mWantsReturnValue);
|
||||
#ifdef DEBUG
|
||||
mWantsReturnValue = false;
|
||||
#endif
|
||||
if (mCoerceToString && !mRetValue.isUndefined()) {
|
||||
JSString* str = JS::ToString(mCx, mRetValue);
|
||||
if (!str) {
|
||||
// ToString can be a function call, so an exception can be raised while
|
||||
// executing the function.
|
||||
mSkip = true;
|
||||
return EvaluationExceptionToNSResult(mCx);
|
||||
}
|
||||
mRetValue.set(JS::StringValue(str));
|
||||
}
|
||||
|
||||
aRetValue.set(mRetValue);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
#include "mozilla/Assertions.h"
|
||||
|
||||
#include "GeckoProfiler.h"
|
||||
#include "jsapi.h"
|
||||
#include "jsfriendapi.h"
|
||||
#include "js/Conversions.h"
|
||||
|
@ -64,52 +65,95 @@ public:
|
|||
const nsAString& aBody,
|
||||
JSObject** aFunctionObject);
|
||||
|
||||
struct MOZ_STACK_CLASS EvaluateOptions {
|
||||
bool coerceToString;
|
||||
JS::AutoObjectVector scopeChain;
|
||||
|
||||
explicit EvaluateOptions(JSContext* cx)
|
||||
: coerceToString(false)
|
||||
, scopeChain(cx)
|
||||
{}
|
||||
// ExecutionContext is used to switch compartment.
|
||||
class MOZ_STACK_CLASS ExecutionContext {
|
||||
// Register stack annotations for the Gecko profiler.
|
||||
mozilla::SamplerStackFrameRAII mSamplerRAII;
|
||||
|
||||
EvaluateOptions& setCoerceToString(bool aCoerce) {
|
||||
coerceToString = aCoerce;
|
||||
JSContext* mCx;
|
||||
|
||||
// Handles switching to our global's compartment.
|
||||
JSAutoCompartment mCompartment;
|
||||
|
||||
// Set to a valid handle if a return value is expected.
|
||||
JS::Rooted<JS::Value> mRetValue;
|
||||
|
||||
// Scope chain in which the execution takes place.
|
||||
JS::AutoObjectVector mScopeChain;
|
||||
|
||||
// returned value forwarded when we have to interupt the execution eagerly
|
||||
// with mSkip.
|
||||
nsresult mRv;
|
||||
|
||||
// Used to skip upcoming phases in case of a failure. In such case the
|
||||
// result is carried by mRv.
|
||||
bool mSkip;
|
||||
|
||||
// Should the result be serialized before being returned.
|
||||
bool mCoerceToString;
|
||||
|
||||
#ifdef DEBUG
|
||||
// Should we set the return value.
|
||||
bool mWantsReturnValue;
|
||||
|
||||
bool mExpectScopeChain;
|
||||
#endif
|
||||
|
||||
public:
|
||||
|
||||
// Enter compartment in which the code would be executed. The JSContext
|
||||
// must come from an AutoEntryScript that has had
|
||||
// TakeOwnershipOfErrorReporting() called on it.
|
||||
ExecutionContext(JSContext* aCx, JS::Handle<JSObject*> aGlobal);
|
||||
|
||||
ExecutionContext(const ExecutionContext&) = delete;
|
||||
ExecutionContext(ExecutionContext&&) = delete;
|
||||
|
||||
~ExecutionContext() {
|
||||
// This flag is resetted, when the returned value is extracted.
|
||||
MOZ_ASSERT(!mWantsReturnValue);
|
||||
}
|
||||
|
||||
// The returned value would be converted to a string if the
|
||||
// |aCoerceToString| is flag set.
|
||||
ExecutionContext& SetCoerceToString(bool aCoerceToString) {
|
||||
mCoerceToString = aCoerceToString;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Set the scope chain in which the code should be executed.
|
||||
void SetScopeChain(const JS::AutoObjectVector& aScopeChain);
|
||||
|
||||
// Copy the returned value in the mutable handle argument, in case of a
|
||||
// evaluation failure either during the execution or the conversion of the
|
||||
// result to a string, the nsresult would be set to the corresponding result
|
||||
// code, and the mutable handle argument would remain unchanged.
|
||||
//
|
||||
// The value returned in the mutable handle argument is part of the
|
||||
// compartment given as argument to the ExecutionContext constructor. If the
|
||||
// caller is in a different compartment, then the out-param value should be
|
||||
// wrapped by calling |JS_WrapValue|.
|
||||
MOZ_MUST_USE nsresult
|
||||
ExtractReturnValue(JS::MutableHandle<JS::Value> aRetValue);
|
||||
|
||||
// After getting a notification that an off-thread compilation terminated,
|
||||
// this function will synchronize the result by moving it to the main thread
|
||||
// before starting the execution of the script.
|
||||
//
|
||||
// The compiled script would be returned in the |aScript| out-param.
|
||||
MOZ_MUST_USE nsresult SyncAndExec(void **aOffThreadToken,
|
||||
JS::MutableHandle<JSScript*> aScript);
|
||||
|
||||
// Compile a script contained in a SourceBuffer, and execute it.
|
||||
nsresult CompileAndExec(JS::CompileOptions& aCompileOptions,
|
||||
JS::SourceBufferHolder& aSrcBuf);
|
||||
|
||||
// Compile a script contained in a string, and execute it.
|
||||
nsresult CompileAndExec(JS::CompileOptions& aCompileOptions,
|
||||
const nsAString& aScript);
|
||||
};
|
||||
|
||||
// aEvaluationGlobal is the global to evaluate in. The return value
|
||||
// will then be wrapped back into the compartment aCx is in when
|
||||
// this function is called. For all the EvaluateString overloads,
|
||||
// the JSContext must come from an AutoJSAPI that has had
|
||||
// TakeOwnershipOfErrorReporting() called on it.
|
||||
static nsresult EvaluateString(JSContext* aCx,
|
||||
const nsAString& aScript,
|
||||
JS::Handle<JSObject*> aEvaluationGlobal,
|
||||
JS::CompileOptions &aCompileOptions,
|
||||
const EvaluateOptions& aEvaluateOptions,
|
||||
JS::MutableHandle<JS::Value> aRetValue);
|
||||
|
||||
static nsresult EvaluateString(JSContext* aCx,
|
||||
JS::SourceBufferHolder& aSrcBuf,
|
||||
JS::Handle<JSObject*> aEvaluationGlobal,
|
||||
JS::CompileOptions &aCompileOptions,
|
||||
const EvaluateOptions& aEvaluateOptions,
|
||||
JS::MutableHandle<JS::Value> aRetValue);
|
||||
|
||||
|
||||
static nsresult EvaluateString(JSContext* aCx,
|
||||
const nsAString& aScript,
|
||||
JS::Handle<JSObject*> aEvaluationGlobal,
|
||||
JS::CompileOptions &aCompileOptions);
|
||||
|
||||
static nsresult EvaluateString(JSContext* aCx,
|
||||
JS::SourceBufferHolder& aSrcBuf,
|
||||
JS::Handle<JSObject*> aEvaluationGlobal,
|
||||
JS::CompileOptions &aCompileOptions,
|
||||
void **aOffThreadToken);
|
||||
|
||||
static nsresult CompileModule(JSContext* aCx,
|
||||
JS::SourceBufferHolder& aSrcBuf,
|
||||
JS::Handle<JSObject*> aEvaluationGlobal,
|
||||
|
@ -129,16 +173,6 @@ public:
|
|||
JS::AutoObjectVector& aScopeChain);
|
||||
|
||||
static void ResetTimeZone();
|
||||
|
||||
private:
|
||||
// Implementation for our EvaluateString bits
|
||||
static nsresult EvaluateString(JSContext* aCx,
|
||||
JS::SourceBufferHolder& aSrcBuf,
|
||||
JS::Handle<JSObject*> aEvaluationGlobal,
|
||||
JS::CompileOptions& aCompileOptions,
|
||||
const EvaluateOptions& aEvaluateOptions,
|
||||
JS::MutableHandle<JS::Value> aRetValue,
|
||||
void **aOffThreadToken);
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
#include "nsCCUncollectableMarker.h"
|
||||
#include "nsNameSpaceManager.h"
|
||||
#include "nsDocument.h"
|
||||
#include "nsNullPrincipal.h"
|
||||
#include "NullPrincipal.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using mozilla::dom::NodeInfo;
|
||||
|
@ -182,7 +182,7 @@ nsNodeInfoManager::Init(nsIDocument *aDocument)
|
|||
NS_PRECONDITION(!mPrincipal,
|
||||
"Being inited when we already have a principal?");
|
||||
|
||||
mPrincipal = nsNullPrincipal::Create();
|
||||
mPrincipal = NullPrincipal::Create();
|
||||
|
||||
if (aDocument) {
|
||||
mBindingManager = new nsBindingManager(aDocument);
|
||||
|
|
|
@ -2152,8 +2152,6 @@ nsScriptLoader::FillCompileOptionsForRequest(const AutoJSAPI&jsapi,
|
|||
aOptions->setFileAndLine(aRequest->mURL.get(), aRequest->mLineNo);
|
||||
aOptions->setVersion(JSVersion(aRequest->mJSVersion));
|
||||
aOptions->setIsRunOnce(true);
|
||||
// We only need the setNoScriptRval bit when compiling off-thread here, since
|
||||
// otherwise nsJSUtils::EvaluateString will set it up for us.
|
||||
aOptions->setNoScriptRval(true);
|
||||
if (aRequest->mHasSourceMapURL) {
|
||||
aOptions->setSourceMapURL(aRequest->mSourceMapURL.get());
|
||||
|
@ -2258,10 +2256,17 @@ nsScriptLoader::EvaluateScript(nsScriptLoadRequest* aRequest)
|
|||
rv = FillCompileOptionsForRequest(aes, aRequest, global, &options);
|
||||
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
nsAutoString inlineData;
|
||||
SourceBufferHolder srcBuf = GetScriptSource(aRequest, inlineData);
|
||||
rv = nsJSUtils::EvaluateString(aes.cx(), srcBuf, global, options,
|
||||
aRequest->OffThreadTokenPtr());
|
||||
{
|
||||
nsJSUtils::ExecutionContext exec(aes.cx(), global);
|
||||
if (aRequest->mOffThreadToken) {
|
||||
JS::Rooted<JSScript*> script(aes.cx());
|
||||
rv = exec.SyncAndExec(&aRequest->mOffThreadToken, &script);
|
||||
} else {
|
||||
nsAutoString inlineData;
|
||||
SourceBufferHolder srcBuf = GetScriptSource(aRequest, inlineData);
|
||||
rv = exec.CompileAndExec(options, srcBuf);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
#include "nsIScriptSecurityManager.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsComponentManagerUtils.h"
|
||||
#include "nsNullPrincipal.h"
|
||||
#include "NullPrincipal.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsIParserUtils.h"
|
||||
#include "nsIDocument.h"
|
||||
|
@ -1522,7 +1522,7 @@ nsTreeSanitizer::InitializeStatics()
|
|||
sAttributesMathML->PutEntry(*kAttributesMathML[i]);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIPrincipal> principal = nsNullPrincipal::Create();
|
||||
nsCOMPtr<nsIPrincipal> principal = NullPrincipal::Create();
|
||||
principal.forget(&sNullPrincipal);
|
||||
}
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
#include "js/Class.h"
|
||||
|
||||
#include "nsJSPrincipals.h"
|
||||
#include "nsNullPrincipal.h"
|
||||
#include "NullPrincipal.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "nsContentUtils.h"
|
||||
|
||||
|
@ -113,7 +113,7 @@ SimpleGlobalObject::Create(GlobalType globalType, JS::Handle<JS::Value> proto)
|
|||
.setSystemZone();
|
||||
|
||||
if (NS_IsMainThread()) {
|
||||
nsCOMPtr<nsIPrincipal> principal = nsNullPrincipal::Create();
|
||||
nsCOMPtr<nsIPrincipal> principal = NullPrincipal::Create();
|
||||
options.creationOptions().setTrace(xpc::TraceXPCGlobal);
|
||||
global = xpc::CreateGlobalObject(cx, js::Jsvalify(&SimpleGlobalClass),
|
||||
nsJSPrincipals::get(principal),
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
namespace {
|
||||
|
||||
using mozilla::Atomic;
|
||||
using mozilla::dom::ContentParentId;
|
||||
using mozilla::dom::cache::Manager;
|
||||
using mozilla::dom::quota::Client;
|
||||
|
@ -25,7 +26,8 @@ using mozilla::dom::quota::UsageInfo;
|
|||
using mozilla::ipc::AssertIsOnBackgroundThread;
|
||||
|
||||
static nsresult
|
||||
GetBodyUsage(nsIFile* aDir, UsageInfo* aUsageInfo)
|
||||
GetBodyUsage(nsIFile* aDir, const Atomic<bool>& aCanceled,
|
||||
UsageInfo* aUsageInfo)
|
||||
{
|
||||
nsCOMPtr<nsISimpleEnumerator> entries;
|
||||
nsresult rv = aDir->GetDirectoryEntries(getter_AddRefs(entries));
|
||||
|
@ -33,7 +35,7 @@ GetBodyUsage(nsIFile* aDir, UsageInfo* aUsageInfo)
|
|||
|
||||
bool hasMore;
|
||||
while (NS_SUCCEEDED(rv = entries->HasMoreElements(&hasMore)) && hasMore &&
|
||||
!aUsageInfo->Canceled()) {
|
||||
!aCanceled) {
|
||||
nsCOMPtr<nsISupports> entry;
|
||||
rv = entries->GetNext(getter_AddRefs(entry));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
|
||||
|
@ -45,7 +47,7 @@ GetBodyUsage(nsIFile* aDir, UsageInfo* aUsageInfo)
|
|||
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
|
||||
|
||||
if (isDir) {
|
||||
rv = GetBodyUsage(file, aUsageInfo);
|
||||
rv = GetBodyUsage(file, aCanceled, aUsageInfo);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
|
||||
continue;
|
||||
}
|
||||
|
@ -72,7 +74,8 @@ public:
|
|||
|
||||
virtual nsresult
|
||||
InitOrigin(PersistenceType aPersistenceType, const nsACString& aGroup,
|
||||
const nsACString& aOrigin, UsageInfo* aUsageInfo) override
|
||||
const nsACString& aOrigin, const AtomicBool& aCanceled,
|
||||
UsageInfo* aUsageInfo) override
|
||||
{
|
||||
// The QuotaManager passes a nullptr UsageInfo if there is no quota being
|
||||
// enforced against the origin.
|
||||
|
@ -80,12 +83,13 @@ public:
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
return GetUsageForOrigin(aPersistenceType, aGroup, aOrigin, aUsageInfo);
|
||||
return GetUsageForOrigin(aPersistenceType, aGroup, aOrigin, aCanceled,
|
||||
aUsageInfo);
|
||||
}
|
||||
|
||||
virtual nsresult
|
||||
GetUsageForOrigin(PersistenceType aPersistenceType, const nsACString& aGroup,
|
||||
const nsACString& aOrigin,
|
||||
const nsACString& aOrigin, const AtomicBool& aCanceled,
|
||||
UsageInfo* aUsageInfo) override
|
||||
{
|
||||
MOZ_DIAGNOSTIC_ASSERT(aUsageInfo);
|
||||
|
@ -107,7 +111,7 @@ public:
|
|||
|
||||
bool hasMore;
|
||||
while (NS_SUCCEEDED(rv = entries->HasMoreElements(&hasMore)) && hasMore &&
|
||||
!aUsageInfo->Canceled()) {
|
||||
!aCanceled) {
|
||||
nsCOMPtr<nsISupports> entry;
|
||||
rv = entries->GetNext(getter_AddRefs(entry));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
|
||||
|
@ -124,7 +128,7 @@ public:
|
|||
|
||||
if (isDir) {
|
||||
if (leafName.EqualsLiteral("morgue")) {
|
||||
rv = GetBodyUsage(file, aUsageInfo);
|
||||
rv = GetBodyUsage(file, aCanceled, aUsageInfo);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) { return rv; }
|
||||
} else {
|
||||
NS_WARNING("Unknown Cache directory found!");
|
||||
|
|
|
@ -37,7 +37,8 @@ function storageUsage() {
|
|||
var qms = SpecialPowers.Services.qms;
|
||||
var principal = SpecialPowers.wrap(document).nodePrincipal;
|
||||
var cb = SpecialPowers.wrapCallback(function(request) {
|
||||
resolve(request.usage, request.fileUsage);
|
||||
var result = request.result;
|
||||
resolve(result.usage, result.fileUsage);
|
||||
});
|
||||
qms.getUsageForPrincipal(principal, cb);
|
||||
});
|
||||
|
|
|
@ -37,7 +37,8 @@ function storageUsage() {
|
|||
var qms = SpecialPowers.Services.qms;
|
||||
var principal = SpecialPowers.wrap(document).nodePrincipal;
|
||||
var cb = SpecialPowers.wrapCallback(function(request) {
|
||||
resolve(request.usage, request.fileUsage);
|
||||
var result = request.result;
|
||||
resolve(result.usage, result.fileUsage);
|
||||
});
|
||||
qms.getUsageForPrincipal(principal, cb);
|
||||
});
|
||||
|
|
|
@ -37,7 +37,8 @@ function storageUsage() {
|
|||
var qms = SpecialPowers.Services.qms;
|
||||
var principal = SpecialPowers.wrap(document).nodePrincipal;
|
||||
var cb = SpecialPowers.wrapCallback(function(request) {
|
||||
resolve(request.usage, request.fileUsage);
|
||||
var result = request.result;
|
||||
resolve(result.usage, result.fileUsage);
|
||||
});
|
||||
qms.getUsageForPrincipal(principal, cb);
|
||||
});
|
||||
|
|
|
@ -379,9 +379,10 @@ nsTextInputSelectionImpl::ScrollSelectionIntoView(
|
|||
if (!mFrameSelection)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
return mFrameSelection->ScrollSelectionIntoView(
|
||||
ToSelectionType(aRawSelectionType),
|
||||
aRegion, aFlags);
|
||||
RefPtr<nsFrameSelection> frameSelection = mFrameSelection;
|
||||
return frameSelection->ScrollSelectionIntoView(
|
||||
ToSelectionType(aRawSelectionType),
|
||||
aRegion, aFlags);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -390,7 +391,8 @@ nsTextInputSelectionImpl::RepaintSelection(RawSelectionType aRawSelectionType)
|
|||
if (!mFrameSelection)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
return mFrameSelection->RepaintSelection(ToSelectionType(aRawSelectionType));
|
||||
RefPtr<nsFrameSelection> frameSelection = mFrameSelection;
|
||||
return frameSelection->RepaintSelection(ToSelectionType(aRawSelectionType));
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
@ -400,7 +402,8 @@ nsTextInputSelectionImpl::RepaintSelection(nsPresContext* aPresContext,
|
|||
if (!mFrameSelection)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
return mFrameSelection->RepaintSelection(aSelectionType);
|
||||
RefPtr<nsFrameSelection> frameSelection = mFrameSelection;
|
||||
return frameSelection->RepaintSelection(aSelectionType);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -487,48 +490,60 @@ NS_IMETHODIMP
|
|||
nsTextInputSelectionImpl::PhysicalMove(int16_t aDirection, int16_t aAmount,
|
||||
bool aExtend)
|
||||
{
|
||||
if (mFrameSelection)
|
||||
return mFrameSelection->PhysicalMove(aDirection, aAmount, aExtend);
|
||||
if (mFrameSelection) {
|
||||
RefPtr<nsFrameSelection> frameSelection = mFrameSelection;
|
||||
return frameSelection->PhysicalMove(aDirection, aAmount, aExtend);
|
||||
}
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsTextInputSelectionImpl::CharacterMove(bool aForward, bool aExtend)
|
||||
{
|
||||
if (mFrameSelection)
|
||||
return mFrameSelection->CharacterMove(aForward, aExtend);
|
||||
if (mFrameSelection) {
|
||||
RefPtr<nsFrameSelection> frameSelection = mFrameSelection;
|
||||
return frameSelection->CharacterMove(aForward, aExtend);
|
||||
}
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsTextInputSelectionImpl::CharacterExtendForDelete()
|
||||
{
|
||||
if (mFrameSelection)
|
||||
return mFrameSelection->CharacterExtendForDelete();
|
||||
if (mFrameSelection) {
|
||||
RefPtr<nsFrameSelection> frameSelection = mFrameSelection;
|
||||
return frameSelection->CharacterExtendForDelete();
|
||||
}
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsTextInputSelectionImpl::CharacterExtendForBackspace()
|
||||
{
|
||||
if (mFrameSelection)
|
||||
return mFrameSelection->CharacterExtendForBackspace();
|
||||
if (mFrameSelection) {
|
||||
RefPtr<nsFrameSelection> frameSelection = mFrameSelection;
|
||||
return frameSelection->CharacterExtendForBackspace();
|
||||
}
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsTextInputSelectionImpl::WordMove(bool aForward, bool aExtend)
|
||||
{
|
||||
if (mFrameSelection)
|
||||
return mFrameSelection->WordMove(aForward, aExtend);
|
||||
if (mFrameSelection) {
|
||||
RefPtr<nsFrameSelection> frameSelection = mFrameSelection;
|
||||
return frameSelection->WordMove(aForward, aExtend);
|
||||
}
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsTextInputSelectionImpl::WordExtendForDelete(bool aForward)
|
||||
{
|
||||
if (mFrameSelection)
|
||||
return mFrameSelection->WordExtendForDelete(aForward);
|
||||
if (mFrameSelection) {
|
||||
RefPtr<nsFrameSelection> frameSelection = mFrameSelection;
|
||||
return frameSelection->WordExtendForDelete(aForward);
|
||||
}
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
|
||||
|
@ -537,7 +552,8 @@ nsTextInputSelectionImpl::LineMove(bool aForward, bool aExtend)
|
|||
{
|
||||
if (mFrameSelection)
|
||||
{
|
||||
nsresult result = mFrameSelection->LineMove(aForward, aExtend);
|
||||
RefPtr<nsFrameSelection> frameSelection = mFrameSelection;
|
||||
nsresult result = frameSelection->LineMove(aForward, aExtend);
|
||||
if (NS_FAILED(result))
|
||||
result = CompleteMove(aForward,aExtend);
|
||||
return result;
|
||||
|
@ -549,8 +565,10 @@ nsTextInputSelectionImpl::LineMove(bool aForward, bool aExtend)
|
|||
NS_IMETHODIMP
|
||||
nsTextInputSelectionImpl::IntraLineMove(bool aForward, bool aExtend)
|
||||
{
|
||||
if (mFrameSelection)
|
||||
return mFrameSelection->IntraLineMove(aForward, aExtend);
|
||||
if (mFrameSelection) {
|
||||
RefPtr<nsFrameSelection> frameSelection = mFrameSelection;
|
||||
return frameSelection->IntraLineMove(aForward, aExtend);
|
||||
}
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
|
||||
|
@ -562,7 +580,8 @@ nsTextInputSelectionImpl::PageMove(bool aForward, bool aExtend)
|
|||
// and to remain relative position of the caret in view. see Bug 4302.
|
||||
if (mScrollFrame)
|
||||
{
|
||||
mFrameSelection->CommonPageMove(aForward, aExtend, mScrollFrame);
|
||||
RefPtr<nsFrameSelection> frameSelection = mFrameSelection;
|
||||
frameSelection->CommonPageMove(aForward, aExtend, mScrollFrame);
|
||||
}
|
||||
// After ScrollSelectionIntoView(), the pending notifications might be
|
||||
// flushed and PresShell/PresContext/Frames may be dead. See bug 418470.
|
||||
|
@ -590,8 +609,11 @@ nsTextInputSelectionImpl::CompleteScroll(bool aForward)
|
|||
NS_IMETHODIMP
|
||||
nsTextInputSelectionImpl::CompleteMove(bool aForward, bool aExtend)
|
||||
{
|
||||
NS_ENSURE_STATE(mFrameSelection);
|
||||
RefPtr<nsFrameSelection> frameSelection = mFrameSelection;
|
||||
|
||||
// grab the parent / root DIV for this text widget
|
||||
nsIContent* parentDIV = mFrameSelection->GetLimiter();
|
||||
nsIContent* parentDIV = frameSelection->GetLimiter();
|
||||
if (!parentDIV)
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
|
||||
|
@ -617,7 +639,7 @@ nsTextInputSelectionImpl::CompleteMove(bool aForward, bool aExtend)
|
|||
}
|
||||
}
|
||||
|
||||
mFrameSelection->HandleClick(parentDIV, offset, offset, aExtend,
|
||||
frameSelection->HandleClick(parentDIV, offset, offset, aExtend,
|
||||
false, hint);
|
||||
|
||||
// if we got this far, attempt to scroll no matter what the above result is
|
||||
|
@ -672,8 +694,10 @@ nsTextInputSelectionImpl::ScrollCharacter(bool aRight)
|
|||
NS_IMETHODIMP
|
||||
nsTextInputSelectionImpl::SelectAll()
|
||||
{
|
||||
if (mFrameSelection)
|
||||
return mFrameSelection->SelectAll();
|
||||
if (mFrameSelection) {
|
||||
RefPtr<nsFrameSelection> frameSelection = mFrameSelection;
|
||||
return frameSelection->SelectAll();
|
||||
}
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
|
||||
|
|
|
@ -9347,12 +9347,14 @@ public:
|
|||
InitOrigin(PersistenceType aPersistenceType,
|
||||
const nsACString& aGroup,
|
||||
const nsACString& aOrigin,
|
||||
const AtomicBool& aCanceled,
|
||||
UsageInfo* aUsageInfo) override;
|
||||
|
||||
nsresult
|
||||
GetUsageForOrigin(PersistenceType aPersistenceType,
|
||||
const nsACString& aGroup,
|
||||
const nsACString& aOrigin,
|
||||
const AtomicBool& aCanceled,
|
||||
UsageInfo* aUsageInfo) override;
|
||||
|
||||
void
|
||||
|
@ -9394,13 +9396,14 @@ private:
|
|||
|
||||
nsresult
|
||||
GetDatabaseFilenames(nsIFile* aDirectory,
|
||||
UsageInfo* aUsageInfo,
|
||||
const AtomicBool& aCanceled,
|
||||
bool aForUpgrade,
|
||||
nsTArray<nsString>& aSubdirsToProcess,
|
||||
nsTHashtable<nsStringHashKey>& aDatabaseFilename);
|
||||
|
||||
nsresult
|
||||
GetUsageForDirectoryInternal(nsIFile* aDirectory,
|
||||
const AtomicBool& aCanceled,
|
||||
UsageInfo* aUsageInfo,
|
||||
bool aDatabaseFiles);
|
||||
|
||||
|
@ -17828,10 +17831,11 @@ QuotaClient::UpgradeStorageFrom1_0To2_0(nsIFile* aDirectory)
|
|||
AssertIsOnIOThread();
|
||||
MOZ_ASSERT(aDirectory);
|
||||
|
||||
AtomicBool dummy(false);
|
||||
AutoTArray<nsString, 20> subdirsToProcess;
|
||||
nsTHashtable<nsStringHashKey> databaseFilenames(20);
|
||||
nsresult rv = GetDatabaseFilenames(aDirectory,
|
||||
nullptr,
|
||||
/* aCanceled */ dummy,
|
||||
/* aForUpgrade */ true,
|
||||
subdirsToProcess,
|
||||
databaseFilenames);
|
||||
|
@ -17924,6 +17928,7 @@ nsresult
|
|||
QuotaClient::InitOrigin(PersistenceType aPersistenceType,
|
||||
const nsACString& aGroup,
|
||||
const nsACString& aOrigin,
|
||||
const AtomicBool& aCanceled,
|
||||
UsageInfo* aUsageInfo)
|
||||
{
|
||||
AssertIsOnIOThread();
|
||||
|
@ -17942,7 +17947,7 @@ QuotaClient::InitOrigin(PersistenceType aPersistenceType,
|
|||
AutoTArray<nsString, 20> subdirsToProcess;
|
||||
nsTHashtable<nsStringHashKey> databaseFilenames(20);
|
||||
rv = GetDatabaseFilenames(directory,
|
||||
aUsageInfo,
|
||||
aCanceled,
|
||||
/* aForUpgrade */ false,
|
||||
subdirsToProcess,
|
||||
databaseFilenames);
|
||||
|
@ -17974,7 +17979,9 @@ QuotaClient::InitOrigin(PersistenceType aPersistenceType,
|
|||
const NS_ConvertASCIItoUTF16 walSuffix(kSQLiteWALSuffix,
|
||||
LiteralStringLength(kSQLiteWALSuffix));
|
||||
|
||||
for (auto iter = databaseFilenames.ConstIter(); !iter.Done(); iter.Next()) {
|
||||
for (auto iter = databaseFilenames.ConstIter();
|
||||
!iter.Done() && !aCanceled;
|
||||
iter.Next()) {
|
||||
auto& databaseFilename = iter.Get()->GetKey();
|
||||
|
||||
nsCOMPtr<nsIFile> fmDirectory;
|
||||
|
@ -18022,7 +18029,7 @@ QuotaClient::InitOrigin(PersistenceType aPersistenceType,
|
|||
return rv;
|
||||
}
|
||||
|
||||
if (aUsageInfo && !aUsageInfo->Canceled()) {
|
||||
if (aUsageInfo) {
|
||||
int64_t fileSize;
|
||||
rv = databaseFile->GetFileSize(&fileSize);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
|
@ -18059,6 +18066,7 @@ nsresult
|
|||
QuotaClient::GetUsageForOrigin(PersistenceType aPersistenceType,
|
||||
const nsACString& aGroup,
|
||||
const nsACString& aOrigin,
|
||||
const AtomicBool& aCanceled,
|
||||
UsageInfo* aUsageInfo)
|
||||
{
|
||||
AssertIsOnIOThread();
|
||||
|
@ -18071,7 +18079,7 @@ QuotaClient::GetUsageForOrigin(PersistenceType aPersistenceType,
|
|||
return rv;
|
||||
}
|
||||
|
||||
rv = GetUsageForDirectoryInternal(directory, aUsageInfo, true);
|
||||
rv = GetUsageForDirectoryInternal(directory, aCanceled, aUsageInfo, true);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
@ -18260,12 +18268,13 @@ QuotaClient::GetDirectory(PersistenceType aPersistenceType,
|
|||
nsresult
|
||||
QuotaClient::GetDatabaseFilenames(
|
||||
nsIFile* aDirectory,
|
||||
UsageInfo* aUsageInfo,
|
||||
const AtomicBool& aCanceled,
|
||||
bool aForUpgrade,
|
||||
nsTArray<nsString>& aSubdirsToProcess,
|
||||
nsTHashtable<nsStringHashKey>& aDatabaseFilenames)
|
||||
{
|
||||
AssertIsOnIOThread();
|
||||
MOZ_ASSERT(aDirectory);
|
||||
|
||||
nsCOMPtr<nsISimpleEnumerator> entries;
|
||||
nsresult rv = aDirectory->GetDirectoryEntries(getter_AddRefs(entries));
|
||||
|
@ -18286,7 +18295,7 @@ QuotaClient::GetDatabaseFilenames(
|
|||
bool hasMore;
|
||||
while (NS_SUCCEEDED((rv = entries->HasMoreElements(&hasMore))) &&
|
||||
hasMore &&
|
||||
(!aUsageInfo || !aUsageInfo->Canceled())) {
|
||||
!aCanceled) {
|
||||
nsCOMPtr<nsISupports> entry;
|
||||
rv = entries->GetNext(getter_AddRefs(entry));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
|
@ -18362,6 +18371,7 @@ QuotaClient::GetDatabaseFilenames(
|
|||
|
||||
nsresult
|
||||
QuotaClient::GetUsageForDirectoryInternal(nsIFile* aDirectory,
|
||||
const AtomicBool& aCanceled,
|
||||
UsageInfo* aUsageInfo,
|
||||
bool aDatabaseFiles)
|
||||
{
|
||||
|
@ -18388,7 +18398,7 @@ QuotaClient::GetUsageForDirectoryInternal(nsIFile* aDirectory,
|
|||
bool hasMore;
|
||||
while (NS_SUCCEEDED((rv = entries->HasMoreElements(&hasMore))) &&
|
||||
hasMore &&
|
||||
!aUsageInfo->Canceled()) {
|
||||
!aCanceled) {
|
||||
nsCOMPtr<nsISupports> entry;
|
||||
rv = entries->GetNext(getter_AddRefs(entry));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
|
@ -18423,7 +18433,7 @@ QuotaClient::GetUsageForDirectoryInternal(nsIFile* aDirectory,
|
|||
|
||||
if (isDirectory) {
|
||||
if (aDatabaseFiles) {
|
||||
rv = GetUsageForDirectoryInternal(file, aUsageInfo, false);
|
||||
rv = GetUsageForDirectoryInternal(file, aCanceled, aUsageInfo, false);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
@ -21236,8 +21246,7 @@ FactoryOp::CheckPermission(ContentParent* aContentParent,
|
|||
if (State::Initial == mState) {
|
||||
QuotaManager::GetInfoForChrome(&mSuffix, &mGroup, &mOrigin);
|
||||
|
||||
MOZ_ASSERT(
|
||||
QuotaManager::IsOriginWhitelistedForPersistentStorage(mOrigin));
|
||||
MOZ_ASSERT(QuotaManager::IsOriginInternal(mOrigin));
|
||||
|
||||
mEnforcingQuota = false;
|
||||
}
|
||||
|
@ -21269,7 +21278,7 @@ FactoryOp::CheckPermission(ContentParent* aContentParent,
|
|||
PermissionRequestBase::PermissionValue permission;
|
||||
|
||||
if (persistenceType == PERSISTENCE_TYPE_PERSISTENT) {
|
||||
if (QuotaManager::IsOriginWhitelistedForPersistentStorage(origin)) {
|
||||
if (QuotaManager::IsOriginInternal(origin)) {
|
||||
permission = PermissionRequestBase::kPermissionAllowed;
|
||||
} else {
|
||||
#ifdef IDB_MOBILE
|
||||
|
|
|
@ -220,10 +220,10 @@ function verifyWasmModule(module1, module2)
|
|||
|
||||
function grabFileUsageAndContinueHandler(request)
|
||||
{
|
||||
testGenerator.next(request.fileUsage);
|
||||
testGenerator.next(request.result.fileUsage);
|
||||
}
|
||||
|
||||
function getUsage(usageHandler)
|
||||
function getCurrentUsage(usageHandler)
|
||||
{
|
||||
let qms = SpecialPowers.Services.qms;
|
||||
let principal = SpecialPowers.wrap(document).nodePrincipal;
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
|
||||
const objectStoreName = "Blobs";
|
||||
|
||||
getUsage(grabFileUsageAndContinueHandler);
|
||||
getCurrentUsage(grabFileUsageAndContinueHandler);
|
||||
let startUsage = yield undefined;
|
||||
|
||||
const fileData1 = {
|
||||
|
@ -61,7 +61,7 @@
|
|||
|
||||
is(event.type, "success", "Got correct event type");
|
||||
|
||||
getUsage(grabFileUsageAndContinueHandler);
|
||||
getCurrentUsage(grabFileUsageAndContinueHandler);
|
||||
let usage = yield undefined;
|
||||
|
||||
is(usage, startUsage + fileData1.obj.file.size + fileData2.obj.file.size,
|
||||
|
@ -74,7 +74,7 @@
|
|||
|
||||
is(event.type, "complete", "Got correct event type");
|
||||
|
||||
getUsage(grabFileUsageAndContinueHandler);
|
||||
getCurrentUsage(grabFileUsageAndContinueHandler);
|
||||
usage = yield undefined;
|
||||
|
||||
is(usage, startUsage + fileData1.obj.file.size + fileData2.obj.file.size,
|
||||
|
@ -90,7 +90,7 @@
|
|||
// Flush pending file deletions before checking usage.
|
||||
flushPendingFileDeletions();
|
||||
|
||||
getUsage(grabFileUsageAndContinueHandler);
|
||||
getCurrentUsage(grabFileUsageAndContinueHandler);
|
||||
let endUsage = yield undefined;
|
||||
|
||||
is(endUsage, startUsage, "OS files deleted");
|
||||
|
|
|
@ -122,8 +122,9 @@ function* testSteps()
|
|||
let usageBeforeMaintenance;
|
||||
|
||||
quotaManagerService.getUsageForPrincipal(principal, (request) => {
|
||||
ok(request.usage > 0, "Usage is non-zero");
|
||||
usageBeforeMaintenance = request.usage;
|
||||
let usage = request.result.usage;
|
||||
ok(usage > 0, "Usage is non-zero");
|
||||
usageBeforeMaintenance = usage;
|
||||
continueToNextStep();
|
||||
});
|
||||
yield undefined;
|
||||
|
@ -155,8 +156,9 @@ function* testSteps()
|
|||
let usageAfterMaintenance;
|
||||
|
||||
quotaManagerService.getUsageForPrincipal(principal, (request) => {
|
||||
ok(request.usage > 0, "Usage is non-zero");
|
||||
usageAfterMaintenance = request.usage;
|
||||
let usage = request.result.usage;
|
||||
ok(usage > 0, "Usage is non-zero");
|
||||
usageAfterMaintenance = usage;
|
||||
continueToNextStep();
|
||||
});
|
||||
yield undefined;
|
||||
|
|
|
@ -80,7 +80,7 @@ function* testSteps()
|
|||
verifyView(request.result, viewData.view);
|
||||
yield undefined;
|
||||
|
||||
getUsage(grabFileUsageAndContinueHandler);
|
||||
getCurrentUsage(grabFileUsageAndContinueHandler);
|
||||
let fileUsage = yield undefined;
|
||||
|
||||
if (external) {
|
||||
|
|
|
@ -516,10 +516,10 @@ function verifyWasmModule(module1, module2)
|
|||
|
||||
function grabFileUsageAndContinueHandler(request)
|
||||
{
|
||||
testGenerator.next(request.fileUsage);
|
||||
testGenerator.next(request.result.fileUsage);
|
||||
}
|
||||
|
||||
function getUsage(usageHandler)
|
||||
function getCurrentUsage(usageHandler)
|
||||
{
|
||||
let qms = Cc["@mozilla.org/dom/quota-manager-service;1"]
|
||||
.getService(Ci.nsIQuotaManagerService);
|
||||
|
|
|
@ -58,7 +58,6 @@
|
|||
#include "nsIDOMWindowUtils.h"
|
||||
#include "nsIInterfaceRequestorUtils.h"
|
||||
#include "nsILoadInfo.h"
|
||||
#include "nsPrincipal.h"
|
||||
#include "nsIPromptFactory.h"
|
||||
#include "nsIURI.h"
|
||||
#include "nsIWindowWatcher.h"
|
||||
|
@ -69,6 +68,7 @@
|
|||
#include "nsViewManager.h"
|
||||
#include "nsVariant.h"
|
||||
#include "nsIWidget.h"
|
||||
#include "nsNetUtil.h"
|
||||
#ifndef XP_WIN
|
||||
#include "nsJARProtocolHandler.h"
|
||||
#endif
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
#include "nsIScriptError.h"
|
||||
#include "nsCRTGlue.h"
|
||||
#include "nsIScriptSecurityManager.h"
|
||||
#include "nsNullPrincipal.h"
|
||||
#include "NullPrincipal.h"
|
||||
#include "mozilla/Maybe.h"
|
||||
#include <algorithm>
|
||||
|
||||
|
@ -407,7 +407,7 @@ nsJSON::DecodeInternal(JSContext* cx,
|
|||
}
|
||||
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIPrincipal> nullPrincipal = nsNullPrincipal::Create();
|
||||
nsCOMPtr<nsIPrincipal> nullPrincipal = NullPrincipal::Create();
|
||||
|
||||
// The ::Decode function is deprecated [Bug 675797] and the following
|
||||
// channel is never openend, so it does not matter what securityFlags
|
||||
|
|
|
@ -269,10 +269,14 @@ nsresult nsJSThunk::EvaluateScript(nsIChannel *aChannel,
|
|||
JS::CompileOptions options(cx);
|
||||
options.setFileAndLine(mURL.get(), 1)
|
||||
.setVersion(JSVERSION_DEFAULT);
|
||||
nsJSUtils::EvaluateOptions evalOptions(cx);
|
||||
evalOptions.setCoerceToString(true);
|
||||
rv = nsJSUtils::EvaluateString(cx, NS_ConvertUTF8toUTF16(script),
|
||||
globalJSObject, options, evalOptions, &v);
|
||||
{
|
||||
nsJSUtils::ExecutionContext exec(cx, globalJSObject);
|
||||
exec.SetCoerceToString(true);
|
||||
exec.CompileAndExec(options, NS_ConvertUTF8toUTF16(script));
|
||||
rv = exec.ExtractReturnValue(&v);
|
||||
}
|
||||
|
||||
js::AssertSameCompartment(cx, v);
|
||||
|
||||
if (NS_FAILED(rv) || !(v.isString() || v.isUndefined())) {
|
||||
return NS_ERROR_MALFORMED_URI;
|
||||
|
|
|
@ -28,7 +28,6 @@
|
|||
#include "nsIIDNService.h"
|
||||
#include "nsNetCID.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsPrincipal.h"
|
||||
#include "nsICryptoHash.h"
|
||||
#include "nsICryptoHMAC.h"
|
||||
#include "nsIKeyModule.h"
|
||||
|
@ -54,7 +53,7 @@
|
|||
#include "VideoUtils.h"
|
||||
#include "Latency.h"
|
||||
#include "nsProxyRelease.h"
|
||||
#include "nsNullPrincipal.h"
|
||||
#include "NullPrincipal.h"
|
||||
#include "nsVariant.h"
|
||||
|
||||
// For snprintf
|
||||
|
@ -1155,7 +1154,7 @@ public:
|
|||
|
||||
nsCOMPtr<nsIPrincipal> principal;
|
||||
if (mPeerIdentity) {
|
||||
principal = nsNullPrincipal::CreateWithInheritedAttributes(window->GetExtantDoc()->NodePrincipal());
|
||||
principal = NullPrincipal::CreateWithInheritedAttributes(window->GetExtantDoc()->NodePrincipal());
|
||||
} else {
|
||||
principal = window->GetExtantDoc()->NodePrincipal();
|
||||
}
|
||||
|
|
|
@ -97,7 +97,7 @@ public:
|
|||
* This is used in WebRTC. A peerIdentity constrained MediaStreamTrack cannot
|
||||
* be sent across the network to anything other than a peer with the provided
|
||||
* identity. If this is set, then GetPrincipal() should return an instance of
|
||||
* nsNullPrincipal.
|
||||
* NullPrincipal.
|
||||
*
|
||||
* A track's PeerIdentity is immutable and will not change during the track's
|
||||
* lifetime.
|
||||
|
|
|
@ -260,27 +260,6 @@ DecodedAudioDataSink::PopFrames(uint32_t aFrames)
|
|||
AudioDataValue* const mData;
|
||||
};
|
||||
|
||||
class SilentChunk : public AudioStream::Chunk {
|
||||
public:
|
||||
SilentChunk(uint32_t aFrames, uint32_t aChannels, uint32_t aRate)
|
||||
: mFrames(aFrames)
|
||||
, mChannels(aChannels)
|
||||
, mRate(aRate)
|
||||
, mData(MakeUnique<AudioDataValue[]>(aChannels * aFrames)) {
|
||||
memset(mData.get(), 0, aChannels * aFrames * sizeof(AudioDataValue));
|
||||
}
|
||||
const AudioDataValue* Data() const { return mData.get(); }
|
||||
uint32_t Frames() const { return mFrames; }
|
||||
uint32_t Channels() const { return mChannels; }
|
||||
uint32_t Rate() const { return mRate; }
|
||||
AudioDataValue* GetWritable() const { return mData.get(); }
|
||||
private:
|
||||
const uint32_t mFrames;
|
||||
const uint32_t mChannels;
|
||||
const uint32_t mRate;
|
||||
UniquePtr<AudioDataValue[]> mData;
|
||||
};
|
||||
|
||||
bool needPopping = false;
|
||||
if (!mCurrentData) {
|
||||
// No data in the queue. Return an empty chunk.
|
||||
|
|
|
@ -1368,14 +1368,23 @@ _evaluate(NPP npp, NPObject* npobj, NPString *script, NPVariant *result)
|
|||
options.setFileAndLine(spec, 0)
|
||||
.setVersion(JSVERSION_DEFAULT);
|
||||
JS::Rooted<JS::Value> rval(cx);
|
||||
nsJSUtils::EvaluateOptions evalOptions(cx);
|
||||
JS::AutoObjectVector scopeChain(cx);
|
||||
if (obj != js::GetGlobalForObjectCrossCompartment(obj) &&
|
||||
!evalOptions.scopeChain.append(obj)) {
|
||||
!scopeChain.append(obj)) {
|
||||
return false;
|
||||
}
|
||||
obj = js::GetGlobalForObjectCrossCompartment(obj);
|
||||
nsresult rv = nsJSUtils::EvaluateString(cx, utf16script, obj, options,
|
||||
evalOptions, &rval);
|
||||
nsresult rv = NS_OK;
|
||||
{
|
||||
nsJSUtils::ExecutionContext exec(cx, obj);
|
||||
exec.SetScopeChain(scopeChain);
|
||||
exec.CompileAndExec(options, utf16script);
|
||||
rv = exec.ExtractReturnValue(&rval);
|
||||
}
|
||||
|
||||
if (!JS_WrapValue(cx, &rval)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return NS_SUCCEEDED(rv) &&
|
||||
(!result || JSValToNPVariant(npp, cx, rval, result));
|
||||
|
|
|
@ -94,7 +94,7 @@
|
|||
#include "nsIImageLoadingContent.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "nsVersionComparator.h"
|
||||
#include "nsNullPrincipal.h"
|
||||
#include "NullPrincipal.h"
|
||||
|
||||
#if defined(XP_WIN)
|
||||
#include "nsIWindowMediator.h"
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
#include "GeckoProfiler.h"
|
||||
#include "nsPluginInstanceOwner.h"
|
||||
#include "nsDataHashtable.h"
|
||||
#include "nsNullPrincipal.h"
|
||||
#include "NullPrincipal.h"
|
||||
|
||||
#define BYTERANGE_REQUEST_CONTEXT 0x01020304
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include "nsVariant.h"
|
||||
#include "QuotaManagerService.h"
|
||||
#include "QuotaRequests.h"
|
||||
#include "QuotaResults.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
@ -141,14 +142,56 @@ QuotaUsageRequestChild::HandleResponse(nsresult aResponse)
|
|||
}
|
||||
|
||||
void
|
||||
QuotaUsageRequestChild::HandleResponse(const UsageResponse& aResponse)
|
||||
QuotaUsageRequestChild::HandleResponse(const nsTArray<OriginUsage>& aResponse)
|
||||
{
|
||||
AssertIsOnOwningThread();
|
||||
MOZ_ASSERT(mRequest);
|
||||
|
||||
mRequest->SetResult(aResponse.usage(),
|
||||
aResponse.fileUsage(),
|
||||
aResponse.limit());
|
||||
RefPtr<nsVariant> variant = new nsVariant();
|
||||
|
||||
if (aResponse.IsEmpty()) {
|
||||
variant->SetAsEmptyArray();
|
||||
} else {
|
||||
nsTArray<RefPtr<UsageResult>> usageResults;
|
||||
|
||||
const uint32_t count = aResponse.Length();
|
||||
|
||||
usageResults.SetCapacity(count);
|
||||
|
||||
for (uint32_t index = 0; index < count; index++) {
|
||||
auto& originUsage = aResponse[index];
|
||||
|
||||
RefPtr<UsageResult> usageResult = new UsageResult(originUsage.origin(),
|
||||
originUsage.persisted(),
|
||||
originUsage.usage());
|
||||
|
||||
usageResults.AppendElement(usageResult.forget());
|
||||
}
|
||||
|
||||
variant->SetAsArray(nsIDataType::VTYPE_INTERFACE_IS,
|
||||
&NS_GET_IID(nsIQuotaUsageResult),
|
||||
usageResults.Length(),
|
||||
static_cast<void*>(usageResults.Elements()));
|
||||
}
|
||||
|
||||
mRequest->SetResult(variant);
|
||||
}
|
||||
|
||||
void
|
||||
QuotaUsageRequestChild::HandleResponse(const OriginUsageResponse& aResponse)
|
||||
{
|
||||
AssertIsOnOwningThread();
|
||||
MOZ_ASSERT(mRequest);
|
||||
|
||||
RefPtr<OriginUsageResult> result =
|
||||
new OriginUsageResult(aResponse.usage(),
|
||||
aResponse.fileUsage(),
|
||||
aResponse.limit());
|
||||
|
||||
RefPtr<nsVariant> variant = new nsVariant();
|
||||
variant->SetAsInterface(NS_GET_IID(nsIQuotaOriginUsageResult), result);
|
||||
|
||||
mRequest->SetResult(variant);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -175,8 +218,12 @@ QuotaUsageRequestChild::Recv__delete__(const UsageRequestResponse& aResponse)
|
|||
HandleResponse(aResponse.get_nsresult());
|
||||
break;
|
||||
|
||||
case UsageRequestResponse::TUsageResponse:
|
||||
HandleResponse(aResponse.get_UsageResponse());
|
||||
case UsageRequestResponse::TAllUsageResponse:
|
||||
HandleResponse(aResponse.get_AllUsageResponse().originUsages());
|
||||
break;
|
||||
|
||||
case UsageRequestResponse::TOriginUsageResponse:
|
||||
HandleResponse(aResponse.get_OriginUsageResponse());
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
|
@ -98,7 +98,10 @@ private:
|
|||
HandleResponse(nsresult aResponse);
|
||||
|
||||
void
|
||||
HandleResponse(const UsageResponse& aResponse);
|
||||
HandleResponse(const nsTArray<OriginUsage>& aResponse);
|
||||
|
||||
void
|
||||
HandleResponse(const OriginUsageResponse& aResponse);
|
||||
|
||||
// IPDL methods are only called by IPDL.
|
||||
virtual void
|
||||
|
|
|
@ -915,6 +915,7 @@ class NormalOriginOperationBase
|
|||
protected:
|
||||
Nullable<PersistenceType> mPersistenceType;
|
||||
OriginScope mOriginScope;
|
||||
mozilla::Atomic<bool> mCanceled;
|
||||
const bool mExclusive;
|
||||
|
||||
public:
|
||||
|
@ -1042,49 +1043,103 @@ private:
|
|||
RecvStopIdleMaintenance() override;
|
||||
};
|
||||
|
||||
class GetUsageOp final
|
||||
class QuotaUsageRequestBase
|
||||
: public NormalOriginOperationBase
|
||||
, public PQuotaUsageRequestParent
|
||||
{
|
||||
public:
|
||||
// May be overridden by subclasses if they need to perform work on the
|
||||
// background thread before being run.
|
||||
virtual bool
|
||||
Init(Quota* aQuota);
|
||||
|
||||
protected:
|
||||
QuotaUsageRequestBase()
|
||||
: NormalOriginOperationBase(Nullable<PersistenceType>(),
|
||||
OriginScope::FromNull(),
|
||||
/* aExclusive */ false)
|
||||
{ }
|
||||
|
||||
nsresult
|
||||
GetUsageForOrigin(QuotaManager* aQuotaManager,
|
||||
PersistenceType aPersistenceType,
|
||||
const nsACString& aGroup,
|
||||
const nsACString& aOrigin,
|
||||
UsageInfo* aUsageInfo);
|
||||
|
||||
// Subclasses use this override to set the IPDL response value.
|
||||
virtual void
|
||||
GetResponse(UsageRequestResponse& aResponse) = 0;
|
||||
|
||||
private:
|
||||
void
|
||||
SendResults() override;
|
||||
|
||||
// IPDL methods.
|
||||
void
|
||||
ActorDestroy(ActorDestroyReason aWhy) override;
|
||||
|
||||
mozilla::ipc::IPCResult
|
||||
RecvCancel() override;
|
||||
};
|
||||
|
||||
class GetUsageOp final
|
||||
: public QuotaUsageRequestBase
|
||||
{
|
||||
nsTArray<OriginUsage> mOriginUsages;
|
||||
nsDataHashtable<nsCStringHashKey, uint32_t> mOriginUsagesIndex;
|
||||
|
||||
bool mGetAll;
|
||||
|
||||
public:
|
||||
explicit GetUsageOp(const UsageRequestParams& aParams);
|
||||
|
||||
private:
|
||||
~GetUsageOp()
|
||||
{ }
|
||||
|
||||
nsresult
|
||||
TraverseRepository(QuotaManager* aQuotaManager,
|
||||
PersistenceType aPersistenceType);
|
||||
|
||||
nsresult
|
||||
DoDirectoryWork(QuotaManager* aQuotaManager) override;
|
||||
|
||||
void
|
||||
GetResponse(UsageRequestResponse& aResponse) override;
|
||||
};
|
||||
|
||||
class GetOriginUsageOp final
|
||||
: public QuotaUsageRequestBase
|
||||
{
|
||||
// If mGetGroupUsage is false, we use mUsageInfo to record the origin usage
|
||||
// and the file usage. Otherwise, we use it to record the group usage and the
|
||||
// limit.
|
||||
UsageInfo mUsageInfo;
|
||||
|
||||
const UsageParams mParams;
|
||||
const OriginUsageParams mParams;
|
||||
nsCString mSuffix;
|
||||
nsCString mGroup;
|
||||
bool mGetGroupUsage;
|
||||
|
||||
public:
|
||||
explicit GetUsageOp(const UsageRequestParams& aParams);
|
||||
explicit GetOriginUsageOp(const UsageRequestParams& aParams);
|
||||
|
||||
MOZ_IS_CLASS_INIT bool
|
||||
Init(Quota* aQuota);
|
||||
Init(Quota* aQuota) override;
|
||||
|
||||
private:
|
||||
~GetUsageOp()
|
||||
~GetOriginUsageOp()
|
||||
{ }
|
||||
|
||||
MOZ_IS_CLASS_INIT virtual nsresult
|
||||
DoInitOnMainThread() override;
|
||||
|
||||
nsresult
|
||||
AddToUsage(QuotaManager* aQuotaManager,
|
||||
PersistenceType aPersistenceType);
|
||||
|
||||
virtual nsresult
|
||||
DoDirectoryWork(QuotaManager* aQuotaManager) override;
|
||||
|
||||
virtual void
|
||||
SendResults() override;
|
||||
|
||||
// IPDL methods.
|
||||
virtual void
|
||||
ActorDestroy(ActorDestroyReason aWhy) override;
|
||||
|
||||
virtual mozilla::ipc::IPCResult
|
||||
RecvCancel() override;
|
||||
void
|
||||
GetResponse(UsageRequestResponse& aResponse) override;
|
||||
};
|
||||
|
||||
class QuotaRequestBase
|
||||
|
@ -4196,7 +4251,11 @@ QuotaManager::InitializeOrigin(PersistenceType aPersistenceType,
|
|||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
rv = mClients[clientType]->InitOrigin(aPersistenceType, aGroup, aOrigin,
|
||||
Atomic<bool> dummy(false);
|
||||
rv = mClients[clientType]->InitOrigin(aPersistenceType,
|
||||
aGroup,
|
||||
aOrigin,
|
||||
/* aCanceled */ dummy,
|
||||
usageInfo);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
@ -5296,10 +5355,9 @@ QuotaManager::GetInfoForChrome(nsACString* aSuffix,
|
|||
|
||||
// static
|
||||
bool
|
||||
QuotaManager::IsOriginWhitelistedForPersistentStorage(const nsACString& aOrigin)
|
||||
QuotaManager::IsOriginInternal(const nsACString& aOrigin)
|
||||
{
|
||||
// The first prompt and quota tracking is not required for these origins in
|
||||
// persistent storage.
|
||||
// The first prompt is not required for these origins.
|
||||
if (aOrigin.EqualsLiteral(kChromeOrigin) ||
|
||||
StringBeginsWith(aOrigin, nsDependentCString(kAboutHomeOriginPrefix)) ||
|
||||
StringBeginsWith(aOrigin, nsDependentCString(kIndexedDBOriginPrefix)) ||
|
||||
|
@ -6230,7 +6288,25 @@ Quota::ActorDestroy(ActorDestroyReason aWhy)
|
|||
PQuotaUsageRequestParent*
|
||||
Quota::AllocPQuotaUsageRequestParent(const UsageRequestParams& aParams)
|
||||
{
|
||||
RefPtr<GetUsageOp> actor = new GetUsageOp(aParams);
|
||||
AssertIsOnBackgroundThread();
|
||||
MOZ_ASSERT(aParams.type() != UsageRequestParams::T__None);
|
||||
|
||||
RefPtr<QuotaUsageRequestBase> actor;
|
||||
|
||||
switch (aParams.type()) {
|
||||
case UsageRequestParams::TAllUsageParams:
|
||||
actor = new GetUsageOp(aParams);
|
||||
break;
|
||||
|
||||
case UsageRequestParams::TOriginUsageParams:
|
||||
actor = new GetOriginUsageOp(aParams);
|
||||
break;
|
||||
|
||||
default:
|
||||
MOZ_CRASH("Should never get here!");
|
||||
}
|
||||
|
||||
MOZ_ASSERT(actor);
|
||||
|
||||
// Transfer ownership to IPDL.
|
||||
return actor.forget().take();
|
||||
|
@ -6244,7 +6320,7 @@ Quota::RecvPQuotaUsageRequestConstructor(PQuotaUsageRequestParent* aActor,
|
|||
MOZ_ASSERT(aActor);
|
||||
MOZ_ASSERT(aParams.type() != UsageRequestParams::T__None);
|
||||
|
||||
auto* op = static_cast<GetUsageOp*>(aActor);
|
||||
auto* op = static_cast<QuotaUsageRequestBase*>(aActor);
|
||||
|
||||
if (NS_WARN_IF(!op->Init(this))) {
|
||||
return IPC_FAIL_NO_REASON(this);
|
||||
|
@ -6261,8 +6337,8 @@ Quota::DeallocPQuotaUsageRequestParent(PQuotaUsageRequestParent* aActor)
|
|||
MOZ_ASSERT(aActor);
|
||||
|
||||
// Transfer ownership back from IPDL.
|
||||
RefPtr<GetUsageOp> actor =
|
||||
dont_AddRef(static_cast<GetUsageOp*>(aActor));
|
||||
RefPtr<QuotaUsageRequestBase> actor =
|
||||
dont_AddRef(static_cast<QuotaUsageRequestBase*>(aActor));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -6336,6 +6412,7 @@ Quota::RecvPQuotaRequestConstructor(PQuotaRequestParent* aActor,
|
|||
MOZ_ASSERT(aParams.type() != RequestParams::T__None);
|
||||
|
||||
auto* op = static_cast<QuotaRequestBase*>(aActor);
|
||||
|
||||
if (NS_WARN_IF(!op->Init(this))) {
|
||||
return IPC_FAIL_NO_REASON(this);
|
||||
}
|
||||
|
@ -6414,67 +6491,32 @@ Quota::RecvStopIdleMaintenance()
|
|||
return IPC_OK();
|
||||
}
|
||||
|
||||
GetUsageOp::GetUsageOp(const UsageRequestParams& aParams)
|
||||
: NormalOriginOperationBase(Nullable<PersistenceType>(),
|
||||
OriginScope::FromNull(),
|
||||
/* aExclusive */ false)
|
||||
, mParams(aParams.get_UsageParams())
|
||||
, mGetGroupUsage(aParams.get_UsageParams().getGroupUsage())
|
||||
{
|
||||
AssertIsOnOwningThread();
|
||||
MOZ_ASSERT(aParams.type() == UsageRequestParams::TUsageParams);
|
||||
}
|
||||
|
||||
bool
|
||||
GetUsageOp::Init(Quota* aQuota)
|
||||
QuotaUsageRequestBase::Init(Quota* aQuota)
|
||||
{
|
||||
AssertIsOnOwningThread();
|
||||
MOZ_ASSERT(aQuota);
|
||||
|
||||
mNeedsMainThreadInit = true;
|
||||
mNeedsQuotaManagerInit = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
nsresult
|
||||
GetUsageOp::DoInitOnMainThread()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(GetState() == State_Initializing);
|
||||
MOZ_ASSERT(mNeedsMainThreadInit);
|
||||
|
||||
const PrincipalInfo& principalInfo = mParams.principalInfo();
|
||||
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIPrincipal> principal =
|
||||
PrincipalInfoToPrincipal(principalInfo, &rv);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
// Figure out which origin we're dealing with.
|
||||
nsCString origin;
|
||||
rv = QuotaManager::GetInfoFromPrincipal(principal, &mSuffix, &mGroup,
|
||||
&origin);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
mOriginScope.SetFromOrigin(origin);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
GetUsageOp::AddToUsage(QuotaManager* aQuotaManager,
|
||||
PersistenceType aPersistenceType)
|
||||
QuotaUsageRequestBase::GetUsageForOrigin(QuotaManager* aQuotaManager,
|
||||
PersistenceType aPersistenceType,
|
||||
const nsACString& aGroup,
|
||||
const nsACString& aOrigin,
|
||||
UsageInfo* aUsageInfo)
|
||||
{
|
||||
AssertIsOnIOThread();
|
||||
MOZ_ASSERT(aQuotaManager);
|
||||
MOZ_ASSERT(aUsageInfo);
|
||||
MOZ_ASSERT(aUsageInfo->TotalUsage() == 0);
|
||||
|
||||
nsCOMPtr<nsIFile> directory;
|
||||
nsresult rv = aQuotaManager->GetDirectoryForOrigin(aPersistenceType,
|
||||
mOriginScope.GetOrigin(),
|
||||
aOrigin,
|
||||
getter_AddRefs(directory));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
|
@ -6484,12 +6526,11 @@ GetUsageOp::AddToUsage(QuotaManager* aQuotaManager,
|
|||
|
||||
// If the directory exists then enumerate all the files inside, adding up
|
||||
// the sizes to get the final usage statistic.
|
||||
if (exists && !mUsageInfo.Canceled()) {
|
||||
if (exists && !mCanceled) {
|
||||
bool initialized;
|
||||
|
||||
if (aPersistenceType == PERSISTENCE_TYPE_PERSISTENT) {
|
||||
initialized =
|
||||
aQuotaManager->IsOriginInitialized(mOriginScope.GetOrigin());
|
||||
initialized = aQuotaManager->IsOriginInitialized(aOrigin);
|
||||
} else {
|
||||
initialized = aQuotaManager->IsTemporaryStorageInitialized();
|
||||
}
|
||||
|
@ -6500,7 +6541,7 @@ GetUsageOp::AddToUsage(QuotaManager* aQuotaManager,
|
|||
|
||||
bool hasMore;
|
||||
while (NS_SUCCEEDED((rv = entries->HasMoreElements(&hasMore))) &&
|
||||
hasMore && !mUsageInfo.Canceled()) {
|
||||
hasMore && !mCanceled) {
|
||||
nsCOMPtr<nsISupports> entry;
|
||||
rv = entries->GetNext(getter_AddRefs(entry));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
@ -6562,15 +6603,17 @@ GetUsageOp::AddToUsage(QuotaManager* aQuotaManager,
|
|||
|
||||
if (initialized) {
|
||||
rv = client->GetUsageForOrigin(aPersistenceType,
|
||||
mGroup,
|
||||
mOriginScope.GetOrigin(),
|
||||
&mUsageInfo);
|
||||
aGroup,
|
||||
aOrigin,
|
||||
mCanceled,
|
||||
aUsageInfo);
|
||||
}
|
||||
else {
|
||||
rv = client->InitOrigin(aPersistenceType,
|
||||
mGroup,
|
||||
mOriginScope.GetOrigin(),
|
||||
&mUsageInfo);
|
||||
aGroup,
|
||||
aOrigin,
|
||||
mCanceled,
|
||||
aUsageInfo);
|
||||
}
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
@ -6579,17 +6622,290 @@ GetUsageOp::AddToUsage(QuotaManager* aQuotaManager,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
QuotaUsageRequestBase::SendResults()
|
||||
{
|
||||
AssertIsOnOwningThread();
|
||||
|
||||
if (IsActorDestroyed()) {
|
||||
if (NS_SUCCEEDED(mResultCode)) {
|
||||
mResultCode = NS_ERROR_FAILURE;
|
||||
}
|
||||
} else {
|
||||
if (mCanceled) {
|
||||
mResultCode = NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
UsageRequestResponse response;
|
||||
|
||||
if (NS_SUCCEEDED(mResultCode)) {
|
||||
GetResponse(response);
|
||||
} else {
|
||||
response = mResultCode;
|
||||
}
|
||||
|
||||
Unused << PQuotaUsageRequestParent::Send__delete__(this, response);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
QuotaUsageRequestBase::ActorDestroy(ActorDestroyReason aWhy)
|
||||
{
|
||||
AssertIsOnOwningThread();
|
||||
|
||||
NoteActorDestroyed();
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult
|
||||
QuotaUsageRequestBase::RecvCancel()
|
||||
{
|
||||
AssertIsOnOwningThread();
|
||||
|
||||
if (mCanceled.exchange(true)) {
|
||||
NS_WARNING("Canceled more than once?!");
|
||||
return IPC_FAIL_NO_REASON(this);
|
||||
}
|
||||
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
GetUsageOp::GetUsageOp(const UsageRequestParams& aParams)
|
||||
: mGetAll(aParams.get_AllUsageParams().getAll())
|
||||
{
|
||||
AssertIsOnOwningThread();
|
||||
MOZ_ASSERT(aParams.type() == UsageRequestParams::TAllUsageParams);
|
||||
}
|
||||
|
||||
nsresult
|
||||
GetUsageOp::TraverseRepository(QuotaManager* aQuotaManager,
|
||||
PersistenceType aPersistenceType)
|
||||
{
|
||||
AssertIsOnIOThread();
|
||||
MOZ_ASSERT(aQuotaManager);
|
||||
|
||||
nsresult rv;
|
||||
|
||||
nsCOMPtr<nsIFile> directory =
|
||||
do_CreateInstance(NS_LOCAL_FILE_CONTRACTID, &rv);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
rv = directory->InitWithPath(aQuotaManager->GetStoragePath(aPersistenceType));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
bool exists;
|
||||
rv = directory->Exists(&exists);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (!exists) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsISimpleEnumerator> entries;
|
||||
rv = directory->GetDirectoryEntries(getter_AddRefs(entries));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
bool persistent = aPersistenceType == PERSISTENCE_TYPE_PERSISTENT;
|
||||
|
||||
bool hasMore;
|
||||
while (NS_SUCCEEDED((rv = entries->HasMoreElements(&hasMore))) &&
|
||||
hasMore && !mCanceled) {
|
||||
nsCOMPtr<nsISupports> entry;
|
||||
rv = entries->GetNext(getter_AddRefs(entry));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIFile> originDir = do_QueryInterface(entry);
|
||||
MOZ_ASSERT(originDir);
|
||||
|
||||
bool isDirectory;
|
||||
rv = originDir->IsDirectory(&isDirectory);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (!isDirectory) {
|
||||
nsString leafName;
|
||||
rv = originDir->GetLeafName(leafName);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (!IsOSMetadata(leafName)) {
|
||||
UNKNOWN_FILE_WARNING(leafName);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
int64_t timestamp;
|
||||
bool persisted;
|
||||
nsCString suffix;
|
||||
nsCString group;
|
||||
nsCString origin;
|
||||
rv = aQuotaManager->GetDirectoryMetadata2WithRestore(originDir,
|
||||
persistent,
|
||||
×tamp,
|
||||
&persisted,
|
||||
suffix,
|
||||
group,
|
||||
origin);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (!mGetAll && aQuotaManager->IsOriginInternal(origin)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
OriginUsage* originUsage;
|
||||
|
||||
// We can't store pointers to OriginUsage objects in the hashtable
|
||||
// since AppendElement() reallocates its internal array buffer as number
|
||||
// of elements grows.
|
||||
uint32_t index;
|
||||
if (mOriginUsagesIndex.Get(origin, &index)) {
|
||||
originUsage = &mOriginUsages[index];
|
||||
} else {
|
||||
index = mOriginUsages.Length();
|
||||
|
||||
originUsage = mOriginUsages.AppendElement();
|
||||
|
||||
originUsage->origin() = origin;
|
||||
originUsage->persisted() = false;
|
||||
originUsage->usage() = 0;
|
||||
|
||||
mOriginUsagesIndex.Put(origin, index);
|
||||
}
|
||||
|
||||
if (aPersistenceType == PERSISTENCE_TYPE_DEFAULT) {
|
||||
originUsage->persisted() = persisted;
|
||||
}
|
||||
|
||||
UsageInfo usageInfo;
|
||||
rv = GetUsageForOrigin(aQuotaManager,
|
||||
aPersistenceType,
|
||||
group,
|
||||
origin,
|
||||
&usageInfo);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
originUsage->usage() = originUsage->usage() + usageInfo.TotalUsage();
|
||||
}
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
GetUsageOp::DoDirectoryWork(QuotaManager* aQuotaManager)
|
||||
{
|
||||
AssertIsOnIOThread();
|
||||
MOZ_ASSERT(mUsageInfo.TotalUsage() == 0);
|
||||
|
||||
PROFILER_LABEL("Quota", "GetUsageOp::DoDirectoryWork",
|
||||
js::ProfileEntry::Category::OTHER);
|
||||
|
||||
nsresult rv;
|
||||
|
||||
for (const PersistenceType type : kAllPersistenceTypes) {
|
||||
rv = TraverseRepository(aQuotaManager, type);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
GetUsageOp::GetResponse(UsageRequestResponse& aResponse)
|
||||
{
|
||||
AssertIsOnOwningThread();
|
||||
|
||||
aResponse = AllUsageResponse();
|
||||
|
||||
if (!mOriginUsages.IsEmpty()) {
|
||||
nsTArray<OriginUsage>& originUsages =
|
||||
aResponse.get_AllUsageResponse().originUsages();
|
||||
|
||||
mOriginUsages.SwapElements(originUsages);
|
||||
}
|
||||
}
|
||||
|
||||
GetOriginUsageOp::GetOriginUsageOp(const UsageRequestParams& aParams)
|
||||
: mParams(aParams.get_OriginUsageParams())
|
||||
, mGetGroupUsage(aParams.get_OriginUsageParams().getGroupUsage())
|
||||
{
|
||||
AssertIsOnOwningThread();
|
||||
MOZ_ASSERT(aParams.type() == UsageRequestParams::TOriginUsageParams);
|
||||
}
|
||||
|
||||
bool
|
||||
GetOriginUsageOp::Init(Quota* aQuota)
|
||||
{
|
||||
AssertIsOnOwningThread();
|
||||
MOZ_ASSERT(aQuota);
|
||||
|
||||
if (NS_WARN_IF(!QuotaUsageRequestBase::Init(aQuota))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
mNeedsMainThreadInit = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
nsresult
|
||||
GetOriginUsageOp::DoInitOnMainThread()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(GetState() == State_Initializing);
|
||||
MOZ_ASSERT(mNeedsMainThreadInit);
|
||||
|
||||
const PrincipalInfo& principalInfo = mParams.principalInfo();
|
||||
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIPrincipal> principal =
|
||||
PrincipalInfoToPrincipal(principalInfo, &rv);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
// Figure out which origin we're dealing with.
|
||||
nsCString origin;
|
||||
rv = QuotaManager::GetInfoFromPrincipal(principal, &mSuffix, &mGroup,
|
||||
&origin);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
mOriginScope.SetFromOrigin(origin);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
GetOriginUsageOp::DoDirectoryWork(QuotaManager* aQuotaManager)
|
||||
{
|
||||
AssertIsOnIOThread();
|
||||
MOZ_ASSERT(mUsageInfo.TotalUsage() == 0);
|
||||
|
||||
PROFILER_LABEL("Quota", "GetOriginUsageOp::DoDirectoryWork",
|
||||
js::ProfileEntry::Category::OTHER);
|
||||
|
||||
nsresult rv;
|
||||
|
||||
if (mGetGroupUsage) {
|
||||
nsCOMPtr<nsIFile> directory;
|
||||
|
||||
|
@ -6611,72 +6927,40 @@ GetUsageOp::DoDirectoryWork(QuotaManager* aQuotaManager)
|
|||
|
||||
// Add all the persistent/temporary/default storage files we care about.
|
||||
for (const PersistenceType type : kAllPersistenceTypes) {
|
||||
rv = AddToUsage(aQuotaManager, type);
|
||||
UsageInfo usageInfo;
|
||||
rv = GetUsageForOrigin(aQuotaManager,
|
||||
type,
|
||||
mGroup,
|
||||
mOriginScope.GetOrigin(),
|
||||
&usageInfo);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
mUsageInfo.Append(usageInfo);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
GetUsageOp::SendResults()
|
||||
GetOriginUsageOp::GetResponse(UsageRequestResponse& aResponse)
|
||||
{
|
||||
AssertIsOnOwningThread();
|
||||
|
||||
if (IsActorDestroyed()) {
|
||||
if (NS_SUCCEEDED(mResultCode)) {
|
||||
mResultCode = NS_ERROR_FAILURE;
|
||||
}
|
||||
OriginUsageResponse usageResponse;
|
||||
|
||||
// We'll get the group usage when mGetGroupUsage is true and get the
|
||||
// origin usage when mGetGroupUsage is false.
|
||||
usageResponse.usage() = mUsageInfo.TotalUsage();
|
||||
|
||||
if (mGetGroupUsage) {
|
||||
usageResponse.limit() = mUsageInfo.Limit();
|
||||
} else {
|
||||
if (mUsageInfo.Canceled()) {
|
||||
mResultCode = NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
UsageRequestResponse response;
|
||||
|
||||
if (NS_SUCCEEDED(mResultCode)) {
|
||||
UsageResponse usageResponse;
|
||||
|
||||
// We'll get the group usage when mGetGroupUsage is true and get the
|
||||
// origin usage when mGetGroupUsage is false.
|
||||
usageResponse.usage() = mUsageInfo.TotalUsage();
|
||||
|
||||
if (mGetGroupUsage) {
|
||||
usageResponse.limit() = mUsageInfo.Limit();
|
||||
} else {
|
||||
usageResponse.fileUsage() = mUsageInfo.FileUsage();
|
||||
}
|
||||
|
||||
response = usageResponse;
|
||||
} else {
|
||||
response = mResultCode;
|
||||
}
|
||||
|
||||
Unused << PQuotaUsageRequestParent::Send__delete__(this, response);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
GetUsageOp::ActorDestroy(ActorDestroyReason aWhy)
|
||||
{
|
||||
AssertIsOnOwningThread();
|
||||
|
||||
NoteActorDestroyed();
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult
|
||||
GetUsageOp::RecvCancel()
|
||||
{
|
||||
AssertIsOnOwningThread();
|
||||
|
||||
nsresult rv = mUsageInfo.Cancel();
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return IPC_FAIL_NO_REASON(this);
|
||||
usageResponse.fileUsage() = mUsageInfo.FileUsage();
|
||||
}
|
||||
|
||||
return IPC_OK();
|
||||
aResponse = usageResponse;
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -8185,9 +8469,7 @@ CreateOrUpgradeDirectoryMetadataHelper::CreateOrUpgradeMetadataFiles()
|
|||
}
|
||||
}
|
||||
else {
|
||||
bool persistent =
|
||||
QuotaManager::IsOriginWhitelistedForPersistentStorage(
|
||||
originProps.mSpec);
|
||||
bool persistent = QuotaManager::IsOriginInternal(originProps.mSpec);
|
||||
originProps.mTimestamp = GetLastModifiedTime(originDir, persistent);
|
||||
}
|
||||
|
||||
|
@ -8331,9 +8613,8 @@ CreateOrUpgradeDirectoryMetadataHelper::ProcessOriginDirectory(
|
|||
return rv;
|
||||
}
|
||||
|
||||
// Move whitelisted origins to new persistent storage.
|
||||
if (QuotaManager::IsOriginWhitelistedForPersistentStorage(
|
||||
aOriginProps.mSpec)) {
|
||||
// Move internal origins to new persistent storage.
|
||||
if (QuotaManager::IsOriginInternal(aOriginProps.mSpec)) {
|
||||
if (!mPermanentStorageDir) {
|
||||
mPermanentStorageDir =
|
||||
do_CreateInstance(NS_LOCAL_FILE_CONTRACTID, &rv);
|
||||
|
|
|
@ -31,6 +31,8 @@ class UsageInfo;
|
|||
class Client
|
||||
{
|
||||
public:
|
||||
typedef mozilla::Atomic<bool> AtomicBool;
|
||||
|
||||
NS_INLINE_DECL_PURE_VIRTUAL_REFCOUNTING
|
||||
|
||||
enum Type {
|
||||
|
@ -100,12 +102,14 @@ public:
|
|||
InitOrigin(PersistenceType aPersistenceType,
|
||||
const nsACString& aGroup,
|
||||
const nsACString& aOrigin,
|
||||
const AtomicBool& aCanceled,
|
||||
UsageInfo* aUsageInfo) = 0;
|
||||
|
||||
virtual nsresult
|
||||
GetUsageForOrigin(PersistenceType aPersistenceType,
|
||||
const nsACString& aGroup,
|
||||
const nsACString& aOrigin,
|
||||
const AtomicBool& aCanceled,
|
||||
UsageInfo* aUsageInfo) = 0;
|
||||
|
||||
virtual void
|
||||
|
|
|
@ -27,7 +27,12 @@ struct InitOriginParams
|
|||
PersistenceType persistenceType;
|
||||
};
|
||||
|
||||
struct UsageParams
|
||||
struct AllUsageParams
|
||||
{
|
||||
bool getAll;
|
||||
};
|
||||
|
||||
struct OriginUsageParams
|
||||
{
|
||||
PrincipalInfo principalInfo;
|
||||
bool getGroupUsage;
|
||||
|
@ -35,7 +40,8 @@ struct UsageParams
|
|||
|
||||
union UsageRequestParams
|
||||
{
|
||||
UsageParams;
|
||||
AllUsageParams;
|
||||
OriginUsageParams;
|
||||
};
|
||||
|
||||
struct ClearOriginParams
|
||||
|
|
|
@ -8,7 +8,19 @@ namespace mozilla {
|
|||
namespace dom {
|
||||
namespace quota {
|
||||
|
||||
struct UsageResponse
|
||||
struct OriginUsage
|
||||
{
|
||||
nsCString origin;
|
||||
bool persisted;
|
||||
uint64_t usage;
|
||||
};
|
||||
|
||||
struct AllUsageResponse
|
||||
{
|
||||
OriginUsage[] originUsages;
|
||||
};
|
||||
|
||||
struct OriginUsageResponse
|
||||
{
|
||||
uint64_t usage;
|
||||
uint64_t fileUsage;
|
||||
|
@ -18,7 +30,8 @@ struct UsageResponse
|
|||
union UsageRequestResponse
|
||||
{
|
||||
nsresult;
|
||||
UsageResponse;
|
||||
AllUsageResponse;
|
||||
OriginUsageResponse;
|
||||
};
|
||||
|
||||
protocol PQuotaUsageRequest
|
||||
|
|
|
@ -398,7 +398,7 @@ public:
|
|||
nsACString* aOrigin);
|
||||
|
||||
static bool
|
||||
IsOriginWhitelistedForPersistentStorage(const nsACString& aOrigin);
|
||||
IsOriginInternal(const nsACString& aOrigin);
|
||||
|
||||
static void
|
||||
ChromeOrigin(nsACString& aOrigin);
|
||||
|
|
|
@ -584,6 +584,31 @@ QuotaManagerService::InitStoragesForPrincipal(
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
QuotaManagerService::GetUsage(nsIQuotaUsageCallback* aCallback,
|
||||
bool aGetAll,
|
||||
nsIQuotaUsageRequest** _retval)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(aCallback);
|
||||
|
||||
RefPtr<UsageRequest> request = new UsageRequest(aCallback);
|
||||
|
||||
AllUsageParams params;
|
||||
|
||||
params.getAll() = aGetAll;
|
||||
|
||||
nsAutoPtr<PendingRequestInfo> info(new UsageRequestInfo(request, params));
|
||||
|
||||
nsresult rv = InitiateRequest(info);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
request.forget(_retval);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
QuotaManagerService::GetUsageForPrincipal(nsIPrincipal* aPrincipal,
|
||||
nsIQuotaUsageCallback* aCallback,
|
||||
|
@ -596,7 +621,7 @@ QuotaManagerService::GetUsageForPrincipal(nsIPrincipal* aPrincipal,
|
|||
|
||||
RefPtr<UsageRequest> request = new UsageRequest(aPrincipal, aCallback);
|
||||
|
||||
UsageParams params;
|
||||
OriginUsageParams params;
|
||||
|
||||
nsresult rv = CheckedPrincipalToPrincipalInfo(aPrincipal,
|
||||
params.principalInfo());
|
||||
|
|
|
@ -91,13 +91,19 @@ RequestBase::GetResultCode(nsresult* aResultCode)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
UsageRequest::UsageRequest(nsIQuotaUsageCallback* aCallback)
|
||||
: mCallback(aCallback)
|
||||
, mBackgroundActor(nullptr)
|
||||
, mCanceled(false)
|
||||
{
|
||||
AssertIsOnOwningThread();
|
||||
MOZ_ASSERT(aCallback);
|
||||
}
|
||||
|
||||
UsageRequest::UsageRequest(nsIPrincipal* aPrincipal,
|
||||
nsIQuotaUsageCallback* aCallback)
|
||||
: RequestBase(aPrincipal)
|
||||
, mCallback(aCallback)
|
||||
, mUsage(0)
|
||||
, mFileUsage(0)
|
||||
, mLimit(0)
|
||||
, mBackgroundActor(nullptr)
|
||||
, mCanceled(false)
|
||||
{
|
||||
|
@ -126,14 +132,14 @@ UsageRequest::SetBackgroundActor(QuotaUsageRequestChild* aBackgroundActor)
|
|||
}
|
||||
|
||||
void
|
||||
UsageRequest::SetResult(uint64_t aUsage, uint64_t aFileUsage, uint64_t aLimit)
|
||||
UsageRequest::SetResult(nsIVariant* aResult)
|
||||
{
|
||||
AssertIsOnOwningThread();
|
||||
MOZ_ASSERT(aResult);
|
||||
MOZ_ASSERT(!mHaveResultOrErrorCode);
|
||||
|
||||
mUsage = aUsage;
|
||||
mFileUsage = aFileUsage;
|
||||
mLimit = aLimit;
|
||||
mResult = aResult;
|
||||
|
||||
mHaveResultOrErrorCode = true;
|
||||
|
||||
FireCallback();
|
||||
|
@ -149,43 +155,18 @@ NS_IMPL_ADDREF_INHERITED(UsageRequest, RequestBase)
|
|||
NS_IMPL_RELEASE_INHERITED(UsageRequest, RequestBase)
|
||||
|
||||
NS_IMETHODIMP
|
||||
UsageRequest::GetUsage(uint64_t* aUsage)
|
||||
UsageRequest::GetResult(nsIVariant** aResult)
|
||||
{
|
||||
AssertIsOnOwningThread();
|
||||
MOZ_ASSERT(aResult);
|
||||
|
||||
if (!mHaveResultOrErrorCode) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
*aUsage = mUsage;
|
||||
return NS_OK;
|
||||
}
|
||||
MOZ_ASSERT(mResult);
|
||||
|
||||
NS_IMETHODIMP
|
||||
UsageRequest::GetFileUsage(uint64_t* aFileUsage)
|
||||
{
|
||||
AssertIsOnOwningThread();
|
||||
MOZ_ASSERT(aFileUsage);
|
||||
|
||||
if (!mHaveResultOrErrorCode) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
*aFileUsage = mFileUsage;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
UsageRequest::GetLimit(uint64_t* aLimit)
|
||||
{
|
||||
AssertIsOnOwningThread();
|
||||
MOZ_ASSERT(aLimit);
|
||||
|
||||
if (!mHaveResultOrErrorCode) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
*aLimit = mLimit;
|
||||
NS_ADDREF(*aResult = mResult);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -72,17 +72,15 @@ class UsageRequest final
|
|||
{
|
||||
nsCOMPtr<nsIQuotaUsageCallback> mCallback;
|
||||
|
||||
uint64_t mUsage;
|
||||
uint64_t mFileUsage;
|
||||
|
||||
// Group Limit.
|
||||
uint64_t mLimit;
|
||||
nsCOMPtr<nsIVariant> mResult;
|
||||
|
||||
QuotaUsageRequestChild* mBackgroundActor;
|
||||
|
||||
bool mCanceled;
|
||||
|
||||
public:
|
||||
explicit UsageRequest(nsIQuotaUsageCallback* aCallback);
|
||||
|
||||
UsageRequest(nsIPrincipal* aPrincipal,
|
||||
nsIQuotaUsageCallback* aCallback);
|
||||
|
||||
|
@ -98,7 +96,7 @@ public:
|
|||
}
|
||||
|
||||
void
|
||||
SetResult(uint64_t aUsage, uint64_t aFileUsage, uint64_t aLimit);
|
||||
SetResult(nsIVariant* aResult);
|
||||
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_FORWARD_NSIQUOTAREQUESTBASE(RequestBase::)
|
||||
|
|
|
@ -0,0 +1,91 @@
|
|||
/* -*- 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 "QuotaResults.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
namespace quota {
|
||||
|
||||
UsageResult::UsageResult(const nsACString& aOrigin,
|
||||
bool aPersisted,
|
||||
uint64_t aUsage)
|
||||
: mOrigin(aOrigin)
|
||||
, mUsage(aUsage)
|
||||
, mPersisted(aPersisted)
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS(UsageResult,
|
||||
nsIQuotaUsageResult)
|
||||
|
||||
NS_IMETHODIMP
|
||||
UsageResult::GetOrigin(nsACString& aOrigin)
|
||||
{
|
||||
aOrigin = mOrigin;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
UsageResult::GetPersisted(bool* aPersisted)
|
||||
{
|
||||
MOZ_ASSERT(aPersisted);
|
||||
|
||||
*aPersisted = mPersisted;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
UsageResult::GetUsage(uint64_t* aUsage)
|
||||
{
|
||||
MOZ_ASSERT(aUsage);
|
||||
|
||||
*aUsage = mUsage;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
OriginUsageResult::OriginUsageResult(uint64_t aUsage,
|
||||
uint64_t aFileUsage,
|
||||
uint64_t aLimit)
|
||||
: mUsage(aUsage)
|
||||
, mFileUsage(aFileUsage)
|
||||
, mLimit(aLimit)
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS(OriginUsageResult,
|
||||
nsIQuotaOriginUsageResult)
|
||||
|
||||
NS_IMETHODIMP
|
||||
OriginUsageResult::GetUsage(uint64_t* aUsage)
|
||||
{
|
||||
MOZ_ASSERT(aUsage);
|
||||
|
||||
*aUsage = mUsage;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
OriginUsageResult::GetFileUsage(uint64_t* aFileUsage)
|
||||
{
|
||||
MOZ_ASSERT(aFileUsage);
|
||||
|
||||
*aFileUsage = mFileUsage;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
OriginUsageResult::GetLimit(uint64_t* aLimit)
|
||||
{
|
||||
MOZ_ASSERT(aLimit);
|
||||
|
||||
*aLimit = mLimit;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
} // namespace quota
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
|
@ -0,0 +1,60 @@
|
|||
/* -*- 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_dom_quota_QuotaResults_h
|
||||
#define mozilla_dom_quota_QuotaResults_h
|
||||
|
||||
#include "nsIQuotaResults.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
namespace quota {
|
||||
|
||||
class UsageResult
|
||||
: public nsIQuotaUsageResult
|
||||
{
|
||||
nsCString mOrigin;
|
||||
uint64_t mUsage;
|
||||
bool mPersisted;
|
||||
|
||||
public:
|
||||
UsageResult(const nsACString& aOrigin,
|
||||
bool aPersisted,
|
||||
uint64_t aUsage);
|
||||
|
||||
private:
|
||||
virtual ~UsageResult()
|
||||
{ }
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIQUOTAUSAGERESULT
|
||||
};
|
||||
|
||||
class OriginUsageResult
|
||||
: public nsIQuotaOriginUsageResult
|
||||
{
|
||||
uint64_t mUsage;
|
||||
uint64_t mFileUsage;
|
||||
uint64_t mLimit;
|
||||
|
||||
public:
|
||||
OriginUsageResult(uint64_t aUsage,
|
||||
uint64_t aFileUsage,
|
||||
uint64_t aLimit);
|
||||
|
||||
private:
|
||||
virtual ~OriginUsageResult()
|
||||
{ }
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIQUOTAORIGINUSAGERESULT
|
||||
};
|
||||
|
||||
} // namespace quota
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_dom_quota_QuotaResults_h
|
|
@ -133,20 +133,31 @@ GetStorageEstimate(nsIQuotaUsageRequest* aRequest,
|
|||
{
|
||||
MOZ_ASSERT(aRequest);
|
||||
|
||||
uint64_t usage;
|
||||
nsresult rv = aRequest->GetUsage(&usage);
|
||||
nsCOMPtr<nsIVariant> result;
|
||||
nsresult rv = aRequest->GetResult(getter_AddRefs(result));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
uint64_t limit;
|
||||
rv = aRequest->GetLimit(&limit);
|
||||
nsID* iid;
|
||||
nsCOMPtr<nsISupports> supports;
|
||||
rv = result->GetAsInterface(&iid, getter_AddRefs(supports));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
aStorageEstimate.mUsage.Construct() = usage;
|
||||
aStorageEstimate.mQuota.Construct() = limit;
|
||||
free(iid);
|
||||
|
||||
nsCOMPtr<nsIQuotaOriginUsageResult> originUsageResult =
|
||||
do_QueryInterface(supports);
|
||||
MOZ_ASSERT(originUsageResult);
|
||||
|
||||
MOZ_ALWAYS_SUCCEEDS(
|
||||
originUsageResult->GetUsage(&aStorageEstimate.mUsage.Construct()));
|
||||
|
||||
MOZ_ALWAYS_SUCCEEDS(
|
||||
originUsageResult->GetLimit(&aStorageEstimate.mQuota.Construct()));
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -18,26 +18,19 @@ class UsageInfo
|
|||
{
|
||||
public:
|
||||
UsageInfo()
|
||||
: mCanceled(false), mDatabaseUsage(0), mFileUsage(0), mLimit(0)
|
||||
: mDatabaseUsage(0)
|
||||
, mFileUsage(0)
|
||||
, mLimit(0)
|
||||
{ }
|
||||
|
||||
virtual ~UsageInfo()
|
||||
{ }
|
||||
|
||||
bool
|
||||
Canceled()
|
||||
void
|
||||
Append(const UsageInfo& aUsageInfo)
|
||||
{
|
||||
return mCanceled;
|
||||
}
|
||||
|
||||
nsresult
|
||||
Cancel()
|
||||
{
|
||||
if (mCanceled.exchange(true)) {
|
||||
NS_WARNING("Canceled more than once?!");
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
return NS_OK;
|
||||
IncrementUsage(&mDatabaseUsage, aUsageInfo.mDatabaseUsage);
|
||||
IncrementUsage(&mFileUsage, aUsageInfo.mFileUsage);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -104,9 +97,6 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
mozilla::Atomic<bool> mCanceled;
|
||||
|
||||
private:
|
||||
uint64_t mDatabaseUsage;
|
||||
uint64_t mFileUsage;
|
||||
|
|
|
@ -15,6 +15,7 @@ XPIDL_SOURCES += [
|
|||
'nsIQuotaCallbacks.idl',
|
||||
'nsIQuotaManagerService.idl',
|
||||
'nsIQuotaRequests.idl',
|
||||
'nsIQuotaResults.idl',
|
||||
]
|
||||
|
||||
XPIDL_MODULE = 'dom_quota'
|
||||
|
@ -43,6 +44,7 @@ UNIFIED_SOURCES += [
|
|||
'FileStreams.cpp',
|
||||
'QuotaManagerService.cpp',
|
||||
'QuotaRequests.cpp',
|
||||
'QuotaResults.cpp',
|
||||
'StorageManager.cpp',
|
||||
]
|
||||
|
||||
|
|
|
@ -41,6 +41,21 @@ interface nsIQuotaManagerService : nsISupports
|
|||
initStoragesForPrincipal(in nsIPrincipal aPrincipal,
|
||||
in ACString aPersistenceType);
|
||||
|
||||
/**
|
||||
* Schedules an asynchronous callback that will inspect all origins and
|
||||
* return the total amount of disk space being used by storages for each
|
||||
* origin separately.
|
||||
*
|
||||
* @param aCallback
|
||||
* The callback that will be called when the usage is available.
|
||||
* @param aGetAll
|
||||
* An optional boolean to indicate inspection of all origins,
|
||||
* including internal ones.
|
||||
*/
|
||||
[must_use] nsIQuotaUsageRequest
|
||||
getUsage(in nsIQuotaUsageCallback aCallback,
|
||||
[optional] in boolean aGetAll);
|
||||
|
||||
/**
|
||||
* Schedules an asynchronous callback that will return the total amount of
|
||||
* disk space being used by storages for the given origin.
|
||||
|
|
|
@ -22,11 +22,10 @@ interface nsIQuotaRequestBase : nsISupports
|
|||
[scriptable, uuid(166e28e6-cf6d-4927-a6d7-b51bca9d3469)]
|
||||
interface nsIQuotaUsageRequest : nsIQuotaRequestBase
|
||||
{
|
||||
[must_use] readonly attribute unsigned long long usage;
|
||||
|
||||
[must_use] readonly attribute unsigned long long fileUsage;
|
||||
|
||||
[must_use] readonly attribute unsigned long long limit;
|
||||
// The result can contain one of these types:
|
||||
// array of nsIQuotaUsageResult
|
||||
// nsIQuotaOriginUsageResult
|
||||
[must_use] readonly attribute nsIVariant result;
|
||||
|
||||
attribute nsIQuotaUsageCallback callback;
|
||||
|
||||
|
@ -37,6 +36,9 @@ interface nsIQuotaUsageRequest : nsIQuotaRequestBase
|
|||
[scriptable, uuid(22890e3e-ff25-4372-9684-d901060e2f6c)]
|
||||
interface nsIQuotaRequest : nsIQuotaRequestBase
|
||||
{
|
||||
// The result can contain one of these types:
|
||||
// void
|
||||
// bool
|
||||
[must_use] readonly attribute nsIVariant result;
|
||||
|
||||
attribute nsIQuotaCallback callback;
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=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 "nsISupports.idl"
|
||||
|
||||
[scriptable, function, uuid(d8c9328b-9aa8-4f5d-90e6-482de4a6d5b8)]
|
||||
interface nsIQuotaUsageResult : nsISupports
|
||||
{
|
||||
readonly attribute ACString origin;
|
||||
|
||||
readonly attribute boolean persisted;
|
||||
|
||||
readonly attribute unsigned long long usage;
|
||||
};
|
||||
|
||||
[scriptable, function, uuid(96df03d2-116a-493f-bb0b-118c212a6b32)]
|
||||
interface nsIQuotaOriginUsageResult : nsISupports
|
||||
{
|
||||
readonly attribute unsigned long long usage;
|
||||
|
||||
readonly attribute unsigned long long fileUsage;
|
||||
|
||||
readonly attribute unsigned long long limit;
|
||||
};
|
Двоичный файл не отображается.
|
@ -261,12 +261,24 @@ function getPersistedFromMetadata(readBuffer)
|
|||
return !!view[persistedPosition];
|
||||
}
|
||||
|
||||
function grabUsageAndContinueHandler(request)
|
||||
function grabResultAndContinueHandler(request)
|
||||
{
|
||||
testGenerator.next(request.usage);
|
||||
testGenerator.next(request.result);
|
||||
}
|
||||
|
||||
function getUsage(usageHandler)
|
||||
function grabUsageAndContinueHandler(request)
|
||||
{
|
||||
testGenerator.next(request.result.usage);
|
||||
}
|
||||
|
||||
function getUsage(usageHandler, getAll)
|
||||
{
|
||||
let request = SpecialPowers._getQuotaManager().getUsage(usageHandler, getAll);
|
||||
|
||||
return request;
|
||||
}
|
||||
|
||||
function getCurrentUsage(usageHandler)
|
||||
{
|
||||
let principal = Cc["@mozilla.org/systemprincipal;1"]
|
||||
.createInstance(Ci.nsIPrincipal);
|
||||
|
|
|
@ -38,7 +38,7 @@ function* testSteps()
|
|||
|
||||
info("Getting usage");
|
||||
|
||||
getUsage(grabUsageAndContinueHandler);
|
||||
getCurrentUsage(grabUsageAndContinueHandler);
|
||||
let usage = yield undefined;
|
||||
|
||||
ok(usage == 0, "Usage is zero");
|
||||
|
@ -53,7 +53,7 @@ function* testSteps()
|
|||
|
||||
info("Getting usage");
|
||||
|
||||
getUsage(grabUsageAndContinueHandler);
|
||||
getCurrentUsage(grabUsageAndContinueHandler);
|
||||
usage = yield undefined;
|
||||
|
||||
ok(usage > 0, "Usage is not zero");
|
||||
|
|
|
@ -0,0 +1,127 @@
|
|||
/**
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
var testGenerator = testSteps();
|
||||
|
||||
function* testSteps()
|
||||
{
|
||||
const origins = [
|
||||
{
|
||||
origin: "http://example.com",
|
||||
persisted: false,
|
||||
usage: 49152
|
||||
},
|
||||
|
||||
{
|
||||
origin: "http://localhost",
|
||||
persisted: false,
|
||||
usage: 147456
|
||||
},
|
||||
|
||||
{
|
||||
origin: "http://www.mozilla.org",
|
||||
persisted: true,
|
||||
usage: 98304
|
||||
}
|
||||
];
|
||||
|
||||
const allOrigins = [
|
||||
{
|
||||
origin: "chrome",
|
||||
persisted: false,
|
||||
usage: 147456
|
||||
},
|
||||
|
||||
{
|
||||
origin: "http://example.com",
|
||||
persisted: false,
|
||||
usage: 49152
|
||||
},
|
||||
|
||||
{
|
||||
origin: "http://localhost",
|
||||
persisted: false,
|
||||
usage: 147456
|
||||
},
|
||||
|
||||
{
|
||||
origin: "http://www.mozilla.org",
|
||||
persisted: true,
|
||||
usage: 98304
|
||||
}
|
||||
];
|
||||
|
||||
function verifyResult(result, origins) {
|
||||
ok(result instanceof Array, "Got an array object");
|
||||
ok(result.length == origins.length, "Correct number of elements");
|
||||
|
||||
info("Sorting elements");
|
||||
|
||||
result.sort(function(a, b) {
|
||||
let originA = a.origin
|
||||
let originB = b.origin
|
||||
|
||||
if (originA < originB) {
|
||||
return -1;
|
||||
}
|
||||
if (originA > originB) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
});
|
||||
|
||||
info("Verifying elements");
|
||||
|
||||
for (let i = 0; i < result.length; i++) {
|
||||
let a = result[i];
|
||||
let b = origins[i];
|
||||
ok(a.origin == b.origin, "Origin equals");
|
||||
ok(a.persisted == b.persisted, "Persisted equals");
|
||||
ok(a.usage == b.usage, "Usage equals");
|
||||
}
|
||||
}
|
||||
|
||||
info("Clearing");
|
||||
|
||||
clear(continueToNextStepSync);
|
||||
yield undefined;
|
||||
|
||||
info("Getting usage");
|
||||
|
||||
getUsage(grabResultAndContinueHandler, /* getAll */ true);
|
||||
let result = yield undefined;
|
||||
|
||||
info("Verifying result");
|
||||
|
||||
verifyResult(result, []);
|
||||
|
||||
info("Installing package");
|
||||
|
||||
// The profile contains IndexedDB databases placed across the repositories.
|
||||
// The file create_db.js in the package was run locally, specifically it was
|
||||
// temporarily added to xpcshell.ini and then executed:
|
||||
// mach xpcshell-test --interactive dom/quota/test/unit/create_db.js
|
||||
installPackage("getUsage_profile");
|
||||
|
||||
info("Getting usage");
|
||||
|
||||
getUsage(grabResultAndContinueHandler, /* getAll */ false);
|
||||
result = yield undefined;
|
||||
|
||||
info("Verifying result");
|
||||
|
||||
verifyResult(result, origins);
|
||||
|
||||
info("Getting usage");
|
||||
|
||||
getUsage(grabResultAndContinueHandler, /* getAll */ true);
|
||||
result = yield undefined;
|
||||
|
||||
info("Verifying result");
|
||||
|
||||
verifyResult(result, allOrigins);
|
||||
|
||||
finishTest();
|
||||
}
|
|
@ -131,7 +131,7 @@ function* testSteps()
|
|||
|
||||
info("Getting usage");
|
||||
|
||||
request = getUsage(continueToNextStepSync);
|
||||
request = getCurrentUsage(continueToNextStepSync);
|
||||
yield undefined;
|
||||
|
||||
ok(request.resultCode == NS_ERROR_UNEXPECTED, "Get usage failed");
|
||||
|
@ -140,7 +140,7 @@ function* testSteps()
|
|||
|
||||
info("Getting usage");
|
||||
|
||||
request = getUsage(continueToNextStepSync);
|
||||
request = getCurrentUsage(continueToNextStepSync);
|
||||
yield undefined;
|
||||
|
||||
ok(request.resultCode == NS_OK, "Get usage succeeded");
|
||||
|
@ -156,7 +156,7 @@ function* testSteps()
|
|||
|
||||
info("Getting usage");
|
||||
|
||||
request = getUsage(continueToNextStepSync);
|
||||
request = getCurrentUsage(continueToNextStepSync);
|
||||
yield undefined;
|
||||
|
||||
ok(request.resultCode == NS_OK, "Get usage succeeded");
|
||||
|
|
|
@ -7,6 +7,7 @@ head = head.js
|
|||
support-files =
|
||||
basics_profile.zip
|
||||
defaultStorageUpgrade_profile.zip
|
||||
getUsage_profile.zip
|
||||
idbSubdirUpgrade1_profile.zip
|
||||
idbSubdirUpgrade2_profile.zip
|
||||
morgueCleanup_profile.zip
|
||||
|
@ -18,6 +19,7 @@ support-files =
|
|||
|
||||
[test_basics.js]
|
||||
[test_defaultStorageUpgrade.js]
|
||||
[test_getUsage.js]
|
||||
[test_idbSubdirUpgrade.js]
|
||||
[test_morgueCleanup.js]
|
||||
[test_obsoleteOriginAttributesUpgrade.js]
|
||||
|
|
|
@ -20,7 +20,6 @@
|
|||
#include "nsIScriptError.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsContentPolicyUtils.h"
|
||||
#include "nsPrincipal.h"
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
|
|
|
@ -57,6 +57,7 @@
|
|||
else {
|
||||
window.parent.postMessage({result: "websocket-error"}, "*");
|
||||
}
|
||||
mySocket.close();
|
||||
};
|
||||
mySocket.onerror = function(e) {
|
||||
// debug information for Bug 1316305
|
||||
|
|
|
@ -58,6 +58,7 @@
|
|||
else {
|
||||
window.parent.postMessage({result: "websocket-error"}, "*");
|
||||
}
|
||||
mySocket.close();
|
||||
};
|
||||
mySocket.onerror = function(e) {
|
||||
window.parent.postMessage({result: "websocket-unexpected-error"}, "*");
|
||||
|
|
|
@ -205,9 +205,6 @@ public:
|
|||
compileOptions.setFileAndLine(NS_ConvertUTF16toUTF8(mURL).get(), 0);
|
||||
compileOptions.setVersion(JSVERSION_DEFAULT);
|
||||
compileOptions.setIsRunOnce(true);
|
||||
|
||||
// We only need the setNoScriptRval bit when compiling off-thread here,
|
||||
// since otherwise nsJSUtils::EvaluateString will set it up for us.
|
||||
compileOptions.setNoScriptRval(true);
|
||||
|
||||
JSAutoCompartment comp(cx, globalObj);
|
||||
|
|
|
@ -427,14 +427,19 @@ nsXBLProtoImplField::InstallField(JS::Handle<JSObject*> aBoundNode,
|
|||
JS::CompileOptions options(cx);
|
||||
options.setFileAndLine(uriSpec.get(), mLineNumber)
|
||||
.setVersion(JSVERSION_LATEST);
|
||||
nsJSUtils::EvaluateOptions evalOptions(cx);
|
||||
if (!nsJSUtils::GetScopeChainForElement(cx, boundElement,
|
||||
evalOptions.scopeChain)) {
|
||||
JS::AutoObjectVector scopeChain(cx);
|
||||
if (!nsJSUtils::GetScopeChainForElement(cx, boundElement, scopeChain)) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
rv = nsJSUtils::EvaluateString(cx, nsDependentString(mFieldText,
|
||||
mFieldTextLength),
|
||||
scopeObject, options, evalOptions, &result);
|
||||
rv = NS_OK;
|
||||
{
|
||||
nsJSUtils::ExecutionContext exec(cx, scopeObject);
|
||||
exec.SetScopeChain(scopeChain);
|
||||
exec.CompileAndExec(options, nsDependentString(mFieldText,
|
||||
mFieldTextLength));
|
||||
rv = exec.ExtractReturnValue(&result);
|
||||
}
|
||||
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
#include "nsIChannel.h"
|
||||
#include "nsIInputStream.h"
|
||||
#include "nsIProtocolHandler.h"
|
||||
#include "nsNullPrincipal.h"
|
||||
#include "NullPrincipal.h"
|
||||
#include "mozilla/Monitor.h"
|
||||
#include "plstr.h"
|
||||
#include "prtime.h"
|
||||
|
|
|
@ -1299,6 +1299,10 @@ RecordedSourceSurfaceCreation::~RecordedSourceSurfaceCreation()
|
|||
bool
|
||||
RecordedSourceSurfaceCreation::PlayEvent(Translator *aTranslator) const
|
||||
{
|
||||
if (!mData) {
|
||||
return false;
|
||||
}
|
||||
|
||||
RefPtr<SourceSurface> src = aTranslator->GetReferenceDrawTarget()->
|
||||
CreateSourceSurfaceFromData(mData, mSize, mSize.width * BytesPerPixel(mFormat), mFormat);
|
||||
aTranslator->AddSourceSurface(mRefPtr, src);
|
||||
|
@ -1311,6 +1315,7 @@ RecordedSourceSurfaceCreation::RecordToStream(ostream &aStream) const
|
|||
WriteElement(aStream, mRefPtr);
|
||||
WriteElement(aStream, mSize);
|
||||
WriteElement(aStream, mFormat);
|
||||
MOZ_ASSERT(mData);
|
||||
for (int y = 0; y < mSize.height; y++) {
|
||||
aStream.write((const char*)mData + y * mStride, BytesPerPixel(mFormat) * mSize.width);
|
||||
}
|
||||
|
@ -1322,8 +1327,12 @@ RecordedSourceSurfaceCreation::RecordedSourceSurfaceCreation(istream &aStream)
|
|||
ReadElement(aStream, mRefPtr);
|
||||
ReadElement(aStream, mSize);
|
||||
ReadElement(aStream, mFormat);
|
||||
mData = (uint8_t*)new char[mSize.width * mSize.height * BytesPerPixel(mFormat)];
|
||||
aStream.read((char*)mData, mSize.width * mSize.height * BytesPerPixel(mFormat));
|
||||
mData = (uint8_t*)new (fallible) char[mSize.width * mSize.height * BytesPerPixel(mFormat)];
|
||||
if (!mData) {
|
||||
gfxWarning() << "RecordedSourceSurfaceCreation failed to allocate data";
|
||||
} else {
|
||||
aStream.read((char*)mData, mSize.width * mSize.height * BytesPerPixel(mFormat));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -592,29 +592,35 @@ static bool clip_to_limit(const SkRegion& orig, SkRegion* reduced) {
|
|||
}
|
||||
|
||||
/**
|
||||
* Variant of SkScalarRoundToInt, identical to SkDScalarRoundToInt except when the input fraction
|
||||
* is 0.5. In this case only, round the value down. This is used to round the top and left
|
||||
* of a rectangle, and corresponds to the way the scan converter treats the top and left edges.
|
||||
* Variants of SkScalarRoundToInt, identical to SkDScalarRoundToInt except when the input fraction
|
||||
* is 0.5. When SK_RASTERIZE_EVEN_ROUNDING is enabled, we must bias the result before rounding to
|
||||
* account for potential FDot6 rounding edge-cases.
|
||||
*/
|
||||
#ifdef SK_RASTERIZE_EVEN_ROUNDING
|
||||
static const double kRoundBias = 0.5 / SK_FDot6One;
|
||||
#else
|
||||
static const double kRoundBias = 0.0;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Round the value down. This is used to round the top and left of a rectangle,
|
||||
* and corresponds to the way the scan converter treats the top and left edges.
|
||||
*/
|
||||
static inline int round_down_to_int(SkScalar x) {
|
||||
double xx = x;
|
||||
xx += 0.5;
|
||||
double floorXX = floor(xx);
|
||||
return (int)floorXX - (xx == floorXX);
|
||||
xx -= 0.5 + kRoundBias;
|
||||
return (int)ceil(xx);
|
||||
}
|
||||
|
||||
#ifdef SK_RASTERIZE_EVEN_ROUNDING
|
||||
/**
|
||||
* Variant of SkDScalarRoundToInt that allows offseting the input by a small fraction
|
||||
* while trying to preserve intermediate double-precision (rather than directly adding
|
||||
* the bias to the input at lower single-precision).
|
||||
* Round the value up. This is used to round the bottom and right of a rectangle,
|
||||
* and corresponds to the way the scan converter treats the bottom and right edges.
|
||||
*/
|
||||
static inline int round_biased_to_int(SkScalar x, SkScalar bias) {
|
||||
static inline int round_up_to_int(SkScalar x) {
|
||||
double xx = x;
|
||||
xx += 0.5 + bias;
|
||||
xx += 0.5 + kRoundBias;
|
||||
return (int)floor(xx);
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Variant of SkRect::round() that explicitly performs the rounding step (i.e. floor(x + 0.5))
|
||||
|
@ -635,26 +641,21 @@ static inline int round_biased_to_int(SkScalar x, SkScalar bias) {
|
|||
* SkASSERT(0 == iright); // <--- succeeds
|
||||
*
|
||||
*
|
||||
* If using SK_RASTERIZE_EVEN_ROUNDING, we need to ensure that bottom and right account for
|
||||
* edges bounded by this rect being rounded to FDot6 format before being later rounded to an
|
||||
* integer. For example, a value like 0.499 can be below 0.5, but round to 0.5 as FDot6, which
|
||||
* would finally round to the integer 1, instead of just rounding to 0.
|
||||
* If using SK_RASTERIZE_EVEN_ROUNDING, we need to ensure we account for edges bounded by this
|
||||
* rect being rounded to FDot6 format before being later rounded to an integer. For example, a
|
||||
* value like 0.499 can be below 0.5, but round to 0.5 as FDot6, which would finally round to
|
||||
* the integer 1, instead of just rounding to 0.
|
||||
*
|
||||
* To handle this, a small bias of half an FDot6 increment is added before actually rounding to
|
||||
* an integer value. This simulates the rounding of SkScalarRoundToFDot6 without incurring the
|
||||
* range loss of converting to FDot6 format first, preserving the integer range for the SkIRect.
|
||||
* Thus, bottom and right are rounded in this manner (biased up), ensuring the rect is large enough.
|
||||
* Top and left can round as normal since they will round (biased down) to values less or equal
|
||||
* to the desired rect origin.
|
||||
* Thus, bottom and right are rounded in this manner (biased up), ensuring the rect is large
|
||||
* enough.
|
||||
*/
|
||||
static void round_asymmetric_to_int(const SkRect& src, SkIRect* dst) {
|
||||
SkASSERT(dst);
|
||||
dst->set(round_down_to_int(src.fLeft), round_down_to_int(src.fTop),
|
||||
#ifdef SK_RASTERIZE_EVEN_ROUNDING
|
||||
round_biased_to_int(src.fRight, 0.5f / SK_FDot6One), round_biased_to_int(src.fBottom, 0.5f / SK_FDot6One));
|
||||
#else
|
||||
SkDScalarRoundToInt(src.fRight), SkDScalarRoundToInt(src.fBottom));
|
||||
#endif
|
||||
round_up_to_int(src.fRight), round_up_to_int(src.fBottom));
|
||||
}
|
||||
|
||||
void SkScan::FillPath(const SkPath& path, const SkRegion& origClip,
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -21,103 +21,4 @@ typedef struct _FcPattern FcPattern;
|
|||
typedef struct FT_FaceRec_* FT_Face;
|
||||
typedef struct FT_LibraryRec_ *FT_Library;
|
||||
|
||||
class gfxPangoFontGroup : public gfxFontGroup {
|
||||
public:
|
||||
gfxPangoFontGroup(const mozilla::FontFamilyList& aFontFamilyList,
|
||||
const gfxFontStyle *aStyle,
|
||||
gfxUserFontSet *aUserFontSet,
|
||||
gfxFloat aDevToCssSize);
|
||||
virtual ~gfxPangoFontGroup();
|
||||
|
||||
virtual gfxFontGroup *Copy(const gfxFontStyle *aStyle);
|
||||
|
||||
virtual gfxFont* GetFirstValidFont(uint32_t aCh = 0x20);
|
||||
|
||||
virtual void UpdateUserFonts();
|
||||
|
||||
virtual already_AddRefed<gfxFont>
|
||||
FindFontForChar(uint32_t aCh, uint32_t aPrevCh, uint32_t aNextCh,
|
||||
Script aRunScript, gfxFont *aPrevMatchedFont,
|
||||
uint8_t *aMatchType);
|
||||
|
||||
static void Shutdown();
|
||||
|
||||
// Used for @font-face { src: local(); }
|
||||
static gfxFontEntry *NewFontEntry(const nsAString& aFontName,
|
||||
uint16_t aWeight,
|
||||
int16_t aStretch,
|
||||
uint8_t aStyle);
|
||||
// Used for @font-face { src: url(); }
|
||||
static gfxFontEntry *NewFontEntry(const nsAString& aFontName,
|
||||
uint16_t aWeight,
|
||||
int16_t aStretch,
|
||||
uint8_t aStyle,
|
||||
const uint8_t* aFontData,
|
||||
uint32_t aLength);
|
||||
|
||||
static FT_Library GetFTLibrary();
|
||||
|
||||
private:
|
||||
|
||||
virtual gfxFont *GetFontAt(int32_t i, uint32_t aCh = 0x20);
|
||||
|
||||
// @param aLang [in] language to use for pref fonts and system default font
|
||||
// selection, or nullptr for the language guessed from the
|
||||
// gfxFontStyle.
|
||||
// The FontGroup holds a reference to this set.
|
||||
gfxFcFontSet *GetFontSet(PangoLanguage *aLang = nullptr);
|
||||
|
||||
class FontSetByLangEntry {
|
||||
public:
|
||||
FontSetByLangEntry(PangoLanguage *aLang, gfxFcFontSet *aFontSet);
|
||||
PangoLanguage *mLang;
|
||||
RefPtr<gfxFcFontSet> mFontSet;
|
||||
};
|
||||
// There is only one of entry in this array unless characters from scripts
|
||||
// of other languages are measured.
|
||||
AutoTArray<FontSetByLangEntry,1> mFontSets;
|
||||
|
||||
gfxFloat mSizeAdjustFactor;
|
||||
PangoLanguage *mPangoLanguage;
|
||||
|
||||
// @param aLang [in] language to use for pref fonts and system font
|
||||
// resolution, or nullptr to guess a language from the gfxFontStyle.
|
||||
// @param aMatchPattern [out] if non-nullptr, will return the pattern used.
|
||||
already_AddRefed<gfxFcFontSet>
|
||||
MakeFontSet(PangoLanguage *aLang, gfxFloat aSizeAdjustFactor,
|
||||
nsAutoRef<FcPattern> *aMatchPattern = nullptr);
|
||||
|
||||
gfxFcFontSet *GetBaseFontSet();
|
||||
gfxFcFont *GetBaseFont();
|
||||
|
||||
gfxFloat GetSizeAdjustFactor()
|
||||
{
|
||||
if (mFontSets.Length() == 0)
|
||||
GetBaseFontSet();
|
||||
return mSizeAdjustFactor;
|
||||
}
|
||||
|
||||
// old helper methods from gfxFontGroup, moved here so that those methods
|
||||
// can be revamped without affecting the legacy code here
|
||||
|
||||
// iterate over the fontlist, lookup names and expand generics
|
||||
void EnumerateFontListPFG(nsIAtom *aLanguage, void *aClosure);
|
||||
|
||||
// expand a generic to a list of specific names based on prefs
|
||||
void FindGenericFontsPFG(mozilla::FontFamilyType aGenericType,
|
||||
nsIAtom *aLanguage,
|
||||
void *aClosure);
|
||||
|
||||
// lookup and add a font with a given name (i.e. *not* a generic!)
|
||||
void FindPlatformFontPFG(const nsAString& aName,
|
||||
bool aUseFontSet,
|
||||
void *aClosure);
|
||||
|
||||
static void
|
||||
ResolveGenericFontNamesPFG(mozilla::FontFamilyType aGenericType,
|
||||
nsIAtom *aLanguage,
|
||||
nsTArray<nsString>& aGenericFamilies);
|
||||
|
||||
};
|
||||
|
||||
#endif /* GFX_FONTCONFIG_FONTS_H */
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -8,11 +8,7 @@
|
|||
|
||||
#include "gfxPlatform.h"
|
||||
|
||||
#include "mozilla/MathAlgorithms.h"
|
||||
#include "nsAutoRef.h"
|
||||
#include "nsTArray.h"
|
||||
#include "nsTHashtable.h"
|
||||
#include "nsISupportsImpl.h"
|
||||
#include "gfxFT2FontBase.h"
|
||||
|
||||
#include <fontconfig/fontconfig.h>
|
||||
|
@ -40,285 +36,14 @@ public:
|
|||
static void Release(FcCharSet *ptr) { FcCharSetDestroy(ptr); }
|
||||
};
|
||||
|
||||
class gfxIgnoreCaseCStringComparator
|
||||
{
|
||||
public:
|
||||
bool Equals(const nsACString& a, const nsACString& b) const
|
||||
{
|
||||
return nsCString(a).Equals(b, nsCaseInsensitiveCStringComparator());
|
||||
}
|
||||
|
||||
bool LessThan(const nsACString& a, const nsACString& b) const
|
||||
{
|
||||
return a < b;
|
||||
}
|
||||
};
|
||||
|
||||
class gfxFontconfigUtils {
|
||||
public:
|
||||
gfxFontconfigUtils();
|
||||
|
||||
static gfxFontconfigUtils* GetFontconfigUtils() {
|
||||
if (!sUtils)
|
||||
sUtils = new gfxFontconfigUtils();
|
||||
return sUtils;
|
||||
}
|
||||
|
||||
static void Shutdown();
|
||||
|
||||
nsresult GetFontList(nsIAtom *aLangGroup,
|
||||
const nsACString& aGenericFamily,
|
||||
nsTArray<nsString>& aListOfFonts);
|
||||
|
||||
nsresult UpdateFontList();
|
||||
|
||||
nsresult GetStandardFamilyName(const nsAString& aFontName, nsAString& aFamilyName);
|
||||
|
||||
const nsTArray< nsCountedRef<FcPattern> >&
|
||||
GetFontsForFamily(const FcChar8 *aFamilyName);
|
||||
|
||||
const nsTArray< nsCountedRef<FcPattern> >&
|
||||
GetFontsForFullname(const FcChar8 *aFullname);
|
||||
|
||||
// Returns the best support that any font offers for |aLang|.
|
||||
FcLangResult GetBestLangSupport(const FcChar8 *aLang);
|
||||
// Returns the fonts offering this best level of support.
|
||||
const nsTArray< nsCountedRef<FcPattern> >&
|
||||
GetFontsForLang(const FcChar8 *aLang);
|
||||
|
||||
// Retuns the language support for a fontconfig font pattern
|
||||
static FcLangResult GetLangSupport(FcPattern *aFont, const FcChar8 *aLang);
|
||||
|
||||
// Conversions between FcChar8*, which is unsigned char*,
|
||||
// and (signed) char*, that check the type of the argument.
|
||||
static const FcChar8 *ToFcChar8(const char *aCharPtr)
|
||||
{
|
||||
return reinterpret_cast<const FcChar8*>(aCharPtr);
|
||||
}
|
||||
static const FcChar8 *ToFcChar8(const nsCString& aCString)
|
||||
{
|
||||
return ToFcChar8(aCString.get());
|
||||
}
|
||||
static const char *ToCString(const FcChar8 *aChar8Ptr)
|
||||
{
|
||||
return reinterpret_cast<const char*>(aChar8Ptr);
|
||||
}
|
||||
|
||||
static uint8_t FcSlantToThebesStyle(int aFcSlant);
|
||||
static uint8_t GetThebesStyle(FcPattern *aPattern); // slant
|
||||
static uint16_t GetThebesWeight(FcPattern *aPattern);
|
||||
static int16_t GetThebesStretch(FcPattern *aPattern);
|
||||
|
||||
static int GetFcSlant(const gfxFontStyle& aFontStyle);
|
||||
// Returns a precise FC_WEIGHT from |aBaseWeight|,
|
||||
// which is a CSS absolute weight / 100.
|
||||
static int FcWeightForBaseWeight(int8_t aBaseWeight);
|
||||
|
||||
static int FcWidthForThebesStretch(int16_t aStretch);
|
||||
|
||||
static bool GetFullnameFromFamilyAndStyle(FcPattern *aFont,
|
||||
nsACString *aFullname);
|
||||
|
||||
// This doesn't consider which faces exist, and so initializes the pattern
|
||||
// using a guessed weight, and doesn't consider sizeAdjust.
|
||||
static nsReturnRef<FcPattern>
|
||||
NewPattern(const nsTArray<nsString>& aFamilies,
|
||||
const gfxFontStyle& aFontStyle, const char *aLang);
|
||||
|
||||
/**
|
||||
* @param aLangGroup [in] a Mozilla langGroup.
|
||||
* @param aFcLang [out] returns a language suitable for fontconfig
|
||||
* matching |aLangGroup| or an empty string if no match is found.
|
||||
*/
|
||||
static void GetSampleLangForGroup(nsIAtom *aLangGroup,
|
||||
nsACString *aFcLang);
|
||||
|
||||
protected:
|
||||
// Base class for hash table entries with case-insensitive FcChar8
|
||||
// string keys.
|
||||
class FcStrEntryBase : public PLDHashEntryHdr {
|
||||
public:
|
||||
typedef const FcChar8 *KeyType;
|
||||
typedef const FcChar8 *KeyTypePointer;
|
||||
|
||||
static KeyTypePointer KeyToPointer(KeyType aKey) { return aKey; }
|
||||
// Case-insensitive hash.
|
||||
//
|
||||
// fontconfig always ignores case of ASCII characters in family
|
||||
// names and languages, but treatment of whitespace in families is
|
||||
// not consistent. FcFontSort and FcFontMatch ignore whitespace
|
||||
// except for whitespace in the first character, while FcFontList
|
||||
// and config subsitution tests require whitespace to match
|
||||
// exactly. CSS 2.1 implies that whitespace is important in the
|
||||
// font-family property. FcStrCmpIgnoreCase considers whitespace
|
||||
// important.
|
||||
static PLDHashNumber HashKey(const FcChar8 *aKey) {
|
||||
uint32_t hash = 0;
|
||||
for (const FcChar8 *c = aKey; *c != '\0'; ++c) {
|
||||
hash = mozilla::RotateLeft(hash, 3) ^ FcToLower(*c);
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
enum { ALLOW_MEMMOVE = true };
|
||||
};
|
||||
|
||||
public:
|
||||
// Hash entry with a dependent const FcChar8* pointer to an external
|
||||
// string for a key (and no data). The user must ensure that the string
|
||||
// associated with the pointer is not destroyed. This entry type is
|
||||
// useful for family name keys as the family name string is held in the
|
||||
// font pattern.
|
||||
class DepFcStrEntry : public FcStrEntryBase {
|
||||
public:
|
||||
// When constructing a new entry in the hashtable, the key is left
|
||||
// nullptr. The caller of PutEntry() must fill in mKey when nullptr.
|
||||
// This provides a mechanism for the caller of PutEntry() to determine
|
||||
// whether the entry has been initialized.
|
||||
explicit DepFcStrEntry(KeyTypePointer aName)
|
||||
: mKey(nullptr) { }
|
||||
|
||||
DepFcStrEntry(const DepFcStrEntry& toCopy)
|
||||
: mKey(toCopy.mKey) { }
|
||||
|
||||
bool KeyEquals(KeyTypePointer aKey) const {
|
||||
return FcStrCmpIgnoreCase(aKey, mKey) == 0;
|
||||
}
|
||||
|
||||
const FcChar8 *mKey;
|
||||
};
|
||||
|
||||
// Hash entry that uses a copy of an FcChar8 string to store the key.
|
||||
// This entry type is useful for language keys, as languages are usually
|
||||
// not stored as strings in font patterns.
|
||||
class CopiedFcStrEntry : public FcStrEntryBase {
|
||||
public:
|
||||
// When constructing a new entry in the hashtable, the key is void.
|
||||
// The caller of PutEntry() must call InitKey() when IsKeyInitialized()
|
||||
// returns false. This provides a mechanism for the caller of
|
||||
// PutEntry() to determine whether the entry has been initialized.
|
||||
explicit CopiedFcStrEntry(KeyTypePointer aName) {
|
||||
mKey.SetIsVoid(true);
|
||||
}
|
||||
|
||||
CopiedFcStrEntry(const CopiedFcStrEntry& toCopy)
|
||||
: mKey(toCopy.mKey) { }
|
||||
|
||||
bool KeyEquals(KeyTypePointer aKey) const {
|
||||
return FcStrCmpIgnoreCase(aKey, ToFcChar8(mKey)) == 0;
|
||||
}
|
||||
|
||||
bool IsKeyInitialized() { return !mKey.IsVoid(); }
|
||||
void InitKey(const FcChar8* aKey) { mKey.Assign(ToCString(aKey)); }
|
||||
|
||||
private:
|
||||
nsCString mKey;
|
||||
};
|
||||
|
||||
protected:
|
||||
class FontsByFcStrEntry : public DepFcStrEntry {
|
||||
public:
|
||||
explicit FontsByFcStrEntry(KeyTypePointer aName)
|
||||
: DepFcStrEntry(aName) { }
|
||||
|
||||
FontsByFcStrEntry(const FontsByFcStrEntry& toCopy)
|
||||
: DepFcStrEntry(toCopy), mFonts(toCopy.mFonts) { }
|
||||
|
||||
bool AddFont(FcPattern *aFont) {
|
||||
return mFonts.AppendElement(aFont) != nullptr;
|
||||
}
|
||||
const nsTArray< nsCountedRef<FcPattern> >& GetFonts() {
|
||||
return mFonts;
|
||||
}
|
||||
private:
|
||||
nsTArray< nsCountedRef<FcPattern> > mFonts;
|
||||
};
|
||||
|
||||
// FontsByFullnameEntry is similar to FontsByFcStrEntry (used for
|
||||
// mFontsByFamily) except for two differences:
|
||||
//
|
||||
// * The font does not always contain a single string for the fullname, so
|
||||
// the key is sometimes a combination of family and style.
|
||||
//
|
||||
// * There is usually only one font.
|
||||
class FontsByFullnameEntry : public DepFcStrEntry {
|
||||
public:
|
||||
// When constructing a new entry in the hashtable, the key is left
|
||||
// nullptr. The caller of PutEntry() is must fill in mKey when adding
|
||||
// the first font if the key is not derived from the family and style.
|
||||
// If the key is derived from family and style, a font must be added.
|
||||
explicit FontsByFullnameEntry(KeyTypePointer aName)
|
||||
: DepFcStrEntry(aName) { }
|
||||
|
||||
FontsByFullnameEntry(const FontsByFullnameEntry& toCopy)
|
||||
: DepFcStrEntry(toCopy), mFonts(toCopy.mFonts) { }
|
||||
|
||||
bool KeyEquals(KeyTypePointer aKey) const;
|
||||
|
||||
bool AddFont(FcPattern *aFont) {
|
||||
return mFonts.AppendElement(aFont) != nullptr;
|
||||
}
|
||||
const nsTArray< nsCountedRef<FcPattern> >& GetFonts() {
|
||||
return mFonts;
|
||||
}
|
||||
|
||||
// Don't memmove the AutoTArray.
|
||||
enum { ALLOW_MEMMOVE = false };
|
||||
private:
|
||||
// There is usually only one font, but sometimes more.
|
||||
AutoTArray<nsCountedRef<FcPattern>,1> mFonts;
|
||||
};
|
||||
|
||||
class LangSupportEntry : public CopiedFcStrEntry {
|
||||
public:
|
||||
explicit LangSupportEntry(KeyTypePointer aName)
|
||||
: CopiedFcStrEntry(aName) { }
|
||||
|
||||
LangSupportEntry(const LangSupportEntry& toCopy)
|
||||
: CopiedFcStrEntry(toCopy), mSupport(toCopy.mSupport) { }
|
||||
|
||||
FcLangResult mSupport;
|
||||
nsTArray< nsCountedRef<FcPattern> > mFonts;
|
||||
};
|
||||
|
||||
static gfxFontconfigUtils* sUtils;
|
||||
|
||||
bool IsExistingFamily(const nsCString& aFamilyName);
|
||||
|
||||
nsresult GetFontListInternal(nsTArray<nsCString>& aListOfFonts,
|
||||
nsIAtom *aLangGroup);
|
||||
nsresult UpdateFontListInternal(bool aForce = false);
|
||||
|
||||
void AddFullnameEntries();
|
||||
|
||||
LangSupportEntry *GetLangSupportEntry(const FcChar8 *aLang,
|
||||
bool aWithFonts);
|
||||
|
||||
// mFontsByFamily and mFontsByFullname contain entries only for families
|
||||
// and fullnames for which there are fonts.
|
||||
nsTHashtable<FontsByFcStrEntry> mFontsByFamily;
|
||||
nsTHashtable<FontsByFullnameEntry> mFontsByFullname;
|
||||
// mLangSupportTable contains an entry for each language that has been
|
||||
// looked up through GetLangSupportEntry, even when the language is not
|
||||
// supported.
|
||||
nsTHashtable<LangSupportEntry> mLangSupportTable;
|
||||
const nsTArray< nsCountedRef<FcPattern> > mEmptyPatternArray;
|
||||
|
||||
FcConfig *mLastConfig;
|
||||
|
||||
#ifdef MOZ_BUNDLED_FONTS
|
||||
void ActivateBundledFonts();
|
||||
|
||||
nsCString mBundledFontsPath;
|
||||
bool mBundledFontsInitialized;
|
||||
#endif
|
||||
};
|
||||
|
||||
class gfxFontconfigFontBase : public gfxFT2FontBase {
|
||||
public:
|
||||
gfxFontconfigFontBase(cairo_scaled_font_t *aScaledFont,
|
||||
FcPattern *aPattern,
|
||||
gfxFontEntry *aFontEntry,
|
||||
const gfxFontStyle *aFontStyle);
|
||||
const gfxFontStyle *aFontStyle)
|
||||
: gfxFT2FontBase(aScaledFont, aFontEntry, aFontStyle)
|
||||
, mPattern(aPattern) { }
|
||||
|
||||
virtual FontType GetType() const override { return FONT_TYPE_FONTCONFIG; }
|
||||
virtual FcPattern *GetPattern() const { return mPattern; }
|
||||
|
|
|
@ -88,10 +88,6 @@
|
|||
#include "GLContextProvider.h"
|
||||
#include "mozilla/gfx/Logging.h"
|
||||
|
||||
#if defined(MOZ_WIDGET_GTK)
|
||||
#include "gfxPlatformGtk.h" // xxx - for UseFcFontList
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_WIDGET_ANDROID
|
||||
#include "TexturePoolOGL.h"
|
||||
#include "mozilla/layers/UiCompositorControllerChild.h"
|
||||
|
@ -711,17 +707,9 @@ gfxPlatform::Init()
|
|||
gPlatform->ComputeTileSize();
|
||||
|
||||
nsresult rv;
|
||||
|
||||
bool usePlatformFontList = true;
|
||||
#if defined(MOZ_WIDGET_GTK)
|
||||
usePlatformFontList = gfxPlatformGtk::UseFcFontList();
|
||||
#endif
|
||||
|
||||
if (usePlatformFontList) {
|
||||
rv = gfxPlatformFontList::Init();
|
||||
if (NS_FAILED(rv)) {
|
||||
MOZ_CRASH("Could not initialize gfxPlatformFontList");
|
||||
}
|
||||
rv = gfxPlatformFontList::Init();
|
||||
if (NS_FAILED(rv)) {
|
||||
MOZ_CRASH("Could not initialize gfxPlatformFontList");
|
||||
}
|
||||
|
||||
gPlatform->mScreenReferenceSurface =
|
||||
|
|
|
@ -67,23 +67,14 @@ using namespace mozilla;
|
|||
using namespace mozilla::gfx;
|
||||
using namespace mozilla::unicode;
|
||||
|
||||
gfxFontconfigUtils *gfxPlatformGtk::sFontconfigUtils = nullptr;
|
||||
|
||||
#if (MOZ_WIDGET_GTK == 2)
|
||||
static cairo_user_data_key_t cairo_gdk_drawable_key;
|
||||
#endif
|
||||
|
||||
bool gfxPlatformGtk::sUseFcFontList = false;
|
||||
|
||||
gfxPlatformGtk::gfxPlatformGtk()
|
||||
{
|
||||
gtk_init(nullptr, nullptr);
|
||||
|
||||
sUseFcFontList = mozilla::Preferences::GetBool("gfx.font_rendering.fontconfig.fontlist.enabled");
|
||||
if (!sUseFcFontList && !sFontconfigUtils) {
|
||||
sFontconfigUtils = gfxFontconfigUtils::GetFontconfigUtils();
|
||||
}
|
||||
|
||||
mMaxGenericSubstitutions = UNINITIALIZED_VALUE;
|
||||
|
||||
#ifdef MOZ_X11
|
||||
|
@ -117,12 +108,6 @@ gfxPlatformGtk::gfxPlatformGtk()
|
|||
|
||||
gfxPlatformGtk::~gfxPlatformGtk()
|
||||
{
|
||||
if (!sUseFcFontList) {
|
||||
gfxFontconfigUtils::Shutdown();
|
||||
sFontconfigUtils = nullptr;
|
||||
gfxPangoFontGroup::Shutdown();
|
||||
}
|
||||
|
||||
#ifdef MOZ_X11
|
||||
if (mCompositorDisplay) {
|
||||
XCloseDisplay(mCompositorDisplay);
|
||||
|
@ -200,27 +185,17 @@ gfxPlatformGtk::GetFontList(nsIAtom *aLangGroup,
|
|||
const nsACString& aGenericFamily,
|
||||
nsTArray<nsString>& aListOfFonts)
|
||||
{
|
||||
if (sUseFcFontList) {
|
||||
gfxPlatformFontList::PlatformFontList()->GetFontList(aLangGroup,
|
||||
aGenericFamily,
|
||||
aListOfFonts);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
return sFontconfigUtils->GetFontList(aLangGroup,
|
||||
aGenericFamily,
|
||||
aListOfFonts);
|
||||
gfxPlatformFontList::PlatformFontList()->GetFontList(aLangGroup,
|
||||
aGenericFamily,
|
||||
aListOfFonts);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
gfxPlatformGtk::UpdateFontList()
|
||||
{
|
||||
if (sUseFcFontList) {
|
||||
gfxPlatformFontList::PlatformFontList()->UpdateFontList();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
return sFontconfigUtils->UpdateFontList();
|
||||
gfxPlatformFontList::PlatformFontList()->UpdateFontList();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// xxx - this is ubuntu centric, need to go through other distros and flesh
|
||||
|
@ -287,13 +262,9 @@ gfxPlatformGtk::CreatePlatformFontList()
|
|||
nsresult
|
||||
gfxPlatformGtk::GetStandardFamilyName(const nsAString& aFontName, nsAString& aFamilyName)
|
||||
{
|
||||
if (sUseFcFontList) {
|
||||
gfxPlatformFontList::PlatformFontList()->
|
||||
GetStandardFamilyName(aFontName, aFamilyName);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
return sFontconfigUtils->GetStandardFamilyName(aFontName, aFamilyName);
|
||||
gfxPlatformFontList::PlatformFontList()->
|
||||
GetStandardFamilyName(aFontName, aFamilyName);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
gfxFontGroup *
|
||||
|
@ -303,13 +274,8 @@ gfxPlatformGtk::CreateFontGroup(const FontFamilyList& aFontFamilyList,
|
|||
gfxUserFontSet* aUserFontSet,
|
||||
gfxFloat aDevToCssSize)
|
||||
{
|
||||
if (sUseFcFontList) {
|
||||
return new gfxFontGroup(aFontFamilyList, aStyle, aTextPerf,
|
||||
aUserFontSet, aDevToCssSize);
|
||||
}
|
||||
|
||||
return new gfxPangoFontGroup(aFontFamilyList, aStyle,
|
||||
aUserFontSet, aDevToCssSize);
|
||||
return new gfxFontGroup(aFontFamilyList, aStyle, aTextPerf,
|
||||
aUserFontSet, aDevToCssSize);
|
||||
}
|
||||
|
||||
gfxFontEntry*
|
||||
|
@ -318,14 +284,9 @@ gfxPlatformGtk::LookupLocalFont(const nsAString& aFontName,
|
|||
int16_t aStretch,
|
||||
uint8_t aStyle)
|
||||
{
|
||||
if (sUseFcFontList) {
|
||||
gfxPlatformFontList* pfl = gfxPlatformFontList::PlatformFontList();
|
||||
return pfl->LookupLocalFont(aFontName, aWeight, aStretch,
|
||||
aStyle);
|
||||
}
|
||||
|
||||
return gfxPangoFontGroup::NewFontEntry(aFontName, aWeight,
|
||||
aStretch, aStyle);
|
||||
gfxPlatformFontList* pfl = gfxPlatformFontList::PlatformFontList();
|
||||
return pfl->LookupLocalFont(aFontName, aWeight, aStretch,
|
||||
aStyle);
|
||||
}
|
||||
|
||||
gfxFontEntry*
|
||||
|
@ -336,26 +297,15 @@ gfxPlatformGtk::MakePlatformFont(const nsAString& aFontName,
|
|||
const uint8_t* aFontData,
|
||||
uint32_t aLength)
|
||||
{
|
||||
if (sUseFcFontList) {
|
||||
gfxPlatformFontList* pfl = gfxPlatformFontList::PlatformFontList();
|
||||
return pfl->MakePlatformFont(aFontName, aWeight, aStretch,
|
||||
aStyle, aFontData, aLength);
|
||||
}
|
||||
|
||||
// passing ownership of the font data to the new font entry
|
||||
return gfxPangoFontGroup::NewFontEntry(aFontName, aWeight,
|
||||
aStretch, aStyle,
|
||||
aFontData, aLength);
|
||||
gfxPlatformFontList* pfl = gfxPlatformFontList::PlatformFontList();
|
||||
return pfl->MakePlatformFont(aFontName, aWeight, aStretch,
|
||||
aStyle, aFontData, aLength);
|
||||
}
|
||||
|
||||
FT_Library
|
||||
gfxPlatformGtk::GetFTLibrary()
|
||||
{
|
||||
if (sUseFcFontList) {
|
||||
return gfxFcPlatformFontList::GetFTLibrary();
|
||||
}
|
||||
|
||||
return gfxPangoFontGroup::GetFTLibrary();
|
||||
return gfxFcPlatformFontList::GetFTLibrary();
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -447,11 +397,9 @@ void gfxPlatformGtk::FontsPrefsChanged(const char *aPref)
|
|||
}
|
||||
|
||||
mMaxGenericSubstitutions = UNINITIALIZED_VALUE;
|
||||
if (sUseFcFontList) {
|
||||
gfxFcPlatformFontList* pfl = gfxFcPlatformFontList::PlatformFontList();
|
||||
pfl->ClearGenericMappings();
|
||||
FlushFontAndWordCaches();
|
||||
}
|
||||
gfxFcPlatformFontList* pfl = gfxFcPlatformFontList::PlatformFontList();
|
||||
pfl->ClearGenericMappings();
|
||||
FlushFontAndWordCaches();
|
||||
}
|
||||
|
||||
uint32_t gfxPlatformGtk::MaxGenericSubstitions()
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче