Merge mozilla-central to inbound. a=merge CLOSED TREE

This commit is contained in:
Brindusan Cristian 2018-10-31 23:45:55 +02:00
commit c0b91fe1ee
176 changed files with 1473 additions and 1100 deletions

View File

@ -41,7 +41,7 @@ async function runTests(browser, accDoc) {
[EVENT_STATE_CHANGE, inIframeChecker("iframe1")]]
});
browser.loadURI(`data:text/html;charset=utf-8,
BrowserTestUtils.loadURI(browser, `data:text/html;charset=utf-8,
<html><body id="body2">
<iframe id="iframe1" src="http://example.com"></iframe>
</body></html>`);
@ -54,7 +54,7 @@ async function runTests(browser, accDoc) {
[EVENT_REORDER, getAccessible(browser)]
]);
browser.loadURI("about:about");
BrowserTestUtils.loadURI(browser, "about:about");
await onLoadEvents;
@ -74,7 +74,7 @@ async function runTests(browser, accDoc) {
[EVENT_REORDER, getAccessible(browser)]
]);
browser.loadURI("about:mozilla");
BrowserTestUtils.loadURI(browser, "about:mozilla");
await onLoadEvents;
@ -94,7 +94,7 @@ async function runTests(browser, accDoc) {
[EVENT_REORDER, getAccessible(browser)]
]);
browser.loadURI("http://www.wronguri.wronguri/");
BrowserTestUtils.loadURI(browser, "http://www.wronguri.wronguri/");
await onLoadEvents;
@ -104,7 +104,7 @@ async function runTests(browser, accDoc) {
[EVENT_REORDER, getAccessible(browser)]
]);
browser.loadURI("https://nocert.example.com:443/");
BrowserTestUtils.loadURI(browser, "https://nocert.example.com:443/");
await onLoadEvents;
}

View File

@ -6315,8 +6315,8 @@ var ToolbarContextMenu = {
updateExtension(popup) {
let removeExtension = popup.querySelector(".customize-context-removeExtension");
let manageExtension = removeExtension.nextElementSibling;
let separator = manageExtension.nextElementSibling;
let manageExtension = popup.querySelector(".customize-context-manageExtension");
let separator = removeExtension.nextElementSibling;
let node = this._getUnwrappedTriggerNode(popup);
let isWebExt = node && node.hasAttribute("data-extensionid");
removeExtension.hidden = manageExtension.hidden = separator.hidden = !isWebExt;

View File

@ -421,16 +421,16 @@ xmlns="http://www.w3.org/1999/xhtml"
<menupopup id="toolbar-context-menu"
onpopupshowing="onViewToolbarsPopupShowing(event, document.getElementById('viewToolbarsMenuSeparator')); ToolbarContextMenu.updateDownloadsAutoHide(this); ToolbarContextMenu.updateExtension(this)">
<menuitem oncommand="ToolbarContextMenu.removeExtensionForContextAction(this.parentElement)"
accesskey="&customizeMenu.removeExtension.accesskey;"
label="&customizeMenu.removeExtension.label;"
contexttype="toolbaritem"
class="customize-context-removeExtension"/>
<menuitem oncommand="ToolbarContextMenu.openAboutAddonsForContextAction(this.parentElement)"
accesskey="&customizeMenu.manageExtension.accesskey;"
label="&customizeMenu.manageExtension.label;"
contexttype="toolbaritem"
class="customize-context-manageExtension"/>
<menuitem oncommand="ToolbarContextMenu.removeExtensionForContextAction(this.parentElement)"
accesskey="&customizeMenu.removeExtension.accesskey;"
label="&customizeMenu.removeExtension.label;"
contexttype="toolbaritem"
class="customize-context-removeExtension"/>
<menuseparator/>
<menuitem oncommand="gCustomizeMode.addToPanel(document.popupNode)"
accesskey="&customizeMenu.pinToOverflowMenu.accesskey;"

View File

@ -30,16 +30,16 @@
-->
<menupopup id="customizationPanelItemContextMenu"
onpopupshowing="gCustomizeMode.onPanelContextMenuShowing(event); ToolbarContextMenu.updateExtension(this)">
<menuitem oncommand="ToolbarContextMenu.removeExtensionForContextAction(this.parentElement)"
accesskey="&customizeMenu.removeExtension.accesskey;"
label="&customizeMenu.removeExtension.label;"
contexttype="toolbaritem"
class="customize-context-removeExtension"/>
<menuitem oncommand="ToolbarContextMenu.openAboutAddonsForContextAction(this.parentElement)"
accesskey="&customizeMenu.manageExtension.accesskey;"
label="&customizeMenu.manageExtension.label;"
contexttype="toolbaritem"
class="customize-context-manageExtension"/>
<menuitem oncommand="ToolbarContextMenu.removeExtensionForContextAction(this.parentElement)"
accesskey="&customizeMenu.removeExtension.accesskey;"
label="&customizeMenu.removeExtension.label;"
contexttype="toolbaritem"
class="customize-context-removeExtension"/>
<menuseparator/>
<menuitem oncommand="gCustomizeMode.addToPanel(document.popupNode)"
id="customizationPanelItemContextMenuPin"

View File

@ -142,7 +142,7 @@ add_task(async function browseraction_contextmenu_manage_extension() {
function checkVisibility(menu, visible) {
let removeExtension = menu.querySelector(".customize-context-removeExtension");
let manageExtension = menu.querySelector(".customize-context-manageExtension");
let separator = manageExtension.nextElementSibling;
let separator = removeExtension.nextElementSibling;
info(`Check visibility`);
let expected = visible ? "visible" : "hidden";

View File

@ -459,7 +459,10 @@
class="accessory-button"
data-l10n-id="update-history"
preference="app.update.disable_button.showUpdateHistory"
searchkeywords="&history.title; &history2.intro;"/>
search-l10n-ids="
history-title,
history-intro
"/>
</vbox>
#endif
</hbox>

View File

@ -18,14 +18,12 @@
<!DOCTYPE page [
<!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd">
<!ENTITY % historyDTD SYSTEM "chrome://mozapps/locale/update/history.dtd">
<!ENTITY % certManagerDTD SYSTEM "chrome://pippki/locale/certManager.dtd">
<!ENTITY % deviceManangerDTD SYSTEM "chrome://pippki/locale/deviceManager.dtd">
<!ENTITY % sanitizeDTD SYSTEM "chrome://browser/locale/sanitize.dtd">
<!ENTITY % aboutDialogDTD SYSTEM "chrome://browser/locale/aboutDialog.dtd" >
%aboutDialogDTD;
%brandDTD;
%historyDTD;
%certManagerDTD;
%deviceManangerDTD;
%sanitizeDTD;
@ -52,6 +50,7 @@
<link rel="localization" href="browser/preferences/permissions.ftl"/>
<link rel="localization" href="browser/preferences/selectBookmark.ftl"/>
<link rel="localization" href="browser/preferences/siteDataSettings.ftl"/>
<link rel="localization" href="toolkit/updates/history.ftl"/>
</linkset>
<html:link rel="shortcut icon"

View File

@ -140,8 +140,11 @@ add_task(async function() {
for (let i = 0; i < updates.length; ++i) {
update = updates[i];
updateData = mockUpdateManager.getUpdateAt(i);
is(update.name, updateData.name + " (" + updateData.buildID + ")", "Wrong update name");
const l10nAttrs = frameDoc.l10n.getAttributes(update);
Assert.deepEqual(l10nAttrs, {
id: "update-full-name",
args: { name: updateData.name, buildID: updateData.buildID },
}, "Wrong update name");
is(update.installDate, formatInstallDate(updateData.installDate), "Wrong update installDate");
is(update.detailsURL, updateData.detailsURL, "Wrong update detailsURL");
is(update.status, updateData.statusText, "Wrong update status");

View File

@ -199,7 +199,7 @@ ContentRestoreInternal.prototype = {
Utils.makeInputStream(loadArguments.postData) : null;
let triggeringPrincipal = loadArguments.triggeringPrincipal
? Utils.deserializePrincipal(loadArguments.triggeringPrincipal)
: null;
: Services.scriptSecurityManager.createNullPrincipal({});
if (loadArguments.userContextId) {
webNavigation.setOriginAttributesBeforeLoading({ userContextId: loadArguments.userContextId });

View File

@ -43,7 +43,8 @@ add_task(async function contentToChromeNavigate() {
await ContentTask.spawn(tab.linkedBrowser, null, function() {
const CHROME_URL = "about:config";
let webnav = content.window.getInterface(Ci.nsIWebNavigation);
webnav.loadURI(CHROME_URL, Ci.nsIWebNavigation.LOAD_FLAGS_NONE, null, null, null);
let systemPrincipal = Services.scriptSecurityManager.getSystemPrincipal();
webnav.loadURI(CHROME_URL, Ci.nsIWebNavigation.LOAD_FLAGS_NONE, null, null, null, systemPrincipal);
});
await BrowserTestUtils.browserLoaded(tab.linkedBrowser);

View File

@ -130,8 +130,9 @@ this.tabExtras = class extends ExtensionAPI {
},
};
windowTracker.addListener("progress", listener);
let triggeringPrincipal = Services.scriptSecurityManager.createNullPrincipal({});
tab.browser.webNavigation.loadURIWithOptions(url, null, null, null,
post, null, null, null);
post, null, null, triggeringPrincipal);
});
},
async getWebcompatInfo(tabId) {

View File

@ -506,6 +506,18 @@ html|input.urlbar-input {
box-shadow: var(--focus-ring-box-shadow);
}
#editBMPanel_folderTree > treechildren::-moz-tree-row(blur,selected),
#editBMPanel_tagsSelector:not(:focus) > richlistitem[selected] {
background-color: var(--arrowpanel-dimmed);
}
#editBMPanel_folderTree > treechildren::-moz-tree-twisty(blur,selected),
#editBMPanel_folderTree > treechildren::-moz-tree-image(blur,selected),
#editBMPanel_folderTree > treechildren::-moz-tree-cell-text(blur,selected),
#editBMPanel_tagsSelector:not(:focus) > richlistitem[selected] {
color: inherit;
}
#editBMPanel_folderTree {
border-bottom: none;
border-bottom-left-radius: 0;

View File

@ -497,7 +497,7 @@ BasePrincipal::ContentScriptAddonPolicy()
}
auto expanded = As<ExpandedPrincipal>();
for (auto& prin : expanded->WhiteList()) {
for (auto& prin : expanded->AllowList()) {
if (auto policy = BasePrincipal::Cast(prin)->AddonPolicy()) {
return policy;
}

View File

@ -170,7 +170,7 @@ public:
//
// For most principal types, this returns the principal itself. For expanded
// principals, it returns the first sub-principal which subsumes the given URI
// (or, if no URI is given, the last whitelist principal).
// (or, if no URI is given, the last allowlist principal).
nsIPrincipal* PrincipalToInherit(nsIURI* aRequestedURI = nullptr);
/**

View File

@ -41,10 +41,10 @@ BroadcastDomainSetChange(DomainSetType aSetType, DomainSetChangeType aChangeType
return NS_OK;
}
DomainPolicy::DomainPolicy() : mBlacklist(new DomainSet(BLACKLIST))
, mSuperBlacklist(new DomainSet(SUPER_BLACKLIST))
, mWhitelist(new DomainSet(WHITELIST))
, mSuperWhitelist(new DomainSet(SUPER_WHITELIST))
DomainPolicy::DomainPolicy() : mBlocklist(new DomainSet(BLOCKLIST))
, mSuperBlocklist(new DomainSet(SUPER_BLOCKLIST))
, mAllowlist(new DomainSet(ALLOWLIST))
, mSuperAllowlist(new DomainSet(SUPER_ALLOWLIST))
{
if (XRE_IsParentProcess()) {
BroadcastDomainSetChange(NO_TYPE, ACTIVATE_POLICY);
@ -55,39 +55,39 @@ DomainPolicy::~DomainPolicy()
{
// The SSM holds a strong ref to the DomainPolicy until Deactivate() is
// invoked, so we should never hit the destructor until that happens.
MOZ_ASSERT(!mBlacklist && !mSuperBlacklist &&
!mWhitelist && !mSuperWhitelist);
MOZ_ASSERT(!mBlocklist && !mSuperBlocklist &&
!mAllowlist && !mSuperAllowlist);
}
NS_IMETHODIMP
DomainPolicy::GetBlacklist(nsIDomainSet** aSet)
DomainPolicy::GetBlocklist(nsIDomainSet** aSet)
{
nsCOMPtr<nsIDomainSet> set = mBlacklist.get();
nsCOMPtr<nsIDomainSet> set = mBlocklist.get();
set.forget(aSet);
return NS_OK;
}
NS_IMETHODIMP
DomainPolicy::GetSuperBlacklist(nsIDomainSet** aSet)
DomainPolicy::GetSuperBlocklist(nsIDomainSet** aSet)
{
nsCOMPtr<nsIDomainSet> set = mSuperBlacklist.get();
nsCOMPtr<nsIDomainSet> set = mSuperBlocklist.get();
set.forget(aSet);
return NS_OK;
}
NS_IMETHODIMP
DomainPolicy::GetWhitelist(nsIDomainSet** aSet)
DomainPolicy::GetAllowlist(nsIDomainSet** aSet)
{
nsCOMPtr<nsIDomainSet> set = mWhitelist.get();
nsCOMPtr<nsIDomainSet> set = mAllowlist.get();
set.forget(aSet);
return NS_OK;
}
NS_IMETHODIMP
DomainPolicy::GetSuperWhitelist(nsIDomainSet** aSet)
DomainPolicy::GetSuperAllowlist(nsIDomainSet** aSet)
{
nsCOMPtr<nsIDomainSet> set = mSuperWhitelist.get();
nsCOMPtr<nsIDomainSet> set = mSuperAllowlist.get();
set.forget(aSet);
return NS_OK;
}
@ -97,16 +97,16 @@ DomainPolicy::Deactivate()
{
// Clear the hashtables first to free up memory, since script might
// hold the doomed sets alive indefinitely.
mBlacklist->Clear();
mSuperBlacklist->Clear();
mWhitelist->Clear();
mSuperWhitelist->Clear();
mBlocklist->Clear();
mSuperBlocklist->Clear();
mAllowlist->Clear();
mSuperAllowlist->Clear();
// Null them out.
mBlacklist = nullptr;
mSuperBlacklist = nullptr;
mWhitelist = nullptr;
mSuperWhitelist = nullptr;
mBlocklist = nullptr;
mSuperBlocklist = nullptr;
mAllowlist = nullptr;
mSuperAllowlist = nullptr;
// Inform the SSM.
nsScriptSecurityManager* ssm = nsScriptSecurityManager::GetScriptSecurityManager();
@ -123,10 +123,10 @@ void
DomainPolicy::CloneDomainPolicy(DomainPolicyClone* aClone)
{
aClone->active() = true;
mBlacklist->CloneSet(&aClone->blacklist());
mSuperBlacklist->CloneSet(&aClone->superBlacklist());
mWhitelist->CloneSet(&aClone->whitelist());
mSuperWhitelist->CloneSet(&aClone->superWhitelist());
mBlocklist->CloneSet(&aClone->blocklist());
mSuperBlocklist->CloneSet(&aClone->superBlocklist());
mAllowlist->CloneSet(&aClone->allowlist());
mSuperAllowlist->CloneSet(&aClone->superAllowlist());
}
static
@ -142,10 +142,10 @@ CopyURIs(const InfallibleTArray<URIParams>& aDomains, nsIDomainSet* aSet)
void
DomainPolicy::ApplyClone(const DomainPolicyClone* aClone)
{
CopyURIs(aClone->blacklist(), mBlacklist);
CopyURIs(aClone->whitelist(), mWhitelist);
CopyURIs(aClone->superBlacklist(), mSuperBlacklist);
CopyURIs(aClone->superWhitelist(), mSuperWhitelist);
CopyURIs(aClone->blocklist(), mBlocklist);
CopyURIs(aClone->allowlist(), mAllowlist);
CopyURIs(aClone->superBlocklist(), mSuperBlocklist);
CopyURIs(aClone->superAllowlist(), mSuperAllowlist);
}
static already_AddRefed<nsIURI>

View File

@ -27,10 +27,10 @@ enum DomainSetChangeType{
enum DomainSetType{
NO_TYPE,
BLACKLIST,
SUPER_BLACKLIST,
WHITELIST,
SUPER_WHITELIST
BLOCKLIST,
SUPER_BLOCKLIST,
ALLOWLIST,
SUPER_ALLOWLIST
};
class DomainSet final : public nsIDomainSet
@ -61,10 +61,10 @@ public:
private:
virtual ~DomainPolicy();
RefPtr<DomainSet> mBlacklist;
RefPtr<DomainSet> mSuperBlacklist;
RefPtr<DomainSet> mWhitelist;
RefPtr<DomainSet> mSuperWhitelist;
RefPtr<DomainSet> mBlocklist;
RefPtr<DomainSet> mSuperBlocklist;
RefPtr<DomainSet> mAllowlist;
RefPtr<DomainSet> mSuperAllowlist;
};
} /* namespace mozilla */

View File

@ -45,14 +45,14 @@ struct OriginComparator
}
};
ExpandedPrincipal::ExpandedPrincipal(nsTArray<nsCOMPtr<nsIPrincipal>> &aWhiteList)
ExpandedPrincipal::ExpandedPrincipal(nsTArray<nsCOMPtr<nsIPrincipal>> &aAllowList)
: BasePrincipal(eExpandedPrincipal)
{
// 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) {
mPrincipals.InsertElementSorted(aWhiteList[i], c);
for (size_t i = 0; i < aAllowList.Length(); ++i) {
mPrincipals.InsertElementSorted(aAllowList[i], c);
}
}
@ -65,10 +65,10 @@ ExpandedPrincipal::~ExpandedPrincipal()
{ }
already_AddRefed<ExpandedPrincipal>
ExpandedPrincipal::Create(nsTArray<nsCOMPtr<nsIPrincipal>>& aWhiteList,
ExpandedPrincipal::Create(nsTArray<nsCOMPtr<nsIPrincipal>>& aAllowList,
const OriginAttributes& aAttrs)
{
RefPtr<ExpandedPrincipal> ep = new ExpandedPrincipal(aWhiteList);
RefPtr<ExpandedPrincipal> ep = new ExpandedPrincipal(aAllowList);
nsAutoCString origin;
origin.AssignLiteral("[Expanded Principal [");
@ -110,7 +110,7 @@ ExpandedPrincipal::SubsumesInternal(nsIPrincipal* aOther,
if (Cast(aOther)->Is<ExpandedPrincipal>()) {
auto* expanded = Cast(aOther)->As<ExpandedPrincipal>();
for (auto& other : expanded->WhiteList()) {
for (auto& other : expanded->AllowList()) {
// Use SubsumesInternal rather than Subsumes here, since OriginAttribute
// checks are only done between non-expanded sub-principals, and we don't
// need to incur the extra virtual call overhead.
@ -158,7 +158,7 @@ ExpandedPrincipal::GetURI(nsIURI** aURI)
}
const nsTArray<nsCOMPtr<nsIPrincipal>>&
ExpandedPrincipal::WhiteList()
ExpandedPrincipal::AllowList()
{
return mPrincipals;
}
@ -207,7 +207,7 @@ ExpandedPrincipal::PrincipalToInherit(nsIURI* aRequestedURI)
// with forced principal inheritance, and creation of XML documents from
// XMLHttpRequests or fetch requests. For URIs that normally inherit a
// principal (such as data: URIs), we fall back to the last principal in the
// whitelist.
// allowlist.
for (const auto& principal : mPrincipals) {
if (Cast(principal)->MayLoadInternal(aRequestedURI)) {
return principal;
@ -316,16 +316,16 @@ ExpandedPrincipal::GetSiteIdentifier(SiteIdentifier& aSite)
// Call GetSiteIdentifier on each of our principals and return a new
// ExpandedPrincipal.
nsTArray<nsCOMPtr<nsIPrincipal>> whitelist;
nsTArray<nsCOMPtr<nsIPrincipal>> allowlist;
for (const auto& principal : mPrincipals) {
SiteIdentifier site;
nsresult rv = Cast(principal)->GetSiteIdentifier(site);
NS_ENSURE_SUCCESS(rv, rv);
whitelist.AppendElement(site.GetPrincipal());
allowlist.AppendElement(site.GetPrincipal());
}
RefPtr<ExpandedPrincipal> expandedPrincipal =
ExpandedPrincipal::Create(whitelist, OriginAttributesRef());
ExpandedPrincipal::Create(allowlist, OriginAttributesRef());
MOZ_ASSERT(expandedPrincipal, "ExpandedPrincipal::Create returned nullptr?");
aSite.Init(expandedPrincipal);

View File

@ -17,7 +17,7 @@ class ExpandedPrincipal : public nsIExpandedPrincipal
{
public:
static already_AddRefed<ExpandedPrincipal>
Create(nsTArray<nsCOMPtr<nsIPrincipal>>& aWhiteList,
Create(nsTArray<nsCOMPtr<nsIPrincipal>>& aAllowList,
const mozilla::OriginAttributes& aAttrs);
static PrincipalKind Kind() { return eExpandedPrincipal; }
@ -50,7 +50,7 @@ public:
nsresult GetSiteIdentifier(mozilla::SiteIdentifier& aSite) override;
protected:
explicit ExpandedPrincipal(nsTArray<nsCOMPtr<nsIPrincipal>> &aWhiteList);
explicit ExpandedPrincipal(nsTArray<nsCOMPtr<nsIPrincipal>> &aAllowList);
virtual ~ExpandedPrincipal();

View File

@ -23,10 +23,10 @@ class DomainPolicyClone;
* When a domain policy is instantiated by invoking activateDomainPolicy() on
* nsIScriptSecurityManager, these domain sets are consulted when each new
* global is created (they have no effect on already-created globals).
* If javascript is globally enabled with |javascript.enabled|, the blacklists
* are consulted. If globally disabled, the whitelists are consulted. Lookups
* on blacklist and whitelist happen with contains(), and lookups on
* superBlacklist and superWhitelist happen with containsSuperDomain().
* If javascript is globally enabled with |javascript.enabled|, the blocklists
* are consulted. If globally disabled, the allowlists are consulted. Lookups
* on blocklist and allowlist happen with contains(), and lookups on
* superBlocklist and superAllowlist happen with containsSuperDomain().
*
* When deactivate() is invoked, the domain sets are emptied, and the
* nsIDomainPolicy ceases to have any effect on the system.
@ -34,10 +34,10 @@ class DomainPolicyClone;
[scriptable, builtinclass, uuid(82b24a20-6701-4d40-a0f9-f5dc7321b555)]
interface nsIDomainPolicy : nsISupports
{
readonly attribute nsIDomainSet blacklist;
readonly attribute nsIDomainSet superBlacklist;
readonly attribute nsIDomainSet whitelist;
readonly attribute nsIDomainSet superWhitelist;
readonly attribute nsIDomainSet blocklist;
readonly attribute nsIDomainSet superBlocklist;
readonly attribute nsIDomainSet allowlist;
readonly attribute nsIDomainSet superAllowlist;
void deactivate();

View File

@ -362,11 +362,11 @@ interface nsIExpandedPrincipal : nsISupports
* When an expanded principal is used as a triggering principal for a
* request that inherits a security context, one of its constitutent
* principals is inherited rather than the expanded principal itself. The
* last principal in the whitelist is the default principal to inherit.
* last principal in the allowlist is the default principal to inherit.
*
* Note: this list is not reference counted, it is shared, so
* should not be changed and should only be used ephemerally.
*/
[noscript, notxpcom, nostdcall]
PrincipalArray WhiteList();
PrincipalArray AllowList();
};

View File

@ -127,11 +127,11 @@ interface nsIScriptSecurityManager : nsISupports
in unsigned long flags);
/**
* Returns true if the URI is from a domain that is white-listed through
* Returns true if the URI is from a domain that is allow-listed through
* prefs to be allowed to use file:// URIs.
* @param aUri the URI to be tested
*/
bool inFileURIWhitelist(in nsIURI aUri);
bool inFileURIAllowlist(in nsIURI aUri);
///////////////// Principals ///////////////////////
@ -274,7 +274,7 @@ interface nsIScriptSecurityManager : nsISupports
*
* If domainPolicyEnabled is false, this simply returns the current value
* of javascript.enabled. Otherwise, it returns the same value, but taking
* the various blacklist/whitelist exceptions into account.
* the various blocklist/allowlist exceptions into account.
*/
bool policyAllowsScript(in nsIURI aDomain);
};

View File

@ -211,7 +211,7 @@ ReadPrincipalInfo(JSStructuredCloneReader* aReader,
if (!ReadPrincipalInfo(aReader, tag, sub)) {
return false;
}
expanded.whitelist().AppendElement(sub);
expanded.allowlist().AppendElement(sub);
}
aInfo = expanded;
@ -307,12 +307,12 @@ WritePrincipalInfo(JSStructuredCloneWriter* aWriter, const PrincipalInfo& aInfo)
if (aInfo.type() == PrincipalInfo::TExpandedPrincipalInfo) {
const ExpandedPrincipalInfo& expanded = aInfo;
if (!JS_WriteUint32Pair(aWriter, SCTAG_DOM_EXPANDED_PRINCIPAL, 0) ||
!JS_WriteUint32Pair(aWriter, expanded.whitelist().Length(), 0)) {
!JS_WriteUint32Pair(aWriter, expanded.allowlist().Length(), 0)) {
return false;
}
for (uint32_t i = 0; i < expanded.whitelist().Length(); i++) {
if (!WritePrincipalInfo(aWriter, expanded.whitelist()[i])) {
for (uint32_t i = 0; i < expanded.allowlist().Length(); i++) {
if (!WritePrincipalInfo(aWriter, expanded.allowlist()[i])) {
return false;
}
}

View File

@ -705,16 +705,16 @@ nsScriptSecurityManager::CheckLoadURIWithPrincipal(nsIPrincipal* aPrincipal,
auto* basePrin = BasePrincipal::Cast(aPrincipal);
if (basePrin->Is<ExpandedPrincipal>()) {
auto expanded = basePrin->As<ExpandedPrincipal>();
for (auto& prin : expanded->WhiteList()) {
for (auto& prin : expanded->AllowList()) {
nsresult rv = CheckLoadURIWithPrincipal(prin,
aTargetURI,
aFlags);
if (NS_SUCCEEDED(rv)) {
// Allow access if it succeeded with one of the white listed principals
// Allow access if it succeeded with one of the allowlisted principals
return NS_OK;
}
}
// None of our whitelisted principals worked.
// None of our allowlisted principals worked.
return NS_ERROR_DOM_BAD_URI;
}
NS_ERROR("Non-system principals or expanded principal passed to CheckLoadURIWithPrincipal "
@ -1008,7 +1008,7 @@ nsScriptSecurityManager::CheckLoadURIFlags(nsIURI *aSourceURI,
return NS_OK;
}
} else if (targetScheme.EqualsLiteral("chrome")) {
// Allow the load only if the chrome package is whitelisted.
// Allow the load only if the chrome package is allowlisted.
nsCOMPtr<nsIXULChromeRegistry> reg(
do_GetService(NS_CHROMEREGISTRY_CONTRACTID));
if (reg) {
@ -1033,11 +1033,11 @@ nsScriptSecurityManager::CheckLoadURIFlags(nsIURI *aSourceURI,
&hasFlags);
NS_ENSURE_SUCCESS(rv, rv);
if (hasFlags) {
// Allow domains that were whitelisted in the prefs. In 99.9% of cases,
// Allow domains that were allowlisted in the prefs. In 99.9% of cases,
// this array is empty.
bool isWhitelisted;
MOZ_ALWAYS_SUCCEEDS(InFileURIWhitelist(aSourceURI, &isWhitelisted));
if (isWhitelisted) {
bool isAllowlisted;
MOZ_ALWAYS_SUCCEEDS(InFileURIAllowlist(aSourceURI, &isAllowlisted));
if (isAllowlisted) {
return NS_OK;
}
@ -1195,13 +1195,13 @@ nsScriptSecurityManager::CheckLoadURIStrWithPrincipal(nsIPrincipal* aPrincipal,
}
NS_IMETHODIMP
nsScriptSecurityManager::InFileURIWhitelist(nsIURI* aUri, bool* aResult)
nsScriptSecurityManager::InFileURIAllowlist(nsIURI* aUri, bool* aResult)
{
MOZ_ASSERT(aUri);
MOZ_ASSERT(aResult);
*aResult = false;
for (nsIURI* uri : EnsureFileURIWhitelist()) {
for (nsIURI* uri : EnsureFileURIAllowlist()) {
if (EqualOrSubdomain(aUri, uri)) {
*aResult = true;
return NS_OK;
@ -1299,7 +1299,7 @@ nsScriptSecurityManager::CanCreateWrapper(JSContext *cx,
{
// XXX Special case for Exception ?
// We give remote-XUL whitelisted domains a free pass here. See bug 932906.
// We give remote-XUL allowlisted domains a free pass here. See bug 932906.
JS::Rooted<JS::Realm*> contextRealm(cx, JS::GetCurrentRealmOrNull(cx));
MOZ_RELEASE_ASSERT(contextRealm);
if (!xpc::AllowContentXBLScope(contextRealm)) {
@ -1533,11 +1533,11 @@ nsScriptSecurityManager::ScriptSecurityPrefChanged(const char* aPref)
Preferences::GetBool(sJSEnabledPrefName, mIsJavaScriptEnabled);
sStrictFileOriginPolicy =
Preferences::GetBool(sFileOriginPolicyPrefName, false);
mFileURIWhitelist.reset();
mFileURIAllowlist.reset();
}
void
nsScriptSecurityManager::AddSitesToFileURIWhitelist(const nsCString& aSiteList)
nsScriptSecurityManager::AddSitesToFileURIAllowlist(const nsCString& aSiteList)
{
for (uint32_t base = SkipPast<IsWhitespace>(aSiteList, 0), bound = 0;
base < aSiteList.Length();
@ -1550,8 +1550,8 @@ nsScriptSecurityManager::AddSitesToFileURIWhitelist(const nsCString& aSiteList)
// Check if the URI is schemeless. If so, add both http and https.
nsAutoCString unused;
if (NS_FAILED(sIOService->ExtractScheme(site, unused))) {
AddSitesToFileURIWhitelist(NS_LITERAL_CSTRING("http://") + site);
AddSitesToFileURIWhitelist(NS_LITERAL_CSTRING("https://") + site);
AddSitesToFileURIAllowlist(NS_LITERAL_CSTRING("http://") + site);
AddSitesToFileURIAllowlist(NS_LITERAL_CSTRING("https://") + site);
continue;
}
@ -1559,11 +1559,11 @@ nsScriptSecurityManager::AddSitesToFileURIWhitelist(const nsCString& aSiteList)
nsCOMPtr<nsIURI> uri;
nsresult rv = NS_NewURI(getter_AddRefs(uri), site, nullptr, nullptr, sIOService);
if (NS_SUCCEEDED(rv)) {
mFileURIWhitelist.ref().AppendElement(uri);
mFileURIAllowlist.ref().AppendElement(uri);
} else {
nsCOMPtr<nsIConsoleService> console(do_GetService("@mozilla.org/consoleservice;1"));
if (console) {
nsAutoString msg = NS_LITERAL_STRING("Unable to to add site to file:// URI whitelist: ") +
nsAutoString msg = NS_LITERAL_STRING("Unable to to add site to file:// URI allowlist: ") +
NS_ConvertASCIItoUTF16(site);
console->LogStringMessage(msg.get());
}
@ -1657,16 +1657,16 @@ nsScriptSecurityManager::PolicyAllowsScript(nsIURI* aURI, bool *aRv)
}
// We have a domain policy. Grab the appropriate set of exceptions to the
// rule (either the blacklist or the whitelist, depending on whether script
// rule (either the blocklist or the allowlist, depending on whether script
// is enabled or disabled by default).
nsCOMPtr<nsIDomainSet> exceptions;
nsCOMPtr<nsIDomainSet> superExceptions;
if (*aRv) {
mDomainPolicy->GetBlacklist(getter_AddRefs(exceptions));
mDomainPolicy->GetSuperBlacklist(getter_AddRefs(superExceptions));
mDomainPolicy->GetBlocklist(getter_AddRefs(exceptions));
mDomainPolicy->GetSuperBlocklist(getter_AddRefs(superExceptions));
} else {
mDomainPolicy->GetWhitelist(getter_AddRefs(exceptions));
mDomainPolicy->GetSuperWhitelist(getter_AddRefs(superExceptions));
mDomainPolicy->GetAllowlist(getter_AddRefs(exceptions));
mDomainPolicy->GetSuperAllowlist(getter_AddRefs(superExceptions));
}
bool contains;
@ -1686,10 +1686,10 @@ nsScriptSecurityManager::PolicyAllowsScript(nsIURI* aURI, bool *aRv)
}
const nsTArray<nsCOMPtr<nsIURI>>&
nsScriptSecurityManager::EnsureFileURIWhitelist()
nsScriptSecurityManager::EnsureFileURIAllowlist()
{
if (mFileURIWhitelist.isSome()) {
return mFileURIWhitelist.ref();
if (mFileURIAllowlist.isSome()) {
return mFileURIAllowlist.ref();
}
//
@ -1698,7 +1698,7 @@ nsScriptSecurityManager::EnsureFileURIWhitelist()
// have come to depend on. See bug 995943.
//
mFileURIWhitelist.emplace();
mFileURIAllowlist.emplace();
nsAutoCString policies;
mozilla::Preferences::GetCString("capability.policy.policynames", policies);
for (uint32_t base = SkipPast<IsWhitespaceOrComma>(policies, 0), bound = 0;
@ -1725,8 +1725,8 @@ nsScriptSecurityManager::EnsureFileURIWhitelist()
NS_LITERAL_CSTRING(".sites");
nsAutoCString siteList;
Preferences::GetCString(domainPrefName.get(), siteList);
AddSitesToFileURIWhitelist(siteList);
AddSitesToFileURIAllowlist(siteList);
}
return mFileURIWhitelist.ref();
return mFileURIAllowlist.ref();
}

View File

@ -100,7 +100,7 @@ private:
ScriptSecurityPrefChanged(const char* aPref = nullptr);
inline void
AddSitesToFileURIWhitelist(const nsCString& aSiteList);
AddSitesToFileURIAllowlist(const nsCString& aSiteList);
nsresult GetChannelResultPrincipal(nsIChannel* aChannel,
nsIPrincipal** aPrincipal,
@ -110,18 +110,18 @@ private:
CheckLoadURIFlags(nsIURI* aSourceURI, nsIURI* aTargetURI, nsIURI* aSourceBaseURI,
nsIURI* aTargetBaseURI, uint32_t aFlags, bool aFromPrivateWindow);
// Returns the file URI whitelist, initializing it if it has not been
// Returns the file URI allowlist, initializing it if it has not been
// initialized.
const nsTArray<nsCOMPtr<nsIURI>>& EnsureFileURIWhitelist();
const nsTArray<nsCOMPtr<nsIURI>>& EnsureFileURIAllowlist();
nsCOMPtr<nsIPrincipal> mSystemPrincipal;
bool mPrefInitialized;
bool mIsJavaScriptEnabled;
// List of URIs whose domains and sub-domains are whitelisted to allow
// List of URIs whose domains and sub-domains are allowlisted to allow
// access to file: URIs. Lazily initialized; isNothing() when not yet
// initialized.
mozilla::Maybe<nsTArray<nsCOMPtr<nsIURI>>> mFileURIWhitelist;
mozilla::Maybe<nsTArray<nsCOMPtr<nsIURI>>> mFileURIAllowlist;
// This machinery controls new-style domain policies. The old-style
// policy machinery will be removed soon.

View File

@ -65,16 +65,16 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1180921
ok(!success, "cross-origin load should fail for addon A");
return tryLoad(addonA, uriForDomain("http://test1.example.org"));
}).then(function(success) {
ok(success, "whitelisted cross-origin load of test1 should succeed for addon A");
ok(success, "allowlisted cross-origin load of test1 should succeed for addon A");
return tryLoad(addonB, uriForDomain("http://test1.example.org"));
}).then(function(success) {
ok(!success, "non-whitelisted cross-origin load of test1 should fail for addon B");
ok(!success, "non-allowlisted cross-origin load of test1 should fail for addon B");
return tryLoad(addonB, uriForDomain("http://test2.example.org"));
}).then(function(success) {
ok(success, "whitelisted cross-origin load of test2 should succeed for addon B");
ok(success, "allowlisted cross-origin load of test2 should succeed for addon B");
return tryLoad(addonA, uriForDomain("http://test2.example.org"));
}).then(function(success) {
ok(!success, "non-whitelisted cross-origin load of test2 should fail for addon A");
ok(!success, "non-allowlisted cross-origin load of test2 should fail for addon A");
SimpleTest.finish();
}, function(e) {
ok(false, "Rejected promise chain: " + e);

View File

@ -21,7 +21,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=292789
/** Test for Bug 292789
**
** Selectively allow access to whitelisted chrome packages
** Selectively allow access to allowlisted chrome packages
** even for ALLOW_CHROME mechanisms (<script>, <img> etc)
**/

View File

@ -249,8 +249,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=840488
} catch (e) {
ok(true, "can't have two live domain policies");
}
var sbRef = policy.superBlacklist;
isnot(sbRef, null, "superBlacklist non-null");
var sbRef = policy.superBlocklist;
isnot(sbRef, null, "superBlocklist non-null");
ok(!sbRef.contains(makeURI('http://www.example.com')));
sbRef.add(makeURI('http://www.example.com/foopy'));
ok(sbRef.contains(makeURI('http://www.example.com')));
@ -273,18 +273,18 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=840488
ok(!sbRef.contains(makeURI('http://www.example.com')),
"Disabling domain policy clears the set");
policy = ssm.activateDomainPolicy();
ok(policy.superBlacklist);
isnot(sbRef, policy.superBlacklist, "Mint new sets each time!");
ok(policy.superBlocklist);
isnot(sbRef, policy.superBlocklist, "Mint new sets each time!");
policy.deactivate();
is(policy.blacklist, null, "blacklist nulled out");
is(policy.blocklist, null, "blocklist nulled out");
policy = ssm.activateDomainPolicy();
isnot(policy.blacklist, null, "non-null again");
isnot(policy.blacklist, sbRef, "freshly minted");
isnot(policy.blocklist, null, "non-null again");
isnot(policy.blocklist, sbRef, "freshly minted");
policy.deactivate();
//
// Now, create and apply a mock-policy. We check the same policy both as
// a blacklist and as a whitelist.
// a blocklist and as a allowlist.
//
window.testPolicy = {
@ -303,20 +303,20 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=840488
};
policy = ssm.activateDomainPolicy();
info("Testing Blacklist-style Domain Policy");
info("Testing Blocklist-style Domain Policy");
return testDomainPolicy(true, testPolicy.exceptions,
testPolicy.superExceptions, testPolicy.exempt,
testPolicy.notExempt, policy.blacklist,
policy.superBlacklist, rootWin);
testPolicy.notExempt, policy.blocklist,
policy.superBlocklist, rootWin);
}).then(function() {
policy.deactivate();
policy = ssm.activateDomainPolicy();
info("Testing Whitelist-style Domain Policy");
info("Testing Allowlist-style Domain Policy");
setScriptEnabledForBrowser(false);
return testDomainPolicy(false, testPolicy.exceptions,
testPolicy.superExceptions, testPolicy.exempt,
testPolicy.notExempt, policy.whitelist,
policy.superWhitelist, rootWin);
testPolicy.notExempt, policy.allowlist,
policy.superAllowlist, rootWin);
}).then(function() {
setScriptEnabledForBrowser(true);
policy.deactivate();

View File

@ -10,12 +10,13 @@
* +--------+----------------+
*/
.sidebar-fixed-item {
.sidebar-fixed-item__container {
align-items: center;
border-radius: 2px;
display: grid;
grid-template-columns: 34px 1fr;
font-size: 16px;
height: 100%;
}
.sidebar-fixed-item__icon {

View File

@ -41,23 +41,27 @@ class SidebarFixedItem extends PureComponent {
{
isSelected,
selectable: true,
className: "sidebar-fixed-item",
onSelect: () => {
dispatch(Actions.selectPage(id, runtimeId));
},
},
dom.img(
dom.div(
{
className: "sidebar-fixed-item__icon",
src: icon,
}
),
dom.span(
{
className: "ellipsis-text",
title: name,
className: "sidebar-fixed-item__container",
},
name
dom.img(
{
className: "sidebar-fixed-item__icon",
src: icon,
}
),
dom.span(
{
className: "ellipsis-text",
title: name,
},
name
)
)
);
}

View File

@ -18,6 +18,16 @@
-moz-user-select: none;
}
.sidebar-item__link {
display: block;
height: 100%;
}
.sidebar-item__link,
.sidebar-item__link:hover {
color: inherit; /* do not apply usual link colors, but grab this element parent's */
}
.sidebar-item:not(.sidebar-item--selectable) {
color: var(--grey-40);
}

View File

@ -30,12 +30,31 @@ class SidebarItem extends PureComponent {
};
}
onItemClick() {
// temporary handler until a router is in place
onItemClick(evt) {
evt.preventDefault();
this.props.onSelect();
}
renderContent() {
const { children, selectable } = this.props;
if (selectable) {
return dom.a(
{
className: "sidebar-item__link js-sidebar-link",
href: "#", // to be changed with a path when a router is in place
onClick: (evt) => this.onItemClick(evt),
},
children
);
}
return children;
}
render() {
const {children, className, isSelected, selectable } = this.props;
const {className, isSelected, selectable } = this.props;
return dom.li(
{
@ -46,9 +65,8 @@ class SidebarItem extends PureComponent {
""
) +
(selectable ? " sidebar-item--selectable" : ""),
onClick: selectable ? () => this.onItemClick() : null,
},
children
this.renderContent()
);
}
}

View File

@ -10,12 +10,13 @@
* +--------+----------------+---------------------------+
*/
.sidebar-runtime-item {
.sidebar-runtime-item__container {
font-size: 0.8em;
align-items: center;
display: grid;
grid-column-gap: var(--base-distance);
grid-template-columns: calc(var(--base-distance) * 6) 1fr auto;
height: 100%;
}
.sidebar-runtime-item__icon {

View File

@ -94,22 +94,25 @@ class SidebarRuntimeItem extends PureComponent {
{
isSelected,
selectable: isConnected,
className: "sidebar-runtime-item",
onSelect: () => {
dispatch(Actions.selectPage(id, runtimeId));
},
},
dom.img(
dom.div(
{
className: "sidebar-runtime-item__icon " +
`${isConnected ? "sidebar-runtime-item__icon--connected" : "" }`,
src: icon,
alt: connectionStatus,
title: connectionStatus,
}
),
deviceName ? this.renderNameWithDevice(name, deviceName) : this.renderName(name),
!isConnected ? this.renderConnectButton() : null
className: "sidebar-runtime-item__container",
},
dom.img(
{
className: "sidebar-runtime-item__icon ",
src: icon,
alt: connectionStatus,
title: connectionStatus,
}
),
deviceName ? this.renderNameWithDevice(name, deviceName) : this.renderName(name),
!isConnected ? this.renderConnectButton() : null
)
);
}
}

View File

@ -18,9 +18,11 @@ add_task(async function() {
const { document, tab } = await openAboutDebugging();
const connectSidebarItem = findSidebarItemByText("Connect", document);
const connectLink = connectSidebarItem.querySelector(".js-sidebar-link");
ok(connectSidebarItem, "Found the Connect sidebar item");
const thisFirefoxSidebarItem = findSidebarItemByText("This Firefox", document);
const thisFirefoxLink = thisFirefoxSidebarItem.querySelector(".js-sidebar-link");
ok(thisFirefoxSidebarItem, "Found the ThisFirefox sidebar item");
ok(isSidebarItemSelected(thisFirefoxSidebarItem),
"ThisFirefox sidebar item is selected by default");
@ -32,7 +34,7 @@ add_task(async function() {
await waitUntil(() => findDebugTargetByText("TAB1", document));
info("Click on the Connect item in the sidebar");
connectSidebarItem.click();
connectLink.click();
info("Wait until Connect page is displayed");
await waitUntil(() => document.querySelector(".js-connect-page"));
@ -43,7 +45,7 @@ add_task(async function() {
const backgroundTab2 = await addTab(TAB_URL_2, { background: true });
info("Click on the ThisFirefox item in the sidebar");
thisFirefoxSidebarItem.click();
thisFirefoxLink.click();
info("Wait until ThisFirefox page is displayed");
await waitUntil(() => document.querySelector(".js-runtime-page"));

View File

@ -89,9 +89,11 @@ async function selectConnectPage(doc) {
return element.textContent === "Connect";
});
ok(connectSidebarItem, "Sidebar contains a Connect item");
const connectLink = connectSidebarItem.querySelector(".js-sidebar-link");
ok(connectLink, "Sidebar contains a Connect link");
info("Click on the Connect item in the sidebar");
connectSidebarItem.click();
info("Click on the Connect link in the sidebar");
connectLink.click();
info("Wait until Connect page is displayed");
await waitUntil(() => doc.querySelector(".js-connect-page"));

View File

@ -71,7 +71,6 @@ skip-if = (os == "win" && ccov) # Bug 1490981
[browser_animation_logic_mutations.js]
[browser_animation_logic_mutations_add_remove_immediately.js]
[browser_animation_logic_mutations_fast.js]
skip-if= true # Bug 1500046
[browser_animation_logic_mutations_properties.js]
[browser_animation_logic_overflowed_delay_end-delay.js]
skip-if = debug #bug 1480027

View File

@ -131,7 +131,7 @@ class FlexItemSizingProperties extends PureComponent {
);
}
renderFlexibilitySection(flexItemSizing, properties) {
renderFlexibilitySection(flexItemSizing, properties, computedStyle) {
const {
mainDeltaSize,
mainBaseSize,
@ -140,40 +140,37 @@ class FlexItemSizingProperties extends PureComponent {
clampState,
} = flexItemSizing;
// Don't attempt to display anything useful if everything is 0.
// Don't display anything if all interesting sizes are 0.
if (!mainFinalSize && !mainBaseSize && !mainDeltaSize) {
return null;
}
const flexGrow = properties["flex-grow"];
const nonZeroFlexGrowDefined = flexGrow && parseFloat(flexGrow) !== 0;
const flexShrink = properties["flex-shrink"];
const flexShrink0 = parseFloat(flexShrink) === 0;
// Also don't display anything if the item did not grow or shrink.
const grew = mainDeltaSize > 0;
const shrank = mainDeltaSize < 0;
if (!grew && !shrank) {
return null;
}
const definedFlexGrow = properties["flex-grow"];
const computedFlexGrow = computedStyle.flexGrow;
const definedFlexShrink = properties["flex-shrink"];
const computedFlexShrink = computedStyle.flexShrink;
const wasClamped = clampState !== "unclamped";
const reasons = [];
// First output a sentence for telling users about whether there was enough room or
// not on the line.
if (lineGrowthState === "growing") {
reasons.push(getStr("flexbox.itemSizing.extraRoomOnLine"));
} else if (lineGrowthState === "shrinking") {
reasons.push(getStr("flexbox.itemSizing.notEnoughRoomOnLine"));
}
// Then tell users whether the item was set to grow, shrink or none of them.
if (nonZeroFlexGrowDefined && lineGrowthState !== "shrinking") {
// Tell users whether the item was set to grow or shrink.
if (computedFlexGrow && lineGrowthState === "growing") {
reasons.push(getStr("flexbox.itemSizing.setToGrow"));
}
if (flexShrink && !flexShrink0 && lineGrowthState !== "growing") {
if (computedFlexShrink && lineGrowthState === "shrinking") {
reasons.push(getStr("flexbox.itemSizing.setToShrink"));
}
if (!nonZeroFlexGrowDefined && !grew && !shrank && lineGrowthState === "growing") {
if (!computedFlexGrow && !grew && !shrank && lineGrowthState === "growing") {
reasons.push(getStr("flexbox.itemSizing.notSetToGrow"));
}
if (!grew && !shrank && lineGrowthState === "shrinking") {
if (!computedFlexShrink && !grew && !shrank && lineGrowthState === "shrinking") {
reasons.push(getStr("flexbox.itemSizing.notSetToShrink"));
}
@ -181,23 +178,26 @@ class FlexItemSizingProperties extends PureComponent {
if (grew) {
// If the item grew.
if (flexGrow) {
if (definedFlexGrow) {
// It's normally because it was set to grow (flex-grow is non 0).
property = this.renderCssProperty("flex-grow", flexGrow);
property = this.renderCssProperty("flex-grow", definedFlexGrow);
}
if (wasClamped) {
if (wasClamped && clampState === "clamped_to_max") {
// It may have wanted to grow more than it did, because it was later max-clamped.
reasons.push(getStr("flexbox.itemSizing.growthAttemptWhenClamped"));
reasons.push(getStr("flexbox.itemSizing.growthAttemptButMaxClamped"));
} else if (wasClamped && clampState === "clamped_to_min") {
// Or it may have wanted to grow less, but was later min-clamped to a larger size.
reasons.push(getStr("flexbox.itemSizing.growthAttemptButMinClamped"));
}
} else if (shrank) {
// If the item shrank.
if (flexShrink && !flexShrink0) {
if (definedFlexShrink && computedFlexShrink) {
// It's either because flex-shrink is non 0.
property = this.renderCssProperty("flex-shrink", flexShrink);
} else {
property = this.renderCssProperty("flex-shrink", definedFlexShrink);
} else if (computedFlexShrink) {
// Or also because it's default value is 1 anyway.
property = this.renderCssProperty("flex-shrink", "1", true);
property = this.renderCssProperty("flex-shrink", computedFlexShrink, true);
}
if (wasClamped) {
@ -205,34 +205,6 @@ class FlexItemSizingProperties extends PureComponent {
// because it was later min-clamped.
reasons.push(getStr("flexbox.itemSizing.shrinkAttemptWhenClamped"));
}
} else if (lineGrowthState === "growing" && nonZeroFlexGrowDefined) {
property = this.renderCssProperty("flex-grow", flexGrow);
if (!wasClamped) {
// The item did not grow or shrink. There was room on the line and flex-grow was
// set, other items have likely used up all of the space.
reasons.push(getStr("flexbox.itemSizing.growthAttemptButSiblings"));
}
} else if (lineGrowthState === "shrinking") {
// The item did not grow or shrink and there wasn't enough room on the line.
if (!flexShrink0) {
// flex-shrink was set (either defined in CSS, or via its default value of 1).
// but the item didn't shrink.
if (flexShrink) {
property = this.renderCssProperty("flex-shrink", flexShrink);
} else {
property = this.renderCssProperty("flex-shrink", 1, true);
}
reasons.push(getStr("flexbox.itemSizing.shrinkAttemptButCouldnt"));
if (wasClamped) {
// Maybe it was clamped.
reasons.push(getStr("flexbox.itemSizing.shrinkAttemptWhenClamped"));
}
} else {
// flex-shrink was set to 0, so it didn't shrink.
property = this.renderCssProperty("flex-shrink", flexShrink);
}
}
// Don't display the section at all if there's nothing useful to show users.
@ -316,6 +288,7 @@ class FlexItemSizingProperties extends PureComponent {
flexItem,
} = this.props;
const {
computedStyle,
flexItemSizing,
properties,
} = flexItem;
@ -336,7 +309,7 @@ class FlexItemSizingProperties extends PureComponent {
return (
dom.ul({ className: "flex-item-sizing" },
this.renderBaseSizeSection(flexItemSizing, properties, dimension),
this.renderFlexibilitySection(flexItemSizing, properties),
this.renderFlexibilitySection(flexItemSizing, properties, computedStyle),
this.renderMinimumSizeSection(flexItemSizing, properties, dimension),
this.renderMaximumSizeSection(flexItemSizing, properties, dimension),
this.renderFinalSizeSection(flexItemSizing)

View File

@ -192,6 +192,7 @@ class FlexboxInspector {
flexItems.push({
actorID: flexItemFront.actorID,
computedStyle: flexItemFront.computedStyle,
flexItemSizing: flexItemFront.flexItemSizing,
nodeFront: itemNodeFront,
properties: flexItemFront.properties,

View File

@ -21,11 +21,10 @@ support-files =
[browser_flexbox_item_outline_hidden_when_useless.js]
[browser_flexbox_item_outline_rotates_for_column.js]
[browser_flexbox_pseudo_elements_are_listed.js]
[browser_flexbox_sizing_grow_and_not_grow.js]
[browser_flexbox_sizing_flexibility_not_displayed_when_useless.js]
[browser_flexbox_sizing_info_exists.js]
[browser_flexbox_sizing_info_for_pseudos.js]
[browser_flexbox_sizing_info_for_text_nodes.js]
[browser_flexbox_sizing_info_has_correct_sections.js]
[browser_flexbox_sizing_unrelated_to_siblings_when_clamped.js]
[browser_flexbox_sizing_wanted_to_grow_but_was_clamped.js]
[browser_flexbox_text_nodes_are_listed.js]

View File

@ -0,0 +1,32 @@
/* vim: set ts=2 et sw=2 tw=80: */
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
// Test that the flexibility section in the flex item sizing properties is not displayed
// when the item did not grow or shrink.
const TEST_URI = URL_ROOT + "doc_flexbox_specific_cases.html";
add_task(async function() {
await addTab(TEST_URI);
const { inspector, flexboxInspector } = await openLayoutView();
const { document: doc } = flexboxInspector;
info("Select an item with flex:0 and wait for the sizing info to be rendered");
let onFlexItemSizingRendered = waitForDOM(doc, "ul.flex-item-sizing");
await selectNode("#did-not-grow-or-shrink div", inspector);
let [flexSizingContainer] = await onFlexItemSizingRendered;
let flexSections = flexSizingContainer.querySelectorAll(".section.flexibility");
is(flexSections.length, 0, "The flexibility section was not found in the DOM");
info("Select a more complex item which also doesn't flex and wait for the sizing info");
onFlexItemSizingRendered = waitForDOM(doc, "ul.flex-item-sizing");
await selectNode("#just-enough-space-for-clamped-items div:last-child", inspector);
([flexSizingContainer] = await onFlexItemSizingRendered);
flexSections = flexSizingContainer.querySelectorAll(".section.flexibility");
is(flexSections.length, 0, "The flexibility section was not found in the DOM");
});

View File

@ -1,33 +0,0 @@
/* vim: set ts=2 et sw=2 tw=80: */
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
const { getStr } = require("devtools/client/inspector/layout/utils/l10n");
// Non-regression for bug 1501207.
// In this bug, an item that was set to grow, with a flex-basis larger than its max-width
// was marked both as "set to grow" and "not set to grow" at the same time.
// So this test checks that this does not happen anymore.
const TEST_URI = URL_ROOT + "doc_flexbox_specific_cases.html";
add_task(async function() {
await addTab(TEST_URI);
const { inspector, flexboxInspector } = await openLayoutView();
const { document: doc } = flexboxInspector;
info("Select the test item in the document and wait for the sizing info to render");
const onFlexibilityReasonsRendered = waitForDOM(doc,
"ul.flex-item-sizing .section.flexibility .reasons");
await selectNode("#grow-not-grow div:first-child", inspector);
const [reasonsList] = await onFlexibilityReasonsRendered;
info("Get the list of reasons in the flexibility section");
const [...reasons] = reasonsList.querySelectorAll("li");
ok(reasons.some(r => r.textContent === getStr("flexbox.itemSizing.setToGrow")),
"The 'set to grow' reason was found");
ok(reasons.every(r => r.textContent !== getStr("flexbox.itemSizing.notSetToGrow")),
"The 'not set to grow' reason was not found");
});

View File

@ -1,33 +0,0 @@
/* vim: set ts=2 et sw=2 tw=80: */
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
const { getStr } = require("devtools/client/inspector/layout/utils/l10n");
// Non-regression for bug 1501263.
// In this bug, an item that was set to grow, with a max-width, and growing siblings
// was marked as "couldn't grow because siblings have used the extra space". This was
// wrong because the item was only being clamped by its max-width.
// This test prevents this from happening again.
const TEST_URI = URL_ROOT + "doc_flexbox_specific_cases.html";
add_task(async function() {
await addTab(TEST_URI);
const { inspector, flexboxInspector } = await openLayoutView();
const { document: doc } = flexboxInspector;
info("Select the test item in the document and wait for the sizing info to render");
const onFlexibilityReasonsRendered = waitForDOM(doc,
"ul.flex-item-sizing .section.flexibility .reasons");
await selectNode("#grow-not-grow div:first-child", inspector);
const [reasonsList] = await onFlexibilityReasonsRendered;
info("Get the list of reasons in the flexibility section");
const [...reasons] = reasonsList.querySelectorAll("li");
const str = getStr("flexbox.itemSizing.growthAttemptButSiblings");
ok(reasons.every(r => r.textContent !== str),
"The 'could not grow because of siblings' reason was not found");
});

View File

@ -29,7 +29,7 @@ add_task(async function() {
info("Check that the flexibility sizing section displays the right info");
const reasons = [...sizingContainer.querySelectorAll(".reasons li")];
const expectedReason = getStr("flexbox.itemSizing.growthAttemptWhenClamped");
const expectedReason = getStr("flexbox.itemSizing.growthAttemptButMaxClamped");
ok(reasons.some(r => r.textContent === expectedReason),
"The 'wanted to grow but was clamped' reason was found");
});

View File

@ -1,20 +1,6 @@
<!DOCTYPE html>
<meta charset="utf-8">
<style>
#grow-not-grow {
display:flex;
width:500px;
border:1px solid;
}
#grow-not-grow div:first-child {
flex-grow:1;
flex-basis:100px;
max-width:50px;
}
#grow-not-grow div:last-child {
flex-grow: 1;
}
#want-to-grow-more-than-max {
width: 500px;
display: flex;
@ -23,11 +9,38 @@
flex: 1;
max-width: 200px;
}
#did-not-grow-or-shrink {
width: 500px;
display: flex;
}
#did-not-grow-or-shrink div {
flex: 0 300px;
}
#just-enough-space-for-clamped-items {
display:flex;
width:100px;
height:40px
}
#just-enough-space-for-clamped-items div:first-child {
flex: 1 300px;
max-width: 20px;
background: teal;
}
#just-enough-space-for-clamped-items div:last-child {
flex: 1 10px;
min-width: 80px;
background: salmon;
}
</style>
<div id="grow-not-grow">
<div>item 1</div>
<div>item 2</div>
</div>
<div id="want-to-grow-more-than-max">
<div>item wants to grow more</div>
</div>
<div id="did-not-grow-or-shrink">
<div>item did not grow or shrink</div>
</div>
<div id="just-enough-space-for-clamped-items">
<div></div>
<div></div>
</div>

View File

@ -72,13 +72,16 @@ const flexItem = exports.flexItem = {
// The actor ID of the flex item.
actorID: PropTypes.string,
// The computed style properties of the flex item.
computedStyle: PropTypes.object,
// The flex item sizing data.
flexItemSizing: PropTypes.shape(flexItemSizing),
// The NodeFront of the flex item.
nodeFront: PropTypes.object,
// The computed style properties of the flex item.
// The authored style properties of the flex item.
properties: PropTypes.shape(flexItemProperties),
};

View File

@ -278,7 +278,7 @@ Inspector.prototype = {
// the ChangesActor. We want the ChangesActor to be guaranteed available before
// the user makes any changes.
this.changesFront = this.toolbox.target.getFront("changes");
this.changesFront.allChanges();
this.changesFront.start();
}
// Setup the splitter before the sidebar is displayed so, we don't miss any events.

View File

@ -62,39 +62,27 @@ flexbox.itemSizing.itemBaseSizeFromContent=The items content size when uncons
# its min-content size.
flexbox.itemSizing.itemMinSizeFromItemMinContent=This is the elements minimum content size.
# LOCALIZATION NOTE (flexbox.itemSizing.extraRoomOnLine): Label shown in the flexbox item
# sizing panel. It tells users that there was extra room to distribute inside a given flex
# line.
flexbox.itemSizing.extraRoomOnLine=There was extra room available on the flex line.
# LOCALIZATION NOTE (flexbox.itemSizing.notEnoughRoomOnLine): Label shown in the flexbox
# item sizing panel. It tells users that there wasnt enough room inside a given flex line
# for all of its items.
flexbox.itemSizing.notEnoughRoomOnLine=There wasnt enough room available on the flex line.
# LOCALIZATION NOTE (flexbox.itemSizing.growthAttemptWhenClamped): Label shown in the
# LOCALIZATION NOTE (flexbox.itemSizing.growthAttemptButMaxClamped): Label shown in the
# flexbox item sizing panel. It tells users that a given item attempted to grow by a
# certain amount but ended up being clamped by a max size.
# (note that clamp is a common word in flexbox terminology. It refers to constraining an
# certain amount but ended up being clamped to a smaller max size.
# (Note that clamp is a common word in flexbox terminology. It refers to constraining an
# item's size to some defined min/max-width/height set on the element, even though there
# might have been room for it to grow, or reason for it to shrink more).
flexbox.itemSizing.growthAttemptWhenClamped=The item wanted to grow, but it was clamped.
flexbox.itemSizing.growthAttemptButMaxClamped=The item wanted to grow more, but it was clamped to its maximum size.
# LOCALIZATION NOTE (flexbox.itemSizing.growthAttemptButMinClamped): Label shown in the
# flexbox item sizing panel. It tells users that a given item attempted to grow by a
# certain amount but ended up being clamped to a larger min size.
# (Note that clamp is a common word in flexbox terminology. It refers to constraining an
# item's size to some defined min/max-width/height set on the element, even though there
# might have been room for it to grow, or reason for it to shrink more).
flexbox.itemSizing.growthAttemptButMinClamped=The item wanted to grow less, but it was clamped to its minimum size.
# LOCALIZATION NOTE (flexbox.itemSizing.shrinkAttemptWhenClamped): Label shown in the
# flexbox item sizing panel. It tells users that a given item attempted to shrink by a
# certain amount but ended up being clamped by a min size.
flexbox.itemSizing.shrinkAttemptWhenClamped=The item wanted to shrink, but it was clamped.
# LOCALIZATION NOTE (flexbox.itemSizing.shrinkAttemptButCouldnt): Label shown in the
# flexbox item sizing panel. It tells users that a given item attempted to shrink by a
# certain amount but could not
flexbox.itemSizing.shrinkAttemptButCouldnt=Item was set to shrink but could not.
# LOCALIZATION NOTE (flexbox.itemSizing.growthAttemptButSiblings): Label shown in the
# flexbox item sizing panel. It tells users that a given item could not grow to occupy
# extra space because its siblings have likely already used it.
flexbox.itemSizing.growthAttemptButSiblings=Item could not grow, siblings have likely used the extra space.
# LOCALIZATION NOTE (flexbox.itemSizing.setToGrow): Label shown in the flex item sizing
# panel. It tells users that a given item was set to grow.
flexbox.itemSizing.setToGrow=Item was set to grow.

View File

@ -37,6 +37,15 @@ const ChangesActor = protocol.ActorClassWithSpec(changesSpec, {
protocol.Actor.prototype.destroy.call(this);
},
start: function() {
/**
* This function currently does nothing and returns nothing. It exists only
* so that the client can trigger the creation of the ChangesActor through
* the front, without triggering side effects, and with a sensible semantic
* meaning.
*/
},
changeCount: function() {
return this.changes.length;
},
@ -51,23 +60,36 @@ const ChangesActor = protocol.ActorClassWithSpec(changesSpec, {
},
allChanges: function() {
/**
* This function is called by all change event consumers on the client
* to get their initial state synchronized with the ChangesActor. We
* set a flag when this function is called so we know that it's worthwhile
* to send events.
*/
this._changesHaveBeenRequested = true;
return this.changes.slice();
},
pushChange: function(change) {
this.changes.push(change);
this.emit("add-change", change);
if (this._changesHaveBeenRequested) {
this.emit("add-change", change);
}
},
popChange: function() {
const change = this.changes.pop();
this.emit("remove-change", change);
if (this._changesHaveBeenRequested) {
this.emit("remove-change", change);
}
return change;
},
clearChanges: function() {
this.changes.length = 0;
this.emit("clear-changes");
if (this._changesHaveBeenRequested) {
this.emit("clear-changes");
}
},
});

View File

@ -168,7 +168,9 @@ const FlexItemActor = ActorClassWithSpec(flexItemSpec, {
[dimension]: "",
};
if (this.element.nodeType === this.element.ELEMENT_NODE) {
const isElementNode = this.element.nodeType === this.element.ELEMENT_NODE;
if (isElementNode) {
for (const name in properties) {
let value = "";
// Look first on the element style.
@ -192,12 +194,20 @@ const FlexItemActor = ActorClassWithSpec(flexItemSpec, {
}
}
// Also find some computed sizing properties that will be useful for this item.
const { flexGrow, flexShrink } = isElementNode
? CssLogic.getComputedStyle(this.element)
: { flexGrow: null, flexShrink: null };
const computedStyle = { flexGrow, flexShrink };
const form = {
actor: this.actorID,
// The flex item sizing data.
flexItemSizing: this.flexItemSizing,
// The authored style properties of the flex item.
properties,
// The computed style properties of the flex item.
computedStyle,
};
// If the WalkerActor already knows the flex item element, then also return its

View File

@ -174,9 +174,10 @@ webExtensionTargetPrototype._createFallbackWindow = function() {
webExtensionTargetPrototype._destroyFallbackWindow = function() {
if (this.fallbackWebNav) {
const systemPrincipal = Services.scriptSecurityManager.getSystemPrincipal();
// Explicitly close the fallback windowless browser to prevent it to leak
// (and to prevent it to freeze devtools xpcshell tests).
this.fallbackWebNav.loadURI("about:blank", 0, null, null, null);
this.fallbackWebNav.loadURI("about:blank", 0, null, null, null, systemPrincipal);
this.fallbackWebNav.close();
this.fallbackWebNav = null;

View File

@ -69,6 +69,13 @@ const FlexItemFront = FrontClassWithSpec(flexItemSpec, {
return this.conn.getActor(this._form.nodeActorID);
},
/**
* Get the computed style properties for the flex item.
*/
get computedStyle() {
return this._form.computedStyle;
},
/**
* Get the style properties for the flex item.
*/

View File

@ -33,6 +33,7 @@ const changesSpec = generateActorSpec({
changes: RetVal("array:json"),
},
},
"start": {}, // no arguments, no response
},
});

View File

@ -4080,6 +4080,9 @@ nsDocShell::LoadURI(const nsAString& aURI,
nsIInputStream* aHeaderStream,
nsIPrincipal* aTriggeringPrincipal)
{
#ifndef ANDROID
MOZ_ASSERT(aTriggeringPrincipal, "LoadURI: Need a valid triggeringPrincipal");
#endif
return LoadURIWithOptions(aURI, aLoadFlags, aReferringURI,
RP_Unset, aPostStream,
aHeaderStream, nullptr, aTriggeringPrincipal);
@ -4115,6 +4118,11 @@ nsDocShell::LoadURIWithOptions(const nsAString& aURI,
uriString.StripCRLF();
NS_ENSURE_TRUE(!uriString.IsEmpty(), NS_ERROR_FAILURE);
#ifndef ANDROID
MOZ_ASSERT(aTriggeringPrincipal, "LoadURIWithOptions: Need a valid triggeringPrincipal");
#endif
rv = NS_NewURI(getter_AddRefs(uri), uriString);
if (uri) {
aLoadFlags &= ~LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP;
@ -9010,6 +9018,9 @@ public:
NS_IMETHOD
Run() override
{
#ifndef ANDROID
MOZ_ASSERT(mTriggeringPrincipal, "InternalLoadEvent: Should always have a principal here");
#endif
return mDocShell->InternalLoad(mURI, mOriginalURI, mResultPrincipalURI,
mKeepResultPrincipalURIIfSet,
mLoadReplace,
@ -13086,6 +13097,9 @@ nsDocShell::OnLinkClick(nsIContent* aContent,
bool aIsTrusted,
nsIPrincipal* aTriggeringPrincipal)
{
#ifndef ANDROID
MOZ_ASSERT(aTriggeringPrincipal, "Need a valid triggeringPrincipal");
#endif
NS_ASSERTION(NS_IsMainThread(), "wrong thread");
if (!IsNavigationAllowed() || !IsOKToLoadURI(aURI)) {

View File

@ -495,6 +495,9 @@ nsDocShellLoadState::SetupTriggeringPrincipal(const mozilla::OriginAttributes& a
return NS_ERROR_FAILURE;
}
} else {
#ifndef ANDROID
MOZ_ASSERT(false, "LoadURI: System principal required.");
#endif
mTriggeringPrincipal = nsContentUtils::GetSystemPrincipal();
}
}

View File

@ -978,6 +978,9 @@ nsDocShellTreeOwner::HandleEvent(Event* aEvent)
nsAutoString url;
if (NS_SUCCEEDED(links[0]->GetUrl(url))) {
if (!url.IsEmpty()) {
#ifndef ANDROID
MOZ_ASSERT(triggeringPrincipal, "nsDocShellTreeOwner::HandleEvent: Need a valid triggeringPrincipal");
#endif
webnav->LoadURI(url, 0, nullptr, nullptr, nullptr,
triggeringPrincipal);
}

View File

@ -34,7 +34,8 @@ add_task(async function() {
equal(loadContext.usePrivateBrowsing, false,
"Should be able to change origin attributes prior to a document load");
webNav.loadURI("data:text/html,", webNav.LOAD_FLAGS_NONE, null, null, null);
let systemPrincipal = Services.scriptSecurityManager.getSystemPrincipal();
webNav.loadURI("data:text/html,", webNav.LOAD_FLAGS_NONE, null, null, null, systemPrincipal);
// Return to the event loop so the load can begin.
await new Promise(executeSoon);

View File

@ -8,6 +8,7 @@
#define mozilla_dom_MessageBroadcaster_h
#include "mozilla/dom/MessageListenerManager.h"
#include "nsContentUtils.h"
namespace mozilla {
namespace dom {

View File

@ -2418,7 +2418,7 @@ nsIDocument::MaybeDowngradePrincipal(nsIPrincipal* aPrincipal)
"an expanded principal");
auto* expanded = basePrin->As<ExpandedPrincipal>();
return do_AddRef(expanded->WhiteList().LastElement());
return do_AddRef(expanded->AllowList().LastElement());
}
if (nsContentUtils::IsSystemPrincipal(aPrincipal)) {

View File

@ -33,9 +33,10 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=430050
if (evt.target == evt.currentTarget) {
document.getElementById('b').setAttribute("src",
"data:text/plain,failed");
document.getElementById('b').loadURI('data:text/plain,succeeded',
null,
'UTF-8');
const systemPrincipal = Services.scriptSecurityManager.getSystemPrincipal();
document.getElementById('b').loadURI('data:text/plain,succeeded', {
triggeringPrincipal: systemPrincipal
});
document.getElementById('b').addEventListener("load", endTest);
}
}, true);

View File

@ -83,9 +83,9 @@ windows.
ok(nonRemote && !nonRemote.isRemoteBrowser,
"Should have found a non-remote browser in test window " + num);
remote.loadURI(page);
BrowserTestUtils.loadURI(remote, page);
await BrowserTestUtils.browserLoaded(remote);
nonRemote.loadURI(page);
BrowserTestUtils.loadURI(nonRemote, page);
await BrowserTestUtils.browserLoaded(nonRemote);
let result = {};

View File

@ -9,13 +9,18 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=713980
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
<!-- Load a cross-origin webfont without CORS (common pain point -->
<!-- Load a cross-origin webfont without CORS (common pain point) and some
other styles that require anonymous CORS -->
<style>
@font-face {
font-family: "bad_cross_origin_webfont";
src: url('http://example.org/tests/dom/security/test/csp/file_CSP.sjs?testid=font_bad&type=application/octet-stream');
}
div#bad_webfont { font-family: "bad_cross_origin_webfont"; }
div#bad_shape_outside { shape-outside: url('http://example.org/tests/dom/security/test/csp/file_CSP.sjs?testid=bad_shape_outside&type=image/png'); }
div#bad_mask_image { mask-image: url('http://example.org/tests/dom/security/test/csp/file_CSP.sjs?testid=bad_mask_image&type=image/svg+xml'); }
</style>
</head>
<body>
@ -25,23 +30,37 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=713980
SimpleTest.waitForExplicitFinish();
var tests = {
xhr : {
uri_test : "http://invalid",
result : null,
category: "CORSAllowOriginNotMatchingOrigin"
},
font : {
uri_test : "font_bad",
result : null,
category: "CORSMissingAllowOrigin",
},
xhr : {
uri_test : "http://invalid",
shape_outside : {
uri_test : "bad_shape_outside",
result : null,
category: "CORSAllowOriginNotMatchingOrigin"
category: "CORSMissingAllowOrigin",
ignore_windowID: true,
},
mask_image : {
uri_test : "bad_mask_image",
result : null,
category: "CORSMissingAllowOrigin",
ignore_windowID: true,
},
}
function testsComplete() {
for (var testName in tests) {
var test = tests[testName];
if (test.result == null)
if (test.result == null) {
info("Still waiting on (at least) " + testName + ".");
return false;
}
}
return true;
}
@ -63,7 +82,9 @@ SpecialPowers.registerConsoleListener(function CORSMsgListener(aMsg) {
ok(aMsg.category == category,
"Got warning message with category \"" + aMsg.category + "\", expected \"" + category + "\"");
// Got the message we wanted - make sure it is destined for a valid inner window
ok(aMsg.windowID != 0, "Valid (non-zero) windowID for the cross-site request blocked message.");
if(!test.ignore_windowID) {
ok(aMsg.windowID != 0, "Valid (non-zero) windowID for the cross-site request blocked message.");
}
break;
}
}
@ -83,12 +104,24 @@ var xhr = new XMLHttpRequest();
xhr.open("GET", "http://example.org/tests/dom/security/test/cors/file_CrossSiteXHR_server.sjs?allowOrigin=http://invalid", true);
xhr.send(null);
let badDiv;
// Create a div that triggers a cross-origin webfont request
// We do this in Javascript in order to guarantee the console listener has
// already been registered; otherwise, there could be a race.
var badDiv = document.createElement('div');
badDiv = document.createElement('div');
badDiv.setAttribute('id', 'bad_webfont');
document.body.appendChild(badDiv);
// Create a div that triggers a cross-origin request for a shape-outside image
badDiv = document.createElement('div');
badDiv.setAttribute('id', 'bad_shape_outside');
document.body.appendChild(badDiv);
// Create a div that triggers a cross-origin request for a mask-image
badDiv = document.createElement('div');
badDiv.setAttribute('id', 'bad_mask_image');
document.body.appendChild(badDiv);
</script>
</pre>

View File

@ -15,7 +15,7 @@ namespace dom {
// Natives for DOM classes that aren't refcounted need to inherit from this
// class.
// If you're seeing objects of this class leak then natives for one of the DOM
// classes inheriting from it is leaking. If the native for that class has
// classes inheriting from it are leaking. If the native for that class has
// MOZ_COUNT_CTOR/DTOR in its constructor/destructor then it should show up in
// the leak log too.
class NonRefcountedDOMObject
@ -25,10 +25,21 @@ protected:
{
MOZ_COUNT_CTOR(NonRefcountedDOMObject);
}
~NonRefcountedDOMObject()
{
MOZ_COUNT_DTOR(NonRefcountedDOMObject);
}
NonRefcountedDOMObject(const NonRefcountedDOMObject& aOther)
: NonRefcountedDOMObject()
{}
NonRefcountedDOMObject& operator=(const NonRefcountedDOMObject& aOther)
{
NonRefcountedDOMObject();
return *this;
}
};
} // namespace dom

View File

@ -1593,7 +1593,7 @@ StartMacOSContentSandbox()
info.hasWindowServer = !Preferences::GetBool(
"security.sandbox.content.mac.disconnect-windowserver");
// These paths are used to whitelist certain directories used by the testing
// These paths are used to allowlist certain directories used by the testing
// system. They should not be considered a public API, and are only intended
// for use in automation.
nsAutoCString testingReadPath1;
@ -2956,17 +2956,17 @@ ContentChild::RecvDomainSetChanged(const uint32_t& aSetType,
nsCOMPtr<nsIDomainSet> set;
switch(aSetType) {
case BLACKLIST:
mPolicy->GetBlacklist(getter_AddRefs(set));
case BLOCKLIST:
mPolicy->GetBlocklist(getter_AddRefs(set));
break;
case SUPER_BLACKLIST:
mPolicy->GetSuperBlacklist(getter_AddRefs(set));
case SUPER_BLOCKLIST:
mPolicy->GetSuperBlocklist(getter_AddRefs(set));
break;
case WHITELIST:
mPolicy->GetWhitelist(getter_AddRefs(set));
case ALLOWLIST:
mPolicy->GetAllowlist(getter_AddRefs(set));
break;
case SUPER_WHITELIST:
mPolicy->GetSuperWhitelist(getter_AddRefs(set));
case SUPER_ALLOWLIST:
mPolicy->GetSuperAllowlist(getter_AddRefs(set));
break;
default:
MOZ_ASSERT_UNREACHABLE("Unexpected setType");

View File

@ -194,10 +194,10 @@ union FileDescOrError {
struct DomainPolicyClone
{
bool active;
URIParams[] blacklist;
URIParams[] whitelist;
URIParams[] superBlacklist;
URIParams[] superWhitelist;
URIParams[] blocklist;
URIParams[] allowlist;
URIParams[] superBlocklist;
URIParams[] superAllowlist;
};
struct AndroidSystemInfo

View File

@ -109,20 +109,20 @@ async function test_domainPolicy() {
}
}
info("Testing simple blacklist policy");
info("Testing simple blocklist policy");
info("Creating child process first, activating domainPolicy after");
currentTask = initProcess();
await currentTask;
activateDomainPolicy();
var bl = policy.blacklist;
var bl = policy.blocklist;
bl.add(Services.io.newURI('http://example.com'));
currentTask = runTest(testDomain("http://example.com"));
checkAndCleanup(await currentTask);
info("Activating domainPolicy first, creating child process after");
activateDomainPolicy();
var bl = policy.blacklist;
var bl = policy.blocklist;
bl.add(Services.io.newURI('http://example.com'));
currentTask = initProcess();
await currentTask;
@ -169,40 +169,40 @@ async function test_domainPolicy() {
'https://example.com', 'http://test1.example.org'],
};
function activate(isBlack, exceptions, superExceptions) {
function activate(isBlock, exceptions, superExceptions) {
activateDomainPolicy();
let set = isBlack ? policy.blacklist : policy.whitelist;
let superSet = isBlack ? policy.superBlacklist : policy.superWhitelist;
for (var e of exceptions)
set.add(makeURI(e));
for (var e of superExceptions)
superSet.add(makeURI(e));
};
let set = isBlock ? policy.blocklist : policy.allowlist;
let superSet = isBlock ? policy.superBlocklist : policy.superAllowlist;
for (var e of exceptions)
set.add(makeURI(e));
for (var e of superExceptions)
superSet.add(makeURI(e));
};
info("Testing Blacklist-style Domain Policy");
info("Activating domainPolicy first, creating child process after");
activate(true, testPolicy.exceptions, testPolicy.superExceptions);
currentTask = initProcess();
await currentTask;
let results = [];
currentTask = runTest(testList(true, testPolicy.notExempt));
results = results.concat(await currentTask);
currentTask = runTest(testList(false, testPolicy.exempt));
results = results.concat(await currentTask);
checkAndCleanup(results);
info("Testing Blocklist-style Domain Policy");
info("Activating domainPolicy first, creating child process after");
activate(true, testPolicy.exceptions, testPolicy.superExceptions);
currentTask = initProcess();
await currentTask;
let results = [];
currentTask = runTest(testList(true, testPolicy.notExempt));
results = results.concat(await currentTask);
currentTask = runTest(testList(false, testPolicy.exempt));
results = results.concat(await currentTask);
checkAndCleanup(results);
info("Creating child process first, activating domainPolicy after");
currentTask = initProcess();
await currentTask;
activate(true, testPolicy.exceptions, testPolicy.superExceptions);
results = [];
currentTask = runTest(testList(true, testPolicy.notExempt));
results = results.concat(await currentTask);
currentTask = runTest(testList(false, testPolicy.exempt));
results = results.concat(await currentTask);
checkAndCleanup(results);
info("Creating child process first, activating domainPolicy after");
currentTask = initProcess();
await currentTask;
activate(true, testPolicy.exceptions, testPolicy.superExceptions);
results = [];
currentTask = runTest(testList(true, testPolicy.notExempt));
results = results.concat(await currentTask);
currentTask = runTest(testList(false, testPolicy.exempt));
results = results.concat(await currentTask);
checkAndCleanup(results);
info("Testing Whitelist-style Domain Policy");
info("Testing Allowlist-style Domain Policy");
deferred = Promise.defer();
currentTask = deferred.promise;
SpecialPowers.pushPrefEnv({set:[["javascript.enabled", false]]}, () => { return deferred.resolve()});

View File

@ -38,8 +38,6 @@
#define PREF_CUBEB_OUTPUT_DEVICE "media.cubeb.output_device"
#define PREF_CUBEB_LATENCY_PLAYBACK "media.cubeb_latency_playback_ms"
#define PREF_CUBEB_LATENCY_MSG "media.cubeb_latency_msg_frames"
// This only works when audio remoting is active, and pulseaudio is the backend.
#define PREF_CUBEB_MAX_INPUT_STREAMS "media.cubeb_max_input_streams"
// Allows to get something non-default for the preferred sample-rate, to allow
// troubleshooting in the field and testing.
#define PREF_CUBEB_FORCE_SAMPLE_RATE "media.cubeb.force_sample_rate"
@ -131,9 +129,6 @@ cubeb* sCubebContext;
double sVolumeScale = 1.0;
uint32_t sCubebPlaybackLatencyInMilliseconds = 100;
uint32_t sCubebMSGLatencyInFrames = 512;
// Maximum number of audio input streams that can be open at once. This pref is
// only used when remoting is on, and we're using PulseAudio as a backend.
uint32_t sCubebMaxInputStreams = 1;
// If sCubebForcedSampleRate is zero, PreferredSampleRate will return the
// preferred sample-rate for the audio backend in use. Otherwise, it will be
// used as the preferred sample-rate.
@ -238,9 +233,6 @@ void PrefChanged(const char* aPref, void* aClosure)
// We don't want to limit the upper limit too much, so that people can
// experiment.
sCubebMSGLatencyInFrames = std::min<uint32_t>(std::max<uint32_t>(value, 128), 1e6);
} else if (strcmp(aPref, PREF_CUBEB_MAX_INPUT_STREAMS) == 0) {
StaticMutexAutoLock lock(sMutex);
sCubebMaxInputStreams = Preferences::GetUint(aPref);
} else if (strcmp(aPref, PREF_CUBEB_FORCE_SAMPLE_RATE) == 0) {
StaticMutexAutoLock lock(sMutex);
sCubebForcedSampleRate = Preferences::GetUint(aPref);
@ -571,19 +563,12 @@ uint32_t GetCubebMSGLatencyInFrames(cubeb_stream_params * params)
#endif
}
uint32_t GetMaxInputStreams()
{
StaticMutexAutoLock lock(sMutex);
return sCubebMaxInputStreams;
}
static const char* gInitCallbackPrefs[] = {
PREF_VOLUME_SCALE, PREF_CUBEB_OUTPUT_DEVICE,
PREF_CUBEB_LATENCY_PLAYBACK, PREF_CUBEB_LATENCY_MSG,
PREF_CUBEB_BACKEND, PREF_CUBEB_FORCE_NULL_CONTEXT,
PREF_CUBEB_SANDBOX, PREF_AUDIOIPC_POOL_SIZE,
PREF_CUBEB_MAX_INPUT_STREAMS, PREF_AUDIOIPC_STACK_SIZE,
nullptr,
PREF_AUDIOIPC_STACK_SIZE, nullptr,
};
static const char* gCallbackPrefs[] = {
PREF_CUBEB_FORCE_SAMPLE_RATE,

View File

@ -50,7 +50,6 @@ void GetDeviceCollection(nsTArray<RefPtr<AudioDeviceInfo>>& aDeviceInfos,
Side aSide);
cubeb_stream_prefs GetDefaultStreamPrefs();
char* GetForcedOutputDevice();
uint32_t GetMaxInputStreams();
#ifdef MOZ_WIDGET_ANDROID
uint32_t AndroidGetAudioOutputSampleRate();

View File

@ -1882,11 +1882,20 @@ class PeerConnectionObserver {
}
onStateChange(state) {
switch (state) {
case "SignalingState":
this.dispatchEvent(new this._win.Event("signalingstatechange"));
break;
if (!this._dompc) {
return;
}
if (state == "SignalingState") {
this.dispatchEvent(new this._win.Event("signalingstatechange"));
return;
}
if (!this._dompc._pc) {
return;
}
switch (state) {
case "IceConnectionState":
let connState = this._dompc._pc.iceConnectionState;
this._dompc._queueTaskWithClosedCheck(() => {

View File

@ -139,9 +139,9 @@ class OriginKeyStore : public nsISupports
aString.AssignLiteral("[Expanded Principal [");
for (uint32_t i = 0; i < info.whitelist().Length(); i++) {
for (uint32_t i = 0; i < info.allowlist().Length(); i++) {
nsAutoCString str;
PrincipalInfoToString(info.whitelist()[i], str);
PrincipalInfoToString(info.allowlist()[i], str);
if (i != 0) {
aString.AppendLiteral(", ");

View File

@ -422,8 +422,7 @@ function setupEnvironment() {
['media.getusermedia.screensharing.enabled', true],
['media.getusermedia.window.focus_source.enabled', false],
['media.recorder.audio_node.enabled', true],
['media.webaudio.audiocontextoptions-samplerate.enabled', true],
['media.cubeb_max_input_streams', 10000]
['media.webaudio.audiocontextoptions-samplerate.enabled', true]
]
};

View File

@ -32,10 +32,6 @@ using namespace webrtc;
#define MAX_CHANNELS 2
#define MAX_SAMPLING_FREQ 48000 // Hz - multiple of 100
#ifdef MOZ_PULSEAUDIO
static uint32_t sInputStreamsOpen = 0;
#endif
namespace mozilla {
#ifdef LOG
@ -656,23 +652,7 @@ MediaEngineWebRTCMicrophoneSource::Start(const RefPtr<const AllocationHandle>&)
return NS_ERROR_FAILURE;
}
// On Linux with PulseAudio, we still only allow a certain number of audio
// input stream in each content process, because of issues related to audio
// remoting and PulseAudio.
#ifdef MOZ_PULSEAUDIO
// When remoting, cubeb reports it's using the "remote" backend instead of the
// backend on the other side of the IPC.
const char* backend = cubeb_get_backend_id(CubebUtils::GetCubebContext());
if (strstr(backend, "remote") &&
sInputStreamsOpen == CubebUtils::GetMaxInputStreams()) {
LOG(("%p Already capturing audio in this process, aborting", this));
return NS_ERROR_FAILURE;
}
sInputStreamsOpen++;
#endif
AssertIsOnOwningThread();
mInputProcessing = new AudioInputProcessing(
mDeviceMaxChannelCount, mStream, mTrackID, mPrincipal);
@ -711,10 +691,7 @@ MediaEngineWebRTCMicrophoneSource::Stop(const RefPtr<const AllocationHandle>&)
return NS_OK;
}
#ifdef MOZ_PULSEAUDIO
MOZ_ASSERT(sInputStreamsOpen > 0);
sInputStreamsOpen--;
#endif
RefPtr<MediaEngineWebRTCMicrophoneSource> that = this;
RefPtr<MediaStreamGraphImpl> gripGraph = mStream->GraphImpl();
NS_DispatchToMainThread(media::NewRunnableFrom(

View File

@ -50,6 +50,7 @@ using mozilla::DefaultXDisplay;
#include "nsIContentInlines.h"
#include "mozilla/MiscEvents.h"
#include "mozilla/MouseEvents.h"
#include "mozilla/NullPrincipal.h"
#include "mozilla/TextEvents.h"
#include "mozilla/dom/DragEvent.h"
#include "mozilla/dom/Element.h"
@ -482,6 +483,8 @@ NS_IMETHODIMP nsPluginInstanceOwner::GetURL(const char *aURL,
mozilla::OriginAttributes attrs =
BasePrincipal::Cast(content->NodePrincipal())->OriginAttributesRef();
triggeringPrincipal = BasePrincipal::CreateCodebasePrincipal(uri, attrs);
} else {
triggeringPrincipal = NullPrincipal::CreateWithInheritedAttributes(content->NodePrincipal());
}
rv = lh->OnLinkClick(content, uri, unitarget.get(), VoidString(),

View File

@ -16,6 +16,7 @@
</tabbox>
<script type="application/javascript" src="plugin-utils.js"/>
<script type="application/javascript"><![CDATA[
ChromeUtils.import("resource://testing-common/BrowserTestUtils.jsm");
const ok = window.opener.wrappedJSObject.ok;
const is = window.opener.wrappedJSObject.is;
const done = window.opener.wrappedJSObject.done;
@ -57,10 +58,10 @@
function setup() {
progressListener1 = new ProgressListener();
browser1.addProgressListener(progressListener1, nsIWebProgress.NOTIFY_STATE_WINDOW);
browser1.loadURI(kURI, null, null);
BrowserTestUtils.loadURI(browser1, kURI);
progressListener2 = new ProgressListener();
browser2.addProgressListener(progressListener2, nsIWebProgress.NOTIFY_STATE_WINDOW);
browser2.loadURI(kURI, null, null);
BrowserTestUtils.loadURI(browser2, kURI);
}
window.addEventListener("load", setup, false);

View File

@ -363,10 +363,13 @@ DoCORSChecks(nsIChannel* aChannel, nsILoadInfo* aLoadInfo,
return NS_OK;
}
nsIPrincipal* loadingPrincipal = aLoadInfo->LoadingPrincipal();
// We use the triggering principal here, rather than the loading principal
// to ensure that anonymous CORS content in the browser resources and in
// WebExtensions is allowed to load.
nsIPrincipal* principal = aLoadInfo->TriggeringPrincipal();
RefPtr<nsCORSListenerProxy> corsListener =
new nsCORSListenerProxy(aInAndOutListener,
loadingPrincipal,
principal,
aLoadInfo->GetCookiePolicy() ==
nsILoadInfo::SEC_COOKIES_INCLUDE);
// XXX: @arg: DataURIHandling::Allow

View File

@ -0,0 +1,25 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Bug 1447784 - Implement CSP upgrade-insecure-requests directive</title>
</head>
<body>
<script type="text/javascript">
// === TEST 1
var url1 = "http://127.0.0.1:8888/tests/dom/security/test/csp/file_upgrade_insecure_loopback_server.sjs?test1";
var xhr1 = new XMLHttpRequest();
xhr1.open("GET", url1, true);
xhr1.onload = function() {
window.parent.postMessage(xhr1.response, "*");
};
xhr1.onerror = function() {
window.parent.postMessage("test1-failed", "*");
};
xhr1.send();
</script>
</body>
</html>

View File

@ -0,0 +1,23 @@
// Custom *.sjs file specifically for the needs of Bug:
// Bug 1447784 - Implement CSP upgrade-insecure-requests directive
function handleRequest(request, response)
{
response.setHeader("Access-Control-Allow-Headers", "content-type", false);
response.setHeader("Access-Control-Allow-Methods", "GET", false);
response.setHeader("Access-Control-Allow-Origin", "*", false);
// avoid confusing cache behaviors
response.setHeader("Cache-Control", "no-cache", false);
// perform sanity check and make sure that all requests get upgraded to use https
if (request.scheme !== "https") {
response.write("request-not-https");
return;
} else {
response.write("request-is-https");
}
// we should not get here, but just in case return something unexpected
response.write("d'oh");
}

View File

@ -138,6 +138,8 @@ support-files =
file_upgrade_insecure_reporting_server.sjs
file_upgrade_insecure_cors.html
file_upgrade_insecure_cors_server.sjs
file_upgrade_insecure_loopback.html
file_upgrade_insecure_loopback_server.sjs
file_report_for_import.css
file_report_for_import.html
file_report_for_import_server.sjs
@ -292,6 +294,7 @@ skip-if = (toolkit == 'android') || (os != 'linux' && !debug) # Bug 1183300
skip-if = toolkit == 'android'
[test_upgrade_insecure_cors.html]
skip-if = toolkit == 'android'
[test_upgrade_insecure_loopback.html]
[test_report_for_import.html]
[test_blocked_uri_in_reports.html]
[test_service_worker.html]

View File

@ -0,0 +1,60 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Bug 1447784 - Implement CSP upgrade-insecure-requests directive</title>
<!-- Including SimpleTest.js so we can use waitForExplicitFinish !-->
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<iframe style="width:100%;" id="testframe"></iframe>
<script class="testbody" type="text/javascript">
/* Description of the test:
* We load a page that performs a CORS XHR to 127.0.0.1 which shouldn't be upgraded to https:
*
* Test 1:
* Main page: https://127.0.0.1:8080
* XHR request: http://127.0.0.1:8080
* No redirect to https://
* Description: Upgrade insecure should *NOT* upgrade from http to https.
*/
const CSP_POLICY = "upgrade-insecure-requests; script-src 'unsafe-inline'";
let tests = 1;
function loadTest() {
var src = "https://example.com/tests/dom/security/test/csp/file_testserver.sjs?file=";
// append the file that should be served
src += escape("tests/dom/security/test/csp/file_upgrade_insecure_loopback.html")
// append the CSP that should be used to serve the file
src += "&csp=" + escape(CSP_POLICY);
document.getElementById("testframe").src = src;
}
function checkResult(result) {
if (result === "request-not-https") {
ok(true, "Didn't upgrade 127.0.0.1:8080 to https://");
}
if (--tests > 0) {
return;
}
window.removeEventListener("message", receiveMessage);
SimpleTest.finish();
}
// a postMessage handler that is used to bubble up results from
// within the iframe.
window.addEventListener("message", receiveMessage);
function receiveMessage(event) {
checkResult(event.data);
}
SimpleTest.waitForExplicitFinish();
loadTest();
</script>
</body>
</html>

View File

@ -2397,12 +2397,12 @@ nsPermissionManager::CommonTestPermissionInternal(nsIPrincipal* aPrincipal,
}
}
// For expanded principals, we want to iterate over the whitelist and see
// For expanded principals, we want to iterate over the allowlist and see
// if the permission is granted for any of them.
auto* basePrin = BasePrincipal::Cast(aPrincipal);
if (basePrin && basePrin->Is<ExpandedPrincipal>()) {
auto ep = basePrin->As<ExpandedPrincipal>();
for (auto& prin : ep->WhiteList()) {
for (auto& prin : ep->AllowList()) {
uint32_t perm;
nsresult rv = CommonTestPermission(prin, aType, &perm,
aExactHostMatch, aIncludingSession);

View File

@ -18,7 +18,8 @@ add_task(async function test_windowlessBrowserTroubleshootCrash() {
}
Services.obs.addObserver(listener, "content-document-global-created");
});
webNav.loadURI("about:blank", 0, null, null, null);
let triggeringPrincipal = Services.scriptSecurityManager.createNullPrincipal({});
webNav.loadURI("about:blank", 0, null, null, null, triggeringPrincipal);
await onLoaded;

View File

@ -112,20 +112,20 @@ PrincipalInfoToPrincipal(const PrincipalInfo& aPrincipalInfo,
case PrincipalInfo::TExpandedPrincipalInfo: {
const ExpandedPrincipalInfo& info = aPrincipalInfo.get_ExpandedPrincipalInfo();
nsTArray<nsCOMPtr<nsIPrincipal>> whitelist;
nsCOMPtr<nsIPrincipal> wlPrincipal;
nsTArray<nsCOMPtr<nsIPrincipal>> allowlist;
nsCOMPtr<nsIPrincipal> alPrincipal;
for (uint32_t i = 0; i < info.whitelist().Length(); i++) {
wlPrincipal = PrincipalInfoToPrincipal(info.whitelist()[i], &rv);
for (uint32_t i = 0; i < info.allowlist().Length(); i++) {
alPrincipal = PrincipalInfoToPrincipal(info.allowlist()[i], &rv);
if (NS_WARN_IF(NS_FAILED(rv))) {
return nullptr;
}
// append that principal to the whitelist
whitelist.AppendElement(wlPrincipal);
// append that principal to the allowlist
allowlist.AppendElement(alPrincipal);
}
RefPtr<ExpandedPrincipal> expandedPrincipal =
ExpandedPrincipal::Create(whitelist, info.attrs());
ExpandedPrincipal::Create(allowlist, info.attrs());
if (!expandedPrincipal) {
NS_WARNING("could not instantiate expanded principal");
return nullptr;
@ -194,21 +194,21 @@ PrincipalToPrincipalInfo(nsIPrincipal* aPrincipal,
if (basePrin->Is<ExpandedPrincipal>()) {
auto* expanded = basePrin->As<ExpandedPrincipal>();
nsTArray<PrincipalInfo> whitelistInfo;
nsTArray<PrincipalInfo> allowlistInfo;
PrincipalInfo info;
for (auto& prin : expanded->WhiteList()) {
for (auto& prin : expanded->AllowList()) {
rv = PrincipalToPrincipalInfo(prin, &info);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
// append that spec to the whitelist
whitelistInfo.AppendElement(info);
// append that spec to the allowlist
allowlistInfo.AppendElement(info);
}
*aPrincipalInfo =
ExpandedPrincipalInfo(aPrincipal->OriginAttributesRef(),
std::move(whitelistInfo));
std::move(allowlistInfo));
return NS_OK;
}

View File

@ -36,7 +36,7 @@ struct NullPrincipalInfo
struct ExpandedPrincipalInfo
{
OriginAttributes attrs;
PrincipalInfo[] whitelist;
PrincipalInfo[] allowlist;
};
union PrincipalInfo

View File

@ -4499,7 +4499,6 @@ PromiseObject::setRequiresUserInteractionHandling(bool state)
void
PromiseObject::setHadUserInteractionUponCreation(bool state)
{
MOZ_ASSERT(this->state() == JS::PromiseState::Pending);
if (state) {
AddPromiseFlags(*this, PROMISE_FLAG_HAD_USER_INTERACTION_UPON_CREATION);
} else {
@ -4510,7 +4509,6 @@ PromiseObject::setHadUserInteractionUponCreation(bool state)
void
PromiseObject::copyUserInteractionFlagsFrom(PromiseObject& rhs)
{
MOZ_ASSERT(state() == JS::PromiseState::Pending);
setRequiresUserInteractionHandling(rhs.requiresUserInteractionHandling());
setHadUserInteractionUponCreation(rhs.hadUserInteractionUponCreation());
}

View File

@ -78,8 +78,7 @@ enum PromiseSlots {
// concept defined by the HTML spec:
// https://html.spec.whatwg.org/multipage/interaction.html#triggered-by-user-activation
// This flag is only effective when the
// PROMISE_FLAG_REQUIRES_USER_INTERACTION_HANDLING is set. Also, it is only
// possible to set this flag on pending promises.
// PROMISE_FLAG_REQUIRES_USER_INTERACTION_HANDLING is set.
#define PROMISE_FLAG_HAD_USER_INTERACTION_UPON_CREATION 0x40
class AutoSetNewObjectMetadata;

View File

@ -409,6 +409,8 @@ HasReader(const ReadableStream* stream)
inline static MOZ_MUST_USE JSFunction*
NewHandler(JSContext* cx, Native handler, HandleObject target)
{
cx->check(target);
RootedAtom funName(cx, cx->names().empty);
RootedFunction handlerFun(cx, NewNativeFunction(cx, handler, 0, funName,
gc::AllocKind::FUNCTION_EXTENDED,
@ -428,7 +430,7 @@ TargetFromHandler(JSObject& handler)
}
inline static MOZ_MUST_USE bool
ResetQueue(JSContext* cx, Handle<ReadableStreamController*> container);
ResetQueue(JSContext* cx, Handle<ReadableStreamController*> unwrappedContainer);
inline static MOZ_MUST_USE bool
InvokeOrNoop(JSContext* cx, HandleValue O, HandlePropertyName P, HandleValue arg,
@ -475,25 +477,22 @@ ReturnPromiseRejectedWithPendingError(JSContext* cx, const CallArgs& args)
* Creates a NativeObject to be used as a list and stores it on the given
* container at the given fixed slot offset.
*
* Note: to make handling of lists easier, SetNewList ensures that the list
* is created in the container's compartment. If the container isn't from the
* currently entered compartment, then it's compartment is entered prior to
* creating the list. The list is returned unwrapped in that case, so won't
* be in the currently entered compartment, either.
* Note: unwrappedContainer does not have to be same-compartment with cx. The
* new List is created in unwrappedContainer's compartment.
*/
inline static MOZ_MUST_USE NativeObject*
SetNewList(JSContext* cx, HandleNativeObject container, uint32_t slot)
inline static MOZ_MUST_USE bool
SetNewList(JSContext* cx, HandleNativeObject unwrappedContainer, uint32_t slot)
{
mozilla::Maybe<AutoRealm> ar;
if (container->compartment() != cx->compartment()) {
ar.emplace(cx, container);
if (unwrappedContainer->compartment() != cx->compartment()) {
ar.emplace(cx, unwrappedContainer);
}
NativeObject* list = NewList(cx);
if (!list) {
return nullptr;
return false;
}
container->setFixedSlot(slot, ObjectValue(*list));
return list;
unwrappedContainer->setFixedSlot(slot, ObjectValue(*list));
return true;
}
class ByteStreamChunk : public NativeObject
@ -1145,10 +1144,11 @@ ReadableStream::locked() const
static MOZ_MUST_USE bool
ReadableStreamDefaultControllerClose(JSContext* cx,
Handle<ReadableStreamDefaultController*> controller);
Handle<ReadableStreamDefaultController*> unwrappedController);
static MOZ_MUST_USE bool
ReadableStreamDefaultControllerEnqueue(JSContext* cx,
Handle<ReadableStreamDefaultController*> controller,
Handle<ReadableStreamDefaultController*> unwrappedController,
HandleValue chunk);
static bool
@ -1240,8 +1240,7 @@ TeeReaderReadHandler(JSContext* cx, unsigned argc, Value* vp)
}
static MOZ_MUST_USE JSObject*
ReadableStreamTee_Pull(JSContext* cx, Handle<TeeState*> teeState,
Handle<ReadableStream*> branchStream)
ReadableStreamTee_Pull(JSContext* cx, Handle<TeeState*> unwrappedTeeState)
{
// Step 1: Let reader be F.[[reader]], branch1 be F.[[branch1]],
// branch2 be F.[[branch2]], teeState be F.[[teeState]], and
@ -1251,24 +1250,24 @@ ReadableStreamTee_Pull(JSContext* cx, Handle<TeeState*> teeState,
// ! ReadableStreamDefaultReaderRead(reader) by a fulfillment
// handler which takes the argument result and performs the
// following steps:
Rooted<ReadableStream*> stream(cx);
if (!UnwrapInternalSlot(cx, teeState, TeeStateSlot_Stream, &stream)) {
Rooted<ReadableStream*> unwrappedStream(cx);
if (!UnwrapInternalSlot(cx, unwrappedTeeState, TeeStateSlot_Stream, &unwrappedStream)) {
return nullptr;
}
Rooted<ReadableStreamReader*> readerObj(cx);
if (!UnwrapReaderFromStream(cx, stream, &readerObj)) {
Rooted<ReadableStreamReader*> unwrappedReaderObj(cx);
if (!UnwrapReaderFromStream(cx, unwrappedStream, &unwrappedReaderObj)) {
return nullptr;
}
Rooted<ReadableStreamDefaultReader*> reader(cx,
&readerObj->as<ReadableStreamDefaultReader>());
Rooted<ReadableStreamDefaultReader*> unwrappedReader(cx,
&unwrappedReaderObj->as<ReadableStreamDefaultReader>());
RootedObject readPromise(cx, ReadableStreamDefaultReader::read(cx, reader));
RootedObject readPromise(cx, ReadableStreamDefaultReader::read(cx, unwrappedReader));
if (!readPromise) {
return nullptr;
}
RootedObject onFulfilled(cx, NewHandler(cx, TeeReaderReadHandler, teeState));
RootedObject onFulfilled(cx, NewHandler(cx, TeeReaderReadHandler, unwrappedTeeState));
if (!onFulfilled) {
return nullptr;
}
@ -2353,21 +2352,22 @@ ReadableStreamControllerPullSteps(JSContext* cx, Handle<ReadableStreamController
* another compartment.
*/
/* static */ MOZ_MUST_USE JSObject*
ReadableStreamDefaultReader::read(JSContext* cx, Handle<ReadableStreamDefaultReader*> reader)
ReadableStreamDefaultReader::read(JSContext* cx,
Handle<ReadableStreamDefaultReader*> unwrappedReader)
{
// Step 1: Let stream be reader.[[ownerReadableStream]].
// Step 2: Assert: stream is not undefined.
Rooted<ReadableStream*> stream(cx);
if (!UnwrapStreamFromReader(cx, reader, &stream)) {
Rooted<ReadableStream*> unwrappedStream(cx);
if (!UnwrapStreamFromReader(cx, unwrappedReader, &unwrappedStream)) {
return nullptr;
}
// Step 3: Set stream.[[disturbed]] to true.
SetStreamState(stream, StreamState(stream) | ReadableStream::Disturbed);
SetStreamState(unwrappedStream, StreamState(unwrappedStream) | ReadableStream::Disturbed);
// Step 4: If stream.[[state]] is "closed", return a new promise resolved with
// ! CreateIterResultObject(undefined, true).
if (stream->closed()) {
if (unwrappedStream->closed()) {
RootedObject iterResult(cx, CreateIterResultObject(cx, UndefinedHandleValue, true));
if (!iterResult) {
return nullptr;
@ -2378,8 +2378,8 @@ ReadableStreamDefaultReader::read(JSContext* cx, Handle<ReadableStreamDefaultRea
// Step 5: If stream.[[state]] is "errored", return a new promise rejected with
// stream.[[storedError]].
if (stream->errored()) {
RootedValue storedError(cx, stream->getFixedSlot(StreamSlot_StoredError));
if (unwrappedStream->errored()) {
RootedValue storedError(cx, unwrappedStream->getFixedSlot(StreamSlot_StoredError));
if (!cx->compartment()->wrap(cx, &storedError)) {
return nullptr;
}
@ -2387,11 +2387,12 @@ ReadableStreamDefaultReader::read(JSContext* cx, Handle<ReadableStreamDefaultRea
}
// Step 6: Assert: stream.[[state]] is "readable".
MOZ_ASSERT(stream->readable());
MOZ_ASSERT(unwrappedStream->readable());
// Step 7: Return ! stream.[[readableStreamController]].[[PullSteps]]().
Rooted<ReadableStreamController*> controller(cx, ControllerFromStream(stream));
return ReadableStreamControllerPullSteps(cx, controller);
Rooted<ReadableStreamController*> unwrappedController(cx,
ControllerFromStream(unwrappedStream));
return ReadableStreamControllerPullSteps(cx, unwrappedController);
}
@ -2399,7 +2400,7 @@ ReadableStreamDefaultReader::read(JSContext* cx, Handle<ReadableStreamDefaultRea
inline static MOZ_MUST_USE bool
ReadableStreamControllerCallPullIfNeeded(JSContext* cx,
Handle<ReadableStreamController*> controller);
Handle<ReadableStreamController*> unwrappedController);
// Streams spec, 3.8.3, step 11.a.
// and
@ -2430,7 +2431,7 @@ ControllerStartHandler(JSContext* cx, unsigned argc, Value* vp)
}
static MOZ_MUST_USE bool
ReadableStreamControllerError(JSContext* cx, Handle<ReadableStreamController*> controller,
ReadableStreamControllerError(JSContext* cx, Handle<ReadableStreamController*> unwrappedController,
HandleValue e);
// Streams spec, 3.8.3, step 11.b.
@ -2486,6 +2487,8 @@ CreateReadableStreamDefaultController(JSContext* cx, Handle<ReadableStream*> str
HandleValue underlyingSource, HandleValue size,
HandleValue highWaterMarkVal)
{
cx->check(stream, underlyingSource, size, highWaterMarkVal);
Rooted<ReadableStreamDefaultController*> controller(cx);
controller = NewBuiltinClassInstance<ReadableStreamDefaultController>(cx);
if (!controller) {
@ -2605,54 +2608,54 @@ ReadableStreamDefaultController_desiredSize(JSContext* cx, unsigned argc, Value*
// Step 1: If ! IsReadableStreamDefaultController(this) is false, throw a
// TypeError exception.
CallArgs args = CallArgsFromVp(argc, vp);
Rooted<ReadableStreamController*> controller(cx);
Rooted<ReadableStreamController*> unwrappedController(cx);
if (!UnwrapThisForNonGenericMethod(cx,
args.thisv(),
"ReadableStreamDefaultController",
"get desiredSize",
&controller))
&unwrappedController))
{
return false;
}
// Streams spec, 3.9.8. steps 1-4.
// 3.9.8. Step 1: Let stream be controller.[[controlledReadableStream]].
ReadableStream* stream = StreamFromController(controller);
ReadableStream* unwrappedStream = StreamFromController(unwrappedController);
// 3.9.8. Step 2: Let state be stream.[[state]].
// 3.9.8. Step 3: If state is "errored", return null.
if (stream->errored()) {
if (unwrappedStream->errored()) {
args.rval().setNull();
return true;
}
// 3.9.8. Step 4: If state is "closed", return 0.
if (stream->closed()) {
if (unwrappedStream->closed()) {
args.rval().setInt32(0);
return true;
}
// Step 2: Return ! ReadableStreamDefaultControllerGetDesiredSize(this).
args.rval().setNumber(ReadableStreamControllerGetDesiredSizeUnchecked(controller));
args.rval().setNumber(ReadableStreamControllerGetDesiredSizeUnchecked(unwrappedController));
return true;
}
static MOZ_MUST_USE bool
ReadableStreamDefaultControllerClose(JSContext* cx,
Handle<ReadableStreamDefaultController*> controller);
Handle<ReadableStreamDefaultController*> unwrappedController);
/**
* Unified implementation of step 2 of 3.8.4.2 and steps 2-3 of 3.10.4.3.
*
* Note: can operate on unwrapped ReadableStream controller instances from
* Note: can operate on unwrapped ReadableStreamController instances from
* another compartment.
*/
static MOZ_MUST_USE bool
VerifyControllerStateForClosing(JSContext* cx, Handle<ReadableStreamController*> controller)
VerifyControllerStateForClosing(JSContext* cx,
Handle<ReadableStreamController*> unwrappedController)
{
// Step 2: If this.[[closeRequested]] is true, throw a TypeError exception.
if (ControllerFlags(controller) & ControllerFlag_CloseRequested) {
if (ControllerFlags(unwrappedController) & ControllerFlag_CloseRequested) {
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
JSMSG_READABLESTREAMCONTROLLER_CLOSED, "close");
return false;
@ -2660,8 +2663,8 @@ VerifyControllerStateForClosing(JSContext* cx, Handle<ReadableStreamController*>
// Step 3: If this.[[controlledReadableStream]].[[state]] is not "readable",
// throw a TypeError exception.
ReadableStream* stream = StreamFromController(controller);
if (!stream->readable()) {
ReadableStream* unwrappedStream = StreamFromController(unwrappedController);
if (!unwrappedStream->readable()) {
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
JSMSG_READABLESTREAMCONTROLLER_NOT_READABLE, "close");
return false;
@ -2679,48 +2682,50 @@ ReadableStreamDefaultController_close(JSContext* cx, unsigned argc, Value* vp)
// Step 1: If ! IsReadableStreamDefaultController(this) is false, throw a
// TypeError exception.
CallArgs args = CallArgsFromVp(argc, vp);
Rooted<ReadableStreamDefaultController*> controller(cx);
Rooted<ReadableStreamDefaultController*> unwrappedController(cx);
if (!UnwrapThisForNonGenericMethod(cx,
args.thisv(),
"ReadableStreamDefaultController",
"close",
&controller))
&unwrappedController))
{
return false;
}
// Steps 2-3.
if (!VerifyControllerStateForClosing(cx, controller)) {
if (!VerifyControllerStateForClosing(cx, unwrappedController)) {
return false;
}
// Step 4: Perform ! ReadableStreamDefaultControllerClose(this).
if (!ReadableStreamDefaultControllerClose(cx, controller)) {
if (!ReadableStreamDefaultControllerClose(cx, unwrappedController)) {
return false;
}
args.rval().setUndefined();
return true;
}
// Streams spec, 3.8.4.3. enqueue ( chunk )
/**
* Streams spec, 3.8.4.3. enqueue ( chunk )
*/
static bool
ReadableStreamDefaultController_enqueue(JSContext* cx, unsigned argc, Value* vp)
{
// Step 1: If ! IsReadableStreamDefaultController(this) is false, throw a
// TypeError exception.
CallArgs args = CallArgsFromVp(argc, vp);
Rooted<ReadableStreamDefaultController*> controller(cx);
Rooted<ReadableStreamDefaultController*> unwrappedController(cx);
if (!UnwrapThisForNonGenericMethod(cx,
args.thisv(),
"ReadableStreamDefaultController",
"enqueue",
&controller))
&unwrappedController))
{
return false;
}
// Step 2: If this.[[closeRequested]] is true, throw a TypeError exception.
if (ControllerFlags(controller) & ControllerFlag_CloseRequested) {
if (ControllerFlags(unwrappedController) & ControllerFlag_CloseRequested) {
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
JSMSG_READABLESTREAMCONTROLLER_CLOSED, "enqueue");
return false;
@ -2728,15 +2733,14 @@ ReadableStreamDefaultController_enqueue(JSContext* cx, unsigned argc, Value* vp)
// Step 3: If this.[[controlledReadableStream]].[[state]] is not "readable",
// throw a TypeError exception.
ReadableStream* stream = StreamFromController(controller);
if (!stream->readable()) {
if (!StreamFromController(unwrappedController)->readable()) {
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
JSMSG_READABLESTREAMCONTROLLER_NOT_READABLE, "enqueue");
return false;
}
// Step 4: Return ! ReadableStreamDefaultControllerEnqueue(this, chunk).
if (!ReadableStreamDefaultControllerEnqueue(cx, controller, args.get(0))) {
if (!ReadableStreamDefaultControllerEnqueue(cx, unwrappedController, args.get(0))) {
return false;
}
args.rval().setUndefined();
@ -2753,26 +2757,26 @@ ReadableStreamDefaultController_error(JSContext* cx, unsigned argc, Value* vp)
// TypeError exception.
CallArgs args = CallArgsFromVp(argc, vp);
Rooted<ReadableStreamDefaultController*> controller(cx);
Rooted<ReadableStreamDefaultController*> unwrappedController(cx);
if (!UnwrapThisForNonGenericMethod(cx,
args.thisv(),
"ReadableStreamDefaultController",
"enqueue",
&controller))
&unwrappedController))
{
return false;
}
// Step 2: Let stream be this.[[controlledReadableStream]].
// Step 3: If stream.[[state]] is not "readable", throw a TypeError exception.
if (!StreamFromController(controller)->readable()) {
if (!StreamFromController(unwrappedController)->readable()) {
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
JSMSG_READABLESTREAMCONTROLLER_NOT_READABLE, "error");
return false;
}
// Step 4: Perform ! ReadableStreamDefaultControllerError(this, e).
if (!ReadableStreamControllerError(cx, controller, args.get(0))) {
if (!ReadableStreamControllerError(cx, unwrappedController, args.get(0))) {
return false;
}
args.rval().setUndefined();
@ -2805,38 +2809,42 @@ CLASS_SPEC(ReadableStreamDefaultController, 4, 7, ClassSpec::DontDefineConstruct
* and
* Streams spec, 3.10.5.1. [[CancelSteps]] ( reason )
*
* Note: can operate on unwrapped ReadableStream |controller| instances
* Note: can operate on unwrapped ReadableStreamController instances
* from another compartment. |reason| must be in the current cx compartment.
*/
static MOZ_MUST_USE JSObject*
ReadableStreamControllerCancelSteps(JSContext* cx, Handle<ReadableStreamController*> controller,
ReadableStreamControllerCancelSteps(JSContext* cx,
Handle<ReadableStreamController*> unwrappedController,
HandleValue reason)
{
AssertSameCompartment(cx, reason);
// Step 1 of 3.10.5.1: If this.[[pendingPullIntos]] is not empty,
if (!controller->is<ReadableStreamDefaultController>()) {
Value val = controller->getFixedSlot(ByteControllerSlot_PendingPullIntos);
RootedNativeObject pendingPullIntos(cx, &val.toObject().as<NativeObject>());
if (!unwrappedController->is<ReadableStreamDefaultController>()) {
Value unwrappedVal =
unwrappedController->getFixedSlot(ByteControllerSlot_PendingPullIntos);
RootedNativeObject unwrappedPendingPullIntos(cx);
unwrappedPendingPullIntos = &unwrappedVal.toObject().as<NativeObject>();
if (pendingPullIntos->getDenseInitializedLength() != 0) {
if (unwrappedPendingPullIntos->getDenseInitializedLength() != 0) {
// Step a: Let firstDescriptor be the first element of
// this.[[pendingPullIntos]].
// Step b: Set firstDescriptor.[[bytesFilled]] to 0.
PullIntoDescriptor* descriptor;
descriptor = ToUnwrapped<PullIntoDescriptor>(cx, PeekList<JSObject>(pendingPullIntos));
if (!descriptor) {
PullIntoDescriptor* unwrappedDescriptor =
ToUnwrapped<PullIntoDescriptor>(cx, PeekList<JSObject>(unwrappedPendingPullIntos));
if (!unwrappedDescriptor) {
return nullptr;
}
descriptor->setBytesFilled(0);
// Step b: Set firstDescriptor.[[bytesFilled]] to 0.
unwrappedDescriptor->setBytesFilled(0);
}
}
RootedValue underlyingSource(cx);
underlyingSource = controller->getFixedSlot(ControllerSlot_UnderlyingSource);
RootedValue unwrappedUnderlyingSource(cx);
unwrappedUnderlyingSource = unwrappedController->getFixedSlot(ControllerSlot_UnderlyingSource);
// Step 1 of 3.8.5.1, step 2 of 3.10.5.1: Perform ! ResetQueue(this).
if (!ResetQueue(cx, controller)) {
if (!ResetQueue(cx, unwrappedController)) {
return nullptr;
}
@ -2848,31 +2856,37 @@ ReadableStreamControllerCancelSteps(JSContext* cx, Handle<ReadableStreamControll
// those, we check if the source is a, maybe wrapped, TeeState instance
// and manually dispatch to the right internal function. TeeState is fully
// under our control, so this isn't content-observable.
if (IsMaybeWrapped<TeeState>(underlyingSource)) {
Rooted<TeeState*> teeState(cx);
teeState = &UncheckedUnwrap(&underlyingSource.toObject())->as<TeeState>();
Rooted<ReadableStreamDefaultController*> defaultController(cx);
defaultController = &controller->as<ReadableStreamDefaultController>();
return ReadableStreamTee_Cancel(cx, teeState, defaultController, reason);
if (IsMaybeWrapped<TeeState>(unwrappedUnderlyingSource)) {
Rooted<TeeState*> unwrappedteeState(cx);
unwrappedteeState = &unwrappedUnderlyingSource.toObject().unwrapAs<TeeState>();
Rooted<ReadableStreamDefaultController*> unwrappedDefaultController(cx);
unwrappedDefaultController = &unwrappedController->as<ReadableStreamDefaultController>();
return ReadableStreamTee_Cancel(cx, unwrappedteeState, unwrappedDefaultController,
reason);
}
if (ControllerFlags(controller) & ControllerFlag_ExternalSource) {
bool needsWrapping = controller->compartment() != cx->compartment();
if (ControllerFlags(unwrappedController) & ControllerFlag_ExternalSource) {
bool needsWrapping = unwrappedController->compartment() != cx->compartment();
RootedValue rval(cx);
{
RootedValue wrappedReason(cx, reason);
mozilla::Maybe<AutoRealm> ar;
if (needsWrapping) {
ar.emplace(cx, controller);
ar.emplace(cx, unwrappedController);
if (!cx->compartment()->wrap(cx, &wrappedReason)) {
return nullptr;
}
}
void* source = underlyingSource.toPrivate();
Rooted<ReadableStream*> stream(cx, StreamFromController(controller));
void* source = unwrappedUnderlyingSource.toPrivate();
// Thanks to `ar`, `unwrappedController` is now same-compartment with `cx`.
// That's why this variable `stream` does not get the `unwrapped` prefix.
Rooted<ReadableStream*> stream(cx, StreamFromController(unwrappedController));
cx->check(stream, wrappedReason);
rval = cx->runtime()->readableStreamCancelCallback(cx, stream, source,
stream->embeddingFlags(),
wrappedReason);
stream->embeddingFlags(),
wrappedReason);
}
if (needsWrapping && !cx->compartment()->wrap(cx, &rval)) {
@ -2884,15 +2898,17 @@ ReadableStreamControllerCancelSteps(JSContext* cx, Handle<ReadableStreamControll
// If the stream and its controller aren't in the cx compartment, we have
// to ensure that the underlying source is correctly wrapped before
// operating on it.
if (!cx->compartment()->wrap(cx, &underlyingSource)) {
if (!cx->compartment()->wrap(cx, &unwrappedUnderlyingSource)) {
return nullptr;
}
return PromiseInvokeOrNoop(cx, underlyingSource, cx->names().cancel, reason);
return PromiseInvokeOrNoop(cx, unwrappedUnderlyingSource, cx->names().cancel, reason);
}
inline static MOZ_MUST_USE bool
DequeueValue(JSContext* cx, Handle<ReadableStreamController*> container, MutableHandleValue chunk);
DequeueValue(JSContext* cx,
Handle<ReadableStreamController*> unwrappedContainer,
MutableHandleValue chunk);
/**
* Streams spec, 3.8.5.2. ReadableStreamDefaultController [[PullSteps]]()
@ -2902,47 +2918,45 @@ DequeueValue(JSContext* cx, Handle<ReadableStreamController*> container, Mutable
*/
static JSObject*
ReadableStreamDefaultControllerPullSteps(JSContext* cx,
Handle<ReadableStreamController*> controller)
Handle<ReadableStreamController*> unwrappedController)
{
MOZ_ASSERT(controller->is<ReadableStreamDefaultController>());
MOZ_ASSERT(unwrappedController->is<ReadableStreamDefaultController>());
// Step 1: Let stream be this.[[controlledReadableStream]].
Rooted<ReadableStream*> stream(cx, StreamFromController(controller));
Rooted<ReadableStream*> unwrappedStream(cx, StreamFromController(unwrappedController));
// Step 2: If this.[[queue]] is not empty,
RootedNativeObject queue(cx);
RootedValue val(cx, controller->getFixedSlot(QueueContainerSlot_Queue));
RootedNativeObject unwrappedQueue(cx);
RootedValue val(cx, unwrappedController->getFixedSlot(QueueContainerSlot_Queue));
if (val.isObject()) {
queue = &val.toObject().as<NativeObject>();
unwrappedQueue = &val.toObject().as<NativeObject>();
}
if (queue && queue->getDenseInitializedLength() != 0) {
if (unwrappedQueue && unwrappedQueue->getDenseInitializedLength() != 0) {
// Step a: Let chunk be ! DequeueValue(this.[[queue]]).
RootedValue chunk(cx);
if (!DequeueValue(cx, controller, &chunk)) {
if (!DequeueValue(cx, unwrappedController, &chunk)) {
return nullptr;
}
// Step b: If this.[[closeRequested]] is true and this.[[queue]] is empty,
// perform ! ReadableStreamClose(stream).
bool closeRequested = ControllerFlags(controller) & ControllerFlag_CloseRequested;
if (closeRequested && queue->getDenseInitializedLength() == 0) {
if (!ReadableStreamCloseInternal(cx, stream)) {
bool closeRequested = ControllerFlags(unwrappedController) & ControllerFlag_CloseRequested;
if (closeRequested && unwrappedQueue->getDenseInitializedLength() == 0) {
if (!ReadableStreamCloseInternal(cx, unwrappedStream)) {
return nullptr;
}
}
// Step c: Otherwise, perform ! ReadableStreamDefaultControllerCallPullIfNeeded(this).
else {
if (!ReadableStreamControllerCallPullIfNeeded(cx, controller)) {
return nullptr;
}
if (!ReadableStreamControllerCallPullIfNeeded(cx, unwrappedController)) {
return nullptr;
}
}
// Step d: Return a promise resolved with ! CreateIterResultObject(chunk, false).
if (!cx->compartment()->wrap(cx, &chunk)) {
return nullptr;
}
cx->check(chunk);
RootedObject iterResultObj(cx, CreateIterResultObject(cx, chunk, false));
if (!iterResultObj) {
return nullptr;
@ -2952,13 +2966,13 @@ ReadableStreamDefaultControllerPullSteps(JSContext* cx,
}
// Step 3: Let pendingPromise be ! ReadableStreamAddReadRequest(stream).
RootedObject pendingPromise(cx, ReadableStreamAddReadOrReadIntoRequest(cx, stream));
RootedObject pendingPromise(cx, ReadableStreamAddReadOrReadIntoRequest(cx, unwrappedStream));
if (!pendingPromise) {
return nullptr;
}
// Step 4: Perform ! ReadableStreamDefaultControllerCallPullIfNeeded(this).
if (!ReadableStreamControllerCallPullIfNeeded(cx, controller)) {
if (!ReadableStreamControllerCallPullIfNeeded(cx, unwrappedController)) {
return nullptr;
}
@ -3087,7 +3101,7 @@ ReadableStreamControllerCallPullIfNeeded(JSContext* cx,
Rooted<TeeState*> teeState(cx);
teeState = &UncheckedUnwrap(&underlyingSource.toObject())->as<TeeState>();
Rooted<ReadableStream*> stream(cx, StreamFromController(controller));
pullPromise = ReadableStreamTee_Pull(cx, teeState, stream);
pullPromise = ReadableStreamTee_Pull(cx, teeState);
} else if (ControllerFlags(controller) & ControllerFlag_ExternalSource) {
void* source = underlyingSource.toPrivate();
Rooted<ReadableStream*> stream(cx, StreamFromController(controller));
@ -4245,19 +4259,22 @@ EnqueueValueWithSize(JSContext* cx, Handle<ReadableStreamController*> container,
/**
* Streams spec, 6.2.4. ResetQueue ( container ) nothrow
*
* Note: can operate on unwrapped container instances from another
* compartment.
*/
inline static MOZ_MUST_USE bool
ResetQueue(JSContext* cx, Handle<ReadableStreamController*> container)
ResetQueue(JSContext* cx, Handle<ReadableStreamController*> unwrappedContainer)
{
// Step 1: Assert: container has [[queue]] and [[queueTotalSize]] internal
// slots (implicit).
// Step 2: Set container.[[queue]] to a new empty List.
if (!SetNewList(cx, container, QueueContainerSlot_Queue)) {
if (!SetNewList(cx, unwrappedContainer, QueueContainerSlot_Queue)) {
return false;
}
// Step 3: Set container.[[queueTotalSize]] to 0.
SetQueueSize(container, 0);
SetQueueSize(unwrappedContainer, 0);
return true;
}

View File

@ -2551,7 +2551,7 @@ js::NewDerivedTypedObject(JSContext* cx, unsigned argc, Value* vp)
MOZ_ASSERT(args.length() == 3);
MOZ_ASSERT(args[0].isObject() && args[0].toObject().is<TypeDescr>());
MOZ_ASSERT(args[1].isObject() && args[1].toObject().is<TypedObject>());
MOZ_ASSERT(args[2].isInt32());
MOZ_RELEASE_ASSERT(args[2].isInt32());
Rooted<TypeDescr*> descr(cx, &args[0].toObject().as<TypeDescr>());
Rooted<TypedObject*> typedObj(cx, &args[1].toObject().as<TypedObject>());
@ -2572,7 +2572,7 @@ js::AttachTypedObject(JSContext* cx, unsigned argc, Value* vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
MOZ_ASSERT(args.length() == 3);
MOZ_ASSERT(args[2].isInt32());
MOZ_RELEASE_ASSERT(args[2].isInt32());
OutlineTypedObject& handle = args[0].toObject().as<OutlineTypedObject>();
TypedObject& target = args[1].toObject().as<TypedObject>();
@ -2590,7 +2590,7 @@ js::SetTypedObjectOffset(JSContext*, unsigned argc, Value* vp)
CallArgs args = CallArgsFromVp(argc, vp);
MOZ_ASSERT(args.length() == 2);
MOZ_ASSERT(args[0].isObject() && args[0].toObject().is<TypedObject>());
MOZ_ASSERT(args[1].isInt32());
MOZ_RELEASE_ASSERT(args[1].isInt32());
OutlineTypedObject& typedObj = args[0].toObject().as<OutlineTypedObject>();
int32_t offset = args[1].toInt32();
@ -2709,7 +2709,7 @@ js::StoreScalar##T::Func(JSContext* cx, unsigned argc, Value* vp)
CallArgs args = CallArgsFromVp(argc, vp); \
MOZ_ASSERT(args.length() == 3); \
MOZ_ASSERT(args[0].isObject() && args[0].toObject().is<TypedObject>()); \
MOZ_ASSERT(args[1].isInt32()); \
MOZ_RELEASE_ASSERT(args[1].isInt32()); \
MOZ_ASSERT(args[2].isNumber()); \
\
TypedObject& typedObj = args[0].toObject().as<TypedObject>(); \
@ -2733,7 +2733,7 @@ js::StoreReference##_name::Func(JSContext* cx, unsigned argc, Value* vp)
CallArgs args = CallArgsFromVp(argc, vp); \
MOZ_ASSERT(args.length() == 4); \
MOZ_ASSERT(args[0].isObject() && args[0].toObject().is<TypedObject>()); \
MOZ_ASSERT(args[1].isInt32()); \
MOZ_RELEASE_ASSERT(args[1].isInt32()); \
MOZ_ASSERT(args[2].isString() || args[2].isNull()); \
\
TypedObject& typedObj = args[0].toObject().as<TypedObject>(); \
@ -2761,7 +2761,7 @@ js::LoadScalar##T::Func(JSContext* cx, unsigned argc, Value* vp)
CallArgs args = CallArgsFromVp(argc, vp); \
MOZ_ASSERT(args.length() == 2); \
MOZ_ASSERT(args[0].isObject() && args[0].toObject().is<TypedObject>()); \
MOZ_ASSERT(args[1].isInt32()); \
MOZ_RELEASE_ASSERT(args[1].isInt32()); \
\
TypedObject& typedObj = args[0].toObject().as<TypedObject>(); \
int32_t offset = args[1].toInt32(); \
@ -2782,7 +2782,7 @@ js::LoadReference##_name::Func(JSContext* cx, unsigned argc, Value* vp)
CallArgs args = CallArgsFromVp(argc, vp); \
MOZ_ASSERT(args.length() == 2); \
MOZ_ASSERT(args[0].isObject() && args[0].toObject().is<TypedObject>()); \
MOZ_ASSERT(args[1].isInt32()); \
MOZ_RELEASE_ASSERT(args[1].isInt32()); \
\
TypedObject& typedObj = args[0].toObject().as<TypedObject>(); \
int32_t offset = args[1].toInt32(); \

View File

@ -65,7 +65,7 @@ function TypedObjectGet(descr, typedObj, offset) {
function TypedObjectGetDerived(descr, typedObj, offset) {
assert(!TypeDescrIsSimpleType(descr),
"getDerived() used with simple type");
return NewDerivedTypedObject(descr, typedObj, offset);
return NewDerivedTypedObject(descr, typedObj, offset | 0);
}
function TypedObjectGetDerivedIf(descr, typedObj, offset, cond) {
@ -76,7 +76,7 @@ function TypedObjectGetOpaque(descr, typedObj, offset) {
assert(!TypeDescrIsSimpleType(descr),
"getDerived() used with simple type");
var opaqueTypedObj = NewOpaqueTypedObject(descr);
AttachTypedObject(opaqueTypedObj, typedObj, offset);
AttachTypedObject(opaqueTypedObj, typedObj, offset | 0);
return opaqueTypedObj;
}
@ -88,29 +88,29 @@ function TypedObjectGetScalar(descr, typedObj, offset) {
var type = DESCR_TYPE(descr);
switch (type) {
case JS_SCALARTYPEREPR_INT8:
return Load_int8(typedObj, offset);
return Load_int8(typedObj, offset | 0);
case JS_SCALARTYPEREPR_UINT8:
case JS_SCALARTYPEREPR_UINT8_CLAMPED:
return Load_uint8(typedObj, offset);
return Load_uint8(typedObj, offset | 0);
case JS_SCALARTYPEREPR_INT16:
return Load_int16(typedObj, offset);
return Load_int16(typedObj, offset | 0);
case JS_SCALARTYPEREPR_UINT16:
return Load_uint16(typedObj, offset);
return Load_uint16(typedObj, offset | 0);
case JS_SCALARTYPEREPR_INT32:
return Load_int32(typedObj, offset);
return Load_int32(typedObj, offset | 0);
case JS_SCALARTYPEREPR_UINT32:
return Load_uint32(typedObj, offset);
return Load_uint32(typedObj, offset | 0);
case JS_SCALARTYPEREPR_FLOAT32:
return Load_float32(typedObj, offset);
return Load_float32(typedObj, offset | 0);
case JS_SCALARTYPEREPR_FLOAT64:
return Load_float64(typedObj, offset);
return Load_float64(typedObj, offset | 0);
}
assert(false, "Unhandled scalar type: " + type);
@ -121,13 +121,13 @@ function TypedObjectGetReference(descr, typedObj, offset) {
var type = DESCR_TYPE(descr);
switch (type) {
case JS_REFERENCETYPEREPR_ANY:
return Load_Any(typedObj, offset);
return Load_Any(typedObj, offset | 0);
case JS_REFERENCETYPEREPR_OBJECT:
return Load_Object(typedObj, offset);
return Load_Object(typedObj, offset | 0);
case JS_REFERENCETYPEREPR_STRING:
return Load_string(typedObj, offset);
return Load_string(typedObj, offset | 0);
}
assert(false, "Unhandled scalar type: " + type);
@ -212,38 +212,38 @@ function TypedObjectSetScalar(descr, typedObj, offset, fromValue) {
var type = DESCR_TYPE(descr);
switch (type) {
case JS_SCALARTYPEREPR_INT8:
return Store_int8(typedObj, offset,
return Store_int8(typedObj, offset | 0,
TO_INT32(fromValue) & 0xFF);
case JS_SCALARTYPEREPR_UINT8:
return Store_uint8(typedObj, offset,
return Store_uint8(typedObj, offset | 0,
TO_UINT32(fromValue) & 0xFF);
case JS_SCALARTYPEREPR_UINT8_CLAMPED:
var v = ClampToUint8(+fromValue);
return Store_int8(typedObj, offset, v);
return Store_int8(typedObj, offset | 0, v);
case JS_SCALARTYPEREPR_INT16:
return Store_int16(typedObj, offset,
return Store_int16(typedObj, offset | 0,
TO_INT32(fromValue) & 0xFFFF);
case JS_SCALARTYPEREPR_UINT16:
return Store_uint16(typedObj, offset,
return Store_uint16(typedObj, offset | 0,
TO_UINT32(fromValue) & 0xFFFF);
case JS_SCALARTYPEREPR_INT32:
return Store_int32(typedObj, offset,
return Store_int32(typedObj, offset | 0,
TO_INT32(fromValue));
case JS_SCALARTYPEREPR_UINT32:
return Store_uint32(typedObj, offset,
return Store_uint32(typedObj, offset | 0,
TO_UINT32(fromValue));
case JS_SCALARTYPEREPR_FLOAT32:
return Store_float32(typedObj, offset, +fromValue);
return Store_float32(typedObj, offset | 0, +fromValue);
case JS_SCALARTYPEREPR_FLOAT64:
return Store_float64(typedObj, offset, +fromValue);
return Store_float64(typedObj, offset | 0, +fromValue);
}
assert(false, "Unhandled scalar type: " + type);
@ -254,14 +254,14 @@ function TypedObjectSetReference(descr, typedObj, offset, name, fromValue) {
var type = DESCR_TYPE(descr);
switch (type) {
case JS_REFERENCETYPEREPR_ANY:
return Store_Any(typedObj, offset, name, fromValue);
return Store_Any(typedObj, offset | 0, name, fromValue);
case JS_REFERENCETYPEREPR_OBJECT:
var value = (fromValue === null ? fromValue : ToObject(fromValue));
return Store_Object(typedObj, offset, name, value);
return Store_Object(typedObj, offset | 0, name, value);
case JS_REFERENCETYPEREPR_STRING:
return Store_string(typedObj, offset, name, ToString(fromValue));
return Store_string(typedObj, offset | 0, name, ToString(fromValue));
}
assert(false, "Unhandled scalar type: " + type);

View File

@ -1,5 +1,6 @@
// setVariable triggering a setter doesn't crash or explode.
// It should throw WouldRunDebuggee, but that isn't implemented yet.
// setVariable triggering a setter throws WouldRunDebuggee.
load(libdir + "asserts.js");
function test(code) {
var g = newGlobal();
@ -7,14 +8,14 @@ function test(code) {
var dbg = Debugger(g);
var hits = 0;
dbg.onDebuggerStatement = function (frame) {
var env = frame.environment.find("x");
try {
env.setVariable("x", 0);
} catch (exc) {
}
var env = frame.older.environment.find("x");
assertThrowsInstanceOf(
() => env.setVariable("x", 0),
Debugger.DebuggeeWouldRun);
hits++;
};
g.eval(code);
assertEq(hits, 1);
}
test("Object.defineProperty(this, 'x', {set: function (v) {}}); d();");

View File

@ -0,0 +1,19 @@
function newPromiseCapability() {
return {};
}
function neverCalled() {}
function resolveCapability(dIs) {}
class P extends Promise {
constructor(executor) {
executor(resolveCapability, neverCalled);
var p = async function() {}();
p.constructor = {
[Symbol.species]: P
};
return p;
}
}
var {
promise: alwaysPending
} = newPromiseCapability();
P.race([alwaysPending]).then(neverCalled, neverCalled);

View File

@ -587,6 +587,8 @@ BaselineCompiler::emitOutOfLinePostBarrierSlot()
bool
BaselineCompiler::emitIC(ICStub* stub, bool isForOp)
{
MOZ_ASSERT_IF(isForOp, BytecodeOpHasIC(JSOp(*pc)));
if (!stub) {
return false;
}

View File

@ -2929,12 +2929,14 @@ class ICUnaryArith_Fallback : public ICFallbackStub
extra_ = 0;
}
static const uint16_t SAW_DOUBLE_RESULT_BIT = 0x1;
public:
bool sawDoubleResult() {
return extra_;
bool sawDoubleResult() const {
return extra_ & SAW_DOUBLE_RESULT_BIT;
}
void setSawDoubleResult() {
extra_ = 1;
extra_ |= SAW_DOUBLE_RESULT_BIT;
}
// Compiler for this stub kind.

View File

@ -760,18 +760,26 @@ BaselineInspector::hasSeenNonStringIterMore(jsbytecode* pc)
return stub->toIteratorMore_Fallback()->hasNonStringResult();
}
// defaultIfEmpty: if we've not seen *anything* (neither double nor non-double),
// return this value. This can happen with, for example, a never-taken branch
// inside a hot loop.
bool
BaselineInspector::hasSeenDoubleResult(jsbytecode* pc)
BaselineInspector::hasSeenDoubleResult(jsbytecode* pc, bool defaultIfEmpty)
{
if (!hasBaselineScript()) {
return false;
}
const ICEntry& entry = icEntryFromPC(pc);
ICStub* stub = entry.fallbackStub();
ICFallbackStub* stub = entry.fallbackStub();
MOZ_ASSERT(stub->isUnaryArith_Fallback() || stub->isBinaryArith_Fallback());
// If no attached stubs, and no failures, then this IC has never been executed.
if (stub->state().numOptimizedStubs() == 0 && !entry.fallbackStub()->state().hasFailures()) {
return defaultIfEmpty;
}
if (stub->isUnaryArith_Fallback()) {
return stub->toUnaryArith_Fallback()->sawDoubleResult();
}

View File

@ -124,7 +124,7 @@ class BaselineInspector
bool hasSeenNegativeIndexGetElement(jsbytecode* pc);
bool hasSeenAccessedGetter(jsbytecode* pc);
bool hasSeenDoubleResult(jsbytecode* pc);
bool hasSeenDoubleResult(jsbytecode* pc, bool defaultIfEmpty);
bool hasSeenNonStringIterMore(jsbytecode* pc);
MOZ_MUST_USE bool isOptimizableConstStringSplit(jsbytecode* pc, JSString** strOut,

View File

@ -98,7 +98,7 @@ MDefinition::PrintOpcodeName(GenericPrinter& out, Opcode op)
#endif
static MConstant*
EvaluateConstantOperands(TempAllocator& alloc, MBinaryInstruction* ins, bool* ptypeChange = nullptr)
EvaluateConstantOperands(TempAllocator& alloc, MBinaryInstruction* ins)
{
MDefinition* left = ins->getOperand(0);
MDefinition* right = ins->getOperand(1);
@ -189,9 +189,6 @@ EvaluateConstantOperands(TempAllocator& alloc, MBinaryInstruction* ins, bool* pt
// denominator), decline folding.
MOZ_ASSERT(ins->type() == MIRType::Int32);
if (!retVal.isInt32()) {
if (ptypeChange) {
*ptypeChange = true;
}
return nullptr;
}
@ -2722,7 +2719,9 @@ MUrsh::infer(BaselineInspector* inspector, jsbytecode* pc)
return;
}
if (inspector->hasSeenDoubleResult(pc)) {
// defaultIfEmpty: if we haven't seen anything, assume no double has been seen:
// unsigned right shift only produces a double if the result overflows a signed int32, which is rare.
if (inspector->hasSeenDoubleResult(pc, /* defaultIfEmpty: */ false)) {
specialization_ = MIRType::Double;
setResultType(MIRType::Double);
return;
@ -2940,10 +2939,19 @@ MBinaryArithInstruction::setNumberSpecialization(TempAllocator& alloc, BaselineI
// Try to specialize as int32.
if (getOperand(0)->type() == MIRType::Int32 && getOperand(1)->type() == MIRType::Int32) {
bool seenDouble = inspector->hasSeenDoubleResult(pc);
// The defaultIfEmpty logic here is a little complex, so here's some pseudocode:
// If both arguments are integers, and this code/IC has never been ran:
// If opcode is Div:
// Assume the result is a double. (i.e. int/int division usually produces a double)
// Else (if opcode is not Div):
// Assume the result is an int. (i.e. int (op) int usually produces an int)
// Note, however, if we assume an int incorrectly (e.g. an int+int addition that
// overflows), we might bailout repeatedly. The "repeated bailout, let's not ion
// compile this" logic should catch this scenario.
bool defaultIfEmpty = op() == Opcode::Div;
bool seenDouble = inspector->hasSeenDoubleResult(pc, defaultIfEmpty);
// Use int32 specialization if the operation doesn't overflow on its
// constant operands and if the operation has never overflowed.
if (!seenDouble && !constantDoubleResult(alloc)) {
setInt32Specialization();
}
@ -2953,9 +2961,8 @@ MBinaryArithInstruction::setNumberSpecialization(TempAllocator& alloc, BaselineI
bool
MBinaryArithInstruction::constantDoubleResult(TempAllocator& alloc)
{
bool typeChange = false;
EvaluateConstantOperands(alloc, this, &typeChange);
return typeChange;
MConstant* constantResult = EvaluateConstantOperands(alloc, this);
return constantResult != nullptr && constantResult->type() == MIRType::Double;
}
MDefinition*

View File

@ -4589,9 +4589,6 @@ JS::SetPromiseUserInputEventHandlingState(JS::HandleObject promiseObj_,
}
auto& promise = promiseObj->as<PromiseObject>();
if (promise.state() != JS::PromiseState::Pending) {
return false;
}
switch (state) {
case JS::PromiseUserInputEventHandlingState::DontCare:

View File

@ -3457,8 +3457,7 @@ GetPromiseUserInputEventHandlingState(JS::HandleObject promise);
* Sets the given Promise's activation behavior state flag per above as a
* JS::PromiseUserInputEventHandlingState value.
*
* Returns false if the given object is a wrapper that can't safely be unwrapped,
* or if the promise isn't pending.
* Returns false if the given object is a wrapper that can't safely be unwrapped.
*/
extern JS_PUBLIC_API(bool)
SetPromiseUserInputEventHandlingState(JS::HandleObject promise,

View File

@ -74,7 +74,7 @@ enum {
JSOP_NEW, JSOP_EVAL, JSOP_CALLITER */
JOF_GNAME = 1 << 13, /* predicted global name */
JOF_TYPESET = 1 << 14, /* has an entry in a script's type sets */
JOF_ARITH = 1 << 15 /* unary or binary arithmetic opcode */
JOF_IC = 1 << 15, /* Baseline may use an IC for this op */
};
/* Shorthand for type from format. */
@ -766,6 +766,12 @@ GetBytecodeInteger(jsbytecode* pc)
}
}
inline bool
BytecodeOpHasIC(JSOp op)
{
return CodeSpec[op].format & JOF_IC;
}
/*
* Counts accumulated for a single opcode in a script. The counts tracked vary
* between opcodes, and this structure ensures that counts are accessed in a

View File

@ -123,13 +123,6 @@ js::DebuggerEnvironment::owner() const
return Debugger::fromJSObject(dbgobj);
}
inline js::Debugger*
js::DebuggerFrame::owner() const
{
JSObject* dbgobj = &getReservedSlot(OWNER_SLOT).toObject();
return Debugger::fromJSObject(dbgobj);
}
inline js::Debugger*
js::DebuggerObject::owner() const
{

View File

@ -91,6 +91,13 @@ enum {
JSSLOT_DEBUGFRAME_COUNT
};
inline js::Debugger*
js::DebuggerFrame::owner() const
{
JSObject* dbgobj = &getReservedSlot(JSSLOT_DEBUGFRAME_OWNER).toObject();
return Debugger::fromJSObject(dbgobj);
}
const ClassOps DebuggerFrame::classOps_ = {
nullptr, /* addProperty */
nullptr, /* delProperty */

View File

@ -1446,12 +1446,6 @@ class DebuggerFrame : public NativeObject
friend class ScriptedOnPopHandler;
public:
enum {
OWNER_SLOT
};
static const unsigned RESERVED_SLOTS = 1;
static const Class class_;
static NativeObject* initClass(JSContext* cx, HandleObject dbgCtor,

Some files were not shown because too many files have changed in this diff Show More