mirror of
https://github.com/electron/electron.git
synced 2026-10-28 19:54:46 +08:00
* chore: bump chromium in DEPS to 156.0.8073.0 * 8409748: Update RenderWidgetHostViewBase::host_ lifetime Ref: https://chromium-review.googlesource.com/c/chromium/src/+/8409748 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * 8410048: [dcheck-to-check] Convert DCHECKs in content/browser/ [34/n] Ref: https://chromium-review.googlesource.com/c/chromium/src/+/8410048 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * 8401889: [Win] Read GetLastError() right after CreateFile() in ProcessSingleton Upstream now reads GetLastError() inside the TRACE_EVENT0 scope, which is the same fix this patch carried, so drop that hunk. Ref: https://chromium-review.googlesource.com/c/chromium/src/+/8401889 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * 8293899: Android: Enable ThemeService for WebUI NTP Upstream moved the //chrome/browser/themes dependency from a per-platform conditional into the unconditional deps of the mixers target, so the patch now removes it from that list instead. Ref: https://chromium-review.googlesource.com/c/chromium/src/+/8293899 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * 8412026: [mac] Support video capture lock on macOS Keep the compositor unsuspended when the window is headless, visible, or has an active video capture lock. Ref: https://chromium-review.googlesource.com/c/chromium/src/+/8412026 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * 8404074: [posix] Don't call SetNonBlocking() inside DCHECK() in ProcessSingleton Upstream made the same change, so drop the hunk from this patch. Ref: https://chromium-review.googlesource.com/c/chromium/src/+/8404074 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * 8421647: media: Move GPU/graphics client utilities to media/gfx/ Ref: https://chromium-review.googlesource.com/c/chromium/src/+/8421647 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * 8361191: [api] Add MicrotaskQueue::SetMicrotasksPolicy()/GetMicrotasksPolicy() V8 now exposes the per-queue microtasks policy on v8::MicrotaskQueue, so remove the patch that added it and switch node_util.cc to the upstream SetMicrotasksPolicy()/GetMicrotasksPolicy() names. Ref: https://chromium-review.googlesource.com/c/v8/v8/+/8361191 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * chore: remove upstreamed patches Ref: https://chromium-review.googlesource.com/c/chromium/src/+/8455783 Ref: https://chromium-review.googlesource.com/c/chromium/src/+/8455325 Ref: https://chromium-review.googlesource.com/c/chromium/src/+/8431509 Ref: https://chromium-review.googlesource.com/c/chromium/src/+/8402403 Ref: https://chromium-review.googlesource.com/c/chromium/src/+/8402402 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * chore: update patches * chore: update siso revision * 8426326: Linux: Rename DarkModeManagerLinux to PortalSettingsLinux Ref: https://chromium-review.googlesource.com/c/chromium/src/+/8426326 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * 8278613: Plumb navigation IDs to MIME handler streams Pass the navigation ID through StreamsPrivateAPI::SendExecuteMimeTypeHandlerEvent to the MIME handler stream manager, and only create the plugin response interceptor throttle for navigation requests, matching the upstream ChromeContentBrowserClient change. Ref: https://chromium-review.googlesource.com/c/chromium/src/+/8278613 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * 8403343: Bump clang revision The new clang package ships the raw_ptr plugin change from crrev.com/c/8358382, after which [chromium-containers] rejects T* template arguments in std::list, std::set and std::vector fields. Store raw_ptr<T> in those Electron containers instead. Ref: https://chromium-review.googlesource.com/c/chromium/src/+/8403343 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * 8362297: viz: Add `is_secure` flag to CopyOutputRequest and friends The new is_secure member brings VideoCaptureParams, together with the use_native_picker field this patch adds, over the chromium-style complexity threshold, so the implicit inline copy constructor is now rejected. Declare out-of-line copy and move constructors and assignment operators for the struct in the patch. Ref: https://chromium-review.googlesource.com/c/chromium/src/+/8362297 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * 8442576: Remove id from ChildProcessData Ref: https://chromium-review.googlesource.com/c/chromium/src/+/8442576 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * 8421383: [RWS] Remove unused RWS cookie exclusion reason Ref: https://chromium-review.googlesource.com/c/chromium/src/+/8421383 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * 8240331: Support targeting a network in NetworkService's WebSockets Ref: https://chromium-review.googlesource.com/c/chromium/src/+/8240331 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * 8426064: Remove flag for restrict frame destinations to navigate The frame-destination check is now unconditional upstream, so drop the feature flag check in net.request. Ref: https://chromium-review.googlesource.com/c/chromium/src/+/8426064 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * 8292633: [atmemory] Add `blink::mojom::ScrollType` to the Autofill scroll callstack Ref: https://chromium-review.googlesource.com/c/chromium/src/+/8292633 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * 8405125: FSA: rename UserAction to AccessTrigger and add programmatic triggers The former UserAction::kNone case is now split into AccessTrigger::kProgrammaticRead and kProgrammaticWrite; both keep the previous behavior of not granting access automatically and of replying to sensitive entry checks without prompting. Ref: https://chromium-review.googlesource.com/c/chromium/src/+/8405125 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * 8399046: Add chrome:// host and path mapping for component extensions ExtensionConfigMap::GetConfigProvider() now takes an Extension; use the new GetConfigProviderByExtensionId() for the id-based lookup. Ref: https://chromium-review.googlesource.com/c/chromium/src/+/8399046 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * 8445301: [Linux] Decouple //components/dbus from //ui/base and //net The //components/dbus component no longer depends on //components/dbus/menu, so depend on it directly for status_icon_linux_dbus.cc. Ref: https://chromium-review.googlesource.com/c/chromium/src/+/8445301 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * 8360557: [Extensions] Make generated features immutable FeatureProvider::AddFeature() no longer replaces an existing feature, so the entries Electron's feature files used to override core ones now fail a CHECK at startup. Drop the ones that duplicate the core definitions, or differ only in ChromeOS-only branches. Keep chrome.webstorePrivate unavailable by moving its delegated availability check into the core definition with a patch. Ref: https://chromium-review.googlesource.com/c/chromium/src/+/8360557 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * 8427384: Generate CDP TypeScript definitions directly from in-tree PDL files Ref: https://chromium-review.googlesource.com/c/chromium/src/+/8427384 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fixup! 8403343: Bump clang revision * chore: update patches Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * 8397345: Move titlebar_config.h to chrome/browser/win The move switched the color mixers' Windows dependency from the narrow titlebar_config target to all of //chrome/browser/win, although the mixer uses nothing from it. On Windows that pulls //chrome/browser/profiles into Electron's link, where its ProfileKeyedServiceFactory collides with the one Electron provides for the spellchecker. Patch the unused dependency out. Ref: https://chromium-review.googlesource.com/c/chromium/src/+/8397345 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * 8403320: [WebUI] Disallow devtools:// scheme for WebUI data sources by default URL data sources are no longer served to devtools:// unless they opt in, so DevTools failed to load its frontend. Opt Electron's bundle data source in, and let its theme data source serve colors.css to devtools:// as Chrome's ThemeSource does. Ref: https://chromium-review.googlesource.com/c/chromium/src/+/8403320 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * 8394377: Migrate RefCountedDeleteOnSequence to start-from-one ref counting (4/4) Ref: https://chromium-review.googlesource.com/c/chromium/src/+/8394377 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * chore: bump chromium in DEPS to 156.0.8075.0 * chore: update patches Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com> * 8467669: [zoom] Key host-less zoom levels on the URL without its fragment Ref: https://chromium-review.googlesource.com/c/chromium/src/+/8467669 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * chore: update patches Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * chore: bump chromium in DEPS to 156.0.8076.0 * 8468407: [gtk] Don't leave GDK_BACKEND set in the environment after GTK init Ref: https://chromium-review.googlesource.com/c/chromium/src/+/8468407 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * 8457646: [snapshot] Include embedder string in version hash Upstream moved Version::Hash() out of line and now builds it with base::Hasher over the version number and embedder string. Fold the v8_version_hash_salt into that hasher the same way instead of carrying a separate FNV-1a helper and hash_combine() call. Ref: https://chromium-review.googlesource.com/c/v8/v8/+/8457646 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * chore: update patches * 8459447: gin: Mark the stack-only helper classes STACK_ALLOCATED() gin::Dictionary is now STACK_ALLOCATED(), and the find-bad-constructs plugin conservatively treats any template instantiated with a stack-allocated type argument as stack-allocated too. Mark the two gin_helper::Promise<gin_helper::Dictionary> fields with STACK_ALLOCATED_IGNORE, since Promise<T> only names T as its resolve type and never stores one. Ref: https://chromium-review.googlesource.com/c/chromium/src/+/8459447 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * 8424587: mojo: Remove unused WrapPlatformFile and UnwrapPlatformFile helpers Ref: https://chromium-review.googlesource.com/c/chromium/src/+/8424587 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * fixup! 8403343: Bump clang revision notifications_ is now a std::set<raw_ptr<Notification>>, and libc++ has no heterogeneous set::erase, so erasing by key after Dismiss() built a temporary raw_ptr from the notification. On macOS Dismiss() has already destroyed it by then, so that took a BackupRefPtr reference on freed memory. Find it with the transparent comparator, which compares addresses without constructing a raw_ptr, and erase by iterator. Also drop NotifyIconHost::NotifyIcons, unused since notify_icons_ became a std::vector<raw_ptr<NotifyIcon>>. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fixup! 8426064: Remove flag for restrict frame destinations to navigate Drop the network features include; its only use was the kRestrictFrameDestinationsToNavigate check this CL removed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: electron-roller[bot] <84116207+electron-roller[bot]@users.noreply.github.com> Co-authored-by: electron-claude[bot] <279139701+electron-claude[bot]@users.noreply.github.com> Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com> Co-authored-by: clavin <clavin@electronjs.org> Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com>
243 lines
9.3 KiB
C++
243 lines
9.3 KiB
C++
// Copyright (c) 2019 GitHub, Inc.
|
|
// Use of this source code is governed by the MIT license that can be
|
|
// found in the LICENSE file.
|
|
|
|
#include "shell/common/node_util.h"
|
|
|
|
#include "base/compiler_specific.h"
|
|
#include "base/containers/to_value_list.h"
|
|
#include "base/json/json_writer.h"
|
|
#include "base/logging.h"
|
|
#include "base/no_destructor.h"
|
|
#include "base/strings/strcat.h"
|
|
#include "base/strings/string_number_conversions.h"
|
|
#include "base/threading/thread_local.h"
|
|
#include "base/values.h"
|
|
#include "gin/converter.h"
|
|
#include "shell/common/gin_converters/callback_converter.h"
|
|
#include "shell/common/node_includes.h"
|
|
#include "shell/common/node_natives_code_cache.h"
|
|
#include "shell/common/process_util.h"
|
|
#include "third_party/electron_node/src/node_process-inl.h"
|
|
|
|
namespace electron::util {
|
|
|
|
v8::MaybeLocal<v8::Function> CompileBundle(
|
|
v8::Local<v8::Context> context,
|
|
const char* id,
|
|
v8::LocalVector<v8::String>* parameters) {
|
|
static base::NoDestructor<
|
|
base::ThreadLocalOwnedPointer<node::builtins::BuiltinLoader>>
|
|
builtin_loader;
|
|
if (!builtin_loader->Get()) {
|
|
auto loader = std::make_unique<node::builtins::BuiltinLoader>();
|
|
// Feed the build-time js2c code cache so the framework bundles are
|
|
// consumed instead of compiled from source. Must run before the first
|
|
// LookupAndCompileFunction; empty on builds without a generated cache.
|
|
const bool has_node_env = node::Environment::GetCurrent(context) != nullptr;
|
|
const auto& cache =
|
|
GetNativesCodeCache(CurrentProcessJs2cCacheFlavor(has_node_env));
|
|
if (!cache.empty())
|
|
loader->RefreshCodeCache(cache);
|
|
builtin_loader->Set(std::move(loader));
|
|
}
|
|
v8::MaybeLocal<v8::Function> compiled =
|
|
builtin_loader->Get()->LookupAndCompileFunction(
|
|
context, id, parameters, node::Realm::GetCurrent(context));
|
|
// TODO(samuelmaddock): how can we get the compilation error message?
|
|
if (compiled.IsEmpty())
|
|
LOG(ERROR) << "Failed to compile electron script (" << id << ")";
|
|
return compiled;
|
|
}
|
|
|
|
v8::MaybeLocal<v8::Value> CompileAndCall(
|
|
v8::Isolate* const isolate,
|
|
v8::Local<v8::Context> context,
|
|
const char* id,
|
|
v8::LocalVector<v8::String>* parameters,
|
|
v8::LocalVector<v8::Value>* arguments) {
|
|
v8::TryCatch try_catch{isolate};
|
|
v8::Local<v8::Function> fn;
|
|
if (!CompileBundle(context, id, parameters).ToLocal(&fn))
|
|
return {};
|
|
v8::MaybeLocal<v8::Value> ret = fn->Call(
|
|
context, v8::Null(isolate), arguments->size(), arguments->data());
|
|
|
|
// This will only be caught when something has gone terrible wrong as all
|
|
// electron scripts are wrapped in a try {} catch {} by
|
|
// build/bundle/bundle.mjs
|
|
if (try_catch.HasCaught()) {
|
|
std::string msg = "no error message";
|
|
if (!try_catch.Message().IsEmpty()) {
|
|
gin::ConvertFromV8(isolate, try_catch.Message()->Get(), &msg);
|
|
} else if (try_catch.HasTerminated()) {
|
|
msg = "script execution has been terminated";
|
|
}
|
|
LOG(ERROR) << "CompileAndCall failed to evaluate electron script (" << id
|
|
<< "): " << msg;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
void FeedEnvironmentCodeCache(node::Environment* env) {
|
|
const auto& cache = GetNativesCodeCache(CurrentProcessJs2cCacheFlavor());
|
|
if (!cache.empty())
|
|
env->builtin_loader()->RefreshCodeCache(cache);
|
|
}
|
|
|
|
void InstallProcessCodeCache() {
|
|
static const bool installed = [] {
|
|
const auto& cache = GetNativesCodeCache(CurrentProcessJs2cCacheFlavor());
|
|
if (!cache.empty())
|
|
node::builtins::BuiltinLoader::SetProcessDefaultCodeCache(&cache);
|
|
return true;
|
|
}();
|
|
(void)installed;
|
|
}
|
|
|
|
void EmitWarning(const std::string_view warning_msg,
|
|
const std::string_view warning_type) {
|
|
// Reachable from renderers, where there is no JavascriptEnvironment.
|
|
EmitWarning(v8::Isolate::TryGetCurrent(), warning_msg, warning_type);
|
|
}
|
|
|
|
void EmitWarning(v8::Isolate* isolate,
|
|
const std::string_view warning_msg,
|
|
const std::string_view warning_type) {
|
|
node::Environment* env =
|
|
isolate ? node::Environment::GetCurrent(isolate) : nullptr;
|
|
if (!env) {
|
|
// No Node.js environment available, fall back to console logging.
|
|
LOG(WARNING) << "[" << warning_type << "] " << warning_msg;
|
|
return;
|
|
}
|
|
node::ProcessEmitWarningGeneric(env, warning_msg, warning_type);
|
|
}
|
|
|
|
void EmitDeprecationWarning(const std::string_view warning_msg,
|
|
const std::string_view deprecation_code) {
|
|
EmitDeprecationWarning(v8::Isolate::TryGetCurrent(), warning_msg,
|
|
deprecation_code);
|
|
}
|
|
|
|
void EmitDeprecationWarning(v8::Isolate* isolate,
|
|
const std::string_view warning_msg,
|
|
const std::string_view deprecation_code) {
|
|
node::Environment* env =
|
|
isolate ? node::Environment::GetCurrent(isolate) : nullptr;
|
|
if (!env) {
|
|
// No Node.js environment available, fall back to console logging.
|
|
LOG(WARNING) << "[DeprecationWarning] " << warning_msg
|
|
<< " (code: " << deprecation_code << ")";
|
|
return;
|
|
}
|
|
node::ProcessEmitWarningGeneric(env, warning_msg, "DeprecationWarning",
|
|
deprecation_code);
|
|
}
|
|
|
|
node::Environment* CreateEnvironment(v8::Isolate* isolate,
|
|
node::IsolateData* isolate_data,
|
|
v8::Local<v8::Context> context,
|
|
const std::vector<std::string>& args,
|
|
const std::vector<std::string>& exec_args,
|
|
node::EnvironmentFlags::Flags env_flags,
|
|
std::string_view process_type) {
|
|
v8::TryCatch try_catch{isolate};
|
|
node::Environment* env = node::CreateEnvironment(isolate_data, context, args,
|
|
exec_args, env_flags);
|
|
if (auto message = try_catch.Message(); !message.IsEmpty()) {
|
|
base::DictValue dict;
|
|
|
|
if (std::string str; gin::ConvertFromV8(isolate, message->Get(), &str))
|
|
dict.Set("message", std::move(str));
|
|
|
|
if (std::string str; gin::ConvertFromV8(
|
|
isolate, message->GetScriptOrigin().ResourceName(), &str)) {
|
|
const auto line_num = message->GetLineNumber(context).FromJust();
|
|
const auto line_str = base::NumberToString(line_num);
|
|
dict.Set("location", base::StrCat({", at ", str, ":", line_str}));
|
|
}
|
|
|
|
if (std::string str; gin::ConvertFromV8(
|
|
isolate, message->GetSourceLine(context).ToLocalChecked(), &str))
|
|
dict.Set("source_line", std::move(str));
|
|
|
|
if (!std::empty(process_type))
|
|
dict.Set("process_type", process_type);
|
|
|
|
if (auto list = base::ToValueList(args); !std::empty(list))
|
|
dict.Set("args", std::move(list));
|
|
|
|
if (auto list = base::ToValueList(exec_args); !std::empty(list))
|
|
dict.Set("exec_args", std::move(list));
|
|
|
|
std::string errstr = "Failed to initialize Node.js.";
|
|
if (std::optional<std::string> jsonstr = base::WriteJsonWithOptions(
|
|
dict, base::JsonOptions::OPTIONS_PRETTY_PRINT))
|
|
errstr += base::StrCat({" ", *jsonstr});
|
|
|
|
LOG(ERROR) << errstr;
|
|
}
|
|
|
|
return env;
|
|
}
|
|
|
|
v8::Local<v8::Object> CreateAbortController(v8::Isolate* isolate) {
|
|
auto context = isolate->GetCurrentContext();
|
|
auto global_object = context->Global();
|
|
|
|
auto value =
|
|
global_object->Get(context, gin::StringToV8(isolate, "AbortController"))
|
|
.ToLocalChecked();
|
|
DCHECK(!value.IsEmpty() && value->IsObject());
|
|
|
|
DCHECK(value->IsFunction());
|
|
auto constructor = value.As<v8::Function>();
|
|
auto instance =
|
|
constructor->NewInstance(context, 0, nullptr).ToLocalChecked();
|
|
return instance;
|
|
}
|
|
|
|
ExplicitMicrotasksScope::ExplicitMicrotasksScope(v8::MicrotaskQueue* queue)
|
|
: microtask_queue_(queue), original_policy_(queue->GetMicrotasksPolicy()) {
|
|
// Browser-like processes already run with kExplicit, nested run loops
|
|
// included. Renderers can get here from inside script (a frame's environment
|
|
// freed by element.remove()); explicit checkpoints are then no-ops until the
|
|
// enclosing scope unwinds.
|
|
if (electron::IsBrowserProcess() || electron::IsUtilityProcess())
|
|
DCHECK_EQ(original_policy_, v8::MicrotasksPolicy::kExplicit);
|
|
|
|
microtask_queue_->SetMicrotasksPolicy(v8::MicrotasksPolicy::kExplicit);
|
|
}
|
|
|
|
ExplicitMicrotasksScope::~ExplicitMicrotasksScope() {
|
|
microtask_queue_->SetMicrotasksPolicy(original_policy_);
|
|
}
|
|
|
|
} // namespace electron::util
|
|
|
|
namespace electron::Buffer {
|
|
|
|
// SAFETY: There is no node::Buffer API that passes the UNSAFE_BUFFER_USAGE
|
|
// test, so let's isolate the unsafe API use into this function. Instead of
|
|
// calling `Buffer::Data()` and `Buffer::Length()` directly, the rest of our
|
|
// code should prefer to use spans returned by this function.
|
|
base::span<uint8_t> as_byte_span(v8::Local<v8::Value> node_buffer) {
|
|
auto* data = reinterpret_cast<uint8_t*>(node::Buffer::Data(node_buffer));
|
|
const auto size = node::Buffer::Length(node_buffer);
|
|
return UNSAFE_BUFFERS(base::span{data, size});
|
|
}
|
|
|
|
v8::MaybeLocal<v8::Object> Copy(v8::Isolate* isolate,
|
|
const base::span<const char> data) {
|
|
// SAFETY: span-friendly version of node::Buffer::Copy()
|
|
return UNSAFE_BUFFERS(node::Buffer::Copy(isolate, data.data(), data.size()));
|
|
}
|
|
|
|
v8::MaybeLocal<v8::Object> Copy(v8::Isolate* isolate,
|
|
const base::span<const uint8_t> data) {
|
|
return Copy(isolate, base::as_chars(data));
|
|
}
|
|
|
|
} // namespace electron::Buffer
|