зеркало из https://github.com/mozilla/pjs.git
Bug 641706: Make SpecialPowers able to create a XHR object with full system powers. r=smaug
This commit is contained in:
Родитель
ef31f6cfa2
Коммит
9a77da1530
|
@ -126,19 +126,16 @@
|
||||||
#define XML_HTTP_REQUEST_ABORTED (1 << 7) // Internal
|
#define XML_HTTP_REQUEST_ABORTED (1 << 7) // Internal
|
||||||
#define XML_HTTP_REQUEST_ASYNC (1 << 8) // Internal
|
#define XML_HTTP_REQUEST_ASYNC (1 << 8) // Internal
|
||||||
#define XML_HTTP_REQUEST_PARSEBODY (1 << 9) // Internal
|
#define XML_HTTP_REQUEST_PARSEBODY (1 << 9) // Internal
|
||||||
#define XML_HTTP_REQUEST_XSITEENABLED (1 << 10) // Internal, Is any cross-site request allowed?
|
#define XML_HTTP_REQUEST_SYNCLOOPING (1 << 10) // Internal
|
||||||
// Even if this is false the
|
#define XML_HTTP_REQUEST_MULTIPART (1 << 11) // Internal
|
||||||
// access-control spec is supported
|
#define XML_HTTP_REQUEST_GOT_FINAL_STOP (1 << 12) // Internal
|
||||||
#define XML_HTTP_REQUEST_SYNCLOOPING (1 << 11) // Internal
|
#define XML_HTTP_REQUEST_BACKGROUND (1 << 13) // Internal
|
||||||
#define XML_HTTP_REQUEST_MULTIPART (1 << 12) // Internal
|
|
||||||
#define XML_HTTP_REQUEST_GOT_FINAL_STOP (1 << 13) // Internal
|
|
||||||
#define XML_HTTP_REQUEST_BACKGROUND (1 << 14) // Internal
|
|
||||||
// This is set when we've got the headers for a multipart XMLHttpRequest,
|
// This is set when we've got the headers for a multipart XMLHttpRequest,
|
||||||
// but haven't yet started to process the first part.
|
// but haven't yet started to process the first part.
|
||||||
#define XML_HTTP_REQUEST_MPART_HEADERS (1 << 15) // Internal
|
#define XML_HTTP_REQUEST_MPART_HEADERS (1 << 14) // Internal
|
||||||
#define XML_HTTP_REQUEST_USE_XSITE_AC (1 << 16) // Internal
|
#define XML_HTTP_REQUEST_USE_XSITE_AC (1 << 15) // Internal
|
||||||
#define XML_HTTP_REQUEST_NEED_AC_PREFLIGHT (1 << 17) // Internal
|
#define XML_HTTP_REQUEST_NEED_AC_PREFLIGHT (1 << 16) // Internal
|
||||||
#define XML_HTTP_REQUEST_AC_WITH_CREDENTIALS (1 << 18) // Internal
|
#define XML_HTTP_REQUEST_AC_WITH_CREDENTIALS (1 << 17) // Internal
|
||||||
|
|
||||||
#define XML_HTTP_REQUEST_LOADSTATES \
|
#define XML_HTTP_REQUEST_LOADSTATES \
|
||||||
(XML_HTTP_REQUEST_UNINITIALIZED | \
|
(XML_HTTP_REQUEST_UNINITIALIZED | \
|
||||||
|
@ -1639,14 +1636,12 @@ nsXMLHttpRequest::GetCurrentHttpChannel()
|
||||||
nsresult
|
nsresult
|
||||||
nsXMLHttpRequest::CheckChannelForCrossSiteRequest(nsIChannel* aChannel)
|
nsXMLHttpRequest::CheckChannelForCrossSiteRequest(nsIChannel* aChannel)
|
||||||
{
|
{
|
||||||
// First check if cross-site requests are enabled
|
// First check if cross-site requests are enabled...
|
||||||
if ((mState & XML_HTTP_REQUEST_XSITEENABLED)) {
|
if (IsSystemXHR()) {
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
// or if this is a same-origin request.
|
// ...or if this is a same-origin request.
|
||||||
NS_ASSERTION(!nsContentUtils::IsSystemPrincipal(mPrincipal),
|
|
||||||
"Shouldn't get here!");
|
|
||||||
if (nsContentUtils::CheckMayLoad(mPrincipal, aChannel)) {
|
if (nsContentUtils::CheckMayLoad(mPrincipal, aChannel)) {
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
@ -1797,12 +1792,6 @@ nsXMLHttpRequest::OpenRequest(const nsACString& method,
|
||||||
channelPolicy);
|
channelPolicy);
|
||||||
if (NS_FAILED(rv)) return rv;
|
if (NS_FAILED(rv)) return rv;
|
||||||
|
|
||||||
// Check if we're doing a cross-origin request.
|
|
||||||
if (nsContentUtils::IsSystemPrincipal(mPrincipal)) {
|
|
||||||
// Chrome callers are always allowed to read from different origins.
|
|
||||||
mState |= XML_HTTP_REQUEST_XSITEENABLED;
|
|
||||||
}
|
|
||||||
|
|
||||||
mState &= ~(XML_HTTP_REQUEST_USE_XSITE_AC |
|
mState &= ~(XML_HTTP_REQUEST_USE_XSITE_AC |
|
||||||
XML_HTTP_REQUEST_NEED_AC_PREFLIGHT);
|
XML_HTTP_REQUEST_NEED_AC_PREFLIGHT);
|
||||||
|
|
||||||
|
@ -1823,17 +1812,6 @@ nsXMLHttpRequest::Open(const nsACString& method, const nsACString& url,
|
||||||
PRBool async, const nsAString& user,
|
PRBool async, const nsAString& user,
|
||||||
const nsAString& password, PRUint8 optional_argc)
|
const nsAString& password, PRUint8 optional_argc)
|
||||||
{
|
{
|
||||||
if (nsContentUtils::GetCurrentJSContext()) {
|
|
||||||
// We're (likely) called from JS
|
|
||||||
|
|
||||||
// Find out if UniversalBrowserRead privileges are enabled
|
|
||||||
if (nsContentUtils::IsCallerTrustedForRead()) {
|
|
||||||
mState |= XML_HTTP_REQUEST_XSITEENABLED;
|
|
||||||
} else {
|
|
||||||
mState &= ~XML_HTTP_REQUEST_XSITEENABLED;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!optional_argc) {
|
if (!optional_argc) {
|
||||||
// No optional arguments were passed in. Default async to true.
|
// No optional arguments were passed in. Default async to true.
|
||||||
async = PR_TRUE;
|
async = PR_TRUE;
|
||||||
|
@ -1954,8 +1932,8 @@ nsXMLHttpRequest::OnStartRequest(nsIRequest *request, nsISupports *ctxt)
|
||||||
nsCOMPtr<nsIChannel> channel(do_QueryInterface(request));
|
nsCOMPtr<nsIChannel> channel(do_QueryInterface(request));
|
||||||
NS_ENSURE_TRUE(channel, NS_ERROR_UNEXPECTED);
|
NS_ENSURE_TRUE(channel, NS_ERROR_UNEXPECTED);
|
||||||
|
|
||||||
nsCOMPtr<nsIPrincipal> documentPrincipal = mPrincipal;
|
nsCOMPtr<nsIPrincipal> documentPrincipal;
|
||||||
if (nsContentUtils::IsSystemPrincipal(documentPrincipal)) {
|
if (IsSystemXHR()) {
|
||||||
// Don't give this document the system principal. We need to keep track of
|
// Don't give this document the system principal. We need to keep track of
|
||||||
// mPrincipal being system because we use it for various security checks
|
// mPrincipal being system because we use it for various security checks
|
||||||
// that should be passing, but the document data shouldn't get a system
|
// that should be passing, but the document data shouldn't get a system
|
||||||
|
@ -1963,6 +1941,8 @@ nsXMLHttpRequest::OnStartRequest(nsIRequest *request, nsISupports *ctxt)
|
||||||
nsresult rv;
|
nsresult rv;
|
||||||
documentPrincipal = do_CreateInstance("@mozilla.org/nullprincipal;1", &rv);
|
documentPrincipal = do_CreateInstance("@mozilla.org/nullprincipal;1", &rv);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
} else {
|
||||||
|
documentPrincipal = mPrincipal;
|
||||||
}
|
}
|
||||||
|
|
||||||
channel->SetOwner(documentPrincipal);
|
channel->SetOwner(documentPrincipal);
|
||||||
|
@ -2040,7 +2020,7 @@ nsXMLHttpRequest::OnStartRequest(nsIRequest *request, nsISupports *ctxt)
|
||||||
nsCOMPtr<nsIDocument> responseDoc = do_QueryInterface(mResponseXML);
|
nsCOMPtr<nsIDocument> responseDoc = do_QueryInterface(mResponseXML);
|
||||||
responseDoc->SetPrincipal(documentPrincipal);
|
responseDoc->SetPrincipal(documentPrincipal);
|
||||||
|
|
||||||
if (nsContentUtils::IsSystemPrincipal(mPrincipal)) {
|
if (IsSystemXHR()) {
|
||||||
responseDoc->ForceEnableXULXBL();
|
responseDoc->ForceEnableXULXBL();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2420,7 +2400,7 @@ nsXMLHttpRequest::Send(nsIVariant *aBody)
|
||||||
if (httpChannel) {
|
if (httpChannel) {
|
||||||
httpChannel->GetRequestMethod(method); // If GET, method name will be uppercase
|
httpChannel->GetRequestMethod(method); // If GET, method name will be uppercase
|
||||||
|
|
||||||
if (!nsContentUtils::IsSystemPrincipal(mPrincipal)) {
|
if (!IsSystemXHR()) {
|
||||||
// Get the referrer for the request.
|
// Get the referrer for the request.
|
||||||
//
|
//
|
||||||
// If it weren't for history.push/replaceState, we could just use the
|
// If it weren't for history.push/replaceState, we could just use the
|
||||||
|
@ -2656,7 +2636,7 @@ nsXMLHttpRequest::Send(nsIVariant *aBody)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(mState & XML_HTTP_REQUEST_XSITEENABLED)) {
|
if (!IsSystemXHR()) {
|
||||||
// Always create a nsCrossSiteListenerProxy here even if it's
|
// Always create a nsCrossSiteListenerProxy here even if it's
|
||||||
// a same-origin request right now, since it could be redirected.
|
// a same-origin request right now, since it could be redirected.
|
||||||
listener = new nsCrossSiteListenerProxy(listener, mPrincipal, mChannel,
|
listener = new nsCrossSiteListenerProxy(listener, mPrincipal, mChannel,
|
||||||
|
@ -2853,7 +2833,7 @@ nsXMLHttpRequest::SetRequestHeader(const nsACString& header,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for dangerous cross-site headers
|
// Check for dangerous cross-site headers
|
||||||
PRBool safeHeader = !!(mState & XML_HTTP_REQUEST_XSITEENABLED);
|
bool safeHeader = IsSystemXHR();
|
||||||
if (!safeHeader) {
|
if (!safeHeader) {
|
||||||
// Content-Type isn't always safe, but we'll deal with it in Send()
|
// Content-Type isn't always safe, but we'll deal with it in Send()
|
||||||
const char *kCrossOriginSafeHeaders[] = {
|
const char *kCrossOriginSafeHeaders[] = {
|
||||||
|
@ -2862,7 +2842,7 @@ nsXMLHttpRequest::SetRequestHeader(const nsACString& header,
|
||||||
};
|
};
|
||||||
for (i = 0; i < NS_ARRAY_LENGTH(kCrossOriginSafeHeaders); ++i) {
|
for (i = 0; i < NS_ARRAY_LENGTH(kCrossOriginSafeHeaders); ++i) {
|
||||||
if (header.LowerCaseEqualsASCII(kCrossOriginSafeHeaders[i])) {
|
if (header.LowerCaseEqualsASCII(kCrossOriginSafeHeaders[i])) {
|
||||||
safeHeader = PR_TRUE;
|
safeHeader = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,6 +69,7 @@
|
||||||
#include "nsIPrivateDOMEvent.h"
|
#include "nsIPrivateDOMEvent.h"
|
||||||
#include "nsDOMProgressEvent.h"
|
#include "nsDOMProgressEvent.h"
|
||||||
#include "nsDOMEventTargetWrapperCache.h"
|
#include "nsDOMEventTargetWrapperCache.h"
|
||||||
|
#include "nsContentUtils.h"
|
||||||
|
|
||||||
class nsILoadGroup;
|
class nsILoadGroup;
|
||||||
class AsyncVerifyRedirectCallbackForwarder;
|
class AsyncVerifyRedirectCallbackForwarder;
|
||||||
|
@ -333,6 +334,10 @@ protected:
|
||||||
|
|
||||||
already_AddRefed<nsIHttpChannel> GetCurrentHttpChannel();
|
already_AddRefed<nsIHttpChannel> GetCurrentHttpChannel();
|
||||||
|
|
||||||
|
bool IsSystemXHR() {
|
||||||
|
return !!nsContentUtils::IsSystemPrincipal(mPrincipal);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if aChannel is ok for a cross-site request by making sure no
|
* Check if aChannel is ok for a cross-site request by making sure no
|
||||||
* inappropriate headers are set, and no username/password is set.
|
* inappropriate headers are set, and no username/password is set.
|
||||||
|
|
|
@ -22,9 +22,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=426308
|
||||||
|
|
||||||
const SJS_URL = "http://example.org:80/tests/content/base/test/bug426308-redirect.sjs";
|
const SJS_URL = "http://example.org:80/tests/content/base/test/bug426308-redirect.sjs";
|
||||||
|
|
||||||
netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead");
|
var req = SpecialPowers.createSystemXHR();
|
||||||
|
|
||||||
var req = new XMLHttpRequest();
|
|
||||||
req.open("GET", SJS_URL + "?" + window.location.href, false);
|
req.open("GET", SJS_URL + "?" + window.location.href, false);
|
||||||
req.send(null);
|
req.send(null);
|
||||||
|
|
||||||
|
|
|
@ -52,8 +52,7 @@ function createDoc() {
|
||||||
function xhrDoc(idx) {
|
function xhrDoc(idx) {
|
||||||
return function() {
|
return function() {
|
||||||
// Defy same-origin restrictions!
|
// Defy same-origin restrictions!
|
||||||
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
|
var xhr = SpecialPowers.createSystemXHR();
|
||||||
var xhr = new XMLHttpRequest();
|
|
||||||
xhr.open("GET", docSources[idx], false);
|
xhr.open("GET", docSources[idx], false);
|
||||||
xhr.send();
|
xhr.send();
|
||||||
return xhr.responseXML;
|
return xhr.responseXML;
|
||||||
|
|
|
@ -37,13 +37,18 @@
|
||||||
/* This code is loaded in every child process that is started by mochitest in
|
/* This code is loaded in every child process that is started by mochitest in
|
||||||
* order to be used as a replacement for UniversalXPConnect
|
* order to be used as a replacement for UniversalXPConnect
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
var Ci = Components.interfaces;
|
||||||
|
var Cc = Components.classes;
|
||||||
|
|
||||||
function SpecialPowers(window) {
|
function SpecialPowers(window) {
|
||||||
this.window = window;
|
this.window = window;
|
||||||
bindDOMWindowUtils(this, window);
|
bindDOMWindowUtils(this, window);
|
||||||
}
|
}
|
||||||
|
|
||||||
function bindDOMWindowUtils(sp, window) {
|
function bindDOMWindowUtils(sp, window) {
|
||||||
var util = window.QueryInterface(Components.interfaces.nsIInterfaceRequestor).getInterface(Components.interfaces.nsIDOMWindowUtils);
|
var util = window.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||||
|
.getInterface(Ci.nsIDOMWindowUtils);
|
||||||
// This bit of magic brought to you by the letters
|
// This bit of magic brought to you by the letters
|
||||||
// B Z, and E, S and the number 5.
|
// B Z, and E, S and the number 5.
|
||||||
//
|
//
|
||||||
|
@ -135,7 +140,6 @@ SpecialPowers.prototype = {
|
||||||
//XXX: these APIs really ought to be removed, they're not e10s-safe.
|
//XXX: these APIs really ought to be removed, they're not e10s-safe.
|
||||||
// (also they're pretty Firefox-specific)
|
// (also they're pretty Firefox-specific)
|
||||||
_getTopChromeWindow: function(window) {
|
_getTopChromeWindow: function(window) {
|
||||||
var Ci = Components.interfaces;
|
|
||||||
return window.QueryInterface(Ci.nsIInterfaceRequestor)
|
return window.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||||
.getInterface(Ci.nsIWebNavigation)
|
.getInterface(Ci.nsIWebNavigation)
|
||||||
.QueryInterface(Ci.nsIDocShellTreeItem)
|
.QueryInterface(Ci.nsIDocShellTreeItem)
|
||||||
|
@ -169,6 +173,11 @@ SpecialPowers.prototype = {
|
||||||
},
|
},
|
||||||
removeChromeEventListener: function(type, listener, capture) {
|
removeChromeEventListener: function(type, listener, capture) {
|
||||||
removeEventListener(type, listener, capture);
|
removeEventListener(type, listener, capture);
|
||||||
|
},
|
||||||
|
|
||||||
|
createSystemXHR: function() {
|
||||||
|
return Cc["@mozilla.org/xmlextras/xmlhttprequest;1"]
|
||||||
|
.createInstance(Ci.nsIXMLHttpRequest);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче