mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 21:31:04 +00:00
Merge mozilla-central to inbound. a=merge CLOSED TREE
This commit is contained in:
commit
c0b91fe1ee
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;"
|
||||
|
@ -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"
|
||||
|
@ -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";
|
||||
|
@ -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>
|
||||
|
@ -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"
|
||||
|
@ -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");
|
||||
|
@ -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 });
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
/**
|
||||
|
@ -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>
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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();
|
||||
};
|
||||
|
@ -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);
|
||||
};
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
**/
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -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"));
|
||||
|
@ -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"));
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -192,6 +192,7 @@ class FlexboxInspector {
|
||||
|
||||
flexItems.push({
|
||||
actorID: flexItemFront.actorID,
|
||||
computedStyle: flexItemFront.computedStyle,
|
||||
flexItemSizing: flexItemFront.flexItemSizing,
|
||||
nodeFront: itemNodeFront,
|
||||
properties: flexItemFront.properties,
|
||||
|
@ -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]
|
||||
|
@ -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");
|
||||
});
|
@ -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");
|
||||
});
|
@ -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");
|
||||
});
|
@ -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");
|
||||
});
|
||||
|
@ -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>
|
||||
|
@ -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),
|
||||
|
||||
};
|
||||
|
@ -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.
|
||||
|
@ -62,39 +62,27 @@ flexbox.itemSizing.itemBaseSizeFromContent=The item’s content size when uncons
|
||||
# its min-content size.
|
||||
flexbox.itemSizing.itemMinSizeFromItemMinContent=This is the element’s 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 wasn’t enough room inside a given flex line
|
||||
# for all of its items.
|
||||
flexbox.itemSizing.notEnoughRoomOnLine=There wasn’t 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.
|
||||
|
@ -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");
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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.
|
||||
*/
|
||||
|
@ -33,6 +33,7 @@ const changesSpec = generateActorSpec({
|
||||
changes: RetVal("array:json"),
|
||||
},
|
||||
},
|
||||
"start": {}, // no arguments, no response
|
||||
},
|
||||
});
|
||||
|
||||
|
@ -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)) {
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -8,6 +8,7 @@
|
||||
#define mozilla_dom_MessageBroadcaster_h
|
||||
|
||||
#include "mozilla/dom/MessageListenerManager.h"
|
||||
#include "nsContentUtils.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
@ -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)) {
|
||||
|
@ -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);
|
||||
|
@ -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 = {};
|
||||
|
@ -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>
|
||||
|
@ -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
|
||||
|
@ -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");
|
||||
|
@ -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
|
||||
|
@ -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()});
|
||||
|
@ -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,
|
||||
|
@ -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();
|
||||
|
@ -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(() => {
|
||||
|
@ -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(", ");
|
||||
|
@ -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]
|
||||
]
|
||||
};
|
||||
|
||||
|
@ -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(
|
||||
|
@ -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(),
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
25
dom/security/test/csp/file_upgrade_insecure_loopback.html
Normal file
25
dom/security/test/csp/file_upgrade_insecure_loopback.html
Normal 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>
|
@ -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");
|
||||
}
|
@ -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]
|
||||
|
60
dom/security/test/csp/test_upgrade_insecure_loopback.html
Normal file
60
dom/security/test/csp/test_upgrade_insecure_loopback.html
Normal 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>
|
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -36,7 +36,7 @@ struct NullPrincipalInfo
|
||||
struct ExpandedPrincipalInfo
|
||||
{
|
||||
OriginAttributes attrs;
|
||||
PrincipalInfo[] whitelist;
|
||||
PrincipalInfo[] allowlist;
|
||||
};
|
||||
|
||||
union PrincipalInfo
|
||||
|
@ -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());
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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(); \
|
||||
|
@ -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);
|
||||
|
@ -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();");
|
||||
|
19
js/src/jit-test/tests/promise/user-activation-propagation.js
Normal file
19
js/src/jit-test/tests/promise/user-activation-propagation.js
Normal 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);
|
@ -587,6 +587,8 @@ BaselineCompiler::emitOutOfLinePostBarrierSlot()
|
||||
bool
|
||||
BaselineCompiler::emitIC(ICStub* stub, bool isForOp)
|
||||
{
|
||||
MOZ_ASSERT_IF(isForOp, BytecodeOpHasIC(JSOp(*pc)));
|
||||
|
||||
if (!stub) {
|
||||
return false;
|
||||
}
|
||||
|
@ -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.
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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*
|
||||
|
@ -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:
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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 */
|
||||
|
@ -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
Loading…
Reference in New Issue
Block a user