Follow-on fix for bug 457825. Use sheet principal for agent and user sheets. r=dbaron,bz sr=dbaron
authorJohn Daggett <jdaggett@mozilla.com>
Thu, 27 Nov 2008 12:50:16 +0900
changeset 21983 32c9710b2398cd38899a5f1d1c095a8a4ac08ff3
parent 21982 8d644579453df7b9a418a77dbfd09996a23fe4b5
child 21984 8dc5392b0c1de8502e06c4b8cee32ea875ed82d1
push id1
push userroot
push dateTue, 26 Apr 2011 22:38:44 +0000
treeherdermozilla-beta@bfdb6e623a36 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdbaron, bz, dbaron
bugs457825
milestone1.9.1b3pre
Follow-on fix for bug 457825. Use sheet principal for agent and user sheets. r=dbaron,bz sr=dbaron
content/xbl/src/nsXBLPrototypeResources.cpp
content/xbl/src/nsXBLResourceLoader.cpp
gfx/thebes/public/gfxUserFontSet.h
gfx/thebes/src/gfxUserFontSet.cpp
layout/base/nsPresContext.cpp
layout/base/nsPresContext.h
layout/style/nsCSSRuleProcessor.cpp
layout/style/nsCSSRuleProcessor.h
layout/style/nsCSSRules.h
layout/style/nsFontFaceLoader.cpp
layout/style/nsFontFaceLoader.h
layout/style/nsStyleSet.cpp
layout/style/nsStyleSet.h
--- a/content/xbl/src/nsXBLPrototypeResources.cpp
+++ b/content/xbl/src/nsXBLPrototypeResources.cpp
@@ -45,16 +45,17 @@
 #include "nsIServiceManager.h"
 #include "nsXBLResourceLoader.h"
 #include "nsXBLPrototypeResources.h"
 #include "nsIDocumentObserver.h"
 #include "nsICSSLoader.h"
 #include "nsIURI.h"
 #include "nsLayoutCID.h"
 #include "nsCSSRuleProcessor.h"
+#include "nsStyleSet.h"
 
 static NS_DEFINE_CID(kCSSLoaderCID, NS_CSS_LOADER_CID);
 
 nsXBLPrototypeResources::nsXBLPrototypeResources(nsXBLPrototypeBinding* aBinding)
 {
   MOZ_COUNT_CTOR(nsXBLPrototypeResources);
 
   mLoader = new nsXBLResourceLoader(aBinding, this);
@@ -134,12 +135,13 @@ nsXBLPrototypeResources::FlushSkinSheets
         continue;
     }
     else {
       newSheet = oldSheet;
     }
     
     mStyleSheetList.AppendObject(newSheet);
   }
-  mRuleProcessor = new nsCSSRuleProcessor(mStyleSheetList);
+  mRuleProcessor = new nsCSSRuleProcessor(mStyleSheetList, 
+                                          nsStyleSet::eDocSheet);
   
   return NS_OK;
 }
--- a/content/xbl/src/nsXBLResourceLoader.cpp
+++ b/content/xbl/src/nsXBLResourceLoader.cpp
@@ -53,16 +53,17 @@
 #include "nsIURI.h"
 #include "nsNetUtil.h"
 #include "nsGkAtoms.h"
 #include "nsFrameManager.h"
 #include "nsStyleContext.h"
 #include "nsXBLPrototypeBinding.h"
 #include "nsCSSRuleProcessor.h"
 #include "nsContentUtils.h"
+#include "nsStyleSet.h"
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(nsXBLResourceLoader)
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsXBLResourceLoader)
 NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMARRAY(mBoundElements)
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsXBLResourceLoader)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMARRAY(mBoundElements)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
@@ -187,17 +188,18 @@ nsXBLResourceLoader::StyleSheetLoaded(ns
   mResources->mStyleSheetList.AppendObject(aSheet);
 
   if (!mInLoadResourcesFunc)
     mPendingSheets--;
   
   if (mPendingSheets == 0) {
     // All stylesheets are loaded.  
     mResources->mRuleProcessor =
-      new nsCSSRuleProcessor(mResources->mStyleSheetList);
+      new nsCSSRuleProcessor(mResources->mStyleSheetList, 
+                             nsStyleSet::eDocSheet);
 
     // XXX Check for mPendingScripts when scripts also come online.
     if (!mInLoadResourcesFunc)
       NotifyBoundElements();
   }
   return NS_OK;
 }
 
--- a/gfx/thebes/public/gfxUserFontSet.h
+++ b/gfx/thebes/public/gfxUserFontSet.h
@@ -49,24 +49,30 @@
 
 class nsIURI;
 class gfxMixedFontFamily;
 
 // parsed CSS @font-face rule information
 // lifetime: from when @font-face rule processed until font is loaded
 struct gfxFontFaceSrc {
     PRPackedBool           mIsLocal;       // url or local
-    nsString               mLocalName;     // full font name if local
-    nsCOMPtr<nsIURI>       mURI;           // uri if url 
-    nsCOMPtr<nsIURI>       mReferrer;      // referrer url if url
+
+    // if url, whether to use the origin principal or not
+    PRPackedBool           mUseOriginPrincipal;
 
     // format hint flags, union of all possible formats
     // (e.g. TrueType, EOT, SVG, etc.)
     // see FLAG_FORMAT_* enum values below
     PRUint32               mFormatFlags;
+
+    nsString               mLocalName;     // full font name if local
+    nsCOMPtr<nsIURI>       mURI;           // uri if url 
+    nsCOMPtr<nsIURI>       mReferrer;      // referrer url if url
+    nsCOMPtr<nsISupports>  mOriginPrincipal; // principal if url 
+    
 };
 
 // subclassed to store platform-specific code cleaned out when font entry is deleted
 // lifetime: from when platform font is created until it is deactivated 
 class gfxUserFontData {
 public:
     gfxUserFontData() { }
     virtual ~gfxUserFontData() { }
@@ -134,19 +140,18 @@ protected:
 };
 
 class gfxProxyFontEntry;
 
 class THEBES_API gfxUserFontSet {
 
 public:
     class LoaderContext;
-    typedef nsresult (*LoaderCallback) (gfxFontEntry *aFontToLoad, 
-                                        nsIURI *aSrcURL,
-                                        nsIURI *aReferrerURI,
+    typedef nsresult (*LoaderCallback) (gfxFontEntry *aFontToLoad,
+                                        const gfxFontFaceSrc *aFontFaceSrc,
                                         LoaderContext *aContextData);
 
     class LoaderContext {
     public:
         LoaderContext(LoaderCallback aLoader)
             : mUserFontSet(nsnull), mLoaderProc(aLoader) { }
         virtual ~LoaderContext() { }
 
--- a/gfx/thebes/src/gfxUserFontSet.cpp
+++ b/gfx/thebes/src/gfxUserFontSet.cpp
@@ -316,19 +316,17 @@ gfxUserFontSet::LoadNext(gfxProxyFontEnt
                      NS_ConvertUTF16toUTF8(aProxyEntry->mFamily->Name()).get()));            
             }
         } 
 
         // src url ==> start the load process
         else {
             if (gfxPlatform::GetPlatform()->IsFontFormatSupported(currSrc.mURI, 
                     currSrc.mFormatFlags)) {
-                nsresult rv = mLoaderContext->mLoaderProc(aProxyEntry, 
-                                                          currSrc.mURI,
-                                                          currSrc.mReferrer,
+                nsresult rv = mLoaderContext->mLoaderProc(aProxyEntry, &currSrc,
                                                           mLoaderContext);
                 PRBool loadOK = NS_SUCCEEDED(rv);
                 
                 if (loadOK) {
 #ifdef PR_LOGGING
                     if (LOG_ENABLED()) {
                         nsCAutoString fontURI;
                         currSrc.mURI->GetSpec(fontURI);
--- a/layout/base/nsPresContext.cpp
+++ b/layout/base/nsPresContext.cpp
@@ -1569,17 +1569,18 @@ nsPresContext::IsChrome() const
 /* virtual */ PRBool
 nsPresContext::HasAuthorSpecifiedRules(nsIFrame *aFrame, PRUint32 ruleTypeMask) const
 {
   return nsRuleNode::
     HasAuthorSpecifiedRules(aFrame->GetStyleContext(), ruleTypeMask);
 }
 
 static void
-InsertFontFaceRule(nsCSSFontFaceRule *aRule, gfxUserFontSet* aFontSet)
+InsertFontFaceRule(nsCSSFontFaceRule *aRule, gfxUserFontSet* aFontSet,
+                   PRUint8 aSheetType)
 {
   PRInt32 type;
   NS_ABORT_IF_FALSE(NS_SUCCEEDED(aRule->GetType(type)) 
                     && type == nsICSSRule::FONT_FACE_RULE, 
                     "InsertFontFaceRule passed a non-fontface CSS rule");
   
   // aRule->List();
   
@@ -1659,16 +1660,26 @@ InsertFontFaceRule(nsCSSFontFaceRule *aR
         face->mURI = nsnull;
         face->mFormatFlags = 0;
         break;
       case eCSSUnit_URL:
         face->mIsLocal = PR_FALSE;
         face->mURI = val.GetURLValue();
         NS_ASSERTION(face->mURI, "null url in @font-face rule");
         face->mReferrer = val.GetURLStructValue()->mReferrer;
+        face->mOriginPrincipal = val.GetURLStructValue()->mOriginPrincipal;
+        NS_ASSERTION(face->mOriginPrincipal, "null origin principal in @font-face rule");
+        
+        // agent and user stylesheets are treated slightly differently,
+        // the same-site origin check and access control headers are
+        // enforced against the sheet principal rather than the document
+        // principal to allow user stylesheets to include @font-face rules
+        face->mUseOriginPrincipal = (aSheetType == nsStyleSet::eUserSheet ||
+                                     aSheetType == nsStyleSet::eAgentSheet);
+                                     
         face->mLocalName.Truncate();
         face->mFormatFlags = 0;
         while (i + 1 < numSrc && (val = srcArr->Item(i+1), 
                  val.GetUnit() == eCSSUnit_Font_Format)) {
           nsDependentString valueString(val.GetStringBufferValue());
           if (valueString.LowerCaseEqualsASCII("opentype")) {
             face->mFormatFlags |= gfxUserFontSet::FLAG_FORMAT_OPENTYPE; 
           } else if (valueString.LowerCaseEqualsASCII("truetype")) {
@@ -1725,25 +1736,26 @@ nsPresContext::FlushUserFontSet()
 {
   if (!mShell)
     return; // we've been torn down
 
   if (mUserFontSetDirty) {
     if (gfxPlatform::GetPlatform()->DownloadableFontsEnabled()) {
       nsRefPtr<gfxUserFontSet> oldUserFontSet = mUserFontSet;
 
-      nsTArray< nsRefPtr<nsCSSFontFaceRule> > rules;
+      nsTArray<nsFontFaceRuleContainer> rules;
       if (!mShell->StyleSet()->AppendFontFaceRules(this, rules))
         return;
 
       PRBool differ;
       if (rules.Length() == mFontFaceRules.Length()) {
         differ = PR_FALSE;
         for (PRUint32 i = 0, i_end = rules.Length(); i < i_end; ++i) {
-          if (rules[i] != mFontFaceRules[i]) {
+          if (rules[i].mRule != mFontFaceRules[i].mRule ||
+              rules[i].mSheetType != mFontFaceRules[i].mSheetType) {
             differ = PR_TRUE;
             break;
           }
         }
       } else {
         differ = PR_TRUE;
       }
 
@@ -1761,17 +1773,17 @@ nsPresContext::FlushUserFontSet()
           if (!fs) {
             delete loaderCtx;
             return;
           }
           mUserFontSet = fs;
           NS_ADDREF(mUserFontSet);
 
           for (PRUint32 i = 0, i_end = rules.Length(); i < i_end; ++i) {
-            InsertFontFaceRule(rules[i], fs);
+            InsertFontFaceRule(rules[i].mRule, fs, rules[i].mSheetType);
           }
         }
       }
 
 #ifdef DEBUG
       PRBool success =
 #endif
         rules.SwapElements(mFontFaceRules);
--- a/layout/base/nsPresContext.h
+++ b/layout/base/nsPresContext.h
@@ -90,17 +90,17 @@ class nsIEventStateManager;
 class nsIURI;
 class nsILookAndFeel;
 class nsICSSPseudoComparator;
 class nsIAtom;
 struct nsStyleBackground;
 template <class T> class nsRunnableMethod;
 class nsIRunnable;
 class gfxUserFontSet;
-class nsCSSFontFaceRule;
+struct nsFontFaceRuleContainer;
 
 #ifdef MOZ_REFLOW_PERF
 class nsIRenderingContext;
 #endif
 
 enum nsWidgetType {
   eWidgetType_Button  	= 1,
   eWidgetType_Checkbox	= 2,
@@ -818,17 +818,17 @@ protected:
   nsPropertyTable       mPropertyTable;
 
   nsRegion              mSameDocDirtyRegion;
   nsRegion              mCrossDocDirtyRegion;
 
   // container for per-context fonts (downloadable, SVG, etc.)
   gfxUserFontSet* mUserFontSet;
   // The list of @font-face rules that we put into mUserFontSet
-  nsTArray< nsRefPtr<nsCSSFontFaceRule> > mFontFaceRules;
+  nsTArray<nsFontFaceRuleContainer> mFontFaceRules;
   
   PRInt32               mFontScaler;
   nscoord               mMinimumFontSize;
 
   nsRect                mVisibleArea;
   nsSize                mPageSize;
   float                 mPageScale;
   float                 mPPScale;
--- a/layout/style/nsCSSRuleProcessor.cpp
+++ b/layout/style/nsCSSRuleProcessor.cpp
@@ -78,16 +78,18 @@
 #include "nsAttrName.h"
 #include "nsILookAndFeel.h"
 #include "nsWidgetsCID.h"
 #include "nsServiceManagerUtils.h"
 #include "nsTArray.h"
 #include "nsContentUtils.h"
 #include "nsIMediaList.h"
 #include "nsCSSRules.h"
+#include "nsIPrincipal.h"
+#include "nsStyleSet.h"
 
 #define VISITED_PSEUDO_PREF "layout.css.visited_links_enabled"
 
 static PRBool gSupportVisitedPseudo = PR_TRUE;
 
 static NS_DEFINE_CID(kLookAndFeelCID, NS_LOOKANDFEEL_CID);
 static nsTArray< nsCOMPtr<nsIAtom> >* sSystemMetrics = 0;
 
@@ -701,17 +703,17 @@ struct RuleCascadeData {
     PL_DHashTableFinish(&mAttributeSelectors);
   }
   RuleHash          mRuleHash;
   nsVoidArray       mStateSelectors;
   nsVoidArray       mClassSelectors;
   nsVoidArray       mIDSelectors;
   PLDHashTable      mAttributeSelectors; // nsIAtom* -> nsVoidArray*
 
-  nsTArray< nsRefPtr<nsCSSFontFaceRule> > mFontFaceRules;
+  nsTArray<nsFontFaceRuleContainer> mFontFaceRules;
 
   // Looks up or creates the appropriate list in |mAttributeSelectors|.
   // Returns null only on allocation failure.
   nsVoidArray* AttributeListFor(nsIAtom* aAttribute);
 
   nsMediaQueryResultCacheKey mCacheKey;
   RuleCascadeData*  mNext; // for a different medium
 };
@@ -732,20 +734,22 @@ RuleCascadeData::AttributeListFor(nsIAto
   }
   return entry->mSelectors;
 }
 
 // -------------------------------
 // CSS Style rule processor implementation
 //
 
-nsCSSRuleProcessor::nsCSSRuleProcessor(const nsCOMArray<nsICSSStyleSheet>& aSheets)
+nsCSSRuleProcessor::nsCSSRuleProcessor(const nsCOMArray<nsICSSStyleSheet>& aSheets,
+                                       PRUint8 aSheetType)
   : mSheets(aSheets)
   , mRuleCascades(nsnull)
   , mLastPresContext(nsnull)
+  , mSheetType(aSheetType)
 {
   for (PRInt32 i = mSheets.Count() - 1; i >= 0; --i)
     mSheets[i]->AddRuleProcessor(this);
 }
 
 nsCSSRuleProcessor::~nsCSSRuleProcessor()
 {
   for (PRInt32 i = mSheets.Count() - 1; i >= 0; --i)
@@ -2146,17 +2150,17 @@ nsCSSRuleProcessor::MediumFeaturesChange
   return NS_OK;
 }
 
 // Append all the currently-active font face rules to aArray.  Return
 // true for success and false for failure.
 PRBool
 nsCSSRuleProcessor::AppendFontFaceRules(
                               nsPresContext *aPresContext,
-                              nsTArray< nsRefPtr<nsCSSFontFaceRule> >& aArray)
+                              nsTArray<nsFontFaceRuleContainer>& aArray)
 {
   RuleCascadeData* cascade = GetRuleCascade(aPresContext);
 
   if (cascade) {
     if (!aArray.AppendElements(cascade->mFontFaceRules))
       return PR_FALSE;
   }
   
@@ -2303,42 +2307,45 @@ static PLDHashTableOps gRulesByWeightOps
     PL_DHashMoveEntryStub,
     PL_DHashClearEntryStub,
     PL_DHashFinalizeStub,
     NULL
 };
 
 struct CascadeEnumData {
   CascadeEnumData(nsPresContext* aPresContext,
-                  nsTArray< nsRefPtr<nsCSSFontFaceRule> >& aFontFaceRules,
+                  nsTArray<nsFontFaceRuleContainer>& aFontFaceRules,
                   nsMediaQueryResultCacheKey& aKey,
-                  PLArenaPool& aArena)
+                  PLArenaPool& aArena,
+                  PRUint8 aSheetType)
     : mPresContext(aPresContext),
       mFontFaceRules(aFontFaceRules),
       mCacheKey(aKey),
-      mArena(aArena)
+      mArena(aArena),
+      mSheetType(aSheetType)
   {
     if (!PL_DHashTableInit(&mRulesByWeight, &gRulesByWeightOps, nsnull,
                           sizeof(RuleByWeightEntry), 64))
       mRulesByWeight.ops = nsnull;
   }
 
   ~CascadeEnumData()
   {
     if (mRulesByWeight.ops)
       PL_DHashTableFinish(&mRulesByWeight);
   }
 
   nsPresContext* mPresContext;
-  nsTArray< nsRefPtr<nsCSSFontFaceRule> >& mFontFaceRules;
+  nsTArray<nsFontFaceRuleContainer>& mFontFaceRules;
   nsMediaQueryResultCacheKey& mCacheKey;
   // Hooray, a manual PLDHashTable since nsClassHashtable doesn't
   // provide a getter that gives me a *reference* to the value.
   PLDHashTable mRulesByWeight; // of RuleValue* linked lists (?)
   PLArenaPool& mArena;
+  PRUint8 mSheetType;
 };
 
 /*
  * This enumerates style rules in a sheet (and recursively into any
  * grouping rules) in order to:
  *  (1) add any style rules, in order, into data->mRulesByWeight (for
  *      the primary CSS cascade), where they are separated by weight
  *      but kept in order per-weight, and
@@ -2374,20 +2381,21 @@ CascadeRuleEnumFunc(nsICSSRule* aRule, v
            nsICSSRule::DOCUMENT_RULE == type) {
     nsICSSGroupRule* groupRule = (nsICSSGroupRule*)aRule;
     if (groupRule->UseForPresentation(data->mPresContext, data->mCacheKey))
       if (!groupRule->EnumerateRulesForwards(CascadeRuleEnumFunc, aData))
         return PR_FALSE;
   }
   else if (nsICSSRule::FONT_FACE_RULE == type) {
     nsCSSFontFaceRule *fontFaceRule = static_cast<nsCSSFontFaceRule*>(aRule);
-    nsRefPtr<nsCSSFontFaceRule> *ptr = data->mFontFaceRules.AppendElement();
+    nsFontFaceRuleContainer *ptr = data->mFontFaceRules.AppendElement();
     if (!ptr)
       return PR_FALSE;
-    *ptr = fontFaceRule;
+    ptr->mRule = fontFaceRule;
+    ptr->mSheetType = data->mSheetType;
   }
 
   return PR_TRUE;
 }
 
 /* static */ PRBool
 nsCSSRuleProcessor::CascadeSheetEnumFunc(nsICSSStyleSheet* aSheet, void* aData)
 {
@@ -2485,17 +2493,18 @@ nsCSSRuleProcessor::RefreshRuleCascade(n
 
   if (mSheets.Count() != 0) {
     nsAutoPtr<RuleCascadeData> newCascade(
       new RuleCascadeData(aPresContext->Medium(),
                           eCompatibility_NavQuirks == aPresContext->CompatibilityMode()));
     if (newCascade) {
       CascadeEnumData data(aPresContext, newCascade->mFontFaceRules,
                            newCascade->mCacheKey,
-                           newCascade->mRuleHash.Arena());
+                           newCascade->mRuleHash.Arena(),
+                           mSheetType);
       if (!data.mRulesByWeight.ops)
         return; /* out of memory */
       if (!mSheets.EnumerateForwards(CascadeSheetEnumFunc, &data))
         return; /* out of memory */
 
       // Sort the hash table of per-weight linked lists by weight.
       PRUint32 weightCount = data.mRulesByWeight.entryCount;
       nsAutoArrayPtr<PerWeightData> weightArray(new PerWeightData[weightCount]);
--- a/layout/style/nsCSSRuleProcessor.h
+++ b/layout/style/nsCSSRuleProcessor.h
@@ -62,17 +62,18 @@ class nsCSSFontFaceRule;
  * CSS style rule processors keep a live reference on all style sheets
  * bound to them.  The CSS style sheets keep a weak reference to all the
  * processors that they are bound to (many to many).  The CSS style sheet
  * is told when the rule processor is going away (via DropRuleProcessor).
  */
 
 class nsCSSRuleProcessor: public nsIStyleRuleProcessor {
 public:
-  nsCSSRuleProcessor(const nsCOMArray<nsICSSStyleSheet>& aSheets);
+  nsCSSRuleProcessor(const nsCOMArray<nsICSSStyleSheet>& aSheets, 
+                     PRUint8 aSheetType);
   virtual ~nsCSSRuleProcessor();
 
   NS_DECL_ISUPPORTS
 
 public:
   nsresult ClearRuleCascades();
 
   static void Startup();
@@ -98,17 +99,17 @@ public:
                                         nsReStyleHint* aResult);
 
   NS_IMETHOD MediumFeaturesChanged(nsPresContext* aPresContext,
                                    PRBool* aRulesChanged);
 
   // Append all the currently-active font face rules to aArray.  Return
   // true for success and false for failure.
   PRBool AppendFontFaceRules(nsPresContext* aPresContext,
-                             nsTArray< nsRefPtr<nsCSSFontFaceRule> >& aArray);
+                             nsTArray<nsFontFaceRuleContainer>& aArray);
 
 #ifdef DEBUG
   void AssertQuirksChangeOK() {
     NS_ASSERTION(!mRuleCascades, "can't toggle quirks style sheet without "
                                  "clearing rule cascades");
   }
 #endif
 
@@ -121,11 +122,14 @@ private:
   // The sheet order here is the same as in nsStyleSet::mSheets
   nsCOMArray<nsICSSStyleSheet> mSheets;
 
   // active first, then cached (most recent first)
   RuleCascadeData* mRuleCascades;
 
   // The last pres context for which GetRuleCascades was called.
   nsPresContext *mLastPresContext;
+  
+  // type of stylesheet using this processor
+  PRUint8 mSheetType;  // == nsStyleSet::sheetType
 };
 
 #endif /* nsCSSRuleProcessor_h_ */
--- a/layout/style/nsCSSRules.h
+++ b/layout/style/nsCSSRules.h
@@ -273,16 +273,23 @@ public:
   void SetDesc(nsCSSFontDesc aDescID, nsCSSValue const & aValue);
   void GetDesc(nsCSSFontDesc aDescID, nsCSSValue & aValue);
 
 protected:
   friend class nsCSSFontFaceStyleDecl;
   nsCSSFontFaceStyleDecl mDecl;
 };
 
+// nsFontFaceRuleContainer - used for associating sheet type with 
+// specific @font-face rules
+struct nsFontFaceRuleContainer {
+  nsRefPtr<nsCSSFontFaceRule> mRule;
+  PRUint8 mSheetType;
+};
+
 inline nsCSSFontFaceRule*
 nsCSSFontFaceStyleDecl::ContainingRule()
 {
   return reinterpret_cast<nsCSSFontFaceRule*>
     (reinterpret_cast<char*>(this) - offsetof(nsCSSFontFaceRule, mDecl));
 }
 
 inline const nsCSSFontFaceRule*
--- a/layout/style/nsFontFaceLoader.cpp
+++ b/layout/style/nsFontFaceLoader.cpp
@@ -138,89 +138,105 @@ nsFontFaceLoader::OnStreamComplete(nsISt
     }
   }
 
   return aStatus;
 }
 
 nsresult
 nsFontFaceLoader::CreateHandler(gfxFontEntry *aFontToLoad, 
-                                nsIURI *aFontURI,
-                                nsIURI *aReferrerURI,
+                                const gfxFontFaceSrc *aFontFaceSrc,
                                 gfxUserFontSet::LoaderContext *aContext)
 {
   nsresult rv;
   
   // check same-site origin
   nsFontFaceLoaderContext *loaderCtx 
                              = static_cast<nsFontFaceLoaderContext*> (aContext);
 
   nsIPresShell *ps = loaderCtx->mPresContext->PresShell();
   if (!ps)
     return NS_ERROR_FAILURE;
     
-  NS_ASSERTION(aFontURI, "null font uri");
-  if (!aFontURI)
+  NS_ASSERTION(aFontFaceSrc && !aFontFaceSrc->mIsLocal, 
+               "bad font face url passed to fontloader");
+  NS_ASSERTION(aFontFaceSrc->mURI, "null font uri");
+  if (!aFontFaceSrc->mURI)
     return NS_ERROR_FAILURE;
 
-  // xxx - need to detect system principal here
+  // use document principal, original principal if flag set
+  // this enables user stylesheets to load font files via
+  // @font-face rules
   nsCOMPtr<nsIPrincipal> principal = ps->GetDocument()->NodePrincipal();
 
-  rv = CheckLoadAllowed(principal, aFontURI, ps->GetDocument());
+  NS_ASSERTION(aFontFaceSrc->mOriginPrincipal, 
+               "null origin principal in @font-face rule");
+  if (aFontFaceSrc->mUseOriginPrincipal) {
+    principal = do_QueryInterface(aFontFaceSrc->mOriginPrincipal);
+  }
+  
+  rv = CheckLoadAllowed(principal, aFontFaceSrc->mURI, ps->GetDocument());
   if (NS_FAILED(rv)) {
-    nsCAutoString fontURI, referrerURI;
-    aFontURI->GetSpec(fontURI);
-    if (aReferrerURI)
-      aReferrerURI->GetSpec(referrerURI);
-    LOG(("fontdownloader download blocked - font uri: (%s) "
-         "referrer uri: (%s) err: %8.8x\n", 
-        fontURI.get(), referrerURI.get(), rv));
+#ifdef PR_LOGGING
+    if (LOG_ENABLED()) {
+      nsCAutoString fontURI, referrerURI;
+      aFontFaceSrc->mURI->GetSpec(fontURI);
+      if (aFontFaceSrc->mReferrer)
+        aFontFaceSrc->mReferrer->GetSpec(referrerURI);
+      LOG(("fontdownloader download blocked - font uri: (%s) "
+           "referrer uri: (%s) err: %8.8x\n", 
+          fontURI.get(), referrerURI.get(), rv));
+    }
+#endif    
     return rv;
   }
     
   nsRefPtr<nsFontFaceLoader> fontLoader = new nsFontFaceLoader(aFontToLoad, 
-                                                               aFontURI, 
+                                                               aFontFaceSrc->mURI, 
                                                                aContext);
   if (!fontLoader)
     return NS_ERROR_OUT_OF_MEMORY;
 
 #ifdef PR_LOGGING
   if (LOG_ENABLED()) {
     nsCAutoString fontURI, referrerURI;
-    aFontURI->GetSpec(fontURI);
-    if (aReferrerURI)
-      aReferrerURI->GetSpec(referrerURI);
+    aFontFaceSrc->mURI->GetSpec(fontURI);
+    if (aFontFaceSrc->mReferrer)
+      aFontFaceSrc->mReferrer->GetSpec(referrerURI);
     LOG(("fontdownloader (%p) download start - font uri: (%s) "
          "referrer uri: (%s)\n", 
          fontLoader.get(), fontURI.get(), referrerURI.get()));
   }
 #endif  
 
   nsCOMPtr<nsIStreamLoader> streamLoader;
   nsCOMPtr<nsILoadGroup> loadGroup(ps->GetDocument()->GetDocumentLoadGroup());
 
   nsCOMPtr<nsIChannel> channel;
   rv = NS_NewChannel(getter_AddRefs(channel),
-                     aFontURI,
+                     aFontFaceSrc->mURI,
                      nsnull,
                      loadGroup,
                      nsnull,
                      nsIRequest::LOAD_NORMAL);
                      
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(channel));
   if (httpChannel)
-    httpChannel->SetReferrer(aReferrerURI);
+    httpChannel->SetReferrer(aFontFaceSrc->mReferrer);
   rv = NS_NewStreamLoader(getter_AddRefs(streamLoader), fontLoader);
   NS_ENSURE_SUCCESS(rv, rv);
   
-  // unless data url, open with cross-site listener
-  PRBool isData = PR_FALSE;
-  if (NS_SUCCEEDED(aFontURI->SchemeIs("data", &isData)) && isData) {
+  PRBool inherits = PR_FALSE;
+  rv = NS_URIChainHasFlags(aFontFaceSrc->mURI,
+                           nsIProtocolHandler::URI_INHERITS_SECURITY_CONTEXT,
+                           &inherits);
+  if (NS_SUCCEEDED(rv) && inherits) {
+    // allow data, javascript, etc URI's
     rv = channel->AsyncOpen(streamLoader, nsnull);
   } else {
     nsCOMPtr<nsIStreamListener> listener =
       new nsCrossSiteListenerProxy(streamLoader, principal, channel, 
                                    PR_FALSE, &rv);
     NS_ENSURE_TRUE(listener, NS_ERROR_OUT_OF_MEMORY);
     NS_ENSURE_SUCCESS(rv, rv);
 
--- a/layout/style/nsFontFaceLoader.h
+++ b/layout/style/nsFontFaceLoader.h
@@ -62,18 +62,17 @@ public:
   NS_DECL_ISUPPORTS
   NS_DECL_NSISTREAMLOADEROBSERVER 
 
   // initiate the load
   nsresult Init();  
 
   // returns whether create succeeded or not
   static nsresult CreateHandler(gfxFontEntry *aFontToLoad, 
-                                nsIURI *aFontURI,
-                                nsIURI *aReferrerURI,
+                                const gfxFontFaceSrc *aFontFaceSrc,
                                 gfxUserFontSet::LoaderContext *aContext);
                               
 private:
 
   static nsresult CheckLoadAllowed(nsIPrincipal* aSourcePrincipal,
                                    nsIURI* aTargetURI,
                                    nsISupports* aContext);
   
--- a/layout/style/nsStyleSet.cpp
+++ b/layout/style/nsStyleSet.cpp
@@ -173,17 +173,18 @@ nsStyleSet::GatherRuleProcessors(sheetTy
         // levels containing CSS stylesheets
         nsCOMArray<nsIStyleSheet>& sheets = mSheets[aType];
         nsCOMArray<nsICSSStyleSheet> cssSheets(sheets.Count());
         for (PRInt32 i = 0, i_end = sheets.Count(); i < i_end; ++i) {
           nsCOMPtr<nsICSSStyleSheet> cssSheet = do_QueryInterface(sheets[i]);
           NS_ASSERTION(cssSheet, "not a CSS sheet");
           cssSheets.AppendObject(cssSheet);
         }
-        mRuleProcessors[aType] = new nsCSSRuleProcessor(cssSheets);
+        mRuleProcessors[aType] = new nsCSSRuleProcessor(cssSheets, 
+                                                        PRUint8(aType));
       } break;
 
       default:
         // levels containing non-CSS stylesheets
         NS_ASSERTION(mSheets[aType].Count() == 1, "only one sheet per level");
         mRuleProcessors[aType] = do_QueryInterface(mSheets[aType][0]);
         break;
     }
@@ -786,17 +787,17 @@ nsStyleSet::ProbePseudoStyleFor(nsIConte
     }
   }
   
   return result;
 }
 
 PRBool
 nsStyleSet::AppendFontFaceRules(nsPresContext* aPresContext,
-                                nsTArray< nsRefPtr<nsCSSFontFaceRule> >& aArray)
+                                nsTArray<nsFontFaceRuleContainer>& aArray)
 {
   NS_ENSURE_FALSE(mInShutdown, PR_FALSE);
 
   for (PRUint32 i = 0; i < NS_ARRAY_LENGTH(gCSSSheetTypes); ++i) {
     nsCSSRuleProcessor *ruleProc = static_cast<nsCSSRuleProcessor*>
                                     (mRuleProcessors[gCSSSheetTypes[i]].get());
     if (ruleProc && !ruleProc->AppendFontFaceRules(aPresContext, aArray))
       return PR_FALSE;
--- a/layout/style/nsStyleSet.h
+++ b/layout/style/nsStyleSet.h
@@ -113,17 +113,17 @@ class nsStyleSet
   already_AddRefed<nsStyleContext>
   ProbePseudoStyleFor(nsIContent* aParentContent,
                       nsIAtom* aPseudoTag,
                       nsStyleContext* aParentContext);
 
   // Append all the currently-active font face rules to aArray.  Return
   // true for success and false for failure.
   PRBool AppendFontFaceRules(nsPresContext* aPresContext,
-                             nsTArray< nsRefPtr<nsCSSFontFaceRule> >& aArray);
+                             nsTArray<nsFontFaceRuleContainer>& aArray);
 
   // Begin ignoring style context destruction, to avoid lots of unnecessary
   // work on document teardown.
   void BeginShutdown(nsPresContext* aPresContext);
 
   // Free all of the data associated with this style set.
   void Shutdown(nsPresContext* aPresContext);