Merge mozilla-inbound to mozilla-central a=merge

This commit is contained in:
Daniel Varga 2018-09-08 01:04:10 +03:00
commit bdd611d2ef
28 changed files with 704 additions and 345 deletions

View file

@ -12,11 +12,6 @@
#include "nsCOMPtr.h"
#include "nsWeakPtr.h"
#define NS_AUDIOCHANNELAGENT_CONTRACTID "@mozilla.org/audiochannelagent;1"
// f27688e2-3dd7-11e2-904e-10bf48d64bd4
#define NS_AUDIOCHANNELAGENT_CID {0xf27688e2, 0x3dd7, 0x11e2, \
{0x90, 0x4e, 0x10, 0xbf, 0x48, 0xd6, 0x4b, 0xd4}}
class nsPIDOMWindowInner;
class nsPIDOMWindowOuter;

View file

@ -34,6 +34,7 @@
#include "nsILoadContext.h"
#include "mozilla/dom/Element.h"
#include "mozilla/dom/HTMLObjectElementBinding.h"
#include "AudioChannelAgent.h"
#include "AudioChannelService.h"
using namespace mozilla;
@ -1241,18 +1242,15 @@ nsNPAPIPluginInstance::CreateAudioChannelAgentIfNeeded()
return NS_OK;
}
nsresult rv;
mAudioChannelAgent = do_CreateInstance("@mozilla.org/audiochannelagent;1", &rv);
if (NS_WARN_IF(!mAudioChannelAgent)) {
return NS_ERROR_FAILURE;
}
mAudioChannelAgent = new AudioChannelAgent();
nsCOMPtr<nsPIDOMWindowOuter> window = GetDOMWindow();
if (NS_WARN_IF(!window)) {
return NS_ERROR_FAILURE;
}
rv = mAudioChannelAgent->Init(window->GetCurrentInnerWindow(), this);
nsresult rv =
mAudioChannelAgent->Init(window->GetCurrentInnerWindow(), this);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}

View file

