mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-17 22:32:51 +00:00
Bug 1461590: Lower-case hostnames when adding substitutions. r=smaug f=dveditz
Since URI hostnames are defined to be case-insensitive, we only ever see lower-case hostnames when looking up substitutions. That means that substitutions containing capital letters are inaccessible, which is a footgun that has hit many people. The handler should lower-case substitutions when they're added so that look-ups are always case-insensitive. MozReview-Commit-ID: C936hS2cSyY --HG-- extra : rebase_source : a70e8ceb822879e51c3a40232b7dffdfb9c0a185
This commit is contained in:
parent
0d7a720986
commit
1ff74da18d
@ -14,6 +14,7 @@
|
||||
#include "nsIFile.h"
|
||||
#include "nsNetCID.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsReadableUtils.h"
|
||||
#include "nsURLHelper.h"
|
||||
#include "nsEscape.h"
|
||||
|
||||
@ -306,8 +307,11 @@ SubstitutingProtocolHandler::SetSubstitution(const nsACString& root, nsIURI *bas
|
||||
}
|
||||
|
||||
nsresult
|
||||
SubstitutingProtocolHandler::SetSubstitutionWithFlags(const nsACString& root, nsIURI *baseURI, uint32_t flags)
|
||||
SubstitutingProtocolHandler::SetSubstitutionWithFlags(const nsACString& origRoot, nsIURI *baseURI, uint32_t flags)
|
||||
{
|
||||
nsAutoCString root;
|
||||
ToLowerCase(origRoot, root);
|
||||
|
||||
if (!baseURI) {
|
||||
mSubstitutions.Remove(root);
|
||||
NotifyObservers(root, baseURI);
|
||||
@ -349,10 +353,13 @@ SubstitutingProtocolHandler::SetSubstitutionWithFlags(const nsACString& root, ns
|
||||
}
|
||||
|
||||
nsresult
|
||||
SubstitutingProtocolHandler::GetSubstitution(const nsACString& root, nsIURI **result)
|
||||
SubstitutingProtocolHandler::GetSubstitution(const nsACString& origRoot, nsIURI **result)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(result);
|
||||
|
||||
nsAutoCString root;
|
||||
ToLowerCase(origRoot, root);
|
||||
|
||||
SubstitutionEntry entry;
|
||||
if (mSubstitutions.Get(root, &entry)) {
|
||||
nsCOMPtr<nsIURI> baseURI = entry.baseURI;
|
||||
@ -367,6 +374,12 @@ SubstitutingProtocolHandler::GetSubstitution(const nsACString& root, nsIURI **re
|
||||
nsresult
|
||||
SubstitutingProtocolHandler::GetSubstitutionFlags(const nsACString& root, uint32_t* flags)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
nsAutoCString lcRoot;
|
||||
ToLowerCase(root, lcRoot);
|
||||
MOZ_ASSERT(root.Equals(lcRoot), "GetSubstitutionFlags should never receive mixed-case root name");
|
||||
#endif
|
||||
|
||||
*flags = 0;
|
||||
SubstitutionEntry entry;
|
||||
if (mSubstitutions.Get(root, &entry)) {
|
||||
@ -379,9 +392,13 @@ SubstitutingProtocolHandler::GetSubstitutionFlags(const nsACString& root, uint32
|
||||
}
|
||||
|
||||
nsresult
|
||||
SubstitutingProtocolHandler::HasSubstitution(const nsACString& root, bool *result)
|
||||
SubstitutingProtocolHandler::HasSubstitution(const nsACString& origRoot, bool *result)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(result);
|
||||
|
||||
nsAutoCString root;
|
||||
ToLowerCase(origRoot, root);
|
||||
|
||||
*result = HasSubstitution(root);
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -25,8 +25,8 @@ interface nsISubstitutingProtocolHandler : nsIProtocolHandler
|
||||
*
|
||||
* A null baseURI removes the specified substitution.
|
||||
*
|
||||
* A root key should always be lowercase; however, this may not be
|
||||
* enforced.
|
||||
* The root key will be converted to lower-case to conform to
|
||||
* case-insensitive URI hostname matching behavior.
|
||||
*/
|
||||
[must_use] void setSubstitution(in ACString root, in nsIURI baseURI);
|
||||
|
||||
|
41
netwerk/test/unit/test_substituting_protocol_handler.js
Normal file
41
netwerk/test/unit/test_substituting_protocol_handler.js
Normal file
@ -0,0 +1,41 @@
|
||||
"use strict";
|
||||
|
||||
ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
add_task(async function test_case_insensitive_substitutions() {
|
||||
let resProto = Services.io.getProtocolHandler("resource")
|
||||
.QueryInterface(Ci.nsISubstitutingProtocolHandler);
|
||||
|
||||
let uri = Services.io.newFileURI(do_get_file("data"));
|
||||
|
||||
resProto.setSubstitution("FooBar", uri);
|
||||
resProto.setSubstitutionWithFlags("BarBaz", uri, 0);
|
||||
|
||||
equal(resProto.resolveURI(Services.io.newURI("resource://foobar/")),
|
||||
uri.spec, "Got correct resolved URI for setSubstitution");
|
||||
|
||||
equal(resProto.resolveURI(Services.io.newURI("resource://foobar/")),
|
||||
uri.spec, "Got correct resolved URI for setSubstitutionWithFlags");
|
||||
|
||||
ok(resProto.hasSubstitution("foobar"), "hasSubstitution works with all-lower-case root");
|
||||
ok(resProto.hasSubstitution("FooBar"), "hasSubstitution works with mixed-case root");
|
||||
|
||||
equal(resProto.getSubstitution("foobar").spec, uri.spec,
|
||||
"getSubstitution works with all-lower-case root");
|
||||
equal(resProto.getSubstitution("FooBar").spec, uri.spec,
|
||||
"getSubstitution works with mixed-case root");
|
||||
|
||||
resProto.setSubstitution("foobar", null);
|
||||
resProto.setSubstitution("barbaz", null);
|
||||
|
||||
Assert.throws(() => resProto.resolveURI(Services.io.newURI("resource://foobar/")),
|
||||
e => e.result == Cr.NS_ERROR_NOT_AVAILABLE,
|
||||
"Correctly unregistered case-insensitive substitution in setSubstitution");
|
||||
Assert.throws(() => resProto.resolveURI(Services.io.newURI("resource://barbaz/")),
|
||||
e => e.result == Cr.NS_ERROR_NOT_AVAILABLE,
|
||||
"Correctly unregistered case-insensitive substitution in setSubstitutionWithFlags");
|
||||
|
||||
Assert.throws(() => resProto.getSubstitution("foobar"),
|
||||
e => e.result == Cr.NS_ERROR_NOT_AVAILABLE,
|
||||
"foobar substitution has been removed");
|
||||
});
|
@ -421,3 +421,4 @@ run-sequentially = node server exceptions dont replay well
|
||||
# http2-using tests require node available
|
||||
skip-if = os == "android"
|
||||
[test_ioservice.js]
|
||||
[test_substituting_protocol_handler.js]
|
||||
|
Loading…
x
Reference in New Issue
Block a user