From 19f3323d773c47f404c789a4ea0be937ad55d013 Mon Sep 17 00:00:00 2001 From: "bzbarsky%mit.edu" Date: Tue, 23 Oct 2007 21:56:43 +0000 Subject: [PATCH] Make the "href" property of stylesheets reflect the original URI that was reflected to load the sheet. Bug 397427, r=dbaron,biesi, sr=dbaron, a=dsicore git-svn-id: svn://10.0.0.236/trunk@238046 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/caps/src/nsScriptSecurityManager.cpp | 9 +- mozilla/content/base/src/nsDocument.cpp | 8 +- .../xul/document/src/nsXULDocument.cpp | 14 +-- mozilla/docshell/base/nsDocShell.cpp | 7 +- mozilla/layout/base/nsPresShell.cpp | 2 +- .../layout/mathml/base/src/nsMathMLFrame.cpp | 2 +- mozilla/layout/style/nsCSSLoader.cpp | 29 +++--- mozilla/layout/style/nsCSSParser.cpp | 2 +- mozilla/layout/style/nsCSSStyleSheet.cpp | 17 ++-- mozilla/layout/style/nsCSSStyleSheet.h | 4 +- mozilla/layout/style/nsICSSStyleSheet.h | 9 +- mozilla/layout/style/test/Makefile.in | 10 ++ mozilla/layout/style/test/post-redirect-1.css | 1 + mozilla/layout/style/test/post-redirect-2.css | 1 + mozilla/layout/style/test/post-redirect-3.css | 1 + .../layout/style/test/redirect-1.css^headers^ | 2 + .../layout/style/test/redirect-2.css^headers^ | 2 + .../layout/style/test/redirect-3.css^headers^ | 2 + mozilla/layout/style/test/test_bug397427.html | 92 +++++++++++++++++++ mozilla/netwerk/base/public/nsNetUtil.h | 22 +++++ 20 files changed, 176 insertions(+), 60 deletions(-) create mode 100644 mozilla/layout/style/test/post-redirect-1.css create mode 100644 mozilla/layout/style/test/post-redirect-2.css create mode 100644 mozilla/layout/style/test/post-redirect-3.css create mode 100644 mozilla/layout/style/test/redirect-1.css^headers^ create mode 100644 mozilla/layout/style/test/redirect-2.css^headers^ create mode 100644 mozilla/layout/style/test/redirect-3.css^headers^ create mode 100644 mozilla/layout/style/test/test_bug397427.html diff --git a/mozilla/caps/src/nsScriptSecurityManager.cpp b/mozilla/caps/src/nsScriptSecurityManager.cpp index 77141739661..11effe6ccb1 100644 --- a/mozilla/caps/src/nsScriptSecurityManager.cpp +++ b/mozilla/caps/src/nsScriptSecurityManager.cpp @@ -446,13 +446,8 @@ nsScriptSecurityManager::GetChannelPrincipal(nsIChannel* aChannel, // OK, get the principal from the URI. Make sure this does the same thing // as nsDocument::Reset and nsXULDocument::StartDocumentLoad. nsCOMPtr uri; - nsLoadFlags loadFlags = 0; - nsresult rv = aChannel->GetLoadFlags(&loadFlags); - if (NS_SUCCEEDED(rv) && (loadFlags & nsIChannel::LOAD_REPLACE)) { - aChannel->GetURI(getter_AddRefs(uri)); - } else { - aChannel->GetOriginalURI(getter_AddRefs(uri)); - } + nsresult rv = NS_GetFinalChannelURI(aChannel, getter_AddRefs(uri)); + NS_ENSURE_SUCCESS(rv, rv); return GetCodebasePrincipal(uri, aPrincipal); } diff --git a/mozilla/content/base/src/nsDocument.cpp b/mozilla/content/base/src/nsDocument.cpp index 300f44fda70..4567ccb8351 100644 --- a/mozilla/content/base/src/nsDocument.cpp +++ b/mozilla/content/base/src/nsDocument.cpp @@ -1161,13 +1161,7 @@ nsDocument::Reset(nsIChannel* aChannel, nsILoadGroup* aLoadGroup) // Note: this code is duplicated in nsXULDocument::StartDocumentLoad and // nsScriptSecurityManager::GetChannelPrincipal. // Note: this should match nsDocShell::OnLoadingSite - nsLoadFlags loadFlags = 0; - nsresult rv = aChannel->GetLoadFlags(&loadFlags); - if (NS_SUCCEEDED(rv) && (loadFlags & nsIChannel::LOAD_REPLACE)) { - aChannel->GetURI(getter_AddRefs(uri)); - } else { - aChannel->GetOriginalURI(getter_AddRefs(uri)); - } + NS_GetFinalChannelURI(aChannel, getter_AddRefs(uri)); nsIScriptSecurityManager *securityManager = nsContentUtils::GetSecurityManager(); diff --git a/mozilla/content/xul/document/src/nsXULDocument.cpp b/mozilla/content/xul/document/src/nsXULDocument.cpp index 06eed0050f3..c8c0548bdb1 100644 --- a/mozilla/content/xul/document/src/nsXULDocument.cpp +++ b/mozilla/content/xul/document/src/nsXULDocument.cpp @@ -424,18 +424,8 @@ nsXULDocument::StartDocumentLoad(const char* aCommand, nsIChannel* aChannel, mChannel = aChannel; // Get the URI. Note that this should match nsDocShell::OnLoadingSite - // XXXbz this code is repeated from nsDocument::Reset and - // nsScriptSecurityManager::GetChannelPrincipal; we really need to refactor - // this part better. - nsLoadFlags loadFlags = 0; - nsresult rv = aChannel->GetLoadFlags(&loadFlags); - if (NS_SUCCEEDED(rv)) { - if (loadFlags & nsIChannel::LOAD_REPLACE) { - rv = aChannel->GetURI(getter_AddRefs(mDocumentURI)); - } else { - rv = aChannel->GetOriginalURI(getter_AddRefs(mDocumentURI)); - } - } + nsresult rv = + NS_GetFinalChannelURI(aChannel, getter_AddRefs(mDocumentURI)); NS_ENSURE_SUCCESS(rv, rv); rv = ResetStylesheetsToURI(mDocumentURI); diff --git a/mozilla/docshell/base/nsDocShell.cpp b/mozilla/docshell/base/nsDocShell.cpp index 8c07f26b6c2..9e0c5e4fa6e 100644 --- a/mozilla/docshell/base/nsDocShell.cpp +++ b/mozilla/docshell/base/nsDocShell.cpp @@ -7760,12 +7760,7 @@ nsDocShell::OnLoadingSite(nsIChannel * aChannel, PRBool aFireOnLocationChange, // else use the original url // // Note that this should match what documents do (see nsDocument::Reset). - nsLoadFlags loadFlags = 0; - aChannel->GetLoadFlags(&loadFlags); - if (loadFlags & nsIChannel::LOAD_REPLACE) - aChannel->GetURI(getter_AddRefs(uri)); - else - aChannel->GetOriginalURI(getter_AddRefs(uri)); + NS_GetFinalChannelURI(aChannel, getter_AddRefs(uri)); NS_ENSURE_TRUE(uri, PR_FALSE); return OnNewURI(uri, aChannel, mLoadType, aFireOnLocationChange, diff --git a/mozilla/layout/base/nsPresShell.cpp b/mozilla/layout/base/nsPresShell.cpp index e4e5c672367..7f2470f3747 100644 --- a/mozilla/layout/base/nsPresShell.cpp +++ b/mozilla/layout/base/nsPresShell.cpp @@ -1849,7 +1849,7 @@ nsresult PresShell::CreatePreferenceStyleSheet(void) result = NS_NewURI(getter_AddRefs(uri), "about:PreferenceStyleSheet", nsnull); if (NS_SUCCEEDED(result)) { NS_ASSERTION(uri, "null but no error"); - result = mPrefStyleSheet->SetURIs(uri, uri); + result = mPrefStyleSheet->SetURIs(uri, nsnull, uri); if (NS_SUCCEEDED(result)) { mPrefStyleSheet->SetComplete(); nsCOMPtr sheet(do_QueryInterface(mPrefStyleSheet)); diff --git a/mozilla/layout/mathml/base/src/nsMathMLFrame.cpp b/mozilla/layout/mathml/base/src/nsMathMLFrame.cpp index 9611a960bcf..6c6516c77e1 100644 --- a/mozilla/layout/mathml/base/src/nsMathMLFrame.cpp +++ b/mozilla/layout/mathml/base/src/nsMathMLFrame.cpp @@ -594,7 +594,7 @@ GetMathMLAttributeStyleSheet(nsPresContext* aPresContext, nsCOMPtr cssSheet(do_CreateInstance(kCSSStyleSheetCID)); if (!cssSheet) return; - cssSheet->SetURIs(uri, uri); + cssSheet->SetURIs(uri, nsnull, uri); cssSheet->SetTitle(NS_ConvertASCIItoUTF16(kTitle)); // all done, no further activity from the net involved, so we better do this cssSheet->SetComplete(); diff --git a/mozilla/layout/style/nsCSSLoader.cpp b/mozilla/layout/style/nsCSSLoader.cpp index 55d0af68558..fb549ba616c 100644 --- a/mozilla/layout/style/nsCSSLoader.cpp +++ b/mozilla/layout/style/nsCSSLoader.cpp @@ -777,19 +777,18 @@ SheetLoadData::OnStreamComplete(nsIUnicharStreamLoader* aLoader, return NS_OK; } - nsCOMPtr channelURI; + nsCOMPtr originalURI; + channel->GetOriginalURI(getter_AddRefs(originalURI)); + // If the channel's original URI is "chrome:", we want that, since // the observer code in nsXULPrototypeCache depends on chrome stylesheets // having a chrome URI. (Whether or not chrome stylesheets come through // this codepath seems nondeterministic.) // Otherwise we want the potentially-HTTP-redirected URI. - channel->GetOriginalURI(getter_AddRefs(channelURI)); - PRBool isChrome; - if (NS_FAILED(channelURI->SchemeIs("chrome", &isChrome)) || !isChrome) { - channel->GetURI(getter_AddRefs(channelURI)); - } + nsCOMPtr channelURI; + NS_GetFinalChannelURI(channel, getter_AddRefs(channelURI)); - if (!channelURI) { + if (!channelURI || !originalURI) { NS_ERROR("Someone just violated the nsIRequest contract"); LOG_WARN((" Channel without a URI. Bad!")); mLoader->SheetComplete(this, NS_ERROR_UNEXPECTED); @@ -875,9 +874,9 @@ SheetLoadData::OnStreamComplete(nsIUnicharStreamLoader* aLoader, return NS_OK; } - // Enough to set the URI on mSheet, since any sibling datas we have share + // Enough to set the URIs on mSheet, since any sibling datas we have share // the same mInner as mSheet and will thus get the same URI. - mSheet->SetURIs(channelURI, channelURI); + mSheet->SetURIs(channelURI, originalURI, channelURI); PRBool completed; return mLoader->ParseSheet(aDataStream, this, completed); @@ -1082,19 +1081,25 @@ CSSLoaderImpl::CreateSheet(nsIURI* aURI, if (!*aSheet) { aSheetState = eSheetNeedsParser; - nsIURI *sheetURI = aURI; - nsCOMPtr baseURI = aURI; + nsIURI *sheetURI; + nsCOMPtr baseURI; + nsIURI* originalURI; if (!aURI) { // Inline style. Use the document's base URL so that @import in // the inline sheet picks up the right base. NS_ASSERTION(aLinkingContent, "Inline stylesheet without linking content?"); baseURI = aLinkingContent->GetBaseURI(); sheetURI = aLinkingContent->GetDocument()->GetDocumentURI(); + originalURI = nsnull; + } else { + baseURI = aURI; + sheetURI = aURI; + originalURI = aURI; } rv = NS_NewCSSStyleSheet(aSheet); NS_ENSURE_SUCCESS(rv, rv); - (*aSheet)->SetURIs(sheetURI, baseURI); + (*aSheet)->SetURIs(sheetURI, originalURI, baseURI); } NS_ASSERTION(*aSheet, "We should have a sheet by now!"); diff --git a/mozilla/layout/style/nsCSSParser.cpp b/mozilla/layout/style/nsCSSParser.cpp index 6afc9ebe843..a844d7462b9 100644 --- a/mozilla/layout/style/nsCSSParser.cpp +++ b/mozilla/layout/style/nsCSSParser.cpp @@ -707,7 +707,7 @@ CSSParserImpl::Parse(nsIUnicharInputStream* aInput, NS_NewCSSStyleSheet(getter_AddRefs(mSheet)); NS_ENSURE_TRUE(mSheet, NS_ERROR_OUT_OF_MEMORY); - mSheet->SetURIs(aSheetURI, aBaseURI); + mSheet->SetURIs(aSheetURI, aSheetURI, aBaseURI); mSheet->SetPrincipal(aSheetPrincipal); mNameSpaceMap = nsnull; } diff --git a/mozilla/layout/style/nsCSSStyleSheet.cpp b/mozilla/layout/style/nsCSSStyleSheet.cpp index a2f458ff4f4..2dc36f89d5a 100644 --- a/mozilla/layout/style/nsCSSStyleSheet.cpp +++ b/mozilla/layout/style/nsCSSStyleSheet.cpp @@ -771,7 +771,8 @@ nsCSSStyleSheet::DropRuleProcessor(nsCSSRuleProcessor* aProcessor) NS_IMETHODIMP -nsCSSStyleSheet::SetURIs(nsIURI* aSheetURI, nsIURI* aBaseURI) +nsCSSStyleSheet::SetURIs(nsIURI* aSheetURI, nsIURI* aOriginalSheetURI, + nsIURI* aBaseURI) { NS_PRECONDITION(aSheetURI && aBaseURI, "null ptr"); @@ -779,6 +780,7 @@ nsCSSStyleSheet::SetURIs(nsIURI* aSheetURI, nsIURI* aBaseURI) "Can't call SetURL on sheets that are complete or have rules"); mInner->mSheetURI = aSheetURI; + mInner->mOriginalSheetURI = aOriginalSheetURI; mInner->mBaseURI = aBaseURI; return NS_OK; } @@ -1416,15 +1418,14 @@ nsCSSStyleSheet::GetParentStyleSheet(nsIDOMStyleSheet** aParentStyleSheet) NS_IMETHODIMP nsCSSStyleSheet::GetHref(nsAString& aHref) { - nsCAutoString str; - - // XXXldb The DOM spec says that this should be null for inline style sheets. - if (mInner->mSheetURI) { - mInner->mSheetURI->GetSpec(str); + if (mInner->mOriginalSheetURI) { + nsCAutoString str; + mInner->mOriginalSheetURI->GetSpec(str); + CopyUTF8toUTF16(str, aHref); + } else { + SetDOMStringToNull(aHref); } - CopyUTF8toUTF16(str, aHref); - return NS_OK; } diff --git a/mozilla/layout/style/nsCSSStyleSheet.h b/mozilla/layout/style/nsCSSStyleSheet.h index 9179ceebf6c..9b72f99a6cc 100644 --- a/mozilla/layout/style/nsCSSStyleSheet.h +++ b/mozilla/layout/style/nsCSSStyleSheet.h @@ -74,6 +74,7 @@ public: nsAutoVoidArray mSheets; nsCOMPtr mSheetURI; // for error reports, etc. + nsCOMPtr mOriginalSheetURI; // for GetHref. Can be null. nsCOMPtr mBaseURI; // for resolving relative URIs nsCOMPtr mPrincipal; nsCOMArray mOrderedRules; @@ -136,7 +137,8 @@ public: NS_IMETHOD ReplaceRuleInGroup(nsICSSGroupRule* aGroup, nsICSSRule* aOld, nsICSSRule* aNew); NS_IMETHOD StyleSheetCount(PRInt32& aCount) const; NS_IMETHOD GetStyleSheetAt(PRInt32 aIndex, nsICSSStyleSheet*& aSheet) const; - NS_IMETHOD SetURIs(nsIURI* aSheetURI, nsIURI* aBaseURI); + NS_IMETHOD SetURIs(nsIURI* aSheetURI, nsIURI* aOriginalSheetURI, + nsIURI* aBaseURI); virtual NS_HIDDEN_(void) SetPrincipal(nsIPrincipal* aPrincipal); virtual NS_HIDDEN_(nsIPrincipal*) Principal() const; NS_IMETHOD SetTitle(const nsAString& aTitle); diff --git a/mozilla/layout/style/nsICSSStyleSheet.h b/mozilla/layout/style/nsICSSStyleSheet.h index 77df3fa9ed9..c38b8367a86 100644 --- a/mozilla/layout/style/nsICSSStyleSheet.h +++ b/mozilla/layout/style/nsICSSStyleSheet.h @@ -53,10 +53,10 @@ class nsICSSImportRule; class nsIPrincipal; // IID for the nsICSSStyleSheet interface -// 36541c18-e735-48ef-8622-3a481275b757 +// 74fa10f3-fab7-425a-a7dd-e2afd1ba7a07 #define NS_ICSS_STYLE_SHEET_IID \ -{ 0x36541c18, 0xe735, 0x48ef, \ - { 0x86, 0x22, 0x3a, 0x48, 0x12, 0x75, 0xb7, 0x57 } } +{ 0x74fa10f3, 0xfab7, 0x425a, \ + { 0xa7, 0xdd, 0xe2, 0xaf, 0xd1, 0xba, 0x7a, 0x07 } } class nsICSSStyleSheet : public nsIStyleSheet { public: @@ -87,7 +87,8 @@ public: * SetURIs may only be called while the sheet is 1) incomplete and 2) * has no rules in it */ - NS_IMETHOD SetURIs(nsIURI* aSheetURI, nsIURI* aBaseURI) = 0; + NS_IMETHOD SetURIs(nsIURI* aSheetURI, nsIURI* aOriginalSheetURI, + nsIURI* aBaseURI) = 0; /** * SetPrincipal should be called on all sheets before parsing into them. diff --git a/mozilla/layout/style/test/Makefile.in b/mozilla/layout/style/test/Makefile.in index 1ba18dfe432..69cb05eb679 100644 --- a/mozilla/layout/style/test/Makefile.in +++ b/mozilla/layout/style/test/Makefile.in @@ -83,6 +83,7 @@ _TEST_FILES = test_bug74880.html \ test_bug389464.html \ test_bug391034.html \ test_bug391221.html \ + test_bug397427.html \ test_compute_data_with_start_struct.html \ test_dont_use_document_colors.html \ test_inherit_storage.html \ @@ -101,6 +102,15 @@ _TEST_FILES = test_bug74880.html \ unstyled.css \ unstyled-frame.xml \ unstyled-frame.css \ + redirect-1.css \ + post-redirect-1.css \ + redirect-1.css^headers^ \ + redirect-2.css \ + post-redirect-2.css \ + redirect-2.css^headers^ \ + redirect-3.css \ + redirect-3.css^headers^ \ + post-redirect-3.css \ $(NULL) diff --git a/mozilla/layout/style/test/post-redirect-1.css b/mozilla/layout/style/test/post-redirect-1.css new file mode 100644 index 00000000000..c2ae5d6eb2c --- /dev/null +++ b/mozilla/layout/style/test/post-redirect-1.css @@ -0,0 +1 @@ +#one { color: green; background: url("#"); } diff --git a/mozilla/layout/style/test/post-redirect-2.css b/mozilla/layout/style/test/post-redirect-2.css new file mode 100644 index 00000000000..0a75299ce2e --- /dev/null +++ b/mozilla/layout/style/test/post-redirect-2.css @@ -0,0 +1 @@ +#two { color: green; background: url("#"); } diff --git a/mozilla/layout/style/test/post-redirect-3.css b/mozilla/layout/style/test/post-redirect-3.css new file mode 100644 index 00000000000..b33887ae32c --- /dev/null +++ b/mozilla/layout/style/test/post-redirect-3.css @@ -0,0 +1 @@ +#three { color: green; background: url("#"); } diff --git a/mozilla/layout/style/test/redirect-1.css^headers^ b/mozilla/layout/style/test/redirect-1.css^headers^ new file mode 100644 index 00000000000..582de3f2be2 --- /dev/null +++ b/mozilla/layout/style/test/redirect-1.css^headers^ @@ -0,0 +1,2 @@ +HTTP 302 Found +Location: http://example.org/tests/layout/style/test/post-redirect-1.css diff --git a/mozilla/layout/style/test/redirect-2.css^headers^ b/mozilla/layout/style/test/redirect-2.css^headers^ new file mode 100644 index 00000000000..09280cc486b --- /dev/null +++ b/mozilla/layout/style/test/redirect-2.css^headers^ @@ -0,0 +1,2 @@ +HTTP 302 Found +Location: http://example.org/tests/layout/style/test/post-redirect-2.css diff --git a/mozilla/layout/style/test/redirect-3.css^headers^ b/mozilla/layout/style/test/redirect-3.css^headers^ new file mode 100644 index 00000000000..42419234f2d --- /dev/null +++ b/mozilla/layout/style/test/redirect-3.css^headers^ @@ -0,0 +1,2 @@ +HTTP 302 Found +Location: http://example.org/tests/layout/style/test/post-redirect-3.css diff --git a/mozilla/layout/style/test/test_bug397427.html b/mozilla/layout/style/test/test_bug397427.html new file mode 100644 index 00000000000..ae457215e11 --- /dev/null +++ b/mozilla/layout/style/test/test_bug397427.html @@ -0,0 +1,92 @@ + + + + + Test for Bug 397427 + + + + + + + + + +Mozilla Bug 397427 +

+ + + +

+ +
+
+
+ + + diff --git a/mozilla/netwerk/base/public/nsNetUtil.h b/mozilla/netwerk/base/public/nsNetUtil.h index ce786fe4bce..5a159b53f71 100644 --- a/mozilla/netwerk/base/public/nsNetUtil.h +++ b/mozilla/netwerk/base/public/nsNetUtil.h @@ -1304,4 +1304,26 @@ NS_GetInnermostURI(nsIURI *uri) return uri; } +/** + * Get the "final" URI for a channel. This is either the same as GetURI or + * GetOriginalURI, depending on whether this channel has + * nsIChanel::LOAD_REPLACE set. For channels without that flag set, the final + * URI is the original URI, while for ones with the flag the final URI is the + * channel URI. + */ +inline nsresult +NS_GetFinalChannelURI(nsIChannel* channel, nsIURI** uri) +{ + *uri = nsnull; + nsLoadFlags loadFlags = 0; + nsresult rv = channel->GetLoadFlags(&loadFlags); + NS_ENSURE_SUCCESS(rv, rv); + + if (loadFlags & nsIChannel::LOAD_REPLACE) { + return channel->GetURI(uri); + } + + return channel->GetOriginalURI(uri); +} + #endif // !nsNetUtil_h__