Bug 1195415 - Add asciiHostPort field to nsIURI, and use it in the implementation of nsPrincipal::GetOriginForURI, r=bholley

This commit is contained in:
Michael Layzell 2015-08-17 15:34:17 -04:00
Родитель 5f0d2e47a6
Коммит 945c9a35f4
14 изменённых файлов: 193 добавлений и 40 удалений

Просмотреть файл

@ -86,6 +86,12 @@ nsNullPrincipalURI::GetAsciiHost(nsACString &_host)
return NS_OK;
}
NS_IMETHODIMP
nsNullPrincipalURI::GetAsciiHostPort(nsACString &_hostport)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsNullPrincipalURI::GetAsciiSpec(nsACString &_spec)
{

Просмотреть файл

@ -111,7 +111,7 @@ nsPrincipal::GetOriginForURI(nsIURI* aURI, nsACString& aOrigin)
return NS_ERROR_FAILURE;
}
nsAutoCString host;
nsAutoCString hostPort;
// chrome: URLs don't have a meaningful origin, so make
// sure we just get the full spec for them.
@ -120,10 +120,10 @@ nsPrincipal::GetOriginForURI(nsIURI* aURI, nsACString& aOrigin)
bool isChrome;
nsresult rv = origin->SchemeIs("chrome", &isChrome);
if (NS_SUCCEEDED(rv) && !isChrome) {
rv = origin->GetAsciiHost(host);
rv = origin->GetAsciiHostPort(hostPort);
// Some implementations return an empty string, treat it as no support
// for asciiHost by that implementation.
if (host.IsEmpty()) {
if (hostPort.IsEmpty()) {
rv = NS_ERROR_FAILURE;
}
}
@ -153,26 +153,7 @@ nsPrincipal::GetOriginForURI(nsIURI* aURI, nsACString& aOrigin)
return NS_OK;
}
int32_t port;
if (NS_SUCCEEDED(rv) && !isChrome) {
rv = origin->GetPort(&port);
}
if (NS_SUCCEEDED(rv) && !isChrome) {
nsAutoCString hostPort;
if (host.FindChar(':') != -1) {
hostPort.Assign("[");
hostPort.Append(host);
hostPort.Append("]");
} else {
hostPort.Assign(host);
}
if (port != -1) {
hostPort.Append(':');
hostPort.AppendInt(port, 10);
}
rv = origin->GetScheme(aOrigin);
NS_ENSURE_SUCCESS(rv, rv);
aOrigin.AppendLiteral("://");

Просмотреть файл

@ -465,6 +465,12 @@ nsMozIconURI::GetAsciiSpec(nsACString& aSpecA)
return GetSpec(aSpecA);
}
NS_IMETHODIMP
nsMozIconURI::GetAsciiHostPort(nsACString& aHostPortA)
{
return GetHostPort(aHostPortA);
}
NS_IMETHODIMP
nsMozIconURI::GetAsciiHost(nsACString& aHostA)
{

Просмотреть файл

@ -45,7 +45,7 @@
* stock images.
*/
[scriptable, uuid(da53adda-cbe3-41bc-a57d-fdd7a0ff448b)]
[scriptable, uuid(f8fe5ef2-5f2b-43f3-857d-5b64d192c427)]
interface nsIMozIconURI : nsIURI
{
/// iconFile: the file URL contained within this moz-icon url, or null.

Просмотреть файл

@ -15,7 +15,7 @@
*
* The nsIURL methods operate on the <jar-entry> part of the spec.
*/
[scriptable, uuid(1ee60719-c056-43b3-8f54-6a6e7ba0ca6c)]
[scriptable, uuid(646a508c-f786-4e14-be6d-8dda2a633c60)]
interface nsIJARURI : nsIURL {
/**

Просмотреть файл

@ -429,6 +429,12 @@ nsJARURI::GetAsciiSpec(nsACString &aSpec)
return GetSpec(aSpec);
}
NS_IMETHODIMP
nsJARURI::GetAsciiHostPort(nsACString &aHostPort)
{
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
nsJARURI::GetAsciiHost(nsACString &aHost)
{

Просмотреть файл

@ -12,7 +12,7 @@ interface nsIFile;
* an URL. The URL scheme need not be file:, since other local protocols may
* map URLs to files (e.g., resource:).
*/
[scriptable, uuid(7750029c-1b0a-414e-8359-a77f24a2a0a6)]
[scriptable, uuid(e91ac988-27c2-448b-b1a1-3822e1ef1987)]
interface nsIFileURL : nsIURL
{
/**

Просмотреть файл

@ -67,7 +67,7 @@
* we will need to add additional checks there for all intermediate IIDs, until
* nsPrincipal is fixed to serialize its URIs as nsISupports (bug 662693).
*/
[scriptable, uuid(395fe045-7d18-4adb-a3fd-af98c8a1af11)]
[scriptable, uuid(92073a54-6d78-4f30-913a-b871813208c6)]
interface nsIURI : nsISupports
{
/************************************************************************
@ -194,6 +194,13 @@ interface nsIURI : nsISupports
*/
readonly attribute ACString asciiSpec;
/**
* The host:port (or simply the host, if port == -1), with an ASCII compatible
* encoding. Host portion follows the IDNA draft spec. The result is strictly
* ASCII.
*/
readonly attribute ACString asciiHostPort;
/**
* The URI host with an ASCII compatible encoding. Follows the IDNA
* draft spec for converting internationalized domain names (UTF-8) to

Просмотреть файл

@ -19,7 +19,7 @@
* |
* filePath
*/
[scriptable, uuid(1419aa16-f134-4154-9886-00c7c5147a13)]
[scriptable, uuid(86adcd89-0b70-47a2-b0fe-5bb2c5f37e31)]
interface nsIURL : nsIURI
{
/*************************************************************************

Просмотреть файл

@ -297,6 +297,7 @@ nsSimpleURI::GetHostPort(nsACString &result)
{
// Note: Audit all callers before changing this to return an empty
// string -- CAPS and UI code may depend on this throwing.
// Note: If this is changed, change GetAsciiHostPort as well.
return NS_ERROR_FAILURE;
}
@ -527,6 +528,13 @@ nsSimpleURI::GetAsciiSpec(nsACString &result)
return NS_OK;
}
NS_IMETHODIMP
nsSimpleURI::GetAsciiHostPort(nsACString &result)
{
// XXX This behavior mimics GetHostPort.
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
nsSimpleURI::GetAsciiHost(nsACString &result)
{

Просмотреть файл

@ -1090,23 +1090,38 @@ nsStandardURL::GetAsciiSpec(nsACString &result)
NS_EscapeURL(Userpass(true), esc_OnlyNonASCII | esc_AlwaysCopy, result);
// get escaped host
nsAutoCString escHostport;
if (mHost.mLen > 0) {
// this doesn't fail
(void) GetAsciiHost(escHostport);
// escHostport = "hostA" + ":port"
uint32_t pos = mHost.mPos + mHost.mLen;
if (pos < mPath.mPos)
escHostport += Substring(mSpec, pos, mPath.mPos - pos);
}
result += escHostport;
// get the hostport
nsAutoCString hostport;
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(GetAsciiHostPort(hostport)));
result += hostport;
NS_EscapeURL(Path(), esc_OnlyNonASCII | esc_AlwaysCopy, result);
return NS_OK;
}
// result is ASCII
NS_IMETHODIMP
nsStandardURL::GetAsciiHostPort(nsACString &result)
{
if (mHostEncoding == eEncoding_ASCII) {
result = Hostport();
return NS_OK;
}
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(GetAsciiHost(result)));
// As our mHostEncoding is not eEncoding_ASCII, we know that
// the our host is not ipv6, and we can avoid looking at it.
MOZ_ASSERT(result.FindChar(':') == -1, "The host must not be ipv6");
// hostport = "hostA" + ":port"
uint32_t pos = mHost.mPos + mHost.mLen;
if (pos < mPath.mPos)
result += Substring(mSpec, pos, mPath.mPos - pos);
return NS_OK;
}
// result is ASCII
NS_IMETHODIMP
nsStandardURL::GetAsciiHost(nsACString &result)

Просмотреть файл

@ -0,0 +1,116 @@
// Test for bug 1195415
function run_test() {
var ios = Cc["@mozilla.org/network/io-service;1"].
getService(Ci.nsIIOService);
var ssm = Cc["@mozilla.org/scriptsecuritymanager;1"].
getService(Ci.nsIScriptSecurityManager);
// NON-UNICODE
var uri = ios.newURI("http://foo.com/file.txt", null, null);
do_check_eq(uri.asciiHostPort, "foo.com");
uri.port = 90;
var prin = ssm.createCodebasePrincipal(uri, {});
do_check_eq(uri.asciiHostPort, "foo.com:90");
do_check_eq(prin.origin, "http://foo.com:90");
uri = ios.newURI("http://foo.com:10/file.txt", null, null);
do_check_eq(uri.asciiHostPort, "foo.com:10");
uri.port = 500;
prin = ssm.createCodebasePrincipal(uri, {});
do_check_eq(uri.asciiHostPort, "foo.com:500");
do_check_eq(prin.origin, "http://foo.com:500");
uri = ios.newURI("http://foo.com:5000/file.txt", null, null);
do_check_eq(uri.asciiHostPort, "foo.com:5000");
uri.port = 20;
prin = ssm.createCodebasePrincipal(uri, {});
do_check_eq(uri.asciiHostPort, "foo.com:20");
do_check_eq(prin.origin, "http://foo.com:20");
uri = ios.newURI("http://foo.com:5000/file.txt", null, null);
do_check_eq(uri.asciiHostPort, "foo.com:5000");
uri.port = -1;
prin = ssm.createCodebasePrincipal(uri, {});
do_check_eq(uri.asciiHostPort, "foo.com");
do_check_eq(prin.origin, "http://foo.com");
uri = ios.newURI("http://foo.com:5000/file.txt", null, null);
do_check_eq(uri.asciiHostPort, "foo.com:5000");
uri.port = 80;
prin = ssm.createCodebasePrincipal(uri, {});
do_check_eq(uri.asciiHostPort, "foo.com");
do_check_eq(prin.origin, "http://foo.com");
// UNICODE
uri = ios.newURI("http://jos\u00e9.example.net.ch/file.txt", null, null);
do_check_eq(uri.asciiHostPort, "xn--jos-dma.example.net.ch");
uri.port = 90;
prin = ssm.createCodebasePrincipal(uri, {});
do_check_eq(uri.asciiHostPort, "xn--jos-dma.example.net.ch:90");
do_check_eq(prin.origin, "http://xn--jos-dma.example.net.ch:90");
uri = ios.newURI("http://jos\u00e9.example.net.ch:10/file.txt", null, null);
do_check_eq(uri.asciiHostPort, "xn--jos-dma.example.net.ch:10");
uri.port = 500;
prin = ssm.createCodebasePrincipal(uri, {});
do_check_eq(uri.asciiHostPort, "xn--jos-dma.example.net.ch:500");
do_check_eq(prin.origin, "http://xn--jos-dma.example.net.ch:500");
uri = ios.newURI("http://jos\u00e9.example.net.ch:5000/file.txt", null, null);
do_check_eq(uri.asciiHostPort, "xn--jos-dma.example.net.ch:5000");
uri.port = 20;
prin = ssm.createCodebasePrincipal(uri, {});
do_check_eq(uri.asciiHostPort, "xn--jos-dma.example.net.ch:20");
do_check_eq(prin.origin, "http://xn--jos-dma.example.net.ch:20");
uri = ios.newURI("http://jos\u00e9.example.net.ch:5000/file.txt", null, null);
do_check_eq(uri.asciiHostPort, "xn--jos-dma.example.net.ch:5000");
uri.port = -1;
prin = ssm.createCodebasePrincipal(uri, {});
do_check_eq(uri.asciiHostPort, "xn--jos-dma.example.net.ch");
do_check_eq(prin.origin, "http://xn--jos-dma.example.net.ch");
uri = ios.newURI("http://jos\u00e9.example.net.ch:5000/file.txt", null, null);
do_check_eq(uri.asciiHostPort, "xn--jos-dma.example.net.ch:5000");
uri.port = 80;
prin = ssm.createCodebasePrincipal(uri, {});
do_check_eq(uri.asciiHostPort, "xn--jos-dma.example.net.ch");
do_check_eq(prin.origin, "http://xn--jos-dma.example.net.ch");
// ipv6
uri = ios.newURI("http://[123:45::678]/file.txt", null, null);
do_check_eq(uri.asciiHostPort, "[123:45::678]");
uri.port = 90;
prin = ssm.createCodebasePrincipal(uri, {});
do_check_eq(uri.asciiHostPort, "[123:45::678]:90");
do_check_eq(prin.origin, "http://[123:45::678]:90");
uri = ios.newURI("http://[123:45::678]:10/file.txt", null, null);
do_check_eq(uri.asciiHostPort, "[123:45::678]:10");
uri.port = 500;
prin = ssm.createCodebasePrincipal(uri, {});
do_check_eq(uri.asciiHostPort, "[123:45::678]:500");
do_check_eq(prin.origin, "http://[123:45::678]:500");
uri = ios.newURI("http://[123:45::678]:5000/file.txt", null, null);
do_check_eq(uri.asciiHostPort, "[123:45::678]:5000");
uri.port = 20;
prin = ssm.createCodebasePrincipal(uri, {});
do_check_eq(uri.asciiHostPort, "[123:45::678]:20");
do_check_eq(prin.origin, "http://[123:45::678]:20");
uri = ios.newURI("http://[123:45::678]:5000/file.txt", null, null);
do_check_eq(uri.asciiHostPort, "[123:45::678]:5000");
uri.port = -1;
prin = ssm.createCodebasePrincipal(uri, {});
do_check_eq(uri.asciiHostPort, "[123:45::678]");
do_check_eq(prin.origin, "http://[123:45::678]");
uri = ios.newURI("http://[123:45::678]:5000/file.txt", null, null);
do_check_eq(uri.asciiHostPort, "[123:45::678]:5000");
uri.port = 80;
prin = ssm.createCodebasePrincipal(uri, {});
do_check_eq(uri.asciiHostPort, "[123:45::678]");
do_check_eq(prin.origin, "http://[123:45::678]");
}

Просмотреть файл

@ -327,3 +327,4 @@ skip-if = os == "android"
[test_dns_disable_ipv4.js]
[test_dns_disable_ipv6.js]
[test_packaged_app_service_paths.js]
[test_bug1195415.js]

Просмотреть файл

@ -917,9 +917,16 @@ nsBinaryInputStream::ReadObject(bool aIsStrongRef, nsISupports** aObject)
{ 0x88, 0xcf, 0x6e, 0x08, 0x76, 0x6e, 0x8b, 0x23 }
};
// hackaround for bug 1195415
static const nsIID oldURIiid4 = {
0x395fe045, 0x7d18, 0x4adb,
{ 0xa3, 0xfd, 0xaf, 0x98, 0xc8, 0xa1, 0xaf, 0x11 }
};
if (iid.Equals(oldURIiid) ||
iid.Equals(oldURIiid2) ||
iid.Equals(oldURIiid3)) {
iid.Equals(oldURIiid3) ||
iid.Equals(oldURIiid4)) {
const nsIID newURIiid = NS_IURI_IID;
iid = newURIiid;
}