mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
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
0d4109c626
commit
b65f2814ef
@ -49,6 +49,8 @@ LIBXUL_LIBRARY = 1
|
||||
REQUIRES = xpcom \
|
||||
string \
|
||||
rdfutil \
|
||||
js \
|
||||
caps \
|
||||
necko \
|
||||
content \
|
||||
htmlparser \
|
||||
|
@ -123,6 +123,9 @@
|
||||
#include "nsNameSpaceMap.h"
|
||||
#include "nsCRT.h"
|
||||
#include "nsCycleCollectionParticipant.h"
|
||||
#include "nsIScriptSecurityManager.h"
|
||||
#include "nsIChannelEventSink.h"
|
||||
#include "nsNetUtil.h"
|
||||
|
||||
#include "rdfIDataSource.h"
|
||||
|
||||
@ -145,7 +148,9 @@ class RDFXMLDataSourceImpl : public nsIRDFDataSource,
|
||||
public nsIRDFXMLSink,
|
||||
public nsIRDFXMLSource,
|
||||
public nsIStreamListener,
|
||||
public rdfIDataSource
|
||||
public rdfIDataSource,
|
||||
public nsIInterfaceRequestor,
|
||||
public nsIChannelEventSink
|
||||
{
|
||||
protected:
|
||||
enum LoadState {
|
||||
@ -318,6 +323,12 @@ public:
|
||||
// nsIStreamListener
|
||||
NS_DECL_NSISTREAMLISTENER
|
||||
|
||||
// nsIInterfaceRequestor
|
||||
NS_DECL_NSIINTERFACEREQUESTOR
|
||||
|
||||
// nsIChannelEventSink
|
||||
NS_DECL_NSICHANNELEVENTSINK
|
||||
|
||||
// rdfIDataSource
|
||||
NS_IMETHOD VisitAllSubjects(rdfITripleVisitor *aVisitor) {
|
||||
nsresult rv;
|
||||
@ -481,9 +492,17 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(RDFXMLDataSourceImpl)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIRequestObserver)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIStreamListener)
|
||||
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_END
|
||||
|
||||
// nsIInterfaceRequestor
|
||||
NS_IMETHODIMP
|
||||
RDFXMLDataSourceImpl::GetInterface(const nsIID& aIID, void** aSink)
|
||||
{
|
||||
return QueryInterface(aIID, aSink);
|
||||
}
|
||||
|
||||
nsresult
|
||||
RDFXMLDataSourceImpl::BlockingParse(nsIURI* aURL, nsIStreamListener* aConsumer)
|
||||
@ -877,6 +896,39 @@ RDFXMLDataSourceImpl::SetReadOnly(PRBool aIsReadOnly)
|
||||
|
||||
#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
|
||||
RDFXMLDataSourceImpl::Refresh(PRBool aBlocking)
|
||||
{
|
||||
@ -925,7 +977,7 @@ RDFXMLDataSourceImpl::Refresh(PRBool aBlocking)
|
||||
}
|
||||
else {
|
||||
// Null LoadGroup ?
|
||||
rv = NS_OpenURI(this, nsnull, mURL, nsnull);
|
||||
rv = NS_OpenURI(this, nsnull, mURL, nsnull, nsnull, this);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
// So we don't try to issue two asynchronous loads at once.
|
||||
|
@ -40,9 +40,13 @@ topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
MODULE = test_rdf
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
DIRS = rdfcat rdfpoll triplescat
|
||||
|
||||
XPCSHELL_TESTS = unit
|
||||
|
||||
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 New Issue
Block a user