From c3494a9ffb662205482f1446053896a8b18b63c5 Mon Sep 17 00:00:00 2001 From: "norris%netscape.com" Date: Sat, 2 Oct 1999 03:41:37 +0000 Subject: [PATCH] Fix the following bugs: 14443 "Same origin" security policy may be circumvented using docu 14820 Fixing up the relationship between nsCodeBasePrincipal and n 14919 Crash in JS MM code Reviewed by mstoltz, approved by scc. git-svn-id: svn://10.0.0.236/trunk@49647 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/caps/src/nsCodebasePrincipal.cpp | 28 +++++- mozilla/caps/src/nsJSPrincipals.cpp | 2 +- mozilla/caps/src/nsScriptSecurityManager.cpp | 13 ++- .../chrome/src/nsChromeProtocolHandler.cpp | 5 - mozilla/content/base/src/nsDocument.cpp | 16 ++++ .../html/document/src/nsHTMLDocument.cpp | 91 +++++++++++++++---- .../html/document/src/nsHTMLDocument.h | 2 + mozilla/dom/public/html/nsIDOMHTMLDocument.h | 3 + mozilla/dom/public/idl/html/HTMLDocument.idl | 2 +- mozilla/dom/public/nsDOMError.h | 5 +- .../dom/public/nsIScriptGlobalObjectData.h | 1 - mozilla/dom/src/base/domerr.msg | 4 + mozilla/dom/src/base/nsGlobalWindow.cpp | 49 ++-------- mozilla/dom/src/base/nsGlobalWindow.h | 2 - mozilla/dom/src/html/nsJSHTMLDocument.cpp | 16 +++- mozilla/js/src/jsobj.c | 19 ++-- mozilla/layout/base/src/nsDocument.cpp | 16 ++++ .../html/document/src/nsHTMLDocument.cpp | 91 +++++++++++++++---- .../layout/html/document/src/nsHTMLDocument.h | 2 + .../chrome/src/nsChromeProtocolHandler.cpp | 5 - .../resources/content/PrefsWindow.xul | 4 +- 21 files changed, 265 insertions(+), 111 deletions(-) diff --git a/mozilla/caps/src/nsCodebasePrincipal.cpp b/mozilla/caps/src/nsCodebasePrincipal.cpp index 4369674d6a0..23cca312760 100644 --- a/mozilla/caps/src/nsCodebasePrincipal.cpp +++ b/mozilla/caps/src/nsCodebasePrincipal.cpp @@ -26,7 +26,33 @@ static NS_DEFINE_IID(kICodebasePrincipalIID, NS_ICODEBASEPRINCIPAL_IID); -NS_IMPL_ISUPPORTS(nsCodebasePrincipal, kICodebasePrincipalIID); +NS_IMPL_QUERY_INTERFACE2(nsCodebasePrincipal, nsICodebasePrincipal, nsIPrincipal) + +// special AddRef/Release to unify reference counts between XPCOM +// and JSPrincipals + +NS_IMETHODIMP_(nsrefcnt) +nsCodebasePrincipal::AddRef(void) +{ + NS_PRECONDITION(PRInt32(mJSPrincipals.refcount) >= 0, "illegal refcnt"); + ++mJSPrincipals.refcount; + NS_LOG_ADDREF(this, mJSPrincipals.refcount, __FILE__, __LINE__); + return mJSPrincipals.refcount; +} + +NS_IMETHODIMP_(nsrefcnt) +nsCodebasePrincipal::Release(void) +{ + NS_PRECONDITION(0 != mJSPrincipals.refcount, "dup release"); + --mJSPrincipals.refcount; + NS_LOG_RELEASE(this, mJSPrincipals.refcount, __FILE__, __LINE__); + if (mJSPrincipals.refcount == 0) { + NS_DELETEXPCOM(this); + return 0; + } + return mJSPrincipals.refcount; +} + //////////////////////////////////// // Methods implementing nsIPrincipal diff --git a/mozilla/caps/src/nsJSPrincipals.cpp b/mozilla/caps/src/nsJSPrincipals.cpp index b683ef2605b..5f99b7cb8d9 100644 --- a/mozilla/caps/src/nsJSPrincipals.cpp +++ b/mozilla/caps/src/nsJSPrincipals.cpp @@ -40,7 +40,7 @@ nsDestroyJSPrincipals(JSContext *cx, struct JSPrincipals *jsprin) { // so we don't need to worry about "codebase" } -nsJSPrincipals::nsJSPrincipals() +nsJSPrincipals::nsJSPrincipals() { codebase = nsnull; getPrincipalArray = nsGetPrincipalArray; diff --git a/mozilla/caps/src/nsScriptSecurityManager.cpp b/mozilla/caps/src/nsScriptSecurityManager.cpp index 059f212bd94..7d5bec3df2b 100644 --- a/mozilla/caps/src/nsScriptSecurityManager.cpp +++ b/mozilla/caps/src/nsScriptSecurityManager.cpp @@ -32,6 +32,7 @@ #include "nsCRT.h" #include "nsXPIDLString.h" #include "nsIJSContextStack.h" +#include "nsDOMError.h" static NS_DEFINE_CID(kPrefServiceCID, NS_PREF_CID); static NS_DEFINE_CID(kURLCID, NS_STANDARDURL_CID); @@ -39,9 +40,6 @@ static NS_DEFINE_CID(kComponentManagerCID, NS_COMPONENTMANAGER_CID); static NS_DEFINE_IID(kIScriptSecurityManagerIID, NS_ISCRIPTSECURITYMANAGER_IID); static NS_DEFINE_IID(kIXPCSecurityManagerIID, NS_IXPCSECURITYMANAGER_IID); -static const char accessErrorMessage[] = - "access disallowed from scripts at %s to documents at another domain"; - enum { SCRIPT_SECURITY_SAME_DOMAIN_ACCESS, SCRIPT_SECURITY_ALL_ACCESS, @@ -181,6 +179,7 @@ nsScriptSecurityManager::CheckURI(nsIScriptContext *aContext, if (NS_FAILED(aURI->GetSpec(getter_Copies(spec)))) return NS_ERROR_FAILURE; JS_ReportError(cx, "illegal URL method '%s'", (const char *)spec); + return NS_ERROR_DOM_BAD_URI; } return NS_OK; } @@ -497,7 +496,6 @@ nsScriptSecurityManager::GetObjectPrincipal(JSContext *aCx, JSObject *aObj, if (NS_FAILED(globalData->GetPrincipal(result))) { return NS_ERROR_FAILURE; } - NS_ADDREF(*result); return NS_OK; } @@ -563,10 +561,11 @@ nsScriptSecurityManager::CheckPermissions(JSContext *aCx, JSObject *aObj, char *spec; if (NS_FAILED(uri->GetSpec(&spec))) return NS_ERROR_FAILURE; - JS_ReportError(aCx, accessErrorMessage, spec); + JS_ReportError(aCx, "access disallowed from scripts at %s to documents " + "at another domain", spec); nsCRT::free(spec); *aResult = PR_FALSE; - return NS_OK; + return NS_ERROR_DOM_PROP_ACCESS_DENIED; } @@ -660,7 +659,7 @@ nsScriptSecurityManager::CheckXPCPermissions(JSContext *aJSContext) return NS_ERROR_FAILURE; if (!ok) { JS_ReportError(aJSContext, "Access denied to XPConnect service."); - return NS_ERROR_FAILURE; + return NS_ERROR_DOM_XPCONNECT_ACCESS_DENIED; } return NS_OK; } diff --git a/mozilla/chrome/src/nsChromeProtocolHandler.cpp b/mozilla/chrome/src/nsChromeProtocolHandler.cpp index 1b83eab6efc..befb0cc2e1f 100644 --- a/mozilla/chrome/src/nsChromeProtocolHandler.cpp +++ b/mozilla/chrome/src/nsChromeProtocolHandler.cpp @@ -190,11 +190,6 @@ nsChromeProtocolHandler::NewChannel(const char* verb, nsIURI* uri, } nsCOMPtr owner = do_QueryInterface(principal); (*result)->SetOwner(owner); -#ifdef DEBUG_norris - nsXPIDLCString spec; - uri->GetSpec(getter_Copies(spec)); - fprintf(stderr, "System principal created for %s\n", (const char *)spec); -#endif } NS_RELEASE(chromeURI); diff --git a/mozilla/content/base/src/nsDocument.cpp b/mozilla/content/base/src/nsDocument.cpp index 5bf35f93826..2369ec39652 100644 --- a/mozilla/content/base/src/nsDocument.cpp +++ b/mozilla/content/base/src/nsDocument.cpp @@ -78,6 +78,8 @@ #include "nsIEnumerator.h" #include "nsDOMError.h" +#include "nsIScriptSecurityManager.h" + static NS_DEFINE_IID(kIDOMTextIID, NS_IDOMTEXT_IID); static NS_DEFINE_IID(kIDOMCommentIID, NS_IDOMCOMMENT_IID); static NS_DEFINE_IID(kIDocumentIID, NS_IDOCUMENT_IID); @@ -674,6 +676,7 @@ nsDocument::~nsDocument() mDocumentTitle = nsnull; } NS_IF_RELEASE(mDocumentURL); + NS_IF_RELEASE(mPrincipal); mDocumentLoadGroup = null_nsCOMPtr(); mParentDocument = nsnull; @@ -841,6 +844,7 @@ nsDocument::Reset(nsIURI *aURL) mDocumentTitle = nsnull; } NS_IF_RELEASE(mDocumentURL); + NS_IF_RELEASE(mPrincipal); mDocumentLoadGroup = null_nsCOMPtr(); // Delete references to sub-documents @@ -933,6 +937,18 @@ nsIURI* nsDocument::GetDocumentURL() const nsIPrincipal* nsDocument::GetDocumentPrincipal() const { + if (!mPrincipal) { + nsresult rv; + NS_WITH_SERVICE(nsIScriptSecurityManager, securityManager, + NS_SCRIPTSECURITYMANAGER_PROGID, &rv); + if (NS_FAILED(rv)) + return nsnull; + nsIPrincipal *p; + if (NS_FAILED(securityManager->CreateCodebasePrincipal(mDocumentURL, &p))) + return nsnull; + // XXX cast away const: should change type of member function + ((nsDocument *) this)->mPrincipal = p; + } NS_IF_ADDREF(mPrincipal); return mPrincipal; } diff --git a/mozilla/content/html/document/src/nsHTMLDocument.cpp b/mozilla/content/html/document/src/nsHTMLDocument.cpp index 941abd30c4c..41704a65a4f 100644 --- a/mozilla/content/html/document/src/nsHTMLDocument.cpp +++ b/mozilla/content/html/document/src/nsHTMLDocument.cpp @@ -58,6 +58,8 @@ #include "nsIScriptGlobalObject.h" #include "nsContentList.h" #include "nsDOMError.h" +#include "nsICodebasePrincipal.h" +#include "nsIScriptSecurityManager.h" #ifndef NECKO #include "nsINetService.h" @@ -1335,29 +1337,84 @@ nsHTMLDocument::GetReferrer(nsString& aReferrer) return NS_OK; } +NS_IMETHODIMP +nsHTMLDocument::GetDomainURI(nsIURI **uri) +{ + nsCOMPtr principal = GetDocumentPrincipal(); + if (!principal) + return NS_ERROR_FAILURE; + nsCOMPtr codebase = do_QueryInterface(principal); + if (!codebase) + return NS_ERROR_FAILURE; + return codebase->GetURI(uri); +} + + NS_IMETHODIMP nsHTMLDocument::GetDomain(nsString& aDomain) { - //XXX TBI - // PCB: This is the domain name of the server that produced this document. Can we just - // extract it from the URL? What about proxy servers, etc.? - if (nsnull != mDocumentURL) { -#ifdef NECKO - char* hostName; -#else - const char* hostName; -#endif - mDocumentURL->GetHost(&hostName); - aDomain.SetString(hostName); -#ifdef NECKO - nsCRT::free(hostName); -#endif - } else { - aDomain.SetLength(0); - } + nsCOMPtr uri; + if (NS_FAILED(GetDomainURI(getter_AddRefs(uri)))) + return NS_ERROR_FAILURE; + + char *hostName; + if (NS_FAILED(uri->GetHost(&hostName))) + return NS_ERROR_FAILURE; + aDomain.SetString(hostName); + nsCRT::free(hostName); + return NS_OK; } +NS_IMETHODIMP +nsHTMLDocument::SetDomain(const nsString& aDomain) +{ + // Check new domain + nsAutoString current; + if (NS_FAILED(GetDomain(current))) + return NS_ERROR_FAILURE; + PRBool ok = PR_FALSE; + if (current.Equals(aDomain)) { + ok = PR_TRUE; + } else if (aDomain.Length() < current.Length()) { + nsAutoString suffix; + current.Right(suffix, aDomain.Length()); + PRUnichar c = current.CharAt(current.Length() - aDomain.Length() - 1); + if (aDomain.EqualsIgnoreCase(suffix) && (c == '.' || c == '/')) + ok = PR_TRUE; + } + if (!ok) { + // Error: illegal domain + return NS_ERROR_DOM_BAD_DOCUMENT_DOMAIN; + } + + // Create new URI + nsCOMPtr uri; + if (NS_FAILED(GetDomainURI(getter_AddRefs(uri)))) + return NS_ERROR_FAILURE; + nsXPIDLCString scheme; + if (NS_FAILED(uri->GetScheme(getter_Copies(scheme)))) + return NS_ERROR_FAILURE; + nsXPIDLCString path; + if (NS_FAILED(uri->GetPath(getter_Copies(path)))) + return NS_ERROR_FAILURE; + nsAutoString newURIString = (const char *)scheme; + newURIString += "://"; + newURIString += aDomain; + newURIString += path; + nsIURI *newURI; + if (NS_FAILED(NS_NewURI(&newURI, newURIString))) + return NS_ERROR_FAILURE; + + // Create new codebase principal + nsresult rv; + NS_WITH_SERVICE(nsIScriptSecurityManager, securityManager, + NS_SCRIPTSECURITYMANAGER_PROGID, &rv); + if (NS_FAILED(rv)) + return NS_ERROR_FAILURE; + return securityManager->CreateCodebasePrincipal(newURI, &mPrincipal); +} + NS_IMETHODIMP nsHTMLDocument::GetURL(nsString& aURL) { diff --git a/mozilla/content/html/document/src/nsHTMLDocument.h b/mozilla/content/html/document/src/nsHTMLDocument.h index 7cf89831e18..bb29d723ba7 100644 --- a/mozilla/content/html/document/src/nsHTMLDocument.h +++ b/mozilla/content/html/document/src/nsHTMLDocument.h @@ -193,6 +193,8 @@ protected: PRBool GetBodyContent(); nsresult GetBodyElement(nsIDOMHTMLBodyElement** aBody); + NS_IMETHOD GetDomainURI(nsIURI **uri); + #ifdef NECKO virtual nsresult Reset(nsIChannel* aChannel, nsILoadGroup* aLoadGroup); #else diff --git a/mozilla/dom/public/html/nsIDOMHTMLDocument.h b/mozilla/dom/public/html/nsIDOMHTMLDocument.h index e1c54b170e7..49b4cdf5330 100644 --- a/mozilla/dom/public/html/nsIDOMHTMLDocument.h +++ b/mozilla/dom/public/html/nsIDOMHTMLDocument.h @@ -44,6 +44,7 @@ public: NS_IMETHOD GetReferrer(nsString& aReferrer)=0; NS_IMETHOD GetDomain(nsString& aDomain)=0; + NS_IMETHOD SetDomain(const nsString& aDomain)=0; NS_IMETHOD GetURL(nsString& aURL)=0; @@ -82,6 +83,7 @@ public: NS_IMETHOD SetTitle(const nsString& aTitle); \ NS_IMETHOD GetReferrer(nsString& aReferrer); \ NS_IMETHOD GetDomain(nsString& aDomain); \ + NS_IMETHOD SetDomain(const nsString& aDomain); \ NS_IMETHOD GetURL(nsString& aURL); \ NS_IMETHOD GetBody(nsIDOMHTMLElement** aBody); \ NS_IMETHOD SetBody(nsIDOMHTMLElement* aBody); \ @@ -106,6 +108,7 @@ public: NS_IMETHOD SetTitle(const nsString& aTitle) { return _to SetTitle(aTitle); } \ NS_IMETHOD GetReferrer(nsString& aReferrer) { return _to GetReferrer(aReferrer); } \ NS_IMETHOD GetDomain(nsString& aDomain) { return _to GetDomain(aDomain); } \ + NS_IMETHOD SetDomain(const nsString& aDomain) { return _to SetDomain(aDomain); } \ NS_IMETHOD GetURL(nsString& aURL) { return _to GetURL(aURL); } \ NS_IMETHOD GetBody(nsIDOMHTMLElement** aBody) { return _to GetBody(aBody); } \ NS_IMETHOD SetBody(nsIDOMHTMLElement* aBody) { return _to SetBody(aBody); } \ diff --git a/mozilla/dom/public/idl/html/HTMLDocument.idl b/mozilla/dom/public/idl/html/HTMLDocument.idl index 08d752eaa30..4509c7a40d9 100644 --- a/mozilla/dom/public/idl/html/HTMLDocument.idl +++ b/mozilla/dom/public/idl/html/HTMLDocument.idl @@ -4,7 +4,7 @@ attribute DOMString title; readonly attribute DOMString referrer; - readonly attribute DOMString domain; + attribute DOMString domain; readonly attribute DOMString URL; attribute HTMLElement body; readonly attribute HTMLCollection images; diff --git a/mozilla/dom/public/nsDOMError.h b/mozilla/dom/public/nsDOMError.h index 67b361f6588..38fb16ea044 100644 --- a/mozilla/dom/public/nsDOMError.h +++ b/mozilla/dom/public/nsDOMError.h @@ -45,7 +45,10 @@ #define NS_ERROR_DOM_NOT_BOOLEAN_ERR NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_DOM,1006) #define NS_ERROR_DOM_NOT_FUNCTION_ERR NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_DOM,1007) #define NS_ERROR_DOM_TOO_FEW_PARAMETERS_ERR NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_DOM,1008) - +#define NS_ERROR_DOM_BAD_DOCUMENT_DOMAIN NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_DOM,1009) +#define NS_ERROR_DOM_PROP_ACCESS_DENIED NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_DOM,1010) +#define NS_ERROR_DOM_XPCONNECT_ACCESS_DENIED NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_DOM,1011) +#define NS_ERROR_DOM_BAD_URI NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_DOM,1012) // XXX Not the right place for this. #include "nsIDOMDOMException.h" diff --git a/mozilla/dom/public/nsIScriptGlobalObjectData.h b/mozilla/dom/public/nsIScriptGlobalObjectData.h index 7cf5f92af37..2572231a860 100644 --- a/mozilla/dom/public/nsIScriptGlobalObjectData.h +++ b/mozilla/dom/public/nsIScriptGlobalObjectData.h @@ -36,7 +36,6 @@ public: NS_DEFINE_STATIC_IID_ACCESSOR(NS_ISCRIPTGLOBALOBJECTDATA_IID) NS_IMETHOD GetPrincipal(nsIPrincipal **aPrincipal) = 0; - NS_IMETHOD SetPrincipal(nsIPrincipal *aPrincipal) = 0; }; #endif //nsIScriptGlobalObjectData_h__ diff --git a/mozilla/dom/src/base/domerr.msg b/mozilla/dom/src/base/domerr.msg index 4bab383377f..e5f6b4d4314 100644 --- a/mozilla/dom/src/base/domerr.msg +++ b/mozilla/dom/src/base/domerr.msg @@ -44,6 +44,10 @@ DOM_MSG_DEF(NS_ERROR_DOM_NOT_NUMBER_ERR, "Parameter is not a number") DOM_MSG_DEF(NS_ERROR_DOM_NOT_BOOLEAN_ERR, "Parameter is not a boolean") DOM_MSG_DEF(NS_ERROR_DOM_NOT_FUNCTION_ERR, "Parameter is not a Function") DOM_MSG_DEF(NS_ERROR_DOM_TOO_FEW_PARAMETERS_ERR, "Too few parameters to method") +DOM_MSG_DEF(NS_ERROR_DOM_BAD_DOCUMENT_DOMAIN, "Illegal document.domain value") +DOM_MSG_DEF(NS_ERROR_DOM_PROP_ACCESS_DENIED, "Access to property denied") +DOM_MSG_DEF(NS_ERROR_DOM_XPCONNECT_ACCESS_DENIED, "Access to XPConnect service denied") +DOM_MSG_DEF(NS_ERROR_DOM_BAD_URI, "Access to restricted URI denied") /* common global codes (from nsError.h) */ diff --git a/mozilla/dom/src/base/nsGlobalWindow.cpp b/mozilla/dom/src/base/nsGlobalWindow.cpp index b3e2cf1afde..06a15df2478 100644 --- a/mozilla/dom/src/base/nsGlobalWindow.cpp +++ b/mozilla/dom/src/base/nsGlobalWindow.cpp @@ -120,7 +120,6 @@ GlobalWindowImpl::GlobalWindowImpl() mLocation = nsnull; mFrames = nsnull; mOpener = nsnull; - mPrincipal = nsnull; mTimeouts = nsnull; mTimeoutInsertionPoint = nsnull; @@ -149,7 +148,6 @@ GlobalWindowImpl::~GlobalWindowImpl() NS_IF_RELEASE(mLocation); NS_IF_RELEASE(mFrames); NS_IF_RELEASE(mOpener); - NS_IF_RELEASE(mPrincipal); NS_IF_RELEASE(mListenerManager); } @@ -293,11 +291,6 @@ GlobalWindowImpl::SetNewDocument(nsIDOMDocument *aDocument) } //XXX Should this be outside the about:blank clearscope exception? - if (nsnull != mPrincipal) - { - NS_RELEASE(mPrincipal); - } - if (nsnull != mDocument) { NS_RELEASE(mDocument); } @@ -2915,41 +2908,15 @@ GlobalWindowImpl::DisableExternalCapture() NS_IMETHODIMP GlobalWindowImpl::GetPrincipal(nsIPrincipal **result) { - if (!mPrincipal) { - nsCOMPtr doc; - if (!mDocument || NS_FAILED(mDocument->QueryInterface(kIDocumentIID, - (void **) getter_AddRefs(doc)))) - { - return NS_ERROR_FAILURE; - } - - mPrincipal = doc->GetDocumentPrincipal(); - if (!mPrincipal) { - nsCOMPtr uri = dont_AddRef(doc->GetDocumentURL()); - if (!uri) - return NS_ERROR_FAILURE; - - nsresult rv; - NS_WITH_SERVICE(nsIScriptSecurityManager, securityManager, - NS_SCRIPTSECURITYMANAGER_PROGID, &rv); - if (NS_FAILED(rv)) - return NS_ERROR_FAILURE; - if (NS_FAILED(securityManager->CreateCodebasePrincipal(uri, &mPrincipal))) - return NS_ERROR_FAILURE; - } + nsCOMPtr doc; + if (!mDocument || NS_FAILED(mDocument->QueryInterface(kIDocumentIID, + (void **) getter_AddRefs(doc)))) + { + return NS_ERROR_FAILURE; } - *result = mPrincipal; - NS_ADDREF(*result); - return NS_OK; -} - -NS_IMETHODIMP -GlobalWindowImpl::SetPrincipal(nsIPrincipal *aPrin) -{ - NS_IF_RELEASE(mPrincipal); - mPrincipal = aPrin; - if (mPrincipal) - NS_ADDREF(mPrincipal); + *result = doc->GetDocumentPrincipal(); + if (!*result) + return NS_ERROR_FAILURE; return NS_OK; } diff --git a/mozilla/dom/src/base/nsGlobalWindow.h b/mozilla/dom/src/base/nsGlobalWindow.h index 357b79aebf9..e51aacada5b 100644 --- a/mozilla/dom/src/base/nsGlobalWindow.h +++ b/mozilla/dom/src/base/nsGlobalWindow.h @@ -212,7 +212,6 @@ public: // nsIScriptGlobalObjectData interface NS_IMETHOD GetPrincipal(nsIPrincipal **prin); - NS_IMETHOD SetPrincipal(nsIPrincipal *prin); friend void nsGlobalWindow_RunTimeout(nsITimer *aTimer, void *aClosure); @@ -254,7 +253,6 @@ protected: HistoryImpl *mHistory; nsIWebShell *mWebShell; nsIDOMWindow *mOpener; - nsIPrincipal *mPrincipal; BarPropImpl *mMenubar; BarPropImpl *mToolbar; diff --git a/mozilla/dom/src/html/nsJSHTMLDocument.cpp b/mozilla/dom/src/html/nsJSHTMLDocument.cpp index c923dce49ca..8aa7158ee25 100644 --- a/mozilla/dom/src/html/nsJSHTMLDocument.cpp +++ b/mozilla/dom/src/html/nsJSHTMLDocument.cpp @@ -631,6 +631,20 @@ SetHTMLDocumentProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp) break; } + case HTMLDOCUMENT_DOMAIN: + { + PRBool ok = PR_FALSE; + secMan->CheckScriptAccess(scriptCX, obj, "htmldocument.domain", PR_TRUE, &ok); + if (!ok) { + return nsJSUtils::nsReportError(cx, NS_ERROR_DOM_SECURITY_ERR); + } + nsAutoString prop; + nsJSUtils::nsConvertJSValToString(prop, cx, *vp); + + a->SetDomain(prop); + + break; + } case HTMLDOCUMENT_BODY: { PRBool ok = PR_FALSE; @@ -1403,7 +1417,7 @@ static JSPropertySpec HTMLDocumentProperties[] = { {"title", HTMLDOCUMENT_TITLE, JSPROP_ENUMERATE}, {"referrer", HTMLDOCUMENT_REFERRER, JSPROP_ENUMERATE | JSPROP_READONLY}, - {"domain", HTMLDOCUMENT_DOMAIN, JSPROP_ENUMERATE | JSPROP_READONLY}, + {"domain", HTMLDOCUMENT_DOMAIN, JSPROP_ENUMERATE}, {"URL", HTMLDOCUMENT_URL, JSPROP_ENUMERATE | JSPROP_READONLY}, {"body", HTMLDOCUMENT_BODY, JSPROP_ENUMERATE}, {"images", HTMLDOCUMENT_IMAGES, JSPROP_ENUMERATE | JSPROP_READONLY}, diff --git a/mozilla/js/src/jsobj.c b/mozilla/js/src/jsobj.c index 9f23cf7caef..87ac06e3c7d 100644 --- a/mozilla/js/src/jsobj.c +++ b/mozilla/js/src/jsobj.c @@ -116,7 +116,8 @@ obj_getCount(JSContext *cx, JSObject *obj, jsval id, jsval *vp); static JSPropertySpec object_props[] = { /* These two must come first; see object_props[slot].name usage below. */ {js_proto_str, JSSLOT_PROTO, JSPROP_PERMANENT, obj_getSlot, obj_setSlot}, - {js_parent_str,JSSLOT_PARENT, JSPROP_PERMANENT, obj_getSlot, obj_setSlot}, + {js_parent_str,JSSLOT_PARENT, JSPROP_PERMANENT|JSPROP_READONLY, + obj_getSlot, obj_setSlot}, {js_count_str, 0, JSPROP_PERMANENT, obj_getCount, obj_getCount}, {0} }; @@ -2776,16 +2777,16 @@ void printString(JSString *str) { fputc('\n', stderr); } -void printVal(jsval val); +void printVal(JSContext *cx, jsval val); static -void printObj(JSObject *jsobj) { +void printObj(JSContext *cx, JSObject *jsobj) { jsuint i; jsval val; JSClass *clasp; fprintf(stderr, "object 0x%p\n", jsobj); - clasp = OBJ_GET_CLASS(NULL, jsobj); + clasp = OBJ_GET_CLASS(cx, jsobj); fprintf(stderr, "class 0x%p %s\n", clasp, clasp->name); for (i=0; i < jsobj->map->nslots; i++) { fprintf(stderr, "slot %3d ", i); @@ -2793,18 +2794,18 @@ void printObj(JSObject *jsobj) { if (JSVAL_IS_OBJECT(val)) fprintf(stderr, "object 0x%p\n", JSVAL_TO_OBJECT(val)); else - printVal(val); + printVal(cx, val); } } -void printVal(jsval val) { +void printVal(JSContext *cx, jsval val) { fprintf(stderr, "val %d (0x%p) = ", (int)val, (void *)val); if (JSVAL_IS_NULL(val)) { fprintf(stderr, "null\n"); } else if (JSVAL_IS_VOID(val)) { fprintf(stderr, "undefined\n"); } else if (JSVAL_IS_OBJECT(val)) { - printObj(JSVAL_TO_OBJECT(val)); + printObj(cx, JSVAL_TO_OBJECT(val)); } else if (JSVAL_IS_INT(val)) { fprintf(stderr, "(int) %d\n", JSVAL_TO_INT(val)); } else if (JSVAL_IS_STRING(val)) { @@ -2820,9 +2821,9 @@ void printVal(jsval val) { } static -void printId(jsid id) { +void printId(JSContext *cx, jsid id) { fprintf(stderr, "id %d (0x%p) is ", (int)id, (void *)id); - printVal(js_IdToValue(id)); + printVal(cx, js_IdToValue(id)); } static diff --git a/mozilla/layout/base/src/nsDocument.cpp b/mozilla/layout/base/src/nsDocument.cpp index 5bf35f93826..2369ec39652 100644 --- a/mozilla/layout/base/src/nsDocument.cpp +++ b/mozilla/layout/base/src/nsDocument.cpp @@ -78,6 +78,8 @@ #include "nsIEnumerator.h" #include "nsDOMError.h" +#include "nsIScriptSecurityManager.h" + static NS_DEFINE_IID(kIDOMTextIID, NS_IDOMTEXT_IID); static NS_DEFINE_IID(kIDOMCommentIID, NS_IDOMCOMMENT_IID); static NS_DEFINE_IID(kIDocumentIID, NS_IDOCUMENT_IID); @@ -674,6 +676,7 @@ nsDocument::~nsDocument() mDocumentTitle = nsnull; } NS_IF_RELEASE(mDocumentURL); + NS_IF_RELEASE(mPrincipal); mDocumentLoadGroup = null_nsCOMPtr(); mParentDocument = nsnull; @@ -841,6 +844,7 @@ nsDocument::Reset(nsIURI *aURL) mDocumentTitle = nsnull; } NS_IF_RELEASE(mDocumentURL); + NS_IF_RELEASE(mPrincipal); mDocumentLoadGroup = null_nsCOMPtr(); // Delete references to sub-documents @@ -933,6 +937,18 @@ nsIURI* nsDocument::GetDocumentURL() const nsIPrincipal* nsDocument::GetDocumentPrincipal() const { + if (!mPrincipal) { + nsresult rv; + NS_WITH_SERVICE(nsIScriptSecurityManager, securityManager, + NS_SCRIPTSECURITYMANAGER_PROGID, &rv); + if (NS_FAILED(rv)) + return nsnull; + nsIPrincipal *p; + if (NS_FAILED(securityManager->CreateCodebasePrincipal(mDocumentURL, &p))) + return nsnull; + // XXX cast away const: should change type of member function + ((nsDocument *) this)->mPrincipal = p; + } NS_IF_ADDREF(mPrincipal); return mPrincipal; } diff --git a/mozilla/layout/html/document/src/nsHTMLDocument.cpp b/mozilla/layout/html/document/src/nsHTMLDocument.cpp index 941abd30c4c..41704a65a4f 100644 --- a/mozilla/layout/html/document/src/nsHTMLDocument.cpp +++ b/mozilla/layout/html/document/src/nsHTMLDocument.cpp @@ -58,6 +58,8 @@ #include "nsIScriptGlobalObject.h" #include "nsContentList.h" #include "nsDOMError.h" +#include "nsICodebasePrincipal.h" +#include "nsIScriptSecurityManager.h" #ifndef NECKO #include "nsINetService.h" @@ -1335,29 +1337,84 @@ nsHTMLDocument::GetReferrer(nsString& aReferrer) return NS_OK; } +NS_IMETHODIMP +nsHTMLDocument::GetDomainURI(nsIURI **uri) +{ + nsCOMPtr principal = GetDocumentPrincipal(); + if (!principal) + return NS_ERROR_FAILURE; + nsCOMPtr codebase = do_QueryInterface(principal); + if (!codebase) + return NS_ERROR_FAILURE; + return codebase->GetURI(uri); +} + + NS_IMETHODIMP nsHTMLDocument::GetDomain(nsString& aDomain) { - //XXX TBI - // PCB: This is the domain name of the server that produced this document. Can we just - // extract it from the URL? What about proxy servers, etc.? - if (nsnull != mDocumentURL) { -#ifdef NECKO - char* hostName; -#else - const char* hostName; -#endif - mDocumentURL->GetHost(&hostName); - aDomain.SetString(hostName); -#ifdef NECKO - nsCRT::free(hostName); -#endif - } else { - aDomain.SetLength(0); - } + nsCOMPtr uri; + if (NS_FAILED(GetDomainURI(getter_AddRefs(uri)))) + return NS_ERROR_FAILURE; + + char *hostName; + if (NS_FAILED(uri->GetHost(&hostName))) + return NS_ERROR_FAILURE; + aDomain.SetString(hostName); + nsCRT::free(hostName); + return NS_OK; } +NS_IMETHODIMP +nsHTMLDocument::SetDomain(const nsString& aDomain) +{ + // Check new domain + nsAutoString current; + if (NS_FAILED(GetDomain(current))) + return NS_ERROR_FAILURE; + PRBool ok = PR_FALSE; + if (current.Equals(aDomain)) { + ok = PR_TRUE; + } else if (aDomain.Length() < current.Length()) { + nsAutoString suffix; + current.Right(suffix, aDomain.Length()); + PRUnichar c = current.CharAt(current.Length() - aDomain.Length() - 1); + if (aDomain.EqualsIgnoreCase(suffix) && (c == '.' || c == '/')) + ok = PR_TRUE; + } + if (!ok) { + // Error: illegal domain + return NS_ERROR_DOM_BAD_DOCUMENT_DOMAIN; + } + + // Create new URI + nsCOMPtr uri; + if (NS_FAILED(GetDomainURI(getter_AddRefs(uri)))) + return NS_ERROR_FAILURE; + nsXPIDLCString scheme; + if (NS_FAILED(uri->GetScheme(getter_Copies(scheme)))) + return NS_ERROR_FAILURE; + nsXPIDLCString path; + if (NS_FAILED(uri->GetPath(getter_Copies(path)))) + return NS_ERROR_FAILURE; + nsAutoString newURIString = (const char *)scheme; + newURIString += "://"; + newURIString += aDomain; + newURIString += path; + nsIURI *newURI; + if (NS_FAILED(NS_NewURI(&newURI, newURIString))) + return NS_ERROR_FAILURE; + + // Create new codebase principal + nsresult rv; + NS_WITH_SERVICE(nsIScriptSecurityManager, securityManager, + NS_SCRIPTSECURITYMANAGER_PROGID, &rv); + if (NS_FAILED(rv)) + return NS_ERROR_FAILURE; + return securityManager->CreateCodebasePrincipal(newURI, &mPrincipal); +} + NS_IMETHODIMP nsHTMLDocument::GetURL(nsString& aURL) { diff --git a/mozilla/layout/html/document/src/nsHTMLDocument.h b/mozilla/layout/html/document/src/nsHTMLDocument.h index 7cf89831e18..bb29d723ba7 100644 --- a/mozilla/layout/html/document/src/nsHTMLDocument.h +++ b/mozilla/layout/html/document/src/nsHTMLDocument.h @@ -193,6 +193,8 @@ protected: PRBool GetBodyContent(); nsresult GetBodyElement(nsIDOMHTMLBodyElement** aBody); + NS_IMETHOD GetDomainURI(nsIURI **uri); + #ifdef NECKO virtual nsresult Reset(nsIChannel* aChannel, nsILoadGroup* aLoadGroup); #else diff --git a/mozilla/rdf/chrome/src/nsChromeProtocolHandler.cpp b/mozilla/rdf/chrome/src/nsChromeProtocolHandler.cpp index 1b83eab6efc..befb0cc2e1f 100644 --- a/mozilla/rdf/chrome/src/nsChromeProtocolHandler.cpp +++ b/mozilla/rdf/chrome/src/nsChromeProtocolHandler.cpp @@ -190,11 +190,6 @@ nsChromeProtocolHandler::NewChannel(const char* verb, nsIURI* uri, } nsCOMPtr owner = do_QueryInterface(principal); (*result)->SetOwner(owner); -#ifdef DEBUG_norris - nsXPIDLCString spec; - uri->GetSpec(getter_Copies(spec)); - fprintf(stderr, "System principal created for %s\n", (const char *)spec); -#endif } NS_RELEASE(chromeURI); diff --git a/mozilla/xpfe/components/prefwindow/resources/content/PrefsWindow.xul b/mozilla/xpfe/components/prefwindow/resources/content/PrefsWindow.xul index c50492aeefa..6592fd2caff 100644 --- a/mozilla/xpfe/components/prefwindow/resources/content/PrefsWindow.xul +++ b/mozilla/xpfe/components/prefwindow/resources/content/PrefsWindow.xul @@ -32,9 +32,9 @@ &categoryHeader; - + + src="chrome://pref/content/pref-appearance.xul" width="72%" height="356" resize="yes" scrolling="auto"/>