Bug 1242961 - nsStandardURL still allows to build valid nsIURIs longer than network.standard-url.max-length. r=valentin

--HG--
extra : commitid : LhDNkRzmNnu
extra : rebase_source : ccd91b21929bf9a8ccc945c3a524d47eef98294f
This commit is contained in:
Marco Bonardo 2016-01-26 17:23:22 +01:00
parent fed7bf0616
commit c6747b6e30
2 changed files with 87 additions and 35 deletions

View File

@ -991,6 +991,8 @@ NS_INTERFACE_MAP_END
NS_IMETHODIMP
nsStandardURL::GetSpec(nsACString &result)
{
MOZ_ASSERT(mSpec.Length() <= (uint32_t) net_GetURLMaxLength(),
"The spec should never be this long, we missed a check.");
result = mSpec;
return NS_OK;
}
@ -1279,6 +1281,10 @@ nsStandardURL::SetScheme(const nsACString &input)
return NS_ERROR_UNEXPECTED;
}
if (mSpec.Length() + input.Length() - Scheme().Length() > (uint32_t) net_GetURLMaxLength()) {
return NS_ERROR_MALFORMED_URI;
}
InvalidateCache();
int32_t shift = ReplaceSegment(mScheme.mPos, mScheme.mLen, scheme);
@ -1316,6 +1322,10 @@ nsStandardURL::SetUserPass(const nsACString &input)
return NS_ERROR_NOT_INITIALIZED;
}
if (mSpec.Length() + input.Length() - Userpass(true).Length() > (uint32_t) net_GetURLMaxLength()) {
return NS_ERROR_MALFORMED_URI;
}
InvalidateCache();
if (userpass.IsEmpty()) {
@ -1416,6 +1426,10 @@ nsStandardURL::SetUsername(const nsACString &input)
if (username.IsEmpty())
return SetUserPass(username);
if (mSpec.Length() + input.Length() - Username().Length() > (uint32_t) net_GetURLMaxLength()) {
return NS_ERROR_MALFORMED_URI;
}
InvalidateCache();
// escape username if necessary
@ -1462,6 +1476,10 @@ nsStandardURL::SetPassword(const nsACString &input)
return NS_ERROR_FAILURE;
}
if (mSpec.Length() + input.Length() - Password().Length() > (uint32_t) net_GetURLMaxLength()) {
return NS_ERROR_MALFORMED_URI;
}
InvalidateCache();
if (password.IsEmpty()) {
@ -1624,6 +1642,10 @@ nsStandardURL::SetHost(const nsACString &input)
if (strchr(host, ' '))
return NS_ERROR_MALFORMED_URI;
if (mSpec.Length() + strlen(host) - Host().Length() > (uint32_t) net_GetURLMaxLength()) {
return NS_ERROR_MALFORMED_URI;
}
InvalidateCache();
mHostEncoding = eEncoding_ASCII;
@ -1672,7 +1694,7 @@ nsStandardURL::SetHost(const nsACString &input)
return NS_OK;
}
NS_IMETHODIMP
nsStandardURL::SetPort(int32_t port)
{
@ -2432,6 +2454,10 @@ nsStandardURL::SetQuery(const nsACString &input)
if (mPath.mLen < 0)
return SetPath(flat);
if (mSpec.Length() + input.Length() - Query().Length() > (uint32_t) net_GetURLMaxLength()) {
return NS_ERROR_MALFORMED_URI;
}
InvalidateCache();
if (!query || !*query) {
@ -2504,6 +2530,10 @@ nsStandardURL::SetRef(const nsACString &input)
if (mPath.mLen < 0)
return SetPath(flat);
if (mSpec.Length() + input.Length() - Ref().Length() > (uint32_t) net_GetURLMaxLength()) {
return NS_ERROR_MALFORMED_URI;
}
InvalidateCache();
if (!ref || !*ref) {
@ -2572,6 +2602,10 @@ nsStandardURL::SetFileName(const nsACString &input)
if (mPath.mLen < 0)
return SetPath(flat);
if (mSpec.Length() + input.Length() - Filename().Length() > (uint32_t) net_GetURLMaxLength()) {
return NS_ERROR_MALFORMED_URI;
}
int32_t shift = 0;
if (!(filename && *filename)) {
@ -2997,6 +3031,8 @@ nsStandardURL::Read(nsIObjectInputStream *stream)
NS_IMETHODIMP
nsStandardURL::Write(nsIObjectOutputStream *stream)
{
MOZ_ASSERT(mSpec.Length() <= (uint32_t) net_GetURLMaxLength(),
"The spec should never be this long, we missed a check.");
nsresult rv;
rv = stream->Write32(mURLType);
@ -3093,6 +3129,8 @@ FromIPCSegment(const mozilla::ipc::StandardURLSegment& aSegment)
void
nsStandardURL::Serialize(URIParams& aParams)
{
MOZ_ASSERT(mSpec.Length() <= (uint32_t) net_GetURLMaxLength(),
"The spec should never be this long, we missed a check.");
StandardURLParams params;
params.urlType() = mURLType;

View File

@ -38,7 +38,7 @@ function pairToURLs(pair) {
return pair.map(stringToURL);
}
function test_setEmptyPath()
add_test(function test_setEmptyPath()
{
var pairs =
[
@ -60,9 +60,10 @@ function test_setEmptyPath()
do_check_eq(provided.spec, target.spec);
symmetricEquality(true, target, provided);
}
}
run_next_test();
});
function test_setQuery()
add_test(function test_setQuery()
{
var pairs =
[
@ -99,10 +100,10 @@ function test_setQuery()
do_check_eq(newProvided.spec, target.spec);
symmetricEquality(true, newProvided, target);
run_next_test();
});
}
function test_setRef()
add_test(function test_setRef()
{
var tests =
[
@ -160,10 +161,11 @@ function test_setRef()
a.ref = ref;
symmetricEquality(true, a, b);
}
}
run_next_test();
});
// Bug 960014 - Make nsStandardURL::SetHost less magical around IPv6
function test_ipv6()
add_test(function test_ipv6()
{
var url = stringToURL("http://example.com");
url.host = "[2001::1]";
@ -180,9 +182,10 @@ function test_ipv6()
do_check_eq(url.host, "2001");
do_check_eq(url.port, 1);
do_check_eq(url.hostPort, "2001:1");
}
run_next_test();
});
function test_ipv6_fail()
add_test(function test_ipv6_fail()
{
var url = stringToURL("http://example.com");
@ -206,9 +209,10 @@ function test_ipv6_fail()
Assert.throws(() => { url.hostPort = ""; }, "Empty hostPort should fail");
Assert.throws(() => { url.hostPort = "[2001::1]:"; }, "missing port number");
Assert.throws(() => { url.hostPort = "[2001::1]:bad"; }, "bad port number");
}
run_next_test();
});
function test_clearedSpec()
add_test(function test_clearedSpec()
{
var url = stringToURL("http://example.com/path");
Assert.throws(() => { url.spec = "http: example"; }, "set bad spec");
@ -218,9 +222,10 @@ function test_clearedSpec()
var ref = stringToURL("http://allizom.org/path");
symmetricEquality(true, url, ref);
}
run_next_test();
});
function test_escapeBrackets()
add_test(function test_escapeBrackets()
{
// Query
var url = stringToURL("http://example.com/?a[x]=1");
@ -241,18 +246,19 @@ function test_escapeBrackets()
url = stringToURL("http://example.com/a%5Bx%5D/test");
do_check_eq(url.spec, "http://example.com/a%5Bx%5D/test");
run_next_test();
});
}
function test_apostropheEncoding()
add_test(function test_apostropheEncoding()
{
// For now, single quote is escaped everywhere _except_ the path.
// This policy is controlled by the bitmask in nsEscape.cpp::EscapeChars[]
var url = stringToURL("http://example.com/dir'/file'.ext'");
do_check_eq(url.spec, "http://example.com/dir'/file'.ext'");
}
run_next_test();
});
function test_accentEncoding()
add_test(function test_accentEncoding()
{
var url = stringToURL("http://example.com/?hello=`");
do_check_eq(url.spec, "http://example.com/?hello=`");
@ -261,9 +267,10 @@ function test_accentEncoding()
url = stringToURL("http://example.com/?hello=%2C");
do_check_eq(url.spec, "http://example.com/?hello=%2C");
do_check_eq(url.query, "hello=%2C");
}
run_next_test();
});
function test_percentDecoding()
add_test(function test_percentDecoding()
{
var url = stringToURL("http://%70%61%73%74%65%62%69%6E.com");
do_check_eq(url.spec, "http://pastebin.com/");
@ -271,18 +278,25 @@ function test_percentDecoding()
// We shouldn't unescape characters that are not allowed in the hostname.
url = stringToURL("http://example.com%0a%23.google.com/");
do_check_eq(url.spec, "http://example.com%0a%23.google.com/");
}
run_next_test();
});
function run_test()
add_test(function test_hugeStringThrows()
{
test_setEmptyPath();
test_setQuery();
test_setRef();
test_ipv6();
test_ipv6_fail();
test_clearedSpec();
test_escapeBrackets();
test_apostropheEncoding();
test_accentEncoding();
test_percentDecoding();
}
let prefs = Cc["@mozilla.org/preferences-service;1"]
.getService(Ci.nsIPrefService);
let maxLen = prefs.getIntPref("network.standard-url.max-length");
let url = stringToURL("http://test:test@example.com");
let hugeString = new Array(maxLen + 1).fill("a").join("");
let properties = ["spec", "scheme", "userPass", "username",
"password", "hostPort", "host", "path", "ref",
"query", "fileName", "filePath", "fileBaseName", "fileExtension"];
for (let prop of properties) {
Assert.throws(() => url[prop] = hugeString,
/NS_ERROR_MALFORMED_URI/,
`Passing a huge string to "${prop}" should throw`);
}
run_next_test();
});