mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-25 13:51:41 +00:00
merge mozilla-inbound to mozilla-central a=merge
This commit is contained in:
commit
cd1be634c9
@ -11,7 +11,7 @@ var gDragDataHelper = {
|
||||
|
||||
getLinkFromDragEvent: function DragDataHelper_getLinkFromDragEvent(aEvent) {
|
||||
let dt = aEvent.dataTransfer;
|
||||
if (!dt || !dt.types.contains(this.mimeType)) {
|
||||
if (!dt || !dt.types.includes(this.mimeType)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -44,7 +44,7 @@ add_task(function*() {
|
||||
|
||||
let dt = event.clipboardData;
|
||||
is(dt.types.length, 3, "number of types");
|
||||
ok(dt.types.contains("text/plain"), "text/plain exists in types");
|
||||
ok(dt.types.includes("text/plain"), "text/plain exists in types");
|
||||
ok(dt.mozTypesAt(0).contains("text/plain"), "text/plain exists in mozTypesAt");
|
||||
is(dt.getData("text/plain"), "Alternate", "text/plain returned in getData");
|
||||
is(dt.mozGetDataAt("text/plain", 0), "Alternate", "text/plain returned in mozGetDataAt");
|
||||
|
@ -656,10 +656,10 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
<parameter name="aEvent"/>
|
||||
<body>
|
||||
var types = aEvent.dataTransfer.types;
|
||||
if (types.contains("application/x-moz-file") ||
|
||||
types.contains("text/x-moz-url") ||
|
||||
types.contains("text/uri-list") ||
|
||||
types.contains("text/unicode"))
|
||||
if (types.includes("application/x-moz-file") ||
|
||||
types.includes("text/x-moz-url") ||
|
||||
types.includes("text/uri-list") ||
|
||||
types.includes("text/unicode"))
|
||||
aEvent.preventDefault();
|
||||
</body>
|
||||
</method>
|
||||
|
@ -1391,9 +1391,9 @@ DownloadsPlacesView.prototype = {
|
||||
|
||||
onDragOver(aEvent) {
|
||||
let types = aEvent.dataTransfer.types;
|
||||
if (types.contains("text/uri-list") ||
|
||||
types.contains("text/x-moz-url") ||
|
||||
types.contains("text/plain")) {
|
||||
if (types.includes("text/uri-list") ||
|
||||
types.includes("text/x-moz-url") ||
|
||||
types.includes("text/plain")) {
|
||||
aEvent.preventDefault();
|
||||
}
|
||||
},
|
||||
|
@ -12,11 +12,6 @@
|
||||
|
||||
window.parent.postMessage("OK", "http://mochi.test:8888");
|
||||
};
|
||||
|
||||
setTimeout(function() {
|
||||
window.parent.postMessage("KO", "http://mochi.test:8888");
|
||||
}, 1000);
|
||||
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
|
@ -856,7 +856,7 @@
|
||||
<handler event="dragover">
|
||||
<![CDATA[
|
||||
var types = event.dataTransfer.types;
|
||||
if (types.contains("text/plain") || types.contains("text/x-moz-text-internal"))
|
||||
if (types.includes("text/plain") || types.includes("text/x-moz-text-internal"))
|
||||
event.preventDefault();
|
||||
]]>
|
||||
</handler>
|
||||
|
@ -44,8 +44,7 @@ public:
|
||||
NS_DECL_NSIDOMLOCATION
|
||||
|
||||
#define THROW_AND_RETURN_IF_CALLER_DOESNT_SUBSUME() { \
|
||||
MOZ_ASSERT(aSubjectPrincipal.isSome()); \
|
||||
if (!CallerSubsumes(aSubjectPrincipal.value())) { \
|
||||
if (!CallerSubsumes(&aSubjectPrincipal)) { \
|
||||
aError.Throw(NS_ERROR_DOM_SECURITY_ERR); \
|
||||
return; \
|
||||
} \
|
||||
@ -53,7 +52,7 @@ public:
|
||||
|
||||
// WebIDL API:
|
||||
void Assign(const nsAString& aUrl,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
nsIPrincipal& aSubjectPrincipal,
|
||||
ErrorResult& aError)
|
||||
{
|
||||
THROW_AND_RETURN_IF_CALLER_DOESNT_SUBSUME();
|
||||
@ -61,14 +60,14 @@ public:
|
||||
}
|
||||
|
||||
void Replace(const nsAString& aUrl,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
nsIPrincipal& aSubjectPrincipal,
|
||||
ErrorResult& aError)
|
||||
{
|
||||
aError = Replace(aUrl);
|
||||
}
|
||||
|
||||
void Reload(bool aForceget,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
nsIPrincipal& aSubjectPrincipal,
|
||||
ErrorResult& aError)
|
||||
{
|
||||
THROW_AND_RETURN_IF_CALLER_DOESNT_SUBSUME();
|
||||
@ -76,7 +75,7 @@ public:
|
||||
}
|
||||
|
||||
void GetHref(nsAString& aHref,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
nsIPrincipal& aSubjectPrincipal,
|
||||
ErrorResult& aError)
|
||||
{
|
||||
THROW_AND_RETURN_IF_CALLER_DOESNT_SUBSUME();
|
||||
@ -84,14 +83,14 @@ public:
|
||||
}
|
||||
|
||||
void SetHref(const nsAString& aHref,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
nsIPrincipal& aSubjectPrincipal,
|
||||
ErrorResult& aError)
|
||||
{
|
||||
aError = SetHref(aHref);
|
||||
}
|
||||
|
||||
void GetOrigin(nsAString& aOrigin,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
nsIPrincipal& aSubjectPrincipal,
|
||||
ErrorResult& aError)
|
||||
{
|
||||
THROW_AND_RETURN_IF_CALLER_DOESNT_SUBSUME();
|
||||
@ -99,7 +98,7 @@ public:
|
||||
}
|
||||
|
||||
void GetProtocol(nsAString& aProtocol,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
nsIPrincipal& aSubjectPrincipal,
|
||||
ErrorResult& aError)
|
||||
{
|
||||
THROW_AND_RETURN_IF_CALLER_DOESNT_SUBSUME();
|
||||
@ -107,7 +106,7 @@ public:
|
||||
}
|
||||
|
||||
void SetProtocol(const nsAString& aProtocol,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
nsIPrincipal& aSubjectPrincipal,
|
||||
ErrorResult& aError)
|
||||
{
|
||||
THROW_AND_RETURN_IF_CALLER_DOESNT_SUBSUME();
|
||||
@ -115,7 +114,7 @@ public:
|
||||
}
|
||||
|
||||
void GetHost(nsAString& aHost,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
nsIPrincipal& aSubjectPrincipal,
|
||||
ErrorResult& aError)
|
||||
{
|
||||
THROW_AND_RETURN_IF_CALLER_DOESNT_SUBSUME();
|
||||
@ -123,7 +122,7 @@ public:
|
||||
}
|
||||
|
||||
void SetHost(const nsAString& aHost,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
nsIPrincipal& aSubjectPrincipal,
|
||||
ErrorResult& aError)
|
||||
{
|
||||
THROW_AND_RETURN_IF_CALLER_DOESNT_SUBSUME();
|
||||
@ -131,7 +130,7 @@ public:
|
||||
}
|
||||
|
||||
void GetHostname(nsAString& aHostname,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
nsIPrincipal& aSubjectPrincipal,
|
||||
ErrorResult& aError)
|
||||
{
|
||||
THROW_AND_RETURN_IF_CALLER_DOESNT_SUBSUME();
|
||||
@ -139,7 +138,7 @@ public:
|
||||
}
|
||||
|
||||
void SetHostname(const nsAString& aHostname,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
nsIPrincipal& aSubjectPrincipal,
|
||||
ErrorResult& aError)
|
||||
{
|
||||
THROW_AND_RETURN_IF_CALLER_DOESNT_SUBSUME();
|
||||
@ -147,7 +146,7 @@ public:
|
||||
}
|
||||
|
||||
void GetPort(nsAString& aPort,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
nsIPrincipal& aSubjectPrincipal,
|
||||
ErrorResult& aError)
|
||||
{
|
||||
THROW_AND_RETURN_IF_CALLER_DOESNT_SUBSUME();
|
||||
@ -155,7 +154,7 @@ public:
|
||||
}
|
||||
|
||||
void SetPort(const nsAString& aPort,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
nsIPrincipal& aSubjectPrincipal,
|
||||
ErrorResult& aError)
|
||||
{
|
||||
THROW_AND_RETURN_IF_CALLER_DOESNT_SUBSUME();
|
||||
@ -163,7 +162,7 @@ public:
|
||||
}
|
||||
|
||||
void GetPathname(nsAString& aPathname,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
nsIPrincipal& aSubjectPrincipal,
|
||||
ErrorResult& aError)
|
||||
{
|
||||
THROW_AND_RETURN_IF_CALLER_DOESNT_SUBSUME();
|
||||
@ -171,7 +170,7 @@ public:
|
||||
}
|
||||
|
||||
void SetPathname(const nsAString& aPathname,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
nsIPrincipal& aSubjectPrincipal,
|
||||
ErrorResult& aError)
|
||||
{
|
||||
THROW_AND_RETURN_IF_CALLER_DOESNT_SUBSUME();
|
||||
@ -179,7 +178,7 @@ public:
|
||||
}
|
||||
|
||||
void GetSearch(nsAString& aSeach,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
nsIPrincipal& aSubjectPrincipal,
|
||||
ErrorResult& aError)
|
||||
{
|
||||
THROW_AND_RETURN_IF_CALLER_DOESNT_SUBSUME();
|
||||
@ -187,7 +186,7 @@ public:
|
||||
}
|
||||
|
||||
void SetSearch(const nsAString& aSeach,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
nsIPrincipal& aSubjectPrincipal,
|
||||
ErrorResult& aError)
|
||||
{
|
||||
THROW_AND_RETURN_IF_CALLER_DOESNT_SUBSUME();
|
||||
@ -195,7 +194,7 @@ public:
|
||||
}
|
||||
|
||||
void GetHash(nsAString& aHash,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
nsIPrincipal& aSubjectPrincipal,
|
||||
ErrorResult& aError)
|
||||
{
|
||||
THROW_AND_RETURN_IF_CALLER_DOESNT_SUBSUME();
|
||||
@ -203,7 +202,7 @@ public:
|
||||
}
|
||||
|
||||
void SetHash(const nsAString& aHash,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
nsIPrincipal& aSubjectPrincipal,
|
||||
ErrorResult& aError)
|
||||
{
|
||||
THROW_AND_RETURN_IF_CALLER_DOESNT_SUBSUME();
|
||||
@ -211,7 +210,7 @@ public:
|
||||
}
|
||||
|
||||
void Stringify(nsAString& aRetval,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
nsIPrincipal& aSubjectPrincipal,
|
||||
ErrorResult& aError)
|
||||
{
|
||||
// GetHref checks CallerSubsumes.
|
||||
|
@ -138,11 +138,11 @@ ContentAreaDropListener.prototype =
|
||||
|
||||
let dataTransfer = aEvent.dataTransfer;
|
||||
let types = dataTransfer.types;
|
||||
if (!types.contains("application/x-moz-file") &&
|
||||
!types.contains("text/x-moz-url") &&
|
||||
!types.contains("text/uri-list") &&
|
||||
!types.contains("text/x-moz-text-internal") &&
|
||||
!types.contains("text/plain"))
|
||||
if (!types.includes("application/x-moz-file") &&
|
||||
!types.includes("text/x-moz-url") &&
|
||||
!types.includes("text/uri-list") &&
|
||||
!types.includes("text/x-moz-text-internal") &&
|
||||
!types.includes("text/plain"))
|
||||
return false;
|
||||
|
||||
if (aAllowSameDocument)
|
||||
|
@ -6241,6 +6241,14 @@ nsDocument::LoadBindingDocument(const nsAString& aURI)
|
||||
return rv.StealNSResult();
|
||||
}
|
||||
|
||||
void
|
||||
nsIDocument::LoadBindingDocument(const nsAString& aURI,
|
||||
nsIPrincipal& aSubjectPrincipal,
|
||||
ErrorResult& rv)
|
||||
{
|
||||
LoadBindingDocument(aURI, Some(&aSubjectPrincipal), rv);
|
||||
}
|
||||
|
||||
void
|
||||
nsIDocument::LoadBindingDocument(const nsAString& aURI,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
|
@ -6817,13 +6817,12 @@ nsGlobalWindow::CanMoveResizeWindows(bool aCallerIsChrome)
|
||||
bool
|
||||
nsGlobalWindow::AlertOrConfirm(bool aAlert,
|
||||
const nsAString& aMessage,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
nsIPrincipal& aSubjectPrincipal,
|
||||
ErrorResult& aError)
|
||||
{
|
||||
// XXX This method is very similar to nsGlobalWindow::Prompt, make
|
||||
// sure any modifications here don't need to happen over there!
|
||||
MOZ_ASSERT(IsOuterWindow());
|
||||
MOZ_ASSERT(aSubjectPrincipal.isSome());
|
||||
|
||||
if (!AreDialogsEnabled()) {
|
||||
// Just silently return. In the case of alert(), the return value is
|
||||
@ -6842,7 +6841,7 @@ nsGlobalWindow::AlertOrConfirm(bool aAlert,
|
||||
EnsureReflowFlushAndPaint();
|
||||
|
||||
nsAutoString title;
|
||||
MakeScriptDialogTitle(title, aSubjectPrincipal.value());
|
||||
MakeScriptDialogTitle(title, &aSubjectPrincipal);
|
||||
|
||||
// Remove non-terminating null characters from the
|
||||
// string. See bug #310037.
|
||||
@ -6895,7 +6894,7 @@ nsGlobalWindow::AlertOrConfirm(bool aAlert,
|
||||
}
|
||||
|
||||
void
|
||||
nsGlobalWindow::Alert(const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
nsGlobalWindow::Alert(nsIPrincipal& aSubjectPrincipal,
|
||||
ErrorResult& aError)
|
||||
{
|
||||
MOZ_ASSERT(IsInnerWindow());
|
||||
@ -6904,7 +6903,7 @@ nsGlobalWindow::Alert(const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
|
||||
void
|
||||
nsGlobalWindow::AlertOuter(const nsAString& aMessage,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
nsIPrincipal& aSubjectPrincipal,
|
||||
ErrorResult& aError)
|
||||
{
|
||||
MOZ_RELEASE_ASSERT(IsOuterWindow());
|
||||
@ -6913,7 +6912,7 @@ nsGlobalWindow::AlertOuter(const nsAString& aMessage,
|
||||
|
||||
void
|
||||
nsGlobalWindow::Alert(const nsAString& aMessage,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
nsIPrincipal& aSubjectPrincipal,
|
||||
ErrorResult& aError)
|
||||
{
|
||||
FORWARD_TO_OUTER_OR_THROW(AlertOuter, (aMessage, aSubjectPrincipal, aError),
|
||||
@ -6922,7 +6921,7 @@ nsGlobalWindow::Alert(const nsAString& aMessage,
|
||||
|
||||
bool
|
||||
nsGlobalWindow::ConfirmOuter(const nsAString& aMessage,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
nsIPrincipal& aSubjectPrincipal,
|
||||
ErrorResult& aError)
|
||||
{
|
||||
MOZ_RELEASE_ASSERT(IsOuterWindow());
|
||||
@ -6933,7 +6932,7 @@ nsGlobalWindow::ConfirmOuter(const nsAString& aMessage,
|
||||
|
||||
bool
|
||||
nsGlobalWindow::Confirm(const nsAString& aMessage,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
nsIPrincipal& aSubjectPrincipal,
|
||||
ErrorResult& aError)
|
||||
{
|
||||
FORWARD_TO_OUTER_OR_THROW(ConfirmOuter, (aMessage, aSubjectPrincipal, aError),
|
||||
@ -6951,13 +6950,12 @@ void
|
||||
nsGlobalWindow::PromptOuter(const nsAString& aMessage,
|
||||
const nsAString& aInitial,
|
||||
nsAString& aReturn,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
nsIPrincipal& aSubjectPrincipal,
|
||||
ErrorResult& aError)
|
||||
{
|
||||
// XXX This method is very similar to nsGlobalWindow::AlertOrConfirm, make
|
||||
// sure any modifications here don't need to happen over there!
|
||||
MOZ_RELEASE_ASSERT(IsOuterWindow());
|
||||
MOZ_ASSERT(aSubjectPrincipal.isSome());
|
||||
|
||||
SetDOMStringToNull(aReturn);
|
||||
|
||||
@ -6976,7 +6974,7 @@ nsGlobalWindow::PromptOuter(const nsAString& aMessage,
|
||||
EnsureReflowFlushAndPaint();
|
||||
|
||||
nsAutoString title;
|
||||
MakeScriptDialogTitle(title, aSubjectPrincipal.value());
|
||||
MakeScriptDialogTitle(title, &aSubjectPrincipal);
|
||||
|
||||
// Remove non-terminating null characters from the
|
||||
// string. See bug #310037.
|
||||
@ -7037,7 +7035,7 @@ nsGlobalWindow::PromptOuter(const nsAString& aMessage,
|
||||
void
|
||||
nsGlobalWindow::Prompt(const nsAString& aMessage, const nsAString& aInitial,
|
||||
nsAString& aReturn,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
nsIPrincipal& aSubjectPrincipal,
|
||||
ErrorResult& aError)
|
||||
{
|
||||
FORWARD_TO_OUTER_OR_THROW(PromptOuter,
|
||||
@ -8283,11 +8281,10 @@ void
|
||||
nsGlobalWindow::PostMessageMozOuter(JSContext* aCx, JS::Handle<JS::Value> aMessage,
|
||||
const nsAString& aTargetOrigin,
|
||||
JS::Handle<JS::Value> aTransfer,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
nsIPrincipal& aSubjectPrincipal,
|
||||
ErrorResult& aError)
|
||||
{
|
||||
MOZ_RELEASE_ASSERT(IsOuterWindow());
|
||||
MOZ_ASSERT(aSubjectPrincipal.isSome());
|
||||
|
||||
//
|
||||
// Window.postMessage is an intentional subversion of the same-origin policy.
|
||||
@ -8370,7 +8367,7 @@ nsGlobalWindow::PostMessageMozOuter(JSContext* aCx, JS::Handle<JS::Value> aMessa
|
||||
}
|
||||
|
||||
PrincipalOriginAttributes attrs =
|
||||
BasePrincipal::Cast(aSubjectPrincipal.value())->OriginAttributesRef();
|
||||
BasePrincipal::Cast(&aSubjectPrincipal)->OriginAttributesRef();
|
||||
// Create a nsIPrincipal inheriting the app/browser attributes from the
|
||||
// caller.
|
||||
providedPrincipal = BasePrincipal::CreateCodebasePrincipal(originURI, attrs);
|
||||
@ -8408,7 +8405,7 @@ void
|
||||
nsGlobalWindow::PostMessageMoz(JSContext* aCx, JS::Handle<JS::Value> aMessage,
|
||||
const nsAString& aTargetOrigin,
|
||||
JS::Handle<JS::Value> aTransfer,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
nsIPrincipal& aSubjectPrincipal,
|
||||
ErrorResult& aError)
|
||||
{
|
||||
FORWARD_TO_OUTER_OR_THROW(PostMessageMozOuter,
|
||||
@ -8421,7 +8418,7 @@ void
|
||||
nsGlobalWindow::PostMessageMoz(JSContext* aCx, JS::Handle<JS::Value> aMessage,
|
||||
const nsAString& aTargetOrigin,
|
||||
const Optional<Sequence<JS::Value>>& aTransfer,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
nsIPrincipal& aSubjectPrincipal,
|
||||
ErrorResult& aError)
|
||||
{
|
||||
JS::Rooted<JS::Value> transferArray(aCx, JS::UndefinedValue());
|
||||
@ -9049,10 +9046,9 @@ nsGlobalWindow::CacheXBLPrototypeHandler(nsXBLPrototypeHandler* aKey,
|
||||
}
|
||||
|
||||
Element*
|
||||
nsGlobalWindow::GetFrameElementOuter(const Maybe<nsIPrincipal*>& aSubjectPrincipal)
|
||||
nsGlobalWindow::GetFrameElementOuter(nsIPrincipal& aSubjectPrincipal)
|
||||
{
|
||||
MOZ_RELEASE_ASSERT(IsOuterWindow());
|
||||
MOZ_ASSERT(aSubjectPrincipal.isSome());
|
||||
|
||||
if (!mDocShell || mDocShell->GetIsMozBrowserOrApp()) {
|
||||
return nullptr;
|
||||
@ -9064,8 +9060,7 @@ nsGlobalWindow::GetFrameElementOuter(const Maybe<nsIPrincipal*>& aSubjectPrincip
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!aSubjectPrincipal.value()->
|
||||
SubsumesConsideringDomain(element->NodePrincipal())) {
|
||||
if (!aSubjectPrincipal.SubsumesConsideringDomain(element->NodePrincipal())) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@ -9073,7 +9068,7 @@ nsGlobalWindow::GetFrameElementOuter(const Maybe<nsIPrincipal*>& aSubjectPrincip
|
||||
}
|
||||
|
||||
Element*
|
||||
nsGlobalWindow::GetFrameElement(const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
nsGlobalWindow::GetFrameElement(nsIPrincipal& aSubjectPrincipal,
|
||||
ErrorResult& aError)
|
||||
{
|
||||
FORWARD_TO_OUTER_OR_THROW(GetFrameElementOuter, (aSubjectPrincipal), aError,
|
||||
@ -9252,11 +9247,10 @@ already_AddRefed<nsIVariant>
|
||||
nsGlobalWindow::ShowModalDialogOuter(const nsAString& aUrl,
|
||||
nsIVariant* aArgument,
|
||||
const nsAString& aOptions,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
nsIPrincipal& aSubjectPrincipal,
|
||||
ErrorResult& aError)
|
||||
{
|
||||
MOZ_RELEASE_ASSERT(IsOuterWindow());
|
||||
MOZ_ASSERT(aSubjectPrincipal.isSome());
|
||||
|
||||
if (mDoc) {
|
||||
mDoc->WarnOnceAbout(nsIDocument::eShowModalDialog);
|
||||
@ -9268,7 +9262,7 @@ nsGlobalWindow::ShowModalDialogOuter(const nsAString& aUrl,
|
||||
}
|
||||
|
||||
RefPtr<DialogValueHolder> argHolder =
|
||||
new DialogValueHolder(aSubjectPrincipal.value(), aArgument);
|
||||
new DialogValueHolder(&aSubjectPrincipal, aArgument);
|
||||
|
||||
// Before bringing up the window/dialog, unsuppress painting and flush
|
||||
// pending reflows.
|
||||
@ -9325,7 +9319,7 @@ nsGlobalWindow::ShowModalDialogOuter(const nsAString& aUrl,
|
||||
already_AddRefed<nsIVariant>
|
||||
nsGlobalWindow::ShowModalDialog(const nsAString& aUrl, nsIVariant* aArgument,
|
||||
const nsAString& aOptions,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
nsIPrincipal& aSubjectPrincipal,
|
||||
ErrorResult& aError)
|
||||
{
|
||||
FORWARD_TO_OUTER_OR_THROW(ShowModalDialogOuter,
|
||||
@ -9338,7 +9332,7 @@ nsGlobalWindow::ShowModalDialog(JSContext* aCx, const nsAString& aUrl,
|
||||
JS::Handle<JS::Value> aArgument,
|
||||
const nsAString& aOptions,
|
||||
JS::MutableHandle<JS::Value> aRetval,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
nsIPrincipal& aSubjectPrincipal,
|
||||
ErrorResult& aError)
|
||||
{
|
||||
MOZ_ASSERT(IsInnerWindow());
|
||||
@ -10587,8 +10581,7 @@ nsGlobalWindow::GetSessionStorage(ErrorResult& aError)
|
||||
}
|
||||
|
||||
DOMStorage*
|
||||
nsGlobalWindow::GetLocalStorage(const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
ErrorResult& aError)
|
||||
nsGlobalWindow::GetLocalStorage(ErrorResult& aError)
|
||||
{
|
||||
MOZ_RELEASE_ASSERT(IsInnerWindow());
|
||||
|
||||
@ -10597,7 +10590,8 @@ nsGlobalWindow::GetLocalStorage(const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
}
|
||||
|
||||
if (!mLocalStorage) {
|
||||
if (!DOMStorage::CanUseStorage(AsInner(), aSubjectPrincipal)) {
|
||||
if (nsContentUtils::StorageAllowedForWindow(AsInner()) ==
|
||||
nsContentUtils::StorageAccess::eDeny) {
|
||||
aError.Throw(NS_ERROR_DOM_SECURITY_ERR);
|
||||
return nullptr;
|
||||
}
|
||||
@ -11663,10 +11657,7 @@ nsGlobalWindow::CloneStorageEvent(const nsAString& aType,
|
||||
|
||||
RefPtr<DOMStorage> storage;
|
||||
if (storageArea->GetType() == DOMStorage::LocalStorage) {
|
||||
storage = GetLocalStorage(nsContentUtils::GetCurrentJSContext()
|
||||
? Some(nsContentUtils::SubjectPrincipal())
|
||||
: Nothing(),
|
||||
aRv);
|
||||
storage = GetLocalStorage(aRv);
|
||||
} else {
|
||||
MOZ_ASSERT(storageArea->GetType() == DOMStorage::SessionStorage);
|
||||
storage = GetSessionStorage(aRv);
|
||||
@ -14001,11 +13992,10 @@ NS_IMPL_RELEASE_INHERITED(nsGlobalModalWindow, nsGlobalWindow)
|
||||
void
|
||||
nsGlobalWindow::GetDialogArgumentsOuter(JSContext* aCx,
|
||||
JS::MutableHandle<JS::Value> aRetval,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
nsIPrincipal& aSubjectPrincipal,
|
||||
ErrorResult& aError)
|
||||
{
|
||||
MOZ_RELEASE_ASSERT(IsOuterWindow());
|
||||
MOZ_ASSERT(aSubjectPrincipal.isSome());
|
||||
MOZ_ASSERT(IsModalContentWindow(),
|
||||
"This should only be called on modal windows!");
|
||||
|
||||
@ -14019,14 +14009,13 @@ nsGlobalWindow::GetDialogArgumentsOuter(JSContext* aCx,
|
||||
// does not subsumes the origin of the arguments.
|
||||
JS::Rooted<JSObject*> wrapper(aCx, GetWrapper());
|
||||
JSAutoCompartment ac(aCx, wrapper);
|
||||
mDialogArguments->Get(aCx, wrapper, aSubjectPrincipal.value(),
|
||||
aRetval, aError);
|
||||
mDialogArguments->Get(aCx, wrapper, &aSubjectPrincipal, aRetval, aError);
|
||||
}
|
||||
|
||||
void
|
||||
nsGlobalWindow::GetDialogArguments(JSContext* aCx,
|
||||
JS::MutableHandle<JS::Value> aRetval,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
nsIPrincipal& aSubjectPrincipal,
|
||||
ErrorResult& aError)
|
||||
{
|
||||
FORWARD_TO_OUTER_OR_THROW(GetDialogArgumentsOuter,
|
||||
@ -14070,19 +14059,17 @@ nsGlobalWindow::InitWasOffline()
|
||||
void
|
||||
nsGlobalWindow::GetReturnValueOuter(JSContext* aCx,
|
||||
JS::MutableHandle<JS::Value> aReturnValue,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
nsIPrincipal& aSubjectPrincipal,
|
||||
ErrorResult& aError)
|
||||
{
|
||||
MOZ_RELEASE_ASSERT(IsOuterWindow());
|
||||
MOZ_ASSERT(aSubjectPrincipal.isSome());
|
||||
MOZ_ASSERT(IsModalContentWindow(),
|
||||
"This should only be called on modal windows!");
|
||||
|
||||
if (mReturnValue) {
|
||||
JS::Rooted<JSObject*> wrapper(aCx, GetWrapper());
|
||||
JSAutoCompartment ac(aCx, wrapper);
|
||||
mReturnValue->Get(aCx, wrapper, aSubjectPrincipal.value(),
|
||||
aReturnValue, aError);
|
||||
mReturnValue->Get(aCx, wrapper, &aSubjectPrincipal, aReturnValue, aError);
|
||||
} else {
|
||||
aReturnValue.setUndefined();
|
||||
}
|
||||
@ -14091,7 +14078,7 @@ nsGlobalWindow::GetReturnValueOuter(JSContext* aCx,
|
||||
void
|
||||
nsGlobalWindow::GetReturnValue(JSContext* aCx,
|
||||
JS::MutableHandle<JS::Value> aReturnValue,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
nsIPrincipal& aSubjectPrincipal,
|
||||
ErrorResult& aError)
|
||||
{
|
||||
FORWARD_TO_OUTER_OR_THROW(GetReturnValueOuter,
|
||||
@ -14115,11 +14102,10 @@ nsGlobalModalWindow::GetReturnValue(nsIVariant **aRetVal)
|
||||
void
|
||||
nsGlobalWindow::SetReturnValueOuter(JSContext* aCx,
|
||||
JS::Handle<JS::Value> aReturnValue,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
nsIPrincipal& aSubjectPrincipal,
|
||||
ErrorResult& aError)
|
||||
{
|
||||
MOZ_RELEASE_ASSERT(IsOuterWindow());
|
||||
MOZ_ASSERT(aSubjectPrincipal.isSome());
|
||||
MOZ_ASSERT(IsModalContentWindow(),
|
||||
"This should only be called on modal windows!");
|
||||
|
||||
@ -14128,15 +14114,14 @@ nsGlobalWindow::SetReturnValueOuter(JSContext* aCx,
|
||||
nsContentUtils::XPConnect()->JSToVariant(aCx, aReturnValue,
|
||||
getter_AddRefs(returnValue));
|
||||
if (!aError.Failed()) {
|
||||
mReturnValue = new DialogValueHolder(aSubjectPrincipal.value(),
|
||||
returnValue);
|
||||
mReturnValue = new DialogValueHolder(&aSubjectPrincipal, returnValue);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsGlobalWindow::SetReturnValue(JSContext* aCx,
|
||||
JS::Handle<JS::Value> aReturnValue,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
nsIPrincipal& aSubjectPrincipal,
|
||||
ErrorResult& aError)
|
||||
{
|
||||
FORWARD_TO_OUTER_OR_THROW(SetReturnValueOuter,
|
||||
|
@ -937,9 +937,9 @@ public:
|
||||
nsPIDOMWindowOuter* GetScriptableParent() override;
|
||||
nsPIDOMWindowOuter* GetScriptableParentOrNull() override;
|
||||
mozilla::dom::Element*
|
||||
GetFrameElementOuter(const mozilla::Maybe<nsIPrincipal*>& aSubjectPrincipal);
|
||||
GetFrameElementOuter(nsIPrincipal& aSubjectPrincipal);
|
||||
mozilla::dom::Element*
|
||||
GetFrameElement(const mozilla::Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
GetFrameElement(nsIPrincipal& aSubjectPrincipal,
|
||||
mozilla::ErrorResult& aError);
|
||||
already_AddRefed<nsIDOMElement> GetFrameElement() override;
|
||||
already_AddRefed<nsPIDOMWindowOuter>
|
||||
@ -982,31 +982,31 @@ public:
|
||||
|
||||
protected:
|
||||
bool AlertOrConfirm(bool aAlert, const nsAString& aMessage,
|
||||
const mozilla::Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
nsIPrincipal& aSubjectPrincipal,
|
||||
mozilla::ErrorResult& aError);
|
||||
|
||||
public:
|
||||
void Alert(const mozilla::Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
void Alert(nsIPrincipal& aSubjectPrincipal,
|
||||
mozilla::ErrorResult& aError);
|
||||
void AlertOuter(const nsAString& aMessage,
|
||||
const mozilla::Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
nsIPrincipal& aSubjectPrincipal,
|
||||
mozilla::ErrorResult& aError);
|
||||
void Alert(const nsAString& aMessage,
|
||||
const mozilla::Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
nsIPrincipal& aSubjectPrincipal,
|
||||
mozilla::ErrorResult& aError);
|
||||
bool ConfirmOuter(const nsAString& aMessage,
|
||||
const mozilla::Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
nsIPrincipal& aSubjectPrincipal,
|
||||
mozilla::ErrorResult& aError);
|
||||
bool Confirm(const nsAString& aMessage,
|
||||
const mozilla::Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
nsIPrincipal& aSubjectPrincipal,
|
||||
mozilla::ErrorResult& aError);
|
||||
void PromptOuter(const nsAString& aMessage, const nsAString& aInitial,
|
||||
nsAString& aReturn,
|
||||
const mozilla::Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
nsIPrincipal& aSubjectPrincipal,
|
||||
mozilla::ErrorResult& aError);
|
||||
void Prompt(const nsAString& aMessage, const nsAString& aInitial,
|
||||
nsAString& aReturn,
|
||||
const mozilla::Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
nsIPrincipal& aSubjectPrincipal,
|
||||
mozilla::ErrorResult& aError);
|
||||
already_AddRefed<mozilla::dom::cache::CacheStorage> GetCaches(mozilla::ErrorResult& aRv);
|
||||
already_AddRefed<mozilla::dom::Promise> Fetch(const mozilla::dom::RequestOrUSVString& aInput,
|
||||
@ -1018,12 +1018,12 @@ public:
|
||||
JS::Handle<JS::Value> aArgument,
|
||||
const nsAString& aOptions,
|
||||
JS::MutableHandle<JS::Value> aRetval,
|
||||
const mozilla::Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
nsIPrincipal& aSubjectPrincipal,
|
||||
mozilla::ErrorResult& aError);
|
||||
void PostMessageMoz(JSContext* aCx, JS::Handle<JS::Value> aMessage,
|
||||
const nsAString& aTargetOrigin,
|
||||
const mozilla::dom::Optional<mozilla::dom::Sequence<JS::Value > >& aTransfer,
|
||||
const mozilla::Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
nsIPrincipal& aSubjectPrincipal,
|
||||
mozilla::ErrorResult& aError);
|
||||
int32_t SetTimeout(JSContext* aCx, mozilla::dom::Function& aFunction,
|
||||
int32_t aTimeout,
|
||||
@ -1049,8 +1049,7 @@ public:
|
||||
mozilla::ErrorResult& aError);
|
||||
mozilla::dom::DOMStorage* GetSessionStorage(mozilla::ErrorResult& aError);
|
||||
mozilla::dom::DOMStorage*
|
||||
GetLocalStorage(const mozilla::Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
mozilla::ErrorResult& aError);
|
||||
GetLocalStorage(mozilla::ErrorResult& aError);
|
||||
mozilla::dom::Selection* GetSelectionOuter();
|
||||
mozilla::dom::Selection* GetSelection(mozilla::ErrorResult& aError);
|
||||
already_AddRefed<nsISelection> GetSelection() override;
|
||||
@ -1270,22 +1269,22 @@ public:
|
||||
mozilla::ErrorResult& aError);
|
||||
|
||||
void GetDialogArgumentsOuter(JSContext* aCx, JS::MutableHandle<JS::Value> aRetval,
|
||||
const mozilla::Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
nsIPrincipal& aSubjectPrincipal,
|
||||
mozilla::ErrorResult& aError);
|
||||
void GetDialogArguments(JSContext* aCx, JS::MutableHandle<JS::Value> aRetval,
|
||||
const mozilla::Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
nsIPrincipal& aSubjectPrincipal,
|
||||
mozilla::ErrorResult& aError);
|
||||
void GetReturnValueOuter(JSContext* aCx, JS::MutableHandle<JS::Value> aReturnValue,
|
||||
const mozilla::Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
nsIPrincipal& aSubjectPrincipal,
|
||||
mozilla::ErrorResult& aError);
|
||||
void GetReturnValue(JSContext* aCx, JS::MutableHandle<JS::Value> aReturnValue,
|
||||
const mozilla::Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
nsIPrincipal& aSubjectPrincipal,
|
||||
mozilla::ErrorResult& aError);
|
||||
void SetReturnValueOuter(JSContext* aCx, JS::Handle<JS::Value> aReturnValue,
|
||||
const mozilla::Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
nsIPrincipal& aSubjectPrincipal,
|
||||
mozilla::ErrorResult& aError);
|
||||
void SetReturnValue(JSContext* aCx, JS::Handle<JS::Value> aReturnValue,
|
||||
const mozilla::Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
nsIPrincipal& aSubjectPrincipal,
|
||||
mozilla::ErrorResult& aError);
|
||||
|
||||
void GetInterface(JSContext* aCx, nsIJSID* aIID,
|
||||
@ -1708,24 +1707,24 @@ protected:
|
||||
void PostMessageMozOuter(JSContext* aCx, JS::Handle<JS::Value> aMessage,
|
||||
const nsAString& aTargetOrigin,
|
||||
JS::Handle<JS::Value> aTransfer,
|
||||
const mozilla::Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
nsIPrincipal& aSubjectPrincipal,
|
||||
mozilla::ErrorResult& aError);
|
||||
void PostMessageMoz(JSContext* aCx, JS::Handle<JS::Value> aMessage,
|
||||
const nsAString& aTargetOrigin,
|
||||
JS::Handle<JS::Value> aTransfer,
|
||||
const mozilla::Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
nsIPrincipal& aSubjectPrincipal,
|
||||
mozilla::ErrorResult& aError);
|
||||
|
||||
already_AddRefed<nsIVariant>
|
||||
ShowModalDialogOuter(const nsAString& aUrl, nsIVariant* aArgument,
|
||||
const nsAString& aOptions,
|
||||
const mozilla::Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
nsIPrincipal& aSubjectPrincipal,
|
||||
mozilla::ErrorResult& aError);
|
||||
|
||||
already_AddRefed<nsIVariant>
|
||||
ShowModalDialog(const nsAString& aUrl, nsIVariant* aArgument,
|
||||
const nsAString& aOptions,
|
||||
const mozilla::Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
nsIPrincipal& aSubjectPrincipal,
|
||||
mozilla::ErrorResult& aError);
|
||||
|
||||
// Ask the user if further dialogs should be blocked, if dialogs are currently
|
||||
|
@ -2687,6 +2687,9 @@ public:
|
||||
const nsAString& aAttrName,
|
||||
const nsAString& aAttrValue);
|
||||
Element* GetBindingParent(nsINode& aNode);
|
||||
void LoadBindingDocument(const nsAString& aURI,
|
||||
nsIPrincipal& aSubjectPrincipal,
|
||||
mozilla::ErrorResult& rv);
|
||||
void LoadBindingDocument(const nsAString& aURI,
|
||||
const mozilla::Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
mozilla::ErrorResult& rv);
|
||||
|
@ -3537,10 +3537,8 @@ nsObjectLoadingContent::ShouldPlay(FallbackType &aReason, bool aIgnoreCurrentTyp
|
||||
}
|
||||
|
||||
nsIDocument*
|
||||
nsObjectLoadingContent::GetContentDocument(const mozilla::Maybe<nsIPrincipal*>& aSubjectPrincipal)
|
||||
nsObjectLoadingContent::GetContentDocument(nsIPrincipal& aSubjectPrincipal)
|
||||
{
|
||||
MOZ_ASSERT(aSubjectPrincipal.isSome());
|
||||
|
||||
nsCOMPtr<nsIContent> thisContent =
|
||||
do_QueryInterface(static_cast<nsIImageLoadingContent*>(this));
|
||||
|
||||
@ -3554,7 +3552,7 @@ nsObjectLoadingContent::GetContentDocument(const mozilla::Maybe<nsIPrincipal*>&
|
||||
}
|
||||
|
||||
// Return null for cross-origin contentDocument.
|
||||
if (!aSubjectPrincipal.value()->SubsumesConsideringDomain(sub_doc->NodePrincipal())) {
|
||||
if (!aSubjectPrincipal.SubsumesConsideringDomain(sub_doc->NodePrincipal())) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
@ -180,7 +180,7 @@ class nsObjectLoadingContent : public nsImageLoadingContent
|
||||
mozilla::ErrorResult& aRv);
|
||||
|
||||
// WebIDL API
|
||||
nsIDocument* GetContentDocument(const mozilla::Maybe<nsIPrincipal*>& aSubjectPrincipal);
|
||||
nsIDocument* GetContentDocument(nsIPrincipal& aSubjectPrincipal);
|
||||
void GetActualType(nsAString& aType) const
|
||||
{
|
||||
CopyUTF8toUTF16(mContentType, aType);
|
||||
|
@ -6907,13 +6907,13 @@ class CGCallGenerator(CGThing):
|
||||
value, resultVar can be omitted.
|
||||
"""
|
||||
def __init__(self, isFallible, needsSubjectPrincipal, arguments, argsPre,
|
||||
returnType, extendedAttributes, descriptorProvider,
|
||||
returnType, extendedAttributes, descriptor,
|
||||
nativeMethodName, static, object="self", argsPost=[],
|
||||
resultVar=None):
|
||||
CGThing.__init__(self)
|
||||
|
||||
result, resultOutParam, resultRooter, resultArgs, resultConversion = \
|
||||
getRetvalDeclarationForType(returnType, descriptorProvider)
|
||||
getRetvalDeclarationForType(returnType, descriptor)
|
||||
|
||||
args = CGList([CGGeneric(arg) for arg in argsPre], ", ")
|
||||
for a, name in arguments:
|
||||
@ -7008,16 +7008,32 @@ class CGCallGenerator(CGThing):
|
||||
self.cgRoot.append(call)
|
||||
|
||||
if needsSubjectPrincipal:
|
||||
self.cgRoot.prepend(CGGeneric(dedent(
|
||||
"""
|
||||
Maybe<nsIPrincipal*> subjectPrincipal;
|
||||
if (NS_IsMainThread()) {
|
||||
JSCompartment* compartment = js::GetContextCompartment(cx);
|
||||
MOZ_ASSERT(compartment);
|
||||
JSPrincipals* principals = JS_GetCompartmentPrincipals(compartment);
|
||||
subjectPrincipal.emplace(nsJSPrincipals::get(principals));
|
||||
}
|
||||
""")))
|
||||
getPrincipal = dedent(
|
||||
"""
|
||||
JSCompartment* compartment = js::GetContextCompartment(cx);
|
||||
MOZ_ASSERT(compartment);
|
||||
JSPrincipals* principals = JS_GetCompartmentPrincipals(compartment);
|
||||
""")
|
||||
|
||||
if descriptor.interface.isExposedInAnyWorker():
|
||||
self.cgRoot.prepend(CGGeneric(fill(
|
||||
"""
|
||||
Maybe<nsIPrincipal*> subjectPrincipal;
|
||||
if (NS_IsMainThread()) {
|
||||
$*{getPrincipal}
|
||||
subjectPrincipal.emplace(nsJSPrincipals::get(principals));
|
||||
}
|
||||
""",
|
||||
getPrincipal=getPrincipal)))
|
||||
else:
|
||||
self.cgRoot.prepend(CGGeneric(fill(
|
||||
"""
|
||||
$*{getPrincipal}
|
||||
// Initializing a nonnull is pretty darn annoying...
|
||||
NonNull<nsIPrincipal> subjectPrincipal;
|
||||
subjectPrincipal = static_cast<nsIPrincipal*>(nsJSPrincipals::get(principals));
|
||||
""",
|
||||
getPrincipal=getPrincipal)))
|
||||
|
||||
if isFallible:
|
||||
self.cgRoot.prepend(CGGeneric("binding_detail::FastErrorResult rv;\n"))
|
||||
@ -13993,7 +14009,7 @@ class CGNativeMember(ClassMethod):
|
||||
|
||||
# And the nsIPrincipal
|
||||
if self.member.getExtendedAttribute('NeedsSubjectPrincipal'):
|
||||
args.append(Argument("const Maybe<nsIPrincipal*>&", "aPrincipal"))
|
||||
args.append(Argument("nsIPrincipal&", "aPrincipal"))
|
||||
# And the ErrorResult
|
||||
if 'infallible' not in self.extendedAttrs:
|
||||
# Use aRv so it won't conflict with local vars named "rv"
|
||||
|
@ -933,6 +933,9 @@ public:
|
||||
void SetThrowingGetterAttr(bool arg);
|
||||
bool ThrowingSetterAttr() const;
|
||||
void SetThrowingSetterAttr(bool arg, ErrorResult& aRv);
|
||||
void NeedsSubjectPrincipalMethod(nsIPrincipal&);
|
||||
bool NeedsSubjectPrincipalAttr(nsIPrincipal&);
|
||||
void SetNeedsSubjectPrincipalAttr(bool, nsIPrincipal&);
|
||||
int16_t LegacyCall(const JS::Value&, uint32_t, TestInterface&);
|
||||
void PassArgsWithDefaults(JSContext*, const Optional<int32_t>&,
|
||||
TestInterface*, const Dict&, double,
|
||||
|
@ -943,6 +943,8 @@ interface TestInterface {
|
||||
[Throws] attribute boolean throwingAttr;
|
||||
[GetterThrows] attribute boolean throwingGetterAttr;
|
||||
[SetterThrows] attribute boolean throwingSetterAttr;
|
||||
[NeedsSubjectPrincipal] void needsSubjectPrincipalMethod();
|
||||
[NeedsSubjectPrincipal] attribute boolean needsSubjectPrincipalAttr;
|
||||
legacycaller short(unsigned long arg1, TestInterface arg2);
|
||||
void passArgsWithDefaults(optional long arg1,
|
||||
optional TestInterface? arg2 = null,
|
||||
|
@ -794,6 +794,10 @@ interface TestJSImplInterface {
|
||||
[Throws] attribute boolean throwingAttr;
|
||||
[GetterThrows] attribute boolean throwingGetterAttr;
|
||||
[SetterThrows] attribute boolean throwingSetterAttr;
|
||||
// NeedsSubjectPrincipal not supported on JS-implemented things for
|
||||
// now, because we always pass in the caller principal anyway.
|
||||
// [NeedsSubjectPrincipal] void needsSubjectPrincipalMethod();
|
||||
// [NeedsSubjectPrincipal] attribute boolean needsSubjectPrincipalAttr;
|
||||
// legacycaller short(unsigned long arg1, TestInterface arg2);
|
||||
void passArgsWithDefaults(optional long arg1,
|
||||
optional TestInterface? arg2 = null,
|
||||
|
@ -76,7 +76,7 @@ ClipboardEvent::Constructor(const GlobalObject& aGlobal,
|
||||
// checked properly within DataTransfer.
|
||||
clipboardData = new DataTransfer(ToSupports(e), eCopy, false, -1);
|
||||
clipboardData->SetData(aParam.mDataType, aParam.mData,
|
||||
Some(aGlobal.GetSubjectPrincipal()), aRv);
|
||||
*aGlobal.GetSubjectPrincipal(), aRv);
|
||||
NS_ENSURE_TRUE(!aRv.Failed(), nullptr);
|
||||
}
|
||||
}
|
||||
|
@ -284,11 +284,10 @@ DataTransfer::GetMozUserCancelled(bool* aUserCancelled)
|
||||
}
|
||||
|
||||
already_AddRefed<FileList>
|
||||
DataTransfer::GetFiles(const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
DataTransfer::GetFiles(nsIPrincipal& aSubjectPrincipal,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
MOZ_ASSERT(aSubjectPrincipal.isSome());
|
||||
return mItems->Files(aSubjectPrincipal.value());
|
||||
return mItems->Files(&aSubjectPrincipal);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
@ -310,21 +309,24 @@ DataTransfer::GetFiles(nsIDOMFileList** aFileList)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
already_AddRefed<DOMStringList>
|
||||
DataTransfer::GetTypes(ErrorResult& aRv) const
|
||||
void
|
||||
DataTransfer::GetTypes(nsTArray<nsString>& aTypes,
|
||||
nsIPrincipal& aSubjectPrincipal) const
|
||||
{
|
||||
RefPtr<DOMStringList> types = new DOMStringList();
|
||||
|
||||
// When called from bindings, aTypes will be empty, but since we might have
|
||||
// Gecko-internal callers too, clear it to be safe.
|
||||
aTypes.Clear();
|
||||
|
||||
const nsTArray<RefPtr<DataTransferItem>>* items = mItems->MozItemsAt(0);
|
||||
if (NS_WARN_IF(!items)) {
|
||||
return types.forget();
|
||||
return;
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < items->Length(); i++) {
|
||||
DataTransferItem* item = items->ElementAt(i);
|
||||
MOZ_ASSERT(item);
|
||||
|
||||
if (item->ChromeOnly() && !nsContentUtils::LegacyIsCallerChromeOrNativeCode()) {
|
||||
if (item->ChromeOnly() && !nsContentUtils::IsSystemPrincipal(&aSubjectPrincipal)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -332,61 +334,33 @@ DataTransfer::GetTypes(ErrorResult& aRv) const
|
||||
item->GetType(type);
|
||||
if (item->Kind() == DataTransferItem::KIND_STRING || type.EqualsASCII(kFileMime)) {
|
||||
// If the entry has kind KIND_STRING, we want to add it to the list.
|
||||
if (NS_WARN_IF(!types->Add(type))) {
|
||||
aRv.Throw(NS_ERROR_FAILURE);
|
||||
return nullptr;
|
||||
}
|
||||
aTypes.AppendElement(type);
|
||||
}
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < mItems->Length(); ++i) {
|
||||
ErrorResult rv;
|
||||
bool found = false;
|
||||
DataTransferItem* item = mItems->IndexedGetter(i, found, rv);
|
||||
if (!found || rv.Failed() || item->Kind() != DataTransferItem::KIND_FILE) {
|
||||
rv.SuppressException();
|
||||
DataTransferItem* item = mItems->IndexedGetter(i, found);
|
||||
MOZ_ASSERT(found);
|
||||
if (item->Kind() != DataTransferItem::KIND_FILE) {
|
||||
continue;
|
||||
}
|
||||
if (NS_WARN_IF(!types->Add(NS_LITERAL_STRING("Files")))) {
|
||||
aRv.Throw(NS_ERROR_FAILURE);
|
||||
return nullptr;
|
||||
}
|
||||
aTypes.AppendElement(NS_LITERAL_STRING("Files"));
|
||||
break;
|
||||
}
|
||||
|
||||
return types.forget();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
DataTransfer::GetTypes(nsISupports** aTypes)
|
||||
{
|
||||
if (NS_WARN_IF(!aTypes)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
ErrorResult rv;
|
||||
RefPtr<DOMStringList> types = GetTypes(rv);
|
||||
if (NS_WARN_IF(rv.Failed())) {
|
||||
return rv.StealNSResult();
|
||||
}
|
||||
|
||||
types.forget(aTypes);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
DataTransfer::GetData(const nsAString& aFormat, nsAString& aData,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
nsIPrincipal& aSubjectPrincipal,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
MOZ_ASSERT(aSubjectPrincipal.isSome());
|
||||
|
||||
// return an empty string if data for the format was not found
|
||||
aData.Truncate();
|
||||
|
||||
nsCOMPtr<nsIVariant> data;
|
||||
nsresult rv =
|
||||
GetDataAtInternal(aFormat, 0, aSubjectPrincipal.value(),
|
||||
GetDataAtInternal(aFormat, 0, &aSubjectPrincipal,
|
||||
getter_AddRefs(data));
|
||||
if (NS_FAILED(rv)) {
|
||||
if (rv != NS_ERROR_DOM_INDEX_SIZE_ERR) {
|
||||
@ -434,34 +408,22 @@ DataTransfer::GetData(const nsAString& aFormat, nsAString& aData,
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
DataTransfer::GetData(const nsAString& aFormat, nsAString& aData)
|
||||
{
|
||||
ErrorResult rv;
|
||||
GetData(aFormat, aData, Some(nsContentUtils::SubjectPrincipal()), rv);
|
||||
return rv.StealNSResult();
|
||||
}
|
||||
|
||||
void
|
||||
DataTransfer::SetData(const nsAString& aFormat, const nsAString& aData,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
nsIPrincipal& aSubjectPrincipal,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
MOZ_ASSERT(aSubjectPrincipal.isSome());
|
||||
|
||||
RefPtr<nsVariantCC> variant = new nsVariantCC();
|
||||
variant->SetAsAString(aData);
|
||||
|
||||
aRv = SetDataAtInternal(aFormat, variant, 0, aSubjectPrincipal.value());
|
||||
aRv = SetDataAtInternal(aFormat, variant, 0, &aSubjectPrincipal);
|
||||
}
|
||||
|
||||
void
|
||||
DataTransfer::ClearData(const Optional<nsAString>& aFormat,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
nsIPrincipal& aSubjectPrincipal,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
MOZ_ASSERT(aSubjectPrincipal.isSome());
|
||||
|
||||
if (mReadOnly) {
|
||||
aRv.Throw(NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR);
|
||||
return;
|
||||
@ -648,13 +610,11 @@ void
|
||||
DataTransfer::MozGetDataAt(JSContext* aCx, const nsAString& aFormat,
|
||||
uint32_t aIndex,
|
||||
JS::MutableHandle<JS::Value> aRetval,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
nsIPrincipal& aSubjectPrincipal,
|
||||
mozilla::ErrorResult& aRv)
|
||||
{
|
||||
MOZ_ASSERT(aSubjectPrincipal.isSome());
|
||||
|
||||
nsCOMPtr<nsIVariant> data;
|
||||
aRv = GetDataAtInternal(aFormat, aIndex, aSubjectPrincipal.value(),
|
||||
aRv = GetDataAtInternal(aFormat, aIndex, &aSubjectPrincipal,
|
||||
getter_AddRefs(data));
|
||||
if (aRv.Failed()) {
|
||||
return;
|
||||
@ -693,6 +653,12 @@ DataTransfer::PrincipalMaySetData(const nsAString& aType,
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
DataTransfer::TypesListMayHaveChanged()
|
||||
{
|
||||
DataTransferBinding::ClearCachedTypesValue(this);
|
||||
}
|
||||
|
||||
nsresult
|
||||
DataTransfer::SetDataAtInternal(const nsAString& aFormat, nsIVariant* aData,
|
||||
uint32_t aIndex,
|
||||
@ -734,26 +700,22 @@ DataTransfer::SetDataAtInternal(const nsAString& aFormat, nsIVariant* aData,
|
||||
void
|
||||
DataTransfer::MozSetDataAt(JSContext* aCx, const nsAString& aFormat,
|
||||
JS::Handle<JS::Value> aData, uint32_t aIndex,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
nsIPrincipal& aSubjectPrincipal,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
MOZ_ASSERT(aSubjectPrincipal.isSome());
|
||||
|
||||
nsCOMPtr<nsIVariant> data;
|
||||
aRv = nsContentUtils::XPConnect()->JSValToVariant(aCx, aData,
|
||||
getter_AddRefs(data));
|
||||
if (!aRv.Failed()) {
|
||||
aRv = SetDataAtInternal(aFormat, data, aIndex, aSubjectPrincipal.value());
|
||||
aRv = SetDataAtInternal(aFormat, data, aIndex, &aSubjectPrincipal);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
DataTransfer::MozClearDataAt(const nsAString& aFormat, uint32_t aIndex,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
nsIPrincipal& aSubjectPrincipal,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
MOZ_ASSERT(aSubjectPrincipal.isSome());
|
||||
|
||||
if (mReadOnly) {
|
||||
aRv.Throw(NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR);
|
||||
return;
|
||||
@ -788,7 +750,7 @@ DataTransfer::MozClearDataAt(const nsAString& aFormat, uint32_t aIndex,
|
||||
|
||||
void
|
||||
DataTransfer::MozClearDataAtHelper(const nsAString& aFormat, uint32_t aIndex,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
nsIPrincipal& aSubjectPrincipal,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
MOZ_ASSERT(!mReadOnly);
|
||||
@ -796,7 +758,6 @@ DataTransfer::MozClearDataAtHelper(const nsAString& aFormat, uint32_t aIndex,
|
||||
MOZ_ASSERT(aIndex == 0 ||
|
||||
(mEventMessage != eCut && mEventMessage != eCopy &&
|
||||
mEventMessage != ePaste));
|
||||
MOZ_ASSERT(aSubjectPrincipal.isSome());
|
||||
|
||||
nsAutoString format;
|
||||
GetRealFormat(aFormat, format);
|
||||
@ -830,11 +791,9 @@ DataTransfer::SetDragImage(nsIDOMElement* aImage, int32_t aX, int32_t aY)
|
||||
}
|
||||
|
||||
already_AddRefed<Promise>
|
||||
DataTransfer::GetFilesAndDirectories(const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
DataTransfer::GetFilesAndDirectories(nsIPrincipal& aSubjectPrincipal,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
MOZ_ASSERT(aSubjectPrincipal.isSome());
|
||||
|
||||
nsCOMPtr<nsINode> parentNode = do_QueryInterface(mParent);
|
||||
if (!parentNode) {
|
||||
aRv.Throw(NS_ERROR_FAILURE);
|
||||
@ -853,7 +812,7 @@ DataTransfer::GetFilesAndDirectories(const Maybe<nsIPrincipal*>& aSubjectPrincip
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<FileList> files = mItems->Files(aSubjectPrincipal.value());
|
||||
RefPtr<FileList> files = mItems->Files(&aSubjectPrincipal);
|
||||
if (NS_WARN_IF(!files)) {
|
||||
return nullptr;
|
||||
}
|
||||
@ -871,7 +830,7 @@ DataTransfer::GetFilesAndDirectories(const Maybe<nsIPrincipal*>& aSubjectPrincip
|
||||
|
||||
already_AddRefed<Promise>
|
||||
DataTransfer::GetFiles(bool aRecursiveFlag,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
nsIPrincipal& aSubjectPrincipal,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
// Currently we don't support directories.
|
||||
@ -1475,8 +1434,8 @@ DataTransfer::FillInExternalCustomTypes(uint32_t aIndex,
|
||||
nsIPrincipal* aPrincipal)
|
||||
{
|
||||
RefPtr<DataTransferItem> item = new DataTransferItem(this,
|
||||
NS_LITERAL_STRING(kCustomTypesMime));
|
||||
item->SetKind(DataTransferItem::KIND_STRING);
|
||||
NS_LITERAL_STRING(kCustomTypesMime),
|
||||
DataTransferItem::KIND_STRING);
|
||||
item->SetIndex(aIndex);
|
||||
|
||||
nsCOMPtr<nsIVariant> variant = item->DataNoSecurityCheck();
|
||||
|
@ -136,31 +136,32 @@ public:
|
||||
void SetDragImage(Element& aElement, int32_t aX, int32_t aY,
|
||||
ErrorResult& aRv);
|
||||
|
||||
already_AddRefed<DOMStringList> GetTypes(ErrorResult& rv) const;
|
||||
void GetTypes(nsTArray<nsString>& aTypes,
|
||||
nsIPrincipal& aSubjectPrincipal) const;
|
||||
|
||||
void GetData(const nsAString& aFormat, nsAString& aData,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
nsIPrincipal& aSubjectPrincipal,
|
||||
ErrorResult& aRv);
|
||||
|
||||
void SetData(const nsAString& aFormat, const nsAString& aData,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
nsIPrincipal& aSubjectPrincipal,
|
||||
ErrorResult& aRv);
|
||||
|
||||
void ClearData(const mozilla::dom::Optional<nsAString>& aFormat,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
nsIPrincipal& aSubjectPrincipal,
|
||||
mozilla::ErrorResult& aRv);
|
||||
|
||||
already_AddRefed<FileList>
|
||||
GetFiles(const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
GetFiles(nsIPrincipal& aSubjectPrincipal,
|
||||
mozilla::ErrorResult& aRv);
|
||||
|
||||
already_AddRefed<Promise>
|
||||
GetFilesAndDirectories(const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
GetFilesAndDirectories(nsIPrincipal& aSubjectPrincipal,
|
||||
mozilla::ErrorResult& aRv);
|
||||
|
||||
already_AddRefed<Promise>
|
||||
GetFiles(bool aRecursiveFlag,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
nsIPrincipal& aSubjectPrincipal,
|
||||
ErrorResult& aRv);
|
||||
|
||||
|
||||
@ -181,17 +182,17 @@ public:
|
||||
mozilla::ErrorResult& aRv) const;
|
||||
|
||||
void MozClearDataAt(const nsAString& aFormat, uint32_t aIndex,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
nsIPrincipal& aSubjectPrincipal,
|
||||
mozilla::ErrorResult& aRv);
|
||||
|
||||
void MozSetDataAt(JSContext* aCx, const nsAString& aFormat,
|
||||
JS::Handle<JS::Value> aData, uint32_t aIndex,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
nsIPrincipal& aSubjectPrincipal,
|
||||
mozilla::ErrorResult& aRv);
|
||||
|
||||
void MozGetDataAt(JSContext* aCx, const nsAString& aFormat,
|
||||
uint32_t aIndex, JS::MutableHandle<JS::Value> aRetval,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
nsIPrincipal& aSubjectPrincipal,
|
||||
mozilla::ErrorResult& aRv);
|
||||
|
||||
bool MozUserCancelled() const
|
||||
@ -289,6 +290,11 @@ public:
|
||||
nsIVariant* aData,
|
||||
nsIPrincipal* aPrincipal);
|
||||
|
||||
// Notify the DataTransfer that the list returned from GetTypes may have
|
||||
// changed. This can happen due to items we care about for purposes of
|
||||
// GetTypes being added or removed or changing item kinds.
|
||||
void TypesListMayHaveChanged();
|
||||
|
||||
protected:
|
||||
|
||||
// caches text and uri-list data formats that exist in the drag service or
|
||||
@ -321,7 +327,7 @@ protected:
|
||||
nsIPrincipal* aPrincipal);
|
||||
|
||||
void MozClearDataAtHelper(const nsAString& aFormat, uint32_t aIndex,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
nsIPrincipal& aSubjectPrincipal,
|
||||
mozilla::ErrorResult& aRv);
|
||||
|
||||
nsCOMPtr<nsISupports> mParent;
|
||||
|
@ -73,12 +73,6 @@ DataTransferItem::Clone(DataTransfer* aDataTransfer) const
|
||||
return it.forget();
|
||||
}
|
||||
|
||||
void
|
||||
DataTransferItem::SetType(const nsAString& aType)
|
||||
{
|
||||
mType = aType;
|
||||
}
|
||||
|
||||
void
|
||||
DataTransferItem::SetData(nsIVariant* aData)
|
||||
{
|
||||
@ -230,26 +224,23 @@ DataTransferItem::FillInExternalData()
|
||||
|
||||
SetData(variant);
|
||||
|
||||
#ifdef DEBUG
|
||||
if (oldKind != Kind()) {
|
||||
NS_WARNING("Clipboard data provided by the OS does not match predicted kind");
|
||||
mDataTransfer->TypesListMayHaveChanged();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
already_AddRefed<File>
|
||||
DataTransferItem::GetAsFile(const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
DataTransferItem::GetAsFile(nsIPrincipal& aSubjectPrincipal,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
MOZ_ASSERT(aSubjectPrincipal.isSome());
|
||||
|
||||
if (mKind != KIND_FILE) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// This is done even if we have an mCachedFile, as it performs the necessary
|
||||
// permissions checks to ensure that we are allowed to access this type.
|
||||
nsCOMPtr<nsIVariant> data = Data(aSubjectPrincipal.value(), aRv);
|
||||
nsCOMPtr<nsIVariant> data = Data(&aSubjectPrincipal, aRv);
|
||||
if (NS_WARN_IF(!data || aRv.Failed())) {
|
||||
return nullptr;
|
||||
}
|
||||
@ -283,11 +274,9 @@ DataTransferItem::GetAsFile(const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
}
|
||||
|
||||
already_AddRefed<FileSystemEntry>
|
||||
DataTransferItem::GetAsEntry(const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
DataTransferItem::GetAsEntry(nsIPrincipal& aSubjectPrincipal,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
MOZ_ASSERT(aSubjectPrincipal.isSome());
|
||||
|
||||
RefPtr<File> file = GetAsFile(aSubjectPrincipal, aRv);
|
||||
if (NS_WARN_IF(aRv.Failed()) || !file) {
|
||||
return nullptr;
|
||||
@ -386,11 +375,9 @@ DataTransferItem::CreateFileFromInputStream(nsIInputStream* aStream)
|
||||
|
||||
void
|
||||
DataTransferItem::GetAsString(FunctionStringCallback* aCallback,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
nsIPrincipal& aSubjectPrincipal,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
MOZ_ASSERT(aSubjectPrincipal.isSome());
|
||||
|
||||
if (!aCallback || mKind != KIND_STRING) {
|
||||
return;
|
||||
}
|
||||
@ -398,7 +385,7 @@ DataTransferItem::GetAsString(FunctionStringCallback* aCallback,
|
||||
// Theoretically this should be done inside of the runnable, as it might be an
|
||||
// expensive operation on some systems, however we wouldn't get access to the
|
||||
// NS_ERROR_DOM_SECURITY_ERROR messages which may be raised by this method.
|
||||
nsCOMPtr<nsIVariant> data = Data(aSubjectPrincipal.value(), aRv);
|
||||
nsCOMPtr<nsIVariant> data = Data(&aSubjectPrincipal, aRv);
|
||||
if (NS_WARN_IF(!data || aRv.Failed())) {
|
||||
return;
|
||||
}
|
||||
|
@ -35,10 +35,11 @@ public:
|
||||
KIND_OTHER,
|
||||
};
|
||||
|
||||
DataTransferItem(DataTransfer* aDataTransfer, const nsAString& aType)
|
||||
DataTransferItem(DataTransfer* aDataTransfer, const nsAString& aType,
|
||||
eKind aKind = KIND_OTHER)
|
||||
: mIndex(0)
|
||||
, mChromeOnly(false)
|
||||
, mKind(KIND_OTHER)
|
||||
, mKind(aKind)
|
||||
, mType(aType)
|
||||
, mDataTransfer(aDataTransfer)
|
||||
{
|
||||
@ -49,9 +50,8 @@ public:
|
||||
|
||||
virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
|
||||
|
||||
// NOTE: This accesses the subject principal, and should not be called from C++
|
||||
void GetAsString(FunctionStringCallback* aCallback,
|
||||
const Maybe<nsIPrincipal*>& aPrincipal,
|
||||
nsIPrincipal& aSubjectPrincipal,
|
||||
ErrorResult& aRv);
|
||||
|
||||
void GetKind(nsAString& aKind) const
|
||||
@ -73,22 +73,17 @@ public:
|
||||
{
|
||||
aType = mType;
|
||||
}
|
||||
void SetType(const nsAString& aType);
|
||||
|
||||
eKind Kind() const
|
||||
{
|
||||
return mKind;
|
||||
}
|
||||
void SetKind(eKind aKind)
|
||||
{
|
||||
mKind = aKind;
|
||||
}
|
||||
|
||||
already_AddRefed<File>
|
||||
GetAsFile(const Maybe<nsIPrincipal*>& aSubjectPrincipal, ErrorResult& aRv);
|
||||
GetAsFile(nsIPrincipal& aSubjectPrincipal, ErrorResult& aRv);
|
||||
|
||||
already_AddRefed<FileSystemEntry>
|
||||
GetAsEntry(const Maybe<nsIPrincipal*>& aSubjectPrincipal, ErrorResult& aRv);
|
||||
GetAsEntry(nsIPrincipal& aSubjectPrincipal, ErrorResult& aRv);
|
||||
|
||||
DataTransfer* GetParentObject() const
|
||||
{
|
||||
@ -106,6 +101,9 @@ public:
|
||||
|
||||
already_AddRefed<nsIVariant> DataNoSecurityCheck();
|
||||
already_AddRefed<nsIVariant> Data(nsIPrincipal* aPrincipal, ErrorResult& aRv);
|
||||
|
||||
// Note: This can modify the mKind. Callers of this method must let the
|
||||
// relevant DataTransfer know, because its types list can change as a result.
|
||||
void SetData(nsIVariant* aData);
|
||||
|
||||
uint32_t Index() const
|
||||
@ -138,7 +136,7 @@ private:
|
||||
|
||||
bool mChromeOnly;
|
||||
eKind mKind;
|
||||
nsString mType;
|
||||
const nsString mType;
|
||||
nsCOMPtr<nsIVariant> mData;
|
||||
nsCOMPtr<nsIPrincipal> mPrincipal;
|
||||
RefPtr<DataTransfer> mDataTransfer;
|
||||
|
@ -82,11 +82,9 @@ DataTransferItemList::Clone(DataTransfer* aDataTransfer) const
|
||||
|
||||
void
|
||||
DataTransferItemList::Remove(uint32_t aIndex,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
nsIPrincipal& aSubjectPrincipal,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
MOZ_ASSERT(aSubjectPrincipal.isSome());
|
||||
|
||||
if (mDataTransfer->IsReadOnly()) {
|
||||
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
|
||||
return;
|
||||
@ -101,7 +99,7 @@ DataTransferItemList::Remove(uint32_t aIndex,
|
||||
}
|
||||
|
||||
DataTransferItem*
|
||||
DataTransferItemList::IndexedGetter(uint32_t aIndex, bool& aFound, ErrorResult& aRv) const
|
||||
DataTransferItemList::IndexedGetter(uint32_t aIndex, bool& aFound) const
|
||||
{
|
||||
if (aIndex >= mItems.Length()) {
|
||||
aFound = false;
|
||||
@ -126,11 +124,9 @@ DataTransferItemList::MozItemCount() const
|
||||
}
|
||||
|
||||
void
|
||||
DataTransferItemList::Clear(const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
DataTransferItemList::Clear(nsIPrincipal& aSubjectPrincipal,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
MOZ_ASSERT(aSubjectPrincipal.isSome());
|
||||
|
||||
if (NS_WARN_IF(mDataTransfer->IsReadOnly())) {
|
||||
return;
|
||||
}
|
||||
@ -149,11 +145,9 @@ DataTransferItemList::Clear(const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
DataTransferItem*
|
||||
DataTransferItemList::Add(const nsAString& aData,
|
||||
const nsAString& aType,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
nsIPrincipal& aSubjectPrincipal,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
MOZ_ASSERT(aSubjectPrincipal.isSome());
|
||||
|
||||
if (NS_WARN_IF(mDataTransfer->IsReadOnly())) {
|
||||
return nullptr;
|
||||
}
|
||||
@ -163,8 +157,7 @@ DataTransferItemList::Add(const nsAString& aData,
|
||||
nsAutoString format;
|
||||
mDataTransfer->GetRealFormat(aType, format);
|
||||
|
||||
if (!DataTransfer::PrincipalMaySetData(format, data,
|
||||
aSubjectPrincipal.value())) {
|
||||
if (!DataTransfer::PrincipalMaySetData(format, data, &aSubjectPrincipal)) {
|
||||
aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
|
||||
return nullptr;
|
||||
}
|
||||
@ -172,7 +165,7 @@ DataTransferItemList::Add(const nsAString& aData,
|
||||
// We add the textual data to index 0. We set aInsertOnly to true, as we don't
|
||||
// want to update an existing entry if it is already present, as per the spec.
|
||||
RefPtr<DataTransferItem> item =
|
||||
SetDataWithPrincipal(format, data, 0, aSubjectPrincipal.value(),
|
||||
SetDataWithPrincipal(format, data, 0, &aSubjectPrincipal,
|
||||
/* aInsertOnly = */ true,
|
||||
/* aHidden = */ false,
|
||||
aRv);
|
||||
@ -186,11 +179,9 @@ DataTransferItemList::Add(const nsAString& aData,
|
||||
|
||||
DataTransferItem*
|
||||
DataTransferItemList::Add(File& aData,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
nsIPrincipal& aSubjectPrincipal,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
MOZ_ASSERT(aSubjectPrincipal.isSome());
|
||||
|
||||
if (mDataTransfer->IsReadOnly()) {
|
||||
return nullptr;
|
||||
}
|
||||
@ -202,8 +193,7 @@ DataTransferItemList::Add(File& aData,
|
||||
nsAutoString type;
|
||||
aData.GetType(type);
|
||||
|
||||
if (!DataTransfer::PrincipalMaySetData(type, data,
|
||||
aSubjectPrincipal.value())) {
|
||||
if (!DataTransfer::PrincipalMaySetData(type, data, &aSubjectPrincipal)) {
|
||||
aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
|
||||
return nullptr;
|
||||
}
|
||||
@ -213,7 +203,7 @@ DataTransferItemList::Add(File& aData,
|
||||
// the internal specced layout.
|
||||
uint32_t index = mIndexedItems.Length();
|
||||
RefPtr<DataTransferItem> item =
|
||||
SetDataWithPrincipal(type, data, index, aSubjectPrincipal.value(),
|
||||
SetDataWithPrincipal(type, data, index, &aSubjectPrincipal,
|
||||
/* aInsertOnly = */ true,
|
||||
/* aHidden = */ false,
|
||||
aRv);
|
||||
@ -272,11 +262,9 @@ DataTransferItemList::Files(nsIPrincipal* aPrincipal)
|
||||
void
|
||||
DataTransferItemList::MozRemoveByTypeAt(const nsAString& aType,
|
||||
uint32_t aIndex,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
nsIPrincipal& aSubjectPrincipal,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
MOZ_ASSERT(aSubjectPrincipal.isSome());
|
||||
|
||||
if (NS_WARN_IF(mDataTransfer->IsReadOnly() ||
|
||||
aIndex >= mIndexedItems.Length())) {
|
||||
return;
|
||||
@ -370,6 +358,10 @@ DataTransferItemList::SetDataWithPrincipal(const nsAString& aType,
|
||||
|
||||
DataTransferItem::eKind oldKind = item->Kind();
|
||||
item->SetData(aData);
|
||||
if (oldKind != item->Kind()) {
|
||||
// Types list may have changed, even if aIndex == 0.
|
||||
mDataTransfer->TypesListMayHaveChanged();
|
||||
}
|
||||
|
||||
if (aIndex != 0) {
|
||||
// If the item changes from being a file to not a file or vice-versa,
|
||||
@ -433,9 +425,15 @@ DataTransferItemList::AppendNewItem(uint32_t aIndex,
|
||||
// adding to is 0, or the item we are adding is a file. If we add an item
|
||||
// which is not a file to a non-zero index, invariants could be broken.
|
||||
// (namely the invariant that there are not 2 non-file entries in the items
|
||||
// array with the same type)
|
||||
if (!aHidden && (item->Kind() == DataTransferItem::KIND_FILE || aIndex == 0)) {
|
||||
mItems.AppendElement(item);
|
||||
// array with the same type).
|
||||
//
|
||||
// We also want to update our DataTransfer's type list any time we're adding a
|
||||
// KIND_FILE item, or an item at index 0.
|
||||
if (item->Kind() == DataTransferItem::KIND_FILE || aIndex == 0) {
|
||||
if (!aHidden) {
|
||||
mItems.AppendElement(item);
|
||||
}
|
||||
mDataTransfer->TypesListMayHaveChanged();
|
||||
}
|
||||
|
||||
return item;
|
||||
@ -475,6 +473,7 @@ DataTransferItemList::ClearAllItems()
|
||||
mItems.Clear();
|
||||
mIndexedItems.Clear();
|
||||
mIndexedItems.SetLength(1);
|
||||
mDataTransfer->TypesListMayHaveChanged();
|
||||
|
||||
// Re-generate files (into an empty list)
|
||||
RegenerateFiles();
|
||||
@ -484,7 +483,7 @@ void
|
||||
DataTransferItemList::ClearDataHelper(DataTransferItem* aItem,
|
||||
uint32_t aIndexHint,
|
||||
uint32_t aMozOffsetHint,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
nsIPrincipal& aSubjectPrincipal,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
MOZ_ASSERT(aItem);
|
||||
@ -492,22 +491,19 @@ DataTransferItemList::ClearDataHelper(DataTransferItem* aItem,
|
||||
return;
|
||||
}
|
||||
|
||||
if (aItem->Principal() && aSubjectPrincipal.isSome() &&
|
||||
!aSubjectPrincipal.value()->Subsumes(aItem->Principal())) {
|
||||
if (aItem->Principal() && !aSubjectPrincipal.Subsumes(aItem->Principal())) {
|
||||
aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if the aIndexHint is actually the index, and then remove the item
|
||||
// from aItems
|
||||
ErrorResult rv;
|
||||
bool found;
|
||||
if (IndexedGetter(aIndexHint, found, rv) == aItem) {
|
||||
if (IndexedGetter(aIndexHint, found) == aItem) {
|
||||
mItems.RemoveElementAt(aIndexHint);
|
||||
} else {
|
||||
mItems.RemoveElement(aItem);
|
||||
}
|
||||
rv.SuppressException();
|
||||
|
||||
// Check if the aMozIndexHint and aMozOffsetHint are actually the index and
|
||||
// offset, and then remove them from mIndexedItems
|
||||
@ -519,6 +515,8 @@ DataTransferItemList::ClearDataHelper(DataTransferItem* aItem,
|
||||
items.RemoveElement(aItem);
|
||||
}
|
||||
|
||||
mDataTransfer->TypesListMayHaveChanged();
|
||||
|
||||
// Check if we should remove the index. We never remove index 0.
|
||||
if (items.Length() == 0 && aItem->Index() != 0) {
|
||||
mIndexedItems.RemoveElementAt(aItem->Index());
|
||||
@ -564,15 +562,13 @@ DataTransferItemList::GenerateFiles(FileList* aFiles,
|
||||
MOZ_ASSERT(aFilesPrincipal);
|
||||
uint32_t count = Length();
|
||||
for (uint32_t i = 0; i < count; i++) {
|
||||
ErrorResult rv;
|
||||
bool found;
|
||||
RefPtr<DataTransferItem> item = IndexedGetter(i, found, rv);
|
||||
if (NS_WARN_IF(!found || rv.Failed())) {
|
||||
continue;
|
||||
}
|
||||
RefPtr<DataTransferItem> item = IndexedGetter(i, found);
|
||||
MOZ_ASSERT(found);
|
||||
|
||||
if (item->Kind() == DataTransferItem::KIND_FILE) {
|
||||
RefPtr<File> file = item->GetAsFile(Some(aFilesPrincipal), rv);
|
||||
IgnoredErrorResult rv;
|
||||
RefPtr<File> file = item->GetAsFile(*aFilesPrincipal, rv);
|
||||
if (NS_WARN_IF(rv.Failed() || !file)) {
|
||||
continue;
|
||||
}
|
||||
|
@ -51,25 +51,24 @@ public:
|
||||
};
|
||||
|
||||
DataTransferItem* Add(const nsAString& aData, const nsAString& aType,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
nsIPrincipal& aSubjectPrincipal,
|
||||
ErrorResult& rv);
|
||||
DataTransferItem* Add(File& aData,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
nsIPrincipal& aSubjectPrincipal,
|
||||
ErrorResult& aRv);
|
||||
|
||||
void Remove(uint32_t aIndex,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
nsIPrincipal& aSubjectPrincipal,
|
||||
ErrorResult& aRv);
|
||||
|
||||
DataTransferItem* IndexedGetter(uint32_t aIndex, bool& aFound,
|
||||
ErrorResult& aRv) const;
|
||||
DataTransferItem* IndexedGetter(uint32_t aIndex, bool& aFound) const;
|
||||
|
||||
DataTransfer* GetParentObject() const
|
||||
{
|
||||
return mDataTransfer;
|
||||
}
|
||||
|
||||
void Clear(const Maybe<nsIPrincipal*>& aSubjectPrincipal, ErrorResult& aRv);
|
||||
void Clear(nsIPrincipal& aSubjectPrincipal, ErrorResult& aRv);
|
||||
|
||||
already_AddRefed<DataTransferItem>
|
||||
SetDataWithPrincipal(const nsAString& aType, nsIVariant* aData,
|
||||
@ -80,7 +79,7 @@ public:
|
||||
|
||||
// Moz-style helper methods for interacting with the stored data
|
||||
void MozRemoveByTypeAt(const nsAString& aType, uint32_t aIndex,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
nsIPrincipal& aSubjectPrincipal,
|
||||
ErrorResult& aRv);
|
||||
DataTransferItem* MozItemByTypeAt(const nsAString& aType, uint32_t aIndex);
|
||||
const nsTArray<RefPtr<DataTransferItem>>* MozItemsAt(uint32_t aIndex);
|
||||
@ -96,7 +95,7 @@ public:
|
||||
private:
|
||||
void ClearDataHelper(DataTransferItem* aItem, uint32_t aIndexHint,
|
||||
uint32_t aMozOffsetHint,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
nsIPrincipal& aSubjectPrincipal,
|
||||
ErrorResult& aRv);
|
||||
DataTransferItem* AppendNewItem(uint32_t aIndex, const nsAString& aType,
|
||||
nsIVariant* aData, nsIPrincipal* aPrincipal,
|
||||
@ -111,7 +110,18 @@ private:
|
||||
RefPtr<FileList> mFiles;
|
||||
// The principal for which mFiles is cached
|
||||
nsCOMPtr<nsIPrincipal> mFilesPrincipal;
|
||||
// mItems is the list of items that corresponds to the spec concept of a
|
||||
// DataTransferItemList. That is, this is the thing the spec's indexed getter
|
||||
// operates on. The items in here are a subset of the items present in the
|
||||
// arrays that live in mIndexedItems.
|
||||
nsTArray<RefPtr<DataTransferItem>> mItems;
|
||||
// mIndexedItems represents all our items. For any given index, all items at
|
||||
// that index have different types in the GetType() sense. That means that
|
||||
// representing multiple items with the same type (e.g. multiple files)
|
||||
// requires using multiple indices.
|
||||
//
|
||||
// There is always a (possibly empty) list of items at index 0, so
|
||||
// mIndexedItems.Length() >= 1 at all times.
|
||||
nsTArray<nsTArray<RefPtr<DataTransferItem>>> mIndexedItems;
|
||||
};
|
||||
|
||||
|
@ -118,7 +118,7 @@ function doDragStartSelection(event)
|
||||
gDataTransfer = dt;
|
||||
|
||||
var types = dt.types;
|
||||
is(types instanceof DOMStringList, true, "initial types is a DOMStringList");
|
||||
ok(Array.isArray(types), "initial types is an Array");
|
||||
checkTypes(dt, ["text/_moz_htmlcontext", "text/_moz_htmlinfo", "text/html", "text/plain"], 0, "initial selection");
|
||||
|
||||
is(dt.getData("text/plain"), "This is a draggable bit of text.", "initial selection text/plain");
|
||||
@ -148,7 +148,7 @@ function test_DataTransfer(dt)
|
||||
is(dt.mozItemCount, 0, "empty itemCount");
|
||||
|
||||
var types = dt.types;
|
||||
is(types instanceof DOMStringList, true, "empty types is a DOMStringList");
|
||||
ok(Array.isArray(types), "empty types is an Array");
|
||||
checkTypes(dt, [], 0, "empty");
|
||||
is(dt.getData("text/plain"), "", "empty data is empty");
|
||||
|
||||
|
@ -168,7 +168,7 @@ public:
|
||||
GetEnumAttr(nsGkAtoms::referrerpolicy, EmptyCString().get(), aReferrer);
|
||||
}
|
||||
nsIDocument*
|
||||
GetSVGDocument(const mozilla::Maybe<nsIPrincipal*>& aSubjectPrincipal)
|
||||
GetSVGDocument(nsIPrincipal& aSubjectPrincipal)
|
||||
{
|
||||
return GetContentDocument(aSubjectPrincipal);
|
||||
}
|
||||
|
@ -2841,11 +2841,9 @@ HTMLInputElement::MozIsTextField(bool aExcludePassword, bool* aResult)
|
||||
|
||||
void
|
||||
HTMLInputElement::SetUserInput(const nsAString& aInput,
|
||||
const mozilla::Maybe<nsIPrincipal*>& aPrincipal) {
|
||||
MOZ_ASSERT(aPrincipal.isSome());
|
||||
|
||||
nsIPrincipal& aSubjectPrincipal) {
|
||||
if (mType == NS_FORM_INPUT_FILE &&
|
||||
!nsContentUtils::IsSystemPrincipal(aPrincipal.value())) {
|
||||
!nsContentUtils::IsSystemPrincipal(&aSubjectPrincipal)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -821,7 +821,7 @@ public:
|
||||
nsIEditor* GetEditor();
|
||||
|
||||
void SetUserInput(const nsAString& aInput,
|
||||
const mozilla::Maybe<nsIPrincipal*>& aPrincipal);
|
||||
nsIPrincipal& aSubjectPrincipal);
|
||||
|
||||
// XPCOM GetPhonetic() is OK
|
||||
|
||||
|
@ -466,13 +466,13 @@ HTMLObjectElement::GetContentDocument(nsIDOMDocument **aContentDocument)
|
||||
NS_ENSURE_ARG_POINTER(aContentDocument);
|
||||
|
||||
nsCOMPtr<nsIDOMDocument> domDoc =
|
||||
do_QueryInterface(GetContentDocument(Some(nsContentUtils::SubjectPrincipal())));
|
||||
do_QueryInterface(GetContentDocument(*nsContentUtils::SubjectPrincipal()));
|
||||
domDoc.forget(aContentDocument);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsPIDOMWindowOuter*
|
||||
HTMLObjectElement::GetContentWindow(const mozilla::Maybe<nsIPrincipal*>& aSubjectPrincipal)
|
||||
HTMLObjectElement::GetContentWindow(nsIPrincipal& aSubjectPrincipal)
|
||||
{
|
||||
nsIDocument* doc = GetContentDocument(aSubjectPrincipal);
|
||||
if (doc) {
|
||||
|
@ -158,7 +158,7 @@ public:
|
||||
using nsObjectLoadingContent::GetContentDocument;
|
||||
|
||||
nsPIDOMWindowOuter*
|
||||
GetContentWindow(const mozilla::Maybe<nsIPrincipal*>& aSubjectPrincipal);
|
||||
GetContentWindow(nsIPrincipal& aSubjectPrincipal);
|
||||
|
||||
using nsIConstraintValidation::CheckValidity;
|
||||
using nsIConstraintValidation::ReportValidity;
|
||||
@ -239,7 +239,7 @@ public:
|
||||
}
|
||||
|
||||
nsIDocument*
|
||||
GetSVGDocument(const mozilla::Maybe<nsIPrincipal*>& aSubjectPrincipal)
|
||||
GetSVGDocument(nsIPrincipal& aSubjectPrincipal)
|
||||
{
|
||||
return GetContentDocument(aSubjectPrincipal);
|
||||
}
|
||||
|
@ -188,7 +188,7 @@ public:
|
||||
// align covered by <applet>
|
||||
// name covered by <applet>
|
||||
nsIDocument*
|
||||
GetSVGDocument(const mozilla::Maybe<nsIPrincipal*>& aSubjectPrincipal)
|
||||
GetSVGDocument(nsIPrincipal& aSubjectPrincipal)
|
||||
{
|
||||
return GetContentDocument(aSubjectPrincipal);
|
||||
}
|
||||
|
@ -80,13 +80,13 @@ nsGenericHTMLFrameElement::GetContentDocument(nsIDOMDocument** aContentDocument)
|
||||
{
|
||||
NS_PRECONDITION(aContentDocument, "Null out param");
|
||||
nsCOMPtr<nsIDOMDocument> document =
|
||||
do_QueryInterface(GetContentDocument(Some(nsContentUtils::SubjectPrincipal())));
|
||||
do_QueryInterface(GetContentDocument(*nsContentUtils::SubjectPrincipal()));
|
||||
document.forget(aContentDocument);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsIDocument*
|
||||
nsGenericHTMLFrameElement::GetContentDocument(const Maybe<nsIPrincipal*>& aSubjectPrincipal)
|
||||
nsGenericHTMLFrameElement::GetContentDocument(nsIPrincipal& aSubjectPrincipal)
|
||||
{
|
||||
nsCOMPtr<nsPIDOMWindowOuter> win = GetContentWindow();
|
||||
if (!win) {
|
||||
@ -99,8 +99,7 @@ nsGenericHTMLFrameElement::GetContentDocument(const Maybe<nsIPrincipal*>& aSubje
|
||||
}
|
||||
|
||||
// Return null for cross-origin contentDocument.
|
||||
if (!aSubjectPrincipal.value()
|
||||
->SubsumesConsideringDomain(doc->NodePrincipal())) {
|
||||
if (!aSubjectPrincipal.SubsumesConsideringDomain(doc->NodePrincipal())) {
|
||||
return nullptr;
|
||||
}
|
||||
return doc;
|
||||
|
@ -102,8 +102,7 @@ protected:
|
||||
// it makes sense.
|
||||
void EnsureFrameLoader();
|
||||
nsresult LoadSrc();
|
||||
nsIDocument*
|
||||
GetContentDocument(const mozilla::Maybe<nsIPrincipal*>& aSubjectPrincipal);
|
||||
nsIDocument* GetContentDocument(nsIPrincipal& aSubjectPrincipal);
|
||||
nsresult GetContentDocument(nsIDOMDocument** aContentDocument);
|
||||
already_AddRefed<nsPIDOMWindowOuter> GetContentWindow();
|
||||
|
||||
|
@ -2841,12 +2841,20 @@ nsHTMLDocument::SetDesignMode(const nsAString& aDesignMode)
|
||||
return rv.StealNSResult();
|
||||
}
|
||||
|
||||
void
|
||||
nsHTMLDocument::SetDesignMode(const nsAString& aDesignMode,
|
||||
nsIPrincipal& aSubjectPrincipal,
|
||||
ErrorResult& rv)
|
||||
{
|
||||
SetDesignMode(aDesignMode, Some(&aSubjectPrincipal), rv);
|
||||
}
|
||||
|
||||
void
|
||||
nsHTMLDocument::SetDesignMode(const nsAString& aDesignMode,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
ErrorResult& rv)
|
||||
{
|
||||
if (!nsContentUtils::LegacyIsCallerNativeCode() &&
|
||||
if (aSubjectPrincipal.isSome() &&
|
||||
!aSubjectPrincipal.value()->Subsumes(NodePrincipal())) {
|
||||
rv.Throw(NS_ERROR_DOM_PROP_ACCESS_DENIED);
|
||||
return;
|
||||
|
@ -211,10 +211,13 @@ public:
|
||||
void Writeln(JSContext* cx, const mozilla::dom::Sequence<nsString>& aText,
|
||||
mozilla::ErrorResult& rv);
|
||||
void GetDesignMode(nsAString& aDesignMode,
|
||||
const mozilla::Maybe<nsIPrincipal*>& aSubjectPrincipal)
|
||||
nsIPrincipal& aSubjectPrincipal)
|
||||
{
|
||||
GetDesignMode(aDesignMode);
|
||||
}
|
||||
void SetDesignMode(const nsAString& aDesignMode,
|
||||
nsIPrincipal& aSubjectPrincipal,
|
||||
mozilla::ErrorResult& rv);
|
||||
void SetDesignMode(const nsAString& aDesignMode,
|
||||
const mozilla::Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
mozilla::ErrorResult& rv);
|
||||
|
@ -66,19 +66,6 @@ interface nsIDOMDataTransfer : nsISupports
|
||||
*/
|
||||
readonly attribute nsIDOMFileList files;
|
||||
|
||||
/**
|
||||
* Holds a list of the format types of the data that is stored for the first
|
||||
* item, in the same order the data was added. An empty list will be
|
||||
* returned if no data was added.
|
||||
*/
|
||||
readonly attribute nsISupports types;
|
||||
|
||||
/**
|
||||
* Retrieves the data for a given format, or an empty string if data for
|
||||
* that format does not exist or the data transfer contains no data.
|
||||
*/
|
||||
DOMString getData(in DOMString format);
|
||||
|
||||
/**
|
||||
* Set the image to be used for dragging if a custom one is desired. Most of
|
||||
* the time, this would not be set, as a default image is created from the
|
||||
|
@ -307,7 +307,8 @@ HangMonitorChild::InterruptCallback()
|
||||
if (forcePaint) {
|
||||
RefPtr<TabChild> tabChild = TabChild::FindTabChild(forcePaintTab);
|
||||
if (tabChild) {
|
||||
JS::AutoAssertOnGC aaogc(mContext);
|
||||
JS::AutoAssertOnGC nogc(mContext);
|
||||
JS::AutoAssertOnBarrier nobarrier(mContext);
|
||||
tabChild->ForcePaint(forcePaintEpoch);
|
||||
}
|
||||
}
|
||||
@ -389,6 +390,7 @@ HangMonitorChild::RecvForcePaint(const TabId& aTabId, const uint64_t& aLayerObse
|
||||
}
|
||||
|
||||
JS_RequestInterruptCallback(mContext);
|
||||
JS::RequestGCInterruptCallback(mContext);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -1187,6 +1189,7 @@ mozilla::CreateHangMonitorChild(mozilla::ipc::Transport* aTransport,
|
||||
|
||||
JSContext* cx = danger::GetJSContext();
|
||||
JS_AddInterruptCallback(cx, InterruptCallback);
|
||||
JS::AddGCInterruptCallback(cx, InterruptCallback);
|
||||
|
||||
ProcessHangMonitor* monitor = ProcessHangMonitor::GetOrCreate();
|
||||
HangMonitorChild* child = new HangMonitorChild(monitor);
|
||||
|
23
dom/media/test/crashtests/1223670.html
Normal file
23
dom/media/test/crashtests/1223670.html
Normal file
@ -0,0 +1,23 @@
|
||||
<!DOCTYPE html>
|
||||
<html class="reftest-wait">
|
||||
<head>
|
||||
<script>
|
||||
|
||||
function boom()
|
||||
{
|
||||
|
||||
var ac = new window.AudioContext("publicnotification");
|
||||
|
||||
setTimeout(function() {
|
||||
document.documentElement.removeAttribute("class");
|
||||
var htmlAudio = new Audio();
|
||||
var stream = htmlAudio.mozCaptureStreamUntilEnded();
|
||||
ac.createMediaStreamSource(stream);
|
||||
}, 0);
|
||||
}
|
||||
|
||||
</script>
|
||||
</head>
|
||||
<body onload="boom();">
|
||||
</body>
|
||||
</html>
|
@ -81,6 +81,7 @@ load 1157994.html
|
||||
skip-if(!B2G) load 1158427.html
|
||||
load 1185176.html
|
||||
load 1185192.html
|
||||
load 1223670.html
|
||||
load 1228484.html
|
||||
load 1304948.html
|
||||
load analyser-channels-1.html
|
||||
|
@ -67,12 +67,10 @@ DOMStorage::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
|
||||
}
|
||||
|
||||
uint32_t
|
||||
DOMStorage::GetLength(const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
DOMStorage::GetLength(nsIPrincipal& aSubjectPrincipal,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
MOZ_ASSERT(aSubjectPrincipal.isSome());
|
||||
|
||||
if (!CanUseStorage(nullptr, aSubjectPrincipal, this)) {
|
||||
if (!CanUseStorage(aSubjectPrincipal)) {
|
||||
aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
|
||||
return 0;
|
||||
}
|
||||
@ -84,12 +82,10 @@ DOMStorage::GetLength(const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
|
||||
void
|
||||
DOMStorage::Key(uint32_t aIndex, nsAString& aResult,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
nsIPrincipal& aSubjectPrincipal,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
MOZ_ASSERT(aSubjectPrincipal.isSome());
|
||||
|
||||
if (!CanUseStorage(nullptr, aSubjectPrincipal, this)) {
|
||||
if (!CanUseStorage(aSubjectPrincipal)) {
|
||||
aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
|
||||
return;
|
||||
}
|
||||
@ -99,12 +95,10 @@ DOMStorage::Key(uint32_t aIndex, nsAString& aResult,
|
||||
|
||||
void
|
||||
DOMStorage::GetItem(const nsAString& aKey, nsAString& aResult,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
nsIPrincipal& aSubjectPrincipal,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
MOZ_ASSERT(aSubjectPrincipal.isSome());
|
||||
|
||||
if (!CanUseStorage(nullptr, aSubjectPrincipal, this)) {
|
||||
if (!CanUseStorage(aSubjectPrincipal)) {
|
||||
aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
|
||||
return;
|
||||
}
|
||||
@ -114,12 +108,10 @@ DOMStorage::GetItem(const nsAString& aKey, nsAString& aResult,
|
||||
|
||||
void
|
||||
DOMStorage::SetItem(const nsAString& aKey, const nsAString& aData,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
nsIPrincipal& aSubjectPrincipal,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
MOZ_ASSERT(aSubjectPrincipal.isSome());
|
||||
|
||||
if (!CanUseStorage(nullptr, aSubjectPrincipal, this)) {
|
||||
if (!CanUseStorage(aSubjectPrincipal)) {
|
||||
aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
|
||||
return;
|
||||
}
|
||||
@ -144,12 +136,10 @@ DOMStorage::SetItem(const nsAString& aKey, const nsAString& aData,
|
||||
|
||||
void
|
||||
DOMStorage::RemoveItem(const nsAString& aKey,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
nsIPrincipal& aSubjectPrincipal,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
MOZ_ASSERT(aSubjectPrincipal.isSome());
|
||||
|
||||
if (!CanUseStorage(nullptr, aSubjectPrincipal, this)) {
|
||||
if (!CanUseStorage(aSubjectPrincipal)) {
|
||||
aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
|
||||
return;
|
||||
}
|
||||
@ -166,12 +156,10 @@ DOMStorage::RemoveItem(const nsAString& aKey,
|
||||
}
|
||||
|
||||
void
|
||||
DOMStorage::Clear(const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
DOMStorage::Clear(nsIPrincipal& aSubjectPrincipal,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
MOZ_ASSERT(aSubjectPrincipal.isSome());
|
||||
|
||||
if (!CanUseStorage(nullptr, aSubjectPrincipal, this)) {
|
||||
if (!CanUseStorage(aSubjectPrincipal)) {
|
||||
aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
|
||||
return;
|
||||
}
|
||||
@ -245,11 +233,8 @@ DOMStorage::BroadcastChangeNotification(const nsSubstring& aKey,
|
||||
static const char kPermissionType[] = "cookie";
|
||||
static const char kStorageEnabled[] = "dom.storage.enabled";
|
||||
|
||||
// static, public
|
||||
bool
|
||||
DOMStorage::CanUseStorage(nsPIDOMWindowInner* aWindow,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
DOMStorage* aStorage)
|
||||
DOMStorage::CanUseStorage(nsIPrincipal& aSubjectPrincipal)
|
||||
{
|
||||
// This method is responsible for correct setting of mIsSessionOnly.
|
||||
|
||||
@ -257,25 +242,15 @@ DOMStorage::CanUseStorage(nsPIDOMWindowInner* aWindow,
|
||||
return false;
|
||||
}
|
||||
|
||||
nsContentUtils::StorageAccess access = nsContentUtils::StorageAccess::eDeny;
|
||||
if (aWindow) {
|
||||
access = nsContentUtils::StorageAllowedForWindow(aWindow);
|
||||
} else if (aStorage) {
|
||||
access = nsContentUtils::StorageAllowedForPrincipal(aStorage->mPrincipal);
|
||||
}
|
||||
nsContentUtils::StorageAccess access =
|
||||
nsContentUtils::StorageAllowedForPrincipal(mPrincipal);
|
||||
|
||||
if (access == nsContentUtils::StorageAccess::eDeny) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (aStorage) {
|
||||
aStorage->mIsSessionOnly = access <= nsContentUtils::StorageAccess::eSessionScoped;
|
||||
|
||||
MOZ_ASSERT(aSubjectPrincipal.isSome());
|
||||
return aStorage->CanAccess(aSubjectPrincipal.value());
|
||||
}
|
||||
|
||||
return true;
|
||||
mIsSessionOnly = access <= nsContentUtils::StorageAccess::eSessionScoped;
|
||||
return CanAccess(&aSubjectPrincipal);
|
||||
}
|
||||
|
||||
DOMStorage::StorageType
|
||||
@ -320,8 +295,7 @@ DOMStorage::CanAccess(nsIPrincipal* aPrincipal)
|
||||
void
|
||||
DOMStorage::GetSupportedNames(nsTArray<nsString>& aKeys)
|
||||
{
|
||||
if (!CanUseStorage(nullptr, Some(nsContentUtils::SubjectPrincipal()),
|
||||
this)) {
|
||||
if (!CanUseStorage(*nsContentUtils::SubjectPrincipal())) {
|
||||
// return just an empty array
|
||||
aKeys.Clear();
|
||||
return;
|
||||
|
@ -70,21 +70,21 @@ public:
|
||||
return mWindow;
|
||||
}
|
||||
|
||||
uint32_t GetLength(const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
uint32_t GetLength(nsIPrincipal& aSubjectPrincipal,
|
||||
ErrorResult& aRv);
|
||||
|
||||
void Key(uint32_t aIndex, nsAString& aResult,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
nsIPrincipal& aSubjectPrincipal,
|
||||
ErrorResult& aRv);
|
||||
|
||||
void GetItem(const nsAString& aKey, nsAString& aResult,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
nsIPrincipal& aSubjectPrincipal,
|
||||
ErrorResult& aRv);
|
||||
|
||||
void GetSupportedNames(nsTArray<nsString>& aKeys);
|
||||
|
||||
void NamedGetter(const nsAString& aKey, bool& aFound, nsAString& aResult,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
nsIPrincipal& aSubjectPrincipal,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
GetItem(aKey, aResult, aSubjectPrincipal, aRv);
|
||||
@ -92,22 +92,22 @@ public:
|
||||
}
|
||||
|
||||
void SetItem(const nsAString& aKey, const nsAString& aValue,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
nsIPrincipal& aSubjectPrincipal,
|
||||
ErrorResult& aRv);
|
||||
|
||||
void NamedSetter(const nsAString& aKey, const nsAString& aValue,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
nsIPrincipal& aSubjectPrincipal,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
SetItem(aKey, aValue, aSubjectPrincipal, aRv);
|
||||
}
|
||||
|
||||
void RemoveItem(const nsAString& aKey,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
nsIPrincipal& aSubjectPrincipal,
|
||||
ErrorResult& aRv);
|
||||
|
||||
void NamedDeleter(const nsAString& aKey, bool& aFound,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
nsIPrincipal& aSubjectPrincipal,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
RemoveItem(aKey, aSubjectPrincipal, aRv);
|
||||
@ -115,20 +115,9 @@ public:
|
||||
aFound = !aRv.ErrorCodeIs(NS_SUCCESS_DOM_NO_OPERATION);
|
||||
}
|
||||
|
||||
void Clear(const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
void Clear(nsIPrincipal& aSubjectPrincipal,
|
||||
ErrorResult& aRv);
|
||||
|
||||
// The method checks whether the caller can use a storage.
|
||||
// CanUseStorage is called before any DOM initiated operation
|
||||
// on a storage is about to happen and ensures that the storage's
|
||||
// session-only flag is properly set according the current settings.
|
||||
// It is an optimization since the privileges check and session only
|
||||
// state determination are complex and share the code (comes hand in
|
||||
// hand together).
|
||||
static bool CanUseStorage(nsPIDOMWindowInner* aWindow,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
DOMStorage* aStorage = nullptr);
|
||||
|
||||
bool IsPrivate() const;
|
||||
bool IsSessionOnly() const { return mIsSessionOnly; }
|
||||
|
||||
@ -138,6 +127,16 @@ public:
|
||||
return mCache == aOther->mCache;
|
||||
}
|
||||
|
||||
protected:
|
||||
// The method checks whether the caller can use a storage.
|
||||
// CanUseStorage is called before any DOM initiated operation
|
||||
// on a storage is about to happen and ensures that the storage's
|
||||
// session-only flag is properly set according the current settings.
|
||||
// It is an optimization since the privileges check and session only
|
||||
// state determination are complex and share the code (comes hand in
|
||||
// hand together).
|
||||
bool CanUseStorage(nsIPrincipal& aSubjectPrincipal);
|
||||
|
||||
private:
|
||||
~DOMStorage();
|
||||
|
||||
|
@ -17,8 +17,8 @@ interface DataTransfer {
|
||||
[Throws]
|
||||
void setDragImage(Element image, long x, long y);
|
||||
|
||||
[Throws]
|
||||
readonly attribute DOMStringList types;
|
||||
[Pure, Cached, Frozen, NeedsSubjectPrincipal]
|
||||
readonly attribute sequence<DOMString> types;
|
||||
[Throws, NeedsSubjectPrincipal]
|
||||
DOMString getData(DOMString format);
|
||||
[Throws, NeedsSubjectPrincipal]
|
||||
|
@ -9,7 +9,6 @@
|
||||
|
||||
interface DataTransferItemList {
|
||||
readonly attribute unsigned long length;
|
||||
[Throws]
|
||||
getter DataTransferItem (unsigned long index);
|
||||
[Throws, NeedsSubjectPrincipal]
|
||||
DataTransferItem? add(DOMString data, DOMString type);
|
||||
|
@ -109,7 +109,7 @@ Window implements WindowSessionStorage;
|
||||
// http://www.whatwg.org/specs/web-apps/current-work/
|
||||
[NoInterfaceObject]
|
||||
interface WindowLocalStorage {
|
||||
[Throws, NeedsSubjectPrincipal] readonly attribute Storage? localStorage;
|
||||
[Throws] readonly attribute Storage? localStorage;
|
||||
};
|
||||
Window implements WindowLocalStorage;
|
||||
|
||||
|
@ -934,19 +934,16 @@ EditorEventListener::CanDrop(nsIDOMDragEvent* aEvent)
|
||||
nsCOMPtr<DataTransfer> dataTransfer = do_QueryInterface(domDataTransfer);
|
||||
NS_ENSURE_TRUE(dataTransfer, false);
|
||||
|
||||
ErrorResult err;
|
||||
RefPtr<DOMStringList> types = dataTransfer->GetTypes(err);
|
||||
if (NS_WARN_IF(err.Failed())) {
|
||||
return false;
|
||||
}
|
||||
nsTArray<nsString> types;
|
||||
dataTransfer->GetTypes(types, *nsContentUtils::GetSystemPrincipal());
|
||||
|
||||
// Plaintext editors only support dropping text. Otherwise, HTML and files
|
||||
// can be dropped as well.
|
||||
if (!types->Contains(NS_LITERAL_STRING(kTextMime)) &&
|
||||
!types->Contains(NS_LITERAL_STRING(kMozTextInternal)) &&
|
||||
if (!types.Contains(NS_LITERAL_STRING(kTextMime)) &&
|
||||
!types.Contains(NS_LITERAL_STRING(kMozTextInternal)) &&
|
||||
(mEditorBase->IsPlaintextEditor() ||
|
||||
(!types->Contains(NS_LITERAL_STRING(kHTMLMime)) &&
|
||||
!types->Contains(NS_LITERAL_STRING(kFileMime))))) {
|
||||
(!types.Contains(NS_LITERAL_STRING(kHTMLMime)) &&
|
||||
!types.Contains(NS_LITERAL_STRING(kFileMime))))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -484,12 +484,23 @@ extern JS_PUBLIC_API(size_t)
|
||||
GetGCNumber();
|
||||
|
||||
/**
|
||||
* Assert if a GC occurs while this class is live. This class does not disable
|
||||
* the static rooting hazard analysis.
|
||||
* Pass a subclass of this "abstract" class to callees to require that they
|
||||
* never GC. Subclasses can use assertions or the hazard analysis to ensure no
|
||||
* GC happens.
|
||||
*/
|
||||
class JS_PUBLIC_API(AutoAssertOnGC)
|
||||
class JS_PUBLIC_API(AutoRequireNoGC)
|
||||
{
|
||||
protected:
|
||||
AutoRequireNoGC() {}
|
||||
~AutoRequireNoGC() {}
|
||||
};
|
||||
|
||||
/**
|
||||
* Release assert if a GC occurs while this class is live. This class does
|
||||
* not disable the static rooting hazard analysis.
|
||||
*/
|
||||
class JS_PUBLIC_API(AutoAssertOnGC) : public AutoRequireNoGC
|
||||
{
|
||||
#ifdef DEBUG
|
||||
js::gc::GCRuntime* gc;
|
||||
size_t gcNumber;
|
||||
|
||||
@ -497,16 +508,6 @@ class JS_PUBLIC_API(AutoAssertOnGC)
|
||||
AutoAssertOnGC();
|
||||
explicit AutoAssertOnGC(JSContext* cx);
|
||||
~AutoAssertOnGC();
|
||||
|
||||
static void VerifyIsSafeToGC(JSRuntime* rt);
|
||||
#else
|
||||
public:
|
||||
AutoAssertOnGC() {}
|
||||
explicit AutoAssertOnGC(JSContext* cx) {}
|
||||
~AutoAssertOnGC() {}
|
||||
|
||||
static void VerifyIsSafeToGC(JSRuntime* rt) {}
|
||||
#endif
|
||||
};
|
||||
|
||||
/**
|
||||
@ -531,6 +532,20 @@ class JS_PUBLIC_API(AutoAssertNoAlloc)
|
||||
#endif
|
||||
};
|
||||
|
||||
/**
|
||||
* Assert if a GC barrier is invoked while this class is live. This class does
|
||||
* not disable the static rooting hazard analysis.
|
||||
*/
|
||||
class JS_PUBLIC_API(AutoAssertOnBarrier)
|
||||
{
|
||||
JSContext* context;
|
||||
bool prev;
|
||||
|
||||
public:
|
||||
explicit AutoAssertOnBarrier(JSContext* cx);
|
||||
~AutoAssertOnBarrier();
|
||||
};
|
||||
|
||||
/**
|
||||
* Disable the static rooting hazard analysis in the live region and assert if
|
||||
* any allocation that could potentially trigger a GC occurs while this guard
|
||||
@ -575,13 +590,24 @@ class JS_PUBLIC_API(AutoAssertGCCallback) : public AutoSuppressGCAnalysis
|
||||
* internal pointers to GC things where the GC thing itself may not be present
|
||||
* for the static analysis: e.g. acquiring inline chars from a JSString* on the
|
||||
* heap.
|
||||
*
|
||||
* We only do the assertion checking in DEBUG builds.
|
||||
*/
|
||||
#ifdef DEBUG
|
||||
class JS_PUBLIC_API(AutoCheckCannotGC) : public AutoAssertOnGC
|
||||
{
|
||||
public:
|
||||
AutoCheckCannotGC() : AutoAssertOnGC() {}
|
||||
explicit AutoCheckCannotGC(JSContext* cx) : AutoAssertOnGC(cx) {}
|
||||
} JS_HAZ_GC_INVALIDATED;
|
||||
#else
|
||||
class JS_PUBLIC_API(AutoCheckCannotGC) : public AutoRequireNoGC
|
||||
{
|
||||
public:
|
||||
AutoCheckCannotGC() {}
|
||||
explicit AutoCheckCannotGC(JSContext* cx) {}
|
||||
} JS_HAZ_GC_INVALIDATED;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Unsets the gray bit for anything reachable from |thing|. |kind| should not be
|
||||
@ -609,6 +635,7 @@ ExposeGCThingToActiveJS(JS::GCCellPtr thing)
|
||||
if (IsInsideNursery(thing.asCell()))
|
||||
return;
|
||||
JS::shadow::Runtime* rt = detail::GetGCThingRuntime(thing.unsafeAsUIntPtr());
|
||||
MOZ_DIAGNOSTIC_ASSERT(rt->allowGCBarriers());
|
||||
if (IsIncrementalBarrierNeededOnTenuredGCThing(rt, thing))
|
||||
JS::IncrementalReferenceBarrier(thing);
|
||||
else if (JS::GCThingIsMarkedGray(thing))
|
||||
@ -619,6 +646,7 @@ static MOZ_ALWAYS_INLINE void
|
||||
MarkGCThingAsLive(JSRuntime* aRt, JS::GCCellPtr thing)
|
||||
{
|
||||
JS::shadow::Runtime* rt = JS::shadow::Runtime::asShadowRuntime(aRt);
|
||||
MOZ_DIAGNOSTIC_ASSERT(rt->allowGCBarriers());
|
||||
/*
|
||||
* Any object in the nursery will not be freed during any GC running at that time.
|
||||
*/
|
||||
@ -676,6 +704,18 @@ PokeGC(JSContext* cx);
|
||||
extern JS_FRIEND_API(void)
|
||||
NotifyDidPaint(JSContext* cx);
|
||||
|
||||
// GC Interrupt callbacks are run during GC. You should not run JS code or use
|
||||
// the JS engine at all while the callback is running. Otherwise they resemble
|
||||
// normal JS interrupt callbacks.
|
||||
typedef bool
|
||||
(* GCInterruptCallback)(JSContext* cx);
|
||||
|
||||
extern JS_FRIEND_API(bool)
|
||||
AddGCInterruptCallback(JSContext* cx, GCInterruptCallback callback);
|
||||
|
||||
extern JS_FRIEND_API(void)
|
||||
RequestGCInterruptCallback(JSContext* cx);
|
||||
|
||||
} /* namespace JS */
|
||||
|
||||
#endif /* js_GCAPI_h */
|
||||
|
@ -7,6 +7,8 @@
|
||||
#ifndef js_SliceBudget_h
|
||||
#define js_SliceBudget_h
|
||||
|
||||
#include "mozilla/Atomics.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
namespace js {
|
||||
@ -36,7 +38,7 @@ class JS_PUBLIC_API(SliceBudget)
|
||||
static const int64_t unlimitedDeadline = INT64_MAX;
|
||||
static const intptr_t unlimitedStartCounter = INTPTR_MAX;
|
||||
|
||||
bool checkOverBudget();
|
||||
bool checkOverBudget(JSContext* maybeCx);
|
||||
|
||||
SliceBudget();
|
||||
|
||||
@ -48,7 +50,7 @@ class JS_PUBLIC_API(SliceBudget)
|
||||
WorkBudget workBudget;
|
||||
|
||||
int64_t deadline; /* in microseconds */
|
||||
intptr_t counter;
|
||||
mozilla::Atomic<intptr_t, mozilla::Relaxed> counter;
|
||||
|
||||
static const intptr_t CounterReset = 1000;
|
||||
|
||||
@ -64,19 +66,44 @@ class JS_PUBLIC_API(SliceBudget)
|
||||
/* Instantiate as SliceBudget(WorkBudget(n)). */
|
||||
explicit SliceBudget(WorkBudget work);
|
||||
|
||||
// Need an explicit copy constructor because Atomic fails to provide one.
|
||||
SliceBudget(const SliceBudget& other)
|
||||
: timeBudget(other.timeBudget),
|
||||
workBudget(other.workBudget),
|
||||
deadline(other.deadline),
|
||||
counter(other.counter)
|
||||
{}
|
||||
|
||||
// Need an explicit operator= because Atomic fails to provide one.
|
||||
SliceBudget& operator=(const SliceBudget& other) {
|
||||
timeBudget = other.timeBudget;
|
||||
workBudget = other.workBudget;
|
||||
deadline = other.deadline;
|
||||
counter = intptr_t(other.counter);
|
||||
return *this;
|
||||
}
|
||||
|
||||
void makeUnlimited() {
|
||||
deadline = unlimitedDeadline;
|
||||
counter = unlimitedStartCounter;
|
||||
}
|
||||
|
||||
// Request that checkOverBudget be called the next time isOverBudget is
|
||||
// called.
|
||||
void requestFullCheck() {
|
||||
counter = 0;
|
||||
}
|
||||
|
||||
void step(intptr_t amt = 1) {
|
||||
counter -= amt;
|
||||
}
|
||||
|
||||
bool isOverBudget() {
|
||||
// Only need to pass maybeCx if the GC interrupt callback should be checked
|
||||
// (and possibly invoked).
|
||||
bool isOverBudget(JSContext* maybeCx = nullptr) {
|
||||
if (counter > 0)
|
||||
return false;
|
||||
return checkOverBudget();
|
||||
return checkOverBudget(maybeCx);
|
||||
}
|
||||
|
||||
bool isWorkBudget() const { return deadline == 0; }
|
||||
|
@ -190,7 +190,7 @@ template bool js::ToSimdConstant<Bool32x4>(JSContext* cx, HandleValue v, jit::Si
|
||||
|
||||
template<typename Elem>
|
||||
static Elem
|
||||
TypedObjectMemory(HandleValue v, const JS::AutoAssertOnGC& nogc)
|
||||
TypedObjectMemory(HandleValue v, const JS::AutoRequireNoGC& nogc)
|
||||
{
|
||||
TypedObject& obj = v.toObject().as<TypedObject>();
|
||||
return reinterpret_cast<Elem>(obj.typedMem(nogc));
|
||||
|
@ -549,14 +549,14 @@ class TypedObject : public ShapedObject
|
||||
|
||||
int32_t offset() const;
|
||||
int32_t length() const;
|
||||
uint8_t* typedMem(const JS::AutoAssertOnGC&) const { return typedMem(); }
|
||||
uint8_t* typedMem(const JS::AutoRequireNoGC&) const { return typedMem(); }
|
||||
bool isAttached() const;
|
||||
|
||||
int32_t size() const {
|
||||
return typeDescr().size();
|
||||
}
|
||||
|
||||
uint8_t* typedMem(size_t offset, const JS::AutoAssertOnGC& nogc) const {
|
||||
uint8_t* typedMem(size_t offset, const JS::AutoRequireNoGC& nogc) const {
|
||||
// It seems a bit surprising that one might request an offset
|
||||
// == size(), but it can happen when taking the "address of" a
|
||||
// 0-sized value. (In other words, we maintain the invariant
|
||||
@ -704,7 +704,7 @@ class InlineTypedObject : public TypedObject
|
||||
return gc::GetGCObjectKindForBytes(nbytes + sizeof(TypedObject));
|
||||
}
|
||||
|
||||
uint8_t* inlineTypedMem(const JS::AutoAssertOnGC&) const {
|
||||
uint8_t* inlineTypedMem(const JS::AutoRequireNoGC&) const {
|
||||
return inlineTypedMem();
|
||||
}
|
||||
|
||||
|
@ -203,7 +203,7 @@ GCRuntime::checkAllocatorState(JSContext* cx, AllocKind kind)
|
||||
|
||||
// Crash if we perform a GC action when it is not safe.
|
||||
if (allowGC && !rt->mainThread.suppressGC)
|
||||
JS::AutoAssertOnGC::VerifyIsSafeToGC(rt);
|
||||
rt->gc.verifyIsSafeToGC();
|
||||
|
||||
// For testing out of memory conditions
|
||||
if (js::oom::ShouldFailWithOOM()) {
|
||||
|
@ -24,6 +24,7 @@ namespace js {
|
||||
|
||||
class AutoLockGC;
|
||||
class AutoLockHelperThreadState;
|
||||
class SliceBudget;
|
||||
class VerifyPreTracer;
|
||||
|
||||
namespace gc {
|
||||
@ -721,13 +722,6 @@ class GCRuntime
|
||||
--noNurseryAllocationCheck;
|
||||
}
|
||||
|
||||
bool isInsideUnsafeRegion() { return inUnsafeRegion != 0; }
|
||||
void enterUnsafeRegion() { ++inUnsafeRegion; }
|
||||
void leaveUnsafeRegion() {
|
||||
MOZ_ASSERT(inUnsafeRegion > 0);
|
||||
--inUnsafeRegion;
|
||||
}
|
||||
|
||||
bool isStrictProxyCheckingEnabled() { return disableStrictProxyCheckingCount == 0; }
|
||||
void disableStrictProxyChecking() { ++disableStrictProxyCheckingCount; }
|
||||
void enableStrictProxyChecking() {
|
||||
@ -736,6 +730,18 @@ class GCRuntime
|
||||
}
|
||||
#endif // DEBUG
|
||||
|
||||
bool isInsideUnsafeRegion() { return inUnsafeRegion != 0; }
|
||||
void enterUnsafeRegion() { ++inUnsafeRegion; }
|
||||
void leaveUnsafeRegion() {
|
||||
MOZ_ASSERT(inUnsafeRegion > 0);
|
||||
--inUnsafeRegion;
|
||||
}
|
||||
|
||||
void verifyIsSafeToGC() {
|
||||
MOZ_DIAGNOSTIC_ASSERT(!isInsideUnsafeRegion(),
|
||||
"[AutoAssertOnGC] possible GC in GC-unsafe region");
|
||||
}
|
||||
|
||||
void setAlwaysPreserveCode() { alwaysPreserveCode = true; }
|
||||
|
||||
bool isIncrementalGCAllowed() const { return incrementalAllowed; }
|
||||
@ -858,6 +864,19 @@ class GCRuntime
|
||||
bool isVerifyPreBarriersEnabled() const { return false; }
|
||||
#endif
|
||||
|
||||
// GC interrupt callbacks.
|
||||
bool addInterruptCallback(JS::GCInterruptCallback callback);
|
||||
void requestInterruptCallback();
|
||||
|
||||
bool checkInterruptCallback(JSContext* cx) {
|
||||
if (interruptCallbackRequested) {
|
||||
invokeInterruptCallback(cx);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
void invokeInterruptCallback(JSContext* cx);
|
||||
|
||||
// Free certain LifoAlloc blocks when it is safe to do so.
|
||||
void freeUnusedLifoBlocksAfterSweeping(LifoAlloc* lifo);
|
||||
void freeAllLifoBlocksAfterSweeping(LifoAlloc* lifo);
|
||||
@ -1070,6 +1089,13 @@ class GCRuntime
|
||||
mozilla::Atomic<uint32_t, mozilla::ReleaseAcquire> numArenasFreeCommitted;
|
||||
VerifyPreTracer* verifyPreData;
|
||||
|
||||
// GC interrupt callbacks.
|
||||
using GCInterruptCallbackVector = js::Vector<JS::GCInterruptCallback, 2, js::SystemAllocPolicy>;
|
||||
GCInterruptCallbackVector interruptCallbacks;
|
||||
|
||||
mozilla::Atomic<bool, mozilla::Relaxed> interruptCallbackRequested;
|
||||
SliceBudget* currentBudget;
|
||||
|
||||
private:
|
||||
bool chunkAllocationSinceLastGC;
|
||||
int64_t lastGCTime;
|
||||
@ -1344,7 +1370,6 @@ class GCRuntime
|
||||
/* Always preserve JIT code during GCs, for testing. */
|
||||
bool alwaysPreserveCode;
|
||||
|
||||
#ifdef DEBUG
|
||||
/*
|
||||
* Some regions of code are hard for the static rooting hazard analysis to
|
||||
* understand. In those cases, we trade the static analysis for a dynamic
|
||||
@ -1353,6 +1378,7 @@ class GCRuntime
|
||||
*/
|
||||
int inUnsafeRegion;
|
||||
|
||||
#ifdef DEBUG
|
||||
size_t noGCOrAllocationCheck;
|
||||
size_t noNurseryAllocationCheck;
|
||||
|
||||
|
@ -1545,13 +1545,15 @@ GCMarker::drainMarkStack(SliceBudget& budget)
|
||||
auto acc = mozilla::MakeScopeExit([&] {strictCompartmentChecking = false;});
|
||||
#endif
|
||||
|
||||
if (budget.isOverBudget())
|
||||
JSContext* cx = runtime()->contextFromMainThread();
|
||||
|
||||
if (budget.isOverBudget(cx))
|
||||
return false;
|
||||
|
||||
for (;;) {
|
||||
while (!stack.isEmpty()) {
|
||||
processMarkStackTop(budget);
|
||||
if (budget.isOverBudget()) {
|
||||
if (budget.isOverBudget(cx)) {
|
||||
saveValueRanges();
|
||||
return false;
|
||||
}
|
||||
@ -1626,6 +1628,8 @@ GCMarker::processMarkStackTop(SliceBudget& budget)
|
||||
uintptr_t tag = addr & StackTagMask;
|
||||
addr &= ~StackTagMask;
|
||||
|
||||
JSContext* cx = runtime()->contextFromMainThread();
|
||||
|
||||
// Dispatch
|
||||
switch (tag) {
|
||||
case ValueArrayTag: {
|
||||
@ -1679,7 +1683,7 @@ GCMarker::processMarkStackTop(SliceBudget& budget)
|
||||
MOZ_ASSERT(vp <= end);
|
||||
while (vp != end) {
|
||||
budget.step();
|
||||
if (budget.isOverBudget()) {
|
||||
if (budget.isOverBudget(cx)) {
|
||||
pushValueArray(obj, vp, end);
|
||||
return;
|
||||
}
|
||||
@ -1709,7 +1713,7 @@ GCMarker::processMarkStackTop(SliceBudget& budget)
|
||||
AssertZoneIsMarking(obj);
|
||||
|
||||
budget.step();
|
||||
if (budget.isOverBudget()) {
|
||||
if (budget.isOverBudget(cx)) {
|
||||
repush(obj);
|
||||
return;
|
||||
}
|
||||
@ -2157,7 +2161,7 @@ GCMarker::markDelayedChildren(SliceBudget& budget)
|
||||
markDelayedChildren(arena);
|
||||
|
||||
budget.step(150);
|
||||
if (budget.isOverBudget())
|
||||
if (budget.isOverBudget(runtime()->contextFromMainThread()))
|
||||
return false;
|
||||
} while (unmarkedArenaStackTop);
|
||||
MOZ_ASSERT(!markLaterArenas);
|
||||
|
@ -188,6 +188,7 @@
|
||||
#include "mozilla/MacroForEach.h"
|
||||
#include "mozilla/MemoryReporting.h"
|
||||
#include "mozilla/Move.h"
|
||||
#include "mozilla/ScopeExit.h"
|
||||
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
@ -506,6 +507,8 @@ FinalizeTypedArenas(FreeOp* fop,
|
||||
size_t thingSize = Arena::thingSize(thingKind);
|
||||
size_t thingsPerArena = Arena::thingsPerArena(thingKind);
|
||||
|
||||
JSContext* cx = fop->onMainThread() ? fop->runtime()->contextFromMainThread() : nullptr;
|
||||
|
||||
while (Arena* arena = *src) {
|
||||
*src = arena->next;
|
||||
size_t nmarked = arena->finalize<T>(fop, thingKind, thingSize);
|
||||
@ -519,7 +522,7 @@ FinalizeTypedArenas(FreeOp* fop,
|
||||
fop->runtime()->gc.releaseArena(arena, maybeLock.ref());
|
||||
|
||||
budget.step(thingsPerArena);
|
||||
if (budget.isOverBudget())
|
||||
if (budget.isOverBudget(cx))
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -808,6 +811,8 @@ GCRuntime::GCRuntime(JSRuntime* rt) :
|
||||
nextCellUniqueId_(LargestTaggedNullCellPointer + 1), // Ensure disjoint from null tagged pointers.
|
||||
numArenasFreeCommitted(0),
|
||||
verifyPreData(nullptr),
|
||||
interruptCallbackRequested(false),
|
||||
currentBudget(nullptr),
|
||||
chunkAllocationSinceLastGC(false),
|
||||
lastGCTime(PRMJ_Now()),
|
||||
mode(JSGC_MODE_INCREMENTAL),
|
||||
@ -864,8 +869,8 @@ GCRuntime::GCRuntime(JSRuntime* rt) :
|
||||
mallocBytesUntilGC(0),
|
||||
mallocGCTriggered(false),
|
||||
alwaysPreserveCode(false),
|
||||
#ifdef DEBUG
|
||||
inUnsafeRegion(0),
|
||||
#ifdef DEBUG
|
||||
noGCOrAllocationCheck(0),
|
||||
noNurseryAllocationCheck(0),
|
||||
arenasEmptyAtShutdown(true),
|
||||
@ -2933,8 +2938,11 @@ SliceBudget::describe(char* buffer, size_t maxlen) const
|
||||
}
|
||||
|
||||
bool
|
||||
SliceBudget::checkOverBudget()
|
||||
SliceBudget::checkOverBudget(JSContext* cx)
|
||||
{
|
||||
if (cx)
|
||||
cx->gc.checkInterruptCallback(cx);
|
||||
|
||||
bool over = PRMJ_Now() >= deadline;
|
||||
if (!over)
|
||||
counter = CounterReset;
|
||||
@ -5481,7 +5489,7 @@ GCRuntime::compactPhase(JS::gcreason::Reason reason, SliceBudget& sliceBudget,
|
||||
updatePointersToRelocatedCells(zone, lock);
|
||||
zone->setGCState(Zone::Finished);
|
||||
zonesToMaybeCompact.removeFront();
|
||||
if (sliceBudget.isOverBudget())
|
||||
if (sliceBudget.isOverBudget(rt->contextFromMainThread()))
|
||||
break;
|
||||
}
|
||||
|
||||
@ -5887,7 +5895,7 @@ GCRuntime::incrementalCollectSlice(SliceBudget& budget, JS::gcreason::Reason rea
|
||||
* now exhasted.
|
||||
*/
|
||||
beginSweepPhase(destroyingRuntime, lock);
|
||||
if (budget.isOverBudget())
|
||||
if (budget.isOverBudget(rt->contextFromMainThread()))
|
||||
break;
|
||||
|
||||
/*
|
||||
@ -6133,7 +6141,7 @@ GCRuntime::gcCycle(bool nonincrementalByAPI, SliceBudget& budget, JS::gcreason::
|
||||
MOZ_ASSERT(!rt->mainThread.suppressGC);
|
||||
|
||||
// Assert if this is a GC unsafe region.
|
||||
JS::AutoAssertOnGC::VerifyIsSafeToGC(rt);
|
||||
verifyIsSafeToGC();
|
||||
|
||||
{
|
||||
gcstats::AutoPhase ap(stats, gcstats::PHASE_WAIT_BACKGROUND_THREAD);
|
||||
@ -6294,6 +6302,11 @@ GCRuntime::collect(bool nonincrementalByAPI, SliceBudget budget, JS::gcreason::R
|
||||
if (!checkIfGCAllowedInCurrentState(reason))
|
||||
return;
|
||||
|
||||
currentBudget = &budget;
|
||||
auto guard = mozilla::MakeScopeExit([&] {
|
||||
currentBudget = nullptr;
|
||||
});
|
||||
|
||||
AutoTraceLog logGC(TraceLoggerForMainThread(rt), TraceLogger_GC);
|
||||
AutoStopVerifyingBarriers av(rt, IsShutdownGC(reason));
|
||||
AutoEnqueuePendingParseTasksAfterGC aept(*this);
|
||||
@ -6974,7 +6987,6 @@ JS::GetGCNumber()
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
JS::AutoAssertOnGC::AutoAssertOnGC()
|
||||
: gc(nullptr), gcNumber(0)
|
||||
{
|
||||
@ -7014,13 +7026,20 @@ JS::AutoAssertOnGC::~AutoAssertOnGC()
|
||||
}
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
JS::AutoAssertOnGC::VerifyIsSafeToGC(JSRuntime* rt)
|
||||
JS::AutoAssertOnBarrier::AutoAssertOnBarrier(JSContext* cx)
|
||||
: context(cx),
|
||||
prev(cx->runtime()->allowGCBarriers())
|
||||
{
|
||||
if (rt->gc.isInsideUnsafeRegion())
|
||||
MOZ_CRASH("[AutoAssertOnGC] possible GC in GC-unsafe region");
|
||||
context->runtime()->allowGCBarriers_ = false;
|
||||
}
|
||||
|
||||
JS::AutoAssertOnBarrier::~AutoAssertOnBarrier()
|
||||
{
|
||||
MOZ_ASSERT(!context->runtime()->allowGCBarriers_);
|
||||
context->runtime()->allowGCBarriers_ = prev;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
JS::AutoAssertNoAlloc::AutoAssertNoAlloc(JSContext* cx)
|
||||
: gc(nullptr)
|
||||
{
|
||||
@ -7662,3 +7681,41 @@ js::gc::Cell::dump() const
|
||||
dump(stderr);
|
||||
}
|
||||
#endif
|
||||
|
||||
bool
|
||||
JS::AddGCInterruptCallback(JSContext* cx, GCInterruptCallback callback)
|
||||
{
|
||||
return cx->runtime()->gc.addInterruptCallback(callback);
|
||||
}
|
||||
|
||||
void
|
||||
JS::RequestGCInterruptCallback(JSContext* cx)
|
||||
{
|
||||
cx->runtime()->gc.requestInterruptCallback();
|
||||
}
|
||||
|
||||
bool
|
||||
GCRuntime::addInterruptCallback(JS::GCInterruptCallback callback)
|
||||
{
|
||||
return interruptCallbacks.append(callback);
|
||||
}
|
||||
|
||||
void
|
||||
GCRuntime::requestInterruptCallback()
|
||||
{
|
||||
if (currentBudget) {
|
||||
interruptCallbackRequested = true;
|
||||
currentBudget->requestFullCheck();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
GCRuntime::invokeInterruptCallback(JSContext* cx)
|
||||
{
|
||||
JS::AutoAssertOnGC nogc(cx);
|
||||
JS::AutoAssertOnBarrier nobarrier(cx);
|
||||
JS::AutoSuppressGCAnalysis suppress;
|
||||
for (JS::GCInterruptCallback callback : interruptCallbacks) {
|
||||
(*callback)(cx);
|
||||
}
|
||||
}
|
||||
|
@ -131,6 +131,7 @@ class StoreBuffer;
|
||||
namespace JS {
|
||||
|
||||
class JS_PUBLIC_API(AutoEnterCycleCollection);
|
||||
class JS_PUBLIC_API(AutoAssertOnBarrier);
|
||||
struct PropertyDescriptor;
|
||||
|
||||
typedef void (*OffThreadCompileCallback)(void* token, void* callbackData);
|
||||
@ -153,11 +154,17 @@ struct Runtime
|
||||
friend class JS::AutoEnterCycleCollection;
|
||||
JS::HeapState heapState_;
|
||||
|
||||
// In some cases, invoking GC barriers (incremental or otherwise) will break
|
||||
// things. These barriers assert if this flag is set.
|
||||
bool allowGCBarriers_;
|
||||
friend class JS::AutoAssertOnBarrier;
|
||||
|
||||
js::gc::StoreBuffer* gcStoreBufferPtr_;
|
||||
|
||||
public:
|
||||
Runtime()
|
||||
: heapState_(JS::HeapState::Idle)
|
||||
, allowGCBarriers_(true)
|
||||
, gcStoreBufferPtr_(nullptr)
|
||||
{}
|
||||
|
||||
@ -169,6 +176,8 @@ struct Runtime
|
||||
return heapState_ == JS::HeapState::CycleCollecting;
|
||||
}
|
||||
|
||||
bool allowGCBarriers() const { return allowGCBarriers_; }
|
||||
|
||||
js::gc::StoreBuffer* gcStoreBufferPtr() { return gcStoreBufferPtr_; }
|
||||
|
||||
static JS::shadow::Runtime* asShadowRuntime(JSRuntime* rt) {
|
||||
|
@ -1498,7 +1498,7 @@ ArrayBufferViewObject::notifyBufferDetached(JSContext* cx, void* newData)
|
||||
}
|
||||
|
||||
uint8_t*
|
||||
ArrayBufferViewObject::dataPointerUnshared(const JS::AutoAssertOnGC& nogc)
|
||||
ArrayBufferViewObject::dataPointerUnshared(const JS::AutoRequireNoGC& nogc)
|
||||
{
|
||||
if (is<DataViewObject>())
|
||||
return static_cast<uint8_t*>(as<DataViewObject>().dataPointer());
|
||||
|
@ -440,7 +440,7 @@ class ArrayBufferViewObject : public JSObject
|
||||
|
||||
// By construction we only need unshared variants here. See
|
||||
// comments in ArrayBufferObject.cpp.
|
||||
uint8_t* dataPointerUnshared(const JS::AutoAssertOnGC&);
|
||||
uint8_t* dataPointerUnshared(const JS::AutoRequireNoGC&);
|
||||
void setDataPointerUnshared(uint8_t* data);
|
||||
|
||||
static void trace(JSTracer* trc, JSObject* obj);
|
||||
|
@ -363,7 +363,7 @@ js::RunScript(JSContext* cx, RunState& state)
|
||||
JS_CHECK_RECURSION(cx, return false);
|
||||
|
||||
// Since any script can conceivably GC, make sure it's safe to do so.
|
||||
JS::AutoAssertOnGC::VerifyIsSafeToGC(cx->runtime());
|
||||
cx->runtime()->gc.verifyIsSafeToGC();
|
||||
|
||||
if (!Debugger::checkNoExecute(cx, state.script()))
|
||||
return false;
|
||||
|
@ -379,14 +379,10 @@ nsFileControlFrame::DnDListener::IsValidDropData(nsIDOMDataTransfer* aDOMDataTra
|
||||
NS_ENSURE_TRUE(dataTransfer, false);
|
||||
|
||||
// We only support dropping files onto a file upload control
|
||||
ErrorResult rv;
|
||||
RefPtr<DOMStringList> types = dataTransfer->GetTypes(rv);
|
||||
if (NS_WARN_IF(rv.Failed())) {
|
||||
rv.SuppressException();
|
||||
return false;
|
||||
}
|
||||
nsTArray<nsString> types;
|
||||
dataTransfer->GetTypes(types, *nsContentUtils::GetSystemPrincipal());
|
||||
|
||||
return types->Contains(NS_LITERAL_STRING("Files"));
|
||||
return types.Contains(NS_LITERAL_STRING("Files"));
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -1626,12 +1626,10 @@ CSSStyleSheet::DidDirty()
|
||||
}
|
||||
|
||||
void
|
||||
CSSStyleSheet::SubjectSubsumesInnerPrincipal(const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
CSSStyleSheet::SubjectSubsumesInnerPrincipal(nsIPrincipal& aSubjectPrincipal,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
MOZ_ASSERT(aSubjectPrincipal.isSome());
|
||||
|
||||
if (aSubjectPrincipal.value()->Subsumes(mInner->mPrincipal)) {
|
||||
if (aSubjectPrincipal.Subsumes(mInner->mPrincipal)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1659,7 +1657,7 @@ CSSStyleSheet::SubjectSubsumesInnerPrincipal(const Maybe<nsIPrincipal*>& aSubjec
|
||||
|
||||
WillDirty();
|
||||
|
||||
mInner->mPrincipal = aSubjectPrincipal.value();
|
||||
mInner->mPrincipal = &aSubjectPrincipal;
|
||||
|
||||
DidDirty();
|
||||
}
|
||||
@ -1782,13 +1780,13 @@ CSSStyleSheet::GetCssRules(nsIDOMCSSRuleList** aCssRules)
|
||||
{
|
||||
ErrorResult rv;
|
||||
nsCOMPtr<nsIDOMCSSRuleList> rules =
|
||||
GetCssRules(Some(nsContentUtils::SubjectPrincipal()), rv);
|
||||
GetCssRules(*nsContentUtils::SubjectPrincipal(), rv);
|
||||
rules.forget(aCssRules);
|
||||
return rv.StealNSResult();
|
||||
}
|
||||
|
||||
CSSRuleList*
|
||||
CSSStyleSheet::GetCssRules(const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
CSSStyleSheet::GetCssRules(nsIPrincipal& aSubjectPrincipal,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
// No doing this on incomplete sheets!
|
||||
@ -1819,13 +1817,13 @@ CSSStyleSheet::InsertRule(const nsAString& aRule,
|
||||
{
|
||||
ErrorResult rv;
|
||||
*aReturn =
|
||||
InsertRule(aRule, aIndex, Some(nsContentUtils::SubjectPrincipal()), rv);
|
||||
InsertRule(aRule, aIndex, *nsContentUtils::SubjectPrincipal(), rv);
|
||||
return rv.StealNSResult();
|
||||
}
|
||||
|
||||
uint32_t
|
||||
CSSStyleSheet::InsertRule(const nsAString& aRule, uint32_t aIndex,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
nsIPrincipal& aSubjectPrincipal,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
//-- Security check: Only scripts whose principal subsumes that of the
|
||||
@ -1977,13 +1975,13 @@ NS_IMETHODIMP
|
||||
CSSStyleSheet::DeleteRule(uint32_t aIndex)
|
||||
{
|
||||
ErrorResult rv;
|
||||
DeleteRule(aIndex, Some(nsContentUtils::SubjectPrincipal()), rv);
|
||||
DeleteRule(aIndex, *nsContentUtils::SubjectPrincipal(), rv);
|
||||
return rv.StealNSResult();
|
||||
}
|
||||
|
||||
void
|
||||
CSSStyleSheet::DeleteRule(uint32_t aIndex,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
nsIPrincipal& aSubjectPrincipal,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
// No doing this if the sheet is not complete!
|
||||
|
@ -246,14 +246,14 @@ public:
|
||||
// called GetOwnerRule because that would be ambiguous with the ImportRule
|
||||
// version.
|
||||
nsIDOMCSSRule* GetDOMOwnerRule() const;
|
||||
dom::CSSRuleList* GetCssRules(const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
dom::CSSRuleList* GetCssRules(nsIPrincipal& aSubjectPrincipal,
|
||||
ErrorResult& aRv);
|
||||
uint32_t InsertRule(const nsAString& aRule, uint32_t aIndex,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
nsIPrincipal& aSubjectPrincipal,
|
||||
ErrorResult& aRv);
|
||||
|
||||
void DeleteRule(uint32_t aIndex,
|
||||
const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
nsIPrincipal& aSubjectPrincipal,
|
||||
ErrorResult& aRv);
|
||||
|
||||
// WebIDL miscellaneous bits
|
||||
@ -291,7 +291,7 @@ protected:
|
||||
// inner, error otherwise. This will also succeed if the subject has
|
||||
// UniversalXPConnect or if access is allowed by CORS. In the latter case,
|
||||
// it will set the principal of the inner to the subject principal.
|
||||
void SubjectSubsumesInnerPrincipal(const Maybe<nsIPrincipal*>& aSubjectPrincipal,
|
||||
void SubjectSubsumesInnerPrincipal(nsIPrincipal& aSubjectPrincipal,
|
||||
ErrorResult& aRv);
|
||||
|
||||
// Add the namespace mapping from this @namespace rule to our namespace map
|
||||
|
@ -38,13 +38,13 @@ SERVO_BINDING_FUNC(Servo_StyleSheet_HasRules, bool,
|
||||
SERVO_BINDING_FUNC(Servo_StyleSet_Init, RawServoStyleSetOwned)
|
||||
SERVO_BINDING_FUNC(Servo_StyleSet_Drop, void, RawServoStyleSetOwned set)
|
||||
SERVO_BINDING_FUNC(Servo_StyleSet_AppendStyleSheet, void,
|
||||
RawServoStyleSetBorrowedMut set, RawServoStyleSheetBorrowed sheet)
|
||||
RawServoStyleSetBorrowed set, RawServoStyleSheetBorrowed sheet)
|
||||
SERVO_BINDING_FUNC(Servo_StyleSet_PrependStyleSheet, void,
|
||||
RawServoStyleSetBorrowedMut set, RawServoStyleSheetBorrowed sheet)
|
||||
RawServoStyleSetBorrowed set, RawServoStyleSheetBorrowed sheet)
|
||||
SERVO_BINDING_FUNC(Servo_StyleSet_RemoveStyleSheet, void,
|
||||
RawServoStyleSetBorrowedMut set, RawServoStyleSheetBorrowed sheet)
|
||||
RawServoStyleSetBorrowed set, RawServoStyleSheetBorrowed sheet)
|
||||
SERVO_BINDING_FUNC(Servo_StyleSet_InsertStyleSheetBefore, void,
|
||||
RawServoStyleSetBorrowedMut set, RawServoStyleSheetBorrowed sheet,
|
||||
RawServoStyleSetBorrowed set, RawServoStyleSheetBorrowed sheet,
|
||||
RawServoStyleSheetBorrowed reference)
|
||||
|
||||
// Animations API
|
||||
@ -96,12 +96,12 @@ SERVO_BINDING_FUNC(Servo_ComputedValues_Get, ServoComputedValuesStrong,
|
||||
SERVO_BINDING_FUNC(Servo_ComputedValues_GetForAnonymousBox,
|
||||
ServoComputedValuesStrong,
|
||||
ServoComputedValuesBorrowedOrNull parent_style_or_null,
|
||||
nsIAtom* pseudoTag, RawServoStyleSetBorrowedMut set)
|
||||
nsIAtom* pseudoTag, RawServoStyleSetBorrowed set)
|
||||
SERVO_BINDING_FUNC(Servo_ComputedValues_GetForPseudoElement,
|
||||
ServoComputedValuesStrong,
|
||||
ServoComputedValuesBorrowed parent_style,
|
||||
RawGeckoElementBorrowed match_element, nsIAtom* pseudo_tag,
|
||||
RawServoStyleSetBorrowedMut set, bool is_probe)
|
||||
RawServoStyleSetBorrowed set, bool is_probe)
|
||||
SERVO_BINDING_FUNC(Servo_ComputedValues_Inherit, ServoComputedValuesStrong,
|
||||
ServoComputedValuesBorrowedOrNull parent_style)
|
||||
SERVO_BINDING_FUNC(Servo_ComputedValues_AddRef, void,
|
||||
@ -121,7 +121,7 @@ SERVO_BINDING_FUNC(Servo_ComputeRestyleHint, nsRestyleHint,
|
||||
|
||||
// Restyle the given subtree.
|
||||
SERVO_BINDING_FUNC(Servo_RestyleSubtree, void,
|
||||
RawGeckoNodeBorrowed node, RawServoStyleSetBorrowedMut set)
|
||||
RawGeckoNodeBorrowed node, RawServoStyleSetBorrowed set)
|
||||
|
||||
// Style-struct management.
|
||||
#define STYLE_STRUCT(name, checkdata_cb) \
|
||||
|
@ -110,9 +110,18 @@ public:
|
||||
void Clear();
|
||||
|
||||
// Must be copy-constructable and assignable
|
||||
#if defined(XP_WIN) && (defined(_M_IX86) || defined(_M_X64))
|
||||
#pragma pack(1)
|
||||
#endif
|
||||
struct nsEntry
|
||||
{
|
||||
nsHttpAtom header;
|
||||
#if defined(XP_WIN) && (defined(_M_IX86) || defined(_M_X64))
|
||||
char padding[4096 -
|
||||
sizeof(nsTArrayHeader) -
|
||||
sizeof(nsHttpAtom) -
|
||||
sizeof(void*)];
|
||||
#endif
|
||||
nsCString value;
|
||||
HeaderVariety variety = eVarietyUnknown;
|
||||
|
||||
@ -127,6 +136,9 @@ public:
|
||||
return header == aOther.header && value == aOther.value;
|
||||
}
|
||||
};
|
||||
#if defined(XP_WIN) && (defined(_M_IX86) || defined(_M_X64))
|
||||
#pragma pack()
|
||||
#endif
|
||||
|
||||
bool operator==(const nsHttpHeaderArray& aOther) const
|
||||
{
|
||||
|
@ -16,6 +16,26 @@
|
||||
namespace mozilla {
|
||||
namespace net {
|
||||
|
||||
#if defined(XP_WIN) && (defined(_M_IX86) || defined(_M_X64))
|
||||
void nsHttpRequestHead::DbgReentrantMonitorAutoEnter::Protect(bool aOn)
|
||||
{
|
||||
if (XRE_GetProcessType() == GeckoProcessType_Content &&
|
||||
mInst.mHeaders.Count()) {
|
||||
DWORD oldProtect;
|
||||
LPVOID hdr = reinterpret_cast<PUINT8>(mInst.mHeaders.mHeaders.Elements()) -
|
||||
sizeof(nsTArrayHeader);
|
||||
if (aOn) {
|
||||
VirtualProtect(hdr, 4096, PAGE_READONLY, &oldProtect);
|
||||
} else {
|
||||
VirtualProtect(hdr, 4096, PAGE_READWRITE, &oldProtect);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#define ReentrantMonitorAutoEnter DbgReentrantMonitorAutoEnter
|
||||
#define mon(x) mon(*this)
|
||||
#endif
|
||||
|
||||
nsHttpRequestHead::nsHttpRequestHead()
|
||||
: mMethod(NS_LITERAL_CSTRING("GET"))
|
||||
, mVersion(NS_HTTP_VERSION_1_1)
|
||||
@ -29,6 +49,14 @@ nsHttpRequestHead::nsHttpRequestHead()
|
||||
|
||||
nsHttpRequestHead::~nsHttpRequestHead()
|
||||
{
|
||||
#if defined(XP_WIN) && (defined(_M_IX86) || defined(_M_X64))
|
||||
if (XRE_GetProcessType() == GeckoProcessType_Content && mHeaders.Count()) {
|
||||
DWORD oldProtect;
|
||||
LPVOID hdr = reinterpret_cast<PUINT8>(mHeaders.mHeaders.Elements()) -
|
||||
sizeof(nsTArrayHeader);
|
||||
VirtualProtect(hdr, 4096, PAGE_READWRITE, &oldProtect);
|
||||
}
|
||||
#endif
|
||||
MOZ_COUNT_DTOR(nsHttpRequestHead);
|
||||
}
|
||||
|
||||
@ -365,5 +393,10 @@ nsHttpRequestHead::Flatten(nsACString &buf, bool pruneProxyHeaders)
|
||||
mHeaders.Flatten(buf, pruneProxyHeaders, false);
|
||||
}
|
||||
|
||||
#if defined(XP_WIN) && (defined(_M_IX86) || defined(_M_X64))
|
||||
#undef ReentrantMonitorAutoEnter
|
||||
#undef mon
|
||||
#endif
|
||||
|
||||
} // namespace net
|
||||
} // namespace mozilla
|
||||
|
@ -120,6 +120,28 @@ private:
|
||||
|
||||
// During VisitHeader we sould not allow cal to SetHeader.
|
||||
bool mInVisitHeaders;
|
||||
|
||||
#if defined(XP_WIN) && (defined(_M_IX86) || defined(_M_X64))
|
||||
class DbgReentrantMonitorAutoEnter : ReentrantMonitorAutoEnter
|
||||
{
|
||||
public:
|
||||
explicit DbgReentrantMonitorAutoEnter(nsHttpRequestHead& aInst)
|
||||
: ReentrantMonitorAutoEnter(aInst.mReentrantMonitor),
|
||||
mInst(aInst)
|
||||
{
|
||||
Protect(false);
|
||||
}
|
||||
~DbgReentrantMonitorAutoEnter(void)
|
||||
{
|
||||
Protect(true);
|
||||
}
|
||||
|
||||
private:
|
||||
void Protect(bool aOn);
|
||||
|
||||
nsHttpRequestHead& mInst;
|
||||
};
|
||||
#endif
|
||||
};
|
||||
|
||||
} // namespace net
|
||||
|
@ -515,7 +515,7 @@ ViewSourceChrome.prototype = {
|
||||
// set the dropEffect to 'none'. This prevents the drop even if some
|
||||
// other listener cancelled the event.
|
||||
let types = event.dataTransfer.types;
|
||||
if (types.contains("text/x-moz-text-internal") && !types.contains("text/plain")) {
|
||||
if (types.includes("text/x-moz-text-internal") && !types.includes("text/plain")) {
|
||||
event.dataTransfer.dropEffect = "none";
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
|
@ -655,7 +655,7 @@ function onToolbarDragOver(aEvent)
|
||||
}
|
||||
|
||||
var documentId = gToolboxDocument.documentElement.id;
|
||||
if (!aEvent.dataTransfer.types.contains("text/toolbarwrapper-id/" + documentId.toLowerCase()))
|
||||
if (!aEvent.dataTransfer.types.includes("text/toolbarwrapper-id/" + documentId.toLowerCase()))
|
||||
return;
|
||||
|
||||
var toolbar = aEvent.target;
|
||||
@ -784,7 +784,7 @@ function onPaletteDragOver(aEvent)
|
||||
return;
|
||||
}
|
||||
var documentId = gToolboxDocument.documentElement.id;
|
||||
if (aEvent.dataTransfer.types.contains("text/toolbarwrapper-id/" + documentId.toLowerCase()))
|
||||
if (aEvent.dataTransfer.types.includes("text/toolbarwrapper-id/" + documentId.toLowerCase()))
|
||||
aEvent.preventDefault();
|
||||
}
|
||||
|
||||
|
@ -1445,7 +1445,7 @@
|
||||
// set the dropEffect to 'none'. This prevents the drop even if some
|
||||
// other listener cancelled the event.
|
||||
var types = event.dataTransfer.types;
|
||||
if (types.contains("text/x-moz-text-internal") && !types.contains("text/plain")) {
|
||||
if (types.includes("text/x-moz-text-internal") && !types.includes("text/plain")) {
|
||||
event.dataTransfer.dropEffect = "none";
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
|
@ -139,7 +139,7 @@
|
||||
]]></handler>
|
||||
|
||||
<handler event="dragover"><![CDATA[
|
||||
if (event.dataTransfer.types.contains("text/plain"))
|
||||
if (event.dataTransfer.types.includes("text/plain"))
|
||||
event.preventDefault();
|
||||
]]></handler>
|
||||
|
||||
|
@ -661,9 +661,9 @@ var gDownloadDNDObserver =
|
||||
onDragOver: function (aEvent)
|
||||
{
|
||||
var types = aEvent.dataTransfer.types;
|
||||
if (types.contains("text/uri-list") ||
|
||||
types.contains("text/x-moz-url") ||
|
||||
types.contains("text/plain"))
|
||||
if (types.includes("text/uri-list") ||
|
||||
types.includes("text/x-moz-url") ||
|
||||
types.includes("text/plain"))
|
||||
aEvent.preventDefault();
|
||||
},
|
||||
|
||||
|
@ -3820,9 +3820,9 @@ var gUpdatesView = {
|
||||
var gDragDrop = {
|
||||
onDragOver: function(aEvent) {
|
||||
var types = aEvent.dataTransfer.types;
|
||||
if (types.contains("text/uri-list") ||
|
||||
types.contains("text/x-moz-url") ||
|
||||
types.contains("application/x-moz-file"))
|
||||
if (types.includes("text/uri-list") ||
|
||||
types.includes("text/x-moz-url") ||
|
||||
types.includes("application/x-moz-file"))
|
||||
aEvent.preventDefault();
|
||||
},
|
||||
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include <X11/XKBlib.h>
|
||||
#include "WidgetUtils.h"
|
||||
#include "keysym2ucs.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsGtkUtils.h"
|
||||
#include "nsIBidiKeyboard.h"
|
||||
#include "nsServiceManagerUtils.h"
|
||||
@ -41,7 +42,6 @@ KeymapWrapper* KeymapWrapper::sInstance = nullptr;
|
||||
guint KeymapWrapper::sLastRepeatableHardwareKeyCode = 0;
|
||||
KeymapWrapper::RepeatState KeymapWrapper::sRepeatState =
|
||||
KeymapWrapper::NOT_PRESSED;
|
||||
nsIBidiKeyboard* sBidiKeyboard = nullptr;
|
||||
|
||||
static const char* GetBoolName(bool aBool)
|
||||
{
|
||||
@ -170,6 +170,8 @@ KeymapWrapper::KeymapWrapper() :
|
||||
g_object_ref(mGdkKeymap);
|
||||
g_signal_connect(mGdkKeymap, "keys-changed",
|
||||
(GCallback)OnKeysChanged, this);
|
||||
g_signal_connect(mGdkKeymap, "direction-changed",
|
||||
(GCallback)OnDirectionChanged, this);
|
||||
|
||||
if (GDK_IS_X11_DISPLAY(gdk_display_get_default()))
|
||||
InitXKBExtension();
|
||||
@ -442,8 +444,9 @@ KeymapWrapper::~KeymapWrapper()
|
||||
gdk_window_remove_filter(nullptr, FilterEvents, this);
|
||||
g_signal_handlers_disconnect_by_func(mGdkKeymap,
|
||||
FuncToGpointer(OnKeysChanged), this);
|
||||
g_signal_handlers_disconnect_by_func(mGdkKeymap,
|
||||
FuncToGpointer(OnDirectionChanged), this);
|
||||
g_object_unref(mGdkKeymap);
|
||||
NS_IF_RELEASE(sBidiKeyboard);
|
||||
MOZ_LOG(gKeymapWrapperLog, LogLevel::Info,
|
||||
("%p Destructor", this));
|
||||
}
|
||||
@ -519,6 +522,17 @@ KeymapWrapper::FilterEvents(GdkXEvent* aXEvent,
|
||||
return GDK_FILTER_CONTINUE;
|
||||
}
|
||||
|
||||
static void
|
||||
ResetBidiKeyboard()
|
||||
{
|
||||
// Reset the bidi keyboard settings for the new GdkKeymap
|
||||
nsCOMPtr<nsIBidiKeyboard> bidiKeyboard = nsContentUtils::GetBidiKeyboard();
|
||||
if (bidiKeyboard) {
|
||||
bidiKeyboard->Reset();
|
||||
}
|
||||
WidgetUtils::SendBidiKeyboardInfoToContent();
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
KeymapWrapper::OnKeysChanged(GdkKeymap *aGdkKeymap,
|
||||
KeymapWrapper* aKeymapWrapper)
|
||||
@ -533,14 +547,27 @@ KeymapWrapper::OnKeysChanged(GdkKeymap *aGdkKeymap,
|
||||
// We cannot reintialize here becasue we don't have GdkWindow which is using
|
||||
// the GdkKeymap. We'll reinitialize it when next GetInstance() is called.
|
||||
sInstance->mInitialized = false;
|
||||
ResetBidiKeyboard();
|
||||
}
|
||||
|
||||
// Reset the bidi keyboard settings for the new GdkKeymap
|
||||
if (!sBidiKeyboard) {
|
||||
CallGetService("@mozilla.org/widget/bidikeyboard;1", &sBidiKeyboard);
|
||||
}
|
||||
if (sBidiKeyboard) {
|
||||
sBidiKeyboard->Reset();
|
||||
}
|
||||
// static
|
||||
void
|
||||
KeymapWrapper::OnDirectionChanged(GdkKeymap *aGdkKeymap,
|
||||
KeymapWrapper* aKeymapWrapper)
|
||||
{
|
||||
// XXX
|
||||
// A lot of diretion-changed signal might be fired on switching bidi
|
||||
// keyboard when using both ibus (with arabic layout) and fcitx (with IME).
|
||||
// See https://github.com/fcitx/fcitx/issues/257
|
||||
//
|
||||
// Also, when using ibus, switching to IM might not cause this signal.
|
||||
// See https://github.com/ibus/ibus/issues/1848
|
||||
|
||||
MOZ_LOG(gKeymapWrapperLog, LogLevel::Info,
|
||||
("OnDirectionChanged, aGdkKeymap=%p, aKeymapWrapper=%p",
|
||||
aGdkKeymap, aKeymapWrapper));
|
||||
|
||||
ResetBidiKeyboard();
|
||||
}
|
||||
|
||||
/* static */ guint
|
||||
|
@ -257,6 +257,8 @@ protected:
|
||||
* Signal handlers.
|
||||
*/
|
||||
static void OnKeysChanged(GdkKeymap* aKeymap, KeymapWrapper* aKeymapWrapper);
|
||||
static void OnDirectionChanged(GdkKeymap *aGdkKeymap,
|
||||
KeymapWrapper* aKeymapWrapper);
|
||||
|
||||
/**
|
||||
* GetCharCodeFor() Computes what character is inputted by the key event
|
||||
|
Loading…
Reference in New Issue
Block a user