diff --git a/layout/style/Loader.cpp b/layout/style/Loader.cpp index 964217685a4..b0cf4a6d8c2 100644 --- a/layout/style/Loader.cpp +++ b/layout/style/Loader.cpp @@ -1093,7 +1093,10 @@ Loader::CreateSheet(nsIURI* aURI, nsIContent* aLinkingContent, nsIPrincipal* aLoaderPrincipal, bool aSyncLoad, + bool aHasAlternateRel, + const nsAString& aTitle, StyleSheetState& aSheetState, + bool *aIsAlternate, nsCSSStyleSheet** aSheet) { LOG(("css::Loader::CreateSheet")); @@ -1108,6 +1111,10 @@ Loader::CreateSheet(nsIURI* aURI, *aSheet = nsnull; aSheetState = eSheetStateUnknown; + // Check the alternate state before doing anything else, because it + // can mess with our hashtables. + *aIsAlternate = IsAlternate(aTitle, aHasAlternateRel); + if (aURI) { aSheetState = eSheetComplete; nsRefPtr sheet; @@ -1241,8 +1248,7 @@ Loader::PrepareSheet(nsCSSStyleSheet* aSheet, const nsSubstring& aTitle, const nsSubstring& aMediaString, nsMediaList* aMediaList, - bool aHasAlternateRel, - bool *aIsAlternate) + bool isAlternate) { NS_PRECONDITION(aSheet, "Must have a sheet!"); @@ -1267,11 +1273,7 @@ Loader::PrepareSheet(nsCSSStyleSheet* aSheet, aSheet->SetMedia(mediaList); aSheet->SetTitle(aTitle); - bool alternate = IsAlternate(aTitle, aHasAlternateRel); - aSheet->SetEnabled(! alternate); - if (aIsAlternate) { - *aIsAlternate = alternate; - } + aSheet->SetEnabled(! isAlternate); return NS_OK; } @@ -1838,15 +1840,15 @@ Loader::LoadInlineStyle(nsIContent* aElement, // Since we're not planning to load a URI, no need to hand a principal to the // load data or to CreateSheet(). StyleSheetState state; + bool isAlternate; nsRefPtr sheet; - nsresult rv = CreateSheet(nsnull, aElement, nsnull, false, state, - getter_AddRefs(sheet)); + nsresult rv = CreateSheet(nsnull, aElement, nsnull, false, false, + aTitle, state, &isAlternate, getter_AddRefs(sheet)); NS_ENSURE_SUCCESS(rv, rv); NS_ASSERTION(state == eSheetNeedsParser, "Inline sheets should not be cached"); - rv = PrepareSheet(sheet, aTitle, aMedia, nsnull, false, - aIsAlternate); + rv = PrepareSheet(sheet, aTitle, aMedia, nsnull, isAlternate); NS_ENSURE_SUCCESS(rv, rv); LOG((" Sheet is alternate: %d", *aIsAlternate)); @@ -1912,13 +1914,13 @@ Loader::LoadStyleLink(nsIContent* aElement, LOG((" Passed load check")); StyleSheetState state; + bool isAlternate; nsRefPtr sheet; - rv = CreateSheet(aURL, aElement, principal, false, state, - getter_AddRefs(sheet)); + rv = CreateSheet(aURL, aElement, principal, false, aHasAlternateRel, + aTitle, state, &isAlternate, getter_AddRefs(sheet)); NS_ENSURE_SUCCESS(rv, rv); - rv = PrepareSheet(sheet, aTitle, aMedia, nsnull, aHasAlternateRel, - aIsAlternate); + rv = PrepareSheet(sheet, aTitle, aMedia, nsnull, isAlternate); NS_ENSURE_SUCCESS(rv, rv); LOG((" Sheet is alternate: %d", *aIsAlternate)); @@ -2070,14 +2072,15 @@ Loader::LoadChildSheet(nsCSSStyleSheet* aParentSheet, // Now that we know it's safe to load this (passes security check and not a // loop) do so nsRefPtr sheet; + bool isAlternate; StyleSheetState state; + const nsSubstring& empty = EmptyString(); rv = CreateSheet(aURL, nsnull, principal, parentData ? parentData->mSyncLoad : false, - state, getter_AddRefs(sheet)); + false, empty, state, &isAlternate, getter_AddRefs(sheet)); NS_ENSURE_SUCCESS(rv, rv); - const nsSubstring& empty = EmptyString(); - rv = PrepareSheet(sheet, empty, empty, aMedia); + rv = PrepareSheet(sheet, empty, empty, aMedia, isAlternate); NS_ENSURE_SUCCESS(rv, rv); rv = InsertChildSheet(sheet, aParentSheet, aParentRule); @@ -2177,15 +2180,16 @@ Loader::InternalLoadNonDocumentSheet(nsIURI* aURL, } StyleSheetState state; + bool isAlternate; nsRefPtr sheet; bool syncLoad = (aObserver == nsnull); + const nsSubstring& empty = EmptyString(); - rv = CreateSheet(aURL, nsnull, aOriginPrincipal, syncLoad, state, - getter_AddRefs(sheet)); + rv = CreateSheet(aURL, nsnull, aOriginPrincipal, syncLoad, false, empty, + state, &isAlternate, getter_AddRefs(sheet)); NS_ENSURE_SUCCESS(rv, rv); - const nsSubstring& empty = EmptyString(); - rv = PrepareSheet(sheet, empty, empty, nsnull); + rv = PrepareSheet(sheet, empty, empty, nsnull, isAlternate); NS_ENSURE_SUCCESS(rv, rv); if (state == eSheetComplete) { diff --git a/layout/style/Loader.h b/layout/style/Loader.h index 71a83bf50f2..31ee5e8b588 100644 --- a/layout/style/Loader.h +++ b/layout/style/Loader.h @@ -384,23 +384,25 @@ private: // For inline style, the aURI param is null, but the aLinkingContent // must be non-null then. The loader principal must never be null // if aURI is not null. + // *aIsAlternate is set based on aTitle and aHasAlternateRel. nsresult CreateSheet(nsIURI* aURI, nsIContent* aLinkingContent, nsIPrincipal* aLoaderPrincipal, bool aSyncLoad, + bool aHasAlternateRel, + const nsAString& aTitle, StyleSheetState& aSheetState, + bool *aIsAlternate, nsCSSStyleSheet** aSheet); // Pass in either a media string or the nsMediaList from the // CSSParser. Don't pass both. - // If aIsAlternate is non-null, this method will set *aIsAlternate to - // correspond to the sheet's enabled state (which it will set no matter what) + // This method will set the sheet's enabled state based on isAlternate nsresult PrepareSheet(nsCSSStyleSheet* aSheet, const nsAString& aTitle, const nsAString& aMediaString, nsMediaList* aMediaList, - bool aHasAlternateRel = false, - bool *aIsAlternate = nsnull); + bool isAlternate); nsresult InsertSheetInDoc(nsCSSStyleSheet* aSheet, nsIContent* aLinkingContent, diff --git a/layout/style/crashtests/700116.html b/layout/style/crashtests/700116.html new file mode 100644 index 00000000000..de35ce70296 --- /dev/null +++ b/layout/style/crashtests/700116.html @@ -0,0 +1,5 @@ + + + diff --git a/layout/style/crashtests/crashtests.list b/layout/style/crashtests/crashtests.list index be9766ac4c9..72f2f2e613e 100644 --- a/layout/style/crashtests/crashtests.list +++ b/layout/style/crashtests/crashtests.list @@ -74,3 +74,4 @@ asserts(2) load 671799-1.html asserts(2) load 671799-2.html load 690990-1.html load 696188-1.html +load 700116.html