forked from mirrors/gecko-dev
Bug 414540 - RDFXMLDataSource should reject cross-domain redirects. Original patch by Neil Deakin, fixed up with better testing, r+sr=bz
This commit is contained in:
parent
ac2f869fe0
commit
d05ca8b26f
5 changed files with 159 additions and 2 deletions
|
|
@ -49,6 +49,8 @@ LIBXUL_LIBRARY = 1
|
||||||
REQUIRES = xpcom \
|
REQUIRES = xpcom \
|
||||||
string \
|
string \
|
||||||
rdfutil \
|
rdfutil \
|
||||||
|
js \
|
||||||
|
caps \
|
||||||
necko \
|
necko \
|
||||||
content \
|
content \
|
||||||
htmlparser \
|
htmlparser \
|
||||||
|
|
|
||||||
|
|
@ -123,6 +123,9 @@
|
||||||
#include "nsNameSpaceMap.h"
|
#include "nsNameSpaceMap.h"
|
||||||
#include "nsCRT.h"
|
#include "nsCRT.h"
|
||||||
#include "nsCycleCollectionParticipant.h"
|
#include "nsCycleCollectionParticipant.h"
|
||||||
|
#include "nsIScriptSecurityManager.h"
|
||||||
|
#include "nsIChannelEventSink.h"
|
||||||
|
#include "nsNetUtil.h"
|
||||||
|
|
||||||
#include "rdfIDataSource.h"
|
#include "rdfIDataSource.h"
|
||||||
|
|
||||||
|
|
@ -145,7 +148,9 @@ class RDFXMLDataSourceImpl : public nsIRDFDataSource,
|
||||||
public nsIRDFXMLSink,
|
public nsIRDFXMLSink,
|
||||||
public nsIRDFXMLSource,
|
public nsIRDFXMLSource,
|
||||||
public nsIStreamListener,
|
public nsIStreamListener,
|
||||||
public rdfIDataSource
|
public rdfIDataSource,
|
||||||
|
public nsIInterfaceRequestor,
|
||||||
|
public nsIChannelEventSink
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
enum LoadState {
|
enum LoadState {
|
||||||
|
|
@ -318,6 +323,12 @@ public:
|
||||||
// nsIStreamListener
|
// nsIStreamListener
|
||||||
NS_DECL_NSISTREAMLISTENER
|
NS_DECL_NSISTREAMLISTENER
|
||||||
|
|
||||||
|
// nsIInterfaceRequestor
|
||||||
|
NS_DECL_NSIINTERFACEREQUESTOR
|
||||||
|
|
||||||
|
// nsIChannelEventSink
|
||||||
|
NS_DECL_NSICHANNELEVENTSINK
|
||||||
|
|
||||||
// rdfIDataSource
|
// rdfIDataSource
|
||||||
NS_IMETHOD VisitAllSubjects(rdfITripleVisitor *aVisitor) {
|
NS_IMETHOD VisitAllSubjects(rdfITripleVisitor *aVisitor) {
|
||||||
nsresult rv;
|
nsresult rv;
|
||||||
|
|
@ -481,9 +492,17 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(RDFXMLDataSourceImpl)
|
||||||
NS_INTERFACE_MAP_ENTRY(nsIRequestObserver)
|
NS_INTERFACE_MAP_ENTRY(nsIRequestObserver)
|
||||||
NS_INTERFACE_MAP_ENTRY(nsIStreamListener)
|
NS_INTERFACE_MAP_ENTRY(nsIStreamListener)
|
||||||
NS_INTERFACE_MAP_ENTRY(rdfIDataSource)
|
NS_INTERFACE_MAP_ENTRY(rdfIDataSource)
|
||||||
|
NS_INTERFACE_MAP_ENTRY(nsIInterfaceRequestor)
|
||||||
|
NS_INTERFACE_MAP_ENTRY(nsIChannelEventSink)
|
||||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIRDFDataSource)
|
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIRDFDataSource)
|
||||||
NS_INTERFACE_MAP_END
|
NS_INTERFACE_MAP_END
|
||||||
|
|
||||||
|
// nsIInterfaceRequestor
|
||||||
|
NS_IMETHODIMP
|
||||||
|
RDFXMLDataSourceImpl::GetInterface(const nsIID& aIID, void** aSink)
|
||||||
|
{
|
||||||
|
return QueryInterface(aIID, aSink);
|
||||||
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
RDFXMLDataSourceImpl::BlockingParse(nsIURI* aURL, nsIStreamListener* aConsumer)
|
RDFXMLDataSourceImpl::BlockingParse(nsIURI* aURL, nsIStreamListener* aConsumer)
|
||||||
|
|
@ -877,6 +896,39 @@ RDFXMLDataSourceImpl::SetReadOnly(PRBool aIsReadOnly)
|
||||||
|
|
||||||
#include "nsITimelineService.h"
|
#include "nsITimelineService.h"
|
||||||
|
|
||||||
|
// nsIChannelEventSink
|
||||||
|
|
||||||
|
// This code is copied from nsSameOriginChecker::OnChannelRedirect. See
|
||||||
|
// bug 475940 on providing this code in a shared location.
|
||||||
|
NS_IMETHODIMP
|
||||||
|
RDFXMLDataSourceImpl::OnChannelRedirect(nsIChannel *aOldChannel,
|
||||||
|
nsIChannel *aNewChannel,
|
||||||
|
PRUint32 aFlags)
|
||||||
|
{
|
||||||
|
NS_PRECONDITION(aNewChannel, "Redirecting to null channel?");
|
||||||
|
|
||||||
|
nsresult rv;
|
||||||
|
nsCOMPtr<nsIScriptSecurityManager> secMan =
|
||||||
|
do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv);
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
nsCOMPtr<nsIPrincipal> oldPrincipal;
|
||||||
|
secMan->GetChannelPrincipal(aOldChannel, getter_AddRefs(oldPrincipal));
|
||||||
|
|
||||||
|
nsCOMPtr<nsIURI> newURI;
|
||||||
|
aNewChannel->GetURI(getter_AddRefs(newURI));
|
||||||
|
nsCOMPtr<nsIURI> newOriginalURI;
|
||||||
|
aNewChannel->GetOriginalURI(getter_AddRefs(newOriginalURI));
|
||||||
|
|
||||||
|
NS_ENSURE_STATE(oldPrincipal && newURI && newOriginalURI);
|
||||||
|
|
||||||
|
rv = oldPrincipal->CheckMayLoad(newURI, PR_FALSE);
|
||||||
|
if (NS_SUCCEEDED(rv) && newOriginalURI != newURI) {
|
||||||
|
rv = oldPrincipal->CheckMayLoad(newOriginalURI, PR_FALSE);
|
||||||
|
}
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
RDFXMLDataSourceImpl::Refresh(PRBool aBlocking)
|
RDFXMLDataSourceImpl::Refresh(PRBool aBlocking)
|
||||||
{
|
{
|
||||||
|
|
@ -925,7 +977,7 @@ RDFXMLDataSourceImpl::Refresh(PRBool aBlocking)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Null LoadGroup ?
|
// Null LoadGroup ?
|
||||||
rv = NS_OpenURI(this, nsnull, mURL, nsnull);
|
rv = NS_OpenURI(this, nsnull, mURL, nsnull, nsnull, this);
|
||||||
if (NS_FAILED(rv)) return rv;
|
if (NS_FAILED(rv)) return rv;
|
||||||
|
|
||||||
// So we don't try to issue two asynchronous loads at once.
|
// So we don't try to issue two asynchronous loads at once.
|
||||||
|
|
|
||||||
|
|
@ -40,9 +40,13 @@ topsrcdir = @top_srcdir@
|
||||||
srcdir = @srcdir@
|
srcdir = @srcdir@
|
||||||
VPATH = @srcdir@
|
VPATH = @srcdir@
|
||||||
|
|
||||||
|
MODULE = test_rdf
|
||||||
|
|
||||||
include $(DEPTH)/config/autoconf.mk
|
include $(DEPTH)/config/autoconf.mk
|
||||||
|
|
||||||
DIRS = rdfcat rdfpoll triplescat
|
DIRS = rdfcat rdfpoll triplescat
|
||||||
|
|
||||||
|
XPCSHELL_TESTS = unit
|
||||||
|
|
||||||
include $(topsrcdir)/config/rules.mk
|
include $(topsrcdir)/config/rules.mk
|
||||||
|
|
||||||
|
|
|
||||||
9
rdf/tests/unit/sample.rdf
Executable file
9
rdf/tests/unit/sample.rdf
Executable file
|
|
@ -0,0 +1,9 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
|
||||||
|
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||||
|
|
||||||
|
<rdf:Description about="urn:mozilla:sample-data"
|
||||||
|
dc:title="Sample" />
|
||||||
|
|
||||||
|
</rdf:RDF>
|
||||||
90
rdf/tests/unit/test_rdfredirect.js
Normal file
90
rdf/tests/unit/test_rdfredirect.js
Normal file
|
|
@ -0,0 +1,90 @@
|
||||||
|
do_import_script("netwerk/test/httpserver/httpd.js");
|
||||||
|
|
||||||
|
function getRDFService()
|
||||||
|
{
|
||||||
|
return Components.classes["@mozilla.org/rdf/rdf-service;1"].
|
||||||
|
getService(Components.interfaces.nsIRDFService);
|
||||||
|
}
|
||||||
|
|
||||||
|
var server1, server2;
|
||||||
|
|
||||||
|
function run_test()
|
||||||
|
{
|
||||||
|
var samplefile = do_get_file('rdf/tests/unit/sample.rdf');
|
||||||
|
|
||||||
|
server1 = new nsHttpServer();
|
||||||
|
server1.registerPathHandler("/sample-xs.rdf", xsRedirect);
|
||||||
|
server1.registerPathHandler("/sample-local.rdf", localRedirect);
|
||||||
|
server1.registerFile('/sample.rdf', samplefile);
|
||||||
|
server1.start(4444);
|
||||||
|
|
||||||
|
server2 = new nsHttpServer();
|
||||||
|
server2.registerFile('/sample.rdf', samplefile);
|
||||||
|
server2.start(4445);
|
||||||
|
|
||||||
|
do_test_pending();
|
||||||
|
|
||||||
|
new rdfLoadObserver('http://localhost:4444/sample.rdf', true);
|
||||||
|
new rdfLoadObserver('http://localhost:4445/sample.rdf', true);
|
||||||
|
new rdfLoadObserver('http://localhost:4444/sample-xs.rdf', false);
|
||||||
|
new rdfLoadObserver('http://localhost:4444/sample-local.rdf', true);
|
||||||
|
}
|
||||||
|
|
||||||
|
var gPending = 0;
|
||||||
|
|
||||||
|
function rdfLoadObserver(uri, shouldPass)
|
||||||
|
{
|
||||||
|
this.shouldPass = shouldPass;
|
||||||
|
this.uri = uri;
|
||||||
|
|
||||||
|
++gPending;
|
||||||
|
|
||||||
|
var rdfService = getRDFService();
|
||||||
|
this.ds = rdfService.GetDataSource(uri).
|
||||||
|
QueryInterface(Components.interfaces.nsIRDFXMLSink);
|
||||||
|
this.ds.addXMLSinkObserver(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
rdfLoadObserver.prototype =
|
||||||
|
{
|
||||||
|
onBeginLoad : function() { },
|
||||||
|
onInterrupt : function() { },
|
||||||
|
onResume : function() { },
|
||||||
|
onEndLoad : function() {
|
||||||
|
print("Testing results of loading " + this.uri);
|
||||||
|
|
||||||
|
var rdfs = getRDFService();
|
||||||
|
var res = rdfs.GetResource("urn:mozilla:sample-data");
|
||||||
|
var arc = rdfs.GetResource("http://purl.org/dc/elements/1.1/title");
|
||||||
|
var answer = this.ds.GetTarget(res, arc, true);
|
||||||
|
if (answer !== null) {
|
||||||
|
do_check_true(this.shouldPass);
|
||||||
|
do_check_true(answer instanceof Components.interfaces.nsIRDFLiteral);
|
||||||
|
do_check_eq(answer.Value, "Sample");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
do_check_false(this.shouldPass);
|
||||||
|
}
|
||||||
|
|
||||||
|
gPending -= 1;
|
||||||
|
|
||||||
|
if (gPending == 0) {
|
||||||
|
server1.stop();
|
||||||
|
server2.stop();
|
||||||
|
do_test_finished();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onError : function() { }
|
||||||
|
}
|
||||||
|
|
||||||
|
function xsRedirect(metadata, response)
|
||||||
|
{
|
||||||
|
response.setStatusLine(metadata.httpVersion, 301, "Moved Permanently");
|
||||||
|
response.setHeader("Location", "http://localhost:4445/sample.rdf", false);
|
||||||
|
}
|
||||||
|
|
||||||
|
function localRedirect(metadata, response)
|
||||||
|
{
|
||||||
|
response.setStatusLine(metadata.httpVersion, 301, "Moved Permanently");
|
||||||
|
response.setHeader("Location", "http://localhost:4444/sample.rdf", false);
|
||||||
|
}
|
||||||
Loading…
Reference in a new issue