diff --git a/caps/include/nsScriptSecurityManager.h b/caps/include/nsScriptSecurityManager.h index 70a531532829..b14a3a5fc688 100644 --- a/caps/include/nsScriptSecurityManager.h +++ b/caps/include/nsScriptSecurityManager.h @@ -67,6 +67,7 @@ class nsIStringBundle; class nsSystemPrincipal; struct ClassPolicy; class ClassInfoData; +class DomainPolicy; #if defined(DEBUG_mstoltz) || defined(DEBUG_caillon) #define DEBUG_CAPS_HACKER @@ -210,6 +211,10 @@ struct ClassPolicy : public PLDHashEntryHdr { char* key; PLDHashTable* mPolicy; + + // Note: the DomainPolicy owns us, so if if dies we will too. Hence no + // need to refcount it here (and in fact, we'd probably leak if we tried). + DomainPolicy* mDomainWeAreWildcardFor; }; PR_STATIC_CALLBACK(void) @@ -224,6 +229,13 @@ ClearClassPolicyEntry(PLDHashTable *table, PLDHashEntryHdr *entry) PL_DHashTableDestroy(cp->mPolicy); } +// Note: actual impl is going to be after the DomainPolicy class definition, +// since we need to access members of DomainPolicy in the impl +PR_STATIC_CALLBACK(void) +MoveClassPolicyEntry(PLDHashTable *table, + const PLDHashEntryHdr *from, + PLDHashEntryHdr *to); + PR_STATIC_CALLBACK(PRBool) InitClassPolicyEntry(PLDHashTable *table, PLDHashEntryHdr *entry, @@ -243,6 +255,7 @@ InitClassPolicyEntry(PLDHashTable *table, }; ClassPolicy* cp = (ClassPolicy*)entry; + cp->mDomainWeAreWildcardFor = nsnull; cp->key = PL_strdup((const char*)key); if (!cp->key) return PR_FALSE; @@ -281,7 +294,7 @@ public: PL_DHashGetKeyStub, PL_DHashStringKey, PL_DHashMatchStringKey, - PL_DHashMoveEntryStub, + MoveClassPolicyEntry, ClearClassPolicyEntry, PL_DHashFinalizeStub, InitClassPolicyEntry @@ -338,6 +351,23 @@ private: }; +PR_STATIC_CALLBACK(void) +MoveClassPolicyEntry(PLDHashTable *table, + const PLDHashEntryHdr *from, + PLDHashEntryHdr *to) +{ + memcpy(to, from, table->entrySize); + + // Now update the mDefaultPolicy pointer that points to us, if any. + ClassPolicy* cp = NS_STATIC_CAST(ClassPolicy*, to); + if (cp->mDomainWeAreWildcardFor) { + NS_ASSERTION(cp->mDomainWeAreWildcardFor->mWildcardPolicy == + NS_STATIC_CAST(const ClassPolicy*, from), + "Unexpected wildcard policy on mDomainWeAreWildcardFor"); + cp->mDomainWeAreWildcardFor->mWildcardPolicy = cp; + } +} + ///////////////////////////// // nsScriptSecurityManager // ///////////////////////////// diff --git a/caps/src/nsScriptSecurityManager.cpp b/caps/src/nsScriptSecurityManager.cpp index def38e8957d4..5c52383f4d10 100644 --- a/caps/src/nsScriptSecurityManager.cpp +++ b/caps/src/nsScriptSecurityManager.cpp @@ -3355,9 +3355,15 @@ nsScriptSecurityManager::InitDomainPolicy(JSContext* cx, // If this is the wildcard class (class '*'), save it in mWildcardPolicy // (we leave it stored in the hashtable too to take care of the cleanup) - if ((*start == '*') && (end == start + 1)) + if ((*start == '*') && (end == start + 1)) { aDomainPolicy->mWildcardPolicy = cpolicy; + // Make sure that cpolicy knows about aDomainPolicy so it can reset + // the mWildcardPolicy pointer as needed if it gets moved in the + // hashtable. + cpolicy->mDomainWeAreWildcardFor = aDomainPolicy; + } + // Get the property name start = end + 1; end = PL_strchr(start, '.');