mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 911864 - Make in-content XBL event handlers allowuntrusted=false by default. r=smaug
This commit is contained in:
parent
c8fd7ea7d1
commit
c3012b9053
@ -154,8 +154,9 @@ nsXBLService::getClass(nsCStringKey *k)
|
||||
|
||||
// Constructors/Destructors
|
||||
nsXBLBinding::nsXBLBinding(nsXBLPrototypeBinding* aBinding)
|
||||
: mMarkedForDeath(false),
|
||||
mPrototypeBinding(aBinding)
|
||||
: mMarkedForDeath(false)
|
||||
, mUsingXBLScope(false)
|
||||
, mPrototypeBinding(aBinding)
|
||||
{
|
||||
NS_ASSERTION(mPrototypeBinding, "Must have a prototype binding!");
|
||||
// Grab a ref to the document info so the prototype binding won't die
|
||||
@ -297,6 +298,20 @@ nsXBLBinding::SetBoundElement(nsIContent* aElement)
|
||||
mBoundElement = aElement;
|
||||
if (mNextBinding)
|
||||
mNextBinding->SetBoundElement(aElement);
|
||||
|
||||
if (!mBoundElement) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Compute whether we're using an XBL scope.
|
||||
//
|
||||
// We disable XBL scopes for remote XUL, where we care about compat more
|
||||
// than security. So we need to know whether we're using an XBL scope so that
|
||||
// we can decide what to do about untrusted events when "allowuntrusted"
|
||||
// is not given in the handler declaration.
|
||||
nsCOMPtr<nsIGlobalObject> go = mBoundElement->OwnerDoc()->GetScopeObject();
|
||||
NS_ENSURE_TRUE_VOID(go && go->GetGlobalJSObject());
|
||||
mUsingXBLScope = xpc::UseXBLScope(js::GetObjectCompartment(go->GetGlobalJSObject()));
|
||||
}
|
||||
|
||||
bool
|
||||
@ -530,7 +545,7 @@ nsXBLBinding::InstallEventHandlers()
|
||||
|
||||
bool hasAllowUntrustedAttr = curr->HasAllowUntrustedAttr();
|
||||
if ((hasAllowUntrustedAttr && curr->AllowUntrustedEvents()) ||
|
||||
(!hasAllowUntrustedAttr && !isChromeDoc)) {
|
||||
(!hasAllowUntrustedAttr && !isChromeDoc && !mUsingXBLScope)) {
|
||||
flags.mAllowUntrustedEvents = true;
|
||||
}
|
||||
|
||||
@ -546,6 +561,7 @@ nsXBLBinding::InstallEventHandlers()
|
||||
for (i = 0; i < keyHandlers->Count(); ++i) {
|
||||
nsXBLKeyEventHandler* handler = keyHandlers->ObjectAt(i);
|
||||
handler->SetIsBoundToChrome(isChromeDoc);
|
||||
handler->SetUsingXBLScope(mUsingXBLScope);
|
||||
|
||||
nsAutoString type;
|
||||
handler->GetEventName(type);
|
||||
|
@ -162,6 +162,7 @@ public:
|
||||
protected:
|
||||
|
||||
bool mMarkedForDeath;
|
||||
bool mUsingXBLScope;
|
||||
|
||||
nsXBLPrototypeBinding* mPrototypeBinding; // Weak, but we're holding a ref to the docinfo
|
||||
nsCOMPtr<nsIContent> mContent; // Strong. Our anonymous content stays around with us.
|
||||
|
@ -70,7 +70,8 @@ nsXBLKeyEventHandler::nsXBLKeyEventHandler(nsIAtom* aEventType, uint8_t aPhase,
|
||||
: mEventType(aEventType),
|
||||
mPhase(aPhase),
|
||||
mType(aType),
|
||||
mIsBoundToChrome(false)
|
||||
mIsBoundToChrome(false),
|
||||
mUsingXBLScope(false)
|
||||
{
|
||||
}
|
||||
|
||||
@ -96,7 +97,7 @@ nsXBLKeyEventHandler::ExecuteMatchedHandlers(nsIDOMKeyEvent* aKeyEvent,
|
||||
bool hasAllowUntrustedAttr = handler->HasAllowUntrustedAttr();
|
||||
if ((trustedEvent ||
|
||||
(hasAllowUntrustedAttr && handler->AllowUntrustedEvents()) ||
|
||||
(!hasAllowUntrustedAttr && !mIsBoundToChrome)) &&
|
||||
(!hasAllowUntrustedAttr && !mIsBoundToChrome && !mUsingXBLScope)) &&
|
||||
handler->KeyEventMatched(aKeyEvent, aCharCode, aIgnoreShiftKey)) {
|
||||
handler->ExecuteHandler(target, aKeyEvent);
|
||||
executed = true;
|
||||
|
@ -85,6 +85,12 @@ public:
|
||||
{
|
||||
mIsBoundToChrome = aIsBoundToChrome;
|
||||
}
|
||||
|
||||
void SetUsingXBLScope(bool aUsingXBLScope)
|
||||
{
|
||||
mUsingXBLScope = aUsingXBLScope;
|
||||
}
|
||||
|
||||
private:
|
||||
nsXBLKeyEventHandler();
|
||||
bool ExecuteMatchedHandlers(nsIDOMKeyEvent* aEvent, uint32_t aCharCode,
|
||||
@ -95,6 +101,7 @@ private:
|
||||
uint8_t mPhase;
|
||||
uint8_t mType;
|
||||
bool mIsBoundToChrome;
|
||||
bool mUsingXBLScope;
|
||||
};
|
||||
|
||||
nsresult
|
||||
|
@ -103,7 +103,10 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=821850
|
||||
</property>
|
||||
</implementation>
|
||||
<handlers>
|
||||
<handler event="testevent" action="ok(true, 'called event handler'); finish();"/>
|
||||
<handler event="testevent" action="ok(true, 'called event handler'); finish();" allowuntrusted="true"/>
|
||||
<handler event="testtrusted" action="ok(true, 'called trusted handler'); window.wrappedJSObject.triggeredTrustedHandler = true;"/>
|
||||
<handler event="keyup" action="ok(true, 'called untrusted key handler'); window.wrappedJSObject.triggeredUntrustedKeyHandler = true;" allowuntrusted="true"/>
|
||||
<handler event="keydown" action="ok(true, 'called trusted key handler'); window.wrappedJSObject.triggeredTrustedKeyHandler = true;"/>
|
||||
</handlers>
|
||||
</binding>
|
||||
</bindings>
|
||||
@ -206,6 +209,58 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=821850
|
||||
Object.defineProperty(bound, 'prop', {value: "redefined"});
|
||||
bound.primitiveField = 321;
|
||||
|
||||
// We need a chrome window to create trusted events. This isn't really doable
|
||||
// in child processes, so let's just skip if that's the case.
|
||||
if (SpecialPowers.isMainProcess()) {
|
||||
var Ci = SpecialPowers.Ci;
|
||||
var chromeWin = SpecialPowers.wrap(window.top)
|
||||
.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIWebNavigation)
|
||||
.QueryInterface(Ci.nsIDocShell)
|
||||
.chromeEventHandler.ownerDocument.defaultView;
|
||||
|
||||
// Untrusted events should not trigger event handlers without
|
||||
// exposeToUntrustedContent=true.
|
||||
window.triggeredTrustedHandler = false;
|
||||
var untrustedEvent = new CustomEvent('testtrusted');
|
||||
ok(!untrustedEvent.isTrusted, "Created an untrusted event");
|
||||
bound.dispatchEvent(untrustedEvent);
|
||||
ok(!window.triggeredTrustedHandler, "untrusted events should not trigger trusted handler");
|
||||
var trustedEvent = new chromeWin.CustomEvent('testtrusted');
|
||||
ok(trustedEvent.isTrusted, "Created a trusted event");
|
||||
SpecialPowers.wrap(bound).dispatchEvent(trustedEvent);
|
||||
ok(window.triggeredTrustedHandler, "trusted events should trigger trusted handler");
|
||||
|
||||
//
|
||||
// We check key events as well, since they're implemented differently.
|
||||
//
|
||||
// NB: We don't check isTrusted on the events we create here, because
|
||||
// according to smaug, old-style event initialization doesn't mark the
|
||||
// event as trusted until it's dispatched.
|
||||
//
|
||||
|
||||
window.triggeredUntrustedKeyHandler = false;
|
||||
window.triggeredTrustedKeyHandler = false;
|
||||
|
||||
// Untrusted event, permissive handler.
|
||||
var untrustedKeyEvent = document.createEvent('KeyboardEvent');
|
||||
untrustedKeyEvent.initEvent('keyup', true, true);
|
||||
bound.dispatchEvent(untrustedKeyEvent);
|
||||
ok(window.triggeredUntrustedKeyHandler, "untrusted key events should trigger untrusted handler");
|
||||
|
||||
// Untrusted event, strict handler.
|
||||
var fakeTrustedKeyEvent = document.createEvent('KeyboardEvent');
|
||||
fakeTrustedKeyEvent.initEvent('keydown', true, true);
|
||||
bound.dispatchEvent(fakeTrustedKeyEvent);
|
||||
ok(!window.triggeredTrustedKeyHandler, "untrusted key events should not trigger trusted handler");
|
||||
|
||||
// Trusted event, strict handler.
|
||||
var trustedKeyEvent = chromeWin.document.createEvent('KeyboardEvent');
|
||||
trustedKeyEvent.initEvent('keydown', true, true);
|
||||
SpecialPowers.wrap(bound).dispatchEvent(trustedKeyEvent);
|
||||
ok(window.triggeredTrustedKeyHandler, "trusted key events should trigger trusted handler");
|
||||
}
|
||||
|
||||
// Hand control back to the XBL scope by dispatching an event on the bound element.
|
||||
bound.dispatchEvent(new CustomEvent('testevent'));
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=403162
|
||||
<bindings xmlns="http://www.mozilla.org/xbl">
|
||||
<binding id="test">
|
||||
<handlers>
|
||||
<handler event="foo" action="XPCNativeWrapper.unwrap(window).triggerCount++"/>
|
||||
<handler event="foo" action="XPCNativeWrapper.unwrap(window).triggerCount++" allowuntrusted="true"/>
|
||||
</handlers>
|
||||
</binding>
|
||||
</bindings>
|
||||
|
@ -9,9 +9,9 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=403162
|
||||
<bindings xmlns="http://www.mozilla.org/xbl">
|
||||
<binding id="test">
|
||||
<handlers>
|
||||
<handler event="DOMMouseScroll" action="XPCNativeWrapper.unwrap(window).triggerCount++"/>
|
||||
<handler event="DOMMouseScroll" modifiers="shift" action="XPCNativeWrapper.unwrap(window).shiftCount++"/>
|
||||
<handler event="DOMMouseScroll" modifiers="control" action="XPCNativeWrapper.unwrap(window).controlCount++"/>
|
||||
<handler event="DOMMouseScroll" action="XPCNativeWrapper.unwrap(window).triggerCount++" allowuntrusted="true"/>
|
||||
<handler event="DOMMouseScroll" modifiers="shift" action="XPCNativeWrapper.unwrap(window).shiftCount++" allowuntrusted="true"/>
|
||||
<handler event="DOMMouseScroll" modifiers="control" action="XPCNativeWrapper.unwrap(window).controlCount++" allowuntrusted="true"/>
|
||||
</handlers>
|
||||
</binding>
|
||||
</bindings>
|
||||
|
@ -298,6 +298,13 @@ bool AllowXBLScope(JSCompartment *c)
|
||||
XPCWrappedNativeScope *scope = EnsureCompartmentPrivate(c)->scope;
|
||||
return scope && scope->AllowXBLScope();
|
||||
}
|
||||
|
||||
bool UseXBLScope(JSCompartment *c)
|
||||
{
|
||||
XPCWrappedNativeScope *scope = EnsureCompartmentPrivate(c)->scope;
|
||||
return scope && scope->UseXBLScope();
|
||||
}
|
||||
|
||||
} /* namespace xpc */
|
||||
|
||||
XPCWrappedNativeScope::~XPCWrappedNativeScope()
|
||||
|
@ -1369,6 +1369,7 @@ public:
|
||||
|
||||
bool IsXBLScope() { return mIsXBLScope; }
|
||||
bool AllowXBLScope();
|
||||
bool UseXBLScope() { return mUseXBLScope; }
|
||||
|
||||
protected:
|
||||
virtual ~XPCWrappedNativeScope();
|
||||
|
@ -54,6 +54,13 @@ GetXBLScope(JSContext *cx, JSObject *contentScope);
|
||||
bool
|
||||
AllowXBLScope(JSCompartment *c);
|
||||
|
||||
// Returns whether we will use an XBL scope for this compartment. This is
|
||||
// semantically equivalent to comparing global != GetXBLScope(global), but it
|
||||
// does not have the side-effect of eagerly creating the XBL scope if it does
|
||||
// not already exist.
|
||||
bool
|
||||
UseXBLScope(JSCompartment *c);
|
||||
|
||||
bool
|
||||
IsSandboxPrototypeProxy(JSObject *obj);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user