@ -7601,9 +7601,9 @@ ClearRequestBase::DeleteFiles(QuotaManager* aQuotaManager,
SanitizeOriginString(originSanitized);
originScope.SetOrigin(originSanitized);
} else if (originScope.IsPrefix()) {
nsCString prefixSanitized(originScope.GetPrefix());
SanitizeOriginString(prefixSanitized);
originScope.SetPrefix(prefixSanitized);
nsCString originNoSuffixSanitized(originScope.GetOriginNoSuffix());
SanitizeOriginString(originNoSuffixSanitized);
originScope.SetOriginNoSuffix(originNoSuffixSanitized);
}
nsCOMPtr<nsIFile> file;
@ -7629,8 +7629,8 @@ ClearRequestBase::DeleteFiles(QuotaManager* aQuotaManager,
}
// Skip the origin directory if it doesn't match the pattern.
if (!originScope.MatchesOrigin(OriginScope::FromOrigin(
NS_ConvertUTF16toUTF8(leafName)))) {
if (!originScope.Matches(OriginScope::FromOrigin(
NS_ConvertUTF16toUTF8(leafName)))) {
continue;
}

View file

@ -10,413 +10,473 @@
#include "mozilla/dom/quota/QuotaCommon.h"
#include "mozilla/BasePrincipal.h"
#include "mozilla/Variant.h"
BEGIN_QUOTA_NAMESPACE
class OriginScope
{
public:
enum Type
{
eOrigin,
ePattern,
ePrefix,
eNull
};
private:
struct OriginAndAttributes
class Origin
{
nsCString mOrigin;
OriginAttributes mAttributes;
nsCString mOriginNoSuffix;
UniquePtr<OriginAttributes> mAttributes;
OriginAndAttributes(const OriginAndAttributes& aOther)
: mOrigin(aOther.mOrigin)
, mAttributes(aOther.mAttributes)
{
MOZ_COUNT_CTOR(OriginAndAttributes);
}
explicit OriginAndAttributes(const nsACString& aOrigin)
public:
explicit Origin(const nsACString& aOrigin)
: mOrigin(aOrigin)
{
nsCString originNoSuffix;
MOZ_ALWAYS_TRUE(mAttributes.PopulateFromOrigin(aOrigin, originNoSuffix));
MOZ_COUNT_CTOR(OriginAndAttributes);
InitMembers();
}
~OriginAndAttributes()
Origin(const Origin& aOther)
: mOrigin(aOther.mOrigin)
, mOriginNoSuffix(aOther.mOriginNoSuffix)
, mAttributes(MakeUnique<OriginAttributes>(*aOther.mAttributes))
{ }
Origin(Origin&& aOther) = default;
const nsACString&
GetOrigin() const
{
MOZ_COUNT_DTOR(OriginAndAttributes);
return mOrigin;
}
void
SetOrigin(const nsACString& aOrigin)
{
mOrigin = aOrigin;
InitMembers();
}
const nsACString&
GetOriginNoSuffix() const
{
return mOriginNoSuffix;
}
const OriginAttributes&
GetAttributes() const
{
MOZ_ASSERT(mAttributes);
return *mAttributes;
}
private:
void
InitMembers()
{
mAttributes = MakeUnique<OriginAttributes>();
MOZ_ALWAYS_TRUE(mAttributes->PopulateFromOrigin(mOrigin,
mOriginNoSuffix));
}
};
union {
// eOrigin
OriginAndAttributes* mOriginAndAttributes;
class Prefix
{
nsCString mOriginNoSuffix;
// ePattern
mozilla::OriginAttributesPattern* mPattern;
public:
explicit Prefix(const nsACString& aOriginNoSuffix)
: mOriginNoSuffix(aOriginNoSuffix)
{ }
// ePrefix
nsCString* mPrefix;
const nsCString&
GetOriginNoSuffix() const
{
return mOriginNoSuffix;
}
// eNull
void* mDummy;
void
SetOriginNoSuffix(const nsACString& aOriginNoSuffix)
{
mOriginNoSuffix = aOriginNoSuffix;
}
};
Type mType;
class Pattern
{
UniquePtr<OriginAttributesPattern> mPattern;
public:
explicit Pattern(const OriginAttributesPattern& aPattern)
: mPattern(MakeUnique<OriginAttributesPattern>(aPattern))
{ }
explicit Pattern(const nsAString& aJSONPattern)
: mPattern(MakeUnique<OriginAttributesPattern>())
{
MOZ_ALWAYS_TRUE(mPattern->Init(aJSONPattern));
}
Pattern(const Pattern& aOther)
: mPattern(MakeUnique<OriginAttributesPattern>(*aOther.mPattern))
{ }
Pattern(Pattern&& aOther) = default;
const OriginAttributesPattern&
GetPattern() const
{
MOZ_ASSERT(mPattern);
return *mPattern;
}
void
SetPattern(const OriginAttributesPattern& aPattern)
{
mPattern = MakeUnique<OriginAttributesPattern>(aPattern);
}
nsString
GetJSONPattern() const
{
MOZ_ASSERT(mPattern);
nsString result;
MOZ_ALWAYS_TRUE(mPattern->ToJSON(result));
return result;
}
};
struct Null
{ };
using DataType = Variant<Origin, Prefix, Pattern, Null>;
DataType mData;
public:
OriginScope()
: mData(Null())
{ }
static OriginScope
FromOrigin(const nsACString& aOrigin)
{
return OriginScope(aOrigin, true);
}
static OriginScope
FromPattern(const mozilla::OriginAttributesPattern& aPattern)
{
return OriginScope(aPattern);
}
static OriginScope
FromJSONPattern(const nsAString& aJSONPattern)
{
return OriginScope(aJSONPattern);
return OriginScope(std::move(Origin(aOrigin)));
}
static OriginScope
FromPrefix(const nsACString& aPrefix)
{
return OriginScope(aPrefix, false);
return OriginScope(std::move(Prefix(aPrefix)));
}
static OriginScope
FromPattern(const OriginAttributesPattern& aPattern)
{
return OriginScope(std::move(Pattern(aPattern)));
}
static OriginScope
FromJSONPattern(const nsAString& aJSONPattern)
{
return OriginScope(std::move(Pattern(aJSONPattern)));
}
static OriginScope
FromNull()
{
return OriginScope();
}
OriginScope(const OriginScope& aOther)
{
if (aOther.IsOrigin()) {
mOriginAndAttributes =
new OriginAndAttributes(*aOther.mOriginAndAttributes);
} else if (aOther.IsPattern()) {
mPattern = new mozilla::OriginAttributesPattern(*aOther.mPattern);
} else if (aOther.IsPrefix()) {
mPrefix = new nsCString(*aOther.mPrefix);
} else {
mDummy = aOther.mDummy;
}
mType = aOther.mType;
}
~OriginScope()
{
Destroy();
return OriginScope(std::move(Null()));
}
bool
IsOrigin() const
{
return mType == eOrigin;
}
bool
IsPattern() const
{
return mType == ePattern;
return mData.is<Origin>();
}
bool
IsPrefix() const
{
return mType == ePrefix;
return mData.is<Prefix>();
}
bool
IsPattern() const
{
return mData.is<Pattern>();
}
bool
IsNull() const
{
return mType == eNull;
}
Type
GetType() const
{
return mType;
return mData.is<Null>();
}
void
SetFromOrigin(const nsACString& aOrigin)
{
Destroy();
mOriginAndAttributes = new OriginAndAttributes(aOrigin);
mType = eOrigin;
}
void
SetFromPattern(const mozilla::OriginAttributesPattern& aPattern)
{
Destroy();
mPattern = new mozilla::OriginAttributesPattern(aPattern);
mType = ePattern;
}
void
SetFromJSONPattern(const nsAString& aJSONPattern)
{
Destroy();
mPattern = new mozilla::OriginAttributesPattern();
MOZ_ALWAYS_TRUE(mPattern->Init(aJSONPattern));
mType = ePattern;
mData = AsVariant(Origin(aOrigin));
}
void
SetFromPrefix(const nsACString& aPrefix)
{
Destroy();
mData = AsVariant(Prefix(aPrefix));
}
mPrefix = new nsCString(aPrefix);
void
SetFromPattern(const OriginAttributesPattern& aPattern)
{
mData = AsVariant(Pattern(aPattern));
}
mType = ePrefix;
void
SetFromJSONPattern(const nsAString& aJSONPattern)
{
mData = AsVariant(Pattern(aJSONPattern));
}
void
SetFromNull()
{
Destroy();
mDummy = nullptr;
mType = eNull;
mData = AsVariant(Null());
}
const nsACString&
GetOrigin() const
{
MOZ_ASSERT(IsOrigin());
MOZ_ASSERT(mOriginAndAttributes);
return mOriginAndAttributes->mOrigin;
return mData.as<Origin>().GetOrigin();
}
void
SetOrigin(const nsACString& aOrigin)
{
MOZ_ASSERT(IsOrigin());
MOZ_ASSERT(mOriginAndAttributes);
mOriginAndAttributes->mOrigin = aOrigin;
}
const mozilla::OriginAttributes&
GetOriginAttributes() const
{
MOZ_ASSERT(IsOrigin());
MOZ_ASSERT(mOriginAndAttributes);
return mOriginAndAttributes->mAttributes;
}
const mozilla::OriginAttributesPattern&
GetPattern() const
{
MOZ_ASSERT(IsPattern());
MOZ_ASSERT(mPattern);
return *mPattern;
mData.as<Origin>().SetOrigin(aOrigin);
}
const nsACString&
GetPrefix() const
GetOriginNoSuffix() const
{
MOZ_ASSERT(IsPrefix());
MOZ_ASSERT(mPrefix);
MOZ_ASSERT(IsOrigin() || IsPrefix());
return *mPrefix;
if (IsOrigin()) {
return mData.as<Origin>().GetOriginNoSuffix();
}
return mData.as<Prefix>().GetOriginNoSuffix();
}
void
SetPrefix(const nsACString& aPrefix)
SetOriginNoSuffix(const nsACString& aOriginNoSuffix)
{
MOZ_ASSERT(IsPrefix());
MOZ_ASSERT(mPrefix);
*mPrefix = aPrefix;
mData.as<Prefix>().SetOriginNoSuffix(aOriginNoSuffix);
}
bool MatchesOrigin(const OriginScope& aOther) const
const OriginAttributesPattern&
GetPattern() const
{
MOZ_ASSERT(aOther.IsOrigin());
MOZ_ASSERT(aOther.mOriginAndAttributes);
MOZ_ASSERT(IsPattern());
bool match;
if (IsOrigin()) {
MOZ_ASSERT(mOriginAndAttributes);
match = mOriginAndAttributes->mOrigin.Equals(
aOther.mOriginAndAttributes->mOrigin);
} else if (IsPattern()) {
MOZ_ASSERT(mPattern);
match = mPattern->Matches(aOther.mOriginAndAttributes->mAttributes);
} else if (IsPrefix()) {
MOZ_ASSERT(mPrefix);
match = StringBeginsWith(aOther.mOriginAndAttributes->mOrigin, *mPrefix);
} else {
match = true;
}
return match;
return mData.as<Pattern>().GetPattern();
}
bool MatchesPattern(const OriginScope& aOther) const
nsString
GetJSONPattern() const
{
MOZ_ASSERT(aOther.IsPattern());
MOZ_ASSERT(aOther.mPattern);
MOZ_ASSERT(IsPattern());
bool match;
if (IsOrigin()) {
MOZ_ASSERT(mOriginAndAttributes);
match = aOther.mPattern->Matches(mOriginAndAttributes->mAttributes);
} else if (IsPattern()) {
MOZ_ASSERT(mPattern);
match = mPattern->Overlaps(*aOther.mPattern);
} else if (IsPrefix()) {
MOZ_ASSERT(mPrefix);
// The match will be always true here because any origin attributes
// pattern overlaps any origin prefix (an origin prefix targets all
// origin attributes).
match = true;
} else {
match = true;
}
return match;
return mData.as<Pattern>().GetJSONPattern();
}
bool MatchesPrefix(const OriginScope& aOther) const
void
SetPattern(const OriginAttributesPattern& aPattern)
{
MOZ_ASSERT(aOther.IsPrefix());
MOZ_ASSERT(aOther.mPrefix);
MOZ_ASSERT(IsPattern());
bool match;
if (IsOrigin()) {
MOZ_ASSERT(mOriginAndAttributes);
match = StringBeginsWith(mOriginAndAttributes->mOrigin, *aOther.mPrefix);
} else if (IsPattern()) {
MOZ_ASSERT(mPattern);
// The match will be always true here because any origin attributes
// pattern overlaps any origin prefix (an origin prefix targets all
// origin attributes).
match = true;
} else if (IsPrefix()) {
MOZ_ASSERT(mPrefix);
match = mPrefix->Equals(*aOther.mPrefix);
} else {
match = true;
}
return match;
mData.as<Pattern>().SetPattern(aPattern);
}
bool Matches(const OriginScope& aOther) const
bool
Matches(const OriginScope& aOther) const
{
bool match;
struct Matcher
{
const OriginScope& mThis;
if (aOther.IsOrigin()) {
match = MatchesOrigin(aOther);
} else if (aOther.IsPattern()) {
match = MatchesPattern(aOther);
} else if (aOther.IsPrefix()) {
match = MatchesPrefix(aOther);
} else {
match = true;
}
explicit Matcher(const OriginScope& aThis)
: mThis(aThis)
{ }
return match;
bool
match(const Origin& aOther) {
return mThis.MatchesOrigin(aOther);
}
bool
match(const Prefix& aOther) {
return mThis.MatchesPrefix(aOther);
}
bool
match(const Pattern& aOther) {
return mThis.MatchesPattern(aOther);
}
bool
match(const Null& aOther) {
return true;
}
};
return aOther.mData.match(Matcher(*this));
}
OriginScope
Clone()
{
if (IsOrigin()) {
MOZ_ASSERT(mOriginAndAttributes);
return OriginScope(*mOriginAndAttributes);
}
if (IsPattern()) {
MOZ_ASSERT(mPattern);
return OriginScope(*mPattern);
}
if (IsPrefix()) {
MOZ_ASSERT(mPrefix);
return OriginScope(*mPrefix, false);
}
MOZ_ASSERT(IsNull());
return OriginScope();
return OriginScope(mData);
}
private:
explicit OriginScope(const OriginAndAttributes& aOriginAndAttributes)
: mOriginAndAttributes(new OriginAndAttributes(aOriginAndAttributes))
, mType(eOrigin)
// Move constructors
explicit OriginScope(const Origin&& aOrigin)
: mData(aOrigin)
{ }
explicit OriginScope(const nsACString& aOriginOrPrefix, bool aOrigin)
explicit OriginScope(const Prefix&& aPrefix)
: mData(aPrefix)
{ }
explicit OriginScope(const Pattern&& aPattern)
: mData(aPattern)
{ }
explicit OriginScope(const Null&& aNull)
: mData(aNull)
{ }
// Copy constructor
explicit OriginScope(const DataType& aOther)
: mData(aOther)
{ }
bool
MatchesOrigin(const Origin& aOther) const
{
if (aOrigin) {
mOriginAndAttributes = new OriginAndAttributes(aOriginOrPrefix);
mType = eOrigin;
} else {
mPrefix = new nsCString(aOriginOrPrefix);
mType = ePrefix;
}
struct OriginMatcher
{
const Origin& mOther;
explicit OriginMatcher(const Origin& aOther)
: mOther(aOther)
{ }
bool
match(const Origin& aThis) {
return aThis.GetOrigin().Equals(mOther.GetOrigin());
}
bool
match(const Prefix& aThis) {
return aThis.GetOriginNoSuffix().Equals(mOther.GetOriginNoSuffix());
}
bool
match(const Pattern& aThis) {
return aThis.GetPattern().Matches(mOther.GetAttributes());
}
bool
match(const Null& aThis) {
// Null covers everything.
return true;
}
};
return mData.match(OriginMatcher(aOther));
}
explicit OriginScope(const mozilla::OriginAttributesPattern& aPattern)
: mPattern(new mozilla::OriginAttributesPattern(aPattern))
, mType(ePattern)
{ }
explicit OriginScope(const nsAString& aJSONPattern)
: mPattern(new mozilla::OriginAttributesPattern())
, mType(ePattern)
bool
MatchesPrefix(const Prefix& aOther) const
{
MOZ_ALWAYS_TRUE(mPattern->Init(aJSONPattern));
struct PrefixMatcher
{
const Prefix& mOther;
explicit PrefixMatcher(const Prefix& aOther)
: mOther(aOther)
{ }
bool
match(const Origin& aThis) {
return aThis.GetOriginNoSuffix().Equals(mOther.GetOriginNoSuffix());
}
bool
match(const Prefix& aThis) {
return aThis.GetOriginNoSuffix().Equals(mOther.GetOriginNoSuffix());
}
bool
match(const Pattern& aThis) {
// The match will be always true here because any origin attributes
// pattern overlaps any origin prefix (an origin prefix targets all
// origin attributes).
return true;
}
bool
match(const Null& aThis) {
// Null covers everything.
return true;
}
};
return mData.match(PrefixMatcher(aOther));
}
OriginScope()
: mDummy(nullptr)
, mType(eNull)
{ }
void
Destroy()
bool
MatchesPattern(const Pattern& aOther) const
{
if (IsOrigin()) {
MOZ_ASSERT(mOriginAndAttributes);
delete mOriginAndAttributes;
mOriginAndAttributes = nullptr;
} else if (IsPattern()) {
MOZ_ASSERT(mPattern);
delete mPattern;
mPattern = nullptr;
} else if (IsPrefix()) {
MOZ_ASSERT(mPrefix);
delete mPrefix;
mPrefix = nullptr;
}
struct PatternMatcher
{
const Pattern& mOther;
explicit PatternMatcher(const Pattern& aOther)
: mOther(aOther)
{ }
bool
match(const Origin& aThis) {
return mOther.GetPattern().Matches(aThis.GetAttributes());
}
bool
match(const Prefix& aThis) {
// The match will be always true here because any origin attributes
// pattern overlaps any origin prefix (an origin prefix targets all
// origin attributes).
return true;
}
bool
match(const Pattern& aThis) {
return aThis.GetPattern().Overlaps(mOther.GetPattern());
}
bool
match(const Null& aThis) {
// Null covers everything.
return true;
}
};
PatternMatcher patternMatcher(aOther);
return mData.match(PatternMatcher(aOther));
}
bool

View file

@ -19,6 +19,8 @@ TEST_HARNESS_FILES.xpcshell.dom.quota.test += [
'test/head-shared.js',
]
TEST_DIRS += ['test/gtest']
XPIDL_SOURCES += [
'nsIQuotaCallbacks.idl',
'nsIQuotaManagerService.idl',
@ -67,6 +69,7 @@ IPDL_SOURCES += [
include('/ipc/chromium/chromium-config.mozbuild')
FINAL_LIBRARY = 'xul'
LOCAL_INCLUDES += [
'/caps',
]

View file

@ -0,0 +1,125 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "gtest/gtest.h"
#include "mozilla/dom/quota/OriginScope.h"
using namespace mozilla;
using namespace mozilla::dom::quota;
namespace {
struct OriginTest {
const char* mOrigin;
bool mMatch;
};
void
CheckOriginScopeMatchesOrigin(const OriginScope& aOriginScope,
const char* aOrigin,
bool aMatch)
{
bool result =
aOriginScope.Matches(OriginScope::FromOrigin(nsDependentCString(aOrigin)));
EXPECT_TRUE(result == aMatch);
}
} // namespace
TEST(QuotaManager, OriginScope)
{
OriginScope originScope;
// Sanity checks.
{
NS_NAMED_LITERAL_CSTRING(origin, "http://www.mozilla.org");
originScope.SetFromOrigin(origin);
EXPECT_TRUE(originScope.IsOrigin());
EXPECT_TRUE(originScope.GetOrigin().Equals(origin));
EXPECT_TRUE(originScope.GetOriginNoSuffix().Equals(origin));
}
{
NS_NAMED_LITERAL_CSTRING(prefix, "http://www.mozilla.org");
originScope.SetFromPrefix(prefix);
EXPECT_TRUE(originScope.IsPrefix());
EXPECT_TRUE(originScope.GetOriginNoSuffix().Equals(prefix));
}
{
NS_NAMED_LITERAL_STRING(pattern, "{\"appId\":1007}");
originScope.SetFromJSONPattern(pattern);
EXPECT_TRUE(originScope.IsPattern());
EXPECT_TRUE(originScope.GetJSONPattern().Equals(pattern));
}
{
originScope.SetFromNull();
EXPECT_TRUE(originScope.IsNull());
}
// Test each origin scope type against particular origins.
{
originScope.SetFromOrigin(NS_LITERAL_CSTRING("http://www.mozilla.org"));
static const OriginTest tests[] = {
{ "http://www.mozilla.org", true },
{ "http://www.example.org", false },
};
for (const auto& test : tests) {
CheckOriginScopeMatchesOrigin(originScope, test.mOrigin, test.mMatch);
}
}
{
originScope.SetFromPrefix(NS_LITERAL_CSTRING("http://www.mozilla.org"));
static const OriginTest tests[] = {
{ "http://www.mozilla.org", true },
{ "http://www.mozilla.org^userContextId=1", true },
{ "http://www.example.org^userContextId=1", false },
};
for (const auto& test : tests) {
CheckOriginScopeMatchesOrigin(originScope, test.mOrigin, test.mMatch);
}
}
{
originScope.SetFromJSONPattern(NS_LITERAL_STRING("{\"appId\":1007}"));
static const OriginTest tests[] = {
{ "http+++www.mozilla.org^appId=1007", true },
{ "http+++www.example.org^appId=1007", true },
{ "http+++www.example.org^appId=1008", false },
};
for (const auto& test : tests) {
CheckOriginScopeMatchesOrigin(originScope, test.mOrigin, test.mMatch);
}
}
{
originScope.SetFromNull();
static const OriginTest tests[] = {
{ "http://www.mozilla.org", true },
{ "http://www.mozilla.org^userContextId=1", true },
{ "http://www.example.org^userContextId=1", true },
{ "http+++www.mozilla.org^appId=1007", true },
{ "http+++www.example.org^appId=1007", true },
{ "http+++www.example.org^appId=1008", true },
};
for (const auto& test : tests) {
CheckOriginScopeMatchesOrigin(originScope, test.mOrigin, test.mMatch);
}
}
}

View file

@ -0,0 +1,17 @@
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, you can obtain one at http://mozilla.org/MPL/2.0/.
UNIFIED_SOURCES = [
'TestQuotaManager.cpp',
]
include('/ipc/chromium/chromium-config.mozbuild')
FINAL_LIBRARY = 'xul-gtest'
LOCAL_INCLUDES += [
'/dom/quota',
]

View file

@ -599,6 +599,9 @@ class NodeBuilder
MOZ_MUST_USE bool metaProperty(HandleValue meta, HandleValue property, TokenPos* pos,
MutableHandleValue dst);
MOZ_MUST_USE bool callImportExpression(HandleValue ident, HandleValue arg, TokenPos* pos,
MutableHandleValue dst);
MOZ_MUST_USE bool super(TokenPos* pos, MutableHandleValue dst);
/*
@ -1599,6 +1602,20 @@ NodeBuilder::metaProperty(HandleValue meta, HandleValue property, TokenPos* pos,
dst);
}
bool
NodeBuilder::callImportExpression(HandleValue ident, HandleValue arg, TokenPos* pos,
MutableHandleValue dst)
{
RootedValue cb(cx, callbacks[AST_CALL_IMPORT]);
if (!cb.isNull())
return callback(cb, arg, pos, dst);
return newNode(AST_CALL_IMPORT, pos,
"ident", ident,
"arg", arg,
dst);
}
bool
NodeBuilder::super(TokenPos* pos, MutableHandleValue dst)
{
@ -2950,6 +2967,21 @@ ASTSerializer::expression(ParseNode* pn, MutableHandleValue dst)
builder.metaProperty(firstIdent, secondIdent, &pn->pn_pos, dst);
}
case ParseNodeKind::CallImport:
{
MOZ_ASSERT(pn->pn_left->isKind(ParseNodeKind::PosHolder));
MOZ_ASSERT(pn->pn_pos.encloses(pn->pn_left->pn_pos));
MOZ_ASSERT(pn->pn_pos.encloses(pn->pn_right->pn_pos));
RootedValue ident(cx);
RootedValue arg(cx);
HandlePropertyName name = cx->names().import;
return identifier(name, &pn->pn_left->pn_pos, &ident) &&
expression(pn->pn_right, &arg) &&
builder.callImportExpression(ident, arg, &pn->pn_pos, dst);
}
case ParseNodeKind::SetThis:
// SETTHIS is used to assign the result of a super() call to |this|.
// It's not part of the original AST, so just forward to the call.

View file

@ -1217,6 +1217,11 @@ BytecodeEmitter::checkSideEffects(ParseNode* pn, bool* answer)
*answer = true;
return true;
case ParseNodeKind::CallImport:
MOZ_ASSERT(pn->isArity(PN_BINARY));
*answer = true;
return true;
// Every part of a loop might be effect-free, but looping infinitely *is*
// an effect. (Language lawyer trivia: C++ says threads can be assumed
// to exit or have side effects, C++14 [intro.multithread]p27, so a C++
@ -8308,6 +8313,10 @@ BytecodeEmitter::emitTree(ParseNode* pn, ValueUsage valueUsage /* = ValueUsage::
return false;
break;
case ParseNodeKind::CallImport:
reportError(nullptr, JSMSG_NO_DYNAMIC_IMPORT);
return false;
case ParseNodeKind::SetThis:
if (!emitSetThis(pn))
return false;

View file

@ -136,6 +136,7 @@ ContainsHoistedDeclaration(JSContext* cx, ParseNode* node, bool* result)
case ParseNodeKind::ExportSpec:
case ParseNodeKind::Export:
case ParseNodeKind::ExportBatchSpec:
case ParseNodeKind::CallImport:
*result = false;
return true;
@ -1755,6 +1756,11 @@ Fold(JSContext* cx, ParseNode** pnp, PerHandlerParser<FullParseHandler>& parser)
MOZ_ASSERT(pn->pn_right->isKind(ParseNodeKind::PosHolder));
return true;
case ParseNodeKind::CallImport:
MOZ_ASSERT(pn->isArity(PN_BINARY));
MOZ_ASSERT(pn->pn_left->isKind(ParseNodeKind::PosHolder));
return Fold(cx, &pn->pn_right, parser);
case ParseNodeKind::ClassNames:
MOZ_ASSERT(pn->isArity(PN_BINARY));
if (ParseNode*& outerBinding = pn->pn_left) {

View file

@ -562,6 +562,10 @@ class FullParseHandler
return new_<BinaryNode>(ParseNodeKind::ImportMeta, JSOP_NOP, importHolder, metaHolder);
}
ParseNode* newCallImport(ParseNode* importHolder, ParseNode* singleArg) {
return new_<BinaryNode>(ParseNodeKind::CallImport, JSOP_NOP, importHolder, singleArg);
}
ParseNode* newExprStatement(ParseNode* expr, uint32_t end) {
MOZ_ASSERT(expr->pn_pos.end <= end);
return new_<UnaryNode>(ParseNodeKind::ExpressionStatement,

View file

@ -786,6 +786,12 @@ class NameResolver
break;
}
case ParseNodeKind::CallImport:
MOZ_ASSERT(cur->isArity(PN_BINARY));
if (!resolve(cur->pn_right, prefix))
return false;
break;
case ParseNodeKind::Dot:
MOZ_ASSERT(cur->isArity(PN_BINARY));

View file

@ -136,6 +136,7 @@ class ObjectBox;
F(SuperCall) \
F(SetThis) \
F(ImportMeta) \
F(CallImport) \
\
/* Unary operators. */ \
F(TypeOfName) \

View file

@ -5442,7 +5442,7 @@ GeneralParser<ParseHandler, CharT>::importDeclaration()
template <class ParseHandler, typename CharT>
inline typename ParseHandler::Node
GeneralParser<ParseHandler, CharT>::importDeclarationOrImportMeta(YieldHandling yieldHandling)
GeneralParser<ParseHandler, CharT>::importDeclarationOrImportExpr(YieldHandling yieldHandling)
{
MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Import));
@ -5450,7 +5450,7 @@ GeneralParser<ParseHandler, CharT>::importDeclarationOrImportMeta(YieldHandling
if (!tokenStream.peekToken(&tt))
return null();
if (tt == TokenKind::Dot)
if (tt == TokenKind::Dot || tt == TokenKind::LeftParen)
return expressionStatement(yieldHandling);
return importDeclaration();
@ -7811,7 +7811,7 @@ GeneralParser<ParseHandler, CharT>::statement(YieldHandling yieldHandling)
// ImportDeclaration (only inside modules)
case TokenKind::Import:
return importDeclarationOrImportMeta(yieldHandling);
return importDeclarationOrImportExpr(yieldHandling);
// ExportDeclaration (only inside modules)
case TokenKind::Export:
@ -8004,7 +8004,7 @@ GeneralParser<ParseHandler, CharT>::statementListItem(YieldHandling yieldHandlin
// ImportDeclaration (only inside modules)
case TokenKind::Import:
return importDeclarationOrImportMeta(yieldHandling);
return importDeclarationOrImportExpr(yieldHandling);
// ExportDeclaration (only inside modules)
case TokenKind::Export:
@ -8841,7 +8841,7 @@ GeneralParser<ParseHandler, CharT>::memberExpr(YieldHandling yieldHandling,
if (!lhs)
return null();
} else if (tt == TokenKind::Import) {
lhs = importMeta();
lhs = importExpr(yieldHandling);
if (!lhs)
return null();
} else {
@ -10024,17 +10024,10 @@ GeneralParser<ParseHandler, CharT>::tryNewTarget(Node &newTarget)
template <class ParseHandler, typename CharT>
typename ParseHandler::Node
GeneralParser<ParseHandler, CharT>::importMeta()
GeneralParser<ParseHandler, CharT>::importExpr(YieldHandling yieldHandling)
{
MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Import));
uint32_t begin = pos().begin;
if (parseGoal() != ParseGoal::Module) {
errorAt(begin, JSMSG_IMPORT_OUTSIDE_MODULE);
return null();
}
Node importHolder = handler.newPosHolder(pos());
if (!importHolder)
return null();
@ -10042,23 +10035,37 @@ GeneralParser<ParseHandler, CharT>::importMeta()
TokenKind next;
if (!tokenStream.getToken(&next))
return null();
if (next != TokenKind::Dot) {
error(JSMSG_UNEXPECTED_TOKEN, "dot", TokenKindToDesc(next));
if (next == TokenKind::Dot) {
if (!tokenStream.getToken(&next))
return null();
if (next != TokenKind::Meta) {
error(JSMSG_UNEXPECTED_TOKEN, "meta", TokenKindToDesc(next));
return null();
}
if (parseGoal() != ParseGoal::Module) {
errorAt(pos().begin, JSMSG_IMPORT_META_OUTSIDE_MODULE);
return null();
}
Node metaHolder = handler.newPosHolder(pos());
if (!metaHolder)
return null();
return handler.newImportMeta(importHolder, metaHolder);
} else if (next == TokenKind::LeftParen) {
Node arg = assignExpr(InAllowed, yieldHandling, TripledotProhibited);
if (!arg)
return null();
MUST_MATCH_TOKEN_MOD(TokenKind::RightParen, TokenStream::Operand, JSMSG_PAREN_AFTER_ARGS);
return handler.newCallImport(importHolder, arg);
} else {
error(JSMSG_UNEXPECTED_TOKEN_NO_EXPECT, TokenKindToDesc(next));
return null();
}
if (!tokenStream.getToken(&next))
return null();
if (next != TokenKind::Meta) {
error(JSMSG_UNEXPECTED_TOKEN, "meta", TokenKindToDesc(next));
return null();
}
Node metaHolder = handler.newPosHolder(pos());
if (!metaHolder)
return null();
return handler.newImportMeta(importHolder, metaHolder);
}
template <class ParseHandler, typename CharT>

View file

@ -1045,7 +1045,7 @@ class MOZ_STACK_CLASS GeneralParser
Node lexicalDeclaration(YieldHandling yieldHandling, DeclarationKind kind);
inline Node importDeclaration();
Node importDeclarationOrImportMeta(YieldHandling yieldHandling);
Node importDeclarationOrImportExpr(YieldHandling yieldHandling);
Node exportFrom(uint32_t begin, Node specList);
Node exportBatch(uint32_t begin);
@ -1145,7 +1145,7 @@ class MOZ_STACK_CLASS GeneralParser
bool tryNewTarget(Node& newTarget);
Node importMeta();
Node importExpr(YieldHandling yieldHandling);
Node methodDefinition(uint32_t toStringStart, PropertyType propType, HandleAtom funName);

View file

@ -302,6 +302,9 @@ class SyntaxParseHandler
Node newImportMeta(Node importHolder, Node metaHolder) {
return NodeGeneric;
}
Node newCallImport(Node importHolder, Node singleArg) {
return NodeGeneric;
}
Node newSetThis(Node thisName, Node value) { return value; }

View file

@ -0,0 +1,85 @@
load(libdir + "match.js");
load(libdir + "asserts.js");
var { Pattern, MatchError } = Match;
program = (elts) => Pattern({
type: "Program",
body: elts
});
expressionStatement = (expression) => Pattern({
type: "ExpressionStatement",
expression: expression
});
assignmentExpression = (left, operator, right) => Pattern({
type: "AssignmentExpression",
operator: operator,
left: left,
right: right
});
ident = (name) => Pattern({
type: "Identifier",
name: name
});
importCall = (ident, singleArg) => Pattern({
type: "CallImport",
ident: ident,
arg: singleArg
});
function parseAsClassicScript(source)
{
return Reflect.parse(source);
}
function parseAsModuleScript(source)
{
return Reflect.parse(source, {target: "module"});
}
for (let parse of [parseAsModuleScript, parseAsClassicScript]) {
program([
expressionStatement(
importCall(
ident("import"),
ident("foo")
)
)
]).assert(parse("import(foo);"));
program([
expressionStatement(
assignmentExpression(
ident("x"),
"=",
importCall(
ident("import"),
ident("foo")
)
)
)
]).assert(parse("x = import(foo);"));
}
function assertParseThrowsSyntaxError(source)
{
assertThrowsInstanceOf(() => parseAsClassicScript(source), SyntaxError);
assertThrowsInstanceOf(() => parseAsModuleScript(source), SyntaxError);
}
assertParseThrowsSyntaxError("import");
assertParseThrowsSyntaxError("import(");
assertParseThrowsSyntaxError("import(1,");
assertParseThrowsSyntaxError("import(1, 2");
assertParseThrowsSyntaxError("import(1, 2)");
assertParseThrowsSyntaxError("x = import");
assertParseThrowsSyntaxError("x = import(");
assertParseThrowsSyntaxError("x = import(1,");
assertParseThrowsSyntaxError("x = import(1, 2");
assertParseThrowsSyntaxError("x = import(1, 2)");
// import() is not implemented.
assertThrowsInstanceOf(() => eval("import('foo')"),
SyntaxError);
assertThrowsInstanceOf(() => parseModule("import('foo')"),
SyntaxError);

View file

@ -263,7 +263,7 @@ MSG_DEF(JSMSG_GARBAGE_AFTER_INPUT, 2, JSEXN_SYNTAXERR, "unexpected garbage a
MSG_DEF(JSMSG_IDSTART_AFTER_NUMBER, 0, JSEXN_SYNTAXERR, "identifier starts immediately after numeric literal")
MSG_DEF(JSMSG_BAD_ESCAPE, 0, JSEXN_SYNTAXERR, "invalid escape sequence")
MSG_DEF(JSMSG_ILLEGAL_CHARACTER, 0, JSEXN_SYNTAXERR, "illegal character")
MSG_DEF(JSMSG_IMPORT_OUTSIDE_MODULE, 0, JSEXN_SYNTAXERR, "the import keyword may only appear in a module")
MSG_DEF(JSMSG_IMPORT_META_OUTSIDE_MODULE, 0, JSEXN_SYNTAXERR, "import.meta may only appear in a module")
MSG_DEF(JSMSG_IMPORT_DECL_AT_TOP_LEVEL, 0, JSEXN_SYNTAXERR, "import declarations may only appear at top level of a module")
MSG_DEF(JSMSG_OF_AFTER_FOR_LOOP_DECL, 0, JSEXN_SYNTAXERR, "a declaration in the head of a for-of loop can't have an initializer")
MSG_DEF(JSMSG_IN_AFTER_LEXICAL_FOR_DECL,0,JSEXN_SYNTAXERR, "a lexical declaration in the head of a for-in loop can't have an initializer")
@ -606,6 +606,7 @@ MSG_DEF(JSMSG_AMBIGUOUS_IMPORT, 0, JSEXN_SYNTAXERR, "ambiguous import")
MSG_DEF(JSMSG_MISSING_NAMESPACE_EXPORT, 0, JSEXN_SYNTAXERR, "export not found for namespace")
MSG_DEF(JSMSG_MISSING_EXPORT, 1, JSEXN_SYNTAXERR, "local binding for export '{0}' not found")
MSG_DEF(JSMSG_BAD_MODULE_STATUS, 0, JSEXN_INTERNALERR, "module record has unexpected status")
MSG_DEF(JSMSG_NO_DYNAMIC_IMPORT, 0, JSEXN_SYNTAXERR, "dynamic module import is not implemented")
// Promise
MSG_DEF(JSMSG_CANNOT_RESOLVE_PROMISE_WITH_ITSELF, 0, JSEXN_TYPEERR, "A promise cannot be resolved with itself.")

View file

@ -38,6 +38,7 @@ ASTDEF(AST_YIELD_EXPR, "YieldExpression", "yieldExpres
ASTDEF(AST_CLASS_EXPR, "ClassExpression", "classExpression")
ASTDEF(AST_METAPROPERTY, "MetaProperty", "metaProperty")
ASTDEF(AST_SUPER, "Super", "super")
ASTDEF(AST_CALL_IMPORT, "CallImport", "callImport")
ASTDEF(AST_EMPTY_STMT, "EmptyStatement", "emptyStatement")
ASTDEF(AST_BLOCK_STMT, "BlockStatement", "blockStatement")

View file

@ -90,9 +90,6 @@ using mozilla::dom::PushNotifier;
#define PUSHNOTIFIER_CID \
{ 0x2fc2d3e3, 0x020f, 0x404e, { 0xb0, 0x6a, 0x6e, 0xcf, 0x3e, 0xa2, 0x33, 0x4a } }
#include "AudioChannelAgent.h"
using mozilla::dom::AudioChannelAgent;
// Editor stuff
#include "mozilla/EditorController.h" //CID
@ -140,7 +137,6 @@ static void Shutdown();
#include "nsIMediaManager.h"
#include "mozilla/dom/nsMixedContentBlocker.h"
#include "AudioChannelService.h"
#include "mozilla/net/WebSocketEventService.h"
#include "mozilla/dom/power/PowerManagerService.h"
@ -211,8 +207,6 @@ NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsSynthVoiceRegistry,
nsSynthVoiceRegistry::GetInstanceForService)
#endif
NS_GENERIC_FACTORY_CONSTRUCTOR(AudioChannelAgent)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsDeviceSensors)
#if defined(ANDROID)
@ -424,14 +418,9 @@ _InstanceClass##Constructor(nsISupports *aOuter, REFNSIID aIID, \
NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(Geolocation, Geolocation::NonWindowSingleton)
#define NS_AUDIOCHANNEL_SERVICE_CID \
{ 0xf712e983, 0x048a, 0x443f, { 0x88, 0x02, 0xfc, 0xc3, 0xd9, 0x27, 0xce, 0xac }}
#define NS_WEBSOCKETEVENT_SERVICE_CID \
{ 0x31689828, 0xda66, 0x49a6, { 0x87, 0x0c, 0xdf, 0x62, 0xb8, 0x3f, 0xe7, 0x89 }}
NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(AudioChannelService, AudioChannelService::GetOrCreate)
NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(WebSocketEventService, WebSocketEventService::GetOrCreate)
#ifdef MOZ_WEBSPEECH_TEST_BACKEND
@ -535,13 +524,11 @@ NS_DEFINE_NAMED_CID(STORAGEACTIVITYSERVICE_CID);
NS_DEFINE_NAMED_CID(NOTIFICATIONTELEMETRYSERVICE_CID);
NS_DEFINE_NAMED_CID(PUSHNOTIFIER_CID);
NS_DEFINE_NAMED_CID(WORKERDEBUGGERMANAGER_CID);
NS_DEFINE_NAMED_CID(NS_AUDIOCHANNELAGENT_CID);
NS_DEFINE_NAMED_CID(NS_EDITORCONTROLLER_CID);
NS_DEFINE_NAMED_CID(NS_EDITINGCONTROLLER_CID);
NS_DEFINE_NAMED_CID(NS_EDITORCOMMANDTABLE_CID);
NS_DEFINE_NAMED_CID(NS_EDITINGCOMMANDTABLE_CID);
NS_DEFINE_NAMED_CID(NS_GEOLOCATION_CID);
NS_DEFINE_NAMED_CID(NS_AUDIOCHANNEL_SERVICE_CID);
NS_DEFINE_NAMED_CID(NS_WEBSOCKETEVENT_SERVICE_CID);
NS_DEFINE_NAMED_CID(NS_FOCUSMANAGER_CID);
NS_DEFINE_NAMED_CID(NS_CONTENTSECURITYMANAGER_CID);
@ -765,13 +752,11 @@ static const mozilla::Module::CIDEntry kLayoutCIDs[] = {
{ &kNOTIFICATIONTELEMETRYSERVICE_CID, false, nullptr, NotificationTelemetryServiceConstructor },
{ &kPUSHNOTIFIER_CID, false, nullptr, PushNotifierConstructor },
{ &kWORKERDEBUGGERMANAGER_CID, true, nullptr, WorkerDebuggerManagerConstructor },
{ &kNS_AUDIOCHANNELAGENT_CID, true, nullptr, AudioChannelAgentConstructor },
{ &kNS_EDITORCONTROLLER_CID, false, nullptr, EditorControllerConstructor },
{ &kNS_EDITINGCONTROLLER_CID, false, nullptr, nsEditingControllerConstructor },
{ &kNS_EDITORCOMMANDTABLE_CID, false, nullptr, nsEditorCommandTableConstructor },
{ &kNS_EDITINGCOMMANDTABLE_CID, false, nullptr, nsEditingCommandTableConstructor },
{ &kNS_GEOLOCATION_CID, false, nullptr, GeolocationConstructor },
{ &kNS_AUDIOCHANNEL_SERVICE_CID, false, nullptr, AudioChannelServiceConstructor },
{ &kNS_WEBSOCKETEVENT_SERVICE_CID, false, nullptr, WebSocketEventServiceConstructor },
{ &kNS_FOCUSMANAGER_CID, false, nullptr, CreateFocusManager },
#ifdef MOZ_WEBSPEECH_TEST_BACKEND
@ -865,11 +850,9 @@ static const mozilla::Module::ContractIDEntry kLayoutContracts[] = {
{ NOTIFICATIONTELEMETRYSERVICE_CONTRACTID, &kNOTIFICATIONTELEMETRYSERVICE_CID },
{ PUSHNOTIFIER_CONTRACTID, &kPUSHNOTIFIER_CID },
{ WORKERDEBUGGERMANAGER_CONTRACTID, &kWORKERDEBUGGERMANAGER_CID },
{ NS_AUDIOCHANNELAGENT_CONTRACTID, &kNS_AUDIOCHANNELAGENT_CID },
{ "@mozilla.org/editor/editorcontroller;1", &kNS_EDITORCONTROLLER_CID },
{ "@mozilla.org/editor/editingcontroller;1", &kNS_EDITINGCONTROLLER_CID },
{ "@mozilla.org/geolocation;1", &kNS_GEOLOCATION_CID },
{ "@mozilla.org/audiochannel/service;1", &kNS_AUDIOCHANNEL_SERVICE_CID },
{ "@mozilla.org/websocketevent/service;1", &kNS_WEBSOCKETEVENT_SERVICE_CID },
{ "@mozilla.org/focus-manager;1", &kNS_FOCUSMANAGER_CID },
#ifdef MOZ_WEBSPEECH_TEST_BACKEND

View file

@ -3,7 +3,7 @@ set -x -e -v
OWNER=luser
PROJECT=rust-size
PROJECT_REVISION=4a5d9148f50dc037dc230f10b8fc4e5ca00016aa
PROJECT_REVISION=ab659d93b1faba95307df952aefe3fbed3583669
# This script is for building rust-size
case "$(uname -s)" in

View file

@ -1,4 +1,8 @@
[dynamic-imports-fetch-error.sub.html]
expected: ERROR
[import(): error cases occuring during fetching]
expected: FAIL
[import() must reject when there is a wrong MIME type]
expected: FAIL

View file

@ -1,4 +1,8 @@
[dynamic-imports-script-error.html]
expected: ERROR
[import(): error cases caused by the imported module script]
expected: FAIL
[import() must reject when there is a parse error]
expected: FAIL

View file

@ -2,3 +2,6 @@
[Basic dynamic imports]
expected: FAIL
[Dynamic imports should resolve module.]
expected: FAIL

View file

@ -5,3 +5,6 @@
[propagate-nonce-external-classic]
expected: FAIL
[Dynamically imported module should eval when imported from script w/ a valid nonce.]
expected: FAIL

View file

@ -5,3 +5,6 @@
[propagate-nonce-external-module]
expected: FAIL
[Dynamically imported module should eval when imported from script w/ a valid nonce.]
expected: FAIL

View file

@ -5,3 +5,6 @@
[propagate-nonce-inline-classic]
expected: FAIL
[Dynamically imported module should eval when imported from script w/ a valid nonce.]
expected: FAIL

View file

@ -5,3 +5,6 @@
[propagate-nonce-inline-module]
expected: FAIL
[Dynamically imported module should eval when imported from script w/ a valid nonce.]
expected: FAIL