зеркало из 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)
|
||||
* - Brendan Eich (brendan@mozilla.org)
|
||||
* - Mike Pinkerton (pinkerton@netscape.com)
|
||||
* Mats Palmgren <mats.palmgren@bredband.net>
|
||||
*
|
||||
* 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"),
|
||||
|
@ -121,7 +122,8 @@ IsAncestorBinding(nsIDocument* aDocument,
|
|||
nsresult rv =
|
||||
binding->PrototypeBinding()->BindingURI()->Equals(aChildBindingURI,
|
||||
&equal);
|
||||
if (NS_FAILED(rv) || equal) {
|
||||
NS_ENSURE_SUCCESS(rv, PR_TRUE); // assume the worst
|
||||
if (equal) {
|
||||
nsCAutoString spec;
|
||||
aChildBindingURI->GetSpec(spec);
|
||||
NS_ConvertUTF8toUTF16 bindingURI(spec);
|
||||
|
@ -838,6 +840,17 @@ nsresult
|
|||
nsXBLService::GetBinding(nsIContent* aBoundElement, nsIURI* aURI,
|
||||
PRBool aPeekOnly, PRBool* aIsReady,
|
||||
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,
|
||||
"Must have non-null out param if not just peeking to see "
|
||||
|
@ -849,6 +862,8 @@ nsXBLService::GetBinding(nsIContent* aBoundElement, nsIURI* aURI,
|
|||
if (!aURI)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
NS_ENSURE_TRUE(aDontExtendURIs.AppendElement(aURI), NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
nsCOMPtr<nsIURL> url(do_QueryInterface(aURI));
|
||||
if (!url) {
|
||||
#ifdef DEBUG
|
||||
|
@ -903,9 +918,11 @@ nsXBLService::GetBinding(nsIContent* aBoundElement, nsIURI* aURI,
|
|||
PRBool hasBase = protoBinding->HasBasePrototype();
|
||||
nsXBLPrototypeBinding* baseProto = protoBinding->GetBasePrototype();
|
||||
if (baseProto) {
|
||||
if (NS_FAILED(GetBinding(aBoundElement, baseProto->BindingURI(),
|
||||
aPeekOnly, aIsReady, getter_AddRefs(baseBinding))))
|
||||
return NS_ERROR_FAILURE; // We aren't ready yet.
|
||||
nsresult rv = GetBinding(aBoundElement, baseProto->BindingURI(), aPeekOnly,
|
||||
aIsReady, getter_AddRefs(baseBinding),
|
||||
aDontExtendURIs);
|
||||
if (NS_FAILED(rv))
|
||||
return rv; // We aren't ready yet.
|
||||
}
|
||||
else if (hasBase) {
|
||||
// Check for the presence of 'extends' and 'display' attributes
|
||||
|
@ -976,9 +993,31 @@ nsXBLService::GetBinding(nsIContent* aBoundElement, nsIURI* aURI,
|
|||
doc->GetBaseURI());
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (NS_FAILED(GetBinding(aBoundElement, bindingURI, aPeekOnly,
|
||||
aIsReady, getter_AddRefs(baseBinding))))
|
||||
return NS_ERROR_FAILURE; // Binding not yet ready or an error occurred.
|
||||
PRUint32 count = aDontExtendURIs.Length();
|
||||
for (PRUint32 index = 0; index < count; ++index) {
|
||||
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) {
|
||||
// Make sure to set the base prototype.
|
||||
baseProto = baseBinding->PrototypeBinding();
|
||||
|
|
|
@ -46,6 +46,7 @@
|
|||
#include "jsapi.h" // nsXBLJSClass derives from JSClass
|
||||
#include "jsclist.h" // nsXBLJSClass derives from JSCList
|
||||
#include "nsFixedSizeAllocator.h"
|
||||
#include "nsTArray.h"
|
||||
|
||||
class nsXBLBinding;
|
||||
class nsIXBLDocumentInfo;
|
||||
|
@ -104,12 +105,32 @@ protected:
|
|||
|
||||
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,
|
||||
PRBool aPeekFlag, PRBool* aIsReady,
|
||||
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
|
||||
public:
|
||||
#ifdef MOZ_XUL
|
||||
|
|
|
@ -38,3 +38,4 @@ UnexpectedElement=Unexpected <%1$S> element.
|
|||
GTK2Conflict=Key event not available on GTK2: 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
|
||||
CircularExtendsBinding=Extending the XBL binding "%S" with "%S" would lead to it extending itself
|
||||
|
|
Загрузка…
Ссылка в новой задаче