mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-21 01:05:45 +00:00
69790bc62e
The inclusions were removed with the following very crude script and the resulting breakage was fixed up by hand. The manual fixups did either revert the changes done by the script, replace a generic header with a more specific one or replace a header with a forward declaration. find . -name "*.idl" | grep -v web-platform | grep -v third_party | while read path; do interfaces=$(grep "^\(class\|interface\).*:.*" "$path" | cut -d' ' -f2) if [ -n "$interfaces" ]; then if [[ "$interfaces" == *$'\n'* ]]; then regexp="\(" for i in $interfaces; do regexp="$regexp$i\|"; done regexp="${regexp%%\\\|}\)" else regexp="$interfaces" fi interface=$(basename "$path") rg -l "#include.*${interface%%.idl}.h" . | while read path2; do hits=$(grep -v "#include.*${interface%%.idl}.h" "$path2" | grep -c "$regexp" ) if [ $hits -eq 0 ]; then echo "Removing ${interface} from ${path2}" grep -v "#include.*${interface%%.idl}.h" "$path2" > "$path2".tmp mv -f "$path2".tmp "$path2" fi done fi done Differential Revision: https://phabricator.services.mozilla.com/D55443 --HG-- extra : moz-landing-system : lando
411 lines
12 KiB
C++
411 lines
12 KiB
C++
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
/* vim: set ts=2 sw=2 et tw=78: */
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
#include "nsChromeRegistry.h"
|
|
#include "nsChromeRegistryChrome.h"
|
|
#include "nsChromeRegistryContent.h"
|
|
|
|
#include "nsCOMPtr.h"
|
|
#include "nsError.h"
|
|
#include "nsEscape.h"
|
|
#include "nsNetUtil.h"
|
|
#include "nsString.h"
|
|
#include "nsQueryObject.h"
|
|
|
|
#include "mozilla/dom/URL.h"
|
|
#include "nsIConsoleService.h"
|
|
#include "mozilla/dom/Document.h"
|
|
#include "nsIObserverService.h"
|
|
#include "nsIScriptError.h"
|
|
#include "mozilla/Preferences.h"
|
|
#include "mozilla/PresShell.h"
|
|
#include "mozilla/Printf.h"
|
|
#include "mozilla/StyleSheet.h"
|
|
#include "mozilla/StyleSheetInlines.h"
|
|
#include "mozilla/dom/Location.h"
|
|
|
|
#include "unicode/uloc.h"
|
|
|
|
nsChromeRegistry* nsChromeRegistry::gChromeRegistry;
|
|
|
|
// DO NOT use namespace mozilla; it'll break due to a naming conflict between
|
|
// mozilla::TextRange and a TextRange in OSX headers.
|
|
using mozilla::PresShell;
|
|
using mozilla::StyleSheet;
|
|
using mozilla::dom::Document;
|
|
using mozilla::dom::Location;
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
void nsChromeRegistry::LogMessage(const char* aMsg, ...) {
|
|
nsCOMPtr<nsIConsoleService> console(
|
|
do_GetService(NS_CONSOLESERVICE_CONTRACTID));
|
|
if (!console) return;
|
|
|
|
va_list args;
|
|
va_start(args, aMsg);
|
|
mozilla::SmprintfPointer formatted = mozilla::Vsmprintf(aMsg, args);
|
|
va_end(args);
|
|
if (!formatted) return;
|
|
|
|
console->LogStringMessage(NS_ConvertUTF8toUTF16(formatted.get()).get());
|
|
}
|
|
|
|
void nsChromeRegistry::LogMessageWithContext(nsIURI* aURL, uint32_t aLineNumber,
|
|
uint32_t flags, const char* aMsg,
|
|
...) {
|
|
nsresult rv;
|
|
|
|
nsCOMPtr<nsIConsoleService> console(
|
|
do_GetService(NS_CONSOLESERVICE_CONTRACTID));
|
|
|
|
nsCOMPtr<nsIScriptError> error(do_CreateInstance(NS_SCRIPTERROR_CONTRACTID));
|
|
if (!console || !error) return;
|
|
|
|
va_list args;
|
|
va_start(args, aMsg);
|
|
mozilla::SmprintfPointer formatted = mozilla::Vsmprintf(aMsg, args);
|
|
va_end(args);
|
|
if (!formatted) return;
|
|
|
|
nsCString spec;
|
|
if (aURL) aURL->GetSpec(spec);
|
|
|
|
rv = error->Init(
|
|
NS_ConvertUTF8toUTF16(formatted.get()), NS_ConvertUTF8toUTF16(spec),
|
|
EmptyString(), aLineNumber, 0, flags, "chrome registration",
|
|
false /* from private window */, true /* from chrome context */);
|
|
|
|
if (NS_FAILED(rv)) return;
|
|
|
|
console->LogMessage(error);
|
|
}
|
|
|
|
nsChromeRegistry::~nsChromeRegistry() { gChromeRegistry = nullptr; }
|
|
|
|
NS_INTERFACE_MAP_BEGIN(nsChromeRegistry)
|
|
NS_INTERFACE_MAP_ENTRY(nsIChromeRegistry)
|
|
NS_INTERFACE_MAP_ENTRY(nsIXULChromeRegistry)
|
|
NS_INTERFACE_MAP_ENTRY(nsIToolkitChromeRegistry)
|
|
NS_INTERFACE_MAP_ENTRY(nsIObserver)
|
|
NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
|
|
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIChromeRegistry)
|
|
NS_INTERFACE_MAP_END
|
|
|
|
NS_IMPL_ADDREF(nsChromeRegistry)
|
|
NS_IMPL_RELEASE(nsChromeRegistry)
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
// nsIChromeRegistry methods:
|
|
|
|
already_AddRefed<nsIChromeRegistry> nsChromeRegistry::GetService() {
|
|
if (!gChromeRegistry) {
|
|
// We don't actually want this ref, we just want the service to
|
|
// initialize if it hasn't already.
|
|
nsCOMPtr<nsIChromeRegistry> reg(
|
|
do_GetService(NS_CHROMEREGISTRY_CONTRACTID));
|
|
if (!gChromeRegistry) return nullptr;
|
|
}
|
|
nsCOMPtr<nsIChromeRegistry> registry = gChromeRegistry;
|
|
return registry.forget();
|
|
}
|
|
|
|
nsresult nsChromeRegistry::Init() {
|
|
// This initialization process is fairly complicated and may cause reentrant
|
|
// getservice calls to resolve chrome URIs (especially locale files). We
|
|
// don't want that, so we inform the protocol handler about our existence
|
|
// before we are actually fully initialized.
|
|
gChromeRegistry = this;
|
|
|
|
mInitialized = true;
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
nsresult nsChromeRegistry::GetProviderAndPath(nsIURI* aChromeURL,
|
|
nsACString& aProvider,
|
|
nsACString& aPath) {
|
|
nsresult rv;
|
|
|
|
NS_ASSERTION(aChromeURL->SchemeIs("chrome"), "Non-chrome URI?");
|
|
|
|
nsAutoCString path;
|
|
rv = aChromeURL->GetPathQueryRef(path);
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
if (path.Length() < 3) {
|
|
LogMessage("Invalid chrome URI: %s", path.get());
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
|
|
path.SetLength(nsUnescapeCount(path.BeginWriting()));
|
|
NS_ASSERTION(path.First() == '/', "Path should always begin with a slash!");
|
|
|
|
int32_t slash = path.FindChar('/', 1);
|
|
if (slash == 1) {
|
|
LogMessage("Invalid chrome URI: %s", path.get());
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
|
|
if (slash == -1) {
|
|
aPath.Truncate();
|
|
} else {
|
|
if (slash == (int32_t)path.Length() - 1)
|
|
aPath.Truncate();
|
|
else
|
|
aPath.Assign(path.get() + slash + 1, path.Length() - slash - 1);
|
|
|
|
--slash;
|
|
}
|
|
|
|
aProvider.Assign(path.get() + 1, slash);
|
|
return NS_OK;
|
|
}
|
|
|
|
nsresult nsChromeRegistry::Canonify(nsCOMPtr<nsIURI>& aChromeURL) {
|
|
NS_NAMED_LITERAL_CSTRING(kSlash, "/");
|
|
|
|
nsresult rv;
|
|
|
|
nsAutoCString provider, path;
|
|
rv = GetProviderAndPath(aChromeURL, provider, path);
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
if (path.IsEmpty()) {
|
|
nsAutoCString package;
|
|
rv = aChromeURL->GetHost(package);
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
// we re-use the "path" local string to build a new URL path
|
|
path.Assign(kSlash + provider + kSlash + package);
|
|
if (provider.EqualsLiteral("content")) {
|
|
path.AppendLiteral(".xul");
|
|
} else if (provider.EqualsLiteral("locale")) {
|
|
path.AppendLiteral(".dtd");
|
|
} else if (provider.EqualsLiteral("skin")) {
|
|
path.AppendLiteral(".css");
|
|
} else {
|
|
return NS_ERROR_INVALID_ARG;
|
|
}
|
|
return NS_MutateURI(aChromeURL).SetPathQueryRef(path).Finalize(aChromeURL);
|
|
} else {
|
|
// prevent directory traversals ("..")
|
|
// path is already unescaped once, but uris can get unescaped twice
|
|
const char* pos = path.BeginReading();
|
|
const char* end = path.EndReading();
|
|
// Must start with [a-zA-Z0-9].
|
|
if (!('a' <= *pos && *pos <= 'z') && !('A' <= *pos && *pos <= 'Z') &&
|
|
!('0' <= *pos && *pos <= '9')) {
|
|
return NS_ERROR_DOM_BAD_URI;
|
|
}
|
|
while (pos < end) {
|
|
switch (*pos) {
|
|
case ':':
|
|
return NS_ERROR_DOM_BAD_URI;
|
|
case '.':
|
|
if (pos[1] == '.') return NS_ERROR_DOM_BAD_URI;
|
|
break;
|
|
case '%':
|
|
// chrome: URIs with double-escapes are trying to trick us.
|
|
// watch for %2e, and %25 in case someone triple unescapes
|
|
if (pos[1] == '2' &&
|
|
(pos[2] == 'e' || pos[2] == 'E' || pos[2] == '5'))
|
|
return NS_ERROR_DOM_BAD_URI;
|
|
break;
|
|
case '?':
|
|
case '#':
|
|
pos = end;
|
|
continue;
|
|
}
|
|
++pos;
|
|
}
|
|
}
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsChromeRegistry::ConvertChromeURL(nsIURI* aChromeURI, nsIURI** aResult) {
|
|
nsresult rv;
|
|
if (NS_WARN_IF(!aChromeURI)) {
|
|
return NS_ERROR_INVALID_ARG;
|
|
}
|
|
|
|
if (mOverrideTable.Get(aChromeURI, aResult)) return NS_OK;
|
|
|
|
nsCOMPtr<nsIURL> chromeURL(do_QueryInterface(aChromeURI));
|
|
NS_ENSURE_TRUE(chromeURL, NS_NOINTERFACE);
|
|
|
|
nsAutoCString package, provider, path;
|
|
rv = chromeURL->GetHostPort(package);
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
rv = GetProviderAndPath(chromeURL, provider, path);
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
nsIURI* baseURI = GetBaseURIFromPackage(package, provider, path);
|
|
|
|
uint32_t flags;
|
|
rv = GetFlagsFromPackage(package, &flags);
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
if (!baseURI) {
|
|
LogMessage("No chrome package registered for chrome://%s/%s/%s",
|
|
package.get(), provider.get(), path.get());
|
|
return NS_ERROR_FILE_NOT_FOUND;
|
|
}
|
|
|
|
return NS_NewURI(aResult, path, nullptr, baseURI);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
void nsChromeRegistry::FlushAllCaches() {
|
|
nsCOMPtr<nsIObserverService> obsSvc = mozilla::services::GetObserverService();
|
|
NS_ASSERTION(obsSvc, "Couldn't get observer service.");
|
|
|
|
obsSvc->NotifyObservers((nsIChromeRegistry*)this, NS_CHROME_FLUSH_TOPIC,
|
|
nullptr);
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsChromeRegistry::AllowScriptsForPackage(nsIURI* aChromeURI, bool* aResult) {
|
|
nsresult rv;
|
|
*aResult = false;
|
|
|
|
NS_ASSERTION(aChromeURI->SchemeIs("chrome"),
|
|
"Non-chrome URI passed to AllowScriptsForPackage!");
|
|
|
|
nsCOMPtr<nsIURL> url(do_QueryInterface(aChromeURI));
|
|
NS_ENSURE_TRUE(url, NS_NOINTERFACE);
|
|
|
|
nsAutoCString provider, file;
|
|
rv = GetProviderAndPath(url, provider, file);
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
if (!provider.EqualsLiteral("skin")) *aResult = true;
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsChromeRegistry::AllowContentToAccess(nsIURI* aURI, bool* aResult) {
|
|
nsresult rv;
|
|
|
|
*aResult = false;
|
|
|
|
NS_ASSERTION(aURI->SchemeIs("chrome"),
|
|
"Non-chrome URI passed to AllowContentToAccess!");
|
|
|
|
nsCOMPtr<nsIURL> url = do_QueryInterface(aURI);
|
|
if (!url) {
|
|
NS_ERROR("Chrome URL doesn't implement nsIURL.");
|
|
return NS_ERROR_UNEXPECTED;
|
|
}
|
|
|
|
nsAutoCString package;
|
|
rv = url->GetHostPort(package);
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
uint32_t flags;
|
|
rv = GetFlagsFromPackage(package, &flags);
|
|
|
|
if (NS_SUCCEEDED(rv)) {
|
|
*aResult = !!(flags & CONTENT_ACCESSIBLE);
|
|
}
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsChromeRegistry::CanLoadURLRemotely(nsIURI* aURI, bool* aResult) {
|
|
nsresult rv;
|
|
|
|
*aResult = false;
|
|
|
|
NS_ASSERTION(aURI->SchemeIs("chrome"),
|
|
"Non-chrome URI passed to CanLoadURLRemotely!");
|
|
|
|
nsCOMPtr<nsIURL> url = do_QueryInterface(aURI);
|
|
if (!url) {
|
|
NS_ERROR("Chrome URL doesn't implement nsIURL.");
|
|
return NS_ERROR_UNEXPECTED;
|
|
}
|
|
|
|
nsAutoCString package;
|
|
rv = url->GetHostPort(package);
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
uint32_t flags;
|
|
rv = GetFlagsFromPackage(package, &flags);
|
|
|
|
if (NS_SUCCEEDED(rv)) {
|
|
*aResult = !!(flags & REMOTE_ALLOWED);
|
|
}
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsChromeRegistry::MustLoadURLRemotely(nsIURI* aURI, bool* aResult) {
|
|
nsresult rv;
|
|
|
|
*aResult = false;
|
|
|
|
NS_ASSERTION(aURI->SchemeIs("chrome"),
|
|
"Non-chrome URI passed to MustLoadURLRemotely!");
|
|
|
|
nsCOMPtr<nsIURL> url = do_QueryInterface(aURI);
|
|
if (!url) {
|
|
NS_ERROR("Chrome URL doesn't implement nsIURL.");
|
|
return NS_ERROR_UNEXPECTED;
|
|
}
|
|
|
|
nsAutoCString package;
|
|
rv = url->GetHostPort(package);
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
uint32_t flags;
|
|
rv = GetFlagsFromPackage(package, &flags);
|
|
|
|
if (NS_SUCCEEDED(rv)) {
|
|
*aResult = !!(flags & REMOTE_REQUIRED);
|
|
}
|
|
return NS_OK;
|
|
}
|
|
|
|
already_AddRefed<nsChromeRegistry> nsChromeRegistry::GetSingleton() {
|
|
if (gChromeRegistry) {
|
|
RefPtr<nsChromeRegistry> registry = gChromeRegistry;
|
|
return registry.forget();
|
|
}
|
|
|
|
RefPtr<nsChromeRegistry> cr;
|
|
if (GeckoProcessType_Content == XRE_GetProcessType())
|
|
cr = new nsChromeRegistryContent();
|
|
else
|
|
cr = new nsChromeRegistryChrome();
|
|
|
|
if (NS_FAILED(cr->Init())) return nullptr;
|
|
|
|
return cr.forget();
|
|
}
|
|
|
|
void nsChromeRegistry::SanitizeForBCP47(nsACString& aLocale) {
|
|
// Currently, the only locale code we use that's not BCP47-conformant is
|
|
// "ja-JP-mac" on OS X, but let's try to be more general than just
|
|
// hard-coding that here.
|
|
const int32_t LANG_TAG_CAPACITY = 128;
|
|
char langTag[LANG_TAG_CAPACITY];
|
|
nsAutoCString locale(aLocale);
|
|
UErrorCode err = U_ZERO_ERROR;
|
|
// This is a fail-safe method that will set langTag to "und" if it cannot
|
|
// match any part of the input locale code.
|
|
int32_t len =
|
|
uloc_toLanguageTag(locale.get(), langTag, LANG_TAG_CAPACITY, false, &err);
|
|
if (U_SUCCESS(err) && len > 0) {
|
|
aLocale.Assign(langTag, len);
|
|
}
|
|
}
|