зеркало из https://github.com/mozilla/gecko-dev.git
XBL needs simple defense against infinite recursion. b=55070 r+sr=bzbarsky
This commit is contained in:
Родитель
d660796ee2
Коммит
ec8d1d8cb7
|
@ -23,6 +23,7 @@
|
||||||
* Original Author: David W. Hyatt (hyatt@netscape.com)
|
* Original Author: David W. Hyatt (hyatt@netscape.com)
|
||||||
* - Brendan Eich (brendan@mozilla.org)
|
* - Brendan Eich (brendan@mozilla.org)
|
||||||
* - Mike Pinkerton (pinkerton@netscape.com)
|
* - Mike Pinkerton (pinkerton@netscape.com)
|
||||||
|
* Mats Palmgren <mats.palmgren@bredband.net>
|
||||||
*
|
*
|
||||||
* Alternatively, the contents of this file may be used under the terms of
|
* Alternatively, the contents of this file may be used under the terms of
|
||||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||||
|
@ -121,7 +122,8 @@ IsAncestorBinding(nsIDocument* aDocument,
|
||||||
nsresult rv =
|
nsresult rv =
|
||||||
binding->PrototypeBinding()->BindingURI()->Equals(aChildBindingURI,
|
binding->PrototypeBinding()->BindingURI()->Equals(aChildBindingURI,
|
||||||
&equal);
|
&equal);
|
||||||
if (NS_FAILED(rv) || equal) {
|
NS_ENSURE_SUCCESS(rv, PR_TRUE); // assume the worst
|
||||||
|
if (equal) {
|
||||||
nsCAutoString spec;
|
nsCAutoString spec;
|
||||||
aChildBindingURI->GetSpec(spec);
|
aChildBindingURI->GetSpec(spec);
|
||||||
NS_ConvertUTF8toUTF16 bindingURI(spec);
|
NS_ConvertUTF8toUTF16 bindingURI(spec);
|
||||||
|
@ -838,6 +840,17 @@ nsresult
|
||||||
nsXBLService::GetBinding(nsIContent* aBoundElement, nsIURI* aURI,
|
nsXBLService::GetBinding(nsIContent* aBoundElement, nsIURI* aURI,
|
||||||
PRBool aPeekOnly, PRBool* aIsReady,
|
PRBool aPeekOnly, PRBool* aIsReady,
|
||||||
nsXBLBinding** aResult)
|
nsXBLBinding** aResult)
|
||||||
|
{
|
||||||
|
// More than 6 binding URIs are rare, see bug 55070 comment 18.
|
||||||
|
nsTArray<nsIURI*> uris(6);
|
||||||
|
return GetBinding(aBoundElement, aURI, aPeekOnly, aIsReady, aResult, uris);
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
nsXBLService::GetBinding(nsIContent* aBoundElement, nsIURI* aURI,
|
||||||
|
PRBool aPeekOnly, PRBool* aIsReady,
|
||||||
|
nsXBLBinding** aResult,
|
||||||
|
nsTArray<nsIURI*>& aDontExtendURIs)
|
||||||
{
|
{
|
||||||
NS_ASSERTION(aPeekOnly || aResult,
|
NS_ASSERTION(aPeekOnly || aResult,
|
||||||
"Must have non-null out param if not just peeking to see "
|
"Must have non-null out param if not just peeking to see "
|
||||||
|
@ -849,6 +862,8 @@ nsXBLService::GetBinding(nsIContent* aBoundElement, nsIURI* aURI,
|
||||||
if (!aURI)
|
if (!aURI)
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
|
|
||||||
|
NS_ENSURE_TRUE(aDontExtendURIs.AppendElement(aURI), NS_ERROR_OUT_OF_MEMORY);
|
||||||
|
|
||||||
nsCOMPtr<nsIURL> url(do_QueryInterface(aURI));
|
nsCOMPtr<nsIURL> url(do_QueryInterface(aURI));
|
||||||
if (!url) {
|
if (!url) {
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
|
@ -903,9 +918,11 @@ nsXBLService::GetBinding(nsIContent* aBoundElement, nsIURI* aURI,
|
||||||
PRBool hasBase = protoBinding->HasBasePrototype();
|
PRBool hasBase = protoBinding->HasBasePrototype();
|
||||||
nsXBLPrototypeBinding* baseProto = protoBinding->GetBasePrototype();
|
nsXBLPrototypeBinding* baseProto = protoBinding->GetBasePrototype();
|
||||||
if (baseProto) {
|
if (baseProto) {
|
||||||
if (NS_FAILED(GetBinding(aBoundElement, baseProto->BindingURI(),
|
nsresult rv = GetBinding(aBoundElement, baseProto->BindingURI(), aPeekOnly,
|
||||||
aPeekOnly, aIsReady, getter_AddRefs(baseBinding))))
|
aIsReady, getter_AddRefs(baseBinding),
|
||||||
return NS_ERROR_FAILURE; // We aren't ready yet.
|
aDontExtendURIs);
|
||||||
|
if (NS_FAILED(rv))
|
||||||
|
return rv; // We aren't ready yet.
|
||||||
}
|
}
|
||||||
else if (hasBase) {
|
else if (hasBase) {
|
||||||
// Check for the presence of 'extends' and 'display' attributes
|
// Check for the presence of 'extends' and 'display' attributes
|
||||||
|
@ -976,9 +993,31 @@ nsXBLService::GetBinding(nsIContent* aBoundElement, nsIURI* aURI,
|
||||||
doc->GetBaseURI());
|
doc->GetBaseURI());
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
if (NS_FAILED(GetBinding(aBoundElement, bindingURI, aPeekOnly,
|
PRUint32 count = aDontExtendURIs.Length();
|
||||||
aIsReady, getter_AddRefs(baseBinding))))
|
for (PRUint32 index = 0; index < count; ++index) {
|
||||||
return NS_ERROR_FAILURE; // Binding not yet ready or an error occurred.
|
PRBool equal;
|
||||||
|
rv = aDontExtendURIs[index]->Equals(bindingURI, &equal);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
if (equal) {
|
||||||
|
nsCAutoString spec;
|
||||||
|
protoBinding->BindingURI()->GetSpec(spec);
|
||||||
|
NS_ConvertUTF8toUTF16 protoSpec(spec);
|
||||||
|
const PRUnichar* params[] = { protoSpec.get(), value.get() };
|
||||||
|
nsContentUtils::ReportToConsole(nsContentUtils::eXBL_PROPERTIES,
|
||||||
|
"CircularExtendsBinding",
|
||||||
|
params, NS_ARRAY_LENGTH(params),
|
||||||
|
boundDocument->GetDocumentURI(),
|
||||||
|
EmptyString(), 0, 0,
|
||||||
|
nsIScriptError::warningFlag,
|
||||||
|
"XBL");
|
||||||
|
return NS_ERROR_ILLEGAL_VALUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
rv = GetBinding(aBoundElement, bindingURI, aPeekOnly, aIsReady,
|
||||||
|
getter_AddRefs(baseBinding), aDontExtendURIs);
|
||||||
|
if (NS_FAILED(rv))
|
||||||
|
return rv; // Binding not yet ready or an error occurred.
|
||||||
if (!aPeekOnly) {
|
if (!aPeekOnly) {
|
||||||
// Make sure to set the base prototype.
|
// Make sure to set the base prototype.
|
||||||
baseProto = baseBinding->PrototypeBinding();
|
baseProto = baseBinding->PrototypeBinding();
|
||||||
|
|
|
@ -46,6 +46,7 @@
|
||||||
#include "jsapi.h" // nsXBLJSClass derives from JSClass
|
#include "jsapi.h" // nsXBLJSClass derives from JSClass
|
||||||
#include "jsclist.h" // nsXBLJSClass derives from JSCList
|
#include "jsclist.h" // nsXBLJSClass derives from JSCList
|
||||||
#include "nsFixedSizeAllocator.h"
|
#include "nsFixedSizeAllocator.h"
|
||||||
|
#include "nsTArray.h"
|
||||||
|
|
||||||
class nsXBLBinding;
|
class nsXBLBinding;
|
||||||
class nsIXBLDocumentInfo;
|
class nsIXBLDocumentInfo;
|
||||||
|
@ -104,12 +105,32 @@ protected:
|
||||||
|
|
||||||
nsresult GetXBLDocumentInfo(nsIURI* aURI, nsIContent* aBoundElement, nsIXBLDocumentInfo** aResult);
|
nsresult GetXBLDocumentInfo(nsIURI* aURI, nsIContent* aBoundElement, nsIXBLDocumentInfo** aResult);
|
||||||
|
|
||||||
// This method loads a binding doc and then builds the specific binding required. It
|
/**
|
||||||
// can also peek without building.
|
* This method calls the one below with an empty |aDontExtendURIs| array.
|
||||||
|
*/
|
||||||
nsresult GetBinding(nsIContent* aBoundElement, nsIURI* aURI,
|
nsresult GetBinding(nsIContent* aBoundElement, nsIURI* aURI,
|
||||||
PRBool aPeekFlag, PRBool* aIsReady,
|
PRBool aPeekFlag, PRBool* aIsReady,
|
||||||
nsXBLBinding** aResult);
|
nsXBLBinding** aResult);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method loads a binding doc and then builds the specific binding
|
||||||
|
* required. It can also peek without building.
|
||||||
|
* @param aBoundElement the element to get a binding for
|
||||||
|
* @param aURI the binding URI
|
||||||
|
* @param aPeekFlag if true then just peek to see if the binding is ready
|
||||||
|
* @param aIsReady [out] if the binding is ready or not
|
||||||
|
* @param aResult [out] where to store the resulting binding (not used if
|
||||||
|
* aPeekFlag is true, otherwise it must be non-null)
|
||||||
|
* @param aDontExtendURIs a set of URIs that are already bound to this
|
||||||
|
* element. If a binding extends any of these then further loading
|
||||||
|
* is aborted (because it would lead to the binding extending itself)
|
||||||
|
* and NS_ERROR_ILLEGAL_VALUE is returned.
|
||||||
|
*/
|
||||||
|
nsresult GetBinding(nsIContent* aBoundElement, nsIURI* aURI,
|
||||||
|
PRBool aPeekFlag, PRBool* aIsReady,
|
||||||
|
nsXBLBinding** aResult,
|
||||||
|
nsTArray<nsIURI*>& aDontExtendURIs);
|
||||||
|
|
||||||
// MEMBER VARIABLES
|
// MEMBER VARIABLES
|
||||||
public:
|
public:
|
||||||
#ifdef MOZ_XUL
|
#ifdef MOZ_XUL
|
||||||
|
|
|
@ -38,3 +38,4 @@ UnexpectedElement=Unexpected <%1$S> element.
|
||||||
GTK2Conflict=Key event not available on GTK2: key="%S" modifiers="%S"
|
GTK2Conflict=Key event not available on GTK2: key="%S" modifiers="%S"
|
||||||
WinConflict=Key event not available on some keyboard layouts: key="%S" modifiers="%S"
|
WinConflict=Key event not available on some keyboard layouts: key="%S" modifiers="%S"
|
||||||
RecursiveBinding=The XBL binding "%S" is already used by an ancestor element
|
RecursiveBinding=The XBL binding "%S" is already used by an ancestor element
|
||||||
|
CircularExtendsBinding=Extending the XBL binding "%S" with "%S" would lead to it extending itself
|
||||||
|
|
Загрузка…
Ссылка в новой задаче