mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-28 23:31:56 +00:00
Bug 1186152 - Implement nsIProtocolHandlerWithDynamicFlags and use it for moz-extension. r=bz
This commit is contained in:
parent
6fdff0800a
commit
4fefff8e42
@ -761,16 +761,6 @@ nsScriptSecurityManager::CheckLoadURIWithPrincipal(nsIPrincipal* aPrincipal,
|
||||
// the methods that work on chains of nested URIs and they will only look
|
||||
// at the flags for our one URI.
|
||||
|
||||
// Special case: moz-extension has a whitelist of URIs that are loadable by
|
||||
// anyone.
|
||||
if (targetScheme.EqualsLiteral("moz-extension") && GetAddonPolicyService()) {
|
||||
bool loadable = false;
|
||||
rv = GetAddonPolicyService()->ExtensionURILoadableByAnyone(targetBaseURI, &loadable);
|
||||
if (NS_SUCCEEDED(rv) && loadable) {
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
// Check for system target URI
|
||||
rv = DenyAccessIfURIHasFlags(targetBaseURI,
|
||||
nsIProtocolHandler::URI_DANGEROUS_TO_LOAD);
|
||||
|
@ -104,7 +104,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1161831
|
||||
} catch (e) {
|
||||
ifr.remove();
|
||||
threw = true;
|
||||
ok(/denied|insecure/.test(e), "exceiton correct: " + e);
|
||||
ok(/denied|insecure/.test(e), "exception correct: " + e);
|
||||
}
|
||||
is(threw, !!shouldThrow, "Correct throwing behavior for: " + url);
|
||||
!threw || resolve();
|
||||
|
@ -557,6 +557,9 @@ nsIOService::GetProtocolFlags(const char* scheme, uint32_t *flags)
|
||||
nsresult rv = GetProtocolHandler(scheme, getter_AddRefs(handler));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
// We can't call DoGetProtocolFlags here because we don't have a URI. This
|
||||
// API is used by (and only used by) extensions, which is why it's still
|
||||
// around. Calling this on a scheme with dynamic flags will throw.
|
||||
rv = handler->GetProtocolFlags(flags);
|
||||
return rv;
|
||||
}
|
||||
@ -722,7 +725,7 @@ nsIOService::NewChannelFromURIWithProxyFlagsInternal(nsIURI* aURI,
|
||||
return rv;
|
||||
|
||||
uint32_t protoFlags;
|
||||
rv = handler->GetProtocolFlags(&protoFlags);
|
||||
rv = handler->DoGetProtocolFlags(aURI, &protoFlags);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
@ -1481,15 +1484,17 @@ nsIOService::ProtocolHasFlags(nsIURI *uri,
|
||||
nsAutoCString scheme;
|
||||
nsresult rv = uri->GetScheme(scheme);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
uint32_t protocolFlags;
|
||||
rv = GetProtocolFlags(scheme.get(), &protocolFlags);
|
||||
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
*result = (protocolFlags & flags) == flags;
|
||||
}
|
||||
|
||||
return rv;
|
||||
// Grab the protocol flags from the URI.
|
||||
uint32_t protocolFlags;
|
||||
nsCOMPtr<nsIProtocolHandler> handler;
|
||||
rv = GetProtocolHandler(scheme.get(), getter_AddRefs(handler));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = handler->DoGetProtocolFlags(uri, &protocolFlags);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
*result = (protocolFlags & flags) == flags;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -5,14 +5,34 @@
|
||||
|
||||
#include "nsISupports.idl"
|
||||
|
||||
%{C++
|
||||
#include "nsCOMPtr.h"
|
||||
%}
|
||||
|
||||
interface nsIURI;
|
||||
interface nsIChannel;
|
||||
interface nsILoadInfo;
|
||||
|
||||
/**
|
||||
* nsIProtocolHandlerWithDynamicFlags
|
||||
*
|
||||
* Protocols that wish to return different flags depending on the URI should
|
||||
* implement this interface.
|
||||
*/
|
||||
[scriptable, builtinclass, uuid(65a8e823-0591-4fc0-a56a-03265e0a4ce8)]
|
||||
interface nsIProtocolHandlerWithDynamicFlags : nsISupports
|
||||
{
|
||||
/*
|
||||
* Returns protocol flags for the given URI, which may be different from the
|
||||
* flags for another URI of the same scheme.
|
||||
*/
|
||||
unsigned long getFlagsForURI(in nsIURI aURI);
|
||||
};
|
||||
|
||||
/**
|
||||
* nsIProtocolHandler
|
||||
*/
|
||||
[scriptable, uuid(a7aad716-e72c-435d-82f1-7582dffae661)]
|
||||
[scriptable, uuid(3393c327-ce70-47f1-9be3-cc312e21c012)]
|
||||
interface nsIProtocolHandler : nsISupports
|
||||
{
|
||||
/**
|
||||
@ -32,6 +52,15 @@ interface nsIProtocolHandler : nsISupports
|
||||
*/
|
||||
readonly attribute unsigned long protocolFlags;
|
||||
|
||||
%{C++
|
||||
// Helper method to get the protocol flags in the right way.
|
||||
nsresult DoGetProtocolFlags(nsIURI* aURI, uint32_t* aFlags)
|
||||
{
|
||||
nsCOMPtr<nsIProtocolHandlerWithDynamicFlags> dh = do_QueryInterface(this);
|
||||
return dh ? dh->GetFlagsForURI(aURI, aFlags) : GetProtocolFlags(aFlags);
|
||||
}
|
||||
%}
|
||||
|
||||
/**
|
||||
* Makes a URI object that is suitable for loading by this protocol,
|
||||
* where the URI string is given as an UTF-8 string. The caller may
|
||||
@ -258,8 +287,6 @@ interface nsIProtocolHandler : nsISupports
|
||||
* by nsMixedContentBlocker
|
||||
*/
|
||||
const unsigned long URI_SAFE_TO_LOAD_IN_SECURE_CONTEXT = (1<<18);
|
||||
|
||||
|
||||
};
|
||||
|
||||
%{C++
|
||||
|
@ -1663,7 +1663,7 @@ nsProtocolProxyService::GetProtocolInfo(nsIURI *uri, nsProtocolInfo *info)
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
rv = handler->GetProtocolFlags(&info->flags);
|
||||
rv = handler->DoGetProtocolFlags(uri, &info->flags);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
|
@ -6,11 +6,31 @@
|
||||
|
||||
#include "ExtensionProtocolHandler.h"
|
||||
|
||||
#include "nsIAddonPolicyService.h"
|
||||
#include "nsServiceManagerUtils.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
NS_IMPL_QUERY_INTERFACE(ExtensionProtocolHandler, nsISubstitutingProtocolHandler,
|
||||
nsIProtocolHandler, nsISupportsWeakReference)
|
||||
nsIProtocolHandler, nsIProtocolHandlerWithDynamicFlags,
|
||||
nsISupportsWeakReference)
|
||||
NS_IMPL_ADDREF_INHERITED(ExtensionProtocolHandler, SubstitutingProtocolHandler)
|
||||
NS_IMPL_RELEASE_INHERITED(ExtensionProtocolHandler, SubstitutingProtocolHandler)
|
||||
|
||||
nsresult
|
||||
ExtensionProtocolHandler::GetFlagsForURI(nsIURI* aURI, uint32_t* aFlags)
|
||||
{
|
||||
// In general a moz-extension URI is only loadable by chrome, but a whitelisted
|
||||
// subset are web-accessible. Check that whitelist.
|
||||
nsCOMPtr<nsIAddonPolicyService> aps = do_GetService("@mozilla.org/addons/policy-service;1");
|
||||
bool loadableByAnyone = false;
|
||||
if (aps) {
|
||||
nsresult rv = aps->ExtensionURILoadableByAnyone(aURI, &loadableByAnyone);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
*aFlags = URI_STD | URI_IS_LOCAL_RESOURCE | (loadableByAnyone ? URI_LOADABLE_BY_ANYONE : URI_DANGEROUS_TO_LOAD);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
|
@ -12,19 +12,17 @@
|
||||
namespace mozilla {
|
||||
|
||||
class ExtensionProtocolHandler final : public nsISubstitutingProtocolHandler,
|
||||
public nsIProtocolHandlerWithDynamicFlags,
|
||||
public mozilla::SubstitutingProtocolHandler,
|
||||
public nsSupportsWeakReference
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_NSIPROTOCOLHANDLERWITHDYNAMICFLAGS
|
||||
NS_FORWARD_NSIPROTOCOLHANDLER(mozilla::SubstitutingProtocolHandler::)
|
||||
NS_FORWARD_NSISUBSTITUTINGPROTOCOLHANDLER(mozilla::SubstitutingProtocolHandler::)
|
||||
|
||||
// In general a moz-extension URI is only loadable by chrome, but a whitelisted
|
||||
// subset are web-accessible (see nsIAddonPolicyService).
|
||||
ExtensionProtocolHandler()
|
||||
: SubstitutingProtocolHandler("moz-extension", URI_STD | URI_DANGEROUS_TO_LOAD | URI_IS_LOCAL_RESOURCE)
|
||||
{}
|
||||
ExtensionProtocolHandler() : SubstitutingProtocolHandler("moz-extension") {}
|
||||
|
||||
protected:
|
||||
~ExtensionProtocolHandler() {}
|
||||
|
@ -84,9 +84,23 @@ SubstitutingURL::GetClassIDNoAlloc(nsCID *aClassIDNoAlloc)
|
||||
SubstitutingProtocolHandler::SubstitutingProtocolHandler(const char* aScheme, uint32_t aFlags,
|
||||
bool aEnforceFileOrJar)
|
||||
: mScheme(aScheme)
|
||||
, mFlags(aFlags)
|
||||
, mSubstitutions(16)
|
||||
, mEnforceFileOrJar(aEnforceFileOrJar)
|
||||
{
|
||||
mFlags.emplace(aFlags);
|
||||
ConstructInternal();
|
||||
}
|
||||
|
||||
SubstitutingProtocolHandler::SubstitutingProtocolHandler(const char* aScheme)
|
||||
: mScheme(aScheme)
|
||||
, mSubstitutions(16)
|
||||
, mEnforceFileOrJar(true)
|
||||
{
|
||||
ConstructInternal();
|
||||
}
|
||||
|
||||
void
|
||||
SubstitutingProtocolHandler::ConstructInternal()
|
||||
{
|
||||
nsresult rv;
|
||||
mIOService = do_GetIOService(&rv);
|
||||
@ -180,7 +194,12 @@ SubstitutingProtocolHandler::GetDefaultPort(int32_t *result)
|
||||
nsresult
|
||||
SubstitutingProtocolHandler::GetProtocolFlags(uint32_t *result)
|
||||
{
|
||||
*result = mFlags;
|
||||
if (mFlags.isNothing()) {
|
||||
NS_WARNING("Trying to get protocol flags the wrong way - use nsIProtocolHandlerWithDynamicFlags instead");
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
*result = mFlags.ref();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include "nsIOService.h"
|
||||
#include "nsStandardURL.h"
|
||||
#include "mozilla/chrome/RegistryMessageUtils.h"
|
||||
#include "mozilla/Maybe.h"
|
||||
|
||||
class nsIIOService;
|
||||
|
||||
@ -27,6 +28,7 @@ class SubstitutingProtocolHandler
|
||||
{
|
||||
public:
|
||||
SubstitutingProtocolHandler(const char* aScheme, uint32_t aFlags, bool aEnforceFileOrJar = true);
|
||||
explicit SubstitutingProtocolHandler(const char* aScheme);
|
||||
|
||||
NS_INLINE_DECL_REFCOUNTING(SubstitutingProtocolHandler);
|
||||
NS_DECL_NON_VIRTUAL_NSIPROTOCOLHANDLER;
|
||||
@ -36,6 +38,7 @@ public:
|
||||
|
||||
protected:
|
||||
virtual ~SubstitutingProtocolHandler() {}
|
||||
void ConstructInternal();
|
||||
|
||||
void SendSubstitution(const nsACString& aRoot, nsIURI* aBaseURI);
|
||||
|
||||
@ -51,7 +54,7 @@ protected:
|
||||
|
||||
private:
|
||||
nsCString mScheme;
|
||||
uint32_t mFlags;
|
||||
Maybe<uint32_t> mFlags;
|
||||
nsInterfaceHashtable<nsCStringHashKey,nsIURI> mSubstitutions;
|
||||
nsCOMPtr<nsIIOService> mIOService;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user