Compare commits

..

45 Commits
7103 ... master

Author SHA1 Message Date
Marshall Greenblatt
c60d380f39 Fix read of crash reporting env vars 2025-06-03 16:02:44 -04:00
Marshall Greenblatt
31d14c386f Tag 13800 API version 2025-06-03 14:20:59 -04:00
Marshall Greenblatt
f8a746373e Update to Chromium version 138.0.7204.0 (#1465706)
Mac: Require Xcode 16.3 (16E140) and SDK 15.4 (24E241)
2025-06-03 14:20:59 -04:00
Marshall Greenblatt
c5e80eb44a tests: Remove unused version_info argument (see #3935) 2025-06-02 13:38:45 -04:00
Marshall Greenblatt
667e23b91c bootstrap: Support use with older API versions (see #3935) 2025-06-02 13:23:59 -04:00
Tom Crowley
2c411892e2 ceftests: Add tests for PrintToPdf 2025-05-29 16:55:50 +00:00
Pedro de Carvalho Gomes
6bd53b6093 linux: Fix parenting of select widget on Wayland (fixes #3937) 2025-05-29 16:45:12 +00:00
Marshall Greenblatt
b36cb4fe56 bootstrap: Don't explicitly call FreeLibary (see #3935)
This avoids an illegal access during shutdown.
2025-05-29 12:29:37 -04:00
Marshall Greenblatt
9ee8d2c848 bootstrap: Add missing deps for bootstrap-only build (see #3935) 2025-05-29 12:29:37 -04:00
Marshall Greenblatt
794601f128 bootstrap: Pass version to CefScopedLibraryLoader (see #3935)
Strict Chromium version checking is necessary because both sandbox
info and chrome_elf introduce Chromium version dependencies, and we
don't know which non-matching versions are compatible.
2025-05-29 12:29:37 -04:00
Marshall Greenblatt
914a6026b4 bootstrap: Depend on //sandbox directly (see #3935)
This allows us to more accurately duplicate the chrome.exe
sandbox initialization logic.
2025-05-29 12:29:37 -04:00
Marshall Greenblatt
4d65863278 bootstrap: Only show error dialogs with DCHECK_IS_ON (see #3935)
This will enable error dialogs for the Official CEF "Debug" builds.
2025-05-29 12:29:03 -04:00
Marshall Greenblatt
66457acccc bootstrap: Initialize crash reporting (see #3935)
This adds a runtime dependency on chrome_elf.dll and makes all
runtime errors LOG(FATAL) to generate a crash report. Don't wait
for libcef to load before running as the crashpad-handler process.
2025-05-29 12:21:55 -04:00
Marshall Greenblatt
1e8093a910 bootstrap: Load client DLL as untrusted for checks (see #3935) 2025-05-29 12:21:10 -04:00
Marshall Greenblatt
6606e241a1 cefclient: win: Add code signing verification (see #3935)
Move code signing verification code to libcef_dll_wrapper
and add example checks in cefclient.

Load libcef.dll with code signing checks.

Add a CefScopedLibraryLoader variant for Windows.
2025-05-29 12:20:30 -04:00
Marshall Greenblatt
77701dda21 Add cef::logging::ScopedEarlySupport (see #3935)
Supports use of logging macros prior to loading libcef.
2025-05-29 12:19:51 -04:00
Marshall Greenblatt
1244bd34bf libcef: Fix incorrect sandbox init with --no-sandbox
Match the current logic for chrome.exe.
2025-05-29 12:18:25 -04:00
Marshall Greenblatt
85b49df98b cmake: win: Fix cefclient delayload config (see #3824) 2025-05-29 12:18:04 -04:00
Marshall Greenblatt
9a115ea48f Exit early on invalid process type flag (see #3824)
This avoids crashes later during Chromium initialization.
2025-05-20 13:48:48 -04:00
Marshall Greenblatt
ce365d4987 bootstrap: Check code signing certificates (see #3824)
If either the bootstrap executable or the client dll is code signed
then both must be valid (all signatures) and signed with the same
primary certificate. This is a protection against mixing binaries
with different trust levels.
2025-05-20 13:48:48 -04:00
Marshall Greenblatt
4ceedd7f43 patch: Add CEF deps for //components patches (see #3824)
These deps were previously applied to //base via
base_sandbox_2743.patch.
2025-05-19 11:50:33 -04:00
Marshall Greenblatt
d009f6e1ee patch: Remove build.patch (see #3928)
This patch is no longer required after removing cef_sandbox
static linking on macOS.
2025-05-19 11:50:33 -04:00
Marshall Greenblatt
79955317be bazel: mac: Remove cef_sandbox.a linking (see #3928) 2025-05-19 11:50:33 -04:00
Marshall Greenblatt
880e82f45f cmake: mac: Remove cef_sandbox.a linking (see #3928) 2025-05-19 11:50:33 -04:00
Marshall Greenblatt
cfaa10a746 mac: Convert cef_sandbox to a shared library (see #3928)
Replace statically linked cef_sandbox.a with dynamically loaded
libcef_sandbox.dylib. See the SandboxSetup Wiki page for details.
2025-05-19 11:50:33 -04:00
Marshall Greenblatt
353b6fb138 build: Remove GN arg is_cef_sandbox_build (see #3824)
This argument is no longer used after removing cef_sandbox patches.
2025-05-19 11:50:33 -04:00
Marshall Greenblatt
992b9d3435 patch: Remove sandbox-related //base patches (see #3824)
The //base target is only used by cef_sandbox on Windows (not macOS).
2025-05-19 11:50:32 -04:00
Marshall Greenblatt
6a97b82ffc distrib: win: Repurpose sandbox distrib for bootstrap executables (see #3824) 2025-05-19 11:50:32 -04:00
Marshall Greenblatt
dadfe2c8dc bazel: win: Remove cef_sandbox.lib linking (see #3824)
Support for bootstrap executables will be added later.
2025-05-19 11:50:32 -04:00
Marshall Greenblatt
572c44bc2e cmake: win: Remove cef_sandbox.lib linking (see #3824)
- Repurpose USE_SANDBOX config to enable the bootstrap.
- Build appname.dll instead of appname.exe.
- Copy bootstrap[c].exe to appname.exe as a post-build step.
2025-05-19 11:50:32 -04:00
Marshall Greenblatt
c302f285c7 patch: Remove Windows-only cef_sandbox patches (see #3824) 2025-05-16 17:43:11 -04:00
Marshall Greenblatt
adcac2c37c win: Add bootstrap[c].exe for sandbox integration (see #3824)
Replace cef_sandbox.lib usage with bootstrap executables.
See the SandboxSetup Wiki page for details.
2025-05-16 17:32:34 -04:00
Marshall Greenblatt
7581264dbb tools: Don't print git errors with fix_style 2025-05-14 13:09:37 -04:00
Marshall Greenblatt
fbb54374d4 distrib: Add --no-format option for faster testing 2025-05-14 13:09:27 -04:00
Marshall Greenblatt
4060fb9c22 bazel: Remove support for angle bracket includes
Fixes the following error:

fail: attribute includes: './' resolves to the workspace root,
which would allow this rule and all of its transitive dependents
to include any file in your workspace. Please include only what
you need.

Bazel's recommendation [1] is to use double quotes instead of
angle brackets.

[1] https://bazel.build/docs/bazel-and-cpp#include-paths
2025-05-13 18:51:20 -04:00
Marshall Greenblatt
4634b6f0d5 win: Fix crash loading chrome://sandbox when sandbox is disabled 2025-05-13 18:51:10 -04:00
Marshall Greenblatt
9051920b44 osr: linux: Fix crash with default JS modal dialogs (fixes #3921) 2025-05-07 16:10:22 -04:00
Marshall Greenblatt
ad4fa9cf24 Tag 13700 API version 2025-05-07 13:25:44 -04:00
Marshall Greenblatt
8b09ea4324 vscode: Fix cwd for clicking file paths in task output 2025-05-06 17:09:21 -04:00
Marshall Greenblatt
a16513512e docs: Fix incorrect function name (fixes #3923) 2025-05-06 17:09:21 -04:00
Marshall Greenblatt
7944038baf Update to Chromium version 137.0.7151.0 (#1453031) 2025-05-06 17:09:21 -04:00
Marshall Greenblatt
faa85bf980 Support JavaScript window.moveTo/By() and resizeTo/By() (fixes #698)
Adds new CefDisplayHandler::OnContentsBoundsChange and
CefDisplayHandler::GetRootWindowScreenRect callbacks.

cefclient: Implement the above callbacks and call
CefBrowserHost::NotifyScreenInfoChanged when the root window
bounds change.

cefclient: osr: Use real screen bounds by default. Pass
`--fake-screen-bounds` for the old default behavior.

Load https://tests/window in cefclient for additional
implementation details and usage examples.
2025-05-05 11:53:33 -04:00
Marshall Greenblatt
f59112d839 Tag 13601 API version 2025-04-22 10:23:52 -04:00
Marshall Greenblatt
d5339f1f2a Fix enum value typos 2025-04-22 10:22:49 -04:00
Marshall Greenblatt
77f2451a5e Add callback to allow Document PiP moveTo/By() (fixes #3714)
Allow Document picture-in-picture moveTo/By() and resizeTo/By()
(without user gesture) if the new
CefBrowserViewDelegate::AllowMoveForPictureInPicture callback
returns true.
2025-04-22 14:05:23 +00:00
236 changed files with 7017 additions and 3314 deletions

340
BUILD.gn
View File

@@ -319,6 +319,16 @@ group("cef") {
":libcef_static_unittests",
]
if (is_win) {
deps += [
":bootstrap",
":bootstrapc",
":cefclient_dll",
":cefsimple_dll",
":ceftests_dll",
]
}
if (!is_linux || ozone_platform_x11) {
deps += [ ":cefclient" ]
}
@@ -373,6 +383,10 @@ if (is_win) {
# Required by content_switches.cc
"//media:media_buildflags",
# Required by crash_keys.cc
"//content/public/common:buildflags",
"//tools/v8_context_snapshot:buildflags",
# Required by crash_keys.cc (from base/stl_util.h)
"//third_party/abseil-cpp:absl",
]
@@ -548,6 +562,8 @@ source_set("libcef_static") {
"libcef/browser/context.h",
"libcef/browser/context_menu_params_impl.cc",
"libcef/browser/context_menu_params_impl.h",
"libcef/browser/crashpad_runner.cc",
"libcef/browser/crashpad_runner.h",
"libcef/browser/devtools/devtools_controller.cc",
"libcef/browser/devtools/devtools_controller.h",
"libcef/browser/devtools/devtools_protocol_manager.cc",
@@ -992,6 +1008,9 @@ source_set("libcef_static") {
"libcef/browser/native/browser_platform_delegate_native_win.h",
"libcef/browser/osr/browser_platform_delegate_osr_win.cc",
"libcef/browser/osr/browser_platform_delegate_osr_win.h",
"libcef/browser/preferred_stack_size_win.inc",
"libcef_dll/bootstrap/bootstrap_util_win.cc",
"libcef_dll/bootstrap/bootstrap_util_win.h",
]
deps += [
@@ -1156,6 +1175,9 @@ config("libcef_dll_wrapper_config") {
# Increase the initial stack size to 8MiB from the default 1MiB.
ldflags = [ "/STACK:0x800000" ]
}
# Required to support CefScopedLibraryLoader.
ldflags += [ "/DELAYLOAD:libcef.dll" ]
}
# Build using the minimum C++ version supported by the CEF binary distribution.
@@ -1191,6 +1213,14 @@ static_library("libcef_dll_wrapper") {
sources += gypi_paths2.libcef_dll_wrapper_sources_mac
}
if (is_win) {
sources += gypi_paths2.libcef_dll_wrapper_sources_win
libs = [
"crypt32.lib",
"wintrust.lib",
]
}
defines = [ "WRAPPING_CEF_SHARED" ]
configs += [ ":libcef_dll_wrapper_config" ]
@@ -1210,14 +1240,13 @@ if (is_win) {
configs += [ ":libcef_includes_config" ]
deps = [
":make_config_header",
"libcef/features:buildflags",
"//sandbox",
]
}
}
if (is_mac) {
static_library("cef_sandbox") {
shared_library("cef_sandbox") {
sources = [ "libcef_dll/sandbox/sandbox_mac.mm" ]
configs += [ ":libcef_includes_config" ]
deps = [
@@ -1228,6 +1257,97 @@ if (is_mac) {
}
}
#
# bootstrap target.
#
if (is_win) {
bootstrap_sources = includes_common +
includes_win + [
"include/wrapper/cef_certificate_util_win.h",
"include/wrapper/cef_util_win.h",
"libcef_dll/bootstrap/bootstrap_util_win.cc",
"libcef_dll/bootstrap/bootstrap_util_win.h",
"libcef_dll/bootstrap/bootstrap_win.cc",
"libcef_dll/bootstrap/win/bootstrap.rc",
"libcef_dll/bootstrap/win/resource.h",
"libcef_dll/wrapper/cef_certificate_util_win.cc",
"libcef_dll/wrapper/cef_util_win.cc",
"libcef/browser/crashpad_runner.cc",
"libcef/browser/crashpad_runner.h",
"libcef/browser/preferred_stack_size_win.inc",
"//chrome/app/delay_load_failure_hook_win.cc",
"//chrome/app/delay_load_failure_hook_win.h",
"//chrome/common/win/delay_load_failure_support.cc",
"//chrome/common/win/delay_load_failure_support.h",
"//content/app/sandbox_helper_win.cc",
"//content/public/app/sandbox_helper_win.h",
]
bootstrap_deps = [
":make_api_versions_header",
":make_config_header",
":make_version_header",
"//base",
"//build/win:default_exe_manifest",
"//chrome/install_static:secondary_module",
"//chrome/chrome_elf",
"//sandbox",
"//sandbox/policy",
"//third_party/crashpad/crashpad/handler",
]
bootstrap_libs = [
"crypt32.lib",
"wintrust.lib",
]
bootstrap_configs = [
":libcef_includes_config",
# Delay-load as many DLLs as possible for sandbox and startup perf
# improvements.
"//build/config/win:delayloads",
"//build/config/win:delayloads_not_for_child_dll",
]
# Windows application that initializes the sandbox and then passes
# execution to a client-provided DLL.
executable("bootstrap") {
# Necessary because the libcef target is testonly.
testonly = true
sources = bootstrap_sources
deps = bootstrap_deps
libs = bootstrap_libs
configs += bootstrap_configs
# Set /SUBSYSTEM:WINDOWS.
configs -= [ "//build/config/win:console" ]
configs += [ "//build/config/win:windowed" ]
defines = [
"CEF_BUILD_BOOTSTRAP",
]
}
# Like "bootstrap", but as a console application.
executable("bootstrapc") {
# Necessary because the libcef target is testonly.
testonly = true
sources = bootstrap_sources
deps = bootstrap_deps
libs = bootstrap_libs
configs += bootstrap_configs
defines = [
"CEF_BUILD_BOOTSTRAP",
"CEF_BUILD_BOOTSTRAP_CONSOLE",
]
}
}
#
# Resource grit/pack targets.
#
@@ -1541,17 +1661,46 @@ if (is_mac) {
]
}
# Add the ANGLE .dylibs in the MODULE_DIR of the Framework app bundle.
bundle_data("cef_framework_angle_binaries") {
if (!use_static_angle) {
# Add the ANGLE .dylibs in the MODULE_DIR of the Framework app bundle.
bundle_data("cef_framework_angle_binaries") {
sources = [
"$root_out_dir/egl_intermediates/libEGL.dylib",
"$root_out_dir/egl_intermediates/libGLESv2.dylib",
]
outputs = [
"{{bundle_contents_dir}}/Libraries/{{source_file_part}}",
]
public_deps = [
"//ui/gl:angle_library_copy",
]
}
}
# We need to copy the CEF libraries so that the bundle_data dependencies have
# a "copy" target type. Otherwise for "shared_library" target types it will
# try to link things into the CEF Framework when we want to keep the libraries
# separate instead.
copy("cef_library_copy") {
sources = [
"$root_out_dir/egl_intermediates/libEGL.dylib",
"$root_out_dir/egl_intermediates/libGLESv2.dylib",
"$root_out_dir/libcef_sandbox.dylib",
]
outputs = [ "$root_out_dir/cef_intermediates/{{source_file_part}}" ]
deps = [
":cef_sandbox",
]
}
# Add the CEF .dylibs in the MODULE_DIR of the Framework app bundle.
bundle_data("cef_framework_cef_binaries") {
sources = [
"$root_out_dir/cef_intermediates/libcef_sandbox.dylib",
]
outputs = [
"{{bundle_contents_dir}}/Libraries/{{source_file_part}}",
]
public_deps = [
"//ui/gl:angle_library_copy",
":cef_library_copy",
]
}
@@ -1584,11 +1733,15 @@ if (is_mac) {
sources = libcef_sources_common + includes_mac
deps = libcef_deps_common + [
":cef_framework_angle_binaries",
":cef_framework_cef_binaries",
":cef_framework_resources",
":cef_framework_swiftshader_binaries",
]
if (!use_static_angle) {
deps += [ ":cef_framework_angle_binaries" ]
}
configs += [
":libcef_autogen_config",
":libcef_includes_config",
@@ -1653,7 +1806,8 @@ if (is_mac) {
]
# Delay-load as many DLLs as possible for sandbox and startup perf
# improvements.
# improvements. Don't use "delayloads_not_for_child_dll" here because
# we need some DLLs loaded in child processes before sandbox lockdown.
configs += [ "//build/config/win:delayloads" ]
libs = [
@@ -1749,7 +1903,6 @@ if (is_mac) {
deps = [
":cef_make_headers",
":cef_sandbox",
":libcef_dll_wrapper",
]
if (defined(invoker.helper_deps)) {
@@ -2150,6 +2303,7 @@ if (is_mac) {
if (is_win) {
sources += includes_win +
gypi_paths2.includes_wrapper_win +
gypi_paths2.shared_sources_win +
gypi_paths2.cefclient_sources_win +
gypi_paths2.cefclient_sources_resources_win_rc
@@ -2160,7 +2314,10 @@ if (is_mac) {
# Delay-load as many DLLs as possible for sandbox and startup perf
# improvements.
configs += [ "//build/config/win:delayloads" ]
configs += [
"//build/config/win:delayloads",
"//build/config/win:delayloads_not_for_child_dll",
]
defines += [
"CEF_USE_ATL",
@@ -2224,6 +2381,70 @@ if (is_mac) {
}
}
if (is_win) {
# Like the "cefclient" executable target, but building a DLL to be loaded by
# bootstrap.exe.
shared_library("cefclient_dll") {
# Necessary because the libcef target is testonly.
testonly = true
output_name = "cefclient"
sources = includes_common +
includes_win +
gypi_paths2.includes_wrapper +
gypi_paths2.includes_wrapper_win +
gypi_paths2.shared_sources_browser +
gypi_paths2.shared_sources_common +
gypi_paths2.shared_sources_renderer +
gypi_paths2.shared_sources_win +
gypi_paths2.cefclient_sources_browser +
gypi_paths2.cefclient_sources_common +
gypi_paths2.cefclient_sources_renderer +
gypi_paths2.cefclient_sources_win +
gypi_paths2.cefclient_sources_resources_win_rc
deps = [
":bootstrap",
":libcef",
":libcef_dll_wrapper",
]
defines = [
"CEF_USE_ATL",
"CEF_USE_BOOTSTRAP",
]
# Delay-load as many DLLs as possible for sandbox and startup perf
# improvements.
configs += [
"//build/config/win:delayloads",
"//build/config/win:delayloads_not_for_child_dll",
]
libs = [
"comctl32.lib",
"d3d11.lib",
"imm32.lib",
"oleacc.lib",
"rpcrt4.lib",
"shlwapi.lib",
]
if (target_cpu != "arm64") {
libs += [
"glu32.lib",
"opengl32.lib",
]
ldflags = [
"/DELAYLOAD:glu32.dll",
"/DELAYLOAD:oleaut32.dll",
"/DELAYLOAD:opengl32.dll",
]
}
}
}
#
# cefsimple targets.
@@ -2248,6 +2469,7 @@ if (is_mac) {
if (is_win) {
sources += includes_win +
gypi_paths2.includes_wrapper_win +
gypi_paths2.cefsimple_sources_win +
gypi_paths2.cefsimple_sources_resources_win_rc
@@ -2257,7 +2479,10 @@ if (is_mac) {
# Delay-load as many DLLs as possible for sandbox and startup perf
# improvements.
configs += [ "//build/config/win:delayloads" ]
configs += [
"//build/config/win:delayloads",
"//build/config/win:delayloads_not_for_child_dll",
]
deps += [
":cef_sandbox",
@@ -2288,6 +2513,48 @@ if (is_mac) {
}
}
if (is_win) {
# Like the "cefsimple" executable target, but building a DLL to be loaded by
# bootstrap.exe.
shared_library("cefsimple_dll") {
# Necessary because the libcef target is testonly.
testonly = true
output_name = "cefsimple"
sources = includes_common +
includes_win +
gypi_paths2.includes_wrapper +
gypi_paths2.includes_wrapper_win +
gypi_paths2.cefsimple_sources_common +
gypi_paths2.cefsimple_sources_win +
gypi_paths2.cefsimple_sources_resources_win_rc
deps = [
":bootstrap",
":libcef",
":libcef_dll_wrapper",
]
defines = [
"CEF_USE_BOOTSTRAP",
]
# Delay-load as many DLLs as possible for sandbox and startup perf
# improvements.
configs += [
"//build/config/win:delayloads",
"//build/config/win:delayloads_not_for_child_dll",
]
libs = [
"comctl32.lib",
"shlwapi.lib",
"rpcrt4.lib",
]
}
}
#
# ceftests targets.
@@ -2323,13 +2590,17 @@ if (is_mac) {
]
if (is_win) {
sources += gypi_paths2.shared_sources_win +
sources += gypi_paths2.includes_wrapper_win +
gypi_paths2.shared_sources_win +
gypi_paths2.ceftests_sources_win +
gypi_paths2.ceftests_sources_resources_win_rc
# Delay-load as many DLLs as possible for sandbox and startup perf
# improvements.
configs += [ "//build/config/win:delayloads" ]
configs += [
"//build/config/win:delayloads",
"//build/config/win:delayloads_not_for_child_dll",
]
deps += [
":cef_sandbox",
@@ -2361,4 +2632,45 @@ if (is_mac) {
configs += [ "//build/config/gcc:rpath_for_built_shared_libraries" ]
}
}
if (is_win) {
# Like the "ceftests" executable target, but building a DLL to be loaded by
# bootstrapc.exe.
shared_library("ceftests_dll") {
testonly = true
output_name = "ceftests"
sources = includes_common +
gypi_paths2.includes_wrapper +
gypi_paths2.includes_wrapper_win +
gypi_paths2.shared_sources_browser +
gypi_paths2.shared_sources_common +
gypi_paths2.shared_sources_renderer +
gypi_paths2.shared_sources_win +
gypi_paths2.ceftests_sources_common +
gypi_paths2.ceftests_sources_win +
gypi_paths2.ceftests_sources_resources_win_rc
deps = [
":bootstrapc",
":libcef",
":libcef_dll_wrapper",
":gtest_teamcity",
"//testing/gtest",
]
defines = [
"CEF_USE_BOOTSTRAP",
"CEF_TESTS_IN_SRC_DIRECTORY",
]
# Delay-load as many DLLs as possible for sandbox and startup perf
# improvements.
configs += [
"//build/config/win:delayloads",
"//build/config/win:delayloads_not_for_child_dll",
]
}
}
}

View File

@@ -7,6 +7,5 @@
# https://bitbucket.org/chromiumembedded/cef/wiki/BranchesAndBuilding
{
'chromium_checkout': 'refs/tags/136.0.7103.114',
'depot_tools_checkout': 'c9fe205c66'
'chromium_checkout': 'refs/tags/138.0.7204.0'
}

View File

@@ -43,9 +43,7 @@ def _declare_helper_app(name, info_plist, deps, helper_base_name, helper_suffix,
bundle_id = "{}.{}.helper{}".format(MACOS_BUNDLE_ID_BASE, name.lower(), bundle_id_suffix),
infoplists = [":{}_InfoPList".format(helper_base_name)],
minimum_os_version = MACOS_DEPLOYMENT_TARGET,
deps = [
"@cef//:cef_sandbox",
] + deps,
deps = deps,
**kwargs,
)

View File

@@ -47,7 +47,6 @@ def declare_exe(name, srcs, manifest_srcs, rc_file, resources_srcs, resources_de
srcs = srcs,
deps = [
"@cef//:cef_wrapper",
"@cef//:cef_sandbox",
] + deps,
linkopts = [
"$(location @cef//:cef_lib)",

View File

@@ -32,9 +32,13 @@ DLLS_X64 = [
# processes. Conversely, some DLLs must be loaded before sandbox lockdown. In
# unsandboxed processes they will load when first needed. The linker will
# automatically ignore anything which is not linked to the binary at all (it is
# harmless to have an unmatched /delayload). This list should be kept in sync
# with Chromium's "delayloads" target from the //build/config/win/BUILD.gn file.
# harmless to have an unmatched /delayload). Lists should be kept in sync with
# targets from Chromium's //build/config/win/BUILD.gn file.
DELAYLOAD_DLLS = [
# Required to support CefScopedLibraryLoader.
"libcef.dll"
# "delayloads" target.
"api-ms-win-core-winrt-error-l1-1-0.dll",
"api-ms-win-core-winrt-l1-1-0.dll",
"api-ms-win-core-winrt-string-l1-1-0.dll",
@@ -76,38 +80,36 @@ DELAYLOAD_DLLS = [
"winusb.dll",
"wsock32.dll",
"wtsapi32.dll",
# "delayloads_not_for_child_dll" target.
"crypt32.dll",
"dbghelp.dll",
"dhcpcsvc.dll",
"dwrite.dll",
"iphlpapi.dll",
"oleaut32.dll",
"secur32.dll",
"userenv.dll",
"winhttp.dll",
"winmm.dll",
"winspool.drv",
"wintrust.dll",
"ws2_32.dll",
]
# Standard link libraries.
STANDARD_LIBS = [
"comctl32.lib",
"crypt32.lib",
"delayimp.lib",
"gdi32.lib",
"rpcrt4.lib",
"shlwapi.lib",
"user32.lib",
"wintrust.lib",
"ws2_32.lib",
]
# Sandbox link libraries.
SANDBOX_LIBS = [
"Advapi32.lib",
"dbghelp.lib",
"Delayimp.lib",
"ntdll.lib",
"OleAut32.lib",
"PowrProf.lib",
"Propsys.lib",
"psapi.lib",
"SetupAPI.lib",
"Shcore.lib",
"Shell32.lib",
"Userenv.lib",
"version.lib",
"wbemuuid.lib",
"WindowsApp.lib",
"winmm.lib",
]
COMMON_LINKOPTS_DEBUG = [
]
@@ -178,18 +180,9 @@ COMMON_DEFINES = [
"WIN32_LEAN_AND_MEAN",
# Disable exceptions
"_HAS_EXCEPTIONS=0",
# Required by cef_sandbox.lib
"PSAPI_VERSION=1",
# Used by apps to test if the sandbox is enabled
"CEF_USE_SANDBOX",
]
COMMON_DEFINES_DEBUG = [
# Required by cef_sandbox.lib
# Disable iterator debugging
"HAS_ITERATOR_DEBUGGING=0",
"_ITERATOR_DEBUG_LEVEL=0",
]
COMMON_DEFINES_RELEASE = [

View File

@@ -59,8 +59,20 @@
"linux": "40b224f295a20694241c5db49721bc90a3796f30",
"mac": "ff885fe921f9eae1a5ce6a71b30b0c37b306bf56",
"windows": "116a4153047ee1ee67f17fc938f084ee72b24e54"
},
"13700": {
"comment": "Added May 07, 2025.",
"linux": "e5ac12b1bd88b9ece6ceaa57848aaba61ab85242",
"mac": "9e84009c92c25aa80935727b5e4526b23439a575",
"windows": "65c7157dd3e8eba9bcc38db2bd7f26508c717f3e"
},
"13800": {
"comment": "Added June 02, 2025.",
"linux": "72c83a1455706c0f964505a6edcbf00c4a00575d",
"mac": "09110c1f3bbe0e8a8c26ddf6df3388d73a6593d1",
"windows": "1cde3ec27f93747ba42c0f2aa00467a5a16adfd4"
}
},
"last": "13601",
"last": "13800",
"min": "13300"
}

View File

@@ -17,6 +17,7 @@
'include/base/cef_cancelable_callback.h',
'include/base/cef_compiler_specific.h',
'include/base/cef_dump_without_crashing.h',
'include/base/cef_immediate_crash.h',
'include/base/cef_lock.h',
'include/base/cef_logging.h',
'include/base/cef_macros.h',
@@ -79,6 +80,11 @@
'includes_wrapper_mac': [
'include/wrapper/cef_library_loader.h',
],
'includes_wrapper_win': [
'include/wrapper/cef_certificate_util_win.h',
'include/wrapper/cef_library_loader.h',
'include/wrapper/cef_util_win.h',
],
'includes_win': [
'include/cef_sandbox_win.h',
'include/internal/cef_win.h',
@@ -165,9 +171,15 @@
'libcef_dll/wrapper/libcef_dll_wrapper2.cc',
],
'libcef_dll_wrapper_sources_mac': [
'libcef_dll/wrapper/cef_library_loader_mac.mm',
'libcef_dll/wrapper/cef_scoped_library_loader_mac.mm',
'libcef_dll/wrapper/cef_scoped_sandbox_context_mac.mm',
'libcef_dll/wrapper/libcef_dll_dylib.cc',
],
'libcef_dll_wrapper_sources_win': [
'libcef_dll/wrapper/cef_certificate_util_win.cc',
'libcef_dll/wrapper/cef_scoped_library_loader_win.cc',
'libcef_dll/wrapper/cef_util_win.cc',
],
'shared_sources_browser': [
'tests/shared/browser/client_app_browser.cc',
'tests/shared/browser/client_app_browser.h',
@@ -410,6 +422,8 @@
'tests/cefclient/browser/temp_window_mac.mm',
'tests/cefclient/browser/text_input_client_osr_mac.h',
'tests/cefclient/browser/text_input_client_osr_mac.mm',
'tests/cefclient/browser/util_mac.h',
'tests/cefclient/browser/util_mac.mm',
'tests/cefclient/browser/views_window_mac.mm',
'tests/cefclient/browser/window_test_runner_mac.h',
'tests/cefclient/browser/window_test_runner_mac.mm',
@@ -526,6 +540,7 @@
'tests/ceftests/permission_prompt_unittest.cc',
'tests/ceftests/preference_unittest.cc',
'tests/ceftests/print_unittest.cc',
'tests/ceftests/print_to_pdf_unittest.cc',
'tests/ceftests/process_message_unittest.cc',
'tests/ceftests/request_context_unittest.cc',
'tests/ceftests/request_handler_unittest.cc',

View File

@@ -36,11 +36,7 @@ macro(PRINT_CEF_CONFIG)
message(STATUS "CEF sandbox: ${USE_SANDBOX}")
set(_libraries ${CEF_STANDARD_LIBS})
if(OS_WINDOWS AND USE_SANDBOX)
list(APPEND _libraries ${CEF_SANDBOX_STANDARD_LIBS})
endif()
message(STATUS "Standard libraries: ${_libraries}")
message(STATUS "Standard libraries: ${CEF_STANDARD_LIBS}")
message(STATUS "Compile defines: ${CEF_COMPILER_DEFINES}")
message(STATUS "Compile defines (Debug): ${CEF_COMPILER_DEFINES_DEBUG}")

View File

@@ -326,7 +326,7 @@ if(OS_MAC)
# Find the newest available base SDK.
execute_process(COMMAND xcode-select --print-path OUTPUT_VARIABLE XCODE_PATH OUTPUT_STRIP_TRAILING_WHITESPACE)
foreach(OS_VERSION 14.2 14.0 11.0)
foreach(OS_VERSION 15.4 14.2 14.0 11.0)
set(SDK "${XCODE_PATH}/Platforms/MacOSX.platform/Developer/SDKs/MacOSX${OS_VERSION}.sdk")
if(NOT "${CMAKE_OSX_SYSROOT}" AND EXISTS "${SDK}" AND IS_DIRECTORY "${SDK}")
set(CMAKE_OSX_SYSROOT ${SDK})
@@ -361,14 +361,6 @@ if(OS_MAC)
list(APPEND CEF_COMPILER_DEFINES
CEF_USE_SANDBOX # Used by apps to test if the sandbox is enabled
)
list(APPEND CEF_STANDARD_LIBS
-lsandbox
)
# CEF sandbox library paths.
set(CEF_SANDBOX_LIB_DEBUG "${CEF_BINARY_DIR_DEBUG}/cef_sandbox.a")
set(CEF_SANDBOX_LIB_RELEASE "${CEF_BINARY_DIR_RELEASE}/cef_sandbox.a")
endif()
# CEF Helper app suffixes.
@@ -396,15 +388,6 @@ if(OS_WINDOWS)
set(CMAKE_CXX_FLAGS_RELEASE "")
endif()
if(USE_SANDBOX)
# Check if the current MSVC version is compatible with the cef_sandbox.lib
# static library. We require VS2015 or newer.
if(MSVC_VERSION LESS 1900)
message(WARNING "CEF sandbox is not compatible with the current MSVC version (${MSVC_VERSION})")
set(USE_SANDBOX OFF)
endif()
endif()
# Consumers who run into LNK4099 warnings can pass /Z7 instead (see issue #385).
set(CEF_DEBUG_INFO_FLAG "/Zi" CACHE STRING "Optional flag specifying specific /Z flag to use")
@@ -449,18 +432,20 @@ if(OS_WINDOWS)
list(APPEND CEF_LINKER_FLAGS_DEBUG
/DEBUG # Generate debug information
)
list(APPEND CEF_EXE_LINKER_FLAGS
/MANIFEST:NO # No default manifest (see ADD_WINDOWS_MANIFEST macro usage)
/LARGEADDRESSAWARE # Allow 32-bit processes to access 3GB of RAM
# Delayload most libraries as the dlls are simply not required at startup (or
# at all, depending on the process type). Some dlls open handles when they are
# loaded, and we may not want them to be loaded in renderers or other sandboxed
# processes. Conversely, some dlls must be loaded before sandbox lockdown. In
# unsandboxed processes they will load when first needed. The linker will
# automatically ignore anything which is not linked to the binary at all (it is
# harmless to have an unmatched /delayload). This list should be kept in sync
# with Chromium's "delayloads" target from the //build/config/win/BUILD.gn file.
# Delayload most libraries as the dlls are simply not required at startup (or
# at all, depending on the process type). Some dlls open handles when they are
# loaded, and we may not want them to be loaded in renderers or other sandboxed
# processes. Conversely, some dlls must be loaded before sandbox lockdown. In
# unsandboxed processes they will load when first needed. The linker will
# automatically ignore anything which is not linked to the binary at all (it is
# harmless to have an unmatched /delayload). Lists should be kept in sync with
# targets from Chromium's //build/config/win/BUILD.gn file.
set(CEF_DELAYLOAD_FLAGS
# Required to support CefScopedLibraryLoader.
/DELAYLOAD:libcef.dll
# "delayloads" target.
/DELAYLOAD:api-ms-win-core-winrt-error-l1-1-0.dll
/DELAYLOAD:api-ms-win-core-winrt-l1-1-0.dll
/DELAYLOAD:api-ms-win-core-winrt-string-l1-1-0.dll
@@ -502,6 +487,31 @@ if(OS_WINDOWS)
/DELAYLOAD:winusb.dll
/DELAYLOAD:wsock32.dll
/DELAYLOAD:wtsapi32.dll
# "delayloads_not_for_child_dll" target.
/DELAYLOAD:crypt32.dll
/DELAYLOAD:dbghelp.dll
/DELAYLOAD:dhcpcsvc.dll
/DELAYLOAD:dwrite.dll
/DELAYLOAD:iphlpapi.dll
/DELAYLOAD:oleaut32.dll
/DELAYLOAD:secur32.dll
/DELAYLOAD:userenv.dll
/DELAYLOAD:winhttp.dll
/DELAYLOAD:winmm.dll
/DELAYLOAD:winspool.drv
/DELAYLOAD:wintrust.dll
/DELAYLOAD:ws2_32.dll
)
list(APPEND CEF_EXE_LINKER_FLAGS
# For executable targets.
/MANIFEST:NO # No default manifest (see ADD_WINDOWS_MANIFEST macro usage)
/LARGEADDRESSAWARE # Allow 32-bit processes to access 3GB of RAM
${CEF_DELAYLOAD_FLAGS}
)
list(APPEND CEF_SHARED_LINKER_FLAGS
# For shared library targets.
${CEF_DELAYLOAD_FLAGS}
)
list(APPEND CEF_COMPILER_DEFINES
WIN32 _WIN32 _WINDOWS # Windows platform
@@ -540,9 +550,12 @@ if(OS_WINDOWS)
# Standard libraries.
set(CEF_STANDARD_LIBS
comctl32.lib
crypt32.lib
delayimp.lib
gdi32.lib
rpcrt4.lib
shlwapi.lib
wintrust.lib
ws2_32.lib
)
@@ -587,36 +600,8 @@ if(OS_WINDOWS)
if(USE_SANDBOX)
list(APPEND CEF_COMPILER_DEFINES
PSAPI_VERSION=1 # Required by cef_sandbox.lib
CEF_USE_SANDBOX # Used by apps to test if the sandbox is enabled
CEF_USE_BOOTSTRAP # Used by apps to test if the bootstrap is enabled
)
list(APPEND CEF_COMPILER_DEFINES_DEBUG
_HAS_ITERATOR_DEBUGGING=0 # Disable iterator debugging
)
# Libraries required by cef_sandbox.lib.
set(CEF_SANDBOX_STANDARD_LIBS
Advapi32.lib
dbghelp.lib
Delayimp.lib
ntdll.lib
OleAut32.lib
PowrProf.lib
Propsys.lib
psapi.lib
SetupAPI.lib
Shell32.lib
Shcore.lib
Userenv.lib
version.lib
wbemuuid.lib
WindowsApp.lib
winmm.lib
)
# CEF sandbox library paths.
set(CEF_SANDBOX_LIB_DEBUG "${CEF_BINARY_DIR_DEBUG}/cef_sandbox.lib")
set(CEF_SANDBOX_LIB_RELEASE "${CEF_BINARY_DIR_RELEASE}/cef_sandbox.lib")
endif()
# Configure use of ATL.

View File

@@ -0,0 +1,197 @@
// Copyright (c) 2025 Marshall A. Greenblatt. Portions copyright (c) 2019
// Google Inc. 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.
#ifndef CEF_INCLUDE_BASE_CEF_IMMEDIATE_CRASH_H_
#define CEF_INCLUDE_BASE_CEF_IMMEDIATE_CRASH_H_
#pragma once
#if defined(USING_CHROMIUM_INCLUDES)
// When building CEF include the Chromium header directly.
#include "base/immediate_crash.h"
#else // !USING_CHROMIUM_INCLUDES
// The following is substantially similar to the Chromium implementation.
// If the Chromium implementation diverges the below implementation should be
// updated to match.
#include "include/base/cef_build.h"
#if defined(OS_WIN)
#include <stdlib.h>
#endif
// Crashes in the fastest possible way with no attempt at logging.
// There are several constraints; see http://crbug.com/664209 for more context.
//
// - TRAP_SEQUENCE_() must be fatal. It should not be possible to ignore the
// resulting exception or simply hit 'continue' to skip over it in a debugger.
// - Different instances of TRAP_SEQUENCE_() must not be folded together, to
// ensure crash reports are debuggable. Unlike __builtin_trap(), asm volatile
// blocks will not be folded together.
// Note: TRAP_SEQUENCE_() previously required an instruction with a unique
// nonce since unlike clang, GCC folds together identical asm volatile
// blocks.
// - TRAP_SEQUENCE_() must produce a signal that is distinct from an invalid
// memory access.
// - TRAP_SEQUENCE_() must be treated as a set of noreturn instructions.
// __builtin_unreachable() is used to provide that hint here. clang also uses
// this as a heuristic to pack the instructions in the function epilogue to
// improve code density.
// - base::ImmediateCrash() is used in allocation hooks. To prevent recursions,
// TRAP_SEQUENCE_() must not allocate.
//
// Additional properties that are nice to have:
// - TRAP_SEQUENCE_() should be as compact as possible.
// - The first instruction of TRAP_SEQUENCE_() should not change, to avoid
// shifting crash reporting clusters. As a consequence of this, explicit
// assembly is preferred over intrinsics.
// Note: this last bullet point may no longer be true, and may be removed in
// the future.
// Note: TRAP_SEQUENCE Is currently split into two macro helpers due to the fact
// that clang emits an actual instruction for __builtin_unreachable() on certain
// platforms (see https://crbug.com/958675). In addition, the int3/bkpt/brk will
// be removed in followups, so splitting it up like this now makes it easy to
// land the followups.
#if defined(COMPILER_GCC)
#if defined(ARCH_CPU_X86_FAMILY)
// TODO(crbug.com/40625592): In theory, it should be possible to use just
// int3. However, there are a number of crashes with SIGILL as the exception
// code, so it seems likely that there's a signal handler that allows execution
// to continue after SIGTRAP.
#define TRAP_SEQUENCE1_() asm volatile("int3")
#if defined(OS_APPLE)
// Intentionally empty: __builtin_unreachable() is always part of the sequence
// (see IMMEDIATE_CRASH below) and already emits a ud2 on Mac.
#define TRAP_SEQUENCE2_() asm volatile("")
#else
#define TRAP_SEQUENCE2_() asm volatile("ud2")
#endif // defined(OS_APPLE)
#elif defined(ARCH_CPU_ARMEL)
// bkpt will generate a SIGBUS when running on armv7 and a SIGTRAP when running
// as a 32 bit userspace app on arm64. There doesn't seem to be any way to
// cause a SIGTRAP from userspace without using a syscall (which would be a
// problem for sandboxing).
// TODO(crbug.com/40625592): Remove bkpt from this sequence.
#define TRAP_SEQUENCE1_() asm volatile("bkpt #0")
#define TRAP_SEQUENCE2_() asm volatile("udf #0")
#elif defined(ARCH_CPU_ARM64)
// This will always generate a SIGTRAP on arm64.
// TODO(crbug.com/40625592): Remove brk from this sequence.
#define TRAP_SEQUENCE1_() asm volatile("brk #0")
#define TRAP_SEQUENCE2_() asm volatile("hlt #0")
#else
// Crash report accuracy will not be guaranteed on other architectures, but at
// least this will crash as expected.
#define TRAP_SEQUENCE1_() __builtin_trap()
#define TRAP_SEQUENCE2_() asm volatile("")
#endif // ARCH_CPU_*
#elif defined(COMPILER_MSVC)
#if !defined(__clang__)
// MSVC x64 doesn't support inline asm, so use the MSVC intrinsic.
#define TRAP_SEQUENCE1_() __debugbreak()
#define TRAP_SEQUENCE2_()
#elif defined(ARCH_CPU_ARM64)
// Windows ARM64 uses "BRK #F000" as its breakpoint instruction, and
// __debugbreak() generates that in both VC++ and clang.
#define TRAP_SEQUENCE1_() __debugbreak()
// Intentionally empty: __builtin_unreachable() is always part of the sequence
// (see IMMEDIATE_CRASH below) and already emits a ud2 on Win64,
// https://crbug.com/958373
#define TRAP_SEQUENCE2_() __asm volatile("")
#else
#define TRAP_SEQUENCE1_() asm volatile("int3")
#define TRAP_SEQUENCE2_() asm volatile("ud2")
#endif // __clang__
#else
#error No supported trap sequence!
#endif // COMPILER_GCC
#define TRAP_SEQUENCE_() \
do { \
TRAP_SEQUENCE1_(); \
TRAP_SEQUENCE2_(); \
} while (false)
// This version of ALWAYS_INLINE inlines even in is_debug=true.
// TODO(pbos): See if NDEBUG can be dropped from ALWAYS_INLINE as well, and if
// so merge. Otherwise document why it cannot inline in debug in
// base/compiler_specific.h.
#if defined(COMPILER_GCC)
#define IMMEDIATE_CRASH_ALWAYS_INLINE inline __attribute__((__always_inline__))
#elif defined(COMPILER_MSVC)
#define IMMEDIATE_CRASH_ALWAYS_INLINE __forceinline
#else
#define IMMEDIATE_CRASH_ALWAYS_INLINE inline
#endif
namespace base {
[[noreturn]] IMMEDIATE_CRASH_ALWAYS_INLINE void ImmediateCrash() {
#if defined(OS_WIN)
// We can't use abort() on Windows because it results in the
// abort/retry/ignore dialog which disrupts automated tests.
// TODO(crbug.com/40948553): investigate if such dialogs can
// be suppressed
TRAP_SEQUENCE_();
#if defined(__clang__) || defined(COMPILER_GCC)
__builtin_unreachable();
#endif // defined(__clang__) || defined(COMPILER_GCC)
#else // !defined(OS_WIN)
abort();
#endif // !defined(OS_WIN)
}
} // namespace base
#endif // !USING_CHROMIUM_INCLUDES
#endif // CEF_INCLUDE_BASE_CEF_LOCK_H_

View File

@@ -189,16 +189,50 @@
namespace cef {
namespace logging {
class ScopedEarlySupport;
namespace internal {
// Structure defining the baseline logging implementation used by client
// and wrapper code that links libcef_dll_wrapper.
struct Implementation {
decltype(&cef_get_min_log_level) get_min_log_level;
decltype(&cef_get_vlog_level) get_vlog_level;
decltype(&cef_log) log;
};
// Returns the currently configured logging implementation.
const Implementation* GetImplementation();
// Change the logging implementation for the lifespan of this scoped object.
// See ScopedEarlySupport for usage.
class ScopedImplementation {
public:
ScopedImplementation(const ScopedImplementation&) = delete;
ScopedImplementation& operator=(const ScopedImplementation&) = delete;
private:
friend class logging::ScopedEarlySupport;
ScopedImplementation();
~ScopedImplementation();
void Init(const Implementation* impl);
const Implementation* previous_ = nullptr;
};
} // namespace internal
// Gets the current log level.
inline int GetMinLogLevel() {
return cef_get_min_log_level();
return internal::GetImplementation()->get_min_log_level();
}
// Gets the current vlog level for the given file (usually taken from
// __FILE__). Note that |N| is the size *with* the null terminator.
template <size_t N>
int GetVlogLevel(const char (&file)[N]) {
return cef_get_vlog_level(file, N);
return internal::GetImplementation()->get_vlog_level(file, N);
}
typedef int LogSeverity;
@@ -218,6 +252,64 @@ const LogSeverity LOG_DFATAL = LOG_ERROR;
const LogSeverity LOG_DFATAL = LOG_FATAL;
#endif
///
/// Support the use of CEF logging macros during early application startup,
/// prior to loading libcef. Not for use during or after CEF initialization.
/// Support is scoped to this object's lifespan. This implementation is not
/// thread-safe and should not be used for logging from multiple threads.
///
class ScopedEarlySupport final : public internal::ScopedImplementation {
public:
///
/// Logging configuration.
///
struct Config {
///
/// Configure logging level.
///
int min_log_level = LOG_ERROR;
int vlog_level = 0;
///
/// Configure log line formatting.
///
const char* log_prefix = nullptr;
bool log_process_id = true;
bool log_thread_id = true;
bool log_timestamp = true;
bool log_tickcount = true;
///
/// Optionally override the default handling of formatted log lines. For
/// example, this callback could be used to write |log_line| to a file.
/// Return false to proceed with the default behavior of writing to stderr
/// or debugger console. FATAL errors will still intentionally crash the
/// application.
///
bool (*formatted_log_handler)(const char* /*log_line*/) = nullptr;
};
explicit ScopedEarlySupport(const Config& config);
ScopedEarlySupport(const ScopedEarlySupport&) = delete;
ScopedEarlySupport& operator=(const ScopedEarlySupport&) = delete;
private:
static const Config& GetConfig();
static int get_min_log_level();
static int get_vlog_level(const char* file_start, size_t N);
static void log(const char* file,
int line,
int severity,
const char* message);
const struct Impl {
internal::Implementation ptrs;
Config config;
} impl_;
};
// A few definitions of macros that don't generate much code. These are used
// by LOG() and LOG_IF, etc. Since these are used all over our code, it's
// better to have compact code for these operations.

View File

@@ -72,8 +72,8 @@ int CefExecuteProcess(const CefMainArgs& args,
/// early exit is desired (for example, due to process singleton relaunch
/// behavior). If this function returns false then the application should exit
/// immediately without calling any other CEF functions except, optionally,
/// CefGetErrorCode. The |windows_sandbox_info| parameter is only used on
/// Windows and may be NULL (see cef_sandbox_win.h for details).
/// CefGetExitCode. The |windows_sandbox_info| parameter is only used on Windows
/// and may be NULL (see cef_sandbox_win.h for details).
///
/*--cef(api_hash_check,optional_param=application,
optional_param=windows_sandbox_info)--*/

View File

@@ -707,12 +707,24 @@ class CefBrowserHost : public virtual CefBaseRefCounted {
virtual void WasHidden(bool hidden) = 0;
///
/// Send a notification to the browser that the screen info has changed. The
/// browser will then call CefRenderHandler::GetScreenInfo to update the
/// screen information with the new values. This simulates moving the webview
/// window from one display to another, or changing the properties of the
/// current display. This method is only used when window rendering is
/// disabled.
/// Notify the browser that screen information has changed. Updated
/// information will be sent to the renderer process to configure screen size
/// and position values used by CSS and JavaScript (window.deviceScaleFactor,
/// window.screenX/Y, window.outerWidth/Height, etc.). For background see
/// https://bitbucket.org/chromiumembedded/cef/wiki/GeneralUsage.md#markdown-header-coordinate-systems
///
/// This method is used with (a) windowless rendering and (b) windowed
/// rendering with external (client-provided) root window.
///
/// With windowless rendering the browser will call
/// CefRenderHandler::GetScreenInfo, CefRenderHandler::GetRootScreenRect and
/// CefRenderHandler::GetViewRect. This simulates moving or resizing the root
/// window in the current display, moving the root window from one display to
/// another, or changing the properties of the current display.
///
/// With windowed rendering the browser will call
/// CefDisplayHandler::GetRootWindowScreenRect and use the associated
/// display properties.
///
/*--cef()--*/
virtual void NotifyScreenInfoChanged() = 0;

View File

@@ -38,6 +38,7 @@
#define CEF_INCLUDE_CEF_DISPLAY_HANDLER_H_
#pragma once
#include "include/cef_api_hash.h"
#include "include/cef_base.h"
#include "include/cef_browser.h"
#include "include/cef_frame.h"
@@ -123,7 +124,7 @@ class CefDisplayHandler : public virtual CefBaseRefCounted {
///
/// Called when auto-resize is enabled via
/// CefBrowserHost::SetAutoResizeEnabled and the contents have auto-resized.
/// |new_size| will be the desired size in view coordinates. Return true if
/// |new_size| will be the desired size in DIP coordinates. Return true if
/// the resize was handled or false for default handling.
///
/*--cef()--*/
@@ -162,6 +163,46 @@ class CefDisplayHandler : public virtual CefBaseRefCounted {
virtual void OnMediaAccessChange(CefRefPtr<CefBrowser> browser,
bool has_video_access,
bool has_audio_access) {}
#if CEF_API_ADDED(13700)
///
/// Called when JavaScript is requesting new bounds via window.moveTo/By() or
/// window.resizeTo/By(). |new_bounds| are in DIP screen coordinates.
///
/// With Views-hosted browsers |new_bounds| are the desired bounds for
/// the containing CefWindow and may be passed directly to
/// CefWindow::SetBounds. With external (client-provided) parent on macOS and
/// Windows |new_bounds| are the desired frame bounds for the containing root
/// window. With other non-Views browsers |new_bounds| are the desired bounds
/// for the browser content only unless the client implements either
/// CefDisplayHandler::GetRootWindowScreenRect for windowed browsers or
/// CefRenderHandler::GetWindowScreenRect for windowless browsers. Clients may
/// expand browser content bounds to window bounds using OS-specific or
/// CefDisplay methods.
///
/// Return true if this method was handled or false for default handling.
/// Default move/resize behavior is only provided with Views-hosted Chrome
/// style browsers.
///
/*--cef(added=13700)--*/
virtual bool OnContentsBoundsChange(CefRefPtr<CefBrowser> browser,
const CefRect& new_bounds) {
return false;
}
///
/// Called to retrieve the external (client-provided) root window rectangle in
/// screen DIP coordinates. Only called for windowed browsers on Windows and
/// Linux. Return true if the rectangle was provided. Return false to use the
/// root window bounds on Windows or the browser content bounds on Linux. For
/// additional usage details see CefBrowserHost::NotifyScreenInfoChanged.
///
/*--cef(added=13700)--*/
virtual bool GetRootWindowScreenRect(CefRefPtr<CefBrowser> browser,
CefRect& rect) {
return false;
}
#endif
};
#endif // CEF_INCLUDE_CEF_DISPLAY_HANDLER_H_

View File

@@ -48,14 +48,8 @@ extern "C" {
/// The sandbox is used to restrict sub-processes (renderer, GPU, etc) from
/// directly accessing system resources. This helps to protect the user from
/// untrusted and potentially malicious Web content. See
/// http://www.chromium.org/developers/design-documents/sandbox for complete
/// details.
///
/// To enable the sandbox on macOS the following requirements must be met:
/// 1. Link the helper process executable with the cef_sandbox static library.
/// 2. Call the cef_sandbox_initialize() function at the beginning of the
/// helper executable main() function and before loading the CEF framework
/// library. See include/wrapper/cef_library_loader.h for example usage.
/// https://bitbucket.org/chromiumembedded/cef/wiki/SandboxSetup.md for usage
/// details. See include/wrapper/cef_library_loader.h for example usage.
///
///
@@ -76,7 +70,7 @@ CEF_EXPORT void cef_sandbox_destroy(void* sandbox_context);
///
/// Scoped helper for managing the life span of a sandbox context handle.
///
class CEF_EXPORT CefScopedSandboxContext {
class CefScopedSandboxContext final {
public:
CefScopedSandboxContext();
~CefScopedSandboxContext();
@@ -87,7 +81,8 @@ class CEF_EXPORT CefScopedSandboxContext {
bool Initialize(int argc, char** argv);
private:
void* sandbox_context_;
void* library_handle_ = nullptr;
void* sandbox_context_ = nullptr;
};
#endif // __cplusplus

View File

@@ -37,6 +37,12 @@
#if defined(OS_WIN)
#include "include/cef_version_info.h"
#if !defined(GENERATING_CEF_API_HASH)
#include <windows.h>
#endif
#ifdef __cplusplus
extern "C" {
#endif
@@ -46,17 +52,9 @@ extern "C" {
/// The sandbox is used to restrict sub-processes (renderer, GPU, etc) from
/// directly accessing system resources. This helps to protect the user from
/// untrusted and potentially malicious Web content. See
/// http://www.chromium.org/developers/design-documents/sandbox for complete
/// https://bitbucket.org/chromiumembedded/cef/wiki/SandboxSetup.md for usage
/// details.
///
/// To enable the sandbox on Windows the following requirements must be met:
/// 1. Use the same executable for the browser process and all sub-processes.
/// 2. Link the executable with the cef_sandbox static library.
/// 3. Call the cef_sandbox_info_create() function from within the executable
/// (not from a separate DLL) and pass the resulting pointer into both the
/// CefExecuteProcess() and CefInitialize() functions via the
/// |windows_sandbox_info| parameter.
///
///
/// Create the sandbox information object for this process. It is safe to create
@@ -76,7 +74,7 @@ void cef_sandbox_info_destroy(void* sandbox_info);
///
/// Manages the life span of a sandbox information object.
///
class CefScopedSandboxInfo {
class CefScopedSandboxInfo final {
public:
CefScopedSandboxInfo() { sandbox_info_ = cef_sandbox_info_create(); }
~CefScopedSandboxInfo() { cef_sandbox_info_destroy(sandbox_info_); }
@@ -88,6 +86,39 @@ class CefScopedSandboxInfo {
};
#endif // __cplusplus
#if defined(CEF_BUILD_BOOTSTRAP)
#define CEF_BOOTSTRAP_EXPORT __declspec(dllimport)
#else
#define CEF_BOOTSTRAP_EXPORT __declspec(dllexport)
#endif
#ifdef __cplusplus
extern "C" {
#endif
///
/// Entry point to be implemented by client DLLs using bootstrap.exe for
/// windows (/SUBSYSTEM:WINDOWS) applications.
///
CEF_BOOTSTRAP_EXPORT int RunWinMain(HINSTANCE hInstance,
LPTSTR lpCmdLine,
int nCmdShow,
void* sandbox_info,
cef_version_info_t* version_info);
///
/// Entry point to be implemented by client DLLs using bootstrapc.exe for
/// console (/SUBSYSTEM:CONSOLE) applications.
///
CEF_BOOTSTRAP_EXPORT int RunConsoleMain(int argc,
char* argv[],
void* sandbox_info,
cef_version_info_t* version_info);
#ifdef __cplusplus
}
#endif
#endif // defined(OS_WIN)
#endif // CEF_INCLUDE_CEF_SANDBOX_WIN_H_

View File

@@ -30,6 +30,9 @@
#ifndef CEF_INCLUDE_CEF_VERSION_INFO_H_
#define CEF_INCLUDE_CEF_VERSION_INFO_H_
#include <stddef.h>
#include "include/cef_api_hash.h"
#include "include/internal/cef_export.h"
#if !defined(GENERATING_CEF_API_HASH)
@@ -55,6 +58,66 @@ extern "C" {
///
CEF_EXPORT int cef_version_info(int entry);
#if CEF_API_ADDED(13800)
///
/// Structure representing all CEF version information.
///
typedef struct _cef_version_info_t {
///
/// Size of this structure.
///
size_t size;
int cef_version_major;
int cef_version_minor;
int cef_version_patch;
int cef_commit_number;
int chrome_version_major;
int chrome_version_minor;
int chrome_version_build;
int chrome_version_patch;
} cef_version_info_t;
///
/// Return all CEF version information for the libcef library.
///
CEF_EXPORT void cef_version_info_all(cef_version_info_t* info);
#elif !defined(GENERATING_CEF_API_HASH)
// Unversioned definition to support use of the bootstrap and
// CefScopedLibraryLoader with older API versions.
typedef struct _cef_version_info_t {
// Size of this structure.
size_t size;
int cef_version_major;
int cef_version_minor;
int cef_version_patch;
int cef_commit_number;
int chrome_version_major;
int chrome_version_minor;
int chrome_version_build;
int chrome_version_patch;
} cef_version_info_t;
#endif // !defined(GENERATING_CEF_API_HASH)
///
/// Populate CEF version information for the client library.
///
#define CEF_POPULATE_VERSION_INFO(info) \
(info)->size = sizeof(cef_version_info_t); \
(info)->cef_version_major = CEF_VERSION_MAJOR; \
(info)->cef_version_minor = CEF_VERSION_MINOR; \
(info)->cef_version_patch = CEF_VERSION_PATCH; \
(info)->cef_commit_number = CEF_COMMIT_NUMBER; \
(info)->chrome_version_major = CHROME_VERSION_MAJOR; \
(info)->chrome_version_minor = CHROME_VERSION_MINOR; \
(info)->chrome_version_build = CHROME_VERSION_BUILD; \
(info)->chrome_version_patch = CHROME_VERSION_PATCH
#ifdef __cplusplus
}
#endif

View File

@@ -41,6 +41,8 @@
#include <windows.h>
#endif
#include "include/internal/cef_export.h"
#ifdef __cplusplus
extern "C" {
#endif

View File

@@ -672,7 +672,11 @@ typedef struct _cef_browser_settings_t {
/// Controls whether databases can be used. Also configurable using the
/// "disable-databases" command-line switch.
///
#if CEF_API_ADDED(13800)
cef_state_t databases_deprecated;
#else
cef_state_t databases;
#endif
///
/// Controls whether WebGL can be used. Note that WebGL requires hardware
@@ -1061,6 +1065,11 @@ typedef enum {
CEF_RESULT_CODE_CHROME_FIRST,
#if CEF_API_ADDED(13800)
/// The process is of an unknown type.
CEF_RESULT_CODE_BAD_PROCESS_TYPE = 6,
#endif
/// A critical chrome file is missing.
CEF_RESULT_CODE_MISSING_DATA = 7,
@@ -1093,7 +1102,16 @@ typedef enum {
/// system state can't be recovered and will be unstable.
CEF_RESULT_CODE_SYSTEM_RESOURCE_EXHAUSTED = 37,
#if CEF_API_ADDED(13800)
/// The browser process exited because it was re-launched without elevation.
CEF_RESULT_CODE_NORMAL_EXIT_AUTO_DE_ELEVATED = 38,
#endif
#if CEF_API_ADDED(13800)
CEF_RESULT_CODE_CHROME_LAST = 39,
#else
CEF_RESULT_CODE_CHROME_LAST = 38,
#endif
// The following values should be kept in sync with Chromium's
// sandbox::TerminationCodes type.
@@ -3628,6 +3646,9 @@ typedef enum {
#endif
#if CEF_API_ADDED(13400)
CEF_CPAIT_CHANGE_PASSWORD,
#endif
#if CEF_API_ADDED(13800)
CEF_CPAIT_LENS_OVERLAY_HOMEWORK,
#endif
CEF_CPAIT_NUM_VALUES,
} cef_chrome_page_action_icon_type_t;

View File

@@ -43,11 +43,12 @@ extern "C" {
/// ContentSettingsType type.
///
typedef enum {
// This setting governs whether cookies are enabled by the user in the
/// This setting governs whether cookies are enabled by the user in the
/// provided context. However, it may be overridden by other settings. This
/// enum should NOT be read directly to determine whether cookies are enabled;
/// the client should instead rely on the CookieSettings API.
CEF_CONTENT_SETTING_TYPE_COOKIES,
CEF_CONTENT_SETTING_TYPE_IMAGES,
CEF_CONTENT_SETTING_TYPE_JAVASCRIPT,
@@ -235,11 +236,15 @@ typedef enum {
/// screens. See also: https://w3c.github.io/window-placement
CEF_CONTENT_SETTING_TYPE_WINDOW_MANAGEMENT,
/// Stores whether to allow insecure websites to make private network
/// requests.
/// See also: https://wicg.github.io/cors-rfc1918
/// Set through enterprise policies only.
/// Stores whether to allow insecure websites to make private network
/// requests.
/// See also: https://wicg.github.io/cors-rfc1918
/// Set through enterprise policies only.
#if CEF_API_ADDED(13800)
CEF_CONTENT_SETTING_TYPE_INSECURE_PRIVATE_NETWORK_DEPRECATED,
#else
CEF_CONTENT_SETTING_TYPE_INSECURE_PRIVATE_NETWORK,
#endif
/// Content setting which stores whether or not a site can access low-level
/// locally installed font data using the Local Fonts Access API.
@@ -329,7 +334,7 @@ typedef enum {
/// HTTP header.
CEF_CONTENT_SETTING_TYPE_FEDERATED_IDENTITY_IDENTITY_PROVIDER_SIGNIN_STATUS,
/// Website setting which is used for UnusedSitePermissionsService to
/// Website setting which is used for RevokedPermissionsService to
/// store revoked permissions of unused sites from unused site permissions
/// feature.
CEF_CONTENT_SETTING_TYPE_REVOKED_UNUSED_SITE_PERMISSIONS,
@@ -382,11 +387,11 @@ typedef enum {
/// a requesting-origin/top-level-site combination and persistent.
CEF_CONTENT_SETTING_TYPE_TOP_LEVEL_TPCD_TRIAL,
/// Content Setting for a first-party origin trial that allows websites to
/// enable third-party cookie deprecation.
/// ALLOW (default): no effect (e.g. third-party cookies allowed, if not
/// blocked otherwise).
/// BLOCK: third-party cookies blocked, but 3PCD mitigations enabled.
/// Content Setting for a first-party origin trial that allows websites to
/// enable third-party cookie deprecation.
/// ALLOW (default): no effect (e.g. third-party cookies allowed, if not
/// blocked otherwise).
/// BLOCK: third-party cookies blocked, but 3PCD mitigations enabled.
#if CEF_API_ADDED(13601)
CEF_CONTENT_SETTING_TYPE_TOP_LEVEL_TPCD_ORIGIN_TRIAL,
#else
@@ -442,7 +447,7 @@ typedef enum {
/// access to mouse inputs.
CEF_CONTENT_SETTING_TYPE_POINTER_LOCK,
/// Website setting which is used for UnusedSitePermissionsService to store
/// Website setting which is used for RevokedPermissionsService to store
/// auto-revoked notification permissions from abusive sites.
CEF_CONTENT_SETTING_TYPE_REVOKED_ABUSIVE_NOTIFICATION_PERMISSIONS,
@@ -500,7 +505,7 @@ typedef enum {
#endif
#if CEF_API_ADDED(13500)
/// Website setting which is used for UnusedSitePermissionsService to
/// Website setting which is used for RevokedPermissionsService to
/// store revoked notification permissions of disruptive sites.
CEF_CONTENT_SETTING_TYPE_REVOKED_DISRUPTIVE_NOTIFICATION_PERMISSIONS,
#endif
@@ -511,6 +516,21 @@ typedef enum {
CEF_CONTENT_SETTING_TYPE_LOCAL_NETWORK_ACCESS,
#endif
#if CEF_API_ADDED(13800)
/// Stores information on-device language packs for which a site has
/// installed using the Web Speech API.
CEF_CONTENT_SETTING_TYPE_ON_DEVICE_SPEECH_RECOGNITION_LANGUAGES_DOWNLOADED,
/// Stores which Translator API language packs the site has initialized.
CEF_CONTENT_SETTING_TYPE_INITIALIZED_TRANSLATIONS,
/// Stores a list of notification ids where content detection found the
/// notification to be suspicious and a warning has already been shown for the
/// site. Used for recovering notification contents from the database if the
/// user decides they would like to see all of these notifications.
CEF_CONTENT_SETTING_TYPE_SUSPICIOUS_NOTIFICATION_IDS,
#endif
CEF_CONTENT_SETTING_TYPE_NUM_VALUES,
} cef_content_setting_types_t;

View File

@@ -567,7 +567,9 @@ struct CefBrowserSettingsTraits {
target->text_area_resize = src->text_area_resize;
target->tab_to_links = src->tab_to_links;
target->local_storage = src->local_storage;
#if !CEF_API_ADDED(13800)
target->databases = src->databases;
#endif
target->webgl = src->webgl;
target->background_color = src->background_color;

View File

@@ -50,6 +50,9 @@
/// indicated. Methods must be called on the browser process UI thread unless
/// otherwise indicated.
///
/// For details on coordinate systems and usage see
/// https://bitbucket.org/chromiumembedded/cef/wiki/GeneralUsage#markdown-header-coordinate-systems
///
/*--cef(source=library)--*/
class CefDisplay : public CefBaseRefCounted {
public:
@@ -129,7 +132,9 @@ class CefDisplay : public CefBaseRefCounted {
/// Returns this Display's device pixel scale factor. This specifies how much
/// the UI should be scaled when the actual output has more pixels than
/// standard displays (which is around 100~120dpi). The potential return
/// values differ by platform.
/// values differ by platform. Windowed browsers with 1.0 zoom will have a
/// JavaScript `window.devicePixelRatio` value matching the associated
/// Display's GetDeviceScaleFactor() value.
///
/*--cef()--*/
virtual float GetDeviceScaleFactor() = 0;

View File

@@ -0,0 +1,151 @@
// Copyright (c) 2025 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 are only available to applications that link
// against the libcef_dll_wrapper target.
//
#ifndef CEF_INCLUDE_WRAPPER_CEF_CERTIFICATE_UTIL_WIN_H_
#define CEF_INCLUDE_WRAPPER_CEF_CERTIFICATE_UTIL_WIN_H_
#pragma once
#include <windows.h>
#include <string>
#include <vector>
namespace cef_certificate_util {
// SHA1 upper-case hex encoded = 40 characters.
inline constexpr size_t kThumbprintLength = 40U;
///
/// Structure populated by GetClientThumbprints().
///
struct ThumbprintsInfo {
///
/// True if one or more signatures exist and all are valid.
///
bool IsSignedAndValid() const {
return !valid_thumbprints.empty() && errors.empty();
}
///
/// True if unsigned, or if one or more signatures exist and all are valid.
///
bool IsUnsignedOrValid() const {
return !has_signature || IsSignedAndValid();
}
///
/// True if this and |other| have the same signature status. If
/// |allow_unsigned| is true then both may be unsigned. Otherwise, one or more
/// signatures must exist, all must be valid, and the primary fingerprint must
/// be the same for both.
///
bool IsSame(const ThumbprintsInfo& other, bool allow_unsigned) const {
if (allow_unsigned && !has_signature && !other.has_signature) {
return true;
}
return IsSignedAndValid() &&
other.HasPrimaryThumbprint(valid_thumbprints[0]);
}
///
/// True if a valid primary signature exists and it matches the specified
/// |thumbprint|.
///
bool HasPrimaryThumbprint(const std::string& thumbprint) const {
return IsSignedAndValid() && valid_thumbprints[0] == thumbprint;
}
///
/// True if a primary signature exists, irrespective of validity.
///
bool has_signature = false;
///
/// Thumbprints for signatures, if any, that passed verification.
///
std::vector<std::string> valid_thumbprints;
///
/// Thumbprints for signatures, if any, that failed verification. Will not be
/// populated if |verify_binary=true| was passed to GetClientThumbprints().
///
std::vector<std::string> invalid_thumbprints;
///
/// Errors (newline delimited) if any signatures failed verification.
///
std::wstring errors;
};
///
/// Process client signatures for the binary at the specified abolute
/// |binary_path| and populate |info|. If |verify_binary| is true and the
/// primary signature fails verification then no further signatures will be
/// processed. For a code signing example and usage details see
/// https://github.com/chromiumembedded/cef/issues/3824#issuecomment-2892139995
///
void GetClientThumbprints(const std::wstring& binary_path,
bool verify_binary,
ThumbprintsInfo& info);
///
/// Evaluate the binary at the specified absolute |binary_path| for common
/// requirements and populate |info|. If the binary is code signed then all
/// signatures must be valid. If |thumbprint| is a SHA1 hash (e.g. 40 character
/// upper-case hex-encoded value) then the primary signature must match that
/// thumbprint. If |allow_unsigned| is true and |thumbprint| is nullptr then the
/// binary may be unsigned, otherwise it must be validly signed. Returns true if
/// all requirements are met.
///
bool ValidateCodeSigning(const std::wstring& binary_path,
const char* thumbprint,
bool allow_unsigned,
ThumbprintsInfo& info);
///
/// Same as ValidateCodeSigning, but failures result in a FATAL error and
/// application termination. Optionally populate |info| is validation succeeds.
/// Usage must be protected by cef::logging::ScopedEarlySupport if called prior
/// to libcef loading.
///
void ValidateCodeSigningAssert(const std::wstring& binary_path,
const char* thumbprint,
bool allow_unsigned,
ThumbprintsInfo* info = nullptr);
} // namespace cef_certificate_util
#endif // CEF_INCLUDE_WRAPPER_CEF_CERTIFICATE_UTIL_WIN_H_

View File

@@ -33,11 +33,11 @@
#include "include/base/cef_build.h"
#ifdef __cplusplus
#include <string>
#if defined(OS_MAC)
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
#endif
///
/// Load the CEF library at the specified |path|. Returns true (1) on
@@ -53,6 +53,12 @@ int cef_unload_library(void);
#ifdef __cplusplus
}
#endif
#endif // defined(OS_MAC)
#ifdef __cplusplus
#include <string>
#if defined(OS_MAC)
@@ -84,7 +90,8 @@ int cef_unload_library(void);
/// #include "include/wrapper/cef_library_loader.h"
///
/// int main(int argc, char* argv[]) {
/// // Initialize the macOS sandbox for this helper process.
/// // Dynamically load and initialize the macOS sandbox for this helper
/// // process.
/// CefScopedSandboxContext sandbox_context;
/// if (!sandbox_context.Initialize(argc, argv))
/// return 1;
@@ -98,7 +105,7 @@ int cef_unload_library(void);
/// }
/// </pre>
///
class CefScopedLibraryLoader {
class CefScopedLibraryLoader final {
public:
CefScopedLibraryLoader();
@@ -124,10 +131,101 @@ class CefScopedLibraryLoader {
private:
bool Load(bool helper);
bool loaded_;
bool loaded_ = false;
};
#endif // defined(OS_MAC)
#elif defined(OS_WIN)
#include <windows.h>
#include "include/cef_version_info.h"
///
/// Scoped helper for loading the CEF library at runtime from a specific
/// location on disk. Can optionally be used to verify code signing status and
/// Chromium version compatibility at the same time. Binaries using this helper
/// must be built with the "/DELAYLOAD:libcef.dll" linker flag.
///
/// Example usage:
///
/// <pre>
/// #include "include/wrapper/cef_library_loader.h"
///
/// int APIENTRY wWinMain(HINSTANCE hInstance,
/// HINSTANCE hPrevInstance,
/// LPTSTR lpCmdLine,
/// int nCmdShow)
/// // Version that was used to compile the CEF client app.
/// cef_version_info_t version_info = {};
/// CEF_POPULATE_VERSION_INFO(&version_info);
///
/// // Dynamically load libcef.dll from the specified location, and verify
/// // that the Chromium version is compatible. Any failures will
/// // intentionally crash the application. All CEF distribution resources
/// // (DLLs, pak, etc) must be located in the same directory.
/// CefScopedLibraryLoader library_loader;
/// if (!library_loader.LoadInSubProcessAssert(&version_info)) {
/// // Not running as a potentially sandboxed sub-process.
/// // Choose the appropriate path for loading libcef.dll...
/// const wchar_t* path = L"c:\\path\\to\\myapp\\cef\\libcef.dll";
/// if (!library_loader.LoadInMainAssert(path, nullptr, true,
/// &version_info)) {
/// // The load failed. We'll crash before reaching this line.
/// NOTREACHED();
/// return CEF_RESULT_CODE_KILLED;
/// }
/// }
///
/// // Continue with CEF initialization...
/// }
/// </pre>
///
class CefScopedLibraryLoader final {
public:
CefScopedLibraryLoader();
CefScopedLibraryLoader(const CefScopedLibraryLoader&) = delete;
CefScopedLibraryLoader& operator=(const CefScopedLibraryLoader&) = delete;
~CefScopedLibraryLoader();
///
/// Load the CEF library (libcef.dll) in the main process from the specified
/// absolute path. If libcef.dll is code signed then all signatures must be
/// valid. If |thumbprint| is a SHA1 hash (e.g. 40 character upper-case
/// hex-encoded value) then the primary signature must match that thumbprint.
/// If |allow_unsigned| is true and |thumbprint| is nullptr then libcef.dll
/// may be unsigned, otherwise it must be validly signed. Failure of code
/// signing requirements or DLL loading will result in a FATAL error and
/// application termination. If |version_info| is specified then the
/// libcef.dll version information must also match. Returns true if the load
/// succeeds. Usage must be protected by cef::logging::ScopedEarlySupport.
///
bool LoadInMainAssert(const wchar_t* dll_path,
const char* thumbprint,
bool allow_unsigned,
cef_version_info_t* version_info);
///
/// Load the CEF library (libcef.dll) in a sub-process that may be sandboxed.
/// The path will be determined based on command-line arguments for the
/// current process. Failure of DLL loading will result in a FATAL error and
/// application termination. If |version_info| is specified then the
/// libcef.dll version information must match. Returns true if the load
/// succeeds. Usage must be protected by cef::logging::ScopedEarlySupport.
///
bool LoadInSubProcessAssert(cef_version_info_t* version_info);
private:
HMODULE handle_ = nullptr;
};
namespace switches {
// Changes to this value require rebuilding libcef.dll.
inline constexpr char kLibcefPath[] = "libcef-path";
inline constexpr wchar_t kLibcefPathW[] = L"libcef-path";
} // namespace switches
#endif // defined(OS_WIN)
#endif // __cplusplus
#endif // CEF_INCLUDE_WRAPPER_CEF_LIBRARY_LOADER_H_

View File

@@ -0,0 +1,65 @@
// Copyright (c) 2025 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 are only available to applications that link
// against the libcef_dll_wrapper target.
//
#ifndef CEF_INCLUDE_WRAPPER_CEF_UTIL_WIN_H_
#define CEF_INCLUDE_WRAPPER_CEF_UTIL_WIN_H_
#pragma once
#include <windows.h>
#include <string>
#include <vector>
namespace cef_util {
// Returns the fully qualified file path for the executable module.
std::wstring GetExePath();
// Returns the fully qualified file path for |module|.
std::wstring GetModulePath(HMODULE module);
// Returns the value of GetLastError() as a string.
std::wstring GetLastErrorAsString();
// Parse command line arguments for |hInstance|.
std::vector<std::wstring> ParseCommandLineArgs(const wchar_t* str);
// Returns the value for |name| in |command_line|, if any.
std::wstring GetCommandLineValue(const std::vector<std::wstring>& command_line,
const std::wstring& name);
} // namespace cef_util
#endif // CEF_INCLUDE_WRAPPER_CEF_UTIL_WIN_H_

View File

@@ -416,24 +416,6 @@ void AlloyBrowserHostImpl::WasHidden(bool hidden) {
}
}
void AlloyBrowserHostImpl::NotifyScreenInfoChanged() {
if (!IsWindowless()) {
DCHECK(false) << "Window rendering is not disabled";
return;
}
if (!CEF_CURRENTLY_ON_UIT()) {
CEF_POST_TASK(
CEF_UIT,
base::BindOnce(&AlloyBrowserHostImpl::NotifyScreenInfoChanged, this));
return;
}
if (platform_delegate_) {
platform_delegate_->NotifyScreenInfoChanged();
}
}
void AlloyBrowserHostImpl::Invalidate(PaintElementType type) {
if (!IsWindowless()) {
DCHECK(false) << "Window rendering is not disabled";
@@ -998,6 +980,11 @@ void AlloyBrowserHostImpl::CloseContents(content::WebContents* source) {
}
}
void AlloyBrowserHostImpl::SetContentsBounds(content::WebContents* source,
const gfx::Rect& bounds) {
contents_delegate_.SetContentsBoundsEx(source, bounds);
}
void AlloyBrowserHostImpl::UpdateTargetURL(content::WebContents* source,
const GURL& url) {
contents_delegate_.UpdateTargetURL(source, url);

View File

@@ -90,7 +90,6 @@ class AlloyBrowserHostImpl : public CefBrowserHostBase,
bool IsWindowRenderingDisabled() override;
void WasResized() override;
void WasHidden(bool hidden) override;
void NotifyScreenInfoChanged() override;
void Invalidate(PaintElementType type) override;
void SendExternalBeginFrame() override;
void SendTouchEvent(const CefTouchEvent& event) override;
@@ -193,6 +192,8 @@ class AlloyBrowserHostImpl : public CefBrowserHostBase,
void LoadingStateChanged(content::WebContents* source,
bool should_show_loading_ui) override;
void CloseContents(content::WebContents* source) override;
void SetContentsBounds(content::WebContents* source,
const gfx::Rect& bounds) override;
void UpdateTargetURL(content::WebContents* source, const GURL& url) override;
bool DidAddMessageToConsole(content::WebContents* source,
blink::mojom::ConsoleMessageLevel log_level,

View File

@@ -142,6 +142,18 @@ content::WebContents* CefBrowserContentsDelegate::OpenURLFromTabEx(
return nullptr;
}
bool CefBrowserContentsDelegate::SetContentsBoundsEx(
content::WebContents* source,
const gfx::Rect& bounds) {
if (auto c = client()) {
if (auto handler = c->GetDisplayHandler()) {
return handler->OnContentsBoundsChange(
browser(), {bounds.x(), bounds.y(), bounds.width(), bounds.height()});
}
}
return false;
}
void CefBrowserContentsDelegate::LoadingStateChanged(
content::WebContents* source,
bool should_show_loading_ui) {

View File

@@ -87,6 +87,10 @@ class CefBrowserContentsDelegate : public content::WebContentsDelegate,
base::OnceCallback<void(content::NavigationHandle&)>&
navigation_handle_callback);
// Same as SetContentsBounds but returning false if unhandled.
bool SetContentsBoundsEx(content::WebContents* source,
const gfx::Rect& bounds);
// WebContentsDelegate methods:
void LoadingStateChanged(content::WebContents* source,
bool should_show_loading_ui) override;

View File

@@ -817,9 +817,30 @@ void CefBrowserHostBase::NotifyMoveOrResizeStarted() {
if (platform_delegate_) {
platform_delegate_->NotifyMoveOrResizeStarted();
}
#else
LOG(WARNING)
<< "Incorrect usage of CefBrowserHost::NotifyMoveOrResizeStarted";
#endif
}
void CefBrowserHostBase::NotifyScreenInfoChanged() {
if (!CEF_CURRENTLY_ON_UIT()) {
CEF_POST_TASK(
CEF_UIT,
base::BindOnce(&CefBrowserHostBase::NotifyScreenInfoChanged, this));
return;
}
if (platform_delegate_) {
if (IsWindowless() || platform_delegate_->HasExternalParent()) {
platform_delegate_->NotifyScreenInfoChanged();
} else {
LOG(WARNING)
<< "Incorrect usage of CefBrowserHost::NotifyScreenInfoChanged";
}
}
}
bool CefBrowserHostBase::IsFullscreen() {
if (!CEF_CURRENTLY_ON_UIT()) {
DCHECK(false) << "called on invalid thread";

View File

@@ -265,6 +265,7 @@ class CefBrowserHostBase : public CefBrowserHost,
void SetAudioMuted(bool mute) override;
bool IsAudioMuted() override;
void NotifyMoveOrResizeStarted() override;
void NotifyScreenInfoChanged() override;
bool IsFullscreen() override;
void ExitFullscreen(bool will_cause_resize) override;
bool IsRenderProcessUnresponsive() override;

View File

@@ -244,8 +244,7 @@ void CefBrowserPlatformDelegate::PopupBrowserCreated(
return;
}
CefRefPtr<CefBrowserView> new_browser_view =
CefBrowserView::GetForBrowser(new_browser);
auto new_browser_view = new_browser->GetBrowserView();
CHECK(new_browser_view);
bool popup_handled = false;
@@ -389,9 +388,7 @@ bool CefBrowserPlatformDelegate::IsHidden() const {
return false;
}
void CefBrowserPlatformDelegate::NotifyScreenInfoChanged() {
DCHECK(false);
}
void CefBrowserPlatformDelegate::NotifyScreenInfoChanged() {}
void CefBrowserPlatformDelegate::Invalidate(cef_paint_element_type_t type) {
DCHECK(false);

View File

@@ -306,7 +306,7 @@ class CefBrowserPlatformDelegate {
virtual bool IsHidden() const;
// Notify the browser that screen information has changed. Only used with
// windowless rendering.
// windowless rendering and external (client-provided) root window.
virtual void NotifyScreenInfoChanged();
// Invalidate the view. Only used with windowless rendering.

View File

@@ -173,6 +173,12 @@ class BrowserDelegate : public content::WebContentsDelegate {
navigation_handle_callback) {
return true;
}
// Same as SetContentsBounds but returning false if unhandled.
virtual bool SetContentsBoundsEx(content::WebContents* source,
const gfx::Rect& bounds) {
return false;
}
};
} // namespace cef

View File

@@ -573,6 +573,14 @@ bool ChromeBrowserDelegate::OpenURLFromTabEx(
return true;
}
bool ChromeBrowserDelegate::SetContentsBoundsEx(content::WebContents* source,
const gfx::Rect& bounds) {
if (auto delegate = GetDelegateForWebContents(source)) {
return delegate->SetContentsBoundsEx(source, bounds);
}
return false;
}
void ChromeBrowserDelegate::LoadingStateChanged(content::WebContents* source,
bool should_show_loading_ui) {
if (auto delegate = GetDelegateForWebContents(source)) {

View File

@@ -94,6 +94,8 @@ class ChromeBrowserDelegate : public cef::BrowserDelegate {
const content::OpenURLParams& params,
base::OnceCallback<void(content::NavigationHandle&)>&
navigation_handle_callback) override;
bool SetContentsBoundsEx(content::WebContents* source,
const gfx::Rect& bounds) override;
// WebContentsDelegate methods:
void WebContentsCreated(content::WebContents* source_contents,

View File

@@ -250,10 +250,6 @@ void ChromeBrowserHostImpl::WasHidden(bool hidden) {
NOTIMPLEMENTED();
}
void ChromeBrowserHostImpl::NotifyScreenInfoChanged() {
NOTIMPLEMENTED();
}
void ChromeBrowserHostImpl::Invalidate(PaintElementType type) {
NOTIMPLEMENTED();
}

View File

@@ -84,7 +84,6 @@ class ChromeBrowserHostImpl : public CefBrowserHostBase {
bool IsWindowRenderingDisabled() override { return false; }
void WasResized() override;
void WasHidden(bool hidden) override;
void NotifyScreenInfoChanged() override;
void Invalidate(PaintElementType type) override;
void SendExternalBeginFrame() override;
void SendTouchEvent(const CefTouchEvent& event) override;

View File

@@ -9,6 +9,7 @@
#include "base/command_line.h"
#include "base/path_service.h"
#include "cef/include/wrapper/cef_library_loader.h"
#include "cef/libcef/browser/browser_frame.h"
#include "cef/libcef/browser/browser_host_base.h"
#include "cef/libcef/browser/browser_info_manager.h"
@@ -50,6 +51,10 @@
#include "cef/libcef/browser/chrome/chrome_web_contents_view_delegate_cef.h"
#endif
#if BUILDFLAG(IS_WIN)
#include "cef/libcef_dll/bootstrap/bootstrap_util_win.h"
#endif
namespace {
class CefSelectClientCertificateCallbackImpl
@@ -160,6 +165,18 @@ void HandleExternalProtocolHelper(
isolation_info, nullptr);
}
#if BUILDFLAG(IS_WIN)
// Returns the module handle that contains this code (e.g. libcef.dll).
HINSTANCE GetCodeModuleHandle() {
HMODULE hModule = nullptr;
CHECK(::GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS |
GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
reinterpret_cast<LPCWSTR>(GetCodeModuleHandle),
&hModule));
return hModule;
}
#endif
} // namespace
ChromeContentBrowserClientCef::ChromeContentBrowserClientCef() = default;
@@ -214,6 +231,23 @@ void ChromeContentBrowserClientCef::AppendExtraCommandLineSwitches(
command_line->CopySwitchesFrom(*browser_cmd, kSwitchNames);
}
#if BUILDFLAG(IS_WIN)
{
const auto& exe_path = bootstrap_util::GetExePath();
const auto& module_value =
bootstrap_util::GetValidatedModuleValue(*browser_cmd, exe_path);
if (!module_value.empty()) {
command_line->AppendSwitchNative(bootstrap_util::switches::kModule,
module_value);
}
const auto& libcef_path =
bootstrap_util::GetModulePath(GetCodeModuleHandle());
if (libcef_path.DirName() != exe_path.DirName()) {
command_line->AppendSwitchPath(switches::kLibcefPath, libcef_path);
}
}
#endif
const std::string& process_type =
command_line->GetSwitchValueASCII(switches::kProcessType);
@@ -554,13 +588,10 @@ bool ChromeContentBrowserClientCef::HandleExternalProtocol(
return true;
}
std::vector<std::unique_ptr<content::NavigationThrottle>>
ChromeContentBrowserClientCef::CreateThrottlesForNavigation(
content::NavigationHandle* navigation_handle) {
auto throttles = ChromeContentBrowserClient::CreateThrottlesForNavigation(
navigation_handle);
throttle::CreateThrottlesForNavigation(navigation_handle, throttles);
return throttles;
void ChromeContentBrowserClientCef::CreateThrottlesForNavigation(
content::NavigationThrottleRegistry& registry) {
ChromeContentBrowserClient::CreateThrottlesForNavigation(registry);
throttle::CreateThrottlesForNavigation(registry);
}
bool ChromeContentBrowserClientCef::ConfigureNetworkContextParams(

View File

@@ -113,9 +113,8 @@ class ChromeContentBrowserClientCef : public ChromeContentBrowserClient {
const net::IsolationInfo& isolation_info,
mojo::PendingRemote<network::mojom::URLLoaderFactory>* out_factory)
override;
std::vector<std::unique_ptr<content::NavigationThrottle>>
CreateThrottlesForNavigation(
content::NavigationHandle* navigation_handle) override;
void CreateThrottlesForNavigation(
content::NavigationThrottleRegistry& registry) override;
bool ConfigureNetworkContextParams(
content::BrowserContext* context,
bool in_memory,

View File

@@ -14,6 +14,10 @@
#include "ui/views/win/hwnd_util.h"
#endif
#if defined(USE_AURA)
#include "cef/libcef/browser/native/browser_platform_delegate_native_aura.h"
#endif
namespace {
gfx::AcceleratedWidget GetParentWidget(const CefWindowInfo& window_info) {
@@ -61,6 +65,9 @@ class ChildWindowDelegate : public CefWindowDelegate {
void OnWindowDestroyed(CefRefPtr<CefWindow> window) override {
browser_view_ = nullptr;
window_ = nullptr;
#if BUILDFLAG(IS_WIN)
native_delegate_ = nullptr;
#endif
}
CefRect GetInitialBounds(CefRefPtr<CefWindow> window) override {
@@ -71,22 +78,38 @@ class ChildWindowDelegate : public CefWindowDelegate {
return initial_bounds;
}
#if defined(USE_AURA)
void OnWindowBoundsChanged(CefRefPtr<CefWindow> window,
const CefRect& new_bounds) override {
if (native_delegate_) {
// Send new bounds to the renderer process and trigger the resize event.
native_delegate_->NotifyScreenInfoChanged();
}
}
#endif
private:
void ShowWindow() {
#if defined(USE_AURA)
auto browser = CefBrowserHostBase::FromBrowser(browser_view_->GetBrowser());
auto platform_delegate = browser->platform_delegate();
DCHECK(platform_delegate->IsViewsHosted());
auto chrome_delegate =
static_cast<CefBrowserPlatformDelegateChromeViews*>(platform_delegate);
native_delegate_ = static_cast<CefBrowserPlatformDelegateNativeAura*>(
chrome_delegate->native_delegate());
native_delegate_->InstallRootWindowBoundsCallback();
#if BUILDFLAG(IS_WIN)
auto widget = static_cast<CefWindowImpl*>(window_.get())->widget();
DCHECK(widget);
const HWND widget_hwnd = HWNDForWidget(widget);
DCHECK(widget_hwnd);
// The native delegate needs state to perform some actions.
auto browser = CefBrowserHostBase::FromBrowser(browser_view_->GetBrowser());
auto platform_delegate = browser->platform_delegate();
DCHECK(platform_delegate->IsViewsHosted());
auto chrome_delegate =
static_cast<CefBrowserPlatformDelegateChromeViews*>(platform_delegate);
auto native_delegate = static_cast<CefBrowserPlatformDelegateNativeWin*>(
chrome_delegate->native_delegate());
native_delegate->set_widget(widget, widget_hwnd);
// The Windows delegate needs state to perform some actions.
auto* delegate_win =
static_cast<CefBrowserPlatformDelegateNativeWin*>(native_delegate_);
delegate_win->set_widget(widget, widget_hwnd);
if (window_info_.ex_style & WS_EX_NOACTIVATE) {
const DWORD widget_ex_styles = GetWindowLongPtr(widget_hwnd, GWL_EXSTYLE);
@@ -105,6 +128,7 @@ class ChildWindowDelegate : public CefWindowDelegate {
return;
}
#endif // BUILDFLAG(IS_WIN)
#endif // defined(USE_AURA)
window_->Show();
@@ -112,7 +136,6 @@ class ChildWindowDelegate : public CefWindowDelegate {
browser_view_->RequestFocus();
}
private:
ChildWindowDelegate(CefRefPtr<CefBrowserView> browser_view,
const CefWindowInfo& window_info)
: browser_view_(browser_view), window_info_(window_info) {}
@@ -122,6 +145,11 @@ class ChildWindowDelegate : public CefWindowDelegate {
CefRefPtr<CefWindow> window_;
#if defined(USE_AURA)
base::raw_ptr<CefBrowserPlatformDelegateNativeAura> native_delegate_ =
nullptr;
#endif
IMPLEMENT_REFCOUNTING(ChildWindowDelegate);
};

View File

@@ -22,9 +22,9 @@
#include "ui/base/ui_base_switches.h"
#if BUILDFLAG(IS_WIN)
#include "base/debug/alias.h"
#include "base/strings/utf_string_conversions.h"
#include "cef/include/internal/cef_win.h"
#include "cef/libcef/browser/preferred_stack_size_win.inc"
#include "chrome/chrome_elf/chrome_elf_main.h"
#include "chrome/install_static/initialize_from_primary_module.h"
#endif
@@ -185,110 +185,6 @@ base::FilePath NormalizeCachePathAndSet(cef_string_t& path_str,
return path;
}
// Based on chrome/app/chrome_exe_main_win.cc.
// In 32-bit builds, the main thread starts with the default (small) stack size.
// The ARCH_CPU_32_BITS blocks here and below are in support of moving the main
// thread to a fiber with a larger stack size.
#if BUILDFLAG(IS_WIN) && defined(ARCH_CPU_32_BITS)
// The information needed to transfer control to the large-stack fiber and later
// pass the main routine's exit code back to the small-stack fiber prior to
// termination.
struct FiberState {
FiberState(wWinMainPtr wWinMain,
HINSTANCE hInstance,
LPWSTR lpCmdLine,
int nCmdShow) {
this->wWinMain = wWinMain;
this->hInstance = hInstance;
this->lpCmdLine = lpCmdLine;
this->nCmdShow = nCmdShow;
}
FiberState(mainPtr main, int argc, char** argv) {
this->main = main;
this->argc = argc;
this->argv = argv;
}
wWinMainPtr wWinMain = nullptr;
HINSTANCE hInstance;
LPWSTR lpCmdLine;
int nCmdShow;
mainPtr main = nullptr;
int argc;
char** argv;
LPVOID original_fiber;
int fiber_result;
};
// A PFIBER_START_ROUTINE function run on a large-stack fiber that calls the
// main routine, stores its return value, and returns control to the small-stack
// fiber. |params| must be a pointer to a FiberState struct.
void WINAPI FiberBinder(void* params) {
auto* fiber_state = static_cast<FiberState*>(params);
// Call the main routine from the fiber. Reusing the entry point minimizes
// confusion when examining call stacks in crash reports - seeing wWinMain on
// the stack is a handy hint that this is the main thread of the process.
if (fiber_state->main) {
fiber_state->fiber_result =
fiber_state->main(fiber_state->argc, fiber_state->argv);
} else {
fiber_state->fiber_result =
fiber_state->wWinMain(fiber_state->hInstance, nullptr,
fiber_state->lpCmdLine, fiber_state->nCmdShow);
}
// Switch back to the main thread to exit.
::SwitchToFiber(fiber_state->original_fiber);
}
int RunMainWithPreferredStackSize(FiberState& fiber_state) {
enum class FiberStatus { kConvertFailed, kCreateFiberFailed, kSuccess };
FiberStatus fiber_status = FiberStatus::kSuccess;
// GetLastError result if fiber conversion failed.
DWORD fiber_error = ERROR_SUCCESS;
if (!::IsThreadAFiber()) {
// Make the main thread's stack size 4 MiB so that it has roughly the same
// effective size as the 64-bit build's 8 MiB stack.
constexpr size_t kStackSize = 4 * 1024 * 1024; // 4 MiB
// Leak the fiber on exit.
LPVOID original_fiber =
::ConvertThreadToFiberEx(nullptr, FIBER_FLAG_FLOAT_SWITCH);
if (original_fiber) {
fiber_state.original_fiber = original_fiber;
// Create a fiber with a bigger stack and switch to it. Leak the fiber on
// exit.
LPVOID big_stack_fiber = ::CreateFiberEx(
0, kStackSize, FIBER_FLAG_FLOAT_SWITCH, FiberBinder, &fiber_state);
if (big_stack_fiber) {
::SwitchToFiber(big_stack_fiber);
// The fibers must be cleaned up to avoid obscure TLS-related shutdown
// crashes.
::DeleteFiber(big_stack_fiber);
::ConvertFiberToThread();
// Control returns here after CEF has finished running on FiberMain.
return fiber_state.fiber_result;
}
fiber_status = FiberStatus::kCreateFiberFailed;
} else {
fiber_status = FiberStatus::kConvertFailed;
}
// If we reach here then creating and switching to a fiber has failed. This
// probably means we are low on memory and will soon crash. Try to report
// this error once crash reporting is initialized.
fiber_error = ::GetLastError();
base::debug::Alias(&fiber_error);
}
// If we are already a fiber then continue normal execution.
// Intentionally crash if converting to a fiber failed.
CHECK_EQ(fiber_status, FiberStatus::kSuccess);
return -1;
}
#endif // BUILDFLAG(IS_WIN) && defined(ARCH_CPU_32_BITS)
} // namespace
NO_STACK_PROTECTOR
@@ -418,23 +314,6 @@ void CefQuitMessageLoop() {
#if BUILDFLAG(IS_WIN)
#if defined(ARCH_CPU_32_BITS)
int CefRunWinMainWithPreferredStackSize(wWinMainPtr wWinMain,
HINSTANCE hInstance,
LPWSTR lpCmdLine,
int nCmdShow) {
CHECK(wWinMain && hInstance);
FiberState fiber_state(wWinMain, hInstance, lpCmdLine, nCmdShow);
return RunMainWithPreferredStackSize(fiber_state);
}
int CefRunMainWithPreferredStackSize(mainPtr main, int argc, char* argv[]) {
CHECK(main);
FiberState fiber_state(main, argc, argv);
return RunMainWithPreferredStackSize(fiber_state);
}
#endif // defined(ARCH_CPU_32_BITS)
void CefSetOSModalLoop(bool osModalLoop) {
// Verify that the context is in a valid state.
if (!CONTEXT_STATE_VALID()) {

View File

@@ -0,0 +1,55 @@
// Copyright 2020 The Chromium Embedded Framework Authors.
// Portions copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "cef/libcef/browser/crashpad_runner.h"
#include "base/command_line.h"
#include "base/files/file_path.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "third_party/crashpad/crashpad/handler/handler_main.h"
namespace crashpad_runner {
// Based on components/crash/core/app/run_as_crashpad_handler_win.cc
int RunAsCrashpadHandler(const base::CommandLine& command_line) {
// Remove the "--type=crashpad-handler" command-line flag that will otherwise
// confuse the crashpad handler.
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());
#if BUILDFLAG(IS_POSIX)
// HandlerMain on POSIX uses the system version of getopt_long which expects
// the first argument to be the program name.
argv.insert(argv.begin(), command_line.GetProgram().value());
#endif
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 BUILDFLAG(IS_WIN)
storage.push_back(base::WideToUTF8(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(), nullptr);
}
} // namespace crashpad_runner

View File

@@ -0,0 +1,22 @@
// Copyright 2020 The Chromium Embedded Framework Authors.
// Portions copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CEF_LIBCEF_BROWSER_CRASHPAD_RUNNER_H_
#define CEF_LIBCEF_BROWSER_CRASHPAD_RUNNER_H_
#include "base/command_line.h"
namespace crashpad_runner {
// 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/core/app/BUILD.gn. CEF uses an embedded handler on all
// platforms 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);
} // namespace crashpad_runner
#endif // CEF_LIBCEF_BROWSER_CRASHPAD_RUNNER_H_

View File

@@ -13,11 +13,13 @@
#include "base/synchronization/waitable_event.h"
#include "cef/libcef/browser/browser_message_loop.h"
#include "cef/libcef/browser/chrome/chrome_content_browser_client_cef.h"
#include "cef/libcef/browser/crashpad_runner.h"
#include "cef/libcef/browser/thread_util.h"
#include "cef/libcef/common/app_manager.h"
#include "cef/libcef/common/cef_switches.h"
#include "chrome/browser/browser_process_impl.h"
#include "chrome/browser/chrome_process_singleton.h"
#include "chrome/chrome_elf/chrome_elf_main.h"
#include "chrome/common/chrome_result_codes.h"
#include "components/crash/core/app/crash_switches.h"
#include "components/keep_alive_registry/keep_alive_types.h"
@@ -27,7 +29,6 @@
#include "content/public/app/content_main.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/common/content_switches.h"
#include "third_party/crashpad/crashpad/handler/handler_main.h"
#if BUILDFLAG(IS_WIN)
#include <windows.h>
@@ -35,57 +36,11 @@
#include <memory>
#include "content/public/app/sandbox_helper_win.h"
#include "sandbox/policy/mojom/sandbox.mojom.h"
#include "sandbox/policy/sandbox_type.h"
#include "sandbox/win/src/sandbox_types.h"
#endif
namespace {
// Based on components/crash/core/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/core/app/BUILD.gn. CEF uses an embedded handler on all
// platforms 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());
#if BUILDFLAG(IS_POSIX)
// HandlerMain on POSIX uses the system version of getopt_long which expects
// the first argument to be the program name.
argv.insert(argv.begin(), command_line.GetProgram().value());
#endif
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 BUILDFLAG(IS_WIN)
storage.push_back(base::WideToUTF8(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(), nullptr);
}
} // namespace
CefMainRunner::CefMainRunner(bool multi_threaded_message_loop,
bool external_message_pump)
: multi_threaded_message_loop_(multi_threaded_message_loop),
@@ -224,10 +179,15 @@ int CefMainRunner::RunAsHelperProcess(const CefMainArgs& args,
// If no process type is specified then it represents the browser process and
// we do nothing.
if (!command_line.HasSwitch(switches::kProcessType)) {
return -1;
}
const std::string& process_type =
command_line.GetSwitchValueASCII(switches::kProcessType);
if (process_type.empty()) {
return -1;
// Early exit on invalid process type.
return CEF_RESULT_CODE_BAD_PROCESS_TYPE;
}
auto main_delegate = std::make_unique<ChromeMainDelegateCef>(
@@ -235,15 +195,35 @@ int CefMainRunner::RunAsHelperProcess(const CefMainArgs& args,
BeforeMainInitialize(args);
if (process_type == crash_reporter::switches::kCrashpadHandler) {
return RunAsCrashpadHandler(command_line);
return crashpad_runner::RunAsCrashpadHandler(command_line);
}
// Execute the secondary process.
content::ContentMainParams main_params(main_delegate.get());
#if BUILDFLAG(IS_WIN)
// Initialize the sandbox services.
// Match the logic in MainDllLoader::Launch.
sandbox::SandboxInterfaceInfo sandbox_info = {nullptr};
if (windows_sandbox_info == nullptr) {
content::InitializeSandboxInfo(&sandbox_info);
// IsUnsandboxedSandboxType() can't be used here because its result can be
// gated behind a feature flag, which are not yet initialized.
const bool is_sandboxed =
sandbox::policy::SandboxTypeFromCommandLine(command_line) !=
sandbox::mojom::Sandbox::kNoSandbox;
// When using cef_sandbox_info_create() the sandbox info will always be
// initialized. This is incorrect for cases where the sandbox is disabled, and
// we adjust for that here.
if (!is_sandboxed || windows_sandbox_info == nullptr) {
if (is_sandboxed) {
// For child processes that are running as --no-sandbox, don't
// initialize the sandbox info, otherwise they'll be treated as brokers
// (as if they were the browser).
content::InitializeSandboxInfo(
&sandbox_info, IsExtensionPointDisableSet()
? sandbox::MITIGATION_EXTENSION_POINT_DISABLE
: 0);
}
windows_sandbox_info = &sandbox_info;
}

View File

@@ -5,6 +5,7 @@
#include "cef/libcef/browser/native/browser_platform_delegate_native.h"
#include "cef/libcef/browser/alloy/alloy_browser_host_impl.h"
#include "content/browser/renderer_host/render_widget_host_impl.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/render_widget_host.h"
#include "third_party/blink/public/common/input/web_mouse_event.h"
@@ -24,3 +25,25 @@ void CefBrowserPlatformDelegateNative::WasResized() {
host->GetWidget()->SynchronizeVisualProperties();
}
}
void CefBrowserPlatformDelegateNative::NotifyScreenInfoChanged() {
content::RenderWidgetHostImpl* render_widget_host = nullptr;
if (web_contents_) {
if (auto* rvh = web_contents_->GetRenderViewHost()) {
render_widget_host =
content::RenderWidgetHostImpl::From(rvh->GetWidget());
}
}
if (!render_widget_host) {
return;
}
// Send updated screen bounds information to the renderer process.
if (render_widget_host->delegate()) {
render_widget_host->delegate()->SendScreenRects();
} else {
render_widget_host->SendScreenRects();
}
render_widget_host->NotifyScreenInfoChanged();
}

View File

@@ -32,6 +32,7 @@ class CefBrowserPlatformDelegateNative
// CefBrowserPlatformDelegate methods:
SkColor GetBackgroundColor() const override;
void WasResized() override;
void NotifyScreenInfoChanged() override;
// Translate CEF events to Chromium/Blink Web events.
virtual input::NativeWebKeyboardEvent TranslateWebKeyEvent(

View File

@@ -4,6 +4,7 @@
#include "cef/libcef/browser/native/browser_platform_delegate_native_aura.h"
#include "cef/libcef/browser/browser_host_base.h"
#include "cef/libcef/browser/native/menu_runner_views_aura.h"
#include "cef/libcef/browser/views/view_util.h"
#include "content/browser/renderer_host/render_widget_host_view_aura.h"
@@ -19,6 +20,42 @@ CefBrowserPlatformDelegateNativeAura::CefBrowserPlatformDelegateNativeAura(
SkColor background_color)
: CefBrowserPlatformDelegateNative(window_info, background_color) {}
void CefBrowserPlatformDelegateNativeAura::InstallRootWindowBoundsCallback() {
auto* host_view = GetHostView();
CHECK(host_view);
host_view->SetRootWindowBoundsCallback(base::BindRepeating(
[](base::WeakPtr<CefBrowserPlatformDelegateNativeAura> self) {
return self->RootWindowBoundsCallback();
},
weak_ptr_factory_.GetWeakPtr()));
}
std::optional<gfx::Rect>
CefBrowserPlatformDelegateNativeAura::RootWindowBoundsCallback() {
if (browser_) {
if (auto client = browser_->client()) {
if (auto handler = client->GetDisplayHandler()) {
CefRect rect;
if (handler->GetRootWindowScreenRect(browser_.get(), rect) &&
!rect.IsEmpty()) {
return gfx::Rect(rect.x, rect.y, rect.width, rect.height);
}
}
}
}
// Call the default platform implementation, if any.
return GetRootWindowBounds();
}
void CefBrowserPlatformDelegateNativeAura::RenderViewReady() {
CefBrowserPlatformDelegateNative::RenderViewReady();
// The RWHV should now exist for Alloy style browsers.
InstallRootWindowBoundsCallback();
}
void CefBrowserPlatformDelegateNativeAura::SendKeyEvent(
const CefKeyEvent& event) {
auto view = GetHostView();

View File

@@ -5,19 +5,19 @@
#ifndef CEF_LIBCEF_BROWSER_NATIVE_BROWSER_PLATFORM_DELEGATE_NATIVE_AURA_H_
#define CEF_LIBCEF_BROWSER_NATIVE_BROWSER_PLATFORM_DELEGATE_NATIVE_AURA_H_
#include <optional>
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "cef/libcef/browser/native/browser_platform_delegate_native.h"
#include "ui/events/event.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/vector2d.h"
namespace content {
class RenderWidgetHostViewAura;
}
namespace gfx {
class Vector2d;
}
// Windowed browser implementation for Aura platforms.
class CefBrowserPlatformDelegateNativeAura
: public CefBrowserPlatformDelegateNative {
@@ -25,7 +25,10 @@ class CefBrowserPlatformDelegateNativeAura
CefBrowserPlatformDelegateNativeAura(const CefWindowInfo& window_info,
SkColor background_color);
void InstallRootWindowBoundsCallback();
// CefBrowserPlatformDelegate methods:
void RenderViewReady() override;
void SendKeyEvent(const CefKeyEvent& event) override;
void SendMouseClickEvent(const CefMouseEvent& event,
CefBrowserHost::MouseButtonType type,
@@ -71,9 +74,16 @@ class CefBrowserPlatformDelegateNativeAura
int deltaY) const;
virtual gfx::Vector2d GetUiWheelEventOffset(int deltaX, int deltaY) const;
// Returns the root window bounds in screen DIP coordinates.
virtual std::optional<gfx::Rect> GetRootWindowBounds() {
return std::nullopt;
}
protected:
base::OnceClosure GetWidgetDeleteCallback();
std::optional<gfx::Rect> RootWindowBoundsCallback();
static base::TimeTicks GetEventTimeStamp();
static int TranslateUiEventModifiers(uint32_t cef_modifiers);
static int TranslateUiChangedButtonFlags(uint32_t cef_modifiers);

View File

@@ -73,7 +73,7 @@ CefRect GetScreenFrameRectFromDIPContentRect(HWND window,
// Convert from DIP using a method that can handle multiple displays with
// different DPI. If |window| is nullptr the closest display will be used.
const auto screen_rect =
display::win::ScreenWin::DIPToScreenRect(window, dip_rect);
display::win::GetScreenWin()->DIPToScreenRect(window, dip_rect);
RECT rect = {screen_rect.x(), screen_rect.y(),
screen_rect.x() + screen_rect.width(),
@@ -109,7 +109,7 @@ CefRect GetAdjustedScreenFrameRect(CefRect screen_rect,
// Convert to DIP using a method that can handle multiple displays with
// different DPI.
const auto dip_rect = display::win::ScreenWin::ScreenToDIPRect(
const auto dip_rect = display::win::GetScreenWin()->ScreenToDIPRect(
nullptr, gfx::Rect(screen_rect.x, screen_rect.y, screen_rect.width,
screen_rect.height));
const auto visible_dip_rect = MakeVisibleOnScreenRect(
@@ -206,7 +206,7 @@ bool CefBrowserPlatformDelegateNativeWin::CreateHostWindow() {
// Convert to DIP using a method that can handle multiple displays with
// different DPI. Client coordinates always have origin (0,0).
const gfx::Rect dip_rect = display::win::ScreenWin::ScreenToDIPRect(
const gfx::Rect dip_rect = display::win::GetScreenWin()->ScreenToDIPRect(
window_info_.window, gfx::Rect(0, 0, cr.right, cr.bottom));
// Stay on top if top-most window hosting the web view is topmost.
@@ -427,6 +427,27 @@ CefEventHandle CefBrowserPlatformDelegateNativeWin::GetEventHandle(
const_cast<CHROME_MSG*>(&event.os_event->native_event()));
}
std::optional<gfx::Rect>
CefBrowserPlatformDelegateNativeWin::GetRootWindowBounds() {
if (window_widget_) {
if (HWND hwnd = GetHostWindowHandle()) {
if (HWND root_hwnd = ::GetAncestor(hwnd, GA_ROOT)) {
RECT root_rect = {};
if (::GetWindowRect(root_hwnd, &root_rect)) {
auto* top_level =
window_widget_->GetNativeWindow()->GetToplevelWindow();
gfx::Rect bounds(root_rect);
bounds = display::Screen::GetScreen()->ScreenToDIPRectInWindow(
top_level, bounds);
return bounds;
}
}
}
}
return std::nullopt;
}
ui::KeyEvent CefBrowserPlatformDelegateNativeWin::TranslateUiKeyEvent(
const CefKeyEvent& key_event) const {
int flags = TranslateUiEventModifiers(key_event.modifiers);
@@ -596,8 +617,8 @@ LRESULT CALLBACK CefBrowserPlatformDelegateNativeWin::WndProc(HWND hwnd,
case WM_MOVING:
case WM_MOVE:
if (browser) {
browser->NotifyMoveOrResizeStarted();
if (platform_delegate) {
platform_delegate->NotifyMoveOrResizeStarted();
}
return 0;

View File

@@ -32,6 +32,7 @@ class CefBrowserPlatformDelegateNativeWin
bool HandleKeyboardEvent(const input::NativeWebKeyboardEvent& event) override;
CefEventHandle GetEventHandle(
const input::NativeWebKeyboardEvent& event) const override;
std::optional<gfx::Rect> GetRootWindowBounds() override;
// CefBrowserPlatformDelegateNativeAura methods:
ui::KeyEvent TranslateUiKeyEvent(const CefKeyEvent& key_event) const override;

View File

@@ -68,8 +68,10 @@ void CefWindowDelegateView::Init(gfx::AcceleratedWidget parent_widget,
DCHECK(widget->widget_delegate()->CanActivate());
// WidgetDelegate::DeleteDelegate() will execute the registered callback.
RegisterDeleteDelegateCallback(base::BindOnce(
&CefWindowDelegateView::DeleteDelegate, base::Unretained(this)));
RegisterDeleteDelegateCallback(
RegisterDeleteCallbackPassKey(),
base::BindOnce(&CefWindowDelegateView::DeleteDelegate,
base::Unretained(this)));
}
void CefWindowDelegateView::InitContent() {

View File

@@ -92,19 +92,19 @@ void NavigationOnUIThread(
} // namespace
void CreateThrottlesForNavigation(content::NavigationHandle* navigation_handle,
NavigationThrottleList& throttles) {
void CreateThrottlesForNavigation(
content::NavigationThrottleRegistry& registry) {
CEF_REQUIRE_UIT();
// Must use SynchronyMode::kSync to ensure that OnBeforeBrowse is always
// called before OnBeforeResourceLoad.
std::unique_ptr<content::NavigationThrottle> throttle =
std::make_unique<navigation_interception::InterceptNavigationThrottle>(
navigation_handle, base::BindRepeating(&NavigationOnUIThread),
registry, base::BindRepeating(&NavigationOnUIThread),
navigation_interception::SynchronyMode::kSync, std::nullopt);
// Always execute our throttle first.
throttles.emplace(throttles.begin(), std::move(throttle));
registry.AddThrottle(std::move(throttle), /*first=*/true);
}
} // namespace throttle

View File

@@ -6,21 +6,14 @@
#define CEF_LIBCEF_BROWSER_NET_THROTTLE_HANDLER_H_
#pragma once
#include <memory>
#include <vector>
namespace content {
class NavigationHandle;
class NavigationThrottle;
class NavigationThrottleRegistry;
} // namespace content
namespace throttle {
using NavigationThrottleList =
std::vector<std::unique_ptr<content::NavigationThrottle>>;
void CreateThrottlesForNavigation(content::NavigationHandle* navigation_handle,
NavigationThrottleList& throttles);
void CreateThrottlesForNavigation(
content::NavigationThrottleRegistry& registry);
} // namespace throttle

View File

@@ -252,7 +252,7 @@ void LoadCookies(const CefBrowserContext::Getter& browser_context_getter,
if (request.trusted_params.has_value() &&
!request.trusted_params->isolation_info.IsEmpty()) {
const auto& isolation_info = request.trusted_params->isolation_info;
partition_key_collection = net::CookiePartitionKeyCollection::FromOptional(
partition_key_collection = net::CookiePartitionKeyCollection(
net::CookiePartitionKey::FromNetworkIsolationKey(
isolation_info.network_isolation_key(), request.site_for_cookies,
net::SchemefulSite(request.url),

View File

@@ -443,7 +443,9 @@ void CefRenderWidgetHostViewOSR::Hide() {
}
if (render_widget_host_) {
render_widget_host_->WasHidden();
if (render_widget_host_->delegate()) {
render_widget_host_->WasHidden();
}
auto provider = content::RenderWidgetHostImpl::From(render_widget_host_)
->render_frame_metadata_provider();

View File

@@ -187,7 +187,7 @@ void CefVideoConsumerOSR::OnFrameCaptured(
view_->OnAcceleratedPaint(damage_rect, info->coded_size, paint_info);
#elif BUILDFLAG(IS_LINUX)
auto& gmb_handle = data->get_gpu_memory_buffer_handle();
auto& native_pixmap = gmb_handle.native_pixmap_handle;
auto& native_pixmap = gmb_handle.native_pixmap_handle();
CHECK(native_pixmap.planes.size() <= kAcceleratedPaintMaxPlanes);
cef_accelerated_paint_info_t paint_info;

View File

@@ -9,6 +9,7 @@
#include "base/notreached.h"
#include "cef/libcef/browser/browser_host_base.h"
#include "chrome/browser/ui/permission_bubble/permission_prompt.h"
#include "components/permissions/permission_request.h"
namespace permission_prompt {

View File

@@ -0,0 +1,129 @@
#include "build/build_config.h"
// Based on chrome/app/chrome_exe_main_win.cc.
// In 32-bit builds, the main thread starts with the default (small) stack size.
// The ARCH_CPU_32_BITS blocks here and below are in support of moving the main
// thread to a fiber with a larger stack size.
#if BUILDFLAG(IS_WIN) && defined(ARCH_CPU_32_BITS)
#include "base/debug/alias.h"
#include "include/internal/cef_app_win.h"
namespace {
// The information needed to transfer control to the large-stack fiber and later
// pass the main routine's exit code back to the small-stack fiber prior to
// termination.
struct FiberState {
FiberState(wWinMainPtr wWinMain,
HINSTANCE hInstance,
LPWSTR lpCmdLine,
int nCmdShow) {
this->wWinMain = wWinMain;
this->hInstance = hInstance;
this->lpCmdLine = lpCmdLine;
this->nCmdShow = nCmdShow;
}
FiberState(mainPtr main, int argc, char** argv) {
this->main = main;
this->argc = argc;
this->argv = argv;
}
wWinMainPtr wWinMain = nullptr;
HINSTANCE hInstance;
LPWSTR lpCmdLine;
int nCmdShow;
mainPtr main = nullptr;
int argc;
char** argv;
LPVOID original_fiber;
int fiber_result;
};
// A PFIBER_START_ROUTINE function run on a large-stack fiber that calls the
// main routine, stores its return value, and returns control to the small-stack
// fiber. |params| must be a pointer to a FiberState struct.
void WINAPI FiberBinder(void* params) {
auto* fiber_state = static_cast<FiberState*>(params);
// Call the main routine from the fiber. Reusing the entry point minimizes
// confusion when examining call stacks in crash reports - seeing wWinMain on
// the stack is a handy hint that this is the main thread of the process.
if (fiber_state->main) {
fiber_state->fiber_result =
fiber_state->main(fiber_state->argc, fiber_state->argv);
} else {
fiber_state->fiber_result =
fiber_state->wWinMain(fiber_state->hInstance, nullptr,
fiber_state->lpCmdLine, fiber_state->nCmdShow);
}
// Switch back to the main thread to exit.
::SwitchToFiber(fiber_state->original_fiber);
}
int RunMainWithPreferredStackSize(FiberState& fiber_state) {
enum class FiberStatus { kConvertFailed, kCreateFiberFailed, kSuccess };
FiberStatus fiber_status = FiberStatus::kSuccess;
// GetLastError result if fiber conversion failed.
DWORD fiber_error = ERROR_SUCCESS;
if (!::IsThreadAFiber()) {
// Make the main thread's stack size 4 MiB so that it has roughly the same
// effective size as the 64-bit build's 8 MiB stack.
constexpr size_t kStackSize = 4 * 1024 * 1024; // 4 MiB
// Leak the fiber on exit.
LPVOID original_fiber =
::ConvertThreadToFiberEx(nullptr, FIBER_FLAG_FLOAT_SWITCH);
if (original_fiber) {
fiber_state.original_fiber = original_fiber;
// Create a fiber with a bigger stack and switch to it. Leak the fiber on
// exit.
LPVOID big_stack_fiber = ::CreateFiberEx(
0, kStackSize, FIBER_FLAG_FLOAT_SWITCH, FiberBinder, &fiber_state);
if (big_stack_fiber) {
::SwitchToFiber(big_stack_fiber);
// The fibers must be cleaned up to avoid obscure TLS-related shutdown
// crashes.
::DeleteFiber(big_stack_fiber);
::ConvertFiberToThread();
// Control returns here after CEF has finished running on FiberMain.
return fiber_state.fiber_result;
}
fiber_status = FiberStatus::kCreateFiberFailed;
} else {
fiber_status = FiberStatus::kConvertFailed;
}
// If we reach here then creating and switching to a fiber has failed. This
// probably means we are low on memory and will soon crash. Try to report
// this error once crash reporting is initialized.
fiber_error = ::GetLastError();
base::debug::Alias(&fiber_error);
}
// If we are already a fiber then continue normal execution.
// Intentionally crash if converting to a fiber failed.
CHECK_EQ(fiber_status, FiberStatus::kSuccess);
return -1;
}
} // namespace
int CefRunWinMainWithPreferredStackSize(wWinMainPtr wWinMain,
HINSTANCE hInstance,
LPWSTR lpCmdLine,
int nCmdShow) {
CHECK(wWinMain && hInstance);
FiberState fiber_state(wWinMain, hInstance, lpCmdLine, nCmdShow);
return RunMainWithPreferredStackSize(fiber_state);
}
int CefRunMainWithPreferredStackSize(mainPtr main, int argc, char* argv[]) {
CHECK(main);
FiberState fiber_state(main, argc, argv);
return RunMainWithPreferredStackSize(fiber_state);
}
#endif // BUILDFLAG(IS_WIN) && defined(ARCH_CPU_32_BITS)

View File

@@ -93,7 +93,6 @@ void SetCefPrefs(const CefBrowserSettings& cef,
SET_STATE(cef.text_area_resize, web.text_areas_are_resizable);
SET_STATE(cef.tab_to_links, web.tabs_to_links);
SET_STATE(cef.local_storage, web.local_storage_enabled);
SET_STATE(cef.databases, web.databases_enabled);
// Never explicitly enable GPU-related functions in this method because the
// GPU blacklist is not being checked here.

View File

@@ -530,14 +530,18 @@ CefRefPtr<CefValue> CefRequestContextImpl::GetWebsiteSetting(
return nullptr;
}
const auto setting_type = setting_helper::FromCefType(content_type);
if (!setting_type) {
return nullptr;
}
// Either or both URLs may be invalid.
GURL requesting_gurl(requesting_url.ToString());
GURL top_level_gurl(top_level_url.ToString());
content_settings::SettingInfo info;
base::Value value = settings_map->GetWebsiteSetting(
requesting_gurl, top_level_gurl,
static_cast<ContentSettingsType>(content_type), &info);
requesting_gurl, top_level_gurl, *setting_type, &info);
if (value.is_none()) {
return nullptr;
}
@@ -576,19 +580,22 @@ cef_content_setting_values_t CefRequestContextImpl::GetContentSetting(
return CEF_CONTENT_SETTING_VALUE_DEFAULT;
}
const auto setting_type = setting_helper::FromCefType(content_type);
if (!setting_type) {
return CEF_CONTENT_SETTING_VALUE_DEFAULT;
}
ContentSetting value = ContentSetting::CONTENT_SETTING_DEFAULT;
if (requesting_url.empty() && top_level_url.empty()) {
value = settings_map->GetDefaultContentSetting(
static_cast<ContentSettingsType>(content_type),
/*provider_id=*/nullptr);
value = settings_map->GetDefaultContentSetting(*setting_type,
/*provider_id=*/nullptr);
} else {
GURL requesting_gurl(requesting_url.ToString());
GURL top_level_gurl(top_level_url.ToString());
if (requesting_gurl.is_valid() || top_level_gurl.is_valid()) {
value = settings_map->GetContentSetting(
requesting_gurl, top_level_gurl,
static_cast<ContentSettingsType>(content_type));
value = settings_map->GetContentSetting(requesting_gurl, top_level_gurl,
*setting_type);
}
}
@@ -901,6 +908,11 @@ void CefRequestContextImpl::SetWebsiteSettingInternal(
return;
}
const auto setting_type = setting_helper::FromCefType(content_type);
if (!setting_type) {
return;
}
// Starts as a NONE value.
base::Value new_value;
if (value && value->IsValid()) {
@@ -910,14 +922,13 @@ void CefRequestContextImpl::SetWebsiteSettingInternal(
if (requesting_url.empty() && top_level_url.empty()) {
settings_map->SetWebsiteSettingCustomScope(
ContentSettingsPattern::Wildcard(), ContentSettingsPattern::Wildcard(),
static_cast<ContentSettingsType>(content_type), std::move(new_value));
*setting_type, std::move(new_value));
} else {
GURL requesting_gurl(requesting_url.ToString());
GURL top_level_gurl(top_level_url.ToString());
if (requesting_gurl.is_valid() || top_level_gurl.is_valid()) {
settings_map->SetWebsiteSettingDefaultScope(
requesting_gurl, top_level_gurl,
static_cast<ContentSettingsType>(content_type), std::move(new_value));
requesting_gurl, top_level_gurl, *setting_type, std::move(new_value));
}
}
}
@@ -939,17 +950,20 @@ void CefRequestContextImpl::SetContentSettingInternal(
return;
}
const auto setting_type = setting_helper::FromCefType(content_type);
if (!setting_type) {
return;
}
if (requesting_url.empty() && top_level_url.empty()) {
settings_map->SetDefaultContentSetting(
static_cast<ContentSettingsType>(content_type),
static_cast<ContentSetting>(value));
settings_map->SetDefaultContentSetting(*setting_type,
static_cast<ContentSetting>(value));
} else {
GURL requesting_gurl(requesting_url.ToString());
GURL top_level_gurl(top_level_url.ToString());
if (requesting_gurl.is_valid() || top_level_gurl.is_valid()) {
settings_map->SetContentSettingDefaultScope(
requesting_gurl, top_level_gurl,
static_cast<ContentSettingsType>(content_type),
requesting_gurl, top_level_gurl, *setting_type,
static_cast<ContentSetting>(value));
}
}

View File

@@ -107,12 +107,283 @@ void Registrar::OnContentSettingChanged(
const CefString requesting_url(primary_pattern.ToRepresentativeUrl().spec());
const CefString top_level_url(secondary_pattern.ToRepresentativeUrl().spec());
const auto content_type =
static_cast<cef_content_setting_types_t>(content_type_set.GetType());
const auto content_type = ToCefType(content_type_set.GetType());
for (Registration& registration : observers_) {
registration.RunCallback(requesting_url, top_level_url, content_type);
}
}
#define TO_CEF_TYPE(name) \
case ContentSettingsType::name: \
return CEF_CONTENT_SETTING_TYPE_##name
cef_content_setting_types_t ToCefType(ContentSettingsType type) {
switch (type) {
TO_CEF_TYPE(COOKIES);
TO_CEF_TYPE(IMAGES);
TO_CEF_TYPE(JAVASCRIPT);
TO_CEF_TYPE(POPUPS);
TO_CEF_TYPE(GEOLOCATION);
TO_CEF_TYPE(NOTIFICATIONS);
TO_CEF_TYPE(AUTO_SELECT_CERTIFICATE);
TO_CEF_TYPE(MIXEDSCRIPT);
TO_CEF_TYPE(MEDIASTREAM_MIC);
TO_CEF_TYPE(MEDIASTREAM_CAMERA);
TO_CEF_TYPE(PROTOCOL_HANDLERS);
TO_CEF_TYPE(DEPRECATED_PPAPI_BROKER);
TO_CEF_TYPE(AUTOMATIC_DOWNLOADS);
TO_CEF_TYPE(MIDI_SYSEX);
TO_CEF_TYPE(SSL_CERT_DECISIONS);
TO_CEF_TYPE(PROTECTED_MEDIA_IDENTIFIER);
TO_CEF_TYPE(APP_BANNER);
TO_CEF_TYPE(SITE_ENGAGEMENT);
TO_CEF_TYPE(DURABLE_STORAGE);
TO_CEF_TYPE(USB_CHOOSER_DATA);
TO_CEF_TYPE(BLUETOOTH_GUARD);
TO_CEF_TYPE(BACKGROUND_SYNC);
TO_CEF_TYPE(AUTOPLAY);
TO_CEF_TYPE(IMPORTANT_SITE_INFO);
TO_CEF_TYPE(PERMISSION_AUTOBLOCKER_DATA);
TO_CEF_TYPE(ADS);
TO_CEF_TYPE(ADS_DATA);
TO_CEF_TYPE(MIDI);
TO_CEF_TYPE(PASSWORD_PROTECTION);
TO_CEF_TYPE(MEDIA_ENGAGEMENT);
TO_CEF_TYPE(SOUND);
TO_CEF_TYPE(CLIENT_HINTS);
TO_CEF_TYPE(SENSORS);
TO_CEF_TYPE(DEPRECATED_ACCESSIBILITY_EVENTS);
TO_CEF_TYPE(PAYMENT_HANDLER);
TO_CEF_TYPE(USB_GUARD);
TO_CEF_TYPE(BACKGROUND_FETCH);
TO_CEF_TYPE(INTENT_PICKER_DISPLAY);
TO_CEF_TYPE(IDLE_DETECTION);
TO_CEF_TYPE(SERIAL_GUARD);
TO_CEF_TYPE(SERIAL_CHOOSER_DATA);
TO_CEF_TYPE(PERIODIC_BACKGROUND_SYNC);
TO_CEF_TYPE(BLUETOOTH_SCANNING);
TO_CEF_TYPE(HID_GUARD);
TO_CEF_TYPE(HID_CHOOSER_DATA);
TO_CEF_TYPE(WAKE_LOCK_SCREEN);
TO_CEF_TYPE(WAKE_LOCK_SYSTEM);
TO_CEF_TYPE(LEGACY_COOKIE_ACCESS);
TO_CEF_TYPE(FILE_SYSTEM_WRITE_GUARD);
TO_CEF_TYPE(NFC);
TO_CEF_TYPE(BLUETOOTH_CHOOSER_DATA);
TO_CEF_TYPE(CLIPBOARD_READ_WRITE);
TO_CEF_TYPE(CLIPBOARD_SANITIZED_WRITE);
TO_CEF_TYPE(SAFE_BROWSING_URL_CHECK_DATA);
TO_CEF_TYPE(VR);
TO_CEF_TYPE(AR);
TO_CEF_TYPE(FILE_SYSTEM_READ_GUARD);
TO_CEF_TYPE(STORAGE_ACCESS);
TO_CEF_TYPE(CAMERA_PAN_TILT_ZOOM);
TO_CEF_TYPE(WINDOW_MANAGEMENT);
TO_CEF_TYPE(LOCAL_FONTS);
TO_CEF_TYPE(PERMISSION_AUTOREVOCATION_DATA);
TO_CEF_TYPE(FILE_SYSTEM_LAST_PICKED_DIRECTORY);
TO_CEF_TYPE(DISPLAY_CAPTURE);
TO_CEF_TYPE(FILE_SYSTEM_ACCESS_CHOOSER_DATA);
TO_CEF_TYPE(FEDERATED_IDENTITY_SHARING);
TO_CEF_TYPE(JAVASCRIPT_JIT);
TO_CEF_TYPE(HTTP_ALLOWED);
TO_CEF_TYPE(FORMFILL_METADATA);
TO_CEF_TYPE(DEPRECATED_FEDERATED_IDENTITY_ACTIVE_SESSION);
TO_CEF_TYPE(AUTO_DARK_WEB_CONTENT);
TO_CEF_TYPE(REQUEST_DESKTOP_SITE);
TO_CEF_TYPE(FEDERATED_IDENTITY_API);
TO_CEF_TYPE(NOTIFICATION_INTERACTIONS);
TO_CEF_TYPE(REDUCED_ACCEPT_LANGUAGE);
TO_CEF_TYPE(NOTIFICATION_PERMISSION_REVIEW);
TO_CEF_TYPE(PRIVATE_NETWORK_GUARD);
TO_CEF_TYPE(PRIVATE_NETWORK_CHOOSER_DATA);
TO_CEF_TYPE(FEDERATED_IDENTITY_IDENTITY_PROVIDER_SIGNIN_STATUS);
TO_CEF_TYPE(REVOKED_UNUSED_SITE_PERMISSIONS);
TO_CEF_TYPE(TOP_LEVEL_STORAGE_ACCESS);
TO_CEF_TYPE(FEDERATED_IDENTITY_AUTO_REAUTHN_PERMISSION);
TO_CEF_TYPE(FEDERATED_IDENTITY_IDENTITY_PROVIDER_REGISTRATION);
TO_CEF_TYPE(ANTI_ABUSE);
TO_CEF_TYPE(THIRD_PARTY_STORAGE_PARTITIONING);
TO_CEF_TYPE(HTTPS_ENFORCED);
TO_CEF_TYPE(ALL_SCREEN_CAPTURE);
TO_CEF_TYPE(COOKIE_CONTROLS_METADATA);
TO_CEF_TYPE(TPCD_HEURISTICS_GRANTS);
TO_CEF_TYPE(TPCD_METADATA_GRANTS);
TO_CEF_TYPE(TPCD_TRIAL);
TO_CEF_TYPE(TOP_LEVEL_TPCD_TRIAL);
TO_CEF_TYPE(TOP_LEVEL_TPCD_ORIGIN_TRIAL);
TO_CEF_TYPE(AUTO_PICTURE_IN_PICTURE);
TO_CEF_TYPE(FILE_SYSTEM_ACCESS_EXTENDED_PERMISSION);
TO_CEF_TYPE(FILE_SYSTEM_ACCESS_RESTORE_PERMISSION);
TO_CEF_TYPE(CAPTURED_SURFACE_CONTROL);
TO_CEF_TYPE(SMART_CARD_GUARD);
TO_CEF_TYPE(SMART_CARD_DATA);
TO_CEF_TYPE(WEB_PRINTING);
TO_CEF_TYPE(AUTOMATIC_FULLSCREEN);
TO_CEF_TYPE(SUB_APP_INSTALLATION_PROMPTS);
TO_CEF_TYPE(SPEAKER_SELECTION);
TO_CEF_TYPE(DIRECT_SOCKETS);
TO_CEF_TYPE(KEYBOARD_LOCK);
TO_CEF_TYPE(POINTER_LOCK);
TO_CEF_TYPE(REVOKED_ABUSIVE_NOTIFICATION_PERMISSIONS);
TO_CEF_TYPE(TRACKING_PROTECTION);
TO_CEF_TYPE(DISPLAY_MEDIA_SYSTEM_AUDIO);
TO_CEF_TYPE(JAVASCRIPT_OPTIMIZER);
TO_CEF_TYPE(STORAGE_ACCESS_HEADER_ORIGIN_TRIAL);
TO_CEF_TYPE(HAND_TRACKING);
TO_CEF_TYPE(WEB_APP_INSTALLATION);
TO_CEF_TYPE(DIRECT_SOCKETS_PRIVATE_NETWORK_ACCESS);
TO_CEF_TYPE(LEGACY_COOKIE_SCOPE);
TO_CEF_TYPE(ARE_SUSPICIOUS_NOTIFICATIONS_ALLOWLISTED_BY_USER);
TO_CEF_TYPE(CONTROLLED_FRAME);
TO_CEF_TYPE(REVOKED_DISRUPTIVE_NOTIFICATION_PERMISSIONS);
TO_CEF_TYPE(LOCAL_NETWORK_ACCESS);
TO_CEF_TYPE(ON_DEVICE_SPEECH_RECOGNITION_LANGUAGES_DOWNLOADED);
TO_CEF_TYPE(INITIALIZED_TRANSLATIONS);
TO_CEF_TYPE(SUSPICIOUS_NOTIFICATION_IDS);
case ContentSettingsType::DEFAULT:
break;
}
NOTREACHED();
}
#define FROM_CEF_TYPE(name) \
case CEF_CONTENT_SETTING_TYPE_##name: \
return ContentSettingsType::name
std::optional<ContentSettingsType> FromCefType(
cef_content_setting_types_t type) {
switch (type) {
FROM_CEF_TYPE(COOKIES);
FROM_CEF_TYPE(IMAGES);
FROM_CEF_TYPE(JAVASCRIPT);
FROM_CEF_TYPE(POPUPS);
FROM_CEF_TYPE(GEOLOCATION);
FROM_CEF_TYPE(NOTIFICATIONS);
FROM_CEF_TYPE(AUTO_SELECT_CERTIFICATE);
FROM_CEF_TYPE(MIXEDSCRIPT);
FROM_CEF_TYPE(MEDIASTREAM_MIC);
FROM_CEF_TYPE(MEDIASTREAM_CAMERA);
FROM_CEF_TYPE(PROTOCOL_HANDLERS);
FROM_CEF_TYPE(DEPRECATED_PPAPI_BROKER);
FROM_CEF_TYPE(AUTOMATIC_DOWNLOADS);
FROM_CEF_TYPE(MIDI_SYSEX);
FROM_CEF_TYPE(SSL_CERT_DECISIONS);
FROM_CEF_TYPE(PROTECTED_MEDIA_IDENTIFIER);
FROM_CEF_TYPE(APP_BANNER);
FROM_CEF_TYPE(SITE_ENGAGEMENT);
FROM_CEF_TYPE(DURABLE_STORAGE);
FROM_CEF_TYPE(USB_CHOOSER_DATA);
FROM_CEF_TYPE(BLUETOOTH_GUARD);
FROM_CEF_TYPE(BACKGROUND_SYNC);
FROM_CEF_TYPE(AUTOPLAY);
FROM_CEF_TYPE(IMPORTANT_SITE_INFO);
FROM_CEF_TYPE(PERMISSION_AUTOBLOCKER_DATA);
FROM_CEF_TYPE(ADS);
FROM_CEF_TYPE(ADS_DATA);
FROM_CEF_TYPE(MIDI);
FROM_CEF_TYPE(PASSWORD_PROTECTION);
FROM_CEF_TYPE(MEDIA_ENGAGEMENT);
FROM_CEF_TYPE(SOUND);
FROM_CEF_TYPE(CLIENT_HINTS);
FROM_CEF_TYPE(SENSORS);
FROM_CEF_TYPE(DEPRECATED_ACCESSIBILITY_EVENTS);
FROM_CEF_TYPE(PAYMENT_HANDLER);
FROM_CEF_TYPE(USB_GUARD);
FROM_CEF_TYPE(BACKGROUND_FETCH);
FROM_CEF_TYPE(INTENT_PICKER_DISPLAY);
FROM_CEF_TYPE(IDLE_DETECTION);
FROM_CEF_TYPE(SERIAL_GUARD);
FROM_CEF_TYPE(SERIAL_CHOOSER_DATA);
FROM_CEF_TYPE(PERIODIC_BACKGROUND_SYNC);
FROM_CEF_TYPE(BLUETOOTH_SCANNING);
FROM_CEF_TYPE(HID_GUARD);
FROM_CEF_TYPE(HID_CHOOSER_DATA);
FROM_CEF_TYPE(WAKE_LOCK_SCREEN);
FROM_CEF_TYPE(WAKE_LOCK_SYSTEM);
FROM_CEF_TYPE(LEGACY_COOKIE_ACCESS);
FROM_CEF_TYPE(FILE_SYSTEM_WRITE_GUARD);
FROM_CEF_TYPE(NFC);
FROM_CEF_TYPE(BLUETOOTH_CHOOSER_DATA);
FROM_CEF_TYPE(CLIPBOARD_READ_WRITE);
FROM_CEF_TYPE(CLIPBOARD_SANITIZED_WRITE);
FROM_CEF_TYPE(SAFE_BROWSING_URL_CHECK_DATA);
FROM_CEF_TYPE(VR);
FROM_CEF_TYPE(AR);
FROM_CEF_TYPE(FILE_SYSTEM_READ_GUARD);
FROM_CEF_TYPE(STORAGE_ACCESS);
FROM_CEF_TYPE(CAMERA_PAN_TILT_ZOOM);
FROM_CEF_TYPE(WINDOW_MANAGEMENT);
FROM_CEF_TYPE(LOCAL_FONTS);
FROM_CEF_TYPE(PERMISSION_AUTOREVOCATION_DATA);
FROM_CEF_TYPE(FILE_SYSTEM_LAST_PICKED_DIRECTORY);
FROM_CEF_TYPE(DISPLAY_CAPTURE);
FROM_CEF_TYPE(FILE_SYSTEM_ACCESS_CHOOSER_DATA);
FROM_CEF_TYPE(FEDERATED_IDENTITY_SHARING);
FROM_CEF_TYPE(JAVASCRIPT_JIT);
FROM_CEF_TYPE(HTTP_ALLOWED);
FROM_CEF_TYPE(FORMFILL_METADATA);
FROM_CEF_TYPE(DEPRECATED_FEDERATED_IDENTITY_ACTIVE_SESSION);
FROM_CEF_TYPE(AUTO_DARK_WEB_CONTENT);
FROM_CEF_TYPE(REQUEST_DESKTOP_SITE);
FROM_CEF_TYPE(FEDERATED_IDENTITY_API);
FROM_CEF_TYPE(NOTIFICATION_INTERACTIONS);
FROM_CEF_TYPE(REDUCED_ACCEPT_LANGUAGE);
FROM_CEF_TYPE(NOTIFICATION_PERMISSION_REVIEW);
FROM_CEF_TYPE(PRIVATE_NETWORK_GUARD);
FROM_CEF_TYPE(PRIVATE_NETWORK_CHOOSER_DATA);
FROM_CEF_TYPE(FEDERATED_IDENTITY_IDENTITY_PROVIDER_SIGNIN_STATUS);
FROM_CEF_TYPE(REVOKED_UNUSED_SITE_PERMISSIONS);
FROM_CEF_TYPE(TOP_LEVEL_STORAGE_ACCESS);
FROM_CEF_TYPE(FEDERATED_IDENTITY_AUTO_REAUTHN_PERMISSION);
FROM_CEF_TYPE(FEDERATED_IDENTITY_IDENTITY_PROVIDER_REGISTRATION);
FROM_CEF_TYPE(ANTI_ABUSE);
FROM_CEF_TYPE(THIRD_PARTY_STORAGE_PARTITIONING);
FROM_CEF_TYPE(HTTPS_ENFORCED);
FROM_CEF_TYPE(ALL_SCREEN_CAPTURE);
FROM_CEF_TYPE(COOKIE_CONTROLS_METADATA);
FROM_CEF_TYPE(TPCD_HEURISTICS_GRANTS);
FROM_CEF_TYPE(TPCD_METADATA_GRANTS);
FROM_CEF_TYPE(TPCD_TRIAL);
FROM_CEF_TYPE(TOP_LEVEL_TPCD_TRIAL);
FROM_CEF_TYPE(TOP_LEVEL_TPCD_ORIGIN_TRIAL);
FROM_CEF_TYPE(AUTO_PICTURE_IN_PICTURE);
FROM_CEF_TYPE(FILE_SYSTEM_ACCESS_EXTENDED_PERMISSION);
FROM_CEF_TYPE(FILE_SYSTEM_ACCESS_RESTORE_PERMISSION);
FROM_CEF_TYPE(CAPTURED_SURFACE_CONTROL);
FROM_CEF_TYPE(SMART_CARD_GUARD);
FROM_CEF_TYPE(SMART_CARD_DATA);
FROM_CEF_TYPE(WEB_PRINTING);
FROM_CEF_TYPE(AUTOMATIC_FULLSCREEN);
FROM_CEF_TYPE(SUB_APP_INSTALLATION_PROMPTS);
FROM_CEF_TYPE(SPEAKER_SELECTION);
FROM_CEF_TYPE(DIRECT_SOCKETS);
FROM_CEF_TYPE(KEYBOARD_LOCK);
FROM_CEF_TYPE(POINTER_LOCK);
FROM_CEF_TYPE(REVOKED_ABUSIVE_NOTIFICATION_PERMISSIONS);
FROM_CEF_TYPE(TRACKING_PROTECTION);
FROM_CEF_TYPE(DISPLAY_MEDIA_SYSTEM_AUDIO);
FROM_CEF_TYPE(JAVASCRIPT_OPTIMIZER);
FROM_CEF_TYPE(STORAGE_ACCESS_HEADER_ORIGIN_TRIAL);
FROM_CEF_TYPE(HAND_TRACKING);
FROM_CEF_TYPE(WEB_APP_INSTALLATION);
FROM_CEF_TYPE(DIRECT_SOCKETS_PRIVATE_NETWORK_ACCESS);
FROM_CEF_TYPE(LEGACY_COOKIE_SCOPE);
FROM_CEF_TYPE(ARE_SUSPICIOUS_NOTIFICATIONS_ALLOWLISTED_BY_USER);
FROM_CEF_TYPE(CONTROLLED_FRAME);
FROM_CEF_TYPE(REVOKED_DISRUPTIVE_NOTIFICATION_PERMISSIONS);
FROM_CEF_TYPE(LOCAL_NETWORK_ACCESS);
FROM_CEF_TYPE(ON_DEVICE_SPEECH_RECOGNITION_LANGUAGES_DOWNLOADED);
FROM_CEF_TYPE(INITIALIZED_TRANSLATIONS);
FROM_CEF_TYPE(SUSPICIOUS_NOTIFICATION_IDS);
case CEF_CONTENT_SETTING_TYPE_INSECURE_PRIVATE_NETWORK_DEPRECATED:
case CEF_CONTENT_SETTING_TYPE_NUM_VALUES:
break;
}
return std::nullopt;
}
} // namespace setting_helper

View File

@@ -5,10 +5,14 @@
#ifndef CEF_LIBCEF_BROWSER_SETTING_HELPER_H_
#define CEF_LIBCEF_BROWSER_SETTING_HELPER_H_
#include <optional>
#include "base/memory/raw_ptr.h"
#include "base/observer_list.h"
#include "cef/include/cef_registration.h"
#include "cef/include/internal/cef_types_content_settings.h"
#include "components/content_settings/core/browser/content_settings_observer.h"
#include "components/content_settings/core/common/content_settings_types.h"
class CefSettingObserver;
class CefRegistration;
@@ -76,6 +80,11 @@ class Registrar final : public content_settings::Observer {
base::ObserverList<Registration> observers_;
};
// Convert between cef_content_setting_types_t and ContentSettingsType.
cef_content_setting_types_t ToCefType(ContentSettingsType type);
std::optional<ContentSettingsType> FromCefType(
cef_content_setting_types_t type);
} // namespace setting_helper
#endif // CEF_LIBCEF_BROWSER_SETTING_HELPER_H_

View File

@@ -3,7 +3,6 @@
// can be found in the LICENSE file.
#include "base/feature_list.h"
#include "base/features.h"
#include "base/files/file_path.h"
#include "base/path_service.h"
#include "cef/include/test/cef_test_helpers.h"
@@ -20,7 +19,6 @@ bool CefIsFeatureEnabledForTests(const CefString& feature_name) {
// Only includes values that are queried by unit tests.
const base::Feature* features[] = {
&net::features::kIgnoreHSTSForLocalhost,
&base::features::kUseRustJsonParser,
&network::features::kReduceAcceptLanguage,
};

View File

@@ -216,8 +216,9 @@ void CefOverlayViewHost::Init(views::View* host_view,
// Cause WidgetDelegate::DeleteDelegate() to delete |this| after executing the
// registered DeleteDelegate callback.
SetOwnedByWidget(true);
SetOwnedByWidget(OwnedByWidgetPassKey());
RegisterDeleteDelegateCallback(
RegisterDeleteCallbackPassKey(),
base::BindOnce(&CefOverlayViewHost::Cleanup, base::Unretained(this)));
if (window_view_->IsChromeStyle()) {

View File

@@ -218,7 +218,7 @@ display::Display GetDisplayNearestPoint(const gfx::Point& point,
#if BUILDFLAG(IS_WIN)
if (input_pixel_coords) {
find_point = gfx::ToFlooredPoint(
display::win::ScreenWin::ScreenToDIPPoint(gfx::PointF(point)));
display::win::GetScreenWin()->ScreenToDIPPoint(gfx::PointF(point)));
}
#endif
return display::Screen::GetScreen()->GetDisplayNearestPoint(find_point);
@@ -230,7 +230,7 @@ display::Display GetDisplayMatchingBounds(const gfx::Rect& bounds,
#if BUILDFLAG(IS_WIN)
if (input_pixel_coords) {
find_bounds =
display::win::ScreenWin::ScreenToDIPRect(nullptr, find_bounds);
display::win::GetScreenWin()->ScreenToDIPRect(nullptr, find_bounds);
}
#endif
return display::Screen::GetScreen()->GetDisplayMatching(find_bounds);
@@ -249,19 +249,19 @@ void ConvertPointToPixels(gfx::Point* point, float device_scale_factor) {
#if BUILDFLAG(IS_WIN)
gfx::Point ConvertPointFromPixels(const gfx::Point& point) {
return gfx::ToFlooredPoint(
display::win::ScreenWin::ScreenToDIPPoint(gfx::PointF(point)));
display::win::GetScreenWin()->ScreenToDIPPoint(gfx::PointF(point)));
}
gfx::Point ConvertPointToPixels(const gfx::Point& point) {
return display::win::ScreenWin::DIPToScreenPoint(point);
return display::win::GetScreenWin()->DIPToScreenPoint(point);
}
gfx::Rect ConvertRectFromPixels(const gfx::Rect& rect) {
return display::win::ScreenWin::ScreenToDIPRect(nullptr, rect);
return display::win::GetScreenWin()->ScreenToDIPRect(nullptr, rect);
}
gfx::Rect ConvertRectToPixels(const gfx::Rect& rect) {
return display::win::ScreenWin::DIPToScreenRect(nullptr, rect);
return display::win::GetScreenWin()->DIPToScreenRect(nullptr, rect);
}
#endif // BUILDFLAG(IS_WIN)

View File

@@ -110,7 +110,7 @@ class NativeFrameViewEx : public views::NativeFrameView {
// Convert from DIP to pixel coordinates using a method that can handle
// multiple displays with different DPI.
const auto screen_rect =
display::win::ScreenWin::DIPToScreenRect(window, client_bounds);
display::win::GetScreenWin()->DIPToScreenRect(window, client_bounds);
RECT rect = {screen_rect.x(), screen_rect.y(),
screen_rect.x() + screen_rect.width(),
@@ -123,7 +123,7 @@ class NativeFrameViewEx : public views::NativeFrameView {
rect.right - rect.left, rect.bottom - rect.top);
// Convert back to DIP.
return display::win::ScreenWin::ScreenToDIPRect(window, pixel_rect);
return display::win::GetScreenWin()->ScreenToDIPRect(window, pixel_rect);
#else
// Use the default implementation.
return views::NativeFrameView::GetWindowBoundsForClientBounds(
@@ -420,8 +420,9 @@ void CefWindowView::CreateWidget(gfx::AcceleratedWidget parent_widget) {
// Cause WidgetDelegate::DeleteDelegate() to delete |this| after executing the
// registered DeleteDelegate callback.
SetOwnedByWidget(true);
SetOwnedByWidget(OwnedByWidgetPassKey());
RegisterDeleteDelegateCallback(
RegisterDeleteCallbackPassKey(),
base::BindOnce(&CefWindowView::DeleteDelegate, base::Unretained(this)));
if (cef_delegate()) {

View File

@@ -548,13 +548,12 @@ bool CefCrashReporterClient::ReadCrashConfigFile() {
// Allow override of some values via environment variables.
{
std::unique_ptr<base::Environment> env(base::Environment::Create());
std::string val_str;
if (env->GetVar("CEF_CRASH_REPORTER_SERVER_URL", &val_str)) {
ParseURL(val_str, &server_url_);
if (const auto& var_str = env->GetVar("CEF_CRASH_REPORTER_SERVER_URL")) {
ParseURL(*var_str, &server_url_);
}
if (env->GetVar("CEF_CRASH_REPORTER_RATE_LIMIT_ENABLED", &val_str)) {
rate_limit_ = ParseBool(val_str);
if (const auto& var_str =
env->GetVar("CEF_CRASH_REPORTER_RATE_LIMIT_ENABLED")) {
rate_limit_ = ParseBool(*var_str);
}
}
@@ -642,11 +641,9 @@ bool CefCrashReporterClient::GetCrashDumpLocation(base::FilePath* crash_dir) {
// By setting the BREAKPAD_DUMP_LOCATION environment variable, an alternate
// location to write breakpad crash dumps can be set.
std::unique_ptr<base::Environment> env(base::Environment::Create());
std::string alternate_crash_dump_location;
if (env->GetVar("BREAKPAD_DUMP_LOCATION", &alternate_crash_dump_location)) {
base::FilePath crash_dumps_dir_path =
base::FilePath::FromUTF8Unsafe(alternate_crash_dump_location);
base::PathService::Override(chrome::DIR_CRASH_DUMPS, crash_dumps_dir_path);
if (const auto& val = env->GetVar("BREAKPAD_DUMP_LOCATION")) {
base::PathService::Override(chrome::DIR_CRASH_DUMPS,
base::FilePath::FromUTF8Unsafe(*val));
}
return base::PathService::Get(chrome::DIR_CRASH_DUMPS, crash_dir);
}
@@ -726,8 +723,7 @@ bool CefCrashReporterClient::EnableBrowserCrashForwarding() {
// storage for each key size and later substituting the actual key name during
// crash dump processing.
#define IDKEY(name) \
{ name, IDKey::Tag::kArray }
#define IDKEY(name) {name, IDKey::Tag::kArray}
#define IDKEY_ENTRIES(n) \
IDKEY(n "-A"), IDKEY(n "-B"), IDKEY(n "-C"), IDKEY(n "-D"), IDKEY(n "-E"), \

View File

@@ -36,9 +36,7 @@ std::string GenerateHeaders(const HeaderMap& map) {
void ParseHeaders(const std::string& header_str, HeaderMap& map) {
// Parse the request header values
for (net::HttpUtil::HeadersIterator i(header_str.begin(), header_str.end(),
"\n\r");
i.GetNext();) {
for (net::HttpUtil::HeadersIterator i(header_str, "\n\r"); i.GetNext();) {
map.insert(std::make_pair(i.name(), i.values()));
}
}

View File

@@ -568,8 +568,7 @@ void CefRequestImpl::Get(const cef::mojom::RequestParamsPtr& params,
CefRequest::HeaderMap headerMap;
if (!params->headers.empty()) {
for (net::HttpUtil::HeadersIterator i(params->headers.begin(),
params->headers.end(), "\n\r");
for (net::HttpUtil::HeadersIterator i(params->headers, "\n\r");
i.GetNext();) {
request.AddHttpHeaderField(blink::WebString::FromUTF8(i.name()),
blink::WebString::FromUTF8(i.values()));

View File

@@ -48,7 +48,7 @@ void OverrideBaseBundleID() {
std::string bundle_id = GetMainBundleID();
DCHECK(!bundle_id.empty());
base::apple::SetBaseBundleID(bundle_id.c_str());
base::apple::SetBaseBundleIDOverride(bundle_id);
}
base::FilePath GetNormalChildProcessPath() {

View File

@@ -84,7 +84,6 @@ buildflag_header("buildflags") {
flags = [
"ENABLE_CEF=$enable_cef",
"IS_CEF_SANDBOX_BUILD=$is_cef_sandbox_build",
]
}

View File

@@ -5,13 +5,6 @@
declare_args() {
enable_cef = true
# Enables base target customizations necessary for distribution of the
# cef_sandbox static library. This value will be set via gn_args.py for the
# official sandbox build configurations only. DO NOT SET THIS VALUE MANUALLY
# FOR OTHER CHROMIUM/CEF BUILD CONFIGURATIONS AS ITS USE MAY HAVE SIGNIFICANT
# PERFORMANCE AND/OR SECURITY IMPLICATIONS.
is_cef_sandbox_build = false
# Optionally configure the CEF API version. This impacts wrapper-side only.
cef_api_version = ""
}

View File

@@ -29,6 +29,7 @@ set(CEF_TARGET libcef_dll_wrapper)
'autogen_capi_includes',
'includes_wrapper',
'includes_wrapper_mac:MAC',
'includes_wrapper_win:WINDOWS',
'includes_win:WINDOWS',
'includes_win_capi:WINDOWS',
'includes_mac:MAC',
@@ -38,6 +39,7 @@ set(CEF_TARGET libcef_dll_wrapper)
'libcef_dll_wrapper_sources_base',
'libcef_dll_wrapper_sources_common',
'libcef_dll_wrapper_sources_mac:MAC',
'libcef_dll_wrapper_sources_win:WINDOWS',
'autogen_client_side',
],
}}

View File

@@ -9,13 +9,26 @@
#include <windows.h>
#include <algorithm>
#include <sstream>
#elif defined(OS_POSIX)
#include <errno.h>
#include <pthread.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <sys/time.h>
#include <time.h>
#include <unistd.h>
#endif
#if defined(OS_APPLE)
#include <mach/mach_time.h>
#endif
#include <iomanip>
#include <iostream>
#include <sstream>
#include "include/base/cef_immediate_crash.h"
#include "include/internal/cef_string_types.h"
namespace cef {
@@ -130,8 +143,254 @@ std::string safe_strerror(int err) {
}
#endif // defined(OS_POSIX)
const internal::Implementation* g_impl_override = nullptr;
const char* const log_severity_names[] = {"INFO", "WARNING", "ERROR", "FATAL"};
static_assert(LOG_NUM_SEVERITIES == std::size(log_severity_names),
"Incorrect number of log_severity_names");
const char* log_severity_name(int severity) {
if (severity >= 0 && severity < LOG_NUM_SEVERITIES) {
return log_severity_names[severity];
}
return "UNKNOWN";
}
#if !defined(NDEBUG) && defined(OS_WIN)
bool IsUser32AndGdi32Available() {
static const bool is_user32_and_gdi32_available = [] {
// If win32k syscalls aren't disabled, then user32 and gdi32 are available.
PROCESS_MITIGATION_SYSTEM_CALL_DISABLE_POLICY policy = {};
if (::GetProcessMitigationPolicy(GetCurrentProcess(),
ProcessSystemCallDisablePolicy, &policy,
sizeof(policy))) {
return policy.DisallowWin32kSystemCalls == 0;
}
return true;
}();
return is_user32_and_gdi32_available;
}
std::wstring UTF8ToWide(const std::string& utf8) {
if (utf8.empty()) {
return {};
}
int size = MultiByteToWideChar(CP_UTF8, 0, utf8.data(),
static_cast<int>(utf8.size()), nullptr, 0);
if (size <= 0) {
return {};
}
std::wstring utf16(size, L'\0');
if (MultiByteToWideChar(CP_UTF8, 0, utf8.data(),
static_cast<int>(utf8.size()), &utf16[0],
size) != size) {
return {};
}
return utf16;
}
// Displays a message box to the user with the error message in it. Used for
// fatal messages, where we close the app simultaneously. This is for developers
// only; we don't use this in circumstances (like release builds) where users
// could see it, since users don't understand these messages anyway.
void DisplayDebugMessageInDialog(const std::string& message) {
if (IsUser32AndGdi32Available()) {
MessageBoxW(nullptr, UTF8ToWide(message).c_str(), L"Fatal error",
MB_OK | MB_ICONHAND | MB_TOPMOST);
} else {
OutputDebugStringW(UTF8ToWide(message).c_str());
}
}
#endif // !defined(NDEBUG) && defined(OS_WIN)
[[noreturn]] void HandleFatal(const std::string& message) {
// Don't display assertions to the user in release mode. The enduser can't do
// anything with this information, and displaying message boxes when the
// application is hosed can cause additional problems. We intentionally don't
// implement a dialog on other platforms. You can just look at stderr.
#if !defined(NDEBUG) && defined(OS_WIN)
if (!::IsDebuggerPresent()) {
// Displaying a dialog is unnecessary when debugging and can complicate
// debugging.
DisplayDebugMessageInDialog(message);
}
#endif
// Crash the process to generate a dump.
base::ImmediateCrash();
}
uint64_t TickCount() {
#if defined(OS_WIN)
return ::GetTickCount();
#elif defined(OS_APPLE)
return mach_absolute_time();
#elif defined(OS_POSIX)
struct timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts);
uint64_t absolute_micro = static_cast<uint64_t>(ts.tv_sec) * 1000000 +
static_cast<uint64_t>(ts.tv_nsec) / 1000;
return absolute_micro;
#else
#error Unsupported platform
#endif
}
} // namespace
namespace internal {
const Implementation* GetImplementation() {
if (g_impl_override) {
return g_impl_override;
}
static constexpr Implementation default_impl = {
&cef_get_min_log_level, &cef_get_vlog_level, &cef_log};
return &default_impl;
}
ScopedImplementation::~ScopedImplementation() {
g_impl_override = previous_;
}
ScopedImplementation::ScopedImplementation() = default;
void ScopedImplementation::Init(const Implementation* impl) {
previous_ = g_impl_override;
g_impl_override = impl;
}
} // namespace internal
ScopedEarlySupport::ScopedEarlySupport(const Config& config)
: impl_{{&ScopedEarlySupport::get_min_log_level,
&ScopedEarlySupport::get_vlog_level, &ScopedEarlySupport::log},
config} {
Init(&impl_.ptrs);
}
// static
const ScopedEarlySupport::Config& ScopedEarlySupport::GetConfig() {
return reinterpret_cast<const ScopedEarlySupport::Impl*>(g_impl_override)
->config;
}
// static
int ScopedEarlySupport::get_min_log_level() {
return GetConfig().min_log_level;
}
// static
int ScopedEarlySupport::get_vlog_level(const char* file_start, size_t N) {
return GetConfig().vlog_level;
}
// static
void ScopedEarlySupport::log(const char* file,
int line,
int severity,
const char* message) {
const Config& config = GetConfig();
// Most logging initializes `file` from __FILE__. Unfortunately, because we
// build from out/Foo we get a `../../` (or \) prefix for all of our
// __FILE__s. This isn't true for base::Location::Current() which already does
// the stripping (and is used for some logging, especially CHECKs).
//
// Here we strip the first 6 (../../ or ..\..\) characters if `file` starts
// with `.` but defensively clamp to strlen(file) just in case.
const std::string_view filename =
file[0] == '.' ? std::string_view(file).substr(
std::min(std::size_t{6}, strlen(file)))
: file;
std::stringstream stream;
stream << '[';
if (config.log_prefix) {
stream << config.log_prefix << ':';
}
if (config.log_process_id) {
#if defined(OS_WIN)
stream << ::GetCurrentProcessId() << ':';
#elif defined(OS_POSIX)
stream << getpid() << ':';
#else
#error Unsupported platform
#endif
}
if (config.log_thread_id) {
#if defined(OS_WIN)
stream << ::GetCurrentThreadId() << ':';
#elif defined(OS_APPLE)
uint64_t tid;
if (pthread_threadid_np(nullptr, &tid) == 0) {
stream << tid << ':';
}
#elif defined(OS_POSIX)
stream << pthread_self() << ':';
#else
#error Unsupported platform
#endif
}
if (config.log_timestamp) {
#if defined(OS_WIN)
SYSTEMTIME local_time;
GetLocalTime(&local_time);
stream << std::setfill('0') << std::setw(2) << local_time.wMonth
<< std::setw(2) << local_time.wDay << '/' << std::setw(2)
<< local_time.wHour << std::setw(2) << local_time.wMinute
<< std::setw(2) << local_time.wSecond << '.' << std::setw(3)
<< local_time.wMilliseconds << ':';
#elif defined(OS_POSIX)
timeval tv;
gettimeofday(&tv, nullptr);
time_t t = tv.tv_sec;
struct tm local_time;
localtime_r(&t, &local_time);
struct tm* tm_time = &local_time;
stream << std::setfill('0') << std::setw(2) << 1 + tm_time->tm_mon
<< std::setw(2) << tm_time->tm_mday << '/' << std::setw(2)
<< tm_time->tm_hour << std::setw(2) << tm_time->tm_min
<< std::setw(2) << tm_time->tm_sec << '.' << std::setw(6)
<< tv.tv_usec << ':';
#else
#error Unsupported platform
#endif
}
if (config.log_tickcount) {
stream << TickCount() << ':';
}
if (severity >= 0) {
stream << log_severity_name(severity);
} else {
stream << "VERBOSE" << -severity;
}
stream << ":" << filename << ":" << line << "] " << message;
const std::string& log_line = stream.str();
if (!config.formatted_log_handler ||
!config.formatted_log_handler(log_line.c_str())) {
// Log to stderr.
std::cerr << log_line << std::endl;
#if !defined(NDEBUG) && defined(OS_WIN)
if (severity < LOG_FATAL) {
// Log to the debugger console in debug builds.
OutputDebugStringW(UTF8ToWide(log_line).c_str());
}
#endif
}
if (severity == LOG_FATAL) {
HandleFatal(log_line);
}
}
// MSVC doesn't like complex extern templates and DLLs.
#if !defined(COMPILER_MSVC)
// Explicit instantiations for commonly used comparisons.
@@ -184,7 +443,8 @@ LogMessage::LogMessage(const char* file,
LogMessage::~LogMessage() {
std::string str_newline(stream_.str());
cef_log(file_, line_, severity_, str_newline.c_str());
internal::GetImplementation()->log(file_, line_, severity_,
str_newline.c_str());
}
#if defined(OS_WIN)

View File

@@ -0,0 +1,82 @@
// Copyright (c) 2025 The Chromium Embedded Framework Authors. All rights
// reserved. Use of this source code is governed by a BSD-style license that
// can be found in the LICENSE file.
#include "cef/libcef_dll/bootstrap/bootstrap_util_win.h"
#include "base/check_op.h"
#include "base/command_line.h"
namespace bootstrap_util {
namespace {
// Changes to these values require rebuilding libcef.dll.
constexpr wchar_t kWindowsSelfName[] = TEXT("bootstrap");
constexpr wchar_t kConsoleSelfName[] = TEXT("bootstrapc");
// Returns the file name only without extension, if any.
inline std::wstring NamePart(const base::FilePath& path) {
return path.BaseName().RemoveExtension().value();
}
} // namespace
bool IsDefaultExeName(const std::wstring& name) {
return base::FilePath::CompareEqualIgnoreCase(name, kWindowsSelfName) ||
base::FilePath::CompareEqualIgnoreCase(name, kConsoleSelfName);
}
std::wstring GetModuleValue(const base::CommandLine& command_line) {
if (command_line.HasSwitch(switches::kModule)) {
const auto& value = command_line.GetSwitchValuePath(switches::kModule);
if (!value.empty()) {
return NamePart(value);
}
}
return std::wstring();
}
base::FilePath GetExePath() {
HMODULE hModule = ::GetModuleHandle(nullptr);
CHECK(hModule);
return GetModulePath(hModule);
}
base::FilePath GetModulePath(HMODULE module) {
wchar_t buffer[MAX_PATH];
DWORD length = ::GetModuleFileName(module, buffer, MAX_PATH);
CHECK_NE(length, 0U);
CHECK_LT(length, static_cast<DWORD>(MAX_PATH));
return base::FilePath(buffer);
}
std::wstring GetValidatedModuleValue(const base::CommandLine& command_line,
const base::FilePath& exe_path) {
// Allow module value configuration if the bootstrap executable has the
// default name.
const auto& value = GetModuleValue(command_line);
if (!value.empty() && IsDefaultExeName(NamePart(exe_path))) {
return value;
}
return std::wstring();
}
std::wstring GetDefaultModuleValue(const base::FilePath& exe_path) {
return NamePart(exe_path);
}
bool IsModulePathAllowed(const base::FilePath& module_path,
const base::FilePath& exe_path) {
// Allow any module path if the bootstrap executable has the default name.
if (IsDefaultExeName(NamePart(exe_path))) {
return true;
}
// Module must be at the same path as the executable.
return module_path.DirName() == exe_path.DirName();
}
} // namespace bootstrap_util

View File

@@ -0,0 +1,53 @@
// Copyright (c) 2025 The Chromium Embedded Framework Authors. All rights
// reserved. Use of this source code is governed by a BSD-style license that
// can be found in the LICENSE file.
#ifndef CEF_LIBCEF_DLL_BOOTSTRAP_BOOTSTRAP_UTIL_WIN_H_
#define CEF_LIBCEF_DLL_BOOTSTRAP_BOOTSTRAP_UTIL_WIN_H_
#pragma once
#include <windows.h>
#include <string>
#include "base/files/file_path.h"
namespace base {
class CommandLine;
}
namespace bootstrap_util {
namespace switches {
// Changes to this value require rebuilding libcef.dll.
inline constexpr char kModule[] = "module";
} // namespace switches
// Returns true if |name| is one of the default bootstrap executable names.
bool IsDefaultExeName(const std::wstring& name);
// Returns the command-line configured module value without validation.
std::wstring GetModuleValue(const base::CommandLine& command_line);
// The following functions can only be called in unsandboxed processes.
// Returns the fully qualified file path for the executable module.
base::FilePath GetExePath();
// Returns the fully qualified file path for |module|.
base::FilePath GetModulePath(HMODULE module);
// Returns the command-line configured module value if it passes validation.
std::wstring GetValidatedModuleValue(const base::CommandLine& command_line,
const base::FilePath& exe_path);
// Returns the default module name (executable name without extension).
std::wstring GetDefaultModuleValue(const base::FilePath& exe_path);
// Returns true if loading |module_path| is allowed.
bool IsModulePathAllowed(const base::FilePath& module_path,
const base::FilePath& exe_path);
} // namespace bootstrap_util
#endif // CEF_LIBCEF_DLL_BOOTSTRAP_BOOTSTRAP_UTIL_WIN_H_

View File

@@ -0,0 +1,391 @@
// Copyright (c) 2025 The Chromium Embedded Framework Authors. All rights
// reserved. Use of this source code is governed by a BSD-style license that
// can be found in the LICENSE file.
#include <windows.h>
#include <iostream>
#include "base/command_line.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/logging.h"
#include "base/process/memory.h"
#include "base/process/process_info.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "cef/include/cef_sandbox_win.h"
#include "cef/include/cef_version.h"
#include "cef/include/cef_version_info.h"
#include "cef/include/internal/cef_types.h"
#include "cef/include/wrapper/cef_certificate_util_win.h"
#include "cef/include/wrapper/cef_util_win.h"
#include "cef/libcef/browser/crashpad_runner.h"
#include "cef/libcef/browser/preferred_stack_size_win.inc"
#include "cef/libcef_dll/bootstrap/bootstrap_util_win.h"
#include "cef/libcef_dll/bootstrap/win/resource.h"
#include "chrome/app/delay_load_failure_hook_win.h"
#include "chrome/chrome_elf/chrome_elf_main.h"
#include "chrome/install_static/initialize_from_primary_module.h"
#include "content/public/app/sandbox_helper_win.h"
#include "sandbox/policy/mojom/sandbox.mojom.h"
#include "sandbox/policy/sandbox_type.h"
#include "sandbox/win/src/sandbox.h"
namespace {
// Sets the current working directory for the process to the directory holding
// the executable if this is the browser process. This avoids leaking a handle
// to an arbitrary directory to child processes (e.g., the crashpad handler
// process).
void SetCwdForBrowserProcess() {
if (!::IsBrowserProcess()) {
return;
}
std::array<wchar_t, MAX_PATH + 1> buffer;
buffer[0] = L'\0';
DWORD length = ::GetModuleFileName(nullptr, &buffer[0], buffer.size());
if (!length || length >= buffer.size()) {
return;
}
base::SetCurrentDirectory(
base::FilePath(base::FilePath::StringViewType(&buffer[0], length))
.DirName());
}
#if DCHECK_IS_ON()
// Displays a message to the user with the error message. Used for fatal
// messages, where we close the app simultaneously. This is for developers only;
// we don't use this in circumstances (like release builds) where users could
// see it, since users don't understand these messages anyway.
// Load a string from the string table in bootstrap.rc.
std::wstring LoadString(int string_id) {
const int kMaxSize = 100;
TCHAR buff[kMaxSize] = {0};
::LoadString(::GetModuleHandle(nullptr), string_id, buff, kMaxSize);
return buff;
}
// Replace $1-$2-$3..$9 in the format string with values from |subst|.
// Additionally, any number of consecutive '$' characters is replaced by that
// number less one. Eg $$->$, $$$->$$, etc. Supports up to 9 replacements.
std::wstring FormatErrorString(int string_id,
base::span<const std::u16string> subst) {
return base::UTF16ToWide(base::ReplaceStringPlaceholders(
base::WideToUTF16(LoadString(string_id)), subst, nullptr));
}
void ShowError(const std::wstring& error) {
const auto subst = std::to_array<std::u16string>(
{base::WideToUTF16(bootstrap_util::GetExePath().BaseName().value())});
const auto& title = FormatErrorString(IDS_ERROR_TITLE, subst);
const auto& extra_info = LoadString(IDS_ERROR_EXTRA_INFO);
#if defined(CEF_BUILD_BOOTSTRAP_CONSOLE)
std::wcerr << title.c_str() << ": " << error << extra_info;
#else
if (!::IsDebuggerPresent()) {
// Displaying a dialog is unnecessary when debugging and can complicate
// debugging.
const std::wstring& msg = error + extra_info;
::MessageBox(nullptr, msg.c_str(), title.c_str(), MB_ICONERROR | MB_OK);
}
#endif
}
#endif // DCHECK_IS_ON()
std::wstring NormalizeError(const std::wstring& err) {
std::wstring str = err;
// Replace newlines.
std::replace(str.begin(), str.end(), L'\n', L' ');
return str;
}
// Verify DLL code signing requirements.
void CheckDllCodeSigning(
const base::FilePath& dll_path,
const cef_certificate_util::ThumbprintsInfo& exe_thumbprints) {
cef_certificate_util::ThumbprintsInfo dll_thumbprints;
cef_certificate_util::GetClientThumbprints(
dll_path.value(), /*verify_binary=*/true, dll_thumbprints);
// The DLL and EXE must either both be unsigned or both have all valid
// signatures and the same primary thumbprint.
if (!dll_thumbprints.IsSame(exe_thumbprints, /*allow_unsigned=*/true)) {
// Some part of the certificate validation process failed.
#if DCHECK_IS_ON()
const auto subst = std::to_array<std::u16string>(
{base::WideToUTF16(dll_path.BaseName().value()),
base::WideToUTF16(dll_thumbprints.errors)});
ShowError(FormatErrorString(IDS_ERROR_INVALID_CERT, subst));
#endif
if (dll_thumbprints.errors.empty()) {
LOG(FATAL) << "Failed " << dll_path.value()
<< " certificate requirements";
} else {
LOG(FATAL) << "Failed " << dll_path.value() << " certificate checks: "
<< NormalizeError(dll_thumbprints.errors);
}
}
}
} // namespace
#if defined(CEF_BUILD_BOOTSTRAP_CONSOLE)
int main(int argc, char* argv[]) {
#else // !defined(CEF_BUILD_BOOTSTRAP_CONSOLE)
// Entry point function for all processes.
int APIENTRY wWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow) {
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
#endif // !defined(CEF_BUILD_BOOTSTRAP_CONSOLE)
#if defined(ARCH_CPU_32_BITS)
// Run the main thread on 32-bit Windows using a fiber with the preferred 4MiB
// stack size. This function must be called at the top of the executable entry
// point function (`main()` or `wWinMain()`). It is used in combination with
// the initial stack size of 0.5MiB configured via the `/STACK:0x80000` linker
// flag on executable targets. This saves significant memory on threads (like
// those in the Windows thread pool, and others) whose stack size can only be
// controlled via the linker flag.
#if defined(CEF_BUILD_BOOTSTRAP_CONSOLE)
int exit_code = CefRunMainWithPreferredStackSize(main, argc, argv);
#else
int exit_code = CefRunWinMainWithPreferredStackSize(wWinMain, hInstance,
lpCmdLine, nCmdShow);
#endif
if (exit_code >= 0) {
// The fiber has completed so return here.
return exit_code;
}
#endif
SetCwdForBrowserProcess();
install_static::InitializeFromPrimaryModule();
SignalInitializeCrashReporting();
if (IsBrowserProcess()) {
chrome::DisableDelayLoadFailureHooksForMainExecutable();
}
// Done here to ensure that OOMs that happen early in process initialization
// are correctly signaled to the OS.
base::EnableTerminationOnOutOfMemory();
logging::RegisterAbslAbortHook();
// Parse command-line arguments.
const base::CommandLine command_line =
base::CommandLine::FromString(::GetCommandLineW());
constexpr char kProcessType[] = "type";
const bool is_subprocess = command_line.HasSwitch(kProcessType);
const std::string& process_type =
command_line.GetSwitchValueASCII(kProcessType);
if (is_subprocess && process_type.empty()) {
// Early exit on invalid process type.
return CEF_RESULT_CODE_BAD_PROCESS_TYPE;
}
// Run the crashpad handler now instead of waiting for libcef to load.
constexpr char kCrashpadHandler[] = "crashpad-handler";
if (process_type == kCrashpadHandler) {
return crashpad_runner::RunAsCrashpadHandler(command_line);
}
// IsUnsandboxedSandboxType() can't be used here because its result can be
// gated behind a feature flag, which are not yet initialized.
// Match the logic in MainDllLoader::Launch.
const bool is_sandboxed =
sandbox::policy::SandboxTypeFromCommandLine(command_line) !=
sandbox::mojom::Sandbox::kNoSandbox;
std::wstring dll_name;
base::FilePath exe_path;
cef_certificate_util::ThumbprintsInfo exe_thumbprints;
if (is_sandboxed) {
// Running as a sandboxed sub-process. May already be locked down, so we
// can't call WinAPI functions. The command-line will already have been
// validated in ChromeContentBrowserClientCef::
// AppendExtraCommandLineSwitches. Retrieve the module value without
// additional validation.
dll_name = bootstrap_util::GetModuleValue(command_line);
if (dll_name.empty()) {
// Default to the command-line program name without extension.
dll_name = command_line.GetProgram().BaseName().RemoveExtension().value();
}
} else {
// Running as the main process or unsandboxed sub-process.
exe_path = bootstrap_util::GetExePath();
// Retrieve the module name with validation.
dll_name = bootstrap_util::GetValidatedModuleValue(command_line, exe_path);
if (dll_name.empty()) {
// Default to the executable module file name without extension. This is
// safer than relying on the command-line program name.
dll_name = bootstrap_util::GetDefaultModuleValue(exe_path);
}
if (bootstrap_util::IsDefaultExeName(dll_name)) {
#if DCHECK_IS_ON()
ShowError(LoadString(IDS_ERROR_NO_MODULE_NAME));
#endif
LOG(FATAL) << "Missing module name";
}
cef_certificate_util::GetClientThumbprints(
exe_path.value(), /*verify_binary=*/true, exe_thumbprints);
// The executable must either be unsigned or have all valid signatures.
if (!exe_thumbprints.IsUnsignedOrValid()) {
// Some part of the certificate validation process failed.
#if DCHECK_IS_ON()
const auto subst = std::to_array<std::u16string>(
{base::WideToUTF16(exe_path.BaseName().value()),
base::WideToUTF16(exe_thumbprints.errors)});
ShowError(FormatErrorString(IDS_ERROR_INVALID_CERT, subst));
#endif
if (exe_thumbprints.errors.empty()) {
LOG(FATAL) << "Failed " << exe_path.value()
<< " certificate requirements";
} else {
LOG(FATAL) << "Failed " << exe_path.value() << " certificate checks: "
<< NormalizeError(exe_thumbprints.errors);
}
}
}
if (!is_sandboxed) {
// Check chrome_elf.dll which should be preloaded to support crash
// reporting.
if (HMODULE hModule = ::LoadLibrary(L"chrome_elf")) {
const auto& dll_path = bootstrap_util::GetModulePath(hModule);
// Must be in the same directory as the EXE.
if (dll_path.DirName() != exe_path.DirName()) {
#if DCHECK_IS_ON()
const auto subst = std::to_array<std::u16string>({u"chrome_elf"});
ShowError(FormatErrorString(IDS_ERROR_INVALID_LOCATION, subst));
#endif
LOG(FATAL) << "Invalid location: " << dll_path.value();
}
CheckDllCodeSigning(dll_path, exe_thumbprints);
FreeLibrary(hModule);
} else {
LOG(FATAL) << "Failed to load chrome_elf.dll with error "
<< ::GetLastError();
}
// Load the client DLL as untrusted (e.g. without executing DllMain or
// loading additional modules) so that we can first check requirements.
// LoadLibrary's "default search order" is tricky and we don't want to
// guess about what DLL it will load. DONT_RESOLVE_DLL_REFERENCES is the
// only option that doesn't execute DllMain while still allowing us
// retrieve the path using GetModuleFileName. No execution of the DLL
// should be attempted while loaded in this mode.
if (HMODULE hModule = ::LoadLibraryEx(dll_name.c_str(), nullptr,
DONT_RESOLVE_DLL_REFERENCES)) {
const auto& dll_path = bootstrap_util::GetModulePath(hModule);
if (!bootstrap_util::IsModulePathAllowed(dll_path, exe_path)) {
#if DCHECK_IS_ON()
const auto subst =
std::to_array<std::u16string>({base::WideToUTF16(dll_name)});
ShowError(FormatErrorString(IDS_ERROR_INVALID_LOCATION, subst));
#endif
LOG(FATAL) << "Invalid location: " << dll_path.value();
}
CheckDllCodeSigning(dll_path, exe_thumbprints);
FreeLibrary(hModule);
} else {
#if DCHECK_IS_ON()
const auto subst = std::to_array<std::u16string>(
{base::WideToUTF16(dll_name),
base::WideToUTF16(cef_util::GetLastErrorAsString())});
ShowError(FormatErrorString(IDS_ERROR_LOAD_FAILED, subst));
#endif
LOG(FATAL) << "Failed to load " << dll_name << ".dll with error "
<< ::GetLastError();
}
}
#if defined(CEF_BUILD_BOOTSTRAP_CONSOLE)
constexpr char kProcName[] = "RunConsoleMain";
using kProcType = decltype(&RunConsoleMain);
#else
constexpr char kProcName[] = "RunWinMain";
using kProcType = decltype(&RunWinMain);
#endif
// Load the client DLL normally.
if (HMODULE hModule = ::LoadLibrary(dll_name.c_str())) {
if (auto* pFunc = (kProcType)::GetProcAddress(hModule, kProcName)) {
// Initialize the sandbox services.
// Match the logic in MainDllLoader::Launch.
sandbox::SandboxInterfaceInfo sandbox_info = {nullptr};
if (!is_subprocess || is_sandboxed) {
// For child processes that are running as --no-sandbox, don't
// initialize the sandbox info, otherwise they'll be treated as brokers
// (as if they were the browser).
content::InitializeSandboxInfo(
&sandbox_info, IsExtensionPointDisableSet()
? sandbox::MITIGATION_EXTENSION_POINT_DISABLE
: 0);
}
cef_version_info_t version_info = {};
CEF_POPULATE_VERSION_INFO(&version_info);
// Return immediately without calling FreeLibrary() to avoid an illegal
// access during shutdown. The sandbox broker owns objects created inside
// libcef.dll (SandboxWin::InitBrokerServices) and cleanup is triggered
// via an _onexit handler (SingletonBase::OnExit) called after wWinMain
// exits.
#if defined(CEF_BUILD_BOOTSTRAP_CONSOLE)
return pFunc(argc, argv, &sandbox_info, &version_info);
#else
return pFunc(hInstance, lpCmdLine, nCmdShow, &sandbox_info,
&version_info);
#endif
} else {
#if DCHECK_IS_ON()
if (!is_sandboxed) {
const auto subst = std::to_array<std::u16string>(
{base::WideToUTF16(dll_name),
base::WideToUTF16(cef_util::GetLastErrorAsString()),
base::ASCIIToUTF16(std::string(kProcName))});
ShowError(FormatErrorString(IDS_ERROR_NO_PROC_EXPORT, subst));
}
#endif
LOG(FATAL) << "Failed to find " << kProcName << " in " << dll_name
<< ".dll with error " << ::GetLastError();
}
} else {
#if DCHECK_IS_ON()
if (!is_sandboxed) {
const auto subst = std::to_array<std::u16string>(
{base::WideToUTF16(dll_name),
base::WideToUTF16(cef_util::GetLastErrorAsString())});
ShowError(FormatErrorString(IDS_ERROR_LOAD_FAILED, subst));
}
#endif
LOG(FATAL) << "Failed to load " << dll_name << ".dll with error "
<< ::GetLastError();
}
// LOG(FATAL) is [[noreturn]], so we never reach this point.
NOTREACHED();
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

View File

@@ -0,0 +1,134 @@
// Microsoft Visual C++ generated resource script.
//
#include "libcef_dll/bootstrap/win/resource.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#define APSTUDIO_HIDDEN_SYMBOLS
#include "windows.h"
#include "include/cef_version.h"
#undef APSTUDIO_HIDDEN_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// English (U.S.) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#endif //_WIN32
/////////////////////////////////////////////////////////////////////////////
//
// Icon
//
// Icon with lowest ID value placed first to ensure application icon
// remains consistent on all systems.
IDI_APPLICATION ICON "bootstrap.ico"
/////////////////////////////////////////////////////////////////////////////
//
// Version
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION CEF_VERSION_MAJOR,CEF_VERSION_MINOR,CEF_VERSION_PATCH,0
PRODUCTVERSION CEF_VERSION_MAJOR,CEF_VERSION_MINOR,CEF_VERSION_PATCH,0
FILEFLAGSMASK 0x17L
#ifdef _DEBUG
FILEFLAGS 0x1L
#else
FILEFLAGS 0x0L
#endif
FILEOS 0x4L
FILETYPE 0x2L
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904b0"
BEGIN
VALUE "FileDescription", "CEF Bootstrap Application"
VALUE "FileVersion", CEF_VERSION
#if defined(CEF_BUILD_BOOTSTRAP_CONSOLE)
VALUE "InternalName", "bootstrapc"
VALUE "OriginalFilename", "bootstrapc.exe"
#else
VALUE "InternalName", "bootstrap"
VALUE "OriginalFilename", "bootstrap.exe"
#endif
VALUE "LegalCopyright", "Copyright (C) " MAKE_STRING(COPYRIGHT_YEAR) " The Chromium Embedded Framework Authors"
VALUE "ProductName", "CEF Bootstrap Application"
VALUE "ProductVersion", CEF_VERSION
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1200
END
END
/////////////////////////////////////////////////////////////////////////////
//
// String Table
//
STRINGTABLE
BEGIN
IDS_ERROR_TITLE "Runtime Error: $1"
IDS_ERROR_EXTRA_INFO "\nTry reinstalling the application to fix this error."
IDS_ERROR_NO_MODULE_NAME "Missing module name"
IDS_ERROR_NO_PROC_EXPORT "Failed to find $3 in $1.dll\n$2"
IDS_ERROR_INVALID_LOCATION "Found $1.dll in an unexpected location"
IDS_ERROR_LOAD_FAILED "Failed to load $1.dll\n$2"
IDS_ERROR_INVALID_CERT "Failed certificate validation for $1\n$2"
END
#endif // English (U.S.) resources
/////////////////////////////////////////////////////////////////////////////
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE
BEGIN
"resource.h\0"
END
2 TEXTINCLUDE
BEGIN
"#define APSTUDIO_HIDDEN_SYMBOLS\r\n"
"#include ""windows.h""\r\n"
"#undef APSTUDIO_HIDDEN_SYMBOLS\r\n"
"\0"
END
3 TEXTINCLUDE
BEGIN
"\r\n"
"\0"
END
#endif // APSTUDIO_INVOKED
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED

View File

@@ -0,0 +1,27 @@
// Copyright (c) 2025 The Chromium Embedded Framework Authors. All rights
// reserved. Use of this source code is governed by a BSD-style license that
// can be found in the LICENSE file.
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by cefclient.rc
//
#define IDS_ERROR_TITLE 100
#define IDS_ERROR_EXTRA_INFO 101
#define IDS_ERROR_NO_MODULE_NAME 102
#define IDS_ERROR_NO_PROC_EXPORT 103
#define IDS_ERROR_INVALID_LOCATION 104
#define IDS_ERROR_LOAD_FAILED 105
#define IDS_ERROR_INVALID_CERT 106
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NO_MFC 1
#define _APS_NEXT_RESOURCE_VALUE 106
#define _APS_NEXT_COMMAND_VALUE 32000
#define _APS_NEXT_CONTROL_VALUE 1000
#define _APS_NEXT_SYMED_VALUE 100
#endif
#endif

View File

@@ -45,6 +45,17 @@ CEF_EXPORT int cef_version_info(int entry) {
}
}
CEF_EXPORT void cef_version_info_all(cef_version_info_t* info) {
info->cef_version_major = CEF_VERSION_MAJOR;
info->cef_version_minor = CEF_VERSION_MINOR;
info->cef_version_patch = CEF_VERSION_PATCH;
info->cef_commit_number = CEF_COMMIT_NUMBER;
info->chrome_version_major = CHROME_VERSION_MAJOR;
info->chrome_version_minor = CHROME_VERSION_MINOR;
info->chrome_version_build = CHROME_VERSION_BUILD;
info->chrome_version_patch = CHROME_VERSION_PATCH;
}
#include "cef/libcef_dll/cef_api_versions.inc"
CEF_EXPORT const char* cef_api_hash(int version, int entry) {

View File

@@ -47,19 +47,3 @@ void cef_sandbox_destroy(void* sandbox_context) {
delete static_cast<sandbox::SeatbeltExecServer::CreateFromArgumentsResult*>(
sandbox_context);
}
CefScopedSandboxContext::CefScopedSandboxContext() : sandbox_context_(NULL) {}
CefScopedSandboxContext::~CefScopedSandboxContext() {
if (sandbox_context_) {
cef_sandbox_destroy(sandbox_context_);
}
}
bool CefScopedSandboxContext::Initialize(int argc, char** argv) {
if (sandbox_context_) {
return false;
}
sandbox_context_ = cef_sandbox_initialize(argc, argv);
return !!sandbox_context_;
}

View File

@@ -5,7 +5,6 @@
#include "sandbox/win/src/sandbox.h"
#include "base/notreached.h"
#include "cef/libcef/features/features.h"
#include "include/cef_sandbox_win.h"
#include "sandbox/win/src/sandbox_factory.h"
@@ -39,19 +38,3 @@ void* cef_sandbox_info_create() {
void cef_sandbox_info_destroy(void* sandbox_info) {
delete static_cast<sandbox::SandboxInterfaceInfo*>(sandbox_info);
}
#if BUILDFLAG(IS_CEF_SANDBOX_BUILD)
// Avoid bringing in partition_alloc dependencies.
namespace partition_alloc {
bool ReleaseReservation() {
DCHECK(false);
return false;
}
void TerminateBecauseOutOfMemory(size_t size) {
DCHECK(false);
}
} // namespace partition_alloc
#endif // BUILDFLAG(IS_CEF_SANDBOX_BUILD)

View File

@@ -0,0 +1,243 @@
// Copyright (c) 2025 The Chromium Embedded Framework Authors. All rights
// reserved. Use of this source code is governed by a BSD-style license that
// can be found in the LICENSE file.
#include "include/wrapper/cef_certificate_util_win.h"
#include <windows.h>
#include <Softpub.h>
#include <stdio.h>
#include <wincrypt.h>
#include <wintrust.h>
#include <algorithm>
#include "include/wrapper/cef_util_win.h"
#if defined(CEF_BUILD_BOOTSTRAP)
#include "base/logging.h"
#else
#include "include/base/cef_logging.h"
#endif
namespace cef_certificate_util {
namespace {
bool InitCryptProviderStructs(WINTRUST_DATA& win_trust_data,
CRYPT_PROVIDER_DATA*& prov_data_ptr,
CRYPT_PROVIDER_SGNR*& prov_signer_ptr,
CRYPT_PROVIDER_CERT*& prov_cert_ptr) {
prov_data_ptr = WTHelperProvDataFromStateData(win_trust_data.hWVTStateData);
if (prov_data_ptr) {
prov_signer_ptr = WTHelperGetProvSignerFromChain(
(PCRYPT_PROVIDER_DATA)prov_data_ptr, 0, FALSE, 0);
if (prov_signer_ptr) {
prov_cert_ptr = WTHelperGetProvCertFromChain(prov_signer_ptr, 0);
if (prov_cert_ptr) {
return true;
}
}
}
return false;
}
// Returns bytes as an upper-case hex string.
std::string BytesToHexString(const BYTE* bytes, size_t length) {
std::string hex_string;
hex_string.resize(length * 2);
for (size_t index = 0; index < length; ++index) {
sprintf_s(&hex_string[2 * index], 3, "%02X", bytes[index]);
}
return hex_string;
}
std::wstring ErrorPrefix(DWORD i) {
return L"\nCertificate " + std::to_wstring(i) + L": ";
}
std::wstring NormalizeError(const std::wstring& err) {
std::wstring str = err;
// Replace newlines.
std::replace(str.begin(), str.end(), L'\n', L' ');
return str;
}
std::wstring GetBinaryName(const std::wstring& path) {
auto sep_pos = path.find_last_of(L"/\\");
if (sep_pos == std::wstring::npos) {
return path;
}
return path.substr(0, sep_pos);
}
} // namespace
void GetClientThumbprints(const std::wstring& binary_path,
bool verify_binary,
ThumbprintsInfo& info) {
info = {};
const HWND wvt_handle = static_cast<HWND>(INVALID_HANDLE_VALUE);
GUID wvt_policy = WINTRUST_ACTION_GENERIC_VERIFY_V2;
WINTRUST_FILE_INFO file_info = {};
file_info.cbStruct = sizeof(file_info);
file_info.pcwszFilePath = binary_path.c_str();
WINTRUST_SIGNATURE_SETTINGS sig_settings = {};
sig_settings.cbStruct = sizeof(sig_settings);
// We will verify each signature separately, but also get the number of
// secondary signatures present in the file.
sig_settings.dwFlags = WSS_GET_SECONDARY_SIG_COUNT | WSS_VERIFY_SPECIFIC;
// cSecondarySigs starts off as 0. We assume we have one primary signature.
// After the first WinVerifyTrust call succeeds, we will continue inspecting
// the rest of the signatures.
for (DWORD i = 0; i < sig_settings.cSecondarySigs + 1; ++i) {
WINTRUST_DATA win_trust_data = {0};
win_trust_data.cbStruct = sizeof(win_trust_data);
win_trust_data.dwUIChoice = WTD_UI_NONE;
// No revocation checking.
win_trust_data.fdwRevocationChecks = WTD_REVOKE_NONE;
// Prevent revocation checks over the network.
win_trust_data.dwProvFlags = WTD_CACHE_ONLY_URL_RETRIEVAL;
win_trust_data.dwUnionChoice = WTD_CHOICE_FILE;
win_trust_data.dwStateAction = WTD_STATEACTION_VERIFY;
win_trust_data.pFile = &file_info;
win_trust_data.pSignatureSettings = &sig_settings;
sig_settings.dwIndex = i;
const auto status =
WinVerifyTrust(wvt_handle, &wvt_policy, &win_trust_data);
const bool valid = status == ERROR_SUCCESS;
if (!valid) {
if (i == 0 && status == TRUST_E_NOSIGNATURE) {
const auto last_error = static_cast<HRESULT>(::GetLastError());
if (TRUST_E_NOSIGNATURE == last_error ||
TRUST_E_SUBJECT_FORM_UNKNOWN == last_error ||
TRUST_E_PROVIDER_UNKNOWN == last_error) {
// The file is not signed.
return;
}
}
info.errors += ErrorPrefix(i) + L"WinVerifyTrust failed: " +
cef_util::GetLastErrorAsString();
// WinVerifyTrust will fail if the signing certificates can't be verified,
// but it will still provide information about them in the StateData
// structure. We only continue if the method asks for this.
if (verify_binary) {
// If the primary signature fails, we will return and not inspect the
// rest of the signatures.
if (i == 0) {
info.has_signature = true;
return;
}
continue;
}
}
if (!win_trust_data.hWVTStateData) {
info.errors += ErrorPrefix(i) + L"No WinVerifyTrust data";
continue;
}
CRYPT_PROVIDER_DATA* prov_data = NULL;
CRYPT_PROVIDER_SGNR* prov_signer = NULL;
CRYPT_PROVIDER_CERT* prov_cert = NULL;
if (InitCryptProviderStructs(win_trust_data, prov_data, prov_signer,
prov_cert)) {
// Using SHA1 hash here because: (a) SHA1 is used internally by default in
// most tools that inspect certificates, (b) the SHA1 value is more likely
// to aleady be cached, (c) SHA1 is faster to compute than SHA256 if not
// already cached, and (d) SHA1 is still resistant to preimage attacks
// (e.g. trying to match specific hashes), particularly when used on DEC
// formatted certificates as in this case.
// SHA1 hash = 20 bytes.
BYTE sha1_bytes[20] = {};
DWORD sha1_bytes_count = sizeof(sha1_bytes);
// Read or compute the SHA1 hash of the certificate (thumbprint), and
// convert it to a hex string.
if (CertGetCertificateContextProperty(prov_cert->pCert,
CERT_SHA1_HASH_PROP_ID, sha1_bytes,
&sha1_bytes_count)) {
auto& thumbprints =
valid ? info.valid_thumbprints : info.invalid_thumbprints;
thumbprints.emplace_back(
BytesToHexString(sha1_bytes, sha1_bytes_count));
} else {
info.errors += ErrorPrefix(i) +
L"CertGetCertificateContextProperty failed: " +
cef_util::GetLastErrorAsString();
}
} else {
info.errors += ErrorPrefix(i) + L"Invalid WinVerifyTrust data";
}
win_trust_data.dwStateAction = WTD_STATEACTION_CLOSE;
WinVerifyTrust(wvt_handle, &wvt_policy, &win_trust_data);
}
info.has_signature = true;
}
bool ValidateCodeSigning(const std::wstring& binary_path,
const char* thumbprint,
bool allow_unsigned,
ThumbprintsInfo& info) {
GetClientThumbprints(binary_path.data(), /*verify_binary=*/true, info);
if (!info.errors.empty()) {
// The binary is signed, but one or more of the signatures failed
// validation.
return false;
}
const bool thumbprint_required =
thumbprint && std::strlen(thumbprint) == kThumbprintLength;
allow_unsigned &= !thumbprint_required;
if (thumbprint_required) {
if (!info.HasPrimaryThumbprint(thumbprint)) {
// The DLL is unsigned or the primary signature does not match the
// required thumbprint.
return false;
}
} else if (!allow_unsigned && !info.has_signature) {
// The DLL in unsigned which is not allowed.
return false;
}
return true;
}
void ValidateCodeSigningAssert(const std::wstring& binary_path,
const char* thumbprint,
bool allow_unsigned,
ThumbprintsInfo* info) {
cef_certificate_util::ThumbprintsInfo thumbprints;
bool valid = cef_certificate_util::ValidateCodeSigning(
binary_path.data(), thumbprint, allow_unsigned, thumbprints);
if (!thumbprints.errors.empty()) {
// The DLL is signed, but one or more of the signatures failed validation.
LOG(FATAL) << "Failed " << GetBinaryName(binary_path)
<< " certificate validation: "
<< NormalizeError(thumbprints.errors);
}
if (!valid) {
// Failed other requirements.
LOG(FATAL) << "Failed " << GetBinaryName(binary_path)
<< " validation requirements.";
}
if (info) {
*info = thumbprints;
}
}
} // namespace cef_certificate_util

View File

@@ -2,8 +2,6 @@
// reserved. Use of this source code is governed by a BSD-style license that
// can be found in the LICENSE file.
#include "include/wrapper/cef_library_loader.h"
#include <libgen.h>
#include <mach-o/dyld.h>
#include <stdio.h>
@@ -11,6 +9,8 @@
#include <memory>
#include <sstream>
#include "include/wrapper/cef_library_loader.h"
namespace {
const char kFrameworkPath[] =
@@ -46,7 +46,7 @@ std::string GetFrameworkPath(bool helper) {
} // namespace
CefScopedLibraryLoader::CefScopedLibraryLoader() : loaded_(false) {}
CefScopedLibraryLoader::CefScopedLibraryLoader() = default;
bool CefScopedLibraryLoader::Load(bool helper) {
if (loaded_) {

View File

@@ -0,0 +1,130 @@
// Copyright (c) 2025 The Chromium Embedded Framework Authors. All rights
// reserved. Use of this source code is governed by a BSD-style license that
// can be found in the LICENSE file.
#include <algorithm>
#include "include/base/cef_logging.h"
#include "include/wrapper/cef_certificate_util_win.h"
#include "include/wrapper/cef_library_loader.h"
#include "include/wrapper/cef_util_win.h"
namespace {
bool IsEqualIgnoringCase(const std::wstring& str1, const std::wstring& str2) {
return std::equal(
str1.begin(), str1.end(), str2.begin(), str2.end(),
[](wchar_t a, wchar_t b) { return std::tolower(a) == std::tolower(b); });
}
HMODULE Load(const std::wstring& dll_path,
const char* thumbprint,
bool allow_unsigned,
bool is_subprocess,
cef_version_info_t* version_info) {
if (!is_subprocess) {
// Load the client DLL as untrusted (e.g. without executing DllMain or
// loading additional modules) so that we can first check requirements.
// LoadLibrary's "default search order" is tricky and we don't want to guess
// about what DLL it will load. DONT_RESOLVE_DLL_REFERENCES is the only
// option that doesn't execute DllMain while still allowing us retrieve the
// path using GetModuleFileName. No execution of the DLL should be attempted
// while loaded in this mode.
if (HMODULE hModule = ::LoadLibraryEx(
dll_path.data(), nullptr,
DONT_RESOLVE_DLL_REFERENCES | LOAD_WITH_ALTERED_SEARCH_PATH)) {
const auto& module_path = cef_util::GetModulePath(hModule);
if (!IsEqualIgnoringCase(module_path, dll_path)) {
LOG(FATAL) << "Found libcef.dll at unexpected path";
}
// Generate a FATAL error and crash if validation fails.
cef_certificate_util::ValidateCodeSigningAssert(dll_path, thumbprint,
allow_unsigned);
FreeLibrary(hModule);
} else {
LOG(FATAL) << "Failed to load libcef.dll";
}
}
// Load normally.
if (HMODULE hModule = ::LoadLibraryEx(dll_path.data(), nullptr,
LOAD_WITH_ALTERED_SEARCH_PATH)) {
// libcef functions should now be callable via the /DELAYLOAD handler.
if (version_info) {
// Compare Chromium version for the client/bootstrap and libcef.dll. This
// strict version check is necessary because both sandbox info and
// chrome_elf introduce Chromium version dependencies, and we don't know
// which non-matching versions are compatible.
cef_version_info_t dll_info = {};
dll_info.size = sizeof(cef_version_info_t);
#if CEF_API_ADDED(13800)
cef_version_info_all(&dll_info);
#else
// Only populating the members that are used below.
dll_info.chrome_version_major = cef_version_info(4);
dll_info.chrome_version_patch = cef_version_info(7);
#endif
if (dll_info.chrome_version_major != version_info->chrome_version_major ||
dll_info.chrome_version_patch != version_info->chrome_version_patch) {
LOG(FATAL) << "Failed libcef.dll version check; expected "
<< version_info->chrome_version_major << "."
<< version_info->chrome_version_major << ", got "
<< dll_info.chrome_version_major << "."
<< dll_info.chrome_version_major;
}
}
return hModule;
}
LOG(FATAL) << "Failed to load libcef.dll";
return nullptr;
}
} // namespace
CefScopedLibraryLoader::CefScopedLibraryLoader() = default;
bool CefScopedLibraryLoader::LoadInMainAssert(
const wchar_t* dll_path,
const char* thumbprint,
bool allow_unsigned,
cef_version_info_t* version_info) {
CHECK(!handle_);
handle_ = Load(dll_path, thumbprint, allow_unsigned, false, version_info);
return handle_ != nullptr;
}
bool CefScopedLibraryLoader::LoadInSubProcessAssert(
cef_version_info_t* version_info) {
CHECK(!handle_);
constexpr wchar_t kProcessTypeW[] = L"type";
const auto& command_line =
cef_util::ParseCommandLineArgs(::GetCommandLineW());
if (command_line.size() <= 1) {
return false;
}
if (cef_util::GetCommandLineValue(command_line, kProcessTypeW).empty()) {
return false;
}
const auto& dll_path =
cef_util::GetCommandLineValue(command_line, switches::kLibcefPathW);
if (dll_path.empty()) {
// Default is libcef.dll in the same directory the executable and loaded by
// the delayload helper.
return true;
}
handle_ = Load(dll_path, nullptr, true, true, version_info);
return handle_ != nullptr;
}
CefScopedLibraryLoader::~CefScopedLibraryLoader() {
if (handle_) {
::FreeLibrary(handle_);
}
}

View File

@@ -0,0 +1,113 @@
// Copyright 2025 The Chromium Embedded Framework Authors. Portions Copyright
// 2018 the Chromium Authors. All rights reserved. Use of this source code is
// governed by a BSD-style license that can be found in the LICENSE file.
#include <dlfcn.h>
#include <libgen.h>
#include <mach-o/dyld.h>
#include <stdio.h>
#include <memory>
#include <sstream>
#include "include/cef_sandbox_mac.h"
namespace {
// Relative path to the library from the Helper executable.
constexpr char kLibraryPath[] =
"../../../Chromium Embedded Framework.framework/"
"Libraries/libcef_sandbox.dylib";
std::string GetLibraryPath() {
uint32_t exec_path_size = 0;
int rv = _NSGetExecutablePath(NULL, &exec_path_size);
if (rv != -1) {
return std::string();
}
std::unique_ptr<char[]> exec_path(new char[exec_path_size]);
rv = _NSGetExecutablePath(exec_path.get(), &exec_path_size);
if (rv != 0) {
return std::string();
}
// Get the directory path of the executable.
const char* parent_dir = dirname(exec_path.get());
if (!parent_dir) {
return std::string();
}
// Append the relative path to the library.
std::stringstream ss;
ss << parent_dir << "/" << kLibraryPath;
return ss.str();
}
void* LoadLibrary(const char* path) {
void* handle = dlopen(path, RTLD_LAZY | RTLD_LOCAL | RTLD_FIRST);
if (!handle) {
fprintf(stderr, "dlopen %s: %s\n", path, dlerror());
return nullptr;
}
return handle;
}
void UnloadLibrary(void* handle) {
// Returns 0 on success.
if (dlclose(handle)) {
fprintf(stderr, "dlclose: %s\n", dlerror());
}
}
void* GetLibraryPtr(void* handle, const char* name) {
void* ptr = dlsym(handle, name);
if (!ptr) {
fprintf(stderr, "dlsym: %s\n", dlerror());
}
return ptr;
}
void* SandboxInitialize(void* handle, int argc, char** argv) {
if (auto* ptr = (decltype(&cef_sandbox_initialize))GetLibraryPtr(
handle, "cef_sandbox_initialize")) {
return ptr(argc, argv);
}
return nullptr;
}
void SandboxDestroy(void* handle, void* sandbox_context) {
if (auto* ptr = (decltype(&cef_sandbox_destroy))GetLibraryPtr(
handle, "cef_sandbox_destroy")) {
ptr(sandbox_context);
}
}
} // namespace
CefScopedSandboxContext::CefScopedSandboxContext() = default;
CefScopedSandboxContext::~CefScopedSandboxContext() {
if (library_handle_) {
if (sandbox_context_) {
SandboxDestroy(library_handle_, sandbox_context_);
}
UnloadLibrary(library_handle_);
}
}
bool CefScopedSandboxContext::Initialize(int argc, char** argv) {
if (!library_handle_) {
const std::string& library_path = GetLibraryPath();
if (library_path.empty()) {
fprintf(stderr, "App does not have the expected bundle structure.\n");
return false;
}
library_handle_ = LoadLibrary(library_path.c_str());
}
if (!library_handle_ || sandbox_context_) {
return false;
}
sandbox_context_ = SandboxInitialize(library_handle_, argc, argv);
return !!sandbox_context_;
}

View File

@@ -0,0 +1,142 @@
// Copyright (c) 2025 The Chromium Embedded Framework Authors. All rights
// reserved. Use of this source code is governed by a BSD-style license that
// can be found in the LICENSE file.
#include "include/wrapper/cef_util_win.h"
#include <shellapi.h>
#include <algorithm>
#include <cwctype>
#include <string>
#include <vector>
#if defined(CEF_BUILD_BOOTSTRAP)
#include "base/check_op.h"
#else
#include "include/base/cef_logging.h"
#endif
namespace cef_util {
namespace {
void TrimWhitespace(std::wstring& str) {
// Trim leading whitespace
str.erase(str.begin(), std::find_if(str.begin(), str.end(), [](auto ch) {
return !std::iswspace(ch);
}));
// Trim trailing whitespace
str.erase(std::find_if(str.rbegin(), str.rend(),
[](auto ch) { return !std::iswspace(ch); })
.base(),
str.end());
}
} // namespace
std::wstring GetExePath() {
HMODULE hModule = ::GetModuleHandle(nullptr);
CHECK(hModule);
return GetModulePath(hModule);
}
std::wstring GetModulePath(HMODULE module) {
wchar_t buffer[MAX_PATH];
DWORD length = ::GetModuleFileName(module, buffer, MAX_PATH);
CHECK_NE(length, 0U);
CHECK_LT(length, static_cast<DWORD>(MAX_PATH));
return buffer;
}
std::wstring GetLastErrorAsString() {
std::wstring error_message;
DWORD error_message_id = ::GetLastError();
if (error_message_id == 0) {
return error_message;
}
LPWSTR message_buffer = NULL;
DWORD size = FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, error_message_id, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPWSTR)&message_buffer, 0, NULL);
if (message_buffer) {
error_message = std::wstring(message_buffer, size);
LocalFree(message_buffer);
}
return error_message;
}
// Implementation based on CommandLine::ParseFromString.
std::vector<std::wstring> ParseCommandLineArgs(const wchar_t* str) {
std::wstring command_line = str;
TrimWhitespace(command_line);
int num_args = 0;
wchar_t** args = NULL;
// When calling CommandLineToArgvW, use the apiset if available.
// Doing so will bypass loading shell32.dll on Windows.
HMODULE downlevel_shell32_dll =
::LoadLibraryEx(L"api-ms-win-downlevel-shell32-l1-1-0.dll", nullptr,
LOAD_LIBRARY_SEARCH_SYSTEM32);
if (downlevel_shell32_dll) {
auto command_line_to_argv_w_proc =
reinterpret_cast<decltype(::CommandLineToArgvW)*>(
::GetProcAddress(downlevel_shell32_dll, "CommandLineToArgvW"));
if (command_line_to_argv_w_proc) {
args = command_line_to_argv_w_proc(command_line.data(), &num_args);
}
} else {
// Since the apiset is not available, allow the delayload of shell32.dll
// to take place.
args = ::CommandLineToArgvW(command_line.data(), &num_args);
}
std::vector<std::wstring> result;
result.reserve(num_args);
for (int i = 0; i < num_args; ++i) {
std::wstring arg = args[i];
TrimWhitespace(arg);
if (!arg.empty()) {
result.push_back(arg);
}
}
LocalFree(args);
if (downlevel_shell32_dll) {
::FreeLibrary(downlevel_shell32_dll);
}
return result;
}
std::wstring GetCommandLineValue(const std::vector<std::wstring>& command_line,
const std::wstring& name) {
constexpr wchar_t kPrefix[] = L"--";
constexpr wchar_t kSeparator[] = L"=";
constexpr wchar_t kQuoteChar = L'"';
const std::wstring& start = kPrefix + name + kSeparator;
for (const auto& arg : command_line) {
if (arg.find(start) == 0) {
auto value = arg.substr(start.length());
if (value.length() > 2 && value[0] == kQuoteChar &&
value[arg.length() - 1] == kQuoteChar) {
value = value.substr(1, value.length() - 2);
}
return value;
}
}
return std::wstring();
}
} // namespace cef_util

View File

@@ -126,6 +126,10 @@ patches = [
# win: Delay enablement of native occlusion tracking until the initially-
# minimized window is restored for the first time.
# https://github.com/chromiumembedded/cef/issues/3638
#
# win: Don't call DwmSetWindowAttribute when the browser has an external
# parent. This call only applies for top-level windows.
# https://issuetracker.google.com/issues/41241478
'name': 'views_widget',
},
{
@@ -266,6 +270,9 @@ patches = [
# Fix usage of JavaScript tab modal dialogs with Alloy style browsers.
# Modifies the logic added in https://crrev.com/78ce55cbc0.
# https://github.com/chromiumembedded/cef/issues/3818
#
# Fix crash with OSR browsers on Linux.
# https://github.com/chromiumembedded/cef/issues/3921
'name': 'chrome_browser_dialogs_jsmodal',
},
{
@@ -350,7 +357,8 @@ patches = [
'name': 'embedder_product_override',
},
{
# Fix Jumbo/component build dependency issue.
# Fix component build dependency issue.
# https://issues.chromium.org/issues/414506471
'name': 'chrome_browser_safe_browsing',
},
{
@@ -389,7 +397,10 @@ patches = [
#
# Windows: Fix crash during window creation.
# https://bugs.chromium.org/p/chromium/issues/detail?id=761389
'name': 'rwh_background_color_1984',
#
# Add RWHVAura::SetRootWindowBoundsCallback.
# https://github.com/chromiumembedded/cef/issues/3920
'name': 'renderer_host_aura',
},
{
# Expose RFH via NavigationHandle for retrieval in DidFinishNavigation on
@@ -425,11 +436,6 @@ patches = [
# https://github.com/chromiumembedded/cef/issues/2196
'name': 'printing_context_2196',
},
{
# Disable thin archives with cef_sandbox builds.
# https://github.com/chromiumembedded/cef/issues/3674
'name': 'build',
},
{
# macOS: Make the NativeEventProcessor protocol dependency optional.
# https://github.com/chromiumembedded/cef/issues/2539
@@ -508,30 +514,6 @@ patches = [
# https://github.com/chromiumembedded/cef/issues/1872
'name': 'base_command_line_1872',
},
{
# Remove cef_sandbox dependency on boringssl functions.
# https://github.com/chromiumembedded/cef/issues/2743
#
# Enable the VS 2015 Update 2 fix when building with the MSVC standard
# library.
#
# Avoid usage of std::atomic_flag::test() added in C++20.
# https://github.com/llvm/llvm-project/issues/57364
#
# Avoid usage of PartitionAlloc assertions (PA_BASE_CHECK) in raw_ptr.h.
#
# win: Add SHA256 implementation for Sid::FromNamedCapability using the
# Crypto API.
# https://github.com/chromiumembedded/cef/issues/3791
#
# win: Disable use of Rust for JSON parsing with cef_sandbox.
# Enables the fallback to C++ that was removed in
# https://crrev.com/9ddc1624637c8cfa8ef50a95abd779e0ba4d67f6
#
# Avoid inclusion of undefined PartitionAlloc dependencies in Dawn after
# https://crrev.com/4dacf2b61c359950d2c2f1b5f9b9d079a01290a4
'name': 'base_sandbox_2743',
},
{
# Add RenderWidgetHostImpl::SetCompositorForFlingScheduler to fix fling
# scrolling in OSR mode.
@@ -541,12 +523,6 @@ patches = [
# https://github.com/chromiumembedded/cef/issues/3834
'name': 'osr_fling_2745',
},
{
# Windows: Build targets as C++17 to avoid export of std::is_integral
# templates in cef_sandbox that should be inlined.
# https://github.com/chromiumembedded/cef/issues/2819
'name': 'win_cpp17_msvc_sandbox_2819',
},
{
# libxml access is now limited to targets audited by the Security Team.
# https://chromium-review.googlesource.com/c/chromium/src/+/1884750
@@ -577,13 +553,6 @@ patches = [
# https://github.com/chromiumembedded/cef/issues/3210
'name': 'win_sandbox_3210',
},
{
# Windows: Fix MSVC compile error with sandbox target.
# error: static assertion failed due to requirement
# '!is_const_v<const unsigned char>': The C++ Standard forbids
# containers of const elements because allocator<const T> is ill-formed.
'name': 'win_sandbox_policy',
},
{
# Windows: Always use the root window as the owner for shell dialogs.
# https://github.com/chromiumembedded/cef/issues/3294
@@ -625,6 +594,9 @@ patches = [
},
{
# Create top-level widget type when Widget::InitParams::child is false.
#
# Allow access to deprecated "owned by widget" model.
# https://github.com/chromiumembedded/cef/issues/3924
'name': 'ui_views_widget_type'
},
{
@@ -734,12 +706,6 @@ patches = [
# https://issues.chromium.org/issues/323753235#comment11
'name': 'content_initiator_policy_323753235'
},
{
# win: Fix undefined std::_Literal_zero_is_expected() when building
# cef_sandbox with VS 17.9.2 version of MSVC STL.
# https://github.com/chromiumembedded/cef/issues/3708
'name': 'win_sandbox_op3way_3708'
},
{
# Fix ThreadPool DCHECK during startup when using multi-threaded message
# loop. Related to the following CL:
@@ -781,5 +747,9 @@ patches = [
# builds.
# https://github.com/chromiumembedded/cef/issues/3892
'name': 'config_3892'
},
{
# Add |first| parameter to NavigationThrottleRegistry::AddThrottle.
'name': 'content_throttle_registry'
}
]

View File

@@ -1,5 +1,5 @@
diff --git base/command_line.cc base/command_line.cc
index d4d3bc52426d1..69d48fac6bbf4 100644
index 7491285cd14c9..90044eb1dddbd 100644
--- base/command_line.cc
+++ base/command_line.cc
@@ -421,11 +421,10 @@ void CommandLine::AppendSwitchNative(std::string_view switch_string,

View File

@@ -1,389 +0,0 @@
diff --git base/BUILD.gn base/BUILD.gn
index 57a6af0061615..d18a8a8a4559d 100644
--- base/BUILD.gn
+++ base/BUILD.gn
@@ -41,6 +41,7 @@ import("//build/rust/rust_static_library.gni")
import("//build/timestamp.gni")
import("//build/util/process_version.gni")
import("//build_overrides/build.gni")
+import("//cef/libcef/features/features.gni")
import("//testing/libfuzzer/fuzzer_test.gni")
import("//testing/test.gni")
@@ -1519,7 +1520,13 @@ component("base") {
"hash/md5_constexpr_internal.h",
"hash/sha1.h",
]
- if (is_nacl) {
+
+ deps += [ "//cef/libcef/features:buildflags" ]
+ if (enable_cef) {
+ configs += [ "//cef/libcef/features:config" ]
+ }
+
+ if (is_nacl || is_cef_sandbox_build) {
sources += [
"hash/md5_nacl.cc",
"hash/md5_nacl.h",
@@ -1969,6 +1976,12 @@ component("base") {
defines += [ "COM_INIT_CHECK_HOOK_DISABLED" ]
}
+ if (!use_custom_libcxx) {
+ # Enable the VS 2015 Update 2 fix when building with the MSVC standard
+ # library.
+ defines += [ "_ENABLE_ATOMIC_ALIGNMENT_FIX" ]
+ }
+
libs += [
"cfgmgr32.lib",
"ntdll.lib",
diff --git base/allocator/dispatcher/dispatcher.cc base/allocator/dispatcher/dispatcher.cc
index f680f63cffc5b..9cb615bbc8a5a 100644
--- base/allocator/dispatcher/dispatcher.cc
+++ base/allocator/dispatcher/dispatcher.cc
@@ -8,6 +8,7 @@
#include "base/check.h"
#include "base/dcheck_is_on.h"
#include "base/no_destructor.h"
+#include "cef/libcef/features/features.h"
#include "partition_alloc/buildflags.h"
#include "partition_alloc/shim/allocator_shim.h"
@@ -33,7 +34,7 @@ struct Dispatcher::Impl {
}
void Reset() {
-#if DCHECK_IS_ON()
+#if DCHECK_IS_ON() && !BUILDFLAG(IS_CEF_SANDBOX_BUILD)
DCHECK([&] {
auto const was_set = is_initialized_check_flag_.test_and_set();
is_initialized_check_flag_.clear();
diff --git base/hash/md5.h base/hash/md5.h
index 215d636fec275..922e88f31b999 100644
--- base/hash/md5.h
+++ base/hash/md5.h
@@ -11,8 +11,9 @@
#include "base/base_export.h"
#include "base/containers/span.h"
#include "build/build_config.h"
+#include "cef/libcef/features/features.h"
-#if BUILDFLAG(IS_NACL)
+#if BUILDFLAG(IS_NACL) || BUILDFLAG(IS_CEF_SANDBOX_BUILD)
#include "base/hash/md5_nacl.h"
#else
#include "base/hash/md5_boringssl.h"
diff --git base/hash/sha1.h base/hash/sha1.h
index 2158b648ca58a..8a8cb13b2fd74 100644
--- base/hash/sha1.h
+++ base/hash/sha1.h
@@ -15,7 +15,9 @@
#include "base/compiler_specific.h"
#include "base/containers/span.h"
#include "build/build_config.h"
-#if BUILDFLAG(IS_NACL)
+#include "cef/libcef/features/features.h"
+
+#if BUILDFLAG(IS_NACL) || BUILDFLAG(IS_CEF_SANDBOX_BUILD)
#include "base/hash/sha1_nacl.h"
#else
#include "base/hash/sha1_boringssl.h"
diff --git base/json/json_reader.cc base/json/json_reader.cc
index 48a9b893d3f9d..a5a2223b2a0fa 100644
--- base/json/json_reader.cc
+++ base/json/json_reader.cc
@@ -12,8 +12,9 @@
#include "base/logging.h"
#include "base/metrics/histogram_macros.h"
#include "build/build_config.h"
+#include "cef/libcef/features/features.h"
-#if !BUILDFLAG(IS_NACL)
+#if !(BUILDFLAG(IS_NACL) || BUILDFLAG(IS_CEF_SANDBOX_BUILD))
#include "base/strings/string_view_rust.h"
#include "third_party/rust/serde_json_lenient/v0_2/wrapper/functions.h"
#include "third_party/rust/serde_json_lenient/v0_2/wrapper/lib.rs.h"
@@ -21,7 +22,7 @@
// TODO(crbug.com/40811643): Move the C++ parser into components/nacl to just
// run in-process there. Don't compile base::JSONReader on NaCL at all.
-#if !BUILDFLAG(IS_NACL)
+#if !(BUILDFLAG(IS_NACL) || BUILDFLAG(IS_CEF_SANDBOX_BUILD))
namespace {
const char kSecurityJsonParsingTime[] = "Security.JSONParser.ParsingTime";
@@ -138,7 +139,7 @@ namespace base {
std::optional<Value> JSONReader::Read(std::string_view json,
int options,
size_t max_depth) {
-#if BUILDFLAG(IS_NACL)
+#if (BUILDFLAG(IS_NACL) || BUILDFLAG(IS_CEF_SANDBOX_BUILD))
internal::JSONParser parser(options, max_depth);
return parser.Parse(json);
#else // BUILDFLAG(IS_NACL)
@@ -183,7 +184,7 @@ std::optional<Value::List> JSONReader::ReadList(std::string_view json,
JSONReader::Result JSONReader::ReadAndReturnValueWithError(
std::string_view json,
int options) {
-#if BUILDFLAG(IS_NACL)
+#if (BUILDFLAG(IS_NACL) || BUILDFLAG(IS_CEF_SANDBOX_BUILD))
internal::JSONParser parser(options);
auto value = parser.Parse(json);
if (!value) {
@@ -224,7 +225,7 @@ bool JSONReader::UsingRust() {
if (!base::FeatureList::GetInstance()) {
return false;
}
-#if BUILDFLAG(IS_NACL)
+#if (BUILDFLAG(IS_NACL) || BUILDFLAG(IS_CEF_SANDBOX_BUILD))
return false;
#else
return base::FeatureList::IsEnabled(base::features::kUseRustJsonParser);
diff --git base/logging.cc base/logging.cc
index 26ba1a286e451..99b2ce6feb274 100644
--- base/logging.cc
+++ base/logging.cc
@@ -51,6 +51,7 @@
#include "base/trace_event/base_tracing.h"
#include "base/vlog.h"
#include "build/build_config.h"
+#include "cef/libcef/features/features.h"
#include "third_party/abseil-cpp/absl/base/internal/raw_logging.h"
#include "third_party/abseil-cpp/absl/cleanup/cleanup.h"
@@ -530,7 +531,7 @@ bool BaseInitLoggingImpl(const LoggingSettings& settings) {
}
#endif
-#if !BUILDFLAG(IS_NACL)
+#if !BUILDFLAG(IS_NACL) && !BUILDFLAG(IS_CEF_SANDBOX_BUILD)
// Connects Rust logging with the //base logging functionality.
internal::init_rust_log_crate();
#endif
diff --git base/metrics/crc32.cc base/metrics/crc32.cc
index 83e3cee2579ab..8238767ab9126 100644
--- base/metrics/crc32.cc
+++ base/metrics/crc32.cc
@@ -3,14 +3,15 @@
// found in the LICENSE file.
#include "base/metrics/crc32.h"
+#include "cef/libcef/features/features.h"
-#if !BUILDFLAG(IS_NACL)
+#if !BUILDFLAG(IS_NACL) && !BUILDFLAG(IS_CEF_SANDBOX_BUILD)
#include "third_party/zlib/zlib.h"
#endif // !BUILDFLAG(IS_NACL)
namespace base {
-#if !BUILDFLAG(IS_NACL)
+#if !BUILDFLAG(IS_NACL) && !BUILDFLAG(IS_CEF_SANDBOX_BUILD)
uint32_t Crc32(uint32_t sum, span<const uint8_t> data) {
if (data.empty()) {
return sum;
diff --git base/process/memory.h base/process/memory.h
index 5d11d4a1560b1..242a93bcca8ed 100644
--- base/process/memory.h
+++ base/process/memory.h
@@ -29,7 +29,7 @@ BASE_EXPORT void EnableTerminationOnOutOfMemory();
#if PA_BUILDFLAG(USE_PARTITION_ALLOC)
using partition_alloc::TerminateBecauseOutOfMemory;
#else
-inline void TerminateBecauseOutOfMemory(size_t) {
+[[noreturn]] inline void TerminateBecauseOutOfMemory(size_t) {
logging::RawCheckFailure("Out of memory");
}
#endif
@@ -58,7 +58,11 @@ bool ReleaseAddressSpaceReservation();
#if BUILDFLAG(IS_WIN)
namespace win {
+#if PA_BUILDFLAG(USE_PARTITION_ALLOC)
using partition_alloc::win::kOomExceptionCode;
+#else
+const DWORD kOomExceptionCode = 0xe0000008;
+#endif
} // namespace win
#endif
diff --git base/rand_util.h base/rand_util.h
index d650943a7b75a..abd5217f8ceed 100644
--- base/rand_util.h
+++ base/rand_util.h
@@ -23,8 +23,9 @@
#include "base/numerics/safe_conversions.h"
#include "base/time/time.h"
#include "build/build_config.h"
+#include "cef/libcef/features/features.h"
-#if !BUILDFLAG(IS_NACL)
+#if !BUILDFLAG(IS_NACL) && !BUILDFLAG(IS_CEF_SANDBOX_BUILD)
#include "third_party/boringssl/src/include/openssl/rand.h"
#endif
@@ -189,7 +190,7 @@ class RandomBitGenerator {
~RandomBitGenerator() = default;
};
-#if !BUILDFLAG(IS_NACL)
+#if !BUILDFLAG(IS_NACL) && !BUILDFLAG(IS_CEF_SANDBOX_BUILD)
class NonAllocatingRandomBitGenerator {
public:
using result_type = uint64_t;
diff --git base/rand_util_win.cc base/rand_util_win.cc
index 0b772cbae8916..b19183b34d176 100644
--- base/rand_util_win.cc
+++ base/rand_util_win.cc
@@ -15,7 +15,11 @@
#include "base/check.h"
#include "base/feature_list.h"
+#include "cef/libcef/features/features.h"
+
+#if !BUILDFLAG(IS_CEF_SANDBOX_BUILD)
#include "third_party/boringssl/src/include/openssl/rand.h"
+#endif
// Prototype for ProcessPrng.
// See: https://learn.microsoft.com/en-us/windows/win32/seccng/processprng
@@ -27,6 +31,7 @@ namespace base {
namespace internal {
+#if !BUILDFLAG(IS_CEF_SANDBOX_BUILD)
namespace {
// The BoringSSl helpers are duplicated in rand_util_fuchsia.cc and
@@ -48,6 +53,10 @@ bool UseBoringSSLForRandBytes() {
return g_use_boringssl.load(std::memory_order_relaxed);
}
+#else // !BUILDFLAG(IS_CEF_SANDBOX_BUILD)
+void ConfigureBoringSSLBackedRandBytesFieldTrial() {}
+#endif
+
} // namespace internal
namespace {
@@ -65,11 +74,13 @@ decltype(&ProcessPrng) GetProcessPrng() {
}
void RandBytesInternal(span<uint8_t> output, bool avoid_allocation) {
+#if !BUILDFLAG(IS_CEF_SANDBOX_BUILD)
if (!avoid_allocation && internal::UseBoringSSLForRandBytes()) {
// BoringSSL's RAND_bytes always returns 1. Any error aborts the program.
(void)RAND_bytes(output.data(), output.size());
return;
}
+#endif // !BUILDFLAG(IS_CEF_SANDBOX_BUILD)
static decltype(&ProcessPrng) process_prng_fn = GetProcessPrng();
BOOL success =
diff --git base/unguessable_token.cc base/unguessable_token.cc
index ea33ca66f384c..33f4cc76f76bd 100644
--- base/unguessable_token.cc
+++ base/unguessable_token.cc
@@ -11,8 +11,9 @@
#include "base/format_macros.h"
#include "base/rand_util.h"
#include "build/build_config.h"
+#include "cef/libcef/features/features.h"
-#if !BUILDFLAG(IS_NACL)
+#if !BUILDFLAG(IS_NACL) && !BUILDFLAG(IS_CEF_SANDBOX_BUILD)
#include "third_party/boringssl/src/include/openssl/mem.h"
#endif
@@ -58,7 +59,7 @@ std::optional<UnguessableToken> UnguessableToken::DeserializeFromString(
}
bool operator==(const UnguessableToken& lhs, const UnguessableToken& rhs) {
-#if BUILDFLAG(IS_NACL)
+#if BUILDFLAG(IS_NACL) || BUILDFLAG(IS_CEF_SANDBOX_BUILD)
// BoringSSL is unavailable for NaCl builds so it remains timing dependent.
return lhs.token_ == rhs.token_;
#else
diff --git base/win/sid.cc base/win/sid.cc
index 6a91e984f5161..4433591d96c99 100644
--- base/win/sid.cc
+++ base/win/sid.cc
@@ -29,12 +29,56 @@
#include "base/win/scoped_handle.h"
#include "base/win/scoped_localalloc.h"
#include "base/win/windows_version.h"
+#include "cef/libcef/features/features.h"
+
+#if !BUILDFLAG(IS_CEF_SANDBOX_BUILD)
#include "third_party/boringssl/src/include/openssl/sha.h"
+#else
+#include <wincrypt.h>
+#endif
namespace base::win {
namespace {
+#if BUILDFLAG(IS_CEF_SANDBOX_BUILD)
+
+#define SHA256_DIGEST_LENGTH 32
+
+bool SHA256(const uint8_t* InData, size_t InDataLen, uint8_t* OutHash) {
+ HCRYPTPROV hProv = 0;
+ HCRYPTHASH hHash = 0;
+
+ if (!CryptAcquireContext(&hProv, nullptr, nullptr, PROV_RSA_AES,
+ CRYPT_VERIFYCONTEXT)) {
+ return false;
+ }
+
+ if (!CryptCreateHash(hProv, CALG_SHA_256, 0, 0, &hHash)) {
+ CryptReleaseContext(hProv, 0);
+ return false;
+ }
+
+ if (!CryptHashData(hHash, InData, static_cast<DWORD>(InDataLen), 0)) {
+ CryptDestroyHash(hHash);
+ CryptReleaseContext(hProv, 0);
+ return false;
+ }
+
+ DWORD dwHashLen = SHA256_DIGEST_LENGTH;
+ if (!CryptGetHashParam(hHash, HP_HASHVAL, OutHash, &dwHashLen, 0)) {
+ CryptDestroyHash(hHash);
+ CryptReleaseContext(hProv, 0);
+ return false;
+ }
+
+ CryptDestroyHash(hHash);
+ CryptReleaseContext(hProv, 0);
+ return true;
+}
+
+#endif // BUILDFLAG(IS_CEF_SANDBOX_BUILD)
+
template <typename Iterator>
Sid FromSubAuthorities(const SID_IDENTIFIER_AUTHORITY& identifier_authority,
size_t sub_authority_count,
diff --git build_overrides/dawn.gni build_overrides/dawn.gni
index cec3df3e50b6e..309b4e6a4fe0d 100644
--- build_overrides/dawn.gni
+++ build_overrides/dawn.gni
@@ -2,11 +2,15 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
+import("//base/allocator/partition_allocator/partition_alloc.gni")
+
# The paths to Dawn's dependencies
dawn_angle_dir = "//third_party/angle"
dawn_glfw_dir = "//third_party/dawn/third_party/glfw"
dawn_googletest_dir = "//third_party/googletest/src"
-dawn_partition_alloc_dir = "//base/allocator/partition_allocator"
+if (use_partition_alloc) {
+ dawn_partition_alloc_dir = "//base/allocator/partition_allocator"
+}
dawn_jinja2_dir = "//third_party/jinja2"
dawn_jsoncpp_dir = "//third_party/jsoncpp"
dawn_spirv_tools_dir = "//third_party/spirv-tools/src"

View File

@@ -1,10 +1,10 @@
diff --git base/test/BUILD.gn base/test/BUILD.gn
index 5beef03e5fd94..0b12fd3afc8fc 100644
index 5c286d8d8f664..1ea302897d823 100644
--- base/test/BUILD.gn
+++ base/test/BUILD.gn
@@ -212,11 +212,6 @@ static_library("test_support") {
if (enable_base_tracing) {
@@ -216,11 +216,6 @@ static_library("test_support") {
# that would require special support in gn2bp (AOSP Cronet).
if (enable_base_tracing && !is_cronet_build) {
public_deps += [ "//third_party/perfetto:perfetto_test_support" ]
- public_deps += [ ":test_trace_processor" ]
- sources += [
@@ -14,7 +14,7 @@ index 5beef03e5fd94..0b12fd3afc8fc 100644
deps += [
":amalgamated_perfetto_sql_stdlib",
":gen_cc_chrome_track_event_descriptor",
@@ -611,7 +606,7 @@ if (enable_base_tracing) {
@@ -615,7 +610,7 @@ if (enable_base_tracing) {
# processor depends on dev_sqlite. The two share the same symbols but have
# different implementations, so we need to hide dev_sqlite in this shared
# library even in non-component builds to prevent duplicate symbols.
@@ -23,7 +23,7 @@ index 5beef03e5fd94..0b12fd3afc8fc 100644
if (is_ios) {
_target_type = "ios_framework_bundle"
}
@@ -620,6 +615,8 @@ if (enable_base_tracing) {
@@ -624,6 +619,8 @@ if (enable_base_tracing) {
defines = [ "TEST_TRACE_PROCESSOR_IMPL" ]
testonly = true
sources = [
@@ -32,7 +32,7 @@ index 5beef03e5fd94..0b12fd3afc8fc 100644
"test_trace_processor_export.h",
"test_trace_processor_impl.cc",
"test_trace_processor_impl.h",
@@ -637,33 +634,6 @@ if (enable_base_tracing) {
@@ -641,33 +638,6 @@ if (enable_base_tracing) {
output_name = "TestTraceProcessor"
bundle_deps_filter = [ "//third_party/icu:icudata" ]
}
@@ -67,7 +67,7 @@ index 5beef03e5fd94..0b12fd3afc8fc 100644
} else if (!is_component_build && is_mac) {
# Provide a dummy target in order for clients to not have to special-case
diff --git base/test/test_trace_processor_export.h base/test/test_trace_processor_export.h
index f5191b804bc07..aadb7d66ba4c3 100644
index 94b5a2ab1e751..6dacffae228ef 100644
--- base/test/test_trace_processor_export.h
+++ base/test/test_trace_processor_export.h
@@ -5,6 +5,7 @@
@@ -78,8 +78,8 @@ index f5191b804bc07..aadb7d66ba4c3 100644
#if defined(WIN32)
#if defined(TEST_TRACE_PROCESSOR_IMPL)
@@ -23,4 +24,8 @@
@@ -17,4 +18,8 @@
#define TEST_TRACE_PROCESSOR_EXPORT __attribute__((visibility("default")))
#endif // defined(WIN32)
+#else // defined(COMPONENT_BUILD)
@@ -88,10 +88,10 @@ index f5191b804bc07..aadb7d66ba4c3 100644
+
#endif // BASE_TEST_TEST_TRACE_PROCESSOR_EXPORT_H_
diff --git content/shell/BUILD.gn content/shell/BUILD.gn
index f4288459097cd..c48696020414c 100644
index d257dbbb2e6f4..886c8e8bc05d7 100644
--- content/shell/BUILD.gn
+++ content/shell/BUILD.gn
@@ -926,7 +926,6 @@ if (is_mac) {
@@ -934,7 +934,6 @@ if (is_mac) {
# Specify a sensible install_name for static builds. The library is
# dlopen()ed so this is not used to resolve the module.
ldflags = [ "-Wl,-install_name,@executable_path/../Frameworks/$output_name.framework/$output_name" ]

View File

@@ -1,8 +1,8 @@
diff --git base/task/thread_pool/thread_pool_impl.cc base/task/thread_pool/thread_pool_impl.cc
index d7f9c33417f64..a6561d3dad060 100644
index e3f1345ac8f1b..e38404995b8bd 100644
--- base/task/thread_pool/thread_pool_impl.cc
+++ base/task/thread_pool/thread_pool_impl.cc
@@ -108,6 +108,10 @@ ThreadPoolImpl::ThreadPoolImpl(std::string_view histogram_label,
@@ -109,6 +109,10 @@ ThreadPoolImpl::ThreadPoolImpl(std::string_view histogram_label,
ThreadGroupType::BACKGROUND, task_tracker_->GetTrackedRef(),
tracked_ref_factory_.GetTrackedRef());
}

View File

@@ -1,8 +1,8 @@
diff --git third_party/blink/public/web/web_element.h third_party/blink/public/web/web_element.h
index 1547a5ee8178c..e3bc0e82b1c66 100644
index 75e28e8088848..9abea1a35f11b 100644
--- third_party/blink/public/web/web_element.h
+++ third_party/blink/public/web/web_element.h
@@ -81,6 +81,9 @@ class BLINK_EXPORT WebElement : public WebNode {
@@ -83,6 +83,9 @@ class BLINK_EXPORT WebElement : public WebNode {
WebString TextContent() const;
WebString TextContentAbridged(unsigned int max_length) const;
WebString InnerHTML() const;
@@ -10,13 +10,13 @@ index 1547a5ee8178c..e3bc0e82b1c66 100644
+ WebString AttributeValue(unsigned index) const;
+ unsigned AttributeCount() const;
// Returns true if the element's computed writing suggestions value is true.
// https://html.spec.whatwg.org/#writing-suggestions:computed-writing-suggestions-value
void Focus();
diff --git third_party/blink/renderer/core/exported/web_element.cc third_party/blink/renderer/core/exported/web_element.cc
index 8baa5193bfbe0..98c3b930a0498 100644
index 6859e192048d3..2b14176b6aa0d 100644
--- third_party/blink/renderer/core/exported/web_element.cc
+++ third_party/blink/renderer/core/exported/web_element.cc
@@ -119,6 +119,24 @@ void WebElement::SetAttribute(const WebString& attr_name,
@@ -124,6 +124,24 @@ void WebElement::SetAttribute(const WebString& attr_name,
IGNORE_EXCEPTION_FOR_TESTING);
}

View File

@@ -1,8 +1,8 @@
diff --git content/browser/child_process_security_policy_impl.cc content/browser/child_process_security_policy_impl.cc
index 53a73d6c75b7a..05290de4c03a0 100644
index 4316d8b8bc09d..d6927a4e71460 100644
--- content/browser/child_process_security_policy_impl.cc
+++ content/browser/child_process_security_policy_impl.cc
@@ -2146,6 +2146,16 @@ bool ChildProcessSecurityPolicyImpl::PerformJailAndCitadelChecks(
@@ -2145,6 +2145,16 @@ bool ChildProcessSecurityPolicyImpl::PerformJailAndCitadelChecks(
if (actual_process_lock.matches_scheme(url::kDataScheme)) {
return true;
}
@@ -20,53 +20,79 @@ index 53a73d6c75b7a..05290de4c03a0 100644
// Make an exception to allow most visited tiles to commit in third-party
diff --git content/browser/renderer_host/navigation_request.cc content/browser/renderer_host/navigation_request.cc
index 29740121f1371..97e4e6b0bcd29 100644
index 32affd3a936bd..9d0723139658c 100644
--- content/browser/renderer_host/navigation_request.cc
+++ content/browser/renderer_host/navigation_request.cc
@@ -8499,10 +8499,22 @@ NavigationRequest::GetOriginForURLLoaderFactoryBeforeResponseWithDebugInfo(
@@ -8601,7 +8601,8 @@ std::optional<url::Origin> NavigationRequest::GetOriginToCommit() {
}
url::Origin NavigationRequest::GetOriginForURLLoaderFactoryBeforeResponse(
- network::mojom::WebSandboxFlags sandbox_flags) {
+ network::mojom::WebSandboxFlags sandbox_flags,
+ bool* cef_nonstandard) {
// Calculate an approximation of the origin. The sandbox/csp are ignored.
url::Origin origin = GetOriginForURLLoaderFactoryUnchecked();
@@ -8618,6 +8619,17 @@ url::Origin NavigationRequest::GetOriginForURLLoaderFactoryBeforeResponse(
bool use_opaque_origin =
(sandbox_flags & network::mojom::WebSandboxFlags::kOrigin) ==
network::mojom::WebSandboxFlags::kOrigin;
+ if (use_opaque_origin) {
+ origin_and_debug_info.second += ", sandbox_flags";
+ }
+
+ if (!origin_and_debug_info.first.GetURL().IsStandard()) {
+ if (!origin.GetURL().IsStandard()) {
+ // Always return an opaque origin for non-standard URLs. Otherwise, the
+ // CanAccessDataForOrigin() check may fail for unregistered custom scheme
+ // requests in CEF.
+ // CanAccessDataForOrigin() check may fail for unregistered custom
+ // scheme requests in CEF.
+ use_opaque_origin = true;
+ origin_and_debug_info.second += ", cef_nonstandard";
+ if (cef_nonstandard) {
+ *cef_nonstandard = true;
+ }
+ }
+
if (use_opaque_origin) {
origin_and_debug_info =
std::pair(origin_and_debug_info.first.DeriveNewOpaqueOrigin(),
- origin_and_debug_info.second + ", sandbox_flags");
+ origin_and_debug_info.second);
origin = origin.DeriveNewOpaqueOrigin();
}
@@ -8677,8 +8689,9 @@ NavigationRequest::GetOriginForURLLoaderFactoryAfterResponse() {
return GetRenderFrameHost()->GetLastCommittedOrigin();
}
return origin_and_debug_info;
@@ -8610,11 +8622,20 @@ NavigationRequest::GetOriginForURLLoaderFactoryAfterResponseWithDebugInfo() {
- url::Origin origin =
- GetOriginForURLLoaderFactoryBeforeResponse(SandboxFlagsToCommit());
+ bool cef_nonstandard = false;
+ url::Origin origin = GetOriginForURLLoaderFactoryBeforeResponse(
+ SandboxFlagsToCommit(), &cef_nonstandard);
SCOPED_CRASH_KEY_BOOL("Bug1454273", "is_in_main_frame", IsInMainFrame());
SCOPED_CRASH_KEY_STRING256(
@@ -8713,10 +8726,17 @@ NavigationRequest::GetOriginForURLLoaderFactoryAfterResponse() {
DetermineInitiatorRelationship(initiator_rfh,
frame_tree_node_->current_frame_host()));
+ if (origin_with_debug_info.first.opaque() &&
+ origin_with_debug_info.second.find("cef_nonstandard") !=
+ std::string::npos) {
+ if (origin.opaque() && cef_nonstandard) {
+ // Always return an opaque origin for non-standard URLs. Otherwise, the
+ // below CanAccessDataForOrigin() check may fail for unregistered custom
+ // scheme requests in CEF.
+ return origin_with_debug_info;
+ // below CanAccessOrigin() check may fail for unregistered custom scheme
+ // requests in CEF.
+ return origin;
+ }
+
// MHTML documents should commit as an opaque origin. They should not be able
// to make network request on behalf of the real origin.
// TODO(crbug.com/370979008): Migrate to CHECK.
- DUMP_WILL_BE_CHECK(!IsMhtmlOrSubframe() ||
- origin_with_debug_info.first.opaque());
+ // DUMP_WILL_BE_CHECK(!IsMhtmlOrSubframe() ||
+ // origin_with_debug_info.first.opaque());
- DUMP_WILL_BE_CHECK(!IsMhtmlOrSubframe() || origin.opaque());
+ // DUMP_WILL_BE_CHECK(!IsMhtmlOrSubframe() || origin.opaque());
// If the target of this navigation will be rendered in a RenderFrameHost,
// then verify that the chosen origin is allowed to be accessed from that
diff --git content/browser/renderer_host/navigation_request.h content/browser/renderer_host/navigation_request.h
index 70321378be68d..b60791ca6bb88 100644
--- content/browser/renderer_host/navigation_request.h
+++ content/browser/renderer_host/navigation_request.h
@@ -2311,7 +2311,8 @@ class CONTENT_EXPORT NavigationRequest
// situations where the final frame host hasn't been determined but the origin
// is needed to create URLLoaderFactory.
url::Origin GetOriginForURLLoaderFactoryBeforeResponse(
- network::mojom::WebSandboxFlags sandbox_flags);
+ network::mojom::WebSandboxFlags sandbox_flags,
+ bool* cef_nonstandard = nullptr);
// Superset of GetOriginForURLLoaderFactoryBeforeResponse(). Calculates
// the origin with information from the final frame host. Can be called only

View File

@@ -1,30 +0,0 @@
diff --git build/config/compiler/BUILD.gn build/config/compiler/BUILD.gn
index e7a60d56b5425..e9a4a4eb91ce8 100644
--- build/config/compiler/BUILD.gn
+++ build/config/compiler/BUILD.gn
@@ -131,6 +131,9 @@ declare_args() {
# The cache can lead to non-determinism: https://crbug.com/1486045
thin_lto_enable_cache = true
+ # Whether to use thin archives in combination with lld.
+ use_thin_archives = use_lld
+
# Initialize all local variables with a pattern. This flag will fill
# uninitialized floating-point types (and 32-bit pointers) with 0xFF and the
# rest with 0xAA. This makes behavior of uninitialized memory bugs consistent,
@@ -2326,6 +2329,7 @@ config("export_dynamic") {
# 2. Remove the thin_archive config, so that the .a file actually contains all
# .o files, instead of just references to .o files in the build directoy
config("thin_archive") {
+ if (use_thin_archives) {
if ((is_apple && use_lld) || (is_linux && !is_clang) || current_os == "aix") {
# The macOS and iOS linker ld64.ldd doesn't support thin archive without
# symbol table, gcc on linux also throws the error `archive has no index`.
@@ -2344,6 +2348,7 @@ config("thin_archive") {
} else if (is_win && use_lld) {
arflags = [ "/llvmlibthin" ]
}
+ }
}
# exceptions -------------------------------------------------------------------

View File

@@ -1,5 +1,5 @@
diff --git chrome/browser/BUILD.gn chrome/browser/BUILD.gn
index b5783087429ee..32b59c28e40bd 100644
index d4f8a4fc16463..ae8beed827a9e 100644
--- chrome/browser/BUILD.gn
+++ chrome/browser/BUILD.gn
@@ -11,6 +11,7 @@ import("//build/config/compiler/pgo/pgo.gni")
@@ -9,8 +9,8 @@ index b5783087429ee..32b59c28e40bd 100644
+import("//cef/libcef/features/features.gni")
import("//chrome/browser/buildflags.gni")
import("//chrome/browser/downgrade/buildflags.gni")
import("//chrome/browser/request_header_integrity/buildflags.gni")
@@ -1884,6 +1885,7 @@ static_library("browser") {
import("//chrome/common/features.gni")
@@ -1894,6 +1895,7 @@ static_library("browser") {
"//build/config/compiler:compiler_buildflags",
"//build/config/linux/dbus:buildflags",
"//cc",
@@ -18,7 +18,7 @@ index b5783087429ee..32b59c28e40bd 100644
"//chrome:extra_resources",
"//chrome:resources",
"//chrome:strings",
@@ -2583,6 +2585,10 @@ static_library("browser") {
@@ -2624,6 +2626,10 @@ static_library("browser") {
sources += [ "net/net_error_diagnostics_dialog_stub.cc" ]
}

View File

@@ -13,7 +13,7 @@ index 7603c2662b8dc..9a38d816bdc40 100644
return false;
}
diff --git chrome/browser/devtools/devtools_window.cc chrome/browser/devtools/devtools_window.cc
index 8e0717f34f37f..df852d4b2e69f 100644
index e8fda706fb348..c98ef9e3f6f4d 100644
--- chrome/browser/devtools/devtools_window.cc
+++ chrome/browser/devtools/devtools_window.cc
@@ -38,6 +38,7 @@
@@ -24,7 +24,7 @@ index 8e0717f34f37f..df852d4b2e69f 100644
#include "chrome/browser/ui/prefs/prefs_tab_helper.h"
#include "chrome/browser/ui/scoped_tabbed_browser_displayer.h"
#include "chrome/browser/ui/tabs/tab_strip_user_gesture_details.h"
@@ -1205,6 +1206,13 @@ DevToolsWindow* DevToolsWindow::Create(
@@ -1249,6 +1250,13 @@ DevToolsWindow* DevToolsWindow::Create(
if (!browser || !browser->is_type_normal()) {
can_dock = false;
}
@@ -38,7 +38,7 @@ index 8e0717f34f37f..df852d4b2e69f 100644
}
#endif
@@ -1646,7 +1654,9 @@ void DevToolsWindow::OpenInNewTab(const GURL& url) {
@@ -1713,7 +1721,9 @@ void DevToolsWindow::OpenInNewTab(const GURL& url) {
/*navigation_handle_callback=*/{})) {
#if BUILDFLAG(IS_ANDROID)
NOTIMPLEMENTED();
@@ -49,7 +49,7 @@ index 8e0717f34f37f..df852d4b2e69f 100644
chrome::ScopedTabbedBrowserDisplayer displayer(profile_);
chrome::AddSelectedTabWithURL(displayer.browser(), fixed_url,
ui::PAGE_TRANSITION_LINK);
@@ -1827,12 +1837,26 @@ void DevToolsWindow::CreateDevToolsBrowser() {
@@ -1900,12 +1910,26 @@ void DevToolsWindow::CreateDevToolsBrowser() {
Browser::CreationStatus::kOk) {
return;
}
@@ -83,7 +83,7 @@ index 8e0717f34f37f..df852d4b2e69f 100644
OverrideAndSyncDevToolsRendererPrefs();
}
diff --git chrome/browser/ui/BUILD.gn chrome/browser/ui/BUILD.gn
index ba0cba1897577..82bb0ac855dc2 100644
index 13941994fd5df..831c19f2fa275 100644
--- chrome/browser/ui/BUILD.gn
+++ chrome/browser/ui/BUILD.gn
@@ -7,6 +7,7 @@ import("//build/config/compiler/compiler.gni")
@@ -94,7 +94,7 @@ index ba0cba1897577..82bb0ac855dc2 100644
import("//chrome/browser/buildflags.gni")
import("//chrome/common/features.gni")
import("//chromeos/ash/components/assistant/assistant.gni")
@@ -302,6 +303,10 @@ static_library("ui") {
@@ -281,6 +282,10 @@ static_library("ui") {
"//build/config/compiler:wexit_time_destructors",
]
@@ -105,7 +105,7 @@ index ba0cba1897577..82bb0ac855dc2 100644
public_deps = [
# WARNING WARNING WARNING
# New dependencies outside of //chrome/browser should be added to
@@ -329,6 +334,7 @@ static_library("ui") {
@@ -308,6 +313,7 @@ static_library("ui") {
"//build/config/chromebox_for_meetings:buildflags",
"//build/config/linux/dbus:buildflags",
"//cc/paint",
@@ -113,7 +113,7 @@ index ba0cba1897577..82bb0ac855dc2 100644
"//chrome:resources",
"//chrome:strings",
"//chrome/app:chrome_dll_resources",
@@ -704,6 +710,13 @@ static_library("ui") {
@@ -687,6 +693,13 @@ static_library("ui") {
deps += [ "//components/plus_addresses/resources:vector_icons" ]
}
@@ -127,7 +127,7 @@ index ba0cba1897577..82bb0ac855dc2 100644
# TODO(crbug.com/41437292): Remove this circular dependency.
# Any circular includes must depend on the target "//chrome/browser:browser_public_dependencies".
# These are all-platform circular includes.
@@ -5504,6 +5517,7 @@ static_library("ui") {
@@ -5506,6 +5519,7 @@ static_library("ui") {
if (enable_printing) {
deps += [
"//components/printing/browser",
@@ -136,10 +136,10 @@ index ba0cba1897577..82bb0ac855dc2 100644
]
}
diff --git chrome/browser/ui/browser.cc chrome/browser/ui/browser.cc
index d45f8f1713c87..7d69f3d8bd4cc 100644
index 8c5e577eb89cf..9e18f03f0c8da 100644
--- chrome/browser/ui/browser.cc
+++ chrome/browser/ui/browser.cc
@@ -272,6 +272,25 @@
@@ -279,6 +279,25 @@
#include "components/captive_portal/content/captive_portal_tab_helper.h"
#endif
@@ -165,7 +165,7 @@ index d45f8f1713c87..7d69f3d8bd4cc 100644
#if BUILDFLAG(ENABLE_EXTENSIONS)
#include "chrome/browser/extensions/extension_browser_window_helper.h"
#endif
@@ -571,6 +590,10 @@ Browser::Browser(const CreateParams& params)
@@ -627,6 +646,10 @@ Browser::Browser(const CreateParams& params)
type_(params.type),
profile_(params.profile),
window_(nullptr),
@@ -176,7 +176,7 @@ index d45f8f1713c87..7d69f3d8bd4cc 100644
tab_strip_model_delegate_(
std::make_unique<chrome::BrowserTabStripModelDelegate>(this)),
tab_strip_model_(std::make_unique<TabStripModel>(
@@ -818,6 +841,12 @@ Browser::~Browser() {
@@ -864,6 +887,12 @@ Browser::~Browser() {
if (select_file_dialog_.get()) {
select_file_dialog_->ListenerDestroyed();
}
@@ -189,7 +189,7 @@ index d45f8f1713c87..7d69f3d8bd4cc 100644
}
///////////////////////////////////////////////////////////////////////////////
@@ -1275,6 +1304,10 @@ BrowserWindowInterface::Type Browser::GetType() const {
@@ -1336,6 +1365,10 @@ BrowserWindowInterface::Type Browser::GetType() const {
return type_;
}
@@ -200,7 +200,7 @@ index d45f8f1713c87..7d69f3d8bd4cc 100644
BrowserUserEducationInterface* Browser::GetUserEducationInterface() {
return window();
}
@@ -1436,6 +1469,8 @@ void Browser::WindowFullscreenStateChanged() {
@@ -1522,6 +1555,8 @@ void Browser::WindowFullscreenStateChanged() {
->WindowFullscreenStateChanged();
command_controller_->FullscreenStateChanged();
UpdateBookmarkBarState(BOOKMARK_BAR_STATE_CHANGE_TOGGLE_FULLSCREEN);
@@ -209,7 +209,7 @@ index d45f8f1713c87..7d69f3d8bd4cc 100644
}
void Browser::FullscreenTopUIStateChanged() {
@@ -1807,6 +1842,15 @@ content::KeyboardEventProcessingResult Browser::PreHandleKeyboardEvent(
@@ -1905,6 +1940,15 @@ content::KeyboardEventProcessingResult Browser::PreHandleKeyboardEvent(
return content::KeyboardEventProcessingResult::HANDLED;
}
@@ -225,7 +225,7 @@ index d45f8f1713c87..7d69f3d8bd4cc 100644
return window()->PreHandleKeyboardEvent(event);
}
@@ -1814,8 +1858,18 @@ bool Browser::HandleKeyboardEvent(content::WebContents* source,
@@ -1912,8 +1956,18 @@ bool Browser::HandleKeyboardEvent(content::WebContents* source,
const NativeWebKeyboardEvent& event) {
DevToolsWindow* devtools_window =
DevToolsWindow::GetInstanceForInspectedWebContents(source);
@@ -246,7 +246,7 @@ index d45f8f1713c87..7d69f3d8bd4cc 100644
}
bool Browser::TabsNeedBeforeUnloadFired() const {
@@ -1910,9 +1964,14 @@ bool Browser::IsBackForwardCacheSupported(content::WebContents& web_contents) {
@@ -2008,9 +2062,14 @@ bool Browser::IsBackForwardCacheSupported(content::WebContents& web_contents) {
content::PreloadingEligibility Browser::IsPrerender2Supported(
content::WebContents& web_contents,
content::PreloadingTriggerType trigger_type) {
@@ -261,7 +261,7 @@ index d45f8f1713c87..7d69f3d8bd4cc 100644
}
bool Browser::ShouldShowStaleContentOnEviction(content::WebContents* source) {
@@ -1975,6 +2034,14 @@ WebContents* Browser::OpenURLFromTab(
@@ -2073,6 +2132,14 @@ WebContents* Browser::OpenURLFromTab(
std::move(navigation_handle_callback));
}
@@ -276,7 +276,7 @@ index d45f8f1713c87..7d69f3d8bd4cc 100644
NavigateParams nav_params(this, params.url, params.transition);
nav_params.FillNavigateParamsFromOpenURLParams(params);
nav_params.source_contents = source;
@@ -2148,6 +2215,8 @@ void Browser::LoadingStateChanged(WebContents* source,
@@ -2246,6 +2313,8 @@ void Browser::LoadingStateChanged(WebContents* source,
bool should_show_loading_ui) {
ScheduleUIUpdate(source, content::INVALIDATE_TYPE_LOAD);
UpdateWindowForLoadingStateChanged(source, should_show_loading_ui);
@@ -285,7 +285,21 @@ index d45f8f1713c87..7d69f3d8bd4cc 100644
}
void Browser::CloseContents(WebContents* source) {
@@ -2177,6 +2246,8 @@ void Browser::SetContentsBounds(WebContents* source, const gfx::Rect& bounds) {
@@ -2255,6 +2324,13 @@ void Browser::CloseContents(WebContents* source) {
}
void Browser::SetContentsBounds(WebContents* source, const gfx::Rect& bounds) {
+#if BUILDFLAG(ENABLE_CEF)
+ if (cef_browser_delegate_ &&
+ cef_browser_delegate_->SetContentsBoundsEx(source, bounds)) {
+ return;
+ }
+#endif
+
if (is_type_normal()) {
return;
}
@@ -2275,6 +2351,8 @@ void Browser::SetContentsBounds(WebContents* source, const gfx::Rect& bounds) {
}
void Browser::UpdateTargetURL(WebContents* source, const GURL& url) {
@@ -294,7 +308,7 @@ index d45f8f1713c87..7d69f3d8bd4cc 100644
std::vector<StatusBubble*> status_bubbles = GetStatusBubbles();
for (StatusBubble* status_bubble : status_bubbles) {
StatusBubbleViews* status_bubble_views =
@@ -2190,6 +2261,17 @@ void Browser::UpdateTargetURL(WebContents* source, const GURL& url) {
@@ -2288,6 +2366,17 @@ void Browser::UpdateTargetURL(WebContents* source, const GURL& url) {
}
}
@@ -312,7 +326,7 @@ index d45f8f1713c87..7d69f3d8bd4cc 100644
void Browser::ContentsMouseEvent(WebContents* source, const ui::Event& event) {
const ui::EventType type = event.type();
const bool exited = type == ui::EventType::kMouseExited;
@@ -2223,9 +2305,23 @@ void Browser::ContentsZoomChange(bool zoom_in) {
@@ -2321,9 +2410,23 @@ void Browser::ContentsZoomChange(bool zoom_in) {
}
bool Browser::TakeFocus(content::WebContents* source, bool reverse) {
@@ -336,7 +350,7 @@ index d45f8f1713c87..7d69f3d8bd4cc 100644
void Browser::BeforeUnloadFired(WebContents* web_contents,
bool proceed,
bool* proceed_to_fire_unload) {
@@ -2338,12 +2434,24 @@ void Browser::WebContentsCreated(WebContents* source_contents,
@@ -2466,12 +2569,24 @@ void Browser::WebContentsCreated(WebContents* source_contents,
// to track `new_contents` after it is added to its TabModel this override can
// be removed.
CreateSessionServiceTabHelper(new_contents);
@@ -361,7 +375,7 @@ index d45f8f1713c87..7d69f3d8bd4cc 100644
// Don't show the page hung dialog when a HTML popup hangs because
// the dialog will take the focus and immediately close the popup.
RenderWidgetHostView* view = render_widget_host->GetView();
@@ -2356,6 +2464,13 @@ void Browser::RendererUnresponsive(
@@ -2484,6 +2599,13 @@ void Browser::RendererUnresponsive(
void Browser::RendererResponsive(
WebContents* source,
content::RenderWidgetHost* render_widget_host) {
@@ -375,7 +389,7 @@ index d45f8f1713c87..7d69f3d8bd4cc 100644
RenderWidgetHostView* view = render_widget_host->GetView();
if (view && !render_widget_host->GetView()->IsHTMLFormPopup()) {
TabDialogs::FromWebContents(source)->HideHungRendererDialog(
@@ -2365,6 +2480,15 @@ void Browser::RendererResponsive(
@@ -2493,6 +2615,15 @@ void Browser::RendererResponsive(
content::JavaScriptDialogManager* Browser::GetJavaScriptDialogManager(
WebContents* source) {
@@ -391,7 +405,7 @@ index d45f8f1713c87..7d69f3d8bd4cc 100644
return javascript_dialogs::TabModalDialogManager::FromWebContents(source);
}
@@ -2400,6 +2524,11 @@ void Browser::DraggableRegionsChanged(
@@ -2528,6 +2659,11 @@ void Browser::DraggableRegionsChanged(
if (app_controller_) {
app_controller_->DraggableRegionsChanged(regions, contents);
}
@@ -403,7 +417,7 @@ index d45f8f1713c87..7d69f3d8bd4cc 100644
}
std::vector<blink::mojom::RelatedApplicationPtr>
@@ -2514,11 +2643,15 @@ void Browser::EnterFullscreenModeForTab(
@@ -2642,11 +2778,15 @@ void Browser::EnterFullscreenModeForTab(
const blink::mojom::FullscreenOptions& options) {
exclusive_access_manager_->fullscreen_controller()->EnterFullscreenModeForTab(
requesting_frame, options.display_id);
@@ -419,7 +433,7 @@ index d45f8f1713c87..7d69f3d8bd4cc 100644
}
bool Browser::IsFullscreenForTabOrPending(const WebContents* web_contents) {
@@ -2728,6 +2861,16 @@ void Browser::RequestMediaAccessPermission(
@@ -2857,6 +2997,16 @@ void Browser::RequestMediaAccessPermission(
content::WebContents* web_contents,
const content::MediaStreamRequest& request,
content::MediaResponseCallback callback) {
@@ -436,7 +450,7 @@ index d45f8f1713c87..7d69f3d8bd4cc 100644
const extensions::Extension* extension =
GetExtensionForOrigin(profile_, request.security_origin);
MediaCaptureDevicesDispatcher::GetInstance()->ProcessMediaAccessRequest(
@@ -3313,9 +3456,11 @@ void Browser::RemoveScheduledUpdatesFor(WebContents* contents) {
@@ -3447,9 +3597,11 @@ void Browser::RemoveScheduledUpdatesFor(WebContents* contents) {
// Browser, Getters for UI (private):
std::vector<StatusBubble*> Browser::GetStatusBubbles() {
@@ -449,7 +463,7 @@ index d45f8f1713c87..7d69f3d8bd4cc 100644
}
// We hide the status bar for web apps windows as this matches native
@@ -3323,6 +3468,12 @@ std::vector<StatusBubble*> Browser::GetStatusBubbles() {
@@ -3457,6 +3609,12 @@ std::vector<StatusBubble*> Browser::GetStatusBubbles() {
// mode, as the minimal browser UI includes the status bar.
if (web_app::AppBrowserController::IsWebApp(this) &&
!app_controller()->HasMinimalUiButtons()) {
@@ -462,7 +476,7 @@ index d45f8f1713c87..7d69f3d8bd4cc 100644
return {};
}
@@ -3476,6 +3627,8 @@ void Browser::SetAsDelegate(WebContents* web_contents, bool set_delegate) {
@@ -3610,6 +3768,8 @@ void Browser::SetAsDelegate(WebContents* web_contents, bool set_delegate) {
BookmarkTabHelper::FromWebContents(web_contents)->RemoveObserver(this);
web_contents_collection_.StopObserving(web_contents);
}
@@ -471,7 +485,7 @@ index d45f8f1713c87..7d69f3d8bd4cc 100644
}
void Browser::TabDetachedAtImpl(content::WebContents* contents,
@@ -3637,6 +3790,14 @@ bool Browser::PictureInPictureBrowserSupportsWindowFeature(
@@ -3771,6 +3931,14 @@ bool Browser::PictureInPictureBrowserSupportsWindowFeature(
bool Browser::SupportsWindowFeatureImpl(WindowFeature feature,
bool check_can_support) const {
@@ -487,7 +501,7 @@ index d45f8f1713c87..7d69f3d8bd4cc 100644
case TYPE_NORMAL:
return NormalBrowserSupportsWindowFeature(feature, check_can_support);
diff --git chrome/browser/ui/browser.h chrome/browser/ui/browser.h
index ce1e404e45a60..7193496de6b31 100644
index 1de7f9596b2f8..9dba7bad5931b 100644
--- chrome/browser/ui/browser.h
+++ chrome/browser/ui/browser.h
@@ -24,6 +24,7 @@
@@ -509,7 +523,7 @@ index ce1e404e45a60..7193496de6b31 100644
#if BUILDFLAG(IS_ANDROID)
#error This file should only be included on desktop.
#endif
@@ -351,6 +356,15 @@ class Browser : public TabStripModelObserver,
@@ -350,6 +355,15 @@ class Browser : public TabStripModelObserver,
// Document Picture in Picture options, specific to TYPE_PICTURE_IN_PICTURE.
std::optional<blink::mojom::PictureInPictureWindowOptions> pip_options;
@@ -525,7 +539,7 @@ index ce1e404e45a60..7193496de6b31 100644
private:
friend class Browser;
friend class WindowSizerChromeOSTest;
@@ -434,6 +448,13 @@ class Browser : public TabStripModelObserver,
@@ -433,6 +447,13 @@ class Browser : public TabStripModelObserver,
update_ui_immediately_for_testing_ = true;
}
@@ -539,7 +553,7 @@ index ce1e404e45a60..7193496de6b31 100644
// Accessors ////////////////////////////////////////////////////////////////
const CreateParams& create_params() const { return create_params_; }
@@ -535,6 +556,12 @@ class Browser : public TabStripModelObserver,
@@ -526,6 +547,12 @@ class Browser : public TabStripModelObserver,
base::WeakPtr<Browser> AsWeakPtr();
base::WeakPtr<const Browser> AsWeakPtr() const;
@@ -552,7 +566,7 @@ index ce1e404e45a60..7193496de6b31 100644
// Get the FindBarController for this browser, creating it if it does not
// yet exist.
FindBarController* GetFindBarController();
@@ -889,6 +916,7 @@ class Browser : public TabStripModelObserver,
@@ -886,6 +913,7 @@ class Browser : public TabStripModelObserver,
ImmersiveModeController* GetImmersiveModeController() override;
BrowserActions* GetActions() override;
Type GetType() const override;
@@ -560,7 +574,7 @@ index ce1e404e45a60..7193496de6b31 100644
BrowserUserEducationInterface* GetUserEducationInterface() override;
web_app::AppBrowserController* GetAppBrowserController() override;
std::vector<tabs::TabInterface*> GetAllTabInterfaces() override;
@@ -991,10 +1019,18 @@ class Browser : public TabStripModelObserver,
@@ -1011,10 +1039,18 @@ class Browser : public TabStripModelObserver,
void SetContentsBounds(content::WebContents* source,
const gfx::Rect& bounds) override;
void UpdateTargetURL(content::WebContents* source, const GURL& url) override;
@@ -579,7 +593,7 @@ index ce1e404e45a60..7193496de6b31 100644
void BeforeUnloadFired(content::WebContents* source,
bool proceed,
bool* proceed_to_fire_unload) override;
@@ -1341,6 +1377,10 @@ class Browser : public TabStripModelObserver,
@@ -1362,6 +1398,10 @@ class Browser : public TabStripModelObserver,
// The active state of this browser.
bool is_active_ = false;
@@ -590,7 +604,7 @@ index ce1e404e45a60..7193496de6b31 100644
std::unique_ptr<TabStripModelDelegate> const tab_strip_model_delegate_;
std::unique_ptr<TabStripModel> const tab_strip_model_;
@@ -1407,6 +1447,8 @@ class Browser : public TabStripModelObserver,
@@ -1426,6 +1466,8 @@ class Browser : public TabStripModelObserver,
const std::string initial_workspace_;
bool initial_visible_on_all_workspaces_state_;
@@ -600,10 +614,10 @@ index ce1e404e45a60..7193496de6b31 100644
UnloadController unload_controller_;
diff --git chrome/browser/ui/browser_navigator.cc chrome/browser/ui/browser_navigator.cc
index cefd4bc59943a..69425ab604ddb 100644
index 5f848bb04fe2a..4bf63873097bb 100644
--- chrome/browser/ui/browser_navigator.cc
+++ chrome/browser/ui/browser_navigator.cc
@@ -260,6 +260,10 @@ std::tuple<Browser*, int> GetBrowserAndTabForDisposition(
@@ -255,6 +255,10 @@ std::tuple<Browser*, int> GetBrowserAndTabForDisposition(
browser_params.pip_options = pip_options;
@@ -614,7 +628,7 @@ index cefd4bc59943a..69425ab604ddb 100644
const BrowserWindow* const browser_window = params.browser->window();
const gfx::NativeWindow native_window =
browser_window ? browser_window->GetNativeWindow()
@@ -547,7 +551,17 @@ std::unique_ptr<content::WebContents> CreateTargetContents(
@@ -543,7 +547,17 @@ std::unique_ptr<content::WebContents> CreateTargetContents(
}
#endif
@@ -670,10 +684,10 @@ index 83a510defbda5..f4305701c5f5a 100644
params.source_contents = source_contents;
params.url = target_url;
diff --git chrome/browser/ui/browser_window/browser_window_features.cc chrome/browser/ui/browser_window/browser_window_features.cc
index 274b403d01d91..4dd3239bf5f48 100644
index 57e4a41495830..7b8c001d4f62a 100644
--- chrome/browser/ui/browser_window/browser_window_features.cc
+++ chrome/browser/ui/browser_window/browser_window_features.cc
@@ -92,6 +92,15 @@ BrowserWindowFeatures::CreateBrowserWindowFeatures() {
@@ -105,6 +105,15 @@ BrowserWindowFeatures::CreateBrowserWindowFeatures() {
BrowserWindowFeatures::~BrowserWindowFeatures() = default;
@@ -689,7 +703,7 @@ index 274b403d01d91..4dd3239bf5f48 100644
// static
void BrowserWindowFeatures::ReplaceBrowserWindowFeaturesForTesting(
BrowserWindowFeaturesFactory factory) {
@@ -168,10 +177,12 @@ void BrowserWindowFeatures::Init(BrowserWindowInterface* browser) {
@@ -205,10 +214,12 @@ void BrowserWindowFeatures::Init(BrowserWindowInterface* browser) {
}
void BrowserWindowFeatures::InitPostWindowConstruction(Browser* browser) {
@@ -703,16 +717,16 @@ index 274b403d01d91..4dd3239bf5f48 100644
if (IsChromeLabsEnabled()) {
chrome_labs_coordinator_ =
std::make_unique<ChromeLabsCoordinator>(browser);
@@ -213,7 +224,7 @@ void BrowserWindowFeatures::InitPostWindowConstruction(Browser* browser) {
@@ -263,7 +274,7 @@ void BrowserWindowFeatures::InitPostWindowConstruction(Browser* browser) {
}
}
- if ((browser->is_type_normal() || browser->is_type_app()) &&
+ if ((supports_toolbar || browser->is_type_app()) &&
base::FeatureList::IsEnabled(toast_features::kToastFramework)) {
- if (browser->is_type_normal() || browser->is_type_app()) {
+ if (supports_toolbar || browser->is_type_app()) {
toast_service_ = std::make_unique<ToastService>(browser);
}
@@ -251,10 +262,12 @@ void BrowserWindowFeatures::InitPostBrowserViewConstruction(
}
@@ -295,10 +306,12 @@ void BrowserWindowFeatures::InitPostBrowserViewConstruction(
browser_view->browser(),
side_panel_coordinator_->GetWindowRegistry());
@@ -724,13 +738,13 @@ index 274b403d01d91..4dd3239bf5f48 100644
- if (browser_view->GetIsNormalType()) {
+ if (supports_toolbar) {
#if BUILDFLAG(ENABLE_GLIC)
if (glic::GlicEnabling::IsProfileEligible(
browser_view->browser()->profile())) {
glic::GlicKeyedService* glic_service =
glic::GlicKeyedService::Get(browser_view->GetProfile());
diff --git chrome/browser/ui/browser_window/public/browser_window_features.h chrome/browser/ui/browser_window/public/browser_window_features.h
index a318b2507f3ca..04bed96bbe382 100644
index f72f8787ba80a..0d9b32b79b062 100644
--- chrome/browser/ui/browser_window/public/browser_window_features.h
+++ chrome/browser/ui/browser_window/public/browser_window_features.h
@@ -81,6 +81,8 @@ class BrowserWindowFeatures {
@@ -93,6 +93,8 @@ class BrowserWindowFeatures {
static std::unique_ptr<BrowserWindowFeatures> CreateBrowserWindowFeatures();
virtual ~BrowserWindowFeatures();
@@ -740,10 +754,10 @@ index a318b2507f3ca..04bed96bbe382 100644
BrowserWindowFeatures& operator=(const BrowserWindowFeatures&) = delete;
diff --git chrome/browser/ui/browser_window/public/browser_window_interface.h chrome/browser/ui/browser_window/public/browser_window_interface.h
index f2b51e7923e96..644d0655ea6c9 100644
index 7e1194112343a..0a0e8c1818a3c 100644
--- chrome/browser/ui/browser_window/public/browser_window_interface.h
+++ chrome/browser/ui/browser_window/public/browser_window_interface.h
@@ -196,6 +196,10 @@ class BrowserWindowInterface : public content::PageNavigator {
@@ -229,6 +229,10 @@ class BrowserWindowInterface : public content::PageNavigator {
};
virtual Type GetType() const = 0;
@@ -755,7 +769,7 @@ index f2b51e7923e96..644d0655ea6c9 100644
// user education. The remainder of functionality is provided directly by the
// UserEducationService, which can be retrieved directly from the profile.
diff --git chrome/browser/ui/views/frame/tab_strip_region_view.cc chrome/browser/ui/views/frame/tab_strip_region_view.cc
index b0a946ad9168f..0f7daf3eb0255 100644
index cd93e66f918eb..dda28d11241d7 100644
--- chrome/browser/ui/views/frame/tab_strip_region_view.cc
+++ chrome/browser/ui/views/frame/tab_strip_region_view.cc
@@ -118,8 +118,7 @@ TabStripRegionView::TabStripRegionView(std::unique_ptr<TabStrip> tab_strip)

View File

@@ -1,5 +1,5 @@
diff --git components/content_settings/renderer/content_settings_agent_impl.cc components/content_settings/renderer/content_settings_agent_impl.cc
index 0897668803c2e..12cdbd7642ffd 100644
index 2394aeb4fb33e..7f27b04a0dc50 100644
--- components/content_settings/renderer/content_settings_agent_impl.cc
+++ components/content_settings/renderer/content_settings_agent_impl.cc
@@ -146,7 +146,7 @@ ContentSetting GetContentSettingFromRules(

Some files were not shown because too many files have changed in this diff Show More