Bug 331883. Restrict anonymous box selectors to agent/user style sheets. r+sr=dbaron/bzbarsky

This commit is contained in:
roc+%cs.cmu.edu 2006-06-15 03:20:19 +00:00
Родитель 13277df928
Коммит 8c3f0278d7
13 изменённых файлов: 87 добавлений и 29 удалений

Просмотреть файл

@ -952,7 +952,7 @@ nsresult nsChromeRegistry::RefreshWindow(nsIDOMWindowInternal* aWindow,
if (IsChromeURI(uri)) {
// Reload the sheet.
nsCOMPtr<nsICSSStyleSheet> newSheet;
rv = aCSSLoader->LoadSheetSync(uri, getter_AddRefs(newSheet));
rv = aCSSLoader->LoadSheetSync(uri, PR_TRUE, getter_AddRefs(newSheet));
if (NS_FAILED(rv)) return rv;
if (newSheet) {
rv = newAgentSheets.AppendObject(newSheet) ? NS_OK : NS_ERROR_FAILURE;

Просмотреть файл

@ -3600,7 +3600,8 @@ nsHTMLEditor::AddOverrideStyleSheet(const nsAString& aURL)
// XXXbz Except this will actually try to load remote files
// synchronously, of course..
nsCOMPtr<nsICSSStyleSheet> sheet;
rv = cssLoader->LoadSheetSync(uaURI, getter_AddRefs(sheet));
// Editor override style sheets may want to style Gecko anonymous boxes
rv = cssLoader->LoadSheetSync(uaURI, PR_TRUE, getter_AddRefs(sheet));
// Synchronous loads should ALWAYS return completed
if (!sheet)

Просмотреть файл

@ -169,7 +169,9 @@ nsStyleSheetService::LoadAndRegisterSheetInternal(nsIURI *aSheetURI,
nsCOMPtr<nsICSSLoader> loader = do_CreateInstance(kCSSLoaderCID);
nsCOMPtr<nsICSSStyleSheet> sheet;
nsresult rv = loader->LoadSheetSync(aSheetURI, getter_AddRefs(sheet));
// Allow UA sheets, but not user sheets, to use unsafe rules
nsresult rv = loader->LoadSheetSync(aSheetURI, aSheetType == AGENT_SHEET,
getter_AddRefs(sheet));
NS_ENSURE_SUCCESS(rv, rv);
if (!mSheets[aSheetType].AppendObject(sheet)) {

Просмотреть файл

@ -625,7 +625,7 @@ nsContentDLF::EnsureUAStyleSheet()
NS_NewCSSLoader(getter_AddRefs(cssLoader));
if (!cssLoader)
return NS_ERROR_OUT_OF_MEMORY;
rv = cssLoader->LoadSheetSync(uri, &gUAStyleSheet);
rv = cssLoader->LoadSheetSync(uri, PR_TRUE, &gUAStyleSheet);
#ifdef DEBUG
if (NS_FAILED(rv))
printf("*** open of %s failed: error=%x\n", UA_CSS_URL, rv);

Просмотреть файл

@ -164,6 +164,7 @@ SheetLoadData::SheetLoadData(CSSLoaderImpl* aLoader,
mIsCancelled(PR_FALSE),
mMustNotify(PR_FALSE),
mWasAlternate(aIsAlternate),
mAllowUnsafeRules(PR_FALSE),
mOwningElement(aOwningElement),
mObserver(aObserver)
{
@ -191,6 +192,7 @@ SheetLoadData::SheetLoadData(CSSLoaderImpl* aLoader,
mIsCancelled(PR_FALSE),
mMustNotify(PR_FALSE),
mWasAlternate(PR_FALSE),
mAllowUnsafeRules(PR_FALSE),
mOwningElement(nsnull),
mObserver(aObserver)
{
@ -201,6 +203,7 @@ SheetLoadData::SheetLoadData(CSSLoaderImpl* aLoader,
NS_ADDREF(mParentData);
mSyncLoad = mParentData->mSyncLoad;
mIsNonDocumentSheet = mParentData->mIsNonDocumentSheet;
mAllowUnsafeRules = mParentData->mAllowUnsafeRules;
++(mParentData->mPendingChildren);
}
}
@ -209,6 +212,7 @@ SheetLoadData::SheetLoadData(CSSLoaderImpl* aLoader,
nsIURI* aURI,
nsICSSStyleSheet* aSheet,
PRBool aSyncLoad,
PRBool aAllowUnsafeRules,
nsICSSLoaderObserver* aObserver)
: mLoader(aLoader),
mParserToUnblock(nsnull),
@ -224,6 +228,7 @@ SheetLoadData::SheetLoadData(CSSLoaderImpl* aLoader,
mIsCancelled(PR_FALSE),
mMustNotify(PR_FALSE),
mWasAlternate(PR_FALSE),
mAllowUnsafeRules(aAllowUnsafeRules),
mOwningElement(nsnull),
mObserver(aObserver)
{
@ -1415,6 +1420,7 @@ CSSLoaderImpl::ParseSheet(nsIUnicharInputStream* aStream,
aLoadData->mSheet->GetSheetURI(getter_AddRefs(sheetURI));
aLoadData->mSheet->GetBaseURI(getter_AddRefs(baseURI));
rv = parser->Parse(aStream, sheetURI, baseURI, aLoadData->mLineNumber,
aLoadData->mAllowUnsafeRules,
*getter_AddRefs(dummySheet));
mParsingDatas.RemoveElementAt(mParsingDatas.Count() - 1);
RecycleParser(parser);
@ -1842,21 +1848,23 @@ CSSLoaderImpl::LoadChildSheet(nsICSSStyleSheet* aParentSheet,
}
NS_IMETHODIMP
CSSLoaderImpl::LoadSheetSync(nsIURI* aURL, nsICSSStyleSheet** aSheet)
CSSLoaderImpl::LoadSheetSync(nsIURI* aURL, PRBool aAllowUnsafeRules,
nsICSSStyleSheet** aSheet)
{
LOG(("CSSLoaderImpl::LoadSheetSync"));
return InternalLoadNonDocumentSheet(aURL, aSheet, nsnull);
return InternalLoadNonDocumentSheet(aURL, aAllowUnsafeRules, aSheet, nsnull);
}
NS_IMETHODIMP
CSSLoaderImpl::LoadSheet(nsIURI* aURL, nsICSSLoaderObserver* aObserver)
{
LOG(("CSSLoaderImpl::LoadSheet api call"));
return InternalLoadNonDocumentSheet(aURL, nsnull, aObserver);
return InternalLoadNonDocumentSheet(aURL, PR_FALSE, nsnull, aObserver);
}
nsresult
CSSLoaderImpl::InternalLoadNonDocumentSheet(nsIURI* aURL,
PRBool aAllowUnsafeRules,
nsICSSStyleSheet** aSheet,
nsICSSLoaderObserver* aObserver)
{
@ -1898,7 +1906,8 @@ CSSLoaderImpl::InternalLoadNonDocumentSheet(nsIURI* aURL,
return rv;
}
SheetLoadData* data = new SheetLoadData(this, aURL, sheet, syncLoad, aObserver);
SheetLoadData* data =
new SheetLoadData(this, aURL, sheet, syncLoad, aAllowUnsafeRules, aObserver);
if (!data) {
sheet->SetComplete();

Просмотреть файл

@ -130,6 +130,7 @@ public:
nsIURI* aURI,
nsICSSStyleSheet* aSheet,
PRBool aSyncLoad,
PRBool aAllowUnsafeRules,
nsICSSLoaderObserver* aObserver);
already_AddRefed<nsIURI> GetReferrerURI();
@ -201,6 +202,10 @@ public:
// created.
PRPackedBool mWasAlternate : 1;
// mAllowUnsafeRules is true if we should allow unsafe rules to be parsed
// in the loaded sheet.
PRPackedBool mAllowUnsafeRules : 1;
// This is the element that imported the sheet. Needed to get the
// charset set on it.
nsCOMPtr<nsIStyleSheetLinkingElement> mOwningElement;
@ -273,7 +278,8 @@ public:
nsMediaList* aMedia,
nsICSSImportRule* aRule);
NS_IMETHOD LoadSheetSync(nsIURI* aURL, nsICSSStyleSheet** aSheet);
NS_IMETHOD LoadSheetSync(nsIURI* aURL, PRBool aAllowUnsafeRules,
nsICSSStyleSheet** aSheet);
NS_IMETHOD LoadSheet(nsIURI* aURL, nsICSSLoaderObserver* aObserver);
@ -333,6 +339,7 @@ private:
nsICSSImportRule* aParentRule);
nsresult InternalLoadNonDocumentSheet(nsIURI* aURL,
PRBool aAllowUnsafeRules,
nsICSSStyleSheet** aSheet,
nsICSSLoaderObserver* aObserver);

Просмотреть файл

@ -109,6 +109,7 @@ public:
nsIURI* aSheetURI,
nsIURI* aBaseURI,
PRUint32 aLineNumber,
PRBool aAllowUnsafeRules,
nsICSSStyleSheet*& aResult);
NS_IMETHOD ParseStyleAttribute(const nsAString& aAttributeValue,
@ -423,6 +424,9 @@ protected:
// True if we are in quirks mode; false in standards or almost standards mode
PRPackedBool mNavQuirkMode : 1;
// True if unsafe rules should be allowed
PRPackedBool mUnsafeRulesEnabled : 1;
#ifdef MOZ_SVG
// True if we are in SVG mode; false in "normal" CSS
@ -530,6 +534,7 @@ CSSParserImpl::CSSParserImpl()
mNameSpaceMap(nsnull),
mHavePushBack(PR_FALSE),
mNavQuirkMode(PR_FALSE),
mUnsafeRulesEnabled(PR_FALSE),
#ifdef MOZ_SVG
mSVGMode(PR_FALSE),
#endif
@ -663,6 +668,7 @@ CSSParserImpl::Parse(nsIUnicharInputStream* aInput,
nsIURI* aSheetURI,
nsIURI* aBaseURI,
PRUint32 aLineNumber,
PRBool aAllowUnsafeRules,
nsICSSStyleSheet*& aResult)
{
NS_ASSERTION(nsnull != aBaseURI, "need base URL");
@ -719,6 +725,8 @@ CSSParserImpl::Parse(nsIUnicharInputStream* aInput,
mSection = eCSSSection_Charset; // sheet is empty, any rules are fair
}
mUnsafeRulesEnabled = aAllowUnsafeRules;
nsCSSToken* tk = &mToken;
for (;;) {
// Get next non-whitespace token
@ -740,6 +748,8 @@ CSSParserImpl::Parse(nsIUnicharInputStream* aInput,
}
ReleaseScanner();
mUnsafeRulesEnabled = PR_FALSE;
aResult = mSheet;
NS_ADDREF(aResult);
@ -2433,7 +2443,9 @@ CSSParserImpl::ParsePseudoSelector(PRInt32& aDataMask,
nsCOMPtr<nsIAtom> pseudo = do_GetAtom(buffer);
// stash away some info about this pseudo so we only have to get it once.
PRBool isTreePseudo = PR_FALSE;
#ifdef MOZ_XUL
isTreePseudo = IsTreePseudoElement(pseudo);
// If a tree pseudo-element is using the function syntax, it will
// get isTree set here and will pass the check below that only
// allows functions if they are in our list of things allowed to be
@ -2441,11 +2453,13 @@ CSSParserImpl::ParsePseudoSelector(PRInt32& aDataMask,
// be false, and it will still pass that check. So the tree
// pseudo-elements are allowed to be either functions or not, as
// desired.
PRBool isTree = (eCSSToken_Function == mToken.mType) &&
IsTreePseudoElement(pseudo);
PRBool isTree = (eCSSToken_Function == mToken.mType) && isTreePseudo;
#endif
PRBool isPseudoElement = nsCSSPseudoElements::IsPseudoElement(pseudo);
PRBool isAnonBox = nsCSSAnonBoxes::IsAnonBox(pseudo);
// anonymous boxes are only allowed if they're the tree boxes or we have
// enabled unsafe rules
PRBool isAnonBox = nsCSSAnonBoxes::IsAnonBox(pseudo) &&
(mUnsafeRulesEnabled || isTreePseudo);
PRBool isPseudoClass = nsCSSPseudoClasses::IsPseudoClass(pseudo);
if (!isPseudoClass && !isPseudoElement && !isAnonBox) {
@ -2523,7 +2537,7 @@ CSSParserImpl::ParsePseudoSelector(PRInt32& aDataMask,
if (!parsingPseudoElement &&
!nsCSSPseudoElements::IsCSS2PseudoElement(pseudo)
#ifdef MOZ_XUL
&& !IsTreePseudoElement(pseudo)
&& !isTreePseudo
#endif
) {
REPORT_UNEXPECTED_TOKEN(PEPseudoSelNewStyleOnly);

Просмотреть файл

@ -60,7 +60,7 @@ class nsICSSImportRule;
// IID for the nsICSSLoader interface
// ff43802a-b355-41f2-919d-5c7ab3dbfb91
#define NS_ICSS_LOADER_IID \
{0xff43802a, 0xb355, 0x41f2, {0x91, 0x9d, 0x5c, 0x7a, 0xb3, 0xdb, 0xfb, 0x91}}
{0x8e8deacc, 0xdfe5, 0x4c61, {0x90, 0x14, 0x65, 0x2b, 0xa7, 0xe9, 0x7f, 0x2c}}
typedef void (*nsCSSLoaderCallbackFunc)(nsICSSStyleSheet* aSheet, void *aData, PRBool aDidNotify);
@ -177,6 +177,13 @@ public:
*
* @param aURL the URL of the sheet to load
* @param [out] aSheet the loaded, complete sheet.
* @param aEnableUnsafeRules whether unsafe rules are enabled for this
* sheet load
* Unsafe rules are rules that can violate key Gecko invariants if misused.
* In particular, most anonymous box pseudoelements must be very carefully
* styled or we will have severe problems. Therefore unsafe rules should
* never be enabled for stylesheets controlled by untrusted sites; preferably
* unsafe rules should only be enabled for agent sheets.
*
* NOTE: At the moment, this method assumes the sheet will be UTF-8, but
* ideally it would allow arbitrary encodings. Callers should NOT depend on
@ -186,7 +193,15 @@ public:
* whether the data could be parsed as CSS and doesn't indicate anything
* about the status of child sheets of the returned sheet.
*/
NS_IMETHOD LoadSheetSync(nsIURI* aURL, nsICSSStyleSheet** aSheet) = 0;
NS_IMETHOD LoadSheetSync(nsIURI* aURL, PRBool aEnableUnsafeRules,
nsICSSStyleSheet** aSheet) = 0;
/**
* As above, but aEnableUnsafeRules is assumed false.
*/
nsresult LoadSheetSync(nsIURI* aURL, nsICSSStyleSheet** aSheet) {
return LoadSheetSync(aURL, PR_FALSE, aSheet);
}
/**
* Asynchronously load the stylesheet at aURL. If a successful result is

Просмотреть файл

@ -56,8 +56,8 @@ class nsICSSRule;
class nsMediaList;
#define NS_ICSS_PARSER_IID \
{ 0x8f2705b6, 0x11ed, 0x47a0, \
{0xaf, 0x25, 0x04, 0x2e, 0x3d, 0x4a, 0x6f, 0xb7} }
{ 0x2cb34728, 0x0f17, 0x4753, \
{0x8e, 0xad, 0xec, 0x73, 0xe5, 0x69, 0xcd, 0xcd} }
// Rule processing function
typedef void (*PR_CALLBACK RuleAppendFunc) (nsICSSRule* aRule, void* aData);
@ -85,10 +85,15 @@ public:
// Set loader to use for child sheets
NS_IMETHOD SetChildLoader(nsICSSLoader* aChildLoader) = 0;
/**
* @param aAllowUnsafeRules see aEnableUnsafeRules in
* nsICSSLoader::LoadSheetSync
*/
NS_IMETHOD Parse(nsIUnicharInputStream* aInput,
nsIURI* aSheetURL,
nsIURI* aBaseURI,
PRUint32 aLineNumber,
PRBool aAllowUnsafeRules,
nsICSSStyleSheet*& aResult) = 0;
// Parse HTML style attribute or its equivalent in other markup

Просмотреть файл

@ -86,8 +86,9 @@ nsLayoutStylesheetCache::ScrollbarsSheet()
NS_LITERAL_CSTRING("chrome://global/skin/xulscrollbars.css"));
#endif
// Scrollbars don't need access to unsafe rules
if (sheetURI)
LoadSheet(sheetURI, gStyleCache->mScrollbarsSheet);
LoadSheet(sheetURI, gStyleCache->mScrollbarsSheet, PR_FALSE);
#ifdef XP_MACOSX
NS_ASSERTION(gStyleCache->mScrollbarsSheet, "Could not load nativescrollbars.css.");
#else
@ -110,8 +111,9 @@ nsLayoutStylesheetCache::FormsSheet()
NS_NewURI(getter_AddRefs(sheetURI),
NS_LITERAL_CSTRING("resource://gre/res/forms.css"));
// forms.css needs access to unsafe rules
if (sheetURI)
LoadSheet(sheetURI, gStyleCache->mFormsSheet);
LoadSheet(sheetURI, gStyleCache->mFormsSheet, PR_TRUE);
NS_ASSERTION(gStyleCache->mFormsSheet, "Could not load forms.css.");
}
@ -213,11 +215,12 @@ nsLayoutStylesheetCache::LoadSheetFile(nsIFile* aFile, nsCOMPtr<nsICSSStyleSheet
nsCOMPtr<nsIURI> uri;
NS_NewFileURI(getter_AddRefs(uri), aFile);
LoadSheet(uri, aSheet);
LoadSheet(uri, aSheet, PR_FALSE);
}
void
nsLayoutStylesheetCache::LoadSheet(nsIURI* aURI, nsCOMPtr<nsICSSStyleSheet> &aSheet)
nsLayoutStylesheetCache::LoadSheet(nsIURI* aURI, nsCOMPtr<nsICSSStyleSheet> &aSheet,
PRBool aEnableUnsafeRules)
{
if (!aURI) {
NS_ERROR("Null URI. Out of memory?");
@ -227,8 +230,9 @@ nsLayoutStylesheetCache::LoadSheet(nsIURI* aURI, nsCOMPtr<nsICSSStyleSheet> &aSh
if (!gCSSLoader)
NS_NewCSSLoader(&gCSSLoader);
if (gCSSLoader)
gCSSLoader->LoadSheetSync(aURI, getter_AddRefs(aSheet));
if (gCSSLoader) {
gCSSLoader->LoadSheetSync(aURI, aEnableUnsafeRules, getter_AddRefs(aSheet));
}
}
nsLayoutStylesheetCache*

Просмотреть файл

@ -65,7 +65,8 @@ private:
static void EnsureGlobal();
void InitFromProfile();
static void LoadSheetFile(nsIFile* aFile, nsCOMPtr<nsICSSStyleSheet> &aSheet);
static void LoadSheet(nsIURI* aURI, nsCOMPtr<nsICSSStyleSheet> &aSheet);
static void LoadSheet(nsIURI* aURI, nsCOMPtr<nsICSSStyleSheet> &aSheet,
PRBool aEnableUnsafeRules);
static nsLayoutStylesheetCache* gStyleCache;
static nsICSSLoader* gCSSLoader;

Просмотреть файл

@ -1415,7 +1415,7 @@ nsresult nsChromeRegistry::RefreshWindow(nsIDOMWindowInternal* aWindow)
if (IsChromeURI(uri)) {
// Reload the sheet.
nsCOMPtr<nsICSSStyleSheet> newSheet;
rv = LoadStyleSheetWithURL(uri, getter_AddRefs(newSheet));
rv = LoadStyleSheetWithURL(uri, PR_TRUE, getter_AddRefs(newSheet));
if (NS_FAILED(rv)) return rv;
if (newSheet) {
rv = newAgentSheets.AppendObject(newSheet) ? NS_OK : NS_ERROR_FAILURE;
@ -1467,7 +1467,7 @@ nsresult nsChromeRegistry::RefreshWindow(nsIDOMWindowInternal* aWindow)
// XXX what about chrome sheets that have a title or are disabled? This
// only works by sheer dumb luck.
// XXXbz this should really use the document's CSSLoader!
LoadStyleSheetWithURL(uri, getter_AddRefs(newSheet));
LoadStyleSheetWithURL(uri, PR_FALSE, getter_AddRefs(newSheet));
// Even if it's null, we put in in there.
newSheets.AppendObject(newSheet);
}
@ -2976,7 +2976,7 @@ nsChromeRegistry::AddToCompositeDataSource(PRBool aUseProfile)
return NS_OK;
}
nsresult nsChromeRegistry::LoadStyleSheetWithURL(nsIURI* aURL, nsICSSStyleSheet** aSheet)
nsresult nsChromeRegistry::LoadStyleSheetWithURL(nsIURI* aURL, PRBool aEnableUnsafeRules, nsICSSStyleSheet** aSheet)
{
*aSheet = nsnull;
@ -2986,7 +2986,7 @@ nsresult nsChromeRegistry::LoadStyleSheetWithURL(nsIURI* aURL, nsICSSStyleSheet*
NS_ENSURE_SUCCESS(rv, rv);
}
return mCSSLoader->LoadSheetSync(aURL, aSheet);
return mCSSLoader->LoadSheetSync(aURL, aEnableUnsafeRules, aSheet);
}
nsresult nsChromeRegistry::LoadInstallDataSource()

Просмотреть файл

@ -121,7 +121,7 @@ protected:
PRBool aIsOverlay, PRBool
aUseProfile, PRBool aRemove);
nsresult LoadStyleSheetWithURL(nsIURI* aURL, nsICSSStyleSheet** aSheet);
nsresult LoadStyleSheetWithURL(nsIURI* aURL, PRBool aEnableUnsafeRules, nsICSSStyleSheet** aSheet);
nsresult LoadInstallDataSource();
nsresult LoadProfileDataSource();