Commit a8344871 authored by Marshall Greenblatt's avatar Marshall Greenblatt
Browse files

Improve crashpad integration (issue #1995)

- Crash reporting is enabled and configured using a "crash_reporter.cfg"
  file. See comments in include/cef_crash_util.h and tools/crash_server.py
  for usage.
parent c990b5d8
......@@ -426,6 +426,8 @@ static_library("libcef_static") {
"libcef/common/content_client.h",
"libcef/common/crash_reporter_client.cc",
"libcef/common/crash_reporter_client.h",
"libcef/common/crash_reporting.cc",
"libcef/common/crash_reporting.h",
"libcef/common/drag_data_impl.cc",
"libcef/common/drag_data_impl.h",
"libcef/common/extensions/chrome_generated_schemas.cc",
......@@ -558,6 +560,11 @@ static_library("libcef_static") {
"//third_party/WebKit/public/web",
]
public_deps = [
# Bring in feature flag defines.
"//cef/libcef/features",
]
deps = [
# Generate pack files and associated CEF header files.
":make_pack_header_resources",
......@@ -679,6 +686,8 @@ static_library("libcef_static") {
"libcef/browser/osr/browser_platform_delegate_osr_win.cc",
"libcef/browser/osr/browser_platform_delegate_osr_win.h",
"libcef/browser/osr/render_widget_host_view_osr_win.cc",
"libcef/common/crash_reporting_win.cc",
"libcef/common/crash_reporting_win.h",
# Part of //chrome/utility.
"//chrome/utility/printing_handler.cc",
......@@ -687,7 +696,6 @@ static_library("libcef_static") {
deps += [
"//chrome_elf",
"//components/crash/content/app:run_as_crashpad_handler",
]
}
......@@ -730,6 +738,10 @@ static_library("libcef_static") {
]
}
if (is_win || is_mac) {
deps += [ "//third_party/crashpad/crashpad/handler:handler_lib" ]
}
if (use_x11) {
deps += [ "//ui/events/devices/x11" ]
}
......
......@@ -21,6 +21,7 @@
'include/cef_command_line.h',
'include/cef_context_menu_handler.h',
'include/cef_cookie.h',
'include/cef_crash_util.h',
'include/cef_dialog_handler.h',
'include/cef_display_handler.h',
'include/cef_dom.h',
......@@ -108,6 +109,7 @@
'include/capi/cef_command_line_capi.h',
'include/capi/cef_context_menu_handler_capi.h',
'include/capi/cef_cookie_capi.h',
'include/capi/cef_crash_util_capi.h',
'include/capi/cef_dialog_handler_capi.h',
'include/capi/cef_display_handler_capi.h',
'include/capi/cef_dom_capi.h',
......
......@@ -193,6 +193,8 @@
'tests/cefclient/browser/bytes_write_handler.cc',
'tests/cefclient/browser/bytes_write_handler.h',
'tests/cefclient/browser/client_app_delegates_browser.cc',
'tests/cefclient/browser/client_browser.cc',
'tests/cefclient/browser/client_browser.h',
'tests/cefclient/browser/client_handler.cc',
'tests/cefclient/browser/client_handler.h',
'tests/cefclient/browser/client_handler_osr.cc',
......
// Copyright (c) 2017 Marshall A. Greenblatt. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the name Chromium Embedded
// Framework nor the names of its contributors may be used to endorse
// or promote products derived from this software without specific prior
// written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// ---------------------------------------------------------------------------
//
// This file was generated by the CEF translator tool and should not edited
// by hand. See the translator.README.txt file in the tools directory for
// more information.
//
#ifndef CEF_INCLUDE_CAPI_CEF_CRASH_UTIL_CAPI_H_
#define CEF_INCLUDE_CAPI_CEF_CRASH_UTIL_CAPI_H_
#pragma once
#include "include/capi/cef_base_capi.h"
#ifdef __cplusplus
extern "C" {
#endif
///
// Crash reporting is configured using an INI-style config file named
// "crash_reporter.cfg". On Windows and Linux this file must be placed next to
// the main application executable. On macOS this file must be placed in the
// top-level app bundle Resources directory (e.g.
// "<appname>.app/Contents/Resources"). File contents are as follows:
//
// # Comments start with a hash character and must be on their own line.
//
// [Config]
// AppName=<Windows only; App-specific folder name component for storing crash
// information; default to "CEF">
// ExternalHandler=<Windows only; Name of the external handler exe to use
// instead of re-launching the main exe; default to empty>
// ServerURL=<crash server URL; default to empty>
// RateLimitEnabled=<True if uploads should be rate limited; default to true>
// MaxUploadsPerDay=<Max uploads per 24 hours, used if rate limit is enabled;
// default to 5>
// MaxDatabaseSizeInMb=<Total crash report disk usage greater than this value
// will cause older reports to be deleted; default to 20>
// MaxDatabaseAgeInDays=<Crash reports older than this value will be deleted;
// default to 5>
//
// [CrashKeys]
// my_key1=<small|medium|large>
// my_key2=<small|medium|large>
//
// Config section:
//
// If "AppName" is set on Windows then crash report information (metrics,
// database and dumps) will be stored locally on disk under the
// "C:\Users\[CurrentUser]\AppData\Local\[AppName]\User Data" folder. On other
// platforms the CefSettings.user_data_path value will be used.
//
// If "ExternalHandler" is set on Windows then the specified exe will be
// launched as the crashpad-handler instead of re-launching the main process
// exe. The value can be an absolute path or a path relative to the main exe
// directory. On Linux the CefSettings.browser_subprocess_path value will be
// used. On macOS the existing subprocess app bundle will be used.
//
// If "ServerURL" is set then crashes will be uploaded as a multi-part POST
// request to the specified URL. Otherwise, reports will only be stored locally
// on disk.
//
// If "RateLimitEnabled" is set to true (1) then crash report uploads will be
// rate limited as follows:
// 1. If "MaxUploadsPerDay" is set to a positive value then at most the
// specified number of crashes will be uploaded in each 24 hour period.
// 2. If crash upload fails due to a network or server error then an
// incremental backoff delay up to a maximum of 24 hours will be applied for
// retries.
// 3. If a backoff delay is applied and "MaxUploadsPerDay" is > 1 then the
// "MaxUploadsPerDay" value will be reduced to 1 until the client is
// restarted. This helps to avoid an upload flood when the network or
// server error is resolved.
// Rate limiting is not supported on Linux.
//
// If "MaxDatabaseSizeInMb" is set to a positive value then crash report storage
// on disk will be limited to that size in megabytes. For example, on Windows
// each dump is about 600KB so a "MaxDatabaseSizeInMb" value of 20 equates to
// about 34 crash reports stored on disk. Not supported on Linux.
//
// If "MaxDatabaseAgeInDays" is set to a positive value then crash reports older
// than the specified age in days will be deleted. Not supported on Linux.
//
// CrashKeys section:
//
// Any number of crash keys can be specified for use by the application. Crash
// key values will be truncated based on the specified size (small = 63 bytes,
// medium = 252 bytes, large = 1008 bytes). The value of crash keys can be set
// from any thread or process using the CefSetCrashKeyValue function. These
// key/value pairs will be sent to the crash server along with the crash dump
// file. Medium and large values will be chunked for submission. For example, if
// your key is named "mykey" then the value will be broken into ordered chunks
// and submitted using keys named "mykey-1", "mykey-2", etc.
///
CEF_EXPORT int cef_crash_reporting_enabled();
///
// Sets or clears a specific key-value pair from the crash metadata.
///
CEF_EXPORT void cef_set_crash_key_value(const cef_string_t* key,
const cef_string_t* value);
#ifdef __cplusplus
}
#endif
#endif // CEF_INCLUDE_CAPI_CEF_CRASH_UTIL_CAPI_H_
// Copyright (c) 2016 Marshall A. Greenblatt. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the name Chromium Embedded
// Framework nor the names of its contributors may be used to endorse
// or promote products derived from this software without specific prior
// written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// ---------------------------------------------------------------------------
//
// The contents of this file must follow a specific format in order to
// support the CEF translator tool. See the translator.README.txt file in the
// tools directory for more information.
//
#ifndef CEF_INCLUDE_CEF_CRASH_UTIL_H_
#define CEF_INCLUDE_CEF_CRASH_UTIL_H_
#pragma once
///
// Crash reporting is configured using an INI-style config file named
// "crash_reporter.cfg". On Windows and Linux this file must be placed next to
// the main application executable. On macOS this file must be placed in the
// top-level app bundle Resources directory (e.g.
// "<appname>.app/Contents/Resources"). File contents are as follows:
//
// # Comments start with a hash character and must be on their own line.
//
// [Config]
// AppName=<Windows only; App-specific folder name component for storing crash
// information; default to "CEF">
// ExternalHandler=<Windows only; Name of the external handler exe to use
// instead of re-launching the main exe; default to empty>
// ServerURL=<crash server URL; default to empty>
// RateLimitEnabled=<True if uploads should be rate limited; default to true>
// MaxUploadsPerDay=<Max uploads per 24 hours, used if rate limit is enabled;
// default to 5>
// MaxDatabaseSizeInMb=<Total crash report disk usage greater than this value
// will cause older reports to be deleted; default to 20>
// MaxDatabaseAgeInDays=<Crash reports older than this value will be deleted;
// default to 5>
//
// [CrashKeys]
// my_key1=<small|medium|large>
// my_key2=<small|medium|large>
//
// Config section:
//
// If "AppName" is set on Windows then crash report information (metrics,
// database and dumps) will be stored locally on disk under the
// "C:\Users\[CurrentUser]\AppData\Local\[AppName]\User Data" folder. On other
// platforms the CefSettings.user_data_path value will be used.
//
// If "ExternalHandler" is set on Windows then the specified exe will be
// launched as the crashpad-handler instead of re-launching the main process
// exe. The value can be an absolute path or a path relative to the main exe
// directory. On Linux the CefSettings.browser_subprocess_path value will be
// used. On macOS the existing subprocess app bundle will be used.
//
// If "ServerURL" is set then crashes will be uploaded as a multi-part POST
// request to the specified URL. Otherwise, reports will only be stored locally
// on disk.
//
// If "RateLimitEnabled" is set to true then crash report uploads will be rate
// limited as follows:
// 1. If "MaxUploadsPerDay" is set to a positive value then at most the
// specified number of crashes will be uploaded in each 24 hour period.
// 2. If crash upload fails due to a network or server error then an
// incremental backoff delay up to a maximum of 24 hours will be applied for
// retries.
// 3. If a backoff delay is applied and "MaxUploadsPerDay" is > 1 then the
// "MaxUploadsPerDay" value will be reduced to 1 until the client is
// restarted. This helps to avoid an upload flood when the network or
// server error is resolved.
// Rate limiting is not supported on Linux.
//
// If "MaxDatabaseSizeInMb" is set to a positive value then crash report storage
// on disk will be limited to that size in megabytes. For example, on Windows
// each dump is about 600KB so a "MaxDatabaseSizeInMb" value of 20 equates to
// about 34 crash reports stored on disk. Not supported on Linux.
//
// If "MaxDatabaseAgeInDays" is set to a positive value then crash reports older
// than the specified age in days will be deleted. Not supported on Linux.
//
// CrashKeys section:
//
// Any number of crash keys can be specified for use by the application. Crash
// key values will be truncated based on the specified size (small = 63 bytes,
// medium = 252 bytes, large = 1008 bytes). The value of crash keys can be set
// from any thread or process using the CefSetCrashKeyValue function. These
// key/value pairs will be sent to the crash server along with the crash dump
// file. Medium and large values will be chunked for submission. For example,
// if your key is named "mykey" then the value will be broken into ordered
// chunks and submitted using keys named "mykey-1", "mykey-2", etc.
///
/*--cef()--*/
bool CefCrashReportingEnabled();
#include "include/cef_base.h"
///
// Sets or clears a specific key-value pair from the crash metadata.
///
/*--cef()--*/
void CefSetCrashKeyValue(const CefString& key, const CefString& value);
#endif // CEF_INCLUDE_CEF_CRASH_UTIL_H_
......@@ -89,6 +89,7 @@
#if defined(OS_POSIX) && !defined(OS_MACOSX)
#include "base/debug/leak_annotations.h"
#include "chrome/common/chrome_paths.h"
#include "components/crash/content/app/breakpad_linux.h"
#include "components/crash/content/browser/crash_handler_host_linux.h"
#include "content/public/common/content_descriptors.h"
......@@ -317,14 +318,15 @@ class CefQuotaPermissionContext : public content::QuotaPermissionContext {
#if defined(OS_POSIX) && !defined(OS_MACOSX)
breakpad::CrashHandlerHostLinux* CreateCrashHandlerHost(
const std::string& process_type) {
base::FilePath dumps_path =
base::CommandLine::ForCurrentProcess()->GetSwitchValuePath(
switches::kCrashDumpsDir);
base::FilePath dumps_path;
PathService::Get(chrome::DIR_CRASH_DUMPS, &dumps_path);
{
ANNOTATE_SCOPED_MEMORY_LEAK;
// Uploads will only occur if a non-empty crash URL is specified in
// CefMainDelegate::InitCrashReporter.
breakpad::CrashHandlerHostLinux* crash_handler =
new breakpad::CrashHandlerHostLinux(
process_type, dumps_path, false);
process_type, dumps_path, true /* upload */);
crash_handler->StartUploaderThread();
return crash_handler;
}
......@@ -618,11 +620,7 @@ void CefContentBrowserClient::AppendExtraCommandLineSwitches(
// Propagate the following switches to all command lines (along with any
// associated values) if present in the browser command line.
static const char* const kSwitchNames[] = {
#if !defined(OS_WIN)
switches::kCrashDumpsDir,
#endif
switches::kDisablePackLoading,
switches::kEnableCrashReporter,
switches::kLang,
switches::kLocalesDirPath,
switches::kLogFile,
......
......@@ -31,14 +31,18 @@
#include "ui/base/ui_base_switches.h"
#if defined(OS_WIN)
#include "base/strings/utf_string_conversions.h"
#include "chrome_elf/chrome_elf_main.h"
#include "content/public/app/sandbox_helper_win.h"
#include "components/crash/content/app/crash_switches.h"
#include "components/crash/content/app/crashpad.h"
#include "components/crash/content/app/run_as_crashpad_handler_win.h"
#include "sandbox/win/src/sandbox_types.h"
#endif
#if defined(OS_MACOSX) || defined(OS_WIN)
#include "components/crash/content/app/crash_switches.h"
#include "third_party/crashpad/crashpad/handler/handler_main.h"
#endif
namespace {
CefContext* g_context = NULL;
......@@ -73,7 +77,7 @@ void DisableFMA3() {
// Signal chrome_elf to initialize crash reporting, rather than doing it in
// DllMain. See https://crbug.com/656800 for details.
void InitializeCrashReporting() {
void InitCrashReporter() {
static bool initialized = false;
if (initialized)
return;
......@@ -82,6 +86,47 @@ void InitializeCrashReporting() {
}
#endif // defined(OS_WIN)
#if defined(OS_MACOSX) || defined(OS_WIN)
// Based on components/crash/content/app/run_as_crashpad_handler_win.cc
// Remove the "--type=crashpad-handler" command-line flag that will otherwise
// confuse the crashpad handler.
// Chrome uses an embedded crashpad handler on Windows only and imports this
// function via the existing "run_as_crashpad_handler" target defined in
// components/crash/content/app/BUILD.gn. CEF uses an embedded handler on both
// Windows and macOS so we define the function here instead of using the
// existing target (because we can't use that target on macOS).
int RunAsCrashpadHandler(const base::CommandLine& command_line) {
base::CommandLine::StringVector argv = command_line.argv();
const base::CommandLine::StringType process_type =
FILE_PATH_LITERAL("--type=");
argv.erase(std::remove_if(argv.begin(), argv.end(),
[&process_type](const base::CommandLine::StringType& str) {
return base::StartsWith(str, process_type,
base::CompareCase::SENSITIVE) ||
(!str.empty() && str[0] == L'/');
}),
argv.end());
std::unique_ptr<char* []> argv_as_utf8(new char*[argv.size() + 1]);
std::vector<std::string> storage;
storage.reserve(argv.size());
for (size_t i = 0; i < argv.size(); ++i) {
#if defined(OS_WIN)
storage.push_back(base::UTF16ToUTF8(argv[i]));
#else
storage.push_back(argv[i]);
#endif
argv_as_utf8[i] = &storage[i][0];
}
argv_as_utf8[argv.size()] = nullptr;
argv.clear();
return crashpad::HandlerMain(static_cast<int>(storage.size()),
argv_as_utf8.get());
}
#endif // defined(OS_MACOSX) || defined(OS_WIN)
} // namespace
int CefExecuteProcess(const CefMainArgs& args,
......@@ -91,7 +136,7 @@ int CefExecuteProcess(const CefMainArgs& args,
#if defined(ARCH_CPU_X86_64)
DisableFMA3();
#endif
InitializeCrashReporting();
InitCrashReporter();
#endif
base::CommandLine command_line(base::CommandLine::NO_PROGRAM);
......@@ -112,9 +157,9 @@ int CefExecuteProcess(const CefMainArgs& args,
if (process_type.empty())
return -1;
#if defined(OS_WIN)
#if defined(OS_MACOSX) || defined(OS_WIN)
if (process_type == crash_reporter::switches::kCrashpadHandler)
return crash_reporter::RunAsCrashpadHandler(command_line);
return RunAsCrashpadHandler(command_line);
#endif
CefMainDelegate main_delegate(application);
......@@ -150,7 +195,7 @@ bool CefInitialize(const CefMainArgs& args,
#if defined(ARCH_CPU_X86_64)
DisableFMA3();
#endif
InitializeCrashReporting();
InitCrashReporter();
#endif
// Return true if the global context already exists.
......
......@@ -32,6 +32,7 @@
#include "chrome/browser/browser_about_handler.h"
#include "chrome/browser/ui/webui/chrome_web_ui_controller_factory.h"
#include "chrome/common/url_constants.h"
#include "content/browser/frame_host/debug_urls.h"
#include "content/browser/webui/content_web_ui_controller_factory.h"
#include "content/public/browser/browser_url_handler.h"
#include "content/public/common/url_constants.h"
......@@ -74,6 +75,13 @@ const char* kAllowedWebUIHosts[] = {
content::kChromeUIWebRTCInternalsHost,
};
// Hosts that don't have useful output when linked directly. They'll be excluded
// from the "chrome://webui-hosts" listing.
const char* kUnlistedHosts[] = {
content::kChromeUINetworkErrorHost,
content::kChromeUIResourcesHost,
};
enum ChromeHostId {
CHROME_UNKNOWN = 0,
CHROME_LICENSE,
......@@ -103,18 +111,87 @@ ChromeHostId GetChromeHostId(const std::string& host) {
return CHROME_UNKNOWN;
}
// Returns CEF and WebUI hosts. Does not include chrome debug hosts (for
// crashing, etc).
void GetAllowedHosts(std::vector<std::string>* hosts) {
// Hosts implemented by CEF.
for (size_t i = 0;
i < sizeof(kAllowedCefHosts) / sizeof(kAllowedCefHosts[0]); ++i) {
hosts->push_back(kAllowedCefHosts[i].host);
}
// Explicitly whitelisted WebUI hosts.
for (size_t i = 0;
i < sizeof(kAllowedWebUIHosts) / sizeof(kAllowedWebUIHosts[0]); ++i) {
hosts->push_back(kAllowedWebUIHosts[i]);
}
}
// Returns true if a host should not be listed on "chrome://webui-hosts".
bool IsUnlistedHost(const std::string& host) {
for (size_t i = 0;
i < sizeof(kUnlistedHosts) / sizeof(kUnlistedHosts[0]); ++i) {
if (host == kUnlistedHosts[i])
return true;
}
return false;
}
// Returns true if a host is WebUI and should be allowed to load.
bool IsAllowedWebUIHost(const std::string& host) {
// Explicitly whitelisted WebUI hosts.
for (size_t i = 0;
i < sizeof(kAllowedWebUIHosts) / sizeof(kAllowedWebUIHosts[0]); ++i) {
if (base::EqualsCaseInsensitiveASCII(kAllowedWebUIHosts[i],
host.c_str())) {
return true;
}
}
return false;
}
// Additional debug URLs that are not included in chrome::kChromeDebugURLs.
const char* kAllowedDebugURLs[] = {
content::kChromeUIBrowserCrashURL,
};
// Returns true for debug URLs that receive special handling (for crashes, etc).
bool IsDebugURL(const GURL& url) {
// URLs handled by the renderer process in
// content/renderer/render_frame_impl.cc MaybeHandleDebugURL().
if (content::IsRendererDebugURL(url))
return true;
// Also include URLs handled by the browser process in
// content/browser/frame_host/debug_urls.cc HandleDebugURL().
for (int i = 0; i < chrome::kNumberOfChromeDebugURLs; ++i) {
GURL host(chrome::kChromeDebugURLs[i]);
if (url.GetOrigin() == host.GetOrigin())
return true;
}
for (size_t i = 0;
i < sizeof(kAllowedDebugURLs) / sizeof(kAllowedDebugURLs[0]); ++i) {
GURL host(kAllowedDebugURLs[i]);
if (url.GetOrigin() == host.GetOrigin())
return true;
}
return false;
}
void GetDebugURLs(std::vector<std::string>* urls) {
for (int i = 0; i < chrome::kNumberOfChromeDebugURLs; ++i) {
urls->push_back(chrome::kChromeDebugURLs[i]);
}
for (size_t i = 0;
i < sizeof(kAllowedDebugURLs) / sizeof(kAllowedDebugURLs[0]); ++i) {
urls->push_back(kAllowedDebugURLs[i]);
}
}
// Intercepts all WebUI calls and either blocks them or forwards them to the
// Content or Chrome WebUI factory as appropriate.
class CefWebUIControllerFactory : public content::WebUIControllerFactory {
......@@ -124,13 +201,8 @@ class CefWebUIControllerFactory : public content::WebUIControllerFactory {
if (!url.SchemeIs(content::kChromeUIScheme))
return false;
for (size_t i = 0;
i < sizeof(kAllowedWebUIHosts) / sizeof(kAllowedWebUIHosts[0]); ++i) {
if (base::EqualsCaseInsensitiveASCII(kAllowedWebUIHosts[i],
url.host().c_str())) {
return true;
}
}
if (IsAllowedWebUIHost(url.host()))
return true;
return false;
}
......@@ -534,16 +606,32 @@ class Delegate : public InternalHandlerDelegate {
std::string html = "<html>\n<head><title>WebUI Hosts</title></head>\n"
"<body bgcolor=\"white\"><h3>WebUI Hosts</h3>\n<ul>\n";
std::vector<std::string> hosts;
GetAllowedHosts(&hosts);
std::sort(hosts.begin(), hosts.end());
std::vector<std::string> list;
GetAllowedHosts(&list);
std::sort(list.begin(), list.end());
for (size_t i = 0U; i < hosts.size(); ++i) {
html += "<li><a href=\"chrome://" + hosts[i] + "\">chrome://" +
hosts[i] + "</a></li>\n";
for (size_t i = 0U; i < list.size(); ++i) {
if (IsUnlistedHost(list[i]))
continue;
html += "<li><a href=\"chrome://" + list[i] + "\">chrome://" +
list[i] + "</a></li>\n";
}
html += "</ul></body>\n</html>";