зеркало из https://github.com/mozilla/pjs.git
Bug 466582 - smarter handling of remote chrome (and not allowing it)
This adds a new flag, URI_IS_LOCAL_RESOURCE, to nsIProtocolHandler that allows something of this protocol to be registered in chrome. This changeset removes a runtime check every time we open a chrome channel to see if it is remote to a registration time check that checks flags. The old code could be easily worked around, and allowed for remote resources to be used. r=bsmedberg r=bz sr=bz
This commit is contained in:
Родитель
f069402a3e
Коммит
79ae006392
|
@ -418,7 +418,7 @@ nsChromeProtocolHandler::AllowPort(PRInt32 port, const char *scheme, PRBool *_re
|
|||
NS_IMETHODIMP
|
||||
nsChromeProtocolHandler::GetProtocolFlags(PRUint32 *result)
|
||||
{
|
||||
*result = URI_STD | URI_IS_UI_RESOURCE;
|
||||
*result = URI_STD | URI_IS_UI_RESOURCE | URI_IS_LOCAL_RESOURCE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -465,7 +465,7 @@ nsChromeProtocolHandler::NewChannel(nsIURI* aURI,
|
|||
|
||||
NS_ENSURE_ARG_POINTER(aURI);
|
||||
NS_PRECONDITION(aResult, "Null out param");
|
||||
|
||||
|
||||
#ifdef DEBUG
|
||||
// Check that the uri we got is already canonified
|
||||
nsresult debug_rv;
|
||||
|
@ -554,38 +554,6 @@ nsChromeProtocolHandler::NewChannel(nsIURI* aURI,
|
|||
rv = ioServ->NewChannelFromURI(resolvedURI, getter_AddRefs(result));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
// XXX Will be removed someday when we handle remote chrome.
|
||||
nsCOMPtr<nsIFileChannel> fileChan
|
||||
(do_QueryInterface(result));
|
||||
if (fileChan) {
|
||||
#ifdef DEBUG
|
||||
nsCOMPtr<nsIFile> file;
|
||||
fileChan->GetFile(getter_AddRefs(file));
|
||||
|
||||
PRBool exists = PR_FALSE;
|
||||
file->Exists(&exists);
|
||||
if (!exists) {
|
||||
nsCAutoString path;
|
||||
file->GetNativePath(path);
|
||||
printf("Chrome file doesn't exist: %s\n", path.get());
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
nsCOMPtr<nsIJARChannel> jarChan
|
||||
(do_QueryInterface(result));
|
||||
if (!jarChan) {
|
||||
nsRefPtr<nsCachedChromeChannel> cachedChannel;
|
||||
if (NS_FAILED(CallQueryInterface(result.get(),
|
||||
static_cast<nsCachedChromeChannel**>(
|
||||
getter_AddRefs(cachedChannel))))) {
|
||||
NS_WARNING("Remote chrome not allowed! Only file:, resource:, jar:, and cached chrome channels are valid.\n");
|
||||
result = nsnull;
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Make sure that the channel remembers where it was
|
||||
// originally loaded from.
|
||||
rv = result->SetOriginalURI(aURI);
|
||||
|
@ -627,24 +595,15 @@ nsChromeProtocolHandler::NewChannel(nsIURI* aURI,
|
|||
if (objectOutput) {
|
||||
nsCOMPtr<nsIFile> file;
|
||||
|
||||
if (fileChan) {
|
||||
fileChan->GetFile(getter_AddRefs(file));
|
||||
} else {
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
result->GetURI(getter_AddRefs(uri));
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
result->GetURI(getter_AddRefs(uri));
|
||||
uri = NS_GetInnermostURI(uri);
|
||||
|
||||
// Loop, jar URIs can nest (e.g. jar:jar:A.jar!B.jar!C.xml).
|
||||
// Often, however, we have jar:resource:/chrome/A.jar!C.xml.
|
||||
nsCOMPtr<nsIJARURI> jarURI;
|
||||
while ((jarURI = do_QueryInterface(uri)) != nsnull)
|
||||
jarURI->GetJARFile(getter_AddRefs(uri));
|
||||
|
||||
// Here we have a URL of the form resource:/chrome/A.jar
|
||||
// or file:/some/path/to/A.jar.
|
||||
nsCOMPtr<nsIFileURL> fileURL(do_QueryInterface(uri));
|
||||
if (fileURL)
|
||||
fileURL->GetFile(getter_AddRefs(file));
|
||||
}
|
||||
// Here we have a URL of the form resource:/chrome/A.jar
|
||||
// or file:/some/path/to/A.jar.
|
||||
nsCOMPtr<nsIFileURL> fileURL(do_QueryInterface(uri));
|
||||
if (fileURL)
|
||||
fileURL->GetFile(getter_AddRefs(file));
|
||||
|
||||
if (file) {
|
||||
rv = fastLoadServ->AddDependency(file);
|
||||
|
|
|
@ -252,6 +252,16 @@ LanguagesMatch(const nsACString& a, const nsACString& b)
|
|||
return PR_FALSE;
|
||||
}
|
||||
|
||||
static PRBool
|
||||
CanLoadResource(nsIURI* aResourceURI)
|
||||
{
|
||||
PRBool isLocalResource = PR_FALSE;
|
||||
(void)NS_URIChainHasFlags(aResourceURI,
|
||||
nsIProtocolHandler::URI_IS_LOCAL_RESOURCE,
|
||||
&isLocalResource);
|
||||
return isLocalResource;
|
||||
}
|
||||
|
||||
nsChromeRegistry::ProviderEntry*
|
||||
nsChromeRegistry::nsProviderArray::GetProvider(const nsACString& aPreferred, MatchType aType)
|
||||
{
|
||||
|
@ -2334,6 +2344,13 @@ nsChromeRegistry::ProcessManifestBuffer(char *buf, PRInt32 length,
|
|||
if (NS_FAILED(rv))
|
||||
continue;
|
||||
|
||||
if (!CanLoadResource(resolved)) {
|
||||
LogMessageWithContext(resolved, line, nsIScriptError::warningFlag,
|
||||
"Warning: cannot register non-local URI '%s' as content.",
|
||||
uri);
|
||||
continue;
|
||||
}
|
||||
|
||||
PackageEntry* entry =
|
||||
static_cast<PackageEntry*>(PL_DHashTableOperate(&mPackagesHash,
|
||||
& (const nsACString&) nsDependentCString(package),
|
||||
|
@ -2409,6 +2426,13 @@ nsChromeRegistry::ProcessManifestBuffer(char *buf, PRInt32 length,
|
|||
if (NS_FAILED(rv))
|
||||
continue;
|
||||
|
||||
if (!CanLoadResource(resolved)) {
|
||||
LogMessageWithContext(resolved, line, nsIScriptError::warningFlag,
|
||||
"Warning: cannot register non-local URI '%s' as a locale.",
|
||||
uri);
|
||||
continue;
|
||||
}
|
||||
|
||||
PackageEntry* entry =
|
||||
static_cast<PackageEntry*>(PL_DHashTableOperate(&mPackagesHash,
|
||||
& (const nsACString&) nsDependentCString(package),
|
||||
|
@ -2464,6 +2488,13 @@ nsChromeRegistry::ProcessManifestBuffer(char *buf, PRInt32 length,
|
|||
if (NS_FAILED(rv))
|
||||
continue;
|
||||
|
||||
if (!CanLoadResource(resolved)) {
|
||||
LogMessageWithContext(resolved, line, nsIScriptError::warningFlag,
|
||||
"Warning: cannot register non-local URI '%s' as a skin.",
|
||||
uri);
|
||||
continue;
|
||||
}
|
||||
|
||||
PackageEntry* entry =
|
||||
static_cast<PackageEntry*>(PL_DHashTableOperate(&mPackagesHash,
|
||||
& (const nsACString&) nsDependentCString(package),
|
||||
|
@ -2525,6 +2556,13 @@ nsChromeRegistry::ProcessManifestBuffer(char *buf, PRInt32 length,
|
|||
continue;
|
||||
}
|
||||
|
||||
if (!CanLoadResource(overlayuri)) {
|
||||
LogMessageWithContext(overlayuri, line, nsIScriptError::warningFlag,
|
||||
"Warning: cannot register non-local URI '%s' as an overlay.",
|
||||
overlay);
|
||||
continue;
|
||||
}
|
||||
|
||||
mOverlayHash.Add(baseuri, overlayuri);
|
||||
}
|
||||
else if (!strcmp(token, "style")) {
|
||||
|
@ -2572,6 +2610,13 @@ nsChromeRegistry::ProcessManifestBuffer(char *buf, PRInt32 length,
|
|||
if (NS_FAILED(rv))
|
||||
continue;
|
||||
|
||||
if (!CanLoadResource(overlayuri)) {
|
||||
LogMessageWithContext(overlayuri, line, nsIScriptError::warningFlag,
|
||||
"Warning: cannot register non-local URI '%s' as a style overlay.",
|
||||
overlay);
|
||||
continue;
|
||||
}
|
||||
|
||||
mStyleHash.Add(baseuri, overlayuri);
|
||||
}
|
||||
else if (!strcmp(token, "override")) {
|
||||
|
@ -2625,6 +2670,13 @@ nsChromeRegistry::ProcessManifestBuffer(char *buf, PRInt32 length,
|
|||
if (NS_FAILED(rv))
|
||||
continue;
|
||||
|
||||
if (!CanLoadResource(resolveduri)) {
|
||||
LogMessageWithContext(resolveduri, line, nsIScriptError::warningFlag,
|
||||
"Warning: cannot register non-local URI '%s' as an override.",
|
||||
resolved);
|
||||
continue;
|
||||
}
|
||||
|
||||
mOverrideTable.Put(chromeuri, resolveduri);
|
||||
}
|
||||
else if (!strcmp(token, "resource")) {
|
||||
|
@ -2690,6 +2742,13 @@ nsChromeRegistry::ProcessManifestBuffer(char *buf, PRInt32 length,
|
|||
if (NS_FAILED(rv))
|
||||
continue;
|
||||
|
||||
if (!CanLoadResource(resolved)) {
|
||||
LogMessageWithContext(resolved, line, nsIScriptError::warningFlag,
|
||||
"Warning: cannot register non-local URI '%s' as a resource.",
|
||||
uri);
|
||||
continue;
|
||||
}
|
||||
|
||||
rv = rph->SetSubstitution(host, resolved);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
|
|
@ -4,9 +4,6 @@ resource test1 test1/
|
|||
# Duplicates should be ignored
|
||||
resource test1 foo/
|
||||
|
||||
# Mapping off file system should work
|
||||
resource test2 http://www.mozilla.org/
|
||||
|
||||
# Mapping into jar files should work
|
||||
resource test3 jar:test3.jar!/resources/
|
||||
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
# package used only for valid override
|
||||
content good-package bar/
|
||||
|
||||
# Local resource (should work)
|
||||
override chrome://good-package/content/test.xul data:application/vnd.mozilla.xul+xml,
|
|
@ -0,0 +1,32 @@
|
|||
# package used only for valid overlaying and overrides
|
||||
content good-package bar/
|
||||
|
||||
# UI Resource URIs (should not work)
|
||||
content moz-protocol-ui-resource moz-protocol-ui-resource://foo/
|
||||
locale moz-protocol-ui-resource en-us moz-protocol-ui-resource://foo/
|
||||
skin moz-protocol-ui-resource skin1 moz-protocol-ui-resource://foo/
|
||||
override chrome://good-package/content/override-moz-protocol-ui-resource.xul moz-protocol-ui-resource://foo/
|
||||
resource moz-protocol-ui-resource moz-protocol-ui-resource://foo/
|
||||
|
||||
# Local file URIs (should not work)
|
||||
content moz-protocol-local-file moz-protocol-local-file://foo/
|
||||
locale moz-protocol-local-file en-us moz-protocol-local-file://foo/
|
||||
skin moz-protocol-local-file skin1 moz-protocol-local-file://foo/
|
||||
override chrome://good-package/content/override-moz-protocol-local-file.xul moz-protocol-local-file://foo/
|
||||
resource moz-protocol-local-file moz-protocol-local-file://foo/
|
||||
|
||||
# Loadable by anyone URIs (should not work)
|
||||
content moz-protocol-loadable-by-anyone moz-protocol-loadable-by-anyone://foo/
|
||||
locale moz-protocol-loadable-by-anyone en-us moz-protocol-loadable-by-anyone://foo/
|
||||
skin moz-protocol-loadable-by-anyone skin1 moz-protocol-loadable-by-anyone://foo/
|
||||
override chrome://good-package/content/override-moz-protocol-loadable-by-anyone.xul moz-protocol-loadable-by-anyone://foo/
|
||||
resource moz-protocol-loadable-by-anyone moz-protocol-loadable-by-anyone://foo/
|
||||
|
||||
# Working protocols should be after this point. Failing ones should be before.
|
||||
|
||||
# Local resource (should work)
|
||||
content moz-protocol-local-resource moz-protocol-local-resource://foo/
|
||||
locale moz-protocol-local-resource en-us moz-protocol-local-resource://foo/
|
||||
skin moz-protocol-local-resource skin1 moz-protocol-local-resource://foo/
|
||||
override chrome://good-package/content/override-moz-protocol-local-resource.xul moz-protocol-local-resource://foo/
|
||||
resource moz-protocol-local-resource moz-protocol-local-resource://foo/
|
|
@ -89,12 +89,12 @@ function test_succeeded_mapping(namespace, target)
|
|||
{
|
||||
try {
|
||||
do_check_true(rph.hasSubstitution(namespace));
|
||||
var thistarget = target + "/test.js";
|
||||
var uri = gIOS.newURI("resource://" + namespace + "/test.js",
|
||||
null, null);
|
||||
do_check_eq(rph.resolveURI(uri), thistarget);
|
||||
var uri = gIOS.newURI("resource://" + namespace, null, null);
|
||||
dump("### checking for " + target + ", getting " + rph.resolveURI(uri) + "\n");
|
||||
do_check_eq(rph.resolveURI(uri), target);
|
||||
}
|
||||
catch (ex) {
|
||||
dump(ex + "\n");
|
||||
do_throw(namespace);
|
||||
}
|
||||
}
|
||||
|
@ -107,9 +107,8 @@ function test_failed_mapping(namespace)
|
|||
function run_test()
|
||||
{
|
||||
var data = gIOS.newFileURI(do_get_file("chrome/test/unit/data")).spec;
|
||||
test_succeeded_mapping("test1", data + "test1");
|
||||
test_succeeded_mapping("test2", "http://www.mozilla.org");
|
||||
test_succeeded_mapping("test3", "jar:" + data + "test3.jar!/resources");
|
||||
test_succeeded_mapping("test1", data + "test1/");
|
||||
test_succeeded_mapping("test3", "jar:" + data + "test3.jar!/resources/");
|
||||
test_failed_mapping("test4");
|
||||
test_succeeded_mapping("test5", data + "test5");
|
||||
test_succeeded_mapping("test5", data + "test5/");
|
||||
}
|
||||
|
|
|
@ -0,0 +1,98 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* vim: sw=2 ts=2 sts=2 tw=78 expandtab :
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Chrome Registration Test Code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Mozilla Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2008
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Shawn Wilsher <me@shawnwilsher.com> (Original Author)
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
let manifests = [
|
||||
do_get_file("chrome/test/unit/data/test_data_protocol_registration.manifest"),
|
||||
];
|
||||
registerManifests(manifests);
|
||||
|
||||
let XULAppInfoFactory = {
|
||||
// These two are used when we register all our factories (and unregister)
|
||||
CID: XULAPPINFO_CID,
|
||||
scheme: "XULAppInfo",
|
||||
contractID: XULAPPINFO_CONTRACTID,
|
||||
createInstance: function (outer, iid) {
|
||||
if (outer != null)
|
||||
throw Cr.NS_ERROR_NO_AGGREGATION;
|
||||
return XULAppInfo.QueryInterface(iid);
|
||||
}
|
||||
};
|
||||
|
||||
function run_test()
|
||||
{
|
||||
// Add our XULAppInfo factory
|
||||
let factories = [XULAppInfoFactory];
|
||||
|
||||
// Register our factories
|
||||
for (let i = 0; i < factories.length; i++) {
|
||||
let factory = factories[i];
|
||||
Components.manager.QueryInterface(Ci.nsIComponentRegistrar)
|
||||
.registerFactory(factory.CID, "test-" + factory.scheme,
|
||||
factory.contractID, factory);
|
||||
}
|
||||
|
||||
// Check for new chrome
|
||||
let cr = Cc["@mozilla.org/chrome/chrome-registry;1"].
|
||||
getService(Ci.nsIChromeRegistry);
|
||||
cr.checkForNewChrome();
|
||||
|
||||
// Check that our override worked
|
||||
let expectedURI = "data:application/vnd.mozilla.xul+xml,";
|
||||
let sourceURI = "chrome://good-package/content/test.xul";
|
||||
try {
|
||||
let ios = Cc["@mozilla.org/network/io-service;1"].
|
||||
getService(Ci.nsIIOService);
|
||||
sourceURI = ios.newURI(sourceURI, null, null);
|
||||
// this throws for packages that are not registered
|
||||
let uri = cr.convertChromeURL(sourceURI).spec;
|
||||
|
||||
do_check_eq(expectedURI, uri);
|
||||
}
|
||||
catch (e) {
|
||||
dump(e + "\n");
|
||||
do_throw("Should have registered our URI!");
|
||||
}
|
||||
|
||||
// Unregister our factories so we do not leak
|
||||
for (let i = 0; i < factories.length; i++) {
|
||||
let factory = factories[i];
|
||||
Components.manager.QueryInterface(Ci.nsIComponentRegistrar)
|
||||
.unregisterFactory(factory.CID, factory);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,244 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* vim: sw=2 ts=2 sts=2 tw=78 expandtab :
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Chrome Registration Test Code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Mozilla Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2008
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Shawn Wilsher <me@shawnwilsher.com> (Original Author)
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
let manifests = [
|
||||
do_get_file("chrome/test/unit/data/test_no_remote_registration.manifest"),
|
||||
];
|
||||
registerManifests(manifests);
|
||||
|
||||
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
||||
let XULAppInfo = {
|
||||
vendor: "Mozilla",
|
||||
name: "XPCShell",
|
||||
ID: "{39885e5f-f6b4-4e2a-87e5-6259ecf79011}",
|
||||
version: "5",
|
||||
appBuildID: "2007010101",
|
||||
platformVersion: "1.9",
|
||||
platformBuildID: "2007010101",
|
||||
inSafeMode: false,
|
||||
logConsoleErrors: true,
|
||||
OS: "XPCShell",
|
||||
XPCOMABI: "noarch-spidermonkey",
|
||||
QueryInterface: XPCOMUtils.generateQI([
|
||||
Ci.nsIXULAppInfo,
|
||||
Ci.nsIXULRuntime,
|
||||
])
|
||||
};
|
||||
|
||||
let XULAppInfoFactory = {
|
||||
// These two are used when we register all our factories (and unregister)
|
||||
CID: XULAPPINFO_CID,
|
||||
scheme: "XULAppInfo",
|
||||
contractID: XULAPPINFO_CONTRACTID,
|
||||
createInstance: function (outer, iid) {
|
||||
if (outer != null)
|
||||
throw Cr.NS_ERROR_NO_AGGREGATION;
|
||||
return XULAppInfo.QueryInterface(iid);
|
||||
}
|
||||
};
|
||||
|
||||
function ProtocolHandler(aScheme, aFlags)
|
||||
{
|
||||
this.scheme = aScheme;
|
||||
this.protocolFlags = aFlags;
|
||||
this.contractID = "@mozilla.org/network/protocol;1?name=" + aScheme;
|
||||
}
|
||||
|
||||
ProtocolHandler.prototype =
|
||||
{
|
||||
defaultPort: -1,
|
||||
allowPort: function() false,
|
||||
newURI: function(aSpec, aCharset, aBaseURI)
|
||||
{
|
||||
let uri = Cc["@mozilla.org/network/standard-url;1"].
|
||||
createInstance(Ci.nsIURI);
|
||||
uri.spec = aSpec;
|
||||
if (!uri.scheme) {
|
||||
// We got a partial uri, so let's resolve it with the base one
|
||||
uri.spec = aBaseURI.resolve(aSpec);
|
||||
}
|
||||
return uri;
|
||||
},
|
||||
newChannel: function() { throw Cr.NS_ERROR_NOT_IMPLEMENTED },
|
||||
QueryInterface: XPCOMUtils.generateQI([
|
||||
Ci.nsIProtocolHandler
|
||||
])
|
||||
};
|
||||
|
||||
let testProtocols = [
|
||||
// It doesn't matter if it has this flag - the only flag we accept is
|
||||
// URI_IS_LOCAL_RESOURCE.
|
||||
{scheme: "moz-protocol-ui-resource",
|
||||
flags: Ci.nsIProtocolHandler.URI_IS_UI_RESOURCE,
|
||||
CID: Components.ID("{d6dedc93-558f-44fe-90f4-3b4bba8a0b14}"),
|
||||
shouldRegister: false
|
||||
},
|
||||
// It doesn't matter if it has this flag - the only flag we accept is
|
||||
// URI_IS_LOCAL_RESOURCE.
|
||||
{scheme: "moz-protocol-local-file",
|
||||
flags: Ci.nsIProtocolHandler.URI_IS_LOCAL_FILE,
|
||||
CID: Components.ID("{ee30d594-0a2d-4f47-89cc-d4cde320ab69}"),
|
||||
shouldRegister: false
|
||||
},
|
||||
// This clearly is non-local
|
||||
{scheme: "moz-protocol-loadable-by-anyone",
|
||||
flags: Ci.nsIProtocolHandler.URI_LOADABLE_BY_ANYONE,
|
||||
CID: Components.ID("{c3735f23-3b0c-4a33-bfa0-79436dcd40b2}"),
|
||||
shouldRegister: false
|
||||
},
|
||||
// This should always be last (unless we add more flags that are OK)
|
||||
{scheme: "moz-protocol-local-resource",
|
||||
flags: Ci.nsIProtocolHandler.URI_IS_LOCAL_RESOURCE,
|
||||
CID: Components.ID("{b79e977c-f840-469a-b413-0125cc1b62a5}"),
|
||||
shouldRegister: true
|
||||
},
|
||||
];
|
||||
function run_test()
|
||||
{
|
||||
// Create factories
|
||||
let factories = [];
|
||||
for (let i = 0; i < testProtocols.length; i++) {
|
||||
factories[i] = {
|
||||
scheme: testProtocols[i].scheme,
|
||||
flags: testProtocols[i].flags,
|
||||
CID: testProtocols[i].CID,
|
||||
contractID: "@mozilla.org/network/protocol;1?name=" + testProtocols[i].scheme,
|
||||
createInstance: function(aOuter, aIID)
|
||||
{
|
||||
if (aOuter != null)
|
||||
throw Cr.NS_ERROR_NO_AGGREGATION;
|
||||
let handler = new ProtocolHandler(this.scheme, this.flags, this.CID);
|
||||
return handler.QueryInterface(aIID);
|
||||
}
|
||||
};
|
||||
}
|
||||
// Add our XULAppInfo factory
|
||||
factories.push(XULAppInfoFactory);
|
||||
|
||||
// Register our factories
|
||||
for (let i = 0; i < factories.length; i++) {
|
||||
let factory = factories[i];
|
||||
Components.manager.QueryInterface(Ci.nsIComponentRegistrar)
|
||||
.registerFactory(factory.CID, "test-" + factory.scheme,
|
||||
factory.contractID, factory);
|
||||
}
|
||||
|
||||
// Check for new chrome
|
||||
let cr = Cc["@mozilla.org/chrome/chrome-registry;1"].
|
||||
getService(Ci.nsIChromeRegistry);
|
||||
cr.checkForNewChrome();
|
||||
|
||||
// See if our various things were able to register
|
||||
let registrationTypes = [
|
||||
"content",
|
||||
"locale",
|
||||
"skin",
|
||||
"override",
|
||||
"resource",
|
||||
];
|
||||
for (let i = 0; i < testProtocols.length; i++) {
|
||||
let protocol = testProtocols[i];
|
||||
for (let j = 0; j < registrationTypes.length; j++) {
|
||||
let type = registrationTypes[j];
|
||||
dump("Testing protocol '" + protocol.scheme + "' with type '" + type +
|
||||
"'\n");
|
||||
let expectedURI = protocol.scheme + "://foo/";
|
||||
let sourceURI = "chrome://" + protocol.scheme + "/" + type + "/";
|
||||
switch (type) {
|
||||
case "content":
|
||||
expectedURI += protocol.scheme + ".xul";
|
||||
break;
|
||||
case "locale":
|
||||
expectedURI += protocol.scheme + ".dtd";
|
||||
break;
|
||||
case "skin":
|
||||
expectedURI += protocol.scheme + ".css";
|
||||
break;
|
||||
case "override":
|
||||
sourceURI = "chrome://good-package/content/override-" +
|
||||
protocol.scheme + ".xul";
|
||||
break;
|
||||
case "resource":
|
||||
sourceURI = "resource://" + protocol.scheme + "/";
|
||||
break;
|
||||
};
|
||||
try {
|
||||
let ios = Cc["@mozilla.org/network/io-service;1"].
|
||||
getService(Ci.nsIIOService);
|
||||
sourceURI = ios.newURI(sourceURI, null, null);
|
||||
let uri;
|
||||
if (type == "resource") {
|
||||
// resources go about a slightly different way than everything else
|
||||
let rph = ios.getProtocolHandler("resource").
|
||||
QueryInterface(Ci.nsIResProtocolHandler);
|
||||
// this throws for packages that are not registered
|
||||
uri = rph.resolveURI(sourceURI);
|
||||
}
|
||||
else {
|
||||
// this throws for packages that are not registered
|
||||
uri = cr.convertChromeURL(sourceURI).spec;
|
||||
}
|
||||
|
||||
if (protocol.shouldRegister) {
|
||||
do_check_eq(expectedURI, uri);
|
||||
}
|
||||
else {
|
||||
// Overrides will not throw, so we'll get to here. We want to make
|
||||
// sure that the two strings are not the same in this situation.
|
||||
do_check_neq(expectedURI, uri);
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
if (protocol.shouldRegister) {
|
||||
dump(e + "\n");
|
||||
do_throw("Should have registered our URI for protocol " +
|
||||
protocol.scheme);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Unregister our factories so we do not leak
|
||||
for (let i = 0; i < factories.length; i++) {
|
||||
let factory = factories[i];
|
||||
Components.manager.QueryInterface(Ci.nsIComponentRegistrar)
|
||||
.unregisterFactory(factory.CID, factory);
|
||||
}
|
||||
}
|
|
@ -9705,6 +9705,12 @@ nsClassifierCallback::Run()
|
|||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (hasFlags) return NS_OK;
|
||||
|
||||
rv = NS_URIChainHasFlags(uri,
|
||||
nsIProtocolHandler::URI_IS_LOCAL_RESOURCE,
|
||||
&hasFlags);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (hasFlags) return NS_OK;
|
||||
|
||||
nsCOMPtr<nsIURIClassifier> uriClassifier =
|
||||
do_GetService(NS_URICLASSIFIERSERVICE_CONTRACTID, &rv);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
|
|
@ -81,9 +81,10 @@ NS_IMETHODIMP nsIconProtocolHandler::AllowPort(PRInt32 port, const char *scheme,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsIconProtocolHandler::GetProtocolFlags(PRUint32 *result)
|
||||
NS_IMETHODIMP nsIconProtocolHandler::GetProtocolFlags(PRUint32 *result)
|
||||
{
|
||||
*result = URI_NORELATIVE | URI_NOAUTH | URI_IS_UI_RESOURCE;
|
||||
*result = URI_NORELATIVE | URI_NOAUTH | URI_IS_UI_RESOURCE |
|
||||
URI_IS_LOCAL_RESOURCE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -221,7 +221,14 @@ interface nsIProtocolHandler : nsISupports
|
|||
* do not return any data that we can use.
|
||||
*/
|
||||
const unsigned long URI_DOES_NOT_RETURN_DATA = (1<<11);
|
||||
|
||||
|
||||
/**
|
||||
* URIs for this protocol are considered to be local resources. This could
|
||||
* be a local file (URI_IS_LOCAL_FILE), a UI resource (URI_IS_UI_RESOURCE),
|
||||
* or something else that would not hit the network.
|
||||
*/
|
||||
const unsigned long URI_IS_LOCAL_RESOURCE = (1<<12);
|
||||
|
||||
/**
|
||||
* This protocol handler can be proxied via a proxy (socks or http)
|
||||
* (e.g., irc, smtp, http, etc.). If the protocol supports transparent
|
||||
|
|
|
@ -91,7 +91,7 @@ nsDataHandler::GetDefaultPort(PRInt32 *result) {
|
|||
NS_IMETHODIMP
|
||||
nsDataHandler::GetProtocolFlags(PRUint32 *result) {
|
||||
*result = URI_NORELATIVE | URI_NOAUTH | URI_INHERITS_SECURITY_CONTEXT |
|
||||
URI_LOADABLE_BY_ANYONE | URI_NON_PERSISTABLE;
|
||||
URI_LOADABLE_BY_ANYONE | URI_NON_PERSISTABLE | URI_IS_LOCAL_RESOURCE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -251,7 +251,7 @@ nsFileProtocolHandler::GetDefaultPort(PRInt32 *result)
|
|||
NS_IMETHODIMP
|
||||
nsFileProtocolHandler::GetProtocolFlags(PRUint32 *result)
|
||||
{
|
||||
*result = URI_NOAUTH | URI_IS_LOCAL_FILE;
|
||||
*result = URI_NOAUTH | URI_IS_LOCAL_FILE | URI_IS_LOCAL_RESOURCE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -215,7 +215,7 @@ nsResProtocolHandler::GetProtocolFlags(PRUint32 *result)
|
|||
{
|
||||
// XXXbz Is this really true for all resource: URIs? Could we
|
||||
// somehow give different flags to some of them?
|
||||
*result = URI_STD | URI_IS_UI_RESOURCE;
|
||||
*result = URI_STD | URI_IS_UI_RESOURCE | URI_IS_LOCAL_RESOURCE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -87,7 +87,8 @@ nsAnnoProtocolHandler::GetDefaultPort(PRInt32 *aDefaultPort)
|
|||
NS_IMETHODIMP
|
||||
nsAnnoProtocolHandler::GetProtocolFlags(PRUint32 *aProtocolFlags)
|
||||
{
|
||||
*aProtocolFlags = (URI_NORELATIVE | URI_NOAUTH | URI_DANGEROUS_TO_LOAD);
|
||||
*aProtocolFlags = (URI_NORELATIVE | URI_NOAUTH | URI_DANGEROUS_TO_LOAD |
|
||||
URI_IS_LOCAL_RESOURCE);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